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 <[email protected]>
@@ -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 <[email protected]>
@@ -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)