linux/drivers/gpu/drm/i915/display/intel_dsi.c
<<
>>
Prefs
   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
   9int 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
  19int 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
  32int 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
  56enum 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, false);
  79}
  80
  81struct 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
 115enum drm_panel_orientation
 116intel_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