This allows an updated simplefb driver in the kernel to correctly claim
clocks, so that these do not get automatically disabled by the kernels
clock framework, and so that simplefb actually does something useful for
the kernel on sunxi hw as well.

Currently, only clocks already defined in the dt today are handled. When
a sunxi KMS driver for mainline kernel happens, further clocks will have
to get defined in the sunxi dtses, and more clocks will have to be
claimed from this side as well. It is relatively pointless to try to
claim these clocks today already, as they will most likely be
significantly altered again when KMS happens.

Signed-off-by: Luc Verhaegen <l...@skynet.be>
---
 drivers/video/sunxi_display.c |   85 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 85 insertions(+), 0 deletions(-)

diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c
index d5bc88e..4d87b66 100644
--- a/drivers/video/sunxi_display.c
+++ b/drivers/video/sunxi_display.c
@@ -590,6 +590,89 @@ video_hw_init(void)
  * Simplefb support.
  */
 #if defined(CONFIG_OF_BOARD_SETUP) && defined(CONFIG_VIDEO_DT_SIMPLEFB)
+static void
+sunxi_simplefb_clocks(void *blob, int node_simplefb)
+{
+       const char *compatible[] = {
+               "allwinner,sun4i-a10-ahb-gates-clk",
+               "allwinner,sun5i-a10s-ahb-gates-clk",
+               "allwinner,sun5i-a13-ahb-gates-clk",
+               "allwinner,sun7i-a20-ahb-gates-clk",
+               NULL,
+       };
+       /*
+        * This currently ignores standalone clocks, like pll3/7, as these
+        * are still ignored in the dts files.
+        */
+#define PLACEHOLDER_AHB_GATES 0xFFFFFFFF
+       fdt32_t cells[] = {
+               PLACEHOLDER_AHB_GATES, fdt32_to_cpu(0x24), /* ahb_lcd0 */
+               PLACEHOLDER_AHB_GATES, fdt32_to_cpu(0x2B), /* ahb_hdmi */
+               PLACEHOLDER_AHB_GATES, fdt32_to_cpu(0x2C), /* ahb_de_be0 */
+       };
+       const char *stringlist;
+       int node_clock, i, phandle, stringlength, ret;
+
+       /* Find the ahb_gates node. */
+       for (i = 0; compatible[i]; i++) {
+               node_clock =
+                       fdt_node_offset_by_compatible(blob, 0, compatible[i]);
+               if (node_clock >= 0)
+                       break;
+       }
+
+       if (!compatible[i]) {
+               eprintf("%s: unable to find ahb_gates device-tree node.\n",
+                       __func__);
+               return;
+       }
+
+       /*
+        * sanity check clock-output-names.
+        *
+        * Not that this really matters as one is supposed to reference
+        * clock gating by actual register bit offsets.
+        */
+       stringlist = fdt_getprop(blob, node_clock, "clock-output-names",
+                                &stringlength);
+       if (!stringlist) {
+               eprintf("%s: unable to find clock-output-names property.\n",
+                       __func__);
+               return;
+       }
+
+       if (!fdt_stringlist_contains(stringlist, stringlength, "ahb_de_be0")) {
+               printf("%s: unable to find ahb gating bit %s\n", __func__,
+                      "ahb_de_be0");
+               return;
+       }
+
+       if (!fdt_stringlist_contains(stringlist, stringlength, "ahb_lcd0")) {
+               printf("%s: unable to find ahb gating bit %s\n", __func__,
+                      "ahb_lcd0");
+               return;
+       }
+
+       if (!fdt_stringlist_contains(stringlist, stringlength, "ahb_hdmi") &&
+           !fdt_stringlist_contains(stringlist, stringlength, "ahb_hdmi0")) {
+               printf("%s: unable to find ahb gating bit %s\n", __func__,
+                      "ahb_hdmi/ahb_hdmi0");
+               return;
+       }
+
+       /* Now add our actual clocks tuples. */
+       phandle = fdt_get_phandle(blob, node_clock);
+
+       for (i = 0; i < (sizeof(cells) / sizeof(*cells)); i++)
+               if (cells[i] == PLACEHOLDER_AHB_GATES)
+                       cells[i] = fdt32_to_cpu(phandle);
+
+       ret = fdt_setprop(blob, node_simplefb, "clocks", cells, sizeof(cells));
+       if (ret)
+               eprintf("%s: fdt_setprop \"clocks\" failed: %d\n",
+                       __func__, ret);
+}
+
 void
 sunxi_simplefb_setup(void *blob)
 {
@@ -638,5 +721,7 @@ sunxi_simplefb_setup(void *blob)
        ret = fdt_setprop(blob, offset, "format", format, strlen(format) + 1);
        if (ret < 0)
                return;
+
+       sunxi_simplefb_clocks(blob, offset);
 }
 #endif /* CONFIG_OF_BOARD_SETUP && CONFIG_VIDEO_DT_SIMPLEFB */
-- 
1.7.7

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to