]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - ipc/ipcdev.git/blob - qnx/src/ipc3x_dev/tiler/tiler_pat/dmm.c
Tests: Update tests to support concurrently loaded slaves
[ipc/ipcdev.git] / qnx / src / ipc3x_dev / tiler / tiler_pat / dmm.c
1 /*
2  * Copyright (c) 2010, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  * */
32 /*
33  * dmm.c
34  *
35  * DMM driver support functions for TI OMAP processors.
36  */
37 #include "proto.h"
38 #include "dmm.h"
40 #define BITS_32(in_NbBits) ((((u32)1 << in_NbBits) - 1) | ((u32)1 << in_NbBits))
41 #define BITFIELD_32(in_UpBit, in_LowBit)\
42         (BITS_32(in_UpBit) & ~((BITS_32(in_LowBit)) >> 1))
43 #define BF BITFIELD_32
46 /* IMPORTANT NOTE: This function needs to be IRQ safe.  Adding traces
47  * or other non-interrupt safe calls to it will result in a crash in
48  * CPU dll. */
49 s32 dmm_pat_refill(struct dmm *dmm, struct pat *pd, enum pat_mode mode)
50 {
51         uintptr_t r = NULL;
52         u32 v = -1, w = -1;
54         /* Only manual refill supported */
55         if (mode != MANUAL)
56                 return -EFAULT;
58         /*
59          * Check that the DMM_PAT_STATUS register
60          * has not reported an error.
61         */
62         r = (uintptr_t)((u32)dmm->base | DMM_PAT_STATUS__0);
63         v = __raw_readl(r);
64         if ((v & 0xFC00) != 0) {
65                 return -EFAULT;
66         }
68         /* Set "next" register to NULL */
69         r = (uintptr_t)((u32)dmm->base | DMM_PAT_DESCR__0);
70         v = __raw_readl(r);
71         w = (v & (~(BF(31, 4)))) | ((((u32)NULL) << 4) & BF(31, 4));
72         __raw_writel(w, r);
74         /* Set area to be refilled */
75         r = (uintptr_t)((u32)dmm->base | DMM_PAT_AREA__0);
76         v = __raw_readl(r);
77 #ifdef TILER_PLATFORM_OMAP5
78         w = (v & (~(BF(31, 24)))) | ((((s8)pd->area.y1) << 24) & BF(31, 24));
79 #else
80         w = (v & (~(BF(30, 24)))) | ((((s8)pd->area.y1) << 24) & BF(30, 24));
81 #endif
82         __raw_writel(w, r);
84         v = __raw_readl(r);
85         w = (v & (~(BF(23, 16)))) | ((((s8)pd->area.x1) << 16) & BF(23, 16));
86         __raw_writel(w, r);
88         v = __raw_readl(r);
89 #ifdef TILER_PLATFORM_OMAP5
90         w = (v & (~(BF(15, 8)))) | ((((s8)pd->area.y0) << 8) & BF(15, 8));
91 #else
92         w = (v & (~(BF(14, 8)))) | ((((s8)pd->area.y0) << 8) & BF(14, 8));
93 #endif
94         __raw_writel(w, r);
96         v = __raw_readl(r);
97         w = (v & (~(BF(7, 0)))) | ((((s8)pd->area.x0) << 0) & BF(7, 0));
98         __raw_writel(w, r);
99         wmb();
101         /* First, clear the DMM_PAT_IRQSTATUS register */
102         r = (uintptr_t)((u32)dmm->base | (u32)DMM_PAT_IRQSTATUS);
103         __raw_writel(0xFFFFFFFF, r);
104         wmb();
106         r = (uintptr_t)((u32)dmm->base | (u32)DMM_PAT_IRQSTATUS_RAW);
107         v = 0xFFFFFFFF;
109         while (v != 0x0) {
110                 v = __raw_readl(r);
111         }
113         /* Fill data register */
114         r = (uintptr_t)((u32)dmm->base | DMM_PAT_DATA__0);
115         v = __raw_readl(r);
117         /* Apply 4 bit left shft to counter the 4 bit right shift */
118         w = (v & (~(BF(31, 4)))) | ((((u32)(pd->data >> 4)) << 4) & BF(31, 4));
119         __raw_writel(w, r);
120         wmb();
122         /* Read back PAT_DATA__0 to see if write was successful */
123         v = 0x0;
124         while (v != pd->data) {
125                 v = __raw_readl(r);
126         }
128         r = (uintptr_t)((u32)dmm->base | (u32)DMM_PAT_CTRL__0);
129         v = __raw_readl(r);
131         w = (v & (~(BF(31, 28)))) | ((((u32)pd->ctrl.ini) << 28) & BF(31, 28));
132         __raw_writel(w, r);
134         v = __raw_readl(r);
135         w = (v & (~(BF(16, 16)))) | ((((u32)pd->ctrl.sync) << 16) & BF(16, 16));
136         __raw_writel(w, r);
138         v = __raw_readl(r);
139         w = (v & (~(BF(9, 8)))) | ((((u32)pd->ctrl.lut_id) << 8) & BF(9, 8));
140         __raw_writel(w, r);
142         v = __raw_readl(r);
143         w = (v & (~(BF(6, 4)))) | ((((u32)pd->ctrl.dir) << 4) & BF(6, 4));
144         __raw_writel(w, r);
146         v = __raw_readl(r);
147         w = (v & (~(BF(0, 0)))) | ((((u32)pd->ctrl.start) << 0) & BF(0, 0));
148         __raw_writel(w, r);
149         wmb();
151         /*
152          * Now, check if PAT_IRQSTATUS_RAW has been
153          * set after the PAT has been refilled
154          */
155         r = (uintptr_t)((u32)dmm->base | (u32)DMM_PAT_IRQSTATUS_RAW);
156         v = 0x0;
157         while ((v & 0x3) != 0x3) {
158                 v = __raw_readl(r);
159         }
161         /* Again, clear the DMM_PAT_IRQSTATUS register */
162         r = (uintptr_t)((u32)dmm->base | (u32)DMM_PAT_IRQSTATUS);
163         __raw_writel(0xFFFFFFFF, r);
164         wmb();
166         r = (uintptr_t)((u32)dmm->base | (u32)DMM_PAT_IRQSTATUS_RAW);
167         v = 0xFFFFFFFF;
169         while (v != 0x0) {
170                 v = __raw_readl(r);
171         }
173         /* Again, set "next" register to NULL to clear any PAT STATUS errors */
174         r = (uintptr_t)((u32)dmm->base | DMM_PAT_DESCR__0);
175         v = __raw_readl(r);
176         w = (v & (~(BF(31, 4)))) | ((((u32)NULL) << 4) & BF(31, 4));
177         __raw_writel(w, r);
179         /*
180          * Now, check that the DMM_PAT_STATUS register
181          * has not reported an error before exiting.
182         */
183         r = (uintptr_t)((u32)dmm->base | DMM_PAT_STATUS__0);
184         v = __raw_readl(r);
185         if ((v & 0xFC00) != 0) {
186                 return -EFAULT;
187         }
189         return 0;
192 struct dmm *dmm_pat_init(u32 id)
194         u32 base = 0;
195         struct dmm *dmm = NULL;
196         switch (id) {
197         case 0:
198                 /* only support id 0 for now */
199                 base = DMM_BASE;
200                 break;
201         default:
202                 return NULL;
203         }
205         dmm = kmalloc(sizeof(*dmm), GFP_KERNEL);
206         if (!dmm)
207                 return NULL;
209         dmm->base = mmap_device_io(DMM_SIZE, base);
210         if (!dmm->base) {
211                 kfree(dmm);
212                 return NULL;
213         }
215         __raw_writel(0x88888888, dmm->base + DMM_PAT_VIEW__0);
216         __raw_writel(0x88888888, dmm->base + DMM_PAT_VIEW__1);
217         __raw_writel(0x80808080, dmm->base + DMM_PAT_VIEW_MAP__0);
218         __raw_writel(0x80000000, dmm->base + DMM_PAT_VIEW_MAP_BASE);
219         __raw_writel(0x88888888, dmm->base + DMM_TILER_OR__0);
220         __raw_writel(0x88888888, dmm->base + DMM_TILER_OR__1);
222         /* Set PEG to zero for ISS */
223         __raw_writel(0x8, dmm->base + DMM_PEG_PRIO + 0x4 * 2);
225         return dmm;
228 /**
229  * Clean up the physical address translator.
230  * @param dmm    Device data
231  * @return an error status.
232  */
233 void dmm_pat_release(struct dmm *dmm)
235         if (dmm) {
236                 munmap_device_io(dmm->base, DMM_SIZE);
237                 kfree(dmm);
238         }
241 s32 dmm_init(void)
243         return 0;
246 void dmm_exit(void)
248         return;