|
@@ -47,6 +47,7 @@
|
|
|
#define PLLC01CR 0xe6150028
|
|
|
|
|
|
#define SUBCKCR 0xe6150080
|
|
|
+#define USBCKCR 0xe615008c
|
|
|
|
|
|
#define MSTPSR0 0xe6150030
|
|
|
#define MSTPSR1 0xe6150038
|
|
@@ -181,6 +182,95 @@ static struct clk pllc1_div2_clk = {
|
|
|
.parent = &pllc1_clk,
|
|
|
};
|
|
|
|
|
|
+/* USB clock */
|
|
|
+static struct clk *usb24s_parents[] = {
|
|
|
+ [0] = &system_clk,
|
|
|
+ [1] = &extal2_clk
|
|
|
+};
|
|
|
+
|
|
|
+static int usb24s_enable(struct clk *clk)
|
|
|
+{
|
|
|
+ __raw_writel(__raw_readl(USBCKCR) & ~(1 << 8), USBCKCR);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void usb24s_disable(struct clk *clk)
|
|
|
+{
|
|
|
+ __raw_writel(__raw_readl(USBCKCR) | (1 << 8), USBCKCR);
|
|
|
+}
|
|
|
+
|
|
|
+static int usb24s_set_parent(struct clk *clk, struct clk *parent)
|
|
|
+{
|
|
|
+ int i, ret;
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ if (!clk->parent_table || !clk->parent_num)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ /* Search the parent */
|
|
|
+ for (i = 0; i < clk->parent_num; i++)
|
|
|
+ if (clk->parent_table[i] == parent)
|
|
|
+ break;
|
|
|
+
|
|
|
+ if (i == clk->parent_num)
|
|
|
+ return -ENODEV;
|
|
|
+
|
|
|
+ ret = clk_reparent(clk, parent);
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
+
|
|
|
+ val = __raw_readl(USBCKCR);
|
|
|
+ val &= ~(1 << 7);
|
|
|
+ val |= i << 7;
|
|
|
+ __raw_writel(val, USBCKCR);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct sh_clk_ops usb24s_clk_ops = {
|
|
|
+ .recalc = followparent_recalc,
|
|
|
+ .enable = usb24s_enable,
|
|
|
+ .disable = usb24s_disable,
|
|
|
+ .set_parent = usb24s_set_parent,
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk usb24s_clk = {
|
|
|
+ .ops = &usb24s_clk_ops,
|
|
|
+ .parent_table = usb24s_parents,
|
|
|
+ .parent_num = ARRAY_SIZE(usb24s_parents),
|
|
|
+ .parent = &system_clk,
|
|
|
+};
|
|
|
+
|
|
|
+static unsigned long usb24_recalc(struct clk *clk)
|
|
|
+{
|
|
|
+ return clk->parent->rate /
|
|
|
+ ((__raw_readl(USBCKCR) & (1 << 6)) ? 1 : 2);
|
|
|
+};
|
|
|
+
|
|
|
+static int usb24_set_rate(struct clk *clk, unsigned long rate)
|
|
|
+{
|
|
|
+ u32 val;
|
|
|
+
|
|
|
+ /* closer to which ? parent->rate or parent->rate/2 */
|
|
|
+ val = __raw_readl(USBCKCR);
|
|
|
+ val &= ~(1 << 6);
|
|
|
+ val |= (rate > (clk->parent->rate / 4) * 3) << 6;
|
|
|
+ __raw_writel(val, USBCKCR);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct sh_clk_ops usb24_clk_ops = {
|
|
|
+ .recalc = usb24_recalc,
|
|
|
+ .set_rate = usb24_set_rate,
|
|
|
+};
|
|
|
+
|
|
|
+static struct clk usb24_clk = {
|
|
|
+ .ops = &usb24_clk_ops,
|
|
|
+ .parent = &usb24s_clk,
|
|
|
+};
|
|
|
+
|
|
|
struct clk *main_clks[] = {
|
|
|
&extalr_clk,
|
|
|
&extal1_clk,
|
|
@@ -196,6 +286,8 @@ struct clk *main_clks[] = {
|
|
|
&pllc0_clk,
|
|
|
&pllc1_clk,
|
|
|
&pllc1_div2_clk,
|
|
|
+ &usb24s_clk,
|
|
|
+ &usb24_clk,
|
|
|
};
|
|
|
|
|
|
static void div4_kick(struct clk *clk)
|
|
@@ -223,7 +315,7 @@ static struct clk_div4_table div4_table = {
|
|
|
|
|
|
enum {
|
|
|
DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
|
|
|
- DIV4_HPP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
|
|
|
+ DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
|
|
|
DIV4_NR
|
|
|
};
|
|
|
|
|
@@ -234,6 +326,7 @@ struct clk div4_clks[DIV4_NR] = {
|
|
|
[DIV4_M1] = SH_CLK_DIV4(&pllc1_clk, FRQCRA, 4, 0x6fff, CLK_ENABLE_ON_INIT),
|
|
|
[DIV4_HP] = SH_CLK_DIV4(&pllc1_clk, FRQCRB, 4, 0x6fff, 0),
|
|
|
[DIV4_HPP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 20, 0x6fff, 0),
|
|
|
+ [DIV4_USBP] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 16, 0x6fff, 0),
|
|
|
[DIV4_S] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 12, 0x6fff, 0),
|
|
|
[DIV4_ZB] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 8, 0x6fff, 0),
|
|
|
[DIV4_M3] = SH_CLK_DIV4(&pllc1_clk, FRQCRC, 4, 0x6fff, 0),
|
|
@@ -257,7 +350,10 @@ enum {
|
|
|
MSTP222,
|
|
|
MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
|
|
|
|
|
|
- MSTP329, MSTP323,
|
|
|
+ MSTP329, MSTP328, MSTP323, MSTP320,
|
|
|
+ MSTP314, MSTP313, MSTP312,
|
|
|
+
|
|
|
+ MSTP416, MSTP415, MSTP407, MSTP406,
|
|
|
|
|
|
MSTP_NR
|
|
|
};
|
|
@@ -280,7 +376,17 @@ static struct clk mstp_clks[MSTP_NR] = {
|
|
|
[MSTP200] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
|
|
|
|
|
|
[MSTP329] = SH_CLK_MSTP32(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
|
|
|
+ [MSTP328] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /* FSI */
|
|
|
[MSTP323] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
|
|
|
+ [MSTP320] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 20, 0), /* USBF */
|
|
|
+ [MSTP314] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
|
|
|
+ [MSTP313] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
|
|
|
+ [MSTP312] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
|
|
|
+
|
|
|
+ [MSTP416] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 16, 0), /* USBHOST */
|
|
|
+ [MSTP415] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 15, 0), /* SDHI2 */
|
|
|
+ [MSTP407] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 7, 0), /* USB-Func */
|
|
|
+ [MSTP406] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR4, 6, 0), /* USB Phy */
|
|
|
};
|
|
|
|
|
|
static struct clk_lookup lookups[] = {
|
|
@@ -299,6 +405,7 @@ static struct clk_lookup lookups[] = {
|
|
|
CLKDEV_CON_ID("pllc0_clk", &pllc0_clk),
|
|
|
CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
|
|
|
CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
|
|
|
+ CLKDEV_CON_ID("usb24s", &usb24s_clk),
|
|
|
|
|
|
/* DIV4 clocks */
|
|
|
CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
|
|
@@ -334,7 +441,21 @@ static struct clk_lookup lookups[] = {
|
|
|
CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
|
|
|
|
|
|
CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]),
|
|
|
+ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]),
|
|
|
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]),
|
|
|
+ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP320]),
|
|
|
+ CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
|
|
|
+ CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
|
|
|
+ CLKDEV_DEV_ID("sh_mmcif", &mstp_clks[MSTP312]),
|
|
|
+
|
|
|
+ CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP415]),
|
|
|
+
|
|
|
+ /* ICK */
|
|
|
+ CLKDEV_ICK_ID("host", "renesas_usbhs", &mstp_clks[MSTP416]),
|
|
|
+ CLKDEV_ICK_ID("func", "renesas_usbhs", &mstp_clks[MSTP407]),
|
|
|
+ CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]),
|
|
|
+ CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]),
|
|
|
+ CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk),
|
|
|
};
|
|
|
|
|
|
void __init r8a7740_clock_init(u8 md_ck)
|