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