1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <stdbool.h> 9*91f16700Schasinglulu #include <stddef.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <lib/mmio.h> 12*91f16700Schasinglulu #include <lib/utils_def.h> 13*91f16700Schasinglulu 14*91f16700Schasinglulu #include "uniphier.h" 15*91f16700Schasinglulu 16*91f16700Schasinglulu #define UNIPHIER_PINMON0 0x0 17*91f16700Schasinglulu #define UNIPHIER_PINMON2 0x8 18*91f16700Schasinglulu 19*91f16700Schasinglulu static const uintptr_t uniphier_pinmon_base[] = { 20*91f16700Schasinglulu [UNIPHIER_SOC_LD11] = 0x5f900100, 21*91f16700Schasinglulu [UNIPHIER_SOC_LD20] = 0x5f900100, 22*91f16700Schasinglulu [UNIPHIER_SOC_PXS3] = 0x5f900100, 23*91f16700Schasinglulu }; 24*91f16700Schasinglulu 25*91f16700Schasinglulu static bool uniphier_ld11_is_usb_boot(uint32_t pinmon) 26*91f16700Schasinglulu { 27*91f16700Schasinglulu return !!(~pinmon & 0x00000080); 28*91f16700Schasinglulu } 29*91f16700Schasinglulu 30*91f16700Schasinglulu static bool uniphier_ld20_is_usb_boot(uint32_t pinmon) 31*91f16700Schasinglulu { 32*91f16700Schasinglulu return !!(~pinmon & 0x00000780); 33*91f16700Schasinglulu } 34*91f16700Schasinglulu 35*91f16700Schasinglulu static bool uniphier_pxs3_is_usb_boot(uint32_t pinmon) 36*91f16700Schasinglulu { 37*91f16700Schasinglulu uintptr_t pinmon_base = uniphier_pinmon_base[UNIPHIER_SOC_PXS3]; 38*91f16700Schasinglulu uint32_t pinmon2 = mmio_read_32(pinmon_base + UNIPHIER_PINMON2); 39*91f16700Schasinglulu 40*91f16700Schasinglulu return !!(pinmon2 & BIT(31)); 41*91f16700Schasinglulu } 42*91f16700Schasinglulu 43*91f16700Schasinglulu static const unsigned int uniphier_ld11_boot_device_table[] = { 44*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 45*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 46*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 47*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 48*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 49*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 50*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 51*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 52*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 53*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 54*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 55*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 56*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 57*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 58*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 59*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 60*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 61*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 62*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 63*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 64*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 65*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 66*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 67*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 68*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 69*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 70*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 71*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 72*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 73*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 74*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 75*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NOR, 76*91f16700Schasinglulu }; 77*91f16700Schasinglulu 78*91f16700Schasinglulu static unsigned int uniphier_ld11_get_boot_device(uint32_t pinmon) 79*91f16700Schasinglulu { 80*91f16700Schasinglulu unsigned int boot_sel = (pinmon >> 1) & 0x1f; 81*91f16700Schasinglulu 82*91f16700Schasinglulu assert(boot_sel < ARRAY_SIZE(uniphier_ld11_boot_device_table)); 83*91f16700Schasinglulu 84*91f16700Schasinglulu return uniphier_ld11_boot_device_table[boot_sel]; 85*91f16700Schasinglulu } 86*91f16700Schasinglulu 87*91f16700Schasinglulu static const unsigned int uniphier_pxs3_boot_device_table[] = { 88*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 89*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 90*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 91*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 92*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 93*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 94*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 95*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 96*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 97*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 98*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 99*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 100*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 101*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_EMMC, 102*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 103*91f16700Schasinglulu UNIPHIER_BOOT_DEVICE_NAND, 104*91f16700Schasinglulu }; 105*91f16700Schasinglulu 106*91f16700Schasinglulu static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon) 107*91f16700Schasinglulu { 108*91f16700Schasinglulu unsigned int boot_sel = (pinmon >> 1) & 0xf; 109*91f16700Schasinglulu 110*91f16700Schasinglulu assert(boot_sel < ARRAY_SIZE(uniphier_pxs3_boot_device_table)); 111*91f16700Schasinglulu 112*91f16700Schasinglulu return uniphier_pxs3_boot_device_table[boot_sel]; 113*91f16700Schasinglulu } 114*91f16700Schasinglulu 115*91f16700Schasinglulu struct uniphier_boot_device_info { 116*91f16700Schasinglulu bool have_boot_swap; 117*91f16700Schasinglulu bool (*is_sd_boot)(uint32_t pinmon); 118*91f16700Schasinglulu bool (*is_usb_boot)(uint32_t pinmon); 119*91f16700Schasinglulu unsigned int (*get_boot_device)(uint32_t pinmon); 120*91f16700Schasinglulu }; 121*91f16700Schasinglulu 122*91f16700Schasinglulu static const struct uniphier_boot_device_info uniphier_boot_device_info[] = { 123*91f16700Schasinglulu [UNIPHIER_SOC_LD11] = { 124*91f16700Schasinglulu .have_boot_swap = true, 125*91f16700Schasinglulu .is_usb_boot = uniphier_ld11_is_usb_boot, 126*91f16700Schasinglulu .get_boot_device = uniphier_ld11_get_boot_device, 127*91f16700Schasinglulu }, 128*91f16700Schasinglulu [UNIPHIER_SOC_LD20] = { 129*91f16700Schasinglulu .have_boot_swap = true, 130*91f16700Schasinglulu .is_usb_boot = uniphier_ld20_is_usb_boot, 131*91f16700Schasinglulu .get_boot_device = uniphier_ld11_get_boot_device, 132*91f16700Schasinglulu }, 133*91f16700Schasinglulu [UNIPHIER_SOC_PXS3] = { 134*91f16700Schasinglulu .have_boot_swap = true, 135*91f16700Schasinglulu .is_usb_boot = uniphier_pxs3_is_usb_boot, 136*91f16700Schasinglulu .get_boot_device = uniphier_pxs3_get_boot_device, 137*91f16700Schasinglulu }, 138*91f16700Schasinglulu }; 139*91f16700Schasinglulu 140*91f16700Schasinglulu unsigned int uniphier_get_boot_device(unsigned int soc) 141*91f16700Schasinglulu { 142*91f16700Schasinglulu const struct uniphier_boot_device_info *info; 143*91f16700Schasinglulu uintptr_t pinmon_base; 144*91f16700Schasinglulu uint32_t pinmon; 145*91f16700Schasinglulu 146*91f16700Schasinglulu assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); 147*91f16700Schasinglulu info = &uniphier_boot_device_info[soc]; 148*91f16700Schasinglulu 149*91f16700Schasinglulu assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); 150*91f16700Schasinglulu pinmon_base = uniphier_pinmon_base[soc]; 151*91f16700Schasinglulu 152*91f16700Schasinglulu pinmon = mmio_read_32(pinmon_base + UNIPHIER_PINMON0); 153*91f16700Schasinglulu 154*91f16700Schasinglulu if (info->have_boot_swap && !(pinmon & BIT(29))) 155*91f16700Schasinglulu return UNIPHIER_BOOT_DEVICE_NOR; 156*91f16700Schasinglulu 157*91f16700Schasinglulu if (info->is_sd_boot && info->is_sd_boot(pinmon)) 158*91f16700Schasinglulu return UNIPHIER_BOOT_DEVICE_SD; 159*91f16700Schasinglulu 160*91f16700Schasinglulu if (info->is_usb_boot && info->is_usb_boot(pinmon)) 161*91f16700Schasinglulu return UNIPHIER_BOOT_DEVICE_USB; 162*91f16700Schasinglulu 163*91f16700Schasinglulu return info->get_boot_device(pinmon); 164*91f16700Schasinglulu } 165*91f16700Schasinglulu 166*91f16700Schasinglulu static const bool uniphier_have_onchip_scp[] = { 167*91f16700Schasinglulu [UNIPHIER_SOC_LD11] = true, 168*91f16700Schasinglulu [UNIPHIER_SOC_LD20] = true, 169*91f16700Schasinglulu [UNIPHIER_SOC_PXS3] = false, 170*91f16700Schasinglulu }; 171*91f16700Schasinglulu 172*91f16700Schasinglulu unsigned int uniphier_get_boot_master(unsigned int soc) 173*91f16700Schasinglulu { 174*91f16700Schasinglulu assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp)); 175*91f16700Schasinglulu 176*91f16700Schasinglulu if (uniphier_have_onchip_scp[soc]) { 177*91f16700Schasinglulu uintptr_t pinmon_base; 178*91f16700Schasinglulu 179*91f16700Schasinglulu assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); 180*91f16700Schasinglulu pinmon_base = uniphier_pinmon_base[soc]; 181*91f16700Schasinglulu 182*91f16700Schasinglulu if (mmio_read_32(pinmon_base + UNIPHIER_PINMON0) & BIT(27)) 183*91f16700Schasinglulu return UNIPHIER_BOOT_MASTER_THIS; 184*91f16700Schasinglulu else 185*91f16700Schasinglulu return UNIPHIER_BOOT_MASTER_SCP; 186*91f16700Schasinglulu } else { 187*91f16700Schasinglulu return UNIPHIER_BOOT_MASTER_EXT; 188*91f16700Schasinglulu } 189*91f16700Schasinglulu } 190