diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-03-16 21:51:27 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-03-16 21:51:27 +0000 |
commit | 855d5c40bfe9c6907938bc9f222cfa53514f4706 (patch) | |
tree | 634c5ed6011a25fddd07b728610ba22bd58786aa /sys/dev | |
parent | 0671133882fe58e124c71ede42ecbc7dbdce0452 (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.c | 90 | ||||
-rw-r--r-- | sys/dev/fdt/rkdrm.c | 4 | ||||
-rw-r--r-- | sys/dev/fdt/rkdwhdmi.c | 85 | ||||
-rw-r--r-- | sys/dev/fdt/rkvop.c | 50 | ||||
-rw-r--r-- | sys/dev/ic/anxdp.c | 5 | ||||
-rw-r--r-- | sys/dev/ofw/ofw_misc.c | 168 | ||||
-rw-r--r-- | sys/dev/ofw/ofw_misc.h | 58 | ||||
-rw-r--r-- | sys/dev/pci/drm/files.drm | 4 |
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 |