• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * MIPI DSI Bus
4  *
5  * Andrzej Hajda <a.hajda@samsung.com>
6  */
7 
8 #ifndef __SOC_MIPI_DSI_H__
9 #define __SOC_MIPI_DSI_H__
10 
11 #include <types.h>
12 
13 struct mipi_dsi_host;
14 struct mipi_dsi_device;
15 
16 /* request ACK from peripheral */
17 #define MIPI_DSI_MSG_REQ_ACK	BIT(0)
18 /* use Low Power Mode to transmit message */
19 #define MIPI_DSI_MSG_USE_LPM	BIT(1)
20 
21 /**
22  * @brief mipi_dsi_msg - read/write DSI buffer
23  */
24 struct mipi_dsi_msg {
25 	u8 channel;	/**< virtual channel id */
26 	u8 type;	/**< payload data type */
27 	u16 flags;	/**< flags controlling this message transmission */
28 
29 	size_t tx_len;	/**< length of tx_buf */
30 	const void *tx_buf;	/**< data to be written */
31 
32 	size_t rx_len;	/**< length of rx_buf */
33 	void *rx_buf;	/**< data to be read, or NULL */
34 };
35 
36 /**
37  * @brief mipi_dsi_host_ops - DSI bus operations
38  * @var mipi_dsi_host_ops::attach
39  *      attach DSI device to DSI host
40  * @var mipi_dsi_host_ops::detach
41  *      detach DSI device from DSI host
42  * @var mipi_dsi_host_ops::transfer
43  *     transmit a DSI packet
44  *
45  * DSI packets transmitted by .transfer() are passed in as mipi_dsi_msg
46  * structures. This structure contains information about the type of packet
47  * being transmitted as well as the transmit and receive buffers. When an
48  * error is encountered during transmission, this function will return a
49  * negative error code. On success it shall return the number of bytes
50  * transmitted for write packets or the number of bytes received for read
51  * packets.
52  *
53  * Note that typically DSI packet transmission is atomic, so the .transfer()
54  * function will seldomly return anything other than the number of bytes
55  * contained in the transmit buffer on success.
56  */
57 struct mipi_dsi_host_ops {
58 	int (*attach)(struct mipi_dsi_host *host,
59 		      struct mipi_dsi_device *dsi);
60 	int (*detach)(struct mipi_dsi_host *host,
61 		      struct mipi_dsi_device *dsi);
62 	ssize_t (*transfer)(struct mipi_dsi_host *host,
63 			    const struct mipi_dsi_msg *msg);
64 };
65 
66 /**
67  * @brief mipi_dsi_host - DSI host device
68  */
69 struct mipi_dsi_host {
70 	//struct device *dev;
71 	void *dev;	/**< driver model device node for this DSI host */
72 	const struct mipi_dsi_host_ops *ops;	/**< DSI host operations */
73 };
74 
75 int mipi_dsi_host_register(struct mipi_dsi_host *host);
76 
77 /* DSI mode flags */
78 
79 /* video mode */
80 #define MIPI_DSI_MODE_VIDEO		BIT(0)
81 /* video burst mode */
82 #define MIPI_DSI_MODE_VIDEO_BURST	BIT(1)
83 /* video pulse mode */
84 #define MIPI_DSI_MODE_VIDEO_SYNC_PULSE	BIT(2)
85 /* enable auto vertical count mode */
86 #define MIPI_DSI_MODE_VIDEO_AUTO_VERT	BIT(3)
87 /* enable hsync-end packets in vsync-pulse and v-porch area */
88 #define MIPI_DSI_MODE_VIDEO_HSE		BIT(4)
89 /* disable hfront-porch area */
90 #define MIPI_DSI_MODE_VIDEO_HFP		BIT(5)
91 /* disable hback-porch area */
92 #define MIPI_DSI_MODE_VIDEO_HBP		BIT(6)
93 /* disable hsync-active area */
94 #define MIPI_DSI_MODE_VIDEO_HSA		BIT(7)
95 /* flush display FIFO on vsync pulse */
96 #define MIPI_DSI_MODE_VSYNC_FLUSH	BIT(8)
97 /* disable EoT packets in HS mode */
98 #define MIPI_DSI_MODE_EOT_PACKET	BIT(9)
99 /* device supports non-continuous clock behavior (DSI spec 5.6.1) */
100 #define MIPI_DSI_CLOCK_NON_CONTINUOUS	BIT(10)
101 
102 enum mipi_dsi_pixel_format {
103 	MIPI_DSI_FMT_RGB888,
104 	MIPI_DSI_FMT_RGB666,
105 	MIPI_DSI_FMT_RGB666_PACKED,
106 	MIPI_DSI_FMT_RGB565,
107 };
108 
109 struct mipi_dsi_master_ops {
110 	int (*enslave)(struct mipi_dsi_device *master,
111 		       struct mipi_dsi_device *slave);
112 	int (*liberate)(struct mipi_dsi_device *master,
113 			struct mipi_dsi_device *slave);
114 };
115 
116 /**
117  * @brief mipi_dsi_device - DSI peripheral device
118  *
119  * For dual-channel interfaces, the master interface can be identified by the
120  * fact that it's .slave field is set to non-NULL. The slave interface will
121  * have the .master field set to non-NULL.
122  */
123 struct mipi_dsi_device {
124 	struct mipi_dsi_host *host;	/**< DSI host for this peripheral */
125 
126 	unsigned int channel;	/**< virtual channel assigned to the peripheral */
127 	unsigned int lanes;	/**< number of active data lanes */
128 	enum mipi_dsi_pixel_format format;	/**< pixel format for video mode */
129 	unsigned long mode_flags;	/**< DSI operation mode related flags */
130 
131 	const struct mipi_dsi_master_ops *ops;	/**< callbacks for master/slave setup */
132 	struct mipi_dsi_device *master;	/**< master interface for dual-channel peripherals */
133 	struct mipi_dsi_device *slave;	/**< slave interface for dual-channel peripherals */
134 };
135 
136 int mipi_dsi_attach(struct mipi_dsi_device *dsi);
137 int mipi_dsi_detach(struct mipi_dsi_device *dsi);
138 int mipi_dsi_enslave(struct mipi_dsi_device *master,
139 		     struct mipi_dsi_device *slave);
140 int mipi_dsi_liberate(struct mipi_dsi_device *master,
141 		      struct mipi_dsi_device *slave);
142 
143 /**
144  * @brief mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
145  * @var mipi_dsi_dcs_tear_mode::MIPI_DSI_DCS_TEAR_MODE_VBLANK
146  *      The TE output line consists of V-Blanking information only
147  * @var mipi_dsi_dcs_tear_mode::MIPI_DSI_DCS_TEAR_MODE_VHBLANK
148  *      The TE output line consists of both V-Blanking and H-Blanking
149  *      information
150  */
151 enum mipi_dsi_dcs_tear_mode {
152 	MIPI_DSI_DCS_TEAR_MODE_VBLANK,
153 	MIPI_DSI_DCS_TEAR_MODE_VHBLANK,
154 };
155 
156 #define MIPI_DSI_DCS_POWER_MODE_DISPLAY (1 << 2)
157 #define MIPI_DSI_DCS_POWER_MODE_NORMAL  (1 << 3)
158 #define MIPI_DSI_DCS_POWER_MODE_SLEEP   (1 << 4)
159 #define MIPI_DSI_DCS_POWER_MODE_PARTIAL (1 << 5)
160 #define MIPI_DSI_DCS_POWER_MODE_IDLE    (1 << 6)
161 
162 ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
163 			   const void *data, size_t len);
164 int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi);
165 int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi);
166 int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
167 				    u16 end);
168 int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
169 				  u16 end);
170 int mipi_dsi_dcs_set_address_mode(struct mipi_dsi_device *dsi,
171 				  bool reverse_page_address,
172 				  bool reverse_col_address,
173 				  bool reverse_page_col_address,
174 				  bool refresh_from_bottom,
175 				  bool reverse_rgb,
176 				  bool latch_right_to_left,
177 				  bool flip_horizontal,
178 				  bool flip_vertical);
179 int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
180 			     enum mipi_dsi_dcs_tear_mode mode);
181 int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format);
182 
183 #define MIPI_CAL_CTRL			0x00
184 #define MIPI_CAL_CTRL_NOISE_FILTER(x)	(((x) & 0xf) << 26)
185 #define MIPI_CAL_CTRL_PRESCALE(x)	(((x) & 0x3) << 24)
186 #define MIPI_CAL_CTRL_CLKEN_OVR		(1 << 4)
187 #define MIPI_CAL_CTRL_START		(1 << 0)
188 
189 #define MIPI_CAL_AUTOCAL_CTRL		0x01
190 
191 #define MIPI_CAL_STATUS			0x02
192 #define MIPI_CAL_STATUS_DONE		(1 << 16)
193 #define MIPI_CAL_STATUS_ACTIVE		(1 <<  0)
194 
195 #define MIPI_CAL_CONFIG_CSIA		0x05
196 #define MIPI_CAL_CONFIG_CSIB		0x06
197 #define MIPI_CAL_CONFIG_CSIC		0x07
198 #define MIPI_CAL_CONFIG_CSID		0x08
199 #define MIPI_CAL_CONFIG_CSIE		0x09
200 #define MIPI_CAL_CONFIG_CSIF		0x0a
201 #define MIPI_CAL_CONFIG_DSIA		0x0e
202 #define MIPI_CAL_CONFIG_DSIB		0x0f
203 #define MIPI_CAL_CONFIG_DSIC		0x10
204 #define MIPI_CAL_CONFIG_DSID		0x11
205 
206 #define MIPI_CAL_CONFIG_DSIA_CLK	0x19
207 #define MIPI_CAL_CONFIG_DSIB_CLK	0x1a
208 #define MIPI_CAL_CONFIG_CSIAB_CLK	0x1b
209 #define MIPI_CAL_CONFIG_DSIC_CLK	0x1c
210 #define MIPI_CAL_CONFIG_CSICD_CLK	0x1c
211 #define MIPI_CAL_CONFIG_DSID_CLK	0x1d
212 #define MIPI_CAL_CONFIG_CSIE_CLK	0x1d
213 
214 /* for data and clock lanes */
215 #define MIPI_CAL_CONFIG_SELECT		(1 << 21)
216 
217 /* for data lanes */
218 #define MIPI_CAL_CONFIG_HSPDOS(x)	(((x) & 0x1f) << 16)
219 #define MIPI_CAL_CONFIG_HSPUOS(x)	(((x) & 0x1f) <<  8)
220 #define MIPI_CAL_CONFIG_TERMOS(x)	(((x) & 0x1f) <<  0)
221 
222 /* for clock lanes */
223 #define MIPI_CAL_CONFIG_HSCLKPDOSD(x)	(((x) & 0x1f) <<  8)
224 #define MIPI_CAL_CONFIG_HSCLKPUOSD(x)	(((x) & 0x1f) <<  0)
225 
226 #define MIPI_CAL_BIAS_PAD_CFG0		0x16
227 #define MIPI_CAL_BIAS_PAD_PDVCLAMP	(1 << 1)
228 #define MIPI_CAL_BIAS_PAD_E_VCLAMP_REF	(1 << 0)
229 
230 #define MIPI_CAL_BIAS_PAD_CFG1		0x17
231 #define MIPI_CAL_BIAS_PAD_DRV_DN_REF(x) (((x) & 0x7) << 16)
232 #define MIPI_CAL_BIAS_PAD_DRV_UP_REF(x) (((x) & 0x7) << 8)
233 
234 #define MIPI_CAL_BIAS_PAD_CFG2		0x18
235 #define MIPI_CAL_BIAS_PAD_VCLAMP(x)	(((x) & 0x7) << 16)
236 #define MIPI_CAL_BIAS_PAD_VAUXP(x)	(((x) & 0x7) << 4)
237 #define MIPI_CAL_BIAS_PAD_PDVREG	(1 << 1)
238 
239 struct tegra_mipi_pad {
240 	unsigned long data;
241 	unsigned long clk;
242 };
243 
244 struct tegra_mipi_soc {
245 	int has_clk_lane;
246 	const struct tegra_mipi_pad *pads;
247 	unsigned int num_pads;
248 
249 	int clock_enable_override;
250 	int needs_vclamp_ref;
251 
252 	/* bias pad configuration settings */
253 	u8 pad_drive_down_ref;
254 	u8 pad_drive_up_ref;
255 
256 	u8 pad_vclamp_level;
257 	u8 pad_vauxp_level;
258 
259 	/* calibration settings for data lanes */
260 	u8 hspdos;
261 	u8 hspuos;
262 	u8 termos;
263 
264 	/* calibration settings for clock lanes */
265 	u8 hsclkpdos;
266 	u8 hsclkpuos;
267 };
268 
269 struct tegra_mipi {
270 	const struct tegra_mipi_soc *soc;
271 	void *regs;
272 };
273 
274 struct tegra_mipi_device {
275 	struct tegra_mipi *mipi;
276 	unsigned long pads;
277 };
278 
279 struct tegra_mipi_device *tegra_mipi_request(struct tegra_mipi_device *device,
280 						int device_index);
281 int tegra_mipi_calibrate(struct tegra_mipi_device *device);
282 #endif /* __SOC_MIPI_DSI_H__ */
283