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