Exemple #1
0
static void rpm_clk_disable(unsigned id)
{
	unsigned long flags;

	spin_lock_irqsave(&rpm_clock_lock, flags);

	if (rpm_clk[id].count > 0)
		rpm_clk[id].count--;
	else {
		pr_warning("%s: Reference counts are incorrect for clock %d!\n",
			   __func__, id);
		goto out;
	}

	if (!rpm_clk[id].count) {
                unsigned peer_id = rpm_clk[id].peer_clk_id;

                if (rpm_clk[id].last_set_khz) {
                        struct msm_rpm_iv_pair iv;
                        unsigned peer_khz = 0, peer_sleep_khz = 0;
                        int rc;

                        iv.id = rpm_clk[id].rpm_clk_id;

                        /* Take peer clock rate into account only if enabled. */
                        if (rpm_clk[peer_id].count) {
                                peer_khz = rpm_clk[peer_id].last_set_khz;
                                peer_sleep_khz =
                                        rpm_clk[peer_id].last_set_sleep_khz;
                        }

                        iv.value = peer_khz;
                        rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
                        if (rc)
                                goto out;

                        iv.value = peer_sleep_khz;
                        rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_SLEEP, &iv, 1);
                }

                /* Turn off local smi_clk after disabling remote clock. */
                if ((id == R_SMI_CLK || id == R_SMI_A_CLK)
                    && !rpm_clk[peer_id].count) {
                        uint32_t regval;
                        spin_lock(&local_clock_reg_lock);
                        regval = secure_readl(MMSS_MAXI_EN2);
                        regval &= ~SMI_2X_AXI_CLK_EN;
                        secure_writel(regval, MMSS_MAXI_EN2);
                        spin_unlock(&local_clock_reg_lock);
                }
        }

out:
	spin_unlock_irqrestore(&rpm_clock_lock, flags);

	return;
}
static void hdmi_msm_reset_core()
{
	uint32_t reg_val = 0;
	hdmi_msm_set_mode(0);
	// Disable clocks
	hdmi_app_clk_init(0);
	udelay(5);
	// Enable clocks
	hdmi_app_clk_init(1);

	reg_val = secure_readl(SW_RESET_CORE_REG);
	reg_val |= BIT(11);
	secure_writel(reg_val, SW_RESET_CORE_REG);
	udelay(5);
	reg_val = secure_readl(SW_RESET_AHB_REG);
	reg_val |= BIT(9);
	secure_writel(reg_val, SW_RESET_AHB_REG);
	udelay(5);
	reg_val = secure_readl(SW_RESET_AHB_REG);
	reg_val |= BIT(9);
	secure_writel(reg_val, SW_RESET_AHB_REG);
	udelay(20);
	reg_val = secure_readl(SW_RESET_CORE_REG);
	reg_val &= ~(BIT(11));
	secure_writel(reg_val, SW_RESET_CORE_REG);
	udelay(5);
	reg_val = secure_readl(SW_RESET_AHB_REG);
	reg_val &= ~(BIT(9));
	secure_writel(reg_val, SW_RESET_AHB_REG);
	udelay(5);
	reg_val = secure_readl(SW_RESET_AHB_REG);
	reg_val &= ~(BIT(9));
	secure_writel(reg_val, SW_RESET_AHB_REG);
	udelay(5);
}
void hdmi_app_clk_init(int on)
{
	uint32_t val = 0;
	if (on) {
		// Enable clocks
		val = secure_readl(MISC_CC2_REG);
		val |= BIT(11);
		secure_writel(val, MISC_CC2_REG);
		udelay(10);
		val = secure_readl(MMSS_AHB_EN_REG);
		val |= BIT(14);
		secure_writel(val, MMSS_AHB_EN_REG);
		udelay(10);
		val = secure_readl(MMSS_AHB_EN_REG);
		val |= BIT(4);
		secure_writel(val, MMSS_AHB_EN_REG);
		udelay(10);
	} else {
		// Disable clocks
		val = secure_readl(MISC_CC2_REG);
		val &= ~(BIT(11));
		secure_writel(val, MISC_CC2_REG);
		udelay(10);
		val = secure_readl(MMSS_AHB_EN_REG);
		val &= ~(BIT(14));
		secure_writel(val, MMSS_AHB_EN_REG);
		udelay(10);
		val = secure_readl(MMSS_AHB_EN_REG);
		val &= ~(BIT(4));
		secure_writel(val, MMSS_AHB_EN_REG);
		udelay(10);
	}
}
static int rpm_clk_enable(unsigned id)
{
	unsigned long flags;
	int rc = 0;

	spin_lock_irqsave(&rpm_clock_lock, flags);

	/* Don't send requests to the RPM if the rate has not been set. */
	if (rpm_clk[id].last_set_khz == 0)
		goto out;

	if (!rpm_clk[id].count) {
		struct msm_rpm_iv_pair iv;
		unsigned this_khz = rpm_clk[id].last_set_khz;
		unsigned this_sleep_khz = rpm_clk[id].last_set_sleep_khz;
		unsigned peer_id = rpm_clk[id].peer_clk_id;
		unsigned peer_khz = 0, peer_sleep_khz = 0;

		/* Turn on local smi_clk before enabling remote clock. */
		if (id == R_SMI_CLK || id == R_SMI_A_CLK) {
			uint32_t regval;
			spin_lock(&local_clock_reg_lock);
			regval = secure_readl(MMSS_MAXI_EN2);
			regval |= SMI_2X_AXI_CLK_EN;
			secure_writel(regval, MMSS_MAXI_EN2);
			spin_unlock(&local_clock_reg_lock);
		}

		iv.id = rpm_clk[id].rpm_clk_id;

		/* Take peer clock's rate into account only if it's enabled. */
		if (rpm_clk[peer_id].count) {
			peer_khz = rpm_clk[peer_id].last_set_khz;
			peer_sleep_khz = rpm_clk[peer_id].last_set_sleep_khz;
		}

		iv.value = max(this_khz, peer_khz);
		rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
		if (rc)
			goto out;

		iv.value = max(this_sleep_khz, peer_sleep_khz);
		rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_SLEEP, &iv, 1);
	}
out:
	if (!rc)
		rpm_clk[id].count++;

	spin_unlock_irqrestore(&rpm_clock_lock, flags);

	return rc;
}
}

/* Enable/disable for non-shared NT PLLs. */
int nt_pll_enable(uint8_t src, uint8_t enable)
{
	static const struct {
		uint32_t const mode_reg;
		uint32_t const status_reg;
	} pll_reg[] = {
		[PLL_1] = {
		MM_PLL0_MODE_REG, MM_PLL0_STATUS_REG},[PLL_2] = {
		MM_PLL1_MODE_REG, MM_PLL1_STATUS_REG},[PLL_3] = {
	MM_PLL2_MODE_REG, MM_PLL2_STATUS_REG},};
	uint32_t pll_mode;

	pll_mode = secure_readl(pll_reg[src].mode_reg);
	if (enable) {
		/* Disable PLL bypass mode. */
		pll_mode |= (1 << 1);
		secure_writel(pll_mode, pll_reg[src].mode_reg);

		/* H/W requires a 5us delay between disabling the bypass and
		 * de-asserting the reset. Delay 10us just to be safe. */
		udelay(10);

		/* De-assert active-low PLL reset. */
		pll_mode |= (1 << 2);
		secure_writel(pll_mode, pll_reg[src].mode_reg);

		/* Enable PLL output. */
		pll_mode |= (1 << 0);