linux/drivers/gpu/drm/i915/display/vlv_dsi.c

/*
 * Copyright © 2013 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Author: Jani Nikula <[email protected]>
 */

#include <linux/dmi.h>
#include <linux/slab.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>

#include "i915_drv.h"
#include "i915_reg.h"
#include "intel_atomic.h"
#include "intel_backlight.h"
#include "intel_connector.h"
#include "intel_crtc.h"
#include "intel_de.h"
#include "intel_display_types.h"
#include "intel_dsi.h"
#include "intel_dsi_vbt.h"
#include "intel_fifo_underrun.h"
#include "intel_panel.h"
#include "skl_scaler.h"
#include "vlv_dsi.h"
#include "vlv_dsi_pll.h"
#include "vlv_dsi_regs.h"
#include "vlv_sideband.h"

/* return pixels in terms of txbyteclkhs */
static u16 txbyteclkhs(u16 pixels, int bpp, int lane_count,
		       u16 burst_mode_ratio)
{}

/* return pixels equvalent to txbyteclkhs */
static u16 pixels_from_txbyteclkhs(u16 clk_hs, int bpp, int lane_count,
			u16 burst_mode_ratio)
{}

enum mipi_dsi_pixel_format pixel_format_from_register_bits(u32 fmt)
{}

void vlv_dsi_wait_for_fifo_empty(struct intel_dsi *intel_dsi, enum port port)
{}

static void write_data(struct intel_display *display,
		       i915_reg_t reg,
		       const u8 *data, u32 len)
{}

static void read_data(struct intel_display *display,
		      i915_reg_t reg,
		      u8 *data, u32 len)
{}

static ssize_t intel_dsi_host_transfer(struct mipi_dsi_host *host,
				       const struct mipi_dsi_msg *msg)
{}

static int intel_dsi_host_attach(struct mipi_dsi_host *host,
				 struct mipi_dsi_device *dsi)
{}

static int intel_dsi_host_detach(struct mipi_dsi_host *host,
				 struct mipi_dsi_device *dsi)
{}

static const struct mipi_dsi_host_ops intel_dsi_host_ops =;

/*
 * send a video mode command
 *
 * XXX: commands with data in MIPI_DPI_DATA?
 */
static int dpi_send_cmd(struct intel_dsi *intel_dsi, u32 cmd, bool hs,
			enum port port)
{}

static void band_gap_reset(struct drm_i915_private *dev_priv)
{}

static int intel_dsi_compute_config(struct intel_encoder *encoder,
				    struct intel_crtc_state *pipe_config,
				    struct drm_connector_state *conn_state)
{}

static bool glk_dsi_enable_io(struct intel_encoder *encoder)
{}

static void glk_dsi_device_ready(struct intel_encoder *encoder)
{}

static void bxt_dsi_device_ready(struct intel_encoder *encoder)
{}

static void vlv_dsi_device_ready(struct intel_encoder *encoder)
{}

static void intel_dsi_device_ready(struct intel_encoder *encoder)
{}

static void glk_dsi_enter_low_power_mode(struct intel_encoder *encoder)
{}

static void glk_dsi_disable_mipi_io(struct intel_encoder *encoder)
{}

static void glk_dsi_clear_device_ready(struct intel_encoder *encoder)
{}

static i915_reg_t port_ctrl_reg(struct drm_i915_private *i915, enum port port)
{}

static void vlv_dsi_clear_device_ready(struct intel_encoder *encoder)
{}

static void intel_dsi_port_enable(struct intel_encoder *encoder,
				  const struct intel_crtc_state *crtc_state)
{}

static void intel_dsi_port_disable(struct intel_encoder *encoder)
{}

static void intel_dsi_prepare(struct intel_encoder *encoder,
			      const struct intel_crtc_state *pipe_config);
static void intel_dsi_unprepare(struct intel_encoder *encoder);

/*
 * Panel enable/disable sequences from the VBT spec.
 *
 * Note the spec has AssertReset / DeassertReset swapped from their
 * usual naming. We use the normal names to avoid confusion (so below
 * they are swapped compared to the spec).
 *
 * Steps starting with MIPI refer to VBT sequences, note that for v2
 * VBTs several steps which have a VBT in v2 are expected to be handled
 * directly by the driver, by directly driving gpios for example.
 *
 * v2 video mode seq         v3 video mode seq         command mode seq
 * - power on                - MIPIPanelPowerOn        - power on
 * - wait t1+t2                                        - wait t1+t2
 * - MIPIDeassertResetPin    - MIPIDeassertResetPin    - MIPIDeassertResetPin
 * - io lines to lp-11       - io lines to lp-11       - io lines to lp-11
 * - MIPISendInitialDcsCmds  - MIPISendInitialDcsCmds  - MIPISendInitialDcsCmds
 *                                                     - MIPITearOn
 *                                                     - MIPIDisplayOn
 * - turn on DPI             - turn on DPI             - set pipe to dsr mode
 * - MIPIDisplayOn           - MIPIDisplayOn
 * - wait t5                                           - wait t5
 * - backlight on            - MIPIBacklightOn         - backlight on
 * ...                       ...                       ... issue mem cmds ...
 * - backlight off           - MIPIBacklightOff        - backlight off
 * - wait t6                                           - wait t6
 * - MIPIDisplayOff
 * - turn off DPI            - turn off DPI            - disable pipe dsr mode
 *                                                     - MIPITearOff
 *                           - MIPIDisplayOff          - MIPIDisplayOff
 * - io lines to lp-00       - io lines to lp-00       - io lines to lp-00
 * - MIPIAssertResetPin      - MIPIAssertResetPin      - MIPIAssertResetPin
 * - wait t3                                           - wait t3
 * - power off               - MIPIPanelPowerOff       - power off
 * - wait t4                                           - wait t4
 */

/*
 * DSI port enable has to be done before pipe and plane enable, so we do it in
 * the pre_enable hook instead of the enable hook.
 */
static void intel_dsi_pre_enable(struct intel_atomic_state *state,
				 struct intel_encoder *encoder,
				 const struct intel_crtc_state *pipe_config,
				 const struct drm_connector_state *conn_state)
{}

static void bxt_dsi_enable(struct intel_atomic_state *state,
			   struct intel_encoder *encoder,
			   const struct intel_crtc_state *crtc_state,
			   const struct drm_connector_state *conn_state)
{}

/*
 * DSI port disable has to be done after pipe and plane disable, so we do it in
 * the post_disable hook.
 */
static void intel_dsi_disable(struct intel_atomic_state *state,
			      struct intel_encoder *encoder,
			      const struct intel_crtc_state *old_crtc_state,
			      const struct drm_connector_state *old_conn_state)
{}

static void intel_dsi_clear_device_ready(struct intel_encoder *encoder)
{}

static void intel_dsi_post_disable(struct intel_atomic_state *state,
				   struct intel_encoder *encoder,
				   const struct intel_crtc_state *old_crtc_state,
				   const struct drm_connector_state *old_conn_state)
{}

static bool intel_dsi_get_hw_state(struct intel_encoder *encoder,
				   enum pipe *pipe)
{}

static void bxt_dsi_get_pipe_config(struct intel_encoder *encoder,
				    struct intel_crtc_state *pipe_config)
{}

static void intel_dsi_get_config(struct intel_encoder *encoder,
				 struct intel_crtc_state *pipe_config)
{}

/* return txclkesc cycles in terms of divider and duration in us */
static u16 txclkesc(u32 divider, unsigned int us)
{}

static void set_dsi_timings(struct intel_encoder *encoder,
			    const struct drm_display_mode *adjusted_mode)
{}

static u32 pixel_format_to_reg(enum mipi_dsi_pixel_format fmt)
{}

static void intel_dsi_prepare(struct intel_encoder *encoder,
			      const struct intel_crtc_state *pipe_config)
{}

static void intel_dsi_unprepare(struct intel_encoder *encoder)
{}

static const struct drm_encoder_funcs intel_dsi_funcs =;

static enum drm_mode_status vlv_dsi_mode_valid(struct drm_connector *connector,
					       struct drm_display_mode *mode)
{}

static const struct drm_connector_helper_funcs intel_dsi_connector_helper_funcs =;

static const struct drm_connector_funcs intel_dsi_connector_funcs =;

static void vlv_dsi_add_properties(struct intel_connector *connector)
{}

#define NS_KHZ_RATIO

#define PREPARE_CNT_MAX
#define EXIT_ZERO_CNT_MAX
#define CLK_ZERO_CNT_MAX
#define TRAIL_CNT_MAX

static void vlv_dphy_param_init(struct intel_dsi *intel_dsi)
{}

vlv_dsi_dmi_quirk_func;

/*
 * Vtotal is wrong on the Asus TF103C leading to the last line of the display
 * being shown as the first line. The factory installed Android has a hardcoded
 * modeline, causing it to not suffer from this BIOS bug.
 *
 * Original mode: "1280x800": 60 67700 1280 1312 1328 1376 800 808 812 820 0x8 0xa
 * Fixed    mode: "1280x800": 60 67700 1280 1312 1328 1376 800 808 812 816 0x8 0xa
 *
 * https://gitlab.freedesktop.org/drm/intel/-/issues/9381
 */
static void vlv_dsi_asus_tf103c_mode_fixup(struct intel_dsi *intel_dsi)
{}

/*
 * On the Lenovo Yoga Tablet 2 830 / 1050 there are 2 problems:
 * 1. The I2C MIPI sequence elements reference bus 3. ACPI has I2C1 - I2C7
 *    which under Linux become bus 0 - 6. And the MIPI sequence reference
 *    to bus 3 is indented for I2C3 which is bus 2 under Linux.
 *
 *    Note mipi_exec_i2c() cannot just subtract 1 from the bus
 *    given in the I2C MIPI sequence element. Since on other
 *    devices the I2C bus-numbers used in the MIPI sequences do
 *    actually start at 0.
 *
 * 2. width_/height_mm contain a bogus 192mm x 120mm size. This is
 *    especially a problem on the 8" 830 version which uses a 10:16
 *    portrait screen where as the bogus size is 16:10.
 *
 * https://gitlab.freedesktop.org/drm/intel/-/issues/9379
 */
static void vlv_dsi_lenovo_yoga_tab2_size_fixup(struct intel_dsi *intel_dsi)
{}

/*
 * On the Lenovo Yoga Tab 3 Pro YT3-X90F there are 2 problems:
 * 1. i2c_acpi_find_adapter() picks the wrong adapter causing mipi_exec_i2c()
 *    to not work. Fix this by setting i2c_bus_num.
 * 2. There is no backlight off MIPI sequence, causing the backlight to stay on.
 *    Add a backlight off sequence mirroring the existing backlight on sequence.
 *
 * https://gitlab.freedesktop.org/drm/intel/-/issues/9380
 */
static void vlv_dsi_lenovo_yoga_tab3_backlight_fixup(struct intel_dsi *intel_dsi)
{}

static const struct dmi_system_id vlv_dsi_dmi_quirk_table[] =;

void vlv_dsi_init(struct drm_i915_private *dev_priv)
{}