summaryrefslogtreecommitdiffstats
path: root/src/soc/qualcomm/common
diff options
context:
space:
mode:
authorShelley Chen <shchen@google.com>2022-03-31 18:07:59 -0700
committerShelley Chen <shchen@google.com>2022-04-14 14:05:04 +0000
commit420ba8b7081757cda307891e7e80f8f2d6b3f762 (patch)
tree968544174ad7ae7e5c7ec83961367f19db494a73 /src/soc/qualcomm/common
parentc3007f38770d192bf32b75331371568447b3623e (diff)
downloadcoreboot-420ba8b7081757cda307891e7e80f8f2d6b3f762.tar.gz
coreboot-420ba8b7081757cda307891e7e80f8f2d6b3f762.tar.bz2
coreboot-420ba8b7081757cda307891e7e80f8f2d6b3f762.zip
soc/qualcomm/common: Make clock_configure() check for exact matches
Previously, clock_configure() will configure the clocks to round up to the next highest frequency bin. This seems non-intuitive. Changing the logic to find an exact frequency match and will halt booting if no match is found. Recently fixed a bug in CB:63311, where the clock was being set incorrectly for emmc and was able to find it because of this stricter check. BUG=b:198627043 BRANCH=None TEST=build herobrine image and try to set SPI frequency to number not supported. Ensure device doesn't boot. Change-Id: I9cfad7236241f4d03ff1a56683654649658b68fc Signed-off-by: Shelley Chen <shchen@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/63289 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Georgi <patrick@coreboot.org>
Diffstat (limited to 'src/soc/qualcomm/common')
-rw-r--r--src/soc/qualcomm/common/clock.c11
-rw-r--r--src/soc/qualcomm/common/include/soc/clock_common.h11
2 files changed, 18 insertions, 4 deletions
diff --git a/src/soc/qualcomm/common/clock.c b/src/soc/qualcomm/common/clock.c
index e06a954f3ca0..09484b76f41e 100644
--- a/src/soc/qualcomm/common/clock.c
+++ b/src/soc/qualcomm/common/clock.c
@@ -90,15 +90,20 @@ static void clock_configure_mnd(struct clock_rcg *clk, uint32_t m, uint32_t n,
/* Clock Root clock Generator Operations */
enum cb_err clock_configure(struct clock_rcg *clk,
- struct clock_freq_config *clk_cfg, uint32_t hz,
- uint32_t num_perfs)
+ struct clock_freq_config *clk_cfg, uint32_t hz,
+ uint32_t num_perfs)
{
uint32_t reg_val, idx;
for (idx = 0; idx < num_perfs; idx++)
- if (hz <= clk_cfg[idx].hz)
+ if (hz == clk_cfg[idx].hz)
break;
+ /* Verify we matched an entry. If not, throw error. */
+ if (idx >= num_perfs)
+ die("Failed to find a matching clock frequency (%d hz) for %p!\n",
+ hz, clk);
+
reg_val = (clk_cfg[idx].src << CLK_CTL_CFG_SRC_SEL_SHFT) |
(clk_cfg[idx].div << CLK_CTL_CFG_SRC_DIV_SHFT);
diff --git a/src/soc/qualcomm/common/include/soc/clock_common.h b/src/soc/qualcomm/common/include/soc/clock_common.h
index 091182714916..b08d39bdd8ac 100644
--- a/src/soc/qualcomm/common/include/soc/clock_common.h
+++ b/src/soc/qualcomm/common/include/soc/clock_common.h
@@ -145,8 +145,17 @@ enum cb_err enable_and_poll_gdsc_status(void *gdscr_addr);
void clock_reset_bcr(void *bcr_addr, bool assert);
+/*
+ * clock_configure(): Configure the clock at the given clock speed (hz). If hz
+ * does not match any entries in the clk_cfg array, will throw and error and die().
+ *
+ * @param clk struct clock_rcg pointer (root clock generator)
+ * @param clk_cfg Array with possible clock configurations
+ * @param hz frequency of clock to set
+ * @param num_perfs size of clock array
+ */
enum cb_err clock_configure(struct clock_rcg *clk, struct clock_freq_config *clk_cfg,
- uint32_t hz, uint32_t num_perfs);
+ uint32_t hz, uint32_t num_perfs);
void clock_configure_dfsr_table(int qup, struct clock_freq_config *clk_cfg,
uint32_t num_perfs);