| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830 |
- /* Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
- *
- * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
- *the the People's Republic of China and other countries.
- * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
- *
- * DISCLAIMER
- * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
- * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
- * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
- * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
- * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
- * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
- * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
- * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
- * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
- * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
- * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "sunxi_hal_common.h"
- #include "clk.h"
- #include "clk_periph.h"
- #include "clk_factors.h"
- #include <stdio.h>
- #include <string.h>
- extern clk_core_pt sunxi_clk_fixed_src_arry[];
- extern clk_fixed_factor_pt sunxi_clk_fixed_factor_arry[];
- extern clk_factor_pt sunxi_clk_factor_arry[];
- extern clk_periph_pt sunxi_clk_periph_arry[];
- extern clk_base_pt sunxi_periph_clk_init_arry[];
- extern hal_clk_status_t (*sunxi_clk_factor_init[])(void);
- static hal_clk_status_t sunxi_clk_set_parent(hal_clk_id_t clk, hal_clk_id_t parent_clk);
- static hal_clk_status_t sunxi_clk_get_parent(hal_clk_id_t clk, hal_clk_id_t *parent_clk);
- static hal_clk_status_t sunxi_clk_disable(hal_clk_id_t clk);
- static hal_clk_status_t sunxi_clk_enabled(hal_clk_id_t clk);
- static hal_clk_status_t sunxi_clk_is_enabled(hal_clk_id_t clk);
- static hal_clk_status_t sunxi_clk_round_rate(hal_clk_id_t clk, u32 rate, u32 *prate);
- static hal_clk_status_t sunxi_clk_recalc_rate(hal_clk_id_t clk, u32 *rate);
- static hal_clk_status_t sunxi_clk_get_rate(hal_clk_id_t clk, u32 *rate);
- static hal_clk_status_t sunxi_clk_set_rate(hal_clk_id_t clk, u32 rate);
- static inline uint64_t read_cntpct(void)
- {
- u64 val;
- asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r"(val));
- return val;
- }
- static inline uint32_t read_cntfrq(void)
- {
- u32 frq;
- asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(frq));
- return frq;
- }
- void clk_udelay(u32 us)
- {
- u64 start, target;
- start = read_cntpct();
- target = read_cntfrq() / 1000000ULL * us;
- while (read_cntpct() - start <= target) ;
- }
- clk_core_pt clk_get_core(hal_clk_id_t clk)
- {
- clk_core_pt pclk = NULL;
- u32 i;
- switch (HAL_CLK_GET_TYPE(clk))
- {
- /* */
- case HAL_CLK_PERIPH:
- for (i = 0; sunxi_clk_periph_arry[i] != NULL; i++)
- {
- pclk = (clk_core_pt)sunxi_clk_periph_arry[i];
- if (pclk->clk == clk)
- {
- break;
- }
- }
- break;
- /* */
- case HAL_CLK_FACTOR:
- for (i = 0; sunxi_clk_factor_arry[i] != NULL; i++)
- {
- pclk = (clk_core_pt)sunxi_clk_factor_arry[i];
- if (pclk->clk == clk)
- {
- break;
- }
- }
- break;
- /* */
- case HAL_CLK_FIXED_SRC:
- for (i = 0; sunxi_clk_fixed_src_arry[i] != NULL; i++)
- {
- pclk = (clk_core_pt)sunxi_clk_fixed_src_arry[i];
- if (pclk->clk == clk)
- {
- break;
- }
- }
- break;
- /* */
- case HAL_CLK_FIXED_FACTOR:
- for (i = 0; sunxi_clk_fixed_factor_arry[i] != NULL; i++)
- {
- pclk = (clk_core_pt)sunxi_clk_fixed_factor_arry[i];
- if (pclk->clk == clk)
- {
- break;
- }
- }
- break;
- /* */
- default:
- break;
- }
- return pclk;
- }
- hal_clk_status_t sunxi_clk_set_parent(hal_clk_id_t clk, hal_clk_id_t parent_clk)
- {
- u32 i = 0, cnt = 0, parent_rate = 0;
- u8 index = 0;
- hal_clk_status_t ret = HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND;
- clk_core_pt pclk = NULL;
- clk_periph_pt periph_clk = NULL;
- CCMU_TRACE();
- pclk = clk_get_core(clk);
- if (pclk == NULL)
- {
- return ret;
- }
- switch (pclk->clk_type)
- {
- case HAL_CLK_PERIPH:
- periph_clk = (clk_periph_pt)pclk;
- if (periph_clk->clk_core.current_parent == parent_clk)
- {
- return HAL_CLK_STATUS_OK;
- }
- for (i = 0; i < periph_clk->parent_arry_size; i++)
- {
- if (periph_clk->parent_arry[i] != parent_clk)
- {
- continue;
- }
- ret = sunxi_clk_periph_set_parent(periph_clk, i);
- break;
- }
- if (ret == HAL_CLK_STATUS_OK)
- {
- periph_clk->clk_core.current_parent = parent_clk;
- periph_clk->clk_core.current_parent_type = HAL_CLK_GET_TYPE(parent_clk);
- ret = sunxi_clk_recalc_rate(parent_clk, &parent_rate);
- if (ret == HAL_CLK_STATUS_OK)
- {
- periph_clk->clk_core.parent_rate = parent_rate;
- }
- else
- {
- periph_clk->clk_core.parent_rate = 0;
- }
- }
- break;
- /* */
- case HAL_CLK_FIXED_SRC:
- case HAL_CLK_FIXED_FACTOR:
- case HAL_CLK_FACTOR:
- ret = HAL_CLK_STATUS_OK;
- break;
- /* */
- default:
- ret = HAL_CLK_STATUS_ERROR_CLK_SET_RATE_REFUSED;
- break;
- }
- CCMU_TRACE();
- return ret;
- }
- hal_clk_status_t sunxi_clk_get_parent(hal_clk_id_t clk, hal_clk_id_t *parent_clk)
- {
- u32 i;
- u8 index = 0;
- hal_clk_status_t ret = HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND;
- hal_clk_id_t parent;
- clk_core_pt pclk = NULL;
- clk_periph_pt periph_clk = NULL;
- CCMU_TRACE();
- pclk = clk_get_core(clk);
- if (pclk == NULL)
- {
- return ret;
- }
- switch (pclk->clk_type)
- {
- case HAL_CLK_PERIPH:
- periph_clk = (clk_periph_pt)pclk;
- ret = sunxi_clk_periph_get_parent(periph_clk, &index);
- if (ret != HAL_CLK_STATUS_OK)
- {
- break;
- }
- if (index >= periph_clk->parent_arry_size)
- {
- ret = HAL_CLK_STATUS_ERROT_CLK_UNDEFINED;
- break;
- }
- parent = periph_clk->parent_arry[index];
- if (periph_clk->clk_core.current_parent == parent)
- {
- break;
- }
- periph_clk->clk_core.current_parent = parent;
- periph_clk->clk_core.current_parent_type = HAL_CLK_GET_TYPE(parent);
- (*parent_clk) = parent;
- break;
- /* */
- case HAL_CLK_FIXED_SRC:
- case HAL_CLK_FIXED_FACTOR:
- case HAL_CLK_FACTOR:
- pclk = clk_get_core(clk);
- (*parent_clk) = pclk->current_parent;
- ret = HAL_CLK_STATUS_OK;
- break;
- /* */
- default:
- ret = HAL_CLK_STATUS_ERROT_CLK_UNDEFINED;
- break;
- }
- CCMU_TRACE();
- return ret;
- }
- hal_clk_status_t sunxi_clk_disable(hal_clk_id_t clk)
- {
- u32 i;
- hal_clk_status_t ret = HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND;
- clk_core_pt pclk = NULL;
- clk_periph_pt periph_clk = NULL;
- clk_factor_pt factor_clk = NULL;
- CCMU_TRACE();
- pclk = clk_get_core(clk);
- if (pclk == NULL)
- {
- return ret;
- }
- switch (pclk->clk_type)
- {
- case HAL_CLK_PERIPH:
- periph_clk = (clk_periph_pt)pclk;
- ret = sunxi_clk_periph_disable(periph_clk);
- if (ret == HAL_CLK_STATUS_DISABLED)
- {
- periph_clk->clk_core.clk_enbale = HAL_CLK_STATUS_DISABLED;
- }
- return HAL_CLK_STATUS_OK;
- break;
- /* */
- case HAL_CLK_FACTOR:
- factor_clk = (clk_factor_pt)pclk;
- ret = sunxi_clk_fators_disable(factor_clk);
- if (ret == HAL_CLK_STATUS_DISABLED)
- {
- factor_clk->clk_core.clk_enbale = HAL_CLK_STATUS_DISABLED;
- }
- return HAL_CLK_STATUS_OK;
- break;
- /* */
- case HAL_CLK_FIXED_FACTOR:
- ret = HAL_CLK_STATUS_ERROR_CLK_FACTOR_REFUSED;
- break;
- /* */
- case HAL_CLK_FIXED_SRC:
- ret = HAL_CLK_STATUS_ERROR_CLK_FACTOR_REFUSED;
- break;
- /* */
- default:
- ret = HAL_CLK_STATUS_ERROT_CLK_UNDEFINED;
- break;
- }
- CCMU_TRACE();
- return ret;
- }
- hal_clk_status_t sunxi_clk_enabled(hal_clk_id_t clk)
- {
- u32 i;
- hal_clk_status_t ret = HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND;
- clk_core_pt pclk = NULL;
- clk_periph_pt periph_clk = NULL;
- clk_factor_pt factor_clk = NULL;
- CCMU_TRACE();
- pclk = clk_get_core(clk);
- if (pclk == NULL)
- {
- return ret;
- }
- switch (pclk->clk_type)
- {
- case HAL_CLK_PERIPH:
- periph_clk = (clk_periph_pt)pclk;
- ret = sunxi_clk_periph_enable(periph_clk);
- if (ret == HAL_CLK_STATUS_ENABLED)
- {
- periph_clk->clk_core.clk_enbale = HAL_CLK_STATUS_ENABLED;
- }
- break;
- /* */
- case HAL_CLK_FACTOR:
- factor_clk = (clk_factor_pt)pclk;
- ret = sunxi_clk_fators_enable(factor_clk);
- if (ret == HAL_CLK_STATUS_ENABLED)
- {
- factor_clk->clk_core.clk_enbale = HAL_CLK_STATUS_ENABLED;
- }
- break;
- /* */
- case HAL_CLK_FIXED_SRC:
- case HAL_CLK_FIXED_FACTOR:
- return pclk->clk_enbale;
- break;
- /* */
- default:
- ret = HAL_CLK_STATUS_ERROT_CLK_UNDEFINED;
- break;
- }
- CCMU_TRACE();
- return ret;
- }
- hal_clk_status_t sunxi_clk_is_enabled(hal_clk_id_t clk)
- {
- u32 i;
- hal_clk_status_t ret = HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND;
- clk_core_pt pclk = NULL;
- clk_periph_pt periph_clk = NULL;
- clk_factor_pt factor_clk = NULL;
- CCMU_TRACE();
- pclk = clk_get_core(clk);
- if (pclk == NULL)
- {
- return ret;
- }
- switch (pclk->clk_type)
- {
- case HAL_CLK_FIXED_SRC:
- case HAL_CLK_FIXED_FACTOR:
- return HAL_CLK_STATUS_ENABLED;
- break;
- /* */
- case HAL_CLK_FACTOR:
- factor_clk = (clk_factor_pt)pclk;
- return sunxi_clk_fators_is_enabled(factor_clk);
- break;
- /* */
- case HAL_CLK_PERIPH:
- periph_clk = (clk_periph_pt)pclk;
- return sunxi_clk_periph_is_enabled(periph_clk);
- break;
- /* */
- default:
- ret = HAL_CLK_STATUS_ERROT_CLK_UNDEFINED;
- break;
- }
- CCMU_TRACE();
- return ret;
- }
- hal_clk_status_t sunxi_clk_round_rate(hal_clk_id_t clk, u32 rate, u32 *prate)
- {
- u32 i, parent_rate = 0, round_rate = 0;
- hal_clk_status_t ret = HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND;
- clk_core_pt pclk = NULL;
- clk_periph_pt periph_clk = NULL;
- clk_factor_pt factor_clk = NULL;
- CCMU_TRACE();
- pclk = clk_get_core(clk);
- if (pclk == NULL)
- {
- return ret;
- }
- switch (pclk->clk_type)
- {
- /* */
- case HAL_CLK_FIXED_SRC:
- case HAL_CLK_FIXED_FACTOR:
- (*prate) = pclk->clk_rate;
- ret = HAL_CLK_STATUS_OK;
- break;
- /* */
- case HAL_CLK_FACTOR:
- factor_clk = (clk_factor_pt)pclk;
- round_rate = sunxi_clk_factors_round_rate(factor_clk, rate);
- if (round_rate == 0)
- {
- ret = HAL_CLK_STATUS_ERROR_CLK_ROUND_FAILED;
- break;
- }
- *prate = round_rate;
- ret = HAL_CLK_STATUS_OK;
- break;
- /* */
- case HAL_CLK_PERIPH:
- periph_clk = (clk_periph_pt)pclk;
- parent_rate = periph_clk->clk_core.parent_rate;
- round_rate = sunxi_clk_periph_round_rate(periph_clk, rate, parent_rate);
- if (round_rate == 0)
- {
- ret = HAL_CLK_STATUS_ERROR_CLK_ROUND_FAILED;
- break;
- }
- *prate = round_rate;
- ret = HAL_CLK_STATUS_OK;
- break;
- /* */
- default:
- ret = HAL_CLK_STATUS_ERROT_CLK_UNDEFINED;
- return ret;
- break;
- }
- CCMU_TRACE();
- return ret;
- }
- hal_clk_status_t sunxi_clk_recalc_rate(hal_clk_id_t clk, u32 *rate)
- {
- u32 i, current_rate = 0;
- u8 index = 0;
- hal_clk_status_t ret = HAL_CLK_STATUS_OK;
- hal_clk_id_t parent;
- clk_core_pt pclk = NULL;
- clk_periph_pt periph_clk = NULL;
- clk_factor_pt factor_clk = NULL;
- CCMU_TRACE();
- pclk = clk_get_core(clk);
- if (pclk == NULL)
- {
- return HAL_CLK_STATUS_ERROT_CLK_UNDEFINED;
- }
- switch (pclk->clk_type)
- {
- case HAL_CLK_PERIPH:
- periph_clk = (clk_periph_pt)pclk;
- ret = sunxi_clk_periph_recalc_rate(periph_clk, ¤t_rate);
- if (ret != HAL_CLK_STATUS_OK)
- {
- ret = HAL_CLK_STATUS_DISABLED;
- break;
- }
- (*rate) = current_rate;
- break;
- case HAL_CLK_FACTOR:
- factor_clk = (clk_factor_pt)pclk;
- ret = sunxi_clk_factors_recalc_rate(factor_clk, ¤t_rate);
- if (ret != HAL_CLK_STATUS_OK)
- {
- ret = HAL_CLK_STATUS_DISABLED;
- break;
- }
- (*rate) = current_rate;
- break;
- /* */
- case HAL_CLK_FIXED_SRC:
- case HAL_CLK_FIXED_FACTOR:
- (*rate) = pclk->clk_rate;
- break;
- /* */
- default:
- ret = HAL_CLK_STATUS_ERROT_CLK_UNDEFINED;
- break;
- }
- return ret;
- }
- hal_clk_status_t sunxi_clk_get_rate(hal_clk_id_t clk, u32 *rate)
- {
- u32 i;
- clk_core_pt pclk = NULL;
- hal_clk_status_t ret = HAL_CLK_STATUS_OK;
- CCMU_TRACE();
- pclk = clk_get_core(clk);
- if (pclk == NULL)
- {
- return HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND;
- }
- (*rate) = pclk->clk_rate;
- return HAL_CLK_STATUS_OK;
- }
- hal_clk_status_t sunxi_clk_set_rate(hal_clk_id_t clk, u32 rate)
- {
- u32 i, parent_rate;
- clk_core_pt pclk = NULL;
- clk_periph_pt periph_clk = NULL;
- clk_factor_pt factor_clk = NULL;
- hal_clk_status_t ret = HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND;
- CCMU_TRACE();
- pclk = clk_get_core(clk);
- if (pclk == NULL)
- {
- return ret;
- }
- switch (HAL_CLK_GET_TYPE(clk))
- {
- /* */
- case HAL_CLK_PERIPH:
- periph_clk = (clk_periph_pt)pclk;
- if (periph_clk->clk_core.clk_enbale == HAL_CLK_STATUS_ENABLED)
- {
- return HAL_CLK_STATUS_ERROR_CLK_NEED_DISABLED;
- }
- if (periph_clk->clk_core.clk_rate == rate)
- {
- return HAL_CLK_STATUS_OK;
- }
- parent_rate = periph_clk->clk_core.parent_rate;
- ret = sunxi_clk_periph_set_rate(periph_clk, rate);
- if (ret == HAL_CLK_STATUS_OK)
- {
- periph_clk->clk_core.clk_rate = rate;
- }
- break;
- /* */
- case HAL_CLK_FACTOR:
- factor_clk = (clk_factor_pt)pclk;
- ret = sunxi_clk_factors_set_rate(factor_clk, rate);
- if (ret == HAL_CLK_STATUS_OK)
- {
- factor_clk->clk_core.clk_rate = rate;
- }
- break;
- /* */
- case HAL_CLK_FIXED_SRC:
- case HAL_CLK_FIXED_FACTOR:
- ret = HAL_CLK_STATUS_ERROR_CLK_SET_RATE_REFUSED;
- break;
- /* */
- default:
- ret = HAL_CLK_STATUS_ERROT_CLK_UNDEFINED;
- break;
- }
- CCMU_TRACE();
- return ret;
- }
- hal_clk_status_t sunxi_fixed_factor_clk_init(void)
- {
- u32 i = 0, parent_rate = 0;
- clk_core_pt pclk = NULL;
- clk_core_pt parent_clk_core = NULL;
- clk_fixed_factor_pt fixed_factor = NULL;
- hal_clk_status_t ret = HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND;
- CCMU_TRACE();
- for (i = 0; sunxi_clk_fixed_factor_arry[i] != NULL; i++)
- {
- fixed_factor = sunxi_clk_fixed_factor_arry[i];
- parent_clk_core = clk_get_core(fixed_factor->clk_core.current_parent);
- if (parent_clk_core == NULL)
- {
- return ret;
- }
- if (parent_clk_core->clk_enbale == HAL_CLK_STATUS_DISABLED)
- {
- return HAL_CLK_STATUS_ERROR_CLK_PARENT_DISABLED;
- }
- parent_rate = parent_clk_core->clk_rate;
- fixed_factor->clk_core.clk_enbale = HAL_CLK_STATUS_ENABLED;
- fixed_factor->clk_core.parent_rate = parent_rate;
- fixed_factor->clk_core.clk_rate = (parent_rate * fixed_factor->clk_mult) / fixed_factor->clk_div;
- }
- ret = HAL_CLK_STATUS_OK;
- CCMU_TRACE();
- return ret;
- }
- hal_clk_status_t sunxi_periph_bus_clk_init(void)
- {
- hal_clk_status_t ret;
- clk_base_pt clk_init;
- clk_periph_pt pclk;
- hal_clk_id_t parent_clk;
- u32 i = 0, parent_rate = 0, round_rate = 0, check_rate = 0;
- CCMU_TRACE();
- for (i = 0; sunxi_periph_clk_init_arry[i] != NULL; i++)
- {
- parent_clk = HAL_CLK_UNINITIALIZED ;
- clk_init = sunxi_periph_clk_init_arry[i];
- pclk = (clk_periph_pt)clk_get_core(clk_init->clk);
- if (pclk == NULL)
- {
- return HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND;
- }
- CCMU_DBG("Clk-id %d init start.................\n", clk_init->clk);
- /* check and set clk parent select regs*/
- ret = sunxi_clk_get_parent(clk_init->clk, &parent_clk);
- if (ret != HAL_CLK_STATUS_OK)
- {
- break;
- }
- if (clk_init->parent != parent_clk)
- {
- CCMU_DBG("set Parent-id %d \n", parent_clk);
- ret = sunxi_clk_set_parent(clk_init->clk, clk_init->parent);
- if (ret != HAL_CLK_STATUS_OK)
- {
- break;
- }
- }
- /* check and get round clk*/
- ret = sunxi_clk_get_rate(clk_init->parent, &parent_rate);
- if (ret != HAL_CLK_STATUS_OK)
- {
- break;
- }
- pclk->clk_core.current_parent = clk_init->parent;
- pclk->clk_core.parent_rate = parent_rate;
- ret = sunxi_clk_round_rate(clk_init->clk, clk_init->clk_rate, &round_rate);
- if (ret != HAL_CLK_STATUS_OK)
- {
- break;
- }
- CCMU_DBG("get round rate %dHZ\n", round_rate);
- /* check and disbale clk status*/
- ret = sunxi_clk_is_enabled(clk_init->clk);
- if (ret == HAL_CLK_STATUS_ENABLED)
- {
- ret = sunxi_clk_disable(clk_init->clk);
- if (ret != HAL_CLK_STATUS_OK)
- {
- break;
- }
- }
- CCMU_DBG("set new rate %dHZ\n", round_rate);
- /* set clk rate*/
- ret = sunxi_clk_set_rate(clk_init->clk, round_rate);
- if (ret != HAL_CLK_STATUS_OK)
- {
- break;
- }
- /* enable clk status*/
- ret = sunxi_clk_enabled(clk_init->clk);
- if (ret != HAL_CLK_STATUS_ENABLED)
- {
- break;
- }
- ret = sunxi_clk_recalc_rate(clk_init->clk, &check_rate);
- if (ret != HAL_CLK_STATUS_OK)
- {
- break;
- }
- CCMU_DBG("Clk-id %d cached rate %dHZ recalc new rate %dHZ, parent-id %d parent rate %dHZ \n", clk_init->clk, pclk->clk_core.clk_rate, check_rate,
- pclk->clk_core.current_parent, pclk->clk_core.parent_rate);
- CCMU_DBG("Clk-id %d init final .................\n", clk_init->clk);
- }
- CCMU_DBG("ret %d \n", ret);
- return ret;
- }
- hal_clk_status_t sunxi_factor_clk_init(void)
- {
- u32 i;
- hal_clk_status_t ret = HAL_CLK_STATUS_OK;
- hal_clk_status_t (*func)(void) = NULL;
- for (i = 0; sunxi_clk_factor_init[i] != NULL; i++)
- {
- func = sunxi_clk_factor_init[i];
- ret = func();
- if (ret != HAL_CLK_STATUS_OK)
- {
- break;
- }
- }
- return ret;
- }
- hal_clk_status_t clk_set_parent(hal_clk_id_t clk, hal_clk_id_t parent_clk)
- {
- return sunxi_clk_set_parent(clk, parent_clk);
- }
- hal_clk_id_t clk_get_parent(hal_clk_id_t clk)
- {
- hal_clk_id_t parent_clk = HAL_CLK_UNINITIALIZED ;
- hal_clk_status_t ret;
- ret = sunxi_clk_get_parent(clk, &parent_clk);
- if (ret == HAL_CLK_STATUS_OK)
- {
- return parent_clk;
- }
- else
- {
- return HAL_CLK_UNINITIALIZED;
- }
- }
- hal_clk_status_t clk_disable_unprepare(hal_clk_id_t clk)
- {
- return sunxi_clk_disable(clk);
- }
- hal_clk_status_t clk_prepare_enable(hal_clk_id_t clk)
- {
- return sunxi_clk_enabled(clk);
- }
- hal_clk_status_t clk_is_enabled(hal_clk_id_t clk)
- {
- return sunxi_clk_is_enabled(clk);
- }
- hal_clk_status_t clk_round_rate(hal_clk_id_t clk, u32 rate, u32 *prate)
- {
- return sunxi_clk_round_rate(clk, rate, prate);
- }
- hal_clk_status_t clk_recalc_rate(hal_clk_id_t clk, u32 *p_rate)
- {
- return sunxi_clk_recalc_rate(clk, p_rate);
- }
- hal_clk_status_t clk_set_rate(hal_clk_id_t clk, u32 rate)
- {
- return sunxi_clk_set_rate(clk, rate);
- }
- hal_clk_status_t clk_get_rate(hal_clk_id_t clk, u32 *rate)
- {
- return sunxi_clk_get_rate(clk, rate);
- }
- hal_clk_id_t clk_get(hal_clk_type_t type, hal_clk_id_t id)
- {
- return id;
- }
- hal_clk_status_t clk_put(hal_clk_id_t id)
- {
- return HAL_CLK_STATUS_OK;
- }
- hal_clk_status_t clk_init(void)
- {
- hal_clk_status_t ret;
- ret = sunxi_factor_clk_init();
- /*the parent clk of some fixed-factor clk maybe factor-pll clk,
- so factor-pll clk init before fixed-factor clk*/
- ret = sunxi_fixed_factor_clk_init();
- ret = sunxi_periph_bus_clk_init();
- return ret;
- }
|