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;
}
Esempio n. 2
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;
}