Commit 7a110b91 authored by Claudiu Beznea's avatar Claudiu Beznea Committed by Stephen Boyd
Browse files

clk: at91: clk-master: re-factor master clock



Re-factor master clock driver by splitting it into 2 clocks: prescaller
and divider clocks. Based on registered clock flags the prescaler's rate
could be changed at runtime. This is necessary for platforms supporting
DVFS (e.g. SAMA7G5) where master clock could be changed at run-time.

Signed-off-by: default avatarClaudiu Beznea <claudiu.beznea@microchip.com>
Link: https://lore.kernel.org/r/1605800597-16720-11-git-send-email-claudiu.beznea@microchip.com


Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 120d5d8b
Loading
Loading
Loading
Loading
+17 −4
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@

#include "pmc.h"

static DEFINE_SPINLOCK(rm9200_mck_lock);

struct sck {
	char *n;
	char *p;
@@ -137,9 +139,20 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
	parent_names[1] = "mainck";
	parent_names[2] = "pllack";
	parent_names[3] = "pllbck";
	hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
	hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,
					   parent_names,
					   &at91rm9200_master_layout,
					   &rm9200_mck_characteristics,
					   &rm9200_mck_lock, CLK_SET_RATE_GATE,
					   INT_MIN);
	if (IS_ERR(hw))
		goto err_free;

	hw = at91_clk_register_master_div(regmap, "masterck_div",
					  "masterck_pres",
					  &at91rm9200_master_layout,
				      &rm9200_mck_characteristics);
					  &rm9200_mck_characteristics,
					  &rm9200_mck_lock, CLK_SET_RATE_GATE);
	if (IS_ERR(hw))
		goto err_free;

@@ -181,7 +194,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
	for (i = 0; i < ARRAY_SIZE(at91rm9200_periphck); i++) {
		hw = at91_clk_register_peripheral(regmap,
						  at91rm9200_periphck[i].n,
						  "masterck",
						  "masterck_div",
						  at91rm9200_periphck[i].id);
		if (IS_ERR(hw))
			goto err_free;
+20 −6
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@ struct at91sam926x_data {
	bool has_slck;
};

static DEFINE_SPINLOCK(at91sam9260_mck_lock);

static const struct clk_master_characteristics sam9260_mck_characteristics = {
	.output = { .min = 0, .max = 105000000 },
	.divisors = { 1, 2, 4, 0 },
@@ -218,8 +220,8 @@ static const struct sck at91sam9261_systemck[] = {
	{ .n = "pck1",  .p = "prog1",    .id = 9 },
	{ .n = "pck2",  .p = "prog2",    .id = 10 },
	{ .n = "pck3",  .p = "prog3",    .id = 11 },
	{ .n = "hclk0", .p = "masterck", .id = 16 },
	{ .n = "hclk1", .p = "masterck", .id = 17 },
	{ .n = "hclk0", .p = "masterck_div", .id = 16 },
	{ .n = "hclk1", .p = "masterck_div", .id = 17 },
};

static const struct pck at91sam9261_periphck[] = {
@@ -413,9 +415,21 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
	parent_names[1] = "mainck";
	parent_names[2] = "pllack";
	parent_names[3] = "pllbck";
	hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
	hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,
					   parent_names,
					   &at91rm9200_master_layout,
					   data->mck_characteristics,
					   &at91sam9260_mck_lock,
					   CLK_SET_RATE_GATE, INT_MIN);
	if (IS_ERR(hw))
		goto err_free;

	hw = at91_clk_register_master_div(regmap, "masterck_div",
					  "masterck_pres",
					  &at91rm9200_master_layout,
				      data->mck_characteristics);
					  data->mck_characteristics,
					  &at91sam9260_mck_lock,
					  CLK_SET_RATE_GATE);
	if (IS_ERR(hw))
		goto err_free;

@@ -457,7 +471,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
	for (i = 0; i < data->num_pck; i++) {
		hw = at91_clk_register_peripheral(regmap,
						  data->pck[i].n,
						  "masterck",
						  "masterck_div",
						  data->pck[i].id);
		if (IS_ERR(hw))
			goto err_free;
+23 −9
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@

#include "pmc.h"

static DEFINE_SPINLOCK(at91sam9g45_mck_lock);

static const struct clk_master_characteristics mck_characteristics = {
	.output = { .min = 0, .max = 133333333 },
	.divisors = { 1, 2, 4, 3 },
@@ -40,7 +42,7 @@ static const struct {
	char *p;
	u8 id;
} at91sam9g45_systemck[] = {
	{ .n = "ddrck", .p = "masterck", .id = 2 },
	{ .n = "ddrck", .p = "masterck_div", .id = 2 },
	{ .n = "uhpck", .p = "usbck",        .id = 6 },
	{ .n = "pck0",  .p = "prog0",        .id = 8 },
	{ .n = "pck1",  .p = "prog1",        .id = 9 },
@@ -148,9 +150,21 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
	parent_names[1] = "mainck";
	parent_names[2] = "plladivck";
	parent_names[3] = "utmick";
	hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
	hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,
					   parent_names,
					   &at91rm9200_master_layout,
					   &mck_characteristics,
					   &at91sam9g45_mck_lock,
					   CLK_SET_RATE_GATE, INT_MIN);
	if (IS_ERR(hw))
		goto err_free;

	hw = at91_clk_register_master_div(regmap, "masterck_div",
					  "masterck_pres",
					  &at91rm9200_master_layout,
				      &mck_characteristics);
					  &mck_characteristics,
					  &at91sam9g45_mck_lock,
					  CLK_SET_RATE_GATE);
	if (IS_ERR(hw))
		goto err_free;

@@ -166,7 +180,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
	parent_names[1] = "mainck";
	parent_names[2] = "plladivck";
	parent_names[3] = "utmick";
	parent_names[4] = "masterck";
	parent_names[4] = "masterck_div";
	for (i = 0; i < 2; i++) {
		char name[6];

@@ -195,7 +209,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
	for (i = 0; i < ARRAY_SIZE(at91sam9g45_periphck); i++) {
		hw = at91_clk_register_peripheral(regmap,
						  at91sam9g45_periphck[i].n,
						  "masterck",
						  "masterck_div",
						  at91sam9g45_periphck[i].id);
		if (IS_ERR(hw))
			goto err_free;
+25 −11
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@

#include "pmc.h"

static DEFINE_SPINLOCK(at91sam9n12_mck_lock);

static const struct clk_master_characteristics mck_characteristics = {
	.output = { .min = 0, .max = 133333333 },
	.divisors = { 1, 2, 4, 3 },
@@ -54,8 +56,8 @@ static const struct {
	char *p;
	u8 id;
} at91sam9n12_systemck[] = {
	{ .n = "ddrck", .p = "masterck", .id = 2 },
	{ .n = "lcdck", .p = "masterck", .id = 3 },
	{ .n = "ddrck", .p = "masterck_div", .id = 2 },
	{ .n = "lcdck", .p = "masterck_div", .id = 3 },
	{ .n = "uhpck", .p = "usbck",        .id = 6 },
	{ .n = "udpck", .p = "usbck",        .id = 7 },
	{ .n = "pck0",  .p = "prog0",        .id = 8 },
@@ -175,9 +177,21 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
	parent_names[1] = "mainck";
	parent_names[2] = "plladivck";
	parent_names[3] = "pllbck";
	hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
	hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,
					   parent_names,
					   &at91sam9x5_master_layout,
					   &mck_characteristics,
					   &at91sam9n12_mck_lock,
					   CLK_SET_RATE_GATE, INT_MIN);
	if (IS_ERR(hw))
		goto err_free;

	hw = at91_clk_register_master_div(regmap, "masterck_div",
					  "masterck_pres",
					  &at91sam9x5_master_layout,
				      &mck_characteristics);
					  &mck_characteristics,
					  &at91sam9n12_mck_lock,
					  CLK_SET_RATE_GATE);
	if (IS_ERR(hw))
		goto err_free;

@@ -191,7 +205,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
	parent_names[1] = "mainck";
	parent_names[2] = "plladivck";
	parent_names[3] = "pllbck";
	parent_names[4] = "masterck";
	parent_names[4] = "masterck_div";
	for (i = 0; i < 2; i++) {
		char name[6];

@@ -221,7 +235,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
		hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock,
							 &at91sam9n12_pcr_layout,
							 at91sam9n12_periphck[i].n,
							 "masterck",
							 "masterck_div",
							 at91sam9n12_periphck[i].id,
							 &range, INT_MIN);
		if (IS_ERR(hw))
+18 −5
Original line number Diff line number Diff line
@@ -7,6 +7,8 @@

#include "pmc.h"

static DEFINE_SPINLOCK(sam9rl_mck_lock);

static const struct clk_master_characteristics sam9rl_mck_characteristics = {
	.output = { .min = 0, .max = 94000000 },
	.divisors = { 1, 2, 4, 0 },
@@ -117,9 +119,20 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
	parent_names[1] = "mainck";
	parent_names[2] = "pllack";
	parent_names[3] = "utmick";
	hw = at91_clk_register_master(regmap, "masterck", 4, parent_names,
	hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4,
					   parent_names,
					   &at91rm9200_master_layout,
					   &sam9rl_mck_characteristics,
					   &sam9rl_mck_lock, CLK_SET_RATE_GATE,
					   INT_MIN);
	if (IS_ERR(hw))
		goto err_free;

	hw = at91_clk_register_master_div(regmap, "masterck_div",
					  "masterck_pres",
					  &at91rm9200_master_layout,
				      &sam9rl_mck_characteristics);
					  &sam9rl_mck_characteristics,
					  &sam9rl_mck_lock, CLK_SET_RATE_GATE);
	if (IS_ERR(hw))
		goto err_free;

@@ -129,7 +142,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
	parent_names[1] = "mainck";
	parent_names[2] = "pllack";
	parent_names[3] = "utmick";
	parent_names[4] = "masterck";
	parent_names[4] = "masterck_div";
	for (i = 0; i < 2; i++) {
		char name[6];

@@ -158,7 +171,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
	for (i = 0; i < ARRAY_SIZE(at91sam9rl_periphck); i++) {
		hw = at91_clk_register_peripheral(regmap,
						  at91sam9rl_periphck[i].n,
						  "masterck",
						  "masterck_div",
						  at91sam9rl_periphck[i].id);
		if (IS_ERR(hw))
			goto err_free;
Loading