1 /*
2  * Copyright (C) 2011 Texas Instruments Incorporated - https://www.ti.com/
3  * Author: Rob Clark <rob@ti.com>
4  *         Andy Gross <andy.gross@ti.com>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation version 2.
9  *
10  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11  * kind, whether express or implied; without even the implied warranty
12  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15 
16 #ifndef OMAP_DMM_PRIV_H
17 #define OMAP_DMM_PRIV_H
18 
19 #define DMM_REVISION          0x000
20 #define DMM_HWINFO            0x004
21 #define DMM_LISA_HWINFO       0x008
22 #define DMM_DMM_SYSCONFIG     0x010
23 #define DMM_LISA_LOCK         0x01C
24 #define DMM_LISA_MAP__0       0x040
25 #define DMM_LISA_MAP__1       0x044
26 #define DMM_TILER_HWINFO      0x208
27 #define DMM_TILER_OR__0       0x220
28 #define DMM_TILER_OR__1       0x224
29 #define DMM_PAT_HWINFO        0x408
30 #define DMM_PAT_GEOMETRY      0x40C
31 #define DMM_PAT_CONFIG        0x410
32 #define DMM_PAT_VIEW__0       0x420
33 #define DMM_PAT_VIEW__1       0x424
34 #define DMM_PAT_VIEW_MAP__0   0x440
35 #define DMM_PAT_VIEW_MAP_BASE 0x460
36 #define DMM_PAT_IRQ_EOI       0x478
37 #define DMM_PAT_IRQSTATUS_RAW 0x480
38 #define DMM_PAT_IRQSTATUS     0x490
39 #define DMM_PAT_IRQENABLE_SET 0x4A0
40 #define DMM_PAT_IRQENABLE_CLR 0x4B0
41 #define DMM_PAT_STATUS__0     0x4C0
42 #define DMM_PAT_STATUS__1     0x4C4
43 #define DMM_PAT_STATUS__2     0x4C8
44 #define DMM_PAT_STATUS__3     0x4CC
45 #define DMM_PAT_DESCR__0      0x500
46 #define DMM_PAT_DESCR__1      0x510
47 #define DMM_PAT_DESCR__2      0x520
48 #define DMM_PAT_DESCR__3      0x530
49 #define DMM_PEG_HWINFO        0x608
50 #define DMM_PEG_PRIO          0x620
51 #define DMM_PEG_PRIO_PAT      0x640
52 
53 #define DMM_IRQSTAT_DST			(1<<0)
54 #define DMM_IRQSTAT_LST			(1<<1)
55 #define DMM_IRQSTAT_ERR_INV_DSC		(1<<2)
56 #define DMM_IRQSTAT_ERR_INV_DATA	(1<<3)
57 #define DMM_IRQSTAT_ERR_UPD_AREA	(1<<4)
58 #define DMM_IRQSTAT_ERR_UPD_CTRL	(1<<5)
59 #define DMM_IRQSTAT_ERR_UPD_DATA	(1<<6)
60 #define DMM_IRQSTAT_ERR_LUT_MISS	(1<<7)
61 
62 #define DMM_IRQSTAT_ERR_MASK	(DMM_IRQSTAT_ERR_INV_DSC | \
63 				DMM_IRQSTAT_ERR_INV_DATA | \
64 				DMM_IRQSTAT_ERR_UPD_AREA | \
65 				DMM_IRQSTAT_ERR_UPD_CTRL | \
66 				DMM_IRQSTAT_ERR_UPD_DATA | \
67 				DMM_IRQSTAT_ERR_LUT_MISS)
68 
69 #define DMM_PATSTATUS_READY		(1<<0)
70 #define DMM_PATSTATUS_VALID		(1<<1)
71 #define DMM_PATSTATUS_RUN		(1<<2)
72 #define DMM_PATSTATUS_DONE		(1<<3)
73 #define DMM_PATSTATUS_LINKED		(1<<4)
74 #define DMM_PATSTATUS_BYPASSED		(1<<7)
75 #define DMM_PATSTATUS_ERR_INV_DESCR	(1<<10)
76 #define DMM_PATSTATUS_ERR_INV_DATA	(1<<11)
77 #define DMM_PATSTATUS_ERR_UPD_AREA	(1<<12)
78 #define DMM_PATSTATUS_ERR_UPD_CTRL	(1<<13)
79 #define DMM_PATSTATUS_ERR_UPD_DATA	(1<<14)
80 #define DMM_PATSTATUS_ERR_ACCESS	(1<<15)
81 
82 /* note: don't treat DMM_PATSTATUS_ERR_ACCESS as an error */
83 #define DMM_PATSTATUS_ERR	(DMM_PATSTATUS_ERR_INV_DESCR | \
84 				DMM_PATSTATUS_ERR_INV_DATA | \
85 				DMM_PATSTATUS_ERR_UPD_AREA | \
86 				DMM_PATSTATUS_ERR_UPD_CTRL | \
87 				DMM_PATSTATUS_ERR_UPD_DATA)
88 
89 
90 
91 enum {
92 	PAT_STATUS,
93 	PAT_DESCR
94 };
95 
96 struct pat_ctrl {
97 	u32 start:4;
98 	u32 dir:4;
99 	u32 lut_id:8;
100 	u32 sync:12;
101 	u32 ini:4;
102 };
103 
104 struct pat {
105 	u32 next_pa;
106 	struct pat_area area;
107 	struct pat_ctrl ctrl;
108 	u32 data_pa;
109 };
110 
111 #define DMM_FIXED_RETRY_COUNT 1000
112 
113 /* create refill buffer big enough to refill all slots, plus 3 descriptors..
114  * 3 descriptors is probably the worst-case for # of 2d-slices in a 1d area,
115  * but I guess you don't hit that worst case at the same time as full area
116  * refill
117  */
118 #define DESCR_SIZE 128
119 #define REFILL_BUFFER_SIZE ((4 * 128 * 256) + (3 * DESCR_SIZE))
120 
121 /* For OMAP5, a fixed offset is added to all Y coordinates for 1D buffers.
122  * This is used in programming to address the upper portion of the LUT
123 */
124 #define OMAP5_LUT_OFFSET       128
125 
126 struct dmm;
127 
128 struct dmm_txn {
129 	void *engine_handle;
130 	struct tcm *tcm;
131 
132 	u8 *current_va;
133 	dma_addr_t current_pa;
134 
135 	struct pat *last_pat;
136 };
137 
138 struct refill_engine {
139 	int id;
140 	struct dmm *dmm;
141 	struct tcm *tcm;
142 
143 	u8 *refill_va;
144 	dma_addr_t refill_pa;
145 
146 	/* only one trans per engine for now */
147 	struct dmm_txn txn;
148 
149 	bool async;
150 
151 	struct completion compl;
152 
153 	struct list_head idle_node;
154 };
155 
156 struct dmm_platform_data {
157 	u32 cpu_cache_flags;
158 };
159 
160 struct dmm {
161 	struct device *dev;
162 	dma_addr_t phys_base;
163 	void __iomem *base;
164 	int irq;
165 
166 	struct page *dummy_page;
167 	dma_addr_t dummy_pa;
168 
169 	void *refill_va;
170 	dma_addr_t refill_pa;
171 
172 	/* refill engines */
173 	wait_queue_head_t engine_queue;
174 	struct list_head idle_head;
175 	struct refill_engine *engines;
176 	int num_engines;
177 	atomic_t engine_counter;
178 
179 	/* container information */
180 	int container_width;
181 	int container_height;
182 	int lut_width;
183 	int lut_height;
184 	int num_lut;
185 
186 	/* array of LUT - TCM containers */
187 	struct tcm **tcm;
188 
189 	/* allocation list and lock */
190 	struct list_head alloc_head;
191 
192 	const struct dmm_platform_data *plat_data;
193 
194 	bool dmm_workaround;
195 	spinlock_t wa_lock;
196 	u32 *wa_dma_data;
197 	dma_addr_t wa_dma_handle;
198 	struct dma_chan *wa_dma_chan;
199 };
200 
201 #endif
202