Module Name: src Committed By: hkenken Date: Wed May 20 09:18:25 UTC 2020
Modified Files: src/sys/arch/arm/imx: imxuart.c src/sys/arch/arm/imx/fdt: files.imx6 imx6_spi.c src/sys/arch/evbarm/conf: GENERIC files.generic src/sys/conf: files Added Files: src/sys/arch/arm/imx/fdt: imx6_dwhdmi.c imx6_pwm.c Removed Files: src/sys/arch/evbarm/conf: IMX files.imx mk.imx std.imx Log Message: i.MX support merged into GENERIC kernel. To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.25 src/sys/arch/arm/imx/imxuart.c cvs rdiff -u -r1.8 -r1.9 src/sys/arch/arm/imx/fdt/files.imx6 cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/imx/fdt/imx6_dwhdmi.c \ src/sys/arch/arm/imx/fdt/imx6_pwm.c cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/imx/fdt/imx6_spi.c cvs rdiff -u -r1.77 -r1.78 src/sys/arch/evbarm/conf/GENERIC cvs rdiff -u -r1.6 -r0 src/sys/arch/evbarm/conf/IMX cvs rdiff -u -r1.9 -r1.10 src/sys/arch/evbarm/conf/files.generic cvs rdiff -u -r1.2 -r0 src/sys/arch/evbarm/conf/files.imx cvs rdiff -u -r1.1 -r0 src/sys/arch/evbarm/conf/mk.imx \ src/sys/arch/evbarm/conf/std.imx cvs rdiff -u -r1.1266 -r1.1267 src/sys/conf/files 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/imx/imxuart.c diff -u src/sys/arch/arm/imx/imxuart.c:1.24 src/sys/arch/arm/imx/imxuart.c:1.25 --- src/sys/arch/arm/imx/imxuart.c:1.24 Wed Jan 15 01:09:56 2020 +++ src/sys/arch/arm/imx/imxuart.c Wed May 20 09:18:25 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: imxuart.c,v 1.24 2020/01/15 01:09:56 jmcneill Exp $ */ +/* $NetBSD: imxuart.c,v 1.25 2020/05/20 09:18:25 hkenken Exp $ */ /* * Copyright (c) 2009, 2010 Genetec Corporation. All rights reserved. @@ -96,7 +96,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imxuart.c,v 1.24 2020/01/15 01:09:56 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imxuart.c,v 1.25 2020/05/20 09:18:25 hkenken Exp $"); #include "opt_imxuart.h" #include "opt_ddb.h" @@ -2083,8 +2083,6 @@ imxuart_load_pendings(struct imxuart_sof sc->sc_pending = 0; } -#if defined(IMXUARTCONSOLE) || defined(KGDB) - /* * The following functions are polled getc and putc routines, shared * by the console and kgdb glue. @@ -2171,7 +2169,6 @@ imxuart_common_putc(dev_t dev, struct im splx(s); } -#endif /* defined(IMXUARTCONSOLE) || defined(KGDB) */ /* * Initialize UART @@ -2236,7 +2233,6 @@ imxuart_init(struct imxuart_regs *regsp, } -#ifdef IMXUARTCONSOLE /* * Following are all routines needed for UART to act as console */ @@ -2295,8 +2291,6 @@ imxucnpollc(dev_t dev, int on) imxuart_readahead_out = 0; } -#endif /* IMXUARTCONSOLE */ - #ifdef KGDB int imxuart_kgdb_attach(bus_space_tag_t iot, paddr_t iobase, u_int rate, Index: src/sys/arch/arm/imx/fdt/files.imx6 diff -u src/sys/arch/arm/imx/fdt/files.imx6:1.8 src/sys/arch/arm/imx/fdt/files.imx6:1.9 --- src/sys/arch/arm/imx/fdt/files.imx6:1.8 Wed Jan 15 01:09:56 2020 +++ src/sys/arch/arm/imx/fdt/files.imx6 Wed May 20 09:18:25 2020 @@ -1,4 +1,4 @@ -# $NetBSD: files.imx6,v 1.8 2020/01/15 01:09:56 jmcneill Exp $ +# $NetBSD: files.imx6,v 1.9 2020/05/20 09:18:25 hkenken Exp $ # # Configuration info for the Freescale i.MX6 # @@ -10,12 +10,11 @@ defflag opt_soc.h SOC_IMX defflag opt_soc.h SOC_IMX6QDL: SOC_IMX # Clock -device imxccm : clk +device imxccm: clk attach imxccm at fdt file arch/arm/imx/imx6_ccm.c imxccm file arch/arm/imx/fdt/imx6_clk.c imxccm - # Common FDT clock framework define imx_ccm file arch/arm/imx/fdt/imx_ccm.c imx_ccm @@ -51,7 +50,7 @@ file arch/arm/imx/imxgpio.c imxgpio ne file arch/arm/imx/fdt/imx6_gpio.c imxgpio # UART -device imxuart { } : bus_space_generic +device imxuart: tty attach imxuart at fdt with imx6_com file arch/arm/imx/imxuart.c imxuart needs-flag file arch/arm/imx/fdt/imx6_com.c imx6_com needs-flag @@ -84,7 +83,6 @@ device imx8mqusbphy attach imx8mqusbphy at fdt file arch/arm/imx/fdt/imx8mq_usbphy.c imx8mqusbphy - # SDMMC attach sdhc at fdt with imx6_sdhc file arch/arm/imx/fdt/imx6_sdhc.c imx6_sdhc @@ -102,9 +100,18 @@ file arch/arm/imx/imxi2c.c imxi2c file arch/arm/imx/fdt/imx6_i2c.c imxi2c # SPI bus controller -device imxspi : spibus +device imxspi: spibus attach imxspi at fdt with imxspi_fdt -file arch/arm/imx/imxspi.c imxspi +file arch/arm/imx/imxspi.c imxspi file arch/arm/imx/fdt/imx6_spi.c imxspi_fdt defparam opt_imxspi.h IMXSPINSLAVES +# PWM +device imxpwm: pwm +attach imxpwm at fdt with imxpwm_fdt +file arch/arm/imx/imxpwm.c imxpwm +file arch/arm/imx/fdt/imx6_pwm.c imxpwm_fdt + +# HDMI TX (Designware based) +attach dwhdmi at fdt with imx6_dwhdmi +file arch/arm/imx/fdt/imx6_dwhdmi.c imx6_dwhdmi Index: src/sys/arch/arm/imx/fdt/imx6_spi.c diff -u src/sys/arch/arm/imx/fdt/imx6_spi.c:1.3 src/sys/arch/arm/imx/fdt/imx6_spi.c:1.4 --- src/sys/arch/arm/imx/fdt/imx6_spi.c:1.3 Tue Dec 3 10:32:53 2019 +++ src/sys/arch/arm/imx/fdt/imx6_spi.c Wed May 20 09:18:25 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: imx6_spi.c,v 1.3 2019/12/03 10:32:53 hkenken Exp $ */ +/* $NetBSD: imx6_spi.c,v 1.4 2020/05/20 09:18:25 hkenken Exp $ */ /*- * Copyright (c) 2019 Genetec Corporation. All rights reserved. * Written by Hashimoto Kenichi for Genetec Corporation. @@ -25,7 +25,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: imx6_spi.c,v 1.3 2019/12/03 10:32:53 hkenken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: imx6_spi.c,v 1.4 2020/05/20 09:18:25 hkenken Exp $"); #include "opt_imxspi.h" @@ -105,7 +105,7 @@ imxspi_attach(device_t parent, device_t u_int nslaves; error = of_getprop_uint32(phandle, "fsl,spi-num-chipselects", &nslaves); if (error) - nslaves = IMXSPINSLAVES; + nslaves = 4; ifsc->sc_pin_cs = kmem_alloc(sizeof(struct fdtbus_gpio_pin *) * nslaves, KM_SLEEP); Index: src/sys/arch/evbarm/conf/GENERIC diff -u src/sys/arch/evbarm/conf/GENERIC:1.77 src/sys/arch/evbarm/conf/GENERIC:1.78 --- src/sys/arch/evbarm/conf/GENERIC:1.77 Mon May 18 21:19:35 2020 +++ src/sys/arch/evbarm/conf/GENERIC Wed May 20 09:18:25 2020 @@ -1,5 +1,5 @@ # -# $NetBSD: GENERIC,v 1.77 2020/05/18 21:19:35 jmcneill Exp $ +# $NetBSD: GENERIC,v 1.78 2020/05/20 09:18:25 hkenken Exp $ # # GENERIC ARM (aarch32) kernel # @@ -19,6 +19,9 @@ options CPU_CORTEXA53 options SOC_AM33XX options SOC_BCM2836 options SOC_EXYNOS5422 +options SOC_IMX6DL +options SOC_IMX6Q +options SOC_IMX6QDL options SOC_MESON8B options SOC_OMAP3 options SOC_SUN4I_A10 @@ -48,6 +51,7 @@ options MSGBUFSIZE=32768 # EARLYCONS is required for early init messages from VERBOSE_INIT_ARM. #options EARLYCONS=am33xx, CONSADDR=0x44e09000 +#options EARLYCONS=imx, CONSADDR=0x02020000 #options EARLYCONS=omap3, CONSADDR=0x49020000 # ODROID-C1 @@ -102,6 +106,7 @@ cycvclkmgr* at fdt? pass 1 # Cyclone V cycvrstmgr* at fdt? pass 0 # Cyclone V reset manager exy5410clk* at fdt? pass 3 # Exynos5410 clock controller exy5422clk* at fdt? pass 3 # Exynos5422 clock controller +imxccm* at fdt? pass 1 # i.MX6 ccm meson8bclkc* at fdt? pass 2 # Amlogic Meson8b clock controller mesonresets* at fdt? pass 2 # Amlogic Meson misc. clock resets omap3cm* at fdt? pass 1 # TI OMAP3 CM @@ -172,6 +177,7 @@ gic* at fdt? pass 1 # ARM GIC armgic0 at gic? bcmicu* at fdt? pass 1 # Broadcom BCM283x ICU exyointr* at fdt? pass 1 # Samsung Exynos ICU +imxgpc* at fdt? pass 2 # i.MX General Power Controller INTC omapintc* at fdt? pass 2 # TI OMAP INTC tegralic* at fdt? pass 1 # NVIDIA Tegra LIC sunxiintc* at fdt? pass 1 # Allwinner INTC @@ -215,6 +221,7 @@ bcmaux* at fdt? pass 1 # Broadcom BCM2 # GPIO controller bcmgpio* at fdt? # Broadcom BCM283x GPIO exyopctl* at fdt? pass 2 # Samsung Exynos GPIO +imxgpio* at fdt? pass 3 # i.MX GPIO mesonpinctrl* at fdt? pass 2 # Amlogic Meson GPIO plgpio* at fdt? # ARM PrimeCell GPIO sunxigpio* at fdt? pass 3 # Allwinner GPIO @@ -225,9 +232,11 @@ gpio* at gpiobus? # MPIO / Pinmux pinctrl* at fdt? pass 2 # Generic pinctrl driver tegrapinmux* at fdt? # NVIDIA Tegra MPIO +imxiomux* at fdt? pass 2 # i.MX IOMUX # PWM controller expwm* at fdt? pass 4 # PWM +imxpwm* at fdt? # i.MX PWM sunxipwm* at fdt? pass 3 # Allwinner PWM # Backlight @@ -244,6 +253,7 @@ tegra210xphy* at tegra210xpad? # PCIE pcihost* at fdt? # Generic PCI host controller tegrapcie0 at fdt? # NVIDIA Tegra PCIE +imxpcie* at fdt? # i.MX PCIE pci* at pcibus? ppb* at pci? dev ? function ? pci* at ppb? @@ -253,12 +263,14 @@ awge* at fdt? # Allwinner Gigabit Et cemac* at fdt? # Cadence EMAC/GEM ethernet controller cpsw* at fdt? # TI CPSW 3-port Ethernet Switch emac* at fdt? # Allwinner Fast/Gigabit Ethernet (EMAC) +enet* at fdt? # i.MX FEC smsh* at fdt? # SMSC LAN9118 # PCI Ethernet re* at pci? dev ? function ? # Realtek RTL8111GS # MII/PHY support +atphy* at mii? phy ? # Attansic/Atheros PHYs exphy* at mii? phy ? # 3Com internal PHYs gentbi* at mii? phy ? # Generic Ten-Bit 1000BASE-[CLS]X PHYs glxtphy* at mii? phy ? # Level One LXT-1000 PHYs @@ -293,6 +305,7 @@ ukphy* at mii? phy ? # generic unknow com* at fdt? pass 4 # UART exuart* at fdt? pass 4 # SSCOM UART plcom* at fdt? pass 4 # ARM PL011 UART +imxuart* at fdt? pass 4 # i.MX UART mesonuart* at fdt? pass 4 # Amlogic Meson UART zynquart* at fdt? pass 4 # Cadence UART @@ -300,6 +313,7 @@ zynquart* at fdt? pass 4 # Cadence UAR options I2C_MAX_ADDR=0xfff bsciic* at fdt? # Broadcom BCM283x Serial Control exyoi2c* at fdt? # Samsung Exynos I2C +imxi2c* at fdt? # i.MX I2C sunxirsb* at fdt? pass 4 # Allwinner RSB sunxitwi* at fdt? # Allwinner TWI tegrai2c* at fdt? pass 4 # NVIDIA Tegra I2C @@ -334,6 +348,7 @@ pseudo-device canloop # CAN loopback sunxican* at fdt? # A10/A20 CAN controller # SPI +imxspi* at fdt? # i.MX SPI sun4ispi* at fdt? sun6ispi* at fdt? spi* at spibus? @@ -425,6 +440,7 @@ hdmicec* at hdmicecbus? # Display #tegradrm* at fdt? # NVIDIA Tegra Display #tegrafb* at tegrafbbus? +dwhdmi* at fdt? # Designware HDMI TX genfb* at fdt? # Simple Framebuffer mesonfb* at fdt? # Amlogic Meson Framebuffer omapfb* at fdt? # TI OMAP3 Framebuffer @@ -478,17 +494,20 @@ tegrasoctherm* at fdt? # NVIDIA Tegra # USB exusbphy* at fdt? pass 9 # Samsung Exynos USB2 PHY exusbdrdphy* at fdt? pass 9 # Samsung Exynos USB3 DRD PHY +imxusbphy* at fdt? pass 9 # i.MX USB PHY mesonusbphy* at fdt? pass 9 # Amlogic Meson USB2 PHY sun9iusbphy* at fdt? pass 9 # Allwinner A80 USB PHY sunxiusbphy* at fdt? pass 9 # Allwinner USB PHY sunxiusb3phy* at fdt? pass 9 # Allwinner USB3 PHY tegrausbphy* at fdt? # NVIDIA Tegra USB PHY usbnopphy* at fdt? pass 9 # Generic USB PHY +imxusbc* at fdt? pass 9 # i.MX USB host tiotg* at fdt? # TI dual port OTG tiusb* at fdt? pass 9 # TI HS USB host tiusbtll* at fdt? pass 8 # TI HS USB host TLL dwctwo* at fdt? # Designware USB DRD ehci* at fdt? # EHCI +ehci* at imxusbc? motg* at fdt? # Mentor Graphics USB OTG ohci* at fdt? # OHCI xhci* at fdt? # XHCI Index: src/sys/arch/evbarm/conf/files.generic diff -u src/sys/arch/evbarm/conf/files.generic:1.9 src/sys/arch/evbarm/conf/files.generic:1.10 --- src/sys/arch/evbarm/conf/files.generic:1.9 Sat Oct 26 14:57:27 2019 +++ src/sys/arch/evbarm/conf/files.generic Wed May 20 09:18:25 2020 @@ -1,4 +1,4 @@ -# $NetBSD: files.generic,v 1.9 2019/10/26 14:57:27 jmcneill Exp $ +# $NetBSD: files.generic,v 1.10 2020/05/20 09:18:25 hkenken Exp $ # # A generic (aarch32) kernel configuration info # @@ -20,6 +20,7 @@ file arch/arm/arm/bus_space_a4x.S include "arch/arm/altera/files.altera" include "arch/arm/amlogic/files.meson" include "arch/arm/broadcom/files.bcm2835" +include "arch/arm/imx/fdt/files.imx6" include "arch/arm/nvidia/files.tegra" include "arch/arm/samsung/files.exynos" include "arch/arm/sunxi/files.sunxi" Index: src/sys/conf/files diff -u src/sys/conf/files:1.1266 src/sys/conf/files:1.1267 --- src/sys/conf/files:1.1266 Wed Apr 22 09:15:40 2020 +++ src/sys/conf/files Wed May 20 09:18:25 2020 @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.1266 2020/04/22 09:15:40 rin Exp $ +# $NetBSD: files,v 1.1267 2020/05/20 09:18:25 hkenken Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 version 20171118 @@ -1472,7 +1472,7 @@ device ipmi: sysmon_envsys, sysmon_wdog attach ipmi at ipmibus # Designware HDMI TX -device dwhdmi: edid, videomode, drmkms, drmkms_i2c +device dwhdmi: edid, videomode, drmkms, drmkms_i2c, ddc_read_edid file dev/ic/dw_hdmi.c dwhdmi file dev/ic/dw_hdmi_phy.c dwhdmi Added files: Index: src/sys/arch/arm/imx/fdt/imx6_dwhdmi.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_dwhdmi.c:1.1 --- /dev/null Wed May 20 09:18:25 2020 +++ src/sys/arch/arm/imx/fdt/imx6_dwhdmi.c Wed May 20 09:18:25 2020 @@ -0,0 +1,285 @@ +/* $NetBSD: imx6_dwhdmi.c,v 1.1 2020/05/20 09:18:25 hkenken Exp $ */ +/*- + * Copyright (c) 2020 Genetec Corporation. All rights reserved. + * Written by Hashimoto Kenichi for Genetec Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_dwhdmi.c,v 1.1 2020/05/20 09:18:25 hkenken Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/conf.h> + +#include <drm/drmP.h> +#include <drm/drm_crtc_helper.h> + +#include <dev/fdt/fdtvar.h> +#include <dev/fdt/fdt_port.h> +#include <dev/fdt/syscon.h> + +#include <dev/ic/dw_hdmi.h> + +static const struct dwhdmi_mpll_config imx6_dwhdmi_mpll_config[] = { + { 45250, 0x01e0, 0x0000, 0x091c }, + { 92500, 0x0072, 0x0001, 0x06dc }, + { 148500, 0x0051, 0x0002, 0x091c }, + { 216000, 0x00a0, 0x000a, 0x06dc }, + { 0, 0x0000, 0x0000, 0x0000 }, +}; + +static const struct dwhdmi_phy_config imx6_dwhdmi_phy_config[] = { + { 216000, 0x800d, 0x000a, 0x01ad }, + { 0, 0x0000, 0x0000, 0x0000 } +}; + +enum { + DWHDMI_PORT_INPUT = 0, + DWHDMI_PORT_OUTPUT = 1, +}; + +static const char * const compatible[] = { + "fsl,imx6dl-hdmi", + "fsl,imx6q-hdmi", + NULL +}; + +struct imx6_dwhdmi_softc { + struct dwhdmi_softc sc_base; + int sc_phandle; + + struct fdt_device_ports sc_ports; + struct drm_display_mode sc_curmode; + struct drm_encoder sc_encoder; + + bool sc_activated; +}; + +#define to_imx6_dwhdmi_softc(x) container_of(x, struct imx6_dwhdmi_softc, sc_base) +#define to_imx6_dwhdmi_encoder(x) container_of(x, struct imx6_dwhdmi_softc, sc_encoder) + +static bool +imx6_dwhdmi_encoder_mode_fixup(struct drm_encoder *encoder, + const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) +{ + return true; +} + +static void +imx6_dwhdmi_encoder_mode_set(struct drm_encoder *encoder, + struct drm_display_mode *mode, struct drm_display_mode *adjusted) +{ +} + +static void +imx6_dwhdmi_encoder_enable(struct drm_encoder *encoder) +{ +} + +static void +imx6_dwhdmi_encoder_disable(struct drm_encoder *encoder) +{ +} + +static void +imx6_dwhdmi_encoder_prepare(struct drm_encoder *encoder) +{ +} + +static void +imx6_dwhdmi_encoder_commit(struct drm_encoder *encoder) +{ +} + +static const struct drm_encoder_funcs imx6_dwhdmi_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + +static const struct drm_encoder_helper_funcs imx6_dwhdmi_encoder_helper_funcs = { + .prepare = imx6_dwhdmi_encoder_prepare, + .mode_fixup = imx6_dwhdmi_encoder_mode_fixup, + .mode_set = imx6_dwhdmi_encoder_mode_set, + .enable = imx6_dwhdmi_encoder_enable, + .disable = imx6_dwhdmi_encoder_disable, + .commit = imx6_dwhdmi_encoder_commit, +}; + +static int +imx6_dwhdmi_ep_activate(device_t dev, struct fdt_endpoint *ep, bool activate) +{ + struct imx6_dwhdmi_softc * const sc = device_private(dev); + struct fdt_endpoint *in_ep = fdt_endpoint_remote(ep); + struct fdt_endpoint *out_ep, *out_rep; + struct drm_crtc *crtc; + int error; + + if (sc->sc_activated != false) { + return 0; + } + + if (!activate) + return EINVAL; + + if (fdt_endpoint_port_index(ep) != DWHDMI_PORT_INPUT) + return EINVAL; + + switch (fdt_endpoint_type(in_ep)) { + case EP_DRM_CRTC: + crtc = fdt_endpoint_get_data(in_ep); + break; + default: + crtc = NULL; + break; + } + + if (crtc == NULL) + return EINVAL; + + sc->sc_encoder.possible_crtcs = 3; // 1U << drm_crtc_index(crtc); /* XXX */ + drm_encoder_init(crtc->dev, &sc->sc_encoder, &imx6_dwhdmi_encoder_funcs, + DRM_MODE_ENCODER_TMDS); + drm_encoder_helper_add(&sc->sc_encoder, &imx6_dwhdmi_encoder_helper_funcs); + + sc->sc_base.sc_connector.base.connector_type = DRM_MODE_CONNECTOR_HDMIA; + error = dwhdmi_bind(&sc->sc_base, &sc->sc_encoder); + if (error != 0) + return error; + sc->sc_activated = true; + + out_ep = fdt_endpoint_get_from_index(&sc->sc_ports, DWHDMI_PORT_OUTPUT, 0); + if (out_ep != NULL) { + /* Ignore downstream connectors, we have our own. */ + out_rep = fdt_endpoint_remote(out_ep); + if (out_rep != NULL && fdt_endpoint_type(out_rep) == EP_DRM_CONNECTOR) + return 0; + + error = fdt_endpoint_activate(out_ep, activate); + if (error != 0) + return error; + } + + return 0; +} + +static void * +imx6_dwhdmi_ep_get_data(device_t dev, struct fdt_endpoint *ep) +{ + struct imx6_dwhdmi_softc * const sc = device_private(dev); + + return &sc->sc_encoder; +} + +static audio_dai_tag_t +imx6_dwhdmi_dai_get_tag(device_t dev, const void *data, size_t len) +{ + struct imx6_dwhdmi_softc * const sc = device_private(dev); + + if (len != 4) + return NULL; + + return &sc->sc_base.sc_dai; +} + +static struct fdtbus_dai_controller_func imx6_dwhdmi_dai_funcs = { + .get_tag = imx6_dwhdmi_dai_get_tag +}; + +static int +imx6_dwhdmi_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +imx6_dwhdmi_attach(device_t parent, device_t self, void *aux) +{ + struct imx6_dwhdmi_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + /* Required */ + if (fdtbus_clock_enable(phandle, "iahb", true) != 0) { + aprint_error(": couldn't enable iahb clock\n"); + return; + } + + /* Required */ + if (fdtbus_clock_enable(phandle, "isfr", true) != 0) { + aprint_error(": couldn't enable isfr clock\n"); + return; + } + + sc->sc_base.sc_dev = self; + sc->sc_base.sc_reg_width = 1; + sc->sc_base.sc_bst = faa->faa_bst; + if (bus_space_map(sc->sc_base.sc_bst, addr, size, 0, &sc->sc_base.sc_bsh) != 0) { + aprint_error(": couldn't map registers\n"); + return; + } + sc->sc_phandle = faa->faa_phandle; + + aprint_naive("\n"); + aprint_normal(": HDMI TX\n"); + + sc->sc_base.sc_ic = fdtbus_i2c_acquire(phandle, "ddc-i2c-bus"); + if (of_hasprop(phandle, "ddc-i2c-bus") && sc->sc_base.sc_ic == NULL) { + aprint_error_dev(self, "couldn't find external I2C master\n"); + return; + } + + sc->sc_base.sc_flags |= DWHDMI_USE_INTERNAL_PHY; + sc->sc_base.sc_detect = dwhdmi_phy_detect; + sc->sc_base.sc_enable = dwhdmi_phy_enable; + sc->sc_base.sc_disable = dwhdmi_phy_disable; + sc->sc_base.sc_mode_set = dwhdmi_phy_mode_set; + sc->sc_base.sc_mpll_config = imx6_dwhdmi_mpll_config; + sc->sc_base.sc_phy_config = imx6_dwhdmi_phy_config; + + if (dwhdmi_attach(&sc->sc_base) != 0) { + aprint_error_dev(self, "failed to attach driver\n"); + return; + } + + sc->sc_ports.dp_ep_activate = imx6_dwhdmi_ep_activate; + sc->sc_ports.dp_ep_get_data = imx6_dwhdmi_ep_get_data; + fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_ENCODER); + + fdtbus_register_dai_controller(self, phandle, &imx6_dwhdmi_dai_funcs); +} + +CFATTACH_DECL_NEW(imx6_dwhdmi, sizeof(struct imx6_dwhdmi_softc), + imx6_dwhdmi_match, imx6_dwhdmi_attach, NULL, NULL); Index: src/sys/arch/arm/imx/fdt/imx6_pwm.c diff -u /dev/null src/sys/arch/arm/imx/fdt/imx6_pwm.c:1.1 --- /dev/null Wed May 20 09:18:25 2020 +++ src/sys/arch/arm/imx/fdt/imx6_pwm.c Wed May 20 09:18:25 2020 @@ -0,0 +1,142 @@ +/* $NetBSD: imx6_pwm.c,v 1.1 2020/05/20 09:18:25 hkenken Exp $ */ +/*- + * Copyright (c) 2019 Genetec Corporation. All rights reserved. + * Written by Hashimoto Kenichi for Genetec Corporation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: imx6_pwm.c,v 1.1 2020/05/20 09:18:25 hkenken Exp $"); + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> + +#include <arm/imx/imxpwmvar.h> + +#include <dev/fdt/fdtvar.h> + +struct imxpwm_fdt_softc { + struct imxpwm_softc sc_imxpwm; /* Must be first */ +}; + +static int imx6_pwm_match(device_t, cfdata_t, void *); +static void imx6_pwm_attach(device_t, device_t, void *); + +CFATTACH_DECL_NEW(imxpwm_fdt, sizeof(struct imxpwm_fdt_softc), + imx6_pwm_match, imx6_pwm_attach, NULL, NULL); + +static pwm_tag_t +imxpwm_get_tag(device_t dev, const void *data, size_t len) +{ + struct imxpwm_fdt_softc * const ifsc = device_private(dev); + struct imxpwm_softc * const sc = &ifsc->sc_imxpwm; + const u_int *pwm = data; + + if (len < 12) + return NULL; + + const u_int index = be32toh(pwm[1]); + if (index != 0) + return NULL; + const u_int period = be32toh(pwm[2]); + + sc->sc_conf.period = period; + if (len >= 16) { + const u_int polarity = be32toh(pwm[3]); + sc->sc_conf.period = polarity ? PWM_ACTIVE_LOW : PWM_ACTIVE_HIGH; + } + + return &sc->sc_pwm; +} + +static struct fdtbus_pwm_controller_func imxpwm_funcs = { + .get_tag = imxpwm_get_tag +}; + +static int +imx6_pwm_match(device_t parent, cfdata_t cf, void *aux) +{ + const char * const compatible[] = { "fsl,imx6q-pwm", NULL }; + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +void +imx6_pwm_attach(device_t parent, device_t self, void *aux) +{ + struct imxpwm_fdt_softc * const ifsc = device_private(self); + struct imxpwm_softc * const sc = &ifsc->sc_imxpwm; + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + char intrstr[128]; + bus_addr_t addr; + bus_size_t size; + int error; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get PWM registers\n"); + return; + } + + sc->sc_dev = self; + sc->sc_iot = faa->faa_bst; + + error = bus_space_map(sc->sc_iot, addr, size, 0, + &sc->sc_ioh); + if (error) { + aprint_error(": couldn't map gpc registers: %d\n", error); + return; + } + + if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { + aprint_error_dev(self, "failed to decode interrupt\n"); + return; + } + + sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, + 0, imxpwm_intr, sc); + if (sc->sc_ih == NULL) { + aprint_error_dev(self, "failed to establish interrupt on %s\n", + intrstr); + return; + } + aprint_normal_dev(self, "interrupting on %s\n", intrstr); + + sc->sc_clk = fdtbus_clock_get(phandle, "per"); + if (sc->sc_clk == NULL) { + aprint_error(": couldn't get clk\n"); + return; + } + sc->sc_freq = clk_get_rate(sc->sc_clk); + + imxpwm_attach_common(sc); + + fdtbus_register_pwm_controller(self, phandle, + &imxpwm_funcs); + + return; +} +