Skip to contentSkip to conversation

arm: at91: clock: Add the generated clock support

PATCH Superseded Wenyou Yang 3 participants 5 messages Oct 26, 2015 – Oct 30, 2015

Subsystems (3)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 arm: at91: clock: Add the generated clock support

Some peripherals may need a second clock source that may be different from the system clock. This second clock is the generated clock (GCK) and is managed by the PMC via PMC_PCR.

For simplicity, the clock source of the GCK is fixed to PLLA_CLK.

---
Hi Andreas, Bo Shen,

Thank you for your so many advices.
Bo Shen, sorry for forgetting version 2 to send for your comments.

Please help review, thank you in advance.

Best Regards,
Wenyou Yang

Changes in v2:
1./ add timeout to wait for GCK ready.
2./ add warning for timeout to wait for GCK ready.
3./ add printout when the improper GCK clock source is selected. 4./ rework AT91_PMC_PCR_GCKDIV_(x) macro to make sure x is right.

 arch/arm/mach-at91/armv7/clock.c           |   65 ++++++++++++++++++++++++++++
 arch/arm/mach-at91/include/mach/at91_pmc.h |   13 ++++++
 arch/arm/mach-at91/include/mach/clk.h      |    3 ++
 3 files changed, 81 insertions(+)
arch/arm/mach-at91/armv7/clock.c +65 -0
index 0bf453e..de95d6b 100644
@@ -5,6 +5,7 @@
  * Copyright (C) 2005 Ivan Kokshaysky
  * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <[email protected]>
  * Copyright (C) 2013 Bo Shen <[email protected]>
+ * Copyright (C) 2015 Wenyou Yang <[email protected]>
  *
  * SPDX-License-Identifier:	GPL-2.0+
  */
@@ -173,3 +174,67 @@ void at91_periph_clk_disable(int id)
 
 	writel(regval, &pmc->pcr);
 }
+
+void at91_enable_periph_generated_clk(u32 id)
+{
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 regval, status;
+	u32 timeout = 1000;
+
+	if (id > AT91_PMC_PCR_PID_MASK)
+		return;
+
+	writel(id, &pmc->pcr);
+	regval = readl(&pmc->pcr);
+	regval &= ~AT91_PMC_PCR_GCKCSS;
+	regval &= ~AT91_PMC_PCR_GCKDIV;
+	regval |= AT91_PMC_PCR_GCKCSS_PLLA_CLK |
+		  AT91_PMC_PCR_CMD_WRITE |
+		  AT91_PMC_PCR_GCKDIV_(1) |
+		  AT91_PMC_PCR_GCKEN;
+
+	writel(regval, &pmc->pcr);
+
+	do {
+		udelay(1);
+		status = readl(&pmc->sr);
+	} while ((!!(--timeout)) && (!(status & AT91_PMC_GCKRDY)));
+
+	if (!timeout)
+		printf("Timeout waiting for GCK ready!\n");
+}
+
+u32 at91_get_periph_generated_clk(u32 id)
+{
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 regval, clk_source, div;
+	u32 freq;
+
+	if (id > AT91_PMC_PCR_PID_MASK)
+		return 0;
+
+	writel(id, &pmc->pcr);
+	regval = readl(&pmc->pcr);
+
+	clk_source = regval & AT91_PMC_PCR_GCKCSS;
+	switch (clk_source) {
+	case AT91_PMC_PCR_GCKCSS_SLOW_CLK:
+		freq = CONFIG_SYS_AT91_SLOW_CLOCK;
+		break;
+	case AT91_PMC_PCR_GCKCSS_MAIN_CLK:
+		freq = gd->arch.main_clk_rate_hz;
+		break;
+	case AT91_PMC_PCR_GCKCSS_PLLA_CLK:
+		freq = gd->arch.plla_rate_hz;
+		break;
+	default:
+		printf("Improper GCK clock source selection!\n");
+		freq = 0;
+		break;
+	}
+
+	div = ((regval & AT91_PMC_PCR_GCKDIV) >> AT91_PMC_PCR_GCKDIV_OFFSET);
+	div += 1;
+
+	return freq / div;
+}
arch/arm/mach-at91/include/mach/at91_pmc.h +13 -0
index 8a3fb94..5a51be6 100644
@@ -153,8 +153,20 @@ typedef struct at91_pmc {
 #define AT91_PMC_IXR_MOSCSELS		0x00010000
 
 #define AT91_PMC_PCR_PID_MASK		(0x3f)
+#define AT91_PMC_PCR_GCKCSS		(0x7 << 8)
+#define		AT91_PMC_PCR_GCKCSS_SLOW_CLK	(0x0 << 8)
+#define		AT91_PMC_PCR_GCKCSS_MAIN_CLK	(0x1 << 8)
+#define		AT91_PMC_PCR_GCKCSS_PLLA_CLK	(0x2 << 8)
+#define		AT91_PMC_PCR_GCKCSS_UPLL_CLK	(0x3 << 8)
+#define		AT91_PMC_PCR_GCKCSS_MCK_CLK	(0x4 << 8)
+#define		AT91_PMC_PCR_GCKCSS_AUDIO_CLK	(0x5 << 8)
 #define AT91_PMC_PCR_CMD_WRITE		(0x1 << 12)
+#define AT91_PMC_PCR_DIV		(0x3 << 16)
+#define AT91_PMC_PCR_GCKDIV		(0xff << 20)
+#define		AT91_PMC_PCR_GCKDIV_(x)		((x & 0xff) << 20)
+#define		AT91_PMC_PCR_GCKDIV_OFFSET	20
 #define AT91_PMC_PCR_EN			(0x1 << 28)
+#define AT91_PMC_PCR_GCKEN		(0x1 << 29)
 
 #define		AT91_PMC_PCK		(1 <<  0)		/* Processor Clock */
 #define		AT91RM9200_PMC_UDP	(1 <<  1)		/* USB Devcice Port Clock [AT91RM9200 only] */
@@ -236,6 +248,7 @@ typedef struct at91_pmc {
 #define		AT91_PMC_PCK1RDY	(1 <<  9)		/* Programmable Clock 1 */
 #define		AT91_PMC_PCK2RDY	(1 << 10)		/* Programmable Clock 2 */
 #define		AT91_PMC_PCK3RDY	(1 << 11)		/* Programmable Clock 3 */
+#define		AT91_PMC_GCKRDY		(1 << 24)
 
 #define		AT91_PMC_PROTKEY	0x504d4301	/* Activation Code */
 #endif
arch/arm/mach-at91/include/mach/clk.h +3 -0
index 1d45e2d..dd1ed96 100644
@@ -119,4 +119,7 @@ static inline unsigned long get_pit_clk_rate(void)
 int at91_clock_init(unsigned long main_clock);
 void at91_periph_clk_enable(int id);
 void at91_periph_clk_disable(int id);
+void at91_enable_periph_generated_clk(u32 id);
+u32 at91_get_periph_generated_clk(u32 id);
+
 #endif /* __ASM_ARM_ARCH_CLK_H__ */
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH v2 1/1 arm: at91: clock: Add the generated clock support

Hi Wenyou,

Quoted 4 lines · Wenyou Yang

Some peripherals may need a second clock source that may be different from the system clock. This second clock is the generated clock (GCK) and is managed by the PMC via PMC_PCR.

Quoted 8 lines

For simplicity, the clock source of the GCK is fixed to PLLA_CLK.

---
Hi Andreas, Bo Shen,

Thank you for your so many advices.
Bo Shen, sorry for forgetting version 2 to send for your comments.

It's OK, don't worry.

At that time the datasheet is not available, now it is available now. So, add one more comment.

Quoted 40 lines

Please help review, thank you in advance.

Best Regards,
Wenyou Yang

Changes in v2:
1./ add timeout to wait for GCK ready.
2./ add warning for timeout to wait for GCK ready.
3./ add printout when the improper GCK clock source is selected. 4./ rework AT91_PMC_PCR_GCKDIV_(x) macro to make sure x is right.

  arch/arm/mach-at91/armv7/clock.c           |   65 ++++++++++++++++++++++++++++
  arch/arm/mach-at91/include/mach/at91_pmc.h |   13 ++++++
  arch/arm/mach-at91/include/mach/clk.h      |    3 ++
  3 files changed, 81 insertions(+)
arch/arm/mach-at91/armv7/clock.c +9 -0
index 0bf453e..de95d6b 100644
@@ -5,6 +5,7 @@
   * Copyright (C) 2005 Ivan Kokshaysky
   * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <[email protected]>
   * Copyright (C) 2013 Bo Shen <[email protected]>
+ * Copyright (C) 2015 Wenyou Yang <[email protected]>
   *
   * SPDX-License-Identifier:	GPL-2.0+
   */
@@ -173,3 +174,67 @@ void at91_periph_clk_disable(int id)
 
  	writel(regval, &pmc->pcr);
  }
+
+void at91_enable_periph_generated_clk(u32 id)
+{
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 regval, status;
+	u32 timeout = 1000;
+
+	if (id > AT91_PMC_PCR_PID_MASK)

arch/arm/mach-at91/armv7/clock.c void at91_periph_clk_disable(int id) · line 194

Quoted 10 lines
arch/arm/mach-at91/armv7/clock.c +10 -0
+		return;
+
+	writel(id, &pmc->pcr);
+	regval = readl(&pmc->pcr);
+	regval &= ~AT91_PMC_PCR_GCKCSS;
+	regval &= ~AT91_PMC_PCR_GCKDIV;
+	regval |= AT91_PMC_PCR_GCKCSS_PLLA_CLK |
+		  AT91_PMC_PCR_CMD_WRITE |
+		  AT91_PMC_PCR_GCKDIV_(1) |
+		  AT91_PMC_PCR_GCKEN;

You hard code the GCKCSS and GCKDIV. Would it be OK for all peripheral which need this kind of clock? Can you make it as a parameter?

Quoted 85 lines
arch/arm/mach-at91/armv7/clock.c +46 -0
+
+	writel(regval, &pmc->pcr);
+
+	do {
+		udelay(1);
+		status = readl(&pmc->sr);
+	} while ((!!(--timeout)) && (!(status & AT91_PMC_GCKRDY)));
+
+	if (!timeout)
+		printf("Timeout waiting for GCK ready!\n");
+}
+
+u32 at91_get_periph_generated_clk(u32 id)
+{
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 regval, clk_source, div;
+	u32 freq;
+
+	if (id > AT91_PMC_PCR_PID_MASK)
+		return 0;
+
+	writel(id, &pmc->pcr);
+	regval = readl(&pmc->pcr);
+
+	clk_source = regval & AT91_PMC_PCR_GCKCSS;
+	switch (clk_source) {
+	case AT91_PMC_PCR_GCKCSS_SLOW_CLK:
+		freq = CONFIG_SYS_AT91_SLOW_CLOCK;
+		break;
+	case AT91_PMC_PCR_GCKCSS_MAIN_CLK:
+		freq = gd->arch.main_clk_rate_hz;
+		break;
+	case AT91_PMC_PCR_GCKCSS_PLLA_CLK:
+		freq = gd->arch.plla_rate_hz;
+		break;
+	default:
+		printf("Improper GCK clock source selection!\n");
+		freq = 0;
+		break;
+	}
+
+	div = ((regval & AT91_PMC_PCR_GCKDIV) >> AT91_PMC_PCR_GCKDIV_OFFSET);
+	div += 1;
+
+	return freq / div;
+}
arch/arm/mach-at91/include/mach/at91_pmc.h +13 -0
index 8a3fb94..5a51be6 100644
@@ -153,8 +153,20 @@ typedef struct at91_pmc {
  #define AT91_PMC_IXR_MOSCSELS		0x00010000
 
  #define AT91_PMC_PCR_PID_MASK		(0x3f)
+#define AT91_PMC_PCR_GCKCSS		(0x7 << 8)
+#define		AT91_PMC_PCR_GCKCSS_SLOW_CLK	(0x0 << 8)
+#define		AT91_PMC_PCR_GCKCSS_MAIN_CLK	(0x1 << 8)
+#define		AT91_PMC_PCR_GCKCSS_PLLA_CLK	(0x2 << 8)
+#define		AT91_PMC_PCR_GCKCSS_UPLL_CLK	(0x3 << 8)
+#define		AT91_PMC_PCR_GCKCSS_MCK_CLK	(0x4 << 8)
+#define		AT91_PMC_PCR_GCKCSS_AUDIO_CLK	(0x5 << 8)
  #define AT91_PMC_PCR_CMD_WRITE		(0x1 << 12)
+#define AT91_PMC_PCR_DIV		(0x3 << 16)
+#define AT91_PMC_PCR_GCKDIV		(0xff << 20)
+#define		AT91_PMC_PCR_GCKDIV_(x)		((x & 0xff) << 20)
+#define		AT91_PMC_PCR_GCKDIV_OFFSET	20
  #define AT91_PMC_PCR_EN			(0x1 << 28)
+#define AT91_PMC_PCR_GCKEN		(0x1 << 29)
 
  #define		AT91_PMC_PCK		(1 <<  0)		/* Processor Clock */
  #define		AT91RM9200_PMC_UDP	(1 <<  1)		/* USB Devcice Port Clock [AT91RM9200 only] */
@@ -236,6 +248,7 @@ typedef struct at91_pmc {
  #define		AT91_PMC_PCK1RDY	(1 <<  9)		/* Programmable Clock 1 */
  #define		AT91_PMC_PCK2RDY	(1 << 10)		/* Programmable Clock 2 */
  #define		AT91_PMC_PCK3RDY	(1 << 11)		/* Programmable Clock 3 */
+#define		AT91_PMC_GCKRDY		(1 << 24)
 
  #define		AT91_PMC_PROTKEY	0x504d4301	/* Activation Code */
  #endif
arch/arm/mach-at91/include/mach/clk.h +0 -0
index 1d45e2d..dd1ed96 100644

arch/arm/mach-at91/include/mach/clk.h static inline unsigned long get_pit_clk_rate(void) · line 125

Quoted 7 lines
arch/arm/mach-at91/include/mach/clk.h +3 -0
@@ -119,4 +119,7 @@ static inline unsigned long get_pit_clk_rate(void)
  int at91_clock_init(unsigned long main_clock);
  void at91_periph_clk_enable(int id);
  void at91_periph_clk_disable(int id);
+void at91_enable_periph_generated_clk(u32 id);
+u32 at91_get_periph_generated_clk(u32 id);
+
  #endif /* __ASM_ARM_ARCH_CLK_H__ */

Best Regards,
Bo Shen

#2 lore raw

PATCH v2 1/1 arm: at91: clock: Add the generated clock support

Hi Bo Shen,

Thank you for your review.

Quoted 75 lines

-----Original Message-----
From: Bo Shen [mailto:voice.shen at gmail.com]
Sent: 2015?10?28? 11:14
To: Yang, Wenyou
Cc: U-Boot Mailing List; andreas.devel at googlemail.com
Subject: Re: [PATCH v2] arm: at91: clock: Add the generated clock support

Hi Wenyou,

Quoted 4 lines · Wenyou Yang

Some peripherals may need a second clock source that may be different from the system clock. This second clock is the generated clock (GCK) and is managed by the PMC via PMC_PCR.

Quoted 8 lines

For simplicity, the clock source of the GCK is fixed to PLLA_CLK.

---
Hi Andreas, Bo Shen,

Thank you for your so many advices.
Bo Shen, sorry for forgetting version 2 to send for your comments.

It's OK, don't worry.

At that time the datasheet is not available, now it is available now. So, add one more comment.

Quoted 5 lines

Please help review, thank you in advance.

Best Regards,
Wenyou Yang

Quoted 7 lines

Changes in v2:
1./ add timeout to wait for GCK ready.
2./ add warning for timeout to wait for GCK ready.
3./ add printout when the improper GCK clock source is selected. 4./ rework AT91_PMC_PCR_GCKDIV_(x) macro to make sure x is right.

  arch/arm/mach-at91/armv7/clock.c           |   65

++++++++++++++++++++++++++++

arch/arm/mach-at91/armv7/clock.c line 6

Quoted 12 lines
  arch/arm/mach-at91/include/mach/at91_pmc.h |   13 ++++++
  arch/arm/mach-at91/include/mach/clk.h      |    3 ++
  3 files changed, 81 insertions(+)
arch/arm/mach-at91/armv7/clock.c +0 -0
index 0bf453e..de95d6b 100644
@@ -5,6 +5,7 @@
   * Copyright (C) 2005 Ivan Kokshaysky
   * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD

<[email protected]>

Quoted 21 lines
arch/arm/mach-at91/armv7/clock.c +13 -0
   * Copyright (C) 2013 Bo Shen <[email protected]>
+ * Copyright (C) 2015 Wenyou Yang <[email protected]>
   *
   * SPDX-License-Identifier:	GPL-2.0+
   */
@@ -173,3 +174,67 @@ void at91_periph_clk_disable(int id)
 
  	writel(regval, &pmc->pcr);
  }
+
+void at91_enable_periph_generated_clk(u32 id) {
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 regval, status;
+	u32 timeout = 1000;
+
+	if (id > AT91_PMC_PCR_PID_MASK)
+		return;
+
+	writel(id, &pmc->pcr);
+	regval = readl(&pmc->pcr);
+	regval &= ~AT91_PMC_PCR_GCKCSS;
Quoted 8 lines

arch/arm/mach-at91/armv7/clock.c void at91_periph_clk_disable(int id) · line 194

Quoted 5 lines
arch/arm/mach-at91/armv7/clock.c +5 -0
+	regval &= ~AT91_PMC_PCR_GCKDIV;
+	regval |= AT91_PMC_PCR_GCKCSS_PLLA_CLK |
+		  AT91_PMC_PCR_CMD_WRITE |
+		  AT91_PMC_PCR_GCKDIV_(1) |
+		  AT91_PMC_PCR_GCKEN;

You hard code the GCKCSS and GCKDIV. Would it be OK for all peripheral which need this kind of clock? Can you make it as a parameter?

As you know, our use-case is not complex, it is only used for one or two peripherals for now, So to make it simple, use hard-code.

Maybe we will improve it in the future, but now it is enough.

Anyway, thank you for your advice.

Quoted 95 lines
Quoted 31 lines
arch/arm/mach-at91/armv7/clock.c +30 -0
+
+	writel(regval, &pmc->pcr);
+
+	do {
+		udelay(1);
+		status = readl(&pmc->sr);
+	} while ((!!(--timeout)) && (!(status & AT91_PMC_GCKRDY)));
+
+	if (!timeout)
+		printf("Timeout waiting for GCK ready!\n"); }
+
+u32 at91_get_periph_generated_clk(u32 id) {
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 regval, clk_source, div;
+	u32 freq;
+
+	if (id > AT91_PMC_PCR_PID_MASK)
+		return 0;
+
+	writel(id, &pmc->pcr);
+	regval = readl(&pmc->pcr);
+
+	clk_source = regval & AT91_PMC_PCR_GCKCSS;
+	switch (clk_source) {
+	case AT91_PMC_PCR_GCKCSS_SLOW_CLK:
+		freq = CONFIG_SYS_AT91_SLOW_CLOCK;
+		break;
+	case AT91_PMC_PCR_GCKCSS_MAIN_CLK:
+		freq = gd->arch.main_clk_rate_hz;
+		break;

arch/arm/mach-at91/armv7/clock.c void at91_periph_clk_disable(int id)

Quoted 10 lines
arch/arm/mach-at91/armv7/clock.c +10 -0
+	case AT91_PMC_PCR_GCKCSS_PLLA_CLK:
+		freq = gd->arch.plla_rate_hz;
+		break;
+	default:
+		printf("Improper GCK clock source selection!\n");
+		freq = 0;
+		break;
+	}
+
+	div = ((regval & AT91_PMC_PCR_GCKDIV) >>

AT91_PMC_PCR_GCKDIV_OFFSET);

Quoted 19 lines
arch/arm/mach-at91/armv7/clock.c +4 -0
+	div += 1;
+
+	return freq / div;
+}
arch/arm/mach-at91/include/mach/at91_pmc.h +6 -0
index 8a3fb94..5a51be6 100644
@@ -153,8 +153,20 @@ typedef struct at91_pmc {
  #define AT91_PMC_IXR_MOSCSELS		0x00010000
 
  #define AT91_PMC_PCR_PID_MASK		(0x3f)
+#define AT91_PMC_PCR_GCKCSS		(0x7 << 8)
+#define		AT91_PMC_PCR_GCKCSS_SLOW_CLK	(0x0 << 8)
+#define		AT91_PMC_PCR_GCKCSS_MAIN_CLK	(0x1 << 8)
+#define		AT91_PMC_PCR_GCKCSS_PLLA_CLK	(0x2 << 8)
+#define		AT91_PMC_PCR_GCKCSS_UPLL_CLK	(0x3 << 8)
+#define		AT91_PMC_PCR_GCKCSS_MCK_CLK	(0x4 << 8)

arch/arm/mach-at91/include/mach/at91_pmc.h typedef struct at91_pmc { · line 171

Quoted 10 lines
arch/arm/mach-at91/include/mach/at91_pmc.h +6 -0
+#define		AT91_PMC_PCR_GCKCSS_AUDIO_CLK	(0x5 << 8)
  #define AT91_PMC_PCR_CMD_WRITE		(0x1 << 12)
+#define AT91_PMC_PCR_DIV		(0x3 << 16)
+#define AT91_PMC_PCR_GCKDIV		(0xff << 20)
+#define		AT91_PMC_PCR_GCKDIV_(x)		((x & 0xff) << 20)
+#define		AT91_PMC_PCR_GCKDIV_OFFSET	20
  #define AT91_PMC_PCR_EN			(0x1 << 28)
+#define AT91_PMC_PCR_GCKEN		(0x1 << 29)
 
  #define		AT91_PMC_PCK		(1 <<  0)		/*

Processor Clock */

arch/arm/mach-at91/include/mach/at91_pmc.h typedef struct at91_pmc { · line 172

Quoted 1 line
arch/arm/mach-at91/include/mach/at91_pmc.h +0 -0
  #define		AT91RM9200_PMC_UDP	(1 <<  1)		/*

USB Devcice Port Clock [AT91RM9200 only] */

arch/arm/mach-at91/include/mach/at91_pmc.h typedef struct at91_pmc { · line 248

Quoted 2 lines
arch/arm/mach-at91/include/mach/at91_pmc.h +0 -0
@@ -236,6 +248,7 @@ typedef struct at91_pmc {
  #define		AT91_PMC_PCK1RDY	(1 <<  9)		/*

Programmable Clock 1 */

arch/arm/mach-at91/include/mach/at91_pmc.h typedef struct at91_pmc { · line 249

Quoted 1 line
arch/arm/mach-at91/include/mach/at91_pmc.h +0 -0
  #define		AT91_PMC_PCK2RDY	(1 << 10)		/*

Programmable Clock 2 */

arch/arm/mach-at91/include/mach/at91_pmc.h typedef struct at91_pmc { · line 250

Quoted 1 line
arch/arm/mach-at91/include/mach/at91_pmc.h +0 -0
  #define		AT91_PMC_PCK3RDY	(1 << 11)		/*

Programmable Clock 3 */

arch/arm/mach-at91/include/mach/at91_pmc.h typedef struct at91_pmc {

Quoted 3 lines
arch/arm/mach-at91/include/mach/at91_pmc.h +1 -0
+#define		AT91_PMC_GCKRDY		(1 << 24)
 
  #define		AT91_PMC_PROTKEY	0x504d4301	/* Activation Code

*/

Quoted 10 lines
arch/arm/mach-at91/include/mach/at91_pmc.h +0 -0
  #endif
arch/arm/mach-at91/include/mach/clk.h +0 -0
index 1d45e2d..dd1ed96 100644
@@ -119,4 +119,7 @@ static inline unsigned long get_pit_clk_rate(void)
  int at91_clock_init(unsigned long main_clock);
  void at91_periph_clk_enable(int id);
  void at91_periph_clk_disable(int id);
Quoted 8 lines

arch/arm/mach-at91/include/mach/clk.h static inline unsigned long get_pit_clk_rate(void) · line 125

Quoted 5 lines
arch/arm/mach-at91/include/mach/clk.h +3 -0
+void at91_enable_periph_generated_clk(u32 id);
+u32 at91_get_periph_generated_clk(u32 id);
+
  #endif /* __ASM_ARM_ARCH_CLK_H__ */

Best Regards,
Bo Shen

Best Regards,
Wenyou Yang

#3 lore raw

PATCH v2 1/1 arm: at91: clock: Add the generated clock support

Hi Wenyou,

Quoted 24 lines · Wenyou
Quoted 16 lines
Quoted 16 lines
(quoted diff) +0 -0
@@ -173,3 +174,67 @@ void at91_periph_clk_disable(int id)
Quoted 15 lines
Quoted 15 lines
  	writel(regval, &pmc->pcr);
  }
arch/arm/mach-at91/armv7/clock.c +12 -0
+
+void at91_enable_periph_generated_clk(u32 id) {
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 regval, status;
+	u32 timeout = 1000;
+
+	if (id > AT91_PMC_PCR_PID_MASK)
+		return;
+
+	writel(id, &pmc->pcr);
+	regval = readl(&pmc->pcr);
+	regval &= ~AT91_PMC_PCR_GCKCSS;
Quoted 8 lines
Quoted 8 lines
Quoted 5 lines

arch/arm/mach-at91/armv7/clock.c void at91_periph_clk_disable(int id) · line 194

Quoted 5 lines
arch/arm/mach-at91/armv7/clock.c +5 -0
+	regval &= ~AT91_PMC_PCR_GCKDIV;
+	regval |= AT91_PMC_PCR_GCKCSS_PLLA_CLK |
+		  AT91_PMC_PCR_CMD_WRITE |
+		  AT91_PMC_PCR_GCKDIV_(1) |
+		  AT91_PMC_PCR_GCKEN;

You hard code the GCKCSS and GCKDIV. Would it be OK for all peripheral which need this kind of clock? Can you make it as a parameter?

Quoted 4 lines

As you know, our use-case is not complex, it is only used for one or two peripherals for now, So to make it simple, use hard-code.

Maybe we will improve it in the future, but now it is enough.

I think if this can be dealt now, that will be better.

Quoted 1 line

Anyway, thank you for your advice.

You are welcome.

Best Regards,
Bo Shen

#4 lore raw

PATCH v2 1/1 arm: at91: clock: Add the generated clock support

Hi Bo Shen,

Quoted 34 lines

-----Original Message-----
From: Bo Shen [mailto:voice.shen at gmail.com]
Sent: 2015?10?29? 12:06
To: Yang, Wenyou
Cc: U-Boot Mailing List; andreas.devel at googlemail.com
Subject: Re: [PATCH v2] arm: at91: clock: Add the generated clock support

Hi Wenyou,

Quoted 24 lines · Wenyou
Quoted 24 lines
Quoted 24 lines
(quoted diff) +0 -0
@@ -173,3 +174,67 @@ void at91_periph_clk_disable(int id)
Quoted 12 lines
Quoted 12 lines
  	writel(regval, &pmc->pcr);
  }
arch/arm/mach-at91/armv7/clock.c +9 -0
+
+void at91_enable_periph_generated_clk(u32 id) {
+	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
+	u32 regval, status;
+	u32 timeout = 1000;
+
+	if (id > AT91_PMC_PCR_PID_MASK)
+		return;
+
Quoted 8 lines

arch/arm/mach-at91/armv7/clock.c void at91_periph_clk_disable(int id) · line 194

Quoted 8 lines
arch/arm/mach-at91/armv7/clock.c +8 -0
+	writel(id, &pmc->pcr);
+	regval = readl(&pmc->pcr);
+	regval &= ~AT91_PMC_PCR_GCKCSS;
+	regval &= ~AT91_PMC_PCR_GCKDIV;
+	regval |= AT91_PMC_PCR_GCKCSS_PLLA_CLK |
+		  AT91_PMC_PCR_CMD_WRITE |
+		  AT91_PMC_PCR_GCKDIV_(1) |
+		  AT91_PMC_PCR_GCKEN;

You hard code the GCKCSS and GCKDIV. Would it be OK for all peripheral which need this kind of clock? Can you make it as a parameter?

Quoted 6 lines
Quoted 4 lines

As you know, our use-case is not complex, it is only used for one or two peripherals for now, So to make it simple, use hard-code.

Maybe we will improve it in the future, but now it is enough.

I think if this can be dealt now, that will be better.

Thank you for your advice.

The changes is in v3, please help review. Thanks.

Quoted 7 lines
Quoted 2 lines

Anyway, thank you for your advice.

You are welcome.

Best Regards,
Bo Shen

Best Regards,
Wenyou Yang