1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2018 Intel Corporation 4 */ 5 6 #include <drm/drm_mipi_dsi.h> 7 #include "intel_dsi.h" 8 9 int intel_dsi_bitrate(const struct intel_dsi *intel_dsi) 10 { 11 int bpp = mipi_dsi_pixel_format_to_bpp(intel_dsi->pixel_format); 12 13 if (WARN_ON(bpp < 0)) 14 bpp = 16; 15 16 return intel_dsi->pclk * bpp / intel_dsi->lane_count; 17 } 18 19 int intel_dsi_tlpx_ns(const struct intel_dsi *intel_dsi) 20 { 21 switch (intel_dsi->escape_clk_div) { 22 default: 23 case 0: 24 return 50; 25 case 1: 26 return 100; 27 case 2: 28 return 200; 29 } 30 } 31 32 int intel_dsi_get_modes(struct drm_connector *connector) 33 { 34 struct drm_i915_private *i915 = to_i915(connector->dev); 35 struct intel_connector *intel_connector = to_intel_connector(connector); 36 struct drm_display_mode *mode; 37 38 drm_dbg_kms(&i915->drm, "\n"); 39 40 if (!intel_connector->panel.fixed_mode) { 41 drm_dbg_kms(&i915->drm, "no fixed mode\n"); 42 return 0; 43 } 44 45 mode = drm_mode_duplicate(connector->dev, 46 intel_connector->panel.fixed_mode); 47 if (!mode) { 48 drm_dbg_kms(&i915->drm, "drm_mode_duplicate failed\n"); 49 return 0; 50 } 51 52 drm_mode_probed_add(connector, mode); 53 return 1; 54 } 55 56 enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector, 57 struct drm_display_mode *mode) 58 { 59 struct drm_i915_private *dev_priv = to_i915(connector->dev); 60 struct intel_connector *intel_connector = to_intel_connector(connector); 61 const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode; 62 int max_dotclk = to_i915(connector->dev)->max_dotclk_freq; 63 64 drm_dbg_kms(&dev_priv->drm, "\n"); 65 66 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 67 return MODE_NO_DBLESCAN; 68 69 if (fixed_mode) { 70 if (mode->hdisplay > fixed_mode->hdisplay) 71 return MODE_PANEL; 72 if (mode->vdisplay > fixed_mode->vdisplay) 73 return MODE_PANEL; 74 if (fixed_mode->clock > max_dotclk) 75 return MODE_CLOCK_HIGH; 76 } 77 78 return intel_mode_valid_max_plane_size(dev_priv, mode); 79 } 80 81 struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi, 82 const struct mipi_dsi_host_ops *funcs, 83 enum port port) 84 { 85 struct intel_dsi_host *host; 86 struct mipi_dsi_device *device; 87 88 host = kzalloc(sizeof(*host), GFP_KERNEL); 89 if (!host) 90 return NULL; 91 92 host->base.ops = funcs; 93 host->intel_dsi = intel_dsi; 94 host->port = port; 95 96 /* 97 * We should call mipi_dsi_host_register(&host->base) here, but we don't 98 * have a host->dev, and we don't have OF stuff either. So just use the 99 * dsi framework as a library and hope for the best. Create the dsi 100 * devices by ourselves here too. Need to be careful though, because we 101 * don't initialize any of the driver model devices here. 102 */ 103 device = kzalloc(sizeof(*device), GFP_KERNEL); 104 if (!device) { 105 kfree(host); 106 return NULL; 107 } 108 109 device->host = &host->base; 110 host->device = device; 111 112 return host; 113 } 114 115 enum drm_panel_orientation 116 intel_dsi_get_panel_orientation(struct intel_connector *connector) 117 { 118 struct drm_i915_private *dev_priv = to_i915(connector->base.dev); 119 enum drm_panel_orientation orientation; 120 121 orientation = dev_priv->vbt.dsi.orientation; 122 if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) 123 return orientation; 124 125 orientation = dev_priv->vbt.orientation; 126 if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN) 127 return orientation; 128 129 return DRM_MODE_PANEL_ORIENTATION_NORMAL; 130 } 131