Module Name:    src
Committed By:   jakllsch
Date:           Tue Dec 17 18:26:36 UTC 2019

Modified Files:
        src/sys/arch/arm/rockchip: rk_dwhdmi.c rk_vop.c

Log Message:
Move drm_encoder from rkvop(4) to the SoC-layer output pipe drivers (rk_dwhdmi).


To generate a diff of this commit:
cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/rockchip/rk_dwhdmi.c \
    src/sys/arch/arm/rockchip/rk_vop.c

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/rockchip/rk_dwhdmi.c
diff -u src/sys/arch/arm/rockchip/rk_dwhdmi.c:1.3 src/sys/arch/arm/rockchip/rk_dwhdmi.c:1.4
--- src/sys/arch/arm/rockchip/rk_dwhdmi.c:1.3	Sat Nov 16 13:25:33 2019
+++ src/sys/arch/arm/rockchip/rk_dwhdmi.c	Tue Dec 17 18:26:36 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_dwhdmi.c,v 1.3 2019/11/16 13:25:33 jmcneill Exp $ */
+/* $NetBSD: rk_dwhdmi.c,v 1.4 2019/12/17 18:26:36 jakllsch Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_dwhdmi.c,v 1.3 2019/11/16 13:25:33 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_dwhdmi.c,v 1.4 2019/12/17 18:26:36 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -38,6 +38,7 @@ __KERNEL_RCSID(0, "$NetBSD: rk_dwhdmi.c,
 #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>
@@ -85,12 +86,14 @@ struct rk_dwhdmi_softc {
 
 	struct fdt_device_ports	sc_ports;
 	struct drm_display_mode	sc_curmode;
+	struct drm_encoder	sc_encoder;
 	struct syscon		*sc_grf;
 
 	bool			sc_activated;
 };
 
 #define	to_rk_dwhdmi_softc(x)	container_of(x, struct rk_dwhdmi_softc, sc_base)
+#define	to_rk_dwhdmi_encoder(x)	container_of(x, struct rk_dwhdmi_softc, sc_encoder)
 
 static void
 rk_dwhdmi_select_input(struct rk_dwhdmi_softc *sc, u_int crtc_index)
@@ -103,16 +106,69 @@ rk_dwhdmi_select_input(struct rk_dwhdmi_
 	syscon_unlock(sc->sc_grf);
 }
 
+static bool
+rk_dwhdmi_encoder_mode_fixup(struct drm_encoder *encoder,
+    const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
+{
+	return true;
+}
+
+static void
+rk_dwhdmi_encoder_mode_set(struct drm_encoder *encoder,
+    struct drm_display_mode *mode, struct drm_display_mode *adjusted)
+{
+}
+
+static void
+rk_dwhdmi_encoder_enable(struct drm_encoder *encoder)
+{
+}
+
+static void
+rk_dwhdmi_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static void
+rk_dwhdmi_encoder_prepare(struct drm_encoder *encoder)
+{
+	struct rk_dwhdmi_softc * const sc = to_rk_dwhdmi_encoder(encoder);
+	const u_int crtc_index = drm_crtc_index(encoder->crtc);
+
+	rk_dwhdmi_select_input(sc, crtc_index);
+}
+
+static void
+rk_dwhdmi_encoder_commit(struct drm_encoder *encoder)
+{
+}
+
+static const struct drm_encoder_funcs rk_dwhdmi_encoder_funcs = {
+	.destroy = drm_encoder_cleanup,
+};
+
+static const struct drm_encoder_helper_funcs rk_dwhdmi_encoder_helper_funcs = {
+	.prepare = rk_dwhdmi_encoder_prepare,
+	.mode_fixup = rk_dwhdmi_encoder_mode_fixup,
+	.mode_set = rk_dwhdmi_encoder_mode_set,
+	.enable = rk_dwhdmi_encoder_enable,
+	.disable = rk_dwhdmi_encoder_disable,
+	.commit = rk_dwhdmi_encoder_commit,
+};
+
 static int
 rk_dwhdmi_ep_activate(device_t dev, struct fdt_endpoint *ep, bool activate)
 {
 	struct rk_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_encoder *encoder;
-	struct drm_bridge *bridge;
+	struct drm_crtc *crtc;
 	int error;
 
+	if (sc->sc_activated != false) {
+		return 0;
+	}
+
 	if (!activate)
 		return EINVAL;
 
@@ -120,27 +176,27 @@ rk_dwhdmi_ep_activate(device_t dev, stru
 		return EINVAL;
 
 	switch (fdt_endpoint_type(in_ep)) {
-	case EP_DRM_ENCODER:
-		encoder = fdt_endpoint_get_data(in_ep);
-		break;
-	case EP_DRM_BRIDGE:
-		bridge = fdt_endpoint_get_data(in_ep);
-		encoder = bridge->encoder;
+	case EP_DRM_CRTC:
+		crtc = fdt_endpoint_get_data(in_ep);
 		break;
 	default:
-		encoder = NULL;
+		crtc = NULL;
 		break;
 	}
 
-	if (encoder == NULL)
+	if (crtc == NULL)
 		return EINVAL;
 
-	if (sc->sc_activated == false) {
-		error = dwhdmi_bind(&sc->sc_base, encoder);
-		if (error != 0)
-			return error;
-		sc->sc_activated = true;
-	}
+	sc->sc_encoder.possible_crtcs = 3; // 1U << drm_crtc_index(crtc); /* XXX */
+	drm_encoder_init(crtc->dev, &sc->sc_encoder, &rk_dwhdmi_encoder_funcs,
+	    DRM_MODE_ENCODER_TMDS);
+	drm_encoder_helper_add(&sc->sc_encoder, &rk_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) {
@@ -162,17 +218,12 @@ rk_dwhdmi_ep_get_data(device_t dev, stru
 {
 	struct rk_dwhdmi_softc * const sc = device_private(dev);
 
-	return &sc->sc_base.sc_bridge;
+	return &sc->sc_encoder;
 }
 
 static void
 rk_dwhdmi_enable(struct dwhdmi_softc *dsc)
 {
-	struct rk_dwhdmi_softc * const sc = to_rk_dwhdmi_softc(dsc);
-
-	const u_int crtc_index = drm_crtc_index(dsc->sc_bridge.encoder->crtc);
-
-	rk_dwhdmi_select_input(sc, crtc_index);
 
 	dwhdmi_phy_enable(dsc);
 }
@@ -301,7 +352,7 @@ rk_dwhdmi_attach(device_t parent, device
 
 	sc->sc_ports.dp_ep_activate = rk_dwhdmi_ep_activate;
 	sc->sc_ports.dp_ep_get_data = rk_dwhdmi_ep_get_data;
-	fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_BRIDGE);
+	fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_ENCODER);
 
 	fdtbus_register_dai_controller(self, phandle, &rk_dwhdmi_dai_funcs);
 }
Index: src/sys/arch/arm/rockchip/rk_vop.c
diff -u src/sys/arch/arm/rockchip/rk_vop.c:1.3 src/sys/arch/arm/rockchip/rk_vop.c:1.4
--- src/sys/arch/arm/rockchip/rk_vop.c:1.3	Sun Dec 15 00:49:00 2019
+++ src/sys/arch/arm/rockchip/rk_vop.c	Tue Dec 17 18:26:36 2019
@@ -1,4 +1,4 @@
-/* $NetBSD: rk_vop.c,v 1.3 2019/12/15 00:49:00 mrg Exp $ */
+/* $NetBSD: rk_vop.c,v 1.4 2019/12/17 18:26:36 jakllsch Exp $ */
 
 /*-
  * Copyright (c) 2019 Jared D. McNeill <jmcne...@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rk_vop.c,v 1.3 2019/12/15 00:49:00 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rk_vop.c,v 1.4 2019/12/17 18:26:36 jakllsch Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -128,12 +128,6 @@ struct rk_vop_crtc {
 	struct rk_vop_softc	*sc;
 };
 
-struct rk_vop_encoder {
-	struct drm_encoder	base;
-	struct rk_vop_softc	*sc;
-	enum vop_ep_type	ep_type;
-};
-
 struct rk_vop_softc {
 	device_t		sc_dev;
 	bus_space_tag_t		sc_bst;
@@ -143,7 +137,6 @@ struct rk_vop_softc {
 	struct clk		*sc_dclk;
 
 	struct rk_vop_crtc	sc_crtc;
-	struct rk_vop_encoder	sc_encoder[VOP_NEP];
 
 	struct fdt_device_ports	sc_ports;
 
@@ -151,7 +144,6 @@ struct rk_vop_softc {
 };
 
 #define	to_rk_vop_crtc(x)	container_of(x, struct rk_vop_crtc, base)
-#define	to_rk_vop_encoder(x)	container_of(x, struct rk_vop_encoder, base)
 
 #define	RD4(sc, reg)				\
 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
@@ -285,14 +277,19 @@ rk_vop_mode_set(struct drm_crtc *crtc, s
 	uint32_t val;
 	u_int lb_mode;
 	int error;
+	u_int pol;
+	int connector_type = 0;
+	struct drm_connector * connector;
 
 	const u_int hactive = adjusted_mode->hdisplay;
 	const u_int hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
 	const u_int hback_porch = adjusted_mode->htotal - adjusted_mode->hsync_end;
+	const u_int hfront_porch = adjusted_mode->hsync_start - adjusted_mode->hdisplay;
 
 	const u_int vactive = adjusted_mode->vdisplay;
 	const u_int vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
 	const u_int vback_porch = adjusted_mode->vtotal - adjusted_mode->vsync_end;
+	const u_int vfront_porch = adjusted_mode->vsync_start - adjusted_mode->vdisplay;
 
 	error = clk_set_rate(sc->sc_dclk, adjusted_mode->clock * 1000);
 	if (error != 0)
@@ -331,6 +328,73 @@ rk_vop_mode_set(struct drm_crtc *crtc, s
 
 	rk_vop_mode_do_set_base(crtc, old_fb, x, y, 0);
 
+	pol = DSP_DCLK_POL;
+	if ((adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) != 0)
+		pol |= DSP_HSYNC_POL;
+	if ((adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) != 0)
+		pol |= DSP_VSYNC_POL;
+
+	drm_for_each_connector(connector, crtc->dev) {
+		if ((connector->encoder) == NULL)
+			continue;
+		if (connector->encoder->crtc == crtc) {
+			connector_type = connector->connector_type;
+			break;
+		}
+	}
+
+	switch (connector_type) {
+	case DRM_MODE_CONNECTOR_HDMIA:
+		sc->sc_conf->set_polarity(sc, VOP_EP_HDMI, pol);
+		break;
+	case DRM_MODE_CONNECTOR_eDP:
+		sc->sc_conf->set_polarity(sc, VOP_EP_EDP, pol);
+		break;
+	}
+
+	val = RD4(sc, VOP_SYS_CTRL);
+	val &= ~VOP_STANDBY_EN;
+	val &= ~(MIPI_OUT_EN|EDP_OUT_EN|HDMI_OUT_EN|RGB_OUT_EN);
+
+	switch (connector_type) {
+	case DRM_MODE_CONNECTOR_HDMIA:
+		val |= HDMI_OUT_EN;
+		break;
+	case DRM_MODE_CONNECTOR_eDP:
+		val |= EDP_OUT_EN;
+		break;
+	}
+	WR4(sc, VOP_SYS_CTRL, val);
+
+	val = RD4(sc, VOP_DSP_CTRL0);
+	val &= ~DSP_OUT_MODE;
+	val |= __SHIFTIN(sc->sc_conf->out_mode, DSP_OUT_MODE);
+	WR4(sc, VOP_DSP_CTRL0, val);
+
+	val = __SHIFTIN(hsync_len + hback_porch, DSP_HACT_ST_POST) |
+	      __SHIFTIN(hsync_len + hback_porch + hactive, DSP_HACT_END_POST);
+	WR4(sc, VOP_POST_DSP_HACT_INFO, val);
+
+	val = __SHIFTIN(hsync_len + hback_porch, DSP_HACT_ST) |
+	      __SHIFTIN(hsync_len + hback_porch + hactive, DSP_HACT_END);
+	WR4(sc, VOP_DSP_HACT_ST_END, val);
+
+	val = __SHIFTIN(hsync_len, DSP_HTOTAL) |
+	      __SHIFTIN(hsync_len + hback_porch + hactive + hfront_porch, DSP_HS_END);
+	WR4(sc, VOP_DSP_HTOTAL_HS_END, val);
+
+	val = __SHIFTIN(vsync_len + vback_porch, DSP_VACT_ST_POST) |
+	      __SHIFTIN(vsync_len + vback_porch + vactive, DSP_VACT_END_POST);
+	WR4(sc, VOP_POST_DSP_VACT_INFO, val);
+
+	val = __SHIFTIN(vsync_len + vback_porch, DSP_VACT_ST) |
+	      __SHIFTIN(vsync_len + vback_porch + vactive, DSP_VACT_END);
+	WR4(sc, VOP_DSP_VACT_ST_END, val);
+
+	val = __SHIFTIN(vsync_len, DSP_VTOTAL) |
+	      __SHIFTIN(vsync_len + vback_porch + vactive + vfront_porch, DSP_VS_END);
+	WR4(sc, VOP_DSP_VTOTAL_VS_END, val);
+
 	return 0;
 }
 
@@ -395,132 +459,11 @@ static const struct drm_crtc_helper_func
 	.commit = rk_vop_commit,
 };
 
-static void
-rk_vop_encoder_destroy(struct drm_encoder *encoder)
-{
-}
-
-static const struct drm_encoder_funcs rk_vop_encoder_funcs = {
-	.destroy = rk_vop_encoder_destroy,
-};
-
-static void
-rk_vop_encoder_dpms(struct drm_encoder *encoder, int mode)
-{
-}
-
-static bool
-rk_vop_encoder_mode_fixup(struct drm_encoder *encoder,
-    const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
-{
-        return true;
-}
-
-static void
-rk_vop_encoder_mode_set(struct drm_encoder *encoder,
-    struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode)
-{
-	struct rk_vop_encoder *rkencoder = to_rk_vop_encoder(encoder);
-	struct rk_vop_softc * const sc = rkencoder->sc;
-	uint32_t val;
-	u_int pol;
-
-	const u_int hactive = adjusted_mode->hdisplay;
-	const u_int hfront_porch = adjusted_mode->hsync_start - adjusted_mode->hdisplay;
-	const u_int hsync_len = adjusted_mode->hsync_end - adjusted_mode->hsync_start;
-	const u_int hback_porch = adjusted_mode->htotal - adjusted_mode->hsync_end;
-
-	const u_int vactive = adjusted_mode->vdisplay;
-	const u_int vfront_porch = adjusted_mode->vsync_start - adjusted_mode->vdisplay;
-	const u_int vsync_len = adjusted_mode->vsync_end - adjusted_mode->vsync_start;
-	const u_int vback_porch = adjusted_mode->vtotal - adjusted_mode->vsync_end;
-
-	pol = DSP_DCLK_POL;
-	if ((adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) != 0)
-		pol |= DSP_HSYNC_POL;
-	if ((adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) != 0)
-		pol |= DSP_VSYNC_POL;
-	sc->sc_conf->set_polarity(sc, rkencoder->ep_type, pol);
-
-	val = RD4(sc, VOP_SYS_CTRL);
-	val &= ~VOP_STANDBY_EN;
-	val &= ~(MIPI_OUT_EN|EDP_OUT_EN|HDMI_OUT_EN|RGB_OUT_EN);
-	switch (rkencoder->ep_type) {
-	case VOP_EP_MIPI:
-	case VOP_EP_MIPI1:
-		val |= MIPI_OUT_EN;
-		break;
-	case VOP_EP_EDP:
-	case VOP_EP_DP:
-		val |= EDP_OUT_EN;
-		break;
-	case VOP_EP_HDMI:
-		val |= HDMI_OUT_EN;
-		break;
-	default:
-		break;
-	}
-	WR4(sc, VOP_SYS_CTRL, val);
-
-	val = RD4(sc, VOP_DSP_CTRL0);
-	val &= ~DSP_OUT_MODE;
-	val |= __SHIFTIN(sc->sc_conf->out_mode, DSP_OUT_MODE);
-	WR4(sc, VOP_DSP_CTRL0, val);
-
-	val = __SHIFTIN(hsync_len + hback_porch, DSP_HACT_ST_POST) |
-	      __SHIFTIN(hsync_len + hback_porch + hactive, DSP_HACT_END_POST);
-	WR4(sc, VOP_POST_DSP_HACT_INFO, val);
-
-	val = __SHIFTIN(hsync_len + hback_porch, DSP_HACT_ST) |
-	      __SHIFTIN(hsync_len + hback_porch + hactive, DSP_HACT_END);
-	WR4(sc, VOP_DSP_HACT_ST_END, val);
-
-	val = __SHIFTIN(hsync_len, DSP_HTOTAL) |
-	      __SHIFTIN(hsync_len + hback_porch + hactive + hfront_porch, DSP_HS_END);
-	WR4(sc, VOP_DSP_HTOTAL_HS_END, val);
-
-	val = __SHIFTIN(vsync_len + vback_porch, DSP_VACT_ST_POST) |
-	      __SHIFTIN(vsync_len + vback_porch + vactive, DSP_VACT_END_POST);
-	WR4(sc, VOP_POST_DSP_VACT_INFO, val);
-
-	val = __SHIFTIN(vsync_len + vback_porch, DSP_VACT_ST) |
-	      __SHIFTIN(vsync_len + vback_porch + vactive, DSP_VACT_END);
-	WR4(sc, VOP_DSP_VACT_ST_END, val);
-
-	val = __SHIFTIN(vsync_len, DSP_VTOTAL) |
-	      __SHIFTIN(vsync_len + vback_porch + vactive + vfront_porch, DSP_VS_END);
-	WR4(sc, VOP_DSP_VTOTAL_VS_END, val);
-}
-
-static void
-rk_vop_encoder_prepare(struct drm_encoder *encoder)
-{
-}
-
-static void
-rk_vop_encoder_commit(struct drm_encoder *encoder)
-{
-	struct rk_vop_encoder *rkencoder = to_rk_vop_encoder(encoder);
-	struct rk_vop_softc * const sc = rkencoder->sc;
-
-	/* Commit settings */
-	WR4(sc, VOP_REG_CFG_DONE, REG_LOAD_EN);
-}
-
-static const struct drm_encoder_helper_funcs rk_vop_encoder_helper_funcs = {
-	.dpms = rk_vop_encoder_dpms,
-	.mode_fixup = rk_vop_encoder_mode_fixup,
-	.prepare = rk_vop_encoder_prepare,
-	.commit = rk_vop_encoder_commit,
-	.mode_set = rk_vop_encoder_mode_set,
-};
-
 static int
 rk_vop_ep_activate(device_t dev, struct fdt_endpoint *ep, bool activate)
 {
 	struct rk_vop_softc * const sc = device_private(dev);
 	struct drm_device *ddev;
-	u_int encoder_type;
 
 	if (!activate)
 		return EINVAL;
@@ -542,28 +485,11 @@ rk_vop_ep_activate(device_t dev, struct 
 	}
 
 	const u_int ep_index = fdt_endpoint_index(ep);
-	switch (ep_index) {
-	case VOP_EP_MIPI:
-	case VOP_EP_MIPI1:
-		encoder_type = DRM_MODE_ENCODER_DSI;
-		break;
-	case VOP_EP_HDMI:
-	case VOP_EP_EDP:
-	case VOP_EP_DP:
-		encoder_type = DRM_MODE_ENCODER_TMDS;
-		break;
-	default:
+	if (ep_index >= VOP_NEP) {
 		DRM_ERROR("endpoint index %d out of range\n", ep_index);
 		return ENXIO;
 	}
 
-	sc->sc_encoder[ep_index].sc = sc;
-	sc->sc_encoder[ep_index].ep_type = ep_index;
-	sc->sc_encoder[ep_index].base.possible_crtcs = 1 << drm_crtc_index(&sc->sc_crtc.base);
-	drm_encoder_init(ddev, &sc->sc_encoder[ep_index].base, &rk_vop_encoder_funcs,
-	    encoder_type);
-	drm_encoder_helper_add(&sc->sc_encoder[ep_index].base, &rk_vop_encoder_helper_funcs);
-
 	return fdt_endpoint_activate(ep, activate);
 }
 
@@ -571,15 +497,8 @@ static void *
 rk_vop_ep_get_data(device_t dev, struct fdt_endpoint *ep)
 {
 	struct rk_vop_softc * const sc = device_private(dev);
-	const u_int ep_index = fdt_endpoint_index(ep);
-
-	if (ep_index >= VOP_NEP)
-		return NULL;
-
-	if (sc->sc_encoder[ep_index].sc == NULL)
-		return NULL;
 
-	return &sc->sc_encoder[ep_index].base;
+	return &sc->sc_crtc.base;
 }
 
 static int
@@ -646,7 +565,7 @@ rk_vop_attach(device_t parent, device_t 
 
 	sc->sc_ports.dp_ep_activate = rk_vop_ep_activate;
 	sc->sc_ports.dp_ep_get_data = rk_vop_ep_get_data;
-	fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_ENCODER);
+	fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_CRTC);
 
 	const int port_phandle = of_find_firstchild_byname(phandle, "port");
 	if (port_phandle > 0)

Reply via email to