xref: /openbmc/u-boot/drivers/video/ipu.h (revision e8f80a5a)
1*83d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
2575001e4SStefano Babic /*
3575001e4SStefano Babic  * Porting to u-boot:
4575001e4SStefano Babic  *
5575001e4SStefano Babic  * (C) Copyright 2010
6575001e4SStefano Babic  * Stefano Babic, DENX Software Engineering, sbabic@denx.de
7575001e4SStefano Babic  *
8575001e4SStefano Babic  * Linux IPU driver for MX51:
9575001e4SStefano Babic  *
10575001e4SStefano Babic  * (C) Copyright 2005-2010 Freescale Semiconductor, Inc.
11575001e4SStefano Babic  */
12575001e4SStefano Babic 
13575001e4SStefano Babic #ifndef __ASM_ARCH_IPU_H__
14575001e4SStefano Babic #define __ASM_ARCH_IPU_H__
15575001e4SStefano Babic 
16575001e4SStefano Babic #include <linux/types.h>
1792a98a4aSStefano Babic #include <ipu_pixfmt.h>
18575001e4SStefano Babic 
19575001e4SStefano Babic #define IDMA_CHAN_INVALID	0xFF
20575001e4SStefano Babic #define HIGH_RESOLUTION_WIDTH	1024
21575001e4SStefano Babic 
22575001e4SStefano Babic struct clk {
23575001e4SStefano Babic 	const char *name;
24575001e4SStefano Babic 	int id;
25575001e4SStefano Babic 	/* Source clock this clk depends on */
26575001e4SStefano Babic 	struct clk *parent;
27575001e4SStefano Babic 	/* Secondary clock to enable/disable with this clock */
28575001e4SStefano Babic 	struct clk *secondary;
29575001e4SStefano Babic 	/* Current clock rate */
30575001e4SStefano Babic 	unsigned long rate;
31575001e4SStefano Babic 	/* Reference count of clock enable/disable */
32575001e4SStefano Babic 	__s8 usecount;
33575001e4SStefano Babic 	/* Register bit position for clock's enable/disable control. */
34575001e4SStefano Babic 	u8 enable_shift;
35575001e4SStefano Babic 	/* Register address for clock's enable/disable control. */
36575001e4SStefano Babic 	void *enable_reg;
37575001e4SStefano Babic 	u32 flags;
38575001e4SStefano Babic 	/*
39575001e4SStefano Babic 	 * Function ptr to recalculate the clock's rate based on parent
40575001e4SStefano Babic 	 * clock's rate
41575001e4SStefano Babic 	 */
42575001e4SStefano Babic 	void (*recalc) (struct clk *);
43575001e4SStefano Babic 	/*
44575001e4SStefano Babic 	 * Function ptr to set the clock to a new rate. The rate must match a
45575001e4SStefano Babic 	 * supported rate returned from round_rate. Leave blank if clock is not
46575001e4SStefano Babic 	* programmable
47575001e4SStefano Babic 	 */
48575001e4SStefano Babic 	int (*set_rate) (struct clk *, unsigned long);
49575001e4SStefano Babic 	/*
50575001e4SStefano Babic 	 * Function ptr to round the requested clock rate to the nearest
51575001e4SStefano Babic 	 * supported rate that is less than or equal to the requested rate.
52575001e4SStefano Babic 	 */
53575001e4SStefano Babic 	unsigned long (*round_rate) (struct clk *, unsigned long);
54575001e4SStefano Babic 	/*
55575001e4SStefano Babic 	 * Function ptr to enable the clock. Leave blank if clock can not
56575001e4SStefano Babic 	 * be gated.
57575001e4SStefano Babic 	 */
58575001e4SStefano Babic 	int (*enable) (struct clk *);
59575001e4SStefano Babic 	/*
60575001e4SStefano Babic 	 * Function ptr to disable the clock. Leave blank if clock can not
61575001e4SStefano Babic 	 * be gated.
62575001e4SStefano Babic 	 */
63575001e4SStefano Babic 	void (*disable) (struct clk *);
64575001e4SStefano Babic 	/* Function ptr to set the parent clock of the clock. */
65575001e4SStefano Babic 	int (*set_parent) (struct clk *, struct clk *);
66575001e4SStefano Babic };
67575001e4SStefano Babic 
68575001e4SStefano Babic /*
69575001e4SStefano Babic  * Enumeration of Synchronous (Memory-less) panel types
70575001e4SStefano Babic  */
71575001e4SStefano Babic typedef enum {
72575001e4SStefano Babic 	IPU_PANEL_SHARP_TFT,
73575001e4SStefano Babic 	IPU_PANEL_TFT,
74575001e4SStefano Babic } ipu_panel_t;
75575001e4SStefano Babic 
76575001e4SStefano Babic /*
77575001e4SStefano Babic  * IPU Driver channels definitions.
78575001e4SStefano Babic  * Note these are different from IDMA channels
79575001e4SStefano Babic  */
80575001e4SStefano Babic #define IPU_MAX_CH	32
81575001e4SStefano Babic #define _MAKE_CHAN(num, v_in, g_in, a_in, out) \
82575001e4SStefano Babic 	((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out)
83575001e4SStefano Babic #define _MAKE_ALT_CHAN(ch)		(ch | (IPU_MAX_CH << 24))
84575001e4SStefano Babic #define IPU_CHAN_ID(ch)			(ch >> 24)
85575001e4SStefano Babic #define IPU_CHAN_ALT(ch)		(ch & 0x02000000)
86575001e4SStefano Babic #define IPU_CHAN_ALPHA_IN_DMA(ch)	((uint32_t) (ch >> 6) & 0x3F)
87575001e4SStefano Babic #define IPU_CHAN_GRAPH_IN_DMA(ch)	((uint32_t) (ch >> 12) & 0x3F)
88575001e4SStefano Babic #define IPU_CHAN_VIDEO_IN_DMA(ch)	((uint32_t) (ch >> 18) & 0x3F)
89575001e4SStefano Babic #define IPU_CHAN_OUT_DMA(ch)		((uint32_t) (ch & 0x3F))
90575001e4SStefano Babic #define NO_DMA 0x3F
91575001e4SStefano Babic #define ALT	1
92575001e4SStefano Babic 
93575001e4SStefano Babic /*
94575001e4SStefano Babic  * Enumeration of IPU logical channels. An IPU logical channel is defined as a
95575001e4SStefano Babic  * combination of an input (memory to IPU), output (IPU to memory), and/or
96575001e4SStefano Babic  * secondary input IDMA channels and in some cases an Image Converter task.
97575001e4SStefano Babic  * Some channels consist of only an input or output.
98575001e4SStefano Babic  */
99575001e4SStefano Babic typedef enum {
100575001e4SStefano Babic 	CHAN_NONE = -1,
101575001e4SStefano Babic 
102575001e4SStefano Babic 	MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA),
103575001e4SStefano Babic 	MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA),
104575001e4SStefano Babic 	MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA),
105575001e4SStefano Babic 	MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA),
106575001e4SStefano Babic 
107575001e4SStefano Babic 	MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA),
108575001e4SStefano Babic 	MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA),
109575001e4SStefano Babic 	MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0),
110575001e4SStefano Babic 	MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0),
111575001e4SStefano Babic 
112575001e4SStefano Babic 	DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
113575001e4SStefano Babic 	DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
114575001e4SStefano Babic 
115575001e4SStefano Babic } ipu_channel_t;
116575001e4SStefano Babic 
117575001e4SStefano Babic /*
118575001e4SStefano Babic  * Enumeration of types of buffers for a logical channel.
119575001e4SStefano Babic  */
120575001e4SStefano Babic typedef enum {
121575001e4SStefano Babic 	IPU_OUTPUT_BUFFER = 0,	/*< Buffer for output from IPU */
122575001e4SStefano Babic 	IPU_ALPHA_IN_BUFFER = 1,	/*< Buffer for input to IPU */
123575001e4SStefano Babic 	IPU_GRAPH_IN_BUFFER = 2,	/*< Buffer for input to IPU */
124575001e4SStefano Babic 	IPU_VIDEO_IN_BUFFER = 3,	/*< Buffer for input to IPU */
125575001e4SStefano Babic 	IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER,
126575001e4SStefano Babic 	IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER,
127575001e4SStefano Babic } ipu_buffer_t;
128575001e4SStefano Babic 
129575001e4SStefano Babic #define IPU_PANEL_SERIAL		1
130575001e4SStefano Babic #define IPU_PANEL_PARALLEL		2
131575001e4SStefano Babic 
132575001e4SStefano Babic struct ipu_channel {
133575001e4SStefano Babic 	u8 video_in_dma;
134575001e4SStefano Babic 	u8 alpha_in_dma;
135575001e4SStefano Babic 	u8 graph_in_dma;
136575001e4SStefano Babic 	u8 out_dma;
137575001e4SStefano Babic };
138575001e4SStefano Babic 
139575001e4SStefano Babic enum ipu_dmfc_type {
140575001e4SStefano Babic 	DMFC_NORMAL = 0,
141575001e4SStefano Babic 	DMFC_HIGH_RESOLUTION_DC,
142575001e4SStefano Babic 	DMFC_HIGH_RESOLUTION_DP,
143575001e4SStefano Babic 	DMFC_HIGH_RESOLUTION_ONLY_DP,
144575001e4SStefano Babic };
145575001e4SStefano Babic 
146575001e4SStefano Babic 
147575001e4SStefano Babic /*
148575001e4SStefano Babic  * Union of initialization parameters for a logical channel.
149575001e4SStefano Babic  */
150575001e4SStefano Babic typedef union {
151575001e4SStefano Babic 	struct {
152575001e4SStefano Babic 		uint32_t di;
153575001e4SStefano Babic 		unsigned char interlaced;
154575001e4SStefano Babic 	} mem_dc_sync;
155575001e4SStefano Babic 	struct {
156575001e4SStefano Babic 		uint32_t temp;
157575001e4SStefano Babic 	} mem_sdc_fg;
158575001e4SStefano Babic 	struct {
159575001e4SStefano Babic 		uint32_t di;
160575001e4SStefano Babic 		unsigned char interlaced;
161575001e4SStefano Babic 		uint32_t in_pixel_fmt;
162575001e4SStefano Babic 		uint32_t out_pixel_fmt;
163575001e4SStefano Babic 		unsigned char alpha_chan_en;
164575001e4SStefano Babic 	} mem_dp_bg_sync;
165575001e4SStefano Babic 	struct {
166575001e4SStefano Babic 		uint32_t temp;
167575001e4SStefano Babic 	} mem_sdc_bg;
168575001e4SStefano Babic 	struct {
169575001e4SStefano Babic 		uint32_t di;
170575001e4SStefano Babic 		unsigned char interlaced;
171575001e4SStefano Babic 		uint32_t in_pixel_fmt;
172575001e4SStefano Babic 		uint32_t out_pixel_fmt;
173575001e4SStefano Babic 		unsigned char alpha_chan_en;
174575001e4SStefano Babic 	} mem_dp_fg_sync;
175575001e4SStefano Babic } ipu_channel_params_t;
176575001e4SStefano Babic 
177575001e4SStefano Babic /*
178e66866c5SLiu Ying  * Enumeration of IPU interrupts.
179e66866c5SLiu Ying  */
180e66866c5SLiu Ying enum ipu_irq_line {
181e66866c5SLiu Ying 	IPU_IRQ_DP_SF_END = 448 + 3,
182e66866c5SLiu Ying 	IPU_IRQ_DC_FC_1 = 448 + 9,
183e66866c5SLiu Ying };
184e66866c5SLiu Ying 
185e66866c5SLiu Ying /*
186575001e4SStefano Babic  * Bitfield of Display Interface signal polarities.
187575001e4SStefano Babic  */
188575001e4SStefano Babic typedef struct {
189575001e4SStefano Babic 	unsigned datamask_en:1;
190575001e4SStefano Babic 	unsigned ext_clk:1;
191575001e4SStefano Babic 	unsigned interlaced:1;
192575001e4SStefano Babic 	unsigned odd_field_first:1;
193575001e4SStefano Babic 	unsigned clksel_en:1;
194575001e4SStefano Babic 	unsigned clkidle_en:1;
195575001e4SStefano Babic 	unsigned data_pol:1;	/* true = inverted */
196575001e4SStefano Babic 	unsigned clk_pol:1;	/* true = rising edge */
197575001e4SStefano Babic 	unsigned enable_pol:1;
198575001e4SStefano Babic 	unsigned Hsync_pol:1;	/* true = active high */
199575001e4SStefano Babic 	unsigned Vsync_pol:1;
200575001e4SStefano Babic } ipu_di_signal_cfg_t;
201575001e4SStefano Babic 
202575001e4SStefano Babic typedef enum {
203575001e4SStefano Babic 	RGB,
204575001e4SStefano Babic 	YCbCr,
205575001e4SStefano Babic 	YUV
206575001e4SStefano Babic } ipu_color_space_t;
207575001e4SStefano Babic 
208575001e4SStefano Babic /* Common IPU API */
209575001e4SStefano Babic int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t *params);
210575001e4SStefano Babic void ipu_uninit_channel(ipu_channel_t channel);
211575001e4SStefano Babic 
212575001e4SStefano Babic int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type,
213575001e4SStefano Babic 				uint32_t pixel_fmt,
214575001e4SStefano Babic 				uint16_t width, uint16_t height,
215575001e4SStefano Babic 				uint32_t stride,
216575001e4SStefano Babic 				dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
217575001e4SStefano Babic 				uint32_t u_offset, uint32_t v_offset);
218575001e4SStefano Babic 
219575001e4SStefano Babic int32_t ipu_update_channel_buffer(ipu_channel_t channel, ipu_buffer_t type,
220575001e4SStefano Babic 				  uint32_t bufNum, dma_addr_t phyaddr);
221575001e4SStefano Babic 
222575001e4SStefano Babic int32_t ipu_is_channel_busy(ipu_channel_t channel);
223575001e4SStefano Babic void ipu_clear_buffer_ready(ipu_channel_t channel, ipu_buffer_t type,
224575001e4SStefano Babic 		uint32_t bufNum);
225575001e4SStefano Babic int32_t ipu_enable_channel(ipu_channel_t channel);
226575001e4SStefano Babic int32_t ipu_disable_channel(ipu_channel_t channel);
227575001e4SStefano Babic 
228575001e4SStefano Babic int32_t ipu_init_sync_panel(int disp,
229575001e4SStefano Babic 			    uint32_t pixel_clk,
230575001e4SStefano Babic 			    uint16_t width, uint16_t height,
231575001e4SStefano Babic 			    uint32_t pixel_fmt,
232575001e4SStefano Babic 			    uint16_t h_start_width, uint16_t h_sync_width,
233575001e4SStefano Babic 			    uint16_t h_end_width, uint16_t v_start_width,
234575001e4SStefano Babic 			    uint16_t v_sync_width, uint16_t v_end_width,
235575001e4SStefano Babic 			    uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig);
236575001e4SStefano Babic 
237575001e4SStefano Babic int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable,
238575001e4SStefano Babic 				  uint8_t alpha);
239575001e4SStefano Babic int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable,
240575001e4SStefano Babic 			       uint32_t colorKey);
241575001e4SStefano Babic 
242575001e4SStefano Babic uint32_t bytes_per_pixel(uint32_t fmt);
243575001e4SStefano Babic 
244575001e4SStefano Babic void clk_enable(struct clk *clk);
245575001e4SStefano Babic void clk_disable(struct clk *clk);
246575001e4SStefano Babic u32 clk_get_rate(struct clk *clk);
247575001e4SStefano Babic int clk_set_rate(struct clk *clk, unsigned long rate);
248575001e4SStefano Babic long clk_round_rate(struct clk *clk, unsigned long rate);
249575001e4SStefano Babic int clk_set_parent(struct clk *clk, struct clk *parent);
250575001e4SStefano Babic int clk_get_usecount(struct clk *clk);
251575001e4SStefano Babic struct clk *clk_get_parent(struct clk *clk);
252575001e4SStefano Babic 
253575001e4SStefano Babic void ipu_dump_registers(void);
254575001e4SStefano Babic int ipu_probe(void);
255f8ba7f27SAnatolij Gustschin bool ipu_clk_enabled(void);
256575001e4SStefano Babic 
257575001e4SStefano Babic void ipu_dmfc_init(int dmfc_type, int first);
258575001e4SStefano Babic void ipu_init_dc_mappings(void);
259575001e4SStefano Babic void ipu_dmfc_set_wait4eot(int dma_chan, int width);
260575001e4SStefano Babic void ipu_dc_init(int dc_chan, int di, unsigned char interlaced);
261575001e4SStefano Babic void ipu_dc_uninit(int dc_chan);
262575001e4SStefano Babic void ipu_dp_dc_enable(ipu_channel_t channel);
263575001e4SStefano Babic int ipu_dp_init(ipu_channel_t channel, uint32_t in_pixel_fmt,
264575001e4SStefano Babic 		 uint32_t out_pixel_fmt);
265575001e4SStefano Babic void ipu_dp_uninit(ipu_channel_t channel);
266575001e4SStefano Babic void ipu_dp_dc_disable(ipu_channel_t channel, unsigned char swap);
267575001e4SStefano Babic ipu_color_space_t format_to_colorspace(uint32_t fmt);
268575001e4SStefano Babic #endif
269