From f4d97b748cb8de2eb36a25c72fbbaacf28a06f9a Mon Sep 17 00:00:00 2001 From: Rahul T R Date: Wed, 2 Nov 2022 20:05:39 +0530 Subject: [PATCH 1/7] Revert "HACK: phy: cdns-dphy: DPHY wrapper related changes" This reverts commit feab9c31074a4d4710be643baa7e5876695c3d61. --- drivers/phy/cadence/cdns-dphy.c | 54 +++++++++++---------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c index 60388551f6975..8105d4343cf54 100644 --- a/drivers/phy/cadence/cdns-dphy.c +++ b/drivers/phy/cadence/cdns-dphy.c @@ -21,7 +21,6 @@ #define REG_WAKEUP_TIME_NS 800 #define DPHY_PLL_RATE_HZ 108000000 -#define POLL_TIMEOUT_US 1000 /* DPHY registers */ #define DPHY_PMA_CMN(reg) (reg) @@ -90,16 +89,6 @@ #define DPHY_LANES_MIN 1 #define DPHY_LANES_MAX 4 -#define DPHY_TX_PLL_CTRL 0xF04 -#define DPHY_TX_STATUS 0xF08 -#define DPHY_TX_RST_CTRL 0xF0C -#define DPHY_TX_PSM_FREQ 0xF10 - -#define IPDIV_WIZ GENMASK(4, 0) -#define OPDIV_WIZ GENMASK(13, 8) -#define FBDIV_WIZ GENMASK(25, 16) - - struct cdns_dphy_cfg { u8 pll_ipdiv; u8 pll_opdiv; @@ -203,9 +192,6 @@ static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, cfg->pll_fbdiv = DIV_ROUND_UP_ULL(dlane_bps * 2 * cfg->pll_opdiv * cfg->pll_ipdiv, pll_ref_hz); - dphy->cfg.pll_ipdiv = cfg->pll_ipdiv; - dphy->cfg.pll_opdiv = cfg->pll_opdiv; - dphy->cfg.pll_fbdiv = cfg->pll_fbdiv; return 0; } @@ -246,25 +232,34 @@ static unsigned long cdns_dphy_get_wakeup_time_ns(struct cdns_dphy *dphy) static unsigned long cdns_dphy_ref_get_wakeup_time_ns(struct cdns_dphy *dphy) { - /* Set minimum wakeup time (1000 us == 1000000 ns). */ - return 1000000; + /* Default wakeup time is 800 ns (in a simulated environment). */ + return 800; } static void cdns_dphy_ref_set_pll_cfg(struct cdns_dphy *dphy, const struct cdns_dphy_cfg *cfg) { - writel(DPHY_CMN_PWM_HIGH(0xE) | DPHY_CMN_PWM_LOW(0x1FF) | + u32 fbdiv_low, fbdiv_high; + + fbdiv_low = (cfg->pll_fbdiv / 4) - 2; + fbdiv_high = cfg->pll_fbdiv - fbdiv_low - 2; + + writel(DPHY_CMN_IPDIV_FROM_REG | DPHY_CMN_OPDIV_FROM_REG | + DPHY_CMN_IPDIV(cfg->pll_ipdiv) | + DPHY_CMN_OPDIV(cfg->pll_opdiv), + dphy->regs + DPHY_CMN_OPIPDIV); + writel(DPHY_CMN_FBDIV_FROM_REG | + DPHY_CMN_FBDIV_VAL(fbdiv_low, fbdiv_high), + dphy->regs + DPHY_CMN_FBDIV); + writel(DPHY_CMN_PWM_HIGH(6) | DPHY_CMN_PWM_LOW(0x101) | DPHY_CMN_PWM_DIV(0x8), dphy->regs + DPHY_CMN_PWM); } static void cdns_dphy_ref_set_psm_div(struct cdns_dphy *dphy, u8 div) { - unsigned long psm_clk_hz = clk_get_rate(dphy->psm_clk); - - /* The signal must be driven such a that internal - * freq of divided psm clock is 1MHZ*/ - writel(psm_clk_hz/1000000, dphy->regs + DPHY_TX_PSM_FREQ); + writel(DPHY_PSM_CFG_FROM_REG | DPHY_PSM_CLK_DIV(div), + dphy->regs + DPHY_PSM_CFG); } static int cdns_dphy_tx_config_from_opts(struct phy *phy, @@ -338,7 +333,6 @@ static int cdns_dphy_tx_validate(struct cdns_dphy *dphy, enum phy_mode mode, static int cdns_dphy_tx_power_on(struct cdns_dphy *dphy) { - u32 status; if (!dphy->psm_clk || !dphy->pll_ref_clk) return -EINVAL; @@ -348,20 +342,6 @@ static int cdns_dphy_tx_power_on(struct cdns_dphy *dphy) /* Start TX state machine. */ writel(DPHY_CMN_SSM_EN | DPHY_CMN_TX_MODE_EN, dphy->regs + DPHY_CMN_SSM); - writel(0x00000229 , dphy->regs + DPHY_CMN_SSM); // this value is required for pll lock - /* Lane reset */ //Required for PLL LOCK - writel(0x80000000, dphy->regs + DPHY_TX_RST_CTRL); - - writel((FIELD_PREP(IPDIV_WIZ, dphy->cfg.pll_ipdiv) | FIELD_PREP(OPDIV_WIZ, dphy->cfg.pll_opdiv) | - FIELD_PREP(FBDIV_WIZ, dphy->cfg.pll_fbdiv)), dphy->regs + DPHY_TX_PLL_CTRL); - - writel(0x14A, dphy->regs + DPHY_BAND_CFG); - - readl_poll_timeout(dphy->regs + DPHY_TX_PLL_CTRL, status, - (status & 0x80000000), 0, POLL_TIMEOUT_US); - - readl_poll_timeout(dphy->regs + DPHY_TX_STATUS, status, - (status & 0x80000000), 0, POLL_TIMEOUT_US); return 0; } From a690ec0e099efe8f021f796c9f721b4732af2506 Mon Sep 17 00:00:00 2001 From: Rahul T R Date: Wed, 2 Nov 2022 20:05:56 +0530 Subject: [PATCH 2/7] Revert "HACK: drm/bridge: cdns-dsi: Remove PM runtime calls" This reverts commit 11b74d8cada0f0bc600ac706e9741711d48701e5. --- .../gpu/drm/bridge/cadence/cdns-dsi-core.c | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index 61276dc444969..b898bd45ee292 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -265,11 +265,15 @@ static void cdns_dsi_bridge_disable(struct drm_bridge *bridge) val = readl(dsi->regs + MCTL_MAIN_EN) & ~IF_EN(input->id); writel(val, dsi->regs + MCTL_MAIN_EN); + pm_runtime_put(dsi->base.dev); } static void cdns_dsi_bridge_post_disable(struct drm_bridge *bridge) { - return; + struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); + struct cdns_dsi *dsi = input_to_dsi(input); + + pm_runtime_put(dsi->base.dev); } static void cdns_dsi_hs_init(struct cdns_dsi *dsi) @@ -353,6 +357,9 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge) u32 tmp, reg_wakeup, div; int nlanes; + if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) + return; + mode = &bridge->encoder->crtc->state->adjusted_mode; nlanes = output->dev->lanes; @@ -480,6 +487,9 @@ static void cdns_dsi_bridge_pre_enable(struct drm_bridge *bridge) struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); struct cdns_dsi *dsi = input_to_dsi(input); + if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) + return; + cdns_dsi_init_link(dsi); cdns_dsi_hs_init(dsi); } @@ -600,6 +610,10 @@ static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host, struct mipi_dsi_packet packet; int ret, i, tx_len, rx_len; + ret = pm_runtime_resume_and_get(host->dev); + if (ret < 0) + return ret; + cdns_dsi_init_link(dsi); ret = mipi_dsi_create_packet(&packet, msg); @@ -700,6 +714,7 @@ static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host, } out: + pm_runtime_put(host->dev); return ret; } @@ -825,15 +840,21 @@ static int cdns_dsi_drm_probe(struct platform_device *pdev) if (ret) goto err_disable_pclk; + pm_runtime_enable(&pdev->dev); dsi->base.dev = &pdev->dev; dsi->base.ops = &cdns_dsi_ops; ret = mipi_dsi_host_register(&dsi->base); + if (ret) + goto err_disable_runtime_pm; clk_disable_unprepare(dsi->dsi_p_clk); return 0; +err_disable_runtime_pm: + pm_runtime_disable(&pdev->dev); + err_disable_pclk: clk_disable_unprepare(dsi->dsi_p_clk); @@ -845,7 +866,7 @@ static int cdns_dsi_drm_remove(struct platform_device *pdev) struct cdns_dsi *dsi = platform_get_drvdata(pdev); mipi_dsi_host_unregister(&dsi->base); - //pm_runtime_disable(&pdev->dev); + pm_runtime_disable(&pdev->dev); return 0; } From a8ca285e9db83286257f850e4782459d98b4d58c Mon Sep 17 00:00:00 2001 From: Rahul T R Date: Wed, 2 Nov 2022 20:06:11 +0530 Subject: [PATCH 3/7] Revert "drm/bridge: cdns-dsi: Set input for DPI0" This reverts commit 33d13f281cb96f6613fbca6ca633a3bf2d6acc35. --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 7 ------- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h | 1 - 2 files changed, 8 deletions(-) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index b898bd45ee292..afb7e7aaf8426 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -770,11 +770,6 @@ static int cdns_dsi_drm_probe(struct platform_device *pdev) if (IS_ERR(dsi->regs)) return PTR_ERR(dsi->regs); - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); - dsi->wrap_regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(dsi->regs)) - return PTR_ERR(dsi->regs); - dsi->dsi_p_clk = devm_clk_get(&pdev->dev, "dsi_p_clk"); if (IS_ERR(dsi->dsi_p_clk)) return PTR_ERR(dsi->dsi_p_clk); @@ -807,8 +802,6 @@ static int cdns_dsi_drm_probe(struct platform_device *pdev) goto err_disable_pclk; } - writel(1, dsi->wrap_regs + 4); - val = readl(dsi->regs + IP_CONF); dsi->direct_cmd_fifo_depth = 1 << (DIRCMD_FIFO_DEPTH(val) + 2); dsi->rx_fifo_depth = RX_FIFO_DEPTH(val); diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h index e706143f29f16..65cc77f19b39c 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h @@ -442,7 +442,6 @@ struct cdns_dsi_input { struct cdns_dsi { struct mipi_dsi_host base; void __iomem *regs; - void __iomem *wrap_regs; struct cdns_dsi_input input; struct cdns_dsi_output output; unsigned int direct_cmd_fifo_depth; From 9219c6ac0783d0bb8cabd77272d20590d373705c Mon Sep 17 00:00:00 2001 From: Rahul T R Date: Wed, 2 Nov 2022 20:06:22 +0530 Subject: [PATCH 4/7] Revert "Revert "drm/bridge: cdns-dsi: Add support for J721E wrapper"" This reverts commit 1bb68a9461a5725d7f3a5e4ad45344d73e94b417. --- drivers/gpu/drm/bridge/cadence/Kconfig | 10 ++++ drivers/gpu/drm/bridge/cadence/Makefile | 1 + .../gpu/drm/bridge/cadence/cdns-dsi-core.c | 37 +++++++++++++- .../gpu/drm/bridge/cadence/cdns-dsi-core.h | 13 +++++ .../gpu/drm/bridge/cadence/cdns-dsi-j721e.c | 51 +++++++++++++++++++ .../gpu/drm/bridge/cadence/cdns-dsi-j721e.h | 18 +++++++ 6 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.c create mode 100644 drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.h diff --git a/drivers/gpu/drm/bridge/cadence/Kconfig b/drivers/gpu/drm/bridge/cadence/Kconfig index 3cee94f1c5102..b0d2c918c6279 100644 --- a/drivers/gpu/drm/bridge/cadence/Kconfig +++ b/drivers/gpu/drm/bridge/cadence/Kconfig @@ -33,3 +33,13 @@ config DRM_CDNS_DSI help Support Cadence DPI to DSI bridge. This is an internal bridge and is meant to be directly embedded in a SoC. + +if DRM_CDNS_DSI + +config DRM_CDNS_DSI_J721E + bool "J721E Cadence DPI/DSI wrapper support" + default y + help + Support J721E Cadence DPI/DSI wrapper. This wrapper adds + support to select which DPI input to use for the bridge. +endif diff --git a/drivers/gpu/drm/bridge/cadence/Makefile b/drivers/gpu/drm/bridge/cadence/Makefile index b524a7ce20287..0e54764a7e636 100644 --- a/drivers/gpu/drm/bridge/cadence/Makefile +++ b/drivers/gpu/drm/bridge/cadence/Makefile @@ -4,3 +4,4 @@ cdns-mhdp8546-y := cdns-mhdp8546-core.o cdns-mhdp8546-$(CONFIG_DRM_CDNS_MHDP8546_J721E) += cdns-mhdp8546-j721e.o obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o cdns-dsi-y := cdns-dsi-core.o +cdns-dsi-$(CONFIG_DRM_CDNS_DSI_J721E) += cdns-dsi-j721e.o diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index afb7e7aaf8426..cce51ee51dfd5 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -15,12 +15,16 @@ #include #include #include +#include #include #include #include #include #include "cdns-dsi-core.h" +#ifdef CONFIG_DRM_CDNS_DSI_J721E +#include "cdns-dsi-j721e.h" +#endif static inline struct cdns_dsi *input_to_dsi(struct cdns_dsi_input *input) { @@ -265,6 +269,10 @@ static void cdns_dsi_bridge_disable(struct drm_bridge *bridge) val = readl(dsi->regs + MCTL_MAIN_EN) & ~IF_EN(input->id); writel(val, dsi->regs + MCTL_MAIN_EN); + + if (dsi->platform_ops && dsi->platform_ops->disable) + dsi->platform_ops->disable(dsi); + pm_runtime_put(dsi->base.dev); } @@ -360,6 +368,9 @@ static void cdns_dsi_bridge_enable(struct drm_bridge *bridge) if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) return; + if (dsi->platform_ops && dsi->platform_ops->enable) + dsi->platform_ops->enable(dsi); + mode = &bridge->encoder->crtc->state->adjusted_mode; nlanes = output->dev->lanes; @@ -802,6 +813,8 @@ static int cdns_dsi_drm_probe(struct platform_device *pdev) goto err_disable_pclk; } + dsi->platform_ops = of_device_get_match_data(&pdev->dev); + val = readl(dsi->regs + IP_CONF); dsi->direct_cmd_fifo_depth = 1 << (DIRCMD_FIFO_DEPTH(val) + 2); dsi->rx_fifo_depth = RX_FIFO_DEPTH(val); @@ -837,14 +850,27 @@ static int cdns_dsi_drm_probe(struct platform_device *pdev) dsi->base.dev = &pdev->dev; dsi->base.ops = &cdns_dsi_ops; + if (dsi->platform_ops && dsi->platform_ops->init) { + ret = dsi->platform_ops->init(dsi); + if (ret != 0) { + dev_err(&pdev->dev, "platform initialization failed: %d\n", + ret); + goto err_disable_runtime_pm; + } + } + ret = mipi_dsi_host_register(&dsi->base); if (ret) - goto err_disable_runtime_pm; + goto err_deinit_platform; clk_disable_unprepare(dsi->dsi_p_clk); return 0; +err_deinit_platform: + if (dsi->platform_ops && dsi->platform_ops->exit) + dsi->platform_ops->exit(dsi); + err_disable_runtime_pm: pm_runtime_disable(&pdev->dev); @@ -859,6 +885,10 @@ static int cdns_dsi_drm_remove(struct platform_device *pdev) struct cdns_dsi *dsi = platform_get_drvdata(pdev); mipi_dsi_host_unregister(&dsi->base); + + if (dsi->platform_ops && dsi->platform_ops->exit) + dsi->platform_ops->exit(dsi); + pm_runtime_disable(&pdev->dev); return 0; @@ -866,6 +896,11 @@ static int cdns_dsi_drm_remove(struct platform_device *pdev) static const struct of_device_id cdns_dsi_of_match[] = { { .compatible = "cdns,dsi" }, +#ifdef CONFIG_DRM_CDNS_DSI_J721E + { .compatible = "ti,j721e-dsi", + .data = &dsi_ti_j721e_ops, + }, +#endif { }, }; MODULE_DEVICE_TABLE(of, cdns_dsi_of_match); diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h index 65cc77f19b39c..37568b547fbed 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h @@ -439,9 +439,22 @@ struct cdns_dsi_input { struct drm_bridge bridge; }; +struct cdns_dsi; + +struct dsi_platform_ops { + int (*init)(struct cdns_dsi *dsi); + void (*exit)(struct cdns_dsi *dsi); + void (*enable)(struct cdns_dsi *dsi); + void (*disable)(struct cdns_dsi *dsi); +}; + struct cdns_dsi { struct mipi_dsi_host base; void __iomem *regs; +#ifdef CONFIG_DRM_CDNS_DSI_J721E + void __iomem *j721e_regs; +#endif + const struct dsi_platform_ops *platform_ops; struct cdns_dsi_input input; struct cdns_dsi_output output; unsigned int direct_cmd_fifo_depth; diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.c new file mode 100644 index 0000000000000..b5216acb333e5 --- /dev/null +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * TI j721e Cadence DSI wrapper + * + * Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com/ + * Author: Rahul T R + */ + +#include +#include + +#include "cdns-dsi-j721e.h" + +#define DSI_WRAP_REVISION 0x0 +#define DSI_WRAP_DPI_CONTROL 0x4 +#define DSI_WRAP_DSC_CONTROL 0x8 +#define DSI_WRAP_DPI_SECURE 0xc +#define DSI_WRAP_DSI_0_ASF_STATUS 0x10 + +#define DSI_WRAP_DPI_0_EN BIT(0) +#define DSI_WRAP_DSI2_MUX_SEL BIT(4) + +static int cdns_dsi_j721e_init(struct cdns_dsi *dsi) +{ + struct platform_device *pdev = to_platform_device(dsi->base.dev); + + dsi->j721e_regs = devm_platform_ioremap_resource(pdev, 1); + return PTR_ERR_OR_ZERO(dsi->j721e_regs); +} + +static void cdns_dsi_j721e_enable(struct cdns_dsi *dsi) +{ + /* + * Enable DPI0 as its input. DSS0 DPI2 is connected + * to DSI DPI0. This is the only supported configuration on + * J721E. + */ + writel(DSI_WRAP_DPI_0_EN, dsi->j721e_regs + DSI_WRAP_DPI_CONTROL); +} + +static void cdns_dsi_j721e_disable(struct cdns_dsi *dsi) +{ + /* Put everything to defaults */ + writel(0, dsi->j721e_regs + DSI_WRAP_DPI_CONTROL); +} + +const struct dsi_platform_ops dsi_ti_j721e_ops = { + .init = cdns_dsi_j721e_init, + .enable = cdns_dsi_j721e_enable, + .disable = cdns_dsi_j721e_disable, +}; diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.h b/drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.h new file mode 100644 index 0000000000000..01f3dbd92db25 --- /dev/null +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-j721e.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * TI j721e Cadence DSI wrapper + * + * Copyright (C) 2022 Texas Instruments Incorporated - http://www.ti.com/ + * Author: Rahul T R + */ + +#ifndef CDNS_DSI_J721E_H +#define CDNS_DSI_J721E_H + +#include "cdns-dsi-core.h" + +struct dsi_platform_ops; + +extern const struct dsi_platform_ops dsi_ti_j721e_ops; + +#endif /* !CDNS_DSI_J721E_H */ From 03a876b713296617e6981382e329437f93df829d Mon Sep 17 00:00:00 2001 From: Rahul T R Date: Wed, 2 Nov 2022 20:06:42 +0530 Subject: [PATCH 5/7] Revert "Revert "phy: cdns-dphy: Add band config for dphy tx"" This reverts commit 4d8f9a9a6c94643947f50e52e53e8a3f5ecdc192. --- drivers/phy/cadence/cdns-dphy.c | 53 ++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c index 8105d4343cf54..0fa302c557a8c 100644 --- a/drivers/phy/cadence/cdns-dphy.c +++ b/drivers/phy/cadence/cdns-dphy.c @@ -139,13 +139,13 @@ struct cdns_dphy_driver_data { const struct cdns_dphy_ops *rx; }; -struct cdns_dphy_rx_band { +struct cdns_dphy_band { unsigned int min_rate; unsigned int max_rate; }; /* Order of bands is important since the index is the band number. */ -struct cdns_dphy_rx_band bands[] = { +struct cdns_dphy_band rx_bands[] = { {80, 100}, {100, 120}, {120, 160}, {160, 200}, {200, 240}, {240, 280}, {280, 320}, {320, 360}, {360, 400}, {400, 480}, {480, 560}, {560, 640}, {640, 720}, {720, 800}, {800, 880}, @@ -153,7 +153,17 @@ struct cdns_dphy_rx_band bands[] = { {1750, 2000}, {2000, 2250}, {2250, 2500} }; -int num_bands = ARRAY_SIZE(bands); +int num_rx_bands = ARRAY_SIZE(rx_bands); + +struct cdns_dphy_band tx_bands[] = { + {80, 100}, {100, 120}, {120, 160}, {160, 200}, {200, 240}, + {240, 320}, {320, 390}, {390, 450}, {450, 510}, {510, 560}, + {560, 640}, {640, 690}, {690, 770}, {770, 870}, {870, 950}, + {950, 1000}, {1000, 1200}, {1200, 1400}, {1400, 1600}, {1600, 1800}, + {1800, 2000}, {2000, 2200}, {2200, 2500} +}; + +int num_tx_bands = ARRAY_SIZE(tx_bands); static int cdns_dsi_get_dphy_pll_cfg(struct cdns_dphy *dphy, struct cdns_dphy_cfg *cfg, @@ -284,11 +294,32 @@ static int cdns_dphy_tx_config_from_opts(struct phy *phy, return 0; } +static int cdns_dphy_tx_get_band_ctrl(unsigned long hs_clk_rate) +{ + unsigned int rate; + int i; + + rate = hs_clk_rate / 1000000UL; + + if (rate < tx_bands[0].min_rate || rate >= tx_bands[num_tx_bands - 1].max_rate) + return -EOPNOTSUPP; + + for (i = 0; i < num_tx_bands; i++) { + if (rate >= tx_bands[i].min_rate && rate < tx_bands[i].max_rate) + return i; + } + + /* Unreachable. */ + WARN(1, "Reached unreachable code."); + return -EINVAL; +} + static int cdns_dphy_tx_configure(struct cdns_dphy *dphy, union phy_configure_opts *opts) { struct cdns_dphy_cfg cfg = { 0 }; - int ret; + int ret, band_ctrl; + unsigned int reg; ret = cdns_dphy_tx_config_from_opts(dphy->phy, &opts->mipi_dphy, &cfg); if (ret) @@ -317,6 +348,14 @@ static int cdns_dphy_tx_configure(struct cdns_dphy *dphy, */ cdns_dphy_set_pll_cfg(dphy, &cfg); + band_ctrl = cdns_dphy_tx_get_band_ctrl(opts->mipi_dphy.hs_clk_rate); + if (band_ctrl < 0) + return band_ctrl; + + reg = FIELD_PREP(DPHY_BAND_CFG_LEFT_BAND, band_ctrl) | + FIELD_PREP(DPHY_BAND_CFG_RIGHT_BAND, band_ctrl); + writel(reg, dphy->regs + DPHY_BAND_CFG); + return 0; } @@ -391,11 +430,11 @@ static int cdns_dphy_rx_get_band_ctrl(unsigned long hs_clk_rate) /* Since CSI-2 clock is DDR, the bit rate is twice the clock rate. */ rate *= 2; - if (rate < bands[0].min_rate || rate >= bands[num_bands - 1].max_rate) + if (rate < rx_bands[0].min_rate || rate >= rx_bands[num_rx_bands - 1].max_rate) return -EOPNOTSUPP; - for (i = 0; i < num_bands; i++) { - if (rate >= bands[i].min_rate && rate < bands[i].max_rate) + for (i = 0; i < num_rx_bands; i++) { + if (rate >= rx_bands[i].min_rate && rate < rx_bands[i].max_rate) return i; } From 2a0f8a60f65561e95df7d6a599f7241ec1188e0a Mon Sep 17 00:00:00 2001 From: Rahul T R Date: Wed, 2 Nov 2022 20:06:55 +0530 Subject: [PATCH 6/7] Revert "Revert "phy: cdns-dphy: Add support for DPHY TX on J721e"" This reverts commit 575642d40fa93364bc7af5882ce044dee98aa44d. --- drivers/phy/cadence/cdns-dphy.c | 65 ++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c index 0fa302c557a8c..68b871111e9d8 100644 --- a/drivers/phy/cadence/cdns-dphy.c +++ b/drivers/phy/cadence/cdns-dphy.c @@ -21,6 +21,7 @@ #define REG_WAKEUP_TIME_NS 800 #define DPHY_PLL_RATE_HZ 108000000 +#define POLL_TIMEOUT_US 1000 /* DPHY registers */ #define DPHY_PMA_CMN(reg) (reg) @@ -89,6 +90,18 @@ #define DPHY_LANES_MIN 1 #define DPHY_LANES_MAX 4 +#define DPHY_TX_J721E_WIZ_PLL_CTRL 0xF04 +#define DPHY_TX_J721E_WIZ_STATUS 0xF08 +#define DPHY_TX_J721E_WIZ_RST_CTRL 0xF0C +#define DPHY_TX_J721E_WIZ_PSM_FREQ 0xF10 + +#define DPHY_TX_J721E_WIZ_IPDIV GENMASK(4, 0) +#define DPHY_TX_J721E_WIZ_OPDIV GENMASK(13, 8) +#define DPHY_TX_J721E_WIZ_FBDIV GENMASK(25, 16) +#define DPHY_TX_J721E_WIZ_LANE_RSTB BIT(31) +#define DPHY_TX_WIZ_PLL_LOCK BIT(31) +#define DPHY_TX_WIZ_O_CMN_READY BIT(31) + struct cdns_dphy_cfg { u8 pll_ipdiv; u8 pll_opdiv; @@ -393,6 +406,41 @@ static int cdns_dphy_tx_power_off(struct cdns_dphy *dphy) return 0; } +static unsigned long cdns_dphy_j721e_get_wakeup_time_ns(struct cdns_dphy *dphy) +{ + return 1000000; +} + +static void cdns_dphy_j721e_set_pll_cfg(struct cdns_dphy *dphy, + const struct cdns_dphy_cfg *cfg) +{ + u32 status; + + writel(DPHY_CMN_PWM_HIGH(6) | DPHY_CMN_PWM_LOW(0x101) | + DPHY_CMN_PWM_DIV(0x8), + dphy->regs + DPHY_CMN_PWM); + + writel((FIELD_PREP(DPHY_TX_J721E_WIZ_IPDIV, cfg->pll_ipdiv) | + FIELD_PREP(DPHY_TX_J721E_WIZ_OPDIV, cfg->pll_opdiv) | + FIELD_PREP(DPHY_TX_J721E_WIZ_FBDIV, cfg->pll_fbdiv)), + dphy->regs + DPHY_TX_J721E_WIZ_PLL_CTRL); + + writel(DPHY_TX_J721E_WIZ_LANE_RSTB, + dphy->regs + DPHY_TX_J721E_WIZ_RST_CTRL); + + readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_PLL_CTRL, status, + (status & DPHY_TX_WIZ_PLL_LOCK), 0, POLL_TIMEOUT_US); + + readl_poll_timeout(dphy->regs + DPHY_TX_J721E_WIZ_STATUS, status, + (status & DPHY_TX_WIZ_O_CMN_READY), 0, + POLL_TIMEOUT_US); +} + +static void cdns_dphy_j721e_set_psm_div(struct cdns_dphy *dphy, u8 div) +{ + writel(div, dphy->regs + DPHY_TX_J721E_WIZ_PSM_FREQ); +} + static const struct cdns_dphy_ops tx_ref_dphy_ops = { .power_on = cdns_dphy_tx_power_on, .power_off = cdns_dphy_tx_power_off, @@ -403,6 +451,16 @@ static const struct cdns_dphy_ops tx_ref_dphy_ops = { .set_psm_div = cdns_dphy_ref_set_psm_div, }; +static const struct cdns_dphy_ops tx_j721e_dphy_ops = { + .power_on = cdns_dphy_tx_power_on, + .power_off = cdns_dphy_tx_power_off, + .validate = cdns_dphy_tx_validate, + .configure = cdns_dphy_tx_configure, + .get_wakeup_time_ns = cdns_dphy_j721e_get_wakeup_time_ns, + .set_pll_cfg = cdns_dphy_j721e_set_pll_cfg, + .set_psm_div = cdns_dphy_j721e_set_psm_div, +}; + static int cdns_dphy_rx_power_on(struct cdns_dphy *dphy) { /* Start RX state machine. */ @@ -565,6 +623,11 @@ static const struct cdns_dphy_driver_data ref_dphy_ops = { .rx = &rx_ref_dphy_ops, }; +static const struct cdns_dphy_driver_data j721e_dphy_ops = { + .tx = &tx_j721e_dphy_ops, + .rx = &rx_ref_dphy_ops, +}; + static int cdns_dphy_validate(struct phy *phy, enum phy_mode mode, int submode, union phy_configure_opts *opts) { @@ -712,7 +775,7 @@ static int cdns_dphy_remove(struct platform_device *pdev) static const struct of_device_id cdns_dphy_of_match[] = { { .compatible = "cdns,dphy", .data = &ref_dphy_ops }, - { .compatible = "ti,j721e-dphy", .data = &ref_dphy_ops }, + { .compatible = "ti,j721e-dphy", .data = &j721e_dphy_ops }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, cdns_dphy_of_match); From 54b48d537ffd192085b700cdf70c1654d2f27a8a Mon Sep 17 00:00:00 2001 From: Rahul T R Date: Tue, 15 Nov 2022 16:35:44 +0530 Subject: [PATCH 7/7] drm/bridge: cdns-dsi: Fix issue with phy init Phy is not being initialized after suspend resume. Fix this by setting phy_initialized flag to false in suspend callback Upstream Link: https://lore.kernel.org/all/20221115083918.23192-1-r-ravikumar@ti.com/ Signed-off-by: Rahul T R --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c index cce51ee51dfd5..aab961daf7c7d 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -754,6 +754,7 @@ static int __maybe_unused cdns_dsi_suspend(struct device *dev) clk_disable_unprepare(dsi->dsi_p_clk); reset_control_assert(dsi->dsi_p_rst); dsi->link_initialized = false; + dsi->phy_initialized = false; return 0; }