1*a45eb267SPeng Fan/* 2*a45eb267SPeng Fan * Copyright (C) 2016 Freescale Semiconductor, Inc. 3*a45eb267SPeng Fan * 4*a45eb267SPeng Fan * SPDX-License-Identifier: GPL-2.0+ 5*a45eb267SPeng Fan */ 6*a45eb267SPeng Fan 7*a45eb267SPeng Fan#include <config.h> 8*a45eb267SPeng Fan 9*a45eb267SPeng Fan#ifdef CONFIG_ROM_UNIFIED_SECTIONS 10*a45eb267SPeng Fan#define ROM_API_TABLE_BASE_ADDR_LEGACY 0x180 11*a45eb267SPeng Fan#define ROM_VERSION_OFFSET 0x80 12*a45eb267SPeng Fan#else 13*a45eb267SPeng Fan#define ROM_API_TABLE_BASE_ADDR_LEGACY 0xC0 14*a45eb267SPeng Fan#define ROM_VERSION_OFFSET 0x48 15*a45eb267SPeng Fan#endif 16*a45eb267SPeng Fan#define ROM_API_TABLE_BASE_ADDR_MX6DQ_TO15 0xC4 17*a45eb267SPeng Fan#define ROM_API_TABLE_BASE_ADDR_MX6DL_TO12 0xC4 18*a45eb267SPeng Fan#define ROM_API_HWCNFG_SETUP_OFFSET 0x08 19*a45eb267SPeng Fan#define ROM_VERSION_TO10 0x10 20*a45eb267SPeng Fan#define ROM_VERSION_TO12 0x12 21*a45eb267SPeng Fan#define ROM_VERSION_TO15 0x15 22*a45eb267SPeng Fan 23*a45eb267SPeng Fanplugin_start: 24*a45eb267SPeng Fan 25*a45eb267SPeng Fan push {r0-r4, lr} 26*a45eb267SPeng Fan 27*a45eb267SPeng Fan imx6_ddr_setting 28*a45eb267SPeng Fan imx6_clock_gating 29*a45eb267SPeng Fan imx6_qos_setting 30*a45eb267SPeng Fan 31*a45eb267SPeng Fan/* 32*a45eb267SPeng Fan * The following is to fill in those arguments for this ROM function 33*a45eb267SPeng Fan * pu_irom_hwcnfg_setup(void **start, size_t *bytes, const void *boot_data) 34*a45eb267SPeng Fan * This function is used to copy data from the storage media into DDR. 35*a45eb267SPeng Fan * start - Initial (possibly partial) image load address on entry. 36*a45eb267SPeng Fan * Final image load address on exit. 37*a45eb267SPeng Fan * bytes - Initial (possibly partial) image size on entry. 38*a45eb267SPeng Fan * Final image size on exit. 39*a45eb267SPeng Fan * boot_data - Initial @ref ivt Boot Data load address. 40*a45eb267SPeng Fan */ 41*a45eb267SPeng Fan adr r0, boot_data2 42*a45eb267SPeng Fan adr r1, image_len2 43*a45eb267SPeng Fan adr r2, boot_data2 44*a45eb267SPeng Fan 45*a45eb267SPeng Fan#ifdef CONFIG_NOR_BOOT 46*a45eb267SPeng Fan#ifdef CONFIG_MX6SX 47*a45eb267SPeng Fan ldr r3, =ROM_VERSION_OFFSET 48*a45eb267SPeng Fan ldr r4, [r3] 49*a45eb267SPeng Fan cmp r4, #ROM_VERSION_TO10 50*a45eb267SPeng Fan bgt before_calling_rom___pu_irom_hwcnfg_setup 51*a45eb267SPeng Fan ldr r3, =0x00900b00 52*a45eb267SPeng Fan ldr r4, =0x50000000 53*a45eb267SPeng Fan str r4, [r3, #0x5c] 54*a45eb267SPeng Fan#else 55*a45eb267SPeng Fan ldr r3, =0x00900800 56*a45eb267SPeng Fan ldr r4, =0x08000000 57*a45eb267SPeng Fan str r4, [r3, #0xc0] 58*a45eb267SPeng Fan#endif 59*a45eb267SPeng Fan#endif 60*a45eb267SPeng Fan 61*a45eb267SPeng Fan/* 62*a45eb267SPeng Fan * check the _pu_irom_api_table for the address 63*a45eb267SPeng Fan */ 64*a45eb267SPeng Fanbefore_calling_rom___pu_irom_hwcnfg_setup: 65*a45eb267SPeng Fan ldr r3, =ROM_VERSION_OFFSET 66*a45eb267SPeng Fan ldr r4, [r3] 67*a45eb267SPeng Fan#if defined(CONFIG_MX6SOLO) || defined(CONFIG_MX6DL) 68*a45eb267SPeng Fan ldr r3, =ROM_VERSION_TO12 69*a45eb267SPeng Fan cmp r4, r3 70*a45eb267SPeng Fan ldrge r3, =ROM_API_TABLE_BASE_ADDR_MX6DL_TO12 71*a45eb267SPeng Fan ldrlt r3, =ROM_API_TABLE_BASE_ADDR_LEGACY 72*a45eb267SPeng Fan#elif defined(CONFIG_MX6Q) 73*a45eb267SPeng Fan ldr r3, =ROM_VERSION_TO15 74*a45eb267SPeng Fan cmp r4, r3 75*a45eb267SPeng Fan ldrge r3, =ROM_API_TABLE_BASE_ADDR_MX6DQ_TO15 76*a45eb267SPeng Fan ldrlt r3, =ROM_API_TABLE_BASE_ADDR_LEGACY 77*a45eb267SPeng Fan#else 78*a45eb267SPeng Fan ldr r3, =ROM_API_TABLE_BASE_ADDR_LEGACY 79*a45eb267SPeng Fan#endif 80*a45eb267SPeng Fan ldr r4, [r3, #ROM_API_HWCNFG_SETUP_OFFSET] 81*a45eb267SPeng Fan blx r4 82*a45eb267SPeng Fanafter_calling_rom___pu_irom_hwcnfg_setup: 83*a45eb267SPeng Fan 84*a45eb267SPeng Fan/* 85*a45eb267SPeng Fan * ROM_API_HWCNFG_SETUP function enables MMU & Caches. 86*a45eb267SPeng Fan * Thus disable MMU & Caches. 87*a45eb267SPeng Fan */ 88*a45eb267SPeng Fan 89*a45eb267SPeng Fan mrc p15, 0, r0, c1, c0, 0 /* read CP15 register 1 into r0*/ 90*a45eb267SPeng Fan ands r0, r0, #0x1 /* check if MMU is enabled */ 91*a45eb267SPeng Fan beq mmu_disable_notreq /* exit if MMU is already disabled */ 92*a45eb267SPeng Fan 93*a45eb267SPeng Fan /* Disable caches, MMU */ 94*a45eb267SPeng Fan mrc p15, 0, r0, c1, c0, 0 /* read CP15 register 1 into r0 */ 95*a45eb267SPeng Fan bic r0, r0, #(1 << 2) /* disable D Cache */ 96*a45eb267SPeng Fan bic r0, r0, #0x1 /* clear bit 0 ; MMU off */ 97*a45eb267SPeng Fan 98*a45eb267SPeng Fan bic r0, r0, #(0x1 << 11) /* disable Z, branch prediction */ 99*a45eb267SPeng Fan bic r0, r0, #(0x1 << 1) /* disable A, Strict alignment */ 100*a45eb267SPeng Fan /* check enabled. */ 101*a45eb267SPeng Fan mcr p15, 0, r0, c1, c0, 0 /* write CP15 register 1 */ 102*a45eb267SPeng Fan mov r0, r0 103*a45eb267SPeng Fan mov r0, r0 104*a45eb267SPeng Fan mov r0, r0 105*a45eb267SPeng Fan mov r0, r0 106*a45eb267SPeng Fan 107*a45eb267SPeng Fanmmu_disable_notreq: 108*a45eb267SPeng Fan NOP 109*a45eb267SPeng Fan 110*a45eb267SPeng Fan/* To return to ROM from plugin, we need to fill in these argument. 111*a45eb267SPeng Fan * Here is what need to do: 112*a45eb267SPeng Fan * Need to construct the paramters for this function before return to ROM: 113*a45eb267SPeng Fan * plugin_download(void **start, size_t *bytes, UINT32 *ivt_offset) 114*a45eb267SPeng Fan */ 115*a45eb267SPeng Fan pop {r0-r4, lr} 116*a45eb267SPeng Fan push {r5} 117*a45eb267SPeng Fan ldr r5, boot_data2 118*a45eb267SPeng Fan str r5, [r0] 119*a45eb267SPeng Fan ldr r5, image_len2 120*a45eb267SPeng Fan str r5, [r1] 121*a45eb267SPeng Fan ldr r5, second_ivt_offset 122*a45eb267SPeng Fan str r5, [r2] 123*a45eb267SPeng Fan mov r0, #1 124*a45eb267SPeng Fan pop {r5} 125*a45eb267SPeng Fan 126*a45eb267SPeng Fan /* return back to ROM code */ 127*a45eb267SPeng Fan bx lr 128*a45eb267SPeng Fan 129*a45eb267SPeng Fan/* make the following data right in the end of the output*/ 130*a45eb267SPeng Fan.ltorg 131*a45eb267SPeng Fan 132*a45eb267SPeng Fan#if (defined(CONFIG_NOR_BOOT) || defined(CONFIG_QSPI_BOOT)) 133*a45eb267SPeng Fan#define FLASH_OFFSET 0x1000 134*a45eb267SPeng Fan#else 135*a45eb267SPeng Fan#define FLASH_OFFSET 0x400 136*a45eb267SPeng Fan#endif 137*a45eb267SPeng Fan 138*a45eb267SPeng Fan/* 139*a45eb267SPeng Fan * second_ivt_offset is the offset from the "second_ivt_header" to 140*a45eb267SPeng Fan * "image_copy_start", which involves FLASH_OFFSET, plus the first 141*a45eb267SPeng Fan * ivt_header, the plugin code size itself recorded by "ivt2_header" 142*a45eb267SPeng Fan */ 143*a45eb267SPeng Fan 144*a45eb267SPeng Fansecond_ivt_offset: .long (ivt2_header + 0x2C + FLASH_OFFSET) 145*a45eb267SPeng Fan 146*a45eb267SPeng Fan/* 147*a45eb267SPeng Fan * The following is the second IVT header plus the second boot data 148*a45eb267SPeng Fan */ 149*a45eb267SPeng Fanivt2_header: .long 0x0 150*a45eb267SPeng Fanapp2_code_jump_v: .long 0x0 151*a45eb267SPeng Fanreserv3: .long 0x0 152*a45eb267SPeng Fandcd2_ptr: .long 0x0 153*a45eb267SPeng Fanboot_data2_ptr: .long 0x0 154*a45eb267SPeng Fanself_ptr2: .long 0x0 155*a45eb267SPeng Fanapp_code_csf2: .long 0x0 156*a45eb267SPeng Fanreserv4: .long 0x0 157*a45eb267SPeng Fanboot_data2: .long 0x0 158*a45eb267SPeng Fanimage_len2: .long 0x0 159*a45eb267SPeng Fanplugin2: .long 0x0 160