ARM: mach-shmobile: clock-sh73a0: add DSIxPHY clock support
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
parent
446e326c15
commit
f5948bac5f
|
@ -314,12 +314,11 @@ static struct resource mipidsi0_resources[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#define DSI0PHYCR 0xe615006c
|
|
||||||
static int sh_mipi_set_dot_clock(struct platform_device *pdev,
|
static int sh_mipi_set_dot_clock(struct platform_device *pdev,
|
||||||
void __iomem *base,
|
void __iomem *base,
|
||||||
int enable)
|
int enable)
|
||||||
{
|
{
|
||||||
struct clk *pck;
|
struct clk *pck, *phy;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
pck = clk_get(&pdev->dev, "dsip_clk");
|
pck = clk_get(&pdev->dev, "dsip_clk");
|
||||||
|
@ -328,18 +327,27 @@ static int sh_mipi_set_dot_clock(struct platform_device *pdev,
|
||||||
goto sh_mipi_set_dot_clock_pck_err;
|
goto sh_mipi_set_dot_clock_pck_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
phy = clk_get(&pdev->dev, "dsiphy_clk");
|
||||||
|
if (IS_ERR(phy)) {
|
||||||
|
ret = PTR_ERR(phy);
|
||||||
|
goto sh_mipi_set_dot_clock_phy_err;
|
||||||
|
}
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
clk_set_rate(pck, clk_round_rate(pck, 24000000));
|
clk_set_rate(pck, clk_round_rate(pck, 24000000));
|
||||||
__raw_writel(0x2a809010, DSI0PHYCR);
|
clk_set_rate(phy, clk_round_rate(pck, 510000000));
|
||||||
clk_enable(pck);
|
clk_enable(pck);
|
||||||
|
clk_enable(phy);
|
||||||
} else {
|
} else {
|
||||||
clk_disable(pck);
|
clk_disable(pck);
|
||||||
|
clk_disable(phy);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
||||||
|
clk_put(phy);
|
||||||
|
sh_mipi_set_dot_clock_phy_err:
|
||||||
clk_put(pck);
|
clk_put(pck);
|
||||||
|
|
||||||
sh_mipi_set_dot_clock_pck_err:
|
sh_mipi_set_dot_clock_pck_err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,6 +365,114 @@ static struct clk div6_clks[DIV6_NR] = {
|
||||||
dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
|
dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* DSI DIV */
|
||||||
|
static unsigned long dsiphy_recalc(struct clk *clk)
|
||||||
|
{
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
value = __raw_readl(clk->mapping->base);
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
if (!(value & 0x000B8000))
|
||||||
|
return clk->parent->rate;
|
||||||
|
|
||||||
|
value &= 0x3f;
|
||||||
|
value += 1;
|
||||||
|
|
||||||
|
if ((value < 12) ||
|
||||||
|
(value > 33)) {
|
||||||
|
pr_err("DSIPHY has wrong value (%d)", value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clk->parent->rate / value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
|
||||||
|
{
|
||||||
|
return clk_rate_mult_range_round(clk, 12, 33, rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dsiphy_disable(struct clk *clk)
|
||||||
|
{
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
value = __raw_readl(clk->mapping->base);
|
||||||
|
value &= ~0x000B8000;
|
||||||
|
|
||||||
|
__raw_writel(value , clk->mapping->base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsiphy_enable(struct clk *clk)
|
||||||
|
{
|
||||||
|
u32 value;
|
||||||
|
int multi;
|
||||||
|
|
||||||
|
value = __raw_readl(clk->mapping->base);
|
||||||
|
multi = (value & 0x3f) + 1;
|
||||||
|
|
||||||
|
if ((multi < 12) || (multi > 33))
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
__raw_writel(value | 0x000B8000, clk->mapping->base);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
|
||||||
|
{
|
||||||
|
u32 value;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
idx = rate / clk->parent->rate;
|
||||||
|
if ((idx < 12) || (idx > 33))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
idx += -1;
|
||||||
|
|
||||||
|
value = __raw_readl(clk->mapping->base);
|
||||||
|
value = (value & ~0x3f) + idx;
|
||||||
|
|
||||||
|
__raw_writel(value, clk->mapping->base);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct clk_ops dsiphy_clk_ops = {
|
||||||
|
.recalc = dsiphy_recalc,
|
||||||
|
.round_rate = dsiphy_round_rate,
|
||||||
|
.set_rate = dsiphy_set_rate,
|
||||||
|
.enable = dsiphy_enable,
|
||||||
|
.disable = dsiphy_disable,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_mapping dsi0phy_clk_mapping = {
|
||||||
|
.phys = DSI0PHYCR,
|
||||||
|
.len = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk_mapping dsi1phy_clk_mapping = {
|
||||||
|
.phys = DSI1PHYCR,
|
||||||
|
.len = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk dsi0phy_clk = {
|
||||||
|
.ops = &dsiphy_clk_ops,
|
||||||
|
.parent = &div6_clks[DIV6_DSI0P], /* late install */
|
||||||
|
.mapping = &dsi0phy_clk_mapping,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk dsi1phy_clk = {
|
||||||
|
.ops = &dsiphy_clk_ops,
|
||||||
|
.parent = &div6_clks[DIV6_DSI1P], /* late install */
|
||||||
|
.mapping = &dsi1phy_clk_mapping,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct clk *late_main_clks[] = {
|
||||||
|
&dsi0phy_clk,
|
||||||
|
&dsi1phy_clk,
|
||||||
|
};
|
||||||
|
|
||||||
enum { MSTP001,
|
enum { MSTP001,
|
||||||
MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
|
MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
|
||||||
MSTP219,
|
MSTP219,
|
||||||
|
@ -429,6 +537,8 @@ static struct clk_lookup lookups[] = {
|
||||||
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
|
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
|
||||||
CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
|
CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
|
||||||
CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
|
CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
|
||||||
|
CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
|
||||||
|
CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
|
||||||
|
|
||||||
/* MSTP32 clocks */
|
/* MSTP32 clocks */
|
||||||
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
|
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
|
||||||
|
@ -504,6 +614,9 @@ void __init sh73a0_clock_init(void)
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
|
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
|
||||||
|
|
||||||
|
for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
|
||||||
|
ret = clk_register(late_main_clks[k]);
|
||||||
|
|
||||||
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
|
Loading…
Reference in New Issue