static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) { int off, ph; phys_addr_t paddr = CONFIG_SYS_CCSRBAR_PHYS + info->compat_offset; u64 dtsec1_addr = (u64)CONFIG_SYS_CCSRBAR_PHYS + CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET; off = fdt_node_offset_by_compat_reg(blob, prop, paddr); if (info->enabled) { fdt_fixup_phy_connection(blob, off, info->enet_if); board_ft_fman_fixup_port(blob, prop, paddr, info->port, off); return ; } /* board code might have caused offset to change */ off = fdt_node_offset_by_compat_reg(blob, prop, paddr); /* Don't disable FM1-DTSEC1 MAC as its used for MDIO */ if (paddr != dtsec1_addr) { /* disable the mac node */ fdt_setprop_string(blob, off, "status", "disabled"); } /* disable the node point to the mac */ ph = fdt_get_phandle(blob, off); do_fixup_by_prop(blob, "fsl,fman-mac", &ph, sizeof(ph), "status", "disabled", strlen("disabled") + 1, 1); }
static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) { int off; uint32_t ph; phys_addr_t paddr = CONFIG_SYS_CCSRBAR_PHYS + info->compat_offset; u64 dtsec1_addr = (u64)CONFIG_SYS_CCSRBAR_PHYS + CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET; off = fdt_node_offset_by_compat_reg(blob, prop, paddr); if (info->enabled) { fdt_fixup_phy_connection(blob, off, info->enet_if); board_ft_fman_fixup_port(blob, prop, paddr, info->port, off); return ; } #ifdef CONFIG_SYS_FMAN_V3 /* * Physically FM1_DTSEC9 and FM1_10GEC1 use the same dual-role MAC, when * FM1_10GEC1 is enabled and FM1_DTSEC9 is disabled, ensure that the * dual-role MAC is not disabled, ditto for other dual-role MACs. */ if (((info->port == FM1_DTSEC9) && (PORT_IS_ENABLED(FM1_10GEC1))) || ((info->port == FM1_DTSEC10) && (PORT_IS_ENABLED(FM1_10GEC2))) || ((info->port == FM1_DTSEC1) && (PORT_IS_ENABLED(FM1_10GEC1))) || ((info->port == FM1_DTSEC1) && (PORT_IS_ENABLED(FM1_10GEC3))) || ((info->port == FM1_DTSEC2) && (PORT_IS_ENABLED(FM1_10GEC4))) || ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC1))) || ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC9))) || ((info->port == FM1_10GEC2) && (PORT_IS_ENABLED(FM1_DTSEC10))) || ((info->port == FM1_10GEC3) && (PORT_IS_ENABLED(FM1_DTSEC1))) || ((info->port == FM1_10GEC4) && (PORT_IS_ENABLED(FM1_DTSEC2))) #if (CONFIG_SYS_NUM_FMAN == 2) || ((info->port == FM2_DTSEC9) && (PORT_IS_ENABLED(FM2_10GEC1))) || ((info->port == FM2_DTSEC10) && (PORT_IS_ENABLED(FM2_10GEC2))) || ((info->port == FM2_10GEC1) && (PORT_IS_ENABLED(FM2_DTSEC9))) || ((info->port == FM2_10GEC2) && (PORT_IS_ENABLED(FM2_DTSEC10))) #endif ) return; #endif /* board code might have caused offset to change */ off = fdt_node_offset_by_compat_reg(blob, prop, paddr); /* Don't disable FM1-DTSEC1 MAC as its used for MDIO */ if (paddr != dtsec1_addr) fdt_status_disabled(blob, off); /* disable the MAC node */ /* disable the fsl,dpa-ethernet node that points to the MAC */ ph = fdt_get_phandle(blob, off); do_fixup_by_prop(blob, "fsl,fman-mac", &ph, sizeof(ph), "status", "disabled", strlen("disabled") + 1, 1); }
static void fdt_fixup_liodn_tbl(void *blob, struct liodn_id_table *tbl, int sz) { int i; for (i = 0; i < sz; i++) { int off; if (tbl[i].compat == NULL) continue; off = fdt_node_offset_by_compat_reg(blob, tbl[i].compat, tbl[i].compat_offset); 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 " "%s: %s\n", tbl[i].compat, fdt_strerror(off)); } else { debug("WARNING: could not set fsl,liodn for %s: %s.\n", tbl[i].compat, fdt_strerror(off)); } } }
/* * Given the following ... * * 1) A pointer to an Fman Ethernet node (as identified by the 'compat' * compatible string and 'addr' physical address) * * 2) The name of an alias that points to the ethernet-phy node (usually inside * a virtual MDIO node) * * ... update that Ethernet node's phy-handle property to point to the * ethernet-phy node. This is how we link an Ethernet node to its PHY, so each * PHY in a virtual MDIO node must have an alias. * * Returns 0 on success, or a negative FDT error code on error. */ int fdt_set_phy_handle(void *fdt, char *compat, phys_addr_t addr, const char *alias) { int offset; unsigned int ph; const char *path; /* Get a path to the node that 'alias' points to */ path = fdt_get_alias(fdt, alias); if (!path) return -FDT_ERR_BADPATH; /* Get the offset of that node */ offset = fdt_path_offset(fdt, path); if (offset < 0) return offset; ph = fdt_create_phandle(fdt, offset); if (!ph) return -FDT_ERR_BADPHANDLE; offset = fdt_node_offset_by_compat_reg(fdt, compat, addr); if (offset < 0) return offset; return fdt_setprop(fdt, offset, "phy-handle", &ph, sizeof(ph)); }
void fdt_del_sec(void *blob, int offset) { int nodeoff = 0; while ((nodeoff = fdt_node_offset_by_compat_reg(blob, "fsl,sec-v6.0", CONFIG_SYS_CCSRBAR_PHYS + CONFIG_SYS_FSL_SEC_OFFSET + offset * 0x20000)) >= 0) { fdt_del_node(blob, nodeoff); offset++; } }
static void ft_pcie_ls_setup(void *blob, const char *pci_compat, unsigned long ctrl_addr, enum srds_prtcl dev) { int off; off = fdt_node_offset_by_compat_reg(blob, pci_compat, (phys_addr_t)ctrl_addr); if (off < 0) return; if (!is_serdes_configured(dev)) fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); }
void fdt_disable_uart1(void *blob) { int nodeoff; nodeoff = fdt_node_offset_by_compat_reg(blob, "fsl,ns16550", CONFIG_SYS_NS16550_COM2); if (nodeoff > 0) { fdt_status_disabled(blob, nodeoff); } else { printf("WARNING unable to set status for fsl,ns16550 " "uart1: %s\n", fdt_strerror(nodeoff)); } }
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 }
void board_ft_fman_fixup_port(void *fdt, char *compat, phys_addr_t addr, enum fm_port port, int offset) { int phy; char alias[20]; char lane_mode[2][20] = {"1000BASE-KX", "10GBASE-KR"}; char buf[32] = "serdes-1,"; struct fixed_link f_link; int media_type = 0; int off; ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); #ifdef CONFIG_T2080QDS serdes_corenet_t *srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR; u32 srds1_pccr1 = in_be32(&srds_regs->srdspccr1); #endif u32 srds_s1 = in_be32(&gur->rcwsr[4]) & FSL_CORENET2_RCWSR4_SRDS1_PRTCL; srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT; if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_SGMII) { phy = fm_info_get_phy_address(port); switch (port) { #if defined(CONFIG_T2080QDS) case FM1_DTSEC1: if (hwconfig_sub("fsl_1gkx", "fm1_1g1")) { media_type = 1; fdt_set_phy_handle(fdt, compat, addr, "phy_1gkx1"); fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio1"); sprintf(buf, "%s%s%s", buf, "lane-c,", (char *)lane_mode[0]); out_be32(&srds_regs->srdspccr1, srds1_pccr1 | PCCR1_SGMIIH_KX_MASK); break; } case FM1_DTSEC2: if (hwconfig_sub("fsl_1gkx", "fm1_1g2")) { media_type = 1; fdt_set_phy_handle(fdt, compat, addr, "phy_1gkx2"); fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio2"); sprintf(buf, "%s%s%s", buf, "lane-d,", (char *)lane_mode[0]); out_be32(&srds_regs->srdspccr1, srds1_pccr1 | PCCR1_SGMIIG_KX_MASK); break; } case FM1_DTSEC9: if (hwconfig_sub("fsl_1gkx", "fm1_1g9")) { media_type = 1; fdt_set_phy_handle(fdt, compat, addr, "phy_1gkx9"); fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio9"); sprintf(buf, "%s%s%s", buf, "lane-a,", (char *)lane_mode[0]); out_be32(&srds_regs->srdspccr1, srds1_pccr1 | PCCR1_SGMIIE_KX_MASK); break; } case FM1_DTSEC10: if (hwconfig_sub("fsl_1gkx", "fm1_1g10")) { media_type = 1; fdt_set_phy_handle(fdt, compat, addr, "phy_1gkx10"); fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio10"); sprintf(buf, "%s%s%s", buf, "lane-b,", (char *)lane_mode[0]); out_be32(&srds_regs->srdspccr1, srds1_pccr1 | PCCR1_SGMIIF_KX_MASK); break; } if (mdio_mux[port] == EMI1_SLOT2) { sprintf(alias, "phy_sgmii_s2_%x", phy); fdt_set_phy_handle(fdt, compat, addr, alias); fdt_status_okay_by_alias(fdt, "emi1_slot2"); } else if (mdio_mux[port] == EMI1_SLOT3) { sprintf(alias, "phy_sgmii_s3_%x", phy); fdt_set_phy_handle(fdt, compat, addr, alias); fdt_status_okay_by_alias(fdt, "emi1_slot3"); } break; case FM1_DTSEC5: if (hwconfig_sub("fsl_1gkx", "fm1_1g5")) { media_type = 1; fdt_set_phy_handle(fdt, compat, addr, "phy_1gkx5"); fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio5"); sprintf(buf, "%s%s%s", buf, "lane-g,", (char *)lane_mode[0]); out_be32(&srds_regs->srdspccr1, srds1_pccr1 | PCCR1_SGMIIC_KX_MASK); break; } case FM1_DTSEC6: if (hwconfig_sub("fsl_1gkx", "fm1_1g6")) { media_type = 1; fdt_set_phy_handle(fdt, compat, addr, "phy_1gkx6"); fdt_status_okay_by_alias(fdt, "1gkx_pcs_mdio6"); sprintf(buf, "%s%s%s", buf, "lane-h,", (char *)lane_mode[0]); out_be32(&srds_regs->srdspccr1, srds1_pccr1 | PCCR1_SGMIID_KX_MASK); break; } if (mdio_mux[port] == EMI1_SLOT1) { sprintf(alias, "phy_sgmii_s1_%x", phy); fdt_set_phy_handle(fdt, compat, addr, alias); fdt_status_okay_by_alias(fdt, "emi1_slot1"); } else if (mdio_mux[port] == EMI1_SLOT2) { sprintf(alias, "phy_sgmii_s2_%x", phy); fdt_set_phy_handle(fdt, compat, addr, alias); fdt_status_okay_by_alias(fdt, "emi1_slot2"); } break; #elif defined(CONFIG_T2081QDS) case FM1_DTSEC1: case FM1_DTSEC2: case FM1_DTSEC5: case FM1_DTSEC6: case FM1_DTSEC9: case FM1_DTSEC10: if (mdio_mux[port] == EMI1_SLOT2) { sprintf(alias, "phy_sgmii_s2_%x", phy); fdt_set_phy_handle(fdt, compat, addr, alias); fdt_status_okay_by_alias(fdt, "emi1_slot2"); } else if (mdio_mux[port] == EMI1_SLOT3) { sprintf(alias, "phy_sgmii_s3_%x", phy); fdt_set_phy_handle(fdt, compat, addr, alias); fdt_status_okay_by_alias(fdt, "emi1_slot3"); } else if (mdio_mux[port] == EMI1_SLOT5) { sprintf(alias, "phy_sgmii_s5_%x", phy); fdt_set_phy_handle(fdt, compat, addr, alias); fdt_status_okay_by_alias(fdt, "emi1_slot5"); } else if (mdio_mux[port] == EMI1_SLOT6) { sprintf(alias, "phy_sgmii_s6_%x", phy); fdt_set_phy_handle(fdt, compat, addr, alias); fdt_status_okay_by_alias(fdt, "emi1_slot6"); } else if (mdio_mux[port] == EMI1_SLOT7) { sprintf(alias, "phy_sgmii_s7_%x", phy); fdt_set_phy_handle(fdt, compat, addr, alias); fdt_status_okay_by_alias(fdt, "emi1_slot7"); } break; #endif default: break; } if (media_type) { /* set property for 1000BASE-KX in dtb */ off = fdt_node_offset_by_compat_reg(fdt, "fsl,fman-memac-mdio", addr + 0x1000); fdt_setprop_string(fdt, off, "lane-instance", buf); } } else if (fm_info_get_enet_if(port) == PHY_INTERFACE_MODE_XGMII) { switch (srds_s1) { case 0x66: /* XFI interface */ case 0x6b: case 0x6c: case 0x6d: case 0x71: /* * if the 10G is XFI, check hwconfig to see what is the * media type, there are two types, fiber or copper, * fix the dtb accordingly. */ switch (port) { case FM1_10GEC1: if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g1")) { /* it's MAC9 */ media_type = 1; fdt_set_phy_handle(fdt, compat, addr, "phy_xfi9"); fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio9"); sprintf(buf, "%s%s%s", buf, "lane-a,", (char *)lane_mode[1]); } break; case FM1_10GEC2: if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g2")) { /* it's MAC10 */ media_type = 1; fdt_set_phy_handle(fdt, compat, addr, "phy_xfi10"); fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio10"); sprintf(buf, "%s%s%s", buf, "lane-b,", (char *)lane_mode[1]); } break; case FM1_10GEC3: if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g3")) { /* it's MAC1 */ media_type = 1; fdt_set_phy_handle(fdt, compat, addr, "phy_xfi1"); fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio1"); sprintf(buf, "%s%s%s", buf, "lane-c,", (char *)lane_mode[1]); } break; case FM1_10GEC4: if (hwconfig_sub("fsl_10gkr_copper", "fm1_10g4")) { /* it's MAC2 */ media_type = 1; fdt_set_phy_handle(fdt, compat, addr, "phy_xfi2"); fdt_status_okay_by_alias(fdt, "xfi_pcs_mdio2"); sprintf(buf, "%s%s%s", buf, "lane-d,", (char *)lane_mode[1]); } break; default: return; } if (!media_type) { /* fixed-link is used for XFI fiber cable */ f_link.phy_id = port; f_link.duplex = 1; f_link.link_speed = 10000; f_link.pause = 0; f_link.asym_pause = 0; fdt_delprop(fdt, offset, "phy-handle"); fdt_setprop(fdt, offset, "fixed-link", &f_link, sizeof(f_link)); } else { /* set property for copper cable */ off = fdt_node_offset_by_compat_reg(fdt, "fsl,fman-memac-mdio", addr + 0x1000); fdt_setprop_string(fdt, off, "lane-instance", buf); } break; default: break; } } }