[Intel-gfx] [RFC] drm/i915: Clean up display pipe register accesses

Jani Nikula jani.nikula at linux.intel.com
Thu Oct 31 08:32:49 CET 2013


On Wed, 30 Oct 2013, Antti Koskipaa <antti.koskipaa at linux.intel.com> wrote:
> Upcoming hardware will not have the various display pipe register
> ranges evenly spaced in memory. Change register address calculations
> into array lookups.
>
> Tested on SandyBridge.
>
> I left the UMS cruft untouched.
>
> Signed-off-by: Antti Koskipaa <antti.koskipaa at linux.intel.com>
> ---
>  drivers/gpu/drm/i915/dvo_ns2501.c |  6 ++--
>  drivers/gpu/drm/i915/i915_dma.c   | 16 +++++++++++
>  drivers/gpu/drm/i915/i915_drv.h   | 10 ++++++-
>  drivers/gpu/drm/i915/i915_reg.h   | 59 +++++++++++++++++++++++++++------------
>  4 files changed, 69 insertions(+), 22 deletions(-)

[snip]

> +/* Pipe timing regs */
> +#define HTOTAL(trans) (dev_priv->trans_offsets[trans])
> +#define HBLANK(trans) (dev_priv->trans_offsets[trans] + 0x04)
> +#define HSYNC(trans) (dev_priv->trans_offsets[trans] + 0x08)
> +#define VTOTAL(trans) (dev_priv->trans_offsets[trans] + 0x0c)
> +#define VBLANK(trans) (dev_priv->trans_offsets[trans] + 0x10)
> +#define VSYNC(trans) (dev_priv->trans_offsets[trans] + 0x14)
> +#define BCLRPAT(trans) (dev_priv->trans_offsets[trans] + 0x20)
> +#define VSYNCSHIFT(trans) (dev_priv->trans_offsets[trans] + 0x28)
> +#define PIPESRC(pipe) (dev_priv->trans_offsets[pipe] + 0x1c)

This is the part that gives me the creeps about this approach, in many
different ways. First, I don't know if we have guarantees that the
offsets between registers remain the same; maybe they do, maybe they
don't. Second, I find myself searching for the register addresses in
this file quite often. With this the "reverse lookup" becomes
hard. Third, an unsubstanciated claim, it just *feels* like too many
levels of indirection to be comfortable.

Here's an alternative approach. How about we change the defines for
_PIPE(), _TRANSCODER(), etc. to require the the register addresses for
*every* pipe, transcoder, etc. as parameters. It may be a bit tedious to
change all uses of the macros, but at least it's straightforward, with,
I think, fewer chances for bugs.

Here's an idea how to do it neatly:

#define _OFFSET(index, ...) (((int[]){ __VA_ARGS__ })[index])

#define _PIPE(pipe, a, b, c)			_OFFSET(pipe, a, b, c)
#define _TRANSCODER(trans, a, b, c, edp)	_OFFSET(trans, a, b, c, edp)

Note that you'd still need to change TRANSCODER_EDP enum value to be in
sequence (but then it's 0xF just to work for the current macros).

I did not look at the assembly produced by that vs. the table lookup.


BR,
Jani.


PS. And don't just go ahead and do what I suggested; more bikeshedding
might be required! ;)


> +
> +
>  /* Pipe A timing regs */
>  #define _HTOTAL_A	(dev_priv->info->display_mmio_offset + 0x60000)
>  #define _HBLANK_A	(dev_priv->info->display_mmio_offset + 0x60004)
> @@ -1941,15 +1969,6 @@
>  #define _BCLRPAT_B	(dev_priv->info->display_mmio_offset + 0x61020)
>  #define _VSYNCSHIFT_B	(dev_priv->info->display_mmio_offset + 0x61028)
>  
> -#define HTOTAL(trans) _TRANSCODER(trans, _HTOTAL_A, _HTOTAL_B)
> -#define HBLANK(trans) _TRANSCODER(trans, _HBLANK_A, _HBLANK_B)
> -#define HSYNC(trans) _TRANSCODER(trans, _HSYNC_A, _HSYNC_B)
> -#define VTOTAL(trans) _TRANSCODER(trans, _VTOTAL_A, _VTOTAL_B)
> -#define VBLANK(trans) _TRANSCODER(trans, _VBLANK_A, _VBLANK_B)
> -#define VSYNC(trans) _TRANSCODER(trans, _VSYNC_A, _VSYNC_B)
> -#define BCLRPAT(pipe) _PIPE(pipe, _BCLRPAT_A, _BCLRPAT_B)
> -#define VSYNCSHIFT(trans) _TRANSCODER(trans, _VSYNCSHIFT_A, _VSYNCSHIFT_B)
> -
>  /* HSW eDP PSR registers */
>  #define EDP_PSR_BASE(dev)			0x64800
>  #define EDP_PSR_CTL(dev)			(EDP_PSR_BASE(dev) + 0)
> @@ -3211,12 +3230,16 @@
>  #define   PIPE_VBLANK_INTERRUPT_STATUS		(1UL<<1)
>  #define   PIPE_OVERLAY_UPDATED_STATUS		(1UL<<0)
>  
> -#define PIPESRC(pipe) _PIPE(pipe, _PIPEASRC, _PIPEBSRC)
> -#define PIPECONF(tran) _TRANSCODER(tran, _PIPEACONF, _PIPEBCONF)
> -#define PIPEDSL(pipe)  _PIPE(pipe, _PIPEADSL, _PIPEBDSL)
> -#define PIPEFRAME(pipe) _PIPE(pipe, _PIPEAFRAMEHIGH, _PIPEBFRAMEHIGH)
> -#define PIPEFRAMEPIXEL(pipe)  _PIPE(pipe, _PIPEAFRAMEPIXEL, _PIPEBFRAMEPIXEL)
> -#define PIPESTAT(pipe) _PIPE(pipe, _PIPEASTAT, _PIPEBSTAT)
> +#define PIPE_A_OFFSET	0x70000
> +#define PIPE_B_OFFSET	0x71000
> +#define PIPE_EDP_OFFSET	0x7f000
> +
> +#define PIPEDSL(pipe) (dev_priv->pipe_offsets[pipe])
> +#define PIPECONF(tran) ((int)(tran) == TRANSCODER_EDP ? PIPE_EDP_OFFSET : \
> +			dev_priv->pipe_offsets[tran] + 0x08)
> +#define PIPESTAT(pipe) (dev_priv->pipe_offsets[pipe] + 0x24)
> +#define PIPEFRAME(pipe) (dev_priv->pipe_offsets[pipe] + 0x40)
> +#define PIPEFRAMEPIXEL(pipe) (dev_priv->pipe_offsets[pipe] + 0x44)
>  
>  #define VLV_DPFLIPSTAT				(VLV_DISPLAY_BASE + 0x70028)
>  #define   PIPEB_LINE_COMPARE_INT_EN		(1<<29)
> -- 
> 1.8.1.5
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Jani Nikula, Intel Open Source Technology Center



More information about the Intel-gfx mailing list