Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/arm/ti drm: Do the attach task dance for ti lcdc drm.
details: https://anonhg.NetBSD.org/src/rev/5c433035d88f
branches: trunk
changeset: 1029026:5c433035d88f
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sun Dec 19 12:44:57 2021 +0000
description:
drm: Do the attach task dance for ti lcdc drm.
diffstat:
sys/arch/arm/ti/ti_fb.c | 21 +++++++++++-
sys/arch/arm/ti/ti_lcdc.c | 71 +++++++++++++++++++++++++++++++++++++++++++++-
sys/arch/arm/ti/ti_lcdc.h | 22 +++++++++++++-
3 files changed, 107 insertions(+), 7 deletions(-)
diffs (245 lines):
diff -r a6a5b386c9f2 -r 5c433035d88f sys/arch/arm/ti/ti_fb.c
--- a/sys/arch/arm/ti/ti_fb.c Sun Dec 19 12:44:50 2021 +0000
+++ b/sys/arch/arm/ti/ti_fb.c Sun Dec 19 12:44:57 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_fb.c,v 1.2 2021/12/19 12:44:25 riastradh Exp $ */
+/* $NetBSD: ti_fb.c,v 1.3 2021/12/19 12:44:57 riastradh Exp $ */
/*-
* Copyright (c) 2015-2019 Jared McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "opt_wsdisplay_compat.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ti_fb.c,v 1.2 2021/12/19 12:44:25 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ti_fb.c,v 1.3 2021/12/19 12:44:57 riastradh Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -46,6 +46,8 @@
static int ti_fb_match(device_t, cfdata_t, void *);
static void ti_fb_attach(device_t, device_t, void *);
+static void tilcdc_fb_init(struct tilcdc_drm_task *);
+
static bool ti_fb_shutdown(device_t, int);
struct ti_fb_softc {
@@ -53,6 +55,7 @@
device_t sc_dev;
struct tilcdc_framebuffer *sc_fb;
struct tilcdcfb_attach_args sc_tfa;
+ struct tilcdc_drm_task sc_attach_task;
};
static paddr_t ti_fb_mmapfb(struct drmfb_softc *, off_t, int);
@@ -78,7 +81,6 @@
{
struct ti_fb_softc * const sc = device_private(self);
struct tilcdcfb_attach_args * const tfa = aux;
- int error;
sc->sc_dev = self;
sc->sc_tfa = *tfa;
@@ -87,6 +89,18 @@
aprint_naive("\n");
aprint_normal("\n");
+ tilcdc_task_init(&sc->sc_attach_task, &tilcdc_fb_init);
+ tilcdc_task_schedule(parent, &sc->sc_attach_task);
+}
+
+static void
+tilcdc_fb_init(struct tilcdc_drm_task *task)
+{
+ struct ti_fb_softc *sc = container_of(task, struct ti_fb_softc,
+ sc_attach_task);
+ device_t self = sc->sc_dev;
+ struct tilcdcfb_attach_args * const tfa = &sc->sc_tfa;
+
#ifdef WSDISPLAY_MULTICONS
prop_dictionary_t dict = device_properties(self);
const bool is_console = true;
@@ -101,6 +115,7 @@
.da_fb_linebytes = tfa->tfa_fb_linebytes,
.da_params = &tifb_drmfb_params,
};
+ int error;
error = drmfb_attach(&sc->sc_drmfb, &da);
if (error) {
diff -r a6a5b386c9f2 -r 5c433035d88f sys/arch/arm/ti/ti_lcdc.c
--- a/sys/arch/arm/ti/ti_lcdc.c Sun Dec 19 12:44:50 2021 +0000
+++ b/sys/arch/arm/ti/ti_lcdc.c Sun Dec 19 12:44:57 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_lcdc.c,v 1.9 2021/12/19 12:44:25 riastradh Exp $ */
+/* $NetBSD: ti_lcdc.c,v 1.10 2021/12/19 12:44:57 riastradh Exp $ */
/*-
* Copyright (c) 2019 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ti_lcdc.c,v 1.9 2021/12/19 12:44:25 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ti_lcdc.c,v 1.10 2021/12/19 12:44:57 riastradh Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -70,6 +70,8 @@
static int tilcdc_load(struct drm_device *, unsigned long);
static void tilcdc_unload(struct drm_device *);
+static void tilcdc_drm_task_work(struct work *, void *);
+
static struct drm_driver tilcdc_driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM,
.dev_priv_size = 0,
@@ -415,6 +417,15 @@
sc->sc_ports.dp_ep_get_data = tilcdc_ep_get_data;
fdt_ports_register(&sc->sc_ports, self, phandle, EP_DRM_ENCODER);
+ sc->sc_task_thread = NULL;
+ SIMPLEQ_INIT(&sc->sc_tasks);
+ if (workqueue_create(&sc->sc_task_wq, "tilcdcdrm",
+ &tilcdc_drm_task_work, NULL, PRI_NONE, IPL_NONE, WQ_MPSAFE)) {
+ aprint_error_dev(self, "unable to create workqueue\n");
+ sc->sc_task_wq = NULL;
+ return;
+ }
+
sc->sc_ddev = drm_dev_alloc(driver, sc->sc_dev);
if (IS_ERR(sc->sc_ddev)) {
aprint_error_dev(self, "couldn't allocate DRM device\n");
@@ -426,17 +437,43 @@
sc->sc_ddev->dmat = sc->sc_ddev->bus_dmat;
sc->sc_ddev->dmat_subregion_p = false;
+ /*
+ * Cause any tasks issued synchronously during attach to be
+ * processed at the end of this function.
+ */
+ sc->sc_task_thread = curlwp;
+
error = -drm_dev_register(sc->sc_ddev, 0);
if (error) {
drm_dev_put(sc->sc_ddev);
+ sc->sc_ddev = NULL;
aprint_error_dev(self, "couldn't register DRM device: %d\n",
error);
- return;
+ goto out;
}
+ sc->sc_dev_registered = true;
aprint_normal_dev(self, "initialized %s %d.%d.%d %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
driver->date, sc->sc_ddev->primary->index);
+
+ /*
+ * Process asynchronous tasks queued synchronously during
+ * attach. This will be for display detection to attach a
+ * framebuffer, so we have the opportunity for a console device
+ * to attach before autoconf has completed, in time for init(8)
+ * to find that console without panicking.
+ */
+ while (!SIMPLEQ_EMPTY(&sc->sc_tasks)) {
+ struct tilcdc_drm_task *const task =
+ SIMPLEQ_FIRST(&sc->sc_tasks);
+
+ SIMPLEQ_REMOVE_HEAD(&sc->sc_tasks, tdt_u.queue);
+ (*task->tdt_fn)(task);
+ }
+
+out: /* Cause any subesquent tasks to be processed by the workqueue. */
+ atomic_store_relaxed(&sc->sc_task_thread, NULL);
}
static int
@@ -630,3 +667,31 @@
drm_mode_config_cleanup(ddev);
}
+
+static void
+tilcdc_drm_task_work(struct work *work, void *cookie)
+{
+ struct tilcdc_drm_task *task = container_of(work,
+ struct tilcdc_drm_task, tdt_u.work);
+
+ (*task->tdt_fn)(task);
+}
+
+void
+tilcdc_task_init(struct tilcdc_drm_task *task,
+ void (*fn)(struct tilcdc_drm_task *))
+{
+
+ task->tdt_fn = fn;
+}
+
+void
+tilcdc_task_schedule(device_t self, struct tilcdc_drm_task *task)
+{
+ struct tilcdc_softc *sc = device_private(self);
+
+ if (atomic_load_relaxed(&sc->sc_task_thread) == curlwp)
+ SIMPLEQ_INSERT_TAIL(&sc->sc_tasks, task, tdt_u.queue);
+ else
+ workqueue_enqueue(sc->sc_task_wq, &task->tdt_u.work, NULL);
+}
diff -r a6a5b386c9f2 -r 5c433035d88f sys/arch/arm/ti/ti_lcdc.h
--- a/sys/arch/arm/ti/ti_lcdc.h Sun Dec 19 12:44:50 2021 +0000
+++ b/sys/arch/arm/ti/ti_lcdc.h Sun Dec 19 12:44:57 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ti_lcdc.h,v 1.2 2021/12/19 12:44:25 riastradh Exp $ */
+/* $NetBSD: ti_lcdc.h,v 1.3 2021/12/19 12:44:57 riastradh Exp $ */
/*-
* Copyright (c) 2019 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,6 +29,8 @@
#ifndef _ARM_TI_TI_LCDC_H
#define _ARM_TI_TI_LCDC_H
+#include <sys/workqueue.h>
+
#include <drm/drm_encoder.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_cma_helper.h>
@@ -74,6 +76,12 @@
struct clk *sc_clk;
int sc_phandle;
+ struct lwp *sc_task_thread;
+ SIMPLEQ_HEAD(, tilcdc_drm_task) sc_tasks;
+ struct workqueue *sc_task_wq;
+
+ bool sc_dev_registered;
+
struct tilcdc_crtc sc_crtc;
struct tilcdc_encoder sc_encoder;
struct tilcdc_vblank sc_vbl;
@@ -99,6 +107,14 @@
uint32_t tfa_fb_linebytes;
};
+struct tilcdc_drm_task {
+ union {
+ SIMPLEQ_ENTRY(tilcdc_drm_task) queue;
+ struct work work;
+ } tdt_u;
+ void (*tdt_fn)(struct tilcdc_drm_task *);
+};
+
#define tilcdc_private(ddev) (ddev)->dev_private
#define to_tilcdc_framebuffer(x) container_of(x, struct tilcdc_framebuffer, base)
#define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base)
@@ -108,4 +124,8 @@
#define WR4(sc, reg, val) \
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+void tilcdc_task_init(struct tilcdc_drm_task *,
+ void (*)(struct tilcdc_drm_task *));
+void tilcdc_task_schedule(device_t, struct tilcdc_drm_task *);
+
#endif /* _ARM_TI_TI_LCDC_H */
Home |
Main Index |
Thread Index |
Old Index