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