Skip to content

Commit dfb8a71

Browse files
Zhihuan-Herkhuangtao
authored andcommitted
PM / devfreq: rockchip-dfi: add dfi pclk management
In the most of the time, the pclk of dfi is turned off. The pclk is only enabled when the result is retrieved for power saving. Change-Id: I040a87e0b146694874b15dce3b23e4ddc5e86c1e Signed-off-by: Zhihuan He <[email protected]>
1 parent 12c5f9d commit dfb8a71

File tree

1 file changed

+70
-20
lines changed

1 file changed

+70
-20
lines changed

drivers/devfreq/event/rockchip-dfi.c

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ struct rockchip_dfi {
121121
struct regmap *regmap_pmu;
122122
struct regmap *regmap_grf;
123123
struct regmap *regmap_pmugrf;
124-
struct clk *clk;
124+
struct clk *clk[MAX_DMC_NUM_CH];
125125
u32 dram_type;
126126
u32 mon_version;
127127
u32 mon_idx;
@@ -506,34 +506,69 @@ static int rockchip_dfi_get_busier_ch(struct devfreq_event_dev *edev)
506506
return busier_ch;
507507
}
508508

509+
static int rockchip_dfi_clk_enable(struct rockchip_dfi *info)
510+
{
511+
u32 i;
512+
int ret;
513+
514+
for (i = 0; i < MAX_DMC_NUM_CH; i++) {
515+
if (!(info->ch_msk & BIT(i)))
516+
continue;
517+
if (info->clk[i]) {
518+
ret = clk_prepare_enable(info->clk[i]);
519+
if (ret) {
520+
dev_err(info->dev, "failed to enable ch%d dfi clk: %d\n",
521+
i, ret);
522+
return ret;
523+
}
524+
}
525+
}
526+
527+
return 0;
528+
}
529+
530+
static int rockchip_dfi_clk_disable(struct rockchip_dfi *info)
531+
{
532+
u32 i;
533+
534+
for (i = 0; i < MAX_DMC_NUM_CH; i++) {
535+
if (!(info->ch_msk & BIT(i)))
536+
continue;
537+
if (info->clk[i])
538+
clk_disable_unprepare(info->clk[i]);
539+
}
540+
541+
return 0;
542+
}
509543
static int rockchip_dfi_disable(struct devfreq_event_dev *edev)
510544
{
545+
int ret;
511546
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
512547

548+
ret = rockchip_dfi_clk_enable(info);
549+
if (ret)
550+
return ret;
551+
513552
rockchip_dfi_stop_hardware_counter(edev);
514-
if (info->clk)
515-
clk_disable_unprepare(info->clk);
553+
rockchip_dfi_clk_disable(info);
516554

517555
return 0;
518556
}
519557

520558
static int rockchip_dfi_enable(struct devfreq_event_dev *edev)
521559
{
522-
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
523560
int ret;
561+
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
524562

525-
if (info->clk) {
526-
ret = clk_prepare_enable(info->clk);
527-
if (ret) {
528-
dev_err(&edev->dev, "failed to enable dfi clk: %d\n",
529-
ret);
530-
return ret;
531-
}
532-
}
563+
ret = rockchip_dfi_clk_enable(info);
564+
if (ret)
565+
return ret;
533566

534567
rockchip_dfi_get_mon_version(edev);
535568

536569
rockchip_dfi_start_hardware_counter(edev);
570+
rockchip_dfi_clk_disable(info);
571+
537572
return 0;
538573
}
539574

@@ -548,11 +583,18 @@ static int rockchip_dfi_get_event(struct devfreq_event_dev *edev,
548583
struct rockchip_dfi *info = devfreq_event_get_drvdata(edev);
549584
int busier_ch;
550585
unsigned long flags;
586+
int ret;
587+
588+
ret = rockchip_dfi_clk_enable(info);
589+
if (ret)
590+
return ret;
551591

552592
local_irq_save(flags);
553593
busier_ch = rockchip_dfi_get_busier_ch(edev);
554594
local_irq_restore(flags);
555595

596+
rockchip_dfi_clk_disable(info);
597+
556598
edata->load_count = info->ch_usage[busier_ch].access;
557599
edata->total_count = info->ch_usage[busier_ch].total;
558600

@@ -572,7 +614,8 @@ static __maybe_unused __init int rk3588_dfi_init(struct platform_device *pdev,
572614
{
573615
struct device_node *np = pdev->dev.of_node;
574616
struct resource *res;
575-
u32 val_2, val_3, val_4;
617+
u32 val_2, val_3, val_4, i;
618+
char clk_name[20];
576619

577620
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
578621
data->regs = devm_ioremap_resource(&pdev->dev, res);
@@ -598,7 +641,17 @@ static __maybe_unused __init int rk3588_dfi_init(struct platform_device *pdev,
598641
data->count_rate = 2;
599642
data->dram_dynamic_info_reg = RK3588_PMUGRF_OS_REG(6);
600643
data->ch_msk = READ_CH_INFO(val_2) | READ_CH_INFO(val_4) << 2;
601-
data->clk = NULL;
644+
645+
for (i = 0; i < MAX_DMC_NUM_CH; i++) {
646+
if (data->ch_msk & BIT(i)) {
647+
snprintf(clk_name, sizeof(clk_name), "pclk_ddr_mon_ch%d", i);
648+
data->clk[i] = devm_clk_get(&pdev->dev, clk_name);
649+
if (IS_ERR(data->clk[i])) {
650+
dev_err(&pdev->dev, "Failed to get %s\n", clk_name);
651+
return PTR_ERR(data->clk[i]);
652+
}
653+
}
654+
}
602655

603656
desc->ops = &rockchip_dfi_ops;
604657

@@ -647,7 +700,6 @@ static __maybe_unused __init int px30_dfi_init(struct platform_device *pdev,
647700
else
648701
data->dram_type = READ_DRAMTYPE_INFO(val_2);
649702
data->ch_msk = 1;
650-
data->clk = NULL;
651703

652704
desc->ops = &rockchip_dfi_ops;
653705

@@ -739,9 +791,9 @@ static __maybe_unused __init int rockchip_dfi_init(struct platform_device *pdev,
739791
if (IS_ERR(data->regs))
740792
return PTR_ERR(data->regs);
741793

742-
data->clk = devm_clk_get(dev, "pclk_ddr_mon");
743-
if (IS_ERR(data->clk))
744-
return dev_err_probe(dev, PTR_ERR(data->clk),
794+
data->clk[0] = devm_clk_get(dev, "pclk_ddr_mon");
795+
if (IS_ERR(data->clk[0]))
796+
return dev_err_probe(dev, PTR_ERR(data->clk[0]),
745797
"Cannot get the clk pclk_ddr_mon\n");
746798

747799
node = of_parse_phandle(np, "rockchip,pmu", 0);
@@ -785,7 +837,6 @@ static __maybe_unused __init int rk3328_dfi_init(struct platform_device *pdev,
785837
regmap_read(data->regmap_grf, RK3328_GRF_OS_REG2, &val);
786838
data->dram_type = READ_DRAMTYPE_INFO(val);
787839
data->ch_msk = 1;
788-
data->clk = NULL;
789840

790841
desc->ops = &rockchip_dfi_ops;
791842

@@ -820,7 +871,6 @@ static __maybe_unused __init int rk3528_dfi_init(struct platform_device *pdev,
820871
data->dram_type = READ_DRAMTYPE_INFO(val_18);
821872
data->count_rate = 2;
822873
data->ch_msk = 1;
823-
data->clk = NULL;
824874

825875
desc->ops = &rockchip_dfi_ops;
826876

0 commit comments

Comments
 (0)