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