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