Merge "clk: msm: clock-osm: Do not initialize ACD if the cluster isn't online"
This commit is contained in:
commit
fd2a5d6bd5
1 changed files with 88 additions and 86 deletions
|
@ -606,6 +606,83 @@ static int clk_osm_acd_auto_local_write_reg(struct clk_osm *c, u32 mask)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int clk_osm_acd_init(struct clk_osm *c)
|
||||||
|
{
|
||||||
|
|
||||||
|
int rc = 0;
|
||||||
|
u32 auto_xfer_mask = 0;
|
||||||
|
|
||||||
|
if (!c->acd_init)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
c->acd_debugfs_addr = ACD_HW_VERSION;
|
||||||
|
|
||||||
|
/* Program ACD tunable-length delay register */
|
||||||
|
clk_osm_acd_master_write_reg(c, c->acd_td, ACDTD);
|
||||||
|
auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACDTD);
|
||||||
|
|
||||||
|
/* Program ACD control register */
|
||||||
|
clk_osm_acd_master_write_reg(c, c->acd_cr, ACDCR);
|
||||||
|
auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACDCR);
|
||||||
|
|
||||||
|
/* Program ACD soft start control register */
|
||||||
|
clk_osm_acd_master_write_reg(c, c->acd_sscr, ACDSSCR);
|
||||||
|
auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACDSSCR);
|
||||||
|
|
||||||
|
/* Program initial ACD external interface configuration register */
|
||||||
|
clk_osm_acd_master_write_reg(c, c->acd_extint0_cfg, ACD_EXTINT_CFG);
|
||||||
|
auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACD_EXTINT_CFG);
|
||||||
|
|
||||||
|
/* Program ACD auto-register transfer control register */
|
||||||
|
clk_osm_acd_master_write_reg(c, c->acd_autoxfer_ctl, ACD_AUTOXFER_CTL);
|
||||||
|
|
||||||
|
/* Ensure writes complete before transfers to local copy */
|
||||||
|
clk_osm_acd_mb(c);
|
||||||
|
|
||||||
|
/* Transfer master copies */
|
||||||
|
rc = clk_osm_acd_auto_local_write_reg(c, auto_xfer_mask);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/* Switch CPUSS clock source to ACD clock */
|
||||||
|
rc = clk_osm_acd_master_write_through_reg(c, ACD_GFMUX_CFG_SELECT,
|
||||||
|
ACD_GFMUX_CFG);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/* Program ACD_DCVS_SW */
|
||||||
|
rc = clk_osm_acd_master_write_through_reg(c,
|
||||||
|
ACD_DCVS_SW_DCVS_IN_PRGR_SET,
|
||||||
|
ACD_DCVS_SW);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
rc = clk_osm_acd_master_write_through_reg(c,
|
||||||
|
ACD_DCVS_SW_DCVS_IN_PRGR_CLEAR,
|
||||||
|
ACD_DCVS_SW);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
udelay(1);
|
||||||
|
|
||||||
|
/* Program final ACD external interface configuration register */
|
||||||
|
rc = clk_osm_acd_master_write_through_reg(c, c->acd_extint1_cfg,
|
||||||
|
ACD_EXTINT_CFG);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ACDCR, ACDTD, ACDSSCR, ACD_EXTINT_CFG, ACD_GFMUX_CFG
|
||||||
|
* must be copied from master to local copy on PC exit.
|
||||||
|
*/
|
||||||
|
auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACD_GFMUX_CFG);
|
||||||
|
clk_osm_acd_master_write_reg(c, auto_xfer_mask, ACD_AUTOXFER_CFG);
|
||||||
|
|
||||||
|
/* ACD has been initialized and enabled for this cluster */
|
||||||
|
c->acd_init = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int clk_osm_count_ns(struct clk_osm *c, u64 nsec)
|
static inline int clk_osm_count_ns(struct clk_osm *c, u64 nsec)
|
||||||
{
|
{
|
||||||
u64 temp;
|
u64 temp;
|
||||||
|
@ -729,6 +806,17 @@ static int clk_osm_set_rate(struct clk *c, unsigned long rate)
|
||||||
static int clk_osm_enable(struct clk *c)
|
static int clk_osm_enable(struct clk *c)
|
||||||
{
|
{
|
||||||
struct clk_osm *cpuclk = to_clk_osm(c);
|
struct clk_osm *cpuclk = to_clk_osm(c);
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = clk_osm_acd_init(cpuclk);
|
||||||
|
if (rc) {
|
||||||
|
pr_err("Failed to initialize ACD for cluster %d, rc=%d\n",
|
||||||
|
cpuclk->cluster_num, rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait for 5 usecs before enabling OSM */
|
||||||
|
udelay(5);
|
||||||
|
|
||||||
clk_osm_write_reg(cpuclk, 1, ENABLE_REG);
|
clk_osm_write_reg(cpuclk, 1, ENABLE_REG);
|
||||||
|
|
||||||
|
@ -3105,81 +3193,6 @@ static int clk_osm_panic_callback(struct notifier_block *nfb,
|
||||||
return NOTIFY_OK;
|
return NOTIFY_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int clk_osm_acd_init(struct clk_osm *c)
|
|
||||||
{
|
|
||||||
|
|
||||||
int rc = 0;
|
|
||||||
u32 auto_xfer_mask = 0;
|
|
||||||
|
|
||||||
if (!c->acd_init)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
c->acd_debugfs_addr = ACD_HW_VERSION;
|
|
||||||
|
|
||||||
/* Program ACD tunable-length delay register */
|
|
||||||
clk_osm_acd_master_write_reg(c, c->acd_td, ACDTD);
|
|
||||||
auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACDTD);
|
|
||||||
|
|
||||||
/* Program ACD control register */
|
|
||||||
clk_osm_acd_master_write_reg(c, c->acd_cr, ACDCR);
|
|
||||||
auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACDCR);
|
|
||||||
|
|
||||||
/* Program ACD soft start control register */
|
|
||||||
clk_osm_acd_master_write_reg(c, c->acd_sscr, ACDSSCR);
|
|
||||||
auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACDSSCR);
|
|
||||||
|
|
||||||
/* Program initial ACD external interface configuration register */
|
|
||||||
clk_osm_acd_master_write_reg(c, c->acd_extint0_cfg, ACD_EXTINT_CFG);
|
|
||||||
auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACD_EXTINT_CFG);
|
|
||||||
|
|
||||||
/* Program ACD auto-register transfer control register */
|
|
||||||
clk_osm_acd_master_write_reg(c, c->acd_autoxfer_ctl, ACD_AUTOXFER_CTL);
|
|
||||||
|
|
||||||
/* Ensure writes complete before transfers to local copy */
|
|
||||||
clk_osm_acd_mb(c);
|
|
||||||
|
|
||||||
/* Transfer master copies */
|
|
||||||
rc = clk_osm_acd_auto_local_write_reg(c, auto_xfer_mask);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
/* Switch CPUSS clock source to ACD clock */
|
|
||||||
rc = clk_osm_acd_master_write_through_reg(c, ACD_GFMUX_CFG_SELECT,
|
|
||||||
ACD_GFMUX_CFG);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
/* Program ACD_DCVS_SW */
|
|
||||||
rc = clk_osm_acd_master_write_through_reg(c,
|
|
||||||
ACD_DCVS_SW_DCVS_IN_PRGR_SET,
|
|
||||||
ACD_DCVS_SW);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
rc = clk_osm_acd_master_write_through_reg(c,
|
|
||||||
ACD_DCVS_SW_DCVS_IN_PRGR_CLEAR,
|
|
||||||
ACD_DCVS_SW);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
udelay(1);
|
|
||||||
|
|
||||||
/* Program final ACD external interface configuration register */
|
|
||||||
rc = clk_osm_acd_master_write_through_reg(c, c->acd_extint1_cfg,
|
|
||||||
ACD_EXTINT_CFG);
|
|
||||||
if (rc)
|
|
||||||
return rc;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ACDCR, ACDTD, ACDSSCR, ACD_EXTINT_CFG, ACD_GFMUX_CFG
|
|
||||||
* must be copied from master to local copy on PC exit.
|
|
||||||
*/
|
|
||||||
auto_xfer_mask |= ACD_REG_RELATIVE_ADDR_BITMASK(ACD_GFMUX_CFG);
|
|
||||||
clk_osm_acd_master_write_reg(c, auto_xfer_mask, ACD_AUTOXFER_CFG);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long init_rate = 300000000;
|
static unsigned long init_rate = 300000000;
|
||||||
static unsigned long osm_clk_init_rate = 200000000;
|
static unsigned long osm_clk_init_rate = 200000000;
|
||||||
|
|
||||||
|
@ -3362,17 +3375,6 @@ static int cpu_clock_osm_driver_probe(struct platform_device *pdev)
|
||||||
clk_osm_setup_cluster_pll(&perfcl_clk);
|
clk_osm_setup_cluster_pll(&perfcl_clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = clk_osm_acd_init(&pwrcl_clk);
|
|
||||||
if (rc) {
|
|
||||||
pr_err("failed to initialize ACD for pwrcl, rc=%d\n", rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
rc = clk_osm_acd_init(&perfcl_clk);
|
|
||||||
if (rc) {
|
|
||||||
pr_err("failed to initialize ACD for perfcl, rc=%d\n", rc);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_init(&pwrcl_clk.lock);
|
spin_lock_init(&pwrcl_clk.lock);
|
||||||
spin_lock_init(&perfcl_clk.lock);
|
spin_lock_init(&perfcl_clk.lock);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue