Commit 1fe7c040 authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-actions-reset', 'clk-imx7-init-critical', 'clk-mmp2-ids'...

Merge branches 'clk-actions-reset', 'clk-imx7-init-critical', 'clk-mmp2-ids' and 'clk-at91-pmc-rework' into clk-next

 - Reset Controller (RMU) support for Actions Semi Owl S900 and S700 SoCs
 - Rework at91 PMC clock driver for new DT bindings

* clk-actions-reset:
  clk: actions: Add Actions Semi S900 SoC Reset Management Unit support
  clk: actions: Add Actions Semi S700 SoC Reset Management Unit support
  clk: actions: Add Actions Semi Owl SoCs Reset Management Unit support
  dt-bindings: reset: Add binding constants for Actions Semi S900 RMU
  dt-bindings: reset: Add binding constants for Actions Semi S700 RMU
  dt-bindings: clock: Add reset controller bindings for Actions Semi Owl SoCs
  clk: actions: Cache regmap info in private clock descriptor

* clk-imx7-init-critical:
  clk: imx7d: remove CLK_IS_CRITICAL flag for arm_a7_root_clk
  clk: imx: cpu clock should be always critical
  clk: imx: imx7d: remove clks_init_on array
  clk: imx: imx7d: remove unnecessary clocks from clks_init_on array

* clk-mmp2-ids:
  clk: mmp2: fix the clock id for sdh2_clk and sdh3_clk

* clk-at91-pmc-rework:
  clk: at91: move DT compatibility code to its own file
  clk: at91: add at91sam9rl PMC driver
  clk: at91: add at91sam9x5 PMCs driver
  clk: at91: add at91sam9260 PMC driver
  clk: at91: add sama5d2 PMC driver
  clk: at91: add sama5d4 pmc driver
  clk: at91: add new DT lookup function
  dt-bindings: clk: at91: Document new PMC binding
  clk: at91: add pmc_data struct and helpers
  clk: at91: allow clock registration from C code
  clk: at91: generated: set audio_pll_allowed in at91_clk_register_generated()
  clk: at91: audio-pll: separate registration from DT parsing
  clk: at91: h32mx: separate registration from DT parsing
  clk: at91: generated: SSCs don't have a gclk
  clk: at91: audio-pll: fix audio pmc type
......@@ -13,6 +13,7 @@ Required Properties:
region.
- clocks: Reference to the parent clocks ("hosc", "losc")
- #clock-cells: should be 1.
- #reset-cells: should be 1.
Each clock is assigned an identifier, and client nodes can use this identifier
to specify the clock which they consume.
......@@ -36,6 +37,7 @@ Example: Clock Management Unit node:
reg = <0x0 0xe0160000 0x0 0x1000>;
clocks = <&hosc>, <&losc>;
#clock-cells = <1>;
#reset-cells = <1>;
};
Example: UART controller node that consumes clock generated by the clock
......
......@@ -2,6 +2,7 @@ config CLK_ACTIONS
bool "Clock driver for Actions Semi SoCs"
depends on ARCH_ACTIONS || COMPILE_TEST
select REGMAP_MMIO
select RESET_CONTROLLER
default ARCH_ACTIONS
if CLK_ACTIONS
......
......@@ -7,6 +7,7 @@ clk-owl-y += owl-divider.o
clk-owl-y += owl-factor.o
clk-owl-y += owl-composite.o
clk-owl-y += owl-pll.o
clk-owl-y += owl-reset.o
# SoC support
obj-$(CONFIG_CLK_OWL_S700) += owl-s700.o
......
......@@ -39,7 +39,7 @@ static void owl_clk_set_regmap(const struct owl_clk_desc *desc,
}
int owl_clk_regmap_init(struct platform_device *pdev,
const struct owl_clk_desc *desc)
struct owl_clk_desc *desc)
{
void __iomem *base;
struct regmap *regmap;
......@@ -57,6 +57,7 @@ int owl_clk_regmap_init(struct platform_device *pdev,
}
owl_clk_set_regmap(desc, regmap);
desc->regmap = regmap;
return 0;
}
......
......@@ -26,6 +26,9 @@ struct owl_clk_desc {
struct owl_clk_common **clks;
unsigned long num_clks;
struct clk_hw_onecell_data *hw_clks;
const struct owl_reset_map *resets;
unsigned long num_resets;
struct regmap *regmap;
};
static inline struct owl_clk_common *
......@@ -35,7 +38,7 @@ static inline struct owl_clk_common *
}
int owl_clk_regmap_init(struct platform_device *pdev,
const struct owl_clk_desc *desc);
struct owl_clk_desc *desc);
int owl_clk_probe(struct device *dev, struct clk_hw_onecell_data *hw_clks);
#endif /* _OWL_COMMON_H_ */
// SPDX-License-Identifier: GPL-2.0-or-later
//
// Actions Semi Owl SoCs Reset Management Unit driver
//
// Copyright (c) 2018 Linaro Ltd.
// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
#include <linux/delay.h>
#include <linux/regmap.h>
#include <linux/reset-controller.h>
#include "owl-reset.h"
static int owl_reset_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct owl_reset *reset = to_owl_reset(rcdev);
const struct owl_reset_map *map = &reset->reset_map[id];
return regmap_update_bits(reset->regmap, map->reg, map->bit, 0);
}
static int owl_reset_deassert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct owl_reset *reset = to_owl_reset(rcdev);
const struct owl_reset_map *map = &reset->reset_map[id];
return regmap_update_bits(reset->regmap, map->reg, map->bit, map->bit);
}
static int owl_reset_reset(struct reset_controller_dev *rcdev,
unsigned long id)
{
owl_reset_assert(rcdev, id);
udelay(1);
owl_reset_deassert(rcdev, id);
return 0;
}
static int owl_reset_status(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct owl_reset *reset = to_owl_reset(rcdev);
const struct owl_reset_map *map = &reset->reset_map[id];
u32 reg;
int ret;
ret = regmap_read(reset->regmap, map->reg, &reg);
if (ret)
return ret;
/*
* The reset control API expects 0 if reset is not asserted,
* which is the opposite of what our hardware uses.
*/
return !(map->bit & reg);
}
const struct reset_control_ops owl_reset_ops = {
.assert = owl_reset_assert,
.deassert = owl_reset_deassert,
.reset = owl_reset_reset,
.status = owl_reset_status,
};
// SPDX-License-Identifier: GPL-2.0-or-later
//
// Actions Semi Owl SoCs Reset Management Unit driver
//
// Copyright (c) 2018 Linaro Ltd.
// Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
#ifndef _OWL_RESET_H_
#define _OWL_RESET_H_
#include <linux/reset-controller.h>
struct owl_reset_map {
u32 reg;
u32 bit;
};
struct owl_reset {
struct reset_controller_dev rcdev;
const struct owl_reset_map *reset_map;
struct regmap *regmap;
};
static inline struct owl_reset *to_owl_reset(struct reset_controller_dev *rcdev)
{
return container_of(rcdev, struct owl_reset, rcdev);
}
extern const struct reset_control_ops owl_reset_ops;
#endif /* _OWL_RESET_H_ */
......@@ -20,8 +20,10 @@
#include "owl-gate.h"
#include "owl-mux.h"
#include "owl-pll.h"
#include "owl-reset.h"
#include <dt-bindings/clock/actions,s700-cmu.h>
#include <dt-bindings/reset/actions,s700-reset.h>
#define CMU_COREPLL (0x0000)
#define CMU_DEVPLL (0x0004)
......@@ -569,20 +571,69 @@ static struct clk_hw_onecell_data s700_hw_clks = {
.num = CLK_NR_CLKS,
};
static const struct owl_clk_desc s700_clk_desc = {
static const struct owl_reset_map s700_resets[] = {
[RESET_DE] = { CMU_DEVRST0, BIT(0) },
[RESET_LCD0] = { CMU_DEVRST0, BIT(1) },
[RESET_DSI] = { CMU_DEVRST0, BIT(2) },
[RESET_CSI] = { CMU_DEVRST0, BIT(13) },
[RESET_SI] = { CMU_DEVRST0, BIT(14) },
[RESET_I2C0] = { CMU_DEVRST1, BIT(0) },
[RESET_I2C1] = { CMU_DEVRST1, BIT(1) },
[RESET_I2C2] = { CMU_DEVRST1, BIT(2) },
[RESET_I2C3] = { CMU_DEVRST1, BIT(3) },
[RESET_SPI0] = { CMU_DEVRST1, BIT(4) },
[RESET_SPI1] = { CMU_DEVRST1, BIT(5) },
[RESET_SPI2] = { CMU_DEVRST1, BIT(6) },
[RESET_SPI3] = { CMU_DEVRST1, BIT(7) },
[RESET_UART0] = { CMU_DEVRST1, BIT(8) },
[RESET_UART1] = { CMU_DEVRST1, BIT(9) },
[RESET_UART2] = { CMU_DEVRST1, BIT(10) },
[RESET_UART3] = { CMU_DEVRST1, BIT(11) },
[RESET_UART4] = { CMU_DEVRST1, BIT(12) },
[RESET_UART5] = { CMU_DEVRST1, BIT(13) },
[RESET_UART6] = { CMU_DEVRST1, BIT(14) },
[RESET_KEY] = { CMU_DEVRST1, BIT(24) },
[RESET_GPIO] = { CMU_DEVRST1, BIT(25) },
[RESET_AUDIO] = { CMU_DEVRST1, BIT(29) },
};
static struct owl_clk_desc s700_clk_desc = {
.clks = s700_clks,
.num_clks = ARRAY_SIZE(s700_clks),
.hw_clks = &s700_hw_clks,
.resets = s700_resets,
.num_resets = ARRAY_SIZE(s700_resets),
};
static int s700_clk_probe(struct platform_device *pdev)
{
const struct owl_clk_desc *desc;
struct owl_clk_desc *desc;
struct owl_reset *reset;
int ret;
desc = &s700_clk_desc;
owl_clk_regmap_init(pdev, desc);
/*
* FIXME: Reset controller registration should be moved to
* common code, once all SoCs of Owl family supports it.
*/
reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
if (!reset)
return -ENOMEM;
reset->rcdev.of_node = pdev->dev.of_node;
reset->rcdev.ops = &owl_reset_ops;
reset->rcdev.nr_resets = desc->num_resets;
reset->reset_map = desc->resets;
reset->regmap = desc->regmap;
ret = devm_reset_controller_register(&pdev->dev, &reset->rcdev);
if (ret)
dev_err(&pdev->dev, "Failed to register reset controller\n");
return owl_clk_probe(&pdev->dev, desc->hw_clks);
}
......
......@@ -19,8 +19,10 @@
#include "owl-gate.h"
#include "owl-mux.h"
#include "owl-pll.h"
#include "owl-reset.h"
#include <dt-bindings/clock/actions,s900-cmu.h>
#include <dt-bindings/reset/actions,s900-reset.h>
#define CMU_COREPLL (0x0000)
#define CMU_DEVPLL (0x0004)
......@@ -684,20 +686,100 @@ static struct clk_hw_onecell_data s900_hw_clks = {
.num = CLK_NR_CLKS,
};
static const struct owl_clk_desc s900_clk_desc = {
static const struct owl_reset_map s900_resets[] = {
[RESET_DMAC] = { CMU_DEVRST0, BIT(0) },
[RESET_SRAMI] = { CMU_DEVRST0, BIT(1) },
[RESET_DDR_CTL_PHY] = { CMU_DEVRST0, BIT(2) },
[RESET_NANDC0] = { CMU_DEVRST0, BIT(3) },
[RESET_SD0] = { CMU_DEVRST0, BIT(4) },
[RESET_SD1] = { CMU_DEVRST0, BIT(5) },
[RESET_PCM1] = { CMU_DEVRST0, BIT(6) },
[RESET_DE] = { CMU_DEVRST0, BIT(7) },
[RESET_LVDS] = { CMU_DEVRST0, BIT(8) },
[RESET_SD2] = { CMU_DEVRST0, BIT(9) },
[RESET_DSI] = { CMU_DEVRST0, BIT(10) },
[RESET_CSI0] = { CMU_DEVRST0, BIT(11) },
[RESET_BISP_AXI] = { CMU_DEVRST0, BIT(12) },
[RESET_CSI1] = { CMU_DEVRST0, BIT(13) },
[RESET_GPIO] = { CMU_DEVRST0, BIT(15) },
[RESET_EDP] = { CMU_DEVRST0, BIT(16) },
[RESET_AUDIO] = { CMU_DEVRST0, BIT(17) },
[RESET_PCM0] = { CMU_DEVRST0, BIT(18) },
[RESET_HDE] = { CMU_DEVRST0, BIT(21) },
[RESET_GPU3D_PA] = { CMU_DEVRST0, BIT(22) },
[RESET_IMX] = { CMU_DEVRST0, BIT(23) },
[RESET_SE] = { CMU_DEVRST0, BIT(24) },
[RESET_NANDC1] = { CMU_DEVRST0, BIT(25) },
[RESET_SD3] = { CMU_DEVRST0, BIT(26) },
[RESET_GIC] = { CMU_DEVRST0, BIT(27) },
[RESET_GPU3D_PB] = { CMU_DEVRST0, BIT(28) },
[RESET_DDR_CTL_PHY_AXI] = { CMU_DEVRST0, BIT(29) },
[RESET_CMU_DDR] = { CMU_DEVRST0, BIT(30) },
[RESET_DMM] = { CMU_DEVRST0, BIT(31) },
[RESET_USB2HUB] = { CMU_DEVRST1, BIT(0) },
[RESET_USB2HSIC] = { CMU_DEVRST1, BIT(1) },
[RESET_HDMI] = { CMU_DEVRST1, BIT(2) },
[RESET_HDCP2TX] = { CMU_DEVRST1, BIT(3) },
[RESET_UART6] = { CMU_DEVRST1, BIT(4) },
[RESET_UART0] = { CMU_DEVRST1, BIT(5) },
[RESET_UART1] = { CMU_DEVRST1, BIT(6) },
[RESET_UART2] = { CMU_DEVRST1, BIT(7) },
[RESET_SPI0] = { CMU_DEVRST1, BIT(8) },
[RESET_SPI1] = { CMU_DEVRST1, BIT(9) },
[RESET_SPI2] = { CMU_DEVRST1, BIT(10) },
[RESET_SPI3] = { CMU_DEVRST1, BIT(11) },
[RESET_I2C0] = { CMU_DEVRST1, BIT(12) },
[RESET_I2C1] = { CMU_DEVRST1, BIT(13) },
[RESET_USB3] = { CMU_DEVRST1, BIT(14) },
[RESET_UART3] = { CMU_DEVRST1, BIT(15) },
[RESET_UART4] = { CMU_DEVRST1, BIT(16) },
[RESET_UART5] = { CMU_DEVRST1, BIT(17) },
[RESET_I2C2] = { CMU_DEVRST1, BIT(18) },
[RESET_I2C3] = { CMU_DEVRST1, BIT(19) },
[RESET_ETHERNET] = { CMU_DEVRST1, BIT(20) },
[RESET_CHIPID] = { CMU_DEVRST1, BIT(21) },
[RESET_I2C4] = { CMU_DEVRST1, BIT(22) },
[RESET_I2C5] = { CMU_DEVRST1, BIT(23) },
[RESET_CPU_SCNT] = { CMU_DEVRST1, BIT(30) }
};
static struct owl_clk_desc s900_clk_desc = {
.clks = s900_clks,
.num_clks = ARRAY_SIZE(s900_clks),
.hw_clks = &s900_hw_clks,
.resets = s900_resets,
.num_resets = ARRAY_SIZE(s900_resets),
};
static int s900_clk_probe(struct platform_device *pdev)
{
const struct owl_clk_desc *desc;
struct owl_clk_desc *desc;
struct owl_reset *reset;
int ret;
desc = &s900_clk_desc;
owl_clk_regmap_init(pdev, desc);
/*
* FIXME: Reset controller registration should be moved to
* common code, once all SoCs of Owl family supports it.
*/
reset = devm_kzalloc(&pdev->dev, sizeof(*reset), GFP_KERNEL);
if (!reset)
return -ENOMEM;
reset->rcdev.of_node = pdev->dev.of_node;
reset->rcdev.ops = &owl_reset_ops;
reset->rcdev.nr_resets = desc->num_resets;
reset->reset_map = desc->resets;
reset->regmap = desc->regmap;
ret = devm_reset_controller_register(&pdev->dev, &reset->rcdev);
if (ret)
dev_err(&pdev->dev, "Failed to register reset controller\n");
return owl_clk_probe(&pdev->dev, desc->hw_clks);
}
......
......@@ -3,7 +3,7 @@
# Makefile for at91 specific clk
#
obj-y += pmc.o sckc.o
obj-y += pmc.o sckc.o dt-compat.o
obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o
obj-y += clk-system.o clk-peripheral.o clk-programmable.o
......@@ -14,3 +14,6 @@ obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o
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_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o
obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
This diff is collapsed.
// 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 sam9rl_mck_characteristics = {
.output = { .min = 0, .max = 94000000 },
.divisors = { 1, 2, 4, 0 },
};
static u8 sam9rl_plla_out[] = { 0, 2 };
static struct clk_range sam9rl_plla_outputs[] = {
{ .min = 80000000, .max = 200000000 },
{ .min = 190000000, .max = 240000000 },
};
static const struct clk_pll_characteristics sam9rl_plla_characteristics = {
.input = { .min = 1000000, .max = 32000000 },
.num_output = ARRAY_SIZE(sam9rl_plla_outputs),
.output = sam9rl_plla_outputs,
.out = sam9rl_plla_out,
};
static const struct {
char *n;
char *p;
u8 id;
} at91sam9rl_systemck[] = {
{ .n = "pck0", .p = "prog0", .id = 8 },
{ .n = "pck1", .p = "prog1", .id = 9 },
};
static const struct {
char *n;
u8 id;
} at91sam9rl_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 = "twi0_clk", .id = 11, },
{ .n = "twi1_clk", .id = 12, },
{ .n = "spi0_clk", .id = 13, },
{ .n = "ssc0_clk", .id = 14, },
{ .n = "ssc1_clk", .id = 15, },
{ .n = "tc0_clk", .id = 16, },
{ .n = "tc1_clk", .id = 17, },
{ .n = "tc2_clk", .id = 18, },
{ .n = "pwm_clk", .id = 19, },
{ .n = "adc_clk", .id = 20, },
{ .n = "dma0_clk", .id = 21, },
{ .n = "udphs_clk", .id = 22, },
{ .n = "lcd_clk", .id = 23, },
};
static void __init at91sam9rl_pmc_setup(struct device_node *np)
{
const char *slck_name, *mainxtal_name;
struct pmc_data *at91sam9rl_pmc;
const char *parent_names[6];
struct regmap *regmap;
struct clk_hw *hw;
int i;
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;
at91sam9rl_pmc = pmc_data_allocate(PMC_MAIN + 1,
nck(at91sam9rl_systemck),
nck(at91sam9rl_periphck), 0);
if (!at91sam9rl_pmc)
return;
hw = at91_clk_register_rm9200_main(regmap, "mainck", mainxtal_name);
if (IS_ERR(hw))
goto err_free;
at91sam9rl_pmc->chws[PMC_MAIN] = hw;
hw = at91_clk_register_pll(regmap, "pllack", "mainck", 0,
&at91rm9200_pll_layout,
&sam9rl_plla_characteristics);
if (IS_ERR(hw))
goto err_free;
hw = at91_clk_register_utmi(regmap, NULL, "utmick", "mainck");
if (IS_ERR(hw))
goto err_free;
at91sam9rl_pmc->chws[PMC_UTMI] = hw;
parent_names[0] = slck_name;
parent_names[1] = "mainck";
parent_names[2] = "pllack";
parent_names[3] = "utmick";
hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
&at91rm9200_master_layout,
&sam9rl_mck_characteristics);
if (IS_ERR(hw))
goto err_free;
at91sam9rl_pmc->chws[PMC_MCK] = hw;
parent_names[0] = slck_name;
parent_names[1] = "mainck";
parent_names[2] = "pllack";
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,
&at91rm9200_programmable_layout);
if (IS_ERR(hw))
goto err_free;
}
for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
hw = at91_clk_register_system(regmap, at91sam9rl_systemck[i].n,
at91sam9rl_systemck[i].p,
at91sam9rl_systemck[i].id);
if (IS_ERR(hw))
goto err_free;
at91sam9rl_pmc->shws[at91sam9rl_systemck[i].id] = hw;
}
for (i = 0; i < ARRAY_SIZE(at91sam9rl_periphck); i++) {
hw = at91_clk_register_peripheral(regmap,
at91sam9rl_periphck[i].n,
"masterck",
at91sam9rl_periphck[i].id);
if (IS_ERR(hw))
goto err_free;
at91sam9rl_pmc->phws[at91sam9rl_periphck[i].id] = hw;
}
of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9rl_pmc);
return;
err_free:
pmc_data_free(at91sam9rl_pmc);
}
CLK_OF_DECLARE_DRIVER(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup);
// 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 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;
} at91sam9x5_systemck[] = {
{ .n = "ddrck", .p = "masterck", .id = 2 },
{ .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 },
};
struct pck {
char *n;
u8 id;
};
static const struct pck at91sam9x5_periphck[] = {
{ .n = "pioAB_clk", .id = 2, },
{ .n = "pioCD_clk", .id = 3, },
{ .n = "smd_clk", .id = 4, },
{ .n = "usart0_clk", .id = 5, },
{ .n = "usart1_clk", .id = 6, },
{ .n = "usart2_clk", .id = 7, },
{ .n = "twi0_clk", .id = 9, },
{ .n = "twi1_clk", .id = 10, },
{ .n = "twi2_clk", .id = 11, },
{ .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 = "tcb0_clk", .id = 17, },
{ .n = "pwm_clk", .id = 18, },
{ .n = "adc_clk", .id = 19, },
{ .n = "dma0_clk", .id = 20, },
{ .n = "dma1_clk", .id = 21, },
{ .n = "uhphs_clk", .id = 22, },
{ .n = "udphs_clk", .id = 23, },
{ .n = "mci1_clk", .id = 26, },
{ .n = "ssc0_clk", .id = 28, },
};
static const struct pck at91sam9g15_periphck[] = {
{ .n = "lcdc_clk", .id = 25, },
{ /* sentinel */}
};
static const struct pck at91sam9g25_periphck[] = {
{ .n = "usart3_clk", .id = 8, },
{ .n = "macb0_clk", .id = 24, },
{ .n = "isi_clk", .id = 25, },
{ /* sentinel */}
};
static const struct pck at91sam9g35_periphck[] = {
{ .n = "macb0_clk", .id = 24, },
{ .n = "lcdc_clk", .id = 25, },
{ /* sentinel */}
};
static const struct pck at91sam9x25_periphck[] = {
{ .n = "usart3_clk", .id = 8, },
{ .n = "macb0_clk", .id = 24, },
{ .n = "macb1_clk", .id = 27, },
{ .n = "can0_clk", .id = 29, },
{ .n = "can1_clk", .id = 30, },
{ /* sentinel */}
};
static const struct pck at91sam9x35_periphck[] = {
{ .n = "macb0_clk", .id = 24, },
{ .n = "lcdc_clk", .id = 25, },
{ .n = "can0_clk", .id = 29, },
{ .n = "can1_clk", .id = 30, },
{ /* sentinel */}
};
static void __init at91sam9x5_pmc_setup(struct device_node *np,
const struct pck *extra_pcks,
bool has_lcdck)
{
struct clk_range range = CLK_RANGE(0, 0);
const char *slck_name, *mainxtal_name;
struct pmc_data *at91sam9x5_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;
at91sam9x5_pmc = pmc_data_allocate(PMC_MAIN + 1,
nck(at91sam9x5_systemck),
nck(at91sam9x35_periphck), 0);
if (!at91sam9x5_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;
at91sam9x5_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;
at91sam9x5_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;
at91sam9x5_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] = "mck";
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(at91sam9x5_systemck); i++) {
hw = at91_clk_register_system(regmap, at91sam9x5_systemck[i].n,
at91sam9x5_systemck[i].p,
at91sam9x5_systemck[i].id);
if (IS_ERR(hw))
goto err_free;
at91sam9x5_pmc->shws[at91sam9x5_systemck[i].id] = hw;
}
if (has_lcdck) {
hw = at91_clk_register_system(regmap, "lcdck", "masterck", 3);
if (IS_ERR(hw))
goto err_free;
at91sam9x5_pmc->shws[3] = hw;
}
for (i = 0; i < ARRAY_SIZE(at91sam9x5_periphck); i++) {
hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
at91sam9x5_periphck[i].n,
"masterck",
at91sam9x5_periphck[i].id,
&range);
if (IS_ERR(hw))
goto err_free;
at91sam9x5_pmc->phws[at91sam9x5_periphck[i].id] = hw;
}
for (i = 0; extra_pcks[i].id; i++) {
hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
extra_pcks[i].n,
"masterck",
extra_pcks[i].id,
&range);
if (IS_ERR(hw))
goto err_free;
at91sam9x5_pmc->phws[extra_pcks[i].id] = hw;
}
of_clk_add_hw_provider(np, of_clk_hw_pmc_get, at91sam9x5_pmc);
return;
err_free:
pmc_data_free(at91sam9x5_pmc);
}
static void __init at91sam9g15_pmc_setup(struct device_node *np)
{
at91sam9x5_pmc_setup(np, at91sam9g15_periphck, true);
}
CLK_OF_DECLARE_DRIVER(at91sam9g15_pmc, "atmel,at91sam9g15-pmc",
at91sam9g15_pmc_setup);
static void __init at91sam9g25_pmc_setup(struct device_node *np)
{
at91sam9x5_pmc_setup(np, at91sam9g25_periphck, false);
}
CLK_OF_DECLARE_DRIVER(at91sam9g25_pmc, "atmel,at91sam9g25-pmc",
at91sam9g25_pmc_setup);
static void __init at91sam9g35_pmc_setup(struct device_node *np)
{
at91sam9x5_pmc_setup(np, at91sam9g35_periphck, true);
}
CLK_OF_DECLARE_DRIVER(at91sam9g35_pmc, "atmel,at91sam9g35-pmc",
at91sam9g35_pmc_setup);
static void __init at91sam9x25_pmc_setup(struct device_node *np)
{
at91sam9x5_pmc_setup(np, at91sam9x25_periphck, false);
}
CLK_OF_DECLARE_DRIVER(at91sam9x25_pmc, "atmel,at91sam9x25-pmc",
at91sam9x25_pmc_setup);
static void __init at91sam9x35_pmc_setup(struct device_node *np)
{
at91sam9x5_pmc_setup(np, at91sam9x35_periphck, true);
}
CLK_OF_DECLARE_DRIVER(at91sam9x35_pmc, "atmel,at91sam9x35-pmc",
at91sam9x35_pmc_setup);
......@@ -43,6 +43,8 @@
#include <linux/regmap.h>
#include <linux/slab.h>
#include "pmc.h"
#define AUDIO_PLL_DIV_FRAC BIT(22)
#define AUDIO_PLL_ND_MAX (AT91_PMC_AUDIO_PLL_ND_MASK >> \
AT91_PMC_AUDIO_PLL_ND_OFFSET)
......@@ -444,93 +446,94 @@ static const struct clk_ops audio_pll_pmc_ops = {
.set_rate = clk_audio_pll_pmc_set_rate,
};
static int of_sama5d2_clk_audio_pll_setup(struct device_node *np,
struct clk_init_data *init,
struct clk_hw *hw,
struct regmap **clk_audio_regmap)
{
struct regmap *regmap;
const char *parent_names[1];
int ret;
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return PTR_ERR(regmap);
init->name = np->name;
of_clk_parent_fill(np, parent_names, 1);
init->parent_names = parent_names;
init->num_parents = 1;
hw->init = init;
*clk_audio_regmap = regmap;
ret = clk_hw_register(NULL, hw);
if (ret)
return ret;
return of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np)
struct clk_hw * __init
at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct clk_audio_frac *frac_ck;
struct clk_init_data init = {};
int ret;
frac_ck = kzalloc(sizeof(*frac_ck), GFP_KERNEL);
if (!frac_ck)
return;
return ERR_PTR(-ENOMEM);
init.name = name;
init.ops = &audio_pll_frac_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = CLK_SET_RATE_GATE;
if (of_sama5d2_clk_audio_pll_setup(np, &init, &frac_ck->hw,
&frac_ck->regmap))
frac_ck->hw.init = &init;
frac_ck->regmap = regmap;
ret = clk_hw_register(NULL, &frac_ck->hw);
if (ret) {
kfree(frac_ck);
return ERR_PTR(ret);
}
return &frac_ck->hw;
}
static void __init of_sama5d2_clk_audio_pll_pad_setup(struct device_node *np)
struct clk_hw * __init
at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct clk_audio_pad *apad_ck;
struct clk_init_data init = {};
struct clk_init_data init;
int ret;
apad_ck = kzalloc(sizeof(*apad_ck), GFP_KERNEL);
if (!apad_ck)
return;
return ERR_PTR(-ENOMEM);
init.name = name;
init.ops = &audio_pll_pad_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT;
if (of_sama5d2_clk_audio_pll_setup(np, &init, &apad_ck->hw,
&apad_ck->regmap))
apad_ck->hw.init = &init;
apad_ck->regmap = regmap;
ret = clk_hw_register(NULL, &apad_ck->hw);
if (ret) {
kfree(apad_ck);
return ERR_PTR(ret);
}
return &apad_ck->hw;
}
static void __init of_sama5d2_clk_audio_pll_pmc_setup(struct device_node *np)
struct clk_hw * __init
at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct clk_audio_pad *apmc_ck;
struct clk_init_data init = {};
struct clk_audio_pmc *apmc_ck;
struct clk_init_data init;
int ret;
apmc_ck = kzalloc(sizeof(*apmc_ck), GFP_KERNEL);
if (!apmc_ck)
return;
return ERR_PTR(-ENOMEM);
init.name = name;
init.ops = &audio_pll_pmc_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT;
if (of_sama5d2_clk_audio_pll_setup(np, &init, &apmc_ck->hw,
&apmc_ck->regmap))
apmc_ck->hw.init = &init;
apmc_ck->regmap = regmap;
ret = clk_hw_register(NULL, &apmc_ck->hw);
if (ret) {
kfree(apmc_ck);
}
return ERR_PTR(ret);
}
CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_frac_setup,
"atmel,sama5d2-clk-audio-pll-frac",
of_sama5d2_clk_audio_pll_frac_setup);
CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pad_setup,
"atmel,sama5d2-clk-audio-pll-pad",
of_sama5d2_clk_audio_pll_pad_setup);
CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup,
"atmel,sama5d2-clk-audio-pll-pmc",
of_sama5d2_clk_audio_pll_pmc_setup);
return &apmc_ck->hw;
}
......@@ -20,17 +20,8 @@
#include "pmc.h"
#define PERIPHERAL_MAX 64
#define PERIPHERAL_ID_MIN 2
#define GENERATED_SOURCE_MAX 6
#define GENERATED_MAX_DIV 255
#define GCK_ID_SSC0 43
#define GCK_ID_SSC1 44
#define GCK_ID_I2S0 54
#define GCK_ID_I2S1 55
#define GCK_ID_CLASSD 59
#define GCK_INDEX_DT_AUDIO_PLL 5
struct clk_generated {
......@@ -279,10 +270,10 @@ static void clk_generated_startup(struct clk_generated *gck)
>> AT91_PMC_PCR_GCKDIV_OFFSET;
}
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
const char *name, const char **parent_names,
u8 num_parents, u8 id,
u8 num_parents, u8 id, bool pll_audio,
const struct clk_range *range)
{
struct clk_generated *gck;
......@@ -306,6 +297,7 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
gck->regmap = regmap;
gck->lock = lock;
gck->range = *range;
gck->audio_pll_allowed = pll_audio;
clk_generated_startup(gck);
hw = &gck->hw;
......@@ -319,70 +311,3 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
return hw;
}
static void __init of_sama5d2_clk_generated_setup(struct device_node *np)
{
int num;
u32 id;
const char *name;
struct clk_hw *hw;
unsigned int num_parents;
const char *parent_names[GENERATED_SOURCE_MAX];
struct device_node *gcknp;
struct clk_range range = CLK_RANGE(0, 0);
struct regmap *regmap;
struct clk_generated *gck;
num_parents = of_clk_get_parent_count(np);
if (num_parents == 0 || num_parents > GENERATED_SOURCE_MAX)
return;
of_clk_parent_fill(np, parent_names, num_parents);
num = of_get_child_count(np);
if (!num || num > PERIPHERAL_MAX)
return;
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
for_each_child_of_node(np, gcknp) {
if (of_property_read_u32(gcknp, "reg", &id))
continue;
if (id < PERIPHERAL_ID_MIN || id >= PERIPHERAL_MAX)
continue;
if (of_property_read_string(np, "clock-output-names", &name))
name = gcknp->name;
of_at91_get_clk_range(gcknp, "atmel,clk-output-range",
&range);
hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name,
parent_names, num_parents,
id, &range);
gck = to_clk_generated(hw);
if (of_device_is_compatible(np,
"atmel,sama5d2-clk-generated")) {
if (gck->id == GCK_ID_SSC0 || gck->id == GCK_ID_SSC1 ||
gck->id == GCK_ID_I2S0 || gck->id == GCK_ID_I2S1 ||
gck->id == GCK_ID_CLASSD)
gck->audio_pll_allowed = true;
else
gck->audio_pll_allowed = false;
} else {
gck->audio_pll_allowed = false;
}
if (IS_ERR(hw))
continue;
of_clk_add_hw_provider(gcknp, of_clk_hw_simple_get, hw);
}
}
CLK_OF_DECLARE(of_sama5d2_clk_generated_setup, "atmel,sama5d2-clk-generated",
of_sama5d2_clk_generated_setup);
......@@ -86,25 +86,19 @@ static const struct clk_ops h32mx_ops = {
.set_rate = clk_sama5d4_h32mx_set_rate,
};
static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
struct clk_hw * __init
at91_clk_register_h32mx(struct regmap *regmap, const char *name,
const char *parent_name)
{
struct clk_sama5d4_h32mx *h32mxclk;
struct clk_init_data init;
const char *parent_name;
struct regmap *regmap;
int ret;
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
h32mxclk = kzalloc(sizeof(*h32mxclk), GFP_KERNEL);
if (!h32mxclk)
return;
parent_name = of_clk_get_parent_name(np, 0);
return ERR_PTR(-ENOMEM);
init.name = np->name;
init.name = name;
init.ops = &h32mx_ops;
init.parent_names = parent_name ? &parent_name : NULL;
init.num_parents = parent_name ? 1 : 0;
......@@ -116,10 +110,8 @@ static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
ret = clk_hw_register(NULL, &h32mxclk->hw);
if (ret) {
kfree(h32mxclk);
return;
return ERR_PTR(ret);
}
of_clk_add_hw_provider(np, of_clk_hw_simple_get, &h32mxclk->hw);
return &h32mxclk->hw;
}
CLK_OF_DECLARE(of_sama5d4_clk_h32mx_setup, "atmel,sama5d4-clk-h32mx",
of_sama5d4_clk_h32mx_setup);
......@@ -14,7 +14,7 @@
#include <soc/at91/atmel-sfr.h>
#define I2S_BUS_NR 2
#include "pmc.h"
struct clk_i2s_mux {
struct clk_hw hw;
......@@ -48,7 +48,7 @@ static const struct clk_ops clk_i2s_mux_ops = {
.determine_rate = __clk_mux_determine_rate,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
const char * const *parent_names,
unsigned int num_parents, u8 bus_id)
......@@ -78,39 +78,3 @@ at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
return &i2s_ck->hw;
}
static void __init of_sama5d2_clk_i2s_mux_setup(struct device_node *np)
{
struct regmap *regmap_sfr;
u8 bus_id;
const char *parent_names[2];
struct device_node *i2s_mux_np;
struct clk_hw *hw;
int ret;
regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
if (IS_ERR(regmap_sfr))
return;
for_each_child_of_node(np, i2s_mux_np) {
if (of_property_read_u8(i2s_mux_np, "reg", &bus_id))
continue;
if (bus_id > I2S_BUS_NR)
continue;
ret = of_clk_parent_fill(i2s_mux_np, parent_names, 2);
if (ret != 2)
continue;
hw = at91_clk_i2s_mux_register(regmap_sfr, i2s_mux_np->name,
parent_names, 2, bus_id);
if (IS_ERR(hw))
continue;
of_clk_add_hw_provider(i2s_mux_np, of_clk_hw_simple_get, hw);
}
}
CLK_OF_DECLARE(sama5d2_clk_i2s_mux, "atmel,sama5d2-clk-i2s-mux",
of_sama5d2_clk_i2s_mux_setup);
......@@ -12,7 +12,6 @@
#include <linux/clkdev.h>
#include <linux/clk/at91_pmc.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
......@@ -128,7 +127,7 @@ static const struct clk_ops main_osc_ops = {
.is_prepared = clk_main_osc_is_prepared,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_main_osc(struct regmap *regmap,
const char *name,
const char *parent_name,
......@@ -171,31 +170,6 @@ at91_clk_register_main_osc(struct regmap *regmap,
return hw;
}
static void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np)
{
struct clk_hw *hw;
const char *name = np->name;
const char *parent_name;
struct regmap *regmap;
bool bypass;
of_property_read_string(np, "clock-output-names", &name);
bypass = of_property_read_bool(np, "atmel,osc-bypass");
parent_name = of_clk_get_parent_name(np, 0);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
hw = at91_clk_register_main_osc(regmap, name, parent_name, bypass);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91rm9200_clk_main_osc, "atmel,at91rm9200-clk-main-osc",
of_at91rm9200_clk_main_osc_setup);
static bool clk_main_rc_osc_ready(struct regmap *regmap)
{
unsigned int status;
......@@ -275,7 +249,7 @@ static const struct clk_ops main_rc_osc_ops = {
.recalc_accuracy = clk_main_rc_osc_recalc_accuracy,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_main_rc_osc(struct regmap *regmap,
const char *name,
u32 frequency, u32 accuracy)
......@@ -313,32 +287,6 @@ at91_clk_register_main_rc_osc(struct regmap *regmap,
return hw;
}
static void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np)
{
struct clk_hw *hw;
u32 frequency = 0;
u32 accuracy = 0;
const char *name = np->name;
struct regmap *regmap;
of_property_read_string(np, "clock-output-names", &name);
of_property_read_u32(np, "clock-frequency", &frequency);
of_property_read_u32(np, "clock-accuracy", &accuracy);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
hw = at91_clk_register_main_rc_osc(regmap, name, frequency, accuracy);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9x5_clk_main_rc_osc, "atmel,at91sam9x5-clk-main-rc-osc",
of_at91sam9x5_clk_main_rc_osc_setup);
static int clk_main_probe_frequency(struct regmap *regmap)
{
unsigned long prep_time, timeout;
......@@ -403,7 +351,7 @@ static const struct clk_ops rm9200_main_ops = {
.recalc_rate = clk_rm9200_main_recalc_rate,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_rm9200_main(struct regmap *regmap,
const char *name,
const char *parent_name)
......@@ -442,29 +390,6 @@ at91_clk_register_rm9200_main(struct regmap *regmap,
return hw;
}
static void __init of_at91rm9200_clk_main_setup(struct device_node *np)
{
struct clk_hw *hw;
const char *parent_name;
const char *name = np->name;
struct regmap *regmap;
parent_name = of_clk_get_parent_name(np, 0);
of_property_read_string(np, "clock-output-names", &name);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
hw = at91_clk_register_rm9200_main(regmap, name, parent_name);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91rm9200_clk_main, "atmel,at91rm9200-clk-main",
of_at91rm9200_clk_main_setup);
static inline bool clk_sam9x5_main_ready(struct regmap *regmap)
{
unsigned int status;
......@@ -541,7 +466,7 @@ static const struct clk_ops sam9x5_main_ops = {
.get_parent = clk_sam9x5_main_get_parent,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_sam9x5_main(struct regmap *regmap,
const char *name,
const char **parent_names,
......@@ -583,32 +508,3 @@ at91_clk_register_sam9x5_main(struct regmap *regmap,
return hw;
}
static void __init of_at91sam9x5_clk_main_setup(struct device_node *np)
{
struct clk_hw *hw;
const char *parent_names[2];
unsigned int num_parents;
const char *name = np->name;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents == 0 || num_parents > 2)
return;
of_clk_parent_fill(np, parent_names, num_parents);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
of_property_read_string(np, "clock-output-names", &name);
hw = at91_clk_register_sam9x5_main(regmap, name, parent_names,
num_parents);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9x5_clk_main, "atmel,at91sam9x5-clk-main",
of_at91sam9x5_clk_main_setup);
......@@ -17,24 +17,11 @@
#include "pmc.h"
#define MASTER_SOURCE_MAX 4
#define MASTER_PRES_MASK 0x7
#define MASTER_PRES_MAX MASTER_PRES_MASK
#define MASTER_DIV_SHIFT 8
#define MASTER_DIV_MASK 0x3
struct clk_master_characteristics {
struct clk_range output;
u32 divisors[4];
u8 have_div3_pres;
};
struct clk_master_layout {
u32 mask;
u8 pres_shift;
};
#define to_clk_master(hw) container_of(hw, struct clk_master, hw)
struct clk_master {
......@@ -120,7 +107,7 @@ static const struct clk_ops master_ops = {
.get_parent = clk_master_get_parent,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_master(struct regmap *regmap,
const char *name, int num_parents,
const char **parent_names,
......@@ -161,92 +148,12 @@ at91_clk_register_master(struct regmap *regmap,
}
static const struct clk_master_layout at91rm9200_master_layout = {
const struct clk_master_layout at91rm9200_master_layout = {
.mask = 0x31F,
.pres_shift = 2,
};
static const struct clk_master_layout at91sam9x5_master_layout = {
const struct clk_master_layout at91sam9x5_master_layout = {
.mask = 0x373,
.pres_shift = 4,
};
static struct clk_master_characteristics * __init
of_at91_clk_master_get_characteristics(struct device_node *np)
{
struct clk_master_characteristics *characteristics;
characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
if (!characteristics)
return NULL;
if (of_at91_get_clk_range(np, "atmel,clk-output-range", &characteristics->output))
goto out_free_characteristics;
of_property_read_u32_array(np, "atmel,clk-divisors",
characteristics->divisors, 4);
characteristics->have_div3_pres =
of_property_read_bool(np, "atmel,master-clk-have-div3-pres");
return characteristics;
out_free_characteristics:
kfree(characteristics);
return NULL;
}
static void __init
of_at91_clk_master_setup(struct device_node *np,
const struct clk_master_layout *layout)
{
struct clk_hw *hw;
unsigned int num_parents;
const char *parent_names[MASTER_SOURCE_MAX];
const char *name = np->name;
struct clk_master_characteristics *characteristics;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents == 0 || num_parents > MASTER_SOURCE_MAX)
return;
of_clk_parent_fill(np, parent_names, num_parents);
of_property_read_string(np, "clock-output-names", &name);
characteristics = of_at91_clk_master_get_characteristics(np);
if (!characteristics)
return;
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
hw = at91_clk_register_master(regmap, name, num_parents,
parent_names, layout,
characteristics);
if (IS_ERR(hw))
goto out_free_characteristics;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
return;
out_free_characteristics:
kfree(characteristics);
}
static void __init of_at91rm9200_clk_master_setup(struct device_node *np)
{
of_at91_clk_master_setup(np, &at91rm9200_master_layout);
}
CLK_OF_DECLARE(at91rm9200_clk_master, "atmel,at91rm9200-clk-master",
of_at91rm9200_clk_master_setup);
static void __init of_at91sam9x5_clk_master_setup(struct device_node *np)
{
of_at91_clk_master_setup(np, &at91sam9x5_master_layout);
}
CLK_OF_DECLARE(at91sam9x5_clk_master, "atmel,at91sam9x5-clk-master",
of_at91sam9x5_clk_master_setup);
......@@ -19,11 +19,6 @@
DEFINE_SPINLOCK(pmc_pcr_lock);
#define PERIPHERAL_MAX 64
#define PERIPHERAL_AT91RM9200 0
#define PERIPHERAL_AT91SAM9X5 1
#define PERIPHERAL_ID_MIN 2
#define PERIPHERAL_ID_MAX 31
#define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX))
......@@ -104,7 +99,7 @@ static const struct clk_ops peripheral_ops = {
.is_enabled = clk_peripheral_is_enabled,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_peripheral(struct regmap *regmap, const char *name,
const char *parent_name, u32 id)
{
......@@ -331,7 +326,7 @@ static const struct clk_ops sam9x5_peripheral_ops = {
.set_rate = clk_sam9x5_peripheral_set_rate,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
const char *name, const char *parent_name,
u32 id, const struct clk_range *range)
......@@ -374,75 +369,3 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
return hw;
}
static void __init
of_at91_clk_periph_setup(struct device_node *np, u8 type)
{
int num;
u32 id;
struct clk_hw *hw;
const char *parent_name;
const char *name;
struct device_node *periphclknp;
struct regmap *regmap;
parent_name = of_clk_get_parent_name(np, 0);
if (!parent_name)
return;
num = of_get_child_count(np);
if (!num || num > PERIPHERAL_MAX)
return;
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
for_each_child_of_node(np, periphclknp) {
if (of_property_read_u32(periphclknp, "reg", &id))
continue;
if (id >= PERIPHERAL_MAX)
continue;
if (of_property_read_string(np, "clock-output-names", &name))
name = periphclknp->name;
if (type == PERIPHERAL_AT91RM9200) {
hw = at91_clk_register_peripheral(regmap, name,
parent_name, id);
} else {
struct clk_range range = CLK_RANGE(0, 0);
of_at91_get_clk_range(periphclknp,
"atmel,clk-output-range",
&range);
hw = at91_clk_register_sam9x5_peripheral(regmap,
&pmc_pcr_lock,
name,
parent_name,
id, &range);
}
if (IS_ERR(hw))
continue;
of_clk_add_hw_provider(periphclknp, of_clk_hw_simple_get, hw);
}
}
static void __init of_at91rm9200_clk_periph_setup(struct device_node *np)
{
of_at91_clk_periph_setup(np, PERIPHERAL_AT91RM9200);
}
CLK_OF_DECLARE(at91rm9200_clk_periph, "atmel,at91rm9200-clk-peripheral",
of_at91rm9200_clk_periph_setup);
static void __init of_at91sam9x5_clk_periph_setup(struct device_node *np)
{
of_at91_clk_periph_setup(np, PERIPHERAL_AT91SAM9X5);
}
CLK_OF_DECLARE(at91sam9x5_clk_periph, "atmel,at91sam9x5-clk-peripheral",
of_at91sam9x5_clk_periph_setup);
......@@ -34,20 +34,6 @@
#define PLL_OUT_SHIFT 14
#define PLL_MAX_ID 1
struct clk_pll_characteristics {
struct clk_range input;
int num_output;
struct clk_range *output;
u16 *icpll;
u8 *out;
};
struct clk_pll_layout {
u32 pllr_mask;
u16 mul_mask;
u8 mul_shift;
};
#define to_clk_pll(hw) container_of(hw, struct clk_pll, hw)
struct clk_pll {
......@@ -288,7 +274,7 @@ static const struct clk_ops pll_ops = {
.set_rate = clk_pll_set_rate,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_pll(struct regmap *regmap, const char *name,
const char *parent_name, u8 id,
const struct clk_pll_layout *layout,
......@@ -334,189 +320,26 @@ at91_clk_register_pll(struct regmap *regmap, const char *name,
}
static const struct clk_pll_layout at91rm9200_pll_layout = {
const struct clk_pll_layout at91rm9200_pll_layout = {
.pllr_mask = 0x7FFFFFF,
.mul_shift = 16,
.mul_mask = 0x7FF,
};
static const struct clk_pll_layout at91sam9g45_pll_layout = {
const struct clk_pll_layout at91sam9g45_pll_layout = {
.pllr_mask = 0xFFFFFF,
.mul_shift = 16,
.mul_mask = 0xFF,
};
static const struct clk_pll_layout at91sam9g20_pllb_layout = {
const struct clk_pll_layout at91sam9g20_pllb_layout = {
.pllr_mask = 0x3FFFFF,
.mul_shift = 16,
.mul_mask = 0x3F,
};
static const struct clk_pll_layout sama5d3_pll_layout = {
const struct clk_pll_layout sama5d3_pll_layout = {
.pllr_mask = 0x1FFFFFF,
.mul_shift = 18,
.mul_mask = 0x7F,
};
static struct clk_pll_characteristics * __init
of_at91_clk_pll_get_characteristics(struct device_node *np)
{
int i;
int offset;
u32 tmp;
int num_output;
u32 num_cells;
struct clk_range input;
struct clk_range *output;
u8 *out = NULL;
u16 *icpll = NULL;
struct clk_pll_characteristics *characteristics;
if (of_at91_get_clk_range(np, "atmel,clk-input-range", &input))
return NULL;
if (of_property_read_u32(np, "#atmel,pll-clk-output-range-cells",
&num_cells))
return NULL;
if (num_cells < 2 || num_cells > 4)
return NULL;
if (!of_get_property(np, "atmel,pll-clk-output-ranges", &tmp))
return NULL;
num_output = tmp / (sizeof(u32) * num_cells);
characteristics = kzalloc(sizeof(*characteristics), GFP_KERNEL);
if (!characteristics)
return NULL;
output = kcalloc(num_output, sizeof(*output), GFP_KERNEL);
if (!output)
goto out_free_characteristics;
if (num_cells > 2) {
out = kcalloc(num_output, sizeof(*out), GFP_KERNEL);
if (!out)
goto out_free_output;
}
if (num_cells > 3) {
icpll = kcalloc(num_output, sizeof(*icpll), GFP_KERNEL);
if (!icpll)
goto out_free_output;
}
for (i = 0; i < num_output; i++) {
offset = i * num_cells;
if (of_property_read_u32_index(np,
"atmel,pll-clk-output-ranges",
offset, &tmp))
goto out_free_output;
output[i].min = tmp;
if (of_property_read_u32_index(np,
"atmel,pll-clk-output-ranges",
offset + 1, &tmp))
goto out_free_output;
output[i].max = tmp;
if (num_cells == 2)
continue;
if (of_property_read_u32_index(np,
"atmel,pll-clk-output-ranges",
offset + 2, &tmp))
goto out_free_output;
out[i] = tmp;
if (num_cells == 3)
continue;
if (of_property_read_u32_index(np,
"atmel,pll-clk-output-ranges",
offset + 3, &tmp))
goto out_free_output;
icpll[i] = tmp;
}
characteristics->input = input;
characteristics->num_output = num_output;
characteristics->output = output;
characteristics->out = out;
characteristics->icpll = icpll;
return characteristics;
out_free_output:
kfree(icpll);
kfree(out);
kfree(output);
out_free_characteristics:
kfree(characteristics);
return NULL;
}
static void __init
of_at91_clk_pll_setup(struct device_node *np,
const struct clk_pll_layout *layout)
{
u32 id;
struct clk_hw *hw;
struct regmap *regmap;
const char *parent_name;
const char *name = np->name;
struct clk_pll_characteristics *characteristics;
if (of_property_read_u32(np, "reg", &id))
return;
parent_name = of_clk_get_parent_name(np, 0);
of_property_read_string(np, "clock-output-names", &name);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
characteristics = of_at91_clk_pll_get_characteristics(np);
if (!characteristics)
return;
hw = at91_clk_register_pll(regmap, name, parent_name, id, layout,
characteristics);
if (IS_ERR(hw))
goto out_free_characteristics;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
return;
out_free_characteristics:
kfree(characteristics);
}
static void __init of_at91rm9200_clk_pll_setup(struct device_node *np)
{
of_at91_clk_pll_setup(np, &at91rm9200_pll_layout);
}
CLK_OF_DECLARE(at91rm9200_clk_pll, "atmel,at91rm9200-clk-pll",
of_at91rm9200_clk_pll_setup);
static void __init of_at91sam9g45_clk_pll_setup(struct device_node *np)
{
of_at91_clk_pll_setup(np, &at91sam9g45_pll_layout);
}
CLK_OF_DECLARE(at91sam9g45_clk_pll, "atmel,at91sam9g45-clk-pll",
of_at91sam9g45_clk_pll_setup);
static void __init of_at91sam9g20_clk_pllb_setup(struct device_node *np)
{
of_at91_clk_pll_setup(np, &at91sam9g20_pllb_layout);
}
CLK_OF_DECLARE(at91sam9g20_clk_pllb, "atmel,at91sam9g20-clk-pllb",
of_at91sam9g20_clk_pllb_setup);
static void __init of_sama5d3_clk_pll_setup(struct device_node *np)
{
of_at91_clk_pll_setup(np, &sama5d3_pll_layout);
}
CLK_OF_DECLARE(sama5d3_clk_pll, "atmel,sama5d3-clk-pll",
of_sama5d3_clk_pll_setup);
......@@ -75,7 +75,7 @@ static const struct clk_ops plldiv_ops = {
.set_rate = clk_plldiv_set_rate,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_plldiv(struct regmap *regmap, const char *name,
const char *parent_name)
{
......@@ -106,28 +106,3 @@ at91_clk_register_plldiv(struct regmap *regmap, const char *name,
return hw;
}
static void __init
of_at91sam9x5_clk_plldiv_setup(struct device_node *np)
{
struct clk_hw *hw;
const char *parent_name;
const char *name = np->name;
struct regmap *regmap;
parent_name = of_clk_get_parent_name(np, 0);
of_property_read_string(np, "clock-output-names", &name);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
hw = at91_clk_register_plldiv(regmap, name, parent_name);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9x5_clk_plldiv, "atmel,at91sam9x5-clk-plldiv",
of_at91sam9x5_clk_plldiv_setup);
......@@ -17,7 +17,6 @@
#include "pmc.h"
#define PROG_SOURCE_MAX 5
#define PROG_ID_MAX 7
#define PROG_STATUS_MASK(id) (1 << ((id) + 8))
......@@ -25,12 +24,6 @@
#define PROG_PRES(layout, pckr) ((pckr >> layout->pres_shift) & PROG_PRES_MASK)
#define PROG_MAX_RM9200_CSS 3
struct clk_programmable_layout {
u8 pres_shift;
u8 css_mask;
u8 have_slck_mck;
};
struct clk_programmable {
struct clk_hw hw;
struct regmap *regmap;
......@@ -170,7 +163,7 @@ static const struct clk_ops programmable_ops = {
.set_rate = clk_programmable_set_rate,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_programmable(struct regmap *regmap,
const char *name, const char **parent_names,
u8 num_parents, u8 id,
......@@ -211,86 +204,20 @@ at91_clk_register_programmable(struct regmap *regmap,
return hw;
}
static const struct clk_programmable_layout at91rm9200_programmable_layout = {
const struct clk_programmable_layout at91rm9200_programmable_layout = {
.pres_shift = 2,
.css_mask = 0x3,
.have_slck_mck = 0,
};
static const struct clk_programmable_layout at91sam9g45_programmable_layout = {
const struct clk_programmable_layout at91sam9g45_programmable_layout = {
.pres_shift = 2,
.css_mask = 0x3,
.have_slck_mck = 1,
};
static const struct clk_programmable_layout at91sam9x5_programmable_layout = {
const struct clk_programmable_layout at91sam9x5_programmable_layout = {
.pres_shift = 4,
.css_mask = 0x7,
.have_slck_mck = 0,
};
static void __init
of_at91_clk_prog_setup(struct device_node *np,
const struct clk_programmable_layout *layout)
{
int num;
u32 id;
struct clk_hw *hw;
unsigned int num_parents;
const char *parent_names[PROG_SOURCE_MAX];
const char *name;
struct device_node *progclknp;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents == 0 || num_parents > PROG_SOURCE_MAX)
return;
of_clk_parent_fill(np, parent_names, num_parents);
num = of_get_child_count(np);
if (!num || num > (PROG_ID_MAX + 1))
return;
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
for_each_child_of_node(np, progclknp) {
if (of_property_read_u32(progclknp, "reg", &id))
continue;
if (of_property_read_string(np, "clock-output-names", &name))
name = progclknp->name;
hw = at91_clk_register_programmable(regmap, name,
parent_names, num_parents,
id, layout);
if (IS_ERR(hw))
continue;
of_clk_add_hw_provider(progclknp, of_clk_hw_simple_get, hw);
}
}
static void __init of_at91rm9200_clk_prog_setup(struct device_node *np)
{
of_at91_clk_prog_setup(np, &at91rm9200_programmable_layout);
}
CLK_OF_DECLARE(at91rm9200_clk_prog, "atmel,at91rm9200-clk-programmable",
of_at91rm9200_clk_prog_setup);
static void __init of_at91sam9g45_clk_prog_setup(struct device_node *np)
{
of_at91_clk_prog_setup(np, &at91sam9g45_programmable_layout);
}
CLK_OF_DECLARE(at91sam9g45_clk_prog, "atmel,at91sam9g45-clk-programmable",
of_at91sam9g45_clk_prog_setup);
static void __init of_at91sam9x5_clk_prog_setup(struct device_node *np)
{
of_at91_clk_prog_setup(np, &at91sam9x5_programmable_layout);
}
CLK_OF_DECLARE(at91sam9x5_clk_prog, "atmel,at91sam9x5-clk-programmable",
of_at91sam9x5_clk_prog_setup);
......@@ -40,7 +40,7 @@ static const struct clk_ops sam9260_slow_ops = {
.get_parent = clk_sam9260_slow_get_parent,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_sam9260_slow(struct regmap *regmap,
const char *name,
const char **parent_names,
......@@ -79,33 +79,3 @@ at91_clk_register_sam9260_slow(struct regmap *regmap,
return hw;
}
static void __init of_at91sam9260_clk_slow_setup(struct device_node *np)
{
struct clk_hw *hw;
const char *parent_names[2];
unsigned int num_parents;
const char *name = np->name;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents != 2)
return;
of_clk_parent_fill(np, parent_names, num_parents);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
of_property_read_string(np, "clock-output-names", &name);
hw = at91_clk_register_sam9260_slow(regmap, name, parent_names,
num_parents);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9260_clk_slow, "atmel,at91sam9260-clk-slow",
of_at91sam9260_clk_slow_setup);
......@@ -17,8 +17,6 @@
#include "pmc.h"
#define SMD_SOURCE_MAX 2
#define SMD_DIV_SHIFT 8
#define SMD_MAX_DIV 0xf
......@@ -111,7 +109,7 @@ static const struct clk_ops at91sam9x5_smd_ops = {
.set_rate = at91sam9x5_clk_smd_set_rate,
};
static struct clk_hw * __init
struct clk_hw * __init
at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents)
{
......@@ -142,33 +140,3 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
return hw;
}
static void __init of_at91sam9x5_clk_smd_setup(struct device_node *np)
{
struct clk_hw *hw;
unsigned int num_parents;
const char *parent_names[SMD_SOURCE_MAX];
const char *name = np->name;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents == 0 || num_parents > SMD_SOURCE_MAX)
return;
of_clk_parent_fill(np, parent_names, num_parents);
of_property_read_string(np, "clock-output-names", &name);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
hw = at91sam9x5_clk_register_smd(regmap, name, parent_names,
num_parents);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9x5_clk_smd, "atmel,at91sam9x5-clk-smd",
of_at91sam9x5_clk_smd_setup);
......@@ -88,7 +88,7 @@ static const struct clk_ops system_ops = {
.is_prepared = clk_system_is_prepared,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_system(struct regmap *regmap, const char *name,
const char *parent_name, u8 id)
{
......@@ -123,40 +123,3 @@ at91_clk_register_system(struct regmap *regmap, const char *name,
return hw;
}
static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
{
int num;
u32 id;
struct clk_hw *hw;
const char *name;
struct device_node *sysclknp;
const char *parent_name;
struct regmap *regmap;
num = of_get_child_count(np);
if (num > (SYSTEM_MAX_ID + 1))
return;
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
for_each_child_of_node(np, sysclknp) {
if (of_property_read_u32(sysclknp, "reg", &id))
continue;
if (of_property_read_string(np, "clock-output-names", &name))
name = sysclknp->name;
parent_name = of_clk_get_parent_name(sysclknp, 0);
hw = at91_clk_register_system(regmap, name, parent_name, id);
if (IS_ERR(hw))
continue;
of_clk_add_hw_provider(sysclknp, of_clk_hw_simple_get, hw);
}
}
CLK_OF_DECLARE(at91rm9200_clk_sys, "atmel,at91rm9200-clk-system",
of_at91rm9200_clk_sys_setup);
......@@ -17,8 +17,6 @@
#include "pmc.h"
#define USB_SOURCE_MAX 2
#define SAM9X5_USB_DIV_SHIFT 8
#define SAM9X5_USB_MAX_DIV 0xf
......@@ -192,7 +190,7 @@ static const struct clk_ops at91sam9n12_usb_ops = {
.set_rate = at91sam9x5_clk_usb_set_rate,
};
static struct clk_hw * __init
struct clk_hw * __init
at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents)
{
......@@ -225,7 +223,7 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
return hw;
}
static struct clk_hw * __init
struct clk_hw * __init
at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
const char *parent_name)
{
......@@ -342,7 +340,7 @@ static const struct clk_ops at91rm9200_usb_ops = {
.set_rate = at91rm9200_clk_usb_set_rate,
};
static struct clk_hw * __init
struct clk_hw * __init
at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
const char *parent_name, const u32 *divisors)
{
......@@ -374,89 +372,3 @@ at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
return hw;
}
static void __init of_at91sam9x5_clk_usb_setup(struct device_node *np)
{
struct clk_hw *hw;
unsigned int num_parents;
const char *parent_names[USB_SOURCE_MAX];
const char *name = np->name;
struct regmap *regmap;
num_parents = of_clk_get_parent_count(np);
if (num_parents == 0 || num_parents > USB_SOURCE_MAX)
return;
of_clk_parent_fill(np, parent_names, num_parents);
of_property_read_string(np, "clock-output-names", &name);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
hw = at91sam9x5_clk_register_usb(regmap, name, parent_names,
num_parents);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9x5_clk_usb, "atmel,at91sam9x5-clk-usb",
of_at91sam9x5_clk_usb_setup);
static void __init of_at91sam9n12_clk_usb_setup(struct device_node *np)
{
struct clk_hw *hw;
const char *parent_name;
const char *name = np->name;
struct regmap *regmap;
parent_name = of_clk_get_parent_name(np, 0);
if (!parent_name)
return;
of_property_read_string(np, "clock-output-names", &name);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
hw = at91sam9n12_clk_register_usb(regmap, name, parent_name);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91sam9n12_clk_usb, "atmel,at91sam9n12-clk-usb",
of_at91sam9n12_clk_usb_setup);
static void __init of_at91rm9200_clk_usb_setup(struct device_node *np)
{
struct clk_hw *hw;
const char *parent_name;
const char *name = np->name;
u32 divisors[4] = {0, 0, 0, 0};
struct regmap *regmap;
parent_name = of_clk_get_parent_name(np, 0);
if (!parent_name)
return;
of_property_read_u32_array(np, "atmel,clk-divisors", divisors, 4);
if (!divisors[0])
return;
of_property_read_string(np, "clock-output-names", &name);
regmap = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap))
return;
hw = at91rm9200_clk_register_usb(regmap, name, parent_name, divisors);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
}
CLK_OF_DECLARE(at91rm9200_clk_usb, "atmel,at91rm9200-clk-usb",
of_at91rm9200_clk_usb_setup);
......@@ -125,7 +125,7 @@ static const struct clk_ops utmi_ops = {
.recalc_rate = clk_utmi_recalc_rate,
};
static struct clk_hw * __init
struct clk_hw * __init
at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
const char *name, const char *parent_name)
{
......@@ -157,46 +157,3 @@ at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
return hw;
}
static void __init of_at91sam9x5_clk_utmi_setup(struct device_node *np)
{
struct clk_hw *hw;
const char *parent_name;
const char *name = np->name;
struct regmap *regmap_pmc, *regmap_sfr;
parent_name = of_clk_get_parent_name(np, 0);
of_property_read_string(np, "clock-output-names", &name);
regmap_pmc = syscon_node_to_regmap(of_get_parent(np));
if (IS_ERR(regmap_pmc))
return;
/*
* If the device supports different mainck rates, this value has to be
* set in the UTMI Clock Trimming register.
* - 9x5: mainck supports several rates but it is indicated that a
* 12 MHz is needed in case of USB.
* - sama5d3 and sama5d2: mainck supports several rates. Configuring
* the FREQ field of the UTMI Clock Trimming register is mandatory.
* - sama5d4: mainck is at 12 MHz.
*
* We only need to retrieve sama5d3 or sama5d2 sfr regmap.
*/
regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d3-sfr");
if (IS_ERR(regmap_sfr)) {
regmap_sfr = syscon_regmap_lookup_by_compatible("atmel,sama5d2-sfr");
if (IS_ERR(regmap_sfr))
regmap_sfr = NULL;
}
hw = at91_clk_register_utmi(regmap_pmc, regmap_sfr, name, parent_name);
if (IS_ERR(hw))
return;
of_clk_add_hw_provider(np, of_clk_hw_simple_get, hw);
return;
}
CLK_OF_DECLARE(at91sam9x5_clk_utmi, "atmel,at91sam9x5-clk-utmi",
of_at91sam9x5_clk_utmi_setup);
This diff is collapsed.
......@@ -19,6 +19,8 @@
#include <asm/proc-fns.h>
#include <dt-bindings/clock/at91.h>
#include "pmc.h"
#define PMC_MAX_IDS 128
......@@ -47,6 +49,82 @@ int of_at91_get_clk_range(struct device_node *np, const char *propname,
}
EXPORT_SYMBOL_GPL(of_at91_get_clk_range);
struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data)
{
unsigned int type = clkspec->args[0];
unsigned int idx = clkspec->args[1];
struct pmc_data *pmc_data = data;
switch (type) {
case PMC_TYPE_CORE:
if (idx < pmc_data->ncore)
return pmc_data->chws[idx];
break;
case PMC_TYPE_SYSTEM:
if (idx < pmc_data->nsystem)
return pmc_data->shws[idx];
break;
case PMC_TYPE_PERIPHERAL:
if (idx < pmc_data->nperiph)
return pmc_data->phws[idx];
break;
case PMC_TYPE_GCK:
if (idx < pmc_data->ngck)
return pmc_data->ghws[idx];
break;
default:
break;
}
pr_err("%s: invalid type (%u) or index (%u)\n", __func__, type, idx);
return ERR_PTR(-EINVAL);
}
void pmc_data_free(struct pmc_data *pmc_data)
{
kfree(pmc_data->chws);
kfree(pmc_data->shws);
kfree(pmc_data->phws);
kfree(pmc_data->ghws);
}
struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
unsigned int nperiph, unsigned int ngck)
{
struct pmc_data *pmc_data = kzalloc(sizeof(*pmc_data), GFP_KERNEL);
if (!pmc_data)
return NULL;
pmc_data->ncore = ncore;
pmc_data->chws = kcalloc(ncore, sizeof(struct clk_hw *), GFP_KERNEL);
if (!pmc_data->chws)
goto err;
pmc_data->nsystem = nsystem;
pmc_data->shws = kcalloc(nsystem, sizeof(struct clk_hw *), GFP_KERNEL);
if (!pmc_data->shws)
goto err;
pmc_data->nperiph = nperiph;
pmc_data->phws = kcalloc(nperiph, sizeof(struct clk_hw *), GFP_KERNEL);
if (!pmc_data->phws)
goto err;
pmc_data->ngck = ngck;
pmc_data->ghws = kcalloc(ngck, sizeof(struct clk_hw *), GFP_KERNEL);
if (!pmc_data->ghws)
goto err;
return pmc_data;
err:
pmc_data_free(pmc_data);
return NULL;
}
#ifdef CONFIG_PM
static struct regmap *pmcreg;
......
......@@ -19,6 +19,17 @@
extern spinlock_t pmc_pcr_lock;
struct pmc_data {
unsigned int ncore;
struct clk_hw **chws;
unsigned int nsystem;
struct clk_hw **shws;
unsigned int nperiph;
struct clk_hw **phws;
unsigned int ngck;
struct clk_hw **ghws;
};
struct clk_range {
unsigned long min;
unsigned long max;
......@@ -26,9 +37,157 @@ struct clk_range {
#define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,}
struct clk_master_layout {
u32 mask;
u8 pres_shift;
};
extern const struct clk_master_layout at91rm9200_master_layout;
extern const struct clk_master_layout at91sam9x5_master_layout;
struct clk_master_characteristics {
struct clk_range output;
u32 divisors[4];
u8 have_div3_pres;
};
struct clk_pll_layout {
u32 pllr_mask;
u16 mul_mask;
u8 mul_shift;
};
extern const struct clk_pll_layout at91rm9200_pll_layout;
extern const struct clk_pll_layout at91sam9g45_pll_layout;
extern const struct clk_pll_layout at91sam9g20_pllb_layout;
extern const struct clk_pll_layout sama5d3_pll_layout;
struct clk_pll_characteristics {
struct clk_range input;
int num_output;
struct clk_range *output;
u16 *icpll;
u8 *out;
};
struct clk_programmable_layout {
u8 pres_shift;
u8 css_mask;
u8 have_slck_mck;
};
extern const struct clk_programmable_layout at91rm9200_programmable_layout;
extern const struct clk_programmable_layout at91sam9g45_programmable_layout;
extern const struct clk_programmable_layout at91sam9x5_programmable_layout;
#define ndck(a, s) (a[s - 1].id + 1)
#define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1)
struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem,
unsigned int nperiph, unsigned int ngck);
void pmc_data_free(struct pmc_data *pmc_data);
int of_at91_get_clk_range(struct device_node *np, const char *propname,
struct clk_range *range);
struct clk_hw *of_clk_hw_pmc_get(struct of_phandle_args *clkspec, void *data);
struct clk_hw * __init
at91_clk_register_audio_pll_frac(struct regmap *regmap, const char *name,
const char *parent_name);
struct clk_hw * __init
at91_clk_register_audio_pll_pad(struct regmap *regmap, const char *name,
const char *parent_name);
struct clk_hw * __init
at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name,
const char *parent_name);
struct clk_hw * __init
at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock,
const char *name, const char **parent_names,
u8 num_parents, u8 id, bool pll_audio,
const struct clk_range *range);
struct clk_hw * __init
at91_clk_register_h32mx(struct regmap *regmap, const char *name,
const char *parent_name);
struct clk_hw * __init
at91_clk_i2s_mux_register(struct regmap *regmap, const char *name,
const char * const *parent_names,
unsigned int num_parents, u8 bus_id);
struct clk_hw * __init
at91_clk_register_main_rc_osc(struct regmap *regmap, const char *name,
u32 frequency, u32 accuracy);
struct clk_hw * __init
at91_clk_register_main_osc(struct regmap *regmap, const char *name,
const char *parent_name, bool bypass);
struct clk_hw * __init
at91_clk_register_rm9200_main(struct regmap *regmap,
const char *name,
const char *parent_name);
struct clk_hw * __init
at91_clk_register_sam9x5_main(struct regmap *regmap, const char *name,
const char **parent_names, int num_parents);
struct clk_hw * __init
at91_clk_register_master(struct regmap *regmap, const char *name,
int num_parents, const char **parent_names,
const struct clk_master_layout *layout,
const struct clk_master_characteristics *characteristics);
struct clk_hw * __init
at91_clk_register_peripheral(struct regmap *regmap, const char *name,
const char *parent_name, u32 id);
struct clk_hw * __init
at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
const char *name, const char *parent_name,
u32 id, const struct clk_range *range);
struct clk_hw * __init
at91_clk_register_pll(struct regmap *regmap, const char *name,
const char *parent_name, u8 id,
const struct clk_pll_layout *layout,
const struct clk_pll_characteristics *characteristics);
struct clk_hw * __init
at91_clk_register_plldiv(struct regmap *regmap, const char *name,
const char *parent_name);
struct clk_hw * __init
at91_clk_register_programmable(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents, u8 id,
const struct clk_programmable_layout *layout);
struct clk_hw * __init
at91_clk_register_sam9260_slow(struct regmap *regmap,
const char *name,
const char **parent_names,
int num_parents);
struct clk_hw * __init
at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents);
struct clk_hw * __init
at91_clk_register_system(struct regmap *regmap, const char *name,
const char *parent_name, u8 id);
struct clk_hw * __init
at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,
const char **parent_names, u8 num_parents);
struct clk_hw * __init
at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name,
const char *parent_name);
struct clk_hw * __init
at91rm9200_clk_register_usb(struct regmap *regmap, const char *name,
const char *parent_name, const u32 *divisors);
struct clk_hw * __init
at91_clk_register_utmi(struct regmap *regmap_pmc, struct regmap *regmap_sfr,
const char *name, const char *parent_name);
#ifdef CONFIG_PM
void pmc_register_id(u8 id);
void pmc_register_pck(u8 pck);
......
This diff is collapsed.
This diff is collapsed.
......@@ -94,7 +94,7 @@ struct clk *imx_clk_cpu(const char *name, const char *parent_name,
init.name = name;
init.ops = &clk_cpu_ops;
init.flags = 0;
init.flags = CLK_IS_CRITICAL;
init.parent_names = &parent_name;
init.num_parents = 1;
......
......@@ -379,14 +379,6 @@ static const char *pll_enet_bypass_sel[] = { "pll_enet_main", "pll_enet_main_src
static const char *pll_audio_bypass_sel[] = { "pll_audio_main", "pll_audio_main_src", };
static const char *pll_video_bypass_sel[] = { "pll_video_main", "pll_video_main_src", };
static int const clks_init_on[] __initconst = {
IMX7D_ARM_A7_ROOT_CLK, IMX7D_MAIN_AXI_ROOT_CLK,
IMX7D_PLL_SYS_MAIN_480M_CLK, IMX7D_NAND_USDHC_BUS_ROOT_CLK,
IMX7D_DRAM_PHYM_ROOT_CLK, IMX7D_DRAM_ROOT_CLK,
IMX7D_DRAM_PHYM_ALT_ROOT_CLK, IMX7D_DRAM_ALT_ROOT_CLK,
IMX7D_AHB_CHANNEL_ROOT_CLK, IMX7D_IPG_ROOT_CLK,
};
static struct clk_onecell_data clk_data;
static struct clk ** const uart_clks[] __initconst = {
......@@ -404,7 +396,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
{
struct device_node *np;
void __iomem *base;
int i;
clks[IMX7D_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
clks[IMX7D_OSC_24M_CLK] = of_clk_get_by_name(ccm_node, "osc");
......@@ -467,7 +458,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_PLL_SYS_MAIN_120M] = imx_clk_fixed_factor("pll_sys_main_120m", "pll_sys_main_clk", 1, 4);
clks[IMX7D_PLL_DRAM_MAIN_533M] = imx_clk_fixed_factor("pll_dram_533m", "pll_dram_main_clk", 1, 2);
clks[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_gate_dis("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4);
clks[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_gate_dis_flags("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4, CLK_IS_CRITICAL);
clks[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_gate_dis("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5);
clks[IMX7D_PLL_SYS_MAIN_120M_CLK] = imx_clk_gate_dis("pll_sys_main_120m_clk", "pll_sys_main_120m", base + 0xb0, 6);
clks[IMX7D_PLL_DRAM_MAIN_533M_CLK] = imx_clk_gate("pll_dram_533m_clk", "pll_dram_533m", base + 0x70, 12);
......@@ -720,7 +711,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_divider2("nand_usdhc_root_clk", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider2("ahb_root_clk", "ahb_pre_div", base + 0x9000, 0, 6);
clks[IMX7D_IPG_ROOT_CLK] = imx_clk_divider2("ipg_root_clk", "ahb_root_clk", base + 0x9080, 0, 2);
clks[IMX7D_IPG_ROOT_CLK] = imx_clk_divider_flags("ipg_root_clk", "ahb_root_clk", base + 0x9080, 0, 2, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_PARENT);
clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider2("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider2("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3);
clks[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_divider2("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3);
......@@ -784,17 +775,17 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider2("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6);
clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider2("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6);
clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate4("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0);
clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate2_flags("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0, CLK_OPS_PARENT_ENABLE);
clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate4("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0);
clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate4("main_axi_root_clk", "axi_post_div", base + 0x4040, 0);
clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate2_flags("main_axi_root_clk", "axi_post_div", base + 0x4040, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate4("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0);
clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate4("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
clks[IMX7D_OCRAM_CLK] = imx_clk_gate4("ocram_clk", "main_axi_root_clk", base + 0x4110, 0);
clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate4("ocram_s_clk", "ahb_root_clk", base + 0x4120, 0);
clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate4("dram_root_clk", "dram_post_div", base + 0x4130, 0);
clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate2_flags("dram_root_clk", "dram_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate2_flags("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate2_flags("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate2_flags("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0);
clks[IMX7D_SNVS_CLK] = imx_clk_gate4("snvs_clk", "ipg_root_clk", base + 0x4250, 0);
clks[IMX7D_MU_ROOT_CLK] = imx_clk_gate4("mu_root_clk", "ipg_root_clk", base + 0x4270, 0);
......@@ -883,9 +874,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
clk_prepare_enable(clks[clks_init_on[i]]);
clk_set_parent(clks[IMX7D_PLL_ARM_MAIN_BYPASS], clks[IMX7D_PLL_ARM_MAIN]);
clk_set_parent(clks[IMX7D_PLL_DRAM_MAIN_BYPASS], clks[IMX7D_PLL_DRAM_MAIN]);
clk_set_parent(clks[IMX7D_PLL_SYS_MAIN_BYPASS], clks[IMX7D_PLL_SYS_MAIN]);
......
......@@ -137,6 +137,13 @@ static inline struct clk *imx_clk_gate_dis(const char *name, const char *parent,
shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
}
static inline struct clk *imx_clk_gate_dis_flags(const char *name, const char *parent,
void __iomem *reg, u8 shift, unsigned long flags)
{
return clk_register_gate(NULL, name, parent, flags | CLK_SET_RATE_PARENT, reg,
shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock);
}
static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
......
......@@ -227,8 +227,8 @@ static struct mmp_param_gate_clk apmu_gate_clks[] = {
/* The gate clocks has mux parent. */
{MMP2_CLK_SDH0, "sdh0_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
{MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
{MMP2_CLK_SDH1, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
{MMP2_CLK_SDH1, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
{MMP2_CLK_SDH2, "sdh2_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH2, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
{MMP2_CLK_SDH3, "sdh3_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH3, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
{MMP2_CLK_DISP0, "disp0_clk", "disp0_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1b, 0x1b, 0x0, 0, &disp0_lock},
{MMP2_CLK_DISP0_SPHY, "disp0_sphy_clk", "disp0_sphy_div", CLK_SET_RATE_PARENT, APMU_DISP0, 0x1024, 0x1024, 0x0, 0, &disp0_lock},
{MMP2_CLK_DISP1, "disp1_clk", "disp1_div", CLK_SET_RATE_PARENT, APMU_DISP1, 0x1b, 0x1b, 0x0, 0, &disp1_lock},
......
......@@ -9,6 +9,20 @@
#ifndef _DT_BINDINGS_CLK_AT91_H
#define _DT_BINDINGS_CLK_AT91_H
#define PMC_TYPE_CORE 0
#define PMC_TYPE_SYSTEM 1
#define PMC_TYPE_PERIPHERAL 2
#define PMC_TYPE_GCK 3
#define PMC_SLOW 0
#define PMC_MCK 1
#define PMC_UTMI 2
#define PMC_MAIN 3
#define PMC_MCK2 4
#define PMC_I2S0_MUX 5
#define PMC_I2S1_MUX 6
#ifndef AT91_PMC_MOSCS
#define AT91_PMC_MOSCS 0 /* MOSCS Flag */
#define AT91_PMC_LOCKA 1 /* PLLA Lock */
#define AT91_PMC_LOCKB 2 /* PLLB Lock */
......@@ -19,5 +33,6 @@
#define AT91_PMC_MOSCRCS 17 /* Main On-Chip RC */
#define AT91_PMC_CFDEV 18 /* Clock Failure Detector Event */
#define AT91_PMC_GCKRDY 24 /* Generated Clocks */
#endif
#endif
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment