Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/arm/rockchip Move drm_encoder from rkvop(4) to the ...



details:   https://anonhg.NetBSD.org/src/rev/365f4e489087
branches:  trunk
changeset: 847308:365f4e489087
user:      jakllsch <jakllsch%NetBSD.org@localhost>
date:      Tue Dec 17 18:26:36 2019 +0000

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

diffstat:

 sys/arch/arm/rockchip/rk_dwhdmi.c |  101 ++++++++++++----
 sys/arch/arm/rockchip/rk_vop.c    |  235 ++++++++++++-------------------------
 2 files changed, 153 insertions(+), 183 deletions(-)

diffs (truncated from 513 to 300 lines):

diff -r 0d49962586e5 -r 365f4e489087 sys/arch/arm/rockchip/rk_dwhdmi.c
--- a/sys/arch/arm/rockchip/rk_dwhdmi.c Tue Dec 17 18:16:05 2019 +0000
+++ b/sys/arch/arm/rockchip/rk_dwhdmi.c Tue Dec 17 18:26:36 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
 #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 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 @@
        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 @@
                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 @@
 {
        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 @@
 
        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);
 }
diff -r 0d49962586e5 -r 365f4e489087 sys/arch/arm/rockchip/rk_vop.c
--- a/sys/arch/arm/rockchip/rk_vop.c    Tue Dec 17 18:16:05 2019 +0000
+++ b/sys/arch/arm/rockchip/rk_vop.c    Tue Dec 17 18:26:36 2019 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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_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 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 @@
 };
 
 #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 @@
        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_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);



Home | Main Index | Thread Index | Old Index