]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ARM: davinci: psc: introduce reset API
authorRobert Tivy <rtivy@ti.com>
Fri, 11 Jan 2013 00:23:23 +0000 (16:23 -0800)
committerSekhar Nori <nsekhar@ti.com>
Tue, 22 Jan 2013 12:12:59 +0000 (17:42 +0530)
Introduce an IP reset API for use on DaVinci SoC.

There is no existing "reset" framework support for SoC devices.
The remoteproc driver needs explicit control of the DSP's reset line.
To support this, a new DaVinci specific API is added.

This private API will disappear with DT migration.  Some discussion
regarding a proposed DT "reset" binding is here:
https://patchwork.kernel.org/patch/1635051/

Modify davinci_clk_init() to set clk "reset" function for clocks
that indicate PSC_LRST support.  Also fix indentation issue with
function opening curly brace.

Signed-off-by: Robert Tivy <rtivy@ti.com>
[nsekhar@ti.com: rename davinci_psc_config_reset() to davinci_psc_reset()]
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
arch/arm/mach-davinci/clock.c
arch/arm/mach-davinci/clock.h
arch/arm/mach-davinci/include/mach/clock.h
arch/arm/mach-davinci/include/mach/psc.h
arch/arm/mach-davinci/psc.c

index 34668ead53c73b1c70ee0b09261ba74ff8a3627b..d458558ee84a436a0506835c3ca9bdfa722798de 100644 (file)
@@ -52,6 +52,40 @@ static void __clk_disable(struct clk *clk)
                __clk_disable(clk->parent);
 }
 
+int davinci_clk_reset(struct clk *clk, bool reset)
+{
+       unsigned long flags;
+
+       if (clk == NULL || IS_ERR(clk))
+               return -EINVAL;
+
+       spin_lock_irqsave(&clockfw_lock, flags);
+       if (clk->flags & CLK_PSC)
+               davinci_psc_reset(clk->gpsc, clk->lpsc, reset);
+       spin_unlock_irqrestore(&clockfw_lock, flags);
+
+       return 0;
+}
+EXPORT_SYMBOL(davinci_clk_reset);
+
+int davinci_clk_reset_assert(struct clk *clk)
+{
+       if (clk == NULL || IS_ERR(clk) || !clk->reset)
+               return -EINVAL;
+
+       return clk->reset(clk, true);
+}
+EXPORT_SYMBOL(davinci_clk_reset_assert);
+
+int davinci_clk_reset_deassert(struct clk *clk)
+{
+       if (clk == NULL || IS_ERR(clk) || !clk->reset)
+               return -EINVAL;
+
+       return clk->reset(clk, false);
+}
+EXPORT_SYMBOL(davinci_clk_reset_deassert);
+
 int clk_enable(struct clk *clk)
 {
        unsigned long flags;
@@ -535,7 +569,7 @@ int davinci_set_refclk_rate(unsigned long rate)
 }
 
 int __init davinci_clk_init(struct clk_lookup *clocks)
-  {
+{
        struct clk_lookup *c;
        struct clk *clk;
        size_t num_clocks = 0;
@@ -576,6 +610,9 @@ int __init davinci_clk_init(struct clk_lookup *clocks)
                if (clk->lpsc)
                        clk->flags |= CLK_PSC;
 
+               if (clk->flags & PSC_LRST)
+                       clk->reset = davinci_clk_reset;
+
                clk_register(clk);
                num_clocks++;
 
index 46f0f1bf1a4ce9b71fd9cc88af7dcc1a3a8e2fe9..8694b395fc92602a60355bb35bd414f0137b041c 100644 (file)
@@ -103,6 +103,7 @@ struct clk {
        unsigned long (*recalc) (struct clk *);
        int (*set_rate) (struct clk *clk, unsigned long rate);
        int (*round_rate) (struct clk *clk, unsigned long rate);
+       int (*reset) (struct clk *clk, bool reset);
 };
 
 /* Clock flags: SoC-specific flags start at BIT(16) */
@@ -112,6 +113,7 @@ struct clk {
 #define PRE_PLL                        BIT(4) /* source is before PLL mult/div */
 #define PSC_SWRSTDISABLE       BIT(5) /* Disable state is SwRstDisable */
 #define PSC_FORCE              BIT(6) /* Force module state transtition */
+#define PSC_LRST               BIT(8) /* Use local reset on enable/disable */
 
 #define CLK(dev, con, ck)      \
        {                       \
@@ -126,6 +128,7 @@ int davinci_set_pllrate(struct pll_data *pll, unsigned int prediv,
 int davinci_set_sysclk_rate(struct clk *clk, unsigned long rate);
 int davinci_set_refclk_rate(unsigned long rate);
 int davinci_simple_set_rate(struct clk *clk, unsigned long rate);
+int davinci_clk_reset(struct clk *clk, bool reset);
 
 extern struct platform_device davinci_wdt_device;
 extern void davinci_watchdog_reset(struct platform_device *);
index a3b040219876646eeaf91de4bbe71e3590f6ef3b..3e8af6a0b64c6aac9f92202a0c732417167005db 100644 (file)
@@ -18,4 +18,7 @@ struct clk;
 extern int clk_register(struct clk *clk);
 extern void clk_unregister(struct clk *clk);
 
+int davinci_clk_reset_assert(struct clk *c);
+int davinci_clk_reset_deassert(struct clk *c);
+
 #endif
index 40a0027838e81601427fbb2bc7ff04311e5300ad..0a22710493fd27f5cc2f8178741fdb0fcc1de666 100644 (file)
 
 #define MDSTAT_STATE_MASK      0x3f
 #define PDSTAT_STATE_MASK      0x1f
+#define MDCTL_LRST             BIT(8)
 #define MDCTL_FORCE            BIT(31)
 #define PDCTL_NEXT             BIT(0)
 #define PDCTL_EPCGOOD          BIT(8)
 #ifndef __ASSEMBLER__
 
 extern int davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id);
+extern void davinci_psc_reset(unsigned int ctlr, unsigned int id,
+               bool reset);
 extern void davinci_psc_config(unsigned int domain, unsigned int ctlr,
                unsigned int id, bool enable, u32 flags);
 
index bddaba9628e16983e9c3a3f1e6a1897bdee21c44..82fdc69d5728c7e897851d1a7ccb91a22e06cb32 100644 (file)
@@ -48,6 +48,31 @@ int __init davinci_psc_is_clk_active(unsigned int ctlr, unsigned int id)
        return mdstat & BIT(12);
 }
 
+/* Control "reset" line associated with PSC domain */
+void davinci_psc_reset(unsigned int ctlr, unsigned int id, bool reset)
+{
+       u32 mdctl;
+       void __iomem *psc_base;
+       struct davinci_soc_info *soc_info = &davinci_soc_info;
+
+       if (!soc_info->psc_bases || (ctlr >= soc_info->psc_bases_num)) {
+               pr_warn("PSC: Bad psc data: 0x%x[%d]\n",
+                               (int)soc_info->psc_bases, ctlr);
+               return;
+       }
+
+       psc_base = ioremap(soc_info->psc_bases[ctlr], SZ_4K);
+
+       mdctl = readl(psc_base + MDCTL + 4 * id);
+       if (reset)
+               mdctl &= ~MDCTL_LRST;
+       else
+               mdctl |= MDCTL_LRST;
+       writel(mdctl, psc_base + MDCTL + 4 * id);
+
+       iounmap(psc_base);
+}
+
 /* Enable or disable a PSC domain */
 void davinci_psc_config(unsigned int domain, unsigned int ctlr,
                unsigned int id, bool enable, u32 flags)