linux/arch/mips/mti-malta/malta-init.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * PROM library initialisation code.
   7 *
   8 * Copyright (C) 1999,2000,2004,2005,2012  MIPS Technologies, Inc.
   9 * All rights reserved.
  10 * Authors: Carsten Langgaard <carstenl@mips.com>
  11 *         Maciej W. Rozycki <macro@mips.com>
  12 *          Steven J. Hill <sjhill@mips.com>
  13 */
  14#include <linux/init.h>
  15#include <linux/string.h>
  16#include <linux/kernel.h>
  17
  18#include <asm/cacheflush.h>
  19#include <asm/smp-ops.h>
  20#include <asm/traps.h>
  21#include <asm/fw/fw.h>
  22#include <asm/gcmpregs.h>
  23#include <asm/mips-boards/generic.h>
  24#include <asm/mips-boards/malta.h>
  25
  26static int mips_revision_corid;
  27int mips_revision_sconid;
  28
  29/* Bonito64 system controller register base. */
  30unsigned long _pcictrl_bonito;
  31unsigned long _pcictrl_bonito_pcicfg;
  32
  33/* GT64120 system controller register base */
  34unsigned long _pcictrl_gt64120;
  35
  36/* MIPS System controller register base */
  37unsigned long _pcictrl_msc;
  38
  39#ifdef CONFIG_SERIAL_8250_CONSOLE
  40static void __init console_config(void)
  41{
  42        char console_string[40];
  43        int baud = 0;
  44        char parity = '\0', bits = '\0', flow = '\0';
  45        char *s;
  46
  47        if ((strstr(fw_getcmdline(), "console=")) == NULL) {
  48                s = fw_getenv("modetty0");
  49                if (s) {
  50                        while (*s >= '0' && *s <= '9')
  51                                baud = baud*10 + *s++ - '0';
  52                        if (*s == ',')
  53                                s++;
  54                        if (*s)
  55                                parity = *s++;
  56                        if (*s == ',')
  57                                s++;
  58                        if (*s)
  59                                bits = *s++;
  60                        if (*s == ',')
  61                                s++;
  62                        if (*s == 'h')
  63                                flow = 'r';
  64                }
  65                if (baud == 0)
  66                        baud = 38400;
  67                if (parity != 'n' && parity != 'o' && parity != 'e')
  68                        parity = 'n';
  69                if (bits != '7' && bits != '8')
  70                        bits = '8';
  71                if (flow == '\0')
  72                        flow = 'r';
  73                sprintf(console_string, " console=ttyS0,%d%c%c%c", baud,
  74                        parity, bits, flow);
  75                strcat(fw_getcmdline(), console_string);
  76                pr_info("Config serial console:%s\n", console_string);
  77        }
  78}
  79#endif
  80
  81static void __init mips_nmi_setup(void)
  82{
  83        void *base;
  84        extern char except_vec_nmi;
  85
  86        base = cpu_has_veic ?
  87                (void *)(CAC_BASE + 0xa80) :
  88                (void *)(CAC_BASE + 0x380);
  89        memcpy(base, &except_vec_nmi, 0x80);
  90        flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
  91}
  92
  93static void __init mips_ejtag_setup(void)
  94{
  95        void *base;
  96        extern char except_vec_ejtag_debug;
  97
  98        base = cpu_has_veic ?
  99                (void *)(CAC_BASE + 0xa00) :
 100                (void *)(CAC_BASE + 0x300);
 101        memcpy(base, &except_vec_ejtag_debug, 0x80);
 102        flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
 103}
 104
 105extern struct plat_smp_ops msmtc_smp_ops;
 106
 107void __init prom_init(void)
 108{
 109        mips_display_message("LINUX");
 110
 111        /*
 112         * early setup of _pcictrl_bonito so that we can determine
 113         * the system controller on a CORE_EMUL board
 114         */
 115        _pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE);
 116
 117        mips_revision_corid = MIPS_REVISION_CORID;
 118
 119        if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) {
 120                if (BONITO_PCIDID == 0x0001df53 ||
 121                    BONITO_PCIDID == 0x0003df53)
 122                        mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON;
 123                else
 124                        mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC;
 125        }
 126
 127        mips_revision_sconid = MIPS_REVISION_SCONID;
 128        if (mips_revision_sconid == MIPS_REVISION_SCON_OTHER) {
 129                switch (mips_revision_corid) {
 130                case MIPS_REVISION_CORID_QED_RM5261:
 131                case MIPS_REVISION_CORID_CORE_LV:
 132                case MIPS_REVISION_CORID_CORE_FPGA:
 133                case MIPS_REVISION_CORID_CORE_FPGAR2:
 134                        mips_revision_sconid = MIPS_REVISION_SCON_GT64120;
 135                        break;
 136                case MIPS_REVISION_CORID_CORE_EMUL_BON:
 137                case MIPS_REVISION_CORID_BONITO64:
 138                case MIPS_REVISION_CORID_CORE_20K:
 139                        mips_revision_sconid = MIPS_REVISION_SCON_BONITO;
 140                        break;
 141                case MIPS_REVISION_CORID_CORE_MSC:
 142                case MIPS_REVISION_CORID_CORE_FPGA2:
 143                case MIPS_REVISION_CORID_CORE_24K:
 144                        /*
 145                         * SOCit/ROCit support is essentially identical
 146                         * but make an attempt to distinguish them
 147                         */
 148                        mips_revision_sconid = MIPS_REVISION_SCON_SOCIT;
 149                        break;
 150                case MIPS_REVISION_CORID_CORE_FPGA3:
 151                case MIPS_REVISION_CORID_CORE_FPGA4:
 152                case MIPS_REVISION_CORID_CORE_FPGA5:
 153                case MIPS_REVISION_CORID_CORE_EMUL_MSC:
 154                default:
 155                        /* See above */
 156                        mips_revision_sconid = MIPS_REVISION_SCON_ROCIT;
 157                        break;
 158                }
 159        }
 160
 161        switch (mips_revision_sconid) {
 162                u32 start, map, mask, data;
 163
 164        case MIPS_REVISION_SCON_GT64120:
 165                /*
 166                 * Setup the North bridge to do Master byte-lane swapping
 167                 * when running in bigendian.
 168                 */
 169                _pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000);
 170
 171#ifdef CONFIG_CPU_LITTLE_ENDIAN
 172                GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
 173                         GT_PCI0_CMD_SBYTESWAP_BIT);
 174#else
 175                GT_WRITE(GT_PCI0_CMD_OFS, 0);
 176#endif
 177                /* Fix up PCI I/O mapping if necessary (for Atlas).  */
 178                start = GT_READ(GT_PCI0IOLD_OFS);
 179                map = GT_READ(GT_PCI0IOREMAP_OFS);
 180                if ((start & map) != 0) {
 181                        map &= ~start;
 182                        GT_WRITE(GT_PCI0IOREMAP_OFS, map);
 183                }
 184
 185                set_io_port_base(MALTA_GT_PORT_BASE);
 186                break;
 187
 188        case MIPS_REVISION_SCON_BONITO:
 189                _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE);
 190
 191                /*
 192                 * Disable Bonito IOBC.
 193                 */
 194                BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
 195                        ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
 196                          BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
 197
 198                /*
 199                 * Setup the North bridge to do Master byte-lane swapping
 200                 * when running in bigendian.
 201                 */
 202#ifdef CONFIG_CPU_LITTLE_ENDIAN
 203                BONITO_BONGENCFG = BONITO_BONGENCFG &
 204                        ~(BONITO_BONGENCFG_MSTRBYTESWAP |
 205                          BONITO_BONGENCFG_BYTESWAP);
 206#else
 207                BONITO_BONGENCFG = BONITO_BONGENCFG |
 208                        BONITO_BONGENCFG_MSTRBYTESWAP |
 209                        BONITO_BONGENCFG_BYTESWAP;
 210#endif
 211
 212                set_io_port_base(MALTA_BONITO_PORT_BASE);
 213                break;
 214
 215        case MIPS_REVISION_SCON_SOCIT:
 216        case MIPS_REVISION_SCON_ROCIT:
 217                _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000);
 218mips_pci_controller:
 219                mb();
 220                MSC_READ(MSC01_PCI_CFG, data);
 221                MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT);
 222                wmb();
 223
 224                /* Fix up lane swapping.  */
 225#ifdef CONFIG_CPU_LITTLE_ENDIAN
 226                MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
 227#else
 228                MSC_WRITE(MSC01_PCI_SWAP,
 229                          MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF |
 230                          MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
 231                          MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
 232#endif
 233                /* Fix up target memory mapping.  */
 234                MSC_READ(MSC01_PCI_BAR0, mask);
 235                MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK);
 236
 237                /* Don't handle target retries indefinitely.  */
 238                if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
 239                    MSC01_PCI_CFG_MAXRTRY_MSK)
 240                        data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK <<
 241                                         MSC01_PCI_CFG_MAXRTRY_SHF)) |
 242                               ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) <<
 243                                MSC01_PCI_CFG_MAXRTRY_SHF);
 244
 245                wmb();
 246                MSC_WRITE(MSC01_PCI_CFG, data);
 247                mb();
 248
 249                set_io_port_base(MALTA_MSC_PORT_BASE);
 250                break;
 251
 252        case MIPS_REVISION_SCON_SOCITSC:
 253        case MIPS_REVISION_SCON_SOCITSCP:
 254                _pcictrl_msc = (unsigned long)ioremap(MIPS_SOCITSC_PCI_REG_BASE, 0x2000);
 255                goto mips_pci_controller;
 256
 257        default:
 258                /* Unknown system controller */
 259                mips_display_message("SC Error");
 260                while (1);      /* We die here... */
 261        }
 262        board_nmi_handler_setup = mips_nmi_setup;
 263        board_ejtag_handler_setup = mips_ejtag_setup;
 264
 265        fw_init_cmdline();
 266        fw_meminit();
 267#ifdef CONFIG_SERIAL_8250_CONSOLE
 268        console_config();
 269#endif
 270        /* Early detection of CMP support */
 271        if (gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ))
 272                if (!register_cmp_smp_ops())
 273                        return;
 274
 275        if (!register_vsmp_smp_ops())
 276                return;
 277
 278#ifdef CONFIG_MIPS_MT_SMTC
 279        register_smp_ops(&msmtc_smp_ops);
 280#endif
 281}
 282