initial version
[glsdk/dra7xx-umlo.git] / main.c
1 /*
2  * (C) Copyright 2017
3  * Texas Instruments Incorporated, <www.ti.com>
4  *
5  * Venkateswara Rao Mandela <venkat.mandela@ti.com>
6  *
7  * SPDX-License-Identifier:     BSD-3-Clause
8  */
9 #include "common.h"
11 typedef void __attribute__((noreturn)) (*mlo_func_proto)(uint32_t *);
13 #define COUNTER32K_CR                   (0x4AE04030)
14 #define QSPI_MMAP_BASE                  (0x5C000000)
15 #define CM_L3MAIN1_TPCC_CLKCTRL         (0x4A008770)
16 #define CM_L3MAIN1_TPTC1_CLKCTRL        (0x4A008778)
17 #define CM_L3MAIN1_TPTC2_CLKCTRL        (0x4A008780)
18 #define CM_L4PER2_QSPI_CLKCTRL          (0x4A009838)
19 #define CTRL_CORE_CONTROL_IO_2          (0x4A002558)
20 #define EDMA_BASE                       (0x43300000)
21 #define EDMA_PARAM_0                    (0x43304000)
22 #define EDMA_TPCC_ESR                   (0x43301010)
23 #define EDMA_TPCC_EESR                  (0x43301030)
24 #define EDMA_TPCC_IPR                   (0x43301068)
25 #define EDMA_TPCC_ICR                   (0x43301070)
27 #define QSPI_CMD_READ_QUAD              (0x6c << 0)
28 #define QSPI_SETUP0_NUM_A_BYTES         (0x3 << 8)
29 #define QSPI_SETUP0_NUM_D_BYTES_8_BITS  (0x1 << 10)
30 #define QSPI_SETUP0_READ_QUAD           (0x3 << 12)
31 #define QSPI_CMD_WRITE                  (0x12 << 16)
32 #define QSPI_NUM_DUMMY_BITS             (0x0 << 24)
33 #define QSPI_SPI_CLOCK_CNTRL_REG        (0x4B300040)
34 #define QSPI_SPI_DC_REG                 (0x4B300044)
35 #define QSPI_SPI_STATUS_REG             (0x4B30004C)
36 #define QSPI_SPI_SETUP0_REG             (0x4B300054)
37 #define QSPI_SPI_SWITCH_REG             (0x4B300064)
38 #define QSPI_SPI_CMD_REG                (0x4B300048)
40 #define CTRL_CORE_PAD_GPMC_A13 (0x4A003474)
41 #define CTRL_CORE_PAD_GPMC_A14 (0x4A003478)
42 #define CTRL_CORE_PAD_GPMC_A15 (0x4A00347C)
43 #define CTRL_CORE_PAD_GPMC_A16 (0x4A003480)
44 #define CTRL_CORE_PAD_GPMC_A17 (0x4A003484)
45 #define CTRL_CORE_PAD_GPMC_A18 (0x4A003488)
46 #define CTRL_CORE_PAD_GPMC_CS2 (0x4A0034B8)
49 #define CM_DIV_H13_DPLL_PER (0x4A008160)
51 struct edma_param_entry {
52         /** OPT field of PaRAM Set */
53         u32 opt;
55         /**
56          * @brief Starting byte address of Source
57          * For FIFO mode, src_addr must be a 256-bit aligned address.
58          */
59         u32 src_addr;
61         /**
62          * @brief Number of bytes in each Array (ACNT)
63          */
64         u16 a_cnt;
66         /**
67          * @brief Number of Arrays in each Frame (BCNT)
68          */
69         u16 b_cnt;
71         /**
72          * @brief Starting byte address of destination
73          * For FIFO mode, dest_addr must be a 256-bit aligned address.
74          * i.e. 5 LSBs should be 0.
75          */
76         u32 dest_addr;
78         /**
79          * @brief Index between consec. arrays of a Source Frame (SRCBIDX)
80          */
81         s16 src_bidx;
83         /**
84          * @brief Index between consec. arrays of a Destination Frame (DSTBIDX)
85          */
86         s16 dest_bidx;
88         /**
89          * @brief Address for linking (AutoReloading of a PaRAM Set)
90          * This must point to a valid aligned 32-byte PaRAM set
91          * A value of 0xFFFF means no linking
92          */
93         u16 link_addr;
95         /**
96          * @brief Reload value of the numArrInFrame (BCNT)
97          * Relevant only for A-sync transfers
98          */
99         u16 b_cnt_reload;
101         /**
102          * @brief Index between consecutive frames of a Source Block (SRCCIDX)
103          */
104         s16 src_cidx;
106         /**
107          * @brief Index between consecutive frames of a Dest Block (DSTCIDX)
108          */
109         s16 dest_cidx;
111         /**
112          * @brief Number of Frames in a block (CCNT)
113          */
114         u16 c_cnt;
116         /**
117          * @brief reserved member.
118          */
119         u16 rsv;
120 } __packed;
121 u32 edma_clkctrl[2] = {
122         CM_L3MAIN1_TPTC1_CLKCTRL,
123         CM_L3MAIN1_TPTC2_CLKCTRL,
124 };
126 volatile int ccs_dbg_flag = 1;
127 void wait_for_debugger(void)
129         ccs_dbg_flag = 1;
130         while (ccs_dbg_flag == 1) {
131                 asm(" NOP");
132         }
133         return;
136 static u32 read_fast_counter(void)
138         u32 reg_val = (u32) reg_read16(COUNTER32K_CR);
139         reg_val |= (u32)(reg_read16(COUNTER32K_CR+2) << 16);
140         return reg_val;
143 static void wait_qspi_idle(void)
145         u32 addr = QSPI_SPI_STATUS_REG;
146         u32 val, reg;
148         do {
149                 reg = reg_read32(addr);
150                 val = FLD_GET(reg, 0, 0);
151         } while (val != 0);
154 u32 pinmux[7] = {
155         CTRL_CORE_PAD_GPMC_A13,
156         CTRL_CORE_PAD_GPMC_A14,
157         CTRL_CORE_PAD_GPMC_A15,
158         CTRL_CORE_PAD_GPMC_A16,
159         CTRL_CORE_PAD_GPMC_A17,
160         CTRL_CORE_PAD_GPMC_A18,
161         CTRL_CORE_PAD_GPMC_CS2,
162 };
163 void set_qspi_pinmux(void)
165         u32 i = 0;
167         /* Match pinmux settings from ROM */
168         for (i = 0; i < 7; i++) {
169                 reg_write32(pinmux[i], 0x40001);
170         }
171         reg_write32(pinmux[6], 0x60001);
174 void set_qspi_clock(void)
176         /* set qspi clock to 76.8 MHz */
177         u32 addr = CM_L4PER2_QSPI_CLKCTRL;
178         u32 reg;
179         u32 t;
180         u32 div = 0;
182         /* Reset QSPI CLKCTRL to default */
183         reg_write32(addr, 0x0);
185         /* Wait until QSPI is off */
186         do {
187                 reg = reg_read32(addr);
188                 t = FLD_GET(reg, 17, 16);
189         } while (t != 3);
192         /* Set DPLL PER divider to 10 => output 76.8 MHz */
193         reg = reg_read32(CM_DIV_H13_DPLL_PER);
194         reg= FLD_MOD(reg, 10, 5, 0);
195         reg_write32(CM_DIV_H13_DPLL_PER, reg);
197         reg = 0x0;
198 #if 1
199         /* Default Clock is from DPLL_PER H13*/
200         reg = FLD_MOD(reg, 1, 24, 24);
201         /* Set divider to 1 for interface clock of 76.8 MHz */
202         reg = FLD_MOD(reg, 0, 26, 25);
203 #else
204         /* Default Clock is from 128 MHz clock */
205         reg = FLD_MOD(reg, 0, 24, 24);
206         /* Set divider to 1 to for interface clock of 64 MHz */
207         reg = FLD_MOD(reg, 1, 26, 25);
208 #endif
209         /* Enable QSPI. */
210         reg = FLD_MOD(reg, 2, 1, 0);
211         reg_write32(addr, reg);
212         do {
213                 reg = reg_read32(addr);
214                 t = FLD_GET(reg, 17, 16);
215         } while (t != 0);
217         wait_qspi_idle();
219         /* turn off QSPI clock */
220         reg = reg_read32(QSPI_SPI_CLOCK_CNTRL_REG);
221         reg = FLD_MOD(reg, 0, 31, 31);
222         reg_write32(QSPI_SPI_CLOCK_CNTRL_REG, reg);
224         /* write divider */
225         reg = FLD_MOD(reg, div, 15, 0);
226         reg_write32(QSPI_SPI_CLOCK_CNTRL_REG, reg);
228         /* enable qspi clock */
229         reg = FLD_MOD(reg, 1, 31, 31);
230         reg_write32(QSPI_SPI_CLOCK_CNTRL_REG, reg);
232         /* Set the Mode for CS0 to mode 0 */
233         addr = QSPI_SPI_DC_REG;
234         reg = reg_read32(addr);
235         reg = FLD_MOD(reg, 0, 4, 0);
236         reg_write32(addr, reg);
238         return;
241 void enable_qspi_mmap(void)
243         u32 addr = CTRL_CORE_CONTROL_IO_2;
244         u32 reg;
247         /* Setup command for CS 0 */
248         reg = (QSPI_CMD_READ_QUAD | QSPI_SETUP0_NUM_A_BYTES |
249                QSPI_SETUP0_NUM_D_BYTES_8_BITS |
250                QSPI_SETUP0_READ_QUAD | QSPI_CMD_WRITE |
251                QSPI_NUM_DUMMY_BITS);
253         reg_write32(QSPI_SPI_SETUP0_REG, reg);
255         reg_write32(QSPI_SPI_SWITCH_REG, 0x1);
257         reg = reg_read32(addr);
258         reg = FLD_MOD(reg, 1, 10, 8);
259         reg_write32(addr, reg);
262 void disable_qspi_mmap(void)
264         u32 addr = CTRL_CORE_CONTROL_IO_2;
265         u32 reg;
267         reg = reg_read32(addr);
268         reg = FLD_MOD(reg, 0, 10, 8);
269         reg_write32(addr, reg);
272 void enable_edma(void)
274         u32 i = 0;
275         for(i = 0; i < 2; i++) {
276                 u32 addr = edma_clkctrl[i];
277                 u32 reg;
278                 u32 t;
280                 reg = reg_read32(addr);
281                 reg = FLD_MOD(reg, 1, 1, 0);
283                 reg_write32(addr, reg);
285                 do {
286                         reg = reg_read32(addr);
287                         t = FLD_GET(reg, 17, 16);
288                 } while (t != 0);
289         }
291         /* Enable Channel 0 */
292         reg_write32(EDMA_TPCC_EESR,0x1);
293         /* Clear any pending interrupts for channel 0 */
294         reg_write32(EDMA_TPCC_ICR,0x1);
297 void disable_edma(void)
299         u32 i = 0;
301         /* Clear any pending interrupts for channel 0 */
302         reg_write32(EDMA_TPCC_ICR,0x1);
303         for(i = 0; i < 2; i++) {
304                 u32 addr = edma_clkctrl[i];
305                 u32 reg;
306                 u32 t;
308                 reg = reg_read32(addr);
309                 reg = FLD_MOD(reg, 0, 1, 0);
311                 reg_write32(addr, reg);
313                 do {
314                         reg = reg_read32(addr);
315                         t = FLD_GET(reg, 17, 16);
316                 } while (t != 3);
317         }
320 void edma_copy(u32 src, u32 dst, u32 len)
322         u32 reg = 0;
323         const u32 max_acnt = (1 << 4);
324         struct edma_param_entry *edma_param;
326         edma_param = (struct edma_param_entry *)EDMA_PARAM_0;
327         edma_param->opt      = 0;
328         edma_param->src_addr  = ((u32) src);
329         edma_param->dest_addr = ((u32) dst);
330         edma_param->a_cnt     = max_acnt;
331         edma_param->b_cnt     = (len + max_acnt - 1) >> 4;
332         edma_param->c_cnt     = 1;
333         edma_param->src_bidx  = max_acnt;
334         edma_param->dest_bidx = max_acnt;
335         edma_param->src_cidx  = 0;
336         edma_param->dest_cidx = 0;
337         edma_param->link_addr = 0xFFFF;
339         reg = 0;
340         reg = FLD_MOD(reg, 1, 20, 20); /* TCINTEN */
341         reg = FLD_MOD(reg, 1, 2, 2); /* ABSYNC */
342         reg = FLD_MOD(reg, 1, 3, 3); /* STATIC */
343         edma_param->opt = reg;
344         reg_write32(EDMA_TPCC_ESR,0x01);
345         do {
346                 reg = reg_read32(EDMA_TPCC_IPR);
347         } while(FLD_GET(reg, 0 , 0) != 1);
348         /* Clear any pending interrupts for channel 0 */
349         reg_write32(EDMA_TPCC_ICR,0x1);
352 volatile u32 entry_cnt = 1;
353 volatile u32 exit_cnt = 1;
354 volatile u32 boot_addr_copy = 1;
355 void main_loop(uint32_t boot_addr)
357         u32 len;
358         u32 entry_point_addr;
359         u32 src_addr;
360         u32 base;
361         mlo_func_proto mlo_entry;
363         boot_addr_copy = boot_addr;
364         /* find entry time */
365         entry_cnt = read_fast_counter();
366         enable_edma();
367         set_qspi_pinmux();
368         set_qspi_clock();
369         enable_qspi_mmap();
371         /* Find length */
372         base = QSPI_MMAP_BASE + 0x10000 + 0x200;
373         len = *((uint32_t *)(base));
374         entry_point_addr = *((uint32_t *)(base + 4));
375         src_addr = base + 8;
376         edma_copy(src_addr, entry_point_addr, len - 8);
377         mlo_entry = (mlo_func_proto)(entry_point_addr);
379         disable_qspi_mmap();
380         disable_edma();
381         exit_cnt = read_fast_counter();
383         /* Jump to the newly loaded image */
384         mlo_entry((uint32_t *)boot_addr_copy);