From 62f8bdfee3db98e2a77ded3e296433c91581e6c4 Mon Sep 17 00:00:00 2001 From: ChiHun Won Date: Wed, 4 Jul 2018 14:30:01 +0900 Subject: [PATCH] fbdev: dpu20: implement DPU SFR dump function Change-Id: I6edab25e9c79b768cc4b0d492b6a245724552682 Signed-off-by: ChiHun Won --- drivers/video/fbdev/exynos/dpu20/decon_core.c | 57 +------------ drivers/video/fbdev/exynos/dpu20/dpp_drv.c | 49 +----------- drivers/video/fbdev/exynos/dpu20/dsim.h | 2 + drivers/video/fbdev/exynos/dpu20/dsim_drv.c | 80 ++++++++++++++----- drivers/video/fbdev/exynos/dpu20/helper.c | 8 ++ 5 files changed, 73 insertions(+), 123 deletions(-) diff --git a/drivers/video/fbdev/exynos/dpu20/decon_core.c b/drivers/video/fbdev/exynos/dpu20/decon_core.c index 55bf1794874a..6d4d31e247d7 100644 --- a/drivers/video/fbdev/exynos/dpu20/decon_core.c +++ b/drivers/video/fbdev/exynos/dpu20/decon_core.c @@ -144,40 +144,10 @@ static void decon_up_list_saved(void) } } -static void __decon_dump(bool en_dsc) -{ - struct decon_device *decon = get_decon_drvdata(0); - - decon_info("\n=== DECON0 WINDOW SFR DUMP ===\n"); - print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, - decon->res.regs + 0x1000, 0x340, false); - - decon_info("\n=== DECON0 WINDOW SHADOW SFR DUMP ===\n"); - print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, - decon->res.regs + SHADOW_OFFSET + 0x1000, 0x220, false); - - if (decon->lcd_info->dsc_enabled && en_dsc) { - decon_info("\n=== DECON0 DSC0 SFR DUMP ===\n"); - print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, - decon->res.regs + 0x4000, 0x80, false); - - decon_info("\n=== DECON0 DSC1 SFR DUMP ===\n"); - print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, - decon->res.regs + 0x5000, 0x80, false); - - decon_info("\n=== DECON0 DSC0 SHADOW SFR DUMP ===\n"); - print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, - decon->res.regs + SHADOW_OFFSET + 0x4000, 0x80, false); - - decon_info("\n=== DECON0 DSC1 SHADOW SFR DUMP ===\n"); - print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, - decon->res.regs + SHADOW_OFFSET + 0x5000, 0x80, false); - } -} - void decon_dump(struct decon_device *decon) { int acquired = console_trylock(); + void __iomem *base_regs = get_decon_drvdata(0)->res.regs; if (IS_DECON_OFF_STATE(decon)) { decon_info("%s: DECON%d is disabled, state(%d)\n", @@ -185,29 +155,8 @@ void decon_dump(struct decon_device *decon) return; } - decon_info("\n=== DECON%d SFR DUMP ===\n", decon->id); - print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, - decon->res.regs, 0x620, false); - - decon_info("\n=== DECON%d SHADOW SFR DUMP ===\n", decon->id); - print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, - decon->res.regs + SHADOW_OFFSET, 0x304, false); - - switch (decon->id) { - case 0: - __decon_dump(1); - break; - case 1: - if (decon->dt.out_type != DECON_OUT_WB) - __decon_dump(0); - else - __decon_dump(1); - break; - case 2: - default: - __decon_dump(0); - break; - } + __decon_dump(decon->id, decon->res.regs, base_regs, + decon->lcd_info->dsc_enabled); if (decon->dt.out_type == DECON_OUT_DSI) v4l2_subdev_call(decon->out_sd[0], core, ioctl, diff --git a/drivers/video/fbdev/exynos/dpu20/dpp_drv.c b/drivers/video/fbdev/exynos/dpu20/dpp_drv.c index 662220e80eb7..e9631456f794 100644 --- a/drivers/video/fbdev/exynos/dpu20/dpp_drv.c +++ b/drivers/video/fbdev/exynos/dpu20/dpp_drv.c @@ -24,58 +24,11 @@ int dpp_log_level = 6; struct dpp_device *dpp_drvdata[MAX_DPP_CNT]; -static void dma_dump_regs(struct dpp_device *dpp) -{ - dpp_info("\n=== DPU_DMA%d SFR DUMP ===\n", dpp->id); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.dma_regs, 0x6C, false); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.dma_regs + 0x100, 0x8, false); - - dpp_info("=== DPU_DMA%d SHADOW SFR DUMP ===\n", dpp->id); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.dma_regs + 0x800, 0x74, false); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.dma_regs + 0x900, 0x8, false); -} - -static void dpp_dump_regs(struct dpp_device *dpp) -{ - dpp_info("=== DPP%d SFR DUMP ===\n", dpp->id); - - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.regs, 0x4C, false); - if (test_bit(DPP_ATTR_AFBC, &dpp->attr)) { - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.regs + 0x5B0, 0x10, false); - } - if (test_bit(DPP_ATTR_ROT, &dpp->attr)) { - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.regs + 0x600, 0x1E0, false); - } - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.regs + 0xA54, 0x4, false); - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.regs + 0xB00, 0x4C, false); - if (test_bit(DPP_ATTR_AFBC, &dpp->attr)) { - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.regs + 0xBB0, 0x10, false); - } - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, 32, 4, - dpp->res.regs + 0xD00, 0xC, false); -} - void dpp_dump(struct dpp_device *dpp) { int acquired = console_trylock(); - dma_reg_dump_com_debug_regs(dpp->id); - - dma_dump_regs(dpp); - dma_reg_dump_debug_regs(dpp->id); - - dpp_dump_regs(dpp); - dpp_reg_dump_debug_regs(dpp->id); + __dpp_dump(dpp->id, dpp->res.regs, dpp->res.dma_regs, dpp->attr); if (acquired) console_unlock(); diff --git a/drivers/video/fbdev/exynos/dpu20/dsim.h b/drivers/video/fbdev/exynos/dpu20/dsim.h index d26bc5163187..fb402f95c3ea 100644 --- a/drivers/video/fbdev/exynos/dpu20/dsim.h +++ b/drivers/video/fbdev/exynos/dpu20/dsim.h @@ -259,6 +259,8 @@ int dsim_wait_for_cmd_done(struct dsim_device *dsim); int dsim_reset_panel(struct dsim_device *dsim); int dsim_set_panel_power(struct dsim_device *dsim, bool on); +void dsim_to_regs_param(struct dsim_device *dsim, struct dsim_regs *regs); + static inline struct dsim_device *get_dsim_drvdata(u32 id) { return dsim_drvdata[id]; diff --git a/drivers/video/fbdev/exynos/dpu20/dsim_drv.c b/drivers/video/fbdev/exynos/dpu20/dsim_drv.c index 93bd00e5fd46..93a1c379b664 100644 --- a/drivers/video/fbdev/exynos/dpu20/dsim_drv.c +++ b/drivers/video/fbdev/exynos/dpu20/dsim_drv.c @@ -64,21 +64,14 @@ static char *dsim_state_names[] = { static int dsim_runtime_suspend(struct device *dev); static int dsim_runtime_resume(struct device *dev); -static void __dsim_dump(struct dsim_device *dsim) -{ - /* change to updated register read mode (meaning: SHADOW in DECON) */ - dsim_info("=== DSIM %d LINK SFR DUMP ===\n", dsim->id); - dsim_reg_enable_shadow_read(dsim->id, 0); - print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 32, 4, - dsim->res.regs, 0xFC, false); - - dsim_reg_enable_shadow_read(dsim->id, 1); -} - static void dsim_dump(struct dsim_device *dsim) { + struct dsim_regs regs; + dsim_info("=== DSIM SFR DUMP ===\n"); - __dsim_dump(dsim); + + dsim_to_regs_param(dsim, ®s); + __dsim_dump(dsim->id, ®s); /* Show panel status */ call_panel_ops(dsim, dump, dsim); @@ -135,6 +128,7 @@ static void dsim_long_data_wr(struct dsim_device *dsim, unsigned long d0, u32 d1 static int dsim_wait_for_cmd_fifo_empty(struct dsim_device *dsim, bool must_wait) { int ret = 0; + struct dsim_regs regs; if (!must_wait) { /* timer is running, but already command is transferred */ @@ -159,7 +153,8 @@ static int dsim_wait_for_cmd_fifo_empty(struct dsim_device *dsim, bool must_wait if (IS_DSIM_ON_STATE(dsim) && (ret == -ETIMEDOUT)) { dsim_err("%s have timed out\n", __func__); - __dsim_dump(dsim); + dsim_to_regs_param(dsim, ®s); + __dsim_dump(dsim->id, ®s); } return ret; } @@ -279,6 +274,7 @@ int dsim_read_data(struct dsim_device *dsim, u32 id, u32 addr, u32 cnt, u8 *buf) int i, j, ret = 0; u32 rx_fifo_depth = DSIM_RX_FIFO_MAX_DEPTH; struct decon_device *decon = get_decon_drvdata(0); + struct dsim_regs regs; decon_hiber_block_exit(decon); @@ -315,7 +311,8 @@ int dsim_read_data(struct dsim_device *dsim, u32 id, u32 addr, u32 cnt, u8 *buf) case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT: ret = dsim_reg_rx_err_handler(dsim->id, rx_fifo); if (ret < 0) { - __dsim_dump(dsim); + dsim_to_regs_param(dsim, ®s); + __dsim_dump(dsim->id, ®s); goto exit; } break; @@ -351,7 +348,8 @@ int dsim_read_data(struct dsim_device *dsim, u32 id, u32 addr, u32 cnt, u8 *buf) break; default: dsim_err("Packet format is invaild.\n"); - __dsim_dump(dsim); + dsim_to_regs_param(dsim, ®s); + __dsim_dump(dsim->id, ®s); ret = -EBUSY; goto exit; } @@ -360,7 +358,8 @@ int dsim_read_data(struct dsim_device *dsim, u32 id, u32 addr, u32 cnt, u8 *buf) ret = rx_size; if (!rx_fifo_depth) { dsim_err("Check DPHY values about HS clk.\n"); - __dsim_dump(dsim); + dsim_to_regs_param(dsim, ®s); + __dsim_dump(dsim->id, ®s); ret = -EBUSY; } exit: @@ -374,6 +373,7 @@ static void dsim_cmd_fail_detector(unsigned long arg) { struct dsim_device *dsim = (struct dsim_device *)arg; struct decon_device *decon = get_decon_drvdata(0); + struct dsim_regs regs; decon_hiber_block(decon); @@ -392,7 +392,8 @@ static void dsim_cmd_fail_detector(unsigned long arg) goto exit; } - __dsim_dump(dsim); + dsim_to_regs_param(dsim, ®s); + __dsim_dump(dsim->id, ®s); exit: decon_hiber_unblock(decon); @@ -452,6 +453,7 @@ static irqreturn_t dsim_irq_handler(int irq, void *dev_id) unsigned int int_src; struct dsim_device *dsim = dev_id; struct decon_device *decon = get_decon_drvdata(0); + struct dsim_regs regs; #ifdef CONFIG_EXYNOS_PD int active; #endif @@ -489,8 +491,10 @@ static irqreturn_t dsim_irq_handler(int irq, void *dev_id) dsim_info("dsim%d underrun irq occurs(%d)\n", dsim->id, dsim->total_underrun_cnt); dsim_underrun_info(dsim); - if (dsim->lcd_info.mode == DECON_VIDEO_MODE) - __dsim_dump(dsim); + if (dsim->lcd_info.mode == DECON_VIDEO_MODE) { + dsim_to_regs_param(dsim, ®s); + __dsim_dump(dsim->id, ®s); + } } if (int_src & DSIM_INTSRC_VT_STATUS) { dsim_dbg("dsim%d vt_status(vsync) irq occurs\n", dsim->id); @@ -805,6 +809,8 @@ out: static int _dsim_disable(struct dsim_device *dsim, enum dsim_state state) { + struct dsim_regs regs; + if (IS_DSIM_OFF_STATE(dsim)) { dsim_warn("%s dsim already off(%s)\n", __func__, dsim_state_names[dsim->state]); @@ -822,8 +828,10 @@ static int _dsim_disable(struct dsim_device *dsim, enum dsim_state state) dsim->state = state; mutex_unlock(&dsim->cmd_lock); - if (dsim_reg_stop(dsim->id, dsim->data_lane) < 0) - __dsim_dump(dsim); + if (dsim_reg_stop(dsim->id, dsim->data_lane) < 0) { + dsim_to_regs_param(dsim, ®s); + __dsim_dump(dsim->id, ®s); + } disable_irq(dsim->res.irq); /* HACK */ @@ -1478,6 +1486,36 @@ static int dsim_init_resources(struct dsim_device *dsim, struct platform_device return -EINVAL; } + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dsim_info("no 2nd mem resource\n"); + dsim->res.phy_regs = NULL; + } else { + dsim_info("dphy res: start(0x%x), end(0x%x)\n", + (u32)res->start, (u32)res->end); + + dsim->res.phy_regs = devm_ioremap_resource(dsim->dev, res); + if (!dsim->res.phy_regs) { + dsim_err("failed to remap DSIM DPHY SFR region\n"); + return -EINVAL; + } + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 2); + if (!res) { + dsim_info("no extra dphy resource\n"); + dsim->res.phy_regs_ex = NULL; + } else { + dsim_info("dphy_extra res: start(0x%x), end(0x%x)\n", + (u32)res->start, (u32)res->end); + + dsim->res.phy_regs_ex = devm_ioremap_resource(dsim->dev, res); + if (!dsim->res.phy_regs_ex) { + dsim_err("failed to remap DSIM DPHY(EXTRA) SFR region\n"); + return -EINVAL; + } + } + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dsim_err("failed to get irq resource\n"); diff --git a/drivers/video/fbdev/exynos/dpu20/helper.c b/drivers/video/fbdev/exynos/dpu20/helper.c index 3952c827b6e4..0d22eb714336 100644 --- a/drivers/video/fbdev/exynos/dpu20/helper.c +++ b/drivers/video/fbdev/exynos/dpu20/helper.c @@ -707,3 +707,11 @@ int dpu_pm_domain_check_status(struct exynos_pm_domain *pm_domain) return 0; } #endif + +void dsim_to_regs_param(struct dsim_device *dsim, struct dsim_regs *regs) +{ + regs->regs = dsim->res.regs; + regs->ss_regs = dsim->res.ss_regs; + regs->phy_regs = dsim->res.phy_regs; + regs->phy_regs_ex = dsim->res.phy_regs_ex; +} -- 2.20.1