linux: add amlogic 5.3 patchset

This commit is contained in:
chewitt 2019-08-17 05:54:16 +00:00
parent 587d35904c
commit bafeab56e3
203 changed files with 36832 additions and 50246 deletions

View File

@ -0,0 +1,110 @@
From f75a1c26012288dca8df4128cb5937afeca70a40 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 12 Jun 2019 10:51:47 +0200
Subject: [PATCH 001/186] FROMGIT: drm/bridge: dw-hdmi: Use automatic CTS
generation mode when using non-AHB audio
When using an I2S source using a different clock source (usually the I2S
audio HW uses dedicated PLLs, different from the HDMI PHY PLL), fixed
CTS values will cause some frequent audio drop-out and glitches as
reported on Amlogic, Allwinner and Rockchip SoCs setups.
Setting the CTS in automatic mode will let the HDMI controller generate
automatically the CTS value to match the input audio clock.
The DesignWare DW-HDMI User Guide explains:
For Automatic CTS generation
Write "0" on the bit field "CTS_manual", Register 0x3205: AUD_CTS3
The DesignWare DW-HDMI Databook explains :
If "CTS_manual" bit equals 0b this registers contains "audCTS[19:0]"
generated by the Cycle time counter according to specified timing.
Cc: Jernej Skrabec <jernej.skrabec@siol.net>
Cc: Maxime Ripard <maxime.ripard@bootlin.com>
Cc: Jonas Karlman <jonas@kwiboo.se>
Cc: Heiko Stuebner <heiko@sntech.de>
Cc: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Tested-by: Jernej Skrabec <jernej.skrabec@siol.net>
Reviewed-by: Jernej Skrabec <jernej.skrabec@siol.net>
Tested-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190612085147.26971-1-narmstrong@baylibre.com
(cherry-picked from fdbdcc83ffd7d00265a531e71f1d166566c09d66
git://anongit.freedesktop.org/drm/drm-misc)
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 45 +++++++++++++++--------
1 file changed, 30 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index c6490949d9db..218a7b2308f7 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -508,8 +508,14 @@ static void hdmi_set_cts_n(struct dw_hdmi *hdmi, unsigned int cts,
/* nshift factor = 0 */
hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3);
- hdmi_writeb(hdmi, ((cts >> 16) & HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
- HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3);
+ /* Use automatic CTS generation mode when CTS is not set */
+ if (cts)
+ hdmi_writeb(hdmi, ((cts >> 16) &
+ HDMI_AUD_CTS3_AUDCTS19_16_MASK) |
+ HDMI_AUD_CTS3_CTS_MANUAL,
+ HDMI_AUD_CTS3);
+ else
+ hdmi_writeb(hdmi, 0, HDMI_AUD_CTS3);
hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2);
hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1);
@@ -579,24 +585,33 @@ static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi,
{
unsigned long ftdms = pixel_clk;
unsigned int n, cts;
+ u8 config3;
u64 tmp;
n = hdmi_compute_n(sample_rate, pixel_clk);
- /*
- * Compute the CTS value from the N value. Note that CTS and N
- * can be up to 20 bits in total, so we need 64-bit math. Also
- * note that our TDMS clock is not fully accurate; it is accurate
- * to kHz. This can introduce an unnecessary remainder in the
- * calculation below, so we don't try to warn about that.
- */
- tmp = (u64)ftdms * n;
- do_div(tmp, 128 * sample_rate);
- cts = tmp;
+ config3 = hdmi_readb(hdmi, HDMI_CONFIG3_ID);
- dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n",
- __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000,
- n, cts);
+ /* Only compute CTS when using internal AHB audio */
+ if (config3 & HDMI_CONFIG3_AHBAUDDMA) {
+ /*
+ * Compute the CTS value from the N value. Note that CTS and N
+ * can be up to 20 bits in total, so we need 64-bit math. Also
+ * note that our TDMS clock is not fully accurate; it is
+ * accurate to kHz. This can introduce an unnecessary remainder
+ * in the calculation below, so we don't try to warn about that.
+ */
+ tmp = (u64)ftdms * n;
+ do_div(tmp, 128 * sample_rate);
+ cts = tmp;
+
+ dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n",
+ __func__, sample_rate,
+ ftdms / 1000000, (ftdms / 1000) % 1000,
+ n, cts);
+ } else {
+ cts = 0;
+ }
spin_lock_irq(&hdmi->audio_lock);
hdmi->audio_n = n;
--
2.17.1

View File

@ -0,0 +1,36 @@
From eb9dac6427adef3545346e0c860be7bcfdab5e49 Mon Sep 17 00:00:00 2001
From: Alexandre Mergnat <amergnat@baylibre.com>
Date: Fri, 24 May 2019 11:15:32 +0200
Subject: [PATCH 002/186] FROMGIT: clk: meson: g12a: fix hifi typo in mali
parent_names
Replace hihi by hifi in the mali parent_names of the g12a SoC family.
Fixes: 085a4ea93d54 ("clk: meson: g12a: add peripheral clock controller")
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
Acked-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit b6297d9e078a4127fb608ede4d0944855dde667d
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/g12a.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index db1c4ed9d54e..7bc5566b66f7 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -2888,7 +2888,7 @@ static struct clk_regmap g12a_hdmi = {
*/
static const char * const g12a_mali_0_1_parent_names[] = {
- IN_PREFIX "xtal", "gp0_pll", "hihi_pll", "fclk_div2p5",
+ IN_PREFIX "xtal", "gp0_pll", "hifi_pll", "fclk_div2p5",
"fclk_div3", "fclk_div4", "fclk_div5", "fclk_div7"
};
--
2.17.1

View File

@ -0,0 +1,534 @@
From 9ab959a3f5d6518065e1e957b21ef08d663550d1 Mon Sep 17 00:00:00 2001
From: Alexandre Mergnat <amergnat@baylibre.com>
Date: Thu, 25 Jul 2019 18:40:23 +0200
Subject: [PATCH 003/186] FROMGIT: clk: meson: axg-audio: migrate to the new
parent description method
This clock controller use the string comparison method to describe parent
relation between the clocks, which is not optimized. A recent patch [0]
allows parents to be specified without string names or with device-tree
clock name by using a new assignment structure.
Migrate to the new way by using .parent_hws where possible (when parent
clocks are localy declared in the controller) and use .parent_data
otherwise.
Remove clk input helper and all bypass clocks (declared in probe function)
which are no longer used since we are able to use device-tree clock name
directly.
[0] commit fc0c209c147f ("clk: Allow parents to be specified without string names")
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
[jbrunet@baylibre.com: remove CLK_SET_RATE_PARENT from mst muxes]
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit 282420eed23f237963f2033b2f2bedb90fbcc5e1
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/Kconfig | 1 -
drivers/clk/meson/axg-audio.c | 261 ++++++++++++++++------------------
2 files changed, 120 insertions(+), 142 deletions(-)
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index a6b20e123e0c..ee0b84b6b329 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -86,7 +86,6 @@ config COMMON_CLK_AXG
config COMMON_CLK_AXG_AUDIO
tristate "Meson AXG Audio Clock Controller Driver"
depends on ARCH_MESON
- select COMMON_CLK_MESON_INPUT
select COMMON_CLK_MESON_REGMAP
select COMMON_CLK_MESON_PHASE
select COMMON_CLK_MESON_SCLK_DIV
diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c
index 8028ff6f6610..741df7e955ca 100644
--- a/drivers/clk/meson/axg-audio.c
+++ b/drivers/clk/meson/axg-audio.c
@@ -15,7 +15,6 @@
#include <linux/slab.h>
#include "axg-audio.h"
-#include "clk-input.h"
#include "clk-regmap.h"
#include "clk-phase.h"
#include "sclk-div.h"
@@ -24,7 +23,7 @@
#define AUD_SLV_SCLK_COUNT 10
#define AUD_SLV_LRCLK_COUNT 10
-#define AUD_GATE(_name, _reg, _bit, _pname, _iflags) \
+#define AUD_GATE(_name, _reg, _bit, _phws, _iflags) \
struct clk_regmap aud_##_name = { \
.data = &(struct clk_regmap_gate_data){ \
.offset = (_reg), \
@@ -33,13 +32,13 @@ struct clk_regmap aud_##_name = { \
.hw.init = &(struct clk_init_data) { \
.name = "aud_"#_name, \
.ops = &clk_regmap_gate_ops, \
- .parent_names = (const char *[]){ _pname }, \
+ .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \
.num_parents = 1, \
.flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \
}, \
}
-#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pnames, _iflags) \
+#define AUD_MUX(_name, _reg, _mask, _shift, _dflags, _pdata, _iflags) \
struct clk_regmap aud_##_name = { \
.data = &(struct clk_regmap_mux_data){ \
.offset = (_reg), \
@@ -50,13 +49,13 @@ struct clk_regmap aud_##_name = { \
.hw.init = &(struct clk_init_data){ \
.name = "aud_"#_name, \
.ops = &clk_regmap_mux_ops, \
- .parent_names = (_pnames), \
- .num_parents = ARRAY_SIZE(_pnames), \
+ .parent_data = _pdata, \
+ .num_parents = ARRAY_SIZE(_pdata), \
.flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \
}, \
}
-#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _pname, _iflags) \
+#define AUD_DIV(_name, _reg, _shift, _width, _dflags, _phws, _iflags) \
struct clk_regmap aud_##_name = { \
.data = &(struct clk_regmap_div_data){ \
.offset = (_reg), \
@@ -67,15 +66,27 @@ struct clk_regmap aud_##_name = { \
.hw.init = &(struct clk_init_data){ \
.name = "aud_"#_name, \
.ops = &clk_regmap_divider_ops, \
- .parent_names = (const char *[]) { _pname }, \
+ .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \
.num_parents = 1, \
.flags = (_iflags), \
}, \
}
#define AUD_PCLK_GATE(_name, _bit) \
- AUD_GATE(_name, AUDIO_CLK_GATE_EN, _bit, "audio_pclk", 0)
-
+struct clk_regmap aud_##_name = { \
+ .data = &(struct clk_regmap_gate_data){ \
+ .offset = (AUDIO_CLK_GATE_EN), \
+ .bit_idx = (_bit), \
+ }, \
+ .hw.init = &(struct clk_init_data) { \
+ .name = "aud_"#_name, \
+ .ops = &clk_regmap_gate_ops, \
+ .parent_data = &(const struct clk_parent_data) { \
+ .fw_name = "pclk", \
+ }, \
+ .num_parents = 1, \
+ }, \
+}
/* Audio peripheral clocks */
static AUD_PCLK_GATE(ddr_arb, 0);
static AUD_PCLK_GATE(pdm, 1);
@@ -100,14 +111,20 @@ static AUD_PCLK_GATE(power_detect, 19);
static AUD_PCLK_GATE(spdifout_b, 21);
/* Audio Master Clocks */
-static const char * const mst_mux_parent_names[] = {
- "aud_mst_in0", "aud_mst_in1", "aud_mst_in2", "aud_mst_in3",
- "aud_mst_in4", "aud_mst_in5", "aud_mst_in6", "aud_mst_in7",
+static const struct clk_parent_data mst_mux_parent_data[] = {
+ { .fw_name = "mst_in0", },
+ { .fw_name = "mst_in1", },
+ { .fw_name = "mst_in2", },
+ { .fw_name = "mst_in3", },
+ { .fw_name = "mst_in4", },
+ { .fw_name = "mst_in5", },
+ { .fw_name = "mst_in6", },
+ { .fw_name = "mst_in7", },
};
#define AUD_MST_MUX(_name, _reg, _flag) \
AUD_MUX(_name##_sel, _reg, 0x7, 24, _flag, \
- mst_mux_parent_names, CLK_SET_RATE_PARENT)
+ mst_mux_parent_data, 0)
#define AUD_MST_MCLK_MUX(_name, _reg) \
AUD_MST_MUX(_name, _reg, CLK_MUX_ROUND_CLOSEST)
@@ -129,7 +146,7 @@ static AUD_MST_MCLK_MUX(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
#define AUD_MST_DIV(_name, _reg, _flag) \
AUD_DIV(_name##_div, _reg, 0, 16, _flag, \
- "aud_"#_name"_sel", CLK_SET_RATE_PARENT) \
+ aud_##_name##_sel, CLK_SET_RATE_PARENT) \
#define AUD_MST_MCLK_DIV(_name, _reg) \
AUD_MST_DIV(_name, _reg, CLK_DIVIDER_ROUND_CLOSEST)
@@ -150,7 +167,7 @@ static AUD_MST_SYS_DIV(pdm_sysclk, AUDIO_CLK_PDMIN_CTRL1);
static AUD_MST_MCLK_DIV(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
#define AUD_MST_MCLK_GATE(_name, _reg) \
- AUD_GATE(_name, _reg, 31, "aud_"#_name"_div", \
+ AUD_GATE(_name, _reg, 31, aud_##_name##_div, \
CLK_SET_RATE_PARENT)
static AUD_MST_MCLK_GATE(mst_a_mclk, AUDIO_MCLK_A_CTRL);
@@ -168,7 +185,7 @@ static AUD_MST_MCLK_GATE(spdifout_b_clk, AUDIO_CLK_SPDIFOUT_B_CTRL);
/* Sample Clocks */
#define AUD_MST_SCLK_PRE_EN(_name, _reg) \
AUD_GATE(mst_##_name##_sclk_pre_en, _reg, 31, \
- "aud_mst_"#_name"_mclk", 0)
+ aud_mst_##_name##_mclk, 0)
static AUD_MST_SCLK_PRE_EN(a, AUDIO_MST_A_SCLK_CTRL0);
static AUD_MST_SCLK_PRE_EN(b, AUDIO_MST_B_SCLK_CTRL0);
@@ -178,7 +195,7 @@ static AUD_MST_SCLK_PRE_EN(e, AUDIO_MST_E_SCLK_CTRL0);
static AUD_MST_SCLK_PRE_EN(f, AUDIO_MST_F_SCLK_CTRL0);
#define AUD_SCLK_DIV(_name, _reg, _div_shift, _div_width, \
- _hi_shift, _hi_width, _pname, _iflags) \
+ _hi_shift, _hi_width, _phws, _iflags) \
struct clk_regmap aud_##_name = { \
.data = &(struct meson_sclk_div_data) { \
.div = { \
@@ -195,7 +212,7 @@ struct clk_regmap aud_##_name = { \
.hw.init = &(struct clk_init_data) { \
.name = "aud_"#_name, \
.ops = &meson_sclk_div_ops, \
- .parent_names = (const char *[]) { _pname }, \
+ .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \
.num_parents = 1, \
.flags = (_iflags), \
}, \
@@ -203,7 +220,7 @@ struct clk_regmap aud_##_name = { \
#define AUD_MST_SCLK_DIV(_name, _reg) \
AUD_SCLK_DIV(mst_##_name##_sclk_div, _reg, 20, 10, 0, 0, \
- "aud_mst_"#_name"_sclk_pre_en", \
+ aud_mst_##_name##_sclk_pre_en, \
CLK_SET_RATE_PARENT)
static AUD_MST_SCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0);
@@ -214,8 +231,8 @@ static AUD_MST_SCLK_DIV(e, AUDIO_MST_E_SCLK_CTRL0);
static AUD_MST_SCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0);
#define AUD_MST_SCLK_POST_EN(_name, _reg) \
- AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \
- "aud_mst_"#_name"_sclk_div", CLK_SET_RATE_PARENT)
+ AUD_GATE(mst_##_name##_sclk_post_en, _reg, 30, \
+ aud_mst_##_name##_sclk_div, CLK_SET_RATE_PARENT)
static AUD_MST_SCLK_POST_EN(a, AUDIO_MST_A_SCLK_CTRL0);
static AUD_MST_SCLK_POST_EN(b, AUDIO_MST_B_SCLK_CTRL0);
@@ -224,8 +241,8 @@ static AUD_MST_SCLK_POST_EN(d, AUDIO_MST_D_SCLK_CTRL0);
static AUD_MST_SCLK_POST_EN(e, AUDIO_MST_E_SCLK_CTRL0);
static AUD_MST_SCLK_POST_EN(f, AUDIO_MST_F_SCLK_CTRL0);
-#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \
- _pname, _iflags) \
+#define AUD_TRIPHASE(_name, _reg, _width, _shift0, _shift1, _shift2, \
+ _phws, _iflags) \
struct clk_regmap aud_##_name = { \
.data = &(struct meson_clk_triphase_data) { \
.ph0 = { \
@@ -247,7 +264,7 @@ struct clk_regmap aud_##_name = { \
.hw.init = &(struct clk_init_data) { \
.name = "aud_"#_name, \
.ops = &meson_clk_triphase_ops, \
- .parent_names = (const char *[]) { _pname }, \
+ .parent_hws = (const struct clk_hw *[]) { &_phws.hw }, \
.num_parents = 1, \
.flags = CLK_DUTY_CYCLE_PARENT | (_iflags), \
}, \
@@ -255,7 +272,7 @@ struct clk_regmap aud_##_name = { \
#define AUD_MST_SCLK(_name, _reg) \
AUD_TRIPHASE(mst_##_name##_sclk, _reg, 1, 0, 2, 4, \
- "aud_mst_"#_name"_sclk_post_en", CLK_SET_RATE_PARENT)
+ aud_mst_##_name##_sclk_post_en, CLK_SET_RATE_PARENT)
static AUD_MST_SCLK(a, AUDIO_MST_A_SCLK_CTRL1);
static AUD_MST_SCLK(b, AUDIO_MST_B_SCLK_CTRL1);
@@ -266,7 +283,7 @@ static AUD_MST_SCLK(f, AUDIO_MST_F_SCLK_CTRL1);
#define AUD_MST_LRCLK_DIV(_name, _reg) \
AUD_SCLK_DIV(mst_##_name##_lrclk_div, _reg, 0, 10, 10, 10, \
- "aud_mst_"#_name"_sclk_post_en", 0) \
+ aud_mst_##_name##_sclk_post_en, 0) \
static AUD_MST_LRCLK_DIV(a, AUDIO_MST_A_SCLK_CTRL0);
static AUD_MST_LRCLK_DIV(b, AUDIO_MST_B_SCLK_CTRL0);
@@ -277,7 +294,7 @@ static AUD_MST_LRCLK_DIV(f, AUDIO_MST_F_SCLK_CTRL0);
#define AUD_MST_LRCLK(_name, _reg) \
AUD_TRIPHASE(mst_##_name##_lrclk, _reg, 1, 1, 3, 5, \
- "aud_mst_"#_name"_lrclk_div", CLK_SET_RATE_PARENT)
+ aud_mst_##_name##_lrclk_div, CLK_SET_RATE_PARENT)
static AUD_MST_LRCLK(a, AUDIO_MST_A_SCLK_CTRL1);
static AUD_MST_LRCLK(b, AUDIO_MST_B_SCLK_CTRL1);
@@ -286,19 +303,29 @@ static AUD_MST_LRCLK(d, AUDIO_MST_D_SCLK_CTRL1);
static AUD_MST_LRCLK(e, AUDIO_MST_E_SCLK_CTRL1);
static AUD_MST_LRCLK(f, AUDIO_MST_F_SCLK_CTRL1);
-static const char * const tdm_sclk_parent_names[] = {
- "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk",
- "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk",
- "aud_slv_sclk0", "aud_slv_sclk1", "aud_slv_sclk2",
- "aud_slv_sclk3", "aud_slv_sclk4", "aud_slv_sclk5",
- "aud_slv_sclk6", "aud_slv_sclk7", "aud_slv_sclk8",
- "aud_slv_sclk9"
+static const struct clk_parent_data tdm_sclk_parent_data[] = {
+ { .hw = &aud_mst_a_sclk.hw, },
+ { .hw = &aud_mst_b_sclk.hw, },
+ { .hw = &aud_mst_c_sclk.hw, },
+ { .hw = &aud_mst_d_sclk.hw, },
+ { .hw = &aud_mst_e_sclk.hw, },
+ { .hw = &aud_mst_f_sclk.hw, },
+ { .fw_name = "slv_sclk0", },
+ { .fw_name = "slv_sclk1", },
+ { .fw_name = "slv_sclk2", },
+ { .fw_name = "slv_sclk3", },
+ { .fw_name = "slv_sclk4", },
+ { .fw_name = "slv_sclk5", },
+ { .fw_name = "slv_sclk6", },
+ { .fw_name = "slv_sclk7", },
+ { .fw_name = "slv_sclk8", },
+ { .fw_name = "slv_sclk9", },
};
#define AUD_TDM_SCLK_MUX(_name, _reg) \
AUD_MUX(tdm##_name##_sclk_sel, _reg, 0xf, 24, \
CLK_MUX_ROUND_CLOSEST, \
- tdm_sclk_parent_names, 0)
+ tdm_sclk_parent_data, 0)
static AUD_TDM_SCLK_MUX(in_a, AUDIO_CLK_TDMIN_A_CTRL);
static AUD_TDM_SCLK_MUX(in_b, AUDIO_CLK_TDMIN_B_CTRL);
@@ -310,7 +337,7 @@ static AUD_TDM_SCLK_MUX(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
#define AUD_TDM_SCLK_PRE_EN(_name, _reg) \
AUD_GATE(tdm##_name##_sclk_pre_en, _reg, 31, \
- "aud_tdm"#_name"_sclk_sel", CLK_SET_RATE_PARENT)
+ aud_tdm##_name##_sclk_sel, CLK_SET_RATE_PARENT)
static AUD_TDM_SCLK_PRE_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL);
static AUD_TDM_SCLK_PRE_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL);
@@ -322,7 +349,7 @@ static AUD_TDM_SCLK_PRE_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
#define AUD_TDM_SCLK_POST_EN(_name, _reg) \
AUD_GATE(tdm##_name##_sclk_post_en, _reg, 30, \
- "aud_tdm"#_name"_sclk_pre_en", CLK_SET_RATE_PARENT)
+ aud_tdm##_name##_sclk_pre_en, CLK_SET_RATE_PARENT)
static AUD_TDM_SCLK_POST_EN(in_a, AUDIO_CLK_TDMIN_A_CTRL);
static AUD_TDM_SCLK_POST_EN(in_b, AUDIO_CLK_TDMIN_B_CTRL);
@@ -344,8 +371,9 @@ static AUD_TDM_SCLK_POST_EN(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
.hw.init = &(struct clk_init_data) { \
.name = "aud_tdm"#_name"_sclk", \
.ops = &meson_clk_phase_ops, \
- .parent_names = (const char *[]) \
- { "aud_tdm"#_name"_sclk_post_en" }, \
+ .parent_hws = (const struct clk_hw *[]) { \
+ &aud_tdm##_name##_sclk_post_en.hw \
+ }, \
.num_parents = 1, \
.flags = CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT, \
}, \
@@ -359,19 +387,29 @@ static AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
static AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
static AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
-static const char * const tdm_lrclk_parent_names[] = {
- "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk",
- "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk",
- "aud_slv_lrclk0", "aud_slv_lrclk1", "aud_slv_lrclk2",
- "aud_slv_lrclk3", "aud_slv_lrclk4", "aud_slv_lrclk5",
- "aud_slv_lrclk6", "aud_slv_lrclk7", "aud_slv_lrclk8",
- "aud_slv_lrclk9"
+static const struct clk_parent_data tdm_lrclk_parent_data[] = {
+ { .hw = &aud_mst_a_lrclk.hw, },
+ { .hw = &aud_mst_b_lrclk.hw, },
+ { .hw = &aud_mst_c_lrclk.hw, },
+ { .hw = &aud_mst_d_lrclk.hw, },
+ { .hw = &aud_mst_e_lrclk.hw, },
+ { .hw = &aud_mst_f_lrclk.hw, },
+ { .fw_name = "slv_lrclk0", },
+ { .fw_name = "slv_lrclk1", },
+ { .fw_name = "slv_lrclk2", },
+ { .fw_name = "slv_lrclk3", },
+ { .fw_name = "slv_lrclk4", },
+ { .fw_name = "slv_lrclk5", },
+ { .fw_name = "slv_lrclk6", },
+ { .fw_name = "slv_lrclk7", },
+ { .fw_name = "slv_lrclk8", },
+ { .fw_name = "slv_lrclk9", },
};
-#define AUD_TDM_LRLCK(_name, _reg) \
- AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \
- CLK_MUX_ROUND_CLOSEST, \
- tdm_lrclk_parent_names, 0)
+#define AUD_TDM_LRLCK(_name, _reg) \
+ AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \
+ CLK_MUX_ROUND_CLOSEST, \
+ tdm_lrclk_parent_data, 0)
static AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL);
static AUD_TDM_LRLCK(in_b, AUDIO_CLK_TDMIN_B_CTRL);
@@ -386,39 +424,51 @@ static AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
AUD_MUX(tdm_##_name, _reg, 0x7, _shift, 0, _parents, \
CLK_SET_RATE_NO_REPARENT)
-static const char * const mclk_pad_ctrl_parent_names[] = {
- "aud_mst_a_mclk", "aud_mst_b_mclk", "aud_mst_c_mclk",
- "aud_mst_d_mclk", "aud_mst_e_mclk", "aud_mst_f_mclk",
+static const struct clk_parent_data mclk_pad_ctrl_parent_data[] = {
+ { .hw = &aud_mst_a_mclk.hw },
+ { .hw = &aud_mst_b_mclk.hw },
+ { .hw = &aud_mst_c_mclk.hw },
+ { .hw = &aud_mst_d_mclk.hw },
+ { .hw = &aud_mst_e_mclk.hw },
+ { .hw = &aud_mst_f_mclk.hw },
};
static AUD_TDM_PAD_CTRL(mclk_pad_0, AUDIO_MST_PAD_CTRL0, 0,
- mclk_pad_ctrl_parent_names);
+ mclk_pad_ctrl_parent_data);
static AUD_TDM_PAD_CTRL(mclk_pad_1, AUDIO_MST_PAD_CTRL0, 4,
- mclk_pad_ctrl_parent_names);
-
-static const char * const lrclk_pad_ctrl_parent_names[] = {
- "aud_mst_a_lrclk", "aud_mst_b_lrclk", "aud_mst_c_lrclk",
- "aud_mst_d_lrclk", "aud_mst_e_lrclk", "aud_mst_f_lrclk",
+ mclk_pad_ctrl_parent_data);
+
+static const struct clk_parent_data lrclk_pad_ctrl_parent_data[] = {
+ { .hw = &aud_mst_a_lrclk.hw },
+ { .hw = &aud_mst_b_lrclk.hw },
+ { .hw = &aud_mst_c_lrclk.hw },
+ { .hw = &aud_mst_d_lrclk.hw },
+ { .hw = &aud_mst_e_lrclk.hw },
+ { .hw = &aud_mst_f_lrclk.hw },
};
static AUD_TDM_PAD_CTRL(lrclk_pad_0, AUDIO_MST_PAD_CTRL1, 16,
- lrclk_pad_ctrl_parent_names);
+ lrclk_pad_ctrl_parent_data);
static AUD_TDM_PAD_CTRL(lrclk_pad_1, AUDIO_MST_PAD_CTRL1, 20,
- lrclk_pad_ctrl_parent_names);
+ lrclk_pad_ctrl_parent_data);
static AUD_TDM_PAD_CTRL(lrclk_pad_2, AUDIO_MST_PAD_CTRL1, 24,
- lrclk_pad_ctrl_parent_names);
-
-static const char * const sclk_pad_ctrl_parent_names[] = {
- "aud_mst_a_sclk", "aud_mst_b_sclk", "aud_mst_c_sclk",
- "aud_mst_d_sclk", "aud_mst_e_sclk", "aud_mst_f_sclk",
+ lrclk_pad_ctrl_parent_data);
+
+static const struct clk_parent_data sclk_pad_ctrl_parent_data[] = {
+ { .hw = &aud_mst_a_sclk.hw },
+ { .hw = &aud_mst_b_sclk.hw },
+ { .hw = &aud_mst_c_sclk.hw },
+ { .hw = &aud_mst_d_sclk.hw },
+ { .hw = &aud_mst_e_sclk.hw },
+ { .hw = &aud_mst_f_sclk.hw },
};
static AUD_TDM_PAD_CTRL(sclk_pad_0, AUDIO_MST_PAD_CTRL1, 0,
- sclk_pad_ctrl_parent_names);
+ sclk_pad_ctrl_parent_data);
static AUD_TDM_PAD_CTRL(sclk_pad_1, AUDIO_MST_PAD_CTRL1, 4,
- sclk_pad_ctrl_parent_names);
+ sclk_pad_ctrl_parent_data);
static AUD_TDM_PAD_CTRL(sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8,
- sclk_pad_ctrl_parent_names);
+ sclk_pad_ctrl_parent_data);
/*
* Array of all clocks provided by this provider
@@ -868,54 +918,6 @@ static int devm_clk_get_enable(struct device *dev, char *id)
return 0;
}
-static int axg_register_clk_hw_input(struct device *dev,
- const char *name)
-{
- char *clk_name;
- struct clk_hw *hw;
- int err = 0;
-
- clk_name = kasprintf(GFP_KERNEL, "aud_%s", name);
- if (!clk_name)
- return -ENOMEM;
-
- hw = meson_clk_hw_register_input(dev, name, clk_name, 0);
- if (IS_ERR(hw)) {
- /* It is ok if an input clock is missing */
- if (PTR_ERR(hw) == -ENOENT) {
- dev_dbg(dev, "%s not provided", name);
- } else {
- err = PTR_ERR(hw);
- if (err != -EPROBE_DEFER)
- dev_err(dev, "failed to get %s clock", name);
- }
- }
-
- kfree(clk_name);
- return err;
-}
-
-static int axg_register_clk_hw_inputs(struct device *dev,
- const char *basename,
- unsigned int count)
-{
- char *name;
- int i, ret;
-
- for (i = 0; i < count; i++) {
- name = kasprintf(GFP_KERNEL, "%s%d", basename, i);
- if (!name)
- return -ENOMEM;
-
- ret = axg_register_clk_hw_input(dev, name);
- kfree(name);
- if (ret)
- return ret;
- }
-
- return 0;
-}
-
static const struct regmap_config axg_audio_regmap_cfg = {
.reg_bits = 32,
.val_bits = 32,
@@ -963,29 +965,6 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
return ret;
}
- /* Register the peripheral input clock */
- hw = meson_clk_hw_register_input(dev, "pclk", "audio_pclk", 0);
- if (IS_ERR(hw))
- return PTR_ERR(hw);
-
- /* Register optional input master clocks */
- ret = axg_register_clk_hw_inputs(dev, "mst_in",
- AUD_MST_IN_COUNT);
- if (ret)
- return ret;
-
- /* Register optional input slave sclks */
- ret = axg_register_clk_hw_inputs(dev, "slv_sclk",
- AUD_SLV_SCLK_COUNT);
- if (ret)
- return ret;
-
- /* Register optional input slave lrclks */
- ret = axg_register_clk_hw_inputs(dev, "slv_lrclk",
- AUD_SLV_LRCLK_COUNT);
- if (ret)
- return ret;
-
/* Populate regmap for the regmap backed clocks */
for (i = 0; i < ARRAY_SIZE(aud_clk_regmaps); i++)
aud_clk_regmaps[i]->map = map;
--
2.17.1

View File

@ -0,0 +1,240 @@
From 187df4ce3a3b4444407efb45ed5cf082079bc87d Mon Sep 17 00:00:00 2001
From: Alexandre Mergnat <amergnat@baylibre.com>
Date: Thu, 25 Jul 2019 18:41:23 +0200
Subject: [PATCH 004/186] FROMGIT: clk: meson: g12a-aoclk: migrate to the new
parent description method
This clock controller use the string comparison method to describe parent
relation between the clocks, which is not optimized.
Migrate to the new way by using .parent_hws where possible (when parent
clocks are localy declared in the controller) and use .parent_data
otherwise.
Remove clk input helper and all bypass clocks (declared in probe function)
which are no longer used since we are able to use device-tree clock name
directly.
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit ba626081107dceacff554e5ca2efc7cea7326b6e
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/g12a-aoclk.c | 81 +++++++++++++++++++++-------------
1 file changed, 50 insertions(+), 31 deletions(-)
diff --git a/drivers/clk/meson/g12a-aoclk.c b/drivers/clk/meson/g12a-aoclk.c
index 1994e735396b..62499563e4f5 100644
--- a/drivers/clk/meson/g12a-aoclk.c
+++ b/drivers/clk/meson/g12a-aoclk.c
@@ -18,8 +18,6 @@
#include "clk-regmap.h"
#include "clk-dualdiv.h"
-#define IN_PREFIX "ao-in-"
-
/*
* AO Configuration Clock registers offsets
* Register offsets from the data sheet must be multiplied by 4.
@@ -51,7 +49,9 @@ static struct clk_regmap g12a_aoclk_##_name = { \
.hw.init = &(struct clk_init_data) { \
.name = "g12a_ao_" #_name, \
.ops = &clk_regmap_gate_ops, \
- .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
+ .parent_data = &(const struct clk_parent_data) { \
+ .fw_name = "mpeg-clk", \
+ }, \
.num_parents = 1, \
.flags = CLK_IGNORE_UNUSED, \
}, \
@@ -81,7 +81,9 @@ static struct clk_regmap g12a_aoclk_cts_oscin = {
.hw.init = &(struct clk_init_data){
.name = "cts_oscin",
.ops = &clk_regmap_gate_ro_ops,
- .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
.num_parents = 1,
},
};
@@ -106,7 +108,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_pre = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_32k_by_oscin_pre",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "cts_oscin" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &g12a_aoclk_cts_oscin.hw
+ },
.num_parents = 1,
},
};
@@ -143,7 +147,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_div = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_32k_by_oscin_div",
.ops = &meson_clk_dualdiv_ops,
- .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_pre" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &g12a_aoclk_32k_by_oscin_pre.hw
+ },
.num_parents = 1,
},
};
@@ -158,8 +164,10 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin_sel = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_32k_by_oscin_sel",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_div",
- "g12a_ao_32k_by_oscin_pre" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &g12a_aoclk_32k_by_oscin_div.hw,
+ &g12a_aoclk_32k_by_oscin_pre.hw,
+ },
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT,
},
@@ -173,7 +181,9 @@ static struct clk_regmap g12a_aoclk_32k_by_oscin = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_32k_by_oscin",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin_sel" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &g12a_aoclk_32k_by_oscin_sel.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -189,7 +199,9 @@ static struct clk_regmap g12a_aoclk_cec_pre = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_cec_pre",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "cts_oscin" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &g12a_aoclk_cts_oscin.hw
+ },
.num_parents = 1,
},
};
@@ -226,7 +238,9 @@ static struct clk_regmap g12a_aoclk_cec_div = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_cec_div",
.ops = &meson_clk_dualdiv_ops,
- .parent_names = (const char *[]){ "g12a_ao_cec_pre" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &g12a_aoclk_cec_pre.hw
+ },
.num_parents = 1,
},
};
@@ -241,8 +255,10 @@ static struct clk_regmap g12a_aoclk_cec_sel = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_cec_sel",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ "g12a_ao_cec_div",
- "g12a_ao_cec_pre" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &g12a_aoclk_cec_div.hw,
+ &g12a_aoclk_cec_pre.hw,
+ },
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT,
},
@@ -256,7 +272,9 @@ static struct clk_regmap g12a_aoclk_cec = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_cec",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "g12a_ao_cec_sel" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &g12a_aoclk_cec_sel.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -272,8 +290,10 @@ static struct clk_regmap g12a_aoclk_cts_rtc_oscin = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_cts_rtc_oscin",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ "g12a_ao_32k_by_oscin",
- IN_PREFIX "ext_32k-0" },
+ .parent_data = (const struct clk_parent_data []) {
+ { .hw = &g12a_aoclk_32k_by_oscin.hw },
+ { .fw_name = "ext-32k-0", },
+ },
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT,
},
@@ -289,8 +309,10 @@ static struct clk_regmap g12a_aoclk_clk81 = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_clk81",
.ops = &clk_regmap_mux_ro_ops,
- .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
- "g12a_ao_cts_rtc_oscin"},
+ .parent_data = (const struct clk_parent_data []) {
+ { .fw_name = "mpeg-clk", },
+ { .hw = &g12a_aoclk_cts_rtc_oscin.hw },
+ },
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT,
},
@@ -305,8 +327,10 @@ static struct clk_regmap g12a_aoclk_saradc_mux = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_saradc_mux",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ IN_PREFIX "xtal",
- "g12a_ao_clk81" },
+ .parent_data = (const struct clk_parent_data []) {
+ { .fw_name = "xtal", },
+ { .hw = &g12a_aoclk_clk81.hw },
+ },
.num_parents = 2,
},
};
@@ -320,7 +344,9 @@ static struct clk_regmap g12a_aoclk_saradc_div = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_saradc_div",
.ops = &clk_regmap_divider_ops,
- .parent_names = (const char *[]){ "g12a_ao_saradc_mux" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &g12a_aoclk_saradc_mux.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -334,7 +360,9 @@ static struct clk_regmap g12a_aoclk_saradc_gate = {
.hw.init = &(struct clk_init_data){
.name = "g12a_ao_saradc_gate",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "g12a_ao_saradc_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &g12a_aoclk_saradc_div.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -417,12 +445,6 @@ static const struct clk_hw_onecell_data g12a_aoclk_onecell_data = {
.num = NR_CLKS,
};
-static const struct meson_aoclk_input g12a_aoclk_inputs[] = {
- { .name = "xtal", .required = true },
- { .name = "mpeg-clk", .required = true },
- { .name = "ext-32k-0", .required = false },
-};
-
static const struct meson_aoclk_data g12a_aoclkc_data = {
.reset_reg = AO_RTI_GEN_CNTL_REG0,
.num_reset = ARRAY_SIZE(g12a_aoclk_reset),
@@ -430,9 +452,6 @@ static const struct meson_aoclk_data g12a_aoclkc_data = {
.num_clks = ARRAY_SIZE(g12a_aoclk_regmap),
.clks = g12a_aoclk_regmap,
.hw_data = &g12a_aoclk_onecell_data,
- .inputs = g12a_aoclk_inputs,
- .num_inputs = ARRAY_SIZE(g12a_aoclk_inputs),
- .input_prefix = IN_PREFIX,
};
static const struct of_device_id g12a_aoclkc_match_table[] = {
--
2.17.1

View File

@ -0,0 +1,172 @@
From 407d6f2dcb17af68280aee9544316961344a5889 Mon Sep 17 00:00:00 2001
From: Alexandre Mergnat <amergnat@baylibre.com>
Date: Thu, 25 Jul 2019 18:41:24 +0200
Subject: [PATCH 005/186] FROMGIT: clk: meson: gxbb-aoclk: migrate to the new
parent description method
This clock controller use the string comparison method to describe parent
relation between the clocks, which is not optimized.
Migrate to the new way by using .parent_hws where possible (when parent
clocks are localy declared in the controller) and use .parent_data
otherwise.
Remove clk input helper and all bypass clocks (declared in probe function)
which are no longer used since we are able to use device-tree clock name
directly.
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit 6e2bfc352e7a3a9b22f13c36627545d5f4caf3e9
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/gxbb-aoclk.c | 55 +++++++++++++++++-----------------
1 file changed, 27 insertions(+), 28 deletions(-)
diff --git a/drivers/clk/meson/gxbb-aoclk.c b/drivers/clk/meson/gxbb-aoclk.c
index 449f6ac189d8..e940861a396b 100644
--- a/drivers/clk/meson/gxbb-aoclk.c
+++ b/drivers/clk/meson/gxbb-aoclk.c
@@ -11,8 +11,6 @@
#include "clk-regmap.h"
#include "clk-dualdiv.h"
-#define IN_PREFIX "ao-in-"
-
/* AO Configuration Clock registers offsets */
#define AO_RTI_PWR_CNTL_REG1 0x0c
#define AO_RTI_PWR_CNTL_REG0 0x10
@@ -31,7 +29,9 @@ static struct clk_regmap _name##_ao = { \
.hw.init = &(struct clk_init_data) { \
.name = #_name "_ao", \
.ops = &clk_regmap_gate_ops, \
- .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
+ .parent_data = &(const struct clk_parent_data) { \
+ .fw_name = "mpeg-clk", \
+ }, \
.num_parents = 1, \
.flags = CLK_IGNORE_UNUSED, \
}, \
@@ -52,7 +52,9 @@ static struct clk_regmap ao_cts_oscin = {
.hw.init = &(struct clk_init_data){
.name = "ao_cts_oscin",
.ops = &clk_regmap_gate_ro_ops,
- .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
.num_parents = 1,
},
};
@@ -65,7 +67,7 @@ static struct clk_regmap ao_32k_pre = {
.hw.init = &(struct clk_init_data){
.name = "ao_32k_pre",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "ao_cts_oscin" },
+ .parent_hws = (const struct clk_hw *[]) { &ao_cts_oscin.hw },
.num_parents = 1,
},
};
@@ -112,7 +114,7 @@ static struct clk_regmap ao_32k_div = {
.hw.init = &(struct clk_init_data){
.name = "ao_32k_div",
.ops = &meson_clk_dualdiv_ops,
- .parent_names = (const char *[]){ "ao_32k_pre" },
+ .parent_hws = (const struct clk_hw *[]) { &ao_32k_pre.hw },
.num_parents = 1,
},
};
@@ -127,8 +129,10 @@ static struct clk_regmap ao_32k_sel = {
.hw.init = &(struct clk_init_data){
.name = "ao_32k_sel",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ "ao_32k_div",
- "ao_32k_pre" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &ao_32k_div.hw,
+ &ao_32k_pre.hw
+ },
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT,
},
@@ -142,7 +146,7 @@ static struct clk_regmap ao_32k = {
.hw.init = &(struct clk_init_data){
.name = "ao_32k",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "ao_32k_sel" },
+ .parent_hws = (const struct clk_hw *[]) { &ao_32k_sel.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -159,10 +163,12 @@ static struct clk_regmap ao_cts_rtc_oscin = {
.hw.init = &(struct clk_init_data){
.name = "ao_cts_rtc_oscin",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ IN_PREFIX "ext-32k-0",
- IN_PREFIX "ext-32k-1",
- IN_PREFIX "ext-32k-2",
- "ao_32k" },
+ .parent_data = (const struct clk_parent_data []) {
+ { .fw_name = "ext-32k-0", },
+ { .fw_name = "ext-32k-1", },
+ { .fw_name = "ext-32k-2", },
+ { .hw = &ao_32k.hw },
+ },
.num_parents = 4,
.flags = CLK_SET_RATE_PARENT,
},
@@ -178,8 +184,10 @@ static struct clk_regmap ao_clk81 = {
.hw.init = &(struct clk_init_data){
.name = "ao_clk81",
.ops = &clk_regmap_mux_ro_ops,
- .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
- "ao_cts_rtc_oscin" },
+ .parent_data = (const struct clk_parent_data []) {
+ { .fw_name = "mpeg-clk", },
+ { .hw = &ao_cts_rtc_oscin.hw },
+ },
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT,
},
@@ -208,8 +216,10 @@ static struct clk_regmap ao_cts_cec = {
* Until CCF gets fixed, adding this fake parent that won't
* ever be registered should work around the problem
*/
- .parent_names = (const char *[]){ "fixme",
- "ao_cts_rtc_oscin" },
+ .parent_data = (const struct clk_parent_data []) {
+ { .name = "fixme", .index = -1, },
+ { .hw = &ao_cts_rtc_oscin.hw },
+ },
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT,
},
@@ -261,14 +271,6 @@ static const struct clk_hw_onecell_data gxbb_aoclk_onecell_data = {
.num = NR_CLKS,
};
-static const struct meson_aoclk_input gxbb_aoclk_inputs[] = {
- { .name = "xtal", .required = true, },
- { .name = "mpeg-clk", .required = true, },
- {. name = "ext-32k-0", .required = false, },
- {. name = "ext-32k-1", .required = false, },
- {. name = "ext-32k-2", .required = false, },
-};
-
static const struct meson_aoclk_data gxbb_aoclkc_data = {
.reset_reg = AO_RTI_GEN_CNTL_REG0,
.num_reset = ARRAY_SIZE(gxbb_aoclk_reset),
@@ -276,9 +278,6 @@ static const struct meson_aoclk_data gxbb_aoclkc_data = {
.num_clks = ARRAY_SIZE(gxbb_aoclk),
.clks = gxbb_aoclk,
.hw_data = &gxbb_aoclk_onecell_data,
- .inputs = gxbb_aoclk_inputs,
- .num_inputs = ARRAY_SIZE(gxbb_aoclk_inputs),
- .input_prefix = IN_PREFIX,
};
static const struct of_device_id gxbb_aoclkc_match_table[] = {
--
2.17.1

View File

@ -0,0 +1,194 @@
From a1d4a324255c10d7fcb33270f81a365f40c05f84 Mon Sep 17 00:00:00 2001
From: Alexandre Mergnat <amergnat@baylibre.com>
Date: Thu, 25 Jul 2019 18:41:25 +0200
Subject: [PATCH 006/186] FROMGIT: clk: meson: axg-aoclk: migrate to the new
parent description method
This clock controller use the string comparison method to describe parent
relation between the clocks, which is not optimized.
Migrate to the new way by using .parent_hws where possible (when parent
clocks are localy declared in the controller) and use .parent_data
otherwise.
Remove clk input helper and all bypass clocks (declared in probe function)
which are no longer used since we are able to use device-tree clock name
directly.
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit b90ec1e344a2dd4c1afebd75c1ce05afaf9e116b
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/axg-aoclk.c | 63 ++++++++++++++++++++---------------
1 file changed, 37 insertions(+), 26 deletions(-)
diff --git a/drivers/clk/meson/axg-aoclk.c b/drivers/clk/meson/axg-aoclk.c
index 0086f31288eb..b488b40c9d0e 100644
--- a/drivers/clk/meson/axg-aoclk.c
+++ b/drivers/clk/meson/axg-aoclk.c
@@ -18,8 +18,6 @@
#include "clk-regmap.h"
#include "clk-dualdiv.h"
-#define IN_PREFIX "ao-in-"
-
/*
* AO Configuration Clock registers offsets
* Register offsets from the data sheet must be multiplied by 4.
@@ -42,7 +40,9 @@ static struct clk_regmap axg_aoclk_##_name = { \
.hw.init = &(struct clk_init_data) { \
.name = "axg_ao_" #_name, \
.ops = &clk_regmap_gate_ops, \
- .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk" }, \
+ .parent_data = &(const struct clk_parent_data) { \
+ .fw_name = "mpeg-clk", \
+ }, \
.num_parents = 1, \
.flags = CLK_IGNORE_UNUSED, \
}, \
@@ -64,7 +64,9 @@ static struct clk_regmap axg_aoclk_cts_oscin = {
.hw.init = &(struct clk_init_data){
.name = "cts_oscin",
.ops = &clk_regmap_gate_ro_ops,
- .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
.num_parents = 1,
},
};
@@ -77,7 +79,9 @@ static struct clk_regmap axg_aoclk_32k_pre = {
.hw.init = &(struct clk_init_data){
.name = "axg_ao_32k_pre",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "cts_oscin" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_aoclk_cts_oscin.hw
+ },
.num_parents = 1,
},
};
@@ -124,7 +128,9 @@ static struct clk_regmap axg_aoclk_32k_div = {
.hw.init = &(struct clk_init_data){
.name = "axg_ao_32k_div",
.ops = &meson_clk_dualdiv_ops,
- .parent_names = (const char *[]){ "axg_ao_32k_pre" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_aoclk_32k_pre.hw
+ },
.num_parents = 1,
},
};
@@ -139,8 +145,10 @@ static struct clk_regmap axg_aoclk_32k_sel = {
.hw.init = &(struct clk_init_data){
.name = "axg_ao_32k_sel",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ "axg_ao_32k_div",
- "axg_ao_32k_pre" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_aoclk_32k_div.hw,
+ &axg_aoclk_32k_pre.hw,
+ },
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT,
},
@@ -154,7 +162,9 @@ static struct clk_regmap axg_aoclk_32k = {
.hw.init = &(struct clk_init_data){
.name = "axg_ao_32k",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "axg_ao_32k_sel" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_aoclk_32k_sel.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -170,8 +180,10 @@ static struct clk_regmap axg_aoclk_cts_rtc_oscin = {
.hw.init = &(struct clk_init_data){
.name = "axg_ao_cts_rtc_oscin",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ "axg_ao_32k",
- IN_PREFIX "ext_32k-0" },
+ .parent_data = (const struct clk_parent_data []) {
+ { .hw = &axg_aoclk_32k.hw },
+ { .fw_name = "ext_32k-0", },
+ },
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT,
},
@@ -187,8 +199,10 @@ static struct clk_regmap axg_aoclk_clk81 = {
.hw.init = &(struct clk_init_data){
.name = "axg_ao_clk81",
.ops = &clk_regmap_mux_ro_ops,
- .parent_names = (const char *[]){ IN_PREFIX "mpeg-clk",
- "axg_ao_cts_rtc_oscin"},
+ .parent_data = (const struct clk_parent_data []) {
+ { .fw_name = "mpeg-clk", },
+ { .hw = &axg_aoclk_cts_rtc_oscin.hw },
+ },
.num_parents = 2,
.flags = CLK_SET_RATE_PARENT,
},
@@ -203,8 +217,10 @@ static struct clk_regmap axg_aoclk_saradc_mux = {
.hw.init = &(struct clk_init_data){
.name = "axg_ao_saradc_mux",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ IN_PREFIX "xtal",
- "axg_ao_clk81" },
+ .parent_data = (const struct clk_parent_data []) {
+ { .fw_name = "xtal", },
+ { .hw = &axg_aoclk_clk81.hw },
+ },
.num_parents = 2,
},
};
@@ -218,7 +234,9 @@ static struct clk_regmap axg_aoclk_saradc_div = {
.hw.init = &(struct clk_init_data){
.name = "axg_ao_saradc_div",
.ops = &clk_regmap_divider_ops,
- .parent_names = (const char *[]){ "axg_ao_saradc_mux" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_aoclk_saradc_mux.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -232,7 +250,9 @@ static struct clk_regmap axg_aoclk_saradc_gate = {
.hw.init = &(struct clk_init_data){
.name = "axg_ao_saradc_gate",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "axg_ao_saradc_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_aoclk_saradc_div.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -290,12 +310,6 @@ static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
.num = NR_CLKS,
};
-static const struct meson_aoclk_input axg_aoclk_inputs[] = {
- { .name = "xtal", .required = true },
- { .name = "mpeg-clk", .required = true },
- { .name = "ext-32k-0", .required = false },
-};
-
static const struct meson_aoclk_data axg_aoclkc_data = {
.reset_reg = AO_RTI_GEN_CNTL_REG0,
.num_reset = ARRAY_SIZE(axg_aoclk_reset),
@@ -303,9 +317,6 @@ static const struct meson_aoclk_data axg_aoclkc_data = {
.num_clks = ARRAY_SIZE(axg_aoclk_regmap),
.clks = axg_aoclk_regmap,
.hw_data = &axg_aoclk_onecell_data,
- .inputs = axg_aoclk_inputs,
- .num_inputs = ARRAY_SIZE(axg_aoclk_inputs),
- .input_prefix = IN_PREFIX,
};
static const struct of_device_id axg_aoclkc_match_table[] = {
--
2.17.1

View File

@ -0,0 +1,130 @@
From 6faf769562fb26a5b7865727a01067817910de4f Mon Sep 17 00:00:00 2001
From: Alexandre Mergnat <amergnat@baylibre.com>
Date: Thu, 25 Jul 2019 18:41:26 +0200
Subject: [PATCH 007/186] FROMGIT: clk: meson: remove ao input bypass clocks
During probe, bypass clocks (i.e. ao-in-xtal) are made from device-tree
inputs to provide input clocks which can be access through global name.
The cons of this method are the duplicated clocks, means more string
comparison.
Specify parent directly with device-tree clock name.
Function to regiter bypass clocks is removed.
Input parameters from meson aoclk data structure are deprecated and then
deleted since all aoclk files are migrated.
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit 072a043f5a2e02441002fff34e3885e6026714eb
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/Kconfig | 1 -
drivers/clk/meson/meson-aoclk.c | 37 ---------------------------------
drivers/clk/meson/meson-aoclk.h | 8 -------
3 files changed, 46 deletions(-)
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index ee0b84b6b329..178ee72ba4bc 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -33,7 +33,6 @@ config COMMON_CLK_MESON_VID_PLL_DIV
config COMMON_CLK_MESON_AO_CLKC
tristate
select COMMON_CLK_MESON_REGMAP
- select COMMON_CLK_MESON_INPUT
select RESET_CONTROLLER
config COMMON_CLK_MESON_EE_CLKC
diff --git a/drivers/clk/meson/meson-aoclk.c b/drivers/clk/meson/meson-aoclk.c
index b67951909e04..bf8bea675d24 100644
--- a/drivers/clk/meson/meson-aoclk.c
+++ b/drivers/clk/meson/meson-aoclk.c
@@ -17,8 +17,6 @@
#include <linux/slab.h>
#include "meson-aoclk.h"
-#include "clk-input.h"
-
static int meson_aoclk_do_reset(struct reset_controller_dev *rcdev,
unsigned long id)
{
@@ -33,37 +31,6 @@ static const struct reset_control_ops meson_aoclk_reset_ops = {
.reset = meson_aoclk_do_reset,
};
-static int meson_aoclkc_register_inputs(struct device *dev,
- struct meson_aoclk_data *data)
-{
- struct clk_hw *hw;
- char *str;
- int i;
-
- for (i = 0; i < data->num_inputs; i++) {
- const struct meson_aoclk_input *in = &data->inputs[i];
-
- str = kasprintf(GFP_KERNEL, "%s%s", data->input_prefix,
- in->name);
- if (!str)
- return -ENOMEM;
-
- hw = meson_clk_hw_register_input(dev, in->name, str, 0);
- kfree(str);
-
- if (IS_ERR(hw)) {
- if (!in->required && PTR_ERR(hw) == -ENOENT)
- continue;
- else if (PTR_ERR(hw) != -EPROBE_DEFER)
- dev_err(dev, "failed to register input %s\n",
- in->name);
- return PTR_ERR(hw);
- }
- }
-
- return 0;
-}
-
int meson_aoclkc_probe(struct platform_device *pdev)
{
struct meson_aoclk_reset_controller *rstc;
@@ -86,10 +53,6 @@ int meson_aoclkc_probe(struct platform_device *pdev)
return PTR_ERR(regmap);
}
- ret = meson_aoclkc_register_inputs(dev, data);
- if (ret)
- return ret;
-
/* Reset Controller */
rstc->data = data;
rstc->regmap = regmap;
diff --git a/drivers/clk/meson/meson-aoclk.h b/drivers/clk/meson/meson-aoclk.h
index 999cde3868f7..605b43855a69 100644
--- a/drivers/clk/meson/meson-aoclk.h
+++ b/drivers/clk/meson/meson-aoclk.h
@@ -18,20 +18,12 @@
#include "clk-regmap.h"
-struct meson_aoclk_input {
- const char *name;
- bool required;
-};
-
struct meson_aoclk_data {
const unsigned int reset_reg;
const int num_reset;
const unsigned int *reset;
const int num_clks;
struct clk_regmap **clks;
- const int num_inputs;
- const struct meson_aoclk_input *inputs;
- const char *input_prefix;
const struct clk_hw_onecell_data *hw_data;
};
--
2.17.1

View File

@ -0,0 +1,579 @@
From 742b86907dc0a2e79d98081fd535f331c2a3632a Mon Sep 17 00:00:00 2001
From: Alexandre Mergnat <amergnat@baylibre.com>
Date: Thu, 25 Jul 2019 18:42:34 +0200
Subject: [PATCH 010/186] FROMGIT: clk: meson: axg: migrate to the new parent
description method
This clock controller use the string comparison method to describe parent
relation between the clocks, which is not optimized.
Migrate to the new way by using .parent_hws where possible (ie. when
all clocks are local to the controller) and use .parent_data otherwise.
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit cc132d113dc589d8449fe2b53043b0f17029acac
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/axg.c | 204 ++++++++++++++++++++++++++++------------
1 file changed, 144 insertions(+), 60 deletions(-)
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 3ddd0efc9ee0..7a3d795cc614 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -14,7 +14,6 @@
#include <linux/of_device.h>
#include <linux/platform_device.h>
-#include "clk-input.h"
#include "clk-regmap.h"
#include "clk-pll.h"
#include "clk-mpll.h"
@@ -59,7 +58,9 @@ static struct clk_regmap axg_fixed_pll_dco = {
.hw.init = &(struct clk_init_data){
.name = "fixed_pll_dco",
.ops = &meson_clk_pll_ro_ops,
- .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
.num_parents = 1,
},
};
@@ -74,7 +75,9 @@ static struct clk_regmap axg_fixed_pll = {
.hw.init = &(struct clk_init_data){
.name = "fixed_pll",
.ops = &clk_regmap_divider_ro_ops,
- .parent_names = (const char *[]){ "fixed_pll_dco" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_fixed_pll_dco.hw
+ },
.num_parents = 1,
/*
* This clock won't ever change at runtime so
@@ -114,7 +117,9 @@ static struct clk_regmap axg_sys_pll_dco = {
.hw.init = &(struct clk_init_data){
.name = "sys_pll_dco",
.ops = &meson_clk_pll_ro_ops,
- .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
.num_parents = 1,
},
};
@@ -129,7 +134,9 @@ static struct clk_regmap axg_sys_pll = {
.hw.init = &(struct clk_init_data){
.name = "sys_pll",
.ops = &clk_regmap_divider_ro_ops,
- .parent_names = (const char *[]){ "sys_pll_dco" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_sys_pll_dco.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -215,7 +222,9 @@ static struct clk_regmap axg_gp0_pll_dco = {
.hw.init = &(struct clk_init_data){
.name = "gp0_pll_dco",
.ops = &meson_clk_pll_ops,
- .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
.num_parents = 1,
},
};
@@ -230,7 +239,9 @@ static struct clk_regmap axg_gp0_pll = {
.hw.init = &(struct clk_init_data){
.name = "gp0_pll",
.ops = &clk_regmap_divider_ops,
- .parent_names = (const char *[]){ "gp0_pll_dco" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_gp0_pll_dco.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -284,7 +295,9 @@ static struct clk_regmap axg_hifi_pll_dco = {
.hw.init = &(struct clk_init_data){
.name = "hifi_pll_dco",
.ops = &meson_clk_pll_ops,
- .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
.num_parents = 1,
},
};
@@ -299,7 +312,9 @@ static struct clk_regmap axg_hifi_pll = {
.hw.init = &(struct clk_init_data){
.name = "hifi_pll",
.ops = &clk_regmap_divider_ops,
- .parent_names = (const char *[]){ "hifi_pll_dco" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_hifi_pll_dco.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -311,7 +326,7 @@ static struct clk_fixed_factor axg_fclk_div2_div = {
.hw.init = &(struct clk_init_data){
.name = "fclk_div2_div",
.ops = &clk_fixed_factor_ops,
- .parent_names = (const char *[]){ "fixed_pll" },
+ .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
.num_parents = 1,
},
};
@@ -324,7 +339,9 @@ static struct clk_regmap axg_fclk_div2 = {
.hw.init = &(struct clk_init_data){
.name = "fclk_div2",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "fclk_div2_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_fclk_div2_div.hw
+ },
.num_parents = 1,
.flags = CLK_IS_CRITICAL,
},
@@ -336,7 +353,7 @@ static struct clk_fixed_factor axg_fclk_div3_div = {
.hw.init = &(struct clk_init_data){
.name = "fclk_div3_div",
.ops = &clk_fixed_factor_ops,
- .parent_names = (const char *[]){ "fixed_pll" },
+ .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
.num_parents = 1,
},
};
@@ -349,7 +366,9 @@ static struct clk_regmap axg_fclk_div3 = {
.hw.init = &(struct clk_init_data){
.name = "fclk_div3",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "fclk_div3_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_fclk_div3_div.hw
+ },
.num_parents = 1,
/*
* FIXME:
@@ -372,7 +391,7 @@ static struct clk_fixed_factor axg_fclk_div4_div = {
.hw.init = &(struct clk_init_data){
.name = "fclk_div4_div",
.ops = &clk_fixed_factor_ops,
- .parent_names = (const char *[]){ "fixed_pll" },
+ .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
.num_parents = 1,
},
};
@@ -385,7 +404,9 @@ static struct clk_regmap axg_fclk_div4 = {
.hw.init = &(struct clk_init_data){
.name = "fclk_div4",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "fclk_div4_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_fclk_div4_div.hw
+ },
.num_parents = 1,
},
};
@@ -396,7 +417,7 @@ static struct clk_fixed_factor axg_fclk_div5_div = {
.hw.init = &(struct clk_init_data){
.name = "fclk_div5_div",
.ops = &clk_fixed_factor_ops,
- .parent_names = (const char *[]){ "fixed_pll" },
+ .parent_hws = (const struct clk_hw *[]) { &axg_fixed_pll.hw },
.num_parents = 1,
},
};
@@ -409,7 +430,9 @@ static struct clk_regmap axg_fclk_div5 = {
.hw.init = &(struct clk_init_data){
.name = "fclk_div5",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "fclk_div5_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_fclk_div5_div.hw
+ },
.num_parents = 1,
},
};
@@ -420,7 +443,9 @@ static struct clk_fixed_factor axg_fclk_div7_div = {
.hw.init = &(struct clk_init_data){
.name = "fclk_div7_div",
.ops = &clk_fixed_factor_ops,
- .parent_names = (const char *[]){ "fixed_pll" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_fixed_pll.hw
+ },
.num_parents = 1,
},
};
@@ -433,7 +458,9 @@ static struct clk_regmap axg_fclk_div7 = {
.hw.init = &(struct clk_init_data){
.name = "fclk_div7",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "fclk_div7_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_fclk_div7_div.hw
+ },
.num_parents = 1,
},
};
@@ -447,7 +474,9 @@ static struct clk_regmap axg_mpll_prediv = {
.hw.init = &(struct clk_init_data){
.name = "mpll_prediv",
.ops = &clk_regmap_divider_ro_ops,
- .parent_names = (const char *[]){ "fixed_pll" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_fixed_pll.hw
+ },
.num_parents = 1,
},
};
@@ -480,7 +509,9 @@ static struct clk_regmap axg_mpll0_div = {
.hw.init = &(struct clk_init_data){
.name = "mpll0_div",
.ops = &meson_clk_mpll_ops,
- .parent_names = (const char *[]){ "mpll_prediv" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_mpll_prediv.hw
+ },
.num_parents = 1,
},
};
@@ -493,7 +524,9 @@ static struct clk_regmap axg_mpll0 = {
.hw.init = &(struct clk_init_data){
.name = "mpll0",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "mpll0_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_mpll0_div.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -527,7 +560,9 @@ static struct clk_regmap axg_mpll1_div = {
.hw.init = &(struct clk_init_data){
.name = "mpll1_div",
.ops = &meson_clk_mpll_ops,
- .parent_names = (const char *[]){ "mpll_prediv" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_mpll_prediv.hw
+ },
.num_parents = 1,
},
};
@@ -540,7 +575,9 @@ static struct clk_regmap axg_mpll1 = {
.hw.init = &(struct clk_init_data){
.name = "mpll1",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "mpll1_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_mpll1_div.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -579,7 +616,9 @@ static struct clk_regmap axg_mpll2_div = {
.hw.init = &(struct clk_init_data){
.name = "mpll2_div",
.ops = &meson_clk_mpll_ops,
- .parent_names = (const char *[]){ "mpll_prediv" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_mpll_prediv.hw
+ },
.num_parents = 1,
},
};
@@ -592,7 +631,9 @@ static struct clk_regmap axg_mpll2 = {
.hw.init = &(struct clk_init_data){
.name = "mpll2",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "mpll2_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_mpll2_div.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -626,7 +667,9 @@ static struct clk_regmap axg_mpll3_div = {
.hw.init = &(struct clk_init_data){
.name = "mpll3_div",
.ops = &meson_clk_mpll_ops,
- .parent_names = (const char *[]){ "mpll_prediv" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_mpll_prediv.hw
+ },
.num_parents = 1,
},
};
@@ -639,7 +682,9 @@ static struct clk_regmap axg_mpll3 = {
.hw.init = &(struct clk_init_data){
.name = "mpll3",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "mpll3_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_mpll3_div.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -702,7 +747,9 @@ static struct clk_regmap axg_pcie_pll_dco = {
.hw.init = &(struct clk_init_data){
.name = "pcie_pll_dco",
.ops = &meson_clk_pll_ops,
- .parent_names = (const char *[]){ IN_PREFIX "xtal" },
+ .parent_data = &(const struct clk_parent_data) {
+ .fw_name = "xtal",
+ },
.num_parents = 1,
},
};
@@ -717,7 +764,9 @@ static struct clk_regmap axg_pcie_pll_od = {
.hw.init = &(struct clk_init_data){
.name = "pcie_pll_od",
.ops = &clk_regmap_divider_ops,
- .parent_names = (const char *[]){ "pcie_pll_dco" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_pcie_pll_dco.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -733,7 +782,9 @@ static struct clk_regmap axg_pcie_pll = {
.hw.init = &(struct clk_init_data){
.name = "pcie_pll",
.ops = &clk_regmap_divider_ops,
- .parent_names = (const char *[]){ "pcie_pll_od" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_pcie_pll_od.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -750,7 +801,7 @@ static struct clk_regmap axg_pcie_mux = {
.hw.init = &(struct clk_init_data){
.name = "pcie_mux",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ "pcie_pll" },
+ .parent_hws = (const struct clk_hw *[]) { &axg_pcie_pll.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -767,7 +818,7 @@ static struct clk_regmap axg_pcie_ref = {
.hw.init = &(struct clk_init_data){
.name = "pcie_ref",
.ops = &clk_regmap_mux_ops,
- .parent_names = (const char *[]){ "pcie_mux" },
+ .parent_hws = (const struct clk_hw *[]) { &axg_pcie_mux.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -781,7 +832,7 @@ static struct clk_regmap axg_pcie_cml_en0 = {
.hw.init = &(struct clk_init_data) {
.name = "pcie_cml_en0",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "pcie_ref" },
+ .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
@@ -796,16 +847,21 @@ static struct clk_regmap axg_pcie_cml_en1 = {
.hw.init = &(struct clk_init_data) {
.name = "pcie_cml_en1",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "pcie_ref" },
+ .parent_hws = (const struct clk_hw *[]) { &axg_pcie_ref.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
-static const char * const clk81_parent_names[] = {
- IN_PREFIX "xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
- "fclk_div3", "fclk_div5"
+static const struct clk_parent_data clk81_parent_data[] = {
+ { .fw_name = "xtal", },
+ { .hw = &axg_fclk_div7.hw },
+ { .hw = &axg_mpll1.hw },
+ { .hw = &axg_mpll2.hw },
+ { .hw = &axg_fclk_div4.hw },
+ { .hw = &axg_fclk_div3.hw },
+ { .hw = &axg_fclk_div5.hw },
};
static struct clk_regmap axg_mpeg_clk_sel = {
@@ -818,8 +874,8 @@ static struct clk_regmap axg_mpeg_clk_sel = {
.hw.init = &(struct clk_init_data){
.name = "mpeg_clk_sel",
.ops = &clk_regmap_mux_ro_ops,
- .parent_names = clk81_parent_names,
- .num_parents = ARRAY_SIZE(clk81_parent_names),
+ .parent_data = clk81_parent_data,
+ .num_parents = ARRAY_SIZE(clk81_parent_data),
},
};
@@ -832,7 +888,9 @@ static struct clk_regmap axg_mpeg_clk_div = {
.hw.init = &(struct clk_init_data){
.name = "mpeg_clk_div",
.ops = &clk_regmap_divider_ops,
- .parent_names = (const char *[]){ "mpeg_clk_sel" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_mpeg_clk_sel.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -846,15 +904,20 @@ static struct clk_regmap axg_clk81 = {
.hw.init = &(struct clk_init_data){
.name = "clk81",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "mpeg_clk_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_mpeg_clk_div.hw
+ },
.num_parents = 1,
.flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
},
};
-static const char * const axg_sd_emmc_clk0_parent_names[] = {
- IN_PREFIX "xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
-
+static const struct clk_parent_data axg_sd_emmc_clk0_parent_data[] = {
+ { .fw_name = "xtal", },
+ { .hw = &axg_fclk_div2.hw },
+ { .hw = &axg_fclk_div3.hw },
+ { .hw = &axg_fclk_div5.hw },
+ { .hw = &axg_fclk_div7.hw },
/*
* Following these parent clocks, we should also have had mpll2, mpll3
* and gp0_pll but these clocks are too precious to be used here. All
@@ -873,8 +936,8 @@ static struct clk_regmap axg_sd_emmc_b_clk0_sel = {
.hw.init = &(struct clk_init_data) {
.name = "sd_emmc_b_clk0_sel",
.ops = &clk_regmap_mux_ops,
- .parent_names = axg_sd_emmc_clk0_parent_names,
- .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
+ .parent_data = axg_sd_emmc_clk0_parent_data,
+ .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data),
.flags = CLK_SET_RATE_PARENT,
},
};
@@ -889,7 +952,9 @@ static struct clk_regmap axg_sd_emmc_b_clk0_div = {
.hw.init = &(struct clk_init_data) {
.name = "sd_emmc_b_clk0_div",
.ops = &clk_regmap_divider_ops,
- .parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_sd_emmc_b_clk0_sel.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -903,7 +968,9 @@ static struct clk_regmap axg_sd_emmc_b_clk0 = {
.hw.init = &(struct clk_init_data){
.name = "sd_emmc_b_clk0",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_sd_emmc_b_clk0_div.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -919,8 +986,8 @@ static struct clk_regmap axg_sd_emmc_c_clk0_sel = {
.hw.init = &(struct clk_init_data) {
.name = "sd_emmc_c_clk0_sel",
.ops = &clk_regmap_mux_ops,
- .parent_names = axg_sd_emmc_clk0_parent_names,
- .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
+ .parent_data = axg_sd_emmc_clk0_parent_data,
+ .num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_data),
.flags = CLK_SET_RATE_PARENT,
},
};
@@ -935,7 +1002,9 @@ static struct clk_regmap axg_sd_emmc_c_clk0_div = {
.hw.init = &(struct clk_init_data) {
.name = "sd_emmc_c_clk0_div",
.ops = &clk_regmap_divider_ops,
- .parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_sd_emmc_c_clk0_sel.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -949,7 +1018,9 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
.hw.init = &(struct clk_init_data){
.name = "sd_emmc_c_clk0",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_sd_emmc_c_clk0_div.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -957,9 +1028,18 @@ static struct clk_regmap axg_sd_emmc_c_clk0 = {
static u32 mux_table_gen_clk[] = { 0, 4, 5, 6, 7, 8,
9, 10, 11, 13, 14, };
-static const char * const gen_clk_parent_names[] = {
- IN_PREFIX "xtal", "hifi_pll", "mpll0", "mpll1", "mpll2", "mpll3",
- "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7", "gp0_pll",
+static const struct clk_parent_data gen_clk_parent_data[] = {
+ { .fw_name = "xtal", },
+ { .hw = &axg_hifi_pll.hw },
+ { .hw = &axg_mpll0.hw },
+ { .hw = &axg_mpll1.hw },
+ { .hw = &axg_mpll2.hw },
+ { .hw = &axg_mpll3.hw },
+ { .hw = &axg_fclk_div4.hw },
+ { .hw = &axg_fclk_div3.hw },
+ { .hw = &axg_fclk_div5.hw },
+ { .hw = &axg_fclk_div7.hw },
+ { .hw = &axg_gp0_pll.hw },
};
static struct clk_regmap axg_gen_clk_sel = {
@@ -978,8 +1058,8 @@ static struct clk_regmap axg_gen_clk_sel = {
* hifi_pll, mpll0, mpll1, mpll2, mpll3, fdiv4,
* fdiv3, fdiv5, [cts_msr_clk], fdiv7, gp0_pll
*/
- .parent_names = gen_clk_parent_names,
- .num_parents = ARRAY_SIZE(gen_clk_parent_names),
+ .parent_data = gen_clk_parent_data,
+ .num_parents = ARRAY_SIZE(gen_clk_parent_data),
},
};
@@ -992,7 +1072,9 @@ static struct clk_regmap axg_gen_clk_div = {
.hw.init = &(struct clk_init_data){
.name = "gen_clk_div",
.ops = &clk_regmap_divider_ops,
- .parent_names = (const char *[]){ "gen_clk_sel" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_gen_clk_sel.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
@@ -1006,7 +1088,9 @@ static struct clk_regmap axg_gen_clk = {
.hw.init = &(struct clk_init_data){
.name = "gen_clk",
.ops = &clk_regmap_gate_ops,
- .parent_names = (const char *[]){ "gen_clk_div" },
+ .parent_hws = (const struct clk_hw *[]) {
+ &axg_gen_clk_div.hw
+ },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
--
2.17.1

View File

@ -0,0 +1,121 @@
From 0cfea924293edf3953e835dba72988839b69c05f Mon Sep 17 00:00:00 2001
From: Alexandre Mergnat <amergnat@baylibre.com>
Date: Thu, 25 Jul 2019 18:42:36 +0200
Subject: [PATCH 012/186] FROMGIT: clk: meson: clk-regmap: migrate to new
parent description method
This clock controller use the string comparison method to describe parent
relation between the clocks, which is not optimized.
Migrate to the new way by using .parent_hws where possible (ie. when
all clocks are local to the controller) and use .parent_data otherwise.
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit 3a36044e7f3909c7ddb7ddfc727ab8104a563439
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/axg.c | 3 +++
drivers/clk/meson/clk-regmap.h | 12 ++++++------
drivers/clk/meson/g12a.c | 6 ++++++
drivers/clk/meson/gxbb.c | 3 +++
drivers/clk/meson/meson8b.c | 3 +++
5 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/meson/axg.c b/drivers/clk/meson/axg.c
index 7a3d795cc614..13fc0006f63d 100644
--- a/drivers/clk/meson/axg.c
+++ b/drivers/clk/meson/axg.c
@@ -1096,6 +1096,9 @@ static struct clk_regmap axg_gen_clk = {
},
};
+#define MESON_GATE(_name, _reg, _bit) \
+ MESON_PCLK(_name, _reg, _bit, &axg_clk81.hw)
+
/* Everything Else (EE) domain gates */
static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0);
static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2);
diff --git a/drivers/clk/meson/clk-regmap.h b/drivers/clk/meson/clk-regmap.h
index 1dd0abe3ba91..c4a39604cffd 100644
--- a/drivers/clk/meson/clk-regmap.h
+++ b/drivers/clk/meson/clk-regmap.h
@@ -111,7 +111,7 @@ clk_get_regmap_mux_data(struct clk_regmap *clk)
extern const struct clk_ops clk_regmap_mux_ops;
extern const struct clk_ops clk_regmap_mux_ro_ops;
-#define __MESON_GATE(_name, _reg, _bit, _ops) \
+#define __MESON_PCLK(_name, _reg, _bit, _ops, _pname) \
struct clk_regmap _name = { \
.data = &(struct clk_regmap_gate_data){ \
.offset = (_reg), \
@@ -120,15 +120,15 @@ struct clk_regmap _name = { \
.hw.init = &(struct clk_init_data) { \
.name = #_name, \
.ops = _ops, \
- .parent_names = (const char *[]){ "clk81" }, \
+ .parent_hws = (const struct clk_hw *[]) { _pname }, \
.num_parents = 1, \
.flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), \
}, \
}
-#define MESON_GATE(_name, _reg, _bit) \
- __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ops)
+#define MESON_PCLK(_name, _reg, _bit, _pname) \
+ __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ops, _pname)
-#define MESON_GATE_RO(_name, _reg, _bit) \
- __MESON_GATE(_name, _reg, _bit, &clk_regmap_gate_ro_ops)
+#define MESON_PCLK_RO(_name, _reg, _bit, _pname) \
+ __MESON_PCLK(_name, _reg, _bit, &clk_regmap_gate_ro_ops, _pname)
#endif /* __CLK_REGMAP_H */
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index 8cc7f5acf7ab..a8f706de811b 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -3325,6 +3325,12 @@ static struct clk_regmap g12a_ts = {
},
};
+#define MESON_GATE(_name, _reg, _bit) \
+ MESON_PCLK(_name, _reg, _bit, &g12a_clk81.hw)
+
+#define MESON_GATE_RO(_name, _reg, _bit) \
+ MESON_PCLK_RO(_name, _reg, _bit, &g12a_clk81.hw)
+
/* Everything Else (EE) domain gates */
static MESON_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0);
static MESON_GATE(g12a_dos, HHI_GCLK_MPEG0, 1);
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
index 67e466356d4b..7cfb998eeb3e 100644
--- a/drivers/clk/meson/gxbb.c
+++ b/drivers/clk/meson/gxbb.c
@@ -2587,6 +2587,9 @@ static struct clk_regmap gxbb_gen_clk = {
},
};
+#define MESON_GATE(_name, _reg, _bit) \
+ MESON_PCLK(_name, _reg, _bit, &gxbb_clk81.hw)
+
/* Everything Else (EE) domain gates */
static MESON_GATE(gxbb_ddr, HHI_GCLK_MPEG0, 0);
static MESON_GATE(gxbb_dos, HHI_GCLK_MPEG0, 1);
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c
index b30279a5bfcc..67e6691e080c 100644
--- a/drivers/clk/meson/meson8b.c
+++ b/drivers/clk/meson/meson8b.c
@@ -2564,6 +2564,9 @@ static struct clk_regmap meson8b_cts_i958 = {
},
};
+#define MESON_GATE(_name, _reg, _bit) \
+ MESON_PCLK(_name, _reg, _bit, &meson8b_clk81.hw)
+
/* Everything Else (EE) domain gates */
static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
--
2.17.1

View File

@ -0,0 +1,88 @@
From f6353b89b99dfe51f7b98bb91f0f2ea61e7a85b3 Mon Sep 17 00:00:00 2001
From: Alexandre Mergnat <amergnat@baylibre.com>
Date: Thu, 25 Jul 2019 18:42:37 +0200
Subject: [PATCH 013/186] FROMGIT: clk: meson: remove ee input bypass clocks
During probe, bypass clocks (i.e. ee-in-xtal) are made from device-tree
inputs to provide input clocks which can be access through global name.
The cons of this method are the duplicated clocks, means more string
comparison.
Specify parent directly with device-tree clock name.
Remove the bypass clock registration from the ee probe function.
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit b11cfaba5b4d6e287540a3d64c403e5b26dd2728
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/Kconfig | 1 -
drivers/clk/meson/meson-eeclk.c | 10 ----------
drivers/clk/meson/meson-eeclk.h | 2 --
3 files changed, 13 deletions(-)
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 178ee72ba4bc..72a37572501f 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -38,7 +38,6 @@ config COMMON_CLK_MESON_AO_CLKC
config COMMON_CLK_MESON_EE_CLKC
tristate
select COMMON_CLK_MESON_REGMAP
- select COMMON_CLK_MESON_INPUT
config COMMON_CLK_MESON8B
bool
diff --git a/drivers/clk/meson/meson-eeclk.c b/drivers/clk/meson/meson-eeclk.c
index 6ba2094be257..a7cb1e7aedc4 100644
--- a/drivers/clk/meson/meson-eeclk.c
+++ b/drivers/clk/meson/meson-eeclk.c
@@ -10,7 +10,6 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
-#include "clk-input.h"
#include "clk-regmap.h"
#include "meson-eeclk.h"
@@ -18,7 +17,6 @@ int meson_eeclkc_probe(struct platform_device *pdev)
{
const struct meson_eeclkc_data *data;
struct device *dev = &pdev->dev;
- struct clk_hw *input;
struct regmap *map;
int ret, i;
@@ -37,14 +35,6 @@ int meson_eeclkc_probe(struct platform_device *pdev)
if (data->init_count)
regmap_multi_reg_write(map, data->init_regs, data->init_count);
- input = meson_clk_hw_register_input(dev, "xtal", IN_PREFIX "xtal", 0);
- if (IS_ERR(input)) {
- ret = PTR_ERR(input);
- if (ret != -EPROBE_DEFER)
- dev_err(dev, "failed to get input clock");
- return ret;
- }
-
/* Populate regmap for the regmap backed clocks */
for (i = 0; i < data->regmap_clk_num; i++)
data->regmap_clks[i]->map = map;
diff --git a/drivers/clk/meson/meson-eeclk.h b/drivers/clk/meson/meson-eeclk.h
index 9ab5d6fa7ccb..77316207bde1 100644
--- a/drivers/clk/meson/meson-eeclk.h
+++ b/drivers/clk/meson/meson-eeclk.h
@@ -10,8 +10,6 @@
#include <linux/clk-provider.h>
#include "clk-regmap.h"
-#define IN_PREFIX "ee-in-"
-
struct platform_device;
struct meson_eeclkc_data {
--
2.17.1

View File

@ -0,0 +1,130 @@
From 7da31180caf32e166a7bbb896918f0fd4ec2e996 Mon Sep 17 00:00:00 2001
From: Alexandre Mergnat <amergnat@baylibre.com>
Date: Thu, 25 Jul 2019 18:42:38 +0200
Subject: [PATCH 014/186] FROMGIT: clk: meson: remove clk input helper
The clk input function which allows clock controllers to register a bypass
clock from a clock producer is no longer needed anymore since meson clock
controllers have migrated to a new parent allocation method.
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit e96c7612315a1183e12d5b6ebd523a3a93617510
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/Kconfig | 3 ---
drivers/clk/meson/Makefile | 1 -
drivers/clk/meson/clk-input.c | 49 -----------------------------------
drivers/clk/meson/clk-input.h | 19 --------------
4 files changed, 72 deletions(-)
delete mode 100644 drivers/clk/meson/clk-input.c
delete mode 100644 drivers/clk/meson/clk-input.h
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 72a37572501f..500be0b0d473 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -1,7 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only
-config COMMON_CLK_MESON_INPUT
- tristate
-
config COMMON_CLK_MESON_REGMAP
tristate
select REGMAP
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index bc35a4efd6b7..f09d83dc3d60 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -4,7 +4,6 @@
obj-$(CONFIG_COMMON_CLK_MESON_AO_CLKC) += meson-aoclk.o
obj-$(CONFIG_COMMON_CLK_MESON_DUALDIV) += clk-dualdiv.o
obj-$(CONFIG_COMMON_CLK_MESON_EE_CLKC) += meson-eeclk.o
-obj-$(CONFIG_COMMON_CLK_MESON_INPUT) += clk-input.o
obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o
obj-$(CONFIG_COMMON_CLK_MESON_PHASE) += clk-phase.o
obj-$(CONFIG_COMMON_CLK_MESON_PLL) += clk-pll.o
diff --git a/drivers/clk/meson/clk-input.c b/drivers/clk/meson/clk-input.c
deleted file mode 100644
index 086226e9dba6..000000000000
--- a/drivers/clk/meson/clk-input.c
+++ /dev/null
@@ -1,49 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0 OR MIT)
-/*
- * Copyright (c) 2018 BayLibre, SAS.
- * Author: Jerome Brunet <jbrunet@baylibre.com>
- */
-
-#include <linux/clk.h>
-#include <linux/clk-provider.h>
-#include <linux/device.h>
-#include <linux/module.h>
-#include "clk-input.h"
-
-static const struct clk_ops meson_clk_no_ops = {};
-
-struct clk_hw *meson_clk_hw_register_input(struct device *dev,
- const char *of_name,
- const char *clk_name,
- unsigned long flags)
-{
- struct clk *parent_clk = devm_clk_get(dev, of_name);
- struct clk_init_data init;
- const char *parent_name;
- struct clk_hw *hw;
- int ret;
-
- if (IS_ERR(parent_clk))
- return (struct clk_hw *)parent_clk;
-
- hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
- if (!hw)
- return ERR_PTR(-ENOMEM);
-
- parent_name = __clk_get_name(parent_clk);
- init.name = clk_name;
- init.ops = &meson_clk_no_ops;
- init.flags = flags;
- init.parent_names = &parent_name;
- init.num_parents = 1;
- hw->init = &init;
-
- ret = devm_clk_hw_register(dev, hw);
-
- return ret ? ERR_PTR(ret) : hw;
-}
-EXPORT_SYMBOL_GPL(meson_clk_hw_register_input);
-
-MODULE_DESCRIPTION("Amlogic clock input helper");
-MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-input.h b/drivers/clk/meson/clk-input.h
deleted file mode 100644
index 4a541b9685a6..000000000000
--- a/drivers/clk/meson/clk-input.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (c) 2019 BayLibre, SAS.
- * Author: Jerome Brunet <jbrunet@baylibre.com>
- */
-
-#ifndef __MESON_CLK_INPUT_H
-#define __MESON_CLK_INPUT_H
-
-#include <linux/clk-provider.h>
-
-struct device;
-
-struct clk_hw *meson_clk_hw_register_input(struct device *dev,
- const char *of_name,
- const char *clk_name,
- unsigned long flags);
-
-#endif /* __MESON_CLK_INPUT_H */
--
2.17.1

View File

@ -0,0 +1,56 @@
From dc9ff799c4ae81fc4279d622036eb2a7044d2ae1 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 31 Jul 2019 10:40:16 +0200
Subject: [PATCH 015/186] FROMGIT: clk: core: introduce clk_hw_set_parent()
Introduce the clk_hw_set_parent() provider call to change parent of
a clock by using the clk_hw pointers.
This eases the clock reparenting from clock rate notifiers and
implementing DVFS with simpler code avoiding the boilerplates
functions as __clk_lookup(clk_hw_get_name()) then clk_set_parent().
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Acked-by: Stephen Boyd <sboyd@kernel.org>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit 3567894b6914813299300019e028874927210880
https://github.com/BayLibre/clk-meson v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/clk.c | 6 ++++++
include/linux/clk-provider.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index 1c46babeb093..ca99e9db6575 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -2510,6 +2510,12 @@ static int clk_core_set_parent_nolock(struct clk_core *core,
return ret;
}
+int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *parent)
+{
+ return clk_core_set_parent_nolock(hw->core, parent->core);
+}
+EXPORT_SYMBOL_GPL(clk_hw_set_parent);
+
/**
* clk_set_parent - switch the parent of a mux clk
* @clk: the mux clk whose input we are switching
diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h
index 2ae7604783dd..dce5521a9bf6 100644
--- a/include/linux/clk-provider.h
+++ b/include/linux/clk-provider.h
@@ -817,6 +817,7 @@ unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
unsigned int index);
+int clk_hw_set_parent(struct clk_hw *hw, struct clk_hw *new_parent);
unsigned int __clk_get_enable_count(struct clk *clk);
unsigned long clk_hw_get_rate(const struct clk_hw *hw);
unsigned long __clk_get_flags(struct clk *clk);
--
2.17.1

View File

@ -0,0 +1,170 @@
From 6ff05d5114e4073db11738008cdfa6fb81c5e7aa Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 31 Jul 2019 10:40:17 +0200
Subject: [PATCH 016/186] FROMGIT: clk: meson: add g12a cpu dynamic divider
driver
Add a clock driver for the cpu dynamic divider, this divider needs
to have a flag set before setting the divider value then removed
while writing the new value to the register.
This drivers implements this behavior and will be used essentially
on the Amlogic G12A and G12B SoCs for cpu clock trees.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit 26d34431add04a98a60b8935c25765914fa773f7
https://github.com/BayLibre/clk-meson v5.4/drivers)
---
drivers/clk/meson/Kconfig | 5 ++
drivers/clk/meson/Makefile | 1 +
drivers/clk/meson/clk-cpu-dyndiv.c | 73 ++++++++++++++++++++++++++++++
drivers/clk/meson/clk-cpu-dyndiv.h | 20 ++++++++
4 files changed, 99 insertions(+)
create mode 100644 drivers/clk/meson/clk-cpu-dyndiv.c
create mode 100644 drivers/clk/meson/clk-cpu-dyndiv.h
diff --git a/drivers/clk/meson/Kconfig b/drivers/clk/meson/Kconfig
index 500be0b0d473..dabeb435d067 100644
--- a/drivers/clk/meson/Kconfig
+++ b/drivers/clk/meson/Kconfig
@@ -36,6 +36,10 @@ config COMMON_CLK_MESON_EE_CLKC
tristate
select COMMON_CLK_MESON_REGMAP
+config COMMON_CLK_MESON_CPU_DYNDIV
+ tristate
+ select COMMON_CLK_MESON_REGMAP
+
config COMMON_CLK_MESON8B
bool
depends on ARCH_MESON
@@ -98,6 +102,7 @@ config COMMON_CLK_G12A
select COMMON_CLK_MESON_PLL
select COMMON_CLK_MESON_AO_CLKC
select COMMON_CLK_MESON_EE_CLKC
+ select COMMON_CLK_MESON_CPU_DYNDIV
select MFD_SYSCON
help
Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
index f09d83dc3d60..3939f218587a 100644
--- a/drivers/clk/meson/Makefile
+++ b/drivers/clk/meson/Makefile
@@ -2,6 +2,7 @@
# Amlogic clock drivers
obj-$(CONFIG_COMMON_CLK_MESON_AO_CLKC) += meson-aoclk.o
+obj-$(CONFIG_COMMON_CLK_MESON_CPU_DYNDIV) += clk-cpu-dyndiv.o
obj-$(CONFIG_COMMON_CLK_MESON_DUALDIV) += clk-dualdiv.o
obj-$(CONFIG_COMMON_CLK_MESON_EE_CLKC) += meson-eeclk.o
obj-$(CONFIG_COMMON_CLK_MESON_MPLL) += clk-mpll.o
diff --git a/drivers/clk/meson/clk-cpu-dyndiv.c b/drivers/clk/meson/clk-cpu-dyndiv.c
new file mode 100644
index 000000000000..36976927fe82
--- /dev/null
+++ b/drivers/clk/meson/clk-cpu-dyndiv.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+
+#include "clk-regmap.h"
+#include "clk-cpu-dyndiv.h"
+
+static inline struct meson_clk_cpu_dyndiv_data *
+meson_clk_cpu_dyndiv_data(struct clk_regmap *clk)
+{
+ return (struct meson_clk_cpu_dyndiv_data *)clk->data;
+}
+
+static unsigned long meson_clk_cpu_dyndiv_recalc_rate(struct clk_hw *hw,
+ unsigned long prate)
+{
+ struct clk_regmap *clk = to_clk_regmap(hw);
+ struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk);
+
+ return divider_recalc_rate(hw, prate,
+ meson_parm_read(clk->map, &data->div),
+ NULL, 0, data->div.width);
+}
+
+static long meson_clk_cpu_dyndiv_round_rate(struct clk_hw *hw,
+ unsigned long rate,
+ unsigned long *prate)
+{
+ struct clk_regmap *clk = to_clk_regmap(hw);
+ struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk);
+
+ return divider_round_rate(hw, rate, prate, NULL, data->div.width, 0);
+}
+
+static int meson_clk_cpu_dyndiv_set_rate(struct clk_hw *hw, unsigned long rate,
+ unsigned long parent_rate)
+{
+ struct clk_regmap *clk = to_clk_regmap(hw);
+ struct meson_clk_cpu_dyndiv_data *data = meson_clk_cpu_dyndiv_data(clk);
+ unsigned int val;
+ int ret;
+
+ ret = divider_get_val(rate, parent_rate, NULL, data->div.width, 0);
+ if (ret < 0)
+ return ret;
+
+ val = (unsigned int)ret << data->div.shift;
+
+ /* Write the SYS_CPU_DYN_ENABLE bit before changing the divider */
+ meson_parm_write(clk->map, &data->dyn, 1);
+
+ /* Update the divider while removing the SYS_CPU_DYN_ENABLE bit */
+ return regmap_update_bits(clk->map, data->div.reg_off,
+ SETPMASK(data->div.width, data->div.shift) |
+ SETPMASK(data->dyn.width, data->dyn.shift),
+ val);
+};
+
+const struct clk_ops meson_clk_cpu_dyndiv_ops = {
+ .recalc_rate = meson_clk_cpu_dyndiv_recalc_rate,
+ .round_rate = meson_clk_cpu_dyndiv_round_rate,
+ .set_rate = meson_clk_cpu_dyndiv_set_rate,
+};
+EXPORT_SYMBOL_GPL(meson_clk_cpu_dyndiv_ops);
+
+MODULE_DESCRIPTION("Amlogic CPU Dynamic Clock divider");
+MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/meson/clk-cpu-dyndiv.h b/drivers/clk/meson/clk-cpu-dyndiv.h
new file mode 100644
index 000000000000..f4908404792e
--- /dev/null
+++ b/drivers/clk/meson/clk-cpu-dyndiv.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#ifndef __MESON_CLK_CPU_DYNDIV_H
+#define __MESON_CLK_CPU_DYNDIV_H
+
+#include <linux/clk-provider.h>
+#include "parm.h"
+
+struct meson_clk_cpu_dyndiv_data {
+ struct parm div;
+ struct parm dyn;
+};
+
+extern const struct clk_ops meson_clk_cpu_dyndiv_ops;
+
+#endif /* __MESON_CLK_CPU_DYNDIV_H */
--
2.17.1

View File

@ -0,0 +1,872 @@
From 89141a5825cfa0672ee737d17027987b5a1a5b60 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 31 Jul 2019 10:40:18 +0200
Subject: [PATCH 017/186] FROMGIT: clk: meson: g12a: add notifiers to handle
cpu clock change
In order to implement clock switching for the CLKID_CPU_CLK and
CLKID_CPUB_CLK, notifiers are added on specific points of the
clock tree :
cpu_clk / cpub_clk
| \- cpu_clk_dyn
| | \- cpu_clk_premux0
| | |- cpu_clk_postmux0
| | | |- cpu_clk_dyn0_div
| | | \- xtal/fclk_div2/fclk_div3
| | \- xtal/fclk_div2/fclk_div3
| \- cpu_clk_premux1
| |- cpu_clk_postmux1
| | |- cpu_clk_dyn1_div
| | \- xtal/fclk_div2/fclk_div3
| \- xtal/fclk_div2/fclk_div3
\ sys_pll / sys1_pll
This for each cluster, a single one for G12A, two for G12B.
Each cpu_clk_premux1 tree is marked as read-only and CLK_SET_RATE_NO_REPARENT,
to be used as "parking" clock in a safe clock frequency.
A notifier is added on each cpu_clk_premux0 to detech when CCF want to
change the frequency of the cpu_clk_dyn tree.
In this notifier, the cpu_clk_premux1 tree is configured to use the xtal
clock and then the cpu_clk_dyn is switch to cpu_clk_premux1 while CCF
updates the cpu_clk_premux0 tree.
A notifier is added on each sys_pll/sys1_pll to detect when CCF wants to
change the PLL clock source of the cpu_clk.
In this notifier, the cpu_clk is switched to cpu_clk_dyn while CCF
updates the sys_pll/sys1_pll frequency.
A third small notifier is added on each cpu_clk / cpub_clk and cpu_clk_dyn,
add a small delay at PRE_RATE_CHANGE/POST_RATE_CHANGE to let the other
notofiers change propagate before changing the cpu_clk_premux0 and sys_pll
clock trees.
This notifier set permits switching the cpu_clk / cpub_clk without any
glitches and using a safe parking clock while switching between sub-GHz
clocks using the cpu_clk_dyn tree.
This setup has been tested and validated on the Amlogic G12A and G12B
SoCs running the arm64 cpuburn at [1] and cycling between all the possible
cpufreq translations of each cluster and checking the final frequency using
the clock-measurer, script at [2].
[1] https://github.com/ssvb/cpuburn-arm/blob/master/cpuburn-a53.S
[2] https://gist.github.com/superna9999/d4de964dbc0f84b7d527e1df2ddea25f
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit ffae8475b90c045ca508675794c08a0c8c12d202
https://github.com/BayLibre/clk-meson v5.4/drivers)
---
drivers/clk/meson/g12a.c | 535 +++++++++++++++++++++++++++++++++++----
1 file changed, 481 insertions(+), 54 deletions(-)
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index a8f706de811b..c3f0ffc3280d 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -14,10 +14,12 @@
#include <linux/init.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
#include "clk-mpll.h"
#include "clk-pll.h"
#include "clk-regmap.h"
+#include "clk-cpu-dyndiv.h"
#include "vid-pll-div.h"
#include "meson-eeclk.h"
#include "g12a.h"
@@ -88,16 +90,9 @@ static struct clk_regmap g12a_fixed_pll = {
},
};
-/*
- * Internal sys pll emulation configuration parameters
- */
-static const struct reg_sequence g12a_sys_init_regs[] = {
- { .reg = HHI_SYS_PLL_CNTL1, .def = 0x00000000 },
- { .reg = HHI_SYS_PLL_CNTL2, .def = 0x00000000 },
- { .reg = HHI_SYS_PLL_CNTL3, .def = 0x48681c00 },
- { .reg = HHI_SYS_PLL_CNTL4, .def = 0x88770290 },
- { .reg = HHI_SYS_PLL_CNTL5, .def = 0x39272000 },
- { .reg = HHI_SYS_PLL_CNTL6, .def = 0x56540000 },
+static const struct pll_mult_range g12a_sys_pll_mult_range = {
+ .min = 128,
+ .max = 250,
};
static struct clk_regmap g12a_sys_pll_dco = {
@@ -127,16 +122,17 @@ static struct clk_regmap g12a_sys_pll_dco = {
.shift = 29,
.width = 1,
},
- .init_regs = g12a_sys_init_regs,
- .init_count = ARRAY_SIZE(g12a_sys_init_regs),
+ .range = &g12a_sys_pll_mult_range,
},
.hw.init = &(struct clk_init_data){
.name = "sys_pll_dco",
- .ops = &meson_clk_pll_ro_ops,
+ .ops = &meson_clk_pll_ops,
.parent_data = &(const struct clk_parent_data) {
.fw_name = "xtal",
},
.num_parents = 1,
+ /* This clock feeds the CPU, avoid disabling it */
+ .flags = CLK_IS_CRITICAL,
},
};
@@ -149,11 +145,12 @@ static struct clk_regmap g12a_sys_pll = {
},
.hw.init = &(struct clk_init_data){
.name = "sys_pll",
- .ops = &clk_regmap_divider_ro_ops,
+ .ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12a_sys_pll_dco.hw
},
.num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -184,14 +181,17 @@ static struct clk_regmap g12b_sys1_pll_dco = {
.shift = 29,
.width = 1,
},
+ .range = &g12a_sys_pll_mult_range,
},
.hw.init = &(struct clk_init_data){
.name = "sys1_pll_dco",
- .ops = &meson_clk_pll_ro_ops,
+ .ops = &meson_clk_pll_ops,
.parent_data = &(const struct clk_parent_data) {
.fw_name = "xtal",
},
.num_parents = 1,
+ /* This clock feeds the CPU, avoid disabling it */
+ .flags = CLK_IS_CRITICAL,
},
};
@@ -204,11 +204,12 @@ static struct clk_regmap g12b_sys1_pll = {
},
.hw.init = &(struct clk_init_data){
.name = "sys1_pll",
- .ops = &clk_regmap_divider_ro_ops,
+ .ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12b_sys1_pll_dco.hw
},
.num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -345,13 +346,15 @@ static struct clk_regmap g12a_cpu_clk_premux0 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn0_sel",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal", },
{ .hw = &g12a_fclk_div2.hw },
{ .hw = &g12a_fclk_div3.hw },
},
.num_parents = 3,
+ /* This sub-tree is used a parking clock */
+ .flags = CLK_SET_RATE_NO_REPARENT,
},
};
@@ -364,30 +367,40 @@ static struct clk_regmap g12a_cpu_clk_premux1 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn1_sel",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal", },
{ .hw = &g12a_fclk_div2.hw },
{ .hw = &g12a_fclk_div3.hw },
},
.num_parents = 3,
+ /* This sub-tree is used a parking clock */
+ .flags = CLK_SET_RATE_NO_REPARENT
},
};
/* Datasheet names this field as "mux0_divn_tcnt" */
static struct clk_regmap g12a_cpu_clk_mux0_div = {
- .data = &(struct clk_regmap_div_data){
- .offset = HHI_SYS_CPU_CLK_CNTL0,
- .shift = 4,
- .width = 6,
+ .data = &(struct meson_clk_cpu_dyndiv_data){
+ .div = {
+ .reg_off = HHI_SYS_CPU_CLK_CNTL0,
+ .shift = 4,
+ .width = 6,
+ },
+ .dyn = {
+ .reg_off = HHI_SYS_CPU_CLK_CNTL0,
+ .shift = 26,
+ .width = 1,
+ },
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn0_div",
- .ops = &clk_regmap_divider_ro_ops,
+ .ops = &meson_clk_cpu_dyndiv_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12a_cpu_clk_premux0.hw
},
.num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -400,12 +413,13 @@ static struct clk_regmap g12a_cpu_clk_postmux0 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn0",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12a_cpu_clk_premux0.hw,
&g12a_cpu_clk_mux0_div.hw,
},
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -435,12 +449,14 @@ static struct clk_regmap g12a_cpu_clk_postmux1 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn1",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12a_cpu_clk_premux1.hw,
&g12a_cpu_clk_mux1_div.hw,
},
.num_parents = 2,
+ /* This sub-tree is used a parking clock */
+ .flags = CLK_SET_RATE_NO_REPARENT,
},
};
@@ -453,12 +469,13 @@ static struct clk_regmap g12a_cpu_clk_dyn = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk_dyn",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12a_cpu_clk_postmux0.hw,
&g12a_cpu_clk_postmux1.hw,
},
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -471,12 +488,13 @@ static struct clk_regmap g12a_cpu_clk = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12a_cpu_clk_dyn.hw,
&g12a_sys_pll.hw,
},
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -489,12 +507,13 @@ static struct clk_regmap g12b_cpu_clk = {
},
.hw.init = &(struct clk_init_data){
.name = "cpu_clk",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12a_cpu_clk_dyn.hw,
&g12b_sys1_pll.hw
},
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -507,7 +526,7 @@ static struct clk_regmap g12b_cpub_clk_premux0 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn0_sel",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal", },
{ .hw = &g12a_fclk_div2.hw },
@@ -519,18 +538,26 @@ static struct clk_regmap g12b_cpub_clk_premux0 = {
/* Datasheet names this field as "mux0_divn_tcnt" */
static struct clk_regmap g12b_cpub_clk_mux0_div = {
- .data = &(struct clk_regmap_div_data){
- .offset = HHI_SYS_CPUB_CLK_CNTL,
- .shift = 4,
- .width = 6,
+ .data = &(struct meson_clk_cpu_dyndiv_data){
+ .div = {
+ .reg_off = HHI_SYS_CPUB_CLK_CNTL,
+ .shift = 4,
+ .width = 6,
+ },
+ .dyn = {
+ .reg_off = HHI_SYS_CPUB_CLK_CNTL,
+ .shift = 26,
+ .width = 1,
+ },
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn0_div",
- .ops = &clk_regmap_divider_ro_ops,
+ .ops = &meson_clk_cpu_dyndiv_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12b_cpub_clk_premux0.hw
},
.num_parents = 1,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -543,12 +570,13 @@ static struct clk_regmap g12b_cpub_clk_postmux0 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn0",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12b_cpub_clk_premux0.hw,
&g12b_cpub_clk_mux0_div.hw
},
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -561,13 +589,15 @@ static struct clk_regmap g12b_cpub_clk_premux1 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn1_sel",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal", },
{ .hw = &g12a_fclk_div2.hw },
{ .hw = &g12a_fclk_div3.hw },
},
.num_parents = 3,
+ /* This sub-tree is used a parking clock */
+ .flags = CLK_SET_RATE_NO_REPARENT,
},
};
@@ -597,12 +627,14 @@ static struct clk_regmap g12b_cpub_clk_postmux1 = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn1",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12b_cpub_clk_premux1.hw,
&g12b_cpub_clk_mux1_div.hw
},
.num_parents = 2,
+ /* This sub-tree is used a parking clock */
+ .flags = CLK_SET_RATE_NO_REPARENT,
},
};
@@ -615,12 +647,13 @@ static struct clk_regmap g12b_cpub_clk_dyn = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk_dyn",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12b_cpub_clk_postmux0.hw,
&g12b_cpub_clk_postmux1.hw
},
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
@@ -633,15 +666,227 @@ static struct clk_regmap g12b_cpub_clk = {
},
.hw.init = &(struct clk_init_data){
.name = "cpub_clk",
- .ops = &clk_regmap_mux_ro_ops,
+ .ops = &clk_regmap_mux_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12b_cpub_clk_dyn.hw,
&g12a_sys_pll.hw
},
.num_parents = 2,
+ .flags = CLK_SET_RATE_PARENT,
},
};
+static int g12a_cpu_clk_mux_notifier_cb(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ if (event == POST_RATE_CHANGE || event == PRE_RATE_CHANGE) {
+ /* Wait for clock propagation before/after changing the mux */
+ udelay(100);
+ return NOTIFY_OK;
+ }
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block g12a_cpu_clk_mux_nb = {
+ .notifier_call = g12a_cpu_clk_mux_notifier_cb,
+};
+
+struct g12a_cpu_clk_postmux_nb_data {
+ struct notifier_block nb;
+ struct clk_hw *xtal;
+ struct clk_hw *cpu_clk_dyn;
+ struct clk_hw *cpu_clk_postmux0;
+ struct clk_hw *cpu_clk_postmux1;
+ struct clk_hw *cpu_clk_premux1;
+};
+
+static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct g12a_cpu_clk_postmux_nb_data *nb_data =
+ container_of(nb, struct g12a_cpu_clk_postmux_nb_data, nb);
+
+ switch (event) {
+ case PRE_RATE_CHANGE:
+ /*
+ * This notifier means cpu_clk_postmux0 clock will be changed
+ * to feed cpu_clk, this is the current path :
+ * cpu_clk
+ * \- cpu_clk_dyn
+ * \- cpu_clk_postmux0
+ * \- cpu_clk_muxX_div
+ * \- cpu_clk_premux0
+ * \- fclk_div3 or fclk_div2
+ * OR
+ * \- cpu_clk_premux0
+ * \- fclk_div3 or fclk_div2
+ */
+
+ /* Setup cpu_clk_premux1 to xtal */
+ clk_hw_set_parent(nb_data->cpu_clk_premux1,
+ nb_data->xtal);
+
+ /* Setup cpu_clk_postmux1 to bypass divider */
+ clk_hw_set_parent(nb_data->cpu_clk_postmux1,
+ nb_data->cpu_clk_premux1);
+
+ /* Switch to parking clk on cpu_clk_postmux1 */
+ clk_hw_set_parent(nb_data->cpu_clk_dyn,
+ nb_data->cpu_clk_postmux1);
+
+ /*
+ * Now, cpu_clk is 24MHz in the current path :
+ * cpu_clk
+ * \- cpu_clk_dyn
+ * \- cpu_clk_postmux1
+ * \- cpu_clk_premux1
+ * \- xtal
+ */
+
+ udelay(100);
+
+ return NOTIFY_OK;
+
+ case POST_RATE_CHANGE:
+ /*
+ * The cpu_clk_postmux0 has ben updated, now switch back
+ * cpu_clk_dyn to cpu_clk_postmux0 and take the changes
+ * in account.
+ */
+
+ /* Configure cpu_clk_dyn back to cpu_clk_postmux0 */
+ clk_hw_set_parent(nb_data->cpu_clk_dyn,
+ nb_data->cpu_clk_postmux0);
+
+ /*
+ * new path :
+ * cpu_clk
+ * \- cpu_clk_dyn
+ * \- cpu_clk_postmux0
+ * \- cpu_clk_muxX_div
+ * \- cpu_clk_premux0
+ * \- fclk_div3 or fclk_div2
+ * OR
+ * \- cpu_clk_premux0
+ * \- fclk_div3 or fclk_div2
+ */
+
+ udelay(100);
+
+ return NOTIFY_OK;
+
+ default:
+ return NOTIFY_DONE;
+ }
+}
+
+static struct g12a_cpu_clk_postmux_nb_data g12a_cpu_clk_postmux0_nb_data = {
+ .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+ .cpu_clk_postmux0 = &g12a_cpu_clk_postmux0.hw,
+ .cpu_clk_postmux1 = &g12a_cpu_clk_postmux1.hw,
+ .cpu_clk_premux1 = &g12a_cpu_clk_premux1.hw,
+ .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb,
+};
+
+static struct g12a_cpu_clk_postmux_nb_data g12b_cpub_clk_postmux0_nb_data = {
+ .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw,
+ .cpu_clk_postmux0 = &g12b_cpub_clk_postmux0.hw,
+ .cpu_clk_postmux1 = &g12b_cpub_clk_postmux1.hw,
+ .cpu_clk_premux1 = &g12b_cpub_clk_premux1.hw,
+ .nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb,
+};
+
+struct g12a_sys_pll_nb_data {
+ struct notifier_block nb;
+ struct clk_hw *sys_pll;
+ struct clk_hw *cpu_clk;
+ struct clk_hw *cpu_clk_dyn;
+};
+
+static int g12a_sys_pll_notifier_cb(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ struct g12a_sys_pll_nb_data *nb_data =
+ container_of(nb, struct g12a_sys_pll_nb_data, nb);
+
+ switch (event) {
+ case PRE_RATE_CHANGE:
+ /*
+ * This notifier means sys_pll clock will be changed
+ * to feed cpu_clk, this the current path :
+ * cpu_clk
+ * \- sys_pll
+ * \- sys_pll_dco
+ */
+
+ /* Configure cpu_clk to use cpu_clk_dyn */
+ clk_hw_set_parent(nb_data->cpu_clk,
+ nb_data->cpu_clk_dyn);
+
+ /*
+ * Now, cpu_clk uses the dyn path
+ * cpu_clk
+ * \- cpu_clk_dyn
+ * \- cpu_clk_dynX
+ * \- cpu_clk_dynX_sel
+ * \- cpu_clk_dynX_div
+ * \- xtal/fclk_div2/fclk_div3
+ * \- xtal/fclk_div2/fclk_div3
+ */
+
+ udelay(100);
+
+ return NOTIFY_OK;
+
+ case POST_RATE_CHANGE:
+ /*
+ * The sys_pll has ben updated, now switch back cpu_clk to
+ * sys_pll
+ */
+
+ /* Configure cpu_clk to use sys_pll */
+ clk_hw_set_parent(nb_data->cpu_clk,
+ nb_data->sys_pll);
+
+ udelay(100);
+
+ /* new path :
+ * cpu_clk
+ * \- sys_pll
+ * \- sys_pll_dco
+ */
+
+ return NOTIFY_OK;
+
+ default:
+ return NOTIFY_DONE;
+ }
+}
+
+static struct g12a_sys_pll_nb_data g12a_sys_pll_nb_data = {
+ .sys_pll = &g12a_sys_pll.hw,
+ .cpu_clk = &g12a_cpu_clk.hw,
+ .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+ .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
+/* G12B first CPU cluster uses sys1_pll */
+static struct g12a_sys_pll_nb_data g12b_cpu_clk_sys1_pll_nb_data = {
+ .sys_pll = &g12b_sys1_pll.hw,
+ .cpu_clk = &g12b_cpu_clk.hw,
+ .cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
+ .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
+/* G12B second CPU cluster uses sys_pll */
+static struct g12a_sys_pll_nb_data g12b_cpub_clk_sys_pll_nb_data = {
+ .sys_pll = &g12a_sys_pll.hw,
+ .cpu_clk = &g12b_cpub_clk.hw,
+ .cpu_clk_dyn = &g12b_cpub_clk_dyn.hw,
+ .nb.notifier_call = g12a_sys_pll_notifier_cb,
+};
+
static struct clk_regmap g12a_cpu_clk_div16_en = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_SYS_CPU_CLK_CNTL1,
@@ -4097,28 +4342,210 @@ static const struct reg_sequence g12a_init_regs[] = {
{ .reg = HHI_MPLL_CNTL0, .def = 0x00000543 },
};
-static const struct meson_eeclkc_data g12a_clkc_data = {
- .regmap_clks = g12a_clk_regmaps,
- .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
- .hw_onecell_data = &g12a_hw_onecell_data,
- .init_regs = g12a_init_regs,
- .init_count = ARRAY_SIZE(g12a_init_regs),
-};
-
-static const struct meson_eeclkc_data g12b_clkc_data = {
- .regmap_clks = g12a_clk_regmaps,
- .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
- .hw_onecell_data = &g12b_hw_onecell_data
+static int meson_g12a_dvfs_setup_common(struct platform_device *pdev,
+ struct clk_hw **hws)
+{
+ const char *notifier_clk_name;
+ struct clk *notifier_clk;
+ struct clk_hw *xtal;
+ int ret;
+
+ xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);
+
+ /* Setup clock notifier for cpu_clk_postmux0 */
+ g12a_cpu_clk_postmux0_nb_data.xtal = xtal;
+ notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_postmux0.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk,
+ &g12a_cpu_clk_postmux0_nb_data.nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpu_clk_postmux0 notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for cpu_clk_dyn mux */
+ notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_dyn.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpu_clk_dyn notifier\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int meson_g12b_dvfs_setup(struct platform_device *pdev)
+{
+ struct clk_hw **hws = g12b_hw_onecell_data.hws;
+ const char *notifier_clk_name;
+ struct clk *notifier_clk;
+ struct clk_hw *xtal;
+ int ret;
+
+ ret = meson_g12a_dvfs_setup_common(pdev, hws);
+ if (ret)
+ return ret;
+
+ xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);
+
+ /* Setup clock notifier for cpu_clk mux */
+ notifier_clk_name = clk_hw_get_name(&g12b_cpu_clk.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for sys1_pll */
+ notifier_clk_name = clk_hw_get_name(&g12b_sys1_pll.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk,
+ &g12b_cpu_clk_sys1_pll_nb_data.nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the sys1_pll notifier\n");
+ return ret;
+ }
+
+ /* Add notifiers for the second CPU cluster */
+
+ /* Setup clock notifier for cpub_clk_postmux0 */
+ g12b_cpub_clk_postmux0_nb_data.xtal = xtal;
+ notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_postmux0.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk,
+ &g12b_cpub_clk_postmux0_nb_data.nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpub_clk_postmux0 notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for cpub_clk_dyn mux */
+ notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_dyn.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpub_clk_dyn notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for cpub_clk mux */
+ notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpub_clk notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for sys_pll */
+ notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk,
+ &g12b_cpub_clk_sys_pll_nb_data.nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the sys_pll notifier\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int meson_g12a_dvfs_setup(struct platform_device *pdev)
+{
+ struct clk_hw **hws = g12a_hw_onecell_data.hws;
+ const char *notifier_clk_name;
+ struct clk *notifier_clk;
+ int ret;
+
+ ret = meson_g12a_dvfs_setup_common(pdev, hws);
+ if (ret)
+ return ret;
+
+ /* Setup clock notifier for cpu_clk mux */
+ notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n");
+ return ret;
+ }
+
+ /* Setup clock notifier for sys_pll */
+ notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw);
+ notifier_clk = __clk_lookup(notifier_clk_name);
+ ret = clk_notifier_register(notifier_clk, &g12a_sys_pll_nb_data.nb);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register the sys_pll notifier\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+struct meson_g12a_data {
+ const struct meson_eeclkc_data eeclkc_data;
+ int (*dvfs_setup)(struct platform_device *pdev);
+};
+
+static int meson_g12a_probe(struct platform_device *pdev)
+{
+ const struct meson_eeclkc_data *eeclkc_data;
+ const struct meson_g12a_data *g12a_data;
+ int ret;
+
+ eeclkc_data = of_device_get_match_data(&pdev->dev);
+ if (!eeclkc_data)
+ return -EINVAL;
+
+ ret = meson_eeclkc_probe(pdev);
+ if (ret)
+ return ret;
+
+ g12a_data = container_of(eeclkc_data, struct meson_g12a_data,
+ eeclkc_data);
+
+ if (g12a_data->dvfs_setup)
+ return g12a_data->dvfs_setup(pdev);
+
+ return 0;
+}
+
+static const struct meson_g12a_data g12a_clkc_data = {
+ .eeclkc_data = {
+ .regmap_clks = g12a_clk_regmaps,
+ .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
+ .hw_onecell_data = &g12a_hw_onecell_data,
+ .init_regs = g12a_init_regs,
+ .init_count = ARRAY_SIZE(g12a_init_regs),
+ },
+ .dvfs_setup = meson_g12a_dvfs_setup,
+};
+
+static const struct meson_g12a_data g12b_clkc_data = {
+ .eeclkc_data = {
+ .regmap_clks = g12a_clk_regmaps,
+ .regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
+ .hw_onecell_data = &g12b_hw_onecell_data,
+ },
+ .dvfs_setup = meson_g12b_dvfs_setup,
};
static const struct of_device_id clkc_match_table[] = {
- { .compatible = "amlogic,g12a-clkc", .data = &g12a_clkc_data },
- { .compatible = "amlogic,g12b-clkc", .data = &g12b_clkc_data },
+ {
+ .compatible = "amlogic,g12a-clkc",
+ .data = &g12a_clkc_data.eeclkc_data
+ },
+ {
+ .compatible = "amlogic,g12b-clkc",
+ .data = &g12b_clkc_data.eeclkc_data
+ },
{}
};
static struct platform_driver g12a_driver = {
- .probe = meson_eeclkc_probe,
+ .probe = meson_g12a_probe,
.driver = {
.name = "g12a-clkc",
.of_match_table = clkc_match_table,
--
2.17.1

View File

@ -0,0 +1,45 @@
From d0998101225886bf6126c3cb7dd281bf91d06435 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 31 Jul 2019 10:40:19 +0200
Subject: [PATCH 018/186] FROMGIT: clk: meson: g12a: expose CPUB clock ID for
G12B
Expose the CPUB clock id to add DVFS to the second CPU cluster of
the Amlogic G12B SoC.
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
(cherry picked from commit 85ab9d954698961960240622de4fad85c7d8a61e
https://github.com/BayLibre/clk-meson v5.4/drivers)
---
drivers/clk/meson/g12a.h | 1 -
include/dt-bindings/clock/g12a-clkc.h | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h
index c8aed31fbe17..559a34cfdfeb 100644
--- a/drivers/clk/meson/g12a.h
+++ b/drivers/clk/meson/g12a.h
@@ -216,7 +216,6 @@
#define CLKID_CPUB_CLK_DYN1_DIV 221
#define CLKID_CPUB_CLK_DYN1 222
#define CLKID_CPUB_CLK_DYN 223
-#define CLKID_CPUB_CLK 224
#define CLKID_CPUB_CLK_DIV16_EN 225
#define CLKID_CPUB_CLK_DIV16 226
#define CLKID_CPUB_CLK_DIV2 227
diff --git a/include/dt-bindings/clock/g12a-clkc.h b/include/dt-bindings/clock/g12a-clkc.h
index b6b127e45634..8ccc29ac7a72 100644
--- a/include/dt-bindings/clock/g12a-clkc.h
+++ b/include/dt-bindings/clock/g12a-clkc.h
@@ -137,5 +137,6 @@
#define CLKID_VDEC_HEVC 207
#define CLKID_VDEC_HEVCF 210
#define CLKID_TS 212
+#define CLKID_CPUB_CLK 224
#endif /* __G12A_CLKC_H */
--
2.17.1

View File

@ -0,0 +1,67 @@
From 65a2ec7507a4b3bb728856d68a385caa3d4c5560 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 29 Jul 2019 15:02:17 +0200
Subject: [PATCH 019/186] FROMGIT: soc: amlogic: meson-clk-measure: protect
measure with a mutex
In order to protect clock measuring when multiple process asks for
a measure, protect the main measure function with mutexes.
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit 3a760d986568b67d1f8411dab64608075817b90d
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/drivers)
---
drivers/soc/amlogic/meson-clk-measure.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/soc/amlogic/meson-clk-measure.c b/drivers/soc/amlogic/meson-clk-measure.c
index 19d4cbc93a17..c470e24f1dfa 100644
--- a/drivers/soc/amlogic/meson-clk-measure.c
+++ b/drivers/soc/amlogic/meson-clk-measure.c
@@ -11,6 +11,8 @@
#include <linux/debugfs.h>
#include <linux/regmap.h>
+static DEFINE_MUTEX(measure_lock);
+
#define MSR_CLK_DUTY 0x0
#define MSR_CLK_REG0 0x4
#define MSR_CLK_REG1 0x8
@@ -360,6 +362,10 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
unsigned int val;
int ret;
+ ret = mutex_lock_interruptible(&measure_lock);
+ if (ret)
+ return ret;
+
regmap_write(priv->regmap, MSR_CLK_REG0, 0);
/* Set measurement duration */
@@ -377,8 +383,10 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
ret = regmap_read_poll_timeout(priv->regmap, MSR_CLK_REG0,
val, !(val & MSR_BUSY), 10, 10000);
- if (ret)
+ if (ret) {
+ mutex_unlock(&measure_lock);
return ret;
+ }
/* Disable */
regmap_update_bits(priv->regmap, MSR_CLK_REG0, MSR_ENABLE, 0);
@@ -386,6 +394,8 @@ static int meson_measure_id(struct meson_msr_id *clk_msr_id,
/* Get the value in multiple of gate time counts */
regmap_read(priv->regmap, MSR_CLK_REG2, &val);
+ mutex_unlock(&measure_lock);
+
if (val >= MSR_VAL_MASK)
return -EINVAL;
--
2.17.1

View File

@ -0,0 +1,37 @@
From 08a3283d36ef13a50a8ddfacd739ff55bdac3c34 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 29 Jul 2019 15:02:18 +0200
Subject: [PATCH 020/186] FROMGIT: soc: amlogic: meson-clk-measure: add G12B
second cluster cpu clk
Add the G12B second CPU cluster CPU and SYS_PLL measure IDs.
These IDs returns 0Hz on G12A.
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit c33b2777d01eb0039a53f14f8c0e4cca8df501c7
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/drivers)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/soc/amlogic/meson-clk-measure.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/soc/amlogic/meson-clk-measure.c b/drivers/soc/amlogic/meson-clk-measure.c
index c470e24f1dfa..f09b404b39d3 100644
--- a/drivers/soc/amlogic/meson-clk-measure.c
+++ b/drivers/soc/amlogic/meson-clk-measure.c
@@ -324,6 +324,8 @@ static struct meson_msr_id clk_msr_g12a[CLK_MSR_MAX] = {
CLK_MSR_ID(84, "co_tx"),
CLK_MSR_ID(89, "hdmi_todig"),
CLK_MSR_ID(90, "hdmitx_sys"),
+ CLK_MSR_ID(91, "sys_cpub_div16"),
+ CLK_MSR_ID(92, "sys_pll_cpub_div16"),
CLK_MSR_ID(94, "eth_phy_rx"),
CLK_MSR_ID(95, "eth_phy_pll"),
CLK_MSR_ID(96, "vpu_b"),
--
2.17.1

View File

@ -0,0 +1,32 @@
From ba74cf5f60291b58387057319b422c5547da6fac Mon Sep 17 00:00:00 2001
From: Christian Hewitt <christianshewitt@gmail.com>
Date: Wed, 31 Jul 2019 14:39:55 +0200
Subject: [PATCH 021/186] FROMGIT: soc: amlogic: meson-gx-socinfo: add A311D id
Add the SoC ID for the A311D Amlogic SoC.
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit 0baf212eab4daf8e4882afd624e1403846418610
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/drivers)
---
drivers/soc/amlogic/meson-gx-socinfo.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/soc/amlogic/meson-gx-socinfo.c b/drivers/soc/amlogic/meson-gx-socinfo.c
index bca34954518e..ff86a75939e8 100644
--- a/drivers/soc/amlogic/meson-gx-socinfo.c
+++ b/drivers/soc/amlogic/meson-gx-socinfo.c
@@ -65,6 +65,7 @@ static const struct meson_gx_package_id {
{ "S905D2", 0x28, 0x10, 0xf0 },
{ "S905X2", 0x28, 0x40, 0xf0 },
{ "S922X", 0x29, 0x40, 0xf0 },
+ { "A311D", 0x29, 0x10, 0xf0 },
};
static inline unsigned int socinfo_to_major(u32 socinfo)
--
2.17.1

View File

@ -0,0 +1,40 @@
From 01ab14ff1351b894986e7796dbddf537cce8805d Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 29 Jul 2019 15:26:18 +0200
Subject: [PATCH 023/186] FROMGIT: arm64: dts: meson-g12-common: add pwm_a on
GPIOE_2 pinmux
Add the ao_pinctrl subnode for the pwm_a function on GPIOE_2.
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit a902d577cfb6c16f0108ad9d43fcc02cf90cfcda
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/dt64)
---
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 06e186ca41e3..38d70ce1cfc7 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1970,6 +1970,14 @@
};
};
+ pwm_a_e_pins: pwm-a-e {
+ mux {
+ groups = "pwm_a_e";
+ function = "pwm_a_e";
+ bias-disable;
+ };
+ };
+
pwm_ao_a_pins: pwm-ao-a {
mux {
groups = "pwm_ao_a";
--
2.17.1

View File

@ -0,0 +1,109 @@
From 5cf5216d8ccae4337d1c79f1eee1d174a47b92ce Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 29 Jul 2019 15:26:19 +0200
Subject: [PATCH 024/186] FROMGIT: arm64: dts: meson-g12a: add cpus OPP table
Add the OPP table taken from the vendor u200 and u211 DTS.
The Amlogic G12A SoC seems to available in 3 types :
- low-speed: up to 1,8GHz
- mid-speed: up to 1,908GHz
- high-speed: up to 2.1GHz
And the S905X2 opp voltages are slightly higher than the S905D2
OPP voltages for the low-speed table.
This adds the conservative OPP table with the S905X2 higher voltages
and the maximum low-speed OPP frequency.
The values were tested to be stable on an Amlogic U200 Reference Board,
SeiRobotics SEI510 and X96 Max Set-Top-Boxes running the arm64 cpuburn
at [1] and cycling between all the possible cpufreq translations and
checking the final frequency using the clock-measurer, script at [2].
[1] https://github.com/ssvb/cpuburn-arm/blob/master/cpuburn-a53.S
[2] https://gist.github.com/superna9999/d4de964dbc0f84b7d527e1df2ddea25f
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit 67444f6c8058e6103de719eb276a8999a18a6ad6
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/dt64)
---
arch/arm64/boot/dts/amlogic/meson-g12a.dtsi | 60 +++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
index ac15967bb7fa..733a9d46fc4b 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a.dtsi
@@ -48,6 +48,66 @@
compatible = "cache";
};
};
+
+ cpu_opp_table: opp-table {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-667000000 {
+ opp-hz = /bits/ 64 <666666666>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1398000000 {
+ opp-hz = /bits/ 64 <1398000000>;
+ opp-microvolt = <761000>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <791000>;
+ };
+
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <831000>;
+ };
+
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <861000>;
+ };
+
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <981000>;
+ };
+ };
};
&sd_emmc_a {
--
2.17.1

View File

@ -0,0 +1,270 @@
From e4cd8a3f40644976d58426dc829fe65e247073aa Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 29 Jul 2019 15:26:20 +0200
Subject: [PATCH 025/186] FROMGIT: arm64: dts: meson-g12a: enable DVFS on G12A
boards
Enable DVFS for the U200, SEI520 and X96-Max Amlogic G12A based board
by setting the clock, OPP and supply for each CPU cores.
The CPU cluster power supply can achieve 0.73V to 1.01V using a PWM
output clocked at 800KHz with an inverse duty-cycle.
DVFS has been tested by running the arm64 cpuburn at [1] and cycling
between all the possible cpufreq translations and checking the final
frequency using the clock-measurer, script at [2].
[1] https://github.com/ssvb/cpuburn-arm/blob/master/cpuburn-a53.S
[2] https://gist.github.com/superna9999/d4de964dbc0f84b7d527e1df2ddea25f
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit 26328b18e2a1cffc92a32cc53c74bbca69ea7f60
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/dt64)
---
.../boot/dts/amlogic/meson-g12a-sei510.dts | 55 +++++++++++++++++++
.../boot/dts/amlogic/meson-g12a-u200.dts | 54 ++++++++++++++++++
.../boot/dts/amlogic/meson-g12a-x96-max.dts | 52 ++++++++++++++++++
3 files changed, 161 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
index 12aa7eaeaf68..c9fa23a56562 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
@@ -129,6 +129,25 @@
enable-active-high;
};
+ vddcpu: regulator-vddcpu {
+ /*
+ * SY8120B1ABC DC/DC Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ vin-supply = <&dc_in>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
vddio_ao1v8: regulator-vddio_ao1v8 {
compatible = "regulator-fixed";
regulator-name = "VDDIO_AO1V8";
@@ -297,6 +316,34 @@
status = "okay";
};
+&cpu0 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu2 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu3 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
&cvbs_vdac_port {
cvbs_vdac_out: endpoint {
remote-endpoint = <&cvbs_connector_in>;
@@ -345,6 +392,14 @@
pinctrl-names = "default";
};
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
&pwm_ef {
status = "okay";
pinctrl-0 = <&pwm_e_pins>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
index 8551fbd4a488..2a324f0136e3 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-u200.dts
@@ -129,6 +129,24 @@
regulator-always-on;
};
+ vddcpu: regulator-vddcpu {
+ /*
+ * MP8756GD Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ vin-supply = <&main_12v>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
};
&cec_AO {
@@ -145,6 +163,34 @@
hdmi-phandle = <&hdmi_tx>;
};
+&cpu0 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu2 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu3 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
&cvbs_vdac_port {
cvbs_vdac_out: endpoint {
remote-endpoint = <&cvbs_connector_in>;
@@ -197,6 +243,14 @@
pinctrl-names = "default";
};
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
/* SD card */
&sd_emmc_b {
status = "okay";
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
index fe4013cca876..c1e58a69d434 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-x96-max.dts
@@ -132,6 +132,22 @@
regulator-always-on;
};
+ vddcpu: regulator-vddcpu {
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ vin-supply = <&dc_in>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
sound {
compatible = "amlogic,axg-sound-card";
model = "G12A-X96-MAX";
@@ -242,6 +258,34 @@
status = "okay";
};
+&cpu0 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu2 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu3 {
+ cpu-supply = <&vddcpu>;
+ operating-points-v2 = <&cpu_opp_table>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
&cvbs_vdac_port {
cvbs_vdac_out: endpoint {
remote-endpoint = <&cvbs_connector_in>;
@@ -279,6 +323,14 @@
pinctrl-names = "default";
};
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
&ext_mdio {
external_phy: ethernet-phy@0 {
/* Realtek RTL8211F (0x001cc916) */
--
2.17.1

View File

@ -0,0 +1,165 @@
From 5de757bd182fc25b5bca929b4d1aa031b32aaa0f Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 29 Jul 2019 15:26:21 +0200
Subject: [PATCH 026/186] FROMGIT: arm64: dts: meson-g12b: add cpus OPP tables
Add the OPP table taken from the HardKernel Odroid-N2 DTS.
The Amlogic G12B SoC seems to available in 2 types :
- low-speed: Cortex-A73 Cluster up to 1,704GHz
- high-speed: Cortex-A73 Cluster up to 2.208GHz
The Cortex-A73 Cluster can be clocked up to 1,896GHz for both types.
The Vendor Amlogic A311D OPP table are slighly different, with lower
voltages than the HardKernel S922X tables but seems to be high-speed type.
This adds the conservative OPP table with the S922X higher voltages
and the maximum low-speed OPP frequency.
The values were tested to be stable on an HardKernel Odroid-N2 board
running the arm64 cpuburn at [1] and cycling between all the possible
cpufreq translations for both clusters and checking the final frequency
using the clock-measurer, script at [2].
[1] https://github.com/ssvb/cpuburn-arm/blob/master/cpuburn-a53.S
[2] https://gist.github.com/superna9999/d4de964dbc0f84b7d527e1df2ddea25f
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit e53df01cf17faea76e29332b88b30ca02998fb3f
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/dt64)
---
arch/arm64/boot/dts/amlogic/meson-g12b.dtsi | 115 ++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
index d5edbc1a1991..98ae8a7c8b41 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
@@ -95,6 +95,121 @@
compatible = "cache";
};
};
+
+ cpu_opp_table_0: opp-table-0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-666666666 {
+ opp-hz = /bits/ 64 <666666666>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1398000000 {
+ opp-hz = /bits/ 64 <1398000000>;
+ opp-microvolt = <761000>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <791000>;
+ };
+
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <831000>;
+ };
+
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <861000>;
+ };
+
+ opp-1896000000 {
+ opp-hz = /bits/ 64 <1896000000>;
+ opp-microvolt = <981000>;
+ };
+ };
+
+ cpub_opp_table_1: opp-table-1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-666666666 {
+ opp-hz = /bits/ 64 <666666666>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <771000>;
+ };
+
+ opp-1398000000 {
+ opp-hz = /bits/ 64 <1398000000>;
+ opp-microvolt = <791000>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <821000>;
+ };
+
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <861000>;
+ };
+
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <891000>;
+ };
+ };
};
&clkc {
--
2.17.1

View File

@ -0,0 +1,67 @@
From 0075d60b445f24e817b7a8f45bdc90e8bde42c07 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 18 Jul 2019 11:03:01 +0200
Subject: [PATCH 027/186] FROMGIT: arm64: dts: meson: add ethernet fifo sizes
If unspecified in DT, the fifo sizes are not automatically detected by
the dwmac1000 dma driver and the reported fifo sizes default to 0.
Because of this, flow control will be turned off on the device.
Add the fifo sizes provided by the datasheets in the SoC in DT so
flow control may be enabled if necessary.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit af29074f707b7f6d07b2484abc62db35c42c38ec
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/dt64)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 2 ++
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 2 ++
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 2 ++
3 files changed, 6 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 6219337033a0..12bf959c17a7 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -182,6 +182,8 @@
<&clkc CLKID_FCLK_DIV2>,
<&clkc CLKID_MPLL2>;
clock-names = "stmmaceth", "clkin0", "clkin1";
+ rx-fifo-depth = <4096>;
+ tx-fifo-depth = <2048>;
status = "disabled";
};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 38d70ce1cfc7..27bb242dc95d 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -106,6 +106,8 @@
<&clkc CLKID_FCLK_DIV2>,
<&clkc CLKID_MPLL2>;
clock-names = "stmmaceth", "clkin0", "clkin1";
+ rx-fifo-depth = <4096>;
+ tx-fifo-depth = <2048>;
status = "disabled";
mdio0: mdio {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index 74d03fc706be..e62aad5bf867 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -493,6 +493,8 @@
0x0 0xc8834540 0x0 0x4>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq";
+ rx-fifo-depth = <4096>;
+ tx-fifo-depth = <2048>;
status = "disabled";
};
--
2.17.1

View File

@ -0,0 +1,34 @@
From bdfc7696b7ad4c394d4bd0c0252706931c55a757 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 31 Jul 2019 14:39:56 +0200
Subject: [PATCH 028/186] FROMGIT: dt-bindings: arm: amlogic: add bindings for
G12B based S922X SoC
Add a specific compatible for the Amlogic G12B family based S922X SoC
to differentiate with the A311D SoC from the same family.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit 5d2b173b89a02a6fc52217dc4d585c81b53d1d29
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/dt64)
---
Documentation/devicetree/bindings/arm/amlogic.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 325c6fd3566d..3c3bc806cd23 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -139,6 +139,7 @@ properties:
items:
- enum:
- hardkernel,odroid-n2
+ - const: amlogic,s922x
- const: amlogic,g12b
...
--
2.17.1

View File

@ -0,0 +1,38 @@
From 37f20443f15463233c86c8db15491242607a64f9 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 31 Jul 2019 14:39:57 +0200
Subject: [PATCH 029/186] FROMGIT: dt-bindings: arm: amlogic: add bindings for
the Amlogic G12B based A311D SoC
Add a specific compatible for the Amlogic G12B bases A311D SoC used
in the Khadas VIM3.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit 96561b0c5e4be51bb57df2cc388a1b688a93a036
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/dt64)
---
Documentation/devicetree/bindings/arm/amlogic.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index 3c3bc806cd23..efa032d12402 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -135,6 +135,11 @@ properties:
- amlogic,u200
- const: amlogic,g12a
+ - description: Boards with the Amlogic Meson G12B A311D SoC
+ items:
+ - const: amlogic,a311d
+ - const: amlogic,g12b
+
- description: Boards with the Amlogic Meson G12B S922X SoC
items:
- enum:
--
2.17.1

View File

@ -0,0 +1,61 @@
From a3f7e2e463ab5f258cfd42f110e135de98a52c70 Mon Sep 17 00:00:00 2001
From: Christian Hewitt <christianshewitt@gmail.com>
Date: Wed, 31 Jul 2019 14:39:58 +0200
Subject: [PATCH 030/186] FROMGIT: dt-bindings: arm: amlogic: add support for
the Khadas VIM3
The Khadas VIM3 uses the Amlogic S922X or A311S SoC, both based on the
Amlogic G12B SoC family, on a board with the same form factor as the
VIM/VIM2 models. It ships in two variants; basic and
pro which differ in RAM and eMMC size:
- 2GB (basic) or 4GB (pro) LPDDR4 RAM
- 16GB (basic) or 32GB (pro) eMMC 5.1 storage
- 16MB SPI flash
- 10/100/1000 Base-T Ethernet
- AP6398S Wireless (802.11 a/b/g/n/ac, BT5.0)
- HDMI 2.1 video
- 1x USB 2.0 + 1x USB 3.0 ports
- 1x USB-C (power) with USB 2.0 OTG
- 3x LED's (1x red, 1x blue, 1x white)
- 3x buttons (power, function, reset)
- IR receiver
- M2 socket with PCIe, USB, ADC & I2C
- 40pin GPIO Header
- 1x micro SD card slot
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit edd55c0496b4bea6b2fa4b8f4646d06f47bb02d6
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/dt64)
---
Documentation/devicetree/bindings/arm/amlogic.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/amlogic.yaml b/Documentation/devicetree/bindings/arm/amlogic.yaml
index efa032d12402..04a2b0ef34c6 100644
--- a/Documentation/devicetree/bindings/arm/amlogic.yaml
+++ b/Documentation/devicetree/bindings/arm/amlogic.yaml
@@ -137,6 +137,8 @@ properties:
- description: Boards with the Amlogic Meson G12B A311D SoC
items:
+ - enum:
+ - khadas,vim3
- const: amlogic,a311d
- const: amlogic,g12b
@@ -144,6 +146,7 @@ properties:
items:
- enum:
- hardkernel,odroid-n2
+ - khadas,vim3
- const: amlogic,s922x
- const: amlogic,g12b
--
2.17.1

View File

@ -0,0 +1,455 @@
From b8575810b01ddddc1c1641a35bb7ef468f4a3844 Mon Sep 17 00:00:00 2001
From: Christian Hewitt <christianshewitt@gmail.com>
Date: Wed, 31 Jul 2019 14:39:59 +0200
Subject: [PATCH 031/186] FROMGIT: arm64: dts: meson-g12b: support a311d and
s922x cpu operating points
Meson g12b ships with a low-speed (S922X) and high-speed (A311D) variant
so remove cpu_opp_table nodes in meson-g12b.dtsi and create two new dtsi
that can be included in device-specific dts files. Opp points were taken
from the vendor BSP kernel.
Also make meson-g12b-odroid-n2.dts include the new meson-g12b-s922x.dtsi.
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Signed-off-by: Kevin Hilman <khilman@baylibre.com>
(cherry picked from commit 81f58a8b290787e52b4b919050f9093b13c485fa
git://git.kernel.org/pub/scm/linux/kernel/git/khilman/linux-amlogic.git v5.4/dt64)
---
.../boot/dts/amlogic/meson-g12b-a311d.dtsi | 149 ++++++++++++++++++
.../boot/dts/amlogic/meson-g12b-odroid-n2.dts | 2 +-
.../boot/dts/amlogic/meson-g12b-s922x.dtsi | 124 +++++++++++++++
arch/arm64/boot/dts/amlogic/meson-g12b.dtsi | 115 --------------
4 files changed, 274 insertions(+), 116 deletions(-)
create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi
create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi
new file mode 100644
index 000000000000..d61f43052a34
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d.dtsi
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include "meson-g12b.dtsi"
+
+/ {
+ cpu_opp_table_0: opp-table-0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-667000000 {
+ opp-hz = /bits/ 64 <667000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <761000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <781000>;
+ };
+
+ opp-1398000000 {
+ opp-hz = /bits/ 64 <1398000000>;
+ opp-microvolt = <811000>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <861000>;
+ };
+
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <901000>;
+ };
+
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <951000>;
+ };
+
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <1001000>;
+ };
+ };
+
+ cpub_opp_table_1: opp-table-1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-667000000 {
+ opp-hz = /bits/ 64 <667000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-1398000000 {
+ opp-hz = /bits/ 64 <1398000000>;
+ opp-microvolt = <771000>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <771000>;
+ };
+
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <781000>;
+ };
+
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <791000>;
+ };
+
+ opp-1800000000 {
+ opp-hz = /bits/ 64 <1800000000>;
+ opp-microvolt = <831000>;
+ };
+
+ opp-1908000000 {
+ opp-hz = /bits/ 64 <1908000000>;
+ opp-microvolt = <861000>;
+ };
+
+ opp-2016000000 {
+ opp-hz = /bits/ 64 <2016000000>;
+ opp-microvolt = <911000>;
+ };
+
+ opp-2108000000 {
+ opp-hz = /bits/ 64 <2108000000>;
+ opp-microvolt = <951000>;
+ };
+
+ opp-2208000000 {
+ opp-hz = /bits/ 64 <2208000000>;
+ opp-microvolt = <1011000>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
index 4e916e1f71f7..237adae0ffae 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
@@ -6,7 +6,7 @@
/dts-v1/;
-#include "meson-g12b.dtsi"
+#include "meson-g12b-s922x.dtsi"
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>
#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi
new file mode 100644
index 000000000000..046cc332d07f
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x.dtsi
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ */
+
+#include "meson-g12b.dtsi"
+
+/ {
+ cpu_opp_table_0: opp-table-0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-667000000 {
+ opp-hz = /bits/ 64 <667000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1398000000 {
+ opp-hz = /bits/ 64 <1398000000>;
+ opp-microvolt = <761000>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <791000>;
+ };
+
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <831000>;
+ };
+
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <861000>;
+ };
+
+ opp-1896000000 {
+ opp-hz = /bits/ 64 <1896000000>;
+ opp-microvolt = <981000>;
+ };
+ };
+
+ cpub_opp_table_1: opp-table-1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-667000000 {
+ opp-hz = /bits/ 64 <667000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <771000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <771000>;
+ };
+
+ opp-1398000000 {
+ opp-hz = /bits/ 64 <1398000000>;
+ opp-microvolt = <791000>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <821000>;
+ };
+
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <861000>;
+ };
+
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <891000>;
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
index 98ae8a7c8b41..d5edbc1a1991 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
@@ -95,121 +95,6 @@
compatible = "cache";
};
};
-
- cpu_opp_table_0: opp-table-0 {
- compatible = "operating-points-v2";
- opp-shared;
-
- opp-100000000 {
- opp-hz = /bits/ 64 <100000000>;
- opp-microvolt = <731000>;
- };
-
- opp-250000000 {
- opp-hz = /bits/ 64 <250000000>;
- opp-microvolt = <731000>;
- };
-
- opp-500000000 {
- opp-hz = /bits/ 64 <500000000>;
- opp-microvolt = <731000>;
- };
-
- opp-666666666 {
- opp-hz = /bits/ 64 <666666666>;
- opp-microvolt = <731000>;
- };
-
- opp-1000000000 {
- opp-hz = /bits/ 64 <1000000000>;
- opp-microvolt = <731000>;
- };
-
- opp-1200000000 {
- opp-hz = /bits/ 64 <1200000000>;
- opp-microvolt = <731000>;
- };
-
- opp-1398000000 {
- opp-hz = /bits/ 64 <1398000000>;
- opp-microvolt = <761000>;
- };
-
- opp-1512000000 {
- opp-hz = /bits/ 64 <1512000000>;
- opp-microvolt = <791000>;
- };
-
- opp-1608000000 {
- opp-hz = /bits/ 64 <1608000000>;
- opp-microvolt = <831000>;
- };
-
- opp-1704000000 {
- opp-hz = /bits/ 64 <1704000000>;
- opp-microvolt = <861000>;
- };
-
- opp-1896000000 {
- opp-hz = /bits/ 64 <1896000000>;
- opp-microvolt = <981000>;
- };
- };
-
- cpub_opp_table_1: opp-table-1 {
- compatible = "operating-points-v2";
- opp-shared;
-
- opp-100000000 {
- opp-hz = /bits/ 64 <100000000>;
- opp-microvolt = <751000>;
- };
-
- opp-250000000 {
- opp-hz = /bits/ 64 <250000000>;
- opp-microvolt = <751000>;
- };
-
- opp-500000000 {
- opp-hz = /bits/ 64 <500000000>;
- opp-microvolt = <751000>;
- };
-
- opp-666666666 {
- opp-hz = /bits/ 64 <666666666>;
- opp-microvolt = <751000>;
- };
-
- opp-1000000000 {
- opp-hz = /bits/ 64 <1000000000>;
- opp-microvolt = <751000>;
- };
-
- opp-1200000000 {
- opp-hz = /bits/ 64 <1200000000>;
- opp-microvolt = <771000>;
- };
-
- opp-1398000000 {
- opp-hz = /bits/ 64 <1398000000>;
- opp-microvolt = <791000>;
- };
-
- opp-1512000000 {
- opp-hz = /bits/ 64 <1512000000>;
- opp-microvolt = <821000>;
- };
-
- opp-1608000000 {
- opp-hz = /bits/ 64 <1608000000>;
- opp-microvolt = <861000>;
- };
-
- opp-1704000000 {
- opp-hz = /bits/ 64 <1704000000>;
- opp-microvolt = <891000>;
- };
- };
};
&clkc {
--
2.17.1

View File

@ -0,0 +1,63 @@
From cb458a02db3f40d6e0dcb0ce24e35d10a804f028 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 29 Jul 2019 14:58:38 +0200
Subject: [PATCH 032/186] FROMGIT: pinctrl: meson-g12a: add pwm_a on GPIOE_2
pinmux
Add the missing pinmux for the pwm_a function on the GPIOE_2 pin.
Reviewed-by: Kevin Hilman <khilman@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://lore.kernel.org/r/20190729125838.6498-1-narmstrong@baylibre.com
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
(cherry picked from commit 726e8d813771ed9c714d75c9ce58a97b9ddf343d
git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl.git for-next)
---
drivers/pinctrl/meson/pinctrl-meson-g12a.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/pinctrl/meson/pinctrl-meson-g12a.c b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
index 3475cd7bd2af..582665fd362a 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-g12a.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-g12a.c
@@ -801,6 +801,9 @@ static const unsigned int remote_ao_input_pins[] = { GPIOAO_5 };
/* ir_out */
static const unsigned int remote_ao_out_pins[] = { GPIOAO_4 };
+/* pwm_a_e */
+static const unsigned int pwm_a_e_pins[] = { GPIOE_2 };
+
/* pwm_ao_a */
static const unsigned int pwm_ao_a_pins[] = { GPIOAO_11 };
static const unsigned int pwm_ao_a_hiz_pins[] = { GPIOAO_11 };
@@ -888,6 +891,7 @@ static struct meson_pmx_group meson_g12a_aobus_groups[] = {
GROUP(i2c_ao_slave_sda, 3),
GROUP(remote_ao_input, 1),
GROUP(remote_ao_out, 1),
+ GROUP(pwm_a_e, 3),
GROUP(pwm_ao_a, 3),
GROUP(pwm_ao_a_hiz, 2),
GROUP(pwm_ao_b, 3),
@@ -1192,6 +1196,10 @@ static const char * const remote_ao_out_groups[] = {
"remote_ao_out",
};
+static const char * const pwm_a_e_groups[] = {
+ "pwm_a_e",
+};
+
static const char * const pwm_ao_a_groups[] = {
"pwm_ao_a", "pwm_ao_a_hiz",
};
@@ -1290,6 +1298,7 @@ static struct meson_pmx_func meson_g12a_aobus_functions[] = {
FUNCTION(i2c_ao_slave),
FUNCTION(remote_ao_input),
FUNCTION(remote_ao_out),
+ FUNCTION(pwm_a_e),
FUNCTION(pwm_ao_a),
FUNCTION(pwm_ao_b),
FUNCTION(pwm_ao_c),
--
2.17.1

View File

@ -0,0 +1,52 @@
From 8f0744434f0dcfede8faf18e39af73d241236e64 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 1 Jul 2019 06:47:01 -0400
Subject: [PATCH 033/186] FROMGIT: media: dt-bindings: media: meson-ao-cec: add
SM1 compatible
Add AO-CEC compatible string for the Amlogic SM1 SoC family,
a derivate of the G12A AO-CECB controller.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
(cherry picked from commit 9bef0d1d053de8db30bc07aa132c0ee94a05609c
git://linuxtv.org/media_tree.git master)
---
Documentation/devicetree/bindings/media/meson-ao-cec.txt | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/meson-ao-cec.txt b/Documentation/devicetree/bindings/media/meson-ao-cec.txt
index c67fc41d4aa2..ad92ee41c0dd 100644
--- a/Documentation/devicetree/bindings/media/meson-ao-cec.txt
+++ b/Documentation/devicetree/bindings/media/meson-ao-cec.txt
@@ -5,10 +5,12 @@ to handle communication between HDMI connected devices over the CEC bus.
Required properties:
- compatible : value should be following depending on the SoC :
- For GXBB, GXL, GXM and G12A (AO_CEC_A module) :
+ For GXBB, GXL, GXM, G12A and SM1 (AO_CEC_A module) :
"amlogic,meson-gx-ao-cec"
For G12A (AO_CEC_B module) :
"amlogic,meson-g12a-ao-cec"
+ For SM1 (AO_CEC_B module) :
+ "amlogic,meson-sm1-ao-cec"
- reg : Physical base address of the IP registers and length of memory
mapped region.
@@ -16,9 +18,9 @@ Required properties:
- interrupts : AO-CEC interrupt number to the CPU.
- clocks : from common clock binding: handle to AO-CEC clock.
- clock-names : from common clock binding, must contain :
- For GXBB, GXL, GXM and G12A (AO_CEC_A module) :
+ For GXBB, GXL, GXM, G12A and SM1 (AO_CEC_A module) :
- "core"
- For G12A (AO_CEC_B module) :
+ For G12A, SM1 (AO_CEC_B module) :
- "oscin"
corresponding to entry in the clocks property.
- hdmi-phandle: phandle to the HDMI controller
--
2.17.1

View File

@ -0,0 +1,107 @@
From d50a38211eff6fbb250df2379812d0df2d595280 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 1 Jul 2019 06:47:02 -0400
Subject: [PATCH 034/186] FROMGIT: media: platform: meson-ao-cec-g12a: add
support for SM1
Add support for the Amlogic SM1 SoC Family to the G12A AO-CECB
derivative.
It only adds a single init register.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
[hverkuil-cisco@xs4all.nl: dropped spurious newline]
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
(cherry picked from commit aef5f47c9907ed6bfe9245124279b9c049077fd7
git://linuxtv.org/media_tree.git master)
---
drivers/media/platform/meson/ao-cec-g12a.c | 36 +++++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/meson/ao-cec-g12a.c b/drivers/media/platform/meson/ao-cec-g12a.c
index fb52e5dd044a..d302eae569b3 100644
--- a/drivers/media/platform/meson/ao-cec-g12a.c
+++ b/drivers/media/platform/meson/ao-cec-g12a.c
@@ -121,6 +121,9 @@
#define CECB_CTRL_TYPE_NEXT 2
#define CECB_CTRL2 0x01
+
+#define CECB_CTRL2_RISE_DEL_MAX GENMASK(4, 0)
+
#define CECB_INTR_MASK 0x02
#define CECB_LADD_LOW 0x05
#define CECB_LADD_HIGH 0x06
@@ -165,6 +168,11 @@
#define CECB_WAKEUPCTRL 0x31
+struct meson_ao_cec_g12a_data {
+ /* Setup the internal CECB_CTRL2 register */
+ bool ctrl2_setup;
+};
+
struct meson_ao_cec_g12a_device {
struct platform_device *pdev;
struct regmap *regmap;
@@ -175,6 +183,7 @@ struct meson_ao_cec_g12a_device {
struct cec_msg rx_msg;
struct clk *oscin;
struct clk *core;
+ const struct meson_ao_cec_g12a_data *data;
};
static const struct regmap_config meson_ao_cec_g12a_regmap_conf = {
@@ -605,6 +614,10 @@ static int meson_ao_cec_g12a_adap_enable(struct cec_adapter *adap, bool enable)
regmap_update_bits(ao_cec->regmap, CECB_GEN_CNTL_REG,
CECB_GEN_CNTL_RESET, 0);
+ if (ao_cec->data->ctrl2_setup)
+ regmap_write(ao_cec->regmap_cec, CECB_CTRL2,
+ FIELD_PREP(CECB_CTRL2_RISE_DEL_MAX, 2));
+
meson_ao_cec_g12a_irq_setup(ao_cec, true);
return 0;
@@ -632,6 +645,12 @@ static int meson_ao_cec_g12a_probe(struct platform_device *pdev)
if (!ao_cec)
return -ENOMEM;
+ ao_cec->data = of_device_get_match_data(&pdev->dev);
+ if (!ao_cec->data) {
+ dev_err(&pdev->dev, "failed to get match data\n");
+ return -ENODEV;
+ }
+
spin_lock_init(&ao_cec->cec_reg_lock);
ao_cec->pdev = pdev;
@@ -742,8 +761,23 @@ static int meson_ao_cec_g12a_remove(struct platform_device *pdev)
return 0;
}
+static const struct meson_ao_cec_g12a_data ao_cec_g12a_data = {
+ .ctrl2_setup = false,
+};
+
+static const struct meson_ao_cec_g12a_data ao_cec_sm1_data = {
+ .ctrl2_setup = true,
+};
+
static const struct of_device_id meson_ao_cec_g12a_of_match[] = {
- { .compatible = "amlogic,meson-g12a-ao-cec", },
+ {
+ .compatible = "amlogic,meson-g12a-ao-cec",
+ .data = &ao_cec_g12a_data,
+ },
+ {
+ .compatible = "amlogic,meson-sm1-ao-cec",
+ .data = &ao_cec_sm1_data,
+ },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, meson_ao_cec_g12a_of_match);
--
2.17.1

View File

@ -0,0 +1,574 @@
From 962431951c7f46837aa3928dfc378a55a0f87294 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:32:12 +0900
Subject: [PATCH 035/186] FROMGIT: ASoC: add soc-dai.c
Current ALSA SoC has many snd_soc_dai_xxx() function which is
using dai->driver->ops->xxx.
But, some of them are implemented as snd_soc_dai_xxx(),
but others are directly using dai->driver->ops->xxx.
Because of it, the code is not easy to read.
This patch creats new soc-dai.c and moves snd_soc_dai_xxx()
functions into it.
One exception is snd_soc_dai_is_dummy() which is based on
soc-utils local variable. We need to keep it as-is there.
Others which is directly using dai->driver->ops->xxx will be
implemented at soc-dai.c by incremental patches.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/871ryij1r6.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 06f6e1d41427f394ad3f67ecf06efcd28a46932c
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
sound/soc/Makefile | 2 +-
sound/soc/soc-core.c | 243 -----------------------------------------
sound/soc/soc-dai.c | 254 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 255 insertions(+), 244 deletions(-)
create mode 100644 sound/soc/soc-dai.c
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index d90ce8a32887..919c3c027c62 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-2.0
-snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-utils.o
+snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-utils.o soc-dai.o
snd-soc-core-objs += soc-pcm.o soc-io.o soc-devres.o soc-ops.o
snd-soc-core-$(CONFIG_SND_SOC_COMPRESS) += soc-compress.o
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 44f899b970c2..a8d2c4ec0ec9 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2397,26 +2397,6 @@ int snd_soc_add_dai_controls(struct snd_soc_dai *dai,
}
EXPORT_SYMBOL_GPL(snd_soc_add_dai_controls);
-/**
- * snd_soc_dai_set_sysclk - configure DAI system or master clock.
- * @dai: DAI
- * @clk_id: DAI specific clock ID
- * @freq: new clock frequency in Hz
- * @dir: new clock direction - input/output.
- *
- * Configures the DAI master (MCLK) or system (SYSCLK) clocking.
- */
-int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
- unsigned int freq, int dir)
-{
- if (dai->driver->ops->set_sysclk)
- return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
-
- return snd_soc_component_set_sysclk(dai->component, clk_id, 0,
- freq, dir);
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
-
/**
* snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
* @component: COMPONENT
@@ -2439,48 +2419,6 @@ int snd_soc_component_set_sysclk(struct snd_soc_component *component,
}
EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
-/**
- * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
- * @dai: DAI
- * @div_id: DAI specific clock divider ID
- * @div: new clock divisor.
- *
- * Configures the clock dividers. This is used to derive the best DAI bit and
- * frame clocks from the system or master clock. It's best to set the DAI bit
- * and frame clocks as low as possible to save system power.
- */
-int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
- int div_id, int div)
-{
- if (dai->driver->ops->set_clkdiv)
- return dai->driver->ops->set_clkdiv(dai, div_id, div);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
-
-/**
- * snd_soc_dai_set_pll - configure DAI PLL.
- * @dai: DAI
- * @pll_id: DAI specific PLL ID
- * @source: DAI specific source for the PLL
- * @freq_in: PLL input clock frequency in Hz
- * @freq_out: requested PLL output clock frequency in Hz
- *
- * Configures and enables PLL to generate output clock based on input clock.
- */
-int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
- unsigned int freq_in, unsigned int freq_out)
-{
- if (dai->driver->ops->set_pll)
- return dai->driver->ops->set_pll(dai, pll_id, source,
- freq_in, freq_out);
-
- return snd_soc_component_set_pll(dai->component, pll_id, source,
- freq_in, freq_out);
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
-
/*
* snd_soc_component_set_pll - configure component PLL.
* @component: COMPONENT
@@ -2503,187 +2441,6 @@ int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
}
EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
-/**
- * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio.
- * @dai: DAI
- * @ratio: Ratio of BCLK to Sample rate.
- *
- * Configures the DAI for a preset BCLK to sample rate ratio.
- */
-int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
-{
- if (dai->driver->ops->set_bclk_ratio)
- return dai->driver->ops->set_bclk_ratio(dai, ratio);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio);
-
-/**
- * snd_soc_dai_set_fmt - configure DAI hardware audio format.
- * @dai: DAI
- * @fmt: SND_SOC_DAIFMT_* format value.
- *
- * Configures the DAI hardware format and clocking.
- */
-int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
-{
- if (dai->driver->ops->set_fmt == NULL)
- return -ENOTSUPP;
- return dai->driver->ops->set_fmt(dai, fmt);
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
-
-/**
- * snd_soc_xlate_tdm_slot - generate tx/rx slot mask.
- * @slots: Number of slots in use.
- * @tx_mask: bitmask representing active TX slots.
- * @rx_mask: bitmask representing active RX slots.
- *
- * Generates the TDM tx and rx slot default masks for DAI.
- */
-static int snd_soc_xlate_tdm_slot_mask(unsigned int slots,
- unsigned int *tx_mask,
- unsigned int *rx_mask)
-{
- if (*tx_mask || *rx_mask)
- return 0;
-
- if (!slots)
- return -EINVAL;
-
- *tx_mask = (1 << slots) - 1;
- *rx_mask = (1 << slots) - 1;
-
- return 0;
-}
-
-/**
- * snd_soc_dai_set_tdm_slot() - Configures a DAI for TDM operation
- * @dai: The DAI to configure
- * @tx_mask: bitmask representing active TX slots.
- * @rx_mask: bitmask representing active RX slots.
- * @slots: Number of slots in use.
- * @slot_width: Width in bits for each slot.
- *
- * This function configures the specified DAI for TDM operation. @slot contains
- * the total number of slots of the TDM stream and @slot_with the width of each
- * slot in bit clock cycles. @tx_mask and @rx_mask are bitmasks specifying the
- * active slots of the TDM stream for the specified DAI, i.e. which slots the
- * DAI should write to or read from. If a bit is set the corresponding slot is
- * active, if a bit is cleared the corresponding slot is inactive. Bit 0 maps to
- * the first slot, bit 1 to the second slot and so on. The first active slot
- * maps to the first channel of the DAI, the second active slot to the second
- * channel and so on.
- *
- * TDM mode can be disabled by passing 0 for @slots. In this case @tx_mask,
- * @rx_mask and @slot_width will be ignored.
- *
- * Returns 0 on success, a negative error code otherwise.
- */
-int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
- unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)
-{
- if (dai->driver->ops->xlate_tdm_slot_mask)
- dai->driver->ops->xlate_tdm_slot_mask(slots,
- &tx_mask, &rx_mask);
- else
- snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);
-
- dai->tx_mask = tx_mask;
- dai->rx_mask = rx_mask;
-
- if (dai->driver->ops->set_tdm_slot)
- return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
- slots, slot_width);
- else
- return -ENOTSUPP;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
-
-/**
- * snd_soc_dai_set_channel_map - configure DAI audio channel map
- * @dai: DAI
- * @tx_num: how many TX channels
- * @tx_slot: pointer to an array which imply the TX slot number channel
- * 0~num-1 uses
- * @rx_num: how many RX channels
- * @rx_slot: pointer to an array which imply the RX slot number channel
- * 0~num-1 uses
- *
- * configure the relationship between channel number and TDM slot number.
- */
-int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
- unsigned int tx_num, unsigned int *tx_slot,
- unsigned int rx_num, unsigned int *rx_slot)
-{
- if (dai->driver->ops->set_channel_map)
- return dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
- rx_num, rx_slot);
- else
- return -ENOTSUPP;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
-
-/**
- * snd_soc_dai_get_channel_map - Get DAI audio channel map
- * @dai: DAI
- * @tx_num: how many TX channels
- * @tx_slot: pointer to an array which imply the TX slot number channel
- * 0~num-1 uses
- * @rx_num: how many RX channels
- * @rx_slot: pointer to an array which imply the RX slot number channel
- * 0~num-1 uses
- */
-int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
- unsigned int *tx_num, unsigned int *tx_slot,
- unsigned int *rx_num, unsigned int *rx_slot)
-{
- if (dai->driver->ops->get_channel_map)
- return dai->driver->ops->get_channel_map(dai, tx_num, tx_slot,
- rx_num, rx_slot);
- else
- return -ENOTSUPP;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map);
-
-/**
- * snd_soc_dai_set_tristate - configure DAI system or master clock.
- * @dai: DAI
- * @tristate: tristate enable
- *
- * Tristates the DAI so that others can use it.
- */
-int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
-{
- if (dai->driver->ops->set_tristate)
- return dai->driver->ops->set_tristate(dai, tristate);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
-
-/**
- * snd_soc_dai_digital_mute - configure DAI system or master clock.
- * @dai: DAI
- * @mute: mute enable
- * @direction: stream to mute
- *
- * Mutes the DAI DAC.
- */
-int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
- int direction)
-{
- if (dai->driver->ops->mute_stream)
- return dai->driver->ops->mute_stream(dai, mute, direction);
- else if (direction == SNDRV_PCM_STREAM_PLAYBACK &&
- dai->driver->ops->digital_mute)
- return dai->driver->ops->digital_mute(dai, mute);
- else
- return -ENOTSUPP;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
-
static int snd_soc_bind_card(struct snd_soc_card *card)
{
struct snd_soc_pcm_runtime *rtd;
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
new file mode 100644
index 000000000000..a1009ead40de
--- /dev/null
+++ b/sound/soc/soc-dai.c
@@ -0,0 +1,254 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// soc-dai.c
+//
+// Copyright (C) 2019 Renesas Electronics Corp.
+// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+//
+
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+/**
+ * snd_soc_dai_set_sysclk - configure DAI system or master clock.
+ * @dai: DAI
+ * @clk_id: DAI specific clock ID
+ * @freq: new clock frequency in Hz
+ * @dir: new clock direction - input/output.
+ *
+ * Configures the DAI master (MCLK) or system (SYSCLK) clocking.
+ */
+int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
+ unsigned int freq, int dir)
+{
+ if (dai->driver->ops->set_sysclk)
+ return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir);
+
+ return snd_soc_component_set_sysclk(dai->component, clk_id, 0,
+ freq, dir);
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
+
+/**
+ * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
+ * @dai: DAI
+ * @div_id: DAI specific clock divider ID
+ * @div: new clock divisor.
+ *
+ * Configures the clock dividers. This is used to derive the best DAI bit and
+ * frame clocks from the system or master clock. It's best to set the DAI bit
+ * and frame clocks as low as possible to save system power.
+ */
+int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
+ int div_id, int div)
+{
+ if (dai->driver->ops->set_clkdiv)
+ return dai->driver->ops->set_clkdiv(dai, div_id, div);
+ else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
+
+/**
+ * snd_soc_dai_set_pll - configure DAI PLL.
+ * @dai: DAI
+ * @pll_id: DAI specific PLL ID
+ * @source: DAI specific source for the PLL
+ * @freq_in: PLL input clock frequency in Hz
+ * @freq_out: requested PLL output clock frequency in Hz
+ *
+ * Configures and enables PLL to generate output clock based on input clock.
+ */
+int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
+ unsigned int freq_in, unsigned int freq_out)
+{
+ if (dai->driver->ops->set_pll)
+ return dai->driver->ops->set_pll(dai, pll_id, source,
+ freq_in, freq_out);
+
+ return snd_soc_component_set_pll(dai->component, pll_id, source,
+ freq_in, freq_out);
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
+
+/**
+ * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio.
+ * @dai: DAI
+ * @ratio: Ratio of BCLK to Sample rate.
+ *
+ * Configures the DAI for a preset BCLK to sample rate ratio.
+ */
+int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+ if (dai->driver->ops->set_bclk_ratio)
+ return dai->driver->ops->set_bclk_ratio(dai, ratio);
+ else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio);
+
+/**
+ * snd_soc_dai_set_fmt - configure DAI hardware audio format.
+ * @dai: DAI
+ * @fmt: SND_SOC_DAIFMT_* format value.
+ *
+ * Configures the DAI hardware format and clocking.
+ */
+int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ if (dai->driver->ops->set_fmt == NULL)
+ return -ENOTSUPP;
+ return dai->driver->ops->set_fmt(dai, fmt);
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
+
+/**
+ * snd_soc_xlate_tdm_slot - generate tx/rx slot mask.
+ * @slots: Number of slots in use.
+ * @tx_mask: bitmask representing active TX slots.
+ * @rx_mask: bitmask representing active RX slots.
+ *
+ * Generates the TDM tx and rx slot default masks for DAI.
+ */
+static int snd_soc_xlate_tdm_slot_mask(unsigned int slots,
+ unsigned int *tx_mask,
+ unsigned int *rx_mask)
+{
+ if (*tx_mask || *rx_mask)
+ return 0;
+
+ if (!slots)
+ return -EINVAL;
+
+ *tx_mask = (1 << slots) - 1;
+ *rx_mask = (1 << slots) - 1;
+
+ return 0;
+}
+
+/**
+ * snd_soc_dai_set_tdm_slot() - Configures a DAI for TDM operation
+ * @dai: The DAI to configure
+ * @tx_mask: bitmask representing active TX slots.
+ * @rx_mask: bitmask representing active RX slots.
+ * @slots: Number of slots in use.
+ * @slot_width: Width in bits for each slot.
+ *
+ * This function configures the specified DAI for TDM operation. @slot contains
+ * the total number of slots of the TDM stream and @slot_with the width of each
+ * slot in bit clock cycles. @tx_mask and @rx_mask are bitmasks specifying the
+ * active slots of the TDM stream for the specified DAI, i.e. which slots the
+ * DAI should write to or read from. If a bit is set the corresponding slot is
+ * active, if a bit is cleared the corresponding slot is inactive. Bit 0 maps to
+ * the first slot, bit 1 to the second slot and so on. The first active slot
+ * maps to the first channel of the DAI, the second active slot to the second
+ * channel and so on.
+ *
+ * TDM mode can be disabled by passing 0 for @slots. In this case @tx_mask,
+ * @rx_mask and @slot_width will be ignored.
+ *
+ * Returns 0 on success, a negative error code otherwise.
+ */
+int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
+ unsigned int tx_mask, unsigned int rx_mask,
+ int slots, int slot_width)
+{
+ if (dai->driver->ops->xlate_tdm_slot_mask)
+ dai->driver->ops->xlate_tdm_slot_mask(slots,
+ &tx_mask, &rx_mask);
+ else
+ snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask);
+
+ dai->tx_mask = tx_mask;
+ dai->rx_mask = rx_mask;
+
+ if (dai->driver->ops->set_tdm_slot)
+ return dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask,
+ slots, slot_width);
+ else
+ return -ENOTSUPP;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
+
+/**
+ * snd_soc_dai_set_channel_map - configure DAI audio channel map
+ * @dai: DAI
+ * @tx_num: how many TX channels
+ * @tx_slot: pointer to an array which imply the TX slot number channel
+ * 0~num-1 uses
+ * @rx_num: how many RX channels
+ * @rx_slot: pointer to an array which imply the RX slot number channel
+ * 0~num-1 uses
+ *
+ * configure the relationship between channel number and TDM slot number.
+ */
+int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
+ unsigned int tx_num, unsigned int *tx_slot,
+ unsigned int rx_num, unsigned int *rx_slot)
+{
+ if (dai->driver->ops->set_channel_map)
+ return dai->driver->ops->set_channel_map(dai, tx_num, tx_slot,
+ rx_num, rx_slot);
+ else
+ return -ENOTSUPP;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
+
+/**
+ * snd_soc_dai_get_channel_map - Get DAI audio channel map
+ * @dai: DAI
+ * @tx_num: how many TX channels
+ * @tx_slot: pointer to an array which imply the TX slot number channel
+ * 0~num-1 uses
+ * @rx_num: how many RX channels
+ * @rx_slot: pointer to an array which imply the RX slot number channel
+ * 0~num-1 uses
+ */
+int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
+ unsigned int *tx_num, unsigned int *tx_slot,
+ unsigned int *rx_num, unsigned int *rx_slot)
+{
+ if (dai->driver->ops->get_channel_map)
+ return dai->driver->ops->get_channel_map(dai, tx_num, tx_slot,
+ rx_num, rx_slot);
+ else
+ return -ENOTSUPP;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map);
+
+/**
+ * snd_soc_dai_set_tristate - configure DAI system or master clock.
+ * @dai: DAI
+ * @tristate: tristate enable
+ *
+ * Tristates the DAI so that others can use it.
+ */
+int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
+{
+ if (dai->driver->ops->set_tristate)
+ return dai->driver->ops->set_tristate(dai, tristate);
+ else
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
+
+/**
+ * snd_soc_dai_digital_mute - configure DAI system or master clock.
+ * @dai: DAI
+ * @mute: mute enable
+ * @direction: stream to mute
+ *
+ * Mutes the DAI DAC.
+ */
+int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
+ int direction)
+{
+ if (dai->driver->ops->mute_stream)
+ return dai->driver->ops->mute_stream(dai, mute, direction);
+ else if (direction == SNDRV_PCM_STREAM_PLAYBACK &&
+ dai->driver->ops->digital_mute)
+ return dai->driver->ops->digital_mute(dai, mute);
+ else
+ return -ENOTSUPP;
+}
+EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
--
2.17.1

View File

@ -0,0 +1,179 @@
From 186c94359b9b259bed211034098424a654502d46 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:33:04 +0900
Subject: [PATCH 036/186] FROMGIT: ASoC: soc-dai: mv soc_dai_hw_params() to
soc-dai
Sometimes ALSA SoC naming is very random.
Current soc_dai_hw_params() should use snd_soc_dai_xxx() style.
And then, 1st parameter should be dai. Otherwise it is confusable.
- soc_dai_hw_params(..., dai);
+ snd_soc_dai_hw_params(dai, ...);
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87zhl6hn5b.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit aa6166c2ac28392d64f2d8b3acfb56c8fe657147
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 4 ++++
include/sound/soc.h | 4 ----
sound/soc/soc-dai.c | 30 ++++++++++++++++++++++++++++++
sound/soc/soc-dapm.c | 4 ++--
sound/soc/soc-pcm.c | 35 +++--------------------------------
5 files changed, 39 insertions(+), 38 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index f5d70041108f..3773262a1b77 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -145,6 +145,10 @@ int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai,
int snd_soc_dai_is_dummy(struct snd_soc_dai *dai);
+int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params);
+
struct snd_soc_dai_ops {
/*
* DAI clocking configuration, all optional.
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 4e8071269639..d770606732cd 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -505,10 +505,6 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *parms);
int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
const struct snd_pcm_hardware *hw);
-int soc_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai);
-
/* Jack reporting */
int snd_soc_card_jack_new(struct snd_soc_card *card, const char *id, int type,
struct snd_soc_jack *jack, struct snd_soc_jack_pin *pins,
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index a1009ead40de..f883d27d136f 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -252,3 +252,33 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
return -ENOTSUPP;
}
EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
+
+int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ int ret;
+
+ /* perform any topology hw_params fixups before DAI */
+ if (rtd->dai_link->be_hw_params_fixup) {
+ ret = rtd->dai_link->be_hw_params_fixup(rtd, params);
+ if (ret < 0) {
+ dev_err(rtd->dev,
+ "ASoC: hw_params topology fixup failed %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ if (dai->driver->ops->hw_params) {
+ ret = dai->driver->ops->hw_params(substream, params, dai);
+ if (ret < 0) {
+ dev_err(dai->dev, "ASoC: can't set %s hw params: %d\n",
+ dai->name, ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 2790c00735f3..e86a2d8d4f35 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3841,7 +3841,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
}
}
source->active++;
- ret = soc_dai_hw_params(&substream, params, source);
+ ret = snd_soc_dai_hw_params(source, &substream, params);
if (ret < 0)
goto out;
@@ -3863,7 +3863,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
}
}
sink->active++;
- ret = soc_dai_hw_params(&substream, params, sink);
+ ret = snd_soc_dai_hw_params(sink, &substream, params);
if (ret < 0)
goto out;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 4878d22ebd8c..420cc94e0a46 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -877,36 +877,6 @@ static void soc_pcm_codec_params_fixup(struct snd_pcm_hw_params *params,
interval->max = channels;
}
-int soc_dai_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- int ret;
-
- /* perform any topology hw_params fixups before DAI */
- if (rtd->dai_link->be_hw_params_fixup) {
- ret = rtd->dai_link->be_hw_params_fixup(rtd, params);
- if (ret < 0) {
- dev_err(rtd->dev,
- "ASoC: hw_params topology fixup failed %d\n",
- ret);
- return ret;
- }
- }
-
- if (dai->driver->ops->hw_params) {
- ret = dai->driver->ops->hw_params(substream, params, dai);
- if (ret < 0) {
- dev_err(dai->dev, "ASoC: can't set %s hw params: %d\n",
- dai->name, ret);
- return ret;
- }
- }
-
- return 0;
-}
-
static int soc_pcm_components_hw_free(struct snd_pcm_substream *substream,
struct snd_soc_component *last)
{
@@ -989,7 +959,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
soc_pcm_codec_params_fixup(&codec_params,
codec_dai->rx_mask);
- ret = soc_dai_hw_params(substream, &codec_params, codec_dai);
+ ret = snd_soc_dai_hw_params(codec_dai, substream,
+ &codec_params);
if(ret < 0)
goto codec_err;
@@ -1001,7 +972,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
snd_soc_dapm_update_dai(substream, &codec_params, codec_dai);
}
- ret = soc_dai_hw_params(substream, params, cpu_dai);
+ ret = snd_soc_dai_hw_params(cpu_dai, substream, params);
if (ret < 0)
goto interface_err;
--
2.17.1

View File

@ -0,0 +1,117 @@
From 739c1209f9e4b78b0a55111fbf341321c5731990 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:33:19 +0900
Subject: [PATCH 037/186] FROMGIT: ASoC: soc-dai: add snd_soc_dai_hw_free()
Current ALSA SoC is directly using dai->driver->ops->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_hw_free() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87y30qhn4w.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 846faaed9df7899e74311db3aec0a41a2f6bc345
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 2 ++
sound/soc/soc-dai.c | 7 +++++++
sound/soc/soc-dapm.c | 7 ++-----
sound/soc/soc-pcm.c | 12 ++++--------
4 files changed, 15 insertions(+), 13 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 3773262a1b77..5222b6a758f2 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -148,6 +148,8 @@ int snd_soc_dai_is_dummy(struct snd_soc_dai *dai);
int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params);
+void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index f883d27d136f..39a685e6acd5 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -282,3 +282,10 @@ int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
return 0;
}
+
+void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream)
+{
+ if (dai->driver->ops->hw_free)
+ dai->driver->ops->hw_free(substream, dai);
+}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index e86a2d8d4f35..a9a717376767 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3900,9 +3900,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
snd_soc_dapm_widget_for_each_source_path(w, path) {
source = path->source->priv;
- if (source->driver->ops->hw_free)
- source->driver->ops->hw_free(&substream,
- source);
+ snd_soc_dai_hw_free(source, &substream);
source->active--;
if (source->driver->ops->shutdown)
@@ -3914,8 +3912,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
snd_soc_dapm_widget_for_each_sink_path(w, path) {
sink = path->sink->priv;
- if (sink->driver->ops->hw_free)
- sink->driver->ops->hw_free(&substream, sink);
+ snd_soc_dai_hw_free(sink, &substream);
sink->active--;
if (sink->driver->ops->shutdown)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 420cc94e0a46..58fc4e98ab59 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1011,8 +1011,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
component_err:
soc_pcm_components_hw_free(substream, component);
- if (cpu_dai->driver->ops->hw_free)
- cpu_dai->driver->ops->hw_free(substream, cpu_dai);
+ snd_soc_dai_hw_free(cpu_dai, substream);
cpu_dai->rate = 0;
interface_err:
@@ -1023,8 +1022,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
continue;
- if (codec_dai->driver->ops->hw_free)
- codec_dai->driver->ops->hw_free(substream, codec_dai);
+ snd_soc_dai_hw_free(codec_dai, substream);
codec_dai->rate = 0;
}
@@ -1083,12 +1081,10 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
continue;
- if (codec_dai->driver->ops->hw_free)
- codec_dai->driver->ops->hw_free(substream, codec_dai);
+ snd_soc_dai_hw_free(codec_dai, substream);
}
- if (cpu_dai->driver->ops->hw_free)
- cpu_dai->driver->ops->hw_free(substream, cpu_dai);
+ snd_soc_dai_hw_free(cpu_dai, substream);
mutex_unlock(&rtd->pcm_mutex);
return 0;
--
2.17.1

View File

@ -0,0 +1,148 @@
From 79486aea72e5af750bd0e66ef348b7195d882705 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:33:32 +0900
Subject: [PATCH 038/186] FROMGIT: ASoC: soc-dai: add snd_soc_dai_startup()
Current ALSA SoC is directly using dai->driver->ops->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_startup() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87wogahn4i.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 5a52a04531486e2ab069b7882432c8b266db36e6
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 2 ++
sound/soc/soc-dai.c | 11 +++++++++++
sound/soc/soc-dapm.c | 28 ++++++++++------------------
sound/soc/soc-pcm.c | 27 +++++++++++----------------
4 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 5222b6a758f2..0d16c5bb20bb 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -150,6 +150,8 @@ int snd_soc_dai_hw_params(struct snd_soc_dai *dai,
struct snd_pcm_hw_params *params);
void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
+int snd_soc_dai_startup(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 39a685e6acd5..6e196636e42f 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -289,3 +289,14 @@ void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
if (dai->driver->ops->hw_free)
dai->driver->ops->hw_free(substream, dai);
}
+
+int snd_soc_dai_startup(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+
+ if (dai->driver->ops->startup)
+ ret = dai->driver->ops->startup(substream, dai);
+
+ return ret;
+}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index a9a717376767..07fe331bce94 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3830,15 +3830,11 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
snd_soc_dapm_widget_for_each_source_path(w, path) {
source = path->source->priv;
- if (source->driver->ops->startup) {
- ret = source->driver->ops->startup(&substream,
- source);
- if (ret < 0) {
- dev_err(source->dev,
- "ASoC: startup() failed: %d\n",
- ret);
- goto out;
- }
+ ret = snd_soc_dai_startup(source, &substream);
+ if (ret < 0) {
+ dev_err(source->dev,
+ "ASoC: startup() failed: %d\n", ret);
+ goto out;
}
source->active++;
ret = snd_soc_dai_hw_params(source, &substream, params);
@@ -3852,15 +3848,11 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
snd_soc_dapm_widget_for_each_sink_path(w, path) {
sink = path->sink->priv;
- if (sink->driver->ops->startup) {
- ret = sink->driver->ops->startup(&substream,
- sink);
- if (ret < 0) {
- dev_err(sink->dev,
- "ASoC: startup() failed: %d\n",
- ret);
- goto out;
- }
+ ret = snd_soc_dai_startup(sink, &substream);
+ if (ret < 0) {
+ dev_err(sink->dev,
+ "ASoC: startup() failed: %d\n", ret);
+ goto out;
}
sink->active++;
ret = snd_soc_dai_hw_params(sink, &substream, params);
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 58fc4e98ab59..9c8713a3eef1 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -535,13 +535,11 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
mutex_lock_nested(&rtd->pcm_mutex, rtd->pcm_subclass);
/* startup the audio subsystem */
- if (cpu_dai->driver->ops->startup) {
- ret = cpu_dai->driver->ops->startup(substream, cpu_dai);
- if (ret < 0) {
- dev_err(cpu_dai->dev, "ASoC: can't open interface"
- " %s: %d\n", cpu_dai->name, ret);
- goto out;
- }
+ ret = snd_soc_dai_startup(cpu_dai, substream);
+ if (ret < 0) {
+ dev_err(cpu_dai->dev, "ASoC: can't open interface %s: %d\n",
+ cpu_dai->name, ret);
+ goto out;
}
ret = soc_pcm_components_open(substream, &component);
@@ -549,15 +547,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
goto component_err;
for_each_rtd_codec_dai(rtd, i, codec_dai) {
- if (codec_dai->driver->ops->startup) {
- ret = codec_dai->driver->ops->startup(substream,
- codec_dai);
- if (ret < 0) {
- dev_err(codec_dai->dev,
- "ASoC: can't open codec %s: %d\n",
- codec_dai->name, ret);
- goto codec_dai_err;
- }
+ ret = snd_soc_dai_startup(codec_dai, substream);
+ if (ret < 0) {
+ dev_err(codec_dai->dev,
+ "ASoC: can't open codec %s: %d\n",
+ codec_dai->name, ret);
+ goto codec_dai_err;
}
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
--
2.17.1

View File

@ -0,0 +1,119 @@
From 8e824fedd82f021536a4963d061b3171de15d3c6 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:33:39 +0900
Subject: [PATCH 039/186] FROMGIT: ASoC: soc-dai: add snd_soc_dai_shutdown()
Current ALSA SoC is directly using dai->driver->ops->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_shutdown() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87v9vuhn4b.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 330fcb5135e0588b1ea3b0bbab587d1317c1cf7b
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 2 ++
sound/soc/soc-dai.c | 7 +++++++
sound/soc/soc-dapm.c | 7 ++-----
sound/soc/soc-pcm.c | 18 ++++++------------
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 0d16c5bb20bb..32545d457b3d 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -152,6 +152,8 @@ void snd_soc_dai_hw_free(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
int snd_soc_dai_startup(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
+void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 6e196636e42f..67ff6cc1fe02 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -300,3 +300,10 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai,
return ret;
}
+
+void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream)
+{
+ if (dai->driver->ops->shutdown)
+ dai->driver->ops->shutdown(substream, dai);
+}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 07fe331bce94..bf0481df870d 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3895,9 +3895,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
snd_soc_dai_hw_free(source, &substream);
source->active--;
- if (source->driver->ops->shutdown)
- source->driver->ops->shutdown(&substream,
- source);
+ snd_soc_dai_shutdown(source, &substream);
}
substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -3907,8 +3905,7 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
snd_soc_dai_hw_free(sink, &substream);
sink->active--;
- if (sink->driver->ops->shutdown)
- sink->driver->ops->shutdown(&substream, sink);
+ snd_soc_dai_shutdown(sink, &substream);
}
break;
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 9c8713a3eef1..ed5ae23c7104 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -641,16 +641,13 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
i = rtd->num_codecs;
codec_dai_err:
- for_each_rtd_codec_dai_rollback(rtd, i, codec_dai) {
- if (codec_dai->driver->ops->shutdown)
- codec_dai->driver->ops->shutdown(substream, codec_dai);
- }
+ for_each_rtd_codec_dai_rollback(rtd, i, codec_dai)
+ snd_soc_dai_shutdown(codec_dai, substream);
component_err:
soc_pcm_components_close(substream, component);
- if (cpu_dai->driver->ops->shutdown)
- cpu_dai->driver->ops->shutdown(substream, cpu_dai);
+ snd_soc_dai_shutdown(cpu_dai, substream);
out:
mutex_unlock(&rtd->pcm_mutex);
@@ -728,13 +725,10 @@ static int soc_pcm_close(struct snd_pcm_substream *substream)
snd_soc_dai_digital_mute(cpu_dai, 1, substream->stream);
- if (cpu_dai->driver->ops->shutdown)
- cpu_dai->driver->ops->shutdown(substream, cpu_dai);
+ snd_soc_dai_shutdown(cpu_dai, substream);
- for_each_rtd_codec_dai(rtd, i, codec_dai) {
- if (codec_dai->driver->ops->shutdown)
- codec_dai->driver->ops->shutdown(substream, codec_dai);
- }
+ for_each_rtd_codec_dai(rtd, i, codec_dai)
+ snd_soc_dai_shutdown(codec_dai, substream);
if (rtd->dai_link->ops->shutdown)
rtd->dai_link->ops->shutdown(substream);
--
2.17.1

View File

@ -0,0 +1,99 @@
From 7b837045cc43ffcce0e6166c756680e54ce2f362 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:33:45 +0900
Subject: [PATCH 040/186] FROMGIT: ASoC: soc-dai: add snd_soc_dai_prepare()
Current ALSA SoC is directly using dai->driver->ops->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_prepare() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tvbehn46.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 4beb8e109d30d339d44308a767dd6f5614492f3e
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 2 ++
sound/soc/soc-dai.c | 11 +++++++++++
sound/soc/soc-pcm.c | 27 +++++++++++----------------
3 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 32545d457b3d..c7dff6a0b5b9 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -154,6 +154,8 @@ int snd_soc_dai_startup(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
+int snd_soc_dai_prepare(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 67ff6cc1fe02..cb810888c563 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -307,3 +307,14 @@ void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
if (dai->driver->ops->shutdown)
dai->driver->ops->shutdown(substream, dai);
}
+
+int snd_soc_dai_prepare(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream)
+{
+ int ret = 0;
+
+ if (dai->driver->ops->prepare)
+ ret = dai->driver->ops->prepare(substream, dai);
+
+ return ret;
+}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index ed5ae23c7104..d7611af90dce 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -814,27 +814,22 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
}
for_each_rtd_codec_dai(rtd, i, codec_dai) {
- if (codec_dai->driver->ops->prepare) {
- ret = codec_dai->driver->ops->prepare(substream,
- codec_dai);
- if (ret < 0) {
- dev_err(codec_dai->dev,
- "ASoC: codec DAI prepare error: %d\n",
- ret);
- goto out;
- }
- }
- }
-
- if (cpu_dai->driver->ops->prepare) {
- ret = cpu_dai->driver->ops->prepare(substream, cpu_dai);
+ ret = snd_soc_dai_prepare(codec_dai, substream);
if (ret < 0) {
- dev_err(cpu_dai->dev,
- "ASoC: cpu DAI prepare error: %d\n", ret);
+ dev_err(codec_dai->dev,
+ "ASoC: codec DAI prepare error: %d\n",
+ ret);
goto out;
}
}
+ ret = snd_soc_dai_prepare(cpu_dai, substream);
+ if (ret < 0) {
+ dev_err(cpu_dai->dev,
+ "ASoC: cpu DAI prepare error: %d\n", ret);
+ goto out;
+ }
+
/* cancel any delayed stream shutdown that is pending */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
rtd->pop_wait) {
--
2.17.1

View File

@ -0,0 +1,92 @@
From 657967d6bb1642fcebcebba9f50839158f428130 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:33:51 +0900
Subject: [PATCH 041/186] FROMGIT: ASoC: soc-dai: add snd_soc_dai_trigger()
Current ALSA SoC is directly using dai->driver->ops->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_trigger() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87sgqyhn40.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 95aef35533844f35544851b0cdc1fc154b603307
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 2 ++
sound/soc/soc-dai.c | 12 ++++++++++++
sound/soc/soc-pcm.c | 17 ++++++-----------
3 files changed, 20 insertions(+), 11 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index c7dff6a0b5b9..72b8e76f1cc4 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -156,6 +156,8 @@ void snd_soc_dai_shutdown(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
int snd_soc_dai_prepare(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
+int snd_soc_dai_trigger(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream, int cmd);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index cb810888c563..18c447e169f6 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -318,3 +318,15 @@ int snd_soc_dai_prepare(struct snd_soc_dai *dai,
return ret;
}
+
+int snd_soc_dai_trigger(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream,
+ int cmd)
+{
+ int ret = 0;
+
+ if (dai->driver->ops->trigger)
+ ret = dai->driver->ops->trigger(substream, cmd, dai);
+
+ return ret;
+}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index d7611af90dce..a628b08f966e 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1084,12 +1084,9 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
int i, ret;
for_each_rtd_codec_dai(rtd, i, codec_dai) {
- if (codec_dai->driver->ops->trigger) {
- ret = codec_dai->driver->ops->trigger(substream,
- cmd, codec_dai);
- if (ret < 0)
- return ret;
- }
+ ret = snd_soc_dai_trigger(codec_dai, substream, cmd);
+ if (ret < 0)
+ return ret;
}
for_each_rtdcom(rtd, rtdcom) {
@@ -1104,11 +1101,9 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
return ret;
}
- if (cpu_dai->driver->ops->trigger) {
- ret = cpu_dai->driver->ops->trigger(substream, cmd, cpu_dai);
- if (ret < 0)
- return ret;
- }
+ snd_soc_dai_trigger(cpu_dai, substream, cmd);
+ if (ret < 0)
+ return ret;
if (rtd->dai_link->ops->trigger) {
ret = rtd->dai_link->ops->trigger(substream, cmd);
--
2.17.1

View File

@ -0,0 +1,88 @@
From c7fef0a5672740f7fed5b42a16c15b1b6ec96e82 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:33:56 +0900
Subject: [PATCH 042/186] FROMGIT: ASoC: soc-dai: add
snd_soc_dai_bespoke_trigger()
Current ALSA SoC is directly using dai->driver->ops->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_bespoke_trigger() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87r26ihn3u.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 5c0769af4caf8fbdad2e9c0051ab0081b8e22b0a
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 2 ++
sound/soc/soc-dai.c | 12 ++++++++++++
sound/soc/soc-pcm.c | 16 ++++++----------
3 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 72b8e76f1cc4..6a5566d459ad 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -158,6 +158,8 @@ int snd_soc_dai_prepare(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
int snd_soc_dai_trigger(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream, int cmd);
+int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream, int cmd);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 18c447e169f6..6f466cfcbeef 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -330,3 +330,15 @@ int snd_soc_dai_trigger(struct snd_soc_dai *dai,
return ret;
}
+
+int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream,
+ int cmd)
+{
+ int ret = 0;
+
+ if (dai->driver->ops->bespoke_trigger)
+ ret = dai->driver->ops->bespoke_trigger(substream, cmd, dai);
+
+ return ret;
+}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index a628b08f966e..a10627f1ceff 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1123,19 +1123,15 @@ static int soc_pcm_bespoke_trigger(struct snd_pcm_substream *substream,
int i, ret;
for_each_rtd_codec_dai(rtd, i, codec_dai) {
- if (codec_dai->driver->ops->bespoke_trigger) {
- ret = codec_dai->driver->ops->bespoke_trigger(substream,
- cmd, codec_dai);
- if (ret < 0)
- return ret;
- }
- }
-
- if (cpu_dai->driver->ops->bespoke_trigger) {
- ret = cpu_dai->driver->ops->bespoke_trigger(substream, cmd, cpu_dai);
+ ret = snd_soc_dai_bespoke_trigger(codec_dai, substream, cmd);
if (ret < 0)
return ret;
}
+
+ snd_soc_dai_bespoke_trigger(cpu_dai, substream, cmd);
+ if (ret < 0)
+ return ret;
+
return 0;
}
/*
--
2.17.1

View File

@ -0,0 +1,78 @@
From 7bd44b68e358463510633ef365862b41e5befede Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:34:09 +0900
Subject: [PATCH 043/186] FROMGIT: ASoC: soc-dai: add snd_soc_dai_delay()
Current ALSA SoC is directly using dai->driver->ops->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_delay() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87o91mhn3i.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 1dea80d4b2bd3b53c58f008ca2bcd73182583711
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 2 ++
sound/soc/soc-dai.c | 11 +++++++++++
sound/soc/soc-pcm.c | 9 +++------
3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 6a5566d459ad..7cfed3034511 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -160,6 +160,8 @@ int snd_soc_dai_trigger(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream, int cmd);
int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream, int cmd);
+snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 6f466cfcbeef..5b5b979cd1f3 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -342,3 +342,14 @@ int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
return ret;
}
+
+snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
+ struct snd_pcm_substream *substream)
+{
+ int delay = 0;
+
+ if (dai->driver->ops->delay)
+ delay = dai->driver->ops->delay(substream, dai);
+
+ return delay;
+}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index a10627f1ceff..f3137723301c 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1169,14 +1169,11 @@ static snd_pcm_uframes_t soc_pcm_pointer(struct snd_pcm_substream *substream)
/* base delay if assigned in pointer callback */
delay = runtime->delay;
- if (cpu_dai->driver->ops->delay)
- delay += cpu_dai->driver->ops->delay(substream, cpu_dai);
+ delay += snd_soc_dai_delay(cpu_dai, substream);
for_each_rtd_codec_dai(rtd, i, codec_dai) {
- if (codec_dai->driver->ops->delay)
- codec_delay = max(codec_delay,
- codec_dai->driver->ops->delay(substream,
- codec_dai));
+ codec_delay = max(codec_delay,
+ snd_soc_dai_delay(codec_dai, substream));
}
delay += codec_delay;
--
2.17.1

View File

@ -0,0 +1,76 @@
From 215effc50526e67beb8744170d9528ab094fee66 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:34:29 +0900
Subject: [PATCH 044/186] FROMGIT: ASoC: soc-dai: add snd_soc_dai_suspend()
Current ALSA SoC is directly using dai->driver->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_suspend() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87muh6hn2x.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit e0f2262292d0c8160cfd9a8c40425107fb65ab29
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 1 +
sound/soc/soc-core.c | 8 ++++----
sound/soc/soc-dai.c | 6 ++++++
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 7cfed3034511..6c5604a7dbc2 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -162,6 +162,7 @@ int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream, int cmd);
snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
+void snd_soc_dai_suspend(struct snd_soc_dai *dai);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a8d2c4ec0ec9..1060836b63fb 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -511,8 +511,8 @@ int snd_soc_suspend(struct device *dev)
if (rtd->dai_link->ignore_suspend)
continue;
- if (cpu_dai->driver->suspend && !cpu_dai->driver->bus_control)
- cpu_dai->driver->suspend(cpu_dai);
+ if (!cpu_dai->driver->bus_control)
+ snd_soc_dai_suspend(cpu_dai);
}
/* close any waiting streams */
@@ -584,8 +584,8 @@ int snd_soc_suspend(struct device *dev)
if (rtd->dai_link->ignore_suspend)
continue;
- if (cpu_dai->driver->suspend && cpu_dai->driver->bus_control)
- cpu_dai->driver->suspend(cpu_dai);
+ if (cpu_dai->driver->bus_control)
+ snd_soc_dai_suspend(cpu_dai);
/* deactivate pins to sleep state */
pinctrl_pm_select_sleep_state(cpu_dai->dev);
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 5b5b979cd1f3..3373598e0682 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -353,3 +353,9 @@ snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
return delay;
}
+
+void snd_soc_dai_suspend(struct snd_soc_dai *dai)
+{
+ if (dai->driver->suspend)
+ dai->driver->suspend(dai);
+}
--
2.17.1

View File

@ -0,0 +1,76 @@
From b756a9e8916d2c52eff076b01b56337e0cccfb9b Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:34:43 +0900
Subject: [PATCH 045/186] FROMGIT: ASoC: soc-dai: add snd_soc_dai_resume()
Current ALSA SoC is directly using dai->driver->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_resume() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87lfwqhn2j.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 24b09d051164680f0a1d1910efe21ce36ad5c1ca
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 1 +
sound/soc/soc-core.c | 8 ++++----
sound/soc/soc-dai.c | 6 ++++++
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 6c5604a7dbc2..ed78e34a814e 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -163,6 +163,7 @@ int snd_soc_dai_bespoke_trigger(struct snd_soc_dai *dai,
snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
void snd_soc_dai_suspend(struct snd_soc_dai *dai);
+void snd_soc_dai_resume(struct snd_soc_dai *dai);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 1060836b63fb..c08d4fff01a6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -631,8 +631,8 @@ static void soc_resume_deferred(struct work_struct *work)
if (rtd->dai_link->ignore_suspend)
continue;
- if (cpu_dai->driver->resume && cpu_dai->driver->bus_control)
- cpu_dai->driver->resume(cpu_dai);
+ if (cpu_dai->driver->bus_control)
+ snd_soc_dai_resume(cpu_dai);
}
for_each_card_components(card, component) {
@@ -678,8 +678,8 @@ static void soc_resume_deferred(struct work_struct *work)
if (rtd->dai_link->ignore_suspend)
continue;
- if (cpu_dai->driver->resume && !cpu_dai->driver->bus_control)
- cpu_dai->driver->resume(cpu_dai);
+ if (!cpu_dai->driver->bus_control)
+ snd_soc_dai_resume(cpu_dai);
}
if (card->resume_post)
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 3373598e0682..ddb6f217c0ed 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -359,3 +359,9 @@ void snd_soc_dai_suspend(struct snd_soc_dai *dai)
if (dai->driver->suspend)
dai->driver->suspend(dai);
}
+
+void snd_soc_dai_resume(struct snd_soc_dai *dai)
+{
+ if (dai->driver->resume)
+ dai->driver->resume(dai);
+}
--
2.17.1

View File

@ -0,0 +1,81 @@
From ce0aa1837af6ec9964c313f381406c72c697965a Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:34:56 +0900
Subject: [PATCH 046/186] FROMGIT: ASoC: soc-dai: add snd_soc_dai_probe()
Current ALSA SoC is directly using dai->driver->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_probe() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87k1cahn26.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit cfd9b5fbfe1e8763018aea2600aa0d6ff015ebfc
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 1 +
sound/soc/soc-core.c | 15 +++++++--------
sound/soc/soc-dai.c | 7 +++++++
3 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index ed78e34a814e..da8d8b889089 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -164,6 +164,7 @@ snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
struct snd_pcm_substream *substream);
void snd_soc_dai_suspend(struct snd_soc_dai *dai);
void snd_soc_dai_resume(struct snd_soc_dai *dai);
+int snd_soc_dai_probe(struct snd_soc_dai *dai);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index c08d4fff01a6..d78f132174b1 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1434,18 +1434,17 @@ static int soc_probe_link_components(struct snd_soc_card *card,
static int soc_probe_dai(struct snd_soc_dai *dai, int order)
{
+ int ret;
+
if (dai->probed ||
dai->driver->probe_order != order)
return 0;
- if (dai->driver->probe) {
- int ret = dai->driver->probe(dai);
-
- if (ret < 0) {
- dev_err(dai->dev, "ASoC: failed to probe DAI %s: %d\n",
- dai->name, ret);
- return ret;
- }
+ ret = snd_soc_dai_probe(dai);
+ if (ret < 0) {
+ dev_err(dai->dev, "ASoC: failed to probe DAI %s: %d\n",
+ dai->name, ret);
+ return ret;
}
dai->probed = 1;
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index ddb6f217c0ed..55c1fac99613 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -365,3 +365,10 @@ void snd_soc_dai_resume(struct snd_soc_dai *dai)
if (dai->driver->resume)
dai->driver->resume(dai);
}
+
+int snd_soc_dai_probe(struct snd_soc_dai *dai)
+{
+ if (dai->driver->probe)
+ return dai->driver->probe(dai);
+ return 0;
+}
--
2.17.1

View File

@ -0,0 +1,75 @@
From c94cf46d290db59db9f694a8e761f7876963c802 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:35:05 +0900
Subject: [PATCH 047/186] FROMGIT: ASoC: soc-dai: add snd_soc_dai_remove()
Current ALSA SoC is directly using dai->driver->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_remvoe() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87imruhn1x.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit dcdab5820edd6123911dbd767ee1e389008b6a83
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 1 +
sound/soc/soc-core.c | 13 ++++++-------
sound/soc/soc-dai.c | 7 +++++++
3 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index da8d8b889089..2a11f177ce01 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -165,6 +165,7 @@ snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai,
void snd_soc_dai_suspend(struct snd_soc_dai *dai);
void snd_soc_dai_resume(struct snd_soc_dai *dai);
int snd_soc_dai_probe(struct snd_soc_dai *dai);
+int snd_soc_dai_remove(struct snd_soc_dai *dai);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d78f132174b1..8a55735c4311 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -992,13 +992,12 @@ static void soc_remove_dai(struct snd_soc_dai *dai, int order)
dai->driver->remove_order != order)
return;
- if (dai->driver->remove) {
- err = dai->driver->remove(dai);
- if (err < 0)
- dev_err(dai->dev,
- "ASoC: failed to remove %s: %d\n",
- dai->name, err);
- }
+ err = snd_soc_dai_remove(dai);
+ if (err < 0)
+ dev_err(dai->dev,
+ "ASoC: failed to remove %s: %d\n",
+ dai->name, err);
+
dai->probed = 0;
}
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 55c1fac99613..384765c747da 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -372,3 +372,10 @@ int snd_soc_dai_probe(struct snd_soc_dai *dai)
return dai->driver->probe(dai);
return 0;
}
+
+int snd_soc_dai_remove(struct snd_soc_dai *dai)
+{
+ if (dai->driver->remove)
+ return dai->driver->remove(dai);
+ return 0;
+}
--
2.17.1

View File

@ -0,0 +1,82 @@
From 97003da8c2d39f2eef55f82b5a226871d6831ae6 Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:35:29 +0900
Subject: [PATCH 048/186] FROMGIT: ASoC: soc-dai: add
snd_soc_dai_compress_new()
Current ALSA SoC is directly using dai->driver->xxx,
thus, it has deep nested bracket, and it makes code unreadable.
This patch adds new snd_soc_dai_compress_new() and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87h87ehn1a.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit b423c4202135f7794e0a9c55a884f5933d8e7156
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 2 ++
sound/soc/soc-core.c | 15 ++++++++-------
sound/soc/soc-dai.c | 8 ++++++++
3 files changed, 18 insertions(+), 7 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 2a11f177ce01..0f8b09520020 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -166,6 +166,8 @@ void snd_soc_dai_suspend(struct snd_soc_dai *dai);
void snd_soc_dai_resume(struct snd_soc_dai *dai);
int snd_soc_dai_probe(struct snd_soc_dai *dai);
int snd_soc_dai_remove(struct snd_soc_dai *dai);
+int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
+ struct snd_soc_pcm_runtime *rtd, int num);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 8a55735c4311..33df0dfe29f0 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1548,15 +1548,16 @@ static int soc_probe_link_dais(struct snd_soc_card *card,
num = rtd->dai_link->id;
}
- if (cpu_dai->driver->compress_new) {
- /* create compress_device" */
- ret = cpu_dai->driver->compress_new(rtd, num);
- if (ret < 0) {
+ /* create compress_device if possible */
+ ret = snd_soc_dai_compress_new(cpu_dai, rtd, num);
+ if (ret != -ENOTSUPP) {
+ if (ret < 0)
dev_err(card->dev, "ASoC: can't create compress %s\n",
dai_link->stream_name);
- return ret;
- }
- } else if (!dai_link->params) {
+ return ret;
+ }
+
+ if (!dai_link->params) {
/* create the pcm */
ret = soc_new_pcm(rtd, num);
if (ret < 0) {
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index 384765c747da..e6f161b9f975 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -379,3 +379,11 @@ int snd_soc_dai_remove(struct snd_soc_dai *dai)
return dai->driver->remove(dai);
return 0;
}
+
+int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
+ struct snd_soc_pcm_runtime *rtd, int num)
+{
+ if (dai->driver->compress_new)
+ return dai->driver->compress_new(rtd, num);
+ return -ENOTSUPP;
+}
--
2.17.1

View File

@ -0,0 +1,172 @@
From 66ef91fbbccf3e259e77e1a83dcc8717565cb65f Mon Sep 17 00:00:00 2001
From: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date: Mon, 22 Jul 2019 10:36:16 +0900
Subject: [PATCH 049/186] FROMGIT: ASoC: soc-dai: move
snd_soc_dai_stream_valid() to soc-dai.c
snd_soc_dai_stream_valid() is function to check stream validity.
But, some code is using it, some code are checking stream->channels_min
directly. Doing samethings by different method is confusable.
This patch uses same funcntion for same purpose.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87ftmyhmzz.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 467fece8fbc6774a3a3bd0981e1a342fb5022706
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
include/sound/soc-dai.h | 1 +
sound/soc/soc-compress.c | 9 ++++-----
sound/soc/soc-dai.c | 18 ++++++++++++++++++
sound/soc/soc-pcm.c | 39 ++++++++++-----------------------------
4 files changed, 33 insertions(+), 34 deletions(-)
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h
index 0f8b09520020..dc48fe081a20 100644
--- a/include/sound/soc-dai.h
+++ b/include/sound/soc-dai.h
@@ -168,6 +168,7 @@ int snd_soc_dai_probe(struct snd_soc_dai *dai);
int snd_soc_dai_remove(struct snd_soc_dai *dai);
int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
struct snd_soc_pcm_runtime *rtd, int num);
+bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream);
struct snd_soc_dai_ops {
/*
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c
index ddef4ff677ce..289211069a1e 100644
--- a/sound/soc/soc-compress.c
+++ b/sound/soc/soc-compress.c
@@ -872,14 +872,13 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num)
}
/* check client and interface hw capabilities */
- if (codec_dai->driver->playback.channels_min)
+ if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
+ snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
playback = 1;
- if (codec_dai->driver->capture.channels_min)
+ if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
+ snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
capture = 1;
- capture = capture && cpu_dai->driver->capture.channels_min;
- playback = playback && cpu_dai->driver->playback.channels_min;
-
/*
* Compress devices are unidirectional so only one of the directions
* should be set, check for that (xor)
diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c
index e6f161b9f975..1c7f63871c1d 100644
--- a/sound/soc/soc-dai.c
+++ b/sound/soc/soc-dai.c
@@ -387,3 +387,21 @@ int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
return dai->driver->compress_new(rtd, num);
return -ENOTSUPP;
}
+
+/*
+ * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
+ *
+ * Returns true if the DAI supports the indicated stream type.
+ */
+bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir)
+{
+ struct snd_soc_pcm_stream *stream;
+
+ if (dir == SNDRV_PCM_STREAM_PLAYBACK)
+ stream = &dai->driver->playback;
+ else
+ stream = &dai->driver->capture;
+
+ /* If the codec specifies any channels at all, it supports the stream */
+ return stream->channels_min;
+}
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index f3137723301c..fabeac164a6c 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -29,24 +29,6 @@
#define DPCM_MAX_BE_USERS 8
-/*
- * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
- *
- * Returns true if the DAI supports the indicated stream type.
- */
-static bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream)
-{
- struct snd_soc_pcm_stream *codec_stream;
-
- if (stream == SNDRV_PCM_STREAM_PLAYBACK)
- codec_stream = &dai->driver->playback;
- else
- codec_stream = &dai->driver->capture;
-
- /* If the codec specifies any channels at all, it supports the stream */
- return codec_stream->channels_min;
-}
-
/**
* snd_soc_runtime_activate() - Increment active count for PCM runtime components
* @rtd: ASoC PCM runtime that is activated
@@ -2688,8 +2670,8 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
new ? "new" : "old", fe->dai_link->name);
/* skip if FE doesn't have playback capability */
- if (!fe->cpu_dai->driver->playback.channels_min ||
- !fe->codec_dai->driver->playback.channels_min)
+ if (!snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_PLAYBACK) ||
+ !snd_soc_dai_stream_valid(fe->codec_dai, SNDRV_PCM_STREAM_PLAYBACK))
goto capture;
/* skip if FE isn't currently playing */
@@ -2719,8 +2701,8 @@ static int soc_dpcm_fe_runtime_update(struct snd_soc_pcm_runtime *fe, int new)
capture:
/* skip if FE doesn't have capture capability */
- if (!fe->cpu_dai->driver->capture.channels_min ||
- !fe->codec_dai->driver->capture.channels_min)
+ if (!snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_CAPTURE) ||
+ !snd_soc_dai_stream_valid(fe->codec_dai, SNDRV_PCM_STREAM_CAPTURE))
return 0;
/* skip if FE isn't currently capturing */
@@ -3030,14 +3012,13 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
capture = rtd->dai_link->dpcm_capture;
} else {
for_each_rtd_codec_dai(rtd, i, codec_dai) {
- if (codec_dai->driver->playback.channels_min)
+ if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
+ snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
playback = 1;
- if (codec_dai->driver->capture.channels_min)
+ if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_CAPTURE) &&
+ snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
capture = 1;
}
-
- capture = capture && cpu_dai->driver->capture.channels_min;
- playback = playback && cpu_dai->driver->playback.channels_min;
}
if (rtd->dai_link->playback_only) {
@@ -3375,11 +3356,11 @@ static ssize_t dpcm_state_read_file(struct file *file, char __user *user_buf,
if (!buf)
return -ENOMEM;
- if (fe->cpu_dai->driver->playback.channels_min)
+ if (snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_PLAYBACK,
buf + offset, out_count - offset);
- if (fe->cpu_dai->driver->capture.channels_min)
+ if (snd_soc_dai_stream_valid(fe->cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
offset += dpcm_show_state(fe, SNDRV_PCM_STREAM_CAPTURE,
buf + offset, out_count - offset);
--
2.17.1

View File

@ -0,0 +1,93 @@
From bbb30231a2b10c7f5b76066946a3ee6328e35608 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 25 Jul 2019 18:59:44 +0200
Subject: [PATCH 050/186] FROMGIT: ASoC: codec2codec: run callbacks in order
When handling dai_link events on codec to codec links, run all .startup()
callbacks on sinks and sources before running any .hw_params(). Same goes
for hw_free() and shutdown(). This is closer to the behavior of regular
dai links
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20190725165949.29699-2-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 68c907f10cd816cad2287167a1a1d77914a6d466
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
sound/soc/soc-dapm.c | 36 +++++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index bf0481df870d..6d84aac8b54c 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3837,11 +3837,6 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
goto out;
}
source->active++;
- ret = snd_soc_dai_hw_params(source, &substream, params);
- if (ret < 0)
- goto out;
-
- dapm_update_dai_unlocked(&substream, params, source);
}
substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
@@ -3855,6 +3850,23 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
goto out;
}
sink->active++;
+ }
+
+ substream.stream = SNDRV_PCM_STREAM_CAPTURE;
+ snd_soc_dapm_widget_for_each_source_path(w, path) {
+ source = path->source->priv;
+
+ ret = snd_soc_dai_hw_params(source, &substream, params);
+ if (ret < 0)
+ goto out;
+
+ dapm_update_dai_unlocked(&substream, params, source);
+ }
+
+ substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
+ snd_soc_dapm_widget_for_each_sink_path(w, path) {
+ sink = path->sink->priv;
+
ret = snd_soc_dai_hw_params(sink, &substream, params);
if (ret < 0)
goto out;
@@ -3891,9 +3903,18 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
substream.stream = SNDRV_PCM_STREAM_CAPTURE;
snd_soc_dapm_widget_for_each_source_path(w, path) {
source = path->source->priv;
-
snd_soc_dai_hw_free(source, &substream);
+ }
+
+ substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
+ snd_soc_dapm_widget_for_each_sink_path(w, path) {
+ sink = path->sink->priv;
+ snd_soc_dai_hw_free(sink, &substream);
+ }
+ substream.stream = SNDRV_PCM_STREAM_CAPTURE;
+ snd_soc_dapm_widget_for_each_source_path(w, path) {
+ source = path->source->priv;
source->active--;
snd_soc_dai_shutdown(source, &substream);
}
@@ -3901,9 +3922,6 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
snd_soc_dapm_widget_for_each_sink_path(w, path) {
sink = path->sink->priv;
-
- snd_soc_dai_hw_free(sink, &substream);
-
sink->active--;
snd_soc_dai_shutdown(sink, &substream);
}
--
2.17.1

View File

@ -0,0 +1,77 @@
From 4073a9679c656970bd3e13045a059045dd81023e Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 25 Jul 2019 18:59:45 +0200
Subject: [PATCH 051/186] FROMGIT: ASoC: codec2codec: name link using stream
direction
At the moment, codec to codec dai link widgets are named after the
cpu dai and the 1st codec valid on the link. This might be confusing
if there is multiple valid codecs on the link for one stream
direction.
Instead, use the dai link name and the stream direction to name the
the dai link widget
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20190725165949.29699-3-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 054d65004c6a008dfefbdae4fc1b46a3ad4e94c1
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
sound/soc/soc-dapm.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 6d84aac8b54c..17286bfec258 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -4058,8 +4058,7 @@ snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card,
static struct snd_soc_dapm_widget *
snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
- struct snd_soc_dapm_widget *source,
- struct snd_soc_dapm_widget *sink)
+ char *id)
{
struct snd_soc_dapm_widget template;
struct snd_soc_dapm_widget *w;
@@ -4069,7 +4068,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
int ret;
link_name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-%s",
- source->name, sink->name);
+ rtd->dai_link->name, id);
if (!link_name)
return ERR_PTR(-ENOMEM);
@@ -4249,15 +4248,13 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
}
for_each_rtd_codec_dai(rtd, i, codec_dai) {
-
/* connect BE DAI playback if widgets are valid */
codec = codec_dai->playback_widget;
if (playback_cpu && codec) {
if (!playback) {
playback = snd_soc_dapm_new_dai(card, rtd,
- playback_cpu,
- codec);
+ "playback");
if (IS_ERR(playback)) {
dev_err(rtd->dev,
"ASoC: Failed to create DAI %s: %ld\n",
@@ -4286,8 +4283,7 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
if (codec && capture_cpu) {
if (!capture) {
capture = snd_soc_dapm_new_dai(card, rtd,
- codec,
- capture_cpu);
+ "capture");
if (IS_ERR(capture)) {
dev_err(rtd->dev,
"ASoC: Failed to create DAI %s: %ld\n",
--
2.17.1

View File

@ -0,0 +1,239 @@
From ba8f6ce6d234a44e9746735174f3c80b649a4e19 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 25 Jul 2019 18:59:46 +0200
Subject: [PATCH 052/186] FROMGIT: ASoC: codec2codec: deal with params when
necessary
When there is an event on codec to codec dai_link, we only need to deal
with params if the event is SND_SOC_DAPM_PRE_PMU, when .hw_params() is
called. For the other events, it is useless.
Also, dealing with the codec to codec params just before calling
.hw_params() callbacks give change to either party on the link to alter
params content in .startup(), which might be useful in some cases
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20190725165949.29699-4-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 3dcfb397dad2ad55bf50de3c5d5a57090d35a18a
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
sound/soc/soc-dapm.c | 159 +++++++++++++++++++++++++------------------
1 file changed, 92 insertions(+), 67 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 17286bfec258..be9bb05b0165 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3766,25 +3766,59 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
}
EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
-static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
+static int
+snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
+ struct snd_pcm_substream *substream)
{
struct snd_soc_dapm_path *path;
struct snd_soc_dai *source, *sink;
- struct snd_soc_pcm_runtime *rtd = w->priv;
- const struct snd_soc_pcm_stream *config;
- struct snd_pcm_substream substream;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_hw_params *params = NULL;
- struct snd_pcm_runtime *runtime = NULL;
+ const struct snd_soc_pcm_stream *config = NULL;
unsigned int fmt;
- int ret = 0;
+ int ret;
- config = rtd->dai_link->params + rtd->params_select;
+ params = kzalloc(sizeof(*params), GFP_KERNEL);
+ if (!params)
+ return -ENOMEM;
- if (WARN_ON(!config) ||
- WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) ||
- list_empty(&w->edges[SND_SOC_DAPM_DIR_IN])))
- return -EINVAL;
+ substream->stream = SNDRV_PCM_STREAM_CAPTURE;
+ snd_soc_dapm_widget_for_each_source_path(w, path) {
+ source = path->source->priv;
+
+ ret = snd_soc_dai_startup(source, substream);
+ if (ret < 0) {
+ dev_err(source->dev,
+ "ASoC: startup() failed: %d\n", ret);
+ goto out;
+ }
+ source->active++;
+ }
+
+ substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
+ snd_soc_dapm_widget_for_each_sink_path(w, path) {
+ sink = path->sink->priv;
+
+ ret = snd_soc_dai_startup(sink, substream);
+ if (ret < 0) {
+ dev_err(sink->dev,
+ "ASoC: startup() failed: %d\n", ret);
+ goto out;
+ }
+ sink->active++;
+ }
+
+ /*
+ * Note: getting the config after .startup() gives a chance to
+ * either party on the link to alter the configuration if
+ * necessary
+ */
+ config = rtd->dai_link->params + rtd->params_select;
+ if (WARN_ON(!config)) {
+ dev_err(w->dapm->dev, "ASoC: link config missing\n");
+ ret = -EINVAL;
+ goto out;
+ }
/* Be a little careful as we don't want to overflow the mask array */
if (config->formats) {
@@ -3792,27 +3826,62 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
} else {
dev_warn(w->dapm->dev, "ASoC: Invalid format %llx specified\n",
config->formats);
- fmt = 0;
- }
- /* Currently very limited parameter selection */
- params = kzalloc(sizeof(*params), GFP_KERNEL);
- if (!params) {
- ret = -ENOMEM;
+ ret = -EINVAL;
goto out;
}
- snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
+ snd_mask_set(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), fmt);
hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->min =
config->rate_min;
hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE)->max =
config->rate_max;
-
hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->min
= config->channels_min;
hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS)->max
= config->channels_max;
+ substream->stream = SNDRV_PCM_STREAM_CAPTURE;
+ snd_soc_dapm_widget_for_each_source_path(w, path) {
+ source = path->source->priv;
+
+ ret = snd_soc_dai_hw_params(source, substream, params);
+ if (ret < 0)
+ goto out;
+
+ dapm_update_dai_unlocked(substream, params, source);
+ }
+
+ substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
+ snd_soc_dapm_widget_for_each_sink_path(w, path) {
+ sink = path->sink->priv;
+
+ ret = snd_soc_dai_hw_params(sink, substream, params);
+ if (ret < 0)
+ goto out;
+
+ dapm_update_dai_unlocked(substream, params, sink);
+ }
+
+out:
+ kfree(params);
+ return 0;
+}
+
+static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_dapm_path *path;
+ struct snd_soc_dai *source, *sink;
+ struct snd_soc_pcm_runtime *rtd = w->priv;
+ struct snd_pcm_substream substream;
+ struct snd_pcm_runtime *runtime = NULL;
+ int ret = 0;
+
+ if (WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) ||
+ list_empty(&w->edges[SND_SOC_DAPM_DIR_IN])))
+ return -EINVAL;
+
memset(&substream, 0, sizeof(substream));
/* Allocate a dummy snd_pcm_runtime for startup() and other ops() */
@@ -3826,53 +3895,10 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- substream.stream = SNDRV_PCM_STREAM_CAPTURE;
- snd_soc_dapm_widget_for_each_source_path(w, path) {
- source = path->source->priv;
-
- ret = snd_soc_dai_startup(source, &substream);
- if (ret < 0) {
- dev_err(source->dev,
- "ASoC: startup() failed: %d\n", ret);
- goto out;
- }
- source->active++;
- }
-
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
- snd_soc_dapm_widget_for_each_sink_path(w, path) {
- sink = path->sink->priv;
-
- ret = snd_soc_dai_startup(sink, &substream);
- if (ret < 0) {
- dev_err(sink->dev,
- "ASoC: startup() failed: %d\n", ret);
- goto out;
- }
- sink->active++;
- }
-
- substream.stream = SNDRV_PCM_STREAM_CAPTURE;
- snd_soc_dapm_widget_for_each_source_path(w, path) {
- source = path->source->priv;
-
- ret = snd_soc_dai_hw_params(source, &substream, params);
- if (ret < 0)
- goto out;
-
- dapm_update_dai_unlocked(&substream, params, source);
- }
-
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
- snd_soc_dapm_widget_for_each_sink_path(w, path) {
- sink = path->sink->priv;
-
- ret = snd_soc_dai_hw_params(sink, &substream, params);
- if (ret < 0)
- goto out;
+ ret = snd_soc_dai_link_event_pre_pmu(w, &substream);
+ if (ret < 0)
+ goto out;
- dapm_update_dai_unlocked(&substream, params, sink);
- }
break;
case SND_SOC_DAPM_POST_PMU:
@@ -3934,7 +3960,6 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
out:
kfree(runtime);
- kfree(params);
return ret;
}
--
2.17.1

View File

@ -0,0 +1,96 @@
From 13440dd12851a643c267aa0b2c64c9552133aea3 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 29 Jul 2019 10:01:39 +0200
Subject: [PATCH 053/186] FROMGIT: ASoC: meson: g12a-tohdmitx: override
codec2codec params
So far, forwarding the hw_params of the input to output relied on the
.hw_params() callback of the cpu side of the codec2codec link to be called
first. This is a bit weak.
Instead, override the stream params of the codec2codec to link to set it up
correctly.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20190729080139.32068-1-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 2c4956bc1e9062e5e3c5ea7612294f24e6d4fbdd
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
sound/soc/meson/g12a-tohdmitx.c | 34 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/sound/soc/meson/g12a-tohdmitx.c b/sound/soc/meson/g12a-tohdmitx.c
index 707ccb192e4c..9943c807ec5d 100644
--- a/sound/soc/meson/g12a-tohdmitx.c
+++ b/sound/soc/meson/g12a-tohdmitx.c
@@ -28,7 +28,7 @@
#define CTRL0_SPDIF_CLK_SEL BIT(0)
struct g12a_tohdmitx_input {
- struct snd_pcm_hw_params params;
+ struct snd_soc_pcm_stream params;
unsigned int fmt;
};
@@ -225,26 +225,17 @@ static int g12a_tohdmitx_input_hw_params(struct snd_pcm_substream *substream,
{
struct g12a_tohdmitx_input *data = dai->playback_dma_data;
- /* Save the stream params for the downstream link */
- memcpy(&data->params, params, sizeof(*params));
+ data->params.rates = snd_pcm_rate_to_rate_bit(params_rate(params));
+ data->params.rate_min = params_rate(params);
+ data->params.rate_max = params_rate(params);
+ data->params.formats = 1 << params_format(params);
+ data->params.channels_min = params_channels(params);
+ data->params.channels_max = params_channels(params);
+ data->params.sig_bits = dai->driver->playback.sig_bits;
return 0;
}
-static int g12a_tohdmitx_output_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params,
- struct snd_soc_dai *dai)
-{
- struct g12a_tohdmitx_input *in_data =
- g12a_tohdmitx_get_input_data(dai->capture_widget);
-
- if (!in_data)
- return -ENODEV;
-
- memcpy(params, &in_data->params, sizeof(*params));
-
- return 0;
-}
static int g12a_tohdmitx_input_set_fmt(struct snd_soc_dai *dai,
unsigned int fmt)
@@ -266,6 +257,14 @@ static int g12a_tohdmitx_output_startup(struct snd_pcm_substream *substream,
if (!in_data)
return -ENODEV;
+ if (WARN_ON(!rtd->dai_link->params)) {
+ dev_warn(dai->dev, "codec2codec link expected\n");
+ return -EINVAL;
+ }
+
+ /* Replace link params with the input params */
+ rtd->dai_link->params = &in_data->params;
+
if (!in_data->fmt)
return 0;
@@ -278,7 +277,6 @@ static const struct snd_soc_dai_ops g12a_tohdmitx_input_ops = {
};
static const struct snd_soc_dai_ops g12a_tohdmitx_output_ops = {
- .hw_params = g12a_tohdmitx_output_hw_params,
.startup = g12a_tohdmitx_output_startup,
};
--
2.17.1

View File

@ -0,0 +1,175 @@
From 33b7f3e71853dad5f6739e051b43cadd32f66913 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 25 Jul 2019 18:59:47 +0200
Subject: [PATCH 054/186] FROMGIT: ASoC: create pcm for codec2codec links as
well
At the moment, codec to codec links uses an ephemeral variable for
the struct snd_pcm_substream. Also the struct snd_soc_pcm_runtime
does not have real struct snd_pcm.
This might a problem if the functions used by a codec on codec to
codec link expect these structures to exist, and keep on existing
during the life of the codec.
For example, it is the case of the hdmi-codec, which uses
snd_pcm_add_chmap_ctls(). For the controls to works, the pcm and
substream must to exist.
This change is first step, it create pcm (and substreams) for codec
to codec links, in the same way as dpcm backend links.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20190725165949.29699-5-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit a342031cdd0818cb0fbcb44798211c7a02c7ca27
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
sound/soc/soc-core.c | 42 ++++++++++++------------------------------
sound/soc/soc-pcm.c | 35 ++++++++++++++++++++++++++++++++---
2 files changed, 44 insertions(+), 33 deletions(-)
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 33df0dfe29f0..b6ca00b472d6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -447,16 +447,6 @@ static void snd_soc_flush_all_delayed_work(struct snd_soc_card *card)
flush_delayed_work(&rtd->delayed_work);
}
-static void codec2codec_close_delayed_work(struct work_struct *work)
-{
- /*
- * Currently nothing to do for c2c links
- * Since c2c links are internal nodes in the DAPM graph and
- * don't interface with the outside world or application layer
- * we don't have to do any special handling on close.
- */
-}
-
#ifdef CONFIG_PM_SLEEP
/* powers down audio subsystem for suspend */
int snd_soc_suspend(struct device *dev)
@@ -1557,27 +1547,19 @@ static int soc_probe_link_dais(struct snd_soc_card *card,
return ret;
}
- if (!dai_link->params) {
- /* create the pcm */
- ret = soc_new_pcm(rtd, num);
- if (ret < 0) {
- dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
- dai_link->stream_name, ret);
- return ret;
- }
- ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
- if (ret < 0)
- return ret;
- ret = soc_link_dai_pcm_new(rtd->codec_dais,
- rtd->num_codecs, rtd);
- if (ret < 0)
- return ret;
- } else {
- INIT_DELAYED_WORK(&rtd->delayed_work,
- codec2codec_close_delayed_work);
+ /* create the pcm */
+ ret = soc_new_pcm(rtd, num);
+ if (ret < 0) {
+ dev_err(card->dev, "ASoC: can't create pcm %s :%d\n",
+ dai_link->stream_name, ret);
+ return ret;
}
-
- return 0;
+ ret = soc_link_dai_pcm_new(&cpu_dai, 1, rtd);
+ if (ret < 0)
+ return ret;
+ ret = soc_link_dai_pcm_new(rtd->codec_dais,
+ rtd->num_codecs, rtd);
+ return ret;
}
static int soc_bind_aux_dev(struct snd_soc_card *card, int num)
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index fabeac164a6c..30264bc592f6 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -678,6 +678,16 @@ static void close_delayed_work(struct work_struct *work)
mutex_unlock(&rtd->pcm_mutex);
}
+static void codec2codec_close_delayed_work(struct work_struct *work)
+{
+ /*
+ * Currently nothing to do for c2c links
+ * Since c2c links are internal nodes in the DAPM graph and
+ * don't interface with the outside world or application layer
+ * we don't have to do any special handling on close.
+ */
+}
+
/*
* Called by ALSA when a PCM substream is closed. Private data can be
* freed here. The cpu DAI, codec DAI, machine and components are also
@@ -3011,6 +3021,12 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
playback = rtd->dai_link->dpcm_playback;
capture = rtd->dai_link->dpcm_capture;
} else {
+ /* Adapt stream for codec2codec links */
+ struct snd_soc_pcm_stream *cpu_capture = rtd->dai_link->params ?
+ &cpu_dai->driver->playback : &cpu_dai->driver->capture;
+ struct snd_soc_pcm_stream *cpu_playback = rtd->dai_link->params ?
+ &cpu_dai->driver->capture : &cpu_dai->driver->playback;
+
for_each_rtd_codec_dai(rtd, i, codec_dai) {
if (snd_soc_dai_stream_valid(codec_dai, SNDRV_PCM_STREAM_PLAYBACK) &&
snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
@@ -3019,6 +3035,9 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
capture = 1;
}
+
+ capture = capture && cpu_capture->channels_min;
+ playback = playback && cpu_playback->channels_min;
}
if (rtd->dai_link->playback_only) {
@@ -3032,7 +3051,13 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
}
/* create the PCM */
- if (rtd->dai_link->no_pcm) {
+ if (rtd->dai_link->params) {
+ snprintf(new_name, sizeof(new_name), "codec2codec(%s)",
+ rtd->dai_link->stream_name);
+
+ ret = snd_pcm_new_internal(rtd->card->snd_card, new_name, num,
+ playback, capture, &pcm);
+ } else if (rtd->dai_link->no_pcm) {
snprintf(new_name, sizeof(new_name), "(%s)",
rtd->dai_link->stream_name);
@@ -3059,13 +3084,17 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
dev_dbg(rtd->card->dev, "ASoC: registered pcm #%d %s\n",num, new_name);
/* DAPM dai link stream work */
- INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
+ if (rtd->dai_link->params)
+ INIT_DELAYED_WORK(&rtd->delayed_work,
+ codec2codec_close_delayed_work);
+ else
+ INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
pcm->nonatomic = rtd->dai_link->nonatomic;
rtd->pcm = pcm;
pcm->private_data = rtd;
- if (rtd->dai_link->no_pcm) {
+ if (rtd->dai_link->no_pcm || rtd->dai_link->params) {
if (playback)
pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream->private_data = rtd;
if (capture)
--
2.17.1

View File

@ -0,0 +1,48 @@
From 31aecb924149fef3b6bdf4d32cc24d58602f08ab Mon Sep 17 00:00:00 2001
From: Colin Ian King <colin.king@canonical.com>
Date: Fri, 26 Jul 2019 13:33:27 +0100
Subject: [PATCH 055/186] FROMGIT: ASoC: codec2codec: fix missing return of
error return code
Currently in function snd_soc_dai_link_event_pre_pmu the error return
code in variable err is being set but this is not actually being returned,
the function just returns zero even when there are failures. Fix this by
returning the error return code.
Addresses-Coverity: ("Unused value")
Fixes: 3dcfb397dad2 ("ASoC: codec2codec: deal with params when necessary")
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Link: https://lore.kernel.org/r/20190726123327.10467-1-colin.king@canonical.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit c8415833ec242b9ddf73bf9e1057e12f9b0fcd16
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
sound/soc/soc-dapm.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index be9bb05b0165..2d183e2d23de 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3776,7 +3776,7 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
struct snd_pcm_hw_params *params = NULL;
const struct snd_soc_pcm_stream *config = NULL;
unsigned int fmt;
- int ret;
+ int ret = 0;
params = kzalloc(sizeof(*params), GFP_KERNEL);
if (!params)
@@ -3865,7 +3865,7 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
out:
kfree(params);
- return 0;
+ return ret;
}
static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
--
2.17.1

View File

@ -0,0 +1,217 @@
From 68942bdc85a5e2f96d8c696bf16aa42361f5020a Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 25 Jul 2019 18:59:48 +0200
Subject: [PATCH 056/186] FROMGIT: ASoC: codec2codec: remove ephemeral
variables
Now that codec to codec links struct snd_soc_pcm_runtime have lasting pcm
and substreams, let's use them. Alsa allocate and keep the
struct snd_pcm_runtime as long as the link is powered.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20190725165949.29699-6-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit a72706ed8208ac3f72d1c3ebbc6509e368b0dcb0
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
sound/soc/soc-dapm.c | 72 ++++++++++++++++++++++++++------------------
1 file changed, 42 insertions(+), 30 deletions(-)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 2d183e2d23de..1c953a1b46ce 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3775,6 +3775,7 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_pcm_hw_params *params = NULL;
const struct snd_soc_pcm_stream *config = NULL;
+ struct snd_pcm_runtime *runtime = NULL;
unsigned int fmt;
int ret = 0;
@@ -3782,6 +3783,14 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
if (!params)
return -ENOMEM;
+ runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
+ if (!runtime) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ substream->runtime = runtime;
+
substream->stream = SNDRV_PCM_STREAM_CAPTURE;
snd_soc_dapm_widget_for_each_source_path(w, path) {
source = path->source->priv;
@@ -3808,6 +3817,8 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
sink->active++;
}
+ substream->hw_opened = 1;
+
/*
* Note: getting the config after .startup() gives a chance to
* either party on the link to alter the configuration if
@@ -3864,6 +3875,9 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
}
out:
+ if (ret < 0)
+ kfree(runtime);
+
kfree(params);
return ret;
}
@@ -3873,29 +3887,16 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_dapm_path *path;
struct snd_soc_dai *source, *sink;
- struct snd_soc_pcm_runtime *rtd = w->priv;
- struct snd_pcm_substream substream;
- struct snd_pcm_runtime *runtime = NULL;
- int ret = 0;
+ struct snd_pcm_substream *substream = w->priv;
+ int ret = 0, saved_stream = substream->stream;
if (WARN_ON(list_empty(&w->edges[SND_SOC_DAPM_DIR_OUT]) ||
list_empty(&w->edges[SND_SOC_DAPM_DIR_IN])))
return -EINVAL;
- memset(&substream, 0, sizeof(substream));
-
- /* Allocate a dummy snd_pcm_runtime for startup() and other ops() */
- runtime = kzalloc(sizeof(*runtime), GFP_KERNEL);
- if (!runtime) {
- ret = -ENOMEM;
- goto out;
- }
- substream.runtime = runtime;
- substream.private_data = rtd;
-
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- ret = snd_soc_dai_link_event_pre_pmu(w, &substream);
+ ret = snd_soc_dai_link_event_pre_pmu(w, substream);
if (ret < 0)
goto out;
@@ -3926,40 +3927,45 @@ static int snd_soc_dai_link_event(struct snd_soc_dapm_widget *w,
ret = 0;
}
- substream.stream = SNDRV_PCM_STREAM_CAPTURE;
+ substream->stream = SNDRV_PCM_STREAM_CAPTURE;
snd_soc_dapm_widget_for_each_source_path(w, path) {
source = path->source->priv;
- snd_soc_dai_hw_free(source, &substream);
+ snd_soc_dai_hw_free(source, substream);
}
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
+ substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
snd_soc_dapm_widget_for_each_sink_path(w, path) {
sink = path->sink->priv;
- snd_soc_dai_hw_free(sink, &substream);
+ snd_soc_dai_hw_free(sink, substream);
}
- substream.stream = SNDRV_PCM_STREAM_CAPTURE;
+ substream->stream = SNDRV_PCM_STREAM_CAPTURE;
snd_soc_dapm_widget_for_each_source_path(w, path) {
source = path->source->priv;
source->active--;
- snd_soc_dai_shutdown(source, &substream);
+ snd_soc_dai_shutdown(source, substream);
}
- substream.stream = SNDRV_PCM_STREAM_PLAYBACK;
+ substream->stream = SNDRV_PCM_STREAM_PLAYBACK;
snd_soc_dapm_widget_for_each_sink_path(w, path) {
sink = path->sink->priv;
sink->active--;
- snd_soc_dai_shutdown(sink, &substream);
+ snd_soc_dai_shutdown(sink, substream);
}
break;
+ case SND_SOC_DAPM_POST_PMD:
+ kfree(substream->runtime);
+ break;
+
default:
WARN(1, "Unknown event %d\n", event);
ret = -EINVAL;
}
out:
- kfree(runtime);
+ /* Restore the substream direction */
+ substream->stream = saved_stream;
return ret;
}
@@ -4082,9 +4088,11 @@ snd_soc_dapm_alloc_kcontrol(struct snd_soc_card *card,
}
static struct snd_soc_dapm_widget *
-snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
+snd_soc_dapm_new_dai(struct snd_soc_card *card,
+ struct snd_pcm_substream *substream,
char *id)
{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dapm_widget template;
struct snd_soc_dapm_widget *w;
const char **w_param_text;
@@ -4103,7 +4111,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
template.name = link_name;
template.event = snd_soc_dai_link_event;
template.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
- SND_SOC_DAPM_PRE_PMD;
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD;
template.kcontrol_news = NULL;
/* allocate memory for control, only in case of multiple configs */
@@ -4138,7 +4146,7 @@ snd_soc_dapm_new_dai(struct snd_soc_card *card, struct snd_soc_pcm_runtime *rtd,
goto outfree_kcontrol_news;
}
- w->priv = rtd;
+ w->priv = substream;
return w;
@@ -4260,6 +4268,8 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
struct snd_soc_dai *codec_dai;
struct snd_soc_dapm_widget *playback = NULL, *capture = NULL;
struct snd_soc_dapm_widget *codec, *playback_cpu, *capture_cpu;
+ struct snd_pcm_substream *substream;
+ struct snd_pcm_str *streams = rtd->pcm->streams;
int i;
if (rtd->dai_link->params) {
@@ -4278,7 +4288,8 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
if (playback_cpu && codec) {
if (!playback) {
- playback = snd_soc_dapm_new_dai(card, rtd,
+ substream = streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
+ playback = snd_soc_dapm_new_dai(card, substream,
"playback");
if (IS_ERR(playback)) {
dev_err(rtd->dev,
@@ -4307,7 +4318,8 @@ static void dapm_connect_dai_link_widgets(struct snd_soc_card *card,
if (codec && capture_cpu) {
if (!capture) {
- capture = snd_soc_dapm_new_dai(card, rtd,
+ substream = streams[SNDRV_PCM_STREAM_CAPTURE].substream;
+ capture = snd_soc_dapm_new_dai(card, substream,
"capture");
if (IS_ERR(capture)) {
dev_err(rtd->dev,
--
2.17.1

View File

@ -0,0 +1,38 @@
From 83cd39f43df32e2d53679b625bc3a1dd54e97280 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Thu, 25 Jul 2019 18:59:49 +0200
Subject: [PATCH 057/186] FROMGIT: ASoC: codec2codec: fill some of the runtime
stream parameters
Set the information provided struct snd_soc_pcm_stream in the
struct snd_pcm_runtime of the codec to codec link.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Link: https://lore.kernel.org/r/20190725165949.29699-7-jbrunet@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 9de98628c895d15427138073986eab1e3ce39cb4
git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.4)
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
sound/soc/soc-dapm.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1c953a1b46ce..e16838e1bda2 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3874,6 +3874,11 @@ snd_soc_dai_link_event_pre_pmu(struct snd_soc_dapm_widget *w,
dapm_update_dai_unlocked(substream, params, sink);
}
+ runtime->format = params_format(params);
+ runtime->subformat = params_subformat(params);
+ runtime->channels = params_channels(params);
+ runtime->rate = params_rate(params);
+
out:
if (ret < 0)
kfree(runtime);
--
2.17.1

View File

@ -0,0 +1,35 @@
From 61a5ceb0bee36183165ecd9d29943b0b6fd6ce65 Mon Sep 17 00:00:00 2001
From: Julien Masson <jmasson@baylibre.com>
Date: Mon, 24 Jun 2019 16:47:56 +0200
Subject: [PATCH 058/186] FROMGIT: drm: meson: mask value when writing bits
relaxed
The value used in the macro writel_bits_relaxed has to be masked since
we don't want change the bits outside the mask.
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/86y31r82fo.fsf@baylibre.com
(cherry picked from commit f237bf2de82eafd224eb981c6c0bca8a9e039af6
git://anongit.freedesktop.org/drm/drm-misc drm-misc-next)
---
drivers/gpu/drm/meson/meson_registers.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index 410e324d6f93..2e6537a21bc4 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -10,7 +10,7 @@
#define _REG(reg) ((reg) << 2)
#define writel_bits_relaxed(mask, val, addr) \
- writel_relaxed((readl_relaxed(addr) & ~(mask)) | (val), addr)
+ writel_relaxed((readl_relaxed(addr) & ~(mask)) | ((val) & (mask)), addr)
/* vpp2 */
#define VPP2_DUMMY_DATA 0x1900
--
2.17.1

View File

@ -0,0 +1,94 @@
From da7640c5ed2a9c39b91d423c9195909b7739ab2c Mon Sep 17 00:00:00 2001
From: Julien Masson <jmasson@baylibre.com>
Date: Mon, 24 Jun 2019 16:48:12 +0200
Subject: [PATCH 059/186] FROMGIT: drm: meson: crtc: use proper macros instead
of magic constants
This patch add new macros which describe couple bits field of the
following registers:
- VD1_BLEND_SRC_CTRL
- VPP_SC_MISC
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/86wohb82fa.fsf@baylibre.com
(cherry picked from commit 39bf9985b8598f20a3bf49844d2ac538a0d5697f
git://anongit.freedesktop.org/drm/drm-misc drm-misc-next)
---
drivers/gpu/drm/meson/meson_crtc.c | 17 +++++++++++------
drivers/gpu/drm/meson/meson_registers.h | 16 ++++++++++++++++
2 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
index aa8ea107524e..6f7d6d258615 100644
--- a/drivers/gpu/drm/meson/meson_crtc.c
+++ b/drivers/gpu/drm/meson/meson_crtc.c
@@ -267,11 +267,11 @@ static void meson_crtc_enable_vd1(struct meson_drm *priv)
static void meson_g12a_crtc_enable_vd1(struct meson_drm *priv)
{
- writel_relaxed(((1 << 16) | /* post bld premult*/
- (1 << 8) | /* post src */
- (1 << 4) | /* pre bld premult*/
- (1 << 0)),
- priv->io_base + _REG(VD1_BLEND_SRC_CTRL));
+ writel_relaxed(VD_BLEND_PREBLD_SRC_VD1 |
+ VD_BLEND_PREBLD_PREMULT_EN |
+ VD_BLEND_POSTBLD_SRC_VD1 |
+ VD_BLEND_POSTBLD_PREMULT_EN,
+ priv->io_base + _REG(VD1_BLEND_SRC_CTRL));
}
void meson_crtc_irq(struct meson_drm *priv)
@@ -489,7 +489,12 @@ void meson_crtc_irq(struct meson_drm *priv)
writel_relaxed(priv->viu.vd1_range_map_cr,
priv->io_base + meson_crtc->viu_offset +
_REG(VD1_IF0_RANGE_MAP_CR));
- writel_relaxed(0x78404,
+ writel_relaxed(VPP_VSC_BANK_LENGTH(4) |
+ VPP_HSC_BANK_LENGTH(4) |
+ VPP_SC_VD_EN_ENABLE |
+ VPP_SC_TOP_EN_ENABLE |
+ VPP_SC_HSC_EN_ENABLE |
+ VPP_SC_VSC_EN_ENABLE,
priv->io_base + _REG(VPP_SC_MISC));
writel_relaxed(priv->viu.vpp_pic_in_height,
priv->io_base + _REG(VPP_PIC_IN_HEIGHT));
diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index 2e6537a21bc4..da31f22fed65 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -360,6 +360,12 @@
#define VPP_HSC_REGION4_PHASE_SLOPE 0x1d17
#define VPP_HSC_PHASE_CTRL 0x1d18
#define VPP_SC_MISC 0x1d19
+#define VPP_SC_VD_EN_ENABLE BIT(15)
+#define VPP_SC_TOP_EN_ENABLE BIT(16)
+#define VPP_SC_HSC_EN_ENABLE BIT(17)
+#define VPP_SC_VSC_EN_ENABLE BIT(18)
+#define VPP_VSC_BANK_LENGTH(length) (length & 0x7)
+#define VPP_HSC_BANK_LENGTH(length) ((length & 0x7) << 8)
#define VPP_PREBLEND_VD1_H_START_END 0x1d1a
#define VPP_PREBLEND_VD1_V_START_END 0x1d1b
#define VPP_POSTBLEND_VD1_H_START_END 0x1d1c
@@ -1628,6 +1634,16 @@
#define VPP_SLEEP_CTRL 0x1dfa
#define VD1_BLEND_SRC_CTRL 0x1dfb
#define VD2_BLEND_SRC_CTRL 0x1dfc
+#define VD_BLEND_PREBLD_SRC_VD1 (1 << 0)
+#define VD_BLEND_PREBLD_SRC_VD2 (2 << 0)
+#define VD_BLEND_PREBLD_SRC_OSD1 (3 << 0)
+#define VD_BLEND_PREBLD_SRC_OSD2 (4 << 0)
+#define VD_BLEND_PREBLD_PREMULT_EN BIT(4)
+#define VD_BLEND_POSTBLD_SRC_VD1 (1 << 8)
+#define VD_BLEND_POSTBLD_SRC_VD2 (2 << 8)
+#define VD_BLEND_POSTBLD_SRC_OSD1 (3 << 8)
+#define VD_BLEND_POSTBLD_SRC_OSD2 (4 << 8)
+#define VD_BLEND_POSTBLD_PREMULT_EN BIT(16)
#define OSD1_BLEND_SRC_CTRL 0x1dfd
#define OSD2_BLEND_SRC_CTRL 0x1dfe
--
2.17.1

View File

@ -0,0 +1,72 @@
From ddbb21c5d461141024a792d8f45ffb6dd448e6bb Mon Sep 17 00:00:00 2001
From: Julien Masson <jmasson@baylibre.com>
Date: Mon, 24 Jun 2019 16:48:27 +0200
Subject: [PATCH 060/186] FROMGIT: drm: meson: drv: use macro when initializing
vpu
This patch add new macro which is used to set WRARB/RDARB mode of
the VPU.
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/86v9wv82f1.fsf@baylibre.com
(cherry picked from commit bfb86819829e5ed5eaba4b9449ecfe6db4f9f91e
git://anongit.freedesktop.org/drm/drm-misc drm-misc-next)
---
drivers/gpu/drm/meson/meson_drv.c | 26 +++++++++++++++++++++----
drivers/gpu/drm/meson/meson_registers.h | 1 +
2 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c
index 2310c96fff46..50096697adc3 100644
--- a/drivers/gpu/drm/meson/meson_drv.c
+++ b/drivers/gpu/drm/meson/meson_drv.c
@@ -149,10 +149,28 @@ static struct regmap_config meson_regmap_config = {
static void meson_vpu_init(struct meson_drm *priv)
{
- writel_relaxed(0x210000, priv->io_base + _REG(VPU_RDARB_MODE_L1C1));
- writel_relaxed(0x10000, priv->io_base + _REG(VPU_RDARB_MODE_L1C2));
- writel_relaxed(0x900000, priv->io_base + _REG(VPU_RDARB_MODE_L2C1));
- writel_relaxed(0x20000, priv->io_base + _REG(VPU_WRARB_MODE_L2C1));
+ u32 value;
+
+ /*
+ * Slave dc0 and dc5 connected to master port 1.
+ * By default other slaves are connected to master port 0.
+ */
+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1) |
+ VPU_RDARB_SLAVE_TO_MASTER_PORT(5, 1);
+ writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L1C1));
+
+ /* Slave dc0 connected to master port 1 */
+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(0, 1);
+ writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L1C2));
+
+ /* Slave dc4 and dc7 connected to master port 1 */
+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(4, 1) |
+ VPU_RDARB_SLAVE_TO_MASTER_PORT(7, 1);
+ writel_relaxed(value, priv->io_base + _REG(VPU_RDARB_MODE_L2C1));
+
+ /* Slave dc1 connected to master port 1 */
+ value = VPU_RDARB_SLAVE_TO_MASTER_PORT(1, 1);
+ writel_relaxed(value, priv->io_base + _REG(VPU_WRARB_MODE_L2C1));
}
static void meson_remove_framebuffers(void)
diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index da31f22fed65..1c3825978e28 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -1486,6 +1486,7 @@
#define VPU_RDARB_MODE_L1C2 0x2799
#define VPU_RDARB_MODE_L2C1 0x279d
#define VPU_WRARB_MODE_L2C1 0x27a2
+#define VPU_RDARB_SLAVE_TO_MASTER_PORT(dc, port) (port << (16 + dc))
/* osd super scale */
#define OSDSR_HV_SIZEIN 0x3130
--
2.17.1

View File

@ -0,0 +1,145 @@
From 6cb0f55b098d69138bfb55f304f340b13a4214f9 Mon Sep 17 00:00:00 2001
From: Julien Masson <jmasson@baylibre.com>
Date: Mon, 24 Jun 2019 16:48:35 +0200
Subject: [PATCH 061/186] FROMGIT: drm: meson: vpp: use proper macros instead
of magic constants
This patch add new macros which are used to set the following
registers:
- VPP_OSD_SCALE_COEF_IDX
- VPP_DOLBY_CTRL
- VPP_OFIFO_SIZE
- VPP_HOLD_LINES
- VPP_SC_MISC
- VPP_VADJ_CTRL
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
[narmstrong: put back 0x1020080 in VPP_DUMMY_DATA1 for GXM]
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/86tvcf82eu.fsf@baylibre.com
(cherry picked from commit 0ce266d018f4749c7049df76d7f670a675bfa9c6
git://anongit.freedesktop.org/drm/drm-misc drm-misc-next)
---
drivers/gpu/drm/meson/meson_registers.h | 8 ++++++++
drivers/gpu/drm/meson/meson_vpp.c | 25 ++++++++++++++++---------
2 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index 1c3825978e28..fdd946b7ebb6 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -339,6 +339,7 @@
#define VPP_LINE_IN_LENGTH 0x1d01
#define VPP_PIC_IN_HEIGHT 0x1d02
#define VPP_SCALE_COEF_IDX 0x1d03
+#define VPP_SCALE_HORIZONTAL_COEF BIT(8)
#define VPP_SCALE_COEF 0x1d04
#define VPP_VSC_REGION12_STARTP 0x1d05
#define VPP_VSC_REGION34_STARTP 0x1d06
@@ -375,6 +376,8 @@
#define VPP_PREBLEND_H_SIZE 0x1d20
#define VPP_POSTBLEND_H_SIZE 0x1d21
#define VPP_HOLD_LINES 0x1d22
+#define VPP_POSTBLEND_HOLD_LINES(lines) (lines & 0xf)
+#define VPP_PREBLEND_HOLD_LINES(lines) ((lines & 0xf) << 8)
#define VPP_BLEND_ONECOLOR_CTRL 0x1d23
#define VPP_PREBLEND_CURRENT_XY 0x1d24
#define VPP_POSTBLEND_CURRENT_XY 0x1d25
@@ -393,6 +396,8 @@
#define VPP_OSD2_PREBLEND BIT(17)
#define VPP_COLOR_MNG_ENABLE BIT(28)
#define VPP_OFIFO_SIZE 0x1d27
+#define VPP_OFIFO_SIZE_MASK GENMASK(13, 0)
+#define VPP_OFIFO_SIZE_DEFAULT (0xfff << 20 | 0x1000)
#define VPP_FIFO_STATUS 0x1d28
#define VPP_SMOKE_CTRL 0x1d29
#define VPP_SMOKE1_VAL 0x1d2a
@@ -408,6 +413,8 @@
#define VPP_HSC_PHASE_CTRL1 0x1d34
#define VPP_HSC_INI_PAT_CTRL 0x1d35
#define VPP_VADJ_CTRL 0x1d40
+#define VPP_MINUS_BLACK_LVL_VADJ1_ENABLE BIT(1)
+
#define VPP_VADJ1_Y 0x1d41
#define VPP_VADJ1_MA_MB 0x1d42
#define VPP_VADJ1_MC_MD 0x1d43
@@ -467,6 +474,7 @@
#define VPP_PEAKING_VGAIN 0x1d92
#define VPP_PEAKING_NLP_1 0x1d93
#define VPP_DOLBY_CTRL 0x1d93
+#define VPP_PPS_DUMMY_DATA_MODE (1 << 17)
#define VPP_PEAKING_NLP_2 0x1d94
#define VPP_PEAKING_NLP_3 0x1d95
#define VPP_PEAKING_NLP_4 0x1d96
diff --git a/drivers/gpu/drm/meson/meson_vpp.c b/drivers/gpu/drm/meson/meson_vpp.c
index bfee30fa6e34..beec199d75e1 100644
--- a/drivers/gpu/drm/meson/meson_vpp.c
+++ b/drivers/gpu/drm/meson/meson_vpp.c
@@ -57,7 +57,7 @@ static void meson_vpp_write_scaling_filter_coefs(struct meson_drm *priv,
{
int i;
- writel_relaxed(is_horizontal ? BIT(8) : 0,
+ writel_relaxed(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
priv->io_base + _REG(VPP_OSD_SCALE_COEF_IDX));
for (i = 0; i < 33; i++)
writel_relaxed(coefs[i],
@@ -82,7 +82,7 @@ static void meson_vpp_write_vd_scaling_filter_coefs(struct meson_drm *priv,
{
int i;
- writel_relaxed(is_horizontal ? BIT(8) : 0,
+ writel_relaxed(is_horizontal ? VPP_SCALE_HORIZONTAL_COEF : 0,
priv->io_base + _REG(VPP_SCALE_COEF_IDX));
for (i = 0; i < 33; i++)
writel_relaxed(coefs[i],
@@ -97,7 +97,8 @@ void meson_vpp_init(struct meson_drm *priv)
else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu")) {
writel_bits_relaxed(0xff << 16, 0xff << 16,
priv->io_base + _REG(VIU_MISC_CTRL1));
- writel_relaxed(0x20000, priv->io_base + _REG(VPP_DOLBY_CTRL));
+ writel_relaxed(VPP_PPS_DUMMY_DATA_MODE,
+ priv->io_base + _REG(VPP_DOLBY_CTRL));
writel_relaxed(0x1020080,
priv->io_base + _REG(VPP_DUMMY_DATA1));
} else if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
@@ -105,12 +106,13 @@ void meson_vpp_init(struct meson_drm *priv)
/* Initialize vpu fifo control registers */
if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
- writel_relaxed(0xfff << 20 | 0x1000,
+ writel_relaxed(VPP_OFIFO_SIZE_DEFAULT,
priv->io_base + _REG(VPP_OFIFO_SIZE));
else
- writel_relaxed(readl_relaxed(priv->io_base + _REG(VPP_OFIFO_SIZE)) |
- 0x77f, priv->io_base + _REG(VPP_OFIFO_SIZE));
- writel_relaxed(0x08080808, priv->io_base + _REG(VPP_HOLD_LINES));
+ writel_bits_relaxed(VPP_OFIFO_SIZE_MASK, 0x77f,
+ priv->io_base + _REG(VPP_OFIFO_SIZE));
+ writel_relaxed(VPP_POSTBLEND_HOLD_LINES(4) | VPP_PREBLEND_HOLD_LINES(4),
+ priv->io_base + _REG(VPP_HOLD_LINES));
if (!meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) {
/* Turn off preblend */
@@ -138,10 +140,15 @@ void meson_vpp_init(struct meson_drm *priv)
writel_relaxed(0, priv->io_base + _REG(VPP_OSD_SC_CTRL0));
writel_relaxed(0, priv->io_base + _REG(VPP_OSD_VSC_CTRL0));
writel_relaxed(0, priv->io_base + _REG(VPP_OSD_HSC_CTRL0));
- writel_relaxed(4 | (4 << 8) | BIT(15),
+
+ /* Set horizontal/vertical bank length and enable video scale out */
+ writel_relaxed(VPP_VSC_BANK_LENGTH(4) | VPP_HSC_BANK_LENGTH(4) |
+ VPP_SC_VD_EN_ENABLE,
priv->io_base + _REG(VPP_SC_MISC));
- writel_relaxed(1, priv->io_base + _REG(VPP_VADJ_CTRL));
+ /* Enable minus black level for vadj1 */
+ writel_relaxed(VPP_MINUS_BLACK_LVL_VADJ1_ENABLE,
+ priv->io_base + _REG(VPP_VADJ_CTRL));
/* Write in the proper filter coefficients. */
meson_vpp_write_scaling_filter_coefs(priv,
--
2.17.1

View File

@ -0,0 +1,251 @@
From 4ce8b119069da36aad4676a714a580255e0c8203 Mon Sep 17 00:00:00 2001
From: Julien Masson <jmasson@baylibre.com>
Date: Mon, 24 Jun 2019 16:48:43 +0200
Subject: [PATCH 062/186] FROMGIT: drm: meson: viu: use proper macros instead
of magic constants
This patch add new macros which are used to set the following
registers:
- VIU_SW_RESET
- VIU_OSD1_CTRL_STAT
- VIU_OSD2_CTRL_STAT
- VIU_OSD1_FIFO_CTRL_STAT
- VIU_OSD2_FIFO_CTRL_STAT
- VIU_MISC_CTRL0
- VIU_OSD_BLEND_CTRL
- OSD1_BLEND_SRC_CTRL
- OSD2_BLEND_SRC_CTRL
- DOLBY_PATH_CTRL
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
[narmstrong: fix OSD1_BLEND_SRC_CTRL register init value for G12A]
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/86sgrz82em.fsf@baylibre.com
(cherry picked from commit 147ae1cbaa18429b9450fd47136a29653294aaad
git://anongit.freedesktop.org/drm/drm-misc drm-misc-next)
---
drivers/gpu/drm/meson/meson_plane.c | 2 +-
drivers/gpu/drm/meson/meson_registers.h | 27 ++++++++
drivers/gpu/drm/meson/meson_viu.c | 82 +++++++++++++------------
3 files changed, 72 insertions(+), 39 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
index 7a7e88dadd0b..c83471b69a1b 100644
--- a/drivers/gpu/drm/meson/meson_plane.c
+++ b/drivers/gpu/drm/meson/meson_plane.c
@@ -332,7 +332,7 @@ static void meson_plane_atomic_disable(struct drm_plane *plane,
/* Disable OSD1 */
if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
- writel_bits_relaxed(3 << 8, 0,
+ writel_bits_relaxed(VIU_OSD1_POSTBLD_SRC_OSD1, 0,
priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
else
writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0,
diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index fdd946b7ebb6..2b4968fd1455 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -136,11 +136,19 @@
#define VIU_ADDR_START 0x1a00
#define VIU_ADDR_END 0x1aff
#define VIU_SW_RESET 0x1a01
+#define VIU_SW_RESET_OSD1 BIT(0)
#define VIU_MISC_CTRL0 0x1a06
+#define VIU_CTRL0_VD1_AFBC_MASK 0x170000
#define VIU_MISC_CTRL1 0x1a07
#define D2D3_INTF_LENGTH 0x1a08
#define D2D3_INTF_CTRL0 0x1a09
#define VIU_OSD1_CTRL_STAT 0x1a10
+#define VIU_OSD1_OSD_BLK_ENABLE BIT(0)
+#define VIU_OSD1_POSTBLD_SRC_VD1 (1 << 8)
+#define VIU_OSD1_POSTBLD_SRC_VD2 (2 << 8)
+#define VIU_OSD1_POSTBLD_SRC_OSD1 (3 << 8)
+#define VIU_OSD1_POSTBLD_SRC_OSD2 (4 << 8)
+#define VIU_OSD1_OSD_ENABLE BIT(21)
#define VIU_OSD1_CTRL_STAT2 0x1a2d
#define VIU_OSD1_COLOR_ADDR 0x1a11
#define VIU_OSD1_COLOR 0x1a12
@@ -230,6 +238,12 @@
#define VIU_OSD3_MALI_UNPACK_CTRL 0x3d9f
#define VIU_OSD3_DIMM_CTRL 0x3da0
+#define VIU_OSD_DDR_PRIORITY_URGENT BIT(0)
+#define VIU_OSD_HOLD_FIFO_LINES(lines) ((lines & 0x1f) << 5)
+#define VIU_OSD_FIFO_DEPTH_VAL(val) ((val & 0x7f) << 12)
+#define VIU_OSD_WORDS_PER_BURST(words) (((words & 0x4) >> 1) << 22)
+#define VIU_OSD_FIFO_LIMITS(size) ((size & 0xf) << 24)
+
#define VD1_IF0_GEN_REG 0x1a50
#define VD1_IF0_CANVAS0 0x1a51
#define VD1_IF0_CANVAS1 0x1a52
@@ -1610,10 +1624,18 @@
#define VPU_MAFBC_PREFETCH_CFG_S3 0x3a7c
#define DOLBY_PATH_CTRL 0x1a0c
+#define DOLBY_BYPASS_EN(val) (val & 0xf)
#define OSD_PATH_MISC_CTRL 0x1a0e
#define MALI_AFBCD_TOP_CTRL 0x1a0f
#define VIU_OSD_BLEND_CTRL 0x39b0
+#define VIU_OSD_BLEND_REORDER(dest, src) ((src) << (dest * 4))
+#define VIU_OSD_BLEND_DIN_EN(bits) ((bits & 0xf) << 20)
+#define VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 BIT(24)
+#define VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 BIT(25)
+#define VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 BIT(26)
+#define VIU_OSD_BLEND_BLEN2_PREMULT_EN(input) ((input & 0x3) << 27)
+#define VIU_OSD_BLEND_HOLD_LINES(lines) ((lines & 0x7) << 29)
#define VIU_OSD_BLEND_CTRL1 0x39c0
#define VIU_OSD_BLEND_DIN0_SCOPE_H 0x39b1
#define VIU_OSD_BLEND_DIN0_SCOPE_V 0x39b2
@@ -1655,6 +1677,11 @@
#define VD_BLEND_POSTBLD_PREMULT_EN BIT(16)
#define OSD1_BLEND_SRC_CTRL 0x1dfd
#define OSD2_BLEND_SRC_CTRL 0x1dfe
+#define OSD_BLEND_POSTBLD_SRC_VD1 (1 << 8)
+#define OSD_BLEND_POSTBLD_SRC_VD2 (2 << 8)
+#define OSD_BLEND_POSTBLD_SRC_OSD1 (3 << 8)
+#define OSD_BLEND_POSTBLD_SRC_OSD2 (4 << 8)
+#define OSD_BLEND_PATH_SEL_ENABLE BIT(20)
#define VPP_POST_BLEND_BLEND_DUMMY_DATA 0x3968
#define VPP_POST_BLEND_DUMMY_ALPHA 0x3969
diff --git a/drivers/gpu/drm/meson/meson_viu.c b/drivers/gpu/drm/meson/meson_viu.c
index 4b2b3024d371..4b36e4b21b51 100644
--- a/drivers/gpu/drm/meson/meson_viu.c
+++ b/drivers/gpu/drm/meson/meson_viu.c
@@ -323,9 +323,9 @@ void meson_viu_osd1_reset(struct meson_drm *priv)
priv->io_base + _REG(VIU_OSD1_CTRL_STAT2));
/* Reset OSD1 */
- writel_bits_relaxed(BIT(0), BIT(0),
+ writel_bits_relaxed(VIU_SW_RESET_OSD1, VIU_SW_RESET_OSD1,
priv->io_base + _REG(VIU_SW_RESET));
- writel_bits_relaxed(BIT(0), 0,
+ writel_bits_relaxed(VIU_SW_RESET_OSD1, 0,
priv->io_base + _REG(VIU_SW_RESET));
/* Rewrite these registers state lost in the reset */
@@ -338,15 +338,22 @@ void meson_viu_osd1_reset(struct meson_drm *priv)
meson_viu_load_matrix(priv);
}
+static inline uint32_t meson_viu_osd_burst_length_reg(uint32_t length)
+{
+ uint32_t val = (((length & 0x80) % 24) / 12);
+
+ return (((val & 0x3) << 10) | (((val & 0x4) >> 2) << 31));
+}
+
void meson_viu_init(struct meson_drm *priv)
{
uint32_t reg;
/* Disable OSDs */
- writel_bits_relaxed(BIT(0) | BIT(21), 0,
- priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
- writel_bits_relaxed(BIT(0) | BIT(21), 0,
- priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
+ writel_bits_relaxed(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
+ priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
+ writel_bits_relaxed(VIU_OSD1_OSD_BLK_ENABLE | VIU_OSD1_OSD_ENABLE, 0,
+ priv->io_base + _REG(VIU_OSD2_CTRL_STAT));
/* On GXL/GXM, Use the 10bit HDR conversion matrix */
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
@@ -357,19 +364,17 @@ void meson_viu_init(struct meson_drm *priv)
true);
/* Initialize OSD1 fifo control register */
- reg = BIT(0) | /* Urgent DDR request priority */
- (4 << 5); /* hold_fifo_lines */
+ reg = VIU_OSD_DDR_PRIORITY_URGENT |
+ VIU_OSD_HOLD_FIFO_LINES(4) |
+ VIU_OSD_FIFO_DEPTH_VAL(32) | /* fifo_depth_val: 32*8=256 */
+ VIU_OSD_WORDS_PER_BURST(4) | /* 4 words in 1 burst */
+ VIU_OSD_FIFO_LIMITS(2); /* fifo_lim: 2*16=32 */
+
if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
- reg |= (1 << 10) | /* burst length 32 */
- (32 << 12) | /* fifo_depth_val: 32*8=256 */
- (2 << 22) | /* 4 words in 1 burst */
- (2 << 24) |
- (1 << 31);
+ reg |= meson_viu_osd_burst_length_reg(32);
else
- reg |= (3 << 10) | /* burst length 64 */
- (32 << 12) | /* fifo_depth_val: 32*8=256 */
- (2 << 22) | /* 4 words in 1 burst */
- (2 << 24);
+ reg |= meson_viu_osd_burst_length_reg(64);
+
writel_relaxed(reg, priv->io_base + _REG(VIU_OSD1_FIFO_CTRL_STAT));
writel_relaxed(reg, priv->io_base + _REG(VIU_OSD2_FIFO_CTRL_STAT));
@@ -382,12 +387,9 @@ void meson_viu_init(struct meson_drm *priv)
priv->io_base + _REG(VIU_OSD2_CTRL_STAT2));
/* Disable VD1 AFBC */
- /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 */
- writel_bits_relaxed(0x7 << 16, 0,
- priv->io_base + _REG(VIU_MISC_CTRL0));
- /* afbc vd1 set=0 */
- writel_bits_relaxed(BIT(20), 0,
- priv->io_base + _REG(VIU_MISC_CTRL0));
+ /* di_mif0_en=0 mif0_to_vpp_en=0 di_mad_en=0 and afbc vd1 set=0*/
+ writel_bits_relaxed(VIU_CTRL0_VD1_AFBC_MASK, 0,
+ priv->io_base + _REG(VIU_MISC_CTRL0));
writel_relaxed(0, priv->io_base + _REG(AFBC_ENABLE));
writel_relaxed(0x00FF00C0,
@@ -396,27 +398,31 @@ void meson_viu_init(struct meson_drm *priv)
priv->io_base + _REG(VD2_IF0_LUMA_FIFO_SIZE));
if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) {
- writel_relaxed(4 << 29 |
- 1 << 27 |
- 1 << 26 | /* blend_din0 input to blend0 */
- 1 << 25 | /* blend1_dout to blend2 */
- 1 << 24 | /* blend1_din3 input to blend1 */
- 1 << 20 |
- 0 << 16 |
- 1,
- priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
- writel_relaxed(1 << 20,
- priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
- writel_relaxed(1 << 20,
- priv->io_base + _REG(OSD2_BLEND_SRC_CTRL));
+ writel_relaxed(VIU_OSD_BLEND_REORDER(0, 1) |
+ VIU_OSD_BLEND_REORDER(1, 0) |
+ VIU_OSD_BLEND_REORDER(2, 0) |
+ VIU_OSD_BLEND_REORDER(3, 0) |
+ VIU_OSD_BLEND_DIN_EN(1) |
+ VIU_OSD_BLEND1_DIN3_BYPASS_TO_DOUT1 |
+ VIU_OSD_BLEND1_DOUT_BYPASS_TO_BLEND2 |
+ VIU_OSD_BLEND_DIN0_BYPASS_TO_DOUT0 |
+ VIU_OSD_BLEND_BLEN2_PREMULT_EN(1) |
+ VIU_OSD_BLEND_HOLD_LINES(4),
+ priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
+
+ writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
+ priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
+ writel_relaxed(OSD_BLEND_PATH_SEL_ENABLE,
+ priv->io_base + _REG(OSD2_BLEND_SRC_CTRL));
writel_relaxed(0, priv->io_base + _REG(VD1_BLEND_SRC_CTRL));
writel_relaxed(0, priv->io_base + _REG(VD2_BLEND_SRC_CTRL));
writel_relaxed(0,
priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_DATA0));
writel_relaxed(0,
priv->io_base + _REG(VIU_OSD_BLEND_DUMMY_ALPHA));
- writel_bits_relaxed(0x3 << 2, 0x3 << 2,
- priv->io_base + _REG(DOLBY_PATH_CTRL));
+
+ writel_bits_relaxed(DOLBY_BYPASS_EN(0xc), DOLBY_BYPASS_EN(0xc),
+ priv->io_base + _REG(DOLBY_PATH_CTRL));
}
priv->viu.osd1_enabled = false;
--
2.17.1

View File

@ -0,0 +1,477 @@
From dab1d5072181becd2214ae1eaf78b664142925b2 Mon Sep 17 00:00:00 2001
From: Julien Masson <jmasson@baylibre.com>
Date: Mon, 24 Jun 2019 16:48:50 +0200
Subject: [PATCH 063/186] FROMGIT: drm: meson: venc: use proper macros instead
of magic constants
This patch add new macros which are used to set the following
registers:
- ENCI_CFILT_CTRL
- ENCI_CFILT_CTRL2
- ENCI_MACV_MAX_AMP
- ENCI_VIDEO_MODE_ADV
- ENCI_VFIFO2VD_CTL
- ENCI_VIDEO_EN
- ENCP_VIDEO_MODE
- VPU_HDMI_SETTING
- VENC_UPSAMPLE_CTRL0
- VENC_UPSAMPLE_CTRL1
- VENC_UPSAMPLE_CTRL2
- VENC_VDAC_FIFO_CTRL
- VENC_VDAC_DAC0_FILT_CTRL0
- VENC_INTCTRL
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/86r27j82ef.fsf@baylibre.com
(cherry picked from commit 7eef9e6104545e3aed75ac84129ab332e71b6557
git://anongit.freedesktop.org/drm/drm-misc drm-misc-next)
---
drivers/gpu/drm/meson/meson_registers.h | 51 ++++++++
drivers/gpu/drm/meson/meson_venc.c | 155 +++++++++++++++++++-----
drivers/gpu/drm/meson/meson_venc_cvbs.c | 3 +-
3 files changed, 177 insertions(+), 32 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index 2b4968fd1455..ec73eaa4a0bf 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -732,6 +732,25 @@
#define VENC_UPSAMPLE_CTRL0 0x1b64
#define VENC_UPSAMPLE_CTRL1 0x1b65
#define VENC_UPSAMPLE_CTRL2 0x1b66
+#define VENC_UPSAMPLE_CTRL_F0_2_CLK_RATIO BIT(0)
+#define VENC_UPSAMPLE_CTRL_F1_EN BIT(5)
+#define VENC_UPSAMPLE_CTRL_F1_UPSAMPLE_EN BIT(6)
+#define VENC_UPSAMPLE_CTRL_INTERLACE_HIGH_LUMA (0x0 << 12)
+#define VENC_UPSAMPLE_CTRL_CVBS (0x1 << 12)
+#define VENC_UPSAMPLE_CTRL_S_VIDEO_LUMA (0x2 << 12)
+#define VENC_UPSAMPLE_CTRL_S_VIDEO_CHROMA (0x3 << 12)
+#define VENC_UPSAMPLE_CTRL_INTERLACE_PB (0x4 << 12)
+#define VENC_UPSAMPLE_CTRL_INTERLACE_PR (0x5 << 12)
+#define VENC_UPSAMPLE_CTRL_INTERLACE_R (0x6 << 12)
+#define VENC_UPSAMPLE_CTRL_INTERLACE_G (0x7 << 12)
+#define VENC_UPSAMPLE_CTRL_INTERLACE_B (0x8 << 12)
+#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_Y (0x9 << 12)
+#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_PB (0xa << 12)
+#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_PR (0xb << 12)
+#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_R (0xc << 12)
+#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_G (0xd << 12)
+#define VENC_UPSAMPLE_CTRL_PROGRESSIVE_B (0xe << 12)
+#define VENC_UPSAMPLE_CTRL_VDAC_TEST_VALUE (0xf << 12)
#define TCON_INVERT_CTL 0x1b67
#define VENC_VIDEO_PROG_MODE 0x1b68
#define VENC_ENCI_LINE 0x1b69
@@ -740,6 +759,7 @@
#define VENC_ENCP_PIXEL 0x1b6c
#define VENC_STATA 0x1b6d
#define VENC_INTCTRL 0x1b6e
+#define VENC_INTCTRL_ENCI_LNRST_INT_EN BIT(1)
#define VENC_INTFLAG 0x1b6f
#define VENC_VIDEO_TST_EN 0x1b70
#define VENC_VIDEO_TST_MDSEL 0x1b71
@@ -750,6 +770,7 @@
#define VENC_VIDEO_TST_CLRBAR_WIDTH 0x1b76
#define VENC_VIDEO_TST_VDCNT_STSET 0x1b77
#define VENC_VDAC_DACSEL0 0x1b78
+#define VENC_VDAC_SEL_ATV_DMD BIT(5)
#define VENC_VDAC_DACSEL1 0x1b79
#define VENC_VDAC_DACSEL2 0x1b7a
#define VENC_VDAC_DACSEL3 0x1b7b
@@ -770,6 +791,7 @@
#define VENC_VDAC_DAC5_GAINCTRL 0x1bfa
#define VENC_VDAC_DAC5_OFFSET 0x1bfb
#define VENC_VDAC_FIFO_CTRL 0x1bfc
+#define VENC_VDAC_FIFO_EN_ENCI_ENABLE BIT(13)
#define ENCL_TCON_INVERT_CTL 0x1bfd
#define ENCP_VIDEO_EN 0x1b80
#define ENCP_VIDEO_SYNC_MODE 0x1b81
@@ -785,6 +807,7 @@
#define ENCP_VIDEO_SYNC_OFFST 0x1b8b
#define ENCP_VIDEO_MACV_OFFST 0x1b8c
#define ENCP_VIDEO_MODE 0x1b8d
+#define ENCP_VIDEO_MODE_DE_V_HIGH BIT(14)
#define ENCP_VIDEO_MODE_ADV 0x1b8e
#define ENCP_DBG_PX_RST 0x1b90
#define ENCP_DBG_LN_RST 0x1b91
@@ -863,6 +886,11 @@
#define C656_FS_LNED 0x1be7
#define ENCI_VIDEO_MODE 0x1b00
#define ENCI_VIDEO_MODE_ADV 0x1b01
+#define ENCI_VIDEO_MODE_ADV_DMXMD(val) (val & 0x3)
+#define ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 BIT(2)
+#define ENCI_VIDEO_MODE_ADV_YBW_MEDIUM (0 << 4)
+#define ENCI_VIDEO_MODE_ADV_YBW_LOW (0x1 << 4)
+#define ENCI_VIDEO_MODE_ADV_YBW_HIGH (0x2 << 4)
#define ENCI_VIDEO_FSC_ADJ 0x1b02
#define ENCI_VIDEO_BRIGHT 0x1b03
#define ENCI_VIDEO_CONT 0x1b04
@@ -933,13 +961,17 @@
#define ENCI_DBG_MAXPX 0x1b4c
#define ENCI_DBG_MAXLN 0x1b4d
#define ENCI_MACV_MAX_AMP 0x1b50
+#define ENCI_MACV_MAX_AMP_ENABLE_CHANGE BIT(15)
+#define ENCI_MACV_MAX_AMP_VAL(val) (val & 0x83ff)
#define ENCI_MACV_PULSE_LO 0x1b51
#define ENCI_MACV_PULSE_HI 0x1b52
#define ENCI_MACV_BKP_MAX 0x1b53
#define ENCI_CFILT_CTRL 0x1b54
+#define ENCI_CFILT_CMPT_SEL_HIGH BIT(1)
#define ENCI_CFILT7 0x1b55
#define ENCI_YC_DELAY 0x1b56
#define ENCI_VIDEO_EN 0x1b57
+#define ENCI_VIDEO_EN_ENABLE BIT(0)
#define ENCI_DVI_HSO_BEGIN 0x1c00
#define ENCI_DVI_HSO_END 0x1c01
#define ENCI_DVI_VSO_BLINE_EVN 0x1c02
@@ -951,6 +983,10 @@
#define ENCI_DVI_VSO_END_EVN 0x1c08
#define ENCI_DVI_VSO_END_ODD 0x1c09
#define ENCI_CFILT_CTRL2 0x1c0a
+#define ENCI_CFILT_CMPT_CR_DLY(delay) (delay & 0xf)
+#define ENCI_CFILT_CMPT_CB_DLY(delay) ((delay & 0xf) << 4)
+#define ENCI_CFILT_CVBS_CR_DLY(delay) ((delay & 0xf) << 8)
+#define ENCI_CFILT_CVBS_CB_DLY(delay) ((delay & 0xf) << 12)
#define ENCI_DACSEL_0 0x1c0b
#define ENCI_DACSEL_1 0x1c0c
#define ENCP_DACSEL_0 0x1c0d
@@ -965,6 +1001,8 @@
#define ENCI_TST_CLRBAR_WIDTH 0x1c16
#define ENCI_TST_VDCNT_STSET 0x1c17
#define ENCI_VFIFO2VD_CTL 0x1c18
+#define ENCI_VFIFO2VD_CTL_ENABLE BIT(0)
+#define ENCI_VFIFO2VD_CTL_VD_SEL(val) ((val & 0xff) << 8)
#define ENCI_VFIFO2VD_PIXEL_START 0x1c19
#define ENCI_VFIFO2VD_PIXEL_END 0x1c1a
#define ENCI_VFIFO2VD_LINE_TOP_START 0x1c1b
@@ -1027,6 +1065,7 @@
#define VENC_VDAC_DAC5_FILT_CTRL0 0x1c56
#define VENC_VDAC_DAC5_FILT_CTRL1 0x1c57
#define VENC_VDAC_DAC0_FILT_CTRL0 0x1c58
+#define VENC_VDAC_DAC0_FILT_CTRL0_EN BIT(0)
#define VENC_VDAC_DAC0_FILT_CTRL1 0x1c59
#define VENC_VDAC_DAC1_FILT_CTRL0 0x1c5a
#define VENC_VDAC_DAC1_FILT_CTRL1 0x1c5b
@@ -1432,6 +1471,18 @@
#define VIU2_SEL_VENC_ENCP (2 << 2)
#define VIU2_SEL_VENC_ENCT (3 << 2)
#define VPU_HDMI_SETTING 0x271b
+#define VPU_HDMI_ENCI_DATA_TO_HDMI BIT(0)
+#define VPU_HDMI_ENCP_DATA_TO_HDMI BIT(1)
+#define VPU_HDMI_INV_HSYNC BIT(2)
+#define VPU_HDMI_INV_VSYNC BIT(3)
+#define VPU_HDMI_OUTPUT_CRYCB (0 << 5)
+#define VPU_HDMI_OUTPUT_YCBCR (1 << 5)
+#define VPU_HDMI_OUTPUT_YCRCB (2 << 5)
+#define VPU_HDMI_OUTPUT_CBCRY (3 << 5)
+#define VPU_HDMI_OUTPUT_CBYCR (4 << 5)
+#define VPU_HDMI_OUTPUT_CRCBY (5 << 5)
+#define VPU_HDMI_WR_RATE(rate) (((rate & 0x1f) - 1) << 8)
+#define VPU_HDMI_RD_RATE(rate) (((rate & 0x1f) - 1) << 12)
#define ENCI_INFO_READ 0x271c
#define ENCP_INFO_READ 0x271d
#define ENCT_INFO_READ 0x271e
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 7b7a0d8d737c..918df02d2aef 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -976,6 +976,7 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
unsigned int eof_lines;
unsigned int sof_lines;
unsigned int vsync_lines;
+ u32 reg;
/* Use VENCI for 480i and 576i and double HDMI pixels */
if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
@@ -1048,8 +1049,11 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
unsigned int lines_f1;
/* CVBS Filter settings */
- writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL));
- writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2));
+ writel_relaxed(ENCI_CFILT_CMPT_SEL_HIGH | 0x10,
+ priv->io_base + _REG(ENCI_CFILT_CTRL));
+ writel_relaxed(ENCI_CFILT_CMPT_CR_DLY(2) |
+ ENCI_CFILT_CMPT_CB_DLY(1),
+ priv->io_base + _REG(ENCI_CFILT_CTRL2));
/* Digital Video Select : Interlace, clk27 clk, external */
writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
@@ -1071,8 +1075,9 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
/* Macrovision max amplitude change */
- writel_relaxed(vmode->enci.macv_max_amp,
- priv->io_base + _REG(ENCI_MACV_MAX_AMP));
+ writel_relaxed(ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
+ ENCI_MACV_MAX_AMP_VAL(vmode->enci.macv_max_amp),
+ priv->io_base + _REG(ENCI_MACV_MAX_AMP));
/* Video mode */
writel_relaxed(vmode->enci.video_prog_mode,
@@ -1088,7 +1093,10 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
* Bypass luma low pass filter
* No macrovision on CSYNC
*/
- writel_relaxed(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
+ writel_relaxed(ENCI_VIDEO_MODE_ADV_DMXMD(2) |
+ ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
+ ENCI_VIDEO_MODE_ADV_YBW_HIGH,
+ priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
writel(vmode->enci.sch_adjust,
priv->io_base + _REG(ENCI_VIDEO_SCH));
@@ -1104,8 +1112,17 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
/* UNreset Interlaced TV Encoder */
writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
- /* Enable Vfifo2vd, Y_Cb_Y_Cr select */
- writel_relaxed(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
+ /*
+ * Enable Vfifo2vd and set Y_Cb_Y_Cr:
+ * Corresponding value:
+ * Y => 00 or 10
+ * Cb => 01
+ * Cr => 11
+ * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y
+ */
+ writel_relaxed(ENCI_VFIFO2VD_CTL_ENABLE |
+ ENCI_VFIFO2VD_CTL_VD_SEL(0x4e),
+ priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
/* Timings */
writel_relaxed(vmode->enci.pixel_start,
@@ -1127,7 +1144,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
/* Interlace video enable */
- writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
+ writel_relaxed(ENCI_VIDEO_EN_ENABLE,
+ priv->io_base + _REG(ENCI_VIDEO_EN));
lines_f0 = mode->vtotal >> 1;
lines_f1 = lines_f0 + 1;
@@ -1374,7 +1392,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
writel_relaxed(1, priv->io_base + _REG(ENCP_VIDEO_EN));
/* Set DE signals polarity is active high */
- writel_bits_relaxed(BIT(14), BIT(14),
+ writel_bits_relaxed(ENCP_VIDEO_MODE_DE_V_HIGH,
+ ENCP_VIDEO_MODE_DE_V_HIGH,
priv->io_base + _REG(ENCP_VIDEO_MODE));
/* Program DE timing */
@@ -1493,13 +1512,39 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCP);
}
- writel_relaxed((use_enci ? 1 : 2) |
- (mode->flags & DRM_MODE_FLAG_PHSYNC ? 1 << 2 : 0) |
- (mode->flags & DRM_MODE_FLAG_PVSYNC ? 1 << 3 : 0) |
- 4 << 5 |
- (venc_repeat ? 1 << 8 : 0) |
- (hdmi_repeat ? 1 << 12 : 0),
- priv->io_base + _REG(VPU_HDMI_SETTING));
+ /* Set VPU HDMI setting */
+ /* Select ENCP or ENCI data to HDMI */
+ if (use_enci)
+ reg = VPU_HDMI_ENCI_DATA_TO_HDMI;
+ else
+ reg = VPU_HDMI_ENCP_DATA_TO_HDMI;
+
+ /* Invert polarity of HSYNC from VENC */
+ if (mode->flags & DRM_MODE_FLAG_PHSYNC)
+ reg |= VPU_HDMI_INV_HSYNC;
+
+ /* Invert polarity of VSYNC from VENC */
+ if (mode->flags & DRM_MODE_FLAG_PVSYNC)
+ reg |= VPU_HDMI_INV_VSYNC;
+
+ /* Output data format: CbYCr */
+ reg |= VPU_HDMI_OUTPUT_CBYCR;
+
+ /*
+ * Write rate to the async FIFO between VENC and HDMI.
+ * One write every 2 wr_clk.
+ */
+ if (venc_repeat)
+ reg |= VPU_HDMI_WR_RATE(2);
+
+ /*
+ * Read rate to the async FIFO between VENC and HDMI.
+ * One read every 2 wr_clk.
+ */
+ if (hdmi_repeat)
+ reg |= VPU_HDMI_RD_RATE(2);
+
+ writel_relaxed(reg, priv->io_base + _REG(VPU_HDMI_SETTING));
priv->venc.hdmi_repeat = hdmi_repeat;
priv->venc.venc_repeat = venc_repeat;
@@ -1512,12 +1557,17 @@ EXPORT_SYMBOL_GPL(meson_venc_hdmi_mode_set);
void meson_venci_cvbs_mode_set(struct meson_drm *priv,
struct meson_cvbs_enci_mode *mode)
{
+ u32 reg;
+
if (mode->mode_tag == priv->venc.current_mode)
return;
/* CVBS Filter settings */
- writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL));
- writel_relaxed(0x12, priv->io_base + _REG(ENCI_CFILT_CTRL2));
+ writel_relaxed(ENCI_CFILT_CMPT_SEL_HIGH | 0x10,
+ priv->io_base + _REG(ENCI_CFILT_CTRL));
+ writel_relaxed(ENCI_CFILT_CMPT_CR_DLY(2) |
+ ENCI_CFILT_CMPT_CB_DLY(1),
+ priv->io_base + _REG(ENCI_CFILT_CTRL2));
/* Digital Video Select : Interlace, clk27 clk, external */
writel_relaxed(0, priv->io_base + _REG(VENC_DVI_SETTING));
@@ -1539,8 +1589,9 @@ void meson_venci_cvbs_mode_set(struct meson_drm *priv,
priv->io_base + _REG(ENCI_SYNC_VSO_ODDLN));
/* Macrovision max amplitude change */
- writel_relaxed(0x8100 + mode->macv_max_amp,
- priv->io_base + _REG(ENCI_MACV_MAX_AMP));
+ writel_relaxed(ENCI_MACV_MAX_AMP_ENABLE_CHANGE |
+ ENCI_MACV_MAX_AMP_VAL(mode->macv_max_amp),
+ priv->io_base + _REG(ENCI_MACV_MAX_AMP));
/* Video mode */
writel_relaxed(mode->video_prog_mode,
@@ -1556,7 +1607,10 @@ void meson_venci_cvbs_mode_set(struct meson_drm *priv,
* Bypass luma low pass filter
* No macrovision on CSYNC
*/
- writel_relaxed(0x26, priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
+ writel_relaxed(ENCI_VIDEO_MODE_ADV_DMXMD(2) |
+ ENCI_VIDEO_MODE_ADV_VBICTL_LINE_17_22 |
+ ENCI_VIDEO_MODE_ADV_YBW_HIGH,
+ priv->io_base + _REG(ENCI_VIDEO_MODE_ADV));
writel(mode->sch_adjust, priv->io_base + _REG(ENCI_VIDEO_SCH));
@@ -1588,16 +1642,50 @@ void meson_venci_cvbs_mode_set(struct meson_drm *priv,
/* UNreset Interlaced TV Encoder */
writel_relaxed(0, priv->io_base + _REG(ENCI_DBG_PX_RST));
- /* Enable Vfifo2vd, Y_Cb_Y_Cr select */
- writel_relaxed(0x4e01, priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
+ /*
+ * Enable Vfifo2vd and set Y_Cb_Y_Cr:
+ * Corresponding value:
+ * Y => 00 or 10
+ * Cb => 01
+ * Cr => 11
+ * Ex: 0x4e => 01001110 would mean Cb/Y/Cr/Y
+ */
+ writel_relaxed(ENCI_VFIFO2VD_CTL_ENABLE |
+ ENCI_VFIFO2VD_CTL_VD_SEL(0x4e),
+ priv->io_base + _REG(ENCI_VFIFO2VD_CTL));
/* Power UP Dacs */
writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_SETTING));
/* Video Upsampling */
- writel_relaxed(0x0061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL0));
- writel_relaxed(0x4061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL1));
- writel_relaxed(0x5061, priv->io_base + _REG(VENC_UPSAMPLE_CTRL2));
+ /*
+ * CTRL0, CTRL1 and CTRL2:
+ * Filter0: input data sample every 2 cloks
+ * Filter1: filtering and upsample enable
+ */
+ reg = VENC_UPSAMPLE_CTRL_F0_2_CLK_RATIO | VENC_UPSAMPLE_CTRL_F1_EN |
+ VENC_UPSAMPLE_CTRL_F1_UPSAMPLE_EN;
+
+ /*
+ * Upsample CTRL0:
+ * Interlace High Bandwidth Luma
+ */
+ writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_HIGH_LUMA | reg,
+ priv->io_base + _REG(VENC_UPSAMPLE_CTRL0));
+
+ /*
+ * Upsample CTRL1:
+ * Interlace Pb
+ */
+ writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_PB | reg,
+ priv->io_base + _REG(VENC_UPSAMPLE_CTRL1));
+
+ /*
+ * Upsample CTRL2:
+ * Interlace R
+ */
+ writel_relaxed(VENC_UPSAMPLE_CTRL_INTERLACE_PR | reg,
+ priv->io_base + _REG(VENC_UPSAMPLE_CTRL2));
/* Select Interlace Y DACs */
writel_relaxed(0, priv->io_base + _REG(VENC_VDAC_DACSEL0));
@@ -1611,14 +1699,16 @@ void meson_venci_cvbs_mode_set(struct meson_drm *priv,
meson_vpp_setup_mux(priv, MESON_VIU_VPP_MUX_ENCI);
/* Enable ENCI FIFO */
- writel_relaxed(0x2000, priv->io_base + _REG(VENC_VDAC_FIFO_CTRL));
+ writel_relaxed(VENC_VDAC_FIFO_EN_ENCI_ENABLE,
+ priv->io_base + _REG(VENC_VDAC_FIFO_CTRL));
/* Select ENCI DACs 0, 1, 4, and 5 */
writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_0));
writel_relaxed(0x11, priv->io_base + _REG(ENCI_DACSEL_1));
/* Interlace video enable */
- writel_relaxed(1, priv->io_base + _REG(ENCI_VIDEO_EN));
+ writel_relaxed(ENCI_VIDEO_EN_ENABLE,
+ priv->io_base + _REG(ENCI_VIDEO_EN));
/* Configure Video Saturation / Contrast / Brightness / Hue */
writel_relaxed(mode->video_saturation,
@@ -1631,7 +1721,8 @@ void meson_venci_cvbs_mode_set(struct meson_drm *priv,
priv->io_base + _REG(ENCI_VIDEO_HUE));
/* Enable DAC0 Filter */
- writel_relaxed(0x1, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0));
+ writel_relaxed(VENC_VDAC_DAC0_FILT_CTRL0_EN,
+ priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL0));
writel_relaxed(0xfc48, priv->io_base + _REG(VENC_VDAC_DAC0_FILT_CTRL1));
/* 0 in Macrovision register 0 */
@@ -1652,7 +1743,8 @@ unsigned int meson_venci_get_field(struct meson_drm *priv)
void meson_venc_enable_vsync(struct meson_drm *priv)
{
- writel_relaxed(2, priv->io_base + _REG(VENC_INTCTRL));
+ writel_relaxed(VENC_INTCTRL_ENCI_LNRST_INT_EN,
+ priv->io_base + _REG(VENC_INTCTRL));
regmap_update_bits(priv->hhi, HHI_GCLK_MPEG2, BIT(25), BIT(25));
}
@@ -1680,7 +1772,8 @@ void meson_venc_init(struct meson_drm *priv)
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0);
/* Disable HDMI */
- writel_bits_relaxed(0x3, 0,
+ writel_bits_relaxed(VPU_HDMI_ENCI_DATA_TO_HDMI |
+ VPU_HDMI_ENCP_DATA_TO_HDMI, 0,
priv->io_base + _REG(VPU_HDMI_SETTING));
/* Disable all encoders */
diff --git a/drivers/gpu/drm/meson/meson_venc_cvbs.c b/drivers/gpu/drm/meson/meson_venc_cvbs.c
index 6313a519f257..7ecc6bb6c8f8 100644
--- a/drivers/gpu/drm/meson/meson_venc_cvbs.c
+++ b/drivers/gpu/drm/meson/meson_venc_cvbs.c
@@ -172,7 +172,8 @@ static void meson_venc_cvbs_encoder_enable(struct drm_encoder *encoder)
struct meson_drm *priv = meson_venc_cvbs->priv;
/* VDAC0 source is not from ATV */
- writel_bits_relaxed(BIT(5), 0, priv->io_base + _REG(VENC_VDAC_DACSEL0));
+ writel_bits_relaxed(VENC_VDAC_SEL_ATV_DMD, 0,
+ priv->io_base + _REG(VENC_VDAC_DACSEL0));
if (meson_vpu_is_compatible(priv, "amlogic,meson-gxbb-vpu")) {
regmap_write(priv->hhi, HHI_VDAC_CNTL0, 1);
--
2.17.1

View File

@ -0,0 +1,209 @@
From c725303b5df553247fe82b4d5f5b67474b8fadb7 Mon Sep 17 00:00:00 2001
From: Julien Masson <jmasson@baylibre.com>
Date: Mon, 24 Jun 2019 16:48:57 +0200
Subject: [PATCH 064/186] FROMGIT: drm: meson: global clean-up
This patch aims to:
- Add general and TODO comments
- Respect coding style for multi-line comments
- Align macro definitions
- Remove useless macro
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/86pnn382e8.fsf@baylibre.com
(cherry picked from commit e1012141242db89259175eeaac36b3de04377664
git://anongit.freedesktop.org/drm/drm-misc drm-misc-next)
---
drivers/gpu/drm/meson/meson_dw_hdmi.c | 2 ++
drivers/gpu/drm/meson/meson_dw_hdmi.h | 12 ++++++----
drivers/gpu/drm/meson/meson_registers.h | 31 +++++++++++--------------
drivers/gpu/drm/meson/meson_vclk.c | 4 +++-
drivers/gpu/drm/meson/meson_venc.c | 10 ++++----
5 files changed, 33 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.c b/drivers/gpu/drm/meson/meson_dw_hdmi.c
index df3f9ddd2234..1579ff76c1ed 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.c
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.c
@@ -428,6 +428,8 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
/* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */
dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
0x3, 0x3);
+
+ /* Enable cec_clk and hdcp22_tmdsclk_en */
dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
0x3 << 4, 0x3 << 4);
diff --git a/drivers/gpu/drm/meson/meson_dw_hdmi.h b/drivers/gpu/drm/meson/meson_dw_hdmi.h
index 1b2ef043eb5c..08e1c14e4ea0 100644
--- a/drivers/gpu/drm/meson/meson_dw_hdmi.h
+++ b/drivers/gpu/drm/meson/meson_dw_hdmi.h
@@ -100,7 +100,8 @@
#define HDMITX_TOP_INTR_RXSENSE_RISE BIT(6)
#define HDMITX_TOP_INTR_RXSENSE_FALL BIT(7)
-/* Bit 14:12 RW tmds_sel: 3'b000=Output zero; 3'b001=Output normal TMDS data;
+/*
+ * Bit 14:12 RW tmds_sel: 3'b000=Output zero; 3'b001=Output normal TMDS data;
* 3'b010=Output PRBS data; 3'b100=Output shift pattern. Default 0.
* Bit 11: 9 RW shift_pttn_repeat: 0=New pattern every clk cycle; 1=New pattern
* every 2 clk cycles; ...; 7=New pattern every 8 clk cycles. Default 0.
@@ -135,7 +136,8 @@
/* Bit 9: 0 RW tmds_clk_pttn[29:20]. Default 0. */
#define HDMITX_TOP_TMDS_CLK_PTTN_23 (0x00B)
-/* Bit 1 RW shift_tmds_clk_pttn:1=Enable shifting clk pattern,
+/*
+ * Bit 1 RW shift_tmds_clk_pttn:1=Enable shifting clk pattern,
* used when TMDS CLK rate = TMDS character rate /4. Default 0.
* Bit 0 R Reserved. Default 0.
* [ 1] shift_tmds_clk_pttn
@@ -143,12 +145,14 @@
*/
#define HDMITX_TOP_TMDS_CLK_PTTN_CNTL (0x00C)
-/* Bit 0 RW revocmem_wr_fail: Read back 1 to indicate Host write REVOC MEM
+/*
+ * Bit 0 RW revocmem_wr_fail: Read back 1 to indicate Host write REVOC MEM
* failure, write 1 to clear the failure flag. Default 0.
*/
#define HDMITX_TOP_REVOCMEM_STAT (0x00D)
-/* Bit 1 R filtered RxSense status
+/*
+ * Bit 1 R filtered RxSense status
* Bit 0 R filtered HPD status.
*/
#define HDMITX_TOP_STAT0 (0x00E)
diff --git a/drivers/gpu/drm/meson/meson_registers.h b/drivers/gpu/drm/meson/meson_registers.h
index ec73eaa4a0bf..cf55723b8f16 100644
--- a/drivers/gpu/drm/meson/meson_registers.h
+++ b/drivers/gpu/drm/meson/meson_registers.h
@@ -396,19 +396,19 @@
#define VPP_PREBLEND_CURRENT_XY 0x1d24
#define VPP_POSTBLEND_CURRENT_XY 0x1d25
#define VPP_MISC 0x1d26
-#define VPP_PREBLEND_ENABLE BIT(6)
-#define VPP_POSTBLEND_ENABLE BIT(7)
-#define VPP_OSD2_ALPHA_PREMULT BIT(8)
-#define VPP_OSD1_ALPHA_PREMULT BIT(9)
-#define VPP_VD1_POSTBLEND BIT(10)
-#define VPP_VD2_POSTBLEND BIT(11)
-#define VPP_OSD1_POSTBLEND BIT(12)
-#define VPP_OSD2_POSTBLEND BIT(13)
-#define VPP_VD1_PREBLEND BIT(14)
-#define VPP_VD2_PREBLEND BIT(15)
-#define VPP_OSD1_PREBLEND BIT(16)
-#define VPP_OSD2_PREBLEND BIT(17)
-#define VPP_COLOR_MNG_ENABLE BIT(28)
+#define VPP_PREBLEND_ENABLE BIT(6)
+#define VPP_POSTBLEND_ENABLE BIT(7)
+#define VPP_OSD2_ALPHA_PREMULT BIT(8)
+#define VPP_OSD1_ALPHA_PREMULT BIT(9)
+#define VPP_VD1_POSTBLEND BIT(10)
+#define VPP_VD2_POSTBLEND BIT(11)
+#define VPP_OSD1_POSTBLEND BIT(12)
+#define VPP_OSD2_POSTBLEND BIT(13)
+#define VPP_VD1_PREBLEND BIT(14)
+#define VPP_VD2_PREBLEND BIT(15)
+#define VPP_OSD1_PREBLEND BIT(16)
+#define VPP_OSD2_PREBLEND BIT(17)
+#define VPP_COLOR_MNG_ENABLE BIT(28)
#define VPP_OFIFO_SIZE 0x1d27
#define VPP_OFIFO_SIZE_MASK GENMASK(13, 0)
#define VPP_OFIFO_SIZE_DEFAULT (0xfff << 20 | 0x1000)
@@ -619,6 +619,7 @@
#define OSD34_SCI_WH_M1 0x3d29
#define OSD34_SCO_H_START_END 0x3d2a
#define OSD34_SCO_V_START_END 0x3d2b
+
/* viu2 */
#define VIU2_ADDR_START 0x1e00
#define VIU2_ADDR_END 0x1eff
@@ -1601,7 +1602,6 @@
#define OSD1_AFBCD_STATUS 0x31a8
#define OSD1_AFBCD_PIXEL_HSCOPE 0x31a9
#define OSD1_AFBCD_PIXEL_VSCOPE 0x31aa
-#define VIU_MISC_CTRL1 0x1a07
/* add for gxm and 962e dv core2 */
#define DOLBY_CORE2A_SWAP_CTRL1 0x3434
@@ -1616,8 +1616,6 @@
#define VPU_MAFBC_COMMAND 0x3a05
#define VPU_MAFBC_STATUS 0x3a06
#define VPU_MAFBC_SURFACE_CFG 0x3a07
-
-/* osd afbc on g12a */
#define VPU_MAFBC_HEADER_BUF_ADDR_LOW_S0 0x3a10
#define VPU_MAFBC_HEADER_BUF_ADDR_HIGH_S0 0x3a11
#define VPU_MAFBC_FORMAT_SPECIFIER_S0 0x3a12
@@ -1738,6 +1736,5 @@
#define VPP_POST_BLEND_DUMMY_ALPHA 0x3969
#define VPP_RDARB_MODE 0x3978
#define VPP_RDARB_REQEN_SLV 0x3979
-#define VPU_RDARB_MODE_L2C1 0x279d
#endif /* __MESON_REGISTERS_H */
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index 26732f038d19..e7c2b439d0f7 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -495,6 +495,7 @@ void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL, 0x0b3a0400 | m);
/* Enable and reset */
+ /* TODO: add specific macro for g12a here */
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
0x3 << 28, 0x3 << 28);
@@ -969,7 +970,8 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
meson_venci_cvbs_clock_config(priv);
return;
} else if (target == MESON_VCLK_TARGET_DMT) {
- /* The DMT clock path is fixed after the PLL:
+ /*
+ * The DMT clock path is fixed after the PLL:
* - automatic PLL freq + OD management
* - vid_pll_div = VID_PLL_DIV_5
* - vclk_div = 2
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 918df02d2aef..2835133ab676 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -61,9 +61,9 @@
/* HHI Registers */
#define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */
#define HHI_VDAC_CNTL0 0x2F4 /* 0xbd offset in data sheet */
-#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbd offset in data sheet */
+#define HHI_VDAC_CNTL0_G12A 0x2EC /* 0xbb offset in data sheet */
#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
-#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbe offset in data sheet */
+#define HHI_VDAC_CNTL1_G12A 0x2F0 /* 0xbc offset in data sheet */
#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 offset in data sheet */
struct meson_cvbs_enci_mode meson_cvbs_enci_pal = {
@@ -1085,7 +1085,8 @@ void meson_venc_hdmi_mode_set(struct meson_drm *priv, int vic,
writel_relaxed(vmode->enci.video_mode,
priv->io_base + _REG(ENCI_VIDEO_MODE));
- /* Advanced Video Mode :
+ /*
+ * Advanced Video Mode :
* Demux shifting 0x2
* Blank line end at line17/22
* High bandwidth Luma Filter
@@ -1599,7 +1600,8 @@ void meson_venci_cvbs_mode_set(struct meson_drm *priv,
writel_relaxed(mode->video_mode,
priv->io_base + _REG(ENCI_VIDEO_MODE));
- /* Advanced Video Mode :
+ /*
+ * Advanced Video Mode :
* Demux shifting 0x2
* Blank line end at line17/22
* High bandwidth Luma Filter
--
2.17.1

View File

@ -0,0 +1,43 @@
From e46b2434cf1888101c42895d0213b86b8cee487b Mon Sep 17 00:00:00 2001
From: Julien Masson <jmasson@baylibre.com>
Date: Mon, 24 Jun 2019 16:49:04 +0200
Subject: [PATCH 065/186] FROMGIT: drm: meson: add macro used to enable HDMI
PLL
This patch add new macro HHI_HDMI_PLL_CNTL_EN which is used to enable
HDMI PLL.
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/86o92n82e1.fsf@baylibre.com
(cherry picked from commit 0703146060786f972aaa22cad9c877a6067fd47d
git://anongit.freedesktop.org/drm/drm-misc drm-misc-next)
---
drivers/gpu/drm/meson/meson_vclk.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index e7c2b439d0f7..be6e152fc75a 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -96,6 +96,7 @@
#define HHI_VDAC_CNTL1 0x2F8 /* 0xbe offset in data sheet */
#define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */
+#define HHI_HDMI_PLL_CNTL_EN BIT(30)
#define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in data sheet */
#define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in data sheet */
#define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in data sheet */
@@ -468,7 +469,7 @@ void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
/* Enable and unreset */
regmap_update_bits(priv->hhi, HHI_HDMI_PLL_CNTL,
- 0x7 << 28, 0x4 << 28);
+ 0x7 << 28, HHI_HDMI_PLL_CNTL_EN);
/* Poll for lock bit */
regmap_read_poll_timeout(priv->hhi, HHI_HDMI_PLL_CNTL,
--
2.17.1

View File

@ -0,0 +1,48 @@
From 50ad4cbf00bae7102ce79455c07f6725af50b5fe Mon Sep 17 00:00:00 2001
From: Julien Masson <jmasson@baylibre.com>
Date: Mon, 24 Jun 2019 16:49:12 +0200
Subject: [PATCH 066/186] FROMGIT: drm: meson: venc: set the correct
macrovision max amplitude value
According to the register description of ENCI_MACV_MAX_AMP, the
macrovision max amplitude value should be:
- hdmi 480i => 0xb
- hdmi 576i => 0x7
The max value is 0x7ff (10 bits).
Signed-off-by: Julien Masson <jmasson@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Link: https://patchwork.freedesktop.org/patch/msgid/86mui782dt.fsf@baylibre.com
(cherry picked from commit a84ddb83806ed43a67f6fe6a03b0b4695cc314c3
git://anongit.freedesktop.org/drm/drm-misc drm-misc-next)
---
drivers/gpu/drm/meson/meson_venc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_venc.c b/drivers/gpu/drm/meson/meson_venc.c
index 2835133ab676..acad16ff7371 100644
--- a/drivers/gpu/drm/meson/meson_venc.c
+++ b/drivers/gpu/drm/meson/meson_venc.c
@@ -192,7 +192,7 @@ union meson_hdmi_venc_mode meson_hdmi_enci_mode_480i = {
.hso_end = 129,
.vso_even = 3,
.vso_odd = 260,
- .macv_max_amp = 0x810b,
+ .macv_max_amp = 0xb,
.video_prog_mode = 0xf0,
.video_mode = 0x8,
.sch_adjust = 0x20,
@@ -212,7 +212,7 @@ union meson_hdmi_venc_mode meson_hdmi_enci_mode_576i = {
.hso_end = 129,
.vso_even = 3,
.vso_odd = 260,
- .macv_max_amp = 8107,
+ .macv_max_amp = 0x7,
.video_prog_mode = 0xff,
.video_mode = 0x13,
.sch_adjust = 0x28,
--
2.17.1

View File

@ -0,0 +1,39 @@
From 7223e09063a1bebb60a57fd9541fc8ec80348f96 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 13 May 2019 14:45:31 +0200
Subject: [PATCH 067/186] FROMLIST: clk: meson: g12a: fix gp0 and hifi ranges
While some SoC samples are able to lock with a PLL factor of 55, others
samples can't. ATM, a minimum of 60 appears to work on all the samples
I have tried.
Even with 60, it sometimes takes a long time for the PLL to eventually
lock. The documentation says that the minimum rate of these PLLs DCO
should be 3GHz, a factor of 125. Let's use that to be on the safe side.
With factor range changed, the PLL seems to lock quickly (enough) so far.
It is still unclear if the range was the only reason for the delay.
Fixes: 085a4ea93d54 ("clk: meson: g12a: add peripheral clock controller")
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/g12a.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c
index c3f0ffc3280d..e6011d18a719 100644
--- a/drivers/clk/meson/g12a.c
+++ b/drivers/clk/meson/g12a.c
@@ -1362,7 +1362,7 @@ static struct clk_regmap g12b_cpub_clk_trace = {
};
static const struct pll_mult_range g12a_gp0_pll_mult_range = {
- .min = 55,
+ .min = 125,
.max = 255,
};
--
2.17.1

View File

@ -0,0 +1,161 @@
From 1730bc1f2e2630a7882f680cb795e1f7229fb470 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 29 Jul 2019 15:26:21 +0200
Subject: [PATCH 068/186] FROMLIST: arm64: dts: meson-g12b: add cpus OPP tables
Add the OPP table taken from the HardKernel Odroid-N2 DTS.
The Amlogic G12B SoC seems to available in 2 types :
- low-speed: Cortex-A73 Cluster up to 1,704GHz
- high-speed: Cortex-A73 Cluster up to 2.208GHz
The Cortex-A73 Cluster can be clocked up to 1,896GHz for both types.
The Vendor Amlogic A311D OPP table are slighly different, with lower
voltages than the HardKernel S922X tables but seems to be high-speed type.
This adds the conservative OPP table with the S922X higher voltages
and the maximum low-speed OPP frequency.
The values were tested to be stable on an HardKernel Odroid-N2 board
running the arm64 cpuburn at [1] and cycling between all the possible
cpufreq translations for both clusters and checking the final frequency
using the clock-measurer, script at [2].
[1] https://github.com/ssvb/cpuburn-arm/blob/master/cpuburn-a53.S
[2] https://gist.github.com/superna9999/d4de964dbc0f84b7d527e1df2ddea25f
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-g12b.dtsi | 115 ++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
index d5edbc1a1991..98ae8a7c8b41 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b.dtsi
@@ -95,6 +95,121 @@
compatible = "cache";
};
};
+
+ cpu_opp_table_0: opp-table-0 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-666666666 {
+ opp-hz = /bits/ 64 <666666666>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <731000>;
+ };
+
+ opp-1398000000 {
+ opp-hz = /bits/ 64 <1398000000>;
+ opp-microvolt = <761000>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <791000>;
+ };
+
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <831000>;
+ };
+
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <861000>;
+ };
+
+ opp-1896000000 {
+ opp-hz = /bits/ 64 <1896000000>;
+ opp-microvolt = <981000>;
+ };
+ };
+
+ cpub_opp_table_1: opp-table-1 {
+ compatible = "operating-points-v2";
+ opp-shared;
+
+ opp-100000000 {
+ opp-hz = /bits/ 64 <100000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-250000000 {
+ opp-hz = /bits/ 64 <250000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-500000000 {
+ opp-hz = /bits/ 64 <500000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-666666666 {
+ opp-hz = /bits/ 64 <666666666>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-1000000000 {
+ opp-hz = /bits/ 64 <1000000000>;
+ opp-microvolt = <751000>;
+ };
+
+ opp-1200000000 {
+ opp-hz = /bits/ 64 <1200000000>;
+ opp-microvolt = <771000>;
+ };
+
+ opp-1398000000 {
+ opp-hz = /bits/ 64 <1398000000>;
+ opp-microvolt = <791000>;
+ };
+
+ opp-1512000000 {
+ opp-hz = /bits/ 64 <1512000000>;
+ opp-microvolt = <821000>;
+ };
+
+ opp-1608000000 {
+ opp-hz = /bits/ 64 <1608000000>;
+ opp-microvolt = <861000>;
+ };
+
+ opp-1704000000 {
+ opp-hz = /bits/ 64 <1704000000>;
+ opp-microvolt = <891000>;
+ };
+ };
};
&clkc {
--
2.17.1

View File

@ -0,0 +1,152 @@
From 8a02a40f31fff630ddc0c9c98c9490a29d192baf Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Mon, 29 Jul 2019 15:26:22 +0200
Subject: [PATCH 069/186] FROMLIST: arm64: dts: meson-g12b-odroid-n2: enable
DVFS
Enable DVFS for the Odroid-N2 by setting the clock, OPP and supply
for each cores of each CPU clusters.
The first cluster uses the "VDDCPU_B" power supply, and the second
cluster uses the "VDDCPU_A" power supply.
Each power supply can achieve 0.73V to 1.01V using 2 distinct PWM
outputs clocked at 800KHz with an inverse duty-cycle.
DVFS has been tested by running the arm64 cpuburn at [1] and cycling
between all the possible cpufreq translations of each cluster and
checking the final frequency using the clock-measurer, script at [2].
[1] https://github.com/ssvb/cpuburn-arm/blob/master/cpuburn-a53.S
[2] https://gist.github.com/superna9999/d4de964dbc0f84b7d527e1df2ddea25f
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../boot/dts/amlogic/meson-g12b-odroid-n2.dts | 96 +++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
index 237adae0ffae..6cfc2c69bb4f 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
@@ -115,6 +115,44 @@
/* FIXME: actually controlled by VDDCPU_B_EN */
};
+ vddcpu_a: regulator-vddcpu-a {
+ /*
+ * MP8756GD Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU_A";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ vin-supply = <&main_12v>;
+
+ pwms = <&pwm_ab 0 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vddcpu_b: regulator-vddcpu-b {
+ /*
+ * Silergy SY8120B1ABC Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU_B";
+ regulator-min-microvolt = <721000>;
+ regulator-max-microvolt = <1022000>;
+
+ vin-supply = <&main_12v>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
hub_5v: regulator-hub_5v {
compatible = "regulator-fixed";
regulator-name = "HUB_5V";
@@ -246,6 +284,48 @@
status = "okay";
};
+&cpu0 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table_0>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table_0>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu100 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu101 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu102 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu103 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
&ext_mdio {
external_phy: ethernet-phy@0 {
/* Realtek RTL8211F (0x001cc916) */
@@ -317,6 +397,22 @@
pinctrl-names = "default";
};
+&pwm_ab {
+ pinctrl-0 = <&pwm_a_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin0";
+ status = "okay";
+};
+
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
/* SD card */
&sd_emmc_b {
status = "okay";
--
2.17.1

View File

@ -0,0 +1,80 @@
From a3b3dc378a10d28451ed5c62b36b39327e7093a6 Mon Sep 17 00:00:00 2001
From: Guillaume La Roque <glaroque@baylibre.com>
Date: Tue, 6 Aug 2019 15:05:01 +0200
Subject: [PATCH 070/186] FROMLIST: dt-bindings: thermal: Add DT bindings
documentation for Amlogic Thermal
Adding the devicetree binding documentation for the Amlogic temperature
sensor found in the Amlogic Meson G12 SoCs.
the G12A and G12B SoCs are supported.
Signed-off-by: Guillaume La Roque <glaroque@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../bindings/thermal/amlogic,thermal.yaml | 54 +++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100644 Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
diff --git a/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
new file mode 100644
index 000000000000..d25e59113398
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/thermal/amlogic,thermal.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic Thermal
+
+maintainers:
+ - Guillaume La Roque <glaroque@baylibre.com>
+
+description: Binding for Amlogic Thermal Driver
+
+properties:
+ compatible:
+ items:
+ - enum:
+ - amlogic,g12-cpu-thermal
+ - amlogic,g12-ddr-thermal
+ - const: amlogic,g12-thermal
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ amlogic,ao-secure:
+ description: phandle to the ao-secure syscon
+ $ref: '/schemas/types.yaml#/definitions/phandle'
+
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - clocks
+ - amlogic,ao-secure
+
+examples:
+ - |
+ cpu_temp: temperature-sensor@ff634800 {
+ compatible = "amlogic,g12-cpu-thermal",
+ "amlogic,g12-thermal";
+ reg = <0xff634800 0x50>;
+ interrupts = <0x0 0x24 0x0>;
+ clocks = <&clk 164>;
+ #thermal-sensor-cells = <0>;
+ amlogic,ao-secure = <&sec_AO>;
+ };
+...
--
2.17.1

View File

@ -0,0 +1,409 @@
From 8af417523f35d2daf7257bc359a8c17632d57435 Mon Sep 17 00:00:00 2001
From: Guillaume La Roque <glaroque@baylibre.com>
Date: Tue, 6 Aug 2019 15:05:02 +0200
Subject: [PATCH 071/186] FROMLIST: thermal: amlogic: Add thermal driver to
support G12 SoCs
Amlogic G12A and G12B SoCs integrate two thermal sensors
with the same design.
One is located close to the DDR controller and the other one is
located close to the PLLs (between the CPU and GPU).
The calibration data for each of the thermal sensors instance is
stored in a different location within the AO region.
Implement reading the temperature from each thermal sensor.
The IP block has more functionality, which may be added to this driver
in the future:
- chip reset when the temperature exceeds a configurable threshold
- up to four interrupts when the temperature has risen above a
configurable threshold
- up to four interrupts when the temperature has fallen below a
configurable threshold
Signed-off-by: Guillaume La Roque <glaroque@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/thermal/Kconfig | 11 +
drivers/thermal/Makefile | 1 +
drivers/thermal/amlogic_thermal.c | 336 ++++++++++++++++++++++++++++++
3 files changed, 348 insertions(+)
create mode 100644 drivers/thermal/amlogic_thermal.c
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 9966364a6deb..0f31bb4bc372 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -348,6 +348,17 @@ config MTK_THERMAL
Enable this option if you want to have support for thermal management
controller present in Mediatek SoCs
+config AMLOGIC_THERMAL
+ tristate "Amlogic Thermal Support"
+ default ARCH_MESON
+ depends on OF && ARCH_MESON
+ help
+ If you say yes here you get support for Amlogic Thermal
+ for G12 SoC Family.
+
+ This driver can also be built as a module. If so, the module will
+ be called amlogic_thermal.
+
menu "Intel thermal drivers"
depends on X86 || X86_INTEL_QUARK || COMPILE_TEST
source "drivers/thermal/intel/Kconfig"
diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile
index 74a37c7f847a..baeb70bf0568 100644
--- a/drivers/thermal/Makefile
+++ b/drivers/thermal/Makefile
@@ -54,3 +54,4 @@ obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o
obj-$(CONFIG_GENERIC_ADC_THERMAL) += thermal-generic-adc.o
obj-$(CONFIG_ZX2967_THERMAL) += zx2967_thermal.o
obj-$(CONFIG_UNIPHIER_THERMAL) += uniphier_thermal.o
+obj-$(CONFIG_AMLOGIC_THERMAL) += amlogic_thermal.o
diff --git a/drivers/thermal/amlogic_thermal.c b/drivers/thermal/amlogic_thermal.c
new file mode 100644
index 000000000000..672d11abd8c7
--- /dev/null
+++ b/drivers/thermal/amlogic_thermal.c
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Amlogic Thermal Sensor Driver
+ *
+ * Copyright (C) 2017 Huan Biao <huan.biao@amlogic.com>
+ * Copyright (C) 2019 Guillaume La Roque <glaroque@baylibre.com>
+ *
+ * Register value to celsius temperature formulas:
+ * Read_Val m * U
+ * U = ---------, Uptat = ---------
+ * 2^16 1 + n * U
+ *
+ * Temperature = A * ( Uptat + u_efuse / 2^16 )- B
+ *
+ * A B m n : calibration parameters
+ * u_efuse : fused calibration value, it's a signed 16 bits value
+ */
+
+#include <linux/bitfield.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/thermal.h>
+
+#include "thermal_core.h"
+
+#define TSENSOR_CFG_REG1 0x4
+ #define TSENSOR_CFG_REG1_RSET_VBG BIT(12)
+ #define TSENSOR_CFG_REG1_RSET_ADC BIT(11)
+ #define TSENSOR_CFG_REG1_VCM_EN BIT(10)
+ #define TSENSOR_CFG_REG1_VBG_EN BIT(9)
+ #define TSENSOR_CFG_REG1_OUT_CTL BIT(6)
+ #define TSENSOR_CFG_REG1_FILTER_EN BIT(5)
+ #define TSENSOR_CFG_REG1_DEM_EN BIT(3)
+ #define TSENSOR_CFG_REG1_CH_SEL GENMASK(1, 0)
+ #define TSENSOR_CFG_REG1_ENABLE \
+ (TSENSOR_CFG_REG1_FILTER_EN | \
+ TSENSOR_CFG_REG1_VCM_EN | \
+ TSENSOR_CFG_REG1_VBG_EN | \
+ TSENSOR_CFG_REG1_DEM_EN | \
+ TSENSOR_CFG_REG1_CH_SEL)
+
+#define TSENSOR_STAT0 0x40
+
+#define TSENSOR_STAT9 0x64
+
+#define TSENSOR_READ_TEMP_MASK GENMASK(15, 0)
+#define TSENSOR_TEMP_MASK GENMASK(11, 0)
+
+#define TSENSOR_TRIM_SIGN_MASK BIT(15)
+#define TSENSOR_TRIM_TEMP_MASK GENMASK(14, 0)
+#define TSENSOR_TRIM_VERSION_MASK GENMASK(31, 24)
+
+#define TSENSOR_TRIM_VERSION(_version) \
+ FIELD_GET(TSENSOR_TRIM_VERSION_MASK, _version)
+
+#define TSENSOR_TRIM_CALIB_VALID_MASK (GENMASK(3, 2) | BIT(7))
+
+#define TSENSOR_CALIB_OFFSET 1
+#define TSENSOR_CALIB_SHIFT 4
+
+/**
+ * struct amlogic_thermal_soc_calib_data
+ * @A, B, m, n: calibration parameters
+ * This structure is required for configuration of amlogic thermal driver.
+ */
+struct amlogic_thermal_soc_calib_data {
+ int A;
+ int B;
+ int m;
+ int n;
+};
+
+/**
+ * struct amlogic_thermal_data
+ * @u_efuse_off: register offset to read fused calibration value
+ * @soc: calibration parameters structure pointer
+ * @regmap_config: regmap config for the device
+ * This structure is required for configuration of amlogic thermal driver.
+ */
+struct amlogic_thermal_data {
+ int u_efuse_off;
+ const struct amlogic_thermal_soc_calib_data *calibration_parameters;
+ const struct regmap_config *regmap_config;
+};
+
+struct amlogic_thermal {
+ struct platform_device *pdev;
+ const struct amlogic_thermal_data *data;
+ struct regmap *regmap;
+ struct regmap *sec_ao_map;
+ struct clk *clk;
+ struct thermal_zone_device *tzd;
+ u32 trim_info;
+ void __iomem *base;
+};
+
+/*
+ * Calculate a temperature value from a temperature code.
+ * The unit of the temperature is degree milliCelsius.
+ */
+static int amlogic_thermal_code_to_millicelsius(struct amlogic_thermal *pdata,
+ int temp_code)
+{
+ const struct amlogic_thermal_soc_calib_data *param =
+ pdata->data->calibration_parameters;
+ int temp;
+ s64 factor, Uptat, uefuse;
+
+ uefuse = pdata->trim_info & TSENSOR_TRIM_SIGN_MASK ?
+ ~(pdata->trim_info & TSENSOR_TRIM_TEMP_MASK) + 1 :
+ (pdata->trim_info & TSENSOR_TRIM_TEMP_MASK);
+
+ factor = param->n * temp_code;
+ factor = div_s64(factor, 100);
+
+ Uptat = temp_code * param->m;
+ Uptat = div_s64(Uptat, 100);
+ Uptat = Uptat * BIT(16);
+ Uptat = div_s64(Uptat, BIT(16) + factor);
+
+ temp = (Uptat + uefuse) * param->A;
+ temp = div_s64(temp, BIT(16));
+ temp = (temp - param->B) * 100;
+
+ return temp;
+}
+
+static int amlogic_thermal_initialize(struct amlogic_thermal *pdata)
+{
+ int ret = 0;
+ int ver;
+
+ regmap_read(pdata->sec_ao_map, pdata->data->u_efuse_off,
+ &pdata->trim_info);
+
+ ver = TSENSOR_TRIM_VERSION(pdata->trim_info);
+
+ if ((ver & TSENSOR_TRIM_CALIB_VALID_MASK) == 0) {
+ ret = -EINVAL;
+ dev_err(&pdata->pdev->dev,
+ "tsensor thermal calibration not supported: 0x%x!\n",
+ ver);
+ }
+
+ return ret;
+}
+
+static int amlogic_thermal_enable(struct amlogic_thermal *data)
+{
+ int ret;
+
+ ret = clk_prepare_enable(data->clk);
+ if (ret)
+ return ret;
+ regmap_update_bits(data->regmap, TSENSOR_CFG_REG1,
+ TSENSOR_CFG_REG1_ENABLE, TSENSOR_CFG_REG1_ENABLE);
+
+ return 0;
+}
+
+static int amlogic_thermal_disable(struct amlogic_thermal *data)
+{
+ regmap_update_bits(data->regmap, TSENSOR_CFG_REG1,
+ TSENSOR_CFG_REG1_ENABLE, 0);
+ clk_disable_unprepare(data->clk);
+
+ return 0;
+}
+
+static int amlogic_thermal_get_temp(void *data, int *temp)
+{
+ unsigned int tval;
+ struct amlogic_thermal *pdata = data;
+
+ if (!data)
+ return -EINVAL;
+
+ regmap_read(pdata->regmap, TSENSOR_STAT0, &tval);
+ *temp =
+ amlogic_thermal_code_to_millicelsius(pdata,
+ tval & TSENSOR_READ_TEMP_MASK);
+
+ return 0;
+}
+
+static const struct thermal_zone_of_device_ops amlogic_thermal_ops = {
+ .get_temp = amlogic_thermal_get_temp,
+};
+
+static const struct regmap_config amlogic_thermal_regmap_config_g12 = {
+ .reg_bits = 8,
+ .val_bits = 32,
+ .reg_stride = 4,
+ .max_register = TSENSOR_STAT9,
+};
+
+static const struct amlogic_thermal_soc_calib_data amlogic_thermal_g12 = {
+ .A = 9411,
+ .B = 3159,
+ .m = 424,
+ .n = 324,
+};
+
+static const struct amlogic_thermal_data amlogic_thermal_g12_cpu_param = {
+ .u_efuse_off = 0x128,
+ .calibration_parameters = &amlogic_thermal_g12,
+ .regmap_config = &amlogic_thermal_regmap_config_g12,
+};
+
+static const struct amlogic_thermal_data amlogic_thermal_g12_ddr_param = {
+ .u_efuse_off = 0xf0,
+ .calibration_parameters = &amlogic_thermal_g12,
+ .regmap_config = &amlogic_thermal_regmap_config_g12,
+};
+
+static const struct of_device_id of_amlogic_thermal_match[] = {
+ {
+ .compatible = "amlogic,g12-ddr-thermal",
+ .data = &amlogic_thermal_g12_ddr_param,
+ },
+ {
+ .compatible = "amlogic,g12-cpu-thermal",
+ .data = &amlogic_thermal_g12_cpu_param,
+ },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, of_amlogic_thermal_match);
+
+static int amlogic_thermal_probe(struct platform_device *pdev)
+{
+ struct amlogic_thermal *pdata;
+ struct device *dev = &pdev->dev;
+ struct resource *res;
+ int ret;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdata->data = of_device_get_match_data(dev);
+ pdata->pdev = pdev;
+ platform_set_drvdata(pdev, pdata);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ pdata->base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(pdata->base)) {
+ dev_err(dev, "failed to get io address\n");
+ return PTR_ERR(pdata->base);
+ }
+
+ pdata->regmap = devm_regmap_init_mmio(dev, pdata->base,
+ pdata->data->regmap_config);
+ if (IS_ERR(pdata->regmap))
+ return PTR_ERR(pdata->regmap);
+
+ pdata->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(pdata->clk)) {
+ if (PTR_ERR(pdata->clk) != -EPROBE_DEFER)
+ dev_err(dev, "failed to get clock\n");
+ return PTR_ERR(pdata->clk);
+ }
+
+ pdata->sec_ao_map = syscon_regmap_lookup_by_phandle
+ (pdev->dev.of_node, "amlogic,ao-secure");
+ if (IS_ERR(pdata->sec_ao_map)) {
+ dev_err(dev, "syscon regmap lookup failed.\n");
+ return PTR_ERR(pdata->sec_ao_map);
+ }
+
+ pdata->tzd = devm_thermal_zone_of_sensor_register(&pdev->dev,
+ 0,
+ pdata,
+ &amlogic_thermal_ops);
+ if (IS_ERR(pdata->tzd)) {
+ ret = PTR_ERR(pdata->tzd);
+ dev_err(dev, "Failed to register tsensor: %d\n", ret);
+ return PTR_ERR(pdata->tzd);
+ }
+
+ ret = amlogic_thermal_initialize(pdata);
+ if (ret)
+ return ret;
+
+ ret = amlogic_thermal_enable(pdata);
+ if (ret)
+ clk_disable_unprepare(pdata->clk);
+
+ return ret;
+}
+
+static int amlogic_thermal_remove(struct platform_device *pdev)
+{
+ struct amlogic_thermal *data = platform_get_drvdata(pdev);
+
+ return amlogic_thermal_disable(data);
+}
+
+static int __maybe_unused amlogic_thermal_suspend(struct device *dev)
+{
+ struct amlogic_thermal *data = dev_get_drvdata(dev);
+
+ return amlogic_thermal_disable(data);
+}
+
+static int __maybe_unused amlogic_thermal_resume(struct device *dev)
+{
+ struct amlogic_thermal *data = dev_get_drvdata(dev);
+
+ return amlogic_thermal_enable(data);
+}
+
+static SIMPLE_DEV_PM_OPS(amlogic_thermal_pm_ops,
+ amlogic_thermal_suspend, amlogic_thermal_resume);
+
+static struct platform_driver amlogic_thermal_driver = {
+ .driver = {
+ .name = "amlogic_thermal",
+ .pm = &amlogic_thermal_pm_ops,
+ .of_match_table = of_amlogic_thermal_match,
+ },
+ .probe = amlogic_thermal_probe,
+ .remove = amlogic_thermal_remove,
+};
+
+module_platform_driver(amlogic_thermal_driver);
+
+MODULE_AUTHOR("Guillaume La Roque <glaroque@baylibre.com>");
+MODULE_DESCRIPTION("Amlogic thermal driver");
+MODULE_LICENSE("GPL v2");
--
2.17.1

View File

@ -0,0 +1,49 @@
From 48ec22b37703479b32535f7f3e5f070e7a9827fb Mon Sep 17 00:00:00 2001
From: Guillaume La Roque <glaroque@baylibre.com>
Date: Tue, 6 Aug 2019 15:05:03 +0200
Subject: [PATCH 072/186] FROMLIST: arm64: dts: amlogic: g12: add temperature
sensor
Add cpu and ddr temperature sensors for G12 Socs
Signed-off-by: Guillaume La Roque <glaroque@baylibre.com>
Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../boot/dts/amlogic/meson-g12-common.dtsi | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 27bb242dc95d..71fd725dee77 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1355,6 +1355,26 @@
};
};
+ cpu_temp: temperature-sensor@34800 {
+ compatible = "amlogic,g12-cpu-thermal",
+ "amlogic,g12-thermal";
+ reg = <0x0 0x34800 0x0 0x50>;
+ interrupts = <GIC_SPI 35 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_TS>;
+ #thermal-sensor-cells = <0>;
+ amlogic,ao-secure = <&sec_AO>;
+ };
+
+ ddr_temp: temperature-sensor@34c00 {
+ compatible = "amlogic,g12-ddr-thermal",
+ "amlogic,g12-thermal";
+ reg = <0x0 0x34c00 0x0 0x50>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_EDGE_RISING>;
+ clocks = <&clkc CLKID_TS>;
+ #thermal-sensor-cells = <0>;
+ amlogic,ao-secure = <&sec_AO>;
+ };
+
usb2_phy0: phy@36000 {
compatible = "amlogic,g12a-usb2-phy";
reg = <0x0 0x36000 0x0 0x2000>;
--
2.17.1

View File

@ -0,0 +1,129 @@
From 25a2ca2aea891043b109daf66e8d7db60f3a2d1c Mon Sep 17 00:00:00 2001
From: Guillaume La Roque <glaroque@baylibre.com>
Date: Tue, 6 Aug 2019 15:05:04 +0200
Subject: [PATCH 073/186] FROMLIST: arm64: dts: meson: sei510: Add minimal
thermal zone
Add minimal thermal zone for two temperature sensor
One is located close to the DDR and the other one is
located close to the PLLs (between the CPU and GPU)
Signed-off-by: Guillaume La Roque <glaroque@baylibre.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../boot/dts/amlogic/meson-g12a-sei510.dts | 56 +++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
index c9fa23a56562..3e8621d7e6a5 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12a-sei510.dts
@@ -10,6 +10,7 @@
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>
#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
compatible = "seirobotics,sei510", "amlogic,g12a";
@@ -33,6 +34,53 @@
ethernet0 = &ethmac;
};
+ thermal-zones {
+ cpu-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <100>;
+ thermal-sensors = <&cpu_temp>;
+
+ trips {
+ cpu_critical: cpu-critical {
+ temperature = <110000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map {
+ trip = <&cpu_critical>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ ddr-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <100>;
+ thermal-sensors = <&ddr_temp>;
+
+ trips {
+ ddr_critical: ddr-critical {
+ temperature = <110000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map {
+ trip = <&ddr_critical>;
+ cooling-device = <&mali THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
mono_dac: audio-codec-0 {
compatible = "maxim,max98357a";
#sound-dai-cells = <0>;
@@ -321,6 +369,7 @@
operating-points-v2 = <&cpu_opp_table>;
clocks = <&clkc CLKID_CPU_CLK>;
clock-latency = <50000>;
+ #cooling-cells = <2>;
};
&cpu1 {
@@ -328,6 +377,7 @@
operating-points-v2 = <&cpu_opp_table>;
clocks = <&clkc CLKID_CPU_CLK>;
clock-latency = <50000>;
+ #cooling-cells = <2>;
};
&cpu2 {
@@ -335,6 +385,7 @@
operating-points-v2 = <&cpu_opp_table>;
clocks = <&clkc CLKID_CPU_CLK>;
clock-latency = <50000>;
+ #cooling-cells = <2>;
};
&cpu3 {
@@ -342,6 +393,7 @@
operating-points-v2 = <&cpu_opp_table>;
clocks = <&clkc CLKID_CPU_CLK>;
clock-latency = <50000>;
+ #cooling-cells = <2>;
};
&cvbs_vdac_port {
@@ -368,6 +420,10 @@
status = "okay";
};
+&mali {
+ #cooling-cells = <2>;
+};
+
&hdmi_tx {
status = "okay";
pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
--
2.17.1

View File

@ -0,0 +1,147 @@
From d7ae633f93a5fd454fbbf87b535873f6cd4227a4 Mon Sep 17 00:00:00 2001
From: Guillaume La Roque <glaroque@baylibre.com>
Date: Tue, 6 Aug 2019 15:05:05 +0200
Subject: [PATCH 074/186] FROMLIST: arm64: dts: amlogic: odroid-n2: add minimal
thermal zone
Add minimal thermal zone for two temperature sensor
One is located close to the DDR and the other one is
located close to the PLLs (between the CPU and GPU)
Signed-off-by: Guillaume La Roque <glaroque@baylibre.com>
Acked-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../boot/dts/amlogic/meson-g12b-odroid-n2.dts | 60 +++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
index 6cfc2c69bb4f..57c84aa9890c 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dts
@@ -10,6 +10,7 @@
#include <dt-bindings/input/input.h>
#include <dt-bindings/gpio/meson-g12a-gpio.h>
#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+#include <dt-bindings/thermal/thermal.h>
/ {
compatible = "hardkernel,odroid-n2", "amlogic,g12b";
@@ -20,6 +21,55 @@
ethernet0 = &ethmac;
};
+ thermal-zones {
+ cpu-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <100>;
+ thermal-sensors = <&cpu_temp>;
+
+ trips {
+ cpu_critical: cpu-critical {
+ temperature = <110000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map {
+ trip = <&cpu_critical>;
+ cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu100 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu101 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu102 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+ <&cpu103 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+
+ ddr-thermal {
+ polling-delay = <1000>;
+ polling-delay-passive = <100>;
+ thermal-sensors = <&ddr_temp>;
+
+ trips {
+ ddr_critical: ddr-critical {
+ temperature = <110000>; /* millicelsius */
+ hysteresis = <2000>; /* millicelsius */
+ type = "critical";
+ };
+ };
+
+ cooling-maps {
+ map {
+ trip = <&ddr_critical>;
+ cooling-device = <&mali THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+ };
+ };
+ };
+ };
+
chosen {
stdout-path = "serial0:115200n8";
};
@@ -289,6 +339,7 @@
operating-points-v2 = <&cpu_opp_table_0>;
clocks = <&clkc CLKID_CPU_CLK>;
clock-latency = <50000>;
+ #cooling-cells = <2>;
};
&cpu1 {
@@ -296,6 +347,7 @@
operating-points-v2 = <&cpu_opp_table_0>;
clocks = <&clkc CLKID_CPU_CLK>;
clock-latency = <50000>;
+ #cooling-cells = <2>;
};
&cpu100 {
@@ -303,6 +355,7 @@
operating-points-v2 = <&cpub_opp_table_1>;
clocks = <&clkc CLKID_CPUB_CLK>;
clock-latency = <50000>;
+ #cooling-cells = <2>;
};
&cpu101 {
@@ -310,6 +363,7 @@
operating-points-v2 = <&cpub_opp_table_1>;
clocks = <&clkc CLKID_CPUB_CLK>;
clock-latency = <50000>;
+ #cooling-cells = <2>;
};
&cpu102 {
@@ -317,6 +371,7 @@
operating-points-v2 = <&cpub_opp_table_1>;
clocks = <&clkc CLKID_CPUB_CLK>;
clock-latency = <50000>;
+ #cooling-cells = <2>;
};
&cpu103 {
@@ -324,6 +379,7 @@
operating-points-v2 = <&cpub_opp_table_1>;
clocks = <&clkc CLKID_CPUB_CLK>;
clock-latency = <50000>;
+ #cooling-cells = <2>;
};
&ext_mdio {
@@ -378,6 +434,10 @@
};
};
+&mali {
+ #cooling-cells = <2>;
+};
+
&hdmi_tx {
status = "okay";
pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
--
2.17.1

View File

@ -0,0 +1,38 @@
From 5bb34848ae192c1329f5c691e6ccb012cdbe68ff Mon Sep 17 00:00:00 2001
From: Guillaume La Roque <glaroque@baylibre.com>
Date: Tue, 6 Aug 2019 15:05:06 +0200
Subject: [PATCH 075/186] FROMLIST: MAINTAINERS: add entry for Amlogic Thermal
driver
Add myself as maintainer for Amlogic Thermal driver.
Signed-off-by: Guillaume La Roque <glaroque@baylibre.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
MAINTAINERS | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index e7a47b5210fd..adb7eeb9b729 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15940,6 +15940,15 @@ F: Documentation/thermal/cpu-cooling-api.rst
F: drivers/thermal/cpu_cooling.c
F: include/linux/cpu_cooling.h
+THERMAL DRIVER FOR AMLOGIC SOCS
+M: Guillaume La Roque <glaroque@baylibre.com>
+L: linux-pm@vger.kernel.org
+L: linux-amlogic@lists.infradead.org
+W: http://linux-meson.com/
+S: Supported
+F: drivers/thermal/amlogic_thermal.c
+F: Documentation/devicetree/bindings/thermal/amlogic,thermal.yaml
+
THINKPAD ACPI EXTRAS DRIVER
M: Henrique de Moraes Holschuh <ibm-acpi@hmh.eng.br>
L: ibm-acpi-devel@lists.sourceforge.net
--
2.17.1

View File

@ -0,0 +1,82 @@
From 69139a81478c0a67920362a180a199914581f327 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 12 Aug 2019 14:07:19 +0200
Subject: [PATCH 076/186] FROMLIST: drm/bridge: dw-hdmi-i2s: support more i2s
format
The dw-hdmi-i2s supports more formats than just regular i2s.
Add support for left justified, right justified and dsp modes
A and B.
Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 26 ++++++++++++++++---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 6 +++--
2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index 5cbb71a866d5..2b624cff541d 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -44,9 +44,8 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
u8 inputclkfs = 0;
/* it cares I2S only */
- if ((fmt->fmt != HDMI_I2S) ||
- (fmt->bit_clk_master | fmt->frame_clk_master)) {
- dev_err(dev, "unsupported format/settings\n");
+ if (fmt->bit_clk_master | fmt->frame_clk_master) {
+ dev_err(dev, "unsupported clock settings\n");
return -EINVAL;
}
@@ -63,6 +62,27 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
break;
}
+ switch (fmt->fmt) {
+ case HDMI_I2S:
+ conf1 |= HDMI_AUD_CONF1_MODE_I2S;
+ break;
+ case HDMI_RIGHT_J:
+ conf1 |= HDMI_AUD_CONF1_MODE_RIGHT_J;
+ break;
+ case HDMI_LEFT_J:
+ conf1 |= HDMI_AUD_CONF1_MODE_LEFT_J;
+ break;
+ case HDMI_DSP_A:
+ conf1 |= HDMI_AUD_CONF1_MODE_BURST_1;
+ break;
+ case HDMI_DSP_B:
+ conf1 |= HDMI_AUD_CONF1_MODE_BURST_2;
+ break;
+ default:
+ dev_err(dev, "unsupported format\n");
+ return -EINVAL;
+ }
+
dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
hdmi_write(audio, inputclkfs, HDMI_AUD_INPUTCLKFS);
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index 4e3ec09d3ca4..091d7c28aa17 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -869,8 +869,10 @@ enum {
/* AUD_CONF1 field values */
HDMI_AUD_CONF1_MODE_I2S = 0x00,
- HDMI_AUD_CONF1_MODE_RIGHT_J = 0x02,
- HDMI_AUD_CONF1_MODE_LEFT_J = 0x04,
+ HDMI_AUD_CONF1_MODE_RIGHT_J = 0x20,
+ HDMI_AUD_CONF1_MODE_LEFT_J = 0x40,
+ HDMI_AUD_CONF1_MODE_BURST_1 = 0x60,
+ HDMI_AUD_CONF1_MODE_BURST_2 = 0x80,
HDMI_AUD_CONF1_WIDTH_16 = 0x10,
HDMI_AUD_CONF1_WIDTH_24 = 0x18,
--
2.17.1

View File

@ -0,0 +1,127 @@
From 36c54e6514ce3d07f4467b8ed6ccf67772008abc Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 12 Aug 2019 14:07:20 +0200
Subject: [PATCH 077/186] FROMLIST: drm/bridge: dw-hdmi: move audio channel
setup out of ahb
Part of the channel count setup done in dw-hdmi ahb should
actually be done whatever the interface providing the data.
Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
Let's move it to dw-hdmi driver instead.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../drm/bridge/synopsys/dw-hdmi-ahb-audio.c | 20 +++---------
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 32 +++++++++++++++++++
include/drm/bridge/dw_hdmi.h | 2 ++
3 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
index a494186ae6ce..2b7539701b42 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c
@@ -63,10 +63,6 @@ enum {
HDMI_REVISION_ID = 0x0001,
HDMI_IH_AHBDMAAUD_STAT0 = 0x0109,
HDMI_IH_MUTE_AHBDMAAUD_STAT0 = 0x0189,
- HDMI_FC_AUDICONF2 = 0x1027,
- HDMI_FC_AUDSCONF = 0x1063,
- HDMI_FC_AUDSCONF_LAYOUT1 = 1 << 0,
- HDMI_FC_AUDSCONF_LAYOUT0 = 0 << 0,
HDMI_AHB_DMA_CONF0 = 0x3600,
HDMI_AHB_DMA_START = 0x3601,
HDMI_AHB_DMA_STOP = 0x3602,
@@ -403,7 +399,7 @@ static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_dw_hdmi *dw = substream->private_data;
- u8 threshold, conf0, conf1, layout, ca;
+ u8 threshold, conf0, conf1, ca;
/* Setup as per 3.0.5 FSL 4.1.0 BSP */
switch (dw->revision) {
@@ -434,20 +430,12 @@ static int dw_hdmi_prepare(struct snd_pcm_substream *substream)
conf1 = default_hdmi_channel_config[runtime->channels - 2].conf1;
ca = default_hdmi_channel_config[runtime->channels - 2].ca;
- /*
- * For >2 channel PCM audio, we need to select layout 1
- * and set an appropriate channel map.
- */
- if (runtime->channels > 2)
- layout = HDMI_FC_AUDSCONF_LAYOUT1;
- else
- layout = HDMI_FC_AUDSCONF_LAYOUT0;
-
writeb_relaxed(threshold, dw->data.base + HDMI_AHB_DMA_THRSLD);
writeb_relaxed(conf0, dw->data.base + HDMI_AHB_DMA_CONF0);
writeb_relaxed(conf1, dw->data.base + HDMI_AHB_DMA_CONF1);
- writeb_relaxed(layout, dw->data.base + HDMI_FC_AUDSCONF);
- writeb_relaxed(ca, dw->data.base + HDMI_FC_AUDICONF2);
+
+ dw_hdmi_set_channel_count(dw->data.hdmi, runtime->channels);
+ dw_hdmi_set_channel_allocation(dw->data.hdmi, ca);
switch (runtime->format) {
case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index 218a7b2308f7..be6d6819bef4 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -645,6 +645,38 @@ void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate)
}
EXPORT_SYMBOL_GPL(dw_hdmi_set_sample_rate);
+void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt)
+{
+ u8 layout;
+
+ mutex_lock(&hdmi->audio_mutex);
+
+ /*
+ * For >2 channel PCM audio, we need to select layout 1
+ * and set an appropriate channel map.
+ */
+ if (cnt > 2)
+ layout = HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT1;
+ else
+ layout = HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_LAYOUT0;
+
+ hdmi_modb(hdmi, layout, HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK,
+ HDMI_FC_AUDSCONF);
+
+ mutex_unlock(&hdmi->audio_mutex);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_set_channel_count);
+
+void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca)
+{
+ mutex_lock(&hdmi->audio_mutex);
+
+ hdmi_writeb(hdmi, ca, HDMI_FC_AUDICONF2);
+
+ mutex_unlock(&hdmi->audio_mutex);
+}
+EXPORT_SYMBOL_GPL(dw_hdmi_set_channel_allocation);
+
static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable)
{
if (enable)
diff --git a/include/drm/bridge/dw_hdmi.h b/include/drm/bridge/dw_hdmi.h
index c402364aec0d..cf528c289857 100644
--- a/include/drm/bridge/dw_hdmi.h
+++ b/include/drm/bridge/dw_hdmi.h
@@ -155,6 +155,8 @@ void dw_hdmi_resume(struct dw_hdmi *hdmi);
void dw_hdmi_setup_rx_sense(struct dw_hdmi *hdmi, bool hpd, bool rx_sense);
void dw_hdmi_set_sample_rate(struct dw_hdmi *hdmi, unsigned int rate);
+void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt);
+void dw_hdmi_set_channel_allocation(struct dw_hdmi *hdmi, unsigned int ca);
void dw_hdmi_audio_enable(struct dw_hdmi *hdmi);
void dw_hdmi_audio_disable(struct dw_hdmi *hdmi);
void dw_hdmi_set_high_tmds_clock_ratio(struct dw_hdmi *hdmi);
--
2.17.1

View File

@ -0,0 +1,33 @@
From 40caa46c4072b291ce35afff7fc7db1d84b6e5ac Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 12 Aug 2019 14:07:21 +0200
Subject: [PATCH 078/186] FROMLIST: drm/bridge: dw-hdmi: set channel count in
the infoframes
Set the number of channel in the infoframes
Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index be6d6819bef4..bed4bb017afd 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -663,6 +663,10 @@ void dw_hdmi_set_channel_count(struct dw_hdmi *hdmi, unsigned int cnt)
hdmi_modb(hdmi, layout, HDMI_FC_AUDSCONF_AUD_PACKET_LAYOUT_MASK,
HDMI_FC_AUDSCONF);
+ /* Set the audio infoframes channel count */
+ hdmi_modb(hdmi, (cnt - 1) << HDMI_FC_AUDICONF0_CC_OFFSET,
+ HDMI_FC_AUDICONF0_CC_MASK, HDMI_FC_AUDICONF0);
+
mutex_unlock(&hdmi->audio_mutex);
}
EXPORT_SYMBOL_GPL(dw_hdmi_set_channel_count);
--
2.17.1

View File

@ -0,0 +1,42 @@
From cdf38f445651140aefa232d9bc6e62462d04c530 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 12 Aug 2019 14:07:22 +0200
Subject: [PATCH 079/186] FROMLIST: drm/bridge: dw-hdmi-i2s: enable lpcm multi
channels
Properly setup the channel count and layout in dw-hdmi i2s driver so
we are not limited to 2 channels.
Also correct the maximum channel reported by the DAI from 6 to 8 ch
Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index 2b624cff541d..caf8aed78fea 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -84,6 +84,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
}
dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
+ dw_hdmi_set_channel_count(hdmi, hparms->channels);
hdmi_write(audio, inputclkfs, HDMI_AUD_INPUTCLKFS);
hdmi_write(audio, conf0, HDMI_AUD_CONF0);
@@ -139,7 +140,7 @@ static int snd_dw_hdmi_probe(struct platform_device *pdev)
pdata.ops = &dw_hdmi_i2s_ops;
pdata.i2s = 1;
- pdata.max_i2s_channels = 6;
+ pdata.max_i2s_channels = 8;
pdata.data = audio;
memset(&pdevinfo, 0, sizeof(pdevinfo));
--
2.17.1

View File

@ -0,0 +1,30 @@
From 3c3dce088cacdfb13d2289a6fc18fd7cb3884216 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 12 Aug 2019 14:07:23 +0200
Subject: [PATCH 080/186] FROMLIST: drm/bridge: dw-hdmi-i2s: set the channel
allocation
setup the channel allocation provided by the generic hdmi-codec driver
Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index caf8aed78fea..0864dee8d180 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -85,6 +85,7 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
dw_hdmi_set_sample_rate(hdmi, hparms->sample_rate);
dw_hdmi_set_channel_count(hdmi, hparms->channels);
+ dw_hdmi_set_channel_allocation(hdmi, hparms->cea.channel_allocation);
hdmi_write(audio, inputclkfs, HDMI_AUD_INPUTCLKFS);
hdmi_write(audio, conf0, HDMI_AUD_CONF0);
--
2.17.1

View File

@ -0,0 +1,59 @@
From 8e0e3d1efdc1f7125d3c4b7cf4815045809744a1 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 12 Aug 2019 14:07:24 +0200
Subject: [PATCH 081/186] FROMLIST: drm/bridge: dw-hdmi-i2s: reset audio fifo
before applying new params
When changing the audio hw params, reset the audio fifo to make sure
any old remaining data is flushed.
The databook mentions that such reset should be followed by a reset of
the i2s block to make sure the samples stay aligned
Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 6 ++++--
drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 1 +
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index 0864dee8d180..41bee0099578 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -49,6 +49,10 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
return -EINVAL;
}
+ /* Reset the FIFOs before applying new params */
+ hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0);
+ hdmi_write(audio, (u8)~HDMI_MC_SWRSTZ_I2SSWRST_REQ, HDMI_MC_SWRSTZ);
+
inputclkfs = HDMI_AUD_INPUTCLKFS_64FS;
conf0 = HDMI_AUD_CONF0_I2S_ALL_ENABLE;
@@ -102,8 +106,6 @@ static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data)
struct dw_hdmi *hdmi = audio->hdmi;
dw_hdmi_audio_disable(hdmi);
-
- hdmi_write(audio, HDMI_AUD_CONF0_SW_RESET, HDMI_AUD_CONF0);
}
static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index 091d7c28aa17..a272fa393ae6 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -940,6 +940,7 @@ enum {
HDMI_MC_CLKDIS_PIXELCLK_DISABLE = 0x1,
/* MC_SWRSTZ field values */
+ HDMI_MC_SWRSTZ_I2SSWRST_REQ = 0x08,
HDMI_MC_SWRSTZ_TMDSSWRST_REQ = 0x02,
/* MC_FLOWCTRL field values */
--
2.17.1

View File

@ -0,0 +1,62 @@
From 4008c7774115d2d69157b461a4940dddeb0bad19 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 12 Aug 2019 14:07:25 +0200
Subject: [PATCH 082/186] FROMLIST: drm/bridge: dw-hdmi-i2s: enable only the
required i2s lanes
Enable the i2s lanes depending on the number of channel in the stream
Reviewed-by: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 15 ++++++++++++++-
drivers/gpu/drm/bridge/synopsys/dw-hdmi.h | 6 +++++-
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index 41bee0099578..b8ece9c1ba2c 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -54,7 +54,20 @@ static int dw_hdmi_i2s_hw_params(struct device *dev, void *data,
hdmi_write(audio, (u8)~HDMI_MC_SWRSTZ_I2SSWRST_REQ, HDMI_MC_SWRSTZ);
inputclkfs = HDMI_AUD_INPUTCLKFS_64FS;
- conf0 = HDMI_AUD_CONF0_I2S_ALL_ENABLE;
+ conf0 = (HDMI_AUD_CONF0_I2S_SELECT | HDMI_AUD_CONF0_I2S_EN0);
+
+ /* Enable the required i2s lanes */
+ switch (hparms->channels) {
+ case 7 ... 8:
+ conf0 |= HDMI_AUD_CONF0_I2S_EN3;
+ /* Fall-thru */
+ case 5 ... 6:
+ conf0 |= HDMI_AUD_CONF0_I2S_EN2;
+ /* Fall-thru */
+ case 3 ... 4:
+ conf0 |= HDMI_AUD_CONF0_I2S_EN1;
+ /* Fall-thru */
+ }
switch (hparms->sample_width) {
case 16:
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
index a272fa393ae6..6988f12d89d9 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
@@ -865,7 +865,11 @@ enum {
/* AUD_CONF0 field values */
HDMI_AUD_CONF0_SW_RESET = 0x80,
- HDMI_AUD_CONF0_I2S_ALL_ENABLE = 0x2F,
+ HDMI_AUD_CONF0_I2S_SELECT = 0x20,
+ HDMI_AUD_CONF0_I2S_EN3 = 0x08,
+ HDMI_AUD_CONF0_I2S_EN2 = 0x04,
+ HDMI_AUD_CONF0_I2S_EN1 = 0x02,
+ HDMI_AUD_CONF0_I2S_EN0 = 0x01,
/* AUD_CONF1 field values */
HDMI_AUD_CONF1_MODE_I2S = 0x00,
--
2.17.1

View File

@ -0,0 +1,82 @@
From e59971a100c3c6feb1f2bf186dc04fd6793c1a8c Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 12 Aug 2019 14:07:26 +0200
Subject: [PATCH 083/186] FROMLIST: drm/bridge: dw-hdmi-i2s: add .get_eld
support
Provide the eld to the generic hdmi-codec driver.
This will let the driver enforce the maximum channel number and set the
channel allocation depending on the hdmi sink.
Cc: Jonas Karlman <jonas@kwiboo.se>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h | 1 +
drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c | 11 +++++++++++
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 1 +
3 files changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
index 63b5756f463b..cb07dc0da5a7 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h
@@ -14,6 +14,7 @@ struct dw_hdmi_audio_data {
struct dw_hdmi_i2s_audio_data {
struct dw_hdmi *hdmi;
+ u8 *eld;
void (*write)(struct dw_hdmi *hdmi, u8 val, int offset);
u8 (*read)(struct dw_hdmi *hdmi, int offset);
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
index b8ece9c1ba2c..1d15cf9b6821 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <drm/bridge/dw_hdmi.h>
+#include <drm/drm_crtc.h>
#include <sound/hdmi-codec.h>
@@ -121,6 +122,15 @@ static void dw_hdmi_i2s_audio_shutdown(struct device *dev, void *data)
dw_hdmi_audio_disable(hdmi);
}
+static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, uint8_t *buf,
+ size_t len)
+{
+ struct dw_hdmi_i2s_audio_data *audio = data;
+
+ memcpy(buf, audio->eld, min_t(size_t, MAX_ELD_BYTES, len));
+ return 0;
+}
+
static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
struct device_node *endpoint)
{
@@ -144,6 +154,7 @@ static int dw_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
static struct hdmi_codec_ops dw_hdmi_i2s_ops = {
.hw_params = dw_hdmi_i2s_hw_params,
.audio_shutdown = dw_hdmi_i2s_audio_shutdown,
+ .get_eld = dw_hdmi_i2s_get_eld,
.get_dai_id = dw_hdmi_i2s_get_dai_id,
};
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
index bed4bb017afd..8df69c9dbfad 100644
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
@@ -2797,6 +2797,7 @@ __dw_hdmi_probe(struct platform_device *pdev,
struct dw_hdmi_i2s_audio_data audio;
audio.hdmi = hdmi;
+ audio.eld = hdmi->connector.eld;
audio.write = hdmi_writeb;
audio.read = hdmi_readb;
hdmi->enable_audio = dw_hdmi_i2s_audio_enable;
--
2.17.1

View File

@ -0,0 +1,76 @@
From 1bb749f7d0c17cf6bc7b2a9c3dcfb718013ee6b2 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 12 Aug 2019 14:32:52 +0200
Subject: [PATCH 084/186] FROMLIST: dt-bindings: clock: meson: add resets to
the audio clock controller
Add the documentation and bindings for the resets provided by the g12a
audio clock controller
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
.../bindings/clock/amlogic,axg-audio-clkc.txt | 1 +
.../reset/amlogic,meson-g12a-audio-reset.h | 38 +++++++++++++++++++
2 files changed, 39 insertions(+)
create mode 100644 include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h
diff --git a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt
index 0f777749f4f1..b3957d10d241 100644
--- a/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt
+++ b/Documentation/devicetree/bindings/clock/amlogic,axg-audio-clkc.txt
@@ -22,6 +22,7 @@ Required Properties:
components.
- resets : phandle of the internal reset line
- #clock-cells : should be 1.
+- #reset-cells : should be 1 on the g12a (and following) soc family
Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. All available clocks are defined as
diff --git a/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h b/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h
new file mode 100644
index 000000000000..14b78dabed0e
--- /dev/null
+++ b/include/dt-bindings/reset/amlogic,meson-g12a-audio-reset.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 BayLibre, SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ *
+ */
+
+#ifndef _DT_BINDINGS_AMLOGIC_MESON_G12A_AUDIO_RESET_H
+#define _DT_BINDINGS_AMLOGIC_MESON_G12A_AUDIO_RESET_H
+
+#define AUD_RESET_PDM 0
+#define AUD_RESET_TDMIN_A 1
+#define AUD_RESET_TDMIN_B 2
+#define AUD_RESET_TDMIN_C 3
+#define AUD_RESET_TDMIN_LB 4
+#define AUD_RESET_LOOPBACK 5
+#define AUD_RESET_TODDR_A 6
+#define AUD_RESET_TODDR_B 7
+#define AUD_RESET_TODDR_C 8
+#define AUD_RESET_FRDDR_A 9
+#define AUD_RESET_FRDDR_B 10
+#define AUD_RESET_FRDDR_C 11
+#define AUD_RESET_TDMOUT_A 12
+#define AUD_RESET_TDMOUT_B 13
+#define AUD_RESET_TDMOUT_C 14
+#define AUD_RESET_SPDIFOUT 15
+#define AUD_RESET_SPDIFOUT_B 16
+#define AUD_RESET_SPDIFIN 17
+#define AUD_RESET_EQDRC 18
+#define AUD_RESET_RESAMPLE 19
+#define AUD_RESET_DDRARB 20
+#define AUD_RESET_POWDET 21
+#define AUD_RESET_TORAM 22
+#define AUD_RESET_TOACODEC 23
+#define AUD_RESET_TOHDMITX 24
+#define AUD_RESET_CLKTREE 25
+
+#endif
--
2.17.1

View File

@ -0,0 +1,186 @@
From 39e69725d2cdf25c54fbeff6751d324efe1158d8 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 12 Aug 2019 14:32:53 +0200
Subject: [PATCH 085/186] FROMLIST: clk: meson: axg-audio: add g12a reset
support
On the g12a, the register space dedicated to the audio clock also
provides some resets. Let the clock controller register a reset
provider as well for this SoC family.
the axg SoC family does not appear to provide this feature.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
drivers/clk/meson/axg-audio.c | 107 +++++++++++++++++++++++++++++++++-
drivers/clk/meson/axg-audio.h | 1 +
2 files changed, 106 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/meson/axg-audio.c b/drivers/clk/meson/axg-audio.c
index 741df7e955ca..6be9df1efce5 100644
--- a/drivers/clk/meson/axg-audio.c
+++ b/drivers/clk/meson/axg-audio.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+#include <linux/reset-controller.h>
#include <linux/slab.h>
#include "axg-audio.h"
@@ -918,6 +919,84 @@ static int devm_clk_get_enable(struct device *dev, char *id)
return 0;
}
+struct axg_audio_reset_data {
+ struct reset_controller_dev rstc;
+ struct regmap *map;
+ unsigned int offset;
+};
+
+static void axg_audio_reset_reg_and_bit(struct axg_audio_reset_data *rst,
+ unsigned long id,
+ unsigned int *reg,
+ unsigned int *bit)
+{
+ unsigned int stride = regmap_get_reg_stride(rst->map);
+
+ *reg = (id / (stride * BITS_PER_BYTE)) * stride;
+ *reg += rst->offset;
+ *bit = id % (stride * BITS_PER_BYTE);
+}
+
+static int axg_audio_reset_update(struct reset_controller_dev *rcdev,
+ unsigned long id, bool assert)
+{
+ struct axg_audio_reset_data *rst =
+ container_of(rcdev, struct axg_audio_reset_data, rstc);
+ unsigned int offset, bit;
+
+ axg_audio_reset_reg_and_bit(rst, id, &offset, &bit);
+
+ regmap_update_bits(rst->map, offset, BIT(bit),
+ assert ? BIT(bit) : 0);
+
+ return 0;
+}
+
+static int axg_audio_reset_status(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ struct axg_audio_reset_data *rst =
+ container_of(rcdev, struct axg_audio_reset_data, rstc);
+ unsigned int val, offset, bit;
+
+ axg_audio_reset_reg_and_bit(rst, id, &offset, &bit);
+
+ regmap_read(rst->map, offset, &val);
+
+ return !!(val & BIT(bit));
+}
+
+static int axg_audio_reset_assert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return axg_audio_reset_update(rcdev, id, true);
+}
+
+static int axg_audio_reset_deassert(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ return axg_audio_reset_update(rcdev, id, false);
+}
+
+static int axg_audio_reset_toggle(struct reset_controller_dev *rcdev,
+ unsigned long id)
+{
+ int ret;
+
+ ret = axg_audio_reset_assert(rcdev, id);
+ if (ret)
+ return ret;
+
+ return axg_audio_reset_deassert(rcdev, id);
+}
+
+static const struct reset_control_ops axg_audio_rstc_ops = {
+ .assert = axg_audio_reset_assert,
+ .deassert = axg_audio_reset_deassert,
+ .reset = axg_audio_reset_toggle,
+ .status = axg_audio_reset_status,
+};
+
static const struct regmap_config axg_audio_regmap_cfg = {
.reg_bits = 32,
.val_bits = 32,
@@ -927,12 +1006,15 @@ static const struct regmap_config axg_audio_regmap_cfg = {
struct audioclk_data {
struct clk_hw_onecell_data *hw_onecell_data;
+ unsigned int reset_offset;
+ unsigned int reset_num;
};
static int axg_audio_clkc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct audioclk_data *data;
+ struct axg_audio_reset_data *rst;
struct regmap *map;
struct resource *res;
void __iomem *regs;
@@ -984,8 +1066,27 @@ static int axg_audio_clkc_probe(struct platform_device *pdev)
}
}
- return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
- data->hw_onecell_data);
+ ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
+ data->hw_onecell_data);
+ if (ret)
+ return ret;
+
+ /* Stop here if there is no reset */
+ if (!data->reset_num)
+ return 0;
+
+ rst = devm_kzalloc(dev, sizeof(*rst), GFP_KERNEL);
+ if (!rst)
+ return -ENOMEM;
+
+ rst->map = map;
+ rst->offset = data->reset_offset;
+ rst->rstc.nr_resets = data->reset_num;
+ rst->rstc.ops = &axg_audio_rstc_ops;
+ rst->rstc.of_node = dev->of_node;
+ rst->rstc.owner = THIS_MODULE;
+
+ return devm_reset_controller_register(dev, &rst->rstc);
}
static const struct audioclk_data axg_audioclk_data = {
@@ -994,6 +1095,8 @@ static const struct audioclk_data axg_audioclk_data = {
static const struct audioclk_data g12a_audioclk_data = {
.hw_onecell_data = &g12a_audio_hw_onecell_data,
+ .reset_offset = AUDIO_SW_RESET,
+ .reset_num = 26,
};
static const struct of_device_id clkc_match_table[] = {
diff --git a/drivers/clk/meson/axg-audio.h b/drivers/clk/meson/axg-audio.h
index 5d972d55d6c7..c00e28b2e1a9 100644
--- a/drivers/clk/meson/axg-audio.h
+++ b/drivers/clk/meson/axg-audio.h
@@ -22,6 +22,7 @@
#define AUDIO_MCLK_F_CTRL 0x018
#define AUDIO_MST_PAD_CTRL0 0x01c
#define AUDIO_MST_PAD_CTRL1 0x020
+#define AUDIO_SW_RESET 0x024
#define AUDIO_MST_A_SCLK_CTRL0 0x040
#define AUDIO_MST_A_SCLK_CTRL1 0x044
#define AUDIO_MST_B_SCLK_CTRL0 0x048
--
2.17.1

View File

@ -0,0 +1,156 @@
From cf0a4ad88bcb392ced80c8b63a7a64fc73c5e712 Mon Sep 17 00:00:00 2001
From: Igor Vavro <afl2001@gmail.com>
Date: Sat, 10 Aug 2019 13:55:34 +0000
Subject: [PATCH 086/186] FROMLIST: pinctrl: meson: add missing tsin pinctrl
for meson gxbb/gxl
This patch adds missing tsin pinctrl definitions for meson gxbb and gxl/gxm
Signed-off-by: Igor Vavro <afl2001@gmail.com>
---
drivers/pinctrl/meson/pinctrl-meson-gxbb.c | 35 ++++++++++++++++++++++
drivers/pinctrl/meson/pinctrl-meson-gxl.c | 27 +++++++++++++++++
2 files changed, 62 insertions(+)
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
index 6c640837073e..eaedc8d67900 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-gxbb.c
@@ -231,10 +231,24 @@ static const unsigned int hdmi_hpd_pins[] = { GPIOH_0 };
static const unsigned int hdmi_sda_pins[] = { GPIOH_1 };
static const unsigned int hdmi_scl_pins[] = { GPIOH_2 };
+static const unsigned int tsin_a_d_valid_pins[] = { GPIOY_0 };
+static const unsigned int tsin_a_sop_pins[] = { GPIOY_1 };
+static const unsigned int tsin_a_clk_pins[] = { GPIOY_2 };
+static const unsigned int tsin_a_d0_pins[] = { GPIOY_3 };
+static const unsigned int tsin_a_dp_pins[] = {
+ GPIOY_4, GPIOY_5, GPIOY_6, GPIOY_7, GPIOY_8, GPIOY_9, GPIOY_10
+};
+
+static const unsigned int tsin_a_fail_pins[] = { GPIOY_11 };
static const unsigned int i2s_out_ch23_y_pins[] = { GPIOY_8 };
static const unsigned int i2s_out_ch45_y_pins[] = { GPIOY_9 };
static const unsigned int i2s_out_ch67_y_pins[] = { GPIOY_10 };
+static const unsigned int tsin_b_d_valid_pins[] = { GPIOX_6 };
+static const unsigned int tsin_b_sop_pins[] = { GPIOX_7 };
+static const unsigned int tsin_b_clk_pins[] = { GPIOX_8 };
+static const unsigned int tsin_b_d0_pins[] = { GPIOX_9 };
+
static const unsigned int spdif_out_y_pins[] = { GPIOY_12 };
static const unsigned int gen_clk_out_pins[] = { GPIOY_15 };
@@ -437,8 +451,18 @@ static struct meson_pmx_group meson_gxbb_periphs_groups[] = {
GROUP(pwm_a_x, 3, 17),
GROUP(pwm_e, 2, 30),
GROUP(pwm_f_x, 3, 18),
+ GROUP(tsin_b_d_valid, 3, 9),
+ GROUP(tsin_b_sop, 3, 8),
+ GROUP(tsin_b_clk, 3, 10),
+ GROUP(tsin_b_d0, 3, 7),
/* Bank Y */
+ GROUP(tsin_a_fail, 3, 3),
+ GROUP(tsin_a_d_valid, 3, 2),
+ GROUP(tsin_a_sop, 3, 1),
+ GROUP(tsin_a_clk, 3, 0),
+ GROUP(tsin_a_d0, 3, 4),
+ GROUP(tsin_a_dp, 3, 5),
GROUP(uart_cts_c, 1, 19),
GROUP(uart_rts_c, 1, 18),
GROUP(uart_tx_c, 1, 17),
@@ -601,6 +625,15 @@ static const char * const gpio_periphs_groups[] = {
"GPIOX_20", "GPIOX_21", "GPIOX_22",
};
+static const char * const tsin_a_groups[] = {
+ "tsin_a_clk", "tsin_a_sop", "tsin_a_d_valid", "tsin_a_d0",
+ "tsin_a_dp", "tsin_a_fail",
+};
+
+static const char * const tsin_b_groups[] = {
+ "tsin_b_clk", "tsin_b_sop", "tsin_b_d_valid", "tsin_b_d0",
+};
+
static const char * const emmc_groups[] = {
"emmc_nand_d07", "emmc_clk", "emmc_cmd", "emmc_ds",
};
@@ -792,6 +825,8 @@ static struct meson_pmx_func meson_gxbb_periphs_functions[] = {
FUNCTION(i2s_out),
FUNCTION(spdif_out),
FUNCTION(gen_clk_out),
+ FUNCTION(tsin_a),
+ FUNCTION(tsin_b),
};
static struct meson_pmx_func meson_gxbb_aobus_functions[] = {
diff --git a/drivers/pinctrl/meson/pinctrl-meson-gxl.c b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
index 72c5373c8dc1..759245e29710 100644
--- a/drivers/pinctrl/meson/pinctrl-meson-gxl.c
+++ b/drivers/pinctrl/meson/pinctrl-meson-gxl.c
@@ -241,6 +241,17 @@ static const unsigned int tsin_a_dp_pins[] = {
GPIODV_1, GPIODV_2, GPIODV_3, GPIODV_4, GPIODV_5, GPIODV_6, GPIODV_7,
};
+static const unsigned int tsin_b_clk_pins[] = { GPIOH_6 };
+static const unsigned int tsin_b_d0_pins[] = { GPIOH_7 };
+static const unsigned int tsin_b_sop_pins[] = { GPIOH_8 };
+static const unsigned int tsin_b_d_valid_pins[] = { GPIOH_9 };
+
+static const unsigned int tsin_b_fail_z4_pins[] = { GPIOZ_4 };
+static const unsigned int tsin_b_clk_z3_pins[] = { GPIOZ_3 };
+static const unsigned int tsin_b_d0_z2_pins[] = { GPIOZ_2 };
+static const unsigned int tsin_b_sop_z1_pins[] = { GPIOZ_1 };
+static const unsigned int tsin_b_d_valid_z0_pins[] = { GPIOZ_0 };
+
static const struct pinctrl_pin_desc meson_gxl_aobus_pins[] = {
MESON_PIN(GPIOAO_0),
MESON_PIN(GPIOAO_1),
@@ -438,6 +449,11 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(eth_txd1, 4, 12),
GROUP(eth_txd2, 4, 11),
GROUP(eth_txd3, 4, 10),
+ GROUP(tsin_b_fail_z4, 3, 15),
+ GROUP(tsin_b_clk_z3, 3, 16),
+ GROUP(tsin_b_d0_z2, 3, 17),
+ GROUP(tsin_b_sop_z1, 3, 18),
+ GROUP(tsin_b_d_valid_z0, 3, 19),
GROUP(pwm_c, 3, 20),
GROUP(i2s_out_ch23_z, 3, 26),
GROUP(i2s_out_ch45_z, 3, 25),
@@ -454,6 +470,10 @@ static struct meson_pmx_group meson_gxl_periphs_groups[] = {
GROUP(i2s_out_lr_clk, 6, 24),
GROUP(i2s_out_ch01, 6, 23),
GROUP(spdif_out_h, 6, 28),
+ GROUP(tsin_b_d0, 6, 17),
+ GROUP(tsin_b_sop, 6, 18),
+ GROUP(tsin_b_d_valid, 6, 19),
+ GROUP(tsin_b_clk, 6, 20),
/* Bank DV */
GROUP(uart_tx_b, 2, 16),
@@ -689,6 +709,12 @@ static const char * const tsin_a_groups[] = {
"tsin_a_dp", "tsin_a_fail",
};
+static const char * const tsin_b_groups[] = {
+ "tsin_b_clk", "tsin_b_sop", "tsin_b_d_valid", "tsin_b_d0",
+ "tsin_b_clk_z3", "tsin_b_sop_z1", "tsin_b_d_valid_z0", "tsin_b_d0_z2",
+ "tsin_b_fail_z4",
+};
+
static const char * const gpio_aobus_groups[] = {
"GPIOAO_0", "GPIOAO_1", "GPIOAO_2", "GPIOAO_3", "GPIOAO_4",
"GPIOAO_5", "GPIOAO_6", "GPIOAO_7", "GPIOAO_8", "GPIOAO_9",
@@ -764,6 +790,7 @@ static struct meson_pmx_func meson_gxl_periphs_functions[] = {
FUNCTION(spdif_out),
FUNCTION(eth_led),
FUNCTION(tsin_a),
+ FUNCTION(tsin_b),
};
static struct meson_pmx_func meson_gxl_aobus_functions[] = {
--
2.17.1

View File

@ -0,0 +1,647 @@
From 774508b13d2f4d53608d14b6da6f53f66e765f23 Mon Sep 17 00:00:00 2001
From: Christian Hewitt <christianshewitt@gmail.com>
Date: Sun, 19 May 2019 14:27:24 +0000
Subject: [PATCH 087/186] FROMLIST: arm64: dts: meson-g12b-khadas-vim3: add
initial device-tree
The Khadas VIM3 uses the Amlogic S922X or A311S SoC, both based on the
Amlogic G12B SoC family, on a board with the same form factor as the
VIM/VIM2 models. It ships in two variants; basic and
pro which differ in RAM and eMMC size:
- 2GB (basic) or 4GB (pro) LPDDR4 RAM
- 16GB (basic) or 32GB (pro) eMMC 5.1 storage
- 16MB SPI flash
- 10/100/1000 Base-T Ethernet
- AP6398S Wireless (802.11 a/b/g/n/ac, BT5.0)
- HDMI 2.1 video
- 1x USB 2.0 + 1x USB 3.0 ports
- 1x USB-C (power) with USB 2.0 OTG
- 3x LED's (1x red, 1x blue, 1x white)
- 3x buttons (power, function, reset)
- IR receiver
- M2 socket with PCIe, USB, ADC & I2C
- 40pin GPIO Header
- 1x micro SD card slot
A common meson-g12b-khadas-vim3.dtsi is added to support both S922X and
A311D SoCs supported by two variants of the board.
Signed-off-by: Christian Hewitt <christianshewitt@gmail.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/boot/dts/amlogic/Makefile | 2 +
.../amlogic/meson-g12b-a311d-khadas-vim3.dts | 15 +
.../dts/amlogic/meson-g12b-khadas-vim3.dtsi | 542 ++++++++++++++++++
.../amlogic/meson-g12b-s922x-khadas-vim3.dts | 15 +
4 files changed, 574 insertions(+)
create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts
create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi
create mode 100644 arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts
diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
index 07b861fe5fa5..ae5e8d0c08da 100644
--- a/arch/arm64/boot/dts/amlogic/Makefile
+++ b/arch/arm64/boot/dts/amlogic/Makefile
@@ -3,6 +3,8 @@ dtb-$(CONFIG_ARCH_MESON) += meson-axg-s400.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-sei510.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-u200.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12a-x96-max.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-a311d-khadas-vim3.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-g12b-s922x-khadas-vim3.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-g12b-odroid-n2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nanopi-k2.dtb
dtb-$(CONFIG_ARCH_MESON) += meson-gxbb-nexbox-a95x.dtb
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts
new file mode 100644
index 000000000000..73128ed24361
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-a311d-khadas-vim3.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-g12b-a311d.dtsi"
+#include "meson-g12b-khadas-vim3.dtsi"
+
+/ {
+ compatible = "khadas,vim3", "amlogic,a311d", "amlogic,g12b";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi
new file mode 100644
index 000000000000..382148ef882a
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-khadas-vim3.dtsi
@@ -0,0 +1,542 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/meson-g12a-gpio.h>
+#include <dt-bindings/sound/meson-g12a-tohdmitx.h>
+#include <dt-bindings/usb/pd.h>
+
+/ {
+ model = "Khadas VIM3";
+
+ aliases {
+ serial0 = &uart_AO;
+ ethernet0 = &ethmac;
+ };
+
+ chosen {
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x40000000>;
+ };
+
+ adc-keys {
+ compatible = "adc-keys";
+ io-channels = <&saradc 2>;
+ io-channel-names = "buttons";
+ keyup-threshold-microvolt = <1710000>;
+
+ button-function {
+ label = "Function";
+ linux,code = <KEY_FN>;
+ press-threshold-microvolt = <10000>;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ white {
+ label = "vim3:white";
+ gpios = <&gpio_ao GPIOAO_4 GPIO_ACTIVE_LOW>;
+ linux,default-trigger = "heartbeat";
+ };
+
+ red {
+ label = "vim3:red";
+ gpios = <&gpio_expander 5 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ emmc_pwrseq: emmc-pwrseq {
+ compatible = "mmc-pwrseq-emmc";
+ reset-gpios = <&gpio BOOT_12 GPIO_ACTIVE_LOW>;
+ };
+
+
+ gpio-keys-polled {
+ compatible = "gpio-keys-polled";
+ poll-interval = <100>;
+
+ power-button {
+ label = "power";
+ linux,code = <KEY_POWER>;
+ gpios = <&gpio_ao GPIOAO_7 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ sdio_pwrseq: sdio-pwrseq {
+ compatible = "mmc-pwrseq-simple";
+ reset-gpios = <&gpio GPIOX_6 GPIO_ACTIVE_LOW>;
+ clocks = <&wifi32k>;
+ clock-names = "ext_clock";
+ };
+
+ dc_in: regulator-dc_in {
+ compatible = "regulator-fixed";
+ regulator-name = "DC_IN";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ regulator-always-on;
+ };
+
+ vcc_5v: regulator-vcc_5v {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_5V";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&dc_in>;
+
+ gpio = <&gpio GPIOH_8 GPIO_OPEN_DRAIN>;
+ enable-active-high;
+ };
+
+ vcc_1v8: regulator-vcc_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_3v3>;
+ regulator-always-on;
+ };
+
+ vcc_3v3: regulator-vcc_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCC_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&vsys_3v3>;
+ regulator-always-on;
+ /* FIXME: actually controlled by VDDCPU_B_EN */
+ };
+
+ vddcpu_a: regulator-vddcpu-a {
+ /*
+ * MP8756GD Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU_A";
+ regulator-min-microvolt = <690000>;
+ regulator-max-microvolt = <1050000>;
+
+ vin-supply = <&dc_in>;
+
+ pwms = <&pwm_ab 0 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vddcpu_b: regulator-vddcpu-b {
+ /*
+ * Silergy SY8030DEC Regulator.
+ */
+ compatible = "pwm-regulator";
+
+ regulator-name = "VDDCPU_B";
+ regulator-min-microvolt = <690000>;
+ regulator-max-microvolt = <1050000>;
+
+ vin-supply = <&vsys_3v3>;
+
+ pwms = <&pwm_AO_cd 1 1250 0>;
+ pwm-dutycycle-range = <100 0>;
+
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vddao_1v8: regulator-vddao_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "VDDIO_AO1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vsys_3v3>;
+ regulator-always-on;
+ };
+
+ emmc_1v8: regulator-emmc_1v8 {
+ compatible = "regulator-fixed";
+ regulator-name = "EMMC_AO1V8";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ vin-supply = <&vcc_3v3>;
+ regulator-always-on;
+ };
+
+ vsys_3v3: regulator-vsys_3v3 {
+ compatible = "regulator-fixed";
+ regulator-name = "VSYS_3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ vin-supply = <&dc_in>;
+ regulator-always-on;
+ };
+
+ usb_pwr: regulator-usb_pwr {
+ compatible = "regulator-fixed";
+ regulator-name = "USB_PWR";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ vin-supply = <&vcc_5v>;
+
+ gpio = <&gpio GPIOA_6 GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ };
+
+ hdmi-connector {
+ compatible = "hdmi-connector";
+ type = "a";
+
+ port {
+ hdmi_connector_in: endpoint {
+ remote-endpoint = <&hdmi_tx_tmds_out>;
+ };
+ };
+ };
+
+ wifi32k: wifi32k {
+ compatible = "pwm-clock";
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ pwms = <&pwm_ef 0 30518 0>; /* PWM_E at 32.768KHz */
+ };
+
+ sound {
+ compatible = "amlogic,axg-sound-card";
+ model = "G12A-KHADAS-VIM3";
+ audio-aux-devs = <&tdmout_b>;
+ audio-routing = "TDMOUT_B IN 0", "FRDDR_A OUT 1",
+ "TDMOUT_B IN 1", "FRDDR_B OUT 1",
+ "TDMOUT_B IN 2", "FRDDR_C OUT 1",
+ "TDM_B Playback", "TDMOUT_B OUT";
+
+ assigned-clocks = <&clkc CLKID_MPLL2>,
+ <&clkc CLKID_MPLL0>,
+ <&clkc CLKID_MPLL1>;
+ assigned-clock-parents = <0>, <0>, <0>;
+ assigned-clock-rates = <294912000>,
+ <270950400>,
+ <393216000>;
+ status = "okay";
+
+ dai-link-0 {
+ sound-dai = <&frddr_a>;
+ };
+
+ dai-link-1 {
+ sound-dai = <&frddr_b>;
+ };
+
+ dai-link-2 {
+ sound-dai = <&frddr_c>;
+ };
+
+ /* 8ch hdmi interface */
+ dai-link-3 {
+ sound-dai = <&tdmif_b>;
+ dai-format = "i2s";
+ dai-tdm-slot-tx-mask-0 = <1 1>;
+ dai-tdm-slot-tx-mask-1 = <1 1>;
+ dai-tdm-slot-tx-mask-2 = <1 1>;
+ dai-tdm-slot-tx-mask-3 = <1 1>;
+ mclk-fs = <256>;
+
+ codec {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_IN_B>;
+ };
+ };
+
+ /* hdmi glue */
+ dai-link-4 {
+ sound-dai = <&tohdmitx TOHDMITX_I2S_OUT>;
+
+ codec {
+ sound-dai = <&hdmi_tx>;
+ };
+ };
+ };
+};
+
+&arb {
+ status = "okay";
+};
+
+&cec_AO {
+ pinctrl-0 = <&cec_ao_a_h_pins>;
+ pinctrl-names = "default";
+ status = "disabled";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&cecb_AO {
+ pinctrl-0 = <&cec_ao_b_h_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ hdmi-phandle = <&hdmi_tx>;
+};
+
+&clkc_audio {
+ status = "okay";
+};
+
+&cpu0 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table_0>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu1 {
+ cpu-supply = <&vddcpu_b>;
+ operating-points-v2 = <&cpu_opp_table_0>;
+ clocks = <&clkc CLKID_CPU_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu100 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu101 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu102 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&cpu103 {
+ cpu-supply = <&vddcpu_a>;
+ operating-points-v2 = <&cpub_opp_table_1>;
+ clocks = <&clkc CLKID_CPUB_CLK>;
+ clock-latency = <50000>;
+};
+
+&ext_mdio {
+ external_phy: ethernet-phy@0 {
+ /* Realtek RTL8211F (0x001cc916) */
+ reg = <0>;
+ max-speed = <1000>;
+ };
+};
+
+&ethmac {
+ pinctrl-0 = <&eth_pins>, <&eth_rgmii_pins>;
+ pinctrl-names = "default";
+ status = "okay";
+ phy-mode = "rgmii";
+ phy-handle = <&external_phy>;
+ amlogic,tx-delay-ns = <2>;
+};
+
+&frddr_a {
+ status = "okay";
+};
+
+&frddr_b {
+ status = "okay";
+};
+
+&frddr_c {
+ status = "okay";
+};
+
+&hdmi_tx {
+ status = "okay";
+ pinctrl-0 = <&hdmitx_hpd_pins>, <&hdmitx_ddc_pins>;
+ pinctrl-names = "default";
+ hdmi-supply = <&vcc_5v>;
+};
+
+&hdmi_tx_tmds_port {
+ hdmi_tx_tmds_out: endpoint {
+ remote-endpoint = <&hdmi_connector_in>;
+ };
+};
+
+&i2c_AO {
+ status = "okay";
+ pinctrl-0 = <&i2c_ao_sck_pins>, <&i2c_ao_sda_pins>;
+ pinctrl-names = "default";
+
+ gpio_expander: gpio-controller@20 {
+ compatible = "ti,tca6408";
+ reg = <0x20>;
+ vcc-supply = <&vcc_3v3>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ rtc@51 {
+ compatible = "haoyu,hym8563";
+ reg = <0x51>;
+ #clock-cells = <0>;
+ };
+};
+
+&ir {
+ status = "okay";
+ pinctrl-0 = <&remote_input_ao_pins>;
+ pinctrl-names = "default";
+ linux,rc-map-name = "rc-khadas";
+};
+
+&pwm_ab {
+ pinctrl-0 = <&pwm_a_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin0";
+ status = "okay";
+};
+
+&pwm_AO_cd {
+ pinctrl-0 = <&pwm_ao_d_e_pins>;
+ pinctrl-names = "default";
+ clocks = <&xtal>;
+ clock-names = "clkin1";
+ status = "okay";
+};
+
+&pwm_ef {
+ status = "okay";
+ pinctrl-0 = <&pwm_e_pins>;
+ pinctrl-names = "default";
+};
+
+&saradc {
+ status = "okay";
+ vref-supply = <&vddao_1v8>;
+};
+
+/* SDIO */
+&sd_emmc_a {
+ status = "okay";
+ pinctrl-0 = <&sdio_pins>;
+ pinctrl-1 = <&sdio_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ sd-uhs-sdr50;
+ max-frequency = <100000000>;
+
+ non-removable;
+ disable-wp;
+
+ mmc-pwrseq = <&sdio_pwrseq>;
+
+ vmmc-supply = <&vsys_3v3>;
+ vqmmc-supply = <&vddao_1v8>;
+
+ brcmf: wifi@1 {
+ reg = <1>;
+ compatible = "brcm,bcm4329-fmac";
+ };
+};
+
+/* SD card */
+&sd_emmc_b {
+ status = "okay";
+ pinctrl-0 = <&sdcard_c_pins>;
+ pinctrl-1 = <&sdcard_clk_gate_c_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <4>;
+ cap-sd-highspeed;
+ max-frequency = <50000000>;
+ disable-wp;
+
+ cd-gpios = <&gpio GPIOC_6 GPIO_ACTIVE_LOW>;
+ vmmc-supply = <&vsys_3v3>;
+ vqmmc-supply = <&vsys_3v3>;
+};
+
+/* eMMC */
+&sd_emmc_c {
+ status = "okay";
+ pinctrl-0 = <&emmc_pins>, <&emmc_ds_pins>;
+ pinctrl-1 = <&emmc_clk_gate_pins>;
+ pinctrl-names = "default", "clk-gate";
+
+ bus-width = <8>;
+ cap-mmc-highspeed;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ max-frequency = <200000000>;
+ disable-wp;
+
+ mmc-pwrseq = <&emmc_pwrseq>;
+ vmmc-supply = <&vcc_3v3>;
+ vqmmc-supply = <&emmc_1v8>;
+};
+
+&tdmif_b {
+ status = "okay";
+};
+
+&tdmout_b {
+ status = "okay";
+};
+
+&tohdmitx {
+ status = "okay";
+};
+
+&uart_A {
+ status = "okay";
+ pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+ pinctrl-names = "default";
+ uart-has-rtscts;
+
+ bluetooth {
+ compatible = "brcm,bcm43438-bt";
+ shutdown-gpios = <&gpio GPIOX_17 GPIO_ACTIVE_HIGH>;
+ max-speed = <2000000>;
+ clocks = <&wifi32k>;
+ clock-names = "lpo";
+ };
+};
+
+&uart_AO {
+ status = "okay";
+ pinctrl-0 = <&uart_ao_a_pins>;
+ pinctrl-names = "default";
+};
+
+&usb2_phy0 {
+ phy-supply = <&dc_in>;
+};
+
+&usb2_phy1 {
+ phy-supply = <&usb_pwr>;
+};
+
+&usb3_pcie_phy {
+ phy-supply = <&usb_pwr>;
+};
+
+&usb {
+ status = "okay";
+ dr_mode = "peripheral";
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts
new file mode 100644
index 000000000000..6bcf972b8bfa
--- /dev/null
+++ b/arch/arm64/boot/dts/amlogic/meson-g12b-s922x-khadas-vim3.dts
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 BayLibre, SAS
+ * Author: Neil Armstrong <narmstrong@baylibre.com>
+ * Copyright (c) 2019 Christian Hewitt <christianshewitt@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-g12b-s922x.dtsi"
+#include "meson-g12b-khadas-vim3.dtsi"
+
+/ {
+ compatible = "khadas,vim3", "amlogic,s922x", "amlogic,g12b";
+};
--
2.17.1

View File

@ -0,0 +1,30 @@
From 7f4fb59e10f9b3451a0995487122bb3f2807667f Mon Sep 17 00:00:00 2001
From: Carlo Caione <ccaione@baylibre.com>
Date: Sat, 10 Aug 2019 13:40:40 +0000
Subject: [PATCH 088/186] FROMLIST: firmware: meson_sm: Mark chip struct as
static const
No need to be a global struct.
Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
drivers/firmware/meson/meson_sm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
index 8d908a8e0d20..772ca6726e7b 100644
--- a/drivers/firmware/meson/meson_sm.c
+++ b/drivers/firmware/meson/meson_sm.c
@@ -35,7 +35,7 @@ struct meson_sm_chip {
struct meson_sm_cmd cmd[];
};
-struct meson_sm_chip gxbb_chip = {
+static const struct meson_sm_chip gxbb_chip = {
.shmem_size = SZ_4K,
.cmd_shmem_in_base = 0x82000020,
.cmd_shmem_out_base = 0x82000021,
--
2.17.1

View File

@ -0,0 +1,49 @@
From 1ebcd7d499b9b06d3ead674d883d18fef2184348 Mon Sep 17 00:00:00 2001
From: Carlo Caione <ccaione@baylibre.com>
Date: Sat, 10 Aug 2019 13:42:08 +0000
Subject: [PATCH 089/186] FROMLIST: nvmem: meson-efuse: bindings: Add
secure-monitor phandle
Add a new property to link the nvmem driver to the secure-monitor. The
nvmem driver needs to access the secure-monitor to be able to access the
fuses.
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
Documentation/devicetree/bindings/nvmem/amlogic-efuse.txt | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/devicetree/bindings/nvmem/amlogic-efuse.txt b/Documentation/devicetree/bindings/nvmem/amlogic-efuse.txt
index 2e0723ab3384..f7b3ed74db54 100644
--- a/Documentation/devicetree/bindings/nvmem/amlogic-efuse.txt
+++ b/Documentation/devicetree/bindings/nvmem/amlogic-efuse.txt
@@ -4,6 +4,7 @@ Required properties:
- compatible: should be "amlogic,meson-gxbb-efuse"
- clocks: phandle to the efuse peripheral clock provided by the
clock controller.
+- secure-monitor: phandle to the secure-monitor node
= Data cells =
Are child nodes of eFuse, bindings of which as described in
@@ -16,6 +17,7 @@ Example:
clocks = <&clkc CLKID_EFUSE>;
#address-cells = <1>;
#size-cells = <1>;
+ secure-monitor = <&sm>;
sn: sn@14 {
reg = <0x14 0x10>;
@@ -30,6 +32,10 @@ Example:
};
};
+ sm: secure-monitor {
+ compatible = "amlogic,meson-gxbb-sm";
+ };
+
= Data consumers =
Are device nodes which consume nvmem data cells.
--
2.17.1

View File

@ -0,0 +1,54 @@
From 1438d7d39c0c4a8b8432acf7318da20f09693564 Mon Sep 17 00:00:00 2001
From: Carlo Caione <ccaione@baylibre.com>
Date: Sat, 10 Aug 2019 13:45:41 +0000
Subject: [PATCH 090/186] FROMLIST: arm64: dts: meson: Link nvmem and
secure-monitor nodes
The former is going to use the latter to retrieve the efuses data.
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-axg.dtsi | 1 +
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 1 +
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 1 +
3 files changed, 3 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
index 12bf959c17a7..15a7b7998dd4 100644
--- a/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-axg.dtsi
@@ -117,6 +117,7 @@
#address-cells = <1>;
#size-cells = <1>;
read-only;
+ secure-monitor = <&sm>;
};
psci {
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index 71fd725dee77..da0dc80b44cb 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -57,6 +57,7 @@
#address-cells = <1>;
#size-cells = <1>;
read-only;
+ secure-monitor = <&sm>;
};
psci {
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
index e62aad5bf867..209f20bea4a1 100644
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
@@ -161,6 +161,7 @@
#address-cells = <1>;
#size-cells = <1>;
read-only;
+ secure-monitor = <&sm>;
sn: sn@14 {
reg = <0x14 0x10>;
--
2.17.1

View File

@ -0,0 +1,347 @@
From 1fed41a5fcf6f23238f9c766e4054b73b8d7365f Mon Sep 17 00:00:00 2001
From: Carlo Caione <ccaione@baylibre.com>
Date: Sat, 10 Aug 2019 13:46:54 +0000
Subject: [PATCH 091/186] FROMLIST: firmware: meson_sm: Rework driver as a
proper platform driver
The secure monitor driver is currently a frankenstein driver which is
registered as a platform driver but its functionality goes through a
global struct accessed by the consumer drivers using exported helper
functions.
Try to tidy up the driver moving the firmware struct into the driver
data and make the consumer drivers referencing the secure-monitor using
a new property in the DT.
Currently only the nvmem driver is using this API so we can fix it in
the same commit.
Reviewed-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Carlo Caione <ccaione@baylibre.com>
---
drivers/firmware/meson/meson_sm.c | 94 +++++++++++++++++--------
drivers/nvmem/meson-efuse.c | 24 ++++++-
include/linux/firmware/meson/meson_sm.h | 15 ++--
3 files changed, 94 insertions(+), 39 deletions(-)
diff --git a/drivers/firmware/meson/meson_sm.c b/drivers/firmware/meson/meson_sm.c
index 772ca6726e7b..2e36a2aa274c 100644
--- a/drivers/firmware/meson/meson_sm.c
+++ b/drivers/firmware/meson/meson_sm.c
@@ -54,8 +54,6 @@ struct meson_sm_firmware {
void __iomem *sm_shmem_out_base;
};
-static struct meson_sm_firmware fw;
-
static u32 meson_sm_get_cmd(const struct meson_sm_chip *chip,
unsigned int cmd_index)
{
@@ -90,6 +88,7 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
/**
* meson_sm_call - generic SMC32 call to the secure-monitor
*
+ * @fw: Pointer to secure-monitor firmware
* @cmd_index: Index of the SMC32 function ID
* @ret: Returned value
* @arg0: SMC32 Argument 0
@@ -100,15 +99,15 @@ static void __iomem *meson_sm_map_shmem(u32 cmd_shmem, unsigned int size)
*
* Return: 0 on success, a negative value on error
*/
-int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0,
- u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
+ u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
u32 cmd, lret;
- if (!fw.chip)
+ if (!fw->chip)
return -ENOENT;
- cmd = meson_sm_get_cmd(fw.chip, cmd_index);
+ cmd = meson_sm_get_cmd(fw->chip, cmd_index);
if (!cmd)
return -EINVAL;
@@ -124,6 +123,7 @@ EXPORT_SYMBOL(meson_sm_call);
/**
* meson_sm_call_read - retrieve data from secure-monitor
*
+ * @fw: Pointer to secure-monitor firmware
* @buffer: Buffer to store the retrieved data
* @bsize: Size of the buffer
* @cmd_index: Index of the SMC32 function ID
@@ -137,22 +137,23 @@ EXPORT_SYMBOL(meson_sm_call);
* When 0 is returned there is no guarantee about the amount of
* data read and bsize bytes are copied in buffer.
*/
-int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
- u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
+ unsigned int bsize, unsigned int cmd_index, u32 arg0,
+ u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
u32 size;
int ret;
- if (!fw.chip)
+ if (!fw->chip)
return -ENOENT;
- if (!fw.chip->cmd_shmem_out_base)
+ if (!fw->chip->cmd_shmem_out_base)
return -EINVAL;
- if (bsize > fw.chip->shmem_size)
+ if (bsize > fw->chip->shmem_size)
return -EINVAL;
- if (meson_sm_call(cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
+ if (meson_sm_call(fw, cmd_index, &size, arg0, arg1, arg2, arg3, arg4) < 0)
return -EINVAL;
if (size > bsize)
@@ -164,7 +165,7 @@ int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
size = bsize;
if (buffer)
- memcpy(buffer, fw.sm_shmem_out_base, size);
+ memcpy(buffer, fw->sm_shmem_out_base, size);
return ret;
}
@@ -173,6 +174,7 @@ EXPORT_SYMBOL(meson_sm_call_read);
/**
* meson_sm_call_write - send data to secure-monitor
*
+ * @fw: Pointer to secure-monitor firmware
* @buffer: Buffer containing data to send
* @size: Size of the data to send
* @cmd_index: Index of the SMC32 function ID
@@ -184,23 +186,24 @@ EXPORT_SYMBOL(meson_sm_call_read);
*
* Return: size of sent data on success, a negative value on error
*/
-int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index,
- u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
+int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
+ unsigned int size, unsigned int cmd_index, u32 arg0,
+ u32 arg1, u32 arg2, u32 arg3, u32 arg4)
{
u32 written;
- if (!fw.chip)
+ if (!fw->chip)
return -ENOENT;
- if (size > fw.chip->shmem_size)
+ if (size > fw->chip->shmem_size)
return -EINVAL;
- if (!fw.chip->cmd_shmem_in_base)
+ if (!fw->chip->cmd_shmem_in_base)
return -EINVAL;
- memcpy(fw.sm_shmem_in_base, buffer, size);
+ memcpy(fw->sm_shmem_in_base, buffer, size);
- if (meson_sm_call(cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
+ if (meson_sm_call(fw, cmd_index, &written, arg0, arg1, arg2, arg3, arg4) < 0)
return -EINVAL;
if (!written)
@@ -210,6 +213,24 @@ int meson_sm_call_write(void *buffer, unsigned int size, unsigned int cmd_index,
}
EXPORT_SYMBOL(meson_sm_call_write);
+/**
+ * meson_sm_get - get pointer to meson_sm_firmware structure.
+ *
+ * @sm_node: Pointer to the secure-monitor Device Tree node.
+ *
+ * Return: NULL is the secure-monitor device is not ready.
+ */
+struct meson_sm_firmware *meson_sm_get(struct device_node *sm_node)
+{
+ struct platform_device *pdev = of_find_device_by_node(sm_node);
+
+ if (!pdev)
+ return NULL;
+
+ return platform_get_drvdata(pdev);
+}
+EXPORT_SYMBOL_GPL(meson_sm_get);
+
#define SM_CHIP_ID_LENGTH 119
#define SM_CHIP_ID_OFFSET 4
#define SM_CHIP_ID_SIZE 12
@@ -217,14 +238,18 @@ EXPORT_SYMBOL(meson_sm_call_write);
static ssize_t serial_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct meson_sm_firmware *fw;
uint8_t *id_buf;
int ret;
+ fw = platform_get_drvdata(pdev);
+
id_buf = kmalloc(SM_CHIP_ID_LENGTH, GFP_KERNEL);
if (!id_buf)
return -ENOMEM;
- ret = meson_sm_call_read(id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
+ ret = meson_sm_call_read(fw, id_buf, SM_CHIP_ID_LENGTH, SM_GET_CHIP_ID,
0, 0, 0, 0, 0);
if (ret < 0) {
kfree(id_buf);
@@ -268,25 +293,34 @@ static const struct of_device_id meson_sm_ids[] = {
static int __init meson_sm_probe(struct platform_device *pdev)
{
+ struct device *dev = &pdev->dev;
const struct meson_sm_chip *chip;
+ struct meson_sm_firmware *fw;
+
+ fw = devm_kzalloc(dev, sizeof(*fw), GFP_KERNEL);
+ if (!fw)
+ return -ENOMEM;
- chip = of_match_device(meson_sm_ids, &pdev->dev)->data;
+ chip = of_match_device(meson_sm_ids, dev)->data;
if (chip->cmd_shmem_in_base) {
- fw.sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
- chip->shmem_size);
- if (WARN_ON(!fw.sm_shmem_in_base))
+ fw->sm_shmem_in_base = meson_sm_map_shmem(chip->cmd_shmem_in_base,
+ chip->shmem_size);
+ if (WARN_ON(!fw->sm_shmem_in_base))
goto out;
}
if (chip->cmd_shmem_out_base) {
- fw.sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base,
- chip->shmem_size);
- if (WARN_ON(!fw.sm_shmem_out_base))
+ fw->sm_shmem_out_base = meson_sm_map_shmem(chip->cmd_shmem_out_base,
+ chip->shmem_size);
+ if (WARN_ON(!fw->sm_shmem_out_base))
goto out_in_base;
}
- fw.chip = chip;
+ fw->chip = chip;
+
+ platform_set_drvdata(pdev, fw);
+
pr_info("secure-monitor enabled\n");
if (sysfs_create_group(&pdev->dev.kobj, &meson_sm_sysfs_attr_group))
@@ -295,7 +329,7 @@ static int __init meson_sm_probe(struct platform_device *pdev)
return 0;
out_in_base:
- iounmap(fw.sm_shmem_in_base);
+ iounmap(fw->sm_shmem_in_base);
out:
return -EINVAL;
}
diff --git a/drivers/nvmem/meson-efuse.c b/drivers/nvmem/meson-efuse.c
index 39bd76306033..d6b533497ce1 100644
--- a/drivers/nvmem/meson-efuse.c
+++ b/drivers/nvmem/meson-efuse.c
@@ -17,14 +17,18 @@
static int meson_efuse_read(void *context, unsigned int offset,
void *val, size_t bytes)
{
- return meson_sm_call_read((u8 *)val, bytes, SM_EFUSE_READ, offset,
+ struct meson_sm_firmware *fw = context;
+
+ return meson_sm_call_read(fw, (u8 *)val, bytes, SM_EFUSE_READ, offset,
bytes, 0, 0, 0);
}
static int meson_efuse_write(void *context, unsigned int offset,
void *val, size_t bytes)
{
- return meson_sm_call_write((u8 *)val, bytes, SM_EFUSE_WRITE, offset,
+ struct meson_sm_firmware *fw = context;
+
+ return meson_sm_call_write(fw, (u8 *)val, bytes, SM_EFUSE_WRITE, offset,
bytes, 0, 0, 0);
}
@@ -37,12 +41,25 @@ MODULE_DEVICE_TABLE(of, meson_efuse_match);
static int meson_efuse_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ struct meson_sm_firmware *fw;
+ struct device_node *sm_np;
struct nvmem_device *nvmem;
struct nvmem_config *econfig;
struct clk *clk;
unsigned int size;
int ret;
+ sm_np = of_parse_phandle(pdev->dev.of_node, "secure-monitor", 0);
+ if (!sm_np) {
+ dev_err(&pdev->dev, "no secure-monitor node\n");
+ return -ENODEV;
+ }
+
+ fw = meson_sm_get(sm_np);
+ of_node_put(sm_np);
+ if (!fw)
+ return -EPROBE_DEFER;
+
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) {
ret = PTR_ERR(clk);
@@ -65,7 +82,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
return ret;
}
- if (meson_sm_call(SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
+ if (meson_sm_call(fw, SM_EFUSE_USER_MAX, &size, 0, 0, 0, 0, 0) < 0) {
dev_err(dev, "failed to get max user");
return -EINVAL;
}
@@ -81,6 +98,7 @@ static int meson_efuse_probe(struct platform_device *pdev)
econfig->reg_read = meson_efuse_read;
econfig->reg_write = meson_efuse_write;
econfig->size = size;
+ econfig->priv = fw;
nvmem = devm_nvmem_register(&pdev->dev, econfig);
diff --git a/include/linux/firmware/meson/meson_sm.h b/include/linux/firmware/meson/meson_sm.h
index 7613bf7c9442..6669e2a1d5fd 100644
--- a/include/linux/firmware/meson/meson_sm.h
+++ b/include/linux/firmware/meson/meson_sm.h
@@ -16,11 +16,14 @@ enum {
struct meson_sm_firmware;
-int meson_sm_call(unsigned int cmd_index, u32 *ret, u32 arg0, u32 arg1,
- u32 arg2, u32 arg3, u32 arg4);
-int meson_sm_call_write(void *buffer, unsigned int b_size, unsigned int cmd_index,
- u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
-int meson_sm_call_read(void *buffer, unsigned int bsize, unsigned int cmd_index,
- u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+int meson_sm_call(struct meson_sm_firmware *fw, unsigned int cmd_index,
+ u32 *ret, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+int meson_sm_call_write(struct meson_sm_firmware *fw, void *buffer,
+ unsigned int b_size, unsigned int cmd_index, u32 arg0,
+ u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+int meson_sm_call_read(struct meson_sm_firmware *fw, void *buffer,
+ unsigned int bsize, unsigned int cmd_index, u32 arg0,
+ u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+struct meson_sm_firmware *meson_sm_get(struct device_node *firmware_node);
#endif /* _MESON_SM_FW_H_ */
--
2.17.1

View File

@ -0,0 +1,29 @@
From 5ef9c6efe2ab55a2b8d8ab478d9ba43337fe6996 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Tue, 20 Aug 2019 15:02:29 +0000
Subject: [PATCH 092/186] FROMLIST: arm64: dts: meson: g12a: audio clock
controller provides resets
The clock controller dedicated to audio clocks also provides reset lines
on the g12 SoC family
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index da0dc80b44cb..f90d681c28bd 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -1455,6 +1455,7 @@
compatible = "amlogic,g12a-audio-clkc";
reg = <0x0 0x0 0x0 0xb4>;
#clock-cells = <1>;
+ #reset-cells = <1>;
clocks = <&clkc CLKID_AUDIO>,
<&clkc CLKID_MPLL0>,
--
2.17.1

View File

@ -0,0 +1,85 @@
From a52df786c1877dd433765142d4483e1767a7640f Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Tue, 20 Aug 2019 15:07:17 +0000
Subject: [PATCH 093/186] FROMLIST: arm64: dts: meson: g12a: add reset to tdm
formatters
Add the reset to the TDM formatters of the g12a. This helps
with channel mapping when a playback/capture uses more than 1 lane.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
index f90d681c28bd..2fa4b43f2dad 100644
--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
+++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -11,6 +11,7 @@
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/interrupt-controller/arm-gic.h>
#include <dt-bindings/reset/amlogic,meson-axg-audio-arb.h>
+#include <dt-bindings/reset/amlogic,meson-g12a-audio-reset.h>
#include <dt-bindings/reset/amlogic,meson-g12a-reset.h>
/ {
@@ -1564,6 +1565,7 @@
"amlogic,axg-tdmin";
reg = <0x0 0x300 0x0 0x40>;
sound-name-prefix = "TDMIN_A";
+ resets = <&clkc_audio AUD_RESET_TDMIN_A>;
clocks = <&clkc_audio AUD_CLKID_TDMIN_A>,
<&clkc_audio AUD_CLKID_TDMIN_A_SCLK>,
<&clkc_audio AUD_CLKID_TDMIN_A_SCLK_SEL>,
@@ -1579,6 +1581,7 @@
"amlogic,axg-tdmin";
reg = <0x0 0x340 0x0 0x40>;
sound-name-prefix = "TDMIN_B";
+ resets = <&clkc_audio AUD_RESET_TDMIN_B>;
clocks = <&clkc_audio AUD_CLKID_TDMIN_B>,
<&clkc_audio AUD_CLKID_TDMIN_B_SCLK>,
<&clkc_audio AUD_CLKID_TDMIN_B_SCLK_SEL>,
@@ -1594,6 +1597,7 @@
"amlogic,axg-tdmin";
reg = <0x0 0x380 0x0 0x40>;
sound-name-prefix = "TDMIN_C";
+ resets = <&clkc_audio AUD_RESET_TDMIN_C>;
clocks = <&clkc_audio AUD_CLKID_TDMIN_C>,
<&clkc_audio AUD_CLKID_TDMIN_C_SCLK>,
<&clkc_audio AUD_CLKID_TDMIN_C_SCLK_SEL>,
@@ -1609,6 +1613,7 @@
"amlogic,axg-tdmin";
reg = <0x0 0x3c0 0x0 0x40>;
sound-name-prefix = "TDMIN_LB";
+ resets = <&clkc_audio AUD_RESET_TDMIN_LB>;
clocks = <&clkc_audio AUD_CLKID_TDMIN_LB>,
<&clkc_audio AUD_CLKID_TDMIN_LB_SCLK>,
<&clkc_audio AUD_CLKID_TDMIN_LB_SCLK_SEL>,
@@ -1648,6 +1653,7 @@
compatible = "amlogic,g12a-tdmout";
reg = <0x0 0x500 0x0 0x40>;
sound-name-prefix = "TDMOUT_A";
+ resets = <&clkc_audio AUD_RESET_TDMOUT_A>;
clocks = <&clkc_audio AUD_CLKID_TDMOUT_A>,
<&clkc_audio AUD_CLKID_TDMOUT_A_SCLK>,
<&clkc_audio AUD_CLKID_TDMOUT_A_SCLK_SEL>,
@@ -1662,6 +1668,7 @@
compatible = "amlogic,g12a-tdmout";
reg = <0x0 0x540 0x0 0x40>;
sound-name-prefix = "TDMOUT_B";
+ resets = <&clkc_audio AUD_RESET_TDMOUT_B>;
clocks = <&clkc_audio AUD_CLKID_TDMOUT_B>,
<&clkc_audio AUD_CLKID_TDMOUT_B_SCLK>,
<&clkc_audio AUD_CLKID_TDMOUT_B_SCLK_SEL>,
@@ -1676,6 +1683,7 @@
compatible = "amlogic,g12a-tdmout";
reg = <0x0 0x580 0x0 0x40>;
sound-name-prefix = "TDMOUT_C";
+ resets = <&clkc_audio AUD_RESET_TDMOUT_C>;
clocks = <&clkc_audio AUD_CLKID_TDMOUT_C>,
<&clkc_audio AUD_CLKID_TDMOUT_C_SCLK>,
<&clkc_audio AUD_CLKID_TDMOUT_C_SCLK_SEL>,
--
2.17.1

View File

@ -0,0 +1,31 @@
From 600ca9000107683458570dc8b2cc6c73d318e83c Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Tue, 20 Aug 2019 15:09:58 +0000
Subject: [PATCH 094/186] FROMLIST: ASoC: meson: axg-tdm-formatter: free reset
on device removal
Use the devm variant to get the formatter reset so it is properly freed
on device removal
Fixes: 751bd5db5260 ("ASoC: meson: axg-tdm-formatter: add reset")
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/meson/axg-tdm-formatter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/meson/axg-tdm-formatter.c b/sound/soc/meson/axg-tdm-formatter.c
index 2e498201139f..1a0bf9d3836d 100644
--- a/sound/soc/meson/axg-tdm-formatter.c
+++ b/sound/soc/meson/axg-tdm-formatter.c
@@ -327,7 +327,7 @@ int axg_tdm_formatter_probe(struct platform_device *pdev)
}
/* Formatter dedicated reset line */
- formatter->reset = reset_control_get_optional_exclusive(dev, NULL);
+ formatter->reset = devm_reset_control_get_optional_exclusive(dev, NULL);
if (IS_ERR(formatter->reset)) {
ret = PTR_ERR(formatter->reset);
if (ret != -EPROBE_DEFER)
--
2.17.1

View File

@ -0,0 +1,29 @@
From 329151cbf8444d19f39e23968c24fb1d81578738 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Tue, 20 Aug 2019 15:12:11 +0000
Subject: [PATCH 095/186] FROMLIST: ASoC: meson: g12a-tohdmitx: require regmap
mmio
The tohdmitx glue uses regmap MMIO so it should require it.
Fixes: c8609f3870f7 ("ASoC: meson: add g12a tohdmitx control")
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
sound/soc/meson/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
index 63b38c123103..2e3676147cea 100644
--- a/sound/soc/meson/Kconfig
+++ b/sound/soc/meson/Kconfig
@@ -87,6 +87,7 @@ config SND_MESON_AXG_PDM
config SND_MESON_G12A_TOHDMITX
tristate "Amlogic G12A To HDMI TX Control Support"
+ select REGMAP_MMIO
imply SND_SOC_HDMI_CODEC
help
Select Y or M to add support for HDMI audio on the g12a SoC
--
2.17.1

View File

@ -0,0 +1,47 @@
From 5922d7ec7001093e7236bcd3d37d86a788c8432e Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Wed, 28 Aug 2019 13:29:48 +0000
Subject: [PATCH 096/186] FROMLIST: drm/meson: vclk: use the correct G12A frac
max value
When calculating the HDMI PLL settings for a DMT mode PHY frequency,
use the correct max fractional PLL value for G12A VPU.
With this fix, we can finally setup the 1024x768-60 mode.
Fixes: 202b9808f8ed ("drm/meson: Add G12A Video Clock setup")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
Fixed typo in commit log, 1024x76 => 1024x768
---
drivers/gpu/drm/meson/meson_vclk.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c
index be6e152fc75a..08c4f82c820d 100644
--- a/drivers/gpu/drm/meson/meson_vclk.c
+++ b/drivers/gpu/drm/meson/meson_vclk.c
@@ -637,13 +637,18 @@ static bool meson_hdmi_pll_validate_params(struct meson_drm *priv,
if (frac >= HDMI_FRAC_MAX_GXBB)
return false;
} else if (meson_vpu_is_compatible(priv, "amlogic,meson-gxm-vpu") ||
- meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu") ||
- meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) {
+ meson_vpu_is_compatible(priv, "amlogic,meson-gxl-vpu")) {
/* Empiric supported min/max dividers */
if (m < 106 || m > 247)
return false;
if (frac >= HDMI_FRAC_MAX_GXL)
return false;
+ } else if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu")) {
+ /* Empiric supported min/max dividers */
+ if (m < 106 || m > 247)
+ return false;
+ if (frac >= HDMI_FRAC_MAX_G12A)
+ return false;
}
return true;
--
2.17.1

View File

@ -0,0 +1,62 @@
From 34ff8f36e6f144166303271a8fa38c1976e7aec9 Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Thu, 14 Mar 2019 09:37:38 +0100
Subject: [PATCH 097/186] TEMP: drm/panfrost: add support for custom soft-reset
on Amlogic GXM
(cherry picked from commit 2e5230c1bf9cf01f035da72291cc460cb3b37096)
---
drivers/gpu/drm/panfrost/panfrost_gpu.c | 13 ++++++++++++-
drivers/gpu/drm/panfrost/panfrost_regs.h | 4 ++++
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c
index 20ab333fc925..2e1c6955efac 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
@@ -7,7 +7,9 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
+#include <linux/reset.h>
#include <linux/io.h>
+#include <linux/of.h>
#include <linux/iopoll.h>
#include <linux/platform_device.h>
@@ -59,7 +61,16 @@ int panfrost_gpu_soft_reset(struct panfrost_device *pfdev)
gpu_write(pfdev, GPU_INT_MASK, 0);
gpu_write(pfdev, GPU_INT_CLEAR, GPU_IRQ_RESET_COMPLETED);
- gpu_write(pfdev, GPU_CMD, GPU_CMD_SOFT_RESET);
+
+ if (of_device_is_compatible(pfdev->dev->of_node, "amlogic,meson-gxm-mali")) {
+ reset_control_assert(pfdev->rstc);
+ udelay(10);
+ reset_control_deassert(pfdev->rstc);
+
+ gpu_write(pfdev, GPU_PWR_KEY, 0x2968A819);
+ gpu_write(pfdev, GPU_PWR_OVERRIDE1, 0xfff | (0x20 << 16));
+ } else
+ gpu_write(pfdev, GPU_CMD, GPU_CMD_SOFT_RESET);
ret = readl_relaxed_poll_timeout(pfdev->iomem + GPU_INT_RAWSTAT,
val, val & GPU_IRQ_RESET_COMPLETED, 100, 10000);
diff --git a/drivers/gpu/drm/panfrost/panfrost_regs.h b/drivers/gpu/drm/panfrost/panfrost_regs.h
index ea38ac60581c..7a0cfa629760 100644
--- a/drivers/gpu/drm/panfrost/panfrost_regs.h
+++ b/drivers/gpu/drm/panfrost/panfrost_regs.h
@@ -69,6 +69,10 @@
#define GPU_PRFCNT_TILER_EN 0x74
#define GPU_PRFCNT_MMU_L2_EN 0x7c
+#define GPU_PWR_KEY 0x050 /* (WO) Power manager key register */
+#define GPU_PWR_OVERRIDE0 0x054 /* (RW) Power manager override settings */
+#define GPU_PWR_OVERRIDE1 0x058 /* (RW) Power manager override settings */
+
#define GPU_THREAD_MAX_THREADS 0x0A0 /* (RO) Maximum number of threads per core */
#define GPU_THREAD_MAX_WORKGROUP_SIZE 0x0A4 /* (RO) Maximum workgroup size */
#define GPU_THREAD_MAX_BARRIER_SIZE 0x0A8 /* (RO) Maximum threads waiting at a barrier */
--
2.17.1

View File

@ -0,0 +1,29 @@
From d0a03a1870329ebd76ab6affcfa3f103183ea771 Mon Sep 17 00:00:00 2001
From: chewitt <github@chrishewitt.net>
Date: Fri, 12 Jul 2019 21:20:38 +0000
Subject: [PATCH 098/186] TEMP: drm/panfrost: kernel driver fix 1/2
https://lkml.org/lkml/2019/5/29/786
Signed-off-by: Christian Hewitt <christian.hewitt@gmail.com>
---
drivers/iommu/io-pgtable-arm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index 161a7d56264d..c1048e741c66 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -1022,7 +1022,9 @@ arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
iop = arm_64_lpae_alloc_pgtable_s1(cfg, cookie);
if (iop) {
u64 mair, ttbr;
+ struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(&iop->ops);
+ data->levels = 4;
/* Copy values as union fields overlap */
mair = cfg->arm_lpae_s1_cfg.mair[0];
ttbr = cfg->arm_lpae_s1_cfg.ttbr[0];
--
2.17.1

View File

@ -0,0 +1,28 @@
From 5c46c60ef67f0d417ea29602e21f435b5da19a3e Mon Sep 17 00:00:00 2001
From: chewitt <github@chrishewitt.net>
Date: Fri, 12 Jul 2019 21:36:32 +0000
Subject: [PATCH 099/186] TEMP: drm/panfrost: kernel driver fix 2/2
https://patchwork.kernel.org/patch/10954241/
Signed-off-by: Christian Hewitt <christian.hewitt@gmail.com>
---
drivers/iommu/io-pgtable-arm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index c1048e741c66..a69b9b5d0f0f 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -1015,7 +1015,7 @@ arm_mali_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg, void *cookie)
{
struct io_pgtable *iop;
- if (cfg->ias != 48 || cfg->oas > 40)
+ if (cfg->ias > 48 || cfg->oas > 40)
return NULL;
cfg->pgsize_bitmap &= (SZ_4K | SZ_2M | SZ_1G);
--
2.17.1

View File

@ -0,0 +1,47 @@
From 4b0808ab45f174fd7ebcc3d20a8daeb83330a377 Mon Sep 17 00:00:00 2001
From: Jerome Brunet <jbrunet@baylibre.com>
Date: Mon, 13 Nov 2017 12:09:40 +0100
Subject: [PATCH 100/186] TEMP: ARM64: defconfig: enable CEC support
Turn on CONFIG_CEC_SUPPORT and CONFIG_CEC_PLATFORM_DRIVERS
Turn on CONFIG_VIDEO_MESON_AO_CEC as module
Turn on CONFIG_DRM_DW_HDMI_CEC as module
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
---
arch/arm64/configs/defconfig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 0e58ef02880c..1053815f20cc 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -493,6 +493,7 @@ CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
CONFIG_MEDIA_DIGITAL_TV_SUPPORT=y
+CONFIG_MEDIA_CEC_SUPPORT=y
CONFIG_MEDIA_CONTROLLER=y
CONFIG_VIDEO_V4L2_SUBDEV_API=y
# CONFIG_DVB_NET is not set
@@ -506,6 +507,8 @@ CONFIG_VIDEO_SAMSUNG_S5P_MFC=m
CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m
CONFIG_VIDEO_RENESAS_FCP=m
CONFIG_VIDEO_RENESAS_VSP1=m
+CONFIG_CEC_PLATFORM_DRIVERS=y
+CONFIG_VIDEO_MESON_AO_CEC=m
CONFIG_DRM=m
CONFIG_DRM_I2C_NXP_TDA998X=m
CONFIG_DRM_NOUVEAU=m
@@ -530,6 +533,7 @@ CONFIG_DRM_TEGRA=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_SII902X=m
CONFIG_DRM_I2C_ADV7511=m
+CONFIG_DRM_DW_HDMI_CEC=m
CONFIG_DRM_VC4=m
CONFIG_DRM_HISI_HIBMC=m
CONFIG_DRM_HISI_KIRIN=m
--
2.17.1

Some files were not shown because too many files have changed in this diff Show More