|
@@ -452,3 +452,135 @@ void omap1_clk_disable(struct clk *clk)
|
|
|
static int omap1_clk_enable_generic(struct clk *clk)
|
|
|
{
|
|
|
__u16 regval16;
|
|
|
+ __u32 regval32;
|
|
|
+
|
|
|
+ if (unlikely(clk->enable_reg == NULL)) {
|
|
|
+ printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
|
|
|
+ clk->name);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (clk->flags & ENABLE_REG_32BIT) {
|
|
|
+ regval32 = __raw_readl(clk->enable_reg);
|
|
|
+ regval32 |= (1 << clk->enable_bit);
|
|
|
+ __raw_writel(regval32, clk->enable_reg);
|
|
|
+ } else {
|
|
|
+ regval16 = __raw_readw(clk->enable_reg);
|
|
|
+ regval16 |= (1 << clk->enable_bit);
|
|
|
+ __raw_writew(regval16, clk->enable_reg);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void omap1_clk_disable_generic(struct clk *clk)
|
|
|
+{
|
|
|
+ __u16 regval16;
|
|
|
+ __u32 regval32;
|
|
|
+
|
|
|
+ if (clk->enable_reg == NULL)
|
|
|
+ return;
|
|
|
+
|
|
|
+ if (clk->flags & ENABLE_REG_32BIT) {
|
|
|
+ regval32 = __raw_readl(clk->enable_reg);
|
|
|
+ regval32 &= ~(1 << clk->enable_bit);
|
|
|
+ __raw_writel(regval32, clk->enable_reg);
|
|
|
+ } else {
|
|
|
+ regval16 = __raw_readw(clk->enable_reg);
|
|
|
+ regval16 &= ~(1 << clk->enable_bit);
|
|
|
+ __raw_writew(regval16, clk->enable_reg);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const struct clkops clkops_generic = {
|
|
|
+ .enable = omap1_clk_enable_generic,
|
|
|
+ .disable = omap1_clk_disable_generic,
|
|
|
+};
|
|
|
+
|
|
|
+static int omap1_clk_enable_dsp_domain(struct clk *clk)
|
|
|
+{
|
|
|
+ int retval;
|
|
|
+
|
|
|
+ retval = omap1_clk_enable(api_ck_p);
|
|
|
+ if (!retval) {
|
|
|
+ retval = omap1_clk_enable_generic(clk);
|
|
|
+ omap1_clk_disable(api_ck_p);
|
|
|
+ }
|
|
|
+
|
|
|
+ return retval;
|
|
|
+}
|
|
|
+
|
|
|
+static void omap1_clk_disable_dsp_domain(struct clk *clk)
|
|
|
+{
|
|
|
+ if (omap1_clk_enable(api_ck_p) == 0) {
|
|
|
+ omap1_clk_disable_generic(clk);
|
|
|
+ omap1_clk_disable(api_ck_p);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const struct clkops clkops_dspck = {
|
|
|
+ .enable = omap1_clk_enable_dsp_domain,
|
|
|
+ .disable = omap1_clk_disable_dsp_domain,
|
|
|
+};
|
|
|
+
|
|
|
+/* XXX SYSC register handling does not belong in the clock framework */
|
|
|
+static int omap1_clk_enable_uart_functional_16xx(struct clk *clk)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+ struct uart_clk *uclk;
|
|
|
+
|
|
|
+ ret = omap1_clk_enable_generic(clk);
|
|
|
+ if (ret == 0) {
|
|
|
+ /* Set smart idle acknowledgement mode */
|
|
|
+ uclk = (struct uart_clk *)clk;
|
|
|
+ omap_writeb((omap_readb(uclk->sysc_addr) & ~0x10) | 8,
|
|
|
+ uclk->sysc_addr);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/* XXX SYSC register handling does not belong in the clock framework */
|
|
|
+static void omap1_clk_disable_uart_functional_16xx(struct clk *clk)
|
|
|
+{
|
|
|
+ struct uart_clk *uclk;
|
|
|
+
|
|
|
+ /* Set force idle acknowledgement mode */
|
|
|
+ uclk = (struct uart_clk *)clk;
|
|
|
+ omap_writeb((omap_readb(uclk->sysc_addr) & ~0x18), uclk->sysc_addr);
|
|
|
+
|
|
|
+ omap1_clk_disable_generic(clk);
|
|
|
+}
|
|
|
+
|
|
|
+/* XXX SYSC register handling does not belong in the clock framework */
|
|
|
+const struct clkops clkops_uart_16xx = {
|
|
|
+ .enable = omap1_clk_enable_uart_functional_16xx,
|
|
|
+ .disable = omap1_clk_disable_uart_functional_16xx,
|
|
|
+};
|
|
|
+
|
|
|
+long omap1_clk_round_rate(struct clk *clk, unsigned long rate)
|
|
|
+{
|
|
|
+ if (clk->round_rate != NULL)
|
|
|
+ return clk->round_rate(clk, rate);
|
|
|
+
|
|
|
+ return clk->rate;
|
|
|
+}
|
|
|
+
|
|
|
+int omap1_clk_set_rate(struct clk *clk, unsigned long rate)
|
|
|
+{
|
|
|
+ int ret = -EINVAL;
|
|
|
+
|
|
|
+ if (clk->set_rate)
|
|
|
+ ret = clk->set_rate(clk, rate);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * Omap1 clock reset and init functions
|
|
|
+ */
|
|
|
+
|
|
|
+#ifdef CONFIG_OMAP_RESET_CLOCKS
|
|
|
+
|
|
|
+void omap1_clk_disable_unused(struct clk *clk)
|
|
|
+{
|
|
|
+ __u32 regval32;
|