summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-03-17 15:49:38 +0000
committerkettenis <kettenis@openbsd.org>2020-03-17 15:49:38 +0000
commita8951e273b10d75e7f1b4612efc67c4136e2df5f (patch)
treedcfb2420585592e8205f1e72f66144da3b3625a0
parentDo not return early if no bits changed because may still need to change the style. (diff)
downloadwireguard-openbsd-a8951e273b10d75e7f1b4612efc67c4136e2df5f.tar.xz
wireguard-openbsd-a8951e273b10d75e7f1b4612efc67c4136e2df5f.zip
Hook this up to the drm(4) panel code and add an override for the
"boe,nv140fhmn49" panel, which is the panel found on the pinebook pro. This particular panel advertizes a mode which on some machines isn't usuable (but works fine on other machines). ok patrick@
-rw-r--r--sys/dev/fdt/simplepanel.c95
1 files changed, 89 insertions, 6 deletions
diff --git a/sys/dev/fdt/simplepanel.c b/sys/dev/fdt/simplepanel.c
index 88a4ce8fb97..77a15e6af40 100644
--- a/sys/dev/fdt/simplepanel.c
+++ b/sys/dev/fdt/simplepanel.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: simplepanel.c,v 1.1 2020/01/26 06:20:30 patrick Exp $ */
+/* $OpenBSD: simplepanel.c,v 1.2 2020/03/17 15:49:38 kettenis Exp $ */
/*
* Copyright (c) 2020 Patrick Wildt <patrick@blueri.se>
*
@@ -28,34 +28,65 @@
#include <dev/ofw/ofw_pinctrl.h>
#include <dev/ofw/ofw_regulator.h>
+#include <drm/drm_modes.h>
+#include <drm/drm_panel.h>
+
+const struct drm_display_mode boe_nv140fhmn49_mode = {
+ .clock = 148500,
+ .hdisplay = 1920,
+ .hsync_start = 1920 + 48,
+ .hsync_end = 1920 + 48 + 32,
+ .htotal = 2200,
+ .vdisplay = 1080,
+ .vsync_start = 1080 + 3,
+ .vsync_end = 1080 + 3 + 5,
+ .vtotal = 1125,
+ .vrefresh = 60,
+};
+
int simplepanel_match(struct device *, void *, void *);
void simplepanel_attach(struct device *, struct device *, void *);
+struct simplepanel_softc {
+ struct device sc_dev;
+ struct device_ports sc_ports;
+ struct drm_panel sc_panel;
+ const struct drm_display_mode *sc_mode;
+};
+
struct cfattach simplepanel_ca = {
- sizeof (struct device), simplepanel_match, simplepanel_attach
+ sizeof (struct simplepanel_softc),
+ simplepanel_match, simplepanel_attach
};
struct cfdriver simplepanel_cd = {
NULL, "simplepanel", DV_DULL
};
+void *simplepanel_ep_get_cookie(void *, struct endpoint *);
+int simplepanel_get_modes(struct drm_panel *);
+
+struct drm_panel_funcs simplepanel_funcs = {
+ .get_modes = simplepanel_get_modes
+};
+
int
simplepanel_match(struct device *parent, void *match, void *aux)
{
struct fdt_attach_args *faa = aux;
- return OF_is_compatible(faa->fa_node, "simple-panel");
+ return (OF_is_compatible(faa->fa_node, "simple-panel") ||
+ OF_is_compatible(faa->fa_node, "boe,nv140fhmn49"));
}
void
simplepanel_attach(struct device *parent, struct device *self, void *aux)
{
+ struct simplepanel_softc *sc = (struct simplepanel_softc *)self;
struct fdt_attach_args *faa = aux;
uint32_t power_supply;
uint32_t *gpios;
- int len;
-
- printf("\n");
+ int len, err;
pinctrl_byname(faa->fa_node, "default");
@@ -71,4 +102,56 @@ simplepanel_attach(struct device *parent, struct device *self, void *aux)
gpio_controller_set_pin(&gpios[0], 1);
free(gpios, M_TEMP, len);
}
+
+ if (OF_is_compatible(faa->fa_node, "boe,nv140fhmn49"))
+ sc->sc_mode = &boe_nv140fhmn49_mode;
+
+ drm_panel_init(&sc->sc_panel);
+ sc->sc_panel.dev = self;
+ sc->sc_panel.funcs = &simplepanel_funcs;
+ err = drm_panel_add(&sc->sc_panel);
+ if (err < 0) {
+ printf(": can't register panel\n");
+ return;
+ }
+
+ printf("\n");
+
+ sc->sc_ports.dp_node = faa->fa_node;
+ sc->sc_ports.dp_cookie = sc;
+ sc->sc_ports.dp_ep_get_cookie = simplepanel_ep_get_cookie;
+ device_ports_register(&sc->sc_ports, EP_DRM_PANEL);
+}
+
+void *
+simplepanel_ep_get_cookie(void *cookie, struct endpoint *ep)
+{
+ struct simplepanel_softc *sc = cookie;
+ return &sc->sc_panel;
+}
+
+static inline struct simplepanel_softc *
+to_simplepanel(struct drm_panel *panel)
+{
+ return container_of(panel, struct simplepanel_softc, sc_panel);
+}
+
+int
+simplepanel_get_modes(struct drm_panel *panel)
+{
+ struct drm_connector *connector = panel->connector;
+ struct simplepanel_softc *sc = to_simplepanel(panel);
+ struct drm_display_mode *mode;
+
+ if (sc->sc_mode == NULL)
+ return 0;
+
+ mode = drm_mode_duplicate(panel->drm, sc->sc_mode);
+ if (mode == NULL)
+ return 0;
+ mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
+
+ drm_mode_set_name(mode);
+ drm_mode_probed_add(connector, mode);
+ return 1;
}