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

Merge branch 'drm-next-analogix-dp-v2' of github.com:yakir-Yang/linux into drm-next

This pull request want to land the analogix_dp driver into drm/bridge directory,
which reused the Exynos DP code, and add Rockchip DP support. And those
patches have been:

* 'drm-next-analogix-dp-v2' of github.com:yakir-Yang/linux:
drm: bridge: analogix/dp: Fix the possible dead lock in bridge disable time
drm: bridge: analogix/dp: add panel prepare/unprepare in suspend/resume time
drm: bridge: analogix/dp: add edid modes parse in get_modes method
drm: bridge: analogix/dp: move hpd detect to connector detect function
drm: bridge: analogix/dp: try force hpd after plug in lookup failed
drm: bridge: analogix/dp: add max link rate and lane count limit for RK3288
drm: bridge: analogix/dp: add some rk3288 special registers setting
dt-bindings: add document for rockchip variant of analogix_dp
drm: rockchip: dp: add rockchip platform dp driver
ARM: dts: exynos/dp: remove some properties that deprecated by analogix_dp driver
dt-bindings: add document for analogix display port driver
drm: bridge: analogix/dp: dynamic parse sync_pol & interlace & dynamic_range
drm: bridge: analogix/dp: remove duplicate configuration of link rate and link count
drm: bridge: analogix/dp: fix some obvious code style
drm: bridge: analogix/dp: rename register constants
drm/exynos: dp: rename implementation specific driver part
drm: bridge: analogix/dp: split exynos dp driver to bridge directory

+4087 -3239
+52
Documentation/devicetree/bindings/display/bridge/analogix_dp.txt
··· 1 + Analogix Display Port bridge bindings 2 + 3 + Required properties for dp-controller: 4 + -compatible: 5 + platform specific such as: 6 + * "samsung,exynos5-dp" 7 + * "rockchip,rk3288-dp" 8 + -reg: 9 + physical base address of the controller and length 10 + of memory mapped region. 11 + -interrupts: 12 + interrupt combiner values. 13 + -clocks: 14 + from common clock binding: handle to dp clock. 15 + -clock-names: 16 + from common clock binding: Shall be "dp". 17 + -interrupt-parent: 18 + phandle to Interrupt combiner node. 19 + -phys: 20 + from general PHY binding: the phandle for the PHY device. 21 + -phy-names: 22 + from general PHY binding: Should be "dp". 23 + 24 + Optional properties for dp-controller: 25 + -force-hpd: 26 + Indicate driver need force hpd when hpd detect failed, this 27 + is used for some eDP screen which don't have hpd signal. 28 + -hpd-gpios: 29 + Hotplug detect GPIO. 30 + Indicates which GPIO should be used for hotplug detection 31 + -port@[X]: SoC specific port nodes with endpoint definitions as defined 32 + in Documentation/devicetree/bindings/media/video-interfaces.txt, 33 + please refer to the SoC specific binding document: 34 + * Documentation/devicetree/bindings/display/exynos/exynos_dp.txt 35 + * Documentation/devicetree/bindings/video/analogix_dp-rockchip.txt 36 + 37 + [1]: Documentation/devicetree/bindings/media/video-interfaces.txt 38 + ------------------------------------------------------------------------------- 39 + 40 + Example: 41 + 42 + dp-controller { 43 + compatible = "samsung,exynos5-dp"; 44 + reg = <0x145b0000 0x10000>; 45 + interrupts = <10 3>; 46 + interrupt-parent = <&combiner>; 47 + clocks = <&clock 342>; 48 + clock-names = "dp"; 49 + 50 + phys = <&dp_phy>; 51 + phy-names = "dp"; 52 + };
+25 -64
Documentation/devicetree/bindings/display/exynos/exynos_dp.txt
··· 1 - Device-Tree bindings for Samsung Exynos Embedded DisplayPort Transmitter(eDP) 2 - 3 - DisplayPort is industry standard to accommodate the growing board adoption 4 - of digital display technology within the PC and CE industries. 5 - It consolidates the internal and external connection methods to reduce device 6 - complexity and cost. It also supports necessary features for important cross 7 - industry applications and provides performance scalability to enable the next 8 - generation of displays that feature higher color depths, refresh rates, and 9 - display resolutions. 10 - 11 - eDP (embedded display port) device is compliant with Embedded DisplayPort 12 - standard as follows, 13 - - DisplayPort standard 1.1a for Exynos5250 and Exynos5260. 14 - - DisplayPort standard 1.3 for Exynos5422s and Exynos5800. 15 - 16 - eDP resides between FIMD and panel or FIMD and bridge such as LVDS. 17 - 18 1 The Exynos display port interface should be configured based on 19 2 the type of panel connected to it. 20 3 ··· 31 48 from general PHY binding: the phandle for the PHY device. 32 49 -phy-names: 33 50 from general PHY binding: Should be "dp". 34 - -samsung,color-space: 35 - input video data format. 36 - COLOR_RGB = 0, COLOR_YCBCR422 = 1, COLOR_YCBCR444 = 2 37 - -samsung,dynamic-range: 38 - dynamic range for input video data. 39 - VESA = 0, CEA = 1 40 - -samsung,ycbcr-coeff: 41 - YCbCr co-efficients for input video. 42 - COLOR_YCBCR601 = 0, COLOR_YCBCR709 = 1 43 - -samsung,color-depth: 44 - number of bits per colour component. 45 - COLOR_6 = 0, COLOR_8 = 1, COLOR_10 = 2, COLOR_12 = 3 46 - -samsung,link-rate: 47 - link rate supported by the panel. 48 - LINK_RATE_1_62GBPS = 0x6, LINK_RATE_2_70GBPS = 0x0A 49 - -samsung,lane-count: 50 - number of lanes supported by the panel. 51 - LANE_COUNT1 = 1, LANE_COUNT2 = 2, LANE_COUNT4 = 4 52 - - display-timings: timings for the connected panel as described by 53 - Documentation/devicetree/bindings/display/display-timing.txt 54 51 55 52 Optional properties for dp-controller: 56 53 -interlaced: ··· 46 83 Hotplug detect GPIO. 47 84 Indicates which GPIO should be used for hotplug 48 85 detection 49 - Video interfaces: 50 - Device node can contain video interface port nodes according to [1]. 51 - The following are properties specific to those nodes: 86 + -video interfaces: Device node can contain video interface port 87 + nodes according to [1]. 88 + - display-timings: timings for the connected panel as described by 89 + Documentation/devicetree/bindings/display/panel/display-timing.txt 52 90 53 - endpoint node connected to bridge or panel node: 54 - - remote-endpoint: specifies the endpoint in panel or bridge node. 55 - This node is required in all kinds of exynos dp 56 - to represent the connection between dp and bridge 57 - or dp and panel. 91 + For the below properties, please refer to Analogix DP binding document: 92 + * Documentation/devicetree/bindings/display/bridge/analogix_dp.txt 93 + -phys (required) 94 + -phy-names (required) 95 + -hpd-gpios (optional) 96 + force-hpd (optional) 58 97 59 - [1]: Documentation/devicetree/bindings/media/video-interfaces.txt 98 + Deprecated properties for DisplayPort: 99 + -interlaced: deprecated prop that can parsed from drm_display_mode. 100 + -vsync-active-high: deprecated prop that can parsed from drm_display_mode. 101 + -hsync-active-high: deprecated prop that can parsed from drm_display_mode. 102 + -samsung,ycbcr-coeff: deprecated prop that can parsed from drm_display_mode. 103 + -samsung,dynamic-range: deprecated prop that can parsed from drm_display_mode. 104 + -samsung,color-space: deprecated prop that can parsed from drm_display_info. 105 + -samsung,color-depth: deprecated prop that can parsed from drm_display_info. 106 + -samsung,link-rate: deprecated prop that can reading from monitor by dpcd method. 107 + -samsung,lane-count: deprecated prop that can reading from monitor by dpcd method. 108 + -samsung,hpd-gpio: deprecated name for hpd-gpios. 109 + 110 + ------------------------------------------------------------------------------- 60 111 61 112 Example: 62 113 ··· 89 112 90 113 Board Specific portion: 91 114 dp-controller { 92 - samsung,color-space = <0>; 93 - samsung,dynamic-range = <0>; 94 - samsung,ycbcr-coeff = <0>; 95 - samsung,color-depth = <1>; 96 - samsung,link-rate = <0x0a>; 97 - samsung,lane-count = <4>; 98 - 99 115 display-timings { 100 116 native-mode = <&lcd_timing>; 101 117 lcd_timing: 1366x768 { ··· 105 135 }; 106 136 107 137 ports { 108 - port { 138 + port@0 { 109 139 dp_out: endpoint { 110 - remote-endpoint = <&dp_in>; 111 - }; 112 - }; 113 - }; 114 - 115 - panel { 116 - ... 117 - port { 118 - dp_in: endpoint { 119 - remote-endpoint = <&dp_out>; 140 + remote-endpoint = <&bridge_in>; 120 141 }; 121 142 }; 122 143 };
+92
Documentation/devicetree/bindings/display/rockchip/analogix_dp-rockchip.txt
··· 1 + Rockchip RK3288 specific extensions to the Analogix Display Port 2 + ================================ 3 + 4 + Required properties: 5 + - compatible: "rockchip,rk3288-edp"; 6 + 7 + - reg: physical base address of the controller and length 8 + 9 + - clocks: from common clock binding: handle to dp clock. 10 + of memory mapped region. 11 + 12 + - clock-names: from common clock binding: 13 + Required elements: "dp" "pclk" 14 + 15 + - resets: Must contain an entry for each entry in reset-names. 16 + See ../reset/reset.txt for details. 17 + 18 + - pinctrl-names: Names corresponding to the chip hotplug pinctrl states. 19 + - pinctrl-0: pin-control mode. should be <&edp_hpd> 20 + 21 + - reset-names: Must include the name "dp" 22 + 23 + - rockchip,grf: this soc should set GRF regs, so need get grf here. 24 + 25 + - ports: there are 2 port nodes with endpoint definitions as defined in 26 + Documentation/devicetree/bindings/media/video-interfaces.txt. 27 + Port 0: contained 2 endpoints, connecting to the output of vop. 28 + Port 1: contained 1 endpoint, connecting to the input of panel. 29 + 30 + For the below properties, please refer to Analogix DP binding document: 31 + * Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt 32 + - phys (required) 33 + - phy-names (required) 34 + - hpd-gpios (optional) 35 + - force-hpd (optional) 36 + ------------------------------------------------------------------------------- 37 + 38 + Example: 39 + dp-controller: dp@ff970000 { 40 + compatible = "rockchip,rk3288-dp"; 41 + reg = <0xff970000 0x4000>; 42 + interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; 43 + clocks = <&cru SCLK_EDP>, <&cru PCLK_EDP_CTRL>; 44 + clock-names = "dp", "pclk"; 45 + phys = <&dp_phy>; 46 + phy-names = "dp"; 47 + 48 + rockchip,grf = <&grf>; 49 + resets = <&cru 111>; 50 + reset-names = "dp"; 51 + 52 + pinctrl-names = "default"; 53 + pinctrl-0 = <&edp_hpd>; 54 + 55 + status = "disabled"; 56 + 57 + ports { 58 + #address-cells = <1>; 59 + #size-cells = <0>; 60 + edp_in: port@0 { 61 + reg = <0>; 62 + #address-cells = <1>; 63 + #size-cells = <0>; 64 + edp_in_vopb: endpoint@0 { 65 + reg = <0>; 66 + remote-endpoint = <&vopb_out_edp>; 67 + }; 68 + edp_in_vopl: endpoint@1 { 69 + reg = <1>; 70 + remote-endpoint = <&vopl_out_edp>; 71 + }; 72 + }; 73 + 74 + edp_out: port@1 { 75 + reg = <1>; 76 + #address-cells = <1>; 77 + #size-cells = <0>; 78 + edp_out_panel: endpoint { 79 + reg = <0>; 80 + remote-endpoint = <&panel_in_edp> 81 + }; 82 + }; 83 + }; 84 + }; 85 + 86 + pinctrl { 87 + edp { 88 + edp_hpd: edp-hpd { 89 + rockchip,pins = <7 11 RK_FUNC_2 &pcfg_pull_none>; 90 + }; 91 + }; 92 + };
-2
arch/arm/boot/dts/exynos5250-arndale.dts
··· 124 124 &dp { 125 125 status = "okay"; 126 126 samsung,color-space = <0>; 127 - samsung,dynamic-range = <0>; 128 - samsung,ycbcr-coeff = <0>; 129 127 samsung,color-depth = <1>; 130 128 samsung,link-rate = <0x0a>; 131 129 samsung,lane-count = <4>;
-2
arch/arm/boot/dts/exynos5250-smdk5250.dts
··· 80 80 81 81 &dp { 82 82 samsung,color-space = <0>; 83 - samsung,dynamic-range = <0>; 84 - samsung,ycbcr-coeff = <0>; 85 83 samsung,color-depth = <1>; 86 84 samsung,link-rate = <0x0a>; 87 85 samsung,lane-count = <4>;
+1 -3
arch/arm/boot/dts/exynos5250-snow-common.dtsi
··· 236 236 pinctrl-names = "default"; 237 237 pinctrl-0 = <&dp_hpd>; 238 238 samsung,color-space = <0>; 239 - samsung,dynamic-range = <0>; 240 - samsung,ycbcr-coeff = <0>; 241 239 samsung,color-depth = <1>; 242 240 samsung,link-rate = <0x0a>; 243 241 samsung,lane-count = <2>; 244 - samsung,hpd-gpio = <&gpx0 7 GPIO_ACTIVE_HIGH>; 242 + hpd-gpios = <&gpx0 7 GPIO_ACTIVE_HIGH>; 245 243 246 244 ports { 247 245 port@0 {
+1 -3
arch/arm/boot/dts/exynos5250-spring.dts
··· 74 74 pinctrl-names = "default"; 75 75 pinctrl-0 = <&dp_hpd_gpio>; 76 76 samsung,color-space = <0>; 77 - samsung,dynamic-range = <0>; 78 - samsung,ycbcr-coeff = <0>; 79 77 samsung,color-depth = <1>; 80 78 samsung,link-rate = <0x0a>; 81 79 samsung,lane-count = <1>; 82 - samsung,hpd-gpio = <&gpc3 0 GPIO_ACTIVE_HIGH>; 80 + hpd-gpios = <&gpc3 0 GPIO_ACTIVE_HIGH>; 83 81 }; 84 82 85 83 &ehci {
+1 -3
arch/arm/boot/dts/exynos5420-peach-pit.dts
··· 157 157 pinctrl-names = "default"; 158 158 pinctrl-0 = <&dp_hpd_gpio>; 159 159 samsung,color-space = <0>; 160 - samsung,dynamic-range = <0>; 161 - samsung,ycbcr-coeff = <0>; 162 160 samsung,color-depth = <1>; 163 161 samsung,link-rate = <0x06>; 164 162 samsung,lane-count = <2>; 165 - samsung,hpd-gpio = <&gpx2 6 GPIO_ACTIVE_HIGH>; 163 + hpd-gpios = <&gpx2 6 GPIO_ACTIVE_HIGH>; 166 164 167 165 ports { 168 166 port@0 {
-2
arch/arm/boot/dts/exynos5420-smdk5420.dts
··· 102 102 pinctrl-names = "default"; 103 103 pinctrl-0 = <&dp_hpd>; 104 104 samsung,color-space = <0>; 105 - samsung,dynamic-range = <0>; 106 - samsung,ycbcr-coeff = <0>; 107 105 samsung,color-depth = <1>; 108 106 samsung,link-rate = <0x0a>; 109 107 samsung,lane-count = <4>;
-2
arch/arm/boot/dts/exynos5800-peach-pi.dts
··· 157 157 pinctrl-names = "default"; 158 158 pinctrl-0 = <&dp_hpd_gpio>; 159 159 samsung,color-space = <0>; 160 - samsung,dynamic-range = <0>; 161 - samsung,ycbcr-coeff = <0>; 162 160 samsung,color-depth = <1>; 163 161 samsung,link-rate = <0x0a>; 164 162 samsung,lane-count = <2>;
+2
drivers/gpu/drm/bridge/Kconfig
··· 40 40 ---help--- 41 41 Parade eDP-LVDS bridge chip driver. 42 42 43 + source "drivers/gpu/drm/bridge/analogix/Kconfig" 44 + 43 45 endmenu
+1
drivers/gpu/drm/bridge/Makefile
··· 4 4 obj-$(CONFIG_DRM_DW_HDMI_AHB_AUDIO) += dw-hdmi-ahb-audio.o 5 5 obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o 6 6 obj-$(CONFIG_DRM_PARADE_PS8622) += parade-ps8622.o 7 + obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix/
+3
drivers/gpu/drm/bridge/analogix/Kconfig
··· 1 + config DRM_ANALOGIX_DP 2 + tristate 3 + depends on DRM
+2
drivers/gpu/drm/bridge/analogix/Makefile
··· 1 + analogix_dp-objs := analogix_dp_core.o analogix_dp_reg.o 2 + obj-$(CONFIG_DRM_ANALOGIX_DP) += analogix_dp.o
+1430
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
··· 1 + /* 2 + * Analogix DP (Display Port) core interface driver. 3 + * 4 + * Copyright (C) 2012 Samsung Electronics Co., Ltd. 5 + * Author: Jingoo Han <jg1.han@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published by the 9 + * Free Software Foundation; either version 2 of the License, or (at your 10 + * option) any later version. 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/err.h> 16 + #include <linux/clk.h> 17 + #include <linux/io.h> 18 + #include <linux/interrupt.h> 19 + #include <linux/of.h> 20 + #include <linux/of_gpio.h> 21 + #include <linux/gpio.h> 22 + #include <linux/component.h> 23 + #include <linux/phy/phy.h> 24 + 25 + #include <drm/drmP.h> 26 + #include <drm/drm_atomic_helper.h> 27 + #include <drm/drm_crtc.h> 28 + #include <drm/drm_crtc_helper.h> 29 + #include <drm/drm_panel.h> 30 + 31 + #include <drm/bridge/analogix_dp.h> 32 + 33 + #include "analogix_dp_core.h" 34 + 35 + #define to_dp(nm) container_of(nm, struct analogix_dp_device, nm) 36 + 37 + struct bridge_init { 38 + struct i2c_client *client; 39 + struct device_node *node; 40 + }; 41 + 42 + static void analogix_dp_init_dp(struct analogix_dp_device *dp) 43 + { 44 + analogix_dp_reset(dp); 45 + 46 + analogix_dp_swreset(dp); 47 + 48 + analogix_dp_init_analog_param(dp); 49 + analogix_dp_init_interrupt(dp); 50 + 51 + /* SW defined function Normal operation */ 52 + analogix_dp_enable_sw_function(dp); 53 + 54 + analogix_dp_config_interrupt(dp); 55 + analogix_dp_init_analog_func(dp); 56 + 57 + analogix_dp_init_hpd(dp); 58 + analogix_dp_init_aux(dp); 59 + } 60 + 61 + static int analogix_dp_detect_hpd(struct analogix_dp_device *dp) 62 + { 63 + int timeout_loop = 0; 64 + 65 + while (timeout_loop < DP_TIMEOUT_LOOP_COUNT) { 66 + if (analogix_dp_get_plug_in_status(dp) == 0) 67 + return 0; 68 + 69 + timeout_loop++; 70 + usleep_range(10, 11); 71 + } 72 + 73 + /* 74 + * Some edp screen do not have hpd signal, so we can't just 75 + * return failed when hpd plug in detect failed, DT property 76 + * "force-hpd" would indicate whether driver need this. 77 + */ 78 + if (!dp->force_hpd) 79 + return -ETIMEDOUT; 80 + 81 + /* 82 + * The eDP TRM indicate that if HPD_STATUS(RO) is 0, AUX CH 83 + * will not work, so we need to give a force hpd action to 84 + * set HPD_STATUS manually. 85 + */ 86 + dev_dbg(dp->dev, "failed to get hpd plug status, try to force hpd\n"); 87 + 88 + analogix_dp_force_hpd(dp); 89 + 90 + if (analogix_dp_get_plug_in_status(dp) != 0) { 91 + dev_err(dp->dev, "failed to get hpd plug in status\n"); 92 + return -EINVAL; 93 + } 94 + 95 + dev_dbg(dp->dev, "success to get plug in status after force hpd\n"); 96 + 97 + return 0; 98 + } 99 + 100 + static unsigned char analogix_dp_calc_edid_check_sum(unsigned char *edid_data) 101 + { 102 + int i; 103 + unsigned char sum = 0; 104 + 105 + for (i = 0; i < EDID_BLOCK_LENGTH; i++) 106 + sum = sum + edid_data[i]; 107 + 108 + return sum; 109 + } 110 + 111 + static int analogix_dp_read_edid(struct analogix_dp_device *dp) 112 + { 113 + unsigned char *edid = dp->edid; 114 + unsigned int extend_block = 0; 115 + unsigned char sum; 116 + unsigned char test_vector; 117 + int retval; 118 + 119 + /* 120 + * EDID device address is 0x50. 121 + * However, if necessary, you must have set upper address 122 + * into E-EDID in I2C device, 0x30. 123 + */ 124 + 125 + /* Read Extension Flag, Number of 128-byte EDID extension blocks */ 126 + retval = analogix_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, 127 + EDID_EXTENSION_FLAG, 128 + &extend_block); 129 + if (retval) 130 + return retval; 131 + 132 + if (extend_block > 0) { 133 + dev_dbg(dp->dev, "EDID data includes a single extension!\n"); 134 + 135 + /* Read EDID data */ 136 + retval = analogix_dp_read_bytes_from_i2c(dp, 137 + I2C_EDID_DEVICE_ADDR, 138 + EDID_HEADER_PATTERN, 139 + EDID_BLOCK_LENGTH, 140 + &edid[EDID_HEADER_PATTERN]); 141 + if (retval != 0) { 142 + dev_err(dp->dev, "EDID Read failed!\n"); 143 + return -EIO; 144 + } 145 + sum = analogix_dp_calc_edid_check_sum(edid); 146 + if (sum != 0) { 147 + dev_err(dp->dev, "EDID bad checksum!\n"); 148 + return -EIO; 149 + } 150 + 151 + /* Read additional EDID data */ 152 + retval = analogix_dp_read_bytes_from_i2c(dp, 153 + I2C_EDID_DEVICE_ADDR, 154 + EDID_BLOCK_LENGTH, 155 + EDID_BLOCK_LENGTH, 156 + &edid[EDID_BLOCK_LENGTH]); 157 + if (retval != 0) { 158 + dev_err(dp->dev, "EDID Read failed!\n"); 159 + return -EIO; 160 + } 161 + sum = analogix_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]); 162 + if (sum != 0) { 163 + dev_err(dp->dev, "EDID bad checksum!\n"); 164 + return -EIO; 165 + } 166 + 167 + analogix_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST, 168 + &test_vector); 169 + if (test_vector & DP_TEST_LINK_EDID_READ) { 170 + analogix_dp_write_byte_to_dpcd(dp, 171 + DP_TEST_EDID_CHECKSUM, 172 + edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]); 173 + analogix_dp_write_byte_to_dpcd(dp, 174 + DP_TEST_RESPONSE, 175 + DP_TEST_EDID_CHECKSUM_WRITE); 176 + } 177 + } else { 178 + dev_info(dp->dev, "EDID data does not include any extensions.\n"); 179 + 180 + /* Read EDID data */ 181 + retval = analogix_dp_read_bytes_from_i2c(dp, 182 + I2C_EDID_DEVICE_ADDR, EDID_HEADER_PATTERN, 183 + EDID_BLOCK_LENGTH, &edid[EDID_HEADER_PATTERN]); 184 + if (retval != 0) { 185 + dev_err(dp->dev, "EDID Read failed!\n"); 186 + return -EIO; 187 + } 188 + sum = analogix_dp_calc_edid_check_sum(edid); 189 + if (sum != 0) { 190 + dev_err(dp->dev, "EDID bad checksum!\n"); 191 + return -EIO; 192 + } 193 + 194 + analogix_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST, 195 + &test_vector); 196 + if (test_vector & DP_TEST_LINK_EDID_READ) { 197 + analogix_dp_write_byte_to_dpcd(dp, 198 + DP_TEST_EDID_CHECKSUM, edid[EDID_CHECKSUM]); 199 + analogix_dp_write_byte_to_dpcd(dp, 200 + DP_TEST_RESPONSE, DP_TEST_EDID_CHECKSUM_WRITE); 201 + } 202 + } 203 + 204 + dev_dbg(dp->dev, "EDID Read success!\n"); 205 + return 0; 206 + } 207 + 208 + static int analogix_dp_handle_edid(struct analogix_dp_device *dp) 209 + { 210 + u8 buf[12]; 211 + int i; 212 + int retval; 213 + 214 + /* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */ 215 + retval = analogix_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 12, buf); 216 + if (retval) 217 + return retval; 218 + 219 + /* Read EDID */ 220 + for (i = 0; i < 3; i++) { 221 + retval = analogix_dp_read_edid(dp); 222 + if (!retval) 223 + break; 224 + } 225 + 226 + return retval; 227 + } 228 + 229 + static void 230 + analogix_dp_enable_rx_to_enhanced_mode(struct analogix_dp_device *dp, 231 + bool enable) 232 + { 233 + u8 data; 234 + 235 + analogix_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data); 236 + 237 + if (enable) 238 + analogix_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET, 239 + DP_LANE_COUNT_ENHANCED_FRAME_EN | 240 + DPCD_LANE_COUNT_SET(data)); 241 + else 242 + analogix_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET, 243 + DPCD_LANE_COUNT_SET(data)); 244 + } 245 + 246 + static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device *dp) 247 + { 248 + u8 data; 249 + int retval; 250 + 251 + analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data); 252 + retval = DPCD_ENHANCED_FRAME_CAP(data); 253 + 254 + return retval; 255 + } 256 + 257 + static void analogix_dp_set_enhanced_mode(struct analogix_dp_device *dp) 258 + { 259 + u8 data; 260 + 261 + data = analogix_dp_is_enhanced_mode_available(dp); 262 + analogix_dp_enable_rx_to_enhanced_mode(dp, data); 263 + analogix_dp_enable_enhanced_mode(dp, data); 264 + } 265 + 266 + static void analogix_dp_training_pattern_dis(struct analogix_dp_device *dp) 267 + { 268 + analogix_dp_set_training_pattern(dp, DP_NONE); 269 + 270 + analogix_dp_write_byte_to_dpcd(dp, DP_TRAINING_PATTERN_SET, 271 + DP_TRAINING_PATTERN_DISABLE); 272 + } 273 + 274 + static void 275 + analogix_dp_set_lane_lane_pre_emphasis(struct analogix_dp_device *dp, 276 + int pre_emphasis, int lane) 277 + { 278 + switch (lane) { 279 + case 0: 280 + analogix_dp_set_lane0_pre_emphasis(dp, pre_emphasis); 281 + break; 282 + case 1: 283 + analogix_dp_set_lane1_pre_emphasis(dp, pre_emphasis); 284 + break; 285 + 286 + case 2: 287 + analogix_dp_set_lane2_pre_emphasis(dp, pre_emphasis); 288 + break; 289 + 290 + case 3: 291 + analogix_dp_set_lane3_pre_emphasis(dp, pre_emphasis); 292 + break; 293 + } 294 + } 295 + 296 + static int analogix_dp_link_start(struct analogix_dp_device *dp) 297 + { 298 + u8 buf[4]; 299 + int lane, lane_count, pll_tries, retval; 300 + 301 + lane_count = dp->link_train.lane_count; 302 + 303 + dp->link_train.lt_state = CLOCK_RECOVERY; 304 + dp->link_train.eq_loop = 0; 305 + 306 + for (lane = 0; lane < lane_count; lane++) 307 + dp->link_train.cr_loop[lane] = 0; 308 + 309 + /* Set link rate and count as you want to establish*/ 310 + analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate); 311 + analogix_dp_set_lane_count(dp, dp->link_train.lane_count); 312 + 313 + /* Setup RX configuration */ 314 + buf[0] = dp->link_train.link_rate; 315 + buf[1] = dp->link_train.lane_count; 316 + retval = analogix_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 2, buf); 317 + if (retval) 318 + return retval; 319 + 320 + /* Set TX pre-emphasis to minimum */ 321 + for (lane = 0; lane < lane_count; lane++) 322 + analogix_dp_set_lane_lane_pre_emphasis(dp, 323 + PRE_EMPHASIS_LEVEL_0, lane); 324 + 325 + /* Wait for PLL lock */ 326 + pll_tries = 0; 327 + while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 328 + if (pll_tries == DP_TIMEOUT_LOOP_COUNT) { 329 + dev_err(dp->dev, "Wait for PLL lock timed out\n"); 330 + return -ETIMEDOUT; 331 + } 332 + 333 + pll_tries++; 334 + usleep_range(90, 120); 335 + } 336 + 337 + /* Set training pattern 1 */ 338 + analogix_dp_set_training_pattern(dp, TRAINING_PTN1); 339 + 340 + /* Set RX training pattern */ 341 + retval = analogix_dp_write_byte_to_dpcd(dp, 342 + DP_TRAINING_PATTERN_SET, 343 + DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1); 344 + if (retval) 345 + return retval; 346 + 347 + for (lane = 0; lane < lane_count; lane++) 348 + buf[lane] = DP_TRAIN_PRE_EMPH_LEVEL_0 | 349 + DP_TRAIN_VOLTAGE_SWING_LEVEL_0; 350 + 351 + retval = analogix_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET, 352 + lane_count, buf); 353 + 354 + return retval; 355 + } 356 + 357 + static unsigned char analogix_dp_get_lane_status(u8 link_status[2], int lane) 358 + { 359 + int shift = (lane & 1) * 4; 360 + u8 link_value = link_status[lane >> 1]; 361 + 362 + return (link_value >> shift) & 0xf; 363 + } 364 + 365 + static int analogix_dp_clock_recovery_ok(u8 link_status[2], int lane_count) 366 + { 367 + int lane; 368 + u8 lane_status; 369 + 370 + for (lane = 0; lane < lane_count; lane++) { 371 + lane_status = analogix_dp_get_lane_status(link_status, lane); 372 + if ((lane_status & DP_LANE_CR_DONE) == 0) 373 + return -EINVAL; 374 + } 375 + return 0; 376 + } 377 + 378 + static int analogix_dp_channel_eq_ok(u8 link_status[2], u8 link_align, 379 + int lane_count) 380 + { 381 + int lane; 382 + u8 lane_status; 383 + 384 + if ((link_align & DP_INTERLANE_ALIGN_DONE) == 0) 385 + return -EINVAL; 386 + 387 + for (lane = 0; lane < lane_count; lane++) { 388 + lane_status = analogix_dp_get_lane_status(link_status, lane); 389 + lane_status &= DP_CHANNEL_EQ_BITS; 390 + if (lane_status != DP_CHANNEL_EQ_BITS) 391 + return -EINVAL; 392 + } 393 + 394 + return 0; 395 + } 396 + 397 + static unsigned char 398 + analogix_dp_get_adjust_request_voltage(u8 adjust_request[2], int lane) 399 + { 400 + int shift = (lane & 1) * 4; 401 + u8 link_value = adjust_request[lane >> 1]; 402 + 403 + return (link_value >> shift) & 0x3; 404 + } 405 + 406 + static unsigned char analogix_dp_get_adjust_request_pre_emphasis( 407 + u8 adjust_request[2], 408 + int lane) 409 + { 410 + int shift = (lane & 1) * 4; 411 + u8 link_value = adjust_request[lane >> 1]; 412 + 413 + return ((link_value >> shift) & 0xc) >> 2; 414 + } 415 + 416 + static void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp, 417 + u8 training_lane_set, int lane) 418 + { 419 + switch (lane) { 420 + case 0: 421 + analogix_dp_set_lane0_link_training(dp, training_lane_set); 422 + break; 423 + case 1: 424 + analogix_dp_set_lane1_link_training(dp, training_lane_set); 425 + break; 426 + 427 + case 2: 428 + analogix_dp_set_lane2_link_training(dp, training_lane_set); 429 + break; 430 + 431 + case 3: 432 + analogix_dp_set_lane3_link_training(dp, training_lane_set); 433 + break; 434 + } 435 + } 436 + 437 + static unsigned int 438 + analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, 439 + int lane) 440 + { 441 + u32 reg; 442 + 443 + switch (lane) { 444 + case 0: 445 + reg = analogix_dp_get_lane0_link_training(dp); 446 + break; 447 + case 1: 448 + reg = analogix_dp_get_lane1_link_training(dp); 449 + break; 450 + case 2: 451 + reg = analogix_dp_get_lane2_link_training(dp); 452 + break; 453 + case 3: 454 + reg = analogix_dp_get_lane3_link_training(dp); 455 + break; 456 + default: 457 + WARN_ON(1); 458 + return 0; 459 + } 460 + 461 + return reg; 462 + } 463 + 464 + static void analogix_dp_reduce_link_rate(struct analogix_dp_device *dp) 465 + { 466 + analogix_dp_training_pattern_dis(dp); 467 + analogix_dp_set_enhanced_mode(dp); 468 + 469 + dp->link_train.lt_state = FAILED; 470 + } 471 + 472 + static void analogix_dp_get_adjust_training_lane(struct analogix_dp_device *dp, 473 + u8 adjust_request[2]) 474 + { 475 + int lane, lane_count; 476 + u8 voltage_swing, pre_emphasis, training_lane; 477 + 478 + lane_count = dp->link_train.lane_count; 479 + for (lane = 0; lane < lane_count; lane++) { 480 + voltage_swing = analogix_dp_get_adjust_request_voltage( 481 + adjust_request, lane); 482 + pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis( 483 + adjust_request, lane); 484 + training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) | 485 + DPCD_PRE_EMPHASIS_SET(pre_emphasis); 486 + 487 + if (voltage_swing == VOLTAGE_LEVEL_3) 488 + training_lane |= DP_TRAIN_MAX_SWING_REACHED; 489 + if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) 490 + training_lane |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; 491 + 492 + dp->link_train.training_lane[lane] = training_lane; 493 + } 494 + } 495 + 496 + static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp) 497 + { 498 + int lane, lane_count, retval; 499 + u8 voltage_swing, pre_emphasis, training_lane; 500 + u8 link_status[2], adjust_request[2]; 501 + 502 + usleep_range(100, 101); 503 + 504 + lane_count = dp->link_train.lane_count; 505 + 506 + retval = analogix_dp_read_bytes_from_dpcd(dp, 507 + DP_LANE0_1_STATUS, 2, link_status); 508 + if (retval) 509 + return retval; 510 + 511 + retval = analogix_dp_read_bytes_from_dpcd(dp, 512 + DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request); 513 + if (retval) 514 + return retval; 515 + 516 + if (analogix_dp_clock_recovery_ok(link_status, lane_count) == 0) { 517 + /* set training pattern 2 for EQ */ 518 + analogix_dp_set_training_pattern(dp, TRAINING_PTN2); 519 + 520 + retval = analogix_dp_write_byte_to_dpcd(dp, 521 + DP_TRAINING_PATTERN_SET, 522 + DP_LINK_SCRAMBLING_DISABLE | 523 + DP_TRAINING_PATTERN_2); 524 + if (retval) 525 + return retval; 526 + 527 + dev_info(dp->dev, "Link Training Clock Recovery success\n"); 528 + dp->link_train.lt_state = EQUALIZER_TRAINING; 529 + } else { 530 + for (lane = 0; lane < lane_count; lane++) { 531 + training_lane = analogix_dp_get_lane_link_training( 532 + dp, lane); 533 + voltage_swing = analogix_dp_get_adjust_request_voltage( 534 + adjust_request, lane); 535 + pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis( 536 + adjust_request, lane); 537 + 538 + if (DPCD_VOLTAGE_SWING_GET(training_lane) == 539 + voltage_swing && 540 + DPCD_PRE_EMPHASIS_GET(training_lane) == 541 + pre_emphasis) 542 + dp->link_train.cr_loop[lane]++; 543 + 544 + if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP || 545 + voltage_swing == VOLTAGE_LEVEL_3 || 546 + pre_emphasis == PRE_EMPHASIS_LEVEL_3) { 547 + dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n", 548 + dp->link_train.cr_loop[lane], 549 + voltage_swing, pre_emphasis); 550 + analogix_dp_reduce_link_rate(dp); 551 + return -EIO; 552 + } 553 + } 554 + } 555 + 556 + analogix_dp_get_adjust_training_lane(dp, adjust_request); 557 + 558 + for (lane = 0; lane < lane_count; lane++) 559 + analogix_dp_set_lane_link_training(dp, 560 + dp->link_train.training_lane[lane], lane); 561 + 562 + retval = analogix_dp_write_bytes_to_dpcd(dp, 563 + DP_TRAINING_LANE0_SET, lane_count, 564 + dp->link_train.training_lane); 565 + if (retval) 566 + return retval; 567 + 568 + return retval; 569 + } 570 + 571 + static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp) 572 + { 573 + int lane, lane_count, retval; 574 + u32 reg; 575 + u8 link_align, link_status[2], adjust_request[2]; 576 + 577 + usleep_range(400, 401); 578 + 579 + lane_count = dp->link_train.lane_count; 580 + 581 + retval = analogix_dp_read_bytes_from_dpcd(dp, 582 + DP_LANE0_1_STATUS, 2, link_status); 583 + if (retval) 584 + return retval; 585 + 586 + if (analogix_dp_clock_recovery_ok(link_status, lane_count)) { 587 + analogix_dp_reduce_link_rate(dp); 588 + return -EIO; 589 + } 590 + 591 + retval = analogix_dp_read_bytes_from_dpcd(dp, 592 + DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request); 593 + if (retval) 594 + return retval; 595 + 596 + retval = analogix_dp_read_byte_from_dpcd(dp, 597 + DP_LANE_ALIGN_STATUS_UPDATED, &link_align); 598 + if (retval) 599 + return retval; 600 + 601 + analogix_dp_get_adjust_training_lane(dp, adjust_request); 602 + 603 + if (!analogix_dp_channel_eq_ok(link_status, link_align, lane_count)) { 604 + /* traing pattern Set to Normal */ 605 + analogix_dp_training_pattern_dis(dp); 606 + 607 + dev_info(dp->dev, "Link Training success!\n"); 608 + 609 + analogix_dp_get_link_bandwidth(dp, &reg); 610 + dp->link_train.link_rate = reg; 611 + dev_dbg(dp->dev, "final bandwidth = %.2x\n", 612 + dp->link_train.link_rate); 613 + 614 + analogix_dp_get_lane_count(dp, &reg); 615 + dp->link_train.lane_count = reg; 616 + dev_dbg(dp->dev, "final lane count = %.2x\n", 617 + dp->link_train.lane_count); 618 + 619 + /* set enhanced mode if available */ 620 + analogix_dp_set_enhanced_mode(dp); 621 + dp->link_train.lt_state = FINISHED; 622 + 623 + return 0; 624 + } 625 + 626 + /* not all locked */ 627 + dp->link_train.eq_loop++; 628 + 629 + if (dp->link_train.eq_loop > MAX_EQ_LOOP) { 630 + dev_err(dp->dev, "EQ Max loop\n"); 631 + analogix_dp_reduce_link_rate(dp); 632 + return -EIO; 633 + } 634 + 635 + for (lane = 0; lane < lane_count; lane++) 636 + analogix_dp_set_lane_link_training(dp, 637 + dp->link_train.training_lane[lane], lane); 638 + 639 + retval = analogix_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET, 640 + lane_count, dp->link_train.training_lane); 641 + 642 + return retval; 643 + } 644 + 645 + static void analogix_dp_get_max_rx_bandwidth(struct analogix_dp_device *dp, 646 + u8 *bandwidth) 647 + { 648 + u8 data; 649 + 650 + /* 651 + * For DP rev.1.1, Maximum link rate of Main Link lanes 652 + * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps 653 + * For DP rev.1.2, Maximum link rate of Main Link lanes 654 + * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps, 0x14 = 5.4Gbps 655 + */ 656 + analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data); 657 + *bandwidth = data; 658 + } 659 + 660 + static void analogix_dp_get_max_rx_lane_count(struct analogix_dp_device *dp, 661 + u8 *lane_count) 662 + { 663 + u8 data; 664 + 665 + /* 666 + * For DP rev.1.1, Maximum number of Main Link lanes 667 + * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes 668 + */ 669 + analogix_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data); 670 + *lane_count = DPCD_MAX_LANE_COUNT(data); 671 + } 672 + 673 + static void analogix_dp_init_training(struct analogix_dp_device *dp, 674 + enum link_lane_count_type max_lane, 675 + int max_rate) 676 + { 677 + /* 678 + * MACRO_RST must be applied after the PLL_LOCK to avoid 679 + * the DP inter pair skew issue for at least 10 us 680 + */ 681 + analogix_dp_reset_macro(dp); 682 + 683 + /* Initialize by reading RX's DPCD */ 684 + analogix_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate); 685 + analogix_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count); 686 + 687 + if ((dp->link_train.link_rate != DP_LINK_BW_1_62) && 688 + (dp->link_train.link_rate != DP_LINK_BW_2_7) && 689 + (dp->link_train.link_rate != DP_LINK_BW_5_4)) { 690 + dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n", 691 + dp->link_train.link_rate); 692 + dp->link_train.link_rate = DP_LINK_BW_1_62; 693 + } 694 + 695 + if (dp->link_train.lane_count == 0) { 696 + dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n", 697 + dp->link_train.lane_count); 698 + dp->link_train.lane_count = (u8)LANE_COUNT1; 699 + } 700 + 701 + /* Setup TX lane count & rate */ 702 + if (dp->link_train.lane_count > max_lane) 703 + dp->link_train.lane_count = max_lane; 704 + if (dp->link_train.link_rate > max_rate) 705 + dp->link_train.link_rate = max_rate; 706 + 707 + /* All DP analog module power up */ 708 + analogix_dp_set_analog_power_down(dp, POWER_ALL, 0); 709 + } 710 + 711 + static int analogix_dp_sw_link_training(struct analogix_dp_device *dp) 712 + { 713 + int retval = 0, training_finished = 0; 714 + 715 + dp->link_train.lt_state = START; 716 + 717 + /* Process here */ 718 + while (!retval && !training_finished) { 719 + switch (dp->link_train.lt_state) { 720 + case START: 721 + retval = analogix_dp_link_start(dp); 722 + if (retval) 723 + dev_err(dp->dev, "LT link start failed!\n"); 724 + break; 725 + case CLOCK_RECOVERY: 726 + retval = analogix_dp_process_clock_recovery(dp); 727 + if (retval) 728 + dev_err(dp->dev, "LT CR failed!\n"); 729 + break; 730 + case EQUALIZER_TRAINING: 731 + retval = analogix_dp_process_equalizer_training(dp); 732 + if (retval) 733 + dev_err(dp->dev, "LT EQ failed!\n"); 734 + break; 735 + case FINISHED: 736 + training_finished = 1; 737 + break; 738 + case FAILED: 739 + return -EREMOTEIO; 740 + } 741 + } 742 + if (retval) 743 + dev_err(dp->dev, "eDP link training failed (%d)\n", retval); 744 + 745 + return retval; 746 + } 747 + 748 + static int analogix_dp_set_link_train(struct analogix_dp_device *dp, 749 + u32 count, u32 bwtype) 750 + { 751 + int i; 752 + int retval; 753 + 754 + for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) { 755 + analogix_dp_init_training(dp, count, bwtype); 756 + retval = analogix_dp_sw_link_training(dp); 757 + if (retval == 0) 758 + break; 759 + 760 + usleep_range(100, 110); 761 + } 762 + 763 + return retval; 764 + } 765 + 766 + static int analogix_dp_config_video(struct analogix_dp_device *dp) 767 + { 768 + int retval = 0; 769 + int timeout_loop = 0; 770 + int done_count = 0; 771 + 772 + analogix_dp_config_video_slave_mode(dp); 773 + 774 + analogix_dp_set_video_color_format(dp); 775 + 776 + if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 777 + dev_err(dp->dev, "PLL is not locked yet.\n"); 778 + return -EINVAL; 779 + } 780 + 781 + for (;;) { 782 + timeout_loop++; 783 + if (analogix_dp_is_slave_video_stream_clock_on(dp) == 0) 784 + break; 785 + if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) { 786 + dev_err(dp->dev, "Timeout of video streamclk ok\n"); 787 + return -ETIMEDOUT; 788 + } 789 + 790 + usleep_range(1, 2); 791 + } 792 + 793 + /* Set to use the register calculated M/N video */ 794 + analogix_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0); 795 + 796 + /* For video bist, Video timing must be generated by register */ 797 + analogix_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE); 798 + 799 + /* Disable video mute */ 800 + analogix_dp_enable_video_mute(dp, 0); 801 + 802 + /* Configure video slave mode */ 803 + analogix_dp_enable_video_master(dp, 0); 804 + 805 + timeout_loop = 0; 806 + 807 + for (;;) { 808 + timeout_loop++; 809 + if (analogix_dp_is_video_stream_on(dp) == 0) { 810 + done_count++; 811 + if (done_count > 10) 812 + break; 813 + } else if (done_count) { 814 + done_count = 0; 815 + } 816 + if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) { 817 + dev_err(dp->dev, "Timeout of video streamclk ok\n"); 818 + return -ETIMEDOUT; 819 + } 820 + 821 + usleep_range(1000, 1001); 822 + } 823 + 824 + if (retval != 0) 825 + dev_err(dp->dev, "Video stream is not detected!\n"); 826 + 827 + return retval; 828 + } 829 + 830 + static void analogix_dp_enable_scramble(struct analogix_dp_device *dp, 831 + bool enable) 832 + { 833 + u8 data; 834 + 835 + if (enable) { 836 + analogix_dp_enable_scrambling(dp); 837 + 838 + analogix_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET, 839 + &data); 840 + analogix_dp_write_byte_to_dpcd(dp, 841 + DP_TRAINING_PATTERN_SET, 842 + (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE)); 843 + } else { 844 + analogix_dp_disable_scrambling(dp); 845 + 846 + analogix_dp_read_byte_from_dpcd(dp, DP_TRAINING_PATTERN_SET, 847 + &data); 848 + analogix_dp_write_byte_to_dpcd(dp, 849 + DP_TRAINING_PATTERN_SET, 850 + (u8)(data | DP_LINK_SCRAMBLING_DISABLE)); 851 + } 852 + } 853 + 854 + static irqreturn_t analogix_dp_hardirq(int irq, void *arg) 855 + { 856 + struct analogix_dp_device *dp = arg; 857 + irqreturn_t ret = IRQ_NONE; 858 + enum dp_irq_type irq_type; 859 + 860 + irq_type = analogix_dp_get_irq_type(dp); 861 + if (irq_type != DP_IRQ_TYPE_UNKNOWN) { 862 + analogix_dp_mute_hpd_interrupt(dp); 863 + ret = IRQ_WAKE_THREAD; 864 + } 865 + 866 + return ret; 867 + } 868 + 869 + static irqreturn_t analogix_dp_irq_thread(int irq, void *arg) 870 + { 871 + struct analogix_dp_device *dp = arg; 872 + enum dp_irq_type irq_type; 873 + 874 + irq_type = analogix_dp_get_irq_type(dp); 875 + if (irq_type & DP_IRQ_TYPE_HP_CABLE_IN || 876 + irq_type & DP_IRQ_TYPE_HP_CABLE_OUT) { 877 + dev_dbg(dp->dev, "Detected cable status changed!\n"); 878 + if (dp->drm_dev) 879 + drm_helper_hpd_irq_event(dp->drm_dev); 880 + } 881 + 882 + if (irq_type != DP_IRQ_TYPE_UNKNOWN) { 883 + analogix_dp_clear_hotplug_interrupts(dp); 884 + analogix_dp_unmute_hpd_interrupt(dp); 885 + } 886 + 887 + return IRQ_HANDLED; 888 + } 889 + 890 + static void analogix_dp_commit(struct analogix_dp_device *dp) 891 + { 892 + int ret; 893 + 894 + /* Keep the panel disabled while we configure video */ 895 + if (dp->plat_data->panel) { 896 + if (drm_panel_disable(dp->plat_data->panel)) 897 + DRM_ERROR("failed to disable the panel\n"); 898 + } 899 + 900 + ret = analogix_dp_set_link_train(dp, dp->video_info.max_lane_count, 901 + dp->video_info.max_link_rate); 902 + if (ret) { 903 + dev_err(dp->dev, "unable to do link train\n"); 904 + return; 905 + } 906 + 907 + analogix_dp_enable_scramble(dp, 1); 908 + analogix_dp_enable_rx_to_enhanced_mode(dp, 1); 909 + analogix_dp_enable_enhanced_mode(dp, 1); 910 + 911 + analogix_dp_init_video(dp); 912 + ret = analogix_dp_config_video(dp); 913 + if (ret) 914 + dev_err(dp->dev, "unable to config video\n"); 915 + 916 + /* Safe to enable the panel now */ 917 + if (dp->plat_data->panel) { 918 + if (drm_panel_enable(dp->plat_data->panel)) 919 + DRM_ERROR("failed to enable the panel\n"); 920 + } 921 + 922 + /* Enable video */ 923 + analogix_dp_start_video(dp); 924 + } 925 + 926 + int analogix_dp_get_modes(struct drm_connector *connector) 927 + { 928 + struct analogix_dp_device *dp = to_dp(connector); 929 + struct edid *edid = (struct edid *)dp->edid; 930 + int num_modes = 0; 931 + 932 + if (analogix_dp_handle_edid(dp) == 0) { 933 + drm_mode_connector_update_edid_property(&dp->connector, edid); 934 + num_modes += drm_add_edid_modes(&dp->connector, edid); 935 + } 936 + 937 + if (dp->plat_data->panel) 938 + num_modes += drm_panel_get_modes(dp->plat_data->panel); 939 + 940 + if (dp->plat_data->get_modes) 941 + num_modes += dp->plat_data->get_modes(dp->plat_data); 942 + 943 + return num_modes; 944 + } 945 + 946 + static struct drm_encoder * 947 + analogix_dp_best_encoder(struct drm_connector *connector) 948 + { 949 + struct analogix_dp_device *dp = to_dp(connector); 950 + 951 + return dp->encoder; 952 + } 953 + 954 + static const struct drm_connector_helper_funcs analogix_dp_connector_helper_funcs = { 955 + .get_modes = analogix_dp_get_modes, 956 + .best_encoder = analogix_dp_best_encoder, 957 + }; 958 + 959 + enum drm_connector_status 960 + analogix_dp_detect(struct drm_connector *connector, bool force) 961 + { 962 + struct analogix_dp_device *dp = to_dp(connector); 963 + 964 + if (analogix_dp_detect_hpd(dp)) 965 + return connector_status_disconnected; 966 + 967 + return connector_status_connected; 968 + } 969 + 970 + static void analogix_dp_connector_destroy(struct drm_connector *connector) 971 + { 972 + drm_connector_unregister(connector); 973 + drm_connector_cleanup(connector); 974 + 975 + } 976 + 977 + static const struct drm_connector_funcs analogix_dp_connector_funcs = { 978 + .dpms = drm_atomic_helper_connector_dpms, 979 + .fill_modes = drm_helper_probe_single_connector_modes, 980 + .detect = analogix_dp_detect, 981 + .destroy = analogix_dp_connector_destroy, 982 + .reset = drm_atomic_helper_connector_reset, 983 + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 984 + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 985 + }; 986 + 987 + static int analogix_dp_bridge_attach(struct drm_bridge *bridge) 988 + { 989 + struct analogix_dp_device *dp = bridge->driver_private; 990 + struct drm_encoder *encoder = dp->encoder; 991 + struct drm_connector *connector = &dp->connector; 992 + int ret; 993 + 994 + if (!bridge->encoder) { 995 + DRM_ERROR("Parent encoder object not found"); 996 + return -ENODEV; 997 + } 998 + 999 + connector->polled = DRM_CONNECTOR_POLL_HPD; 1000 + 1001 + ret = drm_connector_init(dp->drm_dev, connector, 1002 + &analogix_dp_connector_funcs, 1003 + DRM_MODE_CONNECTOR_eDP); 1004 + if (ret) { 1005 + DRM_ERROR("Failed to initialize connector with drm\n"); 1006 + return ret; 1007 + } 1008 + 1009 + drm_connector_helper_add(connector, 1010 + &analogix_dp_connector_helper_funcs); 1011 + drm_mode_connector_attach_encoder(connector, encoder); 1012 + 1013 + /* 1014 + * NOTE: the connector registration is implemented in analogix 1015 + * platform driver, that to say connector would be exist after 1016 + * plat_data->attch return, that's why we record the connector 1017 + * point after plat attached. 1018 + */ 1019 + if (dp->plat_data->attach) { 1020 + ret = dp->plat_data->attach(dp->plat_data, bridge, connector); 1021 + if (ret) { 1022 + DRM_ERROR("Failed at platform attch func\n"); 1023 + return ret; 1024 + } 1025 + } 1026 + 1027 + if (dp->plat_data->panel) { 1028 + ret = drm_panel_attach(dp->plat_data->panel, &dp->connector); 1029 + if (ret) { 1030 + DRM_ERROR("Failed to attach panel\n"); 1031 + return ret; 1032 + } 1033 + } 1034 + 1035 + return 0; 1036 + } 1037 + 1038 + static void analogix_dp_bridge_enable(struct drm_bridge *bridge) 1039 + { 1040 + struct analogix_dp_device *dp = bridge->driver_private; 1041 + 1042 + if (dp->dpms_mode == DRM_MODE_DPMS_ON) 1043 + return; 1044 + 1045 + pm_runtime_get_sync(dp->dev); 1046 + 1047 + if (dp->plat_data->power_on) 1048 + dp->plat_data->power_on(dp->plat_data); 1049 + 1050 + phy_power_on(dp->phy); 1051 + analogix_dp_init_dp(dp); 1052 + enable_irq(dp->irq); 1053 + analogix_dp_commit(dp); 1054 + 1055 + dp->dpms_mode = DRM_MODE_DPMS_ON; 1056 + } 1057 + 1058 + static void analogix_dp_bridge_disable(struct drm_bridge *bridge) 1059 + { 1060 + struct analogix_dp_device *dp = bridge->driver_private; 1061 + 1062 + if (dp->dpms_mode != DRM_MODE_DPMS_ON) 1063 + return; 1064 + 1065 + if (dp->plat_data->panel) { 1066 + if (drm_panel_disable(dp->plat_data->panel)) { 1067 + DRM_ERROR("failed to disable the panel\n"); 1068 + return; 1069 + } 1070 + } 1071 + 1072 + disable_irq(dp->irq); 1073 + phy_power_off(dp->phy); 1074 + 1075 + if (dp->plat_data->power_off) 1076 + dp->plat_data->power_off(dp->plat_data); 1077 + 1078 + pm_runtime_put_sync(dp->dev); 1079 + 1080 + dp->dpms_mode = DRM_MODE_DPMS_OFF; 1081 + } 1082 + 1083 + static void analogix_dp_bridge_mode_set(struct drm_bridge *bridge, 1084 + struct drm_display_mode *orig_mode, 1085 + struct drm_display_mode *mode) 1086 + { 1087 + struct analogix_dp_device *dp = bridge->driver_private; 1088 + struct drm_display_info *display_info = &dp->connector.display_info; 1089 + struct video_info *video = &dp->video_info; 1090 + struct device_node *dp_node = dp->dev->of_node; 1091 + int vic; 1092 + 1093 + /* Input video interlaces & hsync pol & vsync pol */ 1094 + video->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); 1095 + video->v_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NVSYNC); 1096 + video->h_sync_polarity = !!(mode->flags & DRM_MODE_FLAG_NHSYNC); 1097 + 1098 + /* Input video dynamic_range & colorimetry */ 1099 + vic = drm_match_cea_mode(mode); 1100 + if ((vic == 6) || (vic == 7) || (vic == 21) || (vic == 22) || 1101 + (vic == 2) || (vic == 3) || (vic == 17) || (vic == 18)) { 1102 + video->dynamic_range = CEA; 1103 + video->ycbcr_coeff = COLOR_YCBCR601; 1104 + } else if (vic) { 1105 + video->dynamic_range = CEA; 1106 + video->ycbcr_coeff = COLOR_YCBCR709; 1107 + } else { 1108 + video->dynamic_range = VESA; 1109 + video->ycbcr_coeff = COLOR_YCBCR709; 1110 + } 1111 + 1112 + /* Input vide bpc and color_formats */ 1113 + switch (display_info->bpc) { 1114 + case 12: 1115 + video->color_depth = COLOR_12; 1116 + break; 1117 + case 10: 1118 + video->color_depth = COLOR_10; 1119 + break; 1120 + case 8: 1121 + video->color_depth = COLOR_8; 1122 + break; 1123 + case 6: 1124 + video->color_depth = COLOR_6; 1125 + break; 1126 + default: 1127 + video->color_depth = COLOR_8; 1128 + break; 1129 + } 1130 + if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB444) 1131 + video->color_space = COLOR_YCBCR444; 1132 + else if (display_info->color_formats & DRM_COLOR_FORMAT_YCRCB422) 1133 + video->color_space = COLOR_YCBCR422; 1134 + else if (display_info->color_formats & DRM_COLOR_FORMAT_RGB444) 1135 + video->color_space = COLOR_RGB; 1136 + else 1137 + video->color_space = COLOR_RGB; 1138 + 1139 + /* 1140 + * NOTE: those property parsing code is used for providing backward 1141 + * compatibility for samsung platform. 1142 + * Due to we used the "of_property_read_u32" interfaces, when this 1143 + * property isn't present, the "video_info" can keep the original 1144 + * values and wouldn't be modified. 1145 + */ 1146 + of_property_read_u32(dp_node, "samsung,color-space", 1147 + &video->color_space); 1148 + of_property_read_u32(dp_node, "samsung,dynamic-range", 1149 + &video->dynamic_range); 1150 + of_property_read_u32(dp_node, "samsung,ycbcr-coeff", 1151 + &video->ycbcr_coeff); 1152 + of_property_read_u32(dp_node, "samsung,color-depth", 1153 + &video->color_depth); 1154 + if (of_property_read_bool(dp_node, "hsync-active-high")) 1155 + video->h_sync_polarity = true; 1156 + if (of_property_read_bool(dp_node, "vsync-active-high")) 1157 + video->v_sync_polarity = true; 1158 + if (of_property_read_bool(dp_node, "interlaced")) 1159 + video->interlaced = true; 1160 + } 1161 + 1162 + static void analogix_dp_bridge_nop(struct drm_bridge *bridge) 1163 + { 1164 + /* do nothing */ 1165 + } 1166 + 1167 + static const struct drm_bridge_funcs analogix_dp_bridge_funcs = { 1168 + .enable = analogix_dp_bridge_enable, 1169 + .disable = analogix_dp_bridge_disable, 1170 + .pre_enable = analogix_dp_bridge_nop, 1171 + .post_disable = analogix_dp_bridge_nop, 1172 + .mode_set = analogix_dp_bridge_mode_set, 1173 + .attach = analogix_dp_bridge_attach, 1174 + }; 1175 + 1176 + static int analogix_dp_create_bridge(struct drm_device *drm_dev, 1177 + struct analogix_dp_device *dp) 1178 + { 1179 + struct drm_bridge *bridge; 1180 + int ret; 1181 + 1182 + bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL); 1183 + if (!bridge) { 1184 + DRM_ERROR("failed to allocate for drm bridge\n"); 1185 + return -ENOMEM; 1186 + } 1187 + 1188 + dp->bridge = bridge; 1189 + 1190 + dp->encoder->bridge = bridge; 1191 + bridge->driver_private = dp; 1192 + bridge->encoder = dp->encoder; 1193 + bridge->funcs = &analogix_dp_bridge_funcs; 1194 + 1195 + ret = drm_bridge_attach(drm_dev, bridge); 1196 + if (ret) { 1197 + DRM_ERROR("failed to attach drm bridge\n"); 1198 + return -EINVAL; 1199 + } 1200 + 1201 + return 0; 1202 + } 1203 + 1204 + static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp) 1205 + { 1206 + struct device_node *dp_node = dp->dev->of_node; 1207 + struct video_info *video_info = &dp->video_info; 1208 + 1209 + switch (dp->plat_data->dev_type) { 1210 + case RK3288_DP: 1211 + /* 1212 + * Like Rk3288 DisplayPort TRM indicate that "Main link 1213 + * containing 4 physical lanes of 2.7/1.62 Gbps/lane". 1214 + */ 1215 + video_info->max_link_rate = 0x0A; 1216 + video_info->max_lane_count = 0x04; 1217 + break; 1218 + case EXYNOS_DP: 1219 + /* 1220 + * NOTE: those property parseing code is used for 1221 + * providing backward compatibility for samsung platform. 1222 + */ 1223 + of_property_read_u32(dp_node, "samsung,link-rate", 1224 + &video_info->max_link_rate); 1225 + of_property_read_u32(dp_node, "samsung,lane-count", 1226 + &video_info->max_lane_count); 1227 + break; 1228 + } 1229 + 1230 + return 0; 1231 + } 1232 + 1233 + int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, 1234 + struct analogix_dp_plat_data *plat_data) 1235 + { 1236 + struct platform_device *pdev = to_platform_device(dev); 1237 + struct analogix_dp_device *dp; 1238 + struct resource *res; 1239 + unsigned int irq_flags; 1240 + int ret; 1241 + 1242 + if (!plat_data) { 1243 + dev_err(dev, "Invalided input plat_data\n"); 1244 + return -EINVAL; 1245 + } 1246 + 1247 + dp = devm_kzalloc(dev, sizeof(struct analogix_dp_device), GFP_KERNEL); 1248 + if (!dp) 1249 + return -ENOMEM; 1250 + 1251 + dev_set_drvdata(dev, dp); 1252 + 1253 + dp->dev = &pdev->dev; 1254 + dp->dpms_mode = DRM_MODE_DPMS_OFF; 1255 + 1256 + /* 1257 + * platform dp driver need containor_of the plat_data to get 1258 + * the driver private data, so we need to store the point of 1259 + * plat_data, not the context of plat_data. 1260 + */ 1261 + dp->plat_data = plat_data; 1262 + 1263 + ret = analogix_dp_dt_parse_pdata(dp); 1264 + if (ret) 1265 + return ret; 1266 + 1267 + dp->phy = devm_phy_get(dp->dev, "dp"); 1268 + if (IS_ERR(dp->phy)) { 1269 + dev_err(dp->dev, "no DP phy configured\n"); 1270 + ret = PTR_ERR(dp->phy); 1271 + if (ret) { 1272 + /* 1273 + * phy itself is not enabled, so we can move forward 1274 + * assigning NULL to phy pointer. 1275 + */ 1276 + if (ret == -ENOSYS || ret == -ENODEV) 1277 + dp->phy = NULL; 1278 + else 1279 + return ret; 1280 + } 1281 + } 1282 + 1283 + dp->clock = devm_clk_get(&pdev->dev, "dp"); 1284 + if (IS_ERR(dp->clock)) { 1285 + dev_err(&pdev->dev, "failed to get clock\n"); 1286 + return PTR_ERR(dp->clock); 1287 + } 1288 + 1289 + clk_prepare_enable(dp->clock); 1290 + 1291 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1292 + 1293 + dp->reg_base = devm_ioremap_resource(&pdev->dev, res); 1294 + if (IS_ERR(dp->reg_base)) 1295 + return PTR_ERR(dp->reg_base); 1296 + 1297 + dp->force_hpd = of_property_read_bool(dev->of_node, "force-hpd"); 1298 + 1299 + dp->hpd_gpio = of_get_named_gpio(dev->of_node, "hpd-gpios", 0); 1300 + if (!gpio_is_valid(dp->hpd_gpio)) 1301 + dp->hpd_gpio = of_get_named_gpio(dev->of_node, 1302 + "samsung,hpd-gpio", 0); 1303 + 1304 + if (gpio_is_valid(dp->hpd_gpio)) { 1305 + /* 1306 + * Set up the hotplug GPIO from the device tree as an interrupt. 1307 + * Simply specifying a different interrupt in the device tree 1308 + * doesn't work since we handle hotplug rather differently when 1309 + * using a GPIO. We also need the actual GPIO specifier so 1310 + * that we can get the current state of the GPIO. 1311 + */ 1312 + ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN, 1313 + "hpd_gpio"); 1314 + if (ret) { 1315 + dev_err(&pdev->dev, "failed to get hpd gpio\n"); 1316 + return ret; 1317 + } 1318 + dp->irq = gpio_to_irq(dp->hpd_gpio); 1319 + irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; 1320 + } else { 1321 + dp->hpd_gpio = -ENODEV; 1322 + dp->irq = platform_get_irq(pdev, 0); 1323 + irq_flags = 0; 1324 + } 1325 + 1326 + if (dp->irq == -ENXIO) { 1327 + dev_err(&pdev->dev, "failed to get irq\n"); 1328 + return -ENODEV; 1329 + } 1330 + 1331 + pm_runtime_enable(dev); 1332 + 1333 + phy_power_on(dp->phy); 1334 + 1335 + if (dp->plat_data->panel) { 1336 + if (drm_panel_prepare(dp->plat_data->panel)) { 1337 + DRM_ERROR("failed to setup the panel\n"); 1338 + return -EBUSY; 1339 + } 1340 + } 1341 + 1342 + analogix_dp_init_dp(dp); 1343 + 1344 + ret = devm_request_threaded_irq(&pdev->dev, dp->irq, 1345 + analogix_dp_hardirq, 1346 + analogix_dp_irq_thread, 1347 + irq_flags, "analogix-dp", dp); 1348 + if (ret) { 1349 + dev_err(&pdev->dev, "failed to request irq\n"); 1350 + goto err_disable_pm_runtime; 1351 + } 1352 + disable_irq(dp->irq); 1353 + 1354 + dp->drm_dev = drm_dev; 1355 + dp->encoder = dp->plat_data->encoder; 1356 + 1357 + ret = analogix_dp_create_bridge(drm_dev, dp); 1358 + if (ret) { 1359 + DRM_ERROR("failed to create bridge (%d)\n", ret); 1360 + drm_encoder_cleanup(dp->encoder); 1361 + goto err_disable_pm_runtime; 1362 + } 1363 + 1364 + return 0; 1365 + 1366 + err_disable_pm_runtime: 1367 + pm_runtime_disable(dev); 1368 + 1369 + return ret; 1370 + } 1371 + EXPORT_SYMBOL_GPL(analogix_dp_bind); 1372 + 1373 + void analogix_dp_unbind(struct device *dev, struct device *master, 1374 + void *data) 1375 + { 1376 + struct analogix_dp_device *dp = dev_get_drvdata(dev); 1377 + 1378 + analogix_dp_bridge_disable(dp->bridge); 1379 + 1380 + if (dp->plat_data->panel) { 1381 + if (drm_panel_unprepare(dp->plat_data->panel)) 1382 + DRM_ERROR("failed to turnoff the panel\n"); 1383 + } 1384 + 1385 + pm_runtime_disable(dev); 1386 + } 1387 + EXPORT_SYMBOL_GPL(analogix_dp_unbind); 1388 + 1389 + #ifdef CONFIG_PM 1390 + int analogix_dp_suspend(struct device *dev) 1391 + { 1392 + struct analogix_dp_device *dp = dev_get_drvdata(dev); 1393 + 1394 + clk_disable_unprepare(dp->clock); 1395 + 1396 + if (dp->plat_data->panel) { 1397 + if (drm_panel_unprepare(dp->plat_data->panel)) 1398 + DRM_ERROR("failed to turnoff the panel\n"); 1399 + } 1400 + 1401 + return 0; 1402 + } 1403 + EXPORT_SYMBOL_GPL(analogix_dp_suspend); 1404 + 1405 + int analogix_dp_resume(struct device *dev) 1406 + { 1407 + struct analogix_dp_device *dp = dev_get_drvdata(dev); 1408 + int ret; 1409 + 1410 + ret = clk_prepare_enable(dp->clock); 1411 + if (ret < 0) { 1412 + DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret); 1413 + return ret; 1414 + } 1415 + 1416 + if (dp->plat_data->panel) { 1417 + if (drm_panel_prepare(dp->plat_data->panel)) { 1418 + DRM_ERROR("failed to setup the panel\n"); 1419 + return -EBUSY; 1420 + } 1421 + } 1422 + 1423 + return 0; 1424 + } 1425 + EXPORT_SYMBOL_GPL(analogix_dp_resume); 1426 + #endif 1427 + 1428 + MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); 1429 + MODULE_DESCRIPTION("Analogix DP Core Driver"); 1430 + MODULE_LICENSE("GPL v2");
+281
drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
··· 1 + /* 2 + * Header file for Analogix DP (Display Port) core interface driver. 3 + * 4 + * Copyright (C) 2012 Samsung Electronics Co., Ltd. 5 + * Author: Jingoo Han <jg1.han@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published by the 9 + * Free Software Foundation; either version 2 of the License, or (at your 10 + * option) any later version. 11 + */ 12 + 13 + #ifndef _ANALOGIX_DP_CORE_H 14 + #define _ANALOGIX_DP_CORE_H 15 + 16 + #include <drm/drm_crtc.h> 17 + #include <drm/drm_dp_helper.h> 18 + 19 + #define DP_TIMEOUT_LOOP_COUNT 100 20 + #define MAX_CR_LOOP 5 21 + #define MAX_EQ_LOOP 5 22 + 23 + /* I2C EDID Chip ID, Slave Address */ 24 + #define I2C_EDID_DEVICE_ADDR 0x50 25 + #define I2C_E_EDID_DEVICE_ADDR 0x30 26 + 27 + #define EDID_BLOCK_LENGTH 0x80 28 + #define EDID_HEADER_PATTERN 0x00 29 + #define EDID_EXTENSION_FLAG 0x7e 30 + #define EDID_CHECKSUM 0x7f 31 + 32 + /* DP_MAX_LANE_COUNT */ 33 + #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) 34 + #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) 35 + 36 + /* DP_LANE_COUNT_SET */ 37 + #define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f) 38 + 39 + /* DP_TRAINING_LANE0_SET */ 40 + #define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3) 41 + #define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3) 42 + #define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0) 43 + #define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3) 44 + 45 + enum link_lane_count_type { 46 + LANE_COUNT1 = 1, 47 + LANE_COUNT2 = 2, 48 + LANE_COUNT4 = 4 49 + }; 50 + 51 + enum link_training_state { 52 + START, 53 + CLOCK_RECOVERY, 54 + EQUALIZER_TRAINING, 55 + FINISHED, 56 + FAILED 57 + }; 58 + 59 + enum voltage_swing_level { 60 + VOLTAGE_LEVEL_0, 61 + VOLTAGE_LEVEL_1, 62 + VOLTAGE_LEVEL_2, 63 + VOLTAGE_LEVEL_3, 64 + }; 65 + 66 + enum pre_emphasis_level { 67 + PRE_EMPHASIS_LEVEL_0, 68 + PRE_EMPHASIS_LEVEL_1, 69 + PRE_EMPHASIS_LEVEL_2, 70 + PRE_EMPHASIS_LEVEL_3, 71 + }; 72 + 73 + enum pattern_set { 74 + PRBS7, 75 + D10_2, 76 + TRAINING_PTN1, 77 + TRAINING_PTN2, 78 + DP_NONE 79 + }; 80 + 81 + enum color_space { 82 + COLOR_RGB, 83 + COLOR_YCBCR422, 84 + COLOR_YCBCR444 85 + }; 86 + 87 + enum color_depth { 88 + COLOR_6, 89 + COLOR_8, 90 + COLOR_10, 91 + COLOR_12 92 + }; 93 + 94 + enum color_coefficient { 95 + COLOR_YCBCR601, 96 + COLOR_YCBCR709 97 + }; 98 + 99 + enum dynamic_range { 100 + VESA, 101 + CEA 102 + }; 103 + 104 + enum pll_status { 105 + PLL_UNLOCKED, 106 + PLL_LOCKED 107 + }; 108 + 109 + enum clock_recovery_m_value_type { 110 + CALCULATED_M, 111 + REGISTER_M 112 + }; 113 + 114 + enum video_timing_recognition_type { 115 + VIDEO_TIMING_FROM_CAPTURE, 116 + VIDEO_TIMING_FROM_REGISTER 117 + }; 118 + 119 + enum analog_power_block { 120 + AUX_BLOCK, 121 + CH0_BLOCK, 122 + CH1_BLOCK, 123 + CH2_BLOCK, 124 + CH3_BLOCK, 125 + ANALOG_TOTAL, 126 + POWER_ALL 127 + }; 128 + 129 + enum dp_irq_type { 130 + DP_IRQ_TYPE_HP_CABLE_IN, 131 + DP_IRQ_TYPE_HP_CABLE_OUT, 132 + DP_IRQ_TYPE_HP_CHANGE, 133 + DP_IRQ_TYPE_UNKNOWN, 134 + }; 135 + 136 + struct video_info { 137 + char *name; 138 + 139 + bool h_sync_polarity; 140 + bool v_sync_polarity; 141 + bool interlaced; 142 + 143 + enum color_space color_space; 144 + enum dynamic_range dynamic_range; 145 + enum color_coefficient ycbcr_coeff; 146 + enum color_depth color_depth; 147 + 148 + int max_link_rate; 149 + enum link_lane_count_type max_lane_count; 150 + }; 151 + 152 + struct link_train { 153 + int eq_loop; 154 + int cr_loop[4]; 155 + 156 + u8 link_rate; 157 + u8 lane_count; 158 + u8 training_lane[4]; 159 + 160 + enum link_training_state lt_state; 161 + }; 162 + 163 + struct analogix_dp_device { 164 + struct drm_encoder *encoder; 165 + struct device *dev; 166 + struct drm_device *drm_dev; 167 + struct drm_connector connector; 168 + struct drm_bridge *bridge; 169 + struct clk *clock; 170 + unsigned int irq; 171 + void __iomem *reg_base; 172 + 173 + struct video_info video_info; 174 + struct link_train link_train; 175 + struct phy *phy; 176 + int dpms_mode; 177 + int hpd_gpio; 178 + bool force_hpd; 179 + unsigned char edid[EDID_BLOCK_LENGTH * 2]; 180 + 181 + struct analogix_dp_plat_data *plat_data; 182 + }; 183 + 184 + /* analogix_dp_reg.c */ 185 + void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable); 186 + void analogix_dp_stop_video(struct analogix_dp_device *dp); 187 + void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable); 188 + void analogix_dp_init_analog_param(struct analogix_dp_device *dp); 189 + void analogix_dp_init_interrupt(struct analogix_dp_device *dp); 190 + void analogix_dp_reset(struct analogix_dp_device *dp); 191 + void analogix_dp_swreset(struct analogix_dp_device *dp); 192 + void analogix_dp_config_interrupt(struct analogix_dp_device *dp); 193 + void analogix_dp_mute_hpd_interrupt(struct analogix_dp_device *dp); 194 + void analogix_dp_unmute_hpd_interrupt(struct analogix_dp_device *dp); 195 + enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp); 196 + void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable); 197 + void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp, 198 + enum analog_power_block block, 199 + bool enable); 200 + void analogix_dp_init_analog_func(struct analogix_dp_device *dp); 201 + void analogix_dp_init_hpd(struct analogix_dp_device *dp); 202 + void analogix_dp_force_hpd(struct analogix_dp_device *dp); 203 + enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp); 204 + void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp); 205 + void analogix_dp_reset_aux(struct analogix_dp_device *dp); 206 + void analogix_dp_init_aux(struct analogix_dp_device *dp); 207 + int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp); 208 + void analogix_dp_enable_sw_function(struct analogix_dp_device *dp); 209 + int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp); 210 + int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp, 211 + unsigned int reg_addr, 212 + unsigned char data); 213 + int analogix_dp_read_byte_from_dpcd(struct analogix_dp_device *dp, 214 + unsigned int reg_addr, 215 + unsigned char *data); 216 + int analogix_dp_write_bytes_to_dpcd(struct analogix_dp_device *dp, 217 + unsigned int reg_addr, 218 + unsigned int count, 219 + unsigned char data[]); 220 + int analogix_dp_read_bytes_from_dpcd(struct analogix_dp_device *dp, 221 + unsigned int reg_addr, 222 + unsigned int count, 223 + unsigned char data[]); 224 + int analogix_dp_select_i2c_device(struct analogix_dp_device *dp, 225 + unsigned int device_addr, 226 + unsigned int reg_addr); 227 + int analogix_dp_read_byte_from_i2c(struct analogix_dp_device *dp, 228 + unsigned int device_addr, 229 + unsigned int reg_addr, 230 + unsigned int *data); 231 + int analogix_dp_read_bytes_from_i2c(struct analogix_dp_device *dp, 232 + unsigned int device_addr, 233 + unsigned int reg_addr, 234 + unsigned int count, 235 + unsigned char edid[]); 236 + void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype); 237 + void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype); 238 + void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count); 239 + void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count); 240 + void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp, 241 + bool enable); 242 + void analogix_dp_set_training_pattern(struct analogix_dp_device *dp, 243 + enum pattern_set pattern); 244 + void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp, 245 + u32 level); 246 + void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp, 247 + u32 level); 248 + void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp, 249 + u32 level); 250 + void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp, 251 + u32 level); 252 + void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp, 253 + u32 training_lane); 254 + void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp, 255 + u32 training_lane); 256 + void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp, 257 + u32 training_lane); 258 + void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp, 259 + u32 training_lane); 260 + u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp); 261 + u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp); 262 + u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp); 263 + u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp); 264 + void analogix_dp_reset_macro(struct analogix_dp_device *dp); 265 + void analogix_dp_init_video(struct analogix_dp_device *dp); 266 + 267 + void analogix_dp_set_video_color_format(struct analogix_dp_device *dp); 268 + int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp); 269 + void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp, 270 + enum clock_recovery_m_value_type type, 271 + u32 m_value, 272 + u32 n_value); 273 + void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type); 274 + void analogix_dp_enable_video_master(struct analogix_dp_device *dp, 275 + bool enable); 276 + void analogix_dp_start_video(struct analogix_dp_device *dp); 277 + int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp); 278 + void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp); 279 + void analogix_dp_enable_scrambling(struct analogix_dp_device *dp); 280 + void analogix_dp_disable_scrambling(struct analogix_dp_device *dp); 281 + #endif /* _ANALOGIX_DP_CORE_H */
+1320
drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
··· 1 + /* 2 + * Analogix DP (Display port) core register interface driver. 3 + * 4 + * Copyright (C) 2012 Samsung Electronics Co., Ltd. 5 + * Author: Jingoo Han <jg1.han@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published by the 9 + * Free Software Foundation; either version 2 of the License, or (at your 10 + * option) any later version. 11 + */ 12 + 13 + #include <linux/device.h> 14 + #include <linux/io.h> 15 + #include <linux/delay.h> 16 + #include <linux/gpio.h> 17 + 18 + #include <drm/bridge/analogix_dp.h> 19 + 20 + #include "analogix_dp_core.h" 21 + #include "analogix_dp_reg.h" 22 + 23 + #define COMMON_INT_MASK_1 0 24 + #define COMMON_INT_MASK_2 0 25 + #define COMMON_INT_MASK_3 0 26 + #define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG) 27 + #define INT_STA_MASK INT_HPD 28 + 29 + void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable) 30 + { 31 + u32 reg; 32 + 33 + if (enable) { 34 + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1); 35 + reg |= HDCP_VIDEO_MUTE; 36 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1); 37 + } else { 38 + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1); 39 + reg &= ~HDCP_VIDEO_MUTE; 40 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1); 41 + } 42 + } 43 + 44 + void analogix_dp_stop_video(struct analogix_dp_device *dp) 45 + { 46 + u32 reg; 47 + 48 + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1); 49 + reg &= ~VIDEO_EN; 50 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1); 51 + } 52 + 53 + void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable) 54 + { 55 + u32 reg; 56 + 57 + if (enable) 58 + reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 | 59 + LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3; 60 + else 61 + reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 | 62 + LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0; 63 + 64 + writel(reg, dp->reg_base + ANALOGIX_DP_LANE_MAP); 65 + } 66 + 67 + void analogix_dp_init_analog_param(struct analogix_dp_device *dp) 68 + { 69 + u32 reg; 70 + 71 + reg = TX_TERMINAL_CTRL_50_OHM; 72 + writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_1); 73 + 74 + reg = SEL_24M | TX_DVDD_BIT_1_0625V; 75 + writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2); 76 + 77 + if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) { 78 + writel(REF_CLK_24M, dp->reg_base + ANALOGIX_DP_PLL_REG_1); 79 + writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2); 80 + writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3); 81 + writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4); 82 + writel(0x22, dp->reg_base + ANALOGIX_DP_PLL_REG_5); 83 + } 84 + 85 + reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO; 86 + writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_3); 87 + 88 + reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | 89 + TX_CUR1_2X | TX_CUR_16_MA; 90 + writel(reg, dp->reg_base + ANALOGIX_DP_PLL_FILTER_CTL_1); 91 + 92 + reg = CH3_AMP_400_MV | CH2_AMP_400_MV | 93 + CH1_AMP_400_MV | CH0_AMP_400_MV; 94 + writel(reg, dp->reg_base + ANALOGIX_DP_TX_AMP_TUNING_CTL); 95 + } 96 + 97 + void analogix_dp_init_interrupt(struct analogix_dp_device *dp) 98 + { 99 + /* Set interrupt pin assertion polarity as high */ 100 + writel(INT_POL1 | INT_POL0, dp->reg_base + ANALOGIX_DP_INT_CTL); 101 + 102 + /* Clear pending regisers */ 103 + writel(0xff, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1); 104 + writel(0x4f, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_2); 105 + writel(0xe0, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_3); 106 + writel(0xe7, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4); 107 + writel(0x63, dp->reg_base + ANALOGIX_DP_INT_STA); 108 + 109 + /* 0:mask,1: unmask */ 110 + writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1); 111 + writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2); 112 + writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3); 113 + writel(0x00, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4); 114 + writel(0x00, dp->reg_base + ANALOGIX_DP_INT_STA_MASK); 115 + } 116 + 117 + void analogix_dp_reset(struct analogix_dp_device *dp) 118 + { 119 + u32 reg; 120 + 121 + analogix_dp_stop_video(dp); 122 + analogix_dp_enable_video_mute(dp, 0); 123 + 124 + reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N | 125 + AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N | 126 + HDCP_FUNC_EN_N | SW_FUNC_EN_N; 127 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1); 128 + 129 + reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N | 130 + SERDES_FIFO_FUNC_EN_N | 131 + LS_CLK_DOMAIN_FUNC_EN_N; 132 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2); 133 + 134 + usleep_range(20, 30); 135 + 136 + analogix_dp_lane_swap(dp, 0); 137 + 138 + writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_1); 139 + writel(0x40, dp->reg_base + ANALOGIX_DP_SYS_CTL_2); 140 + writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_3); 141 + writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_4); 142 + 143 + writel(0x0, dp->reg_base + ANALOGIX_DP_PKT_SEND_CTL); 144 + writel(0x0, dp->reg_base + ANALOGIX_DP_HDCP_CTL); 145 + 146 + writel(0x5e, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_L); 147 + writel(0x1a, dp->reg_base + ANALOGIX_DP_HPD_DEGLITCH_H); 148 + 149 + writel(0x10, dp->reg_base + ANALOGIX_DP_LINK_DEBUG_CTL); 150 + 151 + writel(0x0, dp->reg_base + ANALOGIX_DP_PHY_TEST); 152 + 153 + writel(0x0, dp->reg_base + ANALOGIX_DP_VIDEO_FIFO_THRD); 154 + writel(0x20, dp->reg_base + ANALOGIX_DP_AUDIO_MARGIN); 155 + 156 + writel(0x4, dp->reg_base + ANALOGIX_DP_M_VID_GEN_FILTER_TH); 157 + writel(0x2, dp->reg_base + ANALOGIX_DP_M_AUD_GEN_FILTER_TH); 158 + 159 + writel(0x00000101, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL); 160 + } 161 + 162 + void analogix_dp_swreset(struct analogix_dp_device *dp) 163 + { 164 + writel(RESET_DP_TX, dp->reg_base + ANALOGIX_DP_TX_SW_RESET); 165 + } 166 + 167 + void analogix_dp_config_interrupt(struct analogix_dp_device *dp) 168 + { 169 + u32 reg; 170 + 171 + /* 0: mask, 1: unmask */ 172 + reg = COMMON_INT_MASK_1; 173 + writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_1); 174 + 175 + reg = COMMON_INT_MASK_2; 176 + writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_2); 177 + 178 + reg = COMMON_INT_MASK_3; 179 + writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_3); 180 + 181 + reg = COMMON_INT_MASK_4; 182 + writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4); 183 + 184 + reg = INT_STA_MASK; 185 + writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK); 186 + } 187 + 188 + void analogix_dp_mute_hpd_interrupt(struct analogix_dp_device *dp) 189 + { 190 + u32 reg; 191 + 192 + /* 0: mask, 1: unmask */ 193 + reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4); 194 + reg &= ~COMMON_INT_MASK_4; 195 + writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4); 196 + 197 + reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA_MASK); 198 + reg &= ~INT_STA_MASK; 199 + writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK); 200 + } 201 + 202 + void analogix_dp_unmute_hpd_interrupt(struct analogix_dp_device *dp) 203 + { 204 + u32 reg; 205 + 206 + /* 0: mask, 1: unmask */ 207 + reg = COMMON_INT_MASK_4; 208 + writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_MASK_4); 209 + 210 + reg = INT_STA_MASK; 211 + writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA_MASK); 212 + } 213 + 214 + enum pll_status analogix_dp_get_pll_lock_status(struct analogix_dp_device *dp) 215 + { 216 + u32 reg; 217 + 218 + reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL); 219 + if (reg & PLL_LOCK) 220 + return PLL_LOCKED; 221 + else 222 + return PLL_UNLOCKED; 223 + } 224 + 225 + void analogix_dp_set_pll_power_down(struct analogix_dp_device *dp, bool enable) 226 + { 227 + u32 reg; 228 + 229 + if (enable) { 230 + reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL); 231 + reg |= DP_PLL_PD; 232 + writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL); 233 + } else { 234 + reg = readl(dp->reg_base + ANALOGIX_DP_PLL_CTL); 235 + reg &= ~DP_PLL_PD; 236 + writel(reg, dp->reg_base + ANALOGIX_DP_PLL_CTL); 237 + } 238 + } 239 + 240 + void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp, 241 + enum analog_power_block block, 242 + bool enable) 243 + { 244 + u32 reg; 245 + u32 phy_pd_addr = ANALOGIX_DP_PHY_PD; 246 + 247 + if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) 248 + phy_pd_addr = ANALOGIX_DP_PD; 249 + 250 + switch (block) { 251 + case AUX_BLOCK: 252 + if (enable) { 253 + reg = readl(dp->reg_base + phy_pd_addr); 254 + reg |= AUX_PD; 255 + writel(reg, dp->reg_base + phy_pd_addr); 256 + } else { 257 + reg = readl(dp->reg_base + phy_pd_addr); 258 + reg &= ~AUX_PD; 259 + writel(reg, dp->reg_base + phy_pd_addr); 260 + } 261 + break; 262 + case CH0_BLOCK: 263 + if (enable) { 264 + reg = readl(dp->reg_base + phy_pd_addr); 265 + reg |= CH0_PD; 266 + writel(reg, dp->reg_base + phy_pd_addr); 267 + } else { 268 + reg = readl(dp->reg_base + phy_pd_addr); 269 + reg &= ~CH0_PD; 270 + writel(reg, dp->reg_base + phy_pd_addr); 271 + } 272 + break; 273 + case CH1_BLOCK: 274 + if (enable) { 275 + reg = readl(dp->reg_base + phy_pd_addr); 276 + reg |= CH1_PD; 277 + writel(reg, dp->reg_base + phy_pd_addr); 278 + } else { 279 + reg = readl(dp->reg_base + phy_pd_addr); 280 + reg &= ~CH1_PD; 281 + writel(reg, dp->reg_base + phy_pd_addr); 282 + } 283 + break; 284 + case CH2_BLOCK: 285 + if (enable) { 286 + reg = readl(dp->reg_base + phy_pd_addr); 287 + reg |= CH2_PD; 288 + writel(reg, dp->reg_base + phy_pd_addr); 289 + } else { 290 + reg = readl(dp->reg_base + phy_pd_addr); 291 + reg &= ~CH2_PD; 292 + writel(reg, dp->reg_base + phy_pd_addr); 293 + } 294 + break; 295 + case CH3_BLOCK: 296 + if (enable) { 297 + reg = readl(dp->reg_base + phy_pd_addr); 298 + reg |= CH3_PD; 299 + writel(reg, dp->reg_base + phy_pd_addr); 300 + } else { 301 + reg = readl(dp->reg_base + phy_pd_addr); 302 + reg &= ~CH3_PD; 303 + writel(reg, dp->reg_base + phy_pd_addr); 304 + } 305 + break; 306 + case ANALOG_TOTAL: 307 + if (enable) { 308 + reg = readl(dp->reg_base + phy_pd_addr); 309 + reg |= DP_PHY_PD; 310 + writel(reg, dp->reg_base + phy_pd_addr); 311 + } else { 312 + reg = readl(dp->reg_base + phy_pd_addr); 313 + reg &= ~DP_PHY_PD; 314 + writel(reg, dp->reg_base + phy_pd_addr); 315 + } 316 + break; 317 + case POWER_ALL: 318 + if (enable) { 319 + reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD | 320 + CH1_PD | CH0_PD; 321 + writel(reg, dp->reg_base + phy_pd_addr); 322 + } else { 323 + writel(0x00, dp->reg_base + phy_pd_addr); 324 + } 325 + break; 326 + default: 327 + break; 328 + } 329 + } 330 + 331 + void analogix_dp_init_analog_func(struct analogix_dp_device *dp) 332 + { 333 + u32 reg; 334 + int timeout_loop = 0; 335 + 336 + analogix_dp_set_analog_power_down(dp, POWER_ALL, 0); 337 + 338 + reg = PLL_LOCK_CHG; 339 + writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1); 340 + 341 + reg = readl(dp->reg_base + ANALOGIX_DP_DEBUG_CTL); 342 + reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL); 343 + writel(reg, dp->reg_base + ANALOGIX_DP_DEBUG_CTL); 344 + 345 + /* Power up PLL */ 346 + if (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 347 + analogix_dp_set_pll_power_down(dp, 0); 348 + 349 + while (analogix_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 350 + timeout_loop++; 351 + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 352 + dev_err(dp->dev, "failed to get pll lock status\n"); 353 + return; 354 + } 355 + usleep_range(10, 20); 356 + } 357 + } 358 + 359 + /* Enable Serdes FIFO function and Link symbol clock domain module */ 360 + reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2); 361 + reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N 362 + | AUX_FUNC_EN_N); 363 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2); 364 + } 365 + 366 + void analogix_dp_clear_hotplug_interrupts(struct analogix_dp_device *dp) 367 + { 368 + u32 reg; 369 + 370 + if (gpio_is_valid(dp->hpd_gpio)) 371 + return; 372 + 373 + reg = HOTPLUG_CHG | HPD_LOST | PLUG; 374 + writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4); 375 + 376 + reg = INT_HPD; 377 + writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA); 378 + } 379 + 380 + void analogix_dp_init_hpd(struct analogix_dp_device *dp) 381 + { 382 + u32 reg; 383 + 384 + if (gpio_is_valid(dp->hpd_gpio)) 385 + return; 386 + 387 + analogix_dp_clear_hotplug_interrupts(dp); 388 + 389 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3); 390 + reg &= ~(F_HPD | HPD_CTRL); 391 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3); 392 + } 393 + 394 + void analogix_dp_force_hpd(struct analogix_dp_device *dp) 395 + { 396 + u32 reg; 397 + 398 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3); 399 + reg = (F_HPD | HPD_CTRL); 400 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3); 401 + } 402 + 403 + enum dp_irq_type analogix_dp_get_irq_type(struct analogix_dp_device *dp) 404 + { 405 + u32 reg; 406 + 407 + if (gpio_is_valid(dp->hpd_gpio)) { 408 + reg = gpio_get_value(dp->hpd_gpio); 409 + if (reg) 410 + return DP_IRQ_TYPE_HP_CABLE_IN; 411 + else 412 + return DP_IRQ_TYPE_HP_CABLE_OUT; 413 + } else { 414 + /* Parse hotplug interrupt status register */ 415 + reg = readl(dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_4); 416 + 417 + if (reg & PLUG) 418 + return DP_IRQ_TYPE_HP_CABLE_IN; 419 + 420 + if (reg & HPD_LOST) 421 + return DP_IRQ_TYPE_HP_CABLE_OUT; 422 + 423 + if (reg & HOTPLUG_CHG) 424 + return DP_IRQ_TYPE_HP_CHANGE; 425 + 426 + return DP_IRQ_TYPE_UNKNOWN; 427 + } 428 + } 429 + 430 + void analogix_dp_reset_aux(struct analogix_dp_device *dp) 431 + { 432 + u32 reg; 433 + 434 + /* Disable AUX channel module */ 435 + reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2); 436 + reg |= AUX_FUNC_EN_N; 437 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2); 438 + } 439 + 440 + void analogix_dp_init_aux(struct analogix_dp_device *dp) 441 + { 442 + u32 reg; 443 + 444 + /* Clear inerrupts related to AUX channel */ 445 + reg = RPLY_RECEIV | AUX_ERR; 446 + writel(reg, dp->reg_base + ANALOGIX_DP_INT_STA); 447 + 448 + analogix_dp_reset_aux(dp); 449 + 450 + /* Disable AUX transaction H/W retry */ 451 + if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) 452 + reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) | 453 + AUX_HW_RETRY_COUNT_SEL(3) | 454 + AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; 455 + else 456 + reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | 457 + AUX_HW_RETRY_COUNT_SEL(0) | 458 + AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; 459 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_HW_RETRY_CTL); 460 + 461 + /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */ 462 + reg = DEFER_CTRL_EN | DEFER_COUNT(1); 463 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_DEFER_CTL); 464 + 465 + /* Enable AUX channel module */ 466 + reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_2); 467 + reg &= ~AUX_FUNC_EN_N; 468 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_2); 469 + } 470 + 471 + int analogix_dp_get_plug_in_status(struct analogix_dp_device *dp) 472 + { 473 + u32 reg; 474 + 475 + if (gpio_is_valid(dp->hpd_gpio)) { 476 + if (gpio_get_value(dp->hpd_gpio)) 477 + return 0; 478 + } else { 479 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3); 480 + if (reg & HPD_STATUS) 481 + return 0; 482 + } 483 + 484 + return -EINVAL; 485 + } 486 + 487 + void analogix_dp_enable_sw_function(struct analogix_dp_device *dp) 488 + { 489 + u32 reg; 490 + 491 + reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1); 492 + reg &= ~SW_FUNC_EN_N; 493 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1); 494 + } 495 + 496 + int analogix_dp_start_aux_transaction(struct analogix_dp_device *dp) 497 + { 498 + int reg; 499 + int retval = 0; 500 + int timeout_loop = 0; 501 + 502 + /* Enable AUX CH operation */ 503 + reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2); 504 + reg |= AUX_EN; 505 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2); 506 + 507 + /* Is AUX CH command reply received? */ 508 + reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA); 509 + while (!(reg & RPLY_RECEIV)) { 510 + timeout_loop++; 511 + if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 512 + dev_err(dp->dev, "AUX CH command reply failed!\n"); 513 + return -ETIMEDOUT; 514 + } 515 + reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA); 516 + usleep_range(10, 11); 517 + } 518 + 519 + /* Clear interrupt source for AUX CH command reply */ 520 + writel(RPLY_RECEIV, dp->reg_base + ANALOGIX_DP_INT_STA); 521 + 522 + /* Clear interrupt source for AUX CH access error */ 523 + reg = readl(dp->reg_base + ANALOGIX_DP_INT_STA); 524 + if (reg & AUX_ERR) { 525 + writel(AUX_ERR, dp->reg_base + ANALOGIX_DP_INT_STA); 526 + return -EREMOTEIO; 527 + } 528 + 529 + /* Check AUX CH error access status */ 530 + reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_STA); 531 + if ((reg & AUX_STATUS_MASK) != 0) { 532 + dev_err(dp->dev, "AUX CH error happens: %d\n\n", 533 + reg & AUX_STATUS_MASK); 534 + return -EREMOTEIO; 535 + } 536 + 537 + return retval; 538 + } 539 + 540 + int analogix_dp_write_byte_to_dpcd(struct analogix_dp_device *dp, 541 + unsigned int reg_addr, 542 + unsigned char data) 543 + { 544 + u32 reg; 545 + int i; 546 + int retval; 547 + 548 + for (i = 0; i < 3; i++) { 549 + /* Clear AUX CH data buffer */ 550 + reg = BUF_CLR; 551 + writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 552 + 553 + /* Select DPCD device address */ 554 + reg = AUX_ADDR_7_0(reg_addr); 555 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0); 556 + reg = AUX_ADDR_15_8(reg_addr); 557 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8); 558 + reg = AUX_ADDR_19_16(reg_addr); 559 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16); 560 + 561 + /* Write data buffer */ 562 + reg = (unsigned int)data; 563 + writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0); 564 + 565 + /* 566 + * Set DisplayPort transaction and write 1 byte 567 + * If bit 3 is 1, DisplayPort transaction. 568 + * If Bit 3 is 0, I2C transaction. 569 + */ 570 + reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; 571 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 572 + 573 + /* Start AUX transaction */ 574 + retval = analogix_dp_start_aux_transaction(dp); 575 + if (retval == 0) 576 + break; 577 + 578 + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); 579 + } 580 + 581 + return retval; 582 + } 583 + 584 + int analogix_dp_read_byte_from_dpcd(struct analogix_dp_device *dp, 585 + unsigned int reg_addr, 586 + unsigned char *data) 587 + { 588 + u32 reg; 589 + int i; 590 + int retval; 591 + 592 + for (i = 0; i < 3; i++) { 593 + /* Clear AUX CH data buffer */ 594 + reg = BUF_CLR; 595 + writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 596 + 597 + /* Select DPCD device address */ 598 + reg = AUX_ADDR_7_0(reg_addr); 599 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0); 600 + reg = AUX_ADDR_15_8(reg_addr); 601 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8); 602 + reg = AUX_ADDR_19_16(reg_addr); 603 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16); 604 + 605 + /* 606 + * Set DisplayPort transaction and read 1 byte 607 + * If bit 3 is 1, DisplayPort transaction. 608 + * If Bit 3 is 0, I2C transaction. 609 + */ 610 + reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; 611 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 612 + 613 + /* Start AUX transaction */ 614 + retval = analogix_dp_start_aux_transaction(dp); 615 + if (retval == 0) 616 + break; 617 + 618 + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); 619 + } 620 + 621 + /* Read data buffer */ 622 + reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0); 623 + *data = (unsigned char)(reg & 0xff); 624 + 625 + return retval; 626 + } 627 + 628 + int analogix_dp_write_bytes_to_dpcd(struct analogix_dp_device *dp, 629 + unsigned int reg_addr, 630 + unsigned int count, 631 + unsigned char data[]) 632 + { 633 + u32 reg; 634 + unsigned int start_offset; 635 + unsigned int cur_data_count; 636 + unsigned int cur_data_idx; 637 + int i; 638 + int retval = 0; 639 + 640 + /* Clear AUX CH data buffer */ 641 + reg = BUF_CLR; 642 + writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 643 + 644 + start_offset = 0; 645 + while (start_offset < count) { 646 + /* Buffer size of AUX CH is 16 * 4bytes */ 647 + if ((count - start_offset) > 16) 648 + cur_data_count = 16; 649 + else 650 + cur_data_count = count - start_offset; 651 + 652 + for (i = 0; i < 3; i++) { 653 + /* Select DPCD device address */ 654 + reg = AUX_ADDR_7_0(reg_addr + start_offset); 655 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0); 656 + reg = AUX_ADDR_15_8(reg_addr + start_offset); 657 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8); 658 + reg = AUX_ADDR_19_16(reg_addr + start_offset); 659 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16); 660 + 661 + for (cur_data_idx = 0; cur_data_idx < cur_data_count; 662 + cur_data_idx++) { 663 + reg = data[start_offset + cur_data_idx]; 664 + writel(reg, dp->reg_base + 665 + ANALOGIX_DP_BUF_DATA_0 + 666 + 4 * cur_data_idx); 667 + } 668 + 669 + /* 670 + * Set DisplayPort transaction and write 671 + * If bit 3 is 1, DisplayPort transaction. 672 + * If Bit 3 is 0, I2C transaction. 673 + */ 674 + reg = AUX_LENGTH(cur_data_count) | 675 + AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; 676 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 677 + 678 + /* Start AUX transaction */ 679 + retval = analogix_dp_start_aux_transaction(dp); 680 + if (retval == 0) 681 + break; 682 + 683 + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 684 + __func__); 685 + } 686 + 687 + start_offset += cur_data_count; 688 + } 689 + 690 + return retval; 691 + } 692 + 693 + int analogix_dp_read_bytes_from_dpcd(struct analogix_dp_device *dp, 694 + unsigned int reg_addr, 695 + unsigned int count, 696 + unsigned char data[]) 697 + { 698 + u32 reg; 699 + unsigned int start_offset; 700 + unsigned int cur_data_count; 701 + unsigned int cur_data_idx; 702 + int i; 703 + int retval = 0; 704 + 705 + /* Clear AUX CH data buffer */ 706 + reg = BUF_CLR; 707 + writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 708 + 709 + start_offset = 0; 710 + while (start_offset < count) { 711 + /* Buffer size of AUX CH is 16 * 4bytes */ 712 + if ((count - start_offset) > 16) 713 + cur_data_count = 16; 714 + else 715 + cur_data_count = count - start_offset; 716 + 717 + /* AUX CH Request Transaction process */ 718 + for (i = 0; i < 3; i++) { 719 + /* Select DPCD device address */ 720 + reg = AUX_ADDR_7_0(reg_addr + start_offset); 721 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0); 722 + reg = AUX_ADDR_15_8(reg_addr + start_offset); 723 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8); 724 + reg = AUX_ADDR_19_16(reg_addr + start_offset); 725 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16); 726 + 727 + /* 728 + * Set DisplayPort transaction and read 729 + * If bit 3 is 1, DisplayPort transaction. 730 + * If Bit 3 is 0, I2C transaction. 731 + */ 732 + reg = AUX_LENGTH(cur_data_count) | 733 + AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; 734 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 735 + 736 + /* Start AUX transaction */ 737 + retval = analogix_dp_start_aux_transaction(dp); 738 + if (retval == 0) 739 + break; 740 + 741 + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 742 + __func__); 743 + } 744 + 745 + for (cur_data_idx = 0; cur_data_idx < cur_data_count; 746 + cur_data_idx++) { 747 + reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 748 + + 4 * cur_data_idx); 749 + data[start_offset + cur_data_idx] = 750 + (unsigned char)reg; 751 + } 752 + 753 + start_offset += cur_data_count; 754 + } 755 + 756 + return retval; 757 + } 758 + 759 + int analogix_dp_select_i2c_device(struct analogix_dp_device *dp, 760 + unsigned int device_addr, 761 + unsigned int reg_addr) 762 + { 763 + u32 reg; 764 + int retval; 765 + 766 + /* Set EDID device address */ 767 + reg = device_addr; 768 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_ADDR_7_0); 769 + writel(0x0, dp->reg_base + ANALOGIX_DP_AUX_ADDR_15_8); 770 + writel(0x0, dp->reg_base + ANALOGIX_DP_AUX_ADDR_19_16); 771 + 772 + /* Set offset from base address of EDID device */ 773 + writel(reg_addr, dp->reg_base + ANALOGIX_DP_BUF_DATA_0); 774 + 775 + /* 776 + * Set I2C transaction and write address 777 + * If bit 3 is 1, DisplayPort transaction. 778 + * If Bit 3 is 0, I2C transaction. 779 + */ 780 + reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT | 781 + AUX_TX_COMM_WRITE; 782 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 783 + 784 + /* Start AUX transaction */ 785 + retval = analogix_dp_start_aux_transaction(dp); 786 + if (retval != 0) 787 + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); 788 + 789 + return retval; 790 + } 791 + 792 + int analogix_dp_read_byte_from_i2c(struct analogix_dp_device *dp, 793 + unsigned int device_addr, 794 + unsigned int reg_addr, 795 + unsigned int *data) 796 + { 797 + u32 reg; 798 + int i; 799 + int retval; 800 + 801 + for (i = 0; i < 3; i++) { 802 + /* Clear AUX CH data buffer */ 803 + reg = BUF_CLR; 804 + writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 805 + 806 + /* Select EDID device */ 807 + retval = analogix_dp_select_i2c_device(dp, device_addr, 808 + reg_addr); 809 + if (retval != 0) 810 + continue; 811 + 812 + /* 813 + * Set I2C transaction and read data 814 + * If bit 3 is 1, DisplayPort transaction. 815 + * If Bit 3 is 0, I2C transaction. 816 + */ 817 + reg = AUX_TX_COMM_I2C_TRANSACTION | 818 + AUX_TX_COMM_READ; 819 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_1); 820 + 821 + /* Start AUX transaction */ 822 + retval = analogix_dp_start_aux_transaction(dp); 823 + if (retval == 0) 824 + break; 825 + 826 + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); 827 + } 828 + 829 + /* Read data */ 830 + if (retval == 0) 831 + *data = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0); 832 + 833 + return retval; 834 + } 835 + 836 + int analogix_dp_read_bytes_from_i2c(struct analogix_dp_device *dp, 837 + unsigned int device_addr, 838 + unsigned int reg_addr, 839 + unsigned int count, 840 + unsigned char edid[]) 841 + { 842 + u32 reg; 843 + unsigned int i, j; 844 + unsigned int cur_data_idx; 845 + unsigned int defer = 0; 846 + int retval = 0; 847 + 848 + for (i = 0; i < count; i += 16) { 849 + for (j = 0; j < 3; j++) { 850 + /* Clear AUX CH data buffer */ 851 + reg = BUF_CLR; 852 + writel(reg, dp->reg_base + ANALOGIX_DP_BUFFER_DATA_CTL); 853 + 854 + /* Set normal AUX CH command */ 855 + reg = readl(dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2); 856 + reg &= ~ADDR_ONLY; 857 + writel(reg, dp->reg_base + ANALOGIX_DP_AUX_CH_CTL_2); 858 + 859 + /* 860 + * If Rx sends defer, Tx sends only reads 861 + * request without sending address 862 + */ 863 + if (!defer) 864 + retval = analogix_dp_select_i2c_device(dp, 865 + device_addr, reg_addr + i); 866 + else 867 + defer = 0; 868 + 869 + if (retval == 0) { 870 + /* 871 + * Set I2C transaction and write data 872 + * If bit 3 is 1, DisplayPort transaction. 873 + * If Bit 3 is 0, I2C transaction. 874 + */ 875 + reg = AUX_LENGTH(16) | 876 + AUX_TX_COMM_I2C_TRANSACTION | 877 + AUX_TX_COMM_READ; 878 + writel(reg, dp->reg_base + 879 + ANALOGIX_DP_AUX_CH_CTL_1); 880 + 881 + /* Start AUX transaction */ 882 + retval = analogix_dp_start_aux_transaction(dp); 883 + if (retval == 0) 884 + break; 885 + 886 + dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 887 + __func__); 888 + } 889 + /* Check if Rx sends defer */ 890 + reg = readl(dp->reg_base + ANALOGIX_DP_AUX_RX_COMM); 891 + if (reg == AUX_RX_COMM_AUX_DEFER || 892 + reg == AUX_RX_COMM_I2C_DEFER) { 893 + dev_err(dp->dev, "Defer: %d\n\n", reg); 894 + defer = 1; 895 + } 896 + } 897 + 898 + for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) { 899 + reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 900 + + 4 * cur_data_idx); 901 + edid[i + cur_data_idx] = (unsigned char)reg; 902 + } 903 + } 904 + 905 + return retval; 906 + } 907 + 908 + void analogix_dp_set_link_bandwidth(struct analogix_dp_device *dp, u32 bwtype) 909 + { 910 + u32 reg; 911 + 912 + reg = bwtype; 913 + if ((bwtype == DP_LINK_BW_2_7) || (bwtype == DP_LINK_BW_1_62)) 914 + writel(reg, dp->reg_base + ANALOGIX_DP_LINK_BW_SET); 915 + } 916 + 917 + void analogix_dp_get_link_bandwidth(struct analogix_dp_device *dp, u32 *bwtype) 918 + { 919 + u32 reg; 920 + 921 + reg = readl(dp->reg_base + ANALOGIX_DP_LINK_BW_SET); 922 + *bwtype = reg; 923 + } 924 + 925 + void analogix_dp_set_lane_count(struct analogix_dp_device *dp, u32 count) 926 + { 927 + u32 reg; 928 + 929 + reg = count; 930 + writel(reg, dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET); 931 + } 932 + 933 + void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count) 934 + { 935 + u32 reg; 936 + 937 + reg = readl(dp->reg_base + ANALOGIX_DP_LANE_COUNT_SET); 938 + *count = reg; 939 + } 940 + 941 + void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp, 942 + bool enable) 943 + { 944 + u32 reg; 945 + 946 + if (enable) { 947 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4); 948 + reg |= ENHANCED; 949 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4); 950 + } else { 951 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4); 952 + reg &= ~ENHANCED; 953 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4); 954 + } 955 + } 956 + 957 + void analogix_dp_set_training_pattern(struct analogix_dp_device *dp, 958 + enum pattern_set pattern) 959 + { 960 + u32 reg; 961 + 962 + switch (pattern) { 963 + case PRBS7: 964 + reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7; 965 + writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET); 966 + break; 967 + case D10_2: 968 + reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2; 969 + writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET); 970 + break; 971 + case TRAINING_PTN1: 972 + reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1; 973 + writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET); 974 + break; 975 + case TRAINING_PTN2: 976 + reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2; 977 + writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET); 978 + break; 979 + case DP_NONE: 980 + reg = SCRAMBLING_ENABLE | 981 + LINK_QUAL_PATTERN_SET_DISABLE | 982 + SW_TRAINING_PATTERN_SET_NORMAL; 983 + writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET); 984 + break; 985 + default: 986 + break; 987 + } 988 + } 989 + 990 + void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp, 991 + u32 level) 992 + { 993 + u32 reg; 994 + 995 + reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL); 996 + reg &= ~PRE_EMPHASIS_SET_MASK; 997 + reg |= level << PRE_EMPHASIS_SET_SHIFT; 998 + writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL); 999 + } 1000 + 1001 + void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp, 1002 + u32 level) 1003 + { 1004 + u32 reg; 1005 + 1006 + reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL); 1007 + reg &= ~PRE_EMPHASIS_SET_MASK; 1008 + reg |= level << PRE_EMPHASIS_SET_SHIFT; 1009 + writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL); 1010 + } 1011 + 1012 + void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp, 1013 + u32 level) 1014 + { 1015 + u32 reg; 1016 + 1017 + reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL); 1018 + reg &= ~PRE_EMPHASIS_SET_MASK; 1019 + reg |= level << PRE_EMPHASIS_SET_SHIFT; 1020 + writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL); 1021 + } 1022 + 1023 + void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp, 1024 + u32 level) 1025 + { 1026 + u32 reg; 1027 + 1028 + reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL); 1029 + reg &= ~PRE_EMPHASIS_SET_MASK; 1030 + reg |= level << PRE_EMPHASIS_SET_SHIFT; 1031 + writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL); 1032 + } 1033 + 1034 + void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp, 1035 + u32 training_lane) 1036 + { 1037 + u32 reg; 1038 + 1039 + reg = training_lane; 1040 + writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL); 1041 + } 1042 + 1043 + void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp, 1044 + u32 training_lane) 1045 + { 1046 + u32 reg; 1047 + 1048 + reg = training_lane; 1049 + writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL); 1050 + } 1051 + 1052 + void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp, 1053 + u32 training_lane) 1054 + { 1055 + u32 reg; 1056 + 1057 + reg = training_lane; 1058 + writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL); 1059 + } 1060 + 1061 + void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp, 1062 + u32 training_lane) 1063 + { 1064 + u32 reg; 1065 + 1066 + reg = training_lane; 1067 + writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL); 1068 + } 1069 + 1070 + u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp) 1071 + { 1072 + u32 reg; 1073 + 1074 + reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL); 1075 + return reg; 1076 + } 1077 + 1078 + u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp) 1079 + { 1080 + u32 reg; 1081 + 1082 + reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL); 1083 + return reg; 1084 + } 1085 + 1086 + u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp) 1087 + { 1088 + u32 reg; 1089 + 1090 + reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL); 1091 + return reg; 1092 + } 1093 + 1094 + u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp) 1095 + { 1096 + u32 reg; 1097 + 1098 + reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL); 1099 + return reg; 1100 + } 1101 + 1102 + void analogix_dp_reset_macro(struct analogix_dp_device *dp) 1103 + { 1104 + u32 reg; 1105 + 1106 + reg = readl(dp->reg_base + ANALOGIX_DP_PHY_TEST); 1107 + reg |= MACRO_RST; 1108 + writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST); 1109 + 1110 + /* 10 us is the minimum reset time. */ 1111 + usleep_range(10, 20); 1112 + 1113 + reg &= ~MACRO_RST; 1114 + writel(reg, dp->reg_base + ANALOGIX_DP_PHY_TEST); 1115 + } 1116 + 1117 + void analogix_dp_init_video(struct analogix_dp_device *dp) 1118 + { 1119 + u32 reg; 1120 + 1121 + reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG; 1122 + writel(reg, dp->reg_base + ANALOGIX_DP_COMMON_INT_STA_1); 1123 + 1124 + reg = 0x0; 1125 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1); 1126 + 1127 + reg = CHA_CRI(4) | CHA_CTRL; 1128 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2); 1129 + 1130 + reg = 0x0; 1131 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3); 1132 + 1133 + reg = VID_HRES_TH(2) | VID_VRES_TH(0); 1134 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_8); 1135 + } 1136 + 1137 + void analogix_dp_set_video_color_format(struct analogix_dp_device *dp) 1138 + { 1139 + u32 reg; 1140 + 1141 + /* Configure the input color depth, color space, dynamic range */ 1142 + reg = (dp->video_info.dynamic_range << IN_D_RANGE_SHIFT) | 1143 + (dp->video_info.color_depth << IN_BPC_SHIFT) | 1144 + (dp->video_info.color_space << IN_COLOR_F_SHIFT); 1145 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_2); 1146 + 1147 + /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ 1148 + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3); 1149 + reg &= ~IN_YC_COEFFI_MASK; 1150 + if (dp->video_info.ycbcr_coeff) 1151 + reg |= IN_YC_COEFFI_ITU709; 1152 + else 1153 + reg |= IN_YC_COEFFI_ITU601; 1154 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_3); 1155 + } 1156 + 1157 + int analogix_dp_is_slave_video_stream_clock_on(struct analogix_dp_device *dp) 1158 + { 1159 + u32 reg; 1160 + 1161 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1); 1162 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_1); 1163 + 1164 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_1); 1165 + 1166 + if (!(reg & DET_STA)) { 1167 + dev_dbg(dp->dev, "Input stream clock not detected.\n"); 1168 + return -EINVAL; 1169 + } 1170 + 1171 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2); 1172 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_2); 1173 + 1174 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_2); 1175 + dev_dbg(dp->dev, "wait SYS_CTL_2.\n"); 1176 + 1177 + if (reg & CHA_STA) { 1178 + dev_dbg(dp->dev, "Input stream clk is changing\n"); 1179 + return -EINVAL; 1180 + } 1181 + 1182 + return 0; 1183 + } 1184 + 1185 + void analogix_dp_set_video_cr_mn(struct analogix_dp_device *dp, 1186 + enum clock_recovery_m_value_type type, 1187 + u32 m_value, u32 n_value) 1188 + { 1189 + u32 reg; 1190 + 1191 + if (type == REGISTER_M) { 1192 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4); 1193 + reg |= FIX_M_VID; 1194 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4); 1195 + reg = m_value & 0xff; 1196 + writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_0); 1197 + reg = (m_value >> 8) & 0xff; 1198 + writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_1); 1199 + reg = (m_value >> 16) & 0xff; 1200 + writel(reg, dp->reg_base + ANALOGIX_DP_M_VID_2); 1201 + 1202 + reg = n_value & 0xff; 1203 + writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_0); 1204 + reg = (n_value >> 8) & 0xff; 1205 + writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_1); 1206 + reg = (n_value >> 16) & 0xff; 1207 + writel(reg, dp->reg_base + ANALOGIX_DP_N_VID_2); 1208 + } else { 1209 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_4); 1210 + reg &= ~FIX_M_VID; 1211 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_4); 1212 + 1213 + writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_0); 1214 + writel(0x80, dp->reg_base + ANALOGIX_DP_N_VID_1); 1215 + writel(0x00, dp->reg_base + ANALOGIX_DP_N_VID_2); 1216 + } 1217 + } 1218 + 1219 + void analogix_dp_set_video_timing_mode(struct analogix_dp_device *dp, u32 type) 1220 + { 1221 + u32 reg; 1222 + 1223 + if (type == VIDEO_TIMING_FROM_CAPTURE) { 1224 + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 1225 + reg &= ~FORMAT_SEL; 1226 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 1227 + } else { 1228 + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 1229 + reg |= FORMAT_SEL; 1230 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 1231 + } 1232 + } 1233 + 1234 + void analogix_dp_enable_video_master(struct analogix_dp_device *dp, bool enable) 1235 + { 1236 + u32 reg; 1237 + 1238 + if (enable) { 1239 + reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL); 1240 + reg &= ~VIDEO_MODE_MASK; 1241 + reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE; 1242 + writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL); 1243 + } else { 1244 + reg = readl(dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL); 1245 + reg &= ~VIDEO_MODE_MASK; 1246 + reg |= VIDEO_MODE_SLAVE_MODE; 1247 + writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL); 1248 + } 1249 + } 1250 + 1251 + void analogix_dp_start_video(struct analogix_dp_device *dp) 1252 + { 1253 + u32 reg; 1254 + 1255 + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1); 1256 + reg |= VIDEO_EN; 1257 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1); 1258 + } 1259 + 1260 + int analogix_dp_is_video_stream_on(struct analogix_dp_device *dp) 1261 + { 1262 + u32 reg; 1263 + 1264 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3); 1265 + writel(reg, dp->reg_base + ANALOGIX_DP_SYS_CTL_3); 1266 + 1267 + reg = readl(dp->reg_base + ANALOGIX_DP_SYS_CTL_3); 1268 + if (!(reg & STRM_VALID)) { 1269 + dev_dbg(dp->dev, "Input video stream is not detected.\n"); 1270 + return -EINVAL; 1271 + } 1272 + 1273 + return 0; 1274 + } 1275 + 1276 + void analogix_dp_config_video_slave_mode(struct analogix_dp_device *dp) 1277 + { 1278 + u32 reg; 1279 + 1280 + reg = readl(dp->reg_base + ANALOGIX_DP_FUNC_EN_1); 1281 + reg &= ~(MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N); 1282 + reg |= MASTER_VID_FUNC_EN_N; 1283 + writel(reg, dp->reg_base + ANALOGIX_DP_FUNC_EN_1); 1284 + 1285 + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 1286 + reg &= ~INTERACE_SCAN_CFG; 1287 + reg |= (dp->video_info.interlaced << 2); 1288 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 1289 + 1290 + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 1291 + reg &= ~VSYNC_POLARITY_CFG; 1292 + reg |= (dp->video_info.v_sync_polarity << 1); 1293 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 1294 + 1295 + reg = readl(dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 1296 + reg &= ~HSYNC_POLARITY_CFG; 1297 + reg |= (dp->video_info.h_sync_polarity << 0); 1298 + writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_10); 1299 + 1300 + reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; 1301 + writel(reg, dp->reg_base + ANALOGIX_DP_SOC_GENERAL_CTL); 1302 + } 1303 + 1304 + void analogix_dp_enable_scrambling(struct analogix_dp_device *dp) 1305 + { 1306 + u32 reg; 1307 + 1308 + reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET); 1309 + reg &= ~SCRAMBLING_DISABLE; 1310 + writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET); 1311 + } 1312 + 1313 + void analogix_dp_disable_scrambling(struct analogix_dp_device *dp) 1314 + { 1315 + u32 reg; 1316 + 1317 + reg = readl(dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET); 1318 + reg |= SCRAMBLING_DISABLE; 1319 + writel(reg, dp->reg_base + ANALOGIX_DP_TRAINING_PTN_SET); 1320 + }
+2 -1
drivers/gpu/drm/exynos/Kconfig
··· 71 71 This enables support for Exynos MIPI-DSI device. 72 72 73 73 config DRM_EXYNOS_DP 74 - bool "Display Port" 74 + bool "EXYNOS specific extensions for Analogix DP driver" 75 75 depends on DRM_EXYNOS_FIMD || DRM_EXYNOS7_DECON 76 + select DRM_ANALOGIX_DP 76 77 default DRM_EXYNOS 77 78 select DRM_PANEL 78 79 help
+1 -1
drivers/gpu/drm/exynos/Makefile
··· 12 12 exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON) += exynos7_drm_decon.o 13 13 exynosdrm-$(CONFIG_DRM_EXYNOS_DPI) += exynos_drm_dpi.o 14 14 exynosdrm-$(CONFIG_DRM_EXYNOS_DSI) += exynos_drm_dsi.o 15 - exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp_core.o exynos_dp_reg.o 15 + exynosdrm-$(CONFIG_DRM_EXYNOS_DP) += exynos_dp.o 16 16 exynosdrm-$(CONFIG_DRM_EXYNOS_MIXER) += exynos_mixer.o 17 17 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o 18 18 exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o
+314
drivers/gpu/drm/exynos/exynos_dp.c
··· 1 + /* 2 + * Samsung SoC DP (Display Port) interface driver. 3 + * 4 + * Copyright (C) 2012 Samsung Electronics Co., Ltd. 5 + * Author: Jingoo Han <jg1.han@samsung.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify it 8 + * under the terms of the GNU General Public License as published by the 9 + * Free Software Foundation; either version 2 of the License, or (at your 10 + * option) any later version. 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/err.h> 16 + #include <linux/clk.h> 17 + #include <linux/of_graph.h> 18 + #include <linux/component.h> 19 + #include <video/of_display_timing.h> 20 + #include <video/of_videomode.h> 21 + #include <video/videomode.h> 22 + 23 + #include <drm/drmP.h> 24 + #include <drm/drm_crtc.h> 25 + #include <drm/drm_crtc_helper.h> 26 + #include <drm/drm_panel.h> 27 + 28 + #include <drm/bridge/analogix_dp.h> 29 + #include <drm/exynos_drm.h> 30 + 31 + #include "exynos_drm_crtc.h" 32 + 33 + #define to_dp(nm) container_of(nm, struct exynos_dp_device, nm) 34 + 35 + struct exynos_dp_device { 36 + struct drm_encoder encoder; 37 + struct drm_connector connector; 38 + struct drm_bridge *ptn_bridge; 39 + struct drm_device *drm_dev; 40 + struct device *dev; 41 + 42 + struct videomode vm; 43 + struct analogix_dp_plat_data plat_data; 44 + }; 45 + 46 + int exynos_dp_crtc_clock_enable(struct analogix_dp_plat_data *plat_data, 47 + bool enable) 48 + { 49 + struct exynos_dp_device *dp = to_dp(plat_data); 50 + struct drm_encoder *encoder = &dp->encoder; 51 + struct exynos_drm_crtc *crtc; 52 + 53 + if (!encoder) 54 + return -1; 55 + 56 + crtc = to_exynos_crtc(encoder->crtc); 57 + if (crtc && crtc->ops && crtc->ops->clock_enable) 58 + crtc->ops->clock_enable(crtc, enable); 59 + 60 + return 0; 61 + } 62 + 63 + static int exynos_dp_poweron(struct analogix_dp_plat_data *plat_data) 64 + { 65 + return exynos_dp_crtc_clock_enable(plat_data, true); 66 + } 67 + 68 + static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data) 69 + { 70 + return exynos_dp_crtc_clock_enable(plat_data, false); 71 + } 72 + 73 + static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data) 74 + { 75 + struct exynos_dp_device *dp = to_dp(plat_data); 76 + struct drm_connector *connector = &dp->connector; 77 + struct drm_display_mode *mode; 78 + int num_modes = 0; 79 + 80 + if (dp->plat_data.panel) 81 + return num_modes; 82 + 83 + mode = drm_mode_create(connector->dev); 84 + if (!mode) { 85 + DRM_ERROR("failed to create a new display mode.\n"); 86 + return num_modes; 87 + } 88 + 89 + drm_display_mode_from_videomode(&dp->vm, mode); 90 + connector->display_info.width_mm = mode->width_mm; 91 + connector->display_info.height_mm = mode->height_mm; 92 + 93 + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 94 + drm_mode_set_name(mode); 95 + drm_mode_probed_add(connector, mode); 96 + 97 + return num_modes + 1; 98 + } 99 + 100 + static int exynos_dp_bridge_attach(struct analogix_dp_plat_data *plat_data, 101 + struct drm_bridge *bridge, 102 + struct drm_connector *connector) 103 + { 104 + struct exynos_dp_device *dp = to_dp(plat_data); 105 + struct drm_encoder *encoder = &dp->encoder; 106 + int ret; 107 + 108 + drm_connector_register(connector); 109 + 110 + /* Pre-empt DP connector creation if there's a bridge */ 111 + if (dp->ptn_bridge) { 112 + bridge->next = dp->ptn_bridge; 113 + dp->ptn_bridge->encoder = encoder; 114 + ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge); 115 + if (ret) { 116 + DRM_ERROR("Failed to attach bridge to drm\n"); 117 + bridge->next = NULL; 118 + return ret; 119 + } 120 + } 121 + 122 + return 0; 123 + } 124 + 125 + static void exynos_dp_mode_set(struct drm_encoder *encoder, 126 + struct drm_display_mode *mode, 127 + struct drm_display_mode *adjusted_mode) 128 + { 129 + } 130 + 131 + static void exynos_dp_nop(struct drm_encoder *encoder) 132 + { 133 + /* do nothing */ 134 + } 135 + 136 + static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = { 137 + .mode_set = exynos_dp_mode_set, 138 + .enable = exynos_dp_nop, 139 + .disable = exynos_dp_nop, 140 + }; 141 + 142 + static const struct drm_encoder_funcs exynos_dp_encoder_funcs = { 143 + .destroy = drm_encoder_cleanup, 144 + }; 145 + 146 + static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) 147 + { 148 + int ret; 149 + 150 + ret = of_get_videomode(dp->dev->of_node, &dp->vm, OF_USE_NATIVE_MODE); 151 + if (ret) { 152 + DRM_ERROR("failed: of_get_videomode() : %d\n", ret); 153 + return ret; 154 + } 155 + return 0; 156 + } 157 + 158 + static int exynos_dp_bind(struct device *dev, struct device *master, void *data) 159 + { 160 + struct exynos_dp_device *dp = dev_get_drvdata(dev); 161 + struct drm_encoder *encoder = &dp->encoder; 162 + struct drm_device *drm_dev = data; 163 + int pipe, ret; 164 + 165 + /* 166 + * Just like the probe function said, we don't need the 167 + * device drvrate anymore, we should leave the charge to 168 + * analogix dp driver, set the device drvdata to NULL. 169 + */ 170 + dev_set_drvdata(dev, NULL); 171 + 172 + dp->dev = dev; 173 + dp->drm_dev = drm_dev; 174 + 175 + dp->plat_data.dev_type = EXYNOS_DP; 176 + dp->plat_data.power_on = exynos_dp_poweron; 177 + dp->plat_data.power_off = exynos_dp_poweroff; 178 + dp->plat_data.attach = exynos_dp_bridge_attach; 179 + dp->plat_data.get_modes = exynos_dp_get_modes; 180 + 181 + if (!dp->plat_data.panel && !dp->ptn_bridge) { 182 + ret = exynos_dp_dt_parse_panel(dp); 183 + if (ret) 184 + return ret; 185 + } 186 + 187 + pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev, 188 + EXYNOS_DISPLAY_TYPE_LCD); 189 + if (pipe < 0) 190 + return pipe; 191 + 192 + encoder->possible_crtcs = 1 << pipe; 193 + 194 + DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); 195 + 196 + drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs, 197 + DRM_MODE_ENCODER_TMDS, NULL); 198 + 199 + drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs); 200 + 201 + dp->plat_data.encoder = encoder; 202 + 203 + return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); 204 + } 205 + 206 + static void exynos_dp_unbind(struct device *dev, struct device *master, 207 + void *data) 208 + { 209 + return analogix_dp_unbind(dev, master, data); 210 + } 211 + 212 + static const struct component_ops exynos_dp_ops = { 213 + .bind = exynos_dp_bind, 214 + .unbind = exynos_dp_unbind, 215 + }; 216 + 217 + static int exynos_dp_probe(struct platform_device *pdev) 218 + { 219 + struct device *dev = &pdev->dev; 220 + struct device_node *np = NULL, *endpoint = NULL; 221 + struct exynos_dp_device *dp; 222 + 223 + dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), 224 + GFP_KERNEL); 225 + if (!dp) 226 + return -ENOMEM; 227 + 228 + /* 229 + * We just use the drvdata until driver run into component 230 + * add function, and then we would set drvdata to null, so 231 + * that analogix dp driver would take charge of the drvdata. 232 + */ 233 + platform_set_drvdata(pdev, dp); 234 + 235 + /* This is for the backward compatibility. */ 236 + np = of_parse_phandle(dev->of_node, "panel", 0); 237 + if (np) { 238 + dp->plat_data.panel = of_drm_find_panel(np); 239 + of_node_put(np); 240 + if (!dp->plat_data.panel) 241 + return -EPROBE_DEFER; 242 + goto out; 243 + } 244 + 245 + endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); 246 + if (endpoint) { 247 + np = of_graph_get_remote_port_parent(endpoint); 248 + if (np) { 249 + /* The remote port can be either a panel or a bridge */ 250 + dp->plat_data.panel = of_drm_find_panel(np); 251 + if (!dp->plat_data.panel) { 252 + dp->ptn_bridge = of_drm_find_bridge(np); 253 + if (!dp->ptn_bridge) { 254 + of_node_put(np); 255 + return -EPROBE_DEFER; 256 + } 257 + } 258 + of_node_put(np); 259 + } else { 260 + DRM_ERROR("no remote endpoint device node found.\n"); 261 + return -EINVAL; 262 + } 263 + } else { 264 + DRM_ERROR("no port endpoint subnode found.\n"); 265 + return -EINVAL; 266 + } 267 + 268 + out: 269 + return component_add(&pdev->dev, &exynos_dp_ops); 270 + } 271 + 272 + static int exynos_dp_remove(struct platform_device *pdev) 273 + { 274 + component_del(&pdev->dev, &exynos_dp_ops); 275 + 276 + return 0; 277 + } 278 + 279 + #ifdef CONFIG_PM 280 + static int exynos_dp_suspend(struct device *dev) 281 + { 282 + return analogix_dp_suspend(dev); 283 + } 284 + 285 + static int exynos_dp_resume(struct device *dev) 286 + { 287 + return analogix_dp_resume(dev); 288 + } 289 + #endif 290 + 291 + static const struct dev_pm_ops exynos_dp_pm_ops = { 292 + SET_RUNTIME_PM_OPS(exynos_dp_suspend, exynos_dp_resume, NULL) 293 + }; 294 + 295 + static const struct of_device_id exynos_dp_match[] = { 296 + { .compatible = "samsung,exynos5-dp" }, 297 + {}, 298 + }; 299 + MODULE_DEVICE_TABLE(of, exynos_dp_match); 300 + 301 + struct platform_driver dp_driver = { 302 + .probe = exynos_dp_probe, 303 + .remove = exynos_dp_remove, 304 + .driver = { 305 + .name = "exynos-dp", 306 + .owner = THIS_MODULE, 307 + .pm = &exynos_dp_pm_ops, 308 + .of_match_table = exynos_dp_match, 309 + }, 310 + }; 311 + 312 + MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); 313 + MODULE_DESCRIPTION("Samsung Specific Analogix-DP Driver Extension"); 314 + MODULE_LICENSE("GPL v2");
-1499
drivers/gpu/drm/exynos/exynos_dp_core.c
··· 1 - /* 2 - * Samsung SoC DP (Display Port) interface driver. 3 - * 4 - * Copyright (C) 2012 Samsung Electronics Co., Ltd. 5 - * Author: Jingoo Han <jg1.han@samsung.com> 6 - * 7 - * This program is free software; you can redistribute it and/or modify it 8 - * under the terms of the GNU General Public License as published by the 9 - * Free Software Foundation; either version 2 of the License, or (at your 10 - * option) any later version. 11 - */ 12 - 13 - #include <linux/module.h> 14 - #include <linux/platform_device.h> 15 - #include <linux/err.h> 16 - #include <linux/clk.h> 17 - #include <linux/io.h> 18 - #include <linux/interrupt.h> 19 - #include <linux/of.h> 20 - #include <linux/of_gpio.h> 21 - #include <linux/of_graph.h> 22 - #include <linux/gpio.h> 23 - #include <linux/component.h> 24 - #include <linux/phy/phy.h> 25 - #include <video/of_display_timing.h> 26 - #include <video/of_videomode.h> 27 - 28 - #include <drm/drmP.h> 29 - #include <drm/drm_crtc.h> 30 - #include <drm/drm_crtc_helper.h> 31 - #include <drm/drm_atomic_helper.h> 32 - #include <drm/drm_panel.h> 33 - 34 - #include "exynos_dp_core.h" 35 - #include "exynos_drm_crtc.h" 36 - 37 - #define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \ 38 - connector) 39 - 40 - static inline struct exynos_drm_crtc *dp_to_crtc(struct exynos_dp_device *dp) 41 - { 42 - return to_exynos_crtc(dp->encoder.crtc); 43 - } 44 - 45 - static inline struct exynos_dp_device *encoder_to_dp( 46 - struct drm_encoder *e) 47 - { 48 - return container_of(e, struct exynos_dp_device, encoder); 49 - } 50 - 51 - struct bridge_init { 52 - struct i2c_client *client; 53 - struct device_node *node; 54 - }; 55 - 56 - static void exynos_dp_init_dp(struct exynos_dp_device *dp) 57 - { 58 - exynos_dp_reset(dp); 59 - 60 - exynos_dp_swreset(dp); 61 - 62 - exynos_dp_init_analog_param(dp); 63 - exynos_dp_init_interrupt(dp); 64 - 65 - /* SW defined function Normal operation */ 66 - exynos_dp_enable_sw_function(dp); 67 - 68 - exynos_dp_config_interrupt(dp); 69 - exynos_dp_init_analog_func(dp); 70 - 71 - exynos_dp_init_hpd(dp); 72 - exynos_dp_init_aux(dp); 73 - } 74 - 75 - static int exynos_dp_detect_hpd(struct exynos_dp_device *dp) 76 - { 77 - int timeout_loop = 0; 78 - 79 - while (exynos_dp_get_plug_in_status(dp) != 0) { 80 - timeout_loop++; 81 - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 82 - dev_err(dp->dev, "failed to get hpd plug status\n"); 83 - return -ETIMEDOUT; 84 - } 85 - usleep_range(10, 11); 86 - } 87 - 88 - return 0; 89 - } 90 - 91 - static unsigned char exynos_dp_calc_edid_check_sum(unsigned char *edid_data) 92 - { 93 - int i; 94 - unsigned char sum = 0; 95 - 96 - for (i = 0; i < EDID_BLOCK_LENGTH; i++) 97 - sum = sum + edid_data[i]; 98 - 99 - return sum; 100 - } 101 - 102 - static int exynos_dp_read_edid(struct exynos_dp_device *dp) 103 - { 104 - unsigned char edid[EDID_BLOCK_LENGTH * 2]; 105 - unsigned int extend_block = 0; 106 - unsigned char sum; 107 - unsigned char test_vector; 108 - int retval; 109 - 110 - /* 111 - * EDID device address is 0x50. 112 - * However, if necessary, you must have set upper address 113 - * into E-EDID in I2C device, 0x30. 114 - */ 115 - 116 - /* Read Extension Flag, Number of 128-byte EDID extension blocks */ 117 - retval = exynos_dp_read_byte_from_i2c(dp, I2C_EDID_DEVICE_ADDR, 118 - EDID_EXTENSION_FLAG, 119 - &extend_block); 120 - if (retval) 121 - return retval; 122 - 123 - if (extend_block > 0) { 124 - dev_dbg(dp->dev, "EDID data includes a single extension!\n"); 125 - 126 - /* Read EDID data */ 127 - retval = exynos_dp_read_bytes_from_i2c(dp, I2C_EDID_DEVICE_ADDR, 128 - EDID_HEADER_PATTERN, 129 - EDID_BLOCK_LENGTH, 130 - &edid[EDID_HEADER_PATTERN]); 131 - if (retval != 0) { 132 - dev_err(dp->dev, "EDID Read failed!\n"); 133 - return -EIO; 134 - } 135 - sum = exynos_dp_calc_edid_check_sum(edid); 136 - if (sum != 0) { 137 - dev_err(dp->dev, "EDID bad checksum!\n"); 138 - return -EIO; 139 - } 140 - 141 - /* Read additional EDID data */ 142 - retval = exynos_dp_read_bytes_from_i2c(dp, 143 - I2C_EDID_DEVICE_ADDR, 144 - EDID_BLOCK_LENGTH, 145 - EDID_BLOCK_LENGTH, 146 - &edid[EDID_BLOCK_LENGTH]); 147 - if (retval != 0) { 148 - dev_err(dp->dev, "EDID Read failed!\n"); 149 - return -EIO; 150 - } 151 - sum = exynos_dp_calc_edid_check_sum(&edid[EDID_BLOCK_LENGTH]); 152 - if (sum != 0) { 153 - dev_err(dp->dev, "EDID bad checksum!\n"); 154 - return -EIO; 155 - } 156 - 157 - exynos_dp_read_byte_from_dpcd(dp, DP_TEST_REQUEST, 158 - &test_vector); 159 - if (test_vector & DP_TEST_LINK_EDID_READ) { 160 - exynos_dp_write_byte_to_dpcd(dp, 161 - DP_TEST_EDID_CHECKSUM, 162 - edid[EDID_BLOCK_LENGTH + EDID_CHECKSUM]); 163 - exynos_dp_write_byte_to_dpcd(dp, 164 - DP_TEST_RESPONSE, 165 - DP_TEST_EDID_CHECKSUM_WRITE); 166 - } 167 - } else { 168 - dev_info(dp->dev, "EDID data does not include any extensions.\n"); 169 - 170 - /* Read EDID data */ 171 - retval = exynos_dp_read_bytes_from_i2c(dp, 172 - I2C_EDID_DEVICE_ADDR, 173 - EDID_HEADER_PATTERN, 174 - EDID_BLOCK_LENGTH, 175 - &edid[EDID_HEADER_PATTERN]); 176 - if (retval != 0) { 177 - dev_err(dp->dev, "EDID Read failed!\n"); 178 - return -EIO; 179 - } 180 - sum = exynos_dp_calc_edid_check_sum(edid); 181 - if (sum != 0) { 182 - dev_err(dp->dev, "EDID bad checksum!\n"); 183 - return -EIO; 184 - } 185 - 186 - exynos_dp_read_byte_from_dpcd(dp, 187 - DP_TEST_REQUEST, 188 - &test_vector); 189 - if (test_vector & DP_TEST_LINK_EDID_READ) { 190 - exynos_dp_write_byte_to_dpcd(dp, 191 - DP_TEST_EDID_CHECKSUM, 192 - edid[EDID_CHECKSUM]); 193 - exynos_dp_write_byte_to_dpcd(dp, 194 - DP_TEST_RESPONSE, 195 - DP_TEST_EDID_CHECKSUM_WRITE); 196 - } 197 - } 198 - 199 - dev_dbg(dp->dev, "EDID Read success!\n"); 200 - return 0; 201 - } 202 - 203 - static int exynos_dp_handle_edid(struct exynos_dp_device *dp) 204 - { 205 - u8 buf[12]; 206 - int i; 207 - int retval; 208 - 209 - /* Read DPCD DP_DPCD_REV~RECEIVE_PORT1_CAP_1 */ 210 - retval = exynos_dp_read_bytes_from_dpcd(dp, DP_DPCD_REV, 211 - 12, buf); 212 - if (retval) 213 - return retval; 214 - 215 - /* Read EDID */ 216 - for (i = 0; i < 3; i++) { 217 - retval = exynos_dp_read_edid(dp); 218 - if (!retval) 219 - break; 220 - } 221 - 222 - return retval; 223 - } 224 - 225 - static void exynos_dp_enable_rx_to_enhanced_mode(struct exynos_dp_device *dp, 226 - bool enable) 227 - { 228 - u8 data; 229 - 230 - exynos_dp_read_byte_from_dpcd(dp, DP_LANE_COUNT_SET, &data); 231 - 232 - if (enable) 233 - exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET, 234 - DP_LANE_COUNT_ENHANCED_FRAME_EN | 235 - DPCD_LANE_COUNT_SET(data)); 236 - else 237 - exynos_dp_write_byte_to_dpcd(dp, DP_LANE_COUNT_SET, 238 - DPCD_LANE_COUNT_SET(data)); 239 - } 240 - 241 - static int exynos_dp_is_enhanced_mode_available(struct exynos_dp_device *dp) 242 - { 243 - u8 data; 244 - int retval; 245 - 246 - exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data); 247 - retval = DPCD_ENHANCED_FRAME_CAP(data); 248 - 249 - return retval; 250 - } 251 - 252 - static void exynos_dp_set_enhanced_mode(struct exynos_dp_device *dp) 253 - { 254 - u8 data; 255 - 256 - data = exynos_dp_is_enhanced_mode_available(dp); 257 - exynos_dp_enable_rx_to_enhanced_mode(dp, data); 258 - exynos_dp_enable_enhanced_mode(dp, data); 259 - } 260 - 261 - static void exynos_dp_training_pattern_dis(struct exynos_dp_device *dp) 262 - { 263 - exynos_dp_set_training_pattern(dp, DP_NONE); 264 - 265 - exynos_dp_write_byte_to_dpcd(dp, 266 - DP_TRAINING_PATTERN_SET, 267 - DP_TRAINING_PATTERN_DISABLE); 268 - } 269 - 270 - static void exynos_dp_set_lane_lane_pre_emphasis(struct exynos_dp_device *dp, 271 - int pre_emphasis, int lane) 272 - { 273 - switch (lane) { 274 - case 0: 275 - exynos_dp_set_lane0_pre_emphasis(dp, pre_emphasis); 276 - break; 277 - case 1: 278 - exynos_dp_set_lane1_pre_emphasis(dp, pre_emphasis); 279 - break; 280 - 281 - case 2: 282 - exynos_dp_set_lane2_pre_emphasis(dp, pre_emphasis); 283 - break; 284 - 285 - case 3: 286 - exynos_dp_set_lane3_pre_emphasis(dp, pre_emphasis); 287 - break; 288 - } 289 - } 290 - 291 - static int exynos_dp_link_start(struct exynos_dp_device *dp) 292 - { 293 - u8 buf[4]; 294 - int lane, lane_count, pll_tries, retval; 295 - 296 - lane_count = dp->link_train.lane_count; 297 - 298 - dp->link_train.lt_state = CLOCK_RECOVERY; 299 - dp->link_train.eq_loop = 0; 300 - 301 - for (lane = 0; lane < lane_count; lane++) 302 - dp->link_train.cr_loop[lane] = 0; 303 - 304 - /* Set link rate and count as you want to establish*/ 305 - exynos_dp_set_link_bandwidth(dp, dp->link_train.link_rate); 306 - exynos_dp_set_lane_count(dp, dp->link_train.lane_count); 307 - 308 - /* Setup RX configuration */ 309 - buf[0] = dp->link_train.link_rate; 310 - buf[1] = dp->link_train.lane_count; 311 - retval = exynos_dp_write_bytes_to_dpcd(dp, DP_LINK_BW_SET, 312 - 2, buf); 313 - if (retval) 314 - return retval; 315 - 316 - /* Set TX pre-emphasis to minimum */ 317 - for (lane = 0; lane < lane_count; lane++) 318 - exynos_dp_set_lane_lane_pre_emphasis(dp, 319 - PRE_EMPHASIS_LEVEL_0, lane); 320 - 321 - /* Wait for PLL lock */ 322 - pll_tries = 0; 323 - while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 324 - if (pll_tries == DP_TIMEOUT_LOOP_COUNT) { 325 - dev_err(dp->dev, "Wait for PLL lock timed out\n"); 326 - return -ETIMEDOUT; 327 - } 328 - 329 - pll_tries++; 330 - usleep_range(90, 120); 331 - } 332 - 333 - /* Set training pattern 1 */ 334 - exynos_dp_set_training_pattern(dp, TRAINING_PTN1); 335 - 336 - /* Set RX training pattern */ 337 - retval = exynos_dp_write_byte_to_dpcd(dp, 338 - DP_TRAINING_PATTERN_SET, 339 - DP_LINK_SCRAMBLING_DISABLE | DP_TRAINING_PATTERN_1); 340 - if (retval) 341 - return retval; 342 - 343 - for (lane = 0; lane < lane_count; lane++) 344 - buf[lane] = DP_TRAIN_PRE_EMPH_LEVEL_0 | 345 - DP_TRAIN_VOLTAGE_SWING_LEVEL_0; 346 - 347 - retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET, 348 - lane_count, buf); 349 - 350 - return retval; 351 - } 352 - 353 - static unsigned char exynos_dp_get_lane_status(u8 link_status[2], int lane) 354 - { 355 - int shift = (lane & 1) * 4; 356 - u8 link_value = link_status[lane>>1]; 357 - 358 - return (link_value >> shift) & 0xf; 359 - } 360 - 361 - static int exynos_dp_clock_recovery_ok(u8 link_status[2], int lane_count) 362 - { 363 - int lane; 364 - u8 lane_status; 365 - 366 - for (lane = 0; lane < lane_count; lane++) { 367 - lane_status = exynos_dp_get_lane_status(link_status, lane); 368 - if ((lane_status & DP_LANE_CR_DONE) == 0) 369 - return -EINVAL; 370 - } 371 - return 0; 372 - } 373 - 374 - static int exynos_dp_channel_eq_ok(u8 link_status[2], u8 link_align, 375 - int lane_count) 376 - { 377 - int lane; 378 - u8 lane_status; 379 - 380 - if ((link_align & DP_INTERLANE_ALIGN_DONE) == 0) 381 - return -EINVAL; 382 - 383 - for (lane = 0; lane < lane_count; lane++) { 384 - lane_status = exynos_dp_get_lane_status(link_status, lane); 385 - lane_status &= DP_CHANNEL_EQ_BITS; 386 - if (lane_status != DP_CHANNEL_EQ_BITS) 387 - return -EINVAL; 388 - } 389 - 390 - return 0; 391 - } 392 - 393 - static unsigned char exynos_dp_get_adjust_request_voltage(u8 adjust_request[2], 394 - int lane) 395 - { 396 - int shift = (lane & 1) * 4; 397 - u8 link_value = adjust_request[lane>>1]; 398 - 399 - return (link_value >> shift) & 0x3; 400 - } 401 - 402 - static unsigned char exynos_dp_get_adjust_request_pre_emphasis( 403 - u8 adjust_request[2], 404 - int lane) 405 - { 406 - int shift = (lane & 1) * 4; 407 - u8 link_value = adjust_request[lane>>1]; 408 - 409 - return ((link_value >> shift) & 0xc) >> 2; 410 - } 411 - 412 - static void exynos_dp_set_lane_link_training(struct exynos_dp_device *dp, 413 - u8 training_lane_set, int lane) 414 - { 415 - switch (lane) { 416 - case 0: 417 - exynos_dp_set_lane0_link_training(dp, training_lane_set); 418 - break; 419 - case 1: 420 - exynos_dp_set_lane1_link_training(dp, training_lane_set); 421 - break; 422 - 423 - case 2: 424 - exynos_dp_set_lane2_link_training(dp, training_lane_set); 425 - break; 426 - 427 - case 3: 428 - exynos_dp_set_lane3_link_training(dp, training_lane_set); 429 - break; 430 - } 431 - } 432 - 433 - static unsigned int exynos_dp_get_lane_link_training( 434 - struct exynos_dp_device *dp, 435 - int lane) 436 - { 437 - u32 reg; 438 - 439 - switch (lane) { 440 - case 0: 441 - reg = exynos_dp_get_lane0_link_training(dp); 442 - break; 443 - case 1: 444 - reg = exynos_dp_get_lane1_link_training(dp); 445 - break; 446 - case 2: 447 - reg = exynos_dp_get_lane2_link_training(dp); 448 - break; 449 - case 3: 450 - reg = exynos_dp_get_lane3_link_training(dp); 451 - break; 452 - default: 453 - WARN_ON(1); 454 - return 0; 455 - } 456 - 457 - return reg; 458 - } 459 - 460 - static void exynos_dp_reduce_link_rate(struct exynos_dp_device *dp) 461 - { 462 - exynos_dp_training_pattern_dis(dp); 463 - exynos_dp_set_enhanced_mode(dp); 464 - 465 - dp->link_train.lt_state = FAILED; 466 - } 467 - 468 - static void exynos_dp_get_adjust_training_lane(struct exynos_dp_device *dp, 469 - u8 adjust_request[2]) 470 - { 471 - int lane, lane_count; 472 - u8 voltage_swing, pre_emphasis, training_lane; 473 - 474 - lane_count = dp->link_train.lane_count; 475 - for (lane = 0; lane < lane_count; lane++) { 476 - voltage_swing = exynos_dp_get_adjust_request_voltage( 477 - adjust_request, lane); 478 - pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( 479 - adjust_request, lane); 480 - training_lane = DPCD_VOLTAGE_SWING_SET(voltage_swing) | 481 - DPCD_PRE_EMPHASIS_SET(pre_emphasis); 482 - 483 - if (voltage_swing == VOLTAGE_LEVEL_3) 484 - training_lane |= DP_TRAIN_MAX_SWING_REACHED; 485 - if (pre_emphasis == PRE_EMPHASIS_LEVEL_3) 486 - training_lane |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; 487 - 488 - dp->link_train.training_lane[lane] = training_lane; 489 - } 490 - } 491 - 492 - static int exynos_dp_process_clock_recovery(struct exynos_dp_device *dp) 493 - { 494 - int lane, lane_count, retval; 495 - u8 voltage_swing, pre_emphasis, training_lane; 496 - u8 link_status[2], adjust_request[2]; 497 - 498 - usleep_range(100, 101); 499 - 500 - lane_count = dp->link_train.lane_count; 501 - 502 - retval = exynos_dp_read_bytes_from_dpcd(dp, 503 - DP_LANE0_1_STATUS, 2, link_status); 504 - if (retval) 505 - return retval; 506 - 507 - retval = exynos_dp_read_bytes_from_dpcd(dp, 508 - DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request); 509 - if (retval) 510 - return retval; 511 - 512 - if (exynos_dp_clock_recovery_ok(link_status, lane_count) == 0) { 513 - /* set training pattern 2 for EQ */ 514 - exynos_dp_set_training_pattern(dp, TRAINING_PTN2); 515 - 516 - retval = exynos_dp_write_byte_to_dpcd(dp, 517 - DP_TRAINING_PATTERN_SET, 518 - DP_LINK_SCRAMBLING_DISABLE | 519 - DP_TRAINING_PATTERN_2); 520 - if (retval) 521 - return retval; 522 - 523 - dev_info(dp->dev, "Link Training Clock Recovery success\n"); 524 - dp->link_train.lt_state = EQUALIZER_TRAINING; 525 - } else { 526 - for (lane = 0; lane < lane_count; lane++) { 527 - training_lane = exynos_dp_get_lane_link_training( 528 - dp, lane); 529 - voltage_swing = exynos_dp_get_adjust_request_voltage( 530 - adjust_request, lane); 531 - pre_emphasis = exynos_dp_get_adjust_request_pre_emphasis( 532 - adjust_request, lane); 533 - 534 - if (DPCD_VOLTAGE_SWING_GET(training_lane) == 535 - voltage_swing && 536 - DPCD_PRE_EMPHASIS_GET(training_lane) == 537 - pre_emphasis) 538 - dp->link_train.cr_loop[lane]++; 539 - 540 - if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP || 541 - voltage_swing == VOLTAGE_LEVEL_3 || 542 - pre_emphasis == PRE_EMPHASIS_LEVEL_3) { 543 - dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n", 544 - dp->link_train.cr_loop[lane], 545 - voltage_swing, pre_emphasis); 546 - exynos_dp_reduce_link_rate(dp); 547 - return -EIO; 548 - } 549 - } 550 - } 551 - 552 - exynos_dp_get_adjust_training_lane(dp, adjust_request); 553 - 554 - for (lane = 0; lane < lane_count; lane++) 555 - exynos_dp_set_lane_link_training(dp, 556 - dp->link_train.training_lane[lane], lane); 557 - 558 - retval = exynos_dp_write_bytes_to_dpcd(dp, 559 - DP_TRAINING_LANE0_SET, lane_count, 560 - dp->link_train.training_lane); 561 - if (retval) 562 - return retval; 563 - 564 - return retval; 565 - } 566 - 567 - static int exynos_dp_process_equalizer_training(struct exynos_dp_device *dp) 568 - { 569 - int lane, lane_count, retval; 570 - u32 reg; 571 - u8 link_align, link_status[2], adjust_request[2]; 572 - 573 - usleep_range(400, 401); 574 - 575 - lane_count = dp->link_train.lane_count; 576 - 577 - retval = exynos_dp_read_bytes_from_dpcd(dp, 578 - DP_LANE0_1_STATUS, 2, link_status); 579 - if (retval) 580 - return retval; 581 - 582 - if (exynos_dp_clock_recovery_ok(link_status, lane_count)) { 583 - exynos_dp_reduce_link_rate(dp); 584 - return -EIO; 585 - } 586 - 587 - retval = exynos_dp_read_bytes_from_dpcd(dp, 588 - DP_ADJUST_REQUEST_LANE0_1, 2, adjust_request); 589 - if (retval) 590 - return retval; 591 - 592 - retval = exynos_dp_read_byte_from_dpcd(dp, 593 - DP_LANE_ALIGN_STATUS_UPDATED, &link_align); 594 - if (retval) 595 - return retval; 596 - 597 - exynos_dp_get_adjust_training_lane(dp, adjust_request); 598 - 599 - if (!exynos_dp_channel_eq_ok(link_status, link_align, lane_count)) { 600 - /* traing pattern Set to Normal */ 601 - exynos_dp_training_pattern_dis(dp); 602 - 603 - dev_info(dp->dev, "Link Training success!\n"); 604 - 605 - exynos_dp_get_link_bandwidth(dp, &reg); 606 - dp->link_train.link_rate = reg; 607 - dev_dbg(dp->dev, "final bandwidth = %.2x\n", 608 - dp->link_train.link_rate); 609 - 610 - exynos_dp_get_lane_count(dp, &reg); 611 - dp->link_train.lane_count = reg; 612 - dev_dbg(dp->dev, "final lane count = %.2x\n", 613 - dp->link_train.lane_count); 614 - 615 - /* set enhanced mode if available */ 616 - exynos_dp_set_enhanced_mode(dp); 617 - dp->link_train.lt_state = FINISHED; 618 - 619 - return 0; 620 - } 621 - 622 - /* not all locked */ 623 - dp->link_train.eq_loop++; 624 - 625 - if (dp->link_train.eq_loop > MAX_EQ_LOOP) { 626 - dev_err(dp->dev, "EQ Max loop\n"); 627 - exynos_dp_reduce_link_rate(dp); 628 - return -EIO; 629 - } 630 - 631 - for (lane = 0; lane < lane_count; lane++) 632 - exynos_dp_set_lane_link_training(dp, 633 - dp->link_train.training_lane[lane], lane); 634 - 635 - retval = exynos_dp_write_bytes_to_dpcd(dp, DP_TRAINING_LANE0_SET, 636 - lane_count, dp->link_train.training_lane); 637 - 638 - return retval; 639 - } 640 - 641 - static void exynos_dp_get_max_rx_bandwidth(struct exynos_dp_device *dp, 642 - u8 *bandwidth) 643 - { 644 - u8 data; 645 - 646 - /* 647 - * For DP rev.1.1, Maximum link rate of Main Link lanes 648 - * 0x06 = 1.62 Gbps, 0x0a = 2.7 Gbps 649 - */ 650 - exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LINK_RATE, &data); 651 - *bandwidth = data; 652 - } 653 - 654 - static void exynos_dp_get_max_rx_lane_count(struct exynos_dp_device *dp, 655 - u8 *lane_count) 656 - { 657 - u8 data; 658 - 659 - /* 660 - * For DP rev.1.1, Maximum number of Main Link lanes 661 - * 0x01 = 1 lane, 0x02 = 2 lanes, 0x04 = 4 lanes 662 - */ 663 - exynos_dp_read_byte_from_dpcd(dp, DP_MAX_LANE_COUNT, &data); 664 - *lane_count = DPCD_MAX_LANE_COUNT(data); 665 - } 666 - 667 - static void exynos_dp_init_training(struct exynos_dp_device *dp, 668 - enum link_lane_count_type max_lane, 669 - enum link_rate_type max_rate) 670 - { 671 - /* 672 - * MACRO_RST must be applied after the PLL_LOCK to avoid 673 - * the DP inter pair skew issue for at least 10 us 674 - */ 675 - exynos_dp_reset_macro(dp); 676 - 677 - /* Initialize by reading RX's DPCD */ 678 - exynos_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate); 679 - exynos_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count); 680 - 681 - if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) && 682 - (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) { 683 - dev_err(dp->dev, "Rx Max Link Rate is abnormal :%x !\n", 684 - dp->link_train.link_rate); 685 - dp->link_train.link_rate = LINK_RATE_1_62GBPS; 686 - } 687 - 688 - if (dp->link_train.lane_count == 0) { 689 - dev_err(dp->dev, "Rx Max Lane count is abnormal :%x !\n", 690 - dp->link_train.lane_count); 691 - dp->link_train.lane_count = (u8)LANE_COUNT1; 692 - } 693 - 694 - /* Setup TX lane count & rate */ 695 - if (dp->link_train.lane_count > max_lane) 696 - dp->link_train.lane_count = max_lane; 697 - if (dp->link_train.link_rate > max_rate) 698 - dp->link_train.link_rate = max_rate; 699 - 700 - /* All DP analog module power up */ 701 - exynos_dp_set_analog_power_down(dp, POWER_ALL, 0); 702 - } 703 - 704 - static int exynos_dp_sw_link_training(struct exynos_dp_device *dp) 705 - { 706 - int retval = 0, training_finished = 0; 707 - 708 - dp->link_train.lt_state = START; 709 - 710 - /* Process here */ 711 - while (!retval && !training_finished) { 712 - switch (dp->link_train.lt_state) { 713 - case START: 714 - retval = exynos_dp_link_start(dp); 715 - if (retval) 716 - dev_err(dp->dev, "LT link start failed!\n"); 717 - break; 718 - case CLOCK_RECOVERY: 719 - retval = exynos_dp_process_clock_recovery(dp); 720 - if (retval) 721 - dev_err(dp->dev, "LT CR failed!\n"); 722 - break; 723 - case EQUALIZER_TRAINING: 724 - retval = exynos_dp_process_equalizer_training(dp); 725 - if (retval) 726 - dev_err(dp->dev, "LT EQ failed!\n"); 727 - break; 728 - case FINISHED: 729 - training_finished = 1; 730 - break; 731 - case FAILED: 732 - return -EREMOTEIO; 733 - } 734 - } 735 - if (retval) 736 - dev_err(dp->dev, "eDP link training failed (%d)\n", retval); 737 - 738 - return retval; 739 - } 740 - 741 - static int exynos_dp_set_link_train(struct exynos_dp_device *dp, 742 - u32 count, 743 - u32 bwtype) 744 - { 745 - int i; 746 - int retval; 747 - 748 - for (i = 0; i < DP_TIMEOUT_LOOP_COUNT; i++) { 749 - exynos_dp_init_training(dp, count, bwtype); 750 - retval = exynos_dp_sw_link_training(dp); 751 - if (retval == 0) 752 - break; 753 - 754 - usleep_range(100, 110); 755 - } 756 - 757 - return retval; 758 - } 759 - 760 - static int exynos_dp_config_video(struct exynos_dp_device *dp) 761 - { 762 - int retval = 0; 763 - int timeout_loop = 0; 764 - int done_count = 0; 765 - 766 - exynos_dp_config_video_slave_mode(dp); 767 - 768 - exynos_dp_set_video_color_format(dp); 769 - 770 - if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 771 - dev_err(dp->dev, "PLL is not locked yet.\n"); 772 - return -EINVAL; 773 - } 774 - 775 - for (;;) { 776 - timeout_loop++; 777 - if (exynos_dp_is_slave_video_stream_clock_on(dp) == 0) 778 - break; 779 - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 780 - dev_err(dp->dev, "Timeout of video streamclk ok\n"); 781 - return -ETIMEDOUT; 782 - } 783 - 784 - usleep_range(1, 2); 785 - } 786 - 787 - /* Set to use the register calculated M/N video */ 788 - exynos_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0); 789 - 790 - /* For video bist, Video timing must be generated by register */ 791 - exynos_dp_set_video_timing_mode(dp, VIDEO_TIMING_FROM_CAPTURE); 792 - 793 - /* Disable video mute */ 794 - exynos_dp_enable_video_mute(dp, 0); 795 - 796 - /* Configure video slave mode */ 797 - exynos_dp_enable_video_master(dp, 0); 798 - 799 - timeout_loop = 0; 800 - 801 - for (;;) { 802 - timeout_loop++; 803 - if (exynos_dp_is_video_stream_on(dp) == 0) { 804 - done_count++; 805 - if (done_count > 10) 806 - break; 807 - } else if (done_count) { 808 - done_count = 0; 809 - } 810 - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 811 - dev_err(dp->dev, "Timeout of video streamclk ok\n"); 812 - return -ETIMEDOUT; 813 - } 814 - 815 - usleep_range(1000, 1001); 816 - } 817 - 818 - if (retval != 0) 819 - dev_err(dp->dev, "Video stream is not detected!\n"); 820 - 821 - return retval; 822 - } 823 - 824 - static void exynos_dp_enable_scramble(struct exynos_dp_device *dp, bool enable) 825 - { 826 - u8 data; 827 - 828 - if (enable) { 829 - exynos_dp_enable_scrambling(dp); 830 - 831 - exynos_dp_read_byte_from_dpcd(dp, 832 - DP_TRAINING_PATTERN_SET, 833 - &data); 834 - exynos_dp_write_byte_to_dpcd(dp, 835 - DP_TRAINING_PATTERN_SET, 836 - (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE)); 837 - } else { 838 - exynos_dp_disable_scrambling(dp); 839 - 840 - exynos_dp_read_byte_from_dpcd(dp, 841 - DP_TRAINING_PATTERN_SET, 842 - &data); 843 - exynos_dp_write_byte_to_dpcd(dp, 844 - DP_TRAINING_PATTERN_SET, 845 - (u8)(data | DP_LINK_SCRAMBLING_DISABLE)); 846 - } 847 - } 848 - 849 - static irqreturn_t exynos_dp_irq_handler(int irq, void *arg) 850 - { 851 - struct exynos_dp_device *dp = arg; 852 - 853 - enum dp_irq_type irq_type; 854 - 855 - irq_type = exynos_dp_get_irq_type(dp); 856 - switch (irq_type) { 857 - case DP_IRQ_TYPE_HP_CABLE_IN: 858 - dev_dbg(dp->dev, "Received irq - cable in\n"); 859 - schedule_work(&dp->hotplug_work); 860 - exynos_dp_clear_hotplug_interrupts(dp); 861 - break; 862 - case DP_IRQ_TYPE_HP_CABLE_OUT: 863 - dev_dbg(dp->dev, "Received irq - cable out\n"); 864 - exynos_dp_clear_hotplug_interrupts(dp); 865 - break; 866 - case DP_IRQ_TYPE_HP_CHANGE: 867 - /* 868 - * We get these change notifications once in a while, but there 869 - * is nothing we can do with them. Just ignore it for now and 870 - * only handle cable changes. 871 - */ 872 - dev_dbg(dp->dev, "Received irq - hotplug change; ignoring.\n"); 873 - exynos_dp_clear_hotplug_interrupts(dp); 874 - break; 875 - default: 876 - dev_err(dp->dev, "Received irq - unknown type!\n"); 877 - break; 878 - } 879 - return IRQ_HANDLED; 880 - } 881 - 882 - static void exynos_dp_hotplug(struct work_struct *work) 883 - { 884 - struct exynos_dp_device *dp; 885 - 886 - dp = container_of(work, struct exynos_dp_device, hotplug_work); 887 - 888 - if (dp->drm_dev) 889 - drm_helper_hpd_irq_event(dp->drm_dev); 890 - } 891 - 892 - static void exynos_dp_commit(struct drm_encoder *encoder) 893 - { 894 - struct exynos_dp_device *dp = encoder_to_dp(encoder); 895 - int ret; 896 - 897 - /* Keep the panel disabled while we configure video */ 898 - if (dp->panel) { 899 - if (drm_panel_disable(dp->panel)) 900 - DRM_ERROR("failed to disable the panel\n"); 901 - } 902 - 903 - ret = exynos_dp_detect_hpd(dp); 904 - if (ret) { 905 - /* Cable has been disconnected, we're done */ 906 - return; 907 - } 908 - 909 - ret = exynos_dp_handle_edid(dp); 910 - if (ret) { 911 - dev_err(dp->dev, "unable to handle edid\n"); 912 - return; 913 - } 914 - 915 - ret = exynos_dp_set_link_train(dp, dp->video_info->lane_count, 916 - dp->video_info->link_rate); 917 - if (ret) { 918 - dev_err(dp->dev, "unable to do link train\n"); 919 - return; 920 - } 921 - 922 - exynos_dp_enable_scramble(dp, 1); 923 - exynos_dp_enable_rx_to_enhanced_mode(dp, 1); 924 - exynos_dp_enable_enhanced_mode(dp, 1); 925 - 926 - exynos_dp_set_lane_count(dp, dp->video_info->lane_count); 927 - exynos_dp_set_link_bandwidth(dp, dp->video_info->link_rate); 928 - 929 - exynos_dp_init_video(dp); 930 - ret = exynos_dp_config_video(dp); 931 - if (ret) 932 - dev_err(dp->dev, "unable to config video\n"); 933 - 934 - /* Safe to enable the panel now */ 935 - if (dp->panel) { 936 - if (drm_panel_enable(dp->panel)) 937 - DRM_ERROR("failed to enable the panel\n"); 938 - } 939 - 940 - /* Enable video */ 941 - exynos_dp_start_video(dp); 942 - } 943 - 944 - static enum drm_connector_status exynos_dp_detect( 945 - struct drm_connector *connector, bool force) 946 - { 947 - return connector_status_connected; 948 - } 949 - 950 - static void exynos_dp_connector_destroy(struct drm_connector *connector) 951 - { 952 - drm_connector_unregister(connector); 953 - drm_connector_cleanup(connector); 954 - } 955 - 956 - static const struct drm_connector_funcs exynos_dp_connector_funcs = { 957 - .dpms = drm_atomic_helper_connector_dpms, 958 - .fill_modes = drm_helper_probe_single_connector_modes, 959 - .detect = exynos_dp_detect, 960 - .destroy = exynos_dp_connector_destroy, 961 - .reset = drm_atomic_helper_connector_reset, 962 - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 963 - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 964 - }; 965 - 966 - static int exynos_dp_get_modes(struct drm_connector *connector) 967 - { 968 - struct exynos_dp_device *dp = ctx_from_connector(connector); 969 - struct drm_display_mode *mode; 970 - 971 - if (dp->panel) 972 - return drm_panel_get_modes(dp->panel); 973 - 974 - mode = drm_mode_create(connector->dev); 975 - if (!mode) { 976 - DRM_ERROR("failed to create a new display mode.\n"); 977 - return 0; 978 - } 979 - 980 - drm_display_mode_from_videomode(&dp->vm, mode); 981 - connector->display_info.width_mm = mode->width_mm; 982 - connector->display_info.height_mm = mode->height_mm; 983 - 984 - mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 985 - drm_mode_set_name(mode); 986 - drm_mode_probed_add(connector, mode); 987 - 988 - return 1; 989 - } 990 - 991 - static struct drm_encoder *exynos_dp_best_encoder( 992 - struct drm_connector *connector) 993 - { 994 - struct exynos_dp_device *dp = ctx_from_connector(connector); 995 - 996 - return &dp->encoder; 997 - } 998 - 999 - static const struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = { 1000 - .get_modes = exynos_dp_get_modes, 1001 - .best_encoder = exynos_dp_best_encoder, 1002 - }; 1003 - 1004 - /* returns the number of bridges attached */ 1005 - static int exynos_drm_attach_lcd_bridge(struct exynos_dp_device *dp, 1006 - struct drm_encoder *encoder) 1007 - { 1008 - int ret; 1009 - 1010 - encoder->bridge->next = dp->ptn_bridge; 1011 - dp->ptn_bridge->encoder = encoder; 1012 - ret = drm_bridge_attach(encoder->dev, dp->ptn_bridge); 1013 - if (ret) { 1014 - DRM_ERROR("Failed to attach bridge to drm\n"); 1015 - return ret; 1016 - } 1017 - 1018 - return 0; 1019 - } 1020 - 1021 - static int exynos_dp_bridge_attach(struct drm_bridge *bridge) 1022 - { 1023 - struct exynos_dp_device *dp = bridge->driver_private; 1024 - struct drm_encoder *encoder = &dp->encoder; 1025 - struct drm_connector *connector = &dp->connector; 1026 - int ret; 1027 - 1028 - /* Pre-empt DP connector creation if there's a bridge */ 1029 - if (dp->ptn_bridge) { 1030 - ret = exynos_drm_attach_lcd_bridge(dp, encoder); 1031 - if (!ret) 1032 - return 0; 1033 - } 1034 - 1035 - connector->polled = DRM_CONNECTOR_POLL_HPD; 1036 - 1037 - ret = drm_connector_init(dp->drm_dev, connector, 1038 - &exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP); 1039 - if (ret) { 1040 - DRM_ERROR("Failed to initialize connector with drm\n"); 1041 - return ret; 1042 - } 1043 - 1044 - drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs); 1045 - drm_connector_register(connector); 1046 - drm_mode_connector_attach_encoder(connector, encoder); 1047 - 1048 - if (dp->panel) 1049 - ret = drm_panel_attach(dp->panel, &dp->connector); 1050 - 1051 - return ret; 1052 - } 1053 - 1054 - static void exynos_dp_bridge_enable(struct drm_bridge *bridge) 1055 - { 1056 - struct exynos_dp_device *dp = bridge->driver_private; 1057 - struct exynos_drm_crtc *crtc = dp_to_crtc(dp); 1058 - 1059 - if (dp->dpms_mode == DRM_MODE_DPMS_ON) 1060 - return; 1061 - 1062 - pm_runtime_get_sync(dp->dev); 1063 - 1064 - if (dp->panel) { 1065 - if (drm_panel_prepare(dp->panel)) { 1066 - DRM_ERROR("failed to setup the panel\n"); 1067 - return; 1068 - } 1069 - } 1070 - 1071 - if (crtc->ops->clock_enable) 1072 - crtc->ops->clock_enable(dp_to_crtc(dp), true); 1073 - 1074 - phy_power_on(dp->phy); 1075 - exynos_dp_init_dp(dp); 1076 - enable_irq(dp->irq); 1077 - exynos_dp_commit(&dp->encoder); 1078 - 1079 - dp->dpms_mode = DRM_MODE_DPMS_ON; 1080 - } 1081 - 1082 - static void exynos_dp_bridge_disable(struct drm_bridge *bridge) 1083 - { 1084 - struct exynos_dp_device *dp = bridge->driver_private; 1085 - struct exynos_drm_crtc *crtc = dp_to_crtc(dp); 1086 - 1087 - if (dp->dpms_mode != DRM_MODE_DPMS_ON) 1088 - return; 1089 - 1090 - if (dp->panel) { 1091 - if (drm_panel_disable(dp->panel)) { 1092 - DRM_ERROR("failed to disable the panel\n"); 1093 - return; 1094 - } 1095 - } 1096 - 1097 - disable_irq(dp->irq); 1098 - flush_work(&dp->hotplug_work); 1099 - phy_power_off(dp->phy); 1100 - 1101 - if (crtc->ops->clock_enable) 1102 - crtc->ops->clock_enable(dp_to_crtc(dp), false); 1103 - 1104 - if (dp->panel) { 1105 - if (drm_panel_unprepare(dp->panel)) 1106 - DRM_ERROR("failed to turnoff the panel\n"); 1107 - } 1108 - 1109 - pm_runtime_put_sync(dp->dev); 1110 - 1111 - dp->dpms_mode = DRM_MODE_DPMS_OFF; 1112 - } 1113 - 1114 - static void exynos_dp_bridge_nop(struct drm_bridge *bridge) 1115 - { 1116 - /* do nothing */ 1117 - } 1118 - 1119 - static const struct drm_bridge_funcs exynos_dp_bridge_funcs = { 1120 - .enable = exynos_dp_bridge_enable, 1121 - .disable = exynos_dp_bridge_disable, 1122 - .pre_enable = exynos_dp_bridge_nop, 1123 - .post_disable = exynos_dp_bridge_nop, 1124 - .attach = exynos_dp_bridge_attach, 1125 - }; 1126 - 1127 - static int exynos_dp_create_connector(struct drm_encoder *encoder) 1128 - { 1129 - struct exynos_dp_device *dp = encoder_to_dp(encoder); 1130 - struct drm_device *drm_dev = dp->drm_dev; 1131 - struct drm_bridge *bridge; 1132 - int ret; 1133 - 1134 - bridge = devm_kzalloc(drm_dev->dev, sizeof(*bridge), GFP_KERNEL); 1135 - if (!bridge) { 1136 - DRM_ERROR("failed to allocate for drm bridge\n"); 1137 - return -ENOMEM; 1138 - } 1139 - 1140 - dp->bridge = bridge; 1141 - 1142 - encoder->bridge = bridge; 1143 - bridge->driver_private = dp; 1144 - bridge->encoder = encoder; 1145 - bridge->funcs = &exynos_dp_bridge_funcs; 1146 - 1147 - ret = drm_bridge_attach(drm_dev, bridge); 1148 - if (ret) { 1149 - DRM_ERROR("failed to attach drm bridge\n"); 1150 - return -EINVAL; 1151 - } 1152 - 1153 - return 0; 1154 - } 1155 - 1156 - static void exynos_dp_mode_set(struct drm_encoder *encoder, 1157 - struct drm_display_mode *mode, 1158 - struct drm_display_mode *adjusted_mode) 1159 - { 1160 - } 1161 - 1162 - static void exynos_dp_enable(struct drm_encoder *encoder) 1163 - { 1164 - } 1165 - 1166 - static void exynos_dp_disable(struct drm_encoder *encoder) 1167 - { 1168 - } 1169 - 1170 - static const struct drm_encoder_helper_funcs exynos_dp_encoder_helper_funcs = { 1171 - .mode_set = exynos_dp_mode_set, 1172 - .enable = exynos_dp_enable, 1173 - .disable = exynos_dp_disable, 1174 - }; 1175 - 1176 - static const struct drm_encoder_funcs exynos_dp_encoder_funcs = { 1177 - .destroy = drm_encoder_cleanup, 1178 - }; 1179 - 1180 - static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev) 1181 - { 1182 - struct device_node *dp_node = dev->of_node; 1183 - struct video_info *dp_video_config; 1184 - 1185 - dp_video_config = devm_kzalloc(dev, 1186 - sizeof(*dp_video_config), GFP_KERNEL); 1187 - if (!dp_video_config) 1188 - return ERR_PTR(-ENOMEM); 1189 - 1190 - dp_video_config->h_sync_polarity = 1191 - of_property_read_bool(dp_node, "hsync-active-high"); 1192 - 1193 - dp_video_config->v_sync_polarity = 1194 - of_property_read_bool(dp_node, "vsync-active-high"); 1195 - 1196 - dp_video_config->interlaced = 1197 - of_property_read_bool(dp_node, "interlaced"); 1198 - 1199 - if (of_property_read_u32(dp_node, "samsung,color-space", 1200 - &dp_video_config->color_space)) { 1201 - dev_err(dev, "failed to get color-space\n"); 1202 - return ERR_PTR(-EINVAL); 1203 - } 1204 - 1205 - if (of_property_read_u32(dp_node, "samsung,dynamic-range", 1206 - &dp_video_config->dynamic_range)) { 1207 - dev_err(dev, "failed to get dynamic-range\n"); 1208 - return ERR_PTR(-EINVAL); 1209 - } 1210 - 1211 - if (of_property_read_u32(dp_node, "samsung,ycbcr-coeff", 1212 - &dp_video_config->ycbcr_coeff)) { 1213 - dev_err(dev, "failed to get ycbcr-coeff\n"); 1214 - return ERR_PTR(-EINVAL); 1215 - } 1216 - 1217 - if (of_property_read_u32(dp_node, "samsung,color-depth", 1218 - &dp_video_config->color_depth)) { 1219 - dev_err(dev, "failed to get color-depth\n"); 1220 - return ERR_PTR(-EINVAL); 1221 - } 1222 - 1223 - if (of_property_read_u32(dp_node, "samsung,link-rate", 1224 - &dp_video_config->link_rate)) { 1225 - dev_err(dev, "failed to get link-rate\n"); 1226 - return ERR_PTR(-EINVAL); 1227 - } 1228 - 1229 - if (of_property_read_u32(dp_node, "samsung,lane-count", 1230 - &dp_video_config->lane_count)) { 1231 - dev_err(dev, "failed to get lane-count\n"); 1232 - return ERR_PTR(-EINVAL); 1233 - } 1234 - 1235 - return dp_video_config; 1236 - } 1237 - 1238 - static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) 1239 - { 1240 - int ret; 1241 - 1242 - ret = of_get_videomode(dp->dev->of_node, &dp->vm, OF_USE_NATIVE_MODE); 1243 - if (ret) { 1244 - DRM_ERROR("failed: of_get_videomode() : %d\n", ret); 1245 - return ret; 1246 - } 1247 - return 0; 1248 - } 1249 - 1250 - static int exynos_dp_bind(struct device *dev, struct device *master, void *data) 1251 - { 1252 - struct exynos_dp_device *dp = dev_get_drvdata(dev); 1253 - struct platform_device *pdev = to_platform_device(dev); 1254 - struct drm_device *drm_dev = data; 1255 - struct drm_encoder *encoder = &dp->encoder; 1256 - struct resource *res; 1257 - unsigned int irq_flags; 1258 - int pipe, ret = 0; 1259 - 1260 - dp->dev = &pdev->dev; 1261 - dp->dpms_mode = DRM_MODE_DPMS_OFF; 1262 - 1263 - dp->video_info = exynos_dp_dt_parse_pdata(&pdev->dev); 1264 - if (IS_ERR(dp->video_info)) 1265 - return PTR_ERR(dp->video_info); 1266 - 1267 - dp->phy = devm_phy_get(dp->dev, "dp"); 1268 - if (IS_ERR(dp->phy)) { 1269 - dev_err(dp->dev, "no DP phy configured\n"); 1270 - ret = PTR_ERR(dp->phy); 1271 - if (ret) { 1272 - /* 1273 - * phy itself is not enabled, so we can move forward 1274 - * assigning NULL to phy pointer. 1275 - */ 1276 - if (ret == -ENOSYS || ret == -ENODEV) 1277 - dp->phy = NULL; 1278 - else 1279 - return ret; 1280 - } 1281 - } 1282 - 1283 - if (!dp->panel && !dp->ptn_bridge) { 1284 - ret = exynos_dp_dt_parse_panel(dp); 1285 - if (ret) 1286 - return ret; 1287 - } 1288 - 1289 - dp->clock = devm_clk_get(&pdev->dev, "dp"); 1290 - if (IS_ERR(dp->clock)) { 1291 - dev_err(&pdev->dev, "failed to get clock\n"); 1292 - return PTR_ERR(dp->clock); 1293 - } 1294 - 1295 - clk_prepare_enable(dp->clock); 1296 - 1297 - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 1298 - 1299 - dp->reg_base = devm_ioremap_resource(&pdev->dev, res); 1300 - if (IS_ERR(dp->reg_base)) 1301 - return PTR_ERR(dp->reg_base); 1302 - 1303 - dp->hpd_gpio = of_get_named_gpio(dev->of_node, "samsung,hpd-gpio", 0); 1304 - 1305 - if (gpio_is_valid(dp->hpd_gpio)) { 1306 - /* 1307 - * Set up the hotplug GPIO from the device tree as an interrupt. 1308 - * Simply specifying a different interrupt in the device tree 1309 - * doesn't work since we handle hotplug rather differently when 1310 - * using a GPIO. We also need the actual GPIO specifier so 1311 - * that we can get the current state of the GPIO. 1312 - */ 1313 - ret = devm_gpio_request_one(&pdev->dev, dp->hpd_gpio, GPIOF_IN, 1314 - "hpd_gpio"); 1315 - if (ret) { 1316 - dev_err(&pdev->dev, "failed to get hpd gpio\n"); 1317 - return ret; 1318 - } 1319 - dp->irq = gpio_to_irq(dp->hpd_gpio); 1320 - irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING; 1321 - } else { 1322 - dp->hpd_gpio = -ENODEV; 1323 - dp->irq = platform_get_irq(pdev, 0); 1324 - irq_flags = 0; 1325 - } 1326 - 1327 - if (dp->irq == -ENXIO) { 1328 - dev_err(&pdev->dev, "failed to get irq\n"); 1329 - return -ENODEV; 1330 - } 1331 - 1332 - INIT_WORK(&dp->hotplug_work, exynos_dp_hotplug); 1333 - 1334 - ret = devm_request_irq(&pdev->dev, dp->irq, exynos_dp_irq_handler, 1335 - irq_flags, "exynos-dp", dp); 1336 - if (ret) { 1337 - dev_err(&pdev->dev, "failed to request irq\n"); 1338 - return ret; 1339 - } 1340 - disable_irq(dp->irq); 1341 - 1342 - dp->drm_dev = drm_dev; 1343 - 1344 - pipe = exynos_drm_crtc_get_pipe_from_type(drm_dev, 1345 - EXYNOS_DISPLAY_TYPE_LCD); 1346 - if (pipe < 0) 1347 - return pipe; 1348 - 1349 - encoder->possible_crtcs = 1 << pipe; 1350 - 1351 - DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); 1352 - 1353 - drm_encoder_init(drm_dev, encoder, &exynos_dp_encoder_funcs, 1354 - DRM_MODE_ENCODER_TMDS, NULL); 1355 - 1356 - drm_encoder_helper_add(encoder, &exynos_dp_encoder_helper_funcs); 1357 - 1358 - ret = exynos_dp_create_connector(encoder); 1359 - if (ret) { 1360 - DRM_ERROR("failed to create connector ret = %d\n", ret); 1361 - drm_encoder_cleanup(encoder); 1362 - return ret; 1363 - } 1364 - 1365 - return 0; 1366 - } 1367 - 1368 - static void exynos_dp_unbind(struct device *dev, struct device *master, 1369 - void *data) 1370 - { 1371 - struct exynos_dp_device *dp = dev_get_drvdata(dev); 1372 - 1373 - exynos_dp_disable(&dp->encoder); 1374 - } 1375 - 1376 - static const struct component_ops exynos_dp_ops = { 1377 - .bind = exynos_dp_bind, 1378 - .unbind = exynos_dp_unbind, 1379 - }; 1380 - 1381 - static int exynos_dp_probe(struct platform_device *pdev) 1382 - { 1383 - struct device *dev = &pdev->dev; 1384 - struct device_node *np = NULL, *endpoint = NULL; 1385 - struct exynos_dp_device *dp; 1386 - int ret; 1387 - 1388 - dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device), 1389 - GFP_KERNEL); 1390 - if (!dp) 1391 - return -ENOMEM; 1392 - 1393 - platform_set_drvdata(pdev, dp); 1394 - 1395 - /* This is for the backward compatibility. */ 1396 - np = of_parse_phandle(dev->of_node, "panel", 0); 1397 - if (np) { 1398 - dp->panel = of_drm_find_panel(np); 1399 - of_node_put(np); 1400 - if (!dp->panel) 1401 - return -EPROBE_DEFER; 1402 - goto out; 1403 - } 1404 - 1405 - endpoint = of_graph_get_next_endpoint(dev->of_node, NULL); 1406 - if (endpoint) { 1407 - np = of_graph_get_remote_port_parent(endpoint); 1408 - if (np) { 1409 - /* The remote port can be either a panel or a bridge */ 1410 - dp->panel = of_drm_find_panel(np); 1411 - if (!dp->panel) { 1412 - dp->ptn_bridge = of_drm_find_bridge(np); 1413 - if (!dp->ptn_bridge) { 1414 - of_node_put(np); 1415 - return -EPROBE_DEFER; 1416 - } 1417 - } 1418 - of_node_put(np); 1419 - } else { 1420 - DRM_ERROR("no remote endpoint device node found.\n"); 1421 - return -EINVAL; 1422 - } 1423 - } else { 1424 - DRM_ERROR("no port endpoint subnode found.\n"); 1425 - return -EINVAL; 1426 - } 1427 - 1428 - out: 1429 - pm_runtime_enable(dev); 1430 - 1431 - ret = component_add(&pdev->dev, &exynos_dp_ops); 1432 - if (ret) 1433 - goto err_disable_pm_runtime; 1434 - 1435 - return ret; 1436 - 1437 - err_disable_pm_runtime: 1438 - pm_runtime_disable(dev); 1439 - 1440 - return ret; 1441 - } 1442 - 1443 - static int exynos_dp_remove(struct platform_device *pdev) 1444 - { 1445 - pm_runtime_disable(&pdev->dev); 1446 - component_del(&pdev->dev, &exynos_dp_ops); 1447 - 1448 - return 0; 1449 - } 1450 - 1451 - #ifdef CONFIG_PM 1452 - static int exynos_dp_suspend(struct device *dev) 1453 - { 1454 - struct exynos_dp_device *dp = dev_get_drvdata(dev); 1455 - 1456 - clk_disable_unprepare(dp->clock); 1457 - 1458 - return 0; 1459 - } 1460 - 1461 - static int exynos_dp_resume(struct device *dev) 1462 - { 1463 - struct exynos_dp_device *dp = dev_get_drvdata(dev); 1464 - int ret; 1465 - 1466 - ret = clk_prepare_enable(dp->clock); 1467 - if (ret < 0) { 1468 - DRM_ERROR("Failed to prepare_enable the clock clk [%d]\n", ret); 1469 - return ret; 1470 - } 1471 - 1472 - return 0; 1473 - } 1474 - #endif 1475 - 1476 - static const struct dev_pm_ops exynos_dp_pm_ops = { 1477 - SET_RUNTIME_PM_OPS(exynos_dp_suspend, exynos_dp_resume, NULL) 1478 - }; 1479 - 1480 - static const struct of_device_id exynos_dp_match[] = { 1481 - { .compatible = "samsung,exynos5-dp" }, 1482 - {}, 1483 - }; 1484 - MODULE_DEVICE_TABLE(of, exynos_dp_match); 1485 - 1486 - struct platform_driver dp_driver = { 1487 - .probe = exynos_dp_probe, 1488 - .remove = exynos_dp_remove, 1489 - .driver = { 1490 - .name = "exynos-dp", 1491 - .owner = THIS_MODULE, 1492 - .pm = &exynos_dp_pm_ops, 1493 - .of_match_table = exynos_dp_match, 1494 - }, 1495 - }; 1496 - 1497 - MODULE_AUTHOR("Jingoo Han <jg1.han@samsung.com>"); 1498 - MODULE_DESCRIPTION("Samsung SoC DP Driver"); 1499 - MODULE_LICENSE("GPL v2");
-282
drivers/gpu/drm/exynos/exynos_dp_core.h
··· 1 - /* 2 - * Header file for Samsung DP (Display Port) interface driver. 3 - * 4 - * Copyright (C) 2012 Samsung Electronics Co., Ltd. 5 - * Author: Jingoo Han <jg1.han@samsung.com> 6 - * 7 - * This program is free software; you can redistribute it and/or modify it 8 - * under the terms of the GNU General Public License as published by the 9 - * Free Software Foundation; either version 2 of the License, or (at your 10 - * option) any later version. 11 - */ 12 - 13 - #ifndef _EXYNOS_DP_CORE_H 14 - #define _EXYNOS_DP_CORE_H 15 - 16 - #include <drm/drm_crtc.h> 17 - #include <drm/drm_dp_helper.h> 18 - #include <drm/exynos_drm.h> 19 - #include <video/videomode.h> 20 - 21 - #include "exynos_drm_drv.h" 22 - 23 - #define DP_TIMEOUT_LOOP_COUNT 100 24 - #define MAX_CR_LOOP 5 25 - #define MAX_EQ_LOOP 5 26 - 27 - enum link_rate_type { 28 - LINK_RATE_1_62GBPS = 0x06, 29 - LINK_RATE_2_70GBPS = 0x0a 30 - }; 31 - 32 - enum link_lane_count_type { 33 - LANE_COUNT1 = 1, 34 - LANE_COUNT2 = 2, 35 - LANE_COUNT4 = 4 36 - }; 37 - 38 - enum link_training_state { 39 - START, 40 - CLOCK_RECOVERY, 41 - EQUALIZER_TRAINING, 42 - FINISHED, 43 - FAILED 44 - }; 45 - 46 - enum voltage_swing_level { 47 - VOLTAGE_LEVEL_0, 48 - VOLTAGE_LEVEL_1, 49 - VOLTAGE_LEVEL_2, 50 - VOLTAGE_LEVEL_3, 51 - }; 52 - 53 - enum pre_emphasis_level { 54 - PRE_EMPHASIS_LEVEL_0, 55 - PRE_EMPHASIS_LEVEL_1, 56 - PRE_EMPHASIS_LEVEL_2, 57 - PRE_EMPHASIS_LEVEL_3, 58 - }; 59 - 60 - enum pattern_set { 61 - PRBS7, 62 - D10_2, 63 - TRAINING_PTN1, 64 - TRAINING_PTN2, 65 - DP_NONE 66 - }; 67 - 68 - enum color_space { 69 - COLOR_RGB, 70 - COLOR_YCBCR422, 71 - COLOR_YCBCR444 72 - }; 73 - 74 - enum color_depth { 75 - COLOR_6, 76 - COLOR_8, 77 - COLOR_10, 78 - COLOR_12 79 - }; 80 - 81 - enum color_coefficient { 82 - COLOR_YCBCR601, 83 - COLOR_YCBCR709 84 - }; 85 - 86 - enum dynamic_range { 87 - VESA, 88 - CEA 89 - }; 90 - 91 - enum pll_status { 92 - PLL_UNLOCKED, 93 - PLL_LOCKED 94 - }; 95 - 96 - enum clock_recovery_m_value_type { 97 - CALCULATED_M, 98 - REGISTER_M 99 - }; 100 - 101 - enum video_timing_recognition_type { 102 - VIDEO_TIMING_FROM_CAPTURE, 103 - VIDEO_TIMING_FROM_REGISTER 104 - }; 105 - 106 - enum analog_power_block { 107 - AUX_BLOCK, 108 - CH0_BLOCK, 109 - CH1_BLOCK, 110 - CH2_BLOCK, 111 - CH3_BLOCK, 112 - ANALOG_TOTAL, 113 - POWER_ALL 114 - }; 115 - 116 - enum dp_irq_type { 117 - DP_IRQ_TYPE_HP_CABLE_IN, 118 - DP_IRQ_TYPE_HP_CABLE_OUT, 119 - DP_IRQ_TYPE_HP_CHANGE, 120 - DP_IRQ_TYPE_UNKNOWN, 121 - }; 122 - 123 - struct video_info { 124 - char *name; 125 - 126 - bool h_sync_polarity; 127 - bool v_sync_polarity; 128 - bool interlaced; 129 - 130 - enum color_space color_space; 131 - enum dynamic_range dynamic_range; 132 - enum color_coefficient ycbcr_coeff; 133 - enum color_depth color_depth; 134 - 135 - enum link_rate_type link_rate; 136 - enum link_lane_count_type lane_count; 137 - }; 138 - 139 - struct link_train { 140 - int eq_loop; 141 - int cr_loop[4]; 142 - 143 - u8 link_rate; 144 - u8 lane_count; 145 - u8 training_lane[4]; 146 - 147 - enum link_training_state lt_state; 148 - }; 149 - 150 - struct exynos_dp_device { 151 - struct drm_encoder encoder; 152 - struct device *dev; 153 - struct drm_device *drm_dev; 154 - struct drm_connector connector; 155 - struct drm_panel *panel; 156 - struct drm_bridge *bridge; 157 - struct drm_bridge *ptn_bridge; 158 - struct clk *clock; 159 - unsigned int irq; 160 - void __iomem *reg_base; 161 - 162 - struct video_info *video_info; 163 - struct link_train link_train; 164 - struct work_struct hotplug_work; 165 - struct phy *phy; 166 - int dpms_mode; 167 - int hpd_gpio; 168 - struct videomode vm; 169 - }; 170 - 171 - /* exynos_dp_reg.c */ 172 - void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable); 173 - void exynos_dp_stop_video(struct exynos_dp_device *dp); 174 - void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable); 175 - void exynos_dp_init_analog_param(struct exynos_dp_device *dp); 176 - void exynos_dp_init_interrupt(struct exynos_dp_device *dp); 177 - void exynos_dp_reset(struct exynos_dp_device *dp); 178 - void exynos_dp_swreset(struct exynos_dp_device *dp); 179 - void exynos_dp_config_interrupt(struct exynos_dp_device *dp); 180 - enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp); 181 - void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable); 182 - void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp, 183 - enum analog_power_block block, 184 - bool enable); 185 - void exynos_dp_init_analog_func(struct exynos_dp_device *dp); 186 - void exynos_dp_init_hpd(struct exynos_dp_device *dp); 187 - enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp); 188 - void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp); 189 - void exynos_dp_reset_aux(struct exynos_dp_device *dp); 190 - void exynos_dp_init_aux(struct exynos_dp_device *dp); 191 - int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp); 192 - void exynos_dp_enable_sw_function(struct exynos_dp_device *dp); 193 - int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp); 194 - int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp, 195 - unsigned int reg_addr, 196 - unsigned char data); 197 - int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp, 198 - unsigned int reg_addr, 199 - unsigned char *data); 200 - int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp, 201 - unsigned int reg_addr, 202 - unsigned int count, 203 - unsigned char data[]); 204 - int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp, 205 - unsigned int reg_addr, 206 - unsigned int count, 207 - unsigned char data[]); 208 - int exynos_dp_select_i2c_device(struct exynos_dp_device *dp, 209 - unsigned int device_addr, 210 - unsigned int reg_addr); 211 - int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp, 212 - unsigned int device_addr, 213 - unsigned int reg_addr, 214 - unsigned int *data); 215 - int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, 216 - unsigned int device_addr, 217 - unsigned int reg_addr, 218 - unsigned int count, 219 - unsigned char edid[]); 220 - void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype); 221 - void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype); 222 - void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count); 223 - void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count); 224 - void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable); 225 - void exynos_dp_set_training_pattern(struct exynos_dp_device *dp, 226 - enum pattern_set pattern); 227 - void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level); 228 - void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level); 229 - void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level); 230 - void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level); 231 - void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp, 232 - u32 training_lane); 233 - void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp, 234 - u32 training_lane); 235 - void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp, 236 - u32 training_lane); 237 - void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp, 238 - u32 training_lane); 239 - u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp); 240 - u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp); 241 - u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp); 242 - u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp); 243 - void exynos_dp_reset_macro(struct exynos_dp_device *dp); 244 - void exynos_dp_init_video(struct exynos_dp_device *dp); 245 - 246 - void exynos_dp_set_video_color_format(struct exynos_dp_device *dp); 247 - int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp); 248 - void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp, 249 - enum clock_recovery_m_value_type type, 250 - u32 m_value, 251 - u32 n_value); 252 - void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type); 253 - void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable); 254 - void exynos_dp_start_video(struct exynos_dp_device *dp); 255 - int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp); 256 - void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp); 257 - void exynos_dp_enable_scrambling(struct exynos_dp_device *dp); 258 - void exynos_dp_disable_scrambling(struct exynos_dp_device *dp); 259 - 260 - /* I2C EDID Chip ID, Slave Address */ 261 - #define I2C_EDID_DEVICE_ADDR 0x50 262 - #define I2C_E_EDID_DEVICE_ADDR 0x30 263 - 264 - #define EDID_BLOCK_LENGTH 0x80 265 - #define EDID_HEADER_PATTERN 0x00 266 - #define EDID_EXTENSION_FLAG 0x7e 267 - #define EDID_CHECKSUM 0x7f 268 - 269 - /* DP_MAX_LANE_COUNT */ 270 - #define DPCD_ENHANCED_FRAME_CAP(x) (((x) >> 7) & 0x1) 271 - #define DPCD_MAX_LANE_COUNT(x) ((x) & 0x1f) 272 - 273 - /* DP_LANE_COUNT_SET */ 274 - #define DPCD_LANE_COUNT_SET(x) ((x) & 0x1f) 275 - 276 - /* DP_TRAINING_LANE0_SET */ 277 - #define DPCD_PRE_EMPHASIS_SET(x) (((x) & 0x3) << 3) 278 - #define DPCD_PRE_EMPHASIS_GET(x) (((x) >> 3) & 0x3) 279 - #define DPCD_VOLTAGE_SWING_SET(x) (((x) & 0x3) << 0) 280 - #define DPCD_VOLTAGE_SWING_GET(x) (((x) >> 0) & 0x3) 281 - 282 - #endif /* _EXYNOS_DP_CORE_H */
-1263
drivers/gpu/drm/exynos/exynos_dp_reg.c
··· 1 - /* 2 - * Samsung DP (Display port) register interface driver. 3 - * 4 - * Copyright (C) 2012 Samsung Electronics Co., Ltd. 5 - * Author: Jingoo Han <jg1.han@samsung.com> 6 - * 7 - * This program is free software; you can redistribute it and/or modify it 8 - * under the terms of the GNU General Public License as published by the 9 - * Free Software Foundation; either version 2 of the License, or (at your 10 - * option) any later version. 11 - */ 12 - 13 - #include <linux/device.h> 14 - #include <linux/io.h> 15 - #include <linux/delay.h> 16 - #include <linux/gpio.h> 17 - 18 - #include "exynos_dp_core.h" 19 - #include "exynos_dp_reg.h" 20 - 21 - #define COMMON_INT_MASK_1 0 22 - #define COMMON_INT_MASK_2 0 23 - #define COMMON_INT_MASK_3 0 24 - #define COMMON_INT_MASK_4 (HOTPLUG_CHG | HPD_LOST | PLUG) 25 - #define INT_STA_MASK INT_HPD 26 - 27 - void exynos_dp_enable_video_mute(struct exynos_dp_device *dp, bool enable) 28 - { 29 - u32 reg; 30 - 31 - if (enable) { 32 - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 33 - reg |= HDCP_VIDEO_MUTE; 34 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 35 - } else { 36 - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 37 - reg &= ~HDCP_VIDEO_MUTE; 38 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 39 - } 40 - } 41 - 42 - void exynos_dp_stop_video(struct exynos_dp_device *dp) 43 - { 44 - u32 reg; 45 - 46 - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 47 - reg &= ~VIDEO_EN; 48 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 49 - } 50 - 51 - void exynos_dp_lane_swap(struct exynos_dp_device *dp, bool enable) 52 - { 53 - u32 reg; 54 - 55 - if (enable) 56 - reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 | 57 - LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3; 58 - else 59 - reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 | 60 - LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0; 61 - 62 - writel(reg, dp->reg_base + EXYNOS_DP_LANE_MAP); 63 - } 64 - 65 - void exynos_dp_init_analog_param(struct exynos_dp_device *dp) 66 - { 67 - u32 reg; 68 - 69 - reg = TX_TERMINAL_CTRL_50_OHM; 70 - writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_1); 71 - 72 - reg = SEL_24M | TX_DVDD_BIT_1_0625V; 73 - writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_2); 74 - 75 - reg = DRIVE_DVDD_BIT_1_0625V | VCO_BIT_600_MICRO; 76 - writel(reg, dp->reg_base + EXYNOS_DP_ANALOG_CTL_3); 77 - 78 - reg = PD_RING_OSC | AUX_TERMINAL_CTRL_50_OHM | 79 - TX_CUR1_2X | TX_CUR_16_MA; 80 - writel(reg, dp->reg_base + EXYNOS_DP_PLL_FILTER_CTL_1); 81 - 82 - reg = CH3_AMP_400_MV | CH2_AMP_400_MV | 83 - CH1_AMP_400_MV | CH0_AMP_400_MV; 84 - writel(reg, dp->reg_base + EXYNOS_DP_TX_AMP_TUNING_CTL); 85 - } 86 - 87 - void exynos_dp_init_interrupt(struct exynos_dp_device *dp) 88 - { 89 - /* Set interrupt pin assertion polarity as high */ 90 - writel(INT_POL1 | INT_POL0, dp->reg_base + EXYNOS_DP_INT_CTL); 91 - 92 - /* Clear pending regisers */ 93 - writel(0xff, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 94 - writel(0x4f, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_2); 95 - writel(0xe0, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_3); 96 - writel(0xe7, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 97 - writel(0x63, dp->reg_base + EXYNOS_DP_INT_STA); 98 - 99 - /* 0:mask,1: unmask */ 100 - writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); 101 - writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); 102 - writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); 103 - writel(0x00, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); 104 - writel(0x00, dp->reg_base + EXYNOS_DP_INT_STA_MASK); 105 - } 106 - 107 - void exynos_dp_reset(struct exynos_dp_device *dp) 108 - { 109 - u32 reg; 110 - 111 - exynos_dp_stop_video(dp); 112 - exynos_dp_enable_video_mute(dp, 0); 113 - 114 - reg = MASTER_VID_FUNC_EN_N | SLAVE_VID_FUNC_EN_N | 115 - AUD_FIFO_FUNC_EN_N | AUD_FUNC_EN_N | 116 - HDCP_FUNC_EN_N | SW_FUNC_EN_N; 117 - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); 118 - 119 - reg = SSC_FUNC_EN_N | AUX_FUNC_EN_N | 120 - SERDES_FIFO_FUNC_EN_N | 121 - LS_CLK_DOMAIN_FUNC_EN_N; 122 - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 123 - 124 - usleep_range(20, 30); 125 - 126 - exynos_dp_lane_swap(dp, 0); 127 - 128 - writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_1); 129 - writel(0x40, dp->reg_base + EXYNOS_DP_SYS_CTL_2); 130 - writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 131 - writel(0x0, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 132 - 133 - writel(0x0, dp->reg_base + EXYNOS_DP_PKT_SEND_CTL); 134 - writel(0x0, dp->reg_base + EXYNOS_DP_HDCP_CTL); 135 - 136 - writel(0x5e, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_L); 137 - writel(0x1a, dp->reg_base + EXYNOS_DP_HPD_DEGLITCH_H); 138 - 139 - writel(0x10, dp->reg_base + EXYNOS_DP_LINK_DEBUG_CTL); 140 - 141 - writel(0x0, dp->reg_base + EXYNOS_DP_PHY_TEST); 142 - 143 - writel(0x0, dp->reg_base + EXYNOS_DP_VIDEO_FIFO_THRD); 144 - writel(0x20, dp->reg_base + EXYNOS_DP_AUDIO_MARGIN); 145 - 146 - writel(0x4, dp->reg_base + EXYNOS_DP_M_VID_GEN_FILTER_TH); 147 - writel(0x2, dp->reg_base + EXYNOS_DP_M_AUD_GEN_FILTER_TH); 148 - 149 - writel(0x00000101, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 150 - } 151 - 152 - void exynos_dp_swreset(struct exynos_dp_device *dp) 153 - { 154 - writel(RESET_DP_TX, dp->reg_base + EXYNOS_DP_TX_SW_RESET); 155 - } 156 - 157 - void exynos_dp_config_interrupt(struct exynos_dp_device *dp) 158 - { 159 - u32 reg; 160 - 161 - /* 0: mask, 1: unmask */ 162 - reg = COMMON_INT_MASK_1; 163 - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_1); 164 - 165 - reg = COMMON_INT_MASK_2; 166 - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_2); 167 - 168 - reg = COMMON_INT_MASK_3; 169 - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_3); 170 - 171 - reg = COMMON_INT_MASK_4; 172 - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_MASK_4); 173 - 174 - reg = INT_STA_MASK; 175 - writel(reg, dp->reg_base + EXYNOS_DP_INT_STA_MASK); 176 - } 177 - 178 - enum pll_status exynos_dp_get_pll_lock_status(struct exynos_dp_device *dp) 179 - { 180 - u32 reg; 181 - 182 - reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); 183 - if (reg & PLL_LOCK) 184 - return PLL_LOCKED; 185 - else 186 - return PLL_UNLOCKED; 187 - } 188 - 189 - void exynos_dp_set_pll_power_down(struct exynos_dp_device *dp, bool enable) 190 - { 191 - u32 reg; 192 - 193 - if (enable) { 194 - reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); 195 - reg |= DP_PLL_PD; 196 - writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); 197 - } else { 198 - reg = readl(dp->reg_base + EXYNOS_DP_PLL_CTL); 199 - reg &= ~DP_PLL_PD; 200 - writel(reg, dp->reg_base + EXYNOS_DP_PLL_CTL); 201 - } 202 - } 203 - 204 - void exynos_dp_set_analog_power_down(struct exynos_dp_device *dp, 205 - enum analog_power_block block, 206 - bool enable) 207 - { 208 - u32 reg; 209 - 210 - switch (block) { 211 - case AUX_BLOCK: 212 - if (enable) { 213 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 214 - reg |= AUX_PD; 215 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 216 - } else { 217 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 218 - reg &= ~AUX_PD; 219 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 220 - } 221 - break; 222 - case CH0_BLOCK: 223 - if (enable) { 224 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 225 - reg |= CH0_PD; 226 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 227 - } else { 228 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 229 - reg &= ~CH0_PD; 230 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 231 - } 232 - break; 233 - case CH1_BLOCK: 234 - if (enable) { 235 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 236 - reg |= CH1_PD; 237 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 238 - } else { 239 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 240 - reg &= ~CH1_PD; 241 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 242 - } 243 - break; 244 - case CH2_BLOCK: 245 - if (enable) { 246 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 247 - reg |= CH2_PD; 248 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 249 - } else { 250 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 251 - reg &= ~CH2_PD; 252 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 253 - } 254 - break; 255 - case CH3_BLOCK: 256 - if (enable) { 257 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 258 - reg |= CH3_PD; 259 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 260 - } else { 261 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 262 - reg &= ~CH3_PD; 263 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 264 - } 265 - break; 266 - case ANALOG_TOTAL: 267 - if (enable) { 268 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 269 - reg |= DP_PHY_PD; 270 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 271 - } else { 272 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_PD); 273 - reg &= ~DP_PHY_PD; 274 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 275 - } 276 - break; 277 - case POWER_ALL: 278 - if (enable) { 279 - reg = DP_PHY_PD | AUX_PD | CH3_PD | CH2_PD | 280 - CH1_PD | CH0_PD; 281 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_PD); 282 - } else { 283 - writel(0x00, dp->reg_base + EXYNOS_DP_PHY_PD); 284 - } 285 - break; 286 - default: 287 - break; 288 - } 289 - } 290 - 291 - void exynos_dp_init_analog_func(struct exynos_dp_device *dp) 292 - { 293 - u32 reg; 294 - int timeout_loop = 0; 295 - 296 - exynos_dp_set_analog_power_down(dp, POWER_ALL, 0); 297 - 298 - reg = PLL_LOCK_CHG; 299 - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 300 - 301 - reg = readl(dp->reg_base + EXYNOS_DP_DEBUG_CTL); 302 - reg &= ~(F_PLL_LOCK | PLL_LOCK_CTRL); 303 - writel(reg, dp->reg_base + EXYNOS_DP_DEBUG_CTL); 304 - 305 - /* Power up PLL */ 306 - if (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 307 - exynos_dp_set_pll_power_down(dp, 0); 308 - 309 - while (exynos_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) { 310 - timeout_loop++; 311 - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 312 - dev_err(dp->dev, "failed to get pll lock status\n"); 313 - return; 314 - } 315 - usleep_range(10, 20); 316 - } 317 - } 318 - 319 - /* Enable Serdes FIFO function and Link symbol clock domain module */ 320 - reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); 321 - reg &= ~(SERDES_FIFO_FUNC_EN_N | LS_CLK_DOMAIN_FUNC_EN_N 322 - | AUX_FUNC_EN_N); 323 - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 324 - } 325 - 326 - void exynos_dp_clear_hotplug_interrupts(struct exynos_dp_device *dp) 327 - { 328 - u32 reg; 329 - 330 - if (gpio_is_valid(dp->hpd_gpio)) 331 - return; 332 - 333 - reg = HOTPLUG_CHG | HPD_LOST | PLUG; 334 - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 335 - 336 - reg = INT_HPD; 337 - writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); 338 - } 339 - 340 - void exynos_dp_init_hpd(struct exynos_dp_device *dp) 341 - { 342 - u32 reg; 343 - 344 - if (gpio_is_valid(dp->hpd_gpio)) 345 - return; 346 - 347 - exynos_dp_clear_hotplug_interrupts(dp); 348 - 349 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 350 - reg &= ~(F_HPD | HPD_CTRL); 351 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 352 - } 353 - 354 - enum dp_irq_type exynos_dp_get_irq_type(struct exynos_dp_device *dp) 355 - { 356 - u32 reg; 357 - 358 - if (gpio_is_valid(dp->hpd_gpio)) { 359 - reg = gpio_get_value(dp->hpd_gpio); 360 - if (reg) 361 - return DP_IRQ_TYPE_HP_CABLE_IN; 362 - else 363 - return DP_IRQ_TYPE_HP_CABLE_OUT; 364 - } else { 365 - /* Parse hotplug interrupt status register */ 366 - reg = readl(dp->reg_base + EXYNOS_DP_COMMON_INT_STA_4); 367 - 368 - if (reg & PLUG) 369 - return DP_IRQ_TYPE_HP_CABLE_IN; 370 - 371 - if (reg & HPD_LOST) 372 - return DP_IRQ_TYPE_HP_CABLE_OUT; 373 - 374 - if (reg & HOTPLUG_CHG) 375 - return DP_IRQ_TYPE_HP_CHANGE; 376 - 377 - return DP_IRQ_TYPE_UNKNOWN; 378 - } 379 - } 380 - 381 - void exynos_dp_reset_aux(struct exynos_dp_device *dp) 382 - { 383 - u32 reg; 384 - 385 - /* Disable AUX channel module */ 386 - reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); 387 - reg |= AUX_FUNC_EN_N; 388 - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 389 - } 390 - 391 - void exynos_dp_init_aux(struct exynos_dp_device *dp) 392 - { 393 - u32 reg; 394 - 395 - /* Clear inerrupts related to AUX channel */ 396 - reg = RPLY_RECEIV | AUX_ERR; 397 - writel(reg, dp->reg_base + EXYNOS_DP_INT_STA); 398 - 399 - exynos_dp_reset_aux(dp); 400 - 401 - /* Disable AUX transaction H/W retry */ 402 - reg = AUX_BIT_PERIOD_EXPECTED_DELAY(3) | AUX_HW_RETRY_COUNT_SEL(0)| 403 - AUX_HW_RETRY_INTERVAL_600_MICROSECONDS; 404 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_HW_RETRY_CTL); 405 - 406 - /* Receive AUX Channel DEFER commands equal to DEFFER_COUNT*64 */ 407 - reg = DEFER_CTRL_EN | DEFER_COUNT(1); 408 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_DEFER_CTL); 409 - 410 - /* Enable AUX channel module */ 411 - reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_2); 412 - reg &= ~AUX_FUNC_EN_N; 413 - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_2); 414 - } 415 - 416 - int exynos_dp_get_plug_in_status(struct exynos_dp_device *dp) 417 - { 418 - u32 reg; 419 - 420 - if (gpio_is_valid(dp->hpd_gpio)) { 421 - if (gpio_get_value(dp->hpd_gpio)) 422 - return 0; 423 - } else { 424 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 425 - if (reg & HPD_STATUS) 426 - return 0; 427 - } 428 - 429 - return -EINVAL; 430 - } 431 - 432 - void exynos_dp_enable_sw_function(struct exynos_dp_device *dp) 433 - { 434 - u32 reg; 435 - 436 - reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); 437 - reg &= ~SW_FUNC_EN_N; 438 - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); 439 - } 440 - 441 - int exynos_dp_start_aux_transaction(struct exynos_dp_device *dp) 442 - { 443 - int reg; 444 - int retval = 0; 445 - int timeout_loop = 0; 446 - 447 - /* Enable AUX CH operation */ 448 - reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 449 - reg |= AUX_EN; 450 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 451 - 452 - /* Is AUX CH command reply received? */ 453 - reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); 454 - while (!(reg & RPLY_RECEIV)) { 455 - timeout_loop++; 456 - if (DP_TIMEOUT_LOOP_COUNT < timeout_loop) { 457 - dev_err(dp->dev, "AUX CH command reply failed!\n"); 458 - return -ETIMEDOUT; 459 - } 460 - reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); 461 - usleep_range(10, 11); 462 - } 463 - 464 - /* Clear interrupt source for AUX CH command reply */ 465 - writel(RPLY_RECEIV, dp->reg_base + EXYNOS_DP_INT_STA); 466 - 467 - /* Clear interrupt source for AUX CH access error */ 468 - reg = readl(dp->reg_base + EXYNOS_DP_INT_STA); 469 - if (reg & AUX_ERR) { 470 - writel(AUX_ERR, dp->reg_base + EXYNOS_DP_INT_STA); 471 - return -EREMOTEIO; 472 - } 473 - 474 - /* Check AUX CH error access status */ 475 - reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_STA); 476 - if ((reg & AUX_STATUS_MASK) != 0) { 477 - dev_err(dp->dev, "AUX CH error happens: %d\n\n", 478 - reg & AUX_STATUS_MASK); 479 - return -EREMOTEIO; 480 - } 481 - 482 - return retval; 483 - } 484 - 485 - int exynos_dp_write_byte_to_dpcd(struct exynos_dp_device *dp, 486 - unsigned int reg_addr, 487 - unsigned char data) 488 - { 489 - u32 reg; 490 - int i; 491 - int retval; 492 - 493 - for (i = 0; i < 3; i++) { 494 - /* Clear AUX CH data buffer */ 495 - reg = BUF_CLR; 496 - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 497 - 498 - /* Select DPCD device address */ 499 - reg = AUX_ADDR_7_0(reg_addr); 500 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 501 - reg = AUX_ADDR_15_8(reg_addr); 502 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 503 - reg = AUX_ADDR_19_16(reg_addr); 504 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 505 - 506 - /* Write data buffer */ 507 - reg = (unsigned int)data; 508 - writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0); 509 - 510 - /* 511 - * Set DisplayPort transaction and write 1 byte 512 - * If bit 3 is 1, DisplayPort transaction. 513 - * If Bit 3 is 0, I2C transaction. 514 - */ 515 - reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; 516 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 517 - 518 - /* Start AUX transaction */ 519 - retval = exynos_dp_start_aux_transaction(dp); 520 - if (retval == 0) 521 - break; 522 - else 523 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 524 - __func__); 525 - } 526 - 527 - return retval; 528 - } 529 - 530 - int exynos_dp_read_byte_from_dpcd(struct exynos_dp_device *dp, 531 - unsigned int reg_addr, 532 - unsigned char *data) 533 - { 534 - u32 reg; 535 - int i; 536 - int retval; 537 - 538 - for (i = 0; i < 3; i++) { 539 - /* Clear AUX CH data buffer */ 540 - reg = BUF_CLR; 541 - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 542 - 543 - /* Select DPCD device address */ 544 - reg = AUX_ADDR_7_0(reg_addr); 545 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 546 - reg = AUX_ADDR_15_8(reg_addr); 547 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 548 - reg = AUX_ADDR_19_16(reg_addr); 549 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 550 - 551 - /* 552 - * Set DisplayPort transaction and read 1 byte 553 - * If bit 3 is 1, DisplayPort transaction. 554 - * If Bit 3 is 0, I2C transaction. 555 - */ 556 - reg = AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; 557 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 558 - 559 - /* Start AUX transaction */ 560 - retval = exynos_dp_start_aux_transaction(dp); 561 - if (retval == 0) 562 - break; 563 - else 564 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 565 - __func__); 566 - } 567 - 568 - /* Read data buffer */ 569 - reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); 570 - *data = (unsigned char)(reg & 0xff); 571 - 572 - return retval; 573 - } 574 - 575 - int exynos_dp_write_bytes_to_dpcd(struct exynos_dp_device *dp, 576 - unsigned int reg_addr, 577 - unsigned int count, 578 - unsigned char data[]) 579 - { 580 - u32 reg; 581 - unsigned int start_offset; 582 - unsigned int cur_data_count; 583 - unsigned int cur_data_idx; 584 - int i; 585 - int retval = 0; 586 - 587 - /* Clear AUX CH data buffer */ 588 - reg = BUF_CLR; 589 - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 590 - 591 - start_offset = 0; 592 - while (start_offset < count) { 593 - /* Buffer size of AUX CH is 16 * 4bytes */ 594 - if ((count - start_offset) > 16) 595 - cur_data_count = 16; 596 - else 597 - cur_data_count = count - start_offset; 598 - 599 - for (i = 0; i < 3; i++) { 600 - /* Select DPCD device address */ 601 - reg = AUX_ADDR_7_0(reg_addr + start_offset); 602 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 603 - reg = AUX_ADDR_15_8(reg_addr + start_offset); 604 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 605 - reg = AUX_ADDR_19_16(reg_addr + start_offset); 606 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 607 - 608 - for (cur_data_idx = 0; cur_data_idx < cur_data_count; 609 - cur_data_idx++) { 610 - reg = data[start_offset + cur_data_idx]; 611 - writel(reg, dp->reg_base + EXYNOS_DP_BUF_DATA_0 612 - + 4 * cur_data_idx); 613 - } 614 - 615 - /* 616 - * Set DisplayPort transaction and write 617 - * If bit 3 is 1, DisplayPort transaction. 618 - * If Bit 3 is 0, I2C transaction. 619 - */ 620 - reg = AUX_LENGTH(cur_data_count) | 621 - AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_WRITE; 622 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 623 - 624 - /* Start AUX transaction */ 625 - retval = exynos_dp_start_aux_transaction(dp); 626 - if (retval == 0) 627 - break; 628 - else 629 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 630 - __func__); 631 - } 632 - 633 - start_offset += cur_data_count; 634 - } 635 - 636 - return retval; 637 - } 638 - 639 - int exynos_dp_read_bytes_from_dpcd(struct exynos_dp_device *dp, 640 - unsigned int reg_addr, 641 - unsigned int count, 642 - unsigned char data[]) 643 - { 644 - u32 reg; 645 - unsigned int start_offset; 646 - unsigned int cur_data_count; 647 - unsigned int cur_data_idx; 648 - int i; 649 - int retval = 0; 650 - 651 - /* Clear AUX CH data buffer */ 652 - reg = BUF_CLR; 653 - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 654 - 655 - start_offset = 0; 656 - while (start_offset < count) { 657 - /* Buffer size of AUX CH is 16 * 4bytes */ 658 - if ((count - start_offset) > 16) 659 - cur_data_count = 16; 660 - else 661 - cur_data_count = count - start_offset; 662 - 663 - /* AUX CH Request Transaction process */ 664 - for (i = 0; i < 3; i++) { 665 - /* Select DPCD device address */ 666 - reg = AUX_ADDR_7_0(reg_addr + start_offset); 667 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 668 - reg = AUX_ADDR_15_8(reg_addr + start_offset); 669 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 670 - reg = AUX_ADDR_19_16(reg_addr + start_offset); 671 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 672 - 673 - /* 674 - * Set DisplayPort transaction and read 675 - * If bit 3 is 1, DisplayPort transaction. 676 - * If Bit 3 is 0, I2C transaction. 677 - */ 678 - reg = AUX_LENGTH(cur_data_count) | 679 - AUX_TX_COMM_DP_TRANSACTION | AUX_TX_COMM_READ; 680 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 681 - 682 - /* Start AUX transaction */ 683 - retval = exynos_dp_start_aux_transaction(dp); 684 - if (retval == 0) 685 - break; 686 - else 687 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 688 - __func__); 689 - } 690 - 691 - for (cur_data_idx = 0; cur_data_idx < cur_data_count; 692 - cur_data_idx++) { 693 - reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 694 - + 4 * cur_data_idx); 695 - data[start_offset + cur_data_idx] = 696 - (unsigned char)reg; 697 - } 698 - 699 - start_offset += cur_data_count; 700 - } 701 - 702 - return retval; 703 - } 704 - 705 - int exynos_dp_select_i2c_device(struct exynos_dp_device *dp, 706 - unsigned int device_addr, 707 - unsigned int reg_addr) 708 - { 709 - u32 reg; 710 - int retval; 711 - 712 - /* Set EDID device address */ 713 - reg = device_addr; 714 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_ADDR_7_0); 715 - writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_15_8); 716 - writel(0x0, dp->reg_base + EXYNOS_DP_AUX_ADDR_19_16); 717 - 718 - /* Set offset from base address of EDID device */ 719 - writel(reg_addr, dp->reg_base + EXYNOS_DP_BUF_DATA_0); 720 - 721 - /* 722 - * Set I2C transaction and write address 723 - * If bit 3 is 1, DisplayPort transaction. 724 - * If Bit 3 is 0, I2C transaction. 725 - */ 726 - reg = AUX_TX_COMM_I2C_TRANSACTION | AUX_TX_COMM_MOT | 727 - AUX_TX_COMM_WRITE; 728 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 729 - 730 - /* Start AUX transaction */ 731 - retval = exynos_dp_start_aux_transaction(dp); 732 - if (retval != 0) 733 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", __func__); 734 - 735 - return retval; 736 - } 737 - 738 - int exynos_dp_read_byte_from_i2c(struct exynos_dp_device *dp, 739 - unsigned int device_addr, 740 - unsigned int reg_addr, 741 - unsigned int *data) 742 - { 743 - u32 reg; 744 - int i; 745 - int retval; 746 - 747 - for (i = 0; i < 3; i++) { 748 - /* Clear AUX CH data buffer */ 749 - reg = BUF_CLR; 750 - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 751 - 752 - /* Select EDID device */ 753 - retval = exynos_dp_select_i2c_device(dp, device_addr, reg_addr); 754 - if (retval != 0) 755 - continue; 756 - 757 - /* 758 - * Set I2C transaction and read data 759 - * If bit 3 is 1, DisplayPort transaction. 760 - * If Bit 3 is 0, I2C transaction. 761 - */ 762 - reg = AUX_TX_COMM_I2C_TRANSACTION | 763 - AUX_TX_COMM_READ; 764 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_1); 765 - 766 - /* Start AUX transaction */ 767 - retval = exynos_dp_start_aux_transaction(dp); 768 - if (retval == 0) 769 - break; 770 - else 771 - dev_dbg(dp->dev, "%s: Aux Transaction fail!\n", 772 - __func__); 773 - } 774 - 775 - /* Read data */ 776 - if (retval == 0) 777 - *data = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0); 778 - 779 - return retval; 780 - } 781 - 782 - int exynos_dp_read_bytes_from_i2c(struct exynos_dp_device *dp, 783 - unsigned int device_addr, 784 - unsigned int reg_addr, 785 - unsigned int count, 786 - unsigned char edid[]) 787 - { 788 - u32 reg; 789 - unsigned int i, j; 790 - unsigned int cur_data_idx; 791 - unsigned int defer = 0; 792 - int retval = 0; 793 - 794 - for (i = 0; i < count; i += 16) { 795 - for (j = 0; j < 3; j++) { 796 - /* Clear AUX CH data buffer */ 797 - reg = BUF_CLR; 798 - writel(reg, dp->reg_base + EXYNOS_DP_BUFFER_DATA_CTL); 799 - 800 - /* Set normal AUX CH command */ 801 - reg = readl(dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 802 - reg &= ~ADDR_ONLY; 803 - writel(reg, dp->reg_base + EXYNOS_DP_AUX_CH_CTL_2); 804 - 805 - /* 806 - * If Rx sends defer, Tx sends only reads 807 - * request without sending address 808 - */ 809 - if (!defer) 810 - retval = exynos_dp_select_i2c_device(dp, 811 - device_addr, reg_addr + i); 812 - else 813 - defer = 0; 814 - 815 - if (retval == 0) { 816 - /* 817 - * Set I2C transaction and write data 818 - * If bit 3 is 1, DisplayPort transaction. 819 - * If Bit 3 is 0, I2C transaction. 820 - */ 821 - reg = AUX_LENGTH(16) | 822 - AUX_TX_COMM_I2C_TRANSACTION | 823 - AUX_TX_COMM_READ; 824 - writel(reg, dp->reg_base + 825 - EXYNOS_DP_AUX_CH_CTL_1); 826 - 827 - /* Start AUX transaction */ 828 - retval = exynos_dp_start_aux_transaction(dp); 829 - if (retval == 0) 830 - break; 831 - else 832 - dev_dbg(dp->dev, 833 - "%s: Aux Transaction fail!\n", 834 - __func__); 835 - } 836 - /* Check if Rx sends defer */ 837 - reg = readl(dp->reg_base + EXYNOS_DP_AUX_RX_COMM); 838 - if (reg == AUX_RX_COMM_AUX_DEFER || 839 - reg == AUX_RX_COMM_I2C_DEFER) { 840 - dev_err(dp->dev, "Defer: %d\n\n", reg); 841 - defer = 1; 842 - } 843 - } 844 - 845 - for (cur_data_idx = 0; cur_data_idx < 16; cur_data_idx++) { 846 - reg = readl(dp->reg_base + EXYNOS_DP_BUF_DATA_0 847 - + 4 * cur_data_idx); 848 - edid[i + cur_data_idx] = (unsigned char)reg; 849 - } 850 - } 851 - 852 - return retval; 853 - } 854 - 855 - void exynos_dp_set_link_bandwidth(struct exynos_dp_device *dp, u32 bwtype) 856 - { 857 - u32 reg; 858 - 859 - reg = bwtype; 860 - if ((bwtype == LINK_RATE_2_70GBPS) || (bwtype == LINK_RATE_1_62GBPS)) 861 - writel(reg, dp->reg_base + EXYNOS_DP_LINK_BW_SET); 862 - } 863 - 864 - void exynos_dp_get_link_bandwidth(struct exynos_dp_device *dp, u32 *bwtype) 865 - { 866 - u32 reg; 867 - 868 - reg = readl(dp->reg_base + EXYNOS_DP_LINK_BW_SET); 869 - *bwtype = reg; 870 - } 871 - 872 - void exynos_dp_set_lane_count(struct exynos_dp_device *dp, u32 count) 873 - { 874 - u32 reg; 875 - 876 - reg = count; 877 - writel(reg, dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); 878 - } 879 - 880 - void exynos_dp_get_lane_count(struct exynos_dp_device *dp, u32 *count) 881 - { 882 - u32 reg; 883 - 884 - reg = readl(dp->reg_base + EXYNOS_DP_LANE_COUNT_SET); 885 - *count = reg; 886 - } 887 - 888 - void exynos_dp_enable_enhanced_mode(struct exynos_dp_device *dp, bool enable) 889 - { 890 - u32 reg; 891 - 892 - if (enable) { 893 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 894 - reg |= ENHANCED; 895 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 896 - } else { 897 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 898 - reg &= ~ENHANCED; 899 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 900 - } 901 - } 902 - 903 - void exynos_dp_set_training_pattern(struct exynos_dp_device *dp, 904 - enum pattern_set pattern) 905 - { 906 - u32 reg; 907 - 908 - switch (pattern) { 909 - case PRBS7: 910 - reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_PRBS7; 911 - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 912 - break; 913 - case D10_2: 914 - reg = SCRAMBLING_ENABLE | LINK_QUAL_PATTERN_SET_D10_2; 915 - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 916 - break; 917 - case TRAINING_PTN1: 918 - reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN1; 919 - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 920 - break; 921 - case TRAINING_PTN2: 922 - reg = SCRAMBLING_DISABLE | SW_TRAINING_PATTERN_SET_PTN2; 923 - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 924 - break; 925 - case DP_NONE: 926 - reg = SCRAMBLING_ENABLE | 927 - LINK_QUAL_PATTERN_SET_DISABLE | 928 - SW_TRAINING_PATTERN_SET_NORMAL; 929 - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 930 - break; 931 - default: 932 - break; 933 - } 934 - } 935 - 936 - void exynos_dp_set_lane0_pre_emphasis(struct exynos_dp_device *dp, u32 level) 937 - { 938 - u32 reg; 939 - 940 - reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 941 - reg &= ~PRE_EMPHASIS_SET_MASK; 942 - reg |= level << PRE_EMPHASIS_SET_SHIFT; 943 - writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 944 - } 945 - 946 - void exynos_dp_set_lane1_pre_emphasis(struct exynos_dp_device *dp, u32 level) 947 - { 948 - u32 reg; 949 - 950 - reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 951 - reg &= ~PRE_EMPHASIS_SET_MASK; 952 - reg |= level << PRE_EMPHASIS_SET_SHIFT; 953 - writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 954 - } 955 - 956 - void exynos_dp_set_lane2_pre_emphasis(struct exynos_dp_device *dp, u32 level) 957 - { 958 - u32 reg; 959 - 960 - reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 961 - reg &= ~PRE_EMPHASIS_SET_MASK; 962 - reg |= level << PRE_EMPHASIS_SET_SHIFT; 963 - writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 964 - } 965 - 966 - void exynos_dp_set_lane3_pre_emphasis(struct exynos_dp_device *dp, u32 level) 967 - { 968 - u32 reg; 969 - 970 - reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 971 - reg &= ~PRE_EMPHASIS_SET_MASK; 972 - reg |= level << PRE_EMPHASIS_SET_SHIFT; 973 - writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 974 - } 975 - 976 - void exynos_dp_set_lane0_link_training(struct exynos_dp_device *dp, 977 - u32 training_lane) 978 - { 979 - u32 reg; 980 - 981 - reg = training_lane; 982 - writel(reg, dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 983 - } 984 - 985 - void exynos_dp_set_lane1_link_training(struct exynos_dp_device *dp, 986 - u32 training_lane) 987 - { 988 - u32 reg; 989 - 990 - reg = training_lane; 991 - writel(reg, dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 992 - } 993 - 994 - void exynos_dp_set_lane2_link_training(struct exynos_dp_device *dp, 995 - u32 training_lane) 996 - { 997 - u32 reg; 998 - 999 - reg = training_lane; 1000 - writel(reg, dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 1001 - } 1002 - 1003 - void exynos_dp_set_lane3_link_training(struct exynos_dp_device *dp, 1004 - u32 training_lane) 1005 - { 1006 - u32 reg; 1007 - 1008 - reg = training_lane; 1009 - writel(reg, dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 1010 - } 1011 - 1012 - u32 exynos_dp_get_lane0_link_training(struct exynos_dp_device *dp) 1013 - { 1014 - u32 reg; 1015 - 1016 - reg = readl(dp->reg_base + EXYNOS_DP_LN0_LINK_TRAINING_CTL); 1017 - return reg; 1018 - } 1019 - 1020 - u32 exynos_dp_get_lane1_link_training(struct exynos_dp_device *dp) 1021 - { 1022 - u32 reg; 1023 - 1024 - reg = readl(dp->reg_base + EXYNOS_DP_LN1_LINK_TRAINING_CTL); 1025 - return reg; 1026 - } 1027 - 1028 - u32 exynos_dp_get_lane2_link_training(struct exynos_dp_device *dp) 1029 - { 1030 - u32 reg; 1031 - 1032 - reg = readl(dp->reg_base + EXYNOS_DP_LN2_LINK_TRAINING_CTL); 1033 - return reg; 1034 - } 1035 - 1036 - u32 exynos_dp_get_lane3_link_training(struct exynos_dp_device *dp) 1037 - { 1038 - u32 reg; 1039 - 1040 - reg = readl(dp->reg_base + EXYNOS_DP_LN3_LINK_TRAINING_CTL); 1041 - return reg; 1042 - } 1043 - 1044 - void exynos_dp_reset_macro(struct exynos_dp_device *dp) 1045 - { 1046 - u32 reg; 1047 - 1048 - reg = readl(dp->reg_base + EXYNOS_DP_PHY_TEST); 1049 - reg |= MACRO_RST; 1050 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); 1051 - 1052 - /* 10 us is the minimum reset time. */ 1053 - usleep_range(10, 20); 1054 - 1055 - reg &= ~MACRO_RST; 1056 - writel(reg, dp->reg_base + EXYNOS_DP_PHY_TEST); 1057 - } 1058 - 1059 - void exynos_dp_init_video(struct exynos_dp_device *dp) 1060 - { 1061 - u32 reg; 1062 - 1063 - reg = VSYNC_DET | VID_FORMAT_CHG | VID_CLK_CHG; 1064 - writel(reg, dp->reg_base + EXYNOS_DP_COMMON_INT_STA_1); 1065 - 1066 - reg = 0x0; 1067 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1068 - 1069 - reg = CHA_CRI(4) | CHA_CTRL; 1070 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1071 - 1072 - reg = 0x0; 1073 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1074 - 1075 - reg = VID_HRES_TH(2) | VID_VRES_TH(0); 1076 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_8); 1077 - } 1078 - 1079 - void exynos_dp_set_video_color_format(struct exynos_dp_device *dp) 1080 - { 1081 - u32 reg; 1082 - 1083 - /* Configure the input color depth, color space, dynamic range */ 1084 - reg = (dp->video_info->dynamic_range << IN_D_RANGE_SHIFT) | 1085 - (dp->video_info->color_depth << IN_BPC_SHIFT) | 1086 - (dp->video_info->color_space << IN_COLOR_F_SHIFT); 1087 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_2); 1088 - 1089 - /* Set Input Color YCbCr Coefficients to ITU601 or ITU709 */ 1090 - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); 1091 - reg &= ~IN_YC_COEFFI_MASK; 1092 - if (dp->video_info->ycbcr_coeff) 1093 - reg |= IN_YC_COEFFI_ITU709; 1094 - else 1095 - reg |= IN_YC_COEFFI_ITU601; 1096 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_3); 1097 - } 1098 - 1099 - int exynos_dp_is_slave_video_stream_clock_on(struct exynos_dp_device *dp) 1100 - { 1101 - u32 reg; 1102 - 1103 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1104 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1105 - 1106 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_1); 1107 - 1108 - if (!(reg & DET_STA)) { 1109 - dev_dbg(dp->dev, "Input stream clock not detected.\n"); 1110 - return -EINVAL; 1111 - } 1112 - 1113 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1114 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1115 - 1116 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_2); 1117 - dev_dbg(dp->dev, "wait SYS_CTL_2.\n"); 1118 - 1119 - if (reg & CHA_STA) { 1120 - dev_dbg(dp->dev, "Input stream clk is changing\n"); 1121 - return -EINVAL; 1122 - } 1123 - 1124 - return 0; 1125 - } 1126 - 1127 - void exynos_dp_set_video_cr_mn(struct exynos_dp_device *dp, 1128 - enum clock_recovery_m_value_type type, 1129 - u32 m_value, 1130 - u32 n_value) 1131 - { 1132 - u32 reg; 1133 - 1134 - if (type == REGISTER_M) { 1135 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1136 - reg |= FIX_M_VID; 1137 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1138 - reg = m_value & 0xff; 1139 - writel(reg, dp->reg_base + EXYNOS_DP_M_VID_0); 1140 - reg = (m_value >> 8) & 0xff; 1141 - writel(reg, dp->reg_base + EXYNOS_DP_M_VID_1); 1142 - reg = (m_value >> 16) & 0xff; 1143 - writel(reg, dp->reg_base + EXYNOS_DP_M_VID_2); 1144 - 1145 - reg = n_value & 0xff; 1146 - writel(reg, dp->reg_base + EXYNOS_DP_N_VID_0); 1147 - reg = (n_value >> 8) & 0xff; 1148 - writel(reg, dp->reg_base + EXYNOS_DP_N_VID_1); 1149 - reg = (n_value >> 16) & 0xff; 1150 - writel(reg, dp->reg_base + EXYNOS_DP_N_VID_2); 1151 - } else { 1152 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1153 - reg &= ~FIX_M_VID; 1154 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_4); 1155 - 1156 - writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_0); 1157 - writel(0x80, dp->reg_base + EXYNOS_DP_N_VID_1); 1158 - writel(0x00, dp->reg_base + EXYNOS_DP_N_VID_2); 1159 - } 1160 - } 1161 - 1162 - void exynos_dp_set_video_timing_mode(struct exynos_dp_device *dp, u32 type) 1163 - { 1164 - u32 reg; 1165 - 1166 - if (type == VIDEO_TIMING_FROM_CAPTURE) { 1167 - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1168 - reg &= ~FORMAT_SEL; 1169 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1170 - } else { 1171 - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1172 - reg |= FORMAT_SEL; 1173 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1174 - } 1175 - } 1176 - 1177 - void exynos_dp_enable_video_master(struct exynos_dp_device *dp, bool enable) 1178 - { 1179 - u32 reg; 1180 - 1181 - if (enable) { 1182 - reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1183 - reg &= ~VIDEO_MODE_MASK; 1184 - reg |= VIDEO_MASTER_MODE_EN | VIDEO_MODE_MASTER_MODE; 1185 - writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1186 - } else { 1187 - reg = readl(dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1188 - reg &= ~VIDEO_MODE_MASK; 1189 - reg |= VIDEO_MODE_SLAVE_MODE; 1190 - writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1191 - } 1192 - } 1193 - 1194 - void exynos_dp_start_video(struct exynos_dp_device *dp) 1195 - { 1196 - u32 reg; 1197 - 1198 - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 1199 - reg |= VIDEO_EN; 1200 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_1); 1201 - } 1202 - 1203 - int exynos_dp_is_video_stream_on(struct exynos_dp_device *dp) 1204 - { 1205 - u32 reg; 1206 - 1207 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1208 - writel(reg, dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1209 - 1210 - reg = readl(dp->reg_base + EXYNOS_DP_SYS_CTL_3); 1211 - if (!(reg & STRM_VALID)) { 1212 - dev_dbg(dp->dev, "Input video stream is not detected.\n"); 1213 - return -EINVAL; 1214 - } 1215 - 1216 - return 0; 1217 - } 1218 - 1219 - void exynos_dp_config_video_slave_mode(struct exynos_dp_device *dp) 1220 - { 1221 - u32 reg; 1222 - 1223 - reg = readl(dp->reg_base + EXYNOS_DP_FUNC_EN_1); 1224 - reg &= ~(MASTER_VID_FUNC_EN_N|SLAVE_VID_FUNC_EN_N); 1225 - reg |= MASTER_VID_FUNC_EN_N; 1226 - writel(reg, dp->reg_base + EXYNOS_DP_FUNC_EN_1); 1227 - 1228 - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1229 - reg &= ~INTERACE_SCAN_CFG; 1230 - reg |= (dp->video_info->interlaced << 2); 1231 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1232 - 1233 - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1234 - reg &= ~VSYNC_POLARITY_CFG; 1235 - reg |= (dp->video_info->v_sync_polarity << 1); 1236 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1237 - 1238 - reg = readl(dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1239 - reg &= ~HSYNC_POLARITY_CFG; 1240 - reg |= (dp->video_info->h_sync_polarity << 0); 1241 - writel(reg, dp->reg_base + EXYNOS_DP_VIDEO_CTL_10); 1242 - 1243 - reg = AUDIO_MODE_SPDIF_MODE | VIDEO_MODE_SLAVE_MODE; 1244 - writel(reg, dp->reg_base + EXYNOS_DP_SOC_GENERAL_CTL); 1245 - } 1246 - 1247 - void exynos_dp_enable_scrambling(struct exynos_dp_device *dp) 1248 - { 1249 - u32 reg; 1250 - 1251 - reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1252 - reg &= ~SCRAMBLING_DISABLE; 1253 - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1254 - } 1255 - 1256 - void exynos_dp_disable_scrambling(struct exynos_dp_device *dp) 1257 - { 1258 - u32 reg; 1259 - 1260 - reg = readl(dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1261 - reg |= SCRAMBLING_DISABLE; 1262 - writel(reg, dp->reg_base + EXYNOS_DP_TRAINING_PTN_SET); 1263 - }
+124 -112
drivers/gpu/drm/exynos/exynos_dp_reg.h drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
··· 1 1 /* 2 - * Register definition file for Samsung DP driver 2 + * Register definition file for Analogix DP core driver 3 3 * 4 4 * Copyright (C) 2012 Samsung Electronics Co., Ltd. 5 5 * Author: Jingoo Han <jg1.han@samsung.com> ··· 9 9 * published by the Free Software Foundation. 10 10 */ 11 11 12 - #ifndef _EXYNOS_DP_REG_H 13 - #define _EXYNOS_DP_REG_H 12 + #ifndef _ANALOGIX_DP_REG_H 13 + #define _ANALOGIX_DP_REG_H 14 14 15 - #define EXYNOS_DP_TX_SW_RESET 0x14 16 - #define EXYNOS_DP_FUNC_EN_1 0x18 17 - #define EXYNOS_DP_FUNC_EN_2 0x1C 18 - #define EXYNOS_DP_VIDEO_CTL_1 0x20 19 - #define EXYNOS_DP_VIDEO_CTL_2 0x24 20 - #define EXYNOS_DP_VIDEO_CTL_3 0x28 15 + #define ANALOGIX_DP_TX_SW_RESET 0x14 16 + #define ANALOGIX_DP_FUNC_EN_1 0x18 17 + #define ANALOGIX_DP_FUNC_EN_2 0x1C 18 + #define ANALOGIX_DP_VIDEO_CTL_1 0x20 19 + #define ANALOGIX_DP_VIDEO_CTL_2 0x24 20 + #define ANALOGIX_DP_VIDEO_CTL_3 0x28 21 21 22 - #define EXYNOS_DP_VIDEO_CTL_8 0x3C 23 - #define EXYNOS_DP_VIDEO_CTL_10 0x44 22 + #define ANALOGIX_DP_VIDEO_CTL_8 0x3C 23 + #define ANALOGIX_DP_VIDEO_CTL_10 0x44 24 24 25 - #define EXYNOS_DP_LANE_MAP 0x35C 25 + #define ANALOGIX_DP_PLL_REG_1 0xfc 26 + #define ANALOGIX_DP_PLL_REG_2 0x9e4 27 + #define ANALOGIX_DP_PLL_REG_3 0x9e8 28 + #define ANALOGIX_DP_PLL_REG_4 0x9ec 29 + #define ANALOGIX_DP_PLL_REG_5 0xa00 26 30 27 - #define EXYNOS_DP_ANALOG_CTL_1 0x370 28 - #define EXYNOS_DP_ANALOG_CTL_2 0x374 29 - #define EXYNOS_DP_ANALOG_CTL_3 0x378 30 - #define EXYNOS_DP_PLL_FILTER_CTL_1 0x37C 31 - #define EXYNOS_DP_TX_AMP_TUNING_CTL 0x380 31 + #define ANALOGIX_DP_PD 0x12c 32 32 33 - #define EXYNOS_DP_AUX_HW_RETRY_CTL 0x390 33 + #define ANALOGIX_DP_LANE_MAP 0x35C 34 34 35 - #define EXYNOS_DP_COMMON_INT_STA_1 0x3C4 36 - #define EXYNOS_DP_COMMON_INT_STA_2 0x3C8 37 - #define EXYNOS_DP_COMMON_INT_STA_3 0x3CC 38 - #define EXYNOS_DP_COMMON_INT_STA_4 0x3D0 39 - #define EXYNOS_DP_INT_STA 0x3DC 40 - #define EXYNOS_DP_COMMON_INT_MASK_1 0x3E0 41 - #define EXYNOS_DP_COMMON_INT_MASK_2 0x3E4 42 - #define EXYNOS_DP_COMMON_INT_MASK_3 0x3E8 43 - #define EXYNOS_DP_COMMON_INT_MASK_4 0x3EC 44 - #define EXYNOS_DP_INT_STA_MASK 0x3F8 45 - #define EXYNOS_DP_INT_CTL 0x3FC 35 + #define ANALOGIX_DP_ANALOG_CTL_1 0x370 36 + #define ANALOGIX_DP_ANALOG_CTL_2 0x374 37 + #define ANALOGIX_DP_ANALOG_CTL_3 0x378 38 + #define ANALOGIX_DP_PLL_FILTER_CTL_1 0x37C 39 + #define ANALOGIX_DP_TX_AMP_TUNING_CTL 0x380 46 40 47 - #define EXYNOS_DP_SYS_CTL_1 0x600 48 - #define EXYNOS_DP_SYS_CTL_2 0x604 49 - #define EXYNOS_DP_SYS_CTL_3 0x608 50 - #define EXYNOS_DP_SYS_CTL_4 0x60C 41 + #define ANALOGIX_DP_AUX_HW_RETRY_CTL 0x390 51 42 52 - #define EXYNOS_DP_PKT_SEND_CTL 0x640 53 - #define EXYNOS_DP_HDCP_CTL 0x648 43 + #define ANALOGIX_DP_COMMON_INT_STA_1 0x3C4 44 + #define ANALOGIX_DP_COMMON_INT_STA_2 0x3C8 45 + #define ANALOGIX_DP_COMMON_INT_STA_3 0x3CC 46 + #define ANALOGIX_DP_COMMON_INT_STA_4 0x3D0 47 + #define ANALOGIX_DP_INT_STA 0x3DC 48 + #define ANALOGIX_DP_COMMON_INT_MASK_1 0x3E0 49 + #define ANALOGIX_DP_COMMON_INT_MASK_2 0x3E4 50 + #define ANALOGIX_DP_COMMON_INT_MASK_3 0x3E8 51 + #define ANALOGIX_DP_COMMON_INT_MASK_4 0x3EC 52 + #define ANALOGIX_DP_INT_STA_MASK 0x3F8 53 + #define ANALOGIX_DP_INT_CTL 0x3FC 54 54 55 - #define EXYNOS_DP_LINK_BW_SET 0x680 56 - #define EXYNOS_DP_LANE_COUNT_SET 0x684 57 - #define EXYNOS_DP_TRAINING_PTN_SET 0x688 58 - #define EXYNOS_DP_LN0_LINK_TRAINING_CTL 0x68C 59 - #define EXYNOS_DP_LN1_LINK_TRAINING_CTL 0x690 60 - #define EXYNOS_DP_LN2_LINK_TRAINING_CTL 0x694 61 - #define EXYNOS_DP_LN3_LINK_TRAINING_CTL 0x698 55 + #define ANALOGIX_DP_SYS_CTL_1 0x600 56 + #define ANALOGIX_DP_SYS_CTL_2 0x604 57 + #define ANALOGIX_DP_SYS_CTL_3 0x608 58 + #define ANALOGIX_DP_SYS_CTL_4 0x60C 62 59 63 - #define EXYNOS_DP_DEBUG_CTL 0x6C0 64 - #define EXYNOS_DP_HPD_DEGLITCH_L 0x6C4 65 - #define EXYNOS_DP_HPD_DEGLITCH_H 0x6C8 66 - #define EXYNOS_DP_LINK_DEBUG_CTL 0x6E0 60 + #define ANALOGIX_DP_PKT_SEND_CTL 0x640 61 + #define ANALOGIX_DP_HDCP_CTL 0x648 67 62 68 - #define EXYNOS_DP_M_VID_0 0x700 69 - #define EXYNOS_DP_M_VID_1 0x704 70 - #define EXYNOS_DP_M_VID_2 0x708 71 - #define EXYNOS_DP_N_VID_0 0x70C 72 - #define EXYNOS_DP_N_VID_1 0x710 73 - #define EXYNOS_DP_N_VID_2 0x714 63 + #define ANALOGIX_DP_LINK_BW_SET 0x680 64 + #define ANALOGIX_DP_LANE_COUNT_SET 0x684 65 + #define ANALOGIX_DP_TRAINING_PTN_SET 0x688 66 + #define ANALOGIX_DP_LN0_LINK_TRAINING_CTL 0x68C 67 + #define ANALOGIX_DP_LN1_LINK_TRAINING_CTL 0x690 68 + #define ANALOGIX_DP_LN2_LINK_TRAINING_CTL 0x694 69 + #define ANALOGIX_DP_LN3_LINK_TRAINING_CTL 0x698 74 70 75 - #define EXYNOS_DP_PLL_CTL 0x71C 76 - #define EXYNOS_DP_PHY_PD 0x720 77 - #define EXYNOS_DP_PHY_TEST 0x724 71 + #define ANALOGIX_DP_DEBUG_CTL 0x6C0 72 + #define ANALOGIX_DP_HPD_DEGLITCH_L 0x6C4 73 + #define ANALOGIX_DP_HPD_DEGLITCH_H 0x6C8 74 + #define ANALOGIX_DP_LINK_DEBUG_CTL 0x6E0 78 75 79 - #define EXYNOS_DP_VIDEO_FIFO_THRD 0x730 80 - #define EXYNOS_DP_AUDIO_MARGIN 0x73C 76 + #define ANALOGIX_DP_M_VID_0 0x700 77 + #define ANALOGIX_DP_M_VID_1 0x704 78 + #define ANALOGIX_DP_M_VID_2 0x708 79 + #define ANALOGIX_DP_N_VID_0 0x70C 80 + #define ANALOGIX_DP_N_VID_1 0x710 81 + #define ANALOGIX_DP_N_VID_2 0x714 81 82 82 - #define EXYNOS_DP_M_VID_GEN_FILTER_TH 0x764 83 - #define EXYNOS_DP_M_AUD_GEN_FILTER_TH 0x778 84 - #define EXYNOS_DP_AUX_CH_STA 0x780 85 - #define EXYNOS_DP_AUX_CH_DEFER_CTL 0x788 86 - #define EXYNOS_DP_AUX_RX_COMM 0x78C 87 - #define EXYNOS_DP_BUFFER_DATA_CTL 0x790 88 - #define EXYNOS_DP_AUX_CH_CTL_1 0x794 89 - #define EXYNOS_DP_AUX_ADDR_7_0 0x798 90 - #define EXYNOS_DP_AUX_ADDR_15_8 0x79C 91 - #define EXYNOS_DP_AUX_ADDR_19_16 0x7A0 92 - #define EXYNOS_DP_AUX_CH_CTL_2 0x7A4 83 + #define ANALOGIX_DP_PLL_CTL 0x71C 84 + #define ANALOGIX_DP_PHY_PD 0x720 85 + #define ANALOGIX_DP_PHY_TEST 0x724 93 86 94 - #define EXYNOS_DP_BUF_DATA_0 0x7C0 87 + #define ANALOGIX_DP_VIDEO_FIFO_THRD 0x730 88 + #define ANALOGIX_DP_AUDIO_MARGIN 0x73C 95 89 96 - #define EXYNOS_DP_SOC_GENERAL_CTL 0x800 90 + #define ANALOGIX_DP_M_VID_GEN_FILTER_TH 0x764 91 + #define ANALOGIX_DP_M_AUD_GEN_FILTER_TH 0x778 92 + #define ANALOGIX_DP_AUX_CH_STA 0x780 93 + #define ANALOGIX_DP_AUX_CH_DEFER_CTL 0x788 94 + #define ANALOGIX_DP_AUX_RX_COMM 0x78C 95 + #define ANALOGIX_DP_BUFFER_DATA_CTL 0x790 96 + #define ANALOGIX_DP_AUX_CH_CTL_1 0x794 97 + #define ANALOGIX_DP_AUX_ADDR_7_0 0x798 98 + #define ANALOGIX_DP_AUX_ADDR_15_8 0x79C 99 + #define ANALOGIX_DP_AUX_ADDR_19_16 0x7A0 100 + #define ANALOGIX_DP_AUX_CH_CTL_2 0x7A4 97 101 98 - /* EXYNOS_DP_TX_SW_RESET */ 102 + #define ANALOGIX_DP_BUF_DATA_0 0x7C0 103 + 104 + #define ANALOGIX_DP_SOC_GENERAL_CTL 0x800 105 + 106 + /* ANALOGIX_DP_TX_SW_RESET */ 99 107 #define RESET_DP_TX (0x1 << 0) 100 108 101 - /* EXYNOS_DP_FUNC_EN_1 */ 109 + /* ANALOGIX_DP_FUNC_EN_1 */ 102 110 #define MASTER_VID_FUNC_EN_N (0x1 << 7) 103 111 #define SLAVE_VID_FUNC_EN_N (0x1 << 5) 104 112 #define AUD_FIFO_FUNC_EN_N (0x1 << 4) ··· 115 107 #define CRC_FUNC_EN_N (0x1 << 1) 116 108 #define SW_FUNC_EN_N (0x1 << 0) 117 109 118 - /* EXYNOS_DP_FUNC_EN_2 */ 110 + /* ANALOGIX_DP_FUNC_EN_2 */ 119 111 #define SSC_FUNC_EN_N (0x1 << 7) 120 112 #define AUX_FUNC_EN_N (0x1 << 2) 121 113 #define SERDES_FIFO_FUNC_EN_N (0x1 << 1) 122 114 #define LS_CLK_DOMAIN_FUNC_EN_N (0x1 << 0) 123 115 124 - /* EXYNOS_DP_VIDEO_CTL_1 */ 116 + /* ANALOGIX_DP_VIDEO_CTL_1 */ 125 117 #define VIDEO_EN (0x1 << 7) 126 118 #define HDCP_VIDEO_MUTE (0x1 << 6) 127 119 128 - /* EXYNOS_DP_VIDEO_CTL_1 */ 120 + /* ANALOGIX_DP_VIDEO_CTL_1 */ 129 121 #define IN_D_RANGE_MASK (0x1 << 7) 130 122 #define IN_D_RANGE_SHIFT (7) 131 123 #define IN_D_RANGE_CEA (0x1 << 7) ··· 142 134 #define IN_COLOR_F_YCBCR422 (0x1 << 0) 143 135 #define IN_COLOR_F_RGB (0x0 << 0) 144 136 145 - /* EXYNOS_DP_VIDEO_CTL_3 */ 137 + /* ANALOGIX_DP_VIDEO_CTL_3 */ 146 138 #define IN_YC_COEFFI_MASK (0x1 << 7) 147 139 #define IN_YC_COEFFI_SHIFT (7) 148 140 #define IN_YC_COEFFI_ITU709 (0x1 << 7) ··· 152 144 #define VID_CHK_UPDATE_TYPE_1 (0x1 << 4) 153 145 #define VID_CHK_UPDATE_TYPE_0 (0x0 << 4) 154 146 155 - /* EXYNOS_DP_VIDEO_CTL_8 */ 147 + /* ANALOGIX_DP_VIDEO_CTL_8 */ 156 148 #define VID_HRES_TH(x) (((x) & 0xf) << 4) 157 149 #define VID_VRES_TH(x) (((x) & 0xf) << 0) 158 150 159 - /* EXYNOS_DP_VIDEO_CTL_10 */ 151 + /* ANALOGIX_DP_VIDEO_CTL_10 */ 160 152 #define FORMAT_SEL (0x1 << 4) 161 153 #define INTERACE_SCAN_CFG (0x1 << 2) 162 154 #define VSYNC_POLARITY_CFG (0x1 << 1) 163 155 #define HSYNC_POLARITY_CFG (0x1 << 0) 164 156 165 - /* EXYNOS_DP_LANE_MAP */ 157 + /* ANALOGIX_DP_PLL_REG_1 */ 158 + #define REF_CLK_24M (0x1 << 1) 159 + #define REF_CLK_27M (0x0 << 1) 160 + 161 + /* ANALOGIX_DP_LANE_MAP */ 166 162 #define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6) 167 163 #define LANE3_MAP_LOGIC_LANE_1 (0x1 << 6) 168 164 #define LANE3_MAP_LOGIC_LANE_2 (0x2 << 6) ··· 184 172 #define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0) 185 173 #define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0) 186 174 187 - /* EXYNOS_DP_ANALOG_CTL_1 */ 175 + /* ANALOGIX_DP_ANALOG_CTL_1 */ 188 176 #define TX_TERMINAL_CTRL_50_OHM (0x1 << 4) 189 177 190 - /* EXYNOS_DP_ANALOG_CTL_2 */ 178 + /* ANALOGIX_DP_ANALOG_CTL_2 */ 191 179 #define SEL_24M (0x1 << 3) 192 180 #define TX_DVDD_BIT_1_0625V (0x4 << 0) 193 181 194 - /* EXYNOS_DP_ANALOG_CTL_3 */ 182 + /* ANALOGIX_DP_ANALOG_CTL_3 */ 195 183 #define DRIVE_DVDD_BIT_1_0625V (0x4 << 5) 196 184 #define VCO_BIT_600_MICRO (0x5 << 0) 197 185 198 - /* EXYNOS_DP_PLL_FILTER_CTL_1 */ 186 + /* ANALOGIX_DP_PLL_FILTER_CTL_1 */ 199 187 #define PD_RING_OSC (0x1 << 6) 200 188 #define AUX_TERMINAL_CTRL_50_OHM (0x2 << 4) 201 189 #define TX_CUR1_2X (0x1 << 2) 202 190 #define TX_CUR_16_MA (0x3 << 0) 203 191 204 - /* EXYNOS_DP_TX_AMP_TUNING_CTL */ 192 + /* ANALOGIX_DP_TX_AMP_TUNING_CTL */ 205 193 #define CH3_AMP_400_MV (0x0 << 24) 206 194 #define CH2_AMP_400_MV (0x0 << 16) 207 195 #define CH1_AMP_400_MV (0x0 << 8) 208 196 #define CH0_AMP_400_MV (0x0 << 0) 209 197 210 - /* EXYNOS_DP_AUX_HW_RETRY_CTL */ 198 + /* ANALOGIX_DP_AUX_HW_RETRY_CTL */ 211 199 #define AUX_BIT_PERIOD_EXPECTED_DELAY(x) (((x) & 0x7) << 8) 212 200 #define AUX_HW_RETRY_INTERVAL_MASK (0x3 << 3) 213 201 #define AUX_HW_RETRY_INTERVAL_600_MICROSECONDS (0x0 << 3) ··· 216 204 #define AUX_HW_RETRY_INTERVAL_1800_MICROSECONDS (0x3 << 3) 217 205 #define AUX_HW_RETRY_COUNT_SEL(x) (((x) & 0x7) << 0) 218 206 219 - /* EXYNOS_DP_COMMON_INT_STA_1 */ 207 + /* ANALOGIX_DP_COMMON_INT_STA_1 */ 220 208 #define VSYNC_DET (0x1 << 7) 221 209 #define PLL_LOCK_CHG (0x1 << 6) 222 210 #define SPDIF_ERR (0x1 << 5) ··· 226 214 #define VID_CLK_CHG (0x1 << 1) 227 215 #define SW_INT (0x1 << 0) 228 216 229 - /* EXYNOS_DP_COMMON_INT_STA_2 */ 217 + /* ANALOGIX_DP_COMMON_INT_STA_2 */ 230 218 #define ENC_EN_CHG (0x1 << 6) 231 219 #define HW_BKSV_RDY (0x1 << 3) 232 220 #define HW_SHA_DONE (0x1 << 2) 233 221 #define HW_AUTH_STATE_CHG (0x1 << 1) 234 222 #define HW_AUTH_DONE (0x1 << 0) 235 223 236 - /* EXYNOS_DP_COMMON_INT_STA_3 */ 224 + /* ANALOGIX_DP_COMMON_INT_STA_3 */ 237 225 #define AFIFO_UNDER (0x1 << 7) 238 226 #define AFIFO_OVER (0x1 << 6) 239 227 #define R0_CHK_FLAG (0x1 << 5) 240 228 241 - /* EXYNOS_DP_COMMON_INT_STA_4 */ 229 + /* ANALOGIX_DP_COMMON_INT_STA_4 */ 242 230 #define PSR_ACTIVE (0x1 << 7) 243 231 #define PSR_INACTIVE (0x1 << 6) 244 232 #define SPDIF_BI_PHASE_ERR (0x1 << 5) ··· 246 234 #define HPD_LOST (0x1 << 1) 247 235 #define PLUG (0x1 << 0) 248 236 249 - /* EXYNOS_DP_INT_STA */ 237 + /* ANALOGIX_DP_INT_STA */ 250 238 #define INT_HPD (0x1 << 6) 251 239 #define HW_TRAINING_FINISH (0x1 << 5) 252 240 #define RPLY_RECEIV (0x1 << 1) 253 241 #define AUX_ERR (0x1 << 0) 254 242 255 - /* EXYNOS_DP_INT_CTL */ 243 + /* ANALOGIX_DP_INT_CTL */ 256 244 #define SOFT_INT_CTRL (0x1 << 2) 257 245 #define INT_POL1 (0x1 << 1) 258 246 #define INT_POL0 (0x1 << 0) 259 247 260 - /* EXYNOS_DP_SYS_CTL_1 */ 248 + /* ANALOGIX_DP_SYS_CTL_1 */ 261 249 #define DET_STA (0x1 << 2) 262 250 #define FORCE_DET (0x1 << 1) 263 251 #define DET_CTRL (0x1 << 0) 264 252 265 - /* EXYNOS_DP_SYS_CTL_2 */ 253 + /* ANALOGIX_DP_SYS_CTL_2 */ 266 254 #define CHA_CRI(x) (((x) & 0xf) << 4) 267 255 #define CHA_STA (0x1 << 2) 268 256 #define FORCE_CHA (0x1 << 1) 269 257 #define CHA_CTRL (0x1 << 0) 270 258 271 - /* EXYNOS_DP_SYS_CTL_3 */ 259 + /* ANALOGIX_DP_SYS_CTL_3 */ 272 260 #define HPD_STATUS (0x1 << 6) 273 261 #define F_HPD (0x1 << 5) 274 262 #define HPD_CTRL (0x1 << 4) ··· 277 265 #define F_VALID (0x1 << 1) 278 266 #define VALID_CTRL (0x1 << 0) 279 267 280 - /* EXYNOS_DP_SYS_CTL_4 */ 268 + /* ANALOGIX_DP_SYS_CTL_4 */ 281 269 #define FIX_M_AUD (0x1 << 4) 282 270 #define ENHANCED (0x1 << 3) 283 271 #define FIX_M_VID (0x1 << 2) 284 272 #define M_VID_UPDATE_CTRL (0x3 << 0) 285 273 286 - /* EXYNOS_DP_TRAINING_PTN_SET */ 274 + /* ANALOGIX_DP_TRAINING_PTN_SET */ 287 275 #define SCRAMBLER_TYPE (0x1 << 9) 288 276 #define HW_LINK_TRAINING_PATTERN (0x1 << 8) 289 277 #define SCRAMBLING_DISABLE (0x1 << 5) ··· 297 285 #define SW_TRAINING_PATTERN_SET_PTN1 (0x1 << 0) 298 286 #define SW_TRAINING_PATTERN_SET_NORMAL (0x0 << 0) 299 287 300 - /* EXYNOS_DP_LN0_LINK_TRAINING_CTL */ 288 + /* ANALOGIX_DP_LN0_LINK_TRAINING_CTL */ 301 289 #define PRE_EMPHASIS_SET_MASK (0x3 << 3) 302 290 #define PRE_EMPHASIS_SET_SHIFT (3) 303 291 304 - /* EXYNOS_DP_DEBUG_CTL */ 292 + /* ANALOGIX_DP_DEBUG_CTL */ 305 293 #define PLL_LOCK (0x1 << 4) 306 294 #define F_PLL_LOCK (0x1 << 3) 307 295 #define PLL_LOCK_CTRL (0x1 << 2) 308 296 #define PN_INV (0x1 << 0) 309 297 310 - /* EXYNOS_DP_PLL_CTL */ 298 + /* ANALOGIX_DP_PLL_CTL */ 311 299 #define DP_PLL_PD (0x1 << 7) 312 300 #define DP_PLL_RESET (0x1 << 6) 313 301 #define DP_PLL_LOOP_BIT_DEFAULT (0x1 << 4) 314 302 #define DP_PLL_REF_BIT_1_1250V (0x5 << 0) 315 303 #define DP_PLL_REF_BIT_1_2500V (0x7 << 0) 316 304 317 - /* EXYNOS_DP_PHY_PD */ 305 + /* ANALOGIX_DP_PHY_PD */ 318 306 #define DP_PHY_PD (0x1 << 5) 319 307 #define AUX_PD (0x1 << 4) 320 308 #define CH3_PD (0x1 << 3) ··· 322 310 #define CH1_PD (0x1 << 1) 323 311 #define CH0_PD (0x1 << 0) 324 312 325 - /* EXYNOS_DP_PHY_TEST */ 313 + /* ANALOGIX_DP_PHY_TEST */ 326 314 #define MACRO_RST (0x1 << 5) 327 315 #define CH1_TEST (0x1 << 1) 328 316 #define CH0_TEST (0x1 << 0) 329 317 330 - /* EXYNOS_DP_AUX_CH_STA */ 318 + /* ANALOGIX_DP_AUX_CH_STA */ 331 319 #define AUX_BUSY (0x1 << 4) 332 320 #define AUX_STATUS_MASK (0xf << 0) 333 321 334 - /* EXYNOS_DP_AUX_CH_DEFER_CTL */ 322 + /* ANALOGIX_DP_AUX_CH_DEFER_CTL */ 335 323 #define DEFER_CTRL_EN (0x1 << 7) 336 324 #define DEFER_COUNT(x) (((x) & 0x7f) << 0) 337 325 338 - /* EXYNOS_DP_AUX_RX_COMM */ 326 + /* ANALOGIX_DP_AUX_RX_COMM */ 339 327 #define AUX_RX_COMM_I2C_DEFER (0x2 << 2) 340 328 #define AUX_RX_COMM_AUX_DEFER (0x2 << 0) 341 329 342 - /* EXYNOS_DP_BUFFER_DATA_CTL */ 330 + /* ANALOGIX_DP_BUFFER_DATA_CTL */ 343 331 #define BUF_CLR (0x1 << 7) 344 332 #define BUF_DATA_COUNT(x) (((x) & 0x1f) << 0) 345 333 346 - /* EXYNOS_DP_AUX_CH_CTL_1 */ 334 + /* ANALOGIX_DP_AUX_CH_CTL_1 */ 347 335 #define AUX_LENGTH(x) (((x - 1) & 0xf) << 4) 348 336 #define AUX_TX_COMM_MASK (0xf << 0) 349 337 #define AUX_TX_COMM_DP_TRANSACTION (0x1 << 3) ··· 352 340 #define AUX_TX_COMM_WRITE (0x0 << 0) 353 341 #define AUX_TX_COMM_READ (0x1 << 0) 354 342 355 - /* EXYNOS_DP_AUX_ADDR_7_0 */ 343 + /* ANALOGIX_DP_AUX_ADDR_7_0 */ 356 344 #define AUX_ADDR_7_0(x) (((x) >> 0) & 0xff) 357 345 358 - /* EXYNOS_DP_AUX_ADDR_15_8 */ 346 + /* ANALOGIX_DP_AUX_ADDR_15_8 */ 359 347 #define AUX_ADDR_15_8(x) (((x) >> 8) & 0xff) 360 348 361 - /* EXYNOS_DP_AUX_ADDR_19_16 */ 349 + /* ANALOGIX_DP_AUX_ADDR_19_16 */ 362 350 #define AUX_ADDR_19_16(x) (((x) >> 16) & 0x0f) 363 351 364 - /* EXYNOS_DP_AUX_CH_CTL_2 */ 352 + /* ANALOGIX_DP_AUX_CH_CTL_2 */ 365 353 #define ADDR_ONLY (0x1 << 1) 366 354 #define AUX_EN (0x1 << 0) 367 355 368 - /* EXYNOS_DP_SOC_GENERAL_CTL */ 356 + /* ANALOGIX_DP_SOC_GENERAL_CTL */ 369 357 #define AUDIO_MODE_SPDIF_MODE (0x1 << 8) 370 358 #define AUDIO_MODE_MASTER_MODE (0x0 << 8) 371 359 #define MASTER_VIDEO_INTERLACE_EN (0x1 << 4) ··· 375 363 #define VIDEO_MODE_SLAVE_MODE (0x1 << 0) 376 364 #define VIDEO_MODE_MASTER_MODE (0x0 << 0) 377 365 378 - #endif /* _EXYNOS_DP_REG_H */ 366 + #endif /* _ANALOGIX_DP_REG_H */
+9
drivers/gpu/drm/rockchip/Kconfig
··· 16 16 2D or 3D acceleration; acceleration is performed by other 17 17 IP found on the SoC. 18 18 19 + config ROCKCHIP_ANALOGIX_DP 20 + tristate "Rockchip specific extensions for Analogix DP driver" 21 + depends on DRM_ROCKCHIP 22 + select DRM_ANALOGIX_DP 23 + help 24 + This selects support for Rockchip SoC specific extensions 25 + for the Analogix Core DP driver. If you want to enable DP 26 + on RK3288 based SoC, you should selet this option. 27 + 19 28 config ROCKCHIP_DW_HDMI 20 29 tristate "Rockchip specific extensions for Synopsys DW HDMI" 21 30 depends on DRM_ROCKCHIP
+1
drivers/gpu/drm/rockchip/Makefile
··· 6 6 rockchip_drm_gem.o rockchip_drm_vop.o 7 7 rockchipdrm-$(CONFIG_DRM_FBDEV_EMULATION) += rockchip_drm_fbdev.o 8 8 9 + obj-$(CONFIG_ROCKCHIP_ANALOGIX_DP) += analogix_dp-rockchip.o 9 10 obj-$(CONFIG_ROCKCHIP_DW_HDMI) += dw_hdmi-rockchip.o 10 11 obj-$(CONFIG_ROCKCHIP_DW_MIPI_DSI) += dw-mipi-dsi.o 11 12 obj-$(CONFIG_ROCKCHIP_INNO_HDMI) += inno_hdmi.o
+384
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
··· 1 + /* 2 + * Rockchip SoC DP (Display Port) interface driver. 3 + * 4 + * Copyright (C) Fuzhou Rockchip Electronics Co., Ltd. 5 + * Author: Andy Yan <andy.yan@rock-chips.com> 6 + * Yakir Yang <ykk@rock-chips.com> 7 + * Jeff Chen <jeff.chen@rock-chips.com> 8 + * 9 + * This program is free software; you can redistribute it and/or modify it 10 + * under the terms of the GNU General Public License as published by the 11 + * Free Software Foundation; either version 2 of the License, or (at your 12 + * option) any later version. 13 + */ 14 + 15 + #include <linux/component.h> 16 + #include <linux/mfd/syscon.h> 17 + #include <linux/of_graph.h> 18 + #include <linux/regmap.h> 19 + #include <linux/reset.h> 20 + #include <linux/clk.h> 21 + 22 + #include <drm/drmP.h> 23 + #include <drm/drm_crtc_helper.h> 24 + #include <drm/drm_dp_helper.h> 25 + #include <drm/drm_of.h> 26 + #include <drm/drm_panel.h> 27 + 28 + #include <video/of_videomode.h> 29 + #include <video/videomode.h> 30 + 31 + #include <drm/bridge/analogix_dp.h> 32 + 33 + #include "rockchip_drm_drv.h" 34 + #include "rockchip_drm_vop.h" 35 + 36 + #define to_dp(nm) container_of(nm, struct rockchip_dp_device, nm) 37 + 38 + /* dp grf register offset */ 39 + #define GRF_SOC_CON6 0x025c 40 + #define GRF_EDP_LCD_SEL_MASK BIT(5) 41 + #define GRF_EDP_SEL_VOP_LIT BIT(5) 42 + #define GRF_EDP_SEL_VOP_BIG 0 43 + 44 + struct rockchip_dp_device { 45 + struct drm_device *drm_dev; 46 + struct device *dev; 47 + struct drm_encoder encoder; 48 + struct drm_display_mode mode; 49 + 50 + struct clk *pclk; 51 + struct regmap *grf; 52 + struct reset_control *rst; 53 + 54 + struct analogix_dp_plat_data plat_data; 55 + }; 56 + 57 + static int rockchip_dp_pre_init(struct rockchip_dp_device *dp) 58 + { 59 + reset_control_assert(dp->rst); 60 + usleep_range(10, 20); 61 + reset_control_deassert(dp->rst); 62 + 63 + return 0; 64 + } 65 + 66 + static int rockchip_dp_poweron(struct analogix_dp_plat_data *plat_data) 67 + { 68 + struct rockchip_dp_device *dp = to_dp(plat_data); 69 + int ret; 70 + 71 + ret = clk_prepare_enable(dp->pclk); 72 + if (ret < 0) { 73 + dev_err(dp->dev, "failed to enable pclk %d\n", ret); 74 + return ret; 75 + } 76 + 77 + ret = rockchip_dp_pre_init(dp); 78 + if (ret < 0) { 79 + dev_err(dp->dev, "failed to dp pre init %d\n", ret); 80 + return ret; 81 + } 82 + 83 + return 0; 84 + } 85 + 86 + static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data) 87 + { 88 + struct rockchip_dp_device *dp = to_dp(plat_data); 89 + 90 + clk_disable_unprepare(dp->pclk); 91 + 92 + return 0; 93 + } 94 + 95 + static bool 96 + rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder, 97 + const struct drm_display_mode *mode, 98 + struct drm_display_mode *adjusted_mode) 99 + { 100 + /* do nothing */ 101 + return true; 102 + } 103 + 104 + static void rockchip_dp_drm_encoder_mode_set(struct drm_encoder *encoder, 105 + struct drm_display_mode *mode, 106 + struct drm_display_mode *adjusted) 107 + { 108 + /* do nothing */ 109 + } 110 + 111 + static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder) 112 + { 113 + struct rockchip_dp_device *dp = to_dp(encoder); 114 + int ret; 115 + u32 val; 116 + 117 + /* 118 + * FIXME(Yakir): driver should configure the CRTC output video 119 + * mode with the display information which indicated the monitor 120 + * support colorimetry. 121 + * 122 + * But don't know why the CRTC driver seems could only output the 123 + * RGBaaa rightly. For example, if connect the "innolux,n116bge" 124 + * eDP screen, EDID would indicated that screen only accepted the 125 + * 6bpc mode. But if I configure CRTC to RGB666 output, then eDP 126 + * screen would show a blue picture (RGB888 show a green picture). 127 + * But if I configure CTRC to RGBaaa, and eDP driver still keep 128 + * RGB666 input video mode, then screen would works prefect. 129 + */ 130 + ret = rockchip_drm_crtc_mode_config(encoder->crtc, 131 + DRM_MODE_CONNECTOR_eDP, 132 + ROCKCHIP_OUT_MODE_AAAA); 133 + if (ret < 0) { 134 + dev_err(dp->dev, "Could not set crtc mode config (%d)\n", ret); 135 + return; 136 + } 137 + 138 + ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node, encoder); 139 + if (ret < 0) 140 + return; 141 + 142 + if (ret) 143 + val = GRF_EDP_SEL_VOP_LIT | (GRF_EDP_LCD_SEL_MASK << 16); 144 + else 145 + val = GRF_EDP_SEL_VOP_BIG | (GRF_EDP_LCD_SEL_MASK << 16); 146 + 147 + dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG"); 148 + 149 + ret = regmap_write(dp->grf, GRF_SOC_CON6, val); 150 + if (ret != 0) { 151 + dev_err(dp->dev, "Could not write to GRF: %d\n", ret); 152 + return; 153 + } 154 + } 155 + 156 + static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder) 157 + { 158 + /* do nothing */ 159 + } 160 + 161 + static struct drm_encoder_helper_funcs rockchip_dp_encoder_helper_funcs = { 162 + .mode_fixup = rockchip_dp_drm_encoder_mode_fixup, 163 + .mode_set = rockchip_dp_drm_encoder_mode_set, 164 + .enable = rockchip_dp_drm_encoder_enable, 165 + .disable = rockchip_dp_drm_encoder_nop, 166 + }; 167 + 168 + static void rockchip_dp_drm_encoder_destroy(struct drm_encoder *encoder) 169 + { 170 + drm_encoder_cleanup(encoder); 171 + } 172 + 173 + static struct drm_encoder_funcs rockchip_dp_encoder_funcs = { 174 + .destroy = rockchip_dp_drm_encoder_destroy, 175 + }; 176 + 177 + static int rockchip_dp_init(struct rockchip_dp_device *dp) 178 + { 179 + struct device *dev = dp->dev; 180 + struct device_node *np = dev->of_node; 181 + int ret; 182 + 183 + dp->grf = syscon_regmap_lookup_by_phandle(np, "rockchip,grf"); 184 + if (IS_ERR(dp->grf)) { 185 + dev_err(dev, "failed to get rockchip,grf property\n"); 186 + return PTR_ERR(dp->grf); 187 + } 188 + 189 + dp->pclk = devm_clk_get(dev, "pclk"); 190 + if (IS_ERR(dp->pclk)) { 191 + dev_err(dev, "failed to get pclk property\n"); 192 + return PTR_ERR(dp->pclk); 193 + } 194 + 195 + dp->rst = devm_reset_control_get(dev, "dp"); 196 + if (IS_ERR(dp->rst)) { 197 + dev_err(dev, "failed to get dp reset control\n"); 198 + return PTR_ERR(dp->rst); 199 + } 200 + 201 + ret = clk_prepare_enable(dp->pclk); 202 + if (ret < 0) { 203 + dev_err(dp->dev, "failed to enable pclk %d\n", ret); 204 + return ret; 205 + } 206 + 207 + ret = rockchip_dp_pre_init(dp); 208 + if (ret < 0) { 209 + dev_err(dp->dev, "failed to pre init %d\n", ret); 210 + return ret; 211 + } 212 + 213 + return 0; 214 + } 215 + 216 + static int rockchip_dp_drm_create_encoder(struct rockchip_dp_device *dp) 217 + { 218 + struct drm_encoder *encoder = &dp->encoder; 219 + struct drm_device *drm_dev = dp->drm_dev; 220 + struct device *dev = dp->dev; 221 + int ret; 222 + 223 + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev, 224 + dev->of_node); 225 + DRM_DEBUG_KMS("possible_crtcs = 0x%x\n", encoder->possible_crtcs); 226 + 227 + ret = drm_encoder_init(drm_dev, encoder, &rockchip_dp_encoder_funcs, 228 + DRM_MODE_ENCODER_TMDS, NULL); 229 + if (ret) { 230 + DRM_ERROR("failed to initialize encoder with drm\n"); 231 + return ret; 232 + } 233 + 234 + drm_encoder_helper_add(encoder, &rockchip_dp_encoder_helper_funcs); 235 + 236 + return 0; 237 + } 238 + 239 + static int rockchip_dp_bind(struct device *dev, struct device *master, 240 + void *data) 241 + { 242 + struct rockchip_dp_device *dp = dev_get_drvdata(dev); 243 + struct drm_device *drm_dev = data; 244 + int ret; 245 + 246 + /* 247 + * Just like the probe function said, we don't need the 248 + * device drvrate anymore, we should leave the charge to 249 + * analogix dp driver, set the device drvdata to NULL. 250 + */ 251 + dev_set_drvdata(dev, NULL); 252 + 253 + ret = rockchip_dp_init(dp); 254 + if (ret < 0) 255 + return ret; 256 + 257 + dp->drm_dev = drm_dev; 258 + 259 + ret = rockchip_dp_drm_create_encoder(dp); 260 + if (ret) { 261 + DRM_ERROR("failed to create drm encoder\n"); 262 + return ret; 263 + } 264 + 265 + dp->plat_data.encoder = &dp->encoder; 266 + 267 + dp->plat_data.dev_type = RK3288_DP; 268 + dp->plat_data.power_on = rockchip_dp_poweron; 269 + dp->plat_data.power_off = rockchip_dp_powerdown; 270 + 271 + return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data); 272 + } 273 + 274 + static void rockchip_dp_unbind(struct device *dev, struct device *master, 275 + void *data) 276 + { 277 + return analogix_dp_unbind(dev, master, data); 278 + } 279 + 280 + static const struct component_ops rockchip_dp_component_ops = { 281 + .bind = rockchip_dp_bind, 282 + .unbind = rockchip_dp_unbind, 283 + }; 284 + 285 + static int rockchip_dp_probe(struct platform_device *pdev) 286 + { 287 + struct device *dev = &pdev->dev; 288 + struct device_node *panel_node, *port, *endpoint; 289 + struct rockchip_dp_device *dp; 290 + struct drm_panel *panel; 291 + 292 + port = of_graph_get_port_by_id(dev->of_node, 1); 293 + if (!port) { 294 + dev_err(dev, "can't find output port\n"); 295 + return -EINVAL; 296 + } 297 + 298 + endpoint = of_get_child_by_name(port, "endpoint"); 299 + of_node_put(port); 300 + if (!endpoint) { 301 + dev_err(dev, "no output endpoint found\n"); 302 + return -EINVAL; 303 + } 304 + 305 + panel_node = of_graph_get_remote_port_parent(endpoint); 306 + of_node_put(endpoint); 307 + if (!panel_node) { 308 + dev_err(dev, "no output node found\n"); 309 + return -EINVAL; 310 + } 311 + 312 + panel = of_drm_find_panel(panel_node); 313 + if (!panel) { 314 + DRM_ERROR("failed to find panel\n"); 315 + of_node_put(panel_node); 316 + return -EPROBE_DEFER; 317 + } 318 + 319 + of_node_put(panel_node); 320 + 321 + dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); 322 + if (!dp) 323 + return -ENOMEM; 324 + 325 + dp->dev = dev; 326 + 327 + dp->plat_data.panel = panel; 328 + 329 + /* 330 + * We just use the drvdata until driver run into component 331 + * add function, and then we would set drvdata to null, so 332 + * that analogix dp driver could take charge of the drvdata. 333 + */ 334 + platform_set_drvdata(pdev, dp); 335 + 336 + return component_add(dev, &rockchip_dp_component_ops); 337 + } 338 + 339 + static int rockchip_dp_remove(struct platform_device *pdev) 340 + { 341 + component_del(&pdev->dev, &rockchip_dp_component_ops); 342 + 343 + return 0; 344 + } 345 + 346 + #ifdef CONFIG_PM_SLEEP 347 + static int rockchip_dp_suspend(struct device *dev) 348 + { 349 + return analogix_dp_suspend(dev); 350 + } 351 + 352 + static int rockchip_dp_resume(struct device *dev) 353 + { 354 + return analogix_dp_resume(dev); 355 + } 356 + #endif 357 + 358 + static const struct dev_pm_ops rockchip_dp_pm_ops = { 359 + SET_SYSTEM_SLEEP_PM_OPS(rockchip_dp_suspend, rockchip_dp_resume) 360 + }; 361 + 362 + static const struct of_device_id rockchip_dp_dt_ids[] = { 363 + {.compatible = "rockchip,rk3288-dp",}, 364 + {} 365 + }; 366 + MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids); 367 + 368 + static struct platform_driver rockchip_dp_driver = { 369 + .probe = rockchip_dp_probe, 370 + .remove = rockchip_dp_remove, 371 + .driver = { 372 + .name = "rockchip-dp", 373 + .owner = THIS_MODULE, 374 + .pm = &rockchip_dp_pm_ops, 375 + .of_match_table = of_match_ptr(rockchip_dp_dt_ids), 376 + }, 377 + }; 378 + 379 + module_platform_driver(rockchip_dp_driver); 380 + 381 + MODULE_AUTHOR("Yakir Yang <ykk@rock-chips.com>"); 382 + MODULE_AUTHOR("Jeff chen <jeff.chen@rock-chips.com>"); 383 + MODULE_DESCRIPTION("Rockchip Specific Analogix-DP Driver Extension"); 384 + MODULE_LICENSE("GPL v2");
+41
include/drm/bridge/analogix_dp.h
··· 1 + /* 2 + * Analogix DP (Display Port) Core interface driver. 3 + * 4 + * Copyright (C) 2015 Rockchip Electronics Co., Ltd. 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License as published by the 8 + * Free Software Foundation; either version 2 of the License, or (at your 9 + * option) any later version. 10 + */ 11 + #ifndef _ANALOGIX_DP_H_ 12 + #define _ANALOGIX_DP_H_ 13 + 14 + #include <drm/drm_crtc.h> 15 + 16 + enum analogix_dp_devtype { 17 + EXYNOS_DP, 18 + RK3288_DP, 19 + }; 20 + 21 + struct analogix_dp_plat_data { 22 + enum analogix_dp_devtype dev_type; 23 + struct drm_panel *panel; 24 + struct drm_encoder *encoder; 25 + struct drm_connector *connector; 26 + 27 + int (*power_on)(struct analogix_dp_plat_data *); 28 + int (*power_off)(struct analogix_dp_plat_data *); 29 + int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *, 30 + struct drm_connector *); 31 + int (*get_modes)(struct analogix_dp_plat_data *); 32 + }; 33 + 34 + int analogix_dp_resume(struct device *dev); 35 + int analogix_dp_suspend(struct device *dev); 36 + 37 + int analogix_dp_bind(struct device *dev, struct drm_device *drm_dev, 38 + struct analogix_dp_plat_data *plat_data); 39 + void analogix_dp_unbind(struct device *dev, struct device *master, void *data); 40 + 41 + #endif /* _ANALOGIX_DP_H_ */