diff options
author | Dave Airlie <airlied@redhat.com> | 2009-09-07 06:27:20 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-09-07 06:27:20 -0400 |
commit | 11670d3c93210793562748d83502ecbef4034765 (patch) | |
tree | 9e2c33c6249e26b05a2b5db87d4f4840e9049840 /drivers/gpu/drm/i915/intel_sdvo.c | |
parent | 575dc34ee0de867ba83abf25998e0963bff451fa (diff) | |
parent | 01dfba93d9dfcf6d7abfc55ff5d9d6e76fa01ba0 (diff) |
Merge intel drm-intel-next branch
Merge remote branch 'anholt/drm-intel-next' of ../anholt-2.6 into drm-next
Conflicts:
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_sdvo.c
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 307 |
1 files changed, 238 insertions, 69 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 91238f0c39a5..0bf28efcf2c1 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -37,6 +37,19 @@ | |||
37 | #include "intel_sdvo_regs.h" | 37 | #include "intel_sdvo_regs.h" |
38 | 38 | ||
39 | #undef SDVO_DEBUG | 39 | #undef SDVO_DEBUG |
40 | |||
41 | static char *tv_format_names[] = { | ||
42 | "NTSC_M" , "NTSC_J" , "NTSC_443", | ||
43 | "PAL_B" , "PAL_D" , "PAL_G" , | ||
44 | "PAL_H" , "PAL_I" , "PAL_M" , | ||
45 | "PAL_N" , "PAL_NC" , "PAL_60" , | ||
46 | "SECAM_B" , "SECAM_D" , "SECAM_G" , | ||
47 | "SECAM_K" , "SECAM_K1", "SECAM_L" , | ||
48 | "SECAM_60" | ||
49 | }; | ||
50 | |||
51 | #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) | ||
52 | |||
40 | struct intel_sdvo_priv { | 53 | struct intel_sdvo_priv { |
41 | u8 slave_addr; | 54 | u8 slave_addr; |
42 | 55 | ||
@@ -70,6 +83,15 @@ struct intel_sdvo_priv { | |||
70 | */ | 83 | */ |
71 | bool is_tv; | 84 | bool is_tv; |
72 | 85 | ||
86 | /* This is for current tv format name */ | ||
87 | char *tv_format_name; | ||
88 | |||
89 | /* This contains all current supported TV format */ | ||
90 | char *tv_format_supported[TV_FORMAT_NUM]; | ||
91 | int format_supported_num; | ||
92 | struct drm_property *tv_format_property; | ||
93 | struct drm_property *tv_format_name_property[TV_FORMAT_NUM]; | ||
94 | |||
73 | /** | 95 | /** |
74 | * This is set if we treat the device as HDMI, instead of DVI. | 96 | * This is set if we treat the device as HDMI, instead of DVI. |
75 | */ | 97 | */ |
@@ -96,14 +118,6 @@ struct intel_sdvo_priv { | |||
96 | */ | 118 | */ |
97 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; | 119 | struct intel_sdvo_sdtv_resolution_reply sdtv_resolutions; |
98 | 120 | ||
99 | /** | ||
100 | * Current selected TV format. | ||
101 | * | ||
102 | * This is stored in the same structure that's passed to the device, for | ||
103 | * convenience. | ||
104 | */ | ||
105 | struct intel_sdvo_tv_format tv_format; | ||
106 | |||
107 | /* | 121 | /* |
108 | * supported encoding mode, used to determine whether HDMI is | 122 | * supported encoding mode, used to determine whether HDMI is |
109 | * supported | 123 | * supported |
@@ -113,6 +127,9 @@ struct intel_sdvo_priv { | |||
113 | /* DDC bus used by this SDVO output */ | 127 | /* DDC bus used by this SDVO output */ |
114 | uint8_t ddc_bus; | 128 | uint8_t ddc_bus; |
115 | 129 | ||
130 | /* Mac mini hack -- use the same DDC as the analog connector */ | ||
131 | struct i2c_adapter *analog_ddc_bus; | ||
132 | |||
116 | int save_sdvo_mult; | 133 | int save_sdvo_mult; |
117 | u16 save_active_outputs; | 134 | u16 save_active_outputs; |
118 | struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; | 135 | struct intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; |
@@ -944,23 +961,28 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output, | |||
944 | 961 | ||
945 | static void intel_sdvo_set_tv_format(struct intel_output *output) | 962 | static void intel_sdvo_set_tv_format(struct intel_output *output) |
946 | { | 963 | { |
964 | |||
965 | struct intel_sdvo_tv_format format; | ||
947 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 966 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; |
948 | struct intel_sdvo_tv_format *format, unset; | 967 | uint32_t format_map, i; |
949 | u8 status; | 968 | uint8_t status; |
950 | 969 | ||
951 | format = &sdvo_priv->tv_format; | 970 | for (i = 0; i < TV_FORMAT_NUM; i++) |
952 | memset(&unset, 0, sizeof(unset)); | 971 | if (tv_format_names[i] == sdvo_priv->tv_format_name) |
953 | if (memcmp(format, &unset, sizeof(*format))) { | 972 | break; |
954 | DRM_DEBUG_KMS("%s: Choosing default TV format of NTSC-M\n", | 973 | |
955 | SDVO_NAME(sdvo_priv)); | 974 | format_map = 1 << i; |
956 | format->ntsc_m = 1; | 975 | memset(&format, 0, sizeof(format)); |
957 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format, | 976 | memcpy(&format, &format_map, sizeof(format_map) > sizeof(format) ? |
958 | sizeof(*format)); | 977 | sizeof(format) : sizeof(format_map)); |
959 | status = intel_sdvo_read_response(output, NULL, 0); | 978 | |
960 | if (status != SDVO_CMD_STATUS_SUCCESS) | 979 | intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, &format_map, |
961 | DRM_DEBUG_KMS("%s: Failed to set TV format\n", | 980 | sizeof(format)); |
962 | SDVO_NAME(sdvo_priv)); | 981 | |
963 | } | 982 | status = intel_sdvo_read_response(output, NULL, 0); |
983 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
984 | DRM_DEBUG("%s: Failed to set TV format\n", | ||
985 | SDVO_NAME(sdvo_priv)); | ||
964 | } | 986 | } |
965 | 987 | ||
966 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, | 988 | static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder, |
@@ -1457,7 +1479,7 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output) | |||
1457 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) | 1479 | (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)) |
1458 | caps++; | 1480 | caps++; |
1459 | if (sdvo_priv->caps.output_flags & | 1481 | if (sdvo_priv->caps.output_flags & |
1460 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID0)) | 1482 | (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_SVID1)) |
1461 | caps++; | 1483 | caps++; |
1462 | if (sdvo_priv->caps.output_flags & | 1484 | if (sdvo_priv->caps.output_flags & |
1463 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) | 1485 | (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_CVBS1)) |
@@ -1477,6 +1499,36 @@ intel_sdvo_multifunc_encoder(struct intel_output *intel_output) | |||
1477 | return (caps > 1); | 1499 | return (caps > 1); |
1478 | } | 1500 | } |
1479 | 1501 | ||
1502 | static struct drm_connector * | ||
1503 | intel_find_analog_connector(struct drm_device *dev) | ||
1504 | { | ||
1505 | struct drm_connector *connector; | ||
1506 | struct intel_output *intel_output; | ||
1507 | |||
1508 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
1509 | intel_output = to_intel_output(connector); | ||
1510 | if (intel_output->type == INTEL_OUTPUT_ANALOG) | ||
1511 | return connector; | ||
1512 | } | ||
1513 | return NULL; | ||
1514 | } | ||
1515 | |||
1516 | static int | ||
1517 | intel_analog_is_connected(struct drm_device *dev) | ||
1518 | { | ||
1519 | struct drm_connector *analog_connector; | ||
1520 | analog_connector = intel_find_analog_connector(dev); | ||
1521 | |||
1522 | if (!analog_connector) | ||
1523 | return false; | ||
1524 | |||
1525 | if (analog_connector->funcs->detect(analog_connector) == | ||
1526 | connector_status_disconnected) | ||
1527 | return false; | ||
1528 | |||
1529 | return true; | ||
1530 | } | ||
1531 | |||
1480 | enum drm_connector_status | 1532 | enum drm_connector_status |
1481 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | 1533 | intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) |
1482 | { | 1534 | { |
@@ -1487,6 +1539,15 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector, u16 response) | |||
1487 | 1539 | ||
1488 | edid = drm_get_edid(&intel_output->base, | 1540 | edid = drm_get_edid(&intel_output->base, |
1489 | intel_output->ddc_bus); | 1541 | intel_output->ddc_bus); |
1542 | |||
1543 | /* when there is no edid and no monitor is connected with VGA | ||
1544 | * port, try to use the CRT ddc to read the EDID for DVI-connector | ||
1545 | */ | ||
1546 | if (edid == NULL && | ||
1547 | sdvo_priv->analog_ddc_bus && | ||
1548 | !intel_analog_is_connected(intel_output->base.dev)) | ||
1549 | edid = drm_get_edid(&intel_output->base, | ||
1550 | sdvo_priv->analog_ddc_bus); | ||
1490 | if (edid != NULL) { | 1551 | if (edid != NULL) { |
1491 | /* Don't report the output as connected if it's a DVI-I | 1552 | /* Don't report the output as connected if it's a DVI-I |
1492 | * connector with a non-digital EDID coming out. | 1553 | * connector with a non-digital EDID coming out. |
@@ -1515,7 +1576,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1515 | struct intel_output *intel_output = to_intel_output(connector); | 1576 | struct intel_output *intel_output = to_intel_output(connector); |
1516 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1577 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
1517 | 1578 | ||
1518 | intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | 1579 | intel_sdvo_write_cmd(intel_output, |
1580 | SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); | ||
1519 | status = intel_sdvo_read_response(intel_output, &response, 2); | 1581 | status = intel_sdvo_read_response(intel_output, &response, 2); |
1520 | 1582 | ||
1521 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); | 1583 | DRM_DEBUG_KMS("SDVO response %d %d\n", response & 0xff, response >> 8); |
@@ -1539,50 +1601,32 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1539 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1601 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1540 | { | 1602 | { |
1541 | struct intel_output *intel_output = to_intel_output(connector); | 1603 | struct intel_output *intel_output = to_intel_output(connector); |
1604 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1605 | int num_modes; | ||
1542 | 1606 | ||
1543 | /* set the bus switch and get the modes */ | 1607 | /* set the bus switch and get the modes */ |
1544 | intel_ddc_get_modes(intel_output); | 1608 | num_modes = intel_ddc_get_modes(intel_output); |
1545 | 1609 | ||
1546 | #if 0 | 1610 | /* |
1547 | struct drm_device *dev = encoder->dev; | 1611 | * Mac mini hack. On this device, the DVI-I connector shares one DDC |
1548 | struct drm_i915_private *dev_priv = dev->dev_private; | 1612 | * link between analog and digital outputs. So, if the regular SDVO |
1549 | /* Mac mini hack. On this device, I get DDC through the analog, which | 1613 | * DDC fails, check to see if the analog output is disconnected, in |
1550 | * load-detects as disconnected. I fail to DDC through the SDVO DDC, | 1614 | * which case we'll look there for the digital DDC data. |
1551 | * but it does load-detect as connected. So, just steal the DDC bits | ||
1552 | * from analog when we fail at finding it the right way. | ||
1553 | */ | 1615 | */ |
1554 | crt = xf86_config->output[0]; | 1616 | if (num_modes == 0 && |
1555 | intel_output = crt->driver_private; | 1617 | sdvo_priv->analog_ddc_bus && |
1556 | if (intel_output->type == I830_OUTPUT_ANALOG && | 1618 | !intel_analog_is_connected(intel_output->base.dev)) { |
1557 | crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { | 1619 | struct i2c_adapter *digital_ddc_bus; |
1558 | I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A"); | ||
1559 | edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus); | ||
1560 | xf86DestroyI2CBusRec(intel_output->pDDCBus, true, true); | ||
1561 | } | ||
1562 | if (edid_mon) { | ||
1563 | xf86OutputSetEDID(output, edid_mon); | ||
1564 | modes = xf86OutputGetEDIDModes(output); | ||
1565 | } | ||
1566 | #endif | ||
1567 | } | ||
1568 | 1620 | ||
1569 | /** | 1621 | /* Switch to the analog ddc bus and try that |
1570 | * This function checks the current TV format, and chooses a default if | 1622 | */ |
1571 | * it hasn't been set. | 1623 | digital_ddc_bus = intel_output->ddc_bus; |
1572 | */ | 1624 | intel_output->ddc_bus = sdvo_priv->analog_ddc_bus; |
1573 | static void | ||
1574 | intel_sdvo_check_tv_format(struct intel_output *output) | ||
1575 | { | ||
1576 | struct intel_sdvo_priv *dev_priv = output->dev_priv; | ||
1577 | struct intel_sdvo_tv_format format; | ||
1578 | uint8_t status; | ||
1579 | 1625 | ||
1580 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0); | 1626 | (void) intel_ddc_get_modes(intel_output); |
1581 | status = intel_sdvo_read_response(output, &format, sizeof(format)); | ||
1582 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
1583 | return; | ||
1584 | 1627 | ||
1585 | memcpy(&dev_priv->tv_format, &format, sizeof(format)); | 1628 | intel_output->ddc_bus = digital_ddc_bus; |
1629 | } | ||
1586 | } | 1630 | } |
1587 | 1631 | ||
1588 | /* | 1632 | /* |
@@ -1655,17 +1699,26 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1655 | struct intel_output *output = to_intel_output(connector); | 1699 | struct intel_output *output = to_intel_output(connector); |
1656 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; | 1700 | struct intel_sdvo_priv *sdvo_priv = output->dev_priv; |
1657 | struct intel_sdvo_sdtv_resolution_request tv_res; | 1701 | struct intel_sdvo_sdtv_resolution_request tv_res; |
1658 | uint32_t reply = 0; | 1702 | uint32_t reply = 0, format_map = 0; |
1703 | int i; | ||
1659 | uint8_t status; | 1704 | uint8_t status; |
1660 | int i = 0; | ||
1661 | 1705 | ||
1662 | intel_sdvo_check_tv_format(output); | ||
1663 | 1706 | ||
1664 | /* Read the list of supported input resolutions for the selected TV | 1707 | /* Read the list of supported input resolutions for the selected TV |
1665 | * format. | 1708 | * format. |
1666 | */ | 1709 | */ |
1667 | memset(&tv_res, 0, sizeof(tv_res)); | 1710 | for (i = 0; i < TV_FORMAT_NUM; i++) |
1668 | memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res)); | 1711 | if (tv_format_names[i] == sdvo_priv->tv_format_name) |
1712 | break; | ||
1713 | |||
1714 | format_map = (1 << i); | ||
1715 | memcpy(&tv_res, &format_map, | ||
1716 | sizeof(struct intel_sdvo_sdtv_resolution_request) > | ||
1717 | sizeof(format_map) ? sizeof(format_map) : | ||
1718 | sizeof(struct intel_sdvo_sdtv_resolution_request)); | ||
1719 | |||
1720 | intel_sdvo_set_target_output(output, sdvo_priv->controlled_output); | ||
1721 | |||
1669 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, | 1722 | intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, |
1670 | &tv_res, sizeof(tv_res)); | 1723 | &tv_res, sizeof(tv_res)); |
1671 | status = intel_sdvo_read_response(output, &reply, 3); | 1724 | status = intel_sdvo_read_response(output, &reply, 3); |
@@ -1680,6 +1733,7 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1680 | if (nmode) | 1733 | if (nmode) |
1681 | drm_mode_probed_add(connector, nmode); | 1734 | drm_mode_probed_add(connector, nmode); |
1682 | } | 1735 | } |
1736 | |||
1683 | } | 1737 | } |
1684 | 1738 | ||
1685 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1739 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
@@ -1747,17 +1801,62 @@ static void intel_sdvo_destroy(struct drm_connector *connector) | |||
1747 | intel_i2c_destroy(intel_output->i2c_bus); | 1801 | intel_i2c_destroy(intel_output->i2c_bus); |
1748 | if (intel_output->ddc_bus) | 1802 | if (intel_output->ddc_bus) |
1749 | intel_i2c_destroy(intel_output->ddc_bus); | 1803 | intel_i2c_destroy(intel_output->ddc_bus); |
1804 | if (sdvo_priv->analog_ddc_bus) | ||
1805 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
1750 | 1806 | ||
1751 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) | 1807 | if (sdvo_priv->sdvo_lvds_fixed_mode != NULL) |
1752 | drm_mode_destroy(connector->dev, | 1808 | drm_mode_destroy(connector->dev, |
1753 | sdvo_priv->sdvo_lvds_fixed_mode); | 1809 | sdvo_priv->sdvo_lvds_fixed_mode); |
1754 | 1810 | ||
1811 | if (sdvo_priv->tv_format_property) | ||
1812 | drm_property_destroy(connector->dev, | ||
1813 | sdvo_priv->tv_format_property); | ||
1814 | |||
1755 | drm_sysfs_connector_remove(connector); | 1815 | drm_sysfs_connector_remove(connector); |
1756 | drm_connector_cleanup(connector); | 1816 | drm_connector_cleanup(connector); |
1757 | 1817 | ||
1758 | kfree(intel_output); | 1818 | kfree(intel_output); |
1759 | } | 1819 | } |
1760 | 1820 | ||
1821 | static int | ||
1822 | intel_sdvo_set_property(struct drm_connector *connector, | ||
1823 | struct drm_property *property, | ||
1824 | uint64_t val) | ||
1825 | { | ||
1826 | struct intel_output *intel_output = to_intel_output(connector); | ||
1827 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1828 | struct drm_encoder *encoder = &intel_output->enc; | ||
1829 | struct drm_crtc *crtc = encoder->crtc; | ||
1830 | int ret = 0; | ||
1831 | bool changed = false; | ||
1832 | |||
1833 | ret = drm_connector_property_set_value(connector, property, val); | ||
1834 | if (ret < 0) | ||
1835 | goto out; | ||
1836 | |||
1837 | if (property == sdvo_priv->tv_format_property) { | ||
1838 | if (val >= TV_FORMAT_NUM) { | ||
1839 | ret = -EINVAL; | ||
1840 | goto out; | ||
1841 | } | ||
1842 | if (sdvo_priv->tv_format_name == | ||
1843 | sdvo_priv->tv_format_supported[val]) | ||
1844 | goto out; | ||
1845 | |||
1846 | sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[val]; | ||
1847 | changed = true; | ||
1848 | } else { | ||
1849 | ret = -EINVAL; | ||
1850 | goto out; | ||
1851 | } | ||
1852 | |||
1853 | if (changed && crtc) | ||
1854 | drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, | ||
1855 | crtc->y, crtc->fb); | ||
1856 | out: | ||
1857 | return ret; | ||
1858 | } | ||
1859 | |||
1761 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { | 1860 | static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = { |
1762 | .dpms = intel_sdvo_dpms, | 1861 | .dpms = intel_sdvo_dpms, |
1763 | .mode_fixup = intel_sdvo_mode_fixup, | 1862 | .mode_fixup = intel_sdvo_mode_fixup, |
@@ -1772,6 +1871,7 @@ static const struct drm_connector_funcs intel_sdvo_connector_funcs = { | |||
1772 | .restore = intel_sdvo_restore, | 1871 | .restore = intel_sdvo_restore, |
1773 | .detect = intel_sdvo_detect, | 1872 | .detect = intel_sdvo_detect, |
1774 | .fill_modes = drm_helper_probe_single_connector_modes, | 1873 | .fill_modes = drm_helper_probe_single_connector_modes, |
1874 | .set_property = intel_sdvo_set_property, | ||
1775 | .destroy = intel_sdvo_destroy, | 1875 | .destroy = intel_sdvo_destroy, |
1776 | }; | 1876 | }; |
1777 | 1877 | ||
@@ -1966,6 +2066,9 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
1966 | intel_sdvo_set_colorimetry(intel_output, | 2066 | intel_sdvo_set_colorimetry(intel_output, |
1967 | SDVO_COLORIMETRY_RGB256); | 2067 | SDVO_COLORIMETRY_RGB256); |
1968 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2068 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2069 | intel_output->clone_mask = | ||
2070 | (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2071 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
1969 | } | 2072 | } |
1970 | } else if (flags & SDVO_OUTPUT_SVID0) { | 2073 | } else if (flags & SDVO_OUTPUT_SVID0) { |
1971 | 2074 | ||
@@ -1974,11 +2077,14 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
1974 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; | 2077 | connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; |
1975 | sdvo_priv->is_tv = true; | 2078 | sdvo_priv->is_tv = true; |
1976 | intel_output->needs_tv_clock = true; | 2079 | intel_output->needs_tv_clock = true; |
2080 | intel_output->clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; | ||
1977 | } else if (flags & SDVO_OUTPUT_RGB0) { | 2081 | } else if (flags & SDVO_OUTPUT_RGB0) { |
1978 | 2082 | ||
1979 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; | 2083 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB0; |
1980 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; | 2084 | encoder->encoder_type = DRM_MODE_ENCODER_DAC; |
1981 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; | 2085 | connector->connector_type = DRM_MODE_CONNECTOR_VGA; |
2086 | intel_output->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | ||
2087 | (1 << INTEL_ANALOG_CLONE_BIT); | ||
1982 | } else if (flags & SDVO_OUTPUT_RGB1) { | 2088 | } else if (flags & SDVO_OUTPUT_RGB1) { |
1983 | 2089 | ||
1984 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; | 2090 | sdvo_priv->controlled_output = SDVO_OUTPUT_RGB1; |
@@ -1990,12 +2096,16 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
1990 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2096 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
1991 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2097 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
1992 | sdvo_priv->is_lvds = true; | 2098 | sdvo_priv->is_lvds = true; |
2099 | intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2100 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
1993 | } else if (flags & SDVO_OUTPUT_LVDS1) { | 2101 | } else if (flags & SDVO_OUTPUT_LVDS1) { |
1994 | 2102 | ||
1995 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; | 2103 | sdvo_priv->controlled_output = SDVO_OUTPUT_LVDS1; |
1996 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; | 2104 | encoder->encoder_type = DRM_MODE_ENCODER_LVDS; |
1997 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; | 2105 | connector->connector_type = DRM_MODE_CONNECTOR_LVDS; |
1998 | sdvo_priv->is_lvds = true; | 2106 | sdvo_priv->is_lvds = true; |
2107 | intel_output->clone_mask = (1 << INTEL_ANALOG_CLONE_BIT) | | ||
2108 | (1 << INTEL_SDVO_LVDS_CLONE_BIT); | ||
1999 | } else { | 2109 | } else { |
2000 | 2110 | ||
2001 | unsigned char bytes[2]; | 2111 | unsigned char bytes[2]; |
@@ -2007,6 +2117,7 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2007 | bytes[0], bytes[1]); | 2117 | bytes[0], bytes[1]); |
2008 | ret = false; | 2118 | ret = false; |
2009 | } | 2119 | } |
2120 | intel_output->crtc_mask = (1 << 0) | (1 << 1); | ||
2010 | 2121 | ||
2011 | if (ret && registered) | 2122 | if (ret && registered) |
2012 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; | 2123 | ret = drm_sysfs_connector_add(connector) == 0 ? true : false; |
@@ -2016,6 +2127,55 @@ intel_sdvo_output_setup(struct intel_output *intel_output, uint16_t flags) | |||
2016 | 2127 | ||
2017 | } | 2128 | } |
2018 | 2129 | ||
2130 | static void intel_sdvo_tv_create_property(struct drm_connector *connector) | ||
2131 | { | ||
2132 | struct intel_output *intel_output = to_intel_output(connector); | ||
2133 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
2134 | struct intel_sdvo_tv_format format; | ||
2135 | uint32_t format_map, i; | ||
2136 | uint8_t status; | ||
2137 | |||
2138 | intel_sdvo_set_target_output(intel_output, | ||
2139 | sdvo_priv->controlled_output); | ||
2140 | |||
2141 | intel_sdvo_write_cmd(intel_output, | ||
2142 | SDVO_CMD_GET_SUPPORTED_TV_FORMATS, NULL, 0); | ||
2143 | status = intel_sdvo_read_response(intel_output, | ||
2144 | &format, sizeof(format)); | ||
2145 | if (status != SDVO_CMD_STATUS_SUCCESS) | ||
2146 | return; | ||
2147 | |||
2148 | memcpy(&format_map, &format, sizeof(format) > sizeof(format_map) ? | ||
2149 | sizeof(format_map) : sizeof(format)); | ||
2150 | |||
2151 | if (format_map == 0) | ||
2152 | return; | ||
2153 | |||
2154 | sdvo_priv->format_supported_num = 0; | ||
2155 | for (i = 0 ; i < TV_FORMAT_NUM; i++) | ||
2156 | if (format_map & (1 << i)) { | ||
2157 | sdvo_priv->tv_format_supported | ||
2158 | [sdvo_priv->format_supported_num++] = | ||
2159 | tv_format_names[i]; | ||
2160 | } | ||
2161 | |||
2162 | |||
2163 | sdvo_priv->tv_format_property = | ||
2164 | drm_property_create( | ||
2165 | connector->dev, DRM_MODE_PROP_ENUM, | ||
2166 | "mode", sdvo_priv->format_supported_num); | ||
2167 | |||
2168 | for (i = 0; i < sdvo_priv->format_supported_num; i++) | ||
2169 | drm_property_add_enum( | ||
2170 | sdvo_priv->tv_format_property, i, | ||
2171 | i, sdvo_priv->tv_format_supported[i]); | ||
2172 | |||
2173 | sdvo_priv->tv_format_name = sdvo_priv->tv_format_supported[0]; | ||
2174 | drm_connector_attach_property( | ||
2175 | connector, sdvo_priv->tv_format_property, 0); | ||
2176 | |||
2177 | } | ||
2178 | |||
2019 | bool intel_sdvo_init(struct drm_device *dev, int output_device) | 2179 | bool intel_sdvo_init(struct drm_device *dev, int output_device) |
2020 | { | 2180 | { |
2021 | struct drm_connector *connector; | 2181 | struct drm_connector *connector; |
@@ -2060,10 +2220,15 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
2060 | } | 2220 | } |
2061 | 2221 | ||
2062 | /* setup the DDC bus. */ | 2222 | /* setup the DDC bus. */ |
2063 | if (output_device == SDVOB) | 2223 | if (output_device == SDVOB) { |
2064 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 2224 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); |
2065 | else | 2225 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, |
2226 | "SDVOB/VGA DDC BUS"); | ||
2227 | } else { | ||
2066 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 2228 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); |
2229 | sdvo_priv->analog_ddc_bus = intel_i2c_create(dev, GPIOA, | ||
2230 | "SDVOC/VGA DDC BUS"); | ||
2231 | } | ||
2067 | 2232 | ||
2068 | if (intel_output->ddc_bus == NULL) | 2233 | if (intel_output->ddc_bus == NULL) |
2069 | goto err_i2c; | 2234 | goto err_i2c; |
@@ -2097,6 +2262,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
2097 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); | 2262 | drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs); |
2098 | 2263 | ||
2099 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); | 2264 | drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); |
2265 | if (sdvo_priv->is_tv) | ||
2266 | intel_sdvo_tv_create_property(connector); | ||
2100 | drm_sysfs_connector_add(connector); | 2267 | drm_sysfs_connector_add(connector); |
2101 | 2268 | ||
2102 | intel_sdvo_select_ddc_bus(sdvo_priv); | 2269 | intel_sdvo_select_ddc_bus(sdvo_priv); |
@@ -2129,6 +2296,8 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
2129 | return true; | 2296 | return true; |
2130 | 2297 | ||
2131 | err_i2c: | 2298 | err_i2c: |
2299 | if (sdvo_priv->analog_ddc_bus != NULL) | ||
2300 | intel_i2c_destroy(sdvo_priv->analog_ddc_bus); | ||
2132 | if (intel_output->ddc_bus != NULL) | 2301 | if (intel_output->ddc_bus != NULL) |
2133 | intel_i2c_destroy(intel_output->ddc_bus); | 2302 | intel_i2c_destroy(intel_output->ddc_bus); |
2134 | if (intel_output->i2c_bus != NULL) | 2303 | if (intel_output->i2c_bus != NULL) |