1*1c66496bSKevin Tang /* SPDX-License-Identifier: GPL-2.0 */ 2*1c66496bSKevin Tang /* 3*1c66496bSKevin Tang * Copyright (C) 2020 Unisoc Inc. 4*1c66496bSKevin Tang */ 5*1c66496bSKevin Tang 6*1c66496bSKevin Tang #ifndef __SPRD_DSI_H__ 7*1c66496bSKevin Tang #define __SPRD_DSI_H__ 8*1c66496bSKevin Tang 9*1c66496bSKevin Tang #include <linux/of.h> 10*1c66496bSKevin Tang #include <linux/device.h> 11*1c66496bSKevin Tang #include <linux/regmap.h> 12*1c66496bSKevin Tang #include <video/videomode.h> 13*1c66496bSKevin Tang 14*1c66496bSKevin Tang #include <drm/drm_bridge.h> 15*1c66496bSKevin Tang #include <drm/drm_connector.h> 16*1c66496bSKevin Tang #include <drm/drm_encoder.h> 17*1c66496bSKevin Tang #include <drm/drm_mipi_dsi.h> 18*1c66496bSKevin Tang #include <drm/drm_print.h> 19*1c66496bSKevin Tang #include <drm/drm_panel.h> 20*1c66496bSKevin Tang 21*1c66496bSKevin Tang #define encoder_to_dsi(encoder) \ 22*1c66496bSKevin Tang container_of(encoder, struct sprd_dsi, encoder) 23*1c66496bSKevin Tang 24*1c66496bSKevin Tang enum dsi_work_mode { 25*1c66496bSKevin Tang DSI_MODE_CMD = 0, 26*1c66496bSKevin Tang DSI_MODE_VIDEO 27*1c66496bSKevin Tang }; 28*1c66496bSKevin Tang 29*1c66496bSKevin Tang enum video_burst_mode { 30*1c66496bSKevin Tang VIDEO_NON_BURST_WITH_SYNC_PULSES = 0, 31*1c66496bSKevin Tang VIDEO_NON_BURST_WITH_SYNC_EVENTS, 32*1c66496bSKevin Tang VIDEO_BURST_WITH_SYNC_PULSES 33*1c66496bSKevin Tang }; 34*1c66496bSKevin Tang 35*1c66496bSKevin Tang enum dsi_color_coding { 36*1c66496bSKevin Tang COLOR_CODE_16BIT_CONFIG1 = 0, 37*1c66496bSKevin Tang COLOR_CODE_16BIT_CONFIG2, 38*1c66496bSKevin Tang COLOR_CODE_16BIT_CONFIG3, 39*1c66496bSKevin Tang COLOR_CODE_18BIT_CONFIG1, 40*1c66496bSKevin Tang COLOR_CODE_18BIT_CONFIG2, 41*1c66496bSKevin Tang COLOR_CODE_24BIT, 42*1c66496bSKevin Tang COLOR_CODE_20BIT_YCC422_LOOSELY, 43*1c66496bSKevin Tang COLOR_CODE_24BIT_YCC422, 44*1c66496bSKevin Tang COLOR_CODE_16BIT_YCC422, 45*1c66496bSKevin Tang COLOR_CODE_30BIT, 46*1c66496bSKevin Tang COLOR_CODE_36BIT, 47*1c66496bSKevin Tang COLOR_CODE_12BIT_YCC420, 48*1c66496bSKevin Tang COLOR_CODE_COMPRESSTION, 49*1c66496bSKevin Tang COLOR_CODE_MAX 50*1c66496bSKevin Tang }; 51*1c66496bSKevin Tang 52*1c66496bSKevin Tang enum pll_timing { 53*1c66496bSKevin Tang NONE, 54*1c66496bSKevin Tang REQUEST_TIME, 55*1c66496bSKevin Tang PREPARE_TIME, 56*1c66496bSKevin Tang SETTLE_TIME, 57*1c66496bSKevin Tang ZERO_TIME, 58*1c66496bSKevin Tang TRAIL_TIME, 59*1c66496bSKevin Tang EXIT_TIME, 60*1c66496bSKevin Tang CLKPOST_TIME, 61*1c66496bSKevin Tang TA_GET, 62*1c66496bSKevin Tang TA_GO, 63*1c66496bSKevin Tang TA_SURE, 64*1c66496bSKevin Tang TA_WAIT, 65*1c66496bSKevin Tang }; 66*1c66496bSKevin Tang 67*1c66496bSKevin Tang struct dphy_pll { 68*1c66496bSKevin Tang u8 refin; /* Pre-divider control signal */ 69*1c66496bSKevin Tang u8 cp_s; /* 00: SDM_EN=1, 10: SDM_EN=0 */ 70*1c66496bSKevin Tang u8 fdk_s; /* PLL mode control: integer or fraction */ 71*1c66496bSKevin Tang u8 sdm_en; 72*1c66496bSKevin Tang u8 div; 73*1c66496bSKevin Tang u8 int_n; /* integer N PLL */ 74*1c66496bSKevin Tang u32 ref_clk; /* dphy reference clock, unit: MHz */ 75*1c66496bSKevin Tang u32 freq; /* panel config, unit: KHz */ 76*1c66496bSKevin Tang u32 fvco; 77*1c66496bSKevin Tang u32 potential_fvco; 78*1c66496bSKevin Tang u32 nint; /* sigma delta modulator NINT control */ 79*1c66496bSKevin Tang u32 kint; /* sigma delta modulator KINT control */ 80*1c66496bSKevin Tang u8 lpf_sel; /* low pass filter control */ 81*1c66496bSKevin Tang u8 out_sel; /* post divider control */ 82*1c66496bSKevin Tang u8 vco_band; /* vco range */ 83*1c66496bSKevin Tang u8 det_delay; 84*1c66496bSKevin Tang }; 85*1c66496bSKevin Tang 86*1c66496bSKevin Tang struct dsi_context { 87*1c66496bSKevin Tang void __iomem *base; 88*1c66496bSKevin Tang struct regmap *regmap; 89*1c66496bSKevin Tang struct dphy_pll pll; 90*1c66496bSKevin Tang struct videomode vm; 91*1c66496bSKevin Tang bool enabled; 92*1c66496bSKevin Tang 93*1c66496bSKevin Tang u8 work_mode; 94*1c66496bSKevin Tang u8 burst_mode; 95*1c66496bSKevin Tang u32 int0_mask; 96*1c66496bSKevin Tang u32 int1_mask; 97*1c66496bSKevin Tang 98*1c66496bSKevin Tang /* maximum time (ns) for data lanes from HS to LP */ 99*1c66496bSKevin Tang u16 data_hs2lp; 100*1c66496bSKevin Tang /* maximum time (ns) for data lanes from LP to HS */ 101*1c66496bSKevin Tang u16 data_lp2hs; 102*1c66496bSKevin Tang /* maximum time (ns) for clk lanes from HS to LP */ 103*1c66496bSKevin Tang u16 clk_hs2lp; 104*1c66496bSKevin Tang /* maximum time (ns) for clk lanes from LP to HS */ 105*1c66496bSKevin Tang u16 clk_lp2hs; 106*1c66496bSKevin Tang /* maximum time (ns) for BTA operation - REQUIRED */ 107*1c66496bSKevin Tang u16 max_rd_time; 108*1c66496bSKevin Tang /* enable receiving frame ack packets - for video mode */ 109*1c66496bSKevin Tang bool frame_ack_en; 110*1c66496bSKevin Tang /* enable receiving tear effect ack packets - for cmd mode */ 111*1c66496bSKevin Tang bool te_ack_en; 112*1c66496bSKevin Tang }; 113*1c66496bSKevin Tang 114*1c66496bSKevin Tang struct sprd_dsi { 115*1c66496bSKevin Tang struct drm_device *drm; 116*1c66496bSKevin Tang struct mipi_dsi_host host; 117*1c66496bSKevin Tang struct mipi_dsi_device *slave; 118*1c66496bSKevin Tang struct drm_encoder encoder; 119*1c66496bSKevin Tang struct drm_bridge *panel_bridge; 120*1c66496bSKevin Tang struct dsi_context ctx; 121*1c66496bSKevin Tang }; 122*1c66496bSKevin Tang 123*1c66496bSKevin Tang int dphy_pll_config(struct dsi_context *ctx); 124*1c66496bSKevin Tang void dphy_timing_config(struct dsi_context *ctx); 125*1c66496bSKevin Tang 126*1c66496bSKevin Tang #endif /* __SPRD_DSI_H__ */ 127