1
0
Fork 0

Merge branch '4.15-rc1-clkctrl-mach-omap2' of https://github.com/t-kristo/linux-pm into omap-for-v4.16/soc

hifive-unleashed-5.1
Tony Lindgren 2017-12-11 07:46:40 -08:00
commit fdf3632938
8 changed files with 59 additions and 55 deletions

View File

@ -1224,14 +1224,6 @@ ccd_exit:
return 0; return 0;
} }
u32 clkdm_xlate_address(struct clockdomain *clkdm)
{
if (arch_clkdm->clkdm_xlate_address)
return arch_clkdm->clkdm_xlate_address(clkdm);
return 0;
}
/** /**
* clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm
* @clkdm: struct clockdomain * * @clkdm: struct clockdomain *

View File

@ -175,7 +175,6 @@ struct clkdm_ops {
void (*clkdm_deny_idle)(struct clockdomain *clkdm); void (*clkdm_deny_idle)(struct clockdomain *clkdm);
int (*clkdm_clk_enable)(struct clockdomain *clkdm); int (*clkdm_clk_enable)(struct clockdomain *clkdm);
int (*clkdm_clk_disable)(struct clockdomain *clkdm); int (*clkdm_clk_disable)(struct clockdomain *clkdm);
u32 (*clkdm_xlate_address)(struct clockdomain *clkdm);
}; };
int clkdm_register_platform_funcs(struct clkdm_ops *co); int clkdm_register_platform_funcs(struct clkdm_ops *co);
@ -214,7 +213,6 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh); int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh); int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);
u32 clkdm_xlate_address(struct clockdomain *clkdm);
extern void __init omap242x_clockdomains_init(void); extern void __init omap242x_clockdomains_init(void);
extern void __init omap243x_clockdomains_init(void); extern void __init omap243x_clockdomains_init(void);

View File

@ -52,6 +52,7 @@ extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2);
* @wait_module_idle: ptr to the SoC CM-specific wait_module_idle impl * @wait_module_idle: ptr to the SoC CM-specific wait_module_idle impl
* @module_enable: ptr to the SoC CM-specific module_enable impl * @module_enable: ptr to the SoC CM-specific module_enable impl
* @module_disable: ptr to the SoC CM-specific module_disable impl * @module_disable: ptr to the SoC CM-specific module_disable impl
* @xlate_clkctrl: ptr to the SoC CM-specific clkctrl xlate addr impl
*/ */
struct cm_ll_data { struct cm_ll_data {
int (*split_idlest_reg)(struct clk_omap_reg *idlest_reg, s16 *prcm_inst, int (*split_idlest_reg)(struct clk_omap_reg *idlest_reg, s16 *prcm_inst,
@ -62,6 +63,7 @@ struct cm_ll_data {
u8 idlest_shift); u8 idlest_shift);
void (*module_enable)(u8 mode, u8 part, u16 inst, u16 clkctrl_offs); void (*module_enable)(u8 mode, u8 part, u16 inst, u16 clkctrl_offs);
void (*module_disable)(u8 part, u16 inst, u16 clkctrl_offs); void (*module_disable)(u8 part, u16 inst, u16 clkctrl_offs);
u32 (*xlate_clkctrl)(u8 part, u16 inst, u16 clkctrl_offs);
}; };
extern int cm_split_idlest_reg(struct clk_omap_reg *idlest_reg, s16 *prcm_inst, extern int cm_split_idlest_reg(struct clk_omap_reg *idlest_reg, s16 *prcm_inst,
@ -72,6 +74,7 @@ int omap_cm_wait_module_idle(u8 part, s16 prcm_mod, u16 idlest_reg,
u8 idlest_shift); u8 idlest_shift);
int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs); int omap_cm_module_enable(u8 mode, u8 part, u16 inst, u16 clkctrl_offs);
int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs); int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs);
u32 omap_cm_xlate_clkctrl(u8 part, u16 inst, u16 clkctrl_offs);
extern int cm_register(const struct cm_ll_data *cld); extern int cm_register(const struct cm_ll_data *cld);
extern int cm_unregister(const struct cm_ll_data *cld); extern int cm_unregister(const struct cm_ll_data *cld);
int omap_cm_init(void); int omap_cm_init(void);

View File

@ -333,6 +333,11 @@ static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm)
return 0; return 0;
} }
static u32 am33xx_cm_xlate_clkctrl(u8 part, u16 inst, u16 offset)
{
return cm_base.pa + inst + offset;
}
struct clkdm_ops am33xx_clkdm_operations = { struct clkdm_ops am33xx_clkdm_operations = {
.clkdm_sleep = am33xx_clkdm_sleep, .clkdm_sleep = am33xx_clkdm_sleep,
.clkdm_wakeup = am33xx_clkdm_wakeup, .clkdm_wakeup = am33xx_clkdm_wakeup,
@ -347,6 +352,7 @@ static const struct cm_ll_data am33xx_cm_ll_data = {
.wait_module_idle = &am33xx_cm_wait_module_idle, .wait_module_idle = &am33xx_cm_wait_module_idle,
.module_enable = &am33xx_cm_module_enable, .module_enable = &am33xx_cm_module_enable,
.module_disable = &am33xx_cm_module_disable, .module_disable = &am33xx_cm_module_disable,
.xlate_clkctrl = &am33xx_cm_xlate_clkctrl,
}; };
int __init am33xx_cm_init(const struct omap_prcm_init_data *data) int __init am33xx_cm_init(const struct omap_prcm_init_data *data)

View File

@ -175,6 +175,16 @@ int omap_cm_module_disable(u8 part, u16 inst, u16 clkctrl_offs)
return 0; return 0;
} }
u32 omap_cm_xlate_clkctrl(u8 part, u16 inst, u16 clkctrl_offs)
{
if (!cm_ll_data->xlate_clkctrl) {
WARN_ONCE(1, "cm: %s: no low-level function defined\n",
__func__);
return 0;
}
return cm_ll_data->xlate_clkctrl(part, inst, clkctrl_offs);
}
/** /**
* cm_register - register per-SoC low-level data with the CM * cm_register - register per-SoC low-level data with the CM
* @cld: low-level per-SoC OMAP CM data & function pointers to register * @cld: low-level per-SoC OMAP CM data & function pointers to register

View File

@ -476,12 +476,9 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
return 0; return 0;
} }
static u32 omap4_clkdm_xlate_address(struct clockdomain *clkdm) static u32 omap4_cminst_xlate_clkctrl(u8 part, u16 inst, u16 offset)
{ {
u32 addr = _cm_bases[clkdm->prcm_partition].pa + clkdm->cm_inst + return _cm_bases[part].pa + inst + offset;
clkdm->clkdm_offs;
return addr;
} }
struct clkdm_ops omap4_clkdm_operations = { struct clkdm_ops omap4_clkdm_operations = {
@ -499,7 +496,6 @@ struct clkdm_ops omap4_clkdm_operations = {
.clkdm_deny_idle = omap4_clkdm_deny_idle, .clkdm_deny_idle = omap4_clkdm_deny_idle,
.clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_enable = omap4_clkdm_clk_enable,
.clkdm_clk_disable = omap4_clkdm_clk_disable, .clkdm_clk_disable = omap4_clkdm_clk_disable,
.clkdm_xlate_address = omap4_clkdm_xlate_address,
}; };
struct clkdm_ops am43xx_clkdm_operations = { struct clkdm_ops am43xx_clkdm_operations = {
@ -509,7 +505,6 @@ struct clkdm_ops am43xx_clkdm_operations = {
.clkdm_deny_idle = omap4_clkdm_deny_idle, .clkdm_deny_idle = omap4_clkdm_deny_idle,
.clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_enable = omap4_clkdm_clk_enable,
.clkdm_clk_disable = omap4_clkdm_clk_disable, .clkdm_clk_disable = omap4_clkdm_clk_disable,
.clkdm_xlate_address = omap4_clkdm_xlate_address,
}; };
static const struct cm_ll_data omap4xxx_cm_ll_data = { static const struct cm_ll_data omap4xxx_cm_ll_data = {
@ -517,6 +512,7 @@ static const struct cm_ll_data omap4xxx_cm_ll_data = {
.wait_module_idle = &omap4_cminst_wait_module_idle, .wait_module_idle = &omap4_cminst_wait_module_idle,
.module_enable = &omap4_cminst_module_enable, .module_enable = &omap4_cminst_module_enable,
.module_disable = &omap4_cminst_module_disable, .module_disable = &omap4_cminst_module_disable,
.xlate_clkctrl = &omap4_cminst_xlate_clkctrl,
}; };
int __init omap4_cm_init(const struct omap_prcm_init_data *data) int __init omap4_cm_init(const struct omap_prcm_init_data *data)

View File

@ -185,15 +185,15 @@
/** /**
* struct clkctrl_provider - clkctrl provider mapping data * struct clkctrl_provider - clkctrl provider mapping data
* @addr: base address for the provider * @addr: base address for the provider
* @offset: base offset for the provider * @size: size of the provider address space
* @clkdm: base clockdomain for provider * @offset: offset of the provider from PRCM instance base
* @node: device node associated with the provider * @node: device node associated with the provider
* @link: list link * @link: list link
*/ */
struct clkctrl_provider { struct clkctrl_provider {
u32 addr; u32 addr;
u32 size;
u16 offset; u16 offset;
struct clockdomain *clkdm;
struct device_node *node; struct device_node *node;
struct list_head link; struct list_head link;
}; };
@ -223,8 +223,7 @@ struct omap_hwmod_soc_ops {
void (*update_context_lost)(struct omap_hwmod *oh); void (*update_context_lost)(struct omap_hwmod *oh);
int (*get_context_lost)(struct omap_hwmod *oh); int (*get_context_lost)(struct omap_hwmod *oh);
int (*disable_direct_prcm)(struct omap_hwmod *oh); int (*disable_direct_prcm)(struct omap_hwmod *oh);
u32 (*xlate_clkctrl)(struct omap_hwmod *oh, u32 (*xlate_clkctrl)(struct omap_hwmod *oh);
struct clkctrl_provider *provider);
}; };
/* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */
@ -716,45 +715,28 @@ static const struct of_device_id ti_clkctrl_match_table[] __initconst = {
{ } { }
}; };
static int _match_clkdm(struct clockdomain *clkdm, void *user)
{
struct clkctrl_provider *provider = user;
if (clkdm_xlate_address(clkdm) == provider->addr) {
pr_debug("%s: Matched clkdm %s for addr %x (%s)\n", __func__,
clkdm->name, provider->addr,
provider->node->parent->name);
provider->clkdm = clkdm;
return -1;
}
return 0;
}
static int _setup_clkctrl_provider(struct device_node *np) static int _setup_clkctrl_provider(struct device_node *np)
{ {
const __be32 *addrp; const __be32 *addrp;
struct clkctrl_provider *provider; struct clkctrl_provider *provider;
u64 size;
provider = memblock_virt_alloc(sizeof(*provider), 0); provider = memblock_virt_alloc(sizeof(*provider), 0);
if (!provider) if (!provider)
return -ENOMEM; return -ENOMEM;
addrp = of_get_address(np, 0, NULL, NULL); addrp = of_get_address(np, 0, &size, NULL);
provider->addr = (u32)of_translate_address(np, addrp); provider->addr = (u32)of_translate_address(np, addrp);
provider->offset = provider->addr & 0xff; addrp = of_get_address(np->parent, 0, NULL, NULL);
provider->offset = provider->addr -
(u32)of_translate_address(np->parent, addrp);
provider->addr &= ~0xff; provider->addr &= ~0xff;
provider->size = size | 0xff;
provider->node = np; provider->node = np;
clkdm_for_each(_match_clkdm, provider); pr_debug("%s: %s: %x...%x [+%x]\n", __func__, np->parent->name,
provider->addr, provider->addr + provider->size,
if (!provider->clkdm) { provider->offset);
pr_err("%s: nothing matched for node %s (%x)\n",
__func__, np->parent->name, provider->addr);
memblock_free_early(__pa(provider), sizeof(*provider));
return -EINVAL;
}
list_add(&provider->link, &clkctrl_providers); list_add(&provider->link, &clkctrl_providers);
@ -775,32 +757,48 @@ static int _init_clkctrl_providers(void)
return ret; return ret;
} }
static u32 _omap4_xlate_clkctrl(struct omap_hwmod *oh, static u32 _omap4_xlate_clkctrl(struct omap_hwmod *oh)
struct clkctrl_provider *provider)
{ {
return oh->prcm.omap4.clkctrl_offs - if (!oh->prcm.omap4.modulemode)
provider->offset - provider->clkdm->clkdm_offs; return 0;
return omap_cm_xlate_clkctrl(oh->clkdm->prcm_partition,
oh->clkdm->cm_inst,
oh->prcm.omap4.clkctrl_offs);
} }
static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh) static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh)
{ {
struct clkctrl_provider *provider; struct clkctrl_provider *provider;
struct clk *clk; struct clk *clk;
u32 addr;
if (!soc_ops.xlate_clkctrl) if (!soc_ops.xlate_clkctrl)
return NULL; return NULL;
addr = soc_ops.xlate_clkctrl(oh);
if (!addr)
return NULL;
pr_debug("%s: %s: addr=%x\n", __func__, oh->name, addr);
list_for_each_entry(provider, &clkctrl_providers, link) { list_for_each_entry(provider, &clkctrl_providers, link) {
if (provider->clkdm == oh->clkdm) { if (provider->addr <= addr &&
provider->addr + provider->size >= addr) {
struct of_phandle_args clkspec; struct of_phandle_args clkspec;
clkspec.np = provider->node; clkspec.np = provider->node;
clkspec.args_count = 2; clkspec.args_count = 2;
clkspec.args[0] = soc_ops.xlate_clkctrl(oh, provider); clkspec.args[0] = addr - provider->addr -
provider->offset;
clkspec.args[1] = 0; clkspec.args[1] = 0;
clk = of_clk_get_from_provider(&clkspec); clk = of_clk_get_from_provider(&clkspec);
pr_debug("%s: %s got %p (offset=%x, provider=%s)\n",
__func__, oh->name, clk, clkspec.args[0],
provider->node->parent->name);
return clk; return clk;
} }
} }
@ -3521,6 +3519,7 @@ void __init omap_hwmod_init(void)
soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted; soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
soc_ops.init_clkdm = _init_clkdm; soc_ops.init_clkdm = _init_clkdm;
soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm; soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm;
soc_ops.xlate_clkctrl = _omap4_xlate_clkctrl;
} else { } else {
WARN(1, "omap_hwmod: unknown SoC type\n"); WARN(1, "omap_hwmod: unknown SoC type\n");
} }

View File

@ -988,7 +988,7 @@ static struct omap_hwmod_class dm81xx_sata_hwmod_class = {
static struct omap_hwmod dm81xx_sata_hwmod = { static struct omap_hwmod dm81xx_sata_hwmod = {
.name = "sata", .name = "sata",
.clkdm_name = "default_sata_clkdm", .clkdm_name = "default_clkdm",
.flags = HWMOD_NO_IDLEST, .flags = HWMOD_NO_IDLEST,
.prcm = { .prcm = {
.omap4 = { .omap4 = {