Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/clk/spacemit/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 3 kB image not shown  

Quelle  ccu_pll.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2024 SpacemiT Technology Co. Ltd
 * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>
 */


#include <linux/clk-provider.h>
#include <linux/math.h>
#include <linux/regmap.h>

#include "ccu_common.h"
#include "ccu_pll.h"

#define PLL_TIMEOUT_US  3000
#define PLL_DELAY_US  5

#define PLL_SWCR3_EN  ((u32)BIT(31))
#define PLL_SWCR3_MASK  GENMASK(30, 0)

static const struct ccu_pll_rate_tbl *ccu_pll_lookup_best_rate(struct ccu_pll *pll,
              unsigned long rate)
{
 struct ccu_pll_config *config = &pll->config;
 const struct ccu_pll_rate_tbl *best_entry;
 unsigned long best_delta = ULONG_MAX;
 int i;

 for (i = 0; i < config->tbl_num; i++) {
  const struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i];
  unsigned long delta = abs_diff(entry->rate, rate);

  if (delta < best_delta) {
   best_delta = delta;
   best_entry = entry;
  }
 }

 return best_entry;
}

static const struct ccu_pll_rate_tbl *ccu_pll_lookup_matched_entry(struct ccu_pll *pll)
{
 struct ccu_pll_config *config = &pll->config;
 u32 swcr1, swcr3;
 int i;

 swcr1 = ccu_read(&pll->common, swcr1);
 swcr3 = ccu_read(&pll->common, swcr3);
 swcr3 &= PLL_SWCR3_MASK;

 for (i = 0; i < config->tbl_num; i++) {
  const struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i];

  if (swcr1 == entry->swcr1 && swcr3 == entry->swcr3)
   return entry;
 }

 return NULL;
}

static void ccu_pll_update_param(struct ccu_pll *pll, const struct ccu_pll_rate_tbl *entry)
{
 struct ccu_common *common = &pll->common;

 regmap_write(common->regmap, common->reg_swcr1, entry->swcr1);
 ccu_update(common, swcr3, PLL_SWCR3_MASK, entry->swcr3);
}

static int ccu_pll_is_enabled(struct clk_hw *hw)
{
 struct ccu_common *common = hw_to_ccu_common(hw);

 return ccu_read(common, swcr3) & PLL_SWCR3_EN;
}

static int ccu_pll_enable(struct clk_hw *hw)
{
 struct ccu_pll *pll = hw_to_ccu_pll(hw);
 struct ccu_common *common = &pll->common;
 unsigned int tmp;

 ccu_update(common, swcr3, PLL_SWCR3_EN, PLL_SWCR3_EN);

 /* check lock status */
 return regmap_read_poll_timeout_atomic(common->lock_regmap,
            pll->config.reg_lock,
            tmp,
            tmp & pll->config.mask_lock,
            PLL_DELAY_US, PLL_TIMEOUT_US);
}

static void ccu_pll_disable(struct clk_hw *hw)
{
 struct ccu_common *common = hw_to_ccu_common(hw);

 ccu_update(common, swcr3, PLL_SWCR3_EN, 0);
}

/*
 * PLLs must be gated before changing rate, which is ensured by
 * flag CLK_SET_RATE_GATE.
 */

static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate,
       unsigned long parent_rate)
{
 struct ccu_pll *pll = hw_to_ccu_pll(hw);
 const struct ccu_pll_rate_tbl *entry;

 entry = ccu_pll_lookup_best_rate(pll, rate);
 ccu_pll_update_param(pll, entry);

 return 0;
}

static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
      unsigned long parent_rate)
{
 struct ccu_pll *pll = hw_to_ccu_pll(hw);
 const struct ccu_pll_rate_tbl *entry;

 entry = ccu_pll_lookup_matched_entry(pll);

 WARN_ON_ONCE(!entry);

 return entry ? entry->rate : 0;
}

static long ccu_pll_round_rate(struct clk_hw *hw, unsigned long rate,
          unsigned long *prate)
{
 struct ccu_pll *pll = hw_to_ccu_pll(hw);

 return ccu_pll_lookup_best_rate(pll, rate)->rate;
}

static int ccu_pll_init(struct clk_hw *hw)
{
 struct ccu_pll *pll = hw_to_ccu_pll(hw);

 if (ccu_pll_lookup_matched_entry(pll))
  return 0;

 ccu_pll_disable(hw);
 ccu_pll_update_param(pll, &pll->config.rate_tbl[0]);

 return 0;
}

const struct clk_ops spacemit_ccu_pll_ops = {
 .init  = ccu_pll_init,
 .enable  = ccu_pll_enable,
 .disable = ccu_pll_disable,
 .set_rate = ccu_pll_set_rate,
 .recalc_rate = ccu_pll_recalc_rate,
 .round_rate = ccu_pll_round_rate,
 .is_enabled = ccu_pll_is_enabled,
};

Messung V0.5
C=96 H=93 G=94

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.