From: 黄涛 Date: Mon, 17 Mar 2014 10:50:55 +0000 (+0800) Subject: ARM: rockchip: rk3288 support save/restore QOS when power domain on/off X-Git-Tag: firefly_0821_release~6049 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=88f776ec316c0d73715462ebb51e8e52ee805b9b;p=firefly-linux-kernel-4.4.55.git ARM: rockchip: rk3288 support save/restore QOS when power domain on/off --- diff --git a/arch/arm/mach-rockchip/cpu_axi.h b/arch/arm/mach-rockchip/cpu_axi.h index e3beedfef471..e6a0cff3a993 100644 --- a/arch/arm/mach-rockchip/cpu_axi.h +++ b/arch/arm/mach-rockchip/cpu_axi.h @@ -38,18 +38,58 @@ writel_relaxed(array[3], base + CPU_AXI_QOS_SATURATION); \ } while (0) -#define RK3188_CPU_AXI_DMAC_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x1000) -#define RK3188_CPU_AXI_CPU0_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x2000) -#define RK3188_CPU_AXI_CPU1R_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x2080) -#define RK3188_CPU_AXI_CPU1W_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x2100) -#define RK3188_CPU_AXI_PERI_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x4000) -#define RK3188_CPU_AXI_GPU_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x5000) -#define RK3188_CPU_AXI_VPU_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x6000) -#define RK3188_CPU_AXI_LCDC0_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7000) -#define RK3188_CPU_AXI_CIF0_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7080) -#define RK3188_CPU_AXI_IPP_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7100) -#define RK3188_CPU_AXI_LCDC1_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7180) -#define RK3188_CPU_AXI_CIF1_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7200) -#define RK3188_CPU_AXI_RGA_QOS_BASE (RK_CPU_AXI_BUS_VIRT + 0x7280) +#define RK3188_CPU_AXI_DMAC_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x1000) +#define RK3188_CPU_AXI_CPU0_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x2000) +#define RK3188_CPU_AXI_CPU1R_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x2080) +#define RK3188_CPU_AXI_CPU1W_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x2100) +#define RK3188_CPU_AXI_PERI_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x4000) +#define RK3188_CPU_AXI_GPU_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x5000) +#define RK3188_CPU_AXI_VPU_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x6000) +#define RK3188_CPU_AXI_LCDC0_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7000) +#define RK3188_CPU_AXI_CIF0_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7080) +#define RK3188_CPU_AXI_IPP_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7100) +#define RK3188_CPU_AXI_LCDC1_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7180) +#define RK3188_CPU_AXI_CIF1_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7200) +#define RK3188_CPU_AXI_RGA_QOS_VIRT (RK_CPU_AXI_BUS_VIRT + 0x7280) + +/* service core */ +#define RK3288_SERVICE_CORE_VIRT RK_CPU_AXI_BUS_VIRT +#define RK3288_CPU_AXI_CPUM_R_QOS_VIRT (RK3288_SERVICE_CORE_VIRT + 0x80) +#define RK3288_CPU_AXI_CPUM_W_QOS_VIRT (RK3288_SERVICE_CORE_VIRT + 0x100) +#define RK3288_CPU_AXI_CPUP_QOS_VIRT (RK3288_SERVICE_CORE_VIRT + 0x0) +/* service dmac */ +#define RK3288_SERVICE_DMAC_VIRT (RK3288_SERVICE_CORE_VIRT + RK3288_SERVICE_CORE_SIZE) +#define RK3288_CPU_AXI_BUS_DMAC_QOS_VIRT (RK3288_SERVICE_DMAC_VIRT + 0x0) +#define RK3288_CPU_AXI_CCP_QOS_VIRT (RK3288_SERVICE_DMAC_VIRT + 0x180) +#define RK3288_CPU_AXI_CRYPTO_QOS_VIRT (RK3288_SERVICE_DMAC_VIRT + 0x100) +#define RK3288_CPU_AXI_CCS_QOS_VIRT (RK3288_SERVICE_DMAC_VIRT + 0x200) +#define RK3288_CPU_AXI_HOST_QOS_VIRT (RK3288_SERVICE_DMAC_VIRT + 0x80) +/* service gpu */ +#define RK3288_SERVICE_GPU_VIRT (RK3288_SERVICE_DMAC_VIRT + RK3288_SERVICE_DMAC_SIZE) +#define RK3288_CPU_AXI_GPU_R_QOS_VIRT (RK3288_SERVICE_GPU_VIRT + 0x0) +#define RK3288_CPU_AXI_GPU_W_QOS_VIRT (RK3288_SERVICE_GPU_VIRT + 0x80) +/* service peri */ +#define RK3288_SERVICE_PERI_VIRT (RK3288_SERVICE_GPU_VIRT + RK3288_SERVICE_GPU_SIZE) +#define RK3288_CPU_AXI_PERI_QOS_VIRT (RK3288_SERVICE_PERI_VIRT + 0x0) +/* service bus */ +#define RK3288_SERVICE_BUS_VIRT (RK3288_SERVICE_PERI_VIRT + RK3288_SERVICE_PERI_SIZE) +/* service vio */ +#define RK3288_SERVICE_VIO_VIRT (RK3288_SERVICE_BUS_VIRT + RK3288_SERVICE_BUS_SIZE) +#define RK3288_CPU_AXI_VIO0_IEP_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x500) +#define RK3288_CPU_AXI_VIO0_VIP_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x480) +#define RK3288_CPU_AXI_VIO0_VOP_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x400) +#define RK3288_CPU_AXI_VIO1_ISP_R_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x900) +#define RK3288_CPU_AXI_VIO1_ISP_W0_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x100) +#define RK3288_CPU_AXI_VIO1_ISP_W1_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x180) +#define RK3288_CPU_AXI_VIO1_VOP_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x0) +#define RK3288_CPU_AXI_VIO2_RGA_R_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x800) +#define RK3288_CPU_AXI_VIO2_RGA_W_QOS_VIRT (RK3288_SERVICE_VIO_VIRT + 0x880) +/* service video */ +#define RK3288_SERVICE_VIDEO_VIRT (RK3288_SERVICE_VIO_VIRT + RK3288_SERVICE_VIO_SIZE) +#define RK3288_CPU_AXI_VIDEO_QOS_VIRT (RK3288_SERVICE_VIDEO_VIRT + 0x0) +/* service hevc */ +#define RK3288_SERVICE_HEVC_VIRT (RK3288_SERVICE_VIDEO_VIRT + RK3288_SERVICE_VIDEO_SIZE) +#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) #endif diff --git a/arch/arm/mach-rockchip/rk3188.c b/arch/arm/mach-rockchip/rk3188.c index 464e64cc0a32..042686335074 100755 --- a/arch/arm/mach-rockchip/rk3188.c +++ b/arch/arm/mach-rockchip/rk3188.c @@ -213,8 +213,8 @@ static u32 rga_qos[CPU_AXI_QOS_NUM_REGS]; static u32 gpu_qos[CPU_AXI_QOS_NUM_REGS]; static u32 vpu_qos[CPU_AXI_QOS_NUM_REGS]; -#define SAVE_QOS(array, NAME) CPU_AXI_SAVE_QOS(array, RK3188_CPU_AXI_##NAME##_QOS_BASE) -#define RESTORE_QOS(array, NAME) CPU_AXI_RESTORE_QOS(array, RK3188_CPU_AXI_##NAME##_QOS_BASE) +#define SAVE_QOS(array, NAME) CPU_AXI_SAVE_QOS(array, RK3188_CPU_AXI_##NAME##_QOS_VIRT) +#define RESTORE_QOS(array, NAME) CPU_AXI_RESTORE_QOS(array, RK3188_CPU_AXI_##NAME##_QOS_VIRT) static int rk3188_pmu_set_power_domain(enum pmu_power_domain pd, bool on) { diff --git a/arch/arm/mach-rockchip/rk3288.c b/arch/arm/mach-rockchip/rk3288.c index 10579018fc64..052ebe2daf5b 100755 --- a/arch/arm/mach-rockchip/rk3288.c +++ b/arch/arm/mach-rockchip/rk3288.c @@ -42,6 +42,9 @@ .type = MT_DEVICE, \ } +#define RK3288_SERVICE_DEVICE(name) \ + RK_DEVICE(RK3288_SERVICE_##name##_VIRT, RK3288_SERVICE_##name##_PHYS, RK3288_SERVICE_##name##_SIZE) + static struct map_desc rk3288_io_desc[] __initdata = { RK3288_DEVICE(CRU), RK3288_DEVICE(GRF), @@ -49,6 +52,13 @@ static struct map_desc rk3288_io_desc[] __initdata = { RK3288_DEVICE(PMU), RK3288_DEVICE(ROM), RK3288_DEVICE(EFUSE), + RK3288_SERVICE_DEVICE(CORE), + RK3288_SERVICE_DEVICE(DMAC), + RK3288_SERVICE_DEVICE(GPU), + RK3288_SERVICE_DEVICE(PERI), + RK3288_SERVICE_DEVICE(VIO), + RK3288_SERVICE_DEVICE(VIDEO), + RK3288_SERVICE_DEVICE(HEVC), RK_DEVICE(RK_DDR_VIRT, RK3288_DDR_PCTL0_PHYS, RK3288_DDR_PCTL_SIZE), RK_DEVICE(RK_DDR_VIRT + RK3288_DDR_PCTL_SIZE, RK3288_DDR_PUBL0_PHYS, RK3288_DDR_PUBL_SIZE), RK_DEVICE(RK_DDR_VIRT + RK3288_DDR_PCTL_SIZE + RK3288_DDR_PUBL_SIZE, RK3288_DDR_PCTL1_PHYS, RK3288_DDR_PCTL_SIZE), @@ -205,6 +215,24 @@ static noinline void rk3288_do_pmu_set_power_domain(enum pmu_power_domain domain ; } +static u32 gpu_r_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 gpu_w_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 vio0_iep_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 vio0_vip_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 vio0_vop_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 vio1_isp_r_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 vio1_isp_w0_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 vio1_isp_w1_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 vio1_vop_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 vio2_rga_r_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 vio2_rga_w_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 video_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 hevc_r_qos[CPU_AXI_QOS_NUM_REGS]; +static u32 hevc_w_qos[CPU_AXI_QOS_NUM_REGS]; + +#define SAVE_QOS(array, NAME) CPU_AXI_SAVE_QOS(array, RK3288_CPU_AXI_##NAME##_QOS_VIRT) +#define RESTORE_QOS(array, NAME) CPU_AXI_RESTORE_QOS(array, RK3288_CPU_AXI_##NAME##_QOS_VIRT) + static int rk3288_pmu_set_power_domain(enum pmu_power_domain pd, bool on) { unsigned long flags; @@ -215,8 +243,62 @@ static int rk3288_pmu_set_power_domain(enum pmu_power_domain pd, bool on) return 0; } + if (!on) { + /* if power down, idle request to NIU first */ + if (pd == PD_VIO) { + SAVE_QOS(vio0_iep_qos, VIO0_IEP); + SAVE_QOS(vio0_vip_qos, VIO0_VIP); + SAVE_QOS(vio0_vop_qos, VIO0_VOP); + SAVE_QOS(vio1_isp_r_qos, VIO1_ISP_R); + SAVE_QOS(vio1_isp_w0_qos, VIO1_ISP_W0); + SAVE_QOS(vio1_isp_w1_qos, VIO1_ISP_W1); + SAVE_QOS(vio1_vop_qos, VIO1_VOP); + SAVE_QOS(vio2_rga_r_qos, VIO2_RGA_R); + SAVE_QOS(vio2_rga_w_qos, VIO2_RGA_W); + rk3288_pmu_set_idle_request(IDLE_REQ_VIO, true); + } else if (pd == PD_VIDEO) { + SAVE_QOS(video_qos, VIDEO); + rk3288_pmu_set_idle_request(IDLE_REQ_VIDEO, true); + } else if (pd == PD_GPU) { + SAVE_QOS(gpu_r_qos, GPU_R); + SAVE_QOS(gpu_w_qos, GPU_W); + rk3288_pmu_set_idle_request(IDLE_REQ_GPU, true); + } else if (pd == PD_HEVC) { + SAVE_QOS(hevc_r_qos, HEVC_R); + SAVE_QOS(hevc_w_qos, HEVC_W); + rk3288_pmu_set_idle_request(IDLE_REQ_HEVC, true); + } + } + rk3288_do_pmu_set_power_domain(pd, on); + if (on) { + /* if power up, idle request release to NIU */ + if (pd == PD_VIO) { + rk3288_pmu_set_idle_request(IDLE_REQ_VIO, false); + RESTORE_QOS(vio0_iep_qos, VIO0_IEP); + RESTORE_QOS(vio0_vip_qos, VIO0_VIP); + RESTORE_QOS(vio0_vop_qos, VIO0_VOP); + RESTORE_QOS(vio1_isp_r_qos, VIO1_ISP_R); + RESTORE_QOS(vio1_isp_w0_qos, VIO1_ISP_W0); + RESTORE_QOS(vio1_isp_w1_qos, VIO1_ISP_W1); + RESTORE_QOS(vio1_vop_qos, VIO1_VOP); + RESTORE_QOS(vio2_rga_r_qos, VIO2_RGA_R); + RESTORE_QOS(vio2_rga_w_qos, VIO2_RGA_W); + } else if (pd == PD_VIDEO) { + rk3288_pmu_set_idle_request(IDLE_REQ_VIDEO, false); + RESTORE_QOS(video_qos, VIDEO); + } else if (pd == PD_GPU) { + rk3288_pmu_set_idle_request(IDLE_REQ_GPU, false); + RESTORE_QOS(gpu_r_qos, GPU_R); + RESTORE_QOS(gpu_w_qos, GPU_W); + } else if (pd == PD_HEVC) { + rk3288_pmu_set_idle_request(IDLE_REQ_HEVC, false); + RESTORE_QOS(hevc_r_qos, HEVC_R); + RESTORE_QOS(hevc_w_qos, HEVC_W); + } + } + spin_unlock_irqrestore(&pmu_pd_lock, flags); return 0; } diff --git a/include/linux/rockchip/iomap.h b/include/linux/rockchip/iomap.h index af834fad8419..d5593ba58500 100644 --- a/include/linux/rockchip/iomap.h +++ b/include/linux/rockchip/iomap.h @@ -83,8 +83,8 @@ #define RK3288_SERVICE_BUS_SIZE SZ_16K #define RK3288_SERVICE_VIO_PHYS 0XFFAD0000 #define RK3288_SERVICE_VIO_SIZE SZ_4K -#define RK3288_SERVICE_VPU_PHYS 0XFFAE0000 -#define RK3288_SERVICE_VPU_SIZE SZ_4K +#define RK3288_SERVICE_VIDEO_PHYS 0XFFAE0000 +#define RK3288_SERVICE_VIDEO_SIZE SZ_4K #define RK3288_SERVICE_HEVC_PHYS 0XFFAF0000 #define RK3288_SERVICE_HEVC_SIZE SZ_4K #define RK3288_TIMER0_PHYS 0xFF6B0000