]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - board/freescale/mpc8569mds/mpc8569mds.c
Merge branch 'master' of git://git.denx.de/u-boot-samsung
[karo-tx-uboot.git] / board / freescale / mpc8569mds / mpc8569mds.c
index cc8873117ef7411fa9a67dd4176c35bc34e46a1a..dc0884e7bf19a4c2ab91ac8a2da046e9d6fde7e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009 Freescale Semiconductor.
+ * Copyright 2009-2010 Freescale Semiconductor.
  *
  * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com>
  *
  */
 
 #include <common.h>
+#include <hwconfig.h>
 #include <pci.h>
 #include <asm/processor.h>
 #include <asm/mmu.h>
+#include <asm/cache.h>
 #include <asm/immap_85xx.h>
 #include <asm/fsl_pci.h>
 #include <asm/fsl_ddr_sdram.h>
 #include <ioports.h>
 #include <libfdt.h>
 #include <fdt_support.h>
+#include <fsl_esdhc.h>
 
 #include "bcsr.h"
+#if defined(CONFIG_PQ_MDS_PIB)
+#include "../common/pq-mds-pib.h"
+#endif
 
 phys_size_t fixed_sdram(void);
 
@@ -152,6 +158,27 @@ const qe_iop_conf_t qe_iop_conf_tab[] = {
        {5, 10, 2, 0, 3}, /* UART1_CTS_B */
        {5, 11, 1, 0, 2}, /* UART1_RTS_B */
 
+       /* QE UART                                     */
+       {0, 19, 1, 0, 2}, /* QEUART_TX                 */
+       {1, 17, 2, 0, 3}, /* QEUART_RX                 */
+       {0, 25, 1, 0, 1}, /* QEUART_RTS                */
+       {1, 23, 2, 0, 1}, /* QEUART_CTS                */
+
+       /* QE USB                                      */
+       {5,  3, 1, 0, 1}, /* USB_OE                    */
+       {5,  4, 1, 0, 2}, /* USB_TP                    */
+       {5,  5, 1, 0, 2}, /* USB_TN                    */
+       {5,  6, 2, 0, 2}, /* USB_RP                    */
+       {5,  7, 2, 0, 1}, /* USB_RX                    */
+       {5,  8, 2, 0, 1}, /* USB_RN                    */
+       {2,  4, 2, 0, 2}, /* CLK5                      */
+
+       /* SPI Flash, M25P40                           */
+       {4, 27, 3, 0, 1}, /* SPI_MOSI                  */
+       {4, 28, 3, 0, 1}, /* SPI_MISO                  */
+       {4, 29, 3, 0, 1}, /* SPI_CLK                   */
+       {4, 30, 1, 0, 0}, /* SPI_SEL, GPIO             */
+
        {0,  0, 0, 0, QE_IOP_TAB_END} /* END of table */
 };
 
@@ -185,6 +212,31 @@ int board_early_init_f (void)
        return 0;
 }
 
+int board_early_init_r(void)
+{
+       const unsigned int flashbase = CONFIG_SYS_NAND_BASE;
+       const u8 flash_esel = 0;
+
+       /*
+        * Remap Boot flash to caching-inhibited
+        * so that flash can be erased properly.
+        */
+
+       /* Flush d-cache and invalidate i-cache of any FLASH data */
+       flush_dcache();
+       invalidate_icache();
+
+       /* invalidate existing TLB entry for flash */
+       disable_tlb(flash_esel);
+
+       set_tlb(1, flashbase, CONFIG_SYS_NAND_BASE,     /* tlb, epn, rpn */
+               MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, /* perms, wimge */
+               0, flash_esel,                          /* ts, esel */
+               BOOKE_PAGESZ_64M, 1);                   /* tsize, iprot */
+
+       return 0;
+}
+
 int checkboard (void)
 {
        printf ("Board: 8569 MDS\n");
@@ -282,7 +334,7 @@ void
 local_bus_init(void)
 {
        volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
-       volatile ccsr_lbc_t *lbc = (void *)(CONFIG_SYS_MPC85xx_LBC_ADDR);
+       volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
 
        uint clkdiv;
        uint lbc_hz;
@@ -303,81 +355,249 @@ local_bus_init(void)
        out_be32(&lbc->lcrr, (u32)in_be32(&lbc->lcrr)| 0x00030000);
 }
 
-#ifdef CONFIG_PCIE1
-static struct pci_controller pcie1_hose;
-#endif  /* CONFIG_PCIE1 */
+static void fdt_board_disable_serial(void *blob, bd_t *bd, const char *alias)
+{
+       const char *status = "disabled";
+       int off;
+       int err;
+
+       off = fdt_path_offset(blob, alias);
+       if (off < 0) {
+               printf("WARNING: could not find %s alias: %s.\n", alias,
+                       fdt_strerror(off));
+               return;
+       }
 
-int first_free_busno = 0;
+       err = fdt_setprop(blob, off, "status", status, strlen(status) + 1);
+       if (err) {
+               printf("WARNING: could not set status for serial0: %s.\n",
+                       fdt_strerror(err));
+               return;
+       }
+}
 
-#ifdef CONFIG_PCI
-void
-pci_init_board(void)
+/*
+ * Because of an erratum in prototype boards it is impossible to use eSDHC
+ * without disabling UART0 (which makes it quite easy to 'brick' the board
+ * by simply issung 'setenv hwconfig esdhc', and not able to interact with
+ * U-Boot anylonger).
+ *
+ * So, but default we assume that the board is a prototype, which is a most
+ * safe assumption. There is no way to determine board revision from a
+ * register, so we use hwconfig.
+ */
+
+static int prototype_board(void)
 {
-       volatile ccsr_gur_t *gur;
-       uint io_sel;
-       uint host_agent;
+       if (hwconfig_subarg("board", "rev", NULL))
+               return hwconfig_subarg_cmp("board", "rev", "prototype");
+       return 1;
+}
 
-       gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
-       io_sel = (gur->pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 19;
-       host_agent = (gur->porbmsr & MPC85xx_PORBMSR_HA) >> 16;
+static int esdhc_disables_uart0(void)
+{
+       return prototype_board() ||
+              hwconfig_subarg_cmp("esdhc", "mode", "4-bits");
+}
 
-#ifdef CONFIG_PCIE1
+static void fdt_board_fixup_qe_uart(void *blob, bd_t *bd)
 {
-       volatile ccsr_fsl_pci_t *pci;
-       struct pci_controller *hose;
-       int pcie_ep;
-       struct pci_region *r;
-       int pcie_configured;
-
-       pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR;
-       hose = &pcie1_hose;
-       pcie_ep = is_fsl_pci_agent(LAW_TRGT_IF_PCIE_1, host_agent);
-       r = hose->regions;
-       pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_1, io_sel);
+       u8 *bcsr = (u8 *)CONFIG_SYS_BCSR_BASE;
+       const char *devtype = "serial";
+       const char *compat = "ucc_uart";
+       const char *clk = "brg9";
+       u32 portnum = 0;
+       int off = -1;
+
+       if (!hwconfig("qe_uart"))
+               return;
+
+       if (hwconfig("esdhc") && esdhc_disables_uart0()) {
+               printf("QE UART: won't enable with esdhc.\n");
+               return;
+       }
+
+       fdt_board_disable_serial(blob, bd, "serial1");
 
-       if (pcie_configured && !(gur->devdisr & MPC85xx_DEVDISR_PCIE)){
-               printf ("\n    PCIE connected to slot as %s (base address %x)",
-                       pcie_ep ? "End Point" : "Root Complex",
-                       (uint)pci);
+       while (1) {
+               const u32 *idx;
+               int len;
 
-               if (pci->pme_msg_det) {
-                       pci->pme_msg_det = 0xffffffff;
-                       debug (" with errors.  Clearing. Now 0x%08x",
-                               pci->pme_msg_det);
+               off = fdt_node_offset_by_compatible(blob, off, "ucc_geth");
+               if (off < 0) {
+                       printf("WARNING: unable to fixup device tree for "
+                               "QE UART\n");
+                       return;
                }
-               printf ("\n");
 
-               /* outbound memory */
-               pci_set_region(r++,
-                               CONFIG_SYS_PCIE1_MEM_BUS,
-                               CONFIG_SYS_PCIE1_MEM_PHYS,
-                               CONFIG_SYS_PCIE1_MEM_SIZE,
-                               PCI_REGION_MEM);
+               idx = fdt_getprop(blob, off, "cell-index", &len);
+               if (!idx || len != sizeof(*idx) || *idx != fdt32_to_cpu(2))
+                       continue;
+               break;
+       }
+
+       fdt_setprop(blob, off, "device_type", devtype, strlen(devtype) + 1);
+       fdt_setprop(blob, off, "compatible", compat, strlen(compat) + 1);
+       fdt_setprop(blob, off, "tx-clock-name", clk, strlen(clk) + 1);
+       fdt_setprop(blob, off, "rx-clock-name", clk, strlen(clk) + 1);
+       fdt_setprop(blob, off, "port-number", &portnum, sizeof(portnum));
+
+       setbits_8(&bcsr[15], BCSR15_QEUART_EN);
+}
+
+#ifdef CONFIG_FSL_ESDHC
+
+int board_mmc_init(bd_t *bd)
+{
+       struct ccsr_gur *gur = (struct ccsr_gur *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
+       u8 *bcsr = (u8 *)CONFIG_SYS_BCSR_BASE;
+       u8 bcsr6 = BCSR6_SD_CARD_1BIT;
+
+       if (!hwconfig("esdhc"))
+               return 0;
+
+       printf("Enabling eSDHC...\n"
+              "  For eSDHC to function, I2C2 ");
+       if (esdhc_disables_uart0()) {
+               printf("and UART0 should be disabled.\n");
+               printf("  Redirecting stderr, stdout and stdin to UART1...\n");
+               console_assign(stderr, "eserial1");
+               console_assign(stdout, "eserial1");
+               console_assign(stdin, "eserial1");
+               printf("Switched to UART1 (initial log has been printed to "
+                      "UART0).\n");
+
+               clrsetbits_be32(&gur->plppar1, PLPPAR1_UART0_BIT_MASK,
+                                              PLPPAR1_ESDHC_4BITS_VAL);
+               clrsetbits_be32(&gur->plpdir1, PLPDIR1_UART0_BIT_MASK,
+                                              PLPDIR1_ESDHC_4BITS_VAL);
+               bcsr6 |= BCSR6_SD_CARD_4BITS;
+       } else {
+               printf("should be disabled.\n");
+       }
+
+       /* Assign I2C2 signals to eSDHC. */
+       clrsetbits_be32(&gur->plppar1, PLPPAR1_I2C_BIT_MASK,
+                                      PLPPAR1_ESDHC_VAL);
+       clrsetbits_be32(&gur->plpdir1, PLPDIR1_I2C_BIT_MASK,
+                                      PLPDIR1_ESDHC_VAL);
 
-               /* outbound io */
-               pci_set_region(r++,
-                               CONFIG_SYS_PCIE1_IO_BUS,
-                               CONFIG_SYS_PCIE1_IO_PHYS,
-                               CONFIG_SYS_PCIE1_IO_SIZE,
-                               PCI_REGION_IO);
+       /* Mux I2C2 (and optionally UART0) signals to eSDHC. */
+       setbits_8(&bcsr[6], bcsr6);
 
-               hose->region_count = r - hose->regions;
+       return fsl_esdhc_mmc_init(bd);
+}
+
+static void fdt_board_fixup_esdhc(void *blob, bd_t *bd)
+{
+       const char *status = "disabled";
+       int off = -1;
 
-               hose->first_busno=first_free_busno;
+       if (!hwconfig("esdhc"))
+               return;
 
-               fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
-               printf ("PCIE on bus %02x - %02x\n",
-                               hose->first_busno,hose->last_busno);
+       if (esdhc_disables_uart0())
+               fdt_board_disable_serial(blob, bd, "serial0");
+
+       while (1) {
+               const u32 *idx;
+               int len;
+
+               off = fdt_node_offset_by_compatible(blob, off, "fsl-i2c");
+               if (off < 0)
+                       break;
+
+               idx = fdt_getprop(blob, off, "cell-index", &len);
+               if (!idx || len != sizeof(*idx))
+                       continue;
+
+               if (*idx == 1) {
+                       fdt_setprop(blob, off, "status", status,
+                                   strlen(status) + 1);
+                       break;
+               }
+       }
 
-               first_free_busno=hose->last_busno+1;
+       if (hwconfig_subarg_cmp("esdhc", "mode", "4-bits")) {
+               off = fdt_node_offset_by_compatible(blob, -1, "fsl,esdhc");
+               if (off < 0) {
+                       printf("WARNING: could not find esdhc node\n");
+                       return;
+               }
+               fdt_delprop(blob, off, "sdhci,1-bit-only");
+       }
+}
+#else
+static inline void fdt_board_fixup_esdhc(void *blob, bd_t *bd) {}
+#endif
 
+static void fdt_board_fixup_qe_usb(void *blob, bd_t *bd)
+{
+       u8 *bcsr = (u8 *)CONFIG_SYS_BCSR_BASE;
+
+       if (hwconfig_subarg_cmp("qe_usb", "speed", "low"))
+               clrbits_8(&bcsr[17], BCSR17_nUSBLOWSPD);
+       else
+               setbits_8(&bcsr[17], BCSR17_nUSBLOWSPD);
+
+       if (hwconfig_subarg_cmp("qe_usb", "mode", "peripheral")) {
+               clrbits_8(&bcsr[17], BCSR17_USBVCC);
+               clrbits_8(&bcsr[17], BCSR17_USBMODE);
+               do_fixup_by_compat(blob, "fsl,mpc8569-qe-usb", "mode",
+                                  "peripheral", sizeof("peripheral"), 1);
        } else {
-               printf ("    PCIE: disabled\n");
+               setbits_8(&bcsr[17], BCSR17_USBVCC);
+               setbits_8(&bcsr[17], BCSR17_USBMODE);
        }
+
+       clrbits_8(&bcsr[17], BCSR17_nUSBEN);
 }
+
+#ifdef CONFIG_PCIE1
+static struct pci_controller pcie1_hose;
+#endif  /* CONFIG_PCIE1 */
+
+#ifdef CONFIG_PCI
+void pci_init_board(void)
+{
+       volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+       struct fsl_pci_info pci_info[1];
+       u32 devdisr, pordevsr, io_sel;
+       int first_free_busno = 0;
+       int num = 0;
+
+       int pcie_ep, pcie_configured;
+
+       devdisr = in_be32(&gur->devdisr);
+       pordevsr = in_be32(&gur->pordevsr);
+       io_sel = (pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 19;
+
+       debug ("   pci_init_board: devdisr=%x, io_sel=%x\n", devdisr, io_sel);
+
+#if defined(CONFIG_PQ_MDS_PIB)
+       pib_init();
+#endif
+
+#ifdef CONFIG_PCIE1
+       pcie_configured = is_fsl_pci_cfg(LAW_TRGT_IF_PCIE_1, io_sel);
+
+       if (pcie_configured && !(devdisr & MPC85xx_DEVDISR_PCIE)){
+               SET_STD_PCIE_INFO(pci_info[num], 1);
+               pcie_ep = fsl_setup_hose(&pcie1_hose, pci_info[num].regs);
+               printf("PCIE1: connected to Slot as %s (base addr %lx)\n",
+                       pcie_ep ? "Endpoint" : "Root Complex",
+                       pci_info[num].regs);
+               first_free_busno = fsl_pci_init_port(&pci_info[num++],
+                                       &pcie1_hose, first_free_busno);
+       } else {
+               printf("PCIE1: disabled\n");
+       }
+
+       puts("\n");
 #else
-       gur->devdisr |= MPC85xx_DEVDISR_PCIE; /* disable */
+       setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCIE); /* disable */
 #endif
+
 }
 #endif /* CONFIG_PCI */
 
@@ -402,8 +622,8 @@ void ft_board_setup(void *blob, bd_t *bd)
                        break;
                }
 
-               err = fdt_setprop_string(blob, nodeoff, "phy-connection-type",
-                                       "rmii");
+               err = fdt_fixup_phy_connection(blob, nodeoff, RMII);
+
                if (err < 0) {
                        printf("WARNING: could not set phy-connection-type "
                                "%s.\n", fdt_strerror(err));
@@ -441,8 +661,10 @@ void ft_board_setup(void *blob, bd_t *bd)
 #endif
        ft_cpu_setup(blob, bd);
 
-#ifdef CONFIG_PCIE1
-       ft_fsl_pci_setup(blob, "pci1", &pcie1_hose);
-#endif
+       FT_FSL_PCI_SETUP;
+
+       fdt_board_fixup_esdhc(blob, bd);
+       fdt_board_fixup_qe_uart(blob, bd);
+       fdt_board_fixup_qe_usb(blob, bd);
 }
 #endif