From: Damien Dusha <d.dusha@gmail.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH] Add support for the MPC5121e USB Host controller.
Date: Sun, 22 Aug 2010 15:41:54 +1000 [thread overview]
Message-ID: <1282455714-12834-1-git-send-email-d.dusha@gmail.com> (raw)
Add support for the USB Host controller of the MPC5121e, based on the original patch by Francesco Rendine [1].
The patch configures the USB Host controller and the on-board UTMI phy, including the Freescale-specific registers as per the Linux kernel driver.
Tested on the MPC5121ADS platform with various USB mass storage devices.
[1] http://lists.denx.de/pipermail/u-boot/2009-June/055022.html
Signed-off-by: Damien Dusha <d.dusha@gmail.com>
---
arch/powerpc/include/asm/immap_512x.h | 4 +
board/freescale/mpc5121ads/mpc5121ads.c | 4 +-
drivers/usb/host/ehci-fsl.c | 137 ++++++++++++++++++++++++++++-
drivers/usb/host/ehci.h | 5 +
include/configs/mpc5121ads.h | 22 +++++-
include/usb/ehci-fsl.h | 149 +++++++++++++++++++++++++------
6 files changed, 292 insertions(+), 29 deletions(-)
diff --git a/arch/powerpc/include/asm/immap_512x.h b/arch/powerpc/include/asm/immap_512x.h
index 7f9db8b..4923a17 100644
--- a/arch/powerpc/include/asm/immap_512x.h
+++ b/arch/powerpc/include/asm/immap_512x.h
@@ -1246,4 +1246,8 @@ static inline u32 get_pata_base (void)
}
#endif /* __ASSEMBLY__ */
+#define CONFIG_SYS_MPC512x_USB_OFFSET 0x4000
+#define CONFIG_SYS_MPC512x_USB_ADDR \
+ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC512x_USB_OFFSET)
+
#endif /* __IMMAP_512x__ */
diff --git a/board/freescale/mpc5121ads/mpc5121ads.c b/board/freescale/mpc5121ads/mpc5121ads.c
index 2e13ea8..4c0caa7 100644
--- a/board/freescale/mpc5121ads/mpc5121ads.c
+++ b/board/freescale/mpc5121ads/mpc5121ads.c
@@ -53,7 +53,9 @@ DECLARE_GLOBAL_DATA_PTR;
#define SCCR2_CLOCKS_EN (CLOCK_SCCR2_DIU_EN | \
CLOCK_SCCR2_I2C_EN | \
CLOCK_SCCR2_MEM_EN | \
- CLOCK_SCCR2_SPDIF_EN)
+ CLOCK_SCCR2_SPDIF_EN | \
+ CLOCK_SCCR2_USB1_EN | \
+ CLOCK_SCCR2_USB2_EN)
void __mpc5121_nfc_select_chip(struct mtd_info *mtd, int chip);
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index c674929..d7b07ca 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -1,4 +1,9 @@
/*
+ * (C) Copyright 2010, Damien Dusha, <d.dusha@gmail.com>
+ *
+ * (C) Copyright 2009, Value Team S.p.A.
+ * Francesco Rendine, <francesco.rendine@...>
+ *
* (C) Copyright 2009 Freescale Semiconductor, Inc.
*
* (C) Copyright 2008, Excito Elektronik i Sk=E5ne AB
@@ -30,6 +35,7 @@
#include "ehci.h"
#include "ehci-core.h"
+#ifndef CONFIG_MPC512X
/*
* Create the appropriate control structures to manage
* a new EHCI host controller.
@@ -40,7 +46,7 @@ int ehci_hcd_init(void)
{
struct usb_ehci *ehci;
- ehci = (struct usb_ehci *)CONFIG_SYS_MPC8xxx_USB_ADDR;
+ ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB_ADDR;
hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
hcor = (struct ehci_hcor *)((uint32_t) hccr +
HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
@@ -77,3 +83,132 @@ int ehci_hcd_stop(void)
{
return 0;
}
+
+#else
+
+static void fsl_setup_phy(volatile struct ehci_hcor *);
+static void fsl_platform_set_host_mode(volatile struct usb_ehci *ehci);
+static int reset_usb_controller(volatile struct usb_ehci *ehci);
+static void usb_platform_dr_init(volatile struct usb_ehci *ehci);
+
+/*
+ * Initialise SOC FSL EHCI Controller
+ *
+ * This code is derived from EHCI FSL USB Linux driver for MPC5121
+ *
+ */
+int ehci_hcd_init(void)
+{
+ volatile struct usb_ehci *ehci;
+
+ /* Hook the memory mapped registers for EHCI-Controller */
+ ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB_ADDR;
+ hccr = (struct ehci_hccr *)((uint32_t)&(ehci->caplength));
+ hcor = (struct ehci_hcor *)((uint32_t) hccr +
+ HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ /* configure interface for UTMI_WIDE */
+ usb_platform_dr_init(ehci);
+
+ /* Init Phy USB0 to UTMI+ */
+ fsl_setup_phy(hcor);
+
+ /* Set to host mode */
+ fsl_platform_set_host_mode(ehci);
+
+ /*
+ * Setting the burst size seems to be required to prevent the
+ * USB from hanging when communicating with certain USB Mass
+ * storage devices. This was determined by analysing the
+ * EHCI registers under Linux vs U-Boot and burstsize was the
+ * major non-interrupt related difference between the two
+ * implementations.
+ *
+ * Some USB sticks behave better than others. In particular,
+ * the following USB stick is especially problematic:
+ * 0930:6545 Toshiba Corp
+ *
+ * The burstsize is set here to match the Linux implementation.
+ */
+ out_be32(&ehci->burstsize, FSL_EHCI_TXPBURST(8) | FSL_EHCI_RXPBURST(8));
+
+ return 0;
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop(void)
+{
+ volatile struct usb_ehci *ehci;
+ int exit_status = 0;
+
+ if (hcor) {
+ /* Unhook struct */
+ hccr = NULL;
+ hcor = NULL;
+
+ /* Reset the USB controller */
+ ehci = (struct usb_ehci *)CONFIG_SYS_FSL_USB_ADDR;
+ exit_status = reset_usb_controller(ehci);
+ }
+
+ return exit_status;
+}
+
+static int reset_usb_controller(volatile struct usb_ehci *ehci)
+{
+ unsigned int i;
+
+ /* Command a reset of the USB Controller */
+ out_be32(&(ehci->usbcmd), EHCI_FSL_USBCMD_RST);
+
+ /* Wait for the reset process to finish */
+ for (i = 65535 ; i > 0 ; i--) {
+ /*
+ * The host will set this bit to zero once the
+ * reset process is complete
+ */
+ if ((in_be32(&(ehci->usbcmd)) & EHCI_FSL_USBCMD_RST) == 0)
+ return 0;
+ }
+
+ /* Hub did not reset in time */
+ return -1;
+}
+
+static void fsl_setup_phy(volatile struct ehci_hcor *hcor)
+{
+ uint32_t portsc;
+
+ portsc = ehci_readl(&hcor->or_portsc[0]);
+ portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
+
+ /* Enable the phy mode to UTMI Wide */
+ portsc |= PORT_PTS_PTW;
+ portsc |= PORT_PTS_UTMI;
+
+ ehci_writel(&hcor->or_portsc[0], portsc);
+}
+
+static void fsl_platform_set_host_mode(volatile struct usb_ehci *ehci)
+{
+ uint32_t temp;
+
+ temp = in_le32(&ehci->usbmode);
+ temp |= CM_HOST | ES_BE;
+ out_le32(&ehci->usbmode, temp);
+}
+
+static void usb_platform_dr_init(volatile struct usb_ehci *ehci)
+{
+ /* Confgure interface for UTMI_WIDE */
+ out_be32(&ehci->isiphyctrl, PHYCTRL_PHYE | PHYCTRL_PXE);
+ out_be32(&ehci->usbgenctrl, GC_PPP | GC_PFP );
+}
+
+#endif
+
+
+
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index b3c1d5d..5ba612d 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -71,6 +71,11 @@ struct ehci_hcor {
#define STD_ASS (1 << 15)
#define STS_HALT (1 << 12)
uint32_t or_usbintr;
+#define INTR_UE (1 << 0) /* USB interrupt enable */
+#define INTR_UEE (1 << 1) /* USB error interrupt enable */
+#define INTR_PCE (1 << 2) /* Port change detect enable */
+#define INTR_SEE (1 << 4) /* system error enable */
+#define INTR_AAE (1 << 5) /* Int on async adavance */
uint32_t or_frindex;
uint32_t or_ctrldssegment;
uint32_t or_periodiclistbase;
diff --git a/include/configs/mpc5121ads.h b/include/configs/mpc5121ads.h
index 5281042..ce0df57 100644
--- a/include/configs/mpc5121ads.h
+++ b/include/configs/mpc5121ads.h
@@ -374,6 +374,20 @@
#define CONFIG_SYS_I2C_RTC_ADDR 0x68 /*@address 0x68 */
/*
+ * USB Support
+ */
+#define CONFIG_CMD_USB
+
+#if defined(CONFIG_CMD_USB)
+#define CONFIG_USB_EHCI /* Enable EHCI Support */
+#define CONFIG_USB_EHCI_FSL /* On a FSL platform */
+#define CONFIG_EHCI_MMIO_BIG_ENDIAN /* With big-endian regs */
+#define CONFIG_EHCI_DESC_BIG_ENDIAN
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_STORAGE
+#endif
+
+/*
* Environment
*/
#define CONFIG_ENV_IS_IN_FLASH 1
@@ -441,10 +455,16 @@
"mpc5121.nand:-(data)"
-#if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_EXT2)
+#if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_EXT2) || \
+ defined(CONFIG_CMD_USB)
+
#define CONFIG_DOS_PARTITION
#define CONFIG_MAC_PARTITION
#define CONFIG_ISO_PARTITION
+
+#define CONFIG_CMD_FAT
+#define CONFIG_SUPPORT_VFAT
+
#endif /* defined(CONFIG_CMD_IDE) */
/*
diff --git a/include/usb/ehci-fsl.h b/include/usb/ehci-fsl.h
index f48945a..559a96a 100644
--- a/include/usb/ehci-fsl.h
+++ b/include/usb/ehci-fsl.h
@@ -35,12 +35,17 @@
#define PORT_PTS_ULPI (2 << 30)
#define PORT_PTS_SERIAL (3 << 30)
#define PORT_PTS_PTW (1 << 28)
+#define PORT_PFSC (1 << 24) /* See p39 of MPC5121e ERM */
+#define PORT_PTS_PHCD (1 << 23)
+#define PORT_PP (1 << 12)
+#define PORT_PR (1 << 8)
/* USBMODE Register bits */
#define CM_IDLE (0 << 0)
#define CM_RESERVED (1 << 0)
#define CM_DEVICE (2 << 0)
#define CM_HOST (3 << 0)
+#define ES_BE (1 << 2) /* Big Endian Select MPC5121e */
#define USBMODE_RESERVED_2 (0 << 2)
#define SLOM (1 << 3)
#define SDIS (1 << 4)
@@ -70,7 +75,78 @@
#define PHY_CLK_VALID (1 << 17)
#define FSL_SOC_USB_PORTSC2 0x188
+
+/* OTG Status Control Register bits */
+#define FSL_SOC_USB_OTGSC 0x1a4
+#define CTRL_VBUS_DISCHARGE (1 << 0)
+#define CTRL_VBUS_CHARGE (1 << 1)
+#define CTRL_OTG_TERMINATION (1 << 3)
+#define CTRL_DATA_PULSING (1 << 4)
+#define CTRL_ID_PULL_EN (1 << 5)
+#define HA_DATA_PULSE (1 << 6)
+#define HA_BA (1 << 7)
+#define STS_USB_ID (1 << 8)
+#define STS_A_VBUS_VALID (1 << 9)
+#define STS_A_SESSION_VALID (1 << 10)
+#define STS_B_SESSION_VALID (1 << 11)
+#define STS_B_SESSION_END (1 << 12)
+#define STS_1MS_TOGGLE (1 << 13)
+#define STS_DATA_PULSING (1 << 14)
+#define INTSTS_USB_ID (1 << 16)
+#define INTSTS_A_VBUS_VALID (1 << 17)
+#define INTSTS_A_SESSION_VALID (1 << 18)
+#define INTSTS_B_SESSION_VALID (1 << 19)
+#define INTSTS_B_SESSION_END (1 << 20)
+#define INTSTS_1MS (1 << 21)
+#define INTSTS_DATA_PULSING (1 << 22)
+#define INTR_USB_ID_EN (1 << 24)
+#define INTR_A_VBUS_VALID_EN (1 << 25)
+#define INTR_A_SESSION_VALID_EN (1 << 26)
+#define INTR_B_SESSION_VALID_EN (1 << 27)
+#define INTR_B_SESSION_END_EN (1 << 28)
+#define INTR_1MS_TIMER_EN (1 << 29)
+#define INTR_DATA_PULSING_EN (1 << 30)
+#define INTSTS_MASK 0x00ff0000
+
+/* USBCMD Bits of interest */
+#define EHCI_FSL_USBCMD_RST (1 << 1)
+#define EHCI_FSL_USBCMD_RS (1 << 0)
+
+#define INTERRUPT_ENABLE_BITS_MASK \
+ (INTR_USB_ID_EN | \
+ INTR_1MS_TIMER_EN | \
+ INTR_A_VBUS_VALID_EN | \
+ INTR_A_SESSION_VALID_EN | \
+ INTR_B_SESSION_VALID_EN | \
+ INTR_B_SESSION_END_EN | \
+ INTR_DATA_PULSING_EN)
+
+#define INTERRUPT_STATUS_BITS_MASK \
+ (INTSTS_USB_ID | \
+ INTR_1MS_TIMER_EN | \
+ INTSTS_A_VBUS_VALID | \
+ INTSTS_A_SESSION_VALID | \
+ INTSTS_B_SESSION_VALID | \
+ INTSTS_B_SESSION_END | \
+ INTSTS_DATA_PULSING)
+
#define FSL_SOC_USB_USBMODE 0x1a8
+
+#define USBGENCTRL 0x200 /* NOTE: big endian */
+#define GC_WU_INT_CLR (1 << 5) /* Wakeup int clear */
+#define GC_ULPI_SEL (1 << 4) /* ULPI i/f select (usb0 only)*/
+#define GC_PPP (1 << 3) /* Port Power Polarity */
+#define GC_PFP (1 << 2) /* Power Fault Polarity */
+#define GC_WU_ULPI_EN (1 << 1) /* Wakeup on ULPI event */
+#define GC_WU_IE (1 << 1) /* Wakeup interrupt enable */
+
+#define ISIPHYCTRL 0x204 /* NOTE: big endian */
+#define PHYCTRL_PHYE (1 << 4) /* On-chip UTMI PHY enable */
+#define PHYCTRL_BSENH (1 << 3) /* Bit Stuff Enable High */
+#define PHYCTRL_BSEN (1 << 2) /* Bit Stuff Enable */
+#define PHYCTRL_LSFE (1 << 1) /* Line State Filter Enable */
+#define PHYCTRL_PXE (1 << 0) /* PHY oscillator enable */
+
#define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */
#define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */
#define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */
@@ -85,65 +161,86 @@
#define MPC83XX_SCCR_USB_DRCM_01 0x00100000
#define MPC83XX_SCCR_USB_DRCM_10 0x00200000
-#if defined(CONFIG_MPC83xx)
-#define CONFIG_SYS_MPC8xxx_USB_ADDR CONFIG_SYS_MPC83xx_USB_ADDR
+#if defined(CONFIG_MPC83XX)
+#define CONFIG_SYS_FSL_USB_ADDR CONFIG_SYS_MPC83xx_USB_ADDR
#elif defined(CONFIG_MPC85xx)
-#define CONFIG_SYS_MPC8xxx_USB_ADDR CONFIG_SYS_MPC85xx_USB_ADDR
+#define CONFIG_SYS_FSL_USB_ADDR CONFIG_SYS_MPC85xx_USB_ADDR
+#elif defined(CONFIG_MPC512X)
+#define CONFIG_SYS_FSL_USB_ADDR CONFIG_SYS_MPC512x_USB_ADDR
#endif
/*
* USB Registers
*/
struct usb_ehci {
- u8 res1[0x100];
+ u32 id; /* 0x000 - Identification register */
+ u32 hwgeneral; /* 0x004 - General hardware parameters */
+ u32 hwhost; /* 0x008 - Host hardware parameters */
+ u32 hwdevice; /* 0x00C - Device hardware parameters */
+ u32 hwtxbuf; /* 0x010 - TX buffer hardware parameters */
+ u32 hwrxbuf; /* 0x014 - RX buffer hardware parameters */
+ u8 res1[0x68];
+ u32 gptimer0_ld; /* 0x080 - General Purpose Timer 0 load value */
+ u32 gptimer0_ctrl; /* 0x084 - General Purpose Timer 0 control */
+ u32 gptimer1_ld; /* 0x088 - General Purpose Timer 1 load value */
+ u32 gptimer1_ctrl; /* 0x08C - General Purpose Timer 1 control */
+ u32 sbuscfg; /* 0x090 - System Bus Interface Control */
+ u8 res2[0x6C];
u16 caplength; /* 0x100 - Capability Register Length */
u16 hciversion; /* 0x102 - Host Interface Version */
u32 hcsparams; /* 0x104 - Host Structural Parameters */
u32 hccparams; /* 0x108 - Host Capability Parameters */
- u8 res2[0x14];
+ u8 res3[0x14];
u32 dciversion; /* 0x120 - Device Interface Version */
u32 dciparams; /* 0x124 - Device Controller Params */
- u8 res3[0x18];
+ u8 res4[0x18];
u32 usbcmd; /* 0x140 - USB Command */
u32 usbsts; /* 0x144 - USB Status */
u32 usbintr; /* 0x148 - USB Interrupt Enable */
u32 frindex; /* 0x14C - USB Frame Index */
- u8 res4[0x4];
+ u8 res5[0x4];
u32 perlistbase; /* 0x154 - Periodic List Base
- USB Device Address */
u32 ep_list_addr; /* 0x158 - Next Asynchronous List
- - Endpoint Address */
- u8 res5[0x4];
+ - End Point Address */
+ u8 res6[0x4];
u32 burstsize; /* 0x160 - Programmable Burst Size */
+#define FSL_EHCI_TXPBURST(X) ((X) << 8)
+#define FSL_EHCI_RXPBURST(X) (X)
u32 txfilltuning; /* 0x164 - Host TT Transmit
pre-buffer packet tuning */
- u8 res6[0x8];
+ u8 res7[0x8];
u32 ulpi_viewpoint; /* 0x170 - ULPI Reister Access */
- u8 res7[0xc];
+ u8 res8[0xc];
u32 config_flag; /* 0x180 - Configured Flag Register */
u32 portsc; /* 0x184 - Port status/control */
- u8 res8[0x20];
+ u8 res9[0x1C];
+ u32 otgsc; /* 0x1a4 - Oo-The-Go status and control */
u32 usbmode; /* 0x1a8 - USB Device Mode */
- u32 epsetupstat; /* 0x1ac - Endpoint Setup Status */
- u32 epprime; /* 0x1b0 - Endpoint Init Status */
- u32 epflush; /* 0x1b4 - Endpoint De-initlialize */
- u32 epstatus; /* 0x1b8 - Endpoint Status */
- u32 epcomplete; /* 0x1bc - Endpoint Complete */
- u32 epctrl0; /* 0x1c0 - Endpoint Control 0 */
- u32 epctrl1; /* 0x1c4 - Endpoint Control 1 */
- u32 epctrl2; /* 0x1c8 - Endpoint Control 2 */
- u32 epctrl3; /* 0x1cc - Endpoint Control 3 */
- u32 epctrl4; /* 0x1d0 - Endpoint Control 4 */
- u32 epctrl5; /* 0x1d4 - Endpoint Control 5 */
- u8 res9[0x228];
+ u32 epsetupstat; /* 0x1ac - End Point Setup Status */
+ u32 epprime; /* 0x1b0 - End Point Init Status */
+ u32 epflush; /* 0x1b4 - End Point De-initlialize */
+ u32 epstatus; /* 0x1b8 - End Point Status */
+ u32 epcomplete; /* 0x1bc - End Point Complete */
+ u32 epctrl0; /* 0x1c0 - End Point Control 0 */
+ u32 epctrl1; /* 0x1c4 - End Point Control 1 */
+ u32 epctrl2; /* 0x1c8 - End Point Control 2 */
+ u32 epctrl3; /* 0x1cc - End Point Control 3 */
+ u32 epctrl4; /* 0x1d0 - End Point Control 4 */
+ u32 epctrl5; /* 0x1d4 - End Point Control 5 */
+ u8 res10[0x28];
+ u32 usbgenctrl; /* 0x200 - USB General Control */
+ u32 isiphyctrl; /* 0x204 - On-Chip PHY Control */
+ u8 res11[0x1F8];
u32 snoop1; /* 0x400 - Snoop 1 */
u32 snoop2; /* 0x404 - Snoop 2 */
u32 age_cnt_limit; /* 0x408 - Age Count Threshold */
u32 prictrl; /* 0x40c - Priority Control */
u32 sictrl; /* 0x410 - System Interface Control */
- u8 res10[0xEC];
+ u8 res12[0xEC];
u32 control; /* 0x500 - Control */
- u8 res11[0xafc];
+ u8 res13[0xafc];
};
#endif /* _EHCI_FSL_H */
+
--
1.7.0.4
next reply other threads:[~2010-08-22 5:41 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-22 5:41 Damien Dusha [this message]
2010-08-24 15:05 ` [U-Boot] [PATCH] Add support for the MPC5121e USB Host controller Einar Már Björgvinsson
2010-08-25 0:45 ` Damien Dusha
2010-08-25 11:27 ` Einar Már Björgvinsson
2010-08-25 13:27 ` Damien Dusha
2010-10-14 13:26 ` Wolfgang Denk
2010-10-14 13:27 ` [U-Boot] [PATCH] MPC5121: Add USB EHCI support Wolfgang Denk
2010-10-14 16:27 ` Wolfgang Denk
2010-10-16 9:51 ` Remy Bohmer
2010-10-18 20:31 ` Wolfgang Denk
2010-10-24 14:14 ` [U-Boot] [PATCH] MPC8315ERD: fix build error Wolfgang Denk
2010-10-26 18:41 ` Wolfgang Denk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1282455714-12834-1-git-send-email-d.dusha@gmail.com \
--to=d.dusha@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.