static int rk3188_pmu_set_power_domain(enum pmu_power_domain pd, bool on) { unsigned long flags; spin_lock_irqsave(&pmu_pd_lock, flags); if (rk3188_pmu_power_domain_is_on(pd) == on) { spin_unlock_irqrestore(&pmu_pd_lock, flags); return 0; } if (!on) { /* if power down, idle request to NIU first */ if (pd == PD_VIO) { SAVE_QOS(lcdc0_qos, LCDC0); SAVE_QOS(lcdc1_qos, LCDC1); SAVE_QOS(cif0_qos, CIF0); SAVE_QOS(cif1_qos, CIF1); SAVE_QOS(ipp_qos, IPP); SAVE_QOS(rga_qos, RGA); rk3188_pmu_set_idle_request(IDLE_REQ_VIO, true); } else if (pd == PD_VIDEO) { SAVE_QOS(vpu_qos, VPU); rk3188_pmu_set_idle_request(IDLE_REQ_VIDEO, true); } else if (pd == PD_GPU) { SAVE_QOS(gpu_qos, GPU); rk3188_pmu_set_idle_request(IDLE_REQ_GPU, true); } } rk3188_do_pmu_set_power_domain(pd, on); if (on) { /* if power up, idle request release to NIU */ if (pd == PD_VIO) { rk3188_pmu_set_idle_request(IDLE_REQ_VIO, false); RESTORE_QOS(lcdc0_qos, LCDC0); RESTORE_QOS(lcdc1_qos, LCDC1); RESTORE_QOS(cif0_qos, CIF0); RESTORE_QOS(cif1_qos, CIF1); RESTORE_QOS(ipp_qos, IPP); RESTORE_QOS(rga_qos, RGA); } else if (pd == PD_VIDEO) { rk3188_pmu_set_idle_request(IDLE_REQ_VIDEO, false); RESTORE_QOS(vpu_qos, VPU); } else if (pd == PD_GPU) { rk3188_pmu_set_idle_request(IDLE_REQ_GPU, false); RESTORE_QOS(gpu_qos, GPU); } } spin_unlock_irqrestore(&pmu_pd_lock, flags); return 0; }
static int rk3288_pmu_set_power_domain(enum pmu_power_domain pd, bool on) { unsigned long flags; spin_lock_irqsave(&pmu_pd_lock, flags); if (rk3288_pmu_power_domain_is_on(pd) == on) goto out; 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); } else if (pd >= PD_CPU_1 && pd <= PD_CPU_3) { writel_relaxed(0x20002 << (pd - PD_CPU_1), RK_CRU_VIRT + RK3288_CRU_SOFTRSTS_CON(0)); dsb(); } } 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); } else if (pd >= PD_CPU_1 && pd <= PD_CPU_3) { writel_relaxed(0x20000 << (pd - PD_CPU_1), RK_CRU_VIRT + RK3288_CRU_SOFTRSTS_CON(0)); dsb(); udelay(10); writel_relaxed(virt_to_phys(secondary_startup), RK3288_IMEM_VIRT + 8); writel_relaxed(0xDEADBEAF, RK3288_IMEM_VIRT + 4); dsb_sev(); } } out: spin_unlock_irqrestore(&pmu_pd_lock, flags); return 0; }