11bb76ff1Sjsg /*
21bb76ff1Sjsg * Copyright (c) 2015 NVIDIA Corporation. All rights reserved.
31bb76ff1Sjsg *
41bb76ff1Sjsg * Permission is hereby granted, free of charge, to any person obtaining a
51bb76ff1Sjsg * copy of this software and associated documentation files (the "Software"),
61bb76ff1Sjsg * to deal in the Software without restriction, including without limitation
71bb76ff1Sjsg * the rights to use, copy, modify, merge, publish, distribute, sub license,
81bb76ff1Sjsg * and/or sell copies of the Software, and to permit persons to whom the
91bb76ff1Sjsg * Software is furnished to do so, subject to the following conditions:
101bb76ff1Sjsg *
111bb76ff1Sjsg * The above copyright notice and this permission notice (including the
121bb76ff1Sjsg * next paragraph) shall be included in all copies or substantial portions
131bb76ff1Sjsg * of the Software.
141bb76ff1Sjsg *
151bb76ff1Sjsg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161bb76ff1Sjsg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171bb76ff1Sjsg * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
181bb76ff1Sjsg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191bb76ff1Sjsg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201bb76ff1Sjsg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211bb76ff1Sjsg * DEALINGS IN THE SOFTWARE.
221bb76ff1Sjsg */
231bb76ff1Sjsg
241bb76ff1Sjsg #include <linux/i2c.h>
251bb76ff1Sjsg #include <linux/slab.h>
261bb76ff1Sjsg #include <linux/delay.h>
271bb76ff1Sjsg
281bb76ff1Sjsg #include <drm/display/drm_scdc_helper.h>
29*f005ef32Sjsg #include <drm/drm_connector.h>
30*f005ef32Sjsg #include <drm/drm_device.h>
311bb76ff1Sjsg #include <drm/drm_print.h>
321bb76ff1Sjsg
331bb76ff1Sjsg /**
341bb76ff1Sjsg * DOC: scdc helpers
351bb76ff1Sjsg *
361bb76ff1Sjsg * Status and Control Data Channel (SCDC) is a mechanism introduced by the
371bb76ff1Sjsg * HDMI 2.0 specification. It is a point-to-point protocol that allows the
381bb76ff1Sjsg * HDMI source and HDMI sink to exchange data. The same I2C interface that
391bb76ff1Sjsg * is used to access EDID serves as the transport mechanism for SCDC.
401bb76ff1Sjsg *
411bb76ff1Sjsg * Note: The SCDC status is going to be lost when the display is
421bb76ff1Sjsg * disconnected. This can happen physically when the user disconnects
431bb76ff1Sjsg * the cable, but also when a display is switched on (such as waking up
441bb76ff1Sjsg * a TV).
451bb76ff1Sjsg *
461bb76ff1Sjsg * This is further complicated by the fact that, upon a disconnection /
471bb76ff1Sjsg * reconnection, KMS won't change the mode on its own. This means that
481bb76ff1Sjsg * one can't just rely on setting the SCDC status on enable, but also
491bb76ff1Sjsg * has to track the connector status changes using interrupts and
501bb76ff1Sjsg * restore the SCDC status. The typical solution for this is to trigger an
511bb76ff1Sjsg * empty modeset in drm_connector_helper_funcs.detect_ctx(), like what vc4 does
521bb76ff1Sjsg * in vc4_hdmi_reset_link().
531bb76ff1Sjsg */
541bb76ff1Sjsg
551bb76ff1Sjsg #define SCDC_I2C_SLAVE_ADDRESS 0x54
561bb76ff1Sjsg
571bb76ff1Sjsg /**
581bb76ff1Sjsg * drm_scdc_read - read a block of data from SCDC
591bb76ff1Sjsg * @adapter: I2C controller
601bb76ff1Sjsg * @offset: start offset of block to read
611bb76ff1Sjsg * @buffer: return location for the block to read
621bb76ff1Sjsg * @size: size of the block to read
631bb76ff1Sjsg *
641bb76ff1Sjsg * Reads a block of data from SCDC, starting at a given offset.
651bb76ff1Sjsg *
661bb76ff1Sjsg * Returns:
671bb76ff1Sjsg * 0 on success, negative error code on failure.
681bb76ff1Sjsg */
drm_scdc_read(struct i2c_adapter * adapter,u8 offset,void * buffer,size_t size)691bb76ff1Sjsg ssize_t drm_scdc_read(struct i2c_adapter *adapter, u8 offset, void *buffer,
701bb76ff1Sjsg size_t size)
711bb76ff1Sjsg {
721bb76ff1Sjsg int ret;
731bb76ff1Sjsg struct i2c_msg msgs[2] = {
741bb76ff1Sjsg {
751bb76ff1Sjsg .addr = SCDC_I2C_SLAVE_ADDRESS,
761bb76ff1Sjsg .flags = 0,
771bb76ff1Sjsg .len = 1,
781bb76ff1Sjsg .buf = &offset,
791bb76ff1Sjsg }, {
801bb76ff1Sjsg .addr = SCDC_I2C_SLAVE_ADDRESS,
811bb76ff1Sjsg .flags = I2C_M_RD,
821bb76ff1Sjsg .len = size,
831bb76ff1Sjsg .buf = buffer,
841bb76ff1Sjsg }
851bb76ff1Sjsg };
861bb76ff1Sjsg
871bb76ff1Sjsg ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
881bb76ff1Sjsg if (ret < 0)
891bb76ff1Sjsg return ret;
901bb76ff1Sjsg if (ret != ARRAY_SIZE(msgs))
911bb76ff1Sjsg return -EPROTO;
921bb76ff1Sjsg
931bb76ff1Sjsg return 0;
941bb76ff1Sjsg }
951bb76ff1Sjsg EXPORT_SYMBOL(drm_scdc_read);
961bb76ff1Sjsg
971bb76ff1Sjsg /**
981bb76ff1Sjsg * drm_scdc_write - write a block of data to SCDC
991bb76ff1Sjsg * @adapter: I2C controller
1001bb76ff1Sjsg * @offset: start offset of block to write
1011bb76ff1Sjsg * @buffer: block of data to write
1021bb76ff1Sjsg * @size: size of the block to write
1031bb76ff1Sjsg *
1041bb76ff1Sjsg * Writes a block of data to SCDC, starting at a given offset.
1051bb76ff1Sjsg *
1061bb76ff1Sjsg * Returns:
1071bb76ff1Sjsg * 0 on success, negative error code on failure.
1081bb76ff1Sjsg */
drm_scdc_write(struct i2c_adapter * adapter,u8 offset,const void * buffer,size_t size)1091bb76ff1Sjsg ssize_t drm_scdc_write(struct i2c_adapter *adapter, u8 offset,
1101bb76ff1Sjsg const void *buffer, size_t size)
1111bb76ff1Sjsg {
1121bb76ff1Sjsg struct i2c_msg msg = {
1131bb76ff1Sjsg .addr = SCDC_I2C_SLAVE_ADDRESS,
1141bb76ff1Sjsg .flags = 0,
1151bb76ff1Sjsg .len = 1 + size,
1161bb76ff1Sjsg .buf = NULL,
1171bb76ff1Sjsg };
1181bb76ff1Sjsg void *data;
1191bb76ff1Sjsg int err;
1201bb76ff1Sjsg
1211bb76ff1Sjsg data = kmalloc(1 + size, GFP_KERNEL);
1221bb76ff1Sjsg if (!data)
1231bb76ff1Sjsg return -ENOMEM;
1241bb76ff1Sjsg
1251bb76ff1Sjsg msg.buf = data;
1261bb76ff1Sjsg
1271bb76ff1Sjsg memcpy(data, &offset, sizeof(offset));
1281bb76ff1Sjsg memcpy(data + 1, buffer, size);
1291bb76ff1Sjsg
1301bb76ff1Sjsg err = i2c_transfer(adapter, &msg, 1);
1311bb76ff1Sjsg
1321bb76ff1Sjsg kfree(data);
1331bb76ff1Sjsg
1341bb76ff1Sjsg if (err < 0)
1351bb76ff1Sjsg return err;
1361bb76ff1Sjsg if (err != 1)
1371bb76ff1Sjsg return -EPROTO;
1381bb76ff1Sjsg
1391bb76ff1Sjsg return 0;
1401bb76ff1Sjsg }
1411bb76ff1Sjsg EXPORT_SYMBOL(drm_scdc_write);
1421bb76ff1Sjsg
1431bb76ff1Sjsg /**
1441bb76ff1Sjsg * drm_scdc_get_scrambling_status - what is status of scrambling?
145*f005ef32Sjsg * @connector: connector
1461bb76ff1Sjsg *
1471bb76ff1Sjsg * Reads the scrambler status over SCDC, and checks the
1481bb76ff1Sjsg * scrambling status.
1491bb76ff1Sjsg *
1501bb76ff1Sjsg * Returns:
1511bb76ff1Sjsg * True if the scrambling is enabled, false otherwise.
1521bb76ff1Sjsg */
drm_scdc_get_scrambling_status(struct drm_connector * connector)153*f005ef32Sjsg bool drm_scdc_get_scrambling_status(struct drm_connector *connector)
1541bb76ff1Sjsg {
1551bb76ff1Sjsg u8 status;
1561bb76ff1Sjsg int ret;
1571bb76ff1Sjsg
158*f005ef32Sjsg ret = drm_scdc_readb(connector->ddc, SCDC_SCRAMBLER_STATUS, &status);
1591bb76ff1Sjsg if (ret < 0) {
160*f005ef32Sjsg drm_dbg_kms(connector->dev,
161*f005ef32Sjsg "[CONNECTOR:%d:%s] Failed to read scrambling status: %d\n",
162*f005ef32Sjsg connector->base.id, connector->name, ret);
1631bb76ff1Sjsg return false;
1641bb76ff1Sjsg }
1651bb76ff1Sjsg
1661bb76ff1Sjsg return status & SCDC_SCRAMBLING_STATUS;
1671bb76ff1Sjsg }
1681bb76ff1Sjsg EXPORT_SYMBOL(drm_scdc_get_scrambling_status);
1691bb76ff1Sjsg
1701bb76ff1Sjsg /**
1711bb76ff1Sjsg * drm_scdc_set_scrambling - enable scrambling
172*f005ef32Sjsg * @connector: connector
1731bb76ff1Sjsg * @enable: bool to indicate if scrambling is to be enabled/disabled
1741bb76ff1Sjsg *
1751bb76ff1Sjsg * Writes the TMDS config register over SCDC channel, and:
1761bb76ff1Sjsg * enables scrambling when enable = 1
1771bb76ff1Sjsg * disables scrambling when enable = 0
1781bb76ff1Sjsg *
1791bb76ff1Sjsg * Returns:
1801bb76ff1Sjsg * True if scrambling is set/reset successfully, false otherwise.
1811bb76ff1Sjsg */
drm_scdc_set_scrambling(struct drm_connector * connector,bool enable)182*f005ef32Sjsg bool drm_scdc_set_scrambling(struct drm_connector *connector,
183*f005ef32Sjsg bool enable)
1841bb76ff1Sjsg {
1851bb76ff1Sjsg u8 config;
1861bb76ff1Sjsg int ret;
1871bb76ff1Sjsg
188*f005ef32Sjsg ret = drm_scdc_readb(connector->ddc, SCDC_TMDS_CONFIG, &config);
1891bb76ff1Sjsg if (ret < 0) {
190*f005ef32Sjsg drm_dbg_kms(connector->dev,
191*f005ef32Sjsg "[CONNECTOR:%d:%s] Failed to read TMDS config: %d\n",
192*f005ef32Sjsg connector->base.id, connector->name, ret);
1931bb76ff1Sjsg return false;
1941bb76ff1Sjsg }
1951bb76ff1Sjsg
1961bb76ff1Sjsg if (enable)
1971bb76ff1Sjsg config |= SCDC_SCRAMBLING_ENABLE;
1981bb76ff1Sjsg else
1991bb76ff1Sjsg config &= ~SCDC_SCRAMBLING_ENABLE;
2001bb76ff1Sjsg
201*f005ef32Sjsg ret = drm_scdc_writeb(connector->ddc, SCDC_TMDS_CONFIG, config);
2021bb76ff1Sjsg if (ret < 0) {
203*f005ef32Sjsg drm_dbg_kms(connector->dev,
204*f005ef32Sjsg "[CONNECTOR:%d:%s] Failed to enable scrambling: %d\n",
205*f005ef32Sjsg connector->base.id, connector->name, ret);
2061bb76ff1Sjsg return false;
2071bb76ff1Sjsg }
2081bb76ff1Sjsg
2091bb76ff1Sjsg return true;
2101bb76ff1Sjsg }
2111bb76ff1Sjsg EXPORT_SYMBOL(drm_scdc_set_scrambling);
2121bb76ff1Sjsg
2131bb76ff1Sjsg /**
2141bb76ff1Sjsg * drm_scdc_set_high_tmds_clock_ratio - set TMDS clock ratio
215*f005ef32Sjsg * @connector: connector
2161bb76ff1Sjsg * @set: ret or reset the high clock ratio
2171bb76ff1Sjsg *
2181bb76ff1Sjsg *
2191bb76ff1Sjsg * TMDS clock ratio calculations go like this:
2201bb76ff1Sjsg * TMDS character = 10 bit TMDS encoded value
2211bb76ff1Sjsg *
2221bb76ff1Sjsg * TMDS character rate = The rate at which TMDS characters are
2231bb76ff1Sjsg * transmitted (Mcsc)
2241bb76ff1Sjsg *
2251bb76ff1Sjsg * TMDS bit rate = 10x TMDS character rate
2261bb76ff1Sjsg *
2271bb76ff1Sjsg * As per the spec:
2281bb76ff1Sjsg * TMDS clock rate for pixel clock < 340 MHz = 1x the character
2291bb76ff1Sjsg * rate = 1/10 pixel clock rate
2301bb76ff1Sjsg *
2311bb76ff1Sjsg * TMDS clock rate for pixel clock > 340 MHz = 0.25x the character
2321bb76ff1Sjsg * rate = 1/40 pixel clock rate
2331bb76ff1Sjsg *
2341bb76ff1Sjsg * Writes to the TMDS config register over SCDC channel, and:
2351bb76ff1Sjsg * sets TMDS clock ratio to 1/40 when set = 1
2361bb76ff1Sjsg *
2371bb76ff1Sjsg * sets TMDS clock ratio to 1/10 when set = 0
2381bb76ff1Sjsg *
2391bb76ff1Sjsg * Returns:
2401bb76ff1Sjsg * True if write is successful, false otherwise.
2411bb76ff1Sjsg */
drm_scdc_set_high_tmds_clock_ratio(struct drm_connector * connector,bool set)242*f005ef32Sjsg bool drm_scdc_set_high_tmds_clock_ratio(struct drm_connector *connector,
243*f005ef32Sjsg bool set)
2441bb76ff1Sjsg {
2451bb76ff1Sjsg u8 config;
2461bb76ff1Sjsg int ret;
2471bb76ff1Sjsg
248*f005ef32Sjsg ret = drm_scdc_readb(connector->ddc, SCDC_TMDS_CONFIG, &config);
2491bb76ff1Sjsg if (ret < 0) {
250*f005ef32Sjsg drm_dbg_kms(connector->dev,
251*f005ef32Sjsg "[CONNECTOR:%d:%s] Failed to read TMDS config: %d\n",
252*f005ef32Sjsg connector->base.id, connector->name, ret);
2531bb76ff1Sjsg return false;
2541bb76ff1Sjsg }
2551bb76ff1Sjsg
2561bb76ff1Sjsg if (set)
2571bb76ff1Sjsg config |= SCDC_TMDS_BIT_CLOCK_RATIO_BY_40;
2581bb76ff1Sjsg else
2591bb76ff1Sjsg config &= ~SCDC_TMDS_BIT_CLOCK_RATIO_BY_40;
2601bb76ff1Sjsg
261*f005ef32Sjsg ret = drm_scdc_writeb(connector->ddc, SCDC_TMDS_CONFIG, config);
2621bb76ff1Sjsg if (ret < 0) {
263*f005ef32Sjsg drm_dbg_kms(connector->dev,
264*f005ef32Sjsg "[CONNECTOR:%d:%s] Failed to set TMDS clock ratio: %d\n",
265*f005ef32Sjsg connector->base.id, connector->name, ret);
2661bb76ff1Sjsg return false;
2671bb76ff1Sjsg }
2681bb76ff1Sjsg
2691bb76ff1Sjsg /*
2701bb76ff1Sjsg * The spec says that a source should wait minimum 1ms and maximum
2711bb76ff1Sjsg * 100ms after writing the TMDS config for clock ratio. Lets allow a
2721bb76ff1Sjsg * wait of up to 2ms here.
2731bb76ff1Sjsg */
2741bb76ff1Sjsg usleep_range(1000, 2000);
2751bb76ff1Sjsg return true;
2761bb76ff1Sjsg }
2771bb76ff1Sjsg EXPORT_SYMBOL(drm_scdc_set_high_tmds_clock_ratio);
278