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/c55737ecc468
branches: trunk
changeset: 831478:c55737ecc468
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 c037e0ec7aa2 -r c55737ecc468 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 c037e0ec7aa2 -r c55737ecc468 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