From ff0626fcc2d19d0e4407d9cfd2779582f08a53bd Mon Sep 17 00:00:00 2001 From: Jianwei Fan Date: Mon, 4 Dec 2023 11:41:32 +0000 Subject: [PATCH] media: i2c: rk628: move some function to rk628_mipi_dphy.c Change-Id: I01a826edaf8c766f616a997d7c83f2009d10adac Signed-off-by: Jianwei Fan --- drivers/media/i2c/rk628/Makefile | 3 +- drivers/media/i2c/rk628/rk628_csi_v4l2.c | 20 +- drivers/media/i2c/rk628/rk628_dsi.c | 6 +- drivers/media/i2c/rk628/rk628_mipi_dphy.c | 279 ++++++++++++++++++++++ drivers/media/i2c/rk628/rk628_mipi_dphy.h | 274 +-------------------- 5 files changed, 302 insertions(+), 280 deletions(-) create mode 100644 drivers/media/i2c/rk628/rk628_mipi_dphy.c diff --git a/drivers/media/i2c/rk628/Makefile b/drivers/media/i2c/rk628/Makefile index d4130e7fb839..44d4388bf547 100644 --- a/drivers/media/i2c/rk628/Makefile +++ b/drivers/media/i2c/rk628/Makefile @@ -2,7 +2,8 @@ # # Makefile for the Rockchip RK628 display bridge driver. # -video-rk628-objs := rk628.o rk628_cru.o rk628_hdmirx.o rk628_dsi.o rk628_combrxphy.o rk628_combtxphy.o rk628_post_process.o +video-rk628-objs := rk628.o rk628_cru.o rk628_hdmirx.o rk628_dsi.o rk628_combrxphy.o \ + rk628_combtxphy.o rk628_mipi_dphy.o rk628_post_process.o obj-$(CONFIG_VIDEO_RK628) += video-rk628.o rk628-csi-objs := rk628_csi_v4l2.o diff --git a/drivers/media/i2c/rk628/rk628_csi_v4l2.c b/drivers/media/i2c/rk628/rk628_csi_v4l2.c index aea46f8f8582..a482715de4ad 100644 --- a/drivers/media/i2c/rk628/rk628_csi_v4l2.c +++ b/drivers/media/i2c/rk628/rk628_csi_v4l2.c @@ -920,7 +920,7 @@ static void rk628_csi_set_csi(struct v4l2_subdev *sd) rk628_csi0_cru_reset(sd); if (csi->rk628->version >= RK628F_VERSION) rk628_csi1_cru_reset(sd); - mipi_dphy_reset(csi->rk628); + rk628_mipi_dphy_reset(csi->rk628); rk628_post_process_setup(sd); if (csi->txphy_pwron) { @@ -1347,7 +1347,7 @@ static void rk628_csi_initial_setup(struct v4l2_subdev *sd) csi->rk628->dphy_lane_en = 0x1f; if (csi->plat_data->tx_mode == CSI_MODE) { - mipi_dphy_reset(csi->rk628); + rk628_mipi_dphy_reset(csi->rk628); mipi_dphy_power_on(csi); } csi->txphy_pwron = true; @@ -2058,19 +2058,19 @@ static int mipi_dphy_power_on(struct rk628_csi *csi) rk628_txphy_set_bus_width(csi->rk628, bus_width); rk628_txphy_set_mode(csi->rk628, PHY_MODE_VIDEO_MIPI); - mipi_dphy_init_hsfreqrange(csi->rk628, csi->lane_mbps, 0); + rk628_mipi_dphy_init_hsfreqrange(csi->rk628, csi->lane_mbps, 0); if (csi->rk628->version >= RK628F_VERSION) - mipi_dphy_init_hsfreqrange(csi->rk628, csi->lane_mbps, 1); + rk628_mipi_dphy_init_hsfreqrange(csi->rk628, csi->lane_mbps, 1); if (csi->rk628->dual_mipi) { - mipi_dphy_init_hsmanual(csi->rk628, true, 0); - mipi_dphy_init_hsmanual(csi->rk628, true, 1); + rk628_mipi_dphy_init_hsmanual(csi->rk628, true, 0); + rk628_mipi_dphy_init_hsmanual(csi->rk628, true, 1); } else if (csi->lane_mbps == MIPI_DATARATE_MBPS_HIGH && !csi->rk628->dual_mipi) { - mipi_dphy_init_hsmanual(csi->rk628, true, 0); - mipi_dphy_init_hsmanual(csi->rk628, false, 1); + rk628_mipi_dphy_init_hsmanual(csi->rk628, true, 0); + rk628_mipi_dphy_init_hsmanual(csi->rk628, false, 1); } else { - mipi_dphy_init_hsmanual(csi->rk628, false, 0); - mipi_dphy_init_hsmanual(csi->rk628, false, 1); + rk628_mipi_dphy_init_hsmanual(csi->rk628, false, 0); + rk628_mipi_dphy_init_hsmanual(csi->rk628, false, 1); } usleep_range(1500, 2000); diff --git a/drivers/media/i2c/rk628/rk628_dsi.c b/drivers/media/i2c/rk628/rk628_dsi.c index b635d69e6481..9a46e36f3d52 100644 --- a/drivers/media/i2c/rk628/rk628_dsi.c +++ b/drivers/media/i2c/rk628/rk628_dsi.c @@ -72,7 +72,7 @@ static void mipi_dphy_power_on_dsi(struct rk628_dsi *dsi) dsi_update_bits(rk628, 0, DSI_PHY_RSTZ, PHY_ENABLECLK, 0); dsi_update_bits(rk628, 0, DSI_PHY_RSTZ, PHY_SHUTDOWNZ, 0); dsi_update_bits(rk628, 0, DSI_PHY_RSTZ, PHY_RSTZ, 0); - testif_testclr_assert(dsi->rk628, 0); + rk628_testif_testclr_assert(dsi->rk628, 0); /* Set all REQUEST inputs to zero */ rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, @@ -80,9 +80,9 @@ static void mipi_dphy_power_on_dsi(struct rk628_dsi *dsi) FORCETXSTOPMODE(0) | FORCERXMODE(0)); udelay(1); - testif_testclr_deassert(dsi->rk628, 0); + rk628_testif_testclr_deassert(dsi->rk628, 0); - mipi_dphy_init_hsfreqrange(dsi->rk628, dsi->lane_mbps, 0); + rk628_mipi_dphy_init_hsfreqrange(dsi->rk628, dsi->lane_mbps, 0); dsi_update_bits(rk628, 0, DSI_PHY_RSTZ, PHY_ENABLECLK, PHY_ENABLECLK); diff --git a/drivers/media/i2c/rk628/rk628_mipi_dphy.c b/drivers/media/i2c/rk628/rk628_mipi_dphy.c new file mode 100644 index 000000000000..8a9fe28458fa --- /dev/null +++ b/drivers/media/i2c/rk628/rk628_mipi_dphy.c @@ -0,0 +1,279 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 Rockchip Electronics Co. Ltd. + * + */ + +#include +#include +#include + +#include "rk628_csi.h" +#include "rk628_dsi.h" +#include "rk628_mipi_dphy.h" + +static inline void testif_testclk_assert(struct rk628 *rk628, uint8_t mipi_id) +{ + rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, + PHY_TESTCLK, PHY_TESTCLK); + udelay(1); +} + +static inline void testif_testclk_deassert(struct rk628 *rk628, uint8_t mipi_id) +{ + rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, + PHY_TESTCLK, 0); + udelay(1); +} + +void rk628_testif_testclr_assert(struct rk628 *rk628, uint8_t mipi_id) +{ + rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, + PHY_TESTCLR, PHY_TESTCLR); + udelay(1); +} +EXPORT_SYMBOL(rk628_testif_testclr_assert); + +void rk628_testif_testclr_deassert(struct rk628 *rk628, uint8_t mipi_id) +{ + rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, + PHY_TESTCLR, 0); + udelay(1); +} +EXPORT_SYMBOL(rk628_testif_testclr_deassert); + +static inline void testif_testen_assert(struct rk628 *rk628, uint8_t mipi_id) +{ + rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, + PHY_TESTEN, PHY_TESTEN); + udelay(1); +} + +static inline void testif_testen_deassert(struct rk628 *rk628, uint8_t mipi_id) +{ + rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, + PHY_TESTEN, 0); + udelay(1); +} + +static inline void testif_set_data(struct rk628 *rk628, u8 data, uint8_t mipi_id) +{ + rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, + PHY_TESTDIN_MASK, PHY_TESTDIN(data)); + udelay(1); +} + +static inline u8 testif_get_data(struct rk628 *rk628, uint8_t mipi_id) +{ + u32 data = 0; + + rk628_i2c_read(rk628, mipi_id ? GRF_DPHY1_STATUS : GRF_DPHY0_STATUS, &data); + + return data >> PHY_TESTDOUT_SHIFT; +} + +static void testif_test_code_write(struct rk628 *rk628, u8 test_code, uint8_t mipi_id) +{ + testif_testclk_assert(rk628, mipi_id); + testif_set_data(rk628, test_code, mipi_id); + testif_testen_assert(rk628, mipi_id); + testif_testclk_deassert(rk628, mipi_id); + testif_testen_deassert(rk628, mipi_id); +} + +static void testif_test_data_write(struct rk628 *rk628, u8 test_data, uint8_t mipi_id) +{ + testif_testclk_deassert(rk628, mipi_id); + testif_set_data(rk628, test_data, mipi_id); + testif_testclk_assert(rk628, mipi_id); +} + +u8 rk628_testif_write(struct rk628 *rk628, u8 test_code, u8 test_data, uint8_t mipi_id) +{ + u8 monitor_data; + + testif_test_code_write(rk628, test_code, mipi_id); + testif_test_data_write(rk628, test_data, mipi_id); + monitor_data = testif_get_data(rk628, mipi_id); + + dev_dbg(rk628->dev, "test_code=0x%02x, mipi dphy%x", test_code, mipi_id); + dev_dbg(rk628->dev, "test_data=0x%02x, mipi dphy%x", test_data, mipi_id); + dev_dbg(rk628->dev, "monitor_data=0x%02x, mipi dphy%x\n", monitor_data, mipi_id); + + return monitor_data; +} +EXPORT_SYMBOL(rk628_testif_write); + +u8 rk628_testif_read(struct rk628 *rk628, u8 test_code, uint8_t mipi_id) +{ + u8 test_data; + + testif_test_code_write(rk628, test_code, mipi_id); + test_data = testif_get_data(rk628, mipi_id); + testif_test_data_write(rk628, test_data, mipi_id); + + return test_data; +} +EXPORT_SYMBOL(rk628_testif_read); + +static inline void mipi_dphy_enablelane_assert(struct rk628 *rk628, uint8_t mipi_id) +{ + rk628_i2c_update_bits(rk628, mipi_id ? CSITX1_DPHY_CTRL : CSITX_DPHY_CTRL, + CSI_DPHY_EN_MASK, CSI_DPHY_EN(rk628->dphy_lane_en)); + udelay(1); +} + +static inline void mipi_dphy_enablelane_deassert(struct rk628 *rk628, uint8_t mipi_id) +{ + rk628_i2c_update_bits(rk628, mipi_id ? CSITX1_DPHY_CTRL : CSITX_DPHY_CTRL, + CSI_DPHY_EN_MASK, 0); + udelay(1); +} + +static inline void mipi_dphy_shutdownz_assert(struct rk628 *rk628) +{ + rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYSHUTDOWNZ, 0); + udelay(1); +} + +static inline void mipi_dphy_shutdownz_deassert(struct rk628 *rk628) +{ + rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYSHUTDOWNZ, + CSI_PHYSHUTDOWNZ); + udelay(1); +} + +static inline void mipi_dphy_rstz_assert(struct rk628 *rk628) +{ + rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYRSTZ, 0); + udelay(1); +} + +static inline void mipi_dphy_rstz_deassert(struct rk628 *rk628) +{ + rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYRSTZ, + CSI_PHYRSTZ); + udelay(1); +} + +void rk628_mipi_dphy_init_hsfreqrange(struct rk628 *rk628, int lane_mbps, uint8_t mipi_id) +{ + const struct { + unsigned long max_lane_mbps; + u8 hsfreqrange; + } hsfreqrange_table[] = { + { 90, 0x00}, { 100, 0x10}, { 110, 0x20}, { 130, 0x01}, + { 140, 0x11}, { 150, 0x21}, { 170, 0x02}, { 180, 0x12}, + { 200, 0x22}, { 220, 0x03}, { 240, 0x13}, { 250, 0x23}, + { 270, 0x04}, { 300, 0x14}, { 330, 0x05}, { 360, 0x15}, + { 400, 0x25}, { 450, 0x06}, { 500, 0x16}, { 550, 0x07}, + { 600, 0x17}, { 650, 0x08}, { 700, 0x18}, { 750, 0x09}, + { 800, 0x19}, { 850, 0x29}, { 900, 0x39}, { 950, 0x0a}, + {1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b}, + {1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c}, + {1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c} + }; + u8 hsfreqrange; + unsigned int index; + + for (index = 0; index < ARRAY_SIZE(hsfreqrange_table); index++) + if (lane_mbps <= hsfreqrange_table[index].max_lane_mbps) + break; + + if (index == ARRAY_SIZE(hsfreqrange_table)) + --index; + + hsfreqrange = hsfreqrange_table[index].hsfreqrange; + rk628_testif_write(rk628, 0x44, HSFREQRANGE(hsfreqrange), mipi_id); +} +EXPORT_SYMBOL(rk628_mipi_dphy_init_hsfreqrange); + +void rk628_mipi_dphy_init_hsmanual(struct rk628 *rk628, bool manual, uint8_t mipi_id) +{ + dev_info(rk628->dev, + "mipi dphy%d hs config, manual: %s\n", mipi_id, manual ? "true" : "false"); + //config mipi timing when mipi freq is 1250Mbps + rk628_testif_write(rk628, 0x71, + manual ? (HSTX(rk628->mipi_timing[mipi_id].data_prepare) | BIT(7)) : 0, mipi_id); + usleep_range(1500, 2000); + rk628_testif_write(rk628, 0x72, + manual ? (HSZERO(rk628->mipi_timing[mipi_id].data_zero) | BIT(6)) : 0, mipi_id); + usleep_range(1500, 2000); + rk628_testif_write(rk628, 0x73, + manual ? (HSTX(rk628->mipi_timing[mipi_id].data_trail) | BIT(7)) : 0, mipi_id); + usleep_range(1500, 2000); + rk628_testif_write(rk628, 0x61, + manual ? (HSTX(rk628->mipi_timing[mipi_id].clk_prepare) | BIT(7)) : 0, mipi_id); + usleep_range(1500, 2000); + rk628_testif_write(rk628, 0x62, + manual ? (HSZERO(rk628->mipi_timing[mipi_id].clk_zero) | BIT(6)) : 0, mipi_id); + usleep_range(1500, 2000); + rk628_testif_write(rk628, 0x63, + manual ? (HSTX(rk628->mipi_timing[mipi_id].clk_trail) | BIT(7)) : 0, mipi_id); + usleep_range(1500, 2000); + rk628_testif_write(rk628, 0x65, + manual ? (HSPOST(rk628->mipi_timing[mipi_id].clk_post) | BIT(5)) : 0, mipi_id); +} +EXPORT_SYMBOL(rk628_mipi_dphy_init_hsmanual); + +int rk628_mipi_dphy_reset(struct rk628 *rk628) +{ + u32 val, mask; + int ret; + + rk628_i2c_write(rk628, CSITX_SYS_CTRL0_IMD, 0x1); + if (rk628->version >= RK628F_VERSION) + rk628_i2c_write(rk628, CSITX1_SYS_CTRL0_IMD, 0x1); + mipi_dphy_enablelane_deassert(rk628, 0); + if (rk628->version >= RK628F_VERSION) + mipi_dphy_enablelane_deassert(rk628, 1); + mipi_dphy_shutdownz_assert(rk628); + mipi_dphy_rstz_assert(rk628); + rk628_testif_testclr_assert(rk628, 0); + if (rk628->version >= RK628F_VERSION) + rk628_testif_testclr_assert(rk628, 1); + + /* Set all REQUEST inputs to zero */ + rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, + FORCETXSTOPMODE_MASK | FORCERXMODE_MASK, + FORCETXSTOPMODE(0) | FORCERXMODE(0)); + if (rk628->version >= RK628F_VERSION) + rk628_i2c_update_bits(rk628, GRF_MIPI_TX1_CON, + FORCETXSTOPMODE_MASK | FORCERXMODE_MASK, + FORCETXSTOPMODE(0) | FORCERXMODE(0)); + udelay(1); + rk628_testif_testclr_deassert(rk628, 0); + if (rk628->version >= RK628F_VERSION) + rk628_testif_testclr_deassert(rk628, 1); + mipi_dphy_enablelane_assert(rk628, 0); + if (rk628->version >= RK628F_VERSION) + mipi_dphy_enablelane_assert(rk628, 1); + mipi_dphy_shutdownz_deassert(rk628); + mipi_dphy_rstz_deassert(rk628); + rk628_i2c_write(rk628, CSITX_SYS_CTRL0_IMD, 0x0); + if (rk628->version >= RK628F_VERSION) + rk628_i2c_write(rk628, CSITX1_SYS_CTRL0_IMD, 0x0); + usleep_range(10000, 11000); + + mask = STOPSTATE_CLK | STOPSTATE_LANE0; + + ret = regmap_read_poll_timeout(rk628->regmap[RK628_DEV_CSI], + CSITX_CSITX_STATUS1, + val, (val & mask) == mask, + 0, 1000); + if (ret < 0) + dev_err(rk628->dev, "csi0 lane module is not in stop state, val: 0x%x\n", val); + + if (rk628->version >= RK628F_VERSION) { + ret = regmap_read_poll_timeout(rk628->regmap[RK628_DEV_CSI1], + CSITX1_CSITX_STATUS1, + val, (val & mask) == mask, + 0, 1000); + if (ret < 0) + dev_err(rk628->dev, + "csi1 lane module is not in stop state, val: 0x%x\n", val); + } + + return 0; +} +EXPORT_SYMBOL(rk628_mipi_dphy_reset); diff --git a/drivers/media/i2c/rk628/rk628_mipi_dphy.h b/drivers/media/i2c/rk628/rk628_mipi_dphy.h index 5bb7379c67cf..531dfe440415 100644 --- a/drivers/media/i2c/rk628/rk628_mipi_dphy.h +++ b/drivers/media/i2c/rk628/rk628_mipi_dphy.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (c) 2020 Rockchip Electronics Co. Ltd. + * Copyright (c) 2023 Rockchip Electronics Co. Ltd. * * Author: Shunqing Chen */ @@ -8,12 +8,6 @@ #ifndef _RK628_MIPI_DPHY_H #define _RK628_MIPI_DPHY_H -#include -#include -#include - -#include "rk628_csi.h" -#include "rk628_dsi.h" #include "rk628.h" /* Test Code: 0x44 (HS RX Control of Lane 0) */ @@ -23,264 +17,12 @@ #define HSPOST(x) UPDATE(x, 4, 0) #define HSEXIT(x) UPDATE(x, 4, 0) -static inline void testif_testclk_assert(struct rk628 *rk628, uint8_t mipi_id) -{ - rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, - PHY_TESTCLK, PHY_TESTCLK); - udelay(1); -} - -static inline void testif_testclk_deassert(struct rk628 *rk628, uint8_t mipi_id) -{ - rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, - PHY_TESTCLK, 0); - udelay(1); -} - -static inline void testif_testclr_assert(struct rk628 *rk628, uint8_t mipi_id) -{ - rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, - PHY_TESTCLR, PHY_TESTCLR); - udelay(1); -} - -static inline void testif_testclr_deassert(struct rk628 *rk628, uint8_t mipi_id) -{ - rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, - PHY_TESTCLR, 0); - udelay(1); -} - -static inline void testif_testen_assert(struct rk628 *rk628, uint8_t mipi_id) -{ - rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, - PHY_TESTEN, PHY_TESTEN); - udelay(1); -} - -static inline void testif_testen_deassert(struct rk628 *rk628, uint8_t mipi_id) -{ - rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, - PHY_TESTEN, 0); - udelay(1); -} - -static inline void testif_set_data(struct rk628 *rk628, u8 data, uint8_t mipi_id) -{ - rk628_i2c_update_bits(rk628, mipi_id ? GRF_MIPI_TX1_CON : GRF_MIPI_TX0_CON, - PHY_TESTDIN_MASK, PHY_TESTDIN(data)); - udelay(1); -} - -static inline u8 testif_get_data(struct rk628 *rk628, uint8_t mipi_id) -{ - u32 data = 0; - - rk628_i2c_read(rk628, mipi_id ? GRF_DPHY1_STATUS : GRF_DPHY0_STATUS, &data); - - return data >> PHY_TESTDOUT_SHIFT; -} - -static void testif_test_code_write(struct rk628 *rk628, u8 test_code, uint8_t mipi_id) -{ - testif_testclk_assert(rk628, mipi_id); - testif_set_data(rk628, test_code, mipi_id); - testif_testen_assert(rk628, mipi_id); - testif_testclk_deassert(rk628, mipi_id); - testif_testen_deassert(rk628, mipi_id); -} - -static void testif_test_data_write(struct rk628 *rk628, u8 test_data, uint8_t mipi_id) -{ - testif_testclk_deassert(rk628, mipi_id); - testif_set_data(rk628, test_data, mipi_id); - testif_testclk_assert(rk628, mipi_id); -} - -static u8 testif_write(struct rk628 *rk628, u8 test_code, u8 test_data, uint8_t mipi_id) -{ - u8 monitor_data; - - testif_test_code_write(rk628, test_code, mipi_id); - testif_test_data_write(rk628, test_data, mipi_id); - monitor_data = testif_get_data(rk628, mipi_id); - - dev_dbg(rk628->dev, "test_code=0x%02x, mipi dphy%x", test_code, mipi_id); - dev_dbg(rk628->dev, "test_data=0x%02x, mipi dphy%x", test_data, mipi_id); - dev_dbg(rk628->dev, "monitor_data=0x%02x, mipi dphy%x\n", monitor_data, mipi_id); - - return monitor_data; -} - -static inline u8 testif_read(struct rk628 *rk628, u8 test_code, uint8_t mipi_id) -{ - u8 test_data; - - testif_test_code_write(rk628, test_code, mipi_id); - test_data = testif_get_data(rk628, mipi_id); - testif_test_data_write(rk628, test_data, mipi_id); - - return test_data; -} - -static inline void mipi_dphy_enablelane_assert(struct rk628 *rk628, uint8_t mipi_id) -{ - rk628_i2c_update_bits(rk628, mipi_id ? CSITX1_DPHY_CTRL : CSITX_DPHY_CTRL, - CSI_DPHY_EN_MASK, CSI_DPHY_EN(rk628->dphy_lane_en)); - udelay(1); -} - -static inline void mipi_dphy_enablelane_deassert(struct rk628 *rk628, uint8_t mipi_id) -{ - rk628_i2c_update_bits(rk628, mipi_id ? CSITX1_DPHY_CTRL : CSITX_DPHY_CTRL, - CSI_DPHY_EN_MASK, 0); - udelay(1); -} - -static inline void mipi_dphy_shutdownz_assert(struct rk628 *rk628) -{ - rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYSHUTDOWNZ, 0); - udelay(1); -} - -static inline void mipi_dphy_shutdownz_deassert(struct rk628 *rk628) -{ - rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYSHUTDOWNZ, - CSI_PHYSHUTDOWNZ); - udelay(1); -} - -static inline void mipi_dphy_rstz_assert(struct rk628 *rk628) -{ - rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYRSTZ, 0); - udelay(1); -} - -static inline void mipi_dphy_rstz_deassert(struct rk628 *rk628) -{ - rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, CSI_PHYRSTZ, - CSI_PHYRSTZ); - udelay(1); -} - -static inline void mipi_dphy_init_hsfreqrange(struct rk628 *rk628, int lane_mbps, uint8_t mipi_id) -{ - const struct { - unsigned long max_lane_mbps; - u8 hsfreqrange; - } hsfreqrange_table[] = { - { 90, 0x00}, { 100, 0x10}, { 110, 0x20}, { 130, 0x01}, - { 140, 0x11}, { 150, 0x21}, { 170, 0x02}, { 180, 0x12}, - { 200, 0x22}, { 220, 0x03}, { 240, 0x13}, { 250, 0x23}, - { 270, 0x04}, { 300, 0x14}, { 330, 0x05}, { 360, 0x15}, - { 400, 0x25}, { 450, 0x06}, { 500, 0x16}, { 550, 0x07}, - { 600, 0x17}, { 650, 0x08}, { 700, 0x18}, { 750, 0x09}, - { 800, 0x19}, { 850, 0x29}, { 900, 0x39}, { 950, 0x0a}, - {1000, 0x1a}, {1050, 0x2a}, {1100, 0x3a}, {1150, 0x0b}, - {1200, 0x1b}, {1250, 0x2b}, {1300, 0x3b}, {1350, 0x0c}, - {1400, 0x1c}, {1450, 0x2c}, {1500, 0x3c} - }; - u8 hsfreqrange; - unsigned int index; - - for (index = 0; index < ARRAY_SIZE(hsfreqrange_table); index++) - if (lane_mbps <= hsfreqrange_table[index].max_lane_mbps) - break; - - if (index == ARRAY_SIZE(hsfreqrange_table)) - --index; - - hsfreqrange = hsfreqrange_table[index].hsfreqrange; - testif_write(rk628, 0x44, HSFREQRANGE(hsfreqrange), mipi_id); -} - -static void __maybe_unused mipi_dphy_init_hsmanual(struct rk628 *rk628, - bool manual, uint8_t mipi_id) -{ - dev_info(rk628->dev, - "mipi dphy%d hs config, manual: %s\n", mipi_id, manual ? "true" : "false"); - //config mipi timing when mipi freq is 1250Mbps - testif_write(rk628, 0x71, - manual ? (HSTX(rk628->mipi_timing[mipi_id].data_prepare) | BIT(7)) : 0, mipi_id); - usleep_range(1500, 2000); - testif_write(rk628, 0x72, - manual ? (HSZERO(rk628->mipi_timing[mipi_id].data_zero) | BIT(6)) : 0, mipi_id); - usleep_range(1500, 2000); - testif_write(rk628, 0x73, - manual ? (HSTX(rk628->mipi_timing[mipi_id].data_trail) | BIT(7)) : 0, mipi_id); - usleep_range(1500, 2000); - testif_write(rk628, 0x61, - manual ? (HSTX(rk628->mipi_timing[mipi_id].clk_prepare) | BIT(7)) : 0, mipi_id); - usleep_range(1500, 2000); - testif_write(rk628, 0x62, - manual ? (HSZERO(rk628->mipi_timing[mipi_id].clk_zero) | BIT(6)) : 0, mipi_id); - usleep_range(1500, 2000); - testif_write(rk628, 0x63, - manual ? (HSTX(rk628->mipi_timing[mipi_id].clk_trail) | BIT(7)) : 0, mipi_id); - usleep_range(1500, 2000); - testif_write(rk628, 0x65, - manual ? (HSPOST(rk628->mipi_timing[mipi_id].clk_post) | BIT(5)) : 0, mipi_id); -} - -static inline int mipi_dphy_reset(struct rk628 *rk628) -{ - u32 val, mask; - int ret; - - rk628_i2c_write(rk628, CSITX_SYS_CTRL0_IMD, 0x1); - if (rk628->version >= RK628F_VERSION) - rk628_i2c_write(rk628, CSITX1_SYS_CTRL0_IMD, 0x1); - mipi_dphy_enablelane_deassert(rk628, 0); - if (rk628->version >= RK628F_VERSION) - mipi_dphy_enablelane_deassert(rk628, 1); - mipi_dphy_shutdownz_assert(rk628); - mipi_dphy_rstz_assert(rk628); - testif_testclr_assert(rk628, 0); - if (rk628->version >= RK628F_VERSION) - testif_testclr_assert(rk628, 1); - - /* Set all REQUEST inputs to zero */ - rk628_i2c_update_bits(rk628, GRF_MIPI_TX0_CON, - FORCETXSTOPMODE_MASK | FORCERXMODE_MASK, - FORCETXSTOPMODE(0) | FORCERXMODE(0)); - if (rk628->version >= RK628F_VERSION) - rk628_i2c_update_bits(rk628, GRF_MIPI_TX1_CON, - FORCETXSTOPMODE_MASK | FORCERXMODE_MASK, - FORCETXSTOPMODE(0) | FORCERXMODE(0)); - udelay(1); - testif_testclr_deassert(rk628, 0); - if (rk628->version >= RK628F_VERSION) - testif_testclr_deassert(rk628, 1); - mipi_dphy_enablelane_assert(rk628, 0); - if (rk628->version >= RK628F_VERSION) - mipi_dphy_enablelane_assert(rk628, 1); - mipi_dphy_shutdownz_deassert(rk628); - mipi_dphy_rstz_deassert(rk628); - rk628_i2c_write(rk628, CSITX_SYS_CTRL0_IMD, 0x0); - if (rk628->version >= RK628F_VERSION) - rk628_i2c_write(rk628, CSITX1_SYS_CTRL0_IMD, 0x0); - usleep_range(10000, 11000); - - mask = STOPSTATE_CLK | STOPSTATE_LANE0; - - ret = regmap_read_poll_timeout(rk628->regmap[RK628_DEV_CSI], - CSITX_CSITX_STATUS1, - val, (val & mask) == mask, - 0, 1000); - if (ret < 0) - dev_err(rk628->dev, "csi0 lane module is not in stop state, val: 0x%x\n", val); - - if (rk628->version >= RK628F_VERSION) { - ret = regmap_read_poll_timeout(rk628->regmap[RK628_DEV_CSI1], - CSITX1_CSITX_STATUS1, - val, (val & mask) == mask, - 0, 1000); - if (ret < 0) - dev_err(rk628->dev, - "csi1 lane module is not in stop state, val: 0x%x\n", val); - } - - return 0; -} +void rk628_testif_testclr_deassert(struct rk628 *rk628, uint8_t mipi_id); +void rk628_testif_testclr_assert(struct rk628 *rk628, uint8_t mipi_id); +u8 rk628_testif_write(struct rk628 *rk628, u8 test_code, u8 test_data, uint8_t mipi_id); +u8 rk628_testif_read(struct rk628 *rk628, u8 test_code, uint8_t mipi_id); +void rk628_mipi_dphy_init_hsfreqrange(struct rk628 *rk628, int lane_mbps, uint8_t mipi_id); +void rk628_mipi_dphy_init_hsmanual(struct rk628 *rk628, bool manual, uint8_t mipi_id); +int rk628_mipi_dphy_reset(struct rk628 *rk628); #endif