|
@@ -491,3 +491,152 @@ static struct clk hsb_clk = {
|
|
|
.get_rate = hsb_clk_get_rate,
|
|
|
};
|
|
|
static struct clk pba_clk = {
|
|
|
+ .name = "pba",
|
|
|
+ .parent = &hsb_clk,
|
|
|
+ .mode = hsb_clk_mode,
|
|
|
+ .get_rate = pba_clk_get_rate,
|
|
|
+ .index = 1,
|
|
|
+};
|
|
|
+static struct clk pbb_clk = {
|
|
|
+ .name = "pbb",
|
|
|
+ .parent = &hsb_clk,
|
|
|
+ .mode = hsb_clk_mode,
|
|
|
+ .get_rate = pbb_clk_get_rate,
|
|
|
+ .users = 1,
|
|
|
+ .index = 2,
|
|
|
+};
|
|
|
+
|
|
|
+/* --------------------------------------------------------------------
|
|
|
+ * Generic Clock operations
|
|
|
+ * -------------------------------------------------------------------- */
|
|
|
+
|
|
|
+static void genclk_mode(struct clk *clk, int enabled)
|
|
|
+{
|
|
|
+ u32 control;
|
|
|
+
|
|
|
+ control = pm_readl(GCCTRL(clk->index));
|
|
|
+ if (enabled)
|
|
|
+ control |= PM_BIT(CEN);
|
|
|
+ else
|
|
|
+ control &= ~PM_BIT(CEN);
|
|
|
+ pm_writel(GCCTRL(clk->index), control);
|
|
|
+}
|
|
|
+
|
|
|
+static unsigned long genclk_get_rate(struct clk *clk)
|
|
|
+{
|
|
|
+ u32 control;
|
|
|
+ unsigned long div = 1;
|
|
|
+
|
|
|
+ control = pm_readl(GCCTRL(clk->index));
|
|
|
+ if (control & PM_BIT(DIVEN))
|
|
|
+ div = 2 * (PM_BFEXT(DIV, control) + 1);
|
|
|
+
|
|
|
+ return clk->parent->get_rate(clk->parent) / div;
|
|
|
+}
|
|
|
+
|
|
|
+static long genclk_set_rate(struct clk *clk, unsigned long rate, int apply)
|
|
|
+{
|
|
|
+ u32 control;
|
|
|
+ unsigned long parent_rate, actual_rate, div;
|
|
|
+
|
|
|
+ parent_rate = clk->parent->get_rate(clk->parent);
|
|
|
+ control = pm_readl(GCCTRL(clk->index));
|
|
|
+
|
|
|
+ if (rate > 3 * parent_rate / 4) {
|
|
|
+ actual_rate = parent_rate;
|
|
|
+ control &= ~PM_BIT(DIVEN);
|
|
|
+ } else {
|
|
|
+ div = (parent_rate + rate) / (2 * rate) - 1;
|
|
|
+ control = PM_BFINS(DIV, div, control) | PM_BIT(DIVEN);
|
|
|
+ actual_rate = parent_rate / (2 * (div + 1));
|
|
|
+ }
|
|
|
+
|
|
|
+ dev_dbg(clk->dev, "clk %s: new rate %lu (actual rate %lu)\n",
|
|
|
+ clk->name, rate, actual_rate);
|
|
|
+
|
|
|
+ if (apply)
|
|
|
+ pm_writel(GCCTRL(clk->index), control);
|
|
|
+
|
|
|
+ return actual_rate;
|
|
|
+}
|
|
|
+
|
|
|
+int genclk_set_parent(struct clk *clk, struct clk *parent)
|
|
|
+{
|
|
|
+ u32 control;
|
|
|
+
|
|
|
+ dev_dbg(clk->dev, "clk %s: new parent %s (was %s)\n",
|
|
|
+ clk->name, parent->name, clk->parent->name);
|
|
|
+
|
|
|
+ control = pm_readl(GCCTRL(clk->index));
|
|
|
+
|
|
|
+ if (parent == &osc1 || parent == &pll1)
|
|
|
+ control |= PM_BIT(OSCSEL);
|
|
|
+ else if (parent == &osc0 || parent == &pll0)
|
|
|
+ control &= ~PM_BIT(OSCSEL);
|
|
|
+ else
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ if (parent == &pll0 || parent == &pll1)
|
|
|
+ control |= PM_BIT(PLLSEL);
|
|
|
+ else
|
|
|
+ control &= ~PM_BIT(PLLSEL);
|
|
|
+
|
|
|
+ pm_writel(GCCTRL(clk->index), control);
|
|
|
+ clk->parent = parent;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void __init genclk_init_parent(struct clk *clk)
|
|
|
+{
|
|
|
+ u32 control;
|
|
|
+ struct clk *parent;
|
|
|
+
|
|
|
+ BUG_ON(clk->index > 7);
|
|
|
+
|
|
|
+ control = pm_readl(GCCTRL(clk->index));
|
|
|
+ if (control & PM_BIT(OSCSEL))
|
|
|
+ parent = (control & PM_BIT(PLLSEL)) ? &pll1 : &osc1;
|
|
|
+ else
|
|
|
+ parent = (control & PM_BIT(PLLSEL)) ? &pll0 : &osc0;
|
|
|
+
|
|
|
+ clk->parent = parent;
|
|
|
+}
|
|
|
+
|
|
|
+static struct dw_dma_platform_data dw_dmac0_data = {
|
|
|
+ .nr_channels = 3,
|
|
|
+ .block_size = 4095U,
|
|
|
+ .nr_masters = 2,
|
|
|
+ .data_width = { 2, 2, 0, 0 },
|
|
|
+};
|
|
|
+
|
|
|
+static struct resource dw_dmac0_resource[] = {
|
|
|
+ PBMEM(0xff200000),
|
|
|
+ IRQ(2),
|
|
|
+};
|
|
|
+DEFINE_DEV_DATA(dw_dmac, 0);
|
|
|
+DEV_CLK(hclk, dw_dmac0, hsb, 10);
|
|
|
+
|
|
|
+/* --------------------------------------------------------------------
|
|
|
+ * System peripherals
|
|
|
+ * -------------------------------------------------------------------- */
|
|
|
+static struct resource at32_pm0_resource[] = {
|
|
|
+ {
|
|
|
+ .start = 0xfff00000,
|
|
|
+ .end = 0xfff0007f,
|
|
|
+ .flags = IORESOURCE_MEM,
|
|
|
+ },
|
|
|
+ IRQ(20),
|
|
|
+};
|
|
|
+
|
|
|
+static struct resource at32ap700x_rtc0_resource[] = {
|
|
|
+ {
|
|
|
+ .start = 0xfff00080,
|
|
|
+ .end = 0xfff000af,
|
|
|
+ .flags = IORESOURCE_MEM,
|
|
|
+ },
|
|
|
+ IRQ(21),
|
|
|
+};
|
|
|
+
|
|
|
+static struct resource at32_wdt0_resource[] = {
|
|
|
+ {
|