Exemplo n.º 1
0
void ft_fixup_num_cores(void *blob) {
	int off, num_cores, del_cores;

	del_cores = 0;
	num_cores = cpu_numcores();

	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);
		u32 phys_cpu_id = thread_to_core(*reg);

		if (!is_core_valid(phys_cpu_id) || is_core_disabled(phys_cpu_id)) {
			int ph = fdt_get_phandle(blob, off);

			/* Delete the cpu node once there are no cpu handles */
			if (-FDT_ERR_NOTFOUND == ft_del_cpuhandle(blob, ph)) {
				fdt_del_node(blob, off);
				del_cores++;
			}
			/* either we deleted some cpu handles or the cpu node
			 * so we reset the offset back to the start since we
			 * can't trust the offsets anymore
			 */
			off = -1;
		}
		off = fdt_node_offset_by_prop_value(blob, off,
				"device_type", "cpu", 4);
	}
	debug ("%x core system found\n", num_cores);
	debug ("deleted %d extra core entry entries from device tree\n",
								del_cores);
}
Exemplo n.º 2
0
void ft_fixup_num_cores(void *blob) {
	int off, num_cores, del_cores;

	del_cores = 0;
	num_cores = cpu_numcores();

	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 we find a cpu node outside of what we expect delete it
		 * and reset the offset back to the start since we can't
		 * trust the offsets anymore
		 */
		if (*reg > num_cores-1) {
			fdt_del_node(blob, off);
			del_cores++;
			off = -1;
		}
		off = fdt_node_offset_by_prop_value(blob, off,
				"device_type", "cpu", 4);
	}
	debug ("%x core system found\n", num_cores);
	debug ("deleted %d extra core entry entries from device tree\n",
								del_cores);
}
Exemplo n.º 3
0
static void fdt_fixup_srio_liodn(void *blob, struct srio_liodn_id_table *tbl)
{
    int i, srio_off;

    /* search for srio node, if doesn't exist just return - nothing todo */
    srio_off = fdt_node_offset_by_compatible(blob, -1, "fsl,srio");
    if (srio_off < 0)
        return ;

    for (i = 0; i < srio_liodn_tbl_sz; i++) {
        int off, portid = tbl[i].portid;

        off = fdt_node_offset_by_prop_value(blob, srio_off,
                                            "cell-index", &portid, 4);
        if (off >= 0) {
            off = fdt_setprop(blob, off, "fsl,liodn",
                              &tbl[i].id[0],
                              sizeof(u32) * tbl[i].num_ids);
            if (off > 0)
                printf("WARNING unable to set fsl,liodn for "
                       "fsl,srio port %d: %s\n",
                       portid, fdt_strerror(off));
        } else {
            debug("WARNING: couldn't set fsl,liodn for srio: %s.\n",
                  fdt_strerror(off));
        }
    }
}
Exemplo n.º 4
0
status_t
of_get_next_device(int *_cookie, int root, const char *type, char *path,
                   size_t pathSize)
{
    int next;
    int err;

    int startoffset = *_cookie ? *_cookie : -1;

    // iterate by property value
    next = fdt_node_offset_by_prop_value(gFDT, startoffset, "device_type",
                                         type, strlen(type) + 1);
    TRACE(("of_get_next_device(c:%d, %d, '%s', %p, %zd) soffset=%d next=%d\n",
           *_cookie, root, type, path, pathSize, startoffset, fdt2of(next)));
    if (next < 0)
        return B_ENTRY_NOT_FOUND;

    // make sure root is the parent
    int parent = next;
    while (root && parent) {
        parent = fdt_parent_offset(gFDT, parent);
        if (parent == root)
            break;
        if (parent <= 0)
            return B_ENTRY_NOT_FOUND;
    }

    *_cookie = next;

    err = fdt_get_path(gFDT, next, path, pathSize);
    if (err < 0)
        return B_ERROR;

    return B_OK;
}
Exemplo n.º 5
0
int dram_init(void)
{
#ifdef CONFIG_OF_CONTROL
	int node;
	fdt_addr_t addr;
	fdt_size_t size;
	const void *blob = gd->fdt_blob;

	node = fdt_node_offset_by_prop_value(blob, -1, "device_type",
					     "memory", 7);
	if (node == -FDT_ERR_NOTFOUND) {
		debug("ZYNQ DRAM: Can't get memory node\n");
		return -1;
	}
	addr = fdtdec_get_addr_size(blob, node, "reg", &size);
	if (addr == FDT_ADDR_T_NONE || size == 0) {
		debug("ZYNQ DRAM: Can't get base address or size\n");
		return -1;
	}
	gd->ram_size = size;
#else
	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
#endif
	zynq_ddrc_init();

	return 0;
}
Exemplo n.º 6
0
int dram_init(void)
{
	int node;
	fdt_addr_t addr;
	fdt_size_t size;
	const void *blob = gd->fdt_blob;

	node = fdt_node_offset_by_prop_value(blob, -1, "device_type",
					     "memory", 7);
	if (node == -FDT_ERR_NOTFOUND) {
		debug("DRAM: Can't get memory node\n");
		return 1;
	}
	addr = fdtdec_get_addr_size(blob, node, "reg", &size);
	if (addr == FDT_ADDR_T_NONE || size == 0) {
		debug("DRAM: Can't get base address or size\n");
		return 1;
	}
	ram_base = addr;

	gd->ram_top = addr; /* In setup_dest_addr() is done +ram_size */
	gd->ram_size = size;

	return 0;
};
Exemplo n.º 7
0
void
fixup_cpubusfreqs(unsigned long cpufreq, unsigned long busfreq)
{
	int lo, o = 0, o2, maxo = 0, depth;
	const uint32_t zero = 0;

	/* We want to modify every subnode of /cpus */
	o = fdt_path_offset(fdtp, "/cpus");
	if (o < 0)
		return;

	/* maxo should contain offset of node next to /cpus */
	depth = 0;
	maxo = o;
	while (depth != -1)
		maxo = fdt_next_node(fdtp, maxo, &depth);

	/* Find CPU frequency properties */
	o = fdt_node_offset_by_prop_value(fdtp, o, "clock-frequency",
	    &zero, sizeof(uint32_t));

	o2 = fdt_node_offset_by_prop_value(fdtp, o, "bus-frequency", &zero,
	    sizeof(uint32_t));

	lo = MIN(o, o2);

	while (o != -FDT_ERR_NOTFOUND && o2 != -FDT_ERR_NOTFOUND) {

		o = fdt_node_offset_by_prop_value(fdtp, lo,
		    "clock-frequency", &zero, sizeof(uint32_t));

		o2 = fdt_node_offset_by_prop_value(fdtp, lo, "bus-frequency",
		    &zero, sizeof(uint32_t));

		/* We're only interested in /cpus subnode(s) */
		if (lo > maxo)
			break;

		fdt_setprop_inplace_cell(fdtp, lo, "clock-frequency",
		    (uint32_t)cpufreq);

		fdt_setprop_inplace_cell(fdtp, lo, "bus-frequency",
		    (uint32_t)busfreq);

		lo = MIN(o, o2);
	}
}
Exemplo n.º 8
0
int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)
{
	if ((phandle == 0) || (phandle == -1))
		return -FDT_ERR_BADPHANDLE;
	phandle = cpu_to_fdt32(phandle);
	return fdt_node_offset_by_prop_value(fdt, -1, "linux,phandle",
					     &phandle, sizeof(phandle));
}
Exemplo n.º 9
0
int ft_board_setup(void *fdt, bd_t *bd)
{
	int offset, tmp, len;
	const struct fdt_property *prop;
	const char *cci_compatible = "arm,cci-400-ctrl-if";

#ifdef CONFIG_ARMV7_NONSEC
	if (!armv7_boot_nonsec())
		return 0;
#else
	return 0;
#endif
	/* Booting in nonsec mode, disable CCI access */
	offset = fdt_path_offset(fdt, "/cpus");
	if (offset < 0) {
		printf("couldn't find /cpus\n");
		return offset;
	}

	/* delete cci-control-port in each cpu node */
	for (tmp = fdt_first_subnode(fdt, offset); tmp >= 0;
	     tmp = fdt_next_subnode(fdt, tmp))
		fdt_delprop(fdt, tmp, "cci-control-port");

	/* disable all ace cci slave ports */
	offset = fdt_node_offset_by_prop_value(fdt, offset, "compatible",
					       cci_compatible, 20);
	while (offset > 0) {
		prop = fdt_get_property(fdt, offset, "interface-type",
					&len);
		if (!prop)
			continue;
		if (len < 4)
			continue;
		if (strcmp(prop->data, "ace"))
			continue;

		fdt_setprop_string(fdt, offset, "status", "disabled");

		offset = fdt_node_offset_by_prop_value(fdt, offset, "compatible",
						       cci_compatible, 20);
	}

	return 0;
}
Exemplo n.º 10
0
static int ft_del_cpuhandle(void *blob, int cpuhandle)
{
	int off, ret = -FDT_ERR_NOTFOUND;

	/* if we find a match, we'll delete at it which point the offsets are
	 * invalid so we start over from the beginning
	 */
	off = fdt_node_offset_by_prop_value(blob, -1, "cpu-handle",
						&cpuhandle, 4);
	while (off != -FDT_ERR_NOTFOUND) {
		fdt_delprop(blob, off, "cpu-handle");
		ret = 1;
		off = fdt_node_offset_by_prop_value(blob, -1, "cpu-handle",
				&cpuhandle, 4);
	}

	return ret;
}
static void *fdt_wrapper_find_node_by_prop_value(const void *prev,
						 const char *name,
						 const char *val,
						 int len)
{
	int offset = fdt_node_offset_by_prop_value(fdt, devp_offset_find(prev),
	                                           name, val, len);
	return offset_devp(offset);
}
Exemplo n.º 12
0
static int get_next_memory_node(const void *blob, int mem)
{
	do {
		mem = fdt_node_offset_by_prop_value(gd->fdt_blob, mem,
						    "device_type", "memory", 7);
	} while (!fdtdec_get_is_enabled(blob, mem));

	return mem;
}
Exemplo n.º 13
0
void ft_fixup_cpu(void *blob)
{
	int off;
	__maybe_unused u64 spin_tbl_addr = (u64)get_spin_tbl_addr();
	fdt32_t *reg;
	int addr_cells;
	u64 val, core_id;
	size_t *boot_code_size = &(__secondary_boot_code_size);

	off = fdt_path_offset(blob, "/cpus");
	if (off < 0) {
		puts("couldn't find /cpus node\n");
		return;
	}
	of_bus_default_count_cells(blob, off, &addr_cells, NULL);

	off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
	while (off != -FDT_ERR_NOTFOUND) {
		reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
		core_id = of_read_number(reg, addr_cells);
		if (reg) {
			if (core_id  == 0 || (is_core_online(core_id))) {
				val = spin_tbl_addr;
				val += id_to_core(core_id) *
				       SPIN_TABLE_ELEM_SIZE;
				val = cpu_to_fdt64(val);
				fdt_setprop_string(blob, off, "enable-method",
						   "spin-table");
				fdt_setprop(blob, off, "cpu-release-addr",
					    &val, sizeof(val));
			} else {
				debug("skipping offline core\n");
			}
		} else {
			puts("Warning: found cpu node without reg property\n");
		}
		off = fdt_node_offset_by_prop_value(blob, off, "device_type",
						    "cpu", 4);
	}

	fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code,
			*boot_code_size);
}
Exemplo n.º 14
0
static inline void ft_disable_srio_port(void *blob, int srio_off, int port)
{
	int off = fdt_node_offset_by_prop_value(blob, srio_off,
			"cell-index", &port, 4);
	if (off >= 0) {
		off = fdt_setprop_string(blob, off, "status", "disabled");
		if (off > 0)
			printf("WARNING unable to set status for fsl,srio "
				"port %d: %s\n", port, fdt_strerror(off));
	}
}
Exemplo n.º 15
0
void do_fixup_by_prop(void *fdt,
		      const char *pname, const void *pval, int plen,
		      const char *prop, const void *val, int len,
		      int create)
{
	int off;
#if defined(DEBUG)
	int i;
	debug("Updating property '%s' = ", prop);
	for (i = 0; i < len; i++)
		debug(" %.2x", *(u8*)(val+i));
	debug("\n");
#endif
	off = fdt_node_offset_by_prop_value(fdt, -1, pname, pval, plen);
	while (off != -FDT_ERR_NOTFOUND) {
		if (create || (fdt_get_property(fdt, off, prop, 0) != NULL))
			fdt_setprop(fdt, off, prop, val, len);
		off = fdt_node_offset_by_prop_value(fdt, off, pname, pval, plen);
	}
}
Exemplo n.º 16
0
/* Create CPU devices.  These are devices so that they can have interrupts.  */
static void create_cpus(const void *dt)
{
    int node = -1;

    while (1) {
        node = fdt_node_offset_by_prop_value(dt, node, "device_type",
                                             "cpu", 4);
        if (node < 0)
            break;
        create_from_node(cpu_device_class, dt, node);
    }
}
Exemplo n.º 17
0
/* Add RAM.  */
static void create_ram(const void *dt)
{
    int node = -1;
    const struct fdt_property *p;
    int len;
    uint32_t base;
    uint32_t size;
    uint32_t *data;
    ram_addr_t offset;

    while (1) {
        node = fdt_node_offset_by_prop_value(dt, node, "device_type",
                                             "memory", 7);
        if (node < 0)
            break;


        check_cells(dt, node, 1, 1);
        p = fdt_get_property(dt, node, "reg", &len);
        if (!p || (len % 8) != 0) {
            fprintf(stderr, "bad memory section %s\n",
                    fdt_get_name(dt, node, NULL));
            exit(1);
        }
        data = (uint32_t *)p->data;
        while (len) {
            base = fdt32_to_cpu(data[0]);
            size = fdt32_to_cpu(data[1]);
            data += 2;
            len -= 8;
            /* Ignore zero size regions.  */
            if (size == 0)
                continue;
            offset = qemu_ram_alloc(size);
            cpu_register_physical_memory(base, size, offset | IO_MEM_RAM);

            devtree_ram_map_size++;
            devtree_ram_map = qemu_realloc(devtree_ram_map,
                devtree_ram_map_size * sizeof(devtree_ram_region));
            devtree_ram_map[devtree_ram_map_size - 1].base = base;
            devtree_ram_map[devtree_ram_map_size - 1].size = size;
        }
    }
    /* FIXME: Merge and sort memory map entries.  */
    /* Technically there's no reason we have to have RAM.  However in
       practice it indicates a busted machine description.  */
    if (!devtree_ram_map) {
        fprintf(stderr, "No memory regions found\n");
        exit(1);
    }
}
Exemplo n.º 18
0
void ft_fixup_cpu(void *blob)
{
	int off;
	__maybe_unused u64 spin_tbl_addr = (u64)get_spin_tbl_addr();
	fdt32_t *reg;
	int addr_cells;
	u64 val, core_id;
	size_t *boot_code_size = &(__secondary_boot_code_size);
	u32 mask = cpu_pos_mask();
	int off_prev = -1;

	off = fdt_path_offset(blob, "/cpus");
	if (off < 0) {
		puts("couldn't find /cpus node\n");
		return;
	}

	fdt_support_default_count_cells(blob, off, &addr_cells, NULL);

	off = fdt_node_offset_by_prop_value(blob, off_prev, "device_type",
					    "cpu", 4);
	while (off != -FDT_ERR_NOTFOUND) {
		reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
		if (reg) {
			core_id = fdt_read_number(reg, addr_cells);
			if (!test_bit(id_to_core(core_id), &mask)) {
				fdt_del_node(blob, off);
				off = off_prev;
			}
		}
		off_prev = off;
		off = fdt_node_offset_by_prop_value(blob, off_prev,
						    "device_type", "cpu", 4);
	}

#if defined(CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT) && \
	defined(CONFIG_SEC_FIRMWARE_ARMV8_PSCI)
	int node;
	u32 psci_ver;

	/* Check the psci version to determine if the psci is supported */
	psci_ver = sec_firmware_support_psci_version();
	if (psci_ver == 0xffffffff) {
		/* remove psci DT node */
		node = fdt_path_offset(blob, "/psci");
		if (node >= 0)
			goto remove_psci_node;

		node = fdt_node_offset_by_compatible(blob, -1, "arm,psci");
		if (node >= 0)
			goto remove_psci_node;

		node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-0.2");
		if (node >= 0)
			goto remove_psci_node;

		node = fdt_node_offset_by_compatible(blob, -1, "arm,psci-1.0");
		if (node >= 0)
			goto remove_psci_node;

remove_psci_node:
		if (node >= 0)
			fdt_del_node(blob, node);
	} else {
		return;
	}
#endif
	off = fdt_path_offset(blob, "/cpus");
	if (off < 0) {
		puts("couldn't find /cpus node\n");
		return;
	}
	fdt_support_default_count_cells(blob, off, &addr_cells, NULL);

	off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
	while (off != -FDT_ERR_NOTFOUND) {
		reg = (fdt32_t *)fdt_getprop(blob, off, "reg", 0);
		if (reg) {
			core_id = fdt_read_number(reg, addr_cells);
			if (core_id  == 0 || (is_core_online(core_id))) {
				val = spin_tbl_addr;
				val += id_to_core(core_id) *
				       SPIN_TABLE_ELEM_SIZE;
				val = cpu_to_fdt64(val);
				fdt_setprop_string(blob, off, "enable-method",
						   "spin-table");
				fdt_setprop(blob, off, "cpu-release-addr",
					    &val, sizeof(val));
			} else {
				debug("skipping offline core\n");
			}
		} else {
			puts("Warning: found cpu node without reg property\n");
		}
		off = fdt_node_offset_by_prop_value(blob, off, "device_type",
						    "cpu", 4);
	}

	fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code,
			*boot_code_size);
#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
	efi_add_memory_map((uintptr_t)&secondary_boot_code,
			   ALIGN(*boot_code_size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
			   EFI_RESERVED_MEMORY_TYPE, false);
#endif
}
Exemplo n.º 19
0
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
		   unsigned long r6, unsigned long r7)
{
	const u32 *na, *ns, *reg, *timebase;
	u64 memsize64;
	int node, size, i;

	/*                            */
	if (fdt_check_header(_dtb_start) != 0)
		fatal("Invalid device tree blob\n");

	/*                                                    */
	node = fdt_path_offset(_dtb_start, "/");
	if (node < 0)
		fatal("Cannot find root node\n");
	na = fdt_getprop(_dtb_start, node, "#address-cells", &size);
	if (!na || (size != 4))
		fatal("Cannot find #address-cells property");
	ns = fdt_getprop(_dtb_start, node, "#size-cells", &size);
	if (!ns || (size != 4))
		fatal("Cannot find #size-cells property");

	/*                       */
	node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
					     "memory", sizeof("memory"));
	if (node < 0)
		fatal("Cannot find memory node\n");
	reg = fdt_getprop(_dtb_start, node, "reg", &size);
	if (size < (*na+*ns) * sizeof(u32))
		fatal("cannot get memory range\n");

	/*                                      */
	for (i = 0; i < *na; i++)
		if (*reg++ != 0)
			fatal("Memory range is not based at address 0\n");

	/*                                                               */
	memsize64 = 0;
	for (i = 0; i < *ns; i++)
		memsize64 = (memsize64 << 32) | *reg++;
	if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL)
		memsize64 = 0xffffffff;

	/*                             */
	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;

	/*                                                  */
	simple_alloc_init(_end, memsize64 - (unsigned long)_end, 32, 64);

	/*                                              */
	fdt_init(_dtb_start);

	if (platform_specific_init)
		platform_specific_init();

	serial_console_init();
}
Exemplo n.º 20
0
void ft_cpu_setup(void *blob, bd_t *bd)
{
	int off;
	int val;
	const char *sysclk_path;
	struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
	unsigned int svr;
	svr = in_be32(&gur->svr);

	unsigned long busclk = get_bus_freq(0);

	/* delete crypto node if not on an E-processor */
	if (!IS_E_PROCESSOR(svr))
		fdt_fixup_crypto_node(blob, 0);
#if CONFIG_SYS_FSL_SEC_COMPAT >= 4
	else {
		ccsr_sec_t __iomem *sec;

		sec = (void __iomem *)CONFIG_SYS_FSL_SEC_ADDR;
		fdt_fixup_crypto_node(blob, sec_in32(&sec->secvid_ms));
	}
#endif

	off = fdt_node_offset_by_prop_value(blob, -1, "device_type", "cpu", 4);
	while (off != -FDT_ERR_NOTFOUND) {
		val = gd->cpu_clk;
		fdt_setprop(blob, off, "clock-frequency", &val, 4);
		off = fdt_node_offset_by_prop_value(blob, off,
						    "device_type", "cpu", 4);
	}

	do_fixup_by_prop_u32(blob, "device_type", "soc",
			     4, "bus-frequency", busclk, 1);

	ft_fixup_enet_phy_connect_type(blob);

#ifdef CONFIG_SYS_NS16550
	do_fixup_by_compat_u32(blob, "fsl,16550-FIFO64",
			       "clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
#endif

	sysclk_path = fdt_get_alias(blob, "sysclk");
	if (sysclk_path)
		do_fixup_by_path_u32(blob, sysclk_path, "clock-frequency",
				     CONFIG_SYS_CLK_FREQ, 1);
	do_fixup_by_compat_u32(blob, "fsl,qoriq-sysclk-2.0",
			       "clock-frequency", CONFIG_SYS_CLK_FREQ, 1);

#if defined(CONFIG_DEEP_SLEEP) && defined(CONFIG_SD_BOOT)
#define UBOOT_HEAD_LEN	0x1000
	/*
	 * Reserved memory in SD boot deep sleep case.
	 * Second stage uboot binary and malloc space should be reserved.
	 * If the memory they occupied has not been reserved, then this
	 * space would be used by kernel and overwritten in uboot when
	 * deep sleep resume, which cause deep sleep failed.
	 * Since second uboot binary has a head, that space need to be
	 * reserved either(assuming its size is less than 0x1000).
	 */
	off = fdt_add_mem_rsv(blob, CONFIG_SYS_TEXT_BASE - UBOOT_HEAD_LEN,
			CONFIG_SYS_MONITOR_LEN + CONFIG_SYS_SPL_MALLOC_SIZE +
			UBOOT_HEAD_LEN);
	if (off < 0)
		printf("Failed to reserve memory for SD boot deep sleep: %s\n",
		       fdt_strerror(off));
#endif

#if defined(CONFIG_FSL_ESDHC)
	fdt_fixup_esdhc(blob, bd);
#endif

	/*
	 * platform bus clock = system bus clock/2
	 * Here busclk = system bus clock
	 * We are using the platform bus clock as 1588 Timer reference
	 * clock source select
	 */
	do_fixup_by_compat_u32(blob, "fsl, gianfar-ptp-timer",
			       "timer-frequency", busclk / 2, 1);

	/*
	 * clock-freq should change to clock-frequency and
	 * flexcan-v1.0 should change to p1010-flexcan respectively
	 * in the future.
	 */
	do_fixup_by_compat_u32(blob, "fsl, flexcan-v1.0",
			       "clock_freq", busclk / 2, 1);

	do_fixup_by_compat_u32(blob, "fsl, flexcan-v1.0",
			       "clock-frequency", busclk / 2, 1);

	do_fixup_by_compat_u32(blob, "fsl, ls1021a-flexcan",
			       "clock-frequency", busclk / 2, 1);

#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
	off = fdt_node_offset_by_compat_reg(blob, FSL_IFC_COMPAT,
					    CONFIG_SYS_IFC_ADDR);
	fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
#else
	off = fdt_node_offset_by_compat_reg(blob, FSL_QSPI_COMPAT,
					    QSPI0_BASE_ADDR);
	fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
	off = fdt_node_offset_by_compat_reg(blob, FSL_DSPI_COMPAT,
					    DSPI1_BASE_ADDR);
	fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
#endif
}
Exemplo n.º 21
0
void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
		   unsigned long r6, unsigned long r7)
{
	const u32 *na, *ns, *reg, *timebase;
	u64 memsize64;
	int node, size, i;
	void *the_dtb = _dtb_start;

	/* See if we were passed a DTB in the regs.  If so, use that instead */
	if (fdt_check_header((void *)r3) == 0)
		the_dtb = (void *)r3;

	/* Make sure FDT blob is sane */
	if (fdt_check_header(the_dtb) != 0)
		fatal("Invalid device tree blob\n");

	/* Find the #address-cells and #size-cells properties */
	node = fdt_path_offset(the_dtb, "/");
	if (node < 0)
		fatal("Cannot find root node\n");
	na = fdt_getprop(the_dtb, node, "#address-cells", &size);
	if (!na || (size != 4))
		fatal("Cannot find #address-cells property");
	ns = fdt_getprop(the_dtb, node, "#size-cells", &size);
	if (!ns || (size != 4))
		fatal("Cannot find #size-cells property");

	/* Find the memory range */
	node = fdt_node_offset_by_prop_value(the_dtb, -1, "device_type",
					     "memory", sizeof("memory"));
	if (node < 0)
		fatal("Cannot find memory node\n");
	reg = fdt_getprop(the_dtb, node, "reg", &size);
	if (size < (*na+*ns) * sizeof(u32))
		fatal("cannot get memory range\n");

	/* Only interested in memory based at 0 */
	for (i = 0; i < *na; i++)
		if (*reg++ != 0)
			fatal("Memory range is not based at address 0\n");

	/* get the memsize and trucate it to under 4G on 32 bit machines */
	memsize64 = 0;
	for (i = 0; i < *ns; i++)
		memsize64 = (memsize64 << 32) | *reg++;
	if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL)
		memsize64 = 0xffffffff;

	/* finally, setup the timebase */
	node = fdt_node_offset_by_prop_value(the_dtb, -1, "device_type",
					     "cpu", sizeof("cpu"));
	if (!node)
		fatal("Cannot find cpu node\n");
	timebase = fdt_getprop(the_dtb, node, "timebase-frequency", &size);
	if (timebase && (size == 4))
		timebase_period_ns = 1000000000 / *timebase;

	/* Now we have the memory size; initialize the heap */
	simple_alloc_init(_end, memsize64 - (unsigned long)_end, 32, 64);

	/* prepare the device tree and find the console */
	fdt_init(the_dtb);

	if (platform_specific_init)
		platform_specific_init();

	serial_console_init();
}
Exemplo n.º 22
0
static void process_boot_dtb(void *boot_dtb)
{
	const u32 *na, *ns, *reg, *val32;
	const char *path;
	u64 memsize64;
	int node, size, i;

	/* Make sure FDT blob is sane */
	if (fdt_check_header(boot_dtb) != 0)
		fatal("Invalid device tree blob\n");

	/* Find the #address-cells and #size-cells properties */
	node = fdt_path_offset(boot_dtb, "/");
	if (node < 0)
		fatal("Cannot find root node\n");
	na = fdt_getprop(boot_dtb, node, "#address-cells", &size);
	if (!na || (size != 4))
		fatal("Cannot find #address-cells property");

	ns = fdt_getprop(boot_dtb, node, "#size-cells", &size);
	if (!ns || (size != 4))
		fatal("Cannot find #size-cells property");

	/* Find the memory range */
	node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type",
					     "memory", sizeof("memory"));
	if (node < 0)
		fatal("Cannot find memory node\n");
	reg = fdt_getprop(boot_dtb, node, "reg", &size);
	if (size < (*na+*ns) * sizeof(u32))
		fatal("cannot get memory range\n");

	/* Only interested in memory based at 0 */
	for (i = 0; i < *na; i++)
		if (*reg++ != 0)
			fatal("Memory range is not based at address 0\n");

	/* get the memsize and trucate it to under 4G on 32 bit machines */
	memsize64 = 0;
	for (i = 0; i < *ns; i++)
		memsize64 = (memsize64 << 32) | *reg++;
	if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL)
		memsize64 = 0xffffffff;

	mem_size = memsize64;

	/* get clock frequencies */
	node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type",
					     "cpu", sizeof("cpu"));
	if (!node)
		fatal("Cannot find cpu node\n");

	val32 = fdt_getprop(boot_dtb, node, "clock-frequency", &size);
	if (!val32 || (size != 4))
		fatal("Cannot get clock frequency");

	int_freq = *val32;

	val32 = fdt_getprop(boot_dtb, node, "bus-frequency", &size);
	if (!val32 || (size != 4))
		fatal("Cannot get bus frequency");

	bus_freq = *val32;

	path = fdt_get_alias(boot_dtb, "ethernet0");
	if (path) {
		const void *p;

		node = fdt_path_offset(boot_dtb, path);
		if (node < 0)
			fatal("Cannot find ethernet0 node");

		p = fdt_getprop(boot_dtb, node, "mac-address", &size);
		if (!p || (size < 6)) {
			printf("no mac-address property, finding local\n\r");
			p = fdt_getprop(boot_dtb, node, "local-mac-address", &size);
		}

		if (!p || (size < 6))
			fatal("cannot get MAC addres");

		memcpy(enetaddr, p, sizeof(enetaddr));
	}
}
Exemplo n.º 23
0
void pci_init_board(void)
{
	struct pci_controller *pci_hoses;
	void *fdt = get_fdt_virt();
	int pci_node = -1;
	int pci_num = 0;
	int pci_count = 0;
	ulong map_addr;

	puts("\n");

	/* Start MMIO and PIO range maps above RAM */
	map_addr = CONFIG_SYS_PCI_MAP_START;

	/* Count and allocate PCI buses */
	pci_node = fdt_node_offset_by_prop_value(fdt, pci_node,
			"device_type", "pci", 4);
	while (pci_node != -FDT_ERR_NOTFOUND) {
		pci_node = fdt_node_offset_by_prop_value(fdt, pci_node,
				"device_type", "pci", 4);
		pci_count++;
	}

	if (pci_count) {
		pci_hoses = malloc(sizeof(struct pci_controller) * pci_count);
	} else {
		printf("PCI: disabled\n\n");
		return;
	}

	/* Spawn PCI buses based on device tree */
	pci_node = fdt_node_offset_by_prop_value(fdt, pci_node,
			"device_type", "pci", 4);
	while (pci_node != -FDT_ERR_NOTFOUND) {
		struct fsl_pci_info pci_info = { };
		const fdt32_t *reg;
		int r;

		reg = fdt_getprop(fdt, pci_node, "reg", NULL);
		pci_info.regs = fdt_translate_address(fdt, pci_node, reg);

		/* Map MMIO range */
		r = pci_map_region(fdt, pci_node, 0, &pci_info.mem_phys, NULL,
				   &pci_info.mem_size, &map_addr);
		if (r)
			break;

		/* Map PIO range */
		r = pci_map_region(fdt, pci_node, 1, &pci_info.io_phys, NULL,
				   &pci_info.io_size, &map_addr);
		if (r)
			break;

		/*
		 * The PCI framework finds virtual addresses for the buses
		 * through our address map, so tell it the physical addresses.
		 */
		pci_info.mem_bus = pci_info.mem_phys;
		pci_info.io_bus = pci_info.io_phys;

		/* Instantiate */
		pci_info.pci_num = pci_num + 1;

		fsl_setup_hose(&pci_hoses[pci_num], pci_info.regs);
		printf("PCI: base address %lx\n", pci_info.regs);

		fsl_pci_init_port(&pci_info, &pci_hoses[pci_num], pci_num);

		/* Jump to next PCI node */
		pci_node = fdt_node_offset_by_prop_value(fdt, pci_node,
				"device_type", "pci", 4);
		pci_num++;
	}

	puts("\n");
}