Message ID | 20250403033748.245007-4-andyshrk@163.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Add support for RK3588 DisplayPort Controller | expand |
Hi Andy, kernel test robot noticed the following build errors: [auto build test ERROR on rockchip/for-next] [also build test ERROR on robh/for-next drm-exynos/exynos-drm-next linus/master v6.14 next-20250404] [cannot apply to drm/drm-next drm-intel/for-linux-next drm-intel/for-linux-next-fixes drm-misc/drm-misc-next drm-tip/drm-tip] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Andy-Yan/dt-bindings-display-rockchip-Add-schema-for-RK3588-DPTX-Controller/20250403-114203 base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next patch link: https://lore.kernel.org/r/20250403033748.245007-4-andyshrk%40163.com patch subject: [PATCH v3 3/9] drm/rockchip: Add RK3588 DPTX output support config: s390-allmodconfig (https://download.01.org/0day-ci/archive/20250404/202504041655.rA3EV7B8-lkp@intel.com/config) compiler: clang version 18.1.8 (https://github.com/llvm/llvm-project 3b5b5c1ec4a3095ab096dd780e84d7ab81f3d7ff) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250404/202504041655.rA3EV7B8-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202504041655.rA3EV7B8-lkp@intel.com/ All errors (new ones prefixed by >>): >> drivers/gpu/drm/bridge/synopsys/dw-dp.c:1599:3: error: call to undeclared function 'drm_dp_link_power_down'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 1599 | drm_dp_link_power_down(&dp->aux, dp->link.revision); | ^ >> drivers/gpu/drm/bridge/synopsys/dw-dp.c:1617:8: error: call to undeclared function 'drm_dp_link_power_up'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 1617 | ret = drm_dp_link_power_up(&dp->aux, dp->link.revision); | ^ >> drivers/gpu/drm/bridge/synopsys/dw-dp.c:1790:19: error: incompatible function pointer types initializing 'void (*)(struct drm_bridge *, struct drm_bridge_state *)' with an expression of type 'void (struct drm_bridge *, struct drm_atomic_state *)' [-Wincompatible-function-pointer-types] 1790 | .atomic_enable = dw_dp_bridge_atomic_enable, | ^~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/bridge/synopsys/dw-dp.c:1791:20: error: incompatible function pointer types initializing 'void (*)(struct drm_bridge *, struct drm_bridge_state *)' with an expression of type 'void (struct drm_bridge *, struct drm_atomic_state *)' [-Wincompatible-function-pointer-types] 1791 | .atomic_disable = dw_dp_bridge_atomic_disable, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ 4 errors generated. vim +1790 drivers/gpu/drm/bridge/synopsys/dw-dp.c d366451bed980ac Andy Yan 2025-04-03 1593 d366451bed980ac Andy Yan 2025-04-03 1594 static void dw_dp_link_disable(struct dw_dp *dp) d366451bed980ac Andy Yan 2025-04-03 1595 { d366451bed980ac Andy Yan 2025-04-03 1596 struct dw_dp_link *link = &dp->link; d366451bed980ac Andy Yan 2025-04-03 1597 d366451bed980ac Andy Yan 2025-04-03 1598 if (dw_dp_hpd_detect(dp)) d366451bed980ac Andy Yan 2025-04-03 @1599 drm_dp_link_power_down(&dp->aux, dp->link.revision); d366451bed980ac Andy Yan 2025-04-03 1600 d366451bed980ac Andy Yan 2025-04-03 1601 dw_dp_phy_xmit_enable(dp, 0); d366451bed980ac Andy Yan 2025-04-03 1602 d366451bed980ac Andy Yan 2025-04-03 1603 phy_power_off(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1604 d366451bed980ac Andy Yan 2025-04-03 1605 link->train.clock_recovered = false; d366451bed980ac Andy Yan 2025-04-03 1606 link->train.channel_equalized = false; d366451bed980ac Andy Yan 2025-04-03 1607 } d366451bed980ac Andy Yan 2025-04-03 1608 d366451bed980ac Andy Yan 2025-04-03 1609 static int dw_dp_link_enable(struct dw_dp *dp) d366451bed980ac Andy Yan 2025-04-03 1610 { d366451bed980ac Andy Yan 2025-04-03 1611 int ret; d366451bed980ac Andy Yan 2025-04-03 1612 d366451bed980ac Andy Yan 2025-04-03 1613 ret = phy_power_on(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1614 if (ret) d366451bed980ac Andy Yan 2025-04-03 1615 return ret; d366451bed980ac Andy Yan 2025-04-03 1616 d366451bed980ac Andy Yan 2025-04-03 @1617 ret = drm_dp_link_power_up(&dp->aux, dp->link.revision); d366451bed980ac Andy Yan 2025-04-03 1618 if (ret < 0) d366451bed980ac Andy Yan 2025-04-03 1619 return ret; d366451bed980ac Andy Yan 2025-04-03 1620 d366451bed980ac Andy Yan 2025-04-03 1621 ret = dw_dp_link_train(dp); d366451bed980ac Andy Yan 2025-04-03 1622 d366451bed980ac Andy Yan 2025-04-03 1623 return ret; d366451bed980ac Andy Yan 2025-04-03 1624 } d366451bed980ac Andy Yan 2025-04-03 1625 d366451bed980ac Andy Yan 2025-04-03 1626 static void dw_dp_bridge_atomic_enable(struct drm_bridge *bridge, d366451bed980ac Andy Yan 2025-04-03 1627 struct drm_atomic_state *state) d366451bed980ac Andy Yan 2025-04-03 1628 { d366451bed980ac Andy Yan 2025-04-03 1629 struct dw_dp *dp = bridge_to_dp(bridge); d366451bed980ac Andy Yan 2025-04-03 1630 struct drm_connector *connector; d366451bed980ac Andy Yan 2025-04-03 1631 struct drm_connector_state *conn_state; d366451bed980ac Andy Yan 2025-04-03 1632 int ret; d366451bed980ac Andy Yan 2025-04-03 1633 d366451bed980ac Andy Yan 2025-04-03 1634 connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); d366451bed980ac Andy Yan 2025-04-03 1635 if (!connector) { d366451bed980ac Andy Yan 2025-04-03 1636 dev_err(dp->dev, "failed to get connector\n"); d366451bed980ac Andy Yan 2025-04-03 1637 return; d366451bed980ac Andy Yan 2025-04-03 1638 } d366451bed980ac Andy Yan 2025-04-03 1639 d366451bed980ac Andy Yan 2025-04-03 1640 conn_state = drm_atomic_get_new_connector_state(state, connector); d366451bed980ac Andy Yan 2025-04-03 1641 if (!conn_state) { d366451bed980ac Andy Yan 2025-04-03 1642 dev_err(dp->dev, "failed to get connector state\n"); d366451bed980ac Andy Yan 2025-04-03 1643 return; d366451bed980ac Andy Yan 2025-04-03 1644 } d366451bed980ac Andy Yan 2025-04-03 1645 d366451bed980ac Andy Yan 2025-04-03 1646 set_bit(0, dp->sdp_reg_bank); d366451bed980ac Andy Yan 2025-04-03 1647 d366451bed980ac Andy Yan 2025-04-03 1648 ret = dw_dp_link_enable(dp); d366451bed980ac Andy Yan 2025-04-03 1649 if (ret < 0) { d366451bed980ac Andy Yan 2025-04-03 1650 dev_err(dp->dev, "failed to enable link: %d\n", ret); d366451bed980ac Andy Yan 2025-04-03 1651 return; d366451bed980ac Andy Yan 2025-04-03 1652 } d366451bed980ac Andy Yan 2025-04-03 1653 d366451bed980ac Andy Yan 2025-04-03 1654 ret = dw_dp_video_enable(dp); d366451bed980ac Andy Yan 2025-04-03 1655 if (ret < 0) { d366451bed980ac Andy Yan 2025-04-03 1656 dev_err(dp->dev, "failed to enable video: %d\n", ret); d366451bed980ac Andy Yan 2025-04-03 1657 return; d366451bed980ac Andy Yan 2025-04-03 1658 } d366451bed980ac Andy Yan 2025-04-03 1659 } d366451bed980ac Andy Yan 2025-04-03 1660 d366451bed980ac Andy Yan 2025-04-03 1661 static void dw_dp_reset(struct dw_dp *dp) d366451bed980ac Andy Yan 2025-04-03 1662 { d366451bed980ac Andy Yan 2025-04-03 1663 int val; d366451bed980ac Andy Yan 2025-04-03 1664 d366451bed980ac Andy Yan 2025-04-03 1665 disable_irq(dp->irq); d366451bed980ac Andy Yan 2025-04-03 1666 regmap_update_bits(dp->regmap, DW_DP_SOFT_RESET_CTRL, CONTROLLER_RESET, d366451bed980ac Andy Yan 2025-04-03 1667 FIELD_PREP(CONTROLLER_RESET, 1)); d366451bed980ac Andy Yan 2025-04-03 1668 udelay(10); d366451bed980ac Andy Yan 2025-04-03 1669 regmap_update_bits(dp->regmap, DW_DP_SOFT_RESET_CTRL, CONTROLLER_RESET, d366451bed980ac Andy Yan 2025-04-03 1670 FIELD_PREP(CONTROLLER_RESET, 0)); d366451bed980ac Andy Yan 2025-04-03 1671 d366451bed980ac Andy Yan 2025-04-03 1672 dw_dp_init_hw(dp); d366451bed980ac Andy Yan 2025-04-03 1673 regmap_read_poll_timeout(dp->regmap, DW_DP_HPD_STATUS, val, d366451bed980ac Andy Yan 2025-04-03 1674 FIELD_GET(HPD_HOT_PLUG, val), 200, 200000); d366451bed980ac Andy Yan 2025-04-03 1675 regmap_write(dp->regmap, DW_DP_HPD_STATUS, HPD_HOT_PLUG); d366451bed980ac Andy Yan 2025-04-03 1676 enable_irq(dp->irq); d366451bed980ac Andy Yan 2025-04-03 1677 } d366451bed980ac Andy Yan 2025-04-03 1678 d366451bed980ac Andy Yan 2025-04-03 1679 static void dw_dp_bridge_atomic_disable(struct drm_bridge *bridge, d366451bed980ac Andy Yan 2025-04-03 1680 struct drm_atomic_state *state) d366451bed980ac Andy Yan 2025-04-03 1681 { d366451bed980ac Andy Yan 2025-04-03 1682 struct dw_dp *dp = bridge_to_dp(bridge); d366451bed980ac Andy Yan 2025-04-03 1683 d366451bed980ac Andy Yan 2025-04-03 1684 dw_dp_video_disable(dp); d366451bed980ac Andy Yan 2025-04-03 1685 dw_dp_link_disable(dp); d366451bed980ac Andy Yan 2025-04-03 1686 bitmap_zero(dp->sdp_reg_bank, SDP_REG_BANK_SIZE); d366451bed980ac Andy Yan 2025-04-03 1687 dw_dp_reset(dp); d366451bed980ac Andy Yan 2025-04-03 1688 } d366451bed980ac Andy Yan 2025-04-03 1689 d366451bed980ac Andy Yan 2025-04-03 1690 static bool dw_dp_hpd_detect_link(struct dw_dp *dp) d366451bed980ac Andy Yan 2025-04-03 1691 { d366451bed980ac Andy Yan 2025-04-03 1692 int ret; d366451bed980ac Andy Yan 2025-04-03 1693 d366451bed980ac Andy Yan 2025-04-03 1694 ret = phy_power_on(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1695 if (ret < 0) d366451bed980ac Andy Yan 2025-04-03 1696 return false; d366451bed980ac Andy Yan 2025-04-03 1697 ret = dw_dp_link_parse(dp); d366451bed980ac Andy Yan 2025-04-03 1698 phy_power_off(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1699 d366451bed980ac Andy Yan 2025-04-03 1700 return !ret; d366451bed980ac Andy Yan 2025-04-03 1701 } d366451bed980ac Andy Yan 2025-04-03 1702 d366451bed980ac Andy Yan 2025-04-03 1703 static enum drm_connector_status dw_dp_bridge_detect(struct drm_bridge *bridge) d366451bed980ac Andy Yan 2025-04-03 1704 { d366451bed980ac Andy Yan 2025-04-03 1705 struct dw_dp *dp = bridge_to_dp(bridge); d366451bed980ac Andy Yan 2025-04-03 1706 d366451bed980ac Andy Yan 2025-04-03 1707 if (!dw_dp_hpd_detect(dp)) d366451bed980ac Andy Yan 2025-04-03 1708 return connector_status_disconnected; d366451bed980ac Andy Yan 2025-04-03 1709 d366451bed980ac Andy Yan 2025-04-03 1710 if (!dw_dp_hpd_detect_link(dp)) d366451bed980ac Andy Yan 2025-04-03 1711 return connector_status_disconnected; d366451bed980ac Andy Yan 2025-04-03 1712 d366451bed980ac Andy Yan 2025-04-03 1713 return connector_status_connected; d366451bed980ac Andy Yan 2025-04-03 1714 } d366451bed980ac Andy Yan 2025-04-03 1715 d366451bed980ac Andy Yan 2025-04-03 1716 static const struct drm_edid *dw_dp_bridge_edid_read(struct drm_bridge *bridge, d366451bed980ac Andy Yan 2025-04-03 1717 struct drm_connector *connector) d366451bed980ac Andy Yan 2025-04-03 1718 { d366451bed980ac Andy Yan 2025-04-03 1719 struct dw_dp *dp = bridge_to_dp(bridge); d366451bed980ac Andy Yan 2025-04-03 1720 const struct drm_edid *edid; d366451bed980ac Andy Yan 2025-04-03 1721 int ret; d366451bed980ac Andy Yan 2025-04-03 1722 d366451bed980ac Andy Yan 2025-04-03 1723 ret = phy_power_on(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1724 if (ret) d366451bed980ac Andy Yan 2025-04-03 1725 return NULL; d366451bed980ac Andy Yan 2025-04-03 1726 d366451bed980ac Andy Yan 2025-04-03 1727 edid = drm_edid_read_ddc(connector, &dp->aux.ddc); d366451bed980ac Andy Yan 2025-04-03 1728 d366451bed980ac Andy Yan 2025-04-03 1729 phy_power_off(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1730 d366451bed980ac Andy Yan 2025-04-03 1731 return edid; d366451bed980ac Andy Yan 2025-04-03 1732 } d366451bed980ac Andy Yan 2025-04-03 1733 d366451bed980ac Andy Yan 2025-04-03 1734 static u32 *dw_dp_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, d366451bed980ac Andy Yan 2025-04-03 1735 struct drm_bridge_state *bridge_state, d366451bed980ac Andy Yan 2025-04-03 1736 struct drm_crtc_state *crtc_state, d366451bed980ac Andy Yan 2025-04-03 1737 struct drm_connector_state *conn_state, d366451bed980ac Andy Yan 2025-04-03 1738 unsigned int *num_output_fmts) d366451bed980ac Andy Yan 2025-04-03 1739 { d366451bed980ac Andy Yan 2025-04-03 1740 struct dw_dp *dp = bridge_to_dp(bridge); d366451bed980ac Andy Yan 2025-04-03 1741 struct dw_dp_link *link = &dp->link; d366451bed980ac Andy Yan 2025-04-03 1742 struct drm_display_info *di = &conn_state->connector->display_info; d366451bed980ac Andy Yan 2025-04-03 1743 struct drm_display_mode mode = crtc_state->mode; d366451bed980ac Andy Yan 2025-04-03 1744 const struct dw_dp_output_format *fmt; d366451bed980ac Andy Yan 2025-04-03 1745 u32 i, j = 0; d366451bed980ac Andy Yan 2025-04-03 1746 u32 *output_fmts; d366451bed980ac Andy Yan 2025-04-03 1747 d366451bed980ac Andy Yan 2025-04-03 1748 *num_output_fmts = 0; d366451bed980ac Andy Yan 2025-04-03 1749 d366451bed980ac Andy Yan 2025-04-03 1750 output_fmts = kcalloc(ARRAY_SIZE(dw_dp_output_formats), sizeof(*output_fmts), GFP_KERNEL); d366451bed980ac Andy Yan 2025-04-03 1751 if (!output_fmts) d366451bed980ac Andy Yan 2025-04-03 1752 return NULL; d366451bed980ac Andy Yan 2025-04-03 1753 d366451bed980ac Andy Yan 2025-04-03 1754 for (i = 0; i < ARRAY_SIZE(dw_dp_output_formats); i++) { d366451bed980ac Andy Yan 2025-04-03 1755 fmt = &dw_dp_output_formats[i]; d366451bed980ac Andy Yan 2025-04-03 1756 d366451bed980ac Andy Yan 2025-04-03 1757 if (fmt->bpc > conn_state->max_bpc) d366451bed980ac Andy Yan 2025-04-03 1758 continue; d366451bed980ac Andy Yan 2025-04-03 1759 d366451bed980ac Andy Yan 2025-04-03 1760 if (!(fmt->color_format & di->color_formats)) d366451bed980ac Andy Yan 2025-04-03 1761 continue; d366451bed980ac Andy Yan 2025-04-03 1762 d366451bed980ac Andy Yan 2025-04-03 1763 if (fmt->color_format == DRM_COLOR_FORMAT_YCBCR420 && d366451bed980ac Andy Yan 2025-04-03 1764 !link->vsc_sdp_supported) d366451bed980ac Andy Yan 2025-04-03 1765 continue; d366451bed980ac Andy Yan 2025-04-03 1766 d366451bed980ac Andy Yan 2025-04-03 1767 if (fmt->color_format != DRM_COLOR_FORMAT_YCBCR420 && d366451bed980ac Andy Yan 2025-04-03 1768 drm_mode_is_420_only(di, &mode)) d366451bed980ac Andy Yan 2025-04-03 1769 continue; d366451bed980ac Andy Yan 2025-04-03 1770 d366451bed980ac Andy Yan 2025-04-03 1771 if (!dw_dp_bandwidth_ok(dp, &mode, fmt->bpp, link->lanes, link->rate)) d366451bed980ac Andy Yan 2025-04-03 1772 continue; d366451bed980ac Andy Yan 2025-04-03 1773 d366451bed980ac Andy Yan 2025-04-03 1774 output_fmts[j++] = fmt->bus_format; d366451bed980ac Andy Yan 2025-04-03 1775 } d366451bed980ac Andy Yan 2025-04-03 1776 d366451bed980ac Andy Yan 2025-04-03 1777 *num_output_fmts = j; d366451bed980ac Andy Yan 2025-04-03 1778 d366451bed980ac Andy Yan 2025-04-03 1779 return output_fmts; d366451bed980ac Andy Yan 2025-04-03 1780 } d366451bed980ac Andy Yan 2025-04-03 1781 d366451bed980ac Andy Yan 2025-04-03 1782 static const struct drm_bridge_funcs dw_dp_bridge_funcs = { d366451bed980ac Andy Yan 2025-04-03 1783 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, d366451bed980ac Andy Yan 2025-04-03 1784 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, d366451bed980ac Andy Yan 2025-04-03 1785 .atomic_reset = drm_atomic_helper_bridge_reset, d366451bed980ac Andy Yan 2025-04-03 1786 .atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt, d366451bed980ac Andy Yan 2025-04-03 1787 .atomic_get_output_bus_fmts = dw_dp_bridge_atomic_get_output_bus_fmts, d366451bed980ac Andy Yan 2025-04-03 1788 .atomic_check = dw_dp_bridge_atomic_check, d366451bed980ac Andy Yan 2025-04-03 1789 .mode_valid = dw_dp_bridge_mode_valid, d366451bed980ac Andy Yan 2025-04-03 @1790 .atomic_enable = dw_dp_bridge_atomic_enable, d366451bed980ac Andy Yan 2025-04-03 1791 .atomic_disable = dw_dp_bridge_atomic_disable, d366451bed980ac Andy Yan 2025-04-03 1792 .detect = dw_dp_bridge_detect, d366451bed980ac Andy Yan 2025-04-03 1793 .edid_read = dw_dp_bridge_edid_read, d366451bed980ac Andy Yan 2025-04-03 1794 }; d366451bed980ac Andy Yan 2025-04-03 1795
Hi Andy, kernel test robot noticed the following build errors: [auto build test ERROR on rockchip/for-next] [also build test ERROR on robh/for-next drm-exynos/exynos-drm-next linus/master v6.14 next-20250404] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information] url: https://github.com/intel-lab-lkp/linux/commits/Andy-Yan/dt-bindings-display-rockchip-Add-schema-for-RK3588-DPTX-Controller/20250403-114203 base: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git for-next patch link: https://lore.kernel.org/r/20250403033748.245007-4-andyshrk%40163.com patch subject: [PATCH v3 3/9] drm/rockchip: Add RK3588 DPTX output support config: s390-allyesconfig (https://download.01.org/0day-ci/archive/20250404/202504041920.g5XTp8Xp-lkp@intel.com/config) compiler: s390-linux-gcc (GCC) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250404/202504041920.g5XTp8Xp-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202504041920.g5XTp8Xp-lkp@intel.com/ All errors (new ones prefixed by >>): drivers/gpu/drm/bridge/synopsys/dw-dp.c: In function 'dw_dp_link_disable': >> drivers/gpu/drm/bridge/synopsys/dw-dp.c:1599:17: error: implicit declaration of function 'drm_dp_link_power_down' [-Wimplicit-function-declaration] 1599 | drm_dp_link_power_down(&dp->aux, dp->link.revision); | ^~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/bridge/synopsys/dw-dp.c: In function 'dw_dp_link_enable': >> drivers/gpu/drm/bridge/synopsys/dw-dp.c:1617:15: error: implicit declaration of function 'drm_dp_link_power_up' [-Wimplicit-function-declaration] 1617 | ret = drm_dp_link_power_up(&dp->aux, dp->link.revision); | ^~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/bridge/synopsys/dw-dp.c: At top level: >> drivers/gpu/drm/bridge/synopsys/dw-dp.c:1790:26: error: initialization of 'void (*)(struct drm_bridge *, struct drm_bridge_state *)' from incompatible pointer type 'void (*)(struct drm_bridge *, struct drm_atomic_state *)' [-Wincompatible-pointer-types] 1790 | .atomic_enable = dw_dp_bridge_atomic_enable, | ^~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/bridge/synopsys/dw-dp.c:1790:26: note: (near initialization for 'dw_dp_bridge_funcs.atomic_enable') drivers/gpu/drm/bridge/synopsys/dw-dp.c:1791:27: error: initialization of 'void (*)(struct drm_bridge *, struct drm_bridge_state *)' from incompatible pointer type 'void (*)(struct drm_bridge *, struct drm_atomic_state *)' [-Wincompatible-pointer-types] 1791 | .atomic_disable = dw_dp_bridge_atomic_disable, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ drivers/gpu/drm/bridge/synopsys/dw-dp.c:1791:27: note: (near initialization for 'dw_dp_bridge_funcs.atomic_disable') vim +1790 drivers/gpu/drm/bridge/synopsys/dw-dp.c d366451bed980ac Andy Yan 2025-04-03 1593 d366451bed980ac Andy Yan 2025-04-03 1594 static void dw_dp_link_disable(struct dw_dp *dp) d366451bed980ac Andy Yan 2025-04-03 1595 { d366451bed980ac Andy Yan 2025-04-03 1596 struct dw_dp_link *link = &dp->link; d366451bed980ac Andy Yan 2025-04-03 1597 d366451bed980ac Andy Yan 2025-04-03 1598 if (dw_dp_hpd_detect(dp)) d366451bed980ac Andy Yan 2025-04-03 @1599 drm_dp_link_power_down(&dp->aux, dp->link.revision); d366451bed980ac Andy Yan 2025-04-03 1600 d366451bed980ac Andy Yan 2025-04-03 1601 dw_dp_phy_xmit_enable(dp, 0); d366451bed980ac Andy Yan 2025-04-03 1602 d366451bed980ac Andy Yan 2025-04-03 1603 phy_power_off(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1604 d366451bed980ac Andy Yan 2025-04-03 1605 link->train.clock_recovered = false; d366451bed980ac Andy Yan 2025-04-03 1606 link->train.channel_equalized = false; d366451bed980ac Andy Yan 2025-04-03 1607 } d366451bed980ac Andy Yan 2025-04-03 1608 d366451bed980ac Andy Yan 2025-04-03 1609 static int dw_dp_link_enable(struct dw_dp *dp) d366451bed980ac Andy Yan 2025-04-03 1610 { d366451bed980ac Andy Yan 2025-04-03 1611 int ret; d366451bed980ac Andy Yan 2025-04-03 1612 d366451bed980ac Andy Yan 2025-04-03 1613 ret = phy_power_on(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1614 if (ret) d366451bed980ac Andy Yan 2025-04-03 1615 return ret; d366451bed980ac Andy Yan 2025-04-03 1616 d366451bed980ac Andy Yan 2025-04-03 @1617 ret = drm_dp_link_power_up(&dp->aux, dp->link.revision); d366451bed980ac Andy Yan 2025-04-03 1618 if (ret < 0) d366451bed980ac Andy Yan 2025-04-03 1619 return ret; d366451bed980ac Andy Yan 2025-04-03 1620 d366451bed980ac Andy Yan 2025-04-03 1621 ret = dw_dp_link_train(dp); d366451bed980ac Andy Yan 2025-04-03 1622 d366451bed980ac Andy Yan 2025-04-03 1623 return ret; d366451bed980ac Andy Yan 2025-04-03 1624 } d366451bed980ac Andy Yan 2025-04-03 1625 d366451bed980ac Andy Yan 2025-04-03 1626 static void dw_dp_bridge_atomic_enable(struct drm_bridge *bridge, d366451bed980ac Andy Yan 2025-04-03 1627 struct drm_atomic_state *state) d366451bed980ac Andy Yan 2025-04-03 1628 { d366451bed980ac Andy Yan 2025-04-03 1629 struct dw_dp *dp = bridge_to_dp(bridge); d366451bed980ac Andy Yan 2025-04-03 1630 struct drm_connector *connector; d366451bed980ac Andy Yan 2025-04-03 1631 struct drm_connector_state *conn_state; d366451bed980ac Andy Yan 2025-04-03 1632 int ret; d366451bed980ac Andy Yan 2025-04-03 1633 d366451bed980ac Andy Yan 2025-04-03 1634 connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); d366451bed980ac Andy Yan 2025-04-03 1635 if (!connector) { d366451bed980ac Andy Yan 2025-04-03 1636 dev_err(dp->dev, "failed to get connector\n"); d366451bed980ac Andy Yan 2025-04-03 1637 return; d366451bed980ac Andy Yan 2025-04-03 1638 } d366451bed980ac Andy Yan 2025-04-03 1639 d366451bed980ac Andy Yan 2025-04-03 1640 conn_state = drm_atomic_get_new_connector_state(state, connector); d366451bed980ac Andy Yan 2025-04-03 1641 if (!conn_state) { d366451bed980ac Andy Yan 2025-04-03 1642 dev_err(dp->dev, "failed to get connector state\n"); d366451bed980ac Andy Yan 2025-04-03 1643 return; d366451bed980ac Andy Yan 2025-04-03 1644 } d366451bed980ac Andy Yan 2025-04-03 1645 d366451bed980ac Andy Yan 2025-04-03 1646 set_bit(0, dp->sdp_reg_bank); d366451bed980ac Andy Yan 2025-04-03 1647 d366451bed980ac Andy Yan 2025-04-03 1648 ret = dw_dp_link_enable(dp); d366451bed980ac Andy Yan 2025-04-03 1649 if (ret < 0) { d366451bed980ac Andy Yan 2025-04-03 1650 dev_err(dp->dev, "failed to enable link: %d\n", ret); d366451bed980ac Andy Yan 2025-04-03 1651 return; d366451bed980ac Andy Yan 2025-04-03 1652 } d366451bed980ac Andy Yan 2025-04-03 1653 d366451bed980ac Andy Yan 2025-04-03 1654 ret = dw_dp_video_enable(dp); d366451bed980ac Andy Yan 2025-04-03 1655 if (ret < 0) { d366451bed980ac Andy Yan 2025-04-03 1656 dev_err(dp->dev, "failed to enable video: %d\n", ret); d366451bed980ac Andy Yan 2025-04-03 1657 return; d366451bed980ac Andy Yan 2025-04-03 1658 } d366451bed980ac Andy Yan 2025-04-03 1659 } d366451bed980ac Andy Yan 2025-04-03 1660 d366451bed980ac Andy Yan 2025-04-03 1661 static void dw_dp_reset(struct dw_dp *dp) d366451bed980ac Andy Yan 2025-04-03 1662 { d366451bed980ac Andy Yan 2025-04-03 1663 int val; d366451bed980ac Andy Yan 2025-04-03 1664 d366451bed980ac Andy Yan 2025-04-03 1665 disable_irq(dp->irq); d366451bed980ac Andy Yan 2025-04-03 1666 regmap_update_bits(dp->regmap, DW_DP_SOFT_RESET_CTRL, CONTROLLER_RESET, d366451bed980ac Andy Yan 2025-04-03 1667 FIELD_PREP(CONTROLLER_RESET, 1)); d366451bed980ac Andy Yan 2025-04-03 1668 udelay(10); d366451bed980ac Andy Yan 2025-04-03 1669 regmap_update_bits(dp->regmap, DW_DP_SOFT_RESET_CTRL, CONTROLLER_RESET, d366451bed980ac Andy Yan 2025-04-03 1670 FIELD_PREP(CONTROLLER_RESET, 0)); d366451bed980ac Andy Yan 2025-04-03 1671 d366451bed980ac Andy Yan 2025-04-03 1672 dw_dp_init_hw(dp); d366451bed980ac Andy Yan 2025-04-03 1673 regmap_read_poll_timeout(dp->regmap, DW_DP_HPD_STATUS, val, d366451bed980ac Andy Yan 2025-04-03 1674 FIELD_GET(HPD_HOT_PLUG, val), 200, 200000); d366451bed980ac Andy Yan 2025-04-03 1675 regmap_write(dp->regmap, DW_DP_HPD_STATUS, HPD_HOT_PLUG); d366451bed980ac Andy Yan 2025-04-03 1676 enable_irq(dp->irq); d366451bed980ac Andy Yan 2025-04-03 1677 } d366451bed980ac Andy Yan 2025-04-03 1678 d366451bed980ac Andy Yan 2025-04-03 1679 static void dw_dp_bridge_atomic_disable(struct drm_bridge *bridge, d366451bed980ac Andy Yan 2025-04-03 1680 struct drm_atomic_state *state) d366451bed980ac Andy Yan 2025-04-03 1681 { d366451bed980ac Andy Yan 2025-04-03 1682 struct dw_dp *dp = bridge_to_dp(bridge); d366451bed980ac Andy Yan 2025-04-03 1683 d366451bed980ac Andy Yan 2025-04-03 1684 dw_dp_video_disable(dp); d366451bed980ac Andy Yan 2025-04-03 1685 dw_dp_link_disable(dp); d366451bed980ac Andy Yan 2025-04-03 1686 bitmap_zero(dp->sdp_reg_bank, SDP_REG_BANK_SIZE); d366451bed980ac Andy Yan 2025-04-03 1687 dw_dp_reset(dp); d366451bed980ac Andy Yan 2025-04-03 1688 } d366451bed980ac Andy Yan 2025-04-03 1689 d366451bed980ac Andy Yan 2025-04-03 1690 static bool dw_dp_hpd_detect_link(struct dw_dp *dp) d366451bed980ac Andy Yan 2025-04-03 1691 { d366451bed980ac Andy Yan 2025-04-03 1692 int ret; d366451bed980ac Andy Yan 2025-04-03 1693 d366451bed980ac Andy Yan 2025-04-03 1694 ret = phy_power_on(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1695 if (ret < 0) d366451bed980ac Andy Yan 2025-04-03 1696 return false; d366451bed980ac Andy Yan 2025-04-03 1697 ret = dw_dp_link_parse(dp); d366451bed980ac Andy Yan 2025-04-03 1698 phy_power_off(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1699 d366451bed980ac Andy Yan 2025-04-03 1700 return !ret; d366451bed980ac Andy Yan 2025-04-03 1701 } d366451bed980ac Andy Yan 2025-04-03 1702 d366451bed980ac Andy Yan 2025-04-03 1703 static enum drm_connector_status dw_dp_bridge_detect(struct drm_bridge *bridge) d366451bed980ac Andy Yan 2025-04-03 1704 { d366451bed980ac Andy Yan 2025-04-03 1705 struct dw_dp *dp = bridge_to_dp(bridge); d366451bed980ac Andy Yan 2025-04-03 1706 d366451bed980ac Andy Yan 2025-04-03 1707 if (!dw_dp_hpd_detect(dp)) d366451bed980ac Andy Yan 2025-04-03 1708 return connector_status_disconnected; d366451bed980ac Andy Yan 2025-04-03 1709 d366451bed980ac Andy Yan 2025-04-03 1710 if (!dw_dp_hpd_detect_link(dp)) d366451bed980ac Andy Yan 2025-04-03 1711 return connector_status_disconnected; d366451bed980ac Andy Yan 2025-04-03 1712 d366451bed980ac Andy Yan 2025-04-03 1713 return connector_status_connected; d366451bed980ac Andy Yan 2025-04-03 1714 } d366451bed980ac Andy Yan 2025-04-03 1715 d366451bed980ac Andy Yan 2025-04-03 1716 static const struct drm_edid *dw_dp_bridge_edid_read(struct drm_bridge *bridge, d366451bed980ac Andy Yan 2025-04-03 1717 struct drm_connector *connector) d366451bed980ac Andy Yan 2025-04-03 1718 { d366451bed980ac Andy Yan 2025-04-03 1719 struct dw_dp *dp = bridge_to_dp(bridge); d366451bed980ac Andy Yan 2025-04-03 1720 const struct drm_edid *edid; d366451bed980ac Andy Yan 2025-04-03 1721 int ret; d366451bed980ac Andy Yan 2025-04-03 1722 d366451bed980ac Andy Yan 2025-04-03 1723 ret = phy_power_on(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1724 if (ret) d366451bed980ac Andy Yan 2025-04-03 1725 return NULL; d366451bed980ac Andy Yan 2025-04-03 1726 d366451bed980ac Andy Yan 2025-04-03 1727 edid = drm_edid_read_ddc(connector, &dp->aux.ddc); d366451bed980ac Andy Yan 2025-04-03 1728 d366451bed980ac Andy Yan 2025-04-03 1729 phy_power_off(dp->phy); d366451bed980ac Andy Yan 2025-04-03 1730 d366451bed980ac Andy Yan 2025-04-03 1731 return edid; d366451bed980ac Andy Yan 2025-04-03 1732 } d366451bed980ac Andy Yan 2025-04-03 1733 d366451bed980ac Andy Yan 2025-04-03 1734 static u32 *dw_dp_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, d366451bed980ac Andy Yan 2025-04-03 1735 struct drm_bridge_state *bridge_state, d366451bed980ac Andy Yan 2025-04-03 1736 struct drm_crtc_state *crtc_state, d366451bed980ac Andy Yan 2025-04-03 1737 struct drm_connector_state *conn_state, d366451bed980ac Andy Yan 2025-04-03 1738 unsigned int *num_output_fmts) d366451bed980ac Andy Yan 2025-04-03 1739 { d366451bed980ac Andy Yan 2025-04-03 1740 struct dw_dp *dp = bridge_to_dp(bridge); d366451bed980ac Andy Yan 2025-04-03 1741 struct dw_dp_link *link = &dp->link; d366451bed980ac Andy Yan 2025-04-03 1742 struct drm_display_info *di = &conn_state->connector->display_info; d366451bed980ac Andy Yan 2025-04-03 1743 struct drm_display_mode mode = crtc_state->mode; d366451bed980ac Andy Yan 2025-04-03 1744 const struct dw_dp_output_format *fmt; d366451bed980ac Andy Yan 2025-04-03 1745 u32 i, j = 0; d366451bed980ac Andy Yan 2025-04-03 1746 u32 *output_fmts; d366451bed980ac Andy Yan 2025-04-03 1747 d366451bed980ac Andy Yan 2025-04-03 1748 *num_output_fmts = 0; d366451bed980ac Andy Yan 2025-04-03 1749 d366451bed980ac Andy Yan 2025-04-03 1750 output_fmts = kcalloc(ARRAY_SIZE(dw_dp_output_formats), sizeof(*output_fmts), GFP_KERNEL); d366451bed980ac Andy Yan 2025-04-03 1751 if (!output_fmts) d366451bed980ac Andy Yan 2025-04-03 1752 return NULL; d366451bed980ac Andy Yan 2025-04-03 1753 d366451bed980ac Andy Yan 2025-04-03 1754 for (i = 0; i < ARRAY_SIZE(dw_dp_output_formats); i++) { d366451bed980ac Andy Yan 2025-04-03 1755 fmt = &dw_dp_output_formats[i]; d366451bed980ac Andy Yan 2025-04-03 1756 d366451bed980ac Andy Yan 2025-04-03 1757 if (fmt->bpc > conn_state->max_bpc) d366451bed980ac Andy Yan 2025-04-03 1758 continue; d366451bed980ac Andy Yan 2025-04-03 1759 d366451bed980ac Andy Yan 2025-04-03 1760 if (!(fmt->color_format & di->color_formats)) d366451bed980ac Andy Yan 2025-04-03 1761 continue; d366451bed980ac Andy Yan 2025-04-03 1762 d366451bed980ac Andy Yan 2025-04-03 1763 if (fmt->color_format == DRM_COLOR_FORMAT_YCBCR420 && d366451bed980ac Andy Yan 2025-04-03 1764 !link->vsc_sdp_supported) d366451bed980ac Andy Yan 2025-04-03 1765 continue; d366451bed980ac Andy Yan 2025-04-03 1766 d366451bed980ac Andy Yan 2025-04-03 1767 if (fmt->color_format != DRM_COLOR_FORMAT_YCBCR420 && d366451bed980ac Andy Yan 2025-04-03 1768 drm_mode_is_420_only(di, &mode)) d366451bed980ac Andy Yan 2025-04-03 1769 continue; d366451bed980ac Andy Yan 2025-04-03 1770 d366451bed980ac Andy Yan 2025-04-03 1771 if (!dw_dp_bandwidth_ok(dp, &mode, fmt->bpp, link->lanes, link->rate)) d366451bed980ac Andy Yan 2025-04-03 1772 continue; d366451bed980ac Andy Yan 2025-04-03 1773 d366451bed980ac Andy Yan 2025-04-03 1774 output_fmts[j++] = fmt->bus_format; d366451bed980ac Andy Yan 2025-04-03 1775 } d366451bed980ac Andy Yan 2025-04-03 1776 d366451bed980ac Andy Yan 2025-04-03 1777 *num_output_fmts = j; d366451bed980ac Andy Yan 2025-04-03 1778 d366451bed980ac Andy Yan 2025-04-03 1779 return output_fmts; d366451bed980ac Andy Yan 2025-04-03 1780 } d366451bed980ac Andy Yan 2025-04-03 1781 d366451bed980ac Andy Yan 2025-04-03 1782 static const struct drm_bridge_funcs dw_dp_bridge_funcs = { d366451bed980ac Andy Yan 2025-04-03 1783 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, d366451bed980ac Andy Yan 2025-04-03 1784 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, d366451bed980ac Andy Yan 2025-04-03 1785 .atomic_reset = drm_atomic_helper_bridge_reset, d366451bed980ac Andy Yan 2025-04-03 1786 .atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt, d366451bed980ac Andy Yan 2025-04-03 1787 .atomic_get_output_bus_fmts = dw_dp_bridge_atomic_get_output_bus_fmts, d366451bed980ac Andy Yan 2025-04-03 1788 .atomic_check = dw_dp_bridge_atomic_check, d366451bed980ac Andy Yan 2025-04-03 1789 .mode_valid = dw_dp_bridge_mode_valid, d366451bed980ac Andy Yan 2025-04-03 @1790 .atomic_enable = dw_dp_bridge_atomic_enable, d366451bed980ac Andy Yan 2025-04-03 1791 .atomic_disable = dw_dp_bridge_atomic_disable, d366451bed980ac Andy Yan 2025-04-03 1792 .detect = dw_dp_bridge_detect, d366451bed980ac Andy Yan 2025-04-03 1793 .edid_read = dw_dp_bridge_edid_read, d366451bed980ac Andy Yan 2025-04-03 1794 }; d366451bed980ac Andy Yan 2025-04-03 1795
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index 26c4410b2407c..00315cc6be5a8 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -8,6 +8,7 @@ config DRM_ROCKCHIP select DRM_PANEL select VIDEOMODE_HELPERS select DRM_ANALOGIX_DP if ROCKCHIP_ANALOGIX_DP + select DRM_DW_DP if ROCKCHIP_DW_DP select DRM_DW_HDMI if ROCKCHIP_DW_HDMI select DRM_DW_HDMI_QP if ROCKCHIP_DW_HDMI_QP select DRM_DW_MIPI_DSI if ROCKCHIP_DW_MIPI_DSI @@ -58,6 +59,14 @@ config ROCKCHIP_CDN_DP RK3399 based SoC, you should select this option. +config ROCKCHIP_DW_DP + bool "Rockchip specific extensions for Synopsys DW DP" + help + This selects support for Rockchip SoC specific extensions + to enable Synopsys DesignWare Cores based DisplayPort transmit + controller support on Rockchip SoC, If you want to enable DP on + rk3588 based SoC, you should select this option. + config ROCKCHIP_DW_HDMI bool "Rockchip specific extensions for Synopsys DW HDMI" help diff --git a/drivers/gpu/drm/rockchip/Makefile b/drivers/gpu/drm/rockchip/Makefile index 2b867cebbc121..097f062399c7a 100644 --- a/drivers/gpu/drm/rockchip/Makefile +++ b/drivers/gpu/drm/rockchip/Makefile @@ -14,6 +14,7 @@ rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o rockchipdrm-$(CONFIG_ROCKCHIP_DW_HDMI_QP) += dw_hdmi_qp-rockchip.o rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi-rockchip.o rockchipdrm-$(CONFIG_ROCKCHIP_DW_MIPI_DSI2) += dw-mipi-dsi2-rockchip.o +rockchipdrm-$(CONFIG_ROCKCHIP_DW_DP) += dw_dp-rockchip.o rockchipdrm-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o rockchipdrm-$(CONFIG_ROCKCHIP_LVDS) += rockchip_lvds.o rockchipdrm-$(CONFIG_ROCKCHIP_RGB) += rockchip_rgb.o diff --git a/drivers/gpu/drm/rockchip/dw_dp-rockchip.c b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c new file mode 100644 index 0000000000000..5ff8a6a54997e --- /dev/null +++ b/drivers/gpu/drm/rockchip/dw_dp-rockchip.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2020 Rockchip Electronics Co., Ltd. + * + * Author: Zhang Yubing <yubing.zhang@rock-chips.com> + * Author: Andy Yan <andy.yan@rock-chips.com> + */ + +#include <linux/component.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <drm/bridge/dw_dp.h> +#include <drm/drm_atomic_helper.h> +#include <drm/drm_bridge.h> +#include <drm/drm_bridge_connector.h> +#include <drm/drm_of.h> +#include <drm/drm_print.h> +#include <drm/drm_probe_helper.h> +#include <drm/drm_simple_kms_helper.h> + +#include <linux/media-bus-format.h> +#include <linux/videodev2.h> + +#include "rockchip_drm_drv.h" +#include "rockchip_drm_vop.h" + +struct rockchip_dw_dp { + struct dw_dp *base; + struct device *dev; + struct rockchip_encoder encoder; +}; + +static inline struct rockchip_dw_dp *encoder_to_dp(struct drm_encoder *encoder) +{ + struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder); + + return container_of(rkencoder, struct rockchip_dw_dp, encoder); +} + +static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); + struct drm_atomic_state *state = conn_state->state; + struct drm_display_info *di = &conn_state->connector->display_info; + struct drm_bridge *bridge = drm_bridge_chain_get_first_bridge(encoder); + struct drm_bridge_state *bridge_state = drm_atomic_get_new_bridge_state(state, bridge); + u32 bus_format = bridge_state->input_bus_cfg.format; + + switch (bus_format) { + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + s->output_mode = ROCKCHIP_OUT_MODE_YUV420; + break; + case MEDIA_BUS_FMT_YUYV10_1X20: + case MEDIA_BUS_FMT_YUYV8_1X16: + s->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY; + break; + case MEDIA_BUS_FMT_RGB101010_1X30: + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: + case MEDIA_BUS_FMT_YUV10_1X30: + case MEDIA_BUS_FMT_YUV8_1X24: + default: + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; + break; + } + + s->output_type = DRM_MODE_CONNECTOR_DisplayPort; + s->bus_format = bus_format; + s->bus_flags = di->bus_flags; + s->color_space = V4L2_COLORSPACE_DEFAULT; + + return 0; +} + +static const struct drm_encoder_helper_funcs dw_dp_encoder_helper_funcs = { + .atomic_check = dw_dp_encoder_atomic_check, +}; + +static int dw_dp_rockchip_bind(struct device *dev, struct device *master, void *data) +{ + struct dw_dp_plat_data plat_data; + struct drm_device *drm_dev = data; + struct rockchip_dw_dp *dp; + struct drm_encoder *encoder; + struct drm_connector *connector; + int ret; + + dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); + if (!dp) + return -ENOMEM; + + dp->dev = dev; + plat_data.max_link_rate = 810000; + encoder = &dp->encoder.encoder; + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, dev->of_node); + rockchip_drm_encoder_set_crtc_endpoint_id(&dp->encoder, dev->of_node, 0, 0); + + ret = drmm_encoder_init(drm_dev, encoder, NULL, DRM_MODE_ENCODER_TMDS, NULL); + if (ret) + return ret; + drm_encoder_helper_add(encoder, &dw_dp_encoder_helper_funcs); + + dp->base = dw_dp_bind(dev, encoder, &plat_data); + if (IS_ERR(dp->base)) { + ret = PTR_ERR(dp->base); + return ret; + } + + connector = drm_bridge_connector_init(drm_dev, encoder); + if (IS_ERR(connector)) { + ret = PTR_ERR(connector); + return dev_err_probe(dev, ret, "Failed to init bridge connector"); + } + + drm_connector_attach_encoder(connector, encoder); + + return 0; +} + +static const struct component_ops dw_dp_rockchip_component_ops = { + .bind = dw_dp_rockchip_bind, +}; + +static int dw_dp_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + return component_add(dev, &dw_dp_rockchip_component_ops); +} + +static void dw_dp_remove(struct platform_device *pdev) +{ + struct rockchip_dw_dp *dp = platform_get_drvdata(pdev); + + component_del(dp->dev, &dw_dp_rockchip_component_ops); +} + +static const struct of_device_id dw_dp_of_match[] = { + { .compatible = "rockchip,rk3588-dp", }, + {} +}; +MODULE_DEVICE_TABLE(of, dw_dp_of_match); + +struct platform_driver dw_dp_driver = { + .probe = dw_dp_probe, + .remove = dw_dp_remove, + .driver = { + .name = "dw-dp", + .of_match_table = dw_dp_of_match, + }, +}; diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c index ed88788e04dd2..687bb7b252e8e 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c @@ -531,6 +531,7 @@ static int __init rockchip_drm_init(void) ADD_ROCKCHIP_SUB_DRIVER(rockchip_dp_driver, CONFIG_ROCKCHIP_ANALOGIX_DP); ADD_ROCKCHIP_SUB_DRIVER(cdn_dp_driver, CONFIG_ROCKCHIP_CDN_DP); + ADD_ROCKCHIP_SUB_DRIVER(dw_dp_driver, CONFIG_ROCKCHIP_DW_DP); ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_rockchip_pltfm_driver, CONFIG_ROCKCHIP_DW_HDMI); ADD_ROCKCHIP_SUB_DRIVER(dw_hdmi_qp_rockchip_pltfm_driver, diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h index c183e82a42a51..2e86ad00979c4 100644 --- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.h +++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.h @@ -87,6 +87,7 @@ int rockchip_drm_encoder_set_crtc_endpoint_id(struct rockchip_encoder *rencoder, struct device_node *np, int port, int reg); int rockchip_drm_endpoint_is_subdriver(struct device_node *ep); extern struct platform_driver cdn_dp_driver; +extern struct platform_driver dw_dp_driver; extern struct platform_driver dw_hdmi_rockchip_pltfm_driver; extern struct platform_driver dw_hdmi_qp_rockchip_pltfm_driver; extern struct platform_driver dw_mipi_dsi_rockchip_driver;