summaryrefslogtreecommitdiff
path: root/chip/stm32/clock-stm32l.c
diff options
context:
space:
mode:
authorYen Lin <yelin@nvidia.com>2014-12-08 12:22:09 -0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-12-17 21:08:20 +0000
commitec12acc81f47e9b88517cd4a955414f7a1ee1cf6 (patch)
tree89f0ae233acc097c53c92e8fbbb7799f9d33d9c3 /chip/stm32/clock-stm32l.c
parenta7bae3588cb976405b90677a324de06c71fa3f48 (diff)
downloadchrome-ec-ec12acc81f47e9b88517cd4a955414f7a1ee1cf6.tar.gz
clock-stm32l: properly setting HSI/MSI clock based on the RM
According the STM32L RM, when writing to RCC_CFGR to change HSI or MSI clock source, SWS bits of RCC_CFGR register have to be checked if the new clock source is taken into account. Also, when writing ACC64 bit and LATENCY bit to FLASH_ACR register, those bits have to be checked too. Also changed in this CL is to disable MSI if HSI is enabled, and disable HSI if MSI is enabled. BUG=chrome-os-partner:32936 BRANCH=none TEST=passed suspend_stress_test on big, blaze and nyan Change-Id: I3ec660d149ecdec3ca3097239612bf2c542d0548 Signed-off-by: Yen Lin <yelin@nvidia.com> Reviewed-on: https://chromium-review.googlesource.com/234490 Reviewed-by: Kary Jin <karyj@nvidia.com> Tested-by: Kary Jin <karyj@nvidia.com> Reviewed-by: Andrew Bresticker <abrestic@chromium.org> (cherry picked from commit 400d9dca8c41f74cf0c2587e881707b80bb17d3d) Reviewed-on: https://chromium-review.googlesource.com/236050
Diffstat (limited to 'chip/stm32/clock-stm32l.c')
-rw-r--r--chip/stm32/clock-stm32l.c52
1 files changed, 45 insertions, 7 deletions
diff --git a/chip/stm32/clock-stm32l.c b/chip/stm32/clock-stm32l.c
index 502a8187c3..e0c7ebc747 100644
--- a/chip/stm32/clock-stm32l.c
+++ b/chip/stm32/clock-stm32l.c
@@ -82,22 +82,38 @@ static void clock_set_osc(enum clock_osc osc)
/*
* Set the recommended flash settings for 16MHz clock.
*
- * The 3 bits must be programmed strictly sequentially, but it
- * is faster not to read-back the value of the ACR register in
- * the middle of the sequence so use a temporary variable.
+ * The 3 bits must be programmed strictly sequentially.
+ * Also, follow the RM to check 64-bit access and latency bit
+ * after writing those bits to the FLASH_ACR register.
*/
tmp_acr = STM32_FLASH_ACR;
/* Enable 64-bit access */
tmp_acr |= STM32_FLASH_ACR_ACC64;
STM32_FLASH_ACR = tmp_acr;
+ /* Check ACC64 bit == 1 */
+ while (!(STM32_FLASH_ACR & STM32_FLASH_ACR_ACC64))
+ ;
+
/* Enable Prefetch Buffer */
tmp_acr |= STM32_FLASH_ACR_PRFTEN;
STM32_FLASH_ACR = tmp_acr;
+
/* Flash 1 wait state */
tmp_acr |= STM32_FLASH_ACR_LATENCY;
STM32_FLASH_ACR = tmp_acr;
+ /* Check LATENCY bit == 1 */
+ while (!(STM32_FLASH_ACR & STM32_FLASH_ACR_LATENCY))
+ ;
+
/* 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)
+ ;
+
+ /* Disable MSI */
+ STM32_RCC_CR &= ~STM32_RCC_CR_MSION;
freq = HSI_CLOCK;
break;
@@ -107,28 +123,50 @@ static void clock_set_osc(enum clock_osc osc)
STM32_RCC_ICSCR =
(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))
+ ;
+ }
+
+ /* 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)
+ ;
/*
* Set the recommended flash settings for <= 2MHz clock.
*
- * The 3 bits must be programmed strictly sequentially, but it
- * is faster not to read-back the value of the ACR register in
- * the middle of the sequence so use a temporary variable.
+ * The 3 bits must be programmed strictly sequentially.
+ * Also, follow the RM to check 64-bit access and latency bit
+ * after writing those bits to the FLASH_ACR register.
*/
tmp_acr = STM32_FLASH_ACR;
/* Flash 0 wait state */
tmp_acr &= ~STM32_FLASH_ACR_LATENCY;
STM32_FLASH_ACR = tmp_acr;
+ /* Check LATENCY bit == 0 */
+ while (STM32_FLASH_ACR & STM32_FLASH_ACR_LATENCY)
+ ;
+
/* Disable prefetch Buffer */
tmp_acr &= ~STM32_FLASH_ACR_PRFTEN;
STM32_FLASH_ACR = tmp_acr;
+
/* Disable 64-bit access */
tmp_acr &= ~STM32_FLASH_ACR_ACC64;
STM32_FLASH_ACR = tmp_acr;
+ /* Check ACC64 bit == 0 */
+ while (STM32_FLASH_ACR & STM32_FLASH_ACR_ACC64)
+ ;
/* Disable HSI */
- STM32_RCC_CR &= STM32_RCC_CR_HSION;
+ STM32_RCC_CR &= ~STM32_RCC_CR_HSION;
/* Enable LPSDSR */
STM32_PWR_CR |= STM32_PWR_CR_LPSDSR;