120 lines
		
	
	
	
		
			3 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			120 lines
		
	
	
	
		
			3 KiB
			
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * Copyright © 2011 Tony Breeds IBM Corporation | ||
|  |  * | ||
|  |  * Based on earlier code: | ||
|  |  *   Copyright (C) Paul Mackerras 1997. | ||
|  |  * | ||
|  |  *   Matt Porter <mporter@kernel.crashing.org> | ||
|  |  *   Copyright 2002-2005 MontaVista Software Inc. | ||
|  |  * | ||
|  |  *   Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net> | ||
|  |  *   Copyright (c) 2003, 2004 Zultys Technologies | ||
|  |  * | ||
|  |  *    Copyright 2007 David Gibson, IBM Corporation. | ||
|  |  *    Copyright 2010 Ben. Herrenschmidt, IBM Corporation. | ||
|  |  *    Copyright © 2011 David Kleikamp IBM Corporation | ||
|  |  * | ||
|  |  * This program is free software; you can redistribute it and/or | ||
|  |  * modify it under the terms of the GNU General Public License | ||
|  |  * as published by the Free Software Foundation; either version | ||
|  |  * 2 of the License, or (at your option) any later version. | ||
|  |  */ | ||
|  | #include <stdarg.h>
 | ||
|  | #include <stddef.h>
 | ||
|  | #include "types.h"
 | ||
|  | #include "elf.h"
 | ||
|  | #include "string.h"
 | ||
|  | #include "stdio.h"
 | ||
|  | #include "page.h"
 | ||
|  | #include "ops.h"
 | ||
|  | #include "reg.h"
 | ||
|  | #include "io.h"
 | ||
|  | #include "dcr.h"
 | ||
|  | #include "4xx.h"
 | ||
|  | #include "44x.h"
 | ||
|  | #include "libfdt.h"
 | ||
|  | 
 | ||
|  | BSS_STACK(4096); | ||
|  | 
 | ||
|  | #define MAX_RANKS	0x4
 | ||
|  | #define DDR3_MR0CF	0x80010011U
 | ||
|  | 
 | ||
|  | static unsigned long long ibm_currituck_memsize; | ||
|  | static unsigned long long ibm_currituck_detect_memsize(void) | ||
|  | { | ||
|  | 	u32 reg; | ||
|  | 	unsigned i; | ||
|  | 	unsigned long long memsize = 0; | ||
|  | 
 | ||
|  | 	for(i = 0; i < MAX_RANKS; i++){ | ||
|  | 		reg = mfdcrx(DDR3_MR0CF + i); | ||
|  | 
 | ||
|  | 		if (!(reg & 1)) | ||
|  | 			continue; | ||
|  | 
 | ||
|  | 		reg &= 0x0000f000; | ||
|  | 		reg >>= 12; | ||
|  | 		memsize += (0x800000ULL << reg); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return memsize; | ||
|  | } | ||
|  | 
 | ||
|  | static void ibm_currituck_fixups(void) | ||
|  | { | ||
|  | 	void *devp = finddevice("/"); | ||
|  | 	u32 dma_ranges[7]; | ||
|  | 
 | ||
|  | 	dt_fixup_memory(0x0ULL,  ibm_currituck_memsize); | ||
|  | 
 | ||
|  | 	while ((devp = find_node_by_devtype(devp, "pci"))) { | ||
|  | 		if (getprop(devp, "dma-ranges", dma_ranges, sizeof(dma_ranges)) < 0) { | ||
|  | 			printf("%s: Failed to get dma-ranges\r\n", __func__); | ||
|  | 			continue; | ||
|  | 		} | ||
|  | 
 | ||
|  | 		dma_ranges[5] = ibm_currituck_memsize >> 32; | ||
|  | 		dma_ranges[6] = ibm_currituck_memsize & 0xffffffffUL; | ||
|  | 
 | ||
|  | 		setprop(devp, "dma-ranges", dma_ranges, sizeof(dma_ranges)); | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | #define SPRN_PIR	0x11E	/* Processor Indentification Register */
 | ||
|  | void platform_init(void) | ||
|  | { | ||
|  | 	unsigned long end_of_ram, avail_ram; | ||
|  | 	u32 pir_reg; | ||
|  | 	int node, size; | ||
|  | 	const u32 *timebase; | ||
|  | 
 | ||
|  | 	ibm_currituck_memsize = ibm_currituck_detect_memsize(); | ||
|  | 	if (ibm_currituck_memsize >> 32) | ||
|  | 		end_of_ram = ~0UL; | ||
|  | 	else | ||
|  | 		end_of_ram = ibm_currituck_memsize; | ||
|  | 	avail_ram = end_of_ram - (unsigned long)_end; | ||
|  | 
 | ||
|  | 	simple_alloc_init(_end, avail_ram, 128, 64); | ||
|  | 	platform_ops.fixups = ibm_currituck_fixups; | ||
|  | 	platform_ops.exit = ibm44x_dbcr_reset; | ||
|  | 	pir_reg = mfspr(SPRN_PIR); | ||
|  | 
 | ||
|  | 	/* Make sure FDT blob is sane */ | ||
|  | 	if (fdt_check_header(_dtb_start) != 0) | ||
|  | 		fatal("Invalid device tree blob\n"); | ||
|  | 
 | ||
|  | 	node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type", | ||
|  | 	                                     "cpu", sizeof("cpu")); | ||
|  | 	if (!node) | ||
|  | 		fatal("Cannot find cpu node\n"); | ||
|  | 	timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size); | ||
|  | 	if (timebase && (size == 4)) | ||
|  | 		timebase_period_ns = 1000000000 / *timebase; | ||
|  | 
 | ||
|  | 	fdt_set_boot_cpuid_phys(_dtb_start, pir_reg); | ||
|  | 	fdt_init(_dtb_start); | ||
|  | 
 | ||
|  | 	serial_console_init(); | ||
|  | } |