All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nicolas Ferre <nicolas.ferre@atmel.com>
To: ARM Linux Mailing List <linux-arm-kernel@lists.arm.linux.org.uk>,
	Stelian Pop <stelian@popies.net>,
	Haavard Skinnemoen <hskinnemoen@atmel.com>
Cc: David Brownell <david-b@pacbell.net>,
	Andrew Victor <linux@maxim.org.za>,
	Linux Kernel list <linux-kernel@vger.kernel.org>,
	Nicolas FERRE <nicolas.ferre@atmel.com>,
	Sedji GAOUAOU <sedji.gaouaou@atmel.com>,
	Patrice VILCHEZ <patrice.vilchez@atmel.com>
Subject: [PATCH] AT91: UDPHS driver: SAM9RL board and cpu integration
Date: Fri, 07 Mar 2008 10:27:53 +0100	[thread overview]
Message-ID: <47D10A99.4050800@atmel.com> (raw)

Adds support for the USB High Speed Device Port on the 
AT91SAM9RL system on chip. The AT91SAM9RL uses the same 
UDPHS IP as the AVR32 and the AT91CAP9 (atmel_usba_udc driver).

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
Like AT91CAP9 patches, this cpu/board integration is generated against 
Linux 2.6.25-rc4 + the very last atmel_usba_udc cleanup patches comming
from those threads :
http://lists.arm.linux.org.uk/lurker/message/20080228.143442.a2338930.en.html
http://lists.arm.linux.org.uk/lurker/message/20080305.141253.d4458042.en.html

Thanks a lot to Stelian, Haavard and David to put this driver integration well
under way.

 arch/arm/mach-at91/at91sam9rl_devices.c |   90 ++++++++++++++++++++++++++++++++
 arch/arm/mach-at91/board-sam9rlek.c     |   10 +++
 arch/arm/mach-at91/clock.c              |    9 +--
 drivers/usb/gadget/Kconfig              |    2 
 include/asm-arm/arch-at91/at91_pmc.h    |    4 -
 include/asm-arm/arch-at91/at91sam9rl.h  |    2 
 6 files changed, 109 insertions(+), 8 deletions(-)

--- linux-2.6.x-rc.orig/arch/arm/mach-at91/at91sam9rl_devices.c
+++ linux-2.6.x-rc/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -26,6 +26,96 @@
 
 
 /* --------------------------------------------------------------------
+ *  USB HS Device (Gadget)
+ * -------------------------------------------------------------------- */
+
+#if defined(CONFIG_USB_GADGET_ATMEL_USBA) || defined(CONFIG_USB_GADGET_ATMEL_USBA_MODULE)
+
+static struct resource usba_udc_resources[] = {
+	[0] = {
+		.start	= AT91SAM9RL_UDPHS_FIFO,
+		.end	= AT91SAM9RL_UDPHS_FIFO + SZ_512K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= AT91SAM9RL_BASE_UDPHS,
+		.end	= AT91SAM9RL_BASE_UDPHS + SZ_1K - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	[2] = {
+		.start	= AT91SAM9RL_ID_UDPHS,
+		.end	= AT91SAM9RL_ID_UDPHS,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+#define EP(nam, idx, maxpkt, maxbk, dma, isoc)			\
+	[idx] = {						\
+		.name		= nam,				\
+		.index		= idx,				\
+		.fifo_size	= maxpkt,			\
+		.nr_banks	= maxbk,			\
+		.can_dma	= dma,				\
+		.can_isoc	= isoc,				\
+	}
+
+static struct usba_ep_data usba_udc_ep[] __initdata = {
+	EP("ep0", 0, 64, 1, 0, 0),
+	EP("ep1", 1, 1024, 2, 1, 1),
+	EP("ep2", 2, 1024, 2, 1, 1),
+	EP("ep3", 3, 1024, 3, 1, 0),
+	EP("ep4", 4, 1024, 3, 1, 0),
+	EP("ep5", 5, 1024, 3, 1, 1),
+	EP("ep6", 6, 1024, 3, 1, 1),
+};
+
+#undef EP
+
+/*
+ * pdata doesn't have room for any endpoints, so we need to
+ * append room for the ones we need right after it.
+ */
+static struct {
+	struct usba_platform_data pdata;
+	struct usba_ep_data ep[7];
+} usba_udc_data;
+
+static struct platform_device at91_usba_udc_device = {
+	.name		= "atmel_usba_udc",
+	.id		= -1,
+	.dev		= {
+				.platform_data	= &usba_udc_data.pdata,
+	},
+	.resource	= usba_udc_resources,
+	.num_resources	= ARRAY_SIZE(usba_udc_resources),
+};
+
+void __init at91_add_device_usba(struct usba_platform_data *data)
+{
+	usba_udc_data.pdata.vbus_pin = -EINVAL;
+	usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
+	memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));;
+
+	if (data && data->vbus_pin >= 0) {
+		at91_set_gpio_input(data->vbus_pin, 0);
+		at91_set_deglitch(data->vbus_pin, 1);
+		usba_udc_data.pdata.vbus_pin = data->vbus_pin;
+	}
+
+	/* Pullup pin is handled internally by USB device peripheral */
+
+	/* Clocks */
+	at91_clock_associate("utmi_clk", &at91_usba_udc_device.dev, "hclk");
+	at91_clock_associate("udphs_clk", &at91_usba_udc_device.dev, "pclk");
+
+	platform_device_register(&at91_usba_udc_device);
+}
+#else
+void __init at91_add_device_usba(struct usba_platform_data *data) {}
+#endif
+
+
+/* --------------------------------------------------------------------
  *  MMC / SD
  * -------------------------------------------------------------------- */
 
--- linux-2.6.x-rc.orig/arch/arm/mach-at91/board-sam9rlek.c
+++ linux-2.6.x-rc/arch/arm/mach-at91/board-sam9rlek.c
@@ -61,6 +61,14 @@ static void __init ek_init_irq(void)
 
 
 /*
+ * USB HS Device port
+ */
+static struct usba_platform_data __initdata ek_usba_udc_data = {
+	.vbus_pin	= AT91_PIN_PA8,
+};
+
+
+/*
  * MCI (SD/MMC)
  */
 static struct at91_mmc_data __initdata ek_mmc_data = {
@@ -190,6 +198,8 @@ static void __init ek_board_init(void)
 	at91_add_device_mmc(0, &ek_mmc_data);
 	/* LCD Controller */
 	at91_add_device_lcdc(&ek_lcdc_data);
+	/* USB HS */
+	at91_add_device_usba(&ek_usba_udc_data);
 }
 
 MACHINE_START(AT91SAM9RLEK, "Atmel AT91SAM9RL-EK")
--- linux-2.6.x-rc.orig/drivers/usb/gadget/Kconfig
+++ linux-2.6.x-rc/drivers/usb/gadget/Kconfig
@@ -121,7 +121,7 @@ config USB_GADGET_ATMEL_USBA
 	depends on AVR32 || ARCH_AT91
 	help
 	  USBA is the integrated high-speed USB Device controller on
-	  the AT32AP700x and AT91CAP9 processors from Atmel.
+	  the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
 
 config USB_ATMEL_USBA
 	tristate
--- linux-2.6.x-rc.orig/arch/arm/mach-at91/clock.c
+++ linux-2.6.x-rc/arch/arm/mach-at91/clock.c
@@ -392,8 +392,9 @@ static int at91_clk_show(struct seq_file
 	seq_printf(s, "MOR  = %8x\n", at91_sys_read(AT91_CKGR_MOR));
 	seq_printf(s, "MCFR = %8x\n", at91_sys_read(AT91_CKGR_MCFR));
 	seq_printf(s, "PLLA = %8x\n", at91_sys_read(AT91_CKGR_PLLAR));
-	seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
-	if (cpu_is_at91cap9())
+	if (!cpu_is_at91sam9rl())
+		seq_printf(s, "PLLB = %8x\n", at91_sys_read(AT91_CKGR_PLLBR));
+	if (cpu_is_at91cap9() || cpu_is_at91sam9rl())
 		seq_printf(s, "UCKR = %8x\n", uckr = at91_sys_read(AT91_CKGR_UCKR));
 	seq_printf(s, "MCKR = %8x\n", at91_sys_read(AT91_PMC_MCKR));
 	seq_printf(s, "SR   = %8x\n", sr = at91_sys_read(AT91_PMC_SR));
@@ -611,7 +612,7 @@ int __init at91_clock_init(unsigned long
 	/*
 	 * USB HS clock init
 	 */
-	if (cpu_is_at91cap9()) {
+	if (cpu_is_at91cap9() || cpu_is_at91sam9rl()) {
 		/*
 		 * multiplier is hard-wired to 40
 		 * (obtain the USB High Speed 480 MHz when input is 12 MHz)
@@ -636,7 +637,7 @@ int __init at91_clock_init(unsigned long
 	for (i = 0; i < ARRAY_SIZE(standard_pmc_clocks); i++)
 		list_add_tail(&standard_pmc_clocks[i]->node, &clocks);
 
-	if (cpu_is_at91cap9())
+	if (cpu_is_at91cap9() || cpu_is_at91sam9rl())
 		list_add_tail(&utmi_clk.node, &clocks);
 
 	/* MCK and CPU clock are "always on" */
--- linux-2.6.x-rc.orig/include/asm-arm/arch-at91/at91sam9rl.h
+++ linux-2.6.x-rc/include/asm-arm/arch-at91/at91sam9rl.h
@@ -110,6 +110,6 @@
 #define AT91SAM9RL_ROM_SIZE	(2 * SZ_16K)	/* Internal ROM size (32Kb) */
 
 #define AT91SAM9RL_LCDC_BASE	0x00500000	/* LCD Controller */
-#define AT91SAM9RL_UDPHS_BASE	0x00600000	/* USB Device HS controller */
+#define AT91SAM9RL_UDPHS_FIFO	0x00600000	/* USB Device HS controller */
 
 #endif
--- linux-2.6.x-rc.orig/include/asm-arm/arch-at91/at91_pmc.h
+++ linux-2.6.x-rc/include/asm-arm/arch-at91/at91_pmc.h
@@ -42,7 +42,7 @@
 #define		AT91_PMC_UPLLEN		(1 << 16)		/* UTMI PLL */
 #define		AT91_PMC_BIASEN		(1 << 24)		/* UTMI BIAS */
 
-#define	AT91_CKGR_MOR		(AT91_PMC + 0x20)	/* Main Oscillator Register [not on SAM9RL] */
+#define	AT91_CKGR_MOR		(AT91_PMC + 0x20)	/* Main Oscillator Register */
 #define		AT91_PMC_MOSCEN		(1    << 0)		/* Main Oscillator Enable */
 #define		AT91_PMC_OSCBYPASS	(1    << 1)		/* Oscillator Bypass [SAM9x, CAP9] */
 #define		AT91_PMC_OSCOUNT	(0xff << 8)		/* Main Oscillator Start-up Time */
@@ -92,7 +92,7 @@
 #define		AT91_PMC_LOCKA		(1 <<  1)		/* PLLA Lock */
 #define		AT91_PMC_LOCKB		(1 <<  2)		/* PLLB Lock */
 #define		AT91_PMC_MCKRDY		(1 <<  3)		/* Master Clock */
-#define		AT91_PMC_LOCKU		(1 <<  6)		/* UPLL Lock [AT91CAP9 only] */
+#define		AT91_PMC_LOCKU		(1 <<  6)		/* UPLL Lock [SAM9RL, CAP9] */
 #define		AT91_PMC_PCK0RDY	(1 <<  8)		/* Programmable Clock 0 */
 #define		AT91_PMC_PCK1RDY	(1 <<  9)		/* Programmable Clock 1 */
 #define		AT91_PMC_PCK2RDY	(1 << 10)		/* Programmable Clock 2 */


             reply	other threads:[~2008-03-07  9:31 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-07  9:27 Nicolas Ferre [this message]
  -- strict thread matches above, loose matches on Subject: below --
2008-04-07 15:46 [PATCH] AT91 UDPHS driver: SAM9RL board and cpu integration Nicolas Ferre
2008-04-08 13:05 ` Nicolas Ferre

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=47D10A99.4050800@atmel.com \
    --to=nicolas.ferre@atmel.com \
    --cc=david-b@pacbell.net \
    --cc=hskinnemoen@atmel.com \
    --cc=linux-arm-kernel@lists.arm.linux.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@maxim.org.za \
    --cc=patrice.vilchez@atmel.com \
    --cc=sedji.gaouaou@atmel.com \
    --cc=stelian@popies.net \
    /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.