hc
2023-11-06 9df731a176aab8e03b984b681b1bea01ccff6644
u-boot/drivers/video/drm/dw_hdmi.c
....@@ -7,6 +7,7 @@
77 #include <common.h>
88 #include <malloc.h>
99 #include <syscon.h>
10
+#include <asm/gpio.h>
1011 #include <asm/arch-rockchip/clock.h>
1112 #include <asm/arch/vendor.h>
1213 #include <edid.h>
....@@ -27,6 +28,7 @@
2728 #define HDCP_PRIVATE_KEY_SIZE 280
2829 #define HDCP_KEY_SHA_SIZE 20
2930 #define HDMI_HDCP1X_ID 5
31
+#define HDMI_EDID_BLOCK_LEN 128
3032 /*
3133 * Unless otherwise noted, entries in this table are 100% optimization.
3234 * Values can be obtained from hdmi_compute_n() but that function is
....@@ -181,6 +183,7 @@
181183 bool sink_has_audio;
182184 void *regs;
183185 void *grf;
186
+ void *gpio_base;
184187 struct dw_hdmi_i2c *i2c;
185188
186189 struct {
....@@ -203,6 +206,8 @@
203206
204207 bool hdcp1x_enable;
205208 bool output_bus_format_rgb;
209
+
210
+ struct gpio_desc hpd_gpiod;
206211 };
207212
208213 static void dw_hdmi_writel(struct dw_hdmi *hdmi, u8 val, int offset)
....@@ -409,6 +414,7 @@
409414 {
410415 struct dw_hdmi_i2c *i2c = hdmi->i2c;
411416 int interrupt = 0, i = 20;
417
+ bool read_edid = false;
412418
413419 if (!i2c->is_regaddr) {
414420 printf("set read register address to 0\n");
....@@ -416,14 +422,36 @@
416422 i2c->is_regaddr = true;
417423 }
418424
419
- while (length--) {
420
- hdmi_writeb(hdmi, i2c->slave_reg++, HDMI_I2CM_ADDRESS);
421
- if (i2c->is_segment)
422
- hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ_EXT,
423
- HDMI_I2CM_OPERATION);
424
- else
425
- hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ,
426
- HDMI_I2CM_OPERATION);
425
+ /* edid reads are in 128 bytes. scdc reads are in 1 byte */
426
+ if (length == HDMI_EDID_BLOCK_LEN)
427
+ read_edid = true;
428
+
429
+ while (length > 0) {
430
+ hdmi_writeb(hdmi, i2c->slave_reg, HDMI_I2CM_ADDRESS);
431
+
432
+ if (read_edid) {
433
+ i2c->slave_reg += 8;
434
+ length -= 8;
435
+ } else {
436
+ i2c->slave_reg++;
437
+ length--;
438
+ }
439
+
440
+ if (i2c->is_segment) {
441
+ if (read_edid)
442
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ8_EXT,
443
+ HDMI_I2CM_OPERATION);
444
+ else
445
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ_EXT,
446
+ HDMI_I2CM_OPERATION);
447
+ } else {
448
+ if (read_edid)
449
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ8,
450
+ HDMI_I2CM_OPERATION);
451
+ else
452
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_READ,
453
+ HDMI_I2CM_OPERATION);
454
+ }
427455
428456 while (i--) {
429457 udelay(1000);
....@@ -439,6 +467,10 @@
439467 if (!interrupt) {
440468 printf("[%s] i2c read reg[0x%02x] no interrupt\n",
441469 __func__, i2c->slave_reg);
470
+ hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
471
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_BUS_CLEAR,
472
+ HDMI_I2CM_OPERATION);
473
+ udelay(1000);
442474 return -EAGAIN;
443475 }
444476
....@@ -446,11 +478,19 @@
446478 if (interrupt & HDMI_IH_I2CM_STAT0_ERROR) {
447479 printf("[%s] read reg[0x%02x] data error:0x%02x\n",
448480 __func__, i2c->slave_reg, interrupt);
481
+ hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
482
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_BUS_CLEAR,
483
+ HDMI_I2CM_OPERATION);
484
+ udelay(1000);
449485 return -EIO;
450486 }
451487
452488 i = 20;
453
- *buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI);
489
+ if (read_edid)
490
+ for (i = 0; i < 8; i++)
491
+ *buf++ = hdmi_readb(hdmi, HDMI_I2CM_READ_BUFF0 + i);
492
+ else
493
+ *buf++ = hdmi_readb(hdmi, HDMI_I2CM_DATAI);
454494 }
455495 i2c->is_segment = false;
456496
....@@ -490,8 +530,22 @@
490530 break;
491531 }
492532
533
+ if (!interrupt) {
534
+ printf("[%s] i2c write reg[0x%02x] no interrupt\n",
535
+ __func__, i2c->slave_reg);
536
+ hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
537
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_BUS_CLEAR,
538
+ HDMI_I2CM_OPERATION);
539
+ udelay(1000);
540
+ return -EAGAIN;
541
+ }
542
+
493543 if ((interrupt & m_I2CM_ERROR) || (i == -1)) {
494544 printf("[%s] write data error\n", __func__);
545
+ hdmi_writeb(hdmi, 0, HDMI_I2CM_SOFTRSTZ);
546
+ hdmi_writeb(hdmi, HDMI_I2CM_OPERATION_BUS_CLEAR,
547
+ HDMI_I2CM_OPERATION);
548
+ udelay(1000);
495549 return -EIO;
496550 } else if (interrupt & m_I2CM_DONE) {
497551 printf("[%s] write offset %02x success\n",
....@@ -959,6 +1013,7 @@
9591013 * but it has a vedor phy.
9601014 */
9611015 if (phy_type == DW_HDMI_PHY_VENDOR_PHY ||
1016
+ hdmi->dev_type == RK3528_HDMI ||
9621017 hdmi->dev_type == RK3328_HDMI ||
9631018 hdmi->dev_type == RK3228_HDMI) {
9641019 /* Vendor PHYs require support from the glue layer. */
....@@ -1042,14 +1097,11 @@
10421097 vmode->mpixelclock, vmode->mtmdsclock);
10431098
10441099 /* Set up HDMI_FC_INVIDCONF
1045
- * fc_invidconf.HDCP_keepout must be set (1'b1)
1046
- * when activate the scrambler feature.
1100
+ * Some display equipments require that the interval
1101
+ * between Video Data and Data island must be at least 58 pixels,
1102
+ * and fc_invidconf.HDCP_keepout set (1'b1) can meet the requirement.
10471103 */
1048
- inv_val = (vmode->mtmdsclock > 340000000 ||
1049
- (hdmi_info->scdc.scrambling.low_rates &&
1050
- hdmi->scramble_low_rates) ?
1051
- HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE :
1052
- HDMI_FC_INVIDCONF_HDCP_KEEPOUT_INACTIVE);
1104
+ inv_val = HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE;
10531105
10541106 inv_val |= mode->flags & DRM_MODE_FLAG_PVSYNC ?
10551107 HDMI_FC_INVIDCONF_VSYNC_IN_POLARITY_ACTIVE_HIGH :
....@@ -1418,13 +1470,8 @@
14181470 HDMI_VP_CONF_PR_EN_MASK |
14191471 HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF);
14201472
1421
- if ((color_depth == 5 && hdmi->previous_mode.htotal % 4) ||
1422
- (color_depth == 6 && hdmi->previous_mode.htotal % 2))
1423
- hdmi_modb(hdmi, 0, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK,
1424
- HDMI_VP_STUFF);
1425
- else
1426
- hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET,
1427
- HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF);
1473
+ hdmi_modb(hdmi, 0, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK,
1474
+ HDMI_VP_STUFF);
14281475
14291476 hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP);
14301477
....@@ -1887,6 +1934,7 @@
18871934 hdmi->sample_rate);
18881935 }
18891936
1937
+#ifndef CONFIG_SPL_BUILD
18901938 static int dw_hdmi_hdcp_load_key(struct dw_hdmi *hdmi)
18911939 {
18921940 int i, j, ret, val;
....@@ -1952,6 +2000,7 @@
19522000 free(hdcp_keys);
19532001 return 0;
19542002 }
2003
+#endif
19552004
19562005 static void hdmi_tx_hdcp_config(struct dw_hdmi *hdmi,
19572006 const struct drm_display_mode *mode)
....@@ -1981,8 +2030,10 @@
19812030 hdmi_modb(hdmi, hdmi_dvi, HDMI_A_HDCPCFG0_HDMIDVI_MASK,
19822031 HDMI_A_HDCPCFG0);
19832032
2033
+#ifndef CONFIG_SPL_BUILD
19842034 if (!(hdmi_readb(hdmi, HDMI_HDCPREG_RMSTS) & 0x3f))
19852035 dw_hdmi_hdcp_load_key(hdmi);
2036
+#endif
19862037
19872038 hdmi_modb(hdmi, HDMI_FC_INVIDCONF_HDCP_KEEPOUT_ACTIVE,
19882039 HDMI_FC_INVIDCONF_HDCP_KEEPOUT_MASK,
....@@ -2269,13 +2320,18 @@
22692320 {
22702321 struct connector_state *conn_state = &state->conn_state;
22712322 const struct dw_hdmi_plat_data *pdata =
2323
+#ifdef CONFIG_SPL_BUILD
2324
+ (const struct dw_hdmi_plat_data *)conn->data;
2325
+#else
22722326 (const struct dw_hdmi_plat_data *)dev_get_driver_data(conn->dev);
2327
+ ofnode hdmi_node = conn->dev->node;
2328
+ struct device_node *ddc_node;
2329
+ int ret;
2330
+#endif
22732331 struct crtc_state *crtc_state = &state->crtc_state;
22742332 struct dw_hdmi *hdmi;
22752333 struct drm_display_mode *mode_buf;
2276
- ofnode hdmi_node = conn->dev->node;
22772334 u32 val;
2278
- struct device_node *ddc_node;
22792335
22802336 hdmi = malloc(sizeof(struct dw_hdmi));
22812337 if (!hdmi)
....@@ -2285,13 +2341,28 @@
22852341 mode_buf = malloc(MODE_LEN * sizeof(struct drm_display_mode));
22862342 if (!mode_buf)
22872343 return -ENOMEM;
2344
+
2345
+#ifdef CONFIG_SPL_BUILD
2346
+ hdmi->id = 0;
2347
+ hdmi->regs = (void *)RK3528_HDMI_BASE;
2348
+ hdmi->io_width = 4;
2349
+ hdmi->scramble_low_rates = false;
2350
+ hdmi->hdcp1x_enable = false;
2351
+ hdmi->output_bus_format_rgb = false;
2352
+ conn_state->type = DRM_MODE_CONNECTOR_HDMIA;
2353
+#else
22882354 hdmi->id = of_alias_get_id(ofnode_to_np(hdmi_node), "hdmi");
22892355 if (hdmi->id < 0)
22902356 hdmi->id = 0;
2291
- conn_state->disp_info = rockchip_get_disp_info(conn_state->type, hdmi->id);
2357
+ conn_state->disp_info = rockchip_get_disp_info(conn_state->type, hdmi->id);
2358
+#endif
22922359
22932360 memset(mode_buf, 0, MODE_LEN * sizeof(struct drm_display_mode));
22942361
2362
+ hdmi->dev_type = pdata->dev_type;
2363
+ hdmi->plat_data = pdata;
2364
+
2365
+#ifndef CONFIG_SPL_BUILD
22952366 hdmi->regs = dev_read_addr_ptr(conn->dev);
22962367 hdmi->io_width = ofnode_read_s32_default(hdmi_node, "reg-io-width", -1);
22972368
....@@ -2309,6 +2380,24 @@
23092380 else
23102381 hdmi->output_bus_format_rgb = false;
23112382
2383
+ ret = dev_read_size(conn->dev, "rockchip,phy-table");
2384
+ if (ret > 0 && hdmi->plat_data->phy_config) {
2385
+ u32 phy_config[ret / 4];
2386
+ int i;
2387
+
2388
+ dev_read_u32_array(conn->dev, "rockchip,phy-table", phy_config, ret / 4);
2389
+
2390
+ for (i = 0; i < ret / 16; i++) {
2391
+ if (phy_config[i * 4] != 0)
2392
+ hdmi->plat_data->phy_config[i].mpixelclock = (u64)phy_config[i * 4];
2393
+ else
2394
+ hdmi->plat_data->phy_config[i].mpixelclock = ~0UL;
2395
+ hdmi->plat_data->phy_config[i].sym_ctr = (u16)phy_config[i * 4 + 1];
2396
+ hdmi->plat_data->phy_config[i].term = (u16)phy_config[i * 4 + 2];
2397
+ hdmi->plat_data->phy_config[i].vlev_ctr = (u16)phy_config[i * 4 + 3];
2398
+ }
2399
+ }
2400
+
23122401 ddc_node = of_parse_phandle(ofnode_to_np(hdmi_node), "ddc-i2c-bus", 0);
23132402 if (ddc_node) {
23142403 uclass_get_device_by_ofnode(UCLASS_I2C, np_to_ofnode(ddc_node),
....@@ -2316,6 +2405,7 @@
23162405 if (hdmi->adap.i2c_bus)
23172406 hdmi->adap.ops = i2c_get_ops(hdmi->adap.i2c_bus);
23182407 }
2408
+#endif
23192409
23202410 hdmi->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
23212411 if (hdmi->grf <= 0) {
....@@ -2323,6 +2413,20 @@
23232413 __func__, hdmi->grf);
23242414 return -ENXIO;
23252415 }
2416
+
2417
+#ifdef CONFIG_SPL_BUILD
2418
+ hdmi->gpio_base = (void *)RK3528_GPIO_BASE;
2419
+#else
2420
+ ret = gpio_request_by_name(conn->dev, "hpd-gpios", 0,
2421
+ &hdmi->hpd_gpiod, GPIOD_IS_IN);
2422
+ if (ret && ret != -ENOENT) {
2423
+ printf("%s: Cannot get HPD GPIO: %d\n", __func__, ret);
2424
+ return ret;
2425
+ }
2426
+ hdmi->gpio_base = (void *)dev_read_addr_index(conn->dev, 1);
2427
+#endif
2428
+ if (!hdmi->gpio_base)
2429
+ return -ENODEV;
23262430
23272431 dw_hdmi_set_reg_wr(hdmi);
23282432
....@@ -2345,24 +2449,28 @@
23452449 * Read high and low time from device tree. If not available use
23462450 * the default timing scl clock rate is about 99.6KHz.
23472451 */
2452
+#ifdef CONFIG_SPL_BUILD
2453
+ hdmi->i2c->scl_high_ns = 9625;
2454
+ hdmi->i2c->scl_low_ns = 10000;
2455
+#else
23482456 hdmi->i2c->scl_high_ns =
23492457 ofnode_read_s32_default(hdmi_node,
23502458 "ddc-i2c-scl-high-time-ns", 4708);
23512459 hdmi->i2c->scl_low_ns =
23522460 ofnode_read_s32_default(hdmi_node,
23532461 "ddc-i2c-scl-low-time-ns", 4916);
2462
+#endif
23542463
23552464 dw_hdmi_i2c_init(hdmi);
23562465 conn_state->output_if |= VOP_OUTPUT_IF_HDMI0;
23572466 conn_state->output_mode = ROCKCHIP_OUT_MODE_AAAA;
23582467
2359
- hdmi->dev_type = pdata->dev_type;
2360
- hdmi->plat_data = pdata;
23612468 hdmi->edid_data.mode_buf = mode_buf;
23622469 hdmi->sample_rate = 48000;
23632470
23642471 conn->data = hdmi;
2365
- dw_hdmi_set_iomux(hdmi->grf, hdmi->dev_type);
2472
+ dw_hdmi_set_iomux(hdmi->grf, hdmi->gpio_base,
2473
+ &hdmi->hpd_gpiod, hdmi->dev_type);
23662474 dw_hdmi_detect_phy(hdmi);
23672475 dw_hdmi_dev_init(hdmi);
23682476
....@@ -2413,7 +2521,7 @@
24132521
24142522 int rockchip_dw_hdmi_get_timing(struct rockchip_connector *conn, struct display_state *state)
24152523 {
2416
- int ret, i;
2524
+ int ret, i, vic;
24172525 struct connector_state *conn_state = &state->conn_state;
24182526 struct drm_display_mode *mode = &conn_state->mode;
24192527 struct dw_hdmi *hdmi = conn->data;
....@@ -2439,9 +2547,13 @@
24392547 hdmi->sink_has_audio = true;
24402548 do_cea_modes(&hdmi->edid_data, def_modes_vic,
24412549 sizeof(def_modes_vic));
2550
+ hdmi->edid_data.mode_buf[0].type |= DRM_MODE_TYPE_PREFERRED;
24422551 hdmi->edid_data.preferred_mode = &hdmi->edid_data.mode_buf[0];
24432552 printf("failed to get edid\n");
24442553 }
2554
+#ifdef CONFIG_SPL_BUILD
2555
+ conn_state->disp_info = rockchip_get_disp_info(conn_state->type, hdmi->id);
2556
+#endif
24452557 drm_rk_filter_whitelist(&hdmi->edid_data);
24462558 if (hdmi->phy.ops->mode_valid)
24472559 hdmi->phy.ops->mode_valid(conn, hdmi, state);
....@@ -2452,9 +2564,20 @@
24522564 return -EINVAL;
24532565 }
24542566
2455
- for (i = 0; i < hdmi->edid_data.modes; i++)
2567
+ for (i = 0; i < hdmi->edid_data.modes; i++) {
24562568 hdmi->edid_data.mode_buf[i].vrefresh =
24572569 drm_mode_vrefresh(&hdmi->edid_data.mode_buf[i]);
2570
+
2571
+ vic = drm_match_cea_mode(&hdmi->edid_data.mode_buf[i]);
2572
+ if (hdmi->edid_data.mode_buf[i].picture_aspect_ratio == HDMI_PICTURE_ASPECT_NONE) {
2573
+ if (vic >= 93 && vic <= 95)
2574
+ hdmi->edid_data.mode_buf[i].picture_aspect_ratio =
2575
+ HDMI_PICTURE_ASPECT_16_9;
2576
+ else if (vic == 98)
2577
+ hdmi->edid_data.mode_buf[i].picture_aspect_ratio =
2578
+ HDMI_PICTURE_ASPECT_256_135;
2579
+ }
2580
+ }
24582581
24592582 drm_mode_sort(&hdmi->edid_data);
24602583 drm_rk_selete_output(&hdmi->edid_data, conn_state, &bus_format,
....@@ -2463,7 +2586,6 @@
24632586 *mode = *hdmi->edid_data.preferred_mode;
24642587 hdmi->vic = drm_match_cea_mode(mode);
24652588
2466
- printf("mode:%dx%d\n", mode->hdisplay, mode->vdisplay);
24672589 if (state->force_output)
24682590 bus_format = state->force_bus_format;
24692591 conn_state->bus_format = bus_format;