Commit 35751323 authored by Lucas De Marchi's avatar Lucas De Marchi

drm/i915: Add _PICK_EVEN_2RANGES()

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.

Add a variant of _PICK_EVEN() that works with 2 ranges and selects which
one to use depending on the index value.

v2: Fix the address expansion in the example (Anusha)
v3: Also rename macro to _PICK_EVEN_2RANGES() in the documentation
    and reword it to clarify what ranges are chosen based on the index
    (Jani)
Signed-off-by: default avatarLucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: default avatarAnusha Srivatsa <anusha.srivatsa@intel.com>
Acked-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20230125182403.7526-1-lucas.demarchi@intel.com
parent d3eb347d
......@@ -119,6 +119,35 @@
*/
#define _PICK_EVEN(__index, __a, __b) ((__a) + (__index) * ((__b) - (__a)))
/*
* Like _PICK_EVEN(), but supports 2 ranges of evenly spaced address offsets.
* @__c_index corresponds to the index in which the second range starts to be
* used. Using math interval notation, the first range is used for indexes [ 0,
* @__c_index), while the second range is used for [ @__c_index, ... ). Example:
*
* #define _FOO_A 0xf000
* #define _FOO_B 0xf004
* #define _FOO_C 0xf008
* #define _SUPER_FOO_A 0xa000
* #define _SUPER_FOO_B 0xa100
* #define FOO(x) _MMIO(_PICK_EVEN_2RANGES(x, 3, \
* _FOO_A, _FOO_B, \
* _SUPER_FOO_A, _SUPER_FOO_B))
*
* This expands to:
* 0: 0xf000,
* 1: 0xf004,
* 2: 0xf008,
* 3: 0xa000,
* 4: 0xa100,
* 5: 0xa200,
* ...
*/
#define _PICK_EVEN_2RANGES(__index, __c_index, __a, __b, __c, __d) \
(BUILD_BUG_ON_ZERO(!__is_constexpr(__c_index)) + \
((__index) < (__c_index) ? _PICK_EVEN(__index, __a, __b) : \
_PICK_EVEN((__index) - (__c_index), __c, __d)))
/*
* Given the arbitrary numbers in varargs, pick the 0-based __index'th number.
*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment