// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2013 Samsung Electronics Co., Ltd.
* Copyright (c) 2013 Linaro Ltd.
*
* This file contains the utility functions to register the pll clocks.
*/
#include <linux/errno.h>
#include <linux/hrtimer.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include "clk.h"
#include "clk-pll.h"
#define PLL_TIMEOUT_MS 10
struct samsung_clk_pll {
struct clk_hw hw;
void __iomem *lock_reg;
void __iomem *con_reg;
/* PLL enable control bit offset in @con_reg register */
unsigned short enable_offs;
/* PLL lock status bit offset in @con_reg register */
unsigned short lock_offs;
enum samsung_pll_type type;
unsigned int rate_count;
const struct samsung_pll_rate_table *rate_table;
};
#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
static const struct samsung_pll_rate_table *samsung_get_pll_settings(
struct samsung_clk_pll *pll, unsigned long rate)
{
const struct samsung_pll_rate_table *rate_table = pll->rate_table;
int i;
for (i = 0; i < pll->rate_count; i++) {
if (rate == rate_table[i].rate)
return &rate_table[i];
}
return NULL;
}
static long samsung_pll_round_rate(struct clk_hw *hw,
unsigned long drate, unsigned long *prate)
{
struct samsung_clk_pll *pll = to_clk_pll(hw);
const struct samsung_pll_rate_table *rate_table = pll->rate_table;
int i;
/* Assumming rate_table is in descending order */
for (i = 0; i < pll->rate_count; i++) {
if (drate >= rate_table[i].rate)
return rate_table[i].rate;
}
/* return minimum supported value */
return rate_table[i - 1].rate;
}
static int samsung_pll3xxx_enable(struct clk_hw *hw)
{
struct samsung_clk_pll *pll = <