Skip to content
Snippets Groups Projects
Commit 64203c7b authored by Sergey Matyukevich's avatar Sergey Matyukevich Committed by Remy Bohmer
Browse files

USB OHCI support for at91sam9g45 SoC


Add USB OHCI support for at91sam9g45ekes/at91sam9m10g45ek boards.

Note that according to errata from Atmel, OHCI is not operational
on the first revision of at91sam9g45 chip. So this patch enables
OHCI support for later revisions.

Signed-off-by: default avatarSergey Matyukevich <geomatsi@gmail.com>
parent 39ddd10b
No related branches found
No related tags found
No related merge requests found
......@@ -35,13 +35,15 @@ typedef struct at91_pmc {
u32 pcer; /* 0x10 Peripheral Clock Enable Register */
u32 pcdr; /* 0x14 Peripheral Clock Disable Register */
u32 pcsr; /* 0x18 Peripheral Clock Status Register */
u32 reserved1;
u32 uckr; /* 0x1C UTMI Clock Register */
u32 mor; /* 0x20 Main Oscilator Register */
u32 mcfr; /* 0x24 Main Clock Frequency Register */
u32 pllar; /* 0x28 PLL A Register */
u32 pllbr; /* 0x2C PLL B Register */
u32 mckr; /* 0x30 Master Clock Register */
u32 reserved2[3];
u32 reserved1;
u32 usb; /* 0x38 USB Clock Register */
u32 reserved2;
u32 pck[4]; /* 0x40 Programmable Clock Register 0 - 3 */
u32 reserved3[4];
u32 ier; /* 0x60 Interrupt Enable Register */
......@@ -198,6 +200,14 @@ typedef struct at91_pmc {
#define AT91_PMC_PDIV_1 (0 << 12)
#define AT91_PMC_PDIV_2 (1 << 12)
#ifdef CONFIG_AT91_LEGACY
#define AT91_PMC_USB (AT91_PMC + 0x38) /* USB Clock Register */
#endif
#define AT91_PMC_USBS_USB_PLLA (0x0) /* USB Clock Input is PLLA */
#define AT91_PMC_USBS_USB_UPLL (0x1) /* USB Clock Input is UPLL */
#define AT91_PMC_USBDIV_8 (0x7 << 8) /* USB Clock divided by 8 */
#define AT91_PMC_USBDIV_10 (0x9 << 8) /* USB Clock divided by 10 */
#ifdef CONFIG_AT91_LEGACY
#define AT91_PMC_PCKR(n) (AT91_PMC + 0x40 + ((n) * 4)) /* Programmable Clock 0-3 Registers */
......
......@@ -87,6 +87,16 @@ static void at91sam9m10g45ek_nand_hw_init(void)
}
#endif
#ifdef CONFIG_CMD_USB
static void at91sam9m10g45ek_usb_hw_init(void)
{
at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9G45_ID_PIODE);
at91_set_gpio_output(AT91_PIN_PD1, 0);
at91_set_gpio_output(AT91_PIN_PD3, 0);
}
#endif
#ifdef CONFIG_MACB
static void at91sam9m10g45ek_macb_hw_init(void)
{
......@@ -251,6 +261,9 @@ int board_init(void)
#ifdef CONFIG_CMD_NAND
at91sam9m10g45ek_nand_hw_init();
#endif
#ifdef CONFIG_CMD_USB
at91sam9m10g45ek_usb_hw_init();
#endif
#ifdef CONFIG_HAS_DATAFLASH
at91_spi0_hw_init(1 << 0);
#endif
......
......@@ -41,6 +41,15 @@ int usb_cpu_init(void)
writel(get_pllb_init(), &pmc->pllbr);
while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != AT91_PMC_LOCKB)
;
#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45)
/* Enable UPLL */
writel(readl(&pmc->uckr) | AT91_PMC_UPLLEN | AT91_PMC_BIASEN,
&pmc->uckr);
while ((readl(&pmc->sr) & AT91_PMC_LOCKU) != AT91_PMC_LOCKU)
;
/* Select PLLA as input clock of OHCI */
writel(AT91_PMC_USBS_USB_UPLL | AT91_PMC_USBDIV_10, &pmc->usb);
#endif
/* Enable USB host clock. */
......@@ -72,6 +81,11 @@ int usb_cpu_stop(void)
writel(0, &pmc->pllbr);
while ((readl(&pmc->sr) & AT91_PMC_LOCKB) != 0)
;
#elif defined(CONFIG_AT91SAM9G45) || defined(CONFIG_AT91SAM9M10G45)
/* Disable UPLL */
writel(readl(&pmc->uckr) & (~AT91_PMC_UPLLEN), &pmc->uckr);
while ((readl(&pmc->sr) & AT91_PMC_LOCKU) == AT91_PMC_LOCKU)
;
#endif
return 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment