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/b93d4cdd9ea5
branches: trunk
changeset: 967674:b93d4cdd9ea5
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 35dd09888fb6 -r b93d4cdd9ea5 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 35dd09888fb6 -r b93d4cdd9ea5 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