linux/arch/mips/mti-malta/malta-init.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 1999, 2000, 2004, 2005  MIPS Technologies, Inc.
   3 *      All rights reserved.
   4 *      Authors: Carsten Langgaard <carstenl@mips.com>
   5 *               Maciej W. Rozycki <macro@mips.com>
   6 *
   7 *  This program is free software; you can distribute it and/or modify it
   8 *  under the terms of the GNU General Public License (Version 2) as
   9 *  published by the Free Software Foundation.
  10 *
  11 *  This program is distributed in the hope it will be useful, but WITHOUT
  12 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14 *  for more details.
  15 *
  16 *  You should have received a copy of the GNU General Public License along
  17 *  with this program; if not, write to the Free Software Foundation, Inc.,
  18 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
  19 *
  20 * PROM library initialisation code.
  21 */
  22#include <linux/init.h>
  23#include <linux/string.h>
  24#include <linux/kernel.h>
  25
  26#include <asm/bootinfo.h>
  27#include <asm/gt64120.h>
  28#include <asm/io.h>
  29#include <asm/system.h>
  30#include <asm/cacheflush.h>
  31#include <asm/traps.h>
  32
  33#include <asm/gcmpregs.h>
  34#include <asm/mips-boards/prom.h>
  35#include <asm/mips-boards/generic.h>
  36#include <asm/mips-boards/bonito64.h>
  37#include <asm/mips-boards/msc01_pci.h>
  38
  39#include <asm/mips-boards/malta.h>
  40
  41int prom_argc;
  42int *_prom_argv, *_prom_envp;
  43
  44/*
  45 * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
  46 * This macro take care of sign extension, if running in 64-bit mode.
  47 */
  48#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
  49
  50int init_debug;
  51
  52static int mips_revision_corid;
  53int mips_revision_sconid;
  54
  55/* Bonito64 system controller register base. */
  56unsigned long _pcictrl_bonito;
  57unsigned long _pcictrl_bonito_pcicfg;
  58
  59/* GT64120 system controller register base */
  60unsigned long _pcictrl_gt64120;
  61
  62/* MIPS System controller register base */
  63unsigned long _pcictrl_msc;
  64
  65char *prom_getenv(char *envname)
  66{
  67        /*
  68         * Return a pointer to the given environment variable.
  69         * In 64-bit mode: we're using 64-bit pointers, but all pointers
  70         * in the PROM structures are only 32-bit, so we need some
  71         * workarounds, if we are running in 64-bit mode.
  72         */
  73        int i, index=0;
  74
  75        i = strlen(envname);
  76
  77        while (prom_envp(index)) {
  78                if(strncmp(envname, prom_envp(index), i) == 0) {
  79                        return(prom_envp(index+1));
  80                }
  81                index += 2;
  82        }
  83
  84        return NULL;
  85}
  86
  87static inline unsigned char str2hexnum(unsigned char c)
  88{
  89        if (c >= '0' && c <= '9')
  90                return c - '0';
  91        if (c >= 'a' && c <= 'f')
  92                return c - 'a' + 10;
  93        return 0; /* foo */
  94}
  95
  96static inline void str2eaddr(unsigned char *ea, unsigned char *str)
  97{
  98        int i;
  99
 100        for (i = 0; i < 6; i++) {
 101                unsigned char num;
 102
 103                if((*str == '.') || (*str == ':'))
 104                        str++;
 105                num = str2hexnum(*str++) << 4;
 106                num |= (str2hexnum(*str++));
 107                ea[i] = num;
 108        }
 109}
 110
 111int get_ethernet_addr(char *ethernet_addr)
 112{
 113        char *ethaddr_str;
 114
 115        ethaddr_str = prom_getenv("ethaddr");
 116        if (!ethaddr_str) {
 117                printk("ethaddr not set in boot prom\n");
 118                return -1;
 119        }
 120        str2eaddr(ethernet_addr, ethaddr_str);
 121
 122        if (init_debug > 1) {
 123                int i;
 124                printk("get_ethernet_addr: ");
 125                for (i=0; i<5; i++)
 126                        printk("%02x:", (unsigned char)*(ethernet_addr+i));
 127                printk("%02x\n", *(ethernet_addr+i));
 128        }
 129
 130        return 0;
 131}
 132
 133#ifdef CONFIG_SERIAL_8250_CONSOLE
 134static void __init console_config(void)
 135{
 136        char console_string[40];
 137        int baud = 0;
 138        char parity = '\0', bits = '\0', flow = '\0';
 139        char *s;
 140
 141        if ((strstr(prom_getcmdline(), "console=")) == NULL) {
 142                s = prom_getenv("modetty0");
 143                if (s) {
 144                        while (*s >= '0' && *s <= '9')
 145                                baud = baud*10 + *s++ - '0';
 146                        if (*s == ',') s++;
 147                        if (*s) parity = *s++;
 148                        if (*s == ',') s++;
 149                        if (*s) bits = *s++;
 150                        if (*s == ',') s++;
 151                        if (*s == 'h') flow = 'r';
 152                }
 153                if (baud == 0)
 154                        baud = 38400;
 155                if (parity != 'n' && parity != 'o' && parity != 'e')
 156                        parity = 'n';
 157                if (bits != '7' && bits != '8')
 158                        bits = '8';
 159                if (flow == '\0')
 160                        flow = 'r';
 161                sprintf(console_string, " console=ttyS0,%d%c%c%c", baud, parity, bits, flow);
 162                strcat(prom_getcmdline(), console_string);
 163                pr_info("Config serial console:%s\n", console_string);
 164        }
 165}
 166#endif
 167
 168static void __init mips_nmi_setup(void)
 169{
 170        void *base;
 171        extern char except_vec_nmi;
 172
 173        base = cpu_has_veic ?
 174                (void *)(CAC_BASE + 0xa80) :
 175                (void *)(CAC_BASE + 0x380);
 176        memcpy(base, &except_vec_nmi, 0x80);
 177        flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
 178}
 179
 180static void __init mips_ejtag_setup(void)
 181{
 182        void *base;
 183        extern char except_vec_ejtag_debug;
 184
 185        base = cpu_has_veic ?
 186                (void *)(CAC_BASE + 0xa00) :
 187                (void *)(CAC_BASE + 0x300);
 188        memcpy(base, &except_vec_ejtag_debug, 0x80);
 189        flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
 190}
 191
 192extern struct plat_smp_ops msmtc_smp_ops;
 193
 194void __init prom_init(void)
 195{
 196        prom_argc = fw_arg0;
 197        _prom_argv = (int *) fw_arg1;
 198        _prom_envp = (int *) fw_arg2;
 199
 200        mips_display_message("LINUX");
 201
 202        /*
 203         * early setup of _pcictrl_bonito so that we can determine
 204         * the system controller on a CORE_EMUL board
 205         */
 206        _pcictrl_bonito = (unsigned long)ioremap(BONITO_REG_BASE, BONITO_REG_SIZE);
 207
 208        mips_revision_corid = MIPS_REVISION_CORID;
 209
 210        if (mips_revision_corid == MIPS_REVISION_CORID_CORE_EMUL) {
 211                if (BONITO_PCIDID == 0x0001df53 ||
 212                    BONITO_PCIDID == 0x0003df53)
 213                        mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_BON;
 214                else
 215                        mips_revision_corid = MIPS_REVISION_CORID_CORE_EMUL_MSC;
 216        }
 217
 218        mips_revision_sconid = MIPS_REVISION_SCONID;
 219        if (mips_revision_sconid == MIPS_REVISION_SCON_OTHER) {
 220                switch (mips_revision_corid) {
 221                case MIPS_REVISION_CORID_QED_RM5261:
 222                case MIPS_REVISION_CORID_CORE_LV:
 223                case MIPS_REVISION_CORID_CORE_FPGA:
 224                case MIPS_REVISION_CORID_CORE_FPGAR2:
 225                        mips_revision_sconid = MIPS_REVISION_SCON_GT64120;
 226                        break;
 227                case MIPS_REVISION_CORID_CORE_EMUL_BON:
 228                case MIPS_REVISION_CORID_BONITO64:
 229                case MIPS_REVISION_CORID_CORE_20K:
 230                        mips_revision_sconid = MIPS_REVISION_SCON_BONITO;
 231                        break;
 232                case MIPS_REVISION_CORID_CORE_MSC:
 233                case MIPS_REVISION_CORID_CORE_FPGA2:
 234                case MIPS_REVISION_CORID_CORE_24K:
 235                        /*
 236                         * SOCit/ROCit support is essentially identical
 237                         * but make an attempt to distinguish them
 238                         */
 239                        mips_revision_sconid = MIPS_REVISION_SCON_SOCIT;
 240                        break;
 241                case MIPS_REVISION_CORID_CORE_FPGA3:
 242                case MIPS_REVISION_CORID_CORE_FPGA4:
 243                case MIPS_REVISION_CORID_CORE_FPGA5:
 244                case MIPS_REVISION_CORID_CORE_EMUL_MSC:
 245                default:
 246                        /* See above */
 247                        mips_revision_sconid = MIPS_REVISION_SCON_ROCIT;
 248                        break;
 249                }
 250        }
 251
 252        switch (mips_revision_sconid) {
 253                u32 start, map, mask, data;
 254
 255        case MIPS_REVISION_SCON_GT64120:
 256                /*
 257                 * Setup the North bridge to do Master byte-lane swapping
 258                 * when running in bigendian.
 259                 */
 260                _pcictrl_gt64120 = (unsigned long)ioremap(MIPS_GT_BASE, 0x2000);
 261
 262#ifdef CONFIG_CPU_LITTLE_ENDIAN
 263                GT_WRITE(GT_PCI0_CMD_OFS, GT_PCI0_CMD_MBYTESWAP_BIT |
 264                         GT_PCI0_CMD_SBYTESWAP_BIT);
 265#else
 266                GT_WRITE(GT_PCI0_CMD_OFS, 0);
 267#endif
 268                /* Fix up PCI I/O mapping if necessary (for Atlas).  */
 269                start = GT_READ(GT_PCI0IOLD_OFS);
 270                map = GT_READ(GT_PCI0IOREMAP_OFS);
 271                if ((start & map) != 0) {
 272                        map &= ~start;
 273                        GT_WRITE(GT_PCI0IOREMAP_OFS, map);
 274                }
 275
 276                set_io_port_base(MALTA_GT_PORT_BASE);
 277                break;
 278
 279        case MIPS_REVISION_SCON_BONITO:
 280                _pcictrl_bonito_pcicfg = (unsigned long)ioremap(BONITO_PCICFG_BASE, BONITO_PCICFG_SIZE);
 281
 282                /*
 283                 * Disable Bonito IOBC.
 284                 */
 285                BONITO_PCIMEMBASECFG = BONITO_PCIMEMBASECFG &
 286                        ~(BONITO_PCIMEMBASECFG_MEMBASE0_CACHED |
 287                          BONITO_PCIMEMBASECFG_MEMBASE1_CACHED);
 288
 289                /*
 290                 * Setup the North bridge to do Master byte-lane swapping
 291                 * when running in bigendian.
 292                 */
 293#ifdef CONFIG_CPU_LITTLE_ENDIAN
 294                BONITO_BONGENCFG = BONITO_BONGENCFG &
 295                        ~(BONITO_BONGENCFG_MSTRBYTESWAP |
 296                          BONITO_BONGENCFG_BYTESWAP);
 297#else
 298                BONITO_BONGENCFG = BONITO_BONGENCFG |
 299                        BONITO_BONGENCFG_MSTRBYTESWAP |
 300                        BONITO_BONGENCFG_BYTESWAP;
 301#endif
 302
 303                set_io_port_base(MALTA_BONITO_PORT_BASE);
 304                break;
 305
 306        case MIPS_REVISION_SCON_SOCIT:
 307        case MIPS_REVISION_SCON_ROCIT:
 308                _pcictrl_msc = (unsigned long)ioremap(MIPS_MSC01_PCI_REG_BASE, 0x2000);
 309        mips_pci_controller:
 310                mb();
 311                MSC_READ(MSC01_PCI_CFG, data);
 312                MSC_WRITE(MSC01_PCI_CFG, data & ~MSC01_PCI_CFG_EN_BIT);
 313                wmb();
 314
 315                /* Fix up lane swapping.  */
 316#ifdef CONFIG_CPU_LITTLE_ENDIAN
 317                MSC_WRITE(MSC01_PCI_SWAP, MSC01_PCI_SWAP_NOSWAP);
 318#else
 319                MSC_WRITE(MSC01_PCI_SWAP,
 320                          MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_IO_SHF |
 321                          MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_MEM_SHF |
 322                          MSC01_PCI_SWAP_BYTESWAP << MSC01_PCI_SWAP_BAR0_SHF);
 323#endif
 324                /* Fix up target memory mapping.  */
 325                MSC_READ(MSC01_PCI_BAR0, mask);
 326                MSC_WRITE(MSC01_PCI_P2SCMSKL, mask & MSC01_PCI_BAR0_SIZE_MSK);
 327
 328                /* Don't handle target retries indefinitely.  */
 329                if ((data & MSC01_PCI_CFG_MAXRTRY_MSK) ==
 330                    MSC01_PCI_CFG_MAXRTRY_MSK)
 331                        data = (data & ~(MSC01_PCI_CFG_MAXRTRY_MSK <<
 332                                         MSC01_PCI_CFG_MAXRTRY_SHF)) |
 333                               ((MSC01_PCI_CFG_MAXRTRY_MSK - 1) <<
 334                                MSC01_PCI_CFG_MAXRTRY_SHF);
 335
 336                wmb();
 337                MSC_WRITE(MSC01_PCI_CFG, data);
 338                mb();
 339
 340                set_io_port_base(MALTA_MSC_PORT_BASE);
 341                break;
 342
 343        case MIPS_REVISION_SCON_SOCITSC:
 344        case MIPS_REVISION_SCON_SOCITSCP:
 345                _pcictrl_msc = (unsigned long)ioremap(MIPS_SOCITSC_PCI_REG_BASE, 0x2000);
 346                goto mips_pci_controller;
 347
 348        default:
 349                /* Unknown system controller */
 350                mips_display_message("SC Error");
 351                while (1);   /* We die here... */
 352        }
 353        board_nmi_handler_setup = mips_nmi_setup;
 354        board_ejtag_handler_setup = mips_ejtag_setup;
 355
 356        prom_init_cmdline();
 357        prom_meminit();
 358#ifdef CONFIG_SERIAL_8250_CONSOLE
 359        console_config();
 360#endif
 361#ifdef CONFIG_MIPS_CMP
 362        /* Early detection of CMP support */
 363        if (gcmp_probe(GCMP_BASE_ADDR, GCMP_ADDRSPACE_SZ))
 364                register_smp_ops(&cmp_smp_ops);
 365        else
 366#endif
 367#ifdef CONFIG_MIPS_MT_SMP
 368                register_smp_ops(&vsmp_smp_ops);
 369#endif
 370#ifdef CONFIG_MIPS_MT_SMTC
 371        register_smp_ops(&msmtc_smp_ops);
 372#endif
 373}
 374