ARM: rockchip: rk3288 support save/restore QOS when power domain on/off
author黄涛 <huangtao@rock-chips.com>
Mon, 17 Mar 2014 10:50:55 +0000 (18:50 +0800)
committer黄涛 <huangtao@rock-chips.com>
Mon, 17 Mar 2014 10:51:44 +0000 (18:51 +0800)
arch/arm/mach-rockchip/cpu_axi.h
arch/arm/mach-rockchip/rk3188.c
arch/arm/mach-rockchip/rk3288.c
include/linux/rockchip/iomap.h

index e3beedfef4710e42f32df6056652c19743549ca1..e6a0cff3a99354e4f174e875b2028dc096ed1cbe 100644 (file)
        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
index 464e64cc0a328b57de04e96719135ad89d972c67..0426863350744ff6399adc5a0d48bb87f7585ac7 100755 (executable)
@@ -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)
 {
index 10579018fc6433e1592eaf4db285b651ce8262f2..052ebe2daf5b1cb97ca4a5004798a2027e0c4487 100755 (executable)
@@ -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;
 }
index af834fad84191d3dfbbde08217c60d3c58b8f6c6..d5593ba5850047317dab49f6a3807178af762d06 100644 (file)
@@ -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