odroidc2-mainline: Add the kernel config and patches
This still doesn't 100% work correctly. I haven't yet tested adding an initrd would would likely make the kernel/u-boot bits a non-issue, that testing will happen later.
This commit is contained in:
6772
kernel-configs/odroidc2-mainline.config
Normal file
6772
kernel-configs/odroidc2-mainline.config
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,53 @@
|
||||
From a14c74cd31c50b4008b4160e516671c5e05e0254 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
||||
Date: Wed, 13 Jun 2018 14:05:07 +0200
|
||||
Subject: [PATCH 01/21] clk: meson-gxbb: set fclk_div2 as CLK_IS_CRITICAL
|
||||
|
||||
On Amlogic Meson GXBB & GXL platforms, the SCPI Cortex-M4 Co-Processor
|
||||
seems to be dependent on the FCLK_DIV2 to be operationnal.
|
||||
|
||||
The issue occured since v4.17-rc1 by freezing the kernel boot when
|
||||
the 'schedutil' cpufreq governor was selected as default :
|
||||
|
||||
[ 12.071837] scpi_protocol scpi: SCP Protocol 0.0 Firmware 0.0.0 version
|
||||
domain-0 init dvfs: 4
|
||||
[ 12.087757] hctosys: unable to open rtc device (rtc0)
|
||||
[ 12.087907] cfg80211: Loading compiled-in X.509 certificates for regulatory database
|
||||
[ 12.102241] cfg80211: Loaded X.509 cert 'sforshee: 00b28ddf47aef9cea7'
|
||||
|
||||
But when disabling the MMC driver, the boot finished but cpufreq failed to
|
||||
change the CPU frequency :
|
||||
|
||||
[ 12.153045] cpufreq: __target_index: Failed to change cpu frequency: -5
|
||||
|
||||
A bisect between v4.16 and v4.16-rc1 gave the 05f814402d61 commit to be
|
||||
the first bad commit.
|
||||
This commit added support for the missing clock gates before the fixed PLL
|
||||
fixed dividers (FCLK_DIVx) and the clock framework basically disabled
|
||||
all the unused fixed dividers, thus disabled a critical clock path for
|
||||
the SCPI Co-Processor.
|
||||
|
||||
This patch simply sets the FCLK_DIV2 gate as critical to ensure
|
||||
nobody can disable it.
|
||||
|
||||
Fixes: 05f814402d61 ("clk: meson: add fdiv clock gates")
|
||||
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
||||
---
|
||||
drivers/clk/meson/gxbb.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
|
||||
index 240658404367..177fffb9ebef 100644
|
||||
--- a/drivers/clk/meson/gxbb.c
|
||||
+++ b/drivers/clk/meson/gxbb.c
|
||||
@@ -498,6 +498,7 @@ static struct clk_regmap gxbb_fclk_div2 = {
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_names = (const char *[]){ "fclk_div2_div" },
|
||||
.num_parents = 1,
|
||||
+ .flags = CLK_IS_CRITICAL,
|
||||
},
|
||||
};
|
||||
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
From bc94a55c85422b420b515623e7e9b21edf8e1a72 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
||||
Date: Tue, 26 Jun 2018 09:37:39 +0200
|
||||
Subject: [PATCH 02/21] ARM64: dts: meson-gxbb-nanopi-k2: Add HDMI, CEC and
|
||||
CVBS nodes
|
||||
|
||||
The Amlogic Meson GXBB based Nanopi-K2 board has an HDMI connector
|
||||
with CEC and CVBS available on the 40pin header.
|
||||
This patch adds the nodes to enable HDMI, CEC and CVBS functionnalities.
|
||||
|
||||
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
||||
---
|
||||
.../boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 48 +++++++++++++++++++
|
||||
1 file changed, 48 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
|
||||
index 7d5709c37e95..cbe99bd4e06d 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
|
||||
@@ -106,6 +106,42 @@
|
||||
compatible = "mmc-pwrseq-emmc";
|
||||
reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
+
|
||||
+ /* CVBS is available on CON1 pin 36, disabled by default */
|
||||
+ cvbs-connector {
|
||||
+ compatible = "composite-video-connector";
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ port {
|
||||
+ cvbs_connector_in: endpoint {
|
||||
+ remote-endpoint = <&cvbs_vdac_out>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ hdmi-connector {
|
||||
+ compatible = "hdmi-connector";
|
||||
+ type = "a";
|
||||
+
|
||||
+ port {
|
||||
+ hdmi_connector_in: endpoint {
|
||||
+ remote-endpoint = <&hdmi_tx_tmds_out>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&cec_AO {
|
||||
+ status = "okay";
|
||||
+ pinctrl-0 = <&ao_cec_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+ hdmi-phandle = <&hdmi_tx>;
|
||||
+};
|
||||
+
|
||||
+&cvbs_vdac_port {
|
||||
+ cvbs_vdac_out: endpoint {
|
||||
+ remote-endpoint = <&cvbs_connector_in>;
|
||||
+ };
|
||||
};
|
||||
|
||||
ðmac {
|
||||
@@ -137,6 +173,18 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&hdmi_tx {
|
||||
+ status = "okay";
|
||||
+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
|
||||
+ pinctrl-names = "default";
|
||||
+};
|
||||
+
|
||||
+&hdmi_tx_tmds_port {
|
||||
+ hdmi_tx_tmds_out: endpoint {
|
||||
+ remote-endpoint = <&hdmi_connector_in>;
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
&ir {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&remote_input_ao_pins>;
|
||||
--
|
||||
2.18.0
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
From 8efe6ad5f651af4dd687449a70c337631324b65d Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Mon, 13 Nov 2017 12:09:40 +0100
|
||||
Subject: [PATCH 04/21] 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 f9a186f6af8a..25846051b6b5 100644
|
||||
--- a/arch/arm64/configs/defconfig
|
||||
+++ b/arch/arm64/configs/defconfig
|
||||
@@ -402,6 +402,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
|
||||
@@ -411,6 +412,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_NOUVEAU=m
|
||||
CONFIG_DRM_EXYNOS=m
|
||||
@@ -431,6 +434,7 @@ CONFIG_DRM_RCAR_LVDS=m
|
||||
CONFIG_DRM_TEGRA=m
|
||||
CONFIG_DRM_PANEL_SIMPLE=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.18.0
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
From 7673bee05a11e0d316f56cd3e2f21d4407052fc4 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Tue, 19 Jun 2018 18:14:49 +0200
|
||||
Subject: [PATCH 05/21] clk: meson: switch gxbb cts-amclk div to the generic
|
||||
divider
|
||||
|
||||
clk-audio-divider was a (poor) attempt to use CCF rate propagation
|
||||
while making sure the PLL rate would be high enough to work with
|
||||
audio use cases. The result is far from optimal. We can do better
|
||||
by carefully choosing the PLL rates for the audio use cases.
|
||||
Doing so, we don't need to use clk-audio-divider anymore. The
|
||||
generic will do
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
drivers/clk/meson/gxbb.c | 12 +++++-------
|
||||
1 file changed, 5 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c
|
||||
index 177fffb9ebef..69a58cbb29ee 100644
|
||||
--- a/drivers/clk/meson/gxbb.c
|
||||
+++ b/drivers/clk/meson/gxbb.c
|
||||
@@ -982,17 +982,15 @@ static struct clk_regmap gxbb_cts_amclk_sel = {
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_cts_amclk_div = {
|
||||
- .data = &(struct meson_clk_audio_div_data){
|
||||
- .div = {
|
||||
- .reg_off = HHI_AUD_CLK_CNTL,
|
||||
- .shift = 0,
|
||||
- .width = 8,
|
||||
- },
|
||||
+ .data = &(struct clk_regmap_div_data) {
|
||||
+ .offset = HHI_AUD_CLK_CNTL,
|
||||
+ .shift = 0,
|
||||
+ .width = 8,
|
||||
.flags = CLK_DIVIDER_ROUND_CLOSEST,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "cts_amclk_div",
|
||||
- .ops = &meson_clk_audio_divider_ops,
|
||||
+ .ops = &clk_regmap_divider_ops,
|
||||
.parent_names = (const char *[]){ "cts_amclk_sel" },
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
From ddbc6160b2cfa047c963077baae58b314e6f21e3 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Tue, 19 Jun 2018 18:23:28 +0200
|
||||
Subject: [PATCH 06/21] clk: meson: remove unused clk-audio-divider driver
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
drivers/clk/meson/Makefile | 2 +-
|
||||
drivers/clk/meson/clkc.h | 7 -------
|
||||
2 files changed, 1 insertion(+), 8 deletions(-)
|
||||
|
||||
diff --git a/drivers/clk/meson/Makefile b/drivers/clk/meson/Makefile
|
||||
index d0d13aeb369a..e40fea96069b 100644
|
||||
--- a/drivers/clk/meson/Makefile
|
||||
+++ b/drivers/clk/meson/Makefile
|
||||
@@ -2,7 +2,7 @@
|
||||
# Makefile for Meson specific clk
|
||||
#
|
||||
|
||||
-obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o clk-audio-divider.o
|
||||
+obj-$(CONFIG_COMMON_CLK_AMLOGIC) += clk-pll.o clk-mpll.o
|
||||
obj-$(CONFIG_COMMON_CLK_MESON_AO) += meson-aoclk.o
|
||||
obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
|
||||
obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o gxbb-aoclk-32k.o
|
||||
diff --git a/drivers/clk/meson/clkc.h b/drivers/clk/meson/clkc.h
|
||||
index 2fb084330ee9..48db02424f02 100644
|
||||
--- a/drivers/clk/meson/clkc.h
|
||||
+++ b/drivers/clk/meson/clkc.h
|
||||
@@ -91,11 +91,6 @@ struct meson_clk_mpll_data {
|
||||
|
||||
#define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0)
|
||||
|
||||
-struct meson_clk_audio_div_data {
|
||||
- struct parm div;
|
||||
- u8 flags;
|
||||
-};
|
||||
-
|
||||
#define MESON_GATE(_name, _reg, _bit) \
|
||||
struct clk_regmap _name = { \
|
||||
.data = &(struct clk_regmap_gate_data){ \
|
||||
@@ -117,7 +112,5 @@ extern const struct clk_ops meson_clk_pll_ops;
|
||||
extern const struct clk_ops meson_clk_cpu_ops;
|
||||
extern const struct clk_ops meson_clk_mpll_ro_ops;
|
||||
extern const struct clk_ops meson_clk_mpll_ops;
|
||||
-extern const struct clk_ops meson_clk_audio_divider_ro_ops;
|
||||
-extern const struct clk_ops meson_clk_audio_divider_ops;
|
||||
|
||||
#endif /* __CLKC_H */
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,311 @@
|
||||
From 6486fe80144b88cfe65e581b53c01e54afa9ba59 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Thu, 30 Mar 2017 11:49:55 +0200
|
||||
Subject: [PATCH 07/21] ASoC: meson: add meson audio core driver
|
||||
|
||||
This patch adds support for the audio core driver for the Amlogic Meson SoC
|
||||
family. The purpose of this driver is to properly reset the audio block and
|
||||
provide register access for the different devices scattered in this address
|
||||
space. This includes output and input DMAs, pcm, i2s and spdif dai, card
|
||||
level routing, internal codec for the gxl variant
|
||||
|
||||
For more information, please refer to the section 5 of the public datasheet
|
||||
of the S905 (gxbb). This datasheet is available here: [0].
|
||||
|
||||
[0]: http://dn.odroid.com/S905/DataSheet/S905_Public_Datasheet_V1.1.4.pdf
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
sound/soc/Kconfig | 1 +
|
||||
sound/soc/Makefile | 1 +
|
||||
sound/soc/meson/Kconfig | 9 ++
|
||||
sound/soc/meson/Makefile | 3 +
|
||||
sound/soc/meson/audio-core.c | 190 +++++++++++++++++++++++++++++++++++
|
||||
sound/soc/meson/audio-core.h | 28 ++++++
|
||||
6 files changed, 232 insertions(+)
|
||||
create mode 100644 sound/soc/meson/Kconfig
|
||||
create mode 100644 sound/soc/meson/Makefile
|
||||
create mode 100644 sound/soc/meson/audio-core.c
|
||||
create mode 100644 sound/soc/meson/audio-core.h
|
||||
|
||||
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
|
||||
index 41af6b9cc350..1cf11cf51e1d 100644
|
||||
--- a/sound/soc/Kconfig
|
||||
+++ b/sound/soc/Kconfig
|
||||
@@ -57,6 +57,7 @@ source "sound/soc/kirkwood/Kconfig"
|
||||
source "sound/soc/img/Kconfig"
|
||||
source "sound/soc/intel/Kconfig"
|
||||
source "sound/soc/mediatek/Kconfig"
|
||||
+source "sound/soc/meson/Kconfig"
|
||||
source "sound/soc/mxs/Kconfig"
|
||||
source "sound/soc/pxa/Kconfig"
|
||||
source "sound/soc/qcom/Kconfig"
|
||||
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
|
||||
index 06389a5385d7..62a5f87c3cfc 100644
|
||||
--- a/sound/soc/Makefile
|
||||
+++ b/sound/soc/Makefile
|
||||
@@ -38,6 +38,7 @@ obj-$(CONFIG_SND_SOC) += jz4740/
|
||||
obj-$(CONFIG_SND_SOC) += img/
|
||||
obj-$(CONFIG_SND_SOC) += intel/
|
||||
obj-$(CONFIG_SND_SOC) += mediatek/
|
||||
+obj-$(CONFIG_SND_SOC) += meson/
|
||||
obj-$(CONFIG_SND_SOC) += mxs/
|
||||
obj-$(CONFIG_SND_SOC) += nuc900/
|
||||
obj-$(CONFIG_SND_SOC) += omap/
|
||||
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
|
||||
new file mode 100644
|
||||
index 000000000000..ca0e3e981a99
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/meson/Kconfig
|
||||
@@ -0,0 +1,9 @@
|
||||
+menuconfig SND_SOC_MESON
|
||||
+ tristate "ASoC support for Amlogic Meson SoCs"
|
||||
+ depends on ARCH_MESON
|
||||
+ select MFD_CORE
|
||||
+ select REGMAP_MMIO
|
||||
+ help
|
||||
+ Say Y or M if you want to add support for codecs attached to
|
||||
+ the Amlogic Meson SoCs Audio interfaces. You will also need to
|
||||
+ select the audio interfaces to support below.
|
||||
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
|
||||
new file mode 100644
|
||||
index 000000000000..22028abb5624
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/meson/Makefile
|
||||
@@ -0,0 +1,3 @@
|
||||
+snd-soc-meson-audio-core-objs := audio-core.o
|
||||
+
|
||||
+obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
|
||||
diff --git a/sound/soc/meson/audio-core.c b/sound/soc/meson/audio-core.c
|
||||
new file mode 100644
|
||||
index 000000000000..99993ec4a5cc
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/meson/audio-core.c
|
||||
@@ -0,0 +1,190 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2017 BayLibre, SAS
|
||||
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
|
||||
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/mfd/core.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/reset.h>
|
||||
+
|
||||
+#include "audio-core.h"
|
||||
+
|
||||
+#define DRV_NAME "meson-audio-core"
|
||||
+
|
||||
+static const char * const acore_clock_names[] = { "aiu_top",
|
||||
+ "aiu_glue",
|
||||
+ "audin" };
|
||||
+
|
||||
+static int meson_acore_init_clocks(struct device *dev)
|
||||
+{
|
||||
+ struct clk *clock;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(acore_clock_names); i++) {
|
||||
+ clock = devm_clk_get(dev, acore_clock_names[i]);
|
||||
+ if (IS_ERR(clock)) {
|
||||
+ if (PTR_ERR(clock) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Failed to get %s clock\n",
|
||||
+ acore_clock_names[i]);
|
||||
+ return PTR_ERR(clock);
|
||||
+ }
|
||||
+
|
||||
+ ret = clk_prepare_enable(clock);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Failed to enable %s clock\n",
|
||||
+ acore_clock_names[i]);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = devm_add_action_or_reset(dev,
|
||||
+ (void(*)(void *))clk_disable_unprepare,
|
||||
+ clock);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const char * const acore_reset_names[] = { "aiu",
|
||||
+ "audin" };
|
||||
+
|
||||
+static int meson_acore_init_resets(struct device *dev)
|
||||
+{
|
||||
+ struct reset_control *reset;
|
||||
+ int i, ret;
|
||||
+
|
||||
+ for (i = 0; i < ARRAY_SIZE(acore_reset_names); i++) {
|
||||
+ reset = devm_reset_control_get_exclusive(dev,
|
||||
+ acore_reset_names[i]);
|
||||
+ if (IS_ERR(reset)) {
|
||||
+ if (PTR_ERR(reset) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Failed to get %s reset\n",
|
||||
+ acore_reset_names[i]);
|
||||
+ return PTR_ERR(reset);
|
||||
+ }
|
||||
+
|
||||
+ ret = reset_control_reset(reset);
|
||||
+ if (ret) {
|
||||
+ dev_err(dev, "Failed to pulse %s reset\n",
|
||||
+ acore_reset_names[i]);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct regmap_config meson_acore_regmap_config = {
|
||||
+ .reg_bits = 32,
|
||||
+ .val_bits = 32,
|
||||
+ .reg_stride = 4,
|
||||
+};
|
||||
+
|
||||
+static const struct mfd_cell meson_acore_devs[] = {
|
||||
+ {
|
||||
+ .name = "meson-i2s-dai",
|
||||
+ .of_compatible = "amlogic,meson-i2s-dai",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "meson-spdif-dai",
|
||||
+ .of_compatible = "amlogic,meson-spdif-dai",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "meson-aiu-i2s-dma",
|
||||
+ .of_compatible = "amlogic,meson-aiu-i2s-dma",
|
||||
+ },
|
||||
+ {
|
||||
+ .name = "meson-aiu-spdif-dma",
|
||||
+ .of_compatible = "amlogic,meson-aiu-spdif-dma",
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+static int meson_acore_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct meson_audio_core_data *data;
|
||||
+ struct resource *res;
|
||||
+ void __iomem *regs;
|
||||
+ int ret;
|
||||
+
|
||||
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
|
||||
+ if (!data)
|
||||
+ return -ENOMEM;
|
||||
+ platform_set_drvdata(pdev, data);
|
||||
+
|
||||
+ ret = meson_acore_init_clocks(dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = meson_acore_init_resets(dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "aiu");
|
||||
+ regs = devm_ioremap_resource(dev, res);
|
||||
+ if (IS_ERR(regs))
|
||||
+ return PTR_ERR(regs);
|
||||
+
|
||||
+ data->aiu = devm_regmap_init_mmio(dev, regs,
|
||||
+ &meson_acore_regmap_config);
|
||||
+ if (IS_ERR(data->aiu)) {
|
||||
+ dev_err(dev, "Couldn't create the AIU regmap\n");
|
||||
+ return PTR_ERR(data->aiu);
|
||||
+ }
|
||||
+
|
||||
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "audin");
|
||||
+ regs = devm_ioremap_resource(dev, res);
|
||||
+ if (IS_ERR(regs))
|
||||
+ return PTR_ERR(regs);
|
||||
+
|
||||
+ data->audin = devm_regmap_init_mmio(dev, regs,
|
||||
+ &meson_acore_regmap_config);
|
||||
+ if (IS_ERR(data->audin)) {
|
||||
+ dev_err(dev, "Couldn't create the AUDIN regmap\n");
|
||||
+ return PTR_ERR(data->audin);
|
||||
+ }
|
||||
+
|
||||
+ return devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, meson_acore_devs,
|
||||
+ ARRAY_SIZE(meson_acore_devs), NULL, 0,
|
||||
+ NULL);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id meson_acore_of_match[] = {
|
||||
+ { .compatible = "amlogic,meson-audio-core", },
|
||||
+ { .compatible = "amlogic,meson-gxbb-audio-core", },
|
||||
+ { .compatible = "amlogic,meson-gxl-audio-core", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, meson_acore_of_match);
|
||||
+
|
||||
+static struct platform_driver meson_acore_pdrv = {
|
||||
+ .probe = meson_acore_probe,
|
||||
+ .driver = {
|
||||
+ .name = DRV_NAME,
|
||||
+ .of_match_table = meson_acore_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(meson_acore_pdrv);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Meson Audio Core Driver");
|
||||
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
diff --git a/sound/soc/meson/audio-core.h b/sound/soc/meson/audio-core.h
|
||||
new file mode 100644
|
||||
index 000000000000..6e7a24cdc4a9
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/meson/audio-core.h
|
||||
@@ -0,0 +1,28 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2017 BayLibre, SAS
|
||||
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
|
||||
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _MESON_AUDIO_CORE_H_
|
||||
+#define _MESON_AUDIO_CORE_H_
|
||||
+
|
||||
+struct meson_audio_core_data {
|
||||
+ struct regmap *aiu;
|
||||
+ struct regmap *audin;
|
||||
+};
|
||||
+
|
||||
+#endif /* _MESON_AUDIO_CORE_H_ */
|
||||
--
|
||||
2.18.0
|
||||
|
||||
360
patches/mainline/0008-ASoC-meson-add-register-definitions.patch
Normal file
360
patches/mainline/0008-ASoC-meson-add-register-definitions.patch
Normal file
@@ -0,0 +1,360 @@
|
||||
From ef9065cecd78f62b97e5301b4489929119c9aabc Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Thu, 30 Mar 2017 12:00:10 +0200
|
||||
Subject: [PATCH 08/21] ASoC: meson: add register definitions
|
||||
|
||||
Add the register definition for the AIU and AUDIN blocks
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
sound/soc/meson/aiu-regs.h | 182 +++++++++++++++++++++++++++++++++++
|
||||
sound/soc/meson/audin-regs.h | 148 ++++++++++++++++++++++++++++
|
||||
2 files changed, 330 insertions(+)
|
||||
create mode 100644 sound/soc/meson/aiu-regs.h
|
||||
create mode 100644 sound/soc/meson/audin-regs.h
|
||||
|
||||
diff --git a/sound/soc/meson/aiu-regs.h b/sound/soc/meson/aiu-regs.h
|
||||
new file mode 100644
|
||||
index 000000000000..67391e64fe1c
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/meson/aiu-regs.h
|
||||
@@ -0,0 +1,182 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2017 BayLibre, SAS
|
||||
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
|
||||
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _AIU_REGS_H_
|
||||
+#define _AIU_REGS_H_
|
||||
+
|
||||
+#define AIU_958_BPF 0x000
|
||||
+#define AIU_958_BRST 0x004
|
||||
+#define AIU_958_LENGTH 0x008
|
||||
+#define AIU_958_PADDSIZE 0x00C
|
||||
+#define AIU_958_MISC 0x010
|
||||
+#define AIU_958_FORCE_LEFT 0x014 /* Unknown */
|
||||
+#define AIU_958_DISCARD_NUM 0x018
|
||||
+#define AIU_958_DCU_FF_CTRL 0x01C
|
||||
+#define AIU_958_CHSTAT_L0 0x020
|
||||
+#define AIU_958_CHSTAT_L1 0x024
|
||||
+#define AIU_958_CTRL 0x028
|
||||
+#define AIU_958_RPT 0x02C
|
||||
+#define AIU_I2S_MUTE_SWAP 0x030
|
||||
+#define AIU_I2S_SOURCE_DESC 0x034
|
||||
+#define AIU_I2S_MED_CTRL 0x038
|
||||
+#define AIU_I2S_MED_THRESH 0x03C
|
||||
+#define AIU_I2S_DAC_CFG 0x040
|
||||
+#define AIU_I2S_SYNC 0x044 /* Unknown */
|
||||
+#define AIU_I2S_MISC 0x048
|
||||
+#define AIU_I2S_OUT_CFG 0x04C
|
||||
+#define AIU_I2S_FF_CTRL 0x050 /* Unknown */
|
||||
+#define AIU_RST_SOFT 0x054
|
||||
+#define AIU_CLK_CTRL 0x058
|
||||
+#define AIU_MIX_ADCCFG 0x05C
|
||||
+#define AIU_MIX_CTRL 0x060
|
||||
+#define AIU_CLK_CTRL_MORE 0x064
|
||||
+#define AIU_958_POP 0x068
|
||||
+#define AIU_MIX_GAIN 0x06C
|
||||
+#define AIU_958_SYNWORD1 0x070
|
||||
+#define AIU_958_SYNWORD2 0x074
|
||||
+#define AIU_958_SYNWORD3 0x078
|
||||
+#define AIU_958_SYNWORD1_MASK 0x07C
|
||||
+#define AIU_958_SYNWORD2_MASK 0x080
|
||||
+#define AIU_958_SYNWORD3_MASK 0x084
|
||||
+#define AIU_958_FFRDOUT_THD 0x088
|
||||
+#define AIU_958_LENGTH_PER_PAUSE 0x08C
|
||||
+#define AIU_958_PAUSE_NUM 0x090
|
||||
+#define AIU_958_PAUSE_PAYLOAD 0x094
|
||||
+#define AIU_958_AUTO_PAUSE 0x098
|
||||
+#define AIU_958_PAUSE_PD_LENGTH 0x09C
|
||||
+#define AIU_CODEC_DAC_LRCLK_CTRL 0x0A0
|
||||
+#define AIU_CODEC_ADC_LRCLK_CTRL 0x0A4
|
||||
+#define AIU_HDMI_CLK_DATA_CTRL 0x0A8
|
||||
+#define AIU_CODEC_CLK_DATA_CTRL 0x0AC
|
||||
+#define AIU_ACODEC_CTRL 0x0B0
|
||||
+#define AIU_958_CHSTAT_R0 0x0C0
|
||||
+#define AIU_958_CHSTAT_R1 0x0C4
|
||||
+#define AIU_958_VALID_CTRL 0x0C8
|
||||
+#define AIU_AUDIO_AMP_REG0 0x0F0 /* Unknown */
|
||||
+#define AIU_AUDIO_AMP_REG1 0x0F4 /* Unknown */
|
||||
+#define AIU_AUDIO_AMP_REG2 0x0F8 /* Unknown */
|
||||
+#define AIU_AUDIO_AMP_REG3 0x0FC /* Unknown */
|
||||
+#define AIU_AIFIFO2_CTRL 0x100
|
||||
+#define AIU_AIFIFO2_STATUS 0x104
|
||||
+#define AIU_AIFIFO2_GBIT 0x108
|
||||
+#define AIU_AIFIFO2_CLB 0x10C
|
||||
+#define AIU_CRC_CTRL 0x110
|
||||
+#define AIU_CRC_STATUS 0x114
|
||||
+#define AIU_CRC_SHIFT_REG 0x118
|
||||
+#define AIU_CRC_IREG 0x11C
|
||||
+#define AIU_CRC_CAL_REG1 0x120
|
||||
+#define AIU_CRC_CAL_REG0 0x124
|
||||
+#define AIU_CRC_POLY_COEF1 0x128
|
||||
+#define AIU_CRC_POLY_COEF0 0x12C
|
||||
+#define AIU_CRC_BIT_SIZE1 0x130
|
||||
+#define AIU_CRC_BIT_SIZE0 0x134
|
||||
+#define AIU_CRC_BIT_CNT1 0x138
|
||||
+#define AIU_CRC_BIT_CNT0 0x13C
|
||||
+#define AIU_AMCLK_GATE_HI 0x140
|
||||
+#define AIU_AMCLK_GATE_LO 0x144
|
||||
+#define AIU_AMCLK_MSR 0x148
|
||||
+#define AIU_AUDAC_CTRL0 0x14C /* Unknown */
|
||||
+#define AIU_DELTA_SIGMA0 0x154 /* Unknown */
|
||||
+#define AIU_DELTA_SIGMA1 0x158 /* Unknown */
|
||||
+#define AIU_DELTA_SIGMA2 0x15C /* Unknown */
|
||||
+#define AIU_DELTA_SIGMA3 0x160 /* Unknown */
|
||||
+#define AIU_DELTA_SIGMA4 0x164 /* Unknown */
|
||||
+#define AIU_DELTA_SIGMA5 0x168 /* Unknown */
|
||||
+#define AIU_DELTA_SIGMA6 0x16C /* Unknown */
|
||||
+#define AIU_DELTA_SIGMA7 0x170 /* Unknown */
|
||||
+#define AIU_DELTA_SIGMA_LCNTS 0x174 /* Unknown */
|
||||
+#define AIU_DELTA_SIGMA_RCNTS 0x178 /* Unknown */
|
||||
+#define AIU_MEM_I2S_START_PTR 0x180
|
||||
+#define AIU_MEM_I2S_RD_PTR 0x184
|
||||
+#define AIU_MEM_I2S_END_PTR 0x188
|
||||
+#define AIU_MEM_I2S_MASKS 0x18C
|
||||
+#define AIU_MEM_I2S_CONTROL 0x190
|
||||
+#define AIU_MEM_IEC958_START_PTR 0x194
|
||||
+#define AIU_MEM_IEC958_RD_PTR 0x198
|
||||
+#define AIU_MEM_IEC958_END_PTR 0x19C
|
||||
+#define AIU_MEM_IEC958_MASKS 0x1A0
|
||||
+#define AIU_MEM_IEC958_CONTROL 0x1A4
|
||||
+#define AIU_MEM_AIFIFO2_START_PTR 0x1A8
|
||||
+#define AIU_MEM_AIFIFO2_CURR_PTR 0x1AC
|
||||
+#define AIU_MEM_AIFIFO2_END_PTR 0x1B0
|
||||
+#define AIU_MEM_AIFIFO2_BYTES_AVAIL 0x1B4
|
||||
+#define AIU_MEM_AIFIFO2_CONTROL 0x1B8
|
||||
+#define AIU_MEM_AIFIFO2_MAN_WP 0x1BC
|
||||
+#define AIU_MEM_AIFIFO2_MAN_RP 0x1C0
|
||||
+#define AIU_MEM_AIFIFO2_LEVEL 0x1C4
|
||||
+#define AIU_MEM_AIFIFO2_BUF_CNTL 0x1C8
|
||||
+#define AIU_MEM_I2S_MAN_WP 0x1CC
|
||||
+#define AIU_MEM_I2S_MAN_RP 0x1D0
|
||||
+#define AIU_MEM_I2S_LEVEL 0x1D4
|
||||
+#define AIU_MEM_I2S_BUF_CNTL 0x1D8
|
||||
+#define AIU_MEM_I2S_BUF_WRAP_COUNT 0x1DC
|
||||
+#define AIU_MEM_I2S_MEM_CTL 0x1E0
|
||||
+#define AIU_MEM_IEC958_MEM_CTL 0x1E4
|
||||
+#define AIU_MEM_IEC958_WRAP_COUNT 0x1E8
|
||||
+#define AIU_MEM_IEC958_IRQ_LEVEL 0x1EC
|
||||
+#define AIU_MEM_IEC958_MAN_WP 0x1F0
|
||||
+#define AIU_MEM_IEC958_MAN_RP 0x1F4
|
||||
+#define AIU_MEM_IEC958_LEVEL 0x1F8
|
||||
+#define AIU_MEM_IEC958_BUF_CNTL 0x1FC
|
||||
+#define AIU_AIFIFO_CTRL 0x200
|
||||
+#define AIU_AIFIFO_STATUS 0x204
|
||||
+#define AIU_AIFIFO_GBIT 0x208
|
||||
+#define AIU_AIFIFO_CLB 0x20C
|
||||
+#define AIU_MEM_AIFIFO_START_PTR 0x210
|
||||
+#define AIU_MEM_AIFIFO_CURR_PTR 0x214
|
||||
+#define AIU_MEM_AIFIFO_END_PTR 0x218
|
||||
+#define AIU_MEM_AIFIFO_BYTES_AVAIL 0x21C
|
||||
+#define AIU_MEM_AIFIFO_CONTROL 0x220
|
||||
+#define AIU_MEM_AIFIFO_MAN_WP 0x224
|
||||
+#define AIU_MEM_AIFIFO_MAN_RP 0x228
|
||||
+#define AIU_MEM_AIFIFO_LEVEL 0x22C
|
||||
+#define AIU_MEM_AIFIFO_BUF_CNTL 0x230
|
||||
+#define AIU_MEM_AIFIFO_BUF_WRAP_COUNT 0x234
|
||||
+#define AIU_MEM_AIFIFO2_BUF_WRAP_COUNT 0x238
|
||||
+#define AIU_MEM_AIFIFO_MEM_CTL 0x23C
|
||||
+#define AIFIFO_TIME_STAMP_CNTL 0x240
|
||||
+#define AIFIFO_TIME_STAMP_SYNC_0 0x244
|
||||
+#define AIFIFO_TIME_STAMP_SYNC_1 0x248
|
||||
+#define AIFIFO_TIME_STAMP_0 0x24C
|
||||
+#define AIFIFO_TIME_STAMP_1 0x250
|
||||
+#define AIFIFO_TIME_STAMP_2 0x254
|
||||
+#define AIFIFO_TIME_STAMP_3 0x258
|
||||
+#define AIFIFO_TIME_STAMP_LENGTH 0x25C
|
||||
+#define AIFIFO2_TIME_STAMP_CNTL 0x260
|
||||
+#define AIFIFO2_TIME_STAMP_SYNC_0 0x264
|
||||
+#define AIFIFO2_TIME_STAMP_SYNC_1 0x268
|
||||
+#define AIFIFO2_TIME_STAMP_0 0x26C
|
||||
+#define AIFIFO2_TIME_STAMP_1 0x270
|
||||
+#define AIFIFO2_TIME_STAMP_2 0x274
|
||||
+#define AIFIFO2_TIME_STAMP_3 0x278
|
||||
+#define AIFIFO2_TIME_STAMP_LENGTH 0x27C
|
||||
+#define IEC958_TIME_STAMP_CNTL 0x280
|
||||
+#define IEC958_TIME_STAMP_SYNC_0 0x284
|
||||
+#define IEC958_TIME_STAMP_SYNC_1 0x288
|
||||
+#define IEC958_TIME_STAMP_0 0x28C
|
||||
+#define IEC958_TIME_STAMP_1 0x290
|
||||
+#define IEC958_TIME_STAMP_2 0x294
|
||||
+#define IEC958_TIME_STAMP_3 0x298
|
||||
+#define IEC958_TIME_STAMP_LENGTH 0x29C
|
||||
+#define AIU_MEM_AIFIFO2_MEM_CTL 0x2A0
|
||||
+#define AIU_I2S_CBUS_DDR_CNTL 0x2A4
|
||||
+#define AIU_I2S_CBUS_DDR_WDATA 0x2A8
|
||||
+#define AIU_I2S_CBUS_DDR_ADDR 0x2AC
|
||||
+
|
||||
+#endif /* _AIU_REGS_H_ */
|
||||
diff --git a/sound/soc/meson/audin-regs.h b/sound/soc/meson/audin-regs.h
|
||||
new file mode 100644
|
||||
index 000000000000..f224610e80e7
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/meson/audin-regs.h
|
||||
@@ -0,0 +1,148 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2017 BayLibre, SAS
|
||||
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
|
||||
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef _AUDIN_REGS_H_
|
||||
+#define _AUDIN_REGS_H_
|
||||
+
|
||||
+/*
|
||||
+ * Note :
|
||||
+ * Datasheet issue page 196
|
||||
+ * AUDIN_MUTE_VAL 0x35 => impossible: Already assigned to AUDIN_FIFO1_PTR
|
||||
+ * AUDIN_FIFO1_PTR is more likely to be correct here since surrounding registers
|
||||
+ * also deal with AUDIN_FIFO1
|
||||
+ *
|
||||
+ * Clarification needed from Amlogic
|
||||
+ */
|
||||
+
|
||||
+#define AUDIN_SPDIF_MODE 0x000
|
||||
+#define AUDIN_SPDIF_FS_CLK_RLTN 0x004
|
||||
+#define AUDIN_SPDIF_CHNL_STS_A 0x008
|
||||
+#define AUDIN_SPDIF_CHNL_STS_B 0x00C
|
||||
+#define AUDIN_SPDIF_MISC 0x010
|
||||
+#define AUDIN_SPDIF_NPCM_PCPD 0x014
|
||||
+#define AUDIN_SPDIF_END 0x03C /* Unknown */
|
||||
+#define AUDIN_I2SIN_CTRL 0x040
|
||||
+#define AUDIN_SOURCE_SEL 0x044
|
||||
+#define AUDIN_DECODE_FORMAT 0x048
|
||||
+#define AUDIN_DECODE_CONTROL_STATUS 0x04C
|
||||
+#define AUDIN_DECODE_CHANNEL_STATUS_A_0 0x050
|
||||
+#define AUDIN_DECODE_CHANNEL_STATUS_A_1 0x054
|
||||
+#define AUDIN_DECODE_CHANNEL_STATUS_A_2 0x058
|
||||
+#define AUDIN_DECODE_CHANNEL_STATUS_A_3 0x05C
|
||||
+#define AUDIN_DECODE_CHANNEL_STATUS_A_4 0x060
|
||||
+#define AUDIN_DECODE_CHANNEL_STATUS_A_5 0x064
|
||||
+#define AUDIN_FIFO0_START 0x080
|
||||
+#define AUDIN_FIFO0_END 0x084
|
||||
+#define AUDIN_FIFO0_PTR 0x088
|
||||
+#define AUDIN_FIFO0_INTR 0x08C
|
||||
+#define AUDIN_FIFO0_RDPTR 0x090
|
||||
+#define AUDIN_FIFO0_CTRL 0x094
|
||||
+#define AUDIN_FIFO0_CTRL1 0x098
|
||||
+#define AUDIN_FIFO0_LVL0 0x09C
|
||||
+#define AUDIN_FIFO0_LVL1 0x0A0
|
||||
+#define AUDIN_FIFO0_LVL2 0x0A4
|
||||
+#define AUDIN_FIFO0_REQID 0x0C0
|
||||
+#define AUDIN_FIFO0_WRAP 0x0C4
|
||||
+#define AUDIN_FIFO1_START 0x0CC
|
||||
+#define AUDIN_FIFO1_END 0x0D0
|
||||
+#define AUDIN_FIFO1_PTR 0x0D4
|
||||
+#define AUDIN_FIFO1_INTR 0x0D8
|
||||
+#define AUDIN_FIFO1_RDPTR 0x0DC
|
||||
+#define AUDIN_FIFO1_CTRL 0x0E0
|
||||
+#define AUDIN_FIFO1_CTRL1 0x0E4
|
||||
+#define AUDIN_FIFO1_LVL0 0x100
|
||||
+#define AUDIN_FIFO1_LVL1 0x104
|
||||
+#define AUDIN_FIFO1_LVL2 0x108
|
||||
+#define AUDIN_FIFO1_REQID 0x10C
|
||||
+#define AUDIN_FIFO1_WRAP 0x110
|
||||
+#define AUDIN_FIFO2_START 0x114
|
||||
+#define AUDIN_FIFO2_END 0x118
|
||||
+#define AUDIN_FIFO2_PTR 0x11C
|
||||
+#define AUDIN_FIFO2_INTR 0x120
|
||||
+#define AUDIN_FIFO2_RDPTR 0x124
|
||||
+#define AUDIN_FIFO2_CTRL 0x128
|
||||
+#define AUDIN_FIFO2_CTRL1 0x12C
|
||||
+#define AUDIN_FIFO2_LVL0 0x130
|
||||
+#define AUDIN_FIFO2_LVL1 0x134
|
||||
+#define AUDIN_FIFO2_LVL2 0x138
|
||||
+#define AUDIN_FIFO2_REQID 0x13C
|
||||
+#define AUDIN_FIFO2_WRAP 0x140
|
||||
+#define AUDIN_INT_CTRL 0x144
|
||||
+#define AUDIN_FIFO_INT 0x148
|
||||
+#define PCMIN_CTRL0 0x180
|
||||
+#define PCMIN_CTRL1 0x184
|
||||
+#define PCMIN1_CTRL0 0x188
|
||||
+#define PCMIN1_CTRL1 0x18C
|
||||
+#define PCMOUT_CTRL0 0x1C0
|
||||
+#define PCMOUT_CTRL1 0x1C4
|
||||
+#define PCMOUT_CTRL2 0x1C8
|
||||
+#define PCMOUT_CTRL3 0x1CC
|
||||
+#define PCMOUT1_CTRL0 0x1D0
|
||||
+#define PCMOUT1_CTRL1 0x1D4
|
||||
+#define PCMOUT1_CTRL2 0x1D8
|
||||
+#define PCMOUT1_CTRL3 0x1DC
|
||||
+#define AUDOUT_CTRL 0x200
|
||||
+#define AUDOUT_CTRL1 0x204
|
||||
+#define AUDOUT_BUF0_STA 0x208
|
||||
+#define AUDOUT_BUF0_EDA 0x20C
|
||||
+#define AUDOUT_BUF0_WPTR 0x210
|
||||
+#define AUDOUT_BUF1_STA 0x214
|
||||
+#define AUDOUT_BUF1_EDA 0x218
|
||||
+#define AUDOUT_BUF1_WPTR 0x21C
|
||||
+#define AUDOUT_FIFO_RPTR 0x220
|
||||
+#define AUDOUT_INTR_PTR 0x224
|
||||
+#define AUDOUT_FIFO_STS 0x228
|
||||
+#define AUDOUT1_CTRL 0x240
|
||||
+#define AUDOUT1_CTRL1 0x244
|
||||
+#define AUDOUT1_BUF0_STA 0x248
|
||||
+#define AUDOUT1_BUF0_EDA 0x24C
|
||||
+#define AUDOUT1_BUF0_WPTR 0x250
|
||||
+#define AUDOUT1_BUF1_STA 0x254
|
||||
+#define AUDOUT1_BUF1_EDA 0x258
|
||||
+#define AUDOUT1_BUF1_WPTR 0x25C
|
||||
+#define AUDOUT1_FIFO_RPTR 0x260
|
||||
+#define AUDOUT1_INTR_PTR 0x264
|
||||
+#define AUDOUT1_FIFO_STS 0x268
|
||||
+#define AUDIN_HDMI_MEAS_CTRL 0x280
|
||||
+#define AUDIN_HDMI_MEAS_CYCLES_M1 0x284
|
||||
+#define AUDIN_HDMI_MEAS_INTR_MASKN 0x288
|
||||
+#define AUDIN_HDMI_MEAS_INTR_STAT 0x28C
|
||||
+#define AUDIN_HDMI_REF_CYCLES_STAT_0 0x290
|
||||
+#define AUDIN_HDMI_REF_CYCLES_STAT_1 0x294
|
||||
+#define AUDIN_HDMIRX_AFIFO_STAT 0x298
|
||||
+#define AUDIN_FIFO0_PIO_STS 0x2C0
|
||||
+#define AUDIN_FIFO0_PIO_RDL 0x2C4
|
||||
+#define AUDIN_FIFO0_PIO_RDH 0x2C8
|
||||
+#define AUDIN_FIFO1_PIO_STS 0x2CC
|
||||
+#define AUDIN_FIFO1_PIO_RDL 0x2D0
|
||||
+#define AUDIN_FIFO1_PIO_RDH 0x2D4
|
||||
+#define AUDIN_FIFO2_PIO_STS 0x2D8
|
||||
+#define AUDIN_FIFO2_PIO_RDL 0x2DC
|
||||
+#define AUDIN_FIFO2_PIO_RDH 0x2E0
|
||||
+#define AUDOUT_FIFO_PIO_STS 0x2E4
|
||||
+#define AUDOUT_FIFO_PIO_WRL 0x2E8
|
||||
+#define AUDOUT_FIFO_PIO_WRH 0x2EC
|
||||
+#define AUDOUT1_FIFO_PIO_STS 0x2F0 /* Unknown */
|
||||
+#define AUDOUT1_FIFO_PIO_WRL 0x2F4 /* Unknown */
|
||||
+#define AUDOUT1_FIFO_PIO_WRH 0x2F8 /* Unknown */
|
||||
+#define AUD_RESAMPLE_CTRL0 0x2FC
|
||||
+#define AUD_RESAMPLE_CTRL1 0x300
|
||||
+#define AUD_RESAMPLE_STATUS 0x304
|
||||
+
|
||||
+#endif /* _AUDIN_REGS_H_ */
|
||||
--
|
||||
2.18.0
|
||||
|
||||
419
patches/mainline/0009-ASoC-meson-add-aiu-i2s-dma-support.patch
Normal file
419
patches/mainline/0009-ASoC-meson-add-aiu-i2s-dma-support.patch
Normal file
@@ -0,0 +1,419 @@
|
||||
From 5141d439ad763571f6ad26e7aa52b9aabea1816a Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Thu, 30 Mar 2017 12:14:40 +0200
|
||||
Subject: [PATCH 09/21] ASoC: meson: add aiu i2s dma support
|
||||
|
||||
Add support for the i2s output dma which is part of the AIU block
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
sound/soc/meson/Kconfig | 7 +
|
||||
sound/soc/meson/Makefile | 2 +
|
||||
sound/soc/meson/aiu-i2s-dma.c | 370 ++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 379 insertions(+)
|
||||
create mode 100644 sound/soc/meson/aiu-i2s-dma.c
|
||||
|
||||
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
|
||||
index ca0e3e981a99..88fbfc264146 100644
|
||||
--- a/sound/soc/meson/Kconfig
|
||||
+++ b/sound/soc/meson/Kconfig
|
||||
@@ -7,3 +7,10 @@ menuconfig SND_SOC_MESON
|
||||
Say Y or M if you want to add support for codecs attached to
|
||||
the Amlogic Meson SoCs Audio interfaces. You will also need to
|
||||
select the audio interfaces to support below.
|
||||
+
|
||||
+config SND_SOC_MESON_I2S
|
||||
+ tristate "Meson i2s interface"
|
||||
+ depends on SND_SOC_MESON
|
||||
+ help
|
||||
+ Say Y or M if you want to add support for i2s dma driver for Amlogic
|
||||
+ Meson SoCs.
|
||||
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
|
||||
index 22028abb5624..273f27590773 100644
|
||||
--- a/sound/soc/meson/Makefile
|
||||
+++ b/sound/soc/meson/Makefile
|
||||
@@ -1,3 +1,5 @@
|
||||
snd-soc-meson-audio-core-objs := audio-core.o
|
||||
+snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
|
||||
+obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
|
||||
diff --git a/sound/soc/meson/aiu-i2s-dma.c b/sound/soc/meson/aiu-i2s-dma.c
|
||||
new file mode 100644
|
||||
index 000000000000..2684bd0db19e
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/meson/aiu-i2s-dma.c
|
||||
@@ -0,0 +1,370 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2017 BayLibre, SAS
|
||||
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
|
||||
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+#include <sound/pcm_params.h>
|
||||
+#include <sound/soc.h>
|
||||
+
|
||||
+#include "aiu-regs.h"
|
||||
+#include "audio-core.h"
|
||||
+
|
||||
+#define DRV_NAME "meson-aiu-i2s-dma"
|
||||
+
|
||||
+struct aiu_i2s_dma {
|
||||
+ struct meson_audio_core_data *core;
|
||||
+ struct clk *fast;
|
||||
+ int irq;
|
||||
+};
|
||||
+
|
||||
+#define AIU_MEM_I2S_BUF_CNTL_INIT BIT(0)
|
||||
+#define AIU_MEM_I2S_CONTROL_INIT BIT(0)
|
||||
+#define AIU_MEM_I2S_CONTROL_FILL_EN BIT(1)
|
||||
+#define AIU_MEM_I2S_CONTROL_EMPTY_EN BIT(2)
|
||||
+#define AIU_MEM_I2S_CONTROL_MODE_16BIT BIT(6)
|
||||
+#define AIU_MEM_I2S_CONTROL_BUSY BIT(7)
|
||||
+#define AIU_MEM_I2S_CONTROL_DATA_READY BIT(8)
|
||||
+#define AIU_MEM_I2S_CONTROL_LEVEL_CNTL BIT(9)
|
||||
+#define AIU_MEM_I2S_MASKS_IRQ_BLOCK_MASK GENMASK(31, 16)
|
||||
+#define AIU_MEM_I2S_MASKS_IRQ_BLOCK(n) ((n) << 16)
|
||||
+#define AIU_MEM_I2S_MASKS_CH_MEM_MASK GENMASK(15, 8)
|
||||
+#define AIU_MEM_I2S_MASKS_CH_MEM(ch) ((ch) << 8)
|
||||
+#define AIU_MEM_I2S_MASKS_CH_RD_MASK GENMASK(7, 0)
|
||||
+#define AIU_MEM_I2S_MASKS_CH_RD(ch) ((ch) << 0)
|
||||
+#define AIU_RST_SOFT_I2S_FAST_DOMAIN BIT(0)
|
||||
+#define AIU_RST_SOFT_I2S_SLOW_DOMAIN BIT(1)
|
||||
+
|
||||
+/*
|
||||
+ * The DMA works by i2s "blocks" (or DMA burst). The burst size and the memory
|
||||
+ * layout expected depends on the mode of operation.
|
||||
+ *
|
||||
+ * - Normal mode: The channels are expected to be packed in 32 bytes groups
|
||||
+ * interleaved the buffer. AIU_MEM_I2S_MASKS_CH_MEM is a bitfield representing
|
||||
+ * the channels present in memory. AIU_MEM_I2S_MASKS_CH_MEM represents the
|
||||
+ * channels read by the DMA. This is very flexible but the unsual memory layout
|
||||
+ * makes it less easy to deal with. The burst size is 32 bytes times the number
|
||||
+ * of channels read.
|
||||
+ *
|
||||
+ * - Split mode:
|
||||
+ * Classical channel interleaved frame organisation. In this mode,
|
||||
+ * AIU_MEM_I2S_MASKS_CH_MEM and AIU_MEM_I2S_MASKS_CH_MEM must be set to 0xff and
|
||||
+ * the burst size is fixed to 256 bytes. The input can be either 2 or 8
|
||||
+ * channels.
|
||||
+ *
|
||||
+ * The following driver implements the split mode.
|
||||
+ */
|
||||
+
|
||||
+#define AIU_I2S_DMA_BURST 256
|
||||
+
|
||||
+static struct snd_pcm_hardware aiu_i2s_dma_hw = {
|
||||
+ .info = (SNDRV_PCM_INFO_INTERLEAVED |
|
||||
+ SNDRV_PCM_INFO_MMAP |
|
||||
+ SNDRV_PCM_INFO_MMAP_VALID |
|
||||
+ SNDRV_PCM_INFO_PAUSE),
|
||||
+
|
||||
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
+ SNDRV_PCM_FMTBIT_S24_LE |
|
||||
+ SNDRV_PCM_FMTBIT_S32_LE),
|
||||
+
|
||||
+ /*
|
||||
+ * TODO: The DMA can change the endianness, the msb position
|
||||
+ * and deal with unsigned - support this later on
|
||||
+ */
|
||||
+
|
||||
+ .rate_min = 8000,
|
||||
+ .rate_max = 192000,
|
||||
+ .channels_min = 2,
|
||||
+ .channels_max = 8,
|
||||
+ .period_bytes_min = AIU_I2S_DMA_BURST,
|
||||
+ .period_bytes_max = AIU_I2S_DMA_BURST * 65535,
|
||||
+ .periods_min = 2,
|
||||
+ .periods_max = UINT_MAX,
|
||||
+ .buffer_bytes_max = 1 * 1024 * 1024,
|
||||
+ .fifo_size = 0,
|
||||
+};
|
||||
+
|
||||
+static struct aiu_i2s_dma *aiu_i2s_dma_priv(struct snd_pcm_substream *s)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = s->private_data;
|
||||
+ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
|
||||
+
|
||||
+ return snd_soc_component_get_drvdata(component);
|
||||
+}
|
||||
+
|
||||
+static snd_pcm_uframes_t
|
||||
+aiu_i2s_dma_pointer(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
+ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream);
|
||||
+ unsigned int addr;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_read(priv->core->aiu, AIU_MEM_I2S_RD_PTR,
|
||||
+ &addr);
|
||||
+ if (ret)
|
||||
+ return 0;
|
||||
+
|
||||
+ return bytes_to_frames(runtime, addr - (unsigned int)runtime->dma_addr);
|
||||
+}
|
||||
+
|
||||
+static void __dma_enable(struct aiu_i2s_dma *priv, bool enable)
|
||||
+{
|
||||
+ unsigned int en_mask = (AIU_MEM_I2S_CONTROL_FILL_EN |
|
||||
+ AIU_MEM_I2S_CONTROL_EMPTY_EN);
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL, en_mask,
|
||||
+ enable ? en_mask : 0);
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static int aiu_i2s_dma_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
+{
|
||||
+ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream);
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case SNDRV_PCM_TRIGGER_START:
|
||||
+ case SNDRV_PCM_TRIGGER_RESUME:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
+ __dma_enable(priv, true);
|
||||
+ break;
|
||||
+ case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
+ case SNDRV_PCM_TRIGGER_STOP:
|
||||
+ __dma_enable(priv, false);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __dma_init_mem(struct aiu_i2s_dma *priv)
|
||||
+{
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL,
|
||||
+ AIU_MEM_I2S_CONTROL_INIT,
|
||||
+ AIU_MEM_I2S_CONTROL_INIT);
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_BUF_CNTL,
|
||||
+ AIU_MEM_I2S_BUF_CNTL_INIT,
|
||||
+ AIU_MEM_I2S_BUF_CNTL_INIT);
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL,
|
||||
+ AIU_MEM_I2S_CONTROL_INIT,
|
||||
+ 0);
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_BUF_CNTL,
|
||||
+ AIU_MEM_I2S_BUF_CNTL_INIT,
|
||||
+ 0);
|
||||
+}
|
||||
+
|
||||
+static int aiu_i2s_dma_prepare(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream);
|
||||
+
|
||||
+ __dma_init_mem(priv);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aiu_i2s_dma_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params)
|
||||
+{
|
||||
+ struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
+ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream);
|
||||
+ int ret;
|
||||
+ u32 burst_num, mem_ctl;
|
||||
+ dma_addr_t end_ptr;
|
||||
+
|
||||
+ ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Setup memory layout */
|
||||
+ if (params_physical_width(params) == 16)
|
||||
+ mem_ctl = AIU_MEM_I2S_CONTROL_MODE_16BIT;
|
||||
+ else
|
||||
+ mem_ctl = 0;
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_I2S_CONTROL,
|
||||
+ AIU_MEM_I2S_CONTROL_MODE_16BIT,
|
||||
+ mem_ctl);
|
||||
+
|
||||
+ /* Initialize memory pointers */
|
||||
+ regmap_write(priv->core->aiu, AIU_MEM_I2S_START_PTR, runtime->dma_addr);
|
||||
+ regmap_write(priv->core->aiu, AIU_MEM_I2S_RD_PTR, runtime->dma_addr);
|
||||
+
|
||||
+ /* The end pointer is the address of the last valid block */
|
||||
+ end_ptr = runtime->dma_addr + runtime->dma_bytes - AIU_I2S_DMA_BURST;
|
||||
+ regmap_write(priv->core->aiu, AIU_MEM_I2S_END_PTR, end_ptr);
|
||||
+
|
||||
+ /* Memory masks */
|
||||
+ burst_num = params_period_bytes(params) / AIU_I2S_DMA_BURST;
|
||||
+ regmap_write(priv->core->aiu, AIU_MEM_I2S_MASKS,
|
||||
+ AIU_MEM_I2S_MASKS_CH_RD(0xff) |
|
||||
+ AIU_MEM_I2S_MASKS_CH_MEM(0xff) |
|
||||
+ AIU_MEM_I2S_MASKS_IRQ_BLOCK(burst_num));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aiu_i2s_dma_hw_free(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ return snd_pcm_lib_free_pages(substream);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static irqreturn_t aiu_i2s_dma_irq_block(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct snd_pcm_substream *playback = dev_id;
|
||||
+
|
||||
+ snd_pcm_period_elapsed(playback);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int aiu_i2s_dma_open(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream);
|
||||
+ int ret;
|
||||
+
|
||||
+ snd_soc_set_runtime_hwparams(substream, &aiu_i2s_dma_hw);
|
||||
+
|
||||
+ /*
|
||||
+ * Make sure the buffer and period size are multiple of the DMA burst
|
||||
+ * size
|
||||
+ */
|
||||
+ ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
|
||||
+ AIU_I2S_DMA_BURST);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
|
||||
+ AIU_I2S_DMA_BURST);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Request the I2S DDR irq */
|
||||
+ ret = request_irq(priv->irq, aiu_i2s_dma_irq_block, 0,
|
||||
+ DRV_NAME, substream);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Power up the i2s fast domain - can't write the registers w/o it */
|
||||
+ ret = clk_prepare_enable(priv->fast);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Make sure the dma is initially disabled */
|
||||
+ __dma_enable(priv, false);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aiu_i2s_dma_close(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct aiu_i2s_dma *priv = aiu_i2s_dma_priv(substream);
|
||||
+
|
||||
+ clk_disable_unprepare(priv->fast);
|
||||
+ free_irq(priv->irq, substream);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct snd_pcm_ops aiu_i2s_dma_ops = {
|
||||
+ .open = aiu_i2s_dma_open,
|
||||
+ .close = aiu_i2s_dma_close,
|
||||
+ .ioctl = snd_pcm_lib_ioctl,
|
||||
+ .hw_params = aiu_i2s_dma_hw_params,
|
||||
+ .hw_free = aiu_i2s_dma_hw_free,
|
||||
+ .prepare = aiu_i2s_dma_prepare,
|
||||
+ .pointer = aiu_i2s_dma_pointer,
|
||||
+ .trigger = aiu_i2s_dma_trigger,
|
||||
+};
|
||||
+
|
||||
+static int aiu_i2s_dma_new(struct snd_soc_pcm_runtime *rtd)
|
||||
+{
|
||||
+ struct snd_card *card = rtd->card->snd_card;
|
||||
+ size_t size = aiu_i2s_dma_hw.buffer_bytes_max;
|
||||
+
|
||||
+ return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
|
||||
+ SNDRV_DMA_TYPE_DEV,
|
||||
+ card->dev, size, size);
|
||||
+}
|
||||
+
|
||||
+static const struct snd_soc_component_driver aiu_i2s_platform = {
|
||||
+ .ops = &aiu_i2s_dma_ops,
|
||||
+ .pcm_new = aiu_i2s_dma_new,
|
||||
+ .name = DRV_NAME,
|
||||
+};
|
||||
+
|
||||
+static int aiu_i2s_dma_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct aiu_i2s_dma *priv;
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, priv);
|
||||
+ priv->core = dev_get_drvdata(dev->parent);
|
||||
+
|
||||
+ priv->fast = devm_clk_get(dev, "fast");
|
||||
+ if (IS_ERR(priv->fast)) {
|
||||
+ if (PTR_ERR(priv->fast) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Can't get i2s fast domain clock\n");
|
||||
+ return PTR_ERR(priv->fast);
|
||||
+ }
|
||||
+
|
||||
+ priv->irq = platform_get_irq(pdev, 0);
|
||||
+ if (priv->irq <= 0) {
|
||||
+ dev_err(dev, "Can't get i2s ddr irq\n");
|
||||
+ return priv->irq;
|
||||
+ }
|
||||
+
|
||||
+ return devm_snd_soc_register_component(dev, &aiu_i2s_platform,
|
||||
+ NULL, 0);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id aiu_i2s_dma_of_match[] = {
|
||||
+ { .compatible = "amlogic,meson-aiu-i2s-dma", },
|
||||
+ { .compatible = "amlogic,meson-gxbb-aiu-i2s-dma", },
|
||||
+ { .compatible = "amlogic,meson-gxl-aiu-i2s-dma", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, aiu_i2s_dma_of_match);
|
||||
+
|
||||
+static struct platform_driver aiu_i2s_dma_pdrv = {
|
||||
+ .probe = aiu_i2s_dma_probe,
|
||||
+ .driver = {
|
||||
+ .name = DRV_NAME,
|
||||
+ .of_match_table = aiu_i2s_dma_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(aiu_i2s_dma_pdrv);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Meson AIU i2s DMA ASoC Driver");
|
||||
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,514 @@
|
||||
From a5eaab662bb676374fd4275d41f209383ecc9130 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Thu, 30 Mar 2017 12:17:27 +0200
|
||||
Subject: [PATCH 10/21] ASoC: meson: add initial i2s dai support
|
||||
|
||||
Add support for the i2s dai found on Amlogic Meson SoC family.
|
||||
With this initial implementation, only playback is supported.
|
||||
Capture will be part of furture work.
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
sound/soc/meson/Kconfig | 2 +-
|
||||
sound/soc/meson/Makefile | 2 +
|
||||
sound/soc/meson/i2s-dai.c | 465 ++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 468 insertions(+), 1 deletion(-)
|
||||
create mode 100644 sound/soc/meson/i2s-dai.c
|
||||
|
||||
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
|
||||
index 88fbfc264146..478f29a2a3b2 100644
|
||||
--- a/sound/soc/meson/Kconfig
|
||||
+++ b/sound/soc/meson/Kconfig
|
||||
@@ -12,5 +12,5 @@ config SND_SOC_MESON_I2S
|
||||
tristate "Meson i2s interface"
|
||||
depends on SND_SOC_MESON
|
||||
help
|
||||
- Say Y or M if you want to add support for i2s dma driver for Amlogic
|
||||
+ Say Y or M if you want to add support for i2s driver for Amlogic
|
||||
Meson SoCs.
|
||||
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
|
||||
index 273f27590773..ea06ddee39d1 100644
|
||||
--- a/sound/soc/meson/Makefile
|
||||
+++ b/sound/soc/meson/Makefile
|
||||
@@ -1,5 +1,7 @@
|
||||
snd-soc-meson-audio-core-objs := audio-core.o
|
||||
snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o
|
||||
+snd-soc-meson-i2s-dai-objs := i2s-dai.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
|
||||
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
|
||||
+obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o
|
||||
diff --git a/sound/soc/meson/i2s-dai.c b/sound/soc/meson/i2s-dai.c
|
||||
new file mode 100644
|
||||
index 000000000000..1008af8d3972
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/meson/i2s-dai.c
|
||||
@@ -0,0 +1,465 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2017 BayLibre, SAS
|
||||
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
|
||||
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+#include <sound/pcm_params.h>
|
||||
+#include <sound/soc.h>
|
||||
+#include <sound/soc-dai.h>
|
||||
+
|
||||
+#include "aiu-regs.h"
|
||||
+#include "audio-core.h"
|
||||
+
|
||||
+#define DRV_NAME "meson-i2s-dai"
|
||||
+
|
||||
+struct meson_i2s_dai {
|
||||
+ struct meson_audio_core_data *core;
|
||||
+ struct clk *mclk;
|
||||
+ struct clk *bclks;
|
||||
+ struct clk *iface;
|
||||
+ struct clk *fast;
|
||||
+ bool bclks_idle;
|
||||
+};
|
||||
+
|
||||
+#define AIU_CLK_CTRL_I2S_DIV_EN BIT(0)
|
||||
+#define AIU_CLK_CTRL_I2S_DIV_MASK GENMASK(3, 2)
|
||||
+#define AIU_CLK_CTRL_AOCLK_POLARITY_MASK BIT(6)
|
||||
+#define AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL (0 << 6)
|
||||
+#define AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED (1 << 6)
|
||||
+#define AIU_CLK_CTRL_ALRCLK_POLARITY_MASK BIT(7)
|
||||
+#define AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL (0 << 7)
|
||||
+#define AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED (1 << 7)
|
||||
+#define AIU_CLK_CTRL_ALRCLK_SKEW_MASK GENMASK(9, 8)
|
||||
+#define AIU_CLK_CTRL_ALRCLK_LEFT_J (0 << 8)
|
||||
+#define AIU_CLK_CTRL_ALRCLK_I2S (1 << 8)
|
||||
+#define AIU_CLK_CTRL_ALRCLK_RIGHT_J (2 << 8)
|
||||
+#define AIU_CLK_CTRL_MORE_I2S_DIV_MASK GENMASK(5, 0)
|
||||
+#define AIU_CLK_CTRL_MORE_I2S_DIV(div) (((div) - 1) << 0)
|
||||
+#define AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK GENMASK(11, 0)
|
||||
+#define AIU_CODEC_DAC_LRCLK_CTRL_DIV(div) (((div) - 1) << 0)
|
||||
+#define AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK GENMASK(1, 0)
|
||||
+#define AIU_I2S_DAC_CFG_AOCLK_32 (0 << 0)
|
||||
+#define AIU_I2S_DAC_CFG_AOCLK_48 (2 << 0)
|
||||
+#define AIU_I2S_DAC_CFG_AOCLK_64 (3 << 0)
|
||||
+#define AIU_I2S_MISC_HOLD_EN BIT(2)
|
||||
+#define AIU_I2S_SOURCE_DESC_MODE_8CH BIT(0)
|
||||
+#define AIU_I2S_SOURCE_DESC_MODE_24BIT BIT(5)
|
||||
+#define AIU_I2S_SOURCE_DESC_MODE_32BIT BIT(9)
|
||||
+#define AIU_I2S_SOURCE_DESC_MODE_SPLIT BIT(11)
|
||||
+
|
||||
+static void __hold(struct meson_i2s_dai *priv, bool enable)
|
||||
+{
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_I2S_MISC,
|
||||
+ AIU_I2S_MISC_HOLD_EN,
|
||||
+ enable ? AIU_I2S_MISC_HOLD_EN : 0);
|
||||
+}
|
||||
+
|
||||
+static void __divider_enable(struct meson_i2s_dai *priv, bool enable)
|
||||
+{
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL,
|
||||
+ AIU_CLK_CTRL_I2S_DIV_EN,
|
||||
+ enable ? AIU_CLK_CTRL_I2S_DIV_EN : 0);
|
||||
+}
|
||||
+
|
||||
+static void __playback_start(struct meson_i2s_dai *priv)
|
||||
+{
|
||||
+ __divider_enable(priv, true);
|
||||
+ __hold(priv, false);
|
||||
+}
|
||||
+
|
||||
+static void __playback_stop(struct meson_i2s_dai *priv, bool clk_force)
|
||||
+{
|
||||
+ __hold(priv, true);
|
||||
+ /* Disable the bit clks if necessary */
|
||||
+ if (clk_force || !priv->bclks_idle)
|
||||
+ __divider_enable(priv, false);
|
||||
+}
|
||||
+
|
||||
+static int meson_i2s_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+ bool clk_force_stop = false;
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case SNDRV_PCM_TRIGGER_START:
|
||||
+ case SNDRV_PCM_TRIGGER_RESUME:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
+ __playback_start(priv);
|
||||
+ return 0;
|
||||
+
|
||||
+ case SNDRV_PCM_TRIGGER_STOP:
|
||||
+ case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
+ clk_force_stop = true;
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
+ __playback_stop(priv, clk_force_stop);
|
||||
+ return 0;
|
||||
+
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int __bclks_set_rate(struct meson_i2s_dai *priv, unsigned int srate,
|
||||
+ unsigned int width)
|
||||
+{
|
||||
+ unsigned int fs;
|
||||
+
|
||||
+ /* Get the oversampling factor */
|
||||
+ fs = DIV_ROUND_CLOSEST(clk_get_rate(priv->mclk), srate);
|
||||
+
|
||||
+ /*
|
||||
+ * This DAI is usually connected to the dw-hdmi which does not support
|
||||
+ * bclk being 32 * lrclk or 48 * lrclk
|
||||
+ * Restrict to blck = 64 * lrclk
|
||||
+ */
|
||||
+ if (fs % 64)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Set the divider between lrclk and bclk */
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_I2S_DAC_CFG,
|
||||
+ AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK,
|
||||
+ AIU_I2S_DAC_CFG_AOCLK_64);
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_CODEC_DAC_LRCLK_CTRL,
|
||||
+ AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK,
|
||||
+ AIU_CODEC_DAC_LRCLK_CTRL_DIV(64));
|
||||
+
|
||||
+ /* Use CLK_MORE for the i2s divider */
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL,
|
||||
+ AIU_CLK_CTRL_I2S_DIV_MASK,
|
||||
+ 0);
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL_MORE,
|
||||
+ AIU_CLK_CTRL_MORE_I2S_DIV_MASK,
|
||||
+ AIU_CLK_CTRL_MORE_I2S_DIV(fs / 64));
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __setup_desc(struct meson_i2s_dai *priv, unsigned int width,
|
||||
+ unsigned int channels)
|
||||
+{
|
||||
+ u32 desc = 0;
|
||||
+
|
||||
+ switch (width) {
|
||||
+ case 24:
|
||||
+ /*
|
||||
+ * For some reason, 24 bits wide audio don't play well
|
||||
+ * if the 32 bits mode is not set
|
||||
+ */
|
||||
+ desc |= (AIU_I2S_SOURCE_DESC_MODE_24BIT |
|
||||
+ AIU_I2S_SOURCE_DESC_MODE_32BIT);
|
||||
+ break;
|
||||
+ case 16:
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ switch (channels) {
|
||||
+ case 2: /* Nothing to do */
|
||||
+ break;
|
||||
+ case 8:
|
||||
+ /* TODO: Still requires testing ... */
|
||||
+ desc |= AIU_I2S_SOURCE_DESC_MODE_8CH;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_I2S_SOURCE_DESC,
|
||||
+ AIU_I2S_SOURCE_DESC_MODE_8CH |
|
||||
+ AIU_I2S_SOURCE_DESC_MODE_24BIT |
|
||||
+ AIU_I2S_SOURCE_DESC_MODE_32BIT,
|
||||
+ desc);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int meson_i2s_dai_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+ unsigned int width = params_width(params);
|
||||
+ unsigned int channels = params_channels(params);
|
||||
+ unsigned int rate = params_rate(params);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = __setup_desc(priv, width, channels);
|
||||
+ if (ret) {
|
||||
+ dev_err(dai->dev, "Unable set to set i2s description\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = __bclks_set_rate(priv, rate, width);
|
||||
+ if (ret) {
|
||||
+ dev_err(dai->dev, "Unable set to the i2s clock rates\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int meson_i2s_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
|
||||
+{
|
||||
+ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+ u32 val;
|
||||
+
|
||||
+ if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* DAI output mode */
|
||||
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
+ case SND_SOC_DAIFMT_I2S:
|
||||
+ val = AIU_CLK_CTRL_ALRCLK_I2S;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_LEFT_J:
|
||||
+ val = AIU_CLK_CTRL_ALRCLK_LEFT_J;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_RIGHT_J:
|
||||
+ val = AIU_CLK_CTRL_ALRCLK_RIGHT_J;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL,
|
||||
+ AIU_CLK_CTRL_ALRCLK_SKEW_MASK,
|
||||
+ val);
|
||||
+
|
||||
+ /* DAI clock polarity */
|
||||
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
|
||||
+ case SND_SOC_DAIFMT_IB_IF:
|
||||
+ /* Invert both clocks */
|
||||
+ val = AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED |
|
||||
+ AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_IB_NF:
|
||||
+ /* Invert bit clock */
|
||||
+ val = AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL |
|
||||
+ AIU_CLK_CTRL_AOCLK_POLARITY_INVERTED;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_NB_IF:
|
||||
+ /* Invert frame clock */
|
||||
+ val = AIU_CLK_CTRL_ALRCLK_POLARITY_INVERTED |
|
||||
+ AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_NB_NF:
|
||||
+ /* Normal clocks */
|
||||
+ val = AIU_CLK_CTRL_ALRCLK_POLARITY_NORMAL |
|
||||
+ AIU_CLK_CTRL_AOCLK_POLARITY_NORMAL;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL,
|
||||
+ AIU_CLK_CTRL_ALRCLK_POLARITY_MASK |
|
||||
+ AIU_CLK_CTRL_AOCLK_POLARITY_MASK,
|
||||
+ val);
|
||||
+
|
||||
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
|
||||
+ case SND_SOC_DAIFMT_CONT:
|
||||
+ priv->bclks_idle = true;
|
||||
+ break;
|
||||
+ case SND_SOC_DAIFMT_GATED:
|
||||
+ priv->bclks_idle = false;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int meson_i2s_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
|
||||
+ unsigned int freq, int dir)
|
||||
+{
|
||||
+ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+ int ret;
|
||||
+
|
||||
+ if (WARN_ON(clk_id != 0))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (dir == SND_SOC_CLOCK_IN)
|
||||
+ return 0;
|
||||
+
|
||||
+ ret = clk_set_rate(priv->mclk, freq);
|
||||
+ if (ret) {
|
||||
+ dev_err(dai->dev, "Failed to set sysclk to %uHz", freq);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int meson_i2s_dai_startup(struct snd_pcm_substream *substream,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Power up the i2s fast domain - can't write the registers w/o it */
|
||||
+ ret = clk_prepare_enable(priv->fast);
|
||||
+ if (ret)
|
||||
+ goto out_clk_fast;
|
||||
+
|
||||
+ /* Make sure nothing gets out of the DAI yet */
|
||||
+ __hold(priv, true);
|
||||
+
|
||||
+ /* I2S encoder needs the mixer interface gate */
|
||||
+ ret = clk_prepare_enable(priv->iface);
|
||||
+ if (ret)
|
||||
+ goto out_clk_iface;
|
||||
+
|
||||
+ /* Enable the i2s master clock */
|
||||
+ ret = clk_prepare_enable(priv->mclk);
|
||||
+ if (ret)
|
||||
+ goto out_mclk;
|
||||
+
|
||||
+ /* Enable the bit clock gate */
|
||||
+ ret = clk_prepare_enable(priv->bclks);
|
||||
+ if (ret)
|
||||
+ goto out_bclks;
|
||||
+
|
||||
+ /* Make sure the interface expect a memory layout we can work with */
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_I2S_SOURCE_DESC,
|
||||
+ AIU_I2S_SOURCE_DESC_MODE_SPLIT,
|
||||
+ AIU_I2S_SOURCE_DESC_MODE_SPLIT);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+out_bclks:
|
||||
+ clk_disable_unprepare(priv->mclk);
|
||||
+out_mclk:
|
||||
+ clk_disable_unprepare(priv->iface);
|
||||
+out_clk_iface:
|
||||
+ clk_disable_unprepare(priv->fast);
|
||||
+out_clk_fast:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void meson_i2s_dai_shutdown(struct snd_pcm_substream *substream,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct meson_i2s_dai *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+
|
||||
+ clk_disable_unprepare(priv->bclks);
|
||||
+ clk_disable_unprepare(priv->mclk);
|
||||
+ clk_disable_unprepare(priv->iface);
|
||||
+ clk_disable_unprepare(priv->fast);
|
||||
+}
|
||||
+
|
||||
+static const struct snd_soc_dai_ops meson_i2s_dai_ops = {
|
||||
+ .startup = meson_i2s_dai_startup,
|
||||
+ .shutdown = meson_i2s_dai_shutdown,
|
||||
+ .trigger = meson_i2s_dai_trigger,
|
||||
+ .hw_params = meson_i2s_dai_hw_params,
|
||||
+ .set_fmt = meson_i2s_dai_set_fmt,
|
||||
+ .set_sysclk = meson_i2s_dai_set_sysclk,
|
||||
+};
|
||||
+
|
||||
+static struct snd_soc_dai_driver meson_i2s_dai = {
|
||||
+ .playback = {
|
||||
+ .stream_name = "Playback",
|
||||
+ .channels_min = 2,
|
||||
+ .channels_max = 8,
|
||||
+ .rates = SNDRV_PCM_RATE_8000_192000,
|
||||
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
+ SNDRV_PCM_FMTBIT_S24_LE)
|
||||
+ },
|
||||
+ .ops = &meson_i2s_dai_ops,
|
||||
+};
|
||||
+
|
||||
+static const struct snd_soc_component_driver meson_i2s_dai_component = {
|
||||
+ .name = DRV_NAME,
|
||||
+};
|
||||
+
|
||||
+static int meson_i2s_dai_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct meson_i2s_dai *priv;
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, priv);
|
||||
+ priv->core = dev_get_drvdata(dev->parent);
|
||||
+
|
||||
+ priv->fast = devm_clk_get(dev, "fast");
|
||||
+ if (IS_ERR(priv->fast)) {
|
||||
+ if (PTR_ERR(priv->fast) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Can't get the i2s fast domain clock\n");
|
||||
+ return PTR_ERR(priv->fast);
|
||||
+ }
|
||||
+
|
||||
+ priv->iface = devm_clk_get(dev, "iface");
|
||||
+ if (IS_ERR(priv->iface)) {
|
||||
+ if (PTR_ERR(priv->iface) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Can't get i2s dai clock gate\n");
|
||||
+ return PTR_ERR(priv->iface);
|
||||
+ }
|
||||
+
|
||||
+ priv->bclks = devm_clk_get(dev, "bclks");
|
||||
+ if (IS_ERR(priv->bclks)) {
|
||||
+ if (PTR_ERR(priv->bclks) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Can't get bit clocks gate\n");
|
||||
+ return PTR_ERR(priv->bclks);
|
||||
+ }
|
||||
+
|
||||
+ priv->mclk = devm_clk_get(dev, "mclk");
|
||||
+ if (IS_ERR(priv->mclk)) {
|
||||
+ if (PTR_ERR(priv->mclk) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "failed to get the i2s master clock\n");
|
||||
+ return PTR_ERR(priv->mclk);
|
||||
+ }
|
||||
+
|
||||
+ return devm_snd_soc_register_component(dev, &meson_i2s_dai_component,
|
||||
+ &meson_i2s_dai, 1);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id meson_i2s_dai_of_match[] = {
|
||||
+ { .compatible = "amlogic,meson-i2s-dai", },
|
||||
+ { .compatible = "amlogic,meson-gxbb-i2s-dai", },
|
||||
+ { .compatible = "amlogic,meson-gxl-i2s-dai", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, meson_i2s_dai_of_match);
|
||||
+
|
||||
+static struct platform_driver meson_i2s_dai_pdrv = {
|
||||
+ .probe = meson_i2s_dai_probe,
|
||||
+ .driver = {
|
||||
+ .name = DRV_NAME,
|
||||
+ .of_match_table = meson_i2s_dai_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(meson_i2s_dai_pdrv);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Meson i2s DAI ASoC Driver");
|
||||
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.18.0
|
||||
|
||||
441
patches/mainline/0011-ASoC-meson-add-aiu-spdif-dma-support.patch
Normal file
441
patches/mainline/0011-ASoC-meson-add-aiu-spdif-dma-support.patch
Normal file
@@ -0,0 +1,441 @@
|
||||
From 9d30eb1c60ba967c4c5dd27a602bd3fb12e8edf0 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Thu, 30 Mar 2017 13:43:52 +0200
|
||||
Subject: [PATCH 11/21] ASoC: meson: add aiu spdif dma support
|
||||
|
||||
Add support for the spdif output dma which is part of the AIU block
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
sound/soc/meson/Kconfig | 7 +
|
||||
sound/soc/meson/Makefile | 2 +
|
||||
sound/soc/meson/aiu-spdif-dma.c | 388 ++++++++++++++++++++++++++++++++
|
||||
3 files changed, 397 insertions(+)
|
||||
create mode 100644 sound/soc/meson/aiu-spdif-dma.c
|
||||
|
||||
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
|
||||
index 478f29a2a3b2..3fb93b9fd107 100644
|
||||
--- a/sound/soc/meson/Kconfig
|
||||
+++ b/sound/soc/meson/Kconfig
|
||||
@@ -14,3 +14,10 @@ config SND_SOC_MESON_I2S
|
||||
help
|
||||
Say Y or M if you want to add support for i2s driver for Amlogic
|
||||
Meson SoCs.
|
||||
+
|
||||
+config SND_SOC_MESON_SPDIF
|
||||
+ tristate "Meson spdif interface"
|
||||
+ depends on SND_SOC_MESON
|
||||
+ help
|
||||
+ Say Y or M if you want to add support for spdif dma driver for Amlogic
|
||||
+ Meson SoCs.
|
||||
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
|
||||
index ea06ddee39d1..cef9a9d675da 100644
|
||||
--- a/sound/soc/meson/Makefile
|
||||
+++ b/sound/soc/meson/Makefile
|
||||
@@ -1,7 +1,9 @@
|
||||
snd-soc-meson-audio-core-objs := audio-core.o
|
||||
snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o
|
||||
+snd-soc-meson-aiu-spdif-dma-objs := aiu-spdif-dma.o
|
||||
snd-soc-meson-i2s-dai-objs := i2s-dai.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
|
||||
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
|
||||
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o
|
||||
+obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o
|
||||
diff --git a/sound/soc/meson/aiu-spdif-dma.c b/sound/soc/meson/aiu-spdif-dma.c
|
||||
new file mode 100644
|
||||
index 000000000000..81c3b856fbf9
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/meson/aiu-spdif-dma.c
|
||||
@@ -0,0 +1,388 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2017 BayLibre, SAS
|
||||
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
|
||||
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+#include <sound/pcm_params.h>
|
||||
+#include <sound/soc.h>
|
||||
+
|
||||
+#include "aiu-regs.h"
|
||||
+#include "audio-core.h"
|
||||
+
|
||||
+#define DRV_NAME "meson-aiu-spdif-dma"
|
||||
+
|
||||
+struct aiu_spdif_dma {
|
||||
+ struct meson_audio_core_data *core;
|
||||
+ struct clk *fast;
|
||||
+ int irq;
|
||||
+};
|
||||
+
|
||||
+#define AIU_958_DCU_FF_CTRL_EN BIT(0)
|
||||
+#define AIU_958_DCU_FF_CTRL_AUTO_DISABLE BIT(1)
|
||||
+#define AIU_958_DCU_FF_CTRL_IRQ_MODE_MASK GENMASK(3, 2)
|
||||
+#define AIU_958_DCU_FF_CTRL_IRQ_OUT_THD BIT(2)
|
||||
+#define AIU_958_DCU_FF_CTRL_IRQ_FRAME_READ BIT(3)
|
||||
+#define AIU_958_DCU_FF_CTRL_SYNC_HEAD_EN BIT(4)
|
||||
+#define AIU_958_DCU_FF_CTRL_BYTE_SEEK BIT(5)
|
||||
+#define AIU_958_DCU_FF_CTRL_CONTINUE BIT(6)
|
||||
+#define AIU_MEM_IEC958_BUF_CNTL_INIT BIT(0)
|
||||
+#define AIU_MEM_IEC958_CONTROL_INIT BIT(0)
|
||||
+#define AIU_MEM_IEC958_CONTROL_FILL_EN BIT(1)
|
||||
+#define AIU_MEM_IEC958_CONTROL_EMPTY_EN BIT(2)
|
||||
+#define AIU_MEM_IEC958_CONTROL_ENDIAN_MASK GENMASK(5, 3)
|
||||
+#define AIU_MEM_IEC958_CONTROL_RD_DDR BIT(6)
|
||||
+#define AIU_MEM_IEC958_CONTROL_MODE_16BIT BIT(7)
|
||||
+#define AIU_MEM_IEC958_MASKS_CH_MEM_MASK GENMASK(15, 8)
|
||||
+#define AIU_MEM_IEC958_MASKS_CH_MEM(ch) ((ch) << 8)
|
||||
+#define AIU_MEM_IEC958_MASKS_CH_RD_MASK GENMASK(7, 0)
|
||||
+#define AIU_MEM_IEC958_MASKS_CH_RD(ch) ((ch) << 0)
|
||||
+
|
||||
+#define AIU_SPDIF_DMA_BURST 8
|
||||
+#define AIU_SPDIF_BPF_MAX USHRT_MAX
|
||||
+
|
||||
+static struct snd_pcm_hardware aiu_spdif_dma_hw = {
|
||||
+ .info = (SNDRV_PCM_INFO_INTERLEAVED |
|
||||
+ SNDRV_PCM_INFO_MMAP |
|
||||
+ SNDRV_PCM_INFO_MMAP_VALID |
|
||||
+ SNDRV_PCM_INFO_PAUSE),
|
||||
+
|
||||
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
+ SNDRV_PCM_FMTBIT_S24_LE |
|
||||
+ SNDRV_PCM_FMTBIT_S32_LE),
|
||||
+
|
||||
+ .rates = (SNDRV_PCM_RATE_32000 |
|
||||
+ SNDRV_PCM_RATE_44100 |
|
||||
+ SNDRV_PCM_RATE_48000 |
|
||||
+ SNDRV_PCM_RATE_96000 |
|
||||
+ SNDRV_PCM_RATE_192000),
|
||||
+ /*
|
||||
+ * TODO: The DMA can change the endianness, the msb position
|
||||
+ * and deal with unsigned - support this later on
|
||||
+ */
|
||||
+
|
||||
+ .channels_min = 2,
|
||||
+ .channels_max = 2,
|
||||
+ .period_bytes_min = AIU_SPDIF_DMA_BURST,
|
||||
+ .period_bytes_max = AIU_SPDIF_BPF_MAX,
|
||||
+ .periods_min = 2,
|
||||
+ .periods_max = UINT_MAX,
|
||||
+ .buffer_bytes_max = 1 * 1024 * 1024,
|
||||
+ .fifo_size = 0,
|
||||
+};
|
||||
+
|
||||
+static struct aiu_spdif_dma *aiu_spdif_dma_priv(struct snd_pcm_substream *s)
|
||||
+{
|
||||
+ struct snd_soc_pcm_runtime *rtd = s->private_data;
|
||||
+ struct snd_soc_component *component = snd_soc_rtdcom_lookup(rtd, DRV_NAME);
|
||||
+
|
||||
+ return snd_soc_component_get_drvdata(component);
|
||||
+}
|
||||
+
|
||||
+static snd_pcm_uframes_t
|
||||
+aiu_spdif_dma_pointer(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
+ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream);
|
||||
+ unsigned int addr;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_read(priv->core->aiu, AIU_MEM_IEC958_RD_PTR,
|
||||
+ &addr);
|
||||
+ if (ret)
|
||||
+ return 0;
|
||||
+
|
||||
+ return bytes_to_frames(runtime, addr - (unsigned int)runtime->dma_addr);
|
||||
+}
|
||||
+
|
||||
+static void __dma_enable(struct aiu_spdif_dma *priv, bool enable)
|
||||
+{
|
||||
+ unsigned int en_mask = (AIU_MEM_IEC958_CONTROL_FILL_EN |
|
||||
+ AIU_MEM_IEC958_CONTROL_EMPTY_EN);
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL, en_mask,
|
||||
+ enable ? en_mask : 0);
|
||||
+}
|
||||
+
|
||||
+static void __dcu_fifo_enable(struct aiu_spdif_dma *priv, bool enable)
|
||||
+{
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_958_DCU_FF_CTRL,
|
||||
+ AIU_958_DCU_FF_CTRL_EN,
|
||||
+ enable ? AIU_958_DCU_FF_CTRL_EN : 0);
|
||||
+}
|
||||
+
|
||||
+static int aiu_spdif_dma_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
+{
|
||||
+ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream);
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case SNDRV_PCM_TRIGGER_START:
|
||||
+ case SNDRV_PCM_TRIGGER_RESUME:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
+ __dcu_fifo_enable(priv, true);
|
||||
+ __dma_enable(priv, true);
|
||||
+ break;
|
||||
+ case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
+ case SNDRV_PCM_TRIGGER_STOP:
|
||||
+ __dma_enable(priv, false);
|
||||
+ __dcu_fifo_enable(priv, false);
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void __dma_init_mem(struct aiu_spdif_dma *priv)
|
||||
+{
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL,
|
||||
+ AIU_MEM_IEC958_CONTROL_INIT,
|
||||
+ AIU_MEM_IEC958_CONTROL_INIT);
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_BUF_CNTL,
|
||||
+ AIU_MEM_IEC958_BUF_CNTL_INIT,
|
||||
+ AIU_MEM_IEC958_BUF_CNTL_INIT);
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL,
|
||||
+ AIU_MEM_IEC958_CONTROL_INIT,
|
||||
+ 0);
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_BUF_CNTL,
|
||||
+ AIU_MEM_IEC958_BUF_CNTL_INIT,
|
||||
+ 0);
|
||||
+}
|
||||
+
|
||||
+static int aiu_spdif_dma_prepare(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream);
|
||||
+
|
||||
+ __dma_init_mem(priv);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __setup_memory_layout(struct aiu_spdif_dma *priv,
|
||||
+ unsigned int width)
|
||||
+{
|
||||
+ u32 mem_ctl = AIU_MEM_IEC958_CONTROL_RD_DDR;
|
||||
+
|
||||
+ if (width == 16)
|
||||
+ mem_ctl |= AIU_MEM_IEC958_CONTROL_MODE_16BIT;
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL,
|
||||
+ AIU_MEM_IEC958_CONTROL_ENDIAN_MASK |
|
||||
+ AIU_MEM_IEC958_CONTROL_MODE_16BIT |
|
||||
+ AIU_MEM_IEC958_CONTROL_RD_DDR,
|
||||
+ mem_ctl);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aiu_spdif_dma_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params)
|
||||
+{
|
||||
+ struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
+ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream);
|
||||
+ int ret;
|
||||
+ dma_addr_t end_ptr;
|
||||
+
|
||||
+ ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params));
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = __setup_memory_layout(priv, params_physical_width(params));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Initialize memory pointers */
|
||||
+ regmap_write(priv->core->aiu,
|
||||
+ AIU_MEM_IEC958_START_PTR, runtime->dma_addr);
|
||||
+ regmap_write(priv->core->aiu,
|
||||
+ AIU_MEM_IEC958_RD_PTR, runtime->dma_addr);
|
||||
+
|
||||
+ /* The end pointer is the address of the last valid block */
|
||||
+ end_ptr = runtime->dma_addr + runtime->dma_bytes - AIU_SPDIF_DMA_BURST;
|
||||
+ regmap_write(priv->core->aiu, AIU_MEM_IEC958_END_PTR, end_ptr);
|
||||
+
|
||||
+ /* Memory masks */
|
||||
+ regmap_write(priv->core->aiu, AIU_MEM_IEC958_MASKS,
|
||||
+ AIU_MEM_IEC958_MASKS_CH_RD(0xff) |
|
||||
+ AIU_MEM_IEC958_MASKS_CH_MEM(0xff));
|
||||
+
|
||||
+ /* Setup the number bytes read by the FIFO between each IRQ */
|
||||
+ regmap_write(priv->core->aiu, AIU_958_BPF, params_period_bytes(params));
|
||||
+
|
||||
+ /*
|
||||
+ * AUTO_DISABLE and SYNC_HEAD are enabled by default but
|
||||
+ * this should be disabled in PCM (uncompressed) mode
|
||||
+ */
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_958_DCU_FF_CTRL,
|
||||
+ AIU_958_DCU_FF_CTRL_AUTO_DISABLE |
|
||||
+ AIU_958_DCU_FF_CTRL_IRQ_MODE_MASK |
|
||||
+ AIU_958_DCU_FF_CTRL_SYNC_HEAD_EN,
|
||||
+ AIU_958_DCU_FF_CTRL_IRQ_FRAME_READ);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aiu_spdif_dma_hw_free(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ return snd_pcm_lib_free_pages(substream);
|
||||
+}
|
||||
+
|
||||
+static irqreturn_t aiu_spdif_dma_irq(int irq, void *dev_id)
|
||||
+{
|
||||
+ struct snd_pcm_substream *playback = dev_id;
|
||||
+
|
||||
+ snd_pcm_period_elapsed(playback);
|
||||
+
|
||||
+ return IRQ_HANDLED;
|
||||
+}
|
||||
+
|
||||
+static int aiu_spdif_dma_open(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream);
|
||||
+ int ret;
|
||||
+
|
||||
+ snd_soc_set_runtime_hwparams(substream, &aiu_spdif_dma_hw);
|
||||
+
|
||||
+ /*
|
||||
+ * Make sure the buffer and period size are multiple of the DMA burst
|
||||
+ * size
|
||||
+ */
|
||||
+ ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
|
||||
+ AIU_SPDIF_DMA_BURST);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
+ SNDRV_PCM_HW_PARAM_PERIOD_BYTES,
|
||||
+ AIU_SPDIF_DMA_BURST);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Request the SPDIF DDR irq */
|
||||
+ ret = request_irq(priv->irq, aiu_spdif_dma_irq, 0,
|
||||
+ DRV_NAME, substream);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Power up the spdif fast domain - can't write the register w/o it */
|
||||
+ ret = clk_prepare_enable(priv->fast);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Make sure the dma is initially halted */
|
||||
+ __dma_enable(priv, false);
|
||||
+ __dcu_fifo_enable(priv, false);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int aiu_spdif_dma_close(struct snd_pcm_substream *substream)
|
||||
+{
|
||||
+ struct aiu_spdif_dma *priv = aiu_spdif_dma_priv(substream);
|
||||
+
|
||||
+ clk_disable_unprepare(priv->fast);
|
||||
+ free_irq(priv->irq, substream);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct snd_pcm_ops aiu_spdif_dma_ops = {
|
||||
+ .open = aiu_spdif_dma_open,
|
||||
+ .close = aiu_spdif_dma_close,
|
||||
+ .ioctl = snd_pcm_lib_ioctl,
|
||||
+ .hw_params = aiu_spdif_dma_hw_params,
|
||||
+ .hw_free = aiu_spdif_dma_hw_free,
|
||||
+ .prepare = aiu_spdif_dma_prepare,
|
||||
+ .pointer = aiu_spdif_dma_pointer,
|
||||
+ .trigger = aiu_spdif_dma_trigger,
|
||||
+};
|
||||
+
|
||||
+static int aiu_spdif_dma_new(struct snd_soc_pcm_runtime *rtd)
|
||||
+{
|
||||
+ struct snd_card *card = rtd->card->snd_card;
|
||||
+ size_t size = aiu_spdif_dma_hw.buffer_bytes_max;
|
||||
+
|
||||
+ return snd_pcm_lib_preallocate_pages_for_all(rtd->pcm,
|
||||
+ SNDRV_DMA_TYPE_DEV,
|
||||
+ card->dev, size, size);
|
||||
+}
|
||||
+
|
||||
+static const struct snd_soc_component_driver aiu_spdif_platform = {
|
||||
+ .ops = &aiu_spdif_dma_ops,
|
||||
+ .pcm_new = aiu_spdif_dma_new,
|
||||
+ .name = DRV_NAME,
|
||||
+};
|
||||
+
|
||||
+static int aiu_spdif_dma_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct aiu_spdif_dma *priv;
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, priv);
|
||||
+ priv->core = dev_get_drvdata(dev->parent);
|
||||
+
|
||||
+ priv->fast = devm_clk_get(dev, "fast");
|
||||
+ if (IS_ERR(priv->fast)) {
|
||||
+ if (PTR_ERR(priv->fast) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Can't get spdif fast domain clock\n");
|
||||
+ return PTR_ERR(priv->fast);
|
||||
+ }
|
||||
+
|
||||
+ priv->irq = platform_get_irq(pdev, 0);
|
||||
+ if (priv->irq <= 0) {
|
||||
+ dev_err(dev, "Can't get spdif ddr irq\n");
|
||||
+ return priv->irq;
|
||||
+ }
|
||||
+
|
||||
+ return devm_snd_soc_register_component(dev, &aiu_spdif_platform,
|
||||
+ NULL, 0);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id aiu_spdif_dma_of_match[] = {
|
||||
+ { .compatible = "amlogic,meson-aiu-spdif-dma", },
|
||||
+ { .compatible = "amlogic,meson-gxbb-aiu-spdif-dma", },
|
||||
+ { .compatible = "amlogic,meson-gxl-aiu-spdif-dma", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, aiu_spdif_dma_of_match);
|
||||
+
|
||||
+static struct platform_driver aiu_spdif_dma_pdrv = {
|
||||
+ .probe = aiu_spdif_dma_probe,
|
||||
+ .driver = {
|
||||
+ .name = DRV_NAME,
|
||||
+ .of_match_table = aiu_spdif_dma_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(aiu_spdif_dma_pdrv);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Meson AIU spdif DMA ASoC Driver");
|
||||
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,429 @@
|
||||
From 1545fc36c9b5cd9ea28dadfc1140e8290923e27b Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Thu, 30 Mar 2017 13:46:03 +0200
|
||||
Subject: [PATCH 12/21] ASoC: meson: add initial spdif dai support
|
||||
|
||||
Add support for the spdif dai found on Amlogic Meson SoC family.
|
||||
With this initial implementation, only uncompressed pcm playback
|
||||
from the spdif dma is supported. Future work will add compressed
|
||||
support, pcm playback from i2s dma and capture.
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
sound/soc/meson/Kconfig | 3 +-
|
||||
sound/soc/meson/Makefile | 2 +
|
||||
sound/soc/meson/spdif-dai.c | 374 ++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 378 insertions(+), 1 deletion(-)
|
||||
create mode 100644 sound/soc/meson/spdif-dai.c
|
||||
|
||||
diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig
|
||||
index 3fb93b9fd107..301d3a3c07ad 100644
|
||||
--- a/sound/soc/meson/Kconfig
|
||||
+++ b/sound/soc/meson/Kconfig
|
||||
@@ -18,6 +18,7 @@ config SND_SOC_MESON_I2S
|
||||
config SND_SOC_MESON_SPDIF
|
||||
tristate "Meson spdif interface"
|
||||
depends on SND_SOC_MESON
|
||||
+ select SND_PCM_IEC958
|
||||
help
|
||||
- Say Y or M if you want to add support for spdif dma driver for Amlogic
|
||||
+ Say Y or M if you want to add support for spdif driver for Amlogic
|
||||
Meson SoCs.
|
||||
diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile
|
||||
index cef9a9d675da..bc4391c50e34 100644
|
||||
--- a/sound/soc/meson/Makefile
|
||||
+++ b/sound/soc/meson/Makefile
|
||||
@@ -2,8 +2,10 @@ snd-soc-meson-audio-core-objs := audio-core.o
|
||||
snd-soc-meson-aiu-i2s-dma-objs := aiu-i2s-dma.o
|
||||
snd-soc-meson-aiu-spdif-dma-objs := aiu-spdif-dma.o
|
||||
snd-soc-meson-i2s-dai-objs := i2s-dai.o
|
||||
+snd-soc-meson-spdif-dai-objs := spdif-dai.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_MESON) += snd-soc-meson-audio-core.o
|
||||
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-aiu-i2s-dma.o
|
||||
obj-$(CONFIG_SND_SOC_MESON_I2S) += snd-soc-meson-i2s-dai.o
|
||||
obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-aiu-spdif-dma.o
|
||||
+obj-$(CONFIG_SND_SOC_MESON_SPDIF) += snd-soc-meson-spdif-dai.o
|
||||
diff --git a/sound/soc/meson/spdif-dai.c b/sound/soc/meson/spdif-dai.c
|
||||
new file mode 100644
|
||||
index 000000000000..e7630007c84b
|
||||
--- /dev/null
|
||||
+++ b/sound/soc/meson/spdif-dai.c
|
||||
@@ -0,0 +1,374 @@
|
||||
+/*
|
||||
+ * Copyright (C) 2017 BayLibre, SAS
|
||||
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
|
||||
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public License as
|
||||
+ * published by the Free Software Foundation; either version 2 of the
|
||||
+ * License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful, but
|
||||
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU General Public License
|
||||
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/clk.h>
|
||||
+#include <linux/mfd/syscon.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of.h>
|
||||
+#include <linux/platform_device.h>
|
||||
+#include <linux/regmap.h>
|
||||
+
|
||||
+#include <sound/pcm_params.h>
|
||||
+#include <sound/soc.h>
|
||||
+#include <sound/soc-dai.h>
|
||||
+#include <sound/pcm_iec958.h>
|
||||
+
|
||||
+#include "aiu-regs.h"
|
||||
+#include "audio-core.h"
|
||||
+
|
||||
+#define DRV_NAME "meson-spdif-dai"
|
||||
+
|
||||
+struct meson_spdif_dai {
|
||||
+ struct meson_audio_core_data *core;
|
||||
+ struct clk *iface;
|
||||
+ struct clk *fast;
|
||||
+ struct clk *mclk_i958;
|
||||
+ struct clk *mclk;
|
||||
+};
|
||||
+
|
||||
+#define AIU_CLK_CTRL_958_DIV_EN BIT(1)
|
||||
+#define AIU_CLK_CTRL_958_DIV_MASK GENMASK(5, 4)
|
||||
+#define AIU_CLK_CTRL_958_DIV_MORE BIT(12)
|
||||
+#define AIU_MEM_IEC958_CONTROL_MODE_LINEAR BIT(8)
|
||||
+#define AIU_958_CTRL_HOLD_EN BIT(0)
|
||||
+#define AIU_958_MISC_NON_PCM BIT(0)
|
||||
+#define AIU_958_MISC_MODE_16BITS BIT(1)
|
||||
+#define AIU_958_MISC_16BITS_ALIGN_MASK GENMASK(6, 5)
|
||||
+#define AIU_958_MISC_16BITS_ALIGN(val) ((val) << 5)
|
||||
+#define AIU_958_MISC_MODE_32BITS BIT(7)
|
||||
+#define AIU_958_MISC_32BITS_SHIFT_MASK GENMASK(10, 8)
|
||||
+#define AIU_958_MISC_32BITS_SHIFT(val) ((val) << 8)
|
||||
+#define AIU_958_MISC_U_FROM_STREAM BIT(12)
|
||||
+#define AIU_958_MISC_FORCE_LR BIT(13)
|
||||
+
|
||||
+#define AIU_CS_WORD_LEN 4
|
||||
+
|
||||
+static void __hold(struct meson_spdif_dai *priv, bool enable)
|
||||
+{
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_958_CTRL,
|
||||
+ AIU_958_CTRL_HOLD_EN,
|
||||
+ enable ? AIU_958_CTRL_HOLD_EN : 0);
|
||||
+}
|
||||
+
|
||||
+static void __divider_enable(struct meson_spdif_dai *priv, bool enable)
|
||||
+{
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL,
|
||||
+ AIU_CLK_CTRL_958_DIV_EN,
|
||||
+ enable ? AIU_CLK_CTRL_958_DIV_EN : 0);
|
||||
+}
|
||||
+
|
||||
+static void __playback_start(struct meson_spdif_dai *priv)
|
||||
+{
|
||||
+ __divider_enable(priv, true);
|
||||
+ __hold(priv, false);
|
||||
+}
|
||||
+
|
||||
+static void __playback_stop(struct meson_spdif_dai *priv)
|
||||
+{
|
||||
+ __hold(priv, true);
|
||||
+ __divider_enable(priv, false);
|
||||
+}
|
||||
+
|
||||
+static int meson_spdif_dai_trigger(struct snd_pcm_substream *substream, int cmd,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+
|
||||
+ switch (cmd) {
|
||||
+ case SNDRV_PCM_TRIGGER_START:
|
||||
+ case SNDRV_PCM_TRIGGER_RESUME:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
+ __playback_start(priv);
|
||||
+ return 0;
|
||||
+
|
||||
+ case SNDRV_PCM_TRIGGER_STOP:
|
||||
+ case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
+ __playback_stop(priv);
|
||||
+ return 0;
|
||||
+
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int __setup_spdif_clk(struct meson_spdif_dai *priv, unsigned int rate)
|
||||
+{
|
||||
+ unsigned int mrate;
|
||||
+
|
||||
+ /* Leave the internal divisor alone */
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL,
|
||||
+ AIU_CLK_CTRL_958_DIV_MASK |
|
||||
+ AIU_CLK_CTRL_958_DIV_MORE,
|
||||
+ 0);
|
||||
+
|
||||
+ /* 2 * 32bits per subframe * 2 channels = 128 */
|
||||
+ mrate = rate * 128;
|
||||
+ return clk_set_rate(priv->mclk, mrate);
|
||||
+}
|
||||
+
|
||||
+static int __setup_cs_word(struct meson_spdif_dai *priv,
|
||||
+ struct snd_pcm_hw_params *params)
|
||||
+{
|
||||
+ u8 cs[AIU_CS_WORD_LEN];
|
||||
+ u32 val;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = snd_pcm_create_iec958_consumer_hw_params(params, cs,
|
||||
+ AIU_CS_WORD_LEN);
|
||||
+ if (ret < 0)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ /* Write the 1st half word */
|
||||
+ val = cs[1] | cs[0] << 8;
|
||||
+ regmap_write(priv->core->aiu, AIU_958_CHSTAT_L0, val);
|
||||
+ regmap_write(priv->core->aiu, AIU_958_CHSTAT_R0, val);
|
||||
+
|
||||
+ /* Write the 2nd half word */
|
||||
+ val = cs[3] | cs[2] << 8;
|
||||
+ regmap_write(priv->core->aiu, AIU_958_CHSTAT_L1, val);
|
||||
+ regmap_write(priv->core->aiu, AIU_958_CHSTAT_R1, val);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int __setup_pcm_fmt(struct meson_spdif_dai *priv,
|
||||
+ unsigned int width)
|
||||
+{
|
||||
+ u32 val = 0;
|
||||
+
|
||||
+ switch (width) {
|
||||
+ case 16:
|
||||
+ val |= AIU_958_MISC_MODE_16BITS;
|
||||
+ val |= AIU_958_MISC_16BITS_ALIGN(2);
|
||||
+ break;
|
||||
+ case 32:
|
||||
+ case 24:
|
||||
+ /*
|
||||
+ * Looks like this should only be set for 32bits mode, but the
|
||||
+ * vendor kernel sets it like this for 24bits as well, let's
|
||||
+ * try and see
|
||||
+ */
|
||||
+ val |= AIU_958_MISC_MODE_32BITS;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* No idea what this actually does, copying the vendor kernel for now */
|
||||
+ val |= AIU_958_MISC_FORCE_LR;
|
||||
+ val |= AIU_958_MISC_U_FROM_STREAM;
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_958_MISC,
|
||||
+ AIU_958_MISC_NON_PCM |
|
||||
+ AIU_958_MISC_MODE_16BITS |
|
||||
+ AIU_958_MISC_16BITS_ALIGN_MASK |
|
||||
+ AIU_958_MISC_MODE_32BITS |
|
||||
+ AIU_958_MISC_FORCE_LR,
|
||||
+ val);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int meson_spdif_dai_hw_params(struct snd_pcm_substream *substream,
|
||||
+ struct snd_pcm_hw_params *params,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = __setup_spdif_clk(priv, params_rate(params));
|
||||
+ if (ret) {
|
||||
+ dev_err(dai->dev, "Unable to set the spdif clock\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = __setup_cs_word(priv, params);
|
||||
+ if (ret) {
|
||||
+ dev_err(dai->dev, "Unable to set the channel status word\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ ret = __setup_pcm_fmt(priv, params_width(params));
|
||||
+ if (ret) {
|
||||
+ dev_err(dai->dev, "Unable to set the pcm format\n");
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int meson_spdif_dai_startup(struct snd_pcm_substream *substream,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Power up the spdif fast domain - can't write the registers w/o it */
|
||||
+ ret = clk_prepare_enable(priv->fast);
|
||||
+ if (ret)
|
||||
+ goto out_clk_fast;
|
||||
+
|
||||
+ /* Make sure nothing gets out of the DAI yet*/
|
||||
+ __hold(priv, true);
|
||||
+
|
||||
+ ret = clk_set_parent(priv->mclk, priv->mclk_i958);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Enable the clock gate */
|
||||
+ ret = clk_prepare_enable(priv->iface);
|
||||
+ if (ret)
|
||||
+ goto out_clk_iface;
|
||||
+
|
||||
+ /* Enable the spdif clock */
|
||||
+ ret = clk_prepare_enable(priv->mclk);
|
||||
+ if (ret)
|
||||
+ goto out_mclk;
|
||||
+
|
||||
+ /*
|
||||
+ * Make sure the interface expect a memory layout we can work with
|
||||
+ * MEM prefixed register usually belong to the DMA, but when the spdif
|
||||
+ * DAI takes data from the i2s buffer, we need to make sure it works in
|
||||
+ * split mode and not the "normal mode" (channel samples packed in
|
||||
+ * 32 bytes groups)
|
||||
+ */
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_MEM_IEC958_CONTROL,
|
||||
+ AIU_MEM_IEC958_CONTROL_MODE_LINEAR,
|
||||
+ AIU_MEM_IEC958_CONTROL_MODE_LINEAR);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
+out_mclk:
|
||||
+ clk_disable_unprepare(priv->iface);
|
||||
+out_clk_iface:
|
||||
+ clk_disable_unprepare(priv->fast);
|
||||
+out_clk_fast:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void meson_spdif_dai_shutdown(struct snd_pcm_substream *substream,
|
||||
+ struct snd_soc_dai *dai)
|
||||
+{
|
||||
+ struct meson_spdif_dai *priv = snd_soc_dai_get_drvdata(dai);
|
||||
+
|
||||
+ clk_disable_unprepare(priv->iface);
|
||||
+ clk_disable_unprepare(priv->mclk);
|
||||
+ clk_disable_unprepare(priv->fast);
|
||||
+}
|
||||
+
|
||||
+static const struct snd_soc_dai_ops meson_spdif_dai_ops = {
|
||||
+ .startup = meson_spdif_dai_startup,
|
||||
+ .shutdown = meson_spdif_dai_shutdown,
|
||||
+ .trigger = meson_spdif_dai_trigger,
|
||||
+ .hw_params = meson_spdif_dai_hw_params,
|
||||
+};
|
||||
+
|
||||
+static struct snd_soc_dai_driver meson_spdif_dai = {
|
||||
+ .playback = {
|
||||
+ .stream_name = "Playback",
|
||||
+ .channels_min = 2,
|
||||
+ .channels_max = 2,
|
||||
+ .rates = (SNDRV_PCM_RATE_32000 |
|
||||
+ SNDRV_PCM_RATE_44100 |
|
||||
+ SNDRV_PCM_RATE_48000 |
|
||||
+ SNDRV_PCM_RATE_96000 |
|
||||
+ SNDRV_PCM_RATE_192000),
|
||||
+ .formats = (SNDRV_PCM_FMTBIT_S16_LE |
|
||||
+ SNDRV_PCM_FMTBIT_S24_LE)
|
||||
+ },
|
||||
+ .ops = &meson_spdif_dai_ops,
|
||||
+};
|
||||
+
|
||||
+static const struct snd_soc_component_driver meson_spdif_dai_component = {
|
||||
+ .name = DRV_NAME,
|
||||
+};
|
||||
+
|
||||
+static int meson_spdif_dai_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct device *dev = &pdev->dev;
|
||||
+ struct meson_spdif_dai *priv;
|
||||
+
|
||||
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ platform_set_drvdata(pdev, priv);
|
||||
+ priv->core = dev_get_drvdata(dev->parent);
|
||||
+
|
||||
+ priv->fast = devm_clk_get(dev, "fast");
|
||||
+ if (IS_ERR(priv->fast)) {
|
||||
+ if (PTR_ERR(priv->fast) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Can't get spdif fast domain clockt\n");
|
||||
+ return PTR_ERR(priv->fast);
|
||||
+ }
|
||||
+
|
||||
+ priv->iface = devm_clk_get(dev, "iface");
|
||||
+ if (IS_ERR(priv->iface)) {
|
||||
+ if (PTR_ERR(priv->iface) != -EPROBE_DEFER)
|
||||
+ dev_err(dev,
|
||||
+ "Can't get the dai clock gate\n");
|
||||
+ return PTR_ERR(priv->iface);
|
||||
+ }
|
||||
+
|
||||
+ priv->mclk_i958 = devm_clk_get(dev, "mclk_i958");
|
||||
+ if (IS_ERR(priv->mclk_i958)) {
|
||||
+ if (PTR_ERR(priv->mclk_i958) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Can't get the spdif master clock\n");
|
||||
+ return PTR_ERR(priv->mclk_i958);
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * TODO: the spdif dai can also get its data from the i2s fifo.
|
||||
+ * For this use-case, the DAI driver will need to get the i2s master
|
||||
+ * clock in order to reparent the spdif clock from cts_mclk_i958 to
|
||||
+ * cts_amclk
|
||||
+ */
|
||||
+
|
||||
+ priv->mclk = devm_clk_get(dev, "mclk");
|
||||
+ if (IS_ERR(priv->mclk)) {
|
||||
+ if (PTR_ERR(priv->mclk) != -EPROBE_DEFER)
|
||||
+ dev_err(dev, "Can't get the spdif input mux clock\n");
|
||||
+ return PTR_ERR(priv->mclk);
|
||||
+ }
|
||||
+
|
||||
+ return devm_snd_soc_register_component(dev, &meson_spdif_dai_component,
|
||||
+ &meson_spdif_dai, 1);
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id meson_spdif_dai_of_match[] = {
|
||||
+ { .compatible = "amlogic,meson-spdif-dai", },
|
||||
+ { .compatible = "amlogic,meson-gxbb-spdif-dai", },
|
||||
+ { .compatible = "amlogic,meson-gxl-spdif-dai", },
|
||||
+ {}
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, meson_spdif_dai_of_match);
|
||||
+
|
||||
+static struct platform_driver meson_spdif_dai_pdrv = {
|
||||
+ .probe = meson_spdif_dai_probe,
|
||||
+ .driver = {
|
||||
+ .name = DRV_NAME,
|
||||
+ .of_match_table = meson_spdif_dai_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(meson_spdif_dai_pdrv);
|
||||
+
|
||||
+MODULE_DESCRIPTION("Meson spdif DAI ASoC Driver");
|
||||
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
+MODULE_LICENSE("GPL v2");
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
From ba4e96a6686b91a4711ee31308d18b47ee93e793 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Fri, 31 Mar 2017 15:55:03 +0200
|
||||
Subject: [PATCH 13/21] ARM64: defconfig: enable audio support for meson SoCs
|
||||
as module
|
||||
|
||||
Add audio support for meson SoCs. This includes the audio core
|
||||
driver and the i2s and spdif output interfaces
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@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 25846051b6b5..ae1f77492a7d 100644
|
||||
--- a/arch/arm64/configs/defconfig
|
||||
+++ b/arch/arm64/configs/defconfig
|
||||
@@ -451,6 +451,10 @@ CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_BCM2835_SOC_I2S=m
|
||||
+CONFIG_SND_SOC_MESON=m
|
||||
+CONFIG_SND_SOC_MESON_I2S=m
|
||||
+CONFIG_SND_SOC_MESON_SPDIF=m
|
||||
+CONFIG_SND_SOC_RCAR=y
|
||||
CONFIG_SND_SOC_SAMSUNG=y
|
||||
CONFIG_SND_SOC_RCAR=m
|
||||
CONFIG_SND_SOC_AK4613=m
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
From 96a0e1456b91652fc7adf03f70222c0d68278eff Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Thu, 30 Mar 2017 15:19:04 +0200
|
||||
Subject: [PATCH 14/21] ARM64: dts: meson-gx: add audio controller nodes
|
||||
|
||||
Add audio controller nodes for Amlogic meson gxbb and gxl.
|
||||
This includes the audio-core node, the i2s and spdif DAIs, i2s and spdif
|
||||
aiu DMAs.
|
||||
|
||||
Audio on this SoC family is still a work in progress. More nodes are likely
|
||||
to be added later on (pcm DAIs, input DMAs, etc ...)
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 35 ++++++++++++++++++
|
||||
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 39 +++++++++++++++++++++
|
||||
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 38 ++++++++++++++++++++
|
||||
3 files changed, 112 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
|
||||
index b8dc4dbb391b..6b64b63f2a68 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi
|
||||
@@ -203,6 +203,41 @@
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
+ audio: audio@5400 {
|
||||
+ compatible = "amlogic,meson-audio-core";
|
||||
+ reg = <0x0 0x5400 0x0 0x2ac>,
|
||||
+ <0x0 0xa000 0x0 0x304>;
|
||||
+ reg-names = "aiu", "audin";
|
||||
+ status = "disabled";
|
||||
+
|
||||
+ aiu_i2s_dma: aiu_i2s_dma {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "amlogic,meson-aiu-i2s-dma";
|
||||
+ interrupts = <GIC_SPI 48 IRQ_TYPE_EDGE_RISING>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ aiu_spdif_dma: aiu_spdif_dma {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "amlogic,meson-aiu-spdif-dma";
|
||||
+ interrupts = <GIC_SPI 50 IRQ_TYPE_EDGE_RISING>;
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ i2s_dai: i2s_dai {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "amlogic,meson-i2s-dai";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ spdif_dai: spdif_dai {
|
||||
+ #sound-dai-cells = <0>;
|
||||
+ compatible = "amlogic,meson-spdif-dai";
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ };
|
||||
+
|
||||
uart_A: serial@84c0 {
|
||||
compatible = "amlogic,meson-gx-uart";
|
||||
reg = <0x0 0x84c0 0x0 0x18>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
|
||||
index 98cbba6809ca..79132496691f 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
|
||||
@@ -659,6 +659,35 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ clocks = <&clkc CLKID_AIU>,
|
||||
+ <&clkc CLKID_AIU_GLUE>,
|
||||
+ <&clkc CLKID_I2S_SPDIF>;
|
||||
+ clock-names = "aiu_top", "aiu_glue", "audin";
|
||||
+ resets = <&reset RESET_AIU>,
|
||||
+ <&reset RESET_AUDIN>;
|
||||
+ reset-names = "aiu", "audin";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ clocks = <&clkc CLKID_I2S_OUT>;
|
||||
+ clock-names = "fast";
|
||||
+};
|
||||
+
|
||||
+&aiu_spdif_dma {
|
||||
+ clocks = <&clkc CLKID_IEC958>;
|
||||
+ clock-names = "fast";
|
||||
+
|
||||
+};
|
||||
+
|
||||
+&i2s_dai {
|
||||
+ clocks = <&clkc CLKID_I2S_OUT>,
|
||||
+ <&clkc CLKID_MIXER_IFACE>,
|
||||
+ <&clkc CLKID_AOCLK_GATE>,
|
||||
+ <&clkc CLKID_CTS_AMCLK>;
|
||||
+ clock-names = "fast", "iface", "bclks", "mclk";
|
||||
+};
|
||||
+
|
||||
&pwrc_vpu {
|
||||
resets = <&reset RESET_VIU>,
|
||||
<&reset RESET_VENC>,
|
||||
@@ -741,6 +770,15 @@
|
||||
num-cs = <1>;
|
||||
};
|
||||
|
||||
+&spdif_dai {
|
||||
+ clocks = <&clkc CLKID_IEC958>,
|
||||
+ <&clkc CLKID_IEC958_GATE>,
|
||||
+ <&clkc CLKID_CTS_MCLK_I958>,
|
||||
+ <&clkc CLKID_CTS_AMCLK>,
|
||||
+ <&clkc CLKID_CTS_I958>;
|
||||
+ clock-names = "fast", "iface", "mclk_i958", "mclk_i2s", "mclk";
|
||||
+};
|
||||
+
|
||||
&spifc {
|
||||
clocks = <&clkc CLKID_SPI>;
|
||||
};
|
||||
@@ -774,3 +812,4 @@
|
||||
compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu";
|
||||
power-domains = <&pwrc_vpu>;
|
||||
};
|
||||
+
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
|
||||
index c87a80e9bcc6..20922cdc2c23 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
|
||||
@@ -660,6 +660,34 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ clocks = <&clkc CLKID_AIU>,
|
||||
+ <&clkc CLKID_AIU_GLUE>,
|
||||
+ <&clkc CLKID_I2S_SPDIF>;
|
||||
+ clock-names = "aiu_top", "aiu_glue", "audin";
|
||||
+ resets = <&reset RESET_AIU>,
|
||||
+ <&reset RESET_AUDIN>;
|
||||
+ reset-names = "aiu", "audin";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ clocks = <&clkc CLKID_I2S_OUT>;
|
||||
+ clock-names = "fast";
|
||||
+};
|
||||
+
|
||||
+&aiu_spdif_dma {
|
||||
+ clocks = <&clkc CLKID_IEC958>;
|
||||
+ clock-names = "fast";
|
||||
+};
|
||||
+
|
||||
+&i2s_dai {
|
||||
+ clocks = <&clkc CLKID_I2S_OUT>,
|
||||
+ <&clkc CLKID_MIXER_IFACE>,
|
||||
+ <&clkc CLKID_AOCLK_GATE>,
|
||||
+ <&clkc CLKID_CTS_AMCLK>;
|
||||
+ clock-names = "fast", "iface", "bclks", "mclk";
|
||||
+};
|
||||
+
|
||||
&pwrc_vpu {
|
||||
resets = <&reset RESET_VIU>,
|
||||
<&reset RESET_VENC>,
|
||||
@@ -742,6 +770,15 @@
|
||||
num-cs = <1>;
|
||||
};
|
||||
|
||||
+&spdif_dai {
|
||||
+ clocks = <&clkc CLKID_IEC958>,
|
||||
+ <&clkc CLKID_IEC958_GATE>,
|
||||
+ <&clkc CLKID_CTS_MCLK_I958>,
|
||||
+ <&clkc CLKID_CTS_AMCLK>,
|
||||
+ <&clkc CLKID_CTS_I958>;
|
||||
+ clock-names = "fast", "iface", "mclk_i958", "mclk_i2s", "mclk";
|
||||
+};
|
||||
+
|
||||
&spifc {
|
||||
clocks = <&clkc CLKID_SPI>;
|
||||
};
|
||||
@@ -775,3 +812,4 @@
|
||||
compatible = "amlogic,meson-gxl-vpu", "amlogic,meson-gx-vpu";
|
||||
power-domains = <&pwrc_vpu>;
|
||||
};
|
||||
+
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
From 97b0b5c8926cc6d9705aa799331e84ec07d52e41 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Fri, 7 Jul 2017 17:39:21 +0200
|
||||
Subject: [PATCH 15/21] snd: meson: activate HDMI audio path
|
||||
|
||||
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
||||
---
|
||||
sound/soc/meson/i2s-dai.c | 22 ++++++++++++++++++++++
|
||||
1 file changed, 22 insertions(+)
|
||||
|
||||
diff --git a/sound/soc/meson/i2s-dai.c b/sound/soc/meson/i2s-dai.c
|
||||
index 1008af8d3972..63fe098ecf82 100644
|
||||
--- a/sound/soc/meson/i2s-dai.c
|
||||
+++ b/sound/soc/meson/i2s-dai.c
|
||||
@@ -56,8 +56,19 @@ struct meson_i2s_dai {
|
||||
#define AIU_CLK_CTRL_ALRCLK_RIGHT_J (2 << 8)
|
||||
#define AIU_CLK_CTRL_MORE_I2S_DIV_MASK GENMASK(5, 0)
|
||||
#define AIU_CLK_CTRL_MORE_I2S_DIV(div) (((div) - 1) << 0)
|
||||
+#define AIU_CLK_CTRL_MORE_HDMI_TX_SEL_MASK BIT(6)
|
||||
+#define AIU_CLK_CTRL_MORE_HDMI_TX_I958_CLK (0 << 6)
|
||||
+#define AIU_CLK_CTRL_MORE_HDMI_TX_INT_CLK (1 << 6)
|
||||
#define AIU_CODEC_DAC_LRCLK_CTRL_DIV_MASK GENMASK(11, 0)
|
||||
#define AIU_CODEC_DAC_LRCLK_CTRL_DIV(div) (((div) - 1) << 0)
|
||||
+#define AIU_HDMI_CLK_DATA_CTRL_CLK_SEL_MASK GENMASK(1, 0)
|
||||
+#define AIU_HDMI_CLK_DATA_CTRL_CLK_DISABLE (0 << 0)
|
||||
+#define AIU_HDMI_CLK_DATA_CTRL_CLK_PCM (1 << 0)
|
||||
+#define AIU_HDMI_CLK_DATA_CTRL_CLK_I2S (2 << 0)
|
||||
+#define AIU_HDMI_CLK_DATA_CTRL_DATA_SEL_MASK GENMASK(5, 4)
|
||||
+#define AIU_HDMI_CLK_DATA_CTRL_DATA_MUTE (0 << 4)
|
||||
+#define AIU_HDMI_CLK_DATA_CTRL_DATA_PCM (1 << 4)
|
||||
+#define AIU_HDMI_CLK_DATA_CTRL_DATA_I2S (2 << 4)
|
||||
#define AIU_I2S_DAC_CFG_PAYLOAD_SIZE_MASK GENMASK(1, 0)
|
||||
#define AIU_I2S_DAC_CFG_AOCLK_32 (0 << 0)
|
||||
#define AIU_I2S_DAC_CFG_AOCLK_48 (2 << 0)
|
||||
@@ -221,6 +232,17 @@ static int meson_i2s_dai_hw_params(struct snd_pcm_substream *substream,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+ /* Quick and dirty hack for HDMI */
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_HDMI_CLK_DATA_CTRL,
|
||||
+ AIU_HDMI_CLK_DATA_CTRL_CLK_SEL_MASK |
|
||||
+ AIU_HDMI_CLK_DATA_CTRL_DATA_SEL_MASK,
|
||||
+ AIU_HDMI_CLK_DATA_CTRL_CLK_I2S |
|
||||
+ AIU_HDMI_CLK_DATA_CTRL_DATA_I2S);
|
||||
+
|
||||
+ regmap_update_bits(priv->core->aiu, AIU_CLK_CTRL_MORE,
|
||||
+ AIU_CLK_CTRL_MORE_HDMI_TX_SEL_MASK,
|
||||
+ AIU_CLK_CTRL_MORE_HDMI_TX_INT_CLK);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
From 6c58bdeef341501efbef53d55ad42c51d209b15f Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Tue, 14 Feb 2017 19:18:04 +0100
|
||||
Subject: [PATCH 16/21] drm/meson: select dw-hdmi i2s audio for meson hdmi
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/Kconfig | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/Kconfig b/drivers/gpu/drm/meson/Kconfig
|
||||
index 3ce51d8dfe1c..02d400b8795c 100644
|
||||
--- a/drivers/gpu/drm/meson/Kconfig
|
||||
+++ b/drivers/gpu/drm/meson/Kconfig
|
||||
@@ -13,3 +13,4 @@ config DRM_MESON_DW_HDMI
|
||||
depends on DRM_MESON
|
||||
default y if DRM_MESON
|
||||
select DRM_DW_HDMI
|
||||
+ select DRM_DW_HDMI_I2S_AUDIO
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From 09c16799996246ff509b857608f0e202dde8dc50 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Wed, 20 Sep 2017 18:01:26 +0200
|
||||
Subject: [PATCH 17/21] ARM64: dts: meson-gx: add sound-dai-cells to HDMI node
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
---
|
||||
arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 1 +
|
||||
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
|
||||
index 79132496691f..2a4d506bad4e 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
|
||||
@@ -305,6 +305,7 @@
|
||||
<&clkc CLKID_CLK81>,
|
||||
<&clkc CLKID_GCLK_VENCI_INT0>;
|
||||
clock-names = "isfr", "iahb", "venci";
|
||||
+ #sound-dai-cells = <0>;
|
||||
};
|
||||
|
||||
&sysctrl {
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
|
||||
index 20922cdc2c23..9f4b6185a61d 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
|
||||
@@ -257,6 +257,7 @@
|
||||
<&clkc CLKID_CLK81>,
|
||||
<&clkc CLKID_GCLK_VENCI_INT0>;
|
||||
clock-names = "isfr", "iahb", "venci";
|
||||
+ #sound-dai-cells = <0>;
|
||||
};
|
||||
|
||||
&sysctrl {
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,864 @@
|
||||
From bc719ab54052fc27f8089820dee4dd85373ff6b4 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Date: Wed, 20 Sep 2017 18:10:08 +0200
|
||||
Subject: [PATCH 18/21] ARM64: dts: meson: activate hdmi audio HDMI enabled
|
||||
boards
|
||||
|
||||
This patch activate audio over HDMI on selected boards
|
||||
|
||||
Please note that this audio support is based on WIP changes
|
||||
This should be considered as preview and it does not reflect
|
||||
the audio I expect to see merged
|
||||
|
||||
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
|
||||
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
||||
---
|
||||
.../boot/dts/amlogic/meson-gx-p23x-q20x.dtsi | 45 +++++++++++++++++++
|
||||
.../boot/dts/amlogic/meson-gxbb-nanopi-k2.dts | 45 +++++++++++++++++++
|
||||
.../dts/amlogic/meson-gxbb-nexbox-a95x.dts | 45 +++++++++++++++++++
|
||||
.../boot/dts/amlogic/meson-gxbb-odroidc2.dts | 45 +++++++++++++++++++
|
||||
.../boot/dts/amlogic/meson-gxbb-p20x.dtsi | 45 +++++++++++++++++++
|
||||
.../boot/dts/amlogic/meson-gxbb-wetek.dtsi | 45 +++++++++++++++++++
|
||||
.../amlogic/meson-gxl-s905x-khadas-vim.dts | 45 +++++++++++++++++++
|
||||
.../amlogic/meson-gxl-s905x-libretech-cc.dts | 45 +++++++++++++++++++
|
||||
.../amlogic/meson-gxl-s905x-nexbox-a95x.dts | 45 +++++++++++++++++++
|
||||
.../boot/dts/amlogic/meson-gxl-s905x-p212.dts | 45 +++++++++++++++++++
|
||||
.../dts/amlogic/meson-gxm-khadas-vim2.dts | 45 +++++++++++++++++++
|
||||
.../boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 45 +++++++++++++++++++
|
||||
12 files changed, 540 insertions(+)
|
||||
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
|
||||
index 88e712ea757a..319512e36e57 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gx-p23x-q20x.dtsi
|
||||
@@ -95,6 +95,39 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&cec_AO {
|
||||
@@ -104,6 +137,14 @@
|
||||
hdmi-phandle = <&hdmi_tx>;
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cvbs_vdac_port {
|
||||
cvbs_vdac_out: endpoint {
|
||||
remote-endpoint = <&cvbs_connector_in>;
|
||||
@@ -126,6 +167,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ir {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&remote_input_ao_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
|
||||
index cbe99bd4e06d..5b10de9a0bad 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
|
||||
@@ -88,6 +88,39 @@
|
||||
clock-names = "ext_clock";
|
||||
};
|
||||
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
vcc1v8: regulator-vcc1v8 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "VCC1.8V";
|
||||
@@ -131,6 +164,14 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cec_AO {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&ao_cec_pins>;
|
||||
@@ -185,6 +226,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ir {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&remote_input_ao_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
|
||||
index 4cf7f6e80c6a..ff87bdc7ddbf 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nexbox-a95x.dts
|
||||
@@ -119,6 +119,39 @@
|
||||
clock-names = "ext_clock";
|
||||
};
|
||||
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
cvbs-connector {
|
||||
compatible = "composite-video-connector";
|
||||
|
||||
@@ -154,6 +187,14 @@
|
||||
hdmi-phandle = <&hdmi_tx>;
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
ðmac {
|
||||
status = "okay";
|
||||
pinctrl-0 = <ð_rmii_pins>;
|
||||
@@ -190,6 +231,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ir {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&remote_input_ao_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
|
||||
index 54954b314a45..3da33090b8fe 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts
|
||||
@@ -110,6 +110,39 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&cec_AO {
|
||||
@@ -119,6 +152,14 @@
|
||||
hdmi-phandle = <&hdmi_tx>;
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
ðmac {
|
||||
status = "okay";
|
||||
pinctrl-0 = <ð_rgmii_pins>;
|
||||
@@ -181,6 +222,10 @@
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ir {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&remote_input_ao_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
|
||||
index ce862266b9aa..84eb93b4229f 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-p20x.dtsi
|
||||
@@ -113,6 +113,39 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&cec_AO {
|
||||
@@ -122,6 +155,14 @@
|
||||
hdmi-phandle = <&hdmi_tx>;
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cvbs_vdac_port {
|
||||
cvbs_vdac_out: endpoint {
|
||||
remote-endpoint = <&cvbs_connector_in>;
|
||||
@@ -140,6 +181,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ir {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&remote_input_ao_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
|
||||
index 70325b273bd2..7d1f1726f29d 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi
|
||||
@@ -105,6 +105,47 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
};
|
||||
|
||||
&cec_AO {
|
||||
@@ -159,6 +200,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ir {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&remote_input_ao_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
|
||||
index d32cf3846370..f053595ebdc4 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-khadas-vim.dts
|
||||
@@ -65,6 +65,39 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&cec_AO {
|
||||
@@ -74,6 +107,14 @@
|
||||
hdmi-phandle = <&hdmi_tx>;
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&hdmi_tx {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
|
||||
@@ -86,6 +127,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&i2c_A {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&i2c_a_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
|
||||
index f63bceb88caa..f56969efffba 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-libretech-cc.dts
|
||||
@@ -84,6 +84,39 @@
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
vcc_3v3: regulator-vcc_3v3 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "VCC_3V3";
|
||||
@@ -130,6 +163,14 @@
|
||||
hdmi-phandle = <&hdmi_tx>;
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cvbs_vdac_port {
|
||||
cvbs_vdac_out: endpoint {
|
||||
remote-endpoint = <&cvbs_connector_in>;
|
||||
@@ -151,6 +192,10 @@
|
||||
pinctrl-names = "default";
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&hdmi_tx {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
|
||||
index 6739697be1de..e3e777f665c0 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-nexbox-a95x.dts
|
||||
@@ -102,6 +102,39 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&cec_AO {
|
||||
@@ -111,6 +144,14 @@
|
||||
hdmi-phandle = <&hdmi_tx>;
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cvbs_vdac_port {
|
||||
cvbs_vdac_out: endpoint {
|
||||
remote-endpoint = <&cvbs_connector_in>;
|
||||
@@ -135,6 +176,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ir {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&remote_input_ao_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
|
||||
index 5896e8a5d86b..f8c66a7972b3 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxl-s905x-p212.dts
|
||||
@@ -32,6 +32,39 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&cec_AO {
|
||||
@@ -41,12 +74,24 @@
|
||||
hdmi-phandle = <&hdmi_tx>;
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cvbs_vdac_port {
|
||||
cvbs_vdac_out: endpoint {
|
||||
remote-endpoint = <&cvbs_connector_in>;
|
||||
};
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&hdmi_tx {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
|
||||
index 0868da476e41..ea71261f1855 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-khadas-vim2.dts
|
||||
@@ -85,6 +85,39 @@
|
||||
};
|
||||
};
|
||||
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
pwmleds {
|
||||
compatible = "pwm-leds";
|
||||
|
||||
@@ -205,6 +238,14 @@
|
||||
hdmi-phandle = <&hdmi_tx>;
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cpu0 {
|
||||
#cooling-cells = <2>;
|
||||
};
|
||||
@@ -255,6 +296,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&i2c_A {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&i2c_a_pins>;
|
||||
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
|
||||
index f7a1cffab4a8..b9c5e6444daa 100644
|
||||
--- a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
|
||||
+++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
|
||||
@@ -75,6 +75,39 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
+
|
||||
+ sound {
|
||||
+ compatible = "simple-audio-card";
|
||||
+ simple-audio-card,name = "meson-gx-audio";
|
||||
+
|
||||
+ assigned-clocks = <&clkc CLKID_MPLL2>,
|
||||
+ <&clkc CLKID_MPLL0>,
|
||||
+ <&clkc CLKID_MPLL1>;
|
||||
+ assigned-clock-parents = <0>, <0>, <0>;
|
||||
+ assigned-clock-rates = <294912000>,
|
||||
+ <270950400>,
|
||||
+ <393216000>;
|
||||
+
|
||||
+ simple-audio-card,dai-link@0 {
|
||||
+ /* HDMI Output */
|
||||
+ format = "i2s";
|
||||
+ mclk-fs = <256>;
|
||||
+ bitclock-master = <&i2s_dai>;
|
||||
+ frame-master = <&i2s_dai>;
|
||||
+
|
||||
+ plat {
|
||||
+ sound-dai = <&aiu_i2s_dma>;
|
||||
+ };
|
||||
+
|
||||
+ cpu {
|
||||
+ sound-dai = <&i2s_dai>;
|
||||
+ };
|
||||
+
|
||||
+ codec {
|
||||
+ sound-dai = <&hdmi_tx>;
|
||||
+ };
|
||||
+ };
|
||||
+ };
|
||||
};
|
||||
|
||||
&cec_AO {
|
||||
@@ -84,6 +117,14 @@
|
||||
hdmi-phandle = <&hdmi_tx>;
|
||||
};
|
||||
|
||||
+&audio {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&aiu_i2s_dma {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&cvbs_vdac_port {
|
||||
cvbs_vdac_out: endpoint {
|
||||
remote-endpoint = <&cvbs_connector_in>;
|
||||
@@ -129,6 +170,10 @@
|
||||
};
|
||||
};
|
||||
|
||||
+&i2s_dai {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
&ir {
|
||||
status = "okay";
|
||||
pinctrl-0 = <&remote_input_ao_pins>;
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
From 5aeac5cbf34078e6ee256ec8684ec95d5c6e5064 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
||||
Date: Mon, 2 Jul 2018 12:21:55 +0200
|
||||
Subject: [PATCH 19/21] drm: bridge: dw-hdmi: Use AUTO CTS setup mode when
|
||||
non-AHB audio
|
||||
|
||||
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
||||
---
|
||||
drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 41 ++++++++++++++---------
|
||||
1 file changed, 26 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||||
index 3c136f2b954f..a68ffbb0ce3e 100644
|
||||
--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||||
+++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
|
||||
@@ -430,8 +430,12 @@ 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 Auto CTS mode with CTS is unknown */
|
||||
+ 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);
|
||||
|
||||
@@ -501,24 +505,31 @@ 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);
|
||||
+ 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.18.0
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
From 2facc1501a79a8a8a2ad8792977a7011abc87adf Mon Sep 17 00:00:00 2001
|
||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
||||
Date: Wed, 28 Feb 2018 16:07:18 +0100
|
||||
Subject: [PATCH 20/21] drm/meson: Call drm_crtc_vblank_on /
|
||||
drm_crtc_vblank_off
|
||||
|
||||
Make sure that the CRTC code will call the enable/disable_vblank hooks.
|
||||
|
||||
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_crtc.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_crtc.c b/drivers/gpu/drm/meson/meson_crtc.c
|
||||
index 05520202c967..4dd0df0fd607 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_crtc.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_crtc.c
|
||||
@@ -102,6 +102,8 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
priv->io_base + _REG(VPP_MISC));
|
||||
|
||||
priv->viu.osd1_enabled = true;
|
||||
+
|
||||
+ drm_crtc_vblank_on(crtc);
|
||||
}
|
||||
|
||||
static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
@@ -110,6 +112,10 @@ static void meson_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
struct meson_crtc *meson_crtc = to_meson_crtc(crtc);
|
||||
struct meson_drm *priv = meson_crtc->priv;
|
||||
|
||||
+ DRM_DEBUG_DRIVER("\n");
|
||||
+
|
||||
+ drm_crtc_vblank_off(crtc);
|
||||
+
|
||||
priv->viu.osd1_enabled = false;
|
||||
priv->viu.osd1_commit = false;
|
||||
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
From cc003c1fada0ef753e1cc28c921c59066e069828 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
||||
Date: Tue, 10 Jul 2018 15:00:45 +0200
|
||||
Subject: [PATCH 21/21] media: platform: meson-ao-cec: make busy TX warning
|
||||
silent
|
||||
|
||||
Switch to dev_dbg for the busy TX message to avoid having a flood of:
|
||||
[ 228.064570] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting
|
||||
[ 230.368489] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting
|
||||
[ 234.208655] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting
|
||||
[ 236.512558] meson-ao-cec c8100100.cec: meson_ao_cec_transmit: busy TX: aborting
|
||||
|
||||
This message is only a debug hint and not an error.
|
||||
|
||||
Fixes: 7ec2c0f72cb1 ("media: platform: Add Amlogic Meson AO CEC Controller driver")
|
||||
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
|
||||
---
|
||||
drivers/media/platform/meson/ao-cec.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/media/platform/meson/ao-cec.c b/drivers/media/platform/meson/ao-cec.c
|
||||
index 8040a6285c3f..cd4be38ab5ac 100644
|
||||
--- a/drivers/media/platform/meson/ao-cec.c
|
||||
+++ b/drivers/media/platform/meson/ao-cec.c
|
||||
@@ -524,7 +524,7 @@ static int meson_ao_cec_transmit(struct cec_adapter *adap, u8 attempts,
|
||||
return ret;
|
||||
|
||||
if (reg == TX_BUSY) {
|
||||
- dev_err(&ao_cec->pdev->dev, "%s: busy TX: aborting\n",
|
||||
+ dev_dbg(&ao_cec->pdev->dev, "%s: busy TX: aborting\n",
|
||||
__func__);
|
||||
meson_ao_cec_write(ao_cec, CEC_TX_MSG_CMD, TX_ABORT, &ret);
|
||||
}
|
||||
--
|
||||
2.18.0
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From 90dc377aa5ed708a38a010e6861b468cd9373f4f Mon Sep 17 00:00:00 2001
|
||||
From: Neil Armstrong <narmstrong@baylibre.com>
|
||||
Date: Tue, 28 Feb 2017 15:23:42 +0100
|
||||
Subject: [PATCH] Disable DRM_FORMAT_ARGB8888 to make X armsoc work cirrectly
|
||||
|
||||
---
|
||||
drivers/gpu/drm/meson/meson_plane.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/drm/meson/meson_plane.c b/drivers/gpu/drm/meson/meson_plane.c
|
||||
index a32d3b6e2e12e..7ab8f4472c741 100644
|
||||
--- a/drivers/gpu/drm/meson/meson_plane.c
|
||||
+++ b/drivers/gpu/drm/meson/meson_plane.c
|
||||
@@ -117,6 +117,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
||||
priv->viu.osd1_blk0_cfg[0] |= OSD_OUTPUT_COLOR_RGB;
|
||||
|
||||
switch (fb->format->format) {
|
||||
+ case DRM_FORMAT_ARGB8888:
|
||||
case DRM_FORMAT_XRGB8888:
|
||||
/* For XRGB, replace the pixel's alpha by 0xFF */
|
||||
writel_bits_relaxed(OSD_REPLACE_EN, OSD_REPLACE_EN,
|
||||
@@ -124,6 +125,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
||||
priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_32 |
|
||||
OSD_COLOR_MATRIX_32_ARGB;
|
||||
break;
|
||||
+#if 0
|
||||
case DRM_FORMAT_ARGB8888:
|
||||
/* For ARGB, use the pixel's alpha */
|
||||
writel_bits_relaxed(OSD_REPLACE_EN, 0,
|
||||
@@ -131,6 +133,7 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
||||
priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_32 |
|
||||
OSD_COLOR_MATRIX_32_ARGB;
|
||||
break;
|
||||
+#endif
|
||||
case DRM_FORMAT_RGB888:
|
||||
priv->viu.osd1_blk0_cfg[0] |= OSD_BLK_MODE_24 |
|
||||
OSD_COLOR_MATRIX_24_RGB;
|
||||
Reference in New Issue
Block a user