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