From: Thierry Reding Date: Wed, 8 Nov 2017 13:40:54 +0100 Subject: drm/tegra: dc: Register debugfs in ->late_register() Git-commit: b95800eeef09f4853904ec4e926d098f1ca4698a Patch-mainline: v4.16-rc1 References: FATE#326289 FATE#326079 FATE#326049 FATE#322398 FATE#326166 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. Signed-off-by: Thierry Reding Acked-by: Petr Tesarik --- drivers/gpu/drm/tegra/dc.c | 698 +++++++++++++++++++++------------------------ drivers/gpu/drm/tegra/dc.h | 2 2 files changed, 335 insertions(+), 365 deletions(-) --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -959,6 +959,339 @@ static void tegra_crtc_atomic_destroy_st 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 .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, 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_c 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_c 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); --- a/drivers/gpu/drm/tegra/dc.h +++ b/drivers/gpu/drm/tegra/dc.h @@ -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;