* Re: [PATCH v5 09/18] thermal: sun8i: rework for ths calibrate func
From: Zhang Rui @ 2019-08-28 12:45 UTC (permalink / raw)
To: Yangtao Li, edubezval, daniel.lezcano, robh+dt, mark.rutland,
maxime.ripard, wens, mchehab+samsung, davem, gregkh,
Jonathan.Cameron, nicolas.ferre
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-pm
In-Reply-To: <20190810052829.6032-10-tiny.windzz@gmail.com>
On Sat, 2019-08-10 at 05:28 +0000, Yangtao Li wrote:
> Here, we do something to prepare for the subsequent
> support of multiple platforms.
>
> 1) rename sun50i_ths_calibrate to sun8i_ths_calibrate, because
> this function should be suitable for all platforms now.
>
> 2) introduce calibrate callback to mask calibration method
> differences.
>
> Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
IMO, patch 4/18 to patch 9/18 are all changes to a new file introduced
in patch 1/18, so why not have a prettier patch 1/18 instead of
separate patches?
thanks,
rui
> ---
> drivers/thermal/sun8i_thermal.c | 86 ++++++++++++++++++-------------
> --
> 1 file changed, 48 insertions(+), 38 deletions(-)
>
> diff --git a/drivers/thermal/sun8i_thermal.c
> b/drivers/thermal/sun8i_thermal.c
> index 6f4294c2aba7..47c20c4c69e7 100644
> --- a/drivers/thermal/sun8i_thermal.c
> +++ b/drivers/thermal/sun8i_thermal.c
> @@ -60,6 +60,8 @@ struct ths_thermal_chip {
> int scale;
> int ft_deviation;
> int temp_data_base;
> + int (*calibrate)(struct ths_device *tmdev,
> + u16 *caldata, int callen);
> int (*init)(struct ths_device *tmdev);
> int (*irq_ack)(struct ths_device *tmdev);
> };
> @@ -152,45 +154,14 @@ static irqreturn_t sun8i_irq_thread(int irq,
> void *data)
> return IRQ_HANDLED;
> }
>
> -static int sun50i_ths_calibrate(struct ths_device *tmdev)
> +static int sun50i_h6_ths_calibrate(struct ths_device *tmdev,
> + u16 *caldata, int callen)
> {
> - struct nvmem_cell *calcell;
> struct device *dev = tmdev->dev;
> - u16 *caldata;
> - size_t callen;
> - int ft_temp;
> - int i, ret = 0;
> -
> - calcell = devm_nvmem_cell_get(dev, "calib");
> - if (IS_ERR(calcell)) {
> - if (PTR_ERR(calcell) == -EPROBE_DEFER)
> - return -EPROBE_DEFER;
> - /*
> - * Even if the external calibration data stored in sid
> is
> - * not accessible, the THS hardware can still work,
> although
> - * the data won't be so accurate.
> - *
> - * The default value of calibration register is 0x800
> for
> - * every sensor, and the calibration value is usually
> 0x7xx
> - * or 0x8xx, so they won't be away from the default
> value
> - * for a lot.
> - *
> - * So here we do not return error if the calibartion
> data is
> - * not available, except the probe needs deferring.
> - */
> - goto out;
> - }
> + int i, ft_temp;
>
> - caldata = nvmem_cell_read(calcell, &callen);
> - if (IS_ERR(caldata)) {
> - ret = PTR_ERR(caldata);
> - goto out;
> - }
> -
> - if (!caldata[0] || callen < 2 + 2 * tmdev->chip->sensor_num) {
> - ret = -EINVAL;
> - goto out_free;
> - }
> + if (!caldata[0] || callen < 2 + 2 * tmdev->chip->sensor_num)
> + return -EINVAL;
>
> /*
> * efuse layout:
> @@ -245,7 +216,45 @@ static int sun50i_ths_calibrate(struct
> ths_device *tmdev)
> cdata << offset);
> }
>
> -out_free:
> + return 0;
> +}
> +
> +static int sun8i_ths_calibrate(struct ths_device *tmdev)
> +{
> + struct nvmem_cell *calcell;
> + struct device *dev = tmdev->dev;
> + u16 *caldata;
> + size_t callen;
> + int ret = 0;
> +
> + calcell = devm_nvmem_cell_get(dev, "calib");
> + if (IS_ERR(calcell)) {
> + if (PTR_ERR(calcell) == -EPROBE_DEFER)
> + return -EPROBE_DEFER;
> + /*
> + * Even if the external calibration data stored in sid
> is
> + * not accessible, the THS hardware can still work,
> although
> + * the data won't be so accurate.
> + *
> + * The default value of calibration register is 0x800
> for
> + * every sensor, and the calibration value is usually
> 0x7xx
> + * or 0x8xx, so they won't be away from the default
> value
> + * for a lot.
> + *
> + * So here we do not return error if the calibartion
> data is
> + * not available, except the probe needs deferring.
> + */
> + goto out;
> + }
> +
> + caldata = nvmem_cell_read(calcell, &callen);
> + if (IS_ERR(caldata)) {
> + ret = PTR_ERR(caldata);
> + goto out;
> + }
> +
> + tmdev->chip->calibrate(tmdev, caldata, callen);
> +
> kfree(caldata);
> out:
> return ret;
> @@ -294,7 +303,7 @@ static int sun8i_ths_resource_init(struct
> ths_device *tmdev)
> if (ret)
> goto bus_disable;
>
> - ret = sun50i_ths_calibrate(tmdev);
> + ret = sun8i_ths_calibrate(tmdev);
> if (ret)
> goto mod_disable;
>
> @@ -422,6 +431,7 @@ static const struct ths_thermal_chip
> sun50i_h6_ths = {
> .scale = -67,
> .ft_deviation = SUN50I_H6_FT_DEVIATION,
> .temp_data_base = SUN50I_H6_THS_TEMP_DATA,
> + .calibrate = sun50i_h6_ths_calibrate,
> .init = sun50i_h6_thermal_init,
> .irq_ack = sun50i_h6_irq_ack,
> };
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 4/8] coresight: etm4x: Fix issues with start-stop logic.
From: Mike Leach @ 2019-08-28 12:40 UTC (permalink / raw)
To: Leo Yan; +Cc: Coresight ML, linux-arm-kernel, Mathieu Poirier
In-Reply-To: <20190828031750.GD26133@leoy-ThinkPad-X240s>
Hi Leo,
On Wed, 28 Aug 2019 at 04:18, Leo Yan <leo.yan@linaro.org> wrote:
>
> Hi Mike,
>
> On Mon, Aug 19, 2019 at 09:57:16PM +0100, Mike Leach wrote:
> > Fixes the following issues when using the ETMv4 start-stop logic.
> >
> > 1) Setting a start or a stop address should not automatically set the
> > start-stop status to 'on'. The value set by the user in 'mode' must
> > be respected or start instances could be missed.
> > 2) Missing API for controlling TRCVIPCSSCTLR - start stop control by
> > PE comparators.
> > 3) Default ETM configuration sets a trace all range, and correctly sets
> > the start-stop status bit. This was not being correctly reflected in
> > the 'mode' parameter.
> >
> > Signed-off-by: Mike Leach <mike.leach@linaro.org>
> > ---
> > .../coresight/coresight-etm4x-sysfs.c | 39 +++++++++++++++++--
> > drivers/hwtracing/coresight/coresight-etm4x.c | 1 +
> > 2 files changed, 36 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> > index 7eab5d7d0b62..3bcc260c9e55 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> > @@ -217,6 +217,7 @@ static ssize_t reset_store(struct device *dev,
> >
> > /* No start-stop filtering for ViewInst */
> > config->vissctlr = 0x0;
> > + config->vipcssctlr = 0x0;
> >
> > /* Disable seq events */
> > for (i = 0; i < drvdata->nrseqstate-1; i++)
> > @@ -1059,8 +1060,6 @@ static ssize_t addr_start_store(struct device *dev,
> > config->addr_val[idx] = (u64)val;
> > config->addr_type[idx] = ETM_ADDR_TYPE_START;
> > config->vissctlr |= BIT(idx);
> > - /* SSSTATUS, bit[9] - turn on start/stop logic */
> > - config->vinst_ctrl |= BIT(9);
> > spin_unlock(&drvdata->spinlock);
> > return size;
> > }
> > @@ -1116,8 +1115,6 @@ static ssize_t addr_stop_store(struct device *dev,
> > config->addr_val[idx] = (u64)val;
> > config->addr_type[idx] = ETM_ADDR_TYPE_STOP;
> > config->vissctlr |= BIT(idx + 16);
> > - /* SSSTATUS, bit[9] - turn on start/stop logic */
> > - config->vinst_ctrl |= BIT(9);
> > spin_unlock(&drvdata->spinlock);
> > return size;
> > }
> > @@ -1271,6 +1268,39 @@ static ssize_t addr_exlevel_s_ns_store(struct device *dev,
> > }
> > static DEVICE_ATTR_RW(addr_exlevel_s_ns);
> >
> > +static ssize_t vinst_pe_cmp_start_stop_show(struct device *dev,
> > + struct device_attribute *attr,
> > + char *buf)
> > +{
> > + unsigned long val;
> > + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
> > + struct etmv4_config *config = &drvdata->config;
> > +
> > + if (!drvdata->nr_pe_cmp)
> > + return -EINVAL;
> > + val = config->vipcssctlr;
> > + return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
> > +}
> > +static ssize_t vinst_pe_cmp_start_stop_store(struct device *dev,
> > + struct device_attribute *attr,
> > + const char *buf, size_t size)
> > +{
> > + unsigned long val;
> > + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
> > + struct etmv4_config *config = &drvdata->config;
> > +
> > + if (kstrtoul(buf, 16, &val))
> > + return -EINVAL;
> > + if (!drvdata->nr_pe_cmp)
> > + return -EINVAL;
> > +
> > + spin_lock(&drvdata->spinlock);
> > + config->vipcssctlr = val;
> > + spin_unlock(&drvdata->spinlock);
>
> I don't find the code to set 'config->vipcssctlr' into hardware register
> TRCVIPCSSCTLR.
>
This is in coresight-etm4x.c, etm4_enable_hw(), ll 126-127
> And based on the register definition, here we also should clamp the
> value for START/STOP?
>
Unimplemented fields are RES0 - there is no issue with writing these -
they will remain RES0. (ETM arch spec, section 7.2.1)
Thanks
Mike
> Thanks,
> Leo Yan
>
> > + return size;
> > +}
> > +static DEVICE_ATTR_RW(vinst_pe_cmp_start_stop);
> > +
> > static ssize_t seq_idx_show(struct device *dev,
> > struct device_attribute *attr,
> > char *buf)
> > @@ -2077,6 +2107,7 @@ static struct attribute *coresight_etmv4_attrs[] = {
> > &dev_attr_addr_ctxtype.attr,
> > &dev_attr_addr_context.attr,
> > &dev_attr_addr_exlevel_s_ns.attr,
> > + &dev_attr_vinst_pe_cmp_start_stop.attr,
> > &dev_attr_seq_idx.attr,
> > &dev_attr_seq_state.attr,
> > &dev_attr_seq_event.attr,
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x.c b/drivers/hwtracing/coresight/coresight-etm4x.c
> > index 52b8876de157..d8b078d0cc7f 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x.c
> > @@ -868,6 +868,7 @@ static void etm4_set_default_filter(struct etmv4_config *config)
> > * in the started state
> > */
> > config->vinst_ctrl |= BIT(9);
> > + config->mode |= ETM_MODE_VIEWINST_STARTSTOP;
> >
> > /* No start-stop filtering for ViewInst */
> > config->vissctlr = 0x0;
> > --
> > 2.17.1
> >
> > _______________________________________________
> > CoreSight mailing list
> > CoreSight@lists.linaro.org
> > https://lists.linaro.org/mailman/listinfo/coresight
--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v5 03/18] thermal: fix indentation in makefile
From: Zhang Rui @ 2019-08-28 12:40 UTC (permalink / raw)
To: Yangtao Li, edubezval, daniel.lezcano, robh+dt, mark.rutland,
maxime.ripard, wens, mchehab+samsung, davem, gregkh,
Jonathan.Cameron, nicolas.ferre
Cc: devicetree, linux-kernel, linux-arm-kernel, linux-pm
In-Reply-To: <20190810052829.6032-4-tiny.windzz@gmail.com>
On Sat, 2019-08-10 at 05:28 +0000, Yangtao Li wrote:
> To unify code style.
>
> Signed-off-by: Yangtao Li <tiny.windzz@gmail.com>
the later patches in this series does not change Makefile.
So this seems to be a cleanup patch independent of this patch set.
It's better to remove this patch from this patch series.
thanks,
rui
> ---
> drivers/thermal/Makefile | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
> index fa6f8b206281..d7eafb5ef8ef 100644
> --- a/drivers/thermal/Makefile
> +++ b/drivers/thermal/Makefile
> @@ -5,7 +5,7 @@
>
> obj-$(CONFIG_THERMAL) += thermal_sys.o
> thermal_sys-y += thermal_core.o
> thermal_sysfs.o \
> - thermal_helpers.o
> + thermal_helpers.o
>
> # interface to/from other layers providing sensors
> thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
> @@ -25,11 +25,11 @@ thermal_sys-$(CONFIG_CPU_THERMAL) +=
> cpu_cooling.o
> thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o
>
> # devfreq cooling
> -thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
> +thermal_sys-$(CONFIG_DEVFREQ_THERMAL) += devfreq_cooling.o
>
> # platform thermal drivers
> obj-y += broadcom/
> -obj-$(CONFIG_THERMAL_MMIO) += thermal_mmio.o
> +obj-$(CONFIG_THERMAL_MMIO) += thermal_mmio.o
> obj-$(CONFIG_SPEAR_THERMAL) += spear_thermal.o
> obj-$(CONFIG_SUN8I_THERMAL) += sun8i_thermal.o
> obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o
> @@ -50,7 +50,7 @@ obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-
> thermal/
> obj-y += st/
> obj-$(CONFIG_QCOM_TSENS) += qcom/
> obj-y += tegra/
> -obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
> +obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o
> obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
> obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
> obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v7 9/9] drm: exynos: exynos_hdmi: use cec_notifier_conn_(un)register
From: Dariusz Marcinkiewicz @ 2019-08-28 12:38 UTC (permalink / raw)
To: Sylwester Nawrocki
Cc: linux-samsung-soc, Joonyoung Shim, David Airlie, Seung-Woo Kim,
open list, dri-devel, Inki Dae, Kyungmin Park, Kukjin Kim,
Krzysztof Kozlowski, Daniel Vetter, Hans Verkuil,
linux-arm-kernel, linux-media
In-Reply-To: <6bbfb6f8-15c2-9ad2-8857-898f4c6435a3@samsung.com>
Hi.
On Wed, Aug 28, 2019 at 10:39 AM Sylwester Nawrocki
<s.nawrocki@samsung.com> wrote:
>
> nit: I think err_rpm_disable or err_pm_runtime_disable could be better
> label names.
>
Submitted v7.1 which replaces err_runtime_disable with err_rpm_disable.
Thank you.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v7.1 9/9] drm: exynos: exynos_hdmi: use cec_notifier_conn_(un)register
From: Dariusz Marcinkiewicz @ 2019-08-28 12:34 UTC (permalink / raw)
To: dri-devel, linux-media, s.nawrocki, hverkuil-cisco
Cc: linux-samsung-soc, Joonyoung Shim, David Airlie, Seung-Woo Kim,
linux-kernel, Krzysztof Kozlowski, Inki Dae, Kyungmin Park,
Kukjin Kim, Daniel Vetter, Dariusz Marcinkiewicz,
linux-arm-kernel
In-Reply-To: <6bbfb6f8-15c2-9ad2-8857-898f4c6435a3@samsung.com>
Use the new cec_notifier_conn_(un)register() functions to
(un)register the notifier for the HDMI connector, and fill in
the cec_connector_info.
Changes since v7:
- err_runtime_disable -> err_rpm_disable
Changes since v2:
- removed unnecessary call to invalidate phys address before
deregistering the notifier,
- use cec_notifier_phys_addr_invalidate instead of setting
invalid address on a notifier.
Signed-off-by: Dariusz Marcinkiewicz <darekm@google.com>
Tested-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
---
drivers/gpu/drm/exynos/exynos_hdmi.c | 31 ++++++++++++++++------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index bc1565f1822ab..799f2db13efe2 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -852,6 +852,10 @@ static enum drm_connector_status hdmi_detect(struct drm_connector *connector,
static void hdmi_connector_destroy(struct drm_connector *connector)
{
+ struct hdmi_context *hdata = connector_to_hdmi(connector);
+
+ cec_notifier_conn_unregister(hdata->notifier);
+
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
}
@@ -935,6 +939,7 @@ static int hdmi_create_connector(struct drm_encoder *encoder)
{
struct hdmi_context *hdata = encoder_to_hdmi(encoder);
struct drm_connector *connector = &hdata->connector;
+ struct cec_connector_info conn_info;
int ret;
connector->interlace_allowed = true;
@@ -957,6 +962,15 @@ static int hdmi_create_connector(struct drm_encoder *encoder)
DRM_DEV_ERROR(hdata->dev, "Failed to attach bridge\n");
}
+ cec_fill_conn_info_from_drm(&conn_info, connector);
+
+ hdata->notifier = cec_notifier_conn_register(hdata->dev, NULL,
+ &conn_info);
+ if (hdata->notifier == NULL) {
+ ret = -ENOMEM;
+ DRM_DEV_ERROR(hdata->dev, "Failed to allocate CEC notifier\n");
+ }
+
return ret;
}
@@ -1528,8 +1542,8 @@ static void hdmi_disable(struct drm_encoder *encoder)
*/
mutex_unlock(&hdata->mutex);
cancel_delayed_work(&hdata->hotplug_work);
- cec_notifier_set_phys_addr(hdata->notifier,
- CEC_PHYS_ADDR_INVALID);
+ if (hdata->notifier)
+ cec_notifier_phys_addr_invalidate(hdata->notifier);
return;
}
@@ -2006,12 +2020,6 @@ static int hdmi_probe(struct platform_device *pdev)
}
}
- hdata->notifier = cec_notifier_get(&pdev->dev);
- if (hdata->notifier == NULL) {
- ret = -ENOMEM;
- goto err_hdmiphy;
- }
-
pm_runtime_enable(dev);
audio_infoframe = &hdata->audio.infoframe;
@@ -2023,7 +2031,7 @@ static int hdmi_probe(struct platform_device *pdev)
ret = hdmi_register_audio_device(hdata);
if (ret)
- goto err_notifier_put;
+ goto err_rpm_disable;
ret = component_add(&pdev->dev, &hdmi_component_ops);
if (ret)
@@ -2034,8 +2042,7 @@ static int hdmi_probe(struct platform_device *pdev)
err_unregister_audio:
platform_device_unregister(hdata->audio.pdev);
-err_notifier_put:
- cec_notifier_put(hdata->notifier);
+err_rpm_disable:
pm_runtime_disable(dev);
err_hdmiphy:
@@ -2054,12 +2061,10 @@ static int hdmi_remove(struct platform_device *pdev)
struct hdmi_context *hdata = platform_get_drvdata(pdev);
cancel_delayed_work_sync(&hdata->hotplug_work);
- cec_notifier_set_phys_addr(hdata->notifier, CEC_PHYS_ADDR_INVALID);
component_del(&pdev->dev, &hdmi_component_ops);
platform_device_unregister(hdata->audio.pdev);
- cec_notifier_put(hdata->notifier);
pm_runtime_disable(&pdev->dev);
if (!IS_ERR(hdata->reg_hdmi_en))
--
2.23.0.187.g17f5b7556c-goog
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V3 06/10] soc: mediatek: add MT8183 dvfsrc support
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Henry Chen,
Fan Chen, devicetree, linux-mediatek, linux-arm-kernel
In-Reply-To: <1566995328-15158-1-git-send-email-henryc.chen@mediatek.com>
Add dvfsrc driver for MT8183
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
drivers/soc/mediatek/Kconfig | 15 ++
drivers/soc/mediatek/Makefile | 1 +
drivers/soc/mediatek/mtk-dvfsrc.c | 374 ++++++++++++++++++++++++++++++++++++++
include/soc/mediatek/mtk_dvfsrc.h | 22 +++
4 files changed, 412 insertions(+)
create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
create mode 100644 include/soc/mediatek/mtk_dvfsrc.h
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig
index 2114b56..384cfb5 100644
--- a/drivers/soc/mediatek/Kconfig
+++ b/drivers/soc/mediatek/Kconfig
@@ -25,6 +25,21 @@ config MTK_INFRACFG
INFRACFG controller contains various infrastructure registers not
directly associated to any device.
+config MTK_DVFSRC
+ bool "MediaTek DVFSRC Support"
+ depends on ARCH_MEDIATEK
+ default ARCH_MEDIATEK
+ select MTK_INFRACFG
+ select PM_GENERIC_DOMAINS if PM
+ depends on MTK_SCPSYS
+ help
+ Say yes here to add support for the MediaTek DVFSRC (dynamic voltage
+ and frequency scaling resource collector) found
+ on different MediaTek SoCs. The DVFSRC is a proprietary
+ hardware which is used to collect all the requests from
+ system and turn into the decision of minimum Vcore voltage
+ and minimum DRAM frequency to fulfill those requests.
+
config MTK_PMIC_WRAP
tristate "MediaTek PMIC Wrapper Support"
depends on RESET_CONTROLLER
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile
index b442be9..f0b09ad 100644
--- a/drivers/soc/mediatek/Makefile
+++ b/drivers/soc/mediatek/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_MTK_CMDQ) += mtk-cmdq-helper.o
+obj-$(CONFIG_MTK_DVFSRC) += mtk-dvfsrc.o
obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o mtk-scpsys-ext.o
obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o
obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o
diff --git a/drivers/soc/mediatek/mtk-dvfsrc.c b/drivers/soc/mediatek/mtk-dvfsrc.c
new file mode 100644
index 0000000..ee2bb12
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-dvfsrc.c
@@ -0,0 +1,374 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 MediaTek Inc.
+ */
+#include <linux/arm-smccc.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <soc/mediatek/mtk_dvfsrc.h>
+#include <soc/mediatek/mtk_sip.h>
+#include <dt-bindings/power/mt8183-power.h>
+#include <dt-bindings/soc/mtk,dvfsrc.h>
+#include "mtk-scpsys.h"
+
+#define DVFSRC_IDLE 0x00
+#define DVFSRC_GET_TARGET_LEVEL(x) (((x) >> 0) & 0x0000ffff)
+#define DVFSRC_GET_CURRENT_LEVEL(x) (((x) >> 16) & 0x0000ffff)
+#define kbps_to_mbps(x) (x / 1000)
+
+#define MT8183_DVFSRC_OPP_LP4 0
+#define MT8183_DVFSRC_OPP_LP4X 1
+#define MT8183_DVFSRC_OPP_LP3 2
+
+#define POLL_TIMEOUT 1000
+#define STARTUP_TIME 1
+
+struct dvfsrc_opp {
+ u32 vcore_opp;
+ u32 dram_opp;
+};
+
+struct dvfsrc_domain {
+ u32 id;
+ u32 state;
+};
+
+struct mtk_dvfsrc;
+struct dvfsrc_soc_data {
+ const int *regs;
+ u32 num_opp;
+ u32 num_domains;
+ const struct dvfsrc_opp **opps;
+ struct dvfsrc_domain *domains;
+ int (*get_target_level)(struct mtk_dvfsrc *dvfsrc);
+ int (*get_current_level)(struct mtk_dvfsrc *dvfsrc);
+ void (*set_dram_bw)(struct mtk_dvfsrc *dvfsrc, u64 bw);
+ void (*set_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+ int (*wait_for_opp_level)(struct mtk_dvfsrc *dvfsrc, u32 level);
+};
+
+struct mtk_dvfsrc {
+ struct device *dev;
+ struct clk *clk_dvfsrc;
+ const struct dvfsrc_soc_data *dvd;
+ int dram_type;
+ void __iomem *regs;
+ struct mutex lock;
+ struct notifier_block scpsys_notifier;
+};
+
+static u32 dvfsrc_read(struct mtk_dvfsrc *dvfs, u32 offset)
+{
+ return readl(dvfs->regs + dvfs->dvd->regs[offset]);
+}
+
+static void dvfsrc_write(struct mtk_dvfsrc *dvfs, u32 offset, u32 val)
+{
+ writel(val, dvfs->regs + dvfs->dvd->regs[offset]);
+}
+
+enum dvfsrc_regs {
+ DVFSRC_SW_REQ,
+ DVFSRC_LEVEL,
+ DVFSRC_SW_BW,
+ DVFSRC_LAST,
+};
+
+static const int mt8183_regs[] = {
+ [DVFSRC_SW_REQ] = 0x4,
+ [DVFSRC_LEVEL] = 0xDC,
+ [DVFSRC_SW_BW] = 0x160,
+ [DVFSRC_LAST] = 0x308,
+};
+
+static const struct dvfsrc_opp *get_current_opp(struct mtk_dvfsrc *dvfsrc)
+{
+ int level;
+
+ level = dvfsrc->dvd->get_current_level(dvfsrc);
+ return &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+}
+
+static int dvfsrc_is_idle(struct mtk_dvfsrc *dvfsrc)
+{
+ if (!dvfsrc->dvd->get_target_level)
+ return true;
+
+ return dvfsrc->dvd->get_target_level(dvfsrc);
+}
+
+static int mt8183_wait_for_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+ const struct dvfsrc_opp *target, *curr;
+ int ret;
+
+ target = &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+ ret = readx_poll_timeout(get_current_opp, dvfsrc, curr,
+ curr->dram_opp >= target->dram_opp &&
+ curr->vcore_opp >= target->vcore_opp,
+ STARTUP_TIME, POLL_TIMEOUT);
+ if (ret < 0) {
+ dev_warn(dvfsrc->dev,
+ "timeout, target: %u, dram: %d, vcore: %d\n",
+ level, curr->dram_opp, curr->vcore_opp);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int mt8183_get_target_level(struct mtk_dvfsrc *dvfsrc)
+{
+ return DVFSRC_GET_TARGET_LEVEL(dvfsrc_read(dvfsrc, DVFSRC_LEVEL));
+}
+
+static int mt8183_get_current_level(struct mtk_dvfsrc *dvfsrc)
+{
+ return ffs(DVFSRC_GET_CURRENT_LEVEL(dvfsrc_read(dvfsrc, DVFSRC_LEVEL)));
+}
+
+static void mt8183_set_dram_bw(struct mtk_dvfsrc *dvfsrc, u64 bw)
+{
+ dvfsrc_write(dvfsrc, DVFSRC_SW_BW, kbps_to_mbps(bw) / 100);
+}
+
+static void mt8183_set_opp_level(struct mtk_dvfsrc *dvfsrc, u32 level)
+{
+ int vcore_opp, dram_opp;
+ const struct dvfsrc_opp *opp;
+
+ /* translate pstate to dvfsrc level, and set it to DVFSRC HW */
+ opp = &dvfsrc->dvd->opps[dvfsrc->dram_type][level];
+ vcore_opp = opp->vcore_opp;
+ dram_opp = opp->dram_opp;
+
+ dev_dbg(dvfsrc->dev, "vcore_opp: %d, dram_opp: %d\n",
+ vcore_opp, dram_opp);
+ dvfsrc_write(dvfsrc, DVFSRC_SW_REQ, dram_opp | vcore_opp << 2);
+}
+
+void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data)
+{
+ int ret, state;
+ struct mtk_dvfsrc *dvfsrc = dev_get_drvdata(dev);
+
+ dev_dbg(dvfsrc->dev, "cmd: %d, data: %llu\n", cmd, data);
+
+ mutex_lock(&dvfsrc->lock);
+
+ switch (cmd) {
+ case MTK_DVFSRC_CMD_BW_REQUEST:
+ dvfsrc->dvd->set_dram_bw(dvfsrc, data);
+ goto out;
+ case MTK_DVFSRC_CMD_OPP_REQUEST:
+ dvfsrc->dvd->set_opp_level(dvfsrc, data);
+ break;
+ default:
+ dev_err(dvfsrc->dev, "unknown command: %d\n", cmd);
+ break;
+ }
+
+ /* DVFSRC need to wait at least 2T(~196ns) to handle request
+ * after recieving command
+ */
+ udelay(STARTUP_TIME);
+
+ ret = readx_poll_timeout(dvfsrc_is_idle, dvfsrc,
+ state, state == DVFSRC_IDLE,
+ STARTUP_TIME, POLL_TIMEOUT);
+
+ if (ret < 0) {
+ dev_warn(dvfsrc->dev,
+ "%d: idle timeout, data: %llu, last: %d -> %d\n",
+ cmd, data,
+ dvfsrc->dvd->get_current_level(dvfsrc),
+ dvfsrc->dvd->get_target_level(dvfsrc));
+ goto out;
+ }
+
+ dvfsrc->dvd->wait_for_opp_level(dvfsrc, data);
+
+out:
+ mutex_unlock(&dvfsrc->lock);
+}
+EXPORT_SYMBOL(mtk_dvfsrc_send_request);
+
+static int dvfsrc_set_performance(struct notifier_block *b,
+ unsigned long pstate, void *v)
+{
+ bool match = false;
+ int i;
+ struct mtk_dvfsrc *dvfsrc;
+ struct scp_event_data *sc = v;
+ struct dvfsrc_domain *d;
+ u32 highest;
+
+ if (sc->event_type != MTK_SCPSYS_PSTATE)
+ return 0;
+
+ dvfsrc = container_of(b, struct mtk_dvfsrc, scpsys_notifier);
+
+ d = dvfsrc->dvd->domains;
+
+ if (pstate > dvfsrc->dvd->num_opp) {
+ dev_err(dvfsrc->dev, "pstate out of range = %ld\n", pstate);
+ return 0;
+ }
+
+ for (i = 0, highest = 0; i < dvfsrc->dvd->num_domains; i++, d++) {
+ if (sc->domain_id == d->id) {
+ d->state = pstate;
+ match = true;
+ }
+ highest = max(highest, d->state);
+ }
+
+ if (!match)
+ return 0;
+
+ /* pstat start from level 1, array index start from 0 */
+ mtk_dvfsrc_send_request(dvfsrc->dev, MTK_DVFSRC_CMD_OPP_REQUEST,
+ highest - 1);
+
+ return 0;
+}
+
+static void pstate_notifier_register(struct mtk_dvfsrc *dvfsrc)
+{
+ dvfsrc->scpsys_notifier.notifier_call = dvfsrc_set_performance;
+ register_scpsys_notifier(&dvfsrc->scpsys_notifier);
+}
+
+static int mtk_dvfsrc_probe(struct platform_device *pdev)
+{
+ struct arm_smccc_res ares;
+ struct resource *res;
+ struct mtk_dvfsrc *dvfsrc;
+ int ret;
+
+ dvfsrc = devm_kzalloc(&pdev->dev, sizeof(*dvfsrc), GFP_KERNEL);
+ if (!dvfsrc)
+ return -ENOMEM;
+
+ dvfsrc->dvd = of_device_get_match_data(&pdev->dev);
+ dvfsrc->dev = &pdev->dev;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dvfsrc->regs = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(dvfsrc->regs))
+ return PTR_ERR(dvfsrc->regs);
+
+ dvfsrc->clk_dvfsrc = devm_clk_get(dvfsrc->dev, "dvfsrc");
+ if (IS_ERR(dvfsrc->clk_dvfsrc)) {
+ dev_err(dvfsrc->dev, "failed to get clock: %ld\n",
+ PTR_ERR(dvfsrc->clk_dvfsrc));
+ return PTR_ERR(dvfsrc->clk_dvfsrc);
+ }
+
+ ret = clk_prepare_enable(dvfsrc->clk_dvfsrc);
+ if (ret)
+ return ret;
+
+ mutex_init(&dvfsrc->lock);
+
+ arm_smccc_smc(MTK_SIP_SPM, MTK_SIP_SPM_DVFSRC_INIT, 0, 0, 0, 0, 0, 0,
+ &ares);
+
+ if (!ares.a0) {
+ dvfsrc->dram_type = ares.a1;
+ dev_info(dvfsrc->dev, "dram_type: %d\n", dvfsrc->dram_type);
+ } else {
+ dev_err(dvfsrc->dev, "init fails: %lu\n", ares.a0);
+ clk_disable_unprepare(dvfsrc->clk_dvfsrc);
+ return ares.a0;
+ }
+
+ platform_set_drvdata(pdev, dvfsrc);
+ pstate_notifier_register(dvfsrc);
+
+ return devm_of_platform_populate(&pdev->dev);
+}
+
+static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp4[] = {
+ {0, 0}, {0, 1}, {0, 2}, {1, 2},
+};
+
+static const struct dvfsrc_opp dvfsrc_opp_mt8183_lp3[] = {
+ {0, 0}, {0, 1}, {1, 1}, {1, 2},
+};
+
+static const struct dvfsrc_opp *dvfsrc_opp_mt8183[] = {
+ [MT8183_DVFSRC_OPP_LP4] = dvfsrc_opp_mt8183_lp4,
+ [MT8183_DVFSRC_OPP_LP4X] = dvfsrc_opp_mt8183_lp3,
+ [MT8183_DVFSRC_OPP_LP3] = dvfsrc_opp_mt8183_lp3,
+};
+
+static struct dvfsrc_domain dvfsrc_domains_mt8183[] = {
+ { MT8183_POWER_DOMAIN_MFG_ASYNC, 0 },
+ { MT8183_POWER_DOMAIN_MFG, 0 },
+ { MT8183_POWER_DOMAIN_CAM, 0 },
+ { MT8183_POWER_DOMAIN_DISP, 0 },
+ { MT8183_POWER_DOMAIN_ISP, 0 },
+ { MT8183_POWER_DOMAIN_VDEC, 0 },
+ { MT8183_POWER_DOMAIN_VENC, 0 },
+};
+
+static const struct dvfsrc_soc_data mt8183_data = {
+ .opps = dvfsrc_opp_mt8183,
+ .num_opp = ARRAY_SIZE(dvfsrc_opp_mt8183_lp4),
+ .regs = mt8183_regs,
+ .domains = dvfsrc_domains_mt8183,
+ .num_domains = ARRAY_SIZE(dvfsrc_domains_mt8183),
+ .get_target_level = mt8183_get_target_level,
+ .get_current_level = mt8183_get_current_level,
+ .set_dram_bw = mt8183_set_dram_bw,
+ .set_opp_level = mt8183_set_opp_level,
+ .wait_for_opp_level = mt8183_wait_for_opp_level,
+};
+
+static int mtk_dvfsrc_remove(struct platform_device *pdev)
+{
+ struct mtk_dvfsrc *dvfsrc = platform_get_drvdata(pdev);
+
+ clk_disable_unprepare(dvfsrc->clk_dvfsrc);
+
+ return 0;
+}
+
+static const struct of_device_id mtk_dvfsrc_of_match[] = {
+ {
+ .compatible = "mediatek,mt8183-dvfsrc",
+ .data = &mt8183_data,
+ }, {
+ /* sentinel */
+ },
+};
+
+static struct platform_driver mtk_dvfsrc_driver = {
+ .probe = mtk_dvfsrc_probe,
+ .remove = mtk_dvfsrc_remove,
+ .driver = {
+ .name = "mtk-dvfsrc",
+ .of_match_table = of_match_ptr(mtk_dvfsrc_of_match),
+ },
+};
+
+static int __init mtk_dvfsrc_init(void)
+{
+ return platform_driver_register(&mtk_dvfsrc_driver);
+}
+subsys_initcall(mtk_dvfsrc_init);
+
+static void __exit mtk_dvfsrc_exit(void)
+{
+ platform_driver_unregister(&mtk_dvfsrc_driver);
+}
+module_exit(mtk_dvfsrc_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MTK DVFSRC driver");
diff --git a/include/soc/mediatek/mtk_dvfsrc.h b/include/soc/mediatek/mtk_dvfsrc.h
new file mode 100644
index 0000000..e759a65
--- /dev/null
+++ b/include/soc/mediatek/mtk_dvfsrc.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+#ifndef __SOC_MTK_DVFSRC_H
+#define __SOC_MTK_DVFSRC_H
+
+#define MTK_DVFSRC_CMD_BW_REQUEST 0
+#define MTK_DVFSRC_CMD_OPP_REQUEST 1
+
+#if IS_ENABLED(CONFIG_MTK_DVFSRC)
+void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd, u64 data);
+
+#else
+
+static inline void mtk_dvfsrc_send_request(const struct device *dev, u32 cmd,
+ u64 data)
+{ return -ENODEV; }
+
+#endif /* CONFIG_MTK_DVFSRC */
+
+#endif
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V3 01/10] dt-bindings: soc: Add dvfsrc driver bindings
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Henry Chen,
Fan Chen, devicetree, linux-mediatek, linux-arm-kernel
In-Reply-To: <1566995328-15158-1-git-send-email-henryc.chen@mediatek.com>
Document the binding for enabling dvfsrc on MediaTek SoC.
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
.../devicetree/bindings/soc/mediatek/dvfsrc.txt | 23 ++++++++++++++++++++++
include/dt-bindings/soc/mtk,dvfsrc.h | 14 +++++++++++++
2 files changed, 37 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
create mode 100644 include/dt-bindings/soc/mtk,dvfsrc.h
diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
new file mode 100644
index 0000000..7f43499
--- /dev/null
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
@@ -0,0 +1,23 @@
+MediaTek DVFSRC
+
+The Dynamic Voltage and Frequency Scaling Resource Collector (DVFSRC) is a
+HW module which is used to collect all the requests from both software and
+hardware and turn into the decision of minimum operating voltage and minimum
+DRAM frequency to fulfill those requests.
+
+Required Properties:
+- compatible: Should be one of the following
+ - "mediatek,mt8183-dvfsrc": For MT8183 SoC
+- reg: Address range of the DVFSRC unit
+- clock-names: Must include the following entries:
+ "dvfsrc": DVFSRC module clock
+- clocks: Must contain an entry for each entry in clock-names.
+
+Example:
+
+ dvfsrc@10012000 {
+ compatible = "mediatek,mt8183-dvfsrc";
+ reg = <0 0x10012000 0 0x1000>;
+ clocks = <&infracfg CLK_INFRA_DVFSRC>;
+ clock-names = "dvfsrc";
+ };
diff --git a/include/dt-bindings/soc/mtk,dvfsrc.h b/include/dt-bindings/soc/mtk,dvfsrc.h
new file mode 100644
index 0000000..a522488
--- /dev/null
+++ b/include/dt-bindings/soc/mtk,dvfsrc.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+
+#ifndef _DT_BINDINGS_POWER_MTK_DVFSRC_H
+#define _DT_BINDINGS_POWER_MTK_DVFSRC_H
+
+#define MT8183_DVFSRC_LEVEL_1 1
+#define MT8183_DVFSRC_LEVEL_2 2
+#define MT8183_DVFSRC_LEVEL_3 3
+#define MT8183_DVFSRC_LEVEL_4 4
+
+#endif /* _DT_BINDINGS_POWER_MTK_DVFSRC_H */
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V3 05/10] soc: mediatek: add header for mediatek SIP interface
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Henry Chen,
Fan Chen, devicetree, linux-mediatek, linux-arm-kernel
In-Reply-To: <1566995328-15158-1-git-send-email-henryc.chen@mediatek.com>
Add a header to collect SIPs and add one SIP call to initialize power
management hardware for the SIP interface defined to access the SPM
handling vcore voltage and ddr rate changes on mt8183 (and most likely
later socs).
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
include/soc/mediatek/mtk_sip.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 include/soc/mediatek/mtk_sip.h
diff --git a/include/soc/mediatek/mtk_sip.h b/include/soc/mediatek/mtk_sip.h
new file mode 100644
index 0000000..945fc72
--- /dev/null
+++ b/include/soc/mediatek/mtk_sip.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+#ifndef __SOC_MTK_SIP_H
+#define __SOC_MTK_SIP_H
+
+#ifdef CONFIG_ARM64
+#define MTK_SIP_SMC_AARCH_BIT 0x40000000
+#else
+#define MTK_SIP_SMC_AARCH_BIT 0x00000000
+#endif
+
+#define MTK_SIP_SPM (0x82000506 | MTK_SIP_SMC_AARCH_BIT)
+#define MTK_SIP_SPM_DVFSRC_INIT 0x00
+
+#endif
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V3 10/10] arm64: dts: mt8183: Add interconnect provider DT nodes
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Henry Chen,
Fan Chen, devicetree, linux-mediatek, linux-arm-kernel
In-Reply-To: <1566995328-15158-1-git-send-email-henryc.chen@mediatek.com>
Add DDR EMI provider dictating dram interconnect bus performance
found on MT8183-based platforms
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 7512f84..a3af77d 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -11,6 +11,7 @@
#include <dt-bindings/power/mt8183-power.h>
#include "mt8183-pinfunc.h"
#include <dt-bindings/soc/mtk,dvfsrc.h>
+#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
/ {
compatible = "mediatek,mt8183";
@@ -148,6 +149,10 @@
reg = <0 0x10012000 0 0x1000>;
clocks = <&infracfg CLK_INFRA_DVFSRC>;
clock-names = "dvfsrc";
+ ddr_emi: interconnect {
+ compatible = "mediatek,mt8183-emi";
+ #interconnect-cells = <1>;
+ };
};
timer {
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V3 00/10] Add driver for dvfsrc, support for active state of scpsys
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Fan Chen,
devicetree, linux-mediatek, linux-arm-kernel
The patchsets add support for MediaTek hardware module named DVFSRC
(dynamic voltage and frequency scaling resource collector). The DVFSRC is
a HW module which is used to collect all the requests from both software
and hardware and turn into the decision of minimum operating voltage and
minimum DRAM frequency to fulfill those requests.
So, This series is to implement the dvfsrc driver to collect all the
requests of operating voltage or DRAM bandwidth from other device drivers
likes GPU/Camera through 2 frameworks basically:
1. interconnect framework: to aggregate the bandwidth
requirements from different clients
[1] https://patchwork.kernel.org/cover/10766329/
Below is the emi bandwidth map of mt8183. There has a hw module "DRAM scheduler"
which used to control the throughput. The DVFSRC will collect forecast data
of dram bandwidth from SW consumers(camera/gpu...), and according the forecast
to change the DRAM frequency
ICC provider ICC Nodes
---- ----
--------- |CPU | |--->|VPU |
----- | |-----> ---- | ----
|DRAM |--|DRAM | ---- | ----
| |--|scheduler|----->|GPU | |--->|DISP|
| |--|(EMI) | ---- | ----
| |--| | ----- | ----
----- | |----->|MMSYS|--|--->|VDEC|
--------- ----- | ----
/|\ | ----
|change DRAM freq |--->|VENC|
---------- | ----
| DVFSR | |
| | | ----
---------- |--->|IMG |
| ----
| ----
|--->|CAM |
----
2. Active state management of power domains[1]: to handle the operating
voltage opp requirement from different power domains
[2] https://lwn.net/Articles/744047/
Changes in RFC V3:
* Remove RFC from the subject prefix of the series
* Combine dt-binding patch and move interconnect dt-binding document into
dvfsrc. (Rob)
* Remove unused header, add unit descirption to the bandwidth, rename compatible
name on interconnect driver. (Georgi)
* Fixed some coding style: check flow, naming, used readx_poll_timeout
on dvfsrc driver. (Ryan)
* Rename interconnect driver mt8183.c to mtk-emi.c
* Rename interconnect header mtk,mt8183.h to mtk,emi.h
* mtk-scpsys.c: Add opp table check first to avoid OF runtime parse failed
Changes in RFC V2:
* Remove the DT property dram_type. (Rob)
* Used generic dts property 'opp-level' to get the performace state. (Stephen)
* Remove unecessary dependency config on Kconfig. (Stephen)
* Remove unused header file, fixed some coding style issue, typo,
error handling on dvfsrc driver. (Nicolas/Stephen)
* Remove irq handler on dvfsrc driver. (Stephen)
* Remove init table on dvfsrc driver, combine hw init on trustzone.
* Add interconnect support of mt8183 to aggregate the emi bandwidth.
(Georgi)
RFC V2: https://lore.kernel.org/patchwork/patch/1068113/
RFC V1: https://lore.kernel.org/patchwork/cover/1028535/
Henry Chen (10):
dt-bindings: soc: Add dvfsrc driver bindings
dt-bindings: soc: Add opp table on scpsys bindings
soc: mediatek: add support for the performance state
arm64: dts: mt8183: add performance state support of scpsys
soc: mediatek: add header for mediatek SIP interface
soc: mediatek: add MT8183 dvfsrc support
arm64: dts: mt8183: add dvfsrc related nodes
dt-bindings: interconnect: add MT8183 interconnect dt-bindings
interconnect: mediatek: Add mt8183 interconnect provider driver
arm64: dts: mt8183: Add interconnect provider DT nodes
.../devicetree/bindings/soc/mediatek/dvfsrc.txt | 32 ++
.../devicetree/bindings/soc/mediatek/scpsys.txt | 42 +++
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 33 ++
drivers/interconnect/Kconfig | 1 +
drivers/interconnect/Makefile | 1 +
drivers/interconnect/mediatek/Kconfig | 13 +
drivers/interconnect/mediatek/Makefile | 3 +
drivers/interconnect/mediatek/mtk-emi.c | 246 ++++++++++++++
drivers/soc/mediatek/Kconfig | 15 +
drivers/soc/mediatek/Makefile | 1 +
drivers/soc/mediatek/mtk-dvfsrc.c | 374 +++++++++++++++++++++
drivers/soc/mediatek/mtk-scpsys.c | 58 ++++
drivers/soc/mediatek/mtk-scpsys.h | 22 ++
include/dt-bindings/interconnect/mtk,mt8183-emi.h | 18 +
include/dt-bindings/soc/mtk,dvfsrc.h | 14 +
include/soc/mediatek/mtk_dvfsrc.h | 22 ++
include/soc/mediatek/mtk_sip.h | 17 +
17 files changed, 912 insertions(+)
create mode 100644 Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
create mode 100644 drivers/interconnect/mediatek/Kconfig
create mode 100644 drivers/interconnect/mediatek/Makefile
create mode 100644 drivers/interconnect/mediatek/mtk-emi.c
create mode 100644 drivers/soc/mediatek/mtk-dvfsrc.c
create mode 100644 drivers/soc/mediatek/mtk-scpsys.h
create mode 100644 include/dt-bindings/interconnect/mtk,mt8183-emi.h
create mode 100644 include/dt-bindings/soc/mtk,dvfsrc.h
create mode 100644 include/soc/mediatek/mtk_dvfsrc.h
create mode 100644 include/soc/mediatek/mtk_sip.h
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH V3 09/10] interconnect: mediatek: Add mt8183 interconnect provider driver
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Henry Chen,
Fan Chen, devicetree, linux-mediatek, linux-arm-kernel
In-Reply-To: <1566995328-15158-1-git-send-email-henryc.chen@mediatek.com>
Introduce Mediatek MT8183 specific provider driver using the
interconnect framework.
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
drivers/interconnect/Kconfig | 1 +
drivers/interconnect/Makefile | 1 +
drivers/interconnect/mediatek/Kconfig | 13 ++
drivers/interconnect/mediatek/Makefile | 3 +
drivers/interconnect/mediatek/mtk-emi.c | 246 ++++++++++++++++++++++++++++++++
5 files changed, 264 insertions(+)
create mode 100644 drivers/interconnect/mediatek/Kconfig
create mode 100644 drivers/interconnect/mediatek/Makefile
create mode 100644 drivers/interconnect/mediatek/mtk-emi.c
diff --git a/drivers/interconnect/Kconfig b/drivers/interconnect/Kconfig
index bfa4ca3..dd9ecb6 100644
--- a/drivers/interconnect/Kconfig
+++ b/drivers/interconnect/Kconfig
@@ -12,5 +12,6 @@ menuconfig INTERCONNECT
if INTERCONNECT
source "drivers/interconnect/qcom/Kconfig"
+source "drivers/interconnect/mediatek/Kconfig"
endif
diff --git a/drivers/interconnect/Makefile b/drivers/interconnect/Makefile
index 28f2ab0..253f24a3 100644
--- a/drivers/interconnect/Makefile
+++ b/drivers/interconnect/Makefile
@@ -4,3 +4,4 @@ icc-core-objs := core.o
obj-$(CONFIG_INTERCONNECT) += icc-core.o
obj-$(CONFIG_INTERCONNECT_QCOM) += qcom/
+obj-$(CONFIG_INTERCONNECT_MTK) += mediatek/
diff --git a/drivers/interconnect/mediatek/Kconfig b/drivers/interconnect/mediatek/Kconfig
new file mode 100644
index 0000000..972d3bb
--- /dev/null
+++ b/drivers/interconnect/mediatek/Kconfig
@@ -0,0 +1,13 @@
+config INTERCONNECT_MTK
+ bool "Mediatek Network-on-Chip interconnect drivers"
+ depends on ARCH_MEDIATEK
+ help
+ Support for Mediatek's Network-on-Chip interconnect hardware.
+
+config INTERCONNECT_MTK_EMI
+ tristate "Mediatek EMI interconnect driver"
+ depends on INTERCONNECT_MTK
+ depends on (MTK_DVFSRC && OF)
+ help
+ This is a driver for the Mediatek Network-on-Chip on DVFSRC-based
+ platforms.
diff --git a/drivers/interconnect/mediatek/Makefile b/drivers/interconnect/mediatek/Makefile
new file mode 100644
index 0000000..353842b
--- /dev/null
+++ b/drivers/interconnect/mediatek/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_INTERCONNECT_MTK_EMI) += mtk-emi.o
\ No newline at end of file
diff --git a/drivers/interconnect/mediatek/mtk-emi.c b/drivers/interconnect/mediatek/mtk-emi.c
new file mode 100644
index 0000000..22d2777
--- /dev/null
+++ b/drivers/interconnect/mediatek/mtk-emi.c
@@ -0,0 +1,246 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ *
+ */
+
+#include <dt-bindings/interconnect/mtk,mt8183-emi.h>
+#include <linux/device.h>
+#include <linux/interconnect-provider.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <soc/mediatek/mtk_dvfsrc.h>
+
+enum mtk_icc_name {
+ SLAVE_DDR_EMI,
+ MASTER_MCUSYS,
+ MASTER_GPUSYS,
+ MASTER_MMSYS,
+ MASTER_MM_VPU,
+ MASTER_MM_DISP,
+ MASTER_MM_VDEC,
+ MASTER_MM_VENC,
+ MASTER_MM_CAM,
+ MASTER_MM_IMG,
+ MASTER_MM_MDP,
+};
+
+#define MT8183_MAX_LINKS 6
+
+/**
+ * struct mtk_icc_node - Mediatek specific interconnect nodes
+ * @name: the node name used in debugfs
+ * @ep: true if the node is an end point.
+ * @id: a unique node identifier
+ * @links: an array of nodes where we can go next while traversing
+ * @num_links: the total number of @links
+ * @buswidth: width of the interconnect between a node and the bus
+ * @sum_avg: current sum aggregate value of all avg bw kBps requests
+ * @max_peak: current max aggregate value of all peak bw kBps requests
+ */
+struct mtk_icc_node {
+ unsigned char *name;
+ bool ep;
+ u16 id;
+ u16 links[MT8183_MAX_LINKS];
+ u16 num_links;
+ u16 buswidth;
+ u64 sum_avg;
+ u64 max_peak;
+};
+
+struct mtk_icc_desc {
+ struct mtk_icc_node **nodes;
+ size_t num_nodes;
+};
+
+#define DEFINE_MNODE(_name, _id, _buswidth, _ep, ...) \
+ static struct mtk_icc_node _name = { \
+ .name = #_name, \
+ .id = _id, \
+ .buswidth = _buswidth, \
+ .ep = _ep, \
+ .num_links = ARRAY_SIZE(((int[]){ __VA_ARGS__ })), \
+}
+
+DEFINE_MNODE(ddr_emi, SLAVE_DDR_EMI, 1024, 1, 0);
+DEFINE_MNODE(mcusys, MASTER_MCUSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(gpu, MASTER_GPUSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mmsys, MASTER_MMSYS, 256, 0, SLAVE_DDR_EMI);
+DEFINE_MNODE(mm_vpu, MASTER_MM_VPU, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_disp, MASTER_MM_DISP, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_vdec, MASTER_MM_VDEC, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_venc, MASTER_MM_VENC, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_cam, MASTER_MM_CAM, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_img, MASTER_MM_IMG, 128, 0, MASTER_MMSYS);
+DEFINE_MNODE(mm_mdp, MASTER_MM_MDP, 128, 0, MASTER_MMSYS);
+
+static struct mtk_icc_node *mt8183_icc_nodes[] = {
+ [MT8183_SLAVE_DDR_EMI] = &ddr_emi,
+ [MT8183_MASTER_MCUSYS] = &mcusys,
+ [MT8183_MASTER_GPU] = &gpu,
+ [MT8183_MASTER_MMSYS] = &mmsys,
+ [MT8183_MASTER_MM_VPU] = &mm_vpu,
+ [MT8183_MASTER_MM_DISP] = &mm_disp,
+ [MT8183_MASTER_MM_VDEC] = &mm_vdec,
+ [MT8183_MASTER_MM_VENC] = &mm_venc,
+ [MT8183_MASTER_MM_CAM] = &mm_cam,
+ [MT8183_MASTER_MM_IMG] = &mm_img,
+ [MT8183_MASTER_MM_MDP] = &mm_mdp,
+};
+
+static struct mtk_icc_desc mt8183_icc = {
+ .nodes = mt8183_icc_nodes,
+ .num_nodes = ARRAY_SIZE(mt8183_icc_nodes),
+};
+
+static int emi_icc_aggregate(struct icc_node *node, u32 avg_bw,
+ u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
+{
+ struct mtk_icc_node *in;
+
+ in = node->data;
+
+ *agg_avg += avg_bw;
+ *agg_peak += peak_bw;
+
+ in->sum_avg = *agg_avg;
+ in->max_peak = *agg_peak;
+
+ return 0;
+}
+
+static int emi_icc_set(struct icc_node *src, struct icc_node *dst)
+{
+ int ret = 0;
+ struct mtk_icc_node *node;
+
+ node = dst->data;
+ if (node->ep) {
+ pr_debug("sum_avg (%llu), max_peak (%llu)\n",
+ node->sum_avg, node->max_peak);
+ mtk_dvfsrc_send_request(src->provider->dev->parent,
+ MTK_DVFSRC_CMD_BW_REQUEST,
+ node->max_peak);
+ }
+
+ return ret;
+}
+
+static int emi_icc_probe(struct platform_device *pdev)
+{
+ int ret;
+ const struct mtk_icc_desc *desc;
+ struct icc_node *node;
+ struct icc_onecell_data *data;
+ struct icc_provider *provider;
+ struct mtk_icc_node **mnodes;
+ size_t num_nodes, i, j;
+
+ desc = of_device_get_match_data(&pdev->dev);
+ if (!desc)
+ return -EINVAL;
+
+ mnodes = desc->nodes;
+ num_nodes = desc->num_nodes;
+
+ provider = devm_kzalloc(&pdev->dev, sizeof(*provider), GFP_KERNEL);
+ if (!provider)
+ return -ENOMEM;
+
+ data = devm_kcalloc(&pdev->dev, num_nodes, sizeof(*node), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ provider->dev = &pdev->dev;
+ provider->set = emi_icc_set;
+ provider->aggregate = emi_icc_aggregate;
+ provider->xlate = of_icc_xlate_onecell;
+ INIT_LIST_HEAD(&provider->nodes);
+ provider->data = data;
+
+ ret = icc_provider_add(provider);
+ if (ret) {
+ dev_err(&pdev->dev, "error adding interconnect provider\n");
+ return ret;
+ }
+
+ for (i = 0; i < num_nodes; i++) {
+ node = icc_node_create(mnodes[i]->id);
+ if (IS_ERR(node)) {
+ ret = PTR_ERR(node);
+ goto err;
+ }
+
+ node->name = mnodes[i]->name;
+ node->data = mnodes[i];
+ icc_node_add(node, provider);
+
+ dev_dbg(&pdev->dev, "registered node %s, num link: %d\n",
+ mnodes[i]->name, mnodes[i]->num_links);
+
+ /* populate links */
+ for (j = 0; j < mnodes[i]->num_links; j++)
+ icc_link_create(node, mnodes[i]->links[j]);
+
+ data->nodes[i] = node;
+ }
+ data->num_nodes = num_nodes;
+
+ platform_set_drvdata(pdev, provider);
+
+ return 0;
+err:
+ list_for_each_entry(node, &provider->nodes, node_list) {
+ icc_node_del(node);
+ icc_node_destroy(node->id);
+ }
+
+ icc_provider_del(provider);
+ return ret;
+}
+
+static int emi_icc_remove(struct platform_device *pdev)
+{
+ struct icc_provider *provider = platform_get_drvdata(pdev);
+ struct icc_node *n;
+
+ list_for_each_entry(n, &provider->nodes, node_list) {
+ icc_node_del(n);
+ icc_node_destroy(n->id);
+ }
+
+ return icc_provider_del(provider);
+}
+
+static const struct of_device_id emi_icc_of_match[] = {
+ { .compatible = "mediatek,mt8183-emi", .data = &mt8183_icc },
+ { },
+};
+MODULE_DEVICE_TABLE(of, emi_icc_of_match);
+
+static struct platform_driver emi_icc_driver = {
+ .probe = emi_icc_probe,
+ .remove = emi_icc_remove,
+ .driver = {
+ .name = "mediatek-emi-icc",
+ .of_match_table = emi_icc_of_match,
+ },
+};
+
+static int __init mtk_emi_icc_init(void)
+{
+ return platform_driver_register(&emi_icc_driver);
+}
+subsys_initcall(mtk_emi_icc_init);
+
+static void __exit mtk_emi_icc_exit(void)
+{
+ platform_driver_unregister(&emi_icc_driver);
+}
+module_exit(mtk_emi_icc_exit);
+
+MODULE_AUTHOR("Henry Chen <henryc.chen@mediatek.com>");
+MODULE_LICENSE("GPL v2");
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V3 02/10] dt-bindings: soc: Add opp table on scpsys bindings
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Henry Chen,
Fan Chen, devicetree, linux-mediatek, linux-arm-kernel
In-Reply-To: <1566995328-15158-1-git-send-email-henryc.chen@mediatek.com>
Add opp table on scpsys dt-bindings for Mediatek SoC.
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
.../devicetree/bindings/soc/mediatek/scpsys.txt | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
index 00eab7e..134430a 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
@@ -64,6 +64,10 @@ Optional properties:
- mfg_2d-supply: Power supply for the mfg_2d power domain
- mfg-supply: Power supply for the mfg power domain
+- operating-points-v2: Phandle to the OPP table for the Power domain.
+ Refer to Documentation/devicetree/bindings/power/power_domain.txt
+ and Documentation/devicetree/bindings/opp/opp.txt for more details
+
Example:
scpsys: scpsys@10006000 {
@@ -76,6 +80,27 @@ Example:
<&topckgen CLK_TOP_VENC_SEL>,
<&topckgen CLK_TOP_VENC_LT_SEL>;
clock-names = "mfg", "mm", "venc", "venc_lt";
+ operating-points-v2 = <&dvfsrc_opp_table>;
+
+ dvfsrc_opp_table: opp-table {
+ compatible = "operating-points-v2-level";
+
+ dvfsrc_vol_min: opp1 {
+ opp,level = <MT8183_DVFSRC_LEVEL_1>;
+ };
+
+ dvfsrc_freq_medium: opp2 {
+ opp,level = <MT8183_DVFSRC_LEVEL_2>;
+ };
+
+ dvfsrc_freq_max: opp3 {
+ opp,level = <MT8183_DVFSRC_LEVEL_3>;
+ };
+
+ dvfsrc_vol_max: opp4 {
+ opp,level = <MT8183_DVFSRC_LEVEL_4>;
+ };
+ };
};
Example consumer:
@@ -83,4 +108,21 @@ Example consumer:
afe: mt8173-afe-pcm@11220000 {
compatible = "mediatek,mt8173-afe-pcm";
power-domains = <&scpsys MT8173_POWER_DOMAIN_AUDIO>;
+ operating-points-v2 = <&aud_opp_table>;
+ };
+
+ aud_opp_table: aud-opp-table {
+ compatible = "operating-points-v2";
+ opp1 {
+ opp-hz = /bits/ 64 <793000000>;
+ required-opps = <&dvfsrc_vol_min>;
+ };
+ opp2 {
+ opp-hz = /bits/ 64 <910000000>;
+ required-opps = <&dvfsrc_vol_max>;
+ };
+ opp3 {
+ opp-hz = /bits/ 64 <1014000000>;
+ required-opps = <&dvfsrc_vol_max>;
+ };
};
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V3 03/10] soc: mediatek: add support for the performance state
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Henry Chen,
Fan Chen, devicetree, linux-mediatek, linux-arm-kernel
In-Reply-To: <1566995328-15158-1-git-send-email-henryc.chen@mediatek.com>
Support power domain performance state, add header file for scp event.
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
drivers/soc/mediatek/mtk-scpsys.c | 58 +++++++++++++++++++++++++++++++++++++++
drivers/soc/mediatek/mtk-scpsys.h | 22 +++++++++++++++
2 files changed, 80 insertions(+)
create mode 100644 drivers/soc/mediatek/mtk-scpsys.h
diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c
index e072810..50bc254 100644
--- a/drivers/soc/mediatek/mtk-scpsys.c
+++ b/drivers/soc/mediatek/mtk-scpsys.c
@@ -10,7 +10,9 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
+#include <linux/pm_opp.h>
#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
#include <linux/soc/mediatek/infracfg.h>
#include <linux/soc/mediatek/scpsys-ext.h>
@@ -21,6 +23,7 @@
#include <dt-bindings/power/mt7623a-power.h>
#include <dt-bindings/power/mt8173-power.h>
#include <dt-bindings/power/mt8183-power.h>
+#include "mtk-scpsys.h"
#define MTK_POLL_DELAY_US 10
#define MTK_POLL_TIMEOUT USEC_PER_SEC
@@ -187,6 +190,18 @@ struct scp_soc_data {
bool bus_prot_reg_update;
};
+static BLOCKING_NOTIFIER_HEAD(scpsys_notifier_list);
+
+int register_scpsys_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&scpsys_notifier_list, nb);
+}
+
+int unregister_scpsys_notifier(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&scpsys_notifier_list, nb);
+}
+
static int scpsys_domain_is_on(struct scp_domain *scpd)
{
struct scp *scp = scpd->scp;
@@ -505,6 +520,41 @@ static void init_clks(struct platform_device *pdev, struct clk **clk)
clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
}
+static int mtk_pd_set_performance(struct generic_pm_domain *genpd,
+ unsigned int state)
+{
+ int i;
+ struct scp_domain *scpd =
+ container_of(genpd, struct scp_domain, genpd);
+ struct scp_event_data scpe;
+ struct scp *scp = scpd->scp;
+ struct genpd_onecell_data *pd_data = &scp->pd_data;
+
+ for (i = 0; i < pd_data->num_domains; i++) {
+ if (genpd == pd_data->domains[i]) {
+ dev_dbg(scp->dev, "%d. %s = %d\n",
+ i, genpd->name, state);
+ break;
+ }
+ }
+
+ if (i == pd_data->num_domains)
+ return 0;
+
+ scpe.event_type = MTK_SCPSYS_PSTATE;
+ scpe.genpd = genpd;
+ scpe.domain_id = i;
+ blocking_notifier_call_chain(&scpsys_notifier_list, state, &scpe);
+
+ return 0;
+}
+
+static unsigned int mtk_pd_get_performance(struct generic_pm_domain *genpd,
+ struct dev_pm_opp *opp)
+{
+ return dev_pm_opp_get_level(opp);
+}
+
static struct scp *init_scp(struct platform_device *pdev,
const struct scp_domain_data *scp_domain_data, int num,
const struct scp_ctrl_reg *scp_ctrl_reg,
@@ -630,6 +680,14 @@ static struct scp *init_scp(struct platform_device *pdev,
genpd->power_on = scpsys_power_on;
if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
+
+ /* Add opp table check first to avoid OF runtime parse failed */
+ if (of_count_phandle_with_args(pdev->dev.of_node,
+ "operating-points-v2", NULL) > 0) {
+ genpd->set_performance_state = mtk_pd_set_performance;
+ genpd->opp_to_performance_state =
+ mtk_pd_get_performance;
+ }
}
return scp;
diff --git a/drivers/soc/mediatek/mtk-scpsys.h b/drivers/soc/mediatek/mtk-scpsys.h
new file mode 100644
index 0000000..c1e8325
--- /dev/null
+++ b/drivers/soc/mediatek/mtk-scpsys.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ */
+
+#ifndef __MTK_SCPSYS_H__
+#define __MTK_SCPSYS_H__
+
+struct scp_event_data {
+ int event_type;
+ int domain_id;
+ struct generic_pm_domain *genpd;
+};
+
+enum scp_event_type {
+ MTK_SCPSYS_PSTATE,
+};
+
+int register_scpsys_notifier(struct notifier_block *nb);
+int unregister_scpsys_notifier(struct notifier_block *nb);
+
+#endif /* __MTK_SCPSYS_H__ */
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V3 04/10] arm64: dts: mt8183: add performance state support of scpsys
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Henry Chen,
Fan Chen, devicetree, linux-mediatek, linux-arm-kernel
In-Reply-To: <1566995328-15158-1-git-send-email-henryc.chen@mediatek.com>
Add support for performance state of scpsys on mt8183 platform.
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index 66aaa07..a58999f 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -10,6 +10,7 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/power/mt8183-power.h>
#include "mt8183-pinfunc.h"
+#include <dt-bindings/soc/mtk,dvfsrc.h>
/ {
compatible = "mediatek,mt8183";
@@ -293,6 +294,26 @@
"vpu-3", "vpu-4", "vpu-5";
infracfg = <&infracfg>;
smi_comm = <&smi_common>;
+ operating-points-v2 = <&dvfsrc_opp_table>;
+ dvfsrc_opp_table: opp-table {
+ compatible = "operating-points-v2-level";
+
+ dvfsrc_vol_min: opp1 {
+ opp,level = <MT8183_DVFSRC_LEVEL_1>;
+ };
+
+ dvfsrc_freq_medium: opp2 {
+ opp,level = <MT8183_DVFSRC_LEVEL_2>;
+ };
+
+ dvfsrc_freq_max: opp3 {
+ opp,level = <MT8183_DVFSRC_LEVEL_3>;
+ };
+
+ dvfsrc_vol_max: opp4 {
+ opp,level = <MT8183_DVFSRC_LEVEL_4>;
+ };
+ };
};
apmixedsys: syscon@1000c000 {
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V3 08/10] dt-bindings: interconnect: add MT8183 interconnect dt-bindings
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Henry Chen,
Fan Chen, devicetree, linux-mediatek, linux-arm-kernel
In-Reply-To: <1566995328-15158-1-git-send-email-henryc.chen@mediatek.com>
Add interconnect provider dt-bindings for MT8183.
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
.../devicetree/bindings/soc/mediatek/dvfsrc.txt | 9 +++++++++
include/dt-bindings/interconnect/mtk,mt8183-emi.h | 18 ++++++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 include/dt-bindings/interconnect/mtk,mt8183-emi.h
diff --git a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
index 7f43499..da98ec9 100644
--- a/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
+++ b/Documentation/devicetree/bindings/soc/mediatek/dvfsrc.txt
@@ -12,6 +12,11 @@ Required Properties:
- clock-names: Must include the following entries:
"dvfsrc": DVFSRC module clock
- clocks: Must contain an entry for each entry in clock-names.
+- #interconnect-cells : should contain 1
+- interconnect : interconnect providers support dram bandwidth requirements.
+ The provider is able to communicate with the DVFSRC and send the dram
+ bandwidth to it. shall contain only one of the following:
+ "mediatek,mt8183-emi"
Example:
@@ -20,4 +25,8 @@ Example:
reg = <0 0x10012000 0 0x1000>;
clocks = <&infracfg CLK_INFRA_DVFSRC>;
clock-names = "dvfsrc";
+ ddr_emi: interconnect {
+ compatible = "mediatek,mt8183-emi";
+ #interconnect-cells = <1>;
+ };
};
diff --git a/include/dt-bindings/interconnect/mtk,mt8183-emi.h b/include/dt-bindings/interconnect/mtk,mt8183-emi.h
new file mode 100644
index 0000000..2a54856
--- /dev/null
+++ b/include/dt-bindings/interconnect/mtk,mt8183-emi.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_MTK_MT8183_EMI_H
+#define __DT_BINDINGS_INTERCONNECT_MTK_MT8183_EMI_H
+
+#define MT8183_SLAVE_DDR_EMI 0
+#define MT8183_MASTER_MCUSYS 1
+#define MT8183_MASTER_GPU 2
+#define MT8183_MASTER_MMSYS 3
+#define MT8183_MASTER_MM_VPU 4
+#define MT8183_MASTER_MM_DISP 5
+#define MT8183_MASTER_MM_VDEC 6
+#define MT8183_MASTER_MM_VENC 7
+#define MT8183_MASTER_MM_CAM 8
+#define MT8183_MASTER_MM_IMG 9
+#define MT8183_MASTER_MM_MDP 10
+
+#endif
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V3 07/10] arm64: dts: mt8183: add dvfsrc related nodes
From: Henry Chen @ 2019-08-28 12:28 UTC (permalink / raw)
To: Georgi Djakov, Rob Herring, Matthias Brugger, Viresh Kumar,
Stephen Boyd, Ryan Case
Cc: James Liao, Weiyi Lu, Nicolas Boichat, linux-kernel, Henry Chen,
Fan Chen, devicetree, linux-mediatek, linux-arm-kernel
In-Reply-To: <1566995328-15158-1-git-send-email-henryc.chen@mediatek.com>
Enable dvfsrc on mt8183 platform.
Signed-off-by: Henry Chen <henryc.chen@mediatek.com>
---
arch/arm64/boot/dts/mediatek/mt8183.dtsi | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8183.dtsi b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
index a58999f..7512f84 100644
--- a/arch/arm64/boot/dts/mediatek/mt8183.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8183.dtsi
@@ -143,6 +143,13 @@
clock-output-names = "clk26m";
};
+ dvfsrc@10012000 {
+ compatible = "mediatek,mt8183-dvfsrc";
+ reg = <0 0x10012000 0 0x1000>;
+ clocks = <&infracfg CLK_INFRA_DVFSRC>;
+ clock-names = "dvfsrc";
+ };
+
timer {
compatible = "arm,armv8-timer";
interrupt-parent = <&gic>;
--
1.9.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH v2 2/2] dma-contiguous: Use fallback alloc_pages for single pages
From: Masahiro Yamada @ 2019-08-28 12:23 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Ulf Hansson, Tony Lindgren, Catalin Marinas, Will Deacon,
Linux Kernel Mailing List, Max Filippov, Marek Szyprowski,
Stephen Rothwell, Joerg Roedel, Russell King, Thierry Reding,
linux-xtensa, Kees Cook, Nicolin Chen, Andrew Morton,
linux-arm-kernel, Chris Zankel, Wolfram Sang, David Woodhouse,
linux-mmc, Adrian Hunter, iommu, iamjoonsoo.kim, Robin Murphy
In-Reply-To: <CAK7LNAQ_nQcBt=xH1-h+=co85mTxFgbe+_46Gu4LaNsDSm+kYA@mail.gmail.com>
On Wed, Aug 28, 2019 at 7:53 PM Masahiro Yamada
<yamada.masahiro@socionext.com> wrote:
>
> Hi Christoph,
>
> On Tue, Aug 27, 2019 at 8:55 PM Christoph Hellwig <hch@lst.de> wrote:
> >
> > On Tue, Aug 27, 2019 at 06:03:14PM +0900, Masahiro Yamada wrote:
> > > Yes, this makes my driver working again
> > > when CONFIG_DMA_CMA=y.
> > >
> > >
> > > If I apply the following, my driver gets back working
> > > irrespective of CONFIG_DMA_CMA.
> >
> > That sounds a lot like the device simply isn't 64-bit DMA capable, and
> > previously always got CMA allocations under the limit it actually
> > supported. I suggest that you submit this quirk to the mmc maintainers.
>
>
> I tested v5.2 and my MMC host controller works with
> dma_address that exceeds 32-bit physical address.
>
> So, I believe my MMC device is 64-bit DMA capable.
>
> I am still looking into the code
> to find out what was changed.
I retract this comment.
Prior to bd2e75633c8012fc8a7431c82fda66237133bf7e,
the descriptor table for ADMA is placed within the
32-bit phys address range, not exceeds the 32-bit limit.
Probably, my device is not 64-bit capable.
I will talk to the hardware engineer,
and check the hardware spec just in case.
Thanks.
--
Best Regards
Masahiro Yamada
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH 3/8] coresight: etm4x: Add missing API to set EL match on address filters
From: Mike Leach @ 2019-08-28 12:10 UTC (permalink / raw)
To: Leo Yan; +Cc: Coresight ML, linux-arm-kernel, Mathieu Poirier
In-Reply-To: <20190828025313.GC26133@leoy-ThinkPad-X240s>
Hi Leo,
On Wed, 28 Aug 2019 at 03:53, Leo Yan <leo.yan@linaro.org> wrote:
>
> On Mon, Aug 19, 2019 at 09:57:15PM +0100, Mike Leach wrote:
> > TRCACATRn registers have match bits for secure and non-secure exception
> > levels which are not accessible by the sysfs API.
> > This adds a new sysfs parameter to enable this - addr_exlevel_s_ns.
> >
> > Signed-off-by: Mike Leach <mike.leach@linaro.org>
> > ---
> > .../coresight/coresight-etm4x-sysfs.c | 39 +++++++++++++++++++
> > 1 file changed, 39 insertions(+)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> > index fa1d6a938f6c..7eab5d7d0b62 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> > @@ -1233,6 +1233,44 @@ static ssize_t addr_context_store(struct device *dev,
> > }
> > static DEVICE_ATTR_RW(addr_context);
> >
> > +static ssize_t addr_exlevel_s_ns_show(struct device *dev,
> > + struct device_attribute *attr,
> > + char *buf)
> > +{
> > + u8 idx;
> > + unsigned long val;
> > + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
> > + struct etmv4_config *config = &drvdata->config;
> > +
> > + spin_lock(&drvdata->spinlock);
> > + idx = config->addr_idx;
> > + val = BMVAL(config->addr_acc[idx], 14, 8);
> > + spin_unlock(&drvdata->spinlock);
> > + return scnprintf(buf, PAGE_SIZE, "%#lx\n", val);
> > +}
> > +
> > +static ssize_t addr_exlevel_s_ns_store(struct device *dev,
> > + struct device_attribute *attr,
> > + const char *buf, size_t size)
> > +{
> > + u8 idx;
> > + unsigned long val;
> > + struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
> > + struct etmv4_config *config = &drvdata->config;
> > +
> > + if (kstrtoul(buf, 16, &val))
> > + return -EINVAL;
> > +
> > + spin_lock(&drvdata->spinlock);
> > + idx = config->addr_idx;
> > + /* clear Exlevel_ns & Exlevel_s bits[14:12, 11:8] */
> > + config->addr_acc[idx] &= ~(GENMASK(14, 8));
> > + config->addr_acc[idx] |= (val << 8);
>
> I think it needs to check if 'val' is out of bound, which only can have
> value which is less than 7 bits (finally set for bit 8 to bit 14).
>
Agreed.
> Just curious, if the CPU runs in non-secure mode (e.g. NS-EL1 in
> kernel mode), does it have permission to access EXLEVEL_S field? I
> don't see the spec give info for this.
>
This field can be accessed in NS mode - the permissions for tracing
secure state are given in the authentication signals - this register
only controls matching in particular states.
If there is no permission to trace secure state, then the EXLEVEL_S
field will have no effect as trace will automatically be disabled
should the PE transit to secure state.
Thanks
Mike
> Thanks,
> Leo Yan
>
> > + spin_unlock(&drvdata->spinlock);
> > + return size;
> > +}
> > +static DEVICE_ATTR_RW(addr_exlevel_s_ns);
> > +
> > static ssize_t seq_idx_show(struct device *dev,
> > struct device_attribute *attr,
> > char *buf)
> > @@ -2038,6 +2076,7 @@ static struct attribute *coresight_etmv4_attrs[] = {
> > &dev_attr_addr_stop.attr,
> > &dev_attr_addr_ctxtype.attr,
> > &dev_attr_addr_context.attr,
> > + &dev_attr_addr_exlevel_s_ns.attr,
> > &dev_attr_seq_idx.attr,
> > &dev_attr_seq_state.attr,
> > &dev_attr_seq_event.attr,
> > --
> > 2.17.1
> >
> > _______________________________________________
> > CoreSight mailing list
> > CoreSight@lists.linaro.org
> > https://lists.linaro.org/mailman/listinfo/coresight
--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v3 0/2] Exynos SoCs: enable support for ARM Architected Timers
From: Marek Szyprowski @ 2019-08-28 12:10 UTC (permalink / raw)
To: linux-samsung-soc, linux-arm-kernel
Cc: Chanwoo Choi, Bartlomiej Zolnierkiewicz, Marc Zyngier,
Krzysztof Kozlowski, Marek Szyprowski
In-Reply-To: <CGME20190828121011eucas1p1ff9b23536aaa79643e5fca10c02db9a0@eucas1p1.samsung.com>
Dear All,
ARM Architected Timers are present in all CortexA7/A15 based Samsung
Exynos SoCs. So far they were not enabled, because there were some issues
related to their initialization. Samsung Exynos SoCs used custom timer
hardware - Exynos MultiCore Timer. It turned out that enabling MCT it is
also needed to get ARM Architected Timers working, because they both
share some common hardware blocks (global system counter).
This patchset enables support for ARM Architected Timer driver together
with a standard Exynos MultiCore Timer driver, which is kept as a default
timer source on ARM 32bit platforms. Support for ARM architected timers
is essential for enabling proper KVM support on those platforms.
Best regards
Marek Szyprowski
Samsung R&D Institute Poland
Changelog:
v3:
- checked the status of arch timer registers on all Exynos5 SoCs,
dropped 'not-fw-configured' property on most of them as requested
by Marc Zyngier
- dropped enabling arch timers on Exynos3250, as there is no benefit from
that (none of the Exynos3250-based board boots in HYP mode)
v2: https://www.spinics.net/lists/arm-kernel/msg751017.html
- dropped MCT patches (merged to v5.1)
- dropped timer priority change patch (merged to v5.3)
v1: https://www.spinics.net/lists/arm-kernel/msg751018.html
- initial version, covers some MCT patches previously sent as a timer
rework for Exynos5433
Patch summary:
Marek Szyprowski (2):
ARM: dts: exynos: Add support ARM architected timers on Exynos5
ARM: exynos: Enable support for ARM architected timers
arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 ++++
arch/arm/boot/dts/exynos54xx.dtsi | 9 +++++++++
arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 ++++
arch/arm/mach-exynos/Kconfig | 1 +
4 files changed, 18 insertions(+)
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH v3 2/2] ARM: exynos: Enable support for ARM architected timers
From: Marek Szyprowski @ 2019-08-28 12:10 UTC (permalink / raw)
To: linux-samsung-soc, linux-arm-kernel
Cc: Chanwoo Choi, Bartlomiej Zolnierkiewicz, Marc Zyngier,
Krzysztof Kozlowski, Marek Szyprowski
In-Reply-To: <20190828121005.29368-1-m.szyprowski@samsung.com>
ARM architected timer can be used together with Exynos MultiCore Timer
driver, so enable support for it. Support for ARM architected timers is
essential for enabling proper KVM support.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
arch/arm/mach-exynos/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index f83786640f94..9dab1f50a02f 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -19,6 +19,7 @@ menuconfig ARCH_EXYNOS
select EXYNOS_SROM
select EXYNOS_PM_DOMAINS if PM_GENERIC_DOMAINS
select GPIOLIB
+ select HAVE_ARM_ARCH_TIMER if ARCH_EXYNOS5 && VIRTUALIZATION
select HAVE_ARM_SCU if SMP
select HAVE_S3C2410_I2C if I2C
select HAVE_S3C2410_WATCHDOG if WATCHDOG
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH v3 1/2] ARM: dts: exynos: Add support ARM architected timers on Exynos5
From: Marek Szyprowski @ 2019-08-28 12:10 UTC (permalink / raw)
To: linux-samsung-soc, linux-arm-kernel
Cc: Chanwoo Choi, Bartlomiej Zolnierkiewicz, Marc Zyngier,
Krzysztof Kozlowski, Marek Szyprowski
In-Reply-To: <20190828121005.29368-1-m.szyprowski@samsung.com>
All CortexA7/A15 based Exynos5 SoCs have ARM architected timers, so enable
support for them directly in the base dtsi. None of the known firmware
properly configures CNTFRQ arch timer register, so force clock frequency
to 24MHz, which is the only configuration supported by the remaining
clock drivers so far.
Stock firmware for Peach Pit and Pi Chromebooks also doesn't reset
properly other arch timer registers, so add respective properties
indicating that. Other Exynos5-based boards behaves correctly in this area,
what finally allows to enable support for KVM-based virtualization.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
arch/arm/boot/dts/exynos5420-peach-pit.dts | 4 ++++
arch/arm/boot/dts/exynos54xx.dtsi | 9 +++++++++
arch/arm/boot/dts/exynos5800-peach-pi.dts | 4 ++++
3 files changed, 17 insertions(+)
diff --git a/arch/arm/boot/dts/exynos5420-peach-pit.dts b/arch/arm/boot/dts/exynos5420-peach-pit.dts
index f78db6809cca..77e08a4c7300 100644
--- a/arch/arm/boot/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/boot/dts/exynos5420-peach-pit.dts
@@ -1064,6 +1064,10 @@
status = "okay";
};
+&timer {
+ arm,cpu-registers-not-fw-configured;
+};
+
&tmu_cpu0 {
vtmu-supply = <&ldo10_reg>;
};
diff --git a/arch/arm/boot/dts/exynos54xx.dtsi b/arch/arm/boot/dts/exynos54xx.dtsi
index 9c3b63b7cac6..02d34957cd83 100644
--- a/arch/arm/boot/dts/exynos54xx.dtsi
+++ b/arch/arm/boot/dts/exynos54xx.dtsi
@@ -45,6 +45,15 @@
status = "disabled";
};
+ timer: timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>;
+ clock-frequency = <24000000>;
+ };
+
soc: soc {
sysram@2020000 {
compatible = "mmio-sram";
diff --git a/arch/arm/boot/dts/exynos5800-peach-pi.dts b/arch/arm/boot/dts/exynos5800-peach-pi.dts
index e0f470fe54c8..5e8cec736444 100644
--- a/arch/arm/boot/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/boot/dts/exynos5800-peach-pi.dts
@@ -1033,6 +1033,10 @@
status = "okay";
};
+&timer {
+ arm,cpu-registers-not-fw-configured;
+};
+
&tmu_cpu0 {
vtmu-supply = <&ldo10_reg>;
};
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* Re: [PATCH] arm/arm64: defconfig: Update configs to use the new CROS_EC options
From: Arnd Bergmann @ 2019-08-28 12:09 UTC (permalink / raw)
To: Enric Balletbo i Serra
Cc: Gwendal Grignou, Collabora kernel ML, Geert Uytterhoeven,
Tony Lindgren, Catalin Marinas, Linus Walleij, Bjorn Andersson,
Thierry Reding, Miquel Raynal, Guenter Roeck, Leonard Crestez,
Will Deacon, Marek Szyprowski, Maxime Ripard,
moderated list:ARM/SAMSUNG EXYNOS ARM ARCHITECTURES, Anson Huang,
Lee Jones, Daniel Lezcano, Russell King, Krzysztof Kozlowski,
Jonathan Hunter, Marcin Juszkiewicz, Chanwoo Choi, Kukjin Kim,
Jagan Teki, Alexandre Torgue, Robert Jarzmik, SoC Team,
open list:TEGRA ARCHITECTURE SUPPORT, Simon Horman,
Fabrice Gasnier, Benson Leung, Linux ARM,
Linux Kernel Mailing List, Yannick Fertr?, Dinh Nguyen,
Sudeep Holla, Olof Johansson, Shawn Guo, Daniel Mack
In-Reply-To: <2db6cde1-9e7f-8b1c-f2e4-80bdd2478d28@collabora.com>
On Wed, Aug 28, 2019 at 12:10 PM Enric Balletbo i Serra
<enric.balletbo@collabora.com> wrote:
> On 27/8/19 18:12, Arnd Bergmann wrote:
> > On Tue, Aug 27, 2019 at 6:08 PM Bjorn Andersson
> > <bjorn.andersson@linaro.org> wrote:
> >>
> >> On Tue 27 Aug 08:48 PDT 2019, Enric Balletbo i Serra wrote:
> >>
> >>> Recently we refactored the CrOS EC drivers moving part of the code from
> >>> the MFD subsystem to the platform chrome subsystem. During this change
> >>> we needed to rename some config options, so, update the defconfigs
> >>> accordingly.
> >>>
> >>> Signed-off-by: Enric Balletbo i Serra <enric.balletbo@collabora.com>
> >>> Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
> >>> Reviewed-by: Gwendal Grignou <gwendal@chromium.org>
> >>> Tested-by: Gwendal Grignou <gwendal@chromium.org>
> >>
> >> Can we make the entries in the generic arm64 defconfig modules?
> >
> > Good idea.
> >
> > Actually I would prefer to have all of them as modules for consistency,
> > if at all possible.
> >
>
> It is very common boot Chromebooks from an USB device, the EC needs to be
> built-in in order to boot from these devices, otherwise you should use an
> initramfs. I'd like to avoid forcing people to build an initramfs just to boot
> from these devices if possible, in fact, my usual workflow is without initramfs,
> and knowing that with the default defconfig just should boot helps a lot sometimes.
>
> Note that, it's not the case for EC subdevices, these are already build as modules.
Ok, fair enough, let's leave it built-in then.
> BTW, Lee asked if this patch should be squashed with the patches that really
> renames the config options to help bisect ability, I don't have a hard opinion
> as I don't usually run the config option between bisection steps, so please let
> me know what do you prefer and I'll respin the patches ASAP if that's the case.
I'm not usually worried about bisection in defconfig changes, since like you
say most commonly one would not run 'make defconfig' betweens the
bisection steps.
If we really care about it, we could keep a symbol like this
in drivers/platform/chrome/Kconfig for one release:
config CONFIG_MFD_CROS_EC
tristate "Enable ChromeOS Embedded Controller"
select CROS_EC
select CHROME_PLATFORMS
select CONFIG_MFD_CROS_EC_DEV
help
This is a transitional Kconfig option and will be removed
after everyone enables the parts individually.
Arnd
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 01/10] KVM: arm64: Document PV-time interface
From: Steven Price @ 2019-08-28 12:09 UTC (permalink / raw)
To: Christoffer Dall
Cc: kvm, linux-doc, Marc Zyngier, linux-kernel, Russell King,
Catalin Marinas, Paolo Bonzini, Will Deacon, kvmarm,
linux-arm-kernel
In-Reply-To: <20190827085706.GB6541@e113682-lin.lund.arm.com>
On 27/08/2019 09:57, Christoffer Dall wrote:
> On Wed, Aug 21, 2019 at 04:36:47PM +0100, Steven Price wrote:
>> Introduce a paravirtualization interface for KVM/arm64 based on the
>> "Arm Paravirtualized Time for Arm-Base Systems" specification DEN 0057A.
>>
>> This only adds the details about "Stolen Time" as the details of "Live
>> Physical Time" have not been fully agreed.
>>
>> User space can specify a reserved area of memory for the guest and
>> inform KVM to populate the memory with information on time that the host
>> kernel has stolen from the guest.
>>
>> A hypercall interface is provided for the guest to interrogate the
>> hypervisor's support for this interface and the location of the shared
>> memory structures.
>>
>> Signed-off-by: Steven Price <steven.price@arm.com>
>> ---
>> Documentation/virt/kvm/arm/pvtime.txt | 100 ++++++++++++++++++++++++++
>> 1 file changed, 100 insertions(+)
>> create mode 100644 Documentation/virt/kvm/arm/pvtime.txt
>>
>> diff --git a/Documentation/virt/kvm/arm/pvtime.txt b/Documentation/virt/kvm/arm/pvtime.txt
>> new file mode 100644
>> index 000000000000..1ceb118694e7
>> --- /dev/null
>> +++ b/Documentation/virt/kvm/arm/pvtime.txt
>> @@ -0,0 +1,100 @@
>> +Paravirtualized time support for arm64
>> +======================================
>> +
>> +Arm specification DEN0057/A defined a standard for paravirtualised time
>> +support for AArch64 guests:
>> +
>> +https://developer.arm.com/docs/den0057/a
>> +
>> +KVM/arm64 implements the stolen time part of this specification by providing
>> +some hypervisor service calls to support a paravirtualized guest obtaining a
>> +view of the amount of time stolen from its execution.
>> +
>> +Two new SMCCC compatible hypercalls are defined:
>> +
>> +PV_FEATURES 0xC5000020
>> +PV_TIME_ST 0xC5000022
>> +
>> +These are only available in the SMC64/HVC64 calling convention as
>> +paravirtualized time is not available to 32 bit Arm guests. The existence of
>> +the PV_FEATURES hypercall should be probed using the SMCCC 1.1 ARCH_FEATURES
>> +mechanism before calling it.
>> +
>> +PV_FEATURES
>> + Function ID: (uint32) : 0xC5000020
>> + PV_func_id: (uint32) : Either PV_TIME_LPT or PV_TIME_ST
>> + Return value: (int32) : NOT_SUPPORTED (-1) or SUCCESS (0) if the relevant
>> + PV-time feature is supported by the hypervisor.
>> +
>> +PV_TIME_ST
>> + Function ID: (uint32) : 0xC5000022
>> + Return value: (int64) : IPA of the stolen time data structure for this
>> + (V)CPU. On failure:
>> + NOT_SUPPORTED (-1)
>> +
>> +The IPA returned by PV_TIME_ST should be mapped by the guest as normal memory
>> +with inner and outer write back caching attributes, in the inner shareable
>> +domain. A total of 16 bytes from the IPA returned are guaranteed to be
>> +meaningfully filled by the hypervisor (see structure below).
>> +
>> +PV_TIME_ST returns the structure for the calling VCPU.
>> +
>> +Stolen Time
>> +-----------
>> +
>> +The structure pointed to by the PV_TIME_ST hypercall is as follows:
>> +
>> + Field | Byte Length | Byte Offset | Description
>> + ----------- | ----------- | ----------- | --------------------------
>> + Revision | 4 | 0 | Must be 0 for version 0.1
>> + Attributes | 4 | 4 | Must be 0
>> + Stolen time | 8 | 8 | Stolen time in unsigned
>> + | | | nanoseconds indicating how
>> + | | | much time this VCPU thread
>> + | | | was involuntarily not
>> + | | | running on a physical CPU.
>> +
>> +The structure will be updated by the hypervisor prior to scheduling a VCPU. It
>> +will be present within a reserved region of the normal memory given to the
>> +guest. The guest should not attempt to write into this memory. There is a
>> +structure per VCPU of the guest.
>> +
>> +User space interface
>> +====================
>> +
>> +User space can request that KVM provide the paravirtualized time interface to
>> +a guest by creating a KVM_DEV_TYPE_ARM_PV_TIME device, for example:
>> +
>> + struct kvm_create_device pvtime_device = {
>> + .type = KVM_DEV_TYPE_ARM_PV_TIME,
>> + .attr = 0,
>> + .flags = 0,
>> + };
>> +
>> + pvtime_fd = ioctl(vm_fd, KVM_CREATE_DEVICE, &pvtime_device);
>> +
>> +Creation of the device should be done after creating the vCPUs of the virtual
>> +machine.
>> +
>> +The IPA of the structures must be given to KVM. This is the base address
>> +of an array of stolen time structures (one for each VCPU). The base address
>> +must be page aligned. The size must be at least 64 * number of VCPUs and be a
>> +multiple of PAGE_SIZE.
>> +
>> +The memory for these structures should be added to the guest in the usual
>> +manner (e.g. using KVM_SET_USER_MEMORY_REGION).
>> +
>> +For example:
>> +
>> + struct kvm_dev_arm_st_region region = {
>> + .gpa = <IPA of guest base address>,
>> + .size = <size in bytes>
>> + };
>
> This feel fragile; how are you handling userspace creating VCPUs after
> setting this up,
In this case as long as the structures all fit within the region created
VCPUs can be created/destroyed at will. If the VCPU index is too high
then the kernel will bail out in kvm_update_stolen_time() so the
structure will not be written. I consider this case as user space
messing up, so beyond protecting the host from the mess, user space gets
to keep the pieces.
> the GPA overlapping guest memory, etc.
Again, the (host) kernel is protected against this, but clearly this
will end badly for the guest.
> Is the
> philosophy here that the VMM can mess up the VM if it wants, but that
> this should never lead attacks on the host (we better hope not) and so
> we don't care?
Yes. For things like GPA overlapping guest memory it's not really the
host's position to work out what is "guest memory". It's quite possible
that user space could decide to place the stolen time structures right
in the middle of guest memory - it's just up to user space to inform the
guest what memory is usable. Obviously the expectation is that the
shared structures would be positioned "out of the way" in GPA space in
any normal arrangement.
> It seems to me setting the IPA per vcpu throught the VCPU device would
> avoid a lot of these issues. See
> Documentation/virt/kvm/devices/vcpu.txt.
That is certainly a possibility, I'm not really sure what the benefit is
though? It would still lead to corner cases:
* What if only some VCPUs had stolen time setup on them?
* What if multiple VCPUs pointed to the same location?
* The structures can still overlap with guest memory
It's also more work to setup in user space with the only "benefit" being
that user space could choose to organise the structures however it sees
fit (e.g. no need for them to be contiguous in memory). But I'm not sure
I see a use case for that flexibility.
Perhaps there's some benefit I'm not seeing?
Steve
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* [PATCH V9 3/3] MAINTAINERS: add imx8 ddr perf admin-guide maintainer information
From: Joakim Zhang @ 2019-08-28 12:07 UTC (permalink / raw)
To: mark.rutland@arm.com, will@kernel.org, robin.murphy@arm.com
Cc: Frank Li, dl-linux-imx, linux-arm-kernel@lists.infradead.org,
Joakim Zhang
In-Reply-To: <20190828120524.9038-1-qiangqing.zhang@nxp.com>
Add imx8 ddr perf admin-guide maintainer information.
Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
---
ChangeLog:
V1 -> V5:
* new add in V5.
V5 -> V6:
* no change.
V6 -> V7:
* no change.
V7 -> V8:
* no change.
V8 -> V9:
* no change.
---
MAINTAINERS | 1 +
1 file changed, 1 insertion(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index e60f5c361969..2ba378e806c7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -6462,6 +6462,7 @@ M: Frank Li <Frank.li@nxp.com>
L: linux-arm-kernel@lists.infradead.org
S: Maintained
F: drivers/perf/fsl_imx8_ddr_perf.c
+F: Documentation/admin-guide/perf/imx-ddr.rst
F: Documentation/devicetree/bindings/perf/fsl-imx-ddr.txt
FREESCALE IMX LPI2C DRIVER
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
* [PATCH V9 2/3] Documentation: admin-guide: perf: add i.MX8 ddr pmu user doc
From: Joakim Zhang @ 2019-08-28 12:07 UTC (permalink / raw)
To: mark.rutland@arm.com, will@kernel.org, robin.murphy@arm.com
Cc: Frank Li, dl-linux-imx, linux-arm-kernel@lists.infradead.org,
Joakim Zhang
In-Reply-To: <20190828120524.9038-1-qiangqing.zhang@nxp.com>
Add i.MX8 ddr pmu user doc.
Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
---
ChangeLog:
V1 -> V4:
* new add in V4.
V4 -> V5:
* no change.
V5 -> V6:
* change the event name
V6 -> V7:
* no change.
V7 -> V8:
* improve the doc, add more details.
V8 -> V9:
* improve the doc.
---
Documentation/admin-guide/perf/imx-ddr.rst | 52 ++++++++++++++++++++++
1 file changed, 52 insertions(+)
create mode 100644 Documentation/admin-guide/perf/imx-ddr.rst
diff --git a/Documentation/admin-guide/perf/imx-ddr.rst b/Documentation/admin-guide/perf/imx-ddr.rst
new file mode 100644
index 000000000000..517a205abad6
--- /dev/null
+++ b/Documentation/admin-guide/perf/imx-ddr.rst
@@ -0,0 +1,52 @@
+=====================================================
+Freescale i.MX8 DDR Performance Monitoring Unit (PMU)
+=====================================================
+
+There are no performance counters inside the DRAM controller, so performance
+signals are brought out to the edge of the controller where a set of 4 x 32 bit
+counters is implemented. This is controlled by the CSV modes programed in counter
+control register which causes a large number of PERF signals to be generated.
+
+Selection of the value for each counter is done via the config registers. There
+is one register for each counter. Counter 0 is special in that it always counts
+“time” and when expired causes a lock on itself and the other counters and an
+interrupt is raised. If any other counter overflows, it continues counting, and
+no interrupt is raised.
+
+The "format" directory describes format of the config (event ID) and config1
+(AXI filtering) fields of the perf_event_attr structure, see /sys/bus/event_source/
+devices/imx8_ddr0/format/. The "events" directory describes the events types
+hardware supported that can be used with perf tool, see /sys/bus/event_source/
+devices/imx8_ddr0/events/.
+ e.g.::
+ perf stat -a -e imx8_ddr0/cycles/ cmd
+ perf stat -a -e imx8_ddr0/read/,imx8_ddr0/write/ cmd
+
+AXI filtering is only used by CSV modes 0x41 (axid-read) and 0x42 (axid-write)
+to count reading or writing matches filter setting. Filter setting is various
+from different DRAM controller implementations, which is distinguished by quirks
+in the driver.
+
+* With DDR_CAP_AXI_ID_FILTER quirk.
+ Filter is defined with two configuration parts:
+ --AXI_ID defines AxID matching value.
+ --AXI_MASKING defines which bits of AxID are meaningful for the matching.
+ 0:corresponding bit is masked.
+ 1: corresponding bit is not masked, i.e. used to do the matching.
+
+ AXI_ID and AXI_MASKING are mapped on DPCR1 register in performance counter.
+ When non-masked bits are matching corresponding AXI_ID bits then counter is
+ incremented. Perf counter is incremented if
+ AxID && AXI_MASKING == AXI_ID && AXI_MASKING
+
+ This filter doesn't support filter different AXI ID for axid-read and axid-write
+ event at the same time as this filter is shared between counters.
+ e.g.::
+ perf stat -a -e imx8_ddr0/axid-read,axi_mask=0xMMMM,axi_id=0xDDDD/ cmd
+ perf stat -a -e imx8_ddr0/axid-write,axi_mask=0xMMMM,axi_id=0xDDDD/ cmd
+
+ NOTE: axi_mask is inverted in userspace(i.e. set bits are bits to mask), and
+ it will be reverted in driver automatically. so that the user can just specify
+ axi_id to monitor a specific id, rather than having to specify axi_mask.
+ e.g.::
+ perf stat -a -e imx8_ddr0/axid-read,axi_id=0x12/ cmd, which will monitor ARID=0x12
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox