root/drivers/soc/tegra/fuse/tegra-apbmisc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. tegra_read_chipid
  2. tegra_get_chip_id
  3. tegra_read_straps
  4. tegra_read_ram_code
  5. tegra_init_revision
  6. tegra_init_apbmisc

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

/* [<][>][^][v][top][bottom][index][help] */