]>
Commit | Line | Data |
---|---|---|
74652cf6 TW |
1 | /* |
2 | * (C) Copyright 2010-2011 | |
3 | * NVIDIA Corporation <www.nvidia.com> | |
4 | * | |
1a459660 | 5 | * SPDX-License-Identifier: GPL-2.0+ |
74652cf6 | 6 | */ |
b2871037 TW |
7 | |
8 | /* Tegra AP (Application Processor) code */ | |
9 | ||
150c2493 | 10 | #include <common.h> |
74652cf6 | 11 | #include <asm/io.h> |
d515362d | 12 | #include <asm/arch/gp_padctrl.h> |
150c2493 | 13 | #include <asm/arch-tegra/ap.h> |
b2871037 | 14 | #include <asm/arch-tegra/clock.h> |
150c2493 TW |
15 | #include <asm/arch-tegra/fuse.h> |
16 | #include <asm/arch-tegra/pmc.h> | |
17 | #include <asm/arch-tegra/scu.h> | |
e23bb6a4 | 18 | #include <asm/arch-tegra/tegra.h> |
150c2493 | 19 | #include <asm/arch-tegra/warmboot.h> |
74652cf6 | 20 | |
49493cb7 | 21 | int tegra_get_chip(void) |
d515362d | 22 | { |
49493cb7 TW |
23 | int rev; |
24 | struct apb_misc_gp_ctlr *gp = | |
25 | (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE; | |
d515362d SG |
26 | |
27 | /* | |
28 | * This is undocumented, Chip ID is bits 15:8 of the register | |
29 | * APB_MISC + 0x804, and has value 0x20 for Tegra20, 0x30 for | |
e23bb6a4 | 30 | * Tegra30, and 0x35 for T114. |
d515362d | 31 | */ |
d515362d | 32 | rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT; |
49493cb7 TW |
33 | debug("%s: CHIPID is 0x%02X\n", __func__, rev); |
34 | ||
35 | return rev; | |
36 | } | |
37 | ||
38 | int tegra_get_sku_info(void) | |
39 | { | |
40 | int sku_id; | |
41 | struct fuse_regs *fuse = (struct fuse_regs *)NV_PA_FUSE_BASE; | |
42 | ||
43 | sku_id = readl(&fuse->sku_info) & 0xff; | |
44 | debug("%s: SKU info byte is 0x%02X\n", __func__, sku_id); | |
45 | ||
46 | return sku_id; | |
47 | } | |
48 | ||
49 | int tegra_get_chip_sku(void) | |
50 | { | |
51 | uint sku_id, chip_id; | |
d515362d | 52 | |
49493cb7 TW |
53 | chip_id = tegra_get_chip(); |
54 | sku_id = tegra_get_sku_info(); | |
d515362d | 55 | |
49493cb7 | 56 | switch (chip_id) { |
00a2749d | 57 | case CHIPID_TEGRA20: |
49493cb7 | 58 | switch (sku_id) { |
20583d04 | 59 | case SKU_ID_T20_7: |
d515362d SG |
60 | case SKU_ID_T20: |
61 | return TEGRA_SOC_T20; | |
62 | case SKU_ID_T25SE: | |
63 | case SKU_ID_AP25: | |
64 | case SKU_ID_T25: | |
65 | case SKU_ID_AP25E: | |
66 | case SKU_ID_T25E: | |
67 | return TEGRA_SOC_T25; | |
68 | } | |
69 | break; | |
b2871037 | 70 | case CHIPID_TEGRA30: |
49493cb7 | 71 | switch (sku_id) { |
eb222d1d | 72 | case SKU_ID_T33: |
b2871037 TW |
73 | case SKU_ID_T30: |
74 | return TEGRA_SOC_T30; | |
75 | } | |
76 | break; | |
e23bb6a4 | 77 | case CHIPID_TEGRA114: |
49493cb7 | 78 | switch (sku_id) { |
e23bb6a4 | 79 | case SKU_ID_T114_ENG: |
840167c2 | 80 | case SKU_ID_T114_1: |
e23bb6a4 TW |
81 | return TEGRA_SOC_T114; |
82 | } | |
83 | break; | |
d515362d | 84 | } |
49493cb7 TW |
85 | /* unknown chip/sku id */ |
86 | printf("%s: ERROR: UNKNOWN CHIP/SKU ID COMBO (0x%02X/0x%02X)\n", | |
87 | __func__, chip_id, sku_id); | |
d515362d SG |
88 | return TEGRA_SOC_UNKNOWN; |
89 | } | |
90 | ||
12b7b70c | 91 | static void enable_scu(void) |
74652cf6 TW |
92 | { |
93 | struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE; | |
94 | u32 reg; | |
95 | ||
dbc000bf TW |
96 | /* Only enable the SCU on T20/T25 */ |
97 | if (tegra_get_chip() != CHIPID_TEGRA20) | |
98 | return; | |
99 | ||
74652cf6 TW |
100 | /* If SCU already setup/enabled, return */ |
101 | if (readl(&scu->scu_ctrl) & SCU_CTRL_ENABLE) | |
102 | return; | |
103 | ||
104 | /* Invalidate all ways for all processors */ | |
105 | writel(0xFFFF, &scu->scu_inv_all); | |
106 | ||
107 | /* Enable SCU - bit 0 */ | |
108 | reg = readl(&scu->scu_ctrl); | |
109 | reg |= SCU_CTRL_ENABLE; | |
110 | writel(reg, &scu->scu_ctrl); | |
111 | } | |
112 | ||
76e350b7 TW |
113 | static u32 get_odmdata(void) |
114 | { | |
115 | /* | |
116 | * ODMDATA is stored in the BCT in IRAM by the BootROM. | |
117 | * The BCT start and size are stored in the BIT in IRAM. | |
118 | * Read the data @ bct_start + (bct_size - 12). This works | |
119 | * on T20 and T30 BCTs, which are locked down. If this changes | |
120 | * in new chips (T114, etc.), we can revisit this algorithm. | |
121 | */ | |
122 | ||
123 | u32 bct_start, odmdata; | |
124 | ||
b2871037 | 125 | bct_start = readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BCTPTR); |
76e350b7 TW |
126 | odmdata = readl(bct_start + BCT_ODMDATA_OFFSET); |
127 | ||
128 | return odmdata; | |
129 | } | |
130 | ||
12b7b70c | 131 | static void init_pmc_scratch(void) |
74652cf6 | 132 | { |
29f3e3f2 | 133 | struct pmc_ctlr *const pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE; |
76e350b7 | 134 | u32 odmdata; |
74652cf6 TW |
135 | int i; |
136 | ||
137 | /* SCRATCH0 is initialized by the boot ROM and shouldn't be cleared */ | |
138 | for (i = 0; i < 23; i++) | |
139 | writel(0, &pmc->pmc_scratch1+i); | |
140 | ||
141 | /* ODMDATA is for kernel use to determine RAM size, LP config, etc. */ | |
76e350b7 TW |
142 | odmdata = get_odmdata(); |
143 | writel(odmdata, &pmc->pmc_scratch20); | |
74652cf6 TW |
144 | } |
145 | ||
12b7b70c | 146 | void s_init(void) |
74652cf6 | 147 | { |
210576fc SG |
148 | /* Init PMC scratch memory */ |
149 | init_pmc_scratch(); | |
74652cf6 | 150 | |
210576fc | 151 | enable_scu(); |
74652cf6 | 152 | |
d0edce4f TW |
153 | /* init the cache */ |
154 | config_cache(); | |
74652cf6 | 155 | } |