Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/bridge: synopsys: Add DW DPTX Controller support library

The DW DP TX Controller is compliant with the DisplayPort Specification
Version 1.4 with the following features:

* DisplayPort 1.4a
* Main Link: 1/2/4 lanes
* Main Link Support 1.62Gbps, 2.7Gbps, 5.4Gbps and 8.1Gbps
* AUX channel 1Mbps
* Single Stream Transport(SST)
* Multistream Transport (MST)
* Type-C support (alternate mode)
* HDCP 2.2, HDCP 1.3
* Supports up to 8/10 bits per color component
* Supports RBG, YCbCr4:4:4, YCbCr4:2:2, YCbCr4:2:0
* Pixel clock up to 594MHz
* I2S, SPDIF audio interface

Add library with common helpers to make it can be shared with
other SoC.

Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Tested-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Link: https://lore.kernel.org/r/20250822063959.692098-3-andyshrk@163.com
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>

authored by

Andy Yan and committed by
Dmitry Baryshkov
86eecc3a 2b036b13

+2123
+7
drivers/gpu/drm/bridge/synopsys/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 + config DRM_DW_DP 3 + tristate 4 + select DRM_DISPLAY_HELPER 5 + select DRM_DISPLAY_DP_HELPER 6 + select DRM_KMS_HELPER 7 + select REGMAP_MMIO 8 + 2 9 config DRM_DW_HDMI 3 10 tristate 4 11 select DRM_DISPLAY_HDMI_HELPER
+1
drivers/gpu/drm/bridge/synopsys/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 + obj-$(CONFIG_DRM_DW_DP) += dw-dp.o 2 3 obj-$(CONFIG_DRM_DW_HDMI) += dw-hdmi.o 3 4 obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o 4 5 obj-$(CONFIG_DRM_DW_HDMI_GP_AUDIO) += dw-hdmi-gp-audio.o
+2095
drivers/gpu/drm/bridge/synopsys/dw-dp.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Synopsys DesignWare Cores DisplayPort Transmitter Controller 4 + * 5 + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. 6 + * 7 + * Author: Andy Yan <andy.yan@rock-chips.com> 8 + */ 9 + #include <linux/bitfield.h> 10 + #include <linux/clk.h> 11 + #include <linux/iopoll.h> 12 + #include <linux/irq.h> 13 + #include <linux/media-bus-format.h> 14 + #include <linux/of_device.h> 15 + #include <linux/platform_device.h> 16 + #include <linux/regmap.h> 17 + #include <linux/reset.h> 18 + #include <linux/phy/phy.h> 19 + #include <linux/unaligned.h> 20 + 21 + #include <drm/bridge/dw_dp.h> 22 + #include <drm/drm_atomic_helper.h> 23 + #include <drm/drm_bridge.h> 24 + #include <drm/drm_bridge_connector.h> 25 + #include <drm/display/drm_dp_helper.h> 26 + #include <drm/drm_edid.h> 27 + #include <drm/drm_of.h> 28 + #include <drm/drm_print.h> 29 + #include <drm/drm_probe_helper.h> 30 + #include <drm/drm_simple_kms_helper.h> 31 + 32 + #define DW_DP_VERSION_NUMBER 0x0000 33 + #define DW_DP_VERSION_TYPE 0x0004 34 + #define DW_DP_ID 0x0008 35 + 36 + #define DW_DP_CONFIG_REG1 0x0100 37 + #define DW_DP_CONFIG_REG2 0x0104 38 + #define DW_DP_CONFIG_REG3 0x0108 39 + 40 + #define DW_DP_CCTL 0x0200 41 + #define FORCE_HPD BIT(4) 42 + #define DEFAULT_FAST_LINK_TRAIN_EN BIT(2) 43 + #define ENHANCE_FRAMING_EN BIT(1) 44 + #define SCRAMBLE_DIS BIT(0) 45 + #define DW_DP_SOFT_RESET_CTRL 0x0204 46 + #define VIDEO_RESET BIT(5) 47 + #define AUX_RESET BIT(4) 48 + #define AUDIO_SAMPLER_RESET BIT(3) 49 + #define HDCP_MODULE_RESET BIT(2) 50 + #define PHY_SOFT_RESET BIT(1) 51 + #define CONTROLLER_RESET BIT(0) 52 + 53 + #define DW_DP_VSAMPLE_CTRL 0x0300 54 + #define PIXEL_MODE_SELECT GENMASK(22, 21) 55 + #define VIDEO_MAPPING GENMASK(20, 16) 56 + #define VIDEO_STREAM_ENABLE BIT(5) 57 + 58 + #define DW_DP_VSAMPLE_STUFF_CTRL1 0x0304 59 + 60 + #define DW_DP_VSAMPLE_STUFF_CTRL2 0x0308 61 + 62 + #define DW_DP_VINPUT_POLARITY_CTRL 0x030c 63 + #define DE_IN_POLARITY BIT(2) 64 + #define HSYNC_IN_POLARITY BIT(1) 65 + #define VSYNC_IN_POLARITY BIT(0) 66 + 67 + #define DW_DP_VIDEO_CONFIG1 0x0310 68 + #define HACTIVE GENMASK(31, 16) 69 + #define HBLANK GENMASK(15, 2) 70 + #define I_P BIT(1) 71 + #define R_V_BLANK_IN_OSC BIT(0) 72 + 73 + #define DW_DP_VIDEO_CONFIG2 0x0314 74 + #define VBLANK GENMASK(31, 16) 75 + #define VACTIVE GENMASK(15, 0) 76 + 77 + #define DW_DP_VIDEO_CONFIG3 0x0318 78 + #define H_SYNC_WIDTH GENMASK(31, 16) 79 + #define H_FRONT_PORCH GENMASK(15, 0) 80 + 81 + #define DW_DP_VIDEO_CONFIG4 0x031c 82 + #define V_SYNC_WIDTH GENMASK(31, 16) 83 + #define V_FRONT_PORCH GENMASK(15, 0) 84 + 85 + #define DW_DP_VIDEO_CONFIG5 0x0320 86 + #define INIT_THRESHOLD_HI GENMASK(22, 21) 87 + #define AVERAGE_BYTES_PER_TU_FRAC GENMASK(19, 16) 88 + #define INIT_THRESHOLD GENMASK(13, 7) 89 + #define AVERAGE_BYTES_PER_TU GENMASK(6, 0) 90 + 91 + #define DW_DP_VIDEO_MSA1 0x0324 92 + #define VSTART GENMASK(31, 16) 93 + #define HSTART GENMASK(15, 0) 94 + 95 + #define DW_DP_VIDEO_MSA2 0x0328 96 + #define MISC0 GENMASK(31, 24) 97 + 98 + #define DW_DP_VIDEO_MSA3 0x032c 99 + #define MISC1 GENMASK(31, 24) 100 + 101 + #define DW_DP_VIDEO_HBLANK_INTERVAL 0x0330 102 + #define HBLANK_INTERVAL_EN BIT(16) 103 + #define HBLANK_INTERVAL GENMASK(15, 0) 104 + 105 + #define DW_DP_AUD_CONFIG1 0x0400 106 + #define AUDIO_TIMESTAMP_VERSION_NUM GENMASK(29, 24) 107 + #define AUDIO_PACKET_ID GENMASK(23, 16) 108 + #define AUDIO_MUTE BIT(15) 109 + #define NUM_CHANNELS GENMASK(14, 12) 110 + #define HBR_MODE_ENABLE BIT(10) 111 + #define AUDIO_DATA_WIDTH GENMASK(9, 5) 112 + #define AUDIO_DATA_IN_EN GENMASK(4, 1) 113 + #define AUDIO_INF_SELECT BIT(0) 114 + 115 + #define DW_DP_SDP_VERTICAL_CTRL 0x0500 116 + #define EN_VERTICAL_SDP BIT(2) 117 + #define EN_AUDIO_STREAM_SDP BIT(1) 118 + #define EN_AUDIO_TIMESTAMP_SDP BIT(0) 119 + #define DW_DP_SDP_HORIZONTAL_CTRL 0x0504 120 + #define EN_HORIZONTAL_SDP BIT(2) 121 + #define DW_DP_SDP_STATUS_REGISTER 0x0508 122 + #define DW_DP_SDP_MANUAL_CTRL 0x050c 123 + #define DW_DP_SDP_STATUS_EN 0x0510 124 + 125 + #define DW_DP_SDP_REGISTER_BANK 0x0600 126 + #define SDP_REGS GENMASK(31, 0) 127 + 128 + #define DW_DP_PHYIF_CTRL 0x0a00 129 + #define PHY_WIDTH BIT(25) 130 + #define PHY_POWERDOWN GENMASK(20, 17) 131 + #define PHY_BUSY GENMASK(15, 12) 132 + #define SSC_DIS BIT(16) 133 + #define XMIT_ENABLE GENMASK(11, 8) 134 + #define PHY_LANES GENMASK(7, 6) 135 + #define PHY_RATE GENMASK(5, 4) 136 + #define TPS_SEL GENMASK(3, 0) 137 + 138 + #define DW_DP_PHY_TX_EQ 0x0a04 139 + #define DW_DP_CUSTOMPAT0 0x0a08 140 + #define DW_DP_CUSTOMPAT1 0x0a0c 141 + #define DW_DP_CUSTOMPAT2 0x0a10 142 + #define DW_DP_HBR2_COMPLIANCE_SCRAMBLER_RESET 0x0a14 143 + #define DW_DP_PHYIF_PWRDOWN_CTRL 0x0a18 144 + 145 + #define DW_DP_AUX_CMD 0x0b00 146 + #define AUX_CMD_TYPE GENMASK(31, 28) 147 + #define AUX_ADDR GENMASK(27, 8) 148 + #define I2C_ADDR_ONLY BIT(4) 149 + #define AUX_LEN_REQ GENMASK(3, 0) 150 + 151 + #define DW_DP_AUX_STATUS 0x0b04 152 + #define AUX_TIMEOUT BIT(17) 153 + #define AUX_BYTES_READ GENMASK(23, 19) 154 + #define AUX_STATUS GENMASK(7, 4) 155 + 156 + #define DW_DP_AUX_DATA0 0x0b08 157 + #define DW_DP_AUX_DATA1 0x0b0c 158 + #define DW_DP_AUX_DATA2 0x0b10 159 + #define DW_DP_AUX_DATA3 0x0b14 160 + 161 + #define DW_DP_GENERAL_INTERRUPT 0x0d00 162 + #define VIDEO_FIFO_OVERFLOW_STREAM0 BIT(6) 163 + #define AUDIO_FIFO_OVERFLOW_STREAM0 BIT(5) 164 + #define SDP_EVENT_STREAM0 BIT(4) 165 + #define AUX_CMD_INVALID BIT(3) 166 + #define HDCP_EVENT BIT(2) 167 + #define AUX_REPLY_EVENT BIT(1) 168 + #define HPD_EVENT BIT(0) 169 + 170 + #define DW_DP_GENERAL_INTERRUPT_ENABLE 0x0d04 171 + #define HDCP_EVENT_EN BIT(2) 172 + #define AUX_REPLY_EVENT_EN BIT(1) 173 + #define HPD_EVENT_EN BIT(0) 174 + 175 + #define DW_DP_HPD_STATUS 0x0d08 176 + #define HPD_STATE GENMASK(11, 9) 177 + #define HPD_STATUS BIT(8) 178 + #define HPD_HOT_UNPLUG BIT(2) 179 + #define HPD_HOT_PLUG BIT(1) 180 + #define HPD_IRQ BIT(0) 181 + 182 + #define DW_DP_HPD_INTERRUPT_ENABLE 0x0d0c 183 + #define HPD_UNPLUG_ERR_EN BIT(3) 184 + #define HPD_UNPLUG_EN BIT(2) 185 + #define HPD_PLUG_EN BIT(1) 186 + #define HPD_IRQ_EN BIT(0) 187 + 188 + #define DW_DP_HDCP_CFG 0x0e00 189 + #define DPCD12PLUS BIT(7) 190 + #define CP_IRQ BIT(6) 191 + #define BYPENCRYPTION BIT(5) 192 + #define HDCP_LOCK BIT(4) 193 + #define ENCRYPTIONDISABLE BIT(3) 194 + #define ENABLE_HDCP_13 BIT(2) 195 + #define ENABLE_HDCP BIT(1) 196 + 197 + #define DW_DP_HDCP_OBS 0x0e04 198 + #define HDCP22_RE_AUTHENTICATION_REQ BIT(31) 199 + #define HDCP22_AUTHENTICATION_FAILED BIT(30) 200 + #define HDCP22_AUTHENTICATION_SUCCESS BIT(29) 201 + #define HDCP22_CAPABLE_SINK BIT(28) 202 + #define HDCP22_SINK_CAP_CHECK_COMPLETE BIT(27) 203 + #define HDCP22_STATE GENMASK(26, 24) 204 + #define HDCP22_BOOTED BIT(23) 205 + #define HDCP13_BSTATUS GENMASK(22, 19) 206 + #define REPEATER BIT(18) 207 + #define HDCP_CAPABLE BIT(17) 208 + #define STATEE GENMASK(16, 14) 209 + #define STATEOEG GENMASK(13, 11) 210 + #define STATER GENMASK(10, 8) 211 + #define STATEA GENMASK(7, 4) 212 + #define SUBSTATEA GENMASK(3, 1) 213 + #define HDCPENGAGED BIT(0) 214 + 215 + #define DW_DP_HDCP_APIINTCLR 0x0e08 216 + #define DW_DP_HDCP_APIINTSTAT 0x0e0c 217 + #define DW_DP_HDCP_APIINTMSK 0x0e10 218 + #define HDCP22_GPIOINT BIT(8) 219 + #define HDCP_ENGAGED BIT(7) 220 + #define HDCP_FAILED BIT(6) 221 + #define KSVSHA1CALCDONEINT BIT(5) 222 + #define AUXRESPNACK7TIMES BIT(4) 223 + #define AUXRESPTIMEOUT BIT(3) 224 + #define AUXRESPDEFER7TIMES BIT(2) 225 + #define KSVACCESSINT BIT(0) 226 + 227 + #define DW_DP_HDCP_KSVMEMCTRL 0x0e18 228 + #define KSVSHA1STATUS BIT(4) 229 + #define KSVMEMACCESS BIT(1) 230 + #define KSVMEMREQUEST BIT(0) 231 + 232 + #define DW_DP_HDCP_REG_BKSV0 0x3600 233 + #define DW_DP_HDCP_REG_BKSV1 0x3604 234 + #define DW_DP_HDCP_REG_ANCONF 0x3608 235 + #define AN_BYPASS BIT(0) 236 + 237 + #define DW_DP_HDCP_REG_AN0 0x360c 238 + #define DW_DP_HDCP_REG_AN1 0x3610 239 + #define DW_DP_HDCP_REG_RMLCTL 0x3614 240 + #define ODPK_DECRYPT_ENABLE BIT(0) 241 + 242 + #define DW_DP_HDCP_REG_RMLSTS 0x3618 243 + #define IDPK_WR_OK_STS BIT(6) 244 + #define IDPK_DATA_INDEX GENMASK(5, 0) 245 + #define DW_DP_HDCP_REG_SEED 0x361c 246 + #define DW_DP_HDCP_REG_DPK0 0x3620 247 + #define DW_DP_HDCP_REG_DPK1 0x3624 248 + #define DW_DP_HDCP22_GPIOSTS 0x3628 249 + #define DW_DP_HDCP22_GPIOCHNGSTS 0x362c 250 + #define DW_DP_HDCP_REG_DPK_CRC 0x3630 251 + 252 + #define DW_DP_MAX_REGISTER DW_DP_HDCP_REG_DPK_CRC 253 + 254 + #define SDP_REG_BANK_SIZE 16 255 + 256 + struct dw_dp_link_caps { 257 + bool enhanced_framing; 258 + bool tps3_supported; 259 + bool tps4_supported; 260 + bool fast_training; 261 + bool channel_coding; 262 + bool ssc; 263 + }; 264 + 265 + struct dw_dp_link_train_set { 266 + unsigned int voltage_swing[4]; 267 + unsigned int pre_emphasis[4]; 268 + bool voltage_max_reached[4]; 269 + bool pre_max_reached[4]; 270 + }; 271 + 272 + struct dw_dp_link_train { 273 + struct dw_dp_link_train_set adjust; 274 + bool clock_recovered; 275 + bool channel_equalized; 276 + }; 277 + 278 + struct dw_dp_link { 279 + u8 dpcd[DP_RECEIVER_CAP_SIZE]; 280 + unsigned char revision; 281 + unsigned int rate; 282 + unsigned int lanes; 283 + u8 sink_count; 284 + u8 vsc_sdp_supported; 285 + struct dw_dp_link_caps caps; 286 + struct dw_dp_link_train train; 287 + struct drm_dp_desc desc; 288 + }; 289 + 290 + struct dw_dp_bridge_state { 291 + struct drm_bridge_state base; 292 + struct drm_display_mode mode; 293 + u8 video_mapping; 294 + u8 color_format; 295 + u8 bpc; 296 + u8 bpp; 297 + }; 298 + 299 + struct dw_dp_sdp { 300 + struct dp_sdp base; 301 + unsigned long flags; 302 + }; 303 + 304 + struct dw_dp_hotplug { 305 + bool long_hpd; 306 + }; 307 + 308 + struct dw_dp { 309 + struct drm_bridge bridge; 310 + struct device *dev; 311 + struct regmap *regmap; 312 + struct phy *phy; 313 + struct clk *apb_clk; 314 + struct clk *aux_clk; 315 + struct clk *i2s_clk; 316 + struct clk *spdif_clk; 317 + struct clk *hdcp_clk; 318 + struct reset_control *rstc; 319 + struct completion complete; 320 + int irq; 321 + struct work_struct hpd_work; 322 + struct dw_dp_hotplug hotplug; 323 + /* Serialize hpd status access */ 324 + struct mutex irq_lock; 325 + 326 + struct drm_dp_aux aux; 327 + 328 + struct dw_dp_link link; 329 + struct dw_dp_plat_data plat_data; 330 + u8 pixel_mode; 331 + 332 + DECLARE_BITMAP(sdp_reg_bank, SDP_REG_BANK_SIZE); 333 + }; 334 + 335 + enum { 336 + DW_DP_RGB_6BIT, 337 + DW_DP_RGB_8BIT, 338 + DW_DP_RGB_10BIT, 339 + DW_DP_RGB_12BIT, 340 + DW_DP_RGB_16BIT, 341 + DW_DP_YCBCR444_8BIT, 342 + DW_DP_YCBCR444_10BIT, 343 + DW_DP_YCBCR444_12BIT, 344 + DW_DP_YCBCR444_16BIT, 345 + DW_DP_YCBCR422_8BIT, 346 + DW_DP_YCBCR422_10BIT, 347 + DW_DP_YCBCR422_12BIT, 348 + DW_DP_YCBCR422_16BIT, 349 + DW_DP_YCBCR420_8BIT, 350 + DW_DP_YCBCR420_10BIT, 351 + DW_DP_YCBCR420_12BIT, 352 + DW_DP_YCBCR420_16BIT, 353 + }; 354 + 355 + enum { 356 + DW_DP_MP_SINGLE_PIXEL, 357 + DW_DP_MP_DUAL_PIXEL, 358 + DW_DP_MP_QUAD_PIXEL, 359 + }; 360 + 361 + enum { 362 + DW_DP_SDP_VERTICAL_INTERVAL = BIT(0), 363 + DW_DP_SDP_HORIZONTAL_INTERVAL = BIT(1), 364 + }; 365 + 366 + enum { 367 + DW_DP_HPD_STATE_IDLE, 368 + DW_DP_HPD_STATE_UNPLUG, 369 + DP_DP_HPD_STATE_TIMEOUT = 4, 370 + DW_DP_HPD_STATE_PLUG = 7 371 + }; 372 + 373 + enum { 374 + DW_DP_PHY_PATTERN_NONE, 375 + DW_DP_PHY_PATTERN_TPS_1, 376 + DW_DP_PHY_PATTERN_TPS_2, 377 + DW_DP_PHY_PATTERN_TPS_3, 378 + DW_DP_PHY_PATTERN_TPS_4, 379 + DW_DP_PHY_PATTERN_SERM, 380 + DW_DP_PHY_PATTERN_PBRS7, 381 + DW_DP_PHY_PATTERN_CUSTOM_80BIT, 382 + DW_DP_PHY_PATTERN_CP2520_1, 383 + DW_DP_PHY_PATTERN_CP2520_2, 384 + }; 385 + 386 + struct dw_dp_output_format { 387 + u32 bus_format; 388 + u32 color_format; 389 + u8 video_mapping; 390 + u8 bpc; 391 + u8 bpp; 392 + }; 393 + 394 + #define to_dw_dp_bridge_state(s) container_of(s, struct dw_dp_bridge_state, base) 395 + 396 + static const struct dw_dp_output_format dw_dp_output_formats[] = { 397 + { MEDIA_BUS_FMT_RGB101010_1X30, DRM_COLOR_FORMAT_RGB444, DW_DP_RGB_10BIT, 10, 30 }, 398 + { MEDIA_BUS_FMT_RGB888_1X24, DRM_COLOR_FORMAT_RGB444, DW_DP_RGB_8BIT, 8, 24 }, 399 + { MEDIA_BUS_FMT_YUV10_1X30, DRM_COLOR_FORMAT_YCBCR444, DW_DP_YCBCR444_10BIT, 10, 30 }, 400 + { MEDIA_BUS_FMT_YUV8_1X24, DRM_COLOR_FORMAT_YCBCR444, DW_DP_YCBCR444_8BIT, 8, 24}, 401 + { MEDIA_BUS_FMT_YUYV10_1X20, DRM_COLOR_FORMAT_YCBCR422, DW_DP_YCBCR422_10BIT, 10, 20 }, 402 + { MEDIA_BUS_FMT_YUYV8_1X16, DRM_COLOR_FORMAT_YCBCR422, DW_DP_YCBCR422_8BIT, 8, 16 }, 403 + { MEDIA_BUS_FMT_UYYVYY10_0_5X30, DRM_COLOR_FORMAT_YCBCR420, DW_DP_YCBCR420_10BIT, 10, 15 }, 404 + { MEDIA_BUS_FMT_UYYVYY8_0_5X24, DRM_COLOR_FORMAT_YCBCR420, DW_DP_YCBCR420_8BIT, 8, 12 }, 405 + { MEDIA_BUS_FMT_RGB666_1X24_CPADHI, DRM_COLOR_FORMAT_RGB444, DW_DP_RGB_6BIT, 6, 18 }, 406 + }; 407 + 408 + static const struct dw_dp_output_format *dw_dp_get_output_format(u32 bus_format) 409 + { 410 + unsigned int i; 411 + 412 + for (i = 0; i < ARRAY_SIZE(dw_dp_output_formats); i++) 413 + if (dw_dp_output_formats[i].bus_format == bus_format) 414 + return &dw_dp_output_formats[i]; 415 + 416 + return NULL; 417 + } 418 + 419 + static inline struct dw_dp *bridge_to_dp(struct drm_bridge *b) 420 + { 421 + return container_of(b, struct dw_dp, bridge); 422 + } 423 + 424 + static struct dw_dp_bridge_state *dw_dp_get_bridge_state(struct dw_dp *dp) 425 + { 426 + struct dw_dp_bridge_state *dw_bridge_state; 427 + struct drm_bridge_state *state; 428 + 429 + state = drm_priv_to_bridge_state(dp->bridge.base.state); 430 + if (!state) 431 + return NULL; 432 + 433 + dw_bridge_state = to_dw_dp_bridge_state(state); 434 + if (!dw_bridge_state) 435 + return NULL; 436 + 437 + return dw_bridge_state; 438 + } 439 + 440 + static inline void dw_dp_phy_set_pattern(struct dw_dp *dp, u32 pattern) 441 + { 442 + regmap_update_bits(dp->regmap, DW_DP_PHYIF_CTRL, TPS_SEL, 443 + FIELD_PREP(TPS_SEL, pattern)); 444 + } 445 + 446 + static void dw_dp_phy_xmit_enable(struct dw_dp *dp, u32 lanes) 447 + { 448 + u32 xmit_enable; 449 + 450 + switch (lanes) { 451 + case 4: 452 + case 2: 453 + case 1: 454 + xmit_enable = GENMASK(lanes - 1, 0); 455 + break; 456 + case 0: 457 + default: 458 + xmit_enable = 0; 459 + break; 460 + } 461 + 462 + regmap_update_bits(dp->regmap, DW_DP_PHYIF_CTRL, XMIT_ENABLE, 463 + FIELD_PREP(XMIT_ENABLE, xmit_enable)); 464 + } 465 + 466 + static bool dw_dp_bandwidth_ok(struct dw_dp *dp, 467 + const struct drm_display_mode *mode, u32 bpp, 468 + unsigned int lanes, unsigned int rate) 469 + { 470 + u32 max_bw, req_bw; 471 + 472 + req_bw = mode->clock * bpp / 8; 473 + max_bw = lanes * rate; 474 + if (req_bw > max_bw) 475 + return false; 476 + 477 + return true; 478 + } 479 + 480 + static bool dw_dp_hpd_detect(struct dw_dp *dp) 481 + { 482 + u32 value; 483 + 484 + regmap_read(dp->regmap, DW_DP_HPD_STATUS, &value); 485 + 486 + return FIELD_GET(HPD_STATE, value) == DW_DP_HPD_STATE_PLUG; 487 + } 488 + 489 + static void dw_dp_link_caps_reset(struct dw_dp_link_caps *caps) 490 + { 491 + caps->enhanced_framing = false; 492 + caps->tps3_supported = false; 493 + caps->tps4_supported = false; 494 + caps->fast_training = false; 495 + caps->channel_coding = false; 496 + } 497 + 498 + static void dw_dp_link_reset(struct dw_dp_link *link) 499 + { 500 + link->vsc_sdp_supported = 0; 501 + link->sink_count = 0; 502 + link->revision = 0; 503 + link->rate = 0; 504 + link->lanes = 0; 505 + 506 + dw_dp_link_caps_reset(&link->caps); 507 + memset(link->dpcd, 0, sizeof(link->dpcd)); 508 + } 509 + 510 + static int dw_dp_link_parse(struct dw_dp *dp, struct drm_connector *connector) 511 + { 512 + struct dw_dp_link *link = &dp->link; 513 + int ret; 514 + 515 + dw_dp_link_reset(link); 516 + 517 + ret = drm_dp_read_dpcd_caps(&dp->aux, link->dpcd); 518 + if (ret < 0) 519 + return ret; 520 + 521 + drm_dp_read_desc(&dp->aux, &link->desc, drm_dp_is_branch(link->dpcd)); 522 + 523 + if (drm_dp_read_sink_count_cap(connector, link->dpcd, &link->desc)) { 524 + ret = drm_dp_read_sink_count(&dp->aux); 525 + if (ret < 0) 526 + return ret; 527 + 528 + link->sink_count = ret; 529 + 530 + /* Dongle connected, but no display */ 531 + if (!link->sink_count) 532 + return -ENODEV; 533 + } 534 + 535 + link->vsc_sdp_supported = drm_dp_vsc_sdp_supported(&dp->aux, link->dpcd); 536 + 537 + link->revision = link->dpcd[DP_DPCD_REV]; 538 + link->rate = min_t(u32, min(dp->plat_data.max_link_rate, 539 + dp->phy->attrs.max_link_rate * 100), 540 + drm_dp_max_link_rate(link->dpcd)); 541 + link->lanes = min_t(u8, phy_get_bus_width(dp->phy), 542 + drm_dp_max_lane_count(link->dpcd)); 543 + 544 + link->caps.enhanced_framing = drm_dp_enhanced_frame_cap(link->dpcd); 545 + link->caps.tps3_supported = drm_dp_tps3_supported(link->dpcd); 546 + link->caps.tps4_supported = drm_dp_tps4_supported(link->dpcd); 547 + link->caps.fast_training = drm_dp_fast_training_cap(link->dpcd); 548 + link->caps.channel_coding = drm_dp_channel_coding_supported(link->dpcd); 549 + link->caps.ssc = !!(link->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5); 550 + 551 + return 0; 552 + } 553 + 554 + static int dw_dp_link_train_update_vs_emph(struct dw_dp *dp) 555 + { 556 + struct dw_dp_link *link = &dp->link; 557 + struct dw_dp_link_train_set *train_set = &link->train.adjust; 558 + unsigned int lanes = dp->link.lanes; 559 + union phy_configure_opts phy_cfg; 560 + unsigned int *vs, *pe; 561 + int i, ret; 562 + u8 buf[4]; 563 + 564 + vs = train_set->voltage_swing; 565 + pe = train_set->pre_emphasis; 566 + 567 + for (i = 0; i < lanes; i++) { 568 + phy_cfg.dp.voltage[i] = vs[i]; 569 + phy_cfg.dp.pre[i] = pe[i]; 570 + } 571 + 572 + phy_cfg.dp.set_lanes = false; 573 + phy_cfg.dp.set_rate = false; 574 + phy_cfg.dp.set_voltages = true; 575 + 576 + ret = phy_configure(dp->phy, &phy_cfg); 577 + if (ret) 578 + return ret; 579 + 580 + for (i = 0; i < lanes; i++) { 581 + buf[i] = (vs[i] << DP_TRAIN_VOLTAGE_SWING_SHIFT) | 582 + (pe[i] << DP_TRAIN_PRE_EMPHASIS_SHIFT); 583 + if (train_set->voltage_max_reached[i]) 584 + buf[i] |= DP_TRAIN_MAX_SWING_REACHED; 585 + if (train_set->pre_max_reached[i]) 586 + buf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; 587 + } 588 + 589 + ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, buf, lanes); 590 + if (ret < 0) 591 + return ret; 592 + 593 + return 0; 594 + } 595 + 596 + static int dw_dp_phy_configure(struct dw_dp *dp, unsigned int rate, 597 + unsigned int lanes, bool ssc) 598 + { 599 + union phy_configure_opts phy_cfg; 600 + int ret; 601 + 602 + /* Move PHY to P3 */ 603 + regmap_update_bits(dp->regmap, DW_DP_PHYIF_CTRL, PHY_POWERDOWN, 604 + FIELD_PREP(PHY_POWERDOWN, 0x3)); 605 + 606 + phy_cfg.dp.lanes = lanes; 607 + phy_cfg.dp.link_rate = rate / 100; 608 + phy_cfg.dp.ssc = ssc; 609 + phy_cfg.dp.set_lanes = true; 610 + phy_cfg.dp.set_rate = true; 611 + phy_cfg.dp.set_voltages = false; 612 + ret = phy_configure(dp->phy, &phy_cfg); 613 + if (ret) 614 + return ret; 615 + 616 + regmap_update_bits(dp->regmap, DW_DP_PHYIF_CTRL, PHY_LANES, 617 + FIELD_PREP(PHY_LANES, lanes / 2)); 618 + 619 + /* Move PHY to P0 */ 620 + regmap_update_bits(dp->regmap, DW_DP_PHYIF_CTRL, PHY_POWERDOWN, 621 + FIELD_PREP(PHY_POWERDOWN, 0x0)); 622 + 623 + dw_dp_phy_xmit_enable(dp, lanes); 624 + 625 + return 0; 626 + } 627 + 628 + static int dw_dp_link_configure(struct dw_dp *dp) 629 + { 630 + struct dw_dp_link *link = &dp->link; 631 + u8 buf[2]; 632 + int ret; 633 + 634 + ret = dw_dp_phy_configure(dp, link->rate, link->lanes, link->caps.ssc); 635 + if (ret) 636 + return ret; 637 + 638 + buf[0] = drm_dp_link_rate_to_bw_code(link->rate); 639 + buf[1] = link->lanes; 640 + 641 + if (link->caps.enhanced_framing) { 642 + buf[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; 643 + regmap_update_bits(dp->regmap, DW_DP_CCTL, ENHANCE_FRAMING_EN, 644 + FIELD_PREP(ENHANCE_FRAMING_EN, 1)); 645 + } else { 646 + regmap_update_bits(dp->regmap, DW_DP_CCTL, ENHANCE_FRAMING_EN, 647 + FIELD_PREP(ENHANCE_FRAMING_EN, 0)); 648 + } 649 + 650 + ret = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, sizeof(buf)); 651 + if (ret < 0) 652 + return ret; 653 + 654 + buf[0] = link->caps.ssc ? DP_SPREAD_AMP_0_5 : 0; 655 + buf[1] = link->caps.channel_coding ? DP_SET_ANSI_8B10B : 0; 656 + 657 + ret = drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, buf, sizeof(buf)); 658 + if (ret < 0) 659 + return ret; 660 + 661 + return 0; 662 + } 663 + 664 + static void dw_dp_link_train_init(struct dw_dp_link_train *train) 665 + { 666 + struct dw_dp_link_train_set *adj = &train->adjust; 667 + unsigned int i; 668 + 669 + for (i = 0; i < 4; i++) { 670 + adj->voltage_swing[i] = 0; 671 + adj->pre_emphasis[i] = 0; 672 + adj->voltage_max_reached[i] = false; 673 + adj->pre_max_reached[i] = false; 674 + } 675 + 676 + train->clock_recovered = false; 677 + train->channel_equalized = false; 678 + } 679 + 680 + static bool dw_dp_link_train_valid(const struct dw_dp_link_train *train) 681 + { 682 + return train->clock_recovered && train->channel_equalized; 683 + } 684 + 685 + static int dw_dp_link_train_set_pattern(struct dw_dp *dp, u32 pattern) 686 + { 687 + u8 buf = 0; 688 + int ret; 689 + 690 + if (pattern && pattern != DP_TRAINING_PATTERN_4) { 691 + buf |= DP_LINK_SCRAMBLING_DISABLE; 692 + 693 + regmap_update_bits(dp->regmap, DW_DP_CCTL, SCRAMBLE_DIS, 694 + FIELD_PREP(SCRAMBLE_DIS, 1)); 695 + } else { 696 + regmap_update_bits(dp->regmap, DW_DP_CCTL, SCRAMBLE_DIS, 697 + FIELD_PREP(SCRAMBLE_DIS, 0)); 698 + } 699 + 700 + switch (pattern) { 701 + case DP_TRAINING_PATTERN_DISABLE: 702 + dw_dp_phy_set_pattern(dp, DW_DP_PHY_PATTERN_NONE); 703 + break; 704 + case DP_TRAINING_PATTERN_1: 705 + dw_dp_phy_set_pattern(dp, DW_DP_PHY_PATTERN_TPS_1); 706 + break; 707 + case DP_TRAINING_PATTERN_2: 708 + dw_dp_phy_set_pattern(dp, DW_DP_PHY_PATTERN_TPS_2); 709 + break; 710 + case DP_TRAINING_PATTERN_3: 711 + dw_dp_phy_set_pattern(dp, DW_DP_PHY_PATTERN_TPS_3); 712 + break; 713 + case DP_TRAINING_PATTERN_4: 714 + dw_dp_phy_set_pattern(dp, DW_DP_PHY_PATTERN_TPS_4); 715 + break; 716 + default: 717 + return -EINVAL; 718 + } 719 + 720 + ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, 721 + buf | pattern); 722 + if (ret < 0) 723 + return ret; 724 + 725 + return 0; 726 + } 727 + 728 + static u8 dw_dp_voltage_max(u8 preemph) 729 + { 730 + switch (preemph & DP_TRAIN_PRE_EMPHASIS_MASK) { 731 + case DP_TRAIN_PRE_EMPH_LEVEL_0: 732 + return DP_TRAIN_VOLTAGE_SWING_LEVEL_3; 733 + case DP_TRAIN_PRE_EMPH_LEVEL_1: 734 + return DP_TRAIN_VOLTAGE_SWING_LEVEL_2; 735 + case DP_TRAIN_PRE_EMPH_LEVEL_2: 736 + return DP_TRAIN_VOLTAGE_SWING_LEVEL_1; 737 + case DP_TRAIN_PRE_EMPH_LEVEL_3: 738 + default: 739 + return DP_TRAIN_VOLTAGE_SWING_LEVEL_0; 740 + } 741 + } 742 + 743 + static bool dw_dp_link_get_adjustments(struct dw_dp_link *link, 744 + u8 status[DP_LINK_STATUS_SIZE]) 745 + { 746 + struct dw_dp_link_train_set *adj = &link->train.adjust; 747 + unsigned int i; 748 + bool changed = false; 749 + u8 v = 0; 750 + u8 p = 0; 751 + 752 + for (i = 0; i < link->lanes; i++) { 753 + v = drm_dp_get_adjust_request_voltage(status, i); 754 + v >>= DP_TRAIN_VOLTAGE_SWING_SHIFT; 755 + p = drm_dp_get_adjust_request_pre_emphasis(status, i); 756 + p >>= DP_TRAIN_PRE_EMPHASIS_SHIFT; 757 + 758 + if (v != adj->voltage_swing[i] || p != adj->pre_emphasis[i]) 759 + changed = true; 760 + 761 + if (p >= (DP_TRAIN_PRE_EMPH_LEVEL_3 >> DP_TRAIN_PRE_EMPHASIS_SHIFT)) { 762 + adj->pre_emphasis[i] = DP_TRAIN_PRE_EMPH_LEVEL_3 >> 763 + DP_TRAIN_PRE_EMPHASIS_SHIFT; 764 + adj->pre_max_reached[i] = true; 765 + } else { 766 + adj->pre_emphasis[i] = p; 767 + adj->pre_max_reached[i] = false; 768 + } 769 + 770 + v = min(v, dw_dp_voltage_max(p)); 771 + if (v >= (DP_TRAIN_VOLTAGE_SWING_LEVEL_3 >> DP_TRAIN_VOLTAGE_SWING_SHIFT)) { 772 + adj->voltage_swing[i] = DP_TRAIN_VOLTAGE_SWING_LEVEL_3 >> 773 + DP_TRAIN_VOLTAGE_SWING_SHIFT; 774 + adj->voltage_max_reached[i] = true; 775 + } else { 776 + adj->voltage_swing[i] = v; 777 + adj->voltage_max_reached[i] = false; 778 + } 779 + } 780 + 781 + return changed; 782 + } 783 + 784 + static int dw_dp_link_clock_recovery(struct dw_dp *dp) 785 + { 786 + struct dw_dp_link *link = &dp->link; 787 + u8 status[DP_LINK_STATUS_SIZE]; 788 + unsigned int tries = 0; 789 + int ret; 790 + bool adj_changed; 791 + 792 + ret = dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_1); 793 + if (ret) 794 + return ret; 795 + 796 + for (;;) { 797 + ret = dw_dp_link_train_update_vs_emph(dp); 798 + if (ret) 799 + return ret; 800 + 801 + drm_dp_link_train_clock_recovery_delay(&dp->aux, link->dpcd); 802 + 803 + ret = drm_dp_dpcd_read_link_status(&dp->aux, status); 804 + if (ret < 0) { 805 + dev_err(dp->dev, "failed to read link status: %d\n", ret); 806 + return ret; 807 + } 808 + 809 + if (drm_dp_clock_recovery_ok(status, link->lanes)) { 810 + link->train.clock_recovered = true; 811 + break; 812 + } 813 + 814 + /* 815 + * According to DP spec 1.4, if current ADJ is the same 816 + * with previous REQ, we need to retry 5 times. 817 + */ 818 + adj_changed = dw_dp_link_get_adjustments(link, status); 819 + if (!adj_changed) 820 + tries++; 821 + else 822 + tries = 0; 823 + 824 + if (tries == 5) 825 + break; 826 + } 827 + 828 + return 0; 829 + } 830 + 831 + static int dw_dp_link_channel_equalization(struct dw_dp *dp) 832 + { 833 + struct dw_dp_link *link = &dp->link; 834 + u8 status[DP_LINK_STATUS_SIZE], pattern; 835 + unsigned int tries; 836 + int ret; 837 + 838 + if (link->caps.tps4_supported) 839 + pattern = DP_TRAINING_PATTERN_4; 840 + else if (link->caps.tps3_supported) 841 + pattern = DP_TRAINING_PATTERN_3; 842 + else 843 + pattern = DP_TRAINING_PATTERN_2; 844 + ret = dw_dp_link_train_set_pattern(dp, pattern); 845 + if (ret) 846 + return ret; 847 + 848 + for (tries = 1; tries < 5; tries++) { 849 + ret = dw_dp_link_train_update_vs_emph(dp); 850 + if (ret) 851 + return ret; 852 + 853 + drm_dp_link_train_channel_eq_delay(&dp->aux, link->dpcd); 854 + 855 + ret = drm_dp_dpcd_read_link_status(&dp->aux, status); 856 + if (ret < 0) 857 + return ret; 858 + 859 + if (!drm_dp_clock_recovery_ok(status, link->lanes)) { 860 + dev_err(dp->dev, "clock recovery lost while equalizing channel\n"); 861 + link->train.clock_recovered = false; 862 + break; 863 + } 864 + 865 + if (drm_dp_channel_eq_ok(status, link->lanes)) { 866 + link->train.channel_equalized = true; 867 + break; 868 + } 869 + 870 + dw_dp_link_get_adjustments(link, status); 871 + } 872 + 873 + return 0; 874 + } 875 + 876 + static int dw_dp_link_downgrade(struct dw_dp *dp) 877 + { 878 + struct dw_dp_link *link = &dp->link; 879 + struct dw_dp_bridge_state *state; 880 + 881 + state = dw_dp_get_bridge_state(dp); 882 + 883 + switch (link->rate) { 884 + case 162000: 885 + return -EINVAL; 886 + case 270000: 887 + link->rate = 162000; 888 + break; 889 + case 540000: 890 + link->rate = 270000; 891 + break; 892 + case 810000: 893 + link->rate = 540000; 894 + break; 895 + } 896 + 897 + if (!dw_dp_bandwidth_ok(dp, &state->mode, state->bpp, link->lanes, 898 + link->rate)) 899 + return -E2BIG; 900 + 901 + return 0; 902 + } 903 + 904 + static int dw_dp_link_train_full(struct dw_dp *dp) 905 + { 906 + struct dw_dp_link *link = &dp->link; 907 + int ret; 908 + 909 + retry: 910 + dw_dp_link_train_init(&link->train); 911 + 912 + dev_dbg(dp->dev, "full-training link: %u lane%s at %u MHz\n", 913 + link->lanes, (link->lanes > 1) ? "s" : "", link->rate / 100); 914 + 915 + ret = dw_dp_link_configure(dp); 916 + if (ret < 0) { 917 + dev_err(dp->dev, "failed to configure DP link: %d\n", ret); 918 + return ret; 919 + } 920 + 921 + ret = dw_dp_link_clock_recovery(dp); 922 + if (ret < 0) { 923 + dev_err(dp->dev, "clock recovery failed: %d\n", ret); 924 + goto out; 925 + } 926 + 927 + if (!link->train.clock_recovered) { 928 + dev_err(dp->dev, "clock recovery failed, downgrading link\n"); 929 + 930 + ret = dw_dp_link_downgrade(dp); 931 + if (ret < 0) 932 + goto out; 933 + else 934 + goto retry; 935 + } 936 + 937 + dev_dbg(dp->dev, "clock recovery succeeded\n"); 938 + 939 + ret = dw_dp_link_channel_equalization(dp); 940 + if (ret < 0) { 941 + dev_err(dp->dev, "channel equalization failed: %d\n", ret); 942 + goto out; 943 + } 944 + 945 + if (!link->train.channel_equalized) { 946 + dev_err(dp->dev, "channel equalization failed, downgrading link\n"); 947 + 948 + ret = dw_dp_link_downgrade(dp); 949 + if (ret < 0) 950 + goto out; 951 + else 952 + goto retry; 953 + } 954 + 955 + dev_dbg(dp->dev, "channel equalization succeeded\n"); 956 + 957 + out: 958 + dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE); 959 + return ret; 960 + } 961 + 962 + static int dw_dp_link_train_fast(struct dw_dp *dp) 963 + { 964 + struct dw_dp_link *link = &dp->link; 965 + int ret; 966 + u8 status[DP_LINK_STATUS_SIZE]; 967 + u8 pattern; 968 + 969 + dw_dp_link_train_init(&link->train); 970 + 971 + dev_dbg(dp->dev, "fast-training link: %u lane%s at %u MHz\n", 972 + link->lanes, (link->lanes > 1) ? "s" : "", link->rate / 100); 973 + 974 + ret = dw_dp_link_configure(dp); 975 + if (ret < 0) { 976 + dev_err(dp->dev, "failed to configure DP link: %d\n", ret); 977 + return ret; 978 + } 979 + 980 + ret = dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_1); 981 + if (ret) 982 + goto out; 983 + 984 + usleep_range(500, 1000); 985 + 986 + if (link->caps.tps4_supported) 987 + pattern = DP_TRAINING_PATTERN_4; 988 + else if (link->caps.tps3_supported) 989 + pattern = DP_TRAINING_PATTERN_3; 990 + else 991 + pattern = DP_TRAINING_PATTERN_2; 992 + ret = dw_dp_link_train_set_pattern(dp, pattern); 993 + if (ret) 994 + goto out; 995 + 996 + usleep_range(500, 1000); 997 + 998 + ret = drm_dp_dpcd_read_link_status(&dp->aux, status); 999 + if (ret < 0) { 1000 + dev_err(dp->dev, "failed to read link status: %d\n", ret); 1001 + goto out; 1002 + } 1003 + 1004 + if (!drm_dp_clock_recovery_ok(status, link->lanes)) { 1005 + dev_err(dp->dev, "clock recovery failed\n"); 1006 + ret = -EIO; 1007 + goto out; 1008 + } 1009 + 1010 + if (!drm_dp_channel_eq_ok(status, link->lanes)) { 1011 + dev_err(dp->dev, "channel equalization failed\n"); 1012 + ret = -EIO; 1013 + goto out; 1014 + } 1015 + 1016 + out: 1017 + dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE); 1018 + return ret; 1019 + } 1020 + 1021 + static int dw_dp_link_train(struct dw_dp *dp) 1022 + { 1023 + struct dw_dp_link *link = &dp->link; 1024 + int ret; 1025 + 1026 + if (link->caps.fast_training) { 1027 + if (dw_dp_link_train_valid(&link->train)) { 1028 + ret = dw_dp_link_train_fast(dp); 1029 + if (ret < 0) 1030 + dev_err(dp->dev, "fast link training failed: %d\n", ret); 1031 + else 1032 + return 0; 1033 + } 1034 + } 1035 + 1036 + ret = dw_dp_link_train_full(dp); 1037 + if (ret < 0) { 1038 + dev_err(dp->dev, "full link training failed: %d\n", ret); 1039 + return ret; 1040 + } 1041 + 1042 + return 0; 1043 + } 1044 + 1045 + static int dw_dp_send_sdp(struct dw_dp *dp, struct dw_dp_sdp *sdp) 1046 + { 1047 + const u8 *payload = sdp->base.db; 1048 + u32 reg; 1049 + int i, nr; 1050 + 1051 + nr = find_first_zero_bit(dp->sdp_reg_bank, SDP_REG_BANK_SIZE); 1052 + if (nr < SDP_REG_BANK_SIZE) 1053 + set_bit(nr, dp->sdp_reg_bank); 1054 + else 1055 + return -EBUSY; 1056 + 1057 + reg = DW_DP_SDP_REGISTER_BANK + nr * 9 * 4; 1058 + 1059 + /* SDP header */ 1060 + regmap_write(dp->regmap, reg, get_unaligned_le32(&sdp->base.sdp_header)); 1061 + 1062 + /* SDP data payload */ 1063 + for (i = 1; i < 9; i++, payload += 4) 1064 + regmap_write(dp->regmap, reg + i * 4, 1065 + FIELD_PREP(SDP_REGS, get_unaligned_le32(payload))); 1066 + 1067 + if (sdp->flags & DW_DP_SDP_VERTICAL_INTERVAL) 1068 + regmap_update_bits(dp->regmap, DW_DP_SDP_VERTICAL_CTRL, 1069 + EN_VERTICAL_SDP << nr, 1070 + EN_VERTICAL_SDP << nr); 1071 + 1072 + if (sdp->flags & DW_DP_SDP_HORIZONTAL_INTERVAL) 1073 + regmap_update_bits(dp->regmap, DW_DP_SDP_HORIZONTAL_CTRL, 1074 + EN_HORIZONTAL_SDP << nr, 1075 + EN_HORIZONTAL_SDP << nr); 1076 + 1077 + return 0; 1078 + } 1079 + 1080 + static int dw_dp_send_vsc_sdp(struct dw_dp *dp) 1081 + { 1082 + struct dw_dp_bridge_state *state; 1083 + struct dw_dp_sdp sdp = {}; 1084 + struct drm_dp_vsc_sdp vsc = {}; 1085 + 1086 + state = dw_dp_get_bridge_state(dp); 1087 + if (!state) 1088 + return -EINVAL; 1089 + 1090 + vsc.bpc = state->bpc; 1091 + 1092 + vsc.sdp_type = DP_SDP_VSC; 1093 + vsc.revision = 0x5; 1094 + vsc.length = 0x13; 1095 + vsc.content_type = DP_CONTENT_TYPE_NOT_DEFINED; 1096 + 1097 + sdp.flags = DW_DP_SDP_VERTICAL_INTERVAL; 1098 + 1099 + switch (state->color_format) { 1100 + case DRM_COLOR_FORMAT_YCBCR444: 1101 + vsc.pixelformat = DP_PIXELFORMAT_YUV444; 1102 + break; 1103 + case DRM_COLOR_FORMAT_YCBCR420: 1104 + vsc.pixelformat = DP_PIXELFORMAT_YUV420; 1105 + break; 1106 + case DRM_COLOR_FORMAT_YCBCR422: 1107 + vsc.pixelformat = DP_PIXELFORMAT_YUV422; 1108 + break; 1109 + case DRM_COLOR_FORMAT_RGB444: 1110 + default: 1111 + vsc.pixelformat = DP_PIXELFORMAT_RGB; 1112 + break; 1113 + } 1114 + 1115 + if (state->color_format == DRM_COLOR_FORMAT_RGB444) { 1116 + vsc.colorimetry = DP_COLORIMETRY_DEFAULT; 1117 + vsc.dynamic_range = DP_DYNAMIC_RANGE_VESA; 1118 + } else { 1119 + vsc.colorimetry = DP_COLORIMETRY_BT709_YCC; 1120 + vsc.dynamic_range = DP_DYNAMIC_RANGE_CTA; 1121 + } 1122 + 1123 + drm_dp_vsc_sdp_pack(&vsc, &sdp.base); 1124 + 1125 + return dw_dp_send_sdp(dp, &sdp); 1126 + } 1127 + 1128 + static int dw_dp_video_set_pixel_mode(struct dw_dp *dp) 1129 + { 1130 + switch (dp->pixel_mode) { 1131 + case DW_DP_MP_SINGLE_PIXEL: 1132 + case DW_DP_MP_DUAL_PIXEL: 1133 + case DW_DP_MP_QUAD_PIXEL: 1134 + break; 1135 + default: 1136 + return -EINVAL; 1137 + } 1138 + 1139 + regmap_update_bits(dp->regmap, DW_DP_VSAMPLE_CTRL, PIXEL_MODE_SELECT, 1140 + FIELD_PREP(PIXEL_MODE_SELECT, dp->pixel_mode)); 1141 + 1142 + return 0; 1143 + } 1144 + 1145 + static bool dw_dp_video_need_vsc_sdp(struct dw_dp *dp) 1146 + { 1147 + struct dw_dp_link *link = &dp->link; 1148 + struct dw_dp_bridge_state *state; 1149 + 1150 + state = dw_dp_get_bridge_state(dp); 1151 + if (!state) 1152 + return -EINVAL; 1153 + 1154 + if (!link->vsc_sdp_supported) 1155 + return false; 1156 + 1157 + if (state->color_format == DRM_COLOR_FORMAT_YCBCR420) 1158 + return true; 1159 + 1160 + return false; 1161 + } 1162 + 1163 + static int dw_dp_video_set_msa(struct dw_dp *dp, u8 color_format, u8 bpc, 1164 + u16 vstart, u16 hstart) 1165 + { 1166 + u16 misc = 0; 1167 + 1168 + if (dw_dp_video_need_vsc_sdp(dp)) 1169 + misc |= DP_MSA_MISC_COLOR_VSC_SDP; 1170 + 1171 + switch (color_format) { 1172 + case DRM_COLOR_FORMAT_RGB444: 1173 + misc |= DP_MSA_MISC_COLOR_RGB; 1174 + break; 1175 + case DRM_COLOR_FORMAT_YCBCR444: 1176 + misc |= DP_MSA_MISC_COLOR_YCBCR_444_BT709; 1177 + break; 1178 + case DRM_COLOR_FORMAT_YCBCR422: 1179 + misc |= DP_MSA_MISC_COLOR_YCBCR_422_BT709; 1180 + break; 1181 + case DRM_COLOR_FORMAT_YCBCR420: 1182 + break; 1183 + default: 1184 + return -EINVAL; 1185 + } 1186 + 1187 + switch (bpc) { 1188 + case 6: 1189 + misc |= DP_MSA_MISC_6_BPC; 1190 + break; 1191 + case 8: 1192 + misc |= DP_MSA_MISC_8_BPC; 1193 + break; 1194 + case 10: 1195 + misc |= DP_MSA_MISC_10_BPC; 1196 + break; 1197 + case 12: 1198 + misc |= DP_MSA_MISC_12_BPC; 1199 + break; 1200 + case 16: 1201 + misc |= DP_MSA_MISC_16_BPC; 1202 + break; 1203 + default: 1204 + return -EINVAL; 1205 + } 1206 + 1207 + regmap_write(dp->regmap, DW_DP_VIDEO_MSA1, 1208 + FIELD_PREP(VSTART, vstart) | FIELD_PREP(HSTART, hstart)); 1209 + regmap_write(dp->regmap, DW_DP_VIDEO_MSA2, FIELD_PREP(MISC0, misc)); 1210 + regmap_write(dp->regmap, DW_DP_VIDEO_MSA3, FIELD_PREP(MISC1, misc >> 8)); 1211 + 1212 + return 0; 1213 + } 1214 + 1215 + static void dw_dp_video_disable(struct dw_dp *dp) 1216 + { 1217 + regmap_update_bits(dp->regmap, DW_DP_VSAMPLE_CTRL, VIDEO_STREAM_ENABLE, 1218 + FIELD_PREP(VIDEO_STREAM_ENABLE, 0)); 1219 + } 1220 + 1221 + static int dw_dp_video_enable(struct dw_dp *dp) 1222 + { 1223 + struct dw_dp_link *link = &dp->link; 1224 + struct dw_dp_bridge_state *state; 1225 + struct drm_display_mode *mode; 1226 + u8 color_format, bpc, bpp; 1227 + u8 init_threshold, vic; 1228 + u32 hstart, hactive, hblank, h_sync_width, h_front_porch; 1229 + u32 vstart, vactive, vblank, v_sync_width, v_front_porch; 1230 + u32 peak_stream_bandwidth, link_bandwidth; 1231 + u32 average_bytes_per_tu, average_bytes_per_tu_frac; 1232 + u32 ts, hblank_interval; 1233 + u32 value; 1234 + int ret; 1235 + 1236 + state = dw_dp_get_bridge_state(dp); 1237 + if (!state) 1238 + return -EINVAL; 1239 + 1240 + bpc = state->bpc; 1241 + bpp = state->bpp; 1242 + color_format = state->color_format; 1243 + mode = &state->mode; 1244 + 1245 + vstart = mode->vtotal - mode->vsync_start; 1246 + hstart = mode->htotal - mode->hsync_start; 1247 + 1248 + ret = dw_dp_video_set_pixel_mode(dp); 1249 + if (ret) 1250 + return ret; 1251 + 1252 + ret = dw_dp_video_set_msa(dp, color_format, bpc, vstart, hstart); 1253 + if (ret) 1254 + return ret; 1255 + 1256 + regmap_update_bits(dp->regmap, DW_DP_VSAMPLE_CTRL, VIDEO_MAPPING, 1257 + FIELD_PREP(VIDEO_MAPPING, state->video_mapping)); 1258 + 1259 + /* Configure DW_DP_VINPUT_POLARITY_CTRL register */ 1260 + value = 0; 1261 + if (mode->flags & DRM_MODE_FLAG_PHSYNC) 1262 + value |= FIELD_PREP(HSYNC_IN_POLARITY, 1); 1263 + if (mode->flags & DRM_MODE_FLAG_PVSYNC) 1264 + value |= FIELD_PREP(VSYNC_IN_POLARITY, 1); 1265 + regmap_write(dp->regmap, DW_DP_VINPUT_POLARITY_CTRL, value); 1266 + 1267 + /* Configure DW_DP_VIDEO_CONFIG1 register */ 1268 + hactive = mode->hdisplay; 1269 + hblank = mode->htotal - mode->hdisplay; 1270 + value = FIELD_PREP(HACTIVE, hactive) | FIELD_PREP(HBLANK, hblank); 1271 + if (mode->flags & DRM_MODE_FLAG_INTERLACE) 1272 + value |= FIELD_PREP(I_P, 1); 1273 + vic = drm_match_cea_mode(mode); 1274 + if (vic == 5 || vic == 6 || vic == 7 || 1275 + vic == 10 || vic == 11 || vic == 20 || 1276 + vic == 21 || vic == 22 || vic == 39 || 1277 + vic == 25 || vic == 26 || vic == 40 || 1278 + vic == 44 || vic == 45 || vic == 46 || 1279 + vic == 50 || vic == 51 || vic == 54 || 1280 + vic == 55 || vic == 58 || vic == 59) 1281 + value |= R_V_BLANK_IN_OSC; 1282 + regmap_write(dp->regmap, DW_DP_VIDEO_CONFIG1, value); 1283 + 1284 + /* Configure DW_DP_VIDEO_CONFIG2 register */ 1285 + vblank = mode->vtotal - mode->vdisplay; 1286 + vactive = mode->vdisplay; 1287 + regmap_write(dp->regmap, DW_DP_VIDEO_CONFIG2, 1288 + FIELD_PREP(VBLANK, vblank) | FIELD_PREP(VACTIVE, vactive)); 1289 + 1290 + /* Configure DW_DP_VIDEO_CONFIG3 register */ 1291 + h_sync_width = mode->hsync_end - mode->hsync_start; 1292 + h_front_porch = mode->hsync_start - mode->hdisplay; 1293 + regmap_write(dp->regmap, DW_DP_VIDEO_CONFIG3, 1294 + FIELD_PREP(H_SYNC_WIDTH, h_sync_width) | 1295 + FIELD_PREP(H_FRONT_PORCH, h_front_porch)); 1296 + 1297 + /* Configure DW_DP_VIDEO_CONFIG4 register */ 1298 + v_sync_width = mode->vsync_end - mode->vsync_start; 1299 + v_front_porch = mode->vsync_start - mode->vdisplay; 1300 + regmap_write(dp->regmap, DW_DP_VIDEO_CONFIG4, 1301 + FIELD_PREP(V_SYNC_WIDTH, v_sync_width) | 1302 + FIELD_PREP(V_FRONT_PORCH, v_front_porch)); 1303 + 1304 + /* Configure DW_DP_VIDEO_CONFIG5 register */ 1305 + peak_stream_bandwidth = mode->clock * bpp / 8; 1306 + link_bandwidth = (link->rate / 1000) * link->lanes; 1307 + ts = peak_stream_bandwidth * 64 / link_bandwidth; 1308 + average_bytes_per_tu = ts / 1000; 1309 + average_bytes_per_tu_frac = ts / 100 - average_bytes_per_tu * 10; 1310 + if (dp->pixel_mode == DW_DP_MP_SINGLE_PIXEL) { 1311 + if (average_bytes_per_tu < 6) 1312 + init_threshold = 32; 1313 + else if (hblank <= 80 && color_format != DRM_COLOR_FORMAT_YCBCR420) 1314 + init_threshold = 12; 1315 + else if (hblank <= 40 && color_format == DRM_COLOR_FORMAT_YCBCR420) 1316 + init_threshold = 3; 1317 + else 1318 + init_threshold = 16; 1319 + } else { 1320 + u32 t1 = 0, t2 = 0, t3 = 0; 1321 + 1322 + switch (bpc) { 1323 + case 6: 1324 + t1 = (4 * 1000 / 9) * link->lanes; 1325 + break; 1326 + case 8: 1327 + if (color_format == DRM_COLOR_FORMAT_YCBCR422) { 1328 + t1 = (1000 / 2) * link->lanes; 1329 + } else { 1330 + if (dp->pixel_mode == DW_DP_MP_DUAL_PIXEL) 1331 + t1 = (1000 / 3) * link->lanes; 1332 + else 1333 + t1 = (3000 / 16) * link->lanes; 1334 + } 1335 + break; 1336 + case 10: 1337 + if (color_format == DRM_COLOR_FORMAT_YCBCR422) 1338 + t1 = (2000 / 5) * link->lanes; 1339 + else 1340 + t1 = (4000 / 15) * link->lanes; 1341 + break; 1342 + case 12: 1343 + if (color_format == DRM_COLOR_FORMAT_YCBCR422) { 1344 + if (dp->pixel_mode == DW_DP_MP_DUAL_PIXEL) 1345 + t1 = (1000 / 6) * link->lanes; 1346 + else 1347 + t1 = (1000 / 3) * link->lanes; 1348 + } else { 1349 + t1 = (2000 / 9) * link->lanes; 1350 + } 1351 + break; 1352 + case 16: 1353 + if (color_format != DRM_COLOR_FORMAT_YCBCR422 && 1354 + dp->pixel_mode == DW_DP_MP_DUAL_PIXEL) 1355 + t1 = (1000 / 6) * link->lanes; 1356 + else 1357 + t1 = (1000 / 4) * link->lanes; 1358 + break; 1359 + default: 1360 + return -EINVAL; 1361 + } 1362 + 1363 + if (color_format == DRM_COLOR_FORMAT_YCBCR420) 1364 + t2 = (link->rate / 4) * 1000 / (mode->clock / 2); 1365 + else 1366 + t2 = (link->rate / 4) * 1000 / mode->clock; 1367 + 1368 + if (average_bytes_per_tu_frac) 1369 + t3 = average_bytes_per_tu + 1; 1370 + else 1371 + t3 = average_bytes_per_tu; 1372 + init_threshold = t1 * t2 * t3 / (1000 * 1000); 1373 + if (init_threshold <= 16 || average_bytes_per_tu < 10) 1374 + init_threshold = 40; 1375 + } 1376 + 1377 + regmap_write(dp->regmap, DW_DP_VIDEO_CONFIG5, 1378 + FIELD_PREP(INIT_THRESHOLD_HI, init_threshold >> 6) | 1379 + FIELD_PREP(AVERAGE_BYTES_PER_TU_FRAC, average_bytes_per_tu_frac) | 1380 + FIELD_PREP(INIT_THRESHOLD, init_threshold) | 1381 + FIELD_PREP(AVERAGE_BYTES_PER_TU, average_bytes_per_tu)); 1382 + 1383 + /* Configure DW_DP_VIDEO_HBLANK_INTERVAL register */ 1384 + hblank_interval = hblank * (link->rate / 4) / mode->clock; 1385 + regmap_write(dp->regmap, DW_DP_VIDEO_HBLANK_INTERVAL, 1386 + FIELD_PREP(HBLANK_INTERVAL_EN, 1) | 1387 + FIELD_PREP(HBLANK_INTERVAL, hblank_interval)); 1388 + 1389 + /* Video stream enable */ 1390 + regmap_update_bits(dp->regmap, DW_DP_VSAMPLE_CTRL, VIDEO_STREAM_ENABLE, 1391 + FIELD_PREP(VIDEO_STREAM_ENABLE, 1)); 1392 + 1393 + if (dw_dp_video_need_vsc_sdp(dp)) 1394 + dw_dp_send_vsc_sdp(dp); 1395 + 1396 + return 0; 1397 + } 1398 + 1399 + static void dw_dp_hpd_init(struct dw_dp *dp) 1400 + { 1401 + /* Enable all HPD interrupts */ 1402 + regmap_update_bits(dp->regmap, DW_DP_HPD_INTERRUPT_ENABLE, 1403 + HPD_UNPLUG_EN | HPD_PLUG_EN | HPD_IRQ_EN, 1404 + FIELD_PREP(HPD_UNPLUG_EN, 1) | 1405 + FIELD_PREP(HPD_PLUG_EN, 1) | 1406 + FIELD_PREP(HPD_IRQ_EN, 1)); 1407 + 1408 + /* Enable all top-level interrupts */ 1409 + regmap_update_bits(dp->regmap, DW_DP_GENERAL_INTERRUPT_ENABLE, 1410 + HPD_EVENT_EN, FIELD_PREP(HPD_EVENT_EN, 1)); 1411 + } 1412 + 1413 + static void dw_dp_aux_init(struct dw_dp *dp) 1414 + { 1415 + regmap_update_bits(dp->regmap, DW_DP_GENERAL_INTERRUPT_ENABLE, 1416 + AUX_REPLY_EVENT_EN, FIELD_PREP(AUX_REPLY_EVENT_EN, 1)); 1417 + } 1418 + 1419 + static void dw_dp_init_hw(struct dw_dp *dp) 1420 + { 1421 + regmap_update_bits(dp->regmap, DW_DP_CCTL, DEFAULT_FAST_LINK_TRAIN_EN, 1422 + FIELD_PREP(DEFAULT_FAST_LINK_TRAIN_EN, 0)); 1423 + 1424 + dw_dp_hpd_init(dp); 1425 + dw_dp_aux_init(dp); 1426 + } 1427 + 1428 + static int dw_dp_aux_write_data(struct dw_dp *dp, const u8 *buffer, size_t size) 1429 + { 1430 + size_t i, j; 1431 + 1432 + for (i = 0; i < DIV_ROUND_UP(size, 4); i++) { 1433 + size_t num = min_t(size_t, size - i * 4, 4); 1434 + u32 value = 0; 1435 + 1436 + for (j = 0; j < num; j++) 1437 + value |= buffer[i * 4 + j] << (j * 8); 1438 + 1439 + regmap_write(dp->regmap, DW_DP_AUX_DATA0 + i * 4, value); 1440 + } 1441 + 1442 + return size; 1443 + } 1444 + 1445 + static int dw_dp_aux_read_data(struct dw_dp *dp, u8 *buffer, size_t size) 1446 + { 1447 + size_t i, j; 1448 + 1449 + for (i = 0; i < DIV_ROUND_UP(size, 4); i++) { 1450 + size_t num = min_t(size_t, size - i * 4, 4); 1451 + u32 value; 1452 + 1453 + regmap_read(dp->regmap, DW_DP_AUX_DATA0 + i * 4, &value); 1454 + 1455 + for (j = 0; j < num; j++) 1456 + buffer[i * 4 + j] = value >> (j * 8); 1457 + } 1458 + 1459 + return size; 1460 + } 1461 + 1462 + static ssize_t dw_dp_aux_transfer(struct drm_dp_aux *aux, 1463 + struct drm_dp_aux_msg *msg) 1464 + { 1465 + struct dw_dp *dp = container_of(aux, struct dw_dp, aux); 1466 + unsigned long timeout = msecs_to_jiffies(10); 1467 + u32 status, value; 1468 + ssize_t ret = 0; 1469 + 1470 + if (WARN_ON(msg->size > 16)) 1471 + return -E2BIG; 1472 + 1473 + switch (msg->request & ~DP_AUX_I2C_MOT) { 1474 + case DP_AUX_NATIVE_WRITE: 1475 + case DP_AUX_I2C_WRITE: 1476 + case DP_AUX_I2C_WRITE_STATUS_UPDATE: 1477 + ret = dw_dp_aux_write_data(dp, msg->buffer, msg->size); 1478 + if (ret < 0) 1479 + return ret; 1480 + break; 1481 + case DP_AUX_NATIVE_READ: 1482 + case DP_AUX_I2C_READ: 1483 + break; 1484 + default: 1485 + return -EINVAL; 1486 + } 1487 + 1488 + if (msg->size > 0) 1489 + value = FIELD_PREP(AUX_LEN_REQ, msg->size - 1); 1490 + else 1491 + value = FIELD_PREP(I2C_ADDR_ONLY, 1); 1492 + value |= FIELD_PREP(AUX_CMD_TYPE, msg->request); 1493 + value |= FIELD_PREP(AUX_ADDR, msg->address); 1494 + regmap_write(dp->regmap, DW_DP_AUX_CMD, value); 1495 + 1496 + status = wait_for_completion_timeout(&dp->complete, timeout); 1497 + if (!status) { 1498 + dev_err(dp->dev, "timeout waiting for AUX reply\n"); 1499 + return -ETIMEDOUT; 1500 + } 1501 + 1502 + regmap_read(dp->regmap, DW_DP_AUX_STATUS, &value); 1503 + if (value & AUX_TIMEOUT) 1504 + return -ETIMEDOUT; 1505 + 1506 + msg->reply = FIELD_GET(AUX_STATUS, value); 1507 + 1508 + if (msg->size > 0 && msg->reply == DP_AUX_NATIVE_REPLY_ACK) { 1509 + if (msg->request & DP_AUX_I2C_READ) { 1510 + size_t count = FIELD_GET(AUX_BYTES_READ, value) - 1; 1511 + 1512 + if (count != msg->size) 1513 + return -EBUSY; 1514 + 1515 + ret = dw_dp_aux_read_data(dp, msg->buffer, count); 1516 + if (ret < 0) 1517 + return ret; 1518 + } 1519 + } 1520 + 1521 + return ret; 1522 + } 1523 + 1524 + /* 1525 + * Limits for the video timing for DP: 1526 + * 1. the hfp should be 2 pixels aligned; 1527 + * 2. the minimum hsync should be 9 pixel; 1528 + * 3. the minimum hbp should be 16 pixel; 1529 + */ 1530 + static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge, 1531 + struct drm_bridge_state *bridge_state, 1532 + struct drm_crtc_state *crtc_state, 1533 + struct drm_connector_state *conn_state) 1534 + { 1535 + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; 1536 + struct dw_dp *dp = bridge_to_dp(bridge); 1537 + struct dw_dp_bridge_state *state; 1538 + const struct dw_dp_output_format *fmt; 1539 + struct drm_display_mode *mode; 1540 + int min_hbp = 16; 1541 + int min_hsync = 9; 1542 + 1543 + state = to_dw_dp_bridge_state(bridge_state); 1544 + mode = &state->mode; 1545 + 1546 + fmt = dw_dp_get_output_format(bridge_state->output_bus_cfg.format); 1547 + if (!fmt) 1548 + return -EINVAL; 1549 + 1550 + state->video_mapping = fmt->video_mapping; 1551 + state->color_format = fmt->color_format; 1552 + state->bpc = fmt->bpc; 1553 + state->bpp = fmt->bpp; 1554 + 1555 + if ((adjusted_mode->hsync_start - adjusted_mode->hdisplay) & 0x1) { 1556 + adjusted_mode->hsync_start += 1; 1557 + dev_warn(dp->dev, "hfp is not 2 pixeel aligned, fixup to aligned hfp\n"); 1558 + } 1559 + 1560 + if (adjusted_mode->hsync_end - adjusted_mode->hsync_start < min_hsync) { 1561 + adjusted_mode->hsync_end = adjusted_mode->hsync_start + min_hsync; 1562 + dev_warn(dp->dev, "hsync is too narrow, fixup to min hsync:%d\n", min_hsync); 1563 + } 1564 + 1565 + if (adjusted_mode->htotal - adjusted_mode->hsync_end < min_hbp) { 1566 + adjusted_mode->htotal = adjusted_mode->hsync_end + min_hbp; 1567 + dev_warn(dp->dev, "hbp is too narrow, fixup to min hbp:%d\n", min_hbp); 1568 + } 1569 + 1570 + drm_mode_copy(mode, adjusted_mode); 1571 + 1572 + return 0; 1573 + } 1574 + 1575 + static enum drm_mode_status dw_dp_bridge_mode_valid(struct drm_bridge *bridge, 1576 + const struct drm_display_info *info, 1577 + const struct drm_display_mode *mode) 1578 + { 1579 + struct dw_dp *dp = bridge_to_dp(bridge); 1580 + struct dw_dp_link *link = &dp->link; 1581 + u32 min_bpp; 1582 + 1583 + if (info->color_formats & DRM_COLOR_FORMAT_YCBCR420 && 1584 + link->vsc_sdp_supported && 1585 + (drm_mode_is_420_only(info, mode) || drm_mode_is_420_also(info, mode))) 1586 + min_bpp = 12; 1587 + else if (info->color_formats & DRM_COLOR_FORMAT_YCBCR422) 1588 + min_bpp = 16; 1589 + else if (info->color_formats & DRM_COLOR_FORMAT_RGB444) 1590 + min_bpp = 18; 1591 + else 1592 + min_bpp = 24; 1593 + 1594 + if (!link->vsc_sdp_supported && 1595 + drm_mode_is_420_only(info, mode)) 1596 + return MODE_NO_420; 1597 + 1598 + if (!dw_dp_bandwidth_ok(dp, mode, min_bpp, link->lanes, link->rate)) 1599 + return MODE_CLOCK_HIGH; 1600 + 1601 + return MODE_OK; 1602 + } 1603 + 1604 + static bool dw_dp_needs_link_retrain(struct dw_dp *dp) 1605 + { 1606 + struct dw_dp_link *link = &dp->link; 1607 + u8 link_status[DP_LINK_STATUS_SIZE]; 1608 + 1609 + if (!dw_dp_link_train_valid(&link->train)) 1610 + return false; 1611 + 1612 + if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) < 0) 1613 + return false; 1614 + 1615 + /* Retrain if Channel EQ or CR not ok */ 1616 + return !drm_dp_channel_eq_ok(link_status, dp->link.lanes); 1617 + } 1618 + 1619 + static void dw_dp_link_disable(struct dw_dp *dp) 1620 + { 1621 + struct dw_dp_link *link = &dp->link; 1622 + 1623 + if (dw_dp_hpd_detect(dp)) 1624 + drm_dp_link_power_down(&dp->aux, dp->link.revision); 1625 + 1626 + dw_dp_phy_xmit_enable(dp, 0); 1627 + 1628 + phy_power_off(dp->phy); 1629 + 1630 + link->train.clock_recovered = false; 1631 + link->train.channel_equalized = false; 1632 + } 1633 + 1634 + static int dw_dp_link_enable(struct dw_dp *dp) 1635 + { 1636 + int ret; 1637 + 1638 + ret = phy_power_on(dp->phy); 1639 + if (ret) 1640 + return ret; 1641 + 1642 + ret = drm_dp_link_power_up(&dp->aux, dp->link.revision); 1643 + if (ret < 0) 1644 + return ret; 1645 + 1646 + ret = dw_dp_link_train(dp); 1647 + 1648 + return ret; 1649 + } 1650 + 1651 + static void dw_dp_bridge_atomic_enable(struct drm_bridge *bridge, 1652 + struct drm_atomic_state *state) 1653 + { 1654 + struct dw_dp *dp = bridge_to_dp(bridge); 1655 + struct drm_connector *connector; 1656 + struct drm_connector_state *conn_state; 1657 + int ret; 1658 + 1659 + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); 1660 + if (!connector) { 1661 + dev_err(dp->dev, "failed to get connector\n"); 1662 + return; 1663 + } 1664 + 1665 + conn_state = drm_atomic_get_new_connector_state(state, connector); 1666 + if (!conn_state) { 1667 + dev_err(dp->dev, "failed to get connector state\n"); 1668 + return; 1669 + } 1670 + 1671 + set_bit(0, dp->sdp_reg_bank); 1672 + 1673 + ret = dw_dp_link_enable(dp); 1674 + if (ret < 0) { 1675 + dev_err(dp->dev, "failed to enable link: %d\n", ret); 1676 + return; 1677 + } 1678 + 1679 + ret = dw_dp_video_enable(dp); 1680 + if (ret < 0) { 1681 + dev_err(dp->dev, "failed to enable video: %d\n", ret); 1682 + return; 1683 + } 1684 + } 1685 + 1686 + static void dw_dp_reset(struct dw_dp *dp) 1687 + { 1688 + int val; 1689 + 1690 + disable_irq(dp->irq); 1691 + regmap_update_bits(dp->regmap, DW_DP_SOFT_RESET_CTRL, CONTROLLER_RESET, 1692 + FIELD_PREP(CONTROLLER_RESET, 1)); 1693 + usleep_range(10, 20); 1694 + regmap_update_bits(dp->regmap, DW_DP_SOFT_RESET_CTRL, CONTROLLER_RESET, 1695 + FIELD_PREP(CONTROLLER_RESET, 0)); 1696 + 1697 + dw_dp_init_hw(dp); 1698 + regmap_read_poll_timeout(dp->regmap, DW_DP_HPD_STATUS, val, 1699 + FIELD_GET(HPD_HOT_PLUG, val), 200, 200000); 1700 + regmap_write(dp->regmap, DW_DP_HPD_STATUS, HPD_HOT_PLUG); 1701 + enable_irq(dp->irq); 1702 + } 1703 + 1704 + static void dw_dp_bridge_atomic_disable(struct drm_bridge *bridge, 1705 + struct drm_atomic_state *state) 1706 + { 1707 + struct dw_dp *dp = bridge_to_dp(bridge); 1708 + 1709 + dw_dp_video_disable(dp); 1710 + dw_dp_link_disable(dp); 1711 + bitmap_zero(dp->sdp_reg_bank, SDP_REG_BANK_SIZE); 1712 + dw_dp_reset(dp); 1713 + } 1714 + 1715 + static bool dw_dp_hpd_detect_link(struct dw_dp *dp, struct drm_connector *connector) 1716 + { 1717 + int ret; 1718 + 1719 + ret = phy_power_on(dp->phy); 1720 + if (ret < 0) 1721 + return false; 1722 + ret = dw_dp_link_parse(dp, connector); 1723 + phy_power_off(dp->phy); 1724 + 1725 + return !ret; 1726 + } 1727 + 1728 + static enum drm_connector_status dw_dp_bridge_detect(struct drm_bridge *bridge, 1729 + struct drm_connector *connector) 1730 + { 1731 + struct dw_dp *dp = bridge_to_dp(bridge); 1732 + 1733 + if (!dw_dp_hpd_detect(dp)) 1734 + return connector_status_disconnected; 1735 + 1736 + if (!dw_dp_hpd_detect_link(dp, connector)) 1737 + return connector_status_disconnected; 1738 + 1739 + return connector_status_connected; 1740 + } 1741 + 1742 + static const struct drm_edid *dw_dp_bridge_edid_read(struct drm_bridge *bridge, 1743 + struct drm_connector *connector) 1744 + { 1745 + struct dw_dp *dp = bridge_to_dp(bridge); 1746 + const struct drm_edid *edid; 1747 + int ret; 1748 + 1749 + ret = phy_power_on(dp->phy); 1750 + if (ret) 1751 + return NULL; 1752 + 1753 + edid = drm_edid_read_ddc(connector, &dp->aux.ddc); 1754 + 1755 + phy_power_off(dp->phy); 1756 + 1757 + return edid; 1758 + } 1759 + 1760 + static u32 *dw_dp_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, 1761 + struct drm_bridge_state *bridge_state, 1762 + struct drm_crtc_state *crtc_state, 1763 + struct drm_connector_state *conn_state, 1764 + unsigned int *num_output_fmts) 1765 + { 1766 + struct dw_dp *dp = bridge_to_dp(bridge); 1767 + struct dw_dp_link *link = &dp->link; 1768 + struct drm_display_info *di = &conn_state->connector->display_info; 1769 + struct drm_display_mode mode = crtc_state->mode; 1770 + const struct dw_dp_output_format *fmt; 1771 + u32 i, j = 0; 1772 + u32 *output_fmts; 1773 + 1774 + *num_output_fmts = 0; 1775 + 1776 + output_fmts = kcalloc(ARRAY_SIZE(dw_dp_output_formats), sizeof(*output_fmts), GFP_KERNEL); 1777 + if (!output_fmts) 1778 + return NULL; 1779 + 1780 + for (i = 0; i < ARRAY_SIZE(dw_dp_output_formats); i++) { 1781 + fmt = &dw_dp_output_formats[i]; 1782 + 1783 + if (fmt->bpc > conn_state->max_bpc) 1784 + continue; 1785 + 1786 + if (!(fmt->color_format & di->color_formats)) 1787 + continue; 1788 + 1789 + if (fmt->color_format == DRM_COLOR_FORMAT_YCBCR420 && 1790 + !link->vsc_sdp_supported) 1791 + continue; 1792 + 1793 + if (fmt->color_format != DRM_COLOR_FORMAT_YCBCR420 && 1794 + drm_mode_is_420_only(di, &mode)) 1795 + continue; 1796 + 1797 + if (!dw_dp_bandwidth_ok(dp, &mode, fmt->bpp, link->lanes, link->rate)) 1798 + continue; 1799 + 1800 + output_fmts[j++] = fmt->bus_format; 1801 + } 1802 + 1803 + *num_output_fmts = j; 1804 + 1805 + return output_fmts; 1806 + } 1807 + 1808 + static struct drm_bridge_state *dw_dp_bridge_atomic_duplicate_state(struct drm_bridge *bridge) 1809 + { 1810 + struct dw_dp_bridge_state *state; 1811 + 1812 + state = kzalloc(sizeof(*state), GFP_KERNEL); 1813 + if (!state) 1814 + return NULL; 1815 + 1816 + __drm_atomic_helper_bridge_duplicate_state(bridge, &state->base); 1817 + 1818 + return &state->base; 1819 + } 1820 + 1821 + static const struct drm_bridge_funcs dw_dp_bridge_funcs = { 1822 + .atomic_duplicate_state = dw_dp_bridge_atomic_duplicate_state, 1823 + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 1824 + .atomic_reset = drm_atomic_helper_bridge_reset, 1825 + .atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt, 1826 + .atomic_get_output_bus_fmts = dw_dp_bridge_atomic_get_output_bus_fmts, 1827 + .atomic_check = dw_dp_bridge_atomic_check, 1828 + .mode_valid = dw_dp_bridge_mode_valid, 1829 + .atomic_enable = dw_dp_bridge_atomic_enable, 1830 + .atomic_disable = dw_dp_bridge_atomic_disable, 1831 + .detect = dw_dp_bridge_detect, 1832 + .edid_read = dw_dp_bridge_edid_read, 1833 + }; 1834 + 1835 + static int dw_dp_link_retrain(struct dw_dp *dp) 1836 + { 1837 + struct drm_device *dev = dp->bridge.dev; 1838 + struct drm_modeset_acquire_ctx ctx; 1839 + int ret; 1840 + 1841 + if (!dw_dp_needs_link_retrain(dp)) 1842 + return 0; 1843 + 1844 + dev_dbg(dp->dev, "Retraining link\n"); 1845 + 1846 + drm_modeset_acquire_init(&ctx, 0); 1847 + for (;;) { 1848 + ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx); 1849 + if (ret != -EDEADLK) 1850 + break; 1851 + 1852 + drm_modeset_backoff(&ctx); 1853 + } 1854 + 1855 + if (!ret) 1856 + ret = dw_dp_link_train(dp); 1857 + 1858 + drm_modeset_drop_locks(&ctx); 1859 + drm_modeset_acquire_fini(&ctx); 1860 + 1861 + return ret; 1862 + } 1863 + 1864 + static void dw_dp_hpd_work(struct work_struct *work) 1865 + { 1866 + struct dw_dp *dp = container_of(work, struct dw_dp, hpd_work); 1867 + bool long_hpd; 1868 + int ret; 1869 + 1870 + mutex_lock(&dp->irq_lock); 1871 + long_hpd = dp->hotplug.long_hpd; 1872 + mutex_unlock(&dp->irq_lock); 1873 + 1874 + dev_dbg(dp->dev, "[drm] Get hpd irq - %s\n", long_hpd ? "long" : "short"); 1875 + 1876 + if (!long_hpd) { 1877 + if (dw_dp_needs_link_retrain(dp)) { 1878 + ret = dw_dp_link_retrain(dp); 1879 + if (ret) 1880 + dev_warn(dp->dev, "Retrain link failed\n"); 1881 + } 1882 + } else { 1883 + drm_helper_hpd_irq_event(dp->bridge.dev); 1884 + } 1885 + } 1886 + 1887 + static void dw_dp_handle_hpd_event(struct dw_dp *dp) 1888 + { 1889 + u32 value; 1890 + 1891 + mutex_lock(&dp->irq_lock); 1892 + regmap_read(dp->regmap, DW_DP_HPD_STATUS, &value); 1893 + 1894 + if (value & HPD_IRQ) { 1895 + dev_dbg(dp->dev, "IRQ from the HPD\n"); 1896 + dp->hotplug.long_hpd = false; 1897 + regmap_write(dp->regmap, DW_DP_HPD_STATUS, HPD_IRQ); 1898 + } 1899 + 1900 + if (value & HPD_HOT_PLUG) { 1901 + dev_dbg(dp->dev, "Hot plug detected\n"); 1902 + dp->hotplug.long_hpd = true; 1903 + regmap_write(dp->regmap, DW_DP_HPD_STATUS, HPD_HOT_PLUG); 1904 + } 1905 + 1906 + if (value & HPD_HOT_UNPLUG) { 1907 + dev_dbg(dp->dev, "Unplug detected\n"); 1908 + dp->hotplug.long_hpd = true; 1909 + regmap_write(dp->regmap, DW_DP_HPD_STATUS, HPD_HOT_UNPLUG); 1910 + } 1911 + mutex_unlock(&dp->irq_lock); 1912 + 1913 + schedule_work(&dp->hpd_work); 1914 + } 1915 + 1916 + static irqreturn_t dw_dp_irq(int irq, void *data) 1917 + { 1918 + struct dw_dp *dp = data; 1919 + u32 value; 1920 + 1921 + regmap_read(dp->regmap, DW_DP_GENERAL_INTERRUPT, &value); 1922 + if (!value) 1923 + return IRQ_NONE; 1924 + 1925 + if (value & HPD_EVENT) 1926 + dw_dp_handle_hpd_event(dp); 1927 + 1928 + if (value & AUX_REPLY_EVENT) { 1929 + regmap_write(dp->regmap, DW_DP_GENERAL_INTERRUPT, AUX_REPLY_EVENT); 1930 + complete(&dp->complete); 1931 + } 1932 + 1933 + return IRQ_HANDLED; 1934 + } 1935 + 1936 + static const struct regmap_range dw_dp_readable_ranges[] = { 1937 + regmap_reg_range(DW_DP_VERSION_NUMBER, DW_DP_ID), 1938 + regmap_reg_range(DW_DP_CONFIG_REG1, DW_DP_CONFIG_REG3), 1939 + regmap_reg_range(DW_DP_CCTL, DW_DP_SOFT_RESET_CTRL), 1940 + regmap_reg_range(DW_DP_VSAMPLE_CTRL, DW_DP_VIDEO_HBLANK_INTERVAL), 1941 + regmap_reg_range(DW_DP_AUD_CONFIG1, DW_DP_AUD_CONFIG1), 1942 + regmap_reg_range(DW_DP_SDP_VERTICAL_CTRL, DW_DP_SDP_STATUS_EN), 1943 + regmap_reg_range(DW_DP_PHYIF_CTRL, DW_DP_PHYIF_PWRDOWN_CTRL), 1944 + regmap_reg_range(DW_DP_AUX_CMD, DW_DP_AUX_DATA3), 1945 + regmap_reg_range(DW_DP_GENERAL_INTERRUPT, DW_DP_HPD_INTERRUPT_ENABLE), 1946 + }; 1947 + 1948 + static const struct regmap_access_table dw_dp_readable_table = { 1949 + .yes_ranges = dw_dp_readable_ranges, 1950 + .n_yes_ranges = ARRAY_SIZE(dw_dp_readable_ranges), 1951 + }; 1952 + 1953 + static const struct regmap_config dw_dp_regmap_config = { 1954 + .reg_bits = 32, 1955 + .reg_stride = 4, 1956 + .val_bits = 32, 1957 + .fast_io = true, 1958 + .max_register = DW_DP_MAX_REGISTER, 1959 + .rd_table = &dw_dp_readable_table, 1960 + }; 1961 + 1962 + static void dw_dp_phy_exit(void *data) 1963 + { 1964 + struct dw_dp *dp = data; 1965 + 1966 + phy_exit(dp->phy); 1967 + } 1968 + 1969 + struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder, 1970 + const struct dw_dp_plat_data *plat_data) 1971 + { 1972 + struct platform_device *pdev = to_platform_device(dev); 1973 + struct dw_dp *dp; 1974 + struct drm_bridge *bridge; 1975 + void __iomem *res; 1976 + int ret; 1977 + 1978 + dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); 1979 + if (!dp) 1980 + return ERR_PTR(-ENOMEM); 1981 + 1982 + dp = devm_drm_bridge_alloc(dev, struct dw_dp, bridge, &dw_dp_bridge_funcs); 1983 + if (IS_ERR(dp)) 1984 + return ERR_CAST(dp); 1985 + 1986 + dp->dev = dev; 1987 + dp->pixel_mode = DW_DP_MP_QUAD_PIXEL; 1988 + 1989 + dp->plat_data.max_link_rate = plat_data->max_link_rate; 1990 + bridge = &dp->bridge; 1991 + mutex_init(&dp->irq_lock); 1992 + INIT_WORK(&dp->hpd_work, dw_dp_hpd_work); 1993 + init_completion(&dp->complete); 1994 + 1995 + res = devm_platform_ioremap_resource(pdev, 0); 1996 + if (IS_ERR(res)) 1997 + return ERR_CAST(res); 1998 + 1999 + dp->regmap = devm_regmap_init_mmio(dev, res, &dw_dp_regmap_config); 2000 + if (IS_ERR(dp->regmap)) { 2001 + dev_err_probe(dev, PTR_ERR(dp->regmap), "failed to create regmap\n"); 2002 + return ERR_CAST(dp->regmap); 2003 + } 2004 + 2005 + dp->phy = devm_of_phy_get(dev, dev->of_node, NULL); 2006 + if (IS_ERR(dp->phy)) { 2007 + dev_err_probe(dev, PTR_ERR(dp->phy), "failed to get phy\n"); 2008 + return ERR_CAST(dp->phy); 2009 + } 2010 + 2011 + dp->apb_clk = devm_clk_get_enabled(dev, "apb"); 2012 + if (IS_ERR(dp->apb_clk)) { 2013 + dev_err_probe(dev, PTR_ERR(dp->apb_clk), "failed to get apb clock\n"); 2014 + return ERR_CAST(dp->apb_clk); 2015 + } 2016 + 2017 + dp->aux_clk = devm_clk_get_enabled(dev, "aux"); 2018 + if (IS_ERR(dp->aux_clk)) { 2019 + dev_err_probe(dev, PTR_ERR(dp->aux_clk), "failed to get aux clock\n"); 2020 + return ERR_CAST(dp->aux_clk); 2021 + } 2022 + 2023 + dp->i2s_clk = devm_clk_get(dev, "i2s"); 2024 + if (IS_ERR(dp->i2s_clk)) { 2025 + dev_err_probe(dev, PTR_ERR(dp->i2s_clk), "failed to get i2s clock\n"); 2026 + return ERR_CAST(dp->i2s_clk); 2027 + } 2028 + 2029 + dp->spdif_clk = devm_clk_get(dev, "spdif"); 2030 + if (IS_ERR(dp->spdif_clk)) { 2031 + dev_err_probe(dev, PTR_ERR(dp->spdif_clk), "failed to get spdif clock\n"); 2032 + return ERR_CAST(dp->spdif_clk); 2033 + } 2034 + 2035 + dp->hdcp_clk = devm_clk_get(dev, "hdcp"); 2036 + if (IS_ERR(dp->hdcp_clk)) { 2037 + dev_err_probe(dev, PTR_ERR(dp->hdcp_clk), "failed to get hdcp clock\n"); 2038 + return ERR_CAST(dp->hdcp_clk); 2039 + } 2040 + 2041 + dp->rstc = devm_reset_control_get(dev, NULL); 2042 + if (IS_ERR(dp->rstc)) { 2043 + dev_err_probe(dev, PTR_ERR(dp->rstc), "failed to get reset control\n"); 2044 + return ERR_CAST(dp->rstc); 2045 + } 2046 + 2047 + bridge->of_node = dev->of_node; 2048 + bridge->ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_HPD; 2049 + bridge->type = DRM_MODE_CONNECTOR_DisplayPort; 2050 + bridge->ycbcr_420_allowed = true; 2051 + 2052 + dp->aux.dev = dev; 2053 + dp->aux.drm_dev = encoder->dev; 2054 + dp->aux.name = dev_name(dev); 2055 + dp->aux.transfer = dw_dp_aux_transfer; 2056 + ret = drm_dp_aux_register(&dp->aux); 2057 + if (ret) { 2058 + dev_err_probe(dev, ret, "Aux register failed\n"); 2059 + return ERR_PTR(ret); 2060 + } 2061 + 2062 + ret = drm_bridge_attach(encoder, bridge, NULL, DRM_BRIDGE_ATTACH_NO_CONNECTOR); 2063 + if (ret) 2064 + dev_err_probe(dev, ret, "Failed to attach bridge\n"); 2065 + 2066 + dw_dp_init_hw(dp); 2067 + 2068 + ret = phy_init(dp->phy); 2069 + if (ret) { 2070 + dev_err_probe(dev, ret, "phy init failed\n"); 2071 + return ERR_PTR(ret); 2072 + } 2073 + 2074 + ret = devm_add_action_or_reset(dev, dw_dp_phy_exit, dp); 2075 + if (ret) 2076 + return ERR_PTR(ret); 2077 + 2078 + dp->irq = platform_get_irq(pdev, 0); 2079 + if (dp->irq < 0) 2080 + return ERR_PTR(ret); 2081 + 2082 + ret = devm_request_threaded_irq(dev, dp->irq, NULL, dw_dp_irq, 2083 + IRQF_ONESHOT, dev_name(dev), dp); 2084 + if (ret) { 2085 + dev_err_probe(dev, ret, "failed to request irq\n"); 2086 + return ERR_PTR(ret); 2087 + } 2088 + 2089 + return dp; 2090 + } 2091 + EXPORT_SYMBOL_GPL(dw_dp_bind); 2092 + 2093 + MODULE_AUTHOR("Andy Yan <andyshrk@163.com>"); 2094 + MODULE_DESCRIPTION("DW DP Core Library"); 2095 + MODULE_LICENSE("GPL");
+20
include/drm/bridge/dw_dp.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* 3 + * Copyright (c) 2025 Rockchip Electronics Co., Ltd. 4 + */ 5 + 6 + #ifndef __DW_DP__ 7 + #define __DW_DP__ 8 + 9 + #include <linux/device.h> 10 + 11 + struct drm_encoder; 12 + struct dw_dp; 13 + 14 + struct dw_dp_plat_data { 15 + u32 max_link_rate; 16 + }; 17 + 18 + struct dw_dp *dw_dp_bind(struct device *dev, struct drm_encoder *encoder, 19 + const struct dw_dp_plat_data *plat_data); 20 + #endif /* __DW_DP__ */