^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Synopsys DesignWare Cores DisplayPort Transmitter Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2021 Rockchip Electronics Co. Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Wyon Bi <bivvy.bi@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Zhang Yubing <yubing.zhang@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <drm/drm_atomic_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <drm/drm_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <drm/drm_dp_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <drm/drm_of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <drm/drm_print.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <drm/drm_probe_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <drm/drm_simple_kms_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/component.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/extcon-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/of_graph.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/mfd/syscon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <sound/hdmi-codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <uapi/linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include "rockchip_drm_drv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include "rockchip_drm_vop.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define DPTX_VERSION_NUMBER 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define DPTX_VERSION_TYPE 0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define DPTX_ID 0x0008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define DPTX_CONFIG_REG1 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DPTX_CONFIG_REG2 0x0104
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DPTX_CONFIG_REG3 0x0108
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define DPTX_CCTL 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define FORCE_HPD BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define DEFAULT_FAST_LINK_TRAIN_EN BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define ENHANCE_FRAMING_EN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define SCRAMBLE_DIS BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define DPTX_SOFT_RESET_CTRL 0x0204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define VIDEO_RESET BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define AUX_RESET BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define AUDIO_SAMPLER_RESET BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define PHY_SOFT_RESET BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define CONTROLLER_RESET BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define DPTX_VSAMPLE_CTRL 0x0300
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define PIXEL_MODE_SELECT GENMASK(22, 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define VIDEO_MAPPING GENMASK(20, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define VIDEO_STREAM_ENABLE BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define DPTX_VSAMPLE_STUFF_CTRL1 0x0304
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define DPTX_VSAMPLE_STUFF_CTRL2 0x0308
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define DPTX_VINPUT_POLARITY_CTRL 0x030c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define DE_IN_POLARITY BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define HSYNC_IN_POLARITY BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define VSYNC_IN_POLARITY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define DPTX_VIDEO_CONFIG1 0x0310
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define HACTIVE GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define HBLANK GENMASK(15, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define I_P BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define R_V_BLANK_IN_OSC BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define DPTX_VIDEO_CONFIG2 0x0314
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define VBLANK GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define VACTIVE GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define DPTX_VIDEO_CONFIG3 0x0318
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define H_SYNC_WIDTH GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define H_FRONT_PORCH GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define DPTX_VIDEO_CONFIG4 0x031c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define V_SYNC_WIDTH GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define V_FRONT_PORCH GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define DPTX_VIDEO_CONFIG5 0x0320
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define INIT_THRESHOLD_HI GENMASK(22, 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define AVERAGE_BYTES_PER_TU_FRAC GENMASK(19, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define INIT_THRESHOLD GENMASK(13, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define AVERAGE_BYTES_PER_TU GENMASK(6, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define DPTX_VIDEO_MSA1 0x0324
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define VSTART GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define HSTART GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define DPTX_VIDEO_MSA2 0x0328
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define MISC0 GENMASK(31, 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define DPTX_VIDEO_MSA3 0x032c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define MISC1 GENMASK(31, 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define DPTX_VIDEO_HBLANK_INTERVAL 0x0330
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define HBLANK_INTERVAL_EN BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define HBLANK_INTERVAL GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define DPTX_AUD_CONFIG1 0x0400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define AUDIO_TIMESTAMP_VERSION_NUM GENMASK(29, 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define AUDIO_PACKET_ID GENMASK(23, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define AUDIO_MUTE BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define NUM_CHANNELS GENMASK(14, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define HBR_MODE_ENABLE BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define AUDIO_DATA_WIDTH GENMASK(9, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define AUDIO_DATA_IN_EN GENMASK(4, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define AUDIO_INF_SELECT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #define DPTX_SDP_VERTICAL_CTRL 0x0500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) #define EN_VERTICAL_SDP BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define EN_AUDIO_STREAM_SDP BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define EN_AUDIO_TIMESTAMP_SDP BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define DPTX_SDP_HORIZONTAL_CTRL 0x0504
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define EN_HORIZONTAL_SDP BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define DPTX_SDP_STATUS_REGISTER 0x0508
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define DPTX_SDP_MANUAL_CTRL 0x050c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define DPTX_SDP_STATUS_EN 0x0510
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define DPTX_SDP_REGISTER_BANK 0x0600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define SDP_REGS GENMASK(31, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define DPTX_PHYIF_CTRL 0x0a00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define PHY_WIDTH BIT(25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define PHY_POWERDOWN GENMASK(20, 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define PHY_BUSY GENMASK(15, 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define SSC_DIS BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define XMIT_ENABLE GENMASK(11, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define PHY_LANES GENMASK(7, 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define PHY_RATE GENMASK(5, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define TPS_SEL GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define DPTX_PHY_TX_EQ 0x0a04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define DPTX_CUSTOMPAT0 0x0a08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define DPTX_CUSTOMPAT1 0x0a0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define DPTX_CUSTOMPAT2 0x0a10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define DPTX_HBR2_COMPLIANCE_SCRAMBLER_RESET 0x0a14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define DPTX_PHYIF_PWRDOWN_CTRL 0x0a18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define DPTX_AUX_CMD 0x0b00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define AUX_CMD_TYPE GENMASK(31, 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define AUX_ADDR GENMASK(27, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define I2C_ADDR_ONLY BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) #define AUX_LEN_REQ GENMASK(3, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define DPTX_AUX_STATUS 0x0b04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define AUX_TIMEOUT BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define AUX_BYTES_READ GENMASK(23, 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define AUX_STATUS GENMASK(7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define DPTX_AUX_DATA0 0x0b08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define DPTX_AUX_DATA1 0x0b0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define DPTX_AUX_DATA2 0x0b10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define DPTX_AUX_DATA3 0x0b14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define DPTX_GENERAL_INTERRUPT 0x0d00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define VIDEO_FIFO_OVERFLOW_STREAM0 BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define AUDIO_FIFO_OVERFLOW_STREAM0 BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define SDP_EVENT_STREAM0 BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define AUX_CMD_INVALID BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define AUX_REPLY_EVENT BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define HPD_EVENT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define DPTX_GENERAL_INTERRUPT_ENABLE 0x0d04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define AUX_REPLY_EVENT_EN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define HPD_EVENT_EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define DPTX_HPD_STATUS 0x0d08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define HPD_STATE GENMASK(11, 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define HPD_STATUS BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define HPD_HOT_UNPLUG BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define HPD_HOT_PLUG BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define HPD_IRQ BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define DPTX_HPD_INTERRUPT_ENABLE 0x0d0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define HPD_UNPLUG_ERR_EN BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define HPD_UNPLUG_EN BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define HPD_PLUG_EN BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define HPD_IRQ_EN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define DPTX_MAX_REGISTER DPTX_HPD_INTERRUPT_ENABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define SDP_REG_BANK_SIZE 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct drm_dp_link_caps {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) bool enhanced_framing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) bool tps3_supported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) bool tps4_supported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) bool fast_training;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) bool channel_coding;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) bool ssc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) struct drm_dp_link_train_set {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) unsigned int voltage_swing[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) unsigned int pre_emphasis[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) bool voltage_max_reached[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) bool pre_max_reached[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct drm_dp_link_train {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct drm_dp_link_train_set request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct drm_dp_link_train_set adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) bool clock_recovered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) bool channel_equalized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct dw_dp_link {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u8 dpcd[DP_RECEIVER_CAP_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) unsigned char revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) unsigned int lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct drm_dp_link_caps caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct drm_dp_link_train train;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct drm_dp_desc desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) u8 sink_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) u8 vsc_sdp_extension_for_colorimetry_supported;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct dw_dp_video {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct drm_display_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) u32 bus_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) u8 video_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) u8 pixel_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u8 color_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) u8 bpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) u8 bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) enum audio_format {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) AFMT_I2S = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) AFMT_SPDIF = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) AFMT_UNUSED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct dw_dp_audio {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) struct platform_device *pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) hdmi_codec_plugged_cb plugged_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct device *codec_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) enum audio_format format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) u8 channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct dw_dp_sdp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct dp_sdp_header header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) u8 db[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct dw_dp_hotplug {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) bool long_hpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) bool status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct dw_dp_compliance_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct drm_dp_phy_test_params phytest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) struct dw_dp_compliance {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) unsigned long test_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) struct dw_dp_compliance_data test_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) bool test_active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct dw_dp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct clk *apb_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) struct clk *aux_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct clk *hclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) struct clk *i2s_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) struct clk *spdif_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) struct reset_control *rstc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) struct regmap *grf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) struct completion complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) int hpd_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct work_struct hpd_work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) struct gpio_desc *hpd_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) bool force_hpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct dw_dp_hotplug hotplug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct mutex irq_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct extcon_dev *extcon;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct drm_bridge bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) struct drm_connector connector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct drm_encoder encoder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct drm_dp_aux aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct drm_bridge *next_bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct dw_dp_link link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct dw_dp_video video;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct dw_dp_audio audio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct dw_dp_compliance compliance;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) DECLARE_BITMAP(sdp_reg_bank, SDP_REG_BANK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) bool split_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct dw_dp *left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) struct dw_dp *right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct drm_property *color_depth_property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct drm_property *color_format_property;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct drm_property *color_depth_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct drm_property *color_format_capacity;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct rockchip_drm_sub_dev sub_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) struct dw_dp_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) struct drm_connector_state state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) int bpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) int color_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) DPTX_VM_RGB_6BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) DPTX_VM_RGB_8BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) DPTX_VM_RGB_10BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) DPTX_VM_RGB_12BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) DPTX_VM_RGB_16BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) DPTX_VM_YCBCR444_8BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) DPTX_VM_YCBCR444_10BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) DPTX_VM_YCBCR444_12BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) DPTX_VM_YCBCR444_16BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) DPTX_VM_YCBCR422_8BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) DPTX_VM_YCBCR422_10BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) DPTX_VM_YCBCR422_12BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) DPTX_VM_YCBCR422_16BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) DPTX_VM_YCBCR420_8BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) DPTX_VM_YCBCR420_10BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) DPTX_VM_YCBCR420_12BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) DPTX_VM_YCBCR420_16BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) DPTX_MP_SINGLE_PIXEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) DPTX_MP_DUAL_PIXEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) DPTX_MP_QUAD_PIXEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) DPTX_SDP_VERTICAL_INTERVAL = BIT(0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) DPTX_SDP_HORIZONTAL_INTERVAL = BIT(1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) SOURCE_STATE_IDLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) SOURCE_STATE_UNPLUG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) SOURCE_STATE_HPD_TIMEOUT = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) SOURCE_STATE_PLUG = 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) DPTX_PHY_PATTERN_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) DPTX_PHY_PATTERN_TPS_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) DPTX_PHY_PATTERN_TPS_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) DPTX_PHY_PATTERN_TPS_3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) DPTX_PHY_PATTERN_TPS_4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) DPTX_PHY_PATTERN_SERM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) DPTX_PHY_PATTERN_PBRS7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) DPTX_PHY_PATTERN_CUSTOM_80BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) DPTX_PHY_PATTERN_CP2520_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) DPTX_PHY_PATTERN_CP2520_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) static const unsigned int dw_dp_cable[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) EXTCON_DISP_DP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) EXTCON_NONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) struct dw_dp_output_format {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) u32 bus_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) u32 color_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) u8 video_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) u8 bpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u8 bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) static const struct dw_dp_output_format possible_output_fmts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) { MEDIA_BUS_FMT_RGB101010_1X30, DRM_COLOR_FORMAT_RGB444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) DPTX_VM_RGB_10BIT, 10, 30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) { MEDIA_BUS_FMT_RGB888_1X24, DRM_COLOR_FORMAT_RGB444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) DPTX_VM_RGB_8BIT, 8, 24 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) { MEDIA_BUS_FMT_YUV10_1X30, DRM_COLOR_FORMAT_YCRCB444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) DPTX_VM_YCBCR444_10BIT, 10, 30 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) { MEDIA_BUS_FMT_YUV8_1X24, DRM_COLOR_FORMAT_YCRCB444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) DPTX_VM_YCBCR444_8BIT, 8, 24},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) { MEDIA_BUS_FMT_YUYV10_1X20, DRM_COLOR_FORMAT_YCRCB422,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) DPTX_VM_YCBCR422_10BIT, 10, 20 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) { MEDIA_BUS_FMT_YUYV8_1X16, DRM_COLOR_FORMAT_YCRCB422,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) DPTX_VM_YCBCR422_8BIT, 8, 16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) { MEDIA_BUS_FMT_UYYVYY10_0_5X30, DRM_COLOR_FORMAT_YCRCB420,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) DPTX_VM_YCBCR420_10BIT, 10, 15 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) { MEDIA_BUS_FMT_UYYVYY8_0_5X24, DRM_COLOR_FORMAT_YCRCB420,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) DPTX_VM_YCBCR420_8BIT, 8, 12 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) { MEDIA_BUS_FMT_RGB666_1X24_CPADHI, DRM_COLOR_FORMAT_RGB444,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) DPTX_VM_RGB_6BIT, 6, 18 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static const struct drm_prop_enum_list color_depth_enum_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) { 0, "Automatic" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) { 6, "18bit" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) { 8, "24bit" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) { 10, "30bit" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static const struct drm_prop_enum_list color_format_enum_list[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) { RK_IF_FORMAT_RGB, "rgb" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) { RK_IF_FORMAT_YCBCR444, "ycbcr444" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) { RK_IF_FORMAT_YCBCR422, "ycbcr422" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) { RK_IF_FORMAT_YCBCR420, "ycbcr420" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) static const struct dw_dp_output_format *dw_dp_get_output_format(u32 bus_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) for (i = 0; i < ARRAY_SIZE(possible_output_fmts); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (possible_output_fmts[i].bus_format == bus_format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return &possible_output_fmts[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return &possible_output_fmts[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) static inline struct dw_dp *connector_to_dp(struct drm_connector *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return container_of(c, struct dw_dp, connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static inline struct dw_dp *encoder_to_dp(struct drm_encoder *e)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) return container_of(e, struct dw_dp, encoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static inline struct dw_dp *bridge_to_dp(struct drm_bridge *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return container_of(b, struct dw_dp, bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static inline struct dw_dp_state *connector_to_dp_state(struct drm_connector_state *cstate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return container_of(cstate, struct dw_dp_state, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) static int dw_dp_match_by_id(struct device *dev, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct dw_dp *dp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) const unsigned int *id = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) return dp->id == *id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static struct dw_dp *dw_dp_find_by_id(struct device_driver *drv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dev = driver_find_device(drv, NULL, &id, dw_dp_match_by_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static void dw_dp_phy_set_pattern(struct dw_dp *dp, u32 pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) regmap_update_bits(dp->regmap, DPTX_PHYIF_CTRL, TPS_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) FIELD_PREP(TPS_SEL, pattern));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) static void dw_dp_phy_xmit_enable(struct dw_dp *dp, u32 lanes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) u32 xmit_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) switch (lanes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) xmit_enable = GENMASK(lanes - 1, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) xmit_enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) regmap_update_bits(dp->regmap, DPTX_PHYIF_CTRL, XMIT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) FIELD_PREP(XMIT_ENABLE, xmit_enable));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) static bool dw_dp_bandwidth_ok(struct dw_dp *dp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) const struct drm_display_mode *mode, u32 bpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) unsigned int lanes, unsigned int rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) u32 max_bw, req_bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) req_bw = mode->clock * bpp / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) max_bw = lanes * rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (req_bw > max_bw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static bool dw_dp_detect(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (dp->hpd_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) return gpiod_get_value_cansleep(dp->hpd_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) regmap_read(dp->regmap, DPTX_HPD_STATUS, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return FIELD_GET(HPD_STATE, value) == SOURCE_STATE_PLUG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static enum drm_connector_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) dw_dp_connector_detect(struct drm_connector *connector, bool force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct dw_dp *dp = connector_to_dp(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (dp->right && drm_bridge_detect(&dp->right->bridge) != connector_status_connected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return connector_status_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return drm_bridge_detect(&dp->bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static void dw_dp_audio_handle_plugged_change(struct dw_dp_audio *audio, bool plugged)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (audio->plugged_cb && audio->codec_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) audio->plugged_cb(audio->codec_dev, plugged);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) static void dw_dp_connector_force(struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct dw_dp *dp = connector_to_dp(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (connector->status == connector_status_connected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) dw_dp_audio_handle_plugged_change(&dp->audio, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) dw_dp_audio_handle_plugged_change(&dp->audio, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) static void dw_dp_atomic_connector_reset(struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) struct dw_dp_state *dp_state = connector_to_dp_state(connector->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (connector->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) __drm_atomic_helper_connector_destroy_state(connector->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) kfree(dp_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) dp_state = kzalloc(sizeof(*dp_state), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (!dp_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) __drm_atomic_helper_connector_reset(connector, &dp_state->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) dp_state->bpc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) dp_state->color_format = RK_IF_FORMAT_RGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static struct drm_connector_state *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) dw_dp_atomic_connector_duplicate_state(struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct dw_dp_state *cstate, *old_cstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) if (WARN_ON(!connector->state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) old_cstate = connector_to_dp_state(connector->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) cstate = kmalloc(sizeof(*cstate), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (!cstate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) __drm_atomic_helper_connector_duplicate_state(connector, &cstate->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) cstate->bpc = old_cstate->bpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) cstate->color_format = old_cstate->color_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return &cstate->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static void dw_dp_atomic_connector_destroy_state(struct drm_connector *connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) struct drm_connector_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) struct dw_dp_state *cstate = connector_to_dp_state(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) __drm_atomic_helper_connector_destroy_state(&cstate->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) kfree(cstate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static int dw_dp_atomic_connector_get_property(struct drm_connector *connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) const struct drm_connector_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) struct drm_property *property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) uint64_t *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) struct dw_dp *dp = connector_to_dp(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) struct dw_dp_state *dp_state = connector_to_dp_state((struct drm_connector_state *)state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) struct drm_display_info *info = &connector->display_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) if (property == dp->color_depth_property) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) *val = dp_state->bpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) } else if (property == dp->color_format_property) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) *val = dp_state->color_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) } else if (property == dp->color_depth_capacity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) *val = BIT(RK_IF_DEPTH_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) switch (info->bpc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) *val |= BIT(RK_IF_DEPTH_10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) *val |= BIT(RK_IF_DEPTH_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) *val |= BIT(RK_IF_DEPTH_6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) } else if (property == dp->color_format_capacity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) *val = info->color_formats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dev_err(dp->dev, "Unknown property [PROP:%d:%s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) property->base.id, property->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static int dw_dp_atomic_connector_set_property(struct drm_connector *connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct drm_connector_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct drm_property *property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) struct dw_dp *dp = connector_to_dp(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) struct dw_dp_state *dp_state = connector_to_dp_state(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (property == dp->color_depth_property) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dp_state->bpc = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) } else if (property == dp->color_format_property) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) dp_state->color_format = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) } else if (property == dp->color_depth_capacity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) } else if (property == dp->color_format_capacity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) dev_err(dp->dev, "Unknown property [PROP:%d:%s]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) property->base.id, property->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static const struct drm_connector_funcs dw_dp_connector_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) .detect = dw_dp_connector_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) .fill_modes = drm_helper_probe_single_connector_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) .destroy = drm_connector_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) .force = dw_dp_connector_force,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) .reset = dw_dp_atomic_connector_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) .atomic_duplicate_state = dw_dp_atomic_connector_duplicate_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) .atomic_destroy_state = dw_dp_atomic_connector_destroy_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) .atomic_get_property = dw_dp_atomic_connector_get_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) .atomic_set_property = dw_dp_atomic_connector_set_property,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int dw_dp_connector_get_modes(struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) struct dw_dp *dp = connector_to_dp(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct drm_display_info *di = &connector->display_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) struct edid *edid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) int num_modes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (dp->right && dp->right->next_bridge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct drm_bridge *bridge = dp->right->next_bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (bridge->ops & DRM_BRIDGE_OP_MODES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (!drm_bridge_get_modes(bridge, connector))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) if (dp->next_bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) num_modes = drm_bridge_get_modes(dp->next_bridge, connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (!num_modes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) edid = drm_bridge_get_edid(&dp->bridge, connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (edid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) drm_connector_update_edid_property(connector, edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) num_modes = drm_add_edid_modes(connector, edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) kfree(edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) if (!di->color_formats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) di->color_formats = DRM_COLOR_FORMAT_RGB444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!di->bpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) di->bpc = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (num_modes > 0 && dp->split_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct drm_display_mode *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) di->width_mm *= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) list_for_each_entry(mode, &connector->probed_modes, head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) drm_mode_convert_to_split_mode(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return num_modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static int dw_dp_connector_atomic_check(struct drm_connector *conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) struct drm_atomic_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct drm_connector_state *old_state, *new_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct dw_dp_state *dp_old_state, *dp_new_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) struct drm_crtc_state *crtc_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct dw_dp *dp = connector_to_dp(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) old_state = drm_atomic_get_old_connector_state(state, conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) new_state = drm_atomic_get_new_connector_state(state, conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) dp_old_state = connector_to_dp_state(old_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) dp_new_state = connector_to_dp_state(new_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (!new_state->crtc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if ((dp_new_state->bpc != 0) && (dp_new_state->bpc != 6) && (dp_new_state->bpc != 8) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) (dp_new_state->bpc != 10)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) dev_err(dp->dev, "set invalid bpc:%d\n", dp_new_state->bpc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) if ((dp_new_state->color_format < RK_IF_FORMAT_RGB) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) (dp_new_state->color_format > RK_IF_FORMAT_YCBCR420)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) dev_err(dp->dev, "set invalid color format:%d\n", dp_new_state->color_format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if ((dp_old_state->bpc != dp_new_state->bpc) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) (dp_old_state->color_format != dp_new_state->color_format)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if ((dp_old_state->bpc == 0) && (dp_new_state->bpc == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) dev_info(dp->dev, "still auto set color mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) crtc_state->mode_changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static const struct drm_connector_helper_funcs dw_dp_connector_helper_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .get_modes = dw_dp_connector_get_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .atomic_check = dw_dp_connector_atomic_check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) static void dw_dp_link_caps_reset(struct drm_dp_link_caps *caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) caps->enhanced_framing = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) caps->tps3_supported = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) caps->tps4_supported = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) caps->fast_training = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) caps->channel_coding = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static void dw_dp_link_reset(struct dw_dp_link *link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) link->vsc_sdp_extension_for_colorimetry_supported = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) link->sink_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) link->revision = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) dw_dp_link_caps_reset(&link->caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) memset(link->dpcd, 0, sizeof(link->dpcd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) link->rate = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) link->lanes = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) static int dw_dp_link_power_up(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (link->revision < 0x11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) value &= ~DP_SET_POWER_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) value |= DP_SET_POWER_D0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) usleep_range(1000, 2000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static int dw_dp_link_power_down(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) u8 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (link->revision < 0x11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) ret = drm_dp_dpcd_readb(&dp->aux, DP_SET_POWER, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) value &= ~DP_SET_POWER_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) value |= DP_SET_POWER_D3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ret = drm_dp_dpcd_writeb(&dp->aux, DP_SET_POWER, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) static bool dw_dp_has_sink_count(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) const struct drm_dp_desc *desc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return dpcd[DP_DPCD_REV] >= DP_DPCD_REV_11 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) dpcd[DP_DOWNSTREAMPORT_PRESENT] & DP_DWN_STRM_PORT_PRESENT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) !drm_dp_has_quirk(desc, 0, DP_DPCD_QUIRK_NO_SINK_COUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static int dw_dp_link_probe(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) u8 dpcd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) dw_dp_link_reset(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) ret = drm_dp_read_dpcd_caps(&dp->aux, link->dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) drm_dp_read_desc(&dp->aux, &link->desc, drm_dp_is_branch(link->dpcd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) if (dw_dp_has_sink_count(link->dpcd, &link->desc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) ret = drm_dp_read_sink_count(&dp->aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) link->sink_count = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /* Dongle connected, but no display */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (!link->sink_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) ret = drm_dp_dpcd_readb(&dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) &dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) link->vsc_sdp_extension_for_colorimetry_supported =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) !!(dpcd & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) link->revision = link->dpcd[DP_DPCD_REV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) link->rate = min_t(u32, dp->phy->attrs.max_link_rate * 100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) drm_dp_max_link_rate(link->dpcd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) link->lanes = min_t(u8, phy_get_bus_width(dp->phy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) drm_dp_max_lane_count(link->dpcd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) link->caps.enhanced_framing = drm_dp_enhanced_frame_cap(link->dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) link->caps.tps3_supported = drm_dp_tps3_supported(link->dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) link->caps.tps4_supported = drm_dp_tps4_supported(link->dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) link->caps.fast_training = drm_dp_fast_training_cap(link->dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) link->caps.channel_coding = drm_dp_channel_coding_supported(link->dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) link->caps.ssc = !!(link->dpcd[DP_MAX_DOWNSPREAD] & DP_MAX_DOWNSPREAD_0_5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static int dw_dp_phy_update_vs_emph(struct dw_dp *dp, unsigned int rate, unsigned int lanes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct drm_dp_link_train_set *train_set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) union phy_configure_opts phy_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) unsigned int *vs, *pe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) u8 buf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) vs = train_set->voltage_swing;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) pe = train_set->pre_emphasis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) for (i = 0; i < lanes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) phy_cfg.dp.voltage[i] = vs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) phy_cfg.dp.pre[i] = pe[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) phy_cfg.dp.lanes = lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) phy_cfg.dp.link_rate = rate / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) phy_cfg.dp.set_lanes = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) phy_cfg.dp.set_rate = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) phy_cfg.dp.set_voltages = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) ret = phy_configure(dp->phy, &phy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) for (i = 0; i < lanes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) buf[i] = (vs[i] << DP_TRAIN_VOLTAGE_SWING_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) (pe[i] << DP_TRAIN_PRE_EMPHASIS_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (train_set->voltage_max_reached[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) buf[i] |= DP_TRAIN_MAX_SWING_REACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (train_set->pre_max_reached[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) buf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) ret = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, buf, lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static int dw_dp_link_train_update_vs_emph(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct drm_dp_link_train_set *request = &link->train.request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return dw_dp_phy_update_vs_emph(dp, dp->link.rate, dp->link.lanes, request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) static int dw_dp_phy_configure(struct dw_dp *dp, unsigned int rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) unsigned int lanes, bool ssc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) union phy_configure_opts phy_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) /* Move PHY to P3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) regmap_update_bits(dp->regmap, DPTX_PHYIF_CTRL, PHY_POWERDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) FIELD_PREP(PHY_POWERDOWN, 0x3));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) phy_cfg.dp.lanes = lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) phy_cfg.dp.link_rate = rate / 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) phy_cfg.dp.ssc = ssc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) phy_cfg.dp.set_lanes = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) phy_cfg.dp.set_rate = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) phy_cfg.dp.set_voltages = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ret = phy_configure(dp->phy, &phy_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) regmap_update_bits(dp->regmap, DPTX_PHYIF_CTRL, PHY_LANES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) FIELD_PREP(PHY_LANES, lanes / 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) /* Move PHY to P0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) regmap_update_bits(dp->regmap, DPTX_PHYIF_CTRL, PHY_POWERDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) FIELD_PREP(PHY_POWERDOWN, 0x0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) dw_dp_phy_xmit_enable(dp, lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static int dw_dp_link_configure(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) u8 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) ret = dw_dp_phy_configure(dp, link->rate, link->lanes, link->caps.ssc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) buf[0] = drm_dp_link_rate_to_bw_code(link->rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) buf[1] = link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (link->caps.enhanced_framing) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) buf[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) regmap_update_bits(dp->regmap, DPTX_CCTL, ENHANCE_FRAMING_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) FIELD_PREP(ENHANCE_FRAMING_EN, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) regmap_update_bits(dp->regmap, DPTX_CCTL, ENHANCE_FRAMING_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) FIELD_PREP(ENHANCE_FRAMING_EN, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ret = drm_dp_dpcd_write(&dp->aux, DP_LINK_BW_SET, buf, sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) buf[0] = link->caps.ssc ? DP_SPREAD_AMP_0_5 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) buf[1] = link->caps.channel_coding ? DP_SET_ANSI_8B10B : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ret = drm_dp_dpcd_write(&dp->aux, DP_DOWNSPREAD_CTRL, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) sizeof(buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static void dw_dp_link_train_init(struct drm_dp_link_train *train)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct drm_dp_link_train_set *request = &train->request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) struct drm_dp_link_train_set *adjust = &train->adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) request->voltage_swing[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) adjust->voltage_swing[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) request->pre_emphasis[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) adjust->pre_emphasis[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) request->voltage_max_reached[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) adjust->voltage_max_reached[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) request->pre_max_reached[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) adjust->pre_max_reached[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) train->clock_recovered = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) train->channel_equalized = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) static bool dw_dp_link_train_valid(const struct drm_dp_link_train *train)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return train->clock_recovered && train->channel_equalized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static int dw_dp_link_train_set_pattern(struct dw_dp *dp, u32 pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) u8 buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) if (pattern && pattern != DP_TRAINING_PATTERN_4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) buf |= DP_LINK_SCRAMBLING_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) FIELD_PREP(SCRAMBLE_DIS, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) FIELD_PREP(SCRAMBLE_DIS, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) switch (pattern) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) case DP_TRAINING_PATTERN_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) case DP_TRAINING_PATTERN_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) case DP_TRAINING_PATTERN_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) case DP_TRAINING_PATTERN_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) case DP_TRAINING_PATTERN_4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) buf | pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static u8 dw_dp_voltage_max(u8 preemph)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) switch (preemph & DP_TRAIN_PRE_EMPHASIS_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) case DP_TRAIN_PRE_EMPH_LEVEL_0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return DP_TRAIN_VOLTAGE_SWING_LEVEL_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) case DP_TRAIN_PRE_EMPH_LEVEL_1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return DP_TRAIN_VOLTAGE_SWING_LEVEL_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) case DP_TRAIN_PRE_EMPH_LEVEL_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) return DP_TRAIN_VOLTAGE_SWING_LEVEL_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) case DP_TRAIN_PRE_EMPH_LEVEL_3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) return DP_TRAIN_VOLTAGE_SWING_LEVEL_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) static void dw_dp_link_get_adjustments(struct dw_dp_link *link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) u8 status[DP_LINK_STATUS_SIZE])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct drm_dp_link_train_set *adjust = &link->train.adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) u8 v = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) u8 p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) for (i = 0; i < link->lanes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) v = drm_dp_get_adjust_request_voltage(status, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) p = drm_dp_get_adjust_request_pre_emphasis(status, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (p >= DP_TRAIN_PRE_EMPH_LEVEL_3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) adjust->pre_emphasis[i] = DP_TRAIN_PRE_EMPH_LEVEL_3 >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) DP_TRAIN_PRE_EMPHASIS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) adjust->pre_max_reached[i] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) adjust->pre_emphasis[i] = p >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) adjust->pre_max_reached[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) v = min(v, dw_dp_voltage_max(p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) if (v >= DP_TRAIN_VOLTAGE_SWING_LEVEL_3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) adjust->voltage_swing[i] = DP_TRAIN_VOLTAGE_SWING_LEVEL_3 >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) DP_TRAIN_VOLTAGE_SWING_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) adjust->voltage_max_reached[i] = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) adjust->voltage_swing[i] = v >> DP_TRAIN_VOLTAGE_SWING_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) adjust->voltage_max_reached[i] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) static void dw_dp_link_train_adjust(struct drm_dp_link_train *train)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) struct drm_dp_link_train_set *request = &train->request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct drm_dp_link_train_set *adjust = &train->adjust;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (request->voltage_swing[i] != adjust->voltage_swing[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) request->voltage_swing[i] = adjust->voltage_swing[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) if (request->voltage_max_reached[i] != adjust->voltage_max_reached[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) request->voltage_max_reached[i] = adjust->voltage_max_reached[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) for (i = 0; i < 4; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) if (request->pre_emphasis[i] != adjust->pre_emphasis[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) request->pre_emphasis[i] = adjust->pre_emphasis[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) if (request->pre_max_reached[i] != adjust->pre_max_reached[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) request->pre_max_reached[i] = adjust->pre_max_reached[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) static int dw_dp_link_clock_recovery(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) u8 status[DP_LINK_STATUS_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) unsigned int tries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) ret = dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) ret = dw_dp_link_train_update_vs_emph(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) drm_dp_link_train_clock_recovery_delay(link->dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) ret = drm_dp_dpcd_read_link_status(&dp->aux, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) dev_err(dp->dev, "failed to read link status: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (drm_dp_clock_recovery_ok(status, link->lanes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) link->train.clock_recovered = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) dw_dp_link_get_adjustments(link, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (link->train.request.voltage_swing[0] ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) link->train.adjust.voltage_swing[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) tries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) tries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (tries == 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) dw_dp_link_train_adjust(&link->train);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) static int dw_dp_link_channel_equalization(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) u8 status[DP_LINK_STATUS_SIZE], pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) unsigned int tries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) if (link->caps.tps4_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) pattern = DP_TRAINING_PATTERN_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) else if (link->caps.tps3_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) pattern = DP_TRAINING_PATTERN_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) pattern = DP_TRAINING_PATTERN_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) ret = dw_dp_link_train_set_pattern(dp, pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) for (tries = 1; tries < 5; tries++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) ret = dw_dp_link_train_update_vs_emph(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) drm_dp_link_train_channel_eq_delay(link->dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) ret = drm_dp_dpcd_read_link_status(&dp->aux, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (!drm_dp_clock_recovery_ok(status, link->lanes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) dev_err(dp->dev, "clock recovery lost while equalizing channel\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) link->train.clock_recovered = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (drm_dp_channel_eq_ok(status, link->lanes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) link->train.channel_equalized = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) dw_dp_link_get_adjustments(link, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) dw_dp_link_train_adjust(&link->train);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static int dw_dp_link_downgrade(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct dw_dp_video *video = &dp->video;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) switch (link->rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) case 162000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) case 270000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) link->rate = 162000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) case 540000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) link->rate = 270000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) case 810000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) link->rate = 540000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (!dw_dp_bandwidth_ok(dp, &video->mode, video->bpp, link->lanes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) link->rate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static int dw_dp_link_train_full(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) dw_dp_link_train_init(&link->train);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) dev_info(dp->dev, "full-training link: %u lane%s at %u MHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) link->lanes, (link->lanes > 1) ? "s" : "", link->rate / 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) ret = dw_dp_link_configure(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) dev_err(dp->dev, "failed to configure DP link: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) ret = dw_dp_link_clock_recovery(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) dev_err(dp->dev, "clock recovery failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (!link->train.clock_recovered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) dev_err(dp->dev, "clock recovery failed, downgrading link\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) ret = dw_dp_link_downgrade(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) dev_info(dp->dev, "clock recovery succeeded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) ret = dw_dp_link_channel_equalization(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) dev_err(dp->dev, "channel equalization failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if (!link->train.channel_equalized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) dev_err(dp->dev, "channel equalization failed, downgrading link\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) ret = dw_dp_link_downgrade(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) dev_info(dp->dev, "channel equalization succeeded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) static int dw_dp_link_train_fast(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) u8 status[DP_LINK_STATUS_SIZE], pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) dw_dp_link_train_init(&link->train);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) dev_info(dp->dev, "fast-training link: %u lane%s at %u MHz\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) link->lanes, (link->lanes > 1) ? "s" : "", link->rate / 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) ret = dw_dp_link_configure(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) dev_err(dp->dev, "failed to configure DP link: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) ret = dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) usleep_range(500, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) if (link->caps.tps4_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) pattern = DP_TRAINING_PATTERN_4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) else if (link->caps.tps3_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) pattern = DP_TRAINING_PATTERN_3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) pattern = DP_TRAINING_PATTERN_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) ret = dw_dp_link_train_set_pattern(dp, pattern);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) usleep_range(500, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) ret = drm_dp_dpcd_read_link_status(&dp->aux, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) dev_err(dp->dev, "failed to read link status: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (!drm_dp_clock_recovery_ok(status, link->lanes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) dev_err(dp->dev, "clock recovery failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) if (!drm_dp_channel_eq_ok(status, link->lanes)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) dev_err(dp->dev, "channel equalization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) dw_dp_link_train_set_pattern(dp, DP_TRAINING_PATTERN_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) static int dw_dp_link_train(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) if (link->caps.fast_training) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (dw_dp_link_train_valid(&link->train)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) ret = dw_dp_link_train_fast(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) dev_err(dp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) "fast link training failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) ret = dw_dp_link_train_full(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) dev_err(dp->dev, "full link training failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static int dw_dp_send_sdp(struct dw_dp *dp, struct dw_dp_sdp *sdp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) const u8 *payload = sdp->db;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) int i, nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) nr = find_first_zero_bit(dp->sdp_reg_bank, SDP_REG_BANK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) if (nr < SDP_REG_BANK_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) set_bit(nr, dp->sdp_reg_bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) reg = DPTX_SDP_REGISTER_BANK + nr * 9 * 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) /* SDP header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) regmap_write(dp->regmap, reg, get_unaligned_le32(&sdp->header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) /* SDP data payload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) for (i = 1; i < 9; i++, payload += 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) regmap_write(dp->regmap, reg + i * 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) FIELD_PREP(SDP_REGS, get_unaligned_le32(payload)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) if (sdp->flags & DPTX_SDP_VERTICAL_INTERVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) regmap_update_bits(dp->regmap, DPTX_SDP_VERTICAL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) EN_VERTICAL_SDP << nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) EN_VERTICAL_SDP << nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) if (sdp->flags & DPTX_SDP_HORIZONTAL_INTERVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) regmap_update_bits(dp->regmap, DPTX_SDP_HORIZONTAL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) EN_HORIZONTAL_SDP << nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) EN_HORIZONTAL_SDP << nr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) static void dw_dp_vsc_sdp_pack(const struct drm_dp_vsc_sdp *vsc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) struct dw_dp_sdp *sdp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) sdp->header.HB0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) sdp->header.HB1 = DP_SDP_VSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) sdp->header.HB2 = vsc->revision;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) sdp->header.HB3 = vsc->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) sdp->db[16] = (vsc->pixelformat & 0xf) << 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) sdp->db[16] |= vsc->colorimetry & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) switch (vsc->bpc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) sdp->db[17] = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) sdp->db[17] = 0x2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) sdp->db[17] = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) sdp->db[17] = 0x4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) if (vsc->dynamic_range == DP_DYNAMIC_RANGE_CTA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) sdp->db[17] |= 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) sdp->db[18] = vsc->content_type & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) sdp->flags |= DPTX_SDP_VERTICAL_INTERVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) static int dw_dp_send_vsc_sdp(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) struct dw_dp_video *video = &dp->video;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) struct drm_dp_vsc_sdp vsc = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) struct dw_dp_sdp sdp = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) vsc.revision = 0x5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) vsc.length = 0x13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) switch (video->color_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) case DRM_COLOR_FORMAT_YCRCB444:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) vsc.pixelformat = DP_PIXELFORMAT_YUV444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) case DRM_COLOR_FORMAT_YCRCB420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) vsc.pixelformat = DP_PIXELFORMAT_YUV420;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) case DRM_COLOR_FORMAT_YCRCB422:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) vsc.pixelformat = DP_PIXELFORMAT_YUV422;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) case DRM_COLOR_FORMAT_RGB444:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) vsc.pixelformat = DP_PIXELFORMAT_RGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) if (video->color_format == DRM_COLOR_FORMAT_RGB444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) vsc.colorimetry = DP_COLORIMETRY_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) vsc.dynamic_range = DP_DYNAMIC_RANGE_VESA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) vsc.colorimetry = DP_COLORIMETRY_BT709_YCC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) vsc.dynamic_range = DP_DYNAMIC_RANGE_CTA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) vsc.bpc = video->bpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) vsc.content_type = DP_CONTENT_TYPE_NOT_DEFINED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) dw_dp_vsc_sdp_pack(&vsc, &sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) return dw_dp_send_sdp(dp, &sdp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) static int dw_dp_video_set_pixel_mode(struct dw_dp *dp, u8 pixel_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) switch (pixel_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) case DPTX_MP_SINGLE_PIXEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) case DPTX_MP_DUAL_PIXEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) case DPTX_MP_QUAD_PIXEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) regmap_update_bits(dp->regmap, DPTX_VSAMPLE_CTRL, PIXEL_MODE_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) FIELD_PREP(PIXEL_MODE_SELECT, pixel_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) static int dw_dp_video_set_msa(struct dw_dp *dp, u8 color_format, u8 bpc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) u16 vstart, u16 hstart)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) u16 misc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) if (link->vsc_sdp_extension_for_colorimetry_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) misc |= DP_MSA_MISC_COLOR_VSC_SDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) switch (color_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) case DRM_COLOR_FORMAT_RGB444:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) misc |= DP_MSA_MISC_COLOR_RGB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) case DRM_COLOR_FORMAT_YCRCB444:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) misc |= DP_MSA_MISC_COLOR_YCBCR_444_BT709;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) case DRM_COLOR_FORMAT_YCRCB422:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) misc |= DP_MSA_MISC_COLOR_YCBCR_422_BT709;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) case DRM_COLOR_FORMAT_YCRCB420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) switch (bpc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) misc |= DP_MSA_MISC_6_BPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) misc |= DP_MSA_MISC_8_BPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) misc |= DP_MSA_MISC_10_BPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) misc |= DP_MSA_MISC_12_BPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) misc |= DP_MSA_MISC_16_BPC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) regmap_write(dp->regmap, DPTX_VIDEO_MSA1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) FIELD_PREP(VSTART, vstart) | FIELD_PREP(HSTART, hstart));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) regmap_write(dp->regmap, DPTX_VIDEO_MSA2, FIELD_PREP(MISC0, misc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) regmap_write(dp->regmap, DPTX_VIDEO_MSA3, FIELD_PREP(MISC1, misc >> 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) static void dw_dp_video_disable(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) regmap_update_bits(dp->regmap, DPTX_VSAMPLE_CTRL, VIDEO_STREAM_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) FIELD_PREP(VIDEO_STREAM_ENABLE, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static int dw_dp_video_enable(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) struct dw_dp_video *video = &dp->video;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) struct drm_display_mode *mode = &video->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) u8 color_format = video->color_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) u8 bpc = video->bpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) u8 pixel_mode = video->pixel_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) u8 bpp = video->bpp, init_threshold, vic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) u32 hactive, hblank, h_sync_width, h_front_porch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) u32 vactive, vblank, v_sync_width, v_front_porch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) u32 vstart = mode->vtotal - mode->vsync_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) u32 hstart = mode->htotal - mode->hsync_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) u32 peak_stream_bandwidth, link_bandwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) u32 average_bytes_per_tu, average_bytes_per_tu_frac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) u32 ts, hblank_interval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) ret = dw_dp_video_set_pixel_mode(dp, pixel_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) ret = dw_dp_video_set_msa(dp, color_format, bpc, vstart, hstart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) regmap_update_bits(dp->regmap, DPTX_VSAMPLE_CTRL, VIDEO_MAPPING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) FIELD_PREP(VIDEO_MAPPING, video->video_mapping));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) /* Configure DPTX_VINPUT_POLARITY_CTRL register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) if (mode->flags & DRM_MODE_FLAG_PHSYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) value |= FIELD_PREP(HSYNC_IN_POLARITY, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (mode->flags & DRM_MODE_FLAG_PVSYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) value |= FIELD_PREP(VSYNC_IN_POLARITY, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) regmap_write(dp->regmap, DPTX_VINPUT_POLARITY_CTRL, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /* Configure DPTX_VIDEO_CONFIG1 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) hactive = mode->hdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) hblank = mode->htotal - mode->hdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) value = FIELD_PREP(HACTIVE, hactive) | FIELD_PREP(HBLANK, hblank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (mode->flags & DRM_MODE_FLAG_INTERLACE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) value |= FIELD_PREP(I_P, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) vic = drm_match_cea_mode(mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (vic == 5 || vic == 6 || vic == 7 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) vic == 10 || vic == 11 || vic == 20 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) vic == 21 || vic == 22 || vic == 39 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) vic == 25 || vic == 26 || vic == 40 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) vic == 44 || vic == 45 || vic == 46 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) vic == 50 || vic == 51 || vic == 54 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) vic == 55 || vic == 58 || vic == 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) value |= R_V_BLANK_IN_OSC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) regmap_write(dp->regmap, DPTX_VIDEO_CONFIG1, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) /* Configure DPTX_VIDEO_CONFIG2 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) vblank = mode->vtotal - mode->vdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) vactive = mode->vdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) regmap_write(dp->regmap, DPTX_VIDEO_CONFIG2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) FIELD_PREP(VBLANK, vblank) | FIELD_PREP(VACTIVE, vactive));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) /* Configure DPTX_VIDEO_CONFIG3 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) h_sync_width = mode->hsync_end - mode->hsync_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) h_front_porch = mode->hsync_start - mode->hdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) regmap_write(dp->regmap, DPTX_VIDEO_CONFIG3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) FIELD_PREP(H_SYNC_WIDTH, h_sync_width) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) FIELD_PREP(H_FRONT_PORCH, h_front_porch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) /* Configure DPTX_VIDEO_CONFIG4 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) v_sync_width = mode->vsync_end - mode->vsync_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) v_front_porch = mode->vsync_start - mode->vdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) regmap_write(dp->regmap, DPTX_VIDEO_CONFIG4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) FIELD_PREP(V_SYNC_WIDTH, v_sync_width) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) FIELD_PREP(V_FRONT_PORCH, v_front_porch));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) /* Configure DPTX_VIDEO_CONFIG5 register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) peak_stream_bandwidth = mode->clock * bpp / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) link_bandwidth = (link->rate / 1000) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) ts = peak_stream_bandwidth * 64 / link_bandwidth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) average_bytes_per_tu = ts / 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) average_bytes_per_tu_frac = ts / 100 - average_bytes_per_tu * 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (pixel_mode == DPTX_MP_SINGLE_PIXEL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) if (average_bytes_per_tu < 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) init_threshold = 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) else if (hblank <= 80 && color_format != DRM_COLOR_FORMAT_YCRCB420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) init_threshold = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) else if (hblank <= 40 && color_format == DRM_COLOR_FORMAT_YCRCB420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) init_threshold = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) init_threshold = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) u32 t1 = 0, t2 = 0, t3 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) switch (bpc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) case 6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) t1 = (4 * 1000 / 9) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) if (color_format == DRM_COLOR_FORMAT_YCRCB422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) t1 = (1000 / 2) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) if (pixel_mode == DPTX_MP_DUAL_PIXEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) t1 = (1000 / 3) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) t1 = (3000 / 16) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) case 10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) if (color_format == DRM_COLOR_FORMAT_YCRCB422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) t1 = (2000 / 5) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) t1 = (4000 / 15) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) case 12:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) if (color_format == DRM_COLOR_FORMAT_YCRCB422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) if (pixel_mode == DPTX_MP_DUAL_PIXEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) t1 = (1000 / 6) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) t1 = (1000 / 3) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) t1 = (2000 / 9) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) case 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if (color_format != DRM_COLOR_FORMAT_YCRCB422 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) pixel_mode == DPTX_MP_DUAL_PIXEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) t1 = (1000 / 6) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) t1 = (1000 / 4) * link->lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (color_format == DRM_COLOR_FORMAT_YCRCB420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) t2 = (link->rate / 4) * 1000 / (mode->clock / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) t2 = (link->rate / 4) * 1000 / mode->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) if (average_bytes_per_tu_frac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) t3 = average_bytes_per_tu + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) t3 = average_bytes_per_tu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) init_threshold = t1 * t2 * t3 / (1000 * 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) if (init_threshold <= 16 || average_bytes_per_tu < 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) init_threshold = 40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) regmap_write(dp->regmap, DPTX_VIDEO_CONFIG5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) FIELD_PREP(INIT_THRESHOLD_HI, init_threshold >> 6) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) FIELD_PREP(AVERAGE_BYTES_PER_TU_FRAC, average_bytes_per_tu_frac) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) FIELD_PREP(INIT_THRESHOLD, init_threshold) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) FIELD_PREP(AVERAGE_BYTES_PER_TU, average_bytes_per_tu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) /* Configure DPTX_VIDEO_HBLANK_INTERVAL register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) hblank_interval = hblank * (link->rate / 4) / mode->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) regmap_write(dp->regmap, DPTX_VIDEO_HBLANK_INTERVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) FIELD_PREP(HBLANK_INTERVAL_EN, 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) FIELD_PREP(HBLANK_INTERVAL, hblank_interval));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) /* Video stream enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) regmap_update_bits(dp->regmap, DPTX_VSAMPLE_CTRL, VIDEO_STREAM_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) FIELD_PREP(VIDEO_STREAM_ENABLE, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (link->vsc_sdp_extension_for_colorimetry_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) dw_dp_send_vsc_sdp(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) static irqreturn_t dw_dp_hpd_irq_handler(int irq, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) struct dw_dp *dp = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) bool hpd = dw_dp_detect(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) mutex_lock(&dp->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) dp->hotplug.long_hpd = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) if (dp->hotplug.status && !hpd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) usleep_range(2000, 2001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) hpd = dw_dp_detect(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) if (hpd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) dp->hotplug.long_hpd = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) dp->hotplug.status = hpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) mutex_unlock(&dp->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) schedule_work(&dp->hpd_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) static void dw_dp_hpd_init(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) dp->hotplug.status = dw_dp_detect(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) if (dp->hpd_gpio || dp->force_hpd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) regmap_update_bits(dp->regmap, DPTX_CCTL, FORCE_HPD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) FIELD_PREP(FORCE_HPD, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) /* Enable all HPD interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) regmap_update_bits(dp->regmap, DPTX_HPD_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) HPD_UNPLUG_EN | HPD_PLUG_EN | HPD_IRQ_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) FIELD_PREP(HPD_UNPLUG_EN, 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) FIELD_PREP(HPD_PLUG_EN, 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) FIELD_PREP(HPD_IRQ_EN, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) /* Enable all top-level interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) regmap_update_bits(dp->regmap, DPTX_GENERAL_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) HPD_EVENT_EN, FIELD_PREP(HPD_EVENT_EN, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) static void dw_dp_aux_init(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) regmap_update_bits(dp->regmap, DPTX_GENERAL_INTERRUPT_ENABLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) AUX_REPLY_EVENT_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) FIELD_PREP(AUX_REPLY_EVENT_EN, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) static void dw_dp_init(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) regmap_update_bits(dp->regmap, DPTX_CCTL, DEFAULT_FAST_LINK_TRAIN_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) FIELD_PREP(DEFAULT_FAST_LINK_TRAIN_EN, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) dw_dp_hpd_init(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) dw_dp_aux_init(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) static void dw_dp_encoder_enable(struct drm_encoder *encoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) static void dw_dp_encoder_disable(struct drm_encoder *encoder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) struct dw_dp *dp = encoder_to_dp(encoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) struct drm_crtc *crtc = encoder->crtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) if (!crtc->state->active_changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) if (dp->split_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) s->output_if &= ~(VOP_OUTPUT_IF_DP0 | VOP_OUTPUT_IF_DP1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) s->output_if &= ~(dp->id ? VOP_OUTPUT_IF_DP1 : VOP_OUTPUT_IF_DP0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) static int dw_dp_encoder_atomic_check(struct drm_encoder *encoder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) struct drm_crtc_state *crtc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) struct drm_connector_state *conn_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) struct dw_dp *dp = encoder_to_dp(encoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) struct dw_dp_video *video = &dp->video;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) struct drm_display_info *di = &conn_state->connector->display_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) switch (video->color_format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) case DRM_COLOR_FORMAT_YCRCB420:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) s->output_mode = ROCKCHIP_OUT_MODE_YUV420;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) case DRM_COLOR_FORMAT_YCRCB422:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) s->output_mode = ROCKCHIP_OUT_MODE_S888_DUMMY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) case DRM_COLOR_FORMAT_RGB444:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) case DRM_COLOR_FORMAT_YCRCB444:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) if (dp->split_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) s->output_flags |= dp->id ? ROCKCHIP_OUTPUT_DATA_SWAP : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) s->output_if |= VOP_OUTPUT_IF_DP0 | VOP_OUTPUT_IF_DP1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) s->output_if |= dp->id ? VOP_OUTPUT_IF_DP1 : VOP_OUTPUT_IF_DP0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) s->output_type = DRM_MODE_CONNECTOR_DisplayPort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) s->bus_format = video->bus_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) s->bus_flags = di->bus_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) s->tv_state = &conn_state->tv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) s->color_space = V4L2_COLORSPACE_DEFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) static enum drm_mode_status dw_dp_encoder_mode_valid(struct drm_encoder *encoder,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) const struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) struct drm_crtc *crtc = encoder->crtc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) struct drm_device *dev = encoder->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) struct rockchip_crtc_state *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) if (!crtc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) drm_for_each_crtc(crtc, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) if (!drm_encoder_crtc_ok(encoder, crtc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) s = to_rockchip_crtc_state(crtc->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) s->output_type = DRM_MODE_CONNECTOR_DisplayPort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) return MODE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) static const struct drm_encoder_helper_funcs dw_dp_encoder_helper_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) .enable = dw_dp_encoder_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) .disable = dw_dp_encoder_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) .atomic_check = dw_dp_encoder_atomic_check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) .mode_valid = dw_dp_encoder_mode_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) static int dw_dp_aux_write_data(struct dw_dp *dp, const u8 *buffer, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) size_t i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) for (i = 0; i < DIV_ROUND_UP(size, 4); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) size_t num = min_t(size_t, size - i * 4, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) u32 value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) for (j = 0; j < num; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) value |= buffer[i * 4 + j] << (j * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) regmap_write(dp->regmap, DPTX_AUX_DATA0 + i * 4, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) static int dw_dp_aux_read_data(struct dw_dp *dp, u8 *buffer, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) size_t i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) for (i = 0; i < DIV_ROUND_UP(size, 4); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) size_t num = min_t(size_t, size - i * 4, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) regmap_read(dp->regmap, DPTX_AUX_DATA0 + i * 4, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) for (j = 0; j < num; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) buffer[i * 4 + j] = value >> (j * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) static ssize_t dw_dp_aux_transfer(struct drm_dp_aux *aux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) struct drm_dp_aux_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) struct dw_dp *dp = container_of(aux, struct dw_dp, aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) unsigned long timeout = msecs_to_jiffies(250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) u32 status, value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) ssize_t ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) if (WARN_ON(msg->size > 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) switch (msg->request & ~DP_AUX_I2C_MOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) case DP_AUX_NATIVE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) case DP_AUX_I2C_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) case DP_AUX_I2C_WRITE_STATUS_UPDATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) ret = dw_dp_aux_write_data(dp, msg->buffer, msg->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) case DP_AUX_NATIVE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) case DP_AUX_I2C_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) if (msg->size > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) value = FIELD_PREP(AUX_LEN_REQ, msg->size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) value = FIELD_PREP(I2C_ADDR_ONLY, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) value |= FIELD_PREP(AUX_CMD_TYPE, msg->request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) value |= FIELD_PREP(AUX_ADDR, msg->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) regmap_write(dp->regmap, DPTX_AUX_CMD, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) status = wait_for_completion_timeout(&dp->complete, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) if (!status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) dev_err(dp->dev, "timeout waiting for AUX reply\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) regmap_read(dp->regmap, DPTX_AUX_STATUS, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) if (value & AUX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) msg->reply = FIELD_GET(AUX_STATUS, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) if (msg->size > 0 && msg->reply == DP_AUX_NATIVE_REPLY_ACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) if (msg->request & DP_AUX_I2C_READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) size_t count = FIELD_GET(AUX_BYTES_READ, value) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) if (count != msg->size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) ret = dw_dp_aux_read_data(dp, msg->buffer, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) static int dw_dp_bridge_mode_valid(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) const struct drm_display_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) const struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) struct dw_dp *dp = bridge_to_dp(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) struct drm_display_mode m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) u32 min_bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) drm_mode_copy(&m, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) if (dp->split_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) drm_mode_convert_to_origin_mode(&m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) if (m.hsync_end - m.hsync_start <= 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) return MODE_HSYNC_NARROW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) if (info->color_formats & DRM_COLOR_FORMAT_YCRCB420 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) link->vsc_sdp_extension_for_colorimetry_supported &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) (drm_mode_is_420_only(info, &m) || drm_mode_is_420_also(info, &m)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) min_bpp = 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) else if (info->color_formats & DRM_COLOR_FORMAT_YCRCB422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) min_bpp = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) else if (info->color_formats & DRM_COLOR_FORMAT_RGB444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) min_bpp = 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) min_bpp = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) if (!link->vsc_sdp_extension_for_colorimetry_supported &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) drm_mode_is_420_only(info, &m))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) return MODE_NO_420;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (!dw_dp_bandwidth_ok(dp, &m, min_bpp, link->lanes, link->rate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) return MODE_CLOCK_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) return MODE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) static void _dw_dp_loader_protect(struct dw_dp *dp, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) struct drm_connector *conn = &dp->connector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) struct drm_display_info *di = &conn->display_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) if (on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) di->color_formats = DRM_COLOR_FORMAT_RGB444;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) di->bpc = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) regmap_read(dp->regmap, DPTX_PHYIF_CTRL, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) switch (FIELD_GET(PHY_LANES, value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) link->lanes = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) link->lanes = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) link->lanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) switch (FIELD_GET(PHY_RATE, value)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) link->rate = 810000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) link->rate = 540000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) link->rate = 270000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) link->rate = 162000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) phy_power_on(dp->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) phy_power_off(dp->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) static int dw_dp_loader_protect(struct drm_encoder *encoder, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) struct dw_dp *dp = encoder_to_dp(encoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) _dw_dp_loader_protect(dp, on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) if (dp->right)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) _dw_dp_loader_protect(dp->right, on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) static int dw_dp_connector_init(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) struct drm_connector *connector = &dp->connector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) struct drm_bridge *bridge = &dp->bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) struct drm_property *prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) connector->polled = DRM_CONNECTOR_POLL_HPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) if (dp->next_bridge && dp->next_bridge->ops & DRM_BRIDGE_OP_DETECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) connector->polled = DRM_CONNECTOR_POLL_CONNECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) DRM_CONNECTOR_POLL_DISCONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) connector->ycbcr_420_allowed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) ret = drm_connector_init(bridge->dev, connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) &dw_dp_connector_funcs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) DRM_MODE_CONNECTOR_DisplayPort);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) DRM_DEV_ERROR(dp->dev, "Failed to initialize connector\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) drm_connector_helper_add(connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) &dw_dp_connector_helper_funcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) drm_connector_attach_encoder(connector, bridge->encoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) prop = drm_property_create_enum(connector->dev, 0, RK_IF_PROP_COLOR_DEPTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) color_depth_enum_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) ARRAY_SIZE(color_depth_enum_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) if (!prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) DRM_DEV_ERROR(dp->dev, "create color depth prop for dp%d failed\n", dp->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) dp->color_depth_property = prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) drm_object_attach_property(&connector->base, prop, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) prop = drm_property_create_enum(connector->dev, 0, RK_IF_PROP_COLOR_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) color_format_enum_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) ARRAY_SIZE(color_format_enum_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) if (!prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) DRM_DEV_ERROR(dp->dev, "create color format prop for dp%d failed\n", dp->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) dp->color_format_property = prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) drm_object_attach_property(&connector->base, prop, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) prop = drm_property_create_range(connector->dev, 0, RK_IF_PROP_COLOR_DEPTH_CAPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 0, 1 << RK_IF_DEPTH_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) if (!prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) DRM_DEV_ERROR(dp->dev, "create color depth caps prop for dp%d failed\n", dp->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) dp->color_depth_capacity = prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) drm_object_attach_property(&connector->base, prop, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) prop = drm_property_create_range(connector->dev, 0, RK_IF_PROP_COLOR_FORMAT_CAPS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 0, 1 << RK_IF_FORMAT_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) if (!prop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) DRM_DEV_ERROR(dp->dev, "create color format caps prop for dp%d failed\n", dp->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) dp->color_format_capacity = prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) drm_object_attach_property(&connector->base, prop, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) static int dw_dp_bridge_attach(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) enum drm_bridge_attach_flags flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) struct dw_dp *dp = bridge_to_dp(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) struct drm_connector *connector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) bool skip_connector = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) if (!bridge->encoder) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) DRM_DEV_ERROR(dp->dev, "Parent encoder object not found");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) ret = drm_of_find_panel_or_bridge(bridge->of_node, 1, 0, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) &dp->next_bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) if (ret < 0 && ret != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) if (dp->next_bridge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) struct drm_bridge *next_bridge = dp->next_bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) ret = drm_bridge_attach(bridge->encoder, next_bridge, bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) next_bridge->ops & DRM_BRIDGE_OP_MODES ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) DRM_BRIDGE_ATTACH_NO_CONNECTOR : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) DRM_DEV_ERROR(dp->dev, "failed to attach next bridge: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) skip_connector = !(next_bridge->ops & DRM_BRIDGE_OP_MODES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) if (!skip_connector) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) ret = dw_dp_connector_init(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) DRM_DEV_ERROR(dp->dev, "failed to create connector\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) connector = &dp->connector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) struct list_head *connector_list =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) &bridge->dev->mode_config.connector_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) list_for_each_entry(connector, connector_list, head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) if (drm_connector_has_possible_encoder(connector,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) bridge->encoder))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) dp->sub_dev.connector = connector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) dp->sub_dev.of_node = dp->dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) dp->sub_dev.loader_protect = dw_dp_loader_protect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) rockchip_drm_register_sub_dev(&dp->sub_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) static void dw_dp_bridge_detach(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) struct dw_dp *dp = bridge_to_dp(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) drm_connector_cleanup(&dp->connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) static void dw_dp_bridge_atomic_pre_enable(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) struct drm_bridge_state *bridge_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) struct dw_dp *dp = bridge_to_dp(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) struct dw_dp_video *video = &dp->video;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) struct drm_crtc_state *crtc_state = bridge->encoder->crtc->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) struct drm_display_mode *m = &video->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) drm_mode_copy(m, &crtc_state->adjusted_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) if (dp->split_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) drm_mode_convert_to_origin_mode(m);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) static bool dw_dp_needs_link_retrain(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) u8 link_status[DP_LINK_STATUS_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) if (!dw_dp_link_train_valid(&link->train))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) if (drm_dp_dpcd_read_link_status(&dp->aux, link_status) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) /* Retrain if Channel EQ or CR not ok */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) return !drm_dp_channel_eq_ok(link_status, dp->link.lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) static void dw_dp_link_disable(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) if (dw_dp_detect(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) dw_dp_link_power_down(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) dw_dp_phy_xmit_enable(dp, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) phy_power_off(dp->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) link->train.clock_recovered = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) link->train.channel_equalized = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) static int dw_dp_link_enable(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) ret = phy_power_on(dp->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) ret = dw_dp_link_power_up(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) ret = dw_dp_link_train(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) dev_err(dp->dev, "link training failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) static void dw_dp_bridge_atomic_enable(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) struct drm_bridge_state *old_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) struct dw_dp *dp = bridge_to_dp(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) set_bit(0, dp->sdp_reg_bank);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) ret = dw_dp_link_enable(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) dev_err(dp->dev, "failed to enable link: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) ret = dw_dp_video_enable(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) dev_err(dp->dev, "failed to enable video: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) static void dw_dp_reset(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) disable_irq(dp->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) regmap_update_bits(dp->regmap, DPTX_SOFT_RESET_CTRL, CONTROLLER_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) FIELD_PREP(CONTROLLER_RESET, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) regmap_update_bits(dp->regmap, DPTX_SOFT_RESET_CTRL, CONTROLLER_RESET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) FIELD_PREP(CONTROLLER_RESET, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) dw_dp_init(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) if (!dp->hpd_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) regmap_read_poll_timeout(dp->regmap, DPTX_HPD_STATUS, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) FIELD_GET(HPD_HOT_PLUG, val), 200, 200000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) regmap_write(dp->regmap, DPTX_HPD_STATUS, HPD_HOT_PLUG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) enable_irq(dp->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) static void dw_dp_bridge_atomic_disable(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) struct drm_bridge_state *old_bridge_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) struct dw_dp *dp = bridge_to_dp(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) dw_dp_video_disable(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) dw_dp_link_disable(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) bitmap_zero(dp->sdp_reg_bank, SDP_REG_BANK_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) dw_dp_reset(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) static bool dw_dp_detect_dpcd(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) ret = phy_power_on(dp->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) ret = dw_dp_link_probe(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) phy_power_off(dp->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) dev_err(dp->dev, "failed to probe DP link: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) phy_power_off(dp->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) static enum drm_connector_status dw_dp_bridge_detect(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) struct dw_dp *dp = bridge_to_dp(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) enum drm_connector_status status = connector_status_connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) if (!dw_dp_detect(dp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) status = connector_status_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) if (!dw_dp_detect_dpcd(dp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) status = connector_status_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) if (dp->next_bridge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) struct drm_bridge *next_bridge = dp->next_bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) if (next_bridge->ops & DRM_BRIDGE_OP_DETECT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) status = drm_bridge_detect(next_bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) if (status == connector_status_connected) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) dw_dp_audio_handle_plugged_change(&dp->audio, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) extcon_set_state_sync(dp->extcon, EXTCON_DISP_DP, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) dw_dp_audio_handle_plugged_change(&dp->audio, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) static struct edid *dw_dp_bridge_get_edid(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) struct dw_dp *dp = bridge_to_dp(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) struct edid *edid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) ret = phy_power_on(dp->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) edid = drm_get_edid(connector, &dp->aux.ddc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) phy_power_off(dp->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) return edid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) static u32 *dw_dp_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) struct drm_bridge_state *bridge_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) struct drm_crtc_state *crtc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) struct drm_connector_state *conn_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) unsigned int *num_output_fmts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) struct dw_dp *dp = bridge_to_dp(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) struct dw_dp_state *dp_state = connector_to_dp_state(conn_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) struct drm_display_info *di = &conn_state->connector->display_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) struct drm_display_mode mode = crtc_state->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) u32 *output_fmts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) unsigned int i, j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) if (dp->split_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) drm_mode_convert_to_origin_mode(&mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) *num_output_fmts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) output_fmts = kcalloc(ARRAY_SIZE(possible_output_fmts),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) sizeof(*output_fmts), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) if (!output_fmts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) for (i = 0; i < ARRAY_SIZE(possible_output_fmts); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) const struct dw_dp_output_format *fmt = &possible_output_fmts[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) if (fmt->bpc > conn_state->max_bpc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) if (!(di->color_formats & fmt->color_format))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) if (fmt->color_format == DRM_COLOR_FORMAT_YCRCB420 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) !link->vsc_sdp_extension_for_colorimetry_supported)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) if (drm_mode_is_420_only(di, &mode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) fmt->color_format != DRM_COLOR_FORMAT_YCRCB420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) if (!dw_dp_bandwidth_ok(dp, &mode, fmt->bpp, link->lanes, link->rate))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) if (dp_state->bpc != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) if ((fmt->bpc != dp_state->bpc) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) (fmt->color_format != BIT(dp_state->color_format)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) output_fmts[j++] = fmt->bus_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) *num_output_fmts = j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) return output_fmts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) static int dw_dp_bridge_atomic_check(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) struct drm_bridge_state *bridge_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) struct drm_crtc_state *crtc_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) struct drm_connector_state *conn_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) struct dw_dp *dp = bridge_to_dp(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) struct dw_dp_video *video = &dp->video;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) const struct dw_dp_output_format *fmt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) dw_dp_get_output_format(bridge_state->output_bus_cfg.format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) dev_dbg(dp->dev, "input format 0x%04x, output format 0x%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) bridge_state->input_bus_cfg.format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) bridge_state->output_bus_cfg.format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) video->video_mapping = fmt->video_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) video->color_format = fmt->color_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) video->bus_format = fmt->bus_format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) video->bpc = fmt->bpc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) video->bpp = fmt->bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) static const struct drm_bridge_funcs dw_dp_bridge_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) .atomic_reset = drm_atomic_helper_bridge_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) .atomic_get_input_bus_fmts = drm_atomic_helper_bridge_propagate_bus_fmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) .atomic_get_output_bus_fmts = dw_dp_bridge_atomic_get_output_bus_fmts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) .attach = dw_dp_bridge_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) .detach = dw_dp_bridge_detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) .mode_valid = dw_dp_bridge_mode_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) .atomic_check = dw_dp_bridge_atomic_check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) .atomic_pre_enable = dw_dp_bridge_atomic_pre_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) .atomic_enable = dw_dp_bridge_atomic_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) .atomic_disable = dw_dp_bridge_atomic_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) .detect = dw_dp_bridge_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) .get_edid = dw_dp_bridge_get_edid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) static int dw_dp_link_retrain(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) struct drm_device *dev = dp->bridge.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) struct drm_modeset_acquire_ctx ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) if (!dw_dp_needs_link_retrain(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) dev_dbg(dp->dev, "Retraining link\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) drm_modeset_acquire_init(&ctx, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) if (ret != -EDEADLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) drm_modeset_backoff(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) ret = dw_dp_link_train(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) drm_modeset_drop_locks(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) drm_modeset_acquire_fini(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) static u8 dw_dp_autotest_phy_pattern(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) struct drm_dp_phy_test_params *data = &dp->compliance.test_data.phytest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) if (drm_dp_get_phy_test_pattern(&dp->aux, data)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) dev_err(dp->dev, "DP Phy Test pattern AUX read failure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) return DP_TEST_NAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) /* Set test active flag here so userspace doesn't interrupt things */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) dp->compliance.test_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) return DP_TEST_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) static void dw_dp_handle_test_request(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) u8 response = DP_TEST_NAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) u8 request = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) status = drm_dp_dpcd_readb(&dp->aux, DP_TEST_REQUEST, &request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) if (status <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) dev_err(dp->dev, "Could not read test request from sink\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) goto update_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) switch (request) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) case DP_TEST_LINK_PHY_TEST_PATTERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) dev_dbg(dp->dev, "PHY_PATTERN test requested\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) response = dw_dp_autotest_phy_pattern(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) dev_warn(dp->dev, "Invalid test request '%02x'\n", request);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) if (response & DP_TEST_ACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) dp->compliance.test_type = request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) update_status:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) status = drm_dp_dpcd_writeb(&dp->aux, DP_TEST_RESPONSE, response);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) if (status <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) dev_warn(dp->dev, "Could not write test response to sink\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) static void dw_dp_check_service_irq(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) struct dw_dp_link *link = &dp->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) if (link->dpcd[DP_DPCD_REV] < 0x11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) if (drm_dp_dpcd_readb(&dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, &val) != 1 || !val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) drm_dp_dpcd_writeb(&dp->aux, DP_DEVICE_SERVICE_IRQ_VECTOR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) if (val & DP_AUTOMATED_TEST_REQUEST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) dw_dp_handle_test_request(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) if (val & DP_SINK_SPECIFIC_IRQ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) dev_info(dp->dev, "Sink specific irq unhandled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) static void dw_dp_phy_pattern_update(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) struct drm_dp_phy_test_params *data = &dp->compliance.test_data.phytest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) switch (data->phy_pattern) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) case DP_PHY_TEST_PATTERN_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) dev_dbg(dp->dev, "Disable Phy Test Pattern\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) FIELD_PREP(SCRAMBLE_DIS, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) case DP_PHY_TEST_PATTERN_D10_2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) dev_dbg(dp->dev, "Set D10.2 Phy Test Pattern\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) FIELD_PREP(SCRAMBLE_DIS, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) case DP_PHY_TEST_PATTERN_ERROR_COUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) FIELD_PREP(SCRAMBLE_DIS, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) dev_dbg(dp->dev, "Set Error Count Phy Test Pattern\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_SERM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) case DP_PHY_TEST_PATTERN_PRBS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) dev_dbg(dp->dev, "Set PRBS7 Phy Test Pattern\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) FIELD_PREP(SCRAMBLE_DIS, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_PBRS7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) dev_dbg(dp->dev, "Set 80Bit Custom Phy Test Pattern\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) FIELD_PREP(SCRAMBLE_DIS, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) regmap_write(dp->regmap, DPTX_CUSTOMPAT0, 0x3e0f83e0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) regmap_write(dp->regmap, DPTX_CUSTOMPAT1, 0x3e0f83e0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) regmap_write(dp->regmap, DPTX_CUSTOMPAT2, 0x000f83e0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_CUSTOM_80BIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) case DP_PHY_TEST_PATTERN_CP2520:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) dev_dbg(dp->dev, "Set HBR2 compliance Phy Test Pattern\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) FIELD_PREP(SCRAMBLE_DIS, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_CP2520_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) case DP_PHY_TEST_PATTERN_SEL_MASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) dev_dbg(dp->dev, "Set TPS4 Phy Test Pattern\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) regmap_update_bits(dp->regmap, DPTX_CCTL, SCRAMBLE_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) FIELD_PREP(SCRAMBLE_DIS, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) dw_dp_phy_set_pattern(dp, DPTX_PHY_PATTERN_TPS_4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) WARN(1, "Invalid Phy Test Pattern\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) static void dw_dp_process_phy_request(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) struct drm_dp_phy_test_params *data = &dp->compliance.test_data.phytest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) u8 link_status[DP_LINK_STATUS_SIZE], spread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) ret = drm_dp_dpcd_read(&dp->aux, DP_LANE0_1_STATUS, link_status, DP_LINK_STATUS_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) dev_err(dp->dev, "failed to get link status\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_DOWNSPREAD, &spread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) dev_err(dp->dev, "failed to get spread\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) dw_dp_phy_configure(dp, data->link_rate, data->num_lanes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) !!(spread & DP_MAX_DOWNSPREAD_0_5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) dw_dp_link_get_adjustments(&dp->link, link_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) dw_dp_phy_update_vs_emph(dp, data->link_rate, data->num_lanes, &dp->link.train.adjust);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) dw_dp_phy_pattern_update(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) drm_dp_set_phy_test_pattern(&dp->aux, data, link_status[DP_DPCD_REV]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) dev_dbg(dp->dev, "phy test rate:%d, lane count:%d, ssc:%d, vs:%d, pe: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) data->link_rate, data->num_lanes, spread, dp->link.train.adjust.voltage_swing[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) dp->link.train.adjust.pre_emphasis[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) static void dw_dp_phy_test(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) struct drm_device *dev = dp->bridge.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) struct drm_modeset_acquire_ctx ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) drm_modeset_acquire_init(&ctx, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) ret = drm_modeset_lock(&dev->mode_config.connection_mutex, &ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) if (ret != -EDEADLK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) drm_modeset_backoff(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) dw_dp_process_phy_request(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) drm_modeset_drop_locks(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) drm_modeset_acquire_fini(&ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) static bool dw_dp_hpd_short_pulse(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) memset(&dp->compliance, 0, sizeof(dp->compliance));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) dw_dp_check_service_irq(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) if (dw_dp_needs_link_retrain(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) switch (dp->compliance.test_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) case DP_TEST_LINK_PHY_TEST_PATTERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) dev_warn(dp->dev, "test_type%lu is not support\n", dp->compliance.test_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) static void dw_dp_hpd_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) struct dw_dp *dp = container_of(work, struct dw_dp, hpd_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) bool long_hpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) mutex_lock(&dp->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) long_hpd = dp->hotplug.long_hpd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) mutex_unlock(&dp->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) dev_dbg(dp->dev, "got hpd irq - %s\n", long_hpd ? "long" : "short");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) if (!long_hpd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) if (dw_dp_hpd_short_pulse(dp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) if (dp->compliance.test_active &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) dp->compliance.test_type == DP_TEST_LINK_PHY_TEST_PATTERN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) dw_dp_phy_test(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) /* just do the PHY test and nothing else */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) ret = dw_dp_link_retrain(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) dev_warn(dp->dev, "Retrain link failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) drm_helper_hpd_irq_event(dp->bridge.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) static void dw_dp_handle_hpd_event(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) mutex_lock(&dp->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) regmap_read(dp->regmap, DPTX_HPD_STATUS, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) if (value & HPD_IRQ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) dev_dbg(dp->dev, "IRQ from the HPD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) dp->hotplug.long_hpd = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) regmap_write(dp->regmap, DPTX_HPD_STATUS, HPD_IRQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) if (value & HPD_HOT_PLUG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) dev_dbg(dp->dev, "Hot plug detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) dp->hotplug.long_hpd = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) regmap_write(dp->regmap, DPTX_HPD_STATUS, HPD_HOT_PLUG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) if (value & HPD_HOT_UNPLUG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) dev_dbg(dp->dev, "Unplug detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) dp->hotplug.long_hpd = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) regmap_write(dp->regmap, DPTX_HPD_STATUS, HPD_HOT_UNPLUG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) mutex_unlock(&dp->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) schedule_work(&dp->hpd_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) static irqreturn_t dw_dp_irq_handler(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) struct dw_dp *dp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) regmap_read(dp->regmap, DPTX_GENERAL_INTERRUPT, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) if (!value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) if (value & HPD_EVENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) dw_dp_handle_hpd_event(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) if (value & AUX_REPLY_EVENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) regmap_write(dp->regmap, DPTX_GENERAL_INTERRUPT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) AUX_REPLY_EVENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) complete(&dp->complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) static int dw_dp_audio_hw_params(struct device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) struct hdmi_codec_daifmt *daifmt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) struct hdmi_codec_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) struct dw_dp *dp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) struct dw_dp_audio *audio = &dp->audio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) u8 audio_data_in_en, num_channels, audio_inf_select;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) audio->channels = params->cea.channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) switch (params->cea.channels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) audio_data_in_en = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) num_channels = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) audio_data_in_en = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) num_channels = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) audio_data_in_en = 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) num_channels = 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) dev_err(dp->dev, "invalid channels %d\n", params->cea.channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) switch (daifmt->fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) case HDMI_SPDIF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) audio_inf_select = 0x1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) audio->format = AFMT_SPDIF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) case HDMI_I2S:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) audio_inf_select = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) audio->format = AFMT_I2S;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) dev_err(dp->dev, "invalid daifmt %d\n", daifmt->fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) clk_prepare_enable(dp->spdif_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) clk_prepare_enable(dp->i2s_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) regmap_update_bits(dp->regmap, DPTX_AUD_CONFIG1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) AUDIO_DATA_IN_EN | NUM_CHANNELS | AUDIO_DATA_WIDTH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) AUDIO_INF_SELECT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) FIELD_PREP(AUDIO_DATA_IN_EN, audio_data_in_en) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) FIELD_PREP(NUM_CHANNELS, num_channels) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) FIELD_PREP(AUDIO_DATA_WIDTH, params->sample_width) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) FIELD_PREP(AUDIO_INF_SELECT, audio_inf_select));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) /* Wait for inf switch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) usleep_range(20, 40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) if (audio->format == AFMT_I2S)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) clk_disable_unprepare(dp->spdif_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) else if (audio->format == AFMT_SPDIF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) clk_disable_unprepare(dp->i2s_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) static int dw_dp_audio_infoframe_send(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) struct dw_dp_audio *audio = &dp->audio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) struct hdmi_audio_infoframe frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) struct dp_sdp_header header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_DRM_INFOFRAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) u8 size = sizeof(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) int i, j, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) header.HB0 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) header.HB1 = HDMI_INFOFRAME_TYPE_AUDIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) header.HB2 = 0x1b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) header.HB3 = 0x48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) ret = hdmi_audio_infoframe_init(&frame);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) frame.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) frame.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) frame.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) frame.channels = audio->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) regmap_write(dp->regmap, DPTX_SDP_REGISTER_BANK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) get_unaligned_le32(&header));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) for (i = 1; i < DIV_ROUND_UP(size, 4); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) size_t num = min_t(size_t, size - i * 4, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) u32 value = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) for (j = 0; j < num; j++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) value |= buffer[i * 4 + j] << (j * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) regmap_write(dp->regmap, DPTX_SDP_REGISTER_BANK + 4 * i, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) regmap_update_bits(dp->regmap, DPTX_SDP_VERTICAL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) EN_VERTICAL_SDP, FIELD_PREP(EN_VERTICAL_SDP, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) static int dw_dp_audio_startup(struct device *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) struct dw_dp *dp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) regmap_update_bits(dp->regmap, DPTX_SDP_VERTICAL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) EN_AUDIO_STREAM_SDP | EN_AUDIO_TIMESTAMP_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) FIELD_PREP(EN_AUDIO_STREAM_SDP, 1) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) FIELD_PREP(EN_AUDIO_TIMESTAMP_SDP, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) regmap_update_bits(dp->regmap, DPTX_SDP_HORIZONTAL_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) EN_AUDIO_STREAM_SDP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) FIELD_PREP(EN_AUDIO_STREAM_SDP, 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) return dw_dp_audio_infoframe_send(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) static void dw_dp_audio_shutdown(struct device *dev, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) struct dw_dp *dp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) struct dw_dp_audio *audio = &dp->audio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) regmap_update_bits(dp->regmap, DPTX_AUD_CONFIG1, AUDIO_DATA_IN_EN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) FIELD_PREP(AUDIO_DATA_IN_EN, 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) if (audio->format == AFMT_SPDIF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) clk_disable_unprepare(dp->spdif_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) else if (audio->format == AFMT_I2S)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) clk_disable_unprepare(dp->i2s_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) audio->format = AFMT_UNUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) static int dw_dp_audio_hook_plugged_cb(struct device *dev, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) hdmi_codec_plugged_cb fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) struct device *codec_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) struct dw_dp *dp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) struct dw_dp_audio *audio = &dp->audio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) audio->plugged_cb = fn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) audio->codec_dev = codec_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) dw_dp_audio_handle_plugged_change(audio, dw_dp_detect(dp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) static int dw_dp_audio_get_eld(struct device *dev, void *data, uint8_t *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) struct dw_dp *dp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) struct drm_connector *connector = &dp->connector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) memcpy(buf, connector->eld, min(sizeof(connector->eld), len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) static const struct hdmi_codec_ops dw_dp_audio_codec_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) .hw_params = dw_dp_audio_hw_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) .audio_startup = dw_dp_audio_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) .audio_shutdown = dw_dp_audio_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) .get_eld = dw_dp_audio_get_eld,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) .hook_plugged_cb = dw_dp_audio_hook_plugged_cb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) static int dw_dp_register_audio_driver(struct dw_dp *dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) struct dw_dp_audio *audio = &dp->audio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) struct hdmi_codec_pdata codec_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) .ops = &dw_dp_audio_codec_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) .spdif = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) .i2s = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) .max_i2s_channels = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) audio->format = AFMT_UNUSED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) audio->pdev = platform_device_register_data(dp->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) HDMI_CODEC_DRV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) PLATFORM_DEVID_AUTO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) &codec_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) sizeof(codec_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) return PTR_ERR_OR_ZERO(audio->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) static void dw_dp_unregister_audio_driver(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) struct dw_dp *dp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) struct dw_dp_audio *audio = &dp->audio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) if (audio->pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) platform_device_unregister(audio->pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) audio->pdev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) static void dw_dp_aux_unregister(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) struct dw_dp *dp = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) drm_dp_aux_unregister(&dp->aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) static int dw_dp_bind(struct device *dev, struct device *master, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) struct dw_dp *dp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) struct drm_device *drm_dev = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) struct drm_encoder *encoder = &dp->encoder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) struct drm_bridge *bridge = &dp->bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) if (!dp->left) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) drm_simple_encoder_init(drm_dev, encoder, DRM_MODE_ENCODER_TMDS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) drm_encoder_helper_add(encoder, &dw_dp_encoder_helper_funcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) encoder->possible_crtcs =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) rockchip_drm_of_find_possible_crtcs(drm_dev, dev->of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) ret = drm_bridge_attach(encoder, bridge, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) dev_err(dev, "failed to attach bridge: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) if (dp->right) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) struct dw_dp *secondary = dp->right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) struct drm_bridge *last_bridge =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) list_last_entry(&encoder->bridge_chain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) struct drm_bridge, chain_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) ret = drm_bridge_attach(encoder, &secondary->bridge, last_bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) DRM_BRIDGE_ATTACH_NO_CONNECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) pm_runtime_enable(dp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) pm_runtime_get_sync(dp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) enable_irq(dp->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) if (dp->hpd_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) enable_irq(dp->hpd_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) static void dw_dp_unbind(struct device *dev, struct device *master, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) struct dw_dp *dp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) if (dp->hpd_gpio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) disable_irq(dp->hpd_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) disable_irq(dp->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) pm_runtime_put(dp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) pm_runtime_disable(dp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) drm_encoder_cleanup(&dp->encoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) static const struct component_ops dw_dp_component_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) .bind = dw_dp_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) .unbind = dw_dp_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) static const struct regmap_range dw_dp_readable_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) regmap_reg_range(DPTX_VERSION_NUMBER, DPTX_ID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) regmap_reg_range(DPTX_CONFIG_REG1, DPTX_CONFIG_REG3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) regmap_reg_range(DPTX_CCTL, DPTX_SOFT_RESET_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) regmap_reg_range(DPTX_VSAMPLE_CTRL, DPTX_VIDEO_HBLANK_INTERVAL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) regmap_reg_range(DPTX_AUD_CONFIG1, DPTX_AUD_CONFIG1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) regmap_reg_range(DPTX_SDP_VERTICAL_CTRL, DPTX_SDP_STATUS_EN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) regmap_reg_range(DPTX_PHYIF_CTRL, DPTX_PHYIF_PWRDOWN_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) regmap_reg_range(DPTX_AUX_CMD, DPTX_AUX_DATA3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) regmap_reg_range(DPTX_GENERAL_INTERRUPT, DPTX_HPD_INTERRUPT_ENABLE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) static const struct regmap_access_table dw_dp_readable_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) .yes_ranges = dw_dp_readable_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) .n_yes_ranges = ARRAY_SIZE(dw_dp_readable_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) static const struct regmap_config dw_dp_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) .fast_io = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) .max_register = DPTX_MAX_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) .rd_table = &dw_dp_readable_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) static int dw_dp_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) struct dw_dp *dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) int id, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) if (!dp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) id = of_alias_get_id(dev->of_node, "dp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) if (id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) dp->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) dp->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) dp->video.pixel_mode = DPTX_MP_QUAD_PIXEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) mutex_init(&dp->irq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) INIT_WORK(&dp->hpd_work, dw_dp_hpd_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) init_completion(&dp->complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) base = devm_platform_ioremap_resource(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) if (IS_ERR(base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) return PTR_ERR(base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) dp->regmap = devm_regmap_init_mmio(dev, base, &dw_dp_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) if (IS_ERR(dp->regmap))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) return dev_err_probe(dev, PTR_ERR(dp->regmap),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172) "failed to create regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174) dp->phy = devm_of_phy_get(dev, dev->of_node, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) if (IS_ERR(dp->phy))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) return dev_err_probe(dev, PTR_ERR(dp->phy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) "failed to get phy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) dp->apb_clk = devm_clk_get(dev, "apb");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) if (IS_ERR(dp->apb_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) return dev_err_probe(dev, PTR_ERR(dp->apb_clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) "failed to get apb clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) dp->aux_clk = devm_clk_get(dev, "aux");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) if (IS_ERR(dp->aux_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) return dev_err_probe(dev, PTR_ERR(dp->aux_clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) "failed to get aux clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) dp->i2s_clk = devm_clk_get(dev, "i2s");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) if (IS_ERR(dp->i2s_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) return dev_err_probe(dev, PTR_ERR(dp->i2s_clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) "failed to get i2s clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) dp->spdif_clk = devm_clk_get(dev, "spdif");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) if (IS_ERR(dp->spdif_clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) return dev_err_probe(dev, PTR_ERR(dp->spdif_clk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) "failed to get spdif clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) dp->hclk = devm_clk_get_optional(dev, "hclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) if (IS_ERR(dp->hclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) return dev_err_probe(dev, PTR_ERR(dp->hclk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) "failed to get hclk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) dp->rstc = devm_reset_control_get(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) if (IS_ERR(dp->rstc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) return dev_err_probe(dev, PTR_ERR(dp->rstc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) "failed to get reset control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) dp->hpd_gpio = devm_gpiod_get_optional(dev, "hpd", GPIOD_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) if (IS_ERR(dp->hpd_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) return dev_err_probe(dev, PTR_ERR(dp->hpd_gpio),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) "failed to get hpd GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) if (dp->hpd_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) dp->hpd_irq = gpiod_to_irq(dp->hpd_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) if (dp->hpd_irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) return dev_err_probe(dev, dp->hpd_irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) "failed to get hpd irq\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) irq_set_status_flags(dp->hpd_irq, IRQ_NOAUTOEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) ret = devm_request_threaded_irq(dev, dp->hpd_irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) dw_dp_hpd_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) IRQF_TRIGGER_RISING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) IRQF_TRIGGER_FALLING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) IRQF_ONESHOT, "dw-dp-hpd", dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) dev_err(dev, "failed to request HPD interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) dp->irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) if (dp->irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) return dp->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) irq_set_status_flags(dp->irq, IRQ_NOAUTOEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) ret = devm_request_threaded_irq(dev, dp->irq, NULL, dw_dp_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) IRQF_ONESHOT, dev_name(dev), dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) dev_err(dev, "failed to request irq: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) dp->extcon = devm_extcon_dev_allocate(dev, dw_dp_cable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) if (IS_ERR(dp->extcon))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) return dev_err_probe(dev, PTR_ERR(dp->extcon),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) "failed to allocate extcon device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) ret = devm_extcon_dev_register(dev, dp->extcon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) return dev_err_probe(dev, ret,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) "failed to register extcon device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) ret = dw_dp_register_audio_driver(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) ret = devm_add_action_or_reset(dev, dw_dp_unregister_audio_driver, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) dp->aux.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) dp->aux.name = dev_name(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) dp->aux.transfer = dw_dp_aux_transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) ret = drm_dp_aux_register(&dp->aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) ret = devm_add_action_or_reset(dev, dw_dp_aux_unregister, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) dp->bridge.of_node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) dp->bridge.funcs = &dw_dp_bridge_funcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) dp->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) DRM_BRIDGE_OP_HPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) dp->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) platform_set_drvdata(pdev, dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) dp->force_hpd = device_property_read_bool(dev, "force-hpd");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) if (device_property_read_bool(dev, "split-mode")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) struct dw_dp *secondary = dw_dp_find_by_id(dev->driver, !dp->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) if (!secondary)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) return -EPROBE_DEFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) dp->right = secondary;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) dp->split_mode = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) secondary->left = dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) secondary->split_mode = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) return component_add(dev, &dw_dp_component_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) static int dw_dp_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) struct dw_dp *dp = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) component_del(dp->dev, &dw_dp_component_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) cancel_work_sync(&dp->hpd_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) static int __maybe_unused dw_dp_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) struct dw_dp *dp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) clk_disable_unprepare(dp->aux_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) clk_disable_unprepare(dp->apb_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) clk_disable_unprepare(dp->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) static int __maybe_unused dw_dp_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) struct dw_dp *dp = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) clk_prepare_enable(dp->hclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) clk_prepare_enable(dp->apb_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) clk_prepare_enable(dp->aux_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) dw_dp_init(dp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) static const struct dev_pm_ops dw_dp_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) SET_RUNTIME_PM_OPS(dw_dp_runtime_suspend, dw_dp_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) pm_runtime_force_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) static const struct of_device_id dw_dp_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) { .compatible = "rockchip,rk3588-dp", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) MODULE_DEVICE_TABLE(of, dw_dp_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) struct platform_driver dw_dp_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) .probe = dw_dp_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) .remove = dw_dp_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) .name = "dw-dp",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) .of_match_table = dw_dp_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) .pm = &dw_dp_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) };