1/* 2 * Broadcom HNDSoC utlities, only for AP router 3 * File: hndsoc.c 4 * 5 * Copyright (C) 2015, Broadcom Corporation. All Rights Reserved. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 14 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 16 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 17 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 * 19 * $Id$ 20 */ 21 22#include <typedefs.h> 23#include <osl.h> 24#include <siutils.h> 25#include <hndsoc.h> 26#include <sbchipc.h> 27#include <bcmdevs.h> 28#include <bcmnvram.h> 29#include <nand_core.h> 30 31static int bootdev = -1; 32static int knldev = -1; 33 34int 35soc_boot_dev(void *socp) 36{ 37 si_t *sih = (si_t *)socp; 38 int bootfrom = SOC_BOOTDEV_SFLASH; 39 uint32 origidx; 40 uint32 option; 41 42 if (bootdev != -1) 43 return bootdev; 44 45 origidx = si_coreidx(sih); 46 47 /* Check 4707 (NorthStar) */ 48 if (sih->ccrev == 42) { 49 if (si_setcore(sih, NS_ROM_CORE_ID, 0) != NULL) { 50 option = si_core_sflags(sih, 0, 0) & SISF_NS_BOOTDEV_MASK; 51 if (option == SISF_NS_BOOTDEV_NOR) { 52 bootfrom = SOC_BOOTDEV_SFLASH; 53 } 54 else if (option == SISF_NS_BOOTDEV_NAND) { 55 bootfrom = SOC_BOOTDEV_NANDFLASH; 56 } 57 else { 58 /* This must be SISF_NS_BOOTDEV_ROM */ 59 bootfrom = SOC_BOOTDEV_ROM; 60 } 61 } 62 } 63 else { 64 chipcregs_t *cc; 65 66 /* Check 5357 */ 67 if (sih->ccrev == 38) { 68 if ((sih->chipst & (1 << 4)) != 0) { 69 bootfrom = SOC_BOOTDEV_NANDFLASH; 70 goto found; 71 } 72 else if ((sih->chipst & (1 << 5)) != 0) { 73 bootfrom = SOC_BOOTDEV_ROM; 74 goto found; 75 } 76 } 77 78 /* Handle old soc, 4704, 4718 */ 79 if ((cc = (chipcregs_t *)si_setcoreidx(sih, SI_CC_IDX))) { 80 option = R_REG(NULL, &cc->capabilities) & CC_CAP_FLASH_MASK; 81 if (option == PFLASH) 82 bootfrom = SOC_BOOTDEV_PFLASH; 83 else 84 bootfrom = SOC_BOOTDEV_SFLASH; 85 } 86 } 87 88found: 89 si_setcoreidx(sih, origidx); 90 91 bootdev = bootfrom; 92 return bootdev; 93} 94 95int 96soc_knl_dev(void *socp) 97{ 98 si_t *sih = (si_t *)socp; 99 char *val; 100 int knlfrom = SOC_KNLDEV_NORFLASH; 101 102 if (knldev != -1) 103 return knldev; 104 105 if (soc_boot_dev(socp) == SOC_BOOTDEV_NANDFLASH) { 106 knlfrom = SOC_KNLDEV_NANDFLASH; 107 goto found; 108 } 109 110 if (((CHIPID(sih->chip) == BCM4706_CHIP_ID) || sih->ccrev == 38) && 111 (sih->cccaps & CC_CAP_NFLASH)) { 112 goto check_nv; 113 } 114 else if (sih->ccrev == 42) { 115 uint32 origidx; 116 nandregs_t *nc; 117 uint32 id = 0; 118 119 origidx = si_coreidx(sih); 120 if ((nc = (nandregs_t *)si_setcore(sih, NS_NAND_CORE_ID, 0)) != NULL) { 121 id = R_REG(NULL, &nc->flash_device_id); 122 } 123 si_setcoreidx(sih, origidx); 124 125 if (id != 0) 126 goto check_nv; 127 } 128 else { 129 /* Break through */ 130 } 131 132 /* Default set to nor boot */ 133 goto found; 134 135check_nv: 136 /* Check NVRAM here */ 137 if ((val = nvram_get("bootflags")) != NULL) { 138 int bootflags; 139#ifdef linux 140 bootflags = simple_strtol(val, NULL, 0); 141#else 142 bootflags = atoi(val); 143#endif 144 if (bootflags & FLASH_KERNEL_NFLASH) 145 knlfrom = SOC_KNLDEV_NANDFLASH; 146 } 147 148found: 149 knldev = knlfrom; 150 return knldev; 151} 152