Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/tegra: sor: Add HDMI support

The SOR1 introduced on Tegra210 supports HDMI 2.0 and DisplayPort. Add
HDMI support and name the debugfs node after the type of SOR. The SOR
introduced with Tegra124 is known simply as "sor", whereas the
additional SOR found on Tegra210 is known as "sor1".

Signed-off-by: Thierry Reding <treding@nvidia.com>

+1052 -34
+1
Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt
··· 201 201 - "nvidia,tegra124-sor": for Tegra124 and Tegra132 202 202 - "nvidia,tegra132-sor": for Tegra132 203 203 - "nvidia,tegra210-sor": for Tegra210 204 + - "nvidia,tegra210-sor1": for Tegra210 204 205 - reg: Physical base address and length of the controller's registers. 205 206 - interrupts: The interrupt outputs from the controller. 206 207 - clocks: Must contain an entry for each entry in clock-names.
+4
drivers/gpu/drm/tegra/dc.h
··· 128 128 #define DC_DISP_DISP_WIN_OPTIONS 0x402 129 129 #define HDMI_ENABLE (1 << 30) 130 130 #define DSI_ENABLE (1 << 29) 131 + #define SOR1_TIMING_CYA (1 << 27) 132 + #define SOR1_ENABLE (1 << 26) 131 133 #define SOR_ENABLE (1 << 25) 132 134 #define CURSOR_ENABLE (1 << 16) 133 135 ··· 249 247 #define BASE_COLOR_SIZE565 (6 << 0) 250 248 #define BASE_COLOR_SIZE332 (7 << 0) 251 249 #define BASE_COLOR_SIZE888 (8 << 0) 250 + #define DITHER_CONTROL_MASK (3 << 8) 252 251 #define DITHER_CONTROL_DISABLE (0 << 8) 253 252 #define DITHER_CONTROL_ORDERED (2 << 8) 254 253 #define DITHER_CONTROL_ERRDIFF (3 << 8) 254 + #define BASE_COLOR_SIZE_MASK (0xf << 0) 255 255 #define BASE_COLOR_SIZE_666 (0 << 0) 256 256 #define BASE_COLOR_SIZE_111 (1 << 0) 257 257 #define BASE_COLOR_SIZE_222 (2 << 0)
+1
drivers/gpu/drm/tegra/drm.c
··· 1061 1061 { .compatible = "nvidia,tegra210-dc", }, 1062 1062 { .compatible = "nvidia,tegra210-dsi", }, 1063 1063 { .compatible = "nvidia,tegra210-sor", }, 1064 + { .compatible = "nvidia,tegra210-sor1", }, 1064 1065 { /* sentinel */ } 1065 1066 }; 1066 1067
+960 -34
drivers/gpu/drm/tegra/sor.c
··· 10 10 #include <linux/debugfs.h> 11 11 #include <linux/gpio.h> 12 12 #include <linux/io.h> 13 + #include <linux/of_device.h> 13 14 #include <linux/platform_device.h> 15 + #include <linux/regulator/consumer.h> 14 16 #include <linux/reset.h> 15 17 16 18 #include <soc/tegra/pmc.h> ··· 25 23 #include "drm.h" 26 24 #include "sor.h" 27 25 26 + #define SOR_REKEY 0x38 27 + 28 + struct tegra_sor_hdmi_settings { 29 + unsigned long frequency; 30 + 31 + u8 vcocap; 32 + u8 ichpmp; 33 + u8 loadadj; 34 + u8 termadj; 35 + u8 tx_pu; 36 + u8 bg_vref; 37 + 38 + u8 drive_current[4]; 39 + u8 preemphasis[4]; 40 + }; 41 + 42 + #if 1 43 + static const struct tegra_sor_hdmi_settings tegra210_sor_hdmi_defaults[] = { 44 + { 45 + .frequency = 54000000, 46 + .vcocap = 0x0, 47 + .ichpmp = 0x1, 48 + .loadadj = 0x3, 49 + .termadj = 0x9, 50 + .tx_pu = 0x10, 51 + .bg_vref = 0x8, 52 + .drive_current = { 0x33, 0x3a, 0x3a, 0x3a }, 53 + .preemphasis = { 0x00, 0x00, 0x00, 0x00 }, 54 + }, { 55 + .frequency = 75000000, 56 + .vcocap = 0x3, 57 + .ichpmp = 0x1, 58 + .loadadj = 0x3, 59 + .termadj = 0x9, 60 + .tx_pu = 0x40, 61 + .bg_vref = 0x8, 62 + .drive_current = { 0x33, 0x3a, 0x3a, 0x3a }, 63 + .preemphasis = { 0x00, 0x00, 0x00, 0x00 }, 64 + }, { 65 + .frequency = 150000000, 66 + .vcocap = 0x3, 67 + .ichpmp = 0x1, 68 + .loadadj = 0x3, 69 + .termadj = 0x9, 70 + .tx_pu = 0x66, 71 + .bg_vref = 0x8, 72 + .drive_current = { 0x33, 0x3a, 0x3a, 0x3a }, 73 + .preemphasis = { 0x00, 0x00, 0x00, 0x00 }, 74 + }, { 75 + .frequency = 300000000, 76 + .vcocap = 0x3, 77 + .ichpmp = 0x1, 78 + .loadadj = 0x3, 79 + .termadj = 0x9, 80 + .tx_pu = 0x66, 81 + .bg_vref = 0xa, 82 + .drive_current = { 0x33, 0x3f, 0x3f, 0x3f }, 83 + .preemphasis = { 0x00, 0x17, 0x17, 0x17 }, 84 + }, { 85 + .frequency = 600000000, 86 + .vcocap = 0x3, 87 + .ichpmp = 0x1, 88 + .loadadj = 0x3, 89 + .termadj = 0x9, 90 + .tx_pu = 0x66, 91 + .bg_vref = 0x8, 92 + .drive_current = { 0x33, 0x3f, 0x3f, 0x3f }, 93 + .preemphasis = { 0x00, 0x00, 0x00, 0x00 }, 94 + }, 95 + }; 96 + #else 97 + static const struct tegra_sor_hdmi_settings tegra210_sor_hdmi_defaults[] = { 98 + { 99 + .frequency = 75000000, 100 + .vcocap = 0x3, 101 + .ichpmp = 0x1, 102 + .loadadj = 0x3, 103 + .termadj = 0x9, 104 + .tx_pu = 0x40, 105 + .bg_vref = 0x8, 106 + .drive_current = { 0x29, 0x29, 0x29, 0x29 }, 107 + .preemphasis = { 0x00, 0x00, 0x00, 0x00 }, 108 + }, { 109 + .frequency = 150000000, 110 + .vcocap = 0x3, 111 + .ichpmp = 0x1, 112 + .loadadj = 0x3, 113 + .termadj = 0x9, 114 + .tx_pu = 0x66, 115 + .bg_vref = 0x8, 116 + .drive_current = { 0x30, 0x37, 0x37, 0x37 }, 117 + .preemphasis = { 0x01, 0x02, 0x02, 0x02 }, 118 + }, { 119 + .frequency = 300000000, 120 + .vcocap = 0x3, 121 + .ichpmp = 0x6, 122 + .loadadj = 0x3, 123 + .termadj = 0x9, 124 + .tx_pu = 0x66, 125 + .bg_vref = 0xf, 126 + .drive_current = { 0x30, 0x37, 0x37, 0x37 }, 127 + .preemphasis = { 0x10, 0x3e, 0x3e, 0x3e }, 128 + }, { 129 + .frequency = 600000000, 130 + .vcocap = 0x3, 131 + .ichpmp = 0xa, 132 + .loadadj = 0x3, 133 + .termadj = 0xb, 134 + .tx_pu = 0x66, 135 + .bg_vref = 0xe, 136 + .drive_current = { 0x35, 0x3e, 0x3e, 0x3e }, 137 + .preemphasis = { 0x02, 0x3f, 0x3f, 0x3f }, 138 + }, 139 + }; 140 + #endif 141 + 142 + struct tegra_sor_soc { 143 + bool supports_edp; 144 + bool supports_lvds; 145 + bool supports_hdmi; 146 + bool supports_dp; 147 + 148 + const struct tegra_sor_hdmi_settings *settings; 149 + unsigned int num_settings; 150 + }; 151 + 152 + struct tegra_sor; 153 + 154 + struct tegra_sor_ops { 155 + const char *name; 156 + int (*probe)(struct tegra_sor *sor); 157 + int (*remove)(struct tegra_sor *sor); 158 + }; 159 + 28 160 struct tegra_sor { 29 161 struct host1x_client client; 30 162 struct tegra_output output; 31 163 struct device *dev; 32 164 165 + const struct tegra_sor_soc *soc; 33 166 void __iomem *regs; 34 167 35 168 struct reset_control *rst; ··· 178 41 struct drm_info_list *debugfs_files; 179 42 struct drm_minor *minor; 180 43 struct dentry *debugfs; 44 + 45 + const struct tegra_sor_ops *ops; 46 + 47 + /* for HDMI 2.0 */ 48 + struct tegra_sor_hdmi_settings *settings; 49 + unsigned int num_settings; 50 + 51 + struct regulator *avdd_io_supply; 52 + struct regulator *vdd_pll_supply; 53 + struct regulator *hdmi_supply; 181 54 }; 182 55 183 56 struct tegra_sor_config { ··· 329 182 return err; 330 183 331 184 return 0; 185 + } 186 + 187 + static void tegra_sor_dp_term_calibrate(struct tegra_sor *sor) 188 + { 189 + u32 mask = 0x08, adj = 0, value; 190 + 191 + /* enable pad calibration logic */ 192 + value = tegra_sor_readl(sor, SOR_DP_PADCTL0); 193 + value &= ~SOR_DP_PADCTL_PAD_CAL_PD; 194 + tegra_sor_writel(sor, value, SOR_DP_PADCTL0); 195 + 196 + value = tegra_sor_readl(sor, SOR_PLL1); 197 + value |= SOR_PLL1_TMDS_TERM; 198 + tegra_sor_writel(sor, value, SOR_PLL1); 199 + 200 + while (mask) { 201 + adj |= mask; 202 + 203 + value = tegra_sor_readl(sor, SOR_PLL1); 204 + value &= ~SOR_PLL1_TMDS_TERMADJ_MASK; 205 + value |= SOR_PLL1_TMDS_TERMADJ(adj); 206 + tegra_sor_writel(sor, value, SOR_PLL1); 207 + 208 + usleep_range(100, 200); 209 + 210 + value = tegra_sor_readl(sor, SOR_PLL1); 211 + if (value & SOR_PLL1_TERM_COMPOUT) 212 + adj &= ~mask; 213 + 214 + mask >>= 1; 215 + } 216 + 217 + value = tegra_sor_readl(sor, SOR_PLL1); 218 + value &= ~SOR_PLL1_TMDS_TERMADJ_MASK; 219 + value |= SOR_PLL1_TMDS_TERMADJ(adj); 220 + tegra_sor_writel(sor, value, SOR_PLL1); 221 + 222 + /* disable pad calibration logic */ 223 + value = tegra_sor_readl(sor, SOR_DP_PADCTL0); 224 + value |= SOR_DP_PADCTL_PAD_CAL_PD; 225 + tegra_sor_writel(sor, value, SOR_DP_PADCTL0); 332 226 } 333 227 334 228 static void tegra_sor_super_update(struct tegra_sor *sor) ··· 988 800 static int tegra_sor_debugfs_init(struct tegra_sor *sor, 989 801 struct drm_minor *minor) 990 802 { 803 + const char *name = sor->soc->supports_dp ? "sor1" : "sor"; 991 804 unsigned int i; 992 805 int err; 993 806 994 - sor->debugfs = debugfs_create_dir("sor", minor->debugfs_root); 807 + sor->debugfs = debugfs_create_dir(name, minor->debugfs_root); 995 808 if (!sor->debugfs) 996 809 return -ENOMEM; 997 810 ··· 1047 858 if (sor->dpaux) 1048 859 return tegra_dpaux_detect(sor->dpaux); 1049 860 1050 - return connector_status_unknown; 861 + return tegra_output_connector_detect(connector, force); 1051 862 } 1052 863 1053 864 static const struct drm_connector_funcs tegra_sor_connector_funcs = { ··· 1144 955 reset_control_assert(sor->rst); 1145 956 clk_disable_unprepare(sor->clk); 1146 957 } 958 + 959 + #if 0 960 + static int calc_h_ref_to_sync(const struct drm_display_mode *mode, 961 + unsigned int *value) 962 + { 963 + unsigned int hfp, hsw, hbp, a = 0, b; 964 + 965 + hfp = mode->hsync_start - mode->hdisplay; 966 + hsw = mode->hsync_end - mode->hsync_start; 967 + hbp = mode->htotal - mode->hsync_end; 968 + 969 + pr_info("hfp: %u, hsw: %u, hbp: %u\n", hfp, hsw, hbp); 970 + 971 + b = hfp - 1; 972 + 973 + pr_info("a: %u, b: %u\n", a, b); 974 + pr_info("a + hsw + hbp = %u\n", a + hsw + hbp); 975 + 976 + if (a + hsw + hbp <= 11) { 977 + a = 1 + 11 - hsw - hbp; 978 + pr_info("a: %u\n", a); 979 + } 980 + 981 + if (a > b) 982 + return -EINVAL; 983 + 984 + if (hsw < 1) 985 + return -EINVAL; 986 + 987 + if (mode->hdisplay < 16) 988 + return -EINVAL; 989 + 990 + if (value) { 991 + if (b > a && a % 2) 992 + *value = a + 1; 993 + else 994 + *value = a; 995 + } 996 + 997 + return 0; 998 + } 999 + #endif 1147 1000 1148 1001 static void tegra_sor_edp_enable(struct drm_encoder *encoder) 1149 1002 { ··· 1608 1377 return 0; 1609 1378 } 1610 1379 1611 - static const struct drm_encoder_helper_funcs tegra_sor_edp_helper_funcs = { 1380 + static const struct drm_encoder_helper_funcs tegra_sor_edp_helpers = { 1612 1381 .disable = tegra_sor_edp_disable, 1613 1382 .enable = tegra_sor_edp_enable, 1383 + .atomic_check = tegra_sor_encoder_atomic_check, 1384 + }; 1385 + 1386 + static inline u32 tegra_sor_hdmi_subpack(const u8 *ptr, size_t size) 1387 + { 1388 + u32 value = 0; 1389 + size_t i; 1390 + 1391 + for (i = size; i > 0; i--) 1392 + value = (value << 8) | ptr[i - 1]; 1393 + 1394 + return value; 1395 + } 1396 + 1397 + static void tegra_sor_hdmi_write_infopack(struct tegra_sor *sor, 1398 + const void *data, size_t size) 1399 + { 1400 + const u8 *ptr = data; 1401 + unsigned long offset; 1402 + size_t i, j; 1403 + u32 value; 1404 + 1405 + switch (ptr[0]) { 1406 + case HDMI_INFOFRAME_TYPE_AVI: 1407 + offset = SOR_HDMI_AVI_INFOFRAME_HEADER; 1408 + break; 1409 + 1410 + case HDMI_INFOFRAME_TYPE_AUDIO: 1411 + offset = SOR_HDMI_AUDIO_INFOFRAME_HEADER; 1412 + break; 1413 + 1414 + case HDMI_INFOFRAME_TYPE_VENDOR: 1415 + offset = SOR_HDMI_VSI_INFOFRAME_HEADER; 1416 + break; 1417 + 1418 + default: 1419 + dev_err(sor->dev, "unsupported infoframe type: %02x\n", 1420 + ptr[0]); 1421 + return; 1422 + } 1423 + 1424 + value = INFOFRAME_HEADER_TYPE(ptr[0]) | 1425 + INFOFRAME_HEADER_VERSION(ptr[1]) | 1426 + INFOFRAME_HEADER_LEN(ptr[2]); 1427 + tegra_sor_writel(sor, value, offset); 1428 + offset++; 1429 + 1430 + /* 1431 + * Each subpack contains 7 bytes, divided into: 1432 + * - subpack_low: bytes 0 - 3 1433 + * - subpack_high: bytes 4 - 6 (with byte 7 padded to 0x00) 1434 + */ 1435 + for (i = 3, j = 0; i < size; i += 7, j += 8) { 1436 + size_t rem = size - i, num = min_t(size_t, rem, 4); 1437 + 1438 + value = tegra_sor_hdmi_subpack(&ptr[i], num); 1439 + tegra_sor_writel(sor, value, offset++); 1440 + 1441 + num = min_t(size_t, rem - num, 3); 1442 + 1443 + value = tegra_sor_hdmi_subpack(&ptr[i + 4], num); 1444 + tegra_sor_writel(sor, value, offset++); 1445 + } 1446 + } 1447 + 1448 + static int 1449 + tegra_sor_hdmi_setup_avi_infoframe(struct tegra_sor *sor, 1450 + const struct drm_display_mode *mode) 1451 + { 1452 + u8 buffer[HDMI_INFOFRAME_SIZE(AVI)]; 1453 + struct hdmi_avi_infoframe frame; 1454 + u32 value; 1455 + int err; 1456 + 1457 + /* disable AVI infoframe */ 1458 + value = tegra_sor_readl(sor, SOR_HDMI_AVI_INFOFRAME_CTRL); 1459 + value &= ~INFOFRAME_CTRL_SINGLE; 1460 + value &= ~INFOFRAME_CTRL_OTHER; 1461 + value &= ~INFOFRAME_CTRL_ENABLE; 1462 + tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL); 1463 + 1464 + err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode); 1465 + if (err < 0) { 1466 + dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err); 1467 + return err; 1468 + } 1469 + 1470 + err = hdmi_avi_infoframe_pack(&frame, buffer, sizeof(buffer)); 1471 + if (err < 0) { 1472 + dev_err(sor->dev, "failed to pack AVI infoframe: %d\n", err); 1473 + return err; 1474 + } 1475 + 1476 + tegra_sor_hdmi_write_infopack(sor, buffer, err); 1477 + 1478 + /* enable AVI infoframe */ 1479 + value = tegra_sor_readl(sor, SOR_HDMI_AVI_INFOFRAME_CTRL); 1480 + value |= INFOFRAME_CTRL_CHECKSUM_ENABLE; 1481 + value |= INFOFRAME_CTRL_ENABLE; 1482 + tegra_sor_writel(sor, value, SOR_HDMI_AVI_INFOFRAME_CTRL); 1483 + 1484 + return 0; 1485 + } 1486 + 1487 + static void tegra_sor_hdmi_disable_audio_infoframe(struct tegra_sor *sor) 1488 + { 1489 + u32 value; 1490 + 1491 + value = tegra_sor_readl(sor, SOR_HDMI_AUDIO_INFOFRAME_CTRL); 1492 + value &= ~INFOFRAME_CTRL_ENABLE; 1493 + tegra_sor_writel(sor, value, SOR_HDMI_AUDIO_INFOFRAME_CTRL); 1494 + } 1495 + 1496 + static struct tegra_sor_hdmi_settings * 1497 + tegra_sor_hdmi_find_settings(struct tegra_sor *sor, unsigned long frequency) 1498 + { 1499 + unsigned int i; 1500 + 1501 + for (i = 0; i < sor->num_settings; i++) 1502 + if (frequency <= sor->settings[i].frequency) 1503 + return &sor->settings[i]; 1504 + 1505 + return NULL; 1506 + } 1507 + 1508 + static void tegra_sor_hdmi_disable(struct drm_encoder *encoder) 1509 + { 1510 + struct tegra_output *output = encoder_to_output(encoder); 1511 + struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 1512 + struct tegra_sor *sor = to_sor(output); 1513 + u32 value; 1514 + int err; 1515 + 1516 + err = tegra_sor_detach(sor); 1517 + if (err < 0) 1518 + dev_err(sor->dev, "failed to detach SOR: %d\n", err); 1519 + 1520 + tegra_sor_writel(sor, 0, SOR_STATE1); 1521 + tegra_sor_update(sor); 1522 + 1523 + /* disable display to SOR clock */ 1524 + value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); 1525 + value &= ~SOR1_TIMING_CYA; 1526 + value &= ~SOR1_ENABLE; 1527 + tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); 1528 + 1529 + tegra_dc_commit(dc); 1530 + 1531 + err = tegra_sor_power_down(sor); 1532 + if (err < 0) 1533 + dev_err(sor->dev, "failed to power down SOR: %d\n", err); 1534 + 1535 + err = tegra_io_rail_power_off(TEGRA_IO_RAIL_HDMI); 1536 + if (err < 0) 1537 + dev_err(sor->dev, "failed to power off HDMI rail: %d\n", err); 1538 + 1539 + reset_control_assert(sor->rst); 1540 + usleep_range(1000, 2000); 1541 + clk_disable_unprepare(sor->clk); 1542 + } 1543 + 1544 + static void tegra_sor_hdmi_enable(struct drm_encoder *encoder) 1545 + { 1546 + struct tegra_output *output = encoder_to_output(encoder); 1547 + unsigned int h_ref_to_sync = 1, pulse_start, max_ac; 1548 + struct tegra_dc *dc = to_tegra_dc(encoder->crtc); 1549 + unsigned int vbe, vse, hbe, hse, vbs, hbs, div; 1550 + struct tegra_sor_hdmi_settings *settings; 1551 + struct tegra_sor *sor = to_sor(output); 1552 + struct drm_display_mode *mode; 1553 + struct drm_display_info *info; 1554 + u32 value; 1555 + int err; 1556 + 1557 + mode = &encoder->crtc->state->adjusted_mode; 1558 + info = &output->connector.display_info; 1559 + 1560 + err = clk_prepare_enable(sor->clk); 1561 + if (err < 0) 1562 + dev_err(sor->dev, "failed to enable clock: %d\n", err); 1563 + 1564 + usleep_range(1000, 2000); 1565 + 1566 + reset_control_deassert(sor->rst); 1567 + 1568 + err = clk_set_parent(sor->clk, sor->clk_safe); 1569 + if (err < 0) 1570 + dev_err(sor->dev, "failed to set safe parent clock: %d\n", err); 1571 + 1572 + div = clk_get_rate(sor->clk) / 1000000 * 4; 1573 + 1574 + err = tegra_io_rail_power_on(TEGRA_IO_RAIL_HDMI); 1575 + if (err < 0) 1576 + dev_err(sor->dev, "failed to power on HDMI rail: %d\n", err); 1577 + 1578 + usleep_range(20, 100); 1579 + 1580 + value = tegra_sor_readl(sor, SOR_PLL2); 1581 + value &= ~SOR_PLL2_BANDGAP_POWERDOWN; 1582 + tegra_sor_writel(sor, value, SOR_PLL2); 1583 + 1584 + usleep_range(20, 100); 1585 + 1586 + value = tegra_sor_readl(sor, SOR_PLL3); 1587 + value &= ~SOR_PLL3_PLL_VDD_MODE_3V3; 1588 + tegra_sor_writel(sor, value, SOR_PLL3); 1589 + 1590 + value = tegra_sor_readl(sor, SOR_PLL0); 1591 + value &= ~SOR_PLL0_VCOPD; 1592 + value &= ~SOR_PLL0_PWR; 1593 + tegra_sor_writel(sor, value, SOR_PLL0); 1594 + 1595 + value = tegra_sor_readl(sor, SOR_PLL2); 1596 + value &= ~SOR_PLL2_SEQ_PLLCAPPD_ENFORCE; 1597 + tegra_sor_writel(sor, value, SOR_PLL2); 1598 + 1599 + usleep_range(200, 400); 1600 + 1601 + value = tegra_sor_readl(sor, SOR_PLL2); 1602 + value &= ~SOR_PLL2_POWERDOWN_OVERRIDE; 1603 + value &= ~SOR_PLL2_PORT_POWERDOWN; 1604 + tegra_sor_writel(sor, value, SOR_PLL2); 1605 + 1606 + usleep_range(20, 100); 1607 + 1608 + value = tegra_sor_readl(sor, SOR_DP_PADCTL0); 1609 + value |= SOR_DP_PADCTL_PD_TXD_3 | SOR_DP_PADCTL_PD_TXD_0 | 1610 + SOR_DP_PADCTL_PD_TXD_1 | SOR_DP_PADCTL_PD_TXD_2; 1611 + tegra_sor_writel(sor, value, SOR_DP_PADCTL0); 1612 + 1613 + while (true) { 1614 + value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL); 1615 + if ((value & SOR_LANE_SEQ_CTL_STATE_BUSY) == 0) 1616 + break; 1617 + 1618 + usleep_range(250, 1000); 1619 + } 1620 + 1621 + value = SOR_LANE_SEQ_CTL_TRIGGER | SOR_LANE_SEQ_CTL_SEQUENCE_DOWN | 1622 + SOR_LANE_SEQ_CTL_POWER_STATE_UP | SOR_LANE_SEQ_CTL_DELAY(5); 1623 + tegra_sor_writel(sor, value, SOR_LANE_SEQ_CTL); 1624 + 1625 + while (true) { 1626 + value = tegra_sor_readl(sor, SOR_LANE_SEQ_CTL); 1627 + if ((value & SOR_LANE_SEQ_CTL_TRIGGER) == 0) 1628 + break; 1629 + 1630 + usleep_range(250, 1000); 1631 + } 1632 + 1633 + value = tegra_sor_readl(sor, SOR_CLK_CNTRL); 1634 + value &= ~SOR_CLK_CNTRL_DP_LINK_SPEED_MASK; 1635 + value &= ~SOR_CLK_CNTRL_DP_CLK_SEL_MASK; 1636 + 1637 + if (mode->clock < 340000) 1638 + value |= SOR_CLK_CNTRL_DP_LINK_SPEED_G2_70; 1639 + else 1640 + value |= SOR_CLK_CNTRL_DP_LINK_SPEED_G5_40; 1641 + 1642 + value |= SOR_CLK_CNTRL_DP_CLK_SEL_SINGLE_PCLK; 1643 + tegra_sor_writel(sor, value, SOR_CLK_CNTRL); 1644 + 1645 + value = tegra_sor_readl(sor, SOR_DP_SPARE0); 1646 + value |= SOR_DP_SPARE_DISP_VIDEO_PREAMBLE; 1647 + value &= ~SOR_DP_SPARE_PANEL_INTERNAL; 1648 + value |= SOR_DP_SPARE_SEQ_ENABLE; 1649 + tegra_sor_writel(sor, value, SOR_DP_SPARE0); 1650 + 1651 + value = SOR_SEQ_CTL_PU_PC(0) | SOR_SEQ_CTL_PU_PC_ALT(0) | 1652 + SOR_SEQ_CTL_PD_PC(8) | SOR_SEQ_CTL_PD_PC_ALT(8); 1653 + tegra_sor_writel(sor, value, SOR_SEQ_CTL); 1654 + 1655 + value = SOR_SEQ_INST_DRIVE_PWM_OUT_LO | SOR_SEQ_INST_HALT | 1656 + SOR_SEQ_INST_WAIT_VSYNC | SOR_SEQ_INST_WAIT(1); 1657 + tegra_sor_writel(sor, value, SOR_SEQ_INST(0)); 1658 + tegra_sor_writel(sor, value, SOR_SEQ_INST(8)); 1659 + 1660 + /* program the reference clock */ 1661 + value = SOR_REFCLK_DIV_INT(div) | SOR_REFCLK_DIV_FRAC(div); 1662 + tegra_sor_writel(sor, value, SOR_REFCLK); 1663 + 1664 + /* XXX don't hardcode */ 1665 + value = SOR_XBAR_CTRL_LINK1_XSEL(4, 4) | 1666 + SOR_XBAR_CTRL_LINK1_XSEL(3, 3) | 1667 + SOR_XBAR_CTRL_LINK1_XSEL(2, 2) | 1668 + SOR_XBAR_CTRL_LINK1_XSEL(1, 1) | 1669 + SOR_XBAR_CTRL_LINK1_XSEL(0, 0) | 1670 + SOR_XBAR_CTRL_LINK0_XSEL(4, 4) | 1671 + SOR_XBAR_CTRL_LINK0_XSEL(3, 3) | 1672 + SOR_XBAR_CTRL_LINK0_XSEL(2, 0) | 1673 + SOR_XBAR_CTRL_LINK0_XSEL(1, 1) | 1674 + SOR_XBAR_CTRL_LINK0_XSEL(0, 2); 1675 + tegra_sor_writel(sor, value, SOR_XBAR_CTRL); 1676 + 1677 + tegra_sor_writel(sor, 0x00000000, SOR_XBAR_POL); 1678 + 1679 + err = clk_set_parent(sor->clk, sor->clk_parent); 1680 + if (err < 0) 1681 + dev_err(sor->dev, "failed to set parent clock: %d\n", err); 1682 + 1683 + value = SOR_INPUT_CONTROL_HDMI_SRC_SELECT(dc->pipe); 1684 + 1685 + /* XXX is this the proper check? */ 1686 + if (mode->clock < 75000) 1687 + value |= SOR_INPUT_CONTROL_ARM_VIDEO_RANGE_LIMITED; 1688 + 1689 + tegra_sor_writel(sor, value, SOR_INPUT_CONTROL); 1690 + 1691 + max_ac = ((mode->htotal - mode->hdisplay) - SOR_REKEY - 18) / 32; 1692 + 1693 + value = SOR_HDMI_CTRL_ENABLE | SOR_HDMI_CTRL_MAX_AC_PACKET(max_ac) | 1694 + SOR_HDMI_CTRL_AUDIO_LAYOUT | SOR_HDMI_CTRL_REKEY(SOR_REKEY); 1695 + tegra_sor_writel(sor, value, SOR_HDMI_CTRL); 1696 + 1697 + /* H_PULSE2 setup */ 1698 + pulse_start = h_ref_to_sync + (mode->hsync_end - mode->hsync_start) + 1699 + (mode->htotal - mode->hsync_end) - 10; 1700 + 1701 + value = PULSE_LAST_END_A | PULSE_QUAL_VACTIVE | 1702 + PULSE_POLARITY_HIGH | PULSE_MODE_NORMAL; 1703 + tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_CONTROL); 1704 + 1705 + value = PULSE_END(pulse_start + 8) | PULSE_START(pulse_start); 1706 + tegra_dc_writel(dc, value, DC_DISP_H_PULSE2_POSITION_A); 1707 + 1708 + value = tegra_dc_readl(dc, DC_DISP_DISP_SIGNAL_OPTIONS0); 1709 + value |= H_PULSE2_ENABLE; 1710 + tegra_dc_writel(dc, value, DC_DISP_DISP_SIGNAL_OPTIONS0); 1711 + 1712 + /* infoframe setup */ 1713 + err = tegra_sor_hdmi_setup_avi_infoframe(sor, mode); 1714 + if (err < 0) 1715 + dev_err(sor->dev, "failed to setup AVI infoframe: %d\n", err); 1716 + 1717 + /* XXX HDMI audio support not implemented yet */ 1718 + tegra_sor_hdmi_disable_audio_infoframe(sor); 1719 + 1720 + /* use single TMDS protocol */ 1721 + value = tegra_sor_readl(sor, SOR_STATE1); 1722 + value &= ~SOR_STATE_ASY_PROTOCOL_MASK; 1723 + value |= SOR_STATE_ASY_PROTOCOL_SINGLE_TMDS_A; 1724 + tegra_sor_writel(sor, value, SOR_STATE1); 1725 + 1726 + /* power up pad calibration */ 1727 + value = tegra_sor_readl(sor, SOR_DP_PADCTL0); 1728 + value &= ~SOR_DP_PADCTL_PAD_CAL_PD; 1729 + tegra_sor_writel(sor, value, SOR_DP_PADCTL0); 1730 + 1731 + /* production settings */ 1732 + settings = tegra_sor_hdmi_find_settings(sor, mode->clock * 1000); 1733 + if (IS_ERR(settings)) { 1734 + dev_err(sor->dev, "no settings for pixel clock %d Hz: %ld\n", 1735 + mode->clock * 1000, PTR_ERR(settings)); 1736 + return; 1737 + } 1738 + 1739 + value = tegra_sor_readl(sor, SOR_PLL0); 1740 + value &= ~SOR_PLL0_ICHPMP_MASK; 1741 + value &= ~SOR_PLL0_VCOCAP_MASK; 1742 + value |= SOR_PLL0_ICHPMP(settings->ichpmp); 1743 + value |= SOR_PLL0_VCOCAP(settings->vcocap); 1744 + tegra_sor_writel(sor, value, SOR_PLL0); 1745 + 1746 + tegra_sor_dp_term_calibrate(sor); 1747 + 1748 + value = tegra_sor_readl(sor, SOR_PLL1); 1749 + value &= ~SOR_PLL1_LOADADJ_MASK; 1750 + value |= SOR_PLL1_LOADADJ(settings->loadadj); 1751 + tegra_sor_writel(sor, value, SOR_PLL1); 1752 + 1753 + value = tegra_sor_readl(sor, SOR_PLL3); 1754 + value &= ~SOR_PLL3_BG_VREF_LEVEL_MASK; 1755 + value |= SOR_PLL3_BG_VREF_LEVEL(settings->bg_vref); 1756 + tegra_sor_writel(sor, value, SOR_PLL3); 1757 + 1758 + value = settings->drive_current[0] << 24 | 1759 + settings->drive_current[1] << 16 | 1760 + settings->drive_current[2] << 8 | 1761 + settings->drive_current[3] << 0; 1762 + tegra_sor_writel(sor, value, SOR_LANE_DRIVE_CURRENT0); 1763 + 1764 + value = settings->preemphasis[0] << 24 | 1765 + settings->preemphasis[1] << 16 | 1766 + settings->preemphasis[2] << 8 | 1767 + settings->preemphasis[3] << 0; 1768 + tegra_sor_writel(sor, value, SOR_LANE_PREEMPHASIS0); 1769 + 1770 + value = tegra_sor_readl(sor, SOR_DP_PADCTL0); 1771 + value &= ~SOR_DP_PADCTL_TX_PU_MASK; 1772 + value |= SOR_DP_PADCTL_TX_PU_ENABLE; 1773 + value |= SOR_DP_PADCTL_TX_PU(settings->tx_pu); 1774 + tegra_sor_writel(sor, value, SOR_DP_PADCTL0); 1775 + 1776 + /* power down pad calibration */ 1777 + value = tegra_sor_readl(sor, SOR_DP_PADCTL0); 1778 + value |= SOR_DP_PADCTL_PAD_CAL_PD; 1779 + tegra_sor_writel(sor, value, SOR_DP_PADCTL0); 1780 + 1781 + /* miscellaneous display controller settings */ 1782 + value = VSYNC_H_POSITION(1); 1783 + tegra_dc_writel(dc, value, DC_DISP_DISP_TIMING_OPTIONS); 1784 + 1785 + value = tegra_dc_readl(dc, DC_DISP_DISP_COLOR_CONTROL); 1786 + value &= ~DITHER_CONTROL_MASK; 1787 + value &= ~BASE_COLOR_SIZE_MASK; 1788 + 1789 + switch (info->bpc) { 1790 + case 6: 1791 + value |= BASE_COLOR_SIZE_666; 1792 + break; 1793 + 1794 + case 8: 1795 + value |= BASE_COLOR_SIZE_888; 1796 + break; 1797 + 1798 + default: 1799 + WARN(1, "%u bits-per-color not supported\n", info->bpc); 1800 + break; 1801 + } 1802 + 1803 + tegra_dc_writel(dc, value, DC_DISP_DISP_COLOR_CONTROL); 1804 + 1805 + err = tegra_sor_power_up(sor, 250); 1806 + if (err < 0) 1807 + dev_err(sor->dev, "failed to power up SOR: %d\n", err); 1808 + 1809 + /* configure mode */ 1810 + value = tegra_sor_readl(sor, SOR_STATE1); 1811 + value &= ~SOR_STATE_ASY_PIXELDEPTH_MASK; 1812 + value &= ~SOR_STATE_ASY_CRC_MODE_MASK; 1813 + value &= ~SOR_STATE_ASY_OWNER_MASK; 1814 + 1815 + value |= SOR_STATE_ASY_CRC_MODE_COMPLETE | 1816 + SOR_STATE_ASY_OWNER(dc->pipe + 1); 1817 + 1818 + if (mode->flags & DRM_MODE_FLAG_PHSYNC) 1819 + value &= ~SOR_STATE_ASY_HSYNCPOL; 1820 + 1821 + if (mode->flags & DRM_MODE_FLAG_NHSYNC) 1822 + value |= SOR_STATE_ASY_HSYNCPOL; 1823 + 1824 + if (mode->flags & DRM_MODE_FLAG_PVSYNC) 1825 + value &= ~SOR_STATE_ASY_VSYNCPOL; 1826 + 1827 + if (mode->flags & DRM_MODE_FLAG_NVSYNC) 1828 + value |= SOR_STATE_ASY_VSYNCPOL; 1829 + 1830 + switch (info->bpc) { 1831 + case 8: 1832 + value |= SOR_STATE_ASY_PIXELDEPTH_BPP_24_444; 1833 + break; 1834 + 1835 + case 6: 1836 + value |= SOR_STATE_ASY_PIXELDEPTH_BPP_18_444; 1837 + break; 1838 + 1839 + default: 1840 + BUG(); 1841 + break; 1842 + } 1843 + 1844 + tegra_sor_writel(sor, value, SOR_STATE1); 1845 + 1846 + value = tegra_sor_readl(sor, SOR_HEAD_STATE0(dc->pipe)); 1847 + value &= ~SOR_HEAD_STATE_RANGECOMPRESS_MASK; 1848 + value &= ~SOR_HEAD_STATE_DYNRANGE_MASK; 1849 + tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe)); 1850 + 1851 + value = tegra_sor_readl(sor, SOR_HEAD_STATE0(dc->pipe)); 1852 + value &= ~SOR_HEAD_STATE_COLORSPACE_MASK; 1853 + value |= SOR_HEAD_STATE_COLORSPACE_RGB; 1854 + tegra_sor_writel(sor, value, SOR_HEAD_STATE0(dc->pipe)); 1855 + 1856 + /* 1857 + * TODO: The video timing programming below doesn't seem to match the 1858 + * register definitions. 1859 + */ 1860 + 1861 + value = ((mode->vtotal & 0x7fff) << 16) | (mode->htotal & 0x7fff); 1862 + tegra_sor_writel(sor, value, SOR_HEAD_STATE1(dc->pipe)); 1863 + 1864 + /* sync end = sync width - 1 */ 1865 + vse = mode->vsync_end - mode->vsync_start - 1; 1866 + hse = mode->hsync_end - mode->hsync_start - 1; 1867 + 1868 + value = ((vse & 0x7fff) << 16) | (hse & 0x7fff); 1869 + tegra_sor_writel(sor, value, SOR_HEAD_STATE2(dc->pipe)); 1870 + 1871 + /* blank end = sync end + back porch */ 1872 + vbe = vse + (mode->vtotal - mode->vsync_end); 1873 + hbe = hse + (mode->htotal - mode->hsync_end); 1874 + 1875 + value = ((vbe & 0x7fff) << 16) | (hbe & 0x7fff); 1876 + tegra_sor_writel(sor, value, SOR_HEAD_STATE3(dc->pipe)); 1877 + 1878 + /* blank start = blank end + active */ 1879 + vbs = vbe + mode->vdisplay; 1880 + hbs = hbe + mode->hdisplay; 1881 + 1882 + value = ((vbs & 0x7fff) << 16) | (hbs & 0x7fff); 1883 + tegra_sor_writel(sor, value, SOR_HEAD_STATE4(dc->pipe)); 1884 + 1885 + tegra_sor_writel(sor, 0x1, SOR_HEAD_STATE5(dc->pipe)); 1886 + 1887 + tegra_sor_update(sor); 1888 + 1889 + err = tegra_sor_attach(sor); 1890 + if (err < 0) 1891 + dev_err(sor->dev, "failed to attach SOR: %d\n", err); 1892 + 1893 + /* enable display to SOR clock and generate HDMI preamble */ 1894 + value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS); 1895 + value |= SOR1_ENABLE | SOR1_TIMING_CYA; 1896 + tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS); 1897 + 1898 + tegra_dc_commit(dc); 1899 + 1900 + err = tegra_sor_wakeup(sor); 1901 + if (err < 0) 1902 + dev_err(sor->dev, "failed to wakeup SOR: %d\n", err); 1903 + } 1904 + 1905 + static const struct drm_encoder_helper_funcs tegra_sor_hdmi_helpers = { 1906 + .disable = tegra_sor_hdmi_disable, 1907 + .enable = tegra_sor_hdmi_enable, 1614 1908 .atomic_check = tegra_sor_encoder_atomic_check, 1615 1909 }; 1616 1910 1617 1911 static int tegra_sor_init(struct host1x_client *client) 1618 1912 { 1619 1913 struct drm_device *drm = dev_get_drvdata(client->parent); 1914 + const struct drm_encoder_helper_funcs *helpers = NULL; 1620 1915 struct tegra_sor *sor = host1x_client_to_sor(client); 1916 + int connector = DRM_MODE_CONNECTOR_Unknown; 1917 + int encoder = DRM_MODE_ENCODER_NONE; 1621 1918 int err; 1622 1919 1623 - if (!sor->dpaux) 1624 - return -ENODEV; 1920 + if (!sor->dpaux) { 1921 + if (sor->soc->supports_hdmi) { 1922 + connector = DRM_MODE_CONNECTOR_HDMIA; 1923 + encoder = DRM_MODE_ENCODER_TMDS; 1924 + helpers = &tegra_sor_hdmi_helpers; 1925 + } else if (sor->soc->supports_lvds) { 1926 + connector = DRM_MODE_CONNECTOR_LVDS; 1927 + encoder = DRM_MODE_ENCODER_LVDS; 1928 + } 1929 + } else { 1930 + if (sor->soc->supports_edp) { 1931 + connector = DRM_MODE_CONNECTOR_eDP; 1932 + encoder = DRM_MODE_ENCODER_TMDS; 1933 + helpers = &tegra_sor_edp_helpers; 1934 + } else if (sor->soc->supports_dp) { 1935 + connector = DRM_MODE_CONNECTOR_DisplayPort; 1936 + encoder = DRM_MODE_ENCODER_TMDS; 1937 + } 1938 + } 1625 1939 1626 1940 sor->output.dev = sor->dev; 1627 1941 1628 1942 drm_connector_init(drm, &sor->output.connector, 1629 1943 &tegra_sor_connector_funcs, 1630 - DRM_MODE_CONNECTOR_eDP); 1944 + connector); 1631 1945 drm_connector_helper_add(&sor->output.connector, 1632 1946 &tegra_sor_connector_helper_funcs); 1633 1947 sor->output.connector.dpms = DRM_MODE_DPMS_OFF; 1634 1948 1635 1949 drm_encoder_init(drm, &sor->output.encoder, &tegra_sor_encoder_funcs, 1636 - DRM_MODE_ENCODER_TMDS); 1637 - drm_encoder_helper_add(&sor->output.encoder, 1638 - &tegra_sor_edp_helper_funcs); 1950 + encoder); 1951 + drm_encoder_helper_add(&sor->output.encoder, helpers); 1639 1952 1640 1953 drm_mode_connector_attach_encoder(&sor->output.connector, 1641 1954 &sor->output.encoder); ··· 2272 1497 .exit = tegra_sor_exit, 2273 1498 }; 2274 1499 1500 + static const struct tegra_sor_ops tegra_sor_edp_ops = { 1501 + .name = "eDP", 1502 + }; 1503 + 1504 + static int tegra_sor_hdmi_probe(struct tegra_sor *sor) 1505 + { 1506 + int err; 1507 + 1508 + sor->avdd_io_supply = devm_regulator_get(sor->dev, "avdd-io"); 1509 + if (IS_ERR(sor->avdd_io_supply)) { 1510 + dev_err(sor->dev, "cannot get AVDD I/O supply: %ld\n", 1511 + PTR_ERR(sor->avdd_io_supply)); 1512 + return PTR_ERR(sor->avdd_io_supply); 1513 + } 1514 + 1515 + err = regulator_enable(sor->avdd_io_supply); 1516 + if (err < 0) { 1517 + dev_err(sor->dev, "failed to enable AVDD I/O supply: %d\n", 1518 + err); 1519 + return err; 1520 + } 1521 + 1522 + sor->vdd_pll_supply = devm_regulator_get(sor->dev, "vdd-pll"); 1523 + if (IS_ERR(sor->vdd_pll_supply)) { 1524 + dev_err(sor->dev, "cannot get VDD PLL supply: %ld\n", 1525 + PTR_ERR(sor->vdd_pll_supply)); 1526 + return PTR_ERR(sor->vdd_pll_supply); 1527 + } 1528 + 1529 + err = regulator_enable(sor->vdd_pll_supply); 1530 + if (err < 0) { 1531 + dev_err(sor->dev, "failed to enable VDD PLL supply: %d\n", 1532 + err); 1533 + return err; 1534 + } 1535 + 1536 + sor->hdmi_supply = devm_regulator_get(sor->dev, "hdmi"); 1537 + if (IS_ERR(sor->hdmi_supply)) { 1538 + dev_err(sor->dev, "cannot get HDMI supply: %ld\n", 1539 + PTR_ERR(sor->hdmi_supply)); 1540 + return PTR_ERR(sor->hdmi_supply); 1541 + } 1542 + 1543 + err = regulator_enable(sor->hdmi_supply); 1544 + if (err < 0) { 1545 + dev_err(sor->dev, "failed to enable HDMI supply: %d\n", err); 1546 + return err; 1547 + } 1548 + 1549 + return 0; 1550 + } 1551 + 1552 + static int tegra_sor_hdmi_remove(struct tegra_sor *sor) 1553 + { 1554 + regulator_disable(sor->hdmi_supply); 1555 + regulator_disable(sor->vdd_pll_supply); 1556 + regulator_disable(sor->avdd_io_supply); 1557 + 1558 + return 0; 1559 + } 1560 + 1561 + static const struct tegra_sor_ops tegra_sor_hdmi_ops = { 1562 + .name = "HDMI", 1563 + .probe = tegra_sor_hdmi_probe, 1564 + .remove = tegra_sor_hdmi_remove, 1565 + }; 1566 + 1567 + static const struct tegra_sor_soc tegra124_sor = { 1568 + .supports_edp = true, 1569 + .supports_lvds = true, 1570 + .supports_hdmi = false, 1571 + .supports_dp = false, 1572 + }; 1573 + 1574 + static const struct tegra_sor_soc tegra210_sor = { 1575 + .supports_edp = true, 1576 + .supports_lvds = false, 1577 + .supports_hdmi = false, 1578 + .supports_dp = false, 1579 + }; 1580 + 1581 + static const struct tegra_sor_soc tegra210_sor1 = { 1582 + .supports_edp = false, 1583 + .supports_lvds = false, 1584 + .supports_hdmi = true, 1585 + .supports_dp = true, 1586 + 1587 + .num_settings = ARRAY_SIZE(tegra210_sor_hdmi_defaults), 1588 + .settings = tegra210_sor_hdmi_defaults, 1589 + }; 1590 + 1591 + static const struct of_device_id tegra_sor_of_match[] = { 1592 + { .compatible = "nvidia,tegra210-sor1", .data = &tegra210_sor1 }, 1593 + { .compatible = "nvidia,tegra210-sor", .data = &tegra210_sor }, 1594 + { .compatible = "nvidia,tegra124-sor", .data = &tegra124_sor }, 1595 + { }, 1596 + }; 1597 + MODULE_DEVICE_TABLE(of, tegra_sor_of_match); 1598 + 2275 1599 static int tegra_sor_probe(struct platform_device *pdev) 2276 1600 { 1601 + const struct of_device_id *match; 2277 1602 struct device_node *np; 2278 1603 struct tegra_sor *sor; 2279 1604 struct resource *regs; 2280 1605 int err; 1606 + 1607 + match = of_match_device(tegra_sor_of_match, &pdev->dev); 2281 1608 2282 1609 sor = devm_kzalloc(&pdev->dev, sizeof(*sor), GFP_KERNEL); 2283 1610 if (!sor) 2284 1611 return -ENOMEM; 2285 1612 2286 1613 sor->output.dev = sor->dev = &pdev->dev; 1614 + sor->soc = match->data; 1615 + 1616 + sor->settings = devm_kmemdup(&pdev->dev, sor->soc->settings, 1617 + sor->soc->num_settings * 1618 + sizeof(*sor->settings), 1619 + GFP_KERNEL); 1620 + if (!sor->settings) 1621 + return -ENOMEM; 1622 + 1623 + sor->num_settings = sor->soc->num_settings; 2287 1624 2288 1625 np = of_parse_phandle(pdev->dev.of_node, "nvidia,dpaux", 0); 2289 1626 if (np) { ··· 2406 1519 return -EPROBE_DEFER; 2407 1520 } 2408 1521 1522 + if (!sor->dpaux) { 1523 + if (sor->soc->supports_hdmi) { 1524 + sor->ops = &tegra_sor_hdmi_ops; 1525 + } else if (sor->soc->supports_lvds) { 1526 + dev_err(&pdev->dev, "LVDS not supported yet\n"); 1527 + return -ENODEV; 1528 + } else { 1529 + dev_err(&pdev->dev, "unknown (non-DP) support\n"); 1530 + return -ENODEV; 1531 + } 1532 + } else { 1533 + if (sor->soc->supports_edp) { 1534 + sor->ops = &tegra_sor_edp_ops; 1535 + } else if (sor->soc->supports_dp) { 1536 + dev_err(&pdev->dev, "DisplayPort not supported yet\n"); 1537 + return -ENODEV; 1538 + } else { 1539 + dev_err(&pdev->dev, "unknown (DP) support\n"); 1540 + return -ENODEV; 1541 + } 1542 + } 1543 + 2409 1544 err = tegra_output_probe(&sor->output); 2410 1545 if (err < 0) { 2411 1546 dev_err(&pdev->dev, "failed to probe output: %d\n", err); 2412 1547 return err; 2413 1548 } 2414 1549 1550 + if (sor->ops && sor->ops->probe) { 1551 + err = sor->ops->probe(sor); 1552 + if (err < 0) { 1553 + dev_err(&pdev->dev, "failed to probe %s: %d\n", 1554 + sor->ops->name, err); 1555 + goto output; 1556 + } 1557 + } 1558 + 2415 1559 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); 2416 1560 sor->regs = devm_ioremap_resource(&pdev->dev, regs); 2417 - if (IS_ERR(sor->regs)) 2418 - return PTR_ERR(sor->regs); 1561 + if (IS_ERR(sor->regs)) { 1562 + err = PTR_ERR(sor->regs); 1563 + goto remove; 1564 + } 2419 1565 2420 1566 sor->rst = devm_reset_control_get(&pdev->dev, "sor"); 2421 1567 if (IS_ERR(sor->rst)) { 2422 - dev_err(&pdev->dev, "failed to get reset control: %ld\n", 2423 - PTR_ERR(sor->rst)); 2424 - return PTR_ERR(sor->rst); 1568 + err = PTR_ERR(sor->rst); 1569 + dev_err(&pdev->dev, "failed to get reset control: %d\n", err); 1570 + goto remove; 2425 1571 } 2426 1572 2427 1573 sor->clk = devm_clk_get(&pdev->dev, NULL); 2428 1574 if (IS_ERR(sor->clk)) { 2429 - dev_err(&pdev->dev, "failed to get module clock: %ld\n", 2430 - PTR_ERR(sor->clk)); 2431 - return PTR_ERR(sor->clk); 1575 + err = PTR_ERR(sor->clk); 1576 + dev_err(&pdev->dev, "failed to get module clock: %d\n", err); 1577 + goto remove; 2432 1578 } 2433 1579 2434 1580 sor->clk_parent = devm_clk_get(&pdev->dev, "parent"); 2435 1581 if (IS_ERR(sor->clk_parent)) { 2436 - dev_err(&pdev->dev, "failed to get parent clock: %ld\n", 2437 - PTR_ERR(sor->clk_parent)); 2438 - return PTR_ERR(sor->clk_parent); 1582 + err = PTR_ERR(sor->clk_parent); 1583 + dev_err(&pdev->dev, "failed to get parent clock: %d\n", err); 1584 + goto remove; 2439 1585 } 2440 1586 2441 1587 sor->clk_safe = devm_clk_get(&pdev->dev, "safe"); 2442 1588 if (IS_ERR(sor->clk_safe)) { 2443 - dev_err(&pdev->dev, "failed to get safe clock: %ld\n", 2444 - PTR_ERR(sor->clk_safe)); 2445 - return PTR_ERR(sor->clk_safe); 1589 + err = PTR_ERR(sor->clk_safe); 1590 + dev_err(&pdev->dev, "failed to get safe clock: %d\n", err); 1591 + goto remove; 2446 1592 } 2447 1593 2448 1594 sor->clk_dp = devm_clk_get(&pdev->dev, "dp"); 2449 1595 if (IS_ERR(sor->clk_dp)) { 2450 - dev_err(&pdev->dev, "failed to get DP clock: %ld\n", 2451 - PTR_ERR(sor->clk_dp)); 2452 - return PTR_ERR(sor->clk_dp); 1596 + err = PTR_ERR(sor->clk_dp); 1597 + dev_err(&pdev->dev, "failed to get DP clock: %d\n", err); 1598 + goto remove; 2453 1599 } 2454 1600 2455 1601 INIT_LIST_HEAD(&sor->client.list); ··· 2493 1573 if (err < 0) { 2494 1574 dev_err(&pdev->dev, "failed to register host1x client: %d\n", 2495 1575 err); 2496 - return err; 1576 + goto remove; 2497 1577 } 2498 1578 2499 1579 platform_set_drvdata(pdev, sor); 2500 1580 2501 1581 return 0; 1582 + 1583 + remove: 1584 + if (sor->ops && sor->ops->remove) 1585 + sor->ops->remove(sor); 1586 + output: 1587 + tegra_output_remove(&sor->output); 1588 + return err; 2502 1589 } 2503 1590 2504 1591 static int tegra_sor_remove(struct platform_device *pdev) ··· 2520 1593 return err; 2521 1594 } 2522 1595 1596 + if (sor->ops && sor->ops->remove) { 1597 + err = sor->ops->remove(sor); 1598 + if (err < 0) 1599 + dev_err(&pdev->dev, "failed to remove SOR: %d\n", err); 1600 + } 1601 + 2523 1602 tegra_output_remove(&sor->output); 2524 1603 2525 1604 return 0; 2526 1605 } 2527 - 2528 - static const struct of_device_id tegra_sor_of_match[] = { 2529 - { .compatible = "nvidia,tegra124-sor", }, 2530 - { .compatible = "nvidia,tegra210-sor", }, 2531 - { }, 2532 - }; 2533 - MODULE_DEVICE_TABLE(of, tegra_sor_of_match); 2534 1606 2535 1607 struct platform_driver tegra_sor_driver = { 2536 1608 .driver = {
+86
drivers/gpu/drm/tegra/sor.h
··· 43 43 #define SOR_STATE_ASY_OWNER(x) (((x) & 0xf) << 0) 44 44 45 45 #define SOR_HEAD_STATE0(x) (0x05 + (x)) 46 + #define SOR_HEAD_STATE_RANGECOMPRESS_MASK (0x1 << 3) 47 + #define SOR_HEAD_STATE_DYNRANGE_MASK (0x1 << 2) 48 + #define SOR_HEAD_STATE_DYNRANGE_VESA (0 << 2) 49 + #define SOR_HEAD_STATE_DYNRANGE_CEA (1 << 2) 50 + #define SOR_HEAD_STATE_COLORSPACE_MASK (0x3 << 0) 51 + #define SOR_HEAD_STATE_COLORSPACE_RGB (0 << 0) 46 52 #define SOR_HEAD_STATE1(x) (0x07 + (x)) 47 53 #define SOR_HEAD_STATE2(x) (0x09 + (x)) 48 54 #define SOR_HEAD_STATE3(x) (0x0b + (x)) ··· 102 96 103 97 #define SOR_PLL1 0x18 104 98 /* XXX: read-only bit? */ 99 + #define SOR_PLL1_LOADADJ_MASK (0xf << 20) 100 + #define SOR_PLL1_LOADADJ(x) (((x) & 0xf) << 20) 105 101 #define SOR_PLL1_TERM_COMPOUT (1 << 15) 102 + #define SOR_PLL1_TMDS_TERMADJ_MASK (0xf << 9) 103 + #define SOR_PLL1_TMDS_TERMADJ(x) (((x) & 0xf) << 9) 106 104 #define SOR_PLL1_TMDS_TERM (1 << 8) 107 105 108 106 #define SOR_PLL2 0x19 ··· 116 106 #define SOR_PLL2_BANDGAP_POWERDOWN (1 << 22) 117 107 #define SOR_PLL2_POWERDOWN_OVERRIDE (1 << 18) 118 108 #define SOR_PLL2_SEQ_PLLCAPPD (1 << 17) 109 + #define SOR_PLL2_SEQ_PLL_PULLDOWN (1 << 16) 119 110 120 111 #define SOR_PLL3 0x1a 112 + #define SOR_PLL3_BG_VREF_LEVEL_MASK (0xf << 24) 113 + #define SOR_PLL3_BG_VREF_LEVEL(x) (((x) & 0xf) << 24) 121 114 #define SOR_PLL3_PLL_VDD_MODE_1V8 (0 << 13) 122 115 #define SOR_PLL3_PLL_VDD_MODE_3V3 (1 << 13) 123 116 124 117 #define SOR_CSTM 0x1b 118 + #define SOR_CSTM_ROTCLK_MASK (0xf << 24) 119 + #define SOR_CSTM_ROTCLK(x) (((x) & 0xf) << 24) 125 120 #define SOR_CSTM_LVDS (1 << 16) 126 121 #define SOR_CSTM_LINK_ACT_B (1 << 15) 127 122 #define SOR_CSTM_LINK_ACT_A (1 << 14) ··· 139 124 #define SOR_CRCB 0x1e 140 125 #define SOR_BLANK 0x1f 141 126 #define SOR_SEQ_CTL 0x20 127 + #define SOR_SEQ_CTL_PD_PC_ALT(x) (((x) & 0xf) << 12) 128 + #define SOR_SEQ_CTL_PD_PC(x) (((x) & 0xf) << 8) 129 + #define SOR_SEQ_CTL_PU_PC_ALT(x) (((x) & 0xf) << 4) 130 + #define SOR_SEQ_CTL_PU_PC(x) (((x) & 0xf) << 0) 142 131 143 132 #define SOR_LANE_SEQ_CTL 0x21 144 133 #define SOR_LANE_SEQ_CTL_TRIGGER (1 << 31) 134 + #define SOR_LANE_SEQ_CTL_STATE_BUSY (1 << 28) 145 135 #define SOR_LANE_SEQ_CTL_SEQUENCE_UP (0 << 20) 146 136 #define SOR_LANE_SEQ_CTL_SEQUENCE_DOWN (1 << 20) 147 137 #define SOR_LANE_SEQ_CTL_POWER_STATE_UP (0 << 16) 148 138 #define SOR_LANE_SEQ_CTL_POWER_STATE_DOWN (1 << 16) 139 + #define SOR_LANE_SEQ_CTL_DELAY(x) (((x) & 0xf) << 12) 149 140 150 141 #define SOR_SEQ_INST(x) (0x22 + (x)) 142 + #define SOR_SEQ_INST_PLL_PULLDOWN (1 << 31) 143 + #define SOR_SEQ_INST_POWERDOWN_MACRO (1 << 30) 144 + #define SOR_SEQ_INST_ASSERT_PLL_RESET (1 << 29) 145 + #define SOR_SEQ_INST_BLANK_V (1 << 28) 146 + #define SOR_SEQ_INST_BLANK_H (1 << 27) 147 + #define SOR_SEQ_INST_BLANK_DE (1 << 26) 148 + #define SOR_SEQ_INST_BLACK_DATA (1 << 25) 149 + #define SOR_SEQ_INST_TRISTATE_IOS (1 << 24) 150 + #define SOR_SEQ_INST_DRIVE_PWM_OUT_LO (1 << 23) 151 + #define SOR_SEQ_INST_PIN_B_LOW (0 << 22) 152 + #define SOR_SEQ_INST_PIN_B_HIGH (1 << 22) 153 + #define SOR_SEQ_INST_PIN_A_LOW (0 << 21) 154 + #define SOR_SEQ_INST_PIN_A_HIGH (1 << 21) 155 + #define SOR_SEQ_INST_SEQUENCE_UP (0 << 19) 156 + #define SOR_SEQ_INST_SEQUENCE_DOWN (1 << 19) 157 + #define SOR_SEQ_INST_LANE_SEQ_STOP (0 << 18) 158 + #define SOR_SEQ_INST_LANE_SEQ_RUN (1 << 18) 159 + #define SOR_SEQ_INST_PORT_POWERDOWN (1 << 17) 160 + #define SOR_SEQ_INST_PLL_POWERDOWN (1 << 16) 161 + #define SOR_SEQ_INST_HALT (1 << 15) 162 + #define SOR_SEQ_INST_WAIT_US (0 << 12) 163 + #define SOR_SEQ_INST_WAIT_MS (1 << 12) 164 + #define SOR_SEQ_INST_WAIT_VSYNC (2 << 12) 165 + #define SOR_SEQ_INST_WAIT(x) (((x) & 0x3ff) << 0) 151 166 152 167 #define SOR_PWM_DIV 0x32 153 168 #define SOR_PWM_DIV_MASK 0xffffff ··· 210 165 #define SOR_TRIG 0x48 211 166 #define SOR_MSCHECK 0x49 212 167 #define SOR_XBAR_CTRL 0x4a 168 + #define SOR_XBAR_CTRL_LINK1_XSEL(channel, value) ((((value) & 0x7) << ((channel) * 3)) << 17) 169 + #define SOR_XBAR_CTRL_LINK0_XSEL(channel, value) ((((value) & 0x7) << ((channel) * 3)) << 2) 170 + #define SOR_XBAR_CTRL_LINK_SWAP (1 << 1) 171 + #define SOR_XBAR_CTRL_BYPASS (1 << 0) 213 172 #define SOR_XBAR_POL 0x4b 214 173 215 174 #define SOR_DP_LINKCTL0 0x4c ··· 286 237 #define SOR_DP_DEBUG1 0x5f 287 238 288 239 #define SOR_DP_SPARE0 0x60 240 + #define SOR_DP_SPARE_DISP_VIDEO_PREAMBLE (1 << 3) 289 241 #define SOR_DP_SPARE_MACRO_SOR_CLK (1 << 2) 290 242 #define SOR_DP_SPARE_PANEL_INTERNAL (1 << 1) 291 243 #define SOR_DP_SPARE_SEQ_ENABLE (1 << 0) ··· 330 280 #define SOR_DP_LQ_CSTM0 0x6f 331 281 #define SOR_DP_LQ_CSTM1 0x70 332 282 #define SOR_DP_LQ_CSTM2 0x71 283 + 284 + #define SOR_HDMI_AUDIO_INFOFRAME_CTRL 0x9a 285 + #define SOR_HDMI_AUDIO_INFOFRAME_STATUS 0x9b 286 + #define SOR_HDMI_AUDIO_INFOFRAME_HEADER 0x9c 287 + 288 + #define SOR_HDMI_AVI_INFOFRAME_CTRL 0x9f 289 + #define INFOFRAME_CTRL_CHECKSUM_ENABLE (1 << 9) 290 + #define INFOFRAME_CTRL_SINGLE (1 << 8) 291 + #define INFOFRAME_CTRL_OTHER (1 << 4) 292 + #define INFOFRAME_CTRL_ENABLE (1 << 0) 293 + 294 + #define SOR_HDMI_AVI_INFOFRAME_STATUS 0xa0 295 + #define INFOFRAME_STATUS_DONE (1 << 0) 296 + 297 + #define SOR_HDMI_AVI_INFOFRAME_HEADER 0xa1 298 + #define INFOFRAME_HEADER_LEN(x) (((x) & 0xff) << 16) 299 + #define INFOFRAME_HEADER_VERSION(x) (((x) & 0xff) << 8) 300 + #define INFOFRAME_HEADER_TYPE(x) (((x) & 0xff) << 0) 301 + 302 + #define SOR_HDMI_CTRL 0xc0 303 + #define SOR_HDMI_CTRL_ENABLE (1 << 30) 304 + #define SOR_HDMI_CTRL_MAX_AC_PACKET(x) (((x) & 0x1f) << 16) 305 + #define SOR_HDMI_CTRL_AUDIO_LAYOUT (1 << 10) 306 + #define SOR_HDMI_CTRL_REKEY(x) (((x) & 0x7f) << 0) 307 + 308 + #define SOR_REFCLK 0xe6 309 + #define SOR_REFCLK_DIV_INT(x) ((((x) >> 2) & 0xff) << 8) 310 + #define SOR_REFCLK_DIV_FRAC(x) (((x) & 0x3) << 6) 311 + 312 + #define SOR_INPUT_CONTROL 0xe8 313 + #define SOR_INPUT_CONTROL_ARM_VIDEO_RANGE_LIMITED (1 << 1) 314 + #define SOR_INPUT_CONTROL_HDMI_SRC_SELECT(x) (((x) & 0x1) << 0) 315 + 316 + #define SOR_HDMI_VSI_INFOFRAME_CTRL 0x123 317 + #define SOR_HDMI_VSI_INFOFRAME_STATUS 0x124 318 + #define SOR_HDMI_VSI_INFOFRAME_HEADER 0x125 333 319 334 320 #endif