TXHD2: bl30 add txhd2 board be301, be309, be311 and be319 [1/1]
PD#SWPL-125307
Problem:
bl30 txhd2 board is only txhd2_skt.
Solution:
bl30 add txhd2 board be301, be309, be311 and be319.
Verify:
local build all board pass.
Change-Id: I683872dbe5d35827d9bd9fead4deae4a875e95ec
Signed-off-by: bangzheng.liu <bangzheng.liu@amlogic.com>
diff --git a/be301_t950s/CMakeLists.txt b/be301_t950s/CMakeLists.txt
new file mode 100644
index 0000000..0e2e79d
--- /dev/null
+++ b/be301_t950s/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+aml_library_include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+aml_library_sources(
+ fsm.c
+ # btwake.c
+ keypad.c
+ power.c
+ hw_business.c
+)
+
+aml_library_sources_ifdef(
+ CONFIG_LEDS
+ leds_plat.c
+)
diff --git a/be301_t950s/FreeRTOSConfig.h b/be301_t950s/FreeRTOSConfig.h
new file mode 100644
index 0000000..f72f6cf
--- /dev/null
+++ b/be301_t950s/FreeRTOSConfig.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include <stdio.h>
+
+#define USER_MODE_TASKS 0
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configUSE_TICKLESS_IDLE 0
+#define configCPU_CLOCK_HZ 24000000 //32768
+#define configTICK_RATE_HZ 50
+#define configMAX_PRIORITIES 4
+#define configMINIMAL_STACK_SIZE 450
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_TASK_NOTIFICATIONS 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 0
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 10
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 1
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 0
+#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
+
+/* Memory allocation related definitions. */
+#define configSUPPORT_STATIC_ALLOCATION 0
+#define configSUPPORT_DYNAMIC_ALLOCATION 1
+#define configTOTAL_HEAP_SIZE (22 * 1024)
+#define configAPPLICATION_ALLOCATED_HEAP 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configCHECK_FOR_STACK_OVERFLOW 0
+#define configUSE_MALLOC_FAILED_HOOK 0
+#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 0
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine related definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 1
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY 1
+#define configTIMER_QUEUE_LENGTH 10
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Interrupt nesting behaviour configuration. */
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 6
+#define configMAX_API_CALL_INTERRUPT_PRIORITY 6
+
+#define configDEFAULT_HEAP_ADDR 0xfffc0000
+#define configDEFAULT_HEAP_SIZE (26 * 1024)
+#define configSTICK_REG_ADDR (configDEFAULT_HEAP_ADDR + configDEFAULT_HEAP_SIZE)
+#define configSTICK_REG_SIZE 128
+
+#define portCRITICAL_NESTING_IN_TCB 1
+
+/* Define to trap errors during development. */
+#define configASSERT(x) \
+ do { \
+ if ((x) == 0) { \
+ taskDISABLE_INTERRUPTS(); \
+ printf("ASSERT: %s %d\n", __FILE__, __LINE__); \
+ for (;;) \
+ ; \
+ } \
+ } while (0)
+
+/* FreeRTOS MPU specific definitions. */
+//#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_xResumeFromISR 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 1
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 1
+#define INCLUDE_xTaskGetIdleTaskHandle 1
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 1
+#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_xTaskAbortDelay 0
+#define INCLUDE_xTaskGetHandle 1
+#define INCLUDE_xTaskResumeFromISR 1
+
+#define configCLINT_BASE_ADDRESS 0x02000000UL
+/* A header file that defines trace macro can be included here. */
+
+#endif /* FREERTOS_CONFIG_H */
diff --git a/be301_t950s/Kconfig b/be301_t950s/Kconfig
new file mode 100644
index 0000000..c6b4c4b
--- /dev/null
+++ b/be301_t950s/Kconfig
@@ -0,0 +1,28 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+config BOARD_BE301_T950S
+ bool "Amlogic BE301_T950S Board"
+ select SOC_TXHD2
+ select LIBC_AML
+ select COMMON
+ select GET_VERSION
+ select STICK_MEM
+ select UART
+ # select CEC
+ select DDR
+ select MAILBOX
+ select VRTC
+ select STR
+ select GPIO
+ select KEY
+ select PWM
+ # select LEDS
+ select TIMER_SOURCE
+ select SARADC
+ select IR
+ select ETHERNET
+ select VERSION_FULL_INFO
+ help
+ Enable Amlogic BE301_T950S Board.
diff --git a/be301_t950s/btwake.c b/be301_t950s/btwake.c
new file mode 100644
index 0000000..bab28d5
--- /dev/null
+++ b/be301_t950s/btwake.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "suspend.h"
+#include "task.h"
+#include "gpio.h"
+
+#include "queue.h" /* RTOS queue related API prototypes. */
+#include "timers.h" /* Software timer related API prototypes. */
+#include "semphr.h" /* Semaphore related API prototypes. */
+
+#define BT_WAKE_HOST GPIOB_13 //bt_wake_host pin
+#define INFO(fmt, args...) printf("[%s] " fmt "\n", __func__, ##args)
+
+void Bt_IRQHandle(void)
+{
+ uint32_t buf[4] = { 0 };
+
+ INFO("bt resume");
+ vDisableGpioIRQ(BT_WAKE_HOST);
+ if (!xGpioGetValue(BT_WAKE_HOST)) {
+ buf[0] = BT_WAKEUP;
+ INFO("power key");
+ STR_Wakeup_src_Queue_Send_FromISR(buf);
+ }
+}
+
+void Bt_GpioIRQRegister(void)
+{
+ INFO();
+ xGpioSetDir(BT_WAKE_HOST, GPIO_DIR_IN);
+ xRequestGpioIRQ(BT_WAKE_HOST, Bt_IRQHandle, IRQF_TRIGGER_FALLING);
+}
+
+void Bt_GpioIRQFree(void)
+{
+ vFreeGpioIRQ(BT_WAKE_HOST);
+}
diff --git a/be301_t950s/compiler_options.cmake b/be301_t950s/compiler_options.cmake
new file mode 100644
index 0000000..3d11a1f
--- /dev/null
+++ b/be301_t950s/compiler_options.cmake
@@ -0,0 +1,5 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+#add compiler options at here which is associated with current board.
diff --git a/be301_t950s/defconfig b/be301_t950s/defconfig
new file mode 100644
index 0000000..ef9e1a0
--- /dev/null
+++ b/be301_t950s/defconfig
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: MIT
+#
+
+CONFIG_BOARD_BE301_T950S=y
+
diff --git a/be301_t950s/fsm.c b/be301_t950s/fsm.c
new file mode 100644
index 0000000..27b34c5
--- /dev/null
+++ b/be301_t950s/fsm.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "FreeRTOS.h" /* Must come first. */
+#include "task.h" /* RTOS task related API prototypes. */
+#include "queue.h" /* RTOS queue related API prototypes. */
+#include "timers.h" /* Software timer related API prototypes. */
+#include "semphr.h" /* Semaphore related API prototypes. */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "n200_func.h"
+#include "common.h"
+#include "riscv_encoding.h"
+#include "mailbox-api.h"
+#include "irq.h"
+
+enum PM_E {
+ PM_CPU_PWR,
+ PM_CPU_CORE0,
+ PM_CPU_CORE1,
+ PM_CPU_CORE2,
+ PM_CPU_CORE3,
+};
+
+static void *xMboxCoreFsmIdle(void *msg)
+{
+ enum PM_E domain = *(uint32_t *)msg;
+
+ switch (domain) {
+ case PM_CPU_CORE0:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 0), 0);
+ EnableIrq(IRQ_NUM_OUT_0);
+ break;
+ case PM_CPU_CORE1:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 1), 0);
+ EnableIrq(IRQ_NUM_OUT_1);
+ break;
+ case PM_CPU_CORE2:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 2), 0);
+ EnableIrq(IRQ_NUM_OUT_2);
+ break;
+ case PM_CPU_CORE3:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 3), 0);
+ EnableIrq(IRQ_NUM_OUT_3);
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static void xSetCoreFsmAwakeIrq(int cpuid)
+{
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << cpuid), (1 << cpuid));
+}
+
+static void xCore0FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(0);
+ DisableIrq(IRQ_NUM_OUT_0);
+}
+
+static void xCore1FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(1);
+ DisableIrq(IRQ_NUM_OUT_1);
+}
+
+static void xCore2FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(2);
+ DisableIrq(IRQ_NUM_OUT_2);
+}
+
+static void xCore3FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(3);
+ DisableIrq(IRQ_NUM_OUT_3);
+}
+
+void vCoreFsmIdleInit(void)
+{
+ int ret;
+
+ ret = xInstallRemoteMessageCallbackFeedBack(AOTEE_CHANNEL, MBX_CMD_CPU_FSM_IDLE,
+ xMboxCoreFsmIdle, 0);
+ if (ret == MBOX_CALL_MAX)
+ printf("mbox cmd 0x%x register fail\n", MBX_CMD_CPU_FSM_IDLE);
+
+ RegisterIrq(IRQ_NUM_OUT_0, 1, xCore0FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_1, 1, xCore1FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_2, 1, xCore2FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_3, 1, xCore3FsmIdleHandleIsr);
+ REG32_UPDATE_BITS(SEC_SYS_CPU_CFG10, 0xF << 10, 0xF << 10);
+}
diff --git a/be301_t950s/fsm.h b/be301_t950s/fsm.h
new file mode 100644
index 0000000..86a1f01
--- /dev/null
+++ b/be301_t950s/fsm.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __FSM_H__
+#define __FSM_H__
+
+void vCoreFsmIdleInit(void);
+extern void vRtcInit(void);
+extern void create_str_task(void);
+extern void trap_entry(void);
+extern void irq_entry(void);
+
+#endif
diff --git a/be301_t950s/hw_business.c b/be301_t950s/hw_business.c
new file mode 100644
index 0000000..6d525cf
--- /dev/null
+++ b/be301_t950s/hw_business.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "semphr.h"
+#include "hw_business.h"
+#include "n200_eclic.h"
+#include "n200_func.h"
+#include "uart.h"
+#include "eth.h"
+#include "common.h"
+#include "mailbox-api.h"
+#include "hdmi_cec.h"
+#include "stick_mem.h"
+#include "keypad.h"
+#include "fsm.h"
+
+#define INT_TEST_NEST_DEPTH 6
+#define INT_TEST_GPIO_NUM 6
+#define INT_TEST_TASK_DELAY 50 // ms
+#define TASK_TEST_STACK_DEPTH 200
+
+#define TASK_TEST_QUEUE_NUM 2
+#define TASK_TEST_QUEUE_LENGTH 3
+
+//#define GPIO_INT_SOURCE(x) (SOC_PIC_INT_GPIO_BASE + x)
+
+/* Configure board type:
+ * Board under test : SIGNAL_BOARD_ENABLE 0
+ * Signal generation board : SIGNAL_BOARD_ENABLE 1
+ */
+#define SIGNAL_BOARD_ENABLE 0
+
+#define INT_TEST_INT_WAVE_ENABLE 1
+
+#if INT_TEST_INT_WAVE_ENABLE
+ #define INT_TEST_TIMER_PERIOD 500 // ms
+ #define INT_TEST_INT_DELAY 10 // ms
+#else
+ #define INT_TEST_TIMER_PERIOD 500 // ms
+ #define INT_TEST_INT_DELAY 0x3ff // ms
+#endif
+
+#define INT_TEST_MAX_TIMER_PERIOD 100 // ms
+#define INT_TEST_MIN_TIMER_PERIOD 50 // ms
+#define INT_TEST_MUTE_TIMER_PERIOD 200 // ms
+
+#define RTOS_BOOT_SUCC_REG AO_DEBUG_REG2
+
+/* Binary Semaphore */
+QueueHandle_t xGPIOSemaphore[INT_TEST_NEST_DEPTH];
+QueueHandle_t xMessageQueue[TASK_TEST_QUEUE_NUM];
+
+void config_eclic_irqs(void)
+{
+ eclic_init(ECLIC_NUM_INTERRUPTS);
+ eclic_set_nlbits(0);
+}
+
+void hw_business_process(void)
+{
+ uint8_t i = 0;
+
+ // Initialize GPIOs, PIC and timer
+ //vGPIOInit();
+ config_eclic_irqs();
+ for (i = 0; i < 8; ++i)
+ printf("AOCPU_IRQ_SEL=0x%x\n", REG32(AOCPU_IRQ_SEL0 + i * 4));
+
+ stick_mem_init();
+ //write watchdog flag
+ stick_mem_write(STICK_REBOOT_FLAG, 0xd);
+
+ // Delay
+ for (uint32_t i = 0; i < 0xffff; ++i)
+ ;
+
+ vMbInit();
+ vCoreFsmIdleInit();
+ // vCecCallbackInit(CEC_CHIP_T5);
+ vRtcInit();
+ vETHMailboxCallback();
+ create_str_task();
+ vKeyPadCreate();
+}
+
+void aocpu_bringup_finished(void)
+{
+ #define RTOS_RUN_SUCC (1 << 0)
+ *(volatile uint32_t *)RTOS_BOOT_SUCC_REG |= RTOS_RUN_SUCC;
+}
+
diff --git a/be301_t950s/hw_business.h b/be301_t950s/hw_business.h
new file mode 100644
index 0000000..2dc1d61
--- /dev/null
+++ b/be301_t950s/hw_business.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __hW_BUSINESS_H__
+#define __hW_BUSINESS_H__
+
+void hw_business_process(void);
+
+#endif
diff --git a/be301_t950s/keypad.c b/be301_t950s/keypad.c
new file mode 100644
index 0000000..7406fb1
--- /dev/null
+++ b/be301_t950s/keypad.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "ir.h"
+#include "keypad.h"
+#include "gpio.h"
+#include "saradc.h"
+#include "suspend.h"
+
+/*KEY ID*/
+#define ADC_KEY_ID_HOME 520
+
+static void vAdcKeyCallBack(struct xReportEvent event)
+{
+ uint32_t buf[4] = { 0 };
+
+ switch (event.ulCode) {
+ case ADC_KEY_ID_HOME:
+ buf[0] = POWER_KEY_WAKEUP;
+ STR_Wakeup_src_Queue_Send(buf);
+ break;
+ default:
+ break;
+ }
+
+ printf("ADC key event 0x%x, key code %d, responseTicks %d\n", event.event, event.ulCode,
+ event.responseTime);
+}
+
+struct xAdcKeyInfo adcKeyInfo[] = { ADC_KEY_INFO(ADC_KEY_ID_HOME, 0, SARADC_CH1, EVENT_SHORT,
+ vAdcKeyCallBack, NULL) };
+
+void vKeyPadCreate(void)
+{
+ vCreateAdcKey(adcKeyInfo, sizeof(adcKeyInfo) / sizeof(struct xAdcKeyInfo));
+
+ vDynamicKeypadInit();
+}
+
+void vKeyPadInit(void)
+{
+ if (vAdcKeyIsEmpty())
+ vCreateAdcKey(adcKeyInfo, sizeof(adcKeyInfo) / sizeof(struct xAdcKeyInfo));
+
+ vAdcKeyEnable();
+ vGpioKeyEnable();
+}
+
+void vKeyPadDeinit(void)
+{
+ vAdcKeyDisable();
+ vGpioKeyDisable();
+}
diff --git a/be301_t950s/keypad.h b/be301_t950s/keypad.h
new file mode 100644
index 0000000..e496629
--- /dev/null
+++ b/be301_t950s/keypad.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __MESON_Button_H
+#define __MESON_Button_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "common.h"
+#include <stdlib.h>
+#include <string.h>
+#include "FreeRTOS.h"
+#include <timers.h>
+#include <task.h>
+#include <gpio.h>
+#include <saradc.h>
+
+/*common macro*/
+#define TIMER_CYCLE_TIME 100
+#define KEY_JITTER_COUNT 1
+
+/* adc key param */
+#define SAMPLE_DEVIATION 40
+#define ADCKEY_ID_BASE 512
+
+/* key event */
+#define EVENT_SHORT (1 << 0)
+#define EVENT_LONG (1 << 1)
+
+/* key threshold */
+#define THRESHOLD_LONG 2000
+
+enum KeyType { GPIO_KEY = 0, ADC_KEY, KEY_TYPE_NUM };
+
+enum GpioLevel { LOW = 0, HIGH };
+
+enum KeyState {
+ UP = 0,
+ DOWN,
+};
+
+struct xReportEvent {
+ uint32_t ulCode;
+ uint32_t event;
+ TickType_t responseTime;
+ void *data;
+};
+
+typedef void (*CallBack_t)(struct xReportEvent arg);
+
+struct xKeyInitInfo {
+ uint32_t ulKeyId;
+ uint32_t eventMask;
+ uint32_t repeatTimeMs;
+ uint32_t repeatDelayTimeMs;
+ uint32_t longDTTMs;
+ uint32_t doubleDTTMs;
+ uint32_t combLongDTTMs;
+ uint32_t combDTTMs;
+ CallBack_t CallBack;
+ void *data;
+};
+
+struct xGpioKeyInfo {
+ int ulInitLevel;
+ struct xKeyInitInfo keyInitInfo;
+};
+
+struct xAdcKeyInfo {
+ int32_t ulValue;
+ struct AdcInstanceConfig xAdcDecp;
+ struct xKeyInitInfo keyInitInfo;
+};
+
+#define KEY_INIT_INFO(_ulKeyId, _eventMask, _repeatTimeMs, _repeatDelayTimeMs, _longDTTMs, \
+ _doubleDTTMs, _combLongDTTMs, _combDTTMs, _CallBack, _data) \
+ { \
+ .ulKeyId = _ulKeyId, .eventMask = _eventMask, .repeatTimeMs = _repeatTimeMs, \
+ .repeatDelayTimeMs = _repeatDelayTimeMs, .longDTTMs = _longDTTMs, \
+ .doubleDTTMs = _doubleDTTMs, .combLongDTTMs = _combLongDTTMs, \
+ .combDTTMs = _combDTTMs, .CallBack = _CallBack, .data = _data, \
+ }
+
+#define GPIO_KEY_INFO(_ulKeyId, _ulInitLevel, _eventMask, _CallBack, _data) \
+ { \
+ .ulInitLevel = _ulInitLevel, \
+ .keyInitInfo = \
+ KEY_INIT_INFO(_ulKeyId, _eventMask, 0, 0, 0, 0, 0, 0, _CallBack, _data), \
+ }
+
+#define ADC_KEY_INFO(_ulKeyId, _ulValue, _adcChan, _eventMask, _CallBack, _data) \
+ { \
+ .ulValue = _ulValue, .xAdcDecp = { _adcChan, NO_AVERAGING, 1 }, \
+ .keyInitInfo = \
+ KEY_INIT_INFO(_ulKeyId, _eventMask, 0, 0, 0, 0, 0, 0, _CallBack, _data), \
+ }
+
+void vCreateGpioKey(struct xGpioKeyInfo *keyArr, uint16_t keyNum);
+void vDestroyGpioKey(void);
+void vGpioKeyEnable(void);
+void vGpioKeyDisable(void);
+int vGpioKeyIsEmpty(void);
+
+void vCreateAdcKey(struct xAdcKeyInfo *keyArr, uint16_t keyNum);
+void vDestroyAdcKey(void);
+void vAdcKeyEnable(void);
+void vAdcKeyDisable(void);
+int vAdcKeyIsEmpty(void);
+
+void vKeyPadCreate(void);
+void vKeyPadInit(void);
+void vKeyPadDeinit(void);
+
+void vDynamicKeypadInit(void);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/be301_t950s/leds_plat.c b/be301_t950s/leds_plat.c
new file mode 100644
index 0000000..de92a5e
--- /dev/null
+++ b/be301_t950s/leds_plat.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "FreeRTOS.h"
+#include <gpio.h>
+#include <leds_plat.h>
+#include <leds_state.h>
+
+/* TODO: Temporarily use static variables instead of stick mem */
+static int32_t LedStickMem0;
+//static int32_t LedStickMem1;
+
+static struct LedCoord BreathInflections0[] = { { 0, 0 }, { 2500, 255 }, { 5000, 0 } };
+
+static struct LedCoord BreathInflections1[] = { { 0, 0 }, { 5000, 255 }, { 10000, 0 } };
+
+static struct LedCoord BreathInflections2[] = { { 0, 0 }, { 10000, 255 }, { 20000, 0 } };
+
+static struct LedCoord BreathInflections3[] = { { 0, 0 }, { 20000, 255 }, { 40000, 0 } };
+
+struct LedCoord *BreathInflections[LED_BREATH_MAX_COUNT] = {
+ BreathInflections0,
+ BreathInflections1,
+ BreathInflections2,
+ BreathInflections3,
+};
+
+struct LedDevice MesonLeds[] = {
+ {
+ .id = LED_ID_0,
+ .type = LED_TYPE_PWM,
+ .name = "sys_led",
+ .hardware_id = MESON_PWM_AO_C,
+ .polarity = LED_POLARITY_POSITIVE,
+ .breathtime = 0,
+ },
+};
+
+int32_t get_led_breath_len(uint32_t breath_id)
+{
+ switch (breath_id) {
+ case 0:
+ return sizeof(BreathInflections0) / sizeof(struct LedCoord);
+ case 1:
+ return sizeof(BreathInflections1) / sizeof(struct LedCoord);
+ case 2:
+ return sizeof(BreathInflections2) / sizeof(struct LedCoord);
+ case 3:
+ return sizeof(BreathInflections3) / sizeof(struct LedCoord);
+ } /* end switch */
+
+ iprintf("%s: id: %ld leds state init!\n", DRIVER_NAME, breath_id);
+
+ return -pdFREERTOS_ERRNO_EINVAL;
+}
+
+int32_t vLedPlatInit(int32_t **stickmem)
+{
+ /* TODO: Here is initialization stickmem, but not doing so now */
+ *stickmem = &LedStickMem0;
+
+ /* off by default */
+ return xLedsStateSetBrightness(LED_ID_0, LED_OFF);
+}
+
+int32_t vLedPinmuxInit(void)
+{
+ /* set pinmux */
+ return xPinmuxSet(GPIOAO_8, PIN_FUNC4);
+}
diff --git a/be301_t950s/leds_plat.h b/be301_t950s/leds_plat.h
new file mode 100644
index 0000000..7f97196
--- /dev/null
+++ b/be301_t950s/leds_plat.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef _MESON_LEDS_PLAT_H_
+#define _MESON_LEDS_PLAT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * pwm t5d leds config
+ */
+#include <leds_state.h>
+#include <pwm_plat.h>
+
+#define LED_BREATH_MAX_COUNT 4
+
+extern struct LedDevice MesonLeds[];
+
+enum led_id {
+ LED_ID_0 = 0,
+ LED_ID_MAX,
+};
+
+int32_t get_led_breath_len(uint32_t breath_id);
+int32_t vLedPinmuxInit(void);
+int32_t vLedPlatInit(int32_t **stickmem);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _MESON_LED_PLAT_H_ */
diff --git a/be301_t950s/lscript.h b/be301_t950s/lscript.h
new file mode 100644
index 0000000..d74a85f
--- /dev/null
+++ b/be301_t950s/lscript.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef _LSCRIPT_H_
+#define _LSCRIPT_H_
+
+#define configMEM_START 0x10000000
+#define configMEM_LEN (64 * 1024)
+
+#endif
diff --git a/be301_t950s/lscript.ld b/be301_t950s/lscript.ld
new file mode 100644
index 0000000..0fe2b4f
--- /dev/null
+++ b/be301_t950s/lscript.ld
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv",
+ "elf32-littleriscv")
+OUTPUT_ARCH("riscv")
+ENTRY( _start )
+MEMORY
+{
+ ram (rw) : ORIGIN = 0x10000000, LENGTH = (64 * 1024)
+}
+SECTIONS
+{
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
+ .text :
+ {
+ . = ALIGN(4);
+ PROVIDE( _text = . );
+ *(.init)
+ *(.text* .rodata*)
+ . = ALIGN(0x100);
+ PROVIDE( _etext = . );
+ *(.vtable)
+ } > ram
+ .data :
+ {
+ _data = .;
+ *(vtable)
+ *(.sdata* .data*)
+ _edata = .;
+ } > ram
+ .bss :
+ {
+ _bss = .;
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ . = ALIGN(4);
+ _ebss = .;
+ } > ram
+ .stack :
+ {
+ PROVIDE( _stack = . );
+ . = ALIGN(1024);
+ . += __stack_size;
+ PROVIDE( _sp = . );
+ } >ram
+}
diff --git a/be301_t950s/power.c b/be301_t950s/power.c
new file mode 100644
index 0000000..83cec03
--- /dev/null
+++ b/be301_t950s/power.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "common.h"
+#include "gpio.h"
+#include "ir.h"
+#include "eth.h"
+#include "suspend.h"
+#include "task.h"
+#include "gpio.h"
+#include "pwm.h"
+#include "pwm_plat.h"
+#include "keypad.h"
+#include "hdmi_cec.h"
+#include "power.h"
+
+static TaskHandle_t cecTask;
+static int vdd_ee;
+static int vdd_cpu;
+
+static struct IRPowerKey prvPowerKeyList[] = {
+ { 0xef10fe01, IR_NORMAL }, /* ref tv pwr */
+ { 0xba45bd02, IR_NORMAL }, /* small ir pwr */
+ { 0xef10fb04, IR_NORMAL }, /* old ref tv pwr */
+ { 0xf20dfe01, IR_NORMAL },
+ { 0xe51afb04, IR_NORMAL },
+ { 0xff00fe06, IR_NORMAL },
+ { 0x3ac5bd02, IR_CUSTOM },
+ {}
+ /* add more */
+};
+
+static void vIRHandler(struct IRPowerKey *pkey)
+{
+ uint32_t buf[4] = { 0 };
+
+ if (pkey->type == IR_NORMAL)
+ buf[0] = REMOTE_WAKEUP;
+ else if (pkey->type == IR_CUSTOM)
+ buf[0] = REMOTE_CUS_WAKEUP;
+
+ /* do sth below to wakeup*/
+ STR_Wakeup_src_Queue_Send_FromISR(buf);
+};
+
+void str_hw_init(void)
+{
+ /*enable device & wakeup source interrupt*/
+ //vIRInit(MODE_HARD_NEC, GPIOD_5, PIN_FUNC1, prvPowerKeyList, ARRAY_SIZE(prvPowerKeyList),
+ // vIRHandler);
+ vETHInit(1);
+ //xTaskCreate(vCEC_task, "CECtask", configMINIMAL_STACK_SIZE, NULL, CEC_TASK_PRI, &cecTask);
+ vBackupAndClearGpioIrqReg();
+ vKeyPadInit();
+ vGpioIRQInit();
+ //Bt_GpioIRQRegister();
+}
+
+void str_hw_disable(void)
+{
+ /*disable wakeup source interrupt*/
+ vIRDeint();
+ vETHDeint();
+ //if (cecTask) {
+ // vTaskDelete(cecTask);
+ // cec_req_irq(0);
+ //}
+ //Bt_GpioIRQFree();
+ vKeyPadDeinit();
+ vRestoreGpioIrqReg();
+}
+
+void str_power_on(int shutdown_flag)
+{
+ int ret;
+
+ /***set vdd_ee val***/
+ ret = vPwmMesonsetvoltage(VDDEE_VOLT, vdd_ee);
+ if (ret < 0) {
+ printf("vdd_EE pwm set fail\n");
+ return;
+ }
+
+ /***set vdd_ee val***/
+ ret = vPwmMesonsetvoltage(VDDCPU_VOLT, vdd_cpu);
+ if (ret < 0) {
+ printf("vdd_CPU pwm set fail\n");
+ return;
+ }
+
+ /***power on vcc3.3***/
+ //ret = xGpioSetDir(GPIOD_10, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_10, GPIO_LEVEL_HIGH);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio val fail\n");
+ // return;
+ //}
+
+ if (shutdown_flag) {
+ /***power on VDDQ/VDDCPU***/
+ //ret = xGpioSetDir(GPIOD_4, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_4, GPIO_LEVEL_HIGH);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio val fail\n");
+ // return;
+ //}
+ /*Wait 10ms for VDDCPU statable*/
+ vTaskDelay(pdMS_TO_TICKS(10));
+ }
+
+ /***power on 5v***/
+ REG32(AO_GPIO_TEST_N) = REG32(AO_GPIO_TEST_N) | (1 << 31);
+}
+
+void str_power_off(int shutdown_flag)
+{
+ int ret;
+
+ printf("poweroff 5v\n");
+ printf("0x%x\n", REG32(AO_GPIO_TEST_N));
+
+ REG32(AO_GPIO_TEST_N) = (REG32(AO_GPIO_TEST_N) << 1) >> 1;
+
+ if (shutdown_flag) {
+ /***power off VDDQ/VDDCPU***/
+ //ret = xGpioSetDir(GPIOD_4, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_4, GPIO_LEVEL_LOW);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio val fail\n");
+ // return;
+ //}
+ }
+
+ /***power off vcc3.3***/
+ //ret = xGpioSetDir(GPIOD_10, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio dir fail\n");
+ // return;
+ //}
+
+ if (get_ETHWol_flag() == 0) {
+ //ret = xGpioSetValue(GPIOD_10, GPIO_LEVEL_LOW);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio val fail\n");
+ // return;
+ //}
+ }
+
+ /***set vdd_cpu val***/
+ vdd_cpu = vPwmMesongetvoltage(VDDCPU_VOLT);
+ if (vdd_cpu < 0) {
+ printf("vdd_CPU pwm get fail\n");
+ return;
+ }
+
+ ret = vPwmMesonsetvoltage(VDDCPU_VOLT, 700);
+ if (ret < 0) {
+ printf("vdd_CPU pwm set fail\n");
+ return;
+ }
+
+ /***set vdd_ee val***/
+ vdd_ee = vPwmMesongetvoltage(VDDEE_VOLT);
+ if (vdd_ee < 0) {
+ printf("vdd_EE pwm get fail\n");
+ return;
+ }
+
+ ret = vPwmMesonsetvoltage(VDDEE_VOLT, 770);
+ if (ret < 0) {
+ printf("vdd_EE pwm set fail\n");
+ return;
+ }
+
+ //REG32( ((0x0000 << 2) + 0xff638c00)) = 0;
+}
diff --git a/be301_t950s/power.h b/be301_t950s/power.h
new file mode 100644
index 0000000..ea41f71
--- /dev/null
+++ b/be301_t950s/power.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __POWER_H__
+#define __POWER_H__
+
+void str_hw_init(void);
+
+void str_hw_disable(void);
+
+void str_power_on(int shutdown_flag);
+
+void str_power_off(int shutdown_flag);
+
+void Bt_GpioIRQRegister(void);
+
+void Bt_GpioIRQFree(void);
+
+
+#endif
diff --git a/be309_t950s/CMakeLists.txt b/be309_t950s/CMakeLists.txt
new file mode 100644
index 0000000..0e2e79d
--- /dev/null
+++ b/be309_t950s/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+aml_library_include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+aml_library_sources(
+ fsm.c
+ # btwake.c
+ keypad.c
+ power.c
+ hw_business.c
+)
+
+aml_library_sources_ifdef(
+ CONFIG_LEDS
+ leds_plat.c
+)
diff --git a/be309_t950s/FreeRTOSConfig.h b/be309_t950s/FreeRTOSConfig.h
new file mode 100644
index 0000000..f72f6cf
--- /dev/null
+++ b/be309_t950s/FreeRTOSConfig.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include <stdio.h>
+
+#define USER_MODE_TASKS 0
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configUSE_TICKLESS_IDLE 0
+#define configCPU_CLOCK_HZ 24000000 //32768
+#define configTICK_RATE_HZ 50
+#define configMAX_PRIORITIES 4
+#define configMINIMAL_STACK_SIZE 450
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_TASK_NOTIFICATIONS 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 0
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 10
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 1
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 0
+#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
+
+/* Memory allocation related definitions. */
+#define configSUPPORT_STATIC_ALLOCATION 0
+#define configSUPPORT_DYNAMIC_ALLOCATION 1
+#define configTOTAL_HEAP_SIZE (22 * 1024)
+#define configAPPLICATION_ALLOCATED_HEAP 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configCHECK_FOR_STACK_OVERFLOW 0
+#define configUSE_MALLOC_FAILED_HOOK 0
+#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 0
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine related definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 1
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY 1
+#define configTIMER_QUEUE_LENGTH 10
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Interrupt nesting behaviour configuration. */
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 6
+#define configMAX_API_CALL_INTERRUPT_PRIORITY 6
+
+#define configDEFAULT_HEAP_ADDR 0xfffc0000
+#define configDEFAULT_HEAP_SIZE (26 * 1024)
+#define configSTICK_REG_ADDR (configDEFAULT_HEAP_ADDR + configDEFAULT_HEAP_SIZE)
+#define configSTICK_REG_SIZE 128
+
+#define portCRITICAL_NESTING_IN_TCB 1
+
+/* Define to trap errors during development. */
+#define configASSERT(x) \
+ do { \
+ if ((x) == 0) { \
+ taskDISABLE_INTERRUPTS(); \
+ printf("ASSERT: %s %d\n", __FILE__, __LINE__); \
+ for (;;) \
+ ; \
+ } \
+ } while (0)
+
+/* FreeRTOS MPU specific definitions. */
+//#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_xResumeFromISR 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 1
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 1
+#define INCLUDE_xTaskGetIdleTaskHandle 1
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 1
+#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_xTaskAbortDelay 0
+#define INCLUDE_xTaskGetHandle 1
+#define INCLUDE_xTaskResumeFromISR 1
+
+#define configCLINT_BASE_ADDRESS 0x02000000UL
+/* A header file that defines trace macro can be included here. */
+
+#endif /* FREERTOS_CONFIG_H */
diff --git a/be309_t950s/Kconfig b/be309_t950s/Kconfig
new file mode 100644
index 0000000..fc3edfb
--- /dev/null
+++ b/be309_t950s/Kconfig
@@ -0,0 +1,28 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+config BOARD_BE309_T950S
+ bool "Amlogic BE309_T950S Board"
+ select SOC_TXHD2
+ select LIBC_AML
+ select COMMON
+ select GET_VERSION
+ select STICK_MEM
+ select UART
+ # select CEC
+ select DDR
+ select MAILBOX
+ select VRTC
+ select STR
+ select GPIO
+ select KEY
+ select PWM
+ # select LEDS
+ select TIMER_SOURCE
+ select SARADC
+ select IR
+ select ETHERNET
+ select VERSION_FULL_INFO
+ help
+ Enable Amlogic BE309_T950S Board.
diff --git a/be309_t950s/btwake.c b/be309_t950s/btwake.c
new file mode 100644
index 0000000..bab28d5
--- /dev/null
+++ b/be309_t950s/btwake.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "suspend.h"
+#include "task.h"
+#include "gpio.h"
+
+#include "queue.h" /* RTOS queue related API prototypes. */
+#include "timers.h" /* Software timer related API prototypes. */
+#include "semphr.h" /* Semaphore related API prototypes. */
+
+#define BT_WAKE_HOST GPIOB_13 //bt_wake_host pin
+#define INFO(fmt, args...) printf("[%s] " fmt "\n", __func__, ##args)
+
+void Bt_IRQHandle(void)
+{
+ uint32_t buf[4] = { 0 };
+
+ INFO("bt resume");
+ vDisableGpioIRQ(BT_WAKE_HOST);
+ if (!xGpioGetValue(BT_WAKE_HOST)) {
+ buf[0] = BT_WAKEUP;
+ INFO("power key");
+ STR_Wakeup_src_Queue_Send_FromISR(buf);
+ }
+}
+
+void Bt_GpioIRQRegister(void)
+{
+ INFO();
+ xGpioSetDir(BT_WAKE_HOST, GPIO_DIR_IN);
+ xRequestGpioIRQ(BT_WAKE_HOST, Bt_IRQHandle, IRQF_TRIGGER_FALLING);
+}
+
+void Bt_GpioIRQFree(void)
+{
+ vFreeGpioIRQ(BT_WAKE_HOST);
+}
diff --git a/be309_t950s/compiler_options.cmake b/be309_t950s/compiler_options.cmake
new file mode 100644
index 0000000..3d11a1f
--- /dev/null
+++ b/be309_t950s/compiler_options.cmake
@@ -0,0 +1,5 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+#add compiler options at here which is associated with current board.
diff --git a/be309_t950s/defconfig b/be309_t950s/defconfig
new file mode 100644
index 0000000..3bbc4be
--- /dev/null
+++ b/be309_t950s/defconfig
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: MIT
+#
+
+CONFIG_BOARD_BE309_T950S=y
+
diff --git a/be309_t950s/fsm.c b/be309_t950s/fsm.c
new file mode 100644
index 0000000..27b34c5
--- /dev/null
+++ b/be309_t950s/fsm.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "FreeRTOS.h" /* Must come first. */
+#include "task.h" /* RTOS task related API prototypes. */
+#include "queue.h" /* RTOS queue related API prototypes. */
+#include "timers.h" /* Software timer related API prototypes. */
+#include "semphr.h" /* Semaphore related API prototypes. */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "n200_func.h"
+#include "common.h"
+#include "riscv_encoding.h"
+#include "mailbox-api.h"
+#include "irq.h"
+
+enum PM_E {
+ PM_CPU_PWR,
+ PM_CPU_CORE0,
+ PM_CPU_CORE1,
+ PM_CPU_CORE2,
+ PM_CPU_CORE3,
+};
+
+static void *xMboxCoreFsmIdle(void *msg)
+{
+ enum PM_E domain = *(uint32_t *)msg;
+
+ switch (domain) {
+ case PM_CPU_CORE0:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 0), 0);
+ EnableIrq(IRQ_NUM_OUT_0);
+ break;
+ case PM_CPU_CORE1:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 1), 0);
+ EnableIrq(IRQ_NUM_OUT_1);
+ break;
+ case PM_CPU_CORE2:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 2), 0);
+ EnableIrq(IRQ_NUM_OUT_2);
+ break;
+ case PM_CPU_CORE3:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 3), 0);
+ EnableIrq(IRQ_NUM_OUT_3);
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static void xSetCoreFsmAwakeIrq(int cpuid)
+{
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << cpuid), (1 << cpuid));
+}
+
+static void xCore0FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(0);
+ DisableIrq(IRQ_NUM_OUT_0);
+}
+
+static void xCore1FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(1);
+ DisableIrq(IRQ_NUM_OUT_1);
+}
+
+static void xCore2FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(2);
+ DisableIrq(IRQ_NUM_OUT_2);
+}
+
+static void xCore3FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(3);
+ DisableIrq(IRQ_NUM_OUT_3);
+}
+
+void vCoreFsmIdleInit(void)
+{
+ int ret;
+
+ ret = xInstallRemoteMessageCallbackFeedBack(AOTEE_CHANNEL, MBX_CMD_CPU_FSM_IDLE,
+ xMboxCoreFsmIdle, 0);
+ if (ret == MBOX_CALL_MAX)
+ printf("mbox cmd 0x%x register fail\n", MBX_CMD_CPU_FSM_IDLE);
+
+ RegisterIrq(IRQ_NUM_OUT_0, 1, xCore0FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_1, 1, xCore1FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_2, 1, xCore2FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_3, 1, xCore3FsmIdleHandleIsr);
+ REG32_UPDATE_BITS(SEC_SYS_CPU_CFG10, 0xF << 10, 0xF << 10);
+}
diff --git a/be309_t950s/fsm.h b/be309_t950s/fsm.h
new file mode 100644
index 0000000..86a1f01
--- /dev/null
+++ b/be309_t950s/fsm.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __FSM_H__
+#define __FSM_H__
+
+void vCoreFsmIdleInit(void);
+extern void vRtcInit(void);
+extern void create_str_task(void);
+extern void trap_entry(void);
+extern void irq_entry(void);
+
+#endif
diff --git a/be309_t950s/hw_business.c b/be309_t950s/hw_business.c
new file mode 100644
index 0000000..6d525cf
--- /dev/null
+++ b/be309_t950s/hw_business.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "semphr.h"
+#include "hw_business.h"
+#include "n200_eclic.h"
+#include "n200_func.h"
+#include "uart.h"
+#include "eth.h"
+#include "common.h"
+#include "mailbox-api.h"
+#include "hdmi_cec.h"
+#include "stick_mem.h"
+#include "keypad.h"
+#include "fsm.h"
+
+#define INT_TEST_NEST_DEPTH 6
+#define INT_TEST_GPIO_NUM 6
+#define INT_TEST_TASK_DELAY 50 // ms
+#define TASK_TEST_STACK_DEPTH 200
+
+#define TASK_TEST_QUEUE_NUM 2
+#define TASK_TEST_QUEUE_LENGTH 3
+
+//#define GPIO_INT_SOURCE(x) (SOC_PIC_INT_GPIO_BASE + x)
+
+/* Configure board type:
+ * Board under test : SIGNAL_BOARD_ENABLE 0
+ * Signal generation board : SIGNAL_BOARD_ENABLE 1
+ */
+#define SIGNAL_BOARD_ENABLE 0
+
+#define INT_TEST_INT_WAVE_ENABLE 1
+
+#if INT_TEST_INT_WAVE_ENABLE
+ #define INT_TEST_TIMER_PERIOD 500 // ms
+ #define INT_TEST_INT_DELAY 10 // ms
+#else
+ #define INT_TEST_TIMER_PERIOD 500 // ms
+ #define INT_TEST_INT_DELAY 0x3ff // ms
+#endif
+
+#define INT_TEST_MAX_TIMER_PERIOD 100 // ms
+#define INT_TEST_MIN_TIMER_PERIOD 50 // ms
+#define INT_TEST_MUTE_TIMER_PERIOD 200 // ms
+
+#define RTOS_BOOT_SUCC_REG AO_DEBUG_REG2
+
+/* Binary Semaphore */
+QueueHandle_t xGPIOSemaphore[INT_TEST_NEST_DEPTH];
+QueueHandle_t xMessageQueue[TASK_TEST_QUEUE_NUM];
+
+void config_eclic_irqs(void)
+{
+ eclic_init(ECLIC_NUM_INTERRUPTS);
+ eclic_set_nlbits(0);
+}
+
+void hw_business_process(void)
+{
+ uint8_t i = 0;
+
+ // Initialize GPIOs, PIC and timer
+ //vGPIOInit();
+ config_eclic_irqs();
+ for (i = 0; i < 8; ++i)
+ printf("AOCPU_IRQ_SEL=0x%x\n", REG32(AOCPU_IRQ_SEL0 + i * 4));
+
+ stick_mem_init();
+ //write watchdog flag
+ stick_mem_write(STICK_REBOOT_FLAG, 0xd);
+
+ // Delay
+ for (uint32_t i = 0; i < 0xffff; ++i)
+ ;
+
+ vMbInit();
+ vCoreFsmIdleInit();
+ // vCecCallbackInit(CEC_CHIP_T5);
+ vRtcInit();
+ vETHMailboxCallback();
+ create_str_task();
+ vKeyPadCreate();
+}
+
+void aocpu_bringup_finished(void)
+{
+ #define RTOS_RUN_SUCC (1 << 0)
+ *(volatile uint32_t *)RTOS_BOOT_SUCC_REG |= RTOS_RUN_SUCC;
+}
+
diff --git a/be309_t950s/hw_business.h b/be309_t950s/hw_business.h
new file mode 100644
index 0000000..2dc1d61
--- /dev/null
+++ b/be309_t950s/hw_business.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __hW_BUSINESS_H__
+#define __hW_BUSINESS_H__
+
+void hw_business_process(void);
+
+#endif
diff --git a/be309_t950s/keypad.c b/be309_t950s/keypad.c
new file mode 100644
index 0000000..7406fb1
--- /dev/null
+++ b/be309_t950s/keypad.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "ir.h"
+#include "keypad.h"
+#include "gpio.h"
+#include "saradc.h"
+#include "suspend.h"
+
+/*KEY ID*/
+#define ADC_KEY_ID_HOME 520
+
+static void vAdcKeyCallBack(struct xReportEvent event)
+{
+ uint32_t buf[4] = { 0 };
+
+ switch (event.ulCode) {
+ case ADC_KEY_ID_HOME:
+ buf[0] = POWER_KEY_WAKEUP;
+ STR_Wakeup_src_Queue_Send(buf);
+ break;
+ default:
+ break;
+ }
+
+ printf("ADC key event 0x%x, key code %d, responseTicks %d\n", event.event, event.ulCode,
+ event.responseTime);
+}
+
+struct xAdcKeyInfo adcKeyInfo[] = { ADC_KEY_INFO(ADC_KEY_ID_HOME, 0, SARADC_CH1, EVENT_SHORT,
+ vAdcKeyCallBack, NULL) };
+
+void vKeyPadCreate(void)
+{
+ vCreateAdcKey(adcKeyInfo, sizeof(adcKeyInfo) / sizeof(struct xAdcKeyInfo));
+
+ vDynamicKeypadInit();
+}
+
+void vKeyPadInit(void)
+{
+ if (vAdcKeyIsEmpty())
+ vCreateAdcKey(adcKeyInfo, sizeof(adcKeyInfo) / sizeof(struct xAdcKeyInfo));
+
+ vAdcKeyEnable();
+ vGpioKeyEnable();
+}
+
+void vKeyPadDeinit(void)
+{
+ vAdcKeyDisable();
+ vGpioKeyDisable();
+}
diff --git a/be309_t950s/keypad.h b/be309_t950s/keypad.h
new file mode 100644
index 0000000..e496629
--- /dev/null
+++ b/be309_t950s/keypad.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __MESON_Button_H
+#define __MESON_Button_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "common.h"
+#include <stdlib.h>
+#include <string.h>
+#include "FreeRTOS.h"
+#include <timers.h>
+#include <task.h>
+#include <gpio.h>
+#include <saradc.h>
+
+/*common macro*/
+#define TIMER_CYCLE_TIME 100
+#define KEY_JITTER_COUNT 1
+
+/* adc key param */
+#define SAMPLE_DEVIATION 40
+#define ADCKEY_ID_BASE 512
+
+/* key event */
+#define EVENT_SHORT (1 << 0)
+#define EVENT_LONG (1 << 1)
+
+/* key threshold */
+#define THRESHOLD_LONG 2000
+
+enum KeyType { GPIO_KEY = 0, ADC_KEY, KEY_TYPE_NUM };
+
+enum GpioLevel { LOW = 0, HIGH };
+
+enum KeyState {
+ UP = 0,
+ DOWN,
+};
+
+struct xReportEvent {
+ uint32_t ulCode;
+ uint32_t event;
+ TickType_t responseTime;
+ void *data;
+};
+
+typedef void (*CallBack_t)(struct xReportEvent arg);
+
+struct xKeyInitInfo {
+ uint32_t ulKeyId;
+ uint32_t eventMask;
+ uint32_t repeatTimeMs;
+ uint32_t repeatDelayTimeMs;
+ uint32_t longDTTMs;
+ uint32_t doubleDTTMs;
+ uint32_t combLongDTTMs;
+ uint32_t combDTTMs;
+ CallBack_t CallBack;
+ void *data;
+};
+
+struct xGpioKeyInfo {
+ int ulInitLevel;
+ struct xKeyInitInfo keyInitInfo;
+};
+
+struct xAdcKeyInfo {
+ int32_t ulValue;
+ struct AdcInstanceConfig xAdcDecp;
+ struct xKeyInitInfo keyInitInfo;
+};
+
+#define KEY_INIT_INFO(_ulKeyId, _eventMask, _repeatTimeMs, _repeatDelayTimeMs, _longDTTMs, \
+ _doubleDTTMs, _combLongDTTMs, _combDTTMs, _CallBack, _data) \
+ { \
+ .ulKeyId = _ulKeyId, .eventMask = _eventMask, .repeatTimeMs = _repeatTimeMs, \
+ .repeatDelayTimeMs = _repeatDelayTimeMs, .longDTTMs = _longDTTMs, \
+ .doubleDTTMs = _doubleDTTMs, .combLongDTTMs = _combLongDTTMs, \
+ .combDTTMs = _combDTTMs, .CallBack = _CallBack, .data = _data, \
+ }
+
+#define GPIO_KEY_INFO(_ulKeyId, _ulInitLevel, _eventMask, _CallBack, _data) \
+ { \
+ .ulInitLevel = _ulInitLevel, \
+ .keyInitInfo = \
+ KEY_INIT_INFO(_ulKeyId, _eventMask, 0, 0, 0, 0, 0, 0, _CallBack, _data), \
+ }
+
+#define ADC_KEY_INFO(_ulKeyId, _ulValue, _adcChan, _eventMask, _CallBack, _data) \
+ { \
+ .ulValue = _ulValue, .xAdcDecp = { _adcChan, NO_AVERAGING, 1 }, \
+ .keyInitInfo = \
+ KEY_INIT_INFO(_ulKeyId, _eventMask, 0, 0, 0, 0, 0, 0, _CallBack, _data), \
+ }
+
+void vCreateGpioKey(struct xGpioKeyInfo *keyArr, uint16_t keyNum);
+void vDestroyGpioKey(void);
+void vGpioKeyEnable(void);
+void vGpioKeyDisable(void);
+int vGpioKeyIsEmpty(void);
+
+void vCreateAdcKey(struct xAdcKeyInfo *keyArr, uint16_t keyNum);
+void vDestroyAdcKey(void);
+void vAdcKeyEnable(void);
+void vAdcKeyDisable(void);
+int vAdcKeyIsEmpty(void);
+
+void vKeyPadCreate(void);
+void vKeyPadInit(void);
+void vKeyPadDeinit(void);
+
+void vDynamicKeypadInit(void);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/be309_t950s/leds_plat.c b/be309_t950s/leds_plat.c
new file mode 100644
index 0000000..de92a5e
--- /dev/null
+++ b/be309_t950s/leds_plat.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "FreeRTOS.h"
+#include <gpio.h>
+#include <leds_plat.h>
+#include <leds_state.h>
+
+/* TODO: Temporarily use static variables instead of stick mem */
+static int32_t LedStickMem0;
+//static int32_t LedStickMem1;
+
+static struct LedCoord BreathInflections0[] = { { 0, 0 }, { 2500, 255 }, { 5000, 0 } };
+
+static struct LedCoord BreathInflections1[] = { { 0, 0 }, { 5000, 255 }, { 10000, 0 } };
+
+static struct LedCoord BreathInflections2[] = { { 0, 0 }, { 10000, 255 }, { 20000, 0 } };
+
+static struct LedCoord BreathInflections3[] = { { 0, 0 }, { 20000, 255 }, { 40000, 0 } };
+
+struct LedCoord *BreathInflections[LED_BREATH_MAX_COUNT] = {
+ BreathInflections0,
+ BreathInflections1,
+ BreathInflections2,
+ BreathInflections3,
+};
+
+struct LedDevice MesonLeds[] = {
+ {
+ .id = LED_ID_0,
+ .type = LED_TYPE_PWM,
+ .name = "sys_led",
+ .hardware_id = MESON_PWM_AO_C,
+ .polarity = LED_POLARITY_POSITIVE,
+ .breathtime = 0,
+ },
+};
+
+int32_t get_led_breath_len(uint32_t breath_id)
+{
+ switch (breath_id) {
+ case 0:
+ return sizeof(BreathInflections0) / sizeof(struct LedCoord);
+ case 1:
+ return sizeof(BreathInflections1) / sizeof(struct LedCoord);
+ case 2:
+ return sizeof(BreathInflections2) / sizeof(struct LedCoord);
+ case 3:
+ return sizeof(BreathInflections3) / sizeof(struct LedCoord);
+ } /* end switch */
+
+ iprintf("%s: id: %ld leds state init!\n", DRIVER_NAME, breath_id);
+
+ return -pdFREERTOS_ERRNO_EINVAL;
+}
+
+int32_t vLedPlatInit(int32_t **stickmem)
+{
+ /* TODO: Here is initialization stickmem, but not doing so now */
+ *stickmem = &LedStickMem0;
+
+ /* off by default */
+ return xLedsStateSetBrightness(LED_ID_0, LED_OFF);
+}
+
+int32_t vLedPinmuxInit(void)
+{
+ /* set pinmux */
+ return xPinmuxSet(GPIOAO_8, PIN_FUNC4);
+}
diff --git a/be309_t950s/leds_plat.h b/be309_t950s/leds_plat.h
new file mode 100644
index 0000000..7f97196
--- /dev/null
+++ b/be309_t950s/leds_plat.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef _MESON_LEDS_PLAT_H_
+#define _MESON_LEDS_PLAT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * pwm t5d leds config
+ */
+#include <leds_state.h>
+#include <pwm_plat.h>
+
+#define LED_BREATH_MAX_COUNT 4
+
+extern struct LedDevice MesonLeds[];
+
+enum led_id {
+ LED_ID_0 = 0,
+ LED_ID_MAX,
+};
+
+int32_t get_led_breath_len(uint32_t breath_id);
+int32_t vLedPinmuxInit(void);
+int32_t vLedPlatInit(int32_t **stickmem);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _MESON_LED_PLAT_H_ */
diff --git a/be309_t950s/lscript.h b/be309_t950s/lscript.h
new file mode 100644
index 0000000..d74a85f
--- /dev/null
+++ b/be309_t950s/lscript.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef _LSCRIPT_H_
+#define _LSCRIPT_H_
+
+#define configMEM_START 0x10000000
+#define configMEM_LEN (64 * 1024)
+
+#endif
diff --git a/be309_t950s/lscript.ld b/be309_t950s/lscript.ld
new file mode 100644
index 0000000..0fe2b4f
--- /dev/null
+++ b/be309_t950s/lscript.ld
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv",
+ "elf32-littleriscv")
+OUTPUT_ARCH("riscv")
+ENTRY( _start )
+MEMORY
+{
+ ram (rw) : ORIGIN = 0x10000000, LENGTH = (64 * 1024)
+}
+SECTIONS
+{
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
+ .text :
+ {
+ . = ALIGN(4);
+ PROVIDE( _text = . );
+ *(.init)
+ *(.text* .rodata*)
+ . = ALIGN(0x100);
+ PROVIDE( _etext = . );
+ *(.vtable)
+ } > ram
+ .data :
+ {
+ _data = .;
+ *(vtable)
+ *(.sdata* .data*)
+ _edata = .;
+ } > ram
+ .bss :
+ {
+ _bss = .;
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ . = ALIGN(4);
+ _ebss = .;
+ } > ram
+ .stack :
+ {
+ PROVIDE( _stack = . );
+ . = ALIGN(1024);
+ . += __stack_size;
+ PROVIDE( _sp = . );
+ } >ram
+}
diff --git a/be309_t950s/power.c b/be309_t950s/power.c
new file mode 100644
index 0000000..83cec03
--- /dev/null
+++ b/be309_t950s/power.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "common.h"
+#include "gpio.h"
+#include "ir.h"
+#include "eth.h"
+#include "suspend.h"
+#include "task.h"
+#include "gpio.h"
+#include "pwm.h"
+#include "pwm_plat.h"
+#include "keypad.h"
+#include "hdmi_cec.h"
+#include "power.h"
+
+static TaskHandle_t cecTask;
+static int vdd_ee;
+static int vdd_cpu;
+
+static struct IRPowerKey prvPowerKeyList[] = {
+ { 0xef10fe01, IR_NORMAL }, /* ref tv pwr */
+ { 0xba45bd02, IR_NORMAL }, /* small ir pwr */
+ { 0xef10fb04, IR_NORMAL }, /* old ref tv pwr */
+ { 0xf20dfe01, IR_NORMAL },
+ { 0xe51afb04, IR_NORMAL },
+ { 0xff00fe06, IR_NORMAL },
+ { 0x3ac5bd02, IR_CUSTOM },
+ {}
+ /* add more */
+};
+
+static void vIRHandler(struct IRPowerKey *pkey)
+{
+ uint32_t buf[4] = { 0 };
+
+ if (pkey->type == IR_NORMAL)
+ buf[0] = REMOTE_WAKEUP;
+ else if (pkey->type == IR_CUSTOM)
+ buf[0] = REMOTE_CUS_WAKEUP;
+
+ /* do sth below to wakeup*/
+ STR_Wakeup_src_Queue_Send_FromISR(buf);
+};
+
+void str_hw_init(void)
+{
+ /*enable device & wakeup source interrupt*/
+ //vIRInit(MODE_HARD_NEC, GPIOD_5, PIN_FUNC1, prvPowerKeyList, ARRAY_SIZE(prvPowerKeyList),
+ // vIRHandler);
+ vETHInit(1);
+ //xTaskCreate(vCEC_task, "CECtask", configMINIMAL_STACK_SIZE, NULL, CEC_TASK_PRI, &cecTask);
+ vBackupAndClearGpioIrqReg();
+ vKeyPadInit();
+ vGpioIRQInit();
+ //Bt_GpioIRQRegister();
+}
+
+void str_hw_disable(void)
+{
+ /*disable wakeup source interrupt*/
+ vIRDeint();
+ vETHDeint();
+ //if (cecTask) {
+ // vTaskDelete(cecTask);
+ // cec_req_irq(0);
+ //}
+ //Bt_GpioIRQFree();
+ vKeyPadDeinit();
+ vRestoreGpioIrqReg();
+}
+
+void str_power_on(int shutdown_flag)
+{
+ int ret;
+
+ /***set vdd_ee val***/
+ ret = vPwmMesonsetvoltage(VDDEE_VOLT, vdd_ee);
+ if (ret < 0) {
+ printf("vdd_EE pwm set fail\n");
+ return;
+ }
+
+ /***set vdd_ee val***/
+ ret = vPwmMesonsetvoltage(VDDCPU_VOLT, vdd_cpu);
+ if (ret < 0) {
+ printf("vdd_CPU pwm set fail\n");
+ return;
+ }
+
+ /***power on vcc3.3***/
+ //ret = xGpioSetDir(GPIOD_10, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_10, GPIO_LEVEL_HIGH);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio val fail\n");
+ // return;
+ //}
+
+ if (shutdown_flag) {
+ /***power on VDDQ/VDDCPU***/
+ //ret = xGpioSetDir(GPIOD_4, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_4, GPIO_LEVEL_HIGH);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio val fail\n");
+ // return;
+ //}
+ /*Wait 10ms for VDDCPU statable*/
+ vTaskDelay(pdMS_TO_TICKS(10));
+ }
+
+ /***power on 5v***/
+ REG32(AO_GPIO_TEST_N) = REG32(AO_GPIO_TEST_N) | (1 << 31);
+}
+
+void str_power_off(int shutdown_flag)
+{
+ int ret;
+
+ printf("poweroff 5v\n");
+ printf("0x%x\n", REG32(AO_GPIO_TEST_N));
+
+ REG32(AO_GPIO_TEST_N) = (REG32(AO_GPIO_TEST_N) << 1) >> 1;
+
+ if (shutdown_flag) {
+ /***power off VDDQ/VDDCPU***/
+ //ret = xGpioSetDir(GPIOD_4, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_4, GPIO_LEVEL_LOW);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio val fail\n");
+ // return;
+ //}
+ }
+
+ /***power off vcc3.3***/
+ //ret = xGpioSetDir(GPIOD_10, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio dir fail\n");
+ // return;
+ //}
+
+ if (get_ETHWol_flag() == 0) {
+ //ret = xGpioSetValue(GPIOD_10, GPIO_LEVEL_LOW);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio val fail\n");
+ // return;
+ //}
+ }
+
+ /***set vdd_cpu val***/
+ vdd_cpu = vPwmMesongetvoltage(VDDCPU_VOLT);
+ if (vdd_cpu < 0) {
+ printf("vdd_CPU pwm get fail\n");
+ return;
+ }
+
+ ret = vPwmMesonsetvoltage(VDDCPU_VOLT, 700);
+ if (ret < 0) {
+ printf("vdd_CPU pwm set fail\n");
+ return;
+ }
+
+ /***set vdd_ee val***/
+ vdd_ee = vPwmMesongetvoltage(VDDEE_VOLT);
+ if (vdd_ee < 0) {
+ printf("vdd_EE pwm get fail\n");
+ return;
+ }
+
+ ret = vPwmMesonsetvoltage(VDDEE_VOLT, 770);
+ if (ret < 0) {
+ printf("vdd_EE pwm set fail\n");
+ return;
+ }
+
+ //REG32( ((0x0000 << 2) + 0xff638c00)) = 0;
+}
diff --git a/be309_t950s/power.h b/be309_t950s/power.h
new file mode 100644
index 0000000..ea41f71
--- /dev/null
+++ b/be309_t950s/power.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __POWER_H__
+#define __POWER_H__
+
+void str_hw_init(void);
+
+void str_hw_disable(void);
+
+void str_power_on(int shutdown_flag);
+
+void str_power_off(int shutdown_flag);
+
+void Bt_GpioIRQRegister(void);
+
+void Bt_GpioIRQFree(void);
+
+
+#endif
diff --git a/be311_t950s/CMakeLists.txt b/be311_t950s/CMakeLists.txt
new file mode 100644
index 0000000..0e2e79d
--- /dev/null
+++ b/be311_t950s/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+aml_library_include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+aml_library_sources(
+ fsm.c
+ # btwake.c
+ keypad.c
+ power.c
+ hw_business.c
+)
+
+aml_library_sources_ifdef(
+ CONFIG_LEDS
+ leds_plat.c
+)
diff --git a/be311_t950s/FreeRTOSConfig.h b/be311_t950s/FreeRTOSConfig.h
new file mode 100644
index 0000000..f72f6cf
--- /dev/null
+++ b/be311_t950s/FreeRTOSConfig.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include <stdio.h>
+
+#define USER_MODE_TASKS 0
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configUSE_TICKLESS_IDLE 0
+#define configCPU_CLOCK_HZ 24000000 //32768
+#define configTICK_RATE_HZ 50
+#define configMAX_PRIORITIES 4
+#define configMINIMAL_STACK_SIZE 450
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_TASK_NOTIFICATIONS 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 0
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 10
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 1
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 0
+#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
+
+/* Memory allocation related definitions. */
+#define configSUPPORT_STATIC_ALLOCATION 0
+#define configSUPPORT_DYNAMIC_ALLOCATION 1
+#define configTOTAL_HEAP_SIZE (22 * 1024)
+#define configAPPLICATION_ALLOCATED_HEAP 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configCHECK_FOR_STACK_OVERFLOW 0
+#define configUSE_MALLOC_FAILED_HOOK 0
+#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 0
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine related definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 1
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY 1
+#define configTIMER_QUEUE_LENGTH 10
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Interrupt nesting behaviour configuration. */
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 6
+#define configMAX_API_CALL_INTERRUPT_PRIORITY 6
+
+#define configDEFAULT_HEAP_ADDR 0xfffc0000
+#define configDEFAULT_HEAP_SIZE (26 * 1024)
+#define configSTICK_REG_ADDR (configDEFAULT_HEAP_ADDR + configDEFAULT_HEAP_SIZE)
+#define configSTICK_REG_SIZE 128
+
+#define portCRITICAL_NESTING_IN_TCB 1
+
+/* Define to trap errors during development. */
+#define configASSERT(x) \
+ do { \
+ if ((x) == 0) { \
+ taskDISABLE_INTERRUPTS(); \
+ printf("ASSERT: %s %d\n", __FILE__, __LINE__); \
+ for (;;) \
+ ; \
+ } \
+ } while (0)
+
+/* FreeRTOS MPU specific definitions. */
+//#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_xResumeFromISR 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 1
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 1
+#define INCLUDE_xTaskGetIdleTaskHandle 1
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 1
+#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_xTaskAbortDelay 0
+#define INCLUDE_xTaskGetHandle 1
+#define INCLUDE_xTaskResumeFromISR 1
+
+#define configCLINT_BASE_ADDRESS 0x02000000UL
+/* A header file that defines trace macro can be included here. */
+
+#endif /* FREERTOS_CONFIG_H */
diff --git a/be311_t950s/Kconfig b/be311_t950s/Kconfig
new file mode 100644
index 0000000..f3b6580
--- /dev/null
+++ b/be311_t950s/Kconfig
@@ -0,0 +1,28 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+config BOARD_BE311_T950S
+ bool "Amlogic BE311_T950S Board"
+ select SOC_TXHD2
+ select LIBC_AML
+ select COMMON
+ select GET_VERSION
+ select STICK_MEM
+ select UART
+ # select CEC
+ select DDR
+ select MAILBOX
+ select VRTC
+ select STR
+ select GPIO
+ select KEY
+ select PWM
+ # select LEDS
+ select TIMER_SOURCE
+ select SARADC
+ select IR
+ select ETHERNET
+ select VERSION_FULL_INFO
+ help
+ Enable Amlogic BE311_T950S Board.
diff --git a/be311_t950s/btwake.c b/be311_t950s/btwake.c
new file mode 100644
index 0000000..bab28d5
--- /dev/null
+++ b/be311_t950s/btwake.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "suspend.h"
+#include "task.h"
+#include "gpio.h"
+
+#include "queue.h" /* RTOS queue related API prototypes. */
+#include "timers.h" /* Software timer related API prototypes. */
+#include "semphr.h" /* Semaphore related API prototypes. */
+
+#define BT_WAKE_HOST GPIOB_13 //bt_wake_host pin
+#define INFO(fmt, args...) printf("[%s] " fmt "\n", __func__, ##args)
+
+void Bt_IRQHandle(void)
+{
+ uint32_t buf[4] = { 0 };
+
+ INFO("bt resume");
+ vDisableGpioIRQ(BT_WAKE_HOST);
+ if (!xGpioGetValue(BT_WAKE_HOST)) {
+ buf[0] = BT_WAKEUP;
+ INFO("power key");
+ STR_Wakeup_src_Queue_Send_FromISR(buf);
+ }
+}
+
+void Bt_GpioIRQRegister(void)
+{
+ INFO();
+ xGpioSetDir(BT_WAKE_HOST, GPIO_DIR_IN);
+ xRequestGpioIRQ(BT_WAKE_HOST, Bt_IRQHandle, IRQF_TRIGGER_FALLING);
+}
+
+void Bt_GpioIRQFree(void)
+{
+ vFreeGpioIRQ(BT_WAKE_HOST);
+}
diff --git a/be311_t950s/compiler_options.cmake b/be311_t950s/compiler_options.cmake
new file mode 100644
index 0000000..3d11a1f
--- /dev/null
+++ b/be311_t950s/compiler_options.cmake
@@ -0,0 +1,5 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+#add compiler options at here which is associated with current board.
diff --git a/be311_t950s/defconfig b/be311_t950s/defconfig
new file mode 100644
index 0000000..531a0c4
--- /dev/null
+++ b/be311_t950s/defconfig
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: MIT
+#
+
+CONFIG_BOARD_BE311_T950S=y
+
diff --git a/be311_t950s/fsm.c b/be311_t950s/fsm.c
new file mode 100644
index 0000000..27b34c5
--- /dev/null
+++ b/be311_t950s/fsm.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "FreeRTOS.h" /* Must come first. */
+#include "task.h" /* RTOS task related API prototypes. */
+#include "queue.h" /* RTOS queue related API prototypes. */
+#include "timers.h" /* Software timer related API prototypes. */
+#include "semphr.h" /* Semaphore related API prototypes. */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "n200_func.h"
+#include "common.h"
+#include "riscv_encoding.h"
+#include "mailbox-api.h"
+#include "irq.h"
+
+enum PM_E {
+ PM_CPU_PWR,
+ PM_CPU_CORE0,
+ PM_CPU_CORE1,
+ PM_CPU_CORE2,
+ PM_CPU_CORE3,
+};
+
+static void *xMboxCoreFsmIdle(void *msg)
+{
+ enum PM_E domain = *(uint32_t *)msg;
+
+ switch (domain) {
+ case PM_CPU_CORE0:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 0), 0);
+ EnableIrq(IRQ_NUM_OUT_0);
+ break;
+ case PM_CPU_CORE1:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 1), 0);
+ EnableIrq(IRQ_NUM_OUT_1);
+ break;
+ case PM_CPU_CORE2:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 2), 0);
+ EnableIrq(IRQ_NUM_OUT_2);
+ break;
+ case PM_CPU_CORE3:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 3), 0);
+ EnableIrq(IRQ_NUM_OUT_3);
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static void xSetCoreFsmAwakeIrq(int cpuid)
+{
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << cpuid), (1 << cpuid));
+}
+
+static void xCore0FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(0);
+ DisableIrq(IRQ_NUM_OUT_0);
+}
+
+static void xCore1FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(1);
+ DisableIrq(IRQ_NUM_OUT_1);
+}
+
+static void xCore2FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(2);
+ DisableIrq(IRQ_NUM_OUT_2);
+}
+
+static void xCore3FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(3);
+ DisableIrq(IRQ_NUM_OUT_3);
+}
+
+void vCoreFsmIdleInit(void)
+{
+ int ret;
+
+ ret = xInstallRemoteMessageCallbackFeedBack(AOTEE_CHANNEL, MBX_CMD_CPU_FSM_IDLE,
+ xMboxCoreFsmIdle, 0);
+ if (ret == MBOX_CALL_MAX)
+ printf("mbox cmd 0x%x register fail\n", MBX_CMD_CPU_FSM_IDLE);
+
+ RegisterIrq(IRQ_NUM_OUT_0, 1, xCore0FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_1, 1, xCore1FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_2, 1, xCore2FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_3, 1, xCore3FsmIdleHandleIsr);
+ REG32_UPDATE_BITS(SEC_SYS_CPU_CFG10, 0xF << 10, 0xF << 10);
+}
diff --git a/be311_t950s/fsm.h b/be311_t950s/fsm.h
new file mode 100644
index 0000000..86a1f01
--- /dev/null
+++ b/be311_t950s/fsm.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __FSM_H__
+#define __FSM_H__
+
+void vCoreFsmIdleInit(void);
+extern void vRtcInit(void);
+extern void create_str_task(void);
+extern void trap_entry(void);
+extern void irq_entry(void);
+
+#endif
diff --git a/be311_t950s/hw_business.c b/be311_t950s/hw_business.c
new file mode 100644
index 0000000..6d525cf
--- /dev/null
+++ b/be311_t950s/hw_business.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "semphr.h"
+#include "hw_business.h"
+#include "n200_eclic.h"
+#include "n200_func.h"
+#include "uart.h"
+#include "eth.h"
+#include "common.h"
+#include "mailbox-api.h"
+#include "hdmi_cec.h"
+#include "stick_mem.h"
+#include "keypad.h"
+#include "fsm.h"
+
+#define INT_TEST_NEST_DEPTH 6
+#define INT_TEST_GPIO_NUM 6
+#define INT_TEST_TASK_DELAY 50 // ms
+#define TASK_TEST_STACK_DEPTH 200
+
+#define TASK_TEST_QUEUE_NUM 2
+#define TASK_TEST_QUEUE_LENGTH 3
+
+//#define GPIO_INT_SOURCE(x) (SOC_PIC_INT_GPIO_BASE + x)
+
+/* Configure board type:
+ * Board under test : SIGNAL_BOARD_ENABLE 0
+ * Signal generation board : SIGNAL_BOARD_ENABLE 1
+ */
+#define SIGNAL_BOARD_ENABLE 0
+
+#define INT_TEST_INT_WAVE_ENABLE 1
+
+#if INT_TEST_INT_WAVE_ENABLE
+ #define INT_TEST_TIMER_PERIOD 500 // ms
+ #define INT_TEST_INT_DELAY 10 // ms
+#else
+ #define INT_TEST_TIMER_PERIOD 500 // ms
+ #define INT_TEST_INT_DELAY 0x3ff // ms
+#endif
+
+#define INT_TEST_MAX_TIMER_PERIOD 100 // ms
+#define INT_TEST_MIN_TIMER_PERIOD 50 // ms
+#define INT_TEST_MUTE_TIMER_PERIOD 200 // ms
+
+#define RTOS_BOOT_SUCC_REG AO_DEBUG_REG2
+
+/* Binary Semaphore */
+QueueHandle_t xGPIOSemaphore[INT_TEST_NEST_DEPTH];
+QueueHandle_t xMessageQueue[TASK_TEST_QUEUE_NUM];
+
+void config_eclic_irqs(void)
+{
+ eclic_init(ECLIC_NUM_INTERRUPTS);
+ eclic_set_nlbits(0);
+}
+
+void hw_business_process(void)
+{
+ uint8_t i = 0;
+
+ // Initialize GPIOs, PIC and timer
+ //vGPIOInit();
+ config_eclic_irqs();
+ for (i = 0; i < 8; ++i)
+ printf("AOCPU_IRQ_SEL=0x%x\n", REG32(AOCPU_IRQ_SEL0 + i * 4));
+
+ stick_mem_init();
+ //write watchdog flag
+ stick_mem_write(STICK_REBOOT_FLAG, 0xd);
+
+ // Delay
+ for (uint32_t i = 0; i < 0xffff; ++i)
+ ;
+
+ vMbInit();
+ vCoreFsmIdleInit();
+ // vCecCallbackInit(CEC_CHIP_T5);
+ vRtcInit();
+ vETHMailboxCallback();
+ create_str_task();
+ vKeyPadCreate();
+}
+
+void aocpu_bringup_finished(void)
+{
+ #define RTOS_RUN_SUCC (1 << 0)
+ *(volatile uint32_t *)RTOS_BOOT_SUCC_REG |= RTOS_RUN_SUCC;
+}
+
diff --git a/be311_t950s/hw_business.h b/be311_t950s/hw_business.h
new file mode 100644
index 0000000..2dc1d61
--- /dev/null
+++ b/be311_t950s/hw_business.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __hW_BUSINESS_H__
+#define __hW_BUSINESS_H__
+
+void hw_business_process(void);
+
+#endif
diff --git a/be311_t950s/keypad.c b/be311_t950s/keypad.c
new file mode 100644
index 0000000..7406fb1
--- /dev/null
+++ b/be311_t950s/keypad.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "ir.h"
+#include "keypad.h"
+#include "gpio.h"
+#include "saradc.h"
+#include "suspend.h"
+
+/*KEY ID*/
+#define ADC_KEY_ID_HOME 520
+
+static void vAdcKeyCallBack(struct xReportEvent event)
+{
+ uint32_t buf[4] = { 0 };
+
+ switch (event.ulCode) {
+ case ADC_KEY_ID_HOME:
+ buf[0] = POWER_KEY_WAKEUP;
+ STR_Wakeup_src_Queue_Send(buf);
+ break;
+ default:
+ break;
+ }
+
+ printf("ADC key event 0x%x, key code %d, responseTicks %d\n", event.event, event.ulCode,
+ event.responseTime);
+}
+
+struct xAdcKeyInfo adcKeyInfo[] = { ADC_KEY_INFO(ADC_KEY_ID_HOME, 0, SARADC_CH1, EVENT_SHORT,
+ vAdcKeyCallBack, NULL) };
+
+void vKeyPadCreate(void)
+{
+ vCreateAdcKey(adcKeyInfo, sizeof(adcKeyInfo) / sizeof(struct xAdcKeyInfo));
+
+ vDynamicKeypadInit();
+}
+
+void vKeyPadInit(void)
+{
+ if (vAdcKeyIsEmpty())
+ vCreateAdcKey(adcKeyInfo, sizeof(adcKeyInfo) / sizeof(struct xAdcKeyInfo));
+
+ vAdcKeyEnable();
+ vGpioKeyEnable();
+}
+
+void vKeyPadDeinit(void)
+{
+ vAdcKeyDisable();
+ vGpioKeyDisable();
+}
diff --git a/be311_t950s/keypad.h b/be311_t950s/keypad.h
new file mode 100644
index 0000000..e496629
--- /dev/null
+++ b/be311_t950s/keypad.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __MESON_Button_H
+#define __MESON_Button_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "common.h"
+#include <stdlib.h>
+#include <string.h>
+#include "FreeRTOS.h"
+#include <timers.h>
+#include <task.h>
+#include <gpio.h>
+#include <saradc.h>
+
+/*common macro*/
+#define TIMER_CYCLE_TIME 100
+#define KEY_JITTER_COUNT 1
+
+/* adc key param */
+#define SAMPLE_DEVIATION 40
+#define ADCKEY_ID_BASE 512
+
+/* key event */
+#define EVENT_SHORT (1 << 0)
+#define EVENT_LONG (1 << 1)
+
+/* key threshold */
+#define THRESHOLD_LONG 2000
+
+enum KeyType { GPIO_KEY = 0, ADC_KEY, KEY_TYPE_NUM };
+
+enum GpioLevel { LOW = 0, HIGH };
+
+enum KeyState {
+ UP = 0,
+ DOWN,
+};
+
+struct xReportEvent {
+ uint32_t ulCode;
+ uint32_t event;
+ TickType_t responseTime;
+ void *data;
+};
+
+typedef void (*CallBack_t)(struct xReportEvent arg);
+
+struct xKeyInitInfo {
+ uint32_t ulKeyId;
+ uint32_t eventMask;
+ uint32_t repeatTimeMs;
+ uint32_t repeatDelayTimeMs;
+ uint32_t longDTTMs;
+ uint32_t doubleDTTMs;
+ uint32_t combLongDTTMs;
+ uint32_t combDTTMs;
+ CallBack_t CallBack;
+ void *data;
+};
+
+struct xGpioKeyInfo {
+ int ulInitLevel;
+ struct xKeyInitInfo keyInitInfo;
+};
+
+struct xAdcKeyInfo {
+ int32_t ulValue;
+ struct AdcInstanceConfig xAdcDecp;
+ struct xKeyInitInfo keyInitInfo;
+};
+
+#define KEY_INIT_INFO(_ulKeyId, _eventMask, _repeatTimeMs, _repeatDelayTimeMs, _longDTTMs, \
+ _doubleDTTMs, _combLongDTTMs, _combDTTMs, _CallBack, _data) \
+ { \
+ .ulKeyId = _ulKeyId, .eventMask = _eventMask, .repeatTimeMs = _repeatTimeMs, \
+ .repeatDelayTimeMs = _repeatDelayTimeMs, .longDTTMs = _longDTTMs, \
+ .doubleDTTMs = _doubleDTTMs, .combLongDTTMs = _combLongDTTMs, \
+ .combDTTMs = _combDTTMs, .CallBack = _CallBack, .data = _data, \
+ }
+
+#define GPIO_KEY_INFO(_ulKeyId, _ulInitLevel, _eventMask, _CallBack, _data) \
+ { \
+ .ulInitLevel = _ulInitLevel, \
+ .keyInitInfo = \
+ KEY_INIT_INFO(_ulKeyId, _eventMask, 0, 0, 0, 0, 0, 0, _CallBack, _data), \
+ }
+
+#define ADC_KEY_INFO(_ulKeyId, _ulValue, _adcChan, _eventMask, _CallBack, _data) \
+ { \
+ .ulValue = _ulValue, .xAdcDecp = { _adcChan, NO_AVERAGING, 1 }, \
+ .keyInitInfo = \
+ KEY_INIT_INFO(_ulKeyId, _eventMask, 0, 0, 0, 0, 0, 0, _CallBack, _data), \
+ }
+
+void vCreateGpioKey(struct xGpioKeyInfo *keyArr, uint16_t keyNum);
+void vDestroyGpioKey(void);
+void vGpioKeyEnable(void);
+void vGpioKeyDisable(void);
+int vGpioKeyIsEmpty(void);
+
+void vCreateAdcKey(struct xAdcKeyInfo *keyArr, uint16_t keyNum);
+void vDestroyAdcKey(void);
+void vAdcKeyEnable(void);
+void vAdcKeyDisable(void);
+int vAdcKeyIsEmpty(void);
+
+void vKeyPadCreate(void);
+void vKeyPadInit(void);
+void vKeyPadDeinit(void);
+
+void vDynamicKeypadInit(void);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/be311_t950s/leds_plat.c b/be311_t950s/leds_plat.c
new file mode 100644
index 0000000..de92a5e
--- /dev/null
+++ b/be311_t950s/leds_plat.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "FreeRTOS.h"
+#include <gpio.h>
+#include <leds_plat.h>
+#include <leds_state.h>
+
+/* TODO: Temporarily use static variables instead of stick mem */
+static int32_t LedStickMem0;
+//static int32_t LedStickMem1;
+
+static struct LedCoord BreathInflections0[] = { { 0, 0 }, { 2500, 255 }, { 5000, 0 } };
+
+static struct LedCoord BreathInflections1[] = { { 0, 0 }, { 5000, 255 }, { 10000, 0 } };
+
+static struct LedCoord BreathInflections2[] = { { 0, 0 }, { 10000, 255 }, { 20000, 0 } };
+
+static struct LedCoord BreathInflections3[] = { { 0, 0 }, { 20000, 255 }, { 40000, 0 } };
+
+struct LedCoord *BreathInflections[LED_BREATH_MAX_COUNT] = {
+ BreathInflections0,
+ BreathInflections1,
+ BreathInflections2,
+ BreathInflections3,
+};
+
+struct LedDevice MesonLeds[] = {
+ {
+ .id = LED_ID_0,
+ .type = LED_TYPE_PWM,
+ .name = "sys_led",
+ .hardware_id = MESON_PWM_AO_C,
+ .polarity = LED_POLARITY_POSITIVE,
+ .breathtime = 0,
+ },
+};
+
+int32_t get_led_breath_len(uint32_t breath_id)
+{
+ switch (breath_id) {
+ case 0:
+ return sizeof(BreathInflections0) / sizeof(struct LedCoord);
+ case 1:
+ return sizeof(BreathInflections1) / sizeof(struct LedCoord);
+ case 2:
+ return sizeof(BreathInflections2) / sizeof(struct LedCoord);
+ case 3:
+ return sizeof(BreathInflections3) / sizeof(struct LedCoord);
+ } /* end switch */
+
+ iprintf("%s: id: %ld leds state init!\n", DRIVER_NAME, breath_id);
+
+ return -pdFREERTOS_ERRNO_EINVAL;
+}
+
+int32_t vLedPlatInit(int32_t **stickmem)
+{
+ /* TODO: Here is initialization stickmem, but not doing so now */
+ *stickmem = &LedStickMem0;
+
+ /* off by default */
+ return xLedsStateSetBrightness(LED_ID_0, LED_OFF);
+}
+
+int32_t vLedPinmuxInit(void)
+{
+ /* set pinmux */
+ return xPinmuxSet(GPIOAO_8, PIN_FUNC4);
+}
diff --git a/be311_t950s/leds_plat.h b/be311_t950s/leds_plat.h
new file mode 100644
index 0000000..7f97196
--- /dev/null
+++ b/be311_t950s/leds_plat.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef _MESON_LEDS_PLAT_H_
+#define _MESON_LEDS_PLAT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * pwm t5d leds config
+ */
+#include <leds_state.h>
+#include <pwm_plat.h>
+
+#define LED_BREATH_MAX_COUNT 4
+
+extern struct LedDevice MesonLeds[];
+
+enum led_id {
+ LED_ID_0 = 0,
+ LED_ID_MAX,
+};
+
+int32_t get_led_breath_len(uint32_t breath_id);
+int32_t vLedPinmuxInit(void);
+int32_t vLedPlatInit(int32_t **stickmem);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _MESON_LED_PLAT_H_ */
diff --git a/be311_t950s/lscript.h b/be311_t950s/lscript.h
new file mode 100644
index 0000000..d74a85f
--- /dev/null
+++ b/be311_t950s/lscript.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef _LSCRIPT_H_
+#define _LSCRIPT_H_
+
+#define configMEM_START 0x10000000
+#define configMEM_LEN (64 * 1024)
+
+#endif
diff --git a/be311_t950s/lscript.ld b/be311_t950s/lscript.ld
new file mode 100644
index 0000000..0fe2b4f
--- /dev/null
+++ b/be311_t950s/lscript.ld
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv",
+ "elf32-littleriscv")
+OUTPUT_ARCH("riscv")
+ENTRY( _start )
+MEMORY
+{
+ ram (rw) : ORIGIN = 0x10000000, LENGTH = (64 * 1024)
+}
+SECTIONS
+{
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
+ .text :
+ {
+ . = ALIGN(4);
+ PROVIDE( _text = . );
+ *(.init)
+ *(.text* .rodata*)
+ . = ALIGN(0x100);
+ PROVIDE( _etext = . );
+ *(.vtable)
+ } > ram
+ .data :
+ {
+ _data = .;
+ *(vtable)
+ *(.sdata* .data*)
+ _edata = .;
+ } > ram
+ .bss :
+ {
+ _bss = .;
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ . = ALIGN(4);
+ _ebss = .;
+ } > ram
+ .stack :
+ {
+ PROVIDE( _stack = . );
+ . = ALIGN(1024);
+ . += __stack_size;
+ PROVIDE( _sp = . );
+ } >ram
+}
diff --git a/be311_t950s/power.c b/be311_t950s/power.c
new file mode 100644
index 0000000..83cec03
--- /dev/null
+++ b/be311_t950s/power.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "common.h"
+#include "gpio.h"
+#include "ir.h"
+#include "eth.h"
+#include "suspend.h"
+#include "task.h"
+#include "gpio.h"
+#include "pwm.h"
+#include "pwm_plat.h"
+#include "keypad.h"
+#include "hdmi_cec.h"
+#include "power.h"
+
+static TaskHandle_t cecTask;
+static int vdd_ee;
+static int vdd_cpu;
+
+static struct IRPowerKey prvPowerKeyList[] = {
+ { 0xef10fe01, IR_NORMAL }, /* ref tv pwr */
+ { 0xba45bd02, IR_NORMAL }, /* small ir pwr */
+ { 0xef10fb04, IR_NORMAL }, /* old ref tv pwr */
+ { 0xf20dfe01, IR_NORMAL },
+ { 0xe51afb04, IR_NORMAL },
+ { 0xff00fe06, IR_NORMAL },
+ { 0x3ac5bd02, IR_CUSTOM },
+ {}
+ /* add more */
+};
+
+static void vIRHandler(struct IRPowerKey *pkey)
+{
+ uint32_t buf[4] = { 0 };
+
+ if (pkey->type == IR_NORMAL)
+ buf[0] = REMOTE_WAKEUP;
+ else if (pkey->type == IR_CUSTOM)
+ buf[0] = REMOTE_CUS_WAKEUP;
+
+ /* do sth below to wakeup*/
+ STR_Wakeup_src_Queue_Send_FromISR(buf);
+};
+
+void str_hw_init(void)
+{
+ /*enable device & wakeup source interrupt*/
+ //vIRInit(MODE_HARD_NEC, GPIOD_5, PIN_FUNC1, prvPowerKeyList, ARRAY_SIZE(prvPowerKeyList),
+ // vIRHandler);
+ vETHInit(1);
+ //xTaskCreate(vCEC_task, "CECtask", configMINIMAL_STACK_SIZE, NULL, CEC_TASK_PRI, &cecTask);
+ vBackupAndClearGpioIrqReg();
+ vKeyPadInit();
+ vGpioIRQInit();
+ //Bt_GpioIRQRegister();
+}
+
+void str_hw_disable(void)
+{
+ /*disable wakeup source interrupt*/
+ vIRDeint();
+ vETHDeint();
+ //if (cecTask) {
+ // vTaskDelete(cecTask);
+ // cec_req_irq(0);
+ //}
+ //Bt_GpioIRQFree();
+ vKeyPadDeinit();
+ vRestoreGpioIrqReg();
+}
+
+void str_power_on(int shutdown_flag)
+{
+ int ret;
+
+ /***set vdd_ee val***/
+ ret = vPwmMesonsetvoltage(VDDEE_VOLT, vdd_ee);
+ if (ret < 0) {
+ printf("vdd_EE pwm set fail\n");
+ return;
+ }
+
+ /***set vdd_ee val***/
+ ret = vPwmMesonsetvoltage(VDDCPU_VOLT, vdd_cpu);
+ if (ret < 0) {
+ printf("vdd_CPU pwm set fail\n");
+ return;
+ }
+
+ /***power on vcc3.3***/
+ //ret = xGpioSetDir(GPIOD_10, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_10, GPIO_LEVEL_HIGH);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio val fail\n");
+ // return;
+ //}
+
+ if (shutdown_flag) {
+ /***power on VDDQ/VDDCPU***/
+ //ret = xGpioSetDir(GPIOD_4, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_4, GPIO_LEVEL_HIGH);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio val fail\n");
+ // return;
+ //}
+ /*Wait 10ms for VDDCPU statable*/
+ vTaskDelay(pdMS_TO_TICKS(10));
+ }
+
+ /***power on 5v***/
+ REG32(AO_GPIO_TEST_N) = REG32(AO_GPIO_TEST_N) | (1 << 31);
+}
+
+void str_power_off(int shutdown_flag)
+{
+ int ret;
+
+ printf("poweroff 5v\n");
+ printf("0x%x\n", REG32(AO_GPIO_TEST_N));
+
+ REG32(AO_GPIO_TEST_N) = (REG32(AO_GPIO_TEST_N) << 1) >> 1;
+
+ if (shutdown_flag) {
+ /***power off VDDQ/VDDCPU***/
+ //ret = xGpioSetDir(GPIOD_4, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_4, GPIO_LEVEL_LOW);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio val fail\n");
+ // return;
+ //}
+ }
+
+ /***power off vcc3.3***/
+ //ret = xGpioSetDir(GPIOD_10, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio dir fail\n");
+ // return;
+ //}
+
+ if (get_ETHWol_flag() == 0) {
+ //ret = xGpioSetValue(GPIOD_10, GPIO_LEVEL_LOW);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio val fail\n");
+ // return;
+ //}
+ }
+
+ /***set vdd_cpu val***/
+ vdd_cpu = vPwmMesongetvoltage(VDDCPU_VOLT);
+ if (vdd_cpu < 0) {
+ printf("vdd_CPU pwm get fail\n");
+ return;
+ }
+
+ ret = vPwmMesonsetvoltage(VDDCPU_VOLT, 700);
+ if (ret < 0) {
+ printf("vdd_CPU pwm set fail\n");
+ return;
+ }
+
+ /***set vdd_ee val***/
+ vdd_ee = vPwmMesongetvoltage(VDDEE_VOLT);
+ if (vdd_ee < 0) {
+ printf("vdd_EE pwm get fail\n");
+ return;
+ }
+
+ ret = vPwmMesonsetvoltage(VDDEE_VOLT, 770);
+ if (ret < 0) {
+ printf("vdd_EE pwm set fail\n");
+ return;
+ }
+
+ //REG32( ((0x0000 << 2) + 0xff638c00)) = 0;
+}
diff --git a/be311_t950s/power.h b/be311_t950s/power.h
new file mode 100644
index 0000000..ea41f71
--- /dev/null
+++ b/be311_t950s/power.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __POWER_H__
+#define __POWER_H__
+
+void str_hw_init(void);
+
+void str_hw_disable(void);
+
+void str_power_on(int shutdown_flag);
+
+void str_power_off(int shutdown_flag);
+
+void Bt_GpioIRQRegister(void);
+
+void Bt_GpioIRQFree(void);
+
+
+#endif
diff --git a/be319_t950s/CMakeLists.txt b/be319_t950s/CMakeLists.txt
new file mode 100644
index 0000000..0e2e79d
--- /dev/null
+++ b/be319_t950s/CMakeLists.txt
@@ -0,0 +1,20 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+aml_library_include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+aml_library_sources(
+ fsm.c
+ # btwake.c
+ keypad.c
+ power.c
+ hw_business.c
+)
+
+aml_library_sources_ifdef(
+ CONFIG_LEDS
+ leds_plat.c
+)
diff --git a/be319_t950s/FreeRTOSConfig.h b/be319_t950s/FreeRTOSConfig.h
new file mode 100644
index 0000000..f72f6cf
--- /dev/null
+++ b/be319_t950s/FreeRTOSConfig.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef FREERTOS_CONFIG_H
+#define FREERTOS_CONFIG_H
+
+#include <stdio.h>
+
+#define USER_MODE_TASKS 0
+
+#define configUSE_PREEMPTION 1
+#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
+#define configUSE_TICKLESS_IDLE 0
+#define configCPU_CLOCK_HZ 24000000 //32768
+#define configTICK_RATE_HZ 50
+#define configMAX_PRIORITIES 4
+#define configMINIMAL_STACK_SIZE 450
+#define configMAX_TASK_NAME_LEN 16
+#define configUSE_16_BIT_TICKS 0
+#define configIDLE_SHOULD_YIELD 1
+#define configUSE_TASK_NOTIFICATIONS 1
+#define configUSE_MUTEXES 1
+#define configUSE_RECURSIVE_MUTEXES 0
+#define configUSE_COUNTING_SEMAPHORES 1
+#define configQUEUE_REGISTRY_SIZE 10
+#define configUSE_QUEUE_SETS 0
+#define configUSE_TIME_SLICING 1
+#define configUSE_NEWLIB_REENTRANT 0
+#define configENABLE_BACKWARD_COMPATIBILITY 0
+#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5
+
+/* Memory allocation related definitions. */
+#define configSUPPORT_STATIC_ALLOCATION 0
+#define configSUPPORT_DYNAMIC_ALLOCATION 1
+#define configTOTAL_HEAP_SIZE (22 * 1024)
+#define configAPPLICATION_ALLOCATED_HEAP 0
+
+/* Hook function related definitions. */
+#define configUSE_IDLE_HOOK 0
+#define configUSE_TICK_HOOK 0
+#define configCHECK_FOR_STACK_OVERFLOW 0
+#define configUSE_MALLOC_FAILED_HOOK 0
+#define configUSE_DAEMON_TASK_STARTUP_HOOK 0
+
+/* Run time and task stats gathering related definitions. */
+#define configGENERATE_RUN_TIME_STATS 0
+#define configUSE_TRACE_FACILITY 0
+#define configUSE_STATS_FORMATTING_FUNCTIONS 0
+
+/* Co-routine related definitions. */
+#define configUSE_CO_ROUTINES 0
+#define configMAX_CO_ROUTINE_PRIORITIES 1
+
+/* Software timer related definitions. */
+#define configUSE_TIMERS 1
+#define configTIMER_TASK_PRIORITY 1
+#define configTIMER_QUEUE_LENGTH 10
+#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE
+
+/* Interrupt nesting behaviour configuration. */
+#define configKERNEL_INTERRUPT_PRIORITY 1
+#define configMAX_SYSCALL_INTERRUPT_PRIORITY 6
+#define configMAX_API_CALL_INTERRUPT_PRIORITY 6
+
+#define configDEFAULT_HEAP_ADDR 0xfffc0000
+#define configDEFAULT_HEAP_SIZE (26 * 1024)
+#define configSTICK_REG_ADDR (configDEFAULT_HEAP_ADDR + configDEFAULT_HEAP_SIZE)
+#define configSTICK_REG_SIZE 128
+
+#define portCRITICAL_NESTING_IN_TCB 1
+
+/* Define to trap errors during development. */
+#define configASSERT(x) \
+ do { \
+ if ((x) == 0) { \
+ taskDISABLE_INTERRUPTS(); \
+ printf("ASSERT: %s %d\n", __FILE__, __LINE__); \
+ for (;;) \
+ ; \
+ } \
+ } while (0)
+
+/* FreeRTOS MPU specific definitions. */
+//#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
+
+/* Optional functions - most linkers will remove unused functions anyway. */
+#define INCLUDE_vTaskPrioritySet 1
+#define INCLUDE_uxTaskPriorityGet 1
+#define INCLUDE_vTaskDelete 1
+#define INCLUDE_vTaskSuspend 1
+#define INCLUDE_xResumeFromISR 1
+#define INCLUDE_vTaskDelayUntil 1
+#define INCLUDE_vTaskDelay 1
+#define INCLUDE_xTaskGetSchedulerState 1
+#define INCLUDE_xTaskGetCurrentTaskHandle 1
+#define INCLUDE_uxTaskGetStackHighWaterMark 1
+#define INCLUDE_xTaskGetIdleTaskHandle 1
+#define INCLUDE_eTaskGetState 0
+#define INCLUDE_xEventGroupSetBitFromISR 1
+#define INCLUDE_xTimerPendFunctionCall 1
+#define INCLUDE_xTaskAbortDelay 0
+#define INCLUDE_xTaskGetHandle 1
+#define INCLUDE_xTaskResumeFromISR 1
+
+#define configCLINT_BASE_ADDRESS 0x02000000UL
+/* A header file that defines trace macro can be included here. */
+
+#endif /* FREERTOS_CONFIG_H */
diff --git a/be319_t950s/Kconfig b/be319_t950s/Kconfig
new file mode 100644
index 0000000..6e52006
--- /dev/null
+++ b/be319_t950s/Kconfig
@@ -0,0 +1,28 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+config BOARD_BE319_T950S
+ bool "Amlogic BE319_T950S Board"
+ select SOC_TXHD2
+ select LIBC_AML
+ select COMMON
+ select GET_VERSION
+ select STICK_MEM
+ select UART
+ # select CEC
+ select DDR
+ select MAILBOX
+ select VRTC
+ select STR
+ select GPIO
+ select KEY
+ select PWM
+ # select LEDS
+ select TIMER_SOURCE
+ select SARADC
+ select IR
+ select ETHERNET
+ select VERSION_FULL_INFO
+ help
+ Enable Amlogic BE319_T950S Board.
diff --git a/be319_t950s/btwake.c b/be319_t950s/btwake.c
new file mode 100644
index 0000000..bab28d5
--- /dev/null
+++ b/be319_t950s/btwake.c
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "suspend.h"
+#include "task.h"
+#include "gpio.h"
+
+#include "queue.h" /* RTOS queue related API prototypes. */
+#include "timers.h" /* Software timer related API prototypes. */
+#include "semphr.h" /* Semaphore related API prototypes. */
+
+#define BT_WAKE_HOST GPIOB_13 //bt_wake_host pin
+#define INFO(fmt, args...) printf("[%s] " fmt "\n", __func__, ##args)
+
+void Bt_IRQHandle(void)
+{
+ uint32_t buf[4] = { 0 };
+
+ INFO("bt resume");
+ vDisableGpioIRQ(BT_WAKE_HOST);
+ if (!xGpioGetValue(BT_WAKE_HOST)) {
+ buf[0] = BT_WAKEUP;
+ INFO("power key");
+ STR_Wakeup_src_Queue_Send_FromISR(buf);
+ }
+}
+
+void Bt_GpioIRQRegister(void)
+{
+ INFO();
+ xGpioSetDir(BT_WAKE_HOST, GPIO_DIR_IN);
+ xRequestGpioIRQ(BT_WAKE_HOST, Bt_IRQHandle, IRQF_TRIGGER_FALLING);
+}
+
+void Bt_GpioIRQFree(void)
+{
+ vFreeGpioIRQ(BT_WAKE_HOST);
+}
diff --git a/be319_t950s/compiler_options.cmake b/be319_t950s/compiler_options.cmake
new file mode 100644
index 0000000..3d11a1f
--- /dev/null
+++ b/be319_t950s/compiler_options.cmake
@@ -0,0 +1,5 @@
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+
+# SPDX-License-Identifier: MIT
+
+#add compiler options at here which is associated with current board.
diff --git a/be319_t950s/defconfig b/be319_t950s/defconfig
new file mode 100644
index 0000000..05841a9
--- /dev/null
+++ b/be319_t950s/defconfig
@@ -0,0 +1,8 @@
+#
+# Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+#
+# SPDX-License-Identifier: MIT
+#
+
+CONFIG_BOARD_BE319_T950S=y
+
diff --git a/be319_t950s/fsm.c b/be319_t950s/fsm.c
new file mode 100644
index 0000000..27b34c5
--- /dev/null
+++ b/be319_t950s/fsm.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "FreeRTOS.h" /* Must come first. */
+#include "task.h" /* RTOS task related API prototypes. */
+#include "queue.h" /* RTOS queue related API prototypes. */
+#include "timers.h" /* Software timer related API prototypes. */
+#include "semphr.h" /* Semaphore related API prototypes. */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "n200_func.h"
+#include "common.h"
+#include "riscv_encoding.h"
+#include "mailbox-api.h"
+#include "irq.h"
+
+enum PM_E {
+ PM_CPU_PWR,
+ PM_CPU_CORE0,
+ PM_CPU_CORE1,
+ PM_CPU_CORE2,
+ PM_CPU_CORE3,
+};
+
+static void *xMboxCoreFsmIdle(void *msg)
+{
+ enum PM_E domain = *(uint32_t *)msg;
+
+ switch (domain) {
+ case PM_CPU_CORE0:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 0), 0);
+ EnableIrq(IRQ_NUM_OUT_0);
+ break;
+ case PM_CPU_CORE1:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 1), 0);
+ EnableIrq(IRQ_NUM_OUT_1);
+ break;
+ case PM_CPU_CORE2:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 2), 0);
+ EnableIrq(IRQ_NUM_OUT_2);
+ break;
+ case PM_CPU_CORE3:
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 3), 0);
+ EnableIrq(IRQ_NUM_OUT_3);
+ break;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static void xSetCoreFsmAwakeIrq(int cpuid)
+{
+ REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << cpuid), (1 << cpuid));
+}
+
+static void xCore0FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(0);
+ DisableIrq(IRQ_NUM_OUT_0);
+}
+
+static void xCore1FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(1);
+ DisableIrq(IRQ_NUM_OUT_1);
+}
+
+static void xCore2FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(2);
+ DisableIrq(IRQ_NUM_OUT_2);
+}
+
+static void xCore3FsmIdleHandleIsr(void)
+{
+ xSetCoreFsmAwakeIrq(3);
+ DisableIrq(IRQ_NUM_OUT_3);
+}
+
+void vCoreFsmIdleInit(void)
+{
+ int ret;
+
+ ret = xInstallRemoteMessageCallbackFeedBack(AOTEE_CHANNEL, MBX_CMD_CPU_FSM_IDLE,
+ xMboxCoreFsmIdle, 0);
+ if (ret == MBOX_CALL_MAX)
+ printf("mbox cmd 0x%x register fail\n", MBX_CMD_CPU_FSM_IDLE);
+
+ RegisterIrq(IRQ_NUM_OUT_0, 1, xCore0FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_1, 1, xCore1FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_2, 1, xCore2FsmIdleHandleIsr);
+ RegisterIrq(IRQ_NUM_OUT_3, 1, xCore3FsmIdleHandleIsr);
+ REG32_UPDATE_BITS(SEC_SYS_CPU_CFG10, 0xF << 10, 0xF << 10);
+}
diff --git a/be319_t950s/fsm.h b/be319_t950s/fsm.h
new file mode 100644
index 0000000..86a1f01
--- /dev/null
+++ b/be319_t950s/fsm.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __FSM_H__
+#define __FSM_H__
+
+void vCoreFsmIdleInit(void);
+extern void vRtcInit(void);
+extern void create_str_task(void);
+extern void trap_entry(void);
+extern void irq_entry(void);
+
+#endif
diff --git a/be319_t950s/hw_business.c b/be319_t950s/hw_business.c
new file mode 100644
index 0000000..6d525cf
--- /dev/null
+++ b/be319_t950s/hw_business.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "queue.h"
+#include "semphr.h"
+#include "hw_business.h"
+#include "n200_eclic.h"
+#include "n200_func.h"
+#include "uart.h"
+#include "eth.h"
+#include "common.h"
+#include "mailbox-api.h"
+#include "hdmi_cec.h"
+#include "stick_mem.h"
+#include "keypad.h"
+#include "fsm.h"
+
+#define INT_TEST_NEST_DEPTH 6
+#define INT_TEST_GPIO_NUM 6
+#define INT_TEST_TASK_DELAY 50 // ms
+#define TASK_TEST_STACK_DEPTH 200
+
+#define TASK_TEST_QUEUE_NUM 2
+#define TASK_TEST_QUEUE_LENGTH 3
+
+//#define GPIO_INT_SOURCE(x) (SOC_PIC_INT_GPIO_BASE + x)
+
+/* Configure board type:
+ * Board under test : SIGNAL_BOARD_ENABLE 0
+ * Signal generation board : SIGNAL_BOARD_ENABLE 1
+ */
+#define SIGNAL_BOARD_ENABLE 0
+
+#define INT_TEST_INT_WAVE_ENABLE 1
+
+#if INT_TEST_INT_WAVE_ENABLE
+ #define INT_TEST_TIMER_PERIOD 500 // ms
+ #define INT_TEST_INT_DELAY 10 // ms
+#else
+ #define INT_TEST_TIMER_PERIOD 500 // ms
+ #define INT_TEST_INT_DELAY 0x3ff // ms
+#endif
+
+#define INT_TEST_MAX_TIMER_PERIOD 100 // ms
+#define INT_TEST_MIN_TIMER_PERIOD 50 // ms
+#define INT_TEST_MUTE_TIMER_PERIOD 200 // ms
+
+#define RTOS_BOOT_SUCC_REG AO_DEBUG_REG2
+
+/* Binary Semaphore */
+QueueHandle_t xGPIOSemaphore[INT_TEST_NEST_DEPTH];
+QueueHandle_t xMessageQueue[TASK_TEST_QUEUE_NUM];
+
+void config_eclic_irqs(void)
+{
+ eclic_init(ECLIC_NUM_INTERRUPTS);
+ eclic_set_nlbits(0);
+}
+
+void hw_business_process(void)
+{
+ uint8_t i = 0;
+
+ // Initialize GPIOs, PIC and timer
+ //vGPIOInit();
+ config_eclic_irqs();
+ for (i = 0; i < 8; ++i)
+ printf("AOCPU_IRQ_SEL=0x%x\n", REG32(AOCPU_IRQ_SEL0 + i * 4));
+
+ stick_mem_init();
+ //write watchdog flag
+ stick_mem_write(STICK_REBOOT_FLAG, 0xd);
+
+ // Delay
+ for (uint32_t i = 0; i < 0xffff; ++i)
+ ;
+
+ vMbInit();
+ vCoreFsmIdleInit();
+ // vCecCallbackInit(CEC_CHIP_T5);
+ vRtcInit();
+ vETHMailboxCallback();
+ create_str_task();
+ vKeyPadCreate();
+}
+
+void aocpu_bringup_finished(void)
+{
+ #define RTOS_RUN_SUCC (1 << 0)
+ *(volatile uint32_t *)RTOS_BOOT_SUCC_REG |= RTOS_RUN_SUCC;
+}
+
diff --git a/be319_t950s/hw_business.h b/be319_t950s/hw_business.h
new file mode 100644
index 0000000..2dc1d61
--- /dev/null
+++ b/be319_t950s/hw_business.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __hW_BUSINESS_H__
+#define __hW_BUSINESS_H__
+
+void hw_business_process(void);
+
+#endif
diff --git a/be319_t950s/keypad.c b/be319_t950s/keypad.c
new file mode 100644
index 0000000..7406fb1
--- /dev/null
+++ b/be319_t950s/keypad.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "ir.h"
+#include "keypad.h"
+#include "gpio.h"
+#include "saradc.h"
+#include "suspend.h"
+
+/*KEY ID*/
+#define ADC_KEY_ID_HOME 520
+
+static void vAdcKeyCallBack(struct xReportEvent event)
+{
+ uint32_t buf[4] = { 0 };
+
+ switch (event.ulCode) {
+ case ADC_KEY_ID_HOME:
+ buf[0] = POWER_KEY_WAKEUP;
+ STR_Wakeup_src_Queue_Send(buf);
+ break;
+ default:
+ break;
+ }
+
+ printf("ADC key event 0x%x, key code %d, responseTicks %d\n", event.event, event.ulCode,
+ event.responseTime);
+}
+
+struct xAdcKeyInfo adcKeyInfo[] = { ADC_KEY_INFO(ADC_KEY_ID_HOME, 0, SARADC_CH1, EVENT_SHORT,
+ vAdcKeyCallBack, NULL) };
+
+void vKeyPadCreate(void)
+{
+ vCreateAdcKey(adcKeyInfo, sizeof(adcKeyInfo) / sizeof(struct xAdcKeyInfo));
+
+ vDynamicKeypadInit();
+}
+
+void vKeyPadInit(void)
+{
+ if (vAdcKeyIsEmpty())
+ vCreateAdcKey(adcKeyInfo, sizeof(adcKeyInfo) / sizeof(struct xAdcKeyInfo));
+
+ vAdcKeyEnable();
+ vGpioKeyEnable();
+}
+
+void vKeyPadDeinit(void)
+{
+ vAdcKeyDisable();
+ vGpioKeyDisable();
+}
diff --git a/be319_t950s/keypad.h b/be319_t950s/keypad.h
new file mode 100644
index 0000000..e496629
--- /dev/null
+++ b/be319_t950s/keypad.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __MESON_Button_H
+#define __MESON_Button_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "common.h"
+#include <stdlib.h>
+#include <string.h>
+#include "FreeRTOS.h"
+#include <timers.h>
+#include <task.h>
+#include <gpio.h>
+#include <saradc.h>
+
+/*common macro*/
+#define TIMER_CYCLE_TIME 100
+#define KEY_JITTER_COUNT 1
+
+/* adc key param */
+#define SAMPLE_DEVIATION 40
+#define ADCKEY_ID_BASE 512
+
+/* key event */
+#define EVENT_SHORT (1 << 0)
+#define EVENT_LONG (1 << 1)
+
+/* key threshold */
+#define THRESHOLD_LONG 2000
+
+enum KeyType { GPIO_KEY = 0, ADC_KEY, KEY_TYPE_NUM };
+
+enum GpioLevel { LOW = 0, HIGH };
+
+enum KeyState {
+ UP = 0,
+ DOWN,
+};
+
+struct xReportEvent {
+ uint32_t ulCode;
+ uint32_t event;
+ TickType_t responseTime;
+ void *data;
+};
+
+typedef void (*CallBack_t)(struct xReportEvent arg);
+
+struct xKeyInitInfo {
+ uint32_t ulKeyId;
+ uint32_t eventMask;
+ uint32_t repeatTimeMs;
+ uint32_t repeatDelayTimeMs;
+ uint32_t longDTTMs;
+ uint32_t doubleDTTMs;
+ uint32_t combLongDTTMs;
+ uint32_t combDTTMs;
+ CallBack_t CallBack;
+ void *data;
+};
+
+struct xGpioKeyInfo {
+ int ulInitLevel;
+ struct xKeyInitInfo keyInitInfo;
+};
+
+struct xAdcKeyInfo {
+ int32_t ulValue;
+ struct AdcInstanceConfig xAdcDecp;
+ struct xKeyInitInfo keyInitInfo;
+};
+
+#define KEY_INIT_INFO(_ulKeyId, _eventMask, _repeatTimeMs, _repeatDelayTimeMs, _longDTTMs, \
+ _doubleDTTMs, _combLongDTTMs, _combDTTMs, _CallBack, _data) \
+ { \
+ .ulKeyId = _ulKeyId, .eventMask = _eventMask, .repeatTimeMs = _repeatTimeMs, \
+ .repeatDelayTimeMs = _repeatDelayTimeMs, .longDTTMs = _longDTTMs, \
+ .doubleDTTMs = _doubleDTTMs, .combLongDTTMs = _combLongDTTMs, \
+ .combDTTMs = _combDTTMs, .CallBack = _CallBack, .data = _data, \
+ }
+
+#define GPIO_KEY_INFO(_ulKeyId, _ulInitLevel, _eventMask, _CallBack, _data) \
+ { \
+ .ulInitLevel = _ulInitLevel, \
+ .keyInitInfo = \
+ KEY_INIT_INFO(_ulKeyId, _eventMask, 0, 0, 0, 0, 0, 0, _CallBack, _data), \
+ }
+
+#define ADC_KEY_INFO(_ulKeyId, _ulValue, _adcChan, _eventMask, _CallBack, _data) \
+ { \
+ .ulValue = _ulValue, .xAdcDecp = { _adcChan, NO_AVERAGING, 1 }, \
+ .keyInitInfo = \
+ KEY_INIT_INFO(_ulKeyId, _eventMask, 0, 0, 0, 0, 0, 0, _CallBack, _data), \
+ }
+
+void vCreateGpioKey(struct xGpioKeyInfo *keyArr, uint16_t keyNum);
+void vDestroyGpioKey(void);
+void vGpioKeyEnable(void);
+void vGpioKeyDisable(void);
+int vGpioKeyIsEmpty(void);
+
+void vCreateAdcKey(struct xAdcKeyInfo *keyArr, uint16_t keyNum);
+void vDestroyAdcKey(void);
+void vAdcKeyEnable(void);
+void vAdcKeyDisable(void);
+int vAdcKeyIsEmpty(void);
+
+void vKeyPadCreate(void);
+void vKeyPadInit(void);
+void vKeyPadDeinit(void);
+
+void vDynamicKeypadInit(void);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/be319_t950s/leds_plat.c b/be319_t950s/leds_plat.c
new file mode 100644
index 0000000..de92a5e
--- /dev/null
+++ b/be319_t950s/leds_plat.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include "FreeRTOS.h"
+#include <gpio.h>
+#include <leds_plat.h>
+#include <leds_state.h>
+
+/* TODO: Temporarily use static variables instead of stick mem */
+static int32_t LedStickMem0;
+//static int32_t LedStickMem1;
+
+static struct LedCoord BreathInflections0[] = { { 0, 0 }, { 2500, 255 }, { 5000, 0 } };
+
+static struct LedCoord BreathInflections1[] = { { 0, 0 }, { 5000, 255 }, { 10000, 0 } };
+
+static struct LedCoord BreathInflections2[] = { { 0, 0 }, { 10000, 255 }, { 20000, 0 } };
+
+static struct LedCoord BreathInflections3[] = { { 0, 0 }, { 20000, 255 }, { 40000, 0 } };
+
+struct LedCoord *BreathInflections[LED_BREATH_MAX_COUNT] = {
+ BreathInflections0,
+ BreathInflections1,
+ BreathInflections2,
+ BreathInflections3,
+};
+
+struct LedDevice MesonLeds[] = {
+ {
+ .id = LED_ID_0,
+ .type = LED_TYPE_PWM,
+ .name = "sys_led",
+ .hardware_id = MESON_PWM_AO_C,
+ .polarity = LED_POLARITY_POSITIVE,
+ .breathtime = 0,
+ },
+};
+
+int32_t get_led_breath_len(uint32_t breath_id)
+{
+ switch (breath_id) {
+ case 0:
+ return sizeof(BreathInflections0) / sizeof(struct LedCoord);
+ case 1:
+ return sizeof(BreathInflections1) / sizeof(struct LedCoord);
+ case 2:
+ return sizeof(BreathInflections2) / sizeof(struct LedCoord);
+ case 3:
+ return sizeof(BreathInflections3) / sizeof(struct LedCoord);
+ } /* end switch */
+
+ iprintf("%s: id: %ld leds state init!\n", DRIVER_NAME, breath_id);
+
+ return -pdFREERTOS_ERRNO_EINVAL;
+}
+
+int32_t vLedPlatInit(int32_t **stickmem)
+{
+ /* TODO: Here is initialization stickmem, but not doing so now */
+ *stickmem = &LedStickMem0;
+
+ /* off by default */
+ return xLedsStateSetBrightness(LED_ID_0, LED_OFF);
+}
+
+int32_t vLedPinmuxInit(void)
+{
+ /* set pinmux */
+ return xPinmuxSet(GPIOAO_8, PIN_FUNC4);
+}
diff --git a/be319_t950s/leds_plat.h b/be319_t950s/leds_plat.h
new file mode 100644
index 0000000..7f97196
--- /dev/null
+++ b/be319_t950s/leds_plat.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef _MESON_LEDS_PLAT_H_
+#define _MESON_LEDS_PLAT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * pwm t5d leds config
+ */
+#include <leds_state.h>
+#include <pwm_plat.h>
+
+#define LED_BREATH_MAX_COUNT 4
+
+extern struct LedDevice MesonLeds[];
+
+enum led_id {
+ LED_ID_0 = 0,
+ LED_ID_MAX,
+};
+
+int32_t get_led_breath_len(uint32_t breath_id);
+int32_t vLedPinmuxInit(void);
+int32_t vLedPlatInit(int32_t **stickmem);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _MESON_LED_PLAT_H_ */
diff --git a/be319_t950s/lscript.h b/be319_t950s/lscript.h
new file mode 100644
index 0000000..d74a85f
--- /dev/null
+++ b/be319_t950s/lscript.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef _LSCRIPT_H_
+#define _LSCRIPT_H_
+
+#define configMEM_START 0x10000000
+#define configMEM_LEN (64 * 1024)
+
+#endif
diff --git a/be319_t950s/lscript.ld b/be319_t950s/lscript.ld
new file mode 100644
index 0000000..0fe2b4f
--- /dev/null
+++ b/be319_t950s/lscript.ld
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv",
+ "elf32-littleriscv")
+OUTPUT_ARCH("riscv")
+ENTRY( _start )
+MEMORY
+{
+ ram (rw) : ORIGIN = 0x10000000, LENGTH = (64 * 1024)
+}
+SECTIONS
+{
+ __stack_size = DEFINED(__stack_size) ? __stack_size : 2K;
+ .text :
+ {
+ . = ALIGN(4);
+ PROVIDE( _text = . );
+ *(.init)
+ *(.text* .rodata*)
+ . = ALIGN(0x100);
+ PROVIDE( _etext = . );
+ *(.vtable)
+ } > ram
+ .data :
+ {
+ _data = .;
+ *(vtable)
+ *(.sdata* .data*)
+ _edata = .;
+ } > ram
+ .bss :
+ {
+ _bss = .;
+ *(.sbss*)
+ *(.gnu.linkonce.sb.*)
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ . = ALIGN(4);
+ _ebss = .;
+ } > ram
+ .stack :
+ {
+ PROVIDE( _stack = . );
+ . = ALIGN(1024);
+ . += __stack_size;
+ PROVIDE( _sp = . );
+ } >ram
+}
diff --git a/be319_t950s/power.c b/be319_t950s/power.c
new file mode 100644
index 0000000..83cec03
--- /dev/null
+++ b/be319_t950s/power.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "common.h"
+#include "gpio.h"
+#include "ir.h"
+#include "eth.h"
+#include "suspend.h"
+#include "task.h"
+#include "gpio.h"
+#include "pwm.h"
+#include "pwm_plat.h"
+#include "keypad.h"
+#include "hdmi_cec.h"
+#include "power.h"
+
+static TaskHandle_t cecTask;
+static int vdd_ee;
+static int vdd_cpu;
+
+static struct IRPowerKey prvPowerKeyList[] = {
+ { 0xef10fe01, IR_NORMAL }, /* ref tv pwr */
+ { 0xba45bd02, IR_NORMAL }, /* small ir pwr */
+ { 0xef10fb04, IR_NORMAL }, /* old ref tv pwr */
+ { 0xf20dfe01, IR_NORMAL },
+ { 0xe51afb04, IR_NORMAL },
+ { 0xff00fe06, IR_NORMAL },
+ { 0x3ac5bd02, IR_CUSTOM },
+ {}
+ /* add more */
+};
+
+static void vIRHandler(struct IRPowerKey *pkey)
+{
+ uint32_t buf[4] = { 0 };
+
+ if (pkey->type == IR_NORMAL)
+ buf[0] = REMOTE_WAKEUP;
+ else if (pkey->type == IR_CUSTOM)
+ buf[0] = REMOTE_CUS_WAKEUP;
+
+ /* do sth below to wakeup*/
+ STR_Wakeup_src_Queue_Send_FromISR(buf);
+};
+
+void str_hw_init(void)
+{
+ /*enable device & wakeup source interrupt*/
+ //vIRInit(MODE_HARD_NEC, GPIOD_5, PIN_FUNC1, prvPowerKeyList, ARRAY_SIZE(prvPowerKeyList),
+ // vIRHandler);
+ vETHInit(1);
+ //xTaskCreate(vCEC_task, "CECtask", configMINIMAL_STACK_SIZE, NULL, CEC_TASK_PRI, &cecTask);
+ vBackupAndClearGpioIrqReg();
+ vKeyPadInit();
+ vGpioIRQInit();
+ //Bt_GpioIRQRegister();
+}
+
+void str_hw_disable(void)
+{
+ /*disable wakeup source interrupt*/
+ vIRDeint();
+ vETHDeint();
+ //if (cecTask) {
+ // vTaskDelete(cecTask);
+ // cec_req_irq(0);
+ //}
+ //Bt_GpioIRQFree();
+ vKeyPadDeinit();
+ vRestoreGpioIrqReg();
+}
+
+void str_power_on(int shutdown_flag)
+{
+ int ret;
+
+ /***set vdd_ee val***/
+ ret = vPwmMesonsetvoltage(VDDEE_VOLT, vdd_ee);
+ if (ret < 0) {
+ printf("vdd_EE pwm set fail\n");
+ return;
+ }
+
+ /***set vdd_ee val***/
+ ret = vPwmMesonsetvoltage(VDDCPU_VOLT, vdd_cpu);
+ if (ret < 0) {
+ printf("vdd_CPU pwm set fail\n");
+ return;
+ }
+
+ /***power on vcc3.3***/
+ //ret = xGpioSetDir(GPIOD_10, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_10, GPIO_LEVEL_HIGH);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio val fail\n");
+ // return;
+ //}
+
+ if (shutdown_flag) {
+ /***power on VDDQ/VDDCPU***/
+ //ret = xGpioSetDir(GPIOD_4, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_4, GPIO_LEVEL_HIGH);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio val fail\n");
+ // return;
+ //}
+ /*Wait 10ms for VDDCPU statable*/
+ vTaskDelay(pdMS_TO_TICKS(10));
+ }
+
+ /***power on 5v***/
+ REG32(AO_GPIO_TEST_N) = REG32(AO_GPIO_TEST_N) | (1 << 31);
+}
+
+void str_power_off(int shutdown_flag)
+{
+ int ret;
+
+ printf("poweroff 5v\n");
+ printf("0x%x\n", REG32(AO_GPIO_TEST_N));
+
+ REG32(AO_GPIO_TEST_N) = (REG32(AO_GPIO_TEST_N) << 1) >> 1;
+
+ if (shutdown_flag) {
+ /***power off VDDQ/VDDCPU***/
+ //ret = xGpioSetDir(GPIOD_4, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio dir fail\n");
+ // return;
+ //}
+
+ //ret = xGpioSetValue(GPIOD_4, GPIO_LEVEL_LOW);
+ //if (ret < 0) {
+ // printf("VDDCPU/VDDQ set gpio val fail\n");
+ // return;
+ //}
+ }
+
+ /***power off vcc3.3***/
+ //ret = xGpioSetDir(GPIOD_10, GPIO_DIR_OUT);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio dir fail\n");
+ // return;
+ //}
+
+ if (get_ETHWol_flag() == 0) {
+ //ret = xGpioSetValue(GPIOD_10, GPIO_LEVEL_LOW);
+ //if (ret < 0) {
+ // printf("vcc3.3 set gpio val fail\n");
+ // return;
+ //}
+ }
+
+ /***set vdd_cpu val***/
+ vdd_cpu = vPwmMesongetvoltage(VDDCPU_VOLT);
+ if (vdd_cpu < 0) {
+ printf("vdd_CPU pwm get fail\n");
+ return;
+ }
+
+ ret = vPwmMesonsetvoltage(VDDCPU_VOLT, 700);
+ if (ret < 0) {
+ printf("vdd_CPU pwm set fail\n");
+ return;
+ }
+
+ /***set vdd_ee val***/
+ vdd_ee = vPwmMesongetvoltage(VDDEE_VOLT);
+ if (vdd_ee < 0) {
+ printf("vdd_EE pwm get fail\n");
+ return;
+ }
+
+ ret = vPwmMesonsetvoltage(VDDEE_VOLT, 770);
+ if (ret < 0) {
+ printf("vdd_EE pwm set fail\n");
+ return;
+ }
+
+ //REG32( ((0x0000 << 2) + 0xff638c00)) = 0;
+}
diff --git a/be319_t950s/power.h b/be319_t950s/power.h
new file mode 100644
index 0000000..ea41f71
--- /dev/null
+++ b/be319_t950s/power.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2021-2022 Amlogic, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef __POWER_H__
+#define __POWER_H__
+
+void str_hw_init(void);
+
+void str_hw_disable(void);
+
+void str_power_on(int shutdown_flag);
+
+void str_power_off(int shutdown_flag);
+
+void Bt_GpioIRQRegister(void);
+
+void Bt_GpioIRQFree(void);
+
+
+#endif
diff --git a/build_combination.in b/build_combination.in
index 4a1e417..88b7ca7 100644
--- a/build_combination.in
+++ b/build_combination.in
@@ -11,6 +11,10 @@
riscv t5m ay301_t963d4 aocpu
riscv t5m ay309_t963d4 aocpu
riscv txhd2 txhd2_skt aocpu
+riscv txhd2 be301_t950s aocpu
+riscv txhd2 be309_t950s aocpu
+riscv txhd2 be311_t950s aocpu
+riscv txhd2 be319_t950s aocpu
riscv s1a s1a_skt aocpu
riscv s5 ax201_s928x aocpu
riscv s5 ax208_s928x aocpu