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