mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
rk312x: support suspend and resume
Signed-off-by: 许盛飞 <xsf@rock-chips.com>
This commit is contained in:
@@ -1552,7 +1552,7 @@
|
||||
|
||||
"clk_crypto", "clk_i2s_2ch_out",
|
||||
"clk_i2s_2ch", "clk_testout";
|
||||
rockchip,suspend-clkgating-setting=<0x0 0x0>;
|
||||
rockchip,suspend-clkgating-setting=<0x11ff 0x0>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
@@ -1586,7 +1586,7 @@
|
||||
"clk_uart2_div", "uart2_frac",
|
||||
"clk_tsp", "reserved";
|
||||
|
||||
rockchip,suspend-clkgating-setting=<0x0 0x0>;
|
||||
rockchip,suspend-clkgating-setting=<0x000f 0x0>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
@@ -1617,7 +1617,7 @@
|
||||
|
||||
"spdif_frac", "clk_sdio",
|
||||
"clk_emmc", "clk_mipi_24m";
|
||||
rockchip,suspend-clkgating-setting=<0x0 0x0>;
|
||||
rockchip,suspend-clkgating-setting=<0x000f 0x0>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
@@ -1650,7 +1650,7 @@
|
||||
|
||||
"hclk_vdpu", "clk_gpu",
|
||||
"g_hclk_gps", "clk_sfc";
|
||||
rockchip,suspend-clkgating-setting=<0x0000 0x0000>;
|
||||
rockchip,suspend-clkgating-setting=<0x0060 0x0000>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
@@ -1685,7 +1685,7 @@
|
||||
"g_aclk_intmem", "reserved",
|
||||
"reserved", "reserved";
|
||||
|
||||
rockchip,suspend-clkgating-setting = <0x0000 0x0000>;
|
||||
rockchip,suspend-clkgating-setting = <0xff8f 0x0000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
@@ -1718,7 +1718,7 @@
|
||||
"reserved", "g_hclk_otg0",
|
||||
"g_pclk_acodec", "reserved";
|
||||
|
||||
rockchip,suspend-clkgating-setting = <0x0000 0x0000>;
|
||||
rockchip,suspend-clkgating-setting = <0x00f0 0x0000>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
@@ -1786,7 +1786,7 @@
|
||||
"g_pclk_spi0", "reserved",
|
||||
"g_pclk_saradc", "g_pclk_wdt";
|
||||
|
||||
rockchip,suspend-clkgating-setting = <0x0000 0x0000>;
|
||||
rockchip,suspend-clkgating-setting = <0x8080 0x0000>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
@@ -1820,7 +1820,7 @@
|
||||
"g_pclk_gpio3", "reserved",
|
||||
"reserved", "reserved";
|
||||
|
||||
rockchip,suspend-clkgating-setting=<0x0000 0x0000>;
|
||||
rockchip,suspend-clkgating-setting=<0xff0f 0x0000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
@@ -1853,7 +1853,7 @@
|
||||
"g_pclk_sim_card", "g_hclk_usb_peri",
|
||||
"g_hclk_pe_arbi", "g_aclk_peri_niu";
|
||||
|
||||
rockchip,suspend-clkgating-setting=<0x0 0x0>;
|
||||
rockchip,suspend-clkgating-setting=<0xf00f 0x0>;
|
||||
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
@@ -1887,7 +1887,7 @@
|
||||
"g_hclk_tsp", "g_clkin0_tsp",
|
||||
"g_hclk_usbhost", "clk_nandc";
|
||||
|
||||
rockchip,suspend-clkgating-setting = <0x0 0x0>; /* pwm logic vol */
|
||||
rockchip,suspend-clkgating-setting = <0x0000 0x0>; /* pwm logic vol */
|
||||
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
@@ -945,4 +945,17 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
rockchip_suspend {
|
||||
rockchip,ctrbits = <
|
||||
(0
|
||||
|RKPM_CTR_PWR_DMNS
|
||||
|RKPM_CTR_GTCLKS
|
||||
|RKPM_CTR_PLLS
|
||||
|RKPM_CTR_ARMOFF_LPMD
|
||||
)
|
||||
>;
|
||||
rockchip,pmic-suspend_gpios = <
|
||||
GPIO1_A1
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -99,4 +99,30 @@
|
||||
#define RK3288_CPU_AXI_HEVC_R_QOS_VIRT (RK3288_SERVICE_HEVC_VIRT + 0x0)
|
||||
#define RK3288_CPU_AXI_HEVC_W_QOS_VIRT (RK3288_SERVICE_HEVC_VIRT + 0x100)
|
||||
|
||||
#define RK312X_CPU_AXI_QOS_NUM_REGS 4
|
||||
#define RK312X_CPU_AXI_SAVE_QOS(array, base) do { \
|
||||
array[0] = readl_relaxed(base + CPU_AXI_QOS_PRIORITY); \
|
||||
array[1] = readl_relaxed(base + CPU_AXI_QOS_MODE); \
|
||||
array[2] = readl_relaxed(base + CPU_AXI_QOS_BANDWIDTH); \
|
||||
array[3] = readl_relaxed(base + CPU_AXI_QOS_SATURATION); \
|
||||
} while (0)
|
||||
#define RK312X_CPU_AXI_RESTORE_QOS(array, base) do { \
|
||||
writel_relaxed(array[0], base + CPU_AXI_QOS_PRIORITY); \
|
||||
writel_relaxed(array[1], base + CPU_AXI_QOS_MODE); \
|
||||
writel_relaxed(array[2], base + CPU_AXI_QOS_BANDWIDTH); \
|
||||
writel_relaxed(array[3], base + CPU_AXI_QOS_SATURATION); \
|
||||
} while (0)
|
||||
#define RK312X_SERVICE_VIO_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7000)
|
||||
|
||||
#define RK312X_CPU_AXI_VIO_RGA_QOS_VIRT (RK312X_SERVICE_VIO_VIRT)
|
||||
#define RK312X_CPU_AXI_VIO_EBC_QOS_VIRT (RK312X_SERVICE_VIO_VIRT + 0x80)
|
||||
#define RK312X_CPU_AXI_VIO_IEP_QOS_VIRT (RK312X_SERVICE_VIO_VIRT + 0x100)
|
||||
#define RK312X_CPU_AXI_VIO_LCDC0_QOS_VIRT (RK312X_SERVICE_VIO_VIRT + 0x180)
|
||||
#define RK312X_CPU_AXI_VIO_VIP0_QOS_VIRT (RK312X_SERVICE_VIO_VIRT + 0x200)
|
||||
|
||||
#define RK312X_SERVICE_GPU_VIRT (RK_CPU_AXI_BUS_VIRT + 0x5000)
|
||||
#define RK312X_CPU_AXI_GPU_QOS_VIRT (RK312X_SERVICE_GPU_VIRT)
|
||||
|
||||
#define RK312X_SERVICE_VIDEO_VIRT (RK_CPU_AXI_BUS_VIRT + 0x6000)
|
||||
#define RK312X_CPU_AXI_VIDEO_QOS_VIRT (RK312X_SERVICE_VIDEO_VIRT)
|
||||
#endif
|
||||
|
||||
916
arch/arm/mach-rockchip/pm-rk312x.c
Normal file
916
arch/arm/mach-rockchip/pm-rk312x.c
Normal file
@@ -0,0 +1,916 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/wakeup_reason.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/rockchip/cpu.h>
|
||||
#include <linux/rockchip/grf.h>
|
||||
#include <linux/rockchip/iomap.h>
|
||||
#include "pm.h"
|
||||
#include <linux/irqchip/arm-gic.h>
|
||||
|
||||
__weak void rk_usb_power_down(void);
|
||||
__weak void rk_usb_power_up(void);
|
||||
|
||||
#define GPIO_INTEN 0x30
|
||||
#define GPIO_INT_STATUS 0x40
|
||||
#define GIC_DIST_PENDING_SET 0x200
|
||||
#define DUMP_GPIO_INTEN(ID)\
|
||||
do { \
|
||||
u32 en = readl_relaxed(RK_GPIO_VIRT(ID) + GPIO_INTEN);\
|
||||
if (en) {\
|
||||
rkpm_ddr_printascii("GPIO" #ID "_INTEN: "); \
|
||||
rkpm_ddr_printhex(en); \
|
||||
rkpm_ddr_printch('\n'); \
|
||||
} \
|
||||
} while (0)
|
||||
#define RK312X_CRU_UNGATING_OPS(id) cru_writel(\
|
||||
CRU_W_MSK_SETBITS(0, (id) % 16, 0x1), RK312X_CRU_GATEID_CONS((id)))
|
||||
#define RK312X_CRU_GATING_OPS(id) cru_writel(\
|
||||
CRU_W_MSK_SETBITS(1, (id) % 16, 0x1), RK312X_CRU_GATEID_CONS((id)))
|
||||
|
||||
enum rk_plls_id {
|
||||
APLL_ID = 0,
|
||||
DPLL_ID,
|
||||
CPLL_ID,
|
||||
GPLL_ID,
|
||||
END_PLL_ID,
|
||||
};
|
||||
|
||||
static inline void uart_printch(char bbyte)
|
||||
{
|
||||
u32 reg_save[2];
|
||||
u32 u_clk_id = (RK312X_CLKGATE_UART0_SRC + CONFIG_RK_DEBUG_UART * 2);
|
||||
u32 u_pclk_id = (RK312X_CLKGATE_PCLK_UART0 + CONFIG_RK_DEBUG_UART);
|
||||
|
||||
reg_save[0] = cru_readl(RK312X_CRU_GATEID_CONS(u_clk_id));
|
||||
reg_save[1] = cru_readl(RK312X_CRU_GATEID_CONS(u_pclk_id));
|
||||
RK312X_CRU_UNGATING_OPS(u_clk_id);
|
||||
RK312X_CRU_UNGATING_OPS(u_pclk_id);
|
||||
rkpm_udelay(1);
|
||||
|
||||
write_uart:
|
||||
writel_relaxed(bbyte, RK_DEBUG_UART_VIRT);
|
||||
dsb();
|
||||
|
||||
while (!(readl_relaxed(RK_DEBUG_UART_VIRT + 0x14) & 0x40))
|
||||
barrier();
|
||||
|
||||
if (bbyte == '\n') {
|
||||
bbyte = '\r';
|
||||
goto write_uart;
|
||||
}
|
||||
|
||||
cru_writel(reg_save[0] | CRU_W_MSK(u_clk_id
|
||||
% 16, 0x1), RK312X_CRU_GATEID_CONS(u_clk_id));
|
||||
cru_writel(reg_save[1] | CRU_W_MSK(u_pclk_id
|
||||
% 16, 0x1), RK312X_CRU_GATEID_CONS(u_pclk_id));
|
||||
|
||||
if (0) {
|
||||
write_uart1:
|
||||
writel_relaxed(bbyte, RK_DEBUG_UART_VIRT);
|
||||
dsb();
|
||||
|
||||
while (!(readl_relaxed(RK_DEBUG_UART_VIRT + 0x14) & 0x40))
|
||||
barrier();
|
||||
if (bbyte == '\n') {
|
||||
bbyte = '\r';
|
||||
goto write_uart1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PIE_FUNC(sram_printch)(char bbyte)
|
||||
{
|
||||
/*uart_printch(byte);*/
|
||||
}
|
||||
static void pll_udelay(u32 udelay)
|
||||
{
|
||||
u32 mode;
|
||||
|
||||
mode = cru_readl(RK312X_CRU_MODE_CON);
|
||||
cru_writel(RK312X_PLL_MODE_SLOW(APLL_ID), RK312X_CRU_MODE_CON);
|
||||
rkpm_udelay(udelay * 5);
|
||||
cru_writel(mode|(RK312X_PLL_MODE_MSK(APLL_ID)
|
||||
<< 16), RK312X_CRU_MODE_CON);
|
||||
}
|
||||
|
||||
#define RK312X_PLL_PWR_DN_MSK (0x01 << 1)
|
||||
#define RK312X_PLL_BYPASS CRU_W_MSK_SETBITS(1, 0xF, 0x01)
|
||||
#define RK312X_PLL_NOBYPASS CRU_W_MSK_SETBITS(0, 0xF, 0x01)
|
||||
#define RK312X_PLL_RESET CRU_W_MSK_SETBITS(1, 14, 0x01)
|
||||
#define RK312X_PLL_RESET_RESUME CRU_W_MSK_SETBITS(0, 14, 0x01)
|
||||
|
||||
static u32 plls_con0_save[END_PLL_ID];
|
||||
static u32 plls_con1_save[END_PLL_ID];
|
||||
static u32 plls_con2_save[END_PLL_ID];
|
||||
static u32 cru_mode_con;
|
||||
|
||||
static void pm_pll_wait_lock(u32 pll_idx)
|
||||
{
|
||||
u32 delay = 600000U;
|
||||
|
||||
dsb();
|
||||
dsb();
|
||||
dsb();
|
||||
dsb();
|
||||
dsb();
|
||||
dsb();
|
||||
while (delay > 0) {
|
||||
if ((cru_readl(RK312X_PLL_CONS(pll_idx, 1)) & (0x1 << 10)))
|
||||
break;
|
||||
delay--;
|
||||
}
|
||||
if (delay == 0) {
|
||||
rkpm_ddr_printascii("unlock-pll:");
|
||||
rkpm_ddr_printhex(pll_idx);
|
||||
rkpm_ddr_printch('\n');
|
||||
}
|
||||
}
|
||||
|
||||
static inline void plls_suspend(u32 pll_id)
|
||||
{
|
||||
plls_con0_save[pll_id] = cru_readl(RK312X_PLL_CONS((pll_id), 0));
|
||||
plls_con1_save[pll_id] = cru_readl(RK312X_PLL_CONS((pll_id), 1));
|
||||
plls_con2_save[pll_id] = cru_readl(RK312X_PLL_CONS((pll_id), 2));
|
||||
|
||||
cru_writel(RK312X_PLL_BYPASS, RK312X_PLL_CONS((pll_id), 0));
|
||||
}
|
||||
static inline void plls_resume(u32 pll_id)
|
||||
{
|
||||
u32 pllcon0, pllcon1, pllcon2;
|
||||
|
||||
cru_writel(RK312X_PLL_MODE_SLOW(pll_id), RK312X_CRU_MODE_CON);
|
||||
/*cru_writel(RK312X_PLL_NOBYPASS, RK312x_PLL_CONS((pll_id), 0));*/
|
||||
|
||||
pllcon0 = plls_con0_save[pll_id];
|
||||
/*cru_readl(RK312x_PLL_CONS((pll_id),0));*/
|
||||
pllcon1 = plls_con1_save[pll_id];
|
||||
/*cru_readl(RK12x_PLL_CONS((pll_id),1));*/
|
||||
pllcon2 = plls_con2_save[pll_id];
|
||||
/*cru_readl(RK312x_PLL_CONS((pll_id),2));*/
|
||||
|
||||
/*cru_writel(RK312X_PLL_RESET, RK312X_PLL_CONS(pll_id, 1));*/
|
||||
|
||||
cru_writel(pllcon2, RK312X_PLL_CONS(pll_id, 2));
|
||||
cru_writel(pllcon1 | 0xf5ff0000, RK312X_PLL_CONS(pll_id, 1));
|
||||
cru_writel(pllcon0 | 0xffff0000, RK312X_PLL_CONS(pll_id, 0));
|
||||
|
||||
pll_udelay(5);
|
||||
|
||||
/*return form rest*/
|
||||
/*cru_writel(RK312X_PLL_RESET_RESUME, RK312X_PLL_CONS(pll_id, 1));*/
|
||||
|
||||
/*wating lock state*/
|
||||
pll_udelay(168);
|
||||
pm_pll_wait_lock(pll_id);
|
||||
}
|
||||
static u32 clk_sel0, clk_sel1, clk_sel10, clk_sel24, clk_sel29;
|
||||
static void pm_plls_suspend(void)
|
||||
{
|
||||
clk_sel0 = cru_readl(RK312X_CRU_CLKSELS_CON(0));
|
||||
clk_sel1 = cru_readl(RK312X_CRU_CLKSELS_CON(1));
|
||||
clk_sel10 = cru_readl(RK312X_CRU_CLKSELS_CON(10));
|
||||
clk_sel24 = cru_readl(RK312X_CRU_CLKSELS_CON(24));
|
||||
clk_sel29 = cru_readl(RK312X_CRU_CLKSELS_CON(29));
|
||||
|
||||
cru_mode_con = cru_readl(RK312X_CRU_MODE_CON);
|
||||
|
||||
/*CPLL*/
|
||||
cru_writel(RK312X_PLL_MODE_SLOW(CPLL_ID), RK312X_CRU_MODE_CON);
|
||||
|
||||
/*GPLL*/
|
||||
cru_writel(RK312X_PLL_MODE_SLOW(GPLL_ID), RK312X_CRU_MODE_CON);
|
||||
|
||||
/*crypto*/
|
||||
cru_writel(CRU_W_MSK_SETBITS(3, 0, 0x3), RK312X_CRU_CLKSELS_CON(24));
|
||||
|
||||
/* peri aclk hclk pclk*/
|
||||
cru_writel(0
|
||||
|CRU_W_MSK_SETBITS(0, 0, 0x1f)/*1 aclk*/
|
||||
|CRU_W_MSK_SETBITS(0, 8, 0x3)/*2 hclk 0 1:1,1 2:1 ,2 4:1*/
|
||||
|CRU_W_MSK_SETBITS(0, 12, 0x3)/* 2 0~3 1 2 4 8 div*/
|
||||
, RK312X_CRU_CLKSELS_CON(10));
|
||||
|
||||
/* pmu*/
|
||||
cru_writel(CRU_W_MSK_SETBITS(0, 8, 0x1f), RK312X_CRU_CLKSELS_CON(29));
|
||||
plls_suspend(CPLL_ID);
|
||||
plls_suspend(GPLL_ID);
|
||||
|
||||
/*apll*/
|
||||
cru_writel(RK312X_PLL_MODE_SLOW(APLL_ID), RK312X_CRU_MODE_CON);
|
||||
/*a7_core*/
|
||||
cru_writel(0 | CRU_W_MSK_SETBITS(0, 0, 0x1f)
|
||||
, RK312X_CRU_CLKSELS_CON(0));
|
||||
|
||||
/*pclk_dbg*/
|
||||
cru_writel(0 | CRU_W_MSK_SETBITS(3, 0, 0x7)
|
||||
, RK312X_CRU_CLKSELS_CON(1));
|
||||
plls_suspend(APLL_ID);
|
||||
}
|
||||
|
||||
static void pm_plls_resume(void)
|
||||
{
|
||||
cru_writel(clk_sel0 | CRU_W_MSK(0, 0x1f), RK312X_CRU_CLKSELS_CON(0));
|
||||
cru_writel(clk_sel1 | CRU_W_MSK(0, 0x7), RK312X_CRU_CLKSELS_CON(1));
|
||||
|
||||
plls_resume(APLL_ID);
|
||||
cru_writel(cru_mode_con
|
||||
|(RK312X_PLL_MODE_MSK(APLL_ID) << 16), RK312X_CRU_MODE_CON);
|
||||
|
||||
|
||||
/*peri aclk hclk pclk*/
|
||||
cru_writel(clk_sel10 | (CRU_W_MSK(0, 0x1f) | CRU_W_MSK(8, 0x3)
|
||||
| CRU_W_MSK(12, 0x3)), RK312X_CRU_CLKSELS_CON(10));
|
||||
|
||||
/* crypto*/
|
||||
cru_writel(clk_sel24 | CRU_W_MSK(0, 0x3), RK312X_CRU_CLKSELS_CON(24));
|
||||
|
||||
cru_writel(clk_sel29 | CRU_W_MSK(8, 0x1f), RK312X_CRU_CLKSELS_CON(29));
|
||||
|
||||
/* pmu alive */
|
||||
plls_resume(GPLL_ID);
|
||||
cru_writel(cru_mode_con | (RK312X_PLL_MODE_MSK(GPLL_ID) << 16)
|
||||
, RK312X_CRU_MODE_CON);
|
||||
|
||||
plls_resume(CPLL_ID);
|
||||
cru_writel(cru_mode_con | (RK312X_PLL_MODE_MSK(CPLL_ID) << 16)
|
||||
, RK312X_CRU_MODE_CON);
|
||||
}
|
||||
#ifdef CONFIG_RK_LAST_LOG
|
||||
extern void rk_last_log_text(char *text, size_t size);
|
||||
#endif
|
||||
|
||||
static void ddr_printch(char byte)
|
||||
{
|
||||
uart_printch(byte);
|
||||
#ifdef CONFIG_RK_LAST_LOG
|
||||
rk_last_log_text(&byte, 1);
|
||||
|
||||
if (byte == '\n') {
|
||||
byte = '\r';
|
||||
rk_last_log_text(&byte, 1);
|
||||
}
|
||||
#endif
|
||||
pll_udelay(2);
|
||||
}
|
||||
|
||||
static noinline void rk312x_pm_dump_inten(void)
|
||||
{
|
||||
DUMP_GPIO_INTEN(0);
|
||||
DUMP_GPIO_INTEN(1);
|
||||
DUMP_GPIO_INTEN(2);
|
||||
DUMP_GPIO_INTEN(3);
|
||||
}
|
||||
static noinline void rk312x_pm_dump_irq(void)
|
||||
{
|
||||
u32 irq[4];
|
||||
int i;
|
||||
|
||||
u32 irq_gpio = (readl_relaxed(RK_GIC_VIRT +
|
||||
GIC_DIST_PENDING_SET + 8) >> 4) & 0x0F;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(irq); i++)
|
||||
irq[i] = readl_relaxed(RK_GIC_VIRT +
|
||||
GIC_DIST_PENDING_SET + (1 + i) * 4);
|
||||
for (i = 0; i < ARRAY_SIZE(irq); i++) {
|
||||
if (irq[i])
|
||||
log_wakeup_reason(32 * (i + 1) + fls(irq[i]) - 1);
|
||||
}
|
||||
for (i = 0; i <= 3; i++) {
|
||||
if (irq_gpio & (1 << i)) {
|
||||
pr_debug("wakeup gpio%d: %08x\n", i
|
||||
, readl_relaxed(RK_GPIO_VIRT(i)
|
||||
+ GPIO_INT_STATUS));
|
||||
rkpm_ddr_printascii("wakeup gpio");
|
||||
rkpm_ddr_printhex(i);
|
||||
rkpm_ddr_printascii(":");
|
||||
rkpm_ddr_printhex(readl_relaxed(RK_GPIO_VIRT(i)
|
||||
+ GPIO_INT_STATUS));
|
||||
rkpm_ddr_printch('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rkpm_prepare(void)
|
||||
{
|
||||
rk312x_pm_dump_inten();
|
||||
}
|
||||
static void rkpm_finish(void)
|
||||
{
|
||||
rk312x_pm_dump_irq();
|
||||
}
|
||||
enum rk312x_pwr_mode_con {
|
||||
pmu_power_mode_en = 0,
|
||||
pmu_clk_core_src_gate_en,
|
||||
pmu_clk_bus_src_gate_en,
|
||||
pmu_global_int_disable,
|
||||
|
||||
pmu_core_pd_en,
|
||||
pmu_use_if,
|
||||
pmu_wait_osc_24m,
|
||||
pmu_sref_enter_en,
|
||||
|
||||
pmu_ddr_gating_en,
|
||||
pmu_int_en,
|
||||
pmu_ddr0io_ret_de_req,
|
||||
|
||||
pmu_clr_crypto = 16,
|
||||
pmu_clr_msch,
|
||||
pmu_clr_sys,
|
||||
pmu_clr_core,
|
||||
|
||||
pmu_clr_gpu,
|
||||
pmu_clr_vio,
|
||||
pmu_clr_video,
|
||||
pmu_clr_peri,
|
||||
};
|
||||
#define SOC_REMAP 12
|
||||
#define GRF_SOC_CON0 0x140
|
||||
|
||||
#define RK312X_IMEM_VIRT (RK_BOOTRAM_VIRT + SZ_32K)
|
||||
#define RKPM_BOOTRAM_PHYS (RK312X_IMEM_PHYS)
|
||||
#define RKPM_BOOTRAM_BASE (RK312X_IMEM_VIRT)
|
||||
#define RKPM_BOOTRAM_SIZE (RK312X_IMEM_SIZE)
|
||||
|
||||
/*sys resume code in boot ram*/
|
||||
#define RKPM_BOOT_CODE_PHY (RKPM_BOOTRAM_PHYS + RKPM_BOOT_CODE_OFFSET)
|
||||
#define RKPM_BOOT_CODE_BASE (RKPM_BOOTRAM_BASE + RKPM_BOOT_CODE_OFFSET)
|
||||
|
||||
|
||||
/*sys resume data in boot ram*/
|
||||
#define RKPM_BOOT_DATA_PHY (RKPM_BOOTRAM_PHYS + RKPM_BOOT_DATA_OFFSET)
|
||||
#define RKPM_BOOT_DATA_BASE (RKPM_BOOTRAM_BASE + RKPM_BOOT_DATA_OFFSET)
|
||||
|
||||
/*ddr resume data in boot ram*/
|
||||
#define RKPM_BOOT_DDRCODE_PHY (RKPM_BOOTRAM_PHYS + RKPM_BOOT_DDRCODE_OFFSET)
|
||||
#define RKPM_BOOT_DDRCODE_BASE (RKPM_BOOTRAM_BASE + RKPM_BOOT_DDRCODE_OFFSET)
|
||||
|
||||
/*#define RKPM_BOOT_CPUSP_PHY (RKPM_BOOTRAM_PHYS+((RKPM_BOOTRAM_SIZE-1)&~0x7))*/
|
||||
#define RKPM_BOOT_CPUSP_PHY (0x00 + ((RKPM_BOOTRAM_SIZE - 1) & (~(0x7))))
|
||||
|
||||
/*the value is used to control cpu resume flow*/
|
||||
static u32 sleep_resume_data[RKPM_BOOTDATA_ARR_SIZE];
|
||||
static char *resume_data_base = (char *)(RKPM_BOOT_DATA_BASE);
|
||||
/*static char *resume_data_phy= (char *)( RKPM_BOOT_DATA_PHY);*/
|
||||
|
||||
/*****save boot sram**********************/
|
||||
#define BOOT_RAM_SAVE_SIZE (RKPM_BOOTRAM_SIZE + 4 * 10)
|
||||
#define INT_RAM_SIZE (64 * 1024)
|
||||
static char boot_ram_data[BOOT_RAM_SAVE_SIZE];/*8K + 40byte*/
|
||||
static char int_ram_data[INT_RAM_SIZE];
|
||||
/******resume code *****************
|
||||
#define RKPM_BOOT_CODE_OFFSET (0x00)
|
||||
#define RKPM_BOOT_CODE_PHY (RKPM_BOOTRAM_PHYS + PM_BOOT_CODE_OFFSET)
|
||||
#define RKPM_BOOT_CODE_BASE (RKPM_BOOTRAM_BASE + PM_BOOT_CODE_OFFSET)
|
||||
#define RKPM_BOOT_CODE_SIZE (0x100)
|
||||
**************************************************/
|
||||
extern void rkpm_slp_cpu_resume(void);
|
||||
|
||||
static void sram_data_for_sleep(char *boot_save, char *int_save, u32 flag)
|
||||
{
|
||||
char *addr_base, *addr_phy, *data_src, *data_dst;
|
||||
u32 sr_size, data_size;
|
||||
|
||||
addr_base = (char *)RKPM_BOOTRAM_BASE;
|
||||
addr_phy = (char *)RKPM_BOOTRAM_PHYS;
|
||||
sr_size = RKPM_BOOTRAM_SIZE; /*SZ8k*/
|
||||
/**********save boot sarm***********************************/
|
||||
if (boot_save)
|
||||
memcpy(boot_save, addr_base, sr_size);
|
||||
/**********move resume code and data to boot sram*************/
|
||||
data_dst = (char *)RKPM_BOOT_CODE_BASE;
|
||||
data_src = (char *)rkpm_slp_cpu_resume;
|
||||
data_size = RKPM_BOOT_CODE_SIZE;
|
||||
|
||||
memcpy(data_dst, data_src, data_size);
|
||||
data_dst = (char *)resume_data_base;
|
||||
data_src = (char *)sleep_resume_data;
|
||||
data_size = sizeof(sleep_resume_data);
|
||||
memcpy((char *)data_dst, (char *)data_src, data_size);
|
||||
}
|
||||
static u32 rk312x_powermode;
|
||||
static u32 pmu_pwrmode_con;
|
||||
static u32 gpio_pmic_sleep_mode;
|
||||
static u32 grf_soc_con0;
|
||||
static u32 pmu_wakeup_conf;
|
||||
static u32 pmic_sleep_gpio;
|
||||
|
||||
static u32 rkpm_slp_mode_set(u32 ctrbits)
|
||||
{
|
||||
u32 pwr_mode_config;
|
||||
|
||||
if ((RKPM_CTR_ARMOFF_LPMD & ctrbits) == 0)
|
||||
return 0;
|
||||
|
||||
pmu_wakeup_conf = pmu_readl(RK312X_PMU_WAKEUP_CFG);
|
||||
/*grf_soc_con0 = grf_readl(GRF_SOC_CON0);*/
|
||||
/*grf_writel((1 << SOC_REMAP)
|
||||
| (1 << (SOC_REMAP + 16)), GRF_SOC_CON0);*/
|
||||
/*grf_gpio1a_iomux = grf_readl(0x00b8);*/
|
||||
/*grf_writel(0x00030003, 0xb8);*/
|
||||
|
||||
pmu_writel(0x01, RK312X_PMU_WAKEUP_CFG);
|
||||
/* arm interrupt wake-up enable*/
|
||||
/*grf_writel((1 << SOC_REMAP)
|
||||
| (1 << (SOC_REMAP + 16)), GRF_SOC_CON0);*/
|
||||
/*remap bit control, when soc_remap = 1, the bootrom is mapped to
|
||||
address 0x10100000,and internal memory is mapped to address 0x0.*/
|
||||
|
||||
/*grf_writel(0X00030002, 0xb4);
|
||||
rk3126 GPIO1A1 : RK3128 GPIO3C1 iomux pmic-sleep*/
|
||||
if ((pmic_sleep_gpio == 0) || (pmic_sleep_gpio == 0x1a10)) {
|
||||
gpio_pmic_sleep_mode = grf_readl(0xb8);
|
||||
grf_writel(0X000C000C, 0xb8);
|
||||
}
|
||||
/*rk3126 GPIO1A1 : RK3128 GPIO3C1 iomux pmic-sleep*/
|
||||
if (pmic_sleep_gpio == 0x3c10) {
|
||||
gpio_pmic_sleep_mode = grf_readl(0xe4);
|
||||
grf_writel(0X000C0004, 0xe4);
|
||||
}
|
||||
/*rk3126 GPIO3C1 : RK3128 GPIO3C1 iomux pmic-sleep*/
|
||||
|
||||
pwr_mode_config = BIT(pmu_power_mode_en) | BIT(pmu_global_int_disable);
|
||||
pmu_pwrmode_con = pmu_readl(RK312X_PMU_PWRMODE_CON);
|
||||
if (rkpm_chk_val_ctrbits(ctrbits, RKPM_CTR_IDLEAUTO_MD)) {
|
||||
rkpm_ddr_printascii("-autoidle-");
|
||||
pwr_mode_config |= BIT(pmu_clk_core_src_gate_en);
|
||||
} else if (rkpm_chk_val_ctrbits(ctrbits, RKPM_CTR_ARMDP_LPMD)) {
|
||||
rkpm_ddr_printascii("-armdp-");
|
||||
pwr_mode_config |= BIT(pmu_core_pd_en);
|
||||
} else if (rkpm_chk_val_ctrbits(ctrbits, RKPM_CTR_ARMOFF_LPMD)) {
|
||||
rkpm_ddr_printascii("-armoff-");
|
||||
/*arm power off */
|
||||
pwr_mode_config |= 0
|
||||
|BIT(pmu_clk_core_src_gate_en)
|
||||
|BIT(pmu_clk_bus_src_gate_en)
|
||||
| BIT(pmu_core_pd_en)
|
||||
/* | BIT(pmu_use_if)//aaa*/
|
||||
| BIT(pmu_sref_enter_en)
|
||||
|BIT(pmu_int_en)
|
||||
/* | BIT(pmu_wait_osc_24m)*/
|
||||
| BIT(pmu_ddr_gating_en)
|
||||
| BIT(pmu_ddr0io_ret_de_req)
|
||||
| BIT(pmu_clr_core)
|
||||
| BIT(pmu_clr_crypto)
|
||||
| BIT(pmu_clr_sys)
|
||||
/*| BIT(pmu_clr_vio)*/
|
||||
/*| BIT(pmu_clr_video)*/
|
||||
| BIT(pmu_clr_peri)
|
||||
| BIT(pmu_clr_msch)
|
||||
/*| BIT(pmu_clr_gpu) */
|
||||
;
|
||||
}
|
||||
pmu_writel(32 * 30, RK312X_PMU_OSC_CNT);
|
||||
pmu_writel(pwr_mode_config, RK312X_PMU_PWRMODE_CON);
|
||||
rk312x_powermode = pwr_mode_config;
|
||||
return pmu_readl(RK312X_PMU_PWRMODE_CON);
|
||||
}
|
||||
|
||||
static void sram_code_data_save(u32 pwrmode)
|
||||
{
|
||||
sleep_resume_data[RKPM_BOOTDATA_L2LTY_F] = 0;
|
||||
sleep_resume_data[RKPM_BOOTDATA_ARM_ERRATA_818325_F] = 0;
|
||||
sleep_resume_data[RKPM_BOOTDATA_DDR_F] = 0;
|
||||
sleep_resume_data[RKPM_BOOTDATA_CPUSP] = RKPM_BOOT_CPUSP_PHY;
|
||||
/*in sys resume ,ddr is need resume*/
|
||||
sleep_resume_data[RKPM_BOOTDATA_CPUCODE] = virt_to_phys(cpu_resume);
|
||||
/*in sys resume ,ddr is need resume*/
|
||||
|
||||
sram_data_for_sleep(boot_ram_data, int_ram_data, 1);
|
||||
flush_cache_all();
|
||||
outer_flush_all();
|
||||
local_flush_tlb_all();
|
||||
}
|
||||
|
||||
#define RK_GICD_BASE (RK_GIC_VIRT)
|
||||
#define RK_GICC_BASE (RK_GIC_VIRT+RK312X_GIC_DIST_SIZE)
|
||||
#define PM_IRQN_START 32
|
||||
#define PM_IRQN_END 107
|
||||
#define gic_reg_dump(a, b, c) {}
|
||||
static u32 slp_gic_save[260+50];
|
||||
|
||||
static void rkpm_gic_dist_save(u32 *context)
|
||||
{
|
||||
int i = 0, j, irqstart = 0;
|
||||
unsigned int gic_irqs;
|
||||
|
||||
gic_irqs = readl_relaxed(RK_GICD_BASE + GIC_DIST_CTR) & 0x1f;
|
||||
gic_irqs = (gic_irqs + 1) * 32;
|
||||
if (gic_irqs > 1020)
|
||||
gic_irqs = 1020;
|
||||
|
||||
irqstart = PM_IRQN_START;
|
||||
|
||||
i = 0;
|
||||
|
||||
for (j = irqstart; j < gic_irqs; j += 16)
|
||||
context[i++] = readl_relaxed(RK_GICD_BASE
|
||||
+ GIC_DIST_CONFIG + (j * 4) / 16);
|
||||
gic_reg_dump("gic level", j, RK_GICD_BASE + GIC_DIST_CONFIG);
|
||||
|
||||
/*
|
||||
* Set all global interrupts to this CPU only.
|
||||
*/
|
||||
for (j = 0; j < gic_irqs; j += 4)
|
||||
context[i++] = readl_relaxed(RK_GICD_BASE
|
||||
+ GIC_DIST_TARGET + (j * 4) / 4);
|
||||
gic_reg_dump("gic trig", j, RK_GICD_BASE + GIC_DIST_TARGET);
|
||||
|
||||
for (j = 0; j < gic_irqs; j += 4)
|
||||
context[i++] = readl_relaxed(RK_GICD_BASE
|
||||
+ GIC_DIST_PRI + (j * 4) / 4);
|
||||
gic_reg_dump("gic pri", j, RK_GICD_BASE + GIC_DIST_PRI);
|
||||
|
||||
for (j = 0; j < gic_irqs; j += 32)
|
||||
context[i++] = readl_relaxed(RK_GICD_BASE
|
||||
+ GIC_DIST_IGROUP + (j * 4) / 32);
|
||||
gic_reg_dump("gic secure", j, RK_GICD_BASE + 0x80);
|
||||
|
||||
for (j = irqstart; j < gic_irqs; j += 32)
|
||||
context[i++] = readl_relaxed(RK_GICD_BASE
|
||||
+ GIC_DIST_PENDING_SET + (j * 4) / 32);
|
||||
gic_reg_dump("gic PENDING", j, RK_GICD_BASE
|
||||
+ GIC_DIST_PENDING_SET);
|
||||
|
||||
for (j = 0; j < gic_irqs; j += 32)
|
||||
context[i++] = readl_relaxed(RK_GICD_BASE
|
||||
+ GIC_DIST_ENABLE_SET + (j * 4) / 32);
|
||||
gic_reg_dump("gic en", j, RK_GICD_BASE + GIC_DIST_ENABLE_SET);
|
||||
gic_reg_dump("gicc", 0x1c, RK_GICC_BASE);
|
||||
gic_reg_dump("giccfc", 0, RK_GICC_BASE + 0xfc);
|
||||
|
||||
context[i++] = readl_relaxed(RK_GICC_BASE + GIC_CPU_PRIMASK);
|
||||
context[i++] = readl_relaxed(RK_GICD_BASE + GIC_DIST_CTRL);
|
||||
context[i++] = readl_relaxed(RK_GICC_BASE + GIC_CPU_CTRL);
|
||||
/*
|
||||
context[i++]=readl_relaxed(RK_GICC_BASE + GIC_CPU_BINPOINT);
|
||||
context[i++]=readl_relaxed(RK_GICC_BASE + GIC_CPU_PRIMASK);
|
||||
context[i++]=readl_relaxed(RK_GICC_BASE + GIC_DIST_SOFTINT);
|
||||
context[i++]=readl_relaxed(RK_GICC_BASE + GIC_CPU_CTRL);
|
||||
context[i++]=readl_relaxed(RK_GICD_BASE + GIC_DIST_CTRL);
|
||||
*/
|
||||
for (j = irqstart; j < gic_irqs; j += 32) {
|
||||
writel_relaxed(0xffffffff, RK_GICD_BASE
|
||||
+ GIC_DIST_ENABLE_CLEAR + j * 4 / 32);
|
||||
dsb();
|
||||
}
|
||||
writel_relaxed(0xffff0000, RK_GICD_BASE + GIC_DIST_ENABLE_CLEAR);
|
||||
writel_relaxed(0x0000ffff, RK_GICD_BASE + GIC_DIST_ENABLE_SET);
|
||||
|
||||
writel_relaxed(0, RK_GICC_BASE + GIC_CPU_CTRL);
|
||||
writel_relaxed(0, RK_GICD_BASE + GIC_DIST_CTRL);
|
||||
}
|
||||
static void rkpm_peri_save(u32 power_mode)
|
||||
{
|
||||
rkpm_gic_dist_save(&slp_gic_save[0]);
|
||||
}
|
||||
|
||||
static void rkpm_save_setting(u32 ctrbits)
|
||||
{
|
||||
u32 pd_cpu;
|
||||
|
||||
if ((RKPM_CTR_ARMOFF_LPMD & ctrbits) == 0)
|
||||
return;
|
||||
|
||||
rkpm_slp_mode_set(ctrbits);
|
||||
if (rk312x_powermode & BIT(pmu_power_mode_en)) {
|
||||
sram_code_data_save(rk312x_powermode);
|
||||
rkpm_peri_save(rk312x_powermode);
|
||||
}
|
||||
grf_soc_con0 = grf_readl(GRF_SOC_CON0);
|
||||
|
||||
grf_writel((1 << SOC_REMAP) | (1 << (SOC_REMAP + 16)), GRF_SOC_CON0);
|
||||
|
||||
for (pd_cpu = PD_CPU_1; pd_cpu <= PD_CPU_3; pd_cpu++) {
|
||||
writel_relaxed(0x20000 << (pd_cpu - PD_CPU_1),
|
||||
RK_CRU_VIRT + RK312X_CRU_SOFTRSTS_CON(0));
|
||||
dsb();
|
||||
udelay(10);
|
||||
}
|
||||
}
|
||||
|
||||
#define UART_DLL 0 /* Out: Divisor Latch Low */
|
||||
#define UART_DLM 1 /* Out: Divisor Latch High */
|
||||
#define UART_IER 1
|
||||
#define UART_FCR 2
|
||||
#define UART_LCR 3 /* Out: Line Control Register */
|
||||
#define UART_MCR 4
|
||||
|
||||
void slp312x_uartdbg_resume(void)
|
||||
{
|
||||
void __iomem *b_addr = RK_DEBUG_UART_VIRT;
|
||||
u32 pclk_id = RK312X_CLKGATE_PCLK_UART2;
|
||||
u32 clk_id = (RK312X_CLKGATE_UART0_SRC + 2 * 2);
|
||||
u32 gate_reg[2];
|
||||
u32 rfl_reg, lsr_reg;
|
||||
|
||||
gate_reg[0] = cru_readl(RK312X_CRU_GATEID_CONS(pclk_id));
|
||||
gate_reg[1] = cru_readl(RK312X_CRU_GATEID_CONS(clk_id));
|
||||
|
||||
RK312X_CRU_UNGATING_OPS(pclk_id);
|
||||
grf_writel(0x00f00000, 0x00c0);
|
||||
|
||||
do {
|
||||
cru_writel(CRU_W_MSK_SETBITS(0x2, 8, 0x3)
|
||||
, RK312X_CRU_CLKSELS_CON(16));
|
||||
cru_writel(0|CRU_W_MSK_SETBITS(1, 9, 0x1)
|
||||
, RK312X_CRU_SOFTRSTS_CON(2));
|
||||
dsb();
|
||||
dsb();
|
||||
rkpm_udelay(10);
|
||||
cru_writel(0 | CRU_W_MSK_SETBITS(0, 9, 0x1)
|
||||
, RK312X_CRU_SOFTRSTS_CON(2));
|
||||
|
||||
reg_writel(0x83, b_addr + UART_LCR*4);
|
||||
|
||||
reg_writel(0xd, b_addr + UART_DLL*4);
|
||||
reg_writel(0x0, b_addr + UART_DLM*4);
|
||||
|
||||
reg_writel(0x3, b_addr + UART_LCR*4);
|
||||
|
||||
reg_writel(0x5, b_addr + UART_IER*4);
|
||||
reg_writel(0xc1, b_addr + UART_FCR*4);
|
||||
|
||||
rfl_reg = readl_relaxed(b_addr + 0x84);
|
||||
lsr_reg = readl_relaxed(b_addr + 0x14);
|
||||
} while ((rfl_reg & 0x1f) || (lsr_reg & 0xf));
|
||||
|
||||
cru_writel(CRU_W_MSK_SETBITS(0x2, 8, 0x3), RK312X_CRU_CLKSELS_CON(16));
|
||||
|
||||
grf_writel(0x00f000a0, 0x00c0);
|
||||
|
||||
cru_writel(gate_reg[0] | CRU_W_MSK(pclk_id % 16, 0x1)
|
||||
, RK312X_CRU_GATEID_CONS(pclk_id));
|
||||
cru_writel(gate_reg[1] | CRU_W_MSK(clk_id % 16, 0x1)
|
||||
, RK312X_CRU_GATEID_CONS(clk_id));
|
||||
}
|
||||
|
||||
static void rkpm_gic_dist_resume(u32 *context)
|
||||
{
|
||||
int i = 0, j, irqstart = 0;
|
||||
unsigned int gic_irqs;
|
||||
|
||||
gic_irqs = readl_relaxed(RK_GICD_BASE + GIC_DIST_CTR) & 0x1f;
|
||||
gic_irqs = (gic_irqs + 1) * 32;
|
||||
if (gic_irqs > 1020)
|
||||
gic_irqs = 1020;
|
||||
|
||||
irqstart = PM_IRQN_START;
|
||||
|
||||
writel_relaxed(0, RK_GICC_BASE + GIC_CPU_CTRL);
|
||||
dsb();
|
||||
writel_relaxed(0, RK_GICD_BASE + GIC_DIST_CTRL);
|
||||
dsb();
|
||||
for (j = irqstart; j < gic_irqs; j += 32) {
|
||||
writel_relaxed(0xffffffff, RK_GICD_BASE
|
||||
+ GIC_DIST_ENABLE_CLEAR + j * 4 / 32);
|
||||
dsb();
|
||||
}
|
||||
|
||||
i = 0;
|
||||
|
||||
for (j = irqstart; j < gic_irqs; j += 16) {
|
||||
writel_relaxed(context[i++], RK_GICD_BASE
|
||||
+ GIC_DIST_CONFIG + j * 4 / 16);
|
||||
dsb();
|
||||
}
|
||||
gic_reg_dump("gic level", j, RK_GICD_BASE + GIC_DIST_CONFIG);
|
||||
|
||||
/*
|
||||
* Set all global interrupts to this CPU only.
|
||||
*/
|
||||
for (j = 0; j < gic_irqs; j += 4) {
|
||||
writel_relaxed(context[i++], RK_GICD_BASE
|
||||
+ GIC_DIST_TARGET + (j * 4) / 4);
|
||||
dsb();
|
||||
}
|
||||
gic_reg_dump("gic target", j, RK_GICD_BASE + GIC_DIST_TARGET);
|
||||
|
||||
for (j = 0; j < gic_irqs; j += 4) {
|
||||
writel_relaxed(context[i++], RK_GICD_BASE
|
||||
+ GIC_DIST_PRI + (j * 4) / 4);
|
||||
dsb();
|
||||
}
|
||||
gic_reg_dump("gic pri", j, RK_GICD_BASE + GIC_DIST_PRI);
|
||||
|
||||
for (j = 0; j < gic_irqs; j += 32) {
|
||||
writel_relaxed(context[i++], RK_GICD_BASE
|
||||
+ GIC_DIST_IGROUP + (j * 4) / 32);
|
||||
dsb();
|
||||
}
|
||||
gic_reg_dump("gic secu", j, RK_GICD_BASE + 0x80);
|
||||
|
||||
for (j = irqstart; j < gic_irqs; j += 32) {
|
||||
/*writel_relaxed(context[i++],
|
||||
RK_GICD_BASE + GIC_DIST_PENDING_SET + j * 4 / 32);*/
|
||||
i++;
|
||||
dsb();
|
||||
}
|
||||
|
||||
gic_reg_dump("gic pending", j, RK_GICD_BASE + GIC_DIST_PENDING_SET);
|
||||
|
||||
if (0) {
|
||||
for (j = 0; j < gic_irqs; j += 32) {
|
||||
writel_relaxed(context[i++], RK_GICD_BASE
|
||||
+ GIC_DIST_ENABLE_CLEAR + j * 4 / 32);
|
||||
dsb();
|
||||
}
|
||||
gic_reg_dump("gic disable", j, RK_GICD_BASE
|
||||
+ GIC_DIST_ENABLE_CLEAR);
|
||||
} else {
|
||||
for (j = irqstart; j < gic_irqs; j += 32)
|
||||
writel_relaxed(0xffffffff, RK_GICD_BASE
|
||||
+ GIC_DIST_ENABLE_CLEAR + j * 4 / 32);
|
||||
writel_relaxed(0xffff0000, RK_GICD_BASE
|
||||
+ GIC_DIST_ENABLE_CLEAR);
|
||||
writel_relaxed(0x0000ffff, RK_GICD_BASE + GIC_DIST_ENABLE_SET);
|
||||
}
|
||||
|
||||
/*enable*/
|
||||
for (j = 0; j < gic_irqs; j += 32) {
|
||||
writel_relaxed(context[i++], RK_GICD_BASE
|
||||
+ GIC_DIST_ENABLE_SET + (j * 4) / 32);
|
||||
dsb();
|
||||
}
|
||||
|
||||
gic_reg_dump("gic enable", j, RK_GICD_BASE + GIC_DIST_ENABLE_SET);
|
||||
|
||||
writel_relaxed(context[i++], RK_GICC_BASE + GIC_CPU_PRIMASK);
|
||||
writel_relaxed(context[i++], RK_GICD_BASE + GIC_DIST_CTRL);
|
||||
writel_relaxed(context[i++], RK_GICC_BASE + GIC_CPU_CTRL);
|
||||
|
||||
gic_reg_dump("gicc", 0x1c, RK_GICC_BASE);
|
||||
gic_reg_dump("giccfc", 0, RK_GICC_BASE + 0xfc);
|
||||
}
|
||||
|
||||
static void sram_data_resume(char *boot_save, char *int_save, u32 flag)
|
||||
{
|
||||
char *addr_base, *addr_phy;
|
||||
u32 sr_size;
|
||||
|
||||
addr_base = (char *)RKPM_BOOTRAM_BASE;
|
||||
addr_phy = (char *)RKPM_BOOTRAM_PHYS;
|
||||
sr_size = RKPM_BOOTRAM_SIZE;
|
||||
/* save boot sram*/
|
||||
if (boot_save)
|
||||
memcpy(addr_base, boot_save, sr_size);
|
||||
|
||||
flush_icache_range((unsigned long)addr_base
|
||||
, (unsigned long)addr_base + sr_size);
|
||||
outer_clean_range((phys_addr_t) addr_phy
|
||||
, (phys_addr_t)addr_phy+sr_size);
|
||||
}
|
||||
|
||||
static inline void sram_code_data_resume(u32 pwrmode)
|
||||
{
|
||||
sram_data_resume(boot_ram_data
|
||||
, int_ram_data, sleep_resume_data[RKPM_BOOTDATA_DDR_F]);
|
||||
}
|
||||
|
||||
static inline void rkpm_slp_mode_set_resume(void)
|
||||
{
|
||||
u32 pd_cpu;
|
||||
|
||||
pmu_writel(pmu_wakeup_conf, RK312X_PMU_WAKEUP_CFG);
|
||||
/* arm interrupt wake-up enable*/
|
||||
pmu_writel(pmu_pwrmode_con, RK312X_PMU_PWRMODE_CON);
|
||||
|
||||
for (pd_cpu = PD_CPU_1; pd_cpu <= PD_CPU_3; pd_cpu++) {
|
||||
writel_relaxed(0x20002 << (pd_cpu - PD_CPU_1),
|
||||
RK_CRU_VIRT + RK312X_CRU_SOFTRSTS_CON(0));
|
||||
dsb();
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
grf_writel(grf_soc_con0 | (1 << (SOC_REMAP + 16)), GRF_SOC_CON0);
|
||||
|
||||
if ((pmic_sleep_gpio == 0) || (pmic_sleep_gpio == 0x1a10))
|
||||
grf_writel(0X000C000C | gpio_pmic_sleep_mode, 0xb8);
|
||||
/*rk3126 GPIO1A1 : RK3128 GPIO3C1 iomux pmic-sleep*/
|
||||
if (pmic_sleep_gpio == 0x3c10)
|
||||
grf_writel(0X000C0004 | gpio_pmic_sleep_mode, 0xe4);
|
||||
}
|
||||
|
||||
void fiq_glue_resume(void);
|
||||
|
||||
static inline void rkpm_peri_resume(u32 power_mode)
|
||||
{
|
||||
rkpm_gic_dist_resume(&slp_gic_save[0]);
|
||||
fiq_glue_resume();
|
||||
}
|
||||
|
||||
static void rkpm_save_setting_resume(void)
|
||||
{
|
||||
if (rk312x_powermode == 0)
|
||||
return;
|
||||
|
||||
rkpm_slp_mode_set_resume();
|
||||
if (rk312x_powermode & BIT(pmu_power_mode_en)) {
|
||||
rkpm_peri_resume(rk312x_powermode);
|
||||
sram_code_data_resume(rk312x_powermode);
|
||||
}
|
||||
}
|
||||
static inline void rkpm_peri_resume_first(u32 power_mode)
|
||||
{
|
||||
slp312x_uartdbg_resume();
|
||||
}
|
||||
static void rkpm_slp_setting(void)
|
||||
{
|
||||
rk_usb_power_down();
|
||||
}
|
||||
static void rkpm_save_setting_resume_first(void)
|
||||
{
|
||||
rk_usb_power_up();
|
||||
rkpm_peri_resume_first(pmu_pwrmode_con);
|
||||
}
|
||||
static u32 clk_ungt_msk[RK312X_CRU_CLKGATES_CON_CNT];
|
||||
/*first clk gating setting*/
|
||||
|
||||
static u32 clk_ungt_msk_1[RK312X_CRU_CLKGATES_CON_CNT];
|
||||
/* first clk gating setting*/
|
||||
|
||||
static u32 clk_ungt_save[RK312X_CRU_CLKGATES_CON_CNT];
|
||||
/*first clk gating value saveing*/
|
||||
|
||||
static u32 *p_rkpm_clkgt_last_set;
|
||||
#define CLK_MSK_GATING(msk, con) cru_writel((msk << 16) | 0xffff, con)
|
||||
#define CLK_MSK_UNGATING(msk, con) cru_writel(((~msk) << 16) | 0xffff, con)
|
||||
|
||||
static void gtclks_suspend(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RK312X_CRU_CLKGATES_CON_CNT; i++) {
|
||||
clk_ungt_save[i] = cru_readl(RK312X_CRU_CLKGATES_CON(i));
|
||||
CLK_MSK_UNGATING(clk_ungt_msk[i], RK312X_CRU_CLKGATES_CON(i));
|
||||
}
|
||||
}
|
||||
|
||||
static void gtclks_resume(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RK312X_CRU_CLKGATES_CON_CNT; i++)
|
||||
cru_writel(clk_ungt_save[i] | 0xffff0000
|
||||
, RK312X_CRU_CLKGATES_CON(i));
|
||||
}
|
||||
static void clks_gating_suspend_init(void)
|
||||
{
|
||||
p_rkpm_clkgt_last_set = &clk_ungt_msk_1[0];
|
||||
if (clk_suspend_clkgt_info_get(clk_ungt_msk, p_rkpm_clkgt_last_set
|
||||
, RK312X_CRU_CLKGATES_CON_CNT) == RK312X_CRU_CLKGATES_CON(0))
|
||||
rkpm_set_ops_gtclks(gtclks_suspend, gtclks_resume);
|
||||
}
|
||||
static void pmic_sleep_gpio_get_dts_info(struct device_node *parent)
|
||||
{
|
||||
struct property *prop;
|
||||
|
||||
prop = of_find_property(parent, "rockchip,pmic-suspend_gpios", NULL);
|
||||
if (!prop)
|
||||
return;
|
||||
if (!prop->value)
|
||||
return;
|
||||
|
||||
of_property_read_u32_array(parent, "rockchip,pmic-suspend_gpios"
|
||||
, &pmic_sleep_gpio, 1);
|
||||
}
|
||||
|
||||
|
||||
static void __init rk312x_suspend_init(void)
|
||||
{
|
||||
struct device_node *parent;
|
||||
u32 pm_ctrbits;
|
||||
|
||||
pr_info("%s\n", __func__);
|
||||
parent = of_find_node_by_name(NULL, "rockchip_suspend");
|
||||
|
||||
if (IS_ERR_OR_NULL(parent)) {
|
||||
PM_ERR("%s dev node err\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (of_property_read_u32_array(parent
|
||||
, "rockchip,ctrbits", &pm_ctrbits, 1)) {
|
||||
PM_ERR("%s:get pm ctr error\n", __func__);
|
||||
return;
|
||||
}
|
||||
pmic_sleep_gpio_get_dts_info(parent);
|
||||
rkpm_set_ctrbits(pm_ctrbits);
|
||||
clks_gating_suspend_init();
|
||||
rkpm_set_ops_prepare_finish(rkpm_prepare, rkpm_finish);
|
||||
rkpm_set_ops_plls(pm_plls_suspend, pm_plls_resume);
|
||||
rkpm_set_ops_save_setting(rkpm_save_setting
|
||||
, rkpm_save_setting_resume);
|
||||
rkpm_set_ops_regs_sleep(rkpm_slp_setting
|
||||
, rkpm_save_setting_resume_first);
|
||||
rkpm_set_ops_printch(ddr_printch);
|
||||
}
|
||||
@@ -30,7 +30,7 @@
|
||||
#include <linux/rockchip/grf.h>
|
||||
#include <linux/rockchip/iomap.h>
|
||||
#include <linux/rockchip/pmu.h>
|
||||
#include <asm/cpuidle.h>
|
||||
/*#include <asm/cpuidle.h>*/
|
||||
#include <asm/cputype.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/map.h>
|
||||
@@ -39,7 +39,7 @@
|
||||
#define CPU 312x
|
||||
#include "sram.h"
|
||||
#include "pm.h"
|
||||
|
||||
#include "pm-rk312x.c"
|
||||
#define RK312X_DEVICE(name) \
|
||||
{ \
|
||||
.virtual = (unsigned long) RK_##name##_VIRT, \
|
||||
@@ -131,10 +131,148 @@ static void __init rk3128_dt_map_io(void)
|
||||
|
||||
rk312x_dt_map_io();
|
||||
}
|
||||
static DEFINE_SPINLOCK(pmu_idle_lock);
|
||||
static const u8 pmu_idle_map[] = {
|
||||
[IDLE_REQ_PERI] = 0,
|
||||
[IDLE_REQ_VIDEO] = 1,
|
||||
[IDLE_REQ_VIO] = 2,
|
||||
[IDLE_REQ_GPU] = 3,
|
||||
[IDLE_REQ_CORE] = 4,
|
||||
[IDLE_REQ_SYS] = 5,
|
||||
[IDLE_REQ_MSCH] = 6,
|
||||
[IDLE_REQ_CRYPTO] = 7,
|
||||
|
||||
};
|
||||
static int rk312x_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
|
||||
{
|
||||
u32 val;
|
||||
unsigned long flags;
|
||||
u32 bit = pmu_idle_map[req];
|
||||
u32 idle_mask = BIT(bit) | BIT(bit + 16);
|
||||
u32 idle_target = (idle << bit) | (idle << (bit + 16));
|
||||
u32 mask = BIT(bit);
|
||||
|
||||
spin_lock_irqsave(&pmu_idle_lock, flags);
|
||||
val = pmu_readl(RK312X_PMU_IDLE_REQ);
|
||||
if (idle)
|
||||
val |= mask;
|
||||
else
|
||||
val &= ~mask;
|
||||
pmu_writel(val, RK312X_PMU_IDLE_REQ);
|
||||
dsb();
|
||||
|
||||
while (((pmu_readl(RK312X_PMU_IDLE_ST) & idle_mask) != idle_target))
|
||||
;
|
||||
spin_unlock_irqrestore(&pmu_idle_lock, flags);
|
||||
return 0;
|
||||
}
|
||||
static const u8 pmu_pd_map[] = {
|
||||
[PD_GPU] = 1,
|
||||
[PD_VIDEO] = 2,
|
||||
[PD_VIO] = 3,
|
||||
};
|
||||
|
||||
static const u8 pmu_st_map[] = {
|
||||
[PD_GPU] = 1,
|
||||
[PD_VIDEO] = 2,
|
||||
[PD_VIO] = 3,
|
||||
};
|
||||
|
||||
static noinline void rk312x_do_pmu_set_power_domain(enum pmu_power_domain domain
|
||||
, bool on)
|
||||
{
|
||||
u8 pd = pmu_pd_map[domain];
|
||||
u32 val = pmu_readl(RK312X_PMU_PWRDN_CON);
|
||||
|
||||
if (on)
|
||||
val &= ~BIT(pd);
|
||||
else
|
||||
val |= BIT(pd);
|
||||
pmu_writel(val, RK312X_PMU_PWRDN_CON);
|
||||
dsb();
|
||||
|
||||
while ((pmu_readl(RK312X_PMU_PWRDN_ST) & BIT(pmu_st_map[domain])) == on)
|
||||
;
|
||||
}
|
||||
|
||||
static bool rk312x_pmu_power_domain_is_on(enum pmu_power_domain pd)
|
||||
{
|
||||
/*1"b0: power on, 1'b1: power off*/
|
||||
return !(pmu_readl(RK312X_PMU_PWRDN_ST) & BIT(pmu_st_map[pd]));
|
||||
}
|
||||
static DEFINE_SPINLOCK(pmu_pd_lock);
|
||||
static u32 rga_qos[RK312X_CPU_AXI_QOS_NUM_REGS];
|
||||
static u32 ebc_qos[RK312X_CPU_AXI_QOS_NUM_REGS];
|
||||
static u32 iep_qos[RK312X_CPU_AXI_QOS_NUM_REGS];
|
||||
static u32 lcdc0_qos[RK312X_CPU_AXI_QOS_NUM_REGS];
|
||||
static u32 vip0_qos[RK312X_CPU_AXI_QOS_NUM_REGS];
|
||||
static u32 gpu_qos[RK312X_CPU_AXI_QOS_NUM_REGS];
|
||||
static u32 video_qos[RK312X_CPU_AXI_QOS_NUM_REGS];
|
||||
|
||||
#define SAVE_QOS(array, NAME) RK312X_CPU_AXI_SAVE_QOS(array, RK312X_CPU_AXI_##NAME##_QOS_VIRT)
|
||||
#define RESTORE_QOS(array, NAME) RK312X_CPU_AXI_RESTORE_QOS(array, RK312X_CPU_AXI_##NAME##_QOS_VIRT)
|
||||
|
||||
static int rk312x_pmu_set_power_domain(enum pmu_power_domain pd, bool on)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&pmu_pd_lock, flags);
|
||||
if (rk312x_pmu_power_domain_is_on(pd) == on)
|
||||
goto out;
|
||||
if (!on) {
|
||||
if (pd == PD_GPU) {
|
||||
SAVE_QOS(gpu_qos, GPU);
|
||||
rk312x_pmu_set_idle_request(IDLE_REQ_GPU, true);
|
||||
} else if (pd == PD_VIO) {
|
||||
SAVE_QOS(rga_qos, VIO_RGA);
|
||||
SAVE_QOS(ebc_qos, VIO_EBC);
|
||||
SAVE_QOS(iep_qos, VIO_IEP);
|
||||
SAVE_QOS(lcdc0_qos, VIO_LCDC0);
|
||||
SAVE_QOS(vip0_qos, VIO_VIP0);
|
||||
rk312x_pmu_set_idle_request(IDLE_REQ_VIO, true);
|
||||
} else if (pd == PD_VIDEO) {
|
||||
SAVE_QOS(video_qos, VIDEO);
|
||||
rk312x_pmu_set_idle_request(IDLE_REQ_VIDEO, true);
|
||||
}
|
||||
}
|
||||
|
||||
rk312x_do_pmu_set_power_domain(pd, on);
|
||||
|
||||
if (on) {
|
||||
if (pd == PD_GPU) {
|
||||
rk312x_pmu_set_idle_request(IDLE_REQ_GPU, false);
|
||||
RESTORE_QOS(gpu_qos, GPU);
|
||||
} else if (pd == PD_VIO) {
|
||||
rk312x_pmu_set_idle_request(IDLE_REQ_VIO, false);
|
||||
RESTORE_QOS(rga_qos, VIO_RGA);
|
||||
RESTORE_QOS(ebc_qos, VIO_EBC);
|
||||
RESTORE_QOS(iep_qos, VIO_IEP);
|
||||
RESTORE_QOS(lcdc0_qos, VIO_LCDC0);
|
||||
RESTORE_QOS(vip0_qos, VIO_VIP0);
|
||||
} else if (pd == PD_VIDEO) {
|
||||
rk312x_pmu_set_idle_request(IDLE_REQ_VIDEO, false);
|
||||
RESTORE_QOS(video_qos, VIDEO);
|
||||
}
|
||||
}
|
||||
out:
|
||||
spin_unlock_irqrestore(&pmu_pd_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
extern void secondary_startup(void);
|
||||
static int rk312x_sys_set_power_domain(enum pmu_power_domain pd, bool on)
|
||||
{
|
||||
u32 clks_save[RK312X_CRU_CLKGATES_CON_CNT];
|
||||
u32 clks_ungating[RK312X_CRU_CLKGATES_CON_CNT];
|
||||
u32 i, ret = 0;
|
||||
|
||||
for (i = 0; i < RK312X_CRU_CLKGATES_CON_CNT; i++) {
|
||||
clks_save[i] = cru_readl(RK312X_CRU_CLKGATES_CON(i));
|
||||
clks_ungating[i] = 0;
|
||||
}
|
||||
for (i = 0; i < RK312X_CRU_CLKGATES_CON_CNT; i++)
|
||||
cru_writel(0xffff0000, RK312X_CRU_CLKGATES_CON(i));
|
||||
|
||||
if (on) {
|
||||
#ifdef CONFIG_SMP
|
||||
if (pd >= PD_CPU_1 && pd <= PD_CPU_3) {
|
||||
@@ -158,17 +296,15 @@ static int rk312x_sys_set_power_domain(enum pmu_power_domain pd, bool on)
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (((pd == PD_GPU) || (pd == PD_VIO) || (pd == PD_VIDEO)))
|
||||
ret = rk312x_pmu_set_power_domain(pd, on);
|
||||
|
||||
static bool rk312x_pmu_power_domain_is_on(enum pmu_power_domain pd)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < RK312X_CRU_CLKGATES_CON_CNT; i++) {
|
||||
cru_writel(clks_save[i] | 0xffff0000
|
||||
, RK312X_CRU_CLKGATES_CON(i));
|
||||
}
|
||||
|
||||
static int rk312x_pmu_set_idle_request(enum pmu_idle_req req, bool idle)
|
||||
{
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __init rk312x_dt_init_timer(void)
|
||||
@@ -186,9 +322,14 @@ static void __init rk312x_reserve(void)
|
||||
/* reserve memory for ION */
|
||||
rockchip_ion_reserve();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static void __init rk321x_init_suspend(void);
|
||||
#endif
|
||||
static void __init rk312x_init_late(void)
|
||||
{
|
||||
#ifdef CONFIG_PM
|
||||
rk321x_init_suspend();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void rk312x_restart(char mode, const char *cmd)
|
||||
@@ -197,8 +338,8 @@ static void rk312x_restart(char mode, const char *cmd)
|
||||
|
||||
rockchip_restart_get_boot_mode(cmd, &boot_flag, &boot_mode);
|
||||
|
||||
writel_relaxed(boot_flag, RK_GRF_VIRT + RK312X_GRF_OS_REG4); // for loader
|
||||
writel_relaxed(boot_mode, RK_GRF_VIRT + RK312X_GRF_OS_REG5); // for linux
|
||||
writel_relaxed(boot_flag, RK_GRF_VIRT + RK312X_GRF_OS_REG4);
|
||||
writel_relaxed(boot_mode, RK_GRF_VIRT + RK312X_GRF_OS_REG5);
|
||||
dsb();
|
||||
|
||||
/* pll enter slow mode */
|
||||
@@ -257,6 +398,7 @@ static int __init rk312x_pie_init(void)
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(rk312x_pie_init);
|
||||
|
||||
#include "ddr_rk3126.c"
|
||||
static int __init rk312x_ddr_init(void)
|
||||
{
|
||||
@@ -269,3 +411,37 @@ static int __init rk312x_ddr_init(void)
|
||||
return 0;
|
||||
}
|
||||
arch_initcall_sync(rk312x_ddr_init);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static u32 rk_pmu_pwrdn_st;
|
||||
static inline void rk_pm_soc_pd_suspend(void)
|
||||
{
|
||||
rk_pmu_pwrdn_st = pmu_readl(RK312X_PMU_PWRDN_ST);
|
||||
if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_GPU])))
|
||||
rk312x_sys_set_power_domain(PD_GPU, false);
|
||||
|
||||
if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIO])))
|
||||
rk312x_sys_set_power_domain(PD_VIO, false);
|
||||
|
||||
if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIDEO])))
|
||||
rk312x_sys_set_power_domain(PD_VIDEO, false);
|
||||
}
|
||||
static inline void rk_pm_soc_pd_resume(void)
|
||||
{
|
||||
if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIDEO])))
|
||||
rk312x_sys_set_power_domain(PD_VIDEO, true);
|
||||
|
||||
if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_VIO])))
|
||||
rk312x_sys_set_power_domain(PD_VIO, true);
|
||||
|
||||
if (!(rk_pmu_pwrdn_st & BIT(pmu_st_map[PD_GPU])))
|
||||
rk312x_sys_set_power_domain(PD_GPU, true);
|
||||
}
|
||||
static void __init rk321x_init_suspend(void)
|
||||
{
|
||||
pr_info("%s\n", __func__);
|
||||
rockchip_suspend_init();
|
||||
rk312x_suspend_init();
|
||||
rkpm_set_ops_pwr_dmns(rk_pm_soc_pd_suspend, rk_pm_soc_pd_resume);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -161,7 +161,6 @@ static inline void rk3288_cru_set_soft_reset(u32 idx, bool on)
|
||||
#define RK3036_CRU_SOFTRSTS_CON_CNT (9)
|
||||
#define RK3036_CRU_SOFTRSTS_CON(i) (RK3036_CRU_SOFTRST_CON + ((i) * 4))
|
||||
|
||||
#define RK312X_CRU_MODE_CON 0x0040
|
||||
#define RK312X_PLL_CONS(id, i) ((id) * 0x10 + ((i) * 4))
|
||||
|
||||
#define RK312X_CRU_GLB_SRST_FST_VALUE 0x00100
|
||||
@@ -176,12 +175,24 @@ static inline void rk3288_cru_set_soft_reset(u32 idx, bool on)
|
||||
#define RK312X_CRU_EMMC_CON0 0x01d8
|
||||
#define RK312X_CRU_EMMC_CON1 0x01dc
|
||||
#define RK312X_CRU_PLL_PRG_EN 0x01f0
|
||||
|
||||
#define RK312X_CRU_MODE_CON 0x40
|
||||
#define RK312X_CRU_RST_ST 0x00160
|
||||
#define RK312X_CRU_PLL_MASK_CON 0x001f0
|
||||
|
||||
#define RK312X_CRU_CLKSEL_CON 0x44
|
||||
#define RK312X_CRU_CLKGATE_CON 0xd0
|
||||
|
||||
#define RK312X_PLL_CONS(id, i) ((id) * 0x10 + ((i) * 4))
|
||||
|
||||
/******************PLL MODE BITS*******************/
|
||||
#define RK312X_PLLS_MODE_OFFSET(id) ((id) <= 3 ? (id * 4) : 14)
|
||||
#define RK312X_PLL_MODE_MSK(id) (0x1 << RK312X_PLLS_MODE_OFFSET(id))
|
||||
#define RK312X_PLL_MODE_SLOW(id) ((0x0 << RK312X_PLLS_MODE_OFFSET(id))\
|
||||
| (0x1 << (16 + RK312X_PLLS_MODE_OFFSET(id))))
|
||||
#define RK312X_PLL_MODE_NORM(id) ((0x1 << RK312X_PLLS_MODE_OFFSET(id))\
|
||||
| (0x1 << (16 + RK312X_PLLS_MODE_OFFSET(id))))
|
||||
|
||||
|
||||
#define RK312X_CRU_SOFTRST_CON 0x110
|
||||
|
||||
#define RK312X_CRU_CLKSELS_CON_CNT (35)
|
||||
@@ -193,4 +204,16 @@ static inline void rk3288_cru_set_soft_reset(u32 idx, bool on)
|
||||
#define RK312X_CRU_SOFTRSTS_CON_CNT (9)
|
||||
#define RK312X_CRU_SOFTRSTS_CON(i) (RK312X_CRU_SOFTRST_CON + ((i) * 4))
|
||||
|
||||
/*******************CRU GATING*********************/
|
||||
#define RK312X_CRU_CONS_GATEID(i) (16 * (i))
|
||||
#define RK312X_CRU_GATEID_CONS(ID) (RK312X_CRU_CLKGATE_CON\
|
||||
+ ((ID) / 16) * 4)
|
||||
|
||||
enum rk312x_cru_clk_gate {
|
||||
/* SCU CLK GATE 0 CON */
|
||||
RK312X_CLKGATE_UART0_SRC = (RK312X_CRU_CONS_GATEID(1) + 8),
|
||||
RK312X_CLKGATE_PCLK_UART0 = (RK312X_CRU_CONS_GATEID(8) + 0),
|
||||
RK312X_CLKGATE_PCLK_UART1,
|
||||
RK312X_CLKGATE_PCLK_UART2,
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -67,6 +67,26 @@
|
||||
#define RK3288_PMU_SYS_REG2 0x9c
|
||||
#define RK3288_PMU_SYS_REG3 0xa0
|
||||
|
||||
#define RK312X_PMU_WAKEUP_CFG 0x00
|
||||
#define RK312X_PMU_PWRDN_CON 0x04
|
||||
#define RK312X_PMU_PWRDN_ST 0x08
|
||||
#define RK312X_PMU_IDLE_REQ 0x0C
|
||||
#define RK312X_PMU_IDLE_ST 0x10
|
||||
#define RK312X_PMU_PWRMODE_CON 0x14
|
||||
#define RK312X_PMU_PWR_STATE 0x18
|
||||
#define RK312X_PMU_OSC_CNT 0x1C
|
||||
#define RK312X_PMU_CORE_PWRDWN_CNT 0x20
|
||||
#define RK312X_PMU_CORE_PWRUP_CNT 0x24
|
||||
#define RK312X_PMU_SFT_CON 0x28
|
||||
#define RK312X_PMU_DDR_SREF_ST 0x2C
|
||||
#define RK312X_PMU_INT_CON 0x30
|
||||
#define RK312X_PMU_INT_ST 0x34
|
||||
#define RK312X_PMU_SYS_REG0 0x38
|
||||
#define RK312X_PMU_SYS_REG1 0x3C
|
||||
#define RK312X_PMU_SYS_REG2 0x40
|
||||
#define RK312X_PMU_SYS_REG3 0x44
|
||||
|
||||
|
||||
enum pmu_power_domain {
|
||||
PD_BCPU,
|
||||
PD_BDSP,
|
||||
@@ -97,6 +117,9 @@ enum pmu_idle_req {
|
||||
IDLE_REQ_PERI,
|
||||
IDLE_REQ_VIDEO,
|
||||
IDLE_REQ_VIO,
|
||||
IDLE_REQ_SYS,
|
||||
IDLE_REQ_MSCH,
|
||||
IDLE_REQ_CRYPTO,
|
||||
};
|
||||
|
||||
struct rockchip_pmu_operations {
|
||||
|
||||
Reference in New Issue
Block a user