STM32: Add HSE and PLL to clock source selection [chromiumos/platform/ec : master]

646 views
Skip to first unread message

Daisuke Nojiri (Gerrit)

unread,
Apr 28, 2016, 6:37:21 PM4/28/16
to Vincent Palatin
Daisuke Nojiri has uploaded a new change for review.

https://chromium-review.googlesource.com/341275

Change subject: STM32: Add HSE and PLL to clock source selection
......................................................................

STM32: Add HSE and PLL to clock source selection

This patch adds HSE and PLL as a system clock oscillator for STM32L4.
This allows us to drive the chip at a higher frequency.

BUG=none
BRANCH=tot
TEST=make buildall. Verified console on STM32L476G-Eval using HSE, PLL-HSE,
PLL-HSI, PLL-MSI as an oscillator.

Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
---
M board/stm32l476g-eval/board.h
M chip/stm32/clock-stm32l4.c
M chip/stm32/config_chip.h
M chip/stm32/registers.h
4 files changed, 282 insertions(+), 51 deletions(-)



diff --git a/board/stm32l476g-eval/board.h b/board/stm32l476g-eval/board.h
index d6f9eb7..7ce7875 100644
--- a/board/stm32l476g-eval/board.h
+++ b/board/stm32l476g-eval/board.h
@@ -40,7 +40,18 @@
#undef CONFIG_FLASH

/* Timer selection */
-#define TIM_CLOCK32 5
+#define TIM_CLOCK32 5
+
+/* External clock speeds (8 MHz) */
+#define STM32_HSE_CLOCK 8000000
+
+/* PLL configuration. Freq = STM32_HSE_CLOCK * n/m/r */
+#undef STM32_PLLM
+#define STM32_PLLM 1
+#undef STM32_PLLN
+#define STM32_PLLN 10
+#undef STM32_PLLR
+#define STM32_PLLR 2

#include "gpio_signal.h"

diff --git a/chip/stm32/clock-stm32l4.c b/chip/stm32/clock-stm32l4.c
index 7cbd098..3c71f10 100644
--- a/chip/stm32/clock-stm32l4.c
+++ b/chip/stm32/clock-stm32l4.c
@@ -15,19 +15,18 @@
#include "util.h"

/* High-speed oscillator is 16 MHz */
-#define HSI_CLOCK 16000000
-/*
- * MSI is 2 MHz (default) 1 MHz, depending on ICSCR setting. We use 1 MHz
- * because it's the lowest clock rate we can still run 115200 baud serial
- * for the debug console.
- */
-#define MSI_2MHZ_CLOCK (1 << 21)
-#define MSI_1MHZ_CLOCK (1 << 20)
+#define STM32_HSI_CLOCK 16000000
+/* Multi-speed oscillator is 4 MHz by default */
+#define STM32_MSI_CLOCK 4000000

enum clock_osc {
OSC_INIT = 0, /* Uninitialized */
- OSC_HSI, /* High-speed oscillator */
- OSC_MSI, /* Med-speed oscillator @ 1 MHz */
+ OSC_HSI, /* High-speed internal oscillator */
+ OSC_MSI, /* Multi-speed internal oscillator */
+#ifdef STM32_HSE_CLOCK /* Allows us to catch absence of HSE at comiple
time */
+ OSC_HSE, /* High-speed external oscillator */
+#endif
+ OSC_PLL, /* PLL */
};

static int freq;
@@ -51,13 +50,174 @@
}
}

+static void clock_enable_osc(enum clock_osc osc)
+{
+ uint32_t ready;
+ uint32_t on;
+
+ switch (osc) {
+ case OSC_HSI:
+ ready = STM32_RCC_CR_HSIRDY;
+ on = STM32_RCC_CR_HSION;
+ break;
+ case OSC_MSI:
+ ready = STM32_RCC_CR_MSIRDY;
+ on = STM32_RCC_CR_MSION;
+ break;
+#ifdef STM32_HSE_CLOCK
+ case OSC_HSE:
+ ready = STM32_RCC_CR_HSERDY;
+ on = STM32_RCC_CR_HSEON;
+ break;
+#endif
+ case OSC_PLL:
+ ready = STM32_RCC_CR_PLLRDY;
+ on = STM32_RCC_CR_PLLON;
+ break;
+ default:
+ return;
+ }
+
+ if (!(STM32_RCC_CR & ready)) {
+ /* Enable HSI */
+ STM32_RCC_CR |= on;
+ /* Wait for HSI to be ready */
+ while (!(STM32_RCC_CR & ready))
+ ;
+ }
+}
+
+/* Switch system clock oscillator */
+static void clock_switch_osc(enum clock_osc osc)
+{
+ uint32_t sw;
+ uint32_t sws;
+
+ switch (osc) {
+ case OSC_HSI:
+ sw = STM32_RCC_CFGR_SW_HSI;
+ sws = STM32_RCC_CFGR_SWS_HSI;
+ break;
+ case OSC_MSI:
+ sw = STM32_RCC_CFGR_SW_MSI;
+ sws = STM32_RCC_CFGR_SWS_MSI;
+ break;
+#ifdef STM32_HSE_CLOCK
+ case OSC_HSE:
+ sw = STM32_RCC_CFGR_SW_HSE;
+ sws = STM32_RCC_CFGR_SWS_HSE;
+ break;
+#endif
+ case OSC_PLL:
+ sw = STM32_RCC_CFGR_SW_PLL;
+ sws = STM32_RCC_CFGR_SWS_PLL;
+ break;
+ default:
+ return;
+ }
+
+ STM32_RCC_CFGR = sw;
+ while ((STM32_RCC_CFGR & STM32_RCC_CFGR_SWS_MASK) != sws)
+ ;
+}
+
+/*
+ * Configure PLL for HSE
+ *
+ * 1. Disable the PLL by setting PLLON to 0 in RCC_CR.
+ * 2. Wait until PLLRDY is cleared. The PLL is now fully stopped.
+ * 3. Change the desired parameter.
+ * 4. Enable the PLL again by setting PLLON to 1.
+ * 5. Enable the desired PLL outputs by configuring PLLPEN, PLLQEN, PLLREN
+ * in RCC_PLLCFGR.
+ */
+static int stm32_configure_pll(enum clock_osc osc,
+ uint8_t m, uint8_t n, uint8_t r)
+{
+ uint32_t val;
+ int f;
+
+ /* 1 */
+ STM32_RCC_CR &= ~STM32_RCC_CR_PLLON;
+
+ /* 2 */
+ while (STM32_RCC_CR & STM32_RCC_CR_PLLRDY)
+ ;
+
+ /* 3 */
+ val = STM32_RCC_PLLCFGR;
+
+ val &= ~STM32_RCC_PLLCFGR_PLLSRC_MASK;
+ switch (osc) {
+ case OSC_HSI:
+ val |= STM32_RCC_PLLCFGR_PLLSRC_HSI;
+ f = STM32_HSI_CLOCK;
+ break;
+ case OSC_MSI:
+ val |= STM32_RCC_PLLCFGR_PLLSRC_MSI;
+ f = STM32_MSI_CLOCK;
+ break;
+#ifdef STM32_HSE_CLOCK
+ case OSC_HSE:
+ val |= STM32_RCC_PLLCFGR_PLLSRC_HSE;
+ f = STM32_HSE_CLOCK;
+ break;
+#endif
+ default:
+ return -1;
+ }
+
+ ASSERT(m > 0 && m < 9);
+ val &= ~STM32_RCC_PLLCFGR_PLLM_MASK;
+ val |= (m - 1) << STM32_RCC_PLLCFGR_PLLM_SHIFT;
+
+ /* Max and min values are from TRM */
+ ASSERT(n > 7 && n < 87);
+ val &= ~STM32_RCC_PLLCFGR_PLLN_MASK;
+ val |= n << STM32_RCC_PLLCFGR_PLLN_SHIFT;
+
+ val &= ~STM32_RCC_PLLCFGR_PLLR_MASK;
+ switch (r) {
+ case 2:
+ val |= 0 << STM32_RCC_PLLCFGR_PLLR_SHIFT;
+ break;
+ case 4:
+ val |= 1 << STM32_RCC_PLLCFGR_PLLR_SHIFT;
+ break;
+ case 6:
+ val |= 2 << STM32_RCC_PLLCFGR_PLLR_SHIFT;
+ break;
+ case 8:
+ val |= 3 << STM32_RCC_PLLCFGR_PLLR_SHIFT;
+ break;
+ default:
+ return -1;
+ }
+
+ STM32_RCC_PLLCFGR = val;
+
+ /* 4 */
+ clock_enable_osc(OSC_PLL);
+
+ /* 5 */
+ val = STM32_RCC_PLLCFGR;
+ val |= 1 << STM32_RCC_PLLCFGR_PLLREN_SHIFT;
+ STM32_RCC_PLLCFGR = val;
+
+ /* (f * n) shouldn't overflow based on their max values */
+ return (f * n / m / r);
+}
+
/**
- * Set which oscillator is used for the clock
+ * Set system clock oscillator
*
* @param osc Oscillator to use
+ * @param pll_osc Source oscillator for PLL. Ignored if osc is not PLL.
*/
-static void clock_set_osc(enum clock_osc osc)
+static void clock_set_osc(enum clock_osc osc, enum clock_osc pll_osc)
{
+ uint32_t val;
+
if (osc == current_osc)
return;

@@ -67,28 +227,18 @@
switch (osc) {
case OSC_HSI:
/* Ensure that HSI is ON */
- if (!(STM32_RCC_CR & STM32_RCC_CR_HSIRDY)) {
- /* Enable HSI */
- STM32_RCC_CR |= STM32_RCC_CR_HSION;
- /* Wait for HSI to be ready */
- while (!(STM32_RCC_CR & STM32_RCC_CR_HSIRDY))
- ;
- }
+ clock_enable_osc(osc);

/* Disable LPSDSR */
STM32_PWR_CR &= ~STM32_PWR_CR_LPSDSR;

/* Switch to HSI */
- STM32_RCC_CFGR = STM32_RCC_CFGR_SW_HSI;
- /* RM says to check SWS bits to make sure HSI is the sysclock */
- while ((STM32_RCC_CFGR & STM32_RCC_CFGR_SWS_MASK) !=
- STM32_RCC_CFGR_SWS_HSI)
- ;
+ clock_switch_osc(osc);

/* Disable MSI */
STM32_RCC_CR &= ~STM32_RCC_CR_MSION;

- freq = HSI_CLOCK;
+ freq = STM32_HSI_CLOCK;
break;

case OSC_MSI:
@@ -97,20 +247,10 @@
(STM32_RCC_ICSCR & ~STM32_RCC_ICSCR_MSIRANGE_MASK) |
STM32_RCC_ICSCR_MSIRANGE_1MHZ;
/* Ensure that MSI is ON */
- if (!(STM32_RCC_CR & STM32_RCC_CR_MSIRDY)) {
- /* Enable MSI */
- STM32_RCC_CR |= STM32_RCC_CR_MSION;
- /* Wait for MSI to be ready */
- while (!(STM32_RCC_CR & STM32_RCC_CR_MSIRDY))
- ;
- }
+ clock_enable_osc(osc);

/* Switch to MSI */
- STM32_RCC_CFGR = STM32_RCC_CFGR_SW_MSI;
- /* RM says to check SWS bits to make sure MSI is the sysclock */
- while ((STM32_RCC_CFGR & STM32_RCC_CFGR_SWS_MASK) !=
- STM32_RCC_CFGR_SWS_MSI)
- ;
+ clock_switch_osc(osc);

/* Disable HSI */
STM32_RCC_CR &= ~STM32_RCC_CR_HSION;
@@ -118,9 +258,55 @@
/* Enable LPSDSR */
STM32_PWR_CR |= STM32_PWR_CR_LPSDSR;

- freq = MSI_1MHZ_CLOCK;
+ freq = STM32_MSI_CLOCK;
break;

+#ifdef STM32_HSE_CLOCK
+ case OSC_HSE:
+ /* Ensure that HSE is stable */
+ clock_enable_osc(osc);
+
+ /* Switch to HSE */
+ clock_switch_osc(osc);
+
+ /* Disable other clock sources */
+ STM32_RCC_CR &= ~(STM32_RCC_CR_MSION | STM32_RCC_CR_HSION |
+ STM32_RCC_CR_PLLON);
+
+ freq = STM32_HSE_CLOCK;
+
+ break;
+#endif
+ case OSC_PLL:
+ /* Ensure that source clock is stable */
+ clock_enable_osc(pll_osc);
+
+ /*
+ * Configure PLLCFGR
+ * To run at 40 MHz, RCC_PLLCFGR is configured as follows
+ * (assuming HSE = 8 MHz crystal is connected to PH0/1):
+ * PLLM = 1 : To get 8 MHz VCO input freq from PLL input freq
+ * PLLN = 10 : To get 80 MHz VCO output freq from VCO input
+ * PLLR = 2 : To get 40 Mhz system clock from VCO output freq
+ */
+ freq = stm32_configure_pll(pll_osc, STM32_PLLM,
+ STM32_PLLN, STM32_PLLR);
+ ASSERT(freq > 0);
+
+ /* Adjust flash latency as instructed in TRM */
+ val = STM32_FLASH_ACR;
+ val &= ~STM32_FLASH_ACR_LATENCY_MASK;
+ /* Flash 4 wait state. TODO: Should depend on freq. */
+ val |= 4 << STM32_FLASH_ACR_LATENCY_SHIFT;
+ STM32_FLASH_ACR = val;
+ while (STM32_FLASH_ACR != val)
+ ;
+
+ /* Switch to PLL */
+ clock_switch_osc(osc);
+
+ /* TODO: Disable other sources */
+ break;
default:
break;
}
@@ -150,7 +336,7 @@
/* Flush UART before switching clock speed */
cflush();

- clock_set_osc(new_mask ? OSC_HSI : OSC_MSI);
+ clock_set_osc(new_mask ? OSC_HSI : OSC_MSI, OSC_INIT);
}

clock_mask = new_mask;
@@ -158,14 +344,11 @@

void clock_init(void)
{
- /*
- * The initial state :
- * SYSCLK from MSI (=2MHz), no divider on AHB, APB1, APB2
- * PLL unlocked, RTC enabled on LSE
- */
-
- /* Switch to high-speed oscillator */
- clock_set_osc(OSC_HSI);
+#ifdef STM32_HSE_CLOCK
+ clock_set_osc(OSC_PLL, OSC_HSE);
+#else
+ clock_set_osc(OSC_HSI, OSC_INIT);
+#endif
}

static void clock_chipset_startup(void)
@@ -188,9 +371,15 @@
{
if (argc >= 2) {
if (!strcasecmp(argv[1], "hsi"))
- clock_set_osc(OSC_HSI);
+ clock_set_osc(OSC_HSI, OSC_INIT);
else if (!strcasecmp(argv[1], "msi"))
- clock_set_osc(OSC_MSI);
+ clock_set_osc(OSC_MSI, OSC_INIT);
+#ifdef STM32_HSE_CLOCK
+ else if (!strcasecmp(argv[1], "hse"))
+ clock_set_osc(OSC_HSE, OSC_INIT);
+ else if (!strcasecmp(argv[1], "pll"))
+ clock_set_osc(OSC_PLL, OSC_HSE);
+#endif
else
return EC_ERROR_PARAM1;
}
@@ -199,6 +388,10 @@
return EC_SUCCESS;
}
DECLARE_CONSOLE_COMMAND(clock, command_clock,
- "hsi | msi",
+ "hsi | msi"
+#ifdef STM32_HSE_CLOCK
+ " | hse | pll"
+#endif
+ ,
"Set clock frequency",
NULL);
diff --git a/chip/stm32/config_chip.h b/chip/stm32/config_chip.h
index 80415e4..0404182 100644
--- a/chip/stm32/config_chip.h
+++ b/chip/stm32/config_chip.h
@@ -115,4 +115,9 @@
#define GPIO_PIN(port, index) GPIO_##port, (1 << index)
#define GPIO_PIN_MASK(port, mask) GPIO_##port, (mask)

+/* Prescaler values for PLL. Currently used only by STM32L476. */
+#define STM32_PLLM 0
+#define STM32_PLLN 0
+#define STM32_PLLR 0
+
#endif /* __CROS_EC_CONFIG_CHIP_H */
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index 70c846a..f74de94 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -575,6 +575,10 @@
#define STM32_RCC_CR_MSIRDY (1 << 1)
#define STM32_RCC_CR_HSION (1 << 8)
#define STM32_RCC_CR_HSIRDY (1 << 10)
+#define STM32_RCC_CR_HSEON (1 << 16)
+#define STM32_RCC_CR_HSERDY (1 << 17)
+#define STM32_RCC_CR_PLLON (1 << 24)
+#define STM32_RCC_CR_PLLRDY (1 << 25)

#define STM32_RCC_ICSCR REG32(STM32_RCC_BASE + 0x04)
#define STM32_RCC_ICSCR_MSIRANGE(n) ((n) << 13)
@@ -593,6 +597,22 @@
#define STM32_RCC_CFGR_SWS_HSE (2 << 2)
#define STM32_RCC_CFGR_SWS_PLL (3 << 2)
#define STM32_RCC_CFGR_SWS_MASK (3 << 2)
+
+#define STM32_RCC_PLLCFGR REG32(STM32_RCC_BASE + 0x0C)
+#define STM32_RCC_PLLCFGR_PLLSRC_SHIFT (0)
+#define STM32_RCC_PLLCFGR_PLLSRC_NONE (0 << STM32_RCC_PLLCFGR_PLLSRC_SHIFT)
+#define STM32_RCC_PLLCFGR_PLLSRC_MSI (1 << STM32_RCC_PLLCFGR_PLLSRC_SHIFT)
+#define STM32_RCC_PLLCFGR_PLLSRC_HSI (2 << STM32_RCC_PLLCFGR_PLLSRC_SHIFT)
+#define STM32_RCC_PLLCFGR_PLLSRC_HSE (3 << STM32_RCC_PLLCFGR_PLLSRC_SHIFT)
+#define STM32_RCC_PLLCFGR_PLLSRC_MASK (3 << STM32_RCC_PLLCFGR_PLLSRC_SHIFT)
+#define STM32_RCC_PLLCFGR_PLLM_SHIFT (4)
+#define STM32_RCC_PLLCFGR_PLLM_MASK (0x7 << STM32_RCC_PLLCFGR_PLLM_SHIFT)
+#define STM32_RCC_PLLCFGR_PLLN_SHIFT (8)
+#define STM32_RCC_PLLCFGR_PLLN_MASK (0x7f << STM32_RCC_PLLCFGR_PLLN_SHIFT)
+#define STM32_RCC_PLLCFGR_PLLREN_SHIFT (24)
+#define STM32_RCC_PLLCFGR_PLLREN_MASK (1 << STM32_RCC_PLLCFGR_PLLREN_SHIFT)
+#define STM32_RCC_PLLCFGR_PLLR_SHIFT (25)
+#define STM32_RCC_PLLCFGR_PLLR_MASK (3 << STM32_RCC_PLLCFGR_PLLR_SHIFT)

#define STM32_RCC_AHB1ENR REG32(STM32_RCC_BASE + 0x48)
#define STM32_RCC_AHB1ENR_DMA1EN (1 << 0)
@@ -869,6 +889,8 @@
#define STM32_FLASH_REGS_BASE 0x40022000

#define STM32_FLASH_ACR REG32(STM32_FLASH_REGS_BASE + 0x00)
+#define STM32_FLASH_ACR_LATENCY_SHIFT (0)
+#define STM32_FLASH_ACR_LATENCY_MASK (7 << STM32_FLASH_ACR_LATENCY_SHIFT)
#define STM32_FLASH_ACR_LATENCY (1 << 0)
#define STM32_FLASH_ACR_PRFTEN (1 << 4)
#define STM32_FLASH_KEYR REG32(STM32_FLASH_REGS_BASE + 0x04)

--
To view, visit https://chromium-review.googlesource.com/341275
To unsubscribe, visit https://chromium-review.googlesource.com/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
Gerrit-PatchSet: 1
Gerrit-Project: chromiumos/platform/ec
Gerrit-Branch: master
Gerrit-Owner: Daisuke Nojiri <dno...@chromium.org>

Daisuke Nojiri (Gerrit)

unread,
Apr 28, 2016, 6:38:52 PM4/28/16
to chromium-...@chromium.org
Daisuke Nojiri has uploaded a new patch set (#2).

Change subject: STM32: Add HSE and PLL to clock source selection
......................................................................

STM32: Add HSE and PLL to clock source selection

This patch adds HSE and PLL as a system clock oscillator for STM32L4.
This allows us to drive the chip at a higher frequency (currently up to
40 MHz).

BUG=none
BRANCH=tot
TEST=make buildall. Verified console on STM32L476G-Eval using HSE, PLL-HSE,
PLL-HSI, PLL-MSI as an oscillator.

Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
---
M board/stm32l476g-eval/board.h
M chip/stm32/clock-stm32l4.c
M chip/stm32/config_chip.h
M chip/stm32/registers.h
4 files changed, 282 insertions(+), 51 deletions(-)


Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
Gerrit-PatchSet: 2

Daisuke Nojiri (Gerrit)

unread,
Apr 28, 2016, 6:55:50 PM4/28/16
to chromium-...@chromium.org
Daisuke Nojiri has uploaded a new patch set (#3).

Change subject: STM32: Add HSE and PLL to clock source selection
......................................................................

STM32: Add HSE and PLL to clock source selection

This patch adds HSE and PLL as a system clock oscillator for STM32L4.
This allows us to drive the chip at a higher frequency.

BUG=none
BRANCH=tot
TEST=make buildall. Verified console on STM32L476G-Eval using HSE, PLL-HSE,
PLL-HSI, PLL-MSI as an oscillator. Verified console runs soundly with
different frequencies from 20 Mhz to 80 Mhz. Verified frequencies using
oscilloscope on MCO (Microcontroller Clock Output) port up to 50 MHz.

Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
---
M board/stm32l476g-eval/board.h
M chip/stm32/clock-stm32l4.c
M chip/stm32/config_chip.h
M chip/stm32/registers.h
4 files changed, 275 insertions(+), 51 deletions(-)
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
Gerrit-PatchSet: 3

Daisuke Nojiri (Gerrit)

unread,
Apr 28, 2016, 6:58:23 PM4/28/16
to chromium-...@chromium.org
Daisuke Nojiri has uploaded a new patch set (#4).

Change subject: STM32: Add HSE and PLL to clock source selection
......................................................................

STM32: Add HSE and PLL to clock source selection

This patch adds HSE and PLL as a system clock oscillator for STM32L4.
This allows us to drive the chip at a higher frequency (up to 80 MHz),
which is necessary to big-bang GPIO ports accurately.

BUG=none
BRANCH=tot
TEST=make buildall. Verified console works on STM32L476G-Eval using HSE,
PLL-HSE, PLL-HSI, PLL-MSI as an oscillator. Verified console runs soundly
with different frequencies from 20 Mhz to 80 Mhz. Verified frequencies
using oscilloscope on MCO (Microcontroller Clock Output) port up to 50 MHz.

Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
---
M board/stm32l476g-eval/board.h
M chip/stm32/clock-stm32l4.c
M chip/stm32/config_chip.h
M chip/stm32/registers.h
4 files changed, 275 insertions(+), 51 deletions(-)
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
Gerrit-PatchSet: 4

Randall Spangler (Gerrit)

unread,
Apr 28, 2016, 7:12:17 PM4/28/16
to Daisuke Nojiri, Vincent Palatin, Gwendal Grignou
Randall Spangler has posted comments on this change.

Change subject: STM32: Add HSE and PLL to clock source selection
......................................................................


Patch Set 4: Code-Review+2
Gerrit-MessageType: comment
Gerrit-Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
Gerrit-PatchSet: 4
Gerrit-Project: chromiumos/platform/ec
Gerrit-Branch: master
Gerrit-Owner: Daisuke Nojiri <dno...@chromium.org>
Gerrit-Reviewer: Gwendal Grignou <gwe...@chromium.org>
Gerrit-Reviewer: Randall Spangler <rspa...@chromium.org>
Gerrit-Reviewer: Vincent Palatin <vpal...@chromium.org>
Gerrit-HasComments: No

Daisuke Nojiri (Gerrit)

unread,
Apr 28, 2016, 8:02:48 PM4/28/16
to Vincent Palatin, Gwendal Grignou, ChromeOS bot, Randall Spangler
Daisuke Nojiri has posted comments on this change.

Change subject: STM32: Add HSE and PLL to clock source selection
......................................................................


Patch Set 4: Verified+1 Commit-Queue+1
Gerrit-MessageType: comment
Gerrit-Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
Gerrit-PatchSet: 4
Gerrit-Project: chromiumos/platform/ec
Gerrit-Branch: master
Gerrit-Owner: Daisuke Nojiri <dno...@chromium.org>
Gerrit-Reviewer: ChromeOS bot
<3su6n15k...@developer.gserviceaccount.com>
Gerrit-Reviewer: Daisuke Nojiri <dno...@chromium.org>

ChromeOS Commit Bot (Gerrit)

unread,
Apr 29, 2016, 10:36:36 AM4/29/16
to Daisuke Nojiri, Randall Spangler, Gwendal Grignou, ChromeOS bot, Vincent Palatin
Hello Randall Spangler, Daisuke Nojiri,

I'd like you to reexamine a change. Please visit

https://chromium-review.googlesource.com/341275

to look at the new patch set (#5).

Change subject: STM32: Add HSE and PLL to clock source selection
......................................................................

STM32: Add HSE and PLL to clock source selection

This patch adds HSE and PLL as a system clock oscillator for STM32L4.
This allows us to drive the chip at a higher frequency (up to 80 MHz),
which is necessary to big-bang GPIO ports accurately.

BUG=none
BRANCH=tot
TEST=make buildall. Verified console works on STM32L476G-Eval using HSE,
PLL-HSE, PLL-HSI, PLL-MSI as an oscillator. Verified console runs soundly
with different frequencies from 20 Mhz to 80 Mhz. Verified frequencies
using oscilloscope on MCO (Microcontroller Clock Output) port up to 50 MHz.

Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
Reviewed-on: https://chromium-review.googlesource.com/341275
Commit-Ready: Daisuke Nojiri <dno...@chromium.org>
Tested-by: Daisuke Nojiri <dno...@chromium.org>
Reviewed-by: Randall Spangler <rspa...@chromium.org>
---
M board/stm32l476g-eval/board.h
M chip/stm32/clock-stm32l4.c
M chip/stm32/config_chip.h
M chip/stm32/registers.h
4 files changed, 275 insertions(+), 51 deletions(-)
Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
Gerrit-PatchSet: 5
Gerrit-Project: chromiumos/platform/ec
Gerrit-Branch: master
Gerrit-Owner: Daisuke Nojiri <dno...@chromium.org>
Gerrit-Reviewer: ChromeOS Commit Bot <chromeos-...@chromium.org>

ChromeOS Commit Bot (Gerrit)

unread,
Apr 29, 2016, 10:36:38 AM4/29/16
to Daisuke Nojiri, Vincent Palatin, Gwendal Grignou, ChromeOS bot, Randall Spangler
ChromeOS Commit Bot has submitted this change and it was merged.

Change subject: STM32: Add HSE and PLL to clock source selection
......................................................................


STM32: Add HSE and PLL to clock source selection

This patch adds HSE and PLL as a system clock oscillator for STM32L4.
This allows us to drive the chip at a higher frequency (up to 80 MHz),
which is necessary to big-bang GPIO ports accurately.

BUG=none
BRANCH=tot
TEST=make buildall. Verified console works on STM32L476G-Eval using HSE,
PLL-HSE, PLL-HSI, PLL-MSI as an oscillator. Verified console runs soundly
with different frequencies from 20 Mhz to 80 Mhz. Verified frequencies
using oscilloscope on MCO (Microcontroller Clock Output) port up to 50 MHz.

Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
Reviewed-on: https://chromium-review.googlesource.com/341275
Commit-Ready: Daisuke Nojiri <dno...@chromium.org>
Tested-by: Daisuke Nojiri <dno...@chromium.org>
Reviewed-by: Randall Spangler <rspa...@chromium.org>
---
M board/stm32l476g-eval/board.h
M chip/stm32/clock-stm32l4.c
M chip/stm32/config_chip.h
M chip/stm32/registers.h
4 files changed, 275 insertions(+), 51 deletions(-)



diff --git a/board/stm32l476g-eval/board.h b/board/stm32l476g-eval/board.h
index d6f9eb7..7ce7875 100644
--- a/board/stm32l476g-eval/board.h
+++ b/board/stm32l476g-eval/board.h
@@ -40,7 +40,18 @@
#undef CONFIG_FLASH

/* Timer selection */
-#define TIM_CLOCK32 5
+#define TIM_CLOCK32 5
+
+/* External clock speeds (8 MHz) */
+#define STM32_HSE_CLOCK 8000000
+
+/* PLL configuration. Freq = STM32_HSE_CLOCK * n/m/r */
+#undef STM32_PLLM
+#define STM32_PLLM 1
+#undef STM32_PLLN
+#define STM32_PLLN 10
+#undef STM32_PLLR
+#define STM32_PLLR 2

#include "gpio_signal.h"

diff --git a/chip/stm32/clock-stm32l4.c b/chip/stm32/clock-stm32l4.c
index 7cbd098..1e825e5 100644
@@ -118,9 +258,48 @@
+ /* Configure PLLCFGR */
+ freq = stm32_configure_pll(pll_osc, STM32_PLLM,
+ STM32_PLLN, STM32_PLLR);
+ ASSERT(freq > 0);
+
+ /* Adjust flash latency as instructed in TRM */
+ val = STM32_FLASH_ACR;
+ val &= ~STM32_FLASH_ACR_LATENCY_MASK;
+ /* Flash 4 wait state. TODO: Should depend on freq. */
+ val |= 4 << STM32_FLASH_ACR_LATENCY_SHIFT;
+ STM32_FLASH_ACR = val;
+ while (STM32_FLASH_ACR != val)
+ ;
+
+ /* Switch to PLL */
+ clock_switch_osc(osc);
+
+ /* TODO: Disable other sources */
+ break;
default:
break;
}
@@ -150,7 +329,7 @@
/* Flush UART before switching clock speed */
cflush();

- clock_set_osc(new_mask ? OSC_HSI : OSC_MSI);
+ clock_set_osc(new_mask ? OSC_HSI : OSC_MSI, OSC_INIT);
}

clock_mask = new_mask;
@@ -158,14 +337,11 @@

void clock_init(void)
{
- /*
- * The initial state :
- * SYSCLK from MSI (=2MHz), no divider on AHB, APB1, APB2
- * PLL unlocked, RTC enabled on LSE
- */
-
- /* Switch to high-speed oscillator */
- clock_set_osc(OSC_HSI);
+#ifdef STM32_HSE_CLOCK
+ clock_set_osc(OSC_PLL, OSC_HSE);
+#else
+ clock_set_osc(OSC_HSI, OSC_INIT);
+#endif
}

static void clock_chipset_startup(void)
@@ -188,9 +364,15 @@
{
if (argc >= 2) {
if (!strcasecmp(argv[1], "hsi"))
- clock_set_osc(OSC_HSI);
+ clock_set_osc(OSC_HSI, OSC_INIT);
else if (!strcasecmp(argv[1], "msi"))
- clock_set_osc(OSC_MSI);
+ clock_set_osc(OSC_MSI, OSC_INIT);
+#ifdef STM32_HSE_CLOCK
+ else if (!strcasecmp(argv[1], "hse"))
+ clock_set_osc(OSC_HSE, OSC_INIT);
+ else if (!strcasecmp(argv[1], "pll"))
+ clock_set_osc(OSC_PLL, OSC_HSE);
+#endif
else
return EC_ERROR_PARAM1;
}
@@ -199,6 +381,10 @@
Gerrit-MessageType: merged
Gerrit-Change-Id: I493cdb6c323eb4e6a1560f6d030935c1950b1a2a
Gerrit-PatchSet: 5
Gerrit-Project: chromiumos/platform/ec
Gerrit-Branch: master
Gerrit-Owner: Daisuke Nojiri <dno...@chromium.org>
Reply all
Reply to author
Forward
0 new messages