summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2020-03-16 21:51:27 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2020-03-16 21:51:27 +0000
commit855d5c40bfe9c6907938bc9f222cfa53514f4706 (patch)
tree634c5ed6011a25fddd07b728610ba22bd58786aa /sys/dev
parent0671133882fe58e124c71ede42ecbc7dbdce0452 (diff)
Replace video "framework" with a more generic port/endpoint "framework".
This also adds panel support to rkanxdp(4). Code to hook up simplepanel(4) is still missing and will come later. ok patrick@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/fdt/rkanxdp.c90
-rw-r--r--sys/dev/fdt/rkdrm.c4
-rw-r--r--sys/dev/fdt/rkdwhdmi.c85
-rw-r--r--sys/dev/fdt/rkvop.c50
-rw-r--r--sys/dev/ic/anxdp.c5
-rw-r--r--sys/dev/ofw/ofw_misc.c168
-rw-r--r--sys/dev/ofw/ofw_misc.h58
-rw-r--r--sys/dev/pci/drm/files.drm4
8 files changed, 252 insertions, 212 deletions
diff --git a/sys/dev/fdt/rkanxdp.c b/sys/dev/fdt/rkanxdp.c
index 5791e7d7337..888abbee33d 100644
--- a/sys/dev/fdt/rkanxdp.c
+++ b/sys/dev/fdt/rkanxdp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rkanxdp.c,v 1.2 2020/03/01 10:19:35 kettenis Exp $ */
+/* $OpenBSD: rkanxdp.c,v 1.3 2020/03/16 21:51:25 kettenis Exp $ */
/* $NetBSD: rk_anxdp.c,v 1.2 2020/01/04 12:08:32 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jonathan A. Kollasch <jakllsch@kollasch.net>
@@ -53,17 +53,6 @@ enum {
ANXDP_PORT_OUTPUT = 1,
};
-struct rkanxdp_port {
- struct rkanxdp_softc *sc;
- struct rkanxdp_ep *ep;
- int nep;
-};
-
-struct rkanxdp_ep {
- struct rkanxdp_port *port;
- struct video_device vd;
-};
-
struct rkanxdp_softc {
struct anxdp_softc sc_base;
@@ -73,8 +62,7 @@ struct rkanxdp_softc {
int sc_activated;
- struct rkanxdp_port *sc_port;
- int sc_nport;
+ struct device_ports sc_ports;
};
#define to_rkanxdp_softc(x) container_of(x, struct rkanxdp_softc, sc_base)
@@ -94,8 +82,8 @@ void rkanxdp_encoder_prepare(struct drm_encoder *);
void rkanxdp_encoder_commit(struct drm_encoder *);
void rkanxdp_encoder_dpms(struct drm_encoder *, int);
-int rkanxdp_ep_activate(void *, struct drm_device *);
-void *rkanxdp_ep_get_data(void *);
+int rkanxdp_ep_activate(void *, struct endpoint *, void *);
+void *rkanxdp_ep_get_cookie(void *, struct endpoint *);
struct cfattach rkanxdp_ca = {
sizeof (struct rkanxdp_softc), rkanxdp_match, rkanxdp_attach
@@ -118,7 +106,7 @@ rkanxdp_attach(struct device *parent, struct device *self, void *aux)
{
struct rkanxdp_softc *sc = (struct rkanxdp_softc *)self;
struct fdt_attach_args *faa = aux;
- int i, j, ep, port, ports, grf;
+ uint32_t grf;
if (faa->fa_nreg < 1) {
printf(": no registers\n");
@@ -157,37 +145,11 @@ rkanxdp_attach(struct device *parent, struct device *self, void *aux)
return;
}
- ports = OF_getnodebyname(faa->fa_node, "ports");
- if (!ports)
- return;
-
- for (port = OF_child(ports); port; port = OF_peer(port))
- sc->sc_nport++;
- if (!sc->sc_nport)
- return;
-
- sc->sc_port = mallocarray(sc->sc_nport, sizeof(*sc->sc_port), M_DEVBUF,
- M_WAITOK | M_ZERO);
- for (i = 0, port = OF_child(ports); port; port = OF_peer(port), i++) {
- for (ep = OF_child(port); ep; ep = OF_peer(ep))
- sc->sc_port[i].nep++;
- if (!sc->sc_port[i].nep)
- continue;
- sc->sc_port[i].sc = sc;
- sc->sc_port[i].ep = mallocarray(sc->sc_port[i].nep,
- sizeof(*sc->sc_port[i].ep), M_DEVBUF, M_WAITOK | M_ZERO);
- for (j = 0, ep = OF_child(port); ep; ep = OF_peer(ep), j++) {
- sc->sc_port[i].ep[j].port = &sc->sc_port[i];
- sc->sc_port[i].ep[j].vd.vd_node = ep;
- sc->sc_port[i].ep[j].vd.vd_cookie =
- &sc->sc_port[i].ep[j];
- sc->sc_port[i].ep[j].vd.vd_ep_activate =
- rkanxdp_ep_activate;
- sc->sc_port[i].ep[j].vd.vd_ep_get_data =
- rkanxdp_ep_get_data;
- video_register(&sc->sc_port[i].ep[j].vd);
- }
- }
+ sc->sc_ports.dp_node = faa->fa_node;
+ sc->sc_ports.dp_cookie = sc;
+ sc->sc_ports.dp_ep_activate = rkanxdp_ep_activate;
+ sc->sc_ports.dp_ep_get_cookie = rkanxdp_ep_get_cookie;
+ device_ports_register(&sc->sc_ports, EP_DRM_ENCODER);
}
void
@@ -259,24 +221,37 @@ struct drm_encoder_helper_funcs rkanxdp_encoder_helper_funcs = {
};
int
-rkanxdp_ep_activate(void *cookie, struct drm_device *ddev)
+rkanxdp_ep_activate(void *cookie, struct endpoint *ep, void *arg)
{
- struct rkanxdp_ep *ep = cookie;
- struct rkanxdp_port *port = ep->port;
- struct rkanxdp_softc *sc = port->sc;
+ struct rkanxdp_softc *sc = cookie;
+ struct drm_crtc *crtc = NULL;
+ struct endpoint *rep;
int error;
if (sc->sc_activated)
return 0;
- if (OF_getpropint(OF_parent(ep->vd.vd_node), "reg", 0) != ANXDP_PORT_INPUT)
+ if (ep->ep_port->dp_reg != ANXDP_PORT_INPUT)
+ return EINVAL;
+
+ rep = endpoint_remote(ep);
+ if (rep && rep->ep_type == EP_DRM_CRTC)
+ crtc = endpoint_get_cookie(rep);
+ if (crtc == NULL)
return EINVAL;
sc->sc_encoder.possible_crtcs = 0x3; /* XXX */
- drm_encoder_init(ddev, &sc->sc_encoder, &rkanxdp_encoder_funcs,
+ drm_encoder_init(crtc->dev, &sc->sc_encoder, &rkanxdp_encoder_funcs,
DRM_MODE_ENCODER_TMDS, NULL);
drm_encoder_helper_add(&sc->sc_encoder, &rkanxdp_encoder_helper_funcs);
+ ep = endpoint_byreg(&sc->sc_ports, ANXDP_PORT_OUTPUT, 0);
+ if (ep) {
+ rep = endpoint_remote(ep);
+ if (rep && rep->ep_type == EP_DRM_PANEL)
+ sc->sc_base.sc_panel = endpoint_get_cookie(rep);
+ }
+
sc->sc_base.sc_connector.base.connector_type = DRM_MODE_CONNECTOR_eDP;
error = anxdp_bind(&sc->sc_base, &sc->sc_encoder);
if (error != 0)
@@ -287,11 +262,8 @@ rkanxdp_ep_activate(void *cookie, struct drm_device *ddev)
}
void *
-rkanxdp_ep_get_data(void *cookie)
+rkanxdp_ep_get_cookie(void *cookie, struct endpoint *ep)
{
- struct rkanxdp_ep *ep = cookie;
- struct rkanxdp_port *port = ep->port;
- struct rkanxdp_softc *sc = port->sc;
-
+ struct rkanxdp_softc *sc = cookie;
return &sc->sc_encoder;
}
diff --git a/sys/dev/fdt/rkdrm.c b/sys/dev/fdt/rkdrm.c
index ac12a48661b..9349bc092ea 100644
--- a/sys/dev/fdt/rkdrm.c
+++ b/sys/dev/fdt/rkdrm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rkdrm.c,v 1.2 2020/03/04 21:19:15 kettenis Exp $ */
+/* $OpenBSD: rkdrm.c,v 1.3 2020/03/16 21:51:25 kettenis Exp $ */
/* $NetBSD: rk_drm.c,v 1.3 2019/12/15 01:00:58 mrg Exp $ */
/*-
* Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca>
@@ -441,7 +441,7 @@ rkdrm_attachhook(struct device *dev)
ports = malloc(portslen, M_TEMP, M_WAITOK);
OF_getpropintarray(sc->sc_node, "ports", ports, portslen);
for (i = 0; i < portslen / sizeof(uint32_t); i++) {
- video_port_activate(ports[i], &sc->sc_ddev);
+ device_port_activate(ports[i], &sc->sc_ddev);
nports++;
}
free(ports, M_TEMP, portslen);
diff --git a/sys/dev/fdt/rkdwhdmi.c b/sys/dev/fdt/rkdwhdmi.c
index 0f015a68350..871ba0ef8dd 100644
--- a/sys/dev/fdt/rkdwhdmi.c
+++ b/sys/dev/fdt/rkdwhdmi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rkdwhdmi.c,v 1.2 2020/03/04 13:38:22 kettenis Exp $ */
+/* $OpenBSD: rkdwhdmi.c,v 1.3 2020/03/16 21:51:25 kettenis Exp $ */
/* $NetBSD: rk_dwhdmi.c,v 1.4 2019/12/17 18:26:36 jakllsch Exp $ */
/*-
@@ -69,22 +69,6 @@ const struct dwhdmi_phy_config rkdwhdmi_phy_config[] = {
{ 0, 0x0000, 0x0000, 0x0000 }
};
-enum {
- DWHDMI_PORT_INPUT = 0,
- DWHDMI_PORT_OUTPUT = 1,
-};
-
-struct rkdwhdmi_port {
- struct rkdwhdmi_softc *sc;
- struct rkdwhdmi_ep *ep;
- int nep;
-};
-
-struct rkdwhdmi_ep {
- struct rkdwhdmi_port *port;
- struct video_device vd;
-};
-
struct rkdwhdmi_softc {
struct dwhdmi_softc sc_base;
int sc_node;
@@ -96,8 +80,7 @@ struct rkdwhdmi_softc {
int sc_activated;
- struct rkdwhdmi_port *sc_port;
- int sc_nport;
+ struct device_ports sc_ports;
};
#define to_rkdwhdmi_softc(x) container_of(x, struct rkdwhdmi_softc, sc_base)
@@ -117,8 +100,8 @@ void rkdwhdmi_encoder_prepare(struct drm_encoder *);
void rkdwhdmi_encoder_commit(struct drm_encoder *);
void rkdwhdmi_encoder_dpms(struct drm_encoder *, int);
-int rkdwhdmi_ep_activate(void *, struct drm_device *);
-void *rkdwhdmi_ep_get_data(void *);
+int rkdwhdmi_ep_activate(void *, struct endpoint *, void *);
+void *rkdwhdmi_ep_get_cookie(void *, struct endpoint *);
void rkdwhdmi_enable(struct dwhdmi_softc *);
void rkdwhdmi_mode_set(struct dwhdmi_softc *, struct drm_display_mode *,
@@ -147,7 +130,7 @@ rkdwhdmi_attach(struct device *parent, struct device *self, void *aux)
{
struct rkdwhdmi_softc *sc = (struct rkdwhdmi_softc *)self;
struct fdt_attach_args *faa = aux;
- int i, j, ep, port, ports, grf;
+ uint32_t grf;
bus_addr_t addr;
bus_size_t size;
uint32_t phandle;
@@ -209,37 +192,11 @@ rkdwhdmi_attach(struct device *parent, struct device *self, void *aux)
return;
}
- ports = OF_getnodebyname(faa->fa_node, "ports");
- if (!ports)
- return;
-
- for (port = OF_child(ports); port; port = OF_peer(port))
- sc->sc_nport++;
- if (!sc->sc_nport)
- return;
-
- sc->sc_port = mallocarray(sc->sc_nport, sizeof(*sc->sc_port), M_DEVBUF,
- M_WAITOK | M_ZERO);
- for (i = 0, port = OF_child(ports); port; port = OF_peer(port), i++) {
- for (ep = OF_child(port); ep; ep = OF_peer(ep))
- sc->sc_port[i].nep++;
- if (!sc->sc_port[i].nep)
- continue;
- sc->sc_port[i].sc = sc;
- sc->sc_port[i].ep = mallocarray(sc->sc_port[i].nep,
- sizeof(*sc->sc_port[i].ep), M_DEVBUF, M_WAITOK | M_ZERO);
- for (j = 0, ep = OF_child(port); ep; ep = OF_peer(ep), j++) {
- sc->sc_port[i].ep[j].port = &sc->sc_port[i];
- sc->sc_port[i].ep[j].vd.vd_node = ep;
- sc->sc_port[i].ep[j].vd.vd_cookie =
- &sc->sc_port[i].ep[j];
- sc->sc_port[i].ep[j].vd.vd_ep_activate =
- rkdwhdmi_ep_activate;
- sc->sc_port[i].ep[j].vd.vd_ep_get_data =
- rkdwhdmi_ep_get_data;
- video_register(&sc->sc_port[i].ep[j].vd);
- }
- }
+ sc->sc_ports.dp_node = faa->fa_node;
+ sc->sc_ports.dp_cookie = sc;
+ sc->sc_ports.dp_ep_activate = rkdwhdmi_ep_activate;
+ sc->sc_ports.dp_ep_get_cookie = rkdwhdmi_ep_get_cookie;
+ device_ports_register(&sc->sc_ports, EP_DRM_ENCODER);
#ifdef notyet
fdtbus_register_dai_controller(self, phandle, &rkdwhdmi_dai_funcs);
@@ -306,21 +263,24 @@ struct drm_encoder_helper_funcs rkdwhdmi_encoder_helper_funcs = {
};
int
-rkdwhdmi_ep_activate(void *cookie, struct drm_device *ddev)
+rkdwhdmi_ep_activate(void *cookie, struct endpoint *ep, void *arg)
{
- struct rkdwhdmi_ep *ep = cookie;
- struct rkdwhdmi_port *port = ep->port;
- struct rkdwhdmi_softc *sc = port->sc;
+ struct rkdwhdmi_softc *sc = cookie;
+ struct drm_crtc *crtc = NULL;
+ struct endpoint *rep;
int error;
if (sc->sc_activated)
return 0;
- if (OF_getpropint(OF_parent(ep->vd.vd_node), "reg", 0) != DWHDMI_PORT_INPUT)
+ rep = endpoint_remote(ep);
+ if (rep && rep->ep_type == EP_DRM_CRTC)
+ crtc = endpoint_get_cookie(rep);
+ if (crtc == NULL)
return EINVAL;
sc->sc_encoder.possible_crtcs = 0x3; /* XXX */
- drm_encoder_init(ddev, &sc->sc_encoder, &rkdwhdmi_encoder_funcs,
+ drm_encoder_init(crtc->dev, &sc->sc_encoder, &rkdwhdmi_encoder_funcs,
DRM_MODE_ENCODER_TMDS, NULL);
drm_encoder_helper_add(&sc->sc_encoder, &rkdwhdmi_encoder_helper_funcs);
@@ -334,12 +294,9 @@ rkdwhdmi_ep_activate(void *cookie, struct drm_device *ddev)
}
void *
-rkdwhdmi_ep_get_data(void *cookie)
+rkdwhdmi_ep_get_cookie(void *cookie, struct endpoint *ep)
{
- struct rkdwhdmi_ep *ep = cookie;
- struct rkdwhdmi_port *port = ep->port;
- struct rkdwhdmi_softc *sc = port->sc;
-
+ struct rkdwhdmi_softc *sc = cookie;
return &sc->sc_encoder;
}
diff --git a/sys/dev/fdt/rkvop.c b/sys/dev/fdt/rkvop.c
index d008ddd97d2..404e2964815 100644
--- a/sys/dev/fdt/rkvop.c
+++ b/sys/dev/fdt/rkvop.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rkvop.c,v 1.1 2020/02/21 15:47:30 patrick Exp $ */
+/* $OpenBSD: rkvop.c,v 1.2 2020/03/16 21:51:25 kettenis Exp $ */
/* $NetBSD: rk_vop.c,v 1.6 2020/01/05 12:14:35 mrg Exp $ */
/*-
* Copyright (c) 2019 Jared D. McNeill <jmcneill@invisible.ca>
@@ -129,11 +129,6 @@ struct rkvop_crtc {
struct rkvop_softc *sc;
};
-struct rkvop_ep {
- struct rkvop_softc *sc;
- struct video_device vd;
-};
-
struct rkvop_softc {
struct device sc_dev;
bus_space_tag_t sc_iot;
@@ -142,8 +137,7 @@ struct rkvop_softc {
struct rkvop_config *sc_conf;
struct rkvop_crtc sc_crtc;
- struct rkvop_ep *sc_ep;
- int sc_nep;
+ struct device_ports sc_ports;
};
#define to_rkvop_crtc(x) container_of(x, struct rkvop_crtc, base)
@@ -182,8 +176,8 @@ void rkvop_commit(struct drm_crtc *);
void rk3399_vop_init(struct rkvop_softc *);
void rk3399_vop_set_polarity(struct rkvop_softc *, enum vop_ep_type, uint32_t);
-int rkvop_ep_activate(void *, struct drm_device *);
-void *rkvop_ep_get_data(void *);
+int rkvop_ep_activate(void *, struct endpoint *, void *);
+void *rkvop_ep_get_cookie(void *, struct endpoint *);
struct rkvop_config rk3399_vop_big_config = {
.descr = "RK3399 VOPB",
@@ -254,25 +248,11 @@ rkvop_attach(struct device *parent, struct device *self, void *aux)
if (sc->sc_conf->init != NULL)
sc->sc_conf->init(sc);
- port = OF_getnodebyname(faa->fa_node, "port");
- if (!port)
- return;
-
- for (ep = OF_child(port); ep; ep = OF_peer(ep))
- sc->sc_nep++;
- if (!sc->sc_nep)
- return;
-
- sc->sc_ep = mallocarray(sc->sc_nep, sizeof(*sc->sc_ep),
- M_DEVBUF, M_WAITOK | M_ZERO);
- for (i = 0, ep = OF_child(port); ep; ep = OF_peer(ep), i++) {
- sc->sc_ep[i].sc = sc;
- sc->sc_ep[i].vd.vd_node = ep;
- sc->sc_ep[i].vd.vd_cookie = &sc->sc_ep[i];
- sc->sc_ep[i].vd.vd_ep_activate = rkvop_ep_activate;
- sc->sc_ep[i].vd.vd_ep_get_data = rkvop_ep_get_data;
- video_register(&sc->sc_ep[i].vd);
- }
+ sc->sc_ports.dp_node = faa->fa_node;
+ sc->sc_ports.dp_cookie = sc;
+ sc->sc_ports.dp_ep_activate = rkvop_ep_activate;
+ sc->sc_ports.dp_ep_get_cookie = rkvop_ep_get_cookie;
+ device_ports_register(&sc->sc_ports, EP_DRM_CRTC);
}
int
@@ -534,10 +514,10 @@ struct drm_crtc_helper_funcs rkvop_crtc_helper_funcs = {
};
int
-rkvop_ep_activate(void *cookie, struct drm_device *ddev)
+rkvop_ep_activate(void *cookie, struct endpoint *ep, void *arg)
{
- struct rkvop_ep *ep = cookie;
- struct rkvop_softc *sc = ep->sc;
+ struct rkvop_softc *sc = cookie;
+ struct drm_device *ddev = arg;
if (sc->sc_crtc.sc == NULL) {
sc->sc_crtc.sc = sc;
@@ -553,11 +533,9 @@ rkvop_ep_activate(void *cookie, struct drm_device *ddev)
}
void *
-rkvop_ep_get_data(void *cookie)
+rkvop_ep_get_cookie(void *cookie, struct endpoint *ep)
{
- struct rkvop_ep *ep = cookie;
- struct rkvop_softc *sc = ep->sc;
-
+ struct rkvop_softc *sc = cookie;
return &sc->sc_crtc.base;
}
diff --git a/sys/dev/ic/anxdp.c b/sys/dev/ic/anxdp.c
index c5938cfbdf9..dda17dbad5c 100644
--- a/sys/dev/ic/anxdp.c
+++ b/sys/dev/ic/anxdp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: anxdp.c,v 1.1 2020/02/21 15:49:09 patrick Exp $ */
+/* $OpenBSD: anxdp.c,v 1.2 2020/03/16 21:51:25 kettenis Exp $ */
/* $NetBSD: anx_dp.c,v 1.2 2020/01/04 12:08:32 jmcneill Exp $ */
/*-
* Copyright (c) 2019 Jonathan A. Kollasch <jakllsch@kollasch.net>
@@ -311,6 +311,9 @@ anxdp_connector_get_modes(struct drm_connector *connector)
struct edid *pedid = NULL;
int error;
+ if (sc->sc_panel)
+ return drm_panel_get_modes(sc->sc_panel);
+
pedid = drm_get_edid(connector, &sc->sc_dpaux.ddc);
drm_connector_update_edid_property(connector, pedid);
diff --git a/sys/dev/ofw/ofw_misc.c b/sys/dev/ofw/ofw_misc.c
index 880457d93d1..53f3aa89685 100644
--- a/sys/dev/ofw/ofw_misc.c
+++ b/sys/dev/ofw/ofw_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofw_misc.c,v 1.14 2020/03/01 18:00:12 kettenis Exp $ */
+/* $OpenBSD: ofw_misc.c,v 1.15 2020/03/16 21:51:26 kettenis Exp $ */
/*
* Copyright (c) 2017 Mark Kettenis
*
@@ -440,57 +440,159 @@ nvmem_read_cell(int node, const char *name, void *data, bus_size_t size)
return nd->nd_read(nd->nd_cookie, nc->nc_addr, data, size);
}
-/* Video interface support */
+/* Port/endpoint interface support */
-LIST_HEAD(, video_device) video_devices =
- LIST_HEAD_INITIALIZER(video_devices);
+LIST_HEAD(, endpoint) endpoints =
+ LIST_HEAD_INITIALIZER(endpoints);
void
-video_register(struct video_device *vd)
+endpoint_register(int node, struct device_port *dp, enum endpoint_type type)
{
- vd->vd_phandle = OF_getpropint(vd->vd_node, "phandle", 0);
- if (vd->vd_phandle == 0)
+ struct endpoint *ep;
+
+ ep = malloc(sizeof(*ep), M_DEVBUF, M_WAITOK);
+ ep->ep_node = node;
+ ep->ep_phandle = OF_getpropint(node, "phandle", 0);
+ ep->ep_reg = OF_getpropint(node, "reg", -1);
+ ep->ep_port = dp;
+ ep->ep_type = type;
+
+ LIST_INSERT_HEAD(&endpoints, ep, ep_list);
+ LIST_INSERT_HEAD(&dp->dp_endpoints, ep, ep_plist);
+}
+
+void
+device_port_register(int node, struct device_ports *ports,
+ enum endpoint_type type)
+{
+ struct device_port *dp;
+
+ dp = malloc(sizeof(*dp), M_DEVBUF, M_WAITOK);
+ dp->dp_node = node;
+ dp->dp_phandle = OF_getpropint(node, "phandle", 0);
+ dp->dp_reg = OF_getpropint(node, "reg", -1);
+ dp->dp_ports = ports;
+ LIST_INIT(&dp->dp_endpoints);
+ for (node = OF_child(node); node; node = OF_peer(node))
+ endpoint_register(node, dp, type);
+
+ LIST_INSERT_HEAD(&ports->dp_ports, dp, dp_list);
+}
+
+void
+device_ports_register(struct device_ports *ports,
+ enum endpoint_type type)
+{
+ int node;
+
+ LIST_INIT(&ports->dp_ports);
+
+ node = OF_getnodebyname(ports->dp_node, "ports");
+ if (node == 0) {
+ node = OF_getnodebyname(ports->dp_node, "port");
+ if (node == 0)
+ return;
+
+ device_port_register(node, ports, type);
return;
- LIST_INSERT_HEAD(&video_devices, vd, vd_list);
+ }
+
+ for (node = OF_child(node); node; node = OF_peer(node))
+ device_port_register(node, ports, type);
}
-int
-video_port_activate(uint32_t phandle, struct drm_device *ddev)
+struct endpoint *
+endpoint_byphandle(uint32_t phandle)
{
- uint32_t ep, rep;
- int node, error;
+ struct endpoint *ep;
- node = OF_getnodebyphandle(phandle);
- if (node == 0)
- return ENXIO;
+ LIST_FOREACH(ep, &endpoints, ep_list) {
+ if (ep->ep_phandle == phandle)
+ return ep;
+ }
- for (node = OF_child(node); node; node = OF_peer(node)) {
- ep = OF_getpropint(node, "phandle", 0);
- rep = OF_getpropint(node, "remote-endpoint", 0);
- if (ep == 0 || rep == 0)
- continue;
- error = video_endpoint_activate(ep, ddev);
- if (error)
- continue;
- error = video_endpoint_activate(rep, ddev);
- if (error)
+ return NULL;
+}
+
+struct endpoint *
+endpoint_byreg(struct device_ports *ports, uint32_t dp_reg, uint32_t ep_reg)
+{
+ struct device_port *dp;
+ struct endpoint *ep;
+
+ LIST_FOREACH(dp, &ports->dp_ports, dp_list) {
+ if (dp->dp_reg != dp_reg)
continue;
+ LIST_FOREACH(ep, &dp->dp_endpoints, ep_list) {
+ if (ep->ep_reg != ep_reg)
+ continue;
+ return ep;
+ }
+ }
+
+ return NULL;
+}
+
+struct endpoint *
+endpoint_remote(struct endpoint *ep)
+{
+ struct endpoint *rep;
+ int phandle;
+
+ phandle = OF_getpropint(ep->ep_node, "remote-endpoint", 0);
+ if (phandle == 0)
+ return NULL;
+
+ LIST_FOREACH(rep, &endpoints, ep_list) {
+ if (rep->ep_phandle == phandle)
+ return rep;
}
- return 0;
+ return NULL;
}
int
-video_endpoint_activate(uint32_t phandle, struct drm_device *ddev)
+endpoint_activate(struct endpoint *ep, void *arg)
+{
+ struct device_ports *ports = ep->ep_port->dp_ports;
+ return ports->dp_ep_activate(ports->dp_cookie, ep, arg);
+}
+
+void *
+endpoint_get_cookie(struct endpoint *ep)
{
- struct video_device *vd;
+ struct device_ports *ports = ep->ep_port->dp_ports;
+ return ports->dp_ep_get_cookie(ports->dp_cookie, ep);
+}
- LIST_FOREACH(vd, &video_devices, vd_list) {
- if (vd->vd_phandle == phandle)
+void
+device_port_activate(uint32_t phandle, void *arg)
+{
+ struct device_ports *ports;
+ struct device_port *dp;
+ struct endpoint *ep, *rep;
+ int error;
+
+ LIST_FOREACH(ep, &endpoints, ep_list) {
+ if (ep->ep_port->dp_phandle == phandle) {
+ dp = ep->ep_port;
break;
+ }
}
- if (vd == NULL)
- return ENXIO;
+ if (dp == NULL)
+ return;
- return vd->vd_ep_activate(vd->vd_cookie, ddev);
+ ports = dp->dp_ports;
+ LIST_FOREACH(ep, &dp->dp_endpoints, ep_plist) {
+ rep = endpoint_remote(ep);
+ if (rep == NULL)
+ continue;
+
+ error = endpoint_activate(ep, arg);
+ if (error)
+ continue;
+ error = endpoint_activate(rep, arg);
+ if (error)
+ continue;
+ }
}
diff --git a/sys/dev/ofw/ofw_misc.h b/sys/dev/ofw/ofw_misc.h
index 35a9b15c1a0..8dc20e9c33b 100644
--- a/sys/dev/ofw/ofw_misc.h
+++ b/sys/dev/ofw/ofw_misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofw_misc.h,v 1.10 2020/02/21 15:46:16 patrick Exp $ */
+/* $OpenBSD: ofw_misc.h,v 1.11 2020/03/16 21:51:26 kettenis Exp $ */
/*
* Copyright (c) 2017 Mark Kettenis
*
@@ -129,24 +129,52 @@ void nvmem_register(struct nvmem_device *);
int nvmem_read(uint32_t, bus_addr_t, void *, bus_size_t);
int nvmem_read_cell(int, const char *name, void *, bus_size_t);
-/* Video interface support */
+/* Port/endpoint interface support */
-struct drm_device;
-struct video_device {
- int vd_node;
- void *vd_cookie;
- int (*vd_read)(void *, bus_addr_t, void *, bus_size_t);
+struct endpoint;
- int (*vd_ep_activate)(void *, struct drm_device *);
- void * (*vd_ep_get_data)(void *);
+struct device_ports {
+ int dp_node;
+ void *dp_cookie;
- LIST_ENTRY(video_device) vd_list;
- uint32_t vd_phandle;
+ int (*dp_ep_activate)(void *, struct endpoint *, void *);
+ void *(*dp_ep_get_cookie)(void *, struct endpoint *);
+
+ LIST_HEAD(, device_port) dp_ports;
+};
+
+struct device_port {
+ int dp_node;
+ uint32_t dp_phandle;
+ uint32_t dp_reg;
+ struct device_ports *dp_ports;
+ LIST_ENTRY(device_port) dp_list;
+ LIST_HEAD(, endpoint) dp_endpoints;
+};
+
+enum endpoint_type {
+ EP_DRM_BRIDGE = 1, /* struct drm_bridge */
+ EP_DRM_CONNECTOR, /* struct drm_connector */
+ EP_DRM_CRTC, /* struct drm_crtc */
+ EP_DRM_ENCODER, /* struct drm_encoder */
+ EP_DRM_PANEL, /* struct drm_panel */
+};
+
+struct endpoint {
+ int ep_node;
+ uint32_t ep_phandle;
+ uint32_t ep_reg;
+ enum endpoint_type ep_type;
+ struct device_port *ep_port;
+ LIST_ENTRY(endpoint) ep_list;
+ LIST_ENTRY(endpoint) ep_plist;
};
-void video_register(struct video_device *);
-int video_port_activate(uint32_t, struct drm_device *);
-int video_endpoint_activate(uint32_t, struct drm_device *);
-void * video_endpoint_get_data(uint32_t);
+void device_ports_register(struct device_ports *, enum endpoint_type);
+void device_port_activate(uint32_t, void *);
+struct endpoint *endpoint_byreg(struct device_ports *, uint32_t, uint32_t);
+struct endpoint *endpoint_remote(struct endpoint *);
+int endpoint_activate(struct endpoint *, void *);
+void *endpoint_get_cookie(struct endpoint *);
#endif /* _DEV_OFW_MISC_H_ */
diff --git a/sys/dev/pci/drm/files.drm b/sys/dev/pci/drm/files.drm
index 3a9312d5def..f72be879d27 100644
--- a/sys/dev/pci/drm/files.drm
+++ b/sys/dev/pci/drm/files.drm
@@ -1,5 +1,5 @@
# $NetBSD: files.drm,v 1.2 2007/03/28 11:29:37 jmcneill Exp $
-# $OpenBSD: files.drm,v 1.47 2019/08/28 10:17:59 kettenis Exp $
+# $OpenBSD: files.drm,v 1.48 2020/03/16 21:51:25 kettenis Exp $
# direct rendering modules
define drmbase {[primary = -1]}
@@ -41,7 +41,7 @@ file dev/pci/drm/drm_mode_object.c drm
file dev/pci/drm/drm_modes.c drm
file dev/pci/drm/drm_modeset_helper.c drm
file dev/pci/drm/drm_modeset_lock.c drm
-file dev/pci/drm/drm_panel.c drm & inteldrm
+file dev/pci/drm/drm_panel.c drm
file dev/pci/drm/drm_panel_orientation_quirks.c drm
file dev/pci/drm/drm_plane.c drm
file dev/pci/drm/drm_plane_helper.c drm