1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 4 */ 5 6 #include <linux/kernel.h> 7 #include <linux/of.h> 8 #include <linux/of_address.h> 9 #include <linux/io.h> 10 11 #include <soc/tegra/fuse.h> 12 #include <soc/tegra/common.h> 13 14 #include "fuse.h" 15 16 #define FUSE_SKU_INFO 0x10 17 18 #define PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT 4 19 #define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_LONG \ 20 (0xf << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT) 21 #define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_SHORT \ 22 (0x3 << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT) 23 24 static bool long_ram_code; 25 static u32 strapping; 26 static u32 chipid; 27 28 u32 tegra_read_chipid(void) 29 { 30 WARN(!chipid, "Tegra APB MISC not yet available\n"); 31 32 return chipid; 33 } 34 35 u8 tegra_get_chip_id(void) 36 { 37 return (tegra_read_chipid() >> 8) & 0xff; 38 } 39 40 u8 tegra_get_major_rev(void) 41 { 42 return (tegra_read_chipid() >> 4) & 0xf; 43 } 44 45 u8 tegra_get_minor_rev(void) 46 { 47 return (tegra_read_chipid() >> 16) & 0xf; 48 } 49 50 u32 tegra_read_straps(void) 51 { 52 WARN(!chipid, "Tegra ABP MISC not yet available\n"); 53 54 return strapping; 55 } 56 57 u32 tegra_read_ram_code(void) 58 { 59 u32 straps = tegra_read_straps(); 60 61 if (long_ram_code) 62 straps &= PMC_STRAPPING_OPT_A_RAM_CODE_MASK_LONG; 63 else 64 straps &= PMC_STRAPPING_OPT_A_RAM_CODE_MASK_SHORT; 65 66 return straps >> PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT; 67 } 68 69 static const struct of_device_id apbmisc_match[] __initconst = { 70 { .compatible = "nvidia,tegra20-apbmisc", }, 71 { .compatible = "nvidia,tegra186-misc", }, 72 { .compatible = "nvidia,tegra194-misc", }, 73 {}, 74 }; 75 76 void __init tegra_init_revision(void) 77 { 78 u8 chip_id, minor_rev; 79 80 chip_id = tegra_get_chip_id(); 81 minor_rev = tegra_get_minor_rev(); 82 83 switch (minor_rev) { 84 case 1: 85 tegra_sku_info.revision = TEGRA_REVISION_A01; 86 break; 87 case 2: 88 tegra_sku_info.revision = TEGRA_REVISION_A02; 89 break; 90 case 3: 91 if (chip_id == TEGRA20 && (tegra_fuse_read_spare(18) || 92 tegra_fuse_read_spare(19))) 93 tegra_sku_info.revision = TEGRA_REVISION_A03p; 94 else 95 tegra_sku_info.revision = TEGRA_REVISION_A03; 96 break; 97 case 4: 98 tegra_sku_info.revision = TEGRA_REVISION_A04; 99 break; 100 default: 101 tegra_sku_info.revision = TEGRA_REVISION_UNKNOWN; 102 } 103 104 tegra_sku_info.sku_id = tegra_fuse_read_early(FUSE_SKU_INFO); 105 } 106 107 void __init tegra_init_apbmisc(void) 108 { 109 void __iomem *apbmisc_base, *strapping_base; 110 struct resource apbmisc, straps; 111 struct device_node *np; 112 113 np = of_find_matching_node(NULL, apbmisc_match); 114 if (!np) { 115 /* 116 * Fall back to legacy initialization for 32-bit ARM only. All 117 * 64-bit ARM device tree files for Tegra are required to have 118 * an APBMISC node. 119 * 120 * This is for backwards-compatibility with old device trees 121 * that didn't contain an APBMISC node. 122 */ 123 if (IS_ENABLED(CONFIG_ARM) && soc_is_tegra()) { 124 /* APBMISC registers (chip revision, ...) */ 125 apbmisc.start = 0x70000800; 126 apbmisc.end = 0x70000863; 127 apbmisc.flags = IORESOURCE_MEM; 128 129 /* strapping options */ 130 if (of_machine_is_compatible("nvidia,tegra124")) { 131 straps.start = 0x7000e864; 132 straps.end = 0x7000e867; 133 } else { 134 straps.start = 0x70000008; 135 straps.end = 0x7000000b; 136 } 137 138 straps.flags = IORESOURCE_MEM; 139 140 pr_warn("Using APBMISC region %pR\n", &apbmisc); 141 pr_warn("Using strapping options registers %pR\n", 142 &straps); 143 } else { 144 /* 145 * At this point we're not running on Tegra, so play 146 * nice with multi-platform kernels. 147 */ 148 return; 149 } 150 } else { 151 /* 152 * Extract information from the device tree if we've found a 153 * matching node. 154 */ 155 if (of_address_to_resource(np, 0, &apbmisc) < 0) { 156 pr_err("failed to get APBMISC registers\n"); 157 return; 158 } 159 160 if (of_address_to_resource(np, 1, &straps) < 0) { 161 pr_err("failed to get strapping options registers\n"); 162 return; 163 } 164 } 165 166 apbmisc_base = ioremap(apbmisc.start, resource_size(&apbmisc)); 167 if (!apbmisc_base) { 168 pr_err("failed to map APBMISC registers\n"); 169 } else { 170 chipid = readl_relaxed(apbmisc_base + 4); 171 iounmap(apbmisc_base); 172 } 173 174 strapping_base = ioremap(straps.start, resource_size(&straps)); 175 if (!strapping_base) { 176 pr_err("failed to map strapping options registers\n"); 177 } else { 178 strapping = readl_relaxed(strapping_base); 179 iounmap(strapping_base); 180 } 181 182 long_ram_code = of_property_read_bool(np, "nvidia,long-ram-code"); 183 } 184