mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
Merge branches 'clk-ti', 'clk-ingenic', 'clk-typo', 'clk-at91', 'clk-mmp2' and 'clk-arm-icst' into clk-next
- EHRPWM's TimeBase clock(TBCLK) for TI AM654 SoCs - Support PMC clks on at91sam9n12, at91rm9200, sama5d3, and at91sam9g45 SoCs - Fixes and improvements for the Marvell MMP2/MMP3 SoC clk drivers * clk-ti: clk: keystone: Add new driver to handle syscon based clocks dt-bindings: clock: Add binding documentation for TI EHRPWM TBCLK * clk-ingenic: clk: ingenic/TCU: Fix round_rate returning error clk: ingenic/jz4770: Exit with error if CGU init failed clk: JZ4780: Add function for enable the second core. clk: Ingenic: Add support for TCU of X1000. * clk-typo: clk: Fix trivia typo in comment exlusive => exclusive * clk-at91: clk: at91: add at91rm9200 pmc driver clk: at91: add at91sam9n12 pmc driver clk: at91: add sama5d3 pmc driver clk: at91: add at91sam9g45 pmc driver clk: at91: usb: introduce num_parents in driver's structure clk: at91: usb: use proper usbs_mask clk: at91: sam9x60: fix usb clock parents clk: at91: usb: continue if clk_hw_round_rate() return zero clk: at91: sam9x60: Don't use audio PLL * clk-mmp2: clk: mmp2: Fix bit masks for LCDC I/O and pixel clocks clk: mmp2: Add clock for fifth SD HCI on MMP3 dt-bindings: marvell,mmp2: Add clock id for the fifth SD HCI on MMP3 clk: mmp2: Add clocks for the thermal sensors dt-bindings: marvell,mmp2: Add clock ids for the thermal sensors clk: mmp2: add the GPU clocks dt-bindings: marvell,mmp2: Add clock ids for the GPU clocks clk: mmp2: Add PLLs that are available on MMP3 dt-bindings: marvell,mmp2: Add clock ids for MMP3 PLLs clk: mmp2: Check for MMP3 dt-bindings: clock: Add MMP3 compatible string clk: mmp2: Stop pretending PLL outputs are constant clk: mmp2: Add support for PLL clock sources dt-bindings: clock: Convert marvell,mmp2-clock to json-schema clk: mmp2: Constify some strings clk: mmp2: Remove a unused prototype * clk-arm-icst: MAINTAINERS: dt: update reference for arm-integrator.txt clk: versatile: Add device tree probing for IM-PD1 clocks clk: versatile: Export icst_clk_setup() dt-bindings: clock: Create YAML schema for ICST clocks
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/arm,syscon-icst.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: ARM System Controller ICST Clocks
|
||||
|
||||
maintainers:
|
||||
- Linus Walleij <linusw@kernel.org>
|
||||
|
||||
description: |
|
||||
The ICS525 and ICS307 oscillators are produced by Integrated
|
||||
Devices Technology (IDT). ARM integrated these oscillators deeply into their
|
||||
reference designs by adding special control registers that manage such
|
||||
oscillators to their system controllers.
|
||||
|
||||
The various ARM system controllers contain logic to serialize and initialize
|
||||
an ICST clock request after a write to the 32 bit register at an offset
|
||||
into the system controller. Furthermore, to even be able to alter one of
|
||||
these frequencies, the system controller must first be unlocked by
|
||||
writing a special token to another offset in the system controller.
|
||||
|
||||
Some ARM hardware contain special versions of the serial interface that only
|
||||
connects the low 8 bits of the VDW (missing one bit), hard-wires RDW to
|
||||
different values and sometimes also hard-wires the output divider. They
|
||||
therefore have special compatible strings as per this table (the OD value is
|
||||
the value on the pins, not the resulting output divider).
|
||||
|
||||
In the core modules and logic tiles, the ICST is a configurable clock fed
|
||||
from a 24 MHz clock on the motherboard (usually the main crystal) used for
|
||||
generating e.g. video clocks. It is located on the core module and there is
|
||||
only one of these. This clock node must be a subnode of the core module.
|
||||
|
||||
Hardware variant RDW OD VDW
|
||||
|
||||
Integrator/AP 22 1 Bit 8 0, rest variable
|
||||
integratorap-cm
|
||||
|
||||
Integrator/AP 46 3 Bit 8 0, rest variable
|
||||
integratorap-sys
|
||||
|
||||
Integrator/AP 22 or 1 17 or (33 or 25 MHz)
|
||||
integratorap-pci 14 1 14
|
||||
|
||||
Integrator/CP 22 variable Bit 8 0, rest variable
|
||||
integratorcp-cm-core
|
||||
|
||||
Integrator/CP 22 variable Bit 8 0, rest variable
|
||||
integratorcp-cm-mem
|
||||
|
||||
The ICST oscillator must be provided inside a system controller node.
|
||||
|
||||
properties:
|
||||
"#clock-cells":
|
||||
const: 0
|
||||
|
||||
compatible:
|
||||
enum:
|
||||
- arm,syscon-icst525
|
||||
- arm,syscon-icst307
|
||||
- arm,syscon-icst525-integratorap-cm
|
||||
- arm,syscon-icst525-integratorap-sys
|
||||
- arm,syscon-icst525-integratorap-pci
|
||||
- arm,syscon-icst525-integratorcp-cm-core
|
||||
- arm,syscon-icst525-integratorcp-cm-mem
|
||||
- arm,integrator-cm-auxosc
|
||||
- arm,versatile-cm-auxosc
|
||||
- arm,impd-vco1
|
||||
- arm,impd-vco2
|
||||
|
||||
clocks:
|
||||
description: Parent clock for the ICST VCO
|
||||
maxItems: 1
|
||||
|
||||
clock-output-names:
|
||||
maxItems: 1
|
||||
|
||||
lock-offset:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: Offset to the unlocking register for the oscillator
|
||||
|
||||
vco-offset:
|
||||
$ref: '/schemas/types.yaml#/definitions/uint32'
|
||||
description: Offset to the VCO register for the oscillator
|
||||
|
||||
required:
|
||||
- "#clock-cells"
|
||||
- compatible
|
||||
- clocks
|
||||
|
||||
examples:
|
||||
- |
|
||||
vco1: clock@00 {
|
||||
compatible = "arm,impd1-vco1";
|
||||
#clock-cells = <0>;
|
||||
lock-offset = <0x08>;
|
||||
vco-offset = <0x00>;
|
||||
clocks = <&sysclk>;
|
||||
clock-output-names = "IM-PD1-VCO1";
|
||||
};
|
||||
|
||||
...
|
||||
@@ -1,34 +0,0 @@
|
||||
Clock bindings for ARM Integrator and Versatile Core Module clocks
|
||||
|
||||
Auxiliary Oscillator Clock
|
||||
|
||||
This is a configurable clock fed from a 24 MHz chrystal,
|
||||
used for generating e.g. video clocks. It is located on the
|
||||
core module and there is only one of these.
|
||||
|
||||
This clock node *must* be a subnode of the core module, since
|
||||
it obtains the base address for it's address range from its
|
||||
parent node.
|
||||
|
||||
|
||||
Required properties:
|
||||
- compatible: must be "arm,integrator-cm-auxosc" or "arm,versatile-cm-auxosc"
|
||||
- #clock-cells: must be <0>
|
||||
|
||||
Optional properties:
|
||||
- clocks: parent clock(s)
|
||||
|
||||
Example:
|
||||
|
||||
core-module@10000000 {
|
||||
xtal24mhz: xtal24mhz@24M {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <24000000>;
|
||||
};
|
||||
auxosc: cm_aux_osc@25M {
|
||||
#clock-cells = <0>;
|
||||
compatible = "arm,integrator-cm-auxosc";
|
||||
clocks = <&xtal24mhz>;
|
||||
};
|
||||
};
|
||||
@@ -1,70 +0,0 @@
|
||||
ARM System Controller ICST clocks
|
||||
|
||||
The ICS525 and ICS307 oscillators are produced by Integrated Devices
|
||||
Technology (IDT). ARM integrated these oscillators deeply into their
|
||||
reference designs by adding special control registers that manage such
|
||||
oscillators to their system controllers.
|
||||
|
||||
The various ARM system controllers contain logic to serialize and initialize
|
||||
an ICST clock request after a write to the 32 bit register at an offset
|
||||
into the system controller. Furthermore, to even be able to alter one of
|
||||
these frequencies, the system controller must first be unlocked by
|
||||
writing a special token to another offset in the system controller.
|
||||
|
||||
Some ARM hardware contain special versions of the serial interface that only
|
||||
connects the low 8 bits of the VDW (missing one bit), hardwires RDW to
|
||||
different values and sometimes also hardwire the output divider. They
|
||||
therefore have special compatible strings as per this table (the OD value is
|
||||
the value on the pins, not the resulting output divider):
|
||||
|
||||
Hardware variant: RDW OD VDW
|
||||
|
||||
Integrator/AP 22 1 Bit 8 0, rest variable
|
||||
integratorap-cm
|
||||
|
||||
Integrator/AP 46 3 Bit 8 0, rest variable
|
||||
integratorap-sys
|
||||
|
||||
Integrator/AP 22 or 1 17 or (33 or 25 MHz)
|
||||
integratorap-pci 14 1 14
|
||||
|
||||
Integrator/CP 22 variable Bit 8 0, rest variable
|
||||
integratorcp-cm-core
|
||||
|
||||
Integrator/CP 22 variable Bit 8 0, rest variable
|
||||
integratorcp-cm-mem
|
||||
|
||||
The ICST oscillator must be provided inside a system controller node.
|
||||
|
||||
Required properties:
|
||||
- compatible: must be one of
|
||||
"arm,syscon-icst525"
|
||||
"arm,syscon-icst307"
|
||||
"arm,syscon-icst525-integratorap-cm"
|
||||
"arm,syscon-icst525-integratorap-sys"
|
||||
"arm,syscon-icst525-integratorap-pci"
|
||||
"arm,syscon-icst525-integratorcp-cm-core"
|
||||
"arm,syscon-icst525-integratorcp-cm-mem"
|
||||
- lock-offset: the offset address into the system controller where the
|
||||
unlocking register is located
|
||||
- vco-offset: the offset address into the system controller where the
|
||||
ICST control register is located (even 32 bit address)
|
||||
- #clock-cells: must be <0>
|
||||
- clocks: parent clock, since the ICST needs a parent clock to derive its
|
||||
frequency from, this attribute is compulsory.
|
||||
|
||||
Example:
|
||||
|
||||
syscon: syscon@10000000 {
|
||||
compatible = "syscon";
|
||||
reg = <0x10000000 0x1000>;
|
||||
|
||||
oscclk0: osc0@c {
|
||||
compatible = "arm,syscon-icst307";
|
||||
#clock-cells = <0>;
|
||||
lock-offset = <0x20>;
|
||||
vco-offset = <0x0c>;
|
||||
clocks = <&xtal24mhz>;
|
||||
};
|
||||
(...)
|
||||
};
|
||||
@@ -0,0 +1,64 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/marvell,mmp2-clock.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Marvell MMP2 and MMP3 Clock Controller
|
||||
|
||||
maintainers:
|
||||
- Lubomir Rintel <lkundrak@v3.sk>
|
||||
|
||||
description: |
|
||||
The clock subsystem on MMP2 or MMP3 generates and supplies clock to various
|
||||
controllers within the SoC.
|
||||
|
||||
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.h>.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- marvell,mmp2-clock # controller compatible with MMP2 SoC
|
||||
- marvell,mmp3-clock # controller compatible with MMP3 SoC
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: MPMU register region
|
||||
- description: APMU register region
|
||||
- description: APBC register region
|
||||
|
||||
reg-names:
|
||||
items:
|
||||
- const: mpmu
|
||||
- const: apmu
|
||||
- const: apbc
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- reg-names
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clock-controller@d4050000 {
|
||||
compatible = "marvell,mmp2-clock";
|
||||
reg = <0xd4050000 0x1000>,
|
||||
<0xd4282800 0x400>,
|
||||
<0xd4015000 0x1000>;
|
||||
reg-names = "mpmu", "apmu", "apbc";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
@@ -1,21 +0,0 @@
|
||||
* Marvell MMP2 Clock Controller
|
||||
|
||||
The MMP2 clock subsystem generates and supplies clock to various
|
||||
controllers within the MMP2 SoC.
|
||||
|
||||
Required Properties:
|
||||
|
||||
- compatible: should be one of the following.
|
||||
- "marvell,mmp2-clock" - controller compatible with MMP2 SoC.
|
||||
|
||||
- reg: physical base address of the clock subsystem and length of memory mapped
|
||||
region. There are 3 places in SOC has clock control logic:
|
||||
"mpmu", "apmu", "apbc". So three reg spaces need to be defined.
|
||||
|
||||
- #clock-cells: should be 1.
|
||||
- #reset-cells: should be 1.
|
||||
|
||||
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.h>.
|
||||
@@ -0,0 +1,35 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/ti,am654-ehrpwm-tbclk.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: TI EHRPWM Time Base Clock
|
||||
|
||||
maintainers:
|
||||
- Vignesh Raghavendra <vigneshr@ti.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- const: ti,am654-ehrpwm-tbclk
|
||||
- const: syscon
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
- reg
|
||||
|
||||
examples:
|
||||
- |
|
||||
ehrpwm_tbclk: syscon@4140 {
|
||||
compatible = "ti,am654-ehrpwm-tbclk", "syscon";
|
||||
reg = <0x4140 0x18>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
+1
-1
@@ -1280,7 +1280,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/arm/arm-boards
|
||||
F: Documentation/devicetree/bindings/auxdisplay/arm-charlcd.txt
|
||||
F: Documentation/devicetree/bindings/clock/arm-integrator.txt
|
||||
F: Documentation/devicetree/bindings/clock/arm,syscon-icst.yaml
|
||||
F: Documentation/devicetree/bindings/i2c/i2c-versatile.txt
|
||||
F: Documentation/devicetree/bindings/interrupt-controller/arm,versatile-fpga-irq.txt
|
||||
F: Documentation/devicetree/bindings/mtd/arm-versatile.txt
|
||||
|
||||
@@ -15,7 +15,11 @@ obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o
|
||||
obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o
|
||||
obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK) += clk-i2s-mux.o
|
||||
obj-$(CONFIG_HAVE_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
|
||||
obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o
|
||||
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o
|
||||
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9g45.o
|
||||
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9n12.o at91sam9x5.o
|
||||
obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o
|
||||
obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o
|
||||
obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
|
||||
obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/at91.h>
|
||||
|
||||
#include "pmc.h"
|
||||
|
||||
struct sck {
|
||||
char *n;
|
||||
char *p;
|
||||
u8 id;
|
||||
};
|
||||
|
||||
struct pck {
|
||||
char *n;
|
||||
u8 id;
|
||||
};
|
||||
|
||||
static const struct clk_master_characteristics rm9200_mck_characteristics = {
|
||||
.output = { .min = 0, .max = 80000000 },
|
||||
.divisors = { 1, 2, 3, 4 },
|
||||
};
|
||||
|
||||
static u8 rm9200_pll_out[] = { 0, 2 };
|
||||
|
||||
static const struct clk_range rm9200_pll_outputs[] = {
|
||||
{ .min = 80000000, .max = 160000000 },
|
||||
{ .min = 150000000, .max = 180000000 },
|
||||
};
|
||||
|
||||
static const struct clk_pll_characteristics rm9200_pll_characteristics = {
|
||||
.input = { .min = 1000000, .max = 32000000 },
|
||||
.num_output = ARRAY_SIZE(rm9200_pll_outputs),
|
||||
.output = rm9200_pll_outputs,
|
||||
.out = rm9200_pll_out,
|
||||
};
|
||||
|
||||
static const struct sck at91rm9200_systemck[] = {
|
||||
{ .n = "udpck", .p = "usbck", .id = 2 },
|
||||
{ .n = "uhpck", .p = "usbck", .id = 4 },
|
||||
{ .n = "pck0", .p = "prog0", .id = 8 },
|
||||
{ .n = "pck1", .p = "prog1", .id = 9 },
|
||||
{ .n = "pck2", .p = "prog2", .id = 10 },
|
||||
{ .n = "pck3", .p = "prog3", .id = 11 },
|
||||
};
|
||||
|
||||
static const struct pck at91rm9200_periphck[] = {
|
||||
{ .n = "pioA_clk", .id = 2 },
|
||||
{ .n = "pioB_clk", .id = 3 },
|
||||
{ .n = "pioC_clk", .id = 4 },
|
||||
{ .n = "pioD_clk", .id = 5 },
|
||||
{ .n = "usart0_clk", .id = 6 },
|
||||
{ .n = "usart1_clk", .id = 7 },
|
||||
{ .n = "usart2_clk", .id = 8 },
|
||||
{ .n = "usart3_clk", .id = 9 },
|
||||
{ .n = "mci0_clk", .id = 10 },
|
||||
{ .n = "udc_clk", .id = 11 },
|
||||
{ .n = "twi0_clk", .id = 12 },
|
||||
{ .n = "spi0_clk", .id = 13 },
|
||||
{ .n = "ssc0_clk", .id = 14 },
|
||||
{ .n = "ssc1_clk", .id = 15 },
|
||||
{ .n = "ssc2_clk", .id = 16 },
|
||||
{ .n = "tc0_clk", .id = 17 },
|
||||
{ .n = "tc1_clk", .id = 18 },
|
||||
{ .n = "tc2_clk", .id = 19 },
|
||||
{ .n = "tc3_clk", .id = 20 },
|
||||
{ .n = "tc4_clk", .id = 21 },
|
||||
{ .n = "tc5_clk", .id = 22 },
|
||||
{ .n = "ohci_clk", .id = 23 },
|
||||
{ .n = "macb0_clk", .id = 24 },
|
||||
};
|
||||
|
||||
static void __init at91rm9200_pmc_setup(struct device_node *np)
|
||||
{
|
||||
const char *slowxtal_name, *mainxtal_name;
|
||||
struct pmc_data *at91rm9200_pmc;
|
||||
u32 usb_div[] = { 1, 2, 0, 0 };
|
||||
const char *parent_names[6];
|
||||
struct regmap *regmap;
|
||||
struct clk_hw *hw;
|
||||
int i;
|
||||
bool bypass;
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "slow_xtal");
|
||||
if (i < 0)
|
||||
return;
|
||||
|
||||
slowxtal_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "main_xtal");
|
||||
if (i < 0)
|
||||
return;
|
||||
mainxtal_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
regmap = device_node_to_regmap(np);
|
||||
if (IS_ERR(regmap))
|
||||
return;
|
||||
|
||||
at91rm9200_pmc = pmc_data_allocate(PMC_MAIN + 1,
|
||||
nck(at91rm9200_systemck),
|
||||
nck(at91rm9200_periphck), 0);
|
||||
if (!at91rm9200_pmc)
|
||||
return;
|
||||
|
||||
bypass = of_property_read_bool(np, "atmel,osc-bypass");
|
||||
|
||||
hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
|
||||
bypass);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_rm9200_main(regmap, "mainck", "main_osc");
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91rm9200_pmc->chws[PMC_MAIN] = hw;
|
||||
|
||||
hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
|
||||
&at91rm9200_pll_layout,
|
||||
&rm9200_pll_characteristics);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
|
||||
&at91rm9200_pll_layout,
|
||||
&rm9200_pll_characteristics);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
parent_names[0] = slowxtal_name;
|
||||
parent_names[1] = "mainck";
|
||||
parent_names[2] = "pllack";
|
||||
parent_names[3] = "pllbck";
|
||||
hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
|
||||
&at91rm9200_master_layout,
|
||||
&rm9200_mck_characteristics);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91rm9200_pmc->chws[PMC_MCK] = hw;
|
||||
|
||||
hw = at91rm9200_clk_register_usb(regmap, "usbck", "pllbck", usb_div);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
parent_names[0] = slowxtal_name;
|
||||
parent_names[1] = "mainck";
|
||||
parent_names[2] = "pllack";
|
||||
parent_names[3] = "pllbck";
|
||||
for (i = 0; i < 4; i++) {
|
||||
char name[6];
|
||||
|
||||
snprintf(name, sizeof(name), "prog%d", i);
|
||||
|
||||
hw = at91_clk_register_programmable(regmap, name,
|
||||
parent_names, 4, i,
|
||||
&at91rm9200_programmable_layout);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(at91rm9200_systemck); i++) {
|
||||
hw = at91_clk_register_system(regmap, at91rm9200_systemck[i].n,
|
||||
at91rm9200_systemck[i].p,
|
||||
at91rm9200_systemck[i].id);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91rm9200_pmc->shws[at91rm9200_systemck[i].id] = hw;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(at91rm9200_periphck); i++) {
|
||||
hw = at91_clk_register_peripheral(regmap,
|
||||
at91rm9200_periphck[i].n,
|
||||
"masterck",
|
||||
at91rm9200_periphck[i].id);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91rm9200_pmc->phws[at91rm9200_periphck[i].id] = hw;
|
||||
}
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91rm9200_pmc);
|
||||
|
||||
return;
|
||||
|
||||
err_free:
|
||||
pmc_data_free(at91rm9200_pmc);
|
||||
}
|
||||
/*
|
||||
* While the TCB can be used as the clocksource, the system timer is most likely
|
||||
* to be used instead. However, the pinctrl driver doesn't support probe
|
||||
* deferring properly. Once this is fixed, this can be switched to a platform
|
||||
* driver.
|
||||
*/
|
||||
CLK_OF_DECLARE_DRIVER(at91rm9200_pmc, "atmel,at91rm9200-pmc",
|
||||
at91rm9200_pmc_setup);
|
||||
@@ -0,0 +1,220 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/at91.h>
|
||||
|
||||
#include "pmc.h"
|
||||
|
||||
static const struct clk_master_characteristics mck_characteristics = {
|
||||
.output = { .min = 0, .max = 133333333 },
|
||||
.divisors = { 1, 2, 4, 3 },
|
||||
};
|
||||
|
||||
static u8 plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
|
||||
|
||||
static u16 plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
|
||||
|
||||
static const struct clk_range plla_outputs[] = {
|
||||
{ .min = 745000000, .max = 800000000 },
|
||||
{ .min = 695000000, .max = 750000000 },
|
||||
{ .min = 645000000, .max = 700000000 },
|
||||
{ .min = 595000000, .max = 650000000 },
|
||||
{ .min = 545000000, .max = 600000000 },
|
||||
{ .min = 495000000, .max = 555000000 },
|
||||
{ .min = 445000000, .max = 500000000 },
|
||||
{ .min = 400000000, .max = 450000000 },
|
||||
};
|
||||
|
||||
static const struct clk_pll_characteristics plla_characteristics = {
|
||||
.input = { .min = 2000000, .max = 32000000 },
|
||||
.num_output = ARRAY_SIZE(plla_outputs),
|
||||
.output = plla_outputs,
|
||||
.icpll = plla_icpll,
|
||||
.out = plla_out,
|
||||
};
|
||||
|
||||
static const struct {
|
||||
char *n;
|
||||
char *p;
|
||||
u8 id;
|
||||
} at91sam9g45_systemck[] = {
|
||||
{ .n = "ddrck", .p = "masterck", .id = 2 },
|
||||
{ .n = "uhpck", .p = "usbck", .id = 6 },
|
||||
{ .n = "pck0", .p = "prog0", .id = 8 },
|
||||
{ .n = "pck1", .p = "prog1", .id = 9 },
|
||||
};
|
||||
|
||||
static const struct clk_pcr_layout at91sam9g45_pcr_layout = {
|
||||
.offset = 0x10c,
|
||||
.cmd = BIT(12),
|
||||
.pid_mask = GENMASK(5, 0),
|
||||
.div_mask = GENMASK(17, 16),
|
||||
};
|
||||
|
||||
struct pck {
|
||||
char *n;
|
||||
u8 id;
|
||||
};
|
||||
|
||||
static const struct pck at91sam9g45_periphck[] = {
|
||||
{ .n = "pioA_clk", .id = 2, },
|
||||
{ .n = "pioB_clk", .id = 3, },
|
||||
{ .n = "pioC_clk", .id = 4, },
|
||||
{ .n = "pioDE_clk", .id = 5, },
|
||||
{ .n = "trng_clk", .id = 6, },
|
||||
{ .n = "usart0_clk", .id = 7, },
|
||||
{ .n = "usart1_clk", .id = 8, },
|
||||
{ .n = "usart2_clk", .id = 9, },
|
||||
{ .n = "usart3_clk", .id = 10, },
|
||||
{ .n = "mci0_clk", .id = 11, },
|
||||
{ .n = "twi0_clk", .id = 12, },
|
||||
{ .n = "twi1_clk", .id = 13, },
|
||||
{ .n = "spi0_clk", .id = 14, },
|
||||
{ .n = "spi1_clk", .id = 15, },
|
||||
{ .n = "ssc0_clk", .id = 16, },
|
||||
{ .n = "ssc1_clk", .id = 17, },
|
||||
{ .n = "tcb0_clk", .id = 18, },
|
||||
{ .n = "pwm_clk", .id = 19, },
|
||||
{ .n = "adc_clk", .id = 20, },
|
||||
{ .n = "dma0_clk", .id = 21, },
|
||||
{ .n = "uhphs_clk", .id = 22, },
|
||||
{ .n = "lcd_clk", .id = 23, },
|
||||
{ .n = "ac97_clk", .id = 24, },
|
||||
{ .n = "macb0_clk", .id = 25, },
|
||||
{ .n = "isi_clk", .id = 26, },
|
||||
{ .n = "udphs_clk", .id = 27, },
|
||||
{ .n = "aestdessha_clk", .id = 28, },
|
||||
{ .n = "mci1_clk", .id = 29, },
|
||||
{ .n = "vdec_clk", .id = 30, },
|
||||
};
|
||||
|
||||
static void __init at91sam9g45_pmc_setup(struct device_node *np)
|
||||
{
|
||||
const char *slck_name, *mainxtal_name;
|
||||
struct pmc_data *at91sam9g45_pmc;
|
||||
const char *parent_names[6];
|
||||
struct regmap *regmap;
|
||||
struct clk_hw *hw;
|
||||
int i;
|
||||
bool bypass;
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "slow_clk");
|
||||
if (i < 0)
|
||||
return;
|
||||
|
||||
slck_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "main_xtal");
|
||||
if (i < 0)
|
||||
return;
|
||||
mainxtal_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
regmap = syscon_node_to_regmap(np);
|
||||
if (IS_ERR(regmap))
|
||||
return;
|
||||
|
||||
at91sam9g45_pmc = pmc_data_allocate(PMC_MAIN + 1,
|
||||
nck(at91sam9g45_systemck),
|
||||
nck(at91sam9g45_periphck), 0);
|
||||
if (!at91sam9g45_pmc)
|
||||
return;
|
||||
|
||||
bypass = of_property_read_bool(np, "atmel,osc-bypass");
|
||||
|
||||
hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
|
||||
bypass);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_rm9200_main(regmap, "mainck", "main_osc");
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91sam9g45_pmc->chws[PMC_MAIN] = hw;
|
||||
|
||||
hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
|
||||
&at91rm9200_pll_layout, &plla_characteristics);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack");
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91sam9g45_pmc->chws[PMC_UTMI] = hw;
|
||||
|
||||
parent_names[0] = slck_name;
|
||||
parent_names[1] = "mainck";
|
||||
parent_names[2] = "plladivck";
|
||||
parent_names[3] = "utmick";
|
||||
hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
|
||||
&at91rm9200_master_layout,
|
||||
&mck_characteristics);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91sam9g45_pmc->chws[PMC_MCK] = hw;
|
||||
|
||||
parent_names[0] = "plladivck";
|
||||
parent_names[1] = "utmick";
|
||||
hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
parent_names[0] = slck_name;
|
||||
parent_names[1] = "mainck";
|
||||
parent_names[2] = "plladivck";
|
||||
parent_names[3] = "utmick";
|
||||
parent_names[4] = "masterck";
|
||||
for (i = 0; i < 2; i++) {
|
||||
char name[6];
|
||||
|
||||
snprintf(name, sizeof(name), "prog%d", i);
|
||||
|
||||
hw = at91_clk_register_programmable(regmap, name,
|
||||
parent_names, 5, i,
|
||||
&at91sam9g45_programmable_layout);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(at91sam9g45_systemck); i++) {
|
||||
hw = at91_clk_register_system(regmap, at91sam9g45_systemck[i].n,
|
||||
at91sam9g45_systemck[i].p,
|
||||
at91sam9g45_systemck[i].id);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91sam9g45_pmc->shws[at91sam9g45_systemck[i].id] = hw;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(at91sam9g45_periphck); i++) {
|
||||
hw = at91_clk_register_peripheral(regmap,
|
||||
at91sam9g45_periphck[i].n,
|
||||
"masterck",
|
||||
at91sam9g45_periphck[i].id);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91sam9g45_pmc->phws[at91sam9g45_periphck[i].id] = hw;
|
||||
}
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9g45_pmc);
|
||||
|
||||
return;
|
||||
|
||||
err_free:
|
||||
pmc_data_free(at91sam9g45_pmc);
|
||||
}
|
||||
/*
|
||||
* The TCB is used as the clocksource so its clock is needed early. This means
|
||||
* this can't be a platform driver.
|
||||
*/
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9g45_pmc, "atmel,at91sam9g45-pmc",
|
||||
at91sam9g45_pmc_setup);
|
||||
@@ -0,0 +1,238 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/at91.h>
|
||||
|
||||
#include "pmc.h"
|
||||
|
||||
static const struct clk_master_characteristics mck_characteristics = {
|
||||
.output = { .min = 0, .max = 133333333 },
|
||||
.divisors = { 1, 2, 4, 3 },
|
||||
.have_div3_pres = 1,
|
||||
};
|
||||
|
||||
static u8 plla_out[] = { 0, 1, 2, 3, 0, 1, 2, 3 };
|
||||
|
||||
static u16 plla_icpll[] = { 0, 0, 0, 0, 1, 1, 1, 1 };
|
||||
|
||||
static const struct clk_range plla_outputs[] = {
|
||||
{ .min = 745000000, .max = 800000000 },
|
||||
{ .min = 695000000, .max = 750000000 },
|
||||
{ .min = 645000000, .max = 700000000 },
|
||||
{ .min = 595000000, .max = 650000000 },
|
||||
{ .min = 545000000, .max = 600000000 },
|
||||
{ .min = 495000000, .max = 555000000 },
|
||||
{ .min = 445000000, .max = 500000000 },
|
||||
{ .min = 400000000, .max = 450000000 },
|
||||
};
|
||||
|
||||
static const struct clk_pll_characteristics plla_characteristics = {
|
||||
.input = { .min = 2000000, .max = 32000000 },
|
||||
.num_output = ARRAY_SIZE(plla_outputs),
|
||||
.output = plla_outputs,
|
||||
.icpll = plla_icpll,
|
||||
.out = plla_out,
|
||||
};
|
||||
|
||||
static u8 pllb_out[] = { 0 };
|
||||
|
||||
static const struct clk_range pllb_outputs[] = {
|
||||
{ .min = 30000000, .max = 100000000 },
|
||||
};
|
||||
|
||||
static const struct clk_pll_characteristics pllb_characteristics = {
|
||||
.input = { .min = 2000000, .max = 32000000 },
|
||||
.num_output = ARRAY_SIZE(pllb_outputs),
|
||||
.output = pllb_outputs,
|
||||
.out = pllb_out,
|
||||
};
|
||||
|
||||
static const struct {
|
||||
char *n;
|
||||
char *p;
|
||||
u8 id;
|
||||
} at91sam9n12_systemck[] = {
|
||||
{ .n = "ddrck", .p = "masterck", .id = 2 },
|
||||
{ .n = "lcdck", .p = "masterck", .id = 3 },
|
||||
{ .n = "uhpck", .p = "usbck", .id = 6 },
|
||||
{ .n = "udpck", .p = "usbck", .id = 7 },
|
||||
{ .n = "pck0", .p = "prog0", .id = 8 },
|
||||
{ .n = "pck1", .p = "prog1", .id = 9 },
|
||||
};
|
||||
|
||||
static const struct clk_pcr_layout at91sam9n12_pcr_layout = {
|
||||
.offset = 0x10c,
|
||||
.cmd = BIT(12),
|
||||
.pid_mask = GENMASK(5, 0),
|
||||
.div_mask = GENMASK(17, 16),
|
||||
};
|
||||
|
||||
struct pck {
|
||||
char *n;
|
||||
u8 id;
|
||||
};
|
||||
|
||||
static const struct pck at91sam9n12_periphck[] = {
|
||||
{ .n = "pioAB_clk", .id = 2, },
|
||||
{ .n = "pioCD_clk", .id = 3, },
|
||||
{ .n = "fuse_clk", .id = 4, },
|
||||
{ .n = "usart0_clk", .id = 5, },
|
||||
{ .n = "usart1_clk", .id = 6, },
|
||||
{ .n = "usart2_clk", .id = 7, },
|
||||
{ .n = "usart3_clk", .id = 8, },
|
||||
{ .n = "twi0_clk", .id = 9, },
|
||||
{ .n = "twi1_clk", .id = 10, },
|
||||
{ .n = "mci0_clk", .id = 12, },
|
||||
{ .n = "spi0_clk", .id = 13, },
|
||||
{ .n = "spi1_clk", .id = 14, },
|
||||
{ .n = "uart0_clk", .id = 15, },
|
||||
{ .n = "uart1_clk", .id = 16, },
|
||||
{ .n = "tcb_clk", .id = 17, },
|
||||
{ .n = "pwm_clk", .id = 18, },
|
||||
{ .n = "adc_clk", .id = 19, },
|
||||
{ .n = "dma0_clk", .id = 20, },
|
||||
{ .n = "uhphs_clk", .id = 22, },
|
||||
{ .n = "udphs_clk", .id = 23, },
|
||||
{ .n = "lcdc_clk", .id = 25, },
|
||||
{ .n = "sha_clk", .id = 27, },
|
||||
{ .n = "ssc0_clk", .id = 28, },
|
||||
{ .n = "aes_clk", .id = 29, },
|
||||
{ .n = "trng_clk", .id = 30, },
|
||||
};
|
||||
|
||||
static void __init at91sam9n12_pmc_setup(struct device_node *np)
|
||||
{
|
||||
struct clk_range range = CLK_RANGE(0, 0);
|
||||
const char *slck_name, *mainxtal_name;
|
||||
struct pmc_data *at91sam9n12_pmc;
|
||||
const char *parent_names[6];
|
||||
struct regmap *regmap;
|
||||
struct clk_hw *hw;
|
||||
int i;
|
||||
bool bypass;
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "slow_clk");
|
||||
if (i < 0)
|
||||
return;
|
||||
|
||||
slck_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "main_xtal");
|
||||
if (i < 0)
|
||||
return;
|
||||
mainxtal_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
regmap = syscon_node_to_regmap(np);
|
||||
if (IS_ERR(regmap))
|
||||
return;
|
||||
|
||||
at91sam9n12_pmc = pmc_data_allocate(PMC_MAIN + 1,
|
||||
nck(at91sam9n12_systemck), 31, 0);
|
||||
if (!at91sam9n12_pmc)
|
||||
return;
|
||||
|
||||
hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
|
||||
50000000);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
bypass = of_property_read_bool(np, "atmel,osc-bypass");
|
||||
|
||||
hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
|
||||
bypass);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
parent_names[0] = "main_rc_osc";
|
||||
parent_names[1] = "main_osc";
|
||||
hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91sam9n12_pmc->chws[PMC_MAIN] = hw;
|
||||
|
||||
hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
|
||||
&at91rm9200_pll_layout, &plla_characteristics);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack");
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_pll(regmap, "pllbck", "mainck", 1,
|
||||
&at91rm9200_pll_layout, &pllb_characteristics);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
parent_names[0] = slck_name;
|
||||
parent_names[1] = "mainck";
|
||||
parent_names[2] = "plladivck";
|
||||
parent_names[3] = "pllbck";
|
||||
hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
|
||||
&at91sam9x5_master_layout,
|
||||
&mck_characteristics);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91sam9n12_pmc->chws[PMC_MCK] = hw;
|
||||
|
||||
hw = at91sam9n12_clk_register_usb(regmap, "usbck", "pllbck");
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
parent_names[0] = slck_name;
|
||||
parent_names[1] = "mainck";
|
||||
parent_names[2] = "plladivck";
|
||||
parent_names[3] = "pllbck";
|
||||
parent_names[4] = "masterck";
|
||||
for (i = 0; i < 2; i++) {
|
||||
char name[6];
|
||||
|
||||
snprintf(name, sizeof(name), "prog%d", i);
|
||||
|
||||
hw = at91_clk_register_programmable(regmap, name,
|
||||
parent_names, 5, i,
|
||||
&at91sam9x5_programmable_layout);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(at91sam9n12_systemck); i++) {
|
||||
hw = at91_clk_register_system(regmap, at91sam9n12_systemck[i].n,
|
||||
at91sam9n12_systemck[i].p,
|
||||
at91sam9n12_systemck[i].id);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91sam9n12_pmc->shws[at91sam9n12_systemck[i].id] = hw;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(at91sam9n12_periphck); i++) {
|
||||
hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
|
||||
&at91sam9n12_pcr_layout,
|
||||
at91sam9n12_periphck[i].n,
|
||||
"masterck",
|
||||
at91sam9n12_periphck[i].id,
|
||||
&range);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
at91sam9n12_pmc->phws[at91sam9n12_periphck[i].id] = hw;
|
||||
}
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9n12_pmc);
|
||||
|
||||
return;
|
||||
|
||||
err_free:
|
||||
pmc_data_free(at91sam9n12_pmc);
|
||||
}
|
||||
/*
|
||||
* The TCB is used as the clocksource so its clock is needed early. This means
|
||||
* this can't be a platform driver.
|
||||
*/
|
||||
CLK_OF_DECLARE_DRIVER(at91sam9n12_pmc, "atmel,at91sam9n12-pmc",
|
||||
at91sam9n12_pmc_setup);
|
||||
@@ -25,6 +25,7 @@ struct at91sam9x5_clk_usb {
|
||||
struct clk_hw hw;
|
||||
struct regmap *regmap;
|
||||
u32 usbs_mask;
|
||||
u8 num_parents;
|
||||
};
|
||||
|
||||
#define to_at91sam9x5_clk_usb(hw) \
|
||||
@@ -75,6 +76,9 @@ static int at91sam9x5_clk_usb_determine_rate(struct clk_hw *hw,
|
||||
tmp_parent_rate = req->rate * div;
|
||||
tmp_parent_rate = clk_hw_round_rate(parent,
|
||||
tmp_parent_rate);
|
||||
if (!tmp_parent_rate)
|
||||
continue;
|
||||
|
||||
tmp_rate = DIV_ROUND_CLOSEST(tmp_parent_rate, div);
|
||||
if (tmp_rate < req->rate)
|
||||
tmp_diff = req->rate - tmp_rate;
|
||||
@@ -107,7 +111,7 @@ static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw);
|
||||
|
||||
if (index > 1)
|
||||
if (index >= usb->num_parents)
|
||||
return -EINVAL;
|
||||
|
||||
regmap_update_bits(usb->regmap, AT91_PMC_USB, usb->usbs_mask, index);
|
||||
@@ -211,7 +215,8 @@ _at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
|
||||
|
||||
usb->hw.init = &init;
|
||||
usb->regmap = regmap;
|
||||
usb->usbs_mask = SAM9X5_USBS_MASK;
|
||||
usb->usbs_mask = usbs_mask;
|
||||
usb->num_parents = num_parents;
|
||||
|
||||
hw = &usb->hw;
|
||||
ret = clk_hw_register(NULL, &usb->hw);
|
||||
|
||||
@@ -124,7 +124,6 @@ static const struct {
|
||||
char *n;
|
||||
u8 id;
|
||||
struct clk_range r;
|
||||
bool pll;
|
||||
} sam9x60_gck[] = {
|
||||
{ .n = "flex0_gclk", .id = 5, },
|
||||
{ .n = "flex1_gclk", .id = 6, },
|
||||
@@ -144,11 +143,9 @@ static const struct {
|
||||
{ .n = "sdmmc1_gclk", .id = 26, .r = { .min = 0, .max = 105000000 }, },
|
||||
{ .n = "flex11_gclk", .id = 32, },
|
||||
{ .n = "flex12_gclk", .id = 33, },
|
||||
{ .n = "i2s_gclk", .id = 34, .r = { .min = 0, .max = 105000000 },
|
||||
.pll = true, },
|
||||
{ .n = "i2s_gclk", .id = 34, .r = { .min = 0, .max = 105000000 }, },
|
||||
{ .n = "pit64b_gclk", .id = 37, },
|
||||
{ .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 },
|
||||
.pll = true, },
|
||||
{ .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 }, },
|
||||
{ .n = "tcb1_gclk", .id = 45, },
|
||||
{ .n = "dbgu_gclk", .id = 47, },
|
||||
};
|
||||
@@ -237,9 +234,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
|
||||
|
||||
parent_names[0] = "pllack";
|
||||
parent_names[1] = "upllck";
|
||||
parent_names[2] = "mainck";
|
||||
parent_names[3] = "mainck";
|
||||
hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 4);
|
||||
parent_names[2] = "main_osc";
|
||||
hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 3);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
@@ -290,7 +286,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
|
||||
sam9x60_gck[i].n,
|
||||
parent_names, 6,
|
||||
sam9x60_gck[i].id,
|
||||
sam9x60_gck[i].pll,
|
||||
false,
|
||||
&sam9x60_gck[i].r);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/at91.h>
|
||||
|
||||
#include "pmc.h"
|
||||
|
||||
static const struct clk_master_characteristics mck_characteristics = {
|
||||
.output = { .min = 0, .max = 166000000 },
|
||||
.divisors = { 1, 2, 4, 3 },
|
||||
};
|
||||
|
||||
static u8 plla_out[] = { 0 };
|
||||
|
||||
static u16 plla_icpll[] = { 0 };
|
||||
|
||||
static const struct clk_range plla_outputs[] = {
|
||||
{ .min = 400000000, .max = 1000000000 },
|
||||
};
|
||||
|
||||
static const struct clk_pll_characteristics plla_characteristics = {
|
||||
.input = { .min = 8000000, .max = 50000000 },
|
||||
.num_output = ARRAY_SIZE(plla_outputs),
|
||||
.output = plla_outputs,
|
||||
.icpll = plla_icpll,
|
||||
.out = plla_out,
|
||||
};
|
||||
|
||||
static const struct clk_pcr_layout sama5d3_pcr_layout = {
|
||||
.offset = 0x10c,
|
||||
.cmd = BIT(12),
|
||||
.pid_mask = GENMASK(6, 0),
|
||||
.div_mask = GENMASK(17, 16),
|
||||
};
|
||||
|
||||
static const struct {
|
||||
char *n;
|
||||
char *p;
|
||||
u8 id;
|
||||
} sama5d3_systemck[] = {
|
||||
{ .n = "ddrck", .p = "masterck", .id = 2 },
|
||||
{ .n = "lcdck", .p = "masterck", .id = 3 },
|
||||
{ .n = "smdck", .p = "smdclk", .id = 4 },
|
||||
{ .n = "uhpck", .p = "usbck", .id = 6 },
|
||||
{ .n = "udpck", .p = "usbck", .id = 7 },
|
||||
{ .n = "pck0", .p = "prog0", .id = 8 },
|
||||
{ .n = "pck1", .p = "prog1", .id = 9 },
|
||||
{ .n = "pck2", .p = "prog2", .id = 10 },
|
||||
};
|
||||
|
||||
static const struct {
|
||||
char *n;
|
||||
u8 id;
|
||||
struct clk_range r;
|
||||
} sama5d3_periphck[] = {
|
||||
{ .n = "dbgu_clk", .id = 2, },
|
||||
{ .n = "hsmc_clk", .id = 5, },
|
||||
{ .n = "pioA_clk", .id = 6, },
|
||||
{ .n = "pioB_clk", .id = 7, },
|
||||
{ .n = "pioC_clk", .id = 8, },
|
||||
{ .n = "pioD_clk", .id = 9, },
|
||||
{ .n = "pioE_clk", .id = 10, },
|
||||
{ .n = "usart0_clk", .id = 12, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "usart1_clk", .id = 13, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "usart2_clk", .id = 14, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "usart3_clk", .id = 15, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "uart0_clk", .id = 16, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "uart1_clk", .id = 17, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "twi0_clk", .id = 18, .r = { .min = 0, .max = 41500000 }, },
|
||||
{ .n = "twi1_clk", .id = 19, .r = { .min = 0, .max = 41500000 }, },
|
||||
{ .n = "twi2_clk", .id = 20, .r = { .min = 0, .max = 41500000 }, },
|
||||
{ .n = "mci0_clk", .id = 21, },
|
||||
{ .n = "mci1_clk", .id = 22, },
|
||||
{ .n = "mci2_clk", .id = 23, },
|
||||
{ .n = "spi0_clk", .id = 24, .r = { .min = 0, .max = 166000000 }, },
|
||||
{ .n = "spi1_clk", .id = 25, .r = { .min = 0, .max = 166000000 }, },
|
||||
{ .n = "tcb0_clk", .id = 26, .r = { .min = 0, .max = 166000000 }, },
|
||||
{ .n = "tcb1_clk", .id = 27, .r = { .min = 0, .max = 166000000 }, },
|
||||
{ .n = "pwm_clk", .id = 28, },
|
||||
{ .n = "adc_clk", .id = 29, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "dma0_clk", .id = 30, },
|
||||
{ .n = "dma1_clk", .id = 31, },
|
||||
{ .n = "uhphs_clk", .id = 32, },
|
||||
{ .n = "udphs_clk", .id = 33, },
|
||||
{ .n = "macb0_clk", .id = 34, },
|
||||
{ .n = "macb1_clk", .id = 35, },
|
||||
{ .n = "lcdc_clk", .id = 36, },
|
||||
{ .n = "isi_clk", .id = 37, },
|
||||
{ .n = "ssc0_clk", .id = 38, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "ssc1_clk", .id = 39, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "can0_clk", .id = 40, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "can1_clk", .id = 41, .r = { .min = 0, .max = 83000000 }, },
|
||||
{ .n = "sha_clk", .id = 42, },
|
||||
{ .n = "aes_clk", .id = 43, },
|
||||
{ .n = "tdes_clk", .id = 44, },
|
||||
{ .n = "trng_clk", .id = 45, },
|
||||
{ .n = "fuse_clk", .id = 48, },
|
||||
{ .n = "mpddr_clk", .id = 49, },
|
||||
};
|
||||
|
||||
static void __init sama5d3_pmc_setup(struct device_node *np)
|
||||
{
|
||||
const char *slck_name, *mainxtal_name;
|
||||
struct pmc_data *sama5d3_pmc;
|
||||
const char *parent_names[5];
|
||||
struct regmap *regmap;
|
||||
struct clk_hw *hw;
|
||||
int i;
|
||||
bool bypass;
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "slow_clk");
|
||||
if (i < 0)
|
||||
return;
|
||||
|
||||
slck_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
i = of_property_match_string(np, "clock-names", "main_xtal");
|
||||
if (i < 0)
|
||||
return;
|
||||
mainxtal_name = of_clk_get_parent_name(np, i);
|
||||
|
||||
regmap = syscon_node_to_regmap(np);
|
||||
if (IS_ERR(regmap))
|
||||
return;
|
||||
|
||||
sama5d3_pmc = pmc_data_allocate(PMC_MAIN + 1,
|
||||
nck(sama5d3_systemck),
|
||||
nck(sama5d3_periphck), 0);
|
||||
if (!sama5d3_pmc)
|
||||
return;
|
||||
|
||||
hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 12000000,
|
||||
50000000);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
bypass = of_property_read_bool(np, "atmel,osc-bypass");
|
||||
|
||||
hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name,
|
||||
bypass);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
parent_names[0] = "main_rc_osc";
|
||||
parent_names[1] = "main_osc";
|
||||
hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
|
||||
&sama5d3_pll_layout, &plla_characteristics);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_plldiv(regmap, "plladivck", "pllack");
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
sama5d3_pmc->chws[PMC_UTMI] = hw;
|
||||
|
||||
parent_names[0] = slck_name;
|
||||
parent_names[1] = "mainck";
|
||||
parent_names[2] = "plladivck";
|
||||
parent_names[3] = "utmick";
|
||||
hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
|
||||
&at91sam9x5_master_layout,
|
||||
&mck_characteristics);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
sama5d3_pmc->chws[PMC_MCK] = hw;
|
||||
|
||||
parent_names[0] = "plladivck";
|
||||
parent_names[1] = "utmick";
|
||||
hw = at91sam9x5_clk_register_usb(regmap, "usbck", parent_names, 2);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
hw = at91sam9x5_clk_register_smd(regmap, "smdclk", parent_names, 2);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
parent_names[0] = slck_name;
|
||||
parent_names[1] = "mainck";
|
||||
parent_names[2] = "plladivck";
|
||||
parent_names[3] = "utmick";
|
||||
parent_names[4] = "masterck";
|
||||
for (i = 0; i < 3; i++) {
|
||||
char name[6];
|
||||
|
||||
snprintf(name, sizeof(name), "prog%d", i);
|
||||
|
||||
hw = at91_clk_register_programmable(regmap, name,
|
||||
parent_names, 5, i,
|
||||
&at91sam9x5_programmable_layout);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sama5d3_systemck); i++) {
|
||||
hw = at91_clk_register_system(regmap, sama5d3_systemck[i].n,
|
||||
sama5d3_systemck[i].p,
|
||||
sama5d3_systemck[i].id);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
sama5d3_pmc->shws[sama5d3_systemck[i].id] = hw;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(sama5d3_periphck); i++) {
|
||||
hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
|
||||
&sama5d3_pcr_layout,
|
||||
sama5d3_periphck[i].n,
|
||||
"masterck",
|
||||
sama5d3_periphck[i].id,
|
||||
&sama5d3_periphck[i].r);
|
||||
if (IS_ERR(hw))
|
||||
goto err_free;
|
||||
|
||||
sama5d3_pmc->phws[sama5d3_periphck[i].id] = hw;
|
||||
}
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sama5d3_pmc);
|
||||
|
||||
return;
|
||||
|
||||
err_free:
|
||||
pmc_data_free(sama5d3_pmc);
|
||||
}
|
||||
/*
|
||||
* The TCB is used as the clocksource so its clock is needed early. This means
|
||||
* this can't be a platform driver.
|
||||
*/
|
||||
CLK_OF_DECLARE_DRIVER(sama5d3_pmc, "atmel,sama5d3-pmc", sama5d3_pmc_setup);
|
||||
+1
-1
@@ -774,7 +774,7 @@ static void clk_core_rate_restore_protect(struct clk_core *core, int count)
|
||||
* clk_rate_exclusive_get - get exclusivity over the clk rate control
|
||||
* @clk: the clk over which the exclusity of rate control is requested
|
||||
*
|
||||
* clk_rate_exlusive_get() begins a critical section during which a clock
|
||||
* clk_rate_exclusive_get() begins a critical section during which a clock
|
||||
* consumer cannot tolerate any other consumer making any operation on the
|
||||
* clock which could result in a rate change or rate glitch. Exclusive clocks
|
||||
* cannot have their rate changed, either directly or indirectly due to changes
|
||||
|
||||
@@ -432,8 +432,10 @@ static void __init jz4770_cgu_init(struct device_node *np)
|
||||
|
||||
cgu = ingenic_cgu_new(jz4770_cgu_clocks,
|
||||
ARRAY_SIZE(jz4770_cgu_clocks), np);
|
||||
if (!cgu)
|
||||
if (!cgu) {
|
||||
pr_err("%s: failed to initialise CGU\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
retval = ingenic_cgu_register_clocks(cgu);
|
||||
if (retval)
|
||||
|
||||
@@ -9,14 +9,16 @@
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <dt-bindings/clock/jz4780-cgu.h>
|
||||
#include "cgu.h"
|
||||
#include "pm.h"
|
||||
|
||||
/* CGU register offsets */
|
||||
#define CGU_REG_CLOCKCONTROL 0x00
|
||||
#define CGU_REG_PLLCONTROL 0x0c
|
||||
#define CGU_REG_LCR 0x04
|
||||
#define CGU_REG_APLL 0x10
|
||||
#define CGU_REG_MPLL 0x14
|
||||
#define CGU_REG_EPLL 0x18
|
||||
@@ -46,8 +48,8 @@
|
||||
#define CGU_REG_CLOCKSTATUS 0xd4
|
||||
|
||||
/* bits within the OPCR register */
|
||||
#define OPCR_SPENDN0 (1 << 7)
|
||||
#define OPCR_SPENDN1 (1 << 6)
|
||||
#define OPCR_SPENDN0 BIT(7)
|
||||
#define OPCR_SPENDN1 BIT(6)
|
||||
|
||||
/* bits within the USBPCR register */
|
||||
#define USBPCR_USB_MODE BIT(31)
|
||||
@@ -88,6 +90,13 @@
|
||||
#define USBVBFIL_IDDIGFIL_MASK (0xffff << USBVBFIL_IDDIGFIL_SHIFT)
|
||||
#define USBVBFIL_USBVBFIL_MASK (0xffff)
|
||||
|
||||
/* bits within the LCR register */
|
||||
#define LCR_PD_SCPU BIT(31)
|
||||
#define LCR_SCPUS BIT(27)
|
||||
|
||||
/* bits within the CLKGR1 register */
|
||||
#define CLKGR1_CORE1 BIT(15)
|
||||
|
||||
static struct ingenic_cgu *cgu;
|
||||
|
||||
static u8 jz4780_otg_phy_get_parent(struct clk_hw *hw)
|
||||
@@ -205,6 +214,42 @@ static const struct clk_ops jz4780_otg_phy_ops = {
|
||||
.set_rate = jz4780_otg_phy_set_rate,
|
||||
};
|
||||
|
||||
static int jz4780_core1_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const unsigned int timeout = 5000;
|
||||
unsigned long flags;
|
||||
int retval;
|
||||
u32 lcr, clkgr1;
|
||||
|
||||
spin_lock_irqsave(&cgu->lock, flags);
|
||||
|
||||
lcr = readl(cgu->base + CGU_REG_LCR);
|
||||
lcr &= ~LCR_PD_SCPU;
|
||||
writel(lcr, cgu->base + CGU_REG_LCR);
|
||||
|
||||
clkgr1 = readl(cgu->base + CGU_REG_CLKGR1);
|
||||
clkgr1 &= ~CLKGR1_CORE1;
|
||||
writel(clkgr1, cgu->base + CGU_REG_CLKGR1);
|
||||
|
||||
spin_unlock_irqrestore(&cgu->lock, flags);
|
||||
|
||||
/* wait for the CPU to be powered up */
|
||||
retval = readl_poll_timeout(cgu->base + CGU_REG_LCR, lcr,
|
||||
!(lcr & LCR_SCPUS), 10, timeout);
|
||||
if (retval == -ETIMEDOUT) {
|
||||
pr_err("%s: Wait for power up core1 timeout\n", __func__);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops jz4780_core1_ops = {
|
||||
.enable = jz4780_core1_enable,
|
||||
};
|
||||
|
||||
static const s8 pll_od_encoding[16] = {
|
||||
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
|
||||
0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf,
|
||||
@@ -699,9 +744,9 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
|
||||
},
|
||||
|
||||
[JZ4780_CLK_CORE1] = {
|
||||
"core1", CGU_CLK_GATE,
|
||||
"core1", CGU_CLK_CUSTOM,
|
||||
.parents = { JZ4780_CLK_CPU, -1, -1, -1 },
|
||||
.gate = { CGU_REG_CLKGR1, 15 },
|
||||
.custom = { &jz4780_core1_ops },
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
@@ -189,7 +189,7 @@ static long ingenic_tcu_round_rate(struct clk_hw *hw, unsigned long req_rate,
|
||||
u8 prescale;
|
||||
|
||||
if (req_rate > rate)
|
||||
return -EINVAL;
|
||||
return rate;
|
||||
|
||||
prescale = ingenic_tcu_get_prescale(rate, req_rate);
|
||||
|
||||
@@ -317,10 +317,17 @@ static const struct ingenic_soc_info jz4770_soc_info = {
|
||||
.has_tcu_clk = false,
|
||||
};
|
||||
|
||||
static const struct ingenic_soc_info x1000_soc_info = {
|
||||
.num_channels = 8,
|
||||
.has_ost = false, /* X1000 has OST, but it not belong TCU */
|
||||
.has_tcu_clk = false,
|
||||
};
|
||||
|
||||
static const struct of_device_id 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, },
|
||||
{ .compatible = "ingenic,x1000-tcu", .data = &x1000_soc_info, },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
@@ -471,3 +478,4 @@ static void __init ingenic_tcu_init(struct device_node *np)
|
||||
CLK_OF_DECLARE_DRIVER(jz4740_cgu, "ingenic,jz4740-tcu", ingenic_tcu_init);
|
||||
CLK_OF_DECLARE_DRIVER(jz4725b_cgu, "ingenic,jz4725b-tcu", ingenic_tcu_init);
|
||||
CLK_OF_DECLARE_DRIVER(jz4770_cgu, "ingenic,jz4770-tcu", ingenic_tcu_init);
|
||||
CLK_OF_DECLARE_DRIVER(x1000_cgu, "ingenic,x1000-tcu", ingenic_tcu_init);
|
||||
|
||||
@@ -26,3 +26,11 @@ config TI_SCI_CLK_PROBE_FROM_FW
|
||||
This is mostly only useful for debugging purposes, and will
|
||||
increase the boot time of the device. If you want the clocks probed
|
||||
from firmware, say Y. Otherwise, say N.
|
||||
|
||||
config TI_SYSCON_CLK
|
||||
tristate "Syscon based clock driver for K2/K3 SoCs"
|
||||
depends on ARCH_KEYSTONE || ARCH_K3 || COMPILE_TEST
|
||||
default ARCH_KEYSTONE || ARCH_K3
|
||||
help
|
||||
This adds clock driver support for syscon based gate
|
||||
clocks on TI's K2 and K3 SoCs.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_COMMON_CLK_KEYSTONE) += pll.o gate.o
|
||||
obj-$(CONFIG_TI_SCI_CLK) += sci-clk.o
|
||||
obj-$(CONFIG_TI_SYSCON_CLK) += syscon-clk.o
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user