From 03650abc50765675492cab2130619145c69d2b0a Mon Sep 17 00:00:00 2001 From: =?utf8?q?=E9=BB=84=E6=B6=9B?= Date: Sat, 26 Jan 2013 12:19:41 +0800 Subject: [PATCH] rk30: support cpu axi qos setup properly, and add setup lcdc qos --- arch/arm/mach-rk30/common.c | 33 ++++--------- arch/arm/mach-rk30/include/mach/cpu_axi.h | 56 +++++++++++++++++++++++ arch/arm/mach-rk30/pm.c | 11 +++++ arch/arm/mach-rk30/pmu.c | 15 ++++-- 4 files changed, 88 insertions(+), 27 deletions(-) create mode 100644 arch/arm/mach-rk30/include/mach/cpu_axi.h diff --git a/arch/arm/mach-rk30/common.c b/arch/arm/mach-rk30/common.c index 8c3f436d279e..f5148b95487a 100755 --- a/arch/arm/mach-rk30/common.c +++ b/arch/arm/mach-rk30/common.c @@ -19,35 +19,22 @@ #include #include #include +#include static void __init rk30_cpu_axi_init(void) { -#ifdef CONFIG_ARCH_RK3188 - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x1008); // dmac1 - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x2008); // cpu0 - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x2088); // cpu1r - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x2108); // cpu1w -#else - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x0088); // cpu0 - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x0108); // dmac1 - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x0188); // cpu1r - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x0388); // cpu1w -#endif + CPU_AXI_SET_QOS_PRIORITY(0, 0, DMAC); + CPU_AXI_SET_QOS_PRIORITY(0, 0, CPU0); + CPU_AXI_SET_QOS_PRIORITY(0, 0, CPU1R); + CPU_AXI_SET_QOS_PRIORITY(0, 0, CPU1W); #ifdef CONFIG_RK29_VMAC - writel_relaxed(0xa, RK30_CPU_AXI_BUS_BASE + 0x4008); // peri + CPU_AXI_SET_QOS_PRIORITY(2, 2, PERI); #else - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x4008); // peri -#endif -#if 0 - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x5008); // gpu - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x6008); // vpu - writel_relaxed(0xa, RK30_CPU_AXI_BUS_BASE + 0x7008); // lcdc0 - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x7088); // cif0 - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x7108); // ipp - writel_relaxed(0xa, RK30_CPU_AXI_BUS_BASE + 0x7188); // lcdc1 - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x7208); // cif1 - writel_relaxed(0x0, RK30_CPU_AXI_BUS_BASE + 0x7288); // rga + CPU_AXI_SET_QOS_PRIORITY(0, 0, PERI); #endif + CPU_AXI_SET_QOS_PRIORITY(3, 3, LCDC0); + CPU_AXI_SET_QOS_PRIORITY(3, 3, LCDC1); + writel_relaxed(0x3f, RK30_CPU_AXI_BUS_BASE + 0x0014); // memory scheduler read latency dsb(); } diff --git a/arch/arm/mach-rk30/include/mach/cpu_axi.h b/arch/arm/mach-rk30/include/mach/cpu_axi.h new file mode 100644 index 000000000000..7fe8556b470e --- /dev/null +++ b/arch/arm/mach-rk30/include/mach/cpu_axi.h @@ -0,0 +1,56 @@ +#ifndef __MACH_CPU_AXI_H +#define __MACH_CPU_AXI_H + +#define CPU_AXI_QOS_PRIORITY 0x08 +#define CPU_AXI_QOS_MODE 0x0c +#define CPU_AXI_QOS_BANDWIDTH 0x10 +#define CPU_AXI_QOS_SATURATION 0x14 + +#define CPU_AXI_QOS_MODE_NONE 0 +#define CPU_AXI_QOS_MODE_FIXED 1 +#define CPU_AXI_QOS_MODE_LIMITER 2 +#define CPU_AXI_QOS_MODE_REGULATOR 3 + +#define CPU_AXI_QOS_PRIORITY_LEVEL(h, l) (((h & 3) << 2) | (l & 3)) +#define CPU_AXI_SET_QOS_PRIORITY(h, l, NAME) \ + writel_relaxed(CPU_AXI_QOS_PRIORITY_LEVEL(h, l), CPU_AXI_##NAME##_QOS_BASE + CPU_AXI_QOS_PRIORITY) +#define CPU_AXI_QOS_NUM_REGS 4 +#define CPU_AXI_SAVE_QOS(array, NAME) do { \ + array[0] = readl_relaxed(CPU_AXI_##NAME##_QOS_BASE + CPU_AXI_QOS_PRIORITY); \ + array[1] = readl_relaxed(CPU_AXI_##NAME##_QOS_BASE + CPU_AXI_QOS_MODE); \ + array[2] = readl_relaxed(CPU_AXI_##NAME##_QOS_BASE + CPU_AXI_QOS_BANDWIDTH); \ + array[3] = readl_relaxed(CPU_AXI_##NAME##_QOS_BASE + CPU_AXI_QOS_SATURATION); \ +} while (0) +#define CPU_AXI_RESTORE_QOS(array, NAME) do { \ + writel_relaxed(array[0], CPU_AXI_##NAME##_QOS_BASE + CPU_AXI_QOS_PRIORITY); \ + writel_relaxed(array[1], CPU_AXI_##NAME##_QOS_BASE + CPU_AXI_QOS_MODE); \ + writel_relaxed(array[2], CPU_AXI_##NAME##_QOS_BASE + CPU_AXI_QOS_BANDWIDTH); \ + writel_relaxed(array[3], CPU_AXI_##NAME##_QOS_BASE + CPU_AXI_QOS_SATURATION); \ +} while (0) + +#define CPU_AXI_LCDC0_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x7000) +#define CPU_AXI_CIF0_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x7080) +#define CPU_AXI_IPP_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x7100) +#define CPU_AXI_LCDC1_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x7180) +#define CPU_AXI_CIF1_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x7200) +#define CPU_AXI_RGA_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x7280) + +#define CPU_AXI_PERI_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x4000) + +#define CPU_AXI_GPU_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x5000) + +#define CPU_AXI_VPU_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x6000) + +#ifdef CONFIG_ARCH_RK3188 +#define CPU_AXI_DMAC_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x1000) +#define CPU_AXI_CPU0_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x2000) +#define CPU_AXI_CPU1R_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x2080) +#define CPU_AXI_CPU1W_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x2100) +#else +#define CPU_AXI_CPU0_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x0080) +#define CPU_AXI_DMAC_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x0100) +#define CPU_AXI_CPU1R_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x0180) +#define CPU_AXI_CPU1W_QOS_BASE (RK30_CPU_AXI_BUS_BASE + 0x0380) +#endif + +#endif diff --git a/arch/arm/mach-rk30/pm.c b/arch/arm/mach-rk30/pm.c index bdc04fec7593..c73a3930b081 100755 --- a/arch/arm/mach-rk30/pm.c +++ b/arch/arm/mach-rk30/pm.c @@ -23,6 +23,7 @@ #include #include #include +#include #define cru_readl(offset) readl_relaxed(RK30_CRU_BASE + offset) #define cru_writel(v, offset) do { writel_relaxed(v, RK30_CRU_BASE + offset); dsb(); } while (0) @@ -402,6 +403,8 @@ static void rk30_pm_set_power_domain(u32 pmu_pwrdn_st, bool state) if (pm_pmu_power_domain_is_on(PD_VIO, pmu_pwrdn_st)) { u32 gate[10]; + static u32 lcdc0_qos[CPU_AXI_QOS_NUM_REGS]; + static u32 lcdc1_qos[CPU_AXI_QOS_NUM_REGS]; gate[0] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC0_SRC)); gate[1] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC1_SRC)); gate[2] = cru_readl(CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC0)); @@ -422,7 +425,15 @@ static void rk30_pm_set_power_domain(u32 pmu_pwrdn_st, bool state) cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_VIO1), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_VIO1)); cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_IPP), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_IPP)); cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_RGA), CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_RGA)); + if (!state) { + CPU_AXI_SAVE_QOS(lcdc0_qos, LCDC0); + CPU_AXI_SAVE_QOS(lcdc1_qos, LCDC0); + } pmu_set_power_domain(PD_VIO, state); + if (state) { + CPU_AXI_RESTORE_QOS(lcdc0_qos, LCDC0); + CPU_AXI_RESTORE_QOS(lcdc1_qos, LCDC0); + } cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC0_SRC) | gate[0], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC0_SRC)); cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC1_SRC) | gate[1], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC1_SRC)); cru_writel(CLK_GATE_W_MSK(CLK_GATE_ACLK_LCDC0) | gate[2], CLK_GATE_CLKID_CONS(CLK_GATE_ACLK_LCDC0)); diff --git a/arch/arm/mach-rk30/pmu.c b/arch/arm/mach-rk30/pmu.c index 11f6b20ba332..d8c3b197a200 100644 --- a/arch/arm/mach-rk30/pmu.c +++ b/arch/arm/mach-rk30/pmu.c @@ -2,6 +2,7 @@ #include #include #include +#include static void __sramfunc pmu_set_power_domain_sram(enum pmu_power_domain pd, bool on) { @@ -34,6 +35,8 @@ static noinline void do_pmu_set_power_domain(enum pmu_power_domain pd, bool on) * change dramatically which will affect the chip function. */ static DEFINE_SPINLOCK(pmu_pd_lock); +static u32 lcdc0_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 lcdc1_qos[CPU_AXI_QOS_NUM_REGS]; void pmu_set_power_domain(enum pmu_power_domain pd, bool on) { @@ -46,9 +49,11 @@ void pmu_set_power_domain(enum pmu_power_domain pd, bool on) } if (!on) { /* if power down, idle request to NIU first */ - if (pd == PD_VIO) + if (pd == PD_VIO) { + CPU_AXI_SAVE_QOS(lcdc0_qos, LCDC0); + CPU_AXI_SAVE_QOS(lcdc1_qos, LCDC1); pmu_set_idle_request(IDLE_REQ_VIO, true); - else if (pd == PD_VIDEO) + } else if (pd == PD_VIDEO) pmu_set_idle_request(IDLE_REQ_VIDEO, true); else if (pd == PD_GPU) pmu_set_idle_request(IDLE_REQ_GPU, true); @@ -56,9 +61,11 @@ void pmu_set_power_domain(enum pmu_power_domain pd, bool on) do_pmu_set_power_domain(pd, on); if (on) { /* if power up, idle request release to NIU */ - if (pd == PD_VIO) + if (pd == PD_VIO) { pmu_set_idle_request(IDLE_REQ_VIO, false); - else if (pd == PD_VIDEO) + CPU_AXI_RESTORE_QOS(lcdc0_qos, LCDC0); + CPU_AXI_RESTORE_QOS(lcdc1_qos, LCDC1); + } else if (pd == PD_VIDEO) pmu_set_idle_request(IDLE_REQ_VIDEO, false); else if (pd == PD_GPU) pmu_set_idle_request(IDLE_REQ_GPU, false); -- 2.34.1