* [PATCH 1/9] drm/amd/display: add GPIO HW translation helpers
2026-05-12 18:59 [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables Guilherme Ivo Bozi
@ 2026-05-12 18:59 ` Guilherme Ivo Bozi
2026-05-16 3:03 ` Claude review: " Claude Code Review Bot
2026-05-12 18:59 ` [PATCH 2/9] drm/amd/display: convert dcn10 GPIO translation to lookup tables Guilherme Ivo Bozi
` (8 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Guilherme Ivo Bozi @ 2026-05-12 18:59 UTC (permalink / raw)
To: airlied, alexander.deucher, christian.koenig, harry.wentland,
simona, siqueira, sunpeng.li
Cc: Guilherme Ivo Bozi, amd-gfx, dri-devel
Add generic helpers and lookup table types for GPIO hardware
translation.
The new helpers provide reusable conversions between GPIO IDs,
register offsets and DDC lines, allowing ASIC-specific drivers
to replace large switch statements with static lookup tables.
No functional changes intended.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
.../drm/amd/display/dc/gpio/hw_translate.c | 86 +++++++++++++++++++
.../drm/amd/display/dc/gpio/hw_translate.h | 21 +++++
.../gpu/drm/amd/display/include/gpio_types.h | 48 +++++++++++
3 files changed, 155 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
index e6e36a912b13..18f14f9f244c 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.c
@@ -129,3 +129,89 @@ bool dal_hw_translate_init(
return false;
}
}
+
+bool dal_hw_translate_gpio_offset_to_id(
+ const struct gpio_id_offset_entry *table,
+ uint32_t table_size,
+ uint32_t offset,
+ uint32_t mask,
+ enum gpio_id *id,
+ uint32_t *en)
+{
+ uint32_t i;
+
+ for (i = 0; i < table_size; i++) {
+ const struct gpio_id_offset_entry *entry = &table[i];
+
+ if (entry->offset != offset)
+ continue;
+
+ if (entry->check_mask && entry->mask != mask)
+ continue;
+
+ *id = entry->id;
+ *en = entry->en;
+
+ return true;
+ }
+
+ return false;
+}
+
+/* we don't care about the GPIO_ID for DDC
+ * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
+ * directly in the create method
+ */
+bool dal_hw_translate_gpio_ddc_offset_to_id(
+ const struct gpio_ddc_offset_entry *table,
+ uint32_t table_size,
+ uint32_t offset,
+ uint32_t *en)
+{
+ uint32_t i;
+
+ for (i = 0; i < table_size; i++) {
+ const struct gpio_ddc_offset_entry *entry = &table[i];
+
+ if (entry->offset != offset)
+ continue;
+
+ *en = entry->en;
+
+ return true;
+ }
+
+ return false;
+}
+
+bool dal_hw_translate_id_to_offset(
+ const struct gpio_pin_entry *table,
+ uint32_t table_size,
+ enum gpio_id id,
+ uint32_t en,
+ struct gpio_pin_info *info)
+{
+ uint32_t i;
+
+ for (i = 0; i < table_size; i++) {
+ const struct gpio_pin_entry *entry = &table[i];
+
+ if (entry->id != id || entry->en != en)
+ continue;
+
+ info->offset = entry->offset;
+ info->mask = entry->mask;
+
+ info->offset_y = info->offset + 2;
+ info->offset_en = info->offset + 1;
+ info->offset_mask = info->offset - 1;
+
+ info->mask_y = info->mask;
+ info->mask_en = info->mask;
+ info->mask_mask = info->mask;
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.h b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.h
index 3a7d89ca1605..339e381f8fde 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.h
+++ b/drivers/gpu/drm/amd/display/dc/gpio/hw_translate.h
@@ -47,4 +47,25 @@ bool dal_hw_translate_init(
enum dce_version dce_version,
enum dce_environment dce_environment);
+bool dal_hw_translate_gpio_offset_to_id(
+ const struct gpio_id_offset_entry *table,
+ uint32_t table_size,
+ uint32_t offset,
+ uint32_t mask,
+ enum gpio_id *id,
+ uint32_t *en);
+
+bool dal_hw_translate_gpio_ddc_offset_to_id(
+ const struct gpio_ddc_offset_entry *table,
+ uint32_t table_size,
+ uint32_t offset,
+ uint32_t *en);
+
+bool dal_hw_translate_id_to_offset(
+ const struct gpio_pin_entry *table,
+ uint32_t table_size,
+ enum gpio_id id,
+ uint32_t en,
+ struct gpio_pin_info *info);
+
#endif
diff --git a/drivers/gpu/drm/amd/display/include/gpio_types.h b/drivers/gpu/drm/amd/display/include/gpio_types.h
index 8dd46ed799e5..afd3fc73a911 100644
--- a/drivers/gpu/drm/amd/display/include/gpio_types.h
+++ b/drivers/gpu/drm/amd/display/include/gpio_types.h
@@ -277,6 +277,49 @@ enum gpio_config_type {
GPIO_CONFIG_TYPE_I2C_AUX_DUAL_MODE
};
+struct gpio_id_offset_entry {
+ uint32_t offset;
+ uint32_t mask;
+
+ bool check_mask;
+
+ enum gpio_id id;
+ uint32_t en;
+};
+
+#define GPIO_ENTRY(_offset, _id, _en) \
+ { \
+ .offset = REG(_offset), \
+ .check_mask = false, \
+ .id = (_id), \
+ .en = (_en), \
+ }
+
+#define GPIO_MASK_ENTRY(_offset, _mask, _id, _en) \
+ { \
+ .offset = REG(_offset), \
+ .mask = (_mask), \
+ .check_mask = true, \
+ .id = (_id), \
+ .en = (_en), \
+ }
+
+struct gpio_pin_entry {
+ enum gpio_id id;
+ uint32_t en;
+
+ uint32_t offset;
+ uint32_t mask;
+};
+
+#define GPIO_PIN_ENTRY(_id, _en, _offset, _mask) \
+ { \
+ .id = (_id), \
+ .en = (_en), \
+ .offset = REG(_offset), \
+ .mask = (_mask), \
+ }
+
/* DDC configuration */
enum gpio_ddc_config_type {
@@ -293,6 +336,11 @@ struct gpio_ddc_config {
bool clock_en_bit_present;
};
+struct gpio_ddc_offset_entry {
+ uint32_t offset;
+ uint32_t en;
+};
+
/* HPD configuration */
struct gpio_hpd_config {
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread* Claude review: drm/amd/display: add GPIO HW translation helpers
2026-05-12 18:59 ` [PATCH 1/9] drm/amd/display: add GPIO HW translation helpers Guilherme Ivo Bozi
@ 2026-05-16 3:03 ` Claude Code Review Bot
0 siblings, 0 replies; 20+ messages in thread
From: Claude Code Review Bot @ 2026-05-16 3:03 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
Good foundational patch. The three helpers and table entry types are clean and generic.
One thing worth noting: `dal_hw_translate_gpio_ddc_offset_to_id()` sets `*en` but does **not** set `*id`. This matches the original switch-statement behavior where DDC cases never set `*id` (with the comment "we don't care about the GPIO_ID for DDC"), but it means callers must not read `*id` after a DDC match. This is pre-existing behavior, not a regression.
The hardcoded offset arithmetic in `dal_hw_translate_id_to_offset()` is correct:
```c
info->offset_y = info->offset + 2;
info->offset_en = info->offset + 1;
info->offset_mask = info->offset - 1;
```
This was duplicated identically in every ASIC's `id_to_offset` function, so centralizing it here is the right call.
No issues.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 2/9] drm/amd/display: convert dcn10 GPIO translation to lookup tables
2026-05-12 18:59 [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables Guilherme Ivo Bozi
2026-05-12 18:59 ` [PATCH 1/9] drm/amd/display: add GPIO HW translation helpers Guilherme Ivo Bozi
@ 2026-05-12 18:59 ` Guilherme Ivo Bozi
2026-05-16 3:03 ` Claude review: " Claude Code Review Bot
2026-05-12 18:59 ` [PATCH 3/9] drm/amd/display: convert dcn20 " Guilherme Ivo Bozi
` (7 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Guilherme Ivo Bozi @ 2026-05-12 18:59 UTC (permalink / raw)
To: airlied, alexander.deucher, christian.koenig, harry.wentland,
simona, siqueira, sunpeng.li
Cc: Guilherme Ivo Bozi, amd-gfx, dri-devel
Replace dcn10 GPIO translation switch statements with the
generic table-based translation helpers.
This simplifies the GPIO mapping logic and reduces duplicated
translation code.
No functional changes intended.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
.../dc/gpio/dcn10/hw_translate_dcn10.c | 484 +++++++-----------
1 file changed, 173 insertions(+), 311 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c
index fecc8688048d..000f603def58 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c
@@ -58,146 +58,180 @@
/* macros to expend register list macro defined in HW object header file
* end *********************/
+static const struct gpio_id_offset_entry gpio_offsets[] = {
+ /* GENERIC */
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_B),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_C),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_D),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_E),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_F),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_G),
+ /* HPD */
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_1),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_2),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_3),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_4),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_5),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_6),
+ /* SYNCA */
+ GPIO_MASK_ENTRY(DC_GPIO_SYNCA_A,
+ DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK,
+ GPIO_ID_SYNC, GPIO_SYNC_HSYNC_A),
+ GPIO_MASK_ENTRY(DC_GPIO_SYNCA_A,
+ DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK,
+ GPIO_ID_SYNC, GPIO_SYNC_VSYNC_A),
+ /* GSL */
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_CLOCK),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_VSYNC),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_B),
+};
+
+/* DDC */
+static const struct gpio_ddc_offset_entry ddc_offset_map[] = {
+ { REG(DC_GPIO_DDC1_A), GPIO_DDC_LINE_DDC1 },
+ { REG(DC_GPIO_DDC2_A), GPIO_DDC_LINE_DDC2 },
+ { REG(DC_GPIO_DDC3_A), GPIO_DDC_LINE_DDC3 },
+ { REG(DC_GPIO_DDC4_A), GPIO_DDC_LINE_DDC4 },
+ { REG(DC_GPIO_DDC5_A), GPIO_DDC_LINE_DDC5 },
+ { REG(DC_GPIO_DDC6_A), GPIO_DDC_LINE_DDC6 },
+ { REG(DC_GPIO_DDCVGA_A), GPIO_DDC_LINE_DDC_VGA },
+ { REG(DC_GPIO_I2CPAD_A), GPIO_DDC_LINE_I2C_PAD },
+};
+
+static const struct gpio_pin_entry gpio_pins[] = {
+ /* DDC */
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC6,
+ DC_GPIO_DDC6_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_I2C_PAD,
+ DC_GPIO_I2CPAD_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC6,
+ DC_GPIO_DDC6_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_I2C_PAD,
+ DC_GPIO_I2CPAD_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ /* GENERIC */
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_B,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_C,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_D,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_E,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_F,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_G,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK),
+ /* HPD */
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_1,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_2,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_3,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_4,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_5,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_6,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK),
+ /* SYNCA */
+ GPIO_PIN_ENTRY(GPIO_ID_SYNC, GPIO_SYNC_HSYNC_A,
+ DC_GPIO_SYNCA_A, DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_SYNC, GPIO_SYNC_VSYNC_A,
+ DC_GPIO_SYNCA_A, DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK),
+ /* GSL */
+ GPIO_PIN_ENTRY(GPIO_ID_GSL, GPIO_GSL_GENLOCK_CLOCK,
+ DC_GPIO_GENLK_A, DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GSL, GPIO_GSL_GENLOCK_VSYNC,
+ DC_GPIO_GENLK_A, DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_A,
+ DC_GPIO_GENLK_A, DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_B,
+ DC_GPIO_GENLK_A, DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK),
+};
+
static bool offset_to_id(
uint32_t offset,
uint32_t mask,
enum gpio_id *id,
uint32_t *en)
{
- switch (offset) {
- /* GENERIC */
- case REG(DC_GPIO_GENERIC_A):
- *id = GPIO_ID_GENERIC;
- switch (mask) {
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
- *en = GPIO_GENERIC_A;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
- *en = GPIO_GENERIC_B;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
- *en = GPIO_GENERIC_C;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
- *en = GPIO_GENERIC_D;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
- *en = GPIO_GENERIC_E;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
- *en = GPIO_GENERIC_F;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
- *en = GPIO_GENERIC_G;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* HPD */
- case REG(DC_GPIO_HPD_A):
- *id = GPIO_ID_HPD;
- switch (mask) {
- case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
- *en = GPIO_HPD_1;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
- *en = GPIO_HPD_2;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
- *en = GPIO_HPD_3;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
- *en = GPIO_HPD_4;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
- *en = GPIO_HPD_5;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
- *en = GPIO_HPD_6;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* SYNCA */
- case REG(DC_GPIO_SYNCA_A):
- *id = GPIO_ID_SYNC;
- switch (mask) {
- case DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK:
- *en = GPIO_SYNC_HSYNC_A;
- return true;
- case DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK:
- *en = GPIO_SYNC_VSYNC_A;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* REG(DC_GPIO_GENLK_MASK */
- case REG(DC_GPIO_GENLK_A):
- *id = GPIO_ID_GSL;
- switch (mask) {
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
- *en = GPIO_GSL_GENLOCK_CLOCK;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
- *en = GPIO_GSL_GENLOCK_VSYNC;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_A;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_B;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* DDC */
- /* we don't care about the GPIO_ID for DDC
- * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
- * directly in the create method */
- case REG(DC_GPIO_DDC1_A):
- *en = GPIO_DDC_LINE_DDC1;
- return true;
- case REG(DC_GPIO_DDC2_A):
- *en = GPIO_DDC_LINE_DDC2;
- return true;
- case REG(DC_GPIO_DDC3_A):
- *en = GPIO_DDC_LINE_DDC3;
- return true;
- case REG(DC_GPIO_DDC4_A):
- *en = GPIO_DDC_LINE_DDC4;
- return true;
- case REG(DC_GPIO_DDC5_A):
- *en = GPIO_DDC_LINE_DDC5;
- return true;
- case REG(DC_GPIO_DDC6_A):
- *en = GPIO_DDC_LINE_DDC6;
+ if (dal_hw_translate_gpio_ddc_offset_to_id(
+ ddc_offset_map,
+ ARRAY_SIZE(ddc_offset_map),
+ offset, en))
return true;
- case REG(DC_GPIO_DDCVGA_A):
- *en = GPIO_DDC_LINE_DDC_VGA;
- return true;
- /* GPIO_I2CPAD */
- case REG(DC_GPIO_I2CPAD_A):
- *en = GPIO_DDC_LINE_I2C_PAD;
+
+ if (dal_hw_translate_gpio_offset_to_id(
+ gpio_offsets,
+ ARRAY_SIZE(gpio_offsets),
+ offset, mask, id, en))
return true;
- /* Not implemented */
- case REG(DC_GPIO_PWRSEQ_A):
- case REG(DC_GPIO_PAD_STRENGTH_1):
- case REG(DC_GPIO_PAD_STRENGTH_2):
- case REG(DC_GPIO_DEBUG):
- return false;
- /* UNEXPECTED */
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
+
+ ASSERT_CRITICAL(false);
+ return false;
}
static bool id_to_offset(
@@ -205,186 +239,14 @@ static bool id_to_offset(
uint32_t en,
struct gpio_pin_info *info)
{
- bool result = true;
-
- switch (id) {
- case GPIO_ID_DDC_DATA:
- info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC6:
- info->offset = REG(DC_GPIO_DDC6_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- info->offset = REG(DC_GPIO_I2CPAD_A);
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_DDC_CLOCK:
- info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC6:
- info->offset = REG(DC_GPIO_DDC6_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- info->offset = REG(DC_GPIO_I2CPAD_A);
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GENERIC:
- info->offset = REG(DC_GPIO_GENERIC_A);
- switch (en) {
- case GPIO_GENERIC_A:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
- break;
- case GPIO_GENERIC_B:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
- break;
- case GPIO_GENERIC_C:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
- break;
- case GPIO_GENERIC_D:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
- break;
- case GPIO_GENERIC_E:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
- break;
- case GPIO_GENERIC_F:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
- break;
- case GPIO_GENERIC_G:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_HPD:
- info->offset = REG(DC_GPIO_HPD_A);
- switch (en) {
- case GPIO_HPD_1:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
- break;
- case GPIO_HPD_2:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
- break;
- case GPIO_HPD_3:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
- break;
- case GPIO_HPD_4:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
- break;
- case GPIO_HPD_5:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
- break;
- case GPIO_HPD_6:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_SYNC:
- switch (en) {
- case GPIO_SYNC_HSYNC_A:
- info->offset = REG(DC_GPIO_SYNCA_A);
- info->mask = DC_GPIO_SYNCA_A__DC_GPIO_HSYNCA_A_MASK;
- break;
- case GPIO_SYNC_VSYNC_A:
- info->offset = REG(DC_GPIO_SYNCA_A);
- info->mask = DC_GPIO_SYNCA_A__DC_GPIO_VSYNCA_A_MASK;
- break;
- case GPIO_SYNC_HSYNC_B:
- case GPIO_SYNC_VSYNC_B:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GSL:
- switch (en) {
- case GPIO_GSL_GENLOCK_CLOCK:
- info->offset = REG(DC_GPIO_GENLK_A);
- info->mask = DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK;
- break;
- case GPIO_GSL_GENLOCK_VSYNC:
- info->offset = REG(DC_GPIO_GENLK_A);
- info->mask =
- DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK;
- break;
- case GPIO_GSL_SWAPLOCK_A:
- info->offset = REG(DC_GPIO_GENLK_A);
- info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK;
- break;
- case GPIO_GSL_SWAPLOCK_B:
- info->offset = REG(DC_GPIO_GENLK_A);
- info->mask = DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_VIP_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
-
- if (result) {
- info->offset_y = info->offset + 2;
- info->offset_en = info->offset + 1;
- info->offset_mask = info->offset - 1;
-
- info->mask_y = info->mask;
- info->mask_en = info->mask;
- info->mask_mask = info->mask;
- }
+ if (dal_hw_translate_id_to_offset(
+ gpio_pins,
+ ARRAY_SIZE(gpio_pins),
+ id, en, info))
+ return true;
- return result;
+ ASSERT_CRITICAL(false);
+ return false;
}
/* function table */
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread* Claude review: drm/amd/display: convert dcn10 GPIO translation to lookup tables
2026-05-12 18:59 ` [PATCH 2/9] drm/amd/display: convert dcn10 GPIO translation to lookup tables Guilherme Ivo Bozi
@ 2026-05-16 3:03 ` Claude Code Review Bot
0 siblings, 0 replies; 20+ messages in thread
From: Claude Code Review Bot @ 2026-05-16 3:03 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
Clean conversion. DCN10 is the most feature-complete generation with SYNCA, I2C_PAD, and all DDC/GENERIC/HPD/GSL entries present in both tables. All entries match the original switch cases.
One minor nit: the `gpio_pins[]` DDC_CLOCK entry for I2C_PAD has slightly different indentation than the other entries:
```c
GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_I2C_PAD,
DC_GPIO_I2CPAD_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
```
The extra spaces before `DC_GPIO_I2CPAD_A` break the alignment pattern used by all other entries (single tab). Trivial cosmetic issue.
The original code had explicit `case REG(DC_GPIO_PWRSEQ_A)` / `case REG(DC_GPIO_PAD_STRENGTH_*)` / `case REG(DC_GPIO_DEBUG)` that returned `false` (without asserting). Those offsets will now fall through to `ASSERT_CRITICAL(false)` instead of a silent `return false`. This is arguably an improvement (unexpected offsets should assert) but is technically a minor behavior change if those offsets are ever hit.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 3/9] drm/amd/display: convert dcn20 GPIO translation to lookup tables
2026-05-12 18:59 [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables Guilherme Ivo Bozi
2026-05-12 18:59 ` [PATCH 1/9] drm/amd/display: add GPIO HW translation helpers Guilherme Ivo Bozi
2026-05-12 18:59 ` [PATCH 2/9] drm/amd/display: convert dcn10 GPIO translation to lookup tables Guilherme Ivo Bozi
@ 2026-05-12 18:59 ` Guilherme Ivo Bozi
2026-05-16 3:03 ` Claude review: " Claude Code Review Bot
2026-05-12 18:59 ` [PATCH 4/9] drm/amd/display: convert dcn21 " Guilherme Ivo Bozi
` (6 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Guilherme Ivo Bozi @ 2026-05-12 18:59 UTC (permalink / raw)
To: airlied, alexander.deucher, christian.koenig, harry.wentland,
simona, siqueira, sunpeng.li
Cc: Guilherme Ivo Bozi, amd-gfx, dri-devel
Replace dcn20 GPIO translation switch statements with the
generic table-based translation helpers.
This simplifies the GPIO mapping logic and reduces duplicated
translation code.
No functional changes intended.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
.../dc/gpio/dcn20/hw_translate_dcn20.c | 432 +++++++-----------
1 file changed, 153 insertions(+), 279 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c
index 3005ee7751a0..a21df8668266 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn20/hw_translate_dcn20.c
@@ -62,131 +62,161 @@
* end *********************/
+static const struct gpio_id_offset_entry gpio_offsets[] = {
+ /* GENERIC */
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_B),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_C),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_D),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_E),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_F),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_G),
+ /* HPD */
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_1),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_2),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_3),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_4),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_5),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_6),
+ /* GSL */
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_CLOCK),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_VSYNC),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_B),
+};
+
+
+/* DDC */
+static const struct gpio_ddc_offset_entry ddc_offset_map[] = {
+ { REG(DC_GPIO_DDC1_A), GPIO_DDC_LINE_DDC1 },
+ { REG(DC_GPIO_DDC2_A), GPIO_DDC_LINE_DDC2 },
+ { REG(DC_GPIO_DDC3_A), GPIO_DDC_LINE_DDC3 },
+ { REG(DC_GPIO_DDC4_A), GPIO_DDC_LINE_DDC4 },
+ { REG(DC_GPIO_DDC5_A), GPIO_DDC_LINE_DDC5 },
+ { REG(DC_GPIO_DDC6_A), GPIO_DDC_LINE_DDC6 },
+ { REG(DC_GPIO_DDCVGA_A), GPIO_DDC_LINE_DDC_VGA },
+};
+
+
+/*
+ * GSL is intentionally omitted here.
+ * id_to_offset() for GSL is not implemented on this ASIC.
+ */
+static const struct gpio_pin_entry gpio_pins[] = {
+ /* DDC */
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC6,
+ DC_GPIO_DDC6_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC6,
+ DC_GPIO_DDC6_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ /* GENERIC */
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_B,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_C,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_D,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_E,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_F,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_G,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK),
+ /* HPD */
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_1,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_2,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_3,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_4,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_5,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_6,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK),
+};
+
+
static bool offset_to_id(
uint32_t offset,
uint32_t mask,
enum gpio_id *id,
uint32_t *en)
{
- switch (offset) {
- /* GENERIC */
- case REG(DC_GPIO_GENERIC_A):
- *id = GPIO_ID_GENERIC;
- switch (mask) {
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
- *en = GPIO_GENERIC_A;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
- *en = GPIO_GENERIC_B;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
- *en = GPIO_GENERIC_C;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
- *en = GPIO_GENERIC_D;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
- *en = GPIO_GENERIC_E;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
- *en = GPIO_GENERIC_F;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
- *en = GPIO_GENERIC_G;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* HPD */
- case REG(DC_GPIO_HPD_A):
- *id = GPIO_ID_HPD;
- switch (mask) {
- case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
- *en = GPIO_HPD_1;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
- *en = GPIO_HPD_2;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
- *en = GPIO_HPD_3;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
- *en = GPIO_HPD_4;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
- *en = GPIO_HPD_5;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
- *en = GPIO_HPD_6;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* REG(DC_GPIO_GENLK_MASK */
- case REG(DC_GPIO_GENLK_A):
- *id = GPIO_ID_GSL;
- switch (mask) {
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
- *en = GPIO_GSL_GENLOCK_CLOCK;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
- *en = GPIO_GSL_GENLOCK_VSYNC;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_A;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_B;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* DDC */
- /* we don't care about the GPIO_ID for DDC
- * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
- * directly in the create method
- */
- case REG(DC_GPIO_DDC1_A):
- *en = GPIO_DDC_LINE_DDC1;
- return true;
- case REG(DC_GPIO_DDC2_A):
- *en = GPIO_DDC_LINE_DDC2;
- return true;
- case REG(DC_GPIO_DDC3_A):
- *en = GPIO_DDC_LINE_DDC3;
- return true;
- case REG(DC_GPIO_DDC4_A):
- *en = GPIO_DDC_LINE_DDC4;
- return true;
- case REG(DC_GPIO_DDC5_A):
- *en = GPIO_DDC_LINE_DDC5;
- return true;
- case REG(DC_GPIO_DDC6_A):
- *en = GPIO_DDC_LINE_DDC6;
+ if (dal_hw_translate_gpio_ddc_offset_to_id(
+ ddc_offset_map,
+ ARRAY_SIZE(ddc_offset_map),
+ offset, en))
return true;
- case REG(DC_GPIO_DDCVGA_A):
- *en = GPIO_DDC_LINE_DDC_VGA;
+
+ if (dal_hw_translate_gpio_offset_to_id(
+ gpio_offsets,
+ ARRAY_SIZE(gpio_offsets),
+ offset, mask, id, en))
return true;
-/*
- * case REG(DC_GPIO_I2CPAD_A): not exit
- * case REG(DC_GPIO_PWRSEQ_A):
- * case REG(DC_GPIO_PAD_STRENGTH_1):
- * case REG(DC_GPIO_PAD_STRENGTH_2):
- * case REG(DC_GPIO_DEBUG):
- */
- /* UNEXPECTED */
- default:
-/* case REG(DC_GPIO_SYNCA_A): not exist */
- ASSERT_CRITICAL(false);
- return false;
- }
+ ASSERT_CRITICAL(false);
+ return false;
}
static bool id_to_offset(
@@ -194,170 +224,14 @@ static bool id_to_offset(
uint32_t en,
struct gpio_pin_info *info)
{
- bool result = true;
-
- switch (id) {
- case GPIO_ID_DDC_DATA:
- info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC6:
- info->offset = REG(DC_GPIO_DDC6_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_DDC_CLOCK:
- info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC6:
- info->offset = REG(DC_GPIO_DDC6_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GENERIC:
- info->offset = REG(DC_GPIO_GENERIC_A);
- switch (en) {
- case GPIO_GENERIC_A:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
- break;
- case GPIO_GENERIC_B:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
- break;
- case GPIO_GENERIC_C:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
- break;
- case GPIO_GENERIC_D:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
- break;
- case GPIO_GENERIC_E:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
- break;
- case GPIO_GENERIC_F:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
- break;
- case GPIO_GENERIC_G:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_HPD:
- info->offset = REG(DC_GPIO_HPD_A);
- switch (en) {
- case GPIO_HPD_1:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
- break;
- case GPIO_HPD_2:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
- break;
- case GPIO_HPD_3:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
- break;
- case GPIO_HPD_4:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
- break;
- case GPIO_HPD_5:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
- break;
- case GPIO_HPD_6:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GSL:
- switch (en) {
- case GPIO_GSL_GENLOCK_CLOCK:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_GENLOCK_VSYNC:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_A:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_B:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
-
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_SYNC:
- case GPIO_ID_VIP_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
-
- if (result) {
- info->offset_y = info->offset + 2;
- info->offset_en = info->offset + 1;
- info->offset_mask = info->offset - 1;
-
- info->mask_y = info->mask;
- info->mask_en = info->mask;
- info->mask_mask = info->mask;
- }
+ if (dal_hw_translate_id_to_offset(
+ gpio_pins,
+ ARRAY_SIZE(gpio_pins),
+ id, en, info))
+ return true;
- return result;
+ ASSERT_CRITICAL(false);
+ return false;
}
/* function table */
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 4/9] drm/amd/display: convert dcn21 GPIO translation to lookup tables
2026-05-12 18:59 [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables Guilherme Ivo Bozi
` (2 preceding siblings ...)
2026-05-12 18:59 ` [PATCH 3/9] drm/amd/display: convert dcn20 " Guilherme Ivo Bozi
@ 2026-05-12 18:59 ` Guilherme Ivo Bozi
2026-05-16 3:03 ` Claude review: " Claude Code Review Bot
2026-05-12 18:59 ` [PATCH 5/9] drm/amd/display: convert dcn30 " Guilherme Ivo Bozi
` (5 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Guilherme Ivo Bozi @ 2026-05-12 18:59 UTC (permalink / raw)
To: airlied, alexander.deucher, christian.koenig, harry.wentland,
simona, siqueira, sunpeng.li
Cc: Guilherme Ivo Bozi, amd-gfx, dri-devel
Replace dcn21 GPIO translation switch statements with the
generic table-based translation helpers.
This simplifies the GPIO mapping logic and reduces duplicated
translation code.
No functional changes intended.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
.../dc/gpio/dcn21/hw_translate_dcn21.c | 417 ++++++------------
1 file changed, 147 insertions(+), 270 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.c
index e3b11b3c1daa..18bd4d4e32d0 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn21/hw_translate_dcn21.c
@@ -60,6 +60,135 @@
/* macros to expend register list macro defined in HW object header file
* end *********************/
+static const struct gpio_id_offset_entry gpio_offsets[] = {
+ /* GENERIC */
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_B),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_C),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_D),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_E),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_F),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_G),
+ /* HPD */
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_1),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_2),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_3),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_4),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_5),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_6),
+ /* GSL */
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_CLOCK),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_VSYNC),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_B),
+};
+
+
+/* DDC */
+static const struct gpio_ddc_offset_entry ddc_offset_map[] = {
+ { REG(DC_GPIO_DDC1_A), GPIO_DDC_LINE_DDC1 },
+ { REG(DC_GPIO_DDC2_A), GPIO_DDC_LINE_DDC2 },
+ { REG(DC_GPIO_DDC3_A), GPIO_DDC_LINE_DDC3 },
+ { REG(DC_GPIO_DDC4_A), GPIO_DDC_LINE_DDC4 },
+ { REG(DC_GPIO_DDC5_A), GPIO_DDC_LINE_DDC5 },
+ { REG(DC_GPIO_DDCVGA_A), GPIO_DDC_LINE_DDC_VGA },
+};
+
+
+/*
+ * GSL is intentionally omitted here.
+ * id_to_offset() for GSL is not implemented on this ASIC.
+ */
+static const struct gpio_pin_entry gpio_pins[] = {
+ /* DDC */
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK),
+ /* GENERIC */
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_B,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_C,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_D,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_E,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_F,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_G,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK),
+ /* HPD */
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_1,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_2,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_3,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_4,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_5,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_6,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK),
+};
+
static bool offset_to_id(
uint32_t offset,
@@ -67,122 +196,20 @@ static bool offset_to_id(
enum gpio_id *id,
uint32_t *en)
{
- switch (offset) {
- /* GENERIC */
- case REG(DC_GPIO_GENERIC_A):
- *id = GPIO_ID_GENERIC;
- switch (mask) {
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
- *en = GPIO_GENERIC_A;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
- *en = GPIO_GENERIC_B;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
- *en = GPIO_GENERIC_C;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
- *en = GPIO_GENERIC_D;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
- *en = GPIO_GENERIC_E;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
- *en = GPIO_GENERIC_F;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
- *en = GPIO_GENERIC_G;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* HPD */
- case REG(DC_GPIO_HPD_A):
- *id = GPIO_ID_HPD;
- switch (mask) {
- case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
- *en = GPIO_HPD_1;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
- *en = GPIO_HPD_2;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
- *en = GPIO_HPD_3;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
- *en = GPIO_HPD_4;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
- *en = GPIO_HPD_5;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
- *en = GPIO_HPD_6;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* REG(DC_GPIO_GENLK_MASK */
- case REG(DC_GPIO_GENLK_A):
- *id = GPIO_ID_GSL;
- switch (mask) {
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
- *en = GPIO_GSL_GENLOCK_CLOCK;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
- *en = GPIO_GSL_GENLOCK_VSYNC;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_A;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_B;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* DDC */
- /* we don't care about the GPIO_ID for DDC
- * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
- * directly in the create method
- */
- case REG(DC_GPIO_DDC1_A):
- *en = GPIO_DDC_LINE_DDC1;
- return true;
- case REG(DC_GPIO_DDC2_A):
- *en = GPIO_DDC_LINE_DDC2;
+ if (dal_hw_translate_gpio_ddc_offset_to_id(
+ ddc_offset_map,
+ ARRAY_SIZE(ddc_offset_map),
+ offset, en))
return true;
- case REG(DC_GPIO_DDC3_A):
- *en = GPIO_DDC_LINE_DDC3;
- return true;
- case REG(DC_GPIO_DDC4_A):
- *en = GPIO_DDC_LINE_DDC4;
- return true;
- case REG(DC_GPIO_DDC5_A):
- *en = GPIO_DDC_LINE_DDC5;
- return true;
- case REG(DC_GPIO_DDCVGA_A):
- *en = GPIO_DDC_LINE_DDC_VGA;
+
+ if (dal_hw_translate_gpio_offset_to_id(
+ gpio_offsets,
+ ARRAY_SIZE(gpio_offsets),
+ offset, mask, id, en))
return true;
-/*
- * case REG(DC_GPIO_I2CPAD_A): not exit
- * case REG(DC_GPIO_PWRSEQ_A):
- * case REG(DC_GPIO_PAD_STRENGTH_1):
- * case REG(DC_GPIO_PAD_STRENGTH_2):
- * case REG(DC_GPIO_DEBUG):
- */
- /* UNEXPECTED */
- default:
-/* case REG(DC_GPIO_SYNCA_A): not exist */
- ASSERT_CRITICAL(false);
- return false;
- }
+ ASSERT_CRITICAL(false);
+ return false;
}
static bool id_to_offset(
@@ -190,164 +217,14 @@ static bool id_to_offset(
uint32_t en,
struct gpio_pin_info *info)
{
- bool result = true;
-
- switch (id) {
- case GPIO_ID_DDC_DATA:
- info->mask = DC_GPIO_DDC5_A__DC_GPIO_DDC5DATA_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_DDC_CLOCK:
- info->mask = DC_GPIO_DDC5_A__DC_GPIO_DDC5CLK_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GENERIC:
- info->offset = REG(DC_GPIO_GENERIC_A);
- switch (en) {
- case GPIO_GENERIC_A:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
- break;
- case GPIO_GENERIC_B:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
- break;
- case GPIO_GENERIC_C:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
- break;
- case GPIO_GENERIC_D:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
- break;
- case GPIO_GENERIC_E:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
- break;
- case GPIO_GENERIC_F:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
- break;
- case GPIO_GENERIC_G:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_HPD:
- info->offset = REG(DC_GPIO_HPD_A);
- switch (en) {
- case GPIO_HPD_1:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
- break;
- case GPIO_HPD_2:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
- break;
- case GPIO_HPD_3:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
- break;
- case GPIO_HPD_4:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
- break;
- case GPIO_HPD_5:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
- break;
- case GPIO_HPD_6:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GSL:
- switch (en) {
- case GPIO_GSL_GENLOCK_CLOCK:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_GENLOCK_VSYNC:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_A:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_B:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
-
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_SYNC:
- case GPIO_ID_VIP_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
-
- if (result) {
- info->offset_y = info->offset + 2;
- info->offset_en = info->offset + 1;
- info->offset_mask = info->offset - 1;
-
- info->mask_y = info->mask;
- info->mask_en = info->mask;
- info->mask_mask = info->mask;
- }
+ if (dal_hw_translate_id_to_offset(
+ gpio_pins,
+ ARRAY_SIZE(gpio_pins),
+ id, en, info))
+ return true;
- return result;
+ ASSERT_CRITICAL(false);
+ return false;
}
/* function table */
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 5/9] drm/amd/display: convert dcn30 GPIO translation to lookup tables
2026-05-12 18:59 [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables Guilherme Ivo Bozi
` (3 preceding siblings ...)
2026-05-12 18:59 ` [PATCH 4/9] drm/amd/display: convert dcn21 " Guilherme Ivo Bozi
@ 2026-05-12 18:59 ` Guilherme Ivo Bozi
2026-05-16 3:03 ` Claude review: " Claude Code Review Bot
2026-05-12 18:59 ` [PATCH 6/9] drm/amd/display: convert dcn315 " Guilherme Ivo Bozi
` (4 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Guilherme Ivo Bozi @ 2026-05-12 18:59 UTC (permalink / raw)
To: airlied, alexander.deucher, christian.koenig, harry.wentland,
simona, siqueira, sunpeng.li
Cc: Guilherme Ivo Bozi, amd-gfx, dri-devel
Replace dcn30 GPIO translation switch statements with the
generic table-based translation helpers.
This simplifies the GPIO mapping logic and reduces duplicated
translation code.
No functional changes intended.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
.../dc/gpio/dcn30/hw_translate_dcn30.c | 432 +++++++-----------
1 file changed, 153 insertions(+), 279 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c
index 49d6250037a9..c4225231f725 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn30/hw_translate_dcn30.c
@@ -67,131 +67,161 @@
* end *********************/
+static const struct gpio_id_offset_entry gpio_offsets[] = {
+ /* GENERIC */
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_B),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_C),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_D),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_E),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_F),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_G),
+ /* HPD */
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_1),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_2),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_3),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_4),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_5),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_6),
+ /* GSL */
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_CLOCK),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_VSYNC),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_B),
+};
+
+
+/* DDC */
+static const struct gpio_ddc_offset_entry ddc_offset_map[] = {
+ { REG(DC_GPIO_DDC1_A), GPIO_DDC_LINE_DDC1 },
+ { REG(DC_GPIO_DDC2_A), GPIO_DDC_LINE_DDC2 },
+ { REG(DC_GPIO_DDC3_A), GPIO_DDC_LINE_DDC3 },
+ { REG(DC_GPIO_DDC4_A), GPIO_DDC_LINE_DDC4 },
+ { REG(DC_GPIO_DDC5_A), GPIO_DDC_LINE_DDC5 },
+ { REG(DC_GPIO_DDC6_A), GPIO_DDC_LINE_DDC6 },
+ { REG(DC_GPIO_DDCVGA_A), GPIO_DDC_LINE_DDC_VGA },
+};
+
+
+/*
+ * GSL is intentionally omitted here.
+ * id_to_offset() for GSL is not implemented on this ASIC.
+ */
+static const struct gpio_pin_entry gpio_pins[] = {
+ /* DDC */
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC6,
+ DC_GPIO_DDC6_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC6,
+ DC_GPIO_DDC6_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK),
+ /* GENERIC */
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_B,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_C,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_D,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_E,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_F,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_G,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK),
+ /* HPD */
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_1,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_2,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_3,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_4,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_5,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_6,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK),
+};
+
+
static bool offset_to_id(
uint32_t offset,
uint32_t mask,
enum gpio_id *id,
uint32_t *en)
{
- switch (offset) {
- /* GENERIC */
- case REG(DC_GPIO_GENERIC_A):
- *id = GPIO_ID_GENERIC;
- switch (mask) {
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
- *en = GPIO_GENERIC_A;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
- *en = GPIO_GENERIC_B;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
- *en = GPIO_GENERIC_C;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
- *en = GPIO_GENERIC_D;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
- *en = GPIO_GENERIC_E;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
- *en = GPIO_GENERIC_F;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
- *en = GPIO_GENERIC_G;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* HPD */
- case REG(DC_GPIO_HPD_A):
- *id = GPIO_ID_HPD;
- switch (mask) {
- case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
- *en = GPIO_HPD_1;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
- *en = GPIO_HPD_2;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
- *en = GPIO_HPD_3;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
- *en = GPIO_HPD_4;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
- *en = GPIO_HPD_5;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
- *en = GPIO_HPD_6;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* REG(DC_GPIO_GENLK_MASK */
- case REG(DC_GPIO_GENLK_A):
- *id = GPIO_ID_GSL;
- switch (mask) {
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
- *en = GPIO_GSL_GENLOCK_CLOCK;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
- *en = GPIO_GSL_GENLOCK_VSYNC;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_A;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_B;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* DDC */
- /* we don't care about the GPIO_ID for DDC
- * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
- * directly in the create method
- */
- case REG(DC_GPIO_DDC1_A):
- *en = GPIO_DDC_LINE_DDC1;
- return true;
- case REG(DC_GPIO_DDC2_A):
- *en = GPIO_DDC_LINE_DDC2;
- return true;
- case REG(DC_GPIO_DDC3_A):
- *en = GPIO_DDC_LINE_DDC3;
- return true;
- case REG(DC_GPIO_DDC4_A):
- *en = GPIO_DDC_LINE_DDC4;
- return true;
- case REG(DC_GPIO_DDC5_A):
- *en = GPIO_DDC_LINE_DDC5;
- return true;
- case REG(DC_GPIO_DDC6_A):
- *en = GPIO_DDC_LINE_DDC6;
+ if (dal_hw_translate_gpio_ddc_offset_to_id(
+ ddc_offset_map,
+ ARRAY_SIZE(ddc_offset_map),
+ offset, en))
return true;
- case REG(DC_GPIO_DDCVGA_A):
- *en = GPIO_DDC_LINE_DDC_VGA;
+
+ if (dal_hw_translate_gpio_offset_to_id(
+ gpio_offsets,
+ ARRAY_SIZE(gpio_offsets),
+ offset, mask, id, en))
return true;
-/*
- * case REG(DC_GPIO_I2CPAD_A): not exit
- * case REG(DC_GPIO_PWRSEQ_A):
- * case REG(DC_GPIO_PAD_STRENGTH_1):
- * case REG(DC_GPIO_PAD_STRENGTH_2):
- * case REG(DC_GPIO_DEBUG):
- */
- /* UNEXPECTED */
- default:
-/* case REG(DC_GPIO_SYNCA_A): not exist */
- ASSERT_CRITICAL(false);
- return false;
- }
+ ASSERT_CRITICAL(false);
+ return false;
}
static bool id_to_offset(
@@ -199,170 +229,14 @@ static bool id_to_offset(
uint32_t en,
struct gpio_pin_info *info)
{
- bool result = true;
-
- switch (id) {
- case GPIO_ID_DDC_DATA:
- info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC6:
- info->offset = REG(DC_GPIO_DDC6_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_DDC_CLOCK:
- info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6CLK_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC6:
- info->offset = REG(DC_GPIO_DDC6_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GENERIC:
- info->offset = REG(DC_GPIO_GENERIC_A);
- switch (en) {
- case GPIO_GENERIC_A:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
- break;
- case GPIO_GENERIC_B:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
- break;
- case GPIO_GENERIC_C:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
- break;
- case GPIO_GENERIC_D:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
- break;
- case GPIO_GENERIC_E:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
- break;
- case GPIO_GENERIC_F:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
- break;
- case GPIO_GENERIC_G:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_HPD:
- info->offset = REG(DC_GPIO_HPD_A);
- switch (en) {
- case GPIO_HPD_1:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
- break;
- case GPIO_HPD_2:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
- break;
- case GPIO_HPD_3:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
- break;
- case GPIO_HPD_4:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
- break;
- case GPIO_HPD_5:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
- break;
- case GPIO_HPD_6:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GSL:
- switch (en) {
- case GPIO_GSL_GENLOCK_CLOCK:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_GENLOCK_VSYNC:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_A:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_B:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
-
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_SYNC:
- case GPIO_ID_VIP_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
-
- if (result) {
- info->offset_y = info->offset + 2;
- info->offset_en = info->offset + 1;
- info->offset_mask = info->offset - 1;
-
- info->mask_y = info->mask;
- info->mask_en = info->mask;
- info->mask_mask = info->mask;
- }
+ if (dal_hw_translate_id_to_offset(
+ gpio_pins,
+ ARRAY_SIZE(gpio_pins),
+ id, en, info))
+ return true;
- return result;
+ ASSERT_CRITICAL(false);
+ return false;
}
/* function table */
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 6/9] drm/amd/display: convert dcn315 GPIO translation to lookup tables
2026-05-12 18:59 [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables Guilherme Ivo Bozi
` (4 preceding siblings ...)
2026-05-12 18:59 ` [PATCH 5/9] drm/amd/display: convert dcn30 " Guilherme Ivo Bozi
@ 2026-05-12 18:59 ` Guilherme Ivo Bozi
2026-05-16 3:03 ` Claude review: " Claude Code Review Bot
2026-05-12 18:59 ` [PATCH 7/9] drm/amd/display: convert dcn32 " Guilherme Ivo Bozi
` (3 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Guilherme Ivo Bozi @ 2026-05-12 18:59 UTC (permalink / raw)
To: airlied, alexander.deucher, christian.koenig, harry.wentland,
simona, siqueira, sunpeng.li
Cc: Guilherme Ivo Bozi, amd-gfx, dri-devel
Replace dcn315 GPIO translation switch statements with the
generic table-based translation helpers.
This simplifies the GPIO mapping logic and reduces duplicated
translation code.
No functional changes intended.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
.../dc/gpio/dcn315/hw_translate_dcn315.c | 418 +++++++-----------
1 file changed, 148 insertions(+), 270 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.c
index fbdaba57f718..aa507f7f4ef9 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn315/hw_translate_dcn315.c
@@ -62,128 +62,156 @@
* end *********************/
+static const struct gpio_id_offset_entry gpio_offsets[] = {
+ /* GENERIC */
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_B),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_C),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_D),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_E),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_F),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_G),
+ /* HPD */
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_1),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_2),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_3),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_4),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_5),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_6),
+ /* GSL */
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_CLOCK),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_VSYNC),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_B),
+};
+
+
+/* DDC */
+static const struct gpio_ddc_offset_entry ddc_offset_map[] = {
+ { REG(DC_GPIO_DDC1_A), GPIO_DDC_LINE_DDC1 },
+ { REG(DC_GPIO_DDC2_A), GPIO_DDC_LINE_DDC2 },
+ { REG(DC_GPIO_DDC3_A), GPIO_DDC_LINE_DDC3 },
+ { REG(DC_GPIO_DDC4_A), GPIO_DDC_LINE_DDC4 },
+ { REG(DC_GPIO_DDC5_A), GPIO_DDC_LINE_DDC5 },
+ { REG(DC_GPIO_DDCVGA_A), GPIO_DDC_LINE_DDC_VGA },
+};
+
+
+/*
+ * GSL is intentionally omitted here.
+ * id_to_offset() for GSL is not implemented on this ASIC.
+ */
+static const struct gpio_pin_entry gpio_pins[] = {
+ /* DDC */
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ /* GENERIC */
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_B,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_C,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_D,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_E,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_F,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_G,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK),
+ /* HPD */
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_1,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_2,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_3,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_4,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_5,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_6,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK),
+};
+
+
static bool offset_to_id(
uint32_t offset,
uint32_t mask,
enum gpio_id *id,
uint32_t *en)
{
- switch (offset) {
- /* GENERIC */
- case REG(DC_GPIO_GENERIC_A):
- *id = GPIO_ID_GENERIC;
- switch (mask) {
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
- *en = GPIO_GENERIC_A;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
- *en = GPIO_GENERIC_B;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
- *en = GPIO_GENERIC_C;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
- *en = GPIO_GENERIC_D;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
- *en = GPIO_GENERIC_E;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
- *en = GPIO_GENERIC_F;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK:
- *en = GPIO_GENERIC_G;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* HPD */
- case REG(DC_GPIO_HPD_A):
- *id = GPIO_ID_HPD;
- switch (mask) {
- case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
- *en = GPIO_HPD_1;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
- *en = GPIO_HPD_2;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
- *en = GPIO_HPD_3;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
- *en = GPIO_HPD_4;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
- *en = GPIO_HPD_5;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK:
- *en = GPIO_HPD_6;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* REG(DC_GPIO_GENLK_MASK */
- case REG(DC_GPIO_GENLK_A):
- *id = GPIO_ID_GSL;
- switch (mask) {
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
- *en = GPIO_GSL_GENLOCK_CLOCK;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
- *en = GPIO_GSL_GENLOCK_VSYNC;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_A;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_B;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* DDC */
- /* we don't care about the GPIO_ID for DDC
- * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
- * directly in the create method
- */
- case REG(DC_GPIO_DDC1_A):
- *en = GPIO_DDC_LINE_DDC1;
- return true;
- case REG(DC_GPIO_DDC2_A):
- *en = GPIO_DDC_LINE_DDC2;
+ if (dal_hw_translate_gpio_ddc_offset_to_id(
+ ddc_offset_map,
+ ARRAY_SIZE(ddc_offset_map),
+ offset, en))
return true;
- case REG(DC_GPIO_DDC3_A):
- *en = GPIO_DDC_LINE_DDC3;
- return true;
- case REG(DC_GPIO_DDC4_A):
- *en = GPIO_DDC_LINE_DDC4;
- return true;
- case REG(DC_GPIO_DDC5_A):
- *en = GPIO_DDC_LINE_DDC5;
- return true;
- case REG(DC_GPIO_DDCVGA_A):
- *en = GPIO_DDC_LINE_DDC_VGA;
+
+ if (dal_hw_translate_gpio_offset_to_id(
+ gpio_offsets,
+ ARRAY_SIZE(gpio_offsets),
+ offset, mask, id, en))
return true;
-/*
- * case REG(DC_GPIO_I2CPAD_A): not exit
- * case REG(DC_GPIO_PWRSEQ_A):
- * case REG(DC_GPIO_PAD_STRENGTH_1):
- * case REG(DC_GPIO_PAD_STRENGTH_2):
- * case REG(DC_GPIO_DEBUG):
- */
- /* UNEXPECTED */
- default:
-/* case REG(DC_GPIO_SYNCA_A): not exist */
- ASSERT_CRITICAL(false);
- return false;
- }
+ ASSERT_CRITICAL(false);
+ return false;
}
static bool id_to_offset(
@@ -191,164 +219,14 @@ static bool id_to_offset(
uint32_t en,
struct gpio_pin_info *info)
{
- bool result = true;
-
- switch (id) {
- case GPIO_ID_DDC_DATA:
- info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_DDC_CLOCK:
- info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GENERIC:
- info->offset = REG(DC_GPIO_GENERIC_A);
- switch (en) {
- case GPIO_GENERIC_A:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
- break;
- case GPIO_GENERIC_B:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
- break;
- case GPIO_GENERIC_C:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
- break;
- case GPIO_GENERIC_D:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
- break;
- case GPIO_GENERIC_E:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
- break;
- case GPIO_GENERIC_F:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
- break;
- case GPIO_GENERIC_G:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICG_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_HPD:
- info->offset = REG(DC_GPIO_HPD_A);
- switch (en) {
- case GPIO_HPD_1:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
- break;
- case GPIO_HPD_2:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
- break;
- case GPIO_HPD_3:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
- break;
- case GPIO_HPD_4:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
- break;
- case GPIO_HPD_5:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
- break;
- case GPIO_HPD_6:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD6_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GSL:
- switch (en) {
- case GPIO_GSL_GENLOCK_CLOCK:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_GENLOCK_VSYNC:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_A:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_B:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
-
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_SYNC:
- case GPIO_ID_VIP_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
-
- if (result) {
- info->offset_y = info->offset + 2;
- info->offset_en = info->offset + 1;
- info->offset_mask = info->offset - 1;
-
- info->mask_y = info->mask;
- info->mask_en = info->mask;
- info->mask_mask = info->mask;
- }
+ if (dal_hw_translate_id_to_offset(
+ gpio_pins,
+ ARRAY_SIZE(gpio_pins),
+ id, en, info))
+ return true;
- return result;
+ ASSERT_CRITICAL(false);
+ return false;
}
/* function table */
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 7/9] drm/amd/display: convert dcn32 GPIO translation to lookup tables
2026-05-12 18:59 [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables Guilherme Ivo Bozi
` (5 preceding siblings ...)
2026-05-12 18:59 ` [PATCH 6/9] drm/amd/display: convert dcn315 " Guilherme Ivo Bozi
@ 2026-05-12 18:59 ` Guilherme Ivo Bozi
2026-05-16 3:03 ` Claude review: " Claude Code Review Bot
2026-05-12 18:59 ` [PATCH 8/9] drm/amd/display: convert dcn401 " Guilherme Ivo Bozi
` (2 subsequent siblings)
9 siblings, 1 reply; 20+ messages in thread
From: Guilherme Ivo Bozi @ 2026-05-12 18:59 UTC (permalink / raw)
To: airlied, alexander.deucher, christian.koenig, harry.wentland,
simona, siqueira, sunpeng.li
Cc: Guilherme Ivo Bozi, amd-gfx, dri-devel
Replace dcn32 GPIO translation switch statements with the
generic table-based translation helpers.
This simplifies the GPIO mapping logic and reduces duplicated
translation code.
No functional changes intended.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
.../dc/gpio/dcn32/hw_translate_dcn32.c | 386 +++++++-----------
1 file changed, 138 insertions(+), 248 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_translate_dcn32.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_translate_dcn32.c
index 8493b9981f9e..71067a8da121 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_translate_dcn32.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn32/hw_translate_dcn32.c
@@ -60,111 +60,145 @@
* end *********************/
+static const struct gpio_id_offset_entry gpio_offsets[] = {
+ /* GENERIC */
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_B),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_C),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_D),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_E),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_F),
+ /* HPD */
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_1),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_2),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_3),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_4),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_5),
+ /* GSL */
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_CLOCK),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_VSYNC),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_B),
+};
+
+
+/* DDC */
+static const struct gpio_ddc_offset_entry ddc_offset_map[] = {
+ { REG(DC_GPIO_DDC1_A), GPIO_DDC_LINE_DDC1 },
+ { REG(DC_GPIO_DDC2_A), GPIO_DDC_LINE_DDC2 },
+ { REG(DC_GPIO_DDC3_A), GPIO_DDC_LINE_DDC3 },
+ { REG(DC_GPIO_DDC4_A), GPIO_DDC_LINE_DDC4 },
+ { REG(DC_GPIO_DDC5_A), GPIO_DDC_LINE_DDC5 },
+ { REG(DC_GPIO_DDCVGA_A), GPIO_DDC_LINE_DDC_VGA },
+};
+
+/*
+ * GSL is intentionally omitted here.
+ * id_to_offset() for GSL is not implemented on this ASIC.
+ */
+static const struct gpio_pin_entry gpio_pins[] = {
+ /* DDC */
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ /* GENERIC */
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_B,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_C,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_D,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_E,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_F,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK),
+ /* HPD */
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_1,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_2,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_3,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_4,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_5,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK),
+};
+
+
static bool offset_to_id(
uint32_t offset,
uint32_t mask,
enum gpio_id *id,
uint32_t *en)
{
- switch (offset) {
- /* GENERIC */
- case REG(DC_GPIO_GENERIC_A):
- *id = GPIO_ID_GENERIC;
- switch (mask) {
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
- *en = GPIO_GENERIC_A;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
- *en = GPIO_GENERIC_B;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
- *en = GPIO_GENERIC_C;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
- *en = GPIO_GENERIC_D;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
- *en = GPIO_GENERIC_E;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
- *en = GPIO_GENERIC_F;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* HPD */
- case REG(DC_GPIO_HPD_A):
- *id = GPIO_ID_HPD;
- switch (mask) {
- case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
- *en = GPIO_HPD_1;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
- *en = GPIO_HPD_2;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
- *en = GPIO_HPD_3;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
- *en = GPIO_HPD_4;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
- *en = GPIO_HPD_5;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* REG(DC_GPIO_GENLK_MASK */
- case REG(DC_GPIO_GENLK_A):
- *id = GPIO_ID_GSL;
- switch (mask) {
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
- *en = GPIO_GSL_GENLOCK_CLOCK;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
- *en = GPIO_GSL_GENLOCK_VSYNC;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_A;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_B;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* DDC */
- /* we don't care about the GPIO_ID for DDC
- * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
- * directly in the create method */
- case REG(DC_GPIO_DDC1_A):
- *en = GPIO_DDC_LINE_DDC1;
- return true;
- case REG(DC_GPIO_DDC2_A):
- *en = GPIO_DDC_LINE_DDC2;
- return true;
- case REG(DC_GPIO_DDC3_A):
- *en = GPIO_DDC_LINE_DDC3;
- return true;
- case REG(DC_GPIO_DDC4_A):
- *en = GPIO_DDC_LINE_DDC4;
- return true;
- case REG(DC_GPIO_DDC5_A):
- *en = GPIO_DDC_LINE_DDC5;
+ if (dal_hw_translate_gpio_ddc_offset_to_id(
+ ddc_offset_map,
+ ARRAY_SIZE(ddc_offset_map),
+ offset, en))
return true;
- case REG(DC_GPIO_DDCVGA_A):
- *en = GPIO_DDC_LINE_DDC_VGA;
+
+ if (dal_hw_translate_gpio_offset_to_id(
+ gpio_offsets,
+ ARRAY_SIZE(gpio_offsets),
+ offset, mask, id, en))
return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
+
+ ASSERT_CRITICAL(false);
+ return false;
}
static bool id_to_offset(
@@ -172,158 +206,14 @@ static bool id_to_offset(
uint32_t en,
struct gpio_pin_info *info)
{
- bool result = true;
-
- switch (id) {
- case GPIO_ID_DDC_DATA:
- info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_DDC_CLOCK:
- info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GENERIC:
- info->offset = REG(DC_GPIO_GENERIC_A);
- switch (en) {
- case GPIO_GENERIC_A:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
- break;
- case GPIO_GENERIC_B:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
- break;
- case GPIO_GENERIC_C:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
- break;
- case GPIO_GENERIC_D:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
- break;
- case GPIO_GENERIC_E:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
- break;
- case GPIO_GENERIC_F:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_HPD:
- info->offset = REG(DC_GPIO_HPD_A);
- switch (en) {
- case GPIO_HPD_1:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
- break;
- case GPIO_HPD_2:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
- break;
- case GPIO_HPD_3:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
- break;
- case GPIO_HPD_4:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
- break;
- case GPIO_HPD_5:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GSL:
- switch (en) {
- case GPIO_GSL_GENLOCK_CLOCK:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_GENLOCK_VSYNC:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_A:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_B:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
-
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_SYNC:
- case GPIO_ID_VIP_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
-
- if (result) {
- info->offset_y = info->offset + 2;
- info->offset_en = info->offset + 1;
- info->offset_mask = info->offset - 1;
-
- info->mask_y = info->mask;
- info->mask_en = info->mask;
- info->mask_mask = info->mask;
- }
+ if (dal_hw_translate_id_to_offset(
+ gpio_pins,
+ ARRAY_SIZE(gpio_pins),
+ id, en, info))
+ return true;
- return result;
+ ASSERT_CRITICAL(false);
+ return false;
}
/* function table */
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 8/9] drm/amd/display: convert dcn401 GPIO translation to lookup tables
2026-05-12 18:59 [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables Guilherme Ivo Bozi
` (6 preceding siblings ...)
2026-05-12 18:59 ` [PATCH 7/9] drm/amd/display: convert dcn32 " Guilherme Ivo Bozi
@ 2026-05-12 18:59 ` Guilherme Ivo Bozi
2026-05-16 3:03 ` Claude review: " Claude Code Review Bot
2026-05-12 18:59 ` [PATCH 9/9] drm/amd/display: convert dcn42 " Guilherme Ivo Bozi
2026-05-16 3:03 ` Claude review: drm/amd/display: convert GPIO translation logic " Claude Code Review Bot
9 siblings, 1 reply; 20+ messages in thread
From: Guilherme Ivo Bozi @ 2026-05-12 18:59 UTC (permalink / raw)
To: airlied, alexander.deucher, christian.koenig, harry.wentland,
simona, siqueira, sunpeng.li
Cc: Guilherme Ivo Bozi, amd-gfx, dri-devel
Replace dcn401 GPIO translation switch statements with the
generic table-based translation helpers.
This simplifies the GPIO mapping logic and reduces duplicated
translation code.
No functional changes intended.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
.../dc/gpio/dcn401/hw_translate_dcn401.c | 392 ++++++------------
1 file changed, 137 insertions(+), 255 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn401/hw_translate_dcn401.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn401/hw_translate_dcn401.c
index ea416f01f888..7aa97f09955c 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn401/hw_translate_dcn401.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn401/hw_translate_dcn401.c
@@ -35,119 +35,145 @@
* end *********************/
+static const struct gpio_id_offset_entry gpio_offsets[] = {
+ /* GENERIC */
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_B),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_C),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_D),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_E),
+ GPIO_MASK_ENTRY(DC_GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK,
+ GPIO_ID_GENERIC, GPIO_GENERIC_F),
+ /* HPD */
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_1),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_2),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_3),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_4),
+ GPIO_MASK_ENTRY(DC_GPIO_HPD_A,
+ DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK,
+ GPIO_ID_HPD, GPIO_HPD_5),
+ /* GSL */
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_CLOCK),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_GENLOCK_VSYNC),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_A),
+ GPIO_MASK_ENTRY(DC_GPIO_GENLK_A,
+ DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK,
+ GPIO_ID_GSL, GPIO_GSL_SWAPLOCK_B),
+};
+
+
+/* DDC */
+static const struct gpio_ddc_offset_entry ddc_offset_map[] = {
+ { REG(DC_GPIO_DDC1_A), GPIO_DDC_LINE_DDC1 },
+ { REG(DC_GPIO_DDC2_A), GPIO_DDC_LINE_DDC2 },
+ { REG(DC_GPIO_DDC3_A), GPIO_DDC_LINE_DDC3 },
+ { REG(DC_GPIO_DDC4_A), GPIO_DDC_LINE_DDC4 },
+ { REG(DC_GPIO_DDCVGA_A), GPIO_DDC_LINE_DDC_VGA },
+};
+
+
+/*
+ * GSL is intentionally omitted here.
+ * id_to_offset() for GSL is not implemented on this ASIC.
+ */
+static const struct gpio_pin_entry gpio_pins[] = {
+ /* DDC */
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ /* GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK), */
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ /* GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK), */
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ /* GENERIC */
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_A,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_B,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_C,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_D,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_E,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_GENERIC, GPIO_GENERIC_F,
+ DC_GPIO_GENERIC_A, DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK),
+ /* HPD */
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_1,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_2,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_3,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_4,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_HPD, GPIO_HPD_5,
+ DC_GPIO_HPD_A, DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK),
+};
+
+
static bool offset_to_id(
uint32_t offset,
uint32_t mask,
enum gpio_id *id,
uint32_t *en)
{
- switch (offset) {
- /* GENERIC */
- case REG(DC_GPIO_GENERIC_A):
- *id = GPIO_ID_GENERIC;
- switch (mask) {
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK:
- *en = GPIO_GENERIC_A;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK:
- *en = GPIO_GENERIC_B;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK:
- *en = GPIO_GENERIC_C;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK:
- *en = GPIO_GENERIC_D;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK:
- *en = GPIO_GENERIC_E;
- return true;
- case DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK:
- *en = GPIO_GENERIC_F;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* HPD */
- case REG(DC_GPIO_HPD_A):
- *id = GPIO_ID_HPD;
- switch (mask) {
- case DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK:
- *en = GPIO_HPD_1;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK:
- *en = GPIO_HPD_2;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK:
- *en = GPIO_HPD_3;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK:
- *en = GPIO_HPD_4;
- return true;
- case DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK:
- *en = GPIO_HPD_5;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* REG(DC_GPIO_GENLK_MASK */
- case REG(DC_GPIO_GENLK_A):
- *id = GPIO_ID_GSL;
- switch (mask) {
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_CLK_A_MASK:
- *en = GPIO_GSL_GENLOCK_CLOCK;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_GENLK_VSYNC_A_MASK:
- *en = GPIO_GSL_GENLOCK_VSYNC;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_A_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_A;
- return true;
- case DC_GPIO_GENLK_A__DC_GPIO_SWAPLOCK_B_A_MASK:
- *en = GPIO_GSL_SWAPLOCK_B;
- return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
- break;
- /* DDC */
- /* we don't care about the GPIO_ID for DDC
- * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
- * directly in the create method
- */
- case REG(DC_GPIO_DDC1_A):
- *en = GPIO_DDC_LINE_DDC1;
+ if (dal_hw_translate_gpio_ddc_offset_to_id(
+ ddc_offset_map,
+ ARRAY_SIZE(ddc_offset_map),
+ offset, en))
return true;
- case REG(DC_GPIO_DDC2_A):
- *en = GPIO_DDC_LINE_DDC2;
- return true;
- case REG(DC_GPIO_DDC3_A):
- *en = GPIO_DDC_LINE_DDC3;
- return true;
- case REG(DC_GPIO_DDC4_A):
- *en = GPIO_DDC_LINE_DDC4;
- return true;
- case REG(DC_GPIO_DDCVGA_A):
- *en = GPIO_DDC_LINE_DDC_VGA;
+
+ if (dal_hw_translate_gpio_offset_to_id(
+ gpio_offsets,
+ ARRAY_SIZE(gpio_offsets),
+ offset, mask, id, en))
return true;
-/*
- * case REG(DC_GPIO_I2CPAD_A): not exit
- * case REG(DC_GPIO_PWRSEQ_A):
- * case REG(DC_GPIO_PAD_STRENGTH_1):
- * case REG(DC_GPIO_PAD_STRENGTH_2):
- * case REG(DC_GPIO_DEBUG):
- */
- /* UNEXPECTED */
- default:
-/* case REG(DC_GPIO_SYNCA_A): not exist */
- ASSERT_CRITICAL(false);
- return false;
- }
+ ASSERT_CRITICAL(false);
+ return false;
}
@@ -156,158 +182,14 @@ static bool id_to_offset(
uint32_t en,
struct gpio_pin_info *info)
{
- bool result = true;
-
- switch (id) {
- case GPIO_ID_DDC_DATA:
- info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
-/* case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break; */
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_DDC_CLOCK:
- info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
-/* case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break; */
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GENERIC:
- info->offset = REG(DC_GPIO_GENERIC_A);
- switch (en) {
- case GPIO_GENERIC_A:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICA_A_MASK;
- break;
- case GPIO_GENERIC_B:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICB_A_MASK;
- break;
- case GPIO_GENERIC_C:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICC_A_MASK;
- break;
- case GPIO_GENERIC_D:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICD_A_MASK;
- break;
- case GPIO_GENERIC_E:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICE_A_MASK;
- break;
- case GPIO_GENERIC_F:
- info->mask = DC_GPIO_GENERIC_A__DC_GPIO_GENERICF_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_HPD:
- info->offset = REG(DC_GPIO_HPD_A);
- switch (en) {
- case GPIO_HPD_1:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD1_A_MASK;
- break;
- case GPIO_HPD_2:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD2_A_MASK;
- break;
- case GPIO_HPD_3:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD3_A_MASK;
- break;
- case GPIO_HPD_4:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD4_A_MASK;
- break;
- case GPIO_HPD_5:
- info->mask = DC_GPIO_HPD_A__DC_GPIO_HPD5_A_MASK;
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_GSL:
- switch (en) {
- case GPIO_GSL_GENLOCK_CLOCK:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_GENLOCK_VSYNC:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_A:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
- break;
- case GPIO_GSL_SWAPLOCK_B:
- /*not implmented*/
- ASSERT_CRITICAL(false);
- result = false;
-
- break;
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_SYNC:
- case GPIO_ID_VIP_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
-
- if (result) {
- info->offset_y = info->offset + 2;
- info->offset_en = info->offset + 1;
- info->offset_mask = info->offset - 1;
-
- info->mask_y = info->mask;
- info->mask_en = info->mask;
- info->mask_mask = info->mask;
- }
+ if (dal_hw_translate_id_to_offset(
+ gpio_pins,
+ ARRAY_SIZE(gpio_pins),
+ id, en, info))
+ return true;
- return result;
+ ASSERT_CRITICAL(false);
+ return false;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 9/9] drm/amd/display: convert dcn42 GPIO translation to lookup tables
2026-05-12 18:59 [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables Guilherme Ivo Bozi
` (7 preceding siblings ...)
2026-05-12 18:59 ` [PATCH 8/9] drm/amd/display: convert dcn401 " Guilherme Ivo Bozi
@ 2026-05-12 18:59 ` Guilherme Ivo Bozi
2026-05-16 3:03 ` Claude review: " Claude Code Review Bot
2026-05-16 3:03 ` Claude review: drm/amd/display: convert GPIO translation logic " Claude Code Review Bot
9 siblings, 1 reply; 20+ messages in thread
From: Guilherme Ivo Bozi @ 2026-05-12 18:59 UTC (permalink / raw)
To: airlied, alexander.deucher, christian.koenig, harry.wentland,
simona, siqueira, sunpeng.li
Cc: Guilherme Ivo Bozi, amd-gfx, dri-devel
Replace dcn42 GPIO translation switch statements with the
generic table-based translation helpers.
This simplifies the GPIO mapping logic and reduces duplicated
translation code.
No functional changes intended.
Signed-off-by: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
---
.../dc/gpio/dcn42/hw_translate_dcn42.c | 193 +++++++-----------
1 file changed, 70 insertions(+), 123 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_translate_dcn42.c b/drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_translate_dcn42.c
index e7e1d9979876..7b2c4cd42450 100644
--- a/drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_translate_dcn42.c
+++ b/drivers/gpu/drm/amd/display/dc/gpio/dcn42/hw_translate_dcn42.c
@@ -39,62 +39,76 @@
* end *********************/
+static const struct gpio_id_offset_entry gpio_offsets[] = {
+ /* HPD */
+ GPIO_ENTRY(HPD0_DC_HPD_INT_STATUS, GPIO_ID_HPD, GPIO_HPD_1),
+ GPIO_ENTRY(HPD1_DC_HPD_INT_STATUS, GPIO_ID_HPD, GPIO_HPD_2),
+ GPIO_ENTRY(HPD2_DC_HPD_INT_STATUS, GPIO_ID_HPD, GPIO_HPD_3),
+ GPIO_ENTRY(HPD3_DC_HPD_INT_STATUS, GPIO_ID_HPD, GPIO_HPD_4),
+ GPIO_ENTRY(HPD4_DC_HPD_INT_STATUS, GPIO_ID_HPD, GPIO_HPD_5),
+};
+
+
+/* DDC */
+static const struct gpio_ddc_offset_entry ddc_offset_map[] = {
+ { REG(DC_GPIO_DDC1_A), GPIO_DDC_LINE_DDC1 },
+ { REG(DC_GPIO_DDC2_A), GPIO_DDC_LINE_DDC2 },
+ { REG(DC_GPIO_DDC3_A), GPIO_DDC_LINE_DDC3 },
+ { REG(DC_GPIO_DDC4_A), GPIO_DDC_LINE_DDC4 },
+ { REG(DC_GPIO_DDC5_A), GPIO_DDC_LINE_DDC5 },
+ { REG(DC_GPIO_DDCVGA_A), GPIO_DDC_LINE_DDC_VGA },
+};
+
+
+static const struct gpio_pin_entry gpio_pins[] = {
+ /* DDC */
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC1,
+ DC_GPIO_DDC1_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC2,
+ DC_GPIO_DDC2_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC3,
+ DC_GPIO_DDC3_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC4,
+ DC_GPIO_DDC4_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC5,
+ DC_GPIO_DDC5_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+ GPIO_PIN_ENTRY(GPIO_ID_DDC_CLOCK, GPIO_DDC_LINE_DDC_VGA,
+ DC_GPIO_DDCVGA_A, DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK),
+};
+
+
static bool offset_to_id(
uint32_t offset,
uint32_t mask,
enum gpio_id *id,
uint32_t *en)
{
- (void)mask;
- switch (offset) {
- /* HPD */
- case REG(HPD0_DC_HPD_INT_STATUS):
- *id = GPIO_ID_HPD;
- *en = GPIO_HPD_1;
- return true;
- case REG(HPD1_DC_HPD_INT_STATUS):
- *id = GPIO_ID_HPD;
- *en = GPIO_HPD_2;
+ if (dal_hw_translate_gpio_ddc_offset_to_id(
+ ddc_offset_map,
+ ARRAY_SIZE(ddc_offset_map),
+ offset, en))
return true;
- case REG(HPD2_DC_HPD_INT_STATUS):
- *id = GPIO_ID_HPD;
- *en = GPIO_HPD_3;
- return true;
- case REG(HPD3_DC_HPD_INT_STATUS):
- *id = GPIO_ID_HPD;
- *en = GPIO_HPD_4;
- return true;
- case REG(HPD4_DC_HPD_INT_STATUS):
- *id = GPIO_ID_HPD;
- *en = GPIO_HPD_5;
- return true;
- /* DDC */
- /* we don't care about the GPIO_ID for DDC
- * in DdcHandle it will use GPIO_ID_DDC_DATA/GPIO_ID_DDC_CLOCK
- * directly in the create method
- */
- case REG(DC_GPIO_DDC1_A):
- *en = GPIO_DDC_LINE_DDC1;
- return true;
- case REG(DC_GPIO_DDC2_A):
- *en = GPIO_DDC_LINE_DDC2;
- return true;
- case REG(DC_GPIO_DDC3_A):
- *en = GPIO_DDC_LINE_DDC3;
- return true;
- case REG(DC_GPIO_DDC4_A):
- *en = GPIO_DDC_LINE_DDC4;
- return true;
- case REG(DC_GPIO_DDC5_A):
- *en = GPIO_DDC_LINE_DDC5;
- return true;
- case REG(DC_GPIO_DDCVGA_A):
- *en = GPIO_DDC_LINE_DDC_VGA;
+
+ if (dal_hw_translate_gpio_offset_to_id(
+ gpio_offsets,
+ ARRAY_SIZE(gpio_offsets),
+ offset, mask, id, en))
return true;
- default:
- ASSERT_CRITICAL(false);
- return false;
- }
+
+ ASSERT_CRITICAL(false);
+ return false;
}
@@ -103,81 +117,14 @@ static bool id_to_offset(
uint32_t en,
struct gpio_pin_info *info)
{
- bool result = true;
-
- switch (id) {
- case GPIO_ID_DDC_DATA:
- info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_DDC_CLOCK:
- info->mask = DC_GPIO_DDC1_A__DC_GPIO_DDC1CLK_A_MASK;
- switch (en) {
- case GPIO_DDC_LINE_DDC1:
- info->offset = REG(DC_GPIO_DDC1_A);
- break;
- case GPIO_DDC_LINE_DDC2:
- info->offset = REG(DC_GPIO_DDC2_A);
- break;
- case GPIO_DDC_LINE_DDC3:
- info->offset = REG(DC_GPIO_DDC3_A);
- break;
- case GPIO_DDC_LINE_DDC4:
- info->offset = REG(DC_GPIO_DDC4_A);
- break;
- case GPIO_DDC_LINE_DDC5:
- info->offset = REG(DC_GPIO_DDC5_A);
- break;
- case GPIO_DDC_LINE_DDC_VGA:
- info->offset = REG(DC_GPIO_DDCVGA_A);
- break;
- case GPIO_DDC_LINE_I2C_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
- break;
- case GPIO_ID_SYNC:
- case GPIO_ID_VIP_PAD:
- default:
- ASSERT_CRITICAL(false);
- result = false;
- }
-
- if (result) {
- info->offset_y = info->offset + 2;
- info->offset_en = info->offset + 1;
- info->offset_mask = info->offset - 1;
-
- info->mask_y = info->mask;
- info->mask_en = info->mask;
- info->mask_mask = info->mask;
- }
-
- return result;
+ if (dal_hw_translate_id_to_offset(
+ gpio_pins,
+ ARRAY_SIZE(gpio_pins),
+ id, en, info))
+ return true;
+
+ ASSERT_CRITICAL(false);
+ return false;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread* Claude review: drm/amd/display: convert dcn42 GPIO translation to lookup tables
2026-05-12 18:59 ` [PATCH 9/9] drm/amd/display: convert dcn42 " Guilherme Ivo Bozi
@ 2026-05-16 3:03 ` Claude Code Review Bot
0 siblings, 0 replies; 20+ messages in thread
From: Claude Code Review Bot @ 2026-05-16 3:03 UTC (permalink / raw)
To: dri-devel-reviews
Patch Review
Good use of `GPIO_ENTRY()` (no mask check) for the HPD entries, since the original dcn42 code explicitly discarded the mask with `(void)mask`. The `gpio_offsets[]` contains only HPD entries, and `gpio_pins[]` contains only DDC entries -- no GENERIC, GSL, or SYNCA -- matching the original minimal implementation for this generation.
No issues.
---
**Summary**: Well-executed mechanical refactoring. The only actionable item is the minor alignment nit in patch 2/9 on the I2C_PAD DDC_CLOCK entry. The behavioral change around previously-silent-return offsets (PWRSEQ, PAD_STRENGTH, DEBUG) in dcn10 now hitting ASSERT_CRITICAL is arguably an improvement rather than a concern.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 20+ messages in thread
* Claude review: drm/amd/display: convert GPIO translation logic to lookup tables
2026-05-12 18:59 [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables Guilherme Ivo Bozi
` (8 preceding siblings ...)
2026-05-12 18:59 ` [PATCH 9/9] drm/amd/display: convert dcn42 " Guilherme Ivo Bozi
@ 2026-05-16 3:03 ` Claude Code Review Bot
9 siblings, 0 replies; 20+ messages in thread
From: Claude Code Review Bot @ 2026-05-16 3:03 UTC (permalink / raw)
To: dri-devel-reviews
Overall Series Review
Subject: drm/amd/display: convert GPIO translation logic to lookup tables
Author: Guilherme Ivo Bozi <guilherme.bozi@usp.br>
Patches: 10
Reviewed: 2026-05-16T13:03:12.579109
---
This is a well-structured refactoring series that replaces repetitive switch-statement GPIO translation logic across 8 DCN generations with static lookup tables and shared helper functions. The approach is sound: patch 1 introduces the infrastructure (table entry types, macros, and three generic lookup helpers), and patches 2-9 mechanically convert each ASIC.
The series achieves a net reduction of ~760 lines while making the per-ASIC GPIO mappings declarative and easier to audit. The table structures are well-designed with the `check_mask` flag in `gpio_id_offset_entry` to handle both mask-discriminated entries (via `GPIO_MASK_ENTRY`) and simple offset-only entries (via `GPIO_ENTRY`, used by dcn42's per-HPD registers).
Behavioral equivalence is preserved across all conversions. The DDC mask values (e.g., `DDC1DATA_A_MASK` vs `DDC6DATA_A_MASK`) are identical constants (0x100 / 0x1) across all DDC channels in the hardware, so using any one channel's mask macro for all DDC lines is correct. The GSL omission from `gpio_pins[]` in dcn20+ is properly commented and matches the original "not implemented" assert paths. The dcn401 DDC5 commented-out entries match the original code.
Overall: **the series looks good** and is ready to merge with a couple of minor nits below.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 20+ messages in thread