static int footswitch_disable(struct regulator_dev *rdev) { struct footswitch *fs = rdev_get_drvdata(rdev); uint32_t regval, rc = 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; } } if (fs->bus_port2) { rc = msm_bus_axi_porthalt(fs->bus_port2); if (rc) { pr_err("%s: Port 1 halt failed.\n", __func__); goto err_port2_halt; } } /* 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(RESET_DELAY_US); /* Clamp the I/O ports of the core to ensure the values * remain fixed while the core is collapsed. */ regval = readl(fs->gfs_ctl_reg); regval |= CLAMP_BIT; writel(regval, fs->gfs_ctl_reg); /* Collapse the power rail at the footswitch. */ regval &= ~ENABLE_BIT; writel(regval, fs->gfs_ctl_reg); /* Return clocks to their state before this function. */ restore_clocks(fs); fs->is_enabled = 0; return rc; err_port2_halt: msm_bus_axi_portunhalt(fs->bus_port1); out: return rc; }
static int pil_q6v4_shutdown(struct pil_desc *pil) { u32 reg; struct q6v4_data *drv = dev_get_drvdata(pil->dev); const struct pil_q6v4_pdata *pdata = pil->dev->platform_data; /* Make sure bus port is halted */ msm_bus_axi_porthalt(pdata->bus_port); /* Turn off Q6 core clock */ writel_relaxed(Q6SS_SRC_SWITCH_CLK_OVR, drv->base + QDSP6SS_GFMUX_CTL); /* Assert resets */ reg = (Q6SS_SS_ARES | Q6SS_CORE_ARES | Q6SS_ISDB_ARES | Q6SS_ETM_ARES | Q6SS_STOP_CORE_ARES | Q6SS_PRIV_ARES); writel_relaxed(reg, drv->base + QDSP6SS_RESET); /* Turn off Q6 memories */ writel_relaxed(Q6SS_CLAMP_IO, drv->base + QDSP6SS_PWR_CTL); if (drv->modem_base) pil_q6v4_shutdown_modem(); if (drv->vreg_enabled) { regulator_disable(drv->vreg); drv->vreg_enabled = false; } return 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 pil_q6v4_shutdown_trusted(struct pil_desc *pil) { int ret; struct q6v4_data *drv = dev_get_drvdata(pil->dev); struct pil_q6v4_pdata *pdata = pil->dev->platform_data; /* Make sure bus port is halted */ msm_bus_axi_porthalt(pdata->bus_port); ret = pas_shutdown(pdata->pas_id); if (ret) return ret; if (drv->vreg_enabled) { regulator_disable(drv->vreg); drv->vreg_enabled = false; } return ret; }
int mercury_core_reset(void) { struct clk *clk = NULL; /*Resettting MMSS Fabric*/ clk = clk_get(NULL, "jpegd_clk"); if (!IS_ERR(clk)) clk_enable(clk); msm_bus_axi_porthalt(MSM_BUS_MASTER_JPEG_DEC); clk_reset(clk, CLK_RESET_ASSERT); /*need to have some delay here, there is no other way to know if hardware reset is complete*/ usleep_range(1000, 1200); msm_bus_axi_portunhalt(MSM_BUS_MASTER_JPEG_DEC); clk_reset(clk, CLK_RESET_DEASSERT); return 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; }
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(RESET_DELAY_US); /* Enable the power rail at the footswitch. */ regval |= ENABLE_BIT; writel_relaxed(regval, fs->gfs_ctl_reg); /* 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(RESET_DELAY_US); clk_reset(fs->core_clk, CLK_RESET_DEASSERT); udelay(RESET_DELAY_US); } /* 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_port2_halt: msm_bus_axi_porthalt(fs->bus_port0); err: restore_clocks(fs); return rc; }
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; }
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); 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; } } 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; } } 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); if (fs->desc.id == FS_GFX3D) { clk_reset(fs->core_clk, CLK_RESET_ASSERT); udelay(RESET_DELAY_US); clk_reset(fs->core_clk, CLK_RESET_DEASSERT); udelay(RESET_DELAY_US); } clk_set_flags(fs->core_clk, CLKFLAG_RETAIN); 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; }