ARM: OMAP2+: clock: add low-level support for regmap
Some of the TI clock providers will be converted to use syscon, thus low-level regmap support is needed for the clock drivers also. This patch adds this support, which can be enabled for individual drivers in later patches. Signed-off-by: Tero Kristo <t-kristo@ti.com>
This commit is contained in:
parent
219595b6ee
commit
80cbb224b7
@ -23,7 +23,9 @@
|
|||||||
#include <linux/clk-provider.h>
|
#include <linux/clk-provider.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/regmap.h>
|
||||||
#include <linux/of_address.h>
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/bootmem.h>
|
||||||
#include <asm/cpu.h>
|
#include <asm/cpu.h>
|
||||||
|
|
||||||
#include <trace/events/power.h>
|
#include <trace/events/power.h>
|
||||||
@ -73,20 +75,37 @@ struct ti_clk_features ti_clk_features;
|
|||||||
static bool clkdm_control = true;
|
static bool clkdm_control = true;
|
||||||
|
|
||||||
static LIST_HEAD(clk_hw_omap_clocks);
|
static LIST_HEAD(clk_hw_omap_clocks);
|
||||||
static void __iomem *clk_memmaps[CLK_MAX_MEMMAPS];
|
|
||||||
|
struct clk_iomap {
|
||||||
|
struct regmap *regmap;
|
||||||
|
void __iomem *mem;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_iomap *clk_memmaps[CLK_MAX_MEMMAPS];
|
||||||
|
|
||||||
static void clk_memmap_writel(u32 val, void __iomem *reg)
|
static void clk_memmap_writel(u32 val, void __iomem *reg)
|
||||||
{
|
{
|
||||||
struct clk_omap_reg *r = (struct clk_omap_reg *)®
|
struct clk_omap_reg *r = (struct clk_omap_reg *)®
|
||||||
|
struct clk_iomap *io = clk_memmaps[r->index];
|
||||||
|
|
||||||
writel_relaxed(val, clk_memmaps[r->index] + r->offset);
|
if (io->regmap)
|
||||||
|
regmap_write(io->regmap, r->offset, val);
|
||||||
|
else
|
||||||
|
writel_relaxed(val, io->mem + r->offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u32 clk_memmap_readl(void __iomem *reg)
|
static u32 clk_memmap_readl(void __iomem *reg)
|
||||||
{
|
{
|
||||||
|
u32 val;
|
||||||
struct clk_omap_reg *r = (struct clk_omap_reg *)®
|
struct clk_omap_reg *r = (struct clk_omap_reg *)®
|
||||||
|
struct clk_iomap *io = clk_memmaps[r->index];
|
||||||
|
|
||||||
return readl_relaxed(clk_memmaps[r->index] + r->offset);
|
if (io->regmap)
|
||||||
|
regmap_read(io->regmap, r->offset, &val);
|
||||||
|
else
|
||||||
|
val = readl_relaxed(io->mem + r->offset);
|
||||||
|
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg)
|
void omap2_clk_writel(u32 val, struct clk_hw_omap *clk, void __iomem *reg)
|
||||||
@ -115,18 +134,27 @@ static struct ti_clk_ll_ops omap_clk_ll_ops = {
|
|||||||
* @match_table: DT device table to match for devices to init
|
* @match_table: DT device table to match for devices to init
|
||||||
* @np: device node pointer for the this clock provider
|
* @np: device node pointer for the this clock provider
|
||||||
* @index: index for the clock provider
|
* @index: index for the clock provider
|
||||||
* @mem: iomem pointer for the clock provider memory area
|
+ @syscon: syscon regmap pointer
|
||||||
|
* @mem: iomem pointer for the clock provider memory area, only used if
|
||||||
|
* syscon is not provided
|
||||||
*
|
*
|
||||||
* Initializes a clock provider module (CM/PRM etc.), registering
|
* Initializes a clock provider module (CM/PRM etc.), registering
|
||||||
* the memory mapping at specified index and initializing the
|
* the memory mapping at specified index and initializing the
|
||||||
* low level driver infrastructure. Returns 0 in success.
|
* low level driver infrastructure. Returns 0 in success.
|
||||||
*/
|
*/
|
||||||
int __init omap2_clk_provider_init(struct device_node *np, int index,
|
int __init omap2_clk_provider_init(struct device_node *np, int index,
|
||||||
void __iomem *mem)
|
struct regmap *syscon, void __iomem *mem)
|
||||||
{
|
{
|
||||||
|
struct clk_iomap *io;
|
||||||
|
|
||||||
ti_clk_ll_ops = &omap_clk_ll_ops;
|
ti_clk_ll_ops = &omap_clk_ll_ops;
|
||||||
|
|
||||||
clk_memmaps[index] = mem;
|
io = kzalloc(sizeof(*io), GFP_KERNEL);
|
||||||
|
|
||||||
|
io->regmap = syscon;
|
||||||
|
io->mem = mem;
|
||||||
|
|
||||||
|
clk_memmaps[index] = io;
|
||||||
|
|
||||||
ti_dt_clk_init_provider(np, index);
|
ti_dt_clk_init_provider(np, index);
|
||||||
|
|
||||||
@ -142,9 +170,15 @@ int __init omap2_clk_provider_init(struct device_node *np, int index,
|
|||||||
*/
|
*/
|
||||||
void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
|
void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem)
|
||||||
{
|
{
|
||||||
|
struct clk_iomap *io;
|
||||||
|
|
||||||
ti_clk_ll_ops = &omap_clk_ll_ops;
|
ti_clk_ll_ops = &omap_clk_ll_ops;
|
||||||
|
|
||||||
clk_memmaps[index] = mem;
|
io = memblock_virt_alloc(sizeof(*io), 0);
|
||||||
|
|
||||||
|
io->mem = mem;
|
||||||
|
|
||||||
|
clk_memmaps[index] = io;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -274,8 +274,10 @@ extern const struct clksel_rate div31_1to31_rates[];
|
|||||||
extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
|
extern int omap2_clkops_enable_clkdm(struct clk_hw *hw);
|
||||||
extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);
|
extern void omap2_clkops_disable_clkdm(struct clk_hw *hw);
|
||||||
|
|
||||||
|
struct regmap;
|
||||||
|
|
||||||
int __init omap2_clk_provider_init(struct device_node *np, int index,
|
int __init omap2_clk_provider_init(struct device_node *np, int index,
|
||||||
void __iomem *mem);
|
struct regmap *syscon, void __iomem *mem);
|
||||||
void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem);
|
void __init omap2_clk_legacy_provider_init(int index, void __iomem *mem);
|
||||||
|
|
||||||
void __init ti_clk_init_features(void);
|
void __init ti_clk_init_features(void);
|
||||||
|
@ -361,7 +361,7 @@ int __init omap_cm_init(void)
|
|||||||
if (data->flags & CM_NO_CLOCKS)
|
if (data->flags & CM_NO_CLOCKS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = omap2_clk_provider_init(np, data->index, data->mem);
|
ret = omap2_clk_provider_init(np, data->index, NULL, data->mem);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -676,7 +676,7 @@ int __init omap_control_init(void)
|
|||||||
for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
|
for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
|
||||||
data = match->data;
|
data = match->data;
|
||||||
|
|
||||||
ret = omap2_clk_provider_init(np, data->index, data->mem);
|
ret = omap2_clk_provider_init(np, data->index, NULL, data->mem);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -798,7 +798,7 @@ int __init omap_prcm_init(void)
|
|||||||
for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) {
|
for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) {
|
||||||
data = match->data;
|
data = match->data;
|
||||||
|
|
||||||
ret = omap2_clk_provider_init(np, data->index, data->mem);
|
ret = omap2_clk_provider_init(np, data->index, NULL, data->mem);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user