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 intel_connector *intel_connector = to_intel_connector(connector);
  35        struct drm_display_mode *mode;
  36
  37        DRM_DEBUG_KMS("\n");
  38
  39        if (!intel_connector->panel.fixed_mode) {
  40                DRM_DEBUG_KMS("no fixed mode\n");
  41                return 0;
  42        }
  43
  44        mode = drm_mode_duplicate(connector->dev,
  45                                  intel_connector->panel.fixed_mode);
  46        if (!mode) {
  47                DRM_DEBUG_KMS("drm_mode_duplicate failed\n");
  48                return 0;
  49        }
  50
  51        drm_mode_probed_add(connector, mode);
  52        return 1;
  53}
  54
  55enum drm_mode_status intel_dsi_mode_valid(struct drm_connector *connector,
  56                                          struct drm_display_mode *mode)
  57{
  58        struct intel_connector *intel_connector = to_intel_connector(connector);
  59        const struct drm_display_mode *fixed_mode = intel_connector->panel.fixed_mode;
  60        int max_dotclk = to_i915(connector->dev)->max_dotclk_freq;
  61
  62        DRM_DEBUG_KMS("\n");
  63
  64        if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
  65                return MODE_NO_DBLESCAN;
  66
  67        if (fixed_mode) {
  68                if (mode->hdisplay > fixed_mode->hdisplay)
  69                        return MODE_PANEL;
  70                if (mode->vdisplay > fixed_mode->vdisplay)
  71                        return MODE_PANEL;
  72                if (fixed_mode->clock > max_dotclk)
  73                        return MODE_CLOCK_HIGH;
  74        }
  75
  76        return MODE_OK;
  77}
  78
  79struct intel_dsi_host *intel_dsi_host_init(struct intel_dsi *intel_dsi,
  80                                           const struct mipi_dsi_host_ops *funcs,
  81                                           enum port port)
  82{
  83        struct intel_dsi_host *host;
  84        struct mipi_dsi_device *device;
  85
  86        host = kzalloc(sizeof(*host), GFP_KERNEL);
  87        if (!host)
  88                return NULL;
  89
  90        host->base.ops = funcs;
  91        host->intel_dsi = intel_dsi;
  92        host->port = port;
  93
  94        /*
  95         * We should call mipi_dsi_host_register(&host->base) here, but we don't
  96         * have a host->dev, and we don't have OF stuff either. So just use the
  97         * dsi framework as a library and hope for the best. Create the dsi
  98         * devices by ourselves here too. Need to be careful though, because we
  99         * don't initialize any of the driver model devices here.
 100         */
 101        device = kzalloc(sizeof(*device), GFP_KERNEL);
 102        if (!device) {
 103                kfree(host);
 104                return NULL;
 105        }
 106
 107        device->host = &host->base;
 108        host->device = device;
 109
 110        return host;
 111}
 112
 113enum drm_panel_orientation
 114intel_dsi_get_panel_orientation(struct intel_connector *connector)
 115{
 116        struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 117        enum drm_panel_orientation orientation;
 118
 119        orientation = dev_priv->vbt.dsi.orientation;
 120        if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
 121                return orientation;
 122
 123        orientation = dev_priv->vbt.orientation;
 124        if (orientation != DRM_MODE_PANEL_ORIENTATION_UNKNOWN)
 125                return orientation;
 126
 127        return DRM_MODE_PANEL_ORIENTATION_NORMAL;
 128}
 129