1 /* $NetBSD: anx_dp.c,v 1.4 2021/12/19 11:01:11 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 2019 Jonathan A. Kollasch <jakllsch@kollasch.net> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: anx_dp.c,v 1.4 2021/12/19 11:01:11 riastradh Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/bus.h> 34 #include <sys/conf.h> 35 #include <sys/device.h> 36 #include <sys/intr.h> 37 #include <sys/kernel.h> 38 #include <sys/systm.h> 39 40 #include <dev/ic/anx_dp.h> 41 42 #if ANXDP_AUDIO 43 #include <dev/audio/audio_dai.h> 44 #endif 45 46 #include <drm/drm_crtc.h> 47 #include <drm/drm_crtc_helper.h> 48 #include <drm/drm_dp_helper.h> 49 #include <drm/drm_drv.h> 50 #include <drm/drm_edid.h> 51 52 #define ANXDP_DP_TX_VERSION 0x010 53 #define ANXDP_TX_SW_RESET 0x014 54 #define RESET_DP_TX __BIT(0) 55 #define ANXDP_FUNC_EN_1 0x018 56 #define MASTER_VID_FUNC_EN_N __BIT(7) 57 #define RK_VID_CAP_FUNC_EN_N __BIT(6) 58 #define SLAVE_VID_FUNC_EN_N __BIT(5) 59 #define RK_VID_FIFO_FUNC_EN_N __BIT(5) 60 #define AUD_FIFO_FUNC_EN_N __BIT(4) 61 #define AUD_FUNC_EN_N __BIT(3) 62 #define HDCP_FUNC_EN_N __BIT(2) 63 #define CRC_FUNC_EN_N __BIT(1) 64 #define SW_FUNC_EN_N __BIT(0) 65 #define ANXDP_FUNC_EN_2 0x01c 66 #define SSC_FUNC_EN_N __BIT(7) 67 #define AUX_FUNC_EN_N __BIT(2) 68 #define SERDES_FIFO_FUNC_EN_N __BIT(1) 69 #define LS_CLK_DOMAIN_FUNC_EN_N __BIT(0) 70 #define ANXDP_VIDEO_CTL_1 0x020 71 #define VIDEO_EN __BIT(7) 72 #define VIDEO_MUTE __BIT(6) 73 #define ANXDP_VIDEO_CTL_2 0x024 74 #define ANXDP_VIDEO_CTL_3 0x028 75 #define ANXDP_VIDEO_CTL_4 0x02c 76 #define ANXDP_VIDEO_CTL_8 0x03c 77 #define ANXDP_VIDEO_CTL_10 0x044 78 #define F_SEL __BIT(4) 79 #define SLAVE_I_SCAN_CFG __BIT(2) 80 #define SLAVE_VSYNC_P_CFG __BIT(1) 81 #define SLAVE_HSYNC_P_CFG __BIT(0) 82 #define ANXDP_PLL_REG_1 0x0fc 83 #define REF_CLK_24M __BIT(0) 84 #define RKANXDP_PD 0x12c 85 #define DP_INC_BG __BIT(7) 86 #define DP_EXP_PD __BIT(6) 87 #define DP_PHY_PD __BIT(5) 88 #define RK_AUX_PD __BIT(5) 89 #define AUX_PD __BIT(4) 90 #define RK_PLL_PD __BIT(4) 91 #define CHx_PD(x) __BIT(x) /* 0<=x<=3 */ 92 #define DP_ALL_PD __BITS(7,0) 93 #define ANXDP_LANE_MAP 0x35c 94 #define ANXDP_ANALOG_CTL_1 0x370 95 #define TX_TERMINAL_CTRL_50_OHM __BIT(4) 96 #define ANXDP_ANALOG_CTL_2 0x374 97 #define SEL_24M __BIT(3) 98 #define TX_DVDD_BIT_1_0625V 0x4 99 #define ANXDP_ANALOG_CTL_3 0x378 100 #define DRIVE_DVDD_BIT_1_0625V (0x4 << 5) 101 #define VCO_BIT_600_MICRO (0x5 << 0) 102 #define ANXDP_PLL_FILTER_CTL_1 0x37c 103 #define PD_RING_OSC __BIT(6) 104 #define AUX_TERMINAL_CTRL_50_OHM (2 << 4) 105 #define TX_CUR1_2X __BIT(2) 106 #define TX_CUR_16_MA 3 107 #define ANXDP_TX_AMP_TUNING_CTL 0x380 108 #define ANXDP_AUX_HW_RETRY_CTL 0x390 109 #define AUX_BIT_PERIOD_EXPECTED_DELAY(x) __SHIFTIN((x), __BITS(10,8)) 110 #define AUX_HW_RETRY_INTERVAL_600_US __SHIFTIN(0, __BITS(4,3)) 111 #define AUX_HW_RETRY_INTERVAL_800_US __SHIFTIN(1, __BITS(4,3)) 112 #define AUX_HW_RETRY_INTERVAL_1000_US __SHIFTIN(2, __BITS(4,3)) 113 #define AUX_HW_RETRY_INTERVAL_1800_US __SHIFTIN(3, __BITS(4,3)) 114 #define AUX_HW_RETRY_COUNT_SEL(x) __SHIFTIN((x), __BITS(2,0)) 115 #define ANXDP_COMMON_INT_STA_1 0x3c4 116 #define PLL_LOCK_CHG __BIT(6) 117 #define ANXDP_COMMON_INT_STA_2 0x3c8 118 #define ANXDP_COMMON_INT_STA_3 0x3cc 119 #define ANXDP_COMMON_INT_STA_4 0x3d0 120 #define ANXDP_DP_INT_STA 0x3dc 121 #define INT_HPD __BIT(6) 122 #define HW_TRAINING_FINISH __BIT(5) 123 #define RPLY_RECEIV __BIT(1) 124 #define AUX_ERR __BIT(0) 125 #define ANXDP_SYS_CTL_1 0x600 126 #define DET_STA __BIT(2) 127 #define FORCE_DET __BIT(1) 128 #define DET_CTRL __BIT(0) 129 #define ANXDP_SYS_CTL_2 0x604 130 #define ANXDP_SYS_CTL_3 0x608 131 #define HPD_STATUS __BIT(6) 132 #define F_HPD __BIT(5) 133 #define HPD_CTRL __BIT(4) 134 #define HDCP_RDY __BIT(3) 135 #define STRM_VALID __BIT(2) 136 #define F_VALID __BIT(1) 137 #define VALID_CTRL __BIT(0) 138 #define ANXDP_SYS_CTL_4 0x60c 139 #define ANXDP_PKT_SEND_CTL 0x640 140 #define ANXDP_HDCP_CTL 0x648 141 #define ANXDP_LINK_BW_SET 0x680 142 #define ANXDP_LANE_COUNT_SET 0x684 143 #define ANXDP_TRAINING_PTN_SET 0x688 144 #define SCRAMBLING_DISABLE __BIT(5) 145 #define SW_TRAINING_PATTERN_SET_PTN2 __SHIFTIN(2, __BITS(1,0)) 146 #define SW_TRAINING_PATTERN_SET_PTN1 __SHIFTIN(1, __BITS(1,0)) 147 #define ANXDP_LNx_LINK_TRAINING_CTL(x) (0x68c + 4 * (x)) /* 0 <= x <= 3 */ 148 #define MAX_PRE_REACH __BIT(5) 149 #define PRE_EMPHASIS_SET(x) __SHIFTIN((x), __BITS(4,3)) 150 #define MAX_DRIVE_REACH __BIT(2) 151 #define DRIVE_CURRENT_SET(x) __SHIFTIN((x), __BITS(1,0)) 152 #define ANXDP_DEBUG_CTL 0x6c0 153 #define PLL_LOCK __BIT(4) 154 #define F_PLL_LOCK __BIT(3) 155 #define PLL_LOCK_CTRL __BIT(2) 156 #define PN_INV __BIT(0) 157 #define ANXDP_LINK_DEBUG_CTL 0x6e0 158 #define ANXDP_PLL_CTL 0x71c 159 #define ANXDP_PHY_PD 0x720 160 #define ANXDP_PHY_TEST 0x724 161 #define MACRO_RST __BIT(5) 162 #define ANXDP_M_AUD_GEN_FILTER_TH 0x778 163 #define ANXDP_AUX_CH_STA 0x780 164 #define AUX_BUSY __BIT(4) 165 #define AUX_STATUS(x) __SHIFTOUT((x), __BITS(3,0)) 166 #define ANXDP_AUX_ERR_NUM 0x784 167 #define ANXDP_AUX_CH_DEFER_CTL 0x788 168 #define DEFER_CTRL_EN __BIT(7) 169 #define DEFER_COUNT(x) __SHIFTIN((x), __BITS(6,0)) 170 #define ANXDP_AUX_RX_COMM 0x78c 171 #define AUX_RX_COMM_I2C_DEFER __BIT(3) 172 #define AUX_RX_COMM_AUX_DEFER __BIT(1) 173 #define ANXDP_BUFFER_DATA_CTL 0x790 174 #define BUF_CLR __BIT(7) 175 #define BUF_DATA_COUNT(x) __SHIFTIN((x), __BITS(4,0)) 176 #define ANXDP_AUX_CH_CTL_1 0x794 177 #define AUX_LENGTH(x) __SHIFTIN((x) - 1, __BITS(7,4)) 178 #define AUX_TX_COMM(x) __SHIFTOUT(x, __BITS(3,0)) 179 #define AUX_TX_COMM_DP __BIT(3) 180 #define AUX_TX_COMM_MOT __BIT(2) 181 #define AUX_TX_COMM_READ __BIT(0) 182 #define ANXDP_AUX_ADDR_7_0 0x798 183 #define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff) 184 #define ANXDP_AUX_ADDR_15_8 0x79c 185 #define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff) 186 #define ANXDP_AUX_ADDR_19_16 0x7a0 187 #define AUX_ADDR_19_16(x) (((x) >> 16) & 0xf) 188 #define ANXDP_AUX_CH_CTL_2 0x7a4 189 #define ADDR_ONLY __BIT(1) 190 #define AUX_EN __BIT(0) 191 #define ANXDP_BUF_DATA(x) (0x7c0 + 4 * (x)) 192 #define ANXDP_SOC_GENERAL_CTL 0x800 193 #define AUDIO_MODE_SPDIF_MODE __BIT(8) 194 #define VIDEO_MODE_SLAVE_MODE __BIT(1) 195 #define ANXDP_CRC_CON 0x890 196 #define ANXDP_PLL_REG_2 0x9e4 197 #define ANXDP_PLL_REG_3 0x9e8 198 #define ANXDP_PLL_REG_4 0x9ec 199 #define ANXDP_PLL_REG_5 0xa00 200 201 struct anxdp_link { 202 uint8_t revision; 203 u_int rate; 204 u_int num_lanes; 205 bool enhanced_framing; 206 }; 207 208 #if ANXDP_AUDIO 209 enum anxdp_dai_mixer_ctrl { 210 ANXDP_DAI_OUTPUT_CLASS, 211 ANXDP_DAI_INPUT_CLASS, 212 213 ANXDP_DAI_OUTPUT_MASTER_VOLUME, 214 ANXDP_DAI_INPUT_DAC_VOLUME, 215 216 ANXDP_DAI_MIXER_CTRL_LAST 217 }; 218 219 static void 220 anxdp_audio_init(struct anxdp_softc *sc) 221 { 222 } 223 #endif 224 225 static inline const bool 226 isrockchip(struct anxdp_softc * const sc) 227 { 228 return (sc->sc_flags & ANXDP_FLAG_ROCKCHIP) != 0; 229 } 230 231 static enum drm_connector_status 232 anxdp_connector_detect(struct drm_connector *connector, bool force) 233 { 234 #if 0 235 struct anxdp_connector *anxdp_connector = to_anxdp_connector(connector); 236 struct anxdp_softc * const sc = anxdp_connector->sc; 237 238 /* XXX HPD */ 239 #endif 240 return connector_status_connected; 241 } 242 243 static void 244 anxdp_connector_destroy(struct drm_connector *connector) 245 { 246 drm_connector_unregister(connector); 247 drm_connector_cleanup(connector); 248 } 249 250 static const struct drm_connector_funcs anxdp_connector_funcs = { 251 .dpms = drm_helper_connector_dpms, 252 .detect = anxdp_connector_detect, 253 .fill_modes = drm_helper_probe_single_connector_modes, 254 .destroy = anxdp_connector_destroy, 255 }; 256 257 static void 258 anxdp_analog_power_up_all(struct anxdp_softc * const sc) 259 { 260 const bus_size_t pd_reg = isrockchip(sc) ? RKANXDP_PD : ANXDP_PHY_PD; 261 262 bus_space_write_4(sc->sc_bst, sc->sc_bsh, pd_reg, DP_ALL_PD); 263 delay(15); 264 bus_space_write_4(sc->sc_bst, sc->sc_bsh, pd_reg, 265 DP_ALL_PD & ~DP_INC_BG); 266 delay(15); 267 bus_space_write_4(sc->sc_bst, sc->sc_bsh, pd_reg, 0); 268 } 269 270 static int 271 anxdp_await_pll_lock(struct anxdp_softc * const sc) 272 { 273 u_int timeout; 274 275 for (timeout = 0; timeout < 100; timeout++) { 276 if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_DEBUG_CTL) & 277 PLL_LOCK) != 0) 278 return 0; 279 delay(20); 280 } 281 282 return ETIMEDOUT; 283 } 284 285 static void 286 anxdp_init_hpd(struct anxdp_softc * const sc) 287 { 288 uint32_t sc3; 289 290 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_COMMON_INT_STA_4, 0x7); 291 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_DP_INT_STA, INT_HPD); 292 293 sc3 = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_SYS_CTL_3); 294 sc3 &= ~(F_HPD | HPD_CTRL); 295 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_SYS_CTL_3, sc3); 296 297 sc3 = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_SYS_CTL_3); 298 sc3 |= F_HPD | HPD_CTRL; 299 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_SYS_CTL_3, sc3); 300 } 301 302 static void 303 anxdp_init_aux(struct anxdp_softc * const sc) 304 { 305 uint32_t fe2, pd, hrc; 306 const bus_size_t pd_reg = isrockchip(sc) ? RKANXDP_PD : ANXDP_PHY_PD; 307 const uint32_t pd_mask = isrockchip(sc) ? RK_AUX_PD : AUX_PD; 308 309 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_DP_INT_STA, 310 RPLY_RECEIV | AUX_ERR); 311 312 pd = bus_space_read_4(sc->sc_bst, sc->sc_bsh, pd_reg); 313 pd |= pd_mask; 314 bus_space_write_4(sc->sc_bst, sc->sc_bsh, pd_reg, pd); 315 316 delay(11); 317 318 pd = bus_space_read_4(sc->sc_bst, sc->sc_bsh, pd_reg); 319 pd &= ~pd_mask; 320 bus_space_write_4(sc->sc_bst, sc->sc_bsh, pd_reg, pd); 321 322 fe2 = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_2); 323 fe2 |= AUX_FUNC_EN_N; 324 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_2, fe2); 325 326 hrc = AUX_HW_RETRY_COUNT_SEL(0) | AUX_HW_RETRY_INTERVAL_600_US; 327 if (!isrockchip(sc)) 328 hrc |= AUX_BIT_PERIOD_EXPECTED_DELAY(3); 329 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_HW_RETRY_CTL, hrc); 330 331 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_CH_DEFER_CTL, 332 DEFER_CTRL_EN | DEFER_COUNT(1)); 333 334 fe2 = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_2); 335 fe2 &= ~AUX_FUNC_EN_N; 336 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_2, fe2); 337 } 338 339 static int 340 anxdp_connector_get_modes(struct drm_connector *connector) 341 { 342 struct anxdp_connector *anxdp_connector = to_anxdp_connector(connector); 343 struct anxdp_softc * const sc = anxdp_connector->sc; 344 struct edid *pedid = NULL; 345 int error; 346 347 pedid = drm_get_edid(connector, &sc->sc_dpaux.ddc); 348 349 #if ANXDP_AUDIO 350 if (pedid) { 351 anxdp_connector->monitor_audio = 352 drm_detect_monitor_audio(pedid); 353 } else { 354 anxdp_connector->monitor_audio = false; 355 } 356 357 #endif 358 drm_connector_update_edid_property(connector, pedid); 359 if (pedid == NULL) 360 return 0; 361 362 error = drm_add_edid_modes(connector, pedid); 363 364 if (pedid != NULL) 365 kfree(pedid); 366 367 return error; 368 } 369 370 static const struct drm_connector_helper_funcs anxdp_connector_helper_funcs = { 371 .get_modes = anxdp_connector_get_modes, 372 }; 373 374 static int 375 anxdp_bridge_attach(struct drm_bridge *bridge) 376 { 377 struct anxdp_softc * const sc = bridge->driver_private; 378 struct anxdp_connector *anxdp_connector = &sc->sc_connector; 379 struct drm_connector *connector = &anxdp_connector->base; 380 int error; 381 382 anxdp_connector->sc = sc; 383 384 connector->polled = 385 DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; 386 connector->interlace_allowed = 0; 387 connector->doublescan_allowed = 0; 388 389 drm_connector_init(bridge->dev, connector, &anxdp_connector_funcs, 390 connector->connector_type); 391 drm_connector_helper_add(connector, &anxdp_connector_helper_funcs); 392 393 error = drm_connector_attach_encoder(connector, bridge->encoder); 394 if (error != 0) 395 return error; 396 397 return drm_connector_register(connector); 398 } 399 400 static void 401 anxdp_macro_reset(struct anxdp_softc * const sc) 402 { 403 uint32_t val; 404 405 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_PHY_TEST); 406 val |= MACRO_RST; 407 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_PHY_TEST, val); 408 delay(10); 409 val &= ~MACRO_RST; 410 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_PHY_TEST, val); 411 } 412 413 static void 414 anxdp_link_start(struct anxdp_softc * const sc, struct anxdp_link * const link) 415 { 416 uint8_t training[4]; 417 uint8_t bw[2]; 418 uint32_t val; 419 420 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_LINK_BW_SET, drm_dp_link_rate_to_bw_code(link->rate)); 421 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_LANE_COUNT_SET, link->num_lanes); 422 423 bw[0] = drm_dp_link_rate_to_bw_code(link->rate); 424 bw[1] = link->num_lanes; 425 if (link->enhanced_framing) 426 bw[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; 427 if (drm_dp_dpcd_write(&sc->sc_dpaux, DP_LINK_BW_SET, bw, sizeof(bw)) < 0) 428 return; 429 430 for (u_int i = 0; i < link->num_lanes; i++) { 431 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 432 ANXDP_LNx_LINK_TRAINING_CTL(i)); 433 val &= ~(PRE_EMPHASIS_SET(3)|DRIVE_CURRENT_SET(3)); 434 val |= PRE_EMPHASIS_SET(0); 435 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 436 ANXDP_LNx_LINK_TRAINING_CTL(i), val); 437 } 438 439 if (anxdp_await_pll_lock(sc) != 0) { 440 device_printf(sc->sc_dev, "PLL lock timeout\n"); 441 } 442 443 for (u_int i = 0; i < link->num_lanes; i++) { 444 training[i] = DP_TRAIN_PRE_EMPH_LEVEL_0 | 445 DP_TRAIN_VOLTAGE_SWING_LEVEL_0; 446 } 447 448 drm_dp_dpcd_write(&sc->sc_dpaux, DP_TRAINING_LANE0_SET, training, 449 link->num_lanes); 450 } 451 452 static void 453 anxdp_process_clock_recovery(struct anxdp_softc * const sc, 454 struct anxdp_link * const link) 455 { 456 u_int i, tries; 457 uint8_t link_status[DP_LINK_STATUS_SIZE]; 458 uint8_t training[4]; 459 460 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_TRAINING_PTN_SET, 461 SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1); 462 drm_dp_dpcd_writeb(&sc->sc_dpaux, DP_TRAINING_PATTERN_SET, 463 DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1); 464 465 tries = 0; 466 again: 467 if (tries++ >= 10) { 468 device_printf(sc->sc_dev, "cr fail\n"); 469 return; 470 } 471 drm_dp_link_train_clock_recovery_delay(sc->sc_dpcd); 472 if (DP_LINK_STATUS_SIZE != 473 drm_dp_dpcd_read_link_status(&sc->sc_dpaux, link_status)) { 474 return; 475 } 476 if (!drm_dp_clock_recovery_ok(link_status, link->num_lanes)) { 477 goto cr_fail; 478 } 479 480 return; 481 482 cr_fail: 483 for (i = 0; i < link->num_lanes; i++) { 484 uint8_t vs, pe; 485 vs = drm_dp_get_adjust_request_voltage(link_status, i); 486 pe = drm_dp_get_adjust_request_pre_emphasis(link_status, i); 487 training[i] = vs | pe; 488 } 489 for (i = 0; i < link->num_lanes; i++) { 490 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 491 ANXDP_LNx_LINK_TRAINING_CTL(i), training[i]); 492 } 493 drm_dp_dpcd_write(&sc->sc_dpaux, DP_TRAINING_LANE0_SET, training, 494 link->num_lanes); 495 goto again; 496 } 497 498 static void 499 anxdp_process_eq(struct anxdp_softc * const sc, struct anxdp_link * const link) 500 { 501 u_int i, tries; 502 uint8_t link_status[DP_LINK_STATUS_SIZE]; 503 uint8_t training[4]; 504 505 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_TRAINING_PTN_SET, 506 SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2); 507 drm_dp_dpcd_writeb(&sc->sc_dpaux, DP_TRAINING_PATTERN_SET, 508 DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_2); 509 510 tries = 0; 511 again: 512 if (tries++ >= 10) { 513 device_printf(sc->sc_dev, "eq fail\n"); 514 return; 515 } 516 drm_dp_link_train_channel_eq_delay(sc->sc_dpcd); 517 if (DP_LINK_STATUS_SIZE != 518 drm_dp_dpcd_read_link_status(&sc->sc_dpaux, link_status)) { 519 return; 520 } 521 if (!drm_dp_channel_eq_ok(link_status, link->num_lanes)) { 522 goto eq_fail; 523 } 524 525 return; 526 527 eq_fail: 528 for (i = 0; i < link->num_lanes; i++) { 529 uint8_t vs, pe; 530 vs = drm_dp_get_adjust_request_voltage(link_status, i); 531 pe = drm_dp_get_adjust_request_pre_emphasis(link_status, i); 532 training[i] = vs | pe; 533 } 534 for (i = 0; i < link->num_lanes; i++) { 535 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 536 ANXDP_LNx_LINK_TRAINING_CTL(i), training[i]); 537 } 538 drm_dp_dpcd_write(&sc->sc_dpaux, DP_TRAINING_LANE0_SET, training, 539 link->num_lanes); 540 goto again; 541 } 542 543 static void 544 anxdp_train_link(struct anxdp_softc * const sc) 545 { 546 struct anxdp_link link; 547 uint8_t values[3], power; 548 549 anxdp_macro_reset(sc); 550 551 if (drm_dp_dpcd_read(&sc->sc_dpaux, DP_DPCD_REV, values, sizeof(values)) < 0) { 552 device_printf(sc->sc_dev, "link probe failed\n"); 553 return; 554 } 555 memset(&link, 0, sizeof(link)); 556 link.revision = values[0]; 557 link.rate = drm_dp_bw_code_to_link_rate(values[1]); 558 link.num_lanes = values[2] & DP_MAX_LANE_COUNT_MASK; 559 if (values[2] & DP_ENHANCED_FRAME_CAP) 560 link.enhanced_framing = true; 561 562 if (link.revision >= 0x11) { 563 if (drm_dp_dpcd_readb(&sc->sc_dpaux, DP_SET_POWER, &power) < 0) 564 return; 565 power &= ~DP_SET_POWER_MASK; 566 power |= DP_SET_POWER_D0; 567 if (drm_dp_dpcd_writeb(&sc->sc_dpaux, DP_SET_POWER, power) < 0) 568 return; 569 delay(2000); 570 } 571 572 if (DP_RECEIVER_CAP_SIZE != drm_dp_dpcd_read(&sc->sc_dpaux, DP_DPCD_REV, 573 sc->sc_dpcd, DP_RECEIVER_CAP_SIZE)) 574 return; 575 576 anxdp_link_start(sc, &link); 577 anxdp_process_clock_recovery(sc, &link); 578 anxdp_process_eq(sc, &link); 579 580 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_TRAINING_PTN_SET, 0); 581 drm_dp_dpcd_writeb(&sc->sc_dpaux, DP_TRAINING_PATTERN_SET, 582 DP_TRAINING_PATTERN_DISABLE); 583 584 } 585 586 static void 587 anxdp_bringup(struct anxdp_softc * const sc) 588 { 589 uint32_t val; 590 591 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_VIDEO_CTL_1); 592 val &= ~VIDEO_EN; 593 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_VIDEO_CTL_1, val); 594 595 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_VIDEO_CTL_1); 596 val &= ~VIDEO_MUTE; 597 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_VIDEO_CTL_1, val); 598 599 val = SW_FUNC_EN_N; 600 if (isrockchip(sc)) { 601 val |= RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N; 602 } else { 603 val |= MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N | 604 AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N | HDCP_FUNC_EN_N; 605 } 606 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_1, val); 607 608 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_2, 609 SSC_FUNC_EN_N | AUX_FUNC_EN_N | SERDES_FIFO_FUNC_EN_N | 610 LS_CLK_DOMAIN_FUNC_EN_N); 611 612 delay(30); 613 614 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_M_AUD_GEN_FILTER_TH, 2); 615 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_SOC_GENERAL_CTL, 0x101); 616 617 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_TX_SW_RESET, 618 RESET_DP_TX); 619 620 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_ANALOG_CTL_1, 621 TX_TERMINAL_CTRL_50_OHM); 622 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_ANALOG_CTL_2, 623 SEL_24M | TX_DVDD_BIT_1_0625V); 624 if (isrockchip(sc)) { 625 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_PLL_REG_1, 626 REF_CLK_24M); 627 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_PLL_REG_2, 628 0x95); 629 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_PLL_REG_3, 630 0x40); 631 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_PLL_REG_4, 632 0x58); 633 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_PLL_REG_5, 634 0x22); 635 } 636 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_ANALOG_CTL_3, 637 DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO); 638 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_PLL_FILTER_CTL_1, 639 PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | TX_CUR1_2X | TX_CUR_16_MA); 640 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_TX_AMP_TUNING_CTL, 0); 641 642 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_1); 643 val &= ~SW_FUNC_EN_N; 644 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_1, val); 645 646 anxdp_analog_power_up_all(sc); 647 648 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_COMMON_INT_STA_1, 649 PLL_LOCK_CHG); 650 651 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_DEBUG_CTL); 652 val &= ~(F_PLL_LOCK | PLL_LOCK_CTRL); 653 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_DEBUG_CTL, val); 654 655 if (anxdp_await_pll_lock(sc) != 0) { 656 device_printf(sc->sc_dev, "PLL lock timeout\n"); 657 } 658 659 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_2); 660 val &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N | 661 AUX_FUNC_EN_N); 662 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_2, val); 663 664 anxdp_init_hpd(sc); 665 anxdp_init_aux(sc); 666 } 667 668 static void 669 anxdp_bridge_enable(struct drm_bridge *bridge) 670 { 671 struct anxdp_softc * const sc = bridge->driver_private; 672 uint32_t val; 673 674 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_1); 675 if (isrockchip(sc)) { 676 val &= ~(RK_VID_CAP_FUNC_EN_N | RK_VID_FIFO_FUNC_EN_N); 677 } else { 678 val &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N); 679 val |= MASTER_VID_FUNC_EN_N; 680 } 681 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_FUNC_EN_1, val); 682 683 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_VIDEO_CTL_10); 684 val &= ~(SLAVE_I_SCAN_CFG|SLAVE_VSYNC_P_CFG|SLAVE_HSYNC_P_CFG); 685 if ((sc->sc_curmode.flags & DRM_MODE_FLAG_INTERLACE) != 0) 686 val |= SLAVE_I_SCAN_CFG; 687 if ((sc->sc_curmode.flags & DRM_MODE_FLAG_NVSYNC) != 0) 688 val |= SLAVE_VSYNC_P_CFG; 689 if ((sc->sc_curmode.flags & DRM_MODE_FLAG_NHSYNC) != 0) 690 val |= SLAVE_HSYNC_P_CFG; 691 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_VIDEO_CTL_10, val); 692 693 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_SOC_GENERAL_CTL, 694 AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE); 695 696 anxdp_train_link(sc); 697 698 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_VIDEO_CTL_1); 699 val |= VIDEO_EN; 700 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_VIDEO_CTL_1, val); 701 702 if (sc->sc_panel != NULL && 703 sc->sc_panel->funcs != NULL && 704 sc->sc_panel->funcs->enable != NULL) 705 sc->sc_panel->funcs->enable(sc->sc_panel); 706 #if ANXDP_AUDIO 707 708 if (sc->sc_connector.monitor_audio) 709 anxdp_audio_init(sc); 710 #endif 711 } 712 713 static void 714 anxdp_bridge_pre_enable(struct drm_bridge *bridge) 715 { 716 } 717 718 static void 719 anxdp_bridge_disable(struct drm_bridge *bridge) 720 { 721 } 722 723 static void 724 anxdp_bridge_post_disable(struct drm_bridge *bridge) 725 { 726 } 727 728 static void 729 anxdp_bridge_mode_set(struct drm_bridge *bridge, 730 const struct drm_display_mode *mode, const struct drm_display_mode *adjusted_mode) 731 { 732 struct anxdp_softc * const sc = bridge->driver_private; 733 734 sc->sc_curmode = *adjusted_mode; 735 } 736 737 static bool 738 anxdp_bridge_mode_fixup(struct drm_bridge *bridge, 739 const struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) 740 { 741 return true; 742 } 743 744 static const struct drm_bridge_funcs anxdp_bridge_funcs = { 745 .attach = anxdp_bridge_attach, 746 .enable = anxdp_bridge_enable, 747 .pre_enable = anxdp_bridge_pre_enable, 748 .disable = anxdp_bridge_disable, 749 .post_disable = anxdp_bridge_post_disable, 750 .mode_set = anxdp_bridge_mode_set, 751 .mode_fixup = anxdp_bridge_mode_fixup, 752 }; 753 754 #if ANXDP_AUDIO 755 static int 756 anxdp_dai_set_format(audio_dai_tag_t dai, u_int format) 757 { 758 return 0; 759 } 760 761 static int 762 anxdp_dai_add_device(audio_dai_tag_t dai, audio_dai_tag_t aux) 763 { 764 /* Not supported */ 765 return 0; 766 } 767 768 static void 769 anxdp_audio_swvol_codec(audio_filter_arg_t *arg) 770 { 771 struct anxdp_softc * const sc = arg->context; 772 const aint_t *src; 773 aint_t *dst; 774 u_int sample_count; 775 u_int i; 776 777 src = arg->src; 778 dst = arg->dst; 779 sample_count = arg->count * arg->srcfmt->channels; 780 for (i = 0; i < sample_count; i++) { 781 aint2_t v = (aint2_t)(*src++); 782 v = v * sc->sc_swvol / 255; 783 *dst++ = (aint_t)v; 784 } 785 } 786 787 static int 788 anxdp_audio_set_format(void *priv, int setmode, 789 const audio_params_t *play, const audio_params_t *rec, 790 audio_filter_reg_t *pfil, audio_filter_reg_t *rfil) 791 { 792 struct anxdp_softc * const sc = priv; 793 794 pfil->codec = anxdp_audio_swvol_codec; 795 pfil->context = sc; 796 797 return 0; 798 } 799 800 static int 801 anxdp_audio_set_port(void *priv, mixer_ctrl_t *mc) 802 { 803 struct anxdp_softc * const sc = priv; 804 805 switch (mc->dev) { 806 case ANXDP_DAI_OUTPUT_MASTER_VOLUME: 807 case ANXDP_DAI_INPUT_DAC_VOLUME: 808 sc->sc_swvol = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; 809 return 0; 810 default: 811 return ENXIO; 812 } 813 } 814 815 static int 816 anxdp_audio_get_port(void *priv, mixer_ctrl_t *mc) 817 { 818 struct anxdp_softc * const sc = priv; 819 820 switch (mc->dev) { 821 case ANXDP_DAI_OUTPUT_MASTER_VOLUME: 822 case ANXDP_DAI_INPUT_DAC_VOLUME: 823 mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = sc->sc_swvol; 824 mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = sc->sc_swvol; 825 return 0; 826 default: 827 return ENXIO; 828 } 829 } 830 831 static int 832 anxdp_audio_query_devinfo(void *priv, mixer_devinfo_t *di) 833 { 834 switch (di->index) { 835 case ANXDP_DAI_OUTPUT_CLASS: 836 di->mixer_class = di->index; 837 strcpy(di->label.name, AudioCoutputs); 838 di->type = AUDIO_MIXER_CLASS; 839 di->next = di->prev = AUDIO_MIXER_LAST; 840 return 0; 841 842 case ANXDP_DAI_INPUT_CLASS: 843 di->mixer_class = di->index; 844 strcpy(di->label.name, AudioCinputs); 845 di->type = AUDIO_MIXER_CLASS; 846 di->next = di->prev = AUDIO_MIXER_LAST; 847 return 0; 848 849 case ANXDP_DAI_OUTPUT_MASTER_VOLUME: 850 di->mixer_class = ANXDP_DAI_OUTPUT_CLASS; 851 strcpy(di->label.name, AudioNmaster); 852 di->un.v.delta = 1; 853 di->un.v.num_channels = 2; 854 strcpy(di->un.v.units.name, AudioNvolume); 855 di->type = AUDIO_MIXER_VALUE; 856 di->next = di->prev = AUDIO_MIXER_LAST; 857 return 0; 858 859 case ANXDP_DAI_INPUT_DAC_VOLUME: 860 di->mixer_class = ANXDP_DAI_INPUT_CLASS; 861 strcpy(di->label.name, AudioNdac); 862 di->un.v.delta = 1; 863 di->un.v.num_channels = 2; 864 strcpy(di->un.v.units.name, AudioNvolume); 865 di->type = AUDIO_MIXER_VALUE; 866 di->next = di->prev = AUDIO_MIXER_LAST; 867 return 0; 868 869 default: 870 return ENXIO; 871 } 872 } 873 874 static const struct audio_hw_if anxdp_dai_hw_if = { 875 .set_format = anxdp_audio_set_format, 876 .set_port = anxdp_audio_set_port, 877 .get_port = anxdp_audio_get_port, 878 .query_devinfo = anxdp_audio_query_devinfo, 879 }; 880 #endif 881 882 static ssize_t 883 anxdp_dp_aux_transfer(struct drm_dp_aux *dpaux, struct drm_dp_aux_msg *dpmsg) 884 { 885 struct anxdp_softc * const sc = container_of(dpaux, struct anxdp_softc, 886 sc_dpaux); 887 size_t loop_timeout = 0; 888 uint32_t val; 889 size_t i; 890 ssize_t ret = 0; 891 892 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_BUFFER_DATA_CTL, 893 BUF_CLR); 894 895 val = AUX_LENGTH(dpmsg->size); 896 if ((dpmsg->request & DP_AUX_I2C_MOT) != 0) 897 val |= AUX_TX_COMM_MOT; 898 899 switch (dpmsg->request & ~DP_AUX_I2C_MOT) { 900 case DP_AUX_I2C_WRITE: 901 break; 902 case DP_AUX_I2C_READ: 903 val |= AUX_TX_COMM_READ; 904 break; 905 case DP_AUX_NATIVE_WRITE: 906 val |= AUX_TX_COMM_DP; 907 break; 908 case DP_AUX_NATIVE_READ: 909 val |= AUX_TX_COMM_READ | AUX_TX_COMM_DP; 910 break; 911 } 912 913 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_CH_CTL_1, val); 914 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_ADDR_7_0, 915 AUX_ADDR_7_0(dpmsg->address)); 916 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_ADDR_15_8, 917 AUX_ADDR_15_8(dpmsg->address)); 918 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_ADDR_19_16, 919 AUX_ADDR_19_16(dpmsg->address)); 920 921 if (!(dpmsg->request & DP_AUX_I2C_READ)) { 922 for (i = 0; i < dpmsg->size; i++) { 923 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 924 ANXDP_BUF_DATA(i), 925 ((const uint8_t *)(dpmsg->buffer))[i]); 926 ret++; 927 } 928 } 929 930 931 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_CH_CTL_2, 932 AUX_EN | ((dpmsg->size == 0) ? ADDR_ONLY : 0)); 933 934 loop_timeout = 0; 935 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_CH_CTL_2); 936 while ((val & AUX_EN) != 0) { 937 if (++loop_timeout > 20000) { 938 ret = -ETIMEDOUT; 939 goto out; 940 } 941 delay(25); 942 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 943 ANXDP_AUX_CH_CTL_2); 944 } 945 946 loop_timeout = 0; 947 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_DP_INT_STA); 948 while (!(val & RPLY_RECEIV)) { 949 if (++loop_timeout > 2000) { 950 ret = -ETIMEDOUT; 951 goto out; 952 } 953 delay(10); 954 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 955 ANXDP_DP_INT_STA); 956 } 957 958 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_DP_INT_STA, 959 RPLY_RECEIV); 960 961 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_DP_INT_STA); 962 if ((val & AUX_ERR) != 0) { 963 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_DP_INT_STA, 964 AUX_ERR); 965 ret = -EREMOTEIO; 966 goto out; 967 } 968 969 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_CH_STA); 970 if (AUX_STATUS(val) != 0) { 971 ret = -EREMOTEIO; 972 goto out; 973 } 974 975 if ((dpmsg->request & DP_AUX_I2C_READ)) { 976 for (i = 0; i < dpmsg->size; i++) { 977 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 978 ANXDP_BUF_DATA(i)); 979 ((uint8_t *)(dpmsg->buffer))[i] = val & 0xffU; 980 ret++; 981 } 982 } 983 984 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_AUX_RX_COMM); 985 if (val == AUX_RX_COMM_AUX_DEFER) 986 dpmsg->reply = DP_AUX_NATIVE_REPLY_DEFER; 987 else if (val == AUX_RX_COMM_I2C_DEFER) 988 dpmsg->reply = DP_AUX_I2C_REPLY_DEFER; 989 else if ((dpmsg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_WRITE || 990 (dpmsg->request & ~DP_AUX_I2C_MOT) == DP_AUX_I2C_READ) 991 dpmsg->reply = DP_AUX_I2C_REPLY_ACK; 992 else if ((dpmsg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_WRITE || 993 (dpmsg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) 994 dpmsg->reply = DP_AUX_NATIVE_REPLY_ACK; 995 996 out: 997 if (ret < 0) 998 anxdp_init_aux(sc); 999 1000 return ret; 1001 } 1002 1003 void 1004 anxdp_dpms(struct anxdp_softc *sc, int mode) 1005 { 1006 switch (mode) { 1007 case DRM_MODE_DPMS_ON: 1008 pmf_event_inject(NULL, PMFE_DISPLAY_ON); 1009 break; 1010 case DRM_MODE_DPMS_STANDBY: 1011 case DRM_MODE_DPMS_SUSPEND: 1012 case DRM_MODE_DPMS_OFF: 1013 pmf_event_inject(NULL, PMFE_DISPLAY_OFF); 1014 break; 1015 } 1016 } 1017 1018 int 1019 anxdp_attach(struct anxdp_softc *sc) 1020 { 1021 #if ANXDP_AUDIO 1022 sc->sc_swvol = 255; 1023 1024 /* 1025 * Initialize audio DAI 1026 */ 1027 sc->sc_dai.dai_set_format = anxdp_dai_set_format; 1028 sc->sc_dai.dai_add_device = anxdp_dai_add_device; 1029 sc->sc_dai.dai_hw_if = &anxdp_dai_hw_if; 1030 sc->sc_dai.dai_dev = sc->sc_dev; 1031 sc->sc_dai.dai_priv = sc; 1032 #endif 1033 1034 sc->sc_dpaux.name = "DP Aux"; 1035 sc->sc_dpaux.transfer = anxdp_dp_aux_transfer; 1036 sc->sc_dpaux.dev = sc->sc_dev; 1037 if (drm_dp_aux_register(&sc->sc_dpaux) != 0) { 1038 device_printf(sc->sc_dev, "registering DP Aux failed\n"); 1039 } 1040 1041 anxdp_bringup(sc); 1042 1043 return 0; 1044 } 1045 1046 int 1047 anxdp_bind(struct anxdp_softc *sc, struct drm_encoder *encoder) 1048 { 1049 int error; 1050 1051 sc->sc_bridge.driver_private = sc; 1052 sc->sc_bridge.funcs = &anxdp_bridge_funcs; 1053 sc->sc_bridge.encoder = encoder; 1054 1055 error = drm_bridge_attach(encoder, &sc->sc_bridge, NULL); 1056 if (error != 0) 1057 return EIO; 1058 1059 if (sc->sc_panel != NULL && sc->sc_panel->funcs != NULL && sc->sc_panel->funcs->prepare != NULL) 1060 sc->sc_panel->funcs->prepare(sc->sc_panel); 1061 1062 return 0; 1063 } 1064 1065 void anxdp0_dump(void); 1066 1067 void 1068 anxdp0_dump(void) 1069 { 1070 extern struct cfdriver anxdp_cd; 1071 struct anxdp_softc * const sc = device_lookup_private(&anxdp_cd, 0); 1072 size_t i; 1073 1074 if (sc == NULL) 1075 return; 1076 1077 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_SYS_CTL_1, 1078 bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_SYS_CTL_1)); 1079 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_SYS_CTL_2, 1080 bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_SYS_CTL_2)); 1081 bus_space_write_4(sc->sc_bst, sc->sc_bsh, ANXDP_SYS_CTL_3, 1082 bus_space_read_4(sc->sc_bst, sc->sc_bsh, ANXDP_SYS_CTL_3)); 1083 for (i = 0x000; i < 0xb00; i += 4) 1084 device_printf(sc->sc_dev, "%03zx 0x%08x\n", i, 1085 bus_space_read_4(sc->sc_bst, sc->sc_bsh, i)); 1086 } 1087