aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Whitehorn <nwhitehorn@FreeBSD.org>2013-11-17 02:03:36 +0000
committerNathan Whitehorn <nwhitehorn@FreeBSD.org>2013-11-17 02:03:36 +0000
commit52cfe485fb3b3154a68c672fcad7a8fcb3be810e (patch)
tree2bab822133b461d9a8600e683d63bcd6b716e341
parentb899f5d5c998cb4ecad28e8251cb1d048a89261f (diff)
downloadsrc-52cfe485fb3b3154a68c672fcad7a8fcb3be810e.tar.gz
src-52cfe485fb3b3154a68c672fcad7a8fcb3be810e.zip
Move CCSR discovery into the platform module, while simultaneously making
it more flexible about how the CCSR range is found. With this change, the stock MPC85XX will boot on a Routerboard 800. Hardware donated by: Benjamin Perrault
Notes
Notes: svn path=/head/; revision=258244
-rw-r--r--sys/powerpc/booke/machdep.c8
-rw-r--r--sys/powerpc/mpc85xx/mpc85xx.h3
-rw-r--r--sys/powerpc/mpc85xx/platform_mpc85xx.c55
3 files changed, 56 insertions, 10 deletions
diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c
index 69a9ef623399..b289fa135549 100644
--- a/sys/powerpc/booke/machdep.c
+++ b/sys/powerpc/booke/machdep.c
@@ -387,14 +387,6 @@ booke_init(uint32_t arg1, uint32_t arg2)
/* Reset TLB1 to get rid of temporary mappings */
tlb1_init();
- /* Set up IMMR */
- if (fdt_immr_addr(0) == 0) {
- fdt_immr_va = pmap_early_io_map(fdt_immr_pa, fdt_immr_size);
- } else {
- printf("Warning: SOC base registers could not be found!\n");
- fdt_immr_va = 0;
- }
-
/* Reset Time Base */
mttb(0);
diff --git a/sys/powerpc/mpc85xx/mpc85xx.h b/sys/powerpc/mpc85xx/mpc85xx.h
index defb3bf2afd6..c3cbf55512ca 100644
--- a/sys/powerpc/mpc85xx/mpc85xx.h
+++ b/sys/powerpc/mpc85xx/mpc85xx.h
@@ -33,7 +33,8 @@
/*
* Configuration control and status registers
*/
-#define CCSRBAR_VA fdt_immr_va
+extern vm_offset_t ccsrbar_va;
+#define CCSRBAR_VA ccsrbar_va
#define OCP85XX_CCSRBAR (CCSRBAR_VA + 0x0)
#define OCP85XX_BPTR (CCSRBAR_VA + 0x20)
diff --git a/sys/powerpc/mpc85xx/platform_mpc85xx.c b/sys/powerpc/mpc85xx/platform_mpc85xx.c
index b98e031c8b2f..b1903929970f 100644
--- a/sys/powerpc/mpc85xx/platform_mpc85xx.c
+++ b/sys/powerpc/mpc85xx/platform_mpc85xx.c
@@ -49,6 +49,9 @@ __FBSDID("$FreeBSD$");
#include <dev/ofw/ofw_bus_subr.h>
#include <dev/ofw/openfirm.h>
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
#include <powerpc/mpc85xx/mpc85xx.h>
#include "platform_if.h"
@@ -63,6 +66,7 @@ extern uint32_t bp_tlb1_end[];
#endif
extern uint32_t *bootinfo;
+vm_offset_t ccsrbar_va;
static int cpu, maxcpu;
@@ -116,8 +120,12 @@ mpc85xx_probe(platform_t plat)
static int
mpc85xx_attach(platform_t plat)
{
- phandle_t cpus, child;
+ phandle_t cpus, child, ccsr;
+ const char *soc_name_guesses[] = {"/soc", "soc", NULL};
+ const char **name;
+ pcell_t ranges[6], acells, pacells, scells;
uint32_t sr;
+ uint64_t ccsrbar, ccsrsize;
int i, law_max, tgt;
if ((cpus = OF_finddevice("/cpus")) != -1) {
@@ -128,6 +136,51 @@ mpc85xx_attach(platform_t plat)
maxcpu = 1;
/*
+ * Locate CCSR region. Irritatingly, there is no way to find it
+ * unless you already know where it is. Try to infer its location
+ * from the device tree.
+ */
+
+ ccsr = -1;
+ for (name = soc_name_guesses; *name != NULL && ccsr == -1; name++)
+ ccsr = OF_finddevice(*name);
+ if (ccsr == -1) {
+ char type[64];
+
+ /* That didn't work. Search for devices of type "soc" */
+ child = OF_child(OF_peer(0));
+ for (OF_child(child); child != 0; child = OF_peer(child)) {
+ if (OF_getprop(child, "device_type", type, sizeof(type))
+ <= 0)
+ continue;
+
+ if (strcmp(type, "soc") == 0) {
+ ccsr = child;
+ break;
+ }
+ }
+ }
+
+ if (ccsr == -1)
+ panic("Could not locate CCSR window!");
+
+ OF_getprop(ccsr, "#size-cells", &scells, sizeof(scells));
+ OF_getprop(ccsr, "#address-cells", &acells, sizeof(acells));
+ OF_searchprop(OF_parent(ccsr), "#address-cells", &pacells,
+ sizeof(pacells));
+ OF_getprop(ccsr, "ranges", ranges, sizeof(ranges));
+ ccsrbar = ccsrsize = 0;
+ for (i = acells; i < acells + pacells; i++) {
+ ccsrbar <<= 32;
+ ccsrbar |= ranges[i];
+ }
+ for (i = acells + pacells; i < acells + pacells + scells; i++) {
+ ccsrsize <<= 32;
+ ccsrsize |= ranges[i];
+ }
+ ccsrbar_va = pmap_early_io_map(ccsrbar, ccsrsize);
+
+ /*
* Clear local access windows. Skip DRAM entries, so we don't shoot
* ourselves in the foot.
*/