Lines Matching +full:ddr +full:- +full:pmu
1 // SPDX-License-Identifier: GPL-2.0-only
4 * Author: Lin Huang <hl@rock-chips.com>
8 #include <linux/devfreq-event.h>
84 /* pmu grf */
105 * The dfi controller can monitor DDR load. It has an upper and lower threshold
107 * generated to indicate the DDR frequency should be changed.
138 regmap_write(info->regmap_grf, in rk3128_dfi_start_hardware_counter()
147 regmap_write(info->regmap_grf, in rk3128_dfi_stop_hardware_counter()
182 regmap_read(info->regmap_grf, RK3128_GRF_DFI_WRNUM, &dfi_wr); in rk3128_dfi_get_event()
183 regmap_read(info->regmap_grf, RK3128_GRF_DFI_RDNUM, &dfi_rd); in rk3128_dfi_get_event()
184 regmap_read(info->regmap_grf, RK3128_GRF_DFI_TIMERVAL, &dfi_timer); in rk3128_dfi_get_event()
186 edata->load_count = (dfi_wr + dfi_rd) * 4; in rk3128_dfi_get_event()
187 edata->total_count = dfi_timer; in rk3128_dfi_get_event()
207 regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_EN); in rk3288_dfi_start_hardware_counter()
214 regmap_write(info->regmap_grf, RK3288_GRF_SOC_CON4, RK3288_DFI_DIS); in rk3288_dfi_stop_hardware_counter()
247 if (!(info->ch_msk & BIT(i))) in rk3288_dfi_get_busier_ch()
249 regmap_read(info->regmap_grf, in rk3288_dfi_get_busier_ch()
251 regmap_read(info->regmap_grf, in rk3288_dfi_get_busier_ch()
253 regmap_read(info->regmap_grf, in rk3288_dfi_get_busier_ch()
255 info->ch_usage[i].access = (wr_count + rd_count) * 4; in rk3288_dfi_get_busier_ch()
256 info->ch_usage[i].total = total_count; in rk3288_dfi_get_busier_ch()
257 tmp = info->ch_usage[i].access; in rk3288_dfi_get_busier_ch()
279 edata->load_count = info->ch_usage[busier_ch].access; in rk3288_dfi_get_event()
280 edata->total_count = info->ch_usage[busier_ch].total; in rk3288_dfi_get_event()
296 regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_EN); in rk3368_dfi_start_hardware_counter()
303 regmap_write(info->regmap_grf, RK3368_GRF_DDRC0_CON0, RK3368_DFI_DIS); in rk3368_dfi_stop_hardware_counter()
336 regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS5, &dfi0_wr); in rk3368_dfi_get_event()
337 regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS6, &dfi0_rd); in rk3368_dfi_get_event()
338 regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS9, &dfi1_wr); in rk3368_dfi_get_event()
339 regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS10, &dfi1_rd); in rk3368_dfi_get_event()
340 regmap_read(info->regmap_grf, RK3368_GRF_SOC_STATUS8, &dfi_timer); in rk3368_dfi_get_event()
342 edata->load_count = (dfi0_wr + dfi0_rd + dfi1_wr + dfi1_rd) * 2; in rk3368_dfi_get_event()
343 edata->total_count = dfi_timer; in rk3368_dfi_get_event()
362 void __iomem *dfi_regs = info->regs; in rockchip_dfi_start_hardware_counter()
366 if (info->mon_idx) in rockchip_dfi_start_hardware_counter()
367 mon_idx = info->mon_idx; in rockchip_dfi_start_hardware_counter()
369 if (info->dram_dynamic_info_reg) in rockchip_dfi_start_hardware_counter()
370 regmap_read(info->regmap_pmugrf, info->dram_dynamic_info_reg, &val_6); in rockchip_dfi_start_hardware_counter()
372 if (info->dram_type == LPDDR5) { in rockchip_dfi_start_hardware_counter()
373 info->lp5_bank_mode = READ_LP5_BANK_MODE(val_6); in rockchip_dfi_start_hardware_counter()
374 info->lp5_ckr = READ_LP5_CKR(val_6); in rockchip_dfi_start_hardware_counter()
378 if (!(info->ch_msk & BIT(i))) in rockchip_dfi_start_hardware_counter()
383 /* set ddr type to dfi */ in rockchip_dfi_start_hardware_counter()
384 if (info->dram_type == LPDDR3 || info->dram_type == LPDDR2) in rockchip_dfi_start_hardware_counter()
386 else if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X) in rockchip_dfi_start_hardware_counter()
388 else if (info->dram_type == DDR4) in rockchip_dfi_start_hardware_counter()
390 else if (info->dram_type == LPDDR5) in rockchip_dfi_start_hardware_counter()
391 writel_relaxed(LPDDR5_EN | LPDDR5_BANK_MODE(info->lp5_bank_mode), in rockchip_dfi_start_hardware_counter()
402 void __iomem *dfi_regs = info->regs; in rockchip_dfi_stop_hardware_counter()
405 if (info->mon_idx) in rockchip_dfi_stop_hardware_counter()
406 mon_idx = info->mon_idx; in rockchip_dfi_stop_hardware_counter()
409 if (!(info->ch_msk & BIT(i))) in rockchip_dfi_stop_hardware_counter()
420 void __iomem *dfi_regs = info->regs; in rockchip_dfi_get_busier_ch()
425 if (info->mon_idx) in rockchip_dfi_get_busier_ch()
426 mon_idx = info->mon_idx; in rockchip_dfi_get_busier_ch()
427 if (info->count_rate) in rockchip_dfi_get_busier_ch()
428 count_rate = info->count_rate; in rockchip_dfi_get_busier_ch()
432 if (!(info->ch_msk & BIT(i))) in rockchip_dfi_get_busier_ch()
436 info->ch_usage[i].total = readl_relaxed(dfi_regs + in rockchip_dfi_get_busier_ch()
439 /* LPDDR5 LPDDR4 and LPDDR4X BL = 16,other DDR type BL = 8 */ in rockchip_dfi_get_busier_ch()
442 if (info->dram_type == LPDDR4 || info->dram_type == LPDDR4X) in rockchip_dfi_get_busier_ch()
444 else if (info->dram_type == LPDDR5) in rockchip_dfi_get_busier_ch()
445 tmp *= 16 / (4 << info->lp5_ckr); in rockchip_dfi_get_busier_ch()
448 info->ch_usage[i].access = tmp; in rockchip_dfi_get_busier_ch()
465 if (info->clk) in rockchip_dfi_disable()
466 clk_disable_unprepare(info->clk); in rockchip_dfi_disable()
476 if (info->clk) { in rockchip_dfi_enable()
477 ret = clk_prepare_enable(info->clk); in rockchip_dfi_enable()
479 dev_err(&edev->dev, "failed to enable dfi clk: %d\n", in rockchip_dfi_enable()
505 edata->load_count = info->ch_usage[busier_ch].access; in rockchip_dfi_get_event()
506 edata->total_count = info->ch_usage[busier_ch].total; in rockchip_dfi_get_event()
522 struct device_node *np = pdev->dev.of_node; in rk3588_dfi_init()
527 data->regs = devm_ioremap_resource(&pdev->dev, res); in rk3588_dfi_init()
528 if (IS_ERR(data->regs)) in rk3588_dfi_init()
529 return PTR_ERR(data->regs); in rk3588_dfi_init()
531 data->regmap_pmugrf = syscon_regmap_lookup_by_phandle(np, "rockchip,pmu_grf"); in rk3588_dfi_init()
532 if (IS_ERR(data->regmap_pmugrf)) in rk3588_dfi_init()
533 return PTR_ERR(data->regmap_pmugrf); in rk3588_dfi_init()
535 regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(2), &val_2); in rk3588_dfi_init()
536 regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(3), &val_3); in rk3588_dfi_init()
537 regmap_read(data->regmap_pmugrf, RK3588_PMUGRF_OS_REG(4), &val_4); in rk3588_dfi_init()
539 data->dram_type = READ_DRAMTYPE_INFO_V3(val_2, val_3); in rk3588_dfi_init()
541 data->dram_type = READ_DRAMTYPE_INFO(val_2); in rk3588_dfi_init()
543 data->mon_idx = 0x4000; in rk3588_dfi_init()
544 if (data->dram_type == LPDDR5) in rk3588_dfi_init()
545 data->count_rate = 1; in rk3588_dfi_init()
547 data->count_rate = 2; in rk3588_dfi_init()
548 data->dram_dynamic_info_reg = RK3588_PMUGRF_OS_REG(6); in rk3588_dfi_init()
549 data->ch_msk = READ_CH_INFO(val_2) | READ_CH_INFO(val_4) << 2; in rk3588_dfi_init()
550 data->clk = NULL; in rk3588_dfi_init()
552 desc->ops = &rockchip_dfi_ops; in rk3588_dfi_init()
561 struct device_node *np = pdev->dev.of_node, *node; in px30_dfi_init()
566 data->regs = devm_ioremap_resource(&pdev->dev, res); in px30_dfi_init()
567 if (IS_ERR(data->regs)) in px30_dfi_init()
568 return PTR_ERR(data->regs); in px30_dfi_init()
572 data->regmap_pmugrf = syscon_node_to_regmap(node); in px30_dfi_init()
573 if (IS_ERR(data->regmap_pmugrf)) in px30_dfi_init()
574 return PTR_ERR(data->regmap_pmugrf); in px30_dfi_init()
577 regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG2, &val_2); in px30_dfi_init()
578 regmap_read(data->regmap_pmugrf, PX30_PMUGRF_OS_REG3, &val_3); in px30_dfi_init()
580 data->dram_type = READ_DRAMTYPE_INFO_V3(val_2, val_3); in px30_dfi_init()
582 data->dram_type = READ_DRAMTYPE_INFO(val_2); in px30_dfi_init()
583 data->ch_msk = 1; in px30_dfi_init()
584 data->clk = NULL; in px30_dfi_init()
586 desc->ops = &rockchip_dfi_ops; in px30_dfi_init()
595 struct device_node *np = pdev->dev.of_node, *node; in rk3128_dfi_init()
599 data->regmap_grf = syscon_node_to_regmap(node); in rk3128_dfi_init()
600 if (IS_ERR(data->regmap_grf)) in rk3128_dfi_init()
601 return PTR_ERR(data->regmap_grf); in rk3128_dfi_init()
604 desc->ops = &rk3128_dfi_ops; in rk3128_dfi_init()
613 struct device_node *np = pdev->dev.of_node, *node; in rk3288_dfi_init()
616 node = of_parse_phandle(np, "rockchip,pmu", 0); in rk3288_dfi_init()
618 data->regmap_pmu = syscon_node_to_regmap(node); in rk3288_dfi_init()
619 if (IS_ERR(data->regmap_pmu)) in rk3288_dfi_init()
620 return PTR_ERR(data->regmap_pmu); in rk3288_dfi_init()
625 data->regmap_grf = syscon_node_to_regmap(node); in rk3288_dfi_init()
626 if (IS_ERR(data->regmap_grf)) in rk3288_dfi_init()
627 return PTR_ERR(data->regmap_grf); in rk3288_dfi_init()
630 regmap_read(data->regmap_pmu, RK3288_PMU_SYS_REG2, &val); in rk3288_dfi_init()
631 data->dram_type = READ_DRAMTYPE_INFO(val); in rk3288_dfi_init()
632 data->ch_msk = READ_CH_INFO(val); in rk3288_dfi_init()
634 if (data->dram_type == DDR3) in rk3288_dfi_init()
635 regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4, in rk3288_dfi_init()
638 regmap_write(data->regmap_grf, RK3288_GRF_SOC_CON4, in rk3288_dfi_init()
641 desc->ops = &rk3288_dfi_ops; in rk3288_dfi_init()
650 struct device *dev = &pdev->dev; in rk3368_dfi_init()
652 if (!dev->parent || !dev->parent->of_node) in rk3368_dfi_init()
653 return -EINVAL; in rk3368_dfi_init()
655 data->regmap_grf = syscon_node_to_regmap(dev->parent->of_node); in rk3368_dfi_init()
656 if (IS_ERR(data->regmap_grf)) in rk3368_dfi_init()
657 return PTR_ERR(data->regmap_grf); in rk3368_dfi_init()
659 desc->ops = &rk3368_dfi_ops; in rk3368_dfi_init()
668 struct device *dev = &pdev->dev; in rockchip_dfi_init()
669 struct device_node *np = pdev->dev.of_node, *node; in rockchip_dfi_init()
672 data->regs = devm_platform_ioremap_resource(pdev, 0); in rockchip_dfi_init()
673 if (IS_ERR(data->regs)) in rockchip_dfi_init()
674 return PTR_ERR(data->regs); in rockchip_dfi_init()
676 data->clk = devm_clk_get(dev, "pclk_ddr_mon"); in rockchip_dfi_init()
677 if (IS_ERR(data->clk)) { in rockchip_dfi_init()
679 return PTR_ERR(data->clk); in rockchip_dfi_init()
682 /* try to find the optional reference to the pmu syscon */ in rockchip_dfi_init()
683 node = of_parse_phandle(np, "rockchip,pmu", 0); in rockchip_dfi_init()
685 data->regmap_pmu = syscon_node_to_regmap(node); in rockchip_dfi_init()
687 if (IS_ERR(data->regmap_pmu)) in rockchip_dfi_init()
688 return PTR_ERR(data->regmap_pmu); in rockchip_dfi_init()
691 regmap_read(data->regmap_pmu, PMUGRF_OS_REG2, &val); in rockchip_dfi_init()
692 data->dram_type = READ_DRAMTYPE_INFO(val); in rockchip_dfi_init()
693 data->ch_msk = READ_CH_INFO(val); in rockchip_dfi_init()
695 desc->ops = &rockchip_dfi_ops; in rockchip_dfi_init()
704 struct device_node *np = pdev->dev.of_node, *node; in rk3328_dfi_init()
709 data->regs = devm_ioremap_resource(&pdev->dev, res); in rk3328_dfi_init()
710 if (IS_ERR(data->regs)) in rk3328_dfi_init()
711 return PTR_ERR(data->regs); in rk3328_dfi_init()
715 data->regmap_grf = syscon_node_to_regmap(node); in rk3328_dfi_init()
716 if (IS_ERR(data->regmap_grf)) in rk3328_dfi_init()
717 return PTR_ERR(data->regmap_grf); in rk3328_dfi_init()
720 regmap_read(data->regmap_grf, RK3328_GRF_OS_REG2, &val); in rk3328_dfi_init()
721 data->dram_type = READ_DRAMTYPE_INFO(val); in rk3328_dfi_init()
722 data->ch_msk = 1; in rk3328_dfi_init()
723 data->clk = NULL; in rk3328_dfi_init()
725 desc->ops = &rockchip_dfi_ops; in rk3328_dfi_init()
734 struct device_node *np = pdev->dev.of_node, *node; in rk3528_dfi_init()
739 data->regs = devm_ioremap_resource(&pdev->dev, res); in rk3528_dfi_init()
740 if (IS_ERR(data->regs)) in rk3528_dfi_init()
741 return PTR_ERR(data->regs); in rk3528_dfi_init()
745 data->regmap_grf = syscon_node_to_regmap(node); in rk3528_dfi_init()
746 if (IS_ERR(data->regmap_grf)) in rk3528_dfi_init()
747 return PTR_ERR(data->regmap_grf); in rk3528_dfi_init()
750 regmap_read(data->regmap_grf, RK3528_PMUGRF_OFFSET + RK3528_PMUGRF_OS_REG18, &val_18); in rk3528_dfi_init()
751 regmap_read(data->regmap_grf, RK3528_PMUGRF_OFFSET + RK3528_PMUGRF_OS_REG19, &val_19); in rk3528_dfi_init()
753 data->dram_type = READ_DRAMTYPE_INFO_V3(val_18, val_19); in rk3528_dfi_init()
755 data->dram_type = READ_DRAMTYPE_INFO(val_18); in rk3528_dfi_init()
756 data->count_rate = 2; in rk3528_dfi_init()
757 data->ch_msk = 1; in rk3528_dfi_init()
758 data->clk = NULL; in rk3528_dfi_init()
760 desc->ops = &rockchip_dfi_ops; in rk3528_dfi_init()
767 { .compatible = "rockchip,px30-dfi", .data = px30_dfi_init },
770 { .compatible = "rockchip,rk1808-dfi", .data = px30_dfi_init },
773 { .compatible = "rockchip,rk3128-dfi", .data = rk3128_dfi_init },
776 { .compatible = "rockchip,rk3288-dfi", .data = rk3288_dfi_init },
779 { .compatible = "rockchip,rk3328-dfi", .data = rk3328_dfi_init },
782 { .compatible = "rockchip,rk3368-dfi", .data = rk3368_dfi_init },
785 { .compatible = "rockchip,rk3399-dfi", .data = rockchip_dfi_init },
788 { .compatible = "rockchip,rk3528-dfi", .data = rk3528_dfi_init },
791 { .compatible = "rockchip,rk3562-dfi", .data = px30_dfi_init },
794 { .compatible = "rockchip,rk3568-dfi", .data = px30_dfi_init },
797 { .compatible = "rockchip,rk3588-dfi", .data = rk3588_dfi_init },
800 { .compatible = "rockchip,rv1126-dfi", .data = px30_dfi_init },
807 struct device *dev = &pdev->dev; in rockchip_dfi_probe()
810 struct device_node *np = pdev->dev.of_node; in rockchip_dfi_probe()
817 return -ENOMEM; in rockchip_dfi_probe()
821 return -ENOMEM; in rockchip_dfi_probe()
823 match = of_match_node(rockchip_dfi_id_match, pdev->dev.of_node); in rockchip_dfi_probe()
825 init = match->data; in rockchip_dfi_probe()
828 return -EINVAL; in rockchip_dfi_probe()
836 desc->driver_data = data; in rockchip_dfi_probe()
837 desc->name = np->name; in rockchip_dfi_probe()
839 data->edev = devm_devfreq_event_add_edev(dev, desc); in rockchip_dfi_probe()
840 if (IS_ERR(data->edev)) { in rockchip_dfi_probe()
841 dev_err(dev, "failed to add devfreq-event device\n"); in rockchip_dfi_probe()
842 return PTR_ERR(data->edev); in rockchip_dfi_probe()
844 data->desc = desc; in rockchip_dfi_probe()
845 data->dev = &pdev->dev; in rockchip_dfi_probe()
855 .name = "rockchip-dfi",
862 MODULE_AUTHOR("Lin Huang <hl@rock-chips.com>");