aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2017-03-13 07:23:59 -0400
committerJani Nikula <jani.nikula@intel.com>2017-03-21 04:15:39 -0400
commit3ad33ae2bc800496e979b9f7920a57835740083d (patch)
treea7979c730fb76efef23e5df960c451b818becf1b
parent9aa1eca095579b8a8ea84d9bbd1fbdeff49cebd4 (diff)
drm: Add SCDC helpers
SCDC is a mechanism defined in the HDMI 2.0 specification that allows the source and sink devices to communicate. This commit introduces helpers to access the SCDC and provides the symbolic names for the various registers defined in the specification. V2: Rebase. V3: Added R-B from Jose. V4: Rebase V5: Addressed review comments from Ville - Handle the I2c return values in a better way (dp_dual_mode) - Make the macros for SCDC Major/Minor more readable, by adding a 'GET' in the macro names V6: Rebase V7: Rebase V8: Rebase V9: Rebase V10: Rebase Signed-off-by: Thierry Reding <treding@nvidia.com> Signed-off-by: Shashank Sharma <shashank.sharma@intel.com> Reviewed-by: Jose Abreu <joabreu@synopsys.com> Signed-off-by: Jani Nikula <jani.nikula@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/1489404244-16608-2-git-send-email-shashank.sharma@intel.com
-rw-r--r--Documentation/gpu/drm-kms-helpers.rst12
-rw-r--r--drivers/gpu/drm/Makefile3
-rw-r--r--drivers/gpu/drm/drm_scdc_helper.c123
-rw-r--r--include/drm/drm_scdc_helper.h132
4 files changed, 269 insertions, 1 deletions
diff --git a/Documentation/gpu/drm-kms-helpers.rst b/Documentation/gpu/drm-kms-helpers.rst
index ac53c0b893f6..c075aadd7078 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -223,6 +223,18 @@ EDID Helper Functions Reference
223.. kernel-doc:: drivers/gpu/drm/drm_edid.c 223.. kernel-doc:: drivers/gpu/drm/drm_edid.c
224 :export: 224 :export:
225 225
226SCDC Helper Functions Reference
227===============================
228
229.. kernel-doc:: drivers/gpu/drm/drm_scdc_helper.c
230 :doc: scdc helpers
231
232.. kernel-doc:: include/drm/drm_scdc_helper.h
233 :internal:
234
235.. kernel-doc:: drivers/gpu/drm/drm_scdc_helper.c
236 :export:
237
226Rectangle Utilities Reference 238Rectangle Utilities Reference
227============================= 239=============================
228 240
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 59aae43005ee..59f0f9b696eb 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -31,7 +31,8 @@ drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
31drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \ 31drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
32 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \ 32 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
33 drm_kms_helper_common.o drm_dp_dual_mode_helper.o \ 33 drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
34 drm_simple_kms_helper.o drm_modeset_helper.o 34 drm_simple_kms_helper.o drm_modeset_helper.o \
35 drm_scdc_helper.o
35 36
36drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o 37drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
37drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o 38drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
diff --git a/drivers/gpu/drm/drm_scdc_helper.c b/drivers/gpu/drm/drm_scdc_helper.c
new file mode 100644
index 000000000000..c2dd33f89c17
--- /dev/null
+++ b/drivers/gpu/drm/drm_scdc_helper.c
@@ -0,0 +1,123 @@
1/*
2 * Copyright (c) 2015 NVIDIA Corporation. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#include <linux/slab.h>
25
26#include <drm/drm_scdc_helper.h>
27
28/**
29 * DOC: scdc helpers
30 *
31 * Status and Control Data Channel (SCDC) is a mechanism introduced by the
32 * HDMI 2.0 specification. It is a point-to-point protocol that allows the
33 * HDMI source and HDMI sink to exchange data. The same I2C interface that
34 * is used to access EDID serves as the transport mechanism for SCDC.
35 */
36
37#define SCDC_I2C_SLAVE_ADDRESS 0x54
38
39/**
40 * drm_scdc_read - read a block of data from SCDC
41 * @adapter: I2C controller
42 * @offset: start offset of block to read
43 * @buffer: return location for the block to read
44 * @size: size of the block to read
45 *
46 * Reads a block of data from SCDC, starting at a given offset.
47 *
48 * Returns:
49 * 0 on success, negative error code on failure.
50 */
51ssize_t drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer,
52 size_t size)
53{
54 int ret;
55 struct i2c_msg msgs[2] = {
56 {
57 .addr = SCDC_I2C_SLAVE_ADDRESS,
58 .flags = 0,
59 .len = 1,
60 .buf = &offset,
61 }, {
62 .addr = SCDC_I2C_SLAVE_ADDRESS,
63 .flags = I2C_M_RD,
64 .len = size,
65 .buf = buffer,
66 }
67 };
68
69 ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
70 if (ret < 0)
71 return ret;
72 if (ret != ARRAY_SIZE(msgs))
73 return -EPROTO;
74
75 return 0;
76}
77EXPORT_SYMBOL(drm_scdc_read);
78
79/**
80 * drm_scdc_write - write a block of data to SCDC
81 * @adapter: I2C controller
82 * @offset: start offset of block to write
83 * @buffer: block of data to write
84 * @size: size of the block to write
85 *
86 * Writes a block of data to SCDC, starting at a given offset.
87 *
88 * Returns:
89 * 0 on success, negative error code on failure.
90 */
91ssize_t drm_scdc_write(struct i2c_adapter *adapter, u8 offset,
92 const void *buffer, size_t size)
93{
94 struct i2c_msg msg = {
95 .addr = SCDC_I2C_SLAVE_ADDRESS,
96 .flags = 0,
97 .len = 1 + size,
98 .buf = NULL,
99 };
100 void *data;
101 int err;
102
103 data = kmalloc(1 + size, GFP_TEMPORARY);
104 if (!data)
105 return -ENOMEM;
106
107 msg.buf = data;
108
109 memcpy(data, &offset, sizeof(offset));
110 memcpy(data + 1, buffer, size);
111
112 err = i2c_transfer(adapter, &msg, 1);
113
114 kfree(data);
115
116 if (err < 0)
117 return err;
118 if (err != 1)
119 return -EPROTO;
120
121 return 0;
122}
123EXPORT_SYMBOL(drm_scdc_write);
diff --git a/include/drm/drm_scdc_helper.h b/include/drm/drm_scdc_helper.h
new file mode 100644
index 000000000000..9c52deb13df4
--- /dev/null
+++ b/include/drm/drm_scdc_helper.h
@@ -0,0 +1,132 @@
1/*
2 * Copyright (c) 2015 NVIDIA Corporation. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24#ifndef DRM_SCDC_HELPER_H
25#define DRM_SCDC_HELPER_H
26
27#include <linux/i2c.h>
28#include <linux/types.h>
29
30#define SCDC_SINK_VERSION 0x01
31
32#define SCDC_SOURCE_VERSION 0x02
33
34#define SCDC_UPDATE_0 0x10
35#define SCDC_READ_REQUEST_TEST (1 << 2)
36#define SCDC_CED_UPDATE (1 << 1)
37#define SCDC_STATUS_UPDATE (1 << 0)
38
39#define SCDC_UPDATE_1 0x11
40
41#define SCDC_TMDS_CONFIG 0x20
42#define SCDC_TMDS_BIT_CLOCK_RATIO_BY_40 (1 << 1)
43#define SCDC_TMDS_BIT_CLOCK_RATIO_BY_10 (0 << 1)
44#define SCDC_SCRAMBLING_ENABLE (1 << 0)
45
46#define SCDC_SCRAMBLER_STATUS 0x21
47#define SCDC_SCRAMBLING_STATUS (1 << 0)
48
49#define SCDC_CONFIG_0 0x30
50#define SCDC_READ_REQUEST_ENABLE (1 << 0)
51
52#define SCDC_STATUS_FLAGS_0 0x40
53#define SCDC_CH2_LOCK (1 < 3)
54#define SCDC_CH1_LOCK (1 < 2)
55#define SCDC_CH0_LOCK (1 < 1)
56#define SCDC_CH_LOCK_MASK (SCDC_CH2_LOCK | SCDC_CH1_LOCK | SCDC_CH0_LOCK)
57#define SCDC_CLOCK_DETECT (1 << 0)
58
59#define SCDC_STATUS_FLAGS_1 0x41
60
61#define SCDC_ERR_DET_0_L 0x50
62#define SCDC_ERR_DET_0_H 0x51
63#define SCDC_ERR_DET_1_L 0x52
64#define SCDC_ERR_DET_1_H 0x53
65#define SCDC_ERR_DET_2_L 0x54
66#define SCDC_ERR_DET_2_H 0x55
67#define SCDC_CHANNEL_VALID (1 << 7)
68
69#define SCDC_ERR_DET_CHECKSUM 0x56
70
71#define SCDC_TEST_CONFIG_0 0xc0
72#define SCDC_TEST_READ_REQUEST (1 << 7)
73#define SCDC_TEST_READ_REQUEST_DELAY(x) ((x) & 0x7f)
74
75#define SCDC_MANUFACTURER_IEEE_OUI 0xd0
76#define SCDC_MANUFACTURER_IEEE_OUI_SIZE 3
77
78#define SCDC_DEVICE_ID 0xd3
79#define SCDC_DEVICE_ID_SIZE 8
80
81#define SCDC_DEVICE_HARDWARE_REVISION 0xdb
82#define SCDC_GET_DEVICE_HARDWARE_REVISION_MAJOR(x) (((x) >> 4) & 0xf)
83#define SCDC_GET_DEVICE_HARDWARE_REVISION_MINOR(x) (((x) >> 0) & 0xf)
84
85#define SCDC_DEVICE_SOFTWARE_MAJOR_REVISION 0xdc
86#define SCDC_DEVICE_SOFTWARE_MINOR_REVISION 0xdd
87
88#define SCDC_MANUFACTURER_SPECIFIC 0xde
89#define SCDC_MANUFACTURER_SPECIFIC_SIZE 34
90
91ssize_t drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer,
92 size_t size);
93ssize_t drm_scdc_write(struct i2c_adapter *adapter, u8 offset,
94 const void *buffer, size_t size);
95
96/**
97 * drm_scdc_readb - read a single byte from SCDC
98 * @adapter: I2C adapter
99 * @offset: offset of register to read
100 * @value: return location for the register value
101 *
102 * Reads a single byte from SCDC. This is a convenience wrapper around the
103 * drm_scdc_read() function.
104 *
105 * Returns:
106 * 0 on success or a negative error code on failure.
107 */
108static inline int drm_scdc_readb(struct i2c_adapter *adapter, u8 offset,
109 u8 *value)
110{
111 return drm_scdc_read(adapter, offset, value, sizeof(*value));
112}
113
114/**
115 * drm_scdc_writeb - write a single byte to SCDC
116 * @adapter: I2C adapter
117 * @offset: offset of register to read
118 * @value: return location for the register value
119 *
120 * Writes a single byte to SCDC. This is a convenience wrapper around the
121 * drm_scdc_write() function.
122 *
123 * Returns:
124 * 0 on success or a negative error code on failure.
125 */
126static inline int drm_scdc_writeb(struct i2c_adapter *adapter, u8 offset,
127 u8 value)
128{
129 return drm_scdc_write(adapter, offset, &value, sizeof(value));
130}
131
132#endif