Skip to content

Commit 8b9d9e9

Browse files
committed
Merge tag 'for-5.19-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into clk-tegra
Pull Tegra clk driver updates from Thierry Reding: This contains a boot time optimization for Tegra chips with BPMP and a switch from .round_rate() to .determine_rate() to take into account any maximum rate that might have been set. Other than that this contains a fix for a DFLL regression on Tegra210 and kerneldoc fixups to avoid build warnings. * tag 'for-5.19-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: clk: tegra: Update kerneldoc to match prototypes clk: tegra: Replace .round_rate() with .determine_rate() clk: tegra: Register clocks from root to leaf clk: tegra: Add missing reset deassertion
2 parents 3123109 + 6f6baf6 commit 8b9d9e9

2 files changed

Lines changed: 82 additions & 25 deletions

File tree

drivers/clk/tegra/clk-bpmp.c

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -164,15 +164,18 @@ static unsigned long tegra_bpmp_clk_recalc_rate(struct clk_hw *hw,
164164
return response.rate;
165165
}
166166

167-
static long tegra_bpmp_clk_round_rate(struct clk_hw *hw, unsigned long rate,
168-
unsigned long *parent_rate)
167+
static int tegra_bpmp_clk_determine_rate(struct clk_hw *hw,
168+
struct clk_rate_request *rate_req)
169169
{
170170
struct tegra_bpmp_clk *clk = to_tegra_bpmp_clk(hw);
171171
struct cmd_clk_round_rate_response response;
172172
struct cmd_clk_round_rate_request request;
173173
struct tegra_bpmp_clk_message msg;
174+
unsigned long rate;
174175
int err;
175176

177+
rate = min(max(rate_req->rate, rate_req->min_rate), rate_req->max_rate);
178+
176179
memset(&request, 0, sizeof(request));
177180
request.rate = min_t(u64, rate, S64_MAX);
178181

@@ -188,7 +191,9 @@ static long tegra_bpmp_clk_round_rate(struct clk_hw *hw, unsigned long rate,
188191
if (err < 0)
189192
return err;
190193

191-
return response.rate;
194+
rate_req->rate = (unsigned long)response.rate;
195+
196+
return 0;
192197
}
193198

194199
static int tegra_bpmp_clk_set_parent(struct clk_hw *hw, u8 index)
@@ -290,7 +295,7 @@ static const struct clk_ops tegra_bpmp_clk_rate_ops = {
290295
.unprepare = tegra_bpmp_clk_unprepare,
291296
.is_prepared = tegra_bpmp_clk_is_prepared,
292297
.recalc_rate = tegra_bpmp_clk_recalc_rate,
293-
.round_rate = tegra_bpmp_clk_round_rate,
298+
.determine_rate = tegra_bpmp_clk_determine_rate,
294299
.set_rate = tegra_bpmp_clk_set_rate,
295300
};
296301

@@ -299,7 +304,7 @@ static const struct clk_ops tegra_bpmp_clk_mux_rate_ops = {
299304
.unprepare = tegra_bpmp_clk_unprepare,
300305
.is_prepared = tegra_bpmp_clk_is_prepared,
301306
.recalc_rate = tegra_bpmp_clk_recalc_rate,
302-
.round_rate = tegra_bpmp_clk_round_rate,
307+
.determine_rate = tegra_bpmp_clk_determine_rate,
303308
.set_parent = tegra_bpmp_clk_set_parent,
304309
.get_parent = tegra_bpmp_clk_get_parent,
305310
.set_rate = tegra_bpmp_clk_set_rate,
@@ -448,15 +453,29 @@ static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp,
448453
return count;
449454
}
450455

456+
static unsigned int
457+
tegra_bpmp_clk_id_to_index(const struct tegra_bpmp_clk_info *clocks,
458+
unsigned int num_clocks, unsigned int id)
459+
{
460+
unsigned int i;
461+
462+
for (i = 0; i < num_clocks; i++)
463+
if (clocks[i].id == id)
464+
return i;
465+
466+
return UINT_MAX;
467+
}
468+
451469
static const struct tegra_bpmp_clk_info *
452470
tegra_bpmp_clk_find(const struct tegra_bpmp_clk_info *clocks,
453471
unsigned int num_clocks, unsigned int id)
454472
{
455473
unsigned int i;
456474

457-
for (i = 0; i < num_clocks; i++)
458-
if (clocks[i].id == id)
459-
return &clocks[i];
475+
i = tegra_bpmp_clk_id_to_index(clocks, num_clocks, id);
476+
477+
if (i < num_clocks)
478+
return &clocks[i];
460479

461480
return NULL;
462481
}
@@ -539,31 +558,57 @@ tegra_bpmp_clk_register(struct tegra_bpmp *bpmp,
539558
return clk;
540559
}
541560

561+
static void tegra_bpmp_register_clocks_one(struct tegra_bpmp *bpmp,
562+
struct tegra_bpmp_clk_info *infos,
563+
unsigned int i,
564+
unsigned int count)
565+
{
566+
unsigned int j;
567+
struct tegra_bpmp_clk_info *info;
568+
struct tegra_bpmp_clk *clk;
569+
570+
if (bpmp->clocks[i]) {
571+
/* already registered */
572+
return;
573+
}
574+
575+
info = &infos[i];
576+
for (j = 0; j < info->num_parents; ++j) {
577+
unsigned int p_id = info->parents[j];
578+
unsigned int p_i = tegra_bpmp_clk_id_to_index(infos, count,
579+
p_id);
580+
if (p_i < count)
581+
tegra_bpmp_register_clocks_one(bpmp, infos, p_i, count);
582+
}
583+
584+
clk = tegra_bpmp_clk_register(bpmp, info, infos, count);
585+
if (IS_ERR(clk)) {
586+
dev_err(bpmp->dev,
587+
"failed to register clock %u (%s): %ld\n",
588+
info->id, info->name, PTR_ERR(clk));
589+
/* intentionally store the error pointer to
590+
* bpmp->clocks[i] to avoid re-attempting the
591+
* registration later
592+
*/
593+
}
594+
595+
bpmp->clocks[i] = clk;
596+
}
597+
542598
static int tegra_bpmp_register_clocks(struct tegra_bpmp *bpmp,
543599
struct tegra_bpmp_clk_info *infos,
544600
unsigned int count)
545601
{
546-
struct tegra_bpmp_clk *clk;
547602
unsigned int i;
548603

549604
bpmp->num_clocks = count;
550605

551-
bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(clk), GFP_KERNEL);
606+
bpmp->clocks = devm_kcalloc(bpmp->dev, count, sizeof(struct tegra_bpmp_clk), GFP_KERNEL);
552607
if (!bpmp->clocks)
553608
return -ENOMEM;
554609

555610
for (i = 0; i < count; i++) {
556-
struct tegra_bpmp_clk_info *info = &infos[i];
557-
558-
clk = tegra_bpmp_clk_register(bpmp, info, infos, count);
559-
if (IS_ERR(clk)) {
560-
dev_err(bpmp->dev,
561-
"failed to register clock %u (%s): %ld\n",
562-
info->id, info->name, PTR_ERR(clk));
563-
continue;
564-
}
565-
566-
bpmp->clocks[i] = clk;
611+
tegra_bpmp_register_clocks_one(bpmp, infos, i, count);
567612
}
568613

569614
return 0;

drivers/clk/tegra/clk-dfll.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ struct tegra_dfll {
271271
struct clk *ref_clk;
272272
struct clk *i2c_clk;
273273
struct clk *dfll_clk;
274+
struct reset_control *dfll_rst;
274275
struct reset_control *dvco_rst;
275276
unsigned long ref_rate;
276277
unsigned long i2c_clk_rate;
@@ -666,7 +667,7 @@ static int dfll_force_output(struct tegra_dfll *td, unsigned int out_sel)
666667
}
667668

668669
/**
669-
* dfll_load_lut - load the voltage lookup table
670+
* dfll_load_i2c_lut - load the voltage lookup table
670671
* @td: struct tegra_dfll *
671672
*
672673
* Load the voltage-to-PMIC register value lookup table into the DFLL
@@ -897,7 +898,7 @@ static void dfll_set_frequency_request(struct tegra_dfll *td,
897898
}
898899

899900
/**
900-
* tegra_dfll_request_rate - set the next rate for the DFLL to tune to
901+
* dfll_request_rate - set the next rate for the DFLL to tune to
901902
* @td: DFLL instance
902903
* @rate: clock rate to target
903904
*
@@ -1005,7 +1006,7 @@ static void dfll_set_open_loop_config(struct tegra_dfll *td)
10051006
}
10061007

10071008
/**
1008-
* tegra_dfll_lock - switch from open-loop to closed-loop mode
1009+
* dfll_lock - switch from open-loop to closed-loop mode
10091010
* @td: DFLL instance
10101011
*
10111012
* Switch from OPEN_LOOP state to CLOSED_LOOP state. Returns 0 upon success,
@@ -1046,7 +1047,7 @@ static int dfll_lock(struct tegra_dfll *td)
10461047
}
10471048

10481049
/**
1049-
* tegra_dfll_unlock - switch from closed-loop to open-loop mode
1050+
* dfll_unlock - switch from closed-loop to open-loop mode
10501051
* @td: DFLL instance
10511052
*
10521053
* Switch from CLOSED_LOOP state to OPEN_LOOP state. Returns 0 upon success,
@@ -1464,6 +1465,7 @@ static int dfll_init(struct tegra_dfll *td)
14641465
return -EINVAL;
14651466
}
14661467

1468+
reset_control_deassert(td->dfll_rst);
14671469
reset_control_deassert(td->dvco_rst);
14681470

14691471
ret = clk_prepare(td->ref_clk);
@@ -1509,6 +1511,7 @@ static int dfll_init(struct tegra_dfll *td)
15091511
clk_unprepare(td->ref_clk);
15101512

15111513
reset_control_assert(td->dvco_rst);
1514+
reset_control_assert(td->dfll_rst);
15121515

15131516
return ret;
15141517
}
@@ -1530,6 +1533,7 @@ int tegra_dfll_suspend(struct device *dev)
15301533
}
15311534

15321535
reset_control_assert(td->dvco_rst);
1536+
reset_control_assert(td->dfll_rst);
15331537

15341538
return 0;
15351539
}
@@ -1548,6 +1552,7 @@ int tegra_dfll_resume(struct device *dev)
15481552
{
15491553
struct tegra_dfll *td = dev_get_drvdata(dev);
15501554

1555+
reset_control_deassert(td->dfll_rst);
15511556
reset_control_deassert(td->dvco_rst);
15521557

15531558
pm_runtime_get_sync(td->dev);
@@ -1951,6 +1956,12 @@ int tegra_dfll_register(struct platform_device *pdev,
19511956

19521957
td->soc = soc;
19531958

1959+
td->dfll_rst = devm_reset_control_get_optional(td->dev, "dfll");
1960+
if (IS_ERR(td->dfll_rst)) {
1961+
dev_err(td->dev, "couldn't get dfll reset\n");
1962+
return PTR_ERR(td->dfll_rst);
1963+
}
1964+
19541965
td->dvco_rst = devm_reset_control_get(td->dev, "dvco");
19551966
if (IS_ERR(td->dvco_rst)) {
19561967
dev_err(td->dev, "couldn't get dvco reset\n");
@@ -2087,6 +2098,7 @@ struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev)
20872098
clk_unprepare(td->i2c_clk);
20882099

20892100
reset_control_assert(td->dvco_rst);
2101+
reset_control_assert(td->dfll_rst);
20902102

20912103
return td->soc;
20922104
}

0 commit comments

Comments
 (0)