* [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 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 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 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 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 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 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 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
* 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
* 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 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 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
* [PATCH v2 1/5] ASoC: dt-bindings: sun4i-spdif: Fix dma-names warning
From: Maxime Ripard @ 2019-08-28 12:52 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Mark Rutland, Rob Herring,
Frank Rowand
Cc: linux-arm-kernel, devicetree, alsa-devel, Chen-Yu Tsai,
Maxime Ripard
From: Maxime Ripard <maxime.ripard@bootlin.com>
Even though the H6 compatible has been properly added, the exeption for the
number of DMA channels hasn't been updated, leading in a validation
warning.
Fix this.
Fixes: b20453031472 ("dt-bindings: sound: sun4i-spdif: Add Allwinner H6 compatible")
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
Changes from v1:
- Fix subject prefix
---
.../devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml
index e0284d8c3b63..38d4cede0860 100644
--- a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-spdif.yaml
@@ -70,7 +70,9 @@ allOf:
properties:
compatible:
contains:
- const: allwinner,sun8i-h3-spdif
+ enum:
+ - allwinner,sun8i-h3-spdif
+ - allwinner,sun50i-h6-spdif
then:
properties:
--
2.21.0
_______________________________________________
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 v2 2/5] ASoC: dt-bindings: Convert Allwinner A10 codec to a schema
From: Maxime Ripard @ 2019-08-28 12:52 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Mark Rutland, Rob Herring,
Frank Rowand
Cc: linux-arm-kernel, devicetree, alsa-devel, Chen-Yu Tsai,
Maxime Ripard
In-Reply-To: <20190828125209.28173-1-mripard@kernel.org>
From: Maxime Ripard <maxime.ripard@bootlin.com>
The Allwinner SoCs have an embedded audio codec that is supported in Linux,
with a matching Device Tree binding.
Now that we have the DT validation in place, let's convert the device tree
bindings for that controller over to a YAML schemas.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
Changes from v1:
- Fix subject prefix
---
.../sound/allwinner,sun4i-a10-codec.yaml | 162 ++++++++++++++++++
.../devicetree/bindings/sound/sun4i-codec.txt | 94 ----------
2 files changed, 162 insertions(+), 94 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
delete mode 100644 Documentation/devicetree/bindings/sound/sun4i-codec.txt
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
new file mode 100644
index 000000000000..44feefae0ef0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-codec.yaml
@@ -0,0 +1,162 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/allwinner,sun4i-a10-codec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A10 Codec Device Tree Bindings
+
+maintainers:
+ - Chen-Yu Tsai <wens@csie.org>
+ - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+ "#sound-dai-cells":
+ const: 0
+
+ compatible:
+ enum:
+ - allwinner,sun4i-a10-codec
+ - allwinner,sun6i-a31-codec
+ - allwinner,sun7i-a20-codec
+ - allwinner,sun8i-a23-codec
+ - allwinner,sun8i-h3-codec
+ - allwinner,sun8i-v3s-codec
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Bus Clock
+ - description: Module Clock
+
+ clock-names:
+ items:
+ - const: apb
+ - const: codec
+
+ dmas:
+ items:
+ - description: RX DMA Channel
+ - description: TX DMA Channel
+
+ dma-names:
+ items:
+ - const: rx
+ - const: tx
+
+ resets:
+ maxItems: 1
+
+ allwinner,audio-routing:
+ $ref: /schemas/types.yaml#definitions/non-unique-string-array
+ description: |-
+ A list of the connections between audio components. Each entry
+ is a pair of strings, the first being the connection\'s sink, the
+ second being the connection\'s source. Valid names include
+
+ Audio pins on the SoC
+ HP
+ HPCOM
+ LINEIN (not on sun8i-v3s)
+ LINEOUT (not on sun8i-a23 or sun8i-v3s)
+ MIC1
+ MIC2 (not on sun8i-v3s)
+ MIC3 (only on sun6i-a31)
+
+ Microphone biases from the SoC
+ HBIAS
+ MBIAS (not on sun8i-v3s)
+
+ Board connectors
+ Headphone
+ Headset Mic
+ Line In
+ Line Out
+ Mic
+ Speaker
+
+ allwinner,codec-analog-controls:
+ $ref: /schemas/types.yaml#/definitions/phandle
+ description: Phandle to the codec analog controls in the PRCM
+
+ allwinner,pa-gpios:
+ description: GPIO to enable the external amplifier
+
+required:
+ - "#sound-dai-cells"
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+ - dmas
+ - dma-names
+
+if:
+ properties:
+ compatible:
+ enum:
+ - allwinner,sun6i-a31-codec
+ - allwinner,sun8i-a23-codec
+ - allwinner,sun8i-h3-codec
+ - allwinner,sun8i-v3s-codec
+
+then:
+ if:
+ properties:
+ compatible:
+ const: allwinner,sun6i-a31-codec
+
+ then:
+ required:
+ - resets
+ - allwinner,audio-routing
+
+ else:
+ required:
+ - resets
+ - allwinner,audio-routing
+ - allwinner,codec-analog-controls
+
+additionalProperties: false
+
+examples:
+ - |
+ codec@1c22c00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun7i-a20-codec";
+ reg = <0x01c22c00 0x40>;
+ interrupts = <0 30 4>;
+ clocks = <&apb0_gates 0>, <&codec_clk>;
+ clock-names = "apb", "codec";
+ dmas = <&dma 0 19>, <&dma 0 19>;
+ dma-names = "rx", "tx";
+ };
+
+ - |
+ codec@1c22c00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun6i-a31-codec";
+ reg = <0x01c22c00 0x98>;
+ interrupts = <0 29 4>;
+ clocks = <&ccu 61>, <&ccu 135>;
+ clock-names = "apb", "codec";
+ resets = <&ccu 42>;
+ dmas = <&dma 15>, <&dma 15>;
+ dma-names = "rx", "tx";
+ allwinner,audio-routing =
+ "Headphone", "HP",
+ "Speaker", "LINEOUT",
+ "LINEIN", "Line In",
+ "MIC1", "MBIAS",
+ "MIC1", "Mic",
+ "MIC2", "HBIAS",
+ "MIC2", "Headset Mic";
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/sun4i-codec.txt b/Documentation/devicetree/bindings/sound/sun4i-codec.txt
deleted file mode 100644
index 66579bbd3294..000000000000
--- a/Documentation/devicetree/bindings/sound/sun4i-codec.txt
+++ /dev/null
@@ -1,94 +0,0 @@
-* Allwinner A10 Codec
-
-Required properties:
-- compatible: must be one of the following compatibles:
- - "allwinner,sun4i-a10-codec"
- - "allwinner,sun6i-a31-codec"
- - "allwinner,sun7i-a20-codec"
- - "allwinner,sun8i-a23-codec"
- - "allwinner,sun8i-h3-codec"
- - "allwinner,sun8i-v3s-codec"
-- reg: must contain the registers location and length
-- interrupts: must contain the codec interrupt
-- dmas: DMA channels for tx and rx dma. See the DMA client binding,
- Documentation/devicetree/bindings/dma/dma.txt
-- dma-names: should include "tx" and "rx".
-- clocks: a list of phandle + clock-specifer pairs, one for each entry
- in clock-names.
-- clock-names: should contain the following:
- - "apb": the parent APB clock for this controller
- - "codec": the parent module clock
-
-Optional properties:
-- allwinner,pa-gpios: gpio to enable external amplifier
-
-Required properties for the following compatibles:
- - "allwinner,sun6i-a31-codec"
- - "allwinner,sun8i-a23-codec"
- - "allwinner,sun8i-h3-codec"
- - "allwinner,sun8i-v3s-codec"
-- resets: phandle to the reset control for this device
-- allwinner,audio-routing: A list of the connections between audio components.
- Each entry is a pair of strings, the first being the
- connection's sink, the second being the connection's
- source. Valid names include:
-
- Audio pins on the SoC:
- "HP"
- "HPCOM"
- "LINEIN" (not on sun8i-v3s)
- "LINEOUT" (not on sun8i-a23 or sun8i-v3s)
- "MIC1"
- "MIC2" (not on sun8i-v3s)
- "MIC3" (sun6i-a31 only)
-
- Microphone biases from the SoC:
- "HBIAS"
- "MBIAS" (not on sun8i-v3s)
-
- Board connectors:
- "Headphone"
- "Headset Mic"
- "Line In"
- "Line Out"
- "Mic"
- "Speaker"
-
-Required properties for the following compatibles:
- - "allwinner,sun8i-a23-codec"
- - "allwinner,sun8i-h3-codec"
- - "allwinner,sun8i-v3s-codec"
-- allwinner,codec-analog-controls: A phandle to the codec analog controls
- block in the PRCM.
-
-Example:
-codec: codec@1c22c00 {
- #sound-dai-cells = <0>;
- compatible = "allwinner,sun7i-a20-codec";
- reg = <0x01c22c00 0x40>;
- interrupts = <0 30 4>;
- clocks = <&apb0_gates 0>, <&codec_clk>;
- clock-names = "apb", "codec";
- dmas = <&dma 0 19>, <&dma 0 19>;
- dma-names = "rx", "tx";
-};
-
-codec: codec@1c22c00 {
- #sound-dai-cells = <0>;
- compatible = "allwinner,sun6i-a31-codec";
- reg = <0x01c22c00 0x98>;
- interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ccu CLK_APB1_CODEC>, <&ccu CLK_CODEC>;
- clock-names = "apb", "codec";
- resets = <&ccu RST_APB1_CODEC>;
- dmas = <&dma 15>, <&dma 15>;
- dma-names = "rx", "tx";
- allwinner,audio-routing =
- "Headphone", "HP",
- "Speaker", "LINEOUT",
- "LINEIN", "Line In",
- "MIC1", "MBIAS",
- "MIC1", "Mic",
- "MIC2", "HBIAS",
- "MIC2", "Headset Mic";
-};
--
2.21.0
_______________________________________________
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 v2 4/5] ASoC: dt-bindings: Convert Allwinner A23 analog codec to a schema
From: Maxime Ripard @ 2019-08-28 12:52 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Mark Rutland, Rob Herring,
Frank Rowand
Cc: linux-arm-kernel, devicetree, alsa-devel, Chen-Yu Tsai,
Maxime Ripard
In-Reply-To: <20190828125209.28173-1-mripard@kernel.org>
From: Maxime Ripard <maxime.ripard@bootlin.com>
The Allwinner A23 SoC and later have an embedded audio codec that uses a
separate controller to drive its analog part, which is supported in Linux,
with a matching Device Tree binding.
Now that we have the DT validation in place, let's convert the device tree
bindings for that controller over to a YAML schemas.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
Changes from v1:
- Fix subject prefix
---
.../allwinner,sun8i-a23-codec-analog.yaml | 38 +++++++++++++++++++
.../bindings/sound/sun8i-codec-analog.txt | 17 ---------
2 files changed, 38 insertions(+), 17 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/allwinner,sun8i-a23-codec-analog.yaml
delete mode 100644 Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a23-codec-analog.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a23-codec-analog.yaml
new file mode 100644
index 000000000000..832779389cbd
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a23-codec-analog.yaml
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/allwinner,sun8i-a23-codec-analog.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A23 Analog Codec Device Tree Bindings
+
+maintainers:
+ - Chen-Yu Tsai <wens@csie.org>
+ - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+ compatible:
+ oneOf:
+ # FIXME: This is documented in the PRCM binding, but needs to be
+ # migrated here at some point
+ # - const: allwinner,sun8i-a23-codec-analog
+ - const: allwinner,sun8i-h3-codec-analog
+ - const: allwinner,sun8i-v3s-codec-analog
+
+ reg:
+ maxItems: 1
+
+required:
+ - compatible
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ codec_analog: codec-analog@1f015c0 {
+ compatible = "allwinner,sun8i-h3-codec-analog";
+ reg = <0x01f015c0 0x4>;
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
deleted file mode 100644
index 07356758bd91..000000000000
--- a/Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-* Allwinner Codec Analog Controls
-
-Required properties:
-- compatible: must be one of the following compatibles:
- - "allwinner,sun8i-a23-codec-analog"
- - "allwinner,sun8i-h3-codec-analog"
- - "allwinner,sun8i-v3s-codec-analog"
-
-Required properties if not a sub-node of the PRCM node:
-- reg: must contain the registers location and length
-
-Example:
-prcm: prcm@1f01400 {
- codec_analog: codec-analog {
- compatible = "allwinner,sun8i-a23-codec-analog";
- };
-};
--
2.21.0
_______________________________________________
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 v2 5/5] ASoC: dt-bindings: Convert Allwinner A64 analog codec to a schema
From: Maxime Ripard @ 2019-08-28 12:52 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Mark Rutland, Rob Herring,
Frank Rowand
Cc: linux-arm-kernel, devicetree, alsa-devel, Chen-Yu Tsai,
Maxime Ripard
In-Reply-To: <20190828125209.28173-1-mripard@kernel.org>
From: Maxime Ripard <maxime.ripard@bootlin.com>
The Allwinner A64 SoC has an embedded audio codec that uses a separate
controller to drive its analog part, which is supported in Linux, with a
matching Device Tree binding.
Now that we have the DT validation in place, let's convert the device tree
bindings for that controller over to a YAML schemas.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
Changes from v1:
- Fix subject prefix
---
.../allwinner,sun50i-a64-codec-analog.yaml | 39 +++++++++++++++++++
.../bindings/sound/sun50i-codec-analog.txt | 14 -------
2 files changed, 39 insertions(+), 14 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml
delete mode 100644 Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml
new file mode 100644
index 000000000000..f290eb72a878
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun50i-a64-codec-analog.yaml
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/allwinner,sun50i-a64-codec-analog.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A64 Analog Codec Device Tree Bindings
+
+maintainers:
+ - Chen-Yu Tsai <wens@csie.org>
+ - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+ compatible:
+ const: allwinner,sun50i-a64-codec-analog
+
+ reg:
+ maxItems: 1
+
+ cpvdd-supply:
+ description:
+ Regulator for the headphone amplifier
+
+required:
+ - compatible
+ - reg
+ - cpvdd-supply
+
+additionalProperties: false
+
+examples:
+ - |
+ codec_analog: codec-analog@1f015c0 {
+ compatible = "allwinner,sun50i-a64-codec-analog";
+ reg = <0x01f015c0 0x4>;
+ cpvdd-supply = <®_eldo1>;
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt b/Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt
deleted file mode 100644
index 056a098495cc..000000000000
--- a/Documentation/devicetree/bindings/sound/sun50i-codec-analog.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-* Allwinner A64 Codec Analog Controls
-
-Required properties:
-- compatible: must be one of the following compatibles:
- - "allwinner,sun50i-a64-codec-analog"
-- reg: must contain the registers location and length
-- cpvdd-supply: Regulator supply for the headphone amplifier
-
-Example:
- codec_analog: codec-analog@1f015c0 {
- compatible = "allwinner,sun50i-a64-codec-analog";
- reg = <0x01f015c0 0x4>;
- cpvdd-supply = <®_eldo1>;
- };
--
2.21.0
_______________________________________________
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 v2 3/5] ASoC: dt-bindings: Convert Allwinner A33 codec to a schema
From: Maxime Ripard @ 2019-08-28 12:52 UTC (permalink / raw)
To: Mark Brown, Liam Girdwood, Mark Rutland, Rob Herring,
Frank Rowand
Cc: linux-arm-kernel, devicetree, alsa-devel, Chen-Yu Tsai,
Maxime Ripard
In-Reply-To: <20190828125209.28173-1-mripard@kernel.org>
From: Maxime Ripard <maxime.ripard@bootlin.com>
The Allwinner A33 SoC have an embedded audio codec that is supported in Linux,
with a matching Device Tree binding.
Now that we have the DT validation in place, let's convert the device tree
bindings for that controller over to a YAML schemas.
Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
---
Changes from v1:
- Fix subject prefix
---
.../sound/allwinner,sun8i-a33-codec.yaml | 57 +++++++++++++++++
.../bindings/sound/sun8i-a33-codec.txt | 63 -------------------
2 files changed, 57 insertions(+), 63 deletions(-)
create mode 100644 Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
delete mode 100644 Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
new file mode 100644
index 000000000000..5e7cc05bbff1
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
@@ -0,0 +1,57 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/allwinner,sun8i-a33-codec.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A33 Codec Device Tree Bindings
+
+maintainers:
+ - Chen-Yu Tsai <wens@csie.org>
+ - Maxime Ripard <maxime.ripard@bootlin.com>
+
+properties:
+ "#sound-dai-cells":
+ const: 0
+
+ compatible:
+ const: allwinner,sun8i-a33-codec
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: Bus Clock
+ - description: Module Clock
+
+ clock-names:
+ items:
+ - const: bus
+ - const: mod
+
+required:
+ - "#sound-dai-cells"
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ - |
+ audio-codec@1c22e00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun8i-a33-codec";
+ reg = <0x01c22e00 0x400>;
+ interrupts = <0 29 4>;
+ clocks = <&ccu 47>, <&ccu 92>;
+ clock-names = "bus", "mod";
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt b/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
deleted file mode 100644
index 7ecf6bd60d27..000000000000
--- a/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-Allwinner SUN8I audio codec
-------------------------------------
-
-On Sun8i-A33 SoCs, the audio is separated in different parts:
- - A DAI driver. It uses the "sun4i-i2s" driver which is
- documented here:
- Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml
- - An analog part of the codec which is handled as PRCM registers.
- See Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
- - An digital part of the codec which is documented in this current
- binding documentation.
- - And finally, an audio card which links all the above components.
- The simple-audio card will be used.
- See Documentation/devicetree/bindings/sound/simple-card.txt
-
-This bindings documentation exposes Sun8i codec (digital part).
-
-Required properties:
-- compatible: must be "allwinner,sun8i-a33-codec"
-- reg: must contain the registers location and length
-- interrupts: must contain the codec interrupt
-- clocks: a list of phandle + clock-specifer pairs, one for each entry
- in clock-names.
-- clock-names: should contain followings:
- - "bus": the parent APB clock for this controller
- - "mod": the parent module clock
-
-Here is an example to add a sound card and the codec binding on sun8i SoCs that
-are similar to A33 using simple-card:
-
- sound {
- compatible = "simple-audio-card";
- simple-audio-card,name = "sun8i-a33-audio";
- simple-audio-card,format = "i2s";
- simple-audio-card,frame-master = <&link_codec>;
- simple-audio-card,bitclock-master = <&link_codec>;
- simple-audio-card,mclk-fs = <512>;
- simple-audio-card,aux-devs = <&codec_analog>;
- simple-audio-card,routing =
- "Left DAC", "Digital Left DAC",
- "Right DAC", "Digital Right DAC";
-
- simple-audio-card,cpu {
- sound-dai = <&dai>;
- };
-
- link_codec: simple-audio-card,codec {
- sound-dai = <&codec>;
- };
-
- soc@1c00000 {
- [...]
-
- audio-codec@1c22e00 {
- #sound-dai-cells = <0>;
- compatible = "allwinner,sun8i-a33-codec";
- reg = <0x01c22e00 0x400>;
- interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
- clock-names = "bus", "mod";
- };
- };
-
--
2.21.0
_______________________________________________
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] mmc: sunxi: fix unusuable eMMC on some H6 boards by disabling DDR
From: Linus Walleij @ 2019-08-28 12:52 UTC (permalink / raw)
To: Alejandro González
Cc: Ulf Hansson, Maxime Ripard, Greg KH, linux-sunxi, linux-mmc,
linux-kernel@vger.kernel.org, Chen-Yu Tsai, Thomas Gleixner,
Linux ARM
In-Reply-To: <20190825150558.15173-1-alejandro.gonzalez.correo@gmail.com>
On Sun, Aug 25, 2019 at 5:06 PM Alejandro González
<alejandro.gonzalez.correo@gmail.com> wrote:
> Jernej Skrabec compared the BSP driver with this
> driver, and found that the BSP driver configures pinctrl to operate at
> 1.8 V when entering DDR mode (although 3.3 V operation is supported), while
> the mainline kernel lacks any mechanism to switch voltages dynamically.
(...)
> the kernel lacks the required
> dynamic pinctrl control for now
This is not a pin control thing, the I/O voltage level is usually
controlled by a regulator called VCCQ, if the selection of the
voltage rails is inside the pin control registers, see the solution
in drivers/pinctrl/sh-pfc/pfc-sh73a0.c where we simply provide
a regulator from inside the pinctrl driver to make things easy
for the MMC core. Do this thing!
If you don't have time to fix it up properly right now I would slap
in a big FIXME in the code so people know this needs
to be fixed properly.
Yours,
Linus Walleij
_______________________________________________
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/5] dt-bindings: sound: Convert Allwinner A33 codec to a schema
From: Maxime Ripard @ 2019-08-28 12:52 UTC (permalink / raw)
To: Chen-Yu Tsai
Cc: Mark Rutland, devicetree, Linux-ALSA, Liam Girdwood, Rob Herring,
Mark Brown, Frank Rowand, linux-arm-kernel
In-Reply-To: <CAGb2v67tEgtD9PEus0TaPQg9969L_7dn2c4GFZSioR1AtxBpmQ@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 5261 bytes --]
Hi,
On Tue, Aug 27, 2019 at 10:29:33PM +0800, Chen-Yu Tsai wrote:
> On Tue, Aug 27, 2019 at 10:25 PM Maxime Ripard <mripard@kernel.org> wrote:
> >
> > From: Maxime Ripard <maxime.ripard@bootlin.com>
> >
> > The Allwinner A33 SoC have an embedded audio codec that is supported in Linux,
> > with a matching Device Tree binding.
> >
> > Now that we have the DT validation in place, let's convert the device tree
> > bindings for that controller over to a YAML schemas.
> >
> > Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com>
> > ---
> > .../sound/allwinner,sun8i-a33-codec.yaml | 57 +++++++++++++++++
> > .../bindings/sound/sun8i-a33-codec.txt | 63 -------------------
> > 2 files changed, 57 insertions(+), 63 deletions(-)
> > create mode 100644 Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
> > delete mode 100644 Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
> >
> > diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
> > new file mode 100644
> > index 000000000000..5e7cc05bbff1
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml
> > @@ -0,0 +1,57 @@
> > +# SPDX-License-Identifier: GPL-2.0
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/sound/allwinner,sun8i-a33-codec.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Allwinner A33 Codec Device Tree Bindings
> > +
> > +maintainers:
> > + - Chen-Yu Tsai <wens@csie.org>
> > + - Maxime Ripard <maxime.ripard@bootlin.com>
> > +
> > +properties:
> > + "#sound-dai-cells":
> > + const: 0
> > +
> > + compatible:
> > + const: allwinner,sun8i-a33-codec
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + interrupts:
> > + maxItems: 1
> > +
> > + clocks:
> > + items:
> > + - description: Bus Clock
> > + - description: Module Clock
> > +
> > + clock-names:
> > + items:
> > + - const: bus
> > + - const: mod
> > +
> > +required:
> > + - "#sound-dai-cells"
> > + - compatible
> > + - reg
> > + - interrupts
> > + - clocks
> > + - clock-names
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > + - |
> > + audio-codec@1c22e00 {
> > + #sound-dai-cells = <0>;
> > + compatible = "allwinner,sun8i-a33-codec";
> > + reg = <0x01c22e00 0x400>;
> > + interrupts = <0 29 4>;
> > + clocks = <&ccu 47>, <&ccu 92>;
> > + clock-names = "bus", "mod";
> > + };
> > +
> > +...
> > diff --git a/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt b/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
> > deleted file mode 100644
> > index 7ecf6bd60d27..000000000000
> > --- a/Documentation/devicetree/bindings/sound/sun8i-a33-codec.txt
> > +++ /dev/null
> > @@ -1,63 +0,0 @@
> > -Allwinner SUN8I audio codec
> > -------------------------------------
> > -
> > -On Sun8i-A33 SoCs, the audio is separated in different parts:
> > - - A DAI driver. It uses the "sun4i-i2s" driver which is
> > - documented here:
> > - Documentation/devicetree/bindings/sound/allwinner,sun4i-a10-i2s.yaml
> > - - An analog part of the codec which is handled as PRCM registers.
> > - See Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
> > - - An digital part of the codec which is documented in this current
> > - binding documentation.
> > - - And finally, an audio card which links all the above components.
> > - The simple-audio card will be used.
> > - See Documentation/devicetree/bindings/sound/simple-card.txt
> > -
> > -This bindings documentation exposes Sun8i codec (digital part).
> > -
> > -Required properties:
> > -- compatible: must be "allwinner,sun8i-a33-codec"
> > -- reg: must contain the registers location and length
> > -- interrupts: must contain the codec interrupt
> > -- clocks: a list of phandle + clock-specifer pairs, one for each entry
> > - in clock-names.
> > -- clock-names: should contain followings:
> > - - "bus": the parent APB clock for this controller
> > - - "mod": the parent module clock
> > -
> > -Here is an example to add a sound card and the codec binding on sun8i SoCs that
> > -are similar to A33 using simple-card:
> > -
> > - sound {
> > - compatible = "simple-audio-card";
> > - simple-audio-card,name = "sun8i-a33-audio";
> > - simple-audio-card,format = "i2s";
> > - simple-audio-card,frame-master = <&link_codec>;
> > - simple-audio-card,bitclock-master = <&link_codec>;
> > - simple-audio-card,mclk-fs = <512>;
> > - simple-audio-card,aux-devs = <&codec_analog>;
> > - simple-audio-card,routing =
> > - "Left DAC", "Digital Left DAC",
> > - "Right DAC", "Digital Right DAC";
>
> At some point we should start listing the endpoints available for routing?
Yeah, we should do that. I'm not sure how easy it would be using the
schemas though.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
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 5/8] coresight: etm4x: Improve usability of sysfs API.
From: Mike Leach @ 2019-08-28 12:56 UTC (permalink / raw)
To: Leo Yan; +Cc: Coresight ML, linux-arm-kernel, Mathieu Poirier
In-Reply-To: <20190828033654.GE26133@leoy-ThinkPad-X240s>
Hi Mathieu, Leo,
Will split & fix comments.
Thanks
Mike
On Wed, 28 Aug 2019 at 04:37, Leo Yan <leo.yan@linaro.org> wrote:
>
> On Mon, Aug 19, 2019 at 09:57:17PM +0100, Mike Leach wrote:
> > Some changes to make the sysfs programming more intuitive.
> >
> > 1) Setting include / exclude on a range had to be done by setting
> > the bit in 'mode' before setting the range. However, setting this
> > bit also had the effect of altering the current range as well.
> >
> > Changed to only set include / exclude setting of a range at the point of
> > setting that range. Either use a 3rd input parameter as the include exclude
> > value, or if not present use the current value of 'mode'. Do not change
> > current range when 'mode' changes.
> >
> > 2) Context ID and VM ID masks required 2 value inputs, even when the
> > second value is ignored as insufficient CID / VMID comparators are
> > implemented.
> > Permit a single value to be used if that is sufficient to cover all
> > implemented comparators.
> >
> > Signed-off-by: Mike Leach <mike.leach@linaro.org>
> > ---
> > .../coresight/coresight-etm4x-sysfs.c | 24 +++++++++++++------
> > 1 file changed, 17 insertions(+), 7 deletions(-)
> >
> > diff --git a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> > index 3bcc260c9e55..baac5b48b7ac 100644
> > --- a/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> > +++ b/drivers/hwtracing/coresight/coresight-etm4x-sysfs.c
> > @@ -297,8 +297,6 @@ static ssize_t mode_store(struct device *dev,
> >
> > spin_lock(&drvdata->spinlock);
> > config->mode = val & ETMv4_MODE_ALL;
> > - etm4_set_mode_exclude(drvdata,
> > - config->mode & ETM_MODE_EXCLUDE ? true : false);
> >
> > if (drvdata->instrp0 == true) {
> > /* start by clearing instruction P0 field */
> > @@ -972,8 +970,12 @@ static ssize_t addr_range_store(struct device *dev,
> > unsigned long val1, val2;
> > struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
> > struct etmv4_config *config = &drvdata->config;
> > + int elements, exclude;
> >
> > - if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
> > + elements = sscanf(buf, "%lx %lx %x", &val1, &val2, &exclude);
> > +
> > + /* exclude is optional, but need at least two parameter */
> > + if (elements < 2)
> > return -EINVAL;
> > /* lower address comparator cannot have a higher address value */
> > if (val1 > val2)
> > @@ -1001,9 +1003,11 @@ static ssize_t addr_range_store(struct device *dev,
> > /*
> > * Program include or exclude control bits for vinst or vdata
> > * whenever we change addr comparators to ETM_ADDR_TYPE_RANGE
> > + * use supplied value, or default to bit set in 'mode'
> > */
> > - etm4_set_mode_exclude(drvdata,
> > - config->mode & ETM_MODE_EXCLUDE ? true : false);
> > + if (elements != 3)
> > + exclude = config->mode & ETM_MODE_EXCLUDE;
> > + etm4_set_mode_exclude(drvdata, exclude ? true : false);
> >
> > spin_unlock(&drvdata->spinlock);
> > return size;
> > @@ -1787,6 +1791,7 @@ static ssize_t ctxid_masks_store(struct device *dev,
> > unsigned long val1, val2, mask;
> > struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
> > struct etmv4_config *config = &drvdata->config;
> > + int nr_inputs;
> >
> > /*
> > * Don't use contextID tracing if coming from a PID namespace. See
> > @@ -1802,7 +1807,9 @@ static ssize_t ctxid_masks_store(struct device *dev,
> > */
> > if (!drvdata->ctxid_size || !drvdata->numcidc)
> > return -EINVAL;
> > - if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
> > + /* one mask if < 4 comparators, two for up to 8 */
>
> One maks is <= 4 comparators.
>
> > + nr_inputs = sscanf(buf, "%lx %lx", &val1, &val2);
> > + if ((drvdata->numcidc > 4) && (nr_inputs != 2))
> > return -EINVAL;
> >
> > spin_lock(&drvdata->spinlock);
> > @@ -1976,6 +1983,7 @@ static ssize_t vmid_masks_store(struct device *dev,
> > unsigned long val1, val2, mask;
> > struct etmv4_drvdata *drvdata = dev_get_drvdata(dev->parent);
> > struct etmv4_config *config = &drvdata->config;
> > + int nr_inputs;
> >
> > /*
> > * only implemented when vmid tracing is enabled, i.e. at least one
> > @@ -1983,7 +1991,9 @@ static ssize_t vmid_masks_store(struct device *dev,
> > */
> > if (!drvdata->vmid_size || !drvdata->numvmidc)
> > return -EINVAL;
> > - if (sscanf(buf, "%lx %lx", &val1, &val2) != 2)
> > + /* one mask if < 4 comparators, two for up to 8 */
>
> One maks is <= 4 comparators.
>
> > + nr_inputs = sscanf(buf, "%lx %lx", &val1, &val2);
> > + if ((drvdata->numvmidc > 4) && (nr_inputs != 2))
> > return -EINVAL;
> >
> > spin_lock(&drvdata->spinlock);
> > --
> > 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 v7 4/4] thermal: cpu_cooling: Migrate to using the EM framework
From: Zhang Rui @ 2019-08-28 12:58 UTC (permalink / raw)
To: Quentin Perret, edubezval, javi.merino, viresh.kumar,
amit.kachhap, rjw, catalin.marinas, will, daniel.lezcano
Cc: linux-pm, linux-kernel, mka, ionela.voinescu, dietmar.eggemann,
linux-arm-kernel
In-Reply-To: <20190812084235.21440-5-quentin.perret@arm.com>
On Mon, 2019-08-12 at 09:42 +0100, Quentin Perret wrote:
> The newly introduced Energy Model framework manages power cost tables
> in
> a generic way. Moreover, it supports several types of models since
> the
> tables can come from DT or firmware (through SCMI) for example. On
> the
> other hand, the cpu_cooling subsystem manages its own power cost
> tables
> using only DT data.
>
> In order to avoid the duplication of data in the kernel, and in order
> to
> enable IPA with EMs coming from more than just DT, remove the private
> tables from cpu_cooling.c and migrate it to using the centralized EM
> framework. Doing so should have no visible functional impact for
> existing users of IPA since:
>
> - recent extenstions to the the PM_OPP infrastructure enable the
> registration of EMs in PM_EM using the DT property used by IPA;
>
> - the existing upstream cpufreq drivers marked with the
> 'CPUFREQ_IS_COOLING_DEV' flag all use the aforementioned PM_OPP
> infrastructure, which means they all support PM_EM. The only two
> exceptions are qoriq-cpufreq which doesn't in fact use an EM and
> scmi-cpufreq which doesn't use DT for power costs.
>
> For existing users of cpu_cooling, PM_EM tables will contain the
> exact
> same power values that IPA used to compute on its own until now. The
> only new dependency for them is to compile in CONFIG_ENERGY_MODEL.
>
> The case where the thermal subsystem is used without an Energy Model
> (cpufreq_cooling_ops) is handled by looking directly at CPUFreq's
> frequency table which is already a dependency for cpu_cooling.c
> anyway.
> Since the thermal framework expects the cooling states in a
> particular
> order, bail out whenever the CPUFreq table is unsorted, since that is
> fairly uncommon in general, and there are currently no users of
> cpu_cooling for this use-case.
>
> Acked-by: Daniel Lezcano <daniel.lezcano@linaro.org>
> Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
> Signed-off-by: Quentin Perret <quentin.perret@arm.com>
this patch has coding style problems, please check the checkpatch.pl
output.
total: 5 errors, 17 warnings, 413 lines checked
thanks,
rui
> ---
> drivers/thermal/Kconfig | 1 +
> drivers/thermal/cpu_cooling.c | 250 ++++++++++++------------------
> ----
> 2 files changed, 91 insertions(+), 160 deletions(-)
>
> diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
> index 9966364a6deb..340853a3ca48 100644
> --- a/drivers/thermal/Kconfig
> +++ b/drivers/thermal/Kconfig
> @@ -144,6 +144,7 @@ config THERMAL_GOV_USER_SPACE
>
> config THERMAL_GOV_POWER_ALLOCATOR
> bool "Power allocator thermal governor"
> + depends on ENERGY_MODEL
> help
> Enable this to manage platform thermals by dynamically
> allocating and limiting power to devices.
> diff --git a/drivers/thermal/cpu_cooling.c
> b/drivers/thermal/cpu_cooling.c
> index 498f59ab64b2..83486775e593 100644
> --- a/drivers/thermal/cpu_cooling.c
> +++ b/drivers/thermal/cpu_cooling.c
> @@ -19,6 +19,7 @@
> #include <linux/slab.h>
> #include <linux/cpu.h>
> #include <linux/cpu_cooling.h>
> +#include <linux/energy_model.h>
>
> #include <trace/events/thermal.h>
>
> @@ -36,21 +37,6 @@
> * ...
> */
>
> -/**
> - * struct freq_table - frequency table along with power entries
> - * @frequency: frequency in KHz
> - * @power: power in mW
> - *
> - * This structure is built when the cooling device registers and
> helps
> - * in translating frequency to power and vice versa.
> - */
> -struct freq_table {
> - u32 frequency;
> -#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
> - u32 power;
> -#endif
> -};
> -
> /**
> * struct time_in_idle - Idle time stats
> * @time: previous reading of the absolute time that this cpu was
> idle
> @@ -72,7 +58,7 @@ struct time_in_idle {
> * frequency.
> * @max_level: maximum cooling level. One less than total number of
> valid
> * cpufreq frequencies.
> - * @freq_table: Freq table in descending order of frequencies
> + * @em: Reference on the Energy Model of the device
> * @cdev: thermal_cooling_device pointer to keep track of the
> * registered cooling device.
> * @policy: cpufreq policy.
> @@ -88,7 +74,7 @@ struct cpufreq_cooling_device {
> unsigned int cpufreq_state;
> unsigned int clipped_freq;
> unsigned int max_level;
> - struct freq_table *freq_table; /* In descending order */
> + struct em_perf_domain *em;
> struct cpufreq_policy *policy;
> struct list_head node;
> struct time_in_idle *idle_time;
> @@ -162,114 +148,40 @@ static int cpufreq_thermal_notifier(struct
> notifier_block *nb,
> static unsigned long get_level(struct cpufreq_cooling_device
> *cpufreq_cdev,
> unsigned int freq)
> {
> - struct freq_table *freq_table = cpufreq_cdev->freq_table;
> - unsigned long level;
> + int i;
>
> - for (level = 1; level <= cpufreq_cdev->max_level; level++)
> - if (freq > freq_table[level].frequency)
> + for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
> + if (freq > cpufreq_cdev->em->table[i].frequency)
> break;
> -
> - return level - 1;
> -}
> -
> -/**
> - * update_freq_table() - Update the freq table with power numbers
> - * @cpufreq_cdev: the cpufreq cooling device in which to update
> the table
> - * @capacitance: dynamic power coefficient for these cpus
> - *
> - * Update the freq table with power numbers. This table will be
> used in
> - * cpu_power_to_freq() and cpu_freq_to_power() to convert between
> power and
> - * frequency efficiently. Power is stored in mW, frequency in
> KHz. The
> - * resulting table is in descending order.
> - *
> - * Return: 0 on success, -EINVAL if there are no OPPs for any CPUs,
> - * or -ENOMEM if we run out of memory.
> - */
> -static int update_freq_table(struct cpufreq_cooling_device
> *cpufreq_cdev,
> - u32 capacitance)
> -{
> - struct freq_table *freq_table = cpufreq_cdev->freq_table;
> - struct dev_pm_opp *opp;
> - struct device *dev = NULL;
> - int num_opps = 0, cpu = cpufreq_cdev->policy->cpu, i;
> -
> - dev = get_cpu_device(cpu);
> - if (unlikely(!dev)) {
> - pr_warn("No cpu device for cpu %d\n", cpu);
> - return -ENODEV;
> - }
> -
> - num_opps = dev_pm_opp_get_opp_count(dev);
> - if (num_opps < 0)
> - return num_opps;
> -
> - /*
> - * The cpufreq table is also built from the OPP table and so
> the count
> - * should match.
> - */
> - if (num_opps != cpufreq_cdev->max_level + 1) {
> - dev_warn(dev, "Number of OPPs not matching with
> max_levels\n");
> - return -EINVAL;
> - }
> -
> - for (i = 0; i <= cpufreq_cdev->max_level; i++) {
> - unsigned long freq = freq_table[i].frequency * 1000;
> - u32 freq_mhz = freq_table[i].frequency / 1000;
> - u64 power;
> - u32 voltage_mv;
> -
> - /*
> - * Find ceil frequency as 'freq' may be slightly lower
> than OPP
> - * freq due to truncation while converting to kHz.
> - */
> - opp = dev_pm_opp_find_freq_ceil(dev, &freq);
> - if (IS_ERR(opp)) {
> - dev_err(dev, "failed to get opp for %lu
> frequency\n",
> - freq);
> - return -EINVAL;
> - }
> -
> - voltage_mv = dev_pm_opp_get_voltage(opp) / 1000;
> - dev_pm_opp_put(opp);
> -
> - /*
> - * Do the multiplication with MHz and millivolt so as
> - * to not overflow.
> - */
> - power = (u64)capacitance * freq_mhz * voltage_mv *
> voltage_mv;
> - do_div(power, 1000000000);
> -
> - /* power is stored in mW */
> - freq_table[i].power = power;
> }
>
> - return 0;
> + return cpufreq_cdev->max_level - i - 1;
> }
>
> static u32 cpu_freq_to_power(struct cpufreq_cooling_device
> *cpufreq_cdev,
> u32 freq)
> {
> int i;
> - struct freq_table *freq_table = cpufreq_cdev->freq_table;
>
> - for (i = 1; i <= cpufreq_cdev->max_level; i++)
> - if (freq > freq_table[i].frequency)
> + for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
> + if (freq > cpufreq_cdev->em->table[i].frequency)
> break;
> + }
>
> - return freq_table[i - 1].power;
> + return cpufreq_cdev->em->table[i + 1].power;
> }
>
> static u32 cpu_power_to_freq(struct cpufreq_cooling_device
> *cpufreq_cdev,
> u32 power)
> {
> int i;
> - struct freq_table *freq_table = cpufreq_cdev->freq_table;
>
> - for (i = 1; i <= cpufreq_cdev->max_level; i++)
> - if (power > freq_table[i].power)
> + for (i = cpufreq_cdev->max_level - 1; i >= 0; i--) {
> + if (power > cpufreq_cdev->em->table[i].power)
> break;
> + }
>
> - return freq_table[i - 1].frequency;
> + return cpufreq_cdev->em->table[i + 1].frequency;
> }
>
> /**
> @@ -410,7 +322,7 @@ static int cpufreq_state2power(struct
> thermal_cooling_device *cdev,
> struct thermal_zone_device *tz,
> unsigned long state, u32 *power)
> {
> - unsigned int freq, num_cpus;
> + unsigned int freq, num_cpus, idx;
> struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata;
>
> /* Request state should be less than max_level */
> @@ -419,7 +331,8 @@ static int cpufreq_state2power(struct
> thermal_cooling_device *cdev,
>
> num_cpus = cpumask_weight(cpufreq_cdev->policy->cpus);
>
> - freq = cpufreq_cdev->freq_table[state].frequency;
> + idx = cpufreq_cdev->max_level - state;
> + freq = cpufreq_cdev->em->table[idx].frequency;
> *power = cpu_freq_to_power(cpufreq_cdev, freq) * num_cpus;
>
> return 0;
> @@ -463,8 +376,60 @@ static int cpufreq_power2state(struct
> thermal_cooling_device *cdev,
> power);
> return 0;
> }
> +
> +static inline bool em_is_sane(struct cpufreq_cooling_device
> *cpufreq_cdev,
> + struct em_perf_domain *em) {
> + struct cpufreq_policy *policy;
> + unsigned int nr_levels;
> +
> + if (!em)
> + return false;
> +
> + policy = cpufreq_cdev->policy;
> + if (!cpumask_equal(policy->related_cpus, to_cpumask(em->cpus)))
> {
> + pr_err("The span of pd %*pbl is misaligned with cpufreq
> policy %*pbl\n",
> + cpumask_pr_args(to_cpumask(em->cpus)),
> + cpumask_pr_args(policy->related_cpus));
> + return false;
> + }
> +
> + nr_levels = cpufreq_cdev->max_level + 1;
> + if (em->nr_cap_states != nr_levels) {
> + pr_err("The number of cap states in pd %*pbl (%u)
> doesn't match the number of cooling levels (%u)\n",
> + cpumask_pr_args(to_cpumask(em->cpus)),
> + em->nr_cap_states, nr_levels);
> + return false;
> + }
> +
> + return true;
> +}
> #endif /* CONFIG_THERMAL_GOV_POWER_ALLOCATOR */
>
> +static unsigned int get_state_freq(struct cpufreq_cooling_device
> *cpufreq_cdev,
> + unsigned long state)
> +{
> + struct cpufreq_policy *policy;
> + unsigned long idx;
> +
> +#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
> + /* Use the Energy Model table if available */
> + if (cpufreq_cdev->em) {
> + idx = cpufreq_cdev->max_level - state;
> + return cpufreq_cdev->em->table[idx].frequency;
> + }
> +#endif
> +
> + /* Otherwise, fallback on the CPUFreq table */
> + policy = cpufreq_cdev->policy;
> + if (policy->freq_table_sorted ==
> CPUFREQ_TABLE_SORTED_ASCENDING)
> + idx = cpufreq_cdev->max_level - state;
> + else
> + idx = state;
> +
> + return policy->freq_table[idx].frequency;
> +}
> +
> +
> /* cpufreq cooling device callback functions are defined below */
>
> /**
> @@ -530,7 +495,7 @@ static int cpufreq_set_cur_state(struct
> thermal_cooling_device *cdev,
> if (cpufreq_cdev->cpufreq_state == state)
> return 0;
>
> - clip_freq = cpufreq_cdev->freq_table[state].frequency;
> + clip_freq = get_state_freq(cpufreq_cdev, state);
> cpufreq_cdev->cpufreq_state = state;
> cpufreq_cdev->clipped_freq = clip_freq;
>
> @@ -552,26 +517,12 @@ static struct notifier_block
> thermal_cpufreq_notifier_block = {
> .notifier_call = cpufreq_thermal_notifier,
> };
>
> -static unsigned int find_next_max(struct cpufreq_frequency_table
> *table,
> - unsigned int prev_max)
> -{
> - struct cpufreq_frequency_table *pos;
> - unsigned int max = 0;
> -
> - cpufreq_for_each_valid_entry(pos, table) {
> - if (pos->frequency > max && pos->frequency < prev_max)
> - max = pos->frequency;
> - }
> -
> - return max;
> -}
> -
> /**
> * __cpufreq_cooling_register - helper function to create cpufreq
> cooling device
> * @np: a valid struct device_node to the cooling device device tree
> node
> * @policy: cpufreq policy
> * Normally this should be same as cpufreq policy->related_cpus.
> - * @capacitance: dynamic power coefficient for these cpus
> + * @em: Energy Model of the cpufreq policy
> *
> * This interface function registers the cpufreq cooling device with
> the name
> * "thermal-cpufreq-%x". This api can support multiple instances of
> cpufreq
> @@ -583,12 +534,13 @@ static unsigned int find_next_max(struct
> cpufreq_frequency_table *table,
> */
> static struct thermal_cooling_device *
> __cpufreq_cooling_register(struct device_node *np,
> - struct cpufreq_policy *policy, u32 capacitance)
> + struct cpufreq_policy *policy,
> + struct em_perf_domain *em)
> {
> struct thermal_cooling_device *cdev;
> struct cpufreq_cooling_device *cpufreq_cdev;
> char dev_name[THERMAL_NAME_LENGTH];
> - unsigned int freq, i, num_cpus;
> + unsigned int i, num_cpus;
> int ret;
> struct thermal_cooling_device_ops *cooling_ops;
> bool first;
> @@ -622,55 +574,38 @@ __cpufreq_cooling_register(struct device_node
> *np,
> /* max_level is an index, not a counter */
> cpufreq_cdev->max_level = i - 1;
>
> - cpufreq_cdev->freq_table = kmalloc_array(i,
> - sizeof(*cpufreq_cdev-
> >freq_table),
> - GFP_KERNEL);
> - if (!cpufreq_cdev->freq_table) {
> - cdev = ERR_PTR(-ENOMEM);
> - goto free_idle_time;
> - }
> -
> ret = ida_simple_get(&cpufreq_ida, 0, 0, GFP_KERNEL);
> if (ret < 0) {
> cdev = ERR_PTR(ret);
> - goto free_table;
> + goto free_idle_time;
> }
> cpufreq_cdev->id = ret;
>
> snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
> cpufreq_cdev->id);
>
> - /* Fill freq-table in descending order of frequencies */
> - for (i = 0, freq = -1; i <= cpufreq_cdev->max_level; i++) {
> - freq = find_next_max(policy->freq_table, freq);
> - cpufreq_cdev->freq_table[i].frequency = freq;
> -
> - /* Warn for duplicate entries */
> - if (!freq)
> - pr_warn("%s: table has duplicate entries\n",
> __func__);
> - else
> - pr_debug("%s: freq:%u KHz\n", __func__, freq);
> - }
> -
> cooling_ops = &cpufreq_cooling_ops;
> #ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
> - if (capacitance) {
> - ret = update_freq_table(cpufreq_cdev, capacitance);
> - if (ret) {
> - cdev = ERR_PTR(ret);
> - goto remove_ida;
> - }
> + if (em_is_sane(cpufreq_cdev, em)) {
> + cpufreq_cdev->em = em;
> cooling_ops->get_requested_power =
> cpufreq_get_requested_power;
> cooling_ops->state2power = cpufreq_state2power;
> cooling_ops->power2state = cpufreq_power2state;
> - }
> + } else
> #endif
> + if (policy->freq_table_sorted == CPUFREQ_TABLE_UNSORTED) {
> + pr_err("%s: unsorted frequency tables are not
> supported\n",
> + __func__);
> + cdev = ERR_PTR(-EINVAL);
> + goto remove_ida;
> + }
> +
> cdev = thermal_of_cooling_device_register(np, dev_name,
> cpufreq_cdev,
> cooling_ops);
> if (IS_ERR(cdev))
> goto remove_ida;
>
> - cpufreq_cdev->clipped_freq = cpufreq_cdev-
> >freq_table[0].frequency;
> + cpufreq_cdev->clipped_freq = get_state_freq(cpufreq_cdev, 0);
>
> mutex_lock(&cooling_list_lock);
> /* Register the notifier for first cpufreq cooling device */
> @@ -686,8 +621,6 @@ __cpufreq_cooling_register(struct device_node
> *np,
>
> remove_ida:
> ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
> -free_table:
> - kfree(cpufreq_cdev->freq_table);
> free_idle_time:
> kfree(cpufreq_cdev->idle_time);
> free_cdev:
> @@ -709,7 +642,7 @@ __cpufreq_cooling_register(struct device_node
> *np,
> struct thermal_cooling_device *
> cpufreq_cooling_register(struct cpufreq_policy *policy)
> {
> - return __cpufreq_cooling_register(NULL, policy, 0);
> + return __cpufreq_cooling_register(NULL, policy, NULL);
> }
> EXPORT_SYMBOL_GPL(cpufreq_cooling_register);
>
> @@ -737,7 +670,6 @@ of_cpufreq_cooling_register(struct cpufreq_policy
> *policy)
> {
> struct device_node *np = of_get_cpu_node(policy->cpu, NULL);
> struct thermal_cooling_device *cdev = NULL;
> - u32 capacitance = 0;
>
> if (!np) {
> pr_err("cpu_cooling: OF node not available for
> cpu%d\n",
> @@ -746,10 +678,9 @@ of_cpufreq_cooling_register(struct
> cpufreq_policy *policy)
> }
>
> if (of_find_property(np, "#cooling-cells", NULL)) {
> - of_property_read_u32(np, "dynamic-power-coefficient",
> - &capacitance);
> + struct em_perf_domain *em = em_cpu_get(policy->cpu);
>
> - cdev = __cpufreq_cooling_register(np, policy,
> capacitance);
> + cdev = __cpufreq_cooling_register(np, policy, em);
> if (IS_ERR(cdev)) {
> pr_err("cpu_cooling: cpu%d failed to register
> as cooling device: %ld\n",
> policy->cpu, PTR_ERR(cdev));
> @@ -791,7 +722,6 @@ void cpufreq_cooling_unregister(struct
> thermal_cooling_device *cdev)
> thermal_cooling_device_unregister(cdev);
> ida_simple_remove(&cpufreq_ida, cpufreq_cdev->id);
> kfree(cpufreq_cdev->idle_time);
> - kfree(cpufreq_cdev->freq_table);
> kfree(cpufreq_cdev);
> }
> EXPORT_SYMBOL_GPL(cpufreq_cooling_unregister);
_______________________________________________
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 2/5] arm64: Use correct ll/sc atomic constraints
From: Andrew Murray @ 2019-08-28 13:01 UTC (permalink / raw)
To: Mark Rutland
Cc: Peter Zijlstra, Catalin Marinas, Boqun Feng, Will Deacon,
Ard.Biesheuvel, linux-arm-kernel
In-Reply-To: <20190822153223.GB33080@lakrids.cambridge.arm.com>
On Thu, Aug 22, 2019 at 04:32:23PM +0100, Mark Rutland wrote:
> Hi Andrew,
>
> On Mon, Aug 12, 2019 at 03:36:22PM +0100, Andrew Murray wrote:
> > For many of the ll/sc atomic operations we use the 'I' machine constraint
> > regardless to the instruction used - this may not be optimal.
> >
> > Let's add an additional parameter to the ATOMIC_xx macros that allows the
> > caller to specify an appropriate machine constraint.
> >
> > Let's also improve __CMPXCHG_CASE by replacing the 'K' constraint with a
> > caller provided constraint. Please note that whilst we would like to use
> > the 'K' constraint on 32 bit operations, we choose not to provide any
> > constraint to avoid a GCC bug which results in a build error.
> >
> > Earlier versions of GCC (no later than 8.1.0) appear to incorrectly handle
> > the 'K' constraint for the value 4294967295.
>
> From reading the above, it's difficult to discern what's a fix and
> what's an improvement, and I think we need to be more explicit about
> that. It would also be helpful to have the necessary context up-front.
>
> How about:
>
> | The A64 ISA accepts distinct (but overlapping) ranges of immediates for:
> |
> | * add arithmetic instructions ('I' machine constraint)
> | * sub arithmetic instructions ('J' machine constraint)
> | * 32-bit logical instructions ('K' machine constraint)
> | * 64-bit logical instructions ('L' machine constraint)
> |
> | ... but we currently use the 'I' constraint for many atomic operations
> | using sub or logical instructions, which is not always valid.
> |
> | When CONFIG_ARM64_LSE_ATOMICS is not set, this allows invalid immediates
> | to be passed to instructions, potentially resulting in a build failure.
> | When CONFIG_ARM64_LSE_ATOMICS is selected the out-of-line ll/sc atomics
> | always use a register as they have no visibility of the value passed by
> | the caller.
> |
> | This patch adds a constraint parameter to the ATOMIC_xx and
> | __CMPXCHG_CASE macros so that we can pass appropriate constraints for
> | each case, with uses updated accordingly.
> |
> | Unfortunately prior to GCC 8.1.0 the 'K' constraint erroneously accepted
> | 0xffffffff, so we must instead force the use of a register.
Looks great - I'll adopt this, thanks for writing it.
>
> Given we haven't had any bug reports, I'm not sure whether this needs a
> Fixes tag or Cc stable. This has been a latent issue for a long time,
> but upstream code doesn't seem to have tickled it.
Yes I guess this is more a correctness issue rather than a reproducible bug
in upstream code. I won't add a fixes tag or CC to stable.
>
> [...]
>
> > -ATOMIC_OPS(and, and)
> > -ATOMIC_OPS(andnot, bic)
> > -ATOMIC_OPS(or, orr)
> > -ATOMIC_OPS(xor, eor)
> > +ATOMIC_OPS(and, and, K)
> > +ATOMIC_OPS(andnot, bic, )
> > +ATOMIC_OPS(or, orr, K)
> > +ATOMIC_OPS(xor, eor, K)
>
> Surely it's not safe to use the K constraint here, either? AFAICT code
> like:
>
> atomic_xor(~0, &atom);
>
> ... would suffer from the same problem as described for cmpxchg.
Thanks for spotting this.
Yes, I think the resolution here (and for any 32bit bitmask immediate) is to
drop the constraint.
Do you agree that we should drop the 'K' constraint for both orr and eor
above?
>
> [...]
>
> > -ATOMIC64_OPS(and, and)
> > -ATOMIC64_OPS(andnot, bic)
> > -ATOMIC64_OPS(or, orr)
> > -ATOMIC64_OPS(xor, eor)
> > +ATOMIC64_OPS(and, and, K)
> > +ATOMIC64_OPS(andnot, bic, )
> > +ATOMIC64_OPS(or, orr, K)
> > +ATOMIC64_OPS(xor, eor, K)
>
> Shouldn't these be 'L'?
>
> IIUC K is a subset of L, so if that's deliberate we should call that out
> explicitly...
Oooh yes that's wrong. I guess the atomic64_[and,or,xor] are rarely called
in the kernel which perhaps is why the compiler hasn't shouted at me.
Do you agree that the and, orr and eor should all be 'L' instead of 'K'?
>
> > +__CMPXCHG_CASE(w, b, , 8, , , , , )
> > +__CMPXCHG_CASE(w, h, , 16, , , , , )
> > +__CMPXCHG_CASE(w, , , 32, , , , , )
> > +__CMPXCHG_CASE( , , , 64, , , , , L)
> > +__CMPXCHG_CASE(w, b, acq_, 8, , a, , "memory", )
> > +__CMPXCHG_CASE(w, h, acq_, 16, , a, , "memory", )
> > +__CMPXCHG_CASE(w, , acq_, 32, , a, , "memory", )
> > +__CMPXCHG_CASE( , , acq_, 64, , a, , "memory", L)
> > +__CMPXCHG_CASE(w, b, rel_, 8, , , l, "memory", )
> > +__CMPXCHG_CASE(w, h, rel_, 16, , , l, "memory", )
> > +__CMPXCHG_CASE(w, , rel_, 32, , , l, "memory", )
> > +__CMPXCHG_CASE( , , rel_, 64, , , l, "memory", L)
> > +__CMPXCHG_CASE(w, b, mb_, 8, dmb ish, , l, "memory", )
> > +__CMPXCHG_CASE(w, h, mb_, 16, dmb ish, , l, "memory", )
> > +__CMPXCHG_CASE(w, , mb_, 32, dmb ish, , l, "memory", )
> > +__CMPXCHG_CASE( , , mb_, 64, dmb ish, , l, "memory", L)
>
> ... but these uses imply that's not the case.
Yup, so I can leave these as they are.
Phew - thanks for the review.
Andrew Murray
>
> Otherwise this looks good to me.
>
> Thanks,
> Mark.
_______________________________________________
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 14/22] ARM: omap1: use pci_ioremap_io() for omap_cf
From: Arnd Bergmann @ 2019-08-28 13:02 UTC (permalink / raw)
To: Aaro Koskinen
Cc: Bartlomiej Zolnierkiewicz, Tony Lindgren, Greg Kroah-Hartman,
Linus Walleij, Linux Kernel Mailing List, Dominik Brodowski,
Tomi Valkeinen, linux-omap, Linux ARM
In-Reply-To: <20190827190453.GJ30291@darkstar.musicnaut.iki.fi>
On Tue, Aug 27, 2019 at 9:05 PM Aaro Koskinen <aaro.koskinen@iki.fi> wrote:
> On Tue, Aug 27, 2019 at 06:33:01PM +0200, Arnd Bergmann wrote:
> > On Fri, Aug 16, 2019 at 10:34 AM Aaro Koskinen <aaro.koskinen@iki.fi> wrote:
> > > However with earlyprintk it seems to hang as soon as kernel tries to print
> > > something. So something goes wrong with early DEBUG_LL mapping code when
> > > CONFIG_DEBUG_UART_VIRT=0xff000000 is used?
> >
> > I just redid the calculation and came out with the same address, so I
> > don't think I put the wrong one there. The address also does not
> > conflict with the PCI mapping, and the address is the same one that
> > is installed later, so that should also be fine.
> >
> > Are you sure you used the correct address in the .config file? If you
> > ran 'make oldconfig', the virtual address would not be changed here
> > as I just modify the default for a fresh 'make omap1_defconfig'
> > run or similar.
>
> Yes... You should be able to try this out also in QEMU to see the hang:
Haven't tried yet, but I took a look at the dump:
> $ qemu-system-arm -M sx1 -kernel sx1-zImage -nographic
>
> [ Hangs silently, press Ctrl-a c to enter monitor. ]
>
> QEMU 4.1.0 monitor - type 'help' for more information
> (qemu) info registers
> R00=c0379de1 R01=0000005b R02=00000000 R03=ff000000
> R04=00000000 R05=00000031 R06=c038f119 R07=00000000
> R08=00000000 R09=c038f50e R10=600001d3 R11=00000001
> R12=00000010 R13=c0379de0 R14=c000e07c R15=c000dfcc
> PSR=000001d3 ---- A svc32
> FPSCR: 00000000
>
> from System.map:
> c000df7c T printascii
> c000dfe0 T printch
Ok, that is clearly the "busyloop" macro in
arch/arm/include/debug/8250.S, checking if the data got sent.
The 'r2' register contains zero, so UART_LSR_TEMT and
UART_LSR_THRE are not set, but presumably the mapping
was installed right since you did not get a page fault.
I assume you checked that the uart output wasn't already broken
by one of the earlier patches, right?
Also, looking at arch/arm/mach-omap1/include/mach/uncompress.h
it seems that SX1 normally uses UART3, not UART1.
Is that different in qemu?
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 v6 11/22] clk: sunxi-ng: a64: Add minimum rate for PLL_MIPI
From: Maxime Ripard @ 2019-08-28 13:03 UTC (permalink / raw)
To: Michael Nazzareno Trimarchi
Cc: Mark Rutland, devicetree, David Airlie, Michael Turquette,
linux-sunxi, linux-kernel, dri-devel, Chen-Yu Tsai, Rob Herring,
Jagan Teki, Daniel Vetter, linux-amarula, linux-clk,
linux-arm-kernel
In-Reply-To: <CAOf5uw=RcBHibiq735NiX452Jde4ZL7PpfwH+Pkc=hARJBudUw@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 12246 bytes --]
Hi,
On Thu, Aug 15, 2019 at 02:25:57PM +0200, Michael Nazzareno Trimarchi wrote:
> On Tue, Aug 13, 2019 at 8:05 AM Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> > On Mon, Jul 29, 2019 at 08:59:04AM +0200, Michael Nazzareno Trimarchi wrote:
> > > Hi
> > >
> > > On Wed, Jul 24, 2019 at 11:05 AM Maxime Ripard
> > > <maxime.ripard@bootlin.com> wrote:
> > > >
> > > > On Mon, Jul 22, 2019 at 03:51:04PM +0530, Jagan Teki wrote:
> > > > > Hi Maxime,
> > > > >
> > > > > On Sat, Jul 20, 2019 at 3:02 PM Maxime Ripard <maxime.ripard@bootlin.com> wrote:
> > > > > >
> > > > > > On Sat, Jul 20, 2019 at 12:46:27PM +0530, Jagan Teki wrote:
> > > > > > > On Sat, Jul 20, 2019 at 12:28 PM Maxime Ripard
> > > > > > > <maxime.ripard@bootlin.com> wrote:
> > > > > > > >
> > > > > > > > On Thu, Jul 11, 2019 at 07:43:16PM +0200, Michael Nazzareno Trimarchi wrote:
> > > > > > > > > > > tcon-pixel clock is the rate that you want to achive on display side
> > > > > > > > > > > and if you have 4 lanes 32bit or lanes and different bit number that
> > > > > > > > > > > you need to have a clock that is able to put outside bits and speed
> > > > > > > > > > > equal to pixel-clock * bits / lanes. so If you want a pixel-clock of
> > > > > > > > > > > 40 mhz and you have 32bits and 4 lanes you need to have a clock of
> > > > > > > > > > > 40 * 32 / 4 in no-burst mode. I think that this is done but most of
> > > > > > > > > > > the display.
> > > > > > > > > >
> > > > > > > > > > So this is what the issue is then?
> > > > > > > > > >
> > > > > > > > > > This one does make sense, and you should just change the rate in the
> > > > > > > > > > call to clk_set_rate in sun4i_tcon0_mode_set_cpu.
> > > > > > > > > >
> > > > > > > > > > I'm still wondering why that hasn't been brought up in either the
> > > > > > > > > > discussion or the commit log before though.
> > > > > > > > > >
> > > > > > > > > Something like this?
> > > > > > > > >
> > > > > > > > > drivers/gpu/drm/sun4i/sun4i_tcon.c | 20 +++++++++++---------
> > > > > > > > > drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h | 2 --
> > > > > > > > > 2 files changed, 11 insertions(+), 11 deletions(-)
> > > > > > > > >
> > > > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > index 64c43ee6bd92..42560d5c327c 100644
> > > > > > > > > --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> > > > > > > > > @@ -263,10 +263,11 @@ static int sun4i_tcon_get_clk_delay(const struct
> > > > > > > > > drm_display_mode *mode,
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
> > > > > > > > > - const struct drm_display_mode *mode)
> > > > > > > > > + const struct drm_display_mode *mode,
> > > > > > > > > + u32 tcon_mul)
> > > > > > > > > {
> > > > > > > > > /* Configure the dot clock */
> > > > > > > > > - clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
> > > > > > > > > + clk_set_rate(tcon->dclk, mode->crtc_clock * tcon_mul * 1000);
> > > > > > > > >
> > > > > > > > > /* Set the resolution */
> > > > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
> > > > > > > > > @@ -335,12 +336,13 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > > u8 bpp = mipi_dsi_pixel_format_to_bpp(device->format);
> > > > > > > > > u8 lanes = device->lanes;
> > > > > > > > > u32 block_space, start_delay;
> > > > > > > > > - u32 tcon_div;
> > > > > > > > > + u32 tcon_div, tcon_mul;
> > > > > > > > >
> > > > > > > > > - tcon->dclk_min_div = SUN6I_DSI_TCON_DIV;
> > > > > > > > > - tcon->dclk_max_div = SUN6I_DSI_TCON_DIV;
> > > > > > > > > + tcon->dclk_min_div = 4;
> > > > > > > > > + tcon->dclk_max_div = 127;
> > > > > > > > >
> > > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > > + tcon_mul = bpp / lanes;
> > > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, tcon_mul);
> > > > > > > > >
> > > > > > > > > /* Set dithering if needed */
> > > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > > > @@ -366,7 +368,7 @@ static void sun4i_tcon0_mode_set_cpu(struct
> > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > > */
> > > > > > > > > regmap_read(tcon->regs, SUN4I_TCON0_DCLK_REG, &tcon_div);
> > > > > > > > > tcon_div &= GENMASK(6, 0);
> > > > > > > > > - block_space = mode->htotal * bpp / (tcon_div * lanes);
> > > > > > > > > + block_space = mode->htotal * tcon_div * tcon_mul;
> > > > > > > > > block_space -= mode->hdisplay + 40;
> > > > > > > > >
> > > > > > > > > regmap_write(tcon->regs, SUN4I_TCON0_CPU_TRI0_REG,
> > > > > > > > > @@ -408,7 +410,7 @@ static void sun4i_tcon0_mode_set_lvds(struct
> > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > >
> > > > > > > > > tcon->dclk_min_div = 7;
> > > > > > > > > tcon->dclk_max_div = 7;
> > > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > > > >
> > > > > > > > > /* Set dithering if needed */
> > > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, sun4i_tcon_get_connector(encoder));
> > > > > > > > > @@ -487,7 +489,7 @@ static void sun4i_tcon0_mode_set_rgb(struct
> > > > > > > > > sun4i_tcon *tcon,
> > > > > > > > >
> > > > > > > > > tcon->dclk_min_div = 6;
> > > > > > > > > tcon->dclk_max_div = 127;
> > > > > > > > > - sun4i_tcon0_mode_set_common(tcon, mode);
> > > > > > > > > + sun4i_tcon0_mode_set_common(tcon, mode, 1);
> > > > > > > > >
> > > > > > > > > /* Set dithering if needed */
> > > > > > > > > sun4i_tcon0_mode_set_dithering(tcon, connector);
> > > > > > > > > diff --git a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > index 5c3ad5be0690..a07090579f84 100644
> > > > > > > > > --- a/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > +++ b/drivers/gpu/drm/sun4i/sun6i_mipi_dsi.h
> > > > > > > > > @@ -13,8 +13,6 @@
> > > > > > > > > #include <drm/drm_encoder.h>
> > > > > > > > > #include <drm/drm_mipi_dsi.h>
> > > > > > > > >
> > > > > > > > > -#define SUN6I_DSI_TCON_DIV 4
> > > > > > > > > -
> > > > > > > > > struct sun6i_dsi {
> > > > > > > > > struct drm_connector connector;
> > > > > > > > > struct drm_encoder encoder;
> > > > > > > >
> > > > > > > > I had more something like this in mind:
> > > > > > > > http://code.bulix.org/nlp5a4-803511
> > > > > > >
> > > > > > > Worth to look at it. was it working on your panel? meanwhile I will check it.
> > > > > >
> > > > > > I haven't tested it.
> > > > > >
> > > > > > > We have updated with below change [1], seems working on but is
> > > > > > > actually checking the each divider as before start with 4... till 127.
> > > > > > >
> > > > > > > This new approach, is start looking the best divider from 4.. based on
> > > > > > > the idea vs rounded it will ended up best divider like [2]
> > > > > >
> > > > > > But why?
> > > > > >
> > > > > > I mean, it's not like it's the first time I'm asking this...
> > > > > >
> > > > > > If the issue is what Micheal described, then the divider has nothing
> > > > > > to do with it. We've had that discussion over and over again.
> > > > >
> > > > > This is what Michael is mentioned in above mail "tcon-pixel clock is
> > > > > the rate that you want to achive on display side and if you have 4
> > > > > lanes 32bit or lanes and different bit number that you need to have
> > > > > a clock that is able to put outside bits and speed equal to
> > > > > pixel-clock * bits / lanes. so If you want a pixel-clock of 40 mhz
> > > > > and you have 32bits and 4 lanes you need to have a clock of 40 * 32
> > > > > / 4 in no-burst mode. "
> > > >
> > > > Yeah, so we need to change the clock rate.
> > > >
> > > > > He is trying to manage the bpp/lanes into dclk_mul (in last mail)
> > > > > and it can multiply with pixel clock which is rate argument in
> > > > > sun4i_dclk_round_rate.
> > > > >
> > > > > The solution I have mentioned in dclk_min, max is bpp/lanes also
> > > > > multiple rate in dotclock sun4i_dclk_round_rate.
> > > > >
> > > > > In both cases the overall pll_rate depends on dividers, the one that I
> > > > > have on this patch is based on BSP and the Michael one is more generic
> > > > > way so-that it can not to touch other functionalities and looping
> > > > > dividers to find the best one.
> > > > >
> > > > > If dclk_min/max is bpp/lanes then dotclock directly using divider 6
> > > > > (assuming 24-bit and 4 lanes) and return the pll_rate and divider 6
> > > > > associated.
> > > > >
> > > > > if dclk_mul is bpp/lanes, on Michael new change, the dividers start
> > > > > with 4 and end with 127 but the constant ideal rate which rate *
> > > > > bpp/lanes but the loop from sun4i_dclk_round_rate computed the divider
> > > > > as 6 only, ie what I'm mentioned on the above mail.
> > > >
> > > > We've been over this a couple of times already.
> > > >
> > > > The clock is generated like this:
> > > >
> > > > PLL -> TCON Module Clock -> TCON DCLK
> > > >
> > > > You want the TCON DCLK to be at the pixel clock rate * bpp /
> > > > lanes. Fine, that makes sense.
> > > >
> > > > Except that the patch you've sent, instead of changing the rate
> > > > itself, changes the ratio between the module clock and DCLK.
> > > >
> > > > And this is where the issue lies. First, from a logical viewpoint, it
> > > > doesn't make sense. If you want to change the clock rate, then just do
> > > > it. Don't hack around the multipliers trying to fall back to something
> > > > that works for you.
> > > >
> > > > Then, the ratio itself needs to be set to 4. This is the part that
> > > > we've discussed way too many times already, but in the Allwinner BSP,
> > > > that ratio is hardcoded to 4, and we've had panels that need it at
> > > > that value.
> > > >
> > > > So, what you want to do is to have:
> > > >
> > > > TCON DCLK = pixel clock * bpp / lanes
> > > > TCON Module Clock = DCLK * 4
> > > > PLL = Module Clock * Module Clock Divider (which I believe is 1 in most cases)
> > >
> > > pll-mipi 1 1 1 178200000
> > > 0 0 50000
> > > tcon0 2 2 1 178200000
> > > 0 0 50000
> > > tcon-pixel-clock 1 1 1 29700000
> > > 0 0 50000
> >
> > Is this before or after your patches?
> >
>
> This is just an example of clock tree to be clear to everyone how they
> are connected
>
> > > This is an english problem from my side:
> > > tcon-pixel-clock is DCLK
> > > tcon0 must be tcon-pixel-clock * bpp / lanes, because the logic need to
> > > put a bit every cycle.
> >
> > Again, I'm not saying this is wrong, but each time I've looked at it
> > the BSP was using a 4 divider between the tcon module clock and the
> > dotclock.
>
> We have tested on 4-5 displays. Well I don't care on bsp but I care
> about if it works and if other SoC has similar approach on clock
> calculation.
Well, it's also breaking another panel.
> > So, please prove me wrong here.
>
> Having only 10 pages of documentation is a bit difficult.
The BSP source code will be a fine example too.
> > > One solution can be:
> > > - set_rate_exclusive to tcon0 and calculate as display pixel clock *
> > > bpp / lanes
> >
> > I'm not sure what set_rate_exclusive has to do with it. I mean, it's a
> > good idea to use it, but it shouldn't really change anything to the
> > discussion.
>
> Well, this will just do a minimal change on source code and put the constrains
> to the tcon0
I agree, but again, this has nothing to do with the current discussion.
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
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 4/4] thermal: cpu_cooling: Migrate to using the EM framework
From: Quentin Perret @ 2019-08-28 13:04 UTC (permalink / raw)
To: Zhang Rui
Cc: ionela.voinescu, linux-pm, viresh.kumar, amit.kachhap,
daniel.lezcano, rjw, linux-kernel, edubezval, mka,
catalin.marinas, javi.merino, will, dietmar.eggemann,
linux-arm-kernel
In-Reply-To: <ebfd68984103084d63cf01a80cfa9538a1a15baf.camel@intel.com>
On Wednesday 28 Aug 2019 at 20:58:47 (+0800), Zhang Rui wrote:
> this patch has coding style problems, please check the checkpatch.pl
> output.
> total: 5 errors, 17 warnings, 413 lines checked
Argh ! And that's what happens when I forget checkpatch ...
I'll fix this shortly. Sorry about that.
Quentin
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
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