diff --git a/drivers/media/platform/raspberrypi/rp1_cfe/csi2.c b/drivers/media/platform/raspberrypi/rp1_cfe/csi2.c index 25dc4354c67dc3..85408880e02931 100644 --- a/drivers/media/platform/raspberrypi/rp1_cfe/csi2.c +++ b/drivers/media/platform/raspberrypi/rp1_cfe/csi2.c @@ -574,7 +574,7 @@ int csi2_init(struct csi2_device *csi2, struct dentry *debugfs) spin_lock_init(&csi2->errors_lock); csi2->dphy.dev = csi2->v4l2_dev->dev; - dphy_probe(&csi2->dphy); + dphy_probe(&csi2->dphy, debugfs); debugfs_create_file("csi2_regs", 0444, debugfs, csi2, &csi2_regs_fops); diff --git a/drivers/media/platform/raspberrypi/rp1_cfe/dphy.c b/drivers/media/platform/raspberrypi/rp1_cfe/dphy.c index f87d445f9361b2..e7db0fbd9fb46a 100644 --- a/drivers/media/platform/raspberrypi/rp1_cfe/dphy.c +++ b/drivers/media/platform/raspberrypi/rp1_cfe/dphy.c @@ -16,7 +16,7 @@ #define dphy_info(fmt, arg...) dev_info(dphy->dev, fmt, ##arg) #define dphy_err(fmt, arg...) dev_err(dphy->dev, fmt, ##arg) -/* DW dphy Host registers */ +/* DW CSI-2 Host registers */ #define VERSION 0x000 #define N_LANES 0x004 #define RESETN 0x008 @@ -29,7 +29,14 @@ #define PHY2_TST_CTRL0 0x058 #define PHY2_TST_CTRL1 0x05c -/* DW dphy Host Transactions */ +/* DW CSI-2 Host and PHY debug registers */ +#define INT_ST_PHY_FATAL 0x0e0 +#define INT_ST_PKT_FATAL 0x0f0 +#define INT_ST_FRAME_FATAL 0x100 +#define INT_ST_PHY 0x110 +#define INT_ST_PKT 0x120 + +/* DW D-PHY transaction codes */ #define DPHY_HS_RX_CTRL_LANE0_OFFSET 0x44 #define DPHY_PLL_INPUT_DIV_OFFSET 0x17 #define DPHY_PLL_LOOP_DIV_OFFSET 0x18 @@ -183,7 +190,37 @@ void dphy_stop(struct dphy_data *dphy) */ } -void dphy_probe(struct dphy_data *dphy) +static int dphy_debug_show(struct seq_file *s, void *data) +{ + /* + * Here we expose various error flags in the CSI-2 Host and PHY. + * All these registers apart from PHY_STOPSTATE are read-to-clear. + * The only reliable way to count errors would be to service a + * dedicated interrupt. For now, we'll just read (and clear) them. + */ + struct dphy_data *dphy = s->private; + int ret; + + ret = pm_runtime_resume_and_get(dphy->dev); + if (ret) + return ret; + +#define DUMP(reg) seq_printf(s, #reg " \t0x%08x\n", dw_csi2_host_read(dphy, reg)) + DUMP(PHY_STOPSTATE); /* Data lane (bits 0-3) or clock (bit 16) is in stopstate */ + DUMP(INT_ST_PHY_FATAL); /* HS start sync error for each data lane (bits 0-3) */ + DUMP(INT_ST_PKT_FATAL); /* CRC error on VC (bits 0-3); ECC unrecoverable error (bit 16) */ + DUMP(INT_ST_FRAME_FATAL); /* FS/FE mismatch (bits 0-3), seq (8-11), CRC error (16-19) */ + DUMP(INT_ST_PHY); /* Non-fatal error for each data lane HS (bits 0-3), LP (16-19) */ + DUMP(INT_ST_PKT); /* Unknown DT on VC (bits 0-3); ECC corrected error (b16-19) */ +#undef DUMP + + pm_runtime_put(dphy->dev); + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(dphy_debug); + +void dphy_probe(struct dphy_data *dphy, struct dentry *debugfs) { u32 host_ver; u8 host_ver_major, host_ver_minor; @@ -195,4 +232,7 @@ void dphy_probe(struct dphy_data *dphy) host_ver_minor += (u8)((host_ver >> 8) - '0'); dphy_info("DW dphy Host HW v%u.%u\n", host_ver_major, host_ver_minor); + + if (debugfs) + debugfs_create_file("dphy_debug", 0444, debugfs, dphy, &dphy_debug_fops); } diff --git a/drivers/media/platform/raspberrypi/rp1_cfe/dphy.h b/drivers/media/platform/raspberrypi/rp1_cfe/dphy.h index 8acfd7c58e8278..c1042a738bb620 100644 --- a/drivers/media/platform/raspberrypi/rp1_cfe/dphy.h +++ b/drivers/media/platform/raspberrypi/rp1_cfe/dphy.h @@ -7,6 +7,7 @@ #ifndef _RP1_DPHY_ #define _RP1_DPHY_ +#include #include #include #include @@ -22,7 +23,7 @@ struct dphy_data { bool lane_polarities[1 + V4L2_MBUS_CSI2_MAX_DATA_LANES]; }; -void dphy_probe(struct dphy_data *dphy); +void dphy_probe(struct dphy_data *dphy, struct dentry *debugfs); void dphy_start(struct dphy_data *dphy); void dphy_stop(struct dphy_data *dphy); diff --git a/drivers/media/platform/raspberrypi/rp1_cfe/pisp_fe.c b/drivers/media/platform/raspberrypi/rp1_cfe/pisp_fe.c index 07bc550deea742..627b9e43d2eb47 100644 --- a/drivers/media/platform/raspberrypi/rp1_cfe/pisp_fe.c +++ b/drivers/media/platform/raspberrypi/rp1_cfe/pisp_fe.c @@ -24,6 +24,8 @@ #define FE_OUTPUT_STATUS 0x014 #define FE_INT_EN 0x018 #define FE_INT_STATUS 0x01c +#define FE_DEBUG_FIFO_FULLNESS 0x024 +#define FE_DEBUG_STATUS2 0x02c /* CONTROL */ #define FE_CONTROL_QUEUE BIT(0) @@ -162,6 +164,8 @@ static int pisp_regs_show(struct seq_file *s, void *data) DUMP(FE_OUTPUT_STATUS); DUMP(FE_INT_EN); DUMP(FE_INT_STATUS); + DUMP(FE_DEBUG_FIFO_FULLNESS); + DUMP(FE_DEBUG_STATUS2); #undef DUMP pm_runtime_put(fe->v4l2_dev->dev);