1*1d3d0f1fSWills Wang /* 2*1d3d0f1fSWills Wang * Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com> 3*1d3d0f1fSWills Wang * 4*1d3d0f1fSWills Wang * SPDX-License-Identifier: GPL-2.0+ 5*1d3d0f1fSWills Wang */ 6*1d3d0f1fSWills Wang 7*1d3d0f1fSWills Wang #include <common.h> 8*1d3d0f1fSWills Wang #include <asm/io.h> 9*1d3d0f1fSWills Wang #include <asm/addrspace.h> 10*1d3d0f1fSWills Wang #include <asm/types.h> 11*1d3d0f1fSWills Wang #include <mach/ath79.h> 12*1d3d0f1fSWills Wang #include <mach/ar71xx_regs.h> 13*1d3d0f1fSWills Wang 14*1d3d0f1fSWills Wang struct ath79_soc_desc { 15*1d3d0f1fSWills Wang enum ath79_soc_type soc; 16*1d3d0f1fSWills Wang const char *chip; 17*1d3d0f1fSWills Wang int major; 18*1d3d0f1fSWills Wang int minor; 19*1d3d0f1fSWills Wang }; 20*1d3d0f1fSWills Wang 21*1d3d0f1fSWills Wang static struct ath79_soc_desc desc[] = { 22*1d3d0f1fSWills Wang {ATH79_SOC_AR7130, "7130", 23*1d3d0f1fSWills Wang REV_ID_MAJOR_AR71XX, AR71XX_REV_ID_MINOR_AR7130}, 24*1d3d0f1fSWills Wang {ATH79_SOC_AR7141, "7141", 25*1d3d0f1fSWills Wang REV_ID_MAJOR_AR71XX, AR71XX_REV_ID_MINOR_AR7141}, 26*1d3d0f1fSWills Wang {ATH79_SOC_AR7161, "7161", 27*1d3d0f1fSWills Wang REV_ID_MAJOR_AR71XX, AR71XX_REV_ID_MINOR_AR7161}, 28*1d3d0f1fSWills Wang {ATH79_SOC_AR7240, "7240", REV_ID_MAJOR_AR7240, 0}, 29*1d3d0f1fSWills Wang {ATH79_SOC_AR7241, "7241", REV_ID_MAJOR_AR7241, 0}, 30*1d3d0f1fSWills Wang {ATH79_SOC_AR7242, "7242", REV_ID_MAJOR_AR7242, 0}, 31*1d3d0f1fSWills Wang {ATH79_SOC_AR9130, "9130", 32*1d3d0f1fSWills Wang REV_ID_MAJOR_AR913X, AR913X_REV_ID_MINOR_AR9130}, 33*1d3d0f1fSWills Wang {ATH79_SOC_AR9132, "9132", 34*1d3d0f1fSWills Wang REV_ID_MAJOR_AR913X, AR913X_REV_ID_MINOR_AR9132}, 35*1d3d0f1fSWills Wang {ATH79_SOC_AR9330, "9330", REV_ID_MAJOR_AR9330, 0}, 36*1d3d0f1fSWills Wang {ATH79_SOC_AR9331, "9331", REV_ID_MAJOR_AR9331, 0}, 37*1d3d0f1fSWills Wang {ATH79_SOC_AR9341, "9341", REV_ID_MAJOR_AR9341, 0}, 38*1d3d0f1fSWills Wang {ATH79_SOC_AR9342, "9342", REV_ID_MAJOR_AR9342, 0}, 39*1d3d0f1fSWills Wang {ATH79_SOC_AR9344, "9344", REV_ID_MAJOR_AR9344, 0}, 40*1d3d0f1fSWills Wang {ATH79_SOC_QCA9533, "9533", REV_ID_MAJOR_QCA9533, 0}, 41*1d3d0f1fSWills Wang {ATH79_SOC_QCA9533, "9533", 42*1d3d0f1fSWills Wang REV_ID_MAJOR_QCA9533_V2, 0}, 43*1d3d0f1fSWills Wang {ATH79_SOC_QCA9556, "9556", REV_ID_MAJOR_QCA9556, 0}, 44*1d3d0f1fSWills Wang {ATH79_SOC_QCA9558, "9558", REV_ID_MAJOR_QCA9558, 0}, 45*1d3d0f1fSWills Wang {ATH79_SOC_TP9343, "9343", REV_ID_MAJOR_TP9343, 0}, 46*1d3d0f1fSWills Wang {ATH79_SOC_QCA9561, "9561", REV_ID_MAJOR_QCA9561, 0}, 47*1d3d0f1fSWills Wang }; 48*1d3d0f1fSWills Wang 49*1d3d0f1fSWills Wang int arch_cpu_init(void) 50*1d3d0f1fSWills Wang { 51*1d3d0f1fSWills Wang void __iomem *base; 52*1d3d0f1fSWills Wang enum ath79_soc_type soc = ATH79_SOC_UNKNOWN; 53*1d3d0f1fSWills Wang u32 id, major, minor = 0; 54*1d3d0f1fSWills Wang u32 rev = 0, ver = 1; 55*1d3d0f1fSWills Wang int i; 56*1d3d0f1fSWills Wang 57*1d3d0f1fSWills Wang base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE, 58*1d3d0f1fSWills Wang MAP_NOCACHE); 59*1d3d0f1fSWills Wang 60*1d3d0f1fSWills Wang id = readl(base + AR71XX_RESET_REG_REV_ID); 61*1d3d0f1fSWills Wang major = id & REV_ID_MAJOR_MASK; 62*1d3d0f1fSWills Wang switch (major) { 63*1d3d0f1fSWills Wang case REV_ID_MAJOR_AR71XX: 64*1d3d0f1fSWills Wang case REV_ID_MAJOR_AR913X: 65*1d3d0f1fSWills Wang minor = id & AR71XX_REV_ID_MINOR_MASK; 66*1d3d0f1fSWills Wang rev = id >> AR71XX_REV_ID_REVISION_SHIFT; 67*1d3d0f1fSWills Wang rev &= AR71XX_REV_ID_REVISION_MASK; 68*1d3d0f1fSWills Wang break; 69*1d3d0f1fSWills Wang 70*1d3d0f1fSWills Wang case REV_ID_MAJOR_QCA9533_V2: 71*1d3d0f1fSWills Wang ver = 2; 72*1d3d0f1fSWills Wang /* drop through */ 73*1d3d0f1fSWills Wang 74*1d3d0f1fSWills Wang case REV_ID_MAJOR_AR9341: 75*1d3d0f1fSWills Wang case REV_ID_MAJOR_AR9342: 76*1d3d0f1fSWills Wang case REV_ID_MAJOR_AR9344: 77*1d3d0f1fSWills Wang case REV_ID_MAJOR_QCA9533: 78*1d3d0f1fSWills Wang case REV_ID_MAJOR_QCA9556: 79*1d3d0f1fSWills Wang case REV_ID_MAJOR_QCA9558: 80*1d3d0f1fSWills Wang case REV_ID_MAJOR_TP9343: 81*1d3d0f1fSWills Wang case REV_ID_MAJOR_QCA9561: 82*1d3d0f1fSWills Wang rev = id & AR71XX_REV_ID_REVISION2_MASK; 83*1d3d0f1fSWills Wang break; 84*1d3d0f1fSWills Wang default: 85*1d3d0f1fSWills Wang rev = id & AR71XX_REV_ID_REVISION_MASK; 86*1d3d0f1fSWills Wang break; 87*1d3d0f1fSWills Wang } 88*1d3d0f1fSWills Wang 89*1d3d0f1fSWills Wang for (i = 0; i < ARRAY_SIZE(desc); i++) { 90*1d3d0f1fSWills Wang if ((desc[i].major == major) && 91*1d3d0f1fSWills Wang (desc[i].minor == minor)) { 92*1d3d0f1fSWills Wang soc = desc[i].soc; 93*1d3d0f1fSWills Wang break; 94*1d3d0f1fSWills Wang } 95*1d3d0f1fSWills Wang } 96*1d3d0f1fSWills Wang 97*1d3d0f1fSWills Wang gd->arch.id = id; 98*1d3d0f1fSWills Wang gd->arch.soc = soc; 99*1d3d0f1fSWills Wang gd->arch.rev = rev; 100*1d3d0f1fSWills Wang gd->arch.ver = ver; 101*1d3d0f1fSWills Wang return 0; 102*1d3d0f1fSWills Wang } 103*1d3d0f1fSWills Wang 104*1d3d0f1fSWills Wang int print_cpuinfo(void) 105*1d3d0f1fSWills Wang { 106*1d3d0f1fSWills Wang enum ath79_soc_type soc = ATH79_SOC_UNKNOWN; 107*1d3d0f1fSWills Wang const char *chip = "????"; 108*1d3d0f1fSWills Wang u32 id, rev, ver; 109*1d3d0f1fSWills Wang int i; 110*1d3d0f1fSWills Wang 111*1d3d0f1fSWills Wang for (i = 0; i < ARRAY_SIZE(desc); i++) { 112*1d3d0f1fSWills Wang if (desc[i].soc == gd->arch.soc) { 113*1d3d0f1fSWills Wang chip = desc[i].chip; 114*1d3d0f1fSWills Wang soc = desc[i].soc; 115*1d3d0f1fSWills Wang break; 116*1d3d0f1fSWills Wang } 117*1d3d0f1fSWills Wang } 118*1d3d0f1fSWills Wang 119*1d3d0f1fSWills Wang id = gd->arch.id; 120*1d3d0f1fSWills Wang rev = gd->arch.rev; 121*1d3d0f1fSWills Wang ver = gd->arch.ver; 122*1d3d0f1fSWills Wang 123*1d3d0f1fSWills Wang switch (soc) { 124*1d3d0f1fSWills Wang case ATH79_SOC_QCA9533: 125*1d3d0f1fSWills Wang case ATH79_SOC_QCA9556: 126*1d3d0f1fSWills Wang case ATH79_SOC_QCA9558: 127*1d3d0f1fSWills Wang case ATH79_SOC_QCA9561: 128*1d3d0f1fSWills Wang printf("Qualcomm Atheros QCA%s ver %u rev %u\n", chip, 129*1d3d0f1fSWills Wang ver, rev); 130*1d3d0f1fSWills Wang break; 131*1d3d0f1fSWills Wang case ATH79_SOC_TP9343: 132*1d3d0f1fSWills Wang printf("Qualcomm Atheros TP%s rev %u\n", chip, rev); 133*1d3d0f1fSWills Wang break; 134*1d3d0f1fSWills Wang case ATH79_SOC_UNKNOWN: 135*1d3d0f1fSWills Wang printf("ATH79: unknown SoC, id:0x%08x", id); 136*1d3d0f1fSWills Wang break; 137*1d3d0f1fSWills Wang default: 138*1d3d0f1fSWills Wang printf("Atheros AR%s rev %u\n", chip, rev); 139*1d3d0f1fSWills Wang } 140*1d3d0f1fSWills Wang 141*1d3d0f1fSWills Wang return 0; 142*1d3d0f1fSWills Wang } 143