]> git.sur5r.net Git - u-boot/commitdiff
clk: uniphier: rework for better clock tree structure
authorMasahiro Yamada <yamada.masahiro@socionext.com>
Fri, 13 Oct 2017 10:21:59 +0000 (19:21 +0900)
committerMasahiro Yamada <yamada.masahiro@socionext.com>
Sun, 15 Oct 2017 13:32:25 +0000 (22:32 +0900)
U-Boot does not support fancy clock tree structures like the Linux
common clock framework.  Implement a simple clock tree model at the
driver level.  With this, the clock data will be simplified.

Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
drivers/clk/uniphier/clk-uniphier-core.c
drivers/clk/uniphier/clk-uniphier-mio.c
drivers/clk/uniphier/clk-uniphier-sys.c
drivers/clk/uniphier/clk-uniphier.h

index 722cd6b060c8d02896aa08f4ec0de4a8394b8686..3d1d411e79201361a51f0a1908824e815707c8bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Socionext Inc.
+ * Copyright (C) 2016-2017 Socionext Inc.
  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
  *
  * SPDX-License-Identifier:    GPL-2.0+
  * @data: SoC specific data
  */
 struct uniphier_clk_priv {
+       struct udevice *dev;
        void __iomem *base;
        const struct uniphier_clk_data *data;
 };
 
-static int uniphier_clk_enable(struct clk *clk)
+static void uniphier_clk_gate_enable(struct uniphier_clk_priv *priv,
+                                    const struct uniphier_clk_gate_data *gate)
 {
-       struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
-       unsigned long id = clk->id;
-       const struct uniphier_clk_gate_data *p;
+       u32 val;
 
-       for (p = priv->data->gate; p->id != UNIPHIER_CLK_ID_END; p++) {
-               u32 val;
+       val = readl(priv->base + gate->reg);
+       val |= BIT(gate->bit);
+       writel(val, priv->base + gate->reg);
+}
 
-               if (p->id != id)
-                       continue;
+static void uniphier_clk_mux_set_parent(struct uniphier_clk_priv *priv,
+                                       const struct uniphier_clk_mux_data *mux,
+                                       u8 id)
+{
+       u32 val;
+       int i;
 
-               val = readl(priv->base + p->reg);
-               val |= BIT(p->bit);
-               writel(val, priv->base + p->reg);
+       for (i = 0; i < mux->num_parents; i++) {
+               if (mux->parent_ids[i] != id)
+                       continue;
 
-               return 0;
+               val = readl(priv->base + mux->reg);
+               val &= ~mux->masks[i];
+               val |= mux->vals[i];
+               writel(val, priv->base + mux->reg);
+               return;
        }
 
-       dev_err(priv->dev, "clk_id=%lu was not handled\n", id);
-       return -EINVAL;
+       WARN_ON(1);
 }
 
-static const struct uniphier_clk_mux_data *
-uniphier_clk_get_mux_data(struct uniphier_clk_priv *priv, unsigned long id)
+static u8 uniphier_clk_mux_get_parent(struct uniphier_clk_priv *priv,
+                                     const struct uniphier_clk_mux_data *mux)
 {
-       const struct uniphier_clk_mux_data *p;
+       u32 val;
+       int i;
 
-       for (p = priv->data->mux; p->id != UNIPHIER_CLK_ID_END; p++) {
-               if (p->id == id)
-                       return p;
-       }
+       val = readl(priv->base + mux->reg);
+
+       for (i = 0; i < mux->num_parents; i++)
+               if ((mux->masks[i] & val) == mux->vals[i])
+                       return mux->parent_ids[i];
+
+       dev_err(priv->dev, "invalid mux setting\n");
+
+       return UNIPHIER_CLK_ID_INVALID;
+}
+
+static const struct uniphier_clk_data *uniphier_clk_get_data(
+                                       struct uniphier_clk_priv *priv, u8 id)
+{
+       const struct uniphier_clk_data *data;
+
+       for (data = priv->data; data->type != UNIPHIER_CLK_TYPE_END; data++)
+               if (data->id == id)
+                       return data;
+
+       dev_err(priv->dev, "id=%u not found\n", id);
 
        return NULL;
 }
 
-static ulong uniphier_clk_get_rate(struct clk *clk)
+static const struct uniphier_clk_data *uniphier_clk_get_parent_data(
+                                       struct uniphier_clk_priv *priv,
+                                       const struct uniphier_clk_data *data)
 {
-       struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
-       const struct uniphier_clk_mux_data *mux;
-       u32 val;
-       int i;
+       const struct uniphier_clk_data *parent_data;
+       u8 parent_id = UNIPHIER_CLK_ID_INVALID;
+
+       switch (data->type) {
+       case UNIPHIER_CLK_TYPE_GATE:
+               parent_id = data->data.gate.parent_id;
+               break;
+       case UNIPHIER_CLK_TYPE_MUX:
+               parent_id = uniphier_clk_mux_get_parent(priv, &data->data.mux);
+               break;
+       default:
+               break;
+       }
 
-       mux = uniphier_clk_get_mux_data(priv, clk->id);
-       if (!mux)
-               return 0;
+       if (parent_id == UNIPHIER_CLK_ID_INVALID)
+               return NULL;
 
-       if (!mux->nr_muxs)              /* fixed-rate */
-               return mux->rates[0];
+       parent_data = uniphier_clk_get_data(priv, parent_id);
 
-       val = readl(priv->base + mux->reg);
+       WARN_ON(!parent_data);
 
-       for (i = 0; i < mux->nr_muxs; i++)
-               if ((mux->masks[i] & val) == mux->vals[i])
-                       return mux->rates[i];
+       return parent_data;
+}
+
+static void __uniphier_clk_enable(struct uniphier_clk_priv *priv,
+                                 const struct uniphier_clk_data *data)
+{
+       const struct uniphier_clk_data *parent_data;
 
-       return -EINVAL;
+       if (data->type == UNIPHIER_CLK_TYPE_GATE)
+               uniphier_clk_gate_enable(priv, &data->data.gate);
+
+       parent_data = uniphier_clk_get_parent_data(priv, data);
+       if (!parent_data)
+               return;
+
+       return __uniphier_clk_enable(priv, parent_data);
 }
 
-static ulong uniphier_clk_set_rate(struct clk *clk, ulong rate)
+static int uniphier_clk_enable(struct clk *clk)
 {
        struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
-       const struct uniphier_clk_mux_data *mux;
-       u32 val;
-       int i, best_rate_id = -1;
-       ulong best_rate = 0;
+       const struct uniphier_clk_data *data;
+
+       data = uniphier_clk_get_data(priv, clk->id);
+       if (!data)
+               return -ENODEV;
+
+       __uniphier_clk_enable(priv, data);
+
+       return 0;
+}
+
+static unsigned long __uniphier_clk_get_rate(
+                                       struct uniphier_clk_priv *priv,
+                                       const struct uniphier_clk_data *data)
+{
+       const struct uniphier_clk_data *parent_data;
 
-       mux = uniphier_clk_get_mux_data(priv, clk->id);
-       if (!mux)
+       if (data->type == UNIPHIER_CLK_TYPE_FIXED_RATE)
+               return data->data.rate.fixed_rate;
+
+       parent_data = uniphier_clk_get_parent_data(priv, data);
+       if (!parent_data)
                return 0;
 
-       if (!mux->nr_muxs)              /* fixed-rate */
-               return mux->rates[0];
+       return __uniphier_clk_get_rate(priv, parent_data);
+}
 
-       /* first, decide the best match rate */
-       for (i = 0; i < mux->nr_muxs; i++) {
-               if (mux->rates[i] > best_rate && mux->rates[i] <= rate) {
-                       best_rate = mux->rates[i];
-                       best_rate_id = i;
+static unsigned long uniphier_clk_get_rate(struct clk *clk)
+{
+       struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
+       const struct uniphier_clk_data *data;
+
+       data = uniphier_clk_get_data(priv, clk->id);
+       if (!data)
+               return -ENODEV;
+
+       return __uniphier_clk_get_rate(priv, data);
+}
+
+static unsigned long __uniphier_clk_set_rate(
+                                       struct uniphier_clk_priv *priv,
+                                       const struct uniphier_clk_data *data,
+                                       unsigned long rate, bool set)
+{
+       const struct uniphier_clk_data *best_parent_data = NULL;
+       const struct uniphier_clk_data *parent_data;
+       unsigned long best_rate = 0;
+       unsigned long parent_rate;
+       u8 parent_id;
+       int i;
+
+       if (data->type == UNIPHIER_CLK_TYPE_FIXED_RATE)
+               return data->data.rate.fixed_rate;
+
+       if (data->type == UNIPHIER_CLK_TYPE_GATE) {
+               parent_data = uniphier_clk_get_parent_data(priv, data);
+               if (!parent_data)
+                       return 0;
+
+               return __uniphier_clk_set_rate(priv, parent_data, rate, set);
+       }
+
+       if (WARN_ON(data->type != UNIPHIER_CLK_TYPE_MUX))
+               return -EINVAL;
+
+       for (i = 0; i < data->data.mux.num_parents; i++) {
+               parent_id = data->data.mux.parent_ids[i];
+               parent_data = uniphier_clk_get_data(priv, parent_id);
+               if (WARN_ON(!parent_data))
+                       return -EINVAL;
+
+               parent_rate = __uniphier_clk_set_rate(priv, parent_data, rate,
+                                                     false);
+
+               if (parent_rate <= rate && best_rate < parent_rate) {
+                       best_rate = parent_rate;
+                       best_parent_data = parent_data;
                }
        }
 
-       if (best_rate_id < 0)
+       dev_dbg(priv->dev, "id=%u, best_rate=%lu\n", data->id, best_rate);
+
+       if (!best_parent_data)
                return -EINVAL;
 
-       val = readl(priv->base + mux->reg);
-       val &= ~mux->masks[best_rate_id];
-       val |= mux->vals[best_rate_id];
-       writel(val, priv->base + mux->reg);
+       if (!set)
+               return best_rate;
+
+       uniphier_clk_mux_set_parent(priv, &data->data.mux,
+                                   best_parent_data->id);
+
+       return best_rate = __uniphier_clk_set_rate(priv, best_parent_data,
+                                                  rate, true);
+}
+
+static unsigned long uniphier_clk_set_rate(struct clk *clk, ulong rate)
+{
+       struct uniphier_clk_priv *priv = dev_get_priv(clk->dev);
+       const struct uniphier_clk_data *data;
 
-       debug("%s: requested rate = %lu, set rate = %lu\n", __func__,
-             rate, best_rate);
+       data = uniphier_clk_get_data(priv, clk->id);
+       if (!data)
+               return -ENODEV;
 
-       return best_rate;
+       return __uniphier_clk_set_rate(priv, data, rate, true);
 }
 
 static const struct clk_ops uniphier_clk_ops = {
@@ -140,6 +260,7 @@ static int uniphier_clk_probe(struct udevice *dev)
        if (!priv->base)
                return -ENOMEM;
 
+       priv->dev = dev;
        priv->data = (void *)dev_get_driver_data(dev);
 
        return 0;
@@ -149,60 +270,60 @@ static const struct udevice_id uniphier_clk_match[] = {
        /* System clock */
        {
                .compatible = "socionext,uniphier-ld4-clock",
-               .data = (ulong)&uniphier_pxs2_sys_clk_data,
+               .data = (ulong)uniphier_pxs2_sys_clk_data,
        },
        {
                .compatible = "socionext,uniphier-pro4-clock",
-               .data = (ulong)&uniphier_pxs2_sys_clk_data,
+               .data = (ulong)uniphier_pxs2_sys_clk_data,
        },
        {
                .compatible = "socionext,uniphier-sld8-clock",
-               .data = (ulong)&uniphier_pxs2_sys_clk_data,
+               .data = (ulong)uniphier_pxs2_sys_clk_data,
        },
        {
                .compatible = "socionext,uniphier-pro5-clock",
-               .data = (ulong)&uniphier_pxs2_sys_clk_data,
+               .data = (ulong)uniphier_pxs2_sys_clk_data,
        },
        {
                .compatible = "socionext,uniphier-pxs2-clock",
-               .data = (ulong)&uniphier_pxs2_sys_clk_data,
+               .data = (ulong)uniphier_pxs2_sys_clk_data,
        },
        {
                .compatible = "socionext,uniphier-ld11-clock",
-               .data = (ulong)&uniphier_ld20_sys_clk_data,
+               .data = (ulong)uniphier_ld20_sys_clk_data,
        },
        {
                .compatible = "socionext,uniphier-ld20-clock",
-               .data = (ulong)&uniphier_ld20_sys_clk_data,
+               .data = (ulong)uniphier_ld20_sys_clk_data,
        },
        /* Media I/O clock */
        {
                .compatible = "socionext,uniphier-ld4-mio-clock",
-               .data = (ulong)&uniphier_mio_clk_data,
+               .data = (ulong)uniphier_mio_clk_data,
        },
        {
                .compatible = "socionext,uniphier-pro4-mio-clock",
-               .data = (ulong)&uniphier_mio_clk_data,
+               .data = (ulong)uniphier_mio_clk_data,
        },
        {
                .compatible = "socionext,uniphier-sld8-mio-clock",
-               .data = (ulong)&uniphier_mio_clk_data,
+               .data = (ulong)uniphier_mio_clk_data,
        },
        {
                .compatible = "socionext,uniphier-pro5-sd-clock",
-               .data = (ulong)&uniphier_mio_clk_data,
+               .data = (ulong)uniphier_mio_clk_data,
        },
        {
                .compatible = "socionext,uniphier-pxs2-sd-clock",
-               .data = (ulong)&uniphier_mio_clk_data,
+               .data = (ulong)uniphier_mio_clk_data,
        },
        {
                .compatible = "socionext,uniphier-ld11-mio-clock",
-               .data = (ulong)&uniphier_mio_clk_data,
+               .data = (ulong)uniphier_mio_clk_data,
        },
        {
                .compatible = "socionext,uniphier-ld20-sd-clock",
-               .data = (ulong)&uniphier_mio_clk_data,
+               .data = (ulong)uniphier_mio_clk_data,
        },
        { /* sentinel */ }
 };
index 9c13dcd55518f5cbe27dd7332e0a3aa2f9e092a4..5c7384840280efa9954c466e5d532cb36436c30e 100644 (file)
@@ -7,59 +7,71 @@
 
 #include "clk-uniphier.h"
 
-#define UNIPHIER_MIO_CLK_SD_GATE(id, ch)                               \
-       UNIPHIER_CLK_GATE((id), 0x20 + 0x200 * (ch), 8)
+#define UNIPHIER_MIO_CLK_SD_FIXED                                      \
+       UNIPHIER_CLK_RATE(128, 44444444),                               \
+       UNIPHIER_CLK_RATE(129, 33333333),                               \
+       UNIPHIER_CLK_RATE(130, 50000000),                               \
+       UNIPHIER_CLK_RATE(131, 66666667),                               \
+       UNIPHIER_CLK_RATE(132, 100000000),                              \
+       UNIPHIER_CLK_RATE(133, 40000000),                               \
+       UNIPHIER_CLK_RATE(134, 25000000),                               \
+       UNIPHIER_CLK_RATE(135, 22222222)
+
+#define UNIPHIER_MIO_CLK_SD(_id, ch)                                   \
+       {                                                               \
+               .type = UNIPHIER_CLK_TYPE_MUX,                          \
+               .id = (_id) + 32,                                       \
+               .data.mux = {                                           \
+                       .parent_ids = {                                 \
+                               128,                                    \
+                               129,                                    \
+                               130,                                    \
+                               131,                                    \
+                               132,                                    \
+                               133,                                    \
+                               134,                                    \
+                               135,                                    \
+                       },                                              \
+                       .num_parents = 8,                               \
+                       .reg = 0x30 + 0x200 * (ch),                     \
+                       .masks = {                                      \
+                               0x00031000,                             \
+                               0x00031000,                             \
+                               0x00031000,                             \
+                               0x00031000,                             \
+                               0x00001300,                             \
+                               0x00001300,                             \
+                               0x00001300,                             \
+                               0x00001300,                             \
+                       },                                              \
+                       .vals = {                                       \
+                               0x00000000,                             \
+                               0x00010000,                             \
+                               0x00020000,                             \
+                               0x00030000,                             \
+                               0x00001000,                             \
+                               0x00001100,                             \
+                               0x00001200,                             \
+                               0x00001300,                             \
+                       },                                              \
+               },                                                      \
+       },                                                              \
+       UNIPHIER_CLK_GATE((_id), (_id) + 32, 0x20 + 0x200 * (ch), 8)
 
 #define UNIPHIER_MIO_CLK_USB2(id, ch)                                  \
-       UNIPHIER_CLK_GATE((id), 0x20 + 0x200 * (ch), 28)
+       UNIPHIER_CLK_GATE_SIMPLE((id), 0x20 + 0x200 * (ch), 28)
 
 #define UNIPHIER_MIO_CLK_USB2_PHY(id, ch)                              \
-       UNIPHIER_CLK_GATE((id), 0x20 + 0x200 * (ch), 29)
+       UNIPHIER_CLK_GATE_SIMPLE((id), 0x20 + 0x200 * (ch), 29)
 
 #define UNIPHIER_MIO_CLK_DMAC(id)                                      \
-       UNIPHIER_CLK_GATE((id), 0x20, 25)
-
-#define UNIPHIER_MIO_CLK_SD_MUX(_id, ch)                               \
-       {                                                               \
-               .id = (_id),                                            \
-               .nr_muxs = 8,                                           \
-               .reg = 0x30 + 0x200 * (ch),                             \
-               .masks = {                                              \
-                       0x00031000,                                     \
-                       0x00031000,                                     \
-                       0x00031000,                                     \
-                       0x00031000,                                     \
-                       0x00001300,                                     \
-                       0x00001300,                                     \
-                       0x00001300,                                     \
-                       0x00001300,                                     \
-               },                                                      \
-               .vals = {                                               \
-                       0x00000000,                                     \
-                       0x00010000,                                     \
-                       0x00020000,                                     \
-                       0x00030000,                                     \
-                       0x00001000,                                     \
-                       0x00001100,                                     \
-                       0x00001200,                                     \
-                       0x00001300,                                     \
-               },                                                      \
-               .rates = {                                              \
-                       44444444,                                       \
-                       33333333,                                       \
-                       50000000,                                       \
-                       66666666,                                       \
-                       100000000,                                      \
-                       40000000,                                       \
-                       25000000,                                       \
-                       22222222,                                       \
-               },                                                      \
-       }
+       UNIPHIER_CLK_GATE_SIMPLE((id), 0x20, 25)
 
-static const struct uniphier_clk_gate_data uniphier_mio_clk_gate[] = {
-       UNIPHIER_MIO_CLK_SD_GATE(0, 0),
-       UNIPHIER_MIO_CLK_SD_GATE(1, 1),
-       UNIPHIER_MIO_CLK_SD_GATE(2, 2),         /* for PH1-Pro4 only */
+const struct uniphier_clk_data uniphier_mio_clk_data[] = {
+       UNIPHIER_MIO_CLK_SD_FIXED,
+       UNIPHIER_MIO_CLK_SD(0, 0),
+       UNIPHIER_MIO_CLK_SD(1, 1),
+       UNIPHIER_MIO_CLK_SD(2, 2),
        UNIPHIER_MIO_CLK_DMAC(7),
        UNIPHIER_MIO_CLK_USB2(8, 0),
        UNIPHIER_MIO_CLK_USB2(9, 1),
@@ -67,17 +79,5 @@ static const struct uniphier_clk_gate_data uniphier_mio_clk_gate[] = {
        UNIPHIER_MIO_CLK_USB2_PHY(12, 0),
        UNIPHIER_MIO_CLK_USB2_PHY(13, 1),
        UNIPHIER_MIO_CLK_USB2_PHY(14, 2),
-       UNIPHIER_CLK_END
-};
-
-static const struct uniphier_clk_mux_data uniphier_mio_clk_mux[] = {
-       UNIPHIER_MIO_CLK_SD_MUX(0, 0),
-       UNIPHIER_MIO_CLK_SD_MUX(1, 1),
-       UNIPHIER_MIO_CLK_SD_MUX(2, 2),          /* for PH1-Pro4 only */
-       UNIPHIER_CLK_END
-};
-
-const struct uniphier_clk_data uniphier_mio_clk_data = {
-       .gate = uniphier_mio_clk_gate,
-       .mux = uniphier_mio_clk_mux,
+       { /* sentinel */ }
 };
index 709fa5081a42adb540e27e2993a0bd8afd6d1e11..e9df88508c39c50c3f552734c3401efaa7efb243 100644 (file)
@@ -7,28 +7,26 @@
 
 #include "clk-uniphier.h"
 
-const struct uniphier_clk_gate_data uniphier_pxs2_sys_clk_gate[] = {
-       UNIPHIER_CLK_GATE(8, 0x2104, 10),       /* stdmac */
-       UNIPHIER_CLK_GATE(12, 0x2104, 6),       /* gio (Pro4, Pro5) */
-       UNIPHIER_CLK_GATE(14, 0x2104, 16),      /* usb30 (Pro4, Pro5, PXs2) */
-       UNIPHIER_CLK_GATE(15, 0x2104, 17),      /* usb31 (Pro4, Pro5, PXs2) */
-       UNIPHIER_CLK_GATE(16, 0x2104, 19),      /* usb30-phy (PXs2) */
-       UNIPHIER_CLK_GATE(20, 0x2104, 20),      /* usb31-phy (PXs2) */
-       UNIPHIER_CLK_END
+const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[] = {
+#if defined(CONFIG_ARCH_UNIPHIER_LD4) || defined(CONFIG_ARCH_UNIPHIER_SLD8) ||\
+    defined(CONFIG_ARCH_UNIPHIER_PRO4) || defined(CONFIG_ARCH_UNIPHIER_PRO5) ||\
+    defined(CONFIG_ARCH_UNIPHIER_PXS2) || defined(CONFIG_ARCH_UNIPHIER_LD6B)
+       UNIPHIER_CLK_GATE_SIMPLE(8, 0x2104, 10),        /* stdmac */
+       UNIPHIER_CLK_GATE_SIMPLE(12, 0x2104, 6),        /* gio (Pro4, Pro5) */
+       UNIPHIER_CLK_GATE_SIMPLE(14, 0x2104, 16),       /* usb30 (Pro4, Pro5, PXs2) */
+       UNIPHIER_CLK_GATE_SIMPLE(15, 0x2104, 17),       /* usb31 (Pro4, Pro5, PXs2) */
+       UNIPHIER_CLK_GATE_SIMPLE(16, 0x2104, 19),       /* usb30-phy (PXs2) */
+       UNIPHIER_CLK_GATE_SIMPLE(20, 0x2104, 20),       /* usb31-phy (PXs2) */
+       { /* sentinel */ }
+#endif
 };
 
-const struct uniphier_clk_data uniphier_pxs2_sys_clk_data = {
-       .gate = uniphier_pxs2_sys_clk_gate,
-};
-
-const struct uniphier_clk_gate_data uniphier_ld20_sys_clk_gate[] = {
-       UNIPHIER_CLK_GATE(8, 0x210c, 8),        /* stdmac */
-       UNIPHIER_CLK_GATE(14, 0x210c, 14),      /* usb30 (LD20) */
-       UNIPHIER_CLK_GATE(16, 0x210c, 12),      /* usb30-phy0 (LD20) */
-       UNIPHIER_CLK_GATE(17, 0x210c, 13),      /* usb30-phy1 (LD20) */
-       UNIPHIER_CLK_END
-};
-
-const struct uniphier_clk_data uniphier_ld20_sys_clk_data = {
-       .gate = uniphier_ld20_sys_clk_gate,
+const struct uniphier_clk_data uniphier_ld20_sys_clk_data[] = {
+#if defined(CONFIG_ARCH_UNIPHIER_LD11) || defined(CONFIG_ARCH_UNIPHIER_LD20)
+       UNIPHIER_CLK_GATE_SIMPLE(8, 0x210c, 8),         /* stdmac */
+       UNIPHIER_CLK_GATE_SIMPLE(14, 0x210c, 14),       /* usb30 (LD20) */
+       UNIPHIER_CLK_GATE_SIMPLE(16, 0x210c, 12),       /* usb30-phy0 (LD20) */
+       UNIPHIER_CLK_GATE_SIMPLE(17, 0x210c, 13),       /* usb30-phy1 (LD20) */
+       { /* sentinel */ }
+#endif
 };
index 770a3225e1a3bdddbad1a0319ef0e50e10f43047..9b6c94fc38ba1572c01646eda10b3dc9c385af50 100644 (file)
@@ -9,49 +9,70 @@
 #define __CLK_UNIPHIER_H__
 
 #include <linux/kernel.h>
+#include <linux/types.h>
 
-#define UNIPHIER_CLK_MAX_NR_MUXS       8
+#define UNIPHIER_CLK_MUX_MAX_PARENTS           8
+
+#define UNIPHIER_CLK_TYPE_END                  0
+#define UNIPHIER_CLK_TYPE_FIXED_RATE           2
+#define UNIPHIER_CLK_TYPE_GATE                 3
+#define UNIPHIER_CLK_TYPE_MUX                  4
+
+#define UNIPHIER_CLK_ID_INVALID                        (U8_MAX)
+
+struct uniphier_clk_fixed_rate_data {
+       unsigned long fixed_rate;
+};
 
 struct uniphier_clk_gate_data {
-       unsigned int id;
-       unsigned int reg;
-       unsigned int bit;
+       u8 parent_id;
+       u16 reg;
+       u8 bit;
 };
 
 struct uniphier_clk_mux_data {
-       unsigned int id;
-       unsigned int nr_muxs;
-       unsigned int reg;
-       unsigned int masks[UNIPHIER_CLK_MAX_NR_MUXS];
-       unsigned int vals[UNIPHIER_CLK_MAX_NR_MUXS];
-       unsigned long rates[UNIPHIER_CLK_MAX_NR_MUXS];
+       u8 parent_ids[UNIPHIER_CLK_MUX_MAX_PARENTS];
+       u8 num_parents;
+       u16 reg;
+       u32 masks[UNIPHIER_CLK_MUX_MAX_PARENTS];
+       u32 vals[UNIPHIER_CLK_MUX_MAX_PARENTS];
 };
 
 struct uniphier_clk_data {
-       const struct uniphier_clk_gate_data *gate;
-       const struct uniphier_clk_mux_data *mux;
+       u8 type;
+       u8 id;
+       union {
+               struct uniphier_clk_fixed_rate_data rate;
+               struct uniphier_clk_gate_data gate;
+               struct uniphier_clk_mux_data mux;
+       } data;
 };
 
-#define UNIPHIER_CLK_ID_END            (unsigned int)(-1)
-
-#define UNIPHIER_CLK_END                               \
-       { .id = UNIPHIER_CLK_ID_END }
-
-#define UNIPHIER_CLK_GATE(_id, _reg, _bit)             \
-       {                                               \
-               .id = (_id),                            \
-               .reg = (_reg),                          \
-               .bit = (_bit),                          \
+#define UNIPHIER_CLK_RATE(_id, _rate)                          \
+       {                                                       \
+               .type = UNIPHIER_CLK_TYPE_FIXED_RATE,           \
+               .id = (_id),                                    \
+               .data.rate = {                                  \
+                       .fixed_rate = (_rate),                  \
+               },                                              \
        }
 
-#define UNIPHIER_CLK_FIXED_RATE(_id, _rate)            \
-       {                                               \
-               .id = (_id),                            \
-               .rates = {(_reg),},                     \
+#define UNIPHIER_CLK_GATE(_id, _parent, _reg, _bit)            \
+       {                                                       \
+               .type = UNIPHIER_CLK_TYPE_GATE,                 \
+               .id = (_id),                                    \
+               .data.gate = {                                  \
+                       .parent_id = (_parent),                 \
+                       .reg = (_reg),                          \
+                       .bit = (_bit),                          \
+               },                                              \
        }
 
-extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data;
-extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data;
-extern const struct uniphier_clk_data uniphier_mio_clk_data;
+#define UNIPHIER_CLK_GATE_SIMPLE(_id, _reg, _bit)              \
+       UNIPHIER_CLK_GATE(_id, UNIPHIER_CLK_ID_INVALID, _reg, _bit)
+
+extern const struct uniphier_clk_data uniphier_pxs2_sys_clk_data[];
+extern const struct uniphier_clk_data uniphier_ld20_sys_clk_data[];
+extern const struct uniphier_clk_data uniphier_mio_clk_data[];
 
 #endif /* __CLK_UNIPHIER_H__ */