2007-11-29 06:15:30 +00:00
|
|
|
/*
|
2010-12-30 18:09:53 +00:00
|
|
|
* Copyright 2007-2011 Freescale Semiconductor, Inc.
|
2007-11-29 06:15:30 +00:00
|
|
|
*
|
|
|
|
* (C) Copyright 2000
|
|
|
|
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
|
|
|
*
|
|
|
|
* See file CREDITS for list of people who contributed to this
|
|
|
|
* project.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <common.h>
|
|
|
|
#include <libfdt.h>
|
|
|
|
#include <fdt_support.h>
|
2008-05-29 16:22:06 +00:00
|
|
|
#include <asm/processor.h>
|
2009-09-22 07:18:27 +00:00
|
|
|
#include <linux/ctype.h>
|
2009-03-19 08:40:08 +00:00
|
|
|
#include <asm/io.h>
|
2009-09-10 08:02:13 +00:00
|
|
|
#include <asm/fsl_portals.h>
|
2009-09-02 05:55:08 +00:00
|
|
|
#ifdef CONFIG_FSL_ESDHC
|
|
|
|
#include <fsl_esdhc.h>
|
|
|
|
#endif
|
2011-05-03 18:35:11 +00:00
|
|
|
#include "../../../../drivers/qe/qe.h" /* For struct qe_firmware */
|
2007-11-29 06:15:30 +00:00
|
|
|
|
mpc8[56]xx: Put localbus clock in device tree
Export the localbus frequency in the device tree, the same way the CPU, TB,
CCB, and various other frequencies are exported in their respective device
tree nodes.
Some localbus devices need this information to be programed correctly, so
it makes sense to export it along with the other frequencies.
Unfortunately, when someone wrote the localbus dts bindings, they didn't
bother to define what the "compatible" property should be. So it seems no
one was quite sure what to put in their dts files.
Based on current existing dts files in the kernel source, I've used
"fsl,pq3-localbus" and "fsl,elbc" for MPC85xx, which are used by almost all
of the 85xx devices, and are looked for by the Linux code. The eLBC is
apparently not entirely backward compatible with the pq3 LBC and so eLBC
equipped platforms like 8572 won't use pq3-localbus.
For MPC86xx, I've used "fsl,elbc" which is used by some of the 86xx systems
and is also looked for by the Linux code. On MPC8641, I've also used
"fsl,mpc8641-localbus" as it is also commonly used in dts files, some of
which don't use "fsl,elbc" or any other acceptable name to match on.
Signed-off-by: Trent Piepho <tpiepho@freescale.com>
Acked-by: Kumar Gala <galak@kernel.crashing.org>
Acked-by: Jon Loeliger <jdl@freescale.com>
2008-12-03 23:16:38 +00:00
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
|
2008-01-17 14:25:45 +00:00
|
|
|
extern void ft_qe_setup(void *blob);
|
2009-09-02 14:10:36 +00:00
|
|
|
extern void ft_fixup_num_cores(void *blob);
|
2010-12-30 18:09:53 +00:00
|
|
|
extern void ft_srio_setup(void *blob);
|
2008-06-16 20:55:53 +00:00
|
|
|
|
2008-01-17 22:48:33 +00:00
|
|
|
#ifdef CONFIG_MP
|
|
|
|
#include "mp.h"
|
|
|
|
|
|
|
|
void ft_fixup_cpu(void *blob, u64 memory_limit)
|
|
|
|
{
|
|
|
|
int off;
|
2009-10-23 20:55:47 +00:00
|
|
|
ulong spin_tbl_addr = get_spin_phys_addr();
|
2009-04-01 04:11:05 +00:00
|
|
|
u32 bootpg = determine_mp_bootpg();
|
|
|
|
u32 id = get_my_id();
|
2010-09-30 17:22:16 +00:00
|
|
|
const char *enable_method;
|
2008-01-17 22:48:33 +00:00
|
|
|
|
|
|
|
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
|
|
|
|
while (off != -FDT_ERR_NOTFOUND) {
|
|
|
|
u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0);
|
|
|
|
|
|
|
|
if (reg) {
|
2010-08-19 18:57:48 +00:00
|
|
|
u64 val = *reg * SIZE_BOOT_ENTRY + spin_tbl_addr;
|
|
|
|
val = cpu_to_fdt32(val);
|
2008-01-17 22:48:33 +00:00
|
|
|
if (*reg == id) {
|
2010-08-19 18:57:48 +00:00
|
|
|
fdt_setprop_string(blob, off, "status",
|
|
|
|
"okay");
|
2008-01-17 22:48:33 +00:00
|
|
|
} else {
|
|
|
|
fdt_setprop_string(blob, off, "status",
|
|
|
|
"disabled");
|
|
|
|
}
|
2010-09-30 17:22:16 +00:00
|
|
|
|
|
|
|
if (hold_cores_in_reset(0)) {
|
|
|
|
#ifdef CONFIG_FSL_CORENET
|
|
|
|
/* Cores held in reset, use BRR to release */
|
|
|
|
enable_method = "fsl,brr-holdoff";
|
|
|
|
#else
|
|
|
|
/* Cores held in reset, use EEBPCR to release */
|
|
|
|
enable_method = "fsl,eebpcr-holdoff";
|
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
/* Cores out of reset and in a spin-loop */
|
|
|
|
enable_method = "spin-table";
|
|
|
|
|
|
|
|
fdt_setprop(blob, off, "cpu-release-addr",
|
|
|
|
&val, sizeof(val));
|
|
|
|
}
|
|
|
|
|
2010-08-19 18:57:48 +00:00
|
|
|
fdt_setprop_string(blob, off, "enable-method",
|
2010-09-30 17:22:16 +00:00
|
|
|
enable_method);
|
2008-01-17 22:48:33 +00:00
|
|
|
} else {
|
|
|
|
printf ("cpu NULL\n");
|
|
|
|
}
|
|
|
|
off = fdt_node_offset_by_prop_value(blob, off,
|
|
|
|
"device_type", "cpu", 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Reserve the boot page so OSes dont use it */
|
|
|
|
if ((u64)bootpg < memory_limit) {
|
|
|
|
off = fdt_add_mem_rsv(blob, bootpg, (u64)4096);
|
|
|
|
if (off < 0)
|
|
|
|
printf("%s: %s\n", __FUNCTION__, fdt_strerror(off));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2008-01-17 14:25:45 +00:00
|
|
|
|
2009-03-19 08:40:08 +00:00
|
|
|
#ifdef CONFIG_SYS_FSL_CPC
|
|
|
|
static inline void ft_fixup_l3cache(void *blob, int off)
|
|
|
|
{
|
|
|
|
u32 line_size, num_ways, size, num_sets;
|
|
|
|
cpc_corenet_t *cpc = (void *)CONFIG_SYS_FSL_CPC_ADDR;
|
|
|
|
u32 cfg0 = in_be32(&cpc->cpccfg0);
|
|
|
|
|
|
|
|
size = CPC_CFG0_SZ_K(cfg0) * 1024 * CONFIG_SYS_NUM_CPC;
|
|
|
|
num_ways = CPC_CFG0_NUM_WAYS(cfg0);
|
|
|
|
line_size = CPC_CFG0_LINE_SZ(cfg0);
|
|
|
|
num_sets = size / (line_size * num_ways);
|
|
|
|
|
|
|
|
fdt_setprop(blob, off, "cache-unified", NULL, 0);
|
|
|
|
fdt_setprop_cell(blob, off, "cache-block-size", line_size);
|
|
|
|
fdt_setprop_cell(blob, off, "cache-size", size);
|
|
|
|
fdt_setprop_cell(blob, off, "cache-sets", num_sets);
|
|
|
|
fdt_setprop_cell(blob, off, "cache-level", 3);
|
|
|
|
#ifdef CONFIG_SYS_CACHE_STASHING
|
|
|
|
fdt_setprop_cell(blob, off, "cache-stash-id", 1);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#else
|
2009-03-19 14:16:10 +00:00
|
|
|
#define ft_fixup_l3cache(x, y)
|
2009-03-19 08:40:08 +00:00
|
|
|
#endif
|
2009-03-19 14:16:10 +00:00
|
|
|
|
|
|
|
#if defined(CONFIG_L2_CACHE)
|
2008-05-29 16:22:06 +00:00
|
|
|
/* return size in kilobytes */
|
|
|
|
static inline u32 l2cache_size(void)
|
|
|
|
{
|
2008-10-16 13:01:15 +00:00
|
|
|
volatile ccsr_l2cache_t *l2cache = (void *)CONFIG_SYS_MPC85xx_L2_ADDR;
|
2008-05-29 16:22:06 +00:00
|
|
|
volatile u32 l2siz_field = (l2cache->l2ctl >> 28) & 0x3;
|
|
|
|
u32 ver = SVR_SOC_VER(get_svr());
|
|
|
|
|
|
|
|
switch (l2siz_field) {
|
|
|
|
case 0x0:
|
|
|
|
break;
|
|
|
|
case 0x1:
|
|
|
|
if (ver == SVR_8540 || ver == SVR_8560 ||
|
|
|
|
ver == SVR_8541 || ver == SVR_8541_E ||
|
|
|
|
ver == SVR_8555 || ver == SVR_8555_E)
|
|
|
|
return 128;
|
|
|
|
else
|
|
|
|
return 256;
|
|
|
|
break;
|
|
|
|
case 0x2:
|
|
|
|
if (ver == SVR_8540 || ver == SVR_8560 ||
|
|
|
|
ver == SVR_8541 || ver == SVR_8541_E ||
|
|
|
|
ver == SVR_8555 || ver == SVR_8555_E)
|
|
|
|
return 256;
|
|
|
|
else
|
|
|
|
return 512;
|
|
|
|
break;
|
|
|
|
case 0x3:
|
|
|
|
return 1024;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void ft_fixup_l2cache(void *blob)
|
|
|
|
{
|
|
|
|
int len, off;
|
|
|
|
u32 *ph;
|
|
|
|
struct cpu_type *cpu = identify_cpu(SVR_SOC_VER(get_svr()));
|
|
|
|
|
|
|
|
const u32 line_size = 32;
|
|
|
|
const u32 num_ways = 8;
|
|
|
|
const u32 size = l2cache_size() * 1024;
|
|
|
|
const u32 num_sets = size / (line_size * num_ways);
|
|
|
|
|
|
|
|
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
|
|
|
|
if (off < 0) {
|
|
|
|
debug("no cpu node fount\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ph = (u32 *)fdt_getprop(blob, off, "next-level-cache", 0);
|
|
|
|
|
|
|
|
if (ph == NULL) {
|
|
|
|
debug("no next-level-cache property\n");
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
|
|
|
off = fdt_node_offset_by_phandle(blob, *ph);
|
|
|
|
if (off < 0) {
|
|
|
|
printf("%s: %s\n", __func__, fdt_strerror(off));
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cpu) {
|
2011-04-29 23:08:44 +00:00
|
|
|
char buf[40];
|
|
|
|
|
|
|
|
if (isdigit(cpu->name[0])) {
|
|
|
|
/* MPCxxxx, where xxxx == 4-digit number */
|
|
|
|
len = sprintf(buf, "fsl,mpc%s-l2-cache-controller",
|
|
|
|
cpu->name) + 1;
|
|
|
|
} else {
|
|
|
|
/* Pxxxx or Txxxx, where xxxx == 4-digit number */
|
|
|
|
len = sprintf(buf, "fsl,%c%s-l2-cache-controller",
|
|
|
|
tolower(cpu->name[0]), cpu->name + 1) + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* append "cache" after the NULL character that the previous
|
|
|
|
* sprintf wrote. This is how a device tree stores multiple
|
|
|
|
* strings in a property.
|
|
|
|
*/
|
|
|
|
len += sprintf(buf + len, "cache") + 1;
|
2009-09-22 07:18:27 +00:00
|
|
|
|
2011-04-29 23:08:44 +00:00
|
|
|
fdt_setprop(blob, off, "compatible", buf, len);
|
2008-05-29 16:22:06 +00:00
|
|
|
}
|
|
|
|
fdt_setprop(blob, off, "cache-unified", NULL, 0);
|
|
|
|
fdt_setprop_cell(blob, off, "cache-block-size", line_size);
|
|
|
|
fdt_setprop_cell(blob, off, "cache-size", size);
|
|
|
|
fdt_setprop_cell(blob, off, "cache-sets", num_sets);
|
|
|
|
fdt_setprop_cell(blob, off, "cache-level", 2);
|
2009-03-19 14:16:10 +00:00
|
|
|
|
|
|
|
/* we dont bother w/L3 since no platform of this type has one */
|
|
|
|
}
|
|
|
|
#elif defined(CONFIG_BACKSIDE_L2_CACHE)
|
|
|
|
static inline void ft_fixup_l2cache(void *blob)
|
|
|
|
{
|
|
|
|
int off, l2_off, l3_off = -1;
|
|
|
|
u32 *ph;
|
|
|
|
u32 l2cfg0 = mfspr(SPRN_L2CFG0);
|
|
|
|
u32 size, line_size, num_ways, num_sets;
|
2011-07-21 05:20:21 +00:00
|
|
|
int has_l2 = 1;
|
|
|
|
|
|
|
|
/* P2040/P2040E has no L2, so dont set any L2 props */
|
|
|
|
if ((SVR_SOC_VER(get_svr()) == SVR_P2040) ||
|
|
|
|
(SVR_SOC_VER(get_svr()) == SVR_P2040_E))
|
|
|
|
has_l2 = 0;
|
2009-03-19 14:16:10 +00:00
|
|
|
|
|
|
|
size = (l2cfg0 & 0x3fff) * 64 * 1024;
|
|
|
|
num_ways = ((l2cfg0 >> 14) & 0x1f) + 1;
|
|
|
|
line_size = (((l2cfg0 >> 23) & 0x3) + 1) * 32;
|
|
|
|
num_sets = size / (line_size * num_ways);
|
|
|
|
|
|
|
|
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
|
|
|
|
|
|
|
|
while (off != -FDT_ERR_NOTFOUND) {
|
|
|
|
ph = (u32 *)fdt_getprop(blob, off, "next-level-cache", 0);
|
|
|
|
|
|
|
|
if (ph == NULL) {
|
|
|
|
debug("no next-level-cache property\n");
|
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
|
|
|
|
l2_off = fdt_node_offset_by_phandle(blob, *ph);
|
|
|
|
if (l2_off < 0) {
|
|
|
|
printf("%s: %s\n", __func__, fdt_strerror(off));
|
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
|
2011-07-21 05:20:21 +00:00
|
|
|
if (has_l2) {
|
2009-03-19 07:53:01 +00:00
|
|
|
#ifdef CONFIG_SYS_CACHE_STASHING
|
|
|
|
u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0);
|
|
|
|
if (reg)
|
|
|
|
fdt_setprop_cell(blob, l2_off, "cache-stash-id",
|
|
|
|
(*reg * 2) + 32 + 1);
|
|
|
|
#endif
|
|
|
|
|
2011-07-21 05:20:21 +00:00
|
|
|
fdt_setprop(blob, l2_off, "cache-unified", NULL, 0);
|
|
|
|
fdt_setprop_cell(blob, l2_off, "cache-block-size",
|
|
|
|
line_size);
|
|
|
|
fdt_setprop_cell(blob, l2_off, "cache-size", size);
|
|
|
|
fdt_setprop_cell(blob, l2_off, "cache-sets", num_sets);
|
|
|
|
fdt_setprop_cell(blob, l2_off, "cache-level", 2);
|
|
|
|
fdt_setprop(blob, l2_off, "compatible", "cache", 6);
|
|
|
|
}
|
2009-03-19 14:16:10 +00:00
|
|
|
|
|
|
|
if (l3_off < 0) {
|
|
|
|
ph = (u32 *)fdt_getprop(blob, l2_off, "next-level-cache", 0);
|
|
|
|
|
|
|
|
if (ph == NULL) {
|
|
|
|
debug("no next-level-cache property\n");
|
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
l3_off = *ph;
|
|
|
|
}
|
|
|
|
next:
|
|
|
|
off = fdt_node_offset_by_prop_value(blob, off,
|
|
|
|
"device_type", "cpu", 4);
|
|
|
|
}
|
|
|
|
if (l3_off > 0) {
|
|
|
|
l3_off = fdt_node_offset_by_phandle(blob, l3_off);
|
|
|
|
if (l3_off < 0) {
|
|
|
|
printf("%s: %s\n", __func__, fdt_strerror(off));
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
ft_fixup_l3cache(blob, l3_off);
|
|
|
|
}
|
2008-05-29 16:22:06 +00:00
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define ft_fixup_l2cache(x)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static inline void ft_fixup_cache(void *blob)
|
|
|
|
{
|
|
|
|
int off;
|
|
|
|
|
|
|
|
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
|
|
|
|
|
|
|
|
while (off != -FDT_ERR_NOTFOUND) {
|
|
|
|
u32 l1cfg0 = mfspr(SPRN_L1CFG0);
|
|
|
|
u32 l1cfg1 = mfspr(SPRN_L1CFG1);
|
|
|
|
u32 isize, iline_size, inum_sets, inum_ways;
|
|
|
|
u32 dsize, dline_size, dnum_sets, dnum_ways;
|
|
|
|
|
|
|
|
/* d-side config */
|
|
|
|
dsize = (l1cfg0 & 0x7ff) * 1024;
|
|
|
|
dnum_ways = ((l1cfg0 >> 11) & 0xff) + 1;
|
|
|
|
dline_size = (((l1cfg0 >> 23) & 0x3) + 1) * 32;
|
|
|
|
dnum_sets = dsize / (dline_size * dnum_ways);
|
|
|
|
|
|
|
|
fdt_setprop_cell(blob, off, "d-cache-block-size", dline_size);
|
|
|
|
fdt_setprop_cell(blob, off, "d-cache-size", dsize);
|
|
|
|
fdt_setprop_cell(blob, off, "d-cache-sets", dnum_sets);
|
|
|
|
|
2009-03-19 07:53:01 +00:00
|
|
|
#ifdef CONFIG_SYS_CACHE_STASHING
|
|
|
|
{
|
|
|
|
u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0);
|
|
|
|
if (reg)
|
|
|
|
fdt_setprop_cell(blob, off, "cache-stash-id",
|
|
|
|
(*reg * 2) + 32 + 0);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-05-29 16:22:06 +00:00
|
|
|
/* i-side config */
|
|
|
|
isize = (l1cfg1 & 0x7ff) * 1024;
|
|
|
|
inum_ways = ((l1cfg1 >> 11) & 0xff) + 1;
|
|
|
|
iline_size = (((l1cfg1 >> 23) & 0x3) + 1) * 32;
|
|
|
|
inum_sets = isize / (iline_size * inum_ways);
|
|
|
|
|
|
|
|
fdt_setprop_cell(blob, off, "i-cache-block-size", iline_size);
|
|
|
|
fdt_setprop_cell(blob, off, "i-cache-size", isize);
|
|
|
|
fdt_setprop_cell(blob, off, "i-cache-sets", inum_sets);
|
|
|
|
|
|
|
|
off = fdt_node_offset_by_prop_value(blob, off,
|
|
|
|
"device_type", "cpu", 4);
|
|
|
|
}
|
|
|
|
|
|
|
|
ft_fixup_l2cache(blob);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-10-07 13:09:50 +00:00
|
|
|
void fdt_add_enet_stashing(void *fdt)
|
|
|
|
{
|
|
|
|
do_fixup_by_compat(fdt, "gianfar", "bd-stash", NULL, 0, 1);
|
|
|
|
|
|
|
|
do_fixup_by_compat_u32(fdt, "gianfar", "rx-stash-len", 96, 1);
|
|
|
|
|
|
|
|
do_fixup_by_compat_u32(fdt, "gianfar", "rx-stash-idx", 0, 1);
|
2011-01-25 09:14:57 +00:00
|
|
|
do_fixup_by_compat(fdt, "fsl,etsec2", "bd-stash", NULL, 0, 1);
|
|
|
|
do_fixup_by_compat_u32(fdt, "fsl,etsec2", "rx-stash-len", 96, 1);
|
|
|
|
do_fixup_by_compat_u32(fdt, "fsl,etsec2", "rx-stash-idx", 0, 1);
|
2008-10-07 13:09:50 +00:00
|
|
|
}
|
|
|
|
|
2009-03-19 07:46:28 +00:00
|
|
|
#if defined(CONFIG_SYS_DPAA_FMAN) || defined(CONFIG_SYS_DPAA_PME)
|
2010-07-10 11:38:16 +00:00
|
|
|
static void ft_fixup_clks(void *blob, const char *compat, u32 offset,
|
|
|
|
unsigned long freq)
|
2009-03-19 07:46:28 +00:00
|
|
|
{
|
2010-07-10 11:38:16 +00:00
|
|
|
phys_addr_t phys = offset + CONFIG_SYS_CCSRBAR_PHYS;
|
|
|
|
int off = fdt_node_offset_by_compat_reg(blob, compat, phys);
|
2009-03-19 07:46:28 +00:00
|
|
|
|
|
|
|
if (off >= 0) {
|
|
|
|
off = fdt_setprop_cell(blob, off, "clock-frequency", freq);
|
|
|
|
if (off > 0)
|
|
|
|
printf("WARNING enable to set clock-frequency "
|
2010-07-10 11:38:16 +00:00
|
|
|
"for %s: %s\n", compat, fdt_strerror(off));
|
2009-03-19 07:46:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ft_fixup_dpaa_clks(void *blob)
|
|
|
|
{
|
|
|
|
sys_info_t sysinfo;
|
|
|
|
|
|
|
|
get_sys_info(&sysinfo);
|
2010-07-10 11:38:16 +00:00
|
|
|
ft_fixup_clks(blob, "fsl,fman", CONFIG_SYS_FSL_FM1_OFFSET,
|
|
|
|
sysinfo.freqFMan[0]);
|
2009-03-19 07:46:28 +00:00
|
|
|
|
|
|
|
#if (CONFIG_SYS_NUM_FMAN == 2)
|
2010-07-10 11:38:16 +00:00
|
|
|
ft_fixup_clks(blob, "fsl,fman", CONFIG_SYS_FSL_FM2_OFFSET,
|
|
|
|
sysinfo.freqFMan[1]);
|
2009-03-19 07:46:28 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_SYS_DPAA_PME
|
2010-07-10 11:38:16 +00:00
|
|
|
do_fixup_by_compat_u32(blob, "fsl,pme",
|
|
|
|
"clock-frequency", sysinfo.freqPME, 1);
|
2009-03-19 07:46:28 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define ft_fixup_dpaa_clks(x)
|
|
|
|
#endif
|
|
|
|
|
2010-01-15 06:58:40 +00:00
|
|
|
#ifdef CONFIG_QE
|
|
|
|
static void ft_fixup_qe_snum(void *blob)
|
|
|
|
{
|
|
|
|
unsigned int svr;
|
|
|
|
|
|
|
|
svr = mfspr(SPRN_SVR);
|
|
|
|
if (SVR_SOC_VER(svr) == SVR_8569_E) {
|
|
|
|
if(IS_SVR_REV(svr, 1, 0))
|
|
|
|
do_fixup_by_compat_u32(blob, "fsl,qe",
|
|
|
|
"fsl,qe-num-snums", 46, 1);
|
|
|
|
else
|
|
|
|
do_fixup_by_compat_u32(blob, "fsl,qe",
|
|
|
|
"fsl,qe-num-snums", 76, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2011-05-03 18:35:11 +00:00
|
|
|
/**
|
|
|
|
* fdt_fixup_fman_firmware -- insert the Fman firmware into the device tree
|
|
|
|
*
|
|
|
|
* The binding for an Fman firmware node is documented in
|
|
|
|
* Documentation/powerpc/dts-bindings/fsl/dpaa/fman.txt. This node contains
|
|
|
|
* the actual Fman firmware binary data. The operating system is expected to
|
|
|
|
* be able to parse the binary data to determine any attributes it needs.
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_SYS_DPAA_FMAN
|
|
|
|
void fdt_fixup_fman_firmware(void *blob)
|
|
|
|
{
|
|
|
|
int rc, fmnode, fwnode = -1;
|
|
|
|
uint32_t phandle;
|
|
|
|
struct qe_firmware *fmanfw;
|
|
|
|
const struct qe_header *hdr;
|
|
|
|
unsigned int length;
|
|
|
|
uint32_t crc;
|
|
|
|
const char *p;
|
|
|
|
|
|
|
|
/* The first Fman we find will contain the actual firmware. */
|
|
|
|
fmnode = fdt_node_offset_by_compatible(blob, -1, "fsl,fman");
|
|
|
|
if (fmnode < 0)
|
|
|
|
/* Exit silently if there are no Fman devices */
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* If we already have a firmware node, then also exit silently. */
|
|
|
|
if (fdt_node_offset_by_compatible(blob, -1, "fsl,fman-firmware") > 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* If the environment variable is not set, then exit silently */
|
|
|
|
p = getenv("fman_ucode");
|
|
|
|
if (!p)
|
|
|
|
return;
|
|
|
|
|
|
|
|
fmanfw = (struct qe_firmware *) simple_strtoul(p, NULL, 0);
|
|
|
|
if (!fmanfw)
|
|
|
|
return;
|
|
|
|
|
|
|
|
hdr = &fmanfw->header;
|
|
|
|
length = be32_to_cpu(hdr->length);
|
|
|
|
|
|
|
|
/* Verify the firmware. */
|
|
|
|
if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
|
|
|
|
(hdr->magic[2] != 'F')) {
|
|
|
|
printf("Data at %p is not an Fman firmware\n", fmanfw);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (length > CONFIG_SYS_FMAN_FW_LENGTH) {
|
|
|
|
printf("Fman firmware at %p is too large (size=%u)\n",
|
|
|
|
fmanfw, length);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
length -= sizeof(u32); /* Subtract the size of the CRC */
|
|
|
|
crc = be32_to_cpu(*(u32 *)((void *)fmanfw + length));
|
|
|
|
if (crc != crc32_no_comp(0, (void *)fmanfw, length)) {
|
|
|
|
printf("Fman firmware at %p has invalid CRC\n", fmanfw);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Increase the size of the fdt to make room for the node. */
|
|
|
|
rc = fdt_increase_size(blob, fmanfw->header.length);
|
|
|
|
if (rc < 0) {
|
|
|
|
printf("Unable to make room for Fman firmware: %s\n",
|
|
|
|
fdt_strerror(rc));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create the firmware node. */
|
|
|
|
fwnode = fdt_add_subnode(blob, fmnode, "fman-firmware");
|
|
|
|
if (fwnode < 0) {
|
|
|
|
char s[64];
|
|
|
|
fdt_get_path(blob, fmnode, s, sizeof(s));
|
|
|
|
printf("Could not add firmware node to %s: %s\n", s,
|
|
|
|
fdt_strerror(fwnode));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
rc = fdt_setprop_string(blob, fwnode, "compatible", "fsl,fman-firmware");
|
|
|
|
if (rc < 0) {
|
|
|
|
char s[64];
|
|
|
|
fdt_get_path(blob, fwnode, s, sizeof(s));
|
|
|
|
printf("Could not add compatible property to node %s: %s\n", s,
|
|
|
|
fdt_strerror(rc));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
phandle = fdt_alloc_phandle(blob);
|
|
|
|
rc = fdt_setprop_cell(blob, fwnode, "linux,phandle", phandle);
|
|
|
|
if (rc < 0) {
|
|
|
|
char s[64];
|
|
|
|
fdt_get_path(blob, fwnode, s, sizeof(s));
|
|
|
|
printf("Could not add phandle property to node %s: %s\n", s,
|
|
|
|
fdt_strerror(rc));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
rc = fdt_setprop(blob, fwnode, "fsl,firmware", fmanfw, fmanfw->header.length);
|
|
|
|
if (rc < 0) {
|
|
|
|
char s[64];
|
|
|
|
fdt_get_path(blob, fwnode, s, sizeof(s));
|
|
|
|
printf("Could not add firmware property to node %s: %s\n", s,
|
|
|
|
fdt_strerror(rc));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find all other Fman nodes and point them to the firmware node. */
|
|
|
|
while ((fmnode = fdt_node_offset_by_compatible(blob, fmnode, "fsl,fman")) > 0) {
|
|
|
|
rc = fdt_setprop_cell(blob, fmnode, "fsl,firmware-phandle", phandle);
|
|
|
|
if (rc < 0) {
|
|
|
|
char s[64];
|
|
|
|
fdt_get_path(blob, fmnode, s, sizeof(s));
|
|
|
|
printf("Could not add pointer property to node %s: %s\n",
|
|
|
|
s, fdt_strerror(rc));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#define fdt_fixup_fman_firmware(x)
|
|
|
|
#endif
|
|
|
|
|
2007-11-29 06:15:30 +00:00
|
|
|
void ft_cpu_setup(void *blob, bd_t *bd)
|
|
|
|
{
|
2009-01-15 16:58:35 +00:00
|
|
|
int off;
|
|
|
|
int val;
|
|
|
|
sys_info_t sysinfo;
|
|
|
|
|
2008-06-16 20:55:53 +00:00
|
|
|
/* delete crypto node if not on an E-processor */
|
|
|
|
if (!IS_E_PROCESSOR(get_svr()))
|
|
|
|
fdt_fixup_crypto_node(blob, 0);
|
|
|
|
|
2008-08-19 20:41:18 +00:00
|
|
|
fdt_fixup_ethernet(blob);
|
2008-10-07 13:09:50 +00:00
|
|
|
|
|
|
|
fdt_add_enet_stashing(blob);
|
2007-11-29 06:15:30 +00:00
|
|
|
|
|
|
|
do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
|
2009-09-17 06:52:37 +00:00
|
|
|
"timebase-frequency", get_tbclk(), 1);
|
2007-11-29 06:15:30 +00:00
|
|
|
do_fixup_by_prop_u32(blob, "device_type", "cpu", 4,
|
|
|
|
"bus-frequency", bd->bi_busfreq, 1);
|
2009-01-15 16:58:35 +00:00
|
|
|
get_sys_info(&sysinfo);
|
|
|
|
off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
|
|
|
|
while (off != -FDT_ERR_NOTFOUND) {
|
|
|
|
u32 *reg = (u32 *)fdt_getprop(blob, off, "reg", 0);
|
|
|
|
val = cpu_to_fdt32(sysinfo.freqProcessor[*reg]);
|
|
|
|
fdt_setprop(blob, off, "clock-frequency", &val, 4);
|
|
|
|
off = fdt_node_offset_by_prop_value(blob, off, "device_type",
|
|
|
|
"cpu", 4);
|
|
|
|
}
|
2007-11-29 06:15:30 +00:00
|
|
|
do_fixup_by_prop_u32(blob, "device_type", "soc", 4,
|
|
|
|
"bus-frequency", bd->bi_busfreq, 1);
|
mpc8[56]xx: Put localbus clock in device tree
Export the localbus frequency in the device tree, the same way the CPU, TB,
CCB, and various other frequencies are exported in their respective device
tree nodes.
Some localbus devices need this information to be programed correctly, so
it makes sense to export it along with the other frequencies.
Unfortunately, when someone wrote the localbus dts bindings, they didn't
bother to define what the "compatible" property should be. So it seems no
one was quite sure what to put in their dts files.
Based on current existing dts files in the kernel source, I've used
"fsl,pq3-localbus" and "fsl,elbc" for MPC85xx, which are used by almost all
of the 85xx devices, and are looked for by the Linux code. The eLBC is
apparently not entirely backward compatible with the pq3 LBC and so eLBC
equipped platforms like 8572 won't use pq3-localbus.
For MPC86xx, I've used "fsl,elbc" which is used by some of the 86xx systems
and is also looked for by the Linux code. On MPC8641, I've also used
"fsl,mpc8641-localbus" as it is also commonly used in dts files, some of
which don't use "fsl,elbc" or any other acceptable name to match on.
Signed-off-by: Trent Piepho <tpiepho@freescale.com>
Acked-by: Kumar Gala <galak@kernel.crashing.org>
Acked-by: Jon Loeliger <jdl@freescale.com>
2008-12-03 23:16:38 +00:00
|
|
|
|
|
|
|
do_fixup_by_compat_u32(blob, "fsl,pq3-localbus",
|
|
|
|
"bus-frequency", gd->lbc_clk, 1);
|
|
|
|
do_fixup_by_compat_u32(blob, "fsl,elbc",
|
|
|
|
"bus-frequency", gd->lbc_clk, 1);
|
2007-11-29 06:15:30 +00:00
|
|
|
#ifdef CONFIG_QE
|
2008-01-17 14:25:45 +00:00
|
|
|
ft_qe_setup(blob);
|
2010-01-15 06:58:40 +00:00
|
|
|
ft_fixup_qe_snum(blob);
|
2007-11-29 06:15:30 +00:00
|
|
|
#endif
|
|
|
|
|
2011-05-03 18:35:11 +00:00
|
|
|
fdt_fixup_fman_firmware(blob);
|
|
|
|
|
2008-10-16 13:01:15 +00:00
|
|
|
#ifdef CONFIG_SYS_NS16550
|
2007-11-29 06:15:30 +00:00
|
|
|
do_fixup_by_compat_u32(blob, "ns16550",
|
2008-10-16 13:01:15 +00:00
|
|
|
"clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
|
2007-11-29 06:15:30 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef CONFIG_CPM2
|
|
|
|
do_fixup_by_compat_u32(blob, "fsl,cpm2-scc-uart",
|
|
|
|
"current-speed", bd->bi_baudrate, 1);
|
|
|
|
|
|
|
|
do_fixup_by_compat_u32(blob, "fsl,cpm2-brg",
|
|
|
|
"clock-frequency", bd->bi_brgfreq, 1);
|
|
|
|
#endif
|
|
|
|
|
2010-07-10 11:55:41 +00:00
|
|
|
#ifdef CONFIG_FSL_CORENET
|
|
|
|
do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-1.0",
|
|
|
|
"clock-frequency", CONFIG_SYS_CLK_FREQ, 1);
|
|
|
|
#endif
|
|
|
|
|
2007-11-29 06:15:30 +00:00
|
|
|
fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize);
|
2008-01-17 22:48:33 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_MP
|
|
|
|
ft_fixup_cpu(blob, (u64)bd->bi_memstart + (u64)bd->bi_memsize);
|
2009-09-02 14:10:36 +00:00
|
|
|
ft_fixup_num_cores(blob);
|
2010-06-10 03:33:53 +00:00
|
|
|
#endif
|
2008-05-29 16:22:06 +00:00
|
|
|
|
|
|
|
ft_fixup_cache(blob);
|
2009-09-02 05:55:08 +00:00
|
|
|
|
|
|
|
#if defined(CONFIG_FSL_ESDHC)
|
|
|
|
fdt_fixup_esdhc(blob, bd);
|
|
|
|
#endif
|
2009-03-19 07:46:28 +00:00
|
|
|
|
|
|
|
ft_fixup_dpaa_clks(blob);
|
2009-09-10 08:02:13 +00:00
|
|
|
|
|
|
|
#if defined(CONFIG_SYS_BMAN_MEM_PHYS)
|
|
|
|
fdt_portal(blob, "fsl,bman-portal", "bman-portals",
|
|
|
|
(u64)CONFIG_SYS_BMAN_MEM_PHYS,
|
|
|
|
CONFIG_SYS_BMAN_MEM_SIZE);
|
2011-03-01 14:30:07 +00:00
|
|
|
fdt_fixup_bportals(blob);
|
2009-09-10 08:02:13 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(CONFIG_SYS_QMAN_MEM_PHYS)
|
|
|
|
fdt_portal(blob, "fsl,qman-portal", "qman-portals",
|
|
|
|
(u64)CONFIG_SYS_QMAN_MEM_PHYS,
|
|
|
|
CONFIG_SYS_QMAN_MEM_SIZE);
|
|
|
|
|
|
|
|
fdt_fixup_qportals(blob);
|
|
|
|
#endif
|
2010-12-30 18:09:53 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_SYS_SRIO
|
|
|
|
ft_srio_setup(blob);
|
|
|
|
#endif
|
2011-02-02 14:44:28 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* system-clock = CCB clock/2
|
|
|
|
* Here gd->bus_clk = CCB clock
|
|
|
|
* We are using the system clock as 1588 Timer reference
|
|
|
|
* clock source select
|
|
|
|
*/
|
|
|
|
do_fixup_by_compat_u32(blob, "fsl,gianfar-ptp-timer",
|
|
|
|
"timer-frequency", gd->bus_clk/2, 1);
|
2007-11-29 06:15:30 +00:00
|
|
|
}
|