* [PATCH 0/9] drm/amd/display: convert GPIO translation logic to lookup tables
@ 2026-05-12 18:59 Guilherme Ivo Bozi
2026-05-12 18:59 ` [PATCH 1/9] drm/amd/display: add GPIO HW translation helpers Guilherme Ivo Bozi
` (9 more replies)
0 siblings, 10 replies; 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
This series converts the GPIO HW translation logic used by
multiple DCN generations from large switch statements to
static lookup tables with shared helper functions.
The new implementation reduces duplicated translation logic
across generations and makes the GPIO mappings easier to
maintain and extend.
The series introduces generic GPIO translation helpers first,
followed by per-generation conversions.
The following generations were converted:
- dcn10
- dcn20
- dcn21
- dcn30
- dcn315
- dcn32
- dcn401
- dcn42
The dce60, dce80, dce110 and dce120 implementations were
left unchanged for now.
dce60 and dce80 contain special switch-case handling paths
that currently do not map cleanly to the new table-based
representation, so they were intentionally excluded from
this refactor.
No functional changes intended.
Guilherme Ivo Bozi (9):
drm/amd/display: add GPIO HW translation helpers
drm/amd/display: convert dcn10 GPIO translation to lookup tables
drm/amd/display: convert dcn20 GPIO translation to lookup tables
drm/amd/display: convert dcn21 GPIO translation to lookup tables
drm/amd/display: convert dcn30 GPIO translation to lookup tables
drm/amd/display: convert dcn315 GPIO translation to lookup tables
drm/amd/display: convert dcn32 GPIO translation to lookup tables
drm/amd/display: convert dcn401 GPIO translation to lookup tables
drm/amd/display: convert dcn42 GPIO translation to lookup tables
.../dc/gpio/dcn10/hw_translate_dcn10.c | 484 +++++++-----------
.../dc/gpio/dcn20/hw_translate_dcn20.c | 432 ++++++----------
.../dc/gpio/dcn21/hw_translate_dcn21.c | 417 ++++++---------
.../dc/gpio/dcn30/hw_translate_dcn30.c | 432 ++++++----------
.../dc/gpio/dcn315/hw_translate_dcn315.c | 418 ++++++---------
.../dc/gpio/dcn32/hw_translate_dcn32.c | 386 +++++---------
.../dc/gpio/dcn401/hw_translate_dcn401.c | 392 +++++---------
.../dc/gpio/dcn42/hw_translate_dcn42.c | 193 +++----
.../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 ++
11 files changed, 1274 insertions(+), 2035 deletions(-)
--
2.47.3
^ permalink raw reply [flat|nested] 20+ messages in thread
* [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
* [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
* [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 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
* 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
* 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
* Claude review: drm/amd/display: convert dcn20 GPIO translation to lookup tables
2026-05-12 18:59 ` [PATCH 3/9] drm/amd/display: convert dcn20 " 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. Correctly omits SYNCA (commented as "not exist" in the original) and I2C_PAD. The comment explaining GSL omission from `gpio_pins[]` is helpful:
```c
/*
* GSL is intentionally omitted here.
* id_to_offset() for GSL is not implemented on this ASIC.
*/
```
No issues.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 20+ messages in thread
* Claude review: drm/amd/display: convert dcn21 GPIO translation to lookup tables
2026-05-12 18:59 ` [PATCH 4/9] drm/amd/display: convert dcn21 " 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
Follows the same pattern as dcn20. DDC entries cover DDC1-5 and VGA (no DDC6, matching original). No SYNCA, no I2C_PAD.
No issues.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 20+ messages in thread
* Claude review: drm/amd/display: convert dcn30 GPIO translation to lookup tables
2026-05-12 18:59 ` [PATCH 5/9] drm/amd/display: convert dcn30 " 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
Same pattern. Adds DDC6 back (7 DDC entries vs 6 in dcn21), matching the original code.
No issues.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 20+ messages in thread
* Claude review: drm/amd/display: convert dcn315 GPIO translation to lookup tables
2026-05-12 18:59 ` [PATCH 6/9] drm/amd/display: convert dcn315 " 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. Uses `DC_GPIO_DDC1_A__DC_GPIO_DDC1DATA_A_MASK` for all DDC lines (instead of `DDC6DATA` used by dcn10/dcn30). This is correct -- all per-line DDC mask macros resolve to the same hardware constant values.
No issues.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 20+ messages in thread
* Claude review: drm/amd/display: convert dcn32 GPIO translation to lookup tables
2026-05-12 18:59 ` [PATCH 7/9] drm/amd/display: convert dcn32 " 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. Similar to dcn315 with 6 GENERIC entries (A-F, no G) and 5 HPDs.
No issues.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [flat|nested] 20+ messages in thread
* Claude review: drm/amd/display: convert dcn401 GPIO translation to lookup tables
2026-05-12 18:59 ` [PATCH 8/9] drm/amd/display: convert dcn401 " 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. DDC5 entries are correctly commented out in the table, matching the original code where DDC5 was also commented out in the switch statement. The `ddc_offset_map[]` also correctly omits DDC5 from the offset-to-id direction.
No issues.
---
Generated by Claude Code Patch Reviewer
^ permalink raw reply [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
end of thread, other threads:[~2026-05-16 3:03 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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-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
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
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
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
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
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
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
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: " Claude Code Review Bot
2026-05-16 3:03 ` Claude review: drm/amd/display: convert GPIO translation logic " Claude Code Review Bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox