Skip to contentSkip to conversation

at91: at91sam9g15 improvements

PATCH New Heiko Schocher 4 participants 24 messages Aug 17, 2016 – Oct 28, 2016

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover at91: at91sam9g15 improvements

This series add some missing things for an at91sam9g15 board, which gets not mainlined, but there are common fixes, which are posted with this patchserie.

2 important things:
- enable icache for AT91 based boards
speeds up them a lot, for example reading 8MiB from an SPI NOR flash into RAM takes with icache off ~15 seconds with icache enabled only ~5 seconds.

gurnard board defines a board specific enable_caches() function which enables dcache .. with acomment that this breaks Ethernet MAC ... I removed this board specific function, and dcache enable functions should be added in arch/arm/mach-at91/arm926ejs/cache.c

- SPL clock fix, posted as RFC, as it may breaks other boards. If so, we may make clock settings in SPL board configurable through a weak function?

buildman finds no new errors/warnings with the patches from this patchseries applied.

Heiko Schocher (6):
arm: at91: mpddrc: add missing MPDDRC_MD defines
ARM: at91: clock: correct PRES offset for at91sam9x5 arm, at91: add icache support
arm, at91: add some missing fields in PIO struct
at91: add function to set IO drive
[RFC] at91: SPL clock fix for AT91SAM9G15 based boards.

 arch/arm/mach-at91/arm926ejs/Makefile          |  1 +
 arch/arm/mach-at91/arm926ejs/cache.c           | 29 ++++++++++++++++++++++++++
 arch/arm/mach-at91/arm926ejs/clock.c           |  6 ++++++
 arch/arm/mach-at91/include/mach/at91_pio.h     | 11 +++++++++-
 arch/arm/mach-at91/include/mach/atmel_mpddrc.h |  3 +++
 arch/arm/mach-at91/include/mach/gpio.h         |  2 ++
 arch/arm/mach-at91/spl_at91.c                  | 13 +++++++++---
 board/bluewater/gurnard/gurnard.c              |  6 ------
 drivers/gpio/at91_gpio.c                       | 29 ++++++++++++++++++++++++++
 9 files changed, 90 insertions(+), 10 deletions(-)
 create mode 100644 arch/arm/mach-at91/arm926ejs/cache.c
Signature · 1 line
2.5.5
#1 lore raw

PATCH 1/6 arm: at91: mpddrc: add missing MPDDRC_MD defines

add missing MPDDRC_MD defines

---

 arch/arm/mach-at91/include/mach/atmel_mpddrc.h | 3 +++
 1 file changed, 3 insertions(+)
arch/arm/mach-at91/include/mach/atmel_mpddrc.h +3 -0
index d37d908..f6bcecd 100644
@@ -147,6 +147,9 @@ int ddr3_init(const unsigned int base,
 #define ATMEL_MPDDRC_TPR2_TFAW_MASK		0xf
 
 /* Bit field in Memory Device Register */
+#define ATMEL_MPDDRC_MD_SDR_SDRAM	0x0
+#define ATMEL_MPDDRC_MD_LP_SDR_SDRAM	0x1
+#define ATMEL_MPDDRC_MD_DDR_SDRAM	0x2
 #define ATMEL_MPDDRC_MD_LPDDR_SDRAM	0x3
 #define ATMEL_MPDDRC_MD_DDR3_SDRAM	0x4
 #define ATMEL_MPDDRC_MD_LPDDR3_SDRAM	0x5
Signature · 1 line
2.5.5
#2 lore raw

PATCH 1/6 arm: at91: mpddrc: add missing MPDDRC_MD defines

Quoted 11 lines

-----Original Message-----
From: U-Boot [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Heiko Schocher
Sent: 2016?8?17? 15:13
To: U-Boot Mailing List <[email protected]>
Cc: Bo Shen <[email protected]>
Subject: [U-Boot] [PATCH 1/6] arm: at91: mpddrc: add missing MPDDRC_MD defines

Quoted 3 lines

add missing MPDDRC_MD defines

Quoted 27 lines

---

 arch/arm/mach-at91/include/mach/atmel_mpddrc.h | 3 +++
 1 file changed, 3 insertions(+)
arch/arm/mach- renamed from arch/arm/mach-at91/include/mach/atmel_mpddrc.h +0 -0

at91/include/mach/atmel_mpddrc.h
index d37d908..f6bcecd 100644

arch/arm/mach-at91/include/mach/atmel_mpddrc.h +3 -1
@@ -147,6 +147,9 @@ int ddr3_init(const unsigned int base,
 #define ATMEL_MPDDRC_TPR2_TFAW_MASK		0xf
 
 /* Bit field in Memory Device Register */
+#define ATMEL_MPDDRC_MD_SDR_SDRAM	0x0
+#define ATMEL_MPDDRC_MD_LP_SDR_SDRAM	0x1
+#define ATMEL_MPDDRC_MD_DDR_SDRAM	0x2
 #define ATMEL_MPDDRC_MD_LPDDR_SDRAM	0x3
 #define ATMEL_MPDDRC_MD_DDR3_SDRAM	0x4
 #define ATMEL_MPDDRC_MD_LPDDR3_SDRAM	0x5
--

2.5.5

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#3 lore raw

PATCH 1/6 arm: at91: mpddrc: add missing MPDDRC_MD defines

In reply to Heiko Schocher
Quoted 3 lines · Heiko Schocher

add missing MPDDRC_MD defines

Quoted 20 lines

---

 arch/arm/mach-at91/include/mach/atmel_mpddrc.h | 3 +++
 1 file changed, 3 insertions(+)
arch/arm/mach-at91/include/mach/atmel_mpddrc.h +3 -0
index d37d908..f6bcecd 100644
@@ -147,6 +147,9 @@ int ddr3_init(const unsigned int base,
 #define ATMEL_MPDDRC_TPR2_TFAW_MASK		0xf
 
 /* Bit field in Memory Device Register */
+#define ATMEL_MPDDRC_MD_SDR_SDRAM	0x0
+#define ATMEL_MPDDRC_MD_LP_SDR_SDRAM	0x1
+#define ATMEL_MPDDRC_MD_DDR_SDRAM	0x2
 #define ATMEL_MPDDRC_MD_LPDDR_SDRAM	0x3
 #define ATMEL_MPDDRC_MD_DDR3_SDRAM	0x4
 #define ATMEL_MPDDRC_MD_LPDDR3_SDRAM	0x5
#4 lore raw

PATCH 1/6 arm: at91: mpddrc: add missing MPDDRC_MD defines

In reply to Heiko Schocher

Dear Heiko Schocher,

Quoted 9 lines · Heiko Schocher

add missing MPDDRC_MD defines

---

arch/arm/mach-at91/include/mach/atmel_mpddrc.h | 3 +++

1 file changed, 3 insertions(+)

applied to u-boot-atmel/master, thanks!

Best regards,
Andreas Bie?mann

#5 lore raw

PATCH 2/6 ARM: at91: clock: correct PRES offset for at91sam9x5

In reply to Heiko Schocher

on at91sam9x5 PRES offset is 4 in the PMC master
clock register.

---

 arch/arm/mach-at91/arm926ejs/clock.c | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/mach-at91/arm926ejs/clock.c +6 -0
index c8d24ae..e3181fa 100644
@@ -162,7 +162,13 @@ int at91_clock_init(unsigned long main_clock)
 	gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
 	freq = gd->arch.mck_rate_hz;
 
+#if defined(CONFIG_AT91SAM9X5)
+	/* different in prescale on at91sam9x5 */
+	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 4));
+#else
 	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/* prescale */
+#endif
+
 #if defined(CONFIG_AT91SAM9G20)
 	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
 	gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ?
Signature · 1 line
2.5.5
#6 lore raw

PATCH 2/6 ARM: at91: clock: correct PRES offset for at91sam9x5

Quoted 11 lines

-----Original Message-----
From: U-Boot [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Heiko Schocher
Sent: 2016?8?17? 15:13
To: U-Boot Mailing List <[email protected]>
Cc: Bo Shen <[email protected]>
Subject: [U-Boot] [PATCH 2/6] ARM: at91: clock: correct PRES offset for at91sam9x5

Quoted 3 lines

on at91sam9x5 PRES offset is 4 in the PMC master clock register.

Quoted 32 lines

---

 arch/arm/mach-at91/arm926ejs/clock.c | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/mach- renamed from arch/arm/mach-at91/arm926ejs/clock.c +0 -0

at91/arm926ejs/clock.c
index c8d24ae..e3181fa 100644

arch/arm/mach-at91/arm926ejs/clock.c +3 -0
@@ -162,7 +162,13 @@ int at91_clock_init(unsigned long main_clock)
 	gd->arch.mck_rate_hz = at91_css_to_rate(mckr &
 AT91_PMC_MCKR_CSS_MASK);
 	freq = gd->arch.mck_rate_hz;
 
+#if defined(CONFIG_AT91SAM9X5)
+	/* different in prescale on at91sam9x5 */
+	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 4)); #else
 	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/*

prescale */

arch/arm/mach-at91/arm926ejs/clock.c +2 -1
+#endif
+
 #if defined(CONFIG_AT91SAM9G20)
 	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
 	gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ?
--

2.5.5

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#7 lore raw

PATCH 2/6 ARM: at91: clock: correct PRES offset for at91sam9x5

In reply to Heiko Schocher
Quoted 14 lines · Heiko Schocher

on at91sam9x5 PRES offset is 4 in the PMC master
clock register.

---

 arch/arm/mach-at91/arm926ejs/clock.c | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/mach-at91/arm926ejs/clock.c +0 -0
index c8d24ae..e3181fa 100644

arch/arm/mach-at91/arm926ejs/clock.c int at91_clock_init(unsigned long main_clock) · line 167

Quoted 6 lines
arch/arm/mach-at91/arm926ejs/clock.c +3 -0
@@ -162,7 +162,13 @@ int at91_clock_init(unsigned long main_clock)
 	gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
 	freq = gd->arch.mck_rate_hz;
 
+#if defined(CONFIG_AT91SAM9X5)
+	/* different in prescale on at91sam9x5 */
+	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 4));

This one is really ugly ... I can live with the ifdef here but have you realized the 0x7 for PRES?

Andreas

Quoted 8 lines
arch/arm/mach-at91/arm926ejs/clock.c +3 -0
+#else
 	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/* prescale */
+#endif
+
 #if defined(CONFIG_AT91SAM9G20)
 	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
 	gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ?
#8 lore raw

PATCH 2/6 ARM: at91: clock: correct PRES offset for at91sam9x5

In reply to Heiko Schocher
Quoted 5 lines · Heiko Schocher

on at91sam9x5 PRES offset is 4 in the PMC master
clock register.

Quoted 23 lines

---

 arch/arm/mach-at91/arm926ejs/clock.c | 6 ++++++
 1 file changed, 6 insertions(+)
arch/arm/mach-at91/arm926ejs/clock.c +6 -0
index c8d24ae..e3181fa 100644
@@ -162,7 +162,13 @@ int at91_clock_init(unsigned long main_clock)
 	gd->arch.mck_rate_hz = at91_css_to_rate(mckr & AT91_PMC_MCKR_CSS_MASK);
 	freq = gd->arch.mck_rate_hz;
 
+#if defined(CONFIG_AT91SAM9X5)
+	/* different in prescale on at91sam9x5 */
+	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 4));
+#else
 	freq /= (1 << ((mckr & AT91_PMC_MCKR_PRES_MASK) >> 2));	/* prescale */
+#endif
+
 #if defined(CONFIG_AT91SAM9G20)
 	/* mdiv ; (x >> 7) = ((x >> 8) * 2) */
 	gd->arch.mck_rate_hz = (mckr & AT91_PMC_MCKR_MDIV_MASK) ?
#9 lore raw

PATCH 2/6 ARM: at91: clock: correct PRES offset for at91sam9x5

In reply to Heiko Schocher

Dear Heiko Schocher,

Quoted 10 lines · Heiko Schocher

on at91sam9x5 PRES offset is 4 in the PMC master clock register.

---

arch/arm/mach-at91/arm926ejs/clock.c | 6 ++++++

1 file changed, 6 insertions(+)

applied to u-boot-atmel/master, thanks!

Best regards,
Andreas Bie?mann

#10 lore raw

PATCH 3/6 arm, at91: add icache support

In reply to Heiko Schocher

add at least icache support for at91 based boards. This speeds up NOR flash access on an at91sam9g15 based board from 15.2 seconds reading 8 MiB from a SPI NOR flash to 5.7 seconds.

---
removed the dcache enable in the gurnard board. Comment says that enabling dcache breaks Ethernet MAC ... why is it then enabled?

@Simon: If you need dache enabled for the gurnard board, arch/arm/mach-at91/arm926ejs/cache.c is the correct place for doing this, I think. Please add there the common functions needed for dcache support on at91 plattforms and undef in the gurnard board configuration CONFIG_SYS_DCACHE_OFF.

 arch/arm/mach-at91/arm926ejs/Makefile |  1 +
 arch/arm/mach-at91/arm926ejs/cache.c  | 29 +++++++++++++++++++++++++++++
 board/bluewater/gurnard/gurnard.c     |  6 ------
 3 files changed, 30 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm/mach-at91/arm926ejs/cache.c
arch/arm/mach-at91/arm926ejs/Makefile +1 -0
index ddc323f..d36e15a 100644
@@ -18,6 +18,7 @@ obj-$(CONFIG_AT91SAM9N12)	+= at91sam9n12_devices.o
 obj-$(CONFIG_AT91SAM9X5)	+= at91sam9x5_devices.o
 obj-$(CONFIG_AT91_EFLASH)	+= eflash.o
 obj-$(CONFIG_AT91_LED)	+= led.o
+obj-y += cache.o
 obj-y += clock.o
 obj-y += cpu.o
 obj-y	+= reset.o
arch/arm/mach-at91/arm926ejs/cache.c new file +29 -0
new file mode 100644
index 0000000..8813706
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2016
+ * Heiko Schocher, DENX Software Engineering, hs at denx.de.
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+#include <linux/types.h>
+#include <common.h>
+
+void enable_caches(void)
+{
+#ifndef CONFIG_SYS_ICACHE_OFF
+	icache_enable();
+#endif
+}
+
+#ifndef CONFIG_SYS_ICACHE_OFF
+/* Invalidate entire I-cache and branch predictor array */
+void invalidate_icache_all(void)
+{
+	unsigned long i = 0;
+
+	asm ("mcr p15, 0, %0, c7, c5, 0" : : "r" (i));
+}
+#else
+void invalidate_icache_all(void)
+{
+}
+#endif
board/bluewater/gurnard/gurnard.c +0 -6
index 2a36d29..08b1401 100644
@@ -414,12 +414,6 @@ void reset_phy(void)
 {
 }
 
-/* This breaks the Ethernet MAC at present */
-void enable_caches(void)
-{
-	dcache_enable();
-}
-
 /* SPI chip select control - only used for FPGA programming */
 #ifdef CONFIG_ATMEL_SPI
 
Signature · 1 line
2.5.5
#11 lore raw

PATCH 3/6 arm, at91: add icache support

Quoted 18 lines · Heiko Schocher

add at least icache support for at91 based boards. This speeds up NOR flash access on an at91sam9g15 based board from 15.2 seconds reading 8 MiB from a SPI NOR flash to 5.7 seconds.

---
removed the dcache enable in the gurnard board. Comment says that enabling dcache breaks Ethernet MAC ... why is it then enabled?

@Simon: If you need dache enabled for the gurnard board, arch/arm/mach-at91/arm926ejs/cache.c is the correct place for doing this, I think. Please add there the common functions needed for dcache support on at91 plattforms and undef in the gurnard board configuration CONFIG_SYS_DCACHE_OFF.

Quoted 5 lines
 arch/arm/mach-at91/arm926ejs/Makefile |  1 +
 arch/arm/mach-at91/arm926ejs/cache.c  | 29 +++++++++++++++++++++++++++++
 board/bluewater/gurnard/gurnard.c     |  6 ------
 3 files changed, 30 insertions(+), 6 deletions(-)
 create mode 100644 arch/arm/mach-at91/arm926ejs/cache.c
#13 lore raw

PATCH 3/6 arm, at91: add icache support

In reply to Heiko Schocher

Dear Heiko Schocher,

Quoted 19 lines · Heiko Schocher

add at least icache support for at91 based boards. This speeds up NOR flash access on an at91sam9g15 based board from 15.2 seconds reading 8 MiB from a SPI NOR flash to 5.7 seconds.

---
removed the dcache enable in the gurnard board. Comment says that enabling dcache breaks Ethernet MAC ... why is it then enabled?

@Simon: If you need dache enabled for the gurnard board, arch/arm/mach-at91/arm926ejs/cache.c is the correct place for doing this, I think. Please add there the common functions needed for dcache support on at91 plattforms and undef in the gurnard board configuration CONFIG_SYS_DCACHE_OFF.

Quoted 5 lines
arch/arm/mach-at91/arm926ejs/Makefile |  1 +
arch/arm/mach-at91/arm926ejs/cache.c  | 29 +++++++++++++++++++++++++++++
board/bluewater/gurnard/gurnard.c     |  6 ------
3 files changed, 30 insertions(+), 6 deletions(-)

create mode 100644 arch/arm/mach-at91/arm926ejs/cache.c

applied to u-boot-atmel/master, thanks!

Best regards,
Andreas Bie?mann

#14 lore raw

PATCH 4/6 arm, at91: add some missing fields in PIO struct

In reply to Heiko Schocher

add missing

u32     io_delay;       /* 0x110 I/O delay register */
u32     io_driver1;     /* 0x114 I/O driver register 1 */
u32     io_driver2;     /* 0x118 I/O driver register 2 */

fields in struct at91_port.

---

 arch/arm/mach-at91/include/mach/at91_pio.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/mach-at91/include/mach/at91_pio.h +5 -1
index 3012278..8e054e1 100644
@@ -103,7 +103,11 @@ typedef struct at91_port {
 	u32	wpsr;		/* 0xE8 Write Protect Status Register */
 	u32	reserved11[5];	/* */
 	u32	schmitt;	/* 0x100 Schmitt Trigger Register */
-	u32	reserved12[63];
+	u32	reserved12[3];
+	u32	io_delay;	/* 0x110 I/O delay register */
+	u32	io_driver1;	/* 0x114 I/O driver register 1 */
+	u32	io_driver2;	/* 0x118 I/O driver register 2 */
+	u32	reserved13[57];
 #else
 	u32	reserved6[85];
 #endif
Signature · 1 line
2.5.5
#15 lore raw

PATCH 4/6 arm, at91: add some missing fields in PIO struct

Quoted 12 lines

-----Original Message-----
From: U-Boot [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Heiko Schocher
Sent: 2016?8?17? 15:13
To: U-Boot Mailing List <[email protected]>
Cc: Bo Shen <[email protected]>
Subject: [U-Boot] [PATCH 4/6] arm, at91: add some missing fields in PIO struct

add missing

Quoted 7 lines
u32     io_delay;       /* 0x110 I/O delay register */
u32     io_driver1;     /* 0x114 I/O driver register 1 */
u32     io_driver2;     /* 0x118 I/O driver register 2 */

fields in struct at91_port.

Quoted 30 lines

---

 arch/arm/mach-at91/include/mach/at91_pio.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/mach- renamed from arch/arm/mach-at91/include/mach/at91_pio.h +0 -0

at91/include/mach/at91_pio.h
index 3012278..8e054e1 100644

arch/arm/mach-at91/include/mach/at91_pio.h +5 -2
@@ -103,7 +103,11 @@ typedef struct at91_port {
 	u32	wpsr;		/* 0xE8 Write Protect Status Register */
 	u32	reserved11[5];	/* */
 	u32	schmitt;	/* 0x100 Schmitt Trigger Register */
-	u32	reserved12[63];
+	u32	reserved12[3];
+	u32	io_delay;	/* 0x110 I/O delay register */
+	u32	io_driver1;	/* 0x114 I/O driver register 1 */
+	u32	io_driver2;	/* 0x118 I/O driver register 2 */
+	u32	reserved13[57];
 #else
 	u32	reserved6[85];
 #endif
--

2.5.5

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#16 lore raw

PATCH 4/6 arm, at91: add some missing fields in PIO struct

In reply to Heiko Schocher
Quoted 5 lines · Heiko Schocher

add missing

u32     io_delay;       /* 0x110 I/O delay register */
u32     io_driver1;     /* 0x114 I/O driver register 1 */
u32     io_driver2;     /* 0x118 I/O driver register 2 */

This is also a mess ... it is true for sam9x5, but sama5d4 has 0x110 reserved, 0x114 reserved and 0x118 I/O driver register 1, same for sama5d3 and persumably others ...

Why is is needed here? Couldn't we switch to device tree on the long run?

Andreas

Quoted 27 lines

fields in struct at91_port.

---

 arch/arm/mach-at91/include/mach/at91_pio.h | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
arch/arm/mach-at91/include/mach/at91_pio.h +5 -1
index 3012278..8e054e1 100644
@@ -103,7 +103,11 @@ typedef struct at91_port {
 	u32	wpsr;		/* 0xE8 Write Protect Status Register */
 	u32	reserved11[5];	/* */
 	u32	schmitt;	/* 0x100 Schmitt Trigger Register */
-	u32	reserved12[63];
+	u32	reserved12[3];
+	u32	io_delay;	/* 0x110 I/O delay register */
+	u32	io_driver1;	/* 0x114 I/O driver register 1 */
+	u32	io_driver2;	/* 0x118 I/O driver register 2 */
+	u32	reserved13[57];
 #else
 	u32	reserved6[85];
 #endif
#17 lore raw

PATCH 5/6 at91: add function to set IO drive

In reply to Heiko Schocher

add new function to set I/O drive.

---

 arch/arm/mach-at91/include/mach/at91_pio.h |  5 +++++
 arch/arm/mach-at91/include/mach/gpio.h     |  2 ++
 drivers/gpio/at91_gpio.c                   | 29 +++++++++++++++++++++++++++++
 3 files changed, 36 insertions(+)
arch/arm/mach-at91/include/mach/at91_pio.h +5 -0
index 8e054e1..535208a 100644
@@ -134,6 +134,7 @@ int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div);
 int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on);
 int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin);
 #endif
+int at91_set_pio_io_drive(unsigned port, unsigned pin, int value);
 int at91_set_pio_input(unsigned port, unsigned pin, int use_pullup);
 int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on);
 int at91_set_pio_output(unsigned port, unsigned pin, int value);
@@ -151,4 +152,8 @@ int at91_get_pio_value(unsigned port, unsigned pin);
 #define	AT91_PIO_PORTD		0x3
 #define	AT91_PIO_PORTE		0x4
 
+/* allowed I/O driver values */
+#define AT91_PIO_HI_DRIVE	0
+#define AT91_PIO_MEDIUM_DRIVE	1
+#define AT91_PIO_LOW_DRIVE	2
 #endif
arch/arm/mach-at91/include/mach/gpio.h +2 -0
index 6d2a7b7..2b89309 100644
@@ -227,6 +227,8 @@ static inline unsigned pin_to_mask(unsigned pin)
 	at91_set_pio_value((x - PIN_BASE) / 32,(x % 32), y)
 #define at91_get_gpio_value(x) \
 	at91_get_pio_value((x - PIN_BASE) / 32,(x % 32))
+#define at91_set_gpio_io_drive(x, v) \
+	at91_set_pio_io_drive((x - PIN_BASE) / 32,(x % 32), v)
 #else
 #define at91_set_gpio_value(x, y)	at91_set_pio_value(x, y)
 #define at91_get_gpio_value(x)		at91_get_pio_value(x)
drivers/gpio/at91_gpio.c +29 -0
index 8e52e3d..1f624f8 100644
@@ -358,6 +358,35 @@ int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
 	return 0;
 }
 
+#if defined(CPU_HAS_PIO3)
+/*
+ * set I/O driver value
+ */
+int at91_set_pio_io_drive(unsigned port, unsigned pin, int value)
+{
+	struct at91_port *at91_port = at91_pio_get_port(port);
+	u32 *reg;
+	u32 mask;
+
+	if (pin > 15) {
+		reg = &at91_port->io_driver2;
+		pin -= 16;
+	} else {
+		reg = &at91_port->io_driver1;
+	}
+
+	mask = 0x3 << (pin * 2);
+	clrsetbits_le32(reg, mask, value << (pin * 2));
+	return 0;
+}
+#else
+int at91_set_pio_io_drive(unsigned port, unsigned pin, int value)
+{
+	return -ENOENT;
+}
+#endif
+
+
 static void at91_set_port_value(struct at91_port *at91_port, int offset,
 				int value)
 {
Signature · 1 line
2.5.5
#18 lore raw

PATCH 5/6 at91: add function to set IO drive

Quoted 10 lines

-----Original Message-----
From: U-Boot [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Heiko Schocher
Sent: 2016?8?17? 15:13
To: U-Boot Mailing List <[email protected]>
Cc: Bo Shen <[email protected]>
Subject: [U-Boot] [PATCH 5/6] at91: add function to set IO drive

Quoted 3 lines

add new function to set I/O drive.

Quoted 89 lines

---

 arch/arm/mach-at91/include/mach/at91_pio.h |  5 +++++
 arch/arm/mach-at91/include/mach/gpio.h     |  2 ++
 drivers/gpio/at91_gpio.c                   | 29 +++++++++++++++++++++++++++++
 3 files changed, 36 insertions(+)
arch/arm/mach- renamed from arch/arm/mach-at91/include/mach/at91_pio.h +0 -0

at91/include/mach/at91_pio.h
index 8e054e1..535208a 100644

arch/arm/mach-at91/include/mach/at91_pio.h +0 -0
@@ -134,6 +134,7 @@ int at91_set_pio_debounce(unsigned port, unsigned pin,

int is_on, int div); int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on); int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin); #endif
+int at91_set_pio_io_drive(unsigned port, unsigned pin, int value);
int at91_set_pio_input(unsigned port, unsigned pin, int use_pullup); int
at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on); int at91_set_pio_output(unsigned port, unsigned pin, int value); @@ -151,4 +152,8 @@ int at91_get_pio_value(unsigned port, unsigned pin);
#define AT91_PIO_PORTD 0x3
#define AT91_PIO_PORTE 0x4

arch/arm/mach-at91/include/mach/at91_pio.h +4 -0
+/* allowed I/O driver values */
+#define AT91_PIO_HI_DRIVE	0
+#define AT91_PIO_MEDIUM_DRIVE	1
+#define AT91_PIO_LOW_DRIVE	2
 #endif
arch/arm/mach- renamed from arch/arm/mach-at91/include/mach/gpio.h +0 -0

at91/include/mach/gpio.h
index 6d2a7b7..2b89309 100644

arch/arm/mach-at91/include/mach/gpio.h +2 -0
@@ -227,6 +227,8 @@ static inline unsigned pin_to_mask(unsigned pin)
 	at91_set_pio_value((x - PIN_BASE) / 32,(x % 32), y)  #define
 at91_get_gpio_value(x) \
 	at91_get_pio_value((x - PIN_BASE) / 32,(x % 32))
+#define at91_set_gpio_io_drive(x, v) \
+	at91_set_pio_io_drive((x - PIN_BASE) / 32,(x % 32), v)
 #else
 #define at91_set_gpio_value(x, y)	at91_set_pio_value(x, y)
 #define at91_get_gpio_value(x)		at91_get_pio_value(x)
drivers/gpio/at91_gpio.c index renamed from drivers/gpio/at91_gpio.c +0 -0

8e52e3d..1f624f8 100644

drivers/gpio/at91_gpio.c +27 -1
@@ -358,6 +358,35 @@ int at91_set_pio_multi_drive(unsigned port, unsigned pin,
 int is_on)
 	return 0;
 }
 
+#if defined(CPU_HAS_PIO3)
+/*
+ * set I/O driver value
+ */
+int at91_set_pio_io_drive(unsigned port, unsigned pin, int value) {
+	struct at91_port *at91_port = at91_pio_get_port(port);
+	u32 *reg;
+	u32 mask;
+
+	if (pin > 15) {
+		reg = &at91_port->io_driver2;
+		pin -= 16;
+	} else {
+		reg = &at91_port->io_driver1;
+	}
+
+	mask = 0x3 << (pin * 2);
+	clrsetbits_le32(reg, mask, value << (pin * 2));
+	return 0;
+}
+#else
+int at91_set_pio_io_drive(unsigned port, unsigned pin, int value) {
+	return -ENOENT;
+}
+#endif
+
+
 static void at91_set_port_value(struct at91_port *at91_port, int offset,
 				int value)
 {
--

2.5.5

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

#19 lore raw

PATCH 5/6 at91: add function to set IO drive

In reply to Heiko Schocher
Quoted 23 lines · Heiko Schocher

add new function to set I/O drive.

---

 arch/arm/mach-at91/include/mach/at91_pio.h |  5 +++++
 arch/arm/mach-at91/include/mach/gpio.h     |  2 ++
 drivers/gpio/at91_gpio.c                   | 29 +++++++++++++++++++++++++++++
 3 files changed, 36 insertions(+)
arch/arm/mach-at91/include/mach/at91_pio.h +1 -0
index 8e054e1..535208a 100644
@@ -134,6 +134,7 @@ int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div);
 int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on);
 int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin);
 #endif
+int at91_set_pio_io_drive(unsigned port, unsigned pin, int value);
 int at91_set_pio_input(unsigned port, unsigned pin, int use_pullup);
 int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on);
 int at91_set_pio_output(unsigned port, unsigned pin, int value);

arch/arm/mach-at91/include/mach/at91_pio.h int at91_get_pio_value(unsigned port, unsigned pin); · line 156

Quoted 5 lines
arch/arm/mach-at91/include/mach/at91_pio.h +2 -0
@@ -151,4 +152,8 @@ int at91_get_pio_value(unsigned port, unsigned pin);
 #define	AT91_PIO_PORTD		0x3
 #define	AT91_PIO_PORTE		0x4
 
+/* allowed I/O driver values */
+#define AT91_PIO_HI_DRIVE	0

sama5 has 0 + 1 low drive, 2 medium and 3 hi :(

Quoted 57 lines
arch/arm/mach-at91/include/mach/at91_pio.h +2 -0
+#define AT91_PIO_MEDIUM_DRIVE	1
+#define AT91_PIO_LOW_DRIVE	2
 #endif
arch/arm/mach-at91/include/mach/gpio.h +2 -0
index 6d2a7b7..2b89309 100644
@@ -227,6 +227,8 @@ static inline unsigned pin_to_mask(unsigned pin)
 	at91_set_pio_value((x - PIN_BASE) / 32,(x % 32), y)
 #define at91_get_gpio_value(x) \
 	at91_get_pio_value((x - PIN_BASE) / 32,(x % 32))
+#define at91_set_gpio_io_drive(x, v) \
+	at91_set_pio_io_drive((x - PIN_BASE) / 32,(x % 32), v)
 #else
 #define at91_set_gpio_value(x, y)	at91_set_pio_value(x, y)
 #define at91_get_gpio_value(x)		at91_get_pio_value(x)
drivers/gpio/at91_gpio.c +29 -0
index 8e52e3d..1f624f8 100644
@@ -358,6 +358,35 @@ int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
 	return 0;
 }
 
+#if defined(CPU_HAS_PIO3)
+/*
+ * set I/O driver value
+ */
+int at91_set_pio_io_drive(unsigned port, unsigned pin, int value)
+{
+	struct at91_port *at91_port = at91_pio_get_port(port);
+	u32 *reg;
+	u32 mask;
+
+	if (pin > 15) {
+		reg = &at91_port->io_driver2;
+		pin -= 16;
+	} else {
+		reg = &at91_port->io_driver1;
+	}
+
+	mask = 0x3 << (pin * 2);
+	clrsetbits_le32(reg, mask, value << (pin * 2));
+	return 0;
+}
+#else
+int at91_set_pio_io_drive(unsigned port, unsigned pin, int value)
+{
+	return -ENOENT;
+}
+#endif
+
+
 static void at91_set_port_value(struct at91_port *at91_port, int offset,
 				int value)
 {
#20 lore raw

RFC PATCH 6/6 at91: SPL clock fix for AT91SAM9G15 based boards.

In reply to Heiko Schocher

on a at91sam9g15 basd board I need another MOR register init as common for at91 based boards. Changes:

- set AT91_PMC_MOR_KEY to 0x37, without this writting has no effect to tthis register.
- AT91_PMC_MOR_OSCOUNT to 0
- set AT91_PMC_MOR_MOSCEN and AT91_PMC_MOR_MOSCSEL

---
I post this as a RFC patch, because this settings may break other boards ... so if this is not a valid common setting, I propose to make this setting board configurable through a weak function ...

 arch/arm/mach-at91/spl_at91.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
arch/arm/mach-at91/spl_at91.c +10 -3
index cc3341a..4d8ed26 100644
@@ -31,13 +31,20 @@ static void enable_ext_reset(void)
 void lowlevel_clock_init(void)
 {
 	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 tmp;
 
 	if (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) {
-		/* Enable Main Oscillator */
-		writel(AT91_PMC_MOSCS | (0x40 << 8), &pmc->mor);
+		tmp = readl(&pmc->mor);
+		tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff);
+		tmp &= ~AT91_PMC_MOR_KEY(0xff);
+		tmp |= AT91_PMC_MOR_MOSCEN;
+		tmp |= AT91_PMC_MOR_MOSCSEL;
+		tmp |= AT91_PMC_MOR_OSCOUNT(0);
+		tmp |= AT91_PMC_MOR_KEY(0x37);
+		writel(tmp, &pmc->mor);
 
 		/* Wait until Main Oscillator is stable */
-		while (!(readl(&pmc->sr) & AT91_PMC_MOSCS))
+		while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS))
 			;
 	}
 
Signature · 1 line
2.5.5
#21 lore raw

RFC PATCH 6/6 at91: SPL clock fix for AT91SAM9G15 based boards.

Hi Heiko,

Quoted 37 lines

-----Original Message-----
From: U-Boot [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Heiko Schocher
Sent: 2016?8?17? 15:13
To: U-Boot Mailing List <[email protected]>
Cc: Bo Shen <[email protected]>
Subject: [U-Boot] [PATCH 6/6] [RFC] at91: SPL clock fix for AT91SAM9G15 based boards.

on a at91sam9g15 basd board I need another MOR register init as common for at91 based boards. Changes:
MM
- set AT91_PMC_MOR_KEY to 0x37, without this writting has
no effect to tthis register.
- AT91_PMC_MOR_OSCOUNT to 0
- set AT91_PMC_MOR_MOSCEN and AT91_PMC_MOR_MOSCSEL

---
I post this as a RFC patch, because this settings may break other boards ... so if this is not a valid common setting, I propose to make this setting board configurable through a weak function ...

 arch/arm/mach-at91/spl_at91.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
arch/arm/mach-at91/spl_at91.c index renamed from arch/arm/mach-at91/spl_at91.c +0 -0

cc3341a..4d8ed26 100644

arch/arm/mach-at91/spl_at91.c +1 -0
@@ -31,13 +31,20 @@ static void enable_ext_reset(void)  void
 lowlevel_clock_init(void)  {
 	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 tmp;
 
 	if (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) {

arch/arm/mach-at91/spl_at91.c static void enable_ext_reset(void) void · line 43

Quoted 10 lines
arch/arm/mach-at91/spl_at91.c +8 -2
-		/* Enable Main Oscillator */
-		writel(AT91_PMC_MOSCS | (0x40 << 8), &pmc->mor);
+		tmp = readl(&pmc->mor);
+		tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff);
+		tmp &= ~AT91_PMC_MOR_KEY(0xff);
+		tmp |= AT91_PMC_MOR_MOSCEN;
+		tmp |= AT91_PMC_MOR_MOSCSEL;
+		tmp |= AT91_PMC_MOR_OSCOUNT(0);
+		tmp |= AT91_PMC_MOR_KEY(0x37);
+		writel(tmp, &pmc->mor);

I think, it needs two steps to configure the CKGR_MOR register.
1./ set AT91_PMC_MOR_MOSCEN, then wait to check the MOSCXTS bit of the PMC Status Register. 2./ set AT91_PMC_MOR_MOSCSEL, then wait for check the MOSCSLES bit of the PMC Status Register.

AT91_PMC_MOR_OSCOUNT should not be set 0.

Quoted 10 lines
arch/arm/mach-at91/spl_at91.c +1 -2
 		/* Wait until Main Oscillator is stable */
-		while (!(readl(&pmc->sr) & AT91_PMC_MOSCS))
+		while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS))
 			;
 	}
 
--

2.5.5

Quoted 4 lines

_______________________________________________
U-Boot mailing list
U-Boot at lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Best Regards,
Wenyou Yang

#22 lore raw

RFC PATCH 6/6 at91: SPL clock fix for AT91SAM9G15 based boards.

In reply to Heiko Schocher

Hi Heiko,

Quoted 28 lines · Heiko Schocher

on a at91sam9g15 basd board I need another MOR register init as common for at91 based boards. Changes:

- set AT91_PMC_MOR_KEY to 0x37, without this writting has no effect to tthis register.
- AT91_PMC_MOR_OSCOUNT to 0
- set AT91_PMC_MOR_MOSCEN and AT91_PMC_MOR_MOSCSEL

---
I post this as a RFC patch, because this settings may break other boards ... so if this is not a valid common setting, I propose to make this setting board configurable through a weak function ...

 arch/arm/mach-at91/spl_at91.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
arch/arm/mach-at91/spl_at91.c +1 -0
index cc3341a..4d8ed26 100644
@@ -31,13 +31,20 @@ static void enable_ext_reset(void)
 void lowlevel_clock_init(void)
 {
 	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 tmp;

arch/arm/mach-at91/spl_at91.c static void enable_ext_reset(void) · line 42

Quoted 10 lines
arch/arm/mach-at91/spl_at91.c +6 -2
 
 	if (!(readl(&pmc->sr) & AT91_PMC_MOSCS)) {
-		/* Enable Main Oscillator */
-		writel(AT91_PMC_MOSCS | (0x40 << 8), &pmc->mor);
+		tmp = readl(&pmc->mor);
+		tmp &= ~AT91_PMC_MOR_OSCOUNT(0xff);
+		tmp &= ~AT91_PMC_MOR_KEY(0xff);
+		tmp |= AT91_PMC_MOR_MOSCEN;
+		tmp |= AT91_PMC_MOR_MOSCSEL;
+		tmp |= AT91_PMC_MOR_OSCOUNT(0);

this is weird configuration to me. Why do you set the counter to 0? Is the Oscillator really immediately stable? Or is it an external Oscillator which should be bypassed?

Nevertheless, you should do a two step procedure here according to PMC Programming Sequence. First switching the Oscillator on and second activate the master clock from it. Each of the steps may poll the status register for appropriate flags (or use interrupts).

Any chance to merge this lowlevel clock init with spl_atmel? At least this part for enabling main oscillator.

Andreas

Quoted 10 lines
arch/arm/mach-at91/spl_at91.c +3 -1
+		tmp |= AT91_PMC_MOR_KEY(0x37);
+		writel(tmp, &pmc->mor);
 
 		/* Wait until Main Oscillator is stable */
-		while (!(readl(&pmc->sr) & AT91_PMC_MOSCS))
+		while (!(readl(&pmc->sr) & AT91_PMC_IXR_MOSCS))
 			;
 	}
 
#23 lore raw

cover at91: at91sam9g15 improvements

In reply to Heiko Schocher

Hello Andreas,

Am 17.08.2016 um 09:13 schrieb Heiko Schocher:

Quoted 42 lines

This series add some missing things for an at91sam9g15 board, which gets not mainlined, but there are common fixes, which are posted with this patchserie.

2 important things:
- enable icache for AT91 based boards
speeds up them a lot, for example reading 8MiB from an SPI NOR flash into RAM takes with icache off ~15 seconds with icache enabled only ~5 seconds.

gurnard board defines a board specific enable_caches() function which enables dcache .. with acomment that this breaks Ethernet MAC ... I removed this board specific function, and dcache enable functions should be added in arch/arm/mach-at91/arm926ejs/cache.c

- SPL clock fix, posted as RFC, as it may breaks other boards. If so, we may make clock settings in SPL board configurable through a weak function?

buildman finds no new errors/warnings with the patches from this patchseries applied.

Heiko Schocher (6):
arm: at91: mpddrc: add missing MPDDRC_MD defines
ARM: at91: clock: correct PRES offset for at91sam9x5 arm, at91: add icache support
arm, at91: add some missing fields in PIO struct
at91: add function to set IO drive
[RFC] at91: SPL clock fix for AT91SAM9G15 based boards.

  arch/arm/mach-at91/arm926ejs/Makefile          |  1 +
  arch/arm/mach-at91/arm926ejs/cache.c           | 29 ++++++++++++++++++++++++++
  arch/arm/mach-at91/arm926ejs/clock.c           |  6 ++++++
  arch/arm/mach-at91/include/mach/at91_pio.h     | 11 +++++++++-
  arch/arm/mach-at91/include/mach/atmel_mpddrc.h |  3 +++
  arch/arm/mach-at91/include/mach/gpio.h         |  2 ++
  arch/arm/mach-at91/spl_at91.c                  | 13 +++++++++---
  board/bluewater/gurnard/gurnard.c              |  6 ------
  drivers/gpio/at91_gpio.c                       | 29 ++++++++++++++++++++++++++
  9 files changed, 90 insertions(+), 10 deletions(-)
Quoted 2 lines

create mode 100644 arch/arm/mach-at91/arm926ejs/cache.c

This patchset is now pending for more than 1 month ... are there any issues, or do you plan to apply it?

Thanks!

bye,
Heiko

Signature · 2 lines
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany