diff options
53 files changed, 4641 insertions, 722 deletions
diff --git a/Documentation/devicetree/bindings/drm/msm/hdmi.txt b/Documentation/devicetree/bindings/drm/msm/hdmi.txt index aca917fe2ba7..a29a55f3d937 100644 --- a/Documentation/devicetree/bindings/drm/msm/hdmi.txt +++ b/Documentation/devicetree/bindings/drm/msm/hdmi.txt | |||
| @@ -2,6 +2,8 @@ Qualcomm adreno/snapdragon hdmi output | |||
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible: one of the following | 4 | - compatible: one of the following |
| 5 | * "qcom,hdmi-tx-8084" | ||
| 6 | * "qcom,hdmi-tx-8074" | ||
| 5 | * "qcom,hdmi-tx-8660" | 7 | * "qcom,hdmi-tx-8660" |
| 6 | * "qcom,hdmi-tx-8960" | 8 | * "qcom,hdmi-tx-8960" |
| 7 | - reg: Physical base address and length of the controller's registers | 9 | - reg: Physical base address and length of the controller's registers |
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c index 79968e39c8d0..f1283878ff6d 100644 --- a/drivers/gpu/drm/drm_dp_helper.c +++ b/drivers/gpu/drm/drm_dp_helper.c | |||
| @@ -354,6 +354,37 @@ int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link) | |||
| 354 | EXPORT_SYMBOL(drm_dp_link_power_up); | 354 | EXPORT_SYMBOL(drm_dp_link_power_up); |
| 355 | 355 | ||
| 356 | /** | 356 | /** |
| 357 | * drm_dp_link_power_down() - power down a DisplayPort link | ||
| 358 | * @aux: DisplayPort AUX channel | ||
| 359 | * @link: pointer to a structure containing the link configuration | ||
| 360 | * | ||
| 361 | * Returns 0 on success or a negative error code on failure. | ||
| 362 | */ | ||
| 363 | int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link) | ||
| 364 | { | ||
| 365 | u8 value; | ||
| 366 | int err; | ||
| 367 | |||
| 368 | /* DP_SET_POWER register is only available on DPCD v1.1 and later */ | ||
| 369 | if (link->revision < 0x11) | ||
| 370 | return 0; | ||
| 371 | |||
| 372 | err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value); | ||
| 373 | if (err < 0) | ||
| 374 | return err; | ||
| 375 | |||
| 376 | value &= ~DP_SET_POWER_MASK; | ||
| 377 | value |= DP_SET_POWER_D3; | ||
| 378 | |||
| 379 | err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value); | ||
| 380 | if (err < 0) | ||
| 381 | return err; | ||
| 382 | |||
| 383 | return 0; | ||
| 384 | } | ||
| 385 | EXPORT_SYMBOL(drm_dp_link_power_down); | ||
| 386 | |||
| 387 | /** | ||
| 357 | * drm_dp_link_configure() - configure a DisplayPort link | 388 | * drm_dp_link_configure() - configure a DisplayPort link |
| 358 | * @aux: DisplayPort AUX channel | 389 | * @aux: DisplayPort AUX channel |
| 359 | * @link: pointer to a structure containing the link configuration | 390 | * @link: pointer to a structure containing the link configuration |
diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 143d988f8add..674a132fd76e 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile | |||
| @@ -1,7 +1,4 @@ | |||
| 1 | ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/msm | 1 | ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/msm |
| 2 | ifeq (, $(findstring -W,$(EXTRA_CFLAGS))) | ||
| 3 | ccflags-y += -Werror | ||
| 4 | endif | ||
| 5 | 2 | ||
| 6 | msm-y := \ | 3 | msm-y := \ |
| 7 | adreno/adreno_device.o \ | 4 | adreno/adreno_device.o \ |
| @@ -16,6 +13,12 @@ msm-y := \ | |||
| 16 | hdmi/hdmi_phy_8960.o \ | 13 | hdmi/hdmi_phy_8960.o \ |
| 17 | hdmi/hdmi_phy_8x60.o \ | 14 | hdmi/hdmi_phy_8x60.o \ |
| 18 | hdmi/hdmi_phy_8x74.o \ | 15 | hdmi/hdmi_phy_8x74.o \ |
| 16 | edp/edp.o \ | ||
| 17 | edp/edp_aux.o \ | ||
| 18 | edp/edp_bridge.o \ | ||
| 19 | edp/edp_connector.o \ | ||
| 20 | edp/edp_ctrl.o \ | ||
| 21 | edp/edp_phy.o \ | ||
| 19 | mdp/mdp_format.o \ | 22 | mdp/mdp_format.o \ |
| 20 | mdp/mdp_kms.o \ | 23 | mdp/mdp_kms.o \ |
| 21 | mdp/mdp4/mdp4_crtc.o \ | 24 | mdp/mdp4/mdp4_crtc.o \ |
diff --git a/drivers/gpu/drm/msm/adreno/a2xx.xml.h b/drivers/gpu/drm/msm/adreno/a2xx.xml.h index 22882cc0a573..edc845fffdf4 100644 --- a/drivers/gpu/drm/msm/adreno/a2xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a2xx.xml.h | |||
| @@ -12,9 +12,9 @@ The rules-ng-ng source files this header was generated from are: | |||
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15085 bytes, from 2014-12-20 21:49:41) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 64344 bytes, from 2014-12-12 20:22:26) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 51069 bytes, from 2014-12-21 15:51:54) |
| 18 | 18 | ||
| 19 | Copyright (C) 2013-2014 by the following authors: | 19 | Copyright (C) 2013-2014 by the following authors: |
| 20 | - Rob Clark <robdclark@gmail.com> (robclark) | 20 | - Rob Clark <robdclark@gmail.com> (robclark) |
diff --git a/drivers/gpu/drm/msm/adreno/a3xx.xml.h b/drivers/gpu/drm/msm/adreno/a3xx.xml.h index 109e9a263daf..e91a739452d7 100644 --- a/drivers/gpu/drm/msm/adreno/a3xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a3xx.xml.h | |||
| @@ -12,9 +12,9 @@ The rules-ng-ng source files this header was generated from are: | |||
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15085 bytes, from 2014-12-20 21:49:41) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 64344 bytes, from 2014-12-12 20:22:26) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 51069 bytes, from 2014-12-21 15:51:54) |
| 18 | 18 | ||
| 19 | Copyright (C) 2013-2014 by the following authors: | 19 | Copyright (C) 2013-2014 by the following authors: |
| 20 | - Rob Clark <robdclark@gmail.com> (robclark) | 20 | - Rob Clark <robdclark@gmail.com> (robclark) |
| @@ -58,111 +58,130 @@ enum a3xx_cache_opcode { | |||
| 58 | }; | 58 | }; |
| 59 | 59 | ||
| 60 | enum a3xx_vtx_fmt { | 60 | enum a3xx_vtx_fmt { |
| 61 | VFMT_FLOAT_32 = 0, | 61 | VFMT_32_FLOAT = 0, |
| 62 | VFMT_FLOAT_32_32 = 1, | 62 | VFMT_32_32_FLOAT = 1, |
| 63 | VFMT_FLOAT_32_32_32 = 2, | 63 | VFMT_32_32_32_FLOAT = 2, |
| 64 | VFMT_FLOAT_32_32_32_32 = 3, | 64 | VFMT_32_32_32_32_FLOAT = 3, |
| 65 | VFMT_FLOAT_16 = 4, | 65 | VFMT_16_FLOAT = 4, |
| 66 | VFMT_FLOAT_16_16 = 5, | 66 | VFMT_16_16_FLOAT = 5, |
| 67 | VFMT_FLOAT_16_16_16 = 6, | 67 | VFMT_16_16_16_FLOAT = 6, |
| 68 | VFMT_FLOAT_16_16_16_16 = 7, | 68 | VFMT_16_16_16_16_FLOAT = 7, |
| 69 | VFMT_FIXED_32 = 8, | 69 | VFMT_32_FIXED = 8, |
| 70 | VFMT_FIXED_32_32 = 9, | 70 | VFMT_32_32_FIXED = 9, |
| 71 | VFMT_FIXED_32_32_32 = 10, | 71 | VFMT_32_32_32_FIXED = 10, |
| 72 | VFMT_FIXED_32_32_32_32 = 11, | 72 | VFMT_32_32_32_32_FIXED = 11, |
| 73 | VFMT_SHORT_16 = 16, | 73 | VFMT_16_SINT = 16, |
| 74 | VFMT_SHORT_16_16 = 17, | 74 | VFMT_16_16_SINT = 17, |
| 75 | VFMT_SHORT_16_16_16 = 18, | 75 | VFMT_16_16_16_SINT = 18, |
| 76 | VFMT_SHORT_16_16_16_16 = 19, | 76 | VFMT_16_16_16_16_SINT = 19, |
| 77 | VFMT_USHORT_16 = 20, | 77 | VFMT_16_UINT = 20, |
| 78 | VFMT_USHORT_16_16 = 21, | 78 | VFMT_16_16_UINT = 21, |
| 79 | VFMT_USHORT_16_16_16 = 22, | 79 | VFMT_16_16_16_UINT = 22, |
| 80 | VFMT_USHORT_16_16_16_16 = 23, | 80 | VFMT_16_16_16_16_UINT = 23, |
| 81 | VFMT_NORM_SHORT_16 = 24, | 81 | VFMT_16_SNORM = 24, |
| 82 | VFMT_NORM_SHORT_16_16 = 25, | 82 | VFMT_16_16_SNORM = 25, |
| 83 | VFMT_NORM_SHORT_16_16_16 = 26, | 83 | VFMT_16_16_16_SNORM = 26, |
| 84 | VFMT_NORM_SHORT_16_16_16_16 = 27, | 84 | VFMT_16_16_16_16_SNORM = 27, |
| 85 | VFMT_NORM_USHORT_16 = 28, | 85 | VFMT_16_UNORM = 28, |
| 86 | VFMT_NORM_USHORT_16_16 = 29, | 86 | VFMT_16_16_UNORM = 29, |
| 87 | VFMT_NORM_USHORT_16_16_16 = 30, | 87 | VFMT_16_16_16_UNORM = 30, |
| 88 | VFMT_NORM_USHORT_16_16_16_16 = 31, | 88 | VFMT_16_16_16_16_UNORM = 31, |
| 89 | VFMT_UINT_32 = 32, | 89 | VFMT_32_UINT = 32, |
| 90 | VFMT_UINT_32_32 = 33, | 90 | VFMT_32_32_UINT = 33, |
| 91 | VFMT_UINT_32_32_32 = 34, | 91 | VFMT_32_32_32_UINT = 34, |
| 92 | VFMT_UINT_32_32_32_32 = 35, | 92 | VFMT_32_32_32_32_UINT = 35, |
| 93 | VFMT_INT_32 = 36, | 93 | VFMT_32_SINT = 36, |
| 94 | VFMT_INT_32_32 = 37, | 94 | VFMT_32_32_SINT = 37, |
| 95 | VFMT_INT_32_32_32 = 38, | 95 | VFMT_32_32_32_SINT = 38, |
| 96 | VFMT_INT_32_32_32_32 = 39, | 96 | VFMT_32_32_32_32_SINT = 39, |
| 97 | VFMT_UBYTE_8 = 40, | 97 | VFMT_8_UINT = 40, |
| 98 | VFMT_UBYTE_8_8 = 41, | 98 | VFMT_8_8_UINT = 41, |
| 99 | VFMT_UBYTE_8_8_8 = 42, | 99 | VFMT_8_8_8_UINT = 42, |
| 100 | VFMT_UBYTE_8_8_8_8 = 43, | 100 | VFMT_8_8_8_8_UINT = 43, |
| 101 | VFMT_NORM_UBYTE_8 = 44, | 101 | VFMT_8_UNORM = 44, |
| 102 | VFMT_NORM_UBYTE_8_8 = 45, | 102 | VFMT_8_8_UNORM = 45, |
| 103 | VFMT_NORM_UBYTE_8_8_8 = 46, | 103 | VFMT_8_8_8_UNORM = 46, |
| 104 | VFMT_NORM_UBYTE_8_8_8_8 = 47, | 104 | VFMT_8_8_8_8_UNORM = 47, |
| 105 | VFMT_BYTE_8 = 48, | 105 | VFMT_8_SINT = 48, |
| 106 | VFMT_BYTE_8_8 = 49, | 106 | VFMT_8_8_SINT = 49, |
| 107 | VFMT_BYTE_8_8_8 = 50, | 107 | VFMT_8_8_8_SINT = 50, |
| 108 | VFMT_BYTE_8_8_8_8 = 51, | 108 | VFMT_8_8_8_8_SINT = 51, |
| 109 | VFMT_NORM_BYTE_8 = 52, | 109 | VFMT_8_SNORM = 52, |
| 110 | VFMT_NORM_BYTE_8_8 = 53, | 110 | VFMT_8_8_SNORM = 53, |
| 111 | VFMT_NORM_BYTE_8_8_8 = 54, | 111 | VFMT_8_8_8_SNORM = 54, |
| 112 | VFMT_NORM_BYTE_8_8_8_8 = 55, | 112 | VFMT_8_8_8_8_SNORM = 55, |
| 113 | VFMT_UINT_10_10_10_2 = 60, | 113 | VFMT_10_10_10_2_UINT = 60, |
| 114 | VFMT_NORM_UINT_10_10_10_2 = 61, | 114 | VFMT_10_10_10_2_UNORM = 61, |
| 115 | VFMT_INT_10_10_10_2 = 62, | 115 | VFMT_10_10_10_2_SINT = 62, |
| 116 | VFMT_NORM_INT_10_10_10_2 = 63, | 116 | VFMT_10_10_10_2_SNORM = 63, |
| 117 | }; | 117 | }; |
| 118 | 118 | ||
| 119 | enum a3xx_tex_fmt { | 119 | enum a3xx_tex_fmt { |
| 120 | TFMT_NORM_USHORT_565 = 4, | 120 | TFMT_5_6_5_UNORM = 4, |
| 121 | TFMT_NORM_USHORT_5551 = 6, | 121 | TFMT_5_5_5_1_UNORM = 5, |
| 122 | TFMT_NORM_USHORT_4444 = 7, | 122 | TFMT_4_4_4_4_UNORM = 7, |
| 123 | TFMT_NORM_USHORT_Z16 = 9, | 123 | TFMT_Z16_UNORM = 9, |
| 124 | TFMT_NORM_UINT_X8Z24 = 10, | 124 | TFMT_X8Z24_UNORM = 10, |
| 125 | TFMT_FLOAT_Z32 = 11, | 125 | TFMT_Z32_FLOAT = 11, |
| 126 | TFMT_NORM_UINT_NV12_UV_TILED = 17, | 126 | TFMT_NV12_UV_TILED = 17, |
| 127 | TFMT_NORM_UINT_NV12_Y_TILED = 19, | 127 | TFMT_NV12_Y_TILED = 19, |
| 128 | TFMT_NORM_UINT_NV12_UV = 21, | 128 | TFMT_NV12_UV = 21, |
| 129 | TFMT_NORM_UINT_NV12_Y = 23, | 129 | TFMT_NV12_Y = 23, |
| 130 | TFMT_NORM_UINT_I420_Y = 24, | 130 | TFMT_I420_Y = 24, |
| 131 | TFMT_NORM_UINT_I420_U = 26, | 131 | TFMT_I420_U = 26, |
| 132 | TFMT_NORM_UINT_I420_V = 27, | 132 | TFMT_I420_V = 27, |
| 133 | TFMT_NORM_UINT_2_10_10_10 = 41, | 133 | TFMT_DXT1 = 36, |
| 134 | TFMT_FLOAT_9_9_9_E5 = 42, | 134 | TFMT_DXT3 = 37, |
| 135 | TFMT_FLOAT_10_11_11 = 43, | 135 | TFMT_DXT5 = 38, |
| 136 | TFMT_NORM_UINT_A8 = 44, | 136 | TFMT_10_10_10_2_UNORM = 41, |
| 137 | TFMT_NORM_UINT_L8_A8 = 47, | 137 | TFMT_9_9_9_E5_FLOAT = 42, |
| 138 | TFMT_NORM_UINT_8 = 48, | 138 | TFMT_11_11_10_FLOAT = 43, |
| 139 | TFMT_NORM_UINT_8_8 = 49, | 139 | TFMT_A8_UNORM = 44, |
| 140 | TFMT_NORM_UINT_8_8_8 = 50, | 140 | TFMT_L8_A8_UNORM = 47, |
| 141 | TFMT_NORM_UINT_8_8_8_8 = 51, | 141 | TFMT_8_UNORM = 48, |
| 142 | TFMT_NORM_SINT_8_8 = 53, | 142 | TFMT_8_8_UNORM = 49, |
| 143 | TFMT_NORM_SINT_8_8_8_8 = 55, | 143 | TFMT_8_8_8_UNORM = 50, |
| 144 | TFMT_UINT_8_8 = 57, | 144 | TFMT_8_8_8_8_UNORM = 51, |
| 145 | TFMT_UINT_8_8_8_8 = 59, | 145 | TFMT_8_SNORM = 52, |
| 146 | TFMT_SINT_8_8 = 61, | 146 | TFMT_8_8_SNORM = 53, |
| 147 | TFMT_SINT_8_8_8_8 = 63, | 147 | TFMT_8_8_8_SNORM = 54, |
| 148 | TFMT_FLOAT_16 = 64, | 148 | TFMT_8_8_8_8_SNORM = 55, |
| 149 | TFMT_FLOAT_16_16 = 65, | 149 | TFMT_8_UINT = 56, |
| 150 | TFMT_FLOAT_16_16_16_16 = 67, | 150 | TFMT_8_8_UINT = 57, |
| 151 | TFMT_UINT_16 = 68, | 151 | TFMT_8_8_8_UINT = 58, |
| 152 | TFMT_UINT_16_16 = 69, | 152 | TFMT_8_8_8_8_UINT = 59, |
| 153 | TFMT_UINT_16_16_16_16 = 71, | 153 | TFMT_8_SINT = 60, |
| 154 | TFMT_SINT_16 = 72, | 154 | TFMT_8_8_SINT = 61, |
| 155 | TFMT_SINT_16_16 = 73, | 155 | TFMT_8_8_8_SINT = 62, |
| 156 | TFMT_SINT_16_16_16_16 = 75, | 156 | TFMT_8_8_8_8_SINT = 63, |
| 157 | TFMT_FLOAT_32 = 84, | 157 | TFMT_16_FLOAT = 64, |
| 158 | TFMT_FLOAT_32_32 = 85, | 158 | TFMT_16_16_FLOAT = 65, |
| 159 | TFMT_FLOAT_32_32_32_32 = 87, | 159 | TFMT_16_16_16_16_FLOAT = 67, |
| 160 | TFMT_UINT_32 = 88, | 160 | TFMT_16_UINT = 68, |
| 161 | TFMT_UINT_32_32 = 89, | 161 | TFMT_16_16_UINT = 69, |
| 162 | TFMT_UINT_32_32_32_32 = 91, | 162 | TFMT_16_16_16_16_UINT = 71, |
| 163 | TFMT_SINT_32 = 92, | 163 | TFMT_16_SINT = 72, |
| 164 | TFMT_SINT_32_32 = 93, | 164 | TFMT_16_16_SINT = 73, |
| 165 | TFMT_SINT_32_32_32_32 = 95, | 165 | TFMT_16_16_16_16_SINT = 75, |
| 166 | TFMT_16_UNORM = 76, | ||
| 167 | TFMT_16_16_UNORM = 77, | ||
| 168 | TFMT_16_16_16_16_UNORM = 79, | ||
| 169 | TFMT_16_SNORM = 80, | ||
| 170 | TFMT_16_16_SNORM = 81, | ||
| 171 | TFMT_16_16_16_16_SNORM = 83, | ||
| 172 | TFMT_32_FLOAT = 84, | ||
| 173 | TFMT_32_32_FLOAT = 85, | ||
| 174 | TFMT_32_32_32_32_FLOAT = 87, | ||
| 175 | TFMT_32_UINT = 88, | ||
| 176 | TFMT_32_32_UINT = 89, | ||
| 177 | TFMT_32_32_32_32_UINT = 91, | ||
| 178 | TFMT_32_SINT = 92, | ||
| 179 | TFMT_32_32_SINT = 93, | ||
| 180 | TFMT_32_32_32_32_SINT = 95, | ||
| 181 | TFMT_RGTC2_SNORM = 112, | ||
| 182 | TFMT_RGTC2_UNORM = 113, | ||
| 183 | TFMT_RGTC1_SNORM = 114, | ||
| 184 | TFMT_RGTC1_UNORM = 115, | ||
| 166 | }; | 185 | }; |
| 167 | 186 | ||
| 168 | enum a3xx_tex_fetchsize { | 187 | enum a3xx_tex_fetchsize { |
| @@ -180,9 +199,11 @@ enum a3xx_color_fmt { | |||
| 180 | RB_R4G4B4A4_UNORM = 3, | 199 | RB_R4G4B4A4_UNORM = 3, |
| 181 | RB_R8G8B8_UNORM = 4, | 200 | RB_R8G8B8_UNORM = 4, |
| 182 | RB_R8G8B8A8_UNORM = 8, | 201 | RB_R8G8B8A8_UNORM = 8, |
| 202 | RB_R8G8B8A8_SNORM = 9, | ||
| 183 | RB_R8G8B8A8_UINT = 10, | 203 | RB_R8G8B8A8_UINT = 10, |
| 184 | RB_R8G8B8A8_SINT = 11, | 204 | RB_R8G8B8A8_SINT = 11, |
| 185 | RB_R8G8_UNORM = 12, | 205 | RB_R8G8_UNORM = 12, |
| 206 | RB_R8G8_SNORM = 13, | ||
| 186 | RB_R8_UINT = 14, | 207 | RB_R8_UINT = 14, |
| 187 | RB_R8_SINT = 15, | 208 | RB_R8_SINT = 15, |
| 188 | RB_R10G10B10A2_UNORM = 16, | 209 | RB_R10G10B10A2_UNORM = 16, |
| @@ -258,6 +279,14 @@ enum a3xx_tex_clamp { | |||
| 258 | A3XX_TEX_MIRROR_CLAMP = 4, | 279 | A3XX_TEX_MIRROR_CLAMP = 4, |
| 259 | }; | 280 | }; |
| 260 | 281 | ||
| 282 | enum a3xx_tex_aniso { | ||
| 283 | A3XX_TEX_ANISO_1 = 0, | ||
| 284 | A3XX_TEX_ANISO_2 = 1, | ||
| 285 | A3XX_TEX_ANISO_4 = 2, | ||
| 286 | A3XX_TEX_ANISO_8 = 3, | ||
| 287 | A3XX_TEX_ANISO_16 = 4, | ||
| 288 | }; | ||
| 289 | |||
| 261 | enum a3xx_tex_swiz { | 290 | enum a3xx_tex_swiz { |
| 262 | A3XX_TEX_X = 0, | 291 | A3XX_TEX_X = 0, |
| 263 | A3XX_TEX_Y = 1, | 292 | A3XX_TEX_Y = 1, |
| @@ -1563,12 +1592,13 @@ static inline uint32_t A3XX_VFD_FETCH_INSTR_0_FETCHSIZE(uint32_t val) | |||
| 1563 | { | 1592 | { |
| 1564 | return ((val) << A3XX_VFD_FETCH_INSTR_0_FETCHSIZE__SHIFT) & A3XX_VFD_FETCH_INSTR_0_FETCHSIZE__MASK; | 1593 | return ((val) << A3XX_VFD_FETCH_INSTR_0_FETCHSIZE__SHIFT) & A3XX_VFD_FETCH_INSTR_0_FETCHSIZE__MASK; |
| 1565 | } | 1594 | } |
| 1566 | #define A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK 0x0001ff80 | 1595 | #define A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK 0x0000ff80 |
| 1567 | #define A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT 7 | 1596 | #define A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT 7 |
| 1568 | static inline uint32_t A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(uint32_t val) | 1597 | static inline uint32_t A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE(uint32_t val) |
| 1569 | { | 1598 | { |
| 1570 | return ((val) << A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT) & A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK; | 1599 | return ((val) << A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT) & A3XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK; |
| 1571 | } | 1600 | } |
| 1601 | #define A3XX_VFD_FETCH_INSTR_0_INSTANCED 0x00010000 | ||
| 1572 | #define A3XX_VFD_FETCH_INSTR_0_SWITCHNEXT 0x00020000 | 1602 | #define A3XX_VFD_FETCH_INSTR_0_SWITCHNEXT 0x00020000 |
| 1573 | #define A3XX_VFD_FETCH_INSTR_0_INDEXCODE__MASK 0x00fc0000 | 1603 | #define A3XX_VFD_FETCH_INSTR_0_INDEXCODE__MASK 0x00fc0000 |
| 1574 | #define A3XX_VFD_FETCH_INSTR_0_INDEXCODE__SHIFT 18 | 1604 | #define A3XX_VFD_FETCH_INSTR_0_INDEXCODE__SHIFT 18 |
| @@ -2509,6 +2539,12 @@ static inline uint32_t A3XX_TEX_SAMP_0_WRAP_R(enum a3xx_tex_clamp val) | |||
| 2509 | { | 2539 | { |
| 2510 | return ((val) << A3XX_TEX_SAMP_0_WRAP_R__SHIFT) & A3XX_TEX_SAMP_0_WRAP_R__MASK; | 2540 | return ((val) << A3XX_TEX_SAMP_0_WRAP_R__SHIFT) & A3XX_TEX_SAMP_0_WRAP_R__MASK; |
| 2511 | } | 2541 | } |
| 2542 | #define A3XX_TEX_SAMP_0_ANISO__MASK 0x00038000 | ||
| 2543 | #define A3XX_TEX_SAMP_0_ANISO__SHIFT 15 | ||
| 2544 | static inline uint32_t A3XX_TEX_SAMP_0_ANISO(enum a3xx_tex_aniso val) | ||
| 2545 | { | ||
| 2546 | return ((val) << A3XX_TEX_SAMP_0_ANISO__SHIFT) & A3XX_TEX_SAMP_0_ANISO__MASK; | ||
| 2547 | } | ||
| 2512 | #define A3XX_TEX_SAMP_0_COMPARE_FUNC__MASK 0x00700000 | 2548 | #define A3XX_TEX_SAMP_0_COMPARE_FUNC__MASK 0x00700000 |
| 2513 | #define A3XX_TEX_SAMP_0_COMPARE_FUNC__SHIFT 20 | 2549 | #define A3XX_TEX_SAMP_0_COMPARE_FUNC__SHIFT 20 |
| 2514 | static inline uint32_t A3XX_TEX_SAMP_0_COMPARE_FUNC(enum adreno_compare_func val) | 2550 | static inline uint32_t A3XX_TEX_SAMP_0_COMPARE_FUNC(enum adreno_compare_func val) |
diff --git a/drivers/gpu/drm/msm/adreno/a4xx.xml.h b/drivers/gpu/drm/msm/adreno/a4xx.xml.h index 5a24c416d2dd..755723fd8ba5 100644 --- a/drivers/gpu/drm/msm/adreno/a4xx.xml.h +++ b/drivers/gpu/drm/msm/adreno/a4xx.xml.h | |||
| @@ -12,9 +12,9 @@ The rules-ng-ng source files this header was generated from are: | |||
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15085 bytes, from 2014-12-20 21:49:41) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 64344 bytes, from 2014-12-12 20:22:26) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 51069 bytes, from 2014-12-21 15:51:54) |
| 18 | 18 | ||
| 19 | Copyright (C) 2013-2014 by the following authors: | 19 | Copyright (C) 2013-2014 by the following authors: |
| 20 | - Rob Clark <robdclark@gmail.com> (robclark) | 20 | - Rob Clark <robdclark@gmail.com> (robclark) |
| @@ -63,72 +63,82 @@ enum a4xx_rb_blend_opcode { | |||
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | enum a4xx_vtx_fmt { | 65 | enum a4xx_vtx_fmt { |
| 66 | VFMT4_FLOAT_32 = 1, | 66 | VFMT4_32_FLOAT = 1, |
| 67 | VFMT4_FLOAT_32_32 = 2, | 67 | VFMT4_32_32_FLOAT = 2, |
| 68 | VFMT4_FLOAT_32_32_32 = 3, | 68 | VFMT4_32_32_32_FLOAT = 3, |
| 69 | VFMT4_FLOAT_32_32_32_32 = 4, | 69 | VFMT4_32_32_32_32_FLOAT = 4, |
| 70 | VFMT4_FLOAT_16 = 5, | 70 | VFMT4_16_FLOAT = 5, |
| 71 | VFMT4_FLOAT_16_16 = 6, | 71 | VFMT4_16_16_FLOAT = 6, |
| 72 | VFMT4_FLOAT_16_16_16 = 7, | 72 | VFMT4_16_16_16_FLOAT = 7, |
| 73 | VFMT4_FLOAT_16_16_16_16 = 8, | 73 | VFMT4_16_16_16_16_FLOAT = 8, |
| 74 | VFMT4_FIXED_32 = 9, | 74 | VFMT4_32_FIXED = 9, |
| 75 | VFMT4_FIXED_32_32 = 10, | 75 | VFMT4_32_32_FIXED = 10, |
| 76 | VFMT4_FIXED_32_32_32 = 11, | 76 | VFMT4_32_32_32_FIXED = 11, |
| 77 | VFMT4_FIXED_32_32_32_32 = 12, | 77 | VFMT4_32_32_32_32_FIXED = 12, |
| 78 | VFMT4_SHORT_16 = 16, | 78 | VFMT4_16_SINT = 16, |
| 79 | VFMT4_SHORT_16_16 = 17, | 79 | VFMT4_16_16_SINT = 17, |
| 80 | VFMT4_SHORT_16_16_16 = 18, | 80 | VFMT4_16_16_16_SINT = 18, |
| 81 | VFMT4_SHORT_16_16_16_16 = 19, | 81 | VFMT4_16_16_16_16_SINT = 19, |
| 82 | VFMT4_USHORT_16 = 20, | 82 | VFMT4_16_UINT = 20, |
| 83 | VFMT4_USHORT_16_16 = 21, | 83 | VFMT4_16_16_UINT = 21, |
| 84 | VFMT4_USHORT_16_16_16 = 22, | 84 | VFMT4_16_16_16_UINT = 22, |
| 85 | VFMT4_USHORT_16_16_16_16 = 23, | 85 | VFMT4_16_16_16_16_UINT = 23, |
| 86 | VFMT4_NORM_SHORT_16 = 24, | 86 | VFMT4_16_SNORM = 24, |
| 87 | VFMT4_NORM_SHORT_16_16 = 25, | 87 | VFMT4_16_16_SNORM = 25, |
| 88 | VFMT4_NORM_SHORT_16_16_16 = 26, | 88 | VFMT4_16_16_16_SNORM = 26, |
| 89 | VFMT4_NORM_SHORT_16_16_16_16 = 27, | 89 | VFMT4_16_16_16_16_SNORM = 27, |
| 90 | VFMT4_NORM_USHORT_16 = 28, | 90 | VFMT4_16_UNORM = 28, |
| 91 | VFMT4_NORM_USHORT_16_16 = 29, | 91 | VFMT4_16_16_UNORM = 29, |
| 92 | VFMT4_NORM_USHORT_16_16_16 = 30, | 92 | VFMT4_16_16_16_UNORM = 30, |
| 93 | VFMT4_NORM_USHORT_16_16_16_16 = 31, | 93 | VFMT4_16_16_16_16_UNORM = 31, |
| 94 | VFMT4_UBYTE_8 = 40, | 94 | VFMT4_32_32_SINT = 37, |
| 95 | VFMT4_UBYTE_8_8 = 41, | 95 | VFMT4_8_UINT = 40, |
| 96 | VFMT4_UBYTE_8_8_8 = 42, | 96 | VFMT4_8_8_UINT = 41, |
| 97 | VFMT4_UBYTE_8_8_8_8 = 43, | 97 | VFMT4_8_8_8_UINT = 42, |
| 98 | VFMT4_NORM_UBYTE_8 = 44, | 98 | VFMT4_8_8_8_8_UINT = 43, |
| 99 | VFMT4_NORM_UBYTE_8_8 = 45, | 99 | VFMT4_8_UNORM = 44, |
| 100 | VFMT4_NORM_UBYTE_8_8_8 = 46, | 100 | VFMT4_8_8_UNORM = 45, |
| 101 | VFMT4_NORM_UBYTE_8_8_8_8 = 47, | 101 | VFMT4_8_8_8_UNORM = 46, |
| 102 | VFMT4_BYTE_8 = 48, | 102 | VFMT4_8_8_8_8_UNORM = 47, |
| 103 | VFMT4_BYTE_8_8 = 49, | 103 | VFMT4_8_SINT = 48, |
| 104 | VFMT4_BYTE_8_8_8 = 50, | 104 | VFMT4_8_8_SINT = 49, |
| 105 | VFMT4_BYTE_8_8_8_8 = 51, | 105 | VFMT4_8_8_8_SINT = 50, |
| 106 | VFMT4_NORM_BYTE_8 = 52, | 106 | VFMT4_8_8_8_8_SINT = 51, |
| 107 | VFMT4_NORM_BYTE_8_8 = 53, | 107 | VFMT4_8_SNORM = 52, |
| 108 | VFMT4_NORM_BYTE_8_8_8 = 54, | 108 | VFMT4_8_8_SNORM = 53, |
| 109 | VFMT4_NORM_BYTE_8_8_8_8 = 55, | 109 | VFMT4_8_8_8_SNORM = 54, |
| 110 | VFMT4_UINT_10_10_10_2 = 60, | 110 | VFMT4_8_8_8_8_SNORM = 55, |
| 111 | VFMT4_NORM_UINT_10_10_10_2 = 61, | 111 | VFMT4_10_10_10_2_UINT = 60, |
| 112 | VFMT4_INT_10_10_10_2 = 62, | 112 | VFMT4_10_10_10_2_UNORM = 61, |
| 113 | VFMT4_NORM_INT_10_10_10_2 = 63, | 113 | VFMT4_10_10_10_2_SINT = 62, |
| 114 | VFMT4_10_10_10_2_SNORM = 63, | ||
| 114 | }; | 115 | }; |
| 115 | 116 | ||
| 116 | enum a4xx_tex_fmt { | 117 | enum a4xx_tex_fmt { |
| 117 | TFMT4_NORM_USHORT_565 = 11, | 118 | TFMT4_5_6_5_UNORM = 11, |
| 118 | TFMT4_NORM_USHORT_5551 = 10, | 119 | TFMT4_5_5_5_1_UNORM = 10, |
| 119 | TFMT4_NORM_USHORT_4444 = 8, | 120 | TFMT4_4_4_4_4_UNORM = 8, |
| 120 | TFMT4_NORM_UINT_X8Z24 = 71, | 121 | TFMT4_X8Z24_UNORM = 71, |
| 121 | TFMT4_NORM_UINT_2_10_10_10 = 33, | 122 | TFMT4_10_10_10_2_UNORM = 33, |
| 122 | TFMT4_NORM_UINT_A8 = 3, | 123 | TFMT4_A8_UNORM = 3, |
| 123 | TFMT4_NORM_UINT_L8_A8 = 13, | 124 | TFMT4_L8_A8_UNORM = 13, |
| 124 | TFMT4_NORM_UINT_8 = 4, | 125 | TFMT4_8_UNORM = 4, |
| 125 | TFMT4_NORM_UINT_8_8_8_8 = 28, | 126 | TFMT4_8_8_UNORM = 14, |
| 126 | TFMT4_FLOAT_16 = 20, | 127 | TFMT4_8_8_8_8_UNORM = 28, |
| 127 | TFMT4_FLOAT_16_16 = 40, | 128 | TFMT4_16_FLOAT = 20, |
| 128 | TFMT4_FLOAT_16_16_16_16 = 53, | 129 | TFMT4_16_16_FLOAT = 40, |
| 129 | TFMT4_FLOAT_32 = 43, | 130 | TFMT4_16_16_16_16_FLOAT = 53, |
| 130 | TFMT4_FLOAT_32_32 = 56, | 131 | TFMT4_32_FLOAT = 43, |
| 131 | TFMT4_FLOAT_32_32_32_32 = 63, | 132 | TFMT4_32_32_FLOAT = 56, |
| 133 | TFMT4_32_32_32_32_FLOAT = 63, | ||
| 134 | }; | ||
| 135 | |||
| 136 | enum a4xx_tex_fetchsize { | ||
| 137 | TFETCH4_1_BYTE = 0, | ||
| 138 | TFETCH4_2_BYTE = 1, | ||
| 139 | TFETCH4_4_BYTE = 2, | ||
| 140 | TFETCH4_8_BYTE = 3, | ||
| 141 | TFETCH4_16_BYTE = 4, | ||
| 132 | }; | 142 | }; |
| 133 | 143 | ||
| 134 | enum a4xx_depth_format { | 144 | enum a4xx_depth_format { |
| @@ -264,14 +274,19 @@ static inline uint32_t A4XX_RB_MSAA_CONTROL_SAMPLES(uint32_t val) | |||
| 264 | return ((val) << A4XX_RB_MSAA_CONTROL_SAMPLES__SHIFT) & A4XX_RB_MSAA_CONTROL_SAMPLES__MASK; | 274 | return ((val) << A4XX_RB_MSAA_CONTROL_SAMPLES__SHIFT) & A4XX_RB_MSAA_CONTROL_SAMPLES__MASK; |
| 265 | } | 275 | } |
| 266 | 276 | ||
| 267 | #define REG_A4XX_RB_MSAA_CONTROL2 0x000020a3 | 277 | #define REG_A4XX_RB_RENDER_CONTROL2 0x000020a3 |
| 268 | #define A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__MASK 0x00000380 | 278 | #define A4XX_RB_RENDER_CONTROL2_XCOORD 0x00000001 |
| 269 | #define A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__SHIFT 7 | 279 | #define A4XX_RB_RENDER_CONTROL2_YCOORD 0x00000002 |
| 270 | static inline uint32_t A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES(uint32_t val) | 280 | #define A4XX_RB_RENDER_CONTROL2_ZCOORD 0x00000004 |
| 281 | #define A4XX_RB_RENDER_CONTROL2_WCOORD 0x00000008 | ||
| 282 | #define A4XX_RB_RENDER_CONTROL2_FACENESS 0x00000020 | ||
| 283 | #define A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES__MASK 0x00000380 | ||
| 284 | #define A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES__SHIFT 7 | ||
| 285 | static inline uint32_t A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES(uint32_t val) | ||
| 271 | { | 286 | { |
| 272 | return ((val) << A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__SHIFT) & A4XX_RB_MSAA_CONTROL2_MSAA_SAMPLES__MASK; | 287 | return ((val) << A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES__SHIFT) & A4XX_RB_RENDER_CONTROL2_MSAA_SAMPLES__MASK; |
| 273 | } | 288 | } |
| 274 | #define A4XX_RB_MSAA_CONTROL2_VARYING 0x00001000 | 289 | #define A4XX_RB_RENDER_CONTROL2_VARYING 0x00001000 |
| 275 | 290 | ||
| 276 | static inline uint32_t REG_A4XX_RB_MRT(uint32_t i0) { return 0x000020a4 + 0x5*i0; } | 291 | static inline uint32_t REG_A4XX_RB_MRT(uint32_t i0) { return 0x000020a4 + 0x5*i0; } |
| 277 | 292 | ||
| @@ -362,7 +377,69 @@ static inline uint32_t A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR(enum adreno_r | |||
| 362 | return ((val) << A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__SHIFT) & A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__MASK; | 377 | return ((val) << A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__SHIFT) & A4XX_RB_MRT_BLEND_CONTROL_ALPHA_DEST_FACTOR__MASK; |
| 363 | } | 378 | } |
| 364 | 379 | ||
| 380 | #define REG_A4XX_RB_BLEND_RED 0x000020f3 | ||
| 381 | #define A4XX_RB_BLEND_RED_UINT__MASK 0x00007fff | ||
| 382 | #define A4XX_RB_BLEND_RED_UINT__SHIFT 0 | ||
| 383 | static inline uint32_t A4XX_RB_BLEND_RED_UINT(uint32_t val) | ||
| 384 | { | ||
| 385 | return ((val) << A4XX_RB_BLEND_RED_UINT__SHIFT) & A4XX_RB_BLEND_RED_UINT__MASK; | ||
| 386 | } | ||
| 387 | #define A4XX_RB_BLEND_RED_FLOAT__MASK 0xffff0000 | ||
| 388 | #define A4XX_RB_BLEND_RED_FLOAT__SHIFT 16 | ||
| 389 | static inline uint32_t A4XX_RB_BLEND_RED_FLOAT(float val) | ||
| 390 | { | ||
| 391 | return ((util_float_to_half(val)) << A4XX_RB_BLEND_RED_FLOAT__SHIFT) & A4XX_RB_BLEND_RED_FLOAT__MASK; | ||
| 392 | } | ||
| 393 | |||
| 394 | #define REG_A4XX_RB_BLEND_GREEN 0x000020f4 | ||
| 395 | #define A4XX_RB_BLEND_GREEN_UINT__MASK 0x00007fff | ||
| 396 | #define A4XX_RB_BLEND_GREEN_UINT__SHIFT 0 | ||
| 397 | static inline uint32_t A4XX_RB_BLEND_GREEN_UINT(uint32_t val) | ||
| 398 | { | ||
| 399 | return ((val) << A4XX_RB_BLEND_GREEN_UINT__SHIFT) & A4XX_RB_BLEND_GREEN_UINT__MASK; | ||
| 400 | } | ||
| 401 | #define A4XX_RB_BLEND_GREEN_FLOAT__MASK 0xffff0000 | ||
| 402 | #define A4XX_RB_BLEND_GREEN_FLOAT__SHIFT 16 | ||
| 403 | static inline uint32_t A4XX_RB_BLEND_GREEN_FLOAT(float val) | ||
| 404 | { | ||
| 405 | return ((util_float_to_half(val)) << A4XX_RB_BLEND_GREEN_FLOAT__SHIFT) & A4XX_RB_BLEND_GREEN_FLOAT__MASK; | ||
| 406 | } | ||
| 407 | |||
| 408 | #define REG_A4XX_RB_BLEND_BLUE 0x000020f5 | ||
| 409 | #define A4XX_RB_BLEND_BLUE_UINT__MASK 0x00007fff | ||
| 410 | #define A4XX_RB_BLEND_BLUE_UINT__SHIFT 0 | ||
| 411 | static inline uint32_t A4XX_RB_BLEND_BLUE_UINT(uint32_t val) | ||
| 412 | { | ||
| 413 | return ((val) << A4XX_RB_BLEND_BLUE_UINT__SHIFT) & A4XX_RB_BLEND_BLUE_UINT__MASK; | ||
| 414 | } | ||
| 415 | #define A4XX_RB_BLEND_BLUE_FLOAT__MASK 0xffff0000 | ||
| 416 | #define A4XX_RB_BLEND_BLUE_FLOAT__SHIFT 16 | ||
| 417 | static inline uint32_t A4XX_RB_BLEND_BLUE_FLOAT(float val) | ||
| 418 | { | ||
| 419 | return ((util_float_to_half(val)) << A4XX_RB_BLEND_BLUE_FLOAT__SHIFT) & A4XX_RB_BLEND_BLUE_FLOAT__MASK; | ||
| 420 | } | ||
| 421 | |||
| 422 | #define REG_A4XX_RB_BLEND_ALPHA 0x000020f6 | ||
| 423 | #define A4XX_RB_BLEND_ALPHA_UINT__MASK 0x00007fff | ||
| 424 | #define A4XX_RB_BLEND_ALPHA_UINT__SHIFT 0 | ||
| 425 | static inline uint32_t A4XX_RB_BLEND_ALPHA_UINT(uint32_t val) | ||
| 426 | { | ||
| 427 | return ((val) << A4XX_RB_BLEND_ALPHA_UINT__SHIFT) & A4XX_RB_BLEND_ALPHA_UINT__MASK; | ||
| 428 | } | ||
| 429 | #define A4XX_RB_BLEND_ALPHA_FLOAT__MASK 0xffff0000 | ||
| 430 | #define A4XX_RB_BLEND_ALPHA_FLOAT__SHIFT 16 | ||
| 431 | static inline uint32_t A4XX_RB_BLEND_ALPHA_FLOAT(float val) | ||
| 432 | { | ||
| 433 | return ((util_float_to_half(val)) << A4XX_RB_BLEND_ALPHA_FLOAT__SHIFT) & A4XX_RB_BLEND_ALPHA_FLOAT__MASK; | ||
| 434 | } | ||
| 435 | |||
| 365 | #define REG_A4XX_RB_ALPHA_CONTROL 0x000020f8 | 436 | #define REG_A4XX_RB_ALPHA_CONTROL 0x000020f8 |
| 437 | #define A4XX_RB_ALPHA_CONTROL_ALPHA_REF__MASK 0x000000ff | ||
| 438 | #define A4XX_RB_ALPHA_CONTROL_ALPHA_REF__SHIFT 0 | ||
| 439 | static inline uint32_t A4XX_RB_ALPHA_CONTROL_ALPHA_REF(uint32_t val) | ||
| 440 | { | ||
| 441 | return ((val) << A4XX_RB_ALPHA_CONTROL_ALPHA_REF__SHIFT) & A4XX_RB_ALPHA_CONTROL_ALPHA_REF__MASK; | ||
| 442 | } | ||
| 366 | #define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST 0x00000100 | 443 | #define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST 0x00000100 |
| 367 | #define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC__MASK 0x00000e00 | 444 | #define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC__MASK 0x00000e00 |
| 368 | #define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC__SHIFT 9 | 445 | #define A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC__SHIFT 9 |
| @@ -372,7 +449,7 @@ static inline uint32_t A4XX_RB_ALPHA_CONTROL_ALPHA_TEST_FUNC(enum adreno_compare | |||
| 372 | } | 449 | } |
| 373 | 450 | ||
| 374 | #define REG_A4XX_RB_FS_OUTPUT 0x000020f9 | 451 | #define REG_A4XX_RB_FS_OUTPUT 0x000020f9 |
| 375 | #define A4XX_RB_FS_OUTPUT_ENABLE_COLOR_PIPE 0x00000001 | 452 | #define A4XX_RB_FS_OUTPUT_ENABLE_BLEND 0x00000001 |
| 376 | #define A4XX_RB_FS_OUTPUT_FAST_CLEAR 0x00000100 | 453 | #define A4XX_RB_FS_OUTPUT_FAST_CLEAR 0x00000100 |
| 377 | #define A4XX_RB_FS_OUTPUT_SAMPLE_MASK__MASK 0xffff0000 | 454 | #define A4XX_RB_FS_OUTPUT_SAMPLE_MASK__MASK 0xffff0000 |
| 378 | #define A4XX_RB_FS_OUTPUT_SAMPLE_MASK__SHIFT 16 | 455 | #define A4XX_RB_FS_OUTPUT_SAMPLE_MASK__SHIFT 16 |
| @@ -416,11 +493,11 @@ static inline uint32_t A4XX_RB_COPY_CONTROL_GMEM_BASE(uint32_t val) | |||
| 416 | } | 493 | } |
| 417 | 494 | ||
| 418 | #define REG_A4XX_RB_COPY_DEST_BASE 0x000020fd | 495 | #define REG_A4XX_RB_COPY_DEST_BASE 0x000020fd |
| 419 | #define A4XX_RB_COPY_DEST_BASE_BASE__MASK 0xfffffff0 | 496 | #define A4XX_RB_COPY_DEST_BASE_BASE__MASK 0xffffffe0 |
| 420 | #define A4XX_RB_COPY_DEST_BASE_BASE__SHIFT 4 | 497 | #define A4XX_RB_COPY_DEST_BASE_BASE__SHIFT 5 |
| 421 | static inline uint32_t A4XX_RB_COPY_DEST_BASE_BASE(uint32_t val) | 498 | static inline uint32_t A4XX_RB_COPY_DEST_BASE_BASE(uint32_t val) |
| 422 | { | 499 | { |
| 423 | return ((val >> 4) << A4XX_RB_COPY_DEST_BASE_BASE__SHIFT) & A4XX_RB_COPY_DEST_BASE_BASE__MASK; | 500 | return ((val >> 5) << A4XX_RB_COPY_DEST_BASE_BASE__SHIFT) & A4XX_RB_COPY_DEST_BASE_BASE__MASK; |
| 424 | } | 501 | } |
| 425 | 502 | ||
| 426 | #define REG_A4XX_RB_COPY_DEST_PITCH 0x000020fe | 503 | #define REG_A4XX_RB_COPY_DEST_PITCH 0x000020fe |
| @@ -508,7 +585,7 @@ static inline uint32_t A4XX_RB_DEPTH_INFO_DEPTH_BASE(uint32_t val) | |||
| 508 | #define A4XX_RB_DEPTH_PITCH__SHIFT 0 | 585 | #define A4XX_RB_DEPTH_PITCH__SHIFT 0 |
| 509 | static inline uint32_t A4XX_RB_DEPTH_PITCH(uint32_t val) | 586 | static inline uint32_t A4XX_RB_DEPTH_PITCH(uint32_t val) |
| 510 | { | 587 | { |
| 511 | return ((val >> 4) << A4XX_RB_DEPTH_PITCH__SHIFT) & A4XX_RB_DEPTH_PITCH__MASK; | 588 | return ((val >> 5) << A4XX_RB_DEPTH_PITCH__SHIFT) & A4XX_RB_DEPTH_PITCH__MASK; |
| 512 | } | 589 | } |
| 513 | 590 | ||
| 514 | #define REG_A4XX_RB_DEPTH_PITCH2 0x00002105 | 591 | #define REG_A4XX_RB_DEPTH_PITCH2 0x00002105 |
| @@ -516,7 +593,7 @@ static inline uint32_t A4XX_RB_DEPTH_PITCH(uint32_t val) | |||
| 516 | #define A4XX_RB_DEPTH_PITCH2__SHIFT 0 | 593 | #define A4XX_RB_DEPTH_PITCH2__SHIFT 0 |
| 517 | static inline uint32_t A4XX_RB_DEPTH_PITCH2(uint32_t val) | 594 | static inline uint32_t A4XX_RB_DEPTH_PITCH2(uint32_t val) |
| 518 | { | 595 | { |
| 519 | return ((val >> 4) << A4XX_RB_DEPTH_PITCH2__SHIFT) & A4XX_RB_DEPTH_PITCH2__MASK; | 596 | return ((val >> 5) << A4XX_RB_DEPTH_PITCH2__SHIFT) & A4XX_RB_DEPTH_PITCH2__MASK; |
| 520 | } | 597 | } |
| 521 | 598 | ||
| 522 | #define REG_A4XX_RB_STENCIL_CONTROL 0x00002106 | 599 | #define REG_A4XX_RB_STENCIL_CONTROL 0x00002106 |
| @@ -630,7 +707,11 @@ static inline uint32_t A4XX_RB_BIN_OFFSET_Y(uint32_t val) | |||
| 630 | return ((val) << A4XX_RB_BIN_OFFSET_Y__SHIFT) & A4XX_RB_BIN_OFFSET_Y__MASK; | 707 | return ((val) << A4XX_RB_BIN_OFFSET_Y__SHIFT) & A4XX_RB_BIN_OFFSET_Y__MASK; |
| 631 | } | 708 | } |
| 632 | 709 | ||
| 633 | #define REG_A4XX_RB_VPORT_Z_CLAMP_MAX_15 0x0000213f | 710 | static inline uint32_t REG_A4XX_RB_VPORT_Z_CLAMP(uint32_t i0) { return 0x00002120 + 0x2*i0; } |
| 711 | |||
| 712 | static inline uint32_t REG_A4XX_RB_VPORT_Z_CLAMP_MIN(uint32_t i0) { return 0x00002120 + 0x2*i0; } | ||
| 713 | |||
| 714 | static inline uint32_t REG_A4XX_RB_VPORT_Z_CLAMP_MAX(uint32_t i0) { return 0x00002121 + 0x2*i0; } | ||
| 634 | 715 | ||
| 635 | #define REG_A4XX_RBBM_HW_VERSION 0x00000000 | 716 | #define REG_A4XX_RBBM_HW_VERSION 0x00000000 |
| 636 | 717 | ||
| @@ -1121,7 +1202,9 @@ static inline uint32_t A4XX_SP_FS_CTRL_REG1_CONSTLENGTH(uint32_t val) | |||
| 1121 | { | 1202 | { |
| 1122 | return ((val) << A4XX_SP_FS_CTRL_REG1_CONSTLENGTH__SHIFT) & A4XX_SP_FS_CTRL_REG1_CONSTLENGTH__MASK; | 1203 | return ((val) << A4XX_SP_FS_CTRL_REG1_CONSTLENGTH__SHIFT) & A4XX_SP_FS_CTRL_REG1_CONSTLENGTH__MASK; |
| 1123 | } | 1204 | } |
| 1205 | #define A4XX_SP_FS_CTRL_REG1_FACENESS 0x00080000 | ||
| 1124 | #define A4XX_SP_FS_CTRL_REG1_VARYING 0x00100000 | 1206 | #define A4XX_SP_FS_CTRL_REG1_VARYING 0x00100000 |
| 1207 | #define A4XX_SP_FS_CTRL_REG1_FRAGCOORD 0x00200000 | ||
| 1125 | 1208 | ||
| 1126 | #define REG_A4XX_SP_FS_OBJ_OFFSET_REG 0x000022ea | 1209 | #define REG_A4XX_SP_FS_OBJ_OFFSET_REG 0x000022ea |
| 1127 | #define A4XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK 0x01ff0000 | 1210 | #define A4XX_SP_FS_OBJ_OFFSET_REG_CONSTOBJECTOFFSET__MASK 0x01ff0000 |
| @@ -1384,6 +1467,12 @@ static inline uint32_t A4XX_VFD_CONTROL_1_REGID4INST(uint32_t val) | |||
| 1384 | #define REG_A4XX_VFD_CONTROL_2 0x00002202 | 1467 | #define REG_A4XX_VFD_CONTROL_2 0x00002202 |
| 1385 | 1468 | ||
| 1386 | #define REG_A4XX_VFD_CONTROL_3 0x00002203 | 1469 | #define REG_A4XX_VFD_CONTROL_3 0x00002203 |
| 1470 | #define A4XX_VFD_CONTROL_3_REGID_VTXCNT__MASK 0x0000ff00 | ||
| 1471 | #define A4XX_VFD_CONTROL_3_REGID_VTXCNT__SHIFT 8 | ||
| 1472 | static inline uint32_t A4XX_VFD_CONTROL_3_REGID_VTXCNT(uint32_t val) | ||
| 1473 | { | ||
| 1474 | return ((val) << A4XX_VFD_CONTROL_3_REGID_VTXCNT__SHIFT) & A4XX_VFD_CONTROL_3_REGID_VTXCNT__MASK; | ||
| 1475 | } | ||
| 1387 | 1476 | ||
| 1388 | #define REG_A4XX_VFD_CONTROL_4 0x00002204 | 1477 | #define REG_A4XX_VFD_CONTROL_4 0x00002204 |
| 1389 | 1478 | ||
| @@ -1405,12 +1494,7 @@ static inline uint32_t A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE(uint32_t val) | |||
| 1405 | return ((val) << A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT) & A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK; | 1494 | return ((val) << A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE__SHIFT) & A4XX_VFD_FETCH_INSTR_0_BUFSTRIDE__MASK; |
| 1406 | } | 1495 | } |
| 1407 | #define A4XX_VFD_FETCH_INSTR_0_SWITCHNEXT 0x00080000 | 1496 | #define A4XX_VFD_FETCH_INSTR_0_SWITCHNEXT 0x00080000 |
| 1408 | #define A4XX_VFD_FETCH_INSTR_0_STEPRATE__MASK 0xff000000 | 1497 | #define A4XX_VFD_FETCH_INSTR_0_INSTANCED 0x00100000 |
| 1409 | #define A4XX_VFD_FETCH_INSTR_0_STEPRATE__SHIFT 24 | ||
| 1410 | static inline uint32_t A4XX_VFD_FETCH_INSTR_0_STEPRATE(uint32_t val) | ||
| 1411 | { | ||
| 1412 | return ((val) << A4XX_VFD_FETCH_INSTR_0_STEPRATE__SHIFT) & A4XX_VFD_FETCH_INSTR_0_STEPRATE__MASK; | ||
| 1413 | } | ||
| 1414 | 1498 | ||
| 1415 | static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_1(uint32_t i0) { return 0x0000220b + 0x4*i0; } | 1499 | static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_1(uint32_t i0) { return 0x0000220b + 0x4*i0; } |
| 1416 | 1500 | ||
| @@ -1423,6 +1507,12 @@ static inline uint32_t A4XX_VFD_FETCH_INSTR_2_SIZE(uint32_t val) | |||
| 1423 | } | 1507 | } |
| 1424 | 1508 | ||
| 1425 | static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_3(uint32_t i0) { return 0x0000220d + 0x4*i0; } | 1509 | static inline uint32_t REG_A4XX_VFD_FETCH_INSTR_3(uint32_t i0) { return 0x0000220d + 0x4*i0; } |
| 1510 | #define A4XX_VFD_FETCH_INSTR_3_STEPRATE__MASK 0x000001ff | ||
| 1511 | #define A4XX_VFD_FETCH_INSTR_3_STEPRATE__SHIFT 0 | ||
| 1512 | static inline uint32_t A4XX_VFD_FETCH_INSTR_3_STEPRATE(uint32_t val) | ||
| 1513 | { | ||
| 1514 | return ((val) << A4XX_VFD_FETCH_INSTR_3_STEPRATE__SHIFT) & A4XX_VFD_FETCH_INSTR_3_STEPRATE__MASK; | ||
| 1515 | } | ||
| 1426 | 1516 | ||
| 1427 | static inline uint32_t REG_A4XX_VFD_DECODE(uint32_t i0) { return 0x0000228a + 0x1*i0; } | 1517 | static inline uint32_t REG_A4XX_VFD_DECODE(uint32_t i0) { return 0x0000228a + 0x1*i0; } |
| 1428 | 1518 | ||
| @@ -1446,6 +1536,7 @@ static inline uint32_t A4XX_VFD_DECODE_INSTR_REGID(uint32_t val) | |||
| 1446 | { | 1536 | { |
| 1447 | return ((val) << A4XX_VFD_DECODE_INSTR_REGID__SHIFT) & A4XX_VFD_DECODE_INSTR_REGID__MASK; | 1537 | return ((val) << A4XX_VFD_DECODE_INSTR_REGID__SHIFT) & A4XX_VFD_DECODE_INSTR_REGID__MASK; |
| 1448 | } | 1538 | } |
| 1539 | #define A4XX_VFD_DECODE_INSTR_INT 0x00100000 | ||
| 1449 | #define A4XX_VFD_DECODE_INSTR_SWAP__MASK 0x00c00000 | 1540 | #define A4XX_VFD_DECODE_INSTR_SWAP__MASK 0x00c00000 |
| 1450 | #define A4XX_VFD_DECODE_INSTR_SWAP__SHIFT 22 | 1541 | #define A4XX_VFD_DECODE_INSTR_SWAP__SHIFT 22 |
| 1451 | static inline uint32_t A4XX_VFD_DECODE_INSTR_SWAP(enum a3xx_color_swap val) | 1542 | static inline uint32_t A4XX_VFD_DECODE_INSTR_SWAP(enum a3xx_color_swap val) |
| @@ -1585,7 +1676,47 @@ static inline uint32_t A4XX_GRAS_SU_POLY_OFFSET_OFFSET(float val) | |||
| 1585 | return ((fui(val)) << A4XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT) & A4XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK; | 1676 | return ((fui(val)) << A4XX_GRAS_SU_POLY_OFFSET_OFFSET__SHIFT) & A4XX_GRAS_SU_POLY_OFFSET_OFFSET__MASK; |
| 1586 | } | 1677 | } |
| 1587 | 1678 | ||
| 1588 | #define REG_A4XX_GRAS_SC_EXTENT_WINDOW_TL 0x0000209f | 1679 | #define REG_A4XX_GRAS_DEPTH_CONTROL 0x00002077 |
| 1680 | #define A4XX_GRAS_DEPTH_CONTROL_FORMAT__MASK 0x00000003 | ||
| 1681 | #define A4XX_GRAS_DEPTH_CONTROL_FORMAT__SHIFT 0 | ||
| 1682 | static inline uint32_t A4XX_GRAS_DEPTH_CONTROL_FORMAT(enum a4xx_depth_format val) | ||
| 1683 | { | ||
| 1684 | return ((val) << A4XX_GRAS_DEPTH_CONTROL_FORMAT__SHIFT) & A4XX_GRAS_DEPTH_CONTROL_FORMAT__MASK; | ||
| 1685 | } | ||
| 1686 | |||
| 1687 | #define REG_A4XX_GRAS_SU_MODE_CONTROL 0x00002078 | ||
| 1688 | #define A4XX_GRAS_SU_MODE_CONTROL_CULL_FRONT 0x00000001 | ||
| 1689 | #define A4XX_GRAS_SU_MODE_CONTROL_CULL_BACK 0x00000002 | ||
| 1690 | #define A4XX_GRAS_SU_MODE_CONTROL_FRONT_CW 0x00000004 | ||
| 1691 | #define A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK 0x000007f8 | ||
| 1692 | #define A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT 3 | ||
| 1693 | static inline uint32_t A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(float val) | ||
| 1694 | { | ||
| 1695 | return ((((int32_t)(val * 4.0))) << A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK; | ||
| 1696 | } | ||
| 1697 | #define A4XX_GRAS_SU_MODE_CONTROL_POLY_OFFSET 0x00000800 | ||
| 1698 | #define A4XX_GRAS_SU_MODE_CONTROL_RENDERING_PASS 0x00100000 | ||
| 1699 | |||
| 1700 | #define REG_A4XX_GRAS_SC_CONTROL 0x0000207b | ||
| 1701 | #define A4XX_GRAS_SC_CONTROL_RENDER_MODE__MASK 0x0000000c | ||
| 1702 | #define A4XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT 2 | ||
| 1703 | static inline uint32_t A4XX_GRAS_SC_CONTROL_RENDER_MODE(enum a3xx_render_mode val) | ||
| 1704 | { | ||
| 1705 | return ((val) << A4XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT) & A4XX_GRAS_SC_CONTROL_RENDER_MODE__MASK; | ||
| 1706 | } | ||
| 1707 | #define A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK 0x00000380 | ||
| 1708 | #define A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT 7 | ||
| 1709 | static inline uint32_t A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(uint32_t val) | ||
| 1710 | { | ||
| 1711 | return ((val) << A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT) & A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK; | ||
| 1712 | } | ||
| 1713 | #define A4XX_GRAS_SC_CONTROL_MSAA_DISABLE 0x00000800 | ||
| 1714 | #define A4XX_GRAS_SC_CONTROL_RASTER_MODE__MASK 0x0000f000 | ||
| 1715 | #define A4XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT 12 | ||
| 1716 | static inline uint32_t A4XX_GRAS_SC_CONTROL_RASTER_MODE(uint32_t val) | ||
| 1717 | { | ||
| 1718 | return ((val) << A4XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT) & A4XX_GRAS_SC_CONTROL_RASTER_MODE__MASK; | ||
| 1719 | } | ||
| 1589 | 1720 | ||
| 1590 | #define REG_A4XX_GRAS_SC_SCREEN_SCISSOR_TL 0x0000207c | 1721 | #define REG_A4XX_GRAS_SC_SCREEN_SCISSOR_TL 0x0000207c |
| 1591 | #define A4XX_GRAS_SC_SCREEN_SCISSOR_TL_WINDOW_OFFSET_DISABLE 0x80000000 | 1722 | #define A4XX_GRAS_SC_SCREEN_SCISSOR_TL_WINDOW_OFFSET_DISABLE 0x80000000 |
| @@ -1647,46 +1778,34 @@ static inline uint32_t A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y(uint32_t val) | |||
| 1647 | return ((val) << A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__SHIFT) & A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__MASK; | 1778 | return ((val) << A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__SHIFT) & A4XX_GRAS_SC_WINDOW_SCISSOR_TL_Y__MASK; |
| 1648 | } | 1779 | } |
| 1649 | 1780 | ||
| 1650 | #define REG_A4XX_GRAS_DEPTH_CONTROL 0x00002077 | 1781 | #define REG_A4XX_GRAS_SC_EXTENT_WINDOW_BR 0x0000209e |
| 1651 | #define A4XX_GRAS_DEPTH_CONTROL_FORMAT__MASK 0x00000003 | 1782 | #define A4XX_GRAS_SC_EXTENT_WINDOW_BR_WINDOW_OFFSET_DISABLE 0x80000000 |
| 1652 | #define A4XX_GRAS_DEPTH_CONTROL_FORMAT__SHIFT 0 | 1783 | #define A4XX_GRAS_SC_EXTENT_WINDOW_BR_X__MASK 0x00007fff |
| 1653 | static inline uint32_t A4XX_GRAS_DEPTH_CONTROL_FORMAT(enum a4xx_depth_format val) | 1784 | #define A4XX_GRAS_SC_EXTENT_WINDOW_BR_X__SHIFT 0 |
| 1785 | static inline uint32_t A4XX_GRAS_SC_EXTENT_WINDOW_BR_X(uint32_t val) | ||
| 1654 | { | 1786 | { |
| 1655 | return ((val) << A4XX_GRAS_DEPTH_CONTROL_FORMAT__SHIFT) & A4XX_GRAS_DEPTH_CONTROL_FORMAT__MASK; | 1787 | return ((val) << A4XX_GRAS_SC_EXTENT_WINDOW_BR_X__SHIFT) & A4XX_GRAS_SC_EXTENT_WINDOW_BR_X__MASK; |
| 1656 | } | 1788 | } |
| 1657 | 1789 | #define A4XX_GRAS_SC_EXTENT_WINDOW_BR_Y__MASK 0x7fff0000 | |
| 1658 | #define REG_A4XX_GRAS_SU_MODE_CONTROL 0x00002078 | 1790 | #define A4XX_GRAS_SC_EXTENT_WINDOW_BR_Y__SHIFT 16 |
| 1659 | #define A4XX_GRAS_SU_MODE_CONTROL_CULL_FRONT 0x00000001 | 1791 | static inline uint32_t A4XX_GRAS_SC_EXTENT_WINDOW_BR_Y(uint32_t val) |
| 1660 | #define A4XX_GRAS_SU_MODE_CONTROL_CULL_BACK 0x00000002 | ||
| 1661 | #define A4XX_GRAS_SU_MODE_CONTROL_FRONT_CW 0x00000004 | ||
| 1662 | #define A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK 0x000007f8 | ||
| 1663 | #define A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT 3 | ||
| 1664 | static inline uint32_t A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH(float val) | ||
| 1665 | { | 1792 | { |
| 1666 | return ((((int32_t)(val * 4.0))) << A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__SHIFT) & A4XX_GRAS_SU_MODE_CONTROL_LINEHALFWIDTH__MASK; | 1793 | return ((val) << A4XX_GRAS_SC_EXTENT_WINDOW_BR_Y__SHIFT) & A4XX_GRAS_SC_EXTENT_WINDOW_BR_Y__MASK; |
| 1667 | } | 1794 | } |
| 1668 | #define A4XX_GRAS_SU_MODE_CONTROL_POLY_OFFSET 0x00000800 | ||
| 1669 | #define A4XX_GRAS_SU_MODE_CONTROL_RENDERING_PASS 0x00100000 | ||
| 1670 | 1795 | ||
| 1671 | #define REG_A4XX_GRAS_SC_CONTROL 0x0000207b | 1796 | #define REG_A4XX_GRAS_SC_EXTENT_WINDOW_TL 0x0000209f |
| 1672 | #define A4XX_GRAS_SC_CONTROL_RENDER_MODE__MASK 0x0000000c | 1797 | #define A4XX_GRAS_SC_EXTENT_WINDOW_TL_WINDOW_OFFSET_DISABLE 0x80000000 |
| 1673 | #define A4XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT 2 | 1798 | #define A4XX_GRAS_SC_EXTENT_WINDOW_TL_X__MASK 0x00007fff |
| 1674 | static inline uint32_t A4XX_GRAS_SC_CONTROL_RENDER_MODE(enum a3xx_render_mode val) | 1799 | #define A4XX_GRAS_SC_EXTENT_WINDOW_TL_X__SHIFT 0 |
| 1675 | { | 1800 | static inline uint32_t A4XX_GRAS_SC_EXTENT_WINDOW_TL_X(uint32_t val) |
| 1676 | return ((val) << A4XX_GRAS_SC_CONTROL_RENDER_MODE__SHIFT) & A4XX_GRAS_SC_CONTROL_RENDER_MODE__MASK; | ||
| 1677 | } | ||
| 1678 | #define A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK 0x00000380 | ||
| 1679 | #define A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT 7 | ||
| 1680 | static inline uint32_t A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES(uint32_t val) | ||
| 1681 | { | 1801 | { |
| 1682 | return ((val) << A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__SHIFT) & A4XX_GRAS_SC_CONTROL_MSAA_SAMPLES__MASK; | 1802 | return ((val) << A4XX_GRAS_SC_EXTENT_WINDOW_TL_X__SHIFT) & A4XX_GRAS_SC_EXTENT_WINDOW_TL_X__MASK; |
| 1683 | } | 1803 | } |
| 1684 | #define A4XX_GRAS_SC_CONTROL_MSAA_DISABLE 0x00000800 | 1804 | #define A4XX_GRAS_SC_EXTENT_WINDOW_TL_Y__MASK 0x7fff0000 |
| 1685 | #define A4XX_GRAS_SC_CONTROL_RASTER_MODE__MASK 0x0000f000 | 1805 | #define A4XX_GRAS_SC_EXTENT_WINDOW_TL_Y__SHIFT 16 |
| 1686 | #define A4XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT 12 | 1806 | static inline uint32_t A4XX_GRAS_SC_EXTENT_WINDOW_TL_Y(uint32_t val) |
| 1687 | static inline uint32_t A4XX_GRAS_SC_CONTROL_RASTER_MODE(uint32_t val) | ||
| 1688 | { | 1807 | { |
| 1689 | return ((val) << A4XX_GRAS_SC_CONTROL_RASTER_MODE__SHIFT) & A4XX_GRAS_SC_CONTROL_RASTER_MODE__MASK; | 1808 | return ((val) << A4XX_GRAS_SC_EXTENT_WINDOW_TL_Y__SHIFT) & A4XX_GRAS_SC_EXTENT_WINDOW_TL_Y__MASK; |
| 1690 | } | 1809 | } |
| 1691 | 1810 | ||
| 1692 | #define REG_A4XX_UCHE_CACHE_MODE_CONTROL 0x00000e80 | 1811 | #define REG_A4XX_UCHE_CACHE_MODE_CONTROL 0x00000e80 |
| @@ -1742,6 +1861,12 @@ static inline uint32_t A4XX_HLSQ_CONTROL_1_REG_VSTHREADSIZE(enum a3xx_threadsize | |||
| 1742 | } | 1861 | } |
| 1743 | #define A4XX_HLSQ_CONTROL_1_REG_VSSUPERTHREADENABLE 0x00000100 | 1862 | #define A4XX_HLSQ_CONTROL_1_REG_VSSUPERTHREADENABLE 0x00000100 |
| 1744 | #define A4XX_HLSQ_CONTROL_1_REG_RESERVED1 0x00000200 | 1863 | #define A4XX_HLSQ_CONTROL_1_REG_RESERVED1 0x00000200 |
| 1864 | #define A4XX_HLSQ_CONTROL_1_REG_COORDREGID__MASK 0x00ff0000 | ||
| 1865 | #define A4XX_HLSQ_CONTROL_1_REG_COORDREGID__SHIFT 16 | ||
| 1866 | static inline uint32_t A4XX_HLSQ_CONTROL_1_REG_COORDREGID(uint32_t val) | ||
| 1867 | { | ||
| 1868 | return ((val) << A4XX_HLSQ_CONTROL_1_REG_COORDREGID__SHIFT) & A4XX_HLSQ_CONTROL_1_REG_COORDREGID__MASK; | ||
| 1869 | } | ||
| 1745 | #define A4XX_HLSQ_CONTROL_1_REG_ZWCOORD 0x02000000 | 1870 | #define A4XX_HLSQ_CONTROL_1_REG_ZWCOORD 0x02000000 |
| 1746 | 1871 | ||
| 1747 | #define REG_A4XX_HLSQ_CONTROL_2_REG 0x000023c2 | 1872 | #define REG_A4XX_HLSQ_CONTROL_2_REG 0x000023c2 |
| @@ -1751,6 +1876,12 @@ static inline uint32_t A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD(uint32_t val) | |||
| 1751 | { | 1876 | { |
| 1752 | return ((val) << A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__SHIFT) & A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__MASK; | 1877 | return ((val) << A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__SHIFT) & A4XX_HLSQ_CONTROL_2_REG_PRIMALLOCTHRESHOLD__MASK; |
| 1753 | } | 1878 | } |
| 1879 | #define A4XX_HLSQ_CONTROL_2_REG_FACEREGID__MASK 0x000003fc | ||
| 1880 | #define A4XX_HLSQ_CONTROL_2_REG_FACEREGID__SHIFT 2 | ||
| 1881 | static inline uint32_t A4XX_HLSQ_CONTROL_2_REG_FACEREGID(uint32_t val) | ||
| 1882 | { | ||
| 1883 | return ((val) << A4XX_HLSQ_CONTROL_2_REG_FACEREGID__SHIFT) & A4XX_HLSQ_CONTROL_2_REG_FACEREGID__MASK; | ||
| 1884 | } | ||
| 1754 | 1885 | ||
| 1755 | #define REG_A4XX_HLSQ_CONTROL_3_REG 0x000023c3 | 1886 | #define REG_A4XX_HLSQ_CONTROL_3_REG 0x000023c3 |
| 1756 | #define A4XX_HLSQ_CONTROL_3_REG_REGID__MASK 0x000000ff | 1887 | #define A4XX_HLSQ_CONTROL_3_REG_REGID__MASK 0x000000ff |
| @@ -1965,15 +2096,13 @@ static inline uint32_t A4XX_HLSQ_GS_CONTROL_REG_INSTRLENGTH(uint32_t val) | |||
| 1965 | 2096 | ||
| 1966 | #define REG_A4XX_UNKNOWN_20F2 0x000020f2 | 2097 | #define REG_A4XX_UNKNOWN_20F2 0x000020f2 |
| 1967 | 2098 | ||
| 1968 | #define REG_A4XX_UNKNOWN_20F3 0x000020f3 | ||
| 1969 | |||
| 1970 | #define REG_A4XX_UNKNOWN_20F4 0x000020f4 | ||
| 1971 | |||
| 1972 | #define REG_A4XX_UNKNOWN_20F5 0x000020f5 | ||
| 1973 | |||
| 1974 | #define REG_A4XX_UNKNOWN_20F6 0x000020f6 | ||
| 1975 | |||
| 1976 | #define REG_A4XX_UNKNOWN_20F7 0x000020f7 | 2099 | #define REG_A4XX_UNKNOWN_20F7 0x000020f7 |
| 2100 | #define A4XX_UNKNOWN_20F7__MASK 0xffffffff | ||
| 2101 | #define A4XX_UNKNOWN_20F7__SHIFT 0 | ||
| 2102 | static inline uint32_t A4XX_UNKNOWN_20F7(float val) | ||
| 2103 | { | ||
| 2104 | return ((fui(val)) << A4XX_UNKNOWN_20F7__SHIFT) & A4XX_UNKNOWN_20F7__MASK; | ||
| 2105 | } | ||
| 1977 | 2106 | ||
| 1978 | #define REG_A4XX_UNKNOWN_2152 0x00002152 | 2107 | #define REG_A4XX_UNKNOWN_2152 0x00002152 |
| 1979 | 2108 | ||
| @@ -2000,6 +2129,7 @@ static inline uint32_t A4XX_HLSQ_GS_CONTROL_REG_INSTRLENGTH(uint32_t val) | |||
| 2000 | #define REG_A4XX_UNKNOWN_23A0 0x000023a0 | 2129 | #define REG_A4XX_UNKNOWN_23A0 0x000023a0 |
| 2001 | 2130 | ||
| 2002 | #define REG_A4XX_TEX_SAMP_0 0x00000000 | 2131 | #define REG_A4XX_TEX_SAMP_0 0x00000000 |
| 2132 | #define A4XX_TEX_SAMP_0_MIPFILTER_LINEAR_NEAR 0x00000001 | ||
| 2003 | #define A4XX_TEX_SAMP_0_XY_MAG__MASK 0x00000006 | 2133 | #define A4XX_TEX_SAMP_0_XY_MAG__MASK 0x00000006 |
| 2004 | #define A4XX_TEX_SAMP_0_XY_MAG__SHIFT 1 | 2134 | #define A4XX_TEX_SAMP_0_XY_MAG__SHIFT 1 |
| 2005 | static inline uint32_t A4XX_TEX_SAMP_0_XY_MAG(enum a4xx_tex_filter val) | 2135 | static inline uint32_t A4XX_TEX_SAMP_0_XY_MAG(enum a4xx_tex_filter val) |
| @@ -2038,17 +2168,19 @@ static inline uint32_t A4XX_TEX_SAMP_1_COMPARE_FUNC(enum adreno_compare_func val | |||
| 2038 | { | 2168 | { |
| 2039 | return ((val) << A4XX_TEX_SAMP_1_COMPARE_FUNC__SHIFT) & A4XX_TEX_SAMP_1_COMPARE_FUNC__MASK; | 2169 | return ((val) << A4XX_TEX_SAMP_1_COMPARE_FUNC__SHIFT) & A4XX_TEX_SAMP_1_COMPARE_FUNC__MASK; |
| 2040 | } | 2170 | } |
| 2171 | #define A4XX_TEX_SAMP_1_UNNORM_COORDS 0x00000020 | ||
| 2172 | #define A4XX_TEX_SAMP_1_MIPFILTER_LINEAR_FAR 0x00000040 | ||
| 2041 | #define A4XX_TEX_SAMP_1_MAX_LOD__MASK 0x000fff00 | 2173 | #define A4XX_TEX_SAMP_1_MAX_LOD__MASK 0x000fff00 |
| 2042 | #define A4XX_TEX_SAMP_1_MAX_LOD__SHIFT 8 | 2174 | #define A4XX_TEX_SAMP_1_MAX_LOD__SHIFT 8 |
| 2043 | static inline uint32_t A4XX_TEX_SAMP_1_MAX_LOD(float val) | 2175 | static inline uint32_t A4XX_TEX_SAMP_1_MAX_LOD(float val) |
| 2044 | { | 2176 | { |
| 2045 | return ((((uint32_t)(val * 64.0))) << A4XX_TEX_SAMP_1_MAX_LOD__SHIFT) & A4XX_TEX_SAMP_1_MAX_LOD__MASK; | 2177 | return ((((uint32_t)(val * 256.0))) << A4XX_TEX_SAMP_1_MAX_LOD__SHIFT) & A4XX_TEX_SAMP_1_MAX_LOD__MASK; |
| 2046 | } | 2178 | } |
| 2047 | #define A4XX_TEX_SAMP_1_MIN_LOD__MASK 0xfff00000 | 2179 | #define A4XX_TEX_SAMP_1_MIN_LOD__MASK 0xfff00000 |
| 2048 | #define A4XX_TEX_SAMP_1_MIN_LOD__SHIFT 20 | 2180 | #define A4XX_TEX_SAMP_1_MIN_LOD__SHIFT 20 |
| 2049 | static inline uint32_t A4XX_TEX_SAMP_1_MIN_LOD(float val) | 2181 | static inline uint32_t A4XX_TEX_SAMP_1_MIN_LOD(float val) |
| 2050 | { | 2182 | { |
| 2051 | return ((((uint32_t)(val * 64.0))) << A4XX_TEX_SAMP_1_MIN_LOD__SHIFT) & A4XX_TEX_SAMP_1_MIN_LOD__MASK; | 2183 | return ((((uint32_t)(val * 256.0))) << A4XX_TEX_SAMP_1_MIN_LOD__SHIFT) & A4XX_TEX_SAMP_1_MIN_LOD__MASK; |
| 2052 | } | 2184 | } |
| 2053 | 2185 | ||
| 2054 | #define REG_A4XX_TEX_CONST_0 0x00000000 | 2186 | #define REG_A4XX_TEX_CONST_0 0x00000000 |
| @@ -2077,6 +2209,12 @@ static inline uint32_t A4XX_TEX_CONST_0_SWIZ_W(enum a4xx_tex_swiz val) | |||
| 2077 | { | 2209 | { |
| 2078 | return ((val) << A4XX_TEX_CONST_0_SWIZ_W__SHIFT) & A4XX_TEX_CONST_0_SWIZ_W__MASK; | 2210 | return ((val) << A4XX_TEX_CONST_0_SWIZ_W__SHIFT) & A4XX_TEX_CONST_0_SWIZ_W__MASK; |
| 2079 | } | 2211 | } |
| 2212 | #define A4XX_TEX_CONST_0_MIPLVLS__MASK 0x000f0000 | ||
| 2213 | #define A4XX_TEX_CONST_0_MIPLVLS__SHIFT 16 | ||
| 2214 | static inline uint32_t A4XX_TEX_CONST_0_MIPLVLS(uint32_t val) | ||
| 2215 | { | ||
| 2216 | return ((val) << A4XX_TEX_CONST_0_MIPLVLS__SHIFT) & A4XX_TEX_CONST_0_MIPLVLS__MASK; | ||
| 2217 | } | ||
| 2080 | #define A4XX_TEX_CONST_0_FMT__MASK 0x1fc00000 | 2218 | #define A4XX_TEX_CONST_0_FMT__MASK 0x1fc00000 |
| 2081 | #define A4XX_TEX_CONST_0_FMT__SHIFT 22 | 2219 | #define A4XX_TEX_CONST_0_FMT__SHIFT 22 |
| 2082 | static inline uint32_t A4XX_TEX_CONST_0_FMT(enum a4xx_tex_fmt val) | 2220 | static inline uint32_t A4XX_TEX_CONST_0_FMT(enum a4xx_tex_fmt val) |
| @@ -2105,6 +2243,12 @@ static inline uint32_t A4XX_TEX_CONST_1_WIDTH(uint32_t val) | |||
| 2105 | } | 2243 | } |
| 2106 | 2244 | ||
| 2107 | #define REG_A4XX_TEX_CONST_2 0x00000002 | 2245 | #define REG_A4XX_TEX_CONST_2 0x00000002 |
| 2246 | #define A4XX_TEX_CONST_2_FETCHSIZE__MASK 0x0000000f | ||
| 2247 | #define A4XX_TEX_CONST_2_FETCHSIZE__SHIFT 0 | ||
| 2248 | static inline uint32_t A4XX_TEX_CONST_2_FETCHSIZE(enum a4xx_tex_fetchsize val) | ||
| 2249 | { | ||
| 2250 | return ((val) << A4XX_TEX_CONST_2_FETCHSIZE__SHIFT) & A4XX_TEX_CONST_2_FETCHSIZE__MASK; | ||
| 2251 | } | ||
| 2108 | #define A4XX_TEX_CONST_2_PITCH__MASK 0x3ffffe00 | 2252 | #define A4XX_TEX_CONST_2_PITCH__MASK 0x3ffffe00 |
| 2109 | #define A4XX_TEX_CONST_2_PITCH__SHIFT 9 | 2253 | #define A4XX_TEX_CONST_2_PITCH__SHIFT 9 |
| 2110 | static inline uint32_t A4XX_TEX_CONST_2_PITCH(uint32_t val) | 2254 | static inline uint32_t A4XX_TEX_CONST_2_PITCH(uint32_t val) |
| @@ -2119,19 +2263,31 @@ static inline uint32_t A4XX_TEX_CONST_2_SWAP(enum a3xx_color_swap val) | |||
| 2119 | } | 2263 | } |
| 2120 | 2264 | ||
| 2121 | #define REG_A4XX_TEX_CONST_3 0x00000003 | 2265 | #define REG_A4XX_TEX_CONST_3 0x00000003 |
| 2122 | #define A4XX_TEX_CONST_3_LAYERSZ__MASK 0x0000000f | 2266 | #define A4XX_TEX_CONST_3_LAYERSZ__MASK 0x00003fff |
| 2123 | #define A4XX_TEX_CONST_3_LAYERSZ__SHIFT 0 | 2267 | #define A4XX_TEX_CONST_3_LAYERSZ__SHIFT 0 |
| 2124 | static inline uint32_t A4XX_TEX_CONST_3_LAYERSZ(uint32_t val) | 2268 | static inline uint32_t A4XX_TEX_CONST_3_LAYERSZ(uint32_t val) |
| 2125 | { | 2269 | { |
| 2126 | return ((val >> 12) << A4XX_TEX_CONST_3_LAYERSZ__SHIFT) & A4XX_TEX_CONST_3_LAYERSZ__MASK; | 2270 | return ((val >> 12) << A4XX_TEX_CONST_3_LAYERSZ__SHIFT) & A4XX_TEX_CONST_3_LAYERSZ__MASK; |
| 2127 | } | 2271 | } |
| 2272 | #define A4XX_TEX_CONST_3_DEPTH__MASK 0x7ffc0000 | ||
| 2273 | #define A4XX_TEX_CONST_3_DEPTH__SHIFT 18 | ||
| 2274 | static inline uint32_t A4XX_TEX_CONST_3_DEPTH(uint32_t val) | ||
| 2275 | { | ||
| 2276 | return ((val) << A4XX_TEX_CONST_3_DEPTH__SHIFT) & A4XX_TEX_CONST_3_DEPTH__MASK; | ||
| 2277 | } | ||
| 2128 | 2278 | ||
| 2129 | #define REG_A4XX_TEX_CONST_4 0x00000004 | 2279 | #define REG_A4XX_TEX_CONST_4 0x00000004 |
| 2130 | #define A4XX_TEX_CONST_4_BASE__MASK 0xffffffff | 2280 | #define A4XX_TEX_CONST_4_LAYERSZ__MASK 0x0000000f |
| 2131 | #define A4XX_TEX_CONST_4_BASE__SHIFT 0 | 2281 | #define A4XX_TEX_CONST_4_LAYERSZ__SHIFT 0 |
| 2282 | static inline uint32_t A4XX_TEX_CONST_4_LAYERSZ(uint32_t val) | ||
| 2283 | { | ||
| 2284 | return ((val >> 12) << A4XX_TEX_CONST_4_LAYERSZ__SHIFT) & A4XX_TEX_CONST_4_LAYERSZ__MASK; | ||
| 2285 | } | ||
| 2286 | #define A4XX_TEX_CONST_4_BASE__MASK 0xffffffe0 | ||
| 2287 | #define A4XX_TEX_CONST_4_BASE__SHIFT 5 | ||
| 2132 | static inline uint32_t A4XX_TEX_CONST_4_BASE(uint32_t val) | 2288 | static inline uint32_t A4XX_TEX_CONST_4_BASE(uint32_t val) |
| 2133 | { | 2289 | { |
| 2134 | return ((val) << A4XX_TEX_CONST_4_BASE__SHIFT) & A4XX_TEX_CONST_4_BASE__MASK; | 2290 | return ((val >> 5) << A4XX_TEX_CONST_4_BASE__SHIFT) & A4XX_TEX_CONST_4_BASE__MASK; |
| 2135 | } | 2291 | } |
| 2136 | 2292 | ||
| 2137 | #define REG_A4XX_TEX_CONST_5 0x00000005 | 2293 | #define REG_A4XX_TEX_CONST_5 0x00000005 |
diff --git a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h index a4b33af9338d..8531beb982e7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_common.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_common.xml.h | |||
| @@ -12,9 +12,9 @@ The rules-ng-ng source files this header was generated from are: | |||
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15085 bytes, from 2014-12-20 21:49:41) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 64344 bytes, from 2014-12-12 20:22:26) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 51069 bytes, from 2014-12-21 15:51:54) |
| 18 | 18 | ||
| 19 | Copyright (C) 2013-2014 by the following authors: | 19 | Copyright (C) 2013-2014 by the following authors: |
| 20 | - Rob Clark <robdclark@gmail.com> (robclark) | 20 | - Rob Clark <robdclark@gmail.com> (robclark) |
diff --git a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h index 6a75cee94d81..6ffc4f6c8af1 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h +++ b/drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h | |||
| @@ -12,9 +12,9 @@ The rules-ng-ng source files this header was generated from are: | |||
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a2xx.xml ( 32901 bytes, from 2014-06-02 15:21:30) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_common.xml ( 10551 bytes, from 2014-11-13 22:44:30) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15053 bytes, from 2014-11-09 15:45:47) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/adreno_pm4.xml ( 15085 bytes, from 2014-12-20 21:49:41) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 63169 bytes, from 2014-11-13 22:44:18) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a3xx.xml ( 64344 bytes, from 2014-12-12 20:22:26) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 49097 bytes, from 2014-11-14 15:38:00) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/adreno/a4xx.xml ( 51069 bytes, from 2014-12-21 15:51:54) |
| 18 | 18 | ||
| 19 | Copyright (C) 2013-2014 by the following authors: | 19 | Copyright (C) 2013-2014 by the following authors: |
| 20 | - Rob Clark <robdclark@gmail.com> (robclark) | 20 | - Rob Clark <robdclark@gmail.com> (robclark) |
| @@ -172,7 +172,9 @@ enum adreno_pm4_type3_packets { | |||
| 172 | CP_DRAW_INDIRECT = 40, | 172 | CP_DRAW_INDIRECT = 40, |
| 173 | CP_DRAW_INDX_INDIRECT = 41, | 173 | CP_DRAW_INDX_INDIRECT = 41, |
| 174 | CP_DRAW_AUTO = 36, | 174 | CP_DRAW_AUTO = 36, |
| 175 | CP_UNKNOWN_19 = 25, | ||
| 175 | CP_UNKNOWN_1A = 26, | 176 | CP_UNKNOWN_1A = 26, |
| 177 | CP_UNKNOWN_4E = 78, | ||
| 176 | CP_WIDE_REG_WRITE = 116, | 178 | CP_WIDE_REG_WRITE = 116, |
| 177 | IN_IB_PREFETCH_END = 23, | 179 | IN_IB_PREFETCH_END = 23, |
| 178 | IN_SUBBLK_PREFETCH = 31, | 180 | IN_SUBBLK_PREFETCH = 31, |
| @@ -203,6 +205,12 @@ enum adreno_state_src { | |||
| 203 | SS_INDIRECT = 4, | 205 | SS_INDIRECT = 4, |
| 204 | }; | 206 | }; |
| 205 | 207 | ||
| 208 | enum a4xx_index_size { | ||
| 209 | INDEX4_SIZE_8_BIT = 0, | ||
| 210 | INDEX4_SIZE_16_BIT = 1, | ||
| 211 | INDEX4_SIZE_32_BIT = 2, | ||
| 212 | }; | ||
| 213 | |||
| 206 | #define REG_CP_LOAD_STATE_0 0x00000000 | 214 | #define REG_CP_LOAD_STATE_0 0x00000000 |
| 207 | #define CP_LOAD_STATE_0_DST_OFF__MASK 0x0000ffff | 215 | #define CP_LOAD_STATE_0_DST_OFF__MASK 0x0000ffff |
| 208 | #define CP_LOAD_STATE_0_DST_OFF__SHIFT 0 | 216 | #define CP_LOAD_STATE_0_DST_OFF__SHIFT 0 |
| @@ -374,29 +382,20 @@ static inline uint32_t CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT(enum pc_di_src_sel va | |||
| 374 | { | 382 | { |
| 375 | return ((val) << CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT__SHIFT) & CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT__MASK; | 383 | return ((val) << CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT__SHIFT) & CP_DRAW_INDX_OFFSET_0_SOURCE_SELECT__MASK; |
| 376 | } | 384 | } |
| 377 | #define CP_DRAW_INDX_OFFSET_0_VIS_CULL__MASK 0x00000700 | 385 | #define CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__MASK 0x00000c00 |
| 378 | #define CP_DRAW_INDX_OFFSET_0_VIS_CULL__SHIFT 8 | 386 | #define CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__SHIFT 10 |
| 379 | static inline uint32_t CP_DRAW_INDX_OFFSET_0_VIS_CULL(enum pc_di_vis_cull_mode val) | 387 | static inline uint32_t CP_DRAW_INDX_OFFSET_0_INDEX_SIZE(enum a4xx_index_size val) |
| 380 | { | ||
| 381 | return ((val) << CP_DRAW_INDX_OFFSET_0_VIS_CULL__SHIFT) & CP_DRAW_INDX_OFFSET_0_VIS_CULL__MASK; | ||
| 382 | } | ||
| 383 | #define CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__MASK 0x00000800 | ||
| 384 | #define CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__SHIFT 11 | ||
| 385 | static inline uint32_t CP_DRAW_INDX_OFFSET_0_INDEX_SIZE(enum pc_di_index_size val) | ||
| 386 | { | 388 | { |
| 387 | return ((val) << CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__SHIFT) & CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__MASK; | 389 | return ((val) << CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__SHIFT) & CP_DRAW_INDX_OFFSET_0_INDEX_SIZE__MASK; |
| 388 | } | 390 | } |
| 389 | #define CP_DRAW_INDX_OFFSET_0_NOT_EOP 0x00001000 | ||
| 390 | #define CP_DRAW_INDX_OFFSET_0_SMALL_INDEX 0x00002000 | ||
| 391 | #define CP_DRAW_INDX_OFFSET_0_PRE_DRAW_INITIATOR_ENABLE 0x00004000 | ||
| 392 | #define CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__MASK 0xffff0000 | ||
| 393 | #define CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__SHIFT 16 | ||
| 394 | static inline uint32_t CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES(uint32_t val) | ||
| 395 | { | ||
| 396 | return ((val) << CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__SHIFT) & CP_DRAW_INDX_OFFSET_0_NUM_INSTANCES__MASK; | ||
| 397 | } | ||
| 398 | 391 | ||
| 399 | #define REG_CP_DRAW_INDX_OFFSET_1 0x00000001 | 392 | #define REG_CP_DRAW_INDX_OFFSET_1 0x00000001 |
| 393 | #define CP_DRAW_INDX_OFFSET_1_NUM_INSTANCES__MASK 0xffffffff | ||
| 394 | #define CP_DRAW_INDX_OFFSET_1_NUM_INSTANCES__SHIFT 0 | ||
| 395 | static inline uint32_t CP_DRAW_INDX_OFFSET_1_NUM_INSTANCES(uint32_t val) | ||
| 396 | { | ||
| 397 | return ((val) << CP_DRAW_INDX_OFFSET_1_NUM_INSTANCES__SHIFT) & CP_DRAW_INDX_OFFSET_1_NUM_INSTANCES__MASK; | ||
| 398 | } | ||
| 400 | 399 | ||
| 401 | #define REG_CP_DRAW_INDX_OFFSET_2 0x00000002 | 400 | #define REG_CP_DRAW_INDX_OFFSET_2 0x00000002 |
| 402 | #define CP_DRAW_INDX_OFFSET_2_NUM_INDICES__MASK 0xffffffff | 401 | #define CP_DRAW_INDX_OFFSET_2_NUM_INDICES__MASK 0xffffffff |
diff --git a/drivers/gpu/drm/msm/dsi/dsi.xml.h b/drivers/gpu/drm/msm/dsi/dsi.xml.h index 448438b759b4..abf1bba520bf 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.xml.h +++ b/drivers/gpu/drm/msm/dsi/dsi.xml.h | |||
| @@ -8,16 +8,17 @@ http://github.com/freedreno/envytools/ | |||
| 8 | git clone https://github.com/freedreno/envytools.git | 8 | git clone https://github.com/freedreno/envytools.git |
| 9 | 9 | ||
| 10 | The rules-ng-ng source files this header was generated from are: | 10 | The rules-ng-ng source files this header was generated from are: |
| 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) | 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49) |
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) |
| 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) | 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) |
| 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) | 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) |
| 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) | 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) |
| 21 | - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) | ||
| 21 | 22 | ||
| 22 | Copyright (C) 2013 by the following authors: | 23 | Copyright (C) 2013 by the following authors: |
| 23 | - Rob Clark <robdclark@gmail.com> (robclark) | 24 | - Rob Clark <robdclark@gmail.com> (robclark) |
diff --git a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h index c102a7f074ac..695f99d4bec2 100644 --- a/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h +++ b/drivers/gpu/drm/msm/dsi/mmss_cc.xml.h | |||
| @@ -8,16 +8,17 @@ http://github.com/freedreno/envytools/ | |||
| 8 | git clone https://github.com/freedreno/envytools.git | 8 | git clone https://github.com/freedreno/envytools.git |
| 9 | 9 | ||
| 10 | The rules-ng-ng source files this header was generated from are: | 10 | The rules-ng-ng source files this header was generated from are: |
| 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) | 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49) |
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) |
| 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) | 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) |
| 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) | 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) |
| 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) | 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) |
| 21 | - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) | ||
| 21 | 22 | ||
| 22 | Copyright (C) 2013-2014 by the following authors: | 23 | Copyright (C) 2013-2014 by the following authors: |
| 23 | - Rob Clark <robdclark@gmail.com> (robclark) | 24 | - Rob Clark <robdclark@gmail.com> (robclark) |
diff --git a/drivers/gpu/drm/msm/dsi/sfpb.xml.h b/drivers/gpu/drm/msm/dsi/sfpb.xml.h index a900134bdf33..50ff9851d73d 100644 --- a/drivers/gpu/drm/msm/dsi/sfpb.xml.h +++ b/drivers/gpu/drm/msm/dsi/sfpb.xml.h | |||
| @@ -8,16 +8,17 @@ http://github.com/freedreno/envytools/ | |||
| 8 | git clone https://github.com/freedreno/envytools.git | 8 | git clone https://github.com/freedreno/envytools.git |
| 9 | 9 | ||
| 10 | The rules-ng-ng source files this header was generated from are: | 10 | The rules-ng-ng source files this header was generated from are: |
| 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) | 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49) |
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) |
| 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) | 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) |
| 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) | 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) |
| 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) | 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) |
| 21 | - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) | ||
| 21 | 22 | ||
| 22 | Copyright (C) 2013 by the following authors: | 23 | Copyright (C) 2013 by the following authors: |
| 23 | - Rob Clark <robdclark@gmail.com> (robclark) | 24 | - Rob Clark <robdclark@gmail.com> (robclark) |
diff --git a/drivers/gpu/drm/msm/edp/edp.c b/drivers/gpu/drm/msm/edp/edp.c new file mode 100644 index 000000000000..0940e84b2821 --- /dev/null +++ b/drivers/gpu/drm/msm/edp/edp.c | |||
| @@ -0,0 +1,208 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 and | ||
| 6 | * only version 2 as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/of_irq.h> | ||
| 15 | #include "edp.h" | ||
| 16 | |||
| 17 | static irqreturn_t edp_irq(int irq, void *dev_id) | ||
| 18 | { | ||
| 19 | struct msm_edp *edp = dev_id; | ||
| 20 | |||
| 21 | /* Process eDP irq */ | ||
| 22 | return msm_edp_ctrl_irq(edp->ctrl); | ||
| 23 | } | ||
| 24 | |||
| 25 | static void edp_destroy(struct platform_device *pdev) | ||
| 26 | { | ||
| 27 | struct msm_edp *edp = platform_get_drvdata(pdev); | ||
| 28 | |||
| 29 | if (!edp) | ||
| 30 | return; | ||
| 31 | |||
| 32 | if (edp->ctrl) { | ||
| 33 | msm_edp_ctrl_destroy(edp->ctrl); | ||
| 34 | edp->ctrl = NULL; | ||
| 35 | } | ||
| 36 | |||
| 37 | platform_set_drvdata(pdev, NULL); | ||
| 38 | } | ||
| 39 | |||
| 40 | /* construct eDP at bind/probe time, grab all the resources. */ | ||
| 41 | static struct msm_edp *edp_init(struct platform_device *pdev) | ||
| 42 | { | ||
| 43 | struct msm_edp *edp = NULL; | ||
| 44 | int ret; | ||
| 45 | |||
| 46 | if (!pdev) { | ||
| 47 | pr_err("no eDP device\n"); | ||
| 48 | ret = -ENXIO; | ||
| 49 | goto fail; | ||
| 50 | } | ||
| 51 | |||
| 52 | edp = devm_kzalloc(&pdev->dev, sizeof(*edp), GFP_KERNEL); | ||
| 53 | if (!edp) { | ||
| 54 | ret = -ENOMEM; | ||
| 55 | goto fail; | ||
| 56 | } | ||
| 57 | DBG("eDP probed=%p", edp); | ||
| 58 | |||
| 59 | edp->pdev = pdev; | ||
| 60 | platform_set_drvdata(pdev, edp); | ||
| 61 | |||
| 62 | ret = msm_edp_ctrl_init(edp); | ||
| 63 | if (ret) | ||
| 64 | goto fail; | ||
| 65 | |||
| 66 | return edp; | ||
| 67 | |||
| 68 | fail: | ||
| 69 | if (edp) | ||
| 70 | edp_destroy(pdev); | ||
| 71 | |||
| 72 | return ERR_PTR(ret); | ||
| 73 | } | ||
| 74 | |||
| 75 | static int edp_bind(struct device *dev, struct device *master, void *data) | ||
| 76 | { | ||
| 77 | struct drm_device *drm = dev_get_drvdata(master); | ||
| 78 | struct msm_drm_private *priv = drm->dev_private; | ||
| 79 | struct msm_edp *edp; | ||
| 80 | |||
| 81 | DBG(""); | ||
| 82 | edp = edp_init(to_platform_device(dev)); | ||
| 83 | if (IS_ERR(edp)) | ||
| 84 | return PTR_ERR(edp); | ||
| 85 | priv->edp = edp; | ||
| 86 | |||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | static void edp_unbind(struct device *dev, struct device *master, void *data) | ||
| 91 | { | ||
| 92 | struct drm_device *drm = dev_get_drvdata(master); | ||
| 93 | struct msm_drm_private *priv = drm->dev_private; | ||
| 94 | |||
| 95 | DBG(""); | ||
| 96 | if (priv->edp) { | ||
| 97 | edp_destroy(to_platform_device(dev)); | ||
| 98 | priv->edp = NULL; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | static const struct component_ops edp_ops = { | ||
| 103 | .bind = edp_bind, | ||
| 104 | .unbind = edp_unbind, | ||
| 105 | }; | ||
| 106 | |||
| 107 | static int edp_dev_probe(struct platform_device *pdev) | ||
| 108 | { | ||
| 109 | DBG(""); | ||
| 110 | return component_add(&pdev->dev, &edp_ops); | ||
| 111 | } | ||
| 112 | |||
| 113 | static int edp_dev_remove(struct platform_device *pdev) | ||
| 114 | { | ||
| 115 | DBG(""); | ||
| 116 | component_del(&pdev->dev, &edp_ops); | ||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | static const struct of_device_id dt_match[] = { | ||
| 121 | { .compatible = "qcom,mdss-edp" }, | ||
| 122 | {} | ||
| 123 | }; | ||
| 124 | |||
| 125 | static struct platform_driver edp_driver = { | ||
| 126 | .probe = edp_dev_probe, | ||
| 127 | .remove = edp_dev_remove, | ||
| 128 | .driver = { | ||
| 129 | .name = "msm_edp", | ||
| 130 | .of_match_table = dt_match, | ||
| 131 | }, | ||
| 132 | }; | ||
| 133 | |||
| 134 | void __init msm_edp_register(void) | ||
| 135 | { | ||
| 136 | DBG(""); | ||
| 137 | platform_driver_register(&edp_driver); | ||
| 138 | } | ||
| 139 | |||
| 140 | void __exit msm_edp_unregister(void) | ||
| 141 | { | ||
| 142 | DBG(""); | ||
| 143 | platform_driver_unregister(&edp_driver); | ||
| 144 | } | ||
| 145 | |||
| 146 | /* Second part of initialization, the drm/kms level modeset_init */ | ||
| 147 | int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, | ||
| 148 | struct drm_encoder *encoder) | ||
| 149 | { | ||
| 150 | struct platform_device *pdev = edp->pdev; | ||
| 151 | struct msm_drm_private *priv = dev->dev_private; | ||
| 152 | int ret; | ||
| 153 | |||
| 154 | edp->encoder = encoder; | ||
| 155 | edp->dev = dev; | ||
| 156 | |||
| 157 | edp->bridge = msm_edp_bridge_init(edp); | ||
| 158 | if (IS_ERR(edp->bridge)) { | ||
| 159 | ret = PTR_ERR(edp->bridge); | ||
| 160 | dev_err(dev->dev, "failed to create eDP bridge: %d\n", ret); | ||
| 161 | edp->bridge = NULL; | ||
| 162 | goto fail; | ||
| 163 | } | ||
| 164 | |||
| 165 | edp->connector = msm_edp_connector_init(edp); | ||
| 166 | if (IS_ERR(edp->connector)) { | ||
| 167 | ret = PTR_ERR(edp->connector); | ||
| 168 | dev_err(dev->dev, "failed to create eDP connector: %d\n", ret); | ||
| 169 | edp->connector = NULL; | ||
| 170 | goto fail; | ||
| 171 | } | ||
| 172 | |||
| 173 | edp->irq = irq_of_parse_and_map(pdev->dev.of_node, 0); | ||
| 174 | if (edp->irq < 0) { | ||
| 175 | ret = edp->irq; | ||
| 176 | dev_err(dev->dev, "failed to get IRQ: %d\n", ret); | ||
| 177 | goto fail; | ||
| 178 | } | ||
| 179 | |||
| 180 | ret = devm_request_irq(&pdev->dev, edp->irq, | ||
| 181 | edp_irq, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, | ||
| 182 | "edp_isr", edp); | ||
| 183 | if (ret < 0) { | ||
| 184 | dev_err(dev->dev, "failed to request IRQ%u: %d\n", | ||
| 185 | edp->irq, ret); | ||
| 186 | goto fail; | ||
| 187 | } | ||
| 188 | |||
| 189 | encoder->bridge = edp->bridge; | ||
| 190 | |||
| 191 | priv->bridges[priv->num_bridges++] = edp->bridge; | ||
| 192 | priv->connectors[priv->num_connectors++] = edp->connector; | ||
| 193 | |||
| 194 | return 0; | ||
| 195 | |||
| 196 | fail: | ||
| 197 | /* bridge/connector are normally destroyed by drm */ | ||
| 198 | if (edp->bridge) { | ||
| 199 | edp_bridge_destroy(edp->bridge); | ||
| 200 | edp->bridge = NULL; | ||
| 201 | } | ||
| 202 | if (edp->connector) { | ||
| 203 | edp->connector->funcs->destroy(edp->connector); | ||
| 204 | edp->connector = NULL; | ||
| 205 | } | ||
| 206 | |||
| 207 | return ret; | ||
| 208 | } | ||
diff --git a/drivers/gpu/drm/msm/edp/edp.h b/drivers/gpu/drm/msm/edp/edp.h new file mode 100644 index 000000000000..ba5bedde5241 --- /dev/null +++ b/drivers/gpu/drm/msm/edp/edp.h | |||
| @@ -0,0 +1,85 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 and | ||
| 6 | * only version 2 as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef __EDP_CONNECTOR_H__ | ||
| 15 | #define __EDP_CONNECTOR_H__ | ||
| 16 | |||
| 17 | #include <linux/i2c.h> | ||
| 18 | #include <linux/interrupt.h> | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/platform_device.h> | ||
| 21 | |||
| 22 | #include "drm_crtc.h" | ||
| 23 | #include "drm_dp_helper.h" | ||
| 24 | #include "msm_drv.h" | ||
| 25 | |||
| 26 | #define edp_read(offset) msm_readl((offset)) | ||
| 27 | #define edp_write(offset, data) msm_writel((data), (offset)) | ||
| 28 | |||
| 29 | struct edp_ctrl; | ||
| 30 | struct edp_aux; | ||
| 31 | struct edp_phy; | ||
| 32 | |||
| 33 | struct msm_edp { | ||
| 34 | struct drm_device *dev; | ||
| 35 | struct platform_device *pdev; | ||
| 36 | |||
| 37 | struct drm_connector *connector; | ||
| 38 | struct drm_bridge *bridge; | ||
| 39 | |||
| 40 | /* the encoder we are hooked to (outside of eDP block) */ | ||
| 41 | struct drm_encoder *encoder; | ||
| 42 | |||
| 43 | struct edp_ctrl *ctrl; | ||
| 44 | |||
| 45 | int irq; | ||
| 46 | }; | ||
| 47 | |||
| 48 | /* eDP bridge */ | ||
| 49 | struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp); | ||
| 50 | void edp_bridge_destroy(struct drm_bridge *bridge); | ||
| 51 | |||
| 52 | /* eDP connector */ | ||
| 53 | struct drm_connector *msm_edp_connector_init(struct msm_edp *edp); | ||
| 54 | |||
| 55 | /* AUX */ | ||
| 56 | void *msm_edp_aux_init(struct device *dev, void __iomem *regbase, | ||
| 57 | struct drm_dp_aux **drm_aux); | ||
| 58 | void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux); | ||
| 59 | irqreturn_t msm_edp_aux_irq(struct edp_aux *aux, u32 isr); | ||
| 60 | void msm_edp_aux_ctrl(struct edp_aux *aux, int enable); | ||
| 61 | |||
| 62 | /* Phy */ | ||
| 63 | bool msm_edp_phy_ready(struct edp_phy *phy); | ||
| 64 | void msm_edp_phy_ctrl(struct edp_phy *phy, int enable); | ||
| 65 | void msm_edp_phy_vm_pe_init(struct edp_phy *phy); | ||
| 66 | void msm_edp_phy_vm_pe_cfg(struct edp_phy *phy, u32 v0, u32 v1); | ||
| 67 | void msm_edp_phy_lane_power_ctrl(struct edp_phy *phy, bool up, u32 max_lane); | ||
| 68 | void *msm_edp_phy_init(struct device *dev, void __iomem *regbase); | ||
| 69 | |||
| 70 | /* Ctrl */ | ||
| 71 | irqreturn_t msm_edp_ctrl_irq(struct edp_ctrl *ctrl); | ||
| 72 | void msm_edp_ctrl_power(struct edp_ctrl *ctrl, bool on); | ||
| 73 | int msm_edp_ctrl_init(struct msm_edp *edp); | ||
| 74 | void msm_edp_ctrl_destroy(struct edp_ctrl *ctrl); | ||
| 75 | bool msm_edp_ctrl_panel_connected(struct edp_ctrl *ctrl); | ||
| 76 | int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl, | ||
| 77 | struct drm_connector *connector, struct edid **edid); | ||
| 78 | int msm_edp_ctrl_timing_cfg(struct edp_ctrl *ctrl, | ||
| 79 | const struct drm_display_mode *mode, | ||
| 80 | const struct drm_display_info *info); | ||
| 81 | /* @pixel_rate is in kHz */ | ||
| 82 | bool msm_edp_ctrl_pixel_clock_valid(struct edp_ctrl *ctrl, | ||
| 83 | u32 pixel_rate, u32 *pm, u32 *pn); | ||
| 84 | |||
| 85 | #endif /* __EDP_CONNECTOR_H__ */ | ||
diff --git a/drivers/gpu/drm/msm/edp/edp.xml.h b/drivers/gpu/drm/msm/edp/edp.xml.h new file mode 100644 index 000000000000..a29f1df15143 --- /dev/null +++ b/drivers/gpu/drm/msm/edp/edp.xml.h | |||
| @@ -0,0 +1,292 @@ | |||
| 1 | #ifndef EDP_XML | ||
| 2 | #define EDP_XML | ||
| 3 | |||
| 4 | /* Autogenerated file, DO NOT EDIT manually! | ||
| 5 | |||
| 6 | This file was generated by the rules-ng-ng headergen tool in this git repository: | ||
| 7 | http://github.com/freedreno/envytools/ | ||
| 8 | git clone https://github.com/freedreno/envytools.git | ||
| 9 | |||
| 10 | The rules-ng-ng source files this header was generated from are: | ||
| 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49) | ||
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | ||
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) | ||
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) | ||
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) | ||
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) | ||
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) | ||
| 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) | ||
| 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) | ||
| 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) | ||
| 21 | - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) | ||
| 22 | |||
| 23 | Copyright (C) 2013-2014 by the following authors: | ||
| 24 | - Rob Clark <robdclark@gmail.com> (robclark) | ||
| 25 | |||
| 26 | Permission is hereby granted, free of charge, to any person obtaining | ||
| 27 | a copy of this software and associated documentation files (the | ||
| 28 | "Software"), to deal in the Software without restriction, including | ||
| 29 | without limitation the rights to use, copy, modify, merge, publish, | ||
| 30 | distribute, sublicense, and/or sell copies of the Software, and to | ||
| 31 | permit persons to whom the Software is furnished to do so, subject to | ||
| 32 | the following conditions: | ||
| 33 | |||
| 34 | The above copyright notice and this permission notice (including the | ||
| 35 | next paragraph) shall be included in all copies or substantial | ||
| 36 | portions of the Software. | ||
| 37 | |||
| 38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
| 39 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
| 40 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
| 41 | IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE | ||
| 42 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
| 43 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
| 44 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
| 45 | */ | ||
| 46 | |||
| 47 | |||
| 48 | enum edp_color_depth { | ||
| 49 | EDP_6BIT = 0, | ||
| 50 | EDP_8BIT = 1, | ||
| 51 | EDP_10BIT = 2, | ||
| 52 | EDP_12BIT = 3, | ||
| 53 | EDP_16BIT = 4, | ||
| 54 | }; | ||
| 55 | |||
| 56 | enum edp_component_format { | ||
| 57 | EDP_RGB = 0, | ||
| 58 | EDP_YUV422 = 1, | ||
| 59 | EDP_YUV444 = 2, | ||
| 60 | }; | ||
| 61 | |||
| 62 | #define REG_EDP_MAINLINK_CTRL 0x00000004 | ||
| 63 | #define EDP_MAINLINK_CTRL_ENABLE 0x00000001 | ||
| 64 | #define EDP_MAINLINK_CTRL_RESET 0x00000002 | ||
| 65 | |||
| 66 | #define REG_EDP_STATE_CTRL 0x00000008 | ||
| 67 | #define EDP_STATE_CTRL_TRAIN_PATTERN_1 0x00000001 | ||
| 68 | #define EDP_STATE_CTRL_TRAIN_PATTERN_2 0x00000002 | ||
| 69 | #define EDP_STATE_CTRL_TRAIN_PATTERN_3 0x00000004 | ||
| 70 | #define EDP_STATE_CTRL_SYMBOL_ERR_RATE_MEAS 0x00000008 | ||
| 71 | #define EDP_STATE_CTRL_PRBS7 0x00000010 | ||
| 72 | #define EDP_STATE_CTRL_CUSTOM_80_BIT_PATTERN 0x00000020 | ||
| 73 | #define EDP_STATE_CTRL_SEND_VIDEO 0x00000040 | ||
| 74 | #define EDP_STATE_CTRL_PUSH_IDLE 0x00000080 | ||
| 75 | |||
| 76 | #define REG_EDP_CONFIGURATION_CTRL 0x0000000c | ||
| 77 | #define EDP_CONFIGURATION_CTRL_SYNC_CLK 0x00000001 | ||
| 78 | #define EDP_CONFIGURATION_CTRL_STATIC_MVID 0x00000002 | ||
| 79 | #define EDP_CONFIGURATION_CTRL_PROGRESSIVE 0x00000004 | ||
| 80 | #define EDP_CONFIGURATION_CTRL_LANES__MASK 0x00000030 | ||
| 81 | #define EDP_CONFIGURATION_CTRL_LANES__SHIFT 4 | ||
| 82 | static inline uint32_t EDP_CONFIGURATION_CTRL_LANES(uint32_t val) | ||
| 83 | { | ||
| 84 | return ((val) << EDP_CONFIGURATION_CTRL_LANES__SHIFT) & EDP_CONFIGURATION_CTRL_LANES__MASK; | ||
| 85 | } | ||
| 86 | #define EDP_CONFIGURATION_CTRL_ENHANCED_FRAMING 0x00000040 | ||
| 87 | #define EDP_CONFIGURATION_CTRL_COLOR__MASK 0x00000100 | ||
| 88 | #define EDP_CONFIGURATION_CTRL_COLOR__SHIFT 8 | ||
| 89 | static inline uint32_t EDP_CONFIGURATION_CTRL_COLOR(enum edp_color_depth val) | ||
| 90 | { | ||
| 91 | return ((val) << EDP_CONFIGURATION_CTRL_COLOR__SHIFT) & EDP_CONFIGURATION_CTRL_COLOR__MASK; | ||
| 92 | } | ||
| 93 | |||
| 94 | #define REG_EDP_SOFTWARE_MVID 0x00000014 | ||
| 95 | |||
| 96 | #define REG_EDP_SOFTWARE_NVID 0x00000018 | ||
| 97 | |||
| 98 | #define REG_EDP_TOTAL_HOR_VER 0x0000001c | ||
| 99 | #define EDP_TOTAL_HOR_VER_HORIZ__MASK 0x0000ffff | ||
| 100 | #define EDP_TOTAL_HOR_VER_HORIZ__SHIFT 0 | ||
| 101 | static inline uint32_t EDP_TOTAL_HOR_VER_HORIZ(uint32_t val) | ||
| 102 | { | ||
| 103 | return ((val) << EDP_TOTAL_HOR_VER_HORIZ__SHIFT) & EDP_TOTAL_HOR_VER_HORIZ__MASK; | ||
| 104 | } | ||
| 105 | #define EDP_TOTAL_HOR_VER_VERT__MASK 0xffff0000 | ||
| 106 | #define EDP_TOTAL_HOR_VER_VERT__SHIFT 16 | ||
| 107 | static inline uint32_t EDP_TOTAL_HOR_VER_VERT(uint32_t val) | ||
| 108 | { | ||
| 109 | return ((val) << EDP_TOTAL_HOR_VER_VERT__SHIFT) & EDP_TOTAL_HOR_VER_VERT__MASK; | ||
| 110 | } | ||
| 111 | |||
| 112 | #define REG_EDP_START_HOR_VER_FROM_SYNC 0x00000020 | ||
| 113 | #define EDP_START_HOR_VER_FROM_SYNC_HORIZ__MASK 0x0000ffff | ||
| 114 | #define EDP_START_HOR_VER_FROM_SYNC_HORIZ__SHIFT 0 | ||
| 115 | static inline uint32_t EDP_START_HOR_VER_FROM_SYNC_HORIZ(uint32_t val) | ||
| 116 | { | ||
| 117 | return ((val) << EDP_START_HOR_VER_FROM_SYNC_HORIZ__SHIFT) & EDP_START_HOR_VER_FROM_SYNC_HORIZ__MASK; | ||
| 118 | } | ||
| 119 | #define EDP_START_HOR_VER_FROM_SYNC_VERT__MASK 0xffff0000 | ||
| 120 | #define EDP_START_HOR_VER_FROM_SYNC_VERT__SHIFT 16 | ||
| 121 | static inline uint32_t EDP_START_HOR_VER_FROM_SYNC_VERT(uint32_t val) | ||
| 122 | { | ||
| 123 | return ((val) << EDP_START_HOR_VER_FROM_SYNC_VERT__SHIFT) & EDP_START_HOR_VER_FROM_SYNC_VERT__MASK; | ||
| 124 | } | ||
| 125 | |||
| 126 | #define REG_EDP_HSYNC_VSYNC_WIDTH_POLARITY 0x00000024 | ||
| 127 | #define EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ__MASK 0x00007fff | ||
| 128 | #define EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ__SHIFT 0 | ||
| 129 | static inline uint32_t EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ(uint32_t val) | ||
| 130 | { | ||
| 131 | return ((val) << EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ__SHIFT) & EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ__MASK; | ||
| 132 | } | ||
| 133 | #define EDP_HSYNC_VSYNC_WIDTH_POLARITY_NHSYNC 0x00008000 | ||
| 134 | #define EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT__MASK 0x7fff0000 | ||
| 135 | #define EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT__SHIFT 16 | ||
| 136 | static inline uint32_t EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT(uint32_t val) | ||
| 137 | { | ||
| 138 | return ((val) << EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT__SHIFT) & EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT__MASK; | ||
| 139 | } | ||
| 140 | #define EDP_HSYNC_VSYNC_WIDTH_POLARITY_NVSYNC 0x80000000 | ||
| 141 | |||
| 142 | #define REG_EDP_ACTIVE_HOR_VER 0x00000028 | ||
| 143 | #define EDP_ACTIVE_HOR_VER_HORIZ__MASK 0x0000ffff | ||
| 144 | #define EDP_ACTIVE_HOR_VER_HORIZ__SHIFT 0 | ||
| 145 | static inline uint32_t EDP_ACTIVE_HOR_VER_HORIZ(uint32_t val) | ||
| 146 | { | ||
| 147 | return ((val) << EDP_ACTIVE_HOR_VER_HORIZ__SHIFT) & EDP_ACTIVE_HOR_VER_HORIZ__MASK; | ||
| 148 | } | ||
| 149 | #define EDP_ACTIVE_HOR_VER_VERT__MASK 0xffff0000 | ||
| 150 | #define EDP_ACTIVE_HOR_VER_VERT__SHIFT 16 | ||
| 151 | static inline uint32_t EDP_ACTIVE_HOR_VER_VERT(uint32_t val) | ||
| 152 | { | ||
| 153 | return ((val) << EDP_ACTIVE_HOR_VER_VERT__SHIFT) & EDP_ACTIVE_HOR_VER_VERT__MASK; | ||
| 154 | } | ||
| 155 | |||
| 156 | #define REG_EDP_MISC1_MISC0 0x0000002c | ||
| 157 | #define EDP_MISC1_MISC0_MISC0__MASK 0x000000ff | ||
| 158 | #define EDP_MISC1_MISC0_MISC0__SHIFT 0 | ||
| 159 | static inline uint32_t EDP_MISC1_MISC0_MISC0(uint32_t val) | ||
| 160 | { | ||
| 161 | return ((val) << EDP_MISC1_MISC0_MISC0__SHIFT) & EDP_MISC1_MISC0_MISC0__MASK; | ||
| 162 | } | ||
| 163 | #define EDP_MISC1_MISC0_SYNC 0x00000001 | ||
| 164 | #define EDP_MISC1_MISC0_COMPONENT_FORMAT__MASK 0x00000006 | ||
| 165 | #define EDP_MISC1_MISC0_COMPONENT_FORMAT__SHIFT 1 | ||
| 166 | static inline uint32_t EDP_MISC1_MISC0_COMPONENT_FORMAT(enum edp_component_format val) | ||
| 167 | { | ||
| 168 | return ((val) << EDP_MISC1_MISC0_COMPONENT_FORMAT__SHIFT) & EDP_MISC1_MISC0_COMPONENT_FORMAT__MASK; | ||
| 169 | } | ||
| 170 | #define EDP_MISC1_MISC0_CEA 0x00000008 | ||
| 171 | #define EDP_MISC1_MISC0_BT709_5 0x00000010 | ||
| 172 | #define EDP_MISC1_MISC0_COLOR__MASK 0x000000e0 | ||
| 173 | #define EDP_MISC1_MISC0_COLOR__SHIFT 5 | ||
| 174 | static inline uint32_t EDP_MISC1_MISC0_COLOR(enum edp_color_depth val) | ||
| 175 | { | ||
| 176 | return ((val) << EDP_MISC1_MISC0_COLOR__SHIFT) & EDP_MISC1_MISC0_COLOR__MASK; | ||
| 177 | } | ||
| 178 | #define EDP_MISC1_MISC0_MISC1__MASK 0x0000ff00 | ||
| 179 | #define EDP_MISC1_MISC0_MISC1__SHIFT 8 | ||
| 180 | static inline uint32_t EDP_MISC1_MISC0_MISC1(uint32_t val) | ||
| 181 | { | ||
| 182 | return ((val) << EDP_MISC1_MISC0_MISC1__SHIFT) & EDP_MISC1_MISC0_MISC1__MASK; | ||
| 183 | } | ||
| 184 | #define EDP_MISC1_MISC0_INTERLACED_ODD 0x00000100 | ||
| 185 | #define EDP_MISC1_MISC0_STEREO__MASK 0x00000600 | ||
| 186 | #define EDP_MISC1_MISC0_STEREO__SHIFT 9 | ||
| 187 | static inline uint32_t EDP_MISC1_MISC0_STEREO(uint32_t val) | ||
| 188 | { | ||
| 189 | return ((val) << EDP_MISC1_MISC0_STEREO__SHIFT) & EDP_MISC1_MISC0_STEREO__MASK; | ||
| 190 | } | ||
| 191 | |||
| 192 | #define REG_EDP_PHY_CTRL 0x00000074 | ||
| 193 | #define EDP_PHY_CTRL_SW_RESET_PLL 0x00000001 | ||
| 194 | #define EDP_PHY_CTRL_SW_RESET 0x00000004 | ||
| 195 | |||
| 196 | #define REG_EDP_MAINLINK_READY 0x00000084 | ||
| 197 | #define EDP_MAINLINK_READY_TRAIN_PATTERN_1_READY 0x00000008 | ||
| 198 | #define EDP_MAINLINK_READY_TRAIN_PATTERN_2_READY 0x00000010 | ||
| 199 | #define EDP_MAINLINK_READY_TRAIN_PATTERN_3_READY 0x00000020 | ||
| 200 | |||
| 201 | #define REG_EDP_AUX_CTRL 0x00000300 | ||
| 202 | #define EDP_AUX_CTRL_ENABLE 0x00000001 | ||
| 203 | #define EDP_AUX_CTRL_RESET 0x00000002 | ||
| 204 | |||
| 205 | #define REG_EDP_INTERRUPT_REG_1 0x00000308 | ||
| 206 | #define EDP_INTERRUPT_REG_1_HPD 0x00000001 | ||
| 207 | #define EDP_INTERRUPT_REG_1_HPD_ACK 0x00000002 | ||
| 208 | #define EDP_INTERRUPT_REG_1_HPD_EN 0x00000004 | ||
| 209 | #define EDP_INTERRUPT_REG_1_AUX_I2C_DONE 0x00000008 | ||
| 210 | #define EDP_INTERRUPT_REG_1_AUX_I2C_DONE_ACK 0x00000010 | ||
| 211 | #define EDP_INTERRUPT_REG_1_AUX_I2C_DONE_EN 0x00000020 | ||
| 212 | #define EDP_INTERRUPT_REG_1_WRONG_ADDR 0x00000040 | ||
| 213 | #define EDP_INTERRUPT_REG_1_WRONG_ADDR_ACK 0x00000080 | ||
| 214 | #define EDP_INTERRUPT_REG_1_WRONG_ADDR_EN 0x00000100 | ||
| 215 | #define EDP_INTERRUPT_REG_1_TIMEOUT 0x00000200 | ||
| 216 | #define EDP_INTERRUPT_REG_1_TIMEOUT_ACK 0x00000400 | ||
| 217 | #define EDP_INTERRUPT_REG_1_TIMEOUT_EN 0x00000800 | ||
| 218 | #define EDP_INTERRUPT_REG_1_NACK_DEFER 0x00001000 | ||
| 219 | #define EDP_INTERRUPT_REG_1_NACK_DEFER_ACK 0x00002000 | ||
| 220 | #define EDP_INTERRUPT_REG_1_NACK_DEFER_EN 0x00004000 | ||
| 221 | #define EDP_INTERRUPT_REG_1_WRONG_DATA_CNT 0x00008000 | ||
| 222 | #define EDP_INTERRUPT_REG_1_WRONG_DATA_CNT_ACK 0x00010000 | ||
| 223 | #define EDP_INTERRUPT_REG_1_WRONG_DATA_CNT_EN 0x00020000 | ||
| 224 | #define EDP_INTERRUPT_REG_1_I2C_NACK 0x00040000 | ||
| 225 | #define EDP_INTERRUPT_REG_1_I2C_NACK_ACK 0x00080000 | ||
| 226 | #define EDP_INTERRUPT_REG_1_I2C_NACK_EN 0x00100000 | ||
| 227 | #define EDP_INTERRUPT_REG_1_I2C_DEFER 0x00200000 | ||
| 228 | #define EDP_INTERRUPT_REG_1_I2C_DEFER_ACK 0x00400000 | ||
| 229 | #define EDP_INTERRUPT_REG_1_I2C_DEFER_EN 0x00800000 | ||
| 230 | #define EDP_INTERRUPT_REG_1_PLL_UNLOCK 0x01000000 | ||
| 231 | #define EDP_INTERRUPT_REG_1_PLL_UNLOCK_ACK 0x02000000 | ||
| 232 | #define EDP_INTERRUPT_REG_1_PLL_UNLOCK_EN 0x04000000 | ||
| 233 | #define EDP_INTERRUPT_REG_1_AUX_ERROR 0x08000000 | ||
| 234 | #define EDP_INTERRUPT_REG_1_AUX_ERROR_ACK 0x10000000 | ||
| 235 | #define EDP_INTERRUPT_REG_1_AUX_ERROR_EN 0x20000000 | ||
| 236 | |||
| 237 | #define REG_EDP_INTERRUPT_REG_2 0x0000030c | ||
| 238 | #define EDP_INTERRUPT_REG_2_READY_FOR_VIDEO 0x00000001 | ||
| 239 | #define EDP_INTERRUPT_REG_2_READY_FOR_VIDEO_ACK 0x00000002 | ||
| 240 | #define EDP_INTERRUPT_REG_2_READY_FOR_VIDEO_EN 0x00000004 | ||
| 241 | #define EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT 0x00000008 | ||
| 242 | #define EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT_ACK 0x00000010 | ||
| 243 | #define EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT_EN 0x00000020 | ||
| 244 | #define EDP_INTERRUPT_REG_2_FRAME_END 0x00000200 | ||
| 245 | #define EDP_INTERRUPT_REG_2_FRAME_END_ACK 0x00000080 | ||
| 246 | #define EDP_INTERRUPT_REG_2_FRAME_END_EN 0x00000100 | ||
| 247 | #define EDP_INTERRUPT_REG_2_CRC_UPDATED 0x00000200 | ||
| 248 | #define EDP_INTERRUPT_REG_2_CRC_UPDATED_ACK 0x00000400 | ||
| 249 | #define EDP_INTERRUPT_REG_2_CRC_UPDATED_EN 0x00000800 | ||
| 250 | |||
| 251 | #define REG_EDP_INTERRUPT_TRANS_NUM 0x00000310 | ||
| 252 | |||
| 253 | #define REG_EDP_AUX_DATA 0x00000314 | ||
| 254 | #define EDP_AUX_DATA_READ 0x00000001 | ||
| 255 | #define EDP_AUX_DATA_DATA__MASK 0x0000ff00 | ||
| 256 | #define EDP_AUX_DATA_DATA__SHIFT 8 | ||
| 257 | static inline uint32_t EDP_AUX_DATA_DATA(uint32_t val) | ||
| 258 | { | ||
| 259 | return ((val) << EDP_AUX_DATA_DATA__SHIFT) & EDP_AUX_DATA_DATA__MASK; | ||
| 260 | } | ||
| 261 | #define EDP_AUX_DATA_INDEX__MASK 0x00ff0000 | ||
| 262 | #define EDP_AUX_DATA_INDEX__SHIFT 16 | ||
| 263 | static inline uint32_t EDP_AUX_DATA_INDEX(uint32_t val) | ||
| 264 | { | ||
| 265 | return ((val) << EDP_AUX_DATA_INDEX__SHIFT) & EDP_AUX_DATA_INDEX__MASK; | ||
| 266 | } | ||
| 267 | #define EDP_AUX_DATA_INDEX_WRITE 0x80000000 | ||
| 268 | |||
| 269 | #define REG_EDP_AUX_TRANS_CTRL 0x00000318 | ||
| 270 | #define EDP_AUX_TRANS_CTRL_I2C 0x00000100 | ||
| 271 | #define EDP_AUX_TRANS_CTRL_GO 0x00000200 | ||
| 272 | |||
| 273 | #define REG_EDP_AUX_STATUS 0x00000324 | ||
| 274 | |||
| 275 | static inline uint32_t REG_EDP_PHY_LN(uint32_t i0) { return 0x00000400 + 0x40*i0; } | ||
| 276 | |||
| 277 | static inline uint32_t REG_EDP_PHY_LN_PD_CTL(uint32_t i0) { return 0x00000404 + 0x40*i0; } | ||
| 278 | |||
| 279 | #define REG_EDP_PHY_GLB_VM_CFG0 0x00000510 | ||
| 280 | |||
| 281 | #define REG_EDP_PHY_GLB_VM_CFG1 0x00000514 | ||
| 282 | |||
| 283 | #define REG_EDP_PHY_GLB_MISC9 0x00000518 | ||
| 284 | |||
| 285 | #define REG_EDP_PHY_GLB_CFG 0x00000528 | ||
| 286 | |||
| 287 | #define REG_EDP_PHY_GLB_PD_CTL 0x0000052c | ||
| 288 | |||
| 289 | #define REG_EDP_PHY_GLB_PHY_STATUS 0x00000598 | ||
| 290 | |||
| 291 | |||
| 292 | #endif /* EDP_XML */ | ||
diff --git a/drivers/gpu/drm/msm/edp/edp_aux.c b/drivers/gpu/drm/msm/edp/edp_aux.c new file mode 100644 index 000000000000..5f5a84f6074c --- /dev/null +++ b/drivers/gpu/drm/msm/edp/edp_aux.c | |||
| @@ -0,0 +1,268 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 and | ||
| 6 | * only version 2 as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include "edp.h" | ||
| 15 | #include "edp.xml.h" | ||
| 16 | |||
| 17 | #define AUX_CMD_FIFO_LEN 144 | ||
| 18 | #define AUX_CMD_NATIVE_MAX 16 | ||
| 19 | #define AUX_CMD_I2C_MAX 128 | ||
| 20 | |||
| 21 | #define EDP_INTR_AUX_I2C_ERR \ | ||
| 22 | (EDP_INTERRUPT_REG_1_WRONG_ADDR | EDP_INTERRUPT_REG_1_TIMEOUT | \ | ||
| 23 | EDP_INTERRUPT_REG_1_NACK_DEFER | EDP_INTERRUPT_REG_1_WRONG_DATA_CNT | \ | ||
| 24 | EDP_INTERRUPT_REG_1_I2C_NACK | EDP_INTERRUPT_REG_1_I2C_DEFER) | ||
| 25 | #define EDP_INTR_TRANS_STATUS \ | ||
| 26 | (EDP_INTERRUPT_REG_1_AUX_I2C_DONE | EDP_INTR_AUX_I2C_ERR) | ||
| 27 | |||
| 28 | struct edp_aux { | ||
| 29 | void __iomem *base; | ||
| 30 | bool msg_err; | ||
| 31 | |||
| 32 | struct completion msg_comp; | ||
| 33 | |||
| 34 | /* To prevent the message transaction routine from reentry. */ | ||
| 35 | struct mutex msg_mutex; | ||
| 36 | |||
| 37 | struct drm_dp_aux drm_aux; | ||
| 38 | }; | ||
| 39 | #define to_edp_aux(x) container_of(x, struct edp_aux, drm_aux) | ||
| 40 | |||
| 41 | static int edp_msg_fifo_tx(struct edp_aux *aux, struct drm_dp_aux_msg *msg) | ||
| 42 | { | ||
| 43 | u32 data[4]; | ||
| 44 | u32 reg, len; | ||
| 45 | bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ); | ||
| 46 | bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ); | ||
| 47 | u8 *msgdata = msg->buffer; | ||
| 48 | int i; | ||
| 49 | |||
| 50 | if (read) | ||
| 51 | len = 4; | ||
| 52 | else | ||
| 53 | len = msg->size + 4; | ||
| 54 | |||
| 55 | /* | ||
| 56 | * cmd fifo only has depth of 144 bytes | ||
| 57 | */ | ||
| 58 | if (len > AUX_CMD_FIFO_LEN) | ||
| 59 | return -EINVAL; | ||
| 60 | |||
| 61 | /* Pack cmd and write to HW */ | ||
| 62 | data[0] = (msg->address >> 16) & 0xf; /* addr[19:16] */ | ||
| 63 | if (read) | ||
| 64 | data[0] |= BIT(4); /* R/W */ | ||
| 65 | |||
| 66 | data[1] = (msg->address >> 8) & 0xff; /* addr[15:8] */ | ||
| 67 | data[2] = msg->address & 0xff; /* addr[7:0] */ | ||
| 68 | data[3] = (msg->size - 1) & 0xff; /* len[7:0] */ | ||
| 69 | |||
| 70 | for (i = 0; i < len; i++) { | ||
| 71 | reg = (i < 4) ? data[i] : msgdata[i - 4]; | ||
| 72 | reg = EDP_AUX_DATA_DATA(reg); /* index = 0, write */ | ||
| 73 | if (i == 0) | ||
| 74 | reg |= EDP_AUX_DATA_INDEX_WRITE; | ||
| 75 | edp_write(aux->base + REG_EDP_AUX_DATA, reg); | ||
| 76 | } | ||
| 77 | |||
| 78 | reg = 0; /* Transaction number is always 1 */ | ||
| 79 | if (!native) /* i2c */ | ||
| 80 | reg |= EDP_AUX_TRANS_CTRL_I2C; | ||
| 81 | |||
| 82 | reg |= EDP_AUX_TRANS_CTRL_GO; | ||
| 83 | edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, reg); | ||
| 84 | |||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | |||
| 88 | static int edp_msg_fifo_rx(struct edp_aux *aux, struct drm_dp_aux_msg *msg) | ||
| 89 | { | ||
| 90 | u32 data; | ||
| 91 | u8 *dp; | ||
| 92 | int i; | ||
| 93 | u32 len = msg->size; | ||
| 94 | |||
| 95 | edp_write(aux->base + REG_EDP_AUX_DATA, | ||
| 96 | EDP_AUX_DATA_INDEX_WRITE | EDP_AUX_DATA_READ); /* index = 0 */ | ||
| 97 | |||
| 98 | dp = msg->buffer; | ||
| 99 | |||
| 100 | /* discard first byte */ | ||
| 101 | data = edp_read(aux->base + REG_EDP_AUX_DATA); | ||
| 102 | for (i = 0; i < len; i++) { | ||
| 103 | data = edp_read(aux->base + REG_EDP_AUX_DATA); | ||
| 104 | dp[i] = (u8)((data >> 8) & 0xff); | ||
| 105 | } | ||
| 106 | |||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | /* | ||
| 111 | * This function does the real job to process an AUX transaction. | ||
| 112 | * It will call msm_edp_aux_ctrl() function to reset the AUX channel, | ||
| 113 | * if the waiting is timeout. | ||
| 114 | * The caller who triggers the transaction should avoid the | ||
| 115 | * msm_edp_aux_ctrl() running concurrently in other threads, i.e. | ||
| 116 | * start transaction only when AUX channel is fully enabled. | ||
| 117 | */ | ||
| 118 | ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux, struct drm_dp_aux_msg *msg) | ||
| 119 | { | ||
| 120 | struct edp_aux *aux = to_edp_aux(drm_aux); | ||
| 121 | ssize_t ret; | ||
| 122 | bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ); | ||
| 123 | bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ); | ||
| 124 | |||
| 125 | /* Ignore address only message */ | ||
| 126 | if ((msg->size == 0) || (msg->buffer == NULL)) { | ||
| 127 | msg->reply = native ? | ||
| 128 | DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK; | ||
| 129 | return msg->size; | ||
| 130 | } | ||
| 131 | |||
| 132 | /* msg sanity check */ | ||
| 133 | if ((native && (msg->size > AUX_CMD_NATIVE_MAX)) || | ||
| 134 | (msg->size > AUX_CMD_I2C_MAX)) { | ||
| 135 | pr_err("%s: invalid msg: size(%d), request(%x)\n", | ||
| 136 | __func__, msg->size, msg->request); | ||
| 137 | return -EINVAL; | ||
| 138 | } | ||
| 139 | |||
| 140 | mutex_lock(&aux->msg_mutex); | ||
| 141 | |||
| 142 | aux->msg_err = false; | ||
| 143 | reinit_completion(&aux->msg_comp); | ||
| 144 | |||
| 145 | ret = edp_msg_fifo_tx(aux, msg); | ||
| 146 | if (ret < 0) | ||
| 147 | goto unlock_exit; | ||
| 148 | |||
| 149 | DBG("wait_for_completion"); | ||
| 150 | ret = wait_for_completion_timeout(&aux->msg_comp, 300); | ||
| 151 | if (ret <= 0) { | ||
| 152 | /* | ||
| 153 | * Clear GO and reset AUX channel | ||
| 154 | * to cancel the current transaction. | ||
| 155 | */ | ||
| 156 | edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0); | ||
| 157 | msm_edp_aux_ctrl(aux, 1); | ||
| 158 | pr_err("%s: aux timeout, %d\n", __func__, ret); | ||
| 159 | goto unlock_exit; | ||
| 160 | } | ||
| 161 | DBG("completion"); | ||
| 162 | |||
| 163 | if (!aux->msg_err) { | ||
| 164 | if (read) { | ||
| 165 | ret = edp_msg_fifo_rx(aux, msg); | ||
| 166 | if (ret < 0) | ||
| 167 | goto unlock_exit; | ||
| 168 | } | ||
| 169 | |||
| 170 | msg->reply = native ? | ||
| 171 | DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK; | ||
| 172 | } else { | ||
| 173 | /* Reply defer to retry */ | ||
| 174 | msg->reply = native ? | ||
| 175 | DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER; | ||
| 176 | /* | ||
| 177 | * The sleep time in caller is not long enough to make sure | ||
| 178 | * our H/W completes transactions. Add more defer time here. | ||
| 179 | */ | ||
| 180 | msleep(100); | ||
| 181 | } | ||
| 182 | |||
| 183 | /* Return requested size for success or retry */ | ||
| 184 | ret = msg->size; | ||
| 185 | |||
| 186 | unlock_exit: | ||
| 187 | mutex_unlock(&aux->msg_mutex); | ||
| 188 | return ret; | ||
| 189 | } | ||
| 190 | |||
| 191 | void *msm_edp_aux_init(struct device *dev, void __iomem *regbase, | ||
| 192 | struct drm_dp_aux **drm_aux) | ||
| 193 | { | ||
| 194 | struct edp_aux *aux = NULL; | ||
| 195 | int ret; | ||
| 196 | |||
| 197 | DBG(""); | ||
| 198 | aux = devm_kzalloc(dev, sizeof(*aux), GFP_KERNEL); | ||
| 199 | if (!aux) | ||
| 200 | return NULL; | ||
| 201 | |||
| 202 | aux->base = regbase; | ||
| 203 | mutex_init(&aux->msg_mutex); | ||
| 204 | init_completion(&aux->msg_comp); | ||
| 205 | |||
| 206 | aux->drm_aux.name = "msm_edp_aux"; | ||
| 207 | aux->drm_aux.dev = dev; | ||
| 208 | aux->drm_aux.transfer = edp_aux_transfer; | ||
| 209 | ret = drm_dp_aux_register(&aux->drm_aux); | ||
| 210 | if (ret) { | ||
| 211 | pr_err("%s: failed to register drm aux: %d\n", __func__, ret); | ||
| 212 | mutex_destroy(&aux->msg_mutex); | ||
| 213 | } | ||
| 214 | |||
| 215 | if (drm_aux && aux) | ||
| 216 | *drm_aux = &aux->drm_aux; | ||
| 217 | |||
| 218 | return aux; | ||
| 219 | } | ||
| 220 | |||
| 221 | void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux) | ||
| 222 | { | ||
| 223 | if (aux) { | ||
| 224 | drm_dp_aux_unregister(&aux->drm_aux); | ||
| 225 | mutex_destroy(&aux->msg_mutex); | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | irqreturn_t msm_edp_aux_irq(struct edp_aux *aux, u32 isr) | ||
| 230 | { | ||
| 231 | if (isr & EDP_INTR_TRANS_STATUS) { | ||
| 232 | DBG("isr=%x", isr); | ||
| 233 | edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0); | ||
| 234 | |||
| 235 | if (isr & EDP_INTR_AUX_I2C_ERR) | ||
| 236 | aux->msg_err = true; | ||
| 237 | else | ||
| 238 | aux->msg_err = false; | ||
| 239 | |||
| 240 | complete(&aux->msg_comp); | ||
| 241 | } | ||
| 242 | |||
| 243 | return IRQ_HANDLED; | ||
| 244 | } | ||
| 245 | |||
| 246 | void msm_edp_aux_ctrl(struct edp_aux *aux, int enable) | ||
| 247 | { | ||
| 248 | u32 data; | ||
| 249 | |||
| 250 | DBG("enable=%d", enable); | ||
| 251 | data = edp_read(aux->base + REG_EDP_AUX_CTRL); | ||
| 252 | |||
| 253 | if (enable) { | ||
| 254 | data |= EDP_AUX_CTRL_RESET; | ||
| 255 | edp_write(aux->base + REG_EDP_AUX_CTRL, data); | ||
| 256 | /* Make sure full reset */ | ||
| 257 | wmb(); | ||
| 258 | usleep_range(500, 1000); | ||
| 259 | |||
| 260 | data &= ~EDP_AUX_CTRL_RESET; | ||
| 261 | data |= EDP_AUX_CTRL_ENABLE; | ||
| 262 | edp_write(aux->base + REG_EDP_AUX_CTRL, data); | ||
| 263 | } else { | ||
| 264 | data &= ~EDP_AUX_CTRL_ENABLE; | ||
| 265 | edp_write(aux->base + REG_EDP_AUX_CTRL, data); | ||
| 266 | } | ||
| 267 | } | ||
| 268 | |||
diff --git a/drivers/gpu/drm/msm/edp/edp_bridge.c b/drivers/gpu/drm/msm/edp/edp_bridge.c new file mode 100644 index 000000000000..2bc73f82f3f5 --- /dev/null +++ b/drivers/gpu/drm/msm/edp/edp_bridge.c | |||
| @@ -0,0 +1,120 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 and | ||
| 6 | * only version 2 as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include "edp.h" | ||
| 15 | |||
| 16 | struct edp_bridge { | ||
| 17 | struct drm_bridge base; | ||
| 18 | struct msm_edp *edp; | ||
| 19 | }; | ||
| 20 | #define to_edp_bridge(x) container_of(x, struct edp_bridge, base) | ||
| 21 | |||
| 22 | void edp_bridge_destroy(struct drm_bridge *bridge) | ||
| 23 | { | ||
| 24 | } | ||
| 25 | |||
| 26 | static void edp_bridge_pre_enable(struct drm_bridge *bridge) | ||
| 27 | { | ||
| 28 | struct edp_bridge *edp_bridge = to_edp_bridge(bridge); | ||
| 29 | struct msm_edp *edp = edp_bridge->edp; | ||
| 30 | |||
| 31 | DBG(""); | ||
| 32 | msm_edp_ctrl_power(edp->ctrl, true); | ||
| 33 | } | ||
| 34 | |||
| 35 | static void edp_bridge_enable(struct drm_bridge *bridge) | ||
| 36 | { | ||
| 37 | DBG(""); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void edp_bridge_disable(struct drm_bridge *bridge) | ||
| 41 | { | ||
| 42 | DBG(""); | ||
| 43 | } | ||
| 44 | |||
| 45 | static void edp_bridge_post_disable(struct drm_bridge *bridge) | ||
| 46 | { | ||
| 47 | struct edp_bridge *edp_bridge = to_edp_bridge(bridge); | ||
| 48 | struct msm_edp *edp = edp_bridge->edp; | ||
| 49 | |||
| 50 | DBG(""); | ||
| 51 | msm_edp_ctrl_power(edp->ctrl, false); | ||
| 52 | } | ||
| 53 | |||
| 54 | static void edp_bridge_mode_set(struct drm_bridge *bridge, | ||
| 55 | struct drm_display_mode *mode, | ||
| 56 | struct drm_display_mode *adjusted_mode) | ||
| 57 | { | ||
| 58 | struct drm_device *dev = bridge->dev; | ||
| 59 | struct drm_connector *connector; | ||
| 60 | struct edp_bridge *edp_bridge = to_edp_bridge(bridge); | ||
| 61 | struct msm_edp *edp = edp_bridge->edp; | ||
| 62 | |||
| 63 | DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", | ||
| 64 | mode->base.id, mode->name, | ||
| 65 | mode->vrefresh, mode->clock, | ||
| 66 | mode->hdisplay, mode->hsync_start, | ||
| 67 | mode->hsync_end, mode->htotal, | ||
| 68 | mode->vdisplay, mode->vsync_start, | ||
| 69 | mode->vsync_end, mode->vtotal, | ||
| 70 | mode->type, mode->flags); | ||
| 71 | |||
| 72 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 73 | if ((connector->encoder != NULL) && | ||
| 74 | (connector->encoder->bridge == bridge)) { | ||
| 75 | msm_edp_ctrl_timing_cfg(edp->ctrl, | ||
| 76 | adjusted_mode, &connector->display_info); | ||
| 77 | break; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | static const struct drm_bridge_funcs edp_bridge_funcs = { | ||
| 83 | .pre_enable = edp_bridge_pre_enable, | ||
| 84 | .enable = edp_bridge_enable, | ||
| 85 | .disable = edp_bridge_disable, | ||
| 86 | .post_disable = edp_bridge_post_disable, | ||
| 87 | .mode_set = edp_bridge_mode_set, | ||
| 88 | }; | ||
| 89 | |||
| 90 | /* initialize bridge */ | ||
| 91 | struct drm_bridge *msm_edp_bridge_init(struct msm_edp *edp) | ||
| 92 | { | ||
| 93 | struct drm_bridge *bridge = NULL; | ||
| 94 | struct edp_bridge *edp_bridge; | ||
| 95 | int ret; | ||
| 96 | |||
| 97 | edp_bridge = devm_kzalloc(edp->dev->dev, | ||
| 98 | sizeof(*edp_bridge), GFP_KERNEL); | ||
| 99 | if (!edp_bridge) { | ||
| 100 | ret = -ENOMEM; | ||
| 101 | goto fail; | ||
| 102 | } | ||
| 103 | |||
| 104 | edp_bridge->edp = edp; | ||
| 105 | |||
| 106 | bridge = &edp_bridge->base; | ||
| 107 | bridge->funcs = &edp_bridge_funcs; | ||
| 108 | |||
| 109 | ret = drm_bridge_attach(edp->dev, bridge); | ||
| 110 | if (ret) | ||
| 111 | goto fail; | ||
| 112 | |||
| 113 | return bridge; | ||
| 114 | |||
| 115 | fail: | ||
| 116 | if (bridge) | ||
| 117 | edp_bridge_destroy(bridge); | ||
| 118 | |||
| 119 | return ERR_PTR(ret); | ||
| 120 | } | ||
diff --git a/drivers/gpu/drm/msm/edp/edp_connector.c b/drivers/gpu/drm/msm/edp/edp_connector.c new file mode 100644 index 000000000000..d8812e84da54 --- /dev/null +++ b/drivers/gpu/drm/msm/edp/edp_connector.c | |||
| @@ -0,0 +1,161 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 and | ||
| 6 | * only version 2 as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include "drm/drm_edid.h" | ||
| 15 | #include "msm_kms.h" | ||
| 16 | #include "edp.h" | ||
| 17 | |||
| 18 | struct edp_connector { | ||
| 19 | struct drm_connector base; | ||
| 20 | struct msm_edp *edp; | ||
| 21 | }; | ||
| 22 | #define to_edp_connector(x) container_of(x, struct edp_connector, base) | ||
| 23 | |||
| 24 | static enum drm_connector_status edp_connector_detect( | ||
| 25 | struct drm_connector *connector, bool force) | ||
| 26 | { | ||
| 27 | struct edp_connector *edp_connector = to_edp_connector(connector); | ||
| 28 | struct msm_edp *edp = edp_connector->edp; | ||
| 29 | |||
| 30 | DBG(""); | ||
| 31 | return msm_edp_ctrl_panel_connected(edp->ctrl) ? | ||
| 32 | connector_status_connected : connector_status_disconnected; | ||
| 33 | } | ||
| 34 | |||
| 35 | static void edp_connector_destroy(struct drm_connector *connector) | ||
| 36 | { | ||
| 37 | struct edp_connector *edp_connector = to_edp_connector(connector); | ||
| 38 | |||
| 39 | DBG(""); | ||
| 40 | drm_connector_unregister(connector); | ||
| 41 | drm_connector_cleanup(connector); | ||
| 42 | |||
| 43 | kfree(edp_connector); | ||
| 44 | } | ||
| 45 | |||
| 46 | static int edp_connector_get_modes(struct drm_connector *connector) | ||
| 47 | { | ||
| 48 | struct edp_connector *edp_connector = to_edp_connector(connector); | ||
| 49 | struct msm_edp *edp = edp_connector->edp; | ||
| 50 | |||
| 51 | struct edid *drm_edid = NULL; | ||
| 52 | int ret = 0; | ||
| 53 | |||
| 54 | DBG(""); | ||
| 55 | ret = msm_edp_ctrl_get_panel_info(edp->ctrl, connector, &drm_edid); | ||
| 56 | if (ret) | ||
| 57 | return ret; | ||
| 58 | |||
| 59 | drm_mode_connector_update_edid_property(connector, drm_edid); | ||
| 60 | if (drm_edid) | ||
| 61 | ret = drm_add_edid_modes(connector, drm_edid); | ||
| 62 | |||
| 63 | return ret; | ||
| 64 | } | ||
| 65 | |||
| 66 | static int edp_connector_mode_valid(struct drm_connector *connector, | ||
| 67 | struct drm_display_mode *mode) | ||
| 68 | { | ||
| 69 | struct edp_connector *edp_connector = to_edp_connector(connector); | ||
| 70 | struct msm_edp *edp = edp_connector->edp; | ||
| 71 | struct msm_drm_private *priv = connector->dev->dev_private; | ||
| 72 | struct msm_kms *kms = priv->kms; | ||
| 73 | long actual, requested; | ||
| 74 | |||
| 75 | requested = 1000 * mode->clock; | ||
| 76 | actual = kms->funcs->round_pixclk(kms, | ||
| 77 | requested, edp_connector->edp->encoder); | ||
| 78 | |||
| 79 | DBG("requested=%ld, actual=%ld", requested, actual); | ||
| 80 | if (actual != requested) | ||
| 81 | return MODE_CLOCK_RANGE; | ||
| 82 | |||
| 83 | if (!msm_edp_ctrl_pixel_clock_valid( | ||
| 84 | edp->ctrl, mode->clock, NULL, NULL)) | ||
| 85 | return MODE_CLOCK_RANGE; | ||
| 86 | |||
| 87 | /* Invalidate all modes if color format is not supported */ | ||
| 88 | if (connector->display_info.bpc > 8) | ||
| 89 | return MODE_BAD; | ||
| 90 | |||
| 91 | return MODE_OK; | ||
| 92 | } | ||
| 93 | |||
| 94 | static struct drm_encoder * | ||
| 95 | edp_connector_best_encoder(struct drm_connector *connector) | ||
| 96 | { | ||
| 97 | struct edp_connector *edp_connector = to_edp_connector(connector); | ||
| 98 | |||
| 99 | DBG(""); | ||
| 100 | return edp_connector->edp->encoder; | ||
| 101 | } | ||
| 102 | |||
| 103 | static const struct drm_connector_funcs edp_connector_funcs = { | ||
| 104 | .dpms = drm_atomic_helper_connector_dpms, | ||
| 105 | .detect = edp_connector_detect, | ||
| 106 | .fill_modes = drm_helper_probe_single_connector_modes, | ||
| 107 | .destroy = edp_connector_destroy, | ||
| 108 | .reset = drm_atomic_helper_connector_reset, | ||
| 109 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | ||
| 110 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | ||
| 111 | }; | ||
| 112 | |||
| 113 | static const struct drm_connector_helper_funcs edp_connector_helper_funcs = { | ||
| 114 | .get_modes = edp_connector_get_modes, | ||
| 115 | .mode_valid = edp_connector_mode_valid, | ||
| 116 | .best_encoder = edp_connector_best_encoder, | ||
| 117 | }; | ||
| 118 | |||
| 119 | /* initialize connector */ | ||
| 120 | struct drm_connector *msm_edp_connector_init(struct msm_edp *edp) | ||
| 121 | { | ||
| 122 | struct drm_connector *connector = NULL; | ||
| 123 | struct edp_connector *edp_connector; | ||
| 124 | int ret; | ||
| 125 | |||
| 126 | edp_connector = kzalloc(sizeof(*edp_connector), GFP_KERNEL); | ||
| 127 | if (!edp_connector) { | ||
| 128 | ret = -ENOMEM; | ||
| 129 | goto fail; | ||
| 130 | } | ||
| 131 | |||
| 132 | edp_connector->edp = edp; | ||
| 133 | |||
| 134 | connector = &edp_connector->base; | ||
| 135 | |||
| 136 | ret = drm_connector_init(edp->dev, connector, &edp_connector_funcs, | ||
| 137 | DRM_MODE_CONNECTOR_eDP); | ||
| 138 | if (ret) | ||
| 139 | goto fail; | ||
| 140 | |||
| 141 | drm_connector_helper_add(connector, &edp_connector_helper_funcs); | ||
| 142 | |||
| 143 | /* We don't support HPD, so only poll status until connected. */ | ||
| 144 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
| 145 | |||
| 146 | /* Display driver doesn't support interlace now. */ | ||
| 147 | connector->interlace_allowed = false; | ||
| 148 | connector->doublescan_allowed = false; | ||
| 149 | |||
| 150 | ret = drm_connector_register(connector); | ||
| 151 | if (ret) | ||
| 152 | goto fail; | ||
| 153 | |||
| 154 | return connector; | ||
| 155 | |||
| 156 | fail: | ||
| 157 | if (connector) | ||
| 158 | edp_connector_destroy(connector); | ||
| 159 | |||
| 160 | return ERR_PTR(ret); | ||
| 161 | } | ||
diff --git a/drivers/gpu/drm/msm/edp/edp_ctrl.c b/drivers/gpu/drm/msm/edp/edp_ctrl.c new file mode 100644 index 000000000000..3e246210c46f --- /dev/null +++ b/drivers/gpu/drm/msm/edp/edp_ctrl.c | |||
| @@ -0,0 +1,1373 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 and | ||
| 6 | * only version 2 as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/clk.h> | ||
| 15 | #include <linux/gpio/consumer.h> | ||
| 16 | #include <linux/regulator/consumer.h> | ||
| 17 | |||
| 18 | #include "drm_crtc.h" | ||
| 19 | #include "drm_dp_helper.h" | ||
| 20 | #include "drm_edid.h" | ||
| 21 | #include "edp.h" | ||
| 22 | #include "edp.xml.h" | ||
| 23 | |||
| 24 | #define VDDA_MIN_UV 1800000 /* uV units */ | ||
| 25 | #define VDDA_MAX_UV 1800000 /* uV units */ | ||
| 26 | #define VDDA_UA_ON_LOAD 100000 /* uA units */ | ||
| 27 | #define VDDA_UA_OFF_LOAD 100 /* uA units */ | ||
| 28 | |||
| 29 | #define DPCD_LINK_VOLTAGE_MAX 4 | ||
| 30 | #define DPCD_LINK_PRE_EMPHASIS_MAX 4 | ||
| 31 | |||
| 32 | #define EDP_LINK_BW_MAX DP_LINK_BW_2_7 | ||
| 33 | |||
| 34 | /* Link training return value */ | ||
| 35 | #define EDP_TRAIN_FAIL -1 | ||
| 36 | #define EDP_TRAIN_SUCCESS 0 | ||
| 37 | #define EDP_TRAIN_RECONFIG 1 | ||
| 38 | |||
| 39 | #define EDP_CLK_MASK_AHB BIT(0) | ||
| 40 | #define EDP_CLK_MASK_AUX BIT(1) | ||
| 41 | #define EDP_CLK_MASK_LINK BIT(2) | ||
| 42 | #define EDP_CLK_MASK_PIXEL BIT(3) | ||
| 43 | #define EDP_CLK_MASK_MDP_CORE BIT(4) | ||
| 44 | #define EDP_CLK_MASK_LINK_CHAN (EDP_CLK_MASK_LINK | EDP_CLK_MASK_PIXEL) | ||
| 45 | #define EDP_CLK_MASK_AUX_CHAN \ | ||
| 46 | (EDP_CLK_MASK_AHB | EDP_CLK_MASK_AUX | EDP_CLK_MASK_MDP_CORE) | ||
| 47 | #define EDP_CLK_MASK_ALL (EDP_CLK_MASK_AUX_CHAN | EDP_CLK_MASK_LINK_CHAN) | ||
| 48 | |||
| 49 | #define EDP_BACKLIGHT_MAX 255 | ||
| 50 | |||
| 51 | #define EDP_INTR_STATUS1 \ | ||
| 52 | (EDP_INTERRUPT_REG_1_HPD | EDP_INTERRUPT_REG_1_AUX_I2C_DONE | \ | ||
| 53 | EDP_INTERRUPT_REG_1_WRONG_ADDR | EDP_INTERRUPT_REG_1_TIMEOUT | \ | ||
| 54 | EDP_INTERRUPT_REG_1_NACK_DEFER | EDP_INTERRUPT_REG_1_WRONG_DATA_CNT | \ | ||
| 55 | EDP_INTERRUPT_REG_1_I2C_NACK | EDP_INTERRUPT_REG_1_I2C_DEFER | \ | ||
| 56 | EDP_INTERRUPT_REG_1_PLL_UNLOCK | EDP_INTERRUPT_REG_1_AUX_ERROR) | ||
| 57 | #define EDP_INTR_MASK1 (EDP_INTR_STATUS1 << 2) | ||
| 58 | #define EDP_INTR_STATUS2 \ | ||
| 59 | (EDP_INTERRUPT_REG_2_READY_FOR_VIDEO | \ | ||
| 60 | EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT | \ | ||
| 61 | EDP_INTERRUPT_REG_2_FRAME_END | EDP_INTERRUPT_REG_2_CRC_UPDATED) | ||
| 62 | #define EDP_INTR_MASK2 (EDP_INTR_STATUS2 << 2) | ||
| 63 | |||
| 64 | struct edp_ctrl { | ||
| 65 | struct platform_device *pdev; | ||
| 66 | |||
| 67 | void __iomem *base; | ||
| 68 | |||
| 69 | /* regulators */ | ||
| 70 | struct regulator *vdda_vreg; | ||
| 71 | struct regulator *lvl_vreg; | ||
| 72 | |||
| 73 | /* clocks */ | ||
| 74 | struct clk *aux_clk; | ||
| 75 | struct clk *pixel_clk; | ||
| 76 | struct clk *ahb_clk; | ||
| 77 | struct clk *link_clk; | ||
| 78 | struct clk *mdp_core_clk; | ||
| 79 | |||
| 80 | /* gpios */ | ||
| 81 | struct gpio_desc *panel_en_gpio; | ||
| 82 | struct gpio_desc *panel_hpd_gpio; | ||
| 83 | |||
| 84 | /* completion and mutex */ | ||
| 85 | struct completion idle_comp; | ||
| 86 | struct mutex dev_mutex; /* To protect device power status */ | ||
| 87 | |||
| 88 | /* work queue */ | ||
| 89 | struct work_struct on_work; | ||
| 90 | struct work_struct off_work; | ||
| 91 | struct workqueue_struct *workqueue; | ||
| 92 | |||
| 93 | /* Interrupt register lock */ | ||
| 94 | spinlock_t irq_lock; | ||
| 95 | |||
| 96 | bool edp_connected; | ||
| 97 | bool power_on; | ||
| 98 | |||
| 99 | /* edid raw data */ | ||
| 100 | struct edid *edid; | ||
| 101 | |||
| 102 | struct drm_dp_link dp_link; | ||
| 103 | struct drm_dp_aux *drm_aux; | ||
| 104 | |||
| 105 | /* dpcd raw data */ | ||
| 106 | u8 dpcd[DP_RECEIVER_CAP_SIZE]; | ||
| 107 | |||
| 108 | /* Link status */ | ||
| 109 | u8 link_rate; | ||
| 110 | u8 lane_cnt; | ||
| 111 | u8 v_level; | ||
| 112 | u8 p_level; | ||
| 113 | |||
| 114 | /* Timing status */ | ||
| 115 | u8 interlaced; | ||
| 116 | u32 pixel_rate; /* in kHz */ | ||
| 117 | u32 color_depth; | ||
| 118 | |||
| 119 | struct edp_aux *aux; | ||
| 120 | struct edp_phy *phy; | ||
| 121 | }; | ||
| 122 | |||
| 123 | struct edp_pixel_clk_div { | ||
| 124 | u32 rate; /* in kHz */ | ||
| 125 | u32 m; | ||
| 126 | u32 n; | ||
| 127 | }; | ||
| 128 | |||
| 129 | #define EDP_PIXEL_CLK_NUM 8 | ||
| 130 | static const struct edp_pixel_clk_div clk_divs[2][EDP_PIXEL_CLK_NUM] = { | ||
| 131 | { /* Link clock = 162MHz, source clock = 810MHz */ | ||
| 132 | {119000, 31, 211}, /* WSXGA+ 1680x1050@60Hz CVT */ | ||
| 133 | {130250, 32, 199}, /* UXGA 1600x1200@60Hz CVT */ | ||
| 134 | {148500, 11, 60}, /* FHD 1920x1080@60Hz */ | ||
| 135 | {154000, 50, 263}, /* WUXGA 1920x1200@60Hz CVT */ | ||
| 136 | {209250, 31, 120}, /* QXGA 2048x1536@60Hz CVT */ | ||
| 137 | {268500, 119, 359}, /* WQXGA 2560x1600@60Hz CVT */ | ||
| 138 | {138530, 33, 193}, /* AUO B116HAN03.0 Panel */ | ||
| 139 | {141400, 48, 275}, /* AUO B133HTN01.2 Panel */ | ||
| 140 | }, | ||
| 141 | { /* Link clock = 270MHz, source clock = 675MHz */ | ||
| 142 | {119000, 52, 295}, /* WSXGA+ 1680x1050@60Hz CVT */ | ||
| 143 | {130250, 11, 57}, /* UXGA 1600x1200@60Hz CVT */ | ||
| 144 | {148500, 11, 50}, /* FHD 1920x1080@60Hz */ | ||
| 145 | {154000, 47, 206}, /* WUXGA 1920x1200@60Hz CVT */ | ||
| 146 | {209250, 31, 100}, /* QXGA 2048x1536@60Hz CVT */ | ||
| 147 | {268500, 107, 269}, /* WQXGA 2560x1600@60Hz CVT */ | ||
| 148 | {138530, 63, 307}, /* AUO B116HAN03.0 Panel */ | ||
| 149 | {141400, 53, 253}, /* AUO B133HTN01.2 Panel */ | ||
| 150 | }, | ||
| 151 | }; | ||
| 152 | |||
| 153 | static int edp_clk_init(struct edp_ctrl *ctrl) | ||
| 154 | { | ||
| 155 | struct device *dev = &ctrl->pdev->dev; | ||
| 156 | int ret; | ||
| 157 | |||
| 158 | ctrl->aux_clk = devm_clk_get(dev, "core_clk"); | ||
| 159 | if (IS_ERR(ctrl->aux_clk)) { | ||
| 160 | ret = PTR_ERR(ctrl->aux_clk); | ||
| 161 | pr_err("%s: Can't find aux_clk, %d\n", __func__, ret); | ||
| 162 | ctrl->aux_clk = NULL; | ||
| 163 | return ret; | ||
| 164 | } | ||
| 165 | |||
| 166 | ctrl->pixel_clk = devm_clk_get(dev, "pixel_clk"); | ||
| 167 | if (IS_ERR(ctrl->pixel_clk)) { | ||
| 168 | ret = PTR_ERR(ctrl->pixel_clk); | ||
| 169 | pr_err("%s: Can't find pixel_clk, %d\n", __func__, ret); | ||
| 170 | ctrl->pixel_clk = NULL; | ||
| 171 | return ret; | ||
| 172 | } | ||
| 173 | |||
| 174 | ctrl->ahb_clk = devm_clk_get(dev, "iface_clk"); | ||
| 175 | if (IS_ERR(ctrl->ahb_clk)) { | ||
| 176 | ret = PTR_ERR(ctrl->ahb_clk); | ||
| 177 | pr_err("%s: Can't find ahb_clk, %d\n", __func__, ret); | ||
| 178 | ctrl->ahb_clk = NULL; | ||
| 179 | return ret; | ||
| 180 | } | ||
| 181 | |||
| 182 | ctrl->link_clk = devm_clk_get(dev, "link_clk"); | ||
| 183 | if (IS_ERR(ctrl->link_clk)) { | ||
| 184 | ret = PTR_ERR(ctrl->link_clk); | ||
| 185 | pr_err("%s: Can't find link_clk, %d\n", __func__, ret); | ||
| 186 | ctrl->link_clk = NULL; | ||
| 187 | return ret; | ||
| 188 | } | ||
| 189 | |||
| 190 | /* need mdp core clock to receive irq */ | ||
| 191 | ctrl->mdp_core_clk = devm_clk_get(dev, "mdp_core_clk"); | ||
| 192 | if (IS_ERR(ctrl->mdp_core_clk)) { | ||
| 193 | ret = PTR_ERR(ctrl->mdp_core_clk); | ||
| 194 | pr_err("%s: Can't find mdp_core_clk, %d\n", __func__, ret); | ||
| 195 | ctrl->mdp_core_clk = NULL; | ||
| 196 | return ret; | ||
| 197 | } | ||
| 198 | |||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | |||
| 202 | static int edp_clk_enable(struct edp_ctrl *ctrl, u32 clk_mask) | ||
| 203 | { | ||
| 204 | int ret; | ||
| 205 | |||
| 206 | DBG("mask=%x", clk_mask); | ||
| 207 | /* ahb_clk should be enabled first */ | ||
| 208 | if (clk_mask & EDP_CLK_MASK_AHB) { | ||
| 209 | ret = clk_prepare_enable(ctrl->ahb_clk); | ||
| 210 | if (ret) { | ||
| 211 | pr_err("%s: Failed to enable ahb clk\n", __func__); | ||
| 212 | goto f0; | ||
| 213 | } | ||
| 214 | } | ||
| 215 | if (clk_mask & EDP_CLK_MASK_AUX) { | ||
| 216 | ret = clk_set_rate(ctrl->aux_clk, 19200000); | ||
| 217 | if (ret) { | ||
| 218 | pr_err("%s: Failed to set rate aux clk\n", __func__); | ||
| 219 | goto f1; | ||
| 220 | } | ||
| 221 | ret = clk_prepare_enable(ctrl->aux_clk); | ||
| 222 | if (ret) { | ||
| 223 | pr_err("%s: Failed to enable aux clk\n", __func__); | ||
| 224 | goto f1; | ||
| 225 | } | ||
| 226 | } | ||
| 227 | /* Need to set rate and enable link_clk prior to pixel_clk */ | ||
| 228 | if (clk_mask & EDP_CLK_MASK_LINK) { | ||
| 229 | DBG("edp->link_clk, set_rate %ld", | ||
| 230 | (unsigned long)ctrl->link_rate * 27000000); | ||
| 231 | ret = clk_set_rate(ctrl->link_clk, | ||
| 232 | (unsigned long)ctrl->link_rate * 27000000); | ||
| 233 | if (ret) { | ||
| 234 | pr_err("%s: Failed to set rate to link clk\n", | ||
| 235 | __func__); | ||
| 236 | goto f2; | ||
| 237 | } | ||
| 238 | |||
| 239 | ret = clk_prepare_enable(ctrl->link_clk); | ||
| 240 | if (ret) { | ||
| 241 | pr_err("%s: Failed to enable link clk\n", __func__); | ||
| 242 | goto f2; | ||
| 243 | } | ||
| 244 | } | ||
| 245 | if (clk_mask & EDP_CLK_MASK_PIXEL) { | ||
| 246 | DBG("edp->pixel_clk, set_rate %ld", | ||
| 247 | (unsigned long)ctrl->pixel_rate * 1000); | ||
| 248 | ret = clk_set_rate(ctrl->pixel_clk, | ||
| 249 | (unsigned long)ctrl->pixel_rate * 1000); | ||
| 250 | if (ret) { | ||
| 251 | pr_err("%s: Failed to set rate to pixel clk\n", | ||
| 252 | __func__); | ||
| 253 | goto f3; | ||
| 254 | } | ||
| 255 | |||
| 256 | ret = clk_prepare_enable(ctrl->pixel_clk); | ||
| 257 | if (ret) { | ||
| 258 | pr_err("%s: Failed to enable pixel clk\n", __func__); | ||
| 259 | goto f3; | ||
| 260 | } | ||
| 261 | } | ||
| 262 | if (clk_mask & EDP_CLK_MASK_MDP_CORE) { | ||
| 263 | ret = clk_prepare_enable(ctrl->mdp_core_clk); | ||
| 264 | if (ret) { | ||
| 265 | pr_err("%s: Failed to enable mdp core clk\n", __func__); | ||
| 266 | goto f4; | ||
| 267 | } | ||
| 268 | } | ||
| 269 | |||
| 270 | return 0; | ||
| 271 | |||
| 272 | f4: | ||
| 273 | if (clk_mask & EDP_CLK_MASK_PIXEL) | ||
| 274 | clk_disable_unprepare(ctrl->pixel_clk); | ||
| 275 | f3: | ||
| 276 | if (clk_mask & EDP_CLK_MASK_LINK) | ||
| 277 | clk_disable_unprepare(ctrl->link_clk); | ||
| 278 | f2: | ||
| 279 | if (clk_mask & EDP_CLK_MASK_AUX) | ||
| 280 | clk_disable_unprepare(ctrl->aux_clk); | ||
| 281 | f1: | ||
| 282 | if (clk_mask & EDP_CLK_MASK_AHB) | ||
| 283 | clk_disable_unprepare(ctrl->ahb_clk); | ||
| 284 | f0: | ||
| 285 | return ret; | ||
| 286 | } | ||
| 287 | |||
| 288 | static void edp_clk_disable(struct edp_ctrl *ctrl, u32 clk_mask) | ||
| 289 | { | ||
| 290 | if (clk_mask & EDP_CLK_MASK_MDP_CORE) | ||
| 291 | clk_disable_unprepare(ctrl->mdp_core_clk); | ||
| 292 | if (clk_mask & EDP_CLK_MASK_PIXEL) | ||
| 293 | clk_disable_unprepare(ctrl->pixel_clk); | ||
| 294 | if (clk_mask & EDP_CLK_MASK_LINK) | ||
| 295 | clk_disable_unprepare(ctrl->link_clk); | ||
| 296 | if (clk_mask & EDP_CLK_MASK_AUX) | ||
| 297 | clk_disable_unprepare(ctrl->aux_clk); | ||
| 298 | if (clk_mask & EDP_CLK_MASK_AHB) | ||
| 299 | clk_disable_unprepare(ctrl->ahb_clk); | ||
| 300 | } | ||
| 301 | |||
| 302 | static int edp_regulator_init(struct edp_ctrl *ctrl) | ||
| 303 | { | ||
| 304 | struct device *dev = &ctrl->pdev->dev; | ||
| 305 | |||
| 306 | DBG(""); | ||
| 307 | ctrl->vdda_vreg = devm_regulator_get(dev, "vdda"); | ||
| 308 | if (IS_ERR(ctrl->vdda_vreg)) { | ||
| 309 | pr_err("%s: Could not get vdda reg, ret = %ld\n", __func__, | ||
| 310 | PTR_ERR(ctrl->vdda_vreg)); | ||
| 311 | ctrl->vdda_vreg = NULL; | ||
| 312 | return PTR_ERR(ctrl->vdda_vreg); | ||
| 313 | } | ||
| 314 | ctrl->lvl_vreg = devm_regulator_get(dev, "lvl-vdd"); | ||
| 315 | if (IS_ERR(ctrl->lvl_vreg)) { | ||
| 316 | pr_err("Could not get lvl-vdd reg, %ld", | ||
| 317 | PTR_ERR(ctrl->lvl_vreg)); | ||
| 318 | ctrl->lvl_vreg = NULL; | ||
| 319 | return PTR_ERR(ctrl->lvl_vreg); | ||
| 320 | } | ||
| 321 | |||
| 322 | return 0; | ||
| 323 | } | ||
| 324 | |||
| 325 | static int edp_regulator_enable(struct edp_ctrl *ctrl) | ||
| 326 | { | ||
| 327 | int ret; | ||
| 328 | |||
| 329 | ret = regulator_set_voltage(ctrl->vdda_vreg, VDDA_MIN_UV, VDDA_MAX_UV); | ||
| 330 | if (ret) { | ||
| 331 | pr_err("%s:vdda_vreg set_voltage failed, %d\n", __func__, ret); | ||
| 332 | goto vdda_set_fail; | ||
| 333 | } | ||
| 334 | |||
| 335 | ret = regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_ON_LOAD); | ||
| 336 | if (ret < 0) { | ||
| 337 | pr_err("%s: vdda_vreg set regulator mode failed.\n", __func__); | ||
| 338 | goto vdda_set_fail; | ||
| 339 | } | ||
| 340 | |||
| 341 | ret = regulator_enable(ctrl->vdda_vreg); | ||
| 342 | if (ret) { | ||
| 343 | pr_err("%s: Failed to enable vdda_vreg regulator.\n", __func__); | ||
| 344 | goto vdda_enable_fail; | ||
| 345 | } | ||
| 346 | |||
| 347 | ret = regulator_enable(ctrl->lvl_vreg); | ||
| 348 | if (ret) { | ||
| 349 | pr_err("Failed to enable lvl-vdd reg regulator, %d", ret); | ||
| 350 | goto lvl_enable_fail; | ||
| 351 | } | ||
| 352 | |||
| 353 | DBG("exit"); | ||
| 354 | return 0; | ||
| 355 | |||
| 356 | lvl_enable_fail: | ||
| 357 | regulator_disable(ctrl->vdda_vreg); | ||
| 358 | vdda_enable_fail: | ||
| 359 | regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD); | ||
| 360 | vdda_set_fail: | ||
| 361 | return ret; | ||
| 362 | } | ||
| 363 | |||
| 364 | static void edp_regulator_disable(struct edp_ctrl *ctrl) | ||
| 365 | { | ||
| 366 | regulator_disable(ctrl->lvl_vreg); | ||
| 367 | regulator_disable(ctrl->vdda_vreg); | ||
| 368 | regulator_set_optimum_mode(ctrl->vdda_vreg, VDDA_UA_OFF_LOAD); | ||
| 369 | } | ||
| 370 | |||
| 371 | static int edp_gpio_config(struct edp_ctrl *ctrl) | ||
| 372 | { | ||
| 373 | struct device *dev = &ctrl->pdev->dev; | ||
| 374 | int ret; | ||
| 375 | |||
| 376 | ctrl->panel_hpd_gpio = devm_gpiod_get(dev, "panel-hpd"); | ||
| 377 | if (IS_ERR(ctrl->panel_hpd_gpio)) { | ||
| 378 | ret = PTR_ERR(ctrl->panel_hpd_gpio); | ||
| 379 | ctrl->panel_hpd_gpio = NULL; | ||
| 380 | pr_err("%s: cannot get panel-hpd-gpios, %d\n", __func__, ret); | ||
| 381 | return ret; | ||
| 382 | } | ||
| 383 | |||
| 384 | ret = gpiod_direction_input(ctrl->panel_hpd_gpio); | ||
| 385 | if (ret) { | ||
| 386 | pr_err("%s: Set direction for hpd failed, %d\n", __func__, ret); | ||
| 387 | return ret; | ||
| 388 | } | ||
| 389 | |||
| 390 | ctrl->panel_en_gpio = devm_gpiod_get(dev, "panel-en"); | ||
| 391 | if (IS_ERR(ctrl->panel_en_gpio)) { | ||
| 392 | ret = PTR_ERR(ctrl->panel_en_gpio); | ||
| 393 | ctrl->panel_en_gpio = NULL; | ||
| 394 | pr_err("%s: cannot get panel-en-gpios, %d\n", __func__, ret); | ||
| 395 | return ret; | ||
| 396 | } | ||
| 397 | |||
| 398 | ret = gpiod_direction_output(ctrl->panel_en_gpio, 0); | ||
| 399 | if (ret) { | ||
| 400 | pr_err("%s: Set direction for panel_en failed, %d\n", | ||
| 401 | __func__, ret); | ||
| 402 | return ret; | ||
| 403 | } | ||
| 404 | |||
| 405 | DBG("gpio on"); | ||
| 406 | |||
| 407 | return 0; | ||
| 408 | } | ||
| 409 | |||
| 410 | static void edp_ctrl_irq_enable(struct edp_ctrl *ctrl, int enable) | ||
| 411 | { | ||
| 412 | unsigned long flags; | ||
| 413 | |||
| 414 | DBG("%d", enable); | ||
| 415 | spin_lock_irqsave(&ctrl->irq_lock, flags); | ||
| 416 | if (enable) { | ||
| 417 | edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, EDP_INTR_MASK1); | ||
| 418 | edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, EDP_INTR_MASK2); | ||
| 419 | } else { | ||
| 420 | edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, 0x0); | ||
| 421 | edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, 0x0); | ||
| 422 | } | ||
| 423 | spin_unlock_irqrestore(&ctrl->irq_lock, flags); | ||
| 424 | DBG("exit"); | ||
| 425 | } | ||
| 426 | |||
| 427 | static void edp_fill_link_cfg(struct edp_ctrl *ctrl) | ||
| 428 | { | ||
| 429 | u32 prate; | ||
| 430 | u32 lrate; | ||
| 431 | u32 bpp; | ||
| 432 | u8 max_lane = ctrl->dp_link.num_lanes; | ||
| 433 | u8 lane; | ||
| 434 | |||
| 435 | prate = ctrl->pixel_rate; | ||
| 436 | bpp = ctrl->color_depth * 3; | ||
| 437 | |||
| 438 | /* | ||
| 439 | * By default, use the maximum link rate and minimum lane count, | ||
| 440 | * so that we can do rate down shift during link training. | ||
| 441 | */ | ||
| 442 | ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.rate); | ||
| 443 | |||
| 444 | prate *= bpp; | ||
| 445 | prate /= 8; /* in kByte */ | ||
| 446 | |||
| 447 | lrate = 270000; /* in kHz */ | ||
| 448 | lrate *= ctrl->link_rate; | ||
| 449 | lrate /= 10; /* in kByte, 10 bits --> 8 bits */ | ||
| 450 | |||
| 451 | for (lane = 1; lane <= max_lane; lane <<= 1) { | ||
| 452 | if (lrate >= prate) | ||
| 453 | break; | ||
| 454 | lrate <<= 1; | ||
| 455 | } | ||
| 456 | |||
| 457 | ctrl->lane_cnt = lane; | ||
| 458 | DBG("rate=%d lane=%d", ctrl->link_rate, ctrl->lane_cnt); | ||
| 459 | } | ||
| 460 | |||
| 461 | static void edp_config_ctrl(struct edp_ctrl *ctrl) | ||
| 462 | { | ||
| 463 | u32 data; | ||
| 464 | enum edp_color_depth depth; | ||
| 465 | |||
| 466 | data = EDP_CONFIGURATION_CTRL_LANES(ctrl->lane_cnt - 1); | ||
| 467 | |||
| 468 | if (ctrl->dp_link.capabilities & DP_LINK_CAP_ENHANCED_FRAMING) | ||
| 469 | data |= EDP_CONFIGURATION_CTRL_ENHANCED_FRAMING; | ||
| 470 | |||
| 471 | depth = EDP_6BIT; | ||
| 472 | if (ctrl->color_depth == 8) | ||
| 473 | depth = EDP_8BIT; | ||
| 474 | |||
| 475 | data |= EDP_CONFIGURATION_CTRL_COLOR(depth); | ||
| 476 | |||
| 477 | if (!ctrl->interlaced) /* progressive */ | ||
| 478 | data |= EDP_CONFIGURATION_CTRL_PROGRESSIVE; | ||
| 479 | |||
| 480 | data |= (EDP_CONFIGURATION_CTRL_SYNC_CLK | | ||
| 481 | EDP_CONFIGURATION_CTRL_STATIC_MVID); | ||
| 482 | |||
| 483 | edp_write(ctrl->base + REG_EDP_CONFIGURATION_CTRL, data); | ||
| 484 | } | ||
| 485 | |||
| 486 | static void edp_state_ctrl(struct edp_ctrl *ctrl, u32 state) | ||
| 487 | { | ||
| 488 | edp_write(ctrl->base + REG_EDP_STATE_CTRL, state); | ||
| 489 | /* Make sure H/W status is set */ | ||
| 490 | wmb(); | ||
| 491 | } | ||
| 492 | |||
| 493 | static int edp_lane_set_write(struct edp_ctrl *ctrl, | ||
| 494 | u8 voltage_level, u8 pre_emphasis_level) | ||
| 495 | { | ||
| 496 | int i; | ||
| 497 | u8 buf[4]; | ||
| 498 | |||
| 499 | if (voltage_level >= DPCD_LINK_VOLTAGE_MAX) | ||
| 500 | voltage_level |= 0x04; | ||
| 501 | |||
| 502 | if (pre_emphasis_level >= DPCD_LINK_PRE_EMPHASIS_MAX) | ||
| 503 | pre_emphasis_level |= 0x04; | ||
| 504 | |||
| 505 | pre_emphasis_level <<= 3; | ||
| 506 | |||
| 507 | for (i = 0; i < 4; i++) | ||
| 508 | buf[i] = voltage_level | pre_emphasis_level; | ||
| 509 | |||
| 510 | DBG("%s: p|v=0x%x", __func__, voltage_level | pre_emphasis_level); | ||
| 511 | if (drm_dp_dpcd_write(ctrl->drm_aux, 0x103, buf, 4) < 4) { | ||
| 512 | pr_err("%s: Set sw/pe to panel failed\n", __func__); | ||
| 513 | return -ENOLINK; | ||
| 514 | } | ||
| 515 | |||
| 516 | return 0; | ||
| 517 | } | ||
| 518 | |||
| 519 | static int edp_train_pattern_set_write(struct edp_ctrl *ctrl, u8 pattern) | ||
| 520 | { | ||
| 521 | u8 p = pattern; | ||
| 522 | |||
| 523 | DBG("pattern=%x", p); | ||
| 524 | if (drm_dp_dpcd_write(ctrl->drm_aux, | ||
| 525 | DP_TRAINING_PATTERN_SET, &p, 1) < 1) { | ||
| 526 | pr_err("%s: Set training pattern to panel failed\n", __func__); | ||
| 527 | return -ENOLINK; | ||
| 528 | } | ||
| 529 | |||
| 530 | return 0; | ||
| 531 | } | ||
| 532 | |||
| 533 | static void edp_sink_train_set_adjust(struct edp_ctrl *ctrl, | ||
| 534 | const u8 *link_status) | ||
| 535 | { | ||
| 536 | int i; | ||
| 537 | u8 max = 0; | ||
| 538 | u8 data; | ||
| 539 | |||
| 540 | /* use the max level across lanes */ | ||
| 541 | for (i = 0; i < ctrl->lane_cnt; i++) { | ||
| 542 | data = drm_dp_get_adjust_request_voltage(link_status, i); | ||
| 543 | DBG("lane=%d req_voltage_swing=0x%x", i, data); | ||
| 544 | if (max < data) | ||
| 545 | max = data; | ||
| 546 | } | ||
| 547 | |||
| 548 | ctrl->v_level = max >> DP_TRAIN_VOLTAGE_SWING_SHIFT; | ||
| 549 | |||
| 550 | /* use the max level across lanes */ | ||
| 551 | max = 0; | ||
| 552 | for (i = 0; i < ctrl->lane_cnt; i++) { | ||
| 553 | data = drm_dp_get_adjust_request_pre_emphasis(link_status, i); | ||
| 554 | DBG("lane=%d req_pre_emphasis=0x%x", i, data); | ||
| 555 | if (max < data) | ||
| 556 | max = data; | ||
| 557 | } | ||
| 558 | |||
| 559 | ctrl->p_level = max >> DP_TRAIN_PRE_EMPHASIS_SHIFT; | ||
| 560 | DBG("v_level=%d, p_level=%d", ctrl->v_level, ctrl->p_level); | ||
| 561 | } | ||
| 562 | |||
| 563 | static void edp_host_train_set(struct edp_ctrl *ctrl, u32 train) | ||
| 564 | { | ||
| 565 | int cnt = 10; | ||
| 566 | u32 data; | ||
| 567 | u32 shift = train - 1; | ||
| 568 | |||
| 569 | DBG("train=%d", train); | ||
| 570 | |||
| 571 | edp_state_ctrl(ctrl, EDP_STATE_CTRL_TRAIN_PATTERN_1 << shift); | ||
| 572 | while (--cnt) { | ||
| 573 | data = edp_read(ctrl->base + REG_EDP_MAINLINK_READY); | ||
| 574 | if (data & (EDP_MAINLINK_READY_TRAIN_PATTERN_1_READY << shift)) | ||
| 575 | break; | ||
| 576 | } | ||
| 577 | |||
| 578 | if (cnt == 0) | ||
| 579 | pr_err("%s: set link_train=%d failed\n", __func__, train); | ||
| 580 | } | ||
| 581 | |||
| 582 | static const u8 vm_pre_emphasis[4][4] = { | ||
| 583 | {0x03, 0x06, 0x09, 0x0C}, /* pe0, 0 db */ | ||
| 584 | {0x03, 0x06, 0x09, 0xFF}, /* pe1, 3.5 db */ | ||
| 585 | {0x03, 0x06, 0xFF, 0xFF}, /* pe2, 6.0 db */ | ||
| 586 | {0x03, 0xFF, 0xFF, 0xFF} /* pe3, 9.5 db */ | ||
| 587 | }; | ||
| 588 | |||
| 589 | /* voltage swing, 0.2v and 1.0v are not support */ | ||
| 590 | static const u8 vm_voltage_swing[4][4] = { | ||
| 591 | {0x14, 0x18, 0x1A, 0x1E}, /* sw0, 0.4v */ | ||
| 592 | {0x18, 0x1A, 0x1E, 0xFF}, /* sw1, 0.6 v */ | ||
| 593 | {0x1A, 0x1E, 0xFF, 0xFF}, /* sw1, 0.8 v */ | ||
| 594 | {0x1E, 0xFF, 0xFF, 0xFF} /* sw1, 1.2 v, optional */ | ||
| 595 | }; | ||
| 596 | |||
| 597 | static int edp_voltage_pre_emphasise_set(struct edp_ctrl *ctrl) | ||
| 598 | { | ||
| 599 | u32 value0; | ||
| 600 | u32 value1; | ||
| 601 | |||
| 602 | DBG("v=%d p=%d", ctrl->v_level, ctrl->p_level); | ||
| 603 | |||
| 604 | value0 = vm_pre_emphasis[(int)(ctrl->v_level)][(int)(ctrl->p_level)]; | ||
| 605 | value1 = vm_voltage_swing[(int)(ctrl->v_level)][(int)(ctrl->p_level)]; | ||
| 606 | |||
| 607 | /* Configure host and panel only if both values are allowed */ | ||
| 608 | if (value0 != 0xFF && value1 != 0xFF) { | ||
| 609 | msm_edp_phy_vm_pe_cfg(ctrl->phy, value0, value1); | ||
| 610 | return edp_lane_set_write(ctrl, ctrl->v_level, ctrl->p_level); | ||
| 611 | } | ||
| 612 | |||
| 613 | return -EINVAL; | ||
| 614 | } | ||
| 615 | |||
| 616 | static int edp_start_link_train_1(struct edp_ctrl *ctrl) | ||
| 617 | { | ||
| 618 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
| 619 | u8 old_v_level; | ||
| 620 | int tries; | ||
| 621 | int ret; | ||
| 622 | int rlen; | ||
| 623 | |||
| 624 | DBG(""); | ||
| 625 | |||
| 626 | edp_host_train_set(ctrl, DP_TRAINING_PATTERN_1); | ||
| 627 | ret = edp_voltage_pre_emphasise_set(ctrl); | ||
| 628 | if (ret) | ||
| 629 | return ret; | ||
| 630 | ret = edp_train_pattern_set_write(ctrl, | ||
| 631 | DP_TRAINING_PATTERN_1 | DP_RECOVERED_CLOCK_OUT_EN); | ||
| 632 | if (ret) | ||
| 633 | return ret; | ||
| 634 | |||
| 635 | tries = 0; | ||
| 636 | old_v_level = ctrl->v_level; | ||
| 637 | while (1) { | ||
| 638 | drm_dp_link_train_clock_recovery_delay(ctrl->dpcd); | ||
| 639 | |||
| 640 | rlen = drm_dp_dpcd_read_link_status(ctrl->drm_aux, link_status); | ||
| 641 | if (rlen < DP_LINK_STATUS_SIZE) { | ||
| 642 | pr_err("%s: read link status failed\n", __func__); | ||
| 643 | return -ENOLINK; | ||
| 644 | } | ||
| 645 | if (drm_dp_clock_recovery_ok(link_status, ctrl->lane_cnt)) { | ||
| 646 | ret = 0; | ||
| 647 | break; | ||
| 648 | } | ||
| 649 | |||
| 650 | if (ctrl->v_level == DPCD_LINK_VOLTAGE_MAX) { | ||
| 651 | ret = -1; | ||
| 652 | break; | ||
| 653 | } | ||
| 654 | |||
| 655 | if (old_v_level == ctrl->v_level) { | ||
| 656 | tries++; | ||
| 657 | if (tries >= 5) { | ||
| 658 | ret = -1; | ||
| 659 | break; | ||
| 660 | } | ||
| 661 | } else { | ||
| 662 | tries = 0; | ||
| 663 | old_v_level = ctrl->v_level; | ||
| 664 | } | ||
| 665 | |||
| 666 | edp_sink_train_set_adjust(ctrl, link_status); | ||
| 667 | ret = edp_voltage_pre_emphasise_set(ctrl); | ||
| 668 | if (ret) | ||
| 669 | return ret; | ||
| 670 | } | ||
| 671 | |||
| 672 | return ret; | ||
| 673 | } | ||
| 674 | |||
| 675 | static int edp_start_link_train_2(struct edp_ctrl *ctrl) | ||
| 676 | { | ||
| 677 | u8 link_status[DP_LINK_STATUS_SIZE]; | ||
| 678 | int tries = 0; | ||
| 679 | int ret; | ||
| 680 | int rlen; | ||
| 681 | |||
| 682 | DBG(""); | ||
| 683 | |||
| 684 | edp_host_train_set(ctrl, DP_TRAINING_PATTERN_2); | ||
| 685 | ret = edp_voltage_pre_emphasise_set(ctrl); | ||
| 686 | if (ret) | ||
| 687 | return ret; | ||
| 688 | |||
| 689 | ret = edp_train_pattern_set_write(ctrl, | ||
| 690 | DP_TRAINING_PATTERN_2 | DP_RECOVERED_CLOCK_OUT_EN); | ||
| 691 | if (ret) | ||
| 692 | return ret; | ||
| 693 | |||
| 694 | while (1) { | ||
| 695 | drm_dp_link_train_channel_eq_delay(ctrl->dpcd); | ||
| 696 | |||
| 697 | rlen = drm_dp_dpcd_read_link_status(ctrl->drm_aux, link_status); | ||
| 698 | if (rlen < DP_LINK_STATUS_SIZE) { | ||
| 699 | pr_err("%s: read link status failed\n", __func__); | ||
| 700 | return -ENOLINK; | ||
| 701 | } | ||
| 702 | if (drm_dp_channel_eq_ok(link_status, ctrl->lane_cnt)) { | ||
| 703 | ret = 0; | ||
| 704 | break; | ||
| 705 | } | ||
| 706 | |||
| 707 | tries++; | ||
| 708 | if (tries > 10) { | ||
| 709 | ret = -1; | ||
| 710 | break; | ||
| 711 | } | ||
| 712 | |||
| 713 | edp_sink_train_set_adjust(ctrl, link_status); | ||
| 714 | ret = edp_voltage_pre_emphasise_set(ctrl); | ||
| 715 | if (ret) | ||
| 716 | return ret; | ||
| 717 | } | ||
| 718 | |||
| 719 | return ret; | ||
| 720 | } | ||
| 721 | |||
| 722 | static int edp_link_rate_down_shift(struct edp_ctrl *ctrl) | ||
| 723 | { | ||
| 724 | u32 prate, lrate, bpp; | ||
| 725 | u8 rate, lane, max_lane; | ||
| 726 | int changed = 0; | ||
| 727 | |||
| 728 | rate = ctrl->link_rate; | ||
| 729 | lane = ctrl->lane_cnt; | ||
| 730 | max_lane = ctrl->dp_link.num_lanes; | ||
| 731 | |||
| 732 | bpp = ctrl->color_depth * 3; | ||
| 733 | prate = ctrl->pixel_rate; | ||
| 734 | prate *= bpp; | ||
| 735 | prate /= 8; /* in kByte */ | ||
| 736 | |||
| 737 | if (rate > DP_LINK_BW_1_62 && rate <= EDP_LINK_BW_MAX) { | ||
| 738 | rate -= 4; /* reduce rate */ | ||
| 739 | changed++; | ||
| 740 | } | ||
| 741 | |||
| 742 | if (changed) { | ||
| 743 | if (lane >= 1 && lane < max_lane) | ||
| 744 | lane <<= 1; /* increase lane */ | ||
| 745 | |||
| 746 | lrate = 270000; /* in kHz */ | ||
| 747 | lrate *= rate; | ||
| 748 | lrate /= 10; /* kByte, 10 bits --> 8 bits */ | ||
| 749 | lrate *= lane; | ||
| 750 | |||
| 751 | DBG("new lrate=%u prate=%u(kHz) rate=%d lane=%d p=%u b=%d", | ||
| 752 | lrate, prate, rate, lane, | ||
| 753 | ctrl->pixel_rate, | ||
| 754 | bpp); | ||
| 755 | |||
| 756 | if (lrate > prate) { | ||
| 757 | ctrl->link_rate = rate; | ||
| 758 | ctrl->lane_cnt = lane; | ||
| 759 | DBG("new rate=%d %d", rate, lane); | ||
| 760 | return 0; | ||
| 761 | } | ||
| 762 | } | ||
| 763 | |||
| 764 | return -EINVAL; | ||
| 765 | } | ||
| 766 | |||
| 767 | static int edp_clear_training_pattern(struct edp_ctrl *ctrl) | ||
| 768 | { | ||
| 769 | int ret; | ||
| 770 | |||
| 771 | ret = edp_train_pattern_set_write(ctrl, 0); | ||
| 772 | |||
| 773 | drm_dp_link_train_channel_eq_delay(ctrl->dpcd); | ||
| 774 | |||
| 775 | return ret; | ||
| 776 | } | ||
| 777 | |||
| 778 | static int edp_do_link_train(struct edp_ctrl *ctrl) | ||
| 779 | { | ||
| 780 | int ret; | ||
| 781 | struct drm_dp_link dp_link; | ||
| 782 | |||
| 783 | DBG(""); | ||
| 784 | /* | ||
| 785 | * Set the current link rate and lane cnt to panel. They may have been | ||
| 786 | * adjusted and the values are different from them in DPCD CAP | ||
| 787 | */ | ||
| 788 | dp_link.num_lanes = ctrl->lane_cnt; | ||
| 789 | dp_link.rate = drm_dp_bw_code_to_link_rate(ctrl->link_rate); | ||
| 790 | dp_link.capabilities = ctrl->dp_link.capabilities; | ||
| 791 | if (drm_dp_link_configure(ctrl->drm_aux, &dp_link) < 0) | ||
| 792 | return EDP_TRAIN_FAIL; | ||
| 793 | |||
| 794 | ctrl->v_level = 0; /* start from default level */ | ||
| 795 | ctrl->p_level = 0; | ||
| 796 | |||
| 797 | edp_state_ctrl(ctrl, 0); | ||
| 798 | if (edp_clear_training_pattern(ctrl)) | ||
| 799 | return EDP_TRAIN_FAIL; | ||
| 800 | |||
| 801 | ret = edp_start_link_train_1(ctrl); | ||
| 802 | if (ret < 0) { | ||
| 803 | if (edp_link_rate_down_shift(ctrl) == 0) { | ||
| 804 | DBG("link reconfig"); | ||
| 805 | ret = EDP_TRAIN_RECONFIG; | ||
| 806 | goto clear; | ||
| 807 | } else { | ||
| 808 | pr_err("%s: Training 1 failed", __func__); | ||
| 809 | ret = EDP_TRAIN_FAIL; | ||
| 810 | goto clear; | ||
| 811 | } | ||
| 812 | } | ||
| 813 | DBG("Training 1 completed successfully"); | ||
| 814 | |||
| 815 | edp_state_ctrl(ctrl, 0); | ||
| 816 | if (edp_clear_training_pattern(ctrl)) | ||
| 817 | return EDP_TRAIN_FAIL; | ||
| 818 | |||
| 819 | ret = edp_start_link_train_2(ctrl); | ||
| 820 | if (ret < 0) { | ||
| 821 | if (edp_link_rate_down_shift(ctrl) == 0) { | ||
| 822 | DBG("link reconfig"); | ||
| 823 | ret = EDP_TRAIN_RECONFIG; | ||
| 824 | goto clear; | ||
| 825 | } else { | ||
| 826 | pr_err("%s: Training 2 failed", __func__); | ||
| 827 | ret = EDP_TRAIN_FAIL; | ||
| 828 | goto clear; | ||
| 829 | } | ||
| 830 | } | ||
| 831 | DBG("Training 2 completed successfully"); | ||
| 832 | |||
| 833 | edp_state_ctrl(ctrl, EDP_STATE_CTRL_SEND_VIDEO); | ||
| 834 | clear: | ||
| 835 | edp_clear_training_pattern(ctrl); | ||
| 836 | |||
| 837 | return ret; | ||
| 838 | } | ||
| 839 | |||
| 840 | static void edp_clock_synchrous(struct edp_ctrl *ctrl, int sync) | ||
| 841 | { | ||
| 842 | u32 data; | ||
| 843 | enum edp_color_depth depth; | ||
| 844 | |||
| 845 | data = edp_read(ctrl->base + REG_EDP_MISC1_MISC0); | ||
| 846 | |||
| 847 | if (sync) | ||
| 848 | data |= EDP_MISC1_MISC0_SYNC; | ||
| 849 | else | ||
| 850 | data &= ~EDP_MISC1_MISC0_SYNC; | ||
| 851 | |||
| 852 | /* only legacy rgb mode supported */ | ||
| 853 | depth = EDP_6BIT; /* Default */ | ||
| 854 | if (ctrl->color_depth == 8) | ||
| 855 | depth = EDP_8BIT; | ||
| 856 | else if (ctrl->color_depth == 10) | ||
| 857 | depth = EDP_10BIT; | ||
| 858 | else if (ctrl->color_depth == 12) | ||
| 859 | depth = EDP_12BIT; | ||
| 860 | else if (ctrl->color_depth == 16) | ||
| 861 | depth = EDP_16BIT; | ||
| 862 | |||
| 863 | data |= EDP_MISC1_MISC0_COLOR(depth); | ||
| 864 | |||
| 865 | edp_write(ctrl->base + REG_EDP_MISC1_MISC0, data); | ||
| 866 | } | ||
| 867 | |||
| 868 | static int edp_sw_mvid_nvid(struct edp_ctrl *ctrl, u32 m, u32 n) | ||
| 869 | { | ||
| 870 | u32 n_multi, m_multi = 5; | ||
| 871 | |||
| 872 | if (ctrl->link_rate == DP_LINK_BW_1_62) { | ||
| 873 | n_multi = 1; | ||
| 874 | } else if (ctrl->link_rate == DP_LINK_BW_2_7) { | ||
| 875 | n_multi = 2; | ||
| 876 | } else { | ||
| 877 | pr_err("%s: Invalid link rate, %d\n", __func__, | ||
| 878 | ctrl->link_rate); | ||
| 879 | return -EINVAL; | ||
| 880 | } | ||
| 881 | |||
| 882 | edp_write(ctrl->base + REG_EDP_SOFTWARE_MVID, m * m_multi); | ||
| 883 | edp_write(ctrl->base + REG_EDP_SOFTWARE_NVID, n * n_multi); | ||
| 884 | |||
| 885 | return 0; | ||
| 886 | } | ||
| 887 | |||
| 888 | static void edp_mainlink_ctrl(struct edp_ctrl *ctrl, int enable) | ||
| 889 | { | ||
| 890 | u32 data = 0; | ||
| 891 | |||
| 892 | edp_write(ctrl->base + REG_EDP_MAINLINK_CTRL, EDP_MAINLINK_CTRL_RESET); | ||
| 893 | /* Make sure fully reset */ | ||
| 894 | wmb(); | ||
| 895 | usleep_range(500, 1000); | ||
| 896 | |||
| 897 | if (enable) | ||
| 898 | data |= EDP_MAINLINK_CTRL_ENABLE; | ||
| 899 | |||
| 900 | edp_write(ctrl->base + REG_EDP_MAINLINK_CTRL, data); | ||
| 901 | } | ||
| 902 | |||
| 903 | static void edp_ctrl_phy_aux_enable(struct edp_ctrl *ctrl, int enable) | ||
| 904 | { | ||
| 905 | if (enable) { | ||
| 906 | edp_regulator_enable(ctrl); | ||
| 907 | edp_clk_enable(ctrl, EDP_CLK_MASK_AUX_CHAN); | ||
| 908 | msm_edp_phy_ctrl(ctrl->phy, 1); | ||
| 909 | msm_edp_aux_ctrl(ctrl->aux, 1); | ||
| 910 | gpiod_set_value(ctrl->panel_en_gpio, 1); | ||
| 911 | } else { | ||
| 912 | gpiod_set_value(ctrl->panel_en_gpio, 0); | ||
| 913 | msm_edp_aux_ctrl(ctrl->aux, 0); | ||
| 914 | msm_edp_phy_ctrl(ctrl->phy, 0); | ||
| 915 | edp_clk_disable(ctrl, EDP_CLK_MASK_AUX_CHAN); | ||
| 916 | edp_regulator_disable(ctrl); | ||
| 917 | } | ||
| 918 | } | ||
| 919 | |||
| 920 | static void edp_ctrl_link_enable(struct edp_ctrl *ctrl, int enable) | ||
| 921 | { | ||
| 922 | u32 m, n; | ||
| 923 | |||
| 924 | if (enable) { | ||
| 925 | /* Enable link channel clocks */ | ||
| 926 | edp_clk_enable(ctrl, EDP_CLK_MASK_LINK_CHAN); | ||
| 927 | |||
| 928 | msm_edp_phy_lane_power_ctrl(ctrl->phy, true, ctrl->lane_cnt); | ||
| 929 | |||
| 930 | msm_edp_phy_vm_pe_init(ctrl->phy); | ||
| 931 | |||
| 932 | /* Make sure phy is programed */ | ||
| 933 | wmb(); | ||
| 934 | msm_edp_phy_ready(ctrl->phy); | ||
| 935 | |||
| 936 | edp_config_ctrl(ctrl); | ||
| 937 | msm_edp_ctrl_pixel_clock_valid(ctrl, ctrl->pixel_rate, &m, &n); | ||
| 938 | edp_sw_mvid_nvid(ctrl, m, n); | ||
| 939 | edp_mainlink_ctrl(ctrl, 1); | ||
| 940 | } else { | ||
| 941 | edp_mainlink_ctrl(ctrl, 0); | ||
| 942 | |||
| 943 | msm_edp_phy_lane_power_ctrl(ctrl->phy, false, 0); | ||
| 944 | edp_clk_disable(ctrl, EDP_CLK_MASK_LINK_CHAN); | ||
| 945 | } | ||
| 946 | } | ||
| 947 | |||
| 948 | static int edp_ctrl_training(struct edp_ctrl *ctrl) | ||
| 949 | { | ||
| 950 | int ret; | ||
| 951 | |||
| 952 | /* Do link training only when power is on */ | ||
| 953 | if (!ctrl->power_on) | ||
| 954 | return -EINVAL; | ||
| 955 | |||
| 956 | train_start: | ||
| 957 | ret = edp_do_link_train(ctrl); | ||
| 958 | if (ret == EDP_TRAIN_RECONFIG) { | ||
| 959 | /* Re-configure main link */ | ||
| 960 | edp_ctrl_irq_enable(ctrl, 0); | ||
| 961 | edp_ctrl_link_enable(ctrl, 0); | ||
| 962 | msm_edp_phy_ctrl(ctrl->phy, 0); | ||
| 963 | |||
| 964 | /* Make sure link is fully disabled */ | ||
| 965 | wmb(); | ||
| 966 | usleep_range(500, 1000); | ||
| 967 | |||
| 968 | msm_edp_phy_ctrl(ctrl->phy, 1); | ||
| 969 | edp_ctrl_link_enable(ctrl, 1); | ||
| 970 | edp_ctrl_irq_enable(ctrl, 1); | ||
| 971 | goto train_start; | ||
| 972 | } | ||
| 973 | |||
| 974 | return ret; | ||
| 975 | } | ||
| 976 | |||
| 977 | static void edp_ctrl_on_worker(struct work_struct *work) | ||
| 978 | { | ||
| 979 | struct edp_ctrl *ctrl = container_of( | ||
| 980 | work, struct edp_ctrl, on_work); | ||
| 981 | int ret; | ||
| 982 | |||
| 983 | mutex_lock(&ctrl->dev_mutex); | ||
| 984 | |||
| 985 | if (ctrl->power_on) { | ||
| 986 | DBG("already on"); | ||
| 987 | goto unlock_ret; | ||
| 988 | } | ||
| 989 | |||
| 990 | edp_ctrl_phy_aux_enable(ctrl, 1); | ||
| 991 | edp_ctrl_link_enable(ctrl, 1); | ||
| 992 | |||
| 993 | edp_ctrl_irq_enable(ctrl, 1); | ||
| 994 | ret = drm_dp_link_power_up(ctrl->drm_aux, &ctrl->dp_link); | ||
| 995 | if (ret) | ||
| 996 | goto fail; | ||
| 997 | |||
| 998 | ctrl->power_on = true; | ||
| 999 | |||
| 1000 | /* Start link training */ | ||
| 1001 | ret = edp_ctrl_training(ctrl); | ||
| 1002 | if (ret != EDP_TRAIN_SUCCESS) | ||
| 1003 | goto fail; | ||
| 1004 | |||
| 1005 | DBG("DONE"); | ||
| 1006 | goto unlock_ret; | ||
| 1007 | |||
| 1008 | fail: | ||
| 1009 | edp_ctrl_irq_enable(ctrl, 0); | ||
| 1010 | edp_ctrl_link_enable(ctrl, 0); | ||
| 1011 | edp_ctrl_phy_aux_enable(ctrl, 0); | ||
| 1012 | ctrl->power_on = false; | ||
| 1013 | unlock_ret: | ||
| 1014 | mutex_unlock(&ctrl->dev_mutex); | ||
| 1015 | } | ||
| 1016 | |||
| 1017 | static void edp_ctrl_off_worker(struct work_struct *work) | ||
| 1018 | { | ||
| 1019 | struct edp_ctrl *ctrl = container_of( | ||
| 1020 | work, struct edp_ctrl, off_work); | ||
| 1021 | int ret; | ||
| 1022 | |||
| 1023 | mutex_lock(&ctrl->dev_mutex); | ||
| 1024 | |||
| 1025 | if (!ctrl->power_on) { | ||
| 1026 | DBG("already off"); | ||
| 1027 | goto unlock_ret; | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | reinit_completion(&ctrl->idle_comp); | ||
| 1031 | edp_state_ctrl(ctrl, EDP_STATE_CTRL_PUSH_IDLE); | ||
| 1032 | |||
| 1033 | ret = wait_for_completion_timeout(&ctrl->idle_comp, | ||
| 1034 | msecs_to_jiffies(500)); | ||
| 1035 | if (ret <= 0) | ||
| 1036 | DBG("%s: idle pattern timedout, %d\n", | ||
| 1037 | __func__, ret); | ||
| 1038 | |||
| 1039 | edp_state_ctrl(ctrl, 0); | ||
| 1040 | |||
| 1041 | drm_dp_link_power_down(ctrl->drm_aux, &ctrl->dp_link); | ||
| 1042 | |||
| 1043 | edp_ctrl_irq_enable(ctrl, 0); | ||
| 1044 | |||
| 1045 | edp_ctrl_link_enable(ctrl, 0); | ||
| 1046 | |||
| 1047 | edp_ctrl_phy_aux_enable(ctrl, 0); | ||
| 1048 | |||
| 1049 | ctrl->power_on = false; | ||
| 1050 | |||
| 1051 | unlock_ret: | ||
| 1052 | mutex_unlock(&ctrl->dev_mutex); | ||
| 1053 | } | ||
| 1054 | |||
| 1055 | irqreturn_t msm_edp_ctrl_irq(struct edp_ctrl *ctrl) | ||
| 1056 | { | ||
| 1057 | u32 isr1, isr2, mask1, mask2; | ||
| 1058 | u32 ack; | ||
| 1059 | |||
| 1060 | DBG(""); | ||
| 1061 | spin_lock(&ctrl->irq_lock); | ||
| 1062 | isr1 = edp_read(ctrl->base + REG_EDP_INTERRUPT_REG_1); | ||
| 1063 | isr2 = edp_read(ctrl->base + REG_EDP_INTERRUPT_REG_2); | ||
| 1064 | |||
| 1065 | mask1 = isr1 & EDP_INTR_MASK1; | ||
| 1066 | mask2 = isr2 & EDP_INTR_MASK2; | ||
| 1067 | |||
| 1068 | isr1 &= ~mask1; /* remove masks bit */ | ||
| 1069 | isr2 &= ~mask2; | ||
| 1070 | |||
| 1071 | DBG("isr=%x mask=%x isr2=%x mask2=%x", | ||
| 1072 | isr1, mask1, isr2, mask2); | ||
| 1073 | |||
| 1074 | ack = isr1 & EDP_INTR_STATUS1; | ||
| 1075 | ack <<= 1; /* ack bits */ | ||
| 1076 | ack |= mask1; | ||
| 1077 | edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_1, ack); | ||
| 1078 | |||
| 1079 | ack = isr2 & EDP_INTR_STATUS2; | ||
| 1080 | ack <<= 1; /* ack bits */ | ||
| 1081 | ack |= mask2; | ||
| 1082 | edp_write(ctrl->base + REG_EDP_INTERRUPT_REG_2, ack); | ||
| 1083 | spin_unlock(&ctrl->irq_lock); | ||
| 1084 | |||
| 1085 | if (isr1 & EDP_INTERRUPT_REG_1_HPD) | ||
| 1086 | DBG("edp_hpd"); | ||
| 1087 | |||
| 1088 | if (isr2 & EDP_INTERRUPT_REG_2_READY_FOR_VIDEO) | ||
| 1089 | DBG("edp_video_ready"); | ||
| 1090 | |||
| 1091 | if (isr2 & EDP_INTERRUPT_REG_2_IDLE_PATTERNs_SENT) { | ||
| 1092 | DBG("idle_patterns_sent"); | ||
| 1093 | complete(&ctrl->idle_comp); | ||
| 1094 | } | ||
| 1095 | |||
| 1096 | msm_edp_aux_irq(ctrl->aux, isr1); | ||
| 1097 | |||
| 1098 | return IRQ_HANDLED; | ||
| 1099 | } | ||
| 1100 | |||
| 1101 | void msm_edp_ctrl_power(struct edp_ctrl *ctrl, bool on) | ||
| 1102 | { | ||
| 1103 | if (on) | ||
| 1104 | queue_work(ctrl->workqueue, &ctrl->on_work); | ||
| 1105 | else | ||
| 1106 | queue_work(ctrl->workqueue, &ctrl->off_work); | ||
| 1107 | } | ||
| 1108 | |||
| 1109 | int msm_edp_ctrl_init(struct msm_edp *edp) | ||
| 1110 | { | ||
| 1111 | struct edp_ctrl *ctrl = NULL; | ||
| 1112 | struct device *dev = &edp->pdev->dev; | ||
| 1113 | int ret; | ||
| 1114 | |||
| 1115 | if (!edp) { | ||
| 1116 | pr_err("%s: edp is NULL!\n", __func__); | ||
| 1117 | return -EINVAL; | ||
| 1118 | } | ||
| 1119 | |||
| 1120 | ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL); | ||
| 1121 | if (!ctrl) | ||
| 1122 | return -ENOMEM; | ||
| 1123 | |||
| 1124 | edp->ctrl = ctrl; | ||
| 1125 | ctrl->pdev = edp->pdev; | ||
| 1126 | |||
| 1127 | ctrl->base = msm_ioremap(ctrl->pdev, "edp", "eDP"); | ||
| 1128 | if (IS_ERR(ctrl->base)) | ||
| 1129 | return PTR_ERR(ctrl->base); | ||
| 1130 | |||
| 1131 | /* Get regulator, clock, gpio, pwm */ | ||
| 1132 | ret = edp_regulator_init(ctrl); | ||
| 1133 | if (ret) { | ||
| 1134 | pr_err("%s:regulator init fail\n", __func__); | ||
| 1135 | return ret; | ||
| 1136 | } | ||
| 1137 | ret = edp_clk_init(ctrl); | ||
| 1138 | if (ret) { | ||
| 1139 | pr_err("%s:clk init fail\n", __func__); | ||
| 1140 | return ret; | ||
| 1141 | } | ||
| 1142 | ret = edp_gpio_config(ctrl); | ||
| 1143 | if (ret) { | ||
| 1144 | pr_err("%s:failed to configure GPIOs: %d", __func__, ret); | ||
| 1145 | return ret; | ||
| 1146 | } | ||
| 1147 | |||
| 1148 | /* Init aux and phy */ | ||
| 1149 | ctrl->aux = msm_edp_aux_init(dev, ctrl->base, &ctrl->drm_aux); | ||
| 1150 | if (!ctrl->aux || !ctrl->drm_aux) { | ||
| 1151 | pr_err("%s:failed to init aux\n", __func__); | ||
| 1152 | return ret; | ||
| 1153 | } | ||
| 1154 | |||
| 1155 | ctrl->phy = msm_edp_phy_init(dev, ctrl->base); | ||
| 1156 | if (!ctrl->phy) { | ||
| 1157 | pr_err("%s:failed to init phy\n", __func__); | ||
| 1158 | goto err_destory_aux; | ||
| 1159 | } | ||
| 1160 | |||
| 1161 | spin_lock_init(&ctrl->irq_lock); | ||
| 1162 | mutex_init(&ctrl->dev_mutex); | ||
| 1163 | init_completion(&ctrl->idle_comp); | ||
| 1164 | |||
| 1165 | /* setup workqueue */ | ||
| 1166 | ctrl->workqueue = alloc_ordered_workqueue("edp_drm_work", 0); | ||
| 1167 | INIT_WORK(&ctrl->on_work, edp_ctrl_on_worker); | ||
| 1168 | INIT_WORK(&ctrl->off_work, edp_ctrl_off_worker); | ||
| 1169 | |||
| 1170 | return 0; | ||
| 1171 | |||
| 1172 | err_destory_aux: | ||
| 1173 | msm_edp_aux_destroy(dev, ctrl->aux); | ||
| 1174 | ctrl->aux = NULL; | ||
| 1175 | return ret; | ||
| 1176 | } | ||
| 1177 | |||
| 1178 | void msm_edp_ctrl_destroy(struct edp_ctrl *ctrl) | ||
| 1179 | { | ||
| 1180 | if (!ctrl) | ||
| 1181 | return; | ||
| 1182 | |||
| 1183 | if (ctrl->workqueue) { | ||
| 1184 | flush_workqueue(ctrl->workqueue); | ||
| 1185 | destroy_workqueue(ctrl->workqueue); | ||
| 1186 | ctrl->workqueue = NULL; | ||
| 1187 | } | ||
| 1188 | |||
| 1189 | if (ctrl->aux) { | ||
| 1190 | msm_edp_aux_destroy(&ctrl->pdev->dev, ctrl->aux); | ||
| 1191 | ctrl->aux = NULL; | ||
| 1192 | } | ||
| 1193 | |||
| 1194 | kfree(ctrl->edid); | ||
| 1195 | ctrl->edid = NULL; | ||
| 1196 | |||
| 1197 | mutex_destroy(&ctrl->dev_mutex); | ||
| 1198 | } | ||
| 1199 | |||
| 1200 | bool msm_edp_ctrl_panel_connected(struct edp_ctrl *ctrl) | ||
| 1201 | { | ||
| 1202 | mutex_lock(&ctrl->dev_mutex); | ||
| 1203 | DBG("connect status = %d", ctrl->edp_connected); | ||
| 1204 | if (ctrl->edp_connected) { | ||
| 1205 | mutex_unlock(&ctrl->dev_mutex); | ||
| 1206 | return true; | ||
| 1207 | } | ||
| 1208 | |||
| 1209 | if (!ctrl->power_on) { | ||
| 1210 | edp_ctrl_phy_aux_enable(ctrl, 1); | ||
| 1211 | edp_ctrl_irq_enable(ctrl, 1); | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | if (drm_dp_dpcd_read(ctrl->drm_aux, DP_DPCD_REV, ctrl->dpcd, | ||
| 1215 | DP_RECEIVER_CAP_SIZE) < DP_RECEIVER_CAP_SIZE) { | ||
| 1216 | pr_err("%s: AUX channel is NOT ready\n", __func__); | ||
| 1217 | memset(ctrl->dpcd, 0, DP_RECEIVER_CAP_SIZE); | ||
| 1218 | } else { | ||
| 1219 | ctrl->edp_connected = true; | ||
| 1220 | } | ||
| 1221 | |||
| 1222 | if (!ctrl->power_on) { | ||
| 1223 | edp_ctrl_irq_enable(ctrl, 0); | ||
| 1224 | edp_ctrl_phy_aux_enable(ctrl, 0); | ||
| 1225 | } | ||
| 1226 | |||
| 1227 | DBG("exit: connect status=%d", ctrl->edp_connected); | ||
| 1228 | |||
| 1229 | mutex_unlock(&ctrl->dev_mutex); | ||
| 1230 | |||
| 1231 | return ctrl->edp_connected; | ||
| 1232 | } | ||
| 1233 | |||
| 1234 | int msm_edp_ctrl_get_panel_info(struct edp_ctrl *ctrl, | ||
| 1235 | struct drm_connector *connector, struct edid **edid) | ||
| 1236 | { | ||
| 1237 | int ret = 0; | ||
| 1238 | |||
| 1239 | mutex_lock(&ctrl->dev_mutex); | ||
| 1240 | |||
| 1241 | if (ctrl->edid) { | ||
| 1242 | if (edid) { | ||
| 1243 | DBG("Just return edid buffer"); | ||
| 1244 | *edid = ctrl->edid; | ||
| 1245 | } | ||
| 1246 | goto unlock_ret; | ||
| 1247 | } | ||
| 1248 | |||
| 1249 | if (!ctrl->power_on) { | ||
| 1250 | edp_ctrl_phy_aux_enable(ctrl, 1); | ||
| 1251 | edp_ctrl_irq_enable(ctrl, 1); | ||
| 1252 | } | ||
| 1253 | |||
| 1254 | ret = drm_dp_link_probe(ctrl->drm_aux, &ctrl->dp_link); | ||
| 1255 | if (ret) { | ||
| 1256 | pr_err("%s: read dpcd cap failed, %d\n", __func__, ret); | ||
| 1257 | goto disable_ret; | ||
| 1258 | } | ||
| 1259 | |||
| 1260 | /* Initialize link rate as panel max link rate */ | ||
| 1261 | ctrl->link_rate = drm_dp_link_rate_to_bw_code(ctrl->dp_link.rate); | ||
| 1262 | |||
| 1263 | ctrl->edid = drm_get_edid(connector, &ctrl->drm_aux->ddc); | ||
| 1264 | if (!ctrl->edid) { | ||
| 1265 | pr_err("%s: edid read fail\n", __func__); | ||
| 1266 | goto disable_ret; | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | if (edid) | ||
| 1270 | *edid = ctrl->edid; | ||
| 1271 | |||
| 1272 | disable_ret: | ||
| 1273 | if (!ctrl->power_on) { | ||
| 1274 | edp_ctrl_irq_enable(ctrl, 0); | ||
| 1275 | edp_ctrl_phy_aux_enable(ctrl, 0); | ||
| 1276 | } | ||
| 1277 | unlock_ret: | ||
| 1278 | mutex_unlock(&ctrl->dev_mutex); | ||
| 1279 | return ret; | ||
| 1280 | } | ||
| 1281 | |||
| 1282 | int msm_edp_ctrl_timing_cfg(struct edp_ctrl *ctrl, | ||
| 1283 | const struct drm_display_mode *mode, | ||
| 1284 | const struct drm_display_info *info) | ||
| 1285 | { | ||
| 1286 | u32 hstart_from_sync, vstart_from_sync; | ||
| 1287 | u32 data; | ||
| 1288 | int ret = 0; | ||
| 1289 | |||
| 1290 | mutex_lock(&ctrl->dev_mutex); | ||
| 1291 | /* | ||
| 1292 | * Need to keep color depth, pixel rate and | ||
| 1293 | * interlaced information in ctrl context | ||
| 1294 | */ | ||
| 1295 | ctrl->color_depth = info->bpc; | ||
| 1296 | ctrl->pixel_rate = mode->clock; | ||
| 1297 | ctrl->interlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); | ||
| 1298 | |||
| 1299 | /* Fill initial link config based on passed in timing */ | ||
| 1300 | edp_fill_link_cfg(ctrl); | ||
| 1301 | |||
| 1302 | if (edp_clk_enable(ctrl, EDP_CLK_MASK_AHB)) { | ||
| 1303 | pr_err("%s, fail to prepare enable ahb clk\n", __func__); | ||
| 1304 | ret = -EINVAL; | ||
| 1305 | goto unlock_ret; | ||
| 1306 | } | ||
| 1307 | edp_clock_synchrous(ctrl, 1); | ||
| 1308 | |||
| 1309 | /* Configure eDP timing to HW */ | ||
| 1310 | edp_write(ctrl->base + REG_EDP_TOTAL_HOR_VER, | ||
| 1311 | EDP_TOTAL_HOR_VER_HORIZ(mode->htotal) | | ||
| 1312 | EDP_TOTAL_HOR_VER_VERT(mode->vtotal)); | ||
| 1313 | |||
| 1314 | vstart_from_sync = mode->vtotal - mode->vsync_start; | ||
| 1315 | hstart_from_sync = mode->htotal - mode->hsync_start; | ||
| 1316 | edp_write(ctrl->base + REG_EDP_START_HOR_VER_FROM_SYNC, | ||
| 1317 | EDP_START_HOR_VER_FROM_SYNC_HORIZ(hstart_from_sync) | | ||
| 1318 | EDP_START_HOR_VER_FROM_SYNC_VERT(vstart_from_sync)); | ||
| 1319 | |||
| 1320 | data = EDP_HSYNC_VSYNC_WIDTH_POLARITY_VERT( | ||
| 1321 | mode->vsync_end - mode->vsync_start); | ||
| 1322 | data |= EDP_HSYNC_VSYNC_WIDTH_POLARITY_HORIZ( | ||
| 1323 | mode->hsync_end - mode->hsync_start); | ||
| 1324 | if (mode->flags & DRM_MODE_FLAG_NVSYNC) | ||
| 1325 | data |= EDP_HSYNC_VSYNC_WIDTH_POLARITY_NVSYNC; | ||
| 1326 | if (mode->flags & DRM_MODE_FLAG_NHSYNC) | ||
| 1327 | data |= EDP_HSYNC_VSYNC_WIDTH_POLARITY_NHSYNC; | ||
| 1328 | edp_write(ctrl->base + REG_EDP_HSYNC_VSYNC_WIDTH_POLARITY, data); | ||
| 1329 | |||
| 1330 | edp_write(ctrl->base + REG_EDP_ACTIVE_HOR_VER, | ||
| 1331 | EDP_ACTIVE_HOR_VER_HORIZ(mode->hdisplay) | | ||
| 1332 | EDP_ACTIVE_HOR_VER_VERT(mode->vdisplay)); | ||
| 1333 | |||
| 1334 | edp_clk_disable(ctrl, EDP_CLK_MASK_AHB); | ||
| 1335 | |||
| 1336 | unlock_ret: | ||
| 1337 | mutex_unlock(&ctrl->dev_mutex); | ||
| 1338 | return ret; | ||
| 1339 | } | ||
| 1340 | |||
| 1341 | bool msm_edp_ctrl_pixel_clock_valid(struct edp_ctrl *ctrl, | ||
| 1342 | u32 pixel_rate, u32 *pm, u32 *pn) | ||
| 1343 | { | ||
| 1344 | const struct edp_pixel_clk_div *divs; | ||
| 1345 | u32 err = 1; /* 1% error tolerance */ | ||
| 1346 | u32 clk_err; | ||
| 1347 | int i; | ||
| 1348 | |||
| 1349 | if (ctrl->link_rate == DP_LINK_BW_1_62) { | ||
| 1350 | divs = clk_divs[0]; | ||
| 1351 | } else if (ctrl->link_rate == DP_LINK_BW_2_7) { | ||
| 1352 | divs = clk_divs[1]; | ||
| 1353 | } else { | ||
| 1354 | pr_err("%s: Invalid link rate,%d\n", __func__, ctrl->link_rate); | ||
| 1355 | return false; | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | for (i = 0; i < EDP_PIXEL_CLK_NUM; i++) { | ||
| 1359 | clk_err = abs(divs[i].rate - pixel_rate); | ||
| 1360 | if ((divs[i].rate * err / 100) >= clk_err) { | ||
| 1361 | if (pm) | ||
| 1362 | *pm = divs[i].m; | ||
| 1363 | if (pn) | ||
| 1364 | *pn = divs[i].n; | ||
| 1365 | return true; | ||
| 1366 | } | ||
| 1367 | } | ||
| 1368 | |||
| 1369 | DBG("pixel clock %d(kHz) not supported", pixel_rate); | ||
| 1370 | |||
| 1371 | return false; | ||
| 1372 | } | ||
| 1373 | |||
diff --git a/drivers/gpu/drm/msm/edp/edp_phy.c b/drivers/gpu/drm/msm/edp/edp_phy.c new file mode 100644 index 000000000000..36bb8933e9ee --- /dev/null +++ b/drivers/gpu/drm/msm/edp/edp_phy.c | |||
| @@ -0,0 +1,106 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 and | ||
| 6 | * only version 2 as published by the Free Software Foundation. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, | ||
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 11 | * GNU General Public License for more details. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include "edp.h" | ||
| 15 | #include "edp.xml.h" | ||
| 16 | |||
| 17 | #define EDP_MAX_LANE 4 | ||
| 18 | |||
| 19 | struct edp_phy { | ||
| 20 | void __iomem *base; | ||
| 21 | }; | ||
| 22 | |||
| 23 | bool msm_edp_phy_ready(struct edp_phy *phy) | ||
| 24 | { | ||
| 25 | u32 status; | ||
| 26 | int cnt = 100; | ||
| 27 | |||
| 28 | while (--cnt) { | ||
| 29 | status = edp_read(phy->base + | ||
| 30 | REG_EDP_PHY_GLB_PHY_STATUS); | ||
| 31 | if (status & 0x01) | ||
| 32 | break; | ||
| 33 | usleep_range(500, 1000); | ||
| 34 | } | ||
| 35 | |||
| 36 | if (cnt == 0) { | ||
| 37 | pr_err("%s: PHY NOT ready\n", __func__); | ||
| 38 | return false; | ||
| 39 | } else { | ||
| 40 | return true; | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | void msm_edp_phy_ctrl(struct edp_phy *phy, int enable) | ||
| 45 | { | ||
| 46 | DBG("enable=%d", enable); | ||
| 47 | if (enable) { | ||
| 48 | /* Reset */ | ||
| 49 | edp_write(phy->base + REG_EDP_PHY_CTRL, | ||
| 50 | EDP_PHY_CTRL_SW_RESET | EDP_PHY_CTRL_SW_RESET_PLL); | ||
| 51 | /* Make sure fully reset */ | ||
| 52 | wmb(); | ||
| 53 | usleep_range(500, 1000); | ||
| 54 | edp_write(phy->base + REG_EDP_PHY_CTRL, 0x000); | ||
| 55 | edp_write(phy->base + REG_EDP_PHY_GLB_PD_CTL, 0x3f); | ||
| 56 | edp_write(phy->base + REG_EDP_PHY_GLB_CFG, 0x1); | ||
| 57 | } else { | ||
| 58 | edp_write(phy->base + REG_EDP_PHY_GLB_PD_CTL, 0xc0); | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | /* voltage mode and pre emphasis cfg */ | ||
| 63 | void msm_edp_phy_vm_pe_init(struct edp_phy *phy) | ||
| 64 | { | ||
| 65 | edp_write(phy->base + REG_EDP_PHY_GLB_VM_CFG0, 0x3); | ||
| 66 | edp_write(phy->base + REG_EDP_PHY_GLB_VM_CFG1, 0x64); | ||
| 67 | edp_write(phy->base + REG_EDP_PHY_GLB_MISC9, 0x6c); | ||
| 68 | } | ||
| 69 | |||
| 70 | void msm_edp_phy_vm_pe_cfg(struct edp_phy *phy, u32 v0, u32 v1) | ||
| 71 | { | ||
| 72 | edp_write(phy->base + REG_EDP_PHY_GLB_VM_CFG0, v0); | ||
| 73 | edp_write(phy->base + REG_EDP_PHY_GLB_VM_CFG1, v1); | ||
| 74 | } | ||
| 75 | |||
| 76 | void msm_edp_phy_lane_power_ctrl(struct edp_phy *phy, bool up, u32 max_lane) | ||
| 77 | { | ||
| 78 | u32 i; | ||
| 79 | u32 data; | ||
| 80 | |||
| 81 | if (up) | ||
| 82 | data = 0; /* power up */ | ||
| 83 | else | ||
| 84 | data = 0x7; /* power down */ | ||
| 85 | |||
| 86 | for (i = 0; i < max_lane; i++) | ||
| 87 | edp_write(phy->base + REG_EDP_PHY_LN_PD_CTL(i) , data); | ||
| 88 | |||
| 89 | /* power down unused lane */ | ||
| 90 | data = 0x7; /* power down */ | ||
| 91 | for (i = max_lane; i < EDP_MAX_LANE; i++) | ||
| 92 | edp_write(phy->base + REG_EDP_PHY_LN_PD_CTL(i) , data); | ||
| 93 | } | ||
| 94 | |||
| 95 | void *msm_edp_phy_init(struct device *dev, void __iomem *regbase) | ||
| 96 | { | ||
| 97 | struct edp_phy *phy = NULL; | ||
| 98 | |||
| 99 | phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); | ||
| 100 | if (!phy) | ||
| 101 | return NULL; | ||
| 102 | |||
| 103 | phy->base = regbase; | ||
| 104 | return phy; | ||
| 105 | } | ||
| 106 | |||
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 95f7b8d0f3ef..814536202efe 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2014 The Linux Foundation. All rights reserved. | ||
| 2 | * Copyright (C) 2013 Red Hat | 3 | * Copyright (C) 2013 Red Hat |
| 3 | * Author: Rob Clark <robdclark@gmail.com> | 4 | * Author: Rob Clark <robdclark@gmail.com> |
| 4 | * | 5 | * |
| @@ -106,7 +107,12 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) | |||
| 106 | goto fail; | 107 | goto fail; |
| 107 | } | 108 | } |
| 108 | 109 | ||
| 109 | BUG_ON(config->hpd_reg_cnt > ARRAY_SIZE(hdmi->hpd_regs)); | 110 | hdmi->hpd_regs = devm_kzalloc(&pdev->dev, sizeof(hdmi->hpd_regs[0]) * |
| 111 | config->hpd_reg_cnt, GFP_KERNEL); | ||
| 112 | if (!hdmi->hpd_regs) { | ||
| 113 | ret = -ENOMEM; | ||
| 114 | goto fail; | ||
| 115 | } | ||
| 110 | for (i = 0; i < config->hpd_reg_cnt; i++) { | 116 | for (i = 0; i < config->hpd_reg_cnt; i++) { |
| 111 | struct regulator *reg; | 117 | struct regulator *reg; |
| 112 | 118 | ||
| @@ -122,7 +128,12 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) | |||
| 122 | hdmi->hpd_regs[i] = reg; | 128 | hdmi->hpd_regs[i] = reg; |
| 123 | } | 129 | } |
| 124 | 130 | ||
| 125 | BUG_ON(config->pwr_reg_cnt > ARRAY_SIZE(hdmi->pwr_regs)); | 131 | hdmi->pwr_regs = devm_kzalloc(&pdev->dev, sizeof(hdmi->pwr_regs[0]) * |
| 132 | config->pwr_reg_cnt, GFP_KERNEL); | ||
| 133 | if (!hdmi->pwr_regs) { | ||
| 134 | ret = -ENOMEM; | ||
| 135 | goto fail; | ||
| 136 | } | ||
| 126 | for (i = 0; i < config->pwr_reg_cnt; i++) { | 137 | for (i = 0; i < config->pwr_reg_cnt; i++) { |
| 127 | struct regulator *reg; | 138 | struct regulator *reg; |
| 128 | 139 | ||
| @@ -138,7 +149,12 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) | |||
| 138 | hdmi->pwr_regs[i] = reg; | 149 | hdmi->pwr_regs[i] = reg; |
| 139 | } | 150 | } |
| 140 | 151 | ||
| 141 | BUG_ON(config->hpd_clk_cnt > ARRAY_SIZE(hdmi->hpd_clks)); | 152 | hdmi->hpd_clks = devm_kzalloc(&pdev->dev, sizeof(hdmi->hpd_clks[0]) * |
| 153 | config->hpd_clk_cnt, GFP_KERNEL); | ||
| 154 | if (!hdmi->hpd_clks) { | ||
| 155 | ret = -ENOMEM; | ||
| 156 | goto fail; | ||
| 157 | } | ||
| 142 | for (i = 0; i < config->hpd_clk_cnt; i++) { | 158 | for (i = 0; i < config->hpd_clk_cnt; i++) { |
| 143 | struct clk *clk; | 159 | struct clk *clk; |
| 144 | 160 | ||
| @@ -153,7 +169,12 @@ static struct hdmi *hdmi_init(struct platform_device *pdev) | |||
| 153 | hdmi->hpd_clks[i] = clk; | 169 | hdmi->hpd_clks[i] = clk; |
| 154 | } | 170 | } |
| 155 | 171 | ||
| 156 | BUG_ON(config->pwr_clk_cnt > ARRAY_SIZE(hdmi->pwr_clks)); | 172 | hdmi->pwr_clks = devm_kzalloc(&pdev->dev, sizeof(hdmi->pwr_clks[0]) * |
| 173 | config->pwr_clk_cnt, GFP_KERNEL); | ||
| 174 | if (!hdmi->pwr_clks) { | ||
| 175 | ret = -ENOMEM; | ||
| 176 | goto fail; | ||
| 177 | } | ||
| 157 | for (i = 0; i < config->pwr_clk_cnt; i++) { | 178 | for (i = 0; i < config->pwr_clk_cnt; i++) { |
| 158 | struct clk *clk; | 179 | struct clk *clk; |
| 159 | 180 | ||
| @@ -266,6 +287,57 @@ fail: | |||
| 266 | 287 | ||
| 267 | #include <linux/of_gpio.h> | 288 | #include <linux/of_gpio.h> |
| 268 | 289 | ||
| 290 | #define HDMI_CFG(item, entry) \ | ||
| 291 | .item ## _names = item ##_names_ ## entry, \ | ||
| 292 | .item ## _cnt = ARRAY_SIZE(item ## _names_ ## entry) | ||
| 293 | |||
| 294 | static struct hdmi_platform_config hdmi_tx_8660_config = { | ||
| 295 | .phy_init = hdmi_phy_8x60_init, | ||
| 296 | }; | ||
| 297 | |||
| 298 | static const char *hpd_reg_names_8960[] = {"core-vdda", "hdmi-mux"}; | ||
| 299 | static const char *hpd_clk_names_8960[] = {"core_clk", "master_iface_clk", "slave_iface_clk"}; | ||
| 300 | |||
| 301 | static struct hdmi_platform_config hdmi_tx_8960_config = { | ||
| 302 | .phy_init = hdmi_phy_8960_init, | ||
| 303 | HDMI_CFG(hpd_reg, 8960), | ||
| 304 | HDMI_CFG(hpd_clk, 8960), | ||
| 305 | }; | ||
| 306 | |||
| 307 | static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"}; | ||
| 308 | static const char *hpd_reg_names_8x74[] = {"hpd-gdsc", "hpd-5v"}; | ||
| 309 | static const char *pwr_clk_names_8x74[] = {"extp_clk", "alt_iface_clk"}; | ||
| 310 | static const char *hpd_clk_names_8x74[] = {"iface_clk", "core_clk", "mdp_core_clk"}; | ||
| 311 | static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0}; | ||
| 312 | |||
| 313 | static struct hdmi_platform_config hdmi_tx_8074_config = { | ||
| 314 | .phy_init = hdmi_phy_8x74_init, | ||
| 315 | HDMI_CFG(pwr_reg, 8x74), | ||
| 316 | HDMI_CFG(hpd_reg, 8x74), | ||
| 317 | HDMI_CFG(pwr_clk, 8x74), | ||
| 318 | HDMI_CFG(hpd_clk, 8x74), | ||
| 319 | .hpd_freq = hpd_clk_freq_8x74, | ||
| 320 | }; | ||
| 321 | |||
| 322 | static const char *hpd_reg_names_8084[] = {"hpd-gdsc", "hpd-5v", "hpd-5v-en"}; | ||
| 323 | |||
| 324 | static struct hdmi_platform_config hdmi_tx_8084_config = { | ||
| 325 | .phy_init = hdmi_phy_8x74_init, | ||
| 326 | HDMI_CFG(pwr_reg, 8x74), | ||
| 327 | HDMI_CFG(hpd_reg, 8084), | ||
| 328 | HDMI_CFG(pwr_clk, 8x74), | ||
| 329 | HDMI_CFG(hpd_clk, 8x74), | ||
| 330 | .hpd_freq = hpd_clk_freq_8x74, | ||
| 331 | }; | ||
| 332 | |||
| 333 | static const struct of_device_id dt_match[] = { | ||
| 334 | { .compatible = "qcom,hdmi-tx-8084", .data = &hdmi_tx_8084_config }, | ||
| 335 | { .compatible = "qcom,hdmi-tx-8074", .data = &hdmi_tx_8074_config }, | ||
| 336 | { .compatible = "qcom,hdmi-tx-8960", .data = &hdmi_tx_8960_config }, | ||
| 337 | { .compatible = "qcom,hdmi-tx-8660", .data = &hdmi_tx_8660_config }, | ||
| 338 | {} | ||
| 339 | }; | ||
| 340 | |||
| 269 | #ifdef CONFIG_OF | 341 | #ifdef CONFIG_OF |
| 270 | static int get_gpio(struct device *dev, struct device_node *of_node, const char *name) | 342 | static int get_gpio(struct device *dev, struct device_node *of_node, const char *name) |
| 271 | { | 343 | { |
| @@ -288,50 +360,31 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) | |||
| 288 | { | 360 | { |
| 289 | struct drm_device *drm = dev_get_drvdata(master); | 361 | struct drm_device *drm = dev_get_drvdata(master); |
| 290 | struct msm_drm_private *priv = drm->dev_private; | 362 | struct msm_drm_private *priv = drm->dev_private; |
| 291 | static struct hdmi_platform_config config = {}; | 363 | static struct hdmi_platform_config *hdmi_cfg; |
| 292 | struct hdmi *hdmi; | 364 | struct hdmi *hdmi; |
| 293 | #ifdef CONFIG_OF | 365 | #ifdef CONFIG_OF |
| 294 | struct device_node *of_node = dev->of_node; | 366 | struct device_node *of_node = dev->of_node; |
| 367 | const struct of_device_id *match; | ||
| 295 | 368 | ||
| 296 | if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8074")) { | 369 | match = of_match_node(dt_match, of_node); |
| 297 | static const char *hpd_reg_names[] = {"hpd-gdsc", "hpd-5v"}; | 370 | if (match && match->data) { |
| 298 | static const char *pwr_reg_names[] = {"core-vdda", "core-vcc"}; | 371 | hdmi_cfg = (struct hdmi_platform_config *)match->data; |
| 299 | static const char *hpd_clk_names[] = {"iface_clk", "core_clk", "mdp_core_clk"}; | 372 | DBG("hdmi phy: %s", match->compatible); |
| 300 | static unsigned long hpd_clk_freq[] = {0, 19200000, 0}; | ||
| 301 | static const char *pwr_clk_names[] = {"extp_clk", "alt_iface_clk"}; | ||
| 302 | config.phy_init = hdmi_phy_8x74_init; | ||
| 303 | config.hpd_reg_names = hpd_reg_names; | ||
| 304 | config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); | ||
| 305 | config.pwr_reg_names = pwr_reg_names; | ||
| 306 | config.pwr_reg_cnt = ARRAY_SIZE(pwr_reg_names); | ||
| 307 | config.hpd_clk_names = hpd_clk_names; | ||
| 308 | config.hpd_freq = hpd_clk_freq; | ||
| 309 | config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); | ||
| 310 | config.pwr_clk_names = pwr_clk_names; | ||
| 311 | config.pwr_clk_cnt = ARRAY_SIZE(pwr_clk_names); | ||
| 312 | } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8960")) { | ||
| 313 | static const char *hpd_clk_names[] = {"core_clk", "master_iface_clk", "slave_iface_clk"}; | ||
| 314 | static const char *hpd_reg_names[] = {"core-vdda", "hdmi-mux"}; | ||
| 315 | config.phy_init = hdmi_phy_8960_init; | ||
| 316 | config.hpd_reg_names = hpd_reg_names; | ||
| 317 | config.hpd_reg_cnt = ARRAY_SIZE(hpd_reg_names); | ||
| 318 | config.hpd_clk_names = hpd_clk_names; | ||
| 319 | config.hpd_clk_cnt = ARRAY_SIZE(hpd_clk_names); | ||
| 320 | } else if (of_device_is_compatible(of_node, "qcom,hdmi-tx-8660")) { | ||
| 321 | config.phy_init = hdmi_phy_8x60_init; | ||
| 322 | } else { | 373 | } else { |
| 323 | dev_err(dev, "unknown phy: %s\n", of_node->name); | 374 | dev_err(dev, "unknown phy: %s\n", of_node->name); |
| 375 | return -ENXIO; | ||
| 324 | } | 376 | } |
| 325 | 377 | ||
| 326 | config.mmio_name = "core_physical"; | 378 | hdmi_cfg->mmio_name = "core_physical"; |
| 327 | config.ddc_clk_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-clk"); | 379 | hdmi_cfg->ddc_clk_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-clk"); |
| 328 | config.ddc_data_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-data"); | 380 | hdmi_cfg->ddc_data_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-ddc-data"); |
| 329 | config.hpd_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-hpd"); | 381 | hdmi_cfg->hpd_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-hpd"); |
| 330 | config.mux_en_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-en"); | 382 | hdmi_cfg->mux_en_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-en"); |
| 331 | config.mux_sel_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-sel"); | 383 | hdmi_cfg->mux_sel_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-sel"); |
| 332 | config.mux_lpm_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-lpm"); | 384 | hdmi_cfg->mux_lpm_gpio = get_gpio(dev, of_node, "qcom,hdmi-tx-mux-lpm"); |
| 333 | 385 | ||
| 334 | #else | 386 | #else |
| 387 | static struct hdmi_platform_config config = {}; | ||
| 335 | static const char *hpd_clk_names[] = { | 388 | static const char *hpd_clk_names[] = { |
| 336 | "core_clk", "master_iface_clk", "slave_iface_clk", | 389 | "core_clk", "master_iface_clk", "slave_iface_clk", |
| 337 | }; | 390 | }; |
| @@ -377,12 +430,15 @@ static int hdmi_bind(struct device *dev, struct device *master, void *data) | |||
| 377 | config.mux_en_gpio = -1; | 430 | config.mux_en_gpio = -1; |
| 378 | config.mux_sel_gpio = -1; | 431 | config.mux_sel_gpio = -1; |
| 379 | } | 432 | } |
| 433 | hdmi_cfg = &config; | ||
| 380 | #endif | 434 | #endif |
| 381 | dev->platform_data = &config; | 435 | dev->platform_data = hdmi_cfg; |
| 436 | |||
| 382 | hdmi = hdmi_init(to_platform_device(dev)); | 437 | hdmi = hdmi_init(to_platform_device(dev)); |
| 383 | if (IS_ERR(hdmi)) | 438 | if (IS_ERR(hdmi)) |
| 384 | return PTR_ERR(hdmi); | 439 | return PTR_ERR(hdmi); |
| 385 | priv->hdmi = hdmi; | 440 | priv->hdmi = hdmi; |
| 441 | |||
| 386 | return 0; | 442 | return 0; |
| 387 | } | 443 | } |
| 388 | 444 | ||
| @@ -413,13 +469,6 @@ static int hdmi_dev_remove(struct platform_device *pdev) | |||
| 413 | return 0; | 469 | return 0; |
| 414 | } | 470 | } |
| 415 | 471 | ||
| 416 | static const struct of_device_id dt_match[] = { | ||
| 417 | { .compatible = "qcom,hdmi-tx-8074" }, | ||
| 418 | { .compatible = "qcom,hdmi-tx-8960" }, | ||
| 419 | { .compatible = "qcom,hdmi-tx-8660" }, | ||
| 420 | {} | ||
| 421 | }; | ||
| 422 | |||
| 423 | static struct platform_driver hdmi_driver = { | 472 | static struct platform_driver hdmi_driver = { |
| 424 | .probe = hdmi_dev_probe, | 473 | .probe = hdmi_dev_probe, |
| 425 | .remove = hdmi_dev_remove, | 474 | .remove = hdmi_dev_remove, |
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index 4d4cad42a776..68fdfb3622a5 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h | |||
| @@ -52,10 +52,10 @@ struct hdmi { | |||
| 52 | 52 | ||
| 53 | void __iomem *mmio; | 53 | void __iomem *mmio; |
| 54 | 54 | ||
| 55 | struct regulator *hpd_regs[2]; | 55 | struct regulator **hpd_regs; |
| 56 | struct regulator *pwr_regs[2]; | 56 | struct regulator **pwr_regs; |
| 57 | struct clk *hpd_clks[3]; | 57 | struct clk **hpd_clks; |
| 58 | struct clk *pwr_clks[2]; | 58 | struct clk **pwr_clks; |
| 59 | 59 | ||
| 60 | struct hdmi_phy *phy; | 60 | struct hdmi_phy *phy; |
| 61 | struct i2c_adapter *i2c; | 61 | struct i2c_adapter *i2c; |
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h index 5b0844befbab..350988740e9f 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.xml.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.xml.h | |||
| @@ -8,18 +8,19 @@ http://github.com/freedreno/envytools/ | |||
| 8 | git clone https://github.com/freedreno/envytools.git | 8 | git clone https://github.com/freedreno/envytools.git |
| 9 | 9 | ||
| 10 | The rules-ng-ng source files this header was generated from are: | 10 | The rules-ng-ng source files this header was generated from are: |
| 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) | 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49) |
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) |
| 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) | 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) |
| 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) | 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) |
| 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) | 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) |
| 21 | - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) | ||
| 21 | 22 | ||
| 22 | Copyright (C) 2013-2014 by the following authors: | 23 | Copyright (C) 2013-2015 by the following authors: |
| 23 | - Rob Clark <robdclark@gmail.com> (robclark) | 24 | - Rob Clark <robdclark@gmail.com> (robclark) |
| 24 | 25 | ||
| 25 | Permission is hereby granted, free of charge, to any person obtaining | 26 | Permission is hereby granted, free of charge, to any person obtaining |
| @@ -45,12 +46,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
| 45 | 46 | ||
| 46 | 47 | ||
| 47 | enum hdmi_hdcp_key_state { | 48 | enum hdmi_hdcp_key_state { |
| 48 | NO_KEYS = 0, | 49 | HDCP_KEYS_STATE_NO_KEYS = 0, |
| 49 | NOT_CHECKED = 1, | 50 | HDCP_KEYS_STATE_NOT_CHECKED = 1, |
| 50 | CHECKING = 2, | 51 | HDCP_KEYS_STATE_CHECKING = 2, |
| 51 | KEYS_VALID = 3, | 52 | HDCP_KEYS_STATE_VALID = 3, |
| 52 | AKSV_INVALID = 4, | 53 | HDCP_KEYS_STATE_AKSV_NOT_VALID = 4, |
| 53 | CHECKSUM_MISMATCH = 5, | 54 | HDCP_KEYS_STATE_CHKSUM_MISMATCH = 5, |
| 55 | HDCP_KEYS_STATE_PROD_AKSV = 6, | ||
| 56 | HDCP_KEYS_STATE_RESERVED = 7, | ||
| 54 | }; | 57 | }; |
| 55 | 58 | ||
| 56 | enum hdmi_ddc_read_write { | 59 | enum hdmi_ddc_read_write { |
| @@ -199,11 +202,29 @@ static inline uint32_t HDMI_AUDIO_INFO1_LSV(uint32_t val) | |||
| 199 | #define HDMI_HDCP_CTRL_ENABLE 0x00000001 | 202 | #define HDMI_HDCP_CTRL_ENABLE 0x00000001 |
| 200 | #define HDMI_HDCP_CTRL_ENCRYPTION_ENABLE 0x00000100 | 203 | #define HDMI_HDCP_CTRL_ENCRYPTION_ENABLE 0x00000100 |
| 201 | 204 | ||
| 205 | #define REG_HDMI_HDCP_DEBUG_CTRL 0x00000114 | ||
| 206 | #define HDMI_HDCP_DEBUG_CTRL_RNG_CIPHER 0x00000004 | ||
| 207 | |||
| 202 | #define REG_HDMI_HDCP_INT_CTRL 0x00000118 | 208 | #define REG_HDMI_HDCP_INT_CTRL 0x00000118 |
| 209 | #define HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_INT 0x00000001 | ||
| 210 | #define HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_ACK 0x00000002 | ||
| 211 | #define HDMI_HDCP_INT_CTRL_AUTH_SUCCESS_MASK 0x00000004 | ||
| 212 | #define HDMI_HDCP_INT_CTRL_AUTH_FAIL_INT 0x00000010 | ||
| 213 | #define HDMI_HDCP_INT_CTRL_AUTH_FAIL_ACK 0x00000020 | ||
| 214 | #define HDMI_HDCP_INT_CTRL_AUTH_FAIL_MASK 0x00000040 | ||
| 215 | #define HDMI_HDCP_INT_CTRL_AUTH_FAIL_INFO_ACK 0x00000080 | ||
| 216 | #define HDMI_HDCP_INT_CTRL_AUTH_XFER_REQ_INT 0x00000100 | ||
| 217 | #define HDMI_HDCP_INT_CTRL_AUTH_XFER_REQ_ACK 0x00000200 | ||
| 218 | #define HDMI_HDCP_INT_CTRL_AUTH_XFER_REQ_MASK 0x00000400 | ||
| 219 | #define HDMI_HDCP_INT_CTRL_AUTH_XFER_DONE_INT 0x00001000 | ||
| 220 | #define HDMI_HDCP_INT_CTRL_AUTH_XFER_DONE_ACK 0x00002000 | ||
| 221 | #define HDMI_HDCP_INT_CTRL_AUTH_XFER_DONE_MASK 0x00004000 | ||
| 203 | 222 | ||
| 204 | #define REG_HDMI_HDCP_LINK0_STATUS 0x0000011c | 223 | #define REG_HDMI_HDCP_LINK0_STATUS 0x0000011c |
| 205 | #define HDMI_HDCP_LINK0_STATUS_AN_0_READY 0x00000100 | 224 | #define HDMI_HDCP_LINK0_STATUS_AN_0_READY 0x00000100 |
| 206 | #define HDMI_HDCP_LINK0_STATUS_AN_1_READY 0x00000200 | 225 | #define HDMI_HDCP_LINK0_STATUS_AN_1_READY 0x00000200 |
| 226 | #define HDMI_HDCP_LINK0_STATUS_RI_MATCHES 0x00001000 | ||
| 227 | #define HDMI_HDCP_LINK0_STATUS_V_MATCHES 0x00100000 | ||
| 207 | #define HDMI_HDCP_LINK0_STATUS_KEY_STATE__MASK 0x70000000 | 228 | #define HDMI_HDCP_LINK0_STATUS_KEY_STATE__MASK 0x70000000 |
| 208 | #define HDMI_HDCP_LINK0_STATUS_KEY_STATE__SHIFT 28 | 229 | #define HDMI_HDCP_LINK0_STATUS_KEY_STATE__SHIFT 28 |
| 209 | static inline uint32_t HDMI_HDCP_LINK0_STATUS_KEY_STATE(enum hdmi_hdcp_key_state val) | 230 | static inline uint32_t HDMI_HDCP_LINK0_STATUS_KEY_STATE(enum hdmi_hdcp_key_state val) |
| @@ -211,9 +232,56 @@ static inline uint32_t HDMI_HDCP_LINK0_STATUS_KEY_STATE(enum hdmi_hdcp_key_state | |||
| 211 | return ((val) << HDMI_HDCP_LINK0_STATUS_KEY_STATE__SHIFT) & HDMI_HDCP_LINK0_STATUS_KEY_STATE__MASK; | 232 | return ((val) << HDMI_HDCP_LINK0_STATUS_KEY_STATE__SHIFT) & HDMI_HDCP_LINK0_STATUS_KEY_STATE__MASK; |
| 212 | } | 233 | } |
| 213 | 234 | ||
| 235 | #define REG_HDMI_HDCP_DDC_CTRL_0 0x00000120 | ||
| 236 | #define HDMI_HDCP_DDC_CTRL_0_DISABLE 0x00000001 | ||
| 237 | |||
| 238 | #define REG_HDMI_HDCP_DDC_CTRL_1 0x00000124 | ||
| 239 | #define HDMI_HDCP_DDC_CTRL_1_FAILED_ACK 0x00000001 | ||
| 240 | |||
| 241 | #define REG_HDMI_HDCP_DDC_STATUS 0x00000128 | ||
| 242 | #define HDMI_HDCP_DDC_STATUS_XFER_REQ 0x00000010 | ||
| 243 | #define HDMI_HDCP_DDC_STATUS_XFER_DONE 0x00000400 | ||
| 244 | #define HDMI_HDCP_DDC_STATUS_ABORTED 0x00001000 | ||
| 245 | #define HDMI_HDCP_DDC_STATUS_TIMEOUT 0x00002000 | ||
| 246 | #define HDMI_HDCP_DDC_STATUS_NACK0 0x00004000 | ||
| 247 | #define HDMI_HDCP_DDC_STATUS_NACK1 0x00008000 | ||
| 248 | #define HDMI_HDCP_DDC_STATUS_FAILED 0x00010000 | ||
| 249 | |||
| 250 | #define REG_HDMI_HDCP_ENTROPY_CTRL0 0x0000012c | ||
| 251 | |||
| 252 | #define REG_HDMI_HDCP_ENTROPY_CTRL1 0x0000025c | ||
| 253 | |||
| 214 | #define REG_HDMI_HDCP_RESET 0x00000130 | 254 | #define REG_HDMI_HDCP_RESET 0x00000130 |
| 215 | #define HDMI_HDCP_RESET_LINK0_DEAUTHENTICATE 0x00000001 | 255 | #define HDMI_HDCP_RESET_LINK0_DEAUTHENTICATE 0x00000001 |
| 216 | 256 | ||
| 257 | #define REG_HDMI_HDCP_RCVPORT_DATA0 0x00000134 | ||
| 258 | |||
| 259 | #define REG_HDMI_HDCP_RCVPORT_DATA1 0x00000138 | ||
| 260 | |||
| 261 | #define REG_HDMI_HDCP_RCVPORT_DATA2_0 0x0000013c | ||
| 262 | |||
| 263 | #define REG_HDMI_HDCP_RCVPORT_DATA2_1 0x00000140 | ||
| 264 | |||
| 265 | #define REG_HDMI_HDCP_RCVPORT_DATA3 0x00000144 | ||
| 266 | |||
| 267 | #define REG_HDMI_HDCP_RCVPORT_DATA4 0x00000148 | ||
| 268 | |||
| 269 | #define REG_HDMI_HDCP_RCVPORT_DATA5 0x0000014c | ||
| 270 | |||
| 271 | #define REG_HDMI_HDCP_RCVPORT_DATA6 0x00000150 | ||
| 272 | |||
| 273 | #define REG_HDMI_HDCP_RCVPORT_DATA7 0x00000154 | ||
| 274 | |||
| 275 | #define REG_HDMI_HDCP_RCVPORT_DATA8 0x00000158 | ||
| 276 | |||
| 277 | #define REG_HDMI_HDCP_RCVPORT_DATA9 0x0000015c | ||
| 278 | |||
| 279 | #define REG_HDMI_HDCP_RCVPORT_DATA10 0x00000160 | ||
| 280 | |||
| 281 | #define REG_HDMI_HDCP_RCVPORT_DATA11 0x00000164 | ||
| 282 | |||
| 283 | #define REG_HDMI_HDCP_RCVPORT_DATA12 0x00000168 | ||
| 284 | |||
| 217 | #define REG_HDMI_VENSPEC_INFO0 0x0000016c | 285 | #define REG_HDMI_VENSPEC_INFO0 0x0000016c |
| 218 | 286 | ||
| 219 | #define REG_HDMI_VENSPEC_INFO1 0x00000170 | 287 | #define REG_HDMI_VENSPEC_INFO1 0x00000170 |
| @@ -266,6 +334,7 @@ static inline uint32_t HDMI_DDC_CTRL_TRANSACTION_CNT(uint32_t val) | |||
| 266 | #define HDMI_DDC_SW_STATUS_NACK3 0x00008000 | 334 | #define HDMI_DDC_SW_STATUS_NACK3 0x00008000 |
| 267 | 335 | ||
| 268 | #define REG_HDMI_DDC_HW_STATUS 0x0000021c | 336 | #define REG_HDMI_DDC_HW_STATUS 0x0000021c |
| 337 | #define HDMI_DDC_HW_STATUS_DONE 0x00000008 | ||
| 269 | 338 | ||
| 270 | #define REG_HDMI_DDC_SPEED 0x00000220 | 339 | #define REG_HDMI_DDC_SPEED 0x00000220 |
| 271 | #define HDMI_DDC_SPEED_THRESHOLD__MASK 0x00000003 | 340 | #define HDMI_DDC_SPEED_THRESHOLD__MASK 0x00000003 |
| @@ -329,6 +398,15 @@ static inline uint32_t HDMI_DDC_DATA_INDEX(uint32_t val) | |||
| 329 | } | 398 | } |
| 330 | #define HDMI_DDC_DATA_INDEX_WRITE 0x80000000 | 399 | #define HDMI_DDC_DATA_INDEX_WRITE 0x80000000 |
| 331 | 400 | ||
| 401 | #define REG_HDMI_HDCP_SHA_CTRL 0x0000023c | ||
| 402 | |||
| 403 | #define REG_HDMI_HDCP_SHA_STATUS 0x00000240 | ||
| 404 | #define HDMI_HDCP_SHA_STATUS_BLOCK_DONE 0x00000001 | ||
| 405 | #define HDMI_HDCP_SHA_STATUS_COMP_DONE 0x00000010 | ||
| 406 | |||
| 407 | #define REG_HDMI_HDCP_SHA_DATA 0x00000244 | ||
| 408 | #define HDMI_HDCP_SHA_DATA_DONE 0x00000001 | ||
| 409 | |||
| 332 | #define REG_HDMI_HPD_INT_STATUS 0x00000250 | 410 | #define REG_HDMI_HPD_INT_STATUS 0x00000250 |
| 333 | #define HDMI_HPD_INT_STATUS_INT 0x00000001 | 411 | #define HDMI_HPD_INT_STATUS_INT 0x00000001 |
| 334 | #define HDMI_HPD_INT_STATUS_CABLE_DETECTED 0x00000002 | 412 | #define HDMI_HPD_INT_STATUS_CABLE_DETECTED 0x00000002 |
| @@ -359,6 +437,10 @@ static inline uint32_t HDMI_DDC_REF_REFTIMER(uint32_t val) | |||
| 359 | return ((val) << HDMI_DDC_REF_REFTIMER__SHIFT) & HDMI_DDC_REF_REFTIMER__MASK; | 437 | return ((val) << HDMI_DDC_REF_REFTIMER__SHIFT) & HDMI_DDC_REF_REFTIMER__MASK; |
| 360 | } | 438 | } |
| 361 | 439 | ||
| 440 | #define REG_HDMI_HDCP_SW_UPPER_AKSV 0x00000284 | ||
| 441 | |||
| 442 | #define REG_HDMI_HDCP_SW_LOWER_AKSV 0x00000288 | ||
| 443 | |||
| 362 | #define REG_HDMI_CEC_STATUS 0x00000298 | 444 | #define REG_HDMI_CEC_STATUS 0x00000298 |
| 363 | 445 | ||
| 364 | #define REG_HDMI_CEC_INT 0x0000029c | 446 | #define REG_HDMI_CEC_INT 0x0000029c |
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index d6f8d5818e18..a7a1d8267cf0 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | |||
| @@ -25,8 +25,6 @@ struct hdmi_bridge { | |||
| 25 | 25 | ||
| 26 | void hdmi_bridge_destroy(struct drm_bridge *bridge) | 26 | void hdmi_bridge_destroy(struct drm_bridge *bridge) |
| 27 | { | 27 | { |
| 28 | struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); | ||
| 29 | kfree(hdmi_bridge); | ||
| 30 | } | 28 | } |
| 31 | 29 | ||
| 32 | static void power_on(struct drm_bridge *bridge) | 30 | static void power_on(struct drm_bridge *bridge) |
| @@ -209,7 +207,8 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi) | |||
| 209 | struct hdmi_bridge *hdmi_bridge; | 207 | struct hdmi_bridge *hdmi_bridge; |
| 210 | int ret; | 208 | int ret; |
| 211 | 209 | ||
| 212 | hdmi_bridge = kzalloc(sizeof(*hdmi_bridge), GFP_KERNEL); | 210 | hdmi_bridge = devm_kzalloc(hdmi->dev->dev, |
| 211 | sizeof(*hdmi_bridge), GFP_KERNEL); | ||
| 213 | if (!hdmi_bridge) { | 212 | if (!hdmi_bridge) { |
| 214 | ret = -ENOMEM; | 213 | ret = -ENOMEM; |
| 215 | goto fail; | 214 | goto fail; |
| @@ -220,7 +219,9 @@ struct drm_bridge *hdmi_bridge_init(struct hdmi *hdmi) | |||
| 220 | bridge = &hdmi_bridge->base; | 219 | bridge = &hdmi_bridge->base; |
| 221 | bridge->funcs = &hdmi_bridge_funcs; | 220 | bridge->funcs = &hdmi_bridge_funcs; |
| 222 | 221 | ||
| 223 | drm_bridge_attach(hdmi->dev, bridge); | 222 | ret = drm_bridge_attach(hdmi->dev, bridge); |
| 223 | if (ret) | ||
| 224 | goto fail; | ||
| 224 | 225 | ||
| 225 | return bridge; | 226 | return bridge; |
| 226 | 227 | ||
diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c index b4e70e0e3cfa..b62cdb968614 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_connector.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_connector.c | |||
| @@ -386,7 +386,7 @@ hdmi_connector_best_encoder(struct drm_connector *connector) | |||
| 386 | } | 386 | } |
| 387 | 387 | ||
| 388 | static const struct drm_connector_funcs hdmi_connector_funcs = { | 388 | static const struct drm_connector_funcs hdmi_connector_funcs = { |
| 389 | .dpms = drm_helper_connector_dpms, | 389 | .dpms = drm_atomic_helper_connector_dpms, |
| 390 | .detect = hdmi_connector_detect, | 390 | .detect = hdmi_connector_detect, |
| 391 | .fill_modes = drm_helper_probe_single_connector_modes, | 391 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 392 | .destroy = hdmi_connector_destroy, | 392 | .destroy = hdmi_connector_destroy, |
| @@ -426,7 +426,7 @@ struct drm_connector *hdmi_connector_init(struct hdmi *hdmi) | |||
| 426 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | | 426 | connector->polled = DRM_CONNECTOR_POLL_CONNECT | |
| 427 | DRM_CONNECTOR_POLL_DISCONNECT; | 427 | DRM_CONNECTOR_POLL_DISCONNECT; |
| 428 | 428 | ||
| 429 | connector->interlace_allowed = 1; | 429 | connector->interlace_allowed = 0; |
| 430 | connector->doublescan_allowed = 0; | 430 | connector->doublescan_allowed = 0; |
| 431 | 431 | ||
| 432 | drm_connector_register(connector); | 432 | drm_connector_register(connector); |
diff --git a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h index 29bd796797de..43bb54a9afbf 100644 --- a/drivers/gpu/drm/msm/hdmi/qfprom.xml.h +++ b/drivers/gpu/drm/msm/hdmi/qfprom.xml.h | |||
| @@ -8,16 +8,17 @@ http://github.com/freedreno/envytools/ | |||
| 8 | git clone https://github.com/freedreno/envytools.git | 8 | git clone https://github.com/freedreno/envytools.git |
| 9 | 9 | ||
| 10 | The rules-ng-ng source files this header was generated from are: | 10 | The rules-ng-ng source files this header was generated from are: |
| 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) | 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49) |
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) |
| 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) | 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) |
| 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) | 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) |
| 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) | 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) |
| 21 | - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) | ||
| 21 | 22 | ||
| 22 | Copyright (C) 2013 by the following authors: | 23 | Copyright (C) 2013 by the following authors: |
| 23 | - Rob Clark <robdclark@gmail.com> (robclark) | 24 | - Rob Clark <robdclark@gmail.com> (robclark) |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h index a4a7f8c7122a..1d39174d91fb 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h | |||
| @@ -8,16 +8,17 @@ http://github.com/freedreno/envytools/ | |||
| 8 | git clone https://github.com/freedreno/envytools.git | 8 | git clone https://github.com/freedreno/envytools.git |
| 9 | 9 | ||
| 10 | The rules-ng-ng source files this header was generated from are: | 10 | The rules-ng-ng source files this header was generated from are: |
| 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) | 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49) |
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) |
| 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) | 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) |
| 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) | 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) |
| 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) | 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) |
| 21 | - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) | ||
| 21 | 22 | ||
| 22 | Copyright (C) 2013-2014 by the following authors: | 23 | Copyright (C) 2013-2014 by the following authors: |
| 23 | - Rob Clark <robdclark@gmail.com> (robclark) | 24 | - Rob Clark <robdclark@gmail.com> (robclark) |
| @@ -72,6 +73,18 @@ enum mdp4_cursor_format { | |||
| 72 | CURSOR_XRGB = 2, | 73 | CURSOR_XRGB = 2, |
| 73 | }; | 74 | }; |
| 74 | 75 | ||
| 76 | enum mdp4_frame_format { | ||
| 77 | FRAME_LINEAR = 0, | ||
| 78 | FRAME_TILE_ARGB_4X4 = 1, | ||
| 79 | FRAME_TILE_YCBCR_420 = 2, | ||
| 80 | }; | ||
| 81 | |||
| 82 | enum mdp4_scale_unit { | ||
| 83 | SCALE_FIR = 0, | ||
| 84 | SCALE_MN_PHASE = 1, | ||
| 85 | SCALE_PIXEL_RPT = 2, | ||
| 86 | }; | ||
| 87 | |||
| 75 | enum mdp4_dma { | 88 | enum mdp4_dma { |
| 76 | DMA_P = 0, | 89 | DMA_P = 0, |
| 77 | DMA_S = 1, | 90 | DMA_S = 1, |
| @@ -637,6 +650,8 @@ static inline uint32_t REG_MDP4_PIPE_SRCP1_BASE(enum mdp4_pipe i0) { return 0x00 | |||
| 637 | 650 | ||
| 638 | static inline uint32_t REG_MDP4_PIPE_SRCP2_BASE(enum mdp4_pipe i0) { return 0x00020018 + 0x10000*i0; } | 651 | static inline uint32_t REG_MDP4_PIPE_SRCP2_BASE(enum mdp4_pipe i0) { return 0x00020018 + 0x10000*i0; } |
| 639 | 652 | ||
| 653 | static inline uint32_t REG_MDP4_PIPE_SRCP3_BASE(enum mdp4_pipe i0) { return 0x0002001c + 0x10000*i0; } | ||
| 654 | |||
| 640 | static inline uint32_t REG_MDP4_PIPE_SRC_STRIDE_A(enum mdp4_pipe i0) { return 0x00020040 + 0x10000*i0; } | 655 | static inline uint32_t REG_MDP4_PIPE_SRC_STRIDE_A(enum mdp4_pipe i0) { return 0x00020040 + 0x10000*i0; } |
| 641 | #define MDP4_PIPE_SRC_STRIDE_A_P0__MASK 0x0000ffff | 656 | #define MDP4_PIPE_SRC_STRIDE_A_P0__MASK 0x0000ffff |
| 642 | #define MDP4_PIPE_SRC_STRIDE_A_P0__SHIFT 0 | 657 | #define MDP4_PIPE_SRC_STRIDE_A_P0__SHIFT 0 |
| @@ -720,7 +735,25 @@ static inline uint32_t MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(uint32_t val) | |||
| 720 | } | 735 | } |
| 721 | #define MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT 0x00020000 | 736 | #define MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT 0x00020000 |
| 722 | #define MDP4_PIPE_SRC_FORMAT_UNPACK_ALIGN_MSB 0x00040000 | 737 | #define MDP4_PIPE_SRC_FORMAT_UNPACK_ALIGN_MSB 0x00040000 |
| 738 | #define MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__MASK 0x00180000 | ||
| 739 | #define MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__SHIFT 19 | ||
| 740 | static inline uint32_t MDP4_PIPE_SRC_FORMAT_FETCH_PLANES(uint32_t val) | ||
| 741 | { | ||
| 742 | return ((val) << MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__SHIFT) & MDP4_PIPE_SRC_FORMAT_FETCH_PLANES__MASK; | ||
| 743 | } | ||
| 723 | #define MDP4_PIPE_SRC_FORMAT_SOLID_FILL 0x00400000 | 744 | #define MDP4_PIPE_SRC_FORMAT_SOLID_FILL 0x00400000 |
| 745 | #define MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK 0x0c000000 | ||
| 746 | #define MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT 26 | ||
| 747 | static inline uint32_t MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP(enum mdp_chroma_samp_type val) | ||
| 748 | { | ||
| 749 | return ((val) << MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT) & MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK; | ||
| 750 | } | ||
| 751 | #define MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__MASK 0x60000000 | ||
| 752 | #define MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__SHIFT 29 | ||
| 753 | static inline uint32_t MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT(enum mdp4_frame_format val) | ||
| 754 | { | ||
| 755 | return ((val) << MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__SHIFT) & MDP4_PIPE_SRC_FORMAT_FRAME_FORMAT__MASK; | ||
| 756 | } | ||
| 724 | 757 | ||
| 725 | static inline uint32_t REG_MDP4_PIPE_SRC_UNPACK(enum mdp4_pipe i0) { return 0x00020054 + 0x10000*i0; } | 758 | static inline uint32_t REG_MDP4_PIPE_SRC_UNPACK(enum mdp4_pipe i0) { return 0x00020054 + 0x10000*i0; } |
| 726 | #define MDP4_PIPE_SRC_UNPACK_ELEM0__MASK 0x000000ff | 759 | #define MDP4_PIPE_SRC_UNPACK_ELEM0__MASK 0x000000ff |
| @@ -751,6 +784,18 @@ static inline uint32_t MDP4_PIPE_SRC_UNPACK_ELEM3(uint32_t val) | |||
| 751 | static inline uint32_t REG_MDP4_PIPE_OP_MODE(enum mdp4_pipe i0) { return 0x00020058 + 0x10000*i0; } | 784 | static inline uint32_t REG_MDP4_PIPE_OP_MODE(enum mdp4_pipe i0) { return 0x00020058 + 0x10000*i0; } |
| 752 | #define MDP4_PIPE_OP_MODE_SCALEX_EN 0x00000001 | 785 | #define MDP4_PIPE_OP_MODE_SCALEX_EN 0x00000001 |
| 753 | #define MDP4_PIPE_OP_MODE_SCALEY_EN 0x00000002 | 786 | #define MDP4_PIPE_OP_MODE_SCALEY_EN 0x00000002 |
| 787 | #define MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__MASK 0x0000000c | ||
| 788 | #define MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__SHIFT 2 | ||
| 789 | static inline uint32_t MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL(enum mdp4_scale_unit val) | ||
| 790 | { | ||
| 791 | return ((val) << MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__SHIFT) & MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL__MASK; | ||
| 792 | } | ||
| 793 | #define MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__MASK 0x00000030 | ||
| 794 | #define MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__SHIFT 4 | ||
| 795 | static inline uint32_t MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL(enum mdp4_scale_unit val) | ||
| 796 | { | ||
| 797 | return ((val) << MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__SHIFT) & MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL__MASK; | ||
| 798 | } | ||
| 754 | #define MDP4_PIPE_OP_MODE_SRC_YCBCR 0x00000200 | 799 | #define MDP4_PIPE_OP_MODE_SRC_YCBCR 0x00000200 |
| 755 | #define MDP4_PIPE_OP_MODE_DST_YCBCR 0x00000400 | 800 | #define MDP4_PIPE_OP_MODE_DST_YCBCR 0x00000400 |
| 756 | #define MDP4_PIPE_OP_MODE_CSC_EN 0x00000800 | 801 | #define MDP4_PIPE_OP_MODE_CSC_EN 0x00000800 |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c index 20ae50385e5b..73afa21822b4 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c | |||
| @@ -140,26 +140,6 @@ static void mdp4_crtc_destroy(struct drm_crtc *crtc) | |||
| 140 | kfree(mdp4_crtc); | 140 | kfree(mdp4_crtc); |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | static void mdp4_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
| 144 | { | ||
| 145 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | ||
| 146 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
| 147 | bool enabled = (mode == DRM_MODE_DPMS_ON); | ||
| 148 | |||
| 149 | DBG("%s: mode=%d", mdp4_crtc->name, mode); | ||
| 150 | |||
| 151 | if (enabled != mdp4_crtc->enabled) { | ||
| 152 | if (enabled) { | ||
| 153 | mdp4_enable(mdp4_kms); | ||
| 154 | mdp_irq_register(&mdp4_kms->base, &mdp4_crtc->err); | ||
| 155 | } else { | ||
| 156 | mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); | ||
| 157 | mdp4_disable(mdp4_kms); | ||
| 158 | } | ||
| 159 | mdp4_crtc->enabled = enabled; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | static bool mdp4_crtc_mode_fixup(struct drm_crtc *crtc, | 143 | static bool mdp4_crtc_mode_fixup(struct drm_crtc *crtc, |
| 164 | const struct drm_display_mode *mode, | 144 | const struct drm_display_mode *mode, |
| 165 | struct drm_display_mode *adjusted_mode) | 145 | struct drm_display_mode *adjusted_mode) |
| @@ -304,23 +284,38 @@ static void mdp4_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
| 304 | } | 284 | } |
| 305 | } | 285 | } |
| 306 | 286 | ||
| 307 | static void mdp4_crtc_prepare(struct drm_crtc *crtc) | 287 | static void mdp4_crtc_disable(struct drm_crtc *crtc) |
| 308 | { | 288 | { |
| 309 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); | 289 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
| 290 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
| 291 | |||
| 310 | DBG("%s", mdp4_crtc->name); | 292 | DBG("%s", mdp4_crtc->name); |
| 311 | /* make sure we hold a ref to mdp clks while setting up mode: */ | 293 | |
| 312 | drm_crtc_vblank_get(crtc); | 294 | if (WARN_ON(!mdp4_crtc->enabled)) |
| 313 | mdp4_enable(get_kms(crtc)); | 295 | return; |
| 314 | mdp4_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 296 | |
| 297 | mdp_irq_unregister(&mdp4_kms->base, &mdp4_crtc->err); | ||
| 298 | mdp4_disable(mdp4_kms); | ||
| 299 | |||
| 300 | mdp4_crtc->enabled = false; | ||
| 315 | } | 301 | } |
| 316 | 302 | ||
| 317 | static void mdp4_crtc_commit(struct drm_crtc *crtc) | 303 | static void mdp4_crtc_enable(struct drm_crtc *crtc) |
| 318 | { | 304 | { |
| 319 | mdp4_crtc_dpms(crtc, DRM_MODE_DPMS_ON); | 305 | struct mdp4_crtc *mdp4_crtc = to_mdp4_crtc(crtc); |
| 306 | struct mdp4_kms *mdp4_kms = get_kms(crtc); | ||
| 307 | |||
| 308 | DBG("%s", mdp4_crtc->name); | ||
| 309 | |||
| 310 | if (WARN_ON(mdp4_crtc->enabled)) | ||
| 311 | return; | ||
| 312 | |||
| 313 | mdp4_enable(mdp4_kms); | ||
| 314 | mdp_irq_register(&mdp4_kms->base, &mdp4_crtc->err); | ||
| 315 | |||
| 320 | crtc_flush(crtc); | 316 | crtc_flush(crtc); |
| 321 | /* drop the ref to mdp clk's that we got in prepare: */ | 317 | |
| 322 | mdp4_disable(get_kms(crtc)); | 318 | mdp4_crtc->enabled = true; |
| 323 | drm_crtc_vblank_put(crtc); | ||
| 324 | } | 319 | } |
| 325 | 320 | ||
| 326 | static int mdp4_crtc_atomic_check(struct drm_crtc *crtc, | 321 | static int mdp4_crtc_atomic_check(struct drm_crtc *crtc, |
| @@ -504,13 +499,10 @@ static const struct drm_crtc_funcs mdp4_crtc_funcs = { | |||
| 504 | }; | 499 | }; |
| 505 | 500 | ||
| 506 | static const struct drm_crtc_helper_funcs mdp4_crtc_helper_funcs = { | 501 | static const struct drm_crtc_helper_funcs mdp4_crtc_helper_funcs = { |
| 507 | .dpms = mdp4_crtc_dpms, | ||
| 508 | .mode_fixup = mdp4_crtc_mode_fixup, | 502 | .mode_fixup = mdp4_crtc_mode_fixup, |
| 509 | .mode_set_nofb = mdp4_crtc_mode_set_nofb, | 503 | .mode_set_nofb = mdp4_crtc_mode_set_nofb, |
| 510 | .mode_set = drm_helper_crtc_mode_set, | 504 | .disable = mdp4_crtc_disable, |
| 511 | .mode_set_base = drm_helper_crtc_mode_set_base, | 505 | .enable = mdp4_crtc_enable, |
| 512 | .prepare = mdp4_crtc_prepare, | ||
| 513 | .commit = mdp4_crtc_commit, | ||
| 514 | .atomic_check = mdp4_crtc_atomic_check, | 506 | .atomic_check = mdp4_crtc_atomic_check, |
| 515 | .atomic_begin = mdp4_crtc_atomic_begin, | 507 | .atomic_begin = mdp4_crtc_atomic_begin, |
| 516 | .atomic_flush = mdp4_crtc_atomic_flush, | 508 | .atomic_flush = mdp4_crtc_atomic_flush, |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c index c3878420180b..7896323b2631 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_dtv_encoder.c | |||
| @@ -94,61 +94,6 @@ static const struct drm_encoder_funcs mdp4_dtv_encoder_funcs = { | |||
| 94 | .destroy = mdp4_dtv_encoder_destroy, | 94 | .destroy = mdp4_dtv_encoder_destroy, |
| 95 | }; | 95 | }; |
| 96 | 96 | ||
| 97 | static void mdp4_dtv_encoder_dpms(struct drm_encoder *encoder, int mode) | ||
| 98 | { | ||
| 99 | struct drm_device *dev = encoder->dev; | ||
| 100 | struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder); | ||
| 101 | struct mdp4_kms *mdp4_kms = get_kms(encoder); | ||
| 102 | bool enabled = (mode == DRM_MODE_DPMS_ON); | ||
| 103 | |||
| 104 | DBG("mode=%d", mode); | ||
| 105 | |||
| 106 | if (enabled == mdp4_dtv_encoder->enabled) | ||
| 107 | return; | ||
| 108 | |||
| 109 | if (enabled) { | ||
| 110 | unsigned long pc = mdp4_dtv_encoder->pixclock; | ||
| 111 | int ret; | ||
| 112 | |||
| 113 | bs_set(mdp4_dtv_encoder, 1); | ||
| 114 | |||
| 115 | DBG("setting src_clk=%lu", pc); | ||
| 116 | |||
| 117 | ret = clk_set_rate(mdp4_dtv_encoder->src_clk, pc); | ||
| 118 | if (ret) | ||
| 119 | dev_err(dev->dev, "failed to set src_clk to %lu: %d\n", pc, ret); | ||
| 120 | clk_prepare_enable(mdp4_dtv_encoder->src_clk); | ||
| 121 | ret = clk_prepare_enable(mdp4_dtv_encoder->hdmi_clk); | ||
| 122 | if (ret) | ||
| 123 | dev_err(dev->dev, "failed to enable hdmi_clk: %d\n", ret); | ||
| 124 | ret = clk_prepare_enable(mdp4_dtv_encoder->mdp_clk); | ||
| 125 | if (ret) | ||
| 126 | dev_err(dev->dev, "failed to enabled mdp_clk: %d\n", ret); | ||
| 127 | |||
| 128 | mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 1); | ||
| 129 | } else { | ||
| 130 | mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0); | ||
| 131 | |||
| 132 | /* | ||
| 133 | * Wait for a vsync so we know the ENABLE=0 latched before | ||
| 134 | * the (connector) source of the vsync's gets disabled, | ||
| 135 | * otherwise we end up in a funny state if we re-enable | ||
| 136 | * before the disable latches, which results that some of | ||
| 137 | * the settings changes for the new modeset (like new | ||
| 138 | * scanout buffer) don't latch properly.. | ||
| 139 | */ | ||
| 140 | mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_EXTERNAL_VSYNC); | ||
| 141 | |||
| 142 | clk_disable_unprepare(mdp4_dtv_encoder->src_clk); | ||
| 143 | clk_disable_unprepare(mdp4_dtv_encoder->hdmi_clk); | ||
| 144 | clk_disable_unprepare(mdp4_dtv_encoder->mdp_clk); | ||
| 145 | |||
| 146 | bs_set(mdp4_dtv_encoder, 0); | ||
| 147 | } | ||
| 148 | |||
| 149 | mdp4_dtv_encoder->enabled = enabled; | ||
| 150 | } | ||
| 151 | |||
| 152 | static bool mdp4_dtv_encoder_mode_fixup(struct drm_encoder *encoder, | 97 | static bool mdp4_dtv_encoder_mode_fixup(struct drm_encoder *encoder, |
| 153 | const struct drm_display_mode *mode, | 98 | const struct drm_display_mode *mode, |
| 154 | struct drm_display_mode *adjusted_mode) | 99 | struct drm_display_mode *adjusted_mode) |
| @@ -221,28 +166,78 @@ static void mdp4_dtv_encoder_mode_set(struct drm_encoder *encoder, | |||
| 221 | mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VEND, 0); | 166 | mdp4_write(mdp4_kms, REG_MDP4_DTV_ACTIVE_VEND, 0); |
| 222 | } | 167 | } |
| 223 | 168 | ||
| 224 | static void mdp4_dtv_encoder_prepare(struct drm_encoder *encoder) | 169 | static void mdp4_dtv_encoder_disable(struct drm_encoder *encoder) |
| 225 | { | 170 | { |
| 226 | mdp4_dtv_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 171 | struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder); |
| 172 | struct mdp4_kms *mdp4_kms = get_kms(encoder); | ||
| 173 | |||
| 174 | if (WARN_ON(!mdp4_dtv_encoder->enabled)) | ||
| 175 | return; | ||
| 176 | |||
| 177 | mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 0); | ||
| 178 | |||
| 179 | /* | ||
| 180 | * Wait for a vsync so we know the ENABLE=0 latched before | ||
| 181 | * the (connector) source of the vsync's gets disabled, | ||
| 182 | * otherwise we end up in a funny state if we re-enable | ||
| 183 | * before the disable latches, which results that some of | ||
| 184 | * the settings changes for the new modeset (like new | ||
| 185 | * scanout buffer) don't latch properly.. | ||
| 186 | */ | ||
| 187 | mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_EXTERNAL_VSYNC); | ||
| 188 | |||
| 189 | clk_disable_unprepare(mdp4_dtv_encoder->src_clk); | ||
| 190 | clk_disable_unprepare(mdp4_dtv_encoder->hdmi_clk); | ||
| 191 | clk_disable_unprepare(mdp4_dtv_encoder->mdp_clk); | ||
| 192 | |||
| 193 | bs_set(mdp4_dtv_encoder, 0); | ||
| 194 | |||
| 195 | mdp4_dtv_encoder->enabled = false; | ||
| 227 | } | 196 | } |
| 228 | 197 | ||
| 229 | static void mdp4_dtv_encoder_commit(struct drm_encoder *encoder) | 198 | static void mdp4_dtv_encoder_enable(struct drm_encoder *encoder) |
| 230 | { | 199 | { |
| 200 | struct drm_device *dev = encoder->dev; | ||
| 201 | struct mdp4_dtv_encoder *mdp4_dtv_encoder = to_mdp4_dtv_encoder(encoder); | ||
| 202 | struct mdp4_kms *mdp4_kms = get_kms(encoder); | ||
| 203 | unsigned long pc = mdp4_dtv_encoder->pixclock; | ||
| 204 | int ret; | ||
| 205 | |||
| 206 | if (WARN_ON(mdp4_dtv_encoder->enabled)) | ||
| 207 | return; | ||
| 208 | |||
| 231 | mdp4_crtc_set_config(encoder->crtc, | 209 | mdp4_crtc_set_config(encoder->crtc, |
| 232 | MDP4_DMA_CONFIG_R_BPC(BPC8) | | 210 | MDP4_DMA_CONFIG_R_BPC(BPC8) | |
| 233 | MDP4_DMA_CONFIG_G_BPC(BPC8) | | 211 | MDP4_DMA_CONFIG_G_BPC(BPC8) | |
| 234 | MDP4_DMA_CONFIG_B_BPC(BPC8) | | 212 | MDP4_DMA_CONFIG_B_BPC(BPC8) | |
| 235 | MDP4_DMA_CONFIG_PACK(0x21)); | 213 | MDP4_DMA_CONFIG_PACK(0x21)); |
| 236 | mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 1); | 214 | mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 1); |
| 237 | mdp4_dtv_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | 215 | |
| 216 | bs_set(mdp4_dtv_encoder, 1); | ||
| 217 | |||
| 218 | DBG("setting src_clk=%lu", pc); | ||
| 219 | |||
| 220 | ret = clk_set_rate(mdp4_dtv_encoder->src_clk, pc); | ||
| 221 | if (ret) | ||
| 222 | dev_err(dev->dev, "failed to set src_clk to %lu: %d\n", pc, ret); | ||
| 223 | clk_prepare_enable(mdp4_dtv_encoder->src_clk); | ||
| 224 | ret = clk_prepare_enable(mdp4_dtv_encoder->hdmi_clk); | ||
| 225 | if (ret) | ||
| 226 | dev_err(dev->dev, "failed to enable hdmi_clk: %d\n", ret); | ||
| 227 | ret = clk_prepare_enable(mdp4_dtv_encoder->mdp_clk); | ||
| 228 | if (ret) | ||
| 229 | dev_err(dev->dev, "failed to enabled mdp_clk: %d\n", ret); | ||
| 230 | |||
| 231 | mdp4_write(mdp4_kms, REG_MDP4_DTV_ENABLE, 1); | ||
| 232 | |||
| 233 | mdp4_dtv_encoder->enabled = true; | ||
| 238 | } | 234 | } |
| 239 | 235 | ||
| 240 | static const struct drm_encoder_helper_funcs mdp4_dtv_encoder_helper_funcs = { | 236 | static const struct drm_encoder_helper_funcs mdp4_dtv_encoder_helper_funcs = { |
| 241 | .dpms = mdp4_dtv_encoder_dpms, | ||
| 242 | .mode_fixup = mdp4_dtv_encoder_mode_fixup, | 237 | .mode_fixup = mdp4_dtv_encoder_mode_fixup, |
| 243 | .mode_set = mdp4_dtv_encoder_mode_set, | 238 | .mode_set = mdp4_dtv_encoder_mode_set, |
| 244 | .prepare = mdp4_dtv_encoder_prepare, | 239 | .enable = mdp4_dtv_encoder_enable, |
| 245 | .commit = mdp4_dtv_encoder_commit, | 240 | .disable = mdp4_dtv_encoder_disable, |
| 246 | }; | 241 | }; |
| 247 | 242 | ||
| 248 | long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate) | 243 | long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate) |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c index a62109e4ae0d..d847b9436194 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c | |||
| @@ -125,6 +125,38 @@ out: | |||
| 125 | return ret; | 125 | return ret; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state) | ||
| 129 | { | ||
| 130 | struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); | ||
| 131 | int i, ncrtcs = state->dev->mode_config.num_crtc; | ||
| 132 | |||
| 133 | mdp4_enable(mdp4_kms); | ||
| 134 | |||
| 135 | /* see 119ecb7fd */ | ||
| 136 | for (i = 0; i < ncrtcs; i++) { | ||
| 137 | struct drm_crtc *crtc = state->crtcs[i]; | ||
| 138 | if (!crtc) | ||
| 139 | continue; | ||
| 140 | drm_crtc_vblank_get(crtc); | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 144 | static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state) | ||
| 145 | { | ||
| 146 | struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); | ||
| 147 | int i, ncrtcs = state->dev->mode_config.num_crtc; | ||
| 148 | |||
| 149 | /* see 119ecb7fd */ | ||
| 150 | for (i = 0; i < ncrtcs; i++) { | ||
| 151 | struct drm_crtc *crtc = state->crtcs[i]; | ||
| 152 | if (!crtc) | ||
| 153 | continue; | ||
| 154 | drm_crtc_vblank_put(crtc); | ||
| 155 | } | ||
| 156 | |||
| 157 | mdp4_disable(mdp4_kms); | ||
| 158 | } | ||
| 159 | |||
| 128 | static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate, | 160 | static long mdp4_round_pixclk(struct msm_kms *kms, unsigned long rate, |
| 129 | struct drm_encoder *encoder) | 161 | struct drm_encoder *encoder) |
| 130 | { | 162 | { |
| @@ -161,6 +193,8 @@ static const struct mdp_kms_funcs kms_funcs = { | |||
| 161 | .irq = mdp4_irq, | 193 | .irq = mdp4_irq, |
| 162 | .enable_vblank = mdp4_enable_vblank, | 194 | .enable_vblank = mdp4_enable_vblank, |
| 163 | .disable_vblank = mdp4_disable_vblank, | 195 | .disable_vblank = mdp4_disable_vblank, |
| 196 | .prepare_commit = mdp4_prepare_commit, | ||
| 197 | .complete_commit = mdp4_complete_commit, | ||
| 164 | .get_format = mdp_get_format, | 198 | .get_format = mdp_get_format, |
| 165 | .round_pixclk = mdp4_round_pixclk, | 199 | .round_pixclk = mdp4_round_pixclk, |
| 166 | .preclose = mdp4_preclose, | 200 | .preclose = mdp4_preclose, |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h index cbd77bc626d5..0a5c58bde7a9 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h | |||
| @@ -175,14 +175,25 @@ irqreturn_t mdp4_irq(struct msm_kms *kms); | |||
| 175 | int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); | 175 | int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); |
| 176 | void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); | 176 | void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); |
| 177 | 177 | ||
| 178 | static inline bool pipe_supports_yuv(enum mdp4_pipe pipe) | ||
| 179 | { | ||
| 180 | switch (pipe) { | ||
| 181 | case VG1: | ||
| 182 | case VG2: | ||
| 183 | case VG3: | ||
| 184 | case VG4: | ||
| 185 | return true; | ||
| 186 | default: | ||
| 187 | return false; | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 178 | static inline | 191 | static inline |
| 179 | uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *pixel_formats, | 192 | uint32_t mdp4_get_formats(enum mdp4_pipe pipe_id, uint32_t *pixel_formats, |
| 180 | uint32_t max_formats) | 193 | uint32_t max_formats) |
| 181 | { | 194 | { |
| 182 | /* TODO when we have YUV, we need to filter supported formats | 195 | return mdp_get_formats(pixel_formats, max_formats, |
| 183 | * based on pipe_id.. | 196 | !pipe_supports_yuv(pipe_id)); |
| 184 | */ | ||
| 185 | return mdp_get_formats(pixel_formats, max_formats); | ||
| 186 | } | 197 | } |
| 187 | 198 | ||
| 188 | void mdp4_plane_install_properties(struct drm_plane *plane, | 199 | void mdp4_plane_install_properties(struct drm_plane *plane, |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c index 41f6436754fc..60ec8222c9f6 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lcdc_encoder.c | |||
| @@ -259,77 +259,6 @@ static void setup_phy(struct drm_encoder *encoder) | |||
| 259 | mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0); | 259 | mdp4_write(mdp4_kms, REG_MDP4_LVDS_PHY_CFG0, lvds_phy_cfg0); |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | static void mdp4_lcdc_encoder_dpms(struct drm_encoder *encoder, int mode) | ||
| 263 | { | ||
| 264 | struct drm_device *dev = encoder->dev; | ||
| 265 | struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = | ||
| 266 | to_mdp4_lcdc_encoder(encoder); | ||
| 267 | struct mdp4_kms *mdp4_kms = get_kms(encoder); | ||
| 268 | struct drm_panel *panel = mdp4_lcdc_encoder->panel; | ||
| 269 | bool enabled = (mode == DRM_MODE_DPMS_ON); | ||
| 270 | int i, ret; | ||
| 271 | |||
| 272 | DBG("mode=%d", mode); | ||
| 273 | |||
| 274 | if (enabled == mdp4_lcdc_encoder->enabled) | ||
| 275 | return; | ||
| 276 | |||
| 277 | if (enabled) { | ||
| 278 | unsigned long pc = mdp4_lcdc_encoder->pixclock; | ||
| 279 | int ret; | ||
| 280 | |||
| 281 | bs_set(mdp4_lcdc_encoder, 1); | ||
| 282 | |||
| 283 | for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { | ||
| 284 | ret = regulator_enable(mdp4_lcdc_encoder->regs[i]); | ||
| 285 | if (ret) | ||
| 286 | dev_err(dev->dev, "failed to enable regulator: %d\n", ret); | ||
| 287 | } | ||
| 288 | |||
| 289 | DBG("setting lcdc_clk=%lu", pc); | ||
| 290 | ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc); | ||
| 291 | if (ret) | ||
| 292 | dev_err(dev->dev, "failed to configure lcdc_clk: %d\n", ret); | ||
| 293 | ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk); | ||
| 294 | if (ret) | ||
| 295 | dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret); | ||
| 296 | |||
| 297 | if (panel) | ||
| 298 | drm_panel_enable(panel); | ||
| 299 | |||
| 300 | setup_phy(encoder); | ||
| 301 | |||
| 302 | mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1); | ||
| 303 | } else { | ||
| 304 | mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); | ||
| 305 | |||
| 306 | if (panel) | ||
| 307 | drm_panel_disable(panel); | ||
| 308 | |||
| 309 | /* | ||
| 310 | * Wait for a vsync so we know the ENABLE=0 latched before | ||
| 311 | * the (connector) source of the vsync's gets disabled, | ||
| 312 | * otherwise we end up in a funny state if we re-enable | ||
| 313 | * before the disable latches, which results that some of | ||
| 314 | * the settings changes for the new modeset (like new | ||
| 315 | * scanout buffer) don't latch properly.. | ||
| 316 | */ | ||
| 317 | mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_PRIMARY_VSYNC); | ||
| 318 | |||
| 319 | clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk); | ||
| 320 | |||
| 321 | for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { | ||
| 322 | ret = regulator_disable(mdp4_lcdc_encoder->regs[i]); | ||
| 323 | if (ret) | ||
| 324 | dev_err(dev->dev, "failed to disable regulator: %d\n", ret); | ||
| 325 | } | ||
| 326 | |||
| 327 | bs_set(mdp4_lcdc_encoder, 0); | ||
| 328 | } | ||
| 329 | |||
| 330 | mdp4_lcdc_encoder->enabled = enabled; | ||
| 331 | } | ||
| 332 | |||
| 333 | static bool mdp4_lcdc_encoder_mode_fixup(struct drm_encoder *encoder, | 262 | static bool mdp4_lcdc_encoder_mode_fixup(struct drm_encoder *encoder, |
| 334 | const struct drm_display_mode *mode, | 263 | const struct drm_display_mode *mode, |
| 335 | struct drm_display_mode *adjusted_mode) | 264 | struct drm_display_mode *adjusted_mode) |
| @@ -403,13 +332,59 @@ static void mdp4_lcdc_encoder_mode_set(struct drm_encoder *encoder, | |||
| 403 | mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_VEND, 0); | 332 | mdp4_write(mdp4_kms, REG_MDP4_LCDC_ACTIVE_VEND, 0); |
| 404 | } | 333 | } |
| 405 | 334 | ||
| 406 | static void mdp4_lcdc_encoder_prepare(struct drm_encoder *encoder) | 335 | static void mdp4_lcdc_encoder_disable(struct drm_encoder *encoder) |
| 407 | { | 336 | { |
| 408 | mdp4_lcdc_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 337 | struct drm_device *dev = encoder->dev; |
| 338 | struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = | ||
| 339 | to_mdp4_lcdc_encoder(encoder); | ||
| 340 | struct mdp4_kms *mdp4_kms = get_kms(encoder); | ||
| 341 | struct drm_panel *panel = mdp4_lcdc_encoder->panel; | ||
| 342 | int i, ret; | ||
| 343 | |||
| 344 | if (WARN_ON(!mdp4_lcdc_encoder->enabled)) | ||
| 345 | return; | ||
| 346 | |||
| 347 | mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 0); | ||
| 348 | |||
| 349 | if (panel) | ||
| 350 | drm_panel_disable(panel); | ||
| 351 | |||
| 352 | /* | ||
| 353 | * Wait for a vsync so we know the ENABLE=0 latched before | ||
| 354 | * the (connector) source of the vsync's gets disabled, | ||
| 355 | * otherwise we end up in a funny state if we re-enable | ||
| 356 | * before the disable latches, which results that some of | ||
| 357 | * the settings changes for the new modeset (like new | ||
| 358 | * scanout buffer) don't latch properly.. | ||
| 359 | */ | ||
| 360 | mdp_irq_wait(&mdp4_kms->base, MDP4_IRQ_PRIMARY_VSYNC); | ||
| 361 | |||
| 362 | clk_disable_unprepare(mdp4_lcdc_encoder->lcdc_clk); | ||
| 363 | |||
| 364 | for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { | ||
| 365 | ret = regulator_disable(mdp4_lcdc_encoder->regs[i]); | ||
| 366 | if (ret) | ||
| 367 | dev_err(dev->dev, "failed to disable regulator: %d\n", ret); | ||
| 368 | } | ||
| 369 | |||
| 370 | bs_set(mdp4_lcdc_encoder, 0); | ||
| 371 | |||
| 372 | mdp4_lcdc_encoder->enabled = false; | ||
| 409 | } | 373 | } |
| 410 | 374 | ||
| 411 | static void mdp4_lcdc_encoder_commit(struct drm_encoder *encoder) | 375 | static void mdp4_lcdc_encoder_enable(struct drm_encoder *encoder) |
| 412 | { | 376 | { |
| 377 | struct drm_device *dev = encoder->dev; | ||
| 378 | struct mdp4_lcdc_encoder *mdp4_lcdc_encoder = | ||
| 379 | to_mdp4_lcdc_encoder(encoder); | ||
| 380 | unsigned long pc = mdp4_lcdc_encoder->pixclock; | ||
| 381 | struct mdp4_kms *mdp4_kms = get_kms(encoder); | ||
| 382 | struct drm_panel *panel = mdp4_lcdc_encoder->panel; | ||
| 383 | int i, ret; | ||
| 384 | |||
| 385 | if (WARN_ON(mdp4_lcdc_encoder->enabled)) | ||
| 386 | return; | ||
| 387 | |||
| 413 | /* TODO: hard-coded for 18bpp: */ | 388 | /* TODO: hard-coded for 18bpp: */ |
| 414 | mdp4_crtc_set_config(encoder->crtc, | 389 | mdp4_crtc_set_config(encoder->crtc, |
| 415 | MDP4_DMA_CONFIG_R_BPC(BPC6) | | 390 | MDP4_DMA_CONFIG_R_BPC(BPC6) | |
| @@ -420,15 +395,38 @@ static void mdp4_lcdc_encoder_commit(struct drm_encoder *encoder) | |||
| 420 | MDP4_DMA_CONFIG_DEFLKR_EN | | 395 | MDP4_DMA_CONFIG_DEFLKR_EN | |
| 421 | MDP4_DMA_CONFIG_DITHER_EN); | 396 | MDP4_DMA_CONFIG_DITHER_EN); |
| 422 | mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0); | 397 | mdp4_crtc_set_intf(encoder->crtc, INTF_LCDC_DTV, 0); |
| 423 | mdp4_lcdc_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | 398 | |
| 399 | bs_set(mdp4_lcdc_encoder, 1); | ||
| 400 | |||
| 401 | for (i = 0; i < ARRAY_SIZE(mdp4_lcdc_encoder->regs); i++) { | ||
| 402 | ret = regulator_enable(mdp4_lcdc_encoder->regs[i]); | ||
| 403 | if (ret) | ||
| 404 | dev_err(dev->dev, "failed to enable regulator: %d\n", ret); | ||
| 405 | } | ||
| 406 | |||
| 407 | DBG("setting lcdc_clk=%lu", pc); | ||
| 408 | ret = clk_set_rate(mdp4_lcdc_encoder->lcdc_clk, pc); | ||
| 409 | if (ret) | ||
| 410 | dev_err(dev->dev, "failed to configure lcdc_clk: %d\n", ret); | ||
| 411 | ret = clk_prepare_enable(mdp4_lcdc_encoder->lcdc_clk); | ||
| 412 | if (ret) | ||
| 413 | dev_err(dev->dev, "failed to enable lcdc_clk: %d\n", ret); | ||
| 414 | |||
| 415 | if (panel) | ||
| 416 | drm_panel_enable(panel); | ||
| 417 | |||
| 418 | setup_phy(encoder); | ||
| 419 | |||
| 420 | mdp4_write(mdp4_kms, REG_MDP4_LCDC_ENABLE, 1); | ||
| 421 | |||
| 422 | mdp4_lcdc_encoder->enabled = true; | ||
| 424 | } | 423 | } |
| 425 | 424 | ||
| 426 | static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = { | 425 | static const struct drm_encoder_helper_funcs mdp4_lcdc_encoder_helper_funcs = { |
| 427 | .dpms = mdp4_lcdc_encoder_dpms, | ||
| 428 | .mode_fixup = mdp4_lcdc_encoder_mode_fixup, | 426 | .mode_fixup = mdp4_lcdc_encoder_mode_fixup, |
| 429 | .mode_set = mdp4_lcdc_encoder_mode_set, | 427 | .mode_set = mdp4_lcdc_encoder_mode_set, |
| 430 | .prepare = mdp4_lcdc_encoder_prepare, | 428 | .disable = mdp4_lcdc_encoder_disable, |
| 431 | .commit = mdp4_lcdc_encoder_commit, | 429 | .enable = mdp4_lcdc_encoder_enable, |
| 432 | }; | 430 | }; |
| 433 | 431 | ||
| 434 | long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate) | 432 | long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate) |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c index 4ddc28e1275b..921185133d38 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c | |||
| @@ -94,7 +94,7 @@ mdp4_lvds_connector_best_encoder(struct drm_connector *connector) | |||
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | static const struct drm_connector_funcs mdp4_lvds_connector_funcs = { | 96 | static const struct drm_connector_funcs mdp4_lvds_connector_funcs = { |
| 97 | .dpms = drm_helper_connector_dpms, | 97 | .dpms = drm_atomic_helper_connector_dpms, |
| 98 | .detect = mdp4_lvds_connector_detect, | 98 | .detect = mdp4_lvds_connector_detect, |
| 99 | .fill_modes = drm_helper_probe_single_connector_modes, | 99 | .fill_modes = drm_helper_probe_single_connector_modes, |
| 100 | .destroy = mdp4_lvds_connector_destroy, | 100 | .destroy = mdp4_lvds_connector_destroy, |
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c index 1e5ebe83647d..cde25009203a 100644 --- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c | |||
| @@ -17,6 +17,8 @@ | |||
| 17 | 17 | ||
| 18 | #include "mdp4_kms.h" | 18 | #include "mdp4_kms.h" |
| 19 | 19 | ||
| 20 | #define DOWN_SCALE_MAX 8 | ||
| 21 | #define UP_SCALE_MAX 8 | ||
| 20 | 22 | ||
| 21 | struct mdp4_plane { | 23 | struct mdp4_plane { |
| 22 | struct drm_plane base; | 24 | struct drm_plane base; |
| @@ -136,10 +138,6 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane, | |||
| 136 | struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); | 138 | struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); |
| 137 | struct mdp4_kms *mdp4_kms = get_kms(plane); | 139 | struct mdp4_kms *mdp4_kms = get_kms(plane); |
| 138 | enum mdp4_pipe pipe = mdp4_plane->pipe; | 140 | enum mdp4_pipe pipe = mdp4_plane->pipe; |
| 139 | uint32_t iova = msm_framebuffer_iova(fb, mdp4_kms->id, 0); | ||
| 140 | |||
| 141 | DBG("%s: set_scanout: %08x (%u)", mdp4_plane->name, | ||
| 142 | iova, fb->pitches[0]); | ||
| 143 | 141 | ||
| 144 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe), | 142 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_STRIDE_A(pipe), |
| 145 | MDP4_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) | | 143 | MDP4_PIPE_SRC_STRIDE_A_P0(fb->pitches[0]) | |
| @@ -149,11 +147,45 @@ static void mdp4_plane_set_scanout(struct drm_plane *plane, | |||
| 149 | MDP4_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) | | 147 | MDP4_PIPE_SRC_STRIDE_B_P2(fb->pitches[2]) | |
| 150 | MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); | 148 | MDP4_PIPE_SRC_STRIDE_B_P3(fb->pitches[3])); |
| 151 | 149 | ||
| 152 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe), iova); | 150 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP0_BASE(pipe), |
| 151 | msm_framebuffer_iova(fb, mdp4_kms->id, 0)); | ||
| 152 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP1_BASE(pipe), | ||
| 153 | msm_framebuffer_iova(fb, mdp4_kms->id, 1)); | ||
| 154 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP2_BASE(pipe), | ||
| 155 | msm_framebuffer_iova(fb, mdp4_kms->id, 2)); | ||
| 156 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRCP3_BASE(pipe), | ||
| 157 | msm_framebuffer_iova(fb, mdp4_kms->id, 3)); | ||
| 153 | 158 | ||
| 154 | plane->fb = fb; | 159 | plane->fb = fb; |
| 155 | } | 160 | } |
| 156 | 161 | ||
| 162 | static void mdp4_write_csc_config(struct mdp4_kms *mdp4_kms, | ||
| 163 | enum mdp4_pipe pipe, struct csc_cfg *csc) | ||
| 164 | { | ||
| 165 | int i; | ||
| 166 | |||
| 167 | for (i = 0; i < ARRAY_SIZE(csc->matrix); i++) { | ||
| 168 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_MV(pipe, i), | ||
| 169 | csc->matrix[i]); | ||
| 170 | } | ||
| 171 | |||
| 172 | for (i = 0; i < ARRAY_SIZE(csc->post_bias) ; i++) { | ||
| 173 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_PRE_BV(pipe, i), | ||
| 174 | csc->pre_bias[i]); | ||
| 175 | |||
| 176 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_POST_BV(pipe, i), | ||
| 177 | csc->post_bias[i]); | ||
| 178 | } | ||
| 179 | |||
| 180 | for (i = 0; i < ARRAY_SIZE(csc->post_clamp) ; i++) { | ||
| 181 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_PRE_LV(pipe, i), | ||
| 182 | csc->pre_clamp[i]); | ||
| 183 | |||
| 184 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_CSC_POST_LV(pipe, i), | ||
| 185 | csc->post_clamp[i]); | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
| 157 | #define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000 | 189 | #define MDP4_VG_PHASE_STEP_DEFAULT 0x20000000 |
| 158 | 190 | ||
| 159 | static int mdp4_plane_mode_set(struct drm_plane *plane, | 191 | static int mdp4_plane_mode_set(struct drm_plane *plane, |
| @@ -163,6 +195,7 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, | |||
| 163 | uint32_t src_x, uint32_t src_y, | 195 | uint32_t src_x, uint32_t src_y, |
| 164 | uint32_t src_w, uint32_t src_h) | 196 | uint32_t src_w, uint32_t src_h) |
| 165 | { | 197 | { |
| 198 | struct drm_device *dev = plane->dev; | ||
| 166 | struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); | 199 | struct mdp4_plane *mdp4_plane = to_mdp4_plane(plane); |
| 167 | struct mdp4_kms *mdp4_kms = get_kms(plane); | 200 | struct mdp4_kms *mdp4_kms = get_kms(plane); |
| 168 | enum mdp4_pipe pipe = mdp4_plane->pipe; | 201 | enum mdp4_pipe pipe = mdp4_plane->pipe; |
| @@ -186,14 +219,59 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, | |||
| 186 | fb->base.id, src_x, src_y, src_w, src_h, | 219 | fb->base.id, src_x, src_y, src_w, src_h, |
| 187 | crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h); | 220 | crtc->base.id, crtc_x, crtc_y, crtc_w, crtc_h); |
| 188 | 221 | ||
| 222 | format = to_mdp_format(msm_framebuffer_format(fb)); | ||
| 223 | |||
| 224 | if (src_w > (crtc_w * DOWN_SCALE_MAX)) { | ||
| 225 | dev_err(dev->dev, "Width down scaling exceeds limits!\n"); | ||
| 226 | return -ERANGE; | ||
| 227 | } | ||
| 228 | |||
| 229 | if (src_h > (crtc_h * DOWN_SCALE_MAX)) { | ||
| 230 | dev_err(dev->dev, "Height down scaling exceeds limits!\n"); | ||
| 231 | return -ERANGE; | ||
| 232 | } | ||
| 233 | |||
| 234 | if (crtc_w > (src_w * UP_SCALE_MAX)) { | ||
| 235 | dev_err(dev->dev, "Width up scaling exceeds limits!\n"); | ||
| 236 | return -ERANGE; | ||
| 237 | } | ||
| 238 | |||
| 239 | if (crtc_h > (src_h * UP_SCALE_MAX)) { | ||
| 240 | dev_err(dev->dev, "Height up scaling exceeds limits!\n"); | ||
| 241 | return -ERANGE; | ||
| 242 | } | ||
| 243 | |||
| 189 | if (src_w != crtc_w) { | 244 | if (src_w != crtc_w) { |
| 245 | uint32_t sel_unit = SCALE_FIR; | ||
| 190 | op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN; | 246 | op_mode |= MDP4_PIPE_OP_MODE_SCALEX_EN; |
| 191 | /* TODO calc phasex_step */ | 247 | |
| 248 | if (MDP_FORMAT_IS_YUV(format)) { | ||
| 249 | if (crtc_w > src_w) | ||
| 250 | sel_unit = SCALE_PIXEL_RPT; | ||
| 251 | else if (crtc_w <= (src_w / 4)) | ||
| 252 | sel_unit = SCALE_MN_PHASE; | ||
| 253 | |||
| 254 | op_mode |= MDP4_PIPE_OP_MODE_SCALEX_UNIT_SEL(sel_unit); | ||
| 255 | phasex_step = mult_frac(MDP4_VG_PHASE_STEP_DEFAULT, | ||
| 256 | src_w, crtc_w); | ||
| 257 | } | ||
| 192 | } | 258 | } |
| 193 | 259 | ||
| 194 | if (src_h != crtc_h) { | 260 | if (src_h != crtc_h) { |
| 261 | uint32_t sel_unit = SCALE_FIR; | ||
| 195 | op_mode |= MDP4_PIPE_OP_MODE_SCALEY_EN; | 262 | op_mode |= MDP4_PIPE_OP_MODE_SCALEY_EN; |
| 196 | /* TODO calc phasey_step */ | 263 | |
| 264 | if (MDP_FORMAT_IS_YUV(format)) { | ||
| 265 | |||
| 266 | if (crtc_h > src_h) | ||
| 267 | sel_unit = SCALE_PIXEL_RPT; | ||
| 268 | else if (crtc_h <= (src_h / 4)) | ||
| 269 | sel_unit = SCALE_MN_PHASE; | ||
| 270 | |||
| 271 | op_mode |= MDP4_PIPE_OP_MODE_SCALEY_UNIT_SEL(sel_unit); | ||
| 272 | phasey_step = mult_frac(MDP4_VG_PHASE_STEP_DEFAULT, | ||
| 273 | src_h, crtc_h); | ||
| 274 | } | ||
| 197 | } | 275 | } |
| 198 | 276 | ||
| 199 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_SIZE(pipe), | 277 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_SIZE(pipe), |
| @@ -214,8 +292,6 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, | |||
| 214 | 292 | ||
| 215 | mdp4_plane_set_scanout(plane, fb); | 293 | mdp4_plane_set_scanout(plane, fb); |
| 216 | 294 | ||
| 217 | format = to_mdp_format(msm_framebuffer_format(fb)); | ||
| 218 | |||
| 219 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_FORMAT(pipe), | 295 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_FORMAT(pipe), |
| 220 | MDP4_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) | | 296 | MDP4_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) | |
| 221 | MDP4_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) | | 297 | MDP4_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) | |
| @@ -224,6 +300,8 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, | |||
| 224 | COND(format->alpha_enable, MDP4_PIPE_SRC_FORMAT_ALPHA_ENABLE) | | 300 | COND(format->alpha_enable, MDP4_PIPE_SRC_FORMAT_ALPHA_ENABLE) | |
| 225 | MDP4_PIPE_SRC_FORMAT_CPP(format->cpp - 1) | | 301 | MDP4_PIPE_SRC_FORMAT_CPP(format->cpp - 1) | |
| 226 | MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) | | 302 | MDP4_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) | |
| 303 | MDP4_PIPE_SRC_FORMAT_FETCH_PLANES(format->fetch_type) | | ||
| 304 | MDP4_PIPE_SRC_FORMAT_CHROMA_SAMP(format->chroma_sample) | | ||
| 227 | COND(format->unpack_tight, MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT)); | 305 | COND(format->unpack_tight, MDP4_PIPE_SRC_FORMAT_UNPACK_TIGHT)); |
| 228 | 306 | ||
| 229 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_UNPACK(pipe), | 307 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_SRC_UNPACK(pipe), |
| @@ -232,6 +310,14 @@ static int mdp4_plane_mode_set(struct drm_plane *plane, | |||
| 232 | MDP4_PIPE_SRC_UNPACK_ELEM2(format->unpack[2]) | | 310 | MDP4_PIPE_SRC_UNPACK_ELEM2(format->unpack[2]) | |
| 233 | MDP4_PIPE_SRC_UNPACK_ELEM3(format->unpack[3])); | 311 | MDP4_PIPE_SRC_UNPACK_ELEM3(format->unpack[3])); |
| 234 | 312 | ||
| 313 | if (MDP_FORMAT_IS_YUV(format)) { | ||
| 314 | struct csc_cfg *csc = mdp_get_default_csc_cfg(CSC_YUV2RGB); | ||
| 315 | |||
| 316 | op_mode |= MDP4_PIPE_OP_MODE_SRC_YCBCR; | ||
| 317 | op_mode |= MDP4_PIPE_OP_MODE_CSC_EN; | ||
| 318 | mdp4_write_csc_config(mdp4_kms, pipe, csc); | ||
| 319 | } | ||
| 320 | |||
| 235 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(pipe), op_mode); | 321 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_OP_MODE(pipe), op_mode); |
| 236 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step); | 322 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEX_STEP(pipe), phasex_step); |
| 237 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step); | 323 | mdp4_write(mdp4_kms, REG_MDP4_PIPE_PHASEY_STEP(pipe), phasey_step); |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h index e87ef5512cb0..09b4a25eb553 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h | |||
| @@ -8,18 +8,19 @@ http://github.com/freedreno/envytools/ | |||
| 8 | git clone https://github.com/freedreno/envytools.git | 8 | git clone https://github.com/freedreno/envytools.git |
| 9 | 9 | ||
| 10 | The rules-ng-ng source files this header was generated from are: | 10 | The rules-ng-ng source files this header was generated from are: |
| 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) | 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49) |
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20136 bytes, from 2014-10-31 16:51:39) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1940 bytes, from 2014-10-31 16:51:39) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 23963 bytes, from 2014-10-31 16:51:46) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) |
| 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) | 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) |
| 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) | 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) |
| 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-07-17 15:33:30) | 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) |
| 21 | - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) | ||
| 21 | 22 | ||
| 22 | Copyright (C) 2013-2014 by the following authors: | 23 | Copyright (C) 2013-2015 by the following authors: |
| 23 | - Rob Clark <robdclark@gmail.com> (robclark) | 24 | - Rob Clark <robdclark@gmail.com> (robclark) |
| 24 | 25 | ||
| 25 | Permission is hereby granted, free of charge, to any person obtaining | 26 | Permission is hereby granted, free of charge, to any person obtaining |
| @@ -88,13 +89,6 @@ enum mdp5_pack_3d { | |||
| 88 | PACK_3D_COL_INT = 3, | 89 | PACK_3D_COL_INT = 3, |
| 89 | }; | 90 | }; |
| 90 | 91 | ||
| 91 | enum mdp5_chroma_samp_type { | ||
| 92 | CHROMA_RGB = 0, | ||
| 93 | CHROMA_H2V1 = 1, | ||
| 94 | CHROMA_H1V2 = 2, | ||
| 95 | CHROMA_420 = 3, | ||
| 96 | }; | ||
| 97 | |||
| 98 | enum mdp5_scale_filter { | 92 | enum mdp5_scale_filter { |
| 99 | SCALE_FILTER_NEAREST = 0, | 93 | SCALE_FILTER_NEAREST = 0, |
| 100 | SCALE_FILTER_BIL = 1, | 94 | SCALE_FILTER_BIL = 1, |
| @@ -135,6 +129,17 @@ enum mdp5_client_id { | |||
| 135 | CID_MAX = 23, | 129 | CID_MAX = 23, |
| 136 | }; | 130 | }; |
| 137 | 131 | ||
| 132 | enum mdp5_cursor_format { | ||
| 133 | CURSOR_FMT_ARGB8888 = 0, | ||
| 134 | CURSOR_FMT_ARGB1555 = 2, | ||
| 135 | CURSOR_FMT_ARGB4444 = 4, | ||
| 136 | }; | ||
| 137 | |||
| 138 | enum mdp5_cursor_alpha { | ||
| 139 | CURSOR_ALPHA_CONST = 0, | ||
| 140 | CURSOR_ALPHA_PER_PIXEL = 2, | ||
| 141 | }; | ||
| 142 | |||
| 138 | enum mdp5_igc_type { | 143 | enum mdp5_igc_type { |
| 139 | IGC_VIG = 0, | 144 | IGC_VIG = 0, |
| 140 | IGC_RGB = 1, | 145 | IGC_RGB = 1, |
| @@ -142,6 +147,11 @@ enum mdp5_igc_type { | |||
| 142 | IGC_DSPP = 3, | 147 | IGC_DSPP = 3, |
| 143 | }; | 148 | }; |
| 144 | 149 | ||
| 150 | enum mdp5_data_format { | ||
| 151 | DATA_FORMAT_RGB = 0, | ||
| 152 | DATA_FORMAT_YUV = 1, | ||
| 153 | }; | ||
| 154 | |||
| 145 | #define MDP5_IRQ_INTF0_WB_ROT_COMP 0x00000001 | 155 | #define MDP5_IRQ_INTF0_WB_ROT_COMP 0x00000001 |
| 146 | #define MDP5_IRQ_INTF1_WB_ROT_COMP 0x00000002 | 156 | #define MDP5_IRQ_INTF1_WB_ROT_COMP 0x00000002 |
| 147 | #define MDP5_IRQ_INTF2_WB_ROT_COMP 0x00000004 | 157 | #define MDP5_IRQ_INTF2_WB_ROT_COMP 0x00000004 |
| @@ -463,12 +473,143 @@ static inline uint32_t __offset_PIPE(enum mdp5_pipe idx) | |||
| 463 | } | 473 | } |
| 464 | static inline uint32_t REG_MDP5_PIPE(enum mdp5_pipe i0) { return 0x00000000 + __offset_PIPE(i0); } | 474 | static inline uint32_t REG_MDP5_PIPE(enum mdp5_pipe i0) { return 0x00000000 + __offset_PIPE(i0); } |
| 465 | 475 | ||
| 476 | static inline uint32_t REG_MDP5_PIPE_OP_MODE(enum mdp5_pipe i0) { return 0x00000200 + __offset_PIPE(i0); } | ||
| 477 | #define MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT__MASK 0x00080000 | ||
| 478 | #define MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT__SHIFT 19 | ||
| 479 | static inline uint32_t MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT(enum mdp5_data_format val) | ||
| 480 | { | ||
| 481 | return ((val) << MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT__SHIFT) & MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT__MASK; | ||
| 482 | } | ||
| 483 | #define MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT__MASK 0x00040000 | ||
| 484 | #define MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT__SHIFT 18 | ||
| 485 | static inline uint32_t MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT(enum mdp5_data_format val) | ||
| 486 | { | ||
| 487 | return ((val) << MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT__SHIFT) & MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT__MASK; | ||
| 488 | } | ||
| 489 | #define MDP5_PIPE_OP_MODE_CSC_1_EN 0x00020000 | ||
| 490 | |||
| 466 | static inline uint32_t REG_MDP5_PIPE_HIST_CTL_BASE(enum mdp5_pipe i0) { return 0x000002c4 + __offset_PIPE(i0); } | 491 | static inline uint32_t REG_MDP5_PIPE_HIST_CTL_BASE(enum mdp5_pipe i0) { return 0x000002c4 + __offset_PIPE(i0); } |
| 467 | 492 | ||
| 468 | static inline uint32_t REG_MDP5_PIPE_HIST_LUT_BASE(enum mdp5_pipe i0) { return 0x000002f0 + __offset_PIPE(i0); } | 493 | static inline uint32_t REG_MDP5_PIPE_HIST_LUT_BASE(enum mdp5_pipe i0) { return 0x000002f0 + __offset_PIPE(i0); } |
| 469 | 494 | ||
| 470 | static inline uint32_t REG_MDP5_PIPE_HIST_LUT_SWAP(enum mdp5_pipe i0) { return 0x00000300 + __offset_PIPE(i0); } | 495 | static inline uint32_t REG_MDP5_PIPE_HIST_LUT_SWAP(enum mdp5_pipe i0) { return 0x00000300 + __offset_PIPE(i0); } |
| 471 | 496 | ||
| 497 | static inline uint32_t REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_0(enum mdp5_pipe i0) { return 0x00000320 + __offset_PIPE(i0); } | ||
| 498 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11__MASK 0x00001fff | ||
| 499 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11__SHIFT 0 | ||
| 500 | static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11(uint32_t val) | ||
| 501 | { | ||
| 502 | return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11__MASK; | ||
| 503 | } | ||
| 504 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12__MASK 0x1fff0000 | ||
| 505 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12__SHIFT 16 | ||
| 506 | static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12(uint32_t val) | ||
| 507 | { | ||
| 508 | return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12__MASK; | ||
| 509 | } | ||
| 510 | |||
| 511 | static inline uint32_t REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_1(enum mdp5_pipe i0) { return 0x00000324 + __offset_PIPE(i0); } | ||
| 512 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13__MASK 0x00001fff | ||
| 513 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13__SHIFT 0 | ||
| 514 | static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13(uint32_t val) | ||
| 515 | { | ||
| 516 | return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13__MASK; | ||
| 517 | } | ||
| 518 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21__MASK 0x1fff0000 | ||
| 519 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21__SHIFT 16 | ||
| 520 | static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21(uint32_t val) | ||
| 521 | { | ||
| 522 | return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21__MASK; | ||
| 523 | } | ||
| 524 | |||
| 525 | static inline uint32_t REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_2(enum mdp5_pipe i0) { return 0x00000328 + __offset_PIPE(i0); } | ||
| 526 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22__MASK 0x00001fff | ||
| 527 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22__SHIFT 0 | ||
| 528 | static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22(uint32_t val) | ||
| 529 | { | ||
| 530 | return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22__MASK; | ||
| 531 | } | ||
| 532 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23__MASK 0x1fff0000 | ||
| 533 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23__SHIFT 16 | ||
| 534 | static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23(uint32_t val) | ||
| 535 | { | ||
| 536 | return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23__MASK; | ||
| 537 | } | ||
| 538 | |||
| 539 | static inline uint32_t REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_3(enum mdp5_pipe i0) { return 0x0000032c + __offset_PIPE(i0); } | ||
| 540 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31__MASK 0x00001fff | ||
| 541 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31__SHIFT 0 | ||
| 542 | static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31(uint32_t val) | ||
| 543 | { | ||
| 544 | return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31__MASK; | ||
| 545 | } | ||
| 546 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32__MASK 0x1fff0000 | ||
| 547 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32__SHIFT 16 | ||
| 548 | static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32(uint32_t val) | ||
| 549 | { | ||
| 550 | return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32__MASK; | ||
| 551 | } | ||
| 552 | |||
| 553 | static inline uint32_t REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_4(enum mdp5_pipe i0) { return 0x00000330 + __offset_PIPE(i0); } | ||
| 554 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33__MASK 0x00001fff | ||
| 555 | #define MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33__SHIFT 0 | ||
| 556 | static inline uint32_t MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33(uint32_t val) | ||
| 557 | { | ||
| 558 | return ((val) << MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33__SHIFT) & MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33__MASK; | ||
| 559 | } | ||
| 560 | |||
| 561 | static inline uint32_t REG_MDP5_PIPE_CSC_1_PRE_CLAMP(enum mdp5_pipe i0, uint32_t i1) { return 0x00000334 + __offset_PIPE(i0) + 0x4*i1; } | ||
| 562 | |||
| 563 | static inline uint32_t REG_MDP5_PIPE_CSC_1_PRE_CLAMP_REG(enum mdp5_pipe i0, uint32_t i1) { return 0x00000334 + __offset_PIPE(i0) + 0x4*i1; } | ||
| 564 | #define MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH__MASK 0x000000ff | ||
| 565 | #define MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH__SHIFT 0 | ||
| 566 | static inline uint32_t MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH(uint32_t val) | ||
| 567 | { | ||
| 568 | return ((val) << MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH__SHIFT) & MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH__MASK; | ||
| 569 | } | ||
| 570 | #define MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW__MASK 0x0000ff00 | ||
| 571 | #define MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW__SHIFT 8 | ||
| 572 | static inline uint32_t MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW(uint32_t val) | ||
| 573 | { | ||
| 574 | return ((val) << MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW__SHIFT) & MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW__MASK; | ||
| 575 | } | ||
| 576 | |||
| 577 | static inline uint32_t REG_MDP5_PIPE_CSC_1_POST_CLAMP(enum mdp5_pipe i0, uint32_t i1) { return 0x00000340 + __offset_PIPE(i0) + 0x4*i1; } | ||
| 578 | |||
| 579 | static inline uint32_t REG_MDP5_PIPE_CSC_1_POST_CLAMP_REG(enum mdp5_pipe i0, uint32_t i1) { return 0x00000340 + __offset_PIPE(i0) + 0x4*i1; } | ||
| 580 | #define MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH__MASK 0x000000ff | ||
| 581 | #define MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH__SHIFT 0 | ||
| 582 | static inline uint32_t MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH(uint32_t val) | ||
| 583 | { | ||
| 584 | return ((val) << MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH__SHIFT) & MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH__MASK; | ||
| 585 | } | ||
| 586 | #define MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW__MASK 0x0000ff00 | ||
| 587 | #define MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW__SHIFT 8 | ||
| 588 | static inline uint32_t MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW(uint32_t val) | ||
| 589 | { | ||
| 590 | return ((val) << MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW__SHIFT) & MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW__MASK; | ||
| 591 | } | ||
| 592 | |||
| 593 | static inline uint32_t REG_MDP5_PIPE_CSC_1_PRE_BIAS(enum mdp5_pipe i0, uint32_t i1) { return 0x0000034c + __offset_PIPE(i0) + 0x4*i1; } | ||
| 594 | |||
| 595 | static inline uint32_t REG_MDP5_PIPE_CSC_1_PRE_BIAS_REG(enum mdp5_pipe i0, uint32_t i1) { return 0x0000034c + __offset_PIPE(i0) + 0x4*i1; } | ||
| 596 | #define MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE__MASK 0x000001ff | ||
| 597 | #define MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE__SHIFT 0 | ||
| 598 | static inline uint32_t MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE(uint32_t val) | ||
| 599 | { | ||
| 600 | return ((val) << MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE__SHIFT) & MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE__MASK; | ||
| 601 | } | ||
| 602 | |||
| 603 | static inline uint32_t REG_MDP5_PIPE_CSC_1_POST_BIAS(enum mdp5_pipe i0, uint32_t i1) { return 0x00000358 + __offset_PIPE(i0) + 0x4*i1; } | ||
| 604 | |||
| 605 | static inline uint32_t REG_MDP5_PIPE_CSC_1_POST_BIAS_REG(enum mdp5_pipe i0, uint32_t i1) { return 0x00000358 + __offset_PIPE(i0) + 0x4*i1; } | ||
| 606 | #define MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE__MASK 0x000001ff | ||
| 607 | #define MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE__SHIFT 0 | ||
| 608 | static inline uint32_t MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE(uint32_t val) | ||
| 609 | { | ||
| 610 | return ((val) << MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE__SHIFT) & MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE__MASK; | ||
| 611 | } | ||
| 612 | |||
| 472 | static inline uint32_t REG_MDP5_PIPE_SRC_SIZE(enum mdp5_pipe i0) { return 0x00000000 + __offset_PIPE(i0); } | 613 | static inline uint32_t REG_MDP5_PIPE_SRC_SIZE(enum mdp5_pipe i0) { return 0x00000000 + __offset_PIPE(i0); } |
| 473 | #define MDP5_PIPE_SRC_SIZE_HEIGHT__MASK 0xffff0000 | 614 | #define MDP5_PIPE_SRC_SIZE_HEIGHT__MASK 0xffff0000 |
| 474 | #define MDP5_PIPE_SRC_SIZE_HEIGHT__SHIFT 16 | 615 | #define MDP5_PIPE_SRC_SIZE_HEIGHT__SHIFT 16 |
| @@ -618,15 +759,15 @@ static inline uint32_t MDP5_PIPE_SRC_FORMAT_UNPACK_COUNT(uint32_t val) | |||
| 618 | } | 759 | } |
| 619 | #define MDP5_PIPE_SRC_FORMAT_UNPACK_TIGHT 0x00020000 | 760 | #define MDP5_PIPE_SRC_FORMAT_UNPACK_TIGHT 0x00020000 |
| 620 | #define MDP5_PIPE_SRC_FORMAT_UNPACK_ALIGN_MSB 0x00040000 | 761 | #define MDP5_PIPE_SRC_FORMAT_UNPACK_ALIGN_MSB 0x00040000 |
| 621 | #define MDP5_PIPE_SRC_FORMAT_NUM_PLANES__MASK 0x00780000 | 762 | #define MDP5_PIPE_SRC_FORMAT_NUM_PLANES__MASK 0x00180000 |
| 622 | #define MDP5_PIPE_SRC_FORMAT_NUM_PLANES__SHIFT 19 | 763 | #define MDP5_PIPE_SRC_FORMAT_NUM_PLANES__SHIFT 19 |
| 623 | static inline uint32_t MDP5_PIPE_SRC_FORMAT_NUM_PLANES(uint32_t val) | 764 | static inline uint32_t MDP5_PIPE_SRC_FORMAT_NUM_PLANES(enum mdp_sspp_fetch_type val) |
| 624 | { | 765 | { |
| 625 | return ((val) << MDP5_PIPE_SRC_FORMAT_NUM_PLANES__SHIFT) & MDP5_PIPE_SRC_FORMAT_NUM_PLANES__MASK; | 766 | return ((val) << MDP5_PIPE_SRC_FORMAT_NUM_PLANES__SHIFT) & MDP5_PIPE_SRC_FORMAT_NUM_PLANES__MASK; |
| 626 | } | 767 | } |
| 627 | #define MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK 0x01800000 | 768 | #define MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK 0x01800000 |
| 628 | #define MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT 23 | 769 | #define MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT 23 |
| 629 | static inline uint32_t MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(enum mdp5_chroma_samp_type val) | 770 | static inline uint32_t MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(enum mdp_chroma_samp_type val) |
| 630 | { | 771 | { |
| 631 | return ((val) << MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT) & MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK; | 772 | return ((val) << MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__SHIFT) & MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP__MASK; |
| 632 | } | 773 | } |
| @@ -753,6 +894,10 @@ static inline uint32_t REG_MDP5_PIPE_SCALE_PHASE_STEP_X(enum mdp5_pipe i0) { ret | |||
| 753 | 894 | ||
| 754 | static inline uint32_t REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(enum mdp5_pipe i0) { return 0x00000214 + __offset_PIPE(i0); } | 895 | static inline uint32_t REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(enum mdp5_pipe i0) { return 0x00000214 + __offset_PIPE(i0); } |
| 755 | 896 | ||
| 897 | static inline uint32_t REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_X(enum mdp5_pipe i0) { return 0x00000218 + __offset_PIPE(i0); } | ||
| 898 | |||
| 899 | static inline uint32_t REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_Y(enum mdp5_pipe i0) { return 0x0000021c + __offset_PIPE(i0); } | ||
| 900 | |||
| 756 | static inline uint32_t REG_MDP5_PIPE_SCALE_INIT_PHASE_X(enum mdp5_pipe i0) { return 0x00000220 + __offset_PIPE(i0); } | 901 | static inline uint32_t REG_MDP5_PIPE_SCALE_INIT_PHASE_X(enum mdp5_pipe i0) { return 0x00000220 + __offset_PIPE(i0); } |
| 757 | 902 | ||
| 758 | static inline uint32_t REG_MDP5_PIPE_SCALE_INIT_PHASE_Y(enum mdp5_pipe i0) { return 0x00000224 + __offset_PIPE(i0); } | 903 | static inline uint32_t REG_MDP5_PIPE_SCALE_INIT_PHASE_Y(enum mdp5_pipe i0) { return 0x00000224 + __offset_PIPE(i0); } |
| @@ -839,20 +984,88 @@ static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_HIGH0(uint32_t i0, uint32_t i | |||
| 839 | static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_HIGH1(uint32_t i0, uint32_t i1) { return 0x00000048 + __offset_LM(i0) + 0x30*i1; } | 984 | static inline uint32_t REG_MDP5_LM_BLEND_BG_TRANSP_HIGH1(uint32_t i0, uint32_t i1) { return 0x00000048 + __offset_LM(i0) + 0x30*i1; } |
| 840 | 985 | ||
| 841 | static inline uint32_t REG_MDP5_LM_CURSOR_IMG_SIZE(uint32_t i0) { return 0x000000e0 + __offset_LM(i0); } | 986 | static inline uint32_t REG_MDP5_LM_CURSOR_IMG_SIZE(uint32_t i0) { return 0x000000e0 + __offset_LM(i0); } |
| 987 | #define MDP5_LM_CURSOR_IMG_SIZE_SRC_W__MASK 0x0000ffff | ||
| 988 | #define MDP5_LM_CURSOR_IMG_SIZE_SRC_W__SHIFT 0 | ||
| 989 | static inline uint32_t MDP5_LM_CURSOR_IMG_SIZE_SRC_W(uint32_t val) | ||
| 990 | { | ||
| 991 | return ((val) << MDP5_LM_CURSOR_IMG_SIZE_SRC_W__SHIFT) & MDP5_LM_CURSOR_IMG_SIZE_SRC_W__MASK; | ||
| 992 | } | ||
| 993 | #define MDP5_LM_CURSOR_IMG_SIZE_SRC_H__MASK 0xffff0000 | ||
| 994 | #define MDP5_LM_CURSOR_IMG_SIZE_SRC_H__SHIFT 16 | ||
| 995 | static inline uint32_t MDP5_LM_CURSOR_IMG_SIZE_SRC_H(uint32_t val) | ||
| 996 | { | ||
| 997 | return ((val) << MDP5_LM_CURSOR_IMG_SIZE_SRC_H__SHIFT) & MDP5_LM_CURSOR_IMG_SIZE_SRC_H__MASK; | ||
| 998 | } | ||
| 842 | 999 | ||
| 843 | static inline uint32_t REG_MDP5_LM_CURSOR_SIZE(uint32_t i0) { return 0x000000e4 + __offset_LM(i0); } | 1000 | static inline uint32_t REG_MDP5_LM_CURSOR_SIZE(uint32_t i0) { return 0x000000e4 + __offset_LM(i0); } |
| 1001 | #define MDP5_LM_CURSOR_SIZE_ROI_W__MASK 0x0000ffff | ||
| 1002 | #define MDP5_LM_CURSOR_SIZE_ROI_W__SHIFT 0 | ||
| 1003 | static inline uint32_t MDP5_LM_CURSOR_SIZE_ROI_W(uint32_t val) | ||
| 1004 | { | ||
| 1005 | return ((val) << MDP5_LM_CURSOR_SIZE_ROI_W__SHIFT) & MDP5_LM_CURSOR_SIZE_ROI_W__MASK; | ||
| 1006 | } | ||
| 1007 | #define MDP5_LM_CURSOR_SIZE_ROI_H__MASK 0xffff0000 | ||
| 1008 | #define MDP5_LM_CURSOR_SIZE_ROI_H__SHIFT 16 | ||
| 1009 | static inline uint32_t MDP5_LM_CURSOR_SIZE_ROI_H(uint32_t val) | ||
| 1010 | { | ||
| 1011 | return ((val) << MDP5_LM_CURSOR_SIZE_ROI_H__SHIFT) & MDP5_LM_CURSOR_SIZE_ROI_H__MASK; | ||
| 1012 | } | ||
| 844 | 1013 | ||
| 845 | static inline uint32_t REG_MDP5_LM_CURSOR_XY(uint32_t i0) { return 0x000000e8 + __offset_LM(i0); } | 1014 | static inline uint32_t REG_MDP5_LM_CURSOR_XY(uint32_t i0) { return 0x000000e8 + __offset_LM(i0); } |
| 1015 | #define MDP5_LM_CURSOR_XY_SRC_X__MASK 0x0000ffff | ||
| 1016 | #define MDP5_LM_CURSOR_XY_SRC_X__SHIFT 0 | ||
| 1017 | static inline uint32_t MDP5_LM_CURSOR_XY_SRC_X(uint32_t val) | ||
| 1018 | { | ||
| 1019 | return ((val) << MDP5_LM_CURSOR_XY_SRC_X__SHIFT) & MDP5_LM_CURSOR_XY_SRC_X__MASK; | ||
| 1020 | } | ||
| 1021 | #define MDP5_LM_CURSOR_XY_SRC_Y__MASK 0xffff0000 | ||
| 1022 | #define MDP5_LM_CURSOR_XY_SRC_Y__SHIFT 16 | ||
| 1023 | static inline uint32_t MDP5_LM_CURSOR_XY_SRC_Y(uint32_t val) | ||
| 1024 | { | ||
| 1025 | return ((val) << MDP5_LM_CURSOR_XY_SRC_Y__SHIFT) & MDP5_LM_CURSOR_XY_SRC_Y__MASK; | ||
| 1026 | } | ||
| 846 | 1027 | ||
| 847 | static inline uint32_t REG_MDP5_LM_CURSOR_STRIDE(uint32_t i0) { return 0x000000dc + __offset_LM(i0); } | 1028 | static inline uint32_t REG_MDP5_LM_CURSOR_STRIDE(uint32_t i0) { return 0x000000dc + __offset_LM(i0); } |
| 1029 | #define MDP5_LM_CURSOR_STRIDE_STRIDE__MASK 0x0000ffff | ||
| 1030 | #define MDP5_LM_CURSOR_STRIDE_STRIDE__SHIFT 0 | ||
| 1031 | static inline uint32_t MDP5_LM_CURSOR_STRIDE_STRIDE(uint32_t val) | ||
| 1032 | { | ||
| 1033 | return ((val) << MDP5_LM_CURSOR_STRIDE_STRIDE__SHIFT) & MDP5_LM_CURSOR_STRIDE_STRIDE__MASK; | ||
| 1034 | } | ||
| 848 | 1035 | ||
| 849 | static inline uint32_t REG_MDP5_LM_CURSOR_FORMAT(uint32_t i0) { return 0x000000ec + __offset_LM(i0); } | 1036 | static inline uint32_t REG_MDP5_LM_CURSOR_FORMAT(uint32_t i0) { return 0x000000ec + __offset_LM(i0); } |
| 1037 | #define MDP5_LM_CURSOR_FORMAT_FORMAT__MASK 0x00000007 | ||
| 1038 | #define MDP5_LM_CURSOR_FORMAT_FORMAT__SHIFT 0 | ||
| 1039 | static inline uint32_t MDP5_LM_CURSOR_FORMAT_FORMAT(enum mdp5_cursor_format val) | ||
| 1040 | { | ||
| 1041 | return ((val) << MDP5_LM_CURSOR_FORMAT_FORMAT__SHIFT) & MDP5_LM_CURSOR_FORMAT_FORMAT__MASK; | ||
| 1042 | } | ||
| 850 | 1043 | ||
| 851 | static inline uint32_t REG_MDP5_LM_CURSOR_BASE_ADDR(uint32_t i0) { return 0x000000f0 + __offset_LM(i0); } | 1044 | static inline uint32_t REG_MDP5_LM_CURSOR_BASE_ADDR(uint32_t i0) { return 0x000000f0 + __offset_LM(i0); } |
| 852 | 1045 | ||
| 853 | static inline uint32_t REG_MDP5_LM_CURSOR_START_XY(uint32_t i0) { return 0x000000f4 + __offset_LM(i0); } | 1046 | static inline uint32_t REG_MDP5_LM_CURSOR_START_XY(uint32_t i0) { return 0x000000f4 + __offset_LM(i0); } |
| 1047 | #define MDP5_LM_CURSOR_START_XY_X_START__MASK 0x0000ffff | ||
| 1048 | #define MDP5_LM_CURSOR_START_XY_X_START__SHIFT 0 | ||
| 1049 | static inline uint32_t MDP5_LM_CURSOR_START_XY_X_START(uint32_t val) | ||
| 1050 | { | ||
| 1051 | return ((val) << MDP5_LM_CURSOR_START_XY_X_START__SHIFT) & MDP5_LM_CURSOR_START_XY_X_START__MASK; | ||
| 1052 | } | ||
| 1053 | #define MDP5_LM_CURSOR_START_XY_Y_START__MASK 0xffff0000 | ||
| 1054 | #define MDP5_LM_CURSOR_START_XY_Y_START__SHIFT 16 | ||
| 1055 | static inline uint32_t MDP5_LM_CURSOR_START_XY_Y_START(uint32_t val) | ||
| 1056 | { | ||
| 1057 | return ((val) << MDP5_LM_CURSOR_START_XY_Y_START__SHIFT) & MDP5_LM_CURSOR_START_XY_Y_START__MASK; | ||
| 1058 | } | ||
| 854 | 1059 | ||
| 855 | static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_CONFIG(uint32_t i0) { return 0x000000f8 + __offset_LM(i0); } | 1060 | static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_CONFIG(uint32_t i0) { return 0x000000f8 + __offset_LM(i0); } |
| 1061 | #define MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN 0x00000001 | ||
| 1062 | #define MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL__MASK 0x00000006 | ||
| 1063 | #define MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL__SHIFT 1 | ||
| 1064 | static inline uint32_t MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(enum mdp5_cursor_alpha val) | ||
| 1065 | { | ||
| 1066 | return ((val) << MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL__SHIFT) & MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL__MASK; | ||
| 1067 | } | ||
| 1068 | #define MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_TRANSP_EN 0x00000008 | ||
| 856 | 1069 | ||
| 857 | static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_PARAM(uint32_t i0) { return 0x000000fc + __offset_LM(i0); } | 1070 | static inline uint32_t REG_MDP5_LM_CURSOR_BLEND_PARAM(uint32_t i0) { return 0x000000fc + __offset_LM(i0); } |
| 858 | 1071 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c index 6b25f9f731ed..46fac545dc2b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c | |||
| @@ -24,6 +24,9 @@ | |||
| 24 | #include "drm_crtc_helper.h" | 24 | #include "drm_crtc_helper.h" |
| 25 | #include "drm_flip_work.h" | 25 | #include "drm_flip_work.h" |
| 26 | 26 | ||
| 27 | #define CURSOR_WIDTH 64 | ||
| 28 | #define CURSOR_HEIGHT 64 | ||
| 29 | |||
| 27 | #define SSPP_MAX (SSPP_RGB3 + 1) /* TODO: Add SSPP_MAX in mdp5.xml.h */ | 30 | #define SSPP_MAX (SSPP_RGB3 + 1) /* TODO: Add SSPP_MAX in mdp5.xml.h */ |
| 28 | 31 | ||
| 29 | struct mdp5_crtc { | 32 | struct mdp5_crtc { |
| @@ -47,8 +50,21 @@ struct mdp5_crtc { | |||
| 47 | #define PENDING_FLIP 0x2 | 50 | #define PENDING_FLIP 0x2 |
| 48 | atomic_t pending; | 51 | atomic_t pending; |
| 49 | 52 | ||
| 53 | /* for unref'ing cursor bo's after scanout completes: */ | ||
| 54 | struct drm_flip_work unref_cursor_work; | ||
| 55 | |||
| 50 | struct mdp_irq vblank; | 56 | struct mdp_irq vblank; |
| 51 | struct mdp_irq err; | 57 | struct mdp_irq err; |
| 58 | |||
| 59 | struct { | ||
| 60 | /* protect REG_MDP5_LM_CURSOR* registers and cursor scanout_bo*/ | ||
| 61 | spinlock_t lock; | ||
| 62 | |||
| 63 | /* current cursor being scanned out: */ | ||
| 64 | struct drm_gem_object *scanout_bo; | ||
| 65 | uint32_t width; | ||
| 66 | uint32_t height; | ||
| 67 | } cursor; | ||
| 52 | }; | 68 | }; |
| 53 | #define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base) | 69 | #define to_mdp5_crtc(x) container_of(x, struct mdp5_crtc, base) |
| 54 | 70 | ||
| @@ -129,37 +145,26 @@ static void complete_flip(struct drm_crtc *crtc, struct drm_file *file) | |||
| 129 | } | 145 | } |
| 130 | } | 146 | } |
| 131 | 147 | ||
| 148 | static void unref_cursor_worker(struct drm_flip_work *work, void *val) | ||
| 149 | { | ||
| 150 | struct mdp5_crtc *mdp5_crtc = | ||
| 151 | container_of(work, struct mdp5_crtc, unref_cursor_work); | ||
| 152 | struct mdp5_kms *mdp5_kms = get_kms(&mdp5_crtc->base); | ||
| 153 | |||
| 154 | msm_gem_put_iova(val, mdp5_kms->id); | ||
| 155 | drm_gem_object_unreference_unlocked(val); | ||
| 156 | } | ||
| 157 | |||
| 132 | static void mdp5_crtc_destroy(struct drm_crtc *crtc) | 158 | static void mdp5_crtc_destroy(struct drm_crtc *crtc) |
| 133 | { | 159 | { |
| 134 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | 160 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); |
| 135 | 161 | ||
| 136 | drm_crtc_cleanup(crtc); | 162 | drm_crtc_cleanup(crtc); |
| 163 | drm_flip_work_cleanup(&mdp5_crtc->unref_cursor_work); | ||
| 137 | 164 | ||
| 138 | kfree(mdp5_crtc); | 165 | kfree(mdp5_crtc); |
| 139 | } | 166 | } |
| 140 | 167 | ||
| 141 | static void mdp5_crtc_dpms(struct drm_crtc *crtc, int mode) | ||
| 142 | { | ||
| 143 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | ||
| 144 | struct mdp5_kms *mdp5_kms = get_kms(crtc); | ||
| 145 | bool enabled = (mode == DRM_MODE_DPMS_ON); | ||
| 146 | |||
| 147 | DBG("%s: mode=%d", mdp5_crtc->name, mode); | ||
| 148 | |||
| 149 | if (enabled != mdp5_crtc->enabled) { | ||
| 150 | if (enabled) { | ||
| 151 | mdp5_enable(mdp5_kms); | ||
| 152 | mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); | ||
| 153 | } else { | ||
| 154 | /* set STAGE_UNUSED for all layers */ | ||
| 155 | mdp5_ctl_blend(mdp5_crtc->ctl, mdp5_crtc->lm, 0x00000000); | ||
| 156 | mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err); | ||
| 157 | mdp5_disable(mdp5_kms); | ||
| 158 | } | ||
| 159 | mdp5_crtc->enabled = enabled; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | static bool mdp5_crtc_mode_fixup(struct drm_crtc *crtc, | 168 | static bool mdp5_crtc_mode_fixup(struct drm_crtc *crtc, |
| 164 | const struct drm_display_mode *mode, | 169 | const struct drm_display_mode *mode, |
| 165 | struct drm_display_mode *adjusted_mode) | 170 | struct drm_display_mode *adjusted_mode) |
| @@ -256,23 +261,41 @@ static void mdp5_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
| 256 | spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags); | 261 | spin_unlock_irqrestore(&mdp5_crtc->lm_lock, flags); |
| 257 | } | 262 | } |
| 258 | 263 | ||
| 259 | static void mdp5_crtc_prepare(struct drm_crtc *crtc) | 264 | static void mdp5_crtc_disable(struct drm_crtc *crtc) |
| 260 | { | 265 | { |
| 261 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | 266 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); |
| 267 | struct mdp5_kms *mdp5_kms = get_kms(crtc); | ||
| 268 | |||
| 262 | DBG("%s", mdp5_crtc->name); | 269 | DBG("%s", mdp5_crtc->name); |
| 263 | /* make sure we hold a ref to mdp clks while setting up mode: */ | 270 | |
| 264 | mdp5_enable(get_kms(crtc)); | 271 | if (WARN_ON(!mdp5_crtc->enabled)) |
| 265 | mdp5_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 272 | return; |
| 273 | |||
| 274 | /* set STAGE_UNUSED for all layers */ | ||
| 275 | mdp5_ctl_blend(mdp5_crtc->ctl, mdp5_crtc->lm, 0x00000000); | ||
| 276 | |||
| 277 | mdp_irq_unregister(&mdp5_kms->base, &mdp5_crtc->err); | ||
| 278 | mdp5_disable(mdp5_kms); | ||
| 279 | |||
| 280 | mdp5_crtc->enabled = false; | ||
| 266 | } | 281 | } |
| 267 | 282 | ||
| 268 | static void mdp5_crtc_commit(struct drm_crtc *crtc) | 283 | static void mdp5_crtc_enable(struct drm_crtc *crtc) |
| 269 | { | 284 | { |
| 270 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | 285 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); |
| 286 | struct mdp5_kms *mdp5_kms = get_kms(crtc); | ||
| 287 | |||
| 271 | DBG("%s", mdp5_crtc->name); | 288 | DBG("%s", mdp5_crtc->name); |
| 272 | mdp5_crtc_dpms(crtc, DRM_MODE_DPMS_ON); | 289 | |
| 290 | if (WARN_ON(mdp5_crtc->enabled)) | ||
| 291 | return; | ||
| 292 | |||
| 293 | mdp5_enable(mdp5_kms); | ||
| 294 | mdp_irq_register(&mdp5_kms->base, &mdp5_crtc->err); | ||
| 295 | |||
| 273 | crtc_flush_all(crtc); | 296 | crtc_flush_all(crtc); |
| 274 | /* drop the ref to mdp clk's that we got in prepare: */ | 297 | |
| 275 | mdp5_disable(get_kms(crtc)); | 298 | mdp5_crtc->enabled = true; |
| 276 | } | 299 | } |
| 277 | 300 | ||
| 278 | struct plane_state { | 301 | struct plane_state { |
| @@ -380,6 +403,132 @@ static int mdp5_crtc_set_property(struct drm_crtc *crtc, | |||
| 380 | return -EINVAL; | 403 | return -EINVAL; |
| 381 | } | 404 | } |
| 382 | 405 | ||
| 406 | static int mdp5_crtc_cursor_set(struct drm_crtc *crtc, | ||
| 407 | struct drm_file *file, uint32_t handle, | ||
| 408 | uint32_t width, uint32_t height) | ||
| 409 | { | ||
| 410 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | ||
| 411 | struct drm_device *dev = crtc->dev; | ||
| 412 | struct mdp5_kms *mdp5_kms = get_kms(crtc); | ||
| 413 | struct drm_gem_object *cursor_bo, *old_bo; | ||
| 414 | uint32_t blendcfg, cursor_addr, stride; | ||
| 415 | int ret, bpp, lm; | ||
| 416 | unsigned int depth; | ||
| 417 | enum mdp5_cursor_alpha cur_alpha = CURSOR_ALPHA_PER_PIXEL; | ||
| 418 | uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); | ||
| 419 | unsigned long flags; | ||
| 420 | |||
| 421 | if ((width > CURSOR_WIDTH) || (height > CURSOR_HEIGHT)) { | ||
| 422 | dev_err(dev->dev, "bad cursor size: %dx%d\n", width, height); | ||
| 423 | return -EINVAL; | ||
| 424 | } | ||
| 425 | |||
| 426 | if (NULL == mdp5_crtc->ctl) | ||
| 427 | return -EINVAL; | ||
| 428 | |||
| 429 | if (!handle) { | ||
| 430 | DBG("Cursor off"); | ||
| 431 | return mdp5_ctl_set_cursor(mdp5_crtc->ctl, false); | ||
| 432 | } | ||
| 433 | |||
| 434 | cursor_bo = drm_gem_object_lookup(dev, file, handle); | ||
| 435 | if (!cursor_bo) | ||
| 436 | return -ENOENT; | ||
| 437 | |||
| 438 | ret = msm_gem_get_iova(cursor_bo, mdp5_kms->id, &cursor_addr); | ||
| 439 | if (ret) | ||
| 440 | return -EINVAL; | ||
| 441 | |||
| 442 | lm = mdp5_crtc->lm; | ||
| 443 | drm_fb_get_bpp_depth(DRM_FORMAT_ARGB8888, &depth, &bpp); | ||
| 444 | stride = width * (bpp >> 3); | ||
| 445 | |||
| 446 | spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); | ||
| 447 | old_bo = mdp5_crtc->cursor.scanout_bo; | ||
| 448 | |||
| 449 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_STRIDE(lm), stride); | ||
| 450 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_FORMAT(lm), | ||
| 451 | MDP5_LM_CURSOR_FORMAT_FORMAT(CURSOR_FMT_ARGB8888)); | ||
| 452 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_IMG_SIZE(lm), | ||
| 453 | MDP5_LM_CURSOR_IMG_SIZE_SRC_H(height) | | ||
| 454 | MDP5_LM_CURSOR_IMG_SIZE_SRC_W(width)); | ||
| 455 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(lm), | ||
| 456 | MDP5_LM_CURSOR_SIZE_ROI_H(height) | | ||
| 457 | MDP5_LM_CURSOR_SIZE_ROI_W(width)); | ||
| 458 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BASE_ADDR(lm), cursor_addr); | ||
| 459 | |||
| 460 | |||
| 461 | blendcfg = MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_EN; | ||
| 462 | blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_TRANSP_EN; | ||
| 463 | blendcfg |= MDP5_LM_CURSOR_BLEND_CONFIG_BLEND_ALPHA_SEL(cur_alpha); | ||
| 464 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_BLEND_CONFIG(lm), blendcfg); | ||
| 465 | |||
| 466 | mdp5_crtc->cursor.scanout_bo = cursor_bo; | ||
| 467 | mdp5_crtc->cursor.width = width; | ||
| 468 | mdp5_crtc->cursor.height = height; | ||
| 469 | spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); | ||
| 470 | |||
| 471 | ret = mdp5_ctl_set_cursor(mdp5_crtc->ctl, true); | ||
| 472 | if (ret) | ||
| 473 | goto end; | ||
| 474 | |||
| 475 | flush_mask |= mdp5_ctl_get_flush(mdp5_crtc->ctl); | ||
| 476 | crtc_flush(crtc, flush_mask); | ||
| 477 | |||
| 478 | end: | ||
| 479 | if (old_bo) { | ||
| 480 | drm_flip_work_queue(&mdp5_crtc->unref_cursor_work, old_bo); | ||
| 481 | /* enable vblank to complete cursor work: */ | ||
| 482 | request_pending(crtc, PENDING_CURSOR); | ||
| 483 | } | ||
| 484 | return ret; | ||
| 485 | } | ||
| 486 | |||
| 487 | static int mdp5_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | ||
| 488 | { | ||
| 489 | struct mdp5_kms *mdp5_kms = get_kms(crtc); | ||
| 490 | struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc); | ||
| 491 | uint32_t flush_mask = mdp_ctl_flush_mask_cursor(0); | ||
| 492 | uint32_t xres = crtc->mode.hdisplay; | ||
| 493 | uint32_t yres = crtc->mode.vdisplay; | ||
| 494 | uint32_t roi_w; | ||
| 495 | uint32_t roi_h; | ||
| 496 | unsigned long flags; | ||
| 497 | |||
| 498 | x = (x > 0) ? x : 0; | ||
| 499 | y = (y > 0) ? y : 0; | ||
| 500 | |||
| 501 | /* | ||
| 502 | * Cursor Region Of Interest (ROI) is a plane read from cursor | ||
| 503 | * buffer to render. The ROI region is determined by the visiblity of | ||
| 504 | * the cursor point. In the default Cursor image the cursor point will | ||
| 505 | * be at the top left of the cursor image, unless it is specified | ||
| 506 | * otherwise using hotspot feature. | ||
| 507 | * | ||
| 508 | * If the cursor point reaches the right (xres - x < cursor.width) or | ||
| 509 | * bottom (yres - y < cursor.height) boundary of the screen, then ROI | ||
| 510 | * width and ROI height need to be evaluated to crop the cursor image | ||
| 511 | * accordingly. | ||
| 512 | * (xres-x) will be new cursor width when x > (xres - cursor.width) | ||
| 513 | * (yres-y) will be new cursor height when y > (yres - cursor.height) | ||
| 514 | */ | ||
| 515 | roi_w = min(mdp5_crtc->cursor.width, xres - x); | ||
| 516 | roi_h = min(mdp5_crtc->cursor.height, yres - y); | ||
| 517 | |||
| 518 | spin_lock_irqsave(&mdp5_crtc->cursor.lock, flags); | ||
| 519 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_SIZE(mdp5_crtc->lm), | ||
| 520 | MDP5_LM_CURSOR_SIZE_ROI_H(roi_h) | | ||
| 521 | MDP5_LM_CURSOR_SIZE_ROI_W(roi_w)); | ||
| 522 | mdp5_write(mdp5_kms, REG_MDP5_LM_CURSOR_START_XY(mdp5_crtc->lm), | ||
| 523 | MDP5_LM_CURSOR_START_XY_Y_START(y) | | ||
| 524 | MDP5_LM_CURSOR_START_XY_X_START(x)); | ||
| 525 | spin_unlock_irqrestore(&mdp5_crtc->cursor.lock, flags); | ||
| 526 | |||
| 527 | crtc_flush(crtc, flush_mask); | ||
| 528 | |||
| 529 | return 0; | ||
| 530 | } | ||
| 531 | |||
| 383 | static const struct drm_crtc_funcs mdp5_crtc_funcs = { | 532 | static const struct drm_crtc_funcs mdp5_crtc_funcs = { |
| 384 | .set_config = drm_atomic_helper_set_config, | 533 | .set_config = drm_atomic_helper_set_config, |
| 385 | .destroy = mdp5_crtc_destroy, | 534 | .destroy = mdp5_crtc_destroy, |
| @@ -388,16 +537,15 @@ static const struct drm_crtc_funcs mdp5_crtc_funcs = { | |||
| 388 | .reset = drm_atomic_helper_crtc_reset, | 537 | .reset = drm_atomic_helper_crtc_reset, |
| 389 | .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, | 538 | .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, |
| 390 | .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, | 539 | .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, |
| 540 | .cursor_set = mdp5_crtc_cursor_set, | ||
| 541 | .cursor_move = mdp5_crtc_cursor_move, | ||
| 391 | }; | 542 | }; |
| 392 | 543 | ||
| 393 | static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = { | 544 | static const struct drm_crtc_helper_funcs mdp5_crtc_helper_funcs = { |
| 394 | .dpms = mdp5_crtc_dpms, | ||
| 395 | .mode_fixup = mdp5_crtc_mode_fixup, | 545 | .mode_fixup = mdp5_crtc_mode_fixup, |
| 396 | .mode_set_nofb = mdp5_crtc_mode_set_nofb, | 546 | .mode_set_nofb = mdp5_crtc_mode_set_nofb, |
| 397 | .mode_set = drm_helper_crtc_mode_set, | 547 | .prepare = mdp5_crtc_disable, |
| 398 | .mode_set_base = drm_helper_crtc_mode_set_base, | 548 | .commit = mdp5_crtc_enable, |
| 399 | .prepare = mdp5_crtc_prepare, | ||
| 400 | .commit = mdp5_crtc_commit, | ||
| 401 | .atomic_check = mdp5_crtc_atomic_check, | 549 | .atomic_check = mdp5_crtc_atomic_check, |
| 402 | .atomic_begin = mdp5_crtc_atomic_begin, | 550 | .atomic_begin = mdp5_crtc_atomic_begin, |
| 403 | .atomic_flush = mdp5_crtc_atomic_flush, | 551 | .atomic_flush = mdp5_crtc_atomic_flush, |
| @@ -407,6 +555,7 @@ static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus) | |||
| 407 | { | 555 | { |
| 408 | struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, vblank); | 556 | struct mdp5_crtc *mdp5_crtc = container_of(irq, struct mdp5_crtc, vblank); |
| 409 | struct drm_crtc *crtc = &mdp5_crtc->base; | 557 | struct drm_crtc *crtc = &mdp5_crtc->base; |
| 558 | struct msm_drm_private *priv = crtc->dev->dev_private; | ||
| 410 | unsigned pending; | 559 | unsigned pending; |
| 411 | 560 | ||
| 412 | mdp_irq_unregister(&get_kms(crtc)->base, &mdp5_crtc->vblank); | 561 | mdp_irq_unregister(&get_kms(crtc)->base, &mdp5_crtc->vblank); |
| @@ -416,6 +565,9 @@ static void mdp5_crtc_vblank_irq(struct mdp_irq *irq, uint32_t irqstatus) | |||
| 416 | if (pending & PENDING_FLIP) { | 565 | if (pending & PENDING_FLIP) { |
| 417 | complete_flip(crtc, NULL); | 566 | complete_flip(crtc, NULL); |
| 418 | } | 567 | } |
| 568 | |||
| 569 | if (pending & PENDING_CURSOR) | ||
| 570 | drm_flip_work_commit(&mdp5_crtc->unref_cursor_work, priv->wq); | ||
| 419 | } | 571 | } |
| 420 | 572 | ||
| 421 | static void mdp5_crtc_err_irq(struct mdp_irq *irq, uint32_t irqstatus) | 573 | static void mdp5_crtc_err_irq(struct mdp_irq *irq, uint32_t irqstatus) |
| @@ -515,6 +667,7 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, | |||
| 515 | mdp5_crtc->lm = GET_LM_ID(id); | 667 | mdp5_crtc->lm = GET_LM_ID(id); |
| 516 | 668 | ||
| 517 | spin_lock_init(&mdp5_crtc->lm_lock); | 669 | spin_lock_init(&mdp5_crtc->lm_lock); |
| 670 | spin_lock_init(&mdp5_crtc->cursor.lock); | ||
| 518 | 671 | ||
| 519 | mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq; | 672 | mdp5_crtc->vblank.irq = mdp5_crtc_vblank_irq; |
| 520 | mdp5_crtc->err.irq = mdp5_crtc_err_irq; | 673 | mdp5_crtc->err.irq = mdp5_crtc_err_irq; |
| @@ -523,6 +676,10 @@ struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, | |||
| 523 | pipe2name(mdp5_plane_pipe(plane)), id); | 676 | pipe2name(mdp5_plane_pipe(plane)), id); |
| 524 | 677 | ||
| 525 | drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs); | 678 | drm_crtc_init_with_planes(dev, crtc, plane, NULL, &mdp5_crtc_funcs); |
| 679 | |||
| 680 | drm_flip_work_init(&mdp5_crtc->unref_cursor_work, | ||
| 681 | "unref cursor", unref_cursor_worker); | ||
| 682 | |||
| 526 | drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs); | 683 | drm_crtc_helper_add(crtc, &mdp5_crtc_helper_funcs); |
| 527 | plane->crtc = crtc; | 684 | plane->crtc = crtc; |
| 528 | 685 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c index dea4505ac963..151129032d16 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c | |||
| @@ -95,7 +95,7 @@ u32 ctl_read(struct mdp5_ctl *ctl, u32 reg) | |||
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | 97 | ||
| 98 | int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, enum mdp5_intf intf) | 98 | int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, int intf) |
| 99 | { | 99 | { |
| 100 | unsigned long flags; | 100 | unsigned long flags; |
| 101 | static const enum mdp5_intfnum intfnum[] = { | 101 | static const enum mdp5_intfnum intfnum[] = { |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h index 1018519b6af2..ad48788efeea 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h | |||
| @@ -34,7 +34,7 @@ void mdp5_ctlm_destroy(struct mdp5_ctl_manager *ctlm); | |||
| 34 | */ | 34 | */ |
| 35 | struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctlm, struct drm_crtc *crtc); | 35 | struct mdp5_ctl *mdp5_ctlm_request(struct mdp5_ctl_manager *ctlm, struct drm_crtc *crtc); |
| 36 | 36 | ||
| 37 | int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, enum mdp5_intf intf); | 37 | int mdp5_ctl_set_intf(struct mdp5_ctl *ctl, int intf); |
| 38 | 38 | ||
| 39 | int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, bool enable); | 39 | int mdp5_ctl_set_cursor(struct mdp5_ctl *ctl, bool enable); |
| 40 | 40 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c index 0254bfdeb92f..d6a14bb99988 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2014, The Linux Foundation. All rights reserved. | ||
| 2 | * Copyright (C) 2013 Red Hat | 3 | * Copyright (C) 2013 Red Hat |
| 3 | * Author: Rob Clark <robdclark@gmail.com> | 4 | * Author: Rob Clark <robdclark@gmail.com> |
| 4 | * | 5 | * |
| @@ -110,45 +111,6 @@ static const struct drm_encoder_funcs mdp5_encoder_funcs = { | |||
| 110 | .destroy = mdp5_encoder_destroy, | 111 | .destroy = mdp5_encoder_destroy, |
| 111 | }; | 112 | }; |
| 112 | 113 | ||
| 113 | static void mdp5_encoder_dpms(struct drm_encoder *encoder, int mode) | ||
| 114 | { | ||
| 115 | struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); | ||
| 116 | struct mdp5_kms *mdp5_kms = get_kms(encoder); | ||
| 117 | int intf = mdp5_encoder->intf; | ||
| 118 | bool enabled = (mode == DRM_MODE_DPMS_ON); | ||
| 119 | unsigned long flags; | ||
| 120 | |||
| 121 | DBG("mode=%d", mode); | ||
| 122 | |||
| 123 | if (enabled == mdp5_encoder->enabled) | ||
| 124 | return; | ||
| 125 | |||
| 126 | if (enabled) { | ||
| 127 | bs_set(mdp5_encoder, 1); | ||
| 128 | spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); | ||
| 129 | mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 1); | ||
| 130 | spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); | ||
| 131 | } else { | ||
| 132 | spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); | ||
| 133 | mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 0); | ||
| 134 | spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); | ||
| 135 | |||
| 136 | /* | ||
| 137 | * Wait for a vsync so we know the ENABLE=0 latched before | ||
| 138 | * the (connector) source of the vsync's gets disabled, | ||
| 139 | * otherwise we end up in a funny state if we re-enable | ||
| 140 | * before the disable latches, which results that some of | ||
| 141 | * the settings changes for the new modeset (like new | ||
| 142 | * scanout buffer) don't latch properly.. | ||
| 143 | */ | ||
| 144 | mdp_irq_wait(&mdp5_kms->base, intf2vblank(intf)); | ||
| 145 | |||
| 146 | bs_set(mdp5_encoder, 0); | ||
| 147 | } | ||
| 148 | |||
| 149 | mdp5_encoder->enabled = enabled; | ||
| 150 | } | ||
| 151 | |||
| 152 | static bool mdp5_encoder_mode_fixup(struct drm_encoder *encoder, | 114 | static bool mdp5_encoder_mode_fixup(struct drm_encoder *encoder, |
| 153 | const struct drm_display_mode *mode, | 115 | const struct drm_display_mode *mode, |
| 154 | struct drm_display_mode *adjusted_mode) | 116 | struct drm_display_mode *adjusted_mode) |
| @@ -162,11 +124,13 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, | |||
| 162 | { | 124 | { |
| 163 | struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); | 125 | struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); |
| 164 | struct mdp5_kms *mdp5_kms = get_kms(encoder); | 126 | struct mdp5_kms *mdp5_kms = get_kms(encoder); |
| 127 | struct drm_device *dev = encoder->dev; | ||
| 128 | struct drm_connector *connector; | ||
| 165 | int intf = mdp5_encoder->intf; | 129 | int intf = mdp5_encoder->intf; |
| 166 | uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol; | 130 | uint32_t dtv_hsync_skew, vsync_period, vsync_len, ctrl_pol; |
| 167 | uint32_t display_v_start, display_v_end; | 131 | uint32_t display_v_start, display_v_end; |
| 168 | uint32_t hsync_start_x, hsync_end_x; | 132 | uint32_t hsync_start_x, hsync_end_x; |
| 169 | uint32_t format; | 133 | uint32_t format = 0x2100; |
| 170 | unsigned long flags; | 134 | unsigned long flags; |
| 171 | 135 | ||
| 172 | mode = adjusted_mode; | 136 | mode = adjusted_mode; |
| @@ -188,7 +152,28 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, | |||
| 188 | /* probably need to get DATA_EN polarity from panel.. */ | 152 | /* probably need to get DATA_EN polarity from panel.. */ |
| 189 | 153 | ||
| 190 | dtv_hsync_skew = 0; /* get this from panel? */ | 154 | dtv_hsync_skew = 0; /* get this from panel? */ |
| 191 | format = 0x213f; /* get this from panel? */ | 155 | |
| 156 | /* Get color format from panel, default is 8bpc */ | ||
| 157 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
| 158 | if (connector->encoder == encoder) { | ||
| 159 | switch (connector->display_info.bpc) { | ||
| 160 | case 4: | ||
| 161 | format |= 0; | ||
| 162 | break; | ||
| 163 | case 5: | ||
| 164 | format |= 0x15; | ||
| 165 | break; | ||
| 166 | case 6: | ||
| 167 | format |= 0x2A; | ||
| 168 | break; | ||
| 169 | case 8: | ||
| 170 | default: | ||
| 171 | format |= 0x3F; | ||
| 172 | break; | ||
| 173 | } | ||
| 174 | break; | ||
| 175 | } | ||
| 176 | } | ||
| 192 | 177 | ||
| 193 | hsync_start_x = (mode->htotal - mode->hsync_start); | 178 | hsync_start_x = (mode->htotal - mode->hsync_start); |
| 194 | hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1; | 179 | hsync_end_x = mode->htotal - (mode->hsync_start - mode->hdisplay) - 1; |
| @@ -198,6 +183,16 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, | |||
| 198 | display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew; | 183 | display_v_start = (mode->vtotal - mode->vsync_start) * mode->htotal + dtv_hsync_skew; |
| 199 | display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1; | 184 | display_v_end = vsync_period - ((mode->vsync_start - mode->vdisplay) * mode->htotal) + dtv_hsync_skew - 1; |
| 200 | 185 | ||
| 186 | /* | ||
| 187 | * For edp only: | ||
| 188 | * DISPLAY_V_START = (VBP * HCYCLE) + HBP | ||
| 189 | * DISPLAY_V_END = (VBP + VACTIVE) * HCYCLE - 1 - HFP | ||
| 190 | */ | ||
| 191 | if (mdp5_encoder->intf_id == INTF_eDP) { | ||
| 192 | display_v_start += mode->htotal - mode->hsync_start; | ||
| 193 | display_v_end -= mode->hsync_start - mode->hdisplay; | ||
| 194 | } | ||
| 195 | |||
| 201 | spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); | 196 | spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); |
| 202 | 197 | ||
| 203 | mdp5_write(mdp5_kms, REG_MDP5_INTF_HSYNC_CTL(intf), | 198 | mdp5_write(mdp5_kms, REG_MDP5_INTF_HSYNC_CTL(intf), |
| @@ -225,25 +220,61 @@ static void mdp5_encoder_mode_set(struct drm_encoder *encoder, | |||
| 225 | spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); | 220 | spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); |
| 226 | } | 221 | } |
| 227 | 222 | ||
| 228 | static void mdp5_encoder_prepare(struct drm_encoder *encoder) | 223 | static void mdp5_encoder_disable(struct drm_encoder *encoder) |
| 229 | { | 224 | { |
| 230 | mdp5_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); | 225 | struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); |
| 226 | struct mdp5_kms *mdp5_kms = get_kms(encoder); | ||
| 227 | int intf = mdp5_encoder->intf; | ||
| 228 | unsigned long flags; | ||
| 229 | |||
| 230 | if (WARN_ON(!mdp5_encoder->enabled)) | ||
| 231 | return; | ||
| 232 | |||
| 233 | spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); | ||
| 234 | mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 0); | ||
| 235 | spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); | ||
| 236 | |||
| 237 | /* | ||
| 238 | * Wait for a vsync so we know the ENABLE=0 latched before | ||
| 239 | * the (connector) source of the vsync's gets disabled, | ||
| 240 | * otherwise we end up in a funny state if we re-enable | ||
| 241 | * before the disable latches, which results that some of | ||
| 242 | * the settings changes for the new modeset (like new | ||
| 243 | * scanout buffer) don't latch properly.. | ||
| 244 | */ | ||
| 245 | mdp_irq_wait(&mdp5_kms->base, intf2vblank(intf)); | ||
| 246 | |||
| 247 | bs_set(mdp5_encoder, 0); | ||
| 248 | |||
| 249 | mdp5_encoder->enabled = false; | ||
| 231 | } | 250 | } |
| 232 | 251 | ||
| 233 | static void mdp5_encoder_commit(struct drm_encoder *encoder) | 252 | static void mdp5_encoder_enable(struct drm_encoder *encoder) |
| 234 | { | 253 | { |
| 235 | struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); | 254 | struct mdp5_encoder *mdp5_encoder = to_mdp5_encoder(encoder); |
| 255 | struct mdp5_kms *mdp5_kms = get_kms(encoder); | ||
| 256 | int intf = mdp5_encoder->intf; | ||
| 257 | unsigned long flags; | ||
| 258 | |||
| 259 | if (WARN_ON(mdp5_encoder->enabled)) | ||
| 260 | return; | ||
| 261 | |||
| 236 | mdp5_crtc_set_intf(encoder->crtc, mdp5_encoder->intf, | 262 | mdp5_crtc_set_intf(encoder->crtc, mdp5_encoder->intf, |
| 237 | mdp5_encoder->intf_id); | 263 | mdp5_encoder->intf_id); |
| 238 | mdp5_encoder_dpms(encoder, DRM_MODE_DPMS_ON); | 264 | |
| 265 | bs_set(mdp5_encoder, 1); | ||
| 266 | spin_lock_irqsave(&mdp5_encoder->intf_lock, flags); | ||
| 267 | mdp5_write(mdp5_kms, REG_MDP5_INTF_TIMING_ENGINE_EN(intf), 1); | ||
| 268 | spin_unlock_irqrestore(&mdp5_encoder->intf_lock, flags); | ||
| 269 | |||
| 270 | mdp5_encoder->enabled = false; | ||
| 239 | } | 271 | } |
| 240 | 272 | ||
| 241 | static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = { | 273 | static const struct drm_encoder_helper_funcs mdp5_encoder_helper_funcs = { |
| 242 | .dpms = mdp5_encoder_dpms, | ||
| 243 | .mode_fixup = mdp5_encoder_mode_fixup, | 274 | .mode_fixup = mdp5_encoder_mode_fixup, |
| 244 | .mode_set = mdp5_encoder_mode_set, | 275 | .mode_set = mdp5_encoder_mode_set, |
| 245 | .prepare = mdp5_encoder_prepare, | 276 | .prepare = mdp5_encoder_disable, |
| 246 | .commit = mdp5_encoder_commit, | 277 | .commit = mdp5_encoder_enable, |
| 247 | }; | 278 | }; |
| 248 | 279 | ||
| 249 | /* initialize encoder */ | 280 | /* initialize encoder */ |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c index 9f01a4f21af2..92b61db5754c 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c | |||
| @@ -68,6 +68,18 @@ static int mdp5_hw_init(struct msm_kms *kms) | |||
| 68 | return 0; | 68 | return 0; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static void mdp5_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state) | ||
| 72 | { | ||
| 73 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); | ||
| 74 | mdp5_enable(mdp5_kms); | ||
| 75 | } | ||
| 76 | |||
| 77 | static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state) | ||
| 78 | { | ||
| 79 | struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); | ||
| 80 | mdp5_disable(mdp5_kms); | ||
| 81 | } | ||
| 82 | |||
| 71 | static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate, | 83 | static long mdp5_round_pixclk(struct msm_kms *kms, unsigned long rate, |
| 72 | struct drm_encoder *encoder) | 84 | struct drm_encoder *encoder) |
| 73 | { | 85 | { |
| @@ -115,6 +127,8 @@ static const struct mdp_kms_funcs kms_funcs = { | |||
| 115 | .irq = mdp5_irq, | 127 | .irq = mdp5_irq, |
| 116 | .enable_vblank = mdp5_enable_vblank, | 128 | .enable_vblank = mdp5_enable_vblank, |
| 117 | .disable_vblank = mdp5_disable_vblank, | 129 | .disable_vblank = mdp5_disable_vblank, |
| 130 | .prepare_commit = mdp5_prepare_commit, | ||
| 131 | .complete_commit = mdp5_complete_commit, | ||
| 118 | .get_format = mdp_get_format, | 132 | .get_format = mdp_get_format, |
| 119 | .round_pixclk = mdp5_round_pixclk, | 133 | .round_pixclk = mdp5_round_pixclk, |
| 120 | .preclose = mdp5_preclose, | 134 | .preclose = mdp5_preclose, |
| @@ -208,19 +222,18 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) | |||
| 208 | } | 222 | } |
| 209 | } | 223 | } |
| 210 | 224 | ||
| 211 | /* Construct encoder for HDMI: */ | 225 | if (priv->hdmi) { |
| 212 | encoder = mdp5_encoder_init(dev, 3, INTF_HDMI); | 226 | /* Construct encoder for HDMI: */ |
| 213 | if (IS_ERR(encoder)) { | 227 | encoder = mdp5_encoder_init(dev, 3, INTF_HDMI); |
| 214 | dev_err(dev->dev, "failed to construct encoder\n"); | 228 | if (IS_ERR(encoder)) { |
| 215 | ret = PTR_ERR(encoder); | 229 | dev_err(dev->dev, "failed to construct encoder\n"); |
| 216 | goto fail; | 230 | ret = PTR_ERR(encoder); |
| 217 | } | 231 | goto fail; |
| 232 | } | ||
| 218 | 233 | ||
| 219 | encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;; | 234 | encoder->possible_crtcs = (1 << priv->num_crtcs) - 1;; |
| 220 | priv->encoders[priv->num_encoders++] = encoder; | 235 | priv->encoders[priv->num_encoders++] = encoder; |
| 221 | 236 | ||
| 222 | /* Construct bridge/connector for HDMI: */ | ||
| 223 | if (priv->hdmi) { | ||
| 224 | ret = hdmi_modeset_init(priv->hdmi, dev, encoder); | 237 | ret = hdmi_modeset_init(priv->hdmi, dev, encoder); |
| 225 | if (ret) { | 238 | if (ret) { |
| 226 | dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); | 239 | dev_err(dev->dev, "failed to initialize HDMI: %d\n", ret); |
| @@ -228,6 +241,27 @@ static int modeset_init(struct mdp5_kms *mdp5_kms) | |||
| 228 | } | 241 | } |
| 229 | } | 242 | } |
| 230 | 243 | ||
| 244 | if (priv->edp) { | ||
| 245 | /* Construct encoder for eDP: */ | ||
| 246 | encoder = mdp5_encoder_init(dev, 0, INTF_eDP); | ||
| 247 | if (IS_ERR(encoder)) { | ||
| 248 | dev_err(dev->dev, "failed to construct eDP encoder\n"); | ||
| 249 | ret = PTR_ERR(encoder); | ||
| 250 | goto fail; | ||
| 251 | } | ||
| 252 | |||
| 253 | encoder->possible_crtcs = (1 << priv->num_crtcs) - 1; | ||
| 254 | priv->encoders[priv->num_encoders++] = encoder; | ||
| 255 | |||
| 256 | /* Construct bridge/connector for eDP: */ | ||
| 257 | ret = msm_edp_modeset_init(priv->edp, dev, encoder); | ||
| 258 | if (ret) { | ||
| 259 | dev_err(dev->dev, "failed to initialize eDP: %d\n", | ||
| 260 | ret); | ||
| 261 | goto fail; | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 231 | return 0; | 265 | return 0; |
| 232 | 266 | ||
| 233 | fail: | 267 | fail: |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h index dd69c77c0d64..49d011e8835b 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h | |||
| @@ -165,14 +165,25 @@ void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); | |||
| 165 | int mdp5_irq_domain_init(struct mdp5_kms *mdp5_kms); | 165 | int mdp5_irq_domain_init(struct mdp5_kms *mdp5_kms); |
| 166 | void mdp5_irq_domain_fini(struct mdp5_kms *mdp5_kms); | 166 | void mdp5_irq_domain_fini(struct mdp5_kms *mdp5_kms); |
| 167 | 167 | ||
| 168 | static inline bool pipe_supports_yuv(enum mdp5_pipe pipe) | ||
| 169 | { | ||
| 170 | switch (pipe) { | ||
| 171 | case SSPP_VIG0: | ||
| 172 | case SSPP_VIG1: | ||
| 173 | case SSPP_VIG2: | ||
| 174 | case SSPP_VIG3: | ||
| 175 | return true; | ||
| 176 | default: | ||
| 177 | return false; | ||
| 178 | } | ||
| 179 | } | ||
| 180 | |||
| 168 | static inline | 181 | static inline |
| 169 | uint32_t mdp5_get_formats(enum mdp5_pipe pipe, uint32_t *pixel_formats, | 182 | uint32_t mdp5_get_formats(enum mdp5_pipe pipe, uint32_t *pixel_formats, |
| 170 | uint32_t max_formats) | 183 | uint32_t max_formats) |
| 171 | { | 184 | { |
| 172 | /* TODO when we have YUV, we need to filter supported formats | 185 | return mdp_get_formats(pixel_formats, max_formats, |
| 173 | * based on pipe id.. | 186 | !pipe_supports_yuv(pipe)); |
| 174 | */ | ||
| 175 | return mdp_get_formats(pixel_formats, max_formats); | ||
| 176 | } | 187 | } |
| 177 | 188 | ||
| 178 | void mdp5_plane_install_properties(struct drm_plane *plane, | 189 | void mdp5_plane_install_properties(struct drm_plane *plane, |
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c index fc76f630e5b1..05cf9ab2a876 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c | |||
| @@ -18,8 +18,6 @@ | |||
| 18 | 18 | ||
| 19 | #include "mdp5_kms.h" | 19 | #include "mdp5_kms.h" |
| 20 | 20 | ||
| 21 | #define MAX_PLANE 4 | ||
| 22 | |||
| 23 | struct mdp5_plane { | 21 | struct mdp5_plane { |
| 24 | struct drm_plane base; | 22 | struct drm_plane base; |
| 25 | const char *name; | 23 | const char *name; |
| @@ -278,6 +276,155 @@ static void set_scanout_locked(struct drm_plane *plane, | |||
| 278 | plane->fb = fb; | 276 | plane->fb = fb; |
| 279 | } | 277 | } |
| 280 | 278 | ||
| 279 | /* Note: mdp5_plane->pipe_lock must be locked */ | ||
| 280 | static void csc_disable(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe) | ||
| 281 | { | ||
| 282 | uint32_t value = mdp5_read(mdp5_kms, REG_MDP5_PIPE_OP_MODE(pipe)) & | ||
| 283 | ~MDP5_PIPE_OP_MODE_CSC_1_EN; | ||
| 284 | |||
| 285 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_OP_MODE(pipe), value); | ||
| 286 | } | ||
| 287 | |||
| 288 | /* Note: mdp5_plane->pipe_lock must be locked */ | ||
| 289 | static void csc_enable(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe, | ||
| 290 | struct csc_cfg *csc) | ||
| 291 | { | ||
| 292 | uint32_t i, mode = 0; /* RGB, no CSC */ | ||
| 293 | uint32_t *matrix; | ||
| 294 | |||
| 295 | if (unlikely(!csc)) | ||
| 296 | return; | ||
| 297 | |||
| 298 | if ((csc->type == CSC_YUV2RGB) || (CSC_YUV2YUV == csc->type)) | ||
| 299 | mode |= MDP5_PIPE_OP_MODE_CSC_SRC_DATA_FORMAT(DATA_FORMAT_YUV); | ||
| 300 | if ((csc->type == CSC_RGB2YUV) || (CSC_YUV2YUV == csc->type)) | ||
| 301 | mode |= MDP5_PIPE_OP_MODE_CSC_DST_DATA_FORMAT(DATA_FORMAT_YUV); | ||
| 302 | mode |= MDP5_PIPE_OP_MODE_CSC_1_EN; | ||
| 303 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_OP_MODE(pipe), mode); | ||
| 304 | |||
| 305 | matrix = csc->matrix; | ||
| 306 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_0(pipe), | ||
| 307 | MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_11(matrix[0]) | | ||
| 308 | MDP5_PIPE_CSC_1_MATRIX_COEFF_0_COEFF_12(matrix[1])); | ||
| 309 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_1(pipe), | ||
| 310 | MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_13(matrix[2]) | | ||
| 311 | MDP5_PIPE_CSC_1_MATRIX_COEFF_1_COEFF_21(matrix[3])); | ||
| 312 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_2(pipe), | ||
| 313 | MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_22(matrix[4]) | | ||
| 314 | MDP5_PIPE_CSC_1_MATRIX_COEFF_2_COEFF_23(matrix[5])); | ||
| 315 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_3(pipe), | ||
| 316 | MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_31(matrix[6]) | | ||
| 317 | MDP5_PIPE_CSC_1_MATRIX_COEFF_3_COEFF_32(matrix[7])); | ||
| 318 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_MATRIX_COEFF_4(pipe), | ||
| 319 | MDP5_PIPE_CSC_1_MATRIX_COEFF_4_COEFF_33(matrix[8])); | ||
| 320 | |||
| 321 | for (i = 0; i < ARRAY_SIZE(csc->pre_bias); i++) { | ||
| 322 | uint32_t *pre_clamp = csc->pre_clamp; | ||
| 323 | uint32_t *post_clamp = csc->post_clamp; | ||
| 324 | |||
| 325 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_PRE_CLAMP(pipe, i), | ||
| 326 | MDP5_PIPE_CSC_1_PRE_CLAMP_REG_HIGH(pre_clamp[2*i+1]) | | ||
| 327 | MDP5_PIPE_CSC_1_PRE_CLAMP_REG_LOW(pre_clamp[2*i])); | ||
| 328 | |||
| 329 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_POST_CLAMP(pipe, i), | ||
| 330 | MDP5_PIPE_CSC_1_POST_CLAMP_REG_HIGH(post_clamp[2*i+1]) | | ||
| 331 | MDP5_PIPE_CSC_1_POST_CLAMP_REG_LOW(post_clamp[2*i])); | ||
| 332 | |||
| 333 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_PRE_BIAS(pipe, i), | ||
| 334 | MDP5_PIPE_CSC_1_PRE_BIAS_REG_VALUE(csc->pre_bias[i])); | ||
| 335 | |||
| 336 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_CSC_1_POST_BIAS(pipe, i), | ||
| 337 | MDP5_PIPE_CSC_1_POST_BIAS_REG_VALUE(csc->post_bias[i])); | ||
| 338 | } | ||
| 339 | } | ||
| 340 | |||
| 341 | #define PHASE_STEP_SHIFT 21 | ||
| 342 | #define DOWN_SCALE_RATIO_MAX 32 /* 2^(26-21) */ | ||
| 343 | |||
| 344 | static int calc_phase_step(uint32_t src, uint32_t dst, uint32_t *out_phase) | ||
| 345 | { | ||
| 346 | uint32_t unit; | ||
| 347 | |||
| 348 | if (src == 0 || dst == 0) | ||
| 349 | return -EINVAL; | ||
| 350 | |||
| 351 | /* | ||
| 352 | * PHASE_STEP_X/Y is coded on 26 bits (25:0), | ||
| 353 | * where 2^21 represents the unity "1" in fixed-point hardware design. | ||
| 354 | * This leaves 5 bits for the integer part (downscale case): | ||
| 355 | * -> maximum downscale ratio = 0b1_1111 = 31 | ||
| 356 | */ | ||
| 357 | if (src > (dst * DOWN_SCALE_RATIO_MAX)) | ||
| 358 | return -EOVERFLOW; | ||
| 359 | |||
| 360 | unit = 1 << PHASE_STEP_SHIFT; | ||
| 361 | *out_phase = mult_frac(unit, src, dst); | ||
| 362 | |||
| 363 | return 0; | ||
| 364 | } | ||
| 365 | |||
| 366 | static int calc_scalex_steps(uint32_t pixel_format, uint32_t src, uint32_t dest, | ||
| 367 | uint32_t phasex_steps[2]) | ||
| 368 | { | ||
| 369 | uint32_t phasex_step; | ||
| 370 | unsigned int hsub; | ||
| 371 | int ret; | ||
| 372 | |||
| 373 | ret = calc_phase_step(src, dest, &phasex_step); | ||
| 374 | if (ret) | ||
| 375 | return ret; | ||
| 376 | |||
| 377 | hsub = drm_format_horz_chroma_subsampling(pixel_format); | ||
| 378 | |||
| 379 | phasex_steps[0] = phasex_step; | ||
| 380 | phasex_steps[1] = phasex_step / hsub; | ||
| 381 | |||
| 382 | return 0; | ||
| 383 | } | ||
| 384 | |||
| 385 | static int calc_scaley_steps(uint32_t pixel_format, uint32_t src, uint32_t dest, | ||
| 386 | uint32_t phasey_steps[2]) | ||
| 387 | { | ||
| 388 | uint32_t phasey_step; | ||
| 389 | unsigned int vsub; | ||
| 390 | int ret; | ||
| 391 | |||
| 392 | ret = calc_phase_step(src, dest, &phasey_step); | ||
| 393 | if (ret) | ||
| 394 | return ret; | ||
| 395 | |||
| 396 | vsub = drm_format_vert_chroma_subsampling(pixel_format); | ||
| 397 | |||
| 398 | phasey_steps[0] = phasey_step; | ||
| 399 | phasey_steps[1] = phasey_step / vsub; | ||
| 400 | |||
| 401 | return 0; | ||
| 402 | } | ||
| 403 | |||
| 404 | static uint32_t get_scalex_config(uint32_t src, uint32_t dest) | ||
| 405 | { | ||
| 406 | uint32_t filter; | ||
| 407 | |||
| 408 | filter = (src <= dest) ? SCALE_FILTER_BIL : SCALE_FILTER_PCMN; | ||
| 409 | |||
| 410 | return MDP5_PIPE_SCALE_CONFIG_SCALEX_EN | | ||
| 411 | MDP5_PIPE_SCALE_CONFIG_SCALEX_MIN_FILTER(filter) | | ||
| 412 | MDP5_PIPE_SCALE_CONFIG_SCALEX_CR_FILTER(filter) | | ||
| 413 | MDP5_PIPE_SCALE_CONFIG_SCALEX_MAX_FILTER(filter); | ||
| 414 | } | ||
| 415 | |||
| 416 | static uint32_t get_scaley_config(uint32_t src, uint32_t dest) | ||
| 417 | { | ||
| 418 | uint32_t filter; | ||
| 419 | |||
| 420 | filter = (src <= dest) ? SCALE_FILTER_BIL : SCALE_FILTER_PCMN; | ||
| 421 | |||
| 422 | return MDP5_PIPE_SCALE_CONFIG_SCALEY_EN | | ||
| 423 | MDP5_PIPE_SCALE_CONFIG_SCALEY_MIN_FILTER(filter) | | ||
| 424 | MDP5_PIPE_SCALE_CONFIG_SCALEY_CR_FILTER(filter) | | ||
| 425 | MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER(filter); | ||
| 426 | } | ||
| 427 | |||
| 281 | static int mdp5_plane_mode_set(struct drm_plane *plane, | 428 | static int mdp5_plane_mode_set(struct drm_plane *plane, |
| 282 | struct drm_crtc *crtc, struct drm_framebuffer *fb, | 429 | struct drm_crtc *crtc, struct drm_framebuffer *fb, |
| 283 | int crtc_x, int crtc_y, | 430 | int crtc_x, int crtc_y, |
| @@ -287,11 +434,14 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, | |||
| 287 | { | 434 | { |
| 288 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); | 435 | struct mdp5_plane *mdp5_plane = to_mdp5_plane(plane); |
| 289 | struct mdp5_kms *mdp5_kms = get_kms(plane); | 436 | struct mdp5_kms *mdp5_kms = get_kms(plane); |
| 437 | struct device *dev = mdp5_kms->dev->dev; | ||
| 290 | enum mdp5_pipe pipe = mdp5_plane->pipe; | 438 | enum mdp5_pipe pipe = mdp5_plane->pipe; |
| 291 | const struct mdp_format *format; | 439 | const struct mdp_format *format; |
| 292 | uint32_t nplanes, config = 0; | 440 | uint32_t nplanes, config = 0; |
| 293 | uint32_t phasex_step = 0, phasey_step = 0; | 441 | /* below array -> index 0: comp 0/3 ; index 1: comp 1/2 */ |
| 442 | uint32_t phasex_step[2] = {0,}, phasey_step[2] = {0,}; | ||
| 294 | uint32_t hdecm = 0, vdecm = 0; | 443 | uint32_t hdecm = 0, vdecm = 0; |
| 444 | uint32_t pix_format; | ||
| 295 | unsigned long flags; | 445 | unsigned long flags; |
| 296 | int ret; | 446 | int ret; |
| 297 | 447 | ||
| @@ -301,6 +451,9 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, | |||
| 301 | if (WARN_ON(nplanes > pipe2nclients(pipe))) | 451 | if (WARN_ON(nplanes > pipe2nclients(pipe))) |
| 302 | return -EINVAL; | 452 | return -EINVAL; |
| 303 | 453 | ||
| 454 | format = to_mdp_format(msm_framebuffer_format(fb)); | ||
| 455 | pix_format = format->base.pixel_format; | ||
| 456 | |||
| 304 | /* src values are in Q16 fixed point, convert to integer: */ | 457 | /* src values are in Q16 fixed point, convert to integer: */ |
| 305 | src_x = src_x >> 16; | 458 | src_x = src_x >> 16; |
| 306 | src_y = src_y >> 16; | 459 | src_y = src_y >> 16; |
| @@ -325,14 +478,28 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, | |||
| 325 | */ | 478 | */ |
| 326 | mdp5_smp_configure(mdp5_kms->smp, pipe); | 479 | mdp5_smp_configure(mdp5_kms->smp, pipe); |
| 327 | 480 | ||
| 328 | if (src_w != crtc_w) { | 481 | /* SCALE is used to both scale and up-sample chroma components */ |
| 329 | config |= MDP5_PIPE_SCALE_CONFIG_SCALEX_EN; | 482 | |
| 330 | /* TODO calc phasex_step, hdecm */ | 483 | if ((src_w != crtc_w) || MDP_FORMAT_IS_YUV(format)) { |
| 484 | /* TODO calc hdecm */ | ||
| 485 | ret = calc_scalex_steps(pix_format, src_w, crtc_w, phasex_step); | ||
| 486 | if (ret) { | ||
| 487 | dev_err(dev, "X scaling (%d -> %d) failed: %d\n", | ||
| 488 | src_w, crtc_w, ret); | ||
| 489 | return ret; | ||
| 490 | } | ||
| 491 | config |= get_scalex_config(src_w, crtc_w); | ||
| 331 | } | 492 | } |
| 332 | 493 | ||
| 333 | if (src_h != crtc_h) { | 494 | if ((src_h != crtc_h) || MDP_FORMAT_IS_YUV(format)) { |
| 334 | config |= MDP5_PIPE_SCALE_CONFIG_SCALEY_EN; | 495 | /* TODO calc vdecm */ |
| 335 | /* TODO calc phasey_step, vdecm */ | 496 | ret = calc_scaley_steps(pix_format, src_h, crtc_h, phasey_step); |
| 497 | if (ret) { | ||
| 498 | dev_err(dev, "Y scaling (%d -> %d) failed: %d\n", | ||
| 499 | src_h, crtc_h, ret); | ||
| 500 | return ret; | ||
| 501 | } | ||
| 502 | config |= get_scaley_config(src_h, crtc_h); | ||
| 336 | } | 503 | } |
| 337 | 504 | ||
| 338 | spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); | 505 | spin_lock_irqsave(&mdp5_plane->pipe_lock, flags); |
| @@ -357,8 +524,6 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, | |||
| 357 | MDP5_PIPE_OUT_XY_X(crtc_x) | | 524 | MDP5_PIPE_OUT_XY_X(crtc_x) | |
| 358 | MDP5_PIPE_OUT_XY_Y(crtc_y)); | 525 | MDP5_PIPE_OUT_XY_Y(crtc_y)); |
| 359 | 526 | ||
| 360 | format = to_mdp_format(msm_framebuffer_format(fb)); | ||
| 361 | |||
| 362 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_FORMAT(pipe), | 527 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_FORMAT(pipe), |
| 363 | MDP5_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) | | 528 | MDP5_PIPE_SRC_FORMAT_A_BPC(format->bpc_a) | |
| 364 | MDP5_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) | | 529 | MDP5_PIPE_SRC_FORMAT_R_BPC(format->bpc_r) | |
| @@ -368,8 +533,8 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, | |||
| 368 | MDP5_PIPE_SRC_FORMAT_CPP(format->cpp - 1) | | 533 | MDP5_PIPE_SRC_FORMAT_CPP(format->cpp - 1) | |
| 369 | MDP5_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) | | 534 | MDP5_PIPE_SRC_FORMAT_UNPACK_COUNT(format->unpack_count - 1) | |
| 370 | COND(format->unpack_tight, MDP5_PIPE_SRC_FORMAT_UNPACK_TIGHT) | | 535 | COND(format->unpack_tight, MDP5_PIPE_SRC_FORMAT_UNPACK_TIGHT) | |
| 371 | MDP5_PIPE_SRC_FORMAT_NUM_PLANES(nplanes - 1) | | 536 | MDP5_PIPE_SRC_FORMAT_NUM_PLANES(format->fetch_type) | |
| 372 | MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(CHROMA_RGB)); | 537 | MDP5_PIPE_SRC_FORMAT_CHROMA_SAMP(format->chroma_sample)); |
| 373 | 538 | ||
| 374 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_UNPACK(pipe), | 539 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_UNPACK(pipe), |
| 375 | MDP5_PIPE_SRC_UNPACK_ELEM0(format->unpack[0]) | | 540 | MDP5_PIPE_SRC_UNPACK_ELEM0(format->unpack[0]) | |
| @@ -383,18 +548,24 @@ static int mdp5_plane_mode_set(struct drm_plane *plane, | |||
| 383 | /* not using secure mode: */ | 548 | /* not using secure mode: */ |
| 384 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_ADDR_SW_STATUS(pipe), 0); | 549 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SRC_ADDR_SW_STATUS(pipe), 0); |
| 385 | 550 | ||
| 386 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_X(pipe), phasex_step); | 551 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_X(pipe), |
| 387 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(pipe), phasey_step); | 552 | phasex_step[0]); |
| 553 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_PHASE_STEP_Y(pipe), | ||
| 554 | phasey_step[0]); | ||
| 555 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_X(pipe), | ||
| 556 | phasex_step[1]); | ||
| 557 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CR_PHASE_STEP_Y(pipe), | ||
| 558 | phasey_step[1]); | ||
| 388 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_DECIMATION(pipe), | 559 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_DECIMATION(pipe), |
| 389 | MDP5_PIPE_DECIMATION_VERT(vdecm) | | 560 | MDP5_PIPE_DECIMATION_VERT(vdecm) | |
| 390 | MDP5_PIPE_DECIMATION_HORZ(hdecm)); | 561 | MDP5_PIPE_DECIMATION_HORZ(hdecm)); |
| 391 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CONFIG(pipe), | 562 | mdp5_write(mdp5_kms, REG_MDP5_PIPE_SCALE_CONFIG(pipe), config); |
| 392 | MDP5_PIPE_SCALE_CONFIG_SCALEX_MIN_FILTER(SCALE_FILTER_NEAREST) | | 563 | |
| 393 | MDP5_PIPE_SCALE_CONFIG_SCALEY_MIN_FILTER(SCALE_FILTER_NEAREST) | | 564 | if (MDP_FORMAT_IS_YUV(format)) |
| 394 | MDP5_PIPE_SCALE_CONFIG_SCALEX_CR_FILTER(SCALE_FILTER_NEAREST) | | 565 | csc_enable(mdp5_kms, pipe, |
| 395 | MDP5_PIPE_SCALE_CONFIG_SCALEY_CR_FILTER(SCALE_FILTER_NEAREST) | | 566 | mdp_get_default_csc_cfg(CSC_YUV2RGB)); |
| 396 | MDP5_PIPE_SCALE_CONFIG_SCALEX_MAX_FILTER(SCALE_FILTER_NEAREST) | | 567 | else |
| 397 | MDP5_PIPE_SCALE_CONFIG_SCALEY_MAX_FILTER(SCALE_FILTER_NEAREST)); | 568 | csc_disable(mdp5_kms, pipe); |
| 398 | 569 | ||
| 399 | set_scanout_locked(plane, fb); | 570 | set_scanout_locked(plane, fb); |
| 400 | 571 | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c index bf551885e019..1f795af89680 100644 --- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c +++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c | |||
| @@ -119,9 +119,10 @@ static int smp_request_block(struct mdp5_smp *smp, | |||
| 119 | 119 | ||
| 120 | spin_lock_irqsave(&smp->state_lock, flags); | 120 | spin_lock_irqsave(&smp->state_lock, flags); |
| 121 | 121 | ||
| 122 | nblks -= reserved; | 122 | if (reserved) { |
| 123 | if (reserved) | 123 | nblks = max(0, nblks - reserved); |
| 124 | DBG("%d MMBs allocated (%d reserved)", nblks, reserved); | 124 | DBG("%d MMBs allocated (%d reserved)", nblks, reserved); |
| 125 | } | ||
| 125 | 126 | ||
| 126 | avail = cnt - bitmap_weight(smp->state, cnt); | 127 | avail = cnt - bitmap_weight(smp->state, cnt); |
| 127 | if (nblks > avail) { | 128 | if (nblks > avail) { |
diff --git a/drivers/gpu/drm/msm/mdp/mdp_common.xml.h b/drivers/gpu/drm/msm/mdp/mdp_common.xml.h index 64c1afd6030a..a1d35f162c7f 100644 --- a/drivers/gpu/drm/msm/mdp/mdp_common.xml.h +++ b/drivers/gpu/drm/msm/mdp/mdp_common.xml.h | |||
| @@ -8,18 +8,19 @@ http://github.com/freedreno/envytools/ | |||
| 8 | git clone https://github.com/freedreno/envytools.git | 8 | git clone https://github.com/freedreno/envytools.git |
| 9 | 9 | ||
| 10 | The rules-ng-ng source files this header was generated from are: | 10 | The rules-ng-ng source files this header was generated from are: |
| 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 647 bytes, from 2013-11-30 14:45:35) | 11 | - /home/robclark/src/freedreno/envytools/rnndb/msm.xml ( 676 bytes, from 2014-12-05 15:34:49) |
| 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) | 12 | - /home/robclark/src/freedreno/envytools/rnndb/freedreno_copyright.xml ( 1453 bytes, from 2013-03-31 16:51:27) |
| 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 17996 bytes, from 2013-12-01 19:10:31) | 13 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp4.xml ( 20908 bytes, from 2014-12-08 16:13:00) |
| 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 1615 bytes, from 2013-11-30 15:00:52) | 14 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp_common.xml ( 2357 bytes, from 2014-12-08 16:13:00) |
| 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 22517 bytes, from 2014-06-25 12:55:02) | 15 | - /home/robclark/src/freedreno/envytools/rnndb/mdp/mdp5.xml ( 27208 bytes, from 2015-01-13 23:56:11) |
| 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) | 16 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/dsi.xml ( 11712 bytes, from 2013-08-17 17:13:43) |
| 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) | 17 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/sfpb.xml ( 344 bytes, from 2013-08-11 19:26:32) |
| 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1544 bytes, from 2013-08-16 19:17:05) | 18 | - /home/robclark/src/freedreno/envytools/rnndb/dsi/mmss_cc.xml ( 1686 bytes, from 2014-10-31 16:48:57) |
| 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) | 19 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/qfprom.xml ( 600 bytes, from 2013-07-05 19:21:12) |
| 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 23613 bytes, from 2014-06-25 12:53:44) | 20 | - /home/robclark/src/freedreno/envytools/rnndb/hdmi/hdmi.xml ( 26848 bytes, from 2015-01-13 23:55:57) |
| 21 | - /home/robclark/src/freedreno/envytools/rnndb/edp/edp.xml ( 8253 bytes, from 2014-12-08 16:13:00) | ||
| 21 | 22 | ||
| 22 | Copyright (C) 2013 by the following authors: | 23 | Copyright (C) 2013-2014 by the following authors: |
| 23 | - Rob Clark <robdclark@gmail.com> (robclark) | 24 | - Rob Clark <robdclark@gmail.com> (robclark) |
| 24 | 25 | ||
| 25 | Permission is hereby granted, free of charge, to any person obtaining | 26 | Permission is hereby granted, free of charge, to any person obtaining |
| @@ -44,6 +45,19 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
| 44 | */ | 45 | */ |
| 45 | 46 | ||
| 46 | 47 | ||
| 48 | enum mdp_chroma_samp_type { | ||
| 49 | CHROMA_RGB = 0, | ||
| 50 | CHROMA_H2V1 = 1, | ||
| 51 | CHROMA_H1V2 = 2, | ||
| 52 | CHROMA_420 = 3, | ||
| 53 | }; | ||
| 54 | |||
| 55 | enum mdp_sspp_fetch_type { | ||
| 56 | MDP_PLANE_INTERLEAVED = 0, | ||
| 57 | MDP_PLANE_PLANAR = 1, | ||
| 58 | MDP_PLANE_PSEUDO_PLANAR = 2, | ||
| 59 | }; | ||
| 60 | |||
| 47 | enum mdp_mixer_stage_id { | 61 | enum mdp_mixer_stage_id { |
| 48 | STAGE_UNUSED = 0, | 62 | STAGE_UNUSED = 0, |
| 49 | STAGE_BASE = 1, | 63 | STAGE_BASE = 1, |
diff --git a/drivers/gpu/drm/msm/mdp/mdp_format.c b/drivers/gpu/drm/msm/mdp/mdp_format.c index e0a6ffbe6ab4..f683433b6727 100644 --- a/drivers/gpu/drm/msm/mdp/mdp_format.c +++ b/drivers/gpu/drm/msm/mdp/mdp_format.c | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2014 The Linux Foundation. All rights reserved. | ||
| 2 | * Copyright (C) 2013 Red Hat | 3 | * Copyright (C) 2013 Red Hat |
| 3 | * Author: Rob Clark <robdclark@gmail.com> | 4 | * Author: Rob Clark <robdclark@gmail.com> |
| 4 | * | 5 | * |
| @@ -19,7 +20,58 @@ | |||
| 19 | #include "msm_drv.h" | 20 | #include "msm_drv.h" |
| 20 | #include "mdp_kms.h" | 21 | #include "mdp_kms.h" |
| 21 | 22 | ||
| 22 | #define FMT(name, a, r, g, b, e0, e1, e2, e3, alpha, tight, c, cnt) { \ | 23 | static struct csc_cfg csc_convert[CSC_MAX] = { |
| 24 | [CSC_RGB2RGB] = { | ||
| 25 | .type = CSC_RGB2RGB, | ||
| 26 | .matrix = { | ||
| 27 | 0x0200, 0x0000, 0x0000, | ||
| 28 | 0x0000, 0x0200, 0x0000, | ||
| 29 | 0x0000, 0x0000, 0x0200 | ||
| 30 | }, | ||
| 31 | .pre_bias = { 0x0, 0x0, 0x0 }, | ||
| 32 | .post_bias = { 0x0, 0x0, 0x0 }, | ||
| 33 | .pre_clamp = { 0x0, 0xff, 0x0, 0xff, 0x0, 0xff }, | ||
| 34 | .post_clamp = { 0x0, 0xff, 0x0, 0xff, 0x0, 0xff }, | ||
| 35 | }, | ||
| 36 | [CSC_YUV2RGB] = { | ||
| 37 | .type = CSC_YUV2RGB, | ||
| 38 | .matrix = { | ||
| 39 | 0x0254, 0x0000, 0x0331, | ||
| 40 | 0x0254, 0xff37, 0xfe60, | ||
| 41 | 0x0254, 0x0409, 0x0000 | ||
| 42 | }, | ||
| 43 | .pre_bias = { 0xfff0, 0xff80, 0xff80 }, | ||
| 44 | .post_bias = { 0x00, 0x00, 0x00 }, | ||
| 45 | .pre_clamp = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, | ||
| 46 | .post_clamp = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, | ||
| 47 | }, | ||
| 48 | [CSC_RGB2YUV] = { | ||
| 49 | .type = CSC_RGB2YUV, | ||
| 50 | .matrix = { | ||
| 51 | 0x0083, 0x0102, 0x0032, | ||
| 52 | 0x1fb5, 0x1f6c, 0x00e1, | ||
| 53 | 0x00e1, 0x1f45, 0x1fdc | ||
| 54 | }, | ||
| 55 | .pre_bias = { 0x00, 0x00, 0x00 }, | ||
| 56 | .post_bias = { 0x10, 0x80, 0x80 }, | ||
| 57 | .pre_clamp = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, | ||
| 58 | .post_clamp = { 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0 }, | ||
| 59 | }, | ||
| 60 | [CSC_YUV2YUV] = { | ||
| 61 | .type = CSC_YUV2YUV, | ||
| 62 | .matrix = { | ||
| 63 | 0x0200, 0x0000, 0x0000, | ||
| 64 | 0x0000, 0x0200, 0x0000, | ||
| 65 | 0x0000, 0x0000, 0x0200 | ||
| 66 | }, | ||
| 67 | .pre_bias = { 0x00, 0x00, 0x00 }, | ||
| 68 | .post_bias = { 0x00, 0x00, 0x00 }, | ||
| 69 | .pre_clamp = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, | ||
| 70 | .post_clamp = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff }, | ||
| 71 | }, | ||
| 72 | }; | ||
| 73 | |||
| 74 | #define FMT(name, a, r, g, b, e0, e1, e2, e3, alpha, tight, c, cnt, fp, cs) { \ | ||
| 23 | .base = { .pixel_format = DRM_FORMAT_ ## name }, \ | 75 | .base = { .pixel_format = DRM_FORMAT_ ## name }, \ |
| 24 | .bpc_a = BPC ## a ## A, \ | 76 | .bpc_a = BPC ## a ## A, \ |
| 25 | .bpc_r = BPC ## r, \ | 77 | .bpc_r = BPC ## r, \ |
| @@ -30,21 +82,46 @@ | |||
| 30 | .unpack_tight = tight, \ | 82 | .unpack_tight = tight, \ |
| 31 | .cpp = c, \ | 83 | .cpp = c, \ |
| 32 | .unpack_count = cnt, \ | 84 | .unpack_count = cnt, \ |
| 33 | } | 85 | .fetch_type = fp, \ |
| 86 | .chroma_sample = cs \ | ||
| 87 | } | ||
| 34 | 88 | ||
| 35 | #define BPC0A 0 | 89 | #define BPC0A 0 |
| 36 | 90 | ||
| 91 | /* | ||
| 92 | * Note: Keep RGB formats 1st, followed by YUV formats to avoid breaking | ||
| 93 | * mdp_get_rgb_formats()'s implementation. | ||
| 94 | */ | ||
| 37 | static const struct mdp_format formats[] = { | 95 | static const struct mdp_format formats[] = { |
| 38 | /* name a r g b e0 e1 e2 e3 alpha tight cpp cnt */ | 96 | /* name a r g b e0 e1 e2 e3 alpha tight cpp cnt ... */ |
| 39 | FMT(ARGB8888, 8, 8, 8, 8, 1, 0, 2, 3, true, true, 4, 4), | 97 | FMT(ARGB8888, 8, 8, 8, 8, 1, 0, 2, 3, true, true, 4, 4, |
| 40 | FMT(XRGB8888, 8, 8, 8, 8, 1, 0, 2, 3, false, true, 4, 4), | 98 | MDP_PLANE_INTERLEAVED, CHROMA_RGB), |
| 41 | FMT(RGB888, 0, 8, 8, 8, 1, 0, 2, 0, false, true, 3, 3), | 99 | FMT(XRGB8888, 8, 8, 8, 8, 1, 0, 2, 3, false, true, 4, 4, |
| 42 | FMT(BGR888, 0, 8, 8, 8, 2, 0, 1, 0, false, true, 3, 3), | 100 | MDP_PLANE_INTERLEAVED, CHROMA_RGB), |
| 43 | FMT(RGB565, 0, 5, 6, 5, 1, 0, 2, 0, false, true, 2, 3), | 101 | FMT(RGB888, 0, 8, 8, 8, 1, 0, 2, 0, false, true, 3, 3, |
| 44 | FMT(BGR565, 0, 5, 6, 5, 2, 0, 1, 0, false, true, 2, 3), | 102 | MDP_PLANE_INTERLEAVED, CHROMA_RGB), |
| 103 | FMT(BGR888, 0, 8, 8, 8, 2, 0, 1, 0, false, true, 3, 3, | ||
| 104 | MDP_PLANE_INTERLEAVED, CHROMA_RGB), | ||
| 105 | FMT(RGB565, 0, 5, 6, 5, 1, 0, 2, 0, false, true, 2, 3, | ||
| 106 | MDP_PLANE_INTERLEAVED, CHROMA_RGB), | ||
| 107 | FMT(BGR565, 0, 5, 6, 5, 2, 0, 1, 0, false, true, 2, 3, | ||
| 108 | MDP_PLANE_INTERLEAVED, CHROMA_RGB), | ||
| 109 | |||
| 110 | /* --- RGB formats above / YUV formats below this line --- */ | ||
| 111 | |||
| 112 | FMT(NV12, 0, 8, 8, 8, 1, 2, 0, 0, false, true, 2, 2, | ||
| 113 | MDP_PLANE_PSEUDO_PLANAR, CHROMA_420), | ||
| 114 | FMT(NV21, 0, 8, 8, 8, 2, 1, 0, 0, false, true, 2, 2, | ||
| 115 | MDP_PLANE_PSEUDO_PLANAR, CHROMA_420), | ||
| 45 | }; | 116 | }; |
| 46 | 117 | ||
| 47 | uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats) | 118 | /* |
| 119 | * Note: | ||
| 120 | * @rgb_only must be set to true, when requesting | ||
| 121 | * supported formats for RGB pipes. | ||
| 122 | */ | ||
| 123 | uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats, | ||
| 124 | bool rgb_only) | ||
| 48 | { | 125 | { |
| 49 | uint32_t i; | 126 | uint32_t i; |
| 50 | for (i = 0; i < ARRAY_SIZE(formats); i++) { | 127 | for (i = 0; i < ARRAY_SIZE(formats); i++) { |
| @@ -53,6 +130,9 @@ uint32_t mdp_get_formats(uint32_t *pixel_formats, uint32_t max_formats) | |||
| 53 | if (i == max_formats) | 130 | if (i == max_formats) |
| 54 | break; | 131 | break; |
| 55 | 132 | ||
| 133 | if (rgb_only && MDP_FORMAT_IS_YUV(f)) | ||
| 134 | break; | ||
| 135 | |||
| 56 | pixel_formats[i] = f->base.pixel_format; | 136 | pixel_formats[i] = f->base.pixel_format; |
| 57 | } | 137 | } |
| 58 | 138 | ||
| @@ -69,3 +149,11 @@ const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format) | |||
| 69 | } | 149 | } |
| 70 | return NULL; | 150 | return NULL; |
| 71 | } | 151 | } |
| 152 | |||
| 153 | struct csc_cfg *mdp_get_default_csc_cfg(enum csc_type type) | ||
| 154 | { | ||
| 155 | if (unlikely(WARN_ON(type >= CSC_MAX))) | ||
| 156 | return NULL; | ||
| 157 | |||
| 158 | return &csc_convert[type]; | ||
| 159 | } | ||
diff --git a/drivers/gpu/drm/msm/mdp/mdp_kms.c b/drivers/gpu/drm/msm/mdp/mdp_kms.c index 2a731722d840..1988c243f437 100644 --- a/drivers/gpu/drm/msm/mdp/mdp_kms.c +++ b/drivers/gpu/drm/msm/mdp/mdp_kms.c | |||
| @@ -34,7 +34,7 @@ static void update_irq(struct mdp_kms *mdp_kms) | |||
| 34 | struct mdp_irq *irq; | 34 | struct mdp_irq *irq; |
| 35 | uint32_t irqmask = mdp_kms->vblank_mask; | 35 | uint32_t irqmask = mdp_kms->vblank_mask; |
| 36 | 36 | ||
| 37 | BUG_ON(!spin_is_locked(&list_lock)); | 37 | assert_spin_locked(&list_lock); |
| 38 | 38 | ||
| 39 | list_for_each_entry(irq, &mdp_kms->irq_list, node) | 39 | list_for_each_entry(irq, &mdp_kms->irq_list, node) |
| 40 | irqmask |= irq->irqmask; | 40 | irqmask |= irq->irqmask; |
diff --git a/drivers/gpu/drm/msm/mdp/mdp_kms.h b/drivers/gpu/drm/msm/mdp/mdp_kms.h index b268ce95d394..5ae4039d68e4 100644 --- a/drivers/gpu/drm/msm/mdp/mdp_kms.h +++ b/drivers/gpu/drm/msm/mdp/mdp_kms.h | |||
| @@ -88,10 +88,32 @@ struct mdp_format { | |||
| 88 | uint8_t unpack[4]; | 88 | uint8_t unpack[4]; |
| 89 | bool alpha_enable, unpack_tight; | 89 | bool alpha_enable, unpack_tight; |
| 90 | uint8_t cpp, unpack_count; | 90 | uint8_t cpp, unpack_count; |
| 91 | enum mdp_sspp_fetch_type fetch_type; | ||
| 92 | enum mdp_chroma_samp_type chroma_sample; | ||
| 91 | }; | 93 | }; |
| 92 | #define to_mdp_format(x) container_of(x, struct mdp_format, base) | 94 | #define to_mdp_format(x) container_of(x, struct mdp_format, base) |
| 95 | #define MDP_FORMAT_IS_YUV(mdp_format) ((mdp_format)->chroma_sample > CHROMA_RGB) | ||
| 93 | 96 | ||
| 94 | uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats); | 97 | uint32_t mdp_get_formats(uint32_t *formats, uint32_t max_formats, bool rgb_only); |
| 95 | const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format); | 98 | const struct msm_format *mdp_get_format(struct msm_kms *kms, uint32_t format); |
| 96 | 99 | ||
| 100 | enum csc_type { | ||
| 101 | CSC_RGB2RGB = 0, | ||
| 102 | CSC_YUV2RGB, | ||
| 103 | CSC_RGB2YUV, | ||
| 104 | CSC_YUV2YUV, | ||
| 105 | CSC_MAX | ||
| 106 | }; | ||
| 107 | |||
| 108 | struct csc_cfg { | ||
| 109 | enum csc_type type; | ||
| 110 | uint32_t matrix[9]; | ||
| 111 | uint32_t pre_bias[3]; | ||
| 112 | uint32_t post_bias[3]; | ||
| 113 | uint32_t pre_clamp[6]; | ||
| 114 | uint32_t post_clamp[6]; | ||
| 115 | }; | ||
| 116 | |||
| 117 | struct csc_cfg *mdp_get_default_csc_cfg(enum csc_type); | ||
| 118 | |||
| 97 | #endif /* __MDP_KMS_H__ */ | 119 | #endif /* __MDP_KMS_H__ */ |
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c index 2c396540e279..871aa2108dc6 100644 --- a/drivers/gpu/drm/msm/msm_atomic.c +++ b/drivers/gpu/drm/msm/msm_atomic.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include "msm_gem.h" | 20 | #include "msm_gem.h" |
| 21 | 21 | ||
| 22 | struct msm_commit { | 22 | struct msm_commit { |
| 23 | struct drm_device *dev; | ||
| 23 | struct drm_atomic_state *state; | 24 | struct drm_atomic_state *state; |
| 24 | uint32_t fence; | 25 | uint32_t fence; |
| 25 | struct msm_fence_cb fence_cb; | 26 | struct msm_fence_cb fence_cb; |
| @@ -58,14 +59,16 @@ static void end_atomic(struct msm_drm_private *priv, uint32_t crtc_mask) | |||
| 58 | spin_unlock(&priv->pending_crtcs_event.lock); | 59 | spin_unlock(&priv->pending_crtcs_event.lock); |
| 59 | } | 60 | } |
| 60 | 61 | ||
| 61 | static struct msm_commit *new_commit(struct drm_atomic_state *state) | 62 | static struct msm_commit *commit_init(struct drm_atomic_state *state) |
| 62 | { | 63 | { |
| 63 | struct msm_commit *c = kzalloc(sizeof(*c), GFP_KERNEL); | 64 | struct msm_commit *c = kzalloc(sizeof(*c), GFP_KERNEL); |
| 64 | 65 | ||
| 65 | if (!c) | 66 | if (!c) |
| 66 | return NULL; | 67 | return NULL; |
| 67 | 68 | ||
| 69 | c->dev = state->dev; | ||
| 68 | c->state = state; | 70 | c->state = state; |
| 71 | |||
| 69 | /* TODO we might need a way to indicate to run the cb on a | 72 | /* TODO we might need a way to indicate to run the cb on a |
| 70 | * different wq so wait_for_vblanks() doesn't block retiring | 73 | * different wq so wait_for_vblanks() doesn't block retiring |
| 71 | * bo's.. | 74 | * bo's.. |
| @@ -75,6 +78,12 @@ static struct msm_commit *new_commit(struct drm_atomic_state *state) | |||
| 75 | return c; | 78 | return c; |
| 76 | } | 79 | } |
| 77 | 80 | ||
| 81 | static void commit_destroy(struct msm_commit *c) | ||
| 82 | { | ||
| 83 | end_atomic(c->dev->dev_private, c->crtc_mask); | ||
| 84 | kfree(c); | ||
| 85 | } | ||
| 86 | |||
| 78 | /* The (potentially) asynchronous part of the commit. At this point | 87 | /* The (potentially) asynchronous part of the commit. At this point |
| 79 | * nothing can fail short of armageddon. | 88 | * nothing can fail short of armageddon. |
| 80 | */ | 89 | */ |
| @@ -82,6 +91,10 @@ static void complete_commit(struct msm_commit *c) | |||
| 82 | { | 91 | { |
| 83 | struct drm_atomic_state *state = c->state; | 92 | struct drm_atomic_state *state = c->state; |
| 84 | struct drm_device *dev = state->dev; | 93 | struct drm_device *dev = state->dev; |
| 94 | struct msm_drm_private *priv = dev->dev_private; | ||
| 95 | struct msm_kms *kms = priv->kms; | ||
| 96 | |||
| 97 | kms->funcs->prepare_commit(kms, state); | ||
| 85 | 98 | ||
| 86 | drm_atomic_helper_commit_pre_planes(dev, state); | 99 | drm_atomic_helper_commit_pre_planes(dev, state); |
| 87 | 100 | ||
| @@ -106,11 +119,11 @@ static void complete_commit(struct msm_commit *c) | |||
| 106 | 119 | ||
| 107 | drm_atomic_helper_cleanup_planes(dev, state); | 120 | drm_atomic_helper_cleanup_planes(dev, state); |
| 108 | 121 | ||
| 109 | drm_atomic_state_free(state); | 122 | kms->funcs->complete_commit(kms, state); |
| 110 | 123 | ||
| 111 | end_atomic(dev->dev_private, c->crtc_mask); | 124 | drm_atomic_state_free(state); |
| 112 | 125 | ||
| 113 | kfree(c); | 126 | commit_destroy(c); |
| 114 | } | 127 | } |
| 115 | 128 | ||
| 116 | static void fence_cb(struct msm_fence_cb *cb) | 129 | static void fence_cb(struct msm_fence_cb *cb) |
| @@ -165,6 +178,7 @@ int msm_atomic_commit(struct drm_device *dev, | |||
| 165 | { | 178 | { |
| 166 | int nplanes = dev->mode_config.num_total_plane; | 179 | int nplanes = dev->mode_config.num_total_plane; |
| 167 | int ncrtcs = dev->mode_config.num_crtc; | 180 | int ncrtcs = dev->mode_config.num_crtc; |
| 181 | struct timespec timeout; | ||
| 168 | struct msm_commit *c; | 182 | struct msm_commit *c; |
| 169 | int i, ret; | 183 | int i, ret; |
| 170 | 184 | ||
| @@ -172,7 +186,7 @@ int msm_atomic_commit(struct drm_device *dev, | |||
| 172 | if (ret) | 186 | if (ret) |
| 173 | return ret; | 187 | return ret; |
| 174 | 188 | ||
| 175 | c = new_commit(state); | 189 | c = commit_init(state); |
| 176 | if (!c) | 190 | if (!c) |
| 177 | return -ENOMEM; | 191 | return -ENOMEM; |
| 178 | 192 | ||
| @@ -237,10 +251,12 @@ int msm_atomic_commit(struct drm_device *dev, | |||
| 237 | return 0; | 251 | return 0; |
| 238 | } | 252 | } |
| 239 | 253 | ||
| 240 | ret = msm_wait_fence_interruptable(dev, c->fence, NULL); | 254 | jiffies_to_timespec(jiffies + msecs_to_jiffies(1000), &timeout); |
| 255 | |||
| 256 | ret = msm_wait_fence_interruptable(dev, c->fence, &timeout); | ||
| 241 | if (ret) { | 257 | if (ret) { |
| 242 | WARN_ON(ret); // TODO unswap state back? or?? | 258 | WARN_ON(ret); // TODO unswap state back? or?? |
| 243 | kfree(c); | 259 | commit_destroy(c); |
| 244 | return ret; | 260 | return ret; |
| 245 | } | 261 | } |
| 246 | 262 | ||
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index f1ebedde6346..a4269119f9ea 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c | |||
| @@ -54,6 +54,12 @@ module_param(reglog, bool, 0600); | |||
| 54 | #define reglog 0 | 54 | #define reglog 0 |
| 55 | #endif | 55 | #endif |
| 56 | 56 | ||
| 57 | #ifdef CONFIG_DRM_MSM_FBDEV | ||
| 58 | static bool fbdev = true; | ||
| 59 | MODULE_PARM_DESC(fbdev, "Enable fbdev compat layer"); | ||
| 60 | module_param(fbdev, bool, 0600); | ||
| 61 | #endif | ||
| 62 | |||
| 57 | static char *vram = "16m"; | 63 | static char *vram = "16m"; |
| 58 | MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU"); | 64 | MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU"); |
| 59 | module_param(vram, charp, 0); | 65 | module_param(vram, charp, 0); |
| @@ -300,7 +306,8 @@ static int msm_load(struct drm_device *dev, unsigned long flags) | |||
| 300 | drm_mode_config_reset(dev); | 306 | drm_mode_config_reset(dev); |
| 301 | 307 | ||
| 302 | #ifdef CONFIG_DRM_MSM_FBDEV | 308 | #ifdef CONFIG_DRM_MSM_FBDEV |
| 303 | priv->fbdev = msm_fbdev_init(dev); | 309 | if (fbdev) |
| 310 | priv->fbdev = msm_fbdev_init(dev); | ||
| 304 | #endif | 311 | #endif |
| 305 | 312 | ||
| 306 | ret = msm_debugfs_late_init(dev); | 313 | ret = msm_debugfs_late_init(dev); |
| @@ -1023,6 +1030,7 @@ static struct platform_driver msm_platform_driver = { | |||
| 1023 | static int __init msm_drm_register(void) | 1030 | static int __init msm_drm_register(void) |
| 1024 | { | 1031 | { |
| 1025 | DBG("init"); | 1032 | DBG("init"); |
| 1033 | msm_edp_register(); | ||
| 1026 | hdmi_register(); | 1034 | hdmi_register(); |
| 1027 | adreno_register(); | 1035 | adreno_register(); |
| 1028 | return platform_driver_register(&msm_platform_driver); | 1036 | return platform_driver_register(&msm_platform_driver); |
| @@ -1034,6 +1042,7 @@ static void __exit msm_drm_unregister(void) | |||
| 1034 | platform_driver_unregister(&msm_platform_driver); | 1042 | platform_driver_unregister(&msm_platform_driver); |
| 1035 | hdmi_unregister(); | 1043 | hdmi_unregister(); |
| 1036 | adreno_unregister(); | 1044 | adreno_unregister(); |
| 1045 | msm_edp_unregister(); | ||
| 1037 | } | 1046 | } |
| 1038 | 1047 | ||
| 1039 | module_init(msm_drm_register); | 1048 | module_init(msm_drm_register); |
diff --git a/drivers/gpu/drm/msm/msm_drv.h b/drivers/gpu/drm/msm/msm_drv.h index 22e5391a7ce8..9e8d441b61c3 100644 --- a/drivers/gpu/drm/msm/msm_drv.h +++ b/drivers/gpu/drm/msm/msm_drv.h | |||
| @@ -76,6 +76,12 @@ struct msm_drm_private { | |||
| 76 | */ | 76 | */ |
| 77 | struct hdmi *hdmi; | 77 | struct hdmi *hdmi; |
| 78 | 78 | ||
| 79 | /* eDP is for mdp5 only, but kms has not been created | ||
| 80 | * when edp_bind() and edp_init() are called. Here is the only | ||
| 81 | * place to keep the edp instance. | ||
| 82 | */ | ||
| 83 | struct msm_edp *edp; | ||
| 84 | |||
| 79 | /* when we have more than one 'msm_gpu' these need to be an array: */ | 85 | /* when we have more than one 'msm_gpu' these need to be an array: */ |
| 80 | struct msm_gpu *gpu; | 86 | struct msm_gpu *gpu; |
| 81 | struct msm_file_private *lastctx; | 87 | struct msm_file_private *lastctx; |
| @@ -224,6 +230,12 @@ int hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev, | |||
| 224 | void __init hdmi_register(void); | 230 | void __init hdmi_register(void); |
| 225 | void __exit hdmi_unregister(void); | 231 | void __exit hdmi_unregister(void); |
| 226 | 232 | ||
| 233 | struct msm_edp; | ||
| 234 | void __init msm_edp_register(void); | ||
| 235 | void __exit msm_edp_unregister(void); | ||
| 236 | int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev, | ||
| 237 | struct drm_encoder *encoder); | ||
| 238 | |||
| 227 | #ifdef CONFIG_DEBUG_FS | 239 | #ifdef CONFIG_DEBUG_FS |
| 228 | void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m); | 240 | void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m); |
| 229 | void msm_gem_describe_objects(struct list_head *list, struct seq_file *m); | 241 | void msm_gem_describe_objects(struct list_head *list, struct seq_file *m); |
diff --git a/drivers/gpu/drm/msm/msm_fb.c b/drivers/gpu/drm/msm/msm_fb.c index 84dec161d836..6b573e612f27 100644 --- a/drivers/gpu/drm/msm/msm_fb.c +++ b/drivers/gpu/drm/msm/msm_fb.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | struct msm_framebuffer { | 24 | struct msm_framebuffer { |
| 25 | struct drm_framebuffer base; | 25 | struct drm_framebuffer base; |
| 26 | const struct msm_format *format; | 26 | const struct msm_format *format; |
| 27 | struct drm_gem_object *planes[3]; | 27 | struct drm_gem_object *planes[MAX_PLANE]; |
| 28 | }; | 28 | }; |
| 29 | #define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base) | 29 | #define to_msm_framebuffer(x) container_of(x, struct msm_framebuffer, base) |
| 30 | 30 | ||
| @@ -122,7 +122,7 @@ uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb, int id, int plane) | |||
| 122 | struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); | 122 | struct msm_framebuffer *msm_fb = to_msm_framebuffer(fb); |
| 123 | if (!msm_fb->planes[plane]) | 123 | if (!msm_fb->planes[plane]) |
| 124 | return 0; | 124 | return 0; |
| 125 | return msm_gem_iova(msm_fb->planes[plane], id); | 125 | return msm_gem_iova(msm_fb->planes[plane], id) + fb->offsets[plane]; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane) | 128 | struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane) |
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c index 115b509a4a00..df60f65728ff 100644 --- a/drivers/gpu/drm/msm/msm_fbdev.c +++ b/drivers/gpu/drm/msm/msm_fbdev.c | |||
| @@ -245,9 +245,6 @@ struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev) | |||
| 245 | if (ret) | 245 | if (ret) |
| 246 | goto fini; | 246 | goto fini; |
| 247 | 247 | ||
| 248 | /* disable all the possible outputs/crtcs before entering KMS mode */ | ||
| 249 | drm_helper_disable_unused_functions(dev); | ||
| 250 | |||
| 251 | ret = drm_fb_helper_initial_config(helper, 32); | 248 | ret = drm_fb_helper_initial_config(helper, 32); |
| 252 | if (ret) | 249 | if (ret) |
| 253 | goto fini; | 250 | goto fini; |
diff --git a/drivers/gpu/drm/msm/msm_kms.h b/drivers/gpu/drm/msm/msm_kms.h index 06437745bc2c..3a78cb48662b 100644 --- a/drivers/gpu/drm/msm/msm_kms.h +++ b/drivers/gpu/drm/msm/msm_kms.h | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | 23 | ||
| 24 | #include "msm_drv.h" | 24 | #include "msm_drv.h" |
| 25 | 25 | ||
| 26 | #define MAX_PLANE 4 | ||
| 27 | |||
| 26 | /* As there are different display controller blocks depending on the | 28 | /* As there are different display controller blocks depending on the |
| 27 | * snapdragon version, the kms support is split out and the appropriate | 29 | * snapdragon version, the kms support is split out and the appropriate |
| 28 | * implementation is loaded at runtime. The kms module is responsible | 30 | * implementation is loaded at runtime. The kms module is responsible |
| @@ -38,6 +40,9 @@ struct msm_kms_funcs { | |||
| 38 | irqreturn_t (*irq)(struct msm_kms *kms); | 40 | irqreturn_t (*irq)(struct msm_kms *kms); |
| 39 | int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); | 41 | int (*enable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); |
| 40 | void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); | 42 | void (*disable_vblank)(struct msm_kms *kms, struct drm_crtc *crtc); |
| 43 | /* modeset, bracketing atomic_commit(): */ | ||
| 44 | void (*prepare_commit)(struct msm_kms *kms, struct drm_atomic_state *state); | ||
| 45 | void (*complete_commit)(struct msm_kms *kms, struct drm_atomic_state *state); | ||
| 41 | /* misc: */ | 46 | /* misc: */ |
| 42 | const struct msm_format *(*get_format)(struct msm_kms *kms, uint32_t format); | 47 | const struct msm_format *(*get_format)(struct msm_kms *kms, uint32_t format); |
| 43 | long (*round_pixclk)(struct msm_kms *kms, unsigned long rate, | 48 | long (*round_pixclk)(struct msm_kms *kms, unsigned long rate, |
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 11f8c84f98ce..7e25030a6aa2 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h | |||
| @@ -586,6 +586,7 @@ struct drm_dp_link { | |||
| 586 | 586 | ||
| 587 | int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); | 587 | int drm_dp_link_probe(struct drm_dp_aux *aux, struct drm_dp_link *link); |
| 588 | int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); | 588 | int drm_dp_link_power_up(struct drm_dp_aux *aux, struct drm_dp_link *link); |
| 589 | int drm_dp_link_power_down(struct drm_dp_aux *aux, struct drm_dp_link *link); | ||
| 589 | int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link); | 590 | int drm_dp_link_configure(struct drm_dp_aux *aux, struct drm_dp_link *link); |
| 590 | 591 | ||
| 591 | int drm_dp_aux_register(struct drm_dp_aux *aux); | 592 | int drm_dp_aux_register(struct drm_dp_aux *aux); |
