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 61276dc444969..aab961daf7c7d 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,11 +269,19 @@ 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); } 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 +365,12 @@ 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; + + if (dsi->platform_ops && dsi->platform_ops->enable) + dsi->platform_ops->enable(dsi); + mode = &bridge->encoder->crtc->state->adjusted_mode; nlanes = output->dev->lanes; @@ -480,6 +498,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 +621,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 +725,7 @@ static ssize_t cdns_dsi_transfer(struct mipi_dsi_host *host, } out: + pm_runtime_put(host->dev); return ret; } @@ -728,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; } @@ -755,11 +782,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); @@ -792,7 +814,7 @@ static int cdns_dsi_drm_probe(struct platform_device *pdev) goto err_disable_pclk; } - writel(1, dsi->wrap_regs + 4); + 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); @@ -825,15 +847,34 @@ 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; + 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_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); + err_disable_pclk: clk_disable_unprepare(dsi->dsi_p_clk); @@ -845,13 +886,22 @@ 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); + + if (dsi->platform_ops && dsi->platform_ops->exit) + dsi->platform_ops->exit(dsi); + + pm_runtime_disable(&pdev->dev); return 0; } 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 e706143f29f16..37568b547fbed 100644 --- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.h @@ -439,10 +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; - void __iomem *wrap_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 */ diff --git a/drivers/phy/cadence/cdns-dphy.c b/drivers/phy/cadence/cdns-dphy.c index 60388551f6975..68b871111e9d8 100644 --- a/drivers/phy/cadence/cdns-dphy.c +++ b/drivers/phy/cadence/cdns-dphy.c @@ -90,15 +90,17 @@ #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) - +#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; @@ -150,13 +152,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}, @@ -164,7 +166,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, @@ -203,9 +215,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 +255,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, @@ -289,11 +307,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) @@ -322,6 +361,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; } @@ -338,7 +385,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 +394,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; } @@ -374,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, @@ -384,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. */ @@ -411,11 +488,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; } @@ -546,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) { @@ -693,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);