Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/sunxi Add a round_rate() callback for the sunxi...



details:   https://anonhg.NetBSD.org/src/rev/40f8528c60e8
branches:  trunk
changeset: 321710:40f8528c60e8
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sun Apr 01 21:19:17 2018 +0000

description:
Add a round_rate() callback for the sunxi clock domain.
Add a sunxi_ccu_display.c file with helpers for setting up display engine
clocks.
for fractional clocks, rename frac_en to div_en, I got the logic inverted.
Adjust tcon0-ch0, tcon0-ch1, tcon1-ch0 and tcon1-ch1 definitions to
automatically select a parent. tcon0 hardcoded to pll3 and tcon1 to pll7.
Define a round_rate() callback for these clocks, as well as fractional clocks.
Hardcode debe clocks parent to pll5.

diffstat:

 sys/arch/arm/sunxi/files.sunxi            |    3 +-
 sys/arch/arm/sunxi/sun4i_a10_ccu.c        |  333 +++++++++++++++++++++++++----
 sys/arch/arm/sunxi/sunxi_ccu.c            |   27 ++-
 sys/arch/arm/sunxi/sunxi_ccu.h            |   25 +-
 sys/arch/arm/sunxi/sunxi_ccu_display.c    |  128 +++++++++++
 sys/arch/arm/sunxi/sunxi_ccu_fractional.c |   58 ++++-
 6 files changed, 511 insertions(+), 63 deletions(-)

diffs (truncated from 797 to 300 lines):

diff -r 2d807e894e6a -r 40f8528c60e8 sys/arch/arm/sunxi/files.sunxi
--- a/sys/arch/arm/sunxi/files.sunxi    Sun Apr 01 21:11:01 2018 +0000
+++ b/sys/arch/arm/sunxi/files.sunxi    Sun Apr 01 21:19:17 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.sunxi,v 1.46 2018/04/01 04:35:04 ryo Exp $
+#      $NetBSD: files.sunxi,v 1.47 2018/04/01 21:19:17 bouyer Exp $
 #
 # Configuration info for Allwinner sunxi family SoCs
 #
@@ -17,6 +17,7 @@
 file   arch/arm/sunxi/sunxi_ccu_nkmp.c         sunxi_ccu
 file   arch/arm/sunxi/sunxi_ccu_phase.c        sunxi_ccu
 file   arch/arm/sunxi/sunxi_ccu_prediv.c       sunxi_ccu
+file   arch/arm/sunxi/sunxi_ccu_display.c      sunxi_ccu
 
 # CCU (A10/A20)
 device sun4ia10ccu: sunxi_ccu
diff -r 2d807e894e6a -r 40f8528c60e8 sys/arch/arm/sunxi/sun4i_a10_ccu.c
--- a/sys/arch/arm/sunxi/sun4i_a10_ccu.c        Sun Apr 01 21:11:01 2018 +0000
+++ b/sys/arch/arm/sunxi/sun4i_a10_ccu.c        Sun Apr 01 21:19:17 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sun4i_a10_ccu.c,v 1.7 2018/03/19 16:18:30 bouyer Exp $ */
+/* $NetBSD: sun4i_a10_ccu.c,v 1.8 2018/04/01 21:19:17 bouyer Exp $ */
 
 /*-
  * Copyright (c) 2017 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -28,7 +28,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: sun4i_a10_ccu.c,v 1.7 2018/03/19 16:18:30 bouyer Exp $");
+__KERNEL_RCSID(1, "$NetBSD: sun4i_a10_ccu.c,v 1.8 2018/04/01 21:19:17 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -116,10 +116,7 @@
 static const char *mod_parents[] = { "osc24m", "pll_periph", "pll_ddr_other" };
 static const char *sata_parents[] = { "pll6_periph_sata", "external" };
 static const char *de_parents[] = { "pll_video0", "pll_video1", "pll_ddr_other" };
-static const char *lcd0_parents[] = { "pll_video0", "pll_video1", "pll_video0x2" };
-static const char *lcd1_parents[] = { "pll_video0", "pll_video1", "pll_video0x2", "pll_video1x2" };
-static const char *lcd0ch1c2[] = { "tcon0-ch1-clk2" };
-static const char *lcd1ch1c2[] = { "tcon1-ch1-clk2" };
+static const char *lcd_parents[] = { "pll_video0", "pll_video1", "pll_video0x2", "pll_video1x2" };
 
 static const struct sunxi_ccu_nkmp_tbl sun4i_a10_pll1_table[] = {
        { 1008000000, 21, 1, 0, 0 },
@@ -139,6 +136,25 @@
        { 0 }
 };
 
+/*
+ * some special cases
+ * hardcode lcd0 (tcon0) to pll3 and lcd1 (tcon1) to pll7.
+ * compute pll rate based on desired pixel clock
+ */
+
+static int sun4i_a10_ccu_lcd0ch0_set_rate(struct sunxi_ccu_softc *,
+    struct sunxi_ccu_clk *, u_int);
+static int sun4i_a10_ccu_lcd1ch0_set_rate(struct sunxi_ccu_softc *,
+    struct sunxi_ccu_clk *, u_int);
+static u_int sun4i_a10_ccu_lcd0ch0_round_rate(struct sunxi_ccu_softc *,
+    struct sunxi_ccu_clk *, u_int);
+static u_int sun4i_a10_ccu_lcd1ch0_round_rate(struct sunxi_ccu_softc *,
+    struct sunxi_ccu_clk *, u_int);
+static int sun4i_a10_ccu_lcd0ch1_set_rate(struct sunxi_ccu_softc *,
+    struct sunxi_ccu_clk *, u_int);
+static int sun4i_a10_ccu_lcd1ch1_set_rate(struct sunxi_ccu_softc *,
+    struct sunxi_ccu_clk *, u_int);
+
 static struct sunxi_ccu_clk sun4i_a10_ccu_clks[] = {
        SUNXI_CCU_GATE(A10_CLK_HOSC, "osc24m", "hosc",
            OSC24M_CFG_REG, 0),
@@ -302,7 +318,7 @@
            __BITS(7,0),                /* m */
            9,                          /* m_min */
            127,                        /* m_max */
-           __BIT(15),                  /* frac_en */
+           __BIT(15),                  /* div_en */
            __BIT(14),                  /* frac_sel */
            270000000, 297000000,       /* frac values */
            8,                          /* prediv */
@@ -313,7 +329,7 @@
            __BITS(7,0),                /* m */
            9,                          /* m_min */
            127,                        /* m_max */
-           __BIT(15),                  /* frac_en */
+           __BIT(15),                  /* div_en */
            __BIT(14),                  /* frac_sel */
            270000000, 297000000,       /* frac values */
            8,                          /* prediv */
@@ -354,49 +370,73 @@
            __BIT(31),                  /* enable */
            0                           /* flags */
            ),
-       SUNXI_CCU_DIV_GATE(A10_CLK_TCON0_CH0, "tcon0-ch0", lcd0_parents,
-           LCD0CH0_CFG_REG,            /* reg */
-           0,                          /* div */
-           __BITS(25,24),              /* sel */
-           __BIT(31),                  /* enable */
-           SUNXI_CCU_DIV_SET_RATE_PARENT /* flags */
-           ),
-       SUNXI_CCU_DIV_GATE(A10_CLK_TCON1_CH0, "tcon1-ch0", lcd1_parents,
-           LCD1CH0_CFG_REG,            /* reg */
-           0,                          /* div */
-           __BITS(25,24),              /* sel */
-           __BIT(31),                  /* enable */
-           SUNXI_CCU_DIV_SET_RATE_PARENT /* flags */
-           ),
-       SUNXI_CCU_DIV_GATE(A10_CLK_TCON0_CH1_SCLK2, "tcon0-ch1-clk2", lcd1_parents,
-           LCD0CH1_CFG_REG,            /* reg */
-           __BITS(3,0),                /* div */
-           __BITS(25,24),              /* sel */
-           __BIT(31),                  /* enable */
-           SUNXI_CCU_DIV_SET_RATE_PARENT /* flags */
-           ),
-       SUNXI_CCU_DIV_GATE(A10_CLK_TCON0_CH1, "tcon0-ch1", lcd0ch1c2,
-           LCD0CH1_CFG_REG,            /* reg */
-           __BIT(11),                  /* div */
-           0,                          /* sel */
-           __BIT(15),                  /* enable */
-           SUNXI_CCU_DIV_SET_RATE_PARENT /* flags */
-           ),
-       SUNXI_CCU_DIV_GATE(A10_CLK_TCON1_CH1_SCLK2, "tcon1-ch1-clk2", lcd1_parents,
-           LCD1CH1_CFG_REG,            /* reg */
-           __BITS(3,0),                /* div */
-           __BITS(25,24),              /* sel */
-           __BIT(31),                  /* enable */
-           SUNXI_CCU_DIV_SET_RATE_PARENT /* flags */
-           ),
-       SUNXI_CCU_DIV_GATE(A10_CLK_TCON1_CH1, "tcon1-ch1", lcd1ch1c2,
-           LCD1CH1_CFG_REG,            /* reg */
-           __BIT(11),                  /* div */
-           0,                          /* sel */
-           __BIT(15),                  /* enable */
-           SUNXI_CCU_DIV_SET_RATE_PARENT /* flags */
-           ),
-       SUNXI_CCU_DIV_GATE(A10_CLK_HDMI, "hdmi-mod", lcd1_parents,
+       [A10_CLK_TCON0_CH0] = {
+           .type = SUNXI_CCU_DIV,
+           .base.name = "tcon0-ch0",
+           .u.div.reg = LCD0CH0_CFG_REG,
+           .u.div.parents = lcd_parents,
+           .u.div.nparents = __arraycount(lcd_parents),
+           .u.div.div = 0,
+           .u.div.sel = __BITS(25,24),
+           .u.div.enable = __BIT(31),
+           .u.div.flags = 0,
+           .enable = sunxi_ccu_div_enable,
+           .get_rate = sunxi_ccu_div_get_rate,
+           .set_rate = sun4i_a10_ccu_lcd0ch0_set_rate,
+           .round_rate = sun4i_a10_ccu_lcd0ch0_round_rate,
+           .set_parent = sunxi_ccu_div_set_parent,
+           .get_parent = sunxi_ccu_div_get_parent,
+           },
+       [A10_CLK_TCON1_CH0] = {
+           .type = SUNXI_CCU_DIV,
+           .base.name = "tcon1-ch0",
+           .u.div.reg = LCD1CH0_CFG_REG,
+           .u.div.parents = lcd_parents,
+           .u.div.nparents = __arraycount(lcd_parents),
+           .u.div.div = 0,
+           .u.div.sel = __BITS(25,24),
+           .u.div.enable = __BIT(31),
+           .u.div.flags = 0,
+           .enable = sunxi_ccu_div_enable,
+           .get_rate = sunxi_ccu_div_get_rate,
+           .set_rate = sun4i_a10_ccu_lcd1ch0_set_rate,
+           .round_rate = sun4i_a10_ccu_lcd1ch0_round_rate,
+           .set_parent = sunxi_ccu_div_set_parent,
+           .get_parent = sunxi_ccu_div_get_parent,
+           },
+       [A10_CLK_TCON0_CH1] = {
+           .type = SUNXI_CCU_DIV,
+           .base.name = "tcon0-ch1",
+           .u.div.reg = LCD0CH1_CFG_REG,
+           .u.div.parents = lcd_parents,
+           .u.div.nparents = __arraycount(lcd_parents),
+           .u.div.div = __BITS(3,0),
+           .u.div.sel = __BITS(25,24),
+           .u.div.enable = __BIT(15) | __BIT(31),
+           .u.div.flags = 0,
+           .enable = sunxi_ccu_div_enable,
+           .get_rate = sunxi_ccu_div_get_rate,
+           .set_rate = sun4i_a10_ccu_lcd0ch1_set_rate,
+           .set_parent = sunxi_ccu_div_set_parent,
+           .get_parent = sunxi_ccu_div_get_parent,
+           },
+       [A10_CLK_TCON1_CH1] = {
+           .type = SUNXI_CCU_DIV,
+           .base.name = "tcon1-ch1",
+           .u.div.reg = LCD1CH1_CFG_REG,
+           .u.div.parents = lcd_parents,
+           .u.div.nparents = __arraycount(lcd_parents),
+           .u.div.div = __BITS(3,0),
+           .u.div.sel = __BITS(25,24),
+           .u.div.enable = __BIT(15) | __BIT(31),
+           .u.div.flags = 0,
+           .enable = sunxi_ccu_div_enable,
+           .get_rate = sunxi_ccu_div_get_rate,
+           .set_rate = sun4i_a10_ccu_lcd1ch1_set_rate,
+           .set_parent = sunxi_ccu_div_set_parent,
+           .get_parent = sunxi_ccu_div_get_parent,
+           },
+       SUNXI_CCU_DIV_GATE(A10_CLK_HDMI, "hdmi-mod", lcd_parents,
            HDMI_CLOCK_CFG_REG,         /* reg */
            __BITS(3,0),                /* div */
            __BITS(25,24),              /* sel */
@@ -571,6 +611,177 @@
            USBPHY_CFG_REG, 8),
 };
 
+/*
+ * some special cases
+ * hardcode lcd0 (tcon0) to pll3 and lcd1 (tcon1) to pll7.
+ * compute pll rate based on desired pixel clock
+ */
+
+static int
+sun4i_a10_ccu_lcd0ch0_set_rate(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk * clk, u_int rate)
+{
+       int error;
+       error = sunxi_ccu_lcdxch0_set_rate(sc, clk,
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO0],
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO0_2X],
+           rate);
+       return error;
+}
+
+static int
+sun4i_a10_ccu_lcd1ch0_set_rate(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk * clk, u_int rate)
+{
+       return sunxi_ccu_lcdxch0_set_rate(sc, clk,
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO1],
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO1_2X],
+           rate);
+}
+
+static u_int
+sun4i_a10_ccu_lcd0ch0_round_rate(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk * clk, u_int rate)
+{
+       return sunxi_ccu_lcdxch0_round_rate(sc, clk,
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO0],
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO0_2X],
+           rate);
+}
+
+static u_int
+sun4i_a10_ccu_lcd1ch0_round_rate(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk * clk, u_int rate)
+{
+       return sunxi_ccu_lcdxch0_round_rate(sc, clk,
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO1],
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO1_2X],
+           rate);
+}
+
+static int
+sun4i_a10_ccu_lcd0ch1_set_rate(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk * clk, u_int rate)
+{
+       return sunxi_ccu_lcdxch1_set_rate(sc, clk,
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO0],
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO0_2X],
+           rate);
+}
+
+static int
+sun4i_a10_ccu_lcd1ch1_set_rate(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk * clk, u_int rate)
+{
+       return sunxi_ccu_lcdxch1_set_rate(sc, clk,
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO1],
+           &sun4i_a10_ccu_clks[A10_CLK_PLL_VIDEO1_2X],
+           rate);
+}
+
+#if 0
+static int
+sun4i_a10_ccu_lcdxch0_set_rate(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk * clk, u_int rate, int unit)
+{
+       int parent_index;
+       struct clk *clkp;
+       int error;
+
+       parent_index = (unit == 0) ? A10_CLK_PLL_VIDEO0 : A10_CLK_PLL_VIDEO1;
+       clkp = &sun4i_a10_ccu_clks[parent_index].base;
+       error = clk_set_rate(clkp, rate);
+       if (error) {
+               error = clk_set_rate(clkp, rate / 2);
+               if (error != 0)
+                       return error;
+               parent_index =
+                   (unit == 0) ? A10_CLK_PLL_VIDEO0_2X : A10_CLK_PLL_VIDEO1_2X;
+               clkp = &sun4i_a10_ccu_clks[parent_index].base;
+       }



Home | Main Index | Thread Index | Old Index