[PATCH 1/3] drm/i915: Add _PICK_EVEN_RANGES()
Lucas De Marchi
lucas.demarchi at intel.com
Wed Oct 12 05:13:59 UTC 2022
On Tue, Oct 11, 2022 at 09:51:08PM -0700, Lucas De Marchi wrote:
>It's a constant pattern in the driver to need to use 2 ranges of MMIOs
>based on port, phy, pll, etc. When that happens, instead of using
>_PICK_EVEN(), _PICK() needs to be used. Using _PICK() is discouraged
>due to some reasons like:
>
> 1) It increases the code size since the array is declared in each
> call site
> 2) Developers need to be careful not to incur an out-of-bounds array
> access
> 3) Developers need to be careful that the indexes match the
> table. For that it may be that the table needs to contain
> holes, making (1) even worse.
>
>Signed-off-by: Lucas De Marchi <lucas.demarchi at intel.com>
>(cherry picked from commit 55a65ca6e5d8f7f46fe4cf29c76a9f1b4ddef5ce)
>---
> drivers/gpu/drm/i915/i915_reg.h | 18 ++++++++++++++++--
> 1 file changed, 16 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>index 3edfbe92c6dd..d157dd693e41 100644
>--- a/drivers/gpu/drm/i915/i915_reg.h
>+++ b/drivers/gpu/drm/i915/i915_reg.h
>@@ -126,10 +126,24 @@
> #define _PICK_EVEN(__index, __a, __b) ((__a) + (__index) * ((__b) - (__a)))
>
> /*
>- * Given the arbitrary numbers in varargs, pick the 0-based __index'th number.
>+ * Like _PICK_EVEN(), but supports 2 ranges of evenly spaced addres offsets. The
>+ * @__use_first_range argument selects if the first or second range should be
>+ * used. It's usually in the form like ``(pll) < n``, in which ``n`` is the
>+ * number of registers in the first range. Example::
> *
>- * Always prefer _PICK_EVEN() over this if the numbers are evenly spaced.
>+ * #define _FOO_A 0xf000
>+ * #define _FOO_B 0xf004
>+ * #define _FOO_C 0xf008
>+ * #define _SUPER_FOO_A 0xa000
>+ * #define _SUPER_FOO_B 0xaf00
>+ * #define FOO(x) _MMIO(_PICK_EVEN_RANGES(x, (x) < 3, \
>+ * _FOO_A, _FOO_B, \
>+ * _SUPER_FOO_A, _SUPER_FOO_B))
> */
>+#define _PICK_EVEN_RANGES(__index, __use_first_range, __a, __b, __c, __d) \
>+ ((__use_first_range) ? _PICK_EVEN(__index, __a, __b) : \
>+ _PICK_EVEN(__index, __c, __d))
humn.. I tried to simplify this with a "__use_first_range" but now this
is broken as the index doesn't start on zero for the second range. This
should actually be something like:
#define _PICK_EVEN_RANGES(__index, __c_idx, __a, __b, __c, __d) \
((__index < __c_idx) ? _PICK_EVEN(__index, __a, __b) : \
_PICK_EVEN((__index) - __c_idx, __c, __d))
Lucas De Marchi
>+
> #define _PICK(__index, ...) (((const u32 []){ __VA_ARGS__ })[__index])
>
> /*
>
>--
>b4 0.10.1
More information about the dri-devel
mailing list