diff mbox series

[v2.1] drm/i915: Add _PICK_EVEN_2RANGES()

Message ID 20230123171556.3322164-1-lucas.demarchi@intel.com (mailing list archive)
State New, archived
Headers show
Series [v2.1] drm/i915: Add _PICK_EVEN_2RANGES() | expand

Commit Message

Lucas De Marchi Jan. 23, 2023, 5:15 p.m. UTC
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)

Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
---
 drivers/gpu/drm/i915/i915_reg_defs.h | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

Comments

Srivatsa, Anusha Jan. 23, 2023, 5:49 p.m. UTC | #1
> -----Original Message-----
> From: De Marchi, Lucas <lucas.demarchi@intel.com>
> Sent: Monday, January 23, 2023 9:16 AM
> To: intel-gfx@lists.freedesktop.org; dri-devel@lists.freedesktop.org
> Cc: Srivatsa, Anusha <anusha.srivatsa@intel.com>; Jani Nikula
> <jani.nikula@linux.intel.com>; De Marchi, Lucas <lucas.demarchi@intel.com>
> Subject: [PATCH v2.1] 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)
> 
> Signed-off-by: Lucas De Marchi <lucas.demarchi@intel.com>
Reviewed-by: Anusha Srivatsa <anusha.srivatsa@intel.com>

> ---
>  drivers/gpu/drm/i915/i915_reg_defs.h | 28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h
> b/drivers/gpu/drm/i915/i915_reg_defs.h
> index be43580a6979..bab6a9ec2ddd 100644
> --- a/drivers/gpu/drm/i915/i915_reg_defs.h
> +++ b/drivers/gpu/drm/i915/i915_reg_defs.h
> @@ -119,6 +119,34 @@
>   */
>  #define _PICK_EVEN(__index, __a, __b) ((__a) + (__index) * ((__b) - (__a)))
> 
> +/*
> + * Like _PICK_EVEN(), but supports 2 ranges of evenly spaced address offsets.
> + * The first range is used for indexes below @__c_index, and the second
> + * range is used for anything above it. 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_RANGES(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.
>   *
> --
> 2.39.0
diff mbox series

Patch

diff --git a/drivers/gpu/drm/i915/i915_reg_defs.h b/drivers/gpu/drm/i915/i915_reg_defs.h
index be43580a6979..bab6a9ec2ddd 100644
--- a/drivers/gpu/drm/i915/i915_reg_defs.h
+++ b/drivers/gpu/drm/i915/i915_reg_defs.h
@@ -119,6 +119,34 @@ 
  */
 #define _PICK_EVEN(__index, __a, __b) ((__a) + (__index) * ((__b) - (__a)))
 
+/*
+ * Like _PICK_EVEN(), but supports 2 ranges of evenly spaced address offsets.
+ * The first range is used for indexes below @__c_index, and the second
+ * range is used for anything above it. 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_RANGES(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.
  *