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