Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * This file is subject to the terms and conditions of the GNU General Public
0003  * License.  See the file "COPYING" in the main directory of this archive
0004  * for more details.
0005  *
0006  * Copyright (C) 2004-2017 Cavium, Inc.
0007  * Copyright (C) 2008 Wind River Systems
0008  */
0009 
0010 #include <linux/etherdevice.h>
0011 #include <linux/of_platform.h>
0012 #include <linux/of_fdt.h>
0013 #include <linux/libfdt.h>
0014 
0015 #include <asm/octeon/octeon.h>
0016 #include <asm/octeon/cvmx-helper-board.h>
0017 
0018 #ifdef CONFIG_USB
0019 #include <linux/usb/ehci_def.h>
0020 #include <linux/usb/ehci_pdriver.h>
0021 #include <linux/usb/ohci_pdriver.h>
0022 #include <asm/octeon/cvmx-uctlx-defs.h>
0023 
0024 #define CVMX_UAHCX_EHCI_USBCMD  (CVMX_ADD_IO_SEG(0x00016F0000000010ull))
0025 #define CVMX_UAHCX_OHCI_USBCMD  (CVMX_ADD_IO_SEG(0x00016F0000000408ull))
0026 
0027 static DEFINE_MUTEX(octeon2_usb_clocks_mutex);
0028 
0029 static int octeon2_usb_clock_start_cnt;
0030 
0031 static int __init octeon2_usb_reset(void)
0032 {
0033     union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
0034     u32 ucmd;
0035 
0036     if (!OCTEON_IS_OCTEON2())
0037         return 0;
0038 
0039     clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
0040     if (clk_rst_ctl.s.hrst) {
0041         ucmd = cvmx_read64_uint32(CVMX_UAHCX_EHCI_USBCMD);
0042         ucmd &= ~CMD_RUN;
0043         cvmx_write64_uint32(CVMX_UAHCX_EHCI_USBCMD, ucmd);
0044         mdelay(2);
0045         ucmd |= CMD_RESET;
0046         cvmx_write64_uint32(CVMX_UAHCX_EHCI_USBCMD, ucmd);
0047         ucmd = cvmx_read64_uint32(CVMX_UAHCX_OHCI_USBCMD);
0048         ucmd |= CMD_RUN;
0049         cvmx_write64_uint32(CVMX_UAHCX_OHCI_USBCMD, ucmd);
0050     }
0051 
0052     return 0;
0053 }
0054 arch_initcall(octeon2_usb_reset);
0055 
0056 static void octeon2_usb_clocks_start(struct device *dev)
0057 {
0058     u64 div;
0059     union cvmx_uctlx_if_ena if_ena;
0060     union cvmx_uctlx_clk_rst_ctl clk_rst_ctl;
0061     union cvmx_uctlx_uphy_portx_ctl_status port_ctl_status;
0062     int i;
0063     unsigned long io_clk_64_to_ns;
0064     u32 clock_rate = 12000000;
0065     bool is_crystal_clock = false;
0066 
0067 
0068     mutex_lock(&octeon2_usb_clocks_mutex);
0069 
0070     octeon2_usb_clock_start_cnt++;
0071     if (octeon2_usb_clock_start_cnt != 1)
0072         goto exit;
0073 
0074     io_clk_64_to_ns = 64000000000ull / octeon_get_io_clock_rate();
0075 
0076     if (dev->of_node) {
0077         struct device_node *uctl_node;
0078         const char *clock_type;
0079 
0080         uctl_node = of_get_parent(dev->of_node);
0081         if (!uctl_node) {
0082             dev_err(dev, "No UCTL device node\n");
0083             goto exit;
0084         }
0085         i = of_property_read_u32(uctl_node,
0086                      "refclk-frequency", &clock_rate);
0087         if (i) {
0088             dev_err(dev, "No UCTL \"refclk-frequency\"\n");
0089             of_node_put(uctl_node);
0090             goto exit;
0091         }
0092         i = of_property_read_string(uctl_node,
0093                         "refclk-type", &clock_type);
0094         of_node_put(uctl_node);
0095         if (!i && strcmp("crystal", clock_type) == 0)
0096             is_crystal_clock = true;
0097     }
0098 
0099     /*
0100      * Step 1: Wait for voltages stable.  That surely happened
0101      * before starting the kernel.
0102      *
0103      * Step 2: Enable  SCLK of UCTL by writing UCTL0_IF_ENA[EN] = 1
0104      */
0105     if_ena.u64 = 0;
0106     if_ena.s.en = 1;
0107     cvmx_write_csr(CVMX_UCTLX_IF_ENA(0), if_ena.u64);
0108 
0109     for (i = 0; i <= 1; i++) {
0110         port_ctl_status.u64 =
0111             cvmx_read_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0));
0112         /* Set txvreftune to 15 to obtain compliant 'eye' diagram. */
0113         port_ctl_status.s.txvreftune = 15;
0114         port_ctl_status.s.txrisetune = 1;
0115         port_ctl_status.s.txpreemphasistune = 1;
0116         cvmx_write_csr(CVMX_UCTLX_UPHY_PORTX_CTL_STATUS(i, 0),
0117                    port_ctl_status.u64);
0118     }
0119 
0120     /* Step 3: Configure the reference clock, PHY, and HCLK */
0121     clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
0122 
0123     /*
0124      * If the UCTL looks like it has already been started, skip
0125      * the initialization, otherwise bus errors are obtained.
0126      */
0127     if (clk_rst_ctl.s.hrst)
0128         goto end_clock;
0129     /* 3a */
0130     clk_rst_ctl.s.p_por = 1;
0131     clk_rst_ctl.s.hrst = 0;
0132     clk_rst_ctl.s.p_prst = 0;
0133     clk_rst_ctl.s.h_clkdiv_rst = 0;
0134     clk_rst_ctl.s.o_clkdiv_rst = 0;
0135     clk_rst_ctl.s.h_clkdiv_en = 0;
0136     clk_rst_ctl.s.o_clkdiv_en = 0;
0137     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0138 
0139     /* 3b */
0140     clk_rst_ctl.s.p_refclk_sel = is_crystal_clock ? 0 : 1;
0141     switch (clock_rate) {
0142     default:
0143         pr_err("Invalid UCTL clock rate of %u, using 12000000 instead\n",
0144             clock_rate);
0145         fallthrough;
0146     case 12000000:
0147         clk_rst_ctl.s.p_refclk_div = 0;
0148         break;
0149     case 24000000:
0150         clk_rst_ctl.s.p_refclk_div = 1;
0151         break;
0152     case 48000000:
0153         clk_rst_ctl.s.p_refclk_div = 2;
0154         break;
0155     }
0156     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0157 
0158     /* 3c */
0159     div = octeon_get_io_clock_rate() / 130000000ull;
0160 
0161     switch (div) {
0162     case 0:
0163         div = 1;
0164         break;
0165     case 1:
0166     case 2:
0167     case 3:
0168     case 4:
0169         break;
0170     case 5:
0171         div = 4;
0172         break;
0173     case 6:
0174     case 7:
0175         div = 6;
0176         break;
0177     case 8:
0178     case 9:
0179     case 10:
0180     case 11:
0181         div = 8;
0182         break;
0183     default:
0184         div = 12;
0185         break;
0186     }
0187     clk_rst_ctl.s.h_div = div;
0188     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0189     /* Read it back, */
0190     clk_rst_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_CLK_RST_CTL(0));
0191     clk_rst_ctl.s.h_clkdiv_en = 1;
0192     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0193     /* 3d */
0194     clk_rst_ctl.s.h_clkdiv_rst = 1;
0195     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0196 
0197     /* 3e: delay 64 io clocks */
0198     ndelay(io_clk_64_to_ns);
0199 
0200     /*
0201      * Step 4: Program the power-on reset field in the UCTL
0202      * clock-reset-control register.
0203      */
0204     clk_rst_ctl.s.p_por = 0;
0205     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0206 
0207     /* Step 5:    Wait 3 ms for the PHY clock to start. */
0208     mdelay(3);
0209 
0210     /* Steps 6..9 for ATE only, are skipped. */
0211 
0212     /* Step 10: Configure the OHCI_CLK48 and OHCI_CLK12 clocks. */
0213     /* 10a */
0214     clk_rst_ctl.s.o_clkdiv_rst = 1;
0215     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0216 
0217     /* 10b */
0218     clk_rst_ctl.s.o_clkdiv_en = 1;
0219     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0220 
0221     /* 10c */
0222     ndelay(io_clk_64_to_ns);
0223 
0224     /*
0225      * Step 11: Program the PHY reset field:
0226      * UCTL0_CLK_RST_CTL[P_PRST] = 1
0227      */
0228     clk_rst_ctl.s.p_prst = 1;
0229     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0230 
0231     /* Step 11b */
0232     udelay(1);
0233 
0234     /* Step 11c */
0235     clk_rst_ctl.s.p_prst = 0;
0236     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0237 
0238     /* Step 11d */
0239     mdelay(1);
0240 
0241     /* Step 11e */
0242     clk_rst_ctl.s.p_prst = 1;
0243     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0244 
0245     /* Step 12: Wait 1 uS. */
0246     udelay(1);
0247 
0248     /* Step 13: Program the HRESET_N field: UCTL0_CLK_RST_CTL[HRST] = 1 */
0249     clk_rst_ctl.s.hrst = 1;
0250     cvmx_write_csr(CVMX_UCTLX_CLK_RST_CTL(0), clk_rst_ctl.u64);
0251 
0252 end_clock:
0253     /* Set uSOF cycle period to 60,000 bits. */
0254     cvmx_write_csr(CVMX_UCTLX_EHCI_FLA(0), 0x20ull);
0255 
0256 exit:
0257     mutex_unlock(&octeon2_usb_clocks_mutex);
0258 }
0259 
0260 static void octeon2_usb_clocks_stop(void)
0261 {
0262     mutex_lock(&octeon2_usb_clocks_mutex);
0263     octeon2_usb_clock_start_cnt--;
0264     mutex_unlock(&octeon2_usb_clocks_mutex);
0265 }
0266 
0267 static int octeon_ehci_power_on(struct platform_device *pdev)
0268 {
0269     octeon2_usb_clocks_start(&pdev->dev);
0270     return 0;
0271 }
0272 
0273 static void octeon_ehci_power_off(struct platform_device *pdev)
0274 {
0275     octeon2_usb_clocks_stop();
0276 }
0277 
0278 static struct usb_ehci_pdata octeon_ehci_pdata = {
0279     /* Octeon EHCI matches CPU endianness. */
0280 #ifdef __BIG_ENDIAN
0281     .big_endian_mmio    = 1,
0282 #endif
0283     /*
0284      * We can DMA from anywhere. But the descriptors must be in
0285      * the lower 4GB.
0286      */
0287     .dma_mask_64    = 0,
0288     .power_on   = octeon_ehci_power_on,
0289     .power_off  = octeon_ehci_power_off,
0290 };
0291 
0292 static void __init octeon_ehci_hw_start(struct device *dev)
0293 {
0294     union cvmx_uctlx_ehci_ctl ehci_ctl;
0295 
0296     octeon2_usb_clocks_start(dev);
0297 
0298     ehci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_EHCI_CTL(0));
0299     /* Use 64-bit addressing. */
0300     ehci_ctl.s.ehci_64b_addr_en = 1;
0301     ehci_ctl.s.l2c_addr_msb = 0;
0302 #ifdef __BIG_ENDIAN
0303     ehci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
0304     ehci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
0305 #else
0306     ehci_ctl.s.l2c_buff_emod = 0; /* not swapped. */
0307     ehci_ctl.s.l2c_desc_emod = 0; /* not swapped. */
0308     ehci_ctl.s.inv_reg_a2 = 1;
0309 #endif
0310     cvmx_write_csr(CVMX_UCTLX_EHCI_CTL(0), ehci_ctl.u64);
0311 
0312     octeon2_usb_clocks_stop();
0313 }
0314 
0315 static int __init octeon_ehci_device_init(void)
0316 {
0317     struct platform_device *pd;
0318     struct device_node *ehci_node;
0319     int ret = 0;
0320 
0321     ehci_node = of_find_node_by_name(NULL, "ehci");
0322     if (!ehci_node)
0323         return 0;
0324 
0325     pd = of_find_device_by_node(ehci_node);
0326     of_node_put(ehci_node);
0327     if (!pd)
0328         return 0;
0329 
0330     pd->dev.platform_data = &octeon_ehci_pdata;
0331     octeon_ehci_hw_start(&pd->dev);
0332     put_device(&pd->dev);
0333 
0334     return ret;
0335 }
0336 device_initcall(octeon_ehci_device_init);
0337 
0338 static int octeon_ohci_power_on(struct platform_device *pdev)
0339 {
0340     octeon2_usb_clocks_start(&pdev->dev);
0341     return 0;
0342 }
0343 
0344 static void octeon_ohci_power_off(struct platform_device *pdev)
0345 {
0346     octeon2_usb_clocks_stop();
0347 }
0348 
0349 static struct usb_ohci_pdata octeon_ohci_pdata = {
0350     /* Octeon OHCI matches CPU endianness. */
0351 #ifdef __BIG_ENDIAN
0352     .big_endian_mmio    = 1,
0353 #endif
0354     .power_on   = octeon_ohci_power_on,
0355     .power_off  = octeon_ohci_power_off,
0356 };
0357 
0358 static void __init octeon_ohci_hw_start(struct device *dev)
0359 {
0360     union cvmx_uctlx_ohci_ctl ohci_ctl;
0361 
0362     octeon2_usb_clocks_start(dev);
0363 
0364     ohci_ctl.u64 = cvmx_read_csr(CVMX_UCTLX_OHCI_CTL(0));
0365     ohci_ctl.s.l2c_addr_msb = 0;
0366 #ifdef __BIG_ENDIAN
0367     ohci_ctl.s.l2c_buff_emod = 1; /* Byte swapped. */
0368     ohci_ctl.s.l2c_desc_emod = 1; /* Byte swapped. */
0369 #else
0370     ohci_ctl.s.l2c_buff_emod = 0; /* not swapped. */
0371     ohci_ctl.s.l2c_desc_emod = 0; /* not swapped. */
0372     ohci_ctl.s.inv_reg_a2 = 1;
0373 #endif
0374     cvmx_write_csr(CVMX_UCTLX_OHCI_CTL(0), ohci_ctl.u64);
0375 
0376     octeon2_usb_clocks_stop();
0377 }
0378 
0379 static int __init octeon_ohci_device_init(void)
0380 {
0381     struct platform_device *pd;
0382     struct device_node *ohci_node;
0383     int ret = 0;
0384 
0385     ohci_node = of_find_node_by_name(NULL, "ohci");
0386     if (!ohci_node)
0387         return 0;
0388 
0389     pd = of_find_device_by_node(ohci_node);
0390     of_node_put(ohci_node);
0391     if (!pd)
0392         return 0;
0393 
0394     pd->dev.platform_data = &octeon_ohci_pdata;
0395     octeon_ohci_hw_start(&pd->dev);
0396     put_device(&pd->dev);
0397 
0398     return ret;
0399 }
0400 device_initcall(octeon_ohci_device_init);
0401 
0402 #endif /* CONFIG_USB */
0403 
0404 /* Octeon Random Number Generator.  */
0405 static int __init octeon_rng_device_init(void)
0406 {
0407     struct platform_device *pd;
0408     int ret = 0;
0409 
0410     struct resource rng_resources[] = {
0411         {
0412             .flags  = IORESOURCE_MEM,
0413             .start  = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS),
0414             .end    = XKPHYS_TO_PHYS(CVMX_RNM_CTL_STATUS) + 0xf
0415         }, {
0416             .flags  = IORESOURCE_MEM,
0417             .start  = cvmx_build_io_address(8, 0),
0418             .end    = cvmx_build_io_address(8, 0) + 0x7
0419         }
0420     };
0421 
0422     pd = platform_device_alloc("octeon_rng", -1);
0423     if (!pd) {
0424         ret = -ENOMEM;
0425         goto out;
0426     }
0427 
0428     ret = platform_device_add_resources(pd, rng_resources,
0429                         ARRAY_SIZE(rng_resources));
0430     if (ret)
0431         goto fail;
0432 
0433     ret = platform_device_add(pd);
0434     if (ret)
0435         goto fail;
0436 
0437     return ret;
0438 fail:
0439     platform_device_put(pd);
0440 
0441 out:
0442     return ret;
0443 }
0444 device_initcall(octeon_rng_device_init);
0445 
0446 static const struct of_device_id octeon_ids[] __initconst = {
0447     { .compatible = "simple-bus", },
0448     { .compatible = "cavium,octeon-6335-uctl", },
0449     { .compatible = "cavium,octeon-5750-usbn", },
0450     { .compatible = "cavium,octeon-3860-bootbus", },
0451     { .compatible = "cavium,mdio-mux", },
0452     { .compatible = "gpio-leds", },
0453     { .compatible = "cavium,octeon-7130-usb-uctl", },
0454     {},
0455 };
0456 
0457 static bool __init octeon_has_88e1145(void)
0458 {
0459     return !OCTEON_IS_MODEL(OCTEON_CN52XX) &&
0460            !OCTEON_IS_MODEL(OCTEON_CN6XXX) &&
0461            !OCTEON_IS_MODEL(OCTEON_CN56XX);
0462 }
0463 
0464 static bool __init octeon_has_fixed_link(int ipd_port)
0465 {
0466     switch (cvmx_sysinfo_get()->board_type) {
0467     case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
0468     case CVMX_BOARD_TYPE_CN3010_EVB_HS5:
0469     case CVMX_BOARD_TYPE_CN3020_EVB_HS5:
0470     case CVMX_BOARD_TYPE_CUST_NB5:
0471     case CVMX_BOARD_TYPE_EBH3100:
0472         /* Port 1 on these boards is always gigabit. */
0473         return ipd_port == 1;
0474     case CVMX_BOARD_TYPE_BBGW_REF:
0475         /* Ports 0 and 1 connect to the switch. */
0476         return ipd_port == 0 || ipd_port == 1;
0477     }
0478     return false;
0479 }
0480 
0481 static void __init octeon_fdt_set_phy(int eth, int phy_addr)
0482 {
0483     const __be32 *phy_handle;
0484     const __be32 *alt_phy_handle;
0485     const __be32 *reg;
0486     u32 phandle;
0487     int phy;
0488     int alt_phy;
0489     const char *p;
0490     int current_len;
0491     char new_name[20];
0492 
0493     phy_handle = fdt_getprop(initial_boot_params, eth, "phy-handle", NULL);
0494     if (!phy_handle)
0495         return;
0496 
0497     phandle = be32_to_cpup(phy_handle);
0498     phy = fdt_node_offset_by_phandle(initial_boot_params, phandle);
0499 
0500     alt_phy_handle = fdt_getprop(initial_boot_params, eth, "cavium,alt-phy-handle", NULL);
0501     if (alt_phy_handle) {
0502         u32 alt_phandle = be32_to_cpup(alt_phy_handle);
0503 
0504         alt_phy = fdt_node_offset_by_phandle(initial_boot_params, alt_phandle);
0505     } else {
0506         alt_phy = -1;
0507     }
0508 
0509     if (phy_addr < 0 || phy < 0) {
0510         /* Delete the PHY things */
0511         fdt_nop_property(initial_boot_params, eth, "phy-handle");
0512         /* This one may fail */
0513         fdt_nop_property(initial_boot_params, eth, "cavium,alt-phy-handle");
0514         if (phy >= 0)
0515             fdt_nop_node(initial_boot_params, phy);
0516         if (alt_phy >= 0)
0517             fdt_nop_node(initial_boot_params, alt_phy);
0518         return;
0519     }
0520 
0521     if (phy_addr >= 256 && alt_phy > 0) {
0522         const struct fdt_property *phy_prop;
0523         struct fdt_property *alt_prop;
0524         fdt32_t phy_handle_name;
0525 
0526         /* Use the alt phy node instead.*/
0527         phy_prop = fdt_get_property(initial_boot_params, eth, "phy-handle", NULL);
0528         phy_handle_name = phy_prop->nameoff;
0529         fdt_nop_node(initial_boot_params, phy);
0530         fdt_nop_property(initial_boot_params, eth, "phy-handle");
0531         alt_prop = fdt_get_property_w(initial_boot_params, eth, "cavium,alt-phy-handle", NULL);
0532         alt_prop->nameoff = phy_handle_name;
0533         phy = alt_phy;
0534     }
0535 
0536     phy_addr &= 0xff;
0537 
0538     if (octeon_has_88e1145()) {
0539         fdt_nop_property(initial_boot_params, phy, "marvell,reg-init");
0540         memset(new_name, 0, sizeof(new_name));
0541         strcpy(new_name, "marvell,88e1145");
0542         p = fdt_getprop(initial_boot_params, phy, "compatible",
0543                 &current_len);
0544         if (p && current_len >= strlen(new_name))
0545             fdt_setprop_inplace(initial_boot_params, phy,
0546                     "compatible", new_name, current_len);
0547     }
0548 
0549     reg = fdt_getprop(initial_boot_params, phy, "reg", NULL);
0550     if (phy_addr == be32_to_cpup(reg))
0551         return;
0552 
0553     fdt_setprop_inplace_cell(initial_boot_params, phy, "reg", phy_addr);
0554 
0555     snprintf(new_name, sizeof(new_name), "ethernet-phy@%x", phy_addr);
0556 
0557     p = fdt_get_name(initial_boot_params, phy, &current_len);
0558     if (p && current_len == strlen(new_name))
0559         fdt_set_name(initial_boot_params, phy, new_name);
0560     else
0561         pr_err("Error: could not rename ethernet phy: <%s>", p);
0562 }
0563 
0564 static void __init octeon_fdt_set_mac_addr(int n, u64 *pmac)
0565 {
0566     const u8 *old_mac;
0567     int old_len;
0568     u8 new_mac[6];
0569     u64 mac = *pmac;
0570     int r;
0571 
0572     old_mac = fdt_getprop(initial_boot_params, n, "local-mac-address",
0573                   &old_len);
0574     if (!old_mac || old_len != 6 || is_valid_ether_addr(old_mac))
0575         return;
0576 
0577     new_mac[0] = (mac >> 40) & 0xff;
0578     new_mac[1] = (mac >> 32) & 0xff;
0579     new_mac[2] = (mac >> 24) & 0xff;
0580     new_mac[3] = (mac >> 16) & 0xff;
0581     new_mac[4] = (mac >> 8) & 0xff;
0582     new_mac[5] = mac & 0xff;
0583 
0584     r = fdt_setprop_inplace(initial_boot_params, n, "local-mac-address",
0585                 new_mac, sizeof(new_mac));
0586 
0587     if (r) {
0588         pr_err("Setting \"local-mac-address\" failed %d", r);
0589         return;
0590     }
0591     *pmac = mac + 1;
0592 }
0593 
0594 static void __init octeon_fdt_rm_ethernet(int node)
0595 {
0596     const __be32 *phy_handle;
0597 
0598     phy_handle = fdt_getprop(initial_boot_params, node, "phy-handle", NULL);
0599     if (phy_handle) {
0600         u32 ph = be32_to_cpup(phy_handle);
0601         int p = fdt_node_offset_by_phandle(initial_boot_params, ph);
0602 
0603         if (p >= 0)
0604             fdt_nop_node(initial_boot_params, p);
0605     }
0606     fdt_nop_node(initial_boot_params, node);
0607 }
0608 
0609 static void __init _octeon_rx_tx_delay(int eth, int rx_delay, int tx_delay)
0610 {
0611     fdt_setprop_inplace_cell(initial_boot_params, eth, "rx-delay",
0612                  rx_delay);
0613     fdt_setprop_inplace_cell(initial_boot_params, eth, "tx-delay",
0614                  tx_delay);
0615 }
0616 
0617 static void __init octeon_rx_tx_delay(int eth, int iface, int port)
0618 {
0619     switch (cvmx_sysinfo_get()->board_type) {
0620     case CVMX_BOARD_TYPE_CN3005_EVB_HS5:
0621         if (iface == 0) {
0622             if (port == 0) {
0623                 /*
0624                  * Boards with gigabit WAN ports need a
0625                  * different setting that is compatible with
0626                  * 100 Mbit settings
0627                  */
0628                 _octeon_rx_tx_delay(eth, 0xc, 0x0c);
0629                 return;
0630             } else if (port == 1) {
0631                 /* Different config for switch port. */
0632                 _octeon_rx_tx_delay(eth, 0x0, 0x0);
0633                 return;
0634             }
0635         }
0636         break;
0637     case CVMX_BOARD_TYPE_UBNT_E100:
0638         if (iface == 0 && port <= 2) {
0639             _octeon_rx_tx_delay(eth, 0x0, 0x10);
0640             return;
0641         }
0642         break;
0643     }
0644     fdt_nop_property(initial_boot_params, eth, "rx-delay");
0645     fdt_nop_property(initial_boot_params, eth, "tx-delay");
0646 }
0647 
0648 static void __init octeon_fdt_pip_port(int iface, int i, int p, int max)
0649 {
0650     char name_buffer[20];
0651     int eth;
0652     int phy_addr;
0653     int ipd_port;
0654     int fixed_link;
0655 
0656     snprintf(name_buffer, sizeof(name_buffer), "ethernet@%x", p);
0657     eth = fdt_subnode_offset(initial_boot_params, iface, name_buffer);
0658     if (eth < 0)
0659         return;
0660     if (p > max) {
0661         pr_debug("Deleting port %x:%x\n", i, p);
0662         octeon_fdt_rm_ethernet(eth);
0663         return;
0664     }
0665     if (OCTEON_IS_MODEL(OCTEON_CN68XX))
0666         ipd_port = (0x100 * i) + (0x10 * p) + 0x800;
0667     else
0668         ipd_port = 16 * i + p;
0669 
0670     phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
0671     octeon_fdt_set_phy(eth, phy_addr);
0672 
0673     fixed_link = fdt_subnode_offset(initial_boot_params, eth, "fixed-link");
0674     if (fixed_link < 0)
0675         WARN_ON(octeon_has_fixed_link(ipd_port));
0676     else if (!octeon_has_fixed_link(ipd_port))
0677         fdt_nop_node(initial_boot_params, fixed_link);
0678     octeon_rx_tx_delay(eth, i, p);
0679 }
0680 
0681 static void __init octeon_fdt_pip_iface(int pip, int idx)
0682 {
0683     char name_buffer[20];
0684     int iface;
0685     int p;
0686     int count = 0;
0687 
0688     snprintf(name_buffer, sizeof(name_buffer), "interface@%d", idx);
0689     iface = fdt_subnode_offset(initial_boot_params, pip, name_buffer);
0690     if (iface < 0)
0691         return;
0692 
0693     if (cvmx_helper_interface_enumerate(idx) == 0)
0694         count = cvmx_helper_ports_on_interface(idx);
0695 
0696     for (p = 0; p < 16; p++)
0697         octeon_fdt_pip_port(iface, idx, p, count - 1);
0698 }
0699 
0700 void __init octeon_fill_mac_addresses(void)
0701 {
0702     const char *alias_prop;
0703     char name_buffer[20];
0704     u64 mac_addr_base;
0705     int aliases;
0706     int pip;
0707     int i;
0708 
0709     aliases = fdt_path_offset(initial_boot_params, "/aliases");
0710     if (aliases < 0)
0711         return;
0712 
0713     mac_addr_base =
0714         ((octeon_bootinfo->mac_addr_base[0] & 0xffull)) << 40 |
0715         ((octeon_bootinfo->mac_addr_base[1] & 0xffull)) << 32 |
0716         ((octeon_bootinfo->mac_addr_base[2] & 0xffull)) << 24 |
0717         ((octeon_bootinfo->mac_addr_base[3] & 0xffull)) << 16 |
0718         ((octeon_bootinfo->mac_addr_base[4] & 0xffull)) << 8 |
0719          (octeon_bootinfo->mac_addr_base[5] & 0xffull);
0720 
0721     for (i = 0; i < 2; i++) {
0722         int mgmt;
0723 
0724         snprintf(name_buffer, sizeof(name_buffer), "mix%d", i);
0725         alias_prop = fdt_getprop(initial_boot_params, aliases,
0726                      name_buffer, NULL);
0727         if (!alias_prop)
0728             continue;
0729         mgmt = fdt_path_offset(initial_boot_params, alias_prop);
0730         if (mgmt < 0)
0731             continue;
0732         octeon_fdt_set_mac_addr(mgmt, &mac_addr_base);
0733     }
0734 
0735     alias_prop = fdt_getprop(initial_boot_params, aliases, "pip", NULL);
0736     if (!alias_prop)
0737         return;
0738 
0739     pip = fdt_path_offset(initial_boot_params, alias_prop);
0740     if (pip < 0)
0741         return;
0742 
0743     for (i = 0; i <= 4; i++) {
0744         int iface;
0745         int p;
0746 
0747         snprintf(name_buffer, sizeof(name_buffer), "interface@%d", i);
0748         iface = fdt_subnode_offset(initial_boot_params, pip,
0749                        name_buffer);
0750         if (iface < 0)
0751             continue;
0752         for (p = 0; p < 16; p++) {
0753             int eth;
0754 
0755             snprintf(name_buffer, sizeof(name_buffer),
0756                  "ethernet@%x", p);
0757             eth = fdt_subnode_offset(initial_boot_params, iface,
0758                          name_buffer);
0759             if (eth < 0)
0760                 continue;
0761             octeon_fdt_set_mac_addr(eth, &mac_addr_base);
0762         }
0763     }
0764 }
0765 
0766 int __init octeon_prune_device_tree(void)
0767 {
0768     int i, max_port, uart_mask;
0769     const char *pip_path;
0770     const char *alias_prop;
0771     char name_buffer[20];
0772     int aliases;
0773 
0774     if (fdt_check_header(initial_boot_params))
0775         panic("Corrupt Device Tree.");
0776 
0777     WARN(octeon_bootinfo->board_type == CVMX_BOARD_TYPE_CUST_DSR1000N,
0778          "Built-in DTB booting is deprecated on %s. Please switch to use appended DTB.",
0779          cvmx_board_type_to_string(octeon_bootinfo->board_type));
0780 
0781     aliases = fdt_path_offset(initial_boot_params, "/aliases");
0782     if (aliases < 0) {
0783         pr_err("Error: No /aliases node in device tree.");
0784         return -EINVAL;
0785     }
0786 
0787     if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN63XX))
0788         max_port = 2;
0789     else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN68XX))
0790         max_port = 1;
0791     else
0792         max_port = 0;
0793 
0794     if (octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC10E)
0795         max_port = 0;
0796 
0797     for (i = 0; i < 2; i++) {
0798         int mgmt;
0799 
0800         snprintf(name_buffer, sizeof(name_buffer),
0801              "mix%d", i);
0802         alias_prop = fdt_getprop(initial_boot_params, aliases,
0803                     name_buffer, NULL);
0804         if (alias_prop) {
0805             mgmt = fdt_path_offset(initial_boot_params, alias_prop);
0806             if (mgmt < 0)
0807                 continue;
0808             if (i >= max_port) {
0809                 pr_debug("Deleting mix%d\n", i);
0810                 octeon_fdt_rm_ethernet(mgmt);
0811                 fdt_nop_property(initial_boot_params, aliases,
0812                          name_buffer);
0813             } else {
0814                 int phy_addr = cvmx_helper_board_get_mii_address(CVMX_HELPER_BOARD_MGMT_IPD_PORT + i);
0815 
0816                 octeon_fdt_set_phy(mgmt, phy_addr);
0817             }
0818         }
0819     }
0820 
0821     pip_path = fdt_getprop(initial_boot_params, aliases, "pip", NULL);
0822     if (pip_path) {
0823         int pip = fdt_path_offset(initial_boot_params, pip_path);
0824 
0825         if (pip  >= 0)
0826             for (i = 0; i <= 4; i++)
0827                 octeon_fdt_pip_iface(pip, i);
0828     }
0829 
0830     /* I2C */
0831     if (OCTEON_IS_MODEL(OCTEON_CN52XX) ||
0832         OCTEON_IS_MODEL(OCTEON_CN63XX) ||
0833         OCTEON_IS_MODEL(OCTEON_CN68XX) ||
0834         OCTEON_IS_MODEL(OCTEON_CN56XX))
0835         max_port = 2;
0836     else
0837         max_port = 1;
0838 
0839     for (i = 0; i < 2; i++) {
0840         int i2c;
0841 
0842         snprintf(name_buffer, sizeof(name_buffer),
0843              "twsi%d", i);
0844         alias_prop = fdt_getprop(initial_boot_params, aliases,
0845                     name_buffer, NULL);
0846 
0847         if (alias_prop) {
0848             i2c = fdt_path_offset(initial_boot_params, alias_prop);
0849             if (i2c < 0)
0850                 continue;
0851             if (i >= max_port) {
0852                 pr_debug("Deleting twsi%d\n", i);
0853                 fdt_nop_node(initial_boot_params, i2c);
0854                 fdt_nop_property(initial_boot_params, aliases,
0855                          name_buffer);
0856             }
0857         }
0858     }
0859 
0860     /* SMI/MDIO */
0861     if (OCTEON_IS_MODEL(OCTEON_CN68XX))
0862         max_port = 4;
0863     else if (OCTEON_IS_MODEL(OCTEON_CN52XX) ||
0864          OCTEON_IS_MODEL(OCTEON_CN63XX) ||
0865          OCTEON_IS_MODEL(OCTEON_CN56XX))
0866         max_port = 2;
0867     else
0868         max_port = 1;
0869 
0870     for (i = 0; i < 2; i++) {
0871         int i2c;
0872 
0873         snprintf(name_buffer, sizeof(name_buffer),
0874              "smi%d", i);
0875         alias_prop = fdt_getprop(initial_boot_params, aliases,
0876                     name_buffer, NULL);
0877         if (alias_prop) {
0878             i2c = fdt_path_offset(initial_boot_params, alias_prop);
0879             if (i2c < 0)
0880                 continue;
0881             if (i >= max_port) {
0882                 pr_debug("Deleting smi%d\n", i);
0883                 fdt_nop_node(initial_boot_params, i2c);
0884                 fdt_nop_property(initial_boot_params, aliases,
0885                          name_buffer);
0886             }
0887         }
0888     }
0889 
0890     /* Serial */
0891     uart_mask = 3;
0892 
0893     /* Right now CN52XX is the only chip with a third uart */
0894     if (OCTEON_IS_MODEL(OCTEON_CN52XX))
0895         uart_mask |= 4; /* uart2 */
0896 
0897     for (i = 0; i < 3; i++) {
0898         int uart;
0899 
0900         snprintf(name_buffer, sizeof(name_buffer),
0901              "uart%d", i);
0902         alias_prop = fdt_getprop(initial_boot_params, aliases,
0903                     name_buffer, NULL);
0904 
0905         if (alias_prop) {
0906             uart = fdt_path_offset(initial_boot_params, alias_prop);
0907             if (uart_mask & (1 << i)) {
0908                 __be32 f;
0909 
0910                 f = cpu_to_be32(octeon_get_io_clock_rate());
0911                 fdt_setprop_inplace(initial_boot_params,
0912                             uart, "clock-frequency",
0913                             &f, sizeof(f));
0914                 continue;
0915             }
0916             pr_debug("Deleting uart%d\n", i);
0917             fdt_nop_node(initial_boot_params, uart);
0918             fdt_nop_property(initial_boot_params, aliases,
0919                      name_buffer);
0920         }
0921     }
0922 
0923     /* Compact Flash */
0924     alias_prop = fdt_getprop(initial_boot_params, aliases,
0925                  "cf0", NULL);
0926     if (alias_prop) {
0927         union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
0928         unsigned long base_ptr, region_base, region_size;
0929         unsigned long region1_base = 0;
0930         unsigned long region1_size = 0;
0931         int cs, bootbus;
0932         bool is_16bit = false;
0933         bool is_true_ide = false;
0934         __be32 new_reg[6];
0935         __be32 *ranges;
0936         int len;
0937 
0938         int cf = fdt_path_offset(initial_boot_params, alias_prop);
0939 
0940         base_ptr = 0;
0941         if (octeon_bootinfo->major_version == 1
0942             && octeon_bootinfo->minor_version >= 1) {
0943             if (octeon_bootinfo->compact_flash_common_base_addr)
0944                 base_ptr = octeon_bootinfo->compact_flash_common_base_addr;
0945         } else {
0946             base_ptr = 0x1d000800;
0947         }
0948 
0949         if (!base_ptr)
0950             goto no_cf;
0951 
0952         /* Find CS0 region. */
0953         for (cs = 0; cs < 8; cs++) {
0954             mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
0955             region_base = mio_boot_reg_cfg.s.base << 16;
0956             region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
0957             if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
0958                 && base_ptr < region_base + region_size) {
0959                 is_16bit = mio_boot_reg_cfg.s.width;
0960                 break;
0961             }
0962         }
0963         if (cs >= 7) {
0964             /* cs and cs + 1 are CS0 and CS1, both must be less than 8. */
0965             goto no_cf;
0966         }
0967 
0968         if (!(base_ptr & 0xfffful)) {
0969             /*
0970              * Boot loader signals availability of DMA (true_ide
0971              * mode) by setting low order bits of base_ptr to
0972              * zero.
0973              */
0974 
0975             /* Asume that CS1 immediately follows. */
0976             mio_boot_reg_cfg.u64 =
0977                 cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs + 1));
0978             region1_base = mio_boot_reg_cfg.s.base << 16;
0979             region1_size = (mio_boot_reg_cfg.s.size + 1) << 16;
0980             if (!mio_boot_reg_cfg.s.en)
0981                 goto no_cf;
0982             is_true_ide = true;
0983 
0984         } else {
0985             fdt_nop_property(initial_boot_params, cf, "cavium,true-ide");
0986             fdt_nop_property(initial_boot_params, cf, "cavium,dma-engine-handle");
0987             if (!is_16bit) {
0988                 __be32 width = cpu_to_be32(8);
0989 
0990                 fdt_setprop_inplace(initial_boot_params, cf,
0991                         "cavium,bus-width", &width, sizeof(width));
0992             }
0993         }
0994         new_reg[0] = cpu_to_be32(cs);
0995         new_reg[1] = cpu_to_be32(0);
0996         new_reg[2] = cpu_to_be32(0x10000);
0997         new_reg[3] = cpu_to_be32(cs + 1);
0998         new_reg[4] = cpu_to_be32(0);
0999         new_reg[5] = cpu_to_be32(0x10000);
1000         fdt_setprop_inplace(initial_boot_params, cf,
1001                     "reg",  new_reg, sizeof(new_reg));
1002 
1003         bootbus = fdt_parent_offset(initial_boot_params, cf);
1004         if (bootbus < 0)
1005             goto no_cf;
1006         ranges = fdt_getprop_w(initial_boot_params, bootbus, "ranges", &len);
1007         if (!ranges || len < (5 * 8 * sizeof(__be32)))
1008             goto no_cf;
1009 
1010         ranges[(cs * 5) + 2] = cpu_to_be32(region_base >> 32);
1011         ranges[(cs * 5) + 3] = cpu_to_be32(region_base & 0xffffffff);
1012         ranges[(cs * 5) + 4] = cpu_to_be32(region_size);
1013         if (is_true_ide) {
1014             cs++;
1015             ranges[(cs * 5) + 2] = cpu_to_be32(region1_base >> 32);
1016             ranges[(cs * 5) + 3] = cpu_to_be32(region1_base & 0xffffffff);
1017             ranges[(cs * 5) + 4] = cpu_to_be32(region1_size);
1018         }
1019         goto end_cf;
1020 no_cf:
1021         fdt_nop_node(initial_boot_params, cf);
1022 
1023 end_cf:
1024         ;
1025     }
1026 
1027     /* 8 char LED */
1028     alias_prop = fdt_getprop(initial_boot_params, aliases,
1029                  "led0", NULL);
1030     if (alias_prop) {
1031         union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
1032         unsigned long base_ptr, region_base, region_size;
1033         int cs, bootbus;
1034         __be32 new_reg[6];
1035         __be32 *ranges;
1036         int len;
1037         int led = fdt_path_offset(initial_boot_params, alias_prop);
1038 
1039         base_ptr = octeon_bootinfo->led_display_base_addr;
1040         if (base_ptr == 0)
1041             goto no_led;
1042         /* Find CS0 region. */
1043         for (cs = 0; cs < 8; cs++) {
1044             mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
1045             region_base = mio_boot_reg_cfg.s.base << 16;
1046             region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
1047             if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
1048                 && base_ptr < region_base + region_size)
1049                 break;
1050         }
1051 
1052         if (cs > 7)
1053             goto no_led;
1054 
1055         new_reg[0] = cpu_to_be32(cs);
1056         new_reg[1] = cpu_to_be32(0x20);
1057         new_reg[2] = cpu_to_be32(0x20);
1058         new_reg[3] = cpu_to_be32(cs);
1059         new_reg[4] = cpu_to_be32(0);
1060         new_reg[5] = cpu_to_be32(0x20);
1061         fdt_setprop_inplace(initial_boot_params, led,
1062                     "reg",  new_reg, sizeof(new_reg));
1063 
1064         bootbus = fdt_parent_offset(initial_boot_params, led);
1065         if (bootbus < 0)
1066             goto no_led;
1067         ranges = fdt_getprop_w(initial_boot_params, bootbus, "ranges", &len);
1068         if (!ranges || len < (5 * 8 * sizeof(__be32)))
1069             goto no_led;
1070 
1071         ranges[(cs * 5) + 2] = cpu_to_be32(region_base >> 32);
1072         ranges[(cs * 5) + 3] = cpu_to_be32(region_base & 0xffffffff);
1073         ranges[(cs * 5) + 4] = cpu_to_be32(region_size);
1074         goto end_led;
1075 
1076 no_led:
1077         fdt_nop_node(initial_boot_params, led);
1078 end_led:
1079         ;
1080     }
1081 
1082 #ifdef CONFIG_USB
1083     /* OHCI/UHCI USB */
1084     alias_prop = fdt_getprop(initial_boot_params, aliases,
1085                  "uctl", NULL);
1086     if (alias_prop) {
1087         int uctl = fdt_path_offset(initial_boot_params, alias_prop);
1088 
1089         if (uctl >= 0 && (!OCTEON_IS_MODEL(OCTEON_CN6XXX) ||
1090                   octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC2E)) {
1091             pr_debug("Deleting uctl\n");
1092             fdt_nop_node(initial_boot_params, uctl);
1093             fdt_nop_property(initial_boot_params, aliases, "uctl");
1094         } else if (octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC10E ||
1095                octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC4E) {
1096             /* Missing "refclk-type" defaults to crystal. */
1097             fdt_nop_property(initial_boot_params, uctl, "refclk-type");
1098         }
1099     }
1100 
1101     /* DWC2 USB */
1102     alias_prop = fdt_getprop(initial_boot_params, aliases,
1103                  "usbn", NULL);
1104     if (alias_prop) {
1105         int usbn = fdt_path_offset(initial_boot_params, alias_prop);
1106 
1107         if (usbn >= 0 && (current_cpu_type() == CPU_CAVIUM_OCTEON2 ||
1108                   !octeon_has_feature(OCTEON_FEATURE_USB))) {
1109             pr_debug("Deleting usbn\n");
1110             fdt_nop_node(initial_boot_params, usbn);
1111             fdt_nop_property(initial_boot_params, aliases, "usbn");
1112         } else  {
1113             __be32 new_f[1];
1114             enum cvmx_helper_board_usb_clock_types c;
1115 
1116             c = __cvmx_helper_board_usb_get_clock_type();
1117             switch (c) {
1118             case USB_CLOCK_TYPE_REF_48:
1119                 new_f[0] = cpu_to_be32(48000000);
1120                 fdt_setprop_inplace(initial_boot_params, usbn,
1121                             "refclk-frequency",  new_f, sizeof(new_f));
1122                 fallthrough;
1123             case USB_CLOCK_TYPE_REF_12:
1124                 /* Missing "refclk-type" defaults to external. */
1125                 fdt_nop_property(initial_boot_params, usbn, "refclk-type");
1126                 break;
1127             default:
1128                 break;
1129             }
1130         }
1131     }
1132 #endif
1133 
1134     return 0;
1135 }
1136 
1137 static int __init octeon_publish_devices(void)
1138 {
1139     return of_platform_populate(NULL, octeon_ids, NULL, NULL);
1140 }
1141 arch_initcall(octeon_publish_devices);