#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();
}
--- /dev/null
+#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
#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)
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));
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));
#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)
{
* 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)
{
}
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);
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);