Esempio n. 1
0
static int gfx2d_footswitch_disable(struct regulator_dev *rdev)
{
	struct footswitch *fs = rdev_get_drvdata(rdev);
	struct fs_clk_data *clock;
	uint32_t regval, rc = 0;

	
	regval = readl_relaxed(fs->gfs_ctl_reg);
	if ((regval & ENABLE_BIT) == 0)
		return 0;

	
	rc = setup_clocks(fs);
	if (rc)
		return rc;

	
	clk_set_flags(fs->core_clk, CLKFLAG_NORETAIN);

	
	if (fs->bus_port0) {
		rc = msm_bus_axi_porthalt(fs->bus_port0);
		if (rc) {
			pr_err("%s port 0 halt failed.\n", fs->desc.name);
			goto err;
		}
	}

	
	clk_disable_unprepare(fs->core_clk);

	for (clock = fs->clk_data; clock->clk; clock++)
		; 
	for (clock--; clock >= fs->clk_data; clock--)
		clk_reset(clock->clk, CLK_RESET_ASSERT);
	
	udelay(5);

	regval |= CLAMP_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	
	regval &= ~ENABLE_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	
	clk_prepare_enable(fs->core_clk);

	
	restore_clocks(fs);

	fs->is_enabled = false;
	return 0;

err:
	clk_set_flags(fs->core_clk, CLKFLAG_RETAIN);
	restore_clocks(fs);
	return rc;
}
static int gfx2d_footswitch_disable(struct regulator_dev *rdev)
{
	struct footswitch *fs = rdev_get_drvdata(rdev);
	uint32_t regval, rc = 0;

	/* Return early if already disabled. */
	regval = readl_relaxed(fs->gfs_ctl_reg);
	if ((regval & ENABLE_BIT) == 0)
		return 0;

	/* Make sure required clocks are on at the correct rates. */
	rc = setup_clocks(fs);
	if (rc)
		goto out;

	/* Halt all bus ports in the power domain. */
	if (fs->bus_port1) {
		rc = msm_bus_axi_porthalt(fs->bus_port1);
		if (rc) {
			pr_err("%s: Port 1 halt failed.\n", __func__);
			goto out;
		}
	}

	/* Disable core clock. */
	clk_disable(fs->core_clk);

	/*
	 * Assert resets for all clocks in the clock domain so that
	 * outputs settle prior to clamping.
	 */
	if (fs->axi_clk)
		clk_reset(fs->axi_clk, CLK_RESET_ASSERT);
	clk_reset(fs->ahb_clk, CLK_RESET_ASSERT);
	clk_reset(fs->core_clk, CLK_RESET_ASSERT);
	/* Wait for synchronous resets to propagate. */
	udelay(20);

	/*
	 * Clamp the I/O ports of the core to ensure the values
	 * remain fixed while the core is collapsed.
	 */
	regval |= CLAMP_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	/* Collapse the power rail at the footswitch. */
	regval &= ~ENABLE_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	/* Re-enable core clock. */
	clk_enable(fs->core_clk);

	/* Return clocks to their state before this function. */
	restore_clocks(fs);

	fs->is_enabled = false;

out:
	return rc;
}
Esempio n. 3
0
static int gfx2d_footswitch_disable(struct regulator_dev *rdev)
{
	struct footswitch *fs = rdev_get_drvdata(rdev);
	struct fs_clk_data *clock;
	uint32_t regval, rc = 0;

	/* Return early if already disabled. */
	regval = readl_relaxed(fs->gfs_ctl_reg);
	if ((regval & ENABLE_BIT) == 0)
		return 0;

	/* Make sure required clocks are on at the correct rates. */
	rc = setup_clocks(fs);
	if (rc)
		return rc;

	/* Allow core memory to collapse when its clock is gated. */
	clk_set_flags(fs->core_clk, CLKFLAG_NORETAIN);

	/* Halt all bus ports in the power domain. */
	if (fs->bus_port0) {
		rc = msm_bus_axi_porthalt(fs->bus_port0);
		if (rc) {
			pr_err("%s port 0 halt failed.\n", fs->desc.name);
			goto err;
		}
	}

	/* Disable core clock. */
	clk_disable_unprepare(fs->core_clk);

	/*
	 * Assert resets for all clocks in the clock domain so that
	 * outputs settle prior to clamping.
	 */
	for (clock = fs->clk_data; clock->clk; clock++)
		; /* Do nothing */
	for (clock--; clock >= fs->clk_data; clock--)
		clk_reset(clock->clk, CLK_RESET_ASSERT);
	/* Wait for synchronous resets to propagate. */
	udelay(5);

	/*
	 * Clamp the I/O ports of the core to ensure the values
	 * remain fixed while the core is collapsed.
	 */
	regval |= CLAMP_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	/* Collapse the power rail at the footswitch. */
	regval &= ~ENABLE_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	/* Re-enable core clock. */
	clk_prepare_enable(fs->core_clk);

	/* Return clocks to their state before this function. */
	restore_clocks(fs);

	fs->is_enabled = false;
	return 0;

err:
	clk_set_flags(fs->core_clk, CLKFLAG_RETAIN);
	restore_clocks(fs);
	return rc;
}
Esempio n. 4
0
static int gfx2d_footswitch_enable(struct regulator_dev *rdev)
{
	struct footswitch *fs = rdev_get_drvdata(rdev);
	struct fs_clk_data *clock;
	uint32_t regval, rc = 0;

	mutex_lock(&claim_lock);
	fs->is_claimed = true;
	mutex_unlock(&claim_lock);

	/* Return early if already enabled. */
	regval = readl_relaxed(fs->gfs_ctl_reg);
	if ((regval & (ENABLE_BIT | CLAMP_BIT)) == ENABLE_BIT)
		return 0;

	/* Make sure required clocks are on at the correct rates. */
	rc = setup_clocks(fs);
	if (rc)
		return rc;

	/* Un-halt all bus ports in the power domain. */
	if (fs->bus_port0) {
		rc = msm_bus_axi_portunhalt(fs->bus_port0);
		if (rc) {
			pr_err("%s port 0 unhalt failed.\n", fs->desc.name);
			goto err;
		}
	}

	/* Disable core clock. */
	clk_disable_unprepare(fs->core_clk);

	/*
	 * (Re-)Assert resets for all clocks in the clock domain, since
	 * footswitch_enable() is first called before footswitch_disable()
	 * and resets should be asserted before power is restored.
	 */
	for (clock = fs->clk_data; clock->clk; clock++)
		; /* Do nothing */
	for (clock--; clock >= fs->clk_data; clock--)
		clk_reset(clock->clk, CLK_RESET_ASSERT);
	/* Wait for synchronous resets to propagate. */
	udelay(RESET_DELAY_US);

	/* Enable the power rail at the footswitch. */
	regval |= ENABLE_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);
	mb();
	udelay(1);

	/* Un-clamp the I/O ports. */
	regval &= ~CLAMP_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	/* Deassert resets for all clocks in the power domain. */
	for (clock = fs->clk_data; clock->clk; clock++)
		clk_reset(clock->clk, CLK_RESET_DEASSERT);
	udelay(RESET_DELAY_US);

	/* Re-enable core clock. */
	clk_prepare_enable(fs->core_clk);

	/* Prevent core memory from collapsing when its clock is gated. */
	clk_set_flags(fs->core_clk, CLKFLAG_RETAIN);

	/* Return clocks to their state before this function. */
	restore_clocks(fs);

	fs->is_enabled = true;
	return 0;

err:
	restore_clocks(fs);
	return rc;
}
Esempio n. 5
0
static int footswitch_disable(struct regulator_dev *rdev)
{
	struct footswitch *fs = rdev_get_drvdata(rdev);
	struct fs_clk_data *clock;
	uint32_t regval, rc = 0;

	/* Return early if already disabled. */
	regval = readl_relaxed(fs->gfs_ctl_reg);
	if ((regval & ENABLE_BIT) == 0)
		return 0;

	/* Make sure required clocks are on at the correct rates. */
	rc = setup_clocks(fs);
	if (rc)
		return rc;

	/* Allow core memory to collapse when its clock is gated. */
	//if (fs->desc.id != FS_GFX3D_8064)
		clk_set_flags(fs->core_clk, CLKFLAG_NORETAIN_MEM);

	/* Halt all bus ports in the power domain. */
	if (fs->bus_port0) {
		rc = msm_bus_axi_porthalt(fs->bus_port0);
		if (rc) {
			pr_err("%s port 0 halt failed.\n", fs->desc.name);
			goto err;
		}
	}
	if (fs->bus_port1) {
		rc = msm_bus_axi_porthalt(fs->bus_port1);
		if (rc) {
			pr_err("%s port 1 halt failed.\n", fs->desc.name);
			goto err_port2_halt;
		}
	}

	/*
	 * Assert resets for all clocks in the clock domain so that
	 * outputs settle prior to clamping.
	 */
	for (clock = fs->clk_data; clock->clk; clock++)
		; /* Do nothing */
	for (clock--; clock >= fs->clk_data; clock--)
		clk_reset(clock->clk, CLK_RESET_ASSERT);
	/* Wait for synchronous resets to propagate. */
	udelay(fs->reset_delay_us);

	/*
	 * Return clocks to their state before this function. For robustness
	 * if memory-retention across collapses is required, clocks should
	 * be disabled before asserting the clamps. Assuming clocks were off
	 * before entering footswitch_disable(), this will be true.
	 */
	restore_clocks(fs);

	/*
	 * Clamp the I/O ports of the core to ensure the values
	 * remain fixed while the core is collapsed.
	 */
	regval |= CLAMP_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	/* Collapse the power rail at the footswitch. */
	regval &= ~ENABLE_BIT;

#if defined(CONFIG_ARCH_MSM8930)
	writel_relaxed(regval, fs->gfs_ctl_reg);
#else
	if (fs->desc.id != FS_GFX3D)
		writel_relaxed(regval, fs->gfs_ctl_reg);
#endif

	fs->is_enabled = false;
	return 0;

err_port2_halt:
	msm_bus_axi_portunhalt(fs->bus_port0);
err:
	clk_set_flags(fs->core_clk, CLKFLAG_RETAIN_MEM);
	restore_clocks(fs);
	return rc;
}
Esempio n. 6
0
static int footswitch_enable(struct regulator_dev *rdev)
{
	struct footswitch *fs = rdev_get_drvdata(rdev);
	struct fs_clk_data *clock;
	uint32_t regval, rc = 0;

	mutex_lock(&claim_lock);
	fs->is_claimed = true;
	mutex_unlock(&claim_lock);

	/* Return early if already enabled. */
	regval = readl_relaxed(fs->gfs_ctl_reg);
	if ((regval & (ENABLE_BIT | CLAMP_BIT)) == ENABLE_BIT)
		return 0;

	/* Make sure required clocks are on at the correct rates. */
	rc = setup_clocks(fs);
	if (rc)
		return rc;

	/* Un-halt all bus ports in the power domain. */
	if (fs->bus_port0) {
		rc = msm_bus_axi_portunhalt(fs->bus_port0);
		if (rc) {
			pr_err("%s port 0 unhalt failed.\n", fs->desc.name);
			goto err;
		}
	}
	if (fs->bus_port1) {
		rc = msm_bus_axi_portunhalt(fs->bus_port1);
		if (rc) {
			pr_err("%s port 1 unhalt failed.\n", fs->desc.name);
			goto err_port2_halt;
		}
	}

	/*
	 * (Re-)Assert resets for all clocks in the clock domain, since
	 * footswitch_enable() is first called before footswitch_disable()
	 * and resets should be asserted before power is restored.
	 */
	for (clock = fs->clk_data; clock->clk; clock++)
		; /* Do nothing */
	for (clock--; clock >= fs->clk_data; clock--)
		clk_reset(clock->clk, CLK_RESET_ASSERT);
	/* Wait for synchronous resets to propagate. */
	udelay(fs->reset_delay_us);

	/* Enable the power rail at the footswitch. */
	regval |= ENABLE_BIT;

#if defined(CONFIG_ARCH_MSM8930)
	writel_relaxed(regval, fs->gfs_ctl_reg);
#else
	if (fs->desc.id != FS_GFX3D)
		writel_relaxed(regval, fs->gfs_ctl_reg);
#endif

	/* Wait for the rail to fully charge. */
	mb();
	udelay(1);

	/* Un-clamp the I/O ports. */
	regval &= ~CLAMP_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	/* Deassert resets for all clocks in the power domain. */
	for (clock = fs->clk_data; clock->clk; clock++)
		clk_reset(clock->clk, CLK_RESET_DEASSERT);
	/* Toggle core reset again after first power-on (required for GFX3D). */
	if (fs->desc.id == FS_GFX3D) {
		clk_reset(fs->core_clk, CLK_RESET_ASSERT);
		udelay(fs->reset_delay_us);
		clk_reset(fs->core_clk, CLK_RESET_DEASSERT);
		udelay(fs->reset_delay_us);
	}

	/* Prevent core memory from collapsing when its clock is gated. */
	clk_set_flags(fs->core_clk, CLKFLAG_RETAIN_MEM);

	/* Return clocks to their state before this function. */
	restore_clocks(fs);

	fs->is_enabled = true;
	return 0;

err_port2_halt:
	msm_bus_axi_porthalt(fs->bus_port0);
err:
	restore_clocks(fs);
	return rc;
}
static int gfx2d_footswitch_enable(struct regulator_dev *rdev)
{
	struct footswitch *fs = rdev_get_drvdata(rdev);
	uint32_t regval, rc = 0;

	mutex_lock(&claim_lock);
	fs->is_claimed = true;
	mutex_unlock(&claim_lock);

	/* Return early if already enabled. */
	regval = readl_relaxed(fs->gfs_ctl_reg);
	if ((regval & (ENABLE_BIT | CLAMP_BIT)) == ENABLE_BIT)
		return 0;

	/* Make sure required clocks are on at the correct rates. */
	rc = setup_clocks(fs);
	if (rc)
		goto out;

	/* Un-halt all bus ports in the power domain. */
	if (fs->bus_port1) {
		rc = msm_bus_axi_portunhalt(fs->bus_port1);
		if (rc) {
			pr_err("%s: Port 1 unhalt failed.\n", __func__);
			goto out;
		}
	}

	/* Disable core clock. */
	clk_disable(fs->core_clk);

	/*
	 * (Re-)Assert resets for all clocks in the clock domain, since
	 * footswitch_enable() is first called before footswitch_disable()
	 * and resets should be asserted before power is restored.
	 */
	if (fs->axi_clk)
		clk_reset(fs->axi_clk, CLK_RESET_ASSERT);
	clk_reset(fs->ahb_clk, CLK_RESET_ASSERT);
	clk_reset(fs->core_clk, CLK_RESET_ASSERT);
	/* Wait for synchronous resets to propagate. */
	udelay(20);

	/* Enable the power rail at the footswitch. */
	regval |= ENABLE_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);
	mb();
	udelay(1);

	/* Un-clamp the I/O ports. */
	regval &= ~CLAMP_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	/* Deassert resets for all clocks in the power domain. */
	if (fs->axi_clk)
		clk_reset(fs->axi_clk, CLK_RESET_DEASSERT);
	clk_reset(fs->ahb_clk, CLK_RESET_DEASSERT);
	clk_reset(fs->core_clk, CLK_RESET_DEASSERT);
	udelay(20);

	/* Re-enable core clock. */
	clk_enable(fs->core_clk);

	/* Return clocks to their state before this function. */
	restore_clocks(fs);

	fs->is_enabled = true;
out:
	return rc;
}
Esempio n. 8
0
static int gfx2d_footswitch_enable(struct regulator_dev *rdev)
{
	struct footswitch *fs = rdev_get_drvdata(rdev);
	struct fs_clk_data *clock;
	uint32_t regval, rc = 0;

	mutex_lock(&claim_lock);
	fs->is_claimed = true;
	mutex_unlock(&claim_lock);

	
	regval = readl_relaxed(fs->gfs_ctl_reg);
	if ((regval & (ENABLE_BIT | CLAMP_BIT)) == ENABLE_BIT)
		return 0;

	
	rc = setup_clocks(fs);
	if (rc)
		return rc;

	
	if (fs->bus_port0) {
		rc = msm_bus_axi_portunhalt(fs->bus_port0);
		if (rc) {
			pr_err("%s port 0 unhalt failed.\n", fs->desc.name);
			goto err;
		}
	}

	
	clk_disable_unprepare(fs->core_clk);

	for (clock = fs->clk_data; clock->clk; clock++)
		; 
	for (clock--; clock >= fs->clk_data; clock--)
		clk_reset(clock->clk, CLK_RESET_ASSERT);
	
	udelay(RESET_DELAY_US);

	
	regval |= ENABLE_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);
	mb();
	udelay(1);

	
	regval &= ~CLAMP_BIT;
	writel_relaxed(regval, fs->gfs_ctl_reg);

	
	for (clock = fs->clk_data; clock->clk; clock++)
		clk_reset(clock->clk, CLK_RESET_DEASSERT);
	udelay(RESET_DELAY_US);

	
	clk_prepare_enable(fs->core_clk);

	
	clk_set_flags(fs->core_clk, CLKFLAG_RETAIN);

	
	restore_clocks(fs);

	fs->is_enabled = true;
	return 0;

err:
	restore_clocks(fs);
	return rc;
}
static int footswitch_enable(struct regulator_dev *rdev)
{
	struct footswitch *fs = rdev_get_drvdata(rdev);
	uint32_t regval, rc = 0;

	mutex_lock(&claim_lock);
	fs->is_claimed = 1;
	mutex_unlock(&claim_lock);

	/* Make sure required clocks are on at the correct rates. */
	rc = setup_clocks(fs);
	if (rc)
		goto out;

	/* (Re-)Assert resets for all clocks in the clock domain, since
	 * footswitch_enable() is first called before footswitch_disable()
	 * and resets should be asserted before power is restored. */
	if (fs->axi_clk)
		clk_reset(fs->axi_clk, CLK_RESET_ASSERT);
	clk_reset(fs->ahb_clk, CLK_RESET_ASSERT);
	clk_reset(fs->core_clk, CLK_RESET_ASSERT);
	/* Wait for synchronous resets to propagate. */
	udelay(RESET_DELAY_US);

	/* Un-halt all bus ports in the power domain. */
	if (fs->bus_port1) {
		rc = msm_bus_axi_portunhalt(fs->bus_port1);
		if (rc) {
			pr_err("%s: Port 1 unhalt failed.\n", __func__);
			goto out;
		}
	}
	if (fs->bus_port2) {
		rc = msm_bus_axi_portunhalt(fs->bus_port2);
		if (rc) {
			pr_err("%s: Port 2 unhalt failed.\n", __func__);
			goto out;
		}
	}

	/* Enable the power rail at the footswitch. */
	regval = readl(fs->gfs_ctl_reg);
	regval |= ENABLE_BIT;
	writel(regval, fs->gfs_ctl_reg);
	/* Wait 2us for the rail to fully charge. */
	udelay(2);

	/* Deassert resets for all clocks in the power domain. */
	clk_reset(fs->core_clk, CLK_RESET_DEASSERT);
	clk_reset(fs->ahb_clk, CLK_RESET_DEASSERT);
	if (fs->axi_clk)
		clk_reset(fs->axi_clk, CLK_RESET_DEASSERT);
	/* Toggle core reset now that power is on (required for some cores). */
	clk_reset(fs->core_clk, CLK_RESET_ASSERT);
	udelay(RESET_DELAY_US);
	clk_reset(fs->core_clk, CLK_RESET_DEASSERT);
	udelay(RESET_DELAY_US);

	/* Un-clamp the I/O ports. */
	regval &= ~CLAMP_BIT;
	writel(regval, fs->gfs_ctl_reg);

	/* Wait for the clamps to clear and signals to settle. */
	udelay(5);

	/* Return clocks to their state before this function. */
	restore_clocks(fs);

	fs->is_enabled = 1;
out:
	return rc;
}