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