Пример #1
0
int qemu_fdt_nop_node(void *fdt, const char *node_path)
{
    int r;

    r = fdt_nop_node(fdt, findnode_nofail(fdt, node_path));
    if (r < 0) {
        error_report("%s: Couldn't nop node %s: %s", __func__, node_path,
                     fdt_strerror(r));
        exit(1);
    }

    return r;
}
Пример #2
0
int qemu_devtree_nop_node(void *fdt, const char *node_path)
{
    int r;

    r = fdt_nop_node(fdt, findnode_nofail(fdt, node_path));
    if (r < 0) {
        fprintf(stderr, "%s: Couldn't nop node %s: %s\n", __func__, node_path,
                fdt_strerror(r));
        exit(1);
    }

    return r;
}
Пример #3
0
static void kill_fdt_phy(void *fdt, int offset, void *arg)
{
	int len, phy_offset;
	const fdt32_t *php;
	uint32_t phandle;

	php = fdt_getprop(fdt, offset, "phy-handle", &len);
	if (php && len == sizeof(*php)) {
		phandle = fdt32_to_cpu(*php);
		fdt_nop_property(fdt, offset, "phy-handle");
		phy_offset = fdt_node_offset_by_phandle(fdt, phandle);
		if (phy_offset > 0)
			fdt_nop_node(fdt, phy_offset);
	}
}
Пример #4
0
static __init int remove_gic(void *fdt)
{
	const unsigned int cpu_ehci_int = 2;
	const unsigned int cpu_uart_int = 4;
	const unsigned int cpu_eth_int = 6;
	int gic_off, cpu_off, uart_off, eth_off, ehci_off, err;
	uint32_t cfg, cpu_phandle;

	/* leave the GIC node intact if a GIC is present */
	cfg = __raw_readl((uint32_t *)SEAD_CONFIG);
	if (cfg & SEAD_CONFIG_GIC_PRESENT)
		return 0;

	gic_off = fdt_node_offset_by_compatible(fdt, -1, "mti,gic");
	if (gic_off < 0) {
		pr_err("unable to find DT GIC node: %d\n", gic_off);
		return gic_off;
	}

	err = fdt_nop_node(fdt, gic_off);
	if (err) {
		pr_err("unable to nop GIC node\n");
		return err;
	}

	cpu_off = fdt_node_offset_by_compatible(fdt, -1,
			"mti,cpu-interrupt-controller");
	if (cpu_off < 0) {
		pr_err("unable to find CPU intc node: %d\n", cpu_off);
		return cpu_off;
	}

	cpu_phandle = fdt_get_phandle(fdt, cpu_off);
	if (!cpu_phandle) {
		pr_err("unable to get CPU intc phandle\n");
		return -EINVAL;
	}

	uart_off = fdt_node_offset_by_compatible(fdt, -1, "ns16550a");
	while (uart_off >= 0) {
		err = fdt_setprop_u32(fdt, uart_off, "interrupt-parent",
				      cpu_phandle);
		if (err) {
			pr_warn("unable to set UART interrupt-parent: %d\n",
				err);
			return err;
		}

		err = fdt_setprop_u32(fdt, uart_off, "interrupts",
				      cpu_uart_int);
		if (err) {
			pr_err("unable to set UART interrupts property: %d\n",
			       err);
			return err;
		}

		uart_off = fdt_node_offset_by_compatible(fdt, uart_off,
							 "ns16550a");
	}
	if (uart_off != -FDT_ERR_NOTFOUND) {
		pr_err("error searching for UART DT node: %d\n", uart_off);
		return uart_off;
	}

	eth_off = fdt_node_offset_by_compatible(fdt, -1, "smsc,lan9115");
	if (eth_off < 0) {
		pr_err("unable to find ethernet DT node: %d\n", eth_off);
		return eth_off;
	}

	err = fdt_setprop_u32(fdt, eth_off, "interrupt-parent", cpu_phandle);
	if (err) {
		pr_err("unable to set ethernet interrupt-parent: %d\n", err);
		return err;
	}

	err = fdt_setprop_u32(fdt, eth_off, "interrupts", cpu_eth_int);
	if (err) {
		pr_err("unable to set ethernet interrupts property: %d\n", err);
		return err;
	}

	ehci_off = fdt_node_offset_by_compatible(fdt, -1, "generic-ehci");
	if (ehci_off < 0) {
		pr_err("unable to find EHCI DT node: %d\n", ehci_off);
		return ehci_off;
	}

	err = fdt_setprop_u32(fdt, ehci_off, "interrupt-parent", cpu_phandle);
	if (err) {
		pr_err("unable to set EHCI interrupt-parent: %d\n", err);
		return err;
	}

	err = fdt_setprop_u32(fdt, ehci_off, "interrupts", cpu_ehci_int);
	if (err) {
		pr_err("unable to set EHCI interrupts property: %d\n", err);
		return err;
	}

	return 0;
}
Пример #5
0
int board_fixup_fdt(void)
{
	char fdt_key[16];
	int qlm;
	char env_var[16];
	const char *mode;
	int node;

	/* First patch the PHY configuration based on board revision */
	octeon_fdt_patch_rename((void *)(gd->fdt_blob),
				gd->arch.board_desc.rev_major == 1
				? "0,rev1" : "0,notrev1",
				"cavium,board-trim", false, NULL, NULL);

	/* Next patch CPU revision chages */
	for (node = 0; node < CVMX_MAX_NODES; node++) {
		if (!(gd->arch.node_mask & (1 << node)))
			continue;
		if (OCTEON_IS_MODEL(OCTEON_CN78XX_PASS1_0))
			sprintf(fdt_key, "%d,rev1.0", node);
		else
			sprintf(fdt_key, "%d,notrev1.0", node);
		octeon_fdt_patch((void *)(gd->fdt_blob), fdt_key, "cavium,cpu-trim");
	}

	for (qlm = 0; qlm < 8; qlm++) {
		sprintf(env_var, "qlm%d:%d_mode", qlm, 0);
		mode = getenv(env_var);
		sprintf(fdt_key, "%d,none", qlm);
		if (!mode) {
			sprintf(fdt_key, "%d,none", qlm);
		} else if (!strncmp(mode, "sgmii", 5)) {
			sprintf(fdt_key, "%d,sgmii", qlm);
		} else if (!strncmp(mode, "xaui", 4)) {
			sprintf(fdt_key, "%d,xaui", qlm);
		} else if (!strncmp(mode, "dxaui", 5)) {
			sprintf(fdt_key, "%d,dxaui", qlm);
		} else if (!strcmp(mode, "ilk")) {
			if (qlm < 4)
				printf("Error: ILK not supported on QLM %d\n",
				       qlm);
			else
				sprintf(fdt_key, "%d,ilk", qlm);
		} else if (!strncmp(mode, "rxaui", 5)) {
			sprintf(fdt_key, "%d,rxaui", qlm);
		} else if (!strncmp(mode, "xlaui", 5)) {
			if (qlm < 4)
				printf("Error: XLAUI not supported on QLM %d\n",
				       qlm);
			else
				sprintf(fdt_key, "%d,xlaui", qlm);
		} else if (!strncmp(mode, "xfi", 3)) {
			if (qlm < 4)
				printf("Error: XFI not supported on QLM %d\n",
				       qlm);
			else
				sprintf(fdt_key, "%d,xfi", qlm);
		} else if (!strncmp(mode, "10G_KR", 6)) {
			if (qlm < 4)
				printf("Error: 10G_KR not supported on QLM %d\n",
				       qlm);
			else
				sprintf(fdt_key, "%d,10G_KR", qlm);
		} else if (!strncmp(mode, "40G_KR4", 7)) {
			if (qlm < 4)
				printf("Error: 40G_KR4 not supported on QLM %d\n",
				       qlm);
			else
				sprintf(fdt_key, "%d,40G_KR4", qlm);
		}
		debug("Patching qlm %d for %s\n", qlm, fdt_key);
		octeon_fdt_patch_rename((void *)gd->fdt_blob, fdt_key, NULL, true,
					strstr(mode, ",no_phy") ? kill_fdt_phy : NULL, NULL);
	}

	/* Test for node 1 */
	if (!(gd->arch.node_mask & (1 << 1))) {
		octeon_fdt_patch((void *)(gd->fdt_blob), "1,none",
				 "cavium,node-trim");
		goto final_cleanup;
	}

	/* This won't do anything if node 1 is missing */
	for (qlm = 10; qlm < 18; qlm++) {
		sprintf(env_var, "qlm%d:%d_mode", qlm - 10, 1);
		mode = getenv(env_var);

		sprintf(fdt_key, "%d,none", qlm);
		if (!mode) {
			sprintf(fdt_key, "%d,none", qlm);
		} else if (!strncmp(mode, "sgmii", 5)) {
			sprintf(fdt_key, "%d,sgmii", qlm);
		} else if (!strncmp(mode, "xaui", 4)) {
			sprintf(fdt_key, "%d,xaui", qlm);
		} else if (!strncmp(mode, "dxaui", 5)) {
			sprintf(fdt_key, "%d,dxaui", qlm);
		} else if (!strcmp(mode, "ilk")) {
			if (qlm < 4)
				printf("Error: ILK not supported on QLM %d\n",
				       qlm);
			else
				sprintf(fdt_key, "%d,ilk", qlm);
		} else if (!strncmp(mode, "rxaui", 5)) {
			sprintf(fdt_key, "%d,rxaui", qlm);
		} else if (!strncmp(mode, "xlaui", 5)) {
			if (qlm < 4)
				printf("Error: XLAUI not supported on QLM %d\n",
				       qlm);
			else
				sprintf(fdt_key, "%d,xlaui", qlm);
		} else if (!strncmp(mode, "xfi", 3)) {
			if (qlm < 4)
				printf("Error: XFI not supported on QLM %d\n",
				       qlm);
			else
				sprintf(fdt_key, "%d,xfi", qlm);
		} else if (!strncmp(mode, "10G_KR", 6)) {
			if (qlm < 4)
				printf("Error: 10G_KR not supported on QLM %d\n",
				       qlm);
			else
				sprintf(fdt_key, "%d,10G_KR", qlm);
		} else if (!strncmp(mode, "40G_KR4", 7)) {
			if (qlm < 4)
				printf("Error: 40G_KR4 not supported on QLM %d\n",
				       qlm);
			else
				sprintf(fdt_key, "%d,40G_KR4", qlm);
		}
		debug("Patching qlm %d for %s\n", qlm, fdt_key);
		octeon_fdt_patch_rename((void *)gd->fdt_blob, fdt_key, NULL, true,
					strstr(mode, ",no_phy") ? kill_fdt_phy : NULL, NULL);
	}

final_cleanup:
	node = fdt_node_offset_by_compatible((void *)gd->fdt_blob, -1, "cavium,octeon-7890-bgx");
	while (node != -FDT_ERR_NOTFOUND) {
		int depth = 0;
		int child = fdt_next_node((void *)gd->fdt_blob, node, &depth);
		if (depth != 1)
			fdt_nop_node((void *)gd->fdt_blob, node);
		node = fdt_node_offset_by_compatible((void *)gd->fdt_blob, node, "cavium,octeon-7890-bgx");
	}

	return 0;
}