Commit c1bdc9aa authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branch 'pm-devfreq'

Merge devfreq updates for 6.7-rc1:

 - Switch to dev_pm_opp_find_freq_(ceil/floor)_indexed() APIs to support
   specific devices like UFS which handle multiple clocks through OPP
   (Operationg Performance Point) framework (Manivannan Sadhasivam).

 - Add perf support to the Rockchip DFI (DDR Monitor Module) devfreq-
   event driver:
   * Generalize rockchip-dfi.c to support new RK3568/RK3588 using
     different DDR type (Sascha Hauer).
   * Convert devicetree bidning document format to yaml (Sascha Hauer).
   * Add perf support for DFI (a unit suitable for measuring DDR
     utilization) to rockchip-dfi.c to extend DFI usage (Sascha Hauer).

 - Add locking to the OPP handling code in the Mediatek CCI devfreq
   driver, because the voltage of shared OPP might be changed by
   multiple drivers (Mark Tseng, Dan Carpenter).

 - Use device_get_match_data() in the Samsung Exynos PPMU devfreq-event
   driver (Rob Herring).

* pm-devfreq: (26 commits)
  dt-bindings: devfreq: event: rockchip,dfi: Add rk3588 support
  dt-bindings: devfreq: event: rockchip,dfi: Add rk3568 support
  dt-bindings: devfreq: event: convert Rockchip DFI binding to yaml
  PM / devfreq: rockchip-dfi: add support for RK3588
  PM / devfreq: rockchip-dfi: account for multiple DDRMON_CTRL registers
  PM / devfreq: rockchip-dfi: make register stride SoC specific
  PM / devfreq: rockchip-dfi: Add perf support
  PM / devfreq: rockchip-dfi: give variable a better name
  PM / devfreq: rockchip-dfi: Prepare for multiple users
  PM / devfreq: rockchip-dfi: Pass private data struct to internal functions
  PM / devfreq: rockchip-dfi: Handle LPDDR4X
  PM / devfreq: rockchip-dfi: Handle LPDDR2 correctly
  PM / devfreq: rockchip-dfi: Add RK3568 support
  PM / devfreq: rockchip-dfi: Clean up DDR type register defines
  PM / devfreq: rk3399_dmc,dfi: generalize DDRTYPE defines
  PM / devfreq: rockchip-dfi: introduce channel mask
  PM / devfreq: rockchip-dfi: Use free running counter
  PM / devfreq: mediatek: unlock on error in mtk_ccifreq_target()
  PM / devfreq: exynos-ppmu: Use device_get_match_data()
  PM / devfreq: rockchip-dfi: dfi store raw values in counter struct
  ...
parents 067e6139 af666466
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/devfreq/event/rockchip,dfi.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Rockchip DFI
maintainers:
- Sascha Hauer <s.hauer@pengutronix.de>
properties:
compatible:
enum:
- rockchip,rk3399-dfi
- rockchip,rk3568-dfi
- rockchip,rk3588-dfi
clocks:
maxItems: 1
clock-names:
items:
- const: pclk_ddr_mon
interrupts:
minItems: 1
maxItems: 4
reg:
maxItems: 1
rockchip,pmu:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to the syscon managing the "PMU general register files".
required:
- compatible
- interrupts
- reg
if:
properties:
compatible:
contains:
enum:
- rockchip,rk3399-dfi
then:
required:
- clocks
- clock-names
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/clock/rk3308-cru.h>
bus {
#address-cells = <2>;
#size-cells = <2>;
dfi: dfi@ff630000 {
compatible = "rockchip,rk3399-dfi";
reg = <0x00 0xff630000 0x00 0x4000>;
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH 0>;
rockchip,pmu = <&pmugrf>;
clocks = <&cru PCLK_DDR_MON>;
clock-names = "pclk_ddr_mon";
};
};
* Rockchip rk3399 DFI device
Required properties:
- compatible: Must be "rockchip,rk3399-dfi".
- reg: physical base address of each DFI and length of memory mapped region
- rockchip,pmu: phandle to the syscon managing the "pmu general register files"
- clocks: phandles for clock specified in "clock-names" property
- clock-names : the name of clock used by the DFI, must be "pclk_ddr_mon";
Example:
dfi: dfi@ff630000 {
compatible = "rockchip,rk3399-dfi";
reg = <0x00 0xff630000 0x00 0x4000>;
rockchip,pmu = <&pmugrf>;
clocks = <&cru PCLK_DDR_MON>;
clock-names = "pclk_ddr_mon";
};
...@@ -18,7 +18,7 @@ properties: ...@@ -18,7 +18,7 @@ properties:
$ref: /schemas/types.yaml#/definitions/phandle $ref: /schemas/types.yaml#/definitions/phandle
description: description:
Node to get DDR loading. Refer to Node to get DDR loading. Refer to
Documentation/devicetree/bindings/devfreq/event/rockchip-dfi.txt. Documentation/devicetree/bindings/devfreq/event/rockchip,dfi.yaml.
clocks: clocks:
maxItems: 1 maxItems: 1
......
...@@ -88,7 +88,7 @@ static unsigned long find_available_min_freq(struct devfreq *devfreq) ...@@ -88,7 +88,7 @@ static unsigned long find_available_min_freq(struct devfreq *devfreq)
struct dev_pm_opp *opp; struct dev_pm_opp *opp;
unsigned long min_freq = 0; unsigned long min_freq = 0;
opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &min_freq); opp = dev_pm_opp_find_freq_ceil_indexed(devfreq->dev.parent, &min_freq, 0);
if (IS_ERR(opp)) if (IS_ERR(opp))
min_freq = 0; min_freq = 0;
else else
...@@ -102,7 +102,7 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq) ...@@ -102,7 +102,7 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq)
struct dev_pm_opp *opp; struct dev_pm_opp *opp;
unsigned long max_freq = ULONG_MAX; unsigned long max_freq = ULONG_MAX;
opp = dev_pm_opp_find_freq_floor(devfreq->dev.parent, &max_freq); opp = dev_pm_opp_find_freq_floor_indexed(devfreq->dev.parent, &max_freq, 0);
if (IS_ERR(opp)) if (IS_ERR(opp))
max_freq = 0; max_freq = 0;
else else
...@@ -196,7 +196,7 @@ static int set_freq_table(struct devfreq *devfreq) ...@@ -196,7 +196,7 @@ static int set_freq_table(struct devfreq *devfreq)
return -ENOMEM; return -ENOMEM;
for (i = 0, freq = 0; i < devfreq->max_state; i++, freq++) { for (i = 0, freq = 0; i < devfreq->max_state; i++, freq++) {
opp = dev_pm_opp_find_freq_ceil(devfreq->dev.parent, &freq); opp = dev_pm_opp_find_freq_ceil_indexed(devfreq->dev.parent, &freq, 0);
if (IS_ERR(opp)) { if (IS_ERR(opp)) {
devm_kfree(devfreq->dev.parent, devfreq->freq_table); devm_kfree(devfreq->dev.parent, devfreq->freq_table);
return PTR_ERR(opp); return PTR_ERR(opp);
...@@ -2036,18 +2036,18 @@ struct dev_pm_opp *devfreq_recommended_opp(struct device *dev, ...@@ -2036,18 +2036,18 @@ struct dev_pm_opp *devfreq_recommended_opp(struct device *dev,
if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) { if (flags & DEVFREQ_FLAG_LEAST_UPPER_BOUND) {
/* The freq is an upper bound. opp should be lower */ /* The freq is an upper bound. opp should be lower */
opp = dev_pm_opp_find_freq_floor(dev, freq); opp = dev_pm_opp_find_freq_floor_indexed(dev, freq, 0);
/* If not available, use the closest opp */ /* If not available, use the closest opp */
if (opp == ERR_PTR(-ERANGE)) if (opp == ERR_PTR(-ERANGE))
opp = dev_pm_opp_find_freq_ceil(dev, freq); opp = dev_pm_opp_find_freq_ceil_indexed(dev, freq, 0);
} else { } else {
/* The freq is an lower bound. opp should be higher */ /* The freq is an lower bound. opp should be higher */
opp = dev_pm_opp_find_freq_ceil(dev, freq); opp = dev_pm_opp_find_freq_ceil_indexed(dev, freq, 0);
/* If not available, use the closest opp */ /* If not available, use the closest opp */
if (opp == ERR_PTR(-ERANGE)) if (opp == ERR_PTR(-ERANGE))
opp = dev_pm_opp_find_freq_floor(dev, freq); opp = dev_pm_opp_find_freq_floor_indexed(dev, freq, 0);
} }
return opp; return opp;
......
...@@ -12,9 +12,9 @@ ...@@ -12,9 +12,9 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_address.h> #include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/devfreq-event.h> #include <linux/devfreq-event.h>
...@@ -507,7 +507,6 @@ static int of_get_devfreq_events(struct device_node *np, ...@@ -507,7 +507,6 @@ static int of_get_devfreq_events(struct device_node *np,
struct device *dev = info->dev; struct device *dev = info->dev;
struct device_node *events_np, *node; struct device_node *events_np, *node;
int i, j, count; int i, j, count;
const struct of_device_id *of_id;
int ret; int ret;
events_np = of_get_child_by_name(np, "events"); events_np = of_get_child_by_name(np, "events");
...@@ -525,13 +524,7 @@ static int of_get_devfreq_events(struct device_node *np, ...@@ -525,13 +524,7 @@ static int of_get_devfreq_events(struct device_node *np,
} }
info->num_events = count; info->num_events = count;
of_id = of_match_device(exynos_ppmu_id_match, dev); info->ppmu_type = (enum exynos_ppmu_type)device_get_match_data(dev);
if (of_id)
info->ppmu_type = (enum exynos_ppmu_type)of_id->data;
else {
of_node_put(events_np);
return -EINVAL;
}
j = 0; j = 0;
for_each_child_of_node(events_np, node) { for_each_child_of_node(events_np, node) {
......
This diff is collapsed.
...@@ -137,6 +137,8 @@ static int mtk_ccifreq_target(struct device *dev, unsigned long *freq, ...@@ -137,6 +137,8 @@ static int mtk_ccifreq_target(struct device *dev, unsigned long *freq,
if (drv->pre_freq == *freq) if (drv->pre_freq == *freq)
return 0; return 0;
mutex_lock(&drv->reg_lock);
inter_voltage = drv->inter_voltage; inter_voltage = drv->inter_voltage;
cci_pll = clk_get_parent(drv->cci_clk); cci_pll = clk_get_parent(drv->cci_clk);
...@@ -144,11 +146,10 @@ static int mtk_ccifreq_target(struct device *dev, unsigned long *freq, ...@@ -144,11 +146,10 @@ static int mtk_ccifreq_target(struct device *dev, unsigned long *freq,
opp = devfreq_recommended_opp(dev, &opp_rate, 1); opp = devfreq_recommended_opp(dev, &opp_rate, 1);
if (IS_ERR(opp)) { if (IS_ERR(opp)) {
dev_err(dev, "failed to find opp for freq: %ld\n", opp_rate); dev_err(dev, "failed to find opp for freq: %ld\n", opp_rate);
return PTR_ERR(opp); ret = PTR_ERR(opp);
goto out_unlock;
} }
mutex_lock(&drv->reg_lock);
voltage = dev_pm_opp_get_voltage(opp); voltage = dev_pm_opp_get_voltage(opp);
dev_pm_opp_put(opp); dev_pm_opp_put(opp);
...@@ -227,9 +228,9 @@ static int mtk_ccifreq_opp_notifier(struct notifier_block *nb, ...@@ -227,9 +228,9 @@ static int mtk_ccifreq_opp_notifier(struct notifier_block *nb,
drv = container_of(nb, struct mtk_ccifreq_drv, opp_nb); drv = container_of(nb, struct mtk_ccifreq_drv, opp_nb);
if (event == OPP_EVENT_ADJUST_VOLTAGE) { if (event == OPP_EVENT_ADJUST_VOLTAGE) {
mutex_lock(&drv->reg_lock);
freq = dev_pm_opp_get_freq(opp); freq = dev_pm_opp_get_freq(opp);
mutex_lock(&drv->reg_lock);
/* current opp item is changed */ /* current opp item is changed */
if (freq == drv->pre_freq) { if (freq == drv->pre_freq) {
volt = dev_pm_opp_get_voltage(opp); volt = dev_pm_opp_get_voltage(opp);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/suspend.h> #include <linux/suspend.h>
#include <soc/rockchip/pm_domains.h> #include <soc/rockchip/pm_domains.h>
#include <soc/rockchip/rockchip_grf.h>
#include <soc/rockchip/rk3399_grf.h> #include <soc/rockchip/rk3399_grf.h>
#include <soc/rockchip/rockchip_sip.h> #include <soc/rockchip/rockchip_sip.h>
...@@ -381,17 +382,16 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev) ...@@ -381,17 +382,16 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
} }
regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val); regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) & ddr_type = FIELD_GET(RK3399_PMUGRF_OS_REG2_DDRTYPE, val);
RK3399_PMUGRF_DDRTYPE_MASK;
switch (ddr_type) { switch (ddr_type) {
case RK3399_PMUGRF_DDRTYPE_DDR3: case ROCKCHIP_DDRTYPE_DDR3:
data->odt_dis_freq = data->ddr3_odt_dis_freq; data->odt_dis_freq = data->ddr3_odt_dis_freq;
break; break;
case RK3399_PMUGRF_DDRTYPE_LPDDR3: case ROCKCHIP_DDRTYPE_LPDDR3:
data->odt_dis_freq = data->lpddr3_odt_dis_freq; data->odt_dis_freq = data->lpddr3_odt_dis_freq;
break; break;
case RK3399_PMUGRF_DDRTYPE_LPDDR4: case ROCKCHIP_DDRTYPE_LPDDR4:
data->odt_dis_freq = data->lpddr4_odt_dis_freq; data->odt_dis_freq = data->lpddr4_odt_dis_freq;
break; break;
default: default:
......
...@@ -11,11 +11,8 @@ ...@@ -11,11 +11,8 @@
/* PMU GRF Registers */ /* PMU GRF Registers */
#define RK3399_PMUGRF_OS_REG2 0x308 #define RK3399_PMUGRF_OS_REG2 0x308
#define RK3399_PMUGRF_DDRTYPE_SHIFT 13 #define RK3399_PMUGRF_OS_REG2_DDRTYPE GENMASK(15, 13)
#define RK3399_PMUGRF_DDRTYPE_MASK 7 #define RK3399_PMUGRF_OS_REG2_BW_CH0 GENMASK(3, 2)
#define RK3399_PMUGRF_DDRTYPE_DDR3 3 #define RK3399_PMUGRF_OS_REG2_BW_CH1 GENMASK(19, 18)
#define RK3399_PMUGRF_DDRTYPE_LPDDR2 5
#define RK3399_PMUGRF_DDRTYPE_LPDDR3 6
#define RK3399_PMUGRF_DDRTYPE_LPDDR4 7
#endif #endif
/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef __SOC_RK3568_GRF_H
#define __SOC_RK3568_GRF_H
#define RK3568_PMUGRF_OS_REG2 0x208
#define RK3568_PMUGRF_OS_REG2_DRAMTYPE_INFO GENMASK(15, 13)
#define RK3568_PMUGRF_OS_REG2_BW_CH0 GENMASK(3, 2)
#define RK3568_PMUGRF_OS_REG3 0x20c
#define RK3568_PMUGRF_OS_REG3_DRAMTYPE_INFO_V3 GENMASK(13, 12)
#define RK3568_PMUGRF_OS_REG3_SYSREG_VERSION GENMASK(31, 28)
#endif /* __SOC_RK3568_GRF_H */
/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef __SOC_RK3588_GRF_H
#define __SOC_RK3588_GRF_H
#define RK3588_PMUGRF_OS_REG2 0x208
#define RK3588_PMUGRF_OS_REG2_DRAMTYPE_INFO GENMASK(15, 13)
#define RK3588_PMUGRF_OS_REG2_BW_CH0 GENMASK(3, 2)
#define RK3588_PMUGRF_OS_REG2_BW_CH1 GENMASK(19, 18)
#define RK3588_PMUGRF_OS_REG2_CH_INFO GENMASK(29, 28)
#define RK3588_PMUGRF_OS_REG3 0x20c
#define RK3588_PMUGRF_OS_REG3_DRAMTYPE_INFO_V3 GENMASK(13, 12)
#define RK3588_PMUGRF_OS_REG3_SYSREG_VERSION GENMASK(31, 28)
#define RK3588_PMUGRF_OS_REG4 0x210
#define RK3588_PMUGRF_OS_REG5 0x214
#endif /* __SOC_RK3588_GRF_H */
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Rockchip General Register Files definitions
*/
#ifndef __SOC_ROCKCHIP_GRF_H
#define __SOC_ROCKCHIP_GRF_H
/* Rockchip DDRTYPE defines */
enum {
ROCKCHIP_DDRTYPE_DDR3 = 3,
ROCKCHIP_DDRTYPE_LPDDR2 = 5,
ROCKCHIP_DDRTYPE_LPDDR3 = 6,
ROCKCHIP_DDRTYPE_LPDDR4 = 7,
ROCKCHIP_DDRTYPE_LPDDR4X = 8,
};
#endif /* __SOC_ROCKCHIP_GRF_H */
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