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:
commit
5debcd01e2
44
Documentation/devicetree/bindings/clock/intel,cgu-lgm.yaml
Normal file
44
Documentation/devicetree/bindings/clock/intel,cgu-lgm.yaml
Normal file
@ -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>;
|
||||
};
|
||||
|
40
Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
Normal file
40
Documentation/devicetree/bindings/clock/qcom,a53pll.yaml
Normal file
@ -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
|
||||
|
@ -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, },
|
||||
|
@ -1,13 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* X1000 SoC CGU driver
|
||||
* Copyright (c) 2019 Zhou Yanjie <zhouyanjie@zoho.com>
|
||||
* Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <dt-bindings/clock/x1000-cgu.h>
|
||||
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
@ -18,6 +21,9 @@
|
||||
#define CGU_REG_CLKGR 0x20
|
||||
#define CGU_REG_OPCR 0x24
|
||||
#define CGU_REG_DDRCDR 0x2c
|
||||
#define CGU_REG_USBPCR 0x3c
|
||||
#define CGU_REG_USBPCR1 0x48
|
||||
#define CGU_REG_USBCDR 0x50
|
||||
#define CGU_REG_MACCDR 0x54
|
||||
#define CGU_REG_I2SCDR 0x60
|
||||
#define CGU_REG_LPCDR 0x64
|
||||
@ -38,8 +44,47 @@
|
||||
#define OPCR_SPENDN0 BIT(7)
|
||||
#define OPCR_SPENDN1 BIT(6)
|
||||
|
||||
/* bits within the USBPCR register */
|
||||
#define USBPCR_SIDDQ BIT(21)
|
||||
#define USBPCR_OTG_DISABLE BIT(20)
|
||||
|
||||
static struct ingenic_cgu *cgu;
|
||||
|
||||
static int x1000_usb_phy_enable(struct clk_hw *hw)
|
||||
{
|
||||
void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
|
||||
void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
|
||||
|
||||
writel(readl(reg_opcr) | OPCR_SPENDN0, reg_opcr);
|
||||
writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void x1000_usb_phy_disable(struct clk_hw *hw)
|
||||
{
|
||||
void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
|
||||
void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
|
||||
|
||||
writel(readl(reg_opcr) & ~OPCR_SPENDN0, reg_opcr);
|
||||
writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
|
||||
}
|
||||
|
||||
static int x1000_usb_phy_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
|
||||
void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
|
||||
|
||||
return (readl(reg_opcr) & OPCR_SPENDN0) &&
|
||||
!(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
|
||||
!(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
|
||||
}
|
||||
|
||||
static const struct clk_ops x1000_otg_phy_ops = {
|
||||
.enable = x1000_usb_phy_enable,
|
||||
.disable = x1000_usb_phy_disable,
|
||||
.is_enabled = x1000_usb_phy_is_enabled,
|
||||
};
|
||||
|
||||
static const s8 pll_od_encoding[8] = {
|
||||
0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
|
||||
};
|
||||
@ -58,6 +103,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
||||
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
|
||||
.pll = {
|
||||
.reg = CGU_REG_APLL,
|
||||
.rate_multiplier = 1,
|
||||
.m_shift = 24,
|
||||
.m_bits = 7,
|
||||
.m_offset = 1,
|
||||
@ -68,6 +114,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
||||
.od_bits = 2,
|
||||
.od_max = 8,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_reg = CGU_REG_APLL,
|
||||
.bypass_bit = 9,
|
||||
.enable_bit = 8,
|
||||
.stable_bit = 10,
|
||||
@ -79,6 +126,7 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
||||
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
|
||||
.pll = {
|
||||
.reg = CGU_REG_MPLL,
|
||||
.rate_multiplier = 1,
|
||||
.m_shift = 24,
|
||||
.m_bits = 7,
|
||||
.m_offset = 1,
|
||||
@ -89,12 +137,22 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
||||
.od_bits = 2,
|
||||
.od_max = 8,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_reg = CGU_REG_MPLL,
|
||||
.bypass_bit = 6,
|
||||
.enable_bit = 7,
|
||||
.stable_bit = 0,
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
/* Custom (SoC-specific) OTG PHY */
|
||||
|
||||
[X1000_CLK_OTGPHY] = {
|
||||
"otg_phy", CGU_CLK_CUSTOM,
|
||||
.parents = { -1, -1, X1000_CLK_EXCLK, -1 },
|
||||
.custom = { &x1000_otg_phy_ops },
|
||||
},
|
||||
|
||||
/* Muxes & dividers */
|
||||
|
||||
[X1000_CLK_SCLKA] = {
|
||||
@ -110,9 +168,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
||||
},
|
||||
|
||||
[X1000_CLK_CPU] = {
|
||||
"cpu", CGU_CLK_DIV,
|
||||
"cpu", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_CPUMUX, -1, -1, -1 },
|
||||
.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR, 30 },
|
||||
},
|
||||
|
||||
[X1000_CLK_L2CACHE] = {
|
||||
@ -141,9 +200,10 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
||||
},
|
||||
|
||||
[X1000_CLK_PCLK] = {
|
||||
"pclk", CGU_CLK_DIV,
|
||||
"pclk", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_AHB2PMUX, -1, -1, -1 },
|
||||
.div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR, 28 },
|
||||
},
|
||||
|
||||
[X1000_CLK_DDR] = {
|
||||
@ -156,12 +216,20 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
||||
|
||||
[X1000_CLK_MAC] = {
|
||||
"mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
|
||||
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
|
||||
.mux = { CGU_REG_MACCDR, 31, 1 },
|
||||
.div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
|
||||
.gate = { CGU_REG_CLKGR, 25 },
|
||||
},
|
||||
|
||||
[X1000_CLK_LCD] = {
|
||||
"lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL },
|
||||
.mux = { CGU_REG_LPCDR, 31, 1 },
|
||||
.div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
|
||||
.gate = { CGU_REG_CLKGR, 23 },
|
||||
},
|
||||
|
||||
[X1000_CLK_MSCMUX] = {
|
||||
"msc_mux", CGU_CLK_MUX,
|
||||
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL},
|
||||
@ -182,6 +250,15 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
||||
.gate = { CGU_REG_CLKGR, 5 },
|
||||
},
|
||||
|
||||
[X1000_CLK_OTG] = {
|
||||
"otg", CGU_CLK_DIV | CGU_CLK_GATE | CGU_CLK_MUX,
|
||||
.parents = { X1000_CLK_EXCLK, -1,
|
||||
X1000_CLK_APLL, X1000_CLK_MPLL },
|
||||
.mux = { CGU_REG_USBCDR, 30, 2 },
|
||||
.div = { CGU_REG_USBCDR, 0, 1, 8, 29, 28, 27 },
|
||||
.gate = { CGU_REG_CLKGR, 3 },
|
||||
},
|
||||
|
||||
[X1000_CLK_SSIPLL] = {
|
||||
"ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
|
||||
.parents = { X1000_CLK_SCLKA, X1000_CLK_MPLL, -1, -1 },
|
||||
@ -189,14 +266,32 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
||||
.div = { CGU_REG_SSICDR, 0, 1, 8, 29, 28, 27 },
|
||||
},
|
||||
|
||||
[X1000_CLK_SSIPLL_DIV2] = {
|
||||
"ssi_pll_div2", CGU_CLK_FIXDIV,
|
||||
.parents = { X1000_CLK_SSIPLL },
|
||||
.fixdiv = { 2 },
|
||||
},
|
||||
|
||||
[X1000_CLK_SSIMUX] = {
|
||||
"ssi_mux", CGU_CLK_MUX,
|
||||
.parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL, -1, -1 },
|
||||
.parents = { X1000_CLK_EXCLK, X1000_CLK_SSIPLL_DIV2, -1, -1 },
|
||||
.mux = { CGU_REG_SSICDR, 30, 1 },
|
||||
},
|
||||
|
||||
/* Gate-only clocks */
|
||||
|
||||
[X1000_CLK_EMC] = {
|
||||
"emc", CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_AHB2, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR, 0 },
|
||||
},
|
||||
|
||||
[X1000_CLK_EFUSE] = {
|
||||
"efuse", CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_AHB2, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR, 1 },
|
||||
},
|
||||
|
||||
[X1000_CLK_SFC] = {
|
||||
"sfc", CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_SSIPLL, -1, -1, -1 },
|
||||
@ -239,12 +334,24 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
||||
.gate = { CGU_REG_CLKGR, 16 },
|
||||
},
|
||||
|
||||
[X1000_CLK_TCU] = {
|
||||
"tcu", CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR, 18 },
|
||||
},
|
||||
|
||||
[X1000_CLK_SSI] = {
|
||||
"ssi", CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_SSIMUX, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR, 19 },
|
||||
},
|
||||
|
||||
[X1000_CLK_OST] = {
|
||||
"ost", CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR, 20 },
|
||||
},
|
||||
|
||||
[X1000_CLK_PDMA] = {
|
||||
"pdma", CGU_CLK_GATE,
|
||||
.parents = { X1000_CLK_EXCLK, -1, -1, -1 },
|
||||
@ -271,4 +378,8 @@ static void __init x1000_cgu_init(struct device_node *np)
|
||||
|
||||
ingenic_cgu_register_syscore_ops(cgu);
|
||||
}
|
||||
CLK_OF_DECLARE(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init);
|
||||
/*
|
||||
* CGU has some children devices, this is useful for probing children devices
|
||||
* in the case where the device node is compatible with "simple-mfd".
|
||||
*/
|
||||
CLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-cgu", x1000_cgu_init);
|
||||
|
448
drivers/clk/ingenic/x1830-cgu.c
Normal file
448
drivers/clk/ingenic/x1830-cgu.c
Normal file
@ -0,0 +1,448 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* X1830 SoC CGU driver
|
||||
* Copyright (c) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <dt-bindings/clock/x1830-cgu.h>
|
||||
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
/* CGU register offsets */
|
||||
#define CGU_REG_CPCCR 0x00
|
||||
#define CGU_REG_CPPCR 0x0c
|
||||
#define CGU_REG_APLL 0x10
|
||||
#define CGU_REG_MPLL 0x14
|
||||
#define CGU_REG_CLKGR0 0x20
|
||||
#define CGU_REG_OPCR 0x24
|
||||
#define CGU_REG_CLKGR1 0x28
|
||||
#define CGU_REG_DDRCDR 0x2c
|
||||
#define CGU_REG_USBPCR 0x3c
|
||||
#define CGU_REG_USBRDT 0x40
|
||||
#define CGU_REG_USBVBFIL 0x44
|
||||
#define CGU_REG_USBPCR1 0x48
|
||||
#define CGU_REG_MACCDR 0x54
|
||||
#define CGU_REG_EPLL 0x58
|
||||
#define CGU_REG_I2SCDR 0x60
|
||||
#define CGU_REG_LPCDR 0x64
|
||||
#define CGU_REG_MSC0CDR 0x68
|
||||
#define CGU_REG_I2SCDR1 0x70
|
||||
#define CGU_REG_SSICDR 0x74
|
||||
#define CGU_REG_CIMCDR 0x7c
|
||||
#define CGU_REG_MSC1CDR 0xa4
|
||||
#define CGU_REG_CMP_INTR 0xb0
|
||||
#define CGU_REG_CMP_INTRE 0xb4
|
||||
#define CGU_REG_DRCG 0xd0
|
||||
#define CGU_REG_CPCSR 0xd4
|
||||
#define CGU_REG_VPLL 0xe0
|
||||
#define CGU_REG_MACPHYC 0xe8
|
||||
|
||||
/* bits within the OPCR register */
|
||||
#define OPCR_GATE_USBPHYCLK BIT(23)
|
||||
#define OPCR_SPENDN0 BIT(7)
|
||||
#define OPCR_SPENDN1 BIT(6)
|
||||
|
||||
/* bits within the USBPCR register */
|
||||
#define USBPCR_SIDDQ BIT(21)
|
||||
#define USBPCR_OTG_DISABLE BIT(20)
|
||||
|
||||
static struct ingenic_cgu *cgu;
|
||||
|
||||
static int x1830_usb_phy_enable(struct clk_hw *hw)
|
||||
{
|
||||
void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
|
||||
void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
|
||||
|
||||
writel((readl(reg_opcr) | OPCR_SPENDN0) & ~OPCR_GATE_USBPHYCLK, reg_opcr);
|
||||
writel(readl(reg_usbpcr) & ~USBPCR_OTG_DISABLE & ~USBPCR_SIDDQ, reg_usbpcr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void x1830_usb_phy_disable(struct clk_hw *hw)
|
||||
{
|
||||
void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
|
||||
void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
|
||||
|
||||
writel((readl(reg_opcr) & ~OPCR_SPENDN0) | OPCR_GATE_USBPHYCLK, reg_opcr);
|
||||
writel(readl(reg_usbpcr) | USBPCR_OTG_DISABLE | USBPCR_SIDDQ, reg_usbpcr);
|
||||
}
|
||||
|
||||
static int x1830_usb_phy_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
void __iomem *reg_opcr = cgu->base + CGU_REG_OPCR;
|
||||
void __iomem *reg_usbpcr = cgu->base + CGU_REG_USBPCR;
|
||||
|
||||
return (readl(reg_opcr) & OPCR_SPENDN0) &&
|
||||
!(readl(reg_usbpcr) & USBPCR_SIDDQ) &&
|
||||
!(readl(reg_usbpcr) & USBPCR_OTG_DISABLE);
|
||||
}
|
||||
|
||||
static const struct clk_ops x1830_otg_phy_ops = {
|
||||
.enable = x1830_usb_phy_enable,
|
||||
.disable = x1830_usb_phy_disable,
|
||||
.is_enabled = x1830_usb_phy_is_enabled,
|
||||
};
|
||||
|
||||
static const s8 pll_od_encoding[64] = {
|
||||
0x0, 0x1, -1, 0x2, -1, -1, -1, 0x3,
|
||||
-1, -1, -1, -1, -1, -1, -1, 0x4,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, 0x5,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, 0x6,
|
||||
};
|
||||
|
||||
static const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = {
|
||||
|
||||
/* External clocks */
|
||||
|
||||
[X1830_CLK_EXCLK] = { "ext", CGU_CLK_EXT },
|
||||
[X1830_CLK_RTCLK] = { "rtc", CGU_CLK_EXT },
|
||||
|
||||
/* PLLs */
|
||||
|
||||
[X1830_CLK_APLL] = {
|
||||
"apll", CGU_CLK_PLL,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.pll = {
|
||||
.reg = CGU_REG_APLL,
|
||||
.rate_multiplier = 2,
|
||||
.m_shift = 20,
|
||||
.m_bits = 9,
|
||||
.m_offset = 1,
|
||||
.n_shift = 14,
|
||||
.n_bits = 6,
|
||||
.n_offset = 1,
|
||||
.od_shift = 11,
|
||||
.od_bits = 3,
|
||||
.od_max = 64,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_reg = CGU_REG_CPPCR,
|
||||
.bypass_bit = 30,
|
||||
.enable_bit = 0,
|
||||
.stable_bit = 3,
|
||||
},
|
||||
},
|
||||
|
||||
[X1830_CLK_MPLL] = {
|
||||
"mpll", CGU_CLK_PLL,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.pll = {
|
||||
.reg = CGU_REG_MPLL,
|
||||
.rate_multiplier = 2,
|
||||
.m_shift = 20,
|
||||
.m_bits = 9,
|
||||
.m_offset = 1,
|
||||
.n_shift = 14,
|
||||
.n_bits = 6,
|
||||
.n_offset = 1,
|
||||
.od_shift = 11,
|
||||
.od_bits = 3,
|
||||
.od_max = 64,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_reg = CGU_REG_CPPCR,
|
||||
.bypass_bit = 28,
|
||||
.enable_bit = 0,
|
||||
.stable_bit = 3,
|
||||
},
|
||||
},
|
||||
|
||||
[X1830_CLK_EPLL] = {
|
||||
"epll", CGU_CLK_PLL,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.pll = {
|
||||
.reg = CGU_REG_EPLL,
|
||||
.rate_multiplier = 2,
|
||||
.m_shift = 20,
|
||||
.m_bits = 9,
|
||||
.m_offset = 1,
|
||||
.n_shift = 14,
|
||||
.n_bits = 6,
|
||||
.n_offset = 1,
|
||||
.od_shift = 11,
|
||||
.od_bits = 3,
|
||||
.od_max = 64,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_reg = CGU_REG_CPPCR,
|
||||
.bypass_bit = 24,
|
||||
.enable_bit = 0,
|
||||
.stable_bit = 3,
|
||||
},
|
||||
},
|
||||
|
||||
[X1830_CLK_VPLL] = {
|
||||
"vpll", CGU_CLK_PLL,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.pll = {
|
||||
.reg = CGU_REG_VPLL,
|
||||
.rate_multiplier = 2,
|
||||
.m_shift = 20,
|
||||
.m_bits = 9,
|
||||
.m_offset = 1,
|
||||
.n_shift = 14,
|
||||
.n_bits = 6,
|
||||
.n_offset = 1,
|
||||
.od_shift = 11,
|
||||
.od_bits = 3,
|
||||
.od_max = 64,
|
||||
.od_encoding = pll_od_encoding,
|
||||
.bypass_reg = CGU_REG_CPPCR,
|
||||
.bypass_bit = 26,
|
||||
.enable_bit = 0,
|
||||
.stable_bit = 3,
|
||||
},
|
||||
},
|
||||
|
||||
/* Custom (SoC-specific) OTG PHY */
|
||||
|
||||
[X1830_CLK_OTGPHY] = {
|
||||
"otg_phy", CGU_CLK_CUSTOM,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.custom = { &x1830_otg_phy_ops },
|
||||
},
|
||||
|
||||
/* Muxes & dividers */
|
||||
|
||||
[X1830_CLK_SCLKA] = {
|
||||
"sclk_a", CGU_CLK_MUX,
|
||||
.parents = { -1, X1830_CLK_EXCLK, X1830_CLK_APLL, -1 },
|
||||
.mux = { CGU_REG_CPCCR, 30, 2 },
|
||||
},
|
||||
|
||||
[X1830_CLK_CPUMUX] = {
|
||||
"cpu_mux", CGU_CLK_MUX,
|
||||
.parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
|
||||
.mux = { CGU_REG_CPCCR, 28, 2 },
|
||||
},
|
||||
|
||||
[X1830_CLK_CPU] = {
|
||||
"cpu", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
|
||||
.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR1, 15 },
|
||||
},
|
||||
|
||||
[X1830_CLK_L2CACHE] = {
|
||||
"l2cache", CGU_CLK_DIV,
|
||||
.parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
|
||||
.div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
|
||||
},
|
||||
|
||||
[X1830_CLK_AHB0] = {
|
||||
"ahb0", CGU_CLK_MUX | CGU_CLK_DIV,
|
||||
.parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
|
||||
.mux = { CGU_REG_CPCCR, 26, 2 },
|
||||
.div = { CGU_REG_CPCCR, 8, 1, 4, 21, -1, -1 },
|
||||
},
|
||||
|
||||
[X1830_CLK_AHB2PMUX] = {
|
||||
"ahb2_apb_mux", CGU_CLK_MUX,
|
||||
.parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
|
||||
.mux = { CGU_REG_CPCCR, 24, 2 },
|
||||
},
|
||||
|
||||
[X1830_CLK_AHB2] = {
|
||||
"ahb2", CGU_CLK_DIV,
|
||||
.parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
|
||||
.div = { CGU_REG_CPCCR, 12, 1, 4, 20, -1, -1 },
|
||||
},
|
||||
|
||||
[X1830_CLK_PCLK] = {
|
||||
"pclk", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_AHB2PMUX, -1, -1, -1 },
|
||||
.div = { CGU_REG_CPCCR, 16, 1, 4, 20, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR1, 14 },
|
||||
},
|
||||
|
||||
[X1830_CLK_DDR] = {
|
||||
"ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
|
||||
.mux = { CGU_REG_DDRCDR, 30, 2 },
|
||||
.div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
|
||||
.gate = { CGU_REG_CLKGR0, 31 },
|
||||
},
|
||||
|
||||
[X1830_CLK_MAC] = {
|
||||
"mac", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
|
||||
X1830_CLK_VPLL, X1830_CLK_EPLL },
|
||||
.mux = { CGU_REG_MACCDR, 30, 2 },
|
||||
.div = { CGU_REG_MACCDR, 0, 1, 8, 29, 28, 27 },
|
||||
.gate = { CGU_REG_CLKGR1, 4 },
|
||||
},
|
||||
|
||||
[X1830_CLK_LCD] = {
|
||||
"lcd", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
|
||||
X1830_CLK_VPLL, X1830_CLK_EPLL },
|
||||
.mux = { CGU_REG_LPCDR, 30, 2 },
|
||||
.div = { CGU_REG_LPCDR, 0, 1, 8, 28, 27, 26 },
|
||||
.gate = { CGU_REG_CLKGR1, 9 },
|
||||
},
|
||||
|
||||
[X1830_CLK_MSCMUX] = {
|
||||
"msc_mux", CGU_CLK_MUX,
|
||||
.parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
|
||||
X1830_CLK_VPLL, X1830_CLK_EPLL },
|
||||
.mux = { CGU_REG_MSC0CDR, 30, 2 },
|
||||
},
|
||||
|
||||
[X1830_CLK_MSC0] = {
|
||||
"msc0", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
|
||||
.div = { CGU_REG_MSC0CDR, 0, 2, 8, 29, 28, 27 },
|
||||
.gate = { CGU_REG_CLKGR0, 4 },
|
||||
},
|
||||
|
||||
[X1830_CLK_MSC1] = {
|
||||
"msc1", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_MSCMUX, -1, -1, -1 },
|
||||
.div = { CGU_REG_MSC1CDR, 0, 2, 8, 29, 28, 27 },
|
||||
.gate = { CGU_REG_CLKGR0, 5 },
|
||||
},
|
||||
|
||||
[X1830_CLK_SSIPLL] = {
|
||||
"ssi_pll", CGU_CLK_MUX | CGU_CLK_DIV,
|
||||
.parents = { X1830_CLK_SCLKA, X1830_CLK_MPLL,
|
||||
X1830_CLK_VPLL, X1830_CLK_EPLL },
|
||||
.mux = { CGU_REG_SSICDR, 30, 2 },
|
||||
.div = { CGU_REG_SSICDR, 0, 1, 8, 28, 27, 26 },
|
||||
},
|
||||
|
||||
[X1830_CLK_SSIPLL_DIV2] = {
|
||||
"ssi_pll_div2", CGU_CLK_FIXDIV,
|
||||
.parents = { X1830_CLK_SSIPLL },
|
||||
.fixdiv = { 2 },
|
||||
},
|
||||
|
||||
[X1830_CLK_SSIMUX] = {
|
||||
"ssi_mux", CGU_CLK_MUX,
|
||||
.parents = { X1830_CLK_EXCLK, X1830_CLK_SSIPLL_DIV2, -1, -1 },
|
||||
.mux = { CGU_REG_SSICDR, 29, 1 },
|
||||
},
|
||||
|
||||
/* Gate-only clocks */
|
||||
|
||||
[X1830_CLK_EMC] = {
|
||||
"emc", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_AHB2, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 0 },
|
||||
},
|
||||
|
||||
[X1830_CLK_EFUSE] = {
|
||||
"efuse", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_AHB2, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 1 },
|
||||
},
|
||||
|
||||
[X1830_CLK_OTG] = {
|
||||
"otg", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 3 },
|
||||
},
|
||||
|
||||
[X1830_CLK_SSI0] = {
|
||||
"ssi0", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 6 },
|
||||
},
|
||||
|
||||
[X1830_CLK_SMB0] = {
|
||||
"smb0", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_PCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 7 },
|
||||
},
|
||||
|
||||
[X1830_CLK_SMB1] = {
|
||||
"smb1", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_PCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 8 },
|
||||
},
|
||||
|
||||
[X1830_CLK_SMB2] = {
|
||||
"smb2", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_PCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 9 },
|
||||
},
|
||||
|
||||
[X1830_CLK_UART0] = {
|
||||
"uart0", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 14 },
|
||||
},
|
||||
|
||||
[X1830_CLK_UART1] = {
|
||||
"uart1", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 15 },
|
||||
},
|
||||
|
||||
[X1830_CLK_SSI1] = {
|
||||
"ssi1", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_SSIMUX, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 19 },
|
||||
},
|
||||
|
||||
[X1830_CLK_SFC] = {
|
||||
"sfc", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_SSIPLL, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 20 },
|
||||
},
|
||||
|
||||
[X1830_CLK_PDMA] = {
|
||||
"pdma", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 21 },
|
||||
},
|
||||
|
||||
[X1830_CLK_TCU] = {
|
||||
"tcu", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR0, 30 },
|
||||
},
|
||||
|
||||
[X1830_CLK_DTRNG] = {
|
||||
"dtrng", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_PCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR1, 1 },
|
||||
},
|
||||
|
||||
[X1830_CLK_OST] = {
|
||||
"ost", CGU_CLK_GATE,
|
||||
.parents = { X1830_CLK_EXCLK, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR1, 11 },
|
||||
},
|
||||
};
|
||||
|
||||
static void __init x1830_cgu_init(struct device_node *np)
|
||||
{
|
||||
int retval;
|
||||
|
||||
cgu = ingenic_cgu_new(x1830_cgu_clocks,
|
||||
ARRAY_SIZE(x1830_cgu_clocks), np);
|
||||
if (!cgu) {
|
||||
pr_err("%s: failed to initialise CGU\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
retval = ingenic_cgu_register_clocks(cgu);
|
||||
if (retval) {
|
||||
pr_err("%s: failed to register CGU Clocks\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ingenic_cgu_register_syscore_ops(cgu);
|
||||
}
|
||||
/*
|
||||
* CGU has some children devices, this is useful for probing children devices
|
||||
* in the case where the device node is compatible with "simple-mfd".
|
||||
*/
|
||||
CLK_OF_DECLARE_DRIVER(x1830_cgu, "ingenic,x1830-cgu", x1830_cgu_init);
|
@ -8,7 +8,8 @@ obj-y += clk-apbc.o clk-apmu.o clk-frac.o clk-mix.o clk-gate.o clk.o
|
||||
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
|
||||
|
||||
obj-$(CONFIG_MACH_MMP_DT) += clk-of-pxa168.o clk-of-pxa910.o
|
||||
obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o
|
||||
obj-$(CONFIG_COMMON_CLK_MMP2) += clk-of-mmp2.o clk-pll.o pwr-island.o
|
||||
obj-$(CONFIG_COMMON_CLK_MMP2_AUDIO) += clk-audio.o
|
||||
|
||||
obj-$(CONFIG_CPU_PXA168) += clk-pxa168.o
|
||||
obj-$(CONFIG_CPU_PXA910) += clk-pxa910.o
|
||||
|
443
drivers/clk/mmp/clk-audio.c
Normal file
443
drivers/clk/mmp/clk-audio.c
Normal file
@ -0,0 +1,443 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* MMP Audio Clock Controller driver
|
||||
*
|
||||
* Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_clock.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/slab.h>
|
||||
#include <dt-bindings/clock/marvell,mmp2-audio.h>
|
||||
|
||||
/* Audio Controller Registers */
|
||||
#define SSPA_AUD_CTRL 0x04
|
||||
#define SSPA_AUD_PLL_CTRL0 0x08
|
||||
#define SSPA_AUD_PLL_CTRL1 0x0c
|
||||
|
||||
/* SSPA Audio Control Register */
|
||||
#define SSPA_AUD_CTRL_SYSCLK_SHIFT 0
|
||||
#define SSPA_AUD_CTRL_SYSCLK_DIV_SHIFT 1
|
||||
#define SSPA_AUD_CTRL_SSPA0_MUX_SHIFT 7
|
||||
#define SSPA_AUD_CTRL_SSPA0_SHIFT 8
|
||||
#define SSPA_AUD_CTRL_SSPA0_DIV_SHIFT 9
|
||||
#define SSPA_AUD_CTRL_SSPA1_SHIFT 16
|
||||
#define SSPA_AUD_CTRL_SSPA1_DIV_SHIFT 17
|
||||
#define SSPA_AUD_CTRL_SSPA1_MUX_SHIFT 23
|
||||
#define SSPA_AUD_CTRL_DIV_MASK 0x7e
|
||||
|
||||
/* SSPA Audio PLL Control 0 Register */
|
||||
#define SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO_MASK (0x7 << 28)
|
||||
#define SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO(x) ((x) << 28)
|
||||
#define SSPA_AUD_PLL_CTRL0_FRACT_MASK (0xfffff << 8)
|
||||
#define SSPA_AUD_PLL_CTRL0_FRACT(x) ((x) << 8)
|
||||
#define SSPA_AUD_PLL_CTRL0_ENA_DITHER (1 << 7)
|
||||
#define SSPA_AUD_PLL_CTRL0_ICP_2UA (0 << 5)
|
||||
#define SSPA_AUD_PLL_CTRL0_ICP_5UA (1 << 5)
|
||||
#define SSPA_AUD_PLL_CTRL0_ICP_7UA (2 << 5)
|
||||
#define SSPA_AUD_PLL_CTRL0_ICP_10UA (3 << 5)
|
||||
#define SSPA_AUD_PLL_CTRL0_DIV_FBCCLK_MASK (0x3 << 3)
|
||||
#define SSPA_AUD_PLL_CTRL0_DIV_FBCCLK(x) ((x) << 3)
|
||||
#define SSPA_AUD_PLL_CTRL0_DIV_MCLK_MASK (0x1 << 2)
|
||||
#define SSPA_AUD_PLL_CTRL0_DIV_MCLK(x) ((x) << 2)
|
||||
#define SSPA_AUD_PLL_CTRL0_PD_OVPROT_DIS (1 << 1)
|
||||
#define SSPA_AUD_PLL_CTRL0_PU (1 << 0)
|
||||
|
||||
/* SSPA Audio PLL Control 1 Register */
|
||||
#define SSPA_AUD_PLL_CTRL1_SEL_FAST_CLK (1 << 24)
|
||||
#define SSPA_AUD_PLL_CTRL1_CLK_SEL_MASK (1 << 11)
|
||||
#define SSPA_AUD_PLL_CTRL1_CLK_SEL_AUDIO_PLL (1 << 11)
|
||||
#define SSPA_AUD_PLL_CTRL1_CLK_SEL_VCXO (0 << 11)
|
||||
#define SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN_MASK (0x7ff << 0)
|
||||
#define SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN(x) ((x) << 0)
|
||||
|
||||
struct mmp2_audio_clk {
|
||||
void __iomem *mmio_base;
|
||||
|
||||
struct clk_hw audio_pll_hw;
|
||||
struct clk_mux sspa_mux;
|
||||
struct clk_mux sspa1_mux;
|
||||
struct clk_divider sysclk_div;
|
||||
struct clk_divider sspa0_div;
|
||||
struct clk_divider sspa1_div;
|
||||
struct clk_gate sysclk_gate;
|
||||
struct clk_gate sspa0_gate;
|
||||
struct clk_gate sspa1_gate;
|
||||
|
||||
u32 aud_ctrl;
|
||||
u32 aud_pll_ctrl0;
|
||||
u32 aud_pll_ctrl1;
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
/* Must be last */
|
||||
struct clk_hw_onecell_data clk_data;
|
||||
};
|
||||
|
||||
static const struct {
|
||||
unsigned long parent_rate;
|
||||
unsigned long freq_vco;
|
||||
unsigned char mclk;
|
||||
unsigned char fbcclk;
|
||||
unsigned short fract;
|
||||
} predivs[] = {
|
||||
{ 26000000, 135475200, 0, 0, 0x8a18 },
|
||||
{ 26000000, 147456000, 0, 1, 0x0da1 },
|
||||
{ 38400000, 135475200, 1, 2, 0x8208 },
|
||||
{ 38400000, 147456000, 1, 3, 0xaaaa },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
unsigned char divisor;
|
||||
unsigned char modulo;
|
||||
unsigned char pattern;
|
||||
} postdivs[] = {
|
||||
{ 1, 3, 0, },
|
||||
{ 2, 5, 0, },
|
||||
{ 4, 0, 0, },
|
||||
{ 6, 1, 1, },
|
||||
{ 8, 1, 0, },
|
||||
{ 9, 1, 2, },
|
||||
{ 12, 2, 1, },
|
||||
{ 16, 2, 0, },
|
||||
{ 18, 2, 2, },
|
||||
{ 24, 4, 1, },
|
||||
{ 36, 4, 2, },
|
||||
{ 48, 6, 1, },
|
||||
{ 72, 6, 2, },
|
||||
};
|
||||
|
||||
static unsigned long audio_pll_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct mmp2_audio_clk *priv = container_of(hw, struct mmp2_audio_clk, audio_pll_hw);
|
||||
unsigned int prediv;
|
||||
unsigned int postdiv;
|
||||
u32 aud_pll_ctrl0;
|
||||
u32 aud_pll_ctrl1;
|
||||
|
||||
aud_pll_ctrl0 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL0);
|
||||
aud_pll_ctrl0 &= SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO_MASK |
|
||||
SSPA_AUD_PLL_CTRL0_FRACT_MASK |
|
||||
SSPA_AUD_PLL_CTRL0_ENA_DITHER |
|
||||
SSPA_AUD_PLL_CTRL0_DIV_FBCCLK_MASK |
|
||||
SSPA_AUD_PLL_CTRL0_DIV_MCLK_MASK |
|
||||
SSPA_AUD_PLL_CTRL0_PU;
|
||||
|
||||
aud_pll_ctrl1 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL1);
|
||||
aud_pll_ctrl1 &= SSPA_AUD_PLL_CTRL1_CLK_SEL_MASK |
|
||||
SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN_MASK;
|
||||
|
||||
for (prediv = 0; prediv < ARRAY_SIZE(predivs); prediv++) {
|
||||
if (predivs[prediv].parent_rate != parent_rate)
|
||||
continue;
|
||||
for (postdiv = 0; postdiv < ARRAY_SIZE(postdivs); postdiv++) {
|
||||
unsigned long freq;
|
||||
u32 val;
|
||||
|
||||
val = SSPA_AUD_PLL_CTRL0_ENA_DITHER;
|
||||
val |= SSPA_AUD_PLL_CTRL0_PU;
|
||||
val |= SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO(postdivs[postdiv].modulo);
|
||||
val |= SSPA_AUD_PLL_CTRL0_FRACT(predivs[prediv].fract);
|
||||
val |= SSPA_AUD_PLL_CTRL0_DIV_FBCCLK(predivs[prediv].fbcclk);
|
||||
val |= SSPA_AUD_PLL_CTRL0_DIV_MCLK(predivs[prediv].mclk);
|
||||
if (val != aud_pll_ctrl0)
|
||||
continue;
|
||||
|
||||
val = SSPA_AUD_PLL_CTRL1_CLK_SEL_AUDIO_PLL;
|
||||
val |= SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN(postdivs[postdiv].pattern);
|
||||
if (val != aud_pll_ctrl1)
|
||||
continue;
|
||||
|
||||
freq = predivs[prediv].freq_vco;
|
||||
freq /= postdivs[postdiv].divisor;
|
||||
return freq;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long audio_pll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
unsigned int prediv;
|
||||
unsigned int postdiv;
|
||||
long rounded = 0;
|
||||
|
||||
for (prediv = 0; prediv < ARRAY_SIZE(predivs); prediv++) {
|
||||
if (predivs[prediv].parent_rate != *parent_rate)
|
||||
continue;
|
||||
for (postdiv = 0; postdiv < ARRAY_SIZE(postdivs); postdiv++) {
|
||||
long freq = predivs[prediv].freq_vco;
|
||||
|
||||
freq /= postdivs[postdiv].divisor;
|
||||
if (freq == rate)
|
||||
return rate;
|
||||
if (freq < rate)
|
||||
continue;
|
||||
if (rounded && freq > rounded)
|
||||
continue;
|
||||
rounded = freq;
|
||||
}
|
||||
}
|
||||
|
||||
return rounded;
|
||||
}
|
||||
|
||||
static int audio_pll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct mmp2_audio_clk *priv = container_of(hw, struct mmp2_audio_clk, audio_pll_hw);
|
||||
unsigned int prediv;
|
||||
unsigned int postdiv;
|
||||
unsigned long val;
|
||||
|
||||
for (prediv = 0; prediv < ARRAY_SIZE(predivs); prediv++) {
|
||||
if (predivs[prediv].parent_rate != parent_rate)
|
||||
continue;
|
||||
|
||||
for (postdiv = 0; postdiv < ARRAY_SIZE(postdivs); postdiv++) {
|
||||
if (rate * postdivs[postdiv].divisor != predivs[prediv].freq_vco)
|
||||
continue;
|
||||
|
||||
val = SSPA_AUD_PLL_CTRL0_ENA_DITHER;
|
||||
val |= SSPA_AUD_PLL_CTRL0_PU;
|
||||
val |= SSPA_AUD_PLL_CTRL0_DIV_OCLK_MODULO(postdivs[postdiv].modulo);
|
||||
val |= SSPA_AUD_PLL_CTRL0_FRACT(predivs[prediv].fract);
|
||||
val |= SSPA_AUD_PLL_CTRL0_DIV_FBCCLK(predivs[prediv].fbcclk);
|
||||
val |= SSPA_AUD_PLL_CTRL0_DIV_MCLK(predivs[prediv].mclk);
|
||||
writel(val, priv->mmio_base + SSPA_AUD_PLL_CTRL0);
|
||||
|
||||
val = SSPA_AUD_PLL_CTRL1_CLK_SEL_AUDIO_PLL;
|
||||
val |= SSPA_AUD_PLL_CTRL1_DIV_OCLK_PATTERN(postdivs[postdiv].pattern);
|
||||
writel(val, priv->mmio_base + SSPA_AUD_PLL_CTRL1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -ERANGE;
|
||||
}
|
||||
|
||||
static const struct clk_ops audio_pll_ops = {
|
||||
.recalc_rate = audio_pll_recalc_rate,
|
||||
.round_rate = audio_pll_round_rate,
|
||||
.set_rate = audio_pll_set_rate,
|
||||
};
|
||||
|
||||
static int register_clocks(struct mmp2_audio_clk *priv, struct device *dev)
|
||||
{
|
||||
const struct clk_parent_data sspa_mux_parents[] = {
|
||||
{ .hw = &priv->audio_pll_hw },
|
||||
{ .fw_name = "i2s0" },
|
||||
};
|
||||
const struct clk_parent_data sspa1_mux_parents[] = {
|
||||
{ .hw = &priv->audio_pll_hw },
|
||||
{ .fw_name = "i2s1" },
|
||||
};
|
||||
int ret;
|
||||
|
||||
priv->audio_pll_hw.init = CLK_HW_INIT_FW_NAME("audio_pll",
|
||||
"vctcxo", &audio_pll_ops,
|
||||
CLK_SET_RATE_PARENT);
|
||||
ret = devm_clk_hw_register(dev, &priv->audio_pll_hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->sspa_mux.hw.init = CLK_HW_INIT_PARENTS_DATA("sspa_mux",
|
||||
sspa_mux_parents, &clk_mux_ops,
|
||||
CLK_SET_RATE_PARENT);
|
||||
priv->sspa_mux.reg = priv->mmio_base + SSPA_AUD_CTRL;
|
||||
priv->sspa_mux.mask = 1;
|
||||
priv->sspa_mux.shift = SSPA_AUD_CTRL_SSPA0_MUX_SHIFT;
|
||||
ret = devm_clk_hw_register(dev, &priv->sspa_mux.hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->sysclk_div.hw.init = CLK_HW_INIT_HW("sys_div",
|
||||
&priv->sspa_mux.hw, &clk_divider_ops,
|
||||
CLK_SET_RATE_PARENT);
|
||||
priv->sysclk_div.reg = priv->mmio_base + SSPA_AUD_CTRL;
|
||||
priv->sysclk_div.shift = SSPA_AUD_CTRL_SYSCLK_DIV_SHIFT;
|
||||
priv->sysclk_div.width = 6;
|
||||
priv->sysclk_div.flags = CLK_DIVIDER_ONE_BASED;
|
||||
priv->sysclk_div.flags |= CLK_DIVIDER_ROUND_CLOSEST;
|
||||
priv->sysclk_div.flags |= CLK_DIVIDER_ALLOW_ZERO;
|
||||
ret = devm_clk_hw_register(dev, &priv->sysclk_div.hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->sysclk_gate.hw.init = CLK_HW_INIT_HW("sys_clk",
|
||||
&priv->sysclk_div.hw, &clk_gate_ops,
|
||||
CLK_SET_RATE_PARENT);
|
||||
priv->sysclk_gate.reg = priv->mmio_base + SSPA_AUD_CTRL;
|
||||
priv->sysclk_gate.bit_idx = SSPA_AUD_CTRL_SYSCLK_SHIFT;
|
||||
ret = devm_clk_hw_register(dev, &priv->sysclk_gate.hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->sspa0_div.hw.init = CLK_HW_INIT_HW("sspa0_div",
|
||||
&priv->sspa_mux.hw, &clk_divider_ops, 0);
|
||||
priv->sspa0_div.reg = priv->mmio_base + SSPA_AUD_CTRL;
|
||||
priv->sspa0_div.shift = SSPA_AUD_CTRL_SSPA0_DIV_SHIFT;
|
||||
priv->sspa0_div.width = 6;
|
||||
priv->sspa0_div.flags = CLK_DIVIDER_ONE_BASED;
|
||||
priv->sspa0_div.flags |= CLK_DIVIDER_ROUND_CLOSEST;
|
||||
priv->sspa0_div.flags |= CLK_DIVIDER_ALLOW_ZERO;
|
||||
ret = devm_clk_hw_register(dev, &priv->sspa0_div.hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->sspa0_gate.hw.init = CLK_HW_INIT_HW("sspa0_clk",
|
||||
&priv->sspa0_div.hw, &clk_gate_ops,
|
||||
CLK_SET_RATE_PARENT);
|
||||
priv->sspa0_gate.reg = priv->mmio_base + SSPA_AUD_CTRL;
|
||||
priv->sspa0_gate.bit_idx = SSPA_AUD_CTRL_SSPA0_SHIFT;
|
||||
ret = devm_clk_hw_register(dev, &priv->sspa0_gate.hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->sspa1_mux.hw.init = CLK_HW_INIT_PARENTS_DATA("sspa1_mux",
|
||||
sspa1_mux_parents, &clk_mux_ops,
|
||||
CLK_SET_RATE_PARENT);
|
||||
priv->sspa1_mux.reg = priv->mmio_base + SSPA_AUD_CTRL;
|
||||
priv->sspa1_mux.mask = 1;
|
||||
priv->sspa1_mux.shift = SSPA_AUD_CTRL_SSPA1_MUX_SHIFT;
|
||||
ret = devm_clk_hw_register(dev, &priv->sspa1_mux.hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->sspa1_div.hw.init = CLK_HW_INIT_HW("sspa1_div",
|
||||
&priv->sspa1_mux.hw, &clk_divider_ops, 0);
|
||||
priv->sspa1_div.reg = priv->mmio_base + SSPA_AUD_CTRL;
|
||||
priv->sspa1_div.shift = SSPA_AUD_CTRL_SSPA1_DIV_SHIFT;
|
||||
priv->sspa1_div.width = 6;
|
||||
priv->sspa1_div.flags = CLK_DIVIDER_ONE_BASED;
|
||||
priv->sspa1_div.flags |= CLK_DIVIDER_ROUND_CLOSEST;
|
||||
priv->sspa1_div.flags |= CLK_DIVIDER_ALLOW_ZERO;
|
||||
ret = devm_clk_hw_register(dev, &priv->sspa1_div.hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->sspa1_gate.hw.init = CLK_HW_INIT_HW("sspa1_clk",
|
||||
&priv->sspa1_div.hw, &clk_gate_ops,
|
||||
CLK_SET_RATE_PARENT);
|
||||
priv->sspa1_gate.reg = priv->mmio_base + SSPA_AUD_CTRL;
|
||||
priv->sspa1_gate.bit_idx = SSPA_AUD_CTRL_SSPA1_SHIFT;
|
||||
ret = devm_clk_hw_register(dev, &priv->sspa1_gate.hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->clk_data.hws[MMP2_CLK_AUDIO_SYSCLK] = &priv->sysclk_gate.hw;
|
||||
priv->clk_data.hws[MMP2_CLK_AUDIO_SSPA0] = &priv->sspa0_gate.hw;
|
||||
priv->clk_data.hws[MMP2_CLK_AUDIO_SSPA1] = &priv->sspa1_gate.hw;
|
||||
priv->clk_data.num = MMP2_CLK_AUDIO_NR_CLKS;
|
||||
|
||||
return of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get,
|
||||
&priv->clk_data);
|
||||
}
|
||||
|
||||
static int mmp2_audio_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mmp2_audio_clk *priv;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev,
|
||||
struct_size(priv, clk_data.hws,
|
||||
MMP2_CLK_AUDIO_NR_CLKS),
|
||||
GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
priv->mmio_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(priv->mmio_base))
|
||||
return PTR_ERR(priv->mmio_base);
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
ret = pm_clk_create(&pdev->dev);
|
||||
if (ret)
|
||||
goto disable_pm_runtime;
|
||||
|
||||
ret = pm_clk_add(&pdev->dev, "audio");
|
||||
if (ret)
|
||||
goto destroy_pm_clk;
|
||||
|
||||
ret = register_clocks(priv, &pdev->dev);
|
||||
if (ret)
|
||||
goto destroy_pm_clk;
|
||||
|
||||
return 0;
|
||||
|
||||
destroy_pm_clk:
|
||||
pm_clk_destroy(&pdev->dev);
|
||||
disable_pm_runtime:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mmp2_audio_clk_remove(struct platform_device *pdev)
|
||||
{
|
||||
pm_clk_destroy(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused mmp2_audio_clk_suspend(struct device *dev)
|
||||
{
|
||||
struct mmp2_audio_clk *priv = dev_get_drvdata(dev);
|
||||
|
||||
priv->aud_ctrl = readl(priv->mmio_base + SSPA_AUD_CTRL);
|
||||
priv->aud_pll_ctrl0 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL0);
|
||||
priv->aud_pll_ctrl1 = readl(priv->mmio_base + SSPA_AUD_PLL_CTRL1);
|
||||
pm_clk_suspend(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused mmp2_audio_clk_resume(struct device *dev)
|
||||
{
|
||||
struct mmp2_audio_clk *priv = dev_get_drvdata(dev);
|
||||
|
||||
pm_clk_resume(dev);
|
||||
writel(priv->aud_ctrl, priv->mmio_base + SSPA_AUD_CTRL);
|
||||
writel(priv->aud_pll_ctrl0, priv->mmio_base + SSPA_AUD_PLL_CTRL0);
|
||||
writel(priv->aud_pll_ctrl1, priv->mmio_base + SSPA_AUD_PLL_CTRL1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops mmp2_audio_clk_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(mmp2_audio_clk_suspend, mmp2_audio_clk_resume, NULL)
|
||||
};
|
||||
|
||||
static const struct of_device_id mmp2_audio_clk_of_match[] = {
|
||||
{ .compatible = "marvell,mmp2-audio-clock" },
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, mmp2_audio_clk_of_match);
|
||||
|
||||
static struct platform_driver mmp2_audio_clk_driver = {
|
||||
.driver = {
|
||||
.name = "mmp2-audio-clock",
|
||||
.of_match_table = of_match_ptr(mmp2_audio_clk_of_match),
|
||||
.pm = &mmp2_audio_clk_pm_ops,
|
||||
},
|
||||
.probe = mmp2_audio_clk_probe,
|
||||
.remove = mmp2_audio_clk_remove,
|
||||
};
|
||||
module_platform_driver(mmp2_audio_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
|
||||
MODULE_DESCRIPTION("Clock driver for MMP2 Audio subsystem");
|
||||
MODULE_LICENSE("GPL");
|
@ -28,13 +28,15 @@ static long clk_factor_round_rate(struct clk_hw *hw, unsigned long drate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
struct mmp_clk_factor *factor = to_clk_factor(hw);
|
||||
unsigned long rate = 0, prev_rate;
|
||||
u64 rate = 0, prev_rate;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < factor->ftbl_cnt; i++) {
|
||||
prev_rate = rate;
|
||||
rate = (((*prate / 10000) * factor->ftbl[i].den) /
|
||||
(factor->ftbl[i].num * factor->masks->factor)) * 10000;
|
||||
rate = *prate;
|
||||
rate *= factor->ftbl[i].den;
|
||||
do_div(rate, factor->ftbl[i].num * factor->masks->factor);
|
||||
|
||||
if (rate > drate)
|
||||
break;
|
||||
}
|
||||
@ -54,6 +56,7 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
|
||||
struct mmp_clk_factor *factor = to_clk_factor(hw);
|
||||
struct mmp_clk_factor_masks *masks = factor->masks;
|
||||
unsigned int val, num, den;
|
||||
u64 rate;
|
||||
|
||||
val = readl_relaxed(factor->base);
|
||||
|
||||
@ -66,8 +69,11 @@ static unsigned long clk_factor_recalc_rate(struct clk_hw *hw,
|
||||
if (!den)
|
||||
return 0;
|
||||
|
||||
return (((parent_rate / 10000) * den) /
|
||||
(num * factor->masks->factor)) * 10000;
|
||||
rate = parent_rate;
|
||||
rate *= den;
|
||||
do_div(rate, num * factor->masks->factor);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
/* Configures new clock rate*/
|
||||
@ -78,12 +84,14 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
|
||||
struct mmp_clk_factor_masks *masks = factor->masks;
|
||||
int i;
|
||||
unsigned long val;
|
||||
unsigned long rate = 0;
|
||||
unsigned long flags = 0;
|
||||
u64 rate = 0;
|
||||
|
||||
for (i = 0; i < factor->ftbl_cnt; i++) {
|
||||
rate = (((prate / 10000) * factor->ftbl[i].den) /
|
||||
(factor->ftbl[i].num * factor->masks->factor)) * 10000;
|
||||
rate = prate;
|
||||
rate *= factor->ftbl[i].den;
|
||||
do_div(rate, factor->ftbl[i].num * factor->masks->factor);
|
||||
|
||||
if (rate > drate)
|
||||
break;
|
||||
}
|
||||
@ -140,7 +148,10 @@ static int clk_factor_init(struct clk_hw *hw)
|
||||
val &= ~(masks->den_mask << masks->den_shift);
|
||||
val |= (factor->ftbl[0].den & masks->den_mask) <<
|
||||
masks->den_shift;
|
||||
}
|
||||
|
||||
if (!(val & masks->enable_mask) || i >= factor->ftbl_cnt) {
|
||||
val |= masks->enable_mask;
|
||||
writel(val, factor->base);
|
||||
}
|
||||
|
||||
|
@ -17,8 +17,10 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/clk.h>
|
||||
|
||||
#include <dt-bindings/clock/marvell,mmp2.h>
|
||||
#include <dt-bindings/power/marvell,mmp2.h>
|
||||
|
||||
#include "clk.h"
|
||||
#include "reset.h"
|
||||
@ -45,6 +47,10 @@
|
||||
#define APBC_SSP1 0x54
|
||||
#define APBC_SSP2 0x58
|
||||
#define APBC_SSP3 0x5c
|
||||
#define APBC_THERMAL0 0x90
|
||||
#define APBC_THERMAL1 0x98
|
||||
#define APBC_THERMAL2 0x9c
|
||||
#define APBC_THERMAL3 0xa0
|
||||
#define APMU_SDH0 0x54
|
||||
#define APMU_SDH1 0x58
|
||||
#define APMU_SDH2 0xe8
|
||||
@ -55,18 +61,19 @@
|
||||
#define APMU_DISP1 0x110
|
||||
#define APMU_CCIC0 0x50
|
||||
#define APMU_CCIC1 0xf4
|
||||
#define APBC_THERMAL0 0x90
|
||||
#define APBC_THERMAL1 0x98
|
||||
#define APBC_THERMAL2 0x9c
|
||||
#define APBC_THERMAL3 0xa0
|
||||
#define APMU_USBHSIC0 0xf8
|
||||
#define APMU_USBHSIC1 0xfc
|
||||
#define APMU_GPU 0xcc
|
||||
#define APMU_AUDIO 0x10c
|
||||
#define APMU_CAMERA 0x1fc
|
||||
|
||||
#define MPMU_FCCR 0x8
|
||||
#define MPMU_POSR 0x10
|
||||
#define MPMU_UART_PLL 0x14
|
||||
#define MPMU_PLL2_CR 0x34
|
||||
#define MPMU_I2S0_PLL 0x40
|
||||
#define MPMU_I2S1_PLL 0x44
|
||||
#define MPMU_ACGR 0x1024
|
||||
/* MMP3 specific below */
|
||||
#define MPMU_PLL3_CR 0x50
|
||||
#define MPMU_PLL3_CTRL1 0x58
|
||||
@ -82,6 +89,8 @@ enum mmp2_clk_model {
|
||||
struct mmp2_clk_unit {
|
||||
struct mmp_clk_unit unit;
|
||||
enum mmp2_clk_model model;
|
||||
struct genpd_onecell_data pd_data;
|
||||
struct generic_pm_domain *pm_domains[MMP2_NR_POWER_DOMAINS];
|
||||
void __iomem *mpmu_base;
|
||||
void __iomem *apmu_base;
|
||||
void __iomem *apbc_base;
|
||||
@ -91,6 +100,7 @@ static struct mmp_param_fixed_rate_clk fixed_rate_clks[] = {
|
||||
{MMP2_CLK_CLK32, "clk32", NULL, 0, 32768},
|
||||
{MMP2_CLK_VCTCXO, "vctcxo", NULL, 0, 26000000},
|
||||
{MMP2_CLK_USB_PLL, "usb_pll", NULL, 0, 480000000},
|
||||
{0, "i2s_pll", NULL, 0, 99666667},
|
||||
};
|
||||
|
||||
static struct mmp_param_pll_clk pll_clks[] = {
|
||||
@ -139,7 +149,35 @@ static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
|
||||
{.num = 3521, .den = 689}, /*19.23MHZ */
|
||||
};
|
||||
|
||||
static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
|
||||
static struct mmp_clk_factor_masks i2s_factor_masks = {
|
||||
.factor = 2,
|
||||
.num_mask = 0x7fff,
|
||||
.den_mask = 0x1fff,
|
||||
.num_shift = 0,
|
||||
.den_shift = 15,
|
||||
.enable_mask = 0xd0000000,
|
||||
};
|
||||
|
||||
static struct mmp_clk_factor_tbl i2s_factor_tbl[] = {
|
||||
{.num = 24868, .den = 511}, /* 2.0480 MHz */
|
||||
{.num = 28003, .den = 793}, /* 2.8224 MHz */
|
||||
{.num = 24941, .den = 1025}, /* 4.0960 MHz */
|
||||
{.num = 28003, .den = 1586}, /* 5.6448 MHz */
|
||||
{.num = 31158, .den = 2561}, /* 8.1920 MHz */
|
||||
{.num = 16288, .den = 1845}, /* 11.2896 MHz */
|
||||
{.num = 20772, .den = 2561}, /* 12.2880 MHz */
|
||||
{.num = 8144, .den = 1845}, /* 22.5792 MHz */
|
||||
{.num = 10386, .den = 2561}, /* 24.5760 MHz */
|
||||
};
|
||||
|
||||
static DEFINE_SPINLOCK(acgr_lock);
|
||||
|
||||
static struct mmp_param_gate_clk mpmu_gate_clks[] = {
|
||||
{MMP2_CLK_I2S0, "i2s0_clk", "i2s0_pll", CLK_SET_RATE_PARENT, MPMU_ACGR, 0x200000, 0x200000, 0x0, 0, &acgr_lock},
|
||||
{MMP2_CLK_I2S1, "i2s1_clk", "i2s1_pll", CLK_SET_RATE_PARENT, MPMU_ACGR, 0x100000, 0x100000, 0x0, 0, &acgr_lock},
|
||||
};
|
||||
|
||||
static void mmp2_main_clk_init(struct mmp2_clk_unit *pxa_unit)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct mmp_clk_unit *unit = &pxa_unit->unit;
|
||||
@ -166,6 +204,20 @@ static void mmp2_pll_init(struct mmp2_clk_unit *pxa_unit)
|
||||
&uart_factor_masks, uart_factor_tbl,
|
||||
ARRAY_SIZE(uart_factor_tbl), NULL);
|
||||
mmp_clk_add(unit, MMP2_CLK_UART_PLL, clk);
|
||||
|
||||
mmp_clk_register_factor("i2s0_pll", "pll1_4",
|
||||
CLK_SET_RATE_PARENT,
|
||||
pxa_unit->mpmu_base + MPMU_I2S0_PLL,
|
||||
&i2s_factor_masks, i2s_factor_tbl,
|
||||
ARRAY_SIZE(i2s_factor_tbl), NULL);
|
||||
mmp_clk_register_factor("i2s1_pll", "pll1_4",
|
||||
CLK_SET_RATE_PARENT,
|
||||
pxa_unit->mpmu_base + MPMU_I2S1_PLL,
|
||||
&i2s_factor_masks, i2s_factor_tbl,
|
||||
ARRAY_SIZE(i2s_factor_tbl), NULL);
|
||||
|
||||
mmp_register_gate_clks(unit, mpmu_gate_clks, pxa_unit->mpmu_base,
|
||||
ARRAY_SIZE(mpmu_gate_clks));
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(uart0_lock);
|
||||
@ -271,6 +323,8 @@ static u32 mmp2_gpu_bus_parent_table[] = { 0x0000, 0x0020, 0x0030,
|
||||
static const char * const mmp3_gpu_bus_parent_names[] = {"pll1_4", "pll1_6", "pll1_2", "pll2_2"};
|
||||
static const char * const mmp3_gpu_gc_parent_names[] = {"pll1", "pll2", "pll1_p", "pll2_p"};
|
||||
|
||||
static DEFINE_SPINLOCK(audio_lock);
|
||||
|
||||
static struct mmp_clk_mix_config ccic0_mix_config = {
|
||||
.reg_info = DEFINE_MIX_REG_INFO(4, 17, 2, 6, 32),
|
||||
};
|
||||
@ -326,6 +380,7 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = {
|
||||
{MMP2_CLK_CCIC1_PHY, "ccic1_phy_clk", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x24, 0x24, 0x0, 0, &ccic1_lock},
|
||||
{MMP2_CLK_CCIC1_SPHY, "ccic1_sphy_clk", "ccic1_sphy_div", CLK_SET_RATE_PARENT, APMU_CCIC1, 0x300, 0x300, 0x0, 0, &ccic1_lock},
|
||||
{MMP2_CLK_GPU_BUS, "gpu_bus_clk", "gpu_bus_mux", CLK_SET_RATE_PARENT, APMU_GPU, 0xa, 0xa, 0x0, MMP_CLK_GATE_NEED_DELAY, &gpu_lock},
|
||||
{MMP2_CLK_AUDIO, "audio_clk", "audio_mix_clk", CLK_SET_RATE_PARENT, APMU_AUDIO, 0x12, 0x12, 0x0, 0, &audio_lock},
|
||||
};
|
||||
|
||||
static struct mmp_param_gate_clk mmp2_apmu_gate_clks[] = {
|
||||
@ -423,6 +478,41 @@ static void mmp2_clk_reset_init(struct device_node *np,
|
||||
mmp_clk_reset_register(np, cells, nr_resets);
|
||||
}
|
||||
|
||||
static void mmp2_pm_domain_init(struct device_node *np,
|
||||
struct mmp2_clk_unit *pxa_unit)
|
||||
{
|
||||
if (pxa_unit->model == CLK_MODEL_MMP3) {
|
||||
pxa_unit->pm_domains[MMP2_POWER_DOMAIN_GPU]
|
||||
= mmp_pm_domain_register("gpu",
|
||||
pxa_unit->apmu_base + APMU_GPU,
|
||||
0x0600, 0x40003, 0x18000c, 0, &gpu_lock);
|
||||
} else {
|
||||
pxa_unit->pm_domains[MMP2_POWER_DOMAIN_GPU]
|
||||
= mmp_pm_domain_register("gpu",
|
||||
pxa_unit->apmu_base + APMU_GPU,
|
||||
0x8600, 0x00003, 0x00000c,
|
||||
MMP_PM_DOMAIN_NO_DISABLE, &gpu_lock);
|
||||
}
|
||||
pxa_unit->pd_data.num_domains++;
|
||||
|
||||
pxa_unit->pm_domains[MMP2_POWER_DOMAIN_AUDIO]
|
||||
= mmp_pm_domain_register("audio",
|
||||
pxa_unit->apmu_base + APMU_AUDIO,
|
||||
0x600, 0x2, 0, 0, &audio_lock);
|
||||
pxa_unit->pd_data.num_domains++;
|
||||
|
||||
if (pxa_unit->model == CLK_MODEL_MMP3) {
|
||||
pxa_unit->pm_domains[MMP3_POWER_DOMAIN_CAMERA]
|
||||
= mmp_pm_domain_register("camera",
|
||||
pxa_unit->apmu_base + APMU_CAMERA,
|
||||
0x600, 0, 0, 0, NULL);
|
||||
pxa_unit->pd_data.num_domains++;
|
||||
}
|
||||
|
||||
pxa_unit->pd_data.domains = pxa_unit->pm_domains;
|
||||
of_genpd_add_provider_onecell(np, &pxa_unit->pd_data);
|
||||
}
|
||||
|
||||
static void __init mmp2_clk_init(struct device_node *np)
|
||||
{
|
||||
struct mmp2_clk_unit *pxa_unit;
|
||||
@ -454,9 +544,11 @@ static void __init mmp2_clk_init(struct device_node *np)
|
||||
goto unmap_apmu_region;
|
||||
}
|
||||
|
||||
mmp2_pm_domain_init(np, pxa_unit);
|
||||
|
||||
mmp_clk_init(np, &pxa_unit->unit, MMP2_NR_CLKS);
|
||||
|
||||
mmp2_pll_init(pxa_unit);
|
||||
mmp2_main_clk_init(pxa_unit);
|
||||
|
||||
mmp2_apb_periph_clk_init(pxa_unit);
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#define __MACH_MMP_CLK_H
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/clkdev.h>
|
||||
|
||||
#define APBC_NO_BUS_CTRL BIT(0)
|
||||
@ -16,6 +17,7 @@ struct mmp_clk_factor_masks {
|
||||
unsigned int den_mask;
|
||||
unsigned int num_shift;
|
||||
unsigned int den_shift;
|
||||
unsigned int enable_mask;
|
||||
};
|
||||
|
||||
struct mmp_clk_factor_tbl {
|
||||
@ -258,4 +260,13 @@ void mmp_clk_init(struct device_node *np, struct mmp_clk_unit *unit,
|
||||
int nr_clks);
|
||||
void mmp_clk_add(struct mmp_clk_unit *unit, unsigned int id,
|
||||
struct clk *clk);
|
||||
|
||||
/* Power islands */
|
||||
#define MMP_PM_DOMAIN_NO_DISABLE BIT(0)
|
||||
|
||||
struct generic_pm_domain *mmp_pm_domain_register(const char *name,
|
||||
void __iomem *reg,
|
||||
u32 power_on, u32 reset, u32 clock_enable,
|
||||
unsigned int flags, spinlock_t *lock);
|
||||
|
||||
#endif
|
||||
|
115
drivers/clk/mmp/pwr-island.c
Normal file
115
drivers/clk/mmp/pwr-island.c
Normal file
@ -0,0 +1,115 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* MMP PMU power island support
|
||||
*
|
||||
* Copyright (C) 2020 Lubomir Rintel <lkundrak@v3.sk>
|
||||
*/
|
||||
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
#define to_mmp_pm_domain(genpd) container_of(genpd, struct mmp_pm_domain, genpd)
|
||||
|
||||
struct mmp_pm_domain {
|
||||
struct generic_pm_domain genpd;
|
||||
void __iomem *reg;
|
||||
spinlock_t *lock;
|
||||
u32 power_on;
|
||||
u32 reset;
|
||||
u32 clock_enable;
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
static int mmp_pm_domain_power_on(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct mmp_pm_domain *pm_domain = to_mmp_pm_domain(genpd);
|
||||
unsigned long flags = 0;
|
||||
u32 val;
|
||||
|
||||
if (pm_domain->lock)
|
||||
spin_lock_irqsave(pm_domain->lock, flags);
|
||||
|
||||
val = readl(pm_domain->reg);
|
||||
|
||||
/* Turn on the power island */
|
||||
val |= pm_domain->power_on;
|
||||
writel(val, pm_domain->reg);
|
||||
|
||||
/* Disable isolation */
|
||||
val |= 0x100;
|
||||
writel(val, pm_domain->reg);
|
||||
|
||||
/* Some blocks need to be reset after a power up */
|
||||
if (pm_domain->reset || pm_domain->clock_enable) {
|
||||
u32 after_power_on = val;
|
||||
|
||||
val &= ~pm_domain->reset;
|
||||
writel(val, pm_domain->reg);
|
||||
|
||||
val |= pm_domain->clock_enable;
|
||||
writel(val, pm_domain->reg);
|
||||
|
||||
val |= pm_domain->reset;
|
||||
writel(val, pm_domain->reg);
|
||||
|
||||
writel(after_power_on, pm_domain->reg);
|
||||
}
|
||||
|
||||
if (pm_domain->lock)
|
||||
spin_unlock_irqrestore(pm_domain->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mmp_pm_domain_power_off(struct generic_pm_domain *genpd)
|
||||
{
|
||||
struct mmp_pm_domain *pm_domain = to_mmp_pm_domain(genpd);
|
||||
unsigned long flags = 0;
|
||||
u32 val;
|
||||
|
||||
if (pm_domain->flags & MMP_PM_DOMAIN_NO_DISABLE)
|
||||
return 0;
|
||||
|
||||
if (pm_domain->lock)
|
||||
spin_lock_irqsave(pm_domain->lock, flags);
|
||||
|
||||
/* Turn off and isolate the the power island. */
|
||||
val = readl(pm_domain->reg);
|
||||
val &= ~pm_domain->power_on;
|
||||
val &= ~0x100;
|
||||
writel(val, pm_domain->reg);
|
||||
|
||||
if (pm_domain->lock)
|
||||
spin_unlock_irqrestore(pm_domain->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct generic_pm_domain *mmp_pm_domain_register(const char *name,
|
||||
void __iomem *reg,
|
||||
u32 power_on, u32 reset, u32 clock_enable,
|
||||
unsigned int flags, spinlock_t *lock)
|
||||
{
|
||||
struct mmp_pm_domain *pm_domain;
|
||||
|
||||
pm_domain = kzalloc(sizeof(*pm_domain), GFP_KERNEL);
|
||||
if (!pm_domain)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pm_domain->reg = reg;
|
||||
pm_domain->power_on = power_on;
|
||||
pm_domain->reset = reset;
|
||||
pm_domain->clock_enable = clock_enable;
|
||||
pm_domain->flags = flags;
|
||||
pm_domain->lock = lock;
|
||||
|
||||
pm_genpd_init(&pm_domain->genpd, NULL, true);
|
||||
pm_domain->genpd.name = name;
|
||||
pm_domain->genpd.power_on = mmp_pm_domain_power_on;
|
||||
pm_domain->genpd.power_off = mmp_pm_domain_power_off;
|
||||
|
||||
return &pm_domain->genpd;
|
||||
}
|
@ -142,6 +142,14 @@ config MSM_GCC_8916
|
||||
Say Y if you want to use devices such as UART, SPI i2c, USB,
|
||||
SD/eMMC, display, graphics, camera etc.
|
||||
|
||||
config MSM_GCC_8939
|
||||
tristate "MSM8939 Global Clock Controller"
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the global clock controller on msm8939 devices.
|
||||
Say Y if you want to use devices such as UART, SPI i2c, USB,
|
||||
SD/eMMC, display, graphics, camera etc.
|
||||
|
||||
config MSM_GCC_8960
|
||||
tristate "APQ8064/MSM8960 Global Clock Controller"
|
||||
help
|
||||
|
@ -28,6 +28,7 @@ obj-$(CONFIG_MDM_GCC_9615) += gcc-mdm9615.o
|
||||
obj-$(CONFIG_MDM_LCC_9615) += lcc-mdm9615.o
|
||||
obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
|
||||
obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
|
||||
obj-$(CONFIG_MSM_GCC_8939) += gcc-msm8939.o
|
||||
obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
|
||||
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
|
||||
obj-$(CONFIG_MSM_GCC_8994) += gcc-msm8994.o
|
||||
|
@ -260,7 +260,7 @@ static struct clk_pll gpll0 = {
|
||||
.l_reg = 0x21004,
|
||||
.m_reg = 0x21008,
|
||||
.n_reg = 0x2100c,
|
||||
.config_reg = 0x21014,
|
||||
.config_reg = 0x21010,
|
||||
.mode_reg = 0x21000,
|
||||
.status_reg = 0x2101c,
|
||||
.status_bit = 17,
|
||||
@ -287,7 +287,7 @@ static struct clk_pll gpll1 = {
|
||||
.l_reg = 0x20004,
|
||||
.m_reg = 0x20008,
|
||||
.n_reg = 0x2000c,
|
||||
.config_reg = 0x20014,
|
||||
.config_reg = 0x20010,
|
||||
.mode_reg = 0x20000,
|
||||
.status_reg = 0x2001c,
|
||||
.status_bit = 17,
|
||||
@ -314,7 +314,7 @@ static struct clk_pll gpll2 = {
|
||||
.l_reg = 0x4a004,
|
||||
.m_reg = 0x4a008,
|
||||
.n_reg = 0x4a00c,
|
||||
.config_reg = 0x4a014,
|
||||
.config_reg = 0x4a010,
|
||||
.mode_reg = 0x4a000,
|
||||
.status_reg = 0x4a01c,
|
||||
.status_bit = 17,
|
||||
@ -341,7 +341,7 @@ static struct clk_pll bimc_pll = {
|
||||
.l_reg = 0x23004,
|
||||
.m_reg = 0x23008,
|
||||
.n_reg = 0x2300c,
|
||||
.config_reg = 0x23014,
|
||||
.config_reg = 0x23010,
|
||||
.mode_reg = 0x23000,
|
||||
.status_reg = 0x2301c,
|
||||
.status_bit = 17,
|
||||
|
3988
drivers/clk/qcom/gcc-msm8939.c
Normal file
3988
drivers/clk/qcom/gcc-msm8939.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -1110,6 +1110,27 @@ static struct clk_rcg2 ufs_axi_clk_src = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_ufs_unipro_core_clk_src[] = {
|
||||
F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0),
|
||||
F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
|
||||
F(150000000, P_GPLL0_OUT_MAIN, 4, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 ufs_unipro_core_clk_src = {
|
||||
.cmd_rcgr = 0x76028,
|
||||
.mnd_width = 8,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.freq_tbl = ftbl_ufs_unipro_core_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "ufs_unipro_core_clk_src",
|
||||
.parent_names = gcc_parent_names_0,
|
||||
.num_parents = 4,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_usb30_master_clk_src[] = {
|
||||
F(19200000, P_XO, 1, 0, 0),
|
||||
F(60000000, P_GPLL0_OUT_MAIN, 10, 0, 0),
|
||||
@ -2549,6 +2570,11 @@ static struct clk_branch gcc_ufs_unipro_core_clk = {
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_unipro_core_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"ufs_unipro_core_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
@ -2904,6 +2930,7 @@ static struct clk_regmap *gcc_msm8998_clocks[] = {
|
||||
[SDCC4_APPS_CLK_SRC] = &sdcc4_apps_clk_src.clkr,
|
||||
[TSIF_REF_CLK_SRC] = &tsif_ref_clk_src.clkr,
|
||||
[UFS_AXI_CLK_SRC] = &ufs_axi_clk_src.clkr,
|
||||
[UFS_UNIPRO_CORE_CLK_SRC] = &ufs_unipro_core_clk_src.clkr,
|
||||
[USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
|
||||
[USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
|
||||
[USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,
|
||||
|
@ -390,6 +390,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
|
||||
F(29491200, P_GPLL0_OUT_EVEN, 1, 1536, 15625),
|
||||
F(32000000, P_GPLL0_OUT_EVEN, 1, 8, 75),
|
||||
F(48000000, P_GPLL0_OUT_EVEN, 1, 4, 25),
|
||||
F(51200000, P_GPLL6_OUT_MAIN, 7.5, 0, 0),
|
||||
F(64000000, P_GPLL0_OUT_EVEN, 1, 16, 75),
|
||||
F(75000000, P_GPLL0_OUT_EVEN, 4, 0, 0),
|
||||
F(80000000, P_GPLL0_OUT_EVEN, 1, 4, 15),
|
||||
@ -405,8 +406,8 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap0_s0_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -414,15 +415,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
|
||||
.cmd_rcgr = 0x17034,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap0_s1_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -430,15 +431,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
|
||||
.cmd_rcgr = 0x17164,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap0_s2_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -446,15 +447,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
|
||||
.cmd_rcgr = 0x17294,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap0_s3_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -462,15 +463,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
|
||||
.cmd_rcgr = 0x173c4,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap0_s4_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -478,15 +479,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
|
||||
.cmd_rcgr = 0x174f4,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap0_s5_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -494,15 +495,15 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
|
||||
.cmd_rcgr = 0x17624,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap1_s0_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -510,15 +511,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
|
||||
.cmd_rcgr = 0x18018,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap1_s1_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -526,15 +527,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
|
||||
.cmd_rcgr = 0x18148,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap1_s2_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -542,15 +543,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
|
||||
.cmd_rcgr = 0x18278,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap1_s3_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -558,15 +559,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
|
||||
.cmd_rcgr = 0x183a8,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap1_s4_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -574,15 +575,15 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
|
||||
.cmd_rcgr = 0x184d8,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
|
||||
};
|
||||
|
||||
static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
|
||||
.name = "gcc_qupv3_wrap1_s5_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_ops,
|
||||
};
|
||||
|
||||
@ -590,7 +591,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
|
||||
.cmd_rcgr = 0x18608,
|
||||
.mnd_width = 16,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_0,
|
||||
.parent_map = gcc_parent_map_1,
|
||||
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
|
||||
.clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
|
||||
};
|
||||
@ -816,6 +817,26 @@ static struct clk_rcg2 gcc_usb3_prim_phy_aux_clk_src = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gcc_sec_ctrl_clk_src[] = {
|
||||
F(4800000, P_BI_TCXO, 4, 0, 0),
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 gcc_sec_ctrl_clk_src = {
|
||||
.cmd_rcgr = 0x3d030,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_3,
|
||||
.freq_tbl = ftbl_gcc_sec_ctrl_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_sec_ctrl_clk_src",
|
||||
.parent_data = gcc_parent_data_3,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_3),
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_aggre_ufs_phy_axi_clk = {
|
||||
.halt_reg = 0x82024,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
@ -2406,6 +2427,7 @@ static struct clk_regmap *gcc_sc7180_clocks[] = {
|
||||
[GCC_MSS_NAV_AXI_CLK] = &gcc_mss_nav_axi_clk.clkr,
|
||||
[GCC_MSS_Q6_MEMNOC_AXI_CLK] = &gcc_mss_q6_memnoc_axi_clk.clkr,
|
||||
[GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
|
||||
[GCC_SEC_CTRL_CLK_SRC] = &gcc_sec_ctrl_clk_src.clkr,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gcc_sc7180_resets[] = {
|
||||
|
@ -1617,6 +1617,36 @@ static struct clk_branch gcc_gpu_cfg_ahb_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_gpu_gpll0_clk_src = {
|
||||
.clkr = {
|
||||
.enable_reg = 0x52004,
|
||||
.enable_mask = BIT(15),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_gpu_gpll0_clk_src",
|
||||
.parent_hws = (const struct clk_hw *[]){
|
||||
&gpll0.clkr.hw },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_gpu_gpll0_div_clk_src = {
|
||||
.clkr = {
|
||||
.enable_reg = 0x52004,
|
||||
.enable_mask = BIT(16),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_gpu_gpll0_div_clk_src",
|
||||
.parent_hws = (const struct clk_hw *[]){
|
||||
&gcc_gpu_gpll0_clk_src.clkr.hw },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_gpu_iref_clk = {
|
||||
.halt_reg = 0x8c010,
|
||||
.halt_check = BRANCH_HALT,
|
||||
@ -1699,6 +1729,36 @@ static struct clk_branch gcc_npu_cfg_ahb_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_npu_gpll0_clk_src = {
|
||||
.clkr = {
|
||||
.enable_reg = 0x52004,
|
||||
.enable_mask = BIT(18),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_npu_gpll0_clk_src",
|
||||
.parent_hws = (const struct clk_hw *[]){
|
||||
&gpll0.clkr.hw },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_npu_gpll0_div_clk_src = {
|
||||
.clkr = {
|
||||
.enable_reg = 0x52004,
|
||||
.enable_mask = BIT(19),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_npu_gpll0_div_clk_src",
|
||||
.parent_hws = (const struct clk_hw *[]){
|
||||
&gcc_npu_gpll0_clk_src.clkr.hw },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_npu_trig_clk = {
|
||||
.halt_reg = 0x4d00c,
|
||||
.halt_check = BRANCH_VOTED,
|
||||
@ -2813,6 +2873,45 @@ static struct clk_branch gcc_ufs_card_phy_aux_hw_ctl_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
/* external clocks so add BRANCH_HALT_SKIP */
|
||||
static struct clk_branch gcc_ufs_card_rx_symbol_0_clk = {
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x7501c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_card_rx_symbol_0_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* external clocks so add BRANCH_HALT_SKIP */
|
||||
static struct clk_branch gcc_ufs_card_rx_symbol_1_clk = {
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x750ac,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_card_rx_symbol_1_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* external clocks so add BRANCH_HALT_SKIP */
|
||||
static struct clk_branch gcc_ufs_card_tx_symbol_0_clk = {
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x75018,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_card_tx_symbol_0_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_ufs_card_unipro_core_clk = {
|
||||
.halt_reg = 0x75058,
|
||||
.halt_check = BRANCH_HALT,
|
||||
@ -2993,6 +3092,45 @@ static struct clk_branch gcc_ufs_phy_phy_aux_hw_ctl_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
/* external clocks so add BRANCH_HALT_SKIP */
|
||||
static struct clk_branch gcc_ufs_phy_rx_symbol_0_clk = {
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x7701c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_phy_rx_symbol_0_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* external clocks so add BRANCH_HALT_SKIP */
|
||||
static struct clk_branch gcc_ufs_phy_rx_symbol_1_clk = {
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x770ac,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_phy_rx_symbol_1_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
/* external clocks so add BRANCH_HALT_SKIP */
|
||||
static struct clk_branch gcc_ufs_phy_tx_symbol_0_clk = {
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x77018,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "gcc_ufs_phy_tx_symbol_0_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_ufs_phy_unipro_core_clk = {
|
||||
.halt_reg = 0x77058,
|
||||
.halt_check = BRANCH_HALT,
|
||||
@ -3375,12 +3513,16 @@ static struct clk_regmap *gcc_sm8150_clocks[] = {
|
||||
[GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
|
||||
[GCC_GP3_CLK_SRC] = &gcc_gp3_clk_src.clkr,
|
||||
[GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
|
||||
[GCC_GPU_GPLL0_CLK_SRC] = &gcc_gpu_gpll0_clk_src.clkr,
|
||||
[GCC_GPU_GPLL0_DIV_CLK_SRC] = &gcc_gpu_gpll0_div_clk_src.clkr,
|
||||
[GCC_GPU_IREF_CLK] = &gcc_gpu_iref_clk.clkr,
|
||||
[GCC_GPU_MEMNOC_GFX_CLK] = &gcc_gpu_memnoc_gfx_clk.clkr,
|
||||
[GCC_GPU_SNOC_DVM_GFX_CLK] = &gcc_gpu_snoc_dvm_gfx_clk.clkr,
|
||||
[GCC_NPU_AT_CLK] = &gcc_npu_at_clk.clkr,
|
||||
[GCC_NPU_AXI_CLK] = &gcc_npu_axi_clk.clkr,
|
||||
[GCC_NPU_CFG_AHB_CLK] = &gcc_npu_cfg_ahb_clk.clkr,
|
||||
[GCC_NPU_GPLL0_CLK_SRC] = &gcc_npu_gpll0_clk_src.clkr,
|
||||
[GCC_NPU_GPLL0_DIV_CLK_SRC] = &gcc_npu_gpll0_div_clk_src.clkr,
|
||||
[GCC_NPU_TRIG_CLK] = &gcc_npu_trig_clk.clkr,
|
||||
[GCC_PCIE0_PHY_REFGEN_CLK] = &gcc_pcie0_phy_refgen_clk.clkr,
|
||||
[GCC_PCIE1_PHY_REFGEN_CLK] = &gcc_pcie1_phy_refgen_clk.clkr,
|
||||
@ -3485,6 +3627,9 @@ static struct clk_regmap *gcc_sm8150_clocks[] = {
|
||||
[GCC_UFS_CARD_PHY_AUX_CLK_SRC] = &gcc_ufs_card_phy_aux_clk_src.clkr,
|
||||
[GCC_UFS_CARD_PHY_AUX_HW_CTL_CLK] =
|
||||
&gcc_ufs_card_phy_aux_hw_ctl_clk.clkr,
|
||||
[GCC_UFS_CARD_RX_SYMBOL_0_CLK] = &gcc_ufs_card_rx_symbol_0_clk.clkr,
|
||||
[GCC_UFS_CARD_RX_SYMBOL_1_CLK] = &gcc_ufs_card_rx_symbol_1_clk.clkr,
|
||||
[GCC_UFS_CARD_TX_SYMBOL_0_CLK] = &gcc_ufs_card_tx_symbol_0_clk.clkr,
|
||||
[GCC_UFS_CARD_UNIPRO_CORE_CLK] = &gcc_ufs_card_unipro_core_clk.clkr,
|
||||
[GCC_UFS_CARD_UNIPRO_CORE_CLK_SRC] =
|
||||
&gcc_ufs_card_unipro_core_clk_src.clkr,
|
||||
@ -3502,6 +3647,9 @@ static struct clk_regmap *gcc_sm8150_clocks[] = {
|
||||
[GCC_UFS_PHY_PHY_AUX_CLK] = &gcc_ufs_phy_phy_aux_clk.clkr,
|
||||
[GCC_UFS_PHY_PHY_AUX_CLK_SRC] = &gcc_ufs_phy_phy_aux_clk_src.clkr,
|
||||
[GCC_UFS_PHY_PHY_AUX_HW_CTL_CLK] = &gcc_ufs_phy_phy_aux_hw_ctl_clk.clkr,
|
||||
[GCC_UFS_PHY_RX_SYMBOL_0_CLK] = &gcc_ufs_phy_rx_symbol_0_clk.clkr,
|
||||
[GCC_UFS_PHY_RX_SYMBOL_1_CLK] = &gcc_ufs_phy_rx_symbol_1_clk.clkr,
|
||||
[GCC_UFS_PHY_TX_SYMBOL_0_CLK] = &gcc_ufs_phy_tx_symbol_0_clk.clkr,
|
||||
[GCC_UFS_PHY_UNIPRO_CORE_CLK] = &gcc_ufs_phy_unipro_core_clk.clkr,
|
||||
[GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC] =
|
||||
&gcc_ufs_phy_unipro_core_clk_src.clkr,
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/pm_domain.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/slab.h>
|
||||
#include "gdsc.h"
|
||||
@ -112,6 +113,12 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status)
|
||||
int ret;
|
||||
u32 val = (status == GDSC_ON) ? 0 : SW_COLLAPSE_MASK;
|
||||
|
||||
if (status == GDSC_ON && sc->rsupply) {
|
||||
ret = regulator_enable(sc->rsupply);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -143,6 +150,13 @@ static int gdsc_toggle_logic(struct gdsc *sc, enum gdsc_status status)
|
||||
|
||||
ret = gdsc_poll_status(sc, status);
|
||||
WARN(ret, "%s status stuck at 'o%s'", sc->pd.name, status ? "ff" : "n");
|
||||
|
||||
if (!ret && status == GDSC_OFF && sc->rsupply) {
|
||||
ret = regulator_disable(sc->rsupply);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -371,6 +385,15 @@ int gdsc_register(struct gdsc_desc *desc,
|
||||
if (!data->domains)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!scs[i] || !scs[i]->supply)
|
||||
continue;
|
||||
|
||||
scs[i]->rsupply = devm_regulator_get(dev, scs[i]->supply);
|
||||
if (IS_ERR(scs[i]->rsupply))
|
||||
return PTR_ERR(scs[i]->rsupply);
|
||||
}
|
||||
|
||||
data->num_domains = num;
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!scs[i])
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/pm_domain.h>
|
||||
|
||||
struct regmap;
|
||||
struct regulator;
|
||||
struct reset_controller_dev;
|
||||
|
||||
/**
|
||||
@ -52,6 +53,9 @@ struct gdsc {
|
||||
struct reset_controller_dev *rcdev;
|
||||
unsigned int *resets;
|
||||
unsigned int reset_count;
|
||||
|
||||
const char *supply;
|
||||
struct regulator *rsupply;
|
||||
};
|
||||
|
||||
struct gdsc_desc {
|
||||
|
@ -3064,7 +3064,9 @@ static struct gdsc gpu_gx_gdsc = {
|
||||
.name = "gpu_gx",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &gpu_gdsc.pd,
|
||||
.flags = CLAMP_IO,
|
||||
.supply = "vdd-gfx",
|
||||
};
|
||||
|
||||
static struct clk_regmap *mmcc_msm8996_clocks[] = {
|
||||
|
8
drivers/clk/x86/Kconfig
Normal file
8
drivers/clk/x86/Kconfig
Normal file
@ -0,0 +1,8 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config CLK_LGM_CGU
|
||||
depends on OF && HAS_IOMEM && (X86 || COMPILE_TEST)
|
||||
select OF_EARLY_FLATTREE
|
||||
bool "Clock driver for Lightning Mountain(LGM) platform"
|
||||
help
|
||||
Clock Generation Unit(CGU) driver for Intel Lightning Mountain(LGM)
|
||||
network processor SoC.
|
@ -3,3 +3,4 @@ obj-$(CONFIG_PMC_ATOM) += clk-pmc-atom.o
|
||||
obj-$(CONFIG_X86_AMD_PLATFORM_DEVICE) += clk-st.o
|
||||
clk-x86-lpss-objs := clk-lpt.o
|
||||
obj-$(CONFIG_X86_INTEL_LPSS) += clk-x86-lpss.o
|
||||
obj-$(CONFIG_CLK_LGM_CGU) += clk-cgu.o clk-cgu-pll.o clk-lgm.o
|
||||
|
156
drivers/clk/x86/clk-cgu-pll.c
Normal file
156
drivers/clk/x86/clk-cgu-pll.c
Normal file
@ -0,0 +1,156 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation.
|
||||
* Zhu YiXin <yixin.zhu@intel.com>
|
||||
* Rahul Tanwar <rahul.tanwar@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "clk-cgu.h"
|
||||
|
||||
#define to_lgm_clk_pll(_hw) container_of(_hw, struct lgm_clk_pll, hw)
|
||||
#define PLL_REF_DIV(x) ((x) + 0x08)
|
||||
|
||||
/*
|
||||
* Calculate formula:
|
||||
* rate = (prate * mult + (prate * frac) / frac_div) / div
|
||||
*/
|
||||
static unsigned long
|
||||
lgm_pll_calc_rate(unsigned long prate, unsigned int mult,
|
||||
unsigned int div, unsigned int frac, unsigned int frac_div)
|
||||
{
|
||||
u64 crate, frate, rate64;
|
||||
|
||||
rate64 = prate;
|
||||
crate = rate64 * mult;
|
||||
frate = rate64 * frac;
|
||||
do_div(frate, frac_div);
|
||||
crate += frate;
|
||||
do_div(crate, div);
|
||||
|
||||
return crate;
|
||||
}
|
||||
|
||||
static unsigned long lgm_pll_recalc_rate(struct clk_hw *hw, unsigned long prate)
|
||||
{
|
||||
struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
|
||||
unsigned int div, mult, frac;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&pll->lock, flags);
|
||||
mult = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 0, 12);
|
||||
div = lgm_get_clk_val(pll->membase, PLL_REF_DIV(pll->reg), 18, 6);
|
||||
frac = lgm_get_clk_val(pll->membase, pll->reg, 2, 24);
|
||||
spin_unlock_irqrestore(&pll->lock, flags);
|
||||
|
||||
if (pll->type == TYPE_LJPLL)
|
||||
div *= 4;
|
||||
|
||||
return lgm_pll_calc_rate(prate, mult, div, frac, BIT(24));
|
||||
}
|
||||
|
||||
static int lgm_pll_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
|
||||
unsigned long flags;
|
||||
unsigned int ret;
|
||||
|
||||
spin_lock_irqsave(&pll->lock, flags);
|
||||
ret = lgm_get_clk_val(pll->membase, pll->reg, 0, 1);
|
||||
spin_unlock_irqrestore(&pll->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lgm_pll_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&pll->lock, flags);
|
||||
lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 1);
|
||||
ret = readl_poll_timeout_atomic(pll->membase + pll->reg,
|
||||
val, (val & 0x1), 1, 100);
|
||||
spin_unlock_irqrestore(&pll->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lgm_pll_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct lgm_clk_pll *pll = to_lgm_clk_pll(hw);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&pll->lock, flags);
|
||||
lgm_set_clk_val(pll->membase, pll->reg, 0, 1, 0);
|
||||
spin_unlock_irqrestore(&pll->lock, flags);
|
||||
}
|
||||
|
||||
static const struct clk_ops lgm_pll_ops = {
|
||||
.recalc_rate = lgm_pll_recalc_rate,
|
||||
.is_enabled = lgm_pll_is_enabled,
|
||||
.enable = lgm_pll_enable,
|
||||
.disable = lgm_pll_disable,
|
||||
};
|
||||
|
||||
static struct clk_hw *
|
||||
lgm_clk_register_pll(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_pll_clk_data *list)
|
||||
{
|
||||
struct clk_init_data init = {};
|
||||
struct lgm_clk_pll *pll;
|
||||
struct device *dev = ctx->dev;
|
||||
struct clk_hw *hw;
|
||||
int ret;
|
||||
|
||||
init.ops = &lgm_pll_ops;
|
||||
init.name = list->name;
|
||||
init.flags = list->flags;
|
||||
init.parent_data = list->parent_data;
|
||||
init.num_parents = list->num_parents;
|
||||
|
||||
pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
|
||||
if (!pll)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
pll->membase = ctx->membase;
|
||||
pll->lock = ctx->lock;
|
||||
pll->reg = list->reg;
|
||||
pll->flags = list->flags;
|
||||
pll->type = list->type;
|
||||
pll->hw.init = &init;
|
||||
|
||||
hw = &pll->hw;
|
||||
ret = clk_hw_register(dev, hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return hw;
|
||||
}
|
||||
|
||||
int lgm_clk_register_plls(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_pll_clk_data *list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nr_clk; i++, list++) {
|
||||
hw = lgm_clk_register_pll(ctx, list);
|
||||
if (IS_ERR(hw)) {
|
||||
dev_err(ctx->dev, "failed to register pll: %s\n",
|
||||
list->name);
|
||||
return PTR_ERR(hw);
|
||||
}
|
||||
ctx->clk_data.hws[list->id] = hw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
636
drivers/clk/x86/clk-cgu.c
Normal file
636
drivers/clk/x86/clk-cgu.c
Normal file
@ -0,0 +1,636 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation.
|
||||
* Zhu YiXin <yixin.zhu@intel.com>
|
||||
* Rahul Tanwar <rahul.tanwar@intel.com>
|
||||
*/
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "clk-cgu.h"
|
||||
|
||||
#define GATE_HW_REG_STAT(reg) ((reg) + 0x0)
|
||||
#define GATE_HW_REG_EN(reg) ((reg) + 0x4)
|
||||
#define GATE_HW_REG_DIS(reg) ((reg) + 0x8)
|
||||
#define MAX_DDIV_REG 8
|
||||
#define MAX_DIVIDER_VAL 64
|
||||
|
||||
#define to_lgm_clk_mux(_hw) container_of(_hw, struct lgm_clk_mux, hw)
|
||||
#define to_lgm_clk_divider(_hw) container_of(_hw, struct lgm_clk_divider, hw)
|
||||
#define to_lgm_clk_gate(_hw) container_of(_hw, struct lgm_clk_gate, hw)
|
||||
#define to_lgm_clk_ddiv(_hw) container_of(_hw, struct lgm_clk_ddiv, hw)
|
||||
|
||||
static struct clk_hw *lgm_clk_register_fixed(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_clk_branch *list)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (list->div_flags & CLOCK_FLAG_VAL_INIT) {
|
||||
spin_lock_irqsave(&ctx->lock, flags);
|
||||
lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift,
|
||||
list->div_width, list->div_val);
|
||||
spin_unlock_irqrestore(&ctx->lock, flags);
|
||||
}
|
||||
|
||||
return clk_hw_register_fixed_rate(NULL, list->name,
|
||||
list->parent_data[0].name,
|
||||
list->flags, list->mux_flags);
|
||||
}
|
||||
|
||||
static u8 lgm_clk_mux_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&mux->lock, flags);
|
||||
if (mux->flags & MUX_CLK_SW)
|
||||
val = mux->reg;
|
||||
else
|
||||
val = lgm_get_clk_val(mux->membase, mux->reg, mux->shift,
|
||||
mux->width);
|
||||
spin_unlock_irqrestore(&mux->lock, flags);
|
||||
return clk_mux_val_to_index(hw, NULL, mux->flags, val);
|
||||
}
|
||||
|
||||
static int lgm_clk_mux_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
val = clk_mux_index_to_val(NULL, mux->flags, index);
|
||||
spin_lock_irqsave(&mux->lock, flags);
|
||||
if (mux->flags & MUX_CLK_SW)
|
||||
mux->reg = val;
|
||||
else
|
||||
lgm_set_clk_val(mux->membase, mux->reg, mux->shift,
|
||||
mux->width, val);
|
||||
spin_unlock_irqrestore(&mux->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lgm_clk_mux_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
|
||||
|
||||
return clk_mux_determine_rate_flags(hw, req, mux->flags);
|
||||
}
|
||||
|
||||
static const struct clk_ops lgm_clk_mux_ops = {
|
||||
.get_parent = lgm_clk_mux_get_parent,
|
||||
.set_parent = lgm_clk_mux_set_parent,
|
||||
.determine_rate = lgm_clk_mux_determine_rate,
|
||||
};
|
||||
|
||||
static struct clk_hw *
|
||||
lgm_clk_register_mux(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_clk_branch *list)
|
||||
{
|
||||
unsigned long flags, cflags = list->mux_flags;
|
||||
struct device *dev = ctx->dev;
|
||||
u8 shift = list->mux_shift;
|
||||
u8 width = list->mux_width;
|
||||
struct clk_init_data init = {};
|
||||
struct lgm_clk_mux *mux;
|
||||
u32 reg = list->mux_off;
|
||||
struct clk_hw *hw;
|
||||
int ret;
|
||||
|
||||
mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
|
||||
if (!mux)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = list->name;
|
||||
init.ops = &lgm_clk_mux_ops;
|
||||
init.flags = list->flags;
|
||||
init.parent_data = list->parent_data;
|
||||
init.num_parents = list->num_parents;
|
||||
|
||||
mux->membase = ctx->membase;
|
||||
mux->lock = ctx->lock;
|
||||
mux->reg = reg;
|
||||
mux->shift = shift;
|
||||
mux->width = width;
|
||||
mux->flags = cflags;
|
||||
mux->hw.init = &init;
|
||||
|
||||
hw = &mux->hw;
|
||||
ret = clk_hw_register(dev, hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (cflags & CLOCK_FLAG_VAL_INIT) {
|
||||
spin_lock_irqsave(&mux->lock, flags);
|
||||
lgm_set_clk_val(mux->membase, reg, shift, width, list->mux_val);
|
||||
spin_unlock_irqrestore(&mux->lock, flags);
|
||||
}
|
||||
|
||||
return hw;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
lgm_clk_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
|
||||
unsigned long flags;
|
||||
unsigned int val;
|
||||
|
||||
spin_lock_irqsave(÷r->lock, flags);
|
||||
val = lgm_get_clk_val(divider->membase, divider->reg,
|
||||
divider->shift, divider->width);
|
||||
spin_unlock_irqrestore(÷r->lock, flags);
|
||||
|
||||
return divider_recalc_rate(hw, parent_rate, val, divider->table,
|
||||
divider->flags, divider->width);
|
||||
}
|
||||
|
||||
static long
|
||||
lgm_clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
|
||||
|
||||
return divider_round_rate(hw, rate, prate, divider->table,
|
||||
divider->width, divider->flags);
|
||||
}
|
||||
|
||||
static int
|
||||
lgm_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
|
||||
unsigned long flags;
|
||||
int value;
|
||||
|
||||
value = divider_get_val(rate, prate, divider->table,
|
||||
divider->width, divider->flags);
|
||||
if (value < 0)
|
||||
return value;
|
||||
|
||||
spin_lock_irqsave(÷r->lock, flags);
|
||||
lgm_set_clk_val(divider->membase, divider->reg,
|
||||
divider->shift, divider->width, value);
|
||||
spin_unlock_irqrestore(÷r->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lgm_clk_divider_enable_disable(struct clk_hw *hw, int enable)
|
||||
{
|
||||
struct lgm_clk_divider *div = to_lgm_clk_divider(hw);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&div->lock, flags);
|
||||
lgm_set_clk_val(div->membase, div->reg, div->shift_gate,
|
||||
div->width_gate, enable);
|
||||
spin_unlock_irqrestore(&div->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lgm_clk_divider_enable(struct clk_hw *hw)
|
||||
{
|
||||
return lgm_clk_divider_enable_disable(hw, 1);
|
||||
}
|
||||
|
||||
static void lgm_clk_divider_disable(struct clk_hw *hw)
|
||||
{
|
||||
lgm_clk_divider_enable_disable(hw, 0);
|
||||
}
|
||||
|
||||
static const struct clk_ops lgm_clk_divider_ops = {
|
||||
.recalc_rate = lgm_clk_divider_recalc_rate,
|
||||
.round_rate = lgm_clk_divider_round_rate,
|
||||
.set_rate = lgm_clk_divider_set_rate,
|
||||
.enable = lgm_clk_divider_enable,
|
||||
.disable = lgm_clk_divider_disable,
|
||||
};
|
||||
|
||||
static struct clk_hw *
|
||||
lgm_clk_register_divider(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_clk_branch *list)
|
||||
{
|
||||
unsigned long flags, cflags = list->div_flags;
|
||||
struct device *dev = ctx->dev;
|
||||
struct lgm_clk_divider *div;
|
||||
struct clk_init_data init = {};
|
||||
u8 shift = list->div_shift;
|
||||
u8 width = list->div_width;
|
||||
u8 shift_gate = list->div_shift_gate;
|
||||
u8 width_gate = list->div_width_gate;
|
||||
u32 reg = list->div_off;
|
||||
struct clk_hw *hw;
|
||||
int ret;
|
||||
|
||||
div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
|
||||
if (!div)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = list->name;
|
||||
init.ops = &lgm_clk_divider_ops;
|
||||
init.flags = list->flags;
|
||||
init.parent_data = list->parent_data;
|
||||
init.num_parents = 1;
|
||||
|
||||
div->membase = ctx->membase;
|
||||
div->lock = ctx->lock;
|
||||
div->reg = reg;
|
||||
div->shift = shift;
|
||||
div->width = width;
|
||||
div->shift_gate = shift_gate;
|
||||
div->width_gate = width_gate;
|
||||
div->flags = cflags;
|
||||
div->table = list->div_table;
|
||||
div->hw.init = &init;
|
||||
|
||||
hw = &div->hw;
|
||||
ret = clk_hw_register(dev, hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (cflags & CLOCK_FLAG_VAL_INIT) {
|
||||
spin_lock_irqsave(&div->lock, flags);
|
||||
lgm_set_clk_val(div->membase, reg, shift, width, list->div_val);
|
||||
spin_unlock_irqrestore(&div->lock, flags);
|
||||
}
|
||||
|
||||
return hw;
|
||||
}
|
||||
|
||||
static struct clk_hw *
|
||||
lgm_clk_register_fixed_factor(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_clk_branch *list)
|
||||
{
|
||||
unsigned long flags;
|
||||
struct clk_hw *hw;
|
||||
|
||||
hw = clk_hw_register_fixed_factor(ctx->dev, list->name,
|
||||
list->parent_data[0].name, list->flags,
|
||||
list->mult, list->div);
|
||||
if (IS_ERR(hw))
|
||||
return ERR_CAST(hw);
|
||||
|
||||
if (list->div_flags & CLOCK_FLAG_VAL_INIT) {
|
||||
spin_lock_irqsave(&ctx->lock, flags);
|
||||
lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift,
|
||||
list->div_width, list->div_val);
|
||||
spin_unlock_irqrestore(&ctx->lock, flags);
|
||||
}
|
||||
|
||||
return hw;
|
||||
}
|
||||
|
||||
static int lgm_clk_gate_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
|
||||
unsigned long flags;
|
||||
unsigned int reg;
|
||||
|
||||
spin_lock_irqsave(&gate->lock, flags);
|
||||
reg = GATE_HW_REG_EN(gate->reg);
|
||||
lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1);
|
||||
spin_unlock_irqrestore(&gate->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lgm_clk_gate_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
|
||||
unsigned long flags;
|
||||
unsigned int reg;
|
||||
|
||||
spin_lock_irqsave(&gate->lock, flags);
|
||||
reg = GATE_HW_REG_DIS(gate->reg);
|
||||
lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1);
|
||||
spin_unlock_irqrestore(&gate->lock, flags);
|
||||
}
|
||||
|
||||
static int lgm_clk_gate_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
|
||||
unsigned int reg, ret;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&gate->lock, flags);
|
||||
reg = GATE_HW_REG_STAT(gate->reg);
|
||||
ret = lgm_get_clk_val(gate->membase, reg, gate->shift, 1);
|
||||
spin_unlock_irqrestore(&gate->lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct clk_ops lgm_clk_gate_ops = {
|
||||
.enable = lgm_clk_gate_enable,
|
||||
.disable = lgm_clk_gate_disable,
|
||||
.is_enabled = lgm_clk_gate_is_enabled,
|
||||
};
|
||||
|
||||
static struct clk_hw *
|
||||
lgm_clk_register_gate(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_clk_branch *list)
|
||||
{
|
||||
unsigned long flags, cflags = list->gate_flags;
|
||||
const char *pname = list->parent_data[0].name;
|
||||
struct device *dev = ctx->dev;
|
||||
u8 shift = list->gate_shift;
|
||||
struct clk_init_data init = {};
|
||||
struct lgm_clk_gate *gate;
|
||||
u32 reg = list->gate_off;
|
||||
struct clk_hw *hw;
|
||||
int ret;
|
||||
|
||||
gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = list->name;
|
||||
init.ops = &lgm_clk_gate_ops;
|
||||
init.flags = list->flags;
|
||||
init.parent_names = pname ? &pname : NULL;
|
||||
init.num_parents = pname ? 1 : 0;
|
||||
|
||||
gate->membase = ctx->membase;
|
||||
gate->lock = ctx->lock;
|
||||
gate->reg = reg;
|
||||
gate->shift = shift;
|
||||
gate->flags = cflags;
|
||||
gate->hw.init = &init;
|
||||
|
||||
hw = &gate->hw;
|
||||
ret = clk_hw_register(dev, hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
if (cflags & CLOCK_FLAG_VAL_INIT) {
|
||||
spin_lock_irqsave(&gate->lock, flags);
|
||||
lgm_set_clk_val(gate->membase, reg, shift, 1, list->gate_val);
|
||||
spin_unlock_irqrestore(&gate->lock, flags);
|
||||
}
|
||||
|
||||
return hw;
|
||||
}
|
||||
|
||||
int lgm_clk_register_branches(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_clk_branch *list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
struct clk_hw *hw;
|
||||
unsigned int idx;
|
||||
|
||||
for (idx = 0; idx < nr_clk; idx++, list++) {
|
||||
switch (list->type) {
|
||||
case CLK_TYPE_FIXED:
|
||||
hw = lgm_clk_register_fixed(ctx, list);
|
||||
break;
|
||||
case CLK_TYPE_MUX:
|
||||
hw = lgm_clk_register_mux(ctx, list);
|
||||
break;
|
||||
case CLK_TYPE_DIVIDER:
|
||||
hw = lgm_clk_register_divider(ctx, list);
|
||||
break;
|
||||
case CLK_TYPE_FIXED_FACTOR:
|
||||
hw = lgm_clk_register_fixed_factor(ctx, list);
|
||||
break;
|
||||
case CLK_TYPE_GATE:
|
||||
hw = lgm_clk_register_gate(ctx, list);
|
||||
break;
|
||||
default:
|
||||
dev_err(ctx->dev, "invalid clk type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (IS_ERR(hw)) {
|
||||
dev_err(ctx->dev,
|
||||
"register clk: %s, type: %u failed!\n",
|
||||
list->name, list->type);
|
||||
return -EIO;
|
||||
}
|
||||
ctx->clk_data.hws[list->id] = hw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
lgm_clk_ddiv_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
|
||||
unsigned int div0, div1, exdiv;
|
||||
unsigned long flags;
|
||||
u64 prate;
|
||||
|
||||
spin_lock_irqsave(&ddiv->lock, flags);
|
||||
div0 = lgm_get_clk_val(ddiv->membase, ddiv->reg,
|
||||
ddiv->shift0, ddiv->width0) + 1;
|
||||
div1 = lgm_get_clk_val(ddiv->membase, ddiv->reg,
|
||||
ddiv->shift1, ddiv->width1) + 1;
|
||||
exdiv = lgm_get_clk_val(ddiv->membase, ddiv->reg,
|
||||
ddiv->shift2, ddiv->width2);
|
||||
spin_unlock_irqrestore(&ddiv->lock, flags);
|
||||
|
||||
prate = (u64)parent_rate;
|
||||
do_div(prate, div0);
|
||||
do_div(prate, div1);
|
||||
|
||||
if (exdiv) {
|
||||
do_div(prate, ddiv->div);
|
||||
prate *= ddiv->mult;
|
||||
}
|
||||
|
||||
return prate;
|
||||
}
|
||||
|
||||
static int lgm_clk_ddiv_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ddiv->lock, flags);
|
||||
lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate,
|
||||
ddiv->width_gate, 1);
|
||||
spin_unlock_irqrestore(&ddiv->lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void lgm_clk_ddiv_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&ddiv->lock, flags);
|
||||
lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate,
|
||||
ddiv->width_gate, 0);
|
||||
spin_unlock_irqrestore(&ddiv->lock, flags);
|
||||
}
|
||||
|
||||
static int
|
||||
lgm_clk_get_ddiv_val(u32 div, u32 *ddiv1, u32 *ddiv2)
|
||||
{
|
||||
u32 idx, temp;
|
||||
|
||||
*ddiv1 = 1;
|
||||
*ddiv2 = 1;
|
||||
|
||||
if (div > MAX_DIVIDER_VAL)
|
||||
div = MAX_DIVIDER_VAL;
|
||||
|
||||
if (div > 1) {
|
||||
for (idx = 2; idx <= MAX_DDIV_REG; idx++) {
|
||||
temp = DIV_ROUND_UP_ULL((u64)div, idx);
|
||||
if (div % idx == 0 && temp <= MAX_DDIV_REG)
|
||||
break;
|
||||
}
|
||||
|
||||
if (idx > MAX_DDIV_REG)
|
||||
return -EINVAL;
|
||||
|
||||
*ddiv1 = temp;
|
||||
*ddiv2 = idx;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
lgm_clk_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
|
||||
u32 div, ddiv1, ddiv2;
|
||||
unsigned long flags;
|
||||
|
||||
div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate);
|
||||
|
||||
spin_lock_irqsave(&ddiv->lock, flags);
|
||||
if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
|
||||
div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
|
||||
div = div * 2;
|
||||
}
|
||||
|
||||
if (div <= 0) {
|
||||
spin_unlock_irqrestore(&ddiv->lock, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2)) {
|
||||
spin_unlock_irqrestore(&ddiv->lock, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift0, ddiv->width0,
|
||||
ddiv1 - 1);
|
||||
|
||||
lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift1, ddiv->width1,
|
||||
ddiv2 - 1);
|
||||
spin_unlock_irqrestore(&ddiv->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long
|
||||
lgm_clk_ddiv_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *prate)
|
||||
{
|
||||
struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
|
||||
u32 div, ddiv1, ddiv2;
|
||||
unsigned long flags;
|
||||
u64 rate64;
|
||||
|
||||
div = DIV_ROUND_CLOSEST_ULL((u64)*prate, rate);
|
||||
|
||||
/* if predivide bit is enabled, modify div by factor of 2.5 */
|
||||
spin_lock_irqsave(&ddiv->lock, flags);
|
||||
if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
|
||||
div = div * 2;
|
||||
div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
|
||||
}
|
||||
|
||||
if (div <= 0) {
|
||||
spin_unlock_irqrestore(&ddiv->lock, flags);
|
||||
return *prate;
|
||||
}
|
||||
|
||||
if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2) != 0) {
|
||||
if (lgm_clk_get_ddiv_val(div + 1, &ddiv1, &ddiv2) != 0) {
|
||||
spin_unlock_irqrestore(&ddiv->lock, flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
rate64 = *prate;
|
||||
do_div(rate64, ddiv1);
|
||||
do_div(rate64, ddiv2);
|
||||
|
||||
/* if predivide bit is enabled, modify rounded rate by factor of 2.5 */
|
||||
if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
|
||||
rate64 = rate64 * 2;
|
||||
rate64 = DIV_ROUND_CLOSEST_ULL(rate64, 5);
|
||||
}
|
||||
spin_unlock_irqrestore(&ddiv->lock, flags);
|
||||
|
||||
return rate64;
|
||||
}
|
||||
|
||||
static const struct clk_ops lgm_clk_ddiv_ops = {
|
||||
.recalc_rate = lgm_clk_ddiv_recalc_rate,
|
||||
.enable = lgm_clk_ddiv_enable,
|
||||
.disable = lgm_clk_ddiv_disable,
|
||||
.set_rate = lgm_clk_ddiv_set_rate,
|
||||
.round_rate = lgm_clk_ddiv_round_rate,
|
||||
};
|
||||
|
||||
int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_clk_ddiv_data *list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
struct device *dev = ctx->dev;
|
||||
struct clk_init_data init = {};
|
||||
struct lgm_clk_ddiv *ddiv;
|
||||
struct clk_hw *hw;
|
||||
unsigned int idx;
|
||||
int ret;
|
||||
|
||||
for (idx = 0; idx < nr_clk; idx++, list++) {
|
||||
ddiv = NULL;
|
||||
ddiv = devm_kzalloc(dev, sizeof(*ddiv), GFP_KERNEL);
|
||||
if (!ddiv)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(&init, 0, sizeof(init));
|
||||
init.name = list->name;
|
||||
init.ops = &lgm_clk_ddiv_ops;
|
||||
init.flags = list->flags;
|
||||
init.parent_data = list->parent_data;
|
||||
init.num_parents = 1;
|
||||
|
||||
ddiv->membase = ctx->membase;
|
||||
ddiv->lock = ctx->lock;
|
||||
ddiv->reg = list->reg;
|
||||
ddiv->shift0 = list->shift0;
|
||||
ddiv->width0 = list->width0;
|
||||
ddiv->shift1 = list->shift1;
|
||||
ddiv->width1 = list->width1;
|
||||
ddiv->shift_gate = list->shift_gate;
|
||||
ddiv->width_gate = list->width_gate;
|
||||
ddiv->shift2 = list->ex_shift;
|
||||
ddiv->width2 = list->ex_width;
|
||||
ddiv->flags = list->div_flags;
|
||||
ddiv->mult = 2;
|
||||
ddiv->div = 5;
|
||||
ddiv->hw.init = &init;
|
||||
|
||||
hw = &ddiv->hw;
|
||||
ret = clk_hw_register(dev, hw);
|
||||
if (ret) {
|
||||
dev_err(dev, "register clk: %s failed!\n", list->name);
|
||||
return ret;
|
||||
}
|
||||
ctx->clk_data.hws[list->id] = hw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
335
drivers/clk/x86/clk-cgu.h
Normal file
335
drivers/clk/x86/clk-cgu.h
Normal file
@ -0,0 +1,335 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright(c) 2020 Intel Corporation.
|
||||
* Zhu YiXin <yixin.zhu@intel.com>
|
||||
* Rahul Tanwar <rahul.tanwar@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __CLK_CGU_H
|
||||
#define __CLK_CGU_H
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
struct lgm_clk_mux {
|
||||
struct clk_hw hw;
|
||||
void __iomem *membase;
|
||||
unsigned int reg;
|
||||
u8 shift;
|
||||
u8 width;
|
||||
unsigned long flags;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
struct lgm_clk_divider {
|
||||
struct clk_hw hw;
|
||||
void __iomem *membase;
|
||||
unsigned int reg;
|
||||
u8 shift;
|
||||
u8 width;
|
||||
u8 shift_gate;
|
||||
u8 width_gate;
|
||||
unsigned long flags;
|
||||
const struct clk_div_table *table;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
struct lgm_clk_ddiv {
|
||||
struct clk_hw hw;
|
||||
void __iomem *membase;
|
||||
unsigned int reg;
|
||||
u8 shift0;
|
||||
u8 width0;
|
||||
u8 shift1;
|
||||
u8 width1;
|
||||
u8 shift2;
|
||||
u8 width2;
|
||||
u8 shift_gate;
|
||||
u8 width_gate;
|
||||
unsigned int mult;
|
||||
unsigned int div;
|
||||
unsigned long flags;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
struct lgm_clk_gate {
|
||||
struct clk_hw hw;
|
||||
void __iomem *membase;
|
||||
unsigned int reg;
|
||||
u8 shift;
|
||||
unsigned long flags;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
enum lgm_clk_type {
|
||||
CLK_TYPE_FIXED,
|
||||
CLK_TYPE_MUX,
|
||||
CLK_TYPE_DIVIDER,
|
||||
CLK_TYPE_FIXED_FACTOR,
|
||||
CLK_TYPE_GATE,
|
||||
CLK_TYPE_NONE,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct lgm_clk_provider
|
||||
* @membase: IO mem base address for CGU.
|
||||
* @np: device node
|
||||
* @dev: device
|
||||
* @clk_data: array of hw clocks and clk number.
|
||||
*/
|
||||
struct lgm_clk_provider {
|
||||
void __iomem *membase;
|
||||
struct device_node *np;
|
||||
struct device *dev;
|
||||
struct clk_hw_onecell_data clk_data;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
enum pll_type {
|
||||
TYPE_ROPLL,
|
||||
TYPE_LJPLL,
|
||||
TYPE_NONE,
|
||||
};
|
||||
|
||||
struct lgm_clk_pll {
|
||||
struct clk_hw hw;
|
||||
void __iomem *membase;
|
||||
unsigned int reg;
|
||||
unsigned long flags;
|
||||
enum pll_type type;
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct lgm_pll_clk_data
|
||||
* @id: platform specific id of the clock.
|
||||
* @name: name of this pll clock.
|
||||
* @parent_data: parent clock data.
|
||||
* @num_parents: number of parents.
|
||||
* @flags: optional flags for basic clock.
|
||||
* @type: platform type of pll.
|
||||
* @reg: offset of the register.
|
||||
*/
|
||||
struct lgm_pll_clk_data {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
const struct clk_parent_data *parent_data;
|
||||
u8 num_parents;
|
||||
unsigned long flags;
|
||||
enum pll_type type;
|
||||
int reg;
|
||||
};
|
||||
|
||||
#define LGM_PLL(_id, _name, _pdata, _flags, \
|
||||
_reg, _type) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_data = _pdata, \
|
||||
.num_parents = ARRAY_SIZE(_pdata), \
|
||||
.flags = _flags, \
|
||||
.reg = _reg, \
|
||||
.type = _type, \
|
||||
}
|
||||
|
||||
struct lgm_clk_ddiv_data {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
const struct clk_parent_data *parent_data;
|
||||
u8 flags;
|
||||
unsigned long div_flags;
|
||||
unsigned int reg;
|
||||
u8 shift0;
|
||||
u8 width0;
|
||||
u8 shift1;
|
||||
u8 width1;
|
||||
u8 shift_gate;
|
||||
u8 width_gate;
|
||||
u8 ex_shift;
|
||||
u8 ex_width;
|
||||
};
|
||||
|
||||
#define LGM_DDIV(_id, _name, _pname, _flags, _reg, \
|
||||
_shft0, _wdth0, _shft1, _wdth1, \
|
||||
_shft_gate, _wdth_gate, _xshft, _df) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_data = &(const struct clk_parent_data){ \
|
||||
.fw_name = _pname, \
|
||||
.name = _pname, \
|
||||
}, \
|
||||
.flags = _flags, \
|
||||
.reg = _reg, \
|
||||
.shift0 = _shft0, \
|
||||
.width0 = _wdth0, \
|
||||
.shift1 = _shft1, \
|
||||
.width1 = _wdth1, \
|
||||
.shift_gate = _shft_gate, \
|
||||
.width_gate = _wdth_gate, \
|
||||
.ex_shift = _xshft, \
|
||||
.ex_width = 1, \
|
||||
.div_flags = _df, \
|
||||
}
|
||||
|
||||
struct lgm_clk_branch {
|
||||
unsigned int id;
|
||||
enum lgm_clk_type type;
|
||||
const char *name;
|
||||
const struct clk_parent_data *parent_data;
|
||||
u8 num_parents;
|
||||
unsigned long flags;
|
||||
unsigned int mux_off;
|
||||
u8 mux_shift;
|
||||
u8 mux_width;
|
||||
unsigned long mux_flags;
|
||||
unsigned int mux_val;
|
||||
unsigned int div_off;
|
||||
u8 div_shift;
|
||||
u8 div_width;
|
||||
u8 div_shift_gate;
|
||||
u8 div_width_gate;
|
||||
unsigned long div_flags;
|
||||
unsigned int div_val;
|
||||
const struct clk_div_table *div_table;
|
||||
unsigned int gate_off;
|
||||
u8 gate_shift;
|
||||
unsigned long gate_flags;
|
||||
unsigned int gate_val;
|
||||
unsigned int mult;
|
||||
unsigned int div;
|
||||
};
|
||||
|
||||
/* clock flags definition */
|
||||
#define CLOCK_FLAG_VAL_INIT BIT(16)
|
||||
#define MUX_CLK_SW BIT(17)
|
||||
|
||||
#define LGM_MUX(_id, _name, _pdata, _f, _reg, \
|
||||
_shift, _width, _cf, _v) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.type = CLK_TYPE_MUX, \
|
||||
.name = _name, \
|
||||
.parent_data = _pdata, \
|
||||
.num_parents = ARRAY_SIZE(_pdata), \
|
||||
.flags = _f, \
|
||||
.mux_off = _reg, \
|
||||
.mux_shift = _shift, \
|
||||
.mux_width = _width, \
|
||||
.mux_flags = _cf, \
|
||||
.mux_val = _v, \
|
||||
}
|
||||
|
||||
#define LGM_DIV(_id, _name, _pname, _f, _reg, _shift, _width, \
|
||||
_shift_gate, _width_gate, _cf, _v, _dtable) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.type = CLK_TYPE_DIVIDER, \
|
||||
.name = _name, \
|
||||
.parent_data = &(const struct clk_parent_data){ \
|
||||
.fw_name = _pname, \
|
||||
.name = _pname, \
|
||||
}, \
|
||||
.num_parents = 1, \
|
||||
.flags = _f, \
|
||||
.div_off = _reg, \
|
||||
.div_shift = _shift, \
|
||||
.div_width = _width, \
|
||||
.div_shift_gate = _shift_gate, \
|
||||
.div_width_gate = _width_gate, \
|
||||
.div_flags = _cf, \
|
||||
.div_val = _v, \
|
||||
.div_table = _dtable, \
|
||||
}
|
||||
|
||||
#define LGM_GATE(_id, _name, _pname, _f, _reg, \
|
||||
_shift, _cf, _v) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.type = CLK_TYPE_GATE, \
|
||||
.name = _name, \
|
||||
.parent_data = &(const struct clk_parent_data){ \
|
||||
.fw_name = _pname, \
|
||||
.name = _pname, \
|
||||
}, \
|
||||
.num_parents = !_pname ? 0 : 1, \
|
||||
.flags = _f, \
|
||||
.gate_off = _reg, \
|
||||
.gate_shift = _shift, \
|
||||
.gate_flags = _cf, \
|
||||
.gate_val = _v, \
|
||||
}
|
||||
|
||||
#define LGM_FIXED(_id, _name, _pname, _f, _reg, \
|
||||
_shift, _width, _cf, _freq, _v) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.type = CLK_TYPE_FIXED, \
|
||||
.name = _name, \
|
||||
.parent_data = &(const struct clk_parent_data){ \
|
||||
.fw_name = _pname, \
|
||||
.name = _pname, \
|
||||
}, \
|
||||
.num_parents = !_pname ? 0 : 1, \
|
||||
.flags = _f, \
|
||||
.div_off = _reg, \
|
||||
.div_shift = _shift, \
|
||||
.div_width = _width, \
|
||||
.div_flags = _cf, \
|
||||
.div_val = _v, \
|
||||
.mux_flags = _freq, \
|
||||
}
|
||||
|
||||
#define LGM_FIXED_FACTOR(_id, _name, _pname, _f, _reg, \
|
||||
_shift, _width, _cf, _v, _m, _d) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.type = CLK_TYPE_FIXED_FACTOR, \
|
||||
.name = _name, \
|
||||
.parent_data = &(const struct clk_parent_data){ \
|
||||
.fw_name = _pname, \
|
||||
.name = _pname, \
|
||||
}, \
|
||||
.num_parents = 1, \
|
||||
.flags = _f, \
|
||||
.div_off = _reg, \
|
||||
.div_shift = _shift, \
|
||||
.div_width = _width, \
|
||||
.div_flags = _cf, \
|
||||
.div_val = _v, \
|
||||
.mult = _m, \
|
||||
.div = _d, \
|
||||
}
|
||||
|
||||
static inline void lgm_set_clk_val(void __iomem *membase, u32 reg,
|
||||
u8 shift, u8 width, u32 set_val)
|
||||
{
|
||||
u32 mask = (GENMASK(width - 1, 0) << shift);
|
||||
u32 regval;
|
||||
|
||||
regval = readl(membase + reg);
|
||||
regval = (regval & ~mask) | ((set_val << shift) & mask);
|
||||
writel(regval, membase + reg);
|
||||
}
|
||||
|
||||
static inline u32 lgm_get_clk_val(void __iomem *membase, u32 reg,
|
||||
u8 shift, u8 width)
|
||||
{
|
||||
u32 mask = (GENMASK(width - 1, 0) << shift);
|
||||
u32 val;
|
||||
|
||||
val = readl(membase + reg);
|
||||
val = (val & mask) >> shift;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
int lgm_clk_register_branches(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_clk_branch *list,
|
||||
unsigned int nr_clk);
|
||||
int lgm_clk_register_plls(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_pll_clk_data *list,
|
||||
unsigned int nr_clk);
|
||||
int lgm_clk_register_ddiv(struct lgm_clk_provider *ctx,
|
||||
const struct lgm_clk_ddiv_data *list,
|
||||
unsigned int nr_clk);
|
||||
#endif /* __CLK_CGU_H */
|
475
drivers/clk/x86/clk-lgm.c
Normal file
475
drivers/clk/x86/clk-lgm.c
Normal file
@ -0,0 +1,475 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation.
|
||||
* Zhu YiXin <yixin.zhu@intel.com>
|
||||
* Rahul Tanwar <rahul.tanwar@intel.com>
|
||||
*/
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <dt-bindings/clock/intel,lgm-clk.h>
|
||||
#include "clk-cgu.h"
|
||||
|
||||
#define PLL_DIV_WIDTH 4
|
||||
#define PLL_DDIV_WIDTH 3
|
||||
|
||||
/* Gate0 clock shift */
|
||||
#define G_C55_SHIFT 7
|
||||
#define G_QSPI_SHIFT 9
|
||||
#define G_EIP197_SHIFT 11
|
||||
#define G_VAULT130_SHIFT 12
|
||||
#define G_TOE_SHIFT 13
|
||||
#define G_SDXC_SHIFT 14
|
||||
#define G_EMMC_SHIFT 15
|
||||
#define G_SPIDBG_SHIFT 17
|
||||
#define G_DMA3_SHIFT 28
|
||||
|
||||
/* Gate1 clock shift */
|
||||
#define G_DMA0_SHIFT 0
|
||||
#define G_LEDC0_SHIFT 1
|
||||
#define G_LEDC1_SHIFT 2
|
||||
#define G_I2S0_SHIFT 3
|
||||
#define G_I2S1_SHIFT 4
|
||||
#define G_EBU_SHIFT 5
|
||||
#define G_PWM_SHIFT 6
|
||||
#define G_I2C0_SHIFT 7
|
||||
#define G_I2C1_SHIFT 8
|
||||
#define G_I2C2_SHIFT 9
|
||||
#define G_I2C3_SHIFT 10
|
||||
|
||||
#define G_SSC0_SHIFT 12
|
||||
#define G_SSC1_SHIFT 13
|
||||
#define G_SSC2_SHIFT 14
|
||||
#define G_SSC3_SHIFT 15
|
||||
|
||||
#define G_GPTC0_SHIFT 17
|
||||
#define G_GPTC1_SHIFT 18
|
||||
#define G_GPTC2_SHIFT 19
|
||||
#define G_GPTC3_SHIFT 20
|
||||
|
||||
#define G_ASC0_SHIFT 22
|
||||
#define G_ASC1_SHIFT 23
|
||||
#define G_ASC2_SHIFT 24
|
||||
#define G_ASC3_SHIFT 25
|
||||
|
||||
#define G_PCM0_SHIFT 27
|
||||
#define G_PCM1_SHIFT 28
|
||||
#define G_PCM2_SHIFT 29
|
||||
|
||||
/* Gate2 clock shift */
|
||||
#define G_PCIE10_SHIFT 1
|
||||
#define G_PCIE11_SHIFT 2
|
||||
#define G_PCIE30_SHIFT 3
|
||||
#define G_PCIE31_SHIFT 4
|
||||
#define G_PCIE20_SHIFT 5
|
||||
#define G_PCIE21_SHIFT 6
|
||||
#define G_PCIE40_SHIFT 7
|
||||
#define G_PCIE41_SHIFT 8
|
||||
|
||||
#define G_XPCS0_SHIFT 10
|
||||
#define G_XPCS1_SHIFT 11
|
||||
#define G_XPCS2_SHIFT 12
|
||||
#define G_XPCS3_SHIFT 13
|
||||
#define G_SATA0_SHIFT 14
|
||||
#define G_SATA1_SHIFT 15
|
||||
#define G_SATA2_SHIFT 16
|
||||
#define G_SATA3_SHIFT 17
|
||||
|
||||
/* Gate3 clock shift */
|
||||
#define G_ARCEM4_SHIFT 0
|
||||
#define G_IDMAR1_SHIFT 2
|
||||
#define G_IDMAT0_SHIFT 3
|
||||
#define G_IDMAT1_SHIFT 4
|
||||
#define G_IDMAT2_SHIFT 5
|
||||
|
||||
#define G_PPV4_SHIFT 8
|
||||
#define G_GSWIPO_SHIFT 9
|
||||
#define G_CQEM_SHIFT 10
|
||||
#define G_XPCS5_SHIFT 14
|
||||
#define G_USB1_SHIFT 25
|
||||
#define G_USB2_SHIFT 26
|
||||
|
||||
|
||||
/* Register definition */
|
||||
#define CGU_PLL0CZ_CFG0 0x000
|
||||
#define CGU_PLL0CM0_CFG0 0x020
|
||||
#define CGU_PLL0CM1_CFG0 0x040
|
||||
#define CGU_PLL0B_CFG0 0x060
|
||||
#define CGU_PLL1_CFG0 0x080
|
||||
#define CGU_PLL2_CFG0 0x0A0
|
||||
#define CGU_PLLPP_CFG0 0x0C0
|
||||
#define CGU_LJPLL3_CFG0 0x0E0
|
||||
#define CGU_LJPLL4_CFG0 0x100
|
||||
#define CGU_C55_PCMCR 0x18C
|
||||
#define CGU_PCMCR 0x190
|
||||
#define CGU_IF_CLK1 0x1A0
|
||||
#define CGU_IF_CLK2 0x1A4
|
||||
#define CGU_GATE0 0x300
|
||||
#define CGU_GATE1 0x310
|
||||
#define CGU_GATE2 0x320
|
||||
#define CGU_GATE3 0x310
|
||||
|
||||
#define PLL_DIV(x) ((x) + 0x04)
|
||||
#define PLL_SSC(x) ((x) + 0x10)
|
||||
|
||||
#define CLK_NR_CLKS (LGM_GCLK_USB2 + 1)
|
||||
|
||||
/*
|
||||
* Below table defines the pair's of regval & effective dividers.
|
||||
* It's more efficient to provide an explicit table due to non-linear
|
||||
* relation between values.
|
||||
*/
|
||||
static const struct clk_div_table pll_div[] = {
|
||||
{ .val = 0, .div = 1 },
|
||||
{ .val = 1, .div = 2 },
|
||||
{ .val = 2, .div = 3 },
|
||||
{ .val = 3, .div = 4 },
|
||||
{ .val = 4, .div = 5 },
|
||||
{ .val = 5, .div = 6 },
|
||||
{ .val = 6, .div = 8 },
|
||||
{ .val = 7, .div = 10 },
|
||||
{ .val = 8, .div = 12 },
|
||||
{ .val = 9, .div = 16 },
|
||||
{ .val = 10, .div = 20 },
|
||||
{ .val = 11, .div = 24 },
|
||||
{ .val = 12, .div = 32 },
|
||||
{ .val = 13, .div = 40 },
|
||||
{ .val = 14, .div = 48 },
|
||||
{ .val = 15, .div = 64 },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct clk_div_table dcl_div[] = {
|
||||
{ .val = 0, .div = 6 },
|
||||
{ .val = 1, .div = 12 },
|
||||
{ .val = 2, .div = 24 },
|
||||
{ .val = 3, .div = 32 },
|
||||
{ .val = 4, .div = 48 },
|
||||
{ .val = 5, .div = 96 },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct clk_parent_data pll_p[] = {
|
||||
{ .fw_name = "osc", .name = "osc" },
|
||||
};
|
||||
static const struct clk_parent_data pllcm_p[] = {
|
||||
{ .fw_name = "cpu_cm", .name = "cpu_cm" },
|
||||
};
|
||||
static const struct clk_parent_data emmc_p[] = {
|
||||
{ .fw_name = "emmc4", .name = "emmc4" },
|
||||
{ .fw_name = "noc4", .name = "noc4" },
|
||||
};
|
||||
static const struct clk_parent_data sdxc_p[] = {
|
||||
{ .fw_name = "sdxc3", .name = "sdxc3" },
|
||||
{ .fw_name = "sdxc2", .name = "sdxc2" },
|
||||
};
|
||||
static const struct clk_parent_data pcm_p[] = {
|
||||
{ .fw_name = "v_docsis", .name = "v_docsis" },
|
||||
{ .fw_name = "dcl", .name = "dcl" },
|
||||
};
|
||||
static const struct clk_parent_data cbphy_p[] = {
|
||||
{ .fw_name = "dd_serdes", .name = "dd_serdes" },
|
||||
{ .fw_name = "dd_pcie", .name = "dd_pcie" },
|
||||
};
|
||||
|
||||
static const struct lgm_pll_clk_data lgm_pll_clks[] = {
|
||||
LGM_PLL(LGM_CLK_PLL0CZ, "pll0cz", pll_p, CLK_IGNORE_UNUSED,
|
||||
CGU_PLL0CZ_CFG0, TYPE_ROPLL),
|
||||
LGM_PLL(LGM_CLK_PLL0CM0, "pll0cm0", pllcm_p, CLK_IGNORE_UNUSED,
|
||||
CGU_PLL0CM0_CFG0, TYPE_ROPLL),
|
||||
LGM_PLL(LGM_CLK_PLL0CM1, "pll0cm1", pllcm_p, CLK_IGNORE_UNUSED,
|
||||
CGU_PLL0CM1_CFG0, TYPE_ROPLL),
|
||||
LGM_PLL(LGM_CLK_PLL0B, "pll0b", pll_p, CLK_IGNORE_UNUSED,
|
||||
CGU_PLL0B_CFG0, TYPE_ROPLL),
|
||||
LGM_PLL(LGM_CLK_PLL1, "pll1", pll_p, 0, CGU_PLL1_CFG0, TYPE_ROPLL),
|
||||
LGM_PLL(LGM_CLK_PLL2, "pll2", pll_p, CLK_IGNORE_UNUSED,
|
||||
CGU_PLL2_CFG0, TYPE_ROPLL),
|
||||
LGM_PLL(LGM_CLK_PLLPP, "pllpp", pll_p, 0, CGU_PLLPP_CFG0, TYPE_ROPLL),
|
||||
LGM_PLL(LGM_CLK_LJPLL3, "ljpll3", pll_p, 0, CGU_LJPLL3_CFG0, TYPE_LJPLL),
|
||||
LGM_PLL(LGM_CLK_LJPLL4, "ljpll4", pll_p, 0, CGU_LJPLL4_CFG0, TYPE_LJPLL),
|
||||
};
|
||||
|
||||
static const struct lgm_clk_branch lgm_branch_clks[] = {
|
||||
LGM_DIV(LGM_CLK_PP_HW, "pp_hw", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
|
||||
0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_PP_UC, "pp_uc", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
|
||||
4, PLL_DIV_WIDTH, 25, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_PP_FXD, "pp_fxd", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
|
||||
8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_PP_TBM, "pp_tbm", "pllpp", 0, PLL_DIV(CGU_PLLPP_CFG0),
|
||||
12, PLL_DIV_WIDTH, 27, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_DDR, "ddr", "pll2", CLK_IGNORE_UNUSED,
|
||||
PLL_DIV(CGU_PLL2_CFG0), 0, PLL_DIV_WIDTH, 24, 1, 0, 0,
|
||||
pll_div),
|
||||
LGM_DIV(LGM_CLK_CM, "cpu_cm", "pll0cz", 0, PLL_DIV(CGU_PLL0CZ_CFG0),
|
||||
0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
|
||||
|
||||
LGM_DIV(LGM_CLK_IC, "cpu_ic", "pll0cz", CLK_IGNORE_UNUSED,
|
||||
PLL_DIV(CGU_PLL0CZ_CFG0), 4, PLL_DIV_WIDTH, 25,
|
||||
1, 0, 0, pll_div),
|
||||
|
||||
LGM_DIV(LGM_CLK_SDXC3, "sdxc3", "pll0cz", 0, PLL_DIV(CGU_PLL0CZ_CFG0),
|
||||
8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
|
||||
|
||||
LGM_DIV(LGM_CLK_CPU0, "cm0", "pll0cm0",
|
||||
CLK_IGNORE_UNUSED, PLL_DIV(CGU_PLL0CM0_CFG0),
|
||||
0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_CPU1, "cm1", "pll0cm1",
|
||||
CLK_IGNORE_UNUSED, PLL_DIV(CGU_PLL0CM1_CFG0),
|
||||
0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
|
||||
|
||||
/*
|
||||
* Marking ngi_clk (next generation interconnect) and noc_clk
|
||||
* (network on chip peripheral clk) as critical clocks because
|
||||
* these are shared parent clock sources for many different
|
||||
* peripherals.
|
||||
*/
|
||||
LGM_DIV(LGM_CLK_NGI, "ngi", "pll0b",
|
||||
(CLK_IGNORE_UNUSED|CLK_IS_CRITICAL), PLL_DIV(CGU_PLL0B_CFG0),
|
||||
0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_NOC4, "noc4", "pll0b",
|
||||
(CLK_IGNORE_UNUSED|CLK_IS_CRITICAL), PLL_DIV(CGU_PLL0B_CFG0),
|
||||
4, PLL_DIV_WIDTH, 25, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_SW, "switch", "pll0b", 0, PLL_DIV(CGU_PLL0B_CFG0),
|
||||
8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_QSPI, "qspi", "pll0b", 0, PLL_DIV(CGU_PLL0B_CFG0),
|
||||
12, PLL_DIV_WIDTH, 27, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_CT, "v_ct", "pll1", 0, PLL_DIV(CGU_PLL1_CFG0),
|
||||
0, PLL_DIV_WIDTH, 24, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_DSP, "v_dsp", "pll1", 0, PLL_DIV(CGU_PLL1_CFG0),
|
||||
8, PLL_DIV_WIDTH, 26, 1, 0, 0, pll_div),
|
||||
LGM_DIV(LGM_CLK_VIF, "v_ifclk", "pll1", 0, PLL_DIV(CGU_PLL1_CFG0),
|
||||
12, PLL_DIV_WIDTH, 27, 1, 0, 0, pll_div),
|
||||
|
||||
LGM_FIXED_FACTOR(LGM_CLK_EMMC4, "emmc4", "sdxc3", 0, 0,
|
||||
0, 0, 0, 0, 1, 4),
|
||||
LGM_FIXED_FACTOR(LGM_CLK_SDXC2, "sdxc2", "noc4", 0, 0,
|
||||
0, 0, 0, 0, 1, 4),
|
||||
LGM_MUX(LGM_CLK_EMMC, "emmc", emmc_p, 0, CGU_IF_CLK1,
|
||||
0, 1, CLK_MUX_ROUND_CLOSEST, 0),
|
||||
LGM_MUX(LGM_CLK_SDXC, "sdxc", sdxc_p, 0, CGU_IF_CLK1,
|
||||
1, 1, CLK_MUX_ROUND_CLOSEST, 0),
|
||||
LGM_FIXED(LGM_CLK_OSC, "osc", NULL, 0, 0, 0, 0, 0, 40000000, 0),
|
||||
LGM_FIXED(LGM_CLK_SLIC, "slic", NULL, 0, CGU_IF_CLK1,
|
||||
8, 2, CLOCK_FLAG_VAL_INIT, 8192000, 2),
|
||||
LGM_FIXED(LGM_CLK_DOCSIS, "v_docsis", NULL, 0, 0, 0, 0, 0, 16000000, 0),
|
||||
LGM_DIV(LGM_CLK_DCL, "dcl", "v_ifclk", 0, CGU_PCMCR,
|
||||
25, 3, 0, 0, 0, 0, dcl_div),
|
||||
LGM_MUX(LGM_CLK_PCM, "pcm", pcm_p, 0, CGU_C55_PCMCR,
|
||||
0, 1, CLK_MUX_ROUND_CLOSEST, 0),
|
||||
LGM_FIXED_FACTOR(LGM_CLK_DDR_PHY, "ddr_phy", "ddr",
|
||||
CLK_IGNORE_UNUSED, 0,
|
||||
0, 0, 0, 0, 2, 1),
|
||||
LGM_FIXED_FACTOR(LGM_CLK_PONDEF, "pondef", "dd_pool",
|
||||
CLK_SET_RATE_PARENT, 0, 0, 0, 0, 0, 1, 2),
|
||||
LGM_MUX(LGM_CLK_CBPHY0, "cbphy0", cbphy_p, 0, 0,
|
||||
0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
|
||||
LGM_MUX(LGM_CLK_CBPHY1, "cbphy1", cbphy_p, 0, 0,
|
||||
0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
|
||||
LGM_MUX(LGM_CLK_CBPHY2, "cbphy2", cbphy_p, 0, 0,
|
||||
0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
|
||||
LGM_MUX(LGM_CLK_CBPHY3, "cbphy3", cbphy_p, 0, 0,
|
||||
0, 0, MUX_CLK_SW | CLK_MUX_ROUND_CLOSEST, 0),
|
||||
|
||||
LGM_GATE(LGM_GCLK_C55, "g_c55", NULL, 0, CGU_GATE0,
|
||||
G_C55_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_QSPI, "g_qspi", "qspi", 0, CGU_GATE0,
|
||||
G_QSPI_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_EIP197, "g_eip197", NULL, 0, CGU_GATE0,
|
||||
G_EIP197_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_VAULT, "g_vault130", NULL, 0, CGU_GATE0,
|
||||
G_VAULT130_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_TOE, "g_toe", NULL, 0, CGU_GATE0,
|
||||
G_TOE_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_SDXC, "g_sdxc", "sdxc", 0, CGU_GATE0,
|
||||
G_SDXC_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_EMMC, "g_emmc", "emmc", 0, CGU_GATE0,
|
||||
G_EMMC_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_SPI_DBG, "g_spidbg", NULL, 0, CGU_GATE0,
|
||||
G_SPIDBG_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_DMA3, "g_dma3", NULL, 0, CGU_GATE0,
|
||||
G_DMA3_SHIFT, 0, 0),
|
||||
|
||||
LGM_GATE(LGM_GCLK_DMA0, "g_dma0", NULL, 0, CGU_GATE1,
|
||||
G_DMA0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_LEDC0, "g_ledc0", NULL, 0, CGU_GATE1,
|
||||
G_LEDC0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_LEDC1, "g_ledc1", NULL, 0, CGU_GATE1,
|
||||
G_LEDC1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_I2S0, "g_i2s0", NULL, 0, CGU_GATE1,
|
||||
G_I2S0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_I2S1, "g_i2s1", NULL, 0, CGU_GATE1,
|
||||
G_I2S1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_EBU, "g_ebu", NULL, 0, CGU_GATE1,
|
||||
G_EBU_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PWM, "g_pwm", NULL, 0, CGU_GATE1,
|
||||
G_PWM_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_I2C0, "g_i2c0", NULL, 0, CGU_GATE1,
|
||||
G_I2C0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_I2C1, "g_i2c1", NULL, 0, CGU_GATE1,
|
||||
G_I2C1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_I2C2, "g_i2c2", NULL, 0, CGU_GATE1,
|
||||
G_I2C2_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_I2C3, "g_i2c3", NULL, 0, CGU_GATE1,
|
||||
G_I2C3_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_SSC0, "g_ssc0", "noc4", 0, CGU_GATE1,
|
||||
G_SSC0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_SSC1, "g_ssc1", "noc4", 0, CGU_GATE1,
|
||||
G_SSC1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_SSC2, "g_ssc2", "noc4", 0, CGU_GATE1,
|
||||
G_SSC2_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_SSC3, "g_ssc3", "noc4", 0, CGU_GATE1,
|
||||
G_SSC3_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_GPTC0, "g_gptc0", "noc4", 0, CGU_GATE1,
|
||||
G_GPTC0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_GPTC1, "g_gptc1", "noc4", 0, CGU_GATE1,
|
||||
G_GPTC1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_GPTC2, "g_gptc2", "noc4", 0, CGU_GATE1,
|
||||
G_GPTC2_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_GPTC3, "g_gptc3", "osc", 0, CGU_GATE1,
|
||||
G_GPTC3_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_ASC0, "g_asc0", "noc4", 0, CGU_GATE1,
|
||||
G_ASC0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_ASC1, "g_asc1", "noc4", 0, CGU_GATE1,
|
||||
G_ASC1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_ASC2, "g_asc2", "noc4", 0, CGU_GATE1,
|
||||
G_ASC2_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_ASC3, "g_asc3", "osc", 0, CGU_GATE1,
|
||||
G_ASC3_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PCM0, "g_pcm0", NULL, 0, CGU_GATE1,
|
||||
G_PCM0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PCM1, "g_pcm1", NULL, 0, CGU_GATE1,
|
||||
G_PCM1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PCM2, "g_pcm2", NULL, 0, CGU_GATE1,
|
||||
G_PCM2_SHIFT, 0, 0),
|
||||
|
||||
LGM_GATE(LGM_GCLK_PCIE10, "g_pcie10", NULL, 0, CGU_GATE2,
|
||||
G_PCIE10_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PCIE11, "g_pcie11", NULL, 0, CGU_GATE2,
|
||||
G_PCIE11_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PCIE30, "g_pcie30", NULL, 0, CGU_GATE2,
|
||||
G_PCIE30_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PCIE31, "g_pcie31", NULL, 0, CGU_GATE2,
|
||||
G_PCIE31_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PCIE20, "g_pcie20", NULL, 0, CGU_GATE2,
|
||||
G_PCIE20_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PCIE21, "g_pcie21", NULL, 0, CGU_GATE2,
|
||||
G_PCIE21_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PCIE40, "g_pcie40", NULL, 0, CGU_GATE2,
|
||||
G_PCIE40_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PCIE41, "g_pcie41", NULL, 0, CGU_GATE2,
|
||||
G_PCIE41_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_XPCS0, "g_xpcs0", NULL, 0, CGU_GATE2,
|
||||
G_XPCS0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_XPCS1, "g_xpcs1", NULL, 0, CGU_GATE2,
|
||||
G_XPCS1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_XPCS2, "g_xpcs2", NULL, 0, CGU_GATE2,
|
||||
G_XPCS2_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_XPCS3, "g_xpcs3", NULL, 0, CGU_GATE2,
|
||||
G_XPCS3_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_SATA0, "g_sata0", NULL, 0, CGU_GATE2,
|
||||
G_SATA0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_SATA1, "g_sata1", NULL, 0, CGU_GATE2,
|
||||
G_SATA1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_SATA2, "g_sata2", NULL, 0, CGU_GATE2,
|
||||
G_SATA2_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_SATA3, "g_sata3", NULL, 0, CGU_GATE2,
|
||||
G_SATA3_SHIFT, 0, 0),
|
||||
|
||||
LGM_GATE(LGM_GCLK_ARCEM4, "g_arcem4", NULL, 0, CGU_GATE3,
|
||||
G_ARCEM4_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_IDMAR1, "g_idmar1", NULL, 0, CGU_GATE3,
|
||||
G_IDMAR1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_IDMAT0, "g_idmat0", NULL, 0, CGU_GATE3,
|
||||
G_IDMAT0_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_IDMAT1, "g_idmat1", NULL, 0, CGU_GATE3,
|
||||
G_IDMAT1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_IDMAT2, "g_idmat2", NULL, 0, CGU_GATE3,
|
||||
G_IDMAT2_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_PPV4, "g_ppv4", NULL, 0, CGU_GATE3,
|
||||
G_PPV4_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_GSWIPO, "g_gswipo", "switch", 0, CGU_GATE3,
|
||||
G_GSWIPO_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_CQEM, "g_cqem", "switch", 0, CGU_GATE3,
|
||||
G_CQEM_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_XPCS5, "g_xpcs5", NULL, 0, CGU_GATE3,
|
||||
G_XPCS5_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_USB1, "g_usb1", NULL, 0, CGU_GATE3,
|
||||
G_USB1_SHIFT, 0, 0),
|
||||
LGM_GATE(LGM_GCLK_USB2, "g_usb2", NULL, 0, CGU_GATE3,
|
||||
G_USB2_SHIFT, 0, 0),
|
||||
};
|
||||
|
||||
|
||||
static const struct lgm_clk_ddiv_data lgm_ddiv_clks[] = {
|
||||
LGM_DDIV(LGM_CLK_CML, "dd_cml", "ljpll3", 0,
|
||||
PLL_DIV(CGU_LJPLL3_CFG0), 0, PLL_DDIV_WIDTH,
|
||||
3, PLL_DDIV_WIDTH, 24, 1, 29, 0),
|
||||
LGM_DDIV(LGM_CLK_SERDES, "dd_serdes", "ljpll3", 0,
|
||||
PLL_DIV(CGU_LJPLL3_CFG0), 6, PLL_DDIV_WIDTH,
|
||||
9, PLL_DDIV_WIDTH, 25, 1, 28, 0),
|
||||
LGM_DDIV(LGM_CLK_POOL, "dd_pool", "ljpll3", 0,
|
||||
PLL_DIV(CGU_LJPLL3_CFG0), 12, PLL_DDIV_WIDTH,
|
||||
15, PLL_DDIV_WIDTH, 26, 1, 28, 0),
|
||||
LGM_DDIV(LGM_CLK_PTP, "dd_ptp", "ljpll3", 0,
|
||||
PLL_DIV(CGU_LJPLL3_CFG0), 18, PLL_DDIV_WIDTH,
|
||||
21, PLL_DDIV_WIDTH, 27, 1, 28, 0),
|
||||
LGM_DDIV(LGM_CLK_PCIE, "dd_pcie", "ljpll4", 0,
|
||||
PLL_DIV(CGU_LJPLL4_CFG0), 0, PLL_DDIV_WIDTH,
|
||||
3, PLL_DDIV_WIDTH, 24, 1, 29, 0),
|
||||
};
|
||||
|
||||
static int lgm_cgu_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct lgm_clk_provider *ctx;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
int ret;
|
||||
|
||||
ctx = devm_kzalloc(dev, struct_size(ctx, clk_data.hws, CLK_NR_CLKS),
|
||||
GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->clk_data.num = CLK_NR_CLKS;
|
||||
|
||||
ctx->membase = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(ctx->membase))
|
||||
return PTR_ERR(ctx->membase);
|
||||
|
||||
ctx->np = np;
|
||||
ctx->dev = dev;
|
||||
spin_lock_init(&ctx->lock);
|
||||
|
||||
ret = lgm_clk_register_plls(ctx, lgm_pll_clks,
|
||||
ARRAY_SIZE(lgm_pll_clks));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = lgm_clk_register_branches(ctx, lgm_branch_clks,
|
||||
ARRAY_SIZE(lgm_branch_clks));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = lgm_clk_register_ddiv(ctx, lgm_ddiv_clks,
|
||||
ARRAY_SIZE(lgm_ddiv_clks));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
|
||||
&ctx->clk_data);
|
||||
}
|
||||
|
||||
static const struct of_device_id of_lgm_cgu_match[] = {
|
||||
{ .compatible = "intel,cgu-lgm" },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver lgm_cgu_driver = {
|
||||
.probe = lgm_cgu_probe,
|
||||
.driver = {
|
||||
.name = "cgu-lgm",
|
||||
.of_match_table = of_lgm_cgu_match,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(lgm_cgu_driver);
|
165
include/dt-bindings/clock/intel,lgm-clk.h
Normal file
165
include/dt-bindings/clock/intel,lgm-clk.h
Normal file
@ -0,0 +1,165 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Copyright (C) 2020 Intel Corporation.
|
||||
* Lei Chuanhua <Chuanhua.lei@intel.com>
|
||||
* Zhu Yixin <Yixin.zhu@intel.com>
|
||||
*/
|
||||
#ifndef __INTEL_LGM_CLK_H
|
||||
#define __INTEL_LGM_CLK_H
|
||||
|
||||
/* PLL clocks */
|
||||
#define LGM_CLK_OSC 1
|
||||
#define LGM_CLK_PLLPP 2
|
||||
#define LGM_CLK_PLL2 3
|
||||
#define LGM_CLK_PLL0CZ 4
|
||||
#define LGM_CLK_PLL0B 5
|
||||
#define LGM_CLK_PLL1 6
|
||||
#define LGM_CLK_LJPLL3 7
|
||||
#define LGM_CLK_LJPLL4 8
|
||||
#define LGM_CLK_PLL0CM0 9
|
||||
#define LGM_CLK_PLL0CM1 10
|
||||
|
||||
/* clocks from PLLs */
|
||||
|
||||
/* ROPLL clocks */
|
||||
#define LGM_CLK_PP_HW 15
|
||||
#define LGM_CLK_PP_UC 16
|
||||
#define LGM_CLK_PP_FXD 17
|
||||
#define LGM_CLK_PP_TBM 18
|
||||
|
||||
/* PLL2 clocks */
|
||||
#define LGM_CLK_DDR 20
|
||||
|
||||
/* PLL0CZ */
|
||||
#define LGM_CLK_CM 25
|
||||
#define LGM_CLK_IC 26
|
||||
#define LGM_CLK_SDXC3 27
|
||||
|
||||
/* PLL0B */
|
||||
#define LGM_CLK_NGI 30
|
||||
#define LGM_CLK_NOC4 31
|
||||
#define LGM_CLK_SW 32
|
||||
#define LGM_CLK_QSPI 33
|
||||
#define LGM_CLK_CQEM LGM_CLK_SW
|
||||
#define LGM_CLK_EMMC5 LGM_CLK_NOC4
|
||||
|
||||
/* PLL1 */
|
||||
#define LGM_CLK_CT 35
|
||||
#define LGM_CLK_DSP 36
|
||||
#define LGM_CLK_VIF 37
|
||||
|
||||
/* LJPLL3 */
|
||||
#define LGM_CLK_CML 40
|
||||
#define LGM_CLK_SERDES 41
|
||||
#define LGM_CLK_POOL 42
|
||||
#define LGM_CLK_PTP 43
|
||||
|
||||
/* LJPLL4 */
|
||||
#define LGM_CLK_PCIE 45
|
||||
#define LGM_CLK_SATA LGM_CLK_PCIE
|
||||
|
||||
/* PLL0CM0 */
|
||||
#define LGM_CLK_CPU0 50
|
||||
|
||||
/* PLL0CM1 */
|
||||
#define LGM_CLK_CPU1 55
|
||||
|
||||
/* Miscellaneous clocks */
|
||||
#define LGM_CLK_EMMC4 60
|
||||
#define LGM_CLK_SDXC2 61
|
||||
#define LGM_CLK_EMMC 62
|
||||
#define LGM_CLK_SDXC 63
|
||||
#define LGM_CLK_SLIC 64
|
||||
#define LGM_CLK_DCL 65
|
||||
#define LGM_CLK_DOCSIS 66
|
||||
#define LGM_CLK_PCM 67
|
||||
#define LGM_CLK_DDR_PHY 68
|
||||
#define LGM_CLK_PONDEF 69
|
||||
#define LGM_CLK_PL25M 70
|
||||
#define LGM_CLK_PL10M 71
|
||||
#define LGM_CLK_PL1544K 72
|
||||
#define LGM_CLK_PL2048K 73
|
||||
#define LGM_CLK_PL8K 74
|
||||
#define LGM_CLK_PON_NTR 75
|
||||
#define LGM_CLK_SYNC0 76
|
||||
#define LGM_CLK_SYNC1 77
|
||||
#define LGM_CLK_PROGDIV 78
|
||||
#define LGM_CLK_OD0 79
|
||||
#define LGM_CLK_OD1 80
|
||||
#define LGM_CLK_CBPHY0 81
|
||||
#define LGM_CLK_CBPHY1 82
|
||||
#define LGM_CLK_CBPHY2 83
|
||||
#define LGM_CLK_CBPHY3 84
|
||||
|
||||
/* Gate clocks */
|
||||
/* Gate CLK0 */
|
||||
#define LGM_GCLK_C55 100
|
||||
#define LGM_GCLK_QSPI 101
|
||||
#define LGM_GCLK_EIP197 102
|
||||
#define LGM_GCLK_VAULT 103
|
||||
#define LGM_GCLK_TOE 104
|
||||
#define LGM_GCLK_SDXC 105
|
||||
#define LGM_GCLK_EMMC 106
|
||||
#define LGM_GCLK_SPI_DBG 107
|
||||
#define LGM_GCLK_DMA3 108
|
||||
|
||||
/* Gate CLK1 */
|
||||
#define LGM_GCLK_DMA0 120
|
||||
#define LGM_GCLK_LEDC0 121
|
||||
#define LGM_GCLK_LEDC1 122
|
||||
#define LGM_GCLK_I2S0 123
|
||||
#define LGM_GCLK_I2S1 124
|
||||
#define LGM_GCLK_EBU 125
|
||||
#define LGM_GCLK_PWM 126
|
||||
#define LGM_GCLK_I2C0 127
|
||||
#define LGM_GCLK_I2C1 128
|
||||
#define LGM_GCLK_I2C2 129
|
||||
#define LGM_GCLK_I2C3 130
|
||||
#define LGM_GCLK_SSC0 131
|
||||
#define LGM_GCLK_SSC1 132
|
||||
#define LGM_GCLK_SSC2 133
|
||||
#define LGM_GCLK_SSC3 134
|
||||
#define LGM_GCLK_GPTC0 135
|
||||
#define LGM_GCLK_GPTC1 136
|
||||
#define LGM_GCLK_GPTC2 137
|
||||
#define LGM_GCLK_GPTC3 138
|
||||
#define LGM_GCLK_ASC0 139
|
||||
#define LGM_GCLK_ASC1 140
|
||||
#define LGM_GCLK_ASC2 141
|
||||
#define LGM_GCLK_ASC3 142
|
||||
#define LGM_GCLK_PCM0 143
|
||||
#define LGM_GCLK_PCM1 144
|
||||
#define LGM_GCLK_PCM2 145
|
||||
|
||||
/* Gate CLK2 */
|
||||
#define LGM_GCLK_PCIE10 150
|
||||
#define LGM_GCLK_PCIE11 151
|
||||
#define LGM_GCLK_PCIE30 152
|
||||
#define LGM_GCLK_PCIE31 153
|
||||
#define LGM_GCLK_PCIE20 154
|
||||
#define LGM_GCLK_PCIE21 155
|
||||
#define LGM_GCLK_PCIE40 156
|
||||
#define LGM_GCLK_PCIE41 157
|
||||
#define LGM_GCLK_XPCS0 158
|
||||
#define LGM_GCLK_XPCS1 159
|
||||
#define LGM_GCLK_XPCS2 160
|
||||
#define LGM_GCLK_XPCS3 161
|
||||
#define LGM_GCLK_SATA0 162
|
||||
#define LGM_GCLK_SATA1 163
|
||||
#define LGM_GCLK_SATA2 164
|
||||
#define LGM_GCLK_SATA3 165
|
||||
|
||||
/* Gate CLK3 */
|
||||
#define LGM_GCLK_ARCEM4 170
|
||||
#define LGM_GCLK_IDMAR1 171
|
||||
#define LGM_GCLK_IDMAT0 172
|
||||
#define LGM_GCLK_IDMAT1 173
|
||||
#define LGM_GCLK_IDMAT2 174
|
||||
#define LGM_GCLK_PPV4 175
|
||||
#define LGM_GCLK_GSWIPO 176
|
||||
#define LGM_GCLK_CQEM 177
|
||||
#define LGM_GCLK_XPCS5 178
|
||||
#define LGM_GCLK_USB1 179
|
||||
#define LGM_GCLK_USB2 180
|
||||
|
||||
#endif /* __INTEL_LGM_CLK_H */
|
10
include/dt-bindings/clock/marvell,mmp2-audio.h
Normal file
10
include/dt-bindings/clock/marvell,mmp2-audio.h
Normal file
@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ OR BSD-2-Clause) */
|
||||
#ifndef __DT_BINDINGS_CLOCK_MARVELL_MMP2_AUDIO_H
|
||||
#define __DT_BINDINGS_CLOCK_MARVELL_MMP2_AUDIO_H
|
||||
|
||||
#define MMP2_CLK_AUDIO_SYSCLK 0
|
||||
#define MMP2_CLK_AUDIO_SSPA0 1
|
||||
#define MMP2_CLK_AUDIO_SSPA1 2
|
||||
|
||||
#define MMP2_CLK_AUDIO_NR_CLKS 3
|
||||
#endif
|
@ -29,6 +29,8 @@
|
||||
#define MMP3_CLK_PLL1_P 28
|
||||
#define MMP3_CLK_PLL2_P 29
|
||||
#define MMP3_CLK_PLL3 30
|
||||
#define MMP2_CLK_I2S0 31
|
||||
#define MMP2_CLK_I2S1 32
|
||||
|
||||
/* apb periphrals */
|
||||
#define MMP2_CLK_TWSI0 60
|
||||
@ -87,6 +89,7 @@
|
||||
#define MMP3_CLK_GPU_3D MMP2_CLK_GPU_3D
|
||||
#define MMP3_CLK_GPU_2D 125
|
||||
#define MMP3_CLK_SDH4 126
|
||||
#define MMP2_CLK_AUDIO 127
|
||||
|
||||
#define MMP2_NR_CLKS 200
|
||||
#endif
|
||||
|
206
include/dt-bindings/clock/qcom,gcc-msm8939.h
Normal file
206
include/dt-bindings/clock/qcom,gcc-msm8939.h
Normal file
@ -0,0 +1,206 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright 2020 Linaro Limited
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MSM_GCC_8939_H
|
||||
#define _DT_BINDINGS_CLK_MSM_GCC_8939_H
|
||||
|
||||
#define GPLL0 0
|
||||
#define GPLL0_VOTE 1
|
||||
#define BIMC_PLL 2
|
||||
#define BIMC_PLL_VOTE 3
|
||||
#define GPLL1 4
|
||||
#define GPLL1_VOTE 5
|
||||
#define GPLL2 6
|
||||
#define GPLL2_VOTE 7
|
||||
#define PCNOC_BFDCD_CLK_SRC 8
|
||||
#define SYSTEM_NOC_BFDCD_CLK_SRC 9
|
||||
#define CAMSS_AHB_CLK_SRC 10
|
||||
#define APSS_AHB_CLK_SRC 11
|
||||
#define CSI0_CLK_SRC 12
|
||||
#define CSI1_CLK_SRC 13
|
||||
#define GFX3D_CLK_SRC 14
|
||||
#define VFE0_CLK_SRC 15
|
||||
#define BLSP1_QUP1_I2C_APPS_CLK_SRC 16
|
||||
#define BLSP1_QUP1_SPI_APPS_CLK_SRC 17
|
||||
#define BLSP1_QUP2_I2C_APPS_CLK_SRC 18
|
||||
#define BLSP1_QUP2_SPI_APPS_CLK_SRC 19
|
||||
#define BLSP1_QUP3_I2C_APPS_CLK_SRC 20
|
||||
#define BLSP1_QUP3_SPI_APPS_CLK_SRC 21
|
||||
#define BLSP1_QUP4_I2C_APPS_CLK_SRC 22
|
||||
#define BLSP1_QUP4_SPI_APPS_CLK_SRC 23
|
||||
#define BLSP1_QUP5_I2C_APPS_CLK_SRC 24
|
||||
#define BLSP1_QUP5_SPI_APPS_CLK_SRC 25
|
||||
#define BLSP1_QUP6_I2C_APPS_CLK_SRC 26
|
||||
#define BLSP1_QUP6_SPI_APPS_CLK_SRC 27
|
||||
#define BLSP1_UART1_APPS_CLK_SRC 28
|
||||
#define BLSP1_UART2_APPS_CLK_SRC 29
|
||||
#define CCI_CLK_SRC 30
|
||||
#define CAMSS_GP0_CLK_SRC 31
|
||||
#define CAMSS_GP1_CLK_SRC 32
|
||||
#define JPEG0_CLK_SRC 33
|
||||
#define MCLK0_CLK_SRC 34
|
||||
#define MCLK1_CLK_SRC 35
|
||||
#define CSI0PHYTIMER_CLK_SRC 36
|
||||
#define CSI1PHYTIMER_CLK_SRC 37
|
||||
#define CPP_CLK_SRC 38
|
||||
#define CRYPTO_CLK_SRC 39
|
||||
#define GP1_CLK_SRC 40
|
||||
#define GP2_CLK_SRC 41
|
||||
#define GP3_CLK_SRC 42
|
||||
#define BYTE0_CLK_SRC 43
|
||||
#define ESC0_CLK_SRC 44
|
||||
#define MDP_CLK_SRC 45
|
||||
#define PCLK0_CLK_SRC 46
|
||||
#define VSYNC_CLK_SRC 47
|
||||
#define PDM2_CLK_SRC 48
|
||||
#define SDCC1_APPS_CLK_SRC 49
|
||||
#define SDCC2_APPS_CLK_SRC 50
|
||||
#define APSS_TCU_CLK_SRC 51
|
||||
#define USB_HS_SYSTEM_CLK_SRC 52
|
||||
#define VCODEC0_CLK_SRC 53
|
||||
#define GCC_BLSP1_AHB_CLK 54
|
||||
#define GCC_BLSP1_SLEEP_CLK 55
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_CLK 56
|
||||
#define GCC_BLSP1_QUP1_SPI_APPS_CLK 57
|
||||
#define GCC_BLSP1_QUP2_I2C_APPS_CLK 58
|
||||
#define GCC_BLSP1_QUP2_SPI_APPS_CLK 59
|
||||
#define GCC_BLSP1_QUP3_I2C_APPS_CLK 60
|
||||
#define GCC_BLSP1_QUP3_SPI_APPS_CLK 61
|
||||
#define GCC_BLSP1_QUP4_I2C_APPS_CLK 62
|
||||
#define GCC_BLSP1_QUP4_SPI_APPS_CLK 63
|
||||
#define GCC_BLSP1_QUP5_I2C_APPS_CLK 64
|
||||
#define GCC_BLSP1_QUP5_SPI_APPS_CLK 65
|
||||
#define GCC_BLSP1_QUP6_I2C_APPS_CLK 66
|
||||
#define GCC_BLSP1_QUP6_SPI_APPS_CLK 67
|
||||
#define GCC_BLSP1_UART1_APPS_CLK 68
|
||||
#define GCC_BLSP1_UART2_APPS_CLK 69
|
||||
#define GCC_BOOT_ROM_AHB_CLK 70
|
||||
#define GCC_CAMSS_CCI_AHB_CLK 71
|
||||
#define GCC_CAMSS_CCI_CLK 72
|
||||
#define GCC_CAMSS_CSI0_AHB_CLK 73
|
||||
#define GCC_CAMSS_CSI0_CLK 74
|
||||
#define GCC_CAMSS_CSI0PHY_CLK 75
|
||||
#define GCC_CAMSS_CSI0PIX_CLK 76
|
||||
#define GCC_CAMSS_CSI0RDI_CLK 77
|
||||
#define GCC_CAMSS_CSI1_AHB_CLK 78
|
||||
#define GCC_CAMSS_CSI1_CLK 79
|
||||
#define GCC_CAMSS_CSI1PHY_CLK 80
|
||||
#define GCC_CAMSS_CSI1PIX_CLK 81
|
||||
#define GCC_CAMSS_CSI1RDI_CLK 82
|
||||
#define GCC_CAMSS_CSI_VFE0_CLK 83
|
||||
#define GCC_CAMSS_GP0_CLK 84
|
||||
#define GCC_CAMSS_GP1_CLK 85
|
||||
#define GCC_CAMSS_ISPIF_AHB_CLK 86
|
||||
#define GCC_CAMSS_JPEG0_CLK 87
|
||||
#define GCC_CAMSS_JPEG_AHB_CLK 88
|
||||
#define GCC_CAMSS_JPEG_AXI_CLK 89
|
||||
#define GCC_CAMSS_MCLK0_CLK 90
|
||||
#define GCC_CAMSS_MCLK1_CLK 91
|
||||
#define GCC_CAMSS_MICRO_AHB_CLK 92
|
||||
#define GCC_CAMSS_CSI0PHYTIMER_CLK 93
|
||||
#define GCC_CAMSS_CSI1PHYTIMER_CLK 94
|
||||
#define GCC_CAMSS_AHB_CLK 95
|
||||
#define GCC_CAMSS_TOP_AHB_CLK 96
|
||||
#define GCC_CAMSS_CPP_AHB_CLK 97
|
||||
#define GCC_CAMSS_CPP_CLK 98
|
||||
#define GCC_CAMSS_VFE0_CLK 99
|
||||
#define GCC_CAMSS_VFE_AHB_CLK 100
|
||||
#define GCC_CAMSS_VFE_AXI_CLK 101
|
||||
#define GCC_CRYPTO_AHB_CLK 102
|
||||
#define GCC_CRYPTO_AXI_CLK 103
|
||||
#define GCC_CRYPTO_CLK 104
|
||||
#define GCC_OXILI_GMEM_CLK 105
|
||||
#define GCC_GP1_CLK 106
|
||||
#define GCC_GP2_CLK 107
|
||||
#define GCC_GP3_CLK 108
|
||||
#define GCC_MDSS_AHB_CLK 109
|
||||
#define GCC_MDSS_AXI_CLK 110
|
||||
#define GCC_MDSS_BYTE0_CLK 111
|
||||
#define GCC_MDSS_ESC0_CLK 112
|
||||
#define GCC_MDSS_MDP_CLK 113
|
||||
#define GCC_MDSS_PCLK0_CLK 114
|
||||
#define GCC_MDSS_VSYNC_CLK 115
|
||||
#define GCC_MSS_CFG_AHB_CLK 116
|
||||
#define GCC_OXILI_AHB_CLK 117
|
||||
#define GCC_OXILI_GFX3D_CLK 118
|
||||
#define GCC_PDM2_CLK 119
|
||||
#define GCC_PDM_AHB_CLK 120
|
||||
#define GCC_PRNG_AHB_CLK 121
|
||||
#define GCC_SDCC1_AHB_CLK 122
|
||||
#define GCC_SDCC1_APPS_CLK 123
|
||||
#define GCC_SDCC2_AHB_CLK 124
|
||||
#define GCC_SDCC2_APPS_CLK 125
|
||||
#define GCC_GTCU_AHB_CLK 126
|
||||
#define GCC_JPEG_TBU_CLK 127
|
||||
#define GCC_MDP_TBU_CLK 128
|
||||
#define GCC_SMMU_CFG_CLK 129
|
||||
#define GCC_VENUS_TBU_CLK 130
|
||||
#define GCC_VFE_TBU_CLK 131
|
||||
#define GCC_USB2A_PHY_SLEEP_CLK 132
|
||||
#define GCC_USB_HS_AHB_CLK 133
|
||||
#define GCC_USB_HS_SYSTEM_CLK 134
|
||||
#define GCC_VENUS0_AHB_CLK 135
|
||||
#define GCC_VENUS0_AXI_CLK 136
|
||||
#define GCC_VENUS0_VCODEC0_CLK 137
|
||||
#define BIMC_DDR_CLK_SRC 138
|
||||
#define GCC_APSS_TCU_CLK 139
|
||||
#define GCC_GFX_TCU_CLK 140
|
||||
#define BIMC_GPU_CLK_SRC 141
|
||||
#define GCC_BIMC_GFX_CLK 142
|
||||
#define GCC_BIMC_GPU_CLK 143
|
||||
#define ULTAUDIO_LPAIF_PRI_I2S_CLK_SRC 144
|
||||
#define ULTAUDIO_LPAIF_SEC_I2S_CLK_SRC 145
|
||||
#define ULTAUDIO_LPAIF_AUX_I2S_CLK_SRC 146
|
||||
#define ULTAUDIO_XO_CLK_SRC 147
|
||||
#define ULTAUDIO_AHBFABRIC_CLK_SRC 148
|
||||
#define CODEC_DIGCODEC_CLK_SRC 149
|
||||
#define GCC_ULTAUDIO_PCNOC_MPORT_CLK 150
|
||||
#define GCC_ULTAUDIO_PCNOC_SWAY_CLK 151
|
||||
#define GCC_ULTAUDIO_AVSYNC_XO_CLK 152
|
||||
#define GCC_ULTAUDIO_STC_XO_CLK 153
|
||||
#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_CLK 154
|
||||
#define GCC_ULTAUDIO_AHBFABRIC_IXFABRIC_LPM_CLK 155
|
||||
#define GCC_ULTAUDIO_LPAIF_PRI_I2S_CLK 156
|
||||
#define GCC_ULTAUDIO_LPAIF_SEC_I2S_CLK 157
|
||||
#define GCC_ULTAUDIO_LPAIF_AUX_I2S_CLK 158
|
||||
#define GCC_CODEC_DIGCODEC_CLK 159
|
||||
#define GCC_MSS_Q6_BIMC_AXI_CLK 160
|
||||
#define GPLL3 161
|
||||
#define GPLL3_VOTE 162
|
||||
#define GPLL4 163
|
||||
#define GPLL4_VOTE 164
|
||||
#define GPLL5 165
|
||||
#define GPLL5_VOTE 166
|
||||
#define GPLL6 167
|
||||
#define GPLL6_VOTE 168
|
||||
#define BYTE1_CLK_SRC 169
|
||||
#define GCC_MDSS_BYTE1_CLK 170
|
||||
#define ESC1_CLK_SRC 171
|
||||
#define GCC_MDSS_ESC1_CLK 172
|
||||
#define PCLK1_CLK_SRC 173
|
||||
#define GCC_MDSS_PCLK1_CLK 174
|
||||
#define GCC_GFX_TBU_CLK 175
|
||||
#define GCC_CPP_TBU_CLK 176
|
||||
#define GCC_MDP_RT_TBU_CLK 177
|
||||
#define USB_FS_SYSTEM_CLK_SRC 178
|
||||
#define USB_FS_IC_CLK_SRC 179
|
||||
#define GCC_USB_FS_AHB_CLK 180
|
||||
#define GCC_USB_FS_IC_CLK 181
|
||||
#define GCC_USB_FS_SYSTEM_CLK 182
|
||||
#define GCC_VENUS0_CORE0_VCODEC0_CLK 183
|
||||
#define GCC_VENUS0_CORE1_VCODEC0_CLK 184
|
||||
#define GCC_OXILI_TIMER_CLK 185
|
||||
|
||||
/* Indexes for GDSCs */
|
||||
#define BIMC_GDSC 0
|
||||
#define VENUS_GDSC 1
|
||||
#define MDSS_GDSC 2
|
||||
#define JPEG_GDSC 3
|
||||
#define VFE_GDSC 4
|
||||
#define OXILI_GDSC 5
|
||||
#define VENUS_CORE0_GDSC 6
|
||||
#define VENUS_CORE1_GDSC 7
|
||||
|
||||
#endif
|
@ -183,6 +183,7 @@
|
||||
#define GCC_MSS_SNOC_AXI_CLK 174
|
||||
#define GCC_MSS_MNOC_BIMC_AXI_CLK 175
|
||||
#define GCC_BIMC_GFX_CLK 176
|
||||
#define UFS_UNIPRO_CORE_CLK_SRC 177
|
||||
|
||||
#define PCIE_0_GDSC 0
|
||||
#define UFS_GDSC 1
|
||||
|
@ -137,6 +137,7 @@
|
||||
#define GCC_MSS_NAV_AXI_CLK 127
|
||||
#define GCC_MSS_Q6_MEMNOC_AXI_CLK 128
|
||||
#define GCC_MSS_SNOC_AXI_CLK 129
|
||||
#define GCC_SEC_CTRL_CLK_SRC 130
|
||||
|
||||
/* GCC resets */
|
||||
#define GCC_QUSB2PHY_PRIM_BCR 0
|
||||
|
@ -12,33 +12,41 @@
|
||||
#ifndef __DT_BINDINGS_CLOCK_X1000_CGU_H__
|
||||
#define __DT_BINDINGS_CLOCK_X1000_CGU_H__
|
||||
|
||||
#define X1000_CLK_EXCLK 0
|
||||
#define X1000_CLK_RTCLK 1
|
||||
#define X1000_CLK_APLL 2
|
||||
#define X1000_CLK_MPLL 3
|
||||
#define X1000_CLK_SCLKA 4
|
||||
#define X1000_CLK_CPUMUX 5
|
||||
#define X1000_CLK_CPU 6
|
||||
#define X1000_CLK_L2CACHE 7
|
||||
#define X1000_CLK_AHB0 8
|
||||
#define X1000_CLK_AHB2PMUX 9
|
||||
#define X1000_CLK_AHB2 10
|
||||
#define X1000_CLK_PCLK 11
|
||||
#define X1000_CLK_DDR 12
|
||||
#define X1000_CLK_MAC 13
|
||||
#define X1000_CLK_MSCMUX 14
|
||||
#define X1000_CLK_MSC0 15
|
||||
#define X1000_CLK_MSC1 16
|
||||
#define X1000_CLK_SSIPLL 17
|
||||
#define X1000_CLK_SSIMUX 18
|
||||
#define X1000_CLK_SFC 19
|
||||
#define X1000_CLK_I2C0 20
|
||||
#define X1000_CLK_I2C1 21
|
||||
#define X1000_CLK_I2C2 22
|
||||
#define X1000_CLK_UART0 23
|
||||
#define X1000_CLK_UART1 24
|
||||
#define X1000_CLK_UART2 25
|
||||
#define X1000_CLK_SSI 26
|
||||
#define X1000_CLK_PDMA 27
|
||||
#define X1000_CLK_EXCLK 0
|
||||
#define X1000_CLK_RTCLK 1
|
||||
#define X1000_CLK_APLL 2
|
||||
#define X1000_CLK_MPLL 3
|
||||
#define X1000_CLK_OTGPHY 4
|
||||
#define X1000_CLK_SCLKA 5
|
||||
#define X1000_CLK_CPUMUX 6
|
||||
#define X1000_CLK_CPU 7
|
||||
#define X1000_CLK_L2CACHE 8
|
||||
#define X1000_CLK_AHB0 9
|
||||
#define X1000_CLK_AHB2PMUX 10
|
||||
#define X1000_CLK_AHB2 11
|
||||
#define X1000_CLK_PCLK 12
|
||||
#define X1000_CLK_DDR 13
|
||||
#define X1000_CLK_MAC 14
|
||||
#define X1000_CLK_LCD 15
|
||||
#define X1000_CLK_MSCMUX 16
|
||||
#define X1000_CLK_MSC0 17
|
||||
#define X1000_CLK_MSC1 18
|
||||
#define X1000_CLK_OTG 19
|
||||
#define X1000_CLK_SSIPLL 20
|
||||
#define X1000_CLK_SSIPLL_DIV2 21
|
||||
#define X1000_CLK_SSIMUX 22
|
||||
#define X1000_CLK_EMC 23
|
||||
#define X1000_CLK_EFUSE 24
|
||||
#define X1000_CLK_SFC 25
|
||||
#define X1000_CLK_I2C0 26
|
||||
#define X1000_CLK_I2C1 27
|
||||
#define X1000_CLK_I2C2 28
|
||||
#define X1000_CLK_UART0 29
|
||||
#define X1000_CLK_UART1 30
|
||||
#define X1000_CLK_UART2 31
|
||||
#define X1000_CLK_TCU 32
|
||||
#define X1000_CLK_SSI 33
|
||||
#define X1000_CLK_OST 34
|
||||
#define X1000_CLK_PDMA 35
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_X1000_CGU_H__ */
|
||||
|
55
include/dt-bindings/clock/x1830-cgu.h
Normal file
55
include/dt-bindings/clock/x1830-cgu.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* This header provides clock numbers for the ingenic,x1830-cgu DT binding.
|
||||
*
|
||||
* They are roughly ordered as:
|
||||
* - external clocks
|
||||
* - PLLs
|
||||
* - muxes/dividers in the order they appear in the x1830 programmers manual
|
||||
* - gates in order of their bit in the CLKGR* registers
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_CLOCK_X1830_CGU_H__
|
||||
#define __DT_BINDINGS_CLOCK_X1830_CGU_H__
|
||||
|
||||
#define X1830_CLK_EXCLK 0
|
||||
#define X1830_CLK_RTCLK 1
|
||||
#define X1830_CLK_APLL 2
|
||||
#define X1830_CLK_MPLL 3
|
||||
#define X1830_CLK_EPLL 4
|
||||
#define X1830_CLK_VPLL 5
|
||||
#define X1830_CLK_OTGPHY 6
|
||||
#define X1830_CLK_SCLKA 7
|
||||
#define X1830_CLK_CPUMUX 8
|
||||
#define X1830_CLK_CPU 9
|
||||
#define X1830_CLK_L2CACHE 10
|
||||
#define X1830_CLK_AHB0 11
|
||||
#define X1830_CLK_AHB2PMUX 12
|
||||
#define X1830_CLK_AHB2 13
|
||||
#define X1830_CLK_PCLK 14
|
||||
#define X1830_CLK_DDR 15
|
||||
#define X1830_CLK_MAC 16
|
||||
#define X1830_CLK_LCD 17
|
||||
#define X1830_CLK_MSCMUX 18
|
||||
#define X1830_CLK_MSC0 19
|
||||
#define X1830_CLK_MSC1 20
|
||||
#define X1830_CLK_SSIPLL 21
|
||||
#define X1830_CLK_SSIPLL_DIV2 22
|
||||
#define X1830_CLK_SSIMUX 23
|
||||
#define X1830_CLK_EMC 24
|
||||
#define X1830_CLK_EFUSE 25
|
||||
#define X1830_CLK_OTG 26
|
||||
#define X1830_CLK_SSI0 27
|
||||
#define X1830_CLK_SMB0 28
|
||||
#define X1830_CLK_SMB1 29
|
||||
#define X1830_CLK_SMB2 30
|
||||
#define X1830_CLK_UART0 31
|
||||
#define X1830_CLK_UART1 32
|
||||
#define X1830_CLK_SSI1 33
|
||||
#define X1830_CLK_SFC 34
|
||||
#define X1830_CLK_PDMA 35
|
||||
#define X1830_CLK_TCU 36
|
||||
#define X1830_CLK_DTRNG 37
|
||||
#define X1830_CLK_OST 38
|
||||
|
||||
#endif /* __DT_BINDINGS_CLOCK_X1830_CGU_H__ */
|
11
include/dt-bindings/power/marvell,mmp2.h
Normal file
11
include/dt-bindings/power/marvell,mmp2.h
Normal file
@ -0,0 +1,11 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef __DTS_MARVELL_MMP2_POWER_H
|
||||
#define __DTS_MARVELL_MMP2_POWER_H
|
||||
|
||||
#define MMP2_POWER_DOMAIN_GPU 0
|
||||
#define MMP2_POWER_DOMAIN_AUDIO 1
|
||||
#define MMP3_POWER_DOMAIN_CAMERA 2
|
||||
|
||||
#define MMP2_NR_POWER_DOMAINS 3
|
||||
|
||||
#endif
|
110
include/dt-bindings/reset/qcom,gcc-msm8939.h
Normal file
110
include/dt-bindings/reset/qcom,gcc-msm8939.h
Normal file
@ -0,0 +1,110 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright 2020 Linaro Limited
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_RESET_MSM_GCC_8939_H
|
||||
#define _DT_BINDINGS_RESET_MSM_GCC_8939_H
|
||||
|
||||
#define GCC_BLSP1_BCR 0
|
||||
#define GCC_BLSP1_QUP1_BCR 1
|
||||
#define GCC_BLSP1_UART1_BCR 2
|
||||
#define GCC_BLSP1_QUP2_BCR 3
|
||||
#define GCC_BLSP1_UART2_BCR 4
|
||||
#define GCC_BLSP1_QUP3_BCR 5
|
||||
#define GCC_BLSP1_QUP4_BCR 6
|
||||
#define GCC_BLSP1_QUP5_BCR 7
|
||||
#define GCC_BLSP1_QUP6_BCR 8
|
||||
#define GCC_IMEM_BCR 9
|
||||
#define GCC_SMMU_BCR 10
|
||||
#define GCC_APSS_TCU_BCR 11
|
||||
#define GCC_SMMU_XPU_BCR 12
|
||||
#define GCC_PCNOC_TBU_BCR 13
|
||||
#define GCC_PRNG_BCR 14
|
||||
#define GCC_BOOT_ROM_BCR 15
|
||||
#define GCC_CRYPTO_BCR 16
|
||||
#define GCC_SEC_CTRL_BCR 17
|
||||
#define GCC_AUDIO_CORE_BCR 18
|
||||
#define GCC_ULT_AUDIO_BCR 19
|
||||
#define GCC_DEHR_BCR 20
|
||||
#define GCC_SYSTEM_NOC_BCR 21
|
||||
#define GCC_PCNOC_BCR 22
|
||||
#define GCC_TCSR_BCR 23
|
||||
#define GCC_QDSS_BCR 24
|
||||
#define GCC_DCD_BCR 25
|
||||
#define GCC_MSG_RAM_BCR 26
|
||||
#define GCC_MPM_BCR 27
|
||||
#define GCC_SPMI_BCR 28
|
||||
#define GCC_SPDM_BCR 29
|
||||
#define GCC_MM_SPDM_BCR 30
|
||||
#define GCC_BIMC_BCR 31
|
||||
#define GCC_RBCPR_BCR 32
|
||||
#define GCC_TLMM_BCR 33
|
||||
#define GCC_USB_HS_BCR 34
|
||||
#define GCC_USB2A_PHY_BCR 35
|
||||
#define GCC_SDCC1_BCR 36
|
||||
#define GCC_SDCC2_BCR 37
|
||||
#define GCC_PDM_BCR 38
|
||||
#define GCC_SNOC_BUS_TIMEOUT0_BCR 39
|
||||
#define GCC_PCNOC_BUS_TIMEOUT0_BCR 40
|
||||
#define GCC_PCNOC_BUS_TIMEOUT1_BCR 41
|
||||
#define GCC_PCNOC_BUS_TIMEOUT2_BCR 42
|
||||
#define GCC_PCNOC_BUS_TIMEOUT3_BCR 43
|
||||
#define GCC_PCNOC_BUS_TIMEOUT4_BCR 44
|
||||
#define GCC_PCNOC_BUS_TIMEOUT5_BCR 45
|
||||
#define GCC_PCNOC_BUS_TIMEOUT6_BCR 46
|
||||
#define GCC_PCNOC_BUS_TIMEOUT7_BCR 47
|
||||
#define GCC_PCNOC_BUS_TIMEOUT8_BCR 48
|
||||
#define GCC_PCNOC_BUS_TIMEOUT9_BCR 49
|
||||
#define GCC_MMSS_BCR 50
|
||||
#define GCC_VENUS0_BCR 51
|
||||
#define GCC_MDSS_BCR 52
|
||||
#define GCC_CAMSS_PHY0_BCR 53
|
||||
#define GCC_CAMSS_CSI0_BCR 54
|
||||
#define GCC_CAMSS_CSI0PHY_BCR 55
|
||||
#define GCC_CAMSS_CSI0RDI_BCR 56
|
||||
#define GCC_CAMSS_CSI0PIX_BCR 57
|
||||
#define GCC_CAMSS_PHY1_BCR 58
|
||||
#define GCC_CAMSS_CSI1_BCR 59
|
||||
#define GCC_CAMSS_CSI1PHY_BCR 60
|
||||
#define GCC_CAMSS_CSI1RDI_BCR 61
|
||||
#define GCC_CAMSS_CSI1PIX_BCR 62
|
||||
#define GCC_CAMSS_ISPIF_BCR 63
|
||||
#define GCC_CAMSS_CCI_BCR 64
|
||||
#define GCC_CAMSS_MCLK0_BCR 65
|
||||
#define GCC_CAMSS_MCLK1_BCR 66
|
||||
#define GCC_CAMSS_GP0_BCR 67
|
||||
#define GCC_CAMSS_GP1_BCR 68
|
||||
#define GCC_CAMSS_TOP_BCR 69
|
||||
#define GCC_CAMSS_MICRO_BCR 70
|
||||
#define GCC_CAMSS_JPEG_BCR 71
|
||||
#define GCC_CAMSS_VFE_BCR 72
|
||||
#define GCC_CAMSS_CSI_VFE0_BCR 73
|
||||
#define GCC_OXILI_BCR 74
|
||||
#define GCC_GMEM_BCR 75
|
||||
#define GCC_CAMSS_AHB_BCR 76
|
||||
#define GCC_MDP_TBU_BCR 77
|
||||
#define GCC_GFX_TBU_BCR 78
|
||||
#define GCC_GFX_TCU_BCR 79
|
||||
#define GCC_MSS_TBU_AXI_BCR 80
|
||||
#define GCC_MSS_TBU_GSS_AXI_BCR 81
|
||||
#define GCC_MSS_TBU_Q6_AXI_BCR 82
|
||||
#define GCC_GTCU_AHB_BCR 83
|
||||
#define GCC_SMMU_CFG_BCR 84
|
||||
#define GCC_VFE_TBU_BCR 85
|
||||
#define GCC_VENUS_TBU_BCR 86
|
||||
#define GCC_JPEG_TBU_BCR 87
|
||||
#define GCC_PRONTO_TBU_BCR 88
|
||||
#define GCC_SMMU_CATS_BCR 89
|
||||
#define GCC_BLSP1_UART3_BCR 90
|
||||
#define GCC_CAMSS_CSI2_BCR 91
|
||||
#define GCC_CAMSS_CSI2PHY_BCR 92
|
||||
#define GCC_CAMSS_CSI2RDI_BCR 93
|
||||
#define GCC_CAMSS_CSI2PIX_BCR 94
|
||||
#define GCC_USB_FS_BCR 95
|
||||
#define GCC_BLSP1_QUP4_SPI_APPS_CBCR 96
|
||||
#define GCC_CAMSS_MCLK2_BCR 97
|
||||
#define GCC_CPP_TBU_BCR 98
|
||||
#define GCC_MDP_RT_TBU_BCR 99
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user