From a5be43f45c13b76e880507177f5dd815ddb81ce7 Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sun, 25 Oct 2020 10:13:57 +0100 Subject: [PATCH 1/2] uboot_helper: Remove Allwinner A20 boards --- scripts/uboot_helper | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/scripts/uboot_helper b/scripts/uboot_helper index 1e4c0f2021..11e1af68a3 100755 --- a/scripts/uboot_helper +++ b/scripts/uboot_helper @@ -21,36 +21,6 @@ import sys devices = \ { 'Allwinner': { - 'A20' : { - 'bananapi': { - 'dtb': 'sun7i-a20-bananapi.dtb', - 'config': 'Bananapi_defconfig' - }, - 'cubieboard2': { - 'dtb': 'sun7i-a20-cubieboard2.dtb', - 'config': 'Cubieboard2_defconfig' - }, - 'cubietruck': { - 'dtb': 'sun7i-a20-cubietruck.dtb', - 'config': 'Cubietruck_defconfig' - }, - 'lime': { - 'dtb': 'sun7i-a20-olinuxino-lime.dtb', - 'config': 'A20-OLinuXino-Lime_defconfig' - }, - 'lime2': { - 'dtb': 'sun7i-a20-olinuxino-lime2.dtb', - 'config': 'A20-OLinuXino-Lime2_defconfig' - }, - 'micro': { - 'dtb': 'sun7i-a20-olinuxino-micro.dtb', - 'config': 'A20-OLinuXino_MICRO_defconfig' - }, - 'mk808c': { - 'dtb': 'sun7i-a20-mk808c.dtb', - 'config': 'MK808C_defconfig' - }, - }, 'A64': { 'orangepi-win': { 'dtb': 'sun50i-a64-orangepi-win.dtb', From cf5e056881caf9583f9ce63155e71f6170b918bd Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Sun, 25 Oct 2020 10:14:21 +0100 Subject: [PATCH 2/2] Allwinner: Remove support for A20 --- .../usr/share/alsa/cards/sun4i-hdmi.conf | 34 -- projects/Allwinner/devices/A20/options | 50 -- .../A20/patches/linux/0001-disp-fix.patch | 193 ------- ...002-Add-support-for-sun4i-HDMI-audio.patch | 506 ------------------ projects/Allwinner/linux/linux.arm.conf | 9 +- 5 files changed, 1 insertion(+), 791 deletions(-) delete mode 100644 projects/Allwinner/devices/A20/filesystem/usr/share/alsa/cards/sun4i-hdmi.conf delete mode 100644 projects/Allwinner/devices/A20/options delete mode 100644 projects/Allwinner/devices/A20/patches/linux/0001-disp-fix.patch delete mode 100644 projects/Allwinner/devices/A20/patches/linux/0002-Add-support-for-sun4i-HDMI-audio.patch diff --git a/projects/Allwinner/devices/A20/filesystem/usr/share/alsa/cards/sun4i-hdmi.conf b/projects/Allwinner/devices/A20/filesystem/usr/share/alsa/cards/sun4i-hdmi.conf deleted file mode 100644 index e6873ff061..0000000000 --- a/projects/Allwinner/devices/A20/filesystem/usr/share/alsa/cards/sun4i-hdmi.conf +++ /dev/null @@ -1,34 +0,0 @@ -# -# Configuration for HDMI -# - - - -sun4i-hdmi.pcm.hdmi.0 { - @args [ CARD AES0 AES1 AES2 AES3 ] - @args.CARD { type string } - @args.AES0 { type integer } - @args.AES1 { type integer } - @args.AES2 { type integer } - @args.AES3 { type integer } - type hooks - slave.pcm { - type hw - card $CARD - device 0 - } - hooks.0 { - type ctl_elems - hook_args [ - { - interface MIXER - name "IEC958 Playback Default" - lock true - preserve true - optional true - value [ $AES0 $AES1 $AES2 $AES3 ] - } - ] - } - hint.device 0 -} diff --git a/projects/Allwinner/devices/A20/options b/projects/Allwinner/devices/A20/options deleted file mode 100644 index 0b2e10dbb4..0000000000 --- a/projects/Allwinner/devices/A20/options +++ /dev/null @@ -1,50 +0,0 @@ -################################################################################ -# setup system defaults -################################################################################ - - # The TARGET_CPU variable controls which processor should be targeted for - # generated code. - case $TARGET_ARCH in - arm) - # TARGET_CPU: - # arm2 arm250 arm3 arm6 arm60 arm600 arm610 arm620 arm7 arm7m arm7d - # arm7dm arm7di arm7dmi arm70 arm700 arm700i arm710 arm710c - # arm7100 arm720 arm7500 arm7500fe arm7tdmi arm7tdmi-s arm710t - # arm720t arm740t strongarm strongarm110 strongarm1100 - # strongarm1110 arm8 arm810 arm9 arm9e arm920 arm920t arm922t - # arm946e-s arm966e-s arm968e-s arm926ej-s arm940t arm9tdmi - # arm10tdmi arm1020t arm1026ej-s arm10e arm1020e arm1022e - # arm1136j-s arm1136jf-s mpcore mpcorenovfp arm1156t2-s - # arm1176jz-s arm1176jzf-s cortex-a8 cortex-a9 cortex-r4 - # cortex-r4f cortex-m3 cortex-m1 xscale iwmmxt iwmmxt2 ep9312. - TARGET_CPU="cortex-a7" - - # TARGET_FLOAT: - # Specifies which floating-point ABI to use. Permissible values are: - # soft hard - TARGET_FLOAT="hard" - - # TARGET_FPU: - # This specifies what floating point hardware (or hardware emulation) is - # available on the target. Permissible names are: - # fpa fpe2 fpe3 maverick vfp vfpv3 vfpv3-fp16 vfpv3-d16 vfpv3-d16-fp16 - # vfpv3xd vfpv3xd-fp16 neon neon-fp16 vfpv4 vfpv4-d16 fpv4-sp-d16 - # neon-vfpv4. - TARGET_FPU="neon-vfpv4" - ;; - esac - - # Kernel target - KERNEL_TARGET="zImage" - - # OpenGL-ES implementation to use (no / bcm2835-driver / gpu-viv-bin-mx6q) - OPENGLES="mesa" - - # Mali GPU family - MALI_FAMILY="400" - - # KODI Player implementation to use (default / bcm2835-driver / libfslvpuwrap) - KODIPLAYER_DRIVER="$OPENGLES" - - # set the addon project - ADDON_PROJECT="ARMv7" diff --git a/projects/Allwinner/devices/A20/patches/linux/0001-disp-fix.patch b/projects/Allwinner/devices/A20/patches/linux/0001-disp-fix.patch deleted file mode 100644 index 478b44d433..0000000000 --- a/projects/Allwinner/devices/A20/patches/linux/0001-disp-fix.patch +++ /dev/null @@ -1,193 +0,0 @@ -From ae3215d37ca2a55642bcae6c83c3612e26275711 Mon Sep 17 00:00:00 2001 -From: Luc Verhaegen -Date: Thu, 8 Aug 2019 16:27:37 +0200 -Subject: [PATCH] kms:sunxi: add engine->crtc_mode_set() hook - -This exposes both shortcomings in universal planes, and the superfluous -intermediate structure of _engine. - -Our backends are half the conceptual old-skool style CRTC, and half the -sequencer/composer. It does not need to have any layer enabled or any -buffer attached to do something useful, it can just show a background -colour. Our 4 main layers are fully independent and can be ordered -(almost) at will. There is no primary layer. - -Universal planes still asume that there is a primary layer. And also do -limited checking on whether this actually true. - -The sun4i driver has, for some reason, an _engine struct in between, -that serves no purpose other than to provide separation where no -separation is needed, and it is clear in several cases that this -separation has holes in it. It also is a psychological barrier for -exposing things as the hardware sees it. - -So instead of quickly bolting up some code to set the crtc width and -height in the backend, it was deferred to setting the primary plane. - -So while KMS assumes that there is a primary plane, it never enforces -the primary plane to be the same dimensions as the CRTC. - -So one is able to set the faux primary plane to whatever dimensions one -likes, which then has the backend set to those dimensions, which then -trips up our whole setup... - -A very avoidable problem, on multiple fronts. - -Also, we set interlacing with _every_ plane format set. This while this -conceptually belongs to the CRTC. The fact that the information comes -from the modeline should've tipped people off that this was wrong. - -Let's at least get rid of this engine struct in future, and have direct -code dependencies between modules, so that at least this psychological -barrier disappears. - -Signed-off-by: Luc Verhaegen ---- - drivers/gpu/drm/sun4i/sun4i_backend.c | 43 ++++++++++++++------------- - drivers/gpu/drm/sun4i/sun4i_crtc.c | 2 ++ - drivers/gpu/drm/sun4i/sun8i_mixer.c | 7 +++++ - drivers/gpu/drm/sun4i/sunxi_engine.h | 7 +++++ - 4 files changed, 39 insertions(+), 20 deletions(-) - -diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c -index 606b33a28be5..4d7a33d0f77f 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_backend.c -+++ b/drivers/gpu/drm/sun4i/sun4i_backend.c -@@ -164,6 +164,28 @@ bool sun4i_backend_format_is_supported(uint32_t fmt, uint64_t modifier) - return 0; - } - -+static int sun4i_backend_crtc_mode_set(struct sunxi_engine *engine, -+ struct drm_display_mode *mode) -+{ -+ DRM_DEBUG_DRIVER("%s(DEBE%d);\n", __func__, engine->id); -+ -+ regmap_write(engine->regs, SUN4I_BACKEND_DISSIZE_REG, -+ SUN4I_BACKEND_DISSIZE(mode->crtc_hdisplay, -+ mode->crtc_vdisplay)); -+ -+ if (mode->flags & DRM_MODE_FLAG_INTERLACE) { -+ DRM_DEBUG_DRIVER("%s(DEBE%d): Enabling interlacing.\n", -+ __func__, engine->id); -+ regmap_update_bits(engine->regs, SUN4I_BACKEND_MODCTL_REG, -+ SUN4I_BACKEND_MODCTL_ITLMOD_EN, -+ SUN4I_BACKEND_MODCTL_ITLMOD_EN); -+ } else -+ regmap_update_bits(engine->regs, SUN4I_BACKEND_MODCTL_REG, -+ SUN4I_BACKEND_MODCTL_ITLMOD_EN, 0); -+ -+ return 0; -+} -+ - int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, - int layer, struct drm_plane *plane) - { -@@ -171,14 +193,6 @@ int sun4i_backend_update_layer_coord(struct sun4i_backend *backend, - - DRM_DEBUG_DRIVER("Updating layer %d\n", layer); - -- if (plane->type == DRM_PLANE_TYPE_PRIMARY) { -- DRM_DEBUG_DRIVER("Primary layer, updating global size W: %u H: %u\n", -- state->crtc_w, state->crtc_h); -- regmap_write(backend->engine.regs, SUN4I_BACKEND_DISSIZE_REG, -- SUN4I_BACKEND_DISSIZE(state->crtc_w, -- state->crtc_h)); -- } -- - /* Set height and width */ - DRM_DEBUG_DRIVER("Layer size W: %u H: %u\n", - state->crtc_w, state->crtc_h); -@@ -325,24 +339,12 @@ int sun4i_backend_update_layer_formats(struct sun4i_backend *backend, - { - struct drm_plane_state *state = plane->state; - struct drm_framebuffer *fb = state->fb; -- bool interlaced = false; - u32 val; - int ret; - - /* Clear the YUV mode */ - regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_ATTCTL_REG0(layer), - SUN4I_BACKEND_ATTCTL_REG0_LAY_YUVEN, 0); -- -- if (plane->state->crtc) -- interlaced = plane->state->crtc->state->adjusted_mode.flags -- & DRM_MODE_FLAG_INTERLACE; -- -- regmap_update_bits(backend->engine.regs, SUN4I_BACKEND_MODCTL_REG, -- SUN4I_BACKEND_MODCTL_ITLMOD_EN, -- interlaced ? SUN4I_BACKEND_MODCTL_ITLMOD_EN : 0); -- -- DRM_DEBUG_DRIVER("Switching display backend interlaced mode %s\n", -- interlaced ? "on" : "off"); - - if (fb->format->is_yuv) - return sun4i_backend_update_yuv_format(backend, layer, plane); -@@ -920,6 +922,7 @@ static const struct sunxi_engine_ops sun4i_backend_engine_ops = { - .apply_color_correction = sun4i_backend_apply_color_correction, - .disable_color_correction = sun4i_backend_disable_color_correction, - .vblank_quirk = sun4i_backend_vblank_quirk, -+ .crtc_mode_set = sun4i_backend_crtc_mode_set, - }; - - static struct regmap_config sun4i_backend_regmap_config = { -diff --git a/drivers/gpu/drm/sun4i/sun4i_crtc.c b/drivers/gpu/drm/sun4i/sun4i_crtc.c -index 9d8504f813a4..cc569d0ec49c 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_crtc.c -+++ b/drivers/gpu/drm/sun4i/sun4i_crtc.c -@@ -138,8 +138,10 @@ static void sun4i_crtc_mode_set_nofb(struct drm_crtc *crtc) - struct drm_display_mode *mode = &crtc->state->adjusted_mode; - struct drm_encoder *encoder = sun4i_crtc_get_encoder(crtc); - struct sun4i_crtc *scrtc = drm_crtc_to_sun4i_crtc(crtc); -+ struct sunxi_engine *engine = scrtc->engine; - - sun4i_tcon_mode_set(scrtc->tcon, encoder, mode); -+ engine->ops->crtc_mode_set(engine, mode); - } - - static const struct drm_crtc_helper_funcs sun4i_crtc_helper_funcs = { -diff --git a/drivers/gpu/drm/sun4i/sun8i_mixer.c b/drivers/gpu/drm/sun4i/sun8i_mixer.c -index c2eedf58bf4b..2d6c7c4501b8 100644 ---- a/drivers/gpu/drm/sun4i/sun8i_mixer.c -+++ b/drivers/gpu/drm/sun4i/sun8i_mixer.c -@@ -307,9 +307,16 @@ static struct drm_plane **sun8i_layers_init(struct drm_device *drm, - return planes; - } - -+static int sun8i_mixer_crtc_mode_set(struct sunxi_engine *engine, -+ struct drm_display_mode *mode) -+{ -+ return 0; -+} -+ - static const struct sunxi_engine_ops sun8i_engine_ops = { - .commit = sun8i_mixer_commit, - .layers_init = sun8i_layers_init, -+ .crtc_mode_set = sun8i_mixer_crtc_mode_set, - }; - - static struct regmap_config sun8i_mixer_regmap_config = { -diff --git a/drivers/gpu/drm/sun4i/sunxi_engine.h b/drivers/gpu/drm/sun4i/sunxi_engine.h -index 548710a936d5..1f3aaef2cabc 100644 ---- a/drivers/gpu/drm/sun4i/sunxi_engine.h -+++ b/drivers/gpu/drm/sun4i/sunxi_engine.h -@@ -9,6 +9,7 @@ - struct drm_plane; - struct drm_device; - struct drm_crtc_state; -+struct drm_display_mode; - - struct sunxi_engine; - -@@ -108,6 +109,12 @@ struct sunxi_engine_ops { - * This function is optional. - */ - void (*vblank_quirk)(struct sunxi_engine *engine); -+ -+ /* -+ * Sets amongst others, CRTC dimensions, and interlacing. -+ */ -+ int (*crtc_mode_set)(struct sunxi_engine *engine, -+ struct drm_display_mode *mode); - }; - - /** diff --git a/projects/Allwinner/devices/A20/patches/linux/0002-Add-support-for-sun4i-HDMI-audio.patch b/projects/Allwinner/devices/A20/patches/linux/0002-Add-support-for-sun4i-HDMI-audio.patch deleted file mode 100644 index 47d8a672c0..0000000000 --- a/projects/Allwinner/devices/A20/patches/linux/0002-Add-support-for-sun4i-HDMI-audio.patch +++ /dev/null @@ -1,506 +0,0 @@ -Subject: [2/2] drm: sun4i: hdmi: Add support for sun4i HDMI encoder audio -From: Stefan Mavrodiev -Date: Fri, 10 Jan 2020 16:11:40 +0200 - -Add HDMI audio support for the sun4i-hdmi encoder, used on -the older Allwinner chips - A10, A20, A31. - -Most of the code is based on the BSP implementation. In it -dditional formats are supported (S20_3LE and S24_LE), however -there where some problems with them and only S16_LE is left. - -Signed-off-by: Stefan Mavrodiev ---- - drivers/gpu/drm/sun4i/Kconfig | 1 + - drivers/gpu/drm/sun4i/Makefile | 1 + - drivers/gpu/drm/sun4i/sun4i_hdmi.h | 30 ++ - drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c | 375 +++++++++++++++++++++++ - drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c | 4 + - 5 files changed, 411 insertions(+) - create mode 100644 drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c - -diff --git a/drivers/gpu/drm/sun4i/Kconfig b/drivers/gpu/drm/sun4i/Kconfig -index 37e90e42943f..192b732b10cd 100644 ---- a/drivers/gpu/drm/sun4i/Kconfig -+++ b/drivers/gpu/drm/sun4i/Kconfig -@@ -19,6 +19,7 @@ if DRM_SUN4I - config DRM_SUN4I_HDMI - tristate "Allwinner A10 HDMI Controller Support" - default DRM_SUN4I -+ select SND_PCM_ELD - help - Choose this option if you have an Allwinner SoC with an HDMI - controller. -diff --git a/drivers/gpu/drm/sun4i/Makefile b/drivers/gpu/drm/sun4i/Makefile -index 0d04f2447b01..e2d82b451c36 100644 ---- a/drivers/gpu/drm/sun4i/Makefile -+++ b/drivers/gpu/drm/sun4i/Makefile -@@ -5,6 +5,7 @@ sun4i-frontend-y += sun4i_frontend.o - sun4i-drm-y += sun4i_drv.o - sun4i-drm-y += sun4i_framebuffer.o - -+sun4i-drm-hdmi-y += sun4i_hdmi_audio.o - sun4i-drm-hdmi-y += sun4i_hdmi_ddc_clk.o - sun4i-drm-hdmi-y += sun4i_hdmi_enc.o - sun4i-drm-hdmi-y += sun4i_hdmi_i2c.o -diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi.h b/drivers/gpu/drm/sun4i/sun4i_hdmi.h -index 7ad3f06c127e..456964e681b0 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_hdmi.h -+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi.h -@@ -42,7 +42,32 @@ - #define SUN4I_HDMI_VID_TIMING_POL_VSYNC BIT(1) - #define SUN4I_HDMI_VID_TIMING_POL_HSYNC BIT(0) - -+#define SUN4I_HDMI_AUDIO_CTRL_REG 0x040 -+#define SUN4I_HDMI_AUDIO_CTRL_ENABLE BIT(31) -+#define SUN4I_HDMI_AUDIO_CTRL_RESET BIT(30) -+ -+#define SUN4I_HDMI_AUDIO_FMT_REG 0x048 -+#define SUN4I_HDMI_AUDIO_FMT_SRC BIT(31) -+#define SUN4I_HDMI_AUDIO_FMT_LAYOUT BIT(3) -+#define SUN4I_HDMI_AUDIO_FMT_CH_CFG(n) (n - 1) -+#define SUN4I_HDMI_AUDIO_FMT_CH_CFG_MASK GENMASK(2, 0) -+ -+#define SUN4I_HDMI_AUDIO_PCM_REG 0x4c -+#define SUN4I_HDMI_AUDIO_PCM_CH_MAP(n, m) ((m - 1) << (n * 4)) -+#define SUN4I_HDMI_AUDIO_PCM_CH_MAP_MASK(n) (GENMASK(2, 0) << (n * 4)) -+ -+#define SUN4I_HDMI_AUDIO_CTS_REG 0x050 -+#define SUN4I_HDMI_AUDIO_CTS(n) (n & GENMASK(19, 0)) -+ -+#define SUN4I_HDMI_AUDIO_N_REG 0x054 -+#define SUN4I_HDMI_AUDIO_N(n) (n & GENMASK(19, 0)) -+ -+#define SUN4I_HDMI_AUDIO_STAT0_REG 0x58 -+#define SUN4I_HDMI_AUDIO_STAT0_FREQ(n) (n << 24) -+#define SUN4I_HDMI_AUDIO_STAT0_FREQ_MASK GENMASK(27, 24) -+ - #define SUN4I_HDMI_AVI_INFOFRAME_REG(n) (0x080 + (n)) -+#define SUN4I_HDMI_AUDIO_INFOFRAME_REG(n) (0x0a0 + (n)) - - #define SUN4I_HDMI_PAD_CTRL0_REG 0x200 - #define SUN4I_HDMI_PAD_CTRL0_BIASEN BIT(31) -@@ -283,9 +308,13 @@ struct sun4i_hdmi { - struct regmap_field *field_ddc_sda_en; - struct regmap_field *field_ddc_sck_en; - -+ u8 hdmi_audio_channels; -+ - struct sun4i_drv *drv; - - bool hdmi_monitor; -+ bool hdmi_audio; -+ - struct cec_adapter *cec_adap; - - const struct sun4i_hdmi_variant *variant; -@@ -294,5 +323,6 @@ struct sun4i_hdmi { - int sun4i_ddc_create(struct sun4i_hdmi *hdmi, struct clk *clk); - int sun4i_tmds_create(struct sun4i_hdmi *hdmi); - int sun4i_hdmi_i2c_create(struct device *dev, struct sun4i_hdmi *hdmi); -+int sun4i_hdmi_audio_create(struct sun4i_hdmi *hdmi); - - #endif /* _SUN4I_HDMI_H_ */ -diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c -new file mode 100644 -index 000000000000..b6d4199d15ce ---- /dev/null -+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_audio.c -@@ -0,0 +1,375 @@ -+// SPDX-License-Identifier: GPL-2.0-or-later -+/* -+ * Copyright (C) 2020 Olimex Ltd. -+ * Author: Stefan Mavrodiev -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "sun4i_hdmi.h" -+ -+static const struct snd_soc_dapm_widget sun4i_hdmi_audio_widgets[] = { -+ SND_SOC_DAPM_OUTPUT("TX"), -+}; -+ -+static const struct snd_soc_dapm_route sun4i_hdmi_audio_routes[] = { -+ { "TX", NULL, "Playback" }, -+}; -+ -+static const struct snd_soc_component_driver sun4i_hdmi_audio_component = { -+ .dapm_widgets = sun4i_hdmi_audio_widgets, -+ .num_dapm_widgets = ARRAY_SIZE(sun4i_hdmi_audio_widgets), -+ .dapm_routes = sun4i_hdmi_audio_routes, -+ .num_dapm_routes = ARRAY_SIZE(sun4i_hdmi_audio_routes), -+}; -+ -+static int sun4i_hdmi_audio_startup(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); -+ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); -+ u32 reg; -+ int ret; -+ -+ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_CTRL_REG, 0); -+ regmap_write(hdmi->regmap, -+ SUN4I_HDMI_AUDIO_CTRL_REG, -+ SUN4I_HDMI_AUDIO_CTRL_RESET); -+ ret = regmap_read_poll_timeout(hdmi->regmap, -+ SUN4I_HDMI_AUDIO_CTRL_REG, -+ reg, !reg, 100, 50000); -+ if (ret < 0) { -+ DRM_ERROR("Failed to reset HDMI Audio\n"); -+ return ret; -+ } -+ -+ regmap_write(hdmi->regmap, -+ SUN4I_HDMI_AUDIO_CTRL_REG, -+ SUN4I_HDMI_AUDIO_CTRL_ENABLE); -+ -+ return snd_pcm_hw_constraint_eld(substream->runtime, -+ hdmi->connector.eld); -+} -+ -+static void sun4i_hdmi_audio_shutdown(struct snd_pcm_substream *substream, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); -+ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); -+ -+ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_CTRL_REG, 0); -+} -+ -+static int sun4i_hdmi_setup_audio_infoframes(struct sun4i_hdmi *hdmi) -+{ -+ union hdmi_infoframe frame; -+ u8 buffer[14]; -+ int i, ret; -+ -+ ret = hdmi_audio_infoframe_init(&frame.audio); -+ if (ret < 0) { -+ DRM_ERROR("Failed to init HDMI audio infoframe\n"); -+ return ret; -+ } -+ -+ frame.audio.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM; -+ frame.audio.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM; -+ frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM; -+ frame.audio.channels = hdmi->hdmi_audio_channels; -+ -+ ret = hdmi_infoframe_pack(&frame, buffer, sizeof(buffer)); -+ if (ret < 0) { -+ DRM_ERROR("Failed to pack HDMI audio infoframe\n"); -+ return ret; -+ } -+ -+ for (i = 0; i < sizeof(buffer); i++) -+ writeb(buffer[i], -+ hdmi->base + SUN4I_HDMI_AUDIO_INFOFRAME_REG(i)); -+ -+ return 0; -+} -+ -+static void sun4i_hdmi_audio_set_cts_n(struct sun4i_hdmi *hdmi, -+ struct snd_pcm_hw_params *params) -+{ -+ struct drm_encoder *encoder = &hdmi->encoder; -+ struct drm_crtc *crtc = encoder->crtc; -+ const struct drm_display_mode *mode = &crtc->state->adjusted_mode; -+ u32 rate = params_rate(params); -+ u32 n, cts; -+ u64 tmp; -+ -+ /** -+ * Calculate Cycle Time Stamp (CTS) and Numerator (N): -+ * -+ * N = 128 * Samplerate / 1000 -+ * CTS = (Ftdms * N) / (128 * Samplerate) -+ */ -+ -+ n = 128 * rate / 1000; -+ tmp = (u64)(mode->clock * 1000) * n; -+ do_div(tmp, 128 * rate); -+ cts = tmp; -+ -+ regmap_write(hdmi->regmap, -+ SUN4I_HDMI_AUDIO_CTS_REG, -+ SUN4I_HDMI_AUDIO_CTS(cts)); -+ -+ regmap_write(hdmi->regmap, -+ SUN4I_HDMI_AUDIO_N_REG, -+ SUN4I_HDMI_AUDIO_N(n)); -+} -+ -+static int sun4i_hdmi_audio_set_hw_rate(struct sun4i_hdmi *hdmi, -+ struct snd_pcm_hw_params *params) -+{ -+ u32 rate = params_rate(params); -+ u32 val; -+ -+ switch (rate) { -+ case 44100: -+ val = 0x0; -+ break; -+ case 48000: -+ val = 0x2; -+ break; -+ case 32000: -+ val = 0x3; -+ break; -+ case 88200: -+ val = 0x8; -+ break; -+ case 96000: -+ val = 0x9; -+ break; -+ case 176400: -+ val = 0xc; -+ break; -+ case 192000: -+ val = 0xe; -+ break; -+ default: -+ return -EINVAL; -+ } -+ -+ regmap_update_bits(hdmi->regmap, -+ SUN4I_HDMI_AUDIO_STAT0_REG, -+ SUN4I_HDMI_AUDIO_STAT0_FREQ_MASK, -+ SUN4I_HDMI_AUDIO_STAT0_FREQ(val)); -+ -+ return 0; -+} -+ -+static int sun4i_hdmi_audio_set_hw_channels(struct sun4i_hdmi *hdmi, -+ struct snd_pcm_hw_params *params) -+{ -+ u32 channels = params_channels(params); -+ -+ if (channels > 8) -+ return -EINVAL; -+ -+ hdmi->hdmi_audio_channels = channels; -+ -+ regmap_update_bits(hdmi->regmap, -+ SUN4I_HDMI_AUDIO_FMT_REG, -+ SUN4I_HDMI_AUDIO_FMT_LAYOUT, -+ (channels > 2) ? SUN4I_HDMI_AUDIO_FMT_LAYOUT : 0); -+ -+ regmap_update_bits(hdmi->regmap, -+ SUN4I_HDMI_AUDIO_FMT_REG, -+ SUN4I_HDMI_AUDIO_FMT_CH_CFG_MASK, -+ SUN4I_HDMI_AUDIO_FMT_CH_CFG(channels)); -+ -+ regmap_write(hdmi->regmap, SUN4I_HDMI_AUDIO_PCM_REG, 0x76543210); -+ -+ /** -+ * If only one channel is required, send the same sample -+ * to the sink device as a left and right channel. -+ */ -+ if (channels == 1) -+ regmap_update_bits(hdmi->regmap, -+ SUN4I_HDMI_AUDIO_PCM_REG, -+ SUN4I_HDMI_AUDIO_PCM_CH_MAP_MASK(1), -+ SUN4I_HDMI_AUDIO_PCM_CH_MAP(1, 1)); -+ -+ return 0; -+} -+ -+static int sun4i_hdmi_audio_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *params, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); -+ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); -+ int ret; -+ -+ ret = sun4i_hdmi_audio_set_hw_rate(hdmi, params); -+ if (ret) -+ return ret; -+ -+ ret = sun4i_hdmi_audio_set_hw_channels(hdmi, params); -+ if (ret) -+ return ret; -+ -+ sun4i_hdmi_audio_set_cts_n(hdmi, params); -+ -+ return 0; -+} -+ -+static int sun4i_hdmi_audio_trigger(struct snd_pcm_substream *substream, -+ int cmd, -+ struct snd_soc_dai *dai) -+{ -+ struct snd_soc_card *card = snd_soc_dai_get_drvdata(dai); -+ struct sun4i_hdmi *hdmi = snd_soc_card_get_drvdata(card); -+ int ret = 0; -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ ret = sun4i_hdmi_setup_audio_infoframes(hdmi); -+ break; -+ default: -+ break; -+ } -+ -+ return ret; -+} -+ -+static const struct snd_soc_dai_ops sun4i_hdmi_audio_dai_ops = { -+ .startup = sun4i_hdmi_audio_startup, -+ .shutdown = sun4i_hdmi_audio_shutdown, -+ .hw_params = sun4i_hdmi_audio_hw_params, -+ .trigger = sun4i_hdmi_audio_trigger, -+}; -+ -+static int sun4i_hdmi_audio_dai_probe(struct snd_soc_dai *dai) -+{ -+ struct snd_dmaengine_dai_dma_data *dma_data; -+ -+ dma_data = devm_kzalloc(dai->dev, sizeof(*dma_data), GFP_KERNEL); -+ if (!dma_data) -+ return -ENOMEM; -+ -+ dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; -+ dma_data->maxburst = 8; -+ -+ snd_soc_dai_init_dma_data(dai, dma_data, NULL); -+ -+ return 0; -+} -+ -+static struct snd_soc_dai_driver sun4i_hdmi_audio_dai = { -+ .name = "HDMI", -+ .ops = &sun4i_hdmi_audio_dai_ops, -+ .probe = sun4i_hdmi_audio_dai_probe, -+ .playback = { -+ .stream_name = "Playback", -+ .channels_min = 1, -+ .channels_max = 8, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ }, -+}; -+ -+static const struct snd_pcm_hardware sun4i_hdmi_audio_pcm_hardware = { -+ .info = SNDRV_PCM_INFO_INTERLEAVED | -+ SNDRV_PCM_INFO_BLOCK_TRANSFER | -+ SNDRV_PCM_INFO_MMAP | -+ SNDRV_PCM_INFO_MMAP_VALID | -+ SNDRV_PCM_INFO_PAUSE | -+ SNDRV_PCM_INFO_RESUME, -+ .formats = SNDRV_PCM_FMTBIT_S16_LE, -+ .rates = SNDRV_PCM_RATE_8000_192000, -+ .rate_min = 8000, -+ .rate_max = 192000, -+ .channels_min = 1, -+ .channels_max = 8, -+ .buffer_bytes_max = 128 * 1024, -+ .period_bytes_min = 4 * 1024, -+ .period_bytes_max = 32 * 1024, -+ .periods_min = 2, -+ .periods_max = 8, -+ .fifo_size = 128, -+}; -+ -+static const struct snd_dmaengine_pcm_config sun4i_hdmi_audio_pcm_config = { -+ .chan_names[SNDRV_PCM_STREAM_PLAYBACK] = "audio-tx", -+ .pcm_hardware = &sun4i_hdmi_audio_pcm_hardware, -+ .prealloc_buffer_size = 128 * 1024, -+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, -+}; -+ -+struct snd_soc_card sun4i_hdmi_audio_card = { -+ .name = "sun4i-hdmi", -+}; -+ -+int sun4i_hdmi_audio_create(struct sun4i_hdmi *hdmi) -+{ -+ struct snd_soc_card *card = &sun4i_hdmi_audio_card; -+ struct snd_soc_dai_link_component *comp; -+ struct snd_soc_dai_link *link; -+ int ret; -+ -+ ret = devm_snd_dmaengine_pcm_register(hdmi->dev, -+ &sun4i_hdmi_audio_pcm_config, 0); -+ if (ret) { -+ DRM_ERROR("Could not register PCM\n"); -+ return ret; -+ } -+ -+ ret = devm_snd_soc_register_component(hdmi->dev, -+ &sun4i_hdmi_audio_component, -+ &sun4i_hdmi_audio_dai, 1); -+ if (ret) { -+ DRM_ERROR("Could not register DAI\n"); -+ return ret; -+ } -+ -+ link = devm_kzalloc(hdmi->dev, sizeof(*link), GFP_KERNEL); -+ if (!link) -+ return -ENOMEM; -+ -+ comp = devm_kzalloc(hdmi->dev, sizeof(*comp) * 3, GFP_KERNEL); -+ if (!comp) -+ return -ENOMEM; -+ -+ link->cpus = &comp[0]; -+ link->codecs = &comp[1]; -+ link->platforms = &comp[2]; -+ -+ link->num_cpus = 1; -+ link->num_codecs = 1; -+ link->num_platforms = 1; -+ -+ link->playback_only = 1; -+ -+ link->name = "SUN4I-HDMI"; -+ link->stream_name = "SUN4I-HDMI PCM"; -+ -+ link->codecs->name = dev_name(hdmi->dev); -+ link->codecs->dai_name = sun4i_hdmi_audio_dai.name; -+ -+ link->cpus->dai_name = dev_name(hdmi->dev); -+ -+ link->platforms->name = dev_name(hdmi->dev); -+ -+ link->dai_fmt = SND_SOC_DAIFMT_I2S; -+ -+ card->dai_link = link; -+ card->num_links = 1; -+ card->dev = hdmi->dev; -+ -+ snd_soc_card_set_drvdata(card, hdmi); -+ return devm_snd_soc_register_card(hdmi->dev, card); -+} -diff --git a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c -index a7c4654445c7..79ecd89fb705 100644 ---- a/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c -+++ b/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c -@@ -114,6 +114,9 @@ static void sun4i_hdmi_enable(struct drm_encoder *encoder) - val |= SUN4I_HDMI_VID_CTRL_HDMI_MODE; - - writel(val, hdmi->base + SUN4I_HDMI_VID_CTRL_REG); -+ -+ if (hdmi->hdmi_audio && sun4i_hdmi_audio_create(hdmi)) -+ DRM_ERROR("Couldn't create the HDMI audio adapter\n"); - } - - static void sun4i_hdmi_mode_set(struct drm_encoder *encoder, -@@ -218,6 +221,7 @@ static int sun4i_hdmi_get_modes(struct drm_connector *connector) - if (!edid) - return 0; - -+ hdmi->hdmi_audio = drm_detect_monitor_audio(edid); - hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid); - DRM_DEBUG_DRIVER("Monitor is %s monitor\n", - hdmi->hdmi_monitor ? "an HDMI" : "a DVI"); diff --git a/projects/Allwinner/linux/linux.arm.conf b/projects/Allwinner/linux/linux.arm.conf index 27672bfd80..5e8b48ec24 100644 --- a/projects/Allwinner/linux/linux.arm.conf +++ b/projects/Allwinner/linux/linux.arm.conf @@ -331,7 +331,7 @@ CONFIG_ARCH_SUNXI=y # CONFIG_MACH_SUN4I is not set # CONFIG_MACH_SUN5I is not set # CONFIG_MACH_SUN6I is not set -CONFIG_MACH_SUN7I=y +# CONFIG_MACH_SUN7I is not set CONFIG_MACH_SUN8I=y # CONFIG_MACH_SUN9I is not set CONFIG_ARCH_SUNXI_MC_SMP=y @@ -369,7 +369,6 @@ CONFIG_ARM_THUMB=y # CONFIG_ARM_THUMBEE is not set CONFIG_ARM_VIRT_EXT=y CONFIG_SWP_EMULATE=y -# CONFIG_CPU_BIG_ENDIAN is not set # CONFIG_CPU_ICACHE_DISABLE is not set # CONFIG_CPU_ICACHE_MISMATCH_WORKAROUND is not set # CONFIG_CPU_BPREDICT_DISABLE is not set @@ -390,7 +389,6 @@ CONFIG_ARM_L1_CACHE_SHIFT_6=y CONFIG_ARM_L1_CACHE_SHIFT=6 CONFIG_ARM_DMA_MEM_BUFFERABLE=y CONFIG_ARM_HEAVY_MB=y -CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y CONFIG_DEBUG_ALIGN_RODATA=y # CONFIG_ARM_ERRATA_430973 is not set CONFIG_ARM_ERRATA_643719=y @@ -1213,7 +1211,6 @@ CONFIG_CAN_DEV=y CONFIG_CAN_CALC_BITTIMING=y # CONFIG_CAN_FLEXCAN is not set # CONFIG_CAN_GRCAN is not set -# CONFIG_CAN_SUN4I is not set # CONFIG_CAN_TI_HECC is not set # CONFIG_CAN_C_CAN is not set # CONFIG_CAN_CC770 is not set @@ -4542,7 +4539,6 @@ CONFIG_RTC_I2C_AND_SPI=y # on-CPU RTC drivers # CONFIG_RTC_DRV_SUN6I=y -CONFIG_RTC_DRV_SUNXI=y # CONFIG_RTC_DRV_CADENCE is not set # CONFIG_RTC_DRV_FTRTC010 is not set # CONFIG_RTC_DRV_R7301 is not set @@ -4560,7 +4556,6 @@ CONFIG_DMA_ENGINE=y CONFIG_DMA_VIRTUAL_CHANNELS=y CONFIG_DMA_OF=y # CONFIG_ALTERA_MSGDMA is not set -CONFIG_DMA_SUN4I=y CONFIG_DMA_SUN6I=y # CONFIG_DW_AXI_DMAC is not set # CONFIG_FSL_EDMA is not set @@ -4725,7 +4720,6 @@ CONFIG_CLK_SUNXI_CLOCKS=y # CONFIG_CLK_SUNXI_PRCM_SUN8I is not set # CONFIG_CLK_SUNXI_PRCM_SUN9I is not set CONFIG_SUNXI_CCU=y -CONFIG_SUN4I_A10_CCU=y # CONFIG_SUN8I_A23_CCU is not set # CONFIG_SUN8I_A33_CCU is not set # CONFIG_SUN8I_A83T_CCU is not set @@ -4743,7 +4737,6 @@ CONFIG_TIMER_OF=y CONFIG_TIMER_PROBE=y CONFIG_CLKSRC_MMIO=y CONFIG_SUN4I_TIMER=y -CONFIG_SUN5I_HSTIMER=y CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y # CONFIG_MICROCHIP_PIT64B is not set