Thread (57 messages) 57 messages, 8 authors, 2015-11-19

[PATCH 08/19] drm: Add Allwinner A10 Display Engine support

From: Daniel Vetter <hidden>
Date: 2015-11-16 15:04:15
Also in: dri-devel, linux-clk, linux-devicetree, lkml

On Wed, Nov 11, 2015 at 02:14:12PM -0800, Maxime Ripard wrote:
Hi Daniel,

Thanks for your review!
Back from vacation, sorry for the delay.
On Fri, Oct 30, 2015 at 03:44:09PM +0100, Daniel Vetter wrote:
quoted
quoted
+static void sun4i_crtc_disable(struct drm_crtc *crtc)
+{
+	struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc);
+	struct sun4i_drv *drv = scrtc->drv;
+
+	DRM_DEBUG_DRIVER("Disabling the CRTC\n");
+
+	if (!scrtc->enabled)
+		return;
Please don't do this - the atomic state should always reflect the true hw
state (fix that up with either hw state readout or reset in the ->reset
callbacks), and the atomic helpers guarantee that they'll never call you
when not needed. If you don't trust them do a WARN_ON at least, but no
early silent returns.

Personally I'd just rip it out, it's too much trouble. And for debugging
the atomic helpers already trace it all (or at least should).
Ok. Is there a preferred way to do HW state readout, or should I just
add that to my probe?
There's no preferred way yet (i.e. something supported in a standard
fashion through helpers). I'd place it in your various ->reset hooks
though. The idea from atomic helpers is that ->reset should make sure that
atomic state structures (i.e. drm_crtc/connector/plane_state or your
driver-specific subclasses of them) should match with the hw state. Either
by resetting the hw or by reading out the hw state inte freshly-allocated
structures.
quoted
quoted
+static int sun4i_drv_connector_plug_all(struct drm_device *drm)
Laurent Pinchart has this as a rfc patch for drm core, please coordinate
with him and rebase on top of his patches.
Ack, I will.
quoted
quoted
+static int sun4i_drv_enable_vblank(struct drm_device *drm, int pipe)
+{
+	struct sun4i_drv *drv = drm->dev_private;
+	struct sun4i_tcon *tcon = drv->tcon;
+
+	DRM_DEBUG_DRIVER("Enabling VBLANK on pipe %d\n", pipe);
+
+	sun4i_tcon_enable_vblank(tcon, true);
+
+	return 0;
atomic helpers rely on enable_vblank failing correctly when the pipe is
off and vlbanks will never happen. You probably need a correct error code
here that checks crtc->state->active (well not that directly but something
derived from it, since the pointer chase would be racy).
Ok.
quoted
I know it's a bit a mess since we don't have kms-native vblank driver
hooks yet and really the drm core should get this right for you. It'll
happen eventually, but drm_irq.c is a bit moldy ;-)
I can't really use drm_irq anyway, since we don't have a single
interrupt for the VBLANK, but two, that we have to use depending on
the output.
drm_irq has 2 parts: irq handling, which only supports 1 hw irq line, and
which is totally optional.

2nd part is the vblank support (all the drm_vblank and drm_crtc_vblank_)
functions, which are completely agnostic to how exactly your hw signals a
vblank for a given output. Those are mandatory if you want to support
vblanks (and really, you want to support vblanks). So whether you have 2
hw irq lines or 1 hw irq line with some additional status register doesn't
matter, since the hw irq -> logical drm_crtc mapping for vblank events is
done in the driver.

Yes I know we should split up the various bits in drm_irq, it's on my todo
;-)
quoted
quoted
+static void sun4i_drv_disable_vblank(struct drm_device *drm, int pipe)
+{
+	struct sun4i_drv *drv = drm->dev_private;
+	struct sun4i_tcon *tcon = drv->tcon;
+
+	DRM_DEBUG_DRIVER("Disabling VBLANK on pipe %d\n", pipe);
+
+	sun4i_tcon_enable_vblank(tcon, false);
+}
+
+static int sun4i_drv_load(struct drm_device *drm, unsigned long flags)
load/unload callbacks are depracated since fundamentally racy, and we
can't fix that due to the pile of legacy dri1 drivers. Please use
drm_dev_alloc/register/unregister/unref functions instead, with the
load/unload code placed in between to avoid races with userspace seeing
the device/driver (e.g. in sysfs) while it's in a partially defunct state.

Relevant kerneldoc has the details, at least in linux-next.
Ok.
quoted
quoted
+static void sun4i_backend_layer_atomic_update(struct drm_plane *plane,
+					      struct drm_plane_state *old_state)
+{
+	struct sun4i_layer *layer = plane_to_sun4i_layer(plane);
+	struct sun4i_drv *drv = layer->drv;
+	struct sun4i_backend *backend = drv->backend;
+
+	sun4i_backend_update_layer_coord(backend, layer->id, plane);
+	sun4i_backend_update_layer_formats(backend, layer->id, plane);
+	sun4i_backend_update_layer_buffer(backend, layer->id, plane);
+	sun4i_backend_layer_enable(backend, layer->id, true);
+	sun4i_backend_commit(backend);
Not idea how exactly your hw works, but the call to sun4i_backend_commit
probably should be in the crtc->atomic_flush function, to make sure that
plane updates across multiple planes are indeed atomic.
The hardware will not take the register writes into account until a
bit is set (in the _commit function), so I guess putting it in
atomic_flush makes sense.
Yeah that's what I suspected, so sun4i_backend_commit definitely needs to
be moved to atomic_flush.

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help