Hello Caesar Wang, Lin Huang, Douglas Anderson, Julius Werner,
I'd like you to do a code review. Please visit
https://chromium-review.googlesource.com/384278
to review the following change.
Change subject: WIP: add M0 source code for rk3399 suspend
......................................................................
WIP: add M0 source code for rk3399 suspend
Change-Id: Ie9b47e403ae91a20a9148bf543fc7d3f53349409
Signed-off-by: Xing Zheng <
zhen...@rock-chips.com>
---
A plat/rockchip/rk3399/drivers/m0/Makefile
A plat/rockchip/rk3399/drivers/m0/include/mcu.h
A plat/rockchip/rk3399/drivers/m0/include/remotectl_pwm.h
A plat/rockchip/rk3399/drivers/m0/include/rk3399.h
A plat/rockchip/rk3399/drivers/m0/src/main.c
A plat/rockchip/rk3399/drivers/m0/src/remotectl_pwm.c
A plat/rockchip/rk3399/drivers/m0/src/startup.c
7 files changed, 900 insertions(+), 0 deletions(-)
diff --git a/plat/rockchip/rk3399/drivers/m0/Makefile
b/plat/rockchip/rk3399/drivers/m0/Makefile
new file mode 100644
index 0000000..73d61b2
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/Makefile
@@ -0,0 +1,203 @@
+#
+# Copyright (c) 2016, Fuzhou Rockchip Electronics Co., Ltd.
+# All rights reserved.
+#
+# Author: Frank Wang <
frank...@rock-chips.com>
+# Date : 15-JUL-2016
+#
+# GCC cross compiation tool: gcc-arm-none-eabi-4_8-2014q3
+#
+
+ifneq ($(wildcard .config),)
+include .config
+endif
+
+#
+# Default values for build configurations
+#
+
+# Build verbosity
+V := 0
+
+# Cross Compile
+CROSS_COMPILE := arm-none-eabi-
+
+# Build architecture
+ARCH := cortex-m0
+
+# Build platform
+PLATFORMS := "RK3399M0"
+PLAT := RK3399M0
+HELP_PLATFORMS := $(shell echo ${PLATFORMS} | sed 's/ /|/g')
+
+# Build path
+BUILD_BASE := ./build
+BUILD_PLAT := ${BUILD_BASE}/${PLAT}
+
+ifeq (${V},0)
+ Q=@
+ CHECKCODE_ARGS += --no-summary --terse
+else
+ Q=
+endif
+export Q
+
+# Check the platform which user inputed is supported or not.
+ifeq (${PLAT},)
+ $(error "Error: Unknown platform. Please use PLAT=<platform name> to
specify the platform.")
+endif
+ifeq ($(findstring ${PLAT},${PLATFORMS}),)
+ $(error "Error: Invalid platform. The following platforms are available:
${PLATFORMS}")
+else
+ $(shell echo "PLAT=${PLAT}" > .config)
+endif
+
+# All PHONY definition
+.PHONY: all clean distclean ${ARCH} msg_start
+all: msg_start ${ARCH}
+
+.SUFFIXES:
+
+INCLUDES += -Iinclude/
+
+# NOTE: Add C source files here
+C_SOURCES := src/startup.c \
+ src/main.c
+ # src/remotectl_pwm.c
+
+# Flags definition
+CFLAGS += -g
+ASFLAGS += -g -Wa,--gdwarf-2
+
+ASFLAGS += -mcpu=$(ARCH) -mthumb -Wall -ffunction-sections -O3
+CFLAGS += -mcpu=$(ARCH) -mthumb -Wall -ffunction-sections -O3
+
+LDFLAGS += -mcpu=$(ARCH) -mthumb -g -nostartfiles -O3
+LDFLAGS += -Wl,--gc-sections
+LOCAL_CFLAGS += -DCPU_FREQ=24
+
+CC := ${CROSS_COMPILE}gcc
+CPP := ${CROSS_COMPILE}cpp
+AS := ${CROSS_COMPILE}gcc
+AR := ${CROSS_COMPILE}ar
+LD := ${CROSS_COMPILE}ld
+OC := ${CROSS_COMPILE}objcopy
+OD := ${CROSS_COMPILE}objdump
+NM := ${CROSS_COMPILE}nm
+PP := ${CROSS_COMPILE}gcc -E ${CFLAGS}
+
+# Function definition related compilation
+define MAKE_C
+$(eval OBJ := $(1)/$(patsubst %.c,%.o,$(notdir $(2))))
+
+$(OBJ) : $(2)
+ @echo " CC $$<"
+ $$(Q)$$(CC) $$(CFLAGS) $$(LOCAL_CFLAGS) $$(INCLUDES) -c $$< -o $$@
+endef
+
+define MAKE_S
+$(eval OBJ := $(1)/$(patsubst %.S,%.o,$(notdir $(2))))
+
+$(OBJ) : $(2)
+ @echo " AS $$<"
+ $$(Q)$$(AS) $$(ASFLAGS) $$(LOCAL_CFLAGS) -c $$< -o $$@
+endef
+
+define MAKE_LD
+$(1) :
+ @echo " PP $$<"
+ $$(AS) $$(ASFLAGS) -P -E -D__LINKER__ -o $$@ $$<
+endef
+
+define MAKE_OBJS
+ $(eval C_OBJS := $(filter %.c,$(2)))
+ $(eval REMAIN := $(filter-out %.c,$(2)))
+ $(eval $(foreach obj,$(C_OBJS),$(call MAKE_C,$(1),$(obj),$(3))))
+
+ $(eval S_OBJS := $(filter %.S,$(REMAIN)))
+ $(eval REMAIN := $(filter-out %.S,$(REMAIN)))
+ $(eval $(foreach obj,$(S_OBJS),$(call MAKE_S,$(1),$(obj),$(3))))
+
+ $(and $(REMAIN),$(error Unexpected source files present: $(REMAIN)))
+endef
+
+# NOTE: The line continuation '\' is required in the next define otherwise
we
+# end up with a line-feed characer at the end of the last c filename.
+# Also bare this issue in mind if extending the list of supported
filetypes.
+define SOURCES_TO_OBJS
+ $(notdir $(patsubst %.c,%.o,$(filter %.c,$(1)))) \
+ $(notdir $(patsubst %.S,%.o,$(filter %.S,$(1))))
+endef
+
+# NOTE: The Main compilation entry
+# MAKE_MCU macro defines the targets and options to build the image.
+define MAKE_MCU
+ $(eval BUILD_DIR := ${BUILD_PLAT}/obj)
+ $(eval BIN_DIR := ${BUILD_PLAT}/bin)
+ $(eval SOURCES := $(C_SOURCES))
+ $(eval OBJS := $(addprefix $(BUILD_DIR)/,$(call
SOURCES_TO_OBJS,$(SOURCES))))
+ $(eval LINKERFILE := $(BUILD_BASE)/arm-gcc-link.ld)
+ $(eval MAPFILE := $(BIN_DIR)/$(PLAT).map)
+ $(eval ELF := $(BIN_DIR)/$(PLAT).elf)
+ $(eval DUMP := $(BIN_DIR)/$(PLAT).dump)
+ $(eval BIN := $(BIN_DIR)/$(PLAT).bin)
+
+ $(eval $(call MAKE_OBJS,$(BUILD_DIR),$(SOURCES),$(1)))
+
+$(BIN_DIR) :
+ $$(Q)mkdir -p "$$@"
+
+$(BUILD_DIR) : $(BIN_DIR)
+ $$(Q)mkdir -p "$$@"
+
+$(ELF) : $(OBJS)
+ @echo " LD $$@"
+ $$(Q)$$(CC) -o $$@ $$(LDFLAGS) -Wl,-Map=$(MAPFILE) -Wl,-T$(LINKERFILE) \
+ $(OBJS)
+
+$(DUMP) : $(ELF)
+ @echo " OD $$@"
+ $${Q}$${OD} -dx $$< > $$@
+
+$(BIN) : $(ELF)
+ @echo " BIN $$@"
+ $$(Q)$$(OC) -O binary $$< $$@
+ @echo
+ @echo "Built $$@ successfully"
+ @echo
+
+.PHONY : ${ARCH}
+${ARCH} : $(BUILD_DIR) $(DUMP) $(BIN)
+endef
+
+$(eval $(call MAKE_MCU))
+
+# Other common compilation entries
+msg_start:
+ @echo " Building ${PLAT}"
+ @echo
+
+clean:
+ @echo " CLEAN"
+ ${Q}rm -rf ${BUILD_BASE}/${PLAT}
+ ${Q}rm -rf ${VER_BIN_DIR}/$(PLAT)*
+
+distclean:
+ @echo " DISTCLEAN"
+ ${Q}rm -rf ${BUILD_BASE}/${PLAT}
+ ${Q}rm -rf ${VER_BIN_DIR}/$(PLAT)*
+ ${Q}rm -rf .config
+
+help:
+ @echo "usage: make PLAT=<${HELP_PLATFORMS}> <all|clean|distclean>"
+ @echo ""
+ @echo "PLAT is used to specify which platform you wish to build."
+ @echo "If no platform is specified in first time, PLAT defaults to:
${DEFAULT_PLAT}"
+ @echo ""
+ @echo "Supported Targets:"
+ @echo " all Build all the project"
+ @echo " clean Clean the current platform project"
+ @echo " distclean Clean the current project and delete .config"
+ @echo ""
+ @echo "example: build the targets for the RK3399M0 project:"
+ @echo " make PLAT=RK3399M0"
diff --git a/plat/rockchip/rk3399/drivers/m0/include/mcu.h
b/plat/rockchip/rk3399/drivers/m0/include/mcu.h
new file mode 100644
index 0000000..dfa96a4
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/include/mcu.h
@@ -0,0 +1,66 @@
+/*
+ * operations related mcu arch.
+ *
+ * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Frank Wang <
frank...@rock-chips.com>
+ */
+
+#ifndef _MCU_H
+#define _MCU_H
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define SCS_BASE (0xE000E000UL)
+#define NVIC_BASE (SCS_BASE + 0x0100UL)
+#define NVIC ((NVIC_TYPE *) NVIC_BASE)
+#define NVIC_ST_CTRL (*((volatile unsigned int *)0xE000E010))
+#define NVIC_ST_RELOAD (*((volatile unsigned int *)0xE000E014))
+#define NVIC_ST_CURRENT (*((volatile unsigned int *)0xE000E018))
+
+/**
+ * NVIC structure
+ * @ISER: Offset: 0x000 (R/W) Interrupt Set Enable Register
+ * @ICER: Offset: 0x080 (R/W) Interrupt Clear Enable Register
+ * @ISPR: Offset: 0x100 (R/W) Interrupt Set Pending Register
+ * @ICPR: Offset: 0x180 (R/W) Interrupt Clear Pending Register
+ * @IP: Offset: 0x300 (R/W) Interrupt Priority Register
+ */
+typedef struct
+{
+ volatile unsigned int ISER[1];
+ unsigned int RESERVED0[31];
+ volatile unsigned int ICER[1];
+ unsigned int RSERVED1[31];
+ volatile unsigned int ISPR[1];
+ unsigned int RESERVED2[31];
+ volatile unsigned int ICPR[1];
+ unsigned int RESERVED3[31];
+ unsigned int RESERVED4[64];
+ volatile unsigned int IP[8];
+} NVIC_TYPE;
+
+static inline void NVIC_EnableIRQ(int IRQn)
+{
+ NVIC->ISER[0] = (1 << ((unsigned int)(IRQn) & 0x1F));
+}
+
+static inline void NVIC_DisableIRQ(int IRQn)
+{
+ NVIC->ICER[0] = (1 << ((unsigned int)(IRQn) & 0x1F));
+}
+
+static inline void NVIC_ClearPendingIRQ(int IRQn)
+{
+ NVIC->ICPR[0] = (1 << ((unsigned int)(IRQn) & 0x1F));
+}
+
+#define readl(c) ({unsigned int __v = (*(unsigned int *) (c)); __v;})
+#define writel(v, c) ((*(unsigned int *) (c)) = (v))
+
+void mdelay(unsigned int);
+int main(void);
+
+#endif
diff --git a/plat/rockchip/rk3399/drivers/m0/include/remotectl_pwm.h
b/plat/rockchip/rk3399/drivers/m0/include/remotectl_pwm.h
new file mode 100644
index 0000000..7668f64
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/include/remotectl_pwm.h
@@ -0,0 +1,162 @@
+
+#ifndef __RKXX_PWM_REMOTECTL_H__
+#define __RKXX_PWM_REMOTECTL_H__
+
+
+#define MAX_NUM_KEYS 60
+
+/* PWM0 registers */
+#define PWM_REG_CNTR 0x30 /* Counter Register */
+#define PWM_REG_HPR 0x34 /* Period Register */
+#define PWM_REG_LPR 0x38 /* Duty Cycle Register */
+#define PWM_REG_CTRL 0x3c /* Control Register */
+#define PWM3_REG_INTSTS 0x10 /* Interrupt Status Refister
For Pwm3*/
+#define PWM2_REG_INTSTS 0x20 /* Interrupt Status Refister
For Pwm2*/
+#define PWM1_REG_INTSTS 0x30 /* Interrupt Status Refister
For Pwm1*/
+#define PWM_REG_INTSTS 0x40 /* Interrupt Status Refister
For Pwm0*/
+#define PWM3_REG_INT_EN 0x14 /* Interrupt Enable Refister
For Pwm3*/
+#define PWM2_REG_INT_EN 0x24 /* Interrupt Enable Refister
For Pwm2*/
+#define PWM1_REG_INT_EN 0x34 /* Interrupt Enable Refister
For Pwm1*/
+#define PWM_REG_INT_EN 0x44 /* Interrupt Enable Refister
For Pwm0*/
+
+/*REG_CTRL bits definitions*/
+#define PWM_ENABLE (1 << 0)
+#define PWM_DISABLE (0 << 0)
+
+/*operation mode*/
+#define PWM_MODE_ONESHOT (0x00 << 1)
+#define PWM_MODE_CONTINUMOUS (0x01 << 1)
+#define PWM_MODE_CAPTURE (0x02 << 1)
+
+/*duty cycle output polarity*/
+#define PWM_DUTY_POSTIVE (0x01 << 3)
+#define PWM_DUTY_NEGATIVE (0x00 << 3)
+
+/*incative state output polarity*/
+#define PWM_INACTIVE_POSTIVE (0x01 << 4)
+#define PWM_INACTIVE_NEGATIVE (0x00 << 4)
+
+/*clock source select*/
+#define PWM_CLK_SCALE (1 << 9)
+#define PWM_CLK_NON_SCALE (0 << 9)
+
+#define PWM_CH0_INT (1 << 0)
+#define PWM_CH1_INT (1 << 1)
+#define PWM_CH2_INT (1 << 2)
+#define PWM_CH3_INT (1 << 3)
+
+#define PWM_CH0_POL (1 << 8)
+#define PWM_CH1_POL (1 << 9)
+#define PWM_CH2_POL (1 << 10)
+#define PWM_CH3_POL (1 << 11)
+
+#define PWM_CH0_INT_ENABLE (1 << 0)
+#define PWM_CH0_INT_DISABLE (0 << 0)
+
+#define PWM_CH1_INT_ENABLE (1 << 0)
+#define PWM_CH1_INT_DISABLE (0 << 1)
+
+#define PWM_CH2_INT_ENABLE (1 << 2)
+#define PWM_CH2_INT_DISABLE (0 << 2)
+
+#define PWM_CH3_INT_ENABLE (1 << 3)
+#define PWM_CH3_INT_DISABLE (0 << 3)
+
+/*prescale factor*/
+#define PWMCR_MIN_PRESCALE 0x00
+#define PWMCR_MAX_PRESCALE 0x07
+
+#define PWMDCR_MIN_DUTY 0x0001
+#define PWMDCR_MAX_DUTY 0xFFFF
+
+#define PWMPCR_MIN_PERIOD 0x0001
+#define PWMPCR_MAX_PERIOD 0xFFFF
+
+#define PWMPCR_MIN_PERIOD 0x0001
+#define PWMPCR_MAX_PERIOD 0xFFFF
+
+enum pwm_div {
+ PWM_DIV1 = (0x0 << 12),
+ PWM_DIV2 = (0x1 << 12),
+ PWM_DIV4 = (0x2 << 12),
+ PWM_DIV8 = (0x3 << 12),
+ PWM_DIV16 = (0x4 << 12),
+ PWM_DIV32 = (0x5 << 12),
+ PWM_DIV64 = (0x6 << 12),
+ PWM_DIV128 = (0x7 << 12),
+};
+
+
+
+
+/********************************************************************
+** ºê¶¨Òå *
+********************************************************************/
+#define RK_PWM_TIME_PRE_MIN 4000
+#define RK_PWM_TIME_PRE_MAX 5000
+
+#define RK_PWM_TIME_BIT0_MIN 480
+#define RK_PWM_TIME_BIT0_MAX 700
+
+#define RK_PWM_TIME_BIT1_MIN 1300
+#define RK_PWM_TIME_BIT1_MAX 2000
+
+#define RK_PWM_TIME_RPT_MIN 2000
+#define RK_PWM_TIME_RPT_MAX 2500
+
+#define RK_PWM_TIME_SEQ1_MIN 95000
+#define RK_PWM_TIME_SEQ1_MAX 98000
+
+#define RK_PWM_TIME_SEQ2_MIN 30000
+#define RK_PWM_TIME_SEQ2_MAX 55000
+
+
+//#define PWM_REG_INTSTS(n) ((4 - (n)) * 0x10)
+//#define PWM_CH_INT(n) BIT(n)
+//#define PWM_CH_POL(n) BIT(n+8)
+
+
+//#define base 0x0000
+#define KEY_CODE0 0xff00
+#define KEY_CODE1 0x4cb3
+#define KEY_CODE2 0x1dcc
+#define KEY_CODE3 0x4040
+
+
+
+#define KEY_POWER0 0x39
+#define KEY_POWER1 0xe7
+#define KEY_POWER2 0x1f
+#define KEY_POWER3 0xff
+#define KEY_POWER4 0xb2
+/********************************************************************
+** ½á¹¹¶¨Òå *
+********************************************************************/
+typedef enum _RMC_STATE
+{
+ RMC_IDLE,
+ RMC_PRELOAD,
+ RMC_USERCODE,
+ RMC_GETDATA,
+ RMC_SEQUENCE
+}eRMC_STATE;
+
+
+struct RKxx_remotectl_platform_data {
+ //struct rkxx_remotectl_button *buttons;
+ int nbuttons;
+ int rep;
+ int timer;
+ int wakeup;
+};
+/********************************************************************
+** ¸½¼Ó *
+********************************************************************/
+
+//void NVIC_EnableIRQ();
+//void NVIC_ClearPendingIRQ();
+//void M0_INT_ARB_SET_MASK();
+void remotect_IRQHandler(void);
+int remotect_init(void);
+
+#endif
diff --git a/plat/rockchip/rk3399/drivers/m0/include/rk3399.h
b/plat/rockchip/rk3399/drivers/m0/include/rk3399.h
new file mode 100644
index 0000000..d407fc3
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/include/rk3399.h
@@ -0,0 +1,48 @@
+/*
+ * RK3399 pmu-m0 generic head file.
+ *
+ * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Frank Wang <
frank...@rock-chips.com>
+ */
+
+#ifndef _RK3399_H
+#define _RK3399_H
+
+#define MCU_BASE 0x40000000
+#define PWM_BASE (MCU_BASE + 0x07420000)
+
+#define UART_DBG_BASE (MCU_BASE + 0x071a0000)
+#define PMU_BASE (MCU_BASE + 0x07310000)
+#define PMU_GRF_BASE (MCU_BASE + 0x07320000)
+
+#define CRU_BASE (MCU_BASE + 0x07760000)
+#define CRU_GLB_SRST_FST 0x0500
+#define GLB_SRST_FST_CFG_VAL 0xfdb9
+
+#define MCUJTAG_IOMUX_ADDR (PMU_GRF_BASE + 0x00014)
+#define MCUJTAG_IOMUX (0xf << (2 + 16) | 0x5 << 2)
+
+#define GPIO_IOMUX 0xf0005000
+
+#include "mcu.h"
+
+#define M0_INT_ARB_MASKN(n) (MCU_BASE + 0x0779c000 + (n) * 4)
+#define M0_INT_ARB_FLAGN(n) (MCU_BASE + 0x0779c080 + (n) * 4)
+
+/* set the mask of m0 interrupt arbiter */
+static inline void M0_INT_ARB_SET_MASK(int IRQn)
+{
+ unsigned int val = readl(M0_INT_ARB_MASKN(IRQn/8));
+ val |= 1 << (IRQn % 8);
+ writel(val, M0_INT_ARB_MASKN(IRQn/8));
+}
+
+/* get the flag of m0 interrupt arbiter */
+static inline unsigned int M0_INT_ARB_GET_FLAG(int IRQ)
+{
+ unsigned int val = (readl(M0_INT_ARB_FLAGN(IRQ))) & 0xff;
+
+ return val;
+}
+#endif
diff --git a/plat/rockchip/rk3399/drivers/m0/src/main.c
b/plat/rockchip/rk3399/drivers/m0/src/main.c
new file mode 100644
index 0000000..026cc27
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/src/main.c
@@ -0,0 +1,49 @@
+/*
+ * RK3399 pmu-m0 applications' main code.
+ *
+ * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Frank Wang <
frank...@rock-chips.com>
+ */
+
+#include "rk3399.h"
+
+#define PMU_PWRMODE_CON 0x20
+#define PMU_POWER_ST 0x78
+
+#define M0_SCR 0xE000ED10 /* System Control Register (SCR) */
+
+#define SCR_SLEEPDEEP_SHIFT (1 << 2)
+
+void system_wakeup(void)
+{
+ volatile unsigned int status_value;
+ unsigned int mode_con;
+
+ mode_con = readl(PMU_BASE + PMU_PWRMODE_CON);
+
+ while (1) {
+ status_value = readl(PMU_BASE + PMU_POWER_ST);
+ if (status_value) {
+ writel(mode_con & (~0x01), (PMU_BASE + PMU_PWRMODE_CON));
+ return;
+ }
+ }
+}
+
+int main(void)
+{
+ volatile unsigned int reg_src;
+
+ system_wakeup();
+
+ reg_src = readl(M0_SCR);
+
+ /* m0 enter deep sleep mode */
+ writel(reg_src | SCR_SLEEPDEEP_SHIFT, M0_SCR);
+
+ for(; ;)
+ __asm volatile("wfi");
+
+ return 0;
+}
diff --git a/plat/rockchip/rk3399/drivers/m0/src/remotectl_pwm.c
b/plat/rockchip/rk3399/drivers/m0/src/remotectl_pwm.c
new file mode 100644
index 0000000..e443bd2
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/src/remotectl_pwm.c
@@ -0,0 +1,237 @@
+
+
+
+
+#include "remotectl_pwm.h"
+#include "rk3399.h"
+#define PWM_IRQ 7
+#define remotect_IRQn 61
+
+struct rkxx_remotectl_drvdata *ddata;
+
+struct rkxx_remotectl_drvdata {
+ int state;
+ int nbuttons;
+ int result;
+ int scandata;
+ int count;
+ int keynum;
+ int maxkeybdnum;
+ int keycode;
+ int press;
+ int pre_press;
+ int irq;
+ int remote_pwm_id;
+ int handle_cpu_id;
+ int wakeup;
+ int clk_rate;
+ unsigned long period;
+ unsigned long temp_period;
+ int pwm_freq_nstime;
+ struct input_dev *input;
+
+};
+
+#if 1
+
+typedef volatile struct {
+ unsigned int rbr;/* 0x0000 */
+ unsigned int res0[(0x007c - 0x0004) / 4];
+ unsigned int usr;/* 0x007c */
+ unsigned int res1[(0x00fc - 0x0080) / 4];
+} uart_reg;
+
+void xpchar(unsigned char ch)
+{
+ uart_reg *puart = (uart_reg *)UART_DBG_BASE; /* uart2 */
+ puart->rbr = (unsigned int)ch;
+}
+
+void pchar(unsigned char ch)
+{
+ return;
+ uart_reg *puart = (uart_reg *)UART_DBG_BASE; /* uart2 */
+
+ while ((puart->usr & 0x01) || !(puart->usr & 0x02))
+ mdelay(1);
+
+ puart->rbr = (unsigned int)ch;
+}
+
+ void _print_hex (unsigned int n)
+{
+ return;
+ if (n & ~0xf) {
+ _print_hex(n >> 4);
+ n &= 0xf;
+ }
+
+ if (n < 10)
+ pchar((unsigned char)(n + '0'));
+ else
+ pchar((unsigned char)(n - 10 + 'A'));
+}
+
+#endif
+
+//Key recognition
+static void m0_pwm_remotectl_do_something(unsigned long period)
+{
+
+ switch (ddata->state) {
+ case RMC_IDLE: {
+ ;
+ break;
+ }
+ case RMC_PRELOAD: {
+ if ((RK_PWM_TIME_PRE_MIN < period) &&
+ (period < RK_PWM_TIME_PRE_MAX)) {
+ ddata->scandata = 0;
+ ddata->count = 0;
+ ddata->state = RMC_USERCODE;
+ } else {
+ ddata->state = RMC_PRELOAD;
+ ddata->scandata = 0;
+ ddata->count = 0;
+ }
+ break;
+ }
+ case RMC_USERCODE: {
+ if ((RK_PWM_TIME_BIT1_MIN < period) &&
+ (period < RK_PWM_TIME_BIT1_MAX))
+ ddata->scandata |= (0x01 << ddata->count);
+ ddata->count++;
+ if (ddata->count == 0x10) {
+ if (ddata->scandata == KEY_CODE0 ||
+ ddata->scandata == KEY_CODE1 ||
+ ddata->scandata == KEY_CODE2 ||
+ ddata->scandata == KEY_CODE3 ) {
+ ddata->state = RMC_GETDATA;
+ ddata->scandata = 0;
+ ddata->count = 0;
+ } else {
+ ddata->scandata = 0;
+ ddata->count = 0;
+ ddata->state = RMC_PRELOAD;
+ }
+ }
+ }
+ break;
+ case RMC_GETDATA: {
+ if ((RK_PWM_TIME_BIT1_MIN < period) &&
+ (period < RK_PWM_TIME_BIT1_MAX))
+ ddata->scandata |= (0x01<<ddata->count);
+ ddata->count++;
+ if (ddata->count < 0x10)
+ return;
+ if ((ddata->scandata&0x0ff) ==
+ ((~ddata->scandata >> 8) & 0x0ff)) {
+ if (ddata->scandata >> 8 == KEY_POWER0 ||
+ ddata->scandata >> 8 == KEY_POWER1 ||
+ ddata->scandata >> 8 == KEY_POWER2 ||
+ ddata->scandata >> 8 == KEY_POWER3 ||
+ ddata->scandata >> 8 == KEY_POWER4) {
+ ddata->state = RMC_PRELOAD;
+ ddata->scandata = 0;
+ ddata->count = 0;
+ pchar('G');
+ system_reset();
+
+ } else {
+ ddata->state = RMC_PRELOAD;
+ }
+ } else {
+ ddata->state = RMC_PRELOAD;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+//interrupt
+void remotect_IRQHandler(void)
+{
+ int val;
+ int temp_hpr;
+ int temp_lpr;
+ int temp_period;
+ unsigned int period;
+
+ NVIC_DisableIRQ(PWM_IRQ);
+
+ val = readl(PWM_BASE + PWM_REG_INTSTS);
+ if ((val & PWM_CH3_INT) == 0)
+ return ;
+ if ((val & PWM_CH3_POL) == 0) {
+ temp_hpr = readl(PWM_BASE + PWM_REG_HPR);
+ temp_lpr = readl(PWM_BASE + PWM_REG_LPR);
+ temp_period = ddata->pwm_freq_nstime * temp_lpr / 1000;
+ if (temp_period > RK_PWM_TIME_BIT0_MIN) {
+ period = ddata->temp_period + ddata->pwm_freq_nstime * temp_hpr / 1000;
+ m0_pwm_remotectl_do_something(period);
+ temp_period = 0;
+ period = 0;
+ temp_hpr = 0;
+ ddata->temp_period = 0;
+ }
+ else {
+ ddata->temp_period += ddata->pwm_freq_nstime
+ * (temp_hpr + temp_lpr) / 1000;
+ }
+ }
+ writel(PWM_CH3_INT, PWM_BASE + PWM_REG_INTSTS);
+
+ NVIC_ClearPendingIRQ(remotect_IRQn);
+ NVIC_EnableIRQ(PWM_IRQ);
+
+}
+
+
+static int m0_pwm_remotectl_hw_init(void)
+{
+ int val;
+
+ val = readl(PWM_BASE + PWM_REG_CTRL);
+ val = (val & 0xFFFFFFFE) | PWM_DISABLE;
+ writel(val, PWM_BASE + PWM_REG_CTRL);
+ val = readl(PWM_BASE + PWM_REG_CTRL);
+ val = (val & 0xFFFFFFF9) | PWM_MODE_CAPTURE;
+ writel(val, PWM_BASE + PWM_REG_CTRL);
+ val = readl(PWM_BASE + PWM_REG_CTRL);
+ val = (val & 0xFF008DFF) | 0x0006000;
+ writel(val, PWM_BASE + PWM_REG_CTRL);
+ val = readl(PWM_BASE + PWM_REG_INT_EN);
+ val = (val & 0xFFFFFFF7) | PWM_CH3_INT_ENABLE;
+ writel(val, PWM_BASE + PWM_REG_INT_EN);
+ val = readl(PWM_BASE + PWM_REG_CTRL);
+ val = (val & 0xFFFFFFFE) | PWM_ENABLE;
+ writel(val, PWM_BASE + PWM_REG_CTRL);
+
+ writel(GPIO_IOMUX, PMU_GRF_BASE + 0x0);
+
+
+ return 0;
+}
+
+/* Initialization */
+
+int remotect_init(void)
+{
+
+ ddata->state = RMC_PRELOAD;
+ ddata->temp_period = 0;
+ m0_pwm_remotectl_hw_init();
+
+ /* enable interrupt */
+ M0_INT_ARB_SET_MASK(remotect_IRQn);
+ NVIC_EnableIRQ(PWM_IRQ);
+
+ /* clear interrupt pending*/
+ NVIC_ClearPendingIRQ(remotect_IRQn);
+
+ ddata->pwm_freq_nstime = 0x481D;
+
+ return 0;
+}
diff --git a/plat/rockchip/rk3399/drivers/m0/src/startup.c
b/plat/rockchip/rk3399/drivers/m0/src/startup.c
new file mode 100644
index 0000000..c85f8fd
--- /dev/null
+++ b/plat/rockchip/rk3399/drivers/m0/src/startup.c
@@ -0,0 +1,135 @@
+/*
+ * RK3399 pmu-m0 startup code.
+ *
+ * Copyright (C) 2016 Fuzhou Rockchip Electronics Co., Ltd
+ *
+ * Frank Wang <
frank...@rock-chips.com>
+ */
+
+#include "rk3399.h"
+
+/* Stack configuration */
+#define STACK_SIZE 0x00000100
+__attribute__ ((section(".co_stack")))
+unsigned long pstack[STACK_SIZE];
+
+/* Macro definition */
+#define WEAK __attribute__ ((weak))
+
+/* System exception vector handler */
+__attribute__ ((used))
+void WEAK reset_handler(void);
+void WEAK nmi_handler(void);
+void WEAK hardware_fault_handler(void);
+void WEAK svc_handler(void);
+void WEAK pend_sv_handler(void);
+void WEAK systick_handler(void);
+
+/* Symbols defined in linker script */
+/* start address for the initialization values of the .data section */
+extern unsigned long _sidata;
+/* start address for the .data section */
+extern unsigned long _sdata;
+/* end address for the .data section */
+extern unsigned long _edata;
+/* start address for the .bss section */
+extern unsigned long _sbss;
+/* end address for the .bss section */
+extern unsigned long _ebss;
+/* end address for ram */
+extern void _eram;
+
+/* Function prototypes */
+static void default_reset_handler(void);
+static void default_handler(void);
+
+/**
+ * The minimal vector table for a Cortex M3. Note that the proper
constructs
+ * must be placed on this to ensure that it ends up at physical address
+ * 0x00000000.
+ */
+__attribute__ ((used,section(".isr_vector")))
+void (* const g_pfnVectors[])(void) =
+{
+ /* core Exceptions */
+ (void *)&pstack[STACK_SIZE], /* the initial stack pointer */
+ reset_handler,
+ nmi_handler,
+ hardware_fault_handler,
+ 0,0,0,0,0,0,0,
+ svc_handler,
+ 0,0,
+ pend_sv_handler,
+ systick_handler,
+
+ /* external exceptions */
+ 0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,
+ 0,0,0,0
+};
+
+/**
+ * This is the code that gets called when the processor first
+ * starts execution following a reset event. Only the absolutely
+ * necessary set is performed, after which the application
+ * supplied main() routine is called.
+ */
+static void default_reset_handler(void)
+{
+ /* initialize data and bss */
+ unsigned long *psrc, *pdst;
+
+ /* copy the data segment initializers from flash to SRAM */
+ psrc = &_sidata;
+ for(pdst = &_sdata; pdst < &_edata; )
+ *(pdst++) = *(psrc++);
+
+ /*
+ * zero fill the bss segment. This is done with inline assembly
+ * since this will clear the value of pdst if it is not kept
+ * in a register.
+ */
+ __asm(" ldr r0, =_sbss \n"
+ " ldr r1, =_ebss \n"
+ " mov r2, #0 \n"
+ " b zero_loop \n"
+ " .thumb_func \n"
+ "fill_zero: \n"
+ " str r2, [r0] \n"
+ " add r0, r0, #4 \n"
+ " .thumb_func \n"
+ "zero_loop: \n"
+ " cmp r0, r1 \n"
+ " bcc fill_zero ");
+
+ /* set mcujtag iomux before enter main */
+ writel(MCUJTAG_IOMUX, (unsigned int *)MCUJTAG_IOMUX_ADDR);
+
+ /* call the application's entry point */
+ main();
+}
+
+/**
+ * Provide weak aliases for each Exception handler to the Default_Handler.
+ * As they are weak aliases, any function with the same name will override
+ * this definition.
+ */
+#pragma weak reset_handler = default_reset_handler
+#pragma weak nmi_handler = default_handler
+#pragma weak hardware_fault_handler = default_handler
+#pragma weak svc_handler = default_handler
+#pragma weak pend_sv_handler = default_handler
+#pragma weak systick_handler = default_handler
+
+/**
+ * This is the code that gets called when the processor receives
+ * an unexpected interrupt. This simply enters an infinite loop,
+ * preserving the system state for examination by a debugger.
+ */
+static void default_handler(void)
+{
+ /* go into an infinite loop. */
+ while (1) ;
+}
--
To view, visit
https://chromium-review.googlesource.com/384278
To unsubscribe, visit
https://chromium-review.googlesource.com/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie9b47e403ae91a20a9148bf543fc7d3f53349409
Gerrit-PatchSet: 1
Gerrit-Project: chromiumos/third_party/arm-trusted-firmware
Gerrit-Branch: upstream_mirror/master
Gerrit-Owner: Xing Zheng <
zhen...@rock-chips.com>
Gerrit-Reviewer: Caesar Wang <
w...@rock-chips.com>
Gerrit-Reviewer: Douglas Anderson <
dian...@chromium.org>
Gerrit-Reviewer: Julius Werner <
jwe...@chromium.org>
Gerrit-Reviewer: Lin Huang <
h...@rock-chips.com>