Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Copyright © 2013 Tony Breeds IBM Corporation
0004  * Copyright © 2013 Alistair Popple IBM Corporation
0005  *
0006  * Based on earlier code:
0007  *   Copyright (C) Paul Mackerras 1997.
0008  *
0009  *   Matt Porter <mporter@kernel.crashing.org>
0010  *   Copyright 2002-2005 MontaVista Software Inc.
0011  *
0012  *   Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
0013  *   Copyright (c) 2003, 2004 Zultys Technologies
0014  *
0015  *    Copyright 2007 David Gibson, IBM Corporation.
0016  *    Copyright 2010 Ben. Herrenschmidt, IBM Corporation.
0017  *    Copyright © 2011 David Kleikamp IBM Corporation
0018  */
0019 #include <stdarg.h>
0020 #include <stddef.h>
0021 #include "types.h"
0022 #include "elf.h"
0023 #include "string.h"
0024 #include "stdlib.h"
0025 #include "stdio.h"
0026 #include "page.h"
0027 #include "ops.h"
0028 #include "reg.h"
0029 #include "io.h"
0030 #include "dcr.h"
0031 #include "4xx.h"
0032 #include "44x.h"
0033 #include "libfdt.h"
0034 
0035 BSS_STACK(4096);
0036 
0037 #define SPRN_PIR    0x11E   /* Processor Identification Register */
0038 #define USERDATA_LEN    256 /* Length of userdata passed in by PIBS */
0039 #define MAX_RANKS   0x4
0040 #define DDR3_MR0CF  0x80010011U
0041 #define CCTL0_MCO2  0x8000080FU
0042 #define CCTL0_MCO3  0x80000810U
0043 #define CCTL0_MCO4  0x80000811U
0044 #define CCTL0_MCO5  0x80000812U
0045 #define CCTL0_MCO6  0x80000813U
0046 
0047 static unsigned long long ibm_akebono_memsize;
0048 static long long unsigned mac_addr;
0049 
0050 static unsigned long long ibm_akebono_detect_memsize(void)
0051 {
0052     u32 reg;
0053     unsigned i;
0054     unsigned long long memsize = 0;
0055 
0056     for (i = 0; i < MAX_RANKS; i++) {
0057         reg = mfdcrx(DDR3_MR0CF + i);
0058 
0059         if (!(reg & 1))
0060             continue;
0061 
0062         reg &= 0x0000f000;
0063         reg >>= 12;
0064         memsize += (0x800000ULL << reg);
0065     }
0066 
0067     return memsize;
0068 }
0069 
0070 static void ibm_akebono_fixups(void)
0071 {
0072     void *emac;
0073     u32 reg;
0074 
0075     dt_fixup_memory(0x0ULL,  ibm_akebono_memsize);
0076 
0077     /* Fixup the SD timeout frequency */
0078     mtdcrx(CCTL0_MCO4, 0x1);
0079 
0080     /* Disable SD high-speed mode (which seems to be broken) */
0081     reg = mfdcrx(CCTL0_MCO2) & ~0x2;
0082     mtdcrx(CCTL0_MCO2, reg);
0083 
0084     /* Set the MAC address */
0085     emac = finddevice("/plb/opb/ethernet");
0086     if (emac > 0) {
0087         if (mac_addr)
0088             setprop(emac, "local-mac-address",
0089                 ((u8 *) &mac_addr) + 2 , 6);
0090     }
0091 }
0092 
0093 void platform_init(char *userdata)
0094 {
0095     unsigned long end_of_ram, avail_ram;
0096     u32 pir_reg;
0097     int node, size;
0098     const u32 *timebase;
0099     int len, i, userdata_len;
0100     char *end;
0101 
0102     userdata[USERDATA_LEN - 1] = '\0';
0103     userdata_len = strlen(userdata);
0104     for (i = 0; i < userdata_len - 15; i++) {
0105         if (strncmp(&userdata[i], "local-mac-addr=", 15) == 0) {
0106             if (i > 0 && userdata[i - 1] != ' ') {
0107                 /* We've only found a substring ending
0108                  * with local-mac-addr so this isn't
0109                  * our mac address. */
0110                 continue;
0111             }
0112 
0113             mac_addr = strtoull(&userdata[i + 15], &end, 16);
0114 
0115             /* Remove the "local-mac-addr=<...>" from the kernel
0116              * command line, including the tailing space if
0117              * present. */
0118             if (*end == ' ')
0119                 end++;
0120 
0121             len = ((int) end) - ((int) &userdata[i]);
0122             memmove(&userdata[i], end,
0123                 userdata_len - (len + i) + 1);
0124             break;
0125         }
0126     }
0127 
0128     loader_info.cmdline = userdata;
0129     loader_info.cmdline_len = 256;
0130 
0131     ibm_akebono_memsize = ibm_akebono_detect_memsize();
0132     if (ibm_akebono_memsize >> 32)
0133         end_of_ram = ~0UL;
0134     else
0135         end_of_ram = ibm_akebono_memsize;
0136     avail_ram = end_of_ram - (unsigned long)_end;
0137 
0138     simple_alloc_init(_end, avail_ram, 128, 64);
0139     platform_ops.fixups = ibm_akebono_fixups;
0140     platform_ops.exit = ibm44x_dbcr_reset;
0141     pir_reg = mfspr(SPRN_PIR);
0142 
0143     /* Make sure FDT blob is sane */
0144     if (fdt_check_header(_dtb_start) != 0)
0145         fatal("Invalid device tree blob\n");
0146 
0147     node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
0148                          "cpu", sizeof("cpu"));
0149     if (!node)
0150         fatal("Cannot find cpu node\n");
0151     timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size);
0152     if (timebase && (size == 4))
0153         timebase_period_ns = 1000000000 / *timebase;
0154 
0155     fdt_set_boot_cpuid_phys(_dtb_start, pir_reg);
0156     fdt_init(_dtb_start);
0157 
0158     serial_console_init();
0159 }