From 706c2cebc2674febd84fbfe94473d13a889bec2c Mon Sep 17 00:00:00 2001 From: Himanshu Sharma Date: Mon, 1 Apr 2024 14:18:34 +0530 Subject: [PATCH] module/sc_pll: Fix the lock timeout and error handling of the functions FWK_E_TIMEOUT is returned if the PLL lock is not achieved till the timeout period. This error is not propagated up to the functions iterating on the POSTDIV min-max values. With timeout returned, the set_rate function should be stopped for any further calculations. Instead, it continues with the next iterations on POSTDIV1 and POSTDIV2 with the existing implementation. Adding the check for FWK_E_TIMEOUT alongside FWK_SUCCESS. The PLL lock timeout value has been erroneously changed to 0x100 while making SC_PLL a generic SCP module. Reverting it back to the original value 0x100000 used previously in the product-based implementation. Also, add unit-tests for pll_write() function and test for its success and timeout. Signed-off-by: Himanshu Sharma Change-Id: I8db833d4ee3edf6ade7e297178b1292cbdc1db75 --- module/sc_pll/include/mod_sc_pll.h | 2 +- module/sc_pll/src/mod_sc_pll.c | 4 +-- module/sc_pll/test/config_sc_pll.h | 1 + module/sc_pll/test/mod_sc_pll_unit_test.c | 36 +++++++++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/module/sc_pll/include/mod_sc_pll.h b/module/sc_pll/include/mod_sc_pll.h index 83541d465..3de755ef2 100644 --- a/module/sc_pll/include/mod_sc_pll.h +++ b/module/sc_pll/include/mod_sc_pll.h @@ -31,7 +31,7 @@ */ /*! Timeout value to wait for a PLL to lock. */ -#define MOD_SC_PLL_LOCK_TIMEOUT UINT32_C(0x100) +#define MOD_SC_PLL_LOCK_TIMEOUT UINT32_C(0x100000) /*! Indexes of APIs that the module offers for binding. */ enum mod_sc_pll_api_types { diff --git a/module/sc_pll/src/mod_sc_pll.c b/module/sc_pll/src/mod_sc_pll.c index 03618951e..8e4fb6e4a 100644 --- a/module/sc_pll/src/mod_sc_pll.c +++ b/module/sc_pll/src/mod_sc_pll.c @@ -185,7 +185,7 @@ static int pll_calc_post_divider_and_feedback_params( postdiv1 <= config->dev_param->postdiv1_max; postdiv1++) { status = pll_calc_fbdiv(ctx, rate, postdiv1, postdiv2); - if (status == FWK_SUCCESS) { + if ((status == FWK_SUCCESS) || (status == FWK_E_TIMEOUT)) { return status; } } @@ -207,7 +207,7 @@ static int pll_fractional_calc(struct sc_pll_dev_ctx *ctx, uint64_t rate) postdiv2 <= config->dev_param->postdiv2_max; postdiv2++) { status = pll_calc_post_divider_and_feedback_params(ctx, rate, postdiv2); - if (status == FWK_SUCCESS) { + if ((status == FWK_SUCCESS) || (status == FWK_E_TIMEOUT)) { return status; } } diff --git a/module/sc_pll/test/config_sc_pll.h b/module/sc_pll/test/config_sc_pll.h index 077b77fde..3d7a86aa5 100644 --- a/module/sc_pll/test/config_sc_pll.h +++ b/module/sc_pll/test/config_sc_pll.h @@ -21,6 +21,7 @@ volatile uint32_t control_reg0 = 0x40000000; volatile uint32_t control_reg1 = 0x80000000; +volatile uint32_t control_reg1_timeout = 0x70000000; static struct mod_sc_pll_dev_param dev_param = { .postdiv1_min = 1, diff --git a/module/sc_pll/test/mod_sc_pll_unit_test.c b/module/sc_pll/test/mod_sc_pll_unit_test.c index a1e9b97cb..0efec6bdf 100644 --- a/module/sc_pll/test/mod_sc_pll_unit_test.c +++ b/module/sc_pll/test/mod_sc_pll_unit_test.c @@ -299,6 +299,40 @@ void test_pll_calc_fbdiv_large_config_ref_rate(void) TEST_ASSERT_EQUAL(status, FWK_E_SUPPORT); } +/*! + * \brief pll unit test: test_pll_write_success + * + * \details Handle case in test_pll_write_success() for a successful pll lock. + */ +void test_pll_write_success(void) +{ + int status; + status = pll_write(&dev_ctx_table[0], 1, 1, 1, 52, SC_PLL_RATE_CPU_PLL0); + TEST_ASSERT_EQUAL(status, FWK_SUCCESS); +} + +/*! + * \brief pll unit test: test_pll_write_fail + * + * \details Handle case in test_pll_write_fail() for the pll lock getting + * timed-out. + */ +void test_pll_write_fail(void) +{ + int status; + struct sc_pll_dev_ctx ctx; + const struct mod_sc_pll_dev_config config = { + .control_reg0 = &control_reg0, + .control_reg1 = &control_reg1_timeout, + .initial_rate = SC_PLL_RATE_CPU_PLL0, + .ref_rate = CLOCK_RATE_REFCLK, + .dev_param = &dev_param, + }; + ctx.config = &config; + status = pll_write(&ctx, 1, 1, 1, 52, SC_PLL_RATE_CPU_PLL0); + TEST_ASSERT_EQUAL(status, FWK_E_TIMEOUT); +} + int pll_test_main(void) { UNITY_BEGIN(); @@ -319,6 +353,8 @@ int pll_test_main(void) RUN_TEST(test_pll_calc_fbdiv_success); RUN_TEST(test_pll_calc_fbdiv_small_config_ref_rate); RUN_TEST(test_pll_calc_fbdiv_large_config_ref_rate); + RUN_TEST(test_pll_write_success); + RUN_TEST(test_pll_write_fail); return UNITY_END(); }