From f89c0e66e018c9594f76a0ef5d3b24742e9811fb Mon Sep 17 00:00:00 2001 From: Cai Wenzhong Date: Fri, 10 Nov 2023 19:54:21 +0800 Subject: [PATCH] media: i2c: maxim2c: driver version v2.00.01 1. MIPI TXPHY add tunnel mode support. 2. MIPI TXPHY mode only support 2x4Lanes and 2x2Lanes. Signed-off-by: Cai Wenzhong Change-Id: I33d5ff240c9f85319f757c3cc2ba7d067ce69aae --- drivers/media/i2c/maxim2c/maxim2c_drv.c | 6 +- .../media/i2c/maxim2c/maxim2c_mipi_txphy.c | 75 +++++++++++++------ .../media/i2c/maxim2c/maxim2c_mipi_txphy.h | 3 +- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/drivers/media/i2c/maxim2c/maxim2c_drv.c b/drivers/media/i2c/maxim2c/maxim2c_drv.c index bd5cf4cfa9ec..0ae41e205673 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_drv.c +++ b/drivers/media/i2c/maxim2c/maxim2c_drv.c @@ -15,6 +15,10 @@ * 6. support remote serializer I2c address mapping * 7. support remote serializer hot plug detection and recovery * + * V2.00.01 + * 1. MIPI TXPHY add tunnel mode support + * 2. MIPI TXPHY mode only support 2x4Lanes and 2x2Lanes + * */ #include #include @@ -44,7 +48,7 @@ #include "maxim2c_api.h" -#define DRIVER_VERSION KERNEL_VERSION(2, 0x00, 0x00) +#define DRIVER_VERSION KERNEL_VERSION(2, 0x00, 0x01) #define MAXIM2C_XVCLK_FREQ 25000000 diff --git a/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c b/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c index 68fa50409c31..fd2149798242 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c +++ b/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.c @@ -22,6 +22,10 @@ static int maxim2c_txphy_auto_init_deskew(maxim2c_t *maxim2c) // D-PHY Deskew Initial Calibration Control for (phy_idx = 0; phy_idx < MAXIM2C_TXPHY_ID_MAX; phy_idx++) { + // Auto Deskew can only be configured on PHY1 and PHY2 + if ((phy_idx == MAXIM2C_TXPHY_ID_A) || (phy_idx == MAXIM2C_TXPHY_ID_D)) + continue; + phy_cfg = &mipi_txphy->phy_cfg[phy_idx]; if (phy_cfg->phy_enable && (phy_cfg->auto_deskew & BIT(7))) { reg_addr = 0x0403 + 0x40 * phy_idx; @@ -129,10 +133,11 @@ static int maxim2c_mipi_txphy_tunnel_init(maxim2c_t *maxim2c) int ret = 0; for (phy_idx = 0; phy_idx < MAXIM2C_TXPHY_ID_MAX; phy_idx++) { - phy_cfg = &mipi_txphy->phy_cfg[phy_idx]; - if (phy_cfg->phy_enable == 0) + // Tunnel mode can only be configured on PHY1 and PHY2 + if ((phy_idx == MAXIM2C_TXPHY_ID_A) || (phy_idx == MAXIM2C_TXPHY_ID_D)) continue; + phy_cfg = &mipi_txphy->phy_cfg[phy_idx]; if (phy_cfg->tunnel_enable) { // tunnel mode: enable reg_mask = BIT(0); @@ -151,6 +156,16 @@ static int maxim2c_mipi_txphy_tunnel_init(maxim2c_t *maxim2c) ret |= maxim2c_i2c_update_byte(client, reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, reg_mask, reg_value); + + if (phy_cfg->tunnel_enable) { + reg_addr = 0x0433 + 0x40 * phy_idx; + reg_mask = (BIT(7) | BIT(6) | BIT(5)); + reg_value = ((phy_cfg->tunnel_vs_wait & 0x07) << 5); + + ret |= maxim2c_i2c_update_byte(client, + reg_addr, MAXIM2C_I2C_REG_ADDR_16BITS, + reg_mask, reg_value); + } } return ret; @@ -399,6 +414,12 @@ static int maxim2c_mipi_txphy_config_parse_dt(struct device *dev, phy_cfg->tunnel_enable = value; } + ret = of_property_read_u32(node, "tunnel-vs-wait", &value); + if (ret == 0) { + dev_info(dev, "tunnel-vs-wait property: %d", value); + phy_cfg->tunnel_vs_wait = value; + } + ret = of_property_read_u32(node, "tunnel-dest", &value); if (ret == 0) { dev_info(dev, "tunnel-dest property: %d", value); @@ -473,35 +494,47 @@ int maxim2c_mipi_txphy_hw_init(maxim2c_t *maxim2c) maxim2c_mipi_txphy_t *mipi_txphy = &maxim2c->mipi_txphy; struct maxim2c_txphy_cfg *phy_cfg = NULL; u8 mode = 0; - int ret = 0, i = 0; + int ret = 0; switch (mipi_txphy->phy_mode) { - case MAXIM2C_TXPHY_MODE_4X2LANES: + case MAXIM2C_TXPHY_MODE_2X2LANES: mode = BIT(0); - - // clock master - for (i = 0; i < MAXIM2C_TXPHY_ID_MAX; i++) { - if (mipi_txphy->phy_cfg[i].phy_enable) - mipi_txphy->phy_cfg[i].clock_master = 1; - } - break; case MAXIM2C_TXPHY_MODE_2X4LANES: default: mode = BIT(2); - - // clock master - phy_cfg = &mipi_txphy->phy_cfg[MAXIM2C_TXPHY_ID_B]; - if (phy_cfg->phy_enable) - phy_cfg->clock_master = 1; - - phy_cfg = &mipi_txphy->phy_cfg[MAXIM2C_TXPHY_ID_C]; - if (phy_cfg->phy_enable) - phy_cfg->clock_master = 1; - break; } + // clock master + phy_cfg = &mipi_txphy->phy_cfg[MAXIM2C_TXPHY_ID_B]; + if (phy_cfg->phy_enable) { + if (phy_cfg->tunnel_enable) { + if (phy_cfg->tunnel_dest == 0) { + phy_cfg->clock_master = 1; + } else { + phy_cfg->phy_enable = 0; + phy_cfg->clock_master = 0; + } + } else { + phy_cfg->clock_master = 1; + } + } + + phy_cfg = &mipi_txphy->phy_cfg[MAXIM2C_TXPHY_ID_C]; + if (phy_cfg->phy_enable) { + if (phy_cfg->tunnel_enable) { + if (phy_cfg->tunnel_dest == 1) { + phy_cfg->clock_master = 1; + } else { + phy_cfg->phy_enable = 0; + phy_cfg->clock_master = 0; + } + } else { + phy_cfg->clock_master = 1; + } + } + // MIPI TXPHY Mode setting ret |= maxim2c_i2c_write_byte(client, 0x0330, MAXIM2C_I2C_REG_ADDR_16BITS, diff --git a/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.h b/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.h index e3ef405bebd9..5e2ae4624cc8 100644 --- a/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.h +++ b/drivers/media/i2c/maxim2c/maxim2c_mipi_txphy.h @@ -33,7 +33,7 @@ enum { /* MIPI TXPHY Mode */ enum { MAXIM2C_TXPHY_MODE_2X4LANES = 0, /* PortA: 1x4Lanes, PortB: 1x4Lanes */ - MAXIM2C_TXPHY_MODE_4X2LANES, /* PortA: 2x2Lanes, PortB: 2x2Lanes */ + MAXIM2C_TXPHY_MODE_2X2LANES, /* PortA: 2Lanes, PortB: 2Lanes */ }; /* MIPI TXPHY DPLL */ @@ -50,6 +50,7 @@ struct maxim2c_txphy_cfg { u8 data_lane_map; u8 vc_ext_en; u8 tunnel_enable; + u8 tunnel_vs_wait; u8 tunnel_dest; u8 clock_master; u8 clock_mode;