Skip to contentSkip to conversation

drm/tegra: Miscellaneous cleanups

PATCH New Thierry Reding 2 participants 14 messages Nov 27, 2017 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover drm/tegra: Miscellaneous cleanups

From: Thierry Reding <[email protected]>

This series has some cleanup patches to fix up various, mostly minor issues with the Tegra DRM driver.

Patches 1-4 move register definitions into a table, which is necessary in order to prevent the stack from growing excessively large in the debugfs support.

Patches 5-10 move debugfs registration code into ->late_register() callbacks in order to tie them to the correct lifetime of device nodes.

Patches 11 and 12 are whitespace fixups and patch 13 fixes some naming issues in hardware capabilities.

Thierry

Thierry Reding (13):
drm/tegra: dc: Move register definitions into a table drm/tegra: dsi: Move register definitions into a table drm/tegra: hdmi: Move register definitions into a table drm/tegra: sor: Move register definitions into a table drm/tegra: dc: Reshuffle some code
drm/tegra: dc: Register debugfs in ->late_register() drm/tegra: dsi: Register debugfs in ->late_register() drm/tegra: hdmi: Register debugfs in ->late_register() drm/tegra: sor: Root debugfs files at the connector drm/tegra: sor: Register debugfs in ->late_register() drm/tegra: Do not wrap lines unnecessarily drm/tegra: vic: Properly align arguments drm/tegra: dc: Support background color

 drivers/gpu/drm/tegra/dc.c   | 858 +++++++++++++++++++++----------------------
 drivers/gpu/drm/tegra/dc.h   |  10 +-
 drivers/gpu/drm/tegra/drm.c  |   3 +-
 drivers/gpu/drm/tegra/dsi.c  | 228 +++++-------
 drivers/gpu/drm/tegra/hdmi.c | 504 ++++++++++++-------------
 drivers/gpu/drm/tegra/sor.c  | 304 ++++++++-------
 drivers/gpu/drm/tegra/vic.c  |   2 +-
 7 files changed, 919 insertions(+), 990 deletions(-)
Signature · 6 lines
2.15.0

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

A message that is not in the archive (sent off-list or not yet received): 20171127100758.22149-1-thierry.reding-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#2 lore raw

PATCH 1/13 drm/tegra: dc: Move register definitions into a table

From: Thierry Reding <[email protected]>

After commit 67e04d1ab19b ("drm/tegra: dc: Trace register accesses"), the debugfs register dump implementation causes excessive stack usage and can result in build warnings. To fix this, move the register definitions into a table and iterate over the table while dumping the registers to debugfs.

---
 drivers/gpu/drm/tegra/dc.c | 442 +++++++++++++++++++++++----------------------
 1 file changed, 224 insertions(+), 218 deletions(-)
drivers/gpu/drm/tegra/dc.c +224 -218
index 24a5ef4f5bb8..825419dff07b 100644
@@ -1383,10 +1383,228 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
+
+static const struct debugfs_reg32 tegra_dc_regs[] = {
+	DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT),
+	DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL),
+	DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT_ERROR),
+	DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT),
+	DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL),
+	DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT_ERROR),
+	DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT),
+	DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL),
+	DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT_ERROR),
+	DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT),
+	DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL),
+	DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT_ERROR),
+	DEBUGFS_REG32(DC_CMD_CONT_SYNCPT_VSYNC),
+	DEBUGFS_REG32(DC_CMD_DISPLAY_COMMAND_OPTION0),
+	DEBUGFS_REG32(DC_CMD_DISPLAY_COMMAND),
+	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE),
+	DEBUGFS_REG32(DC_CMD_DISPLAY_POWER_CONTROL),
+	DEBUGFS_REG32(DC_CMD_INT_STATUS),
+	DEBUGFS_REG32(DC_CMD_INT_MASK),
+	DEBUGFS_REG32(DC_CMD_INT_ENABLE),
+	DEBUGFS_REG32(DC_CMD_INT_TYPE),
+	DEBUGFS_REG32(DC_CMD_INT_POLARITY),
+	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE1),
+	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE2),
+	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE3),
+	DEBUGFS_REG32(DC_CMD_STATE_ACCESS),
+	DEBUGFS_REG32(DC_CMD_STATE_CONTROL),
+	DEBUGFS_REG32(DC_CMD_DISPLAY_WINDOW_HEADER),
+	DEBUGFS_REG32(DC_CMD_REG_ACT_CONTROL),
+	DEBUGFS_REG32(DC_COM_CRC_CONTROL),
+	DEBUGFS_REG32(DC_COM_CRC_CHECKSUM),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(0)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(1)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(2)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(3)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(0)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(1)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(2)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(3)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(0)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(1)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(2)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(3)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(0)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(1)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(2)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(3)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_DATA(0)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_DATA(1)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(0)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(1)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(2)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(3)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(4)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(5)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(6)),
+	DEBUGFS_REG32(DC_COM_PIN_MISC_CONTROL),
+	DEBUGFS_REG32(DC_COM_PIN_PM0_CONTROL),
+	DEBUGFS_REG32(DC_COM_PIN_PM0_DUTY_CYCLE),
+	DEBUGFS_REG32(DC_COM_PIN_PM1_CONTROL),
+	DEBUGFS_REG32(DC_COM_PIN_PM1_DUTY_CYCLE),
+	DEBUGFS_REG32(DC_COM_SPI_CONTROL),
+	DEBUGFS_REG32(DC_COM_SPI_START_BYTE),
+	DEBUGFS_REG32(DC_COM_HSPI_WRITE_DATA_AB),
+	DEBUGFS_REG32(DC_COM_HSPI_WRITE_DATA_CD),
+	DEBUGFS_REG32(DC_COM_HSPI_CS_DC),
+	DEBUGFS_REG32(DC_COM_SCRATCH_REGISTER_A),
+	DEBUGFS_REG32(DC_COM_SCRATCH_REGISTER_B),
+	DEBUGFS_REG32(DC_COM_GPIO_CTRL),
+	DEBUGFS_REG32(DC_COM_GPIO_DEBOUNCE_COUNTER),
+	DEBUGFS_REG32(DC_COM_CRC_CHECKSUM_LATCHED),
+	DEBUGFS_REG32(DC_DISP_DISP_SIGNAL_OPTIONS0),
+	DEBUGFS_REG32(DC_DISP_DISP_SIGNAL_OPTIONS1),
+	DEBUGFS_REG32(DC_DISP_DISP_WIN_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_DISP_MEM_HIGH_PRIORITY),
+	DEBUGFS_REG32(DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER),
+	DEBUGFS_REG32(DC_DISP_DISP_TIMING_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_REF_TO_SYNC),
+	DEBUGFS_REG32(DC_DISP_SYNC_WIDTH),
+	DEBUGFS_REG32(DC_DISP_BACK_PORCH),
+	DEBUGFS_REG32(DC_DISP_ACTIVE),
+	DEBUGFS_REG32(DC_DISP_FRONT_PORCH),
+	DEBUGFS_REG32(DC_DISP_H_PULSE0_CONTROL),
+	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_B),
+	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_C),
+	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_D),
+	DEBUGFS_REG32(DC_DISP_H_PULSE1_CONTROL),
+	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_B),
+	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_C),
+	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_D),
+	DEBUGFS_REG32(DC_DISP_H_PULSE2_CONTROL),
+	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_B),
+	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_C),
+	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_D),
+	DEBUGFS_REG32(DC_DISP_V_PULSE0_CONTROL),
+	DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_B),
+	DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_C),
+	DEBUGFS_REG32(DC_DISP_V_PULSE1_CONTROL),
+	DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_B),
+	DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_C),
+	DEBUGFS_REG32(DC_DISP_V_PULSE2_CONTROL),
+	DEBUGFS_REG32(DC_DISP_V_PULSE2_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_V_PULSE3_CONTROL),
+	DEBUGFS_REG32(DC_DISP_V_PULSE3_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_M0_CONTROL),
+	DEBUGFS_REG32(DC_DISP_M1_CONTROL),
+	DEBUGFS_REG32(DC_DISP_DI_CONTROL),
+	DEBUGFS_REG32(DC_DISP_PP_CONTROL),
+	DEBUGFS_REG32(DC_DISP_PP_SELECT_A),
+	DEBUGFS_REG32(DC_DISP_PP_SELECT_B),
+	DEBUGFS_REG32(DC_DISP_PP_SELECT_C),
+	DEBUGFS_REG32(DC_DISP_PP_SELECT_D),
+	DEBUGFS_REG32(DC_DISP_DISP_CLOCK_CONTROL),
+	DEBUGFS_REG32(DC_DISP_DISP_INTERFACE_CONTROL),
+	DEBUGFS_REG32(DC_DISP_DISP_COLOR_CONTROL),
+	DEBUGFS_REG32(DC_DISP_SHIFT_CLOCK_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_DATA_ENABLE_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_SERIAL_INTERFACE_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_LCD_SPI_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_BORDER_COLOR),
+	DEBUGFS_REG32(DC_DISP_COLOR_KEY0_LOWER),
+	DEBUGFS_REG32(DC_DISP_COLOR_KEY0_UPPER),
+	DEBUGFS_REG32(DC_DISP_COLOR_KEY1_LOWER),
+	DEBUGFS_REG32(DC_DISP_COLOR_KEY1_UPPER),
+	DEBUGFS_REG32(DC_DISP_CURSOR_FOREGROUND),
+	DEBUGFS_REG32(DC_DISP_CURSOR_BACKGROUND),
+	DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR),
+	DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR_NS),
+	DEBUGFS_REG32(DC_DISP_CURSOR_POSITION),
+	DEBUGFS_REG32(DC_DISP_CURSOR_POSITION_NS),
+	DEBUGFS_REG32(DC_DISP_INIT_SEQ_CONTROL),
+	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_A),
+	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_B),
+	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_C),
+	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_D),
+	DEBUGFS_REG32(DC_DISP_DC_MCCIF_FIFOCTRL),
+	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY0A_HYST),
+	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY0B_HYST),
+	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY1A_HYST),
+	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY1B_HYST),
+	DEBUGFS_REG32(DC_DISP_DAC_CRT_CTRL),
+	DEBUGFS_REG32(DC_DISP_DISP_MISC_CONTROL),
+	DEBUGFS_REG32(DC_DISP_SD_CONTROL),
+	DEBUGFS_REG32(DC_DISP_SD_CSC_COEFF),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(0)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(1)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(2)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(3)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(4)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(5)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(6)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(7)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(8)),
+	DEBUGFS_REG32(DC_DISP_SD_FLICKER_CONTROL),
+	DEBUGFS_REG32(DC_DISP_DC_PIXEL_COUNT),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(0)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(1)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(2)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(3)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(4)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(5)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(6)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(7)),
+	DEBUGFS_REG32(DC_DISP_SD_BL_TF(0)),
+	DEBUGFS_REG32(DC_DISP_SD_BL_TF(1)),
+	DEBUGFS_REG32(DC_DISP_SD_BL_TF(2)),
+	DEBUGFS_REG32(DC_DISP_SD_BL_TF(3)),
+	DEBUGFS_REG32(DC_DISP_SD_BL_CONTROL),
+	DEBUGFS_REG32(DC_DISP_SD_HW_K_VALUES),
+	DEBUGFS_REG32(DC_DISP_SD_MAN_K_VALUES),
+	DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR_HI),
+	DEBUGFS_REG32(DC_DISP_BLEND_CURSOR_CONTROL),
+	DEBUGFS_REG32(DC_WIN_WIN_OPTIONS),
+	DEBUGFS_REG32(DC_WIN_BYTE_SWAP),
+	DEBUGFS_REG32(DC_WIN_BUFFER_CONTROL),
+	DEBUGFS_REG32(DC_WIN_COLOR_DEPTH),
+	DEBUGFS_REG32(DC_WIN_POSITION),
+	DEBUGFS_REG32(DC_WIN_SIZE),
+	DEBUGFS_REG32(DC_WIN_PRESCALED_SIZE),
+	DEBUGFS_REG32(DC_WIN_H_INITIAL_DDA),
+	DEBUGFS_REG32(DC_WIN_V_INITIAL_DDA),
+	DEBUGFS_REG32(DC_WIN_DDA_INC),
+	DEBUGFS_REG32(DC_WIN_LINE_STRIDE),
+	DEBUGFS_REG32(DC_WIN_BUF_STRIDE),
+	DEBUGFS_REG32(DC_WIN_UV_BUF_STRIDE),
+	DEBUGFS_REG32(DC_WIN_BUFFER_ADDR_MODE),
+	DEBUGFS_REG32(DC_WIN_DV_CONTROL),
+	DEBUGFS_REG32(DC_WIN_BLEND_NOKEY),
+	DEBUGFS_REG32(DC_WIN_BLEND_1WIN),
+	DEBUGFS_REG32(DC_WIN_BLEND_2WIN_X),
+	DEBUGFS_REG32(DC_WIN_BLEND_2WIN_Y),
+	DEBUGFS_REG32(DC_WIN_BLEND_3WIN_XY),
+	DEBUGFS_REG32(DC_WIN_HP_FETCH_CONTROL),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR_NS),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR_U),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR_U_NS),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR_V),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR_V_NS),
+	DEBUGFS_REG32(DC_WINBUF_ADDR_H_OFFSET),
+	DEBUGFS_REG32(DC_WINBUF_ADDR_H_OFFSET_NS),
+	DEBUGFS_REG32(DC_WINBUF_ADDR_V_OFFSET),
+	DEBUGFS_REG32(DC_WINBUF_ADDR_V_OFFSET_NS),
+	DEBUGFS_REG32(DC_WINBUF_UFLOW_STATUS),
+	DEBUGFS_REG32(DC_WINBUF_AD_UFLOW_STATUS),
+	DEBUGFS_REG32(DC_WINBUF_BD_UFLOW_STATUS),
+	DEBUGFS_REG32(DC_WINBUF_CD_UFLOW_STATUS),
+};
+
 static int tegra_dc_show_regs(struct seq_file *s, void *data)
 {
 	struct drm_info_node *node = s->private;
 	struct tegra_dc *dc = node->info_ent->data;
+	unsigned int i;
 	int err = 0;
 
 	drm_modeset_lock(&dc->base.mutex, NULL);
@@ -1396,224 +1614,12 @@ static int tegra_dc_show_regs(struct seq_file *s, void *data)
 		goto unlock;
 	}
 
-#define DUMP_REG(name)						\
-	seq_printf(s, "%-40s %#05x %08x\n", #name, name,	\
-		   tegra_dc_readl(dc, name))
-
-	DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT);
-	DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
-	DUMP_REG(DC_CMD_GENERAL_INCR_SYNCPT_ERROR);
-	DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT);
-	DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL);
-	DUMP_REG(DC_CMD_WIN_A_INCR_SYNCPT_ERROR);
-	DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT);
-	DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL);
-	DUMP_REG(DC_CMD_WIN_B_INCR_SYNCPT_ERROR);
-	DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT);
-	DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL);
-	DUMP_REG(DC_CMD_WIN_C_INCR_SYNCPT_ERROR);
-	DUMP_REG(DC_CMD_CONT_SYNCPT_VSYNC);
-	DUMP_REG(DC_CMD_DISPLAY_COMMAND_OPTION0);
-	DUMP_REG(DC_CMD_DISPLAY_COMMAND);
-	DUMP_REG(DC_CMD_SIGNAL_RAISE);
-	DUMP_REG(DC_CMD_DISPLAY_POWER_CONTROL);
-	DUMP_REG(DC_CMD_INT_STATUS);
-	DUMP_REG(DC_CMD_INT_MASK);
-	DUMP_REG(DC_CMD_INT_ENABLE);
-	DUMP_REG(DC_CMD_INT_TYPE);
-	DUMP_REG(DC_CMD_INT_POLARITY);
-	DUMP_REG(DC_CMD_SIGNAL_RAISE1);
-	DUMP_REG(DC_CMD_SIGNAL_RAISE2);
-	DUMP_REG(DC_CMD_SIGNAL_RAISE3);
-	DUMP_REG(DC_CMD_STATE_ACCESS);
-	DUMP_REG(DC_CMD_STATE_CONTROL);
-	DUMP_REG(DC_CMD_DISPLAY_WINDOW_HEADER);
-	DUMP_REG(DC_CMD_REG_ACT_CONTROL);
-	DUMP_REG(DC_COM_CRC_CONTROL);
-	DUMP_REG(DC_COM_CRC_CHECKSUM);
-	DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(0));
-	DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(1));
-	DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(2));
-	DUMP_REG(DC_COM_PIN_OUTPUT_ENABLE(3));
-	DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(0));
-	DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(1));
-	DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(2));
-	DUMP_REG(DC_COM_PIN_OUTPUT_POLARITY(3));
-	DUMP_REG(DC_COM_PIN_OUTPUT_DATA(0));
-	DUMP_REG(DC_COM_PIN_OUTPUT_DATA(1));
-	DUMP_REG(DC_COM_PIN_OUTPUT_DATA(2));
-	DUMP_REG(DC_COM_PIN_OUTPUT_DATA(3));
-	DUMP_REG(DC_COM_PIN_INPUT_ENABLE(0));
-	DUMP_REG(DC_COM_PIN_INPUT_ENABLE(1));
-	DUMP_REG(DC_COM_PIN_INPUT_ENABLE(2));
-	DUMP_REG(DC_COM_PIN_INPUT_ENABLE(3));
-	DUMP_REG(DC_COM_PIN_INPUT_DATA(0));
-	DUMP_REG(DC_COM_PIN_INPUT_DATA(1));
-	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(0));
-	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(1));
-	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(2));
-	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(3));
-	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(4));
-	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(5));
-	DUMP_REG(DC_COM_PIN_OUTPUT_SELECT(6));
-	DUMP_REG(DC_COM_PIN_MISC_CONTROL);
-	DUMP_REG(DC_COM_PIN_PM0_CONTROL);
-	DUMP_REG(DC_COM_PIN_PM0_DUTY_CYCLE);
-	DUMP_REG(DC_COM_PIN_PM1_CONTROL);
-	DUMP_REG(DC_COM_PIN_PM1_DUTY_CYCLE);
-	DUMP_REG(DC_COM_SPI_CONTROL);
-	DUMP_REG(DC_COM_SPI_START_BYTE);
-	DUMP_REG(DC_COM_HSPI_WRITE_DATA_AB);
-	DUMP_REG(DC_COM_HSPI_WRITE_DATA_CD);
-	DUMP_REG(DC_COM_HSPI_CS_DC);
-	DUMP_REG(DC_COM_SCRATCH_REGISTER_A);
-	DUMP_REG(DC_COM_SCRATCH_REGISTER_B);
-	DUMP_REG(DC_COM_GPIO_CTRL);
-	DUMP_REG(DC_COM_GPIO_DEBOUNCE_COUNTER);
-	DUMP_REG(DC_COM_CRC_CHECKSUM_LATCHED);
-	DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS0);
-	DUMP_REG(DC_DISP_DISP_SIGNAL_OPTIONS1);
-	DUMP_REG(DC_DISP_DISP_WIN_OPTIONS);
-	DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY);
-	DUMP_REG(DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
-	DUMP_REG(DC_DISP_DISP_TIMING_OPTIONS);
-	DUMP_REG(DC_DISP_REF_TO_SYNC);
-	DUMP_REG(DC_DISP_SYNC_WIDTH);
-	DUMP_REG(DC_DISP_BACK_PORCH);
-	DUMP_REG(DC_DISP_ACTIVE);
-	DUMP_REG(DC_DISP_FRONT_PORCH);
-	DUMP_REG(DC_DISP_H_PULSE0_CONTROL);
-	DUMP_REG(DC_DISP_H_PULSE0_POSITION_A);
-	DUMP_REG(DC_DISP_H_PULSE0_POSITION_B);
-	DUMP_REG(DC_DISP_H_PULSE0_POSITION_C);
-	DUMP_REG(DC_DISP_H_PULSE0_POSITION_D);
-	DUMP_REG(DC_DISP_H_PULSE1_CONTROL);
-	DUMP_REG(DC_DISP_H_PULSE1_POSITION_A);
-	DUMP_REG(DC_DISP_H_PULSE1_POSITION_B);
-	DUMP_REG(DC_DISP_H_PULSE1_POSITION_C);
-	DUMP_REG(DC_DISP_H_PULSE1_POSITION_D);
-	DUMP_REG(DC_DISP_H_PULSE2_CONTROL);
-	DUMP_REG(DC_DISP_H_PULSE2_POSITION_A);
-	DUMP_REG(DC_DISP_H_PULSE2_POSITION_B);
-	DUMP_REG(DC_DISP_H_PULSE2_POSITION_C);
-	DUMP_REG(DC_DISP_H_PULSE2_POSITION_D);
-	DUMP_REG(DC_DISP_V_PULSE0_CONTROL);
-	DUMP_REG(DC_DISP_V_PULSE0_POSITION_A);
-	DUMP_REG(DC_DISP_V_PULSE0_POSITION_B);
-	DUMP_REG(DC_DISP_V_PULSE0_POSITION_C);
-	DUMP_REG(DC_DISP_V_PULSE1_CONTROL);
-	DUMP_REG(DC_DISP_V_PULSE1_POSITION_A);
-	DUMP_REG(DC_DISP_V_PULSE1_POSITION_B);
-	DUMP_REG(DC_DISP_V_PULSE1_POSITION_C);
-	DUMP_REG(DC_DISP_V_PULSE2_CONTROL);
-	DUMP_REG(DC_DISP_V_PULSE2_POSITION_A);
-	DUMP_REG(DC_DISP_V_PULSE3_CONTROL);
-	DUMP_REG(DC_DISP_V_PULSE3_POSITION_A);
-	DUMP_REG(DC_DISP_M0_CONTROL);
-	DUMP_REG(DC_DISP_M1_CONTROL);
-	DUMP_REG(DC_DISP_DI_CONTROL);
-	DUMP_REG(DC_DISP_PP_CONTROL);
-	DUMP_REG(DC_DISP_PP_SELECT_A);
-	DUMP_REG(DC_DISP_PP_SELECT_B);
-	DUMP_REG(DC_DISP_PP_SELECT_C);
-	DUMP_REG(DC_DISP_PP_SELECT_D);
-	DUMP_REG(DC_DISP_DISP_CLOCK_CONTROL);
-	DUMP_REG(DC_DISP_DISP_INTERFACE_CONTROL);
-	DUMP_REG(DC_DISP_DISP_COLOR_CONTROL);
-	DUMP_REG(DC_DISP_SHIFT_CLOCK_OPTIONS);
-	DUMP_REG(DC_DISP_DATA_ENABLE_OPTIONS);
-	DUMP_REG(DC_DISP_SERIAL_INTERFACE_OPTIONS);
-	DUMP_REG(DC_DISP_LCD_SPI_OPTIONS);
-	DUMP_REG(DC_DISP_BORDER_COLOR);
-	DUMP_REG(DC_DISP_COLOR_KEY0_LOWER);
-	DUMP_REG(DC_DISP_COLOR_KEY0_UPPER);
-	DUMP_REG(DC_DISP_COLOR_KEY1_LOWER);
-	DUMP_REG(DC_DISP_COLOR_KEY1_UPPER);
-	DUMP_REG(DC_DISP_CURSOR_FOREGROUND);
-	DUMP_REG(DC_DISP_CURSOR_BACKGROUND);
-	DUMP_REG(DC_DISP_CURSOR_START_ADDR);
-	DUMP_REG(DC_DISP_CURSOR_START_ADDR_NS);
-	DUMP_REG(DC_DISP_CURSOR_POSITION);
-	DUMP_REG(DC_DISP_CURSOR_POSITION_NS);
-	DUMP_REG(DC_DISP_INIT_SEQ_CONTROL);
-	DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_A);
-	DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_B);
-	DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_C);
-	DUMP_REG(DC_DISP_SPI_INIT_SEQ_DATA_D);
-	DUMP_REG(DC_DISP_DC_MCCIF_FIFOCTRL);
-	DUMP_REG(DC_DISP_MCCIF_DISPLAY0A_HYST);
-	DUMP_REG(DC_DISP_MCCIF_DISPLAY0B_HYST);
-	DUMP_REG(DC_DISP_MCCIF_DISPLAY1A_HYST);
-	DUMP_REG(DC_DISP_MCCIF_DISPLAY1B_HYST);
-	DUMP_REG(DC_DISP_DAC_CRT_CTRL);
-	DUMP_REG(DC_DISP_DISP_MISC_CONTROL);
-	DUMP_REG(DC_DISP_SD_CONTROL);
-	DUMP_REG(DC_DISP_SD_CSC_COEFF);
-	DUMP_REG(DC_DISP_SD_LUT(0));
-	DUMP_REG(DC_DISP_SD_LUT(1));
-	DUMP_REG(DC_DISP_SD_LUT(2));
-	DUMP_REG(DC_DISP_SD_LUT(3));
-	DUMP_REG(DC_DISP_SD_LUT(4));
-	DUMP_REG(DC_DISP_SD_LUT(5));
-	DUMP_REG(DC_DISP_SD_LUT(6));
-	DUMP_REG(DC_DISP_SD_LUT(7));
-	DUMP_REG(DC_DISP_SD_LUT(8));
-	DUMP_REG(DC_DISP_SD_FLICKER_CONTROL);
-	DUMP_REG(DC_DISP_DC_PIXEL_COUNT);
-	DUMP_REG(DC_DISP_SD_HISTOGRAM(0));
-	DUMP_REG(DC_DISP_SD_HISTOGRAM(1));
-	DUMP_REG(DC_DISP_SD_HISTOGRAM(2));
-	DUMP_REG(DC_DISP_SD_HISTOGRAM(3));
-	DUMP_REG(DC_DISP_SD_HISTOGRAM(4));
-	DUMP_REG(DC_DISP_SD_HISTOGRAM(5));
-	DUMP_REG(DC_DISP_SD_HISTOGRAM(6));
-	DUMP_REG(DC_DISP_SD_HISTOGRAM(7));
-	DUMP_REG(DC_DISP_SD_BL_TF(0));
-	DUMP_REG(DC_DISP_SD_BL_TF(1));
-	DUMP_REG(DC_DISP_SD_BL_TF(2));
-	DUMP_REG(DC_DISP_SD_BL_TF(3));
-	DUMP_REG(DC_DISP_SD_BL_CONTROL);
-	DUMP_REG(DC_DISP_SD_HW_K_VALUES);
-	DUMP_REG(DC_DISP_SD_MAN_K_VALUES);
-	DUMP_REG(DC_DISP_CURSOR_START_ADDR_HI);
-	DUMP_REG(DC_DISP_BLEND_CURSOR_CONTROL);
-	DUMP_REG(DC_WIN_WIN_OPTIONS);
-	DUMP_REG(DC_WIN_BYTE_SWAP);
-	DUMP_REG(DC_WIN_BUFFER_CONTROL);
-	DUMP_REG(DC_WIN_COLOR_DEPTH);
-	DUMP_REG(DC_WIN_POSITION);
-	DUMP_REG(DC_WIN_SIZE);
-	DUMP_REG(DC_WIN_PRESCALED_SIZE);
-	DUMP_REG(DC_WIN_H_INITIAL_DDA);
-	DUMP_REG(DC_WIN_V_INITIAL_DDA);
-	DUMP_REG(DC_WIN_DDA_INC);
-	DUMP_REG(DC_WIN_LINE_STRIDE);
-	DUMP_REG(DC_WIN_BUF_STRIDE);
-	DUMP_REG(DC_WIN_UV_BUF_STRIDE);
-	DUMP_REG(DC_WIN_BUFFER_ADDR_MODE);
-	DUMP_REG(DC_WIN_DV_CONTROL);
-	DUMP_REG(DC_WIN_BLEND_NOKEY);
-	DUMP_REG(DC_WIN_BLEND_1WIN);
-	DUMP_REG(DC_WIN_BLEND_2WIN_X);
-	DUMP_REG(DC_WIN_BLEND_2WIN_Y);
-	DUMP_REG(DC_WIN_BLEND_3WIN_XY);
-	DUMP_REG(DC_WIN_HP_FETCH_CONTROL);
-	DUMP_REG(DC_WINBUF_START_ADDR);
-	DUMP_REG(DC_WINBUF_START_ADDR_NS);
-	DUMP_REG(DC_WINBUF_START_ADDR_U);
-	DUMP_REG(DC_WINBUF_START_ADDR_U_NS);
-	DUMP_REG(DC_WINBUF_START_ADDR_V);
-	DUMP_REG(DC_WINBUF_START_ADDR_V_NS);
-	DUMP_REG(DC_WINBUF_ADDR_H_OFFSET);
-	DUMP_REG(DC_WINBUF_ADDR_H_OFFSET_NS);
-	DUMP_REG(DC_WINBUF_ADDR_V_OFFSET);
-	DUMP_REG(DC_WINBUF_ADDR_V_OFFSET_NS);
-	DUMP_REG(DC_WINBUF_UFLOW_STATUS);
-	DUMP_REG(DC_WINBUF_AD_UFLOW_STATUS);
-	DUMP_REG(DC_WINBUF_BD_UFLOW_STATUS);
-	DUMP_REG(DC_WINBUF_CD_UFLOW_STATUS);
-
-#undef DUMP_REG
+	for (i = 0; i < ARRAY_SIZE(tegra_dc_regs); i++) {
+		unsigned int offset = tegra_dc_regs[i].offset;
+
+		seq_printf(s, "%-40s %#05x %08x\n", tegra_dc_regs[i].name,
+			   offset, tegra_dc_readl(dc, offset));
+	}
 
 unlock:
 	drm_modeset_unlock(&dc->base.mutex);
Signature · 1 line
2.15.0
#3 lore raw

PATCH 2/13 drm/tegra: dsi: Move register definitions into a table

In reply to a message not in the archive

From: Thierry Reding <[email protected]>

After commit 75af8fa7fd47 ("drm/tegra: dsi: Trace register accesses"), the debugfs register dump implementation causes excessive stack usage and can result in build warnings. To fix this, move the register definitions into a table and iterate over the table while dumping the registers to debugfs.

---
 drivers/gpu/drm/tegra/dsi.c | 170 +++++++++++++++++++++-----------------------
 1 file changed, 83 insertions(+), 87 deletions(-)
drivers/gpu/drm/tegra/dsi.c +83 -87
index 046649ec9441..4a78af08df82 100644
@@ -122,12 +122,89 @@ static inline void tegra_dsi_writel(struct tegra_dsi *dsi, u32 value,
 	writel(value, dsi->regs + (offset << 2));
 }
 
+#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
+
+static const struct debugfs_reg32 tegra_dsi_regs[] = {
+	DEBUGFS_REG32(DSI_INCR_SYNCPT),
+	DEBUGFS_REG32(DSI_INCR_SYNCPT_CONTROL),
+	DEBUGFS_REG32(DSI_INCR_SYNCPT_ERROR),
+	DEBUGFS_REG32(DSI_CTXSW),
+	DEBUGFS_REG32(DSI_RD_DATA),
+	DEBUGFS_REG32(DSI_WR_DATA),
+	DEBUGFS_REG32(DSI_POWER_CONTROL),
+	DEBUGFS_REG32(DSI_INT_ENABLE),
+	DEBUGFS_REG32(DSI_INT_STATUS),
+	DEBUGFS_REG32(DSI_INT_MASK),
+	DEBUGFS_REG32(DSI_HOST_CONTROL),
+	DEBUGFS_REG32(DSI_CONTROL),
+	DEBUGFS_REG32(DSI_SOL_DELAY),
+	DEBUGFS_REG32(DSI_MAX_THRESHOLD),
+	DEBUGFS_REG32(DSI_TRIGGER),
+	DEBUGFS_REG32(DSI_TX_CRC),
+	DEBUGFS_REG32(DSI_STATUS),
+	DEBUGFS_REG32(DSI_INIT_SEQ_CONTROL),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_0),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_1),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_2),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_3),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_4),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_5),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_6),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_7),
+	DEBUGFS_REG32(DSI_PKT_SEQ_0_LO),
+	DEBUGFS_REG32(DSI_PKT_SEQ_0_HI),
+	DEBUGFS_REG32(DSI_PKT_SEQ_1_LO),
+	DEBUGFS_REG32(DSI_PKT_SEQ_1_HI),
+	DEBUGFS_REG32(DSI_PKT_SEQ_2_LO),
+	DEBUGFS_REG32(DSI_PKT_SEQ_2_HI),
+	DEBUGFS_REG32(DSI_PKT_SEQ_3_LO),
+	DEBUGFS_REG32(DSI_PKT_SEQ_3_HI),
+	DEBUGFS_REG32(DSI_PKT_SEQ_4_LO),
+	DEBUGFS_REG32(DSI_PKT_SEQ_4_HI),
+	DEBUGFS_REG32(DSI_PKT_SEQ_5_LO),
+	DEBUGFS_REG32(DSI_PKT_SEQ_5_HI),
+	DEBUGFS_REG32(DSI_DCS_CMDS),
+	DEBUGFS_REG32(DSI_PKT_LEN_0_1),
+	DEBUGFS_REG32(DSI_PKT_LEN_2_3),
+	DEBUGFS_REG32(DSI_PKT_LEN_4_5),
+	DEBUGFS_REG32(DSI_PKT_LEN_6_7),
+	DEBUGFS_REG32(DSI_PHY_TIMING_0),
+	DEBUGFS_REG32(DSI_PHY_TIMING_1),
+	DEBUGFS_REG32(DSI_PHY_TIMING_2),
+	DEBUGFS_REG32(DSI_BTA_TIMING),
+	DEBUGFS_REG32(DSI_TIMEOUT_0),
+	DEBUGFS_REG32(DSI_TIMEOUT_1),
+	DEBUGFS_REG32(DSI_TO_TALLY),
+	DEBUGFS_REG32(DSI_PAD_CONTROL_0),
+	DEBUGFS_REG32(DSI_PAD_CONTROL_CD),
+	DEBUGFS_REG32(DSI_PAD_CD_STATUS),
+	DEBUGFS_REG32(DSI_VIDEO_MODE_CONTROL),
+	DEBUGFS_REG32(DSI_PAD_CONTROL_1),
+	DEBUGFS_REG32(DSI_PAD_CONTROL_2),
+	DEBUGFS_REG32(DSI_PAD_CONTROL_3),
+	DEBUGFS_REG32(DSI_PAD_CONTROL_4),
+	DEBUGFS_REG32(DSI_GANGED_MODE_CONTROL),
+	DEBUGFS_REG32(DSI_GANGED_MODE_START),
+	DEBUGFS_REG32(DSI_GANGED_MODE_SIZE),
+	DEBUGFS_REG32(DSI_RAW_DATA_BYTE_COUNT),
+	DEBUGFS_REG32(DSI_ULTRA_LOW_POWER_CONTROL),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_8),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_9),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_10),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_11),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_12),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_13),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_14),
+	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_15),
+};
+
 static int tegra_dsi_show_regs(struct seq_file *s, void *data)
 {
 	struct drm_info_node *node = s->private;
 	struct tegra_dsi *dsi = node->info_ent->data;
 	struct drm_crtc *crtc = dsi->output.encoder.crtc;
 	struct drm_device *drm = node->minor->dev;
+	unsigned int i;
 	int err = 0;
 
 	drm_modeset_lock_all(drm);
@@ -137,93 +214,12 @@ static int tegra_dsi_show_regs(struct seq_file *s, void *data)
 		goto unlock;
 	}
 
-#define DUMP_REG(name)						\
-	seq_printf(s, "%-32s %#05x %08x\n", #name, name,	\
-		   tegra_dsi_readl(dsi, name))
-
-	DUMP_REG(DSI_INCR_SYNCPT);
-	DUMP_REG(DSI_INCR_SYNCPT_CONTROL);
-	DUMP_REG(DSI_INCR_SYNCPT_ERROR);
-	DUMP_REG(DSI_CTXSW);
-	DUMP_REG(DSI_RD_DATA);
-	DUMP_REG(DSI_WR_DATA);
-	DUMP_REG(DSI_POWER_CONTROL);
-	DUMP_REG(DSI_INT_ENABLE);
-	DUMP_REG(DSI_INT_STATUS);
-	DUMP_REG(DSI_INT_MASK);
-	DUMP_REG(DSI_HOST_CONTROL);
-	DUMP_REG(DSI_CONTROL);
-	DUMP_REG(DSI_SOL_DELAY);
-	DUMP_REG(DSI_MAX_THRESHOLD);
-	DUMP_REG(DSI_TRIGGER);
-	DUMP_REG(DSI_TX_CRC);
-	DUMP_REG(DSI_STATUS);
-
-	DUMP_REG(DSI_INIT_SEQ_CONTROL);
-	DUMP_REG(DSI_INIT_SEQ_DATA_0);
-	DUMP_REG(DSI_INIT_SEQ_DATA_1);
-	DUMP_REG(DSI_INIT_SEQ_DATA_2);
-	DUMP_REG(DSI_INIT_SEQ_DATA_3);
-	DUMP_REG(DSI_INIT_SEQ_DATA_4);
-	DUMP_REG(DSI_INIT_SEQ_DATA_5);
-	DUMP_REG(DSI_INIT_SEQ_DATA_6);
-	DUMP_REG(DSI_INIT_SEQ_DATA_7);
-
-	DUMP_REG(DSI_PKT_SEQ_0_LO);
-	DUMP_REG(DSI_PKT_SEQ_0_HI);
-	DUMP_REG(DSI_PKT_SEQ_1_LO);
-	DUMP_REG(DSI_PKT_SEQ_1_HI);
-	DUMP_REG(DSI_PKT_SEQ_2_LO);
-	DUMP_REG(DSI_PKT_SEQ_2_HI);
-	DUMP_REG(DSI_PKT_SEQ_3_LO);
-	DUMP_REG(DSI_PKT_SEQ_3_HI);
-	DUMP_REG(DSI_PKT_SEQ_4_LO);
-	DUMP_REG(DSI_PKT_SEQ_4_HI);
-	DUMP_REG(DSI_PKT_SEQ_5_LO);
-	DUMP_REG(DSI_PKT_SEQ_5_HI);
-
-	DUMP_REG(DSI_DCS_CMDS);
-
-	DUMP_REG(DSI_PKT_LEN_0_1);
-	DUMP_REG(DSI_PKT_LEN_2_3);
-	DUMP_REG(DSI_PKT_LEN_4_5);
-	DUMP_REG(DSI_PKT_LEN_6_7);
-
-	DUMP_REG(DSI_PHY_TIMING_0);
-	DUMP_REG(DSI_PHY_TIMING_1);
-	DUMP_REG(DSI_PHY_TIMING_2);
-	DUMP_REG(DSI_BTA_TIMING);
-
-	DUMP_REG(DSI_TIMEOUT_0);
-	DUMP_REG(DSI_TIMEOUT_1);
-	DUMP_REG(DSI_TO_TALLY);
-
-	DUMP_REG(DSI_PAD_CONTROL_0);
-	DUMP_REG(DSI_PAD_CONTROL_CD);
-	DUMP_REG(DSI_PAD_CD_STATUS);
-	DUMP_REG(DSI_VIDEO_MODE_CONTROL);
-	DUMP_REG(DSI_PAD_CONTROL_1);
-	DUMP_REG(DSI_PAD_CONTROL_2);
-	DUMP_REG(DSI_PAD_CONTROL_3);
-	DUMP_REG(DSI_PAD_CONTROL_4);
-
-	DUMP_REG(DSI_GANGED_MODE_CONTROL);
-	DUMP_REG(DSI_GANGED_MODE_START);
-	DUMP_REG(DSI_GANGED_MODE_SIZE);
-
-	DUMP_REG(DSI_RAW_DATA_BYTE_COUNT);
-	DUMP_REG(DSI_ULTRA_LOW_POWER_CONTROL);
-
-	DUMP_REG(DSI_INIT_SEQ_DATA_8);
-	DUMP_REG(DSI_INIT_SEQ_DATA_9);
-	DUMP_REG(DSI_INIT_SEQ_DATA_10);
-	DUMP_REG(DSI_INIT_SEQ_DATA_11);
-	DUMP_REG(DSI_INIT_SEQ_DATA_12);
-	DUMP_REG(DSI_INIT_SEQ_DATA_13);
-	DUMP_REG(DSI_INIT_SEQ_DATA_14);
-	DUMP_REG(DSI_INIT_SEQ_DATA_15);
-
-#undef DUMP_REG
+	for (i = 0; i < ARRAY_SIZE(tegra_dsi_regs); i++) {
+		unsigned int offset = tegra_dsi_regs[i].offset;
+
+		seq_printf(s, "%-32s %#05x %08x\n", tegra_dsi_regs[i].name,
+			   offset, tegra_dsi_readl(dsi, offset));
+	}
 
 unlock:
 	drm_modeset_unlock_all(drm);
Signature · 1 line
2.15.0
#4 lore raw

PATCH 6/13 drm/tegra: dc: Register debugfs in ->late_register()

In reply to a message not in the archive

From: Thierry Reding <[email protected]>

The ->late_register() and ->early_unregister() callbacks are called at the right time to make sure userspace only accesses interfaces when it should. Move debugfs registration and unregistration to these callback functions to avoid potential races with userspace.

---
 drivers/gpu/drm/tegra/dc.c | 698 ++++++++++++++++++++++-----------------------
 drivers/gpu/drm/tegra/dc.h |   2 -
 2 files changed, 335 insertions(+), 365 deletions(-)
drivers/gpu/drm/tegra/dc.c +335 -363
index 052f512572d5..69d98bf84ceb 100644
@@ -959,6 +959,339 @@ static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc,
 	kfree(state);
 }
 
+#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
+
+static const struct debugfs_reg32 tegra_dc_regs[] = {
+	DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT),
+	DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL),
+	DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT_ERROR),
+	DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT),
+	DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL),
+	DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT_ERROR),
+	DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT),
+	DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL),
+	DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT_ERROR),
+	DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT),
+	DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL),
+	DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT_ERROR),
+	DEBUGFS_REG32(DC_CMD_CONT_SYNCPT_VSYNC),
+	DEBUGFS_REG32(DC_CMD_DISPLAY_COMMAND_OPTION0),
+	DEBUGFS_REG32(DC_CMD_DISPLAY_COMMAND),
+	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE),
+	DEBUGFS_REG32(DC_CMD_DISPLAY_POWER_CONTROL),
+	DEBUGFS_REG32(DC_CMD_INT_STATUS),
+	DEBUGFS_REG32(DC_CMD_INT_MASK),
+	DEBUGFS_REG32(DC_CMD_INT_ENABLE),
+	DEBUGFS_REG32(DC_CMD_INT_TYPE),
+	DEBUGFS_REG32(DC_CMD_INT_POLARITY),
+	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE1),
+	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE2),
+	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE3),
+	DEBUGFS_REG32(DC_CMD_STATE_ACCESS),
+	DEBUGFS_REG32(DC_CMD_STATE_CONTROL),
+	DEBUGFS_REG32(DC_CMD_DISPLAY_WINDOW_HEADER),
+	DEBUGFS_REG32(DC_CMD_REG_ACT_CONTROL),
+	DEBUGFS_REG32(DC_COM_CRC_CONTROL),
+	DEBUGFS_REG32(DC_COM_CRC_CHECKSUM),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(0)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(1)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(2)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(3)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(0)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(1)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(2)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(3)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(0)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(1)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(2)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(3)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(0)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(1)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(2)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(3)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_DATA(0)),
+	DEBUGFS_REG32(DC_COM_PIN_INPUT_DATA(1)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(0)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(1)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(2)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(3)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(4)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(5)),
+	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(6)),
+	DEBUGFS_REG32(DC_COM_PIN_MISC_CONTROL),
+	DEBUGFS_REG32(DC_COM_PIN_PM0_CONTROL),
+	DEBUGFS_REG32(DC_COM_PIN_PM0_DUTY_CYCLE),
+	DEBUGFS_REG32(DC_COM_PIN_PM1_CONTROL),
+	DEBUGFS_REG32(DC_COM_PIN_PM1_DUTY_CYCLE),
+	DEBUGFS_REG32(DC_COM_SPI_CONTROL),
+	DEBUGFS_REG32(DC_COM_SPI_START_BYTE),
+	DEBUGFS_REG32(DC_COM_HSPI_WRITE_DATA_AB),
+	DEBUGFS_REG32(DC_COM_HSPI_WRITE_DATA_CD),
+	DEBUGFS_REG32(DC_COM_HSPI_CS_DC),
+	DEBUGFS_REG32(DC_COM_SCRATCH_REGISTER_A),
+	DEBUGFS_REG32(DC_COM_SCRATCH_REGISTER_B),
+	DEBUGFS_REG32(DC_COM_GPIO_CTRL),
+	DEBUGFS_REG32(DC_COM_GPIO_DEBOUNCE_COUNTER),
+	DEBUGFS_REG32(DC_COM_CRC_CHECKSUM_LATCHED),
+	DEBUGFS_REG32(DC_DISP_DISP_SIGNAL_OPTIONS0),
+	DEBUGFS_REG32(DC_DISP_DISP_SIGNAL_OPTIONS1),
+	DEBUGFS_REG32(DC_DISP_DISP_WIN_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_DISP_MEM_HIGH_PRIORITY),
+	DEBUGFS_REG32(DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER),
+	DEBUGFS_REG32(DC_DISP_DISP_TIMING_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_REF_TO_SYNC),
+	DEBUGFS_REG32(DC_DISP_SYNC_WIDTH),
+	DEBUGFS_REG32(DC_DISP_BACK_PORCH),
+	DEBUGFS_REG32(DC_DISP_ACTIVE),
+	DEBUGFS_REG32(DC_DISP_FRONT_PORCH),
+	DEBUGFS_REG32(DC_DISP_H_PULSE0_CONTROL),
+	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_B),
+	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_C),
+	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_D),
+	DEBUGFS_REG32(DC_DISP_H_PULSE1_CONTROL),
+	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_B),
+	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_C),
+	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_D),
+	DEBUGFS_REG32(DC_DISP_H_PULSE2_CONTROL),
+	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_B),
+	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_C),
+	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_D),
+	DEBUGFS_REG32(DC_DISP_V_PULSE0_CONTROL),
+	DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_B),
+	DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_C),
+	DEBUGFS_REG32(DC_DISP_V_PULSE1_CONTROL),
+	DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_B),
+	DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_C),
+	DEBUGFS_REG32(DC_DISP_V_PULSE2_CONTROL),
+	DEBUGFS_REG32(DC_DISP_V_PULSE2_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_V_PULSE3_CONTROL),
+	DEBUGFS_REG32(DC_DISP_V_PULSE3_POSITION_A),
+	DEBUGFS_REG32(DC_DISP_M0_CONTROL),
+	DEBUGFS_REG32(DC_DISP_M1_CONTROL),
+	DEBUGFS_REG32(DC_DISP_DI_CONTROL),
+	DEBUGFS_REG32(DC_DISP_PP_CONTROL),
+	DEBUGFS_REG32(DC_DISP_PP_SELECT_A),
+	DEBUGFS_REG32(DC_DISP_PP_SELECT_B),
+	DEBUGFS_REG32(DC_DISP_PP_SELECT_C),
+	DEBUGFS_REG32(DC_DISP_PP_SELECT_D),
+	DEBUGFS_REG32(DC_DISP_DISP_CLOCK_CONTROL),
+	DEBUGFS_REG32(DC_DISP_DISP_INTERFACE_CONTROL),
+	DEBUGFS_REG32(DC_DISP_DISP_COLOR_CONTROL),
+	DEBUGFS_REG32(DC_DISP_SHIFT_CLOCK_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_DATA_ENABLE_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_SERIAL_INTERFACE_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_LCD_SPI_OPTIONS),
+	DEBUGFS_REG32(DC_DISP_BORDER_COLOR),
+	DEBUGFS_REG32(DC_DISP_COLOR_KEY0_LOWER),
+	DEBUGFS_REG32(DC_DISP_COLOR_KEY0_UPPER),
+	DEBUGFS_REG32(DC_DISP_COLOR_KEY1_LOWER),
+	DEBUGFS_REG32(DC_DISP_COLOR_KEY1_UPPER),
+	DEBUGFS_REG32(DC_DISP_CURSOR_FOREGROUND),
+	DEBUGFS_REG32(DC_DISP_CURSOR_BACKGROUND),
+	DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR),
+	DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR_NS),
+	DEBUGFS_REG32(DC_DISP_CURSOR_POSITION),
+	DEBUGFS_REG32(DC_DISP_CURSOR_POSITION_NS),
+	DEBUGFS_REG32(DC_DISP_INIT_SEQ_CONTROL),
+	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_A),
+	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_B),
+	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_C),
+	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_D),
+	DEBUGFS_REG32(DC_DISP_DC_MCCIF_FIFOCTRL),
+	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY0A_HYST),
+	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY0B_HYST),
+	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY1A_HYST),
+	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY1B_HYST),
+	DEBUGFS_REG32(DC_DISP_DAC_CRT_CTRL),
+	DEBUGFS_REG32(DC_DISP_DISP_MISC_CONTROL),
+	DEBUGFS_REG32(DC_DISP_SD_CONTROL),
+	DEBUGFS_REG32(DC_DISP_SD_CSC_COEFF),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(0)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(1)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(2)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(3)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(4)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(5)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(6)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(7)),
+	DEBUGFS_REG32(DC_DISP_SD_LUT(8)),
+	DEBUGFS_REG32(DC_DISP_SD_FLICKER_CONTROL),
+	DEBUGFS_REG32(DC_DISP_DC_PIXEL_COUNT),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(0)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(1)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(2)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(3)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(4)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(5)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(6)),
+	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(7)),
+	DEBUGFS_REG32(DC_DISP_SD_BL_TF(0)),
+	DEBUGFS_REG32(DC_DISP_SD_BL_TF(1)),
+	DEBUGFS_REG32(DC_DISP_SD_BL_TF(2)),
+	DEBUGFS_REG32(DC_DISP_SD_BL_TF(3)),
+	DEBUGFS_REG32(DC_DISP_SD_BL_CONTROL),
+	DEBUGFS_REG32(DC_DISP_SD_HW_K_VALUES),
+	DEBUGFS_REG32(DC_DISP_SD_MAN_K_VALUES),
+	DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR_HI),
+	DEBUGFS_REG32(DC_DISP_BLEND_CURSOR_CONTROL),
+	DEBUGFS_REG32(DC_WIN_WIN_OPTIONS),
+	DEBUGFS_REG32(DC_WIN_BYTE_SWAP),
+	DEBUGFS_REG32(DC_WIN_BUFFER_CONTROL),
+	DEBUGFS_REG32(DC_WIN_COLOR_DEPTH),
+	DEBUGFS_REG32(DC_WIN_POSITION),
+	DEBUGFS_REG32(DC_WIN_SIZE),
+	DEBUGFS_REG32(DC_WIN_PRESCALED_SIZE),
+	DEBUGFS_REG32(DC_WIN_H_INITIAL_DDA),
+	DEBUGFS_REG32(DC_WIN_V_INITIAL_DDA),
+	DEBUGFS_REG32(DC_WIN_DDA_INC),
+	DEBUGFS_REG32(DC_WIN_LINE_STRIDE),
+	DEBUGFS_REG32(DC_WIN_BUF_STRIDE),
+	DEBUGFS_REG32(DC_WIN_UV_BUF_STRIDE),
+	DEBUGFS_REG32(DC_WIN_BUFFER_ADDR_MODE),
+	DEBUGFS_REG32(DC_WIN_DV_CONTROL),
+	DEBUGFS_REG32(DC_WIN_BLEND_NOKEY),
+	DEBUGFS_REG32(DC_WIN_BLEND_1WIN),
+	DEBUGFS_REG32(DC_WIN_BLEND_2WIN_X),
+	DEBUGFS_REG32(DC_WIN_BLEND_2WIN_Y),
+	DEBUGFS_REG32(DC_WIN_BLEND_3WIN_XY),
+	DEBUGFS_REG32(DC_WIN_HP_FETCH_CONTROL),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR_NS),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR_U),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR_U_NS),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR_V),
+	DEBUGFS_REG32(DC_WINBUF_START_ADDR_V_NS),
+	DEBUGFS_REG32(DC_WINBUF_ADDR_H_OFFSET),
+	DEBUGFS_REG32(DC_WINBUF_ADDR_H_OFFSET_NS),
+	DEBUGFS_REG32(DC_WINBUF_ADDR_V_OFFSET),
+	DEBUGFS_REG32(DC_WINBUF_ADDR_V_OFFSET_NS),
+	DEBUGFS_REG32(DC_WINBUF_UFLOW_STATUS),
+	DEBUGFS_REG32(DC_WINBUF_AD_UFLOW_STATUS),
+	DEBUGFS_REG32(DC_WINBUF_BD_UFLOW_STATUS),
+	DEBUGFS_REG32(DC_WINBUF_CD_UFLOW_STATUS),
+};
+
+static int tegra_dc_show_regs(struct seq_file *s, void *data)
+{
+	struct drm_info_node *node = s->private;
+	struct tegra_dc *dc = node->info_ent->data;
+	unsigned int i;
+	int err = 0;
+
+	drm_modeset_lock(&dc->base.mutex, NULL);
+
+	if (!dc->base.state->active) {
+		err = -EBUSY;
+		goto unlock;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(tegra_dc_regs); i++) {
+		unsigned int offset = tegra_dc_regs[i].offset;
+
+		seq_printf(s, "%-40s %#05x %08x\n", tegra_dc_regs[i].name,
+			   offset, tegra_dc_readl(dc, offset));
+	}
+
+unlock:
+	drm_modeset_unlock(&dc->base.mutex);
+	return err;
+}
+
+static int tegra_dc_show_crc(struct seq_file *s, void *data)
+{
+	struct drm_info_node *node = s->private;
+	struct tegra_dc *dc = node->info_ent->data;
+	int err = 0;
+	u32 value;
+
+	drm_modeset_lock(&dc->base.mutex, NULL);
+
+	if (!dc->base.state->active) {
+		err = -EBUSY;
+		goto unlock;
+	}
+
+	value = DC_COM_CRC_CONTROL_ACTIVE_DATA | DC_COM_CRC_CONTROL_ENABLE;
+	tegra_dc_writel(dc, value, DC_COM_CRC_CONTROL);
+	tegra_dc_commit(dc);
+
+	drm_crtc_wait_one_vblank(&dc->base);
+	drm_crtc_wait_one_vblank(&dc->base);
+
+	value = tegra_dc_readl(dc, DC_COM_CRC_CHECKSUM);
+	seq_printf(s, "%08x\n", value);
+
+	tegra_dc_writel(dc, 0, DC_COM_CRC_CONTROL);
+
+unlock:
+	drm_modeset_unlock(&dc->base.mutex);
+	return err;
+}
+
+static int tegra_dc_show_stats(struct seq_file *s, void *data)
+{
+	struct drm_info_node *node = s->private;
+	struct tegra_dc *dc = node->info_ent->data;
+
+	seq_printf(s, "frames: %lu\n", dc->stats.frames);
+	seq_printf(s, "vblank: %lu\n", dc->stats.vblank);
+	seq_printf(s, "underflow: %lu\n", dc->stats.underflow);
+	seq_printf(s, "overflow: %lu\n", dc->stats.overflow);
+
+	return 0;
+}
+
+static struct drm_info_list debugfs_files[] = {
+	{ "regs", tegra_dc_show_regs, 0, NULL },
+	{ "crc", tegra_dc_show_crc, 0, NULL },
+	{ "stats", tegra_dc_show_stats, 0, NULL },
+};
+
+static int tegra_dc_late_register(struct drm_crtc *crtc)
+{
+	unsigned int i, count = ARRAY_SIZE(debugfs_files);
+	struct drm_minor *minor = crtc->dev->primary;
+	struct dentry *root = crtc->debugfs_entry;
+	struct tegra_dc *dc = to_tegra_dc(crtc);
+	int err;
+
+	dc->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
+				    GFP_KERNEL);
+	if (!dc->debugfs_files)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++)
+		dc->debugfs_files[i].data = dc;
+
+	err = drm_debugfs_create_files(dc->debugfs_files, count, root, minor);
+	if (err < 0)
+		goto free;
+
+	return 0;
+
+free:
+	kfree(dc->debugfs_files);
+	dc->debugfs_files = NULL;
+
+	return err;
+}
+
+static void tegra_dc_early_unregister(struct drm_crtc *crtc)
+{
+	unsigned int count = ARRAY_SIZE(debugfs_files);
+	struct drm_minor *minor = crtc->dev->primary;
+	struct tegra_dc *dc = to_tegra_dc(crtc);
+
+	drm_debugfs_remove_files(dc->debugfs_files, count, minor);
+	kfree(dc->debugfs_files);
+	dc->debugfs_files = NULL;
+}
+
 static u32 tegra_dc_get_vblank_counter(struct drm_crtc *crtc)
 {
 	struct tegra_dc *dc = to_tegra_dc(crtc);
@@ -1007,6 +1340,8 @@ static const struct drm_crtc_funcs tegra_crtc_funcs = {
 	.reset = tegra_crtc_reset,
 	.atomic_duplicate_state = tegra_crtc_atomic_duplicate_state,
 	.atomic_destroy_state = tegra_crtc_atomic_destroy_state,
+	.late_register = tegra_dc_late_register,
+	.early_unregister = tegra_dc_early_unregister,
 	.get_vblank_counter = tegra_dc_get_vblank_counter,
 	.enable_vblank = tegra_dc_enable_vblank,
 	.disable_vblank = tegra_dc_disable_vblank,
@@ -1383,357 +1718,6 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
-
-static const struct debugfs_reg32 tegra_dc_regs[] = {
-	DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT),
-	DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT_CNTRL),
-	DEBUGFS_REG32(DC_CMD_GENERAL_INCR_SYNCPT_ERROR),
-	DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT),
-	DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT_CNTRL),
-	DEBUGFS_REG32(DC_CMD_WIN_A_INCR_SYNCPT_ERROR),
-	DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT),
-	DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT_CNTRL),
-	DEBUGFS_REG32(DC_CMD_WIN_B_INCR_SYNCPT_ERROR),
-	DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT),
-	DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT_CNTRL),
-	DEBUGFS_REG32(DC_CMD_WIN_C_INCR_SYNCPT_ERROR),
-	DEBUGFS_REG32(DC_CMD_CONT_SYNCPT_VSYNC),
-	DEBUGFS_REG32(DC_CMD_DISPLAY_COMMAND_OPTION0),
-	DEBUGFS_REG32(DC_CMD_DISPLAY_COMMAND),
-	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE),
-	DEBUGFS_REG32(DC_CMD_DISPLAY_POWER_CONTROL),
-	DEBUGFS_REG32(DC_CMD_INT_STATUS),
-	DEBUGFS_REG32(DC_CMD_INT_MASK),
-	DEBUGFS_REG32(DC_CMD_INT_ENABLE),
-	DEBUGFS_REG32(DC_CMD_INT_TYPE),
-	DEBUGFS_REG32(DC_CMD_INT_POLARITY),
-	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE1),
-	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE2),
-	DEBUGFS_REG32(DC_CMD_SIGNAL_RAISE3),
-	DEBUGFS_REG32(DC_CMD_STATE_ACCESS),
-	DEBUGFS_REG32(DC_CMD_STATE_CONTROL),
-	DEBUGFS_REG32(DC_CMD_DISPLAY_WINDOW_HEADER),
-	DEBUGFS_REG32(DC_CMD_REG_ACT_CONTROL),
-	DEBUGFS_REG32(DC_COM_CRC_CONTROL),
-	DEBUGFS_REG32(DC_COM_CRC_CHECKSUM),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(0)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(1)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(2)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_ENABLE(3)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(0)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(1)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(2)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_POLARITY(3)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(0)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(1)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(2)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_DATA(3)),
-	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(0)),
-	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(1)),
-	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(2)),
-	DEBUGFS_REG32(DC_COM_PIN_INPUT_ENABLE(3)),
-	DEBUGFS_REG32(DC_COM_PIN_INPUT_DATA(0)),
-	DEBUGFS_REG32(DC_COM_PIN_INPUT_DATA(1)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(0)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(1)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(2)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(3)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(4)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(5)),
-	DEBUGFS_REG32(DC_COM_PIN_OUTPUT_SELECT(6)),
-	DEBUGFS_REG32(DC_COM_PIN_MISC_CONTROL),
-	DEBUGFS_REG32(DC_COM_PIN_PM0_CONTROL),
-	DEBUGFS_REG32(DC_COM_PIN_PM0_DUTY_CYCLE),
-	DEBUGFS_REG32(DC_COM_PIN_PM1_CONTROL),
-	DEBUGFS_REG32(DC_COM_PIN_PM1_DUTY_CYCLE),
-	DEBUGFS_REG32(DC_COM_SPI_CONTROL),
-	DEBUGFS_REG32(DC_COM_SPI_START_BYTE),
-	DEBUGFS_REG32(DC_COM_HSPI_WRITE_DATA_AB),
-	DEBUGFS_REG32(DC_COM_HSPI_WRITE_DATA_CD),
-	DEBUGFS_REG32(DC_COM_HSPI_CS_DC),
-	DEBUGFS_REG32(DC_COM_SCRATCH_REGISTER_A),
-	DEBUGFS_REG32(DC_COM_SCRATCH_REGISTER_B),
-	DEBUGFS_REG32(DC_COM_GPIO_CTRL),
-	DEBUGFS_REG32(DC_COM_GPIO_DEBOUNCE_COUNTER),
-	DEBUGFS_REG32(DC_COM_CRC_CHECKSUM_LATCHED),
-	DEBUGFS_REG32(DC_DISP_DISP_SIGNAL_OPTIONS0),
-	DEBUGFS_REG32(DC_DISP_DISP_SIGNAL_OPTIONS1),
-	DEBUGFS_REG32(DC_DISP_DISP_WIN_OPTIONS),
-	DEBUGFS_REG32(DC_DISP_DISP_MEM_HIGH_PRIORITY),
-	DEBUGFS_REG32(DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER),
-	DEBUGFS_REG32(DC_DISP_DISP_TIMING_OPTIONS),
-	DEBUGFS_REG32(DC_DISP_REF_TO_SYNC),
-	DEBUGFS_REG32(DC_DISP_SYNC_WIDTH),
-	DEBUGFS_REG32(DC_DISP_BACK_PORCH),
-	DEBUGFS_REG32(DC_DISP_ACTIVE),
-	DEBUGFS_REG32(DC_DISP_FRONT_PORCH),
-	DEBUGFS_REG32(DC_DISP_H_PULSE0_CONTROL),
-	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_A),
-	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_B),
-	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_C),
-	DEBUGFS_REG32(DC_DISP_H_PULSE0_POSITION_D),
-	DEBUGFS_REG32(DC_DISP_H_PULSE1_CONTROL),
-	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_A),
-	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_B),
-	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_C),
-	DEBUGFS_REG32(DC_DISP_H_PULSE1_POSITION_D),
-	DEBUGFS_REG32(DC_DISP_H_PULSE2_CONTROL),
-	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_A),
-	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_B),
-	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_C),
-	DEBUGFS_REG32(DC_DISP_H_PULSE2_POSITION_D),
-	DEBUGFS_REG32(DC_DISP_V_PULSE0_CONTROL),
-	DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_A),
-	DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_B),
-	DEBUGFS_REG32(DC_DISP_V_PULSE0_POSITION_C),
-	DEBUGFS_REG32(DC_DISP_V_PULSE1_CONTROL),
-	DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_A),
-	DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_B),
-	DEBUGFS_REG32(DC_DISP_V_PULSE1_POSITION_C),
-	DEBUGFS_REG32(DC_DISP_V_PULSE2_CONTROL),
-	DEBUGFS_REG32(DC_DISP_V_PULSE2_POSITION_A),
-	DEBUGFS_REG32(DC_DISP_V_PULSE3_CONTROL),
-	DEBUGFS_REG32(DC_DISP_V_PULSE3_POSITION_A),
-	DEBUGFS_REG32(DC_DISP_M0_CONTROL),
-	DEBUGFS_REG32(DC_DISP_M1_CONTROL),
-	DEBUGFS_REG32(DC_DISP_DI_CONTROL),
-	DEBUGFS_REG32(DC_DISP_PP_CONTROL),
-	DEBUGFS_REG32(DC_DISP_PP_SELECT_A),
-	DEBUGFS_REG32(DC_DISP_PP_SELECT_B),
-	DEBUGFS_REG32(DC_DISP_PP_SELECT_C),
-	DEBUGFS_REG32(DC_DISP_PP_SELECT_D),
-	DEBUGFS_REG32(DC_DISP_DISP_CLOCK_CONTROL),
-	DEBUGFS_REG32(DC_DISP_DISP_INTERFACE_CONTROL),
-	DEBUGFS_REG32(DC_DISP_DISP_COLOR_CONTROL),
-	DEBUGFS_REG32(DC_DISP_SHIFT_CLOCK_OPTIONS),
-	DEBUGFS_REG32(DC_DISP_DATA_ENABLE_OPTIONS),
-	DEBUGFS_REG32(DC_DISP_SERIAL_INTERFACE_OPTIONS),
-	DEBUGFS_REG32(DC_DISP_LCD_SPI_OPTIONS),
-	DEBUGFS_REG32(DC_DISP_BORDER_COLOR),
-	DEBUGFS_REG32(DC_DISP_COLOR_KEY0_LOWER),
-	DEBUGFS_REG32(DC_DISP_COLOR_KEY0_UPPER),
-	DEBUGFS_REG32(DC_DISP_COLOR_KEY1_LOWER),
-	DEBUGFS_REG32(DC_DISP_COLOR_KEY1_UPPER),
-	DEBUGFS_REG32(DC_DISP_CURSOR_FOREGROUND),
-	DEBUGFS_REG32(DC_DISP_CURSOR_BACKGROUND),
-	DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR),
-	DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR_NS),
-	DEBUGFS_REG32(DC_DISP_CURSOR_POSITION),
-	DEBUGFS_REG32(DC_DISP_CURSOR_POSITION_NS),
-	DEBUGFS_REG32(DC_DISP_INIT_SEQ_CONTROL),
-	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_A),
-	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_B),
-	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_C),
-	DEBUGFS_REG32(DC_DISP_SPI_INIT_SEQ_DATA_D),
-	DEBUGFS_REG32(DC_DISP_DC_MCCIF_FIFOCTRL),
-	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY0A_HYST),
-	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY0B_HYST),
-	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY1A_HYST),
-	DEBUGFS_REG32(DC_DISP_MCCIF_DISPLAY1B_HYST),
-	DEBUGFS_REG32(DC_DISP_DAC_CRT_CTRL),
-	DEBUGFS_REG32(DC_DISP_DISP_MISC_CONTROL),
-	DEBUGFS_REG32(DC_DISP_SD_CONTROL),
-	DEBUGFS_REG32(DC_DISP_SD_CSC_COEFF),
-	DEBUGFS_REG32(DC_DISP_SD_LUT(0)),
-	DEBUGFS_REG32(DC_DISP_SD_LUT(1)),
-	DEBUGFS_REG32(DC_DISP_SD_LUT(2)),
-	DEBUGFS_REG32(DC_DISP_SD_LUT(3)),
-	DEBUGFS_REG32(DC_DISP_SD_LUT(4)),
-	DEBUGFS_REG32(DC_DISP_SD_LUT(5)),
-	DEBUGFS_REG32(DC_DISP_SD_LUT(6)),
-	DEBUGFS_REG32(DC_DISP_SD_LUT(7)),
-	DEBUGFS_REG32(DC_DISP_SD_LUT(8)),
-	DEBUGFS_REG32(DC_DISP_SD_FLICKER_CONTROL),
-	DEBUGFS_REG32(DC_DISP_DC_PIXEL_COUNT),
-	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(0)),
-	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(1)),
-	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(2)),
-	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(3)),
-	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(4)),
-	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(5)),
-	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(6)),
-	DEBUGFS_REG32(DC_DISP_SD_HISTOGRAM(7)),
-	DEBUGFS_REG32(DC_DISP_SD_BL_TF(0)),
-	DEBUGFS_REG32(DC_DISP_SD_BL_TF(1)),
-	DEBUGFS_REG32(DC_DISP_SD_BL_TF(2)),
-	DEBUGFS_REG32(DC_DISP_SD_BL_TF(3)),
-	DEBUGFS_REG32(DC_DISP_SD_BL_CONTROL),
-	DEBUGFS_REG32(DC_DISP_SD_HW_K_VALUES),
-	DEBUGFS_REG32(DC_DISP_SD_MAN_K_VALUES),
-	DEBUGFS_REG32(DC_DISP_CURSOR_START_ADDR_HI),
-	DEBUGFS_REG32(DC_DISP_BLEND_CURSOR_CONTROL),
-	DEBUGFS_REG32(DC_WIN_WIN_OPTIONS),
-	DEBUGFS_REG32(DC_WIN_BYTE_SWAP),
-	DEBUGFS_REG32(DC_WIN_BUFFER_CONTROL),
-	DEBUGFS_REG32(DC_WIN_COLOR_DEPTH),
-	DEBUGFS_REG32(DC_WIN_POSITION),
-	DEBUGFS_REG32(DC_WIN_SIZE),
-	DEBUGFS_REG32(DC_WIN_PRESCALED_SIZE),
-	DEBUGFS_REG32(DC_WIN_H_INITIAL_DDA),
-	DEBUGFS_REG32(DC_WIN_V_INITIAL_DDA),
-	DEBUGFS_REG32(DC_WIN_DDA_INC),
-	DEBUGFS_REG32(DC_WIN_LINE_STRIDE),
-	DEBUGFS_REG32(DC_WIN_BUF_STRIDE),
-	DEBUGFS_REG32(DC_WIN_UV_BUF_STRIDE),
-	DEBUGFS_REG32(DC_WIN_BUFFER_ADDR_MODE),
-	DEBUGFS_REG32(DC_WIN_DV_CONTROL),
-	DEBUGFS_REG32(DC_WIN_BLEND_NOKEY),
-	DEBUGFS_REG32(DC_WIN_BLEND_1WIN),
-	DEBUGFS_REG32(DC_WIN_BLEND_2WIN_X),
-	DEBUGFS_REG32(DC_WIN_BLEND_2WIN_Y),
-	DEBUGFS_REG32(DC_WIN_BLEND_3WIN_XY),
-	DEBUGFS_REG32(DC_WIN_HP_FETCH_CONTROL),
-	DEBUGFS_REG32(DC_WINBUF_START_ADDR),
-	DEBUGFS_REG32(DC_WINBUF_START_ADDR_NS),
-	DEBUGFS_REG32(DC_WINBUF_START_ADDR_U),
-	DEBUGFS_REG32(DC_WINBUF_START_ADDR_U_NS),
-	DEBUGFS_REG32(DC_WINBUF_START_ADDR_V),
-	DEBUGFS_REG32(DC_WINBUF_START_ADDR_V_NS),
-	DEBUGFS_REG32(DC_WINBUF_ADDR_H_OFFSET),
-	DEBUGFS_REG32(DC_WINBUF_ADDR_H_OFFSET_NS),
-	DEBUGFS_REG32(DC_WINBUF_ADDR_V_OFFSET),
-	DEBUGFS_REG32(DC_WINBUF_ADDR_V_OFFSET_NS),
-	DEBUGFS_REG32(DC_WINBUF_UFLOW_STATUS),
-	DEBUGFS_REG32(DC_WINBUF_AD_UFLOW_STATUS),
-	DEBUGFS_REG32(DC_WINBUF_BD_UFLOW_STATUS),
-	DEBUGFS_REG32(DC_WINBUF_CD_UFLOW_STATUS),
-};
-
-static int tegra_dc_show_regs(struct seq_file *s, void *data)
-{
-	struct drm_info_node *node = s->private;
-	struct tegra_dc *dc = node->info_ent->data;
-	unsigned int i;
-	int err = 0;
-
-	drm_modeset_lock(&dc->base.mutex, NULL);
-
-	if (!dc->base.state->active) {
-		err = -EBUSY;
-		goto unlock;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(tegra_dc_regs); i++) {
-		unsigned int offset = tegra_dc_regs[i].offset;
-
-		seq_printf(s, "%-40s %#05x %08x\n", tegra_dc_regs[i].name,
-			   offset, tegra_dc_readl(dc, offset));
-	}
-
-unlock:
-	drm_modeset_unlock(&dc->base.mutex);
-	return err;
-}
-
-static int tegra_dc_show_crc(struct seq_file *s, void *data)
-{
-	struct drm_info_node *node = s->private;
-	struct tegra_dc *dc = node->info_ent->data;
-	int err = 0;
-	u32 value;
-
-	drm_modeset_lock(&dc->base.mutex, NULL);
-
-	if (!dc->base.state->active) {
-		err = -EBUSY;
-		goto unlock;
-	}
-
-	value = DC_COM_CRC_CONTROL_ACTIVE_DATA | DC_COM_CRC_CONTROL_ENABLE;
-	tegra_dc_writel(dc, value, DC_COM_CRC_CONTROL);
-	tegra_dc_commit(dc);
-
-	drm_crtc_wait_one_vblank(&dc->base);
-	drm_crtc_wait_one_vblank(&dc->base);
-
-	value = tegra_dc_readl(dc, DC_COM_CRC_CHECKSUM);
-	seq_printf(s, "%08x\n", value);
-
-	tegra_dc_writel(dc, 0, DC_COM_CRC_CONTROL);
-
-unlock:
-	drm_modeset_unlock(&dc->base.mutex);
-	return err;
-}
-
-static int tegra_dc_show_stats(struct seq_file *s, void *data)
-{
-	struct drm_info_node *node = s->private;
-	struct tegra_dc *dc = node->info_ent->data;
-
-	seq_printf(s, "frames: %lu\n", dc->stats.frames);
-	seq_printf(s, "vblank: %lu\n", dc->stats.vblank);
-	seq_printf(s, "underflow: %lu\n", dc->stats.underflow);
-	seq_printf(s, "overflow: %lu\n", dc->stats.overflow);
-
-	return 0;
-}
-
-static struct drm_info_list debugfs_files[] = {
-	{ "regs", tegra_dc_show_regs, 0, NULL },
-	{ "crc", tegra_dc_show_crc, 0, NULL },
-	{ "stats", tegra_dc_show_stats, 0, NULL },
-};
-
-static int tegra_dc_debugfs_init(struct tegra_dc *dc, struct drm_minor *minor)
-{
-	unsigned int i;
-	char *name;
-	int err;
-
-	name = kasprintf(GFP_KERNEL, "dc.%d", dc->pipe);
-	dc->debugfs = debugfs_create_dir(name, minor->debugfs_root);
-	kfree(name);
-
-	if (!dc->debugfs)
-		return -ENOMEM;
-
-	dc->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
-				    GFP_KERNEL);
-	if (!dc->debugfs_files) {
-		err = -ENOMEM;
-		goto remove;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(debugfs_files); i++)
-		dc->debugfs_files[i].data = dc;
-
-	err = drm_debugfs_create_files(dc->debugfs_files,
-				       ARRAY_SIZE(debugfs_files),
-				       dc->debugfs, minor);
-	if (err < 0)
-		goto free;
-
-	dc->minor = minor;
-
-	return 0;
-
-free:
-	kfree(dc->debugfs_files);
-	dc->debugfs_files = NULL;
-remove:
-	debugfs_remove(dc->debugfs);
-	dc->debugfs = NULL;
-
-	return err;
-}
-
-static int tegra_dc_debugfs_exit(struct tegra_dc *dc)
-{
-	drm_debugfs_remove_files(dc->debugfs_files, ARRAY_SIZE(debugfs_files),
-				 dc->minor);
-	dc->minor = NULL;
-
-	kfree(dc->debugfs_files);
-	dc->debugfs_files = NULL;
-
-	debugfs_remove(dc->debugfs);
-	dc->debugfs = NULL;
-
-	return 0;
-}
-
 static int tegra_dc_init(struct host1x_client *client)
 {
 	struct drm_device *drm = dev_get_drvdata(client->parent);
@@ -1797,12 +1781,6 @@ static int tegra_dc_init(struct host1x_client *client)
 	if (err < 0)
 		goto cleanup;
 
-	if (IS_ENABLED(CONFIG_DEBUG_FS)) {
-		err = tegra_dc_debugfs_init(dc, drm->primary);
-		if (err < 0)
-			dev_err(dc->dev, "debugfs setup failed: %d\n", err);
-	}
-
 	err = devm_request_irq(dc->dev, dc->irq, tegra_dc_irq, 0,
 			       dev_name(dc->dev), dc);
 	if (err < 0) {
@@ -1835,12 +1813,6 @@ static int tegra_dc_exit(struct host1x_client *client)
 
 	devm_free_irq(dc->dev, dc->irq, dc);
 
-	if (IS_ENABLED(CONFIG_DEBUG_FS)) {
-		err = tegra_dc_debugfs_exit(dc);
-		if (err < 0)
-			dev_err(dc->dev, "debugfs cleanup failed: %d\n", err);
-	}
-
 	err = tegra_dc_rgb_exit(dc);
 	if (err) {
 		dev_err(dc->dev, "failed to shutdown RGB output: %d\n", err);
drivers/gpu/drm/tegra/dc.h +0 -2
index cb100b6e3282..032c734dd470 100644
@@ -56,8 +56,6 @@ struct tegra_dc {
 	struct list_head list;
 
 	struct drm_info_list *debugfs_files;
-	struct drm_minor *minor;
-	struct dentry *debugfs;
 
 	/* page-flip handling */
 	struct drm_pending_vblank_event *event;
Signature · 1 line
2.15.0
#5 lore raw

PATCH 7/13 drm/tegra: dsi: Register debugfs in ->late_register()

In reply to a message not in the archive

From: Thierry Reding <[email protected]>

The ->late_register() and ->early_unregister() callbacks are called at the right time to make sure userspace only accesses interfaces when it should. Move debugfs registration and unregistration to these callback functions to avoid potential races with userspace.

---
 drivers/gpu/drm/tegra/dsi.c | 58 ++++++++++++++-------------------------------
 1 file changed, 18 insertions(+), 40 deletions(-)
drivers/gpu/drm/tegra/dsi.c +18 -40
index 4a78af08df82..4d2ed966f9e3 100644
@@ -65,8 +65,6 @@ struct tegra_dsi {
 	struct clk *clk;
 
 	struct drm_info_list *debugfs_files;
-	struct drm_minor *minor;
-	struct dentry *debugfs;
 
 	unsigned long flags;
 	enum mipi_dsi_pixel_format format;
@@ -230,58 +228,46 @@ static struct drm_info_list debugfs_files[] = {
 	{ "regs", tegra_dsi_show_regs, 0, NULL },
 };
 
-static int tegra_dsi_debugfs_init(struct tegra_dsi *dsi,
-				  struct drm_minor *minor)
+static int tegra_dsi_late_register(struct drm_connector *connector)
 {
-	const char *name = dev_name(dsi->dev);
-	unsigned int i;
+	struct tegra_output *output = connector_to_output(connector);
+	unsigned int i, count = ARRAY_SIZE(debugfs_files);
+	struct drm_minor *minor = connector->dev->primary;
+	struct dentry *root = connector->debugfs_entry;
+	struct tegra_dsi *dsi = to_dsi(output);
 	int err;
 
-	dsi->debugfs = debugfs_create_dir(name, minor->debugfs_root);
-	if (!dsi->debugfs)
-		return -ENOMEM;
-
 	dsi->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
 				     GFP_KERNEL);
-	if (!dsi->debugfs_files) {
-		err = -ENOMEM;
-		goto remove;
-	}
+	if (!dsi->debugfs_files)
+		return -ENOMEM;
 
-	for (i = 0; i < ARRAY_SIZE(debugfs_files); i++)
+	for (i = 0; i < count; i++)
 		dsi->debugfs_files[i].data = dsi;
 
-	err = drm_debugfs_create_files(dsi->debugfs_files,
-				       ARRAY_SIZE(debugfs_files),
-				       dsi->debugfs, minor);
+	err = drm_debugfs_create_files(dsi->debugfs_files, count, root, minor);
 	if (err < 0)
 		goto free;
 
-	dsi->minor = minor;
-
 	return 0;
 
 free:
 	kfree(dsi->debugfs_files);
 	dsi->debugfs_files = NULL;
-remove:
-	debugfs_remove(dsi->debugfs);
-	dsi->debugfs = NULL;
 
 	return err;
 }
 
-static void tegra_dsi_debugfs_exit(struct tegra_dsi *dsi)
+static void tegra_dsi_early_unregister(struct drm_connector *connector)
 {
-	drm_debugfs_remove_files(dsi->debugfs_files, ARRAY_SIZE(debugfs_files),
-				 dsi->minor);
-	dsi->minor = NULL;
+	struct tegra_output *output = connector_to_output(connector);
+	unsigned int count = ARRAY_SIZE(debugfs_files);
+	struct tegra_dsi *dsi = to_dsi(output);
 
+	drm_debugfs_remove_files(dsi->debugfs_files, count,
+				 connector->dev->primary);
 	kfree(dsi->debugfs_files);
 	dsi->debugfs_files = NULL;
-
-	debugfs_remove(dsi->debugfs);
-	dsi->debugfs = NULL;
 }
 
 #define PKT_ID0(id)	((((id) & 0x3f) <<  3) | (1 <<  9))
@@ -823,6 +809,8 @@ static const struct drm_connector_funcs tegra_dsi_connector_funcs = {
 	.destroy = tegra_output_connector_destroy,
 	.atomic_duplicate_state = tegra_dsi_connector_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.late_register = tegra_dsi_late_register,
+	.early_unregister = tegra_dsi_early_unregister,
 };
 
 static enum drm_mode_status
@@ -1076,12 +1064,6 @@ static int tegra_dsi_init(struct host1x_client *client)
 		dsi->output.encoder.possible_crtcs = 0x3;
 	}
 
-	if (IS_ENABLED(CONFIG_DEBUG_FS)) {
-		err = tegra_dsi_debugfs_init(dsi, drm->primary);
-		if (err < 0)
-			dev_err(dsi->dev, "debugfs setup failed: %d\n", err);
-	}
-
 	return 0;
 }
 
@@ -1090,10 +1072,6 @@ static int tegra_dsi_exit(struct host1x_client *client)
 	struct tegra_dsi *dsi = host1x_client_to_dsi(client);
 
 	tegra_output_exit(&dsi->output);
-
-	if (IS_ENABLED(CONFIG_DEBUG_FS))
-		tegra_dsi_debugfs_exit(dsi);
-
 	regulator_disable(dsi->vdd);
 
 	return 0;
Signature · 1 line
2.15.0
#6 lore raw

PATCH 8/13 drm/tegra: hdmi: Register debugfs in ->late_register()

In reply to a message not in the archive

From: Thierry Reding <[email protected]>

The ->late_register() and ->early_unregister() callbacks are called at the right time to make sure userspace only accesses interfaces when it should. Move debugfs registration and unregistration to these callback functions to avoid potential races with userspace.

---
 drivers/gpu/drm/tegra/hdmi.c | 510 +++++++++++++++++++++----------------------
 1 file changed, 245 insertions(+), 265 deletions(-)
drivers/gpu/drm/tegra/hdmi.c +245 -265
index a68d80476e46..784739a9f497 100644
@@ -79,8 +79,6 @@ struct tegra_hdmi {
 	bool dvi;
 
 	struct drm_info_list *debugfs_files;
-	struct drm_minor *minor;
-	struct dentry *debugfs;
 };
 
 static inline struct tegra_hdmi *
@@ -910,6 +908,249 @@ tegra_hdmi_connector_detect(struct drm_connector *connector, bool force)
 	return status;
 }
 
+#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
+
+static const struct debugfs_reg32 tegra_hdmi_regs[] = {
+	DEBUGFS_REG32(HDMI_CTXSW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_STATE0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_STATE1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_STATE2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AN_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AN_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CN_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CN_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AKSV_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AKSV_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_BKSV_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_BKSV_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CKSV_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CKSV_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_DKSV_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_DKSV_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CMODE),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_MPRIME_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_MPRIME_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_SPRIME_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_RI),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CS_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CS_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU_RDATA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_STATUS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_STATUS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_STATUS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_HEADER),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_VSYNC_KEEPOUT),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_VSYNC_WINDOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GCP_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GCP_STATUS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GCP_SUBPACK),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_EMU0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_EMU1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_EMU1_RDATA),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_SPARE),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_HDCPRIF_ROM_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CAP),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PWR),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_TEST),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PLL0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PLL1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PLL2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CSTM),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_LVDS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CRCA),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CRCB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_BLANK),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_CTL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(0)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(1)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(2)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(3)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(4)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(5)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(6)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(7)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(8)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(9)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(10)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(11)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(12)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(13)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(14)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(15)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_VCRCA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_VCRCA1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CCRCA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CCRCA1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_EDATAA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_EDATAA1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_COUNTA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_COUNTA1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_DEBUGA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_DEBUGA1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_TRIG),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_MSCHECK),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_DEBUG0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_DEBUG1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_DEBUG2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(0)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(1)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(2)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(3)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(4)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(5)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(6)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_PULSE_WIDTH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_THRESHOLD),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_CNTRL0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_N),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDCPRIF_ROM_TIMING),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_REFCLK),
+	DEBUGFS_REG32(HDMI_NV_PDISP_CRC_CONTROL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_INPUT_CONTROL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SCRATCH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_PE_CURRENT),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_DEBUG0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_DEBUG1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_DEBUG2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_3),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_TRIG),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_SKEY_INDEX),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_CNTRL0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_SPARE0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE),
+	DEBUGFS_REG32(HDMI_NV_PDISP_INT_STATUS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_INT_MASK),
+	DEBUGFS_REG32(HDMI_NV_PDISP_INT_ENABLE),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT),
+};
+
+static int tegra_hdmi_show_regs(struct seq_file *s, void *data)
+{
+	struct drm_info_node *node = s->private;
+	struct tegra_hdmi *hdmi = node->info_ent->data;
+	struct drm_crtc *crtc = hdmi->output.encoder.crtc;
+	struct drm_device *drm = node->minor->dev;
+	unsigned int i;
+	int err = 0;
+
+	drm_modeset_lock_all(drm);
+
+	if (!crtc || !crtc->state->active) {
+		err = -EBUSY;
+		goto unlock;
+	}
+
+	for (i = 0; i < ARRAY_SIZE(tegra_hdmi_regs); i++) {
+		unsigned int offset = tegra_hdmi_regs[i].offset;
+
+		seq_printf(s, "%-56s %#05x %08x\n", tegra_hdmi_regs[i].name,
+			   offset, tegra_hdmi_readl(hdmi, offset));
+	}
+
+unlock:
+	drm_modeset_unlock_all(drm);
+	return err;
+}
+
+static struct drm_info_list debugfs_files[] = {
+	{ "regs", tegra_hdmi_show_regs, 0, NULL },
+};
+
+static int tegra_hdmi_late_register(struct drm_connector *connector)
+{
+	struct tegra_output *output = connector_to_output(connector);
+	unsigned int i, count = ARRAY_SIZE(debugfs_files);
+	struct drm_minor *minor = connector->dev->primary;
+	struct dentry *root = connector->debugfs_entry;
+	struct tegra_hdmi *hdmi = to_hdmi(output);
+	int err;
+
+	hdmi->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
+				      GFP_KERNEL);
+	if (!hdmi->debugfs_files)
+		return -ENOMEM;
+
+	for (i = 0; i < count; i++)
+		hdmi->debugfs_files[i].data = hdmi;
+
+	err = drm_debugfs_create_files(hdmi->debugfs_files, count, root, minor);
+	if (err < 0)
+		goto free;
+
+	return 0;
+
+free:
+	kfree(hdmi->debugfs_files);
+	hdmi->debugfs_files = NULL;
+
+	return err;
+}
+
+static void tegra_hdmi_early_unregister(struct drm_connector *connector)
+{
+	struct tegra_output *output = connector_to_output(connector);
+	struct drm_minor *minor = connector->dev->primary;
+	unsigned int count = ARRAY_SIZE(debugfs_files);
+	struct tegra_hdmi *hdmi = to_hdmi(output);
+
+	drm_debugfs_remove_files(hdmi->debugfs_files, count, minor);
+	kfree(hdmi->debugfs_files);
+	hdmi->debugfs_files = NULL;
+}
+
 static const struct drm_connector_funcs tegra_hdmi_connector_funcs = {
 	.reset = drm_atomic_helper_connector_reset,
 	.detect = tegra_hdmi_connector_detect,
@@ -917,6 +1158,8 @@ static const struct drm_connector_funcs tegra_hdmi_connector_funcs = {
 	.destroy = tegra_output_connector_destroy,
 	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.late_register = tegra_hdmi_late_register,
+	.early_unregister = tegra_hdmi_early_unregister,
 };
 
 static enum drm_mode_status
@@ -1225,260 +1468,6 @@ static const struct drm_encoder_helper_funcs tegra_hdmi_encoder_helper_funcs = {
 	.atomic_check = tegra_hdmi_encoder_atomic_check,
 };
 
-#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
-
-static const struct debugfs_reg32 tegra_hdmi_regs[] = {
-	DEBUGFS_REG32(HDMI_CTXSW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_STATE0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_STATE1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_STATE2),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AN_MSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AN_LSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CN_MSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CN_LSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AKSV_MSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AKSV_LSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_BKSV_MSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_BKSV_LSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CKSV_MSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CKSV_LSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_DKSV_MSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_DKSV_LSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CTRL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CMODE),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_MPRIME_MSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_MPRIME_LSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_SPRIME_MSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB2),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_RI),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CS_MSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CS_LSB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU_RDATA0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU2),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_STATUS),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_STATUS),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_CTRL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_STATUS),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_HEADER),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_CTRL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_LOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_HIGH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_CTRL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_VSYNC_KEEPOUT),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_VSYNC_WINDOW),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GCP_CTRL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GCP_STATUS),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GCP_SUBPACK),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS2),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_EMU0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_EMU1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_EMU1_RDATA),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_SPARE),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS2),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_HDCPRIF_ROM_CTRL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CAP),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PWR),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_TEST),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PLL0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PLL1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PLL2),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CSTM),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_LVDS),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CRCA),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CRCB),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_BLANK),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_CTL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(0)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(1)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(2)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(3)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(4)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(5)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(6)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(7)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(8)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(9)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(10)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(11)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(12)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(13)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(14)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(15)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_VCRCA0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_VCRCA1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CCRCA0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CCRCA1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_EDATAA0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_EDATAA1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_COUNTA0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_COUNTA1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_DEBUGA0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_DEBUGA1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_TRIG),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_MSCHECK),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_DEBUG0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_DEBUG1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_DEBUG2),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(0)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(1)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(2)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(3)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(4)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(5)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(6)),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_PULSE_WIDTH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_THRESHOLD),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_CNTRL0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_N),
-	DEBUGFS_REG32(HDMI_NV_PDISP_HDCPRIF_ROM_TIMING),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_REFCLK),
-	DEBUGFS_REG32(HDMI_NV_PDISP_CRC_CONTROL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_INPUT_CONTROL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SCRATCH),
-	DEBUGFS_REG32(HDMI_NV_PDISP_PE_CURRENT),
-	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_CTRL),
-	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_DEBUG0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_DEBUG1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_DEBUG2),
-	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_2),
-	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_3),
-	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_TRIG),
-	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_SKEY_INDEX),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_CNTRL0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_SPARE0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH1),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE),
-	DEBUGFS_REG32(HDMI_NV_PDISP_INT_STATUS),
-	DEBUGFS_REG32(HDMI_NV_PDISP_INT_MASK),
-	DEBUGFS_REG32(HDMI_NV_PDISP_INT_ENABLE),
-	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT),
-};
-
-static int tegra_hdmi_show_regs(struct seq_file *s, void *data)
-{
-	struct drm_info_node *node = s->private;
-	struct tegra_hdmi *hdmi = node->info_ent->data;
-	struct drm_crtc *crtc = hdmi->output.encoder.crtc;
-	struct drm_device *drm = node->minor->dev;
-	unsigned int i;
-	int err = 0;
-
-	drm_modeset_lock_all(drm);
-
-	if (!crtc || !crtc->state->active) {
-		err = -EBUSY;
-		goto unlock;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(tegra_hdmi_regs); i++) {
-		unsigned int offset = tegra_hdmi_regs[i].offset;
-
-		seq_printf(s, "%-56s %#05x %08x\n", tegra_hdmi_regs[i].name,
-			   offset, tegra_hdmi_readl(hdmi, offset));
-	}
-
-unlock:
-	drm_modeset_unlock_all(drm);
-	return err;
-}
-
-static struct drm_info_list debugfs_files[] = {
-	{ "regs", tegra_hdmi_show_regs, 0, NULL },
-};
-
-static int tegra_hdmi_debugfs_init(struct tegra_hdmi *hdmi,
-				   struct drm_minor *minor)
-{
-	unsigned int i;
-	int err;
-
-	hdmi->debugfs = debugfs_create_dir("hdmi", minor->debugfs_root);
-	if (!hdmi->debugfs)
-		return -ENOMEM;
-
-	hdmi->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
-				      GFP_KERNEL);
-	if (!hdmi->debugfs_files) {
-		err = -ENOMEM;
-		goto remove;
-	}
-
-	for (i = 0; i < ARRAY_SIZE(debugfs_files); i++)
-		hdmi->debugfs_files[i].data = hdmi;
-
-	err = drm_debugfs_create_files(hdmi->debugfs_files,
-				       ARRAY_SIZE(debugfs_files),
-				       hdmi->debugfs, minor);
-	if (err < 0)
-		goto free;
-
-	hdmi->minor = minor;
-
-	return 0;
-
-free:
-	kfree(hdmi->debugfs_files);
-	hdmi->debugfs_files = NULL;
-remove:
-	debugfs_remove(hdmi->debugfs);
-	hdmi->debugfs = NULL;
-
-	return err;
-}
-
-static void tegra_hdmi_debugfs_exit(struct tegra_hdmi *hdmi)
-{
-	drm_debugfs_remove_files(hdmi->debugfs_files, ARRAY_SIZE(debugfs_files),
-				 hdmi->minor);
-	hdmi->minor = NULL;
-
-	kfree(hdmi->debugfs_files);
-	hdmi->debugfs_files = NULL;
-
-	debugfs_remove(hdmi->debugfs);
-	hdmi->debugfs = NULL;
-}
-
 static int tegra_hdmi_init(struct host1x_client *client)
 {
 	struct drm_device *drm = dev_get_drvdata(client->parent);
@@ -1511,12 +1500,6 @@ static int tegra_hdmi_init(struct host1x_client *client)
 
 	hdmi->output.encoder.possible_crtcs = 0x3;
 
-	if (IS_ENABLED(CONFIG_DEBUG_FS)) {
-		err = tegra_hdmi_debugfs_init(hdmi, drm->primary);
-		if (err < 0)
-			dev_err(client->dev, "debugfs setup failed: %d\n", err);
-	}
-
 	err = regulator_enable(hdmi->hdmi);
 	if (err < 0) {
 		dev_err(client->dev, "failed to enable HDMI regulator: %d\n",
@@ -1549,9 +1532,6 @@ static int tegra_hdmi_exit(struct host1x_client *client)
 	regulator_disable(hdmi->pll);
 	regulator_disable(hdmi->hdmi);
 
-	if (IS_ENABLED(CONFIG_DEBUG_FS))
-		tegra_hdmi_debugfs_exit(hdmi);
-
 	return 0;
 }
 
Signature · 1 line
2.15.0
#7 lore raw

PATCH 9/13 drm/tegra: sor: Root debugfs files at the connector

In reply to a message not in the archive

From: Thierry Reding <[email protected]>

Rather create new files within the top-level DRM device's debugfs node, add the SOR specific files to the connector's debugfs node. This avoids the need to come up with subdirectory names and is also more intuitive.

---
 drivers/gpu/drm/tegra/sor.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)
drivers/gpu/drm/tegra/sor.c +6 -11
index 75b21dbaa8f0..f40fc987900c 100644
@@ -184,7 +184,6 @@ struct tegra_sor {
 
 	struct drm_info_list *debugfs_files;
 	struct drm_minor *minor;
-	struct dentry *debugfs;
 
 	const struct tegra_sor_ops *ops;
 
@@ -1260,14 +1259,10 @@ static const struct drm_info_list debugfs_files[] = {
 static int tegra_sor_debugfs_init(struct tegra_sor *sor,
 				  struct drm_minor *minor)
 {
-	const char *name = sor->soc->supports_dp ? "sor1" : "sor";
+	struct dentry *root = sor->output.connector.debugfs_entry;
 	unsigned int i;
 	int err;
 
-	sor->debugfs = debugfs_create_dir(name, minor->debugfs_root);
-	if (!sor->debugfs)
-		return -ENOMEM;
-
 	sor->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
 				     GFP_KERNEL);
 	if (!sor->debugfs_files) {
@@ -1280,7 +1275,7 @@ static int tegra_sor_debugfs_init(struct tegra_sor *sor,
 
 	err = drm_debugfs_create_files(sor->debugfs_files,
 				       ARRAY_SIZE(debugfs_files),
-				       sor->debugfs, minor);
+				       root, minor);
 	if (err < 0)
 		goto free;
 
@@ -1292,13 +1287,14 @@ static int tegra_sor_debugfs_init(struct tegra_sor *sor,
 	kfree(sor->debugfs_files);
 	sor->debugfs_files = NULL;
 remove:
-	debugfs_remove_recursive(sor->debugfs);
-	sor->debugfs = NULL;
+	debugfs_remove_recursive(root);
 	return err;
 }
 
 static void tegra_sor_debugfs_exit(struct tegra_sor *sor)
 {
+	struct dentry *root = sor->output.connector.debugfs_entry;
+
 	drm_debugfs_remove_files(sor->debugfs_files, ARRAY_SIZE(debugfs_files),
 				 sor->minor);
 	sor->minor = NULL;
@@ -1306,8 +1302,7 @@ static void tegra_sor_debugfs_exit(struct tegra_sor *sor)
 	kfree(sor->debugfs_files);
 	sor->debugfs_files = NULL;
 
-	debugfs_remove_recursive(sor->debugfs);
-	sor->debugfs = NULL;
+	debugfs_remove_recursive(root);
 }
 
 static void tegra_sor_connector_reset(struct drm_connector *connector)
Signature · 1 line
2.15.0
#8 lore raw

PATCH 10/13 drm/tegra: sor: Register debugfs in ->late_register()

In reply to a message not in the archive

From: Thierry Reding <[email protected]>

The ->late_register() and ->early_unregister() callbacks are called at the right time to make sure userspace only accesses interfaces when it should. Move debugfs registration and unregistration to these callback functions to avoid potential races with userspace.

---
 drivers/gpu/drm/tegra/sor.c | 53 ++++++++++++++++-----------------------------
 1 file changed, 19 insertions(+), 34 deletions(-)
drivers/gpu/drm/tegra/sor.c +19 -34
index f40fc987900c..2fba6c2bd486 100644
@@ -183,7 +183,6 @@ struct tegra_sor {
 	struct drm_dp_aux *aux;
 
 	struct drm_info_list *debugfs_files;
-	struct drm_minor *minor;
 
 	const struct tegra_sor_ops *ops;
 
@@ -1256,53 +1255,46 @@ static const struct drm_info_list debugfs_files[] = {
 	{ "regs", tegra_sor_show_regs, 0, NULL },
 };
 
-static int tegra_sor_debugfs_init(struct tegra_sor *sor,
-				  struct drm_minor *minor)
+static int tegra_sor_late_register(struct drm_connector *connector)
 {
-	struct dentry *root = sor->output.connector.debugfs_entry;
-	unsigned int i;
+	struct tegra_output *output = connector_to_output(connector);
+	unsigned int i, count = ARRAY_SIZE(debugfs_files);
+	struct drm_minor *minor = connector->dev->primary;
+	struct dentry *root = connector->debugfs_entry;
+	struct tegra_sor *sor = to_sor(output);
 	int err;
 
 	sor->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
 				     GFP_KERNEL);
-	if (!sor->debugfs_files) {
-		err = -ENOMEM;
-		goto remove;
-	}
+	if (!sor->debugfs_files)
+		return -ENOMEM;
 
-	for (i = 0; i < ARRAY_SIZE(debugfs_files); i++)
+	for (i = 0; i < count; i++)
 		sor->debugfs_files[i].data = sor;
 
-	err = drm_debugfs_create_files(sor->debugfs_files,
-				       ARRAY_SIZE(debugfs_files),
-				       root, minor);
+	err = drm_debugfs_create_files(sor->debugfs_files, count, root, minor);
 	if (err < 0)
 		goto free;
 
-	sor->minor = minor;
-
 	return 0;
 
 free:
 	kfree(sor->debugfs_files);
 	sor->debugfs_files = NULL;
-remove:
-	debugfs_remove_recursive(root);
+
 	return err;
 }
 
-static void tegra_sor_debugfs_exit(struct tegra_sor *sor)
+static void tegra_sor_early_unregister(struct drm_connector *connector)
 {
-	struct dentry *root = sor->output.connector.debugfs_entry;
-
-	drm_debugfs_remove_files(sor->debugfs_files, ARRAY_SIZE(debugfs_files),
-				 sor->minor);
-	sor->minor = NULL;
+	struct tegra_output *output = connector_to_output(connector);
+	unsigned int count = ARRAY_SIZE(debugfs_files);
+	struct tegra_sor *sor = to_sor(output);
 
+	drm_debugfs_remove_files(sor->debugfs_files, count,
+				 connector->dev->primary);
 	kfree(sor->debugfs_files);
 	sor->debugfs_files = NULL;
-
-	debugfs_remove_recursive(root);
 }
 
 static void tegra_sor_connector_reset(struct drm_connector *connector)
@@ -1355,6 +1347,8 @@ static const struct drm_connector_funcs tegra_sor_connector_funcs = {
 	.destroy = tegra_output_connector_destroy,
 	.atomic_duplicate_state = tegra_sor_connector_duplicate_state,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+	.late_register = tegra_sor_late_register,
+	.early_unregister = tegra_sor_early_unregister,
 };
 
 static int tegra_sor_connector_get_modes(struct drm_connector *connector)
@@ -2347,12 +2341,6 @@ static int tegra_sor_init(struct host1x_client *client)
 
 	sor->output.encoder.possible_crtcs = 0x3;
 
-	if (IS_ENABLED(CONFIG_DEBUG_FS)) {
-		err = tegra_sor_debugfs_init(sor, drm->primary);
-		if (err < 0)
-			dev_err(sor->dev, "debugfs setup failed: %d\n", err);
-	}
-
 	if (sor->aux) {
 		err = drm_dp_aux_attach(sor->aux, &sor->output);
 		if (err < 0) {
@@ -2421,9 +2409,6 @@ static int tegra_sor_exit(struct host1x_client *client)
 	clk_disable_unprepare(sor->clk_dp);
 	clk_disable_unprepare(sor->clk);
 
-	if (IS_ENABLED(CONFIG_DEBUG_FS))
-		tegra_sor_debugfs_exit(sor);
-
 	return 0;
 }
 
Signature · 1 line
2.15.0
#9 lore raw

PATCH 11/13 drm/tegra: Do not wrap lines unnecessarily

In reply to a message not in the archive

From: Thierry Reding <[email protected]>

The tegra_drm_alloc() function signature fits on a single line, no need to wrap it.

---
 drivers/gpu/drm/tegra/drm.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/gpu/drm/tegra/drm.c +1 -2
index 52552b9b89ef..de1d122ba820 100644
@@ -1148,8 +1148,7 @@ int tegra_drm_unregister_client(struct tegra_drm *tegra,
 	return 0;
 }
 
-void *tegra_drm_alloc(struct tegra_drm *tegra, size_t size,
-			      dma_addr_t *dma)
+void *tegra_drm_alloc(struct tegra_drm *tegra, size_t size, dma_addr_t *dma)
 {
 	struct iova *alloc;
 	void *virt;
Signature · 1 line
2.15.0
#10 lore raw

PATCH 12/13 drm/tegra: vic: Properly align arguments

In reply to a message not in the archive

From: Thierry Reding <[email protected]>

Properly align function arguments on subsequent lines with the first argument on the first line.

---
 drivers/gpu/drm/tegra/vic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/tegra/vic.c +1 -1
index 18024183aa2b..d9664a34fb43 100644
@@ -115,7 +115,7 @@ static int vic_boot(struct vic *vic)
 }
 
 static void *vic_falcon_alloc(struct falcon *falcon, size_t size,
-			       dma_addr_t *iova)
+			      dma_addr_t *iova)
 {
 	struct tegra_drm *tegra = falcon->data;
 
Signature · 1 line
2.15.0
#11 lore raw

PATCH 13/13 drm/tegra: dc: Support background color

In reply to a message not in the archive

From: Thierry Reding <[email protected]>

Starting with Tegra124, the interface to set the background color (the value generated for pixels that are not sourced from any window) is via a different register. Earlier generations called this the border color. Reverse the feature flag and assume that IP revisions that don't have support for background color will support border color instead.

---
 drivers/gpu/drm/tegra/dc.c | 14 ++++++++------
 drivers/gpu/drm/tegra/dc.h |  8 +++++++-
 2 files changed, 15 insertions(+), 7 deletions(-)
drivers/gpu/drm/tegra/dc.c +8 -6
index 69d98bf84ceb..954bf92f21fd 100644
@@ -1572,7 +1572,9 @@ static void tegra_crtc_atomic_enable(struct drm_crtc *crtc,
 		WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
 	tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
 
-	if (dc->soc->supports_border_color)
+	if (dc->soc->supports_background_color)
+		tegra_dc_writel(dc, 0, DC_DISP_BLEND_BACKGROUND_COLOR);
+	else
 		tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR);
 
 	/* apply PLL and pixel clock changes */
@@ -1835,7 +1837,7 @@ static const struct host1x_client_ops dc_client_ops = {
 };
 
 static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
-	.supports_border_color = true,
+	.supports_background_color = false,
 	.supports_interlacing = false,
 	.supports_cursor = false,
 	.supports_block_linear = false,
@@ -1845,7 +1847,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
 };
 
 static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
-	.supports_border_color = true,
+	.supports_background_color = false,
 	.supports_interlacing = false,
 	.supports_cursor = false,
 	.supports_block_linear = false,
@@ -1855,7 +1857,7 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
 };
 
 static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
-	.supports_border_color = true,
+	.supports_background_color = false,
 	.supports_interlacing = false,
 	.supports_cursor = false,
 	.supports_block_linear = false,
@@ -1865,7 +1867,7 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
 };
 
 static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
-	.supports_border_color = false,
+	.supports_background_color = true,
 	.supports_interlacing = true,
 	.supports_cursor = true,
 	.supports_block_linear = true,
@@ -1875,7 +1877,7 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
 };
 
 static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
-	.supports_border_color = false,
+	.supports_background_color = true,
 	.supports_interlacing = true,
 	.supports_cursor = true,
 	.supports_block_linear = true,
drivers/gpu/drm/tegra/dc.h +7 -1
index 032c734dd470..571a6c78619f 100644
@@ -26,7 +26,7 @@ struct tegra_dc_stats {
 };
 
 struct tegra_dc_soc_info {
-	bool supports_border_color;
+	bool supports_background_color;
 	bool supports_interlacing;
 	bool supports_cursor;
 	bool supports_block_linear;
@@ -447,6 +447,12 @@ int tegra_dc_rgb_exit(struct tegra_dc *dc);
 #define DC_DISP_SD_HW_K_VALUES			0x4dd
 #define DC_DISP_SD_MAN_K_VALUES			0x4de
 
+#define DC_DISP_BLEND_BACKGROUND_COLOR		0x4e4
+#define  BACKGROUND_COLOR_ALPHA(x) (((x) & 0xff) << 24)
+#define  BACKGROUND_COLOR_BLUE(x)  (((x) & 0xff) << 16)
+#define  BACKGROUND_COLOR_GREEN(x) (((x) & 0xff) << 8)
+#define  BACKGROUND_COLOR_RED(x)   (((x) & 0xff) << 0)
+
 #define DC_DISP_INTERLACE_CONTROL		0x4e5
 #define  INTERLACE_STATUS (1 << 2)
 #define  INTERLACE_START  (1 << 1)
Signature · 1 line
2.15.0
#12 lore raw

PATCH 3/13 drm/tegra: hdmi: Move register definitions into a table

In reply to Thierry Reding

From: Thierry Reding <[email protected]>

After commit 07a8aab89927 ("drm/tegra: hdmi: Trace register accesses"), the debugfs register dump implementation causes excessive stack usage and can result in build warnings. To fix this, move the register definitions into a table and iterate over the table while dumping the registers to debugfs.

---
 drivers/gpu/drm/tegra/hdmi.c | 346 ++++++++++++++++++++++---------------------
 1 file changed, 176 insertions(+), 170 deletions(-)
drivers/gpu/drm/tegra/hdmi.c +176 -170
index 6434b3d3d1ba..a68d80476e46 100644
@@ -1225,12 +1225,182 @@ static const struct drm_encoder_helper_funcs tegra_hdmi_encoder_helper_funcs = {
 	.atomic_check = tegra_hdmi_encoder_atomic_check,
 };
 
+#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
+
+static const struct debugfs_reg32 tegra_hdmi_regs[] = {
+	DEBUGFS_REG32(HDMI_CTXSW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_STATE0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_STATE1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_STATE2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AN_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AN_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CN_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CN_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AKSV_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_AKSV_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_BKSV_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_BKSV_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CKSV_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CKSV_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_DKSV_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_DKSV_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CMODE),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_MPRIME_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_MPRIME_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_SPRIME_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_RI),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CS_MSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_RG_HDCP_CS_LSB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU_RDATA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_EMU2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_STATUS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_STATUS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_STATUS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_HEADER),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_LOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_HIGH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_VSYNC_KEEPOUT),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_VSYNC_WINDOW),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GCP_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GCP_STATUS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_GCP_SUBPACK),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_EMU0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_EMU1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_EMU1_RDATA),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_SPARE),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDMI_HDCPRIF_ROM_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CAP),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PWR),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_TEST),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PLL0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PLL1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_PLL2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CSTM),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_LVDS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CRCA),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CRCB),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_BLANK),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_CTL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(0)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(1)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(2)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(3)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(4)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(5)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(6)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(7)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(8)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(9)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(10)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(11)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(12)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(13)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(14)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_SEQ_INST(15)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_VCRCA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_VCRCA1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CCRCA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_CCRCA1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_EDATAA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_EDATAA1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_COUNTA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_COUNTA1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_DEBUGA0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_DEBUGA1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_TRIG),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_MSCHECK),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_DEBUG0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_DEBUG1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_DEBUG2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(0)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(1)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(2)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(3)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(4)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(5)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_FS(6)),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_PULSE_WIDTH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_THRESHOLD),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_CNTRL0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_AUDIO_N),
+	DEBUGFS_REG32(HDMI_NV_PDISP_HDCPRIF_ROM_TIMING),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_REFCLK),
+	DEBUGFS_REG32(HDMI_NV_PDISP_CRC_CONTROL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_INPUT_CONTROL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SCRATCH),
+	DEBUGFS_REG32(HDMI_NV_PDISP_PE_CURRENT),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_CTRL),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_DEBUG0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_DEBUG1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_DEBUG2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_2),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_3),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_HDCP_KEY_TRIG),
+	DEBUGFS_REG32(HDMI_NV_PDISP_KEY_SKEY_INDEX),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_CNTRL0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_SPARE0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH1),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE),
+	DEBUGFS_REG32(HDMI_NV_PDISP_INT_STATUS),
+	DEBUGFS_REG32(HDMI_NV_PDISP_INT_MASK),
+	DEBUGFS_REG32(HDMI_NV_PDISP_INT_ENABLE),
+	DEBUGFS_REG32(HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT),
+};
+
 static int tegra_hdmi_show_regs(struct seq_file *s, void *data)
 {
 	struct drm_info_node *node = s->private;
 	struct tegra_hdmi *hdmi = node->info_ent->data;
 	struct drm_crtc *crtc = hdmi->output.encoder.crtc;
 	struct drm_device *drm = node->minor->dev;
+	unsigned int i;
 	int err = 0;
 
 	drm_modeset_lock_all(drm);
@@ -1240,176 +1410,12 @@ static int tegra_hdmi_show_regs(struct seq_file *s, void *data)
 		goto unlock;
 	}
 
-#define DUMP_REG(name)						\
-	seq_printf(s, "%-56s %#05x %08x\n", #name, name,	\
-		   tegra_hdmi_readl(hdmi, name))
-
-	DUMP_REG(HDMI_CTXSW);
-	DUMP_REG(HDMI_NV_PDISP_SOR_STATE0);
-	DUMP_REG(HDMI_NV_PDISP_SOR_STATE1);
-	DUMP_REG(HDMI_NV_PDISP_SOR_STATE2);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AN_MSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AN_LSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CN_MSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CN_LSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AKSV_MSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_AKSV_LSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_BKSV_MSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_BKSV_LSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CKSV_MSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CKSV_LSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_DKSV_MSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_DKSV_LSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CTRL);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CMODE);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_MPRIME_MSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_MPRIME_LSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_SPRIME_MSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB2);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_SPRIME_LSB1);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_RI);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CS_MSB);
-	DUMP_REG(HDMI_NV_PDISP_RG_HDCP_CS_LSB);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU0);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU_RDATA0);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU1);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_EMU2);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_CTRL);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_STATUS);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_HEADER);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AUDIO_INFOFRAME_SUBPACK0_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_CTRL);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_STATUS);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_HEADER);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK0_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_AVI_INFOFRAME_SUBPACK1_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_CTRL);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_STATUS);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_HEADER);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK0_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK1_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK2_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GENERIC_SUBPACK3_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_CTRL);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0320_SUBPACK_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0441_SUBPACK_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0882_SUBPACK_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1764_SUBPACK_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0480_SUBPACK_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_0960_SUBPACK_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_LOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_ACR_1920_SUBPACK_HIGH);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_CTRL);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_VSYNC_KEEPOUT);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_VSYNC_WINDOW);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GCP_CTRL);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GCP_STATUS);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_GCP_SUBPACK);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS1);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_CHANNEL_STATUS2);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_EMU0);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_EMU1);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_EMU1_RDATA);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_SPARE);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS1);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_SPDIF_CHN_STATUS2);
-	DUMP_REG(HDMI_NV_PDISP_HDMI_HDCPRIF_ROM_CTRL);
-	DUMP_REG(HDMI_NV_PDISP_SOR_CAP);
-	DUMP_REG(HDMI_NV_PDISP_SOR_PWR);
-	DUMP_REG(HDMI_NV_PDISP_SOR_TEST);
-	DUMP_REG(HDMI_NV_PDISP_SOR_PLL0);
-	DUMP_REG(HDMI_NV_PDISP_SOR_PLL1);
-	DUMP_REG(HDMI_NV_PDISP_SOR_PLL2);
-	DUMP_REG(HDMI_NV_PDISP_SOR_CSTM);
-	DUMP_REG(HDMI_NV_PDISP_SOR_LVDS);
-	DUMP_REG(HDMI_NV_PDISP_SOR_CRCA);
-	DUMP_REG(HDMI_NV_PDISP_SOR_CRCB);
-	DUMP_REG(HDMI_NV_PDISP_SOR_BLANK);
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_CTL);
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(0));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(1));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(2));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(3));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(4));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(5));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(6));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(7));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(8));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(9));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(10));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(11));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(12));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(13));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(14));
-	DUMP_REG(HDMI_NV_PDISP_SOR_SEQ_INST(15));
-	DUMP_REG(HDMI_NV_PDISP_SOR_VCRCA0);
-	DUMP_REG(HDMI_NV_PDISP_SOR_VCRCA1);
-	DUMP_REG(HDMI_NV_PDISP_SOR_CCRCA0);
-	DUMP_REG(HDMI_NV_PDISP_SOR_CCRCA1);
-	DUMP_REG(HDMI_NV_PDISP_SOR_EDATAA0);
-	DUMP_REG(HDMI_NV_PDISP_SOR_EDATAA1);
-	DUMP_REG(HDMI_NV_PDISP_SOR_COUNTA0);
-	DUMP_REG(HDMI_NV_PDISP_SOR_COUNTA1);
-	DUMP_REG(HDMI_NV_PDISP_SOR_DEBUGA0);
-	DUMP_REG(HDMI_NV_PDISP_SOR_DEBUGA1);
-	DUMP_REG(HDMI_NV_PDISP_SOR_TRIG);
-	DUMP_REG(HDMI_NV_PDISP_SOR_MSCHECK);
-	DUMP_REG(HDMI_NV_PDISP_SOR_LANE_DRIVE_CURRENT);
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG0);
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG1);
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_DEBUG2);
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(0));
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(1));
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(2));
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(3));
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(4));
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(5));
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_FS(6));
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_PULSE_WIDTH);
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_THRESHOLD);
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_CNTRL0);
-	DUMP_REG(HDMI_NV_PDISP_AUDIO_N);
-	DUMP_REG(HDMI_NV_PDISP_HDCPRIF_ROM_TIMING);
-	DUMP_REG(HDMI_NV_PDISP_SOR_REFCLK);
-	DUMP_REG(HDMI_NV_PDISP_CRC_CONTROL);
-	DUMP_REG(HDMI_NV_PDISP_INPUT_CONTROL);
-	DUMP_REG(HDMI_NV_PDISP_SCRATCH);
-	DUMP_REG(HDMI_NV_PDISP_PE_CURRENT);
-	DUMP_REG(HDMI_NV_PDISP_KEY_CTRL);
-	DUMP_REG(HDMI_NV_PDISP_KEY_DEBUG0);
-	DUMP_REG(HDMI_NV_PDISP_KEY_DEBUG1);
-	DUMP_REG(HDMI_NV_PDISP_KEY_DEBUG2);
-	DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_0);
-	DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_1);
-	DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_2);
-	DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_3);
-	DUMP_REG(HDMI_NV_PDISP_KEY_HDCP_KEY_TRIG);
-	DUMP_REG(HDMI_NV_PDISP_KEY_SKEY_INDEX);
-	DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_CNTRL0);
-	DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_SPARE0);
-	DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH0);
-	DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_CODEC_SCRATCH1);
-	DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_ELD_BUFWR);
-	DUMP_REG(HDMI_NV_PDISP_SOR_AUDIO_HDA_PRESENSE);
-	DUMP_REG(HDMI_NV_PDISP_INT_STATUS);
-	DUMP_REG(HDMI_NV_PDISP_INT_MASK);
-	DUMP_REG(HDMI_NV_PDISP_INT_ENABLE);
-	DUMP_REG(HDMI_NV_PDISP_SOR_IO_PEAK_CURRENT);
-
-#undef DUMP_REG
+	for (i = 0; i < ARRAY_SIZE(tegra_hdmi_regs); i++) {
+		unsigned int offset = tegra_hdmi_regs[i].offset;
+
+		seq_printf(s, "%-56s %#05x %08x\n", tegra_hdmi_regs[i].name,
+			   offset, tegra_hdmi_readl(hdmi, offset));
+	}
 
 unlock:
 	drm_modeset_unlock_all(drm);
Signature · 6 lines
2.15.0

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
#13 lore raw

PATCH 4/13 drm/tegra: sor: Move register definitions into a table

In reply to Thierry Reding

From: Thierry Reding <[email protected]>

After commit 932f6529139e ("drm/tegra: sor: Trace register accesses"), the debugfs register dump implementation causes excessive stack usage and can result in build warnings. To fix this, move the register definitions into a table and iterate over the table while dumping the registers to debugfs.

---
 drivers/gpu/drm/tegra/sor.c | 246 +++++++++++++++++++++++---------------------
 1 file changed, 126 insertions(+), 120 deletions(-)
drivers/gpu/drm/tegra/sor.c +126 -120
index b0a1dedac802..75b21dbaa8f0 100644
@@ -1105,12 +1105,132 @@ static int tegra_sor_show_crc(struct seq_file *s, void *data)
 	return err;
 }
 
+#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }
+
+static const struct debugfs_reg32 tegra_sor_regs[] = {
+	DEBUGFS_REG32(SOR_CTXSW),
+	DEBUGFS_REG32(SOR_SUPER_STATE0),
+	DEBUGFS_REG32(SOR_SUPER_STATE1),
+	DEBUGFS_REG32(SOR_STATE0),
+	DEBUGFS_REG32(SOR_STATE1),
+	DEBUGFS_REG32(SOR_HEAD_STATE0(0)),
+	DEBUGFS_REG32(SOR_HEAD_STATE0(1)),
+	DEBUGFS_REG32(SOR_HEAD_STATE1(0)),
+	DEBUGFS_REG32(SOR_HEAD_STATE1(1)),
+	DEBUGFS_REG32(SOR_HEAD_STATE2(0)),
+	DEBUGFS_REG32(SOR_HEAD_STATE2(1)),
+	DEBUGFS_REG32(SOR_HEAD_STATE3(0)),
+	DEBUGFS_REG32(SOR_HEAD_STATE3(1)),
+	DEBUGFS_REG32(SOR_HEAD_STATE4(0)),
+	DEBUGFS_REG32(SOR_HEAD_STATE4(1)),
+	DEBUGFS_REG32(SOR_HEAD_STATE5(0)),
+	DEBUGFS_REG32(SOR_HEAD_STATE5(1)),
+	DEBUGFS_REG32(SOR_CRC_CNTRL),
+	DEBUGFS_REG32(SOR_DP_DEBUG_MVID),
+	DEBUGFS_REG32(SOR_CLK_CNTRL),
+	DEBUGFS_REG32(SOR_CAP),
+	DEBUGFS_REG32(SOR_PWR),
+	DEBUGFS_REG32(SOR_TEST),
+	DEBUGFS_REG32(SOR_PLL0),
+	DEBUGFS_REG32(SOR_PLL1),
+	DEBUGFS_REG32(SOR_PLL2),
+	DEBUGFS_REG32(SOR_PLL3),
+	DEBUGFS_REG32(SOR_CSTM),
+	DEBUGFS_REG32(SOR_LVDS),
+	DEBUGFS_REG32(SOR_CRCA),
+	DEBUGFS_REG32(SOR_CRCB),
+	DEBUGFS_REG32(SOR_BLANK),
+	DEBUGFS_REG32(SOR_SEQ_CTL),
+	DEBUGFS_REG32(SOR_LANE_SEQ_CTL),
+	DEBUGFS_REG32(SOR_SEQ_INST(0)),
+	DEBUGFS_REG32(SOR_SEQ_INST(1)),
+	DEBUGFS_REG32(SOR_SEQ_INST(2)),
+	DEBUGFS_REG32(SOR_SEQ_INST(3)),
+	DEBUGFS_REG32(SOR_SEQ_INST(4)),
+	DEBUGFS_REG32(SOR_SEQ_INST(5)),
+	DEBUGFS_REG32(SOR_SEQ_INST(6)),
+	DEBUGFS_REG32(SOR_SEQ_INST(7)),
+	DEBUGFS_REG32(SOR_SEQ_INST(8)),
+	DEBUGFS_REG32(SOR_SEQ_INST(9)),
+	DEBUGFS_REG32(SOR_SEQ_INST(10)),
+	DEBUGFS_REG32(SOR_SEQ_INST(11)),
+	DEBUGFS_REG32(SOR_SEQ_INST(12)),
+	DEBUGFS_REG32(SOR_SEQ_INST(13)),
+	DEBUGFS_REG32(SOR_SEQ_INST(14)),
+	DEBUGFS_REG32(SOR_SEQ_INST(15)),
+	DEBUGFS_REG32(SOR_PWM_DIV),
+	DEBUGFS_REG32(SOR_PWM_CTL),
+	DEBUGFS_REG32(SOR_VCRC_A0),
+	DEBUGFS_REG32(SOR_VCRC_A1),
+	DEBUGFS_REG32(SOR_VCRC_B0),
+	DEBUGFS_REG32(SOR_VCRC_B1),
+	DEBUGFS_REG32(SOR_CCRC_A0),
+	DEBUGFS_REG32(SOR_CCRC_A1),
+	DEBUGFS_REG32(SOR_CCRC_B0),
+	DEBUGFS_REG32(SOR_CCRC_B1),
+	DEBUGFS_REG32(SOR_EDATA_A0),
+	DEBUGFS_REG32(SOR_EDATA_A1),
+	DEBUGFS_REG32(SOR_EDATA_B0),
+	DEBUGFS_REG32(SOR_EDATA_B1),
+	DEBUGFS_REG32(SOR_COUNT_A0),
+	DEBUGFS_REG32(SOR_COUNT_A1),
+	DEBUGFS_REG32(SOR_COUNT_B0),
+	DEBUGFS_REG32(SOR_COUNT_B1),
+	DEBUGFS_REG32(SOR_DEBUG_A0),
+	DEBUGFS_REG32(SOR_DEBUG_A1),
+	DEBUGFS_REG32(SOR_DEBUG_B0),
+	DEBUGFS_REG32(SOR_DEBUG_B1),
+	DEBUGFS_REG32(SOR_TRIG),
+	DEBUGFS_REG32(SOR_MSCHECK),
+	DEBUGFS_REG32(SOR_XBAR_CTRL),
+	DEBUGFS_REG32(SOR_XBAR_POL),
+	DEBUGFS_REG32(SOR_DP_LINKCTL0),
+	DEBUGFS_REG32(SOR_DP_LINKCTL1),
+	DEBUGFS_REG32(SOR_LANE_DRIVE_CURRENT0),
+	DEBUGFS_REG32(SOR_LANE_DRIVE_CURRENT1),
+	DEBUGFS_REG32(SOR_LANE4_DRIVE_CURRENT0),
+	DEBUGFS_REG32(SOR_LANE4_DRIVE_CURRENT1),
+	DEBUGFS_REG32(SOR_LANE_PREEMPHASIS0),
+	DEBUGFS_REG32(SOR_LANE_PREEMPHASIS1),
+	DEBUGFS_REG32(SOR_LANE4_PREEMPHASIS0),
+	DEBUGFS_REG32(SOR_LANE4_PREEMPHASIS1),
+	DEBUGFS_REG32(SOR_LANE_POSTCURSOR0),
+	DEBUGFS_REG32(SOR_LANE_POSTCURSOR1),
+	DEBUGFS_REG32(SOR_DP_CONFIG0),
+	DEBUGFS_REG32(SOR_DP_CONFIG1),
+	DEBUGFS_REG32(SOR_DP_MN0),
+	DEBUGFS_REG32(SOR_DP_MN1),
+	DEBUGFS_REG32(SOR_DP_PADCTL0),
+	DEBUGFS_REG32(SOR_DP_PADCTL1),
+	DEBUGFS_REG32(SOR_DP_DEBUG0),
+	DEBUGFS_REG32(SOR_DP_DEBUG1),
+	DEBUGFS_REG32(SOR_DP_SPARE0),
+	DEBUGFS_REG32(SOR_DP_SPARE1),
+	DEBUGFS_REG32(SOR_DP_AUDIO_CTRL),
+	DEBUGFS_REG32(SOR_DP_AUDIO_HBLANK_SYMBOLS),
+	DEBUGFS_REG32(SOR_DP_AUDIO_VBLANK_SYMBOLS),
+	DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_HEADER),
+	DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK0),
+	DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK1),
+	DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK2),
+	DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK3),
+	DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK4),
+	DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK5),
+	DEBUGFS_REG32(SOR_DP_GENERIC_INFOFRAME_SUBPACK6),
+	DEBUGFS_REG32(SOR_DP_TPG),
+	DEBUGFS_REG32(SOR_DP_TPG_CONFIG),
+	DEBUGFS_REG32(SOR_DP_LQ_CSTM0),
+	DEBUGFS_REG32(SOR_DP_LQ_CSTM1),
+	DEBUGFS_REG32(SOR_DP_LQ_CSTM2),
+};
+
 static int tegra_sor_show_regs(struct seq_file *s, void *data)
 {
 	struct drm_info_node *node = s->private;
 	struct tegra_sor *sor = node->info_ent->data;
 	struct drm_crtc *crtc = sor->output.encoder.crtc;
 	struct drm_device *drm = node->minor->dev;
+	unsigned int i;
 	int err = 0;
 
 	drm_modeset_lock_all(drm);
@@ -1120,126 +1240,12 @@ static int tegra_sor_show_regs(struct seq_file *s, void *data)
 		goto unlock;
 	}
 
-#define DUMP_REG(name)						\
-	seq_printf(s, "%-38s %#05x %08x\n", #name, name,	\
-		   tegra_sor_readl(sor, name))
-
-	DUMP_REG(SOR_CTXSW);
-	DUMP_REG(SOR_SUPER_STATE0);
-	DUMP_REG(SOR_SUPER_STATE1);
-	DUMP_REG(SOR_STATE0);
-	DUMP_REG(SOR_STATE1);
-	DUMP_REG(SOR_HEAD_STATE0(0));
-	DUMP_REG(SOR_HEAD_STATE0(1));
-	DUMP_REG(SOR_HEAD_STATE1(0));
-	DUMP_REG(SOR_HEAD_STATE1(1));
-	DUMP_REG(SOR_HEAD_STATE2(0));
-	DUMP_REG(SOR_HEAD_STATE2(1));
-	DUMP_REG(SOR_HEAD_STATE3(0));
-	DUMP_REG(SOR_HEAD_STATE3(1));
-	DUMP_REG(SOR_HEAD_STATE4(0));
-	DUMP_REG(SOR_HEAD_STATE4(1));
-	DUMP_REG(SOR_HEAD_STATE5(0));
-	DUMP_REG(SOR_HEAD_STATE5(1));
-	DUMP_REG(SOR_CRC_CNTRL);
-	DUMP_REG(SOR_DP_DEBUG_MVID);
-	DUMP_REG(SOR_CLK_CNTRL);
-	DUMP_REG(SOR_CAP);
-	DUMP_REG(SOR_PWR);
-	DUMP_REG(SOR_TEST);
-	DUMP_REG(SOR_PLL0);
-	DUMP_REG(SOR_PLL1);
-	DUMP_REG(SOR_PLL2);
-	DUMP_REG(SOR_PLL3);
-	DUMP_REG(SOR_CSTM);
-	DUMP_REG(SOR_LVDS);
-	DUMP_REG(SOR_CRCA);
-	DUMP_REG(SOR_CRCB);
-	DUMP_REG(SOR_BLANK);
-	DUMP_REG(SOR_SEQ_CTL);
-	DUMP_REG(SOR_LANE_SEQ_CTL);
-	DUMP_REG(SOR_SEQ_INST(0));
-	DUMP_REG(SOR_SEQ_INST(1));
-	DUMP_REG(SOR_SEQ_INST(2));
-	DUMP_REG(SOR_SEQ_INST(3));
-	DUMP_REG(SOR_SEQ_INST(4));
-	DUMP_REG(SOR_SEQ_INST(5));
-	DUMP_REG(SOR_SEQ_INST(6));
-	DUMP_REG(SOR_SEQ_INST(7));
-	DUMP_REG(SOR_SEQ_INST(8));
-	DUMP_REG(SOR_SEQ_INST(9));
-	DUMP_REG(SOR_SEQ_INST(10));
-	DUMP_REG(SOR_SEQ_INST(11));
-	DUMP_REG(SOR_SEQ_INST(12));
-	DUMP_REG(SOR_SEQ_INST(13));
-	DUMP_REG(SOR_SEQ_INST(14));
-	DUMP_REG(SOR_SEQ_INST(15));
-	DUMP_REG(SOR_PWM_DIV);
-	DUMP_REG(SOR_PWM_CTL);
-	DUMP_REG(SOR_VCRC_A0);
-	DUMP_REG(SOR_VCRC_A1);
-	DUMP_REG(SOR_VCRC_B0);
-	DUMP_REG(SOR_VCRC_B1);
-	DUMP_REG(SOR_CCRC_A0);
-	DUMP_REG(SOR_CCRC_A1);
-	DUMP_REG(SOR_CCRC_B0);
-	DUMP_REG(SOR_CCRC_B1);
-	DUMP_REG(SOR_EDATA_A0);
-	DUMP_REG(SOR_EDATA_A1);
-	DUMP_REG(SOR_EDATA_B0);
-	DUMP_REG(SOR_EDATA_B1);
-	DUMP_REG(SOR_COUNT_A0);
-	DUMP_REG(SOR_COUNT_A1);
-	DUMP_REG(SOR_COUNT_B0);
-	DUMP_REG(SOR_COUNT_B1);
-	DUMP_REG(SOR_DEBUG_A0);
-	DUMP_REG(SOR_DEBUG_A1);
-	DUMP_REG(SOR_DEBUG_B0);
-	DUMP_REG(SOR_DEBUG_B1);
-	DUMP_REG(SOR_TRIG);
-	DUMP_REG(SOR_MSCHECK);
-	DUMP_REG(SOR_XBAR_CTRL);
-	DUMP_REG(SOR_XBAR_POL);
-	DUMP_REG(SOR_DP_LINKCTL0);
-	DUMP_REG(SOR_DP_LINKCTL1);
-	DUMP_REG(SOR_LANE_DRIVE_CURRENT0);
-	DUMP_REG(SOR_LANE_DRIVE_CURRENT1);
-	DUMP_REG(SOR_LANE4_DRIVE_CURRENT0);
-	DUMP_REG(SOR_LANE4_DRIVE_CURRENT1);
-	DUMP_REG(SOR_LANE_PREEMPHASIS0);
-	DUMP_REG(SOR_LANE_PREEMPHASIS1);
-	DUMP_REG(SOR_LANE4_PREEMPHASIS0);
-	DUMP_REG(SOR_LANE4_PREEMPHASIS1);
-	DUMP_REG(SOR_LANE_POSTCURSOR0);
-	DUMP_REG(SOR_LANE_POSTCURSOR1);
-	DUMP_REG(SOR_DP_CONFIG0);
-	DUMP_REG(SOR_DP_CONFIG1);
-	DUMP_REG(SOR_DP_MN0);
-	DUMP_REG(SOR_DP_MN1);
-	DUMP_REG(SOR_DP_PADCTL0);
-	DUMP_REG(SOR_DP_PADCTL1);
-	DUMP_REG(SOR_DP_DEBUG0);
-	DUMP_REG(SOR_DP_DEBUG1);
-	DUMP_REG(SOR_DP_SPARE0);
-	DUMP_REG(SOR_DP_SPARE1);
-	DUMP_REG(SOR_DP_AUDIO_CTRL);
-	DUMP_REG(SOR_DP_AUDIO_HBLANK_SYMBOLS);
-	DUMP_REG(SOR_DP_AUDIO_VBLANK_SYMBOLS);
-	DUMP_REG(SOR_DP_GENERIC_INFOFRAME_HEADER);
-	DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK0);
-	DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK1);
-	DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK2);
-	DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK3);
-	DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK4);
-	DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK5);
-	DUMP_REG(SOR_DP_GENERIC_INFOFRAME_SUBPACK6);
-	DUMP_REG(SOR_DP_TPG);
-	DUMP_REG(SOR_DP_TPG_CONFIG);
-	DUMP_REG(SOR_DP_LQ_CSTM0);
-	DUMP_REG(SOR_DP_LQ_CSTM1);
-	DUMP_REG(SOR_DP_LQ_CSTM2);
-
-#undef DUMP_REG
+	for (i = 0; i < ARRAY_SIZE(tegra_sor_regs); i++) {
+		unsigned int offset = tegra_sor_regs[i].offset;
+
+		seq_printf(s, "%-38s %#05x %08x\n", tegra_sor_regs[i].name,
+			   offset, tegra_sor_readl(sor, offset));
+	}
 
 unlock:
 	drm_modeset_unlock_all(drm);
Signature · 6 lines
2.15.0

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel
#14 lore raw

PATCH 5/13 drm/tegra: dc: Reshuffle some code

In reply to Thierry Reding

From: Thierry Reding <[email protected]>

Reshuffle some code so that functions are defined closer to where they are used.

---
 drivers/gpu/drm/tegra/dc.c | 152 ++++++++++++++++++++++-----------------------
 1 file changed, 76 insertions(+), 76 deletions(-)
drivers/gpu/drm/tegra/dc.c +76 -76
index 825419dff07b..052f512572d5 100644
@@ -909,82 +909,6 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc)
 	return 0;
 }
 
-static u32 tegra_dc_get_vblank_counter(struct drm_crtc *crtc)
-{
-	struct tegra_dc *dc = to_tegra_dc(crtc);
-
-	if (dc->syncpt)
-		return host1x_syncpt_read(dc->syncpt);
-
-	/* fallback to software emulated VBLANK counter */
-	return drm_crtc_vblank_count(&dc->base);
-}
-
-static int tegra_dc_enable_vblank(struct drm_crtc *crtc)
-{
-	struct tegra_dc *dc = to_tegra_dc(crtc);
-	unsigned long value, flags;
-
-	spin_lock_irqsave(&dc->lock, flags);
-
-	value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
-	value |= VBLANK_INT;
-	tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
-
-	spin_unlock_irqrestore(&dc->lock, flags);
-
-	return 0;
-}
-
-static void tegra_dc_disable_vblank(struct drm_crtc *crtc)
-{
-	struct tegra_dc *dc = to_tegra_dc(crtc);
-	unsigned long value, flags;
-
-	spin_lock_irqsave(&dc->lock, flags);
-
-	value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
-	value &= ~VBLANK_INT;
-	tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
-
-	spin_unlock_irqrestore(&dc->lock, flags);
-}
-
-static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
-{
-	struct drm_device *drm = dc->base.dev;
-	struct drm_crtc *crtc = &dc->base;
-	unsigned long flags, base;
-	struct tegra_bo *bo;
-
-	spin_lock_irqsave(&drm->event_lock, flags);
-
-	if (!dc->event) {
-		spin_unlock_irqrestore(&drm->event_lock, flags);
-		return;
-	}
-
-	bo = tegra_fb_get_plane(crtc->primary->fb, 0);
-
-	spin_lock(&dc->lock);
-
-	/* check if new start address has been latched */
-	tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
-	tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
-	base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
-	tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);
-
-	spin_unlock(&dc->lock);
-
-	if (base == bo->paddr + crtc->primary->fb->offsets[0]) {
-		drm_crtc_send_vblank_event(crtc, dc->event);
-		drm_crtc_vblank_put(crtc);
-		dc->event = NULL;
-	}
-
-	spin_unlock_irqrestore(&drm->event_lock, flags);
-}
-
 static void tegra_dc_destroy(struct drm_crtc *crtc)
 {
 	drm_crtc_cleanup(crtc);
@@ -1035,6 +959,47 @@ static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc,
 	kfree(state);
 }
 
+static u32 tegra_dc_get_vblank_counter(struct drm_crtc *crtc)
+{
+	struct tegra_dc *dc = to_tegra_dc(crtc);
+
+	if (dc->syncpt)
+		return host1x_syncpt_read(dc->syncpt);
+
+	/* fallback to software emulated VBLANK counter */
+	return drm_crtc_vblank_count(&dc->base);
+}
+
+static int tegra_dc_enable_vblank(struct drm_crtc *crtc)
+{
+	struct tegra_dc *dc = to_tegra_dc(crtc);
+	unsigned long value, flags;
+
+	spin_lock_irqsave(&dc->lock, flags);
+
+	value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
+	value |= VBLANK_INT;
+	tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
+
+	spin_unlock_irqrestore(&dc->lock, flags);
+
+	return 0;
+}
+
+static void tegra_dc_disable_vblank(struct drm_crtc *crtc)
+{
+	struct tegra_dc *dc = to_tegra_dc(crtc);
+	unsigned long value, flags;
+
+	spin_lock_irqsave(&dc->lock, flags);
+
+	value = tegra_dc_readl(dc, DC_CMD_INT_MASK);
+	value &= ~VBLANK_INT;
+	tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
+
+	spin_unlock_irqrestore(&dc->lock, flags);
+}
+
 static const struct drm_crtc_funcs tegra_crtc_funcs = {
 	.page_flip = drm_atomic_helper_page_flip,
 	.set_config = drm_atomic_helper_set_config,
@@ -1342,6 +1307,41 @@ static const struct drm_crtc_helper_funcs tegra_crtc_helper_funcs = {
 	.atomic_disable = tegra_crtc_atomic_disable,
 };
 
+static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
+{
+	struct drm_device *drm = dc->base.dev;
+	struct drm_crtc *crtc = &dc->base;
+	unsigned long flags, base;
+	struct tegra_bo *bo;
+
+	spin_lock_irqsave(&drm->event_lock, flags);
+
+	if (!dc->event) {
+		spin_unlock_irqrestore(&drm->event_lock, flags);
+		return;
+	}
+
+	bo = tegra_fb_get_plane(crtc->primary->fb, 0);
+
+	spin_lock(&dc->lock);
+
+	/* check if new start address has been latched */
+	tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
+	tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
+	base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
+	tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);
+
+	spin_unlock(&dc->lock);
+
+	if (base == bo->paddr + crtc->primary->fb->offsets[0]) {
+		drm_crtc_send_vblank_event(crtc, dc->event);
+		drm_crtc_vblank_put(crtc);
+		dc->event = NULL;
+	}
+
+	spin_unlock_irqrestore(&drm->event_lock, flags);
+}
+
 static irqreturn_t tegra_dc_irq(int irq, void *data)
 {
 	struct tegra_dc *dc = data;
Signature · 6 lines
2.15.0

_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel