rk30: support cpu axi qos setup properly, and add setup lcdc qos

This commit is contained in:
黄涛
2013-01-26 12:19:41 +08:00
parent 33330b1b19
commit 03650abc50
4 changed files with 88 additions and 27 deletions

View File

@@ -19,35 +19,22 @@
#include <mach/loader.h>
#include <mach/ddr.h>
#include <mach/dvfs.h>
#include <mach/cpu_axi.h>
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();
}

View File

@@ -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

View File

@@ -23,6 +23,7 @@
#include <mach/cru.h>
#include <mach/ddr.h>
#include <mach/debug_uart.h>
#include <mach/cpu_axi.h>
#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));

View File

@@ -2,6 +2,7 @@
#include <linux/spinlock.h>
#include <mach/pmu.h>
#include <mach/sram.h>
#include <mach/cpu_axi.h>
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);