aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/vlv_dsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/vlv_dsi.c')
-rw-r--r--drivers/gpu/drm/i915/vlv_dsi.c190
1 files changed, 51 insertions, 139 deletions
diff --git a/drivers/gpu/drm/i915/vlv_dsi.c b/drivers/gpu/drm/i915/vlv_dsi.c
index 435a2c35ee8c..361e962a7969 100644
--- a/drivers/gpu/drm/i915/vlv_dsi.c
+++ b/drivers/gpu/drm/i915/vlv_dsi.c
@@ -206,39 +206,6 @@ static const struct mipi_dsi_host_ops intel_dsi_host_ops = {
206 .transfer = intel_dsi_host_transfer, 206 .transfer = intel_dsi_host_transfer,
207}; 207};
208 208
209static struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
210 enum port port)
211{
212 struct intel_dsi_host *host;
213 struct mipi_dsi_device *device;
214
215 host = kzalloc(sizeof(*host), GFP_KERNEL);
216 if (!host)
217 return NULL;
218
219 host->base.ops = &intel_dsi_host_ops;
220 host->intel_dsi = intel_dsi;
221 host->port = port;
222
223 /*
224 * We should call mipi_dsi_host_register(&host->base) here, but we don't
225 * have a host->dev, and we don't have OF stuff either. So just use the
226 * dsi framework as a library and hope for the best. Create the dsi
227 * devices by ourselves here too. Need to be careful though, because we
228 * don't initialize any of the driver model devices here.
229 */
230 device = kzalloc(sizeof(*device), GFP_KERNEL);
231 if (!device) {
232 kfree(host);
233 return NULL;
234 }
235
236 device->host = &host->base;
237 host->device = device;
238
239 return host;
240}
241
242/* 209/*
243 * send a video mode command 210 * send a video mode command
244 * 211 *
@@ -290,16 +257,6 @@ static void band_gap_reset(struct drm_i915_private *dev_priv)
290 mutex_unlock(&dev_priv->sb_lock); 257 mutex_unlock(&dev_priv->sb_lock);
291} 258}
292 259
293static inline bool is_vid_mode(struct intel_dsi *intel_dsi)
294{
295 return intel_dsi->operation_mode == INTEL_DSI_VIDEO_MODE;
296}
297
298static inline bool is_cmd_mode(struct intel_dsi *intel_dsi)
299{
300 return intel_dsi->operation_mode == INTEL_DSI_COMMAND_MODE;
301}
302
303static bool intel_dsi_compute_config(struct intel_encoder *encoder, 260static bool intel_dsi_compute_config(struct intel_encoder *encoder,
304 struct intel_crtc_state *pipe_config, 261 struct intel_crtc_state *pipe_config,
305 struct drm_connector_state *conn_state) 262 struct drm_connector_state *conn_state)
@@ -314,6 +271,7 @@ static bool intel_dsi_compute_config(struct intel_encoder *encoder,
314 int ret; 271 int ret;
315 272
316 DRM_DEBUG_KMS("\n"); 273 DRM_DEBUG_KMS("\n");
274 pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
317 275
318 if (fixed_mode) { 276 if (fixed_mode) {
319 intel_fixed_panel_mode(fixed_mode, adjusted_mode); 277 intel_fixed_panel_mode(fixed_mode, adjusted_mode);
@@ -745,17 +703,6 @@ static void intel_dsi_prepare(struct intel_encoder *intel_encoder,
745 const struct intel_crtc_state *pipe_config); 703 const struct intel_crtc_state *pipe_config);
746static void intel_dsi_unprepare(struct intel_encoder *encoder); 704static void intel_dsi_unprepare(struct intel_encoder *encoder);
747 705
748static void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec)
749{
750 struct drm_i915_private *dev_priv = to_i915(intel_dsi->base.base.dev);
751
752 /* For v3 VBTs in vid-mode the delays are part of the VBT sequences */
753 if (is_vid_mode(intel_dsi) && dev_priv->vbt.dsi.seq_version >= 3)
754 return;
755
756 msleep(msec);
757}
758
759/* 706/*
760 * Panel enable/disable sequences from the VBT spec. 707 * Panel enable/disable sequences from the VBT spec.
761 * 708 *
@@ -793,6 +740,10 @@ static void intel_dsi_msleep(struct intel_dsi *intel_dsi, int msec)
793 * - wait t4 - wait t4 740 * - wait t4 - wait t4
794 */ 741 */
795 742
743/*
744 * DSI port enable has to be done before pipe and plane enable, so we do it in
745 * the pre_enable hook instead of the enable hook.
746 */
796static void intel_dsi_pre_enable(struct intel_encoder *encoder, 747static void intel_dsi_pre_enable(struct intel_encoder *encoder,
797 const struct intel_crtc_state *pipe_config, 748 const struct intel_crtc_state *pipe_config,
798 const struct drm_connector_state *conn_state) 749 const struct drm_connector_state *conn_state)
@@ -895,17 +846,6 @@ static void intel_dsi_pre_enable(struct intel_encoder *encoder,
895} 846}
896 847
897/* 848/*
898 * DSI port enable has to be done before pipe and plane enable, so we do it in
899 * the pre_enable hook.
900 */
901static void intel_dsi_enable_nop(struct intel_encoder *encoder,
902 const struct intel_crtc_state *pipe_config,
903 const struct drm_connector_state *conn_state)
904{
905 DRM_DEBUG_KMS("\n");
906}
907
908/*
909 * DSI port disable has to be done after pipe and plane disable, so we do it in 849 * DSI port disable has to be done after pipe and plane disable, so we do it in
910 * the post_disable hook. 850 * the post_disable hook.
911 */ 851 */
@@ -1272,31 +1212,6 @@ static void intel_dsi_get_config(struct intel_encoder *encoder,
1272 } 1212 }
1273} 1213}
1274 1214
1275static enum drm_mode_status
1276intel_dsi_mode_valid(struct drm_connector *connector,
1277 struct drm_display_mode *mode)
1278{
1279 struct intel_connector *intel_connector = to_intel_connector(connector);
1280 const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
1281 int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
1282
1283 DRM_DEBUG_KMS("\n");
1284
1285 if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
1286 return MODE_NO_DBLESCAN;
1287
1288 if (fixed_mode) {
1289 if (mode->hdisplay > fixed_mode->hdisplay)
1290 return MODE_PANEL;
1291 if (mode->vdisplay > fixed_mode->vdisplay)
1292 return MODE_PANEL;
1293 if (fixed_mode->clock > max_dotclk)
1294 return MODE_CLOCK_HIGH;
1295 }
1296
1297 return MODE_OK;
1298}
1299
1300/* return txclkesc cycles in terms of divider and duration in us */ 1215/* return txclkesc cycles in terms of divider and duration in us */
1301static u16 txclkesc(u32 divider, unsigned int us) 1216static u16 txclkesc(u32 divider, unsigned int us)
1302{ 1217{
@@ -1619,39 +1534,6 @@ static void intel_dsi_unprepare(struct intel_encoder *encoder)
1619 } 1534 }
1620} 1535}
1621 1536
1622static int intel_dsi_get_modes(struct drm_connector *connector)
1623{
1624 struct intel_connector *intel_connector = to_intel_connector(connector);
1625 struct drm_display_mode *mode;
1626
1627 DRM_DEBUG_KMS("\n");
1628
1629 if (!intel_connector->panel.fixed_mode) {
1630 DRM_DEBUG_KMS("no fixed mode\n");
1631 return 0;
1632 }
1633
1634 mode = drm_mode_duplicate(connector->dev,
1635 intel_connector->panel.fixed_mode);
1636 if (!mode) {
1637 DRM_DEBUG_KMS("drm_mode_duplicate failed\n");
1638 return 0;
1639 }
1640
1641 drm_mode_probed_add(connector, mode);
1642 return 1;
1643}
1644
1645static void intel_dsi_connector_destroy(struct drm_connector *connector)
1646{
1647 struct intel_connector *intel_connector = to_intel_connector(connector);
1648
1649 DRM_DEBUG_KMS("\n");
1650 intel_panel_fini(&intel_connector->panel);
1651 drm_connector_cleanup(connector);
1652 kfree(connector);
1653}
1654
1655static void intel_dsi_encoder_destroy(struct drm_encoder *encoder) 1537static void intel_dsi_encoder_destroy(struct drm_encoder *encoder)
1656{ 1538{
1657 struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder); 1539 struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
@@ -1676,7 +1558,7 @@ static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs
1676static const struct drm_connector_funcs intel_dsi_connector_funcs = { 1558static const struct drm_connector_funcs intel_dsi_connector_funcs = {
1677 .late_register = intel_connector_register, 1559 .late_register = intel_connector_register,
1678 .early_unregister = intel_connector_unregister, 1560 .early_unregister = intel_connector_unregister,
1679 .destroy = intel_dsi_connector_destroy, 1561 .destroy = intel_connector_destroy,
1680 .fill_modes = drm_helper_probe_single_connector_modes, 1562 .fill_modes = drm_helper_probe_single_connector_modes,
1681 .atomic_get_property = intel_digital_connector_atomic_get_property, 1563 .atomic_get_property = intel_digital_connector_atomic_get_property,
1682 .atomic_set_property = intel_digital_connector_atomic_set_property, 1564 .atomic_set_property = intel_digital_connector_atomic_set_property,
@@ -1684,27 +1566,57 @@ static const struct drm_connector_funcs intel_dsi_connector_funcs = {
1684 .atomic_duplicate_state = intel_digital_connector_duplicate_state, 1566 .atomic_duplicate_state = intel_digital_connector_duplicate_state,
1685}; 1567};
1686 1568
1687static int intel_dsi_get_panel_orientation(struct intel_connector *connector) 1569static enum drm_panel_orientation
1570vlv_dsi_get_hw_panel_orientation(struct intel_connector *connector)
1688{ 1571{
1689 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1572 struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1690 int orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL; 1573 struct intel_encoder *encoder = connector->encoder;
1691 enum i9xx_plane_id i9xx_plane; 1574 enum intel_display_power_domain power_domain;
1575 enum drm_panel_orientation orientation;
1576 struct intel_plane *plane;
1577 struct intel_crtc *crtc;
1578 enum pipe pipe;
1692 u32 val; 1579 u32 val;
1693 1580
1694 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) { 1581 if (!encoder->get_hw_state(encoder, &pipe))
1695 if (connector->encoder->crtc_mask == BIT(PIPE_B)) 1582 return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
1696 i9xx_plane = PLANE_B;
1697 else
1698 i9xx_plane = PLANE_A;
1699 1583
1700 val = I915_READ(DSPCNTR(i9xx_plane)); 1584 crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
1701 if (val & DISPPLANE_ROTATE_180) 1585 plane = to_intel_plane(crtc->base.primary);
1702 orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP; 1586
1703 } 1587 power_domain = POWER_DOMAIN_PIPE(pipe);
1588 if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
1589 return DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
1590
1591 val = I915_READ(DSPCNTR(plane->i9xx_plane));
1592
1593 if (!(val & DISPLAY_PLANE_ENABLE))
1594 orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
1595 else if (val & DISPPLANE_ROTATE_180)
1596 orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
1597 else
1598 orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
1599
1600 intel_display_power_put(dev_priv, power_domain);
1704 1601
1705 return orientation; 1602 return orientation;
1706} 1603}
1707 1604
1605static enum drm_panel_orientation
1606vlv_dsi_get_panel_orientation(struct intel_connector *connector)
1607{
1608 struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
1609 enum drm_panel_orientation orientation;
1610
1611 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1612 orientation = vlv_dsi_get_hw_panel_orientation(connector);
1613 if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
1614 return orientation;
1615 }
1616
1617 return intel_dsi_get_panel_orientation(connector);
1618}
1619
1708static void intel_dsi_add_properties(struct intel_connector *connector) 1620static void intel_dsi_add_properties(struct intel_connector *connector)
1709{ 1621{
1710 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 1622 struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
@@ -1722,7 +1634,7 @@ static void intel_dsi_add_properties(struct intel_connector *connector)
1722 connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT; 1634 connector->base.state->scaling_mode = DRM_MODE_SCALE_ASPECT;
1723 1635
1724 connector->base.display_info.panel_orientation = 1636 connector->base.display_info.panel_orientation =
1725 intel_dsi_get_panel_orientation(connector); 1637 vlv_dsi_get_panel_orientation(connector);
1726 drm_connector_init_panel_orientation_property( 1638 drm_connector_init_panel_orientation_property(
1727 &connector->base, 1639 &connector->base,
1728 connector->panel.fixed_mode->hdisplay, 1640 connector->panel.fixed_mode->hdisplay,
@@ -1773,7 +1685,6 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
1773 1685
1774 intel_encoder->compute_config = intel_dsi_compute_config; 1686 intel_encoder->compute_config = intel_dsi_compute_config;
1775 intel_encoder->pre_enable = intel_dsi_pre_enable; 1687 intel_encoder->pre_enable = intel_dsi_pre_enable;
1776 intel_encoder->enable = intel_dsi_enable_nop;
1777 intel_encoder->disable = intel_dsi_disable; 1688 intel_encoder->disable = intel_dsi_disable;
1778 intel_encoder->post_disable = intel_dsi_post_disable; 1689 intel_encoder->post_disable = intel_dsi_post_disable;
1779 intel_encoder->get_hw_state = intel_dsi_get_hw_state; 1690 intel_encoder->get_hw_state = intel_dsi_get_hw_state;
@@ -1806,7 +1717,8 @@ void vlv_dsi_init(struct drm_i915_private *dev_priv)
1806 for_each_dsi_port(port, intel_dsi->ports) { 1717 for_each_dsi_port(port, intel_dsi->ports) {
1807 struct intel_dsi_host *host; 1718 struct intel_dsi_host *host;
1808 1719
1809 host = intel_dsi_host_init(intel_dsi, port); 1720 host = intel_dsi_host_init(intel_dsi, &intel_dsi_host_ops,
1721 port);
1810 if (!host) 1722 if (!host)
1811 goto err; 1723 goto err;
1812 1724