mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
Merge branches 'clk-mmp', 'clk-intel', 'clk-ingenic', 'clk-qcom' and 'clk-silabs' into clk-next
- Start making audio and GPU clks work on Marvell MMP2/MMP3 SoCs - Add support for X1830 and X1000 Ingenic SoC clk controllers - Add support for Qualcomm's MSM8939 Generic Clock Controller - Add some GPU, NPU, and UFS clks to Qualcomm SM8150 driver - Enable supply regulators for GPU gdscs on Qualcomm SoCs - Add support for Si5342, Si5344 and Si5345 chips * clk-mmp: clk: mmp2: Add audio clock controller driver dt-bindings: clock: Add Marvell MMP Audio Clock Controller binding clk: mmp2: Add support for power islands dt-bindings: marvell,mmp2: Add ids for the power domains dt-bindings: clock: Make marvell,mmp2-clock a power controller clk: mmp2: Add the audio clock clk: mmp2: Add the I2S clocks clk: mmp2: Rename mmp2_pll_init() to mmp2_main_clk_init() clk: mmp2: Move thermal register defines up a bit dt-bindings: marvell,mmp2: Add clock id for the Audio clock dt-bindings: marvell,mmp2: Add clock id for the I2S clocks clk: mmp: frac: Allow setting bits other than the numerator/denominator clk: mmp: frac: Do not lose last 4 digits of precision * clk-intel: clk: intel: remove redundant initialization of variable rate64 clk: intel: Add CGU clock driver for a new SoC dt-bindings: clk: intel: Add bindings document & header file for CGU * clk-ingenic: clk: ingenic: Mark ingenic_tcu_of_match as __maybe_unused clk: X1000: Add FIXDIV for SSI clock of X1000. dt-bindings: clock: Add and reorder ABI for X1000. clk: Ingenic: Add CGU driver for X1830. dt-bindings: clock: Add X1830 clock bindings. clk: Ingenic: Adjust cgu code to make it compatible with X1830. clk: Ingenic: Remove unnecessary spinlock when reading registers. * clk-qcom: clk: qcom: Add missing msm8998 ufs_unipro_core_clk_src dt-bindings: clock: Add YAML schemas for QCOM A53 PLL clk: qcom: gcc-msm8939: Add MSM8939 Generic Clock Controller clk: qcom: gcc: Add support for Secure control source clock dt-bindings: clock: Add gcc_sec_ctrl_clk_src clock ID clk: qcom: gcc: Add support for a new frequency for SC7180 clk: qcom: Add DT bindings for MSM8939 GCC clk: qcom: gcc: Add missing UFS clocks for SM8150 clk: qcom: gcc: Add GPU and NPU clocks for SM8150 clk: qcom: mmcc-msm8996: Properly describe GPU_GX gdsc clk: qcom: gdsc: Handle GDSC regulator supplies clk: qcom: msm8916: Fix the address location of pll->config_reg * clk-silabs: clk: clk-si5341: Add support for the Si5345 series
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/intel,cgu-lgm.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Intel Lightning Mountain SoC's Clock Controller(CGU) Binding
|
||||
|
||||
maintainers:
|
||||
- Rahul Tanwar <rahul.tanwar@linux.intel.com>
|
||||
|
||||
description: |
|
||||
Lightning Mountain(LGM) SoC's Clock Generation Unit(CGU) driver provides
|
||||
all means to access the CGU hardware module in order to generate a series
|
||||
of clocks for the whole system and individual peripherals.
|
||||
|
||||
Please refer to include/dt-bindings/clock/intel,lgm-clk.h header file, it
|
||||
defines all available clocks as macros. These macros can be used in device
|
||||
tree sources.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: intel,cgu-lgm
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
|
||||
examples:
|
||||
- |
|
||||
cgu: clock-controller@e0200000 {
|
||||
compatible = "intel,cgu-lgm";
|
||||
reg = <0xe0200000 0x33c>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
...
|
||||
@@ -0,0 +1,74 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/marvell,mmp2-audio-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Marvell MMP2 Audio Clock Controller
|
||||
|
||||
maintainers:
|
||||
- Lubomir Rintel <lkundrak@v3.sk>
|
||||
|
||||
description: |
|
||||
The audio clock controller generates and supplies the clocks to the audio
|
||||
codec.
|
||||
|
||||
Each clock is assigned an identifier and client nodes use this identifier
|
||||
to specify the clock which they consume.
|
||||
|
||||
All these identifiers could be found in
|
||||
<dt-bindings/clock/marvell,mmp2-audio.h>.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- marvell,mmp2-audio-clock
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Audio subsystem clock
|
||||
- description: The crystal oscillator clock
|
||||
- description: First I2S clock
|
||||
- description: Second I2S clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: audio
|
||||
- const: vctcxo
|
||||
- const: i2s0
|
||||
- const: i2s1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/marvell,mmp2-audio.h>
|
||||
#include <dt-bindings/power/marvell,mmp2.h>
|
||||
|
||||
clock-controller@d42a0c30 {
|
||||
compatible = "marvell,mmp2-audio-clock";
|
||||
reg = <0xd42a0c30 0x10>;
|
||||
clock-names = "audio", "vctcxo", "i2s0", "i2s1";
|
||||
clocks = <&soc_clocks MMP2_CLK_AUDIO>,
|
||||
<&soc_clocks MMP2_CLK_VCTCXO>,
|
||||
<&soc_clocks MMP2_CLK_I2S0>,
|
||||
<&soc_clocks MMP2_CLK_I2S1>;
|
||||
power-domains = <&soc_clocks MMP2_POWER_DOMAIN_AUDIO>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
@@ -42,12 +42,16 @@ properties:
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
@@ -61,4 +65,5 @@ examples:
|
||||
reg-names = "mpmu", "apmu", "apbc";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
Qualcomm MSM8916 A53 PLL Binding
|
||||
--------------------------------
|
||||
The A53 PLL on MSM8916 platforms is the main CPU PLL used used for frequencies
|
||||
above 1GHz.
|
||||
|
||||
Required properties :
|
||||
- compatible : Shall contain only one of the following:
|
||||
|
||||
"qcom,msm8916-a53pll"
|
||||
|
||||
- reg : shall contain base register location and length
|
||||
|
||||
- #clock-cells : must be set to <0>
|
||||
|
||||
Example:
|
||||
|
||||
a53pll: clock@b016000 {
|
||||
compatible = "qcom,msm8916-a53pll";
|
||||
reg = <0xb016000 0x40>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,a53pll.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm A53 PLL Binding
|
||||
|
||||
maintainers:
|
||||
- Sivaprakash Murugesan <sivaprak@codeaurora.org>
|
||||
|
||||
description:
|
||||
The A53 PLL on few Qualcomm platforms is the main CPU PLL used used for
|
||||
frequencies above 1GHz.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,msm8916-a53pll
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
#Example 1 - A53 PLL found on MSM8916 devices
|
||||
- |
|
||||
a53pll: clock@b016000 {
|
||||
compatible = "qcom,msm8916-a53pll";
|
||||
reg = <0xb016000 0x40>;
|
||||
#clock-cells = <0>;
|
||||
};
|
||||
@@ -22,6 +22,8 @@ description: |
|
||||
- dt-bindings/reset/qcom,gcc-ipq6018.h
|
||||
- dt-bindings/clock/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
|
||||
- dt-bindings/reset/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
|
||||
- dt-bindings/clock/qcom,gcc-msm8939.h
|
||||
- dt-bindings/reset/qcom,gcc-msm8939.h
|
||||
- dt-bindings/clock/qcom,gcc-msm8660.h
|
||||
- dt-bindings/reset/qcom,gcc-msm8660.h
|
||||
- dt-bindings/clock/qcom,gcc-msm8974.h
|
||||
@@ -41,6 +43,7 @@ properties:
|
||||
- qcom,gcc-ipq8064
|
||||
- qcom,gcc-msm8660
|
||||
- qcom,gcc-msm8916
|
||||
- qcom,gcc-msm8939
|
||||
- qcom,gcc-msm8960
|
||||
- qcom,gcc-msm8974
|
||||
- qcom,gcc-msm8974pro
|
||||
|
||||
@@ -67,6 +67,10 @@ properties:
|
||||
description:
|
||||
Protected clock specifier list as per common clock binding
|
||||
|
||||
vdd-gfx-supply:
|
||||
description:
|
||||
Regulator supply for the GPU_GX GDSC
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
Binding for Silicon Labs Si5341 and Si5340 programmable i2c clock generator.
|
||||
Binding for Silicon Labs Si5340, Si5341 Si5342, Si5344 and Si5345 programmable
|
||||
i2c clock generator.
|
||||
|
||||
Reference
|
||||
[1] Si5341 Data Sheet
|
||||
https://www.silabs.com/documents/public/data-sheets/Si5341-40-D-DataSheet.pdf
|
||||
[2] Si5341 Reference Manual
|
||||
https://www.silabs.com/documents/public/reference-manuals/Si5341-40-D-RM.pdf
|
||||
[3] Si5345 Reference Manual
|
||||
https://www.silabs.com/documents/public/reference-manuals/Si5345-44-42-D-RM.pdf
|
||||
|
||||
The Si5341 and Si5340 are programmable i2c clock generators with up to 10 output
|
||||
clocks. The chip contains a PLL that sources 5 (or 4) multisynth clocks, which
|
||||
in turn can be directed to any of the 10 (or 4) outputs through a divider.
|
||||
The internal structure of the clock generators can be found in [2].
|
||||
The Si5345 is similar to the Si5341 with the addition of fractional input
|
||||
dividers and automatic input selection, as described in [3].
|
||||
The Si5342 and Si5344 are smaller versions of the Si5345, with 2 or 4 outputs.
|
||||
|
||||
The driver can be used in "as is" mode, reading the current settings from the
|
||||
chip at boot, in case you have a (pre-)programmed device. If the PLL is not
|
||||
@@ -28,6 +34,9 @@ Required properties:
|
||||
- compatible: shall be one of the following:
|
||||
"silabs,si5340" - Si5340 A/B/C/D
|
||||
"silabs,si5341" - Si5341 A/B/C/D
|
||||
"silabs,si5342" - Si5342 A/B/C/D
|
||||
"silabs,si5344" - Si5344 A/B/C/D
|
||||
"silabs,si5345" - Si5345 A/B/C/D
|
||||
- reg: i2c device address, usually 0x74
|
||||
- #clock-cells: from common clock binding; shall be set to 2.
|
||||
The first value is "0" for outputs, "1" for synthesizers.
|
||||
|
||||
@@ -124,6 +124,8 @@ config MACH_MMP2_DT
|
||||
select PINCTRL_SINGLE
|
||||
select ARCH_HAS_RESET_CONTROLLER
|
||||
select CPU_PJ4
|
||||
select PM_GENERIC_DOMAINS if PM
|
||||
select PM_GENERIC_DOMAINS_OF if PM && OF
|
||||
help
|
||||
Include support for Marvell MMP2 based platforms using
|
||||
the device tree.
|
||||
|
||||
@@ -341,6 +341,12 @@ config COMMON_CLK_MMP2
|
||||
help
|
||||
Support for Marvell MMP2 and MMP3 SoC clocks
|
||||
|
||||
config COMMON_CLK_MMP2_AUDIO
|
||||
tristate "Clock driver for MMP2 Audio subsystem"
|
||||
depends on COMMON_CLK_MMP2 || COMPILE_TEST
|
||||
help
|
||||
This driver supports clocks for Audio subsystem on MMP2 SoC.
|
||||
|
||||
config COMMON_CLK_BD718XX
|
||||
tristate "Clock driver for 32K clk gates on ROHM PMICs"
|
||||
depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 || MFD_ROHM_BD71828
|
||||
@@ -375,6 +381,7 @@ source "drivers/clk/sunxi-ng/Kconfig"
|
||||
source "drivers/clk/tegra/Kconfig"
|
||||
source "drivers/clk/ti/Kconfig"
|
||||
source "drivers/clk/uniphier/Kconfig"
|
||||
source "drivers/clk/x86/Kconfig"
|
||||
source "drivers/clk/zynqmp/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Driver for Silicon Labs Si5341/Si5340 Clock generator
|
||||
* Driver for Silicon Labs Si5340, Si5341, Si5342, Si5344 and Si5345
|
||||
* Copyright (C) 2019 Topic Embedded Products
|
||||
* Author: Mike Looijmans <mike.looijmans@topic.nl>
|
||||
*
|
||||
* The Si5341 has 10 outputs and 5 synthesizers.
|
||||
* The Si5340 is a smaller version of the Si5341 with only 4 outputs.
|
||||
* The Si5345 is similar to the Si5341, with the addition of fractional input
|
||||
* dividers and automatic input selection.
|
||||
* The Si5342 and Si5344 are smaller versions of the Si5345.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
@@ -18,11 +24,17 @@
|
||||
|
||||
#define SI5341_NUM_INPUTS 4
|
||||
|
||||
#define SI5341_MAX_NUM_OUTPUTS 10
|
||||
#define SI5340_MAX_NUM_OUTPUTS 4
|
||||
#define SI5341_MAX_NUM_OUTPUTS 10
|
||||
#define SI5342_MAX_NUM_OUTPUTS 2
|
||||
#define SI5344_MAX_NUM_OUTPUTS 4
|
||||
#define SI5345_MAX_NUM_OUTPUTS 10
|
||||
|
||||
#define SI5341_NUM_SYNTH 5
|
||||
#define SI5340_NUM_SYNTH 4
|
||||
#define SI5341_NUM_SYNTH 5
|
||||
#define SI5342_NUM_SYNTH 2
|
||||
#define SI5344_NUM_SYNTH 4
|
||||
#define SI5345_NUM_SYNTH 5
|
||||
|
||||
/* Range of the synthesizer fractional divider */
|
||||
#define SI5341_SYNTH_N_MIN 10
|
||||
@@ -65,6 +77,7 @@ struct clk_si5341 {
|
||||
u64 freq_vco; /* 13500–14256 MHz */
|
||||
u8 num_outputs;
|
||||
u8 num_synth;
|
||||
u16 chip_id;
|
||||
};
|
||||
#define to_clk_si5341(_hw) container_of(_hw, struct clk_si5341, hw)
|
||||
|
||||
@@ -142,6 +155,7 @@ static const char * const si5341_input_clock_names[] = {
|
||||
};
|
||||
|
||||
/* Output configuration registers 0..9 are not quite logically organized */
|
||||
/* Also for si5345 */
|
||||
static const u16 si5341_reg_output_offset[] = {
|
||||
0x0108,
|
||||
0x010D,
|
||||
@@ -155,6 +169,7 @@ static const u16 si5341_reg_output_offset[] = {
|
||||
0x013A,
|
||||
};
|
||||
|
||||
/* for si5340, si5342 and si5344 */
|
||||
static const u16 si5340_reg_output_offset[] = {
|
||||
0x0112,
|
||||
0x0117,
|
||||
@@ -974,12 +989,32 @@ static int si5341_probe_chip_id(struct clk_si5341 *data)
|
||||
data->reg_output_offset = si5341_reg_output_offset;
|
||||
data->reg_rdiv_offset = si5341_reg_rdiv_offset;
|
||||
break;
|
||||
case 0x5342:
|
||||
data->num_outputs = SI5342_MAX_NUM_OUTPUTS;
|
||||
data->num_synth = SI5342_NUM_SYNTH;
|
||||
data->reg_output_offset = si5340_reg_output_offset;
|
||||
data->reg_rdiv_offset = si5340_reg_rdiv_offset;
|
||||
break;
|
||||
case 0x5344:
|
||||
data->num_outputs = SI5344_MAX_NUM_OUTPUTS;
|
||||
data->num_synth = SI5344_NUM_SYNTH;
|
||||
data->reg_output_offset = si5340_reg_output_offset;
|
||||
data->reg_rdiv_offset = si5340_reg_rdiv_offset;
|
||||
break;
|
||||
case 0x5345:
|
||||
data->num_outputs = SI5345_MAX_NUM_OUTPUTS;
|
||||
data->num_synth = SI5345_NUM_SYNTH;
|
||||
data->reg_output_offset = si5341_reg_output_offset;
|
||||
data->reg_rdiv_offset = si5341_reg_rdiv_offset;
|
||||
break;
|
||||
default:
|
||||
dev_err(&data->i2c_client->dev, "Model '%x' not supported\n",
|
||||
model);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data->chip_id = model;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1054,6 +1089,11 @@ static const struct si5341_reg_default si5341_preamble[] = {
|
||||
{ 0x0B4E, 0x1A },
|
||||
};
|
||||
|
||||
static const struct si5341_reg_default si5345_preamble[] = {
|
||||
{ 0x0B25, 0x00 },
|
||||
{ 0x0540, 0x01 },
|
||||
};
|
||||
|
||||
static int si5341_send_preamble(struct clk_si5341 *data)
|
||||
{
|
||||
int res;
|
||||
@@ -1068,8 +1108,14 @@ static int si5341_send_preamble(struct clk_si5341 *data)
|
||||
res = regmap_write(data->regmap, 0xB24, revision < 2 ? 0xD8 : 0xC0);
|
||||
if (res < 0)
|
||||
return res;
|
||||
res = si5341_write_multiple(data,
|
||||
si5341_preamble, ARRAY_SIZE(si5341_preamble));
|
||||
|
||||
/* The si5342..si5345 require a different preamble */
|
||||
if (data->chip_id > 0x5341)
|
||||
res = si5341_write_multiple(data,
|
||||
si5345_preamble, ARRAY_SIZE(si5345_preamble));
|
||||
else
|
||||
res = si5341_write_multiple(data,
|
||||
si5341_preamble, ARRAY_SIZE(si5341_preamble));
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
@@ -1095,6 +1141,13 @@ static int si5341_finalize_defaults(struct clk_si5341 *data)
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
/* The si5342..si5345 have an additional post-amble */
|
||||
if (data->chip_id > 0x5341) {
|
||||
res = regmap_write(data->regmap, 0x540, 0x0);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Datasheet does not explain these nameless registers */
|
||||
res = regmap_write(data->regmap, 0xB24, revision < 2 ? 0xDB : 0xC3);
|
||||
if (res < 0)
|
||||
@@ -1499,6 +1552,9 @@ static int si5341_probe(struct i2c_client *client,
|
||||
static const struct i2c_device_id si5341_id[] = {
|
||||
{ "si5340", 0 },
|
||||
{ "si5341", 1 },
|
||||
{ "si5342", 2 },
|
||||
{ "si5344", 4 },
|
||||
{ "si5345", 5 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, si5341_id);
|
||||
@@ -1506,6 +1562,9 @@ MODULE_DEVICE_TABLE(i2c, si5341_id);
|
||||
static const struct of_device_id clk_si5341_of_match[] = {
|
||||
{ .compatible = "silabs,si5340" },
|
||||
{ .compatible = "silabs,si5341" },
|
||||
{ .compatible = "silabs,si5342" },
|
||||
{ .compatible = "silabs,si5344" },
|
||||
{ .compatible = "silabs,si5345" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, clk_si5341_of_match);
|
||||
|
||||
@@ -55,6 +55,16 @@ config INGENIC_CGU_X1000
|
||||
|
||||
If building for a X1000 SoC, you want to say Y here.
|
||||
|
||||
config INGENIC_CGU_X1830
|
||||
bool "Ingenic X1830 CGU driver"
|
||||
default MACH_X1830
|
||||
select INGENIC_CGU_COMMON
|
||||
help
|
||||
Support the clocks provided by the CGU hardware on Ingenic X1830
|
||||
and compatible SoCs.
|
||||
|
||||
If building for a X1830 SoC, you want to say Y here.
|
||||
|
||||
config INGENIC_TCU_CLK
|
||||
bool "Ingenic JZ47xx TCU clocks driver"
|
||||
default MACH_INGENIC
|
||||
|
||||
@@ -5,4 +5,5 @@ obj-$(CONFIG_INGENIC_CGU_JZ4725B) += jz4725b-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_JZ4770) += jz4770-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_JZ4780) += jz4780-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_X1000) += x1000-cgu.o
|
||||
obj-$(CONFIG_INGENIC_CGU_X1830) += x1830-cgu.o
|
||||
obj-$(CONFIG_INGENIC_TCU_CLK) += tcu.o
|
||||
|
||||
+14
-14
@@ -76,16 +76,13 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
const struct ingenic_cgu_pll_info *pll_info;
|
||||
unsigned m, n, od_enc, od;
|
||||
bool bypass;
|
||||
unsigned long flags;
|
||||
u32 ctl;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
BUG_ON(clk_info->type != CGU_CLK_PLL);
|
||||
pll_info = &clk_info->pll;
|
||||
|
||||
spin_lock_irqsave(&cgu->lock, flags);
|
||||
ctl = readl(cgu->base + pll_info->reg);
|
||||
spin_unlock_irqrestore(&cgu->lock, flags);
|
||||
|
||||
m = (ctl >> pll_info->m_shift) & GENMASK(pll_info->m_bits - 1, 0);
|
||||
m += pll_info->m_offset;
|
||||
@@ -93,6 +90,9 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
n += pll_info->n_offset;
|
||||
od_enc = ctl >> pll_info->od_shift;
|
||||
od_enc &= GENMASK(pll_info->od_bits - 1, 0);
|
||||
|
||||
ctl = readl(cgu->base + pll_info->bypass_reg);
|
||||
|
||||
bypass = !pll_info->no_bypass_bit &&
|
||||
!!(ctl & BIT(pll_info->bypass_bit));
|
||||
|
||||
@@ -106,7 +106,8 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
BUG_ON(od == pll_info->od_max);
|
||||
od++;
|
||||
|
||||
return div_u64((u64)parent_rate * m, n * od);
|
||||
return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
|
||||
n * od);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
@@ -139,7 +140,8 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
|
||||
if (pod)
|
||||
*pod = od;
|
||||
|
||||
return div_u64((u64)parent_rate * m, n * od);
|
||||
return div_u64((u64)parent_rate * m * pll_info->rate_multiplier,
|
||||
n * od);
|
||||
}
|
||||
|
||||
static inline const struct ingenic_cgu_clk_info *to_clk_info(
|
||||
@@ -212,9 +214,14 @@ static int ingenic_pll_enable(struct clk_hw *hw)
|
||||
u32 ctl;
|
||||
|
||||
spin_lock_irqsave(&cgu->lock, flags);
|
||||
ctl = readl(cgu->base + pll_info->reg);
|
||||
ctl = readl(cgu->base + pll_info->bypass_reg);
|
||||
|
||||
ctl &= ~BIT(pll_info->bypass_bit);
|
||||
|
||||
writel(ctl, cgu->base + pll_info->bypass_reg);
|
||||
|
||||
ctl = readl(cgu->base + pll_info->reg);
|
||||
|
||||
ctl |= BIT(pll_info->enable_bit);
|
||||
|
||||
writel(ctl, cgu->base + pll_info->reg);
|
||||
@@ -259,12 +266,9 @@ static int ingenic_pll_is_enabled(struct clk_hw *hw)
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
|
||||
unsigned long flags;
|
||||
u32 ctl;
|
||||
|
||||
spin_lock_irqsave(&cgu->lock, flags);
|
||||
ctl = readl(cgu->base + pll_info->reg);
|
||||
spin_unlock_irqrestore(&cgu->lock, flags);
|
||||
|
||||
return !!(ctl & BIT(pll_info->enable_bit));
|
||||
}
|
||||
@@ -562,16 +566,12 @@ static int ingenic_clk_is_enabled(struct clk_hw *hw)
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
unsigned long flags;
|
||||
int enabled = 1;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
|
||||
if (clk_info->type & CGU_CLK_GATE) {
|
||||
spin_lock_irqsave(&cgu->lock, flags);
|
||||
if (clk_info->type & CGU_CLK_GATE)
|
||||
enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);
|
||||
spin_unlock_irqrestore(&cgu->lock, flags);
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
/**
|
||||
* struct ingenic_cgu_pll_info - information about a PLL
|
||||
* @reg: the offset of the PLL's control register within the CGU
|
||||
* @rate_multiplier: the multiplier needed by pll rate calculation
|
||||
* @m_shift: the number of bits to shift the multiplier value by (ie. the
|
||||
* index of the lowest bit of the multiplier value in the PLL's
|
||||
* control register)
|
||||
@@ -37,6 +38,7 @@
|
||||
* @od_encoding: a pointer to an array mapping post-VCO divider values to
|
||||
* their encoded values in the PLL control register, or -1 for
|
||||
* unsupported values
|
||||
* @bypass_reg: the offset of the bypass control register within the CGU
|
||||
* @bypass_bit: the index of the bypass bit in the PLL control register
|
||||
* @enable_bit: the index of the enable bit in the PLL control register
|
||||
* @stable_bit: the index of the stable bit in the PLL control register
|
||||
@@ -44,10 +46,12 @@
|
||||
*/
|
||||
struct ingenic_cgu_pll_info {
|
||||
unsigned reg;
|
||||
unsigned rate_multiplier;
|
||||
const s8 *od_encoding;
|
||||
u8 m_shift, m_bits, m_offset;
|
||||
u8 n_shift, n_bits, n_offset;
|
||||
u8 od_shift, od_bits, od_max;
|
||||
unsigned bypass_reg;
|
||||
u8 bypass_bit;
|
||||
u8 enable_bit;
|
||||
u8 stable_bit;
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <dt-bindings/clock/jz4725b-cgu.h>
|
||||
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
@@ -54,6 +56,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
|
||||
.parents = { JZ4725B_CLK_EXT, -1, -1, -1 },
|
||||
.pll = {
|
||||
.reg = CGU_REG_CPPCR,
|
||||
.rate_multiplier = 1,
|
||||
.m_shift = 23,
|
||||
.m_bits = 9,
|
||||
.m_offset = 2,
|
||||
@@ -65,6 +68,7 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
|
||||
.od_max = 4,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.stable_bit = 10,
|
||||
.bypass_reg = CGU_REG_CPPCR,
|
||||
.bypass_bit = 9,
|
||||
.enable_bit = 8,
|
||||
},
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <dt-bindings/clock/jz4740-cgu.h>
|
||||
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
@@ -69,6 +71,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
|
||||
.parents = { JZ4740_CLK_EXT, -1, -1, -1 },
|
||||
.pll = {
|
||||
.reg = CGU_REG_CPPCR,
|
||||
.rate_multiplier = 1,
|
||||
.m_shift = 23,
|
||||
.m_bits = 9,
|
||||
.m_offset = 2,
|
||||
@@ -80,6 +83,7 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
|
||||
.od_max = 4,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.stable_bit = 10,
|
||||
.bypass_reg = CGU_REG_CPPCR,
|
||||
.bypass_bit = 9,
|
||||
.enable_bit = 8,
|
||||
},
|
||||
|
||||
@@ -9,7 +9,9 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <dt-bindings/clock/jz4770-cgu.h>
|
||||
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
@@ -102,6 +104,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
.parents = { JZ4770_CLK_EXT },
|
||||
.pll = {
|
||||
.reg = CGU_REG_CPPCR0,
|
||||
.rate_multiplier = 1,
|
||||
.m_shift = 24,
|
||||
.m_bits = 7,
|
||||
.m_offset = 1,
|
||||
@@ -112,6 +115,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
.od_bits = 2,
|
||||
.od_max = 8,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_reg = CGU_REG_CPPCR0,
|
||||
.bypass_bit = 9,
|
||||
.enable_bit = 8,
|
||||
.stable_bit = 10,
|
||||
@@ -124,6 +128,7 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
.parents = { JZ4770_CLK_EXT },
|
||||
.pll = {
|
||||
.reg = CGU_REG_CPPCR1,
|
||||
.rate_multiplier = 1,
|
||||
.m_shift = 24,
|
||||
.m_bits = 7,
|
||||
.m_offset = 1,
|
||||
@@ -134,9 +139,10 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
||||
.od_bits = 2,
|
||||
.od_max = 8,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_reg = CGU_REG_CPPCR1,
|
||||
.no_bypass_bit = true,
|
||||
.enable_bit = 7,
|
||||
.stable_bit = 6,
|
||||
.no_bypass_bit = true,
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <dt-bindings/clock/jz4780-cgu.h>
|
||||
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
@@ -266,6 +267,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
|
||||
|
||||
#define DEF_PLL(name) { \
|
||||
.reg = CGU_REG_ ## name, \
|
||||
.rate_multiplier = 1, \
|
||||
.m_shift = 19, \
|
||||
.m_bits = 13, \
|
||||
.m_offset = 1, \
|
||||
@@ -277,6 +279,7 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
|
||||
.od_max = 16, \
|
||||
.od_encoding = pll_od_encoding, \
|
||||
.stable_bit = 6, \
|
||||
.bypass_reg = CGU_REG_ ## name, \
|
||||
.bypass_bit = 1, \
|
||||
.enable_bit = 0, \
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ static const struct ingenic_soc_info x1000_soc_info = {
|
||||
.has_tcu_clk = false,
|
||||
};
|
||||
|
||||
static const struct of_device_id ingenic_tcu_of_match[] __initconst = {
|
||||
static const struct of_device_id __maybe_unused ingenic_tcu_of_match[] __initconst = {
|
||||
{ .compatible = "ingenic,jz4740-tcu", .data = &jz4740_soc_info, },
|
||||
{ .compatible = "ingenic,jz4725b-tcu", .data = &jz4725b_soc_info, },
|
||||
{ .compatible = "ingenic,jz4770-tcu", .data = &jz4770_soc_info, },
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user