^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * tc358767 eDP bridge driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2016 CogentEmbedded Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Andrey Gusakov <andrey.gusakov@cogentembedded.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2016 Pengutronix, Philipp Zabel <p.zabel@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (C) 2016 Zodiac Inflight Innovations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Initially based on: drivers/gpu/drm/i2c/tda998x_drv.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Copyright (C) 2012 Texas Instruments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Author: Rob Clark <robdclark@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <drm/drm_atomic_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <drm/drm_bridge.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <drm/drm_dp_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <drm/drm_edid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <drm/drm_of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <drm/drm_panel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <drm/drm_print.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <drm/drm_probe_helper.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /* Registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) /* Display Parallel Interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define DPIPXLFMT 0x0440
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define VS_POL_ACTIVE_LOW (1 << 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define HS_POL_ACTIVE_LOW (1 << 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define DE_POL_ACTIVE_HIGH (0 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define SUB_CFG_TYPE_CONFIG1 (0 << 2) /* LSB aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define SUB_CFG_TYPE_CONFIG2 (1 << 2) /* Loosely Packed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define SUB_CFG_TYPE_CONFIG3 (2 << 2) /* LSB aligned 8-bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define DPI_BPP_RGB888 (0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define DPI_BPP_RGB666 (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define DPI_BPP_RGB565 (2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* Video Path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define VPCTRL0 0x0450
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define VSDELAY GENMASK(31, 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define OPXLFMT_RGB666 (0 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define OPXLFMT_RGB888 (1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define FRMSYNC_DISABLED (0 << 4) /* Video Timing Gen Disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define FRMSYNC_ENABLED (1 << 4) /* Video Timing Gen Enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define MSF_DISABLED (0 << 0) /* Magic Square FRC disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define MSF_ENABLED (1 << 0) /* Magic Square FRC enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define HTIM01 0x0454
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define HPW GENMASK(8, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define HBPR GENMASK(24, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define HTIM02 0x0458
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define HDISPR GENMASK(10, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define HFPR GENMASK(24, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define VTIM01 0x045c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define VSPR GENMASK(7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define VBPR GENMASK(23, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define VTIM02 0x0460
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define VFPR GENMASK(23, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define VDISPR GENMASK(10, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define VFUEN0 0x0464
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define VFUEN BIT(0) /* Video Frame Timing Upload */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* System */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define TC_IDREG 0x0500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define SYSSTAT 0x0508
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define SYSCTRL 0x0510
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define DP0_AUDSRC_NO_INPUT (0 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define DP0_AUDSRC_I2S_RX (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define DP0_VIDSRC_NO_INPUT (0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define DP0_VIDSRC_DSI_RX (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define DP0_VIDSRC_DPI_RX (2 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define DP0_VIDSRC_COLOR_BAR (3 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define SYSRSTENB 0x050c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define ENBI2C (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define ENBLCD0 (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define ENBBM (1 << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define ENBDSIRX (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define ENBREG (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define ENBHDCP (1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define GPIOM 0x0540
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define GPIOC 0x0544
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define GPIOO 0x0548
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define GPIOI 0x054c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define INTCTL_G 0x0560
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define INTSTS_G 0x0564
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define INT_SYSERR BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define INT_GPIO_H(x) (1 << (x == 0 ? 2 : 10))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define INT_GPIO_LC(x) (1 << (x == 0 ? 3 : 11))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define INT_GP0_LCNT 0x0584
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define INT_GP1_LCNT 0x0588
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define DP0CTL 0x0600
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define VID_MN_GEN BIT(6) /* Auto-generate M/N values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define EF_EN BIT(5) /* Enable Enhanced Framing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define VID_EN BIT(1) /* Video transmission enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define DP_EN BIT(0) /* Enable DPTX function */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* Clocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define DP0_VIDMNGEN0 0x0610
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #define DP0_VIDMNGEN1 0x0614
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define DP0_VMNGENSTATUS 0x0618
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* Main Channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define DP0_SECSAMPLE 0x0640
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define DP0_VIDSYNCDELAY 0x0644
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define VID_SYNC_DLY GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define THRESH_DLY GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define DP0_TOTALVAL 0x0648
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define H_TOTAL GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define V_TOTAL GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) #define DP0_STARTVAL 0x064c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #define H_START GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define V_START GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define DP0_ACTIVEVAL 0x0650
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define H_ACT GENMASK(15, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #define V_ACT GENMASK(31, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define DP0_SYNCVAL 0x0654
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define VS_WIDTH GENMASK(30, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) #define HS_WIDTH GENMASK(14, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) #define SYNCVAL_HS_POL_ACTIVE_LOW (1 << 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define SYNCVAL_VS_POL_ACTIVE_LOW (1 << 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define DP0_MISC 0x0658
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define TU_SIZE_RECOMMENDED (63) /* LSCLK cycles per TU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define MAX_TU_SYMBOL GENMASK(28, 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define TU_SIZE GENMASK(21, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #define BPC_6 (0 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define BPC_8 (1 << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* AUX channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define DP0_AUXCFG0 0x0660
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define DP0_AUXCFG0_BSIZE GENMASK(11, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define DP0_AUXCFG0_ADDR_ONLY BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define DP0_AUXCFG1 0x0664
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define AUX_RX_FILTER_EN BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define DP0_AUXADDR 0x0668
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define DP0_AUXWDATA(i) (0x066c + (i) * 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define DP0_AUXRDATA(i) (0x067c + (i) * 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define DP0_AUXSTATUS 0x068c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define AUX_BYTES GENMASK(15, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define AUX_STATUS GENMASK(7, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) #define AUX_TIMEOUT BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) #define AUX_BUSY BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define DP0_AUXI2CADR 0x0698
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Link Training */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define DP0_SRCCTRL 0x06a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define DP0_SRCCTRL_SCRMBLDIS BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define DP0_SRCCTRL_EN810B BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #define DP0_SRCCTRL_NOTP (0 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define DP0_SRCCTRL_TP1 (1 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #define DP0_SRCCTRL_TP2 (2 << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define DP0_SRCCTRL_LANESKEW BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define DP0_SRCCTRL_SSCG BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define DP0_SRCCTRL_LANES_1 (0 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define DP0_SRCCTRL_LANES_2 (1 << 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define DP0_SRCCTRL_BW27 (1 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define DP0_SRCCTRL_BW162 (0 << 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define DP0_SRCCTRL_AUTOCORRECT BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define DP0_LTSTAT 0x06d0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define LT_LOOPDONE BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define LT_STATUS_MASK (0x1f << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #define LT_CHANNEL1_EQ_BITS (DP_CHANNEL_EQ_BITS << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define LT_INTERLANE_ALIGN_DONE BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define LT_CHANNEL0_EQ_BITS (DP_CHANNEL_EQ_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define DP0_SNKLTCHGREQ 0x06d4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define DP0_LTLOOPCTRL 0x06d8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define DP0_SNKLTCTRL 0x06e4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define DP1_SRCCTRL 0x07a0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define DP_PHY_CTRL 0x0800
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define DP_PHY_RST BIT(28) /* DP PHY Global Soft Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define BGREN BIT(25) /* AUX PHY BGR Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define PWR_SW_EN BIT(24) /* PHY Power Switch Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define PHY_M1_RST BIT(12) /* Reset PHY1 Main Channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define PHY_RDY BIT(16) /* PHY Main Channels Ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define PHY_M0_RST BIT(8) /* Reset PHY0 Main Channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define PHY_2LANE BIT(2) /* PHY Enable 2 lanes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) #define PHY_A0_EN BIT(1) /* PHY Aux Channel0 Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define PHY_M0_EN BIT(0) /* PHY Main Channel0 Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) #define DP0_PLLCTRL 0x0900
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define DP1_PLLCTRL 0x0904 /* not defined in DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define PXL_PLLCTRL 0x0908
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define PLLUPDATE BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define PLLBYP BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define PLLEN BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define PXL_PLLPARAM 0x0914
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define IN_SEL_REFCLK (0 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) #define SYS_PLLPARAM 0x0918
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #define REF_FREQ_38M4 (0 << 8) /* 38.4 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define REF_FREQ_19M2 (1 << 8) /* 19.2 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define REF_FREQ_26M (2 << 8) /* 26 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define REF_FREQ_13M (3 << 8) /* 13 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define SYSCLK_SEL_LSCLK (0 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define LSCLK_DIV_1 (0 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define LSCLK_DIV_2 (1 << 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) /* Test & Debug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define TSTCTL 0x0a00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define COLOR_R GENMASK(31, 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define COLOR_G GENMASK(23, 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #define COLOR_B GENMASK(15, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define ENI2CFILTER BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define COLOR_BAR_MODE GENMASK(1, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define COLOR_BAR_MODE_BARS 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define PLL_DBG 0x0a04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static bool tc_test_pattern;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) module_param_named(test, tc_test_pattern, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) struct tc_edp_link {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u8 dpcd[DP_RECEIVER_CAP_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) unsigned int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) u8 num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) u8 assr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) bool scrambler_dis;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) bool spread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct tc_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct drm_dp_aux aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) struct drm_bridge bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct drm_bridge *panel_bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct drm_connector connector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /* link settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) struct tc_edp_link link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) struct drm_display_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u32 rev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) u8 assr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) struct gpio_desc *sd_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct gpio_desc *reset_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct clk *refclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) /* do we have IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) bool have_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* HPD pin number (0 or 1) or -ENODEV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) int hpd_pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static inline struct tc_data *aux_to_tc(struct drm_dp_aux *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return container_of(a, struct tc_data, aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static inline struct tc_data *bridge_to_tc(struct drm_bridge *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return container_of(b, struct tc_data, bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) static inline struct tc_data *connector_to_tc(struct drm_connector *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return container_of(c, struct tc_data, connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static inline int tc_poll_timeout(struct tc_data *tc, unsigned int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) unsigned int cond_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) unsigned int cond_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) unsigned long sleep_us, u64 timeout_us)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return regmap_read_poll_timeout(tc->regmap, addr, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) (val & cond_mask) == cond_value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) sleep_us, timeout_us);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) static int tc_aux_wait_busy(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return tc_poll_timeout(tc, DP0_AUXSTATUS, AUX_BUSY, 0, 100, 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int tc_aux_write_data(struct tc_data *tc, const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) u32 auxwdata[DP_AUX_MAX_PAYLOAD_BYTES / sizeof(u32)] = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int ret, count = ALIGN(size, sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) memcpy(auxwdata, data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ret = regmap_raw_write(tc->regmap, DP0_AUXWDATA(0), auxwdata, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) static int tc_aux_read_data(struct tc_data *tc, void *data, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u32 auxrdata[DP_AUX_MAX_PAYLOAD_BYTES / sizeof(u32)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) int ret, count = ALIGN(size, sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) ret = regmap_raw_read(tc->regmap, DP0_AUXRDATA(0), auxrdata, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) memcpy(data, auxrdata, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) static u32 tc_auxcfg0(struct drm_dp_aux_msg *msg, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) u32 auxcfg0 = msg->request;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) auxcfg0 |= FIELD_PREP(DP0_AUXCFG0_BSIZE, size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) auxcfg0 |= DP0_AUXCFG0_ADDR_ONLY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return auxcfg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static ssize_t tc_aux_transfer(struct drm_dp_aux *aux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) struct drm_dp_aux_msg *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) struct tc_data *tc = aux_to_tc(aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) size_t size = min_t(size_t, DP_AUX_MAX_PAYLOAD_BYTES - 1, msg->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) u8 request = msg->request & ~DP_AUX_I2C_MOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) u32 auxstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ret = tc_aux_wait_busy(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) switch (request) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) case DP_AUX_NATIVE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) case DP_AUX_I2C_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) case DP_AUX_NATIVE_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) case DP_AUX_I2C_WRITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) ret = tc_aux_write_data(tc, msg->buffer, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* Store address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = regmap_write(tc->regmap, DP0_AUXADDR, msg->address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /* Start transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ret = regmap_write(tc->regmap, DP0_AUXCFG0, tc_auxcfg0(msg, size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) ret = tc_aux_wait_busy(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ret = regmap_read(tc->regmap, DP0_AUXSTATUS, &auxstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (auxstatus & AUX_TIMEOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * For some reason address-only DP_AUX_I2C_WRITE (MOT), still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * reports 1 byte transferred in its status. To deal we that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * we ignore aux_bytes field if we know that this was an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * address-only transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) size = FIELD_GET(AUX_BYTES, auxstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) msg->reply = FIELD_GET(AUX_STATUS, auxstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) switch (request) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) case DP_AUX_NATIVE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) case DP_AUX_I2C_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) return tc_aux_read_data(tc, msg->buffer, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) static const char * const training_pattern1_errors[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) "No errors",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) "Aux write error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) "Aux read error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) "Max voltage reached error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) "Loop counter expired error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) "res", "res", "res"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static const char * const training_pattern2_errors[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) "No errors",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) "Aux write error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) "Aux read error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) "Clock recovery failed error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) "Loop counter expired error",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) "res", "res", "res"
^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 u32 tc_srcctrl(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * No training pattern, skew lane 1 data by two LSCLK cycles with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * respect to lane 0 data, AutoCorrect Mode = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) u32 reg = DP0_SRCCTRL_NOTP | DP0_SRCCTRL_LANESKEW | DP0_SRCCTRL_EN810B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (tc->link.scrambler_dis)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) reg |= DP0_SRCCTRL_SCRMBLDIS; /* Scrambler Disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) if (tc->link.spread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) reg |= DP0_SRCCTRL_SSCG; /* Spread Spectrum Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (tc->link.num_lanes == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) reg |= DP0_SRCCTRL_LANES_2; /* Two Main Channel Lanes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (tc->link.rate != 162000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) reg |= DP0_SRCCTRL_BW27; /* 2.7 Gbps link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) static int tc_pllupdate(struct tc_data *tc, unsigned int pllctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) ret = regmap_write(tc->regmap, pllctrl, PLLUPDATE | PLLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) /* Wait for PLL to lock: up to 2.09 ms, depending on refclk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) usleep_range(3000, 6000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) static int tc_pxl_pll_en(struct tc_data *tc, u32 refclk, u32 pixelclock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) int i_pre, best_pre = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) int i_post, best_post = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) int div, best_div = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int mul, best_mul = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) int delta, best_delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) int ext_div[] = {1, 2, 3, 5, 7};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) int best_pixelclock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int vco_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) u32 pxl_pllparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) dev_dbg(tc->dev, "PLL: requested %d pixelclock, ref %d\n", pixelclock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) refclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) best_delta = pixelclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* Loop over all possible ext_divs, skipping invalid configurations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) for (i_pre = 0; i_pre < ARRAY_SIZE(ext_div); i_pre++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * refclk / ext_pre_div should be in the 1 to 200 MHz range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * We don't allow any refclk > 200 MHz, only check lower bounds.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) if (refclk / ext_div[i_pre] < 1000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) for (i_post = 0; i_post < ARRAY_SIZE(ext_div); i_post++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) for (div = 1; div <= 16; div++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) u32 clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) u64 tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) tmp = pixelclock * ext_div[i_pre] *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ext_div[i_post] * div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) do_div(tmp, refclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) mul = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /* Check limits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) if ((mul < 1) || (mul > 128))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) clk = (refclk / ext_div[i_pre] / div) * mul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * refclk * mul / (ext_pre_div * pre_div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * should be in the 150 to 650 MHz range
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if ((clk > 650000000) || (clk < 150000000))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) clk = clk / ext_div[i_post];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) delta = clk - pixelclock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (abs(delta) < abs(best_delta)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) best_pre = i_pre;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) best_post = i_post;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) best_div = div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) best_mul = mul;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) best_delta = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) best_pixelclock = clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (best_pixelclock == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) dev_err(tc->dev, "Failed to calc clock for %d pixelclock\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) pixelclock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) dev_dbg(tc->dev, "PLL: got %d, delta %d\n", best_pixelclock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) best_delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) dev_dbg(tc->dev, "PLL: %d / %d / %d * %d / %d\n", refclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ext_div[best_pre], best_div, best_mul, ext_div[best_post]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /* if VCO >= 300 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (refclk / ext_div[best_pre] / best_div * best_mul >= 300000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) vco_hi = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) /* see DS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (best_div == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) best_div = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (best_mul == 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) best_mul = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) /* Power up PLL and switch to bypass */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ret = regmap_write(tc->regmap, PXL_PLLCTRL, PLLBYP | PLLEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) pxl_pllparam = vco_hi << 24; /* For PLL VCO >= 300 MHz = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) pxl_pllparam |= ext_div[best_pre] << 20; /* External Pre-divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) pxl_pllparam |= ext_div[best_post] << 16; /* External Post-divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) pxl_pllparam |= IN_SEL_REFCLK; /* Use RefClk as PLL input */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) pxl_pllparam |= best_div << 8; /* Divider for PLL RefClk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) pxl_pllparam |= best_mul; /* Multiplier for PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) ret = regmap_write(tc->regmap, PXL_PLLPARAM, pxl_pllparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* Force PLL parameter update and disable bypass */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return tc_pllupdate(tc, PXL_PLLCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static int tc_pxl_pll_dis(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) /* Enable PLL bypass, power down PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) return regmap_write(tc->regmap, PXL_PLLCTRL, PLLBYP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static int tc_stream_clock_calc(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * If the Stream clock and Link Symbol clock are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * asynchronous with each other, the value of M changes over
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * time. This way of generating link clock and stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * clock is called Asynchronous Clock mode. The value M
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * must change while the value N stays constant. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * value of N in this Asynchronous Clock mode must be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * to 2^15 or 32,768.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * LSCLK = 1/10 of high speed link clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * f_STRMCLK = M/N * f_LSCLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * M/N = f_STRMCLK / f_LSCLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return regmap_write(tc->regmap, DP0_VIDMNGEN1, 32768);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static int tc_set_syspllparam(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) u32 pllparam = SYSCLK_SEL_LSCLK | LSCLK_DIV_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) rate = clk_get_rate(tc->refclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) switch (rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) case 38400000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) pllparam |= REF_FREQ_38M4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) case 26000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) pllparam |= REF_FREQ_26M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) case 19200000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) pllparam |= REF_FREQ_19M2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) case 13000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) pllparam |= REF_FREQ_13M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) dev_err(tc->dev, "Invalid refclk rate: %lu Hz\n", rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) return regmap_write(tc->regmap, SYS_PLLPARAM, pllparam);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static int tc_aux_link_setup(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) u32 dp0_auxcfg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /* Setup DP-PHY / PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) ret = tc_set_syspllparam(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ret = regmap_write(tc->regmap, DP_PHY_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) BGREN | PWR_SW_EN | PHY_A0_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * Initially PLLs are in bypass. Force PLL parameter update,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * disable PLL bypass, enable PLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) ret = tc_pllupdate(tc, DP0_PLLCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ret = tc_pllupdate(tc, DP1_PLLCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) ret = tc_poll_timeout(tc, DP_PHY_CTRL, PHY_RDY, PHY_RDY, 100, 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (ret == -ETIMEDOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) dev_err(tc->dev, "Timeout waiting for PHY to become ready");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) } else if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* Setup AUX link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) dp0_auxcfg1 = AUX_RX_FILTER_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) dp0_auxcfg1 |= 0x06 << 8; /* Aux Bit Period Calculator Threshold */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) dp0_auxcfg1 |= 0x3f << 0; /* Aux Response Timeout Timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ret = regmap_write(tc->regmap, DP0_AUXCFG1, dp0_auxcfg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) dev_err(tc->dev, "tc_aux_link_setup failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) static int tc_get_display_props(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) u8 revision, num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) unsigned int rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) u8 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /* Read DP Rx Link Capability */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ret = drm_dp_dpcd_read(&tc->aux, DP_DPCD_REV, tc->link.dpcd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) DP_RECEIVER_CAP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) goto err_dpcd_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) revision = tc->link.dpcd[DP_DPCD_REV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) rate = drm_dp_max_link_rate(tc->link.dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) num_lanes = drm_dp_max_lane_count(tc->link.dpcd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (rate != 162000 && rate != 270000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) dev_dbg(tc->dev, "Falling to 2.7 Gbps rate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) rate = 270000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) tc->link.rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) if (num_lanes > 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) dev_dbg(tc->dev, "Falling to 2 lanes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) num_lanes = 2;
^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) tc->link.num_lanes = num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) ret = drm_dp_dpcd_readb(&tc->aux, DP_MAX_DOWNSPREAD, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) goto err_dpcd_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) tc->link.spread = reg & DP_MAX_DOWNSPREAD_0_5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) ret = drm_dp_dpcd_readb(&tc->aux, DP_MAIN_LINK_CHANNEL_CODING, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) goto err_dpcd_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) tc->link.scrambler_dis = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* read assr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) ret = drm_dp_dpcd_readb(&tc->aux, DP_EDP_CONFIGURATION_SET, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) goto err_dpcd_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) tc->link.assr = reg & DP_ALTERNATE_SCRAMBLER_RESET_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) dev_dbg(tc->dev, "DPCD rev: %d.%d, rate: %s, lanes: %d, framing: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) revision >> 4, revision & 0x0f,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) (tc->link.rate == 162000) ? "1.62Gbps" : "2.7Gbps",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) tc->link.num_lanes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) drm_dp_enhanced_frame_cap(tc->link.dpcd) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) "enhanced" : "default");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) dev_dbg(tc->dev, "Downspread: %s, scrambler: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) tc->link.spread ? "0.5%" : "0.0%",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) tc->link.scrambler_dis ? "disabled" : "enabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) dev_dbg(tc->dev, "Display ASSR: %d, TC358767 ASSR: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) tc->link.assr, tc->assr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) err_dpcd_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) dev_err(tc->dev, "failed to read DPCD: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) static int tc_set_video_mode(struct tc_data *tc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) const struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) int vid_sync_dly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) int max_tu_symbol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) int left_margin = mode->htotal - mode->hsync_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) int right_margin = mode->hsync_start - mode->hdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) int hsync_len = mode->hsync_end - mode->hsync_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) int upper_margin = mode->vtotal - mode->vsync_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) int lower_margin = mode->vsync_start - mode->vdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) int vsync_len = mode->vsync_end - mode->vsync_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) u32 dp0_syncval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) u32 bits_per_pixel = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) u32 in_bw, out_bw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * Recommended maximum number of symbols transferred in a transfer unit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * DIV_ROUND_UP((input active video bandwidth in bytes) * tu_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * (output active video bandwidth in bytes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * Must be less than tu_size.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) in_bw = mode->clock * bits_per_pixel / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) out_bw = tc->link.num_lanes * tc->link.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) max_tu_symbol = DIV_ROUND_UP(in_bw * TU_SIZE_RECOMMENDED, out_bw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) dev_dbg(tc->dev, "set mode %dx%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) mode->hdisplay, mode->vdisplay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) dev_dbg(tc->dev, "H margin %d,%d sync %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) left_margin, right_margin, hsync_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) dev_dbg(tc->dev, "V margin %d,%d sync %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) upper_margin, lower_margin, vsync_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) dev_dbg(tc->dev, "total: %dx%d\n", mode->htotal, mode->vtotal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * LCD Ctl Frame Size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * datasheet is not clear of vsdelay in case of DPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * assume we do not need any delay when DPI is a source of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * sync signals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) ret = regmap_write(tc->regmap, VPCTRL0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) FIELD_PREP(VSDELAY, 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) OPXLFMT_RGB888 | FRMSYNC_DISABLED | MSF_DISABLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) ret = regmap_write(tc->regmap, HTIM01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) FIELD_PREP(HBPR, ALIGN(left_margin, 2)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) FIELD_PREP(HPW, ALIGN(hsync_len, 2)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ret = regmap_write(tc->regmap, HTIM02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) FIELD_PREP(HDISPR, ALIGN(mode->hdisplay, 2)) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) FIELD_PREP(HFPR, ALIGN(right_margin, 2)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) ret = regmap_write(tc->regmap, VTIM01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) FIELD_PREP(VBPR, upper_margin) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) FIELD_PREP(VSPR, vsync_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) ret = regmap_write(tc->regmap, VTIM02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) FIELD_PREP(VFPR, lower_margin) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) FIELD_PREP(VDISPR, mode->vdisplay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) ret = regmap_write(tc->regmap, VFUEN0, VFUEN); /* update settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) /* Test pattern settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) ret = regmap_write(tc->regmap, TSTCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) FIELD_PREP(COLOR_R, 120) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) FIELD_PREP(COLOR_G, 20) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) FIELD_PREP(COLOR_B, 99) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) ENI2CFILTER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) FIELD_PREP(COLOR_BAR_MODE, COLOR_BAR_MODE_BARS));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) /* DP Main Stream Attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) vid_sync_dly = hsync_len + left_margin + mode->hdisplay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) ret = regmap_write(tc->regmap, DP0_VIDSYNCDELAY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) FIELD_PREP(THRESH_DLY, max_tu_symbol) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) FIELD_PREP(VID_SYNC_DLY, vid_sync_dly));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) ret = regmap_write(tc->regmap, DP0_TOTALVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) FIELD_PREP(H_TOTAL, mode->htotal) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) FIELD_PREP(V_TOTAL, mode->vtotal));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (ret)
^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) ret = regmap_write(tc->regmap, DP0_STARTVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) FIELD_PREP(H_START, left_margin + hsync_len) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) FIELD_PREP(V_START, upper_margin + vsync_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ret = regmap_write(tc->regmap, DP0_ACTIVEVAL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) FIELD_PREP(V_ACT, mode->vdisplay) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) FIELD_PREP(H_ACT, mode->hdisplay));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) dp0_syncval = FIELD_PREP(VS_WIDTH, vsync_len) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) FIELD_PREP(HS_WIDTH, hsync_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (mode->flags & DRM_MODE_FLAG_NVSYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) dp0_syncval |= SYNCVAL_VS_POL_ACTIVE_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (mode->flags & DRM_MODE_FLAG_NHSYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) dp0_syncval |= SYNCVAL_HS_POL_ACTIVE_LOW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) ret = regmap_write(tc->regmap, DP0_SYNCVAL, dp0_syncval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) ret = regmap_write(tc->regmap, DPIPXLFMT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) VS_POL_ACTIVE_LOW | HS_POL_ACTIVE_LOW |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) DE_POL_ACTIVE_HIGH | SUB_CFG_TYPE_CONFIG1 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) DPI_BPP_RGB888);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ret = regmap_write(tc->regmap, DP0_MISC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) FIELD_PREP(MAX_TU_SYMBOL, max_tu_symbol) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) FIELD_PREP(TU_SIZE, TU_SIZE_RECOMMENDED) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) BPC_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) static int tc_wait_link_training(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ret = tc_poll_timeout(tc, DP0_LTSTAT, LT_LOOPDONE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) LT_LOOPDONE, 500, 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) dev_err(tc->dev, "Link training timeout waiting for LT_LOOPDONE!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) ret = regmap_read(tc->regmap, DP0_LTSTAT, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return (value >> 8) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static int tc_main_link_enable(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct drm_dp_aux *aux = &tc->aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct device *dev = tc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) u32 dp_phy_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) u8 tmp[DP_LINK_STATUS_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) dev_dbg(tc->dev, "link enable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ret = regmap_read(tc->regmap, DP0CTL, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (WARN_ON(value & DP_EN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ret = regmap_write(tc->regmap, DP0CTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) ret = regmap_write(tc->regmap, DP0_SRCCTRL, tc_srcctrl(tc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) /* SSCG and BW27 on DP1 must be set to the same as on DP0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) ret = regmap_write(tc->regmap, DP1_SRCCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) (tc->link.spread ? DP0_SRCCTRL_SSCG : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ((tc->link.rate != 162000) ? DP0_SRCCTRL_BW27 : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) ret = tc_set_syspllparam(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /* Setup Main Link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) dp_phy_ctrl = BGREN | PWR_SW_EN | PHY_A0_EN | PHY_M0_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (tc->link.num_lanes == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) dp_phy_ctrl |= PHY_2LANE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) ret = regmap_write(tc->regmap, DP_PHY_CTRL, dp_phy_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) /* PLL setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) ret = tc_pllupdate(tc, DP0_PLLCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ret = tc_pllupdate(tc, DP1_PLLCTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) /* Reset/Enable Main Links */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) dp_phy_ctrl |= DP_PHY_RST | PHY_M1_RST | PHY_M0_RST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ret = regmap_write(tc->regmap, DP_PHY_CTRL, dp_phy_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) usleep_range(100, 200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) dp_phy_ctrl &= ~(DP_PHY_RST | PHY_M1_RST | PHY_M0_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) ret = regmap_write(tc->regmap, DP_PHY_CTRL, dp_phy_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) ret = tc_poll_timeout(tc, DP_PHY_CTRL, PHY_RDY, PHY_RDY, 500, 100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) dev_err(dev, "timeout waiting for phy become ready");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) /* Set misc: 8 bits per color */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) ret = regmap_update_bits(tc->regmap, DP0_MISC, BPC_8, BPC_8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * ASSR mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * on TC358767 side ASSR configured through strap pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * seems there is no way to change this setting from SW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) * check is tc configured for same mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (tc->assr != tc->link.assr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) dev_dbg(dev, "Trying to set display to ASSR: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) tc->assr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* try to set ASSR on display side */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) tmp[0] = tc->assr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) ret = drm_dp_dpcd_writeb(aux, DP_EDP_CONFIGURATION_SET, tmp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) goto err_dpcd_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) /* read back */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) ret = drm_dp_dpcd_readb(aux, DP_EDP_CONFIGURATION_SET, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) goto err_dpcd_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) if (tmp[0] != tc->assr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) dev_dbg(dev, "Failed to switch display ASSR to %d, falling back to unscrambled mode\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) tc->assr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) /* trying with disabled scrambler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) tc->link.scrambler_dis = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /* Setup Link & DPRx Config for Training */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) tmp[0] = drm_dp_link_rate_to_bw_code(tc->link.rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) tmp[1] = tc->link.num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (drm_dp_enhanced_frame_cap(tc->link.dpcd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) tmp[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) ret = drm_dp_dpcd_write(aux, DP_LINK_BW_SET, tmp, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) goto err_dpcd_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /* DOWNSPREAD_CTRL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) tmp[0] = tc->link.spread ? DP_SPREAD_AMP_0_5 : 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) /* MAIN_LINK_CHANNEL_CODING_SET */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) tmp[1] = DP_SET_ANSI_8B10B;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) ret = drm_dp_dpcd_write(aux, DP_DOWNSPREAD_CTRL, tmp, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) goto err_dpcd_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* Reset voltage-swing & pre-emphasis */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) tmp[0] = tmp[1] = DP_TRAIN_VOLTAGE_SWING_LEVEL_0 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) DP_TRAIN_PRE_EMPH_LEVEL_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) ret = drm_dp_dpcd_write(aux, DP_TRAINING_LANE0_SET, tmp, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) goto err_dpcd_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* Clock-Recovery */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) /* Set DPCD 0x102 for Training Pattern 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) ret = regmap_write(tc->regmap, DP0_SNKLTCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) DP_LINK_SCRAMBLING_DISABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) DP_TRAINING_PATTERN_1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) ret = regmap_write(tc->regmap, DP0_LTLOOPCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) (15 << 28) | /* Defer Iteration Count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) (15 << 24) | /* Loop Iteration Count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) (0xd << 0)); /* Loop Timer Delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) ret = regmap_write(tc->regmap, DP0_SRCCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) tc_srcctrl(tc) | DP0_SRCCTRL_SCRMBLDIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) DP0_SRCCTRL_AUTOCORRECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) DP0_SRCCTRL_TP1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* Enable DP0 to start Link Training */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) ret = regmap_write(tc->regmap, DP0CTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) (drm_dp_enhanced_frame_cap(tc->link.dpcd) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) EF_EN : 0) | DP_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /* wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) ret = tc_wait_link_training(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) dev_err(tc->dev, "Link training phase 1 failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) training_pattern1_errors[ret]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) /* Channel Equalization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /* Set DPCD 0x102 for Training Pattern 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) ret = regmap_write(tc->regmap, DP0_SNKLTCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) DP_LINK_SCRAMBLING_DISABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) DP_TRAINING_PATTERN_2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) ret = regmap_write(tc->regmap, DP0_SRCCTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) tc_srcctrl(tc) | DP0_SRCCTRL_SCRMBLDIS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) DP0_SRCCTRL_AUTOCORRECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) DP0_SRCCTRL_TP2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ret = tc_wait_link_training(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) dev_err(tc->dev, "Link training phase 2 failed: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) training_pattern2_errors[ret]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * Toshiba's documentation suggests to first clear DPCD 0x102, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) * clear the training pattern bit in DP0_SRCCTRL. Testing shows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) * that the link sometimes drops if those steps are done in that order,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) * but if the steps are done in reverse order, the link stays up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * So we do the steps differently than documented here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) /* Clear Training Pattern, set AutoCorrect Mode = 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) ret = regmap_write(tc->regmap, DP0_SRCCTRL, tc_srcctrl(tc) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) DP0_SRCCTRL_AUTOCORRECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) /* Clear DPCD 0x102 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) /* Note: Can Not use DP0_SNKLTCTRL (0x06E4) short cut */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) tmp[0] = tc->link.scrambler_dis ? DP_LINK_SCRAMBLING_DISABLE : 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) ret = drm_dp_dpcd_writeb(aux, DP_TRAINING_PATTERN_SET, tmp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) goto err_dpcd_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) /* Check link status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) ret = drm_dp_dpcd_read_link_status(aux, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) goto err_dpcd_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) value = tmp[0] & DP_CHANNEL_EQ_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (value != DP_CHANNEL_EQ_BITS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) dev_err(tc->dev, "Lane 0 failed: %x\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (tc->link.num_lanes == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) value = (tmp[0] >> 4) & DP_CHANNEL_EQ_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (value != DP_CHANNEL_EQ_BITS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) dev_err(tc->dev, "Lane 1 failed: %x\n", value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) if (!(tmp[2] & DP_INTERLANE_ALIGN_DONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) dev_err(tc->dev, "Interlane align failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) ret = -ENODEV;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) dev_err(dev, "0x0202 LANE0_1_STATUS: 0x%02x\n", tmp[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) dev_err(dev, "0x0203 LANE2_3_STATUS 0x%02x\n", tmp[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) dev_err(dev, "0x0204 LANE_ALIGN_STATUS_UPDATED: 0x%02x\n", tmp[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) dev_err(dev, "0x0205 SINK_STATUS: 0x%02x\n", tmp[3]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) dev_err(dev, "0x0206 ADJUST_REQUEST_LANE0_1: 0x%02x\n", tmp[4]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) dev_err(dev, "0x0207 ADJUST_REQUEST_LANE2_3: 0x%02x\n", tmp[5]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) err_dpcd_read:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) dev_err(tc->dev, "Failed to read DPCD: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) err_dpcd_write:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) dev_err(tc->dev, "Failed to write DPCD: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) return ret;
^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) static int tc_main_link_disable(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) dev_dbg(tc->dev, "link disable\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ret = regmap_write(tc->regmap, DP0_SRCCTRL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) return regmap_write(tc->regmap, DP0CTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) static int tc_stream_enable(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) dev_dbg(tc->dev, "enable video stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) /* PXL PLL setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (tc_test_pattern) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) ret = tc_pxl_pll_en(tc, clk_get_rate(tc->refclk),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 1000 * tc->mode.clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) ret = tc_set_video_mode(tc, &tc->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /* Set M/N */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) ret = tc_stream_clock_calc(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) value = VID_MN_GEN | DP_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) if (drm_dp_enhanced_frame_cap(tc->link.dpcd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) value |= EF_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) ret = regmap_write(tc->regmap, DP0CTL, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) * VID_EN assertion should be delayed by at least N * LSCLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * cycles from the time VID_MN_GEN is enabled in order to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) * generate stable values for VID_M. LSCLK is 270 MHz or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) * 162 MHz, VID_N is set to 32768 in tc_stream_clock_calc(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) * so a delay of at least 203 us should suffice.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) usleep_range(500, 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) value |= VID_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) ret = regmap_write(tc->regmap, DP0CTL, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) /* Set input interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) value = DP0_AUDSRC_NO_INPUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) if (tc_test_pattern)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) value |= DP0_VIDSRC_COLOR_BAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) value |= DP0_VIDSRC_DPI_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) ret = regmap_write(tc->regmap, SYSCTRL, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) static int tc_stream_disable(struct tc_data *tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) dev_dbg(tc->dev, "disable video stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) ret = regmap_update_bits(tc->regmap, DP0CTL, VID_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) tc_pxl_pll_dis(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static void tc_bridge_enable(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) struct tc_data *tc = bridge_to_tc(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) ret = tc_get_display_props(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) dev_err(tc->dev, "failed to read display props: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ret = tc_main_link_enable(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) dev_err(tc->dev, "main link enable error: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) ret = tc_stream_enable(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) dev_err(tc->dev, "main link stream start error: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) tc_main_link_disable(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) static void tc_bridge_disable(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) struct tc_data *tc = bridge_to_tc(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) ret = tc_stream_disable(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) dev_err(tc->dev, "main link stream stop error: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) ret = tc_main_link_disable(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) dev_err(tc->dev, "main link disable error: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) const struct drm_display_mode *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) struct drm_display_mode *adj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) /* Fixup sync polarities, both hsync and vsync are active low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) adj->flags = mode->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) adj->flags |= (DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) adj->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) static enum drm_mode_status tc_mode_valid(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) const struct drm_display_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) const struct drm_display_mode *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) struct tc_data *tc = bridge_to_tc(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) u32 req, avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) u32 bits_per_pixel = 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) /* DPI interface clock limitation: upto 154 MHz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (mode->clock > 154000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return MODE_CLOCK_HIGH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) req = mode->clock * bits_per_pixel / 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) avail = tc->link.num_lanes * tc->link.rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (req > avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) return MODE_BAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return MODE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) static void tc_bridge_mode_set(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) const struct drm_display_mode *mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) const struct drm_display_mode *adj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) struct tc_data *tc = bridge_to_tc(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) tc->mode = *mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) static struct edid *tc_get_edid(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) struct tc_data *tc = bridge_to_tc(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) return drm_get_edid(connector, &tc->aux.ddc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) static int tc_connector_get_modes(struct drm_connector *connector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) struct tc_data *tc = connector_to_tc(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) int num_modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) struct edid *edid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ret = tc_get_display_props(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) dev_err(tc->dev, "failed to read display props: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) if (tc->panel_bridge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) num_modes = drm_bridge_get_modes(tc->panel_bridge, connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (num_modes > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return num_modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) edid = tc_get_edid(&tc->bridge, connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) num_modes = drm_add_edid_modes(connector, edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) kfree(edid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) return num_modes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static const struct drm_connector_helper_funcs tc_connector_helper_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) .get_modes = tc_connector_get_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) static enum drm_connector_status tc_bridge_detect(struct drm_bridge *bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) struct tc_data *tc = bridge_to_tc(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) bool conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) ret = regmap_read(tc->regmap, GPIOI, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) return connector_status_unknown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) conn = val & BIT(tc->hpd_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) if (conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) return connector_status_connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return connector_status_disconnected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) static enum drm_connector_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) tc_connector_detect(struct drm_connector *connector, bool force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) struct tc_data *tc = connector_to_tc(connector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) if (tc->hpd_pin >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) return tc_bridge_detect(&tc->bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (tc->panel_bridge)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return connector_status_connected;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) return connector_status_unknown;
^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 const struct drm_connector_funcs tc_connector_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) .detect = tc_connector_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) .fill_modes = drm_helper_probe_single_connector_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) .destroy = drm_connector_cleanup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) .reset = drm_atomic_helper_connector_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) static int tc_bridge_attach(struct drm_bridge *bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) enum drm_bridge_attach_flags flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) struct tc_data *tc = bridge_to_tc(bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) struct drm_device *drm = bridge->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (tc->panel_bridge) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) /* If a connector is required then this driver shall create it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) ret = drm_bridge_attach(tc->bridge.encoder, tc->panel_bridge,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) &tc->bridge, flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return ret;
^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) if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) /* Create DP/eDP connector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) drm_connector_helper_add(&tc->connector, &tc_connector_helper_funcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) ret = drm_connector_init(drm, &tc->connector, &tc_connector_funcs, tc->bridge.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) /* Don't poll if don't have HPD connected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) if (tc->hpd_pin >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (tc->have_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) tc->connector.polled = DRM_CONNECTOR_POLL_HPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) tc->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) DRM_CONNECTOR_POLL_DISCONNECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) drm_display_info_set_bus_formats(&tc->connector.display_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) &bus_format, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) tc->connector.display_info.bus_flags =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) DRM_BUS_FLAG_DE_HIGH |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) drm_connector_attach_encoder(&tc->connector, tc->bridge.encoder);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) static const struct drm_bridge_funcs tc_bridge_funcs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) .attach = tc_bridge_attach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) .mode_valid = tc_mode_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .mode_set = tc_bridge_mode_set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) .enable = tc_bridge_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) .disable = tc_bridge_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) .mode_fixup = tc_bridge_mode_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) .detect = tc_bridge_detect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) .get_edid = tc_get_edid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) static bool tc_readable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) return reg != SYSCTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) static const struct regmap_range tc_volatile_ranges[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) regmap_reg_range(DP0_AUXWDATA(0), DP0_AUXSTATUS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) regmap_reg_range(DP0_LTSTAT, DP0_SNKLTCHGREQ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) regmap_reg_range(DP_PHY_CTRL, DP_PHY_CTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) regmap_reg_range(DP0_PLLCTRL, PXL_PLLCTRL),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) regmap_reg_range(VFUEN0, VFUEN0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) regmap_reg_range(INTSTS_G, INTSTS_G),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) regmap_reg_range(GPIOI, GPIOI),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) static const struct regmap_access_table tc_volatile_table = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) .yes_ranges = tc_volatile_ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) .n_yes_ranges = ARRAY_SIZE(tc_volatile_ranges),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) static bool tc_writeable_reg(struct device *dev, unsigned int reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) return (reg != TC_IDREG) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) (reg != DP0_LTSTAT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) (reg != DP0_SNKLTCHGREQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) static const struct regmap_config tc_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) .name = "tc358767",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) .reg_bits = 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) .max_register = PLL_DBG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) .cache_type = REGCACHE_RBTREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) .readable_reg = tc_readable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) .volatile_table = &tc_volatile_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) .writeable_reg = tc_writeable_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) .reg_format_endian = REGMAP_ENDIAN_BIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) .val_format_endian = REGMAP_ENDIAN_LITTLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) static irqreturn_t tc_irq_handler(int irq, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) struct tc_data *tc = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) r = regmap_read(tc->regmap, INTSTS_G, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) if (val & INT_SYSERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) u32 stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) regmap_read(tc->regmap, SYSSTAT, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) dev_err(tc->dev, "syserr %x\n", stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (tc->hpd_pin >= 0 && tc->bridge.dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) * H is triggered when the GPIO goes high.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) * LC is triggered when the GPIO goes low and stays low for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) * the duration of LCNT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) bool h = val & INT_GPIO_H(tc->hpd_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) bool lc = val & INT_GPIO_LC(tc->hpd_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) dev_dbg(tc->dev, "GPIO%d: %s %s\n", tc->hpd_pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) h ? "H" : "", lc ? "LC" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (h || lc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) drm_kms_helper_hotplug_event(tc->bridge.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) regmap_write(tc->regmap, INTSTS_G, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) return IRQ_HANDLED;
^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) static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) struct device *dev = &client->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) struct drm_panel *panel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) struct tc_data *tc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) tc = devm_kzalloc(dev, sizeof(*tc), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) if (!tc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) tc->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) /* port@2 is the output port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &panel, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (ret && ret != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (panel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) struct drm_bridge *panel_bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) panel_bridge = devm_drm_panel_bridge_add(dev, panel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if (IS_ERR(panel_bridge))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) return PTR_ERR(panel_bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) tc->panel_bridge = panel_bridge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) tc->bridge.type = DRM_MODE_CONNECTOR_eDP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) tc->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
^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) /* Shut down GPIO is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) tc->sd_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) if (IS_ERR(tc->sd_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) return PTR_ERR(tc->sd_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) if (tc->sd_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) gpiod_set_value_cansleep(tc->sd_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) usleep_range(5000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) /* Reset GPIO is optional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) tc->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) if (IS_ERR(tc->reset_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return PTR_ERR(tc->reset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if (tc->reset_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) gpiod_set_value_cansleep(tc->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) usleep_range(5000, 10000);
^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) tc->refclk = devm_clk_get(dev, "ref");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) if (IS_ERR(tc->refclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) ret = PTR_ERR(tc->refclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) dev_err(dev, "Failed to get refclk: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) tc->regmap = devm_regmap_init_i2c(client, &tc_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) if (IS_ERR(tc->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) ret = PTR_ERR(tc->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) dev_err(dev, "Failed to initialize regmap: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) return ret;
^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) ret = of_property_read_u32(dev->of_node, "toshiba,hpd-pin",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) &tc->hpd_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) tc->hpd_pin = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (tc->hpd_pin < 0 || tc->hpd_pin > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) dev_err(dev, "failed to parse HPD number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) if (client->irq > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) /* enable SysErr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) regmap_write(tc->regmap, INTCTL_G, INT_SYSERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) ret = devm_request_threaded_irq(dev, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) NULL, tc_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) "tc358767-irq", tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) dev_err(dev, "failed to register dp interrupt\n");
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) tc->have_irq = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) ret = regmap_read(tc->regmap, TC_IDREG, &tc->rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) dev_err(tc->dev, "can not read device ID: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) if ((tc->rev != 0x6601) && (tc->rev != 0x6603)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) dev_err(tc->dev, "invalid device ID: 0x%08x\n", tc->rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) tc->assr = (tc->rev == 0x6601); /* Enable ASSR for eDP panels */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (!tc->reset_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) * If the reset pin isn't present, do a software reset. It isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) * as thorough as the hardware reset, as we can't reset the I2C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) * communication block for obvious reasons, but it's getting the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) * chip into a defined state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) regmap_update_bits(tc->regmap, SYSRSTENB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) ENBLCD0 | ENBBM | ENBDSIRX | ENBREG | ENBHDCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) regmap_update_bits(tc->regmap, SYSRSTENB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) ENBLCD0 | ENBBM | ENBDSIRX | ENBREG | ENBHDCP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) ENBLCD0 | ENBBM | ENBDSIRX | ENBREG | ENBHDCP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) usleep_range(5000, 10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) if (tc->hpd_pin >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) u32 lcnt_reg = tc->hpd_pin == 0 ? INT_GP0_LCNT : INT_GP1_LCNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) u32 h_lc = INT_GPIO_H(tc->hpd_pin) | INT_GPIO_LC(tc->hpd_pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) /* Set LCNT to 2ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) regmap_write(tc->regmap, lcnt_reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) clk_get_rate(tc->refclk) * 2 / 1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) /* We need the "alternate" mode for HPD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) regmap_write(tc->regmap, GPIOM, BIT(tc->hpd_pin));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) if (tc->have_irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) /* enable H & LC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) regmap_update_bits(tc->regmap, INTCTL_G, h_lc, h_lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) ret = tc_aux_link_setup(tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) /* Register DP AUX channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) tc->aux.name = "TC358767 AUX i2c adapter";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) tc->aux.dev = tc->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) tc->aux.transfer = tc_aux_transfer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) ret = drm_dp_aux_register(&tc->aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) tc->bridge.funcs = &tc_bridge_funcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) if (tc->hpd_pin >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) tc->bridge.ops |= DRM_BRIDGE_OP_DETECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) tc->bridge.ops |= DRM_BRIDGE_OP_EDID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) tc->bridge.of_node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) drm_bridge_add(&tc->bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) i2c_set_clientdata(client, tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) static int tc_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) struct tc_data *tc = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) drm_bridge_remove(&tc->bridge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) drm_dp_aux_unregister(&tc->aux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) static const struct i2c_device_id tc358767_i2c_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) { "tc358767", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) MODULE_DEVICE_TABLE(i2c, tc358767_i2c_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) static const struct of_device_id tc358767_of_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) { .compatible = "toshiba,tc358767", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) MODULE_DEVICE_TABLE(of, tc358767_of_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) static struct i2c_driver tc358767_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) .name = "tc358767",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) .of_match_table = tc358767_of_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) .id_table = tc358767_i2c_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) .probe = tc_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) .remove = tc_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) module_i2c_driver(tc358767_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) MODULE_AUTHOR("Andrey Gusakov <andrey.gusakov@cogentembedded.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) MODULE_DESCRIPTION("tc358767 eDP encoder driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) MODULE_LICENSE("GPL");