Module Name: src Committed By: martin Date: Mon Nov 25 16:18:41 UTC 2019
Modified Files: src/sys/arch/arm/dts [netbsd-9]: sun50i-a64-pinebook.dts src/sys/arch/arm/sunxi [netbsd-9]: sun50i_a64_ccu.c sunxi_ccu.h sunxi_ccu_fractional.c sunxi_dwhdmi.c sunxi_hdmiphy.c sunxi_hdmiphy.h sunxi_lcdc.c sunxi_mixer.c sunxi_platform.c src/sys/dev/fdt [netbsd-9]: fdt_port.c src/sys/dev/ic [netbsd-9]: dw_hdmi.c dw_hdmi.h Log Message: Pull up following revision(s) (requested by jmcneill in ticket #470): sys/arch/arm/sunxi/sunxi_hdmiphy.c: revision 1.4 sys/arch/arm/sunxi/sun50i_a64_ccu.c: revision 1.16 sys/dev/ic/dw_hdmi.c: revision 1.5 sys/arch/arm/sunxi/sunxi_hdmiphy.h: revision 1.2 sys/arch/arm/sunxi/sun50i_a64_ccu.c: revision 1.17 sys/dev/ic/dw_hdmi.c: revision 1.6 sys/arch/arm/sunxi/sun50i_a64_ccu.c: revision 1.18 sys/arch/arm/sunxi/sun50i_a64_ccu.c: revision 1.19 sys/dev/ic/dw_hdmi.h: revision 1.5 sys/arch/arm/sunxi/sunxi_mixer.c: revision 1.8 sys/arch/arm/sunxi/sunxi_mixer.c: revision 1.9 sys/arch/arm/sunxi/sunxi_ccu.h: revision 1.22 sys/arch/arm/sunxi/sunxi_dwhdmi.c: revision 1.5 sys/arch/arm/sunxi/sunxi_dwhdmi.c: revision 1.6 sys/arch/arm/sunxi/sunxi_dwhdmi.c: revision 1.7 sys/arch/arm/sunxi/sunxi_dwhdmi.c: revision 1.8 sys/arch/arm/sunxi/sun50i_a64_ccu.c: revision 1.20 sys/arch/arm/sunxi/sunxi_mixer.c: revision 1.10 sys/arch/arm/dts/sun50i-a64-pinebook.dts: revision 1.17 sys/arch/arm/sunxi/sunxi_platform.c: revision 1.38 sys/dev/fdt/fdt_port.c: revision 1.3 sys/dev/fdt/fdt_port.c: revision 1.4 sys/arch/arm/sunxi/sunxi_ccu_fractional.c: revision 1.5 sys/arch/arm/sunxi/sunxi_lcdc.c: revision 1.7 sys/arch/arm/sunxi/sunxi_ccu_fractional.c: revision 1.6 sys/arch/arm/sunxi/sunxi_hdmiphy.c: revision 1.3 Fix CLK_BUS_HDMI bit Enable TMDS clock Store the flags passed to SUNXI_CCU_FRACTIONAL macro. Previously the macro dropped the flags argument entirely, and did not initialize the structure with it. Allow bus glue to setup DDC clocks Add TCON0 clock HDMI PHY and TX share the same clocks. Do not enable clocks until both reset resources have been deasserted. Explicitly set DDC clock dividers. Honour SUNXI_CCU_FRACTIONAL_SET_ENABLE in fractional mode Use fdtbus_get_reg to read "reg" property Need to initialize the PHY before HPD sense and DDC will work Set pixel clock on mode set Set TCON1 parent to PLL_VIDEO1(1X) Do not assume that an fb's pitch is width * 4 bytes. Use actual hw mode, not proposed mode. Set pre-divider M to 0 in fractional mode, as noted in user manual. Spotted by jak. Support non-zero fb start pixels. Set video PLLs to 297MHz Do not assume the cursor pitch is the same as the primary fb Enable HDMI and HDMI audio Try to avoid changing hardware settings when the "nomodeset" kernel arg is present. To generate a diff of this commit: cvs rdiff -u -r1.16 -r1.16.2.1 src/sys/arch/arm/dts/sun50i-a64-pinebook.dts cvs rdiff -u -r1.13.2.2 -r1.13.2.3 src/sys/arch/arm/sunxi/sun50i_a64_ccu.c cvs rdiff -u -r1.21 -r1.21.4.1 src/sys/arch/arm/sunxi/sunxi_ccu.h cvs rdiff -u -r1.4 -r1.4.4.1 src/sys/arch/arm/sunxi/sunxi_ccu_fractional.c cvs rdiff -u -r1.3.6.1 -r1.3.6.2 src/sys/arch/arm/sunxi/sunxi_dwhdmi.c cvs rdiff -u -r1.2 -r1.2.6.1 src/sys/arch/arm/sunxi/sunxi_hdmiphy.c cvs rdiff -u -r1.1 -r1.1.6.1 src/sys/arch/arm/sunxi/sunxi_hdmiphy.h cvs rdiff -u -r1.6 -r1.6.2.1 src/sys/arch/arm/sunxi/sunxi_lcdc.c cvs rdiff -u -r1.7 -r1.7.6.1 src/sys/arch/arm/sunxi/sunxi_mixer.c cvs rdiff -u -r1.37 -r1.37.2.1 src/sys/arch/arm/sunxi/sunxi_platform.c cvs rdiff -u -r1.2 -r1.2.4.1 src/sys/dev/fdt/fdt_port.c cvs rdiff -u -r1.1.6.1 -r1.1.6.2 src/sys/dev/ic/dw_hdmi.c \ src/sys/dev/ic/dw_hdmi.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/dts/sun50i-a64-pinebook.dts diff -u src/sys/arch/arm/dts/sun50i-a64-pinebook.dts:1.16 src/sys/arch/arm/dts/sun50i-a64-pinebook.dts:1.16.2.1 --- src/sys/arch/arm/dts/sun50i-a64-pinebook.dts:1.16 Thu Jun 6 23:19:45 2019 +++ src/sys/arch/arm/dts/sun50i-a64-pinebook.dts Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sun50i-a64-pinebook.dts,v 1.16 2019/06/06 23:19:45 jmcneill Exp $ */ +/* $NetBSD: sun50i-a64-pinebook.dts,v 1.16.2.1 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2017-2019 Jared McNeill <jmcne...@invisible.ca> @@ -54,6 +54,17 @@ sound_spdif { status = "disabled"; }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "c"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; }; &cpu0 { @@ -151,3 +162,28 @@ }; }; }; + +®_dldo1 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-hdmi"; +}; + +&hdmi { + hvcc-supply = <®_dldo1>; + status = "okay"; +}; + +&hdmi_out { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&i2s2 { + status = "okay"; +}; + +&sound_hdmi { + status = "okay"; +}; Index: src/sys/arch/arm/sunxi/sun50i_a64_ccu.c diff -u src/sys/arch/arm/sunxi/sun50i_a64_ccu.c:1.13.2.2 src/sys/arch/arm/sunxi/sun50i_a64_ccu.c:1.13.2.3 --- src/sys/arch/arm/sunxi/sun50i_a64_ccu.c:1.13.2.2 Mon Nov 18 19:36:03 2019 +++ src/sys/arch/arm/sunxi/sun50i_a64_ccu.c Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sun50i_a64_ccu.c,v 1.13.2.2 2019/11/18 19:36:03 martin Exp $ */ +/* $NetBSD: sun50i_a64_ccu.c,v 1.13.2.3 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -28,7 +28,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: sun50i_a64_ccu.c,v 1.13.2.2 2019/11/18 19:36:03 martin Exp $"); +__KERNEL_RCSID(1, "$NetBSD: sun50i_a64_ccu.c,v 1.13.2.3 2019/11/25 16:18:40 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -69,6 +69,7 @@ __KERNEL_RCSID(1, "$NetBSD: sun50i_a64_c #define DRAM_CFG_REG 0x0f4 #define MBUS_RST_REG 0x0fc #define DE_CLK_REG 0x104 +#define TCON0_CLK_REG 0x118 #define TCON1_CLK_REG 0x11c #define AC_DIG_CLK_REG 0x140 #define HDMI_CLK_REG 0x150 @@ -161,6 +162,7 @@ static const char *de_parents[] = { "pll static const char *hdmi_parents[] = { "pll_video0", "pll_video1" }; static const char *i2s_parents[] = { "pll_audio_8x", "pll_audio_4x", "pll_audio_2x", "pll_audio" }; static const char *spi_parents[] = { "hosc", "pll_periph0", "pll_periph1", NULL }; +static const char *tcon0_parents[] = { "pll_mipi", NULL, "pll_video0_2x", NULL }; static const char *tcon1_parents[] = { "pll_video0", NULL, "pll_video1", NULL }; static const char *gpu_parents[] = { "pll_gpu" }; @@ -459,6 +461,13 @@ static struct sunxi_ccu_clk sun50i_a64_c __BIT(31), /* enable */ SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN), + SUNXI_CCU_DIV_GATE(A64_CLK_TCON0, "tcon0", tcon0_parents, + TCON0_CLK_REG, /* reg */ + 0, /* div */ + __BITS(26,24), /* sel */ + __BIT(31), /* enable */ + 0), + SUNXI_CCU_DIV_GATE(A64_CLK_TCON1, "tcon1", tcon1_parents, TCON1_CLK_REG, /* reg */ __BITS(3,0), /* div */ @@ -521,7 +530,7 @@ static struct sunxi_ccu_clk sun50i_a64_c SUNXI_CCU_GATE(A64_CLK_BUS_CSI, "bus-csi", "ahb1", BUS_CLK_GATING_REG1, 8), SUNXI_CCU_GATE(A64_CLK_BUS_HDMI, "bus-hdmi", "ahb1", - BUS_CLK_GATING_REG1, 10), + BUS_CLK_GATING_REG1, 11), SUNXI_CCU_GATE(A64_CLK_BUS_DE, "bus-de", "ahb1", BUS_CLK_GATING_REG1, 12), SUNXI_CCU_GATE(A64_CLK_BUS_GPU, "bus-gpu", "ahb1", @@ -592,6 +601,8 @@ sun50i_a64_ccu_attach(device_t parent, d { struct sunxi_ccu_softc * const sc = device_private(self); struct fdt_attach_args * const faa = aux; + prop_dictionary_t prop = device_properties(self); + bool nomodeset; sc->sc_dev = self; sc->sc_phandle = faa->faa_phandle; @@ -609,9 +620,23 @@ sun50i_a64_ccu_attach(device_t parent, d aprint_naive("\n"); aprint_normal(": A64 CCU\n"); - /* Set DE parent to PLL_DE */ - clk_set_parent(&sc->sc_clks[A64_CLK_DE].base, &sc->sc_clks[A64_CLK_PLL_DE].base); - clk_set_rate(&sc->sc_clks[A64_CLK_PLL_DE].base, 420000000); + nomodeset = false; + prop_dictionary_get_bool(prop, "nomodeset", &nomodeset); + if (!nomodeset) { + /* Set DE parent to PLL_DE */ + clk_set_parent(&sc->sc_clks[A64_CLK_DE].base, &sc->sc_clks[A64_CLK_PLL_DE].base); + clk_set_rate(&sc->sc_clks[A64_CLK_PLL_DE].base, 420000000); + + /* Set video PLLs to 297 MHz */ + clk_set_rate(&sc->sc_clks[A64_CLK_PLL_VIDEO0].base, 297000000); + clk_set_rate(&sc->sc_clks[A64_CLK_PLL_VIDEO1].base, 297000000); + + /* Set TCON1 parent to PLL_VIDEO1(1X) */ + clk_set_parent(&sc->sc_clks[A64_CLK_TCON1].base, &sc->sc_clks[A64_CLK_PLL_VIDEO1].base); + + /* Set HDMI parent to PLL_VIDEO1(1X) */ + clk_set_parent(&sc->sc_clks[A64_CLK_HDMI].base, &sc->sc_clks[A64_CLK_PLL_VIDEO1].base); + } sunxi_ccu_print(sc); } Index: src/sys/arch/arm/sunxi/sunxi_ccu.h diff -u src/sys/arch/arm/sunxi/sunxi_ccu.h:1.21 src/sys/arch/arm/sunxi/sunxi_ccu.h:1.21.4.1 --- src/sys/arch/arm/sunxi/sunxi_ccu.h:1.21 Wed Jan 30 01:24:00 2019 +++ src/sys/arch/arm/sunxi/sunxi_ccu.h Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_ccu.h,v 1.21 2019/01/30 01:24:00 jmcneill Exp $ */ +/* $NetBSD: sunxi_ccu.h,v 1.21.4.1 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -405,6 +405,7 @@ const char *sunxi_ccu_fractional_get_par .u.fractional.frac[0] = (_frac0), \ .u.fractional.frac[1] = (_frac1), \ .u.fractional.enable = (_enable), \ + .u.fractional.flags = (_flags), \ .enable = sunxi_ccu_fractional_enable, \ .get_rate = sunxi_ccu_fractional_get_rate, \ .set_rate = sunxi_ccu_fractional_set_rate, \ Index: src/sys/arch/arm/sunxi/sunxi_ccu_fractional.c diff -u src/sys/arch/arm/sunxi/sunxi_ccu_fractional.c:1.4 src/sys/arch/arm/sunxi/sunxi_ccu_fractional.c:1.4.4.1 --- src/sys/arch/arm/sunxi/sunxi_ccu_fractional.c:1.4 Wed Jan 30 01:24:00 2019 +++ src/sys/arch/arm/sunxi/sunxi_ccu_fractional.c Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_ccu_fractional.c,v 1.4 2019/01/30 01:24:00 jmcneill Exp $ */ +/* $NetBSD: sunxi_ccu_fractional.c,v 1.4.4.1 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_fractional.c,v 1.4 2019/01/30 01:24:00 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_fractional.c,v 1.4.4.1 2019/11/25 16:18:40 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -137,9 +137,12 @@ sunxi_ccu_fractional_set_rate(struct sun for (i = 0; i < __arraycount(fractional->frac); i++) { if (fractional->frac[i] == new_rate) { + val &= ~fractional->prediv; val &= ~fractional->div_en; val &= ~fractional->frac_sel; val |= __SHIFTIN(i, fractional->frac_sel); + if (fractional->flags & SUNXI_CCU_FRACTIONAL_SET_ENABLE) + val |= fractional->enable; CCU_WRITE(sc, fractional->reg, val); return 0; } Index: src/sys/arch/arm/sunxi/sunxi_dwhdmi.c diff -u src/sys/arch/arm/sunxi/sunxi_dwhdmi.c:1.3.6.1 src/sys/arch/arm/sunxi/sunxi_dwhdmi.c:1.3.6.2 --- src/sys/arch/arm/sunxi/sunxi_dwhdmi.c:1.3.6.1 Mon Nov 18 19:31:00 2019 +++ src/sys/arch/arm/sunxi/sunxi_dwhdmi.c Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_dwhdmi.c,v 1.3.6.1 2019/11/18 19:31:00 martin Exp $ */ +/* $NetBSD: sunxi_dwhdmi.c,v 1.3.6.2 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_dwhdmi.c,v 1.3.6.1 2019/11/18 19:31:00 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_dwhdmi.c,v 1.3.6.2 2019/11/25 16:18:40 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -62,6 +62,7 @@ struct sunxi_dwhdmi_softc { int sc_phandle; struct fdtbus_phy *sc_phy; struct fdtbus_regulator *sc_regulator; + struct clk *sc_clk; struct fdt_device_ports sc_ports; struct drm_display_mode sc_curmode; @@ -101,13 +102,6 @@ sunxi_dwhdmi_ep_activate(device_t dev, s if (encoder == NULL) return EINVAL; - sc->sc_phy = fdtbus_phy_get(sc->sc_phandle, "hdmi-phy"); - if (sc->sc_phy == NULL) { - device_printf(dev, "couldn't find hdmi-phy\n"); - return ENXIO; - } - - sc->sc_regulator = fdtbus_regulator_acquire(sc->sc_phandle, "hvcc-supply"); if (sc->sc_regulator != NULL) { error = fdtbus_regulator_enable(sc->sc_regulator); if (error != 0) { @@ -193,6 +187,15 @@ sunxi_dwhdmi_mode_set(struct dwhdmi_soft struct drm_display_mode *adjusted_mode) { struct sunxi_dwhdmi_softc * const sc = to_sunxi_dwhdmi_softc(dsc); + int error; + + if (sc->sc_clk != NULL) { + error = clk_set_rate(sc->sc_clk, adjusted_mode->clock * 1000); + if (error != 0) + device_printf(sc->sc_base.sc_dev, + "couldn't set pixel clock to %u Hz: %d\n", + adjusted_mode->clock * 1000, error); + } sc->sc_curmode = *adjusted_mode; } @@ -225,20 +228,22 @@ sunxi_dwhdmi_attach(device_t parent, dev { struct sunxi_dwhdmi_softc * const sc = device_private(self); struct fdt_attach_args * const faa = aux; + prop_dictionary_t prop = device_properties(self); const int phandle = faa->faa_phandle; - struct clk *clk_iahb, *clk_isfr; + struct clk *clk_iahb, *clk_isfr, *clk_tmds; struct fdtbus_reset *rst; + bool is_disabled; bus_addr_t addr; bus_size_t size; - if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { - aprint_error(": couldn't get registers\n"); + if (prop_dictionary_get_bool(prop, "disabled", &is_disabled) && is_disabled) { + aprint_naive("\n"); + aprint_normal(": HDMI TX (disabled)\n"); return; } - rst = fdtbus_reset_get(phandle, "ctrl"); - if (rst == NULL || fdtbus_reset_deassert(rst) != 0) { - aprint_error(": couldn't de-assert reset\n"); + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); return; } @@ -254,6 +259,12 @@ sunxi_dwhdmi_attach(device_t parent, dev return; } + clk_tmds = fdtbus_clock_get(phandle, "tmds"); + if (clk_tmds == NULL || clk_enable(clk_tmds) != 0) { + aprint_error(": couldn't enable tmds clock\n"); + return; + } + sc->sc_base.sc_dev = self; sc->sc_base.sc_reg_width = 1; sc->sc_base.sc_bst = faa->faa_bst; @@ -265,11 +276,32 @@ sunxi_dwhdmi_attach(device_t parent, dev sc->sc_base.sc_enable = sunxi_dwhdmi_enable; sc->sc_base.sc_disable = sunxi_dwhdmi_disable; sc->sc_base.sc_mode_set = sunxi_dwhdmi_mode_set; + sc->sc_base.sc_scl_hcnt = 0xd8; + sc->sc_base.sc_scl_lcnt = 0xfe; sc->sc_phandle = faa->faa_phandle; + sc->sc_clk = clk_tmds; aprint_naive("\n"); aprint_normal(": HDMI TX\n"); + sc->sc_regulator = fdtbus_regulator_acquire(sc->sc_phandle, "hvcc-supply"); + + sc->sc_phy = fdtbus_phy_get(sc->sc_phandle, "hdmi-phy"); + if (sc->sc_phy == NULL) + sc->sc_phy = fdtbus_phy_get(sc->sc_phandle, "phy"); + if (sc->sc_phy == NULL) { + device_printf(self, "couldn't find PHY\n"); + return; + } + + rst = fdtbus_reset_get(phandle, "ctrl"); + if (rst == NULL || fdtbus_reset_deassert(rst) != 0) { + aprint_error_dev(self, "couldn't de-assert reset\n"); + return; + } + + sunxi_hdmiphy_init(sc->sc_phy); + if (dwhdmi_attach(&sc->sc_base) != 0) { aprint_error_dev(self, "failed to attach driver\n"); return; Index: src/sys/arch/arm/sunxi/sunxi_hdmiphy.c diff -u src/sys/arch/arm/sunxi/sunxi_hdmiphy.c:1.2 src/sys/arch/arm/sunxi/sunxi_hdmiphy.c:1.2.6.1 --- src/sys/arch/arm/sunxi/sunxi_hdmiphy.c:1.2 Thu Jan 31 01:49:28 2019 +++ src/sys/arch/arm/sunxi/sunxi_hdmiphy.c Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_hdmiphy.c,v 1.2 2019/01/31 01:49:28 jmcneill Exp $ */ +/* $NetBSD: sunxi_hdmiphy.c,v 1.2.6.1 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2019 Jared McNeill <jmcne...@invisible.ca> @@ -28,7 +28,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_hdmiphy.c,v 1.2 2019/01/31 01:49:28 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_hdmiphy.c,v 1.2.6.1 2019/11/25 16:18:40 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -128,6 +128,9 @@ struct sunxi_hdmiphy_softc { const struct sunxi_hdmiphy_data *sc_data; + struct fdtbus_reset *sc_rst; + struct clk *sc_clk_bus; + struct clk *sc_clk_mod; struct clk *sc_clk_pll0; u_int sc_rcalib; @@ -171,14 +174,6 @@ sunxi_hdmiphy_release(device_t dev, void static int sunxi_hdmiphy_enable(device_t dev, void *priv, bool enable) { - struct sunxi_hdmiphy_softc * const sc = priv; - - if (enable) { - sc->sc_data->init(sc); - } else { - sc->sc_data->config(sc, 0); - } - return 0; } @@ -419,26 +414,15 @@ sunxi_hdmiphy_attach(device_t parent, de } rst = fdtbus_reset_get(phandle, "phy"); - if (rst == NULL || fdtbus_reset_deassert(rst) != 0) { - aprint_error(": couldn't de-assert reset\n"); + if (rst == NULL) { + aprint_error(": couldn't get reset\n"); return; } - clk_bus = fdtbus_clock_get(phandle, "bus"); - if (clk_bus == NULL || clk_enable(clk_bus) != 0) { - aprint_error(": couldn't enable bus clock\n"); - return; - } - clk_mod = fdtbus_clock_get(phandle, "mod"); - if (clk_mod == NULL || clk_enable(clk_mod) != 0) { - aprint_error(": couldn't enable mod clock\n"); - return; - } - clk_pll0 = fdtbus_clock_get(phandle, "pll-0"); - if (clk_pll0 == NULL || clk_enable(clk_pll0) != 0) { - aprint_error(": couldn't enable pll-0 clock\n"); + if (clk_bus == NULL || clk_mod == NULL || clk_pll0 == NULL) { + aprint_error(": couldn't get clocks\n"); return; } @@ -449,12 +433,30 @@ sunxi_hdmiphy_attach(device_t parent, de aprint_error(": couldn't map registers\n"); return; } + sc->sc_rst = rst; + sc->sc_clk_bus = clk_bus; + sc->sc_clk_mod = clk_mod; sc->sc_clk_pll0 = clk_pll0; aprint_naive("\n"); aprint_normal(": HDMI PHY\n"); fdtbus_register_phy_controller(self, phandle, &sunxi_hdmiphy_funcs); +} + +void +sunxi_hdmiphy_init(struct fdtbus_phy *phy) +{ + device_t dev = fdtbus_phy_device(phy); + struct sunxi_hdmiphy_softc * const sc = device_private(dev); + + clk_enable(sc->sc_clk_bus); + clk_enable(sc->sc_clk_mod); + clk_enable(sc->sc_clk_pll0); + + fdtbus_reset_deassert(sc->sc_rst); + + sc->sc_data->init(sc); PHY_WRITE(sc, READ_EN, READ_EN_MAGIC); PHY_WRITE(sc, UNSCRAMBLE, UNSCRAMBLE_MAGIC); Index: src/sys/arch/arm/sunxi/sunxi_hdmiphy.h diff -u src/sys/arch/arm/sunxi/sunxi_hdmiphy.h:1.1 src/sys/arch/arm/sunxi/sunxi_hdmiphy.h:1.1.6.1 --- src/sys/arch/arm/sunxi/sunxi_hdmiphy.h:1.1 Wed Jan 30 01:24:00 2019 +++ src/sys/arch/arm/sunxi/sunxi_hdmiphy.h Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_hdmiphy.h,v 1.1 2019/01/30 01:24:00 jmcneill Exp $ */ +/* $NetBSD: sunxi_hdmiphy.h,v 1.1.6.1 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2019 Jared McNeill <jmcne...@invisible.ca> @@ -32,6 +32,7 @@ #include <drm/drmP.h> #include <drm/drm_modes.h> +void sunxi_hdmiphy_init(struct fdtbus_phy *); int sunxi_hdmiphy_config(struct fdtbus_phy *, struct drm_display_mode *); bool sunxi_hdmiphy_detect(struct fdtbus_phy *, bool); Index: src/sys/arch/arm/sunxi/sunxi_lcdc.c diff -u src/sys/arch/arm/sunxi/sunxi_lcdc.c:1.6 src/sys/arch/arm/sunxi/sunxi_lcdc.c:1.6.2.1 --- src/sys/arch/arm/sunxi/sunxi_lcdc.c:1.6 Sat Jul 6 00:23:38 2019 +++ src/sys/arch/arm/sunxi/sunxi_lcdc.c Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_lcdc.c,v 1.6 2019/07/06 00:23:38 jmcneill Exp $ */ +/* $NetBSD: sunxi_lcdc.c,v 1.6.2.1 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_lcdc.c,v 1.6 2019/07/06 00:23:38 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_lcdc.c,v 1.6.2.1 2019/11/25 16:18:40 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -81,7 +81,7 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_lcdc.c #define TCON1_CTL_REG 0x090 #define TCON1_CTL_TCON1_EN __BIT(31) #define TCON1_CTL_START_DELAY __BITS(8,4) -#define TCON1_CTL_TCON1_SRC_SEL __BIT(1) +#define TCON1_CTL_TCON1_SRC_SEL __BITS(1,0) #define TCON1_BASIC0_REG 0x094 #define TCON1_BASIC1_REG 0x098 #define TCON1_BASIC2_REG 0x09c @@ -185,6 +185,7 @@ sunxi_lcdc_tcon0_prepare(struct drm_enco val = TCON_READ(sc, TCON_GCTL_REG); val |= TCON_GCTL_TCON_EN; + val &= ~TCON_GCTL_IO_MAP_SEL; TCON_WRITE(sc, TCON_GCTL_REG, val); TCON_WRITE(sc, TCON0_IO_TRI_REG, 0); @@ -215,20 +216,20 @@ sunxi_lcdc_tcon0_commit(struct drm_encod int error; const u_int interlace_p = (mode->flags & DRM_MODE_FLAG_INTERLACE) != 0; - const u_int hspw = mode->hsync_end - mode->hsync_start; - const u_int hbp = mode->htotal - mode->hsync_start; - const u_int vspw = mode->vsync_end - mode->vsync_start; - const u_int vbp = mode->vtotal - mode->vsync_start; - const u_int vblank_len = (mode->vtotal - mode->vdisplay) >> interlace_p; + const u_int hspw = mode->crtc_hsync_end - mode->crtc_hsync_start; + const u_int hbp = mode->crtc_htotal - mode->crtc_hsync_start; + const u_int vspw = mode->crtc_vsync_end - mode->crtc_vsync_start; + const u_int vbp = mode->crtc_vtotal - mode->crtc_vsync_start; + const u_int vblank_len = (mode->crtc_vtotal - mode->crtc_vdisplay) >> interlace_p; const u_int start_delay = uimin(vblank_len, 30); val = TCON0_CTL_TCON0_EN | __SHIFTIN(start_delay, TCON0_CTL_START_DELAY); TCON_WRITE(sc, TCON0_CTL_REG, val); - TCON_WRITE(sc, TCON0_BASIC0_REG, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - TCON_WRITE(sc, TCON0_BASIC1_REG, ((mode->htotal - 1) << 16) | (hbp - 1)); - TCON_WRITE(sc, TCON0_BASIC2_REG, ((mode->vtotal * 2) << 16) | (vbp - 1)); + TCON_WRITE(sc, TCON0_BASIC0_REG, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); + TCON_WRITE(sc, TCON0_BASIC1_REG, ((mode->crtc_htotal - 1) << 16) | (hbp - 1)); + TCON_WRITE(sc, TCON0_BASIC2_REG, ((mode->crtc_vtotal * 2) << 16) | (vbp - 1)); TCON_WRITE(sc, TCON0_BASIC3_REG, ((hspw - 1) << 16) | (vspw - 1)); val = TCON_READ(sc, TCON0_IO_POL_REG); @@ -268,24 +269,22 @@ sunxi_lcdc_tcon1_commit(struct drm_encod int error; const u_int interlace_p = (mode->flags & DRM_MODE_FLAG_INTERLACE) != 0; - const u_int hspw = mode->hsync_end - mode->hsync_start; - const u_int hbp = mode->htotal - mode->hsync_start; - const u_int vspw = mode->vsync_end - mode->vsync_start; - const u_int vbp = mode->vtotal - mode->vsync_start; - const u_int vblank_len = - ((mode->vtotal << interlace_p) >> 1) - mode->vdisplay - 2; - const u_int start_delay = - vblank_len >= 32 ? 30 : vblank_len - 2; + const u_int hspw = mode->crtc_hsync_end - mode->crtc_hsync_start; + const u_int hbp = mode->crtc_htotal - mode->crtc_hsync_start; + const u_int vspw = mode->crtc_vsync_end - mode->crtc_vsync_start; + const u_int vbp = mode->crtc_vtotal - mode->crtc_vsync_start; + const u_int vblank_len = ((mode->crtc_vtotal - mode->crtc_vdisplay) >> interlace_p) - 2; + const u_int start_delay = uimin(vblank_len, 30); val = TCON1_CTL_TCON1_EN | __SHIFTIN(start_delay, TCON1_CTL_START_DELAY); TCON_WRITE(sc, TCON1_CTL_REG, val); - TCON_WRITE(sc, TCON1_BASIC0_REG, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - TCON_WRITE(sc, TCON1_BASIC1_REG, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - TCON_WRITE(sc, TCON1_BASIC2_REG, ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1)); - TCON_WRITE(sc, TCON1_BASIC3_REG, ((mode->htotal - 1) << 16) | (hbp - 1)); - TCON_WRITE(sc, TCON1_BASIC4_REG, ((mode->vtotal * 2) << 16) | (vbp - 1)); + TCON_WRITE(sc, TCON1_BASIC0_REG, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); + TCON_WRITE(sc, TCON1_BASIC1_REG, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); + TCON_WRITE(sc, TCON1_BASIC2_REG, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1)); + TCON_WRITE(sc, TCON1_BASIC3_REG, ((mode->crtc_htotal - 1) << 16) | (hbp - 1)); + TCON_WRITE(sc, TCON1_BASIC4_REG, ((mode->crtc_vtotal * 2) << 16) | (vbp - 1)); TCON_WRITE(sc, TCON1_BASIC5_REG, ((hspw - 1) << 16) | (vspw - 1)); TCON_WRITE(sc, TCON_GINT1_REG, Index: src/sys/arch/arm/sunxi/sunxi_mixer.c diff -u src/sys/arch/arm/sunxi/sunxi_mixer.c:1.7 src/sys/arch/arm/sunxi/sunxi_mixer.c:1.7.6.1 --- src/sys/arch/arm/sunxi/sunxi_mixer.c:1.7 Sat Feb 16 16:20:50 2019 +++ src/sys/arch/arm/sunxi/sunxi_mixer.c Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_mixer.c,v 1.7 2019/02/16 16:20:50 jmcneill Exp $ */ +/* $NetBSD: sunxi_mixer.c,v 1.7.6.1 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.c,v 1.7 2019/02/16 16:20:50 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_mixer.c,v 1.7.6.1 2019/11/25 16:18:40 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -252,9 +252,15 @@ sunxi_mixer_mode_do_set_base(struct drm_ uint64_t paddr = (uint64_t)sfb->obj->dmamap->dm_segs[0].ds_addr; + paddr += y * sfb->base.pitches[0]; + paddr += x * drm_format_plane_cpp(sfb->base.pixel_format, 0); + uint32_t haddr = (paddr >> 32) & OVL_UI_TOP_HADD_LAYER0; uint32_t laddr = paddr & 0xffffffff; + /* Set UI overlay line size */ + OVL_UI_WRITE(sc, 0, OVL_UI_PITCH(0), sfb->base.pitches[0]); + /* Framebuffer start address */ val = OVL_UI_READ(sc, 0, OVL_UI_TOP_HADD); val &= ~OVL_UI_TOP_HADD_LAYER0; @@ -458,7 +464,6 @@ sunxi_mixer_mode_set(struct drm_crtc *cr const uint32_t size = ((adjusted_mode->vdisplay - 1) << 16) | (adjusted_mode->hdisplay - 1); - const uint32_t offset = (y << 16) | x; /* Set global size */ GLB_WRITE(sc, GLB_SIZE, size); @@ -471,7 +476,7 @@ sunxi_mixer_mode_set(struct drm_crtc *cr /* Set blender 0 input size */ BLD_WRITE(sc, BLD_CH_ISIZE(0), size); /* Set blender 0 offset */ - BLD_WRITE(sc, BLD_CH_OFFSET(0), offset); + BLD_WRITE(sc, BLD_CH_OFFSET(0), 0); /* Route channel 1 to pipe 0 */ val = BLD_READ(sc, BLD_CH_RTCTL); val &= ~BLD_CH_RTCTL_P0; @@ -490,9 +495,7 @@ sunxi_mixer_mode_set(struct drm_crtc *cr /* Set UI overlay layer size */ OVL_UI_WRITE(sc, 0, OVL_UI_MBSIZE(0), size); /* Set UI overlay offset */ - OVL_UI_WRITE(sc, 0, OVL_UI_COOR(0), offset); - /* Set UI overlay line size */ - OVL_UI_WRITE(sc, 0, OVL_UI_PITCH(0), adjusted_mode->hdisplay * 4); + OVL_UI_WRITE(sc, 0, OVL_UI_COOR(0), 0); /* Set UI overlay window size */ OVL_UI_WRITE(sc, 0, OVL_UI_SIZE, size); Index: src/sys/arch/arm/sunxi/sunxi_platform.c diff -u src/sys/arch/arm/sunxi/sunxi_platform.c:1.37 src/sys/arch/arm/sunxi/sunxi_platform.c:1.37.2.1 --- src/sys/arch/arm/sunxi/sunxi_platform.c:1.37 Mon Jun 17 05:27:01 2019 +++ src/sys/arch/arm/sunxi/sunxi_platform.c Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_platform.c,v 1.37 2019/06/17 05:27:01 mrg Exp $ */ +/* $NetBSD: sunxi_platform.c,v 1.37.2.1 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -31,7 +31,7 @@ #include "opt_console.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.37 2019/06/17 05:27:01 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.37.2.1 2019/11/25 16:18:40 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -230,11 +230,17 @@ sunxi_platform_device_register(device_t } } - if (device_is_a(self, "sunxidrm")) { + if (device_is_a(self, "sunxidrm") || device_is_a(self, "dwhdmi")) { if (get_bootconf_option(boot_args, "nomodeset", BOOTOPT_TYPE_BOOLEAN, &val)) if (val) prop_dictionary_set_bool(prop, "disabled", true); } + + if (device_is_a(self, "sun50ia64ccu0")) { + if (get_bootconf_option(boot_args, "nomodeset", BOOTOPT_TYPE_BOOLEAN, &val)) + if (val) + prop_dictionary_set_bool(prop, "nomodeset", true); + } } static u_int Index: src/sys/dev/fdt/fdt_port.c diff -u src/sys/dev/fdt/fdt_port.c:1.2 src/sys/dev/fdt/fdt_port.c:1.2.4.1 --- src/sys/dev/fdt/fdt_port.c:1.2 Wed Jan 30 01:24:00 2019 +++ src/sys/dev/fdt/fdt_port.c Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: fdt_port.c,v 1.2 2019/01/30 01:24:00 jmcneill Exp $ */ +/* $NetBSD: fdt_port.c,v 1.2.4.1 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2018 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: fdt_port.c,v 1.2 2019/01/30 01:24:00 jmcneill Exp $"); +__KERNEL_RCSID(1, "$NetBSD: fdt_port.c,v 1.2.4.1 2019/11/25 16:18:40 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -257,7 +257,7 @@ fdt_ports_register(struct fdt_device_por int port_phandle, child; int i; char buf[20]; - uint64_t id; + bus_addr_t id; ports->dp_dev = self; SLIST_INSERT_HEAD(&fdt_port_devices, ports, dp_list); @@ -296,7 +296,7 @@ again: } if (strcmp(buf, "port") != 0) continue; - if (fdtbus_get_reg64(child, 0, &id, NULL) != 0) { + if (fdtbus_get_reg(child, 0, &id, NULL) != 0) { if (ports->dp_nports > 1) aprint_error_dev(self, "%s: missing reg property", Index: src/sys/dev/ic/dw_hdmi.c diff -u src/sys/dev/ic/dw_hdmi.c:1.1.6.1 src/sys/dev/ic/dw_hdmi.c:1.1.6.2 --- src/sys/dev/ic/dw_hdmi.c:1.1.6.1 Sat Nov 16 16:48:25 2019 +++ src/sys/dev/ic/dw_hdmi.c Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: dw_hdmi.c,v 1.1.6.1 2019/11/16 16:48:25 martin Exp $ */ +/* $NetBSD: dw_hdmi.c,v 1.1.6.2 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dw_hdmi.c,v 1.1.6.1 2019/11/16 16:48:25 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dw_hdmi.c,v 1.1.6.2 2019/11/25 16:18:40 martin Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -239,6 +239,8 @@ __KERNEL_RCSID(0, "$NetBSD: dw_hdmi.c,v #define HDMI_I2CM_SOFTRSTZ 0x7e09 #define HDMI_I2CM_SOFTRSTZ_I2C_SOFTRST __BIT(0) #define HDMI_I2CM_SEGPTR 0x7e0a +#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR 0x730c +#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR 0x730e enum dwhdmi_dai_mixer_ctrl { DWHDMI_DAI_OUTPUT_CLASS, @@ -291,6 +293,10 @@ dwhdmi_ddc_exec(void *priv, i2c_op_t op, dwhdmi_write(sc, HDMI_I2CM_SOFTRSTZ, 0); dwhdmi_write(sc, HDMI_IH_I2CM_STAT0, dwhdmi_read(sc, HDMI_IH_I2CM_STAT0)); + if (sc->sc_scl_hcnt) + dwhdmi_write(sc, HDMI_I2CM_SS_SCL_HCNT_0_ADDR, sc->sc_scl_hcnt); + if (sc->sc_scl_lcnt) + dwhdmi_write(sc, HDMI_I2CM_SS_SCL_LCNT_0_ADDR, sc->sc_scl_lcnt); dwhdmi_write(sc, HDMI_I2CM_DIV, 0); dwhdmi_write(sc, HDMI_I2CM_SLAVE, DDC_ADDR); dwhdmi_write(sc, HDMI_I2CM_SEGADDR, DDC_SEGMENT_ADDR); @@ -299,6 +305,8 @@ dwhdmi_ddc_exec(void *priv, i2c_op_t op, operation = block ? HDMI_I2CM_OPERATION_RD_EXT : HDMI_I2CM_OPERATION_RD; off = (block & 1) ? 128 : 0; + dwhdmi_write(sc, HDMI_I2CM_SEGPTR, block >> 1); + for (n = 0; n < len; n++) { dwhdmi_write(sc, HDMI_I2CM_ADDRESS, n + off); dwhdmi_write(sc, HDMI_I2CM_OPERATION, operation); @@ -421,14 +429,14 @@ dwhdmi_fc_init(struct dwhdmi_softc *sc, uint8_t val; const uint8_t vic = drm_match_cea_mode(mode); - const uint16_t inhactiv = mode->hdisplay; - const uint16_t inhblank = mode->htotal - mode->hdisplay; - const uint16_t invactiv = mode->vdisplay; - const uint8_t invblank = mode->vtotal - mode->vdisplay; - const uint16_t hsyncindelay = mode->hsync_start - mode->hdisplay; - const uint16_t hsyncinwidth = mode->hsync_end - mode->hsync_start; - const uint8_t vsyncindelay = mode->vsync_start - mode->vdisplay; - const uint8_t vsyncinwidth = mode->vsync_end - mode->vsync_start; + const uint16_t inhactiv = mode->crtc_hdisplay; + const uint16_t inhblank = mode->crtc_htotal - mode->crtc_hdisplay; + const uint16_t invactiv = mode->crtc_vdisplay; + const uint8_t invblank = mode->crtc_vtotal - mode->crtc_vdisplay; + const uint16_t hsyncindelay = mode->crtc_hsync_start - mode->crtc_hdisplay; + const uint16_t hsyncinwidth = mode->crtc_hsync_end - mode->crtc_hsync_start; + const uint8_t vsyncindelay = mode->crtc_vsync_start - mode->crtc_vdisplay; + const uint8_t vsyncinwidth = mode->crtc_vsync_end - mode->crtc_vsync_start; /* Input video configuration for frame composer */ val = HDMI_FC_INVIDCONF_DE_IN_POLARITY; Index: src/sys/dev/ic/dw_hdmi.h diff -u src/sys/dev/ic/dw_hdmi.h:1.1.6.1 src/sys/dev/ic/dw_hdmi.h:1.1.6.2 --- src/sys/dev/ic/dw_hdmi.h:1.1.6.1 Sat Nov 16 16:48:25 2019 +++ src/sys/dev/ic/dw_hdmi.h Mon Nov 25 16:18:40 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: dw_hdmi.h,v 1.1.6.1 2019/11/16 16:48:25 martin Exp $ */ +/* $NetBSD: dw_hdmi.h,v 1.1.6.2 2019/11/25 16:18:40 martin Exp $ */ /*- * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca> @@ -67,6 +67,8 @@ struct dwhdmi_softc { u_int sc_reg_width; u_int sc_flags; #define DWHDMI_USE_INTERNAL_PHY __BIT(0) + u_int sc_scl_hcnt; + u_int sc_scl_lcnt; u_int sc_phytype; u_int sc_version;