hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
kernel/drivers/gpu/drm/bridge/sii902x.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) 2018 Renesas Electronics
34 *
....@@ -8,18 +9,7 @@
89 * Boris Brezillon <boris.brezillon@free-electrons.com>
910 * Wu, Songjun <Songjun.Wu@atmel.com>
1011 *
11
- *
1212 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
13
- *
14
- * This program is free software; you can redistribute it and/or modify
15
- * it under the terms of the GNU General Public License as published by
16
- * the Free Software Foundation; either version 2 of the License, or
17
- * (at your option) any later version.
18
- *
19
- * This program is distributed in the hope that it will be useful,
20
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
- * GNU General Public License for more details.
2313 */
2414
2515 #include <linux/gpio/consumer.h>
....@@ -27,13 +17,16 @@
2717 #include <linux/i2c.h>
2818 #include <linux/module.h>
2919 #include <linux/regmap.h>
20
+#include <linux/regulator/consumer.h>
3021 #include <linux/clk.h>
3122
32
-#include <drm/drmP.h>
3323 #include <drm/drm_atomic_helper.h>
34
-#include <drm/drm_crtc_helper.h>
24
+#include <drm/drm_bridge.h>
25
+#include <drm/drm_drv.h>
3526 #include <drm/drm_edid.h>
3627 #include <drm/drm_modes.h>
28
+#include <drm/drm_print.h>
29
+#include <drm/drm_probe_helper.h>
3730
3831 #include <sound/hdmi-codec.h>
3932 #include <video/videomode.h>
....@@ -185,6 +178,7 @@
185178 struct gpio_desc *reset_gpio;
186179 struct gpio_desc *enable_gpio;
187180 struct i2c_mux_core *i2cmux;
181
+ struct regulator_bulk_data supplies[2];
188182 /*
189183 * Mutex protects audio and video functions from interfering
190184 * each other, by keeping their i2c command sequences atomic.
....@@ -298,38 +292,42 @@
298292 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390,
299293 1430, 1650, 0, 720, 725, 730, 750, 0,
300294 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
301
- .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
295
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
302296 /* 16 - 1920x1080@60Hz 16:9 */
303297 { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008,
304298 2052, 2200, 0, 1080, 1084, 1089, 1125, 0,
305299 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
306
- .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
300
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
307301 /* 5 - 1920x1080i@60Hz 16:9 */
308302 { DRM_MODE("1920x1080i", DRM_MODE_TYPE_DRIVER, 74250, 1920, 2008,
309303 2052, 2200, 0, 1080, 1084, 1094, 1125, 0,
310304 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
311305 DRM_MODE_FLAG_INTERLACE),
312
- .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
313
- /* 62 - 1280x720@30Hz 16:9 */
314
- { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 3040,
315
- 3080, 3300, 0, 720, 725, 730, 750, 0,
306
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
307
+ /* 31 - 1920x1080@50Hz 16:9 */
308
+ { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2448,
309
+ 2492, 2640, 0, 1080, 1084, 1089, 1125, 0,
316310 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
317
- .vrefresh = 30, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
311
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
318312 /* 19 - 1280x720@50Hz 16:9 */
319313 { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1720,
320314 1760, 1980, 0, 720, 725, 730, 750, 0,
321315 DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC),
322
- .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
316
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
317
+ /* 0x10 - 1024x768@60Hz */
318
+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048,
319
+ 1184, 1344, 0, 768, 771, 777, 806, 0,
320
+ DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) },
323321 /* 17 - 720x576@50Hz 4:3 */
324322 { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 27000, 720, 732,
325323 796, 864, 0, 576, 581, 586, 625, 0,
326324 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
327
- .vrefresh = 50, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
325
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
328326 /* 2 - 720x480@60Hz 4:3 */
329327 { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 27000, 720, 736,
330328 798, 858, 0, 480, 489, 495, 525, 0,
331329 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
332
- .vrefresh = 60, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
330
+ .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
333331 };
334332
335333 static int sii902x_get_modes(struct drm_connector *connector)
....@@ -428,13 +426,42 @@
428426 mutex_unlock(&sii902x->mutex);
429427 }
430428
429
+static bool sii902x_check_embedded_format(uint32_t bus_format)
430
+{
431
+ switch (bus_format) {
432
+ case MEDIA_BUS_FMT_YUYV8_2X8:
433
+ case MEDIA_BUS_FMT_YVYU8_2X8:
434
+ case MEDIA_BUS_FMT_UYVY8_2X8:
435
+ case MEDIA_BUS_FMT_VYUY8_2X8:
436
+ case MEDIA_BUS_FMT_YUYV8_1X16:
437
+ case MEDIA_BUS_FMT_YVYU8_1X16:
438
+ case MEDIA_BUS_FMT_UYVY8_1X16:
439
+ case MEDIA_BUS_FMT_VYUY8_1X16:
440
+ return true;
441
+ default:
442
+ return false;
443
+ }
444
+}
445
+
431446 static void sii902x_set_embedded_sync(struct sii902x *sii902x)
432447 {
433448 unsigned char data[8];
434449 struct videomode vm;
435450
436
- if (sii902x->bus_format == MEDIA_BUS_FMT_RGB888_1X24)
451
+ if (!sii902x_check_embedded_format(sii902x->bus_format))
437452 return;
453
+
454
+ switch (sii902x->bus_format) {
455
+ case MEDIA_BUS_FMT_YUYV8_2X8:
456
+ case MEDIA_BUS_FMT_YVYU8_2X8:
457
+ case MEDIA_BUS_FMT_UYVY8_2X8:
458
+ case MEDIA_BUS_FMT_VYUY8_2X8:
459
+ sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
460
+ 0x20, 0x20);
461
+ break;
462
+ default:
463
+ break;
464
+ }
438465
439466 sii902x_update_bits_unlocked(sii902x->i2c, SII902X_TPI_SYNC_GEN_CTRL,
440467 0x80, 0x00);
....@@ -446,8 +473,13 @@
446473 drm_display_mode_to_videomode(&sii902x->mode, &vm);
447474 data[0] = vm.hfront_porch & 0xff;
448475 data[1] = (vm.hfront_porch >> 8) & 0x03;
449
- data[2] = 0;
450
- data[3] = 0;
476
+ if (sii902x->mode.flags & DRM_MODE_FLAG_INTERLACE) {
477
+ data[2] = (sii902x->mode.vtotal >> 1) & 0xff;
478
+ data[3] = ((sii902x->mode.vtotal >> 1) >> 8) & 0x1f;
479
+ } else {
480
+ data[2] = 0;
481
+ data[3] = 0;
482
+ }
451483 data[4] = vm.hsync_len & 0xff;
452484 data[5] = (vm.hsync_len >> 8) & 0x03;
453485 data[6] = vm.vfront_porch;
....@@ -475,6 +507,10 @@
475507 case MEDIA_BUS_FMT_YVYU8_1X16:
476508 case MEDIA_BUS_FMT_UYVY8_1X16:
477509 case MEDIA_BUS_FMT_VYUY8_1X16:
510
+ case MEDIA_BUS_FMT_YUYV8_2X8:
511
+ case MEDIA_BUS_FMT_YVYU8_2X8:
512
+ case MEDIA_BUS_FMT_UYVY8_2X8:
513
+ case MEDIA_BUS_FMT_VYUY8_2X8:
478514 val = SII902X_TPI_AVI_INPUT_COLORSPACE_YUV422;
479515 break;
480516 case MEDIA_BUS_FMT_YUV8_1X24:
....@@ -496,8 +532,8 @@
496532 }
497533
498534 static void sii902x_bridge_mode_set(struct drm_bridge *bridge,
499
- struct drm_display_mode *mode,
500
- struct drm_display_mode *adj)
535
+ const struct drm_display_mode *mode,
536
+ const struct drm_display_mode *adj)
501537 {
502538 struct sii902x *sii902x = bridge_to_sii902x(bridge);
503539 struct regmap *regmap = sii902x->regmap;
....@@ -523,6 +559,10 @@
523559 case MEDIA_BUS_FMT_YVYU8_1X16:
524560 case MEDIA_BUS_FMT_UYVY8_1X16:
525561 case MEDIA_BUS_FMT_VYUY8_1X16:
562
+ case MEDIA_BUS_FMT_YUYV8_2X8:
563
+ case MEDIA_BUS_FMT_YVYU8_2X8:
564
+ case MEDIA_BUS_FMT_UYVY8_2X8:
565
+ case MEDIA_BUS_FMT_VYUY8_2X8:
526566 buf[8] |= SII902X_TPI_AVI_PIXEL_REP_RISING_EDGE;
527567 break;
528568 default:
....@@ -535,6 +575,10 @@
535575 case MEDIA_BUS_FMT_YVYU8_1X16:
536576 case MEDIA_BUS_FMT_UYVY8_1X16:
537577 case MEDIA_BUS_FMT_VYUY8_1X16:
578
+ case MEDIA_BUS_FMT_YUYV8_2X8:
579
+ case MEDIA_BUS_FMT_YVYU8_2X8:
580
+ case MEDIA_BUS_FMT_UYVY8_2X8:
581
+ case MEDIA_BUS_FMT_VYUY8_2X8:
538582 buf[9] |= SII902X_TPI_AVI_INPUT_COLORSPACE_YUV422;
539583 break;
540584 case MEDIA_BUS_FMT_YUV8_1X24:
....@@ -553,7 +597,8 @@
553597 if (ret)
554598 goto out;
555599
556
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, adj, false);
600
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
601
+ &sii902x->connector, adj);
557602 if (ret < 0) {
558603 DRM_ERROR("couldn't fill AVI infoframe\n");
559604 goto out;
....@@ -569,17 +614,22 @@
569614 regmap_bulk_write(regmap, SII902X_TPI_AVI_INFOFRAME,
570615 buf + HDMI_INFOFRAME_HEADER_SIZE - 1,
571616 HDMI_AVI_INFOFRAME_SIZE + 1);
572
-
573617 sii902x_set_format(sii902x);
574618 out:
575619 mutex_unlock(&sii902x->mutex);
576620 }
577621
578
-static int sii902x_bridge_attach(struct drm_bridge *bridge)
622
+static int sii902x_bridge_attach(struct drm_bridge *bridge,
623
+ enum drm_bridge_attach_flags flags)
579624 {
580625 struct sii902x *sii902x = bridge_to_sii902x(bridge);
581626 struct drm_device *drm = bridge->dev;
582627 int ret;
628
+
629
+ if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
630
+ DRM_ERROR("Fix bridge driver to make connector optional!");
631
+ return -EINVAL;
632
+ }
583633
584634 sii902x->connector.interlace_allowed = true;
585635 drm_connector_helper_add(&sii902x->connector,
....@@ -843,8 +893,8 @@
843893 clk_disable_unprepare(sii902x->audio.mclk);
844894 }
845895
846
-static int sii902x_audio_digital_mute(struct device *dev,
847
- void *data, bool enable)
896
+static int sii902x_audio_mute(struct device *dev, void *data,
897
+ bool enable, int direction)
848898 {
849899 struct sii902x *sii902x = dev_get_drvdata(dev);
850900
....@@ -895,9 +945,10 @@
895945 static const struct hdmi_codec_ops sii902x_audio_codec_ops = {
896946 .hw_params = sii902x_audio_hw_params,
897947 .audio_shutdown = sii902x_audio_shutdown,
898
- .digital_mute = sii902x_audio_digital_mute,
948
+ .mute_stream = sii902x_audio_mute,
899949 .get_eld = sii902x_audio_get_eld,
900950 .get_dai_id = sii902x_audio_get_dai_id,
951
+ .no_capture_mute = 1,
901952 };
902953
903954 static int sii902x_audio_codec_init(struct sii902x *sii902x,
....@@ -1118,13 +1169,82 @@
11181169 return 0;
11191170 }
11201171
1172
+static const struct drm_bridge_timings default_sii902x_timings = {
1173
+ .input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE
1174
+ | DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE
1175
+ | DRM_BUS_FLAG_DE_HIGH,
1176
+};
1177
+
1178
+static int sii902x_init(struct sii902x *sii902x)
1179
+{
1180
+ struct device *dev = &sii902x->i2c->dev;
1181
+ unsigned int status = 0;
1182
+ u8 chipid[4];
1183
+ int ret;
1184
+
1185
+ sii902x_reset(sii902x);
1186
+
1187
+ ret = regmap_write(sii902x->regmap, SII902X_REG_TPI_RQB, 0x0);
1188
+ if (ret) {
1189
+ dev_err(dev, "enable TPI mode failed %d\n", ret);
1190
+ return ret;
1191
+ }
1192
+
1193
+ ret = regmap_bulk_read(sii902x->regmap, SII902X_REG_CHIPID(0),
1194
+ &chipid, 4);
1195
+ if (ret) {
1196
+ dev_err(dev, "regmap_read failed %d\n", ret);
1197
+ return ret;
1198
+ }
1199
+
1200
+ if (chipid[0] != 0xb0) {
1201
+ dev_err(dev, "Invalid chipid: %02x (expecting 0xb0)\n",
1202
+ chipid[0]);
1203
+ return -EINVAL;
1204
+ }
1205
+
1206
+ /* Clear all pending interrupts */
1207
+ regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status);
1208
+ regmap_write(sii902x->regmap, SII902X_INT_STATUS, status);
1209
+
1210
+ if (sii902x->i2c->irq > 0) {
1211
+ regmap_write(sii902x->regmap, SII902X_INT_ENABLE,
1212
+ SII902X_HOTPLUG_EVENT);
1213
+
1214
+ ret = devm_request_threaded_irq(dev, sii902x->i2c->irq, NULL,
1215
+ sii902x_interrupt,
1216
+ IRQF_TRIGGER_FALLING |
1217
+ IRQF_ONESHOT, dev_name(dev),
1218
+ sii902x);
1219
+ if (ret)
1220
+ return ret;
1221
+ }
1222
+
1223
+ sii902x->bridge.funcs = &sii902x_bridge_funcs;
1224
+ sii902x->bridge.of_node = dev->of_node;
1225
+ sii902x->bridge.timings = &default_sii902x_timings;
1226
+ drm_bridge_add(&sii902x->bridge);
1227
+
1228
+ sii902x_audio_codec_init(sii902x, dev);
1229
+
1230
+ i2c_set_clientdata(sii902x->i2c, sii902x);
1231
+
1232
+ sii902x->i2cmux = i2c_mux_alloc(sii902x->i2c->adapter, dev,
1233
+ 1, 0, I2C_MUX_GATE,
1234
+ sii902x_i2c_bypass_select,
1235
+ sii902x_i2c_bypass_deselect);
1236
+ if (!sii902x->i2cmux)
1237
+ return -ENOMEM;
1238
+
1239
+ sii902x->i2cmux->priv = sii902x;
1240
+ return i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0);
1241
+}
1242
+
11211243 static int sii902x_probe(struct i2c_client *client,
11221244 const struct i2c_device_id *id)
11231245 {
11241246 struct device *dev = &client->dev;
1125
- unsigned int status = 0;
11261247 struct sii902x *sii902x;
1127
- u8 chipid[4];
11281248 int ret;
11291249 u32 val;
11301250
....@@ -1185,59 +1305,28 @@
11851305
11861306 mutex_init(&sii902x->mutex);
11871307
1188
- sii902x_reset(sii902x);
1189
-
1190
- ret = regmap_write(sii902x->regmap, SII902X_REG_TPI_RQB, 0x0);
1191
- if (ret)
1308
+ sii902x->supplies[0].supply = "iovcc";
1309
+ sii902x->supplies[1].supply = "cvcc12";
1310
+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sii902x->supplies),
1311
+ sii902x->supplies);
1312
+ if (ret < 0)
11921313 return ret;
11931314
1194
- ret = regmap_bulk_read(sii902x->regmap, SII902X_REG_CHIPID(0),
1195
- &chipid, 4);
1196
- if (ret) {
1197
- dev_err(dev, "regmap_read failed %d\n", ret);
1315
+ ret = regulator_bulk_enable(ARRAY_SIZE(sii902x->supplies),
1316
+ sii902x->supplies);
1317
+ if (ret < 0) {
1318
+ dev_err_probe(dev, ret, "Failed to enable supplies");
11981319 return ret;
11991320 }
12001321
1201
- if (chipid[0] != 0xb0) {
1202
- dev_err(dev, "Invalid chipid: %02x (expecting 0xb0)\n",
1203
- chipid[0]);
1204
- return -EINVAL;
1322
+ ret = sii902x_init(sii902x);
1323
+ if (ret < 0) {
1324
+ dev_err(dev, "Failed to init sii902x %d\n", ret);
1325
+ regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies),
1326
+ sii902x->supplies);
12051327 }
12061328
1207
- /* Clear all pending interrupts */
1208
- regmap_read(sii902x->regmap, SII902X_INT_STATUS, &status);
1209
- regmap_write(sii902x->regmap, SII902X_INT_STATUS, status);
1210
-
1211
- if (client->irq > 0) {
1212
- regmap_write(sii902x->regmap, SII902X_INT_ENABLE,
1213
- SII902X_HOTPLUG_EVENT);
1214
-
1215
- ret = devm_request_threaded_irq(dev, client->irq, NULL,
1216
- sii902x_interrupt,
1217
- IRQF_TRIGGER_FALLING |
1218
- IRQF_ONESHOT, dev_name(dev),
1219
- sii902x);
1220
- if (ret)
1221
- return ret;
1222
- }
1223
-
1224
- sii902x->bridge.funcs = &sii902x_bridge_funcs;
1225
- sii902x->bridge.of_node = dev->of_node;
1226
- drm_bridge_add(&sii902x->bridge);
1227
-
1228
- sii902x_audio_codec_init(sii902x, dev);
1229
-
1230
- i2c_set_clientdata(client, sii902x);
1231
-
1232
- sii902x->i2cmux = i2c_mux_alloc(client->adapter, dev,
1233
- 1, 0, I2C_MUX_GATE,
1234
- sii902x_i2c_bypass_select,
1235
- sii902x_i2c_bypass_deselect);
1236
- if (!sii902x->i2cmux)
1237
- return -ENOMEM;
1238
-
1239
- sii902x->i2cmux->priv = sii902x;
1240
- return i2c_mux_add_adapter(sii902x->i2cmux, 0, 0, 0);
1329
+ return ret;
12411330 }
12421331
12431332 static int sii902x_remove(struct i2c_client *client)
....@@ -1247,6 +1336,8 @@
12471336
12481337 i2c_mux_del_adapters(sii902x->i2cmux);
12491338 drm_bridge_remove(&sii902x->bridge);
1339
+ regulator_bulk_disable(ARRAY_SIZE(sii902x->supplies),
1340
+ sii902x->supplies);
12501341
12511342 return 0;
12521343 }