/* SPDX-License-Identifier: GPL-2.0-only */
|
#ifndef __KIRIN_DRM_DSI_H__
|
#define __KIRIN_DRM_DSI_H__
|
|
#include <linux/clk.h>
|
#include <linux/component.h>
|
#include <linux/of_graph.h>
|
#include <linux/iopoll.h>
|
#include <video/mipi_display.h>
|
#include <linux/gpio/consumer.h>
|
#include <linux/of_address.h>
|
#include <linux/of_platform.h>
|
|
#include <drm/drm_of.h>
|
#include <drm/drm_crtc_helper.h>
|
#include <drm/drm_mipi_dsi.h>
|
#include <drm/drm_encoder_slave.h>
|
#include <drm/drm_atomic_helper.h>
|
#include <drm/drm_panel.h>
|
|
#define ROUND(x, y) ((x) / (y) + ((x) % (y) * 10 / (y) >= 5 ? 1 : 0))
|
#define PHY_REF_CLK_RATE 19200000
|
#define PHY_REF_CLK_PERIOD_PS (1000000000 / (PHY_REF_CLK_RATE / 1000))
|
|
#define encoder_to_dsi(encoder) container_of(encoder, struct dw_dsi, encoder)
|
#define host_to_dsi(host) container_of(host, struct dw_dsi, host)
|
#define connector_to_dsi(connector) \
|
container_of(connector, struct dw_dsi, connector)
|
|
enum dsi_output_client { OUT_HDMI = 0, OUT_PANEL, OUT_MAX };
|
|
struct dsi_phy_range {
|
u32 min_range_kHz;
|
u32 max_range_kHz;
|
u32 pll_vco_750M;
|
u32 hstx_ckg_sel;
|
};
|
|
static const struct dsi_phy_range dphy_range_info[] = {
|
{ 46875, 62500, 1, 7 },
|
{ 62500, 93750, 0, 7 },
|
{ 93750, 125000, 1, 6 },
|
{ 125000, 187500, 0, 6 },
|
{ 187500, 250000, 1, 5 },
|
{ 250000, 375000, 0, 5 },
|
{ 375000, 500000, 1, 4 },
|
{ 500000, 750000, 0, 4 },
|
{ 750000, 1000000, 1, 0 },
|
{ 1000000, 1500000, 0, 0 }
|
};
|
|
struct dsi_hw_ctx {
|
void __iomem *base;
|
char __iomem *peri_crg_base;
|
|
struct clk *pclk;
|
struct clk *dss_dphy0_ref_clk;
|
struct clk *dss_dphy1_ref_clk;
|
struct clk *dss_dphy0_cfg_clk;
|
struct clk *dss_dphy1_cfg_clk;
|
struct clk *dss_pclk_dsi0_clk;
|
struct clk *dss_pclk_dsi1_clk;
|
};
|
|
struct mipi_panel_info {
|
u8 dsi_version;
|
u8 vc;
|
u8 lane_nums;
|
u8 lane_nums_select_support;
|
u8 color_mode;
|
u32 dsi_bit_clk; /* clock lane(p/n) */
|
u32 burst_mode;
|
u32 max_tx_esc_clk;
|
u8 non_continue_en;
|
|
u32 dsi_bit_clk_val1;
|
u32 dsi_bit_clk_val2;
|
u32 dsi_bit_clk_val3;
|
u32 dsi_bit_clk_val4;
|
u32 dsi_bit_clk_val5;
|
u32 dsi_bit_clk_upt;
|
/*uint32_t dsi_pclk_rate;*/
|
|
u32 hs_wr_to_time;
|
|
/* dphy config parameter adjust*/
|
u32 clk_post_adjust;
|
u32 clk_pre_adjust;
|
u32 clk_pre_delay_adjust;
|
u32 clk_t_hs_exit_adjust;
|
u32 clk_t_hs_trial_adjust;
|
u32 clk_t_hs_prepare_adjust;
|
int clk_t_lpx_adjust;
|
u32 clk_t_hs_zero_adjust;
|
u32 data_post_delay_adjust;
|
int data_t_lpx_adjust;
|
u32 data_t_hs_prepare_adjust;
|
u32 data_t_hs_zero_adjust;
|
u32 data_t_hs_trial_adjust;
|
u32 rg_vrefsel_vcm_adjust;
|
|
/*only for Chicago<3660> use*/
|
u32 rg_vrefsel_vcm_clk_adjust;
|
u32 rg_vrefsel_vcm_data_adjust;
|
};
|
|
struct mipi_phy_params {
|
u32 clk_t_lpx;
|
u32 clk_t_hs_prepare;
|
u32 clk_t_hs_zero;
|
u32 clk_t_hs_trial;
|
u32 clk_t_wakeup;
|
u32 data_t_lpx;
|
u32 data_t_hs_prepare;
|
u32 data_t_hs_zero;
|
u32 data_t_hs_trial;
|
u32 data_t_ta_go;
|
u32 data_t_ta_get;
|
u32 data_t_wakeup;
|
u32 hstx_ckg_sel;
|
u32 pll_fbd_div5f;
|
u32 pll_fbd_div1f;
|
u32 pll_fbd_2p;
|
u32 pll_enbwt;
|
u32 pll_fbd_p;
|
u32 pll_fbd_s;
|
u32 pll_pre_div1p;
|
u32 pll_pre_p;
|
u32 pll_vco_750M;
|
u32 pll_lpf_rs;
|
u32 pll_lpf_cs;
|
u32 clk_division;
|
/********for hikey620************/
|
u32 clklp2hs_time;
|
u32 clkhs2lp_time;
|
u32 lp2hs_time;
|
u32 hs2lp_time;
|
u32 clk_to_data_delay;
|
u32 data_to_clk_delay;
|
u32 lane_byte_clk_kHz;
|
/*****************/
|
|
/****for hikey960*****/
|
u64 lane_byte_clk;
|
|
u32 clk_lane_lp2hs_time;
|
u32 clk_lane_hs2lp_time;
|
u32 data_lane_lp2hs_time;
|
u32 data_lane_hs2lp_time;
|
u32 clk2data_delay;
|
u32 data2clk_delay;
|
|
u32 clk_pre_delay;
|
u32 clk_post_delay;
|
u32 data_pre_delay;
|
u32 data_post_delay;
|
u32 phy_stop_wait_time;
|
u32 rg_vrefsel_vcm;
|
|
u32 rg_pll_enswc;
|
u32 rg_pll_chp;
|
|
u32 pll_register_override; /*0x1E[0]*/
|
u32 pll_power_down; /*0x1E[1]*/
|
u32 rg_band_sel; /*0x1E[2]*/
|
u32 rg_phase_gen_en; /*0x1E[3]*/
|
u32 reload_sel; /*0x1E[4]*/
|
u32 rg_pll_cp_p; /*0x1E[7:5]*/
|
u32 rg_pll_refsel; /*0x16[1:0]*/
|
u32 rg_pll_cp; /*0x16[7:5]*/
|
u32 load_command;
|
/*********/
|
};
|
|
struct ldi_panel_info {
|
u32 h_back_porch;
|
u32 h_front_porch;
|
u32 h_pulse_width;
|
|
/*
|
* note: vbp > 8 if used overlay compose,
|
* also lcd vbp > 8 in lcd power on sequence
|
*/
|
u32 v_back_porch;
|
u32 v_front_porch;
|
u32 v_pulse_width;
|
|
u8 hsync_plr;
|
u8 vsync_plr;
|
u8 pixelclk_plr;
|
u8 data_en_plr;
|
|
/* for cabc */
|
u8 dpi0_overlap_size;
|
u8 dpi1_overlap_size;
|
};
|
|
struct dw_dsi_client {
|
u32 lanes;
|
u32 phy_clock; /* in kHz */
|
enum mipi_dsi_pixel_format format;
|
unsigned long mode_flags;
|
};
|
|
struct dw_dsi {
|
struct drm_encoder encoder;
|
struct drm_bridge *bridge;
|
struct drm_panel *panel;
|
struct mipi_dsi_host host;
|
struct drm_connector connector; /* connector for panel */
|
struct drm_display_mode cur_mode;
|
struct dsi_hw_ctx *ctx;
|
struct mipi_phy_params phy;
|
struct mipi_panel_info mipi;
|
struct ldi_panel_info ldi;
|
u32 lanes;
|
enum mipi_dsi_pixel_format format;
|
unsigned long mode_flags;
|
struct gpio_desc *gpio_mux;
|
struct dw_dsi_client client[OUT_MAX];
|
enum dsi_output_client cur_client;
|
bool enable;
|
};
|
|
struct dsi_data {
|
struct dw_dsi dsi;
|
struct dsi_hw_ctx ctx;
|
};
|
|
enum kirin_dsi_version {
|
KIRIN620_DSI = 0,
|
KIRIN960_DSI
|
};
|
|
/* display controller init/cleanup ops */
|
struct kirin_dsi_ops {
|
enum kirin_dsi_version version;
|
int (*parse_dt)(struct platform_device *pdev, struct dw_dsi *dsi);
|
int (*host_init)(struct device *dev, struct dw_dsi *dsi);
|
void (*encoder_enable)(struct drm_encoder *encoder);
|
enum drm_mode_status (*encoder_valid)(
|
struct drm_encoder *encoder,
|
const struct drm_display_mode *mode);
|
};
|
|
#ifdef CONFIG_DRM_HISI_KIRIN960
|
extern const struct kirin_dsi_ops kirin_dsi_960;
|
#endif
|
#ifdef CONFIG_DRM_HISI_KIRIN620
|
extern const struct kirin_dsi_ops kirin_dsi_620;
|
#endif
|
|
#endif /* __KIRIN_DRM_DSI_H__ */
|