1*e77e65dfSangelo@sysam.it /* 2*e77e65dfSangelo@sysam.it * (C) Copyright 2014 Angelo Dureghello <angelo@sysam.it> 3*e77e65dfSangelo@sysam.it * 4*e77e65dfSangelo@sysam.it * SPDX-License-Identifier: GPL-2.0+ 5*e77e65dfSangelo@sysam.it * 6*e77e65dfSangelo@sysam.it */ 7*e77e65dfSangelo@sysam.it 8*e77e65dfSangelo@sysam.it #include <common.h> 9*e77e65dfSangelo@sysam.it #include <watchdog.h> 10*e77e65dfSangelo@sysam.it #include <asm/immap.h> 11*e77e65dfSangelo@sysam.it #include <asm/io.h> 12*e77e65dfSangelo@sysam.it 13*e77e65dfSangelo@sysam.it #if defined(CONFIG_M5307) 14*e77e65dfSangelo@sysam.it /* 15*e77e65dfSangelo@sysam.it * Simple mcf5307 chip select module init. 16*e77e65dfSangelo@sysam.it * 17*e77e65dfSangelo@sysam.it * Note: this chip has an issue reported in the device "errata": 18*e77e65dfSangelo@sysam.it * MCF5307ER Rev 4.2 reports @ section 35: 19*e77e65dfSangelo@sysam.it * Corrupted Return PC in Exception Stack Frame 20*e77e65dfSangelo@sysam.it * When processing an autovectored interrupt an error can occur that 21*e77e65dfSangelo@sysam.it * causes 0xFFFFFFFF to be written as the return PC value in the 22*e77e65dfSangelo@sysam.it * exception stack frame. The problem is caused by a conflict between 23*e77e65dfSangelo@sysam.it * an internal autovector access and a chip select mapped to the IACK 24*e77e65dfSangelo@sysam.it * address space (0xFFFFXXXX). 25*e77e65dfSangelo@sysam.it * Workaround: 26*e77e65dfSangelo@sysam.it * Set the C/I bit in the chip select mask register (CSMR) for the 27*e77e65dfSangelo@sysam.it * chip select that is mapped to 0xFFFFXXXX. 28*e77e65dfSangelo@sysam.it * This will prevent the chip select from asserting for IACK accesses. 29*e77e65dfSangelo@sysam.it */ 30*e77e65dfSangelo@sysam.it 31*e77e65dfSangelo@sysam.it #define MCF5307_SP_ERR_FIX(cs_base, mask) \ 32*e77e65dfSangelo@sysam.it do { \ 33*e77e65dfSangelo@sysam.it if (((cs_base<<16)+(in_be32(&mask)&0xffff0000)) >= \ 34*e77e65dfSangelo@sysam.it 0xffff0000) \ 35*e77e65dfSangelo@sysam.it setbits_be32(&mask, CSMR_CI); \ 36*e77e65dfSangelo@sysam.it } while (0) 37*e77e65dfSangelo@sysam.it 38*e77e65dfSangelo@sysam.it void init_csm(void) 39*e77e65dfSangelo@sysam.it { 40*e77e65dfSangelo@sysam.it csm_t *csm = (csm_t *)(MMAP_CSM); 41*e77e65dfSangelo@sysam.it 42*e77e65dfSangelo@sysam.it #if (defined(CONFIG_SYS_CS0_BASE) && defined(CONFIG_SYS_CS0_MASK) && \ 43*e77e65dfSangelo@sysam.it defined(CONFIG_SYS_CS0_CTRL)) 44*e77e65dfSangelo@sysam.it out_be16(&csm->csar0, CONFIG_SYS_CS0_BASE); 45*e77e65dfSangelo@sysam.it out_be32(&csm->csmr0, CONFIG_SYS_CS0_MASK); 46*e77e65dfSangelo@sysam.it out_be16(&csm->cscr0, CONFIG_SYS_CS0_CTRL); 47*e77e65dfSangelo@sysam.it MCF5307_SP_ERR_FIX(CONFIG_SYS_CS0_BASE, csm->csmr0); 48*e77e65dfSangelo@sysam.it #else 49*e77e65dfSangelo@sysam.it #warning "Chip Select 0 are not initialized/used" 50*e77e65dfSangelo@sysam.it #endif 51*e77e65dfSangelo@sysam.it #if (defined(CONFIG_SYS_CS1_BASE) && defined(CONFIG_SYS_CS1_MASK) && \ 52*e77e65dfSangelo@sysam.it defined(CONFIG_SYS_CS1_CTRL)) 53*e77e65dfSangelo@sysam.it out_be16(&csm->csar1, CONFIG_SYS_CS1_BASE); 54*e77e65dfSangelo@sysam.it out_be32(&csm->csmr1, CONFIG_SYS_CS1_MASK); 55*e77e65dfSangelo@sysam.it out_be16(&csm->cscr1, CONFIG_SYS_CS1_CTRL); 56*e77e65dfSangelo@sysam.it MCF5307_SP_ERR_FIX(CONFIG_SYS_CS1_BASE, csm->csmr1); 57*e77e65dfSangelo@sysam.it #endif 58*e77e65dfSangelo@sysam.it #if (defined(CONFIG_SYS_CS2_BASE) && defined(CONFIG_SYS_CS2_MASK) && \ 59*e77e65dfSangelo@sysam.it defined(CONFIG_SYS_CS2_CTRL)) 60*e77e65dfSangelo@sysam.it out_be16(&csm->csar2, CONFIG_SYS_CS2_BASE); 61*e77e65dfSangelo@sysam.it out_be32(&csm->csmr2, CONFIG_SYS_CS2_MASK); 62*e77e65dfSangelo@sysam.it out_be16(&csm->cscr2, CONFIG_SYS_CS2_CTRL); 63*e77e65dfSangelo@sysam.it MCF5307_SP_ERR_FIX(CONFIG_SYS_CS2_BASE, csm->csmr2); 64*e77e65dfSangelo@sysam.it #endif 65*e77e65dfSangelo@sysam.it #if (defined(CONFIG_SYS_CS3_BASE) && defined(CONFIG_SYS_CS3_MASK) && \ 66*e77e65dfSangelo@sysam.it defined(CONFIG_SYS_CS3_CTRL)) 67*e77e65dfSangelo@sysam.it out_be16(&csm->csar3, CONFIG_SYS_CS3_BASE); 68*e77e65dfSangelo@sysam.it out_be32(&csm->csmr3, CONFIG_SYS_CS3_MASK); 69*e77e65dfSangelo@sysam.it out_be16(&csm->cscr3, CONFIG_SYS_CS3_CTRL); 70*e77e65dfSangelo@sysam.it MCF5307_SP_ERR_FIX(CONFIG_SYS_CS3_BASE, csm->csmr3); 71*e77e65dfSangelo@sysam.it #endif 72*e77e65dfSangelo@sysam.it #if (defined(CONFIG_SYS_CS4_BASE) && defined(CONFIG_SYS_CS4_MASK) && \ 73*e77e65dfSangelo@sysam.it defined(CONFIG_SYS_CS4_CTRL)) 74*e77e65dfSangelo@sysam.it out_be16(&csm->csar4, CONFIG_SYS_CS4_BASE); 75*e77e65dfSangelo@sysam.it out_be32(&csm->csmr4, CONFIG_SYS_CS4_MASK); 76*e77e65dfSangelo@sysam.it out_be16(&csm->cscr4, CONFIG_SYS_CS4_CTRL); 77*e77e65dfSangelo@sysam.it MCF5307_SP_ERR_FIX(CONFIG_SYS_CS4_BASE, csm->csmr4); 78*e77e65dfSangelo@sysam.it #endif 79*e77e65dfSangelo@sysam.it #if (defined(CONFIG_SYS_CS5_BASE) && defined(CONFIG_SYS_CS5_MASK) && \ 80*e77e65dfSangelo@sysam.it defined(CONFIG_SYS_CS5_CTRL)) 81*e77e65dfSangelo@sysam.it out_be16(&csm->csar5, CONFIG_SYS_CS5_BASE); 82*e77e65dfSangelo@sysam.it out_be32(&csm->csmr5, CONFIG_SYS_CS5_MASK); 83*e77e65dfSangelo@sysam.it out_be16(&csm->cscr5, CONFIG_SYS_CS5_CTRL); 84*e77e65dfSangelo@sysam.it MCF5307_SP_ERR_FIX(CONFIG_SYS_CS5_BASE, csm->csmr5); 85*e77e65dfSangelo@sysam.it #endif 86*e77e65dfSangelo@sysam.it #if (defined(CONFIG_SYS_CS6_BASE) && defined(CONFIG_SYS_CS6_MASK) && \ 87*e77e65dfSangelo@sysam.it defined(CONFIG_SYS_CS6_CTRL)) 88*e77e65dfSangelo@sysam.it out_be16(&csm->csar6, CONFIG_SYS_CS6_BASE); 89*e77e65dfSangelo@sysam.it out_be32(&csm->csmr6, CONFIG_SYS_CS6_MASK); 90*e77e65dfSangelo@sysam.it out_be16(&csm->cscr6, CONFIG_SYS_CS6_CTRL); 91*e77e65dfSangelo@sysam.it MCF5307_SP_ERR_FIX(CONFIG_SYS_CS6_BASE, csm->csmr6); 92*e77e65dfSangelo@sysam.it #endif 93*e77e65dfSangelo@sysam.it #if (defined(CONFIG_SYS_CS7_BASE) && defined(CONFIG_SYS_CS7_MASK) && \ 94*e77e65dfSangelo@sysam.it defined(CONFIG_SYS_CS7_CTRL)) 95*e77e65dfSangelo@sysam.it out_be16(&csm->csar7, CONFIG_SYS_CS7_BASE); 96*e77e65dfSangelo@sysam.it out_be32(&csm->csmr7, CONFIG_SYS_CS7_MASK); 97*e77e65dfSangelo@sysam.it out_be16(&csm->cscr7, CONFIG_SYS_CS7_CTRL); 98*e77e65dfSangelo@sysam.it MCF5307_SP_ERR_FIX(CONFIG_SYS_CS7_BASE, csm->csmr7); 99*e77e65dfSangelo@sysam.it #endif 100*e77e65dfSangelo@sysam.it } 101*e77e65dfSangelo@sysam.it 102*e77e65dfSangelo@sysam.it /* 103*e77e65dfSangelo@sysam.it * Set up the memory map and initialize registers 104*e77e65dfSangelo@sysam.it */ 105*e77e65dfSangelo@sysam.it void cpu_init_f(void) 106*e77e65dfSangelo@sysam.it { 107*e77e65dfSangelo@sysam.it sim_t *sim = (sim_t *)(MMAP_SIM); 108*e77e65dfSangelo@sysam.it 109*e77e65dfSangelo@sysam.it out_8(&sim->sypcr, 0x00); 110*e77e65dfSangelo@sysam.it out_8(&sim->swivr, 0x0f); 111*e77e65dfSangelo@sysam.it out_8(&sim->swsr, 0x00); 112*e77e65dfSangelo@sysam.it out_8(&sim->mpark, 0x00); 113*e77e65dfSangelo@sysam.it 114*e77e65dfSangelo@sysam.it intctrl_t *icr = (intctrl_t *)(MMAP_INTC); 115*e77e65dfSangelo@sysam.it 116*e77e65dfSangelo@sysam.it /* timer 2 not masked */ 117*e77e65dfSangelo@sysam.it out_be32(&icr->imr, 0xfffffbff); 118*e77e65dfSangelo@sysam.it 119*e77e65dfSangelo@sysam.it out_8(&icr->icr0, 0x00); /* sw watchdog */ 120*e77e65dfSangelo@sysam.it out_8(&icr->icr1, 0x00); /* timer 1 */ 121*e77e65dfSangelo@sysam.it out_8(&icr->icr2, 0x88); /* timer 2 */ 122*e77e65dfSangelo@sysam.it out_8(&icr->icr3, 0x00); /* i2c */ 123*e77e65dfSangelo@sysam.it out_8(&icr->icr4, 0x00); /* uart 0 */ 124*e77e65dfSangelo@sysam.it out_8(&icr->icr5, 0x00); /* uart 1 */ 125*e77e65dfSangelo@sysam.it out_8(&icr->icr6, 0x00); /* dma 0 */ 126*e77e65dfSangelo@sysam.it out_8(&icr->icr7, 0x00); /* dma 1 */ 127*e77e65dfSangelo@sysam.it out_8(&icr->icr8, 0x00); /* dma 2 */ 128*e77e65dfSangelo@sysam.it out_8(&icr->icr9, 0x00); /* dma 3 */ 129*e77e65dfSangelo@sysam.it 130*e77e65dfSangelo@sysam.it /* Chipselect Init */ 131*e77e65dfSangelo@sysam.it init_csm(); 132*e77e65dfSangelo@sysam.it 133*e77e65dfSangelo@sysam.it /* enable data/instruction cache now */ 134*e77e65dfSangelo@sysam.it icache_enable(); 135*e77e65dfSangelo@sysam.it } 136*e77e65dfSangelo@sysam.it 137*e77e65dfSangelo@sysam.it /* 138*e77e65dfSangelo@sysam.it * initialize higher level parts of CPU like timers 139*e77e65dfSangelo@sysam.it */ 140*e77e65dfSangelo@sysam.it int cpu_init_r(void) 141*e77e65dfSangelo@sysam.it { 142*e77e65dfSangelo@sysam.it return 0; 143*e77e65dfSangelo@sysam.it } 144*e77e65dfSangelo@sysam.it 145*e77e65dfSangelo@sysam.it void uart_port_conf(void) 146*e77e65dfSangelo@sysam.it { 147*e77e65dfSangelo@sysam.it } 148*e77e65dfSangelo@sysam.it 149*e77e65dfSangelo@sysam.it void arch_preboot_os(void) 150*e77e65dfSangelo@sysam.it { 151*e77e65dfSangelo@sysam.it /* 152*e77e65dfSangelo@sysam.it * OS can change interrupt offsets and are about to boot the OS so 153*e77e65dfSangelo@sysam.it * we need to make sure we disable all async interrupts. 154*e77e65dfSangelo@sysam.it */ 155*e77e65dfSangelo@sysam.it intctrl_t *icr = (intctrl_t *)(MMAP_INTC); 156*e77e65dfSangelo@sysam.it 157*e77e65dfSangelo@sysam.it out_8(&icr->icr1, 0x00); /* timer 1 */ 158*e77e65dfSangelo@sysam.it out_8(&icr->icr2, 0x00); /* timer 2 */ 159*e77e65dfSangelo@sysam.it } 160*e77e65dfSangelo@sysam.it #endif 161