Release 4.11 drivers/gpu/drm/sun4i/sun4i_dotclock.c
/*
* Copyright (C) 2016 Free Electrons
* Copyright (C) 2016 NextThing Co
*
* Maxime Ripard <maxime.ripard@free-electrons.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*/
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include "sun4i_tcon.h"
#include "sun4i_dotclock.h"
struct sun4i_dclk {
struct clk_hw hw;
struct regmap *regmap;
};
static inline struct sun4i_dclk *hw_to_dclk(struct clk_hw *hw)
{
return container_of(hw, struct sun4i_dclk, hw);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 25 | 100.00% | 1 | 100.00% |
Total | 25 | 100.00% | 1 | 100.00% |
static void sun4i_dclk_disable(struct clk_hw *hw)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
regmap_update_bits(dclk->regmap, SUN4I_TCON0_DCLK_REG,
BIT(SUN4I_TCON0_DCLK_GATE_BIT), 0);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 37 | 100.00% | 1 | 100.00% |
Total | 37 | 100.00% | 1 | 100.00% |
static int sun4i_dclk_enable(struct clk_hw *hw)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
return regmap_update_bits(dclk->regmap, SUN4I_TCON0_DCLK_REG,
BIT(SUN4I_TCON0_DCLK_GATE_BIT),
BIT(SUN4I_TCON0_DCLK_GATE_BIT));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 41 | 100.00% | 1 | 100.00% |
Total | 41 | 100.00% | 1 | 100.00% |
static int sun4i_dclk_is_enabled(struct clk_hw *hw)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
u32 val;
regmap_read(dclk->regmap, SUN4I_TCON0_DCLK_REG, &val);
return val & BIT(SUN4I_TCON0_DCLK_GATE_BIT);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 44 | 100.00% | 1 | 100.00% |
Total | 44 | 100.00% | 1 | 100.00% |
static unsigned long sun4i_dclk_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
u32 val;
regmap_read(dclk->regmap, SUN4I_TCON0_DCLK_REG, &val);
val >>= SUN4I_TCON0_DCLK_DIV_SHIFT;
val &= (1 << SUN4I_TCON0_DCLK_DIV_WIDTH) - 1;
if (!val)
val = 1;
return parent_rate / val;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 63 | 91.30% | 1 | 50.00% |
Chen-Yu Tsai | 6 | 8.70% | 1 | 50.00% |
Total | 69 | 100.00% | 2 | 100.00% |
static long sun4i_dclk_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
unsigned long best_parent = 0;
u8 best_div = 1;
int i;
for (i = 6; i <= 127; i++) {
unsigned long ideal = rate * i;
unsigned long rounded;
rounded = clk_hw_round_rate(clk_hw_get_parent(hw),
ideal);
if (rounded == ideal) {
best_parent = rounded;
best_div = i;
goto out;
}
if (abs(rate - rounded / i) <
abs(rate - best_parent / best_div)) {
best_parent = rounded;
best_div = i;
}
}
out:
*parent_rate = best_parent;
return best_parent / best_div;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 119 | 88.81% | 2 | 50.00% |
Chen-Yu Tsai | 15 | 11.19% | 2 | 50.00% |
Total | 134 | 100.00% | 4 | 100.00% |
static int sun4i_dclk_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
u8 div = parent_rate / rate;
return regmap_update_bits(dclk->regmap, SUN4I_TCON0_DCLK_REG,
GENMASK(6, 0), div);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 55 | 100.00% | 2 | 100.00% |
Total | 55 | 100.00% | 2 | 100.00% |
static int sun4i_dclk_get_phase(struct clk_hw *hw)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
u32 val;
regmap_read(dclk->regmap, SUN4I_TCON0_IO_POL_REG, &val);
val >>= 28;
val &= 3;
return val * 120;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 49 | 100.00% | 1 | 100.00% |
Total | 49 | 100.00% | 1 | 100.00% |
static int sun4i_dclk_set_phase(struct clk_hw *hw, int degrees)
{
struct sun4i_dclk *dclk = hw_to_dclk(hw);
regmap_update_bits(dclk->regmap, SUN4I_TCON0_IO_POL_REG,
GENMASK(29, 28),
degrees / 120);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 47 | 100.00% | 1 | 100.00% |
Total | 47 | 100.00% | 1 | 100.00% |
static const struct clk_ops sun4i_dclk_ops = {
.disable = sun4i_dclk_disable,
.enable = sun4i_dclk_enable,
.is_enabled = sun4i_dclk_is_enabled,
.recalc_rate = sun4i_dclk_recalc_rate,
.round_rate = sun4i_dclk_round_rate,
.set_rate = sun4i_dclk_set_rate,
.get_phase = sun4i_dclk_get_phase,
.set_phase = sun4i_dclk_set_phase,
};
int sun4i_dclk_create(struct device *dev, struct sun4i_tcon *tcon)
{
const char *clk_name, *parent_name;
struct clk_init_data init;
struct sun4i_dclk *dclk;
int ret;
parent_name = __clk_get_name(tcon->sclk0);
ret = of_property_read_string_index(dev->of_node,
"clock-output-names", 0,
&clk_name);
if (ret)
return ret;
dclk = devm_kzalloc(dev, sizeof(*dclk), GFP_KERNEL);
if (!dclk)
return -ENOMEM;
init.name = clk_name;
init.ops = &sun4i_dclk_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = CLK_SET_RATE_PARENT;
dclk->regmap = tcon->regs;
dclk->hw.init = &init;
tcon->dclk = clk_register(dev, &dclk->hw);
if (IS_ERR(tcon->dclk))
return PTR_ERR(tcon->dclk);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 162 | 93.10% | 2 | 66.67% |
Arnd Bergmann | 12 | 6.90% | 1 | 33.33% |
Total | 174 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(sun4i_dclk_create);
int sun4i_dclk_free(struct sun4i_tcon *tcon)
{
clk_unregister(tcon->dclk);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 20 | 100.00% | 1 | 100.00% |
Total | 20 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL(sun4i_dclk_free);
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Maxime Ripard | 744 | 95.38% | 2 | 28.57% |
Chen-Yu Tsai | 21 | 2.69% | 3 | 42.86% |
Arnd Bergmann | 12 | 1.54% | 1 | 14.29% |
Baoyou Xie | 3 | 0.38% | 1 | 14.29% |
Total | 780 | 100.00% | 7 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.