fbdev: dpu20: implement DPU SFR dump function
authorChiHun Won <chihun.won@samsung.com>
Wed, 4 Jul 2018 05:30:01 +0000 (14:30 +0900)
committerWooyeon Kim <wooy88.kim@samsung.com>
Fri, 6 Jul 2018 01:43:17 +0000 (10:43 +0900)
Change-Id: I6edab25e9c79b768cc4b0d492b6a245724552682
Signed-off-by: ChiHun Won <chihun.won@samsung.com>
drivers/video/fbdev/exynos/dpu20/decon_core.c
drivers/video/fbdev/exynos/dpu20/dpp_drv.c
drivers/video/fbdev/exynos/dpu20/dsim.h
drivers/video/fbdev/exynos/dpu20/dsim_drv.c
drivers/video/fbdev/exynos/dpu20/helper.c

index 55bf1794874ae31116b694a242cfad19c321e5e3..6d4d31e247d7dfd5494d83c8138a4e8c0202f0c2 100644 (file)
@@ -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,
index 662220e80eb73ab027f4fe9c522382a82080c050..e9631456f79401fb40b195889567ad04e5d1e59c 100644 (file)
@@ -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();
index d26bc51631877b8165b31f6b0e2fc9baee9ebf62..fb402f95c3ea7228caa26a7db67e1d568d409750 100644 (file)
@@ -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];
index 93bd00e5fd46c1a825c2cca26cf5ff7bdcd1f0b3..93a1c379b664effdeceb201931dda2c5e8ba118d 100644 (file)
@@ -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, &regs);
+       __dsim_dump(dsim->id, &regs);
 
        /* 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, &regs);
+               __dsim_dump(dsim->id, &regs);
        }
        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, &regs);
+                               __dsim_dump(dsim->id, &regs);
                                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, &regs);
+                       __dsim_dump(dsim->id, &regs);
                        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, &regs);
+               __dsim_dump(dsim->id, &regs);
                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, &regs);
+       __dsim_dump(dsim->id, &regs);
 
 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, &regs);
+                       __dsim_dump(dsim->id, &regs);
+               }
        }
        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, &regs);
+               __dsim_dump(dsim->id, &regs);
+       }
        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");
index 3952c827b6e4481b5fe801fe5a293aa6921540e8..0d22eb714336a8d9dc346b33d915d2847f30d5d0 100644 (file)
@@ -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;
+}