Commit e74581b7 authored by Stephen Boyd's avatar Stephen Boyd

Merge tag 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson into clk-meson

Pull more meson clk driver updates from Neil Armstrong:

 - Fix GXL HDMI Pll fractional bits (from first round)
 - Add the Meson8/Meson8b video clocks
 - Add clk-input helper and use it for axg-audio clock driver

* tag 'meson-clk-4.21-2' of https://github.com/BayLibre/clk-meson:
  clk: meson: axg-audio: use the clk input helper function
  clk: meson: add clk-input helper function
  clk: meson: meson8b: add the read-only video clock trees
  clk: meson: meson8b: add the fractional divider for vid_pll_dco
  clk: meson: meson8b: fix the offset of vid_pll_dco's N value
  clk: meson: Fix GXL HDMI PLL fractional bits width
parents 8913e8a7 f03566d0
......@@ -3,6 +3,7 @@
#
obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-phase.o vid-pll-div.o
obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-input.o
obj-$(CONFIG_COMMON_CLK_AMLOGIC_AUDIO) += clk-triphase.o sclk-div.o
obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o
obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
......
......@@ -631,22 +631,23 @@ static struct clk_regmap *const axg_audio_clk_regmaps[] = {
&axg_tdmout_c_lrclk,
};
static struct clk *devm_clk_get_enable(struct device *dev, char *id)
static int devm_clk_get_enable(struct device *dev, char *id)
{
struct clk *clk;
int ret;
clk = devm_clk_get(dev, id);
if (IS_ERR(clk)) {
if (PTR_ERR(clk) != -EPROBE_DEFER)
ret = PTR_ERR(clk);
if (ret != -EPROBE_DEFER)
dev_err(dev, "failed to get %s", id);
return clk;
return ret;
}
ret = clk_prepare_enable(clk);
if (ret) {
dev_err(dev, "failed to enable %s", id);
return ERR_PTR(ret);
return ret;
}
ret = devm_add_action_or_reset(dev,
......@@ -654,74 +655,40 @@ static struct clk *devm_clk_get_enable(struct device *dev, char *id)
clk);
if (ret) {
dev_err(dev, "failed to add reset action on %s", id);
return ERR_PTR(ret);
return ret;
}
return clk;
}
static const struct clk_ops axg_clk_no_ops = {};
static struct clk_hw *axg_clk_hw_register_bypass(struct device *dev,
const char *name,
const char *parent_name)
{
struct clk_hw *hw;
struct clk_init_data init;
char *clk_name;
int ret;
hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
if (!hw)
return ERR_PTR(-ENOMEM);
clk_name = kasprintf(GFP_KERNEL, "axg_%s", name);
if (!clk_name)
return ERR_PTR(-ENOMEM);
init.name = clk_name;
init.ops = &axg_clk_no_ops;
init.flags = 0;
init.parent_names = parent_name ? &parent_name : NULL;
init.num_parents = parent_name ? 1 : 0;
hw->init = &init;
ret = devm_clk_hw_register(dev, hw);
kfree(clk_name);
return ret ? ERR_PTR(ret) : hw;
return 0;
}
static int axg_register_clk_hw_input(struct device *dev,
const char *name,
unsigned int clkid)
{
struct clk *parent_clk = devm_clk_get(dev, name);
struct clk_hw *hw = NULL;
char *clk_name;
struct clk_hw *hw;
int err = 0;
if (IS_ERR(parent_clk)) {
int err = PTR_ERR(parent_clk);
clk_name = kasprintf(GFP_KERNEL, "axg_%s", name);
if (!clk_name)
return -ENOMEM;
hw = meson_clk_hw_register_input(dev, name, clk_name, 0);
if (IS_ERR(hw)) {
/* It is ok if an input clock is missing */
if (err == -ENOENT) {
if (PTR_ERR(hw) == -ENOENT) {
dev_dbg(dev, "%s not provided", name);
} else {
err = PTR_ERR(hw);
if (err != -EPROBE_DEFER)
dev_err(dev, "failed to get %s clock", name);
return err;
}
} else {
hw = axg_clk_hw_register_bypass(dev, name,
__clk_get_name(parent_clk));
}
if (IS_ERR(hw)) {
dev_err(dev, "failed to register %s clock", name);
return PTR_ERR(hw);
axg_audio_hw_onecell_data.hws[clkid] = hw;
}
axg_audio_hw_onecell_data.hws[clkid] = hw;
return 0;
kfree(clk_name);
return err;
}
static int axg_register_clk_hw_inputs(struct device *dev,
......@@ -759,7 +726,6 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
struct regmap *map;
struct resource *res;
void __iomem *regs;
struct clk *clk;
struct clk_hw *hw;
int ret, i;
......@@ -775,9 +741,9 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
}
/* Get the mandatory peripheral clock */
clk = devm_clk_get_enable(dev, "pclk");
if (IS_ERR(clk))
return PTR_ERR(clk);
ret = devm_clk_get_enable(dev, "pclk");
if (ret)
return ret;
ret = device_reset(dev);
if (ret) {
......@@ -786,8 +752,7 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
}
/* Register the peripheral input clock */
hw = axg_clk_hw_register_bypass(dev, "audio_pclk",
__clk_get_name(clk));
hw = meson_clk_hw_register_input(dev, "pclk", "axg_audio_pclk", 0);
if (IS_ERR(hw))
return PTR_ERR(hw);
......
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (c) 2018 BayLibre, SAS.
* Author: Jerome Brunet <jbrunet@baylibre.com>
*/
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/device.h>
#include "clkc.h"
static const struct clk_ops meson_clk_no_ops = {};
struct clk_hw *meson_clk_hw_register_input(struct device *dev,
const char *of_name,
const char *clk_name,
unsigned long flags)
{
struct clk *parent_clk = devm_clk_get(dev, of_name);
struct clk_init_data init;
const char *parent_name;
struct clk_hw *hw;
int ret;
if (IS_ERR(parent_clk))
return (struct clk_hw *)parent_clk;
hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
if (!hw)
return ERR_PTR(-ENOMEM);
parent_name = __clk_get_name(parent_clk);
init.name = clk_name;
init.ops = &meson_clk_no_ops;
init.flags = flags;
init.parent_names = &parent_name;
init.num_parents = 1;
hw->init = &init;
ret = devm_clk_hw_register(dev, hw);
return ret ? ERR_PTR(ret) : hw;
}
EXPORT_SYMBOL_GPL(meson_clk_hw_register_input);
......@@ -119,4 +119,9 @@ extern const struct clk_ops meson_clk_mpll_ops;
extern const struct clk_ops meson_clk_phase_ops;
extern const struct clk_ops meson_vid_pll_div_ro_ops;
struct clk_hw *meson_clk_hw_register_input(struct device *dev,
const char *of_name,
const char *clk_name,
unsigned long flags);
#endif /* __CLKC_H */
......@@ -216,10 +216,16 @@ static struct clk_regmap gxl_hdmi_pll_dco = {
.shift = 9,
.width = 5,
},
/*
* On gxl, there is a register shift due to
* HHI_HDMI_PLL_CNTL1 which does not exist on gxbb,
* so we use the HHI_HDMI_PLL_CNTL2 define from GXBB
* instead which is defined at the same offset.
*/
.frac = {
.reg_off = HHI_HDMI_PLL_CNTL2,
.shift = 0,
.width = 12,
.width = 10,
},
.l = {
.reg_off = HHI_HDMI_PLL_CNTL,
......
This diff is collapsed.
......@@ -19,20 +19,26 @@
*
* [0] http://dn.odroid.com/S805/Datasheet/S805_Datasheet%20V0.8%2020150126.pdf
*/
#define HHI_VIID_CLK_DIV 0x128 /* 0x4a offset in data sheet */
#define HHI_VIID_CLK_CNTL 0x12c /* 0x4b offset in data sheet */
#define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */
#define HHI_GCLK_MPEG1 0x144 /* 0x51 offset in data sheet */
#define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
#define HHI_GCLK_OTHER 0x150 /* 0x54 offset in data sheet */
#define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */
#define HHI_SYS_CPU_CLK_CNTL1 0x15c /* 0x57 offset in data sheet */
#define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */
#define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */
#define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */
#define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */
#define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */
#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */
#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 offset in data sheet */
#define HHI_NAND_CLK_CNTL 0x25c /* 0x97 offset in data sheet */
#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */
#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */
#define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
#define HHI_VID_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */
/*
* MPLL register offeset taken from the S905 datasheet. Vendor kernel source
......@@ -76,7 +82,7 @@
#define CLKID_NAND_SEL 110
#define CLKID_NAND_DIV 111
#define CLKID_PLL_FIXED_DCO 113
#define CLKID_PLL_VID_DCO 114
#define CLKID_HDMI_PLL_DCO 114
#define CLKID_PLL_SYS_DCO 115
#define CLKID_CPU_CLK_DIV2 116
#define CLKID_CPU_CLK_DIV3 117
......@@ -89,8 +95,52 @@
#define CLKID_PERIPH_SEL 125
#define CLKID_AXI_SEL 127
#define CLKID_L2_DRAM_SEL 129
#define CLKID_HDMI_PLL_LVDS_OUT 131
#define CLKID_HDMI_PLL_HDMI_OUT 132
#define CLKID_VID_PLL_IN_SEL 133
#define CLKID_VID_PLL_IN_EN 134
#define CLKID_VID_PLL_PRE_DIV 135
#define CLKID_VID_PLL_POST_DIV 136
#define CLKID_VID_PLL_FINAL_DIV 137
#define CLKID_VCLK_IN_SEL 138
#define CLKID_VCLK_IN_EN 139
#define CLKID_VCLK_DIV1 140
#define CLKID_VCLK_DIV2_DIV 141
#define CLKID_VCLK_DIV2 142
#define CLKID_VCLK_DIV4_DIV 143
#define CLKID_VCLK_DIV4 144
#define CLKID_VCLK_DIV6_DIV 145
#define CLKID_VCLK_DIV6 146
#define CLKID_VCLK_DIV12_DIV 147
#define CLKID_VCLK_DIV12 148
#define CLKID_VCLK2_IN_SEL 149
#define CLKID_VCLK2_IN_EN 150
#define CLKID_VCLK2_DIV1 151
#define CLKID_VCLK2_DIV2_DIV 152
#define CLKID_VCLK2_DIV2 153
#define CLKID_VCLK2_DIV4_DIV 154
#define CLKID_VCLK2_DIV4 155
#define CLKID_VCLK2_DIV6_DIV 156
#define CLKID_VCLK2_DIV6 157
#define CLKID_VCLK2_DIV12_DIV 158
#define CLKID_VCLK2_DIV12 159
#define CLKID_CTS_ENCT_SEL 160
#define CLKID_CTS_ENCT 161
#define CLKID_CTS_ENCP_SEL 162
#define CLKID_CTS_ENCP 163
#define CLKID_CTS_ENCI_SEL 164
#define CLKID_CTS_ENCI 165
#define CLKID_HDMI_TX_PIXEL_SEL 166
#define CLKID_HDMI_TX_PIXEL 167
#define CLKID_CTS_ENCL_SEL 168
#define CLKID_CTS_ENCL 169
#define CLKID_CTS_VDAC0_SEL 170
#define CLKID_CTS_VDAC0 171
#define CLKID_HDMI_SYS_SEL 172
#define CLKID_HDMI_SYS_DIV 173
#define CLKID_HDMI_SYS 174
#define CLK_NR_CLKS 131
#define CLK_NR_CLKS 175
/*
* include the CLKID and RESETID that have
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment