mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 04:10:18 +09:00
rk30: support cpu axi qos setup properly, and add setup lcdc qos
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
56
arch/arm/mach-rk30/include/mach/cpu_axi.h
Normal file
56
arch/arm/mach-rk30/include/mach/cpu_axi.h
Normal 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
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user