From 3a93356c5ff3f1295807f4abeeee5d39b795d60a Mon Sep 17 00:00:00 2001 From: Hoegeun Kwon Date: Fri, 29 Jan 2021 14:22:38 +0900 Subject: [PATCH 01/16] arm64: configs: tizen_*: Enable meson drm config options Enable meson drim config options. Change-Id: Ief736b97522ad16d0c76f1d9d1f7fde1342b827d Signed-off-by: Hoegeun Kwon Signed-off-by: Seung-Woo Kim --- arch/arm64/configs/tizen_kvims_defconfig | 8 ++++++++ arch/arm64/configs/tizen_odroidg12_defconfig | 7 +++++++ 2 files changed, 15 insertions(+) diff --git a/arch/arm64/configs/tizen_kvims_defconfig b/arch/arm64/configs/tizen_kvims_defconfig index 45f58d8..409b87a 100644 --- a/arch/arm64/configs/tizen_kvims_defconfig +++ b/arch/arm64/configs/tizen_kvims_defconfig @@ -384,6 +384,12 @@ CONFIG_AMLOGIC_SARADC=y CONFIG_AMLOGIC_DDR_TOOL=y # CONFIG_AMLOGIC_DDR_WINDOW_TOOL is not set CONFIG_AMLOGIC_DDR_BANDWIDTH=y +CONFIG_AMLOGIC_DRM=y +CONFIG_DRM_MESON=y +CONFIG_DRM_MESON_VPU=y +CONFIG_DRM_MESON_HDMI=y +CONFIG_DRM_MESON_PANEL=y +CONFIG_DRM_MESON_USE_ION=y CONFIG_AMLOGIC_TEE=y # CONFIG_AMLOGIC_PAGE_TRACE is not set # CONFIG_AMLOGIC_VMAP is not set @@ -510,6 +516,8 @@ CONFIG_VIDEO_CX231XX_DVB=y CONFIG_V4L_PLATFORM_DRIVERS=y # CONFIG_VGA_ARB is not set CONFIG_DRM=y +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_LEGACY=y CONFIG_BACKLIGHT_LCD_SUPPORT=y CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_FRAMEBUFFER_CONSOLE=y diff --git a/arch/arm64/configs/tizen_odroidg12_defconfig b/arch/arm64/configs/tizen_odroidg12_defconfig index 0198fb2..e255f53 100644 --- a/arch/arm64/configs/tizen_odroidg12_defconfig +++ b/arch/arm64/configs/tizen_odroidg12_defconfig @@ -383,6 +383,11 @@ CONFIG_AMLOGIC_SARADC=y CONFIG_AMLOGIC_DDR_TOOL=y # CONFIG_AMLOGIC_DDR_WINDOW_TOOL is not set CONFIG_AMLOGIC_DDR_BANDWIDTH=y +CONFIG_AMLOGIC_DRM=y +CONFIG_DRM_MESON=y +CONFIG_DRM_MESON_VPU=y +CONFIG_DRM_MESON_HDMI=y +CONFIG_DRM_MESON_USE_ION=y CONFIG_AMLOGIC_TEE=y # CONFIG_AMLOGIC_PAGE_TRACE is not set CONFIG_AMLOGIC_RAMDUMP=y @@ -577,6 +582,8 @@ CONFIG_V4L_PLATFORM_DRIVERS=y CONFIG_CYPRESS_FIRMWARE=m # CONFIG_VGA_ARB is not set CONFIG_DRM=y +CONFIG_DRM_LOAD_EDID_FIRMWARE=y +CONFIG_DRM_LEGACY=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_SOUND=y -- 2.7.4 From f37333761b9b9cbef022ec51deeea747ad32ae4a Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Mon, 1 Feb 2021 16:43:15 +0900 Subject: [PATCH 02/16] crypto: zstd: Remove not backported scompress The zstd was backported but there was build issue. Remove not backported scompress from ztd. Fixes: commit 147b60871fc2 ("zstd_support") Ref: commit cc388d204f77 ("BACKPORT: crypto: zstd - Add zstd support") of https://android.googlesource.com/kernel/common Signed-off-by: Seung-Woo Kim Change-Id: Icd35f40ed2295d26c26be8c82edad0108edd4ae0 --- crypto/zstd.c | 56 -------------------------------------------------------- 1 file changed, 56 deletions(-) diff --git a/crypto/zstd.c b/crypto/zstd.c index 9a76b3e..9bfd28f 100644 --- a/crypto/zstd.c +++ b/crypto/zstd.c @@ -20,7 +20,6 @@ #include #include #include -#include #define ZSTD_DEF_LEVEL 3 @@ -111,24 +110,6 @@ static int __zstd_init(void *ctx) return ret; } -static void *zstd_alloc_ctx(struct crypto_scomp *tfm) -{ - int ret; - struct zstd_ctx *ctx; - - ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return ERR_PTR(-ENOMEM); - - ret = __zstd_init(ctx); - if (ret) { - kfree(ctx); - return ERR_PTR(ret); - } - - return ctx; -} - static int zstd_init(struct crypto_tfm *tfm) { struct zstd_ctx *ctx = crypto_tfm_ctx(tfm); @@ -142,12 +123,6 @@ static void __zstd_exit(void *ctx) zstd_decomp_exit(ctx); } -static void zstd_free_ctx(struct crypto_scomp *tfm, void *ctx) -{ - __zstd_exit(ctx); - kzfree(ctx); -} - static void zstd_exit(struct crypto_tfm *tfm) { struct zstd_ctx *ctx = crypto_tfm_ctx(tfm); @@ -177,13 +152,6 @@ static int zstd_compress(struct crypto_tfm *tfm, const u8 *src, return __zstd_compress(src, slen, dst, dlen, ctx); } -static int zstd_scompress(struct crypto_scomp *tfm, const u8 *src, - unsigned int slen, u8 *dst, unsigned int *dlen, - void *ctx) -{ - return __zstd_compress(src, slen, dst, dlen, ctx); -} - static int __zstd_decompress(const u8 *src, unsigned int slen, u8 *dst, unsigned int *dlen, void *ctx) { @@ -205,13 +173,6 @@ static int zstd_decompress(struct crypto_tfm *tfm, const u8 *src, return __zstd_decompress(src, slen, dst, dlen, ctx); } -static int zstd_sdecompress(struct crypto_scomp *tfm, const u8 *src, - unsigned int slen, u8 *dst, unsigned int *dlen, - void *ctx) -{ - return __zstd_decompress(src, slen, dst, dlen, ctx); -} - static struct crypto_alg alg = { .cra_name = "zstd", .cra_flags = CRYPTO_ALG_TYPE_COMPRESS, @@ -224,18 +185,6 @@ static struct crypto_alg alg = { .coa_decompress = zstd_decompress } } }; -static struct scomp_alg scomp = { - .alloc_ctx = zstd_alloc_ctx, - .free_ctx = zstd_free_ctx, - .compress = zstd_scompress, - .decompress = zstd_sdecompress, - .base = { - .cra_name = "zstd", - .cra_driver_name = "zstd-scomp", - .cra_module = THIS_MODULE, - } -}; - static int __init zstd_mod_init(void) { int ret; @@ -244,17 +193,12 @@ static int __init zstd_mod_init(void) if (ret) return ret; - ret = crypto_register_scomp(&scomp); - if (ret) - crypto_unregister_alg(&alg); - return ret; } static void __exit zstd_mod_fini(void) { crypto_unregister_alg(&alg); - crypto_unregister_scomp(&scomp); } module_init(zstd_mod_init); -- 2.7.4 From 9216188d4f89f842c0ac7d24e4dfdfec1fc67c3b Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Tue, 30 May 2017 10:27:23 +0530 Subject: [PATCH 03/16] ANDROID: usb: gadget: configfs: Support multiple android instances Some platforms may choose to create more than one gadget ConfigFS instance, often due to the hardware having multiple USB gadget controllers which can be used simultaneously. Currently android_device_create() assumes only one gadget instance is ever created and creates a single "android0" device under the "android_usb" class, resulting in a crash if a second gadget is registered since the global android_device pointer gets overwritten with -EEXIST. Fix this by properly supporting multiple instances and naming the devices "android0", "android1", etc. when each instance is created (via mkdir). For now keep the global singleton android_device pointing to android0 for ease of use since f_midi and f_audio_source currently use create_function_device() without any context as to which gadget they will be bound to. Bug: 120441124 Fixes: 429213f5d9eb ("ANDROID: usb: gadget: configfs: Add function devices to the parent") Signed-off-by: Ajay Agarwal [jackp@codeaurora.org: reworded commit text] Signed-off-by: Jack Pham [sw0312.kim: backport from android common kernel commit 852619242c94 to support multiple udc] Signed-off-by: Seung-Woo Kim Change-Id: Iade5973db69a2a4a1800c8218b9f5fba6b59a1c8 --- drivers/usb/gadget/configfs.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/drivers/usb/gadget/configfs.c b/drivers/usb/gadget/configfs.c index 2a8528e..1f21941 100644 --- a/drivers/usb/gadget/configfs.c +++ b/drivers/usb/gadget/configfs.c @@ -26,6 +26,7 @@ void acc_disconnect(void); static struct class *android_class; static struct device *android_device; static int index; +static int gadget_index; struct device *create_function_device(char *name) { @@ -1463,15 +1464,13 @@ static void android_work(struct work_struct *data) spin_unlock_irqrestore(&cdev->lock, flags); if (status[0]) { - kobject_uevent_env(&android_device->kobj, - KOBJ_CHANGE, connected); + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, connected); pr_info("%s: sent uevent %s\n", __func__, connected[0]); uevent_sent = true; } if (status[1]) { - kobject_uevent_env(&android_device->kobj, - KOBJ_CHANGE, configured); + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, configured); pr_info("%s: sent uevent %s\n", __func__, configured[0]); uevent_sent = true; #ifdef CONFIG_AMLOGIC_USB @@ -1480,8 +1479,7 @@ static void android_work(struct work_struct *data) } if (status[2]) { - kobject_uevent_env(&android_device->kobj, - KOBJ_CHANGE, disconnected); + kobject_uevent_env(&gi->dev->kobj, KOBJ_CHANGE, disconnected); pr_info("%s: sent uevent %s\n", __func__, disconnected[0]); uevent_sent = true; #ifdef CONFIG_AMLOGIC_USB @@ -1753,21 +1751,23 @@ static int android_device_create(struct gadget_info *gi) struct device_attribute *attr; INIT_WORK(&gi->work, android_work); - android_device = device_create(android_class, NULL, - MKDEV(0, 0), NULL, "android0"); - if (IS_ERR(android_device)) - return PTR_ERR(android_device); + gi->dev = device_create(android_class, NULL, + MKDEV(0, 0), NULL, "android%d", gadget_index++); + if (IS_ERR(gi->dev)) + return PTR_ERR(gi->dev); - dev_set_drvdata(android_device, gi); + dev_set_drvdata(gi->dev, gi); + if (!android_device) + android_device = gi->dev; attrs = android_usb_attributes; while ((attr = *attrs++)) { int err; - err = device_create_file(android_device, attr); + err = device_create_file(gi->dev, attr); if (err) { - device_destroy(android_device->class, - android_device->devt); + device_destroy(gi->dev->class, + gi->dev->devt); return err; } } @@ -1775,15 +1775,15 @@ static int android_device_create(struct gadget_info *gi) return 0; } -static void android_device_destroy(void) +static void android_device_destroy(struct gadget_info *gi) { struct device_attribute **attrs; struct device_attribute *attr; attrs = android_usb_attributes; while ((attr = *attrs++)) - device_remove_file(android_device, attr); - device_destroy(android_device->class, android_device->devt); + device_remove_file(gi->dev, attr); + device_destroy(gi->dev->class, gi->dev->devt); } #else static inline int android_device_create(struct gadget_info *gi) @@ -1791,7 +1791,7 @@ static inline int android_device_create(struct gadget_info *gi) return 0; } -static inline void android_device_destroy(void) +static inline void android_device_destroy(struct gadget_info *gi) { } #endif @@ -1860,8 +1860,11 @@ err: static void gadgets_drop(struct config_group *group, struct config_item *item) { + struct gadget_info *gi; + + gi = container_of(to_config_group(item), struct gadget_info, group); config_item_put(item); - android_device_destroy(); + android_device_destroy(gi); } static struct configfs_group_operations gadgets_ops = { -- 2.7.4 From b81891757c62852b75a2eee5c99e9265a0e624e2 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Mon, 1 Feb 2021 15:52:43 +0900 Subject: [PATCH 04/16] arm64: configs: tizen_*: enable peripheral devices To support Tizen platform and TCT, enable related peripheral devices including virtual devices. Change-Id: I621ecaa8342f0c4f2b92c16dcb156e011cc42b8d Signed-off-by: Seung-Woo Kim --- arch/arm64/configs/tizen_kvims_defconfig | 5 +++++ arch/arm64/configs/tizen_odroidg12_defconfig | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/arch/arm64/configs/tizen_kvims_defconfig b/arch/arm64/configs/tizen_kvims_defconfig index 409b87a..cf5e291 100644 --- a/arch/arm64/configs/tizen_kvims_defconfig +++ b/arch/arm64/configs/tizen_kvims_defconfig @@ -484,6 +484,7 @@ CONFIG_INPUT_UINPUT=y # CONFIG_DEVKMEM is not set CONFIG_HW_RANDOM=y # CONFIG_DEVPORT is not set +CONFIG_I2C_STUB=m CONFIG_SPI=y CONFIG_SPI_DEBUG=y CONFIG_SPI_GPIO=y @@ -510,6 +511,7 @@ CONFIG_MEDIA_RC_SUPPORT=y CONFIG_MEDIA_CONTROLLER=y CONFIG_MEDIA_USB_SUPPORT=y CONFIG_USB_VIDEO_CLASS=y +CONFIG_USB_GSPCA_ZC3XX=m CONFIG_VIDEO_CX231XX=y # CONFIG_VIDEO_CX231XX_RC is not set CONFIG_VIDEO_CX231XX_DVB=y @@ -568,6 +570,7 @@ CONFIG_USB_SERIAL_PL2303=y CONFIG_USB_SERIAL_OPTION=y CONFIG_USB_ISP1301=y CONFIG_USB_GADGET=y +CONFIG_USB_DUMMY_HCD=m CONFIG_USB_F_ACM_DUMMY=y CONFIG_USB_CONFIGFS=y CONFIG_USB_CONFIGFS_ACM=y @@ -694,6 +697,8 @@ CONFIG_CRYPTO_MICHAEL_MIC=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_LZ4=y +CONFIG_CRYPTO_ZSTD=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_USER_API_SKCIPHER=y diff --git a/arch/arm64/configs/tizen_odroidg12_defconfig b/arch/arm64/configs/tizen_odroidg12_defconfig index e255f53..0fb59ea 100644 --- a/arch/arm64/configs/tizen_odroidg12_defconfig +++ b/arch/arm64/configs/tizen_odroidg12_defconfig @@ -289,6 +289,8 @@ CONFIG_AMLOGIC_INPUT=y CONFIG_AMLOGIC_INPUT_KEYBOARD=y CONFIG_AMLOGIC_ADC_KEYPADS=y CONFIG_AMLOGIC_GPIO_KEY=y +CONFIG_AMLOGIC_REMOTE=y +CONFIG_AMLOGIC_MESON_REMOTE=y CONFIG_AMLOGIC_TOUCHSCREEN=y CONFIG_AMLOGIC_TOUCHSCREEN_FTS=y CONFIG_AMLOGIC_TOUCHSCREEN_GT1X=y @@ -527,6 +529,7 @@ CONFIG_INPUT_MISC=y CONFIG_INPUT_UINPUT=y # CONFIG_LEGACY_PTYS is not set CONFIG_HW_RANDOM=y +CONFIG_I2C_STUB=m CONFIG_SPI=y CONFIG_SPI_DEBUG=y CONFIG_SPI_GPIO=y @@ -637,6 +640,7 @@ CONFIG_USB_SERIAL_PL2303=y CONFIG_USB_SERIAL_OPTION=y CONFIG_USB_ISP1301=y CONFIG_USB_GADGET=y +CONFIG_USB_DUMMY_HCD=m CONFIG_USB_F_ACM_DUMMY=y CONFIG_USB_CONFIGFS=y CONFIG_USB_CONFIGFS_ACM=y @@ -771,6 +775,8 @@ CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MICHAEL_MIC=y CONFIG_CRYPTO_SHA512=y CONFIG_CRYPTO_TWOFISH=y +CONFIG_CRYPTO_LZ4=y +CONFIG_CRYPTO_ZSTD=y CONFIG_CRYPTO_ANSI_CPRNG=y CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_USER_API_SKCIPHER=y -- 2.7.4 From 9976738e59153f805bdbfcfe09f3433b8e229a8a Mon Sep 17 00:00:00 2001 From: Hoegeun Kwon Date: Tue, 2 Feb 2021 16:20:10 +0900 Subject: [PATCH 05/16] arm64: dts: amlogic: Fix to use drm for odroid-c4 Fix to use g12a_drm for odroid-c4. Change-Id: I031e0e3e51c01d4f87a68a63177fbb195111d983 Signed-off-by: Hoegeun Kwon Signed-off-by: Seung-Woo Kim --- arch/arm64/boot/dts/amlogic/meson64_odroidc4.dts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/amlogic/meson64_odroidc4.dts b/arch/arm64/boot/dts/amlogic/meson64_odroidc4.dts index a8aeb3a..168adbe 100644 --- a/arch/arm64/boot/dts/amlogic/meson64_odroidc4.dts +++ b/arch/arm64/boot/dts/amlogic/meson64_odroidc4.dts @@ -19,6 +19,7 @@ #include "mesonsm1.dtsi" #include "mesong12_odroid_common.dtsi" +#include "mesong12a_drm.dtsi" / { model = "Hardkernel ODROID-C4"; @@ -354,7 +355,7 @@ compatible = "amlogic, meson-g12a"; /*memory-region = <&logo_reserved>;*/ dev_name = "meson-fb"; - status = "okay"; + status = "disabled"; interrupts = <0 3 1 0 56 1 0 89 1>; @@ -973,3 +974,17 @@ &i2c3 { status = "disabled"; }; + +&drm_vpu { + status = "okay"; + logo_addr = "0x3f800000"; +}; + +&drm_amhdmitx { + status = "okay"; + hdcp = "disabled"; +}; + +&drm_lcd { + status = "disabled"; +}; -- 2.7.4 From 4ea109181274fcc35df69987bbea04285848c2eb Mon Sep 17 00:00:00 2001 From: Hoegeun Kwon Date: Tue, 2 Feb 2021 16:29:00 +0900 Subject: [PATCH 06/16] arm64: dts: amlogic: Fix use drm of g12b for odroid-n2 The odroid-n2 has g12b soc family, so use the g12b drm instead of g12a. Change-Id: I2fb0cd03e6b9289bcd4361a80fdbeaad6a45d2bb Signed-off-by: Hoegeun Kwon Signed-off-by: Seung-Woo Kim --- arch/arm64/boot/dts/amlogic/meson64_odroidn2_drm.dts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/meson64_odroidn2_drm.dts b/arch/arm64/boot/dts/amlogic/meson64_odroidn2_drm.dts index bd0e5a6..6c5aa70 100644 --- a/arch/arm64/boot/dts/amlogic/meson64_odroidn2_drm.dts +++ b/arch/arm64/boot/dts/amlogic/meson64_odroidn2_drm.dts @@ -18,7 +18,7 @@ /dts-v1/; #include "meson64_odroidn2.dts" -#include "mesong12a_drm.dtsi" +#include "mesong12b_drm.dtsi" &meson_fb { status = "disabled"; @@ -26,7 +26,6 @@ &drm_vpu { status = "okay"; - compatible = "amlogic,meson-g12b-vpu"; logo_addr = "0x7f800000"; }; -- 2.7.4 From b77350d9a27657139c303cec4461230c179e9e14 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Tue, 2 Feb 2021 16:30:56 +0900 Subject: [PATCH 07/16] arm64: dts: amlogic: VIM3/VIM3L: change display to drm Instead of fbdev, change display to drm. Change-Id: I1c49c92f83ae4c9904116143881839d55cac2634 Signed-off-by: Seung-Woo Kim --- arch/arm64/boot/dts/amlogic/kvim3_linux.dts | 17 ++++++++++++++++- arch/arm64/boot/dts/amlogic/kvim3l_linux.dts | 17 ++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/kvim3_linux.dts b/arch/arm64/boot/dts/amlogic/kvim3_linux.dts index 6583f3a..8961974 100644 --- a/arch/arm64/boot/dts/amlogic/kvim3_linux.dts +++ b/arch/arm64/boot/dts/amlogic/kvim3_linux.dts @@ -20,6 +20,7 @@ #include "mesong12b.dtsi" #include "partition_linux.dtsi" #include "khadas-ts050-panel.dtsi" +#include "mesong12b_drm.dtsi" / { model = "Khadas VIM3"; @@ -876,7 +877,7 @@ }; &meson_fb { - status = "okay"; + status = "disabled"; display_size_default = <1920 1080 1920 2160 32>; mem_size = <0x00800000 0x4b80000 0x100000 0x100000 0x800000>; logo_addr = "0x7f800000"; @@ -885,6 +886,20 @@ 4k2k_fb = <1>; }; +&drm_vpu { + status = "okay"; + logo_addr = "0x7f800000"; +}; + +&drm_amhdmitx { + status = "okay"; + hdcp = "disabled"; +}; + +&drm_lcd { + status = "disabled"; +}; + &pwm_ab { status = "okay"; }; diff --git a/arch/arm64/boot/dts/amlogic/kvim3l_linux.dts b/arch/arm64/boot/dts/amlogic/kvim3l_linux.dts index 1c38e44..de3e240 100644 --- a/arch/arm64/boot/dts/amlogic/kvim3l_linux.dts +++ b/arch/arm64/boot/dts/amlogic/kvim3l_linux.dts @@ -20,6 +20,7 @@ #include "mesonsm1.dtsi" #include "partition_linux.dtsi" #include "khadas-ts050-panel.dtsi" +#include "mesong12a_drm.dtsi" / { model = "Khadas VIM3L"; @@ -1070,7 +1071,7 @@ }; /* end of / */ &meson_fb { - status = "okay"; + status = "disabled"; display_size_default = <1920 1080 1920 2160 32>; mem_size = <0x00800000 0x4b80000 0x100000 0x100000 0x800000>; logo_addr = "0x7f800000"; @@ -1079,6 +1080,20 @@ 4k2k_fb = <1>; }; +&drm_vpu { + status = "okay"; + logo_addr = "0x7f800000"; +}; + +&drm_amhdmitx { + status = "okay"; + hdcp = "disabled"; +}; + +&drm_lcd { + status = "disabled"; +}; + &pwm_AO_cd { status = "okay"; }; -- 2.7.4 From 4ec7cc3e85ec61360059af79ef5947c65ad5b889 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Tue, 2 Feb 2021 19:16:12 +0100 Subject: [PATCH 08/16] Add perf package build Add build of the perf performance monitoring tool package. Based on spec from the platform/kernel/linux-rpi3 kernel tree. Change-Id: Iedee81ac5f81f63c40ed6a379f2fca3f793c4d8b Signed-off-by: Sylwester Nawrocki --- packaging/linux-amlogic.spec | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/packaging/linux-amlogic.spec b/packaging/linux-amlogic.spec index fb61b40..2aef3dc 100644 --- a/packaging/linux-amlogic.spec +++ b/packaging/linux-amlogic.spec @@ -34,6 +34,12 @@ BuildRequires: module-init-tools BuildRequires: bison BuildRequires: flex BuildRequires: libopenssl1.1-devel +BuildRequires: libunwind-devel +BuildRequires: libdw-devel +BuildRequires: libelf-devel +BuildRequires: elfutils +BuildRequires: xz-devel +BuildRequires: binutils-devel %description The Linux Kernel, the operating system core itself @@ -115,6 +121,15 @@ Provides: linux-kernel-devel-amlogic-kvim = %{version}-%{CHIPSET}-kvim %description -n linux-kernel-devel-amlogic-kvim This package provides kernel map and etc information. %endif + +%package -n linux-kernel-perf +Summary: The perf performance counter tool +Group: System/Kernel +Provides: perf = %{fullVersion} + +%description -n linux-kernel-perf +This package provides the "perf" tool that can be used to monitor performance +counter events as well as various kernel internal events. ## 0. End of Packages lists %prep @@ -212,6 +227,14 @@ mv %{_builddir}/uapi-headers/usr %{buildroot} mv %{_builddir}/boot/* %{buildroot}/boot mv %{_builddir}/lib %{buildroot} %endif + +# 2-3. Install perf +install -d %{buildroot}/usr +make -s -C tools/perf EXTRA_CFLAGS="-fPIE -rdynamic" DESTDIR=%{buildroot}/usr install NO_LIBPERL=1 +rm -rf %{buildroot}/usr/etc +rm -rf %{buildroot}/usr/lib/debug +rm -rf %{buildroot}/usr/lib/perf +rm -rf %{buildroot}/usr/share ## 2. End of install steps %clean @@ -252,4 +275,10 @@ rm -rf %{_builddir}/lib %files -n linux-kernel-devel-amlogic-kvim /boot/%{TARGET_VIMS}/kernel/* %endif + +%files -n linux-kernel-perf +%license COPYING +/usr/bin/* +/usr/libexec/* +/usr/lib/traceevent/* ## 3. End of rpm pack -- 2.7.4 From f856681273ba71fa7e833f57cf23cb92e034cb0c Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Tue, 2 Feb 2021 11:24:36 +0100 Subject: [PATCH 09/16] of: fix reserved memory handling Mainline u-boot marks some secure monitor relate memory with the /memreserve/ device-tree method. On the other hand, the same memory is already defined in /reserved-memory node with the all details needed to use it by the respective secure monitor deamon. Check for such case and properly initialize such reserved memory regions instead of returning a failure. This allows to use vendor kernel with mainline u-boot on Amlogic SoCs. Signed-off-by: Marek Szyprowski Change-Id: I0bd3b51899cc17f17d1bcbd0c2c5a0d88686b245 --- drivers/of/of_reserved_mem.c | 8 ++++++++ include/linux/memblock.h | 1 + mm/memblock.c | 10 ++++++++++ 3 files changed, 19 insertions(+) diff --git a/drivers/of/of_reserved_mem.c b/drivers/of/of_reserved_mem.c index c4a7b04..aa5ed94 100644 --- a/drivers/of/of_reserved_mem.c +++ b/drivers/of/of_reserved_mem.c @@ -43,6 +43,14 @@ int __init __weak early_init_dt_alloc_reserved_memory_arch(phys_addr_t size, phys_addr_t *res_base) { phys_addr_t base; + + /* check if the region has been alredy reserved by the bootloader */ + if (start && end && memblock_is_region_reserved(start, end - start)) { + pr_info("OF: region (%pa--%pa) is reserved both in /memreserve/ and /reserved-memory, fixing\n", + &start, &end); + memblock_unreserve(start, end - start); + } + /* * We use __memblock_alloc_base() because memblock_alloc_base() * panic()s on allocation failure. diff --git a/include/linux/memblock.h b/include/linux/memblock.h index 4024af0..debfcb9 100644 --- a/include/linux/memblock.h +++ b/include/linux/memblock.h @@ -84,6 +84,7 @@ int memblock_add(phys_addr_t base, phys_addr_t size); int memblock_remove(phys_addr_t base, phys_addr_t size); int memblock_free(phys_addr_t base, phys_addr_t size); int memblock_reserve(phys_addr_t base, phys_addr_t size); +int memblock_unreserve(phys_addr_t base, phys_addr_t size); void memblock_trim_memory(phys_addr_t align); bool memblock_overlaps_region(struct memblock_type *type, phys_addr_t base, phys_addr_t size); diff --git a/mm/memblock.c b/mm/memblock.c index 42b98af..71867c2 100644 --- a/mm/memblock.c +++ b/mm/memblock.c @@ -733,6 +733,16 @@ int __init_memblock memblock_reserve(phys_addr_t base, phys_addr_t size) return memblock_add_range(&memblock.reserved, base, size, MAX_NUMNODES, 0); } +int __init_memblock memblock_unreserve(phys_addr_t base, phys_addr_t size) +{ + memblock_dbg(" memblock_unreserve: [%#016llx-%#016llx] %pF\n", + (unsigned long long)base, + (unsigned long long)base + size - 1, + (void *)_RET_IP_); + + return memblock_remove_range(&memblock.reserved, base, size); +} + /** * * This function isolates region [@base, @base + @size), and sets/clears flag -- 2.7.4 From 1156b464e225eacd149a405134d46b3fd9649a54 Mon Sep 17 00:00:00 2001 From: Marek Szyprowski Date: Fri, 5 Feb 2021 14:15:35 +0100 Subject: [PATCH 10/16] arm64: dts: amlogic: Use only meson64_odroidn2.dtb for OdroidN2 boards Switch OdroidN2 board to use meson64_odroidn2.dtb. For Tizen, the DRM subsystem is enabled for the all Amlogic boards, so there is no need to have separate dtb with the DRM enabled for OdroidN2 board. This also fixes DRM support for the OdroidN2+ variant, which use meson64_odroidn2_plus.dtb, which is based on meson64_odroidn2.dts. Signed-off-by: Marek Szyprowski Change-Id: Ideeefcaabe5355e59f564abba730e1ad88ea2ce8 --- arch/arm64/boot/dts/amlogic/Makefile | 1 - arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts | 19 +++++++++++ .../boot/dts/amlogic/meson64_odroidn2_drm.dts | 39 ---------------------- 3 files changed, 19 insertions(+), 40 deletions(-) delete mode 100644 arch/arm64/boot/dts/amlogic/meson64_odroidn2_drm.dts diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile index 81034e2..d18eaa5d 100644 --- a/arch/arm64/boot/dts/amlogic/Makefile +++ b/arch/arm64/boot/dts/amlogic/Makefile @@ -24,7 +24,6 @@ dtb-$(CONFIG_ARCH_MESON64_ODROIDC4) += meson64_odroidc4.dtb dtb-$(CONFIG_ARCH_MESON64_ODROIDC4) += meson64_odroidhc4.dtb dtb-$(CONFIG_ARCH_MESON64_ODROIDN2) += meson64_odroidn2.dtb dtb-$(CONFIG_ARCH_MESON64_ODROIDN2) += meson64_odroidn2_plus.dtb -dtb-$(CONFIG_ARCH_MESON64_ODROIDN2) += meson64_odroidn2_drm.dtb subdir-$(CONFIG_ARCH_MESON64_ODROIDC4) += overlays/odroidc4 subdir-$(CONFIG_ARCH_MESON64_ODROIDN2) += overlays/odroidn2 diff --git a/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts b/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts index a2a0ea9..4da3b15 100644 --- a/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts +++ b/arch/arm64/boot/dts/amlogic/meson64_odroidn2.dts @@ -19,6 +19,7 @@ #include "mesong12b_a.dtsi" #include "meson64_odroidn2.dtsi" +#include "mesong12b_drm.dtsi" / { model = "Hardkernel ODROID-N2"; @@ -146,3 +147,21 @@ status = "okay"; }; }; /* end of / */ + +&meson_fb { + status = "disabled"; +}; + +&drm_vpu { + status = "okay"; + logo_addr = "0x7f800000"; +}; + +&drm_amhdmitx { + status = "okay"; + hdcp = "disabled"; +}; + +&drm_lcd { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/amlogic/meson64_odroidn2_drm.dts b/arch/arm64/boot/dts/amlogic/meson64_odroidn2_drm.dts deleted file mode 100644 index 6c5aa70..0000000 --- a/arch/arm64/boot/dts/amlogic/meson64_odroidn2_drm.dts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * arch/arm64/boot/dts/amlogic/meson64_odroidn2_drm.dts - * - * Copyright (C) 2019 Hardkernel Co,. Ltd. 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. - * - */ - -/dts-v1/; - -#include "meson64_odroidn2.dts" -#include "mesong12b_drm.dtsi" - -&meson_fb { - status = "disabled"; -}; - -&drm_vpu { - status = "okay"; - logo_addr = "0x7f800000"; -}; - -&drm_amhdmitx { - status = "okay"; - hdcp = "disabled"; -}; - -&drm_lcd { - status = "disabled"; -}; -- 2.7.4 From 8cb922922e39823a2e214519fbcb86bdc4f9e9f6 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Wed, 17 Feb 2021 10:32:21 +0900 Subject: [PATCH 11/16] ARM/ARM64: defconfig: disable SECURITY_SMACK_NETFILTER config Disable SECURITY_SMACK_NETFILTER configuration. Change-Id: Ifc649881900c93064d9e48ef1e762d5ee335a9e2 Signed-off-by: Jaehoon Chung --- arch/arm64/configs/tizen_kvims_defconfig | 1 - arch/arm64/configs/tizen_odroidg12_defconfig | 1 - 2 files changed, 2 deletions(-) diff --git a/arch/arm64/configs/tizen_kvims_defconfig b/arch/arm64/configs/tizen_kvims_defconfig index cf5e291..3351f0d 100644 --- a/arch/arm64/configs/tizen_kvims_defconfig +++ b/arch/arm64/configs/tizen_kvims_defconfig @@ -690,7 +690,6 @@ CONFIG_SECURITYFS=y CONFIG_SECURITY_PATH=y CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SMACK=y -CONFIG_SECURITY_SMACK_NETFILTER=y CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MICHAEL_MIC=y diff --git a/arch/arm64/configs/tizen_odroidg12_defconfig b/arch/arm64/configs/tizen_odroidg12_defconfig index 0fb59ea..2ee8981 100644 --- a/arch/arm64/configs/tizen_odroidg12_defconfig +++ b/arch/arm64/configs/tizen_odroidg12_defconfig @@ -769,7 +769,6 @@ CONFIG_SECURITYFS=y CONFIG_SECURITY_PATH=y CONFIG_HARDENED_USERCOPY=y CONFIG_SECURITY_SMACK=y -CONFIG_SECURITY_SMACK_NETFILTER=y CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y CONFIG_CRYPTO_MD4=y CONFIG_CRYPTO_MICHAEL_MIC=y -- 2.7.4 From 678d419a343f75547de83ca20cd0656c0f464c5f Mon Sep 17 00:00:00 2001 From: "Sihyun, Park" Date: Mon, 12 Apr 2021 15:36:32 +0900 Subject: [PATCH 12/16] amlogic: drm: disable 'meson_fb is NULL! warning log The log is printed when ovelay layer has no content to display, and it is normal thing. Change-Id: I83f078a2670f5f98098d5508603b77b6d5820d4e Signed-off-by: Sihyun, Park Signed-off-by: Seung-Woo Kim --- drivers/amlogic/drm/meson_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/amlogic/drm/meson_plane.c b/drivers/amlogic/drm/meson_plane.c index 08270f1..7a66a9c 100644 --- a/drivers/amlogic/drm/meson_plane.c +++ b/drivers/amlogic/drm/meson_plane.c @@ -152,7 +152,7 @@ static int meson_plane_fb_check(struct drm_plane *plane, #ifdef CONFIG_DRM_MESON_USE_ION meson_fb = container_of(fb, struct am_meson_fb, base); if (!meson_fb) { - DRM_INFO("meson_fb is NULL!\n"); + DRM_DEBUG("meson_fb is NULL!\n"); return -EINVAL; } phyaddr = am_meson_gem_object_get_phyaddr(drv, meson_fb->bufp); -- 2.7.4 From c1ddcee7e73b2242ed2a85cc5f41cc51cbebae67 Mon Sep 17 00:00:00 2001 From: "Sihyun, Park" Date: Mon, 12 Apr 2021 15:38:35 +0900 Subject: [PATCH 13/16] amlogic: drm: mmap a dmabuf imported from another driver Change-Id: Iff7d5c204bbffac22e528840f264f669cae21d96 Signed-off-by: Sihyun, Park Signed-off-by: Seung-Woo Kim --- drivers/amlogic/drm/meson_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/amlogic/drm/meson_gem.c b/drivers/amlogic/drm/meson_gem.c index fba2bb7..7c472e3 100644 --- a/drivers/amlogic/drm/meson_gem.c +++ b/drivers/amlogic/drm/meson_gem.c @@ -160,7 +160,7 @@ int am_meson_gem_object_mmap( vma->vm_pgoff = 0; if (obj->base.import_attach) { - DRM_ERROR("Not support import buffer from other driver.\n"); + return dma_buf_mmap(obj->base.dma_buf, vma, 0); } else { buffer = obj->handle->buffer; -- 2.7.4 From 1fcbd6d000def5bd7c6099b2a3e74bc30b7cd752 Mon Sep 17 00:00:00 2001 From: Ao Xu Date: Mon, 12 Apr 2021 15:38:45 +0900 Subject: [PATCH 14/16] amlogic: drm: don't call irq in crtc init stage vblank_disable_fn and am_meson_vpu_irq exist deadlock. Disable vblank_disable_fn to avoid spin_lock_irqsave to resolve the deadlock issue. Change-Id: I59b454d2c2c0535f2e786e3beb4ca31c124483b0 Signed-off-by: Ao Xu Signed-off-by: Sihyun, Park Signed-off-by: Seung-Woo Kim --- drivers/amlogic/drm/meson_crtc.c | 13 ++----------- drivers/amlogic/drm/meson_crtc.h | 4 +--- drivers/amlogic/drm/meson_drv.c | 15 ++------------- drivers/amlogic/drm/meson_vpu.c | 35 +++++++---------------------------- 4 files changed, 12 insertions(+), 55 deletions(-) diff --git a/drivers/amlogic/drm/meson_crtc.c b/drivers/amlogic/drm/meson_crtc.c index 011f871..05e79bd 100644 --- a/drivers/amlogic/drm/meson_crtc.c +++ b/drivers/amlogic/drm/meson_crtc.c @@ -97,7 +97,6 @@ static bool am_meson_crtc_mode_fixup(struct drm_crtc *crtc, static void am_meson_crtc_enable(struct drm_crtc *crtc) { - unsigned long flags; char *name; enum vmode_e mode; struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode; @@ -124,16 +123,12 @@ static void am_meson_crtc_enable(struct drm_crtc *crtc) update_vout_viu(); memcpy(&pipeline->mode, adjusted_mode, sizeof(struct drm_display_mode)); - spin_lock_irqsave(&amcrtc->vblank_irq_lock, flags); - amcrtc->vblank_enable = 1; - spin_unlock_irqrestore(&amcrtc->vblank_irq_lock, flags); - enable_irq(amcrtc->vblank_irq); + enable_irq(amcrtc->irq); } static void am_meson_crtc_disable(struct drm_crtc *crtc) { struct am_meson_crtc *amcrtc = to_am_meson_crtc(crtc); - unsigned long flags; DRM_INFO("%s\n", __func__); if (crtc->state->event && !crtc->state->active) { @@ -143,11 +138,7 @@ static void am_meson_crtc_disable(struct drm_crtc *crtc) crtc->state->event = NULL; } - spin_lock_irqsave(&amcrtc->vblank_irq_lock, flags); - amcrtc->vblank_enable = 0; - spin_unlock_irqrestore(&amcrtc->vblank_irq_lock, flags); - - disable_irq(amcrtc->vblank_irq); + disable_irq(amcrtc->irq); } static void am_meson_crtc_commit(struct drm_crtc *crtc) diff --git a/drivers/amlogic/drm/meson_crtc.h b/drivers/amlogic/drm/meson_crtc.h index d97dd7b..7370177 100644 --- a/drivers/amlogic/drm/meson_crtc.h +++ b/drivers/amlogic/drm/meson_crtc.h @@ -46,9 +46,7 @@ struct am_meson_crtc { struct drm_pending_vblank_event *event; - unsigned int vblank_irq; - spinlock_t vblank_irq_lock;/*atomic*/ - u32 vblank_enable; + unsigned int irq; struct dentry *crtc_debugfs_dir; diff --git a/drivers/amlogic/drm/meson_drv.c b/drivers/amlogic/drm/meson_drv.c index bfa6893..f94d45b 100644 --- a/drivers/amlogic/drm/meson_drv.c +++ b/drivers/amlogic/drm/meson_drv.c @@ -95,23 +95,11 @@ EXPORT_SYMBOL(am_meson_unregister_crtc_funcs); static int am_meson_enable_vblank(struct drm_device *dev, unsigned int crtc) { - struct meson_drm *priv = dev->dev_private; - - if (crtc >= MESON_MAX_CRTC) - return -EBADFD; - - priv->crtc_funcs[crtc]->enable_vblank(priv->crtc); return 0; } static void am_meson_disable_vblank(struct drm_device *dev, unsigned int crtc) { - struct meson_drm *priv = dev->dev_private; - - if (crtc >= MESON_MAX_CRTC) - return; - - priv->crtc_funcs[crtc]->disable_vblank(priv->crtc); } static void am_meson_load(struct drm_device *dev) @@ -271,7 +259,8 @@ static int am_meson_drm_bind(struct device *dev) drm->mode_config.funcs = &meson_mode_config_funcs; drm->mode_config.allow_fb_modifiers = true; /* - * irq will init in each crtc, just mark the enable flag here. + * enable drm irq mode. + * - with irq_enabled = true, we can use the vblank feature. */ drm->irq_enabled = true; diff --git a/drivers/amlogic/drm/meson_vpu.c b/drivers/amlogic/drm/meson_vpu.c index ca025a8..83caebe 100644 --- a/drivers/amlogic/drm/meson_vpu.c +++ b/drivers/amlogic/drm/meson_vpu.c @@ -291,10 +291,10 @@ static int am_meson_crtc_loader_protect(struct drm_crtc *crtc, bool on) DRM_INFO("%s %d\n", __func__, on); if (on) { - enable_irq(amcrtc->vblank_irq); + enable_irq(amcrtc->irq); drm_crtc_vblank_on(crtc); } else { - disable_irq(amcrtc->vblank_irq); + disable_irq(amcrtc->irq); drm_crtc_vblank_off(crtc); } @@ -303,24 +303,11 @@ static int am_meson_crtc_loader_protect(struct drm_crtc *crtc, bool on) static int am_meson_crtc_enable_vblank(struct drm_crtc *crtc) { - unsigned long flags; - struct am_meson_crtc *amcrtc = to_am_meson_crtc(crtc); - - spin_lock_irqsave(&amcrtc->vblank_irq_lock, flags); - amcrtc->vblank_enable = true; - spin_unlock_irqrestore(&amcrtc->vblank_irq_lock, flags); - return 0; } static void am_meson_crtc_disable_vblank(struct drm_crtc *crtc) { - unsigned long flags; - struct am_meson_crtc *amcrtc = to_am_meson_crtc(crtc); - - spin_lock_irqsave(&amcrtc->vblank_irq_lock, flags); - amcrtc->vblank_enable = false; - spin_unlock_irqrestore(&amcrtc->vblank_irq_lock, flags); } const struct meson_crtc_funcs meson_private_crtc_funcs = { @@ -369,15 +356,9 @@ void am_meson_crtc_handle_vsync(struct am_meson_crtc *amcrtc) void am_meson_crtc_irq(struct meson_drm *priv) { - unsigned long flags; struct am_meson_crtc *amcrtc = to_am_meson_crtc(priv->crtc); - spin_lock_irqsave(&amcrtc->vblank_irq_lock, flags); - if (amcrtc->vblank_enable) { - osd_drm_vsync_isr_handler(); - am_meson_crtc_handle_vsync(amcrtc); - } - spin_unlock_irqrestore(&amcrtc->vblank_irq_lock, flags); + am_meson_crtc_handle_vsync(amcrtc); } static irqreturn_t am_meson_vpu_irq(int irq, void *arg) @@ -484,17 +465,15 @@ static int am_meson_vpu_bind(struct device *dev, dev_err(dev, "cannot find irq for vpu\n"); return irq; } - amcrtc->vblank_irq = (unsigned int)irq; - - spin_lock_init(&amcrtc->vblank_irq_lock); - amcrtc->vblank_enable = false; + amcrtc->irq = (unsigned int)irq; - ret = devm_request_irq(dev, amcrtc->vblank_irq, am_meson_vpu_irq, + ret = devm_request_irq(dev, amcrtc->irq, am_meson_vpu_irq, IRQF_SHARED, dev_name(dev), drm_dev); if (ret) return ret; - disable_irq(amcrtc->vblank_irq); + /* IRQ is initially disabled; it gets enabled in crtc_enable */ + disable_irq(amcrtc->irq); INIT_DELAYED_WORK(&osd_dwork, mem_free_work); schedule_delayed_work(&osd_dwork, msecs_to_jiffies(60 * 1000)); -- 2.7.4 From 4972b2edd43dd88301e6454124f3f0eceb78e93a Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Mon, 12 Apr 2021 15:40:26 +0900 Subject: [PATCH 15/16] amlogic: drm: support fence/cache op and gem_info Support fence operation, cache operation and geminfo in debugfs from amlogic meson drm. Change-Id: I0d7bc71c7d489e65c0c1051df21fc7b034c3af53 Signed-off-by: Seung-Woo Kim amlogic: drm: add am_meson_gem_get_ioctl am_meson_gem_get_ioctl is used by libtbm-meson. Change-Id: I1f2fd5b8413d26bbf774b0f12a09534fa911d305 Signed-off-by: Sihyun, Park Signed-off-by: Seung-Woo Kim --- drivers/amlogic/drm/Makefile | 3 + drivers/amlogic/drm/meson_crtc.c | 9 +- drivers/amlogic/drm/meson_crtc.h | 4 +- drivers/amlogic/drm/meson_debugfs.c | 59 ++++++- drivers/amlogic/drm/meson_drv.c | 70 +++++--- drivers/amlogic/drm/meson_drv.h | 11 +- drivers/amlogic/drm/meson_fb.c | 21 ++- drivers/amlogic/drm/meson_fb.h | 38 ++++- drivers/amlogic/drm/meson_fence.c | 110 +++++++++++++ drivers/amlogic/drm/meson_fence.h | 40 +++++ drivers/amlogic/drm/meson_gem.c | 219 ++++++++++++++++++++++++- drivers/amlogic/drm/meson_gem.h | 34 ++++ drivers/amlogic/drm/meson_hdmi.c | 23 ++- drivers/amlogic/drm/meson_lcd.c | 14 +- drivers/amlogic/drm/meson_plane.c | 119 +++++++++----- drivers/amlogic/drm/meson_plane.h | 2 + drivers/amlogic/drm/meson_vpu.c | 103 ++++++++---- drivers/amlogic/drm/meson_vpu.h | 2 +- drivers/amlogic/drm/meson_vpu_pipeline.c | 1 + drivers/amlogic/drm/meson_vpu_pipeline.h | 4 +- drivers/amlogic/drm/meson_vpu_util.c | 15 -- drivers/amlogic/drm/vpu-hw/meson_osd_scaler.c | 61 +++++-- drivers/amlogic/drm/vpu-hw/meson_osd_scaler.h | 9 + drivers/amlogic/drm/vpu-hw/meson_vpu_osd_mif.c | 34 ++-- drivers/gpu/drm/drm_fops.c | 1 + include/drm/drmP.h | 1 + include/uapi/drm/meson_drm.h | 60 ++++++- 27 files changed, 878 insertions(+), 189 deletions(-) create mode 100644 drivers/amlogic/drm/meson_fence.c create mode 100644 drivers/amlogic/drm/meson_fence.h diff --git a/drivers/amlogic/drm/Makefile b/drivers/amlogic/drm/Makefile index 022ca0b..2159b3a 100644 --- a/drivers/amlogic/drm/Makefile +++ b/drivers/amlogic/drm/Makefile @@ -1,3 +1,5 @@ +ccflags-y += -I$(srctree)/drivers/amlogic + ifeq ($(CONFIG_DRM_MESON_USE_ION),y) meson-drm-y += meson_gem.o meson_fb.o ccflags-y += -Idrivers/staging/android/ @@ -22,6 +24,7 @@ endif meson-drm-y += meson_drv.o meson_plane.o meson_vpu_pipeline_traverse.o \ meson_crtc.o meson_vpu_pipeline.o meson_vpu_pipeline_private.o \ meson_debugfs.o meson_vpu_util.o \ + meson_fence.o meson-drm-y += \ vpu-hw/meson_vpu_osd_mif.o \ diff --git a/drivers/amlogic/drm/meson_crtc.c b/drivers/amlogic/drm/meson_crtc.c index 05e79bd..444155e 100644 --- a/drivers/amlogic/drm/meson_crtc.c +++ b/drivers/amlogic/drm/meson_crtc.c @@ -242,7 +242,8 @@ static const struct drm_crtc_helper_funcs am_crtc_helper_funcs = { .atomic_flush = am_meson_crtc_atomic_flush, }; -int am_meson_crtc_create(struct am_meson_crtc *amcrtc) +int am_meson_crtc_create(struct am_meson_crtc *amcrtc, + struct osd_device_data_s *osd_dev) { struct meson_drm *priv = amcrtc->priv; struct drm_crtc *crtc = &amcrtc->base; @@ -254,7 +255,7 @@ int am_meson_crtc_create(struct am_meson_crtc *amcrtc) DRM_INFO("%s\n", __func__); ret = drm_crtc_init_with_planes(priv->drm, crtc, - priv->primary_plane, priv->cursor_plane, + priv->primary_plane, NULL, &am_meson_crtc_funcs, "amlogic vpu"); if (ret) { dev_err(amcrtc->dev, "Failed to init CRTC\n"); @@ -262,7 +263,7 @@ int am_meson_crtc_create(struct am_meson_crtc *amcrtc) } drm_crtc_helper_add(crtc, &am_crtc_helper_funcs); - osd_drm_init(&osd_meson_dev); + osd_drm_init(osd_dev); #ifdef CONFIG_AMLOGIC_MEDIA_ENHANCEMENT amvecm_drm_init(0); @@ -279,4 +280,4 @@ int am_meson_crtc_create(struct am_meson_crtc *amcrtc) return 0; } - +EXPORT_SYMBOL(am_meson_crtc_create); diff --git a/drivers/amlogic/drm/meson_crtc.h b/drivers/amlogic/drm/meson_crtc.h index 7370177..82f4483 100644 --- a/drivers/amlogic/drm/meson_crtc.h +++ b/drivers/amlogic/drm/meson_crtc.h @@ -63,7 +63,7 @@ struct am_meson_crtc { struct am_meson_crtc, base) #define to_am_meson_crtc_state(x) container_of(x, \ struct am_meson_crtc_state, base) - -int am_meson_crtc_create(struct am_meson_crtc *amcrtc); +int am_meson_crtc_create(struct am_meson_crtc *amcrtc, + struct osd_device_data_s *osd_dev); #endif diff --git a/drivers/amlogic/drm/meson_debugfs.c b/drivers/amlogic/drm/meson_debugfs.c index ff9eea87..8eb3e52 100644 --- a/drivers/amlogic/drm/meson_debugfs.c +++ b/drivers/amlogic/drm/meson_debugfs.c @@ -18,7 +18,11 @@ #ifdef CONFIG_DEBUG_FS #include #include -#endif + +#include +#include + +#endif /* CONFIG_DEBUG_FS */ #include "meson_drv.h" #include "meson_crtc.h" @@ -26,6 +30,11 @@ #ifdef CONFIG_DEBUG_FS +struct meson_gem_info_debugfs { + struct drm_file *filp; + struct seq_file *m; +}; + static int meson_dump_show(struct seq_file *sf, void *data) { struct drm_crtc *crtc = sf->private; @@ -266,8 +275,54 @@ static int mm_show(struct seq_file *sf, void *arg) &dev->vma_offset_manager->vm_addr_space_mm); } +static int meson_gem_info_print(int id, void *ptr, void *data) +{ + struct drm_gem_object *obj = ptr; + struct meson_gem_info_debugfs *gem_info = data; + + if(!obj) { + pr_err("obj is already null\n"); + return 0; + } + + if(gem_info) { + seq_printf(gem_info->m, " %5d %3d %4d %8zd %3d %3d %6d\n", + gem_info->filp->drm_pid, + obj->name, + id, + obj->size, + atomic_read(&obj->refcount.refcount), + obj->handle_count, + obj->import_attach ? 1 : 0); + } + return 0; +} + +static int meson_gem_info(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *)m->private; + struct drm_device *drm_dev = node->minor->dev; + struct meson_gem_info_debugfs gem_info; + + seq_printf(m, " pid name id size ref handles import\n"); + + gem_info.m = m; + + mutex_lock(&drm_dev->struct_mutex); + list_for_each_entry_reverse(gem_info.filp, &drm_dev->filelist, lhead) { + spin_lock(&gem_info.filp->table_lock); + idr_for_each(&gem_info.filp->object_idr, meson_gem_info_print, + &gem_info); + spin_unlock(&gem_info.filp->table_lock); + } + mutex_unlock(&drm_dev->struct_mutex); + + return 0; +} + static struct drm_info_list meson_debugfs_list[] = { {"mm", mm_show, 0}, + {"gem_info", meson_gem_info, 0}, }; int meson_debugfs_init(struct drm_minor *minor) @@ -295,4 +350,4 @@ void meson_debugfs_cleanup(struct drm_minor *minor) drm_debugfs_remove_files(meson_debugfs_list, ARRAY_SIZE(meson_debugfs_list), minor); } -#endif +#endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/amlogic/drm/meson_drv.c b/drivers/amlogic/drm/meson_drv.c index f94d45b..ae1f242 100644 --- a/drivers/amlogic/drm/meson_drv.c +++ b/drivers/amlogic/drm/meson_drv.c @@ -34,14 +34,16 @@ #include #include +#include "osd_hw.h" #include "meson_fbdev.h" #ifdef CONFIG_DRM_MESON_USE_ION #include "meson_gem.h" #include "meson_fb.h" #endif #include "meson_drv.h" +#include "meson_vpu.h" #include "meson_vpu_pipeline.h" - +#include "meson_fence.h" #define DRIVER_NAME "meson" #define DRIVER_DESC "Amlogic Meson DRM driver" @@ -102,26 +104,40 @@ static void am_meson_disable_vblank(struct drm_device *dev, unsigned int crtc) { } -static void am_meson_load(struct drm_device *dev) -{ -#if 0 - struct meson_drm *priv = dev->dev_private; - struct drm_crtc *crtc = priv->crtc; - int pipe = drm_crtc_index(crtc); - - if (priv->crtc_funcs[pipe] && - priv->crtc_funcs[pipe]->loader_protect) - priv->crtc_funcs[pipe]->loader_protect(crtc, true); -#endif -} #ifdef CONFIG_DRM_MESON_USE_ION static const struct drm_ioctl_desc meson_ioctls[] = { DRM_IOCTL_DEF_DRV(MESON_GEM_CREATE, am_meson_gem_create_ioctl, - DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW), + DRM_UNLOCKED | DRM_AUTH | DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(MESON_GEM_GET, am_meson_gem_get_ioctl, + DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(MESON_SET_BLANK, am_meson_drv_set_blank_ioctl, + DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(MESON_GEM_SYNC, am_meson_gem_sync_ioctl, + DRM_UNLOCKED | DRM_AUTH), + DRM_IOCTL_DEF_DRV(MESON_GEM_CPU_PREP, am_meson_gem_cpu_prep_ioctl, + DRM_UNLOCKED), + DRM_IOCTL_DEF_DRV(MESON_GEM_CPU_FINI, am_meson_gem_cpu_fini_ioctl, + DRM_UNLOCKED), }; #endif +int am_meson_drv_set_blank_ioctl( + struct drm_device *dev, + void *data, + struct drm_file *file_priv) +{ + struct drm_meson_plane_blank *args = data; + u32 index, enable; + + index = (args->plane_type == DRM_PLANE_TYPE_OVERLAY) ? OSD2 : OSD1; + enable = (args->onoff) ? 0 : 1; + + osd_drm_plane_enable_hw(index, enable); + + return 0; +} + static const struct file_operations fops = { .owner = THIS_MODULE, .open = drm_open, @@ -155,7 +171,7 @@ static struct drm_driver meson_driver = { /* PRIME Ops */ .prime_handle_to_fd = drm_gem_prime_handle_to_fd, .prime_fd_to_handle = drm_gem_prime_fd_to_handle, - + .gem_open_object = am_meson_gem_open_object, .gem_prime_export = drm_gem_prime_export, .gem_prime_get_sg_table = am_meson_gem_prime_get_sg_table, @@ -249,9 +265,14 @@ static int am_meson_drm_bind(struct device *dev) goto err_gem; DRM_INFO("mode_config crtc number:%d\n", drm->mode_config.num_crtc); + priv->dev_fctx = am_meson_fence_context_create("meson.drm-fence"); + + if (IS_ERR(priv->dev_fctx)) + goto err_unbind_all; + ret = drm_vblank_init(drm, drm->mode_config.num_crtc); if (ret) - goto err_unbind_all; + goto err_fctx; drm_mode_config_reset(drm); drm->mode_config.max_width = 4096; @@ -266,7 +287,10 @@ static int am_meson_drm_bind(struct device *dev) drm_kms_helper_poll_init(drm); - am_meson_load(drm); + if (priv->primary_plane != NULL && priv->overlay_plane != NULL) { + drm_plane_create_zpos_property(priv->primary_plane, 0, 0, OSD_MAX); + drm_plane_create_zpos_property(priv->overlay_plane, 1, 0, OSD_MAX); + } #ifdef CONFIG_DRM_MESON_EMULATE_FBDEV ret = am_meson_drm_fbdev_init(drm); @@ -279,7 +303,6 @@ static int am_meson_drm_bind(struct device *dev) return 0; - err_fbdev_fini: #ifdef CONFIG_DRM_MESON_EMULATE_FBDEV am_meson_drm_fbdev_fini(drm); @@ -290,6 +313,8 @@ err_poll_fini: drm_vblank_cleanup(drm); err_unbind_all: component_unbind_all(dev, drm); +err_fctx: + am_meson_fence_context_destroy(priv->dev_fctx); err_gem: drm_mode_config_cleanup(drm); #ifdef CONFIG_DRM_MESON_USE_ION @@ -307,6 +332,7 @@ err_free1: static void am_meson_drm_unbind(struct device *dev) { struct drm_device *drm = dev_get_drvdata(dev); + struct meson_drm *priv = dev->driver_data; drm_dev_unregister(drm); #ifdef CONFIG_DRM_MESON_EMULATE_FBDEV @@ -316,6 +342,7 @@ static void am_meson_drm_unbind(struct device *dev) drm->irq_enabled = false; drm_vblank_cleanup(drm); component_unbind_all(dev, drm); + am_meson_fence_context_destroy(priv->dev_fctx); drm_mode_config_cleanup(drm); #ifdef CONFIG_DRM_MESON_USE_ION am_meson_gem_cleanup(drm->dev_private); @@ -373,10 +400,10 @@ static bool am_meson_drv_use_osd(void) if (strcmp(str, "okay") && strcmp(str, "ok")) { DRM_INFO("device %s status is %s\n", - node->name, str); + node->name, str); } else { DRM_INFO("device %s status is %s\n", - node->name, str); + node->name, str); return true; } } @@ -455,6 +482,7 @@ static int am_meson_drv_probe(struct platform_device *pdev) struct component_match *match = NULL; int i; + pr_info("[%s] in\n", __func__); if (am_meson_drv_use_osd()) return am_meson_drv_probe_prune(pdev); @@ -507,7 +535,7 @@ static int am_meson_drv_probe(struct platform_device *pdev) am_meson_add_endpoints(dev, &match, port); of_node_put(port); } - + pr_info("[%s] out\n", __func__); return component_master_add_with_match(dev, &am_meson_drm_ops, match); } diff --git a/drivers/amlogic/drm/meson_drv.h b/drivers/amlogic/drm/meson_drv.h index 4260a3c..7047b67 100644 --- a/drivers/amlogic/drm/meson_drv.h +++ b/drivers/amlogic/drm/meson_drv.h @@ -50,15 +50,18 @@ struct meson_drm { struct drm_fb_helper *fbdev_helper; struct drm_gem_object *fbdev_bo; struct drm_plane *primary_plane; - struct drm_plane *cursor_plane; + struct drm_plane *overlay_plane; struct drm_property_blob *gamma_lut_blob; #ifdef CONFIG_DRM_MESON_USE_ION struct ion_client *gem_client; #endif + struct meson_fence_context *dev_fctx; + struct meson_vpu_pipeline *pipeline; struct meson_vpu_funcs *funcs; + struct am_meson_logo *logo; u32 num_crtcs; struct am_meson_crtc *crtcs[MESON_MAX_CRTC]; @@ -67,6 +70,11 @@ struct meson_drm { struct am_osd_plane *planes[MESON_MAX_OSD]; }; +int am_meson_drv_set_blank_ioctl( + struct drm_device *dev, + void *data, + struct drm_file *file_priv); + static inline int meson_vpu_is_compatible(struct meson_drm *priv, const char *compat) { @@ -76,6 +84,7 @@ static inline int meson_vpu_is_compatible(struct meson_drm *priv, extern int am_meson_register_crtc_funcs(struct drm_crtc *crtc, const struct meson_crtc_funcs *crtc_funcs); extern void am_meson_unregister_crtc_funcs(struct drm_crtc *crtc); +struct drm_connector *am_meson_hdmi_connector(void); #ifdef CONFIG_DEBUG_FS int meson_debugfs_init(struct drm_minor *minor); diff --git a/drivers/amlogic/drm/meson_fb.c b/drivers/amlogic/drm/meson_fb.c index 1c364da..359ed1f 100644 --- a/drivers/amlogic/drm/meson_fb.c +++ b/drivers/amlogic/drm/meson_fb.c @@ -18,8 +18,7 @@ #include #include "meson_fb.h" - -#define to_am_meson_fb(x) container_of(x, struct am_meson_fb, base) +#include "meson_vpu.h" void am_meson_fb_destroy(struct drm_framebuffer *fb) { @@ -27,6 +26,7 @@ void am_meson_fb_destroy(struct drm_framebuffer *fb) drm_gem_object_unreference_unlocked(&meson_fb->bufp->base); drm_framebuffer_cleanup(fb); + DRM_DEBUG("meson_fb=0x%p,\n", meson_fb); kfree(meson_fb); } @@ -58,9 +58,12 @@ am_meson_fb_alloc(struct drm_device *dev, if (!meson_fb) return ERR_PTR(-ENOMEM); - meson_gem = container_of(obj, struct am_meson_gem_object, base); - meson_fb->bufp = meson_gem; - + if (obj) { + meson_gem = container_of(obj, struct am_meson_gem_object, base); + meson_fb->bufp = meson_gem; + } else { + meson_fb->bufp = NULL; + } drm_helper_mode_fill_fb_struct(&meson_fb->base, mode_cmd); ret = drm_framebuffer_init(dev, &meson_fb->base, @@ -70,6 +73,10 @@ am_meson_fb_alloc(struct drm_device *dev, ret); goto err_free_fb; } + DRM_INFO("meson_fb[id:%d,ref:%d]=0x%p,meson_fb->bufp=0x%p\n", + meson_fb->base.base.id, + atomic_read(&meson_fb->base.base.refcount.refcount), + meson_fb, meson_fb->bufp); return &meson_fb->base; @@ -113,6 +120,10 @@ struct drm_framebuffer *am_meson_fb_create(struct drm_device *dev, kfree(meson_fb); return ERR_PTR(ret); } + DRM_DEBUG("meson_fb[in:%d,ref:%d]=0x%px,meson_fb->bufp=0x%p\n", + meson_fb->base.base.id, + atomic_read(&meson_fb->base.base.refcount.refcount), + meson_fb, meson_fb->bufp); return &meson_fb->base; } diff --git a/drivers/amlogic/drm/meson_fb.h b/drivers/amlogic/drm/meson_fb.h index 9c76d2e..0226ee7 100644 --- a/drivers/amlogic/drm/meson_fb.h +++ b/drivers/amlogic/drm/meson_fb.h @@ -24,16 +24,40 @@ #include "meson_gem.h" +#define to_am_meson_fb(x) container_of(x, struct am_meson_fb, base) + +#define VMODE_NAME_LEN_MAX 64 + +struct am_meson_logo { + struct page *logo_page; + phys_addr_t start; + u32 size; + u32 width; + u32 height; + u32 bpp; + u32 alloc_flag; + u32 info_loaded_mask; + char *outputmode_t; + char outputmode[VMODE_NAME_LEN_MAX]; +}; + struct am_meson_fb { struct drm_framebuffer base; struct am_meson_gem_object *bufp; + struct am_meson_logo *logo; }; -struct drm_framebuffer *am_meson_fb_create(struct drm_device *dev, - struct drm_file *file_priv, - const struct drm_mode_fb_cmd2 *mode_cmd); -struct drm_framebuffer *am_meson_drm_framebuffer_init( - struct drm_device *dev, - struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj); +struct drm_framebuffer * +am_meson_fb_create(struct drm_device *dev, + struct drm_file *file_priv, + const struct drm_mode_fb_cmd2 *mode_cmd); +struct drm_framebuffer * +am_meson_drm_framebuffer_init(struct drm_device *dev, + struct drm_mode_fb_cmd2 *mode_cmd, + struct drm_gem_object *obj); +struct drm_framebuffer * +am_meson_fb_alloc(struct drm_device *dev, + struct drm_mode_fb_cmd2 *mode_cmd, + struct drm_gem_object *obj); + #endif diff --git a/drivers/amlogic/drm/meson_fence.c b/drivers/amlogic/drm/meson_fence.c new file mode 100644 index 0000000..f1f30f6 --- /dev/null +++ b/drivers/amlogic/drm/meson_fence.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2019 Samsung Electronics Co.Ltd + * + * based on: drivers/gpu/drm/tilcdc/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include "meson_fence.h" + +#define to_meson_fence(fence) container_of(fence, struct meson_fence, base) + +struct meson_fence_context* +am_meson_fence_context_create(const char *name) +{ + struct meson_fence_context *fence_context; + + fence_context = kmalloc(sizeof(*fence_context), GFP_KERNEL); + if (!fence_context) + return NULL; + + fence_context->context = fence_context_alloc(1); + fence_context->name = name; + atomic_set(&fence_context->seqno, 0); + atomic_set(&fence_context->fence_count, 0); + + return fence_context; +} + +void +am_meson_fence_context_destroy( + struct meson_fence_context *fence_context) +{ + unsigned fence_count; + + fence_count = atomic_read(&fence_context->fence_count); + if (WARN_ON(fence_count)) + DRM_DEBUG_DRIVER("%s context has %u fence(s) remaining\n", + fence_context->name, fence_count); + + kfree(fence_context); +} + +static const char* +am_meson_fence_get_driver_name(struct fence *fence) +{ + return "meson.drm"; +} + +static const char* +am_meson_fence_get_timeline_name(struct fence *fence) +{ + struct meson_fence *meson_fence = to_meson_fence(fence); + return meson_fence->fence_context->name; +} + +static bool +am_meson_fence_enable_signaling(struct fence *fence) +{ + return true; +} + +static void +am_meson_fence_release(struct fence *fence) +{ + struct meson_fence *meson_fence = to_meson_fence(fence); + + atomic_dec(&meson_fence->fence_context->fence_count); + kfree(meson_fence); +} + +static struct fence_ops meson_fence_ops = { + .get_driver_name = am_meson_fence_get_driver_name, + .get_timeline_name = am_meson_fence_get_timeline_name, + .enable_signaling = am_meson_fence_enable_signaling, + .wait = fence_default_wait, + .release = am_meson_fence_release, +}; + +static inline unsigned +am_meson_fence_context_seqno_next( + struct meson_fence_context *fence_context) +{ + return atomic_inc_return(&fence_context->seqno) - 1; +} + +struct fence * +am_meson_fence_create(struct meson_fence_context *fence_context) +{ + struct meson_fence *meson_fence; + unsigned int seqno; + + meson_fence = kmalloc(sizeof(*meson_fence), GFP_KERNEL); + if (!meson_fence) + return NULL; + + spin_lock_init(&meson_fence->lock); + meson_fence->fence_context = fence_context; + + seqno = am_meson_fence_context_seqno_next(fence_context); + fence_init(&meson_fence->base, &meson_fence_ops, &meson_fence->lock, + fence_context->context, seqno); + + atomic_inc(&fence_context->fence_count); + + return &meson_fence->base; +} + diff --git a/drivers/amlogic/drm/meson_fence.h b/drivers/amlogic/drm/meson_fence.h new file mode 100644 index 0000000..c6fa538 --- /dev/null +++ b/drivers/amlogic/drm/meson_fence.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2019 Samsung Electronics Co.Ltd + * + * based on: drivers/gpu/drm/tilcdc/ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef __MESON_FENCE_H__ +#define __MESON_FENCE_H__ + +#include +#include +#include + +struct meson_fence_context { + unsigned int context; + const char *name; + atomic_t seqno; + atomic_t fence_count; +}; + +struct meson_fence { + struct meson_fence_context *fence_context; + struct fence base; + spinlock_t lock; +}; + +struct meson_fence_context* +am_meson_fence_context_create(const char *name); + +struct fence * +am_meson_fence_create(struct meson_fence_context *fence_context); + +void +am_meson_fence_context_destroy(struct meson_fence_context *fence_context); + +#endif /* __MESON_FENCE_H__ */ + diff --git a/drivers/amlogic/drm/meson_gem.c b/drivers/amlogic/drm/meson_gem.c index 7c472e3..6864ed4 100644 --- a/drivers/amlogic/drm/meson_gem.c +++ b/drivers/amlogic/drm/meson_gem.c @@ -22,10 +22,11 @@ #include #include #include -#include +#include #include #include "meson_gem.h" +#include "meson_fence.h" #define to_am_meson_gem_obj(x) container_of(x, struct am_meson_gem_object, base) @@ -45,7 +46,7 @@ static int am_meson_gem_alloc_ion_buff( //check flags to set different ion heap type. //if flags is set to 0, need to use ion dma buffer. - if (((flags & (MESON_USE_SCANOUT | MESON_USE_CURSOR)) != 0) + if (((flags & (MESON_USE_SCANOUT | MESON_USE_CURSOR | MESON_USE_OVERLAY)) != 0) || (flags == 0)) { handle = ion_alloc(client, meson_gem_obj->base.size, 0, (1 << ION_HEAP_TYPE_DMA), 0); @@ -55,7 +56,7 @@ static int am_meson_gem_alloc_ion_buff( bscatter = true; } - if (IS_ERR(handle)) { + if (IS_ERR_OR_NULL(handle)) { DRM_ERROR("%s: FAILED, flags:0x%x.\n", __func__, flags); return -ENOMEM; @@ -63,6 +64,7 @@ static int am_meson_gem_alloc_ion_buff( meson_gem_obj->handle = handle; meson_gem_obj->bscatter = bscatter; + meson_gem_obj->flags = flags; DRM_DEBUG("%s: allocate handle (%p).\n", __func__, meson_gem_obj->handle); return 0; @@ -116,6 +118,12 @@ struct am_meson_gem_object *am_meson_gem_object_create( goto error; } + /*for release check*/ + meson_gem_obj->flags = flags; + meson_gem_obj->size = size; + + reservation_object_init(&meson_gem_obj->resv); + return meson_gem_obj; error: @@ -130,6 +138,8 @@ void am_meson_gem_object_free(struct drm_gem_object *obj) DRM_DEBUG("am_meson_gem_object_free %p handle count = %d\n", meson_gem_obj, obj->handle_count); + reservation_object_fini(&meson_gem_obj->resv); + if (obj->import_attach == false) am_meson_gem_free_ion_buf(obj->dev, meson_gem_obj); else @@ -212,6 +222,16 @@ int am_meson_gem_mmap( return ret; } +int am_meson_gem_open_object( + struct drm_gem_object *obj, + struct drm_file *file_priv) +{ + if (obj && file_priv) + file_priv->drm_pid = task_tgid_nr(current); + + return 0; +} + phys_addr_t am_meson_gem_object_get_phyaddr( struct meson_drm *drm, struct am_meson_gem_object *meson_gem) @@ -305,8 +325,11 @@ int am_meson_gem_dumb_map_offset( } ret = drm_gem_create_mmap_offset(obj); - if (ret) + if (ret) { + struct am_meson_gem_object *meson_gem_obj = to_am_meson_gem_obj(obj); + reservation_object_fini(&meson_gem_obj->resv); goto out; + } *offset = drm_vma_node_offset_addr(&obj->vma_node); DRM_DEBUG("offset = 0x%lx\n", (unsigned long)*offset); @@ -376,6 +399,194 @@ void am_meson_gem_cleanup(struct meson_drm *drmdrv) } } +int am_meson_gem_get_ioctl( + struct drm_device *dev, + void *data, + struct drm_file *file_priv) +{ + struct drm_gem_object *obj; + struct drm_meson_gem_info *args; + struct am_meson_gem_object *meson_gem_obj; + + args = (struct drm_meson_gem_info *)data; + obj = drm_gem_object_lookup(file_priv, args->handle); + if (!obj) { + DRM_ERROR("failed to lookup gem object.\n"); + return -EINVAL; + } + meson_gem_obj = to_am_meson_gem_obj(obj); + args->flags = meson_gem_obj->flags; + args->size = meson_gem_obj->size; + + drm_gem_object_unreference_unlocked(obj); + + return 0; +} + +int am_meson_gem_sync_ioctl( + struct drm_device *dev, + void *data, + struct drm_file *file_priv) +{ + struct drm_gem_object *obj; + struct drm_meson_gem_sync *args; + struct am_meson_gem_object *meson_gem_obj; + struct ion_buffer *buffer; + int ret = 0; + + mutex_lock(&dev->struct_mutex); + + args = (struct drm_meson_gem_sync *)data; + obj = drm_gem_object_lookup(file_priv, args->handle); + if (!obj) { + DRM_ERROR("failed to lookup gem object.\n"); + ret = -EINVAL; + goto unlock; + } + meson_gem_obj = to_am_meson_gem_obj(obj); + if (!meson_gem_obj) { + DRM_ERROR("failed to lookup am_meson_gem_object.\n"); + ret = -EINVAL; + goto out; + } + if (meson_gem_obj->bscatter && + !(meson_gem_obj->flags & MESON_USE_RENDER_VIP)) { + buffer = meson_gem_obj->handle->buffer; + dma_sync_sg_for_cpu(dev->dev, buffer->sg_table->sgl, + buffer->sg_table->nents, DMA_FROM_DEVICE); + } + +out: + drm_gem_object_unreference(obj); +unlock: + mutex_unlock(&dev->struct_mutex); + return ret; +} + +int am_meson_gem_cpu_prep_ioctl( + struct drm_device *dev, + void *data, + struct drm_file *file_priv) +{ + int err = 0; + struct drm_meson_gem_cpu_access *args = (struct drm_meson_gem_cpu_access *)data; + struct meson_drm *priv = dev->dev_private; + struct drm_gem_object *obj; + bool write = !!(args->flags & MESON_GEM_CPU_PREP_WRITE); + bool wait = !(args->flags & MESON_GEM_CPU_PREP_NOWAIT); + struct am_meson_gem_object *meson_gem_obj; + + if (args->flags & ~(MESON_GEM_CPU_PREP_READ | + MESON_GEM_CPU_PREP_WRITE | + MESON_GEM_CPU_PREP_NOWAIT)) { + DRM_ERROR("invalid flags: %#08x\n", args->flags); + return -EINVAL; + } + + mutex_lock(&dev->struct_mutex); + obj = drm_gem_object_lookup(file_priv, args->handle); + mutex_unlock(&dev->struct_mutex); + if (!obj) { + err = -ENOENT; + goto exit_unlock; + } + if (obj->import_attach) { + err = -EINVAL; + goto exit_unref; + } + + meson_gem_obj = to_am_meson_gem_obj(obj); + if (meson_gem_obj->prep_data.cpu_prep) { + err = -EBUSY; + DRM_DEBUG("EBUSY cpu_prep not unlocked yet by caller\n"); + goto exit_unref; + } + + if (wait) { + long lerr; + lerr = reservation_object_wait_timeout_rcu(&meson_gem_obj->resv, write, true, 10 * HZ); + if (!lerr) { + err = -EBUSY; + goto exit_unref; + } else if (lerr < 0) { + err = lerr; + goto exit_unref; + } + + meson_gem_obj->prep_data.fence = am_meson_fence_create(priv->dev_fctx); + if (!meson_gem_obj->prep_data.fence) { + err = -ENOMEM; + goto exit_unref; + } + + if (write) { + ww_mutex_lock(&meson_gem_obj->resv.lock, NULL); + reservation_object_add_excl_fence( + &meson_gem_obj->resv, meson_gem_obj->prep_data.fence); + ww_mutex_unlock(&meson_gem_obj->resv.lock); + } else { + ww_mutex_lock(&meson_gem_obj->resv.lock, NULL); + err = reservation_object_reserve_shared(&meson_gem_obj->resv); + if (err) { + fence_put(meson_gem_obj->prep_data.fence); + } else { + reservation_object_add_shared_fence( + &meson_gem_obj->resv, meson_gem_obj->prep_data.fence); + } + ww_mutex_unlock(&meson_gem_obj->resv.lock); + } + } else { + if (!reservation_object_test_signaled_rcu(&meson_gem_obj->resv, write)) + err = -EBUSY; + } + + if (!err) + meson_gem_obj->prep_data.cpu_prep = true; + +exit_unref: + drm_gem_object_unreference_unlocked(obj); +exit_unlock: + return err; +} + +int am_meson_gem_cpu_fini_ioctl( + struct drm_device *dev, + void *data, + struct drm_file *file_priv) +{ + int err = 0; + struct drm_meson_gem_cpu_access *args = (struct drm_meson_gem_cpu_access *)data; + struct drm_gem_object *obj; + struct am_meson_gem_object *meson_gem_obj; + + mutex_lock(&dev->struct_mutex); + obj = drm_gem_object_lookup(file_priv, args->handle); + if (!obj) { + err = -ENOENT; + goto exit_unlock; + } + + meson_gem_obj = to_am_meson_gem_obj(obj); + if (!meson_gem_obj->prep_data.cpu_prep) { + err = -EINVAL; + goto exit_unref; + } + + if (meson_gem_obj->prep_data.fence) { + WARN_ON(fence_signal(meson_gem_obj->prep_data.fence)); /* Signal the fence */ + fence_put(meson_gem_obj->prep_data.fence); + meson_gem_obj->prep_data.fence = NULL; + } + meson_gem_obj->prep_data.cpu_prep = false; + +exit_unref: + drm_gem_object_unreference_unlocked(obj); +exit_unlock: + mutex_unlock(&dev->struct_mutex); + + return err; +} + struct sg_table *am_meson_gem_prime_get_sg_table( struct drm_gem_object *obj) { diff --git a/drivers/amlogic/drm/meson_gem.h b/drivers/amlogic/drm/meson_gem.h index cab22a5..1c59f9f 100644 --- a/drivers/amlogic/drm/meson_gem.h +++ b/drivers/amlogic/drm/meson_gem.h @@ -20,9 +20,15 @@ #include #include #include +#include #include "meson_drv.h" +struct fence_prep_data { + int cpu_prep; + struct fence *fence; +}; + struct am_meson_gem_object { struct drm_gem_object base; unsigned int flags; @@ -34,6 +40,10 @@ struct am_meson_gem_object { /* for buffer import form other driver */ phys_addr_t addr; struct sg_table *sg; + + struct reservation_object resv; + struct fence_prep_data prep_data; + unsigned int size; }; /* GEM MANAGER CREATE*/ @@ -67,6 +77,26 @@ int am_meson_gem_dumb_map_offset( uint32_t handle, uint64_t *offset); +int am_meson_gem_get_ioctl( + struct drm_device *dev, + void *data, + struct drm_file *file_priv); + +int am_meson_gem_sync_ioctl( + struct drm_device *dev, + void *data, + struct drm_file *file_priv); + +int am_meson_gem_cpu_prep_ioctl( + struct drm_device *dev, + void *data, + struct drm_file *file_priv); + +int am_meson_gem_cpu_fini_ioctl( + struct drm_device *dev, + void *data, + struct drm_file *file_priv); + /* GEM OBJECT OPERATIONS */ struct am_meson_gem_object *am_meson_gem_object_create( struct drm_device *dev, unsigned int flags, @@ -78,6 +108,10 @@ int am_meson_gem_object_mmap( struct am_meson_gem_object *obj, struct vm_area_struct *vma); +int am_meson_gem_open_object( + struct drm_gem_object *obj, + struct drm_file *file_priv); + extern phys_addr_t am_meson_gem_object_get_phyaddr( struct meson_drm *drm, struct am_meson_gem_object *meson_gem); diff --git a/drivers/amlogic/drm/meson_hdmi.c b/drivers/amlogic/drm/meson_hdmi.c index e5f0ce6..7cbe8c1 100644 --- a/drivers/amlogic/drm/meson_hdmi.c +++ b/drivers/amlogic/drm/meson_hdmi.c @@ -35,17 +35,11 @@ #include #include "meson_hdmi.h" #include "meson_hdcp.h" +#include "meson_vpu.h" #define DEVICE_NAME "amhdmitx" struct am_hdmi_tx am_hdmi_info; -struct am_vout_mode { - char name[DRM_DISPLAY_MODE_LEN]; - enum vmode_e mode; - int width, height, vrefresh; - unsigned int flags; -}; - static struct am_vout_mode am_vout_modes[] = { { "1080p60hz", VMODE_HDMI, 1920, 1080, 60, 0}, { "1080p30hz", VMODE_HDMI, 1920, 1080, 30, 0}, @@ -300,7 +294,6 @@ void am_hdmi_encoder_enable(struct drm_encoder *encoder) vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE_PRE, &vmode); set_vout_vmode(vmode); vout_notifier_call_chain(VOUT_EVENT_MODE_CHANGE, &vmode); - am_hdmi->hdcp_work = NULL; mdelay(1000); am_hdmi_hdcp_work_state_change(am_hdmi, 0); } @@ -584,6 +577,11 @@ static const struct of_device_id am_meson_hdmi_dt_ids[] = { MODULE_DEVICE_TABLE(of, am_meson_hdmi_dt_ids); +struct drm_connector *am_meson_hdmi_connector(void) +{ + return &am_hdmi_info.connector; +} + static int am_meson_hdmi_bind(struct device *dev, struct device *master, void *data) { @@ -596,12 +594,9 @@ static int am_meson_hdmi_bind(struct device *dev, int ret; int irq; - am_hdmi = devm_kzalloc(priv->dev, sizeof(*am_hdmi), - GFP_KERNEL); - if (!am_hdmi) - return -ENOMEM; - memcpy(&am_hdmi_info, am_hdmi, sizeof(*am_hdmi)); + DRM_INFO("[%s] in\n", __func__); am_hdmi = &am_hdmi_info; + memset(am_hdmi, 0, sizeof(*am_hdmi)); DRM_INFO("drm hdmitx init and version:%s\n", DRM_HDMITX_VER); am_hdmi->priv = priv; @@ -662,6 +657,7 @@ static int am_meson_hdmi_bind(struct device *dev, DRM_DEBUG_KMS("HDCP init failed, skipping.\n"); } } + DRM_INFO("[%s] out\n", __func__); return 0; } @@ -679,6 +675,7 @@ static const struct component_ops am_meson_hdmi_ops = { static int am_meson_hdmi_probe(struct platform_device *pdev) { + DRM_INFO("[%s] in\n", __func__); return component_add(&pdev->dev, &am_meson_hdmi_ops); } diff --git a/drivers/amlogic/drm/meson_lcd.c b/drivers/amlogic/drm/meson_lcd.c index e9c6f21..029878e 100644 --- a/drivers/amlogic/drm/meson_lcd.c +++ b/drivers/amlogic/drm/meson_lcd.c @@ -116,6 +116,9 @@ static int am_lcd_connector_get_modes(struct drm_connector *connector) __func__, lcd->lcd_drv->lcd_config->lcd_basic.h_active, lcd->lcd_drv->lcd_config->lcd_basic.v_active); + connector->display_info.width_mm = mode->width_mm; + connector->display_info.height_mm = mode->height_mm; + drm_mode_probed_add(connector, mode); count = 1; pr_info("am_drm_lcd: %s %d\n", __func__, __LINE__); @@ -607,10 +610,6 @@ int am_drm_lcd_notify_callback(struct notifier_block *block, unsigned long cmd, return 0; } -static struct notifier_block am_drm_lcd_notifier_nb = { - .notifier_call = am_drm_lcd_notify_callback, -}; - static const struct of_device_id am_meson_lcd_dt_ids[] = { { .compatible = "amlogic,drm-lcd", }, {}, @@ -636,12 +635,7 @@ static int am_meson_lcd_bind(struct device *dev, struct device *master, pr_err("invalid lcd driver, exit\n"); return -ENODEV; } - /* - * register vout client for timing init, - * avoid init with null info when lcd probe with unifykey case. - */ - vout_register_client(&am_drm_lcd_notifier_nb); - + am_drm_lcd_display_mode_timing_init(am_drm_lcd); drm_panel_init(&am_drm_lcd->panel); am_drm_lcd->panel.dev = NULL; am_drm_lcd->panel.funcs = &am_drm_lcd_funcs; diff --git a/drivers/amlogic/drm/meson_plane.c b/drivers/amlogic/drm/meson_plane.c index 7a66a9c..855e190 100644 --- a/drivers/amlogic/drm/meson_plane.c +++ b/drivers/amlogic/drm/meson_plane.c @@ -42,12 +42,18 @@ static u64 afbc_wb_modifier[] = { DRM_FORMAT_MOD_INVALID }; -static void meson_plane_position_calc( - struct meson_vpu_osd_layer_info *plane_info, - struct drm_plane_state *state, - struct drm_display_mode *mode) +static void +meson_plane_position_calc(struct meson_vpu_osd_layer_info *plane_info, + struct drm_plane_state *state, + struct drm_display_mode *disp_mode) { u32 dst_w, dst_h, src_w, src_h, scan_mode_out; + struct drm_display_mode *mode; + + if (IS_ERR_OR_NULL(state->crtc)) + mode = disp_mode; + else + mode = &state->crtc->mode; scan_mode_out = mode->flags & DRM_MODE_FLAG_INTERLACE; plane_info->src_x = state->src_x; @@ -147,7 +153,7 @@ static int meson_plane_fb_check(struct drm_plane *plane, #else struct drm_gem_cma_object *gem; #endif - dma_addr_t phyaddr; + phys_addr_t phyaddr; #ifdef CONFIG_DRM_MESON_USE_ION meson_fb = container_of(fb, struct am_meson_fb, base); @@ -155,9 +161,21 @@ static int meson_plane_fb_check(struct drm_plane *plane, DRM_DEBUG("meson_fb is NULL!\n"); return -EINVAL; } - phyaddr = am_meson_gem_object_get_phyaddr(drv, meson_fb->bufp); - if (meson_fb->bufp->bscatter) - DRM_ERROR("am_meson_plane meet a scatter framebuffer.\n"); + DRM_DEBUG("meson_fb[id:%d,ref:%d]=0x%p\n", + meson_fb->base.base.id, + atomic_read(&meson_fb->base.base.refcount.refcount), + meson_fb); + if (meson_fb->logo && meson_fb->logo->alloc_flag && + meson_fb->logo->start) { + phyaddr = meson_fb->logo->start; + DRM_DEBUG("logo->phyaddr=0x%pa\n", &phyaddr); + } else if (meson_fb->bufp) { + phyaddr = am_meson_gem_object_get_phyaddr(drv, meson_fb->bufp); + } else { + phyaddr = 0; + DRM_INFO("don't find phyaddr!\n"); + return -EINVAL; + } #else if (!fb) { DRM_INFO("fb is NULL!\n"); @@ -182,12 +200,6 @@ static int meson_plane_get_fb_info(struct drm_plane *plane, struct am_osd_plane *osd_plane = to_am_osd_plane(plane); struct drm_framebuffer *fb = new_state->fb; struct meson_drm *drv = osd_plane->drv; - #ifdef CONFIG_DRM_MESON_USE_ION - struct am_meson_fb *meson_fb; - #else - struct drm_gem_cma_object *gem; - #endif - dma_addr_t phyaddr; if (!drv) { DRM_INFO("%s new_state/meson_drm is NULL!\n", __func__); @@ -197,29 +209,7 @@ static int meson_plane_get_fb_info(struct drm_plane *plane, DRM_INFO("%s invalid plane_index!\n", __func__); return -EINVAL; } - - #ifdef CONFIG_DRM_MESON_USE_ION - meson_fb = container_of(fb, struct am_meson_fb, base); - if (!meson_fb) { - DRM_INFO("meson_fb is NULL!\n"); - return 0; - } - phyaddr = am_meson_gem_object_get_phyaddr(drv, meson_fb->bufp); - if (meson_fb->bufp->bscatter) - DRM_ERROR("ERROR:am_meson_plane meet a scatter framebuffer.\n"); - plane_info->fb_size = meson_fb->bufp->base.size; - #else - if (!fb) { - DRM_INFO("fb is NULL!\n"); - return -EINVAL; - } - /* Update Canvas with buffer address */ - gem = drm_fb_cma_get_gem_obj(fb, 0); - phyaddr = gem->paddr; - #endif - plane_info->pixel_format = fb->pixel_format; - plane_info->phy_addr = phyaddr; plane_info->byte_stride = fb->pitches[0]; /*setup afbc info*/ @@ -261,6 +251,13 @@ static int meson_plane_atomic_get_property(struct drm_plane *plane, struct drm_property *property, uint64_t *val) { + struct am_osd_plane *osd_plane; + struct am_meson_plane_state *plane_state; + + osd_plane = to_am_osd_plane(plane); + plane_state = to_am_meson_plane_state(state); + if (property == osd_plane->prop_premult_en) + *val = plane_state->premult_en; return 0; } @@ -269,6 +266,14 @@ static int meson_plane_atomic_set_property(struct drm_plane *plane, struct drm_property *property, uint64_t val) { + struct am_osd_plane *osd_plane; + struct am_meson_plane_state *plane_state; + + osd_plane = to_am_osd_plane(plane); + plane_state = to_am_meson_plane_state(state); + if (property == osd_plane->prop_premult_en) + plane_state->premult_en = val; + return 0; } @@ -333,13 +338,11 @@ bool am_meson_vpu_check_format_mod(struct drm_plane *plane, ret = true; break; case DRM_FORMAT_MOD_MESON_AFBC: - if (osd_meson_dev.afbc_type == MESON_AFBC && - plane->type == DRM_PLANE_TYPE_PRIMARY) + if (plane->type == DRM_PLANE_TYPE_PRIMARY) ret = true; break; case DRM_FORMAT_MOD_MESON_AFBC_WB: - if (osd_meson_dev.afbc_type == MALI_AFBC && - plane->type == DRM_PLANE_TYPE_PRIMARY) { + if (plane->type == DRM_PLANE_TYPE_PRIMARY) { if (format == DRM_FORMAT_BGR565) ret = false; else @@ -376,7 +379,7 @@ static void meson_plane_cleanup_fb(struct drm_plane *plane, { struct am_osd_plane *osd_plane = to_am_osd_plane(plane); - DRM_DEBUG("%s osd %d.\n", __func__, osd_plane->plane_index); + DRM_DEBUG("osd %d.\n", osd_plane->plane_index); } static void meson_plane_atomic_update(struct drm_plane *plane, @@ -393,6 +396,7 @@ static int meson_plane_atomic_check(struct drm_plane *plane, struct meson_vpu_pipeline_state *mvps; struct am_osd_plane *osd_plane = to_am_osd_plane(plane); struct meson_drm *drv = osd_plane->drv; + struct am_meson_plane_state *plane_state; int ret; if (!state || !drv) { @@ -431,6 +435,8 @@ static int meson_plane_atomic_check(struct drm_plane *plane, return ret; } + plane_state = to_am_meson_plane_state(state); + plane_info->premult_en = plane_state->premult_en; plane_info->enable = 1; DRM_DEBUG("index=%d, zorder=%d\n", plane_info->plane_index, plane_info->zorder); @@ -459,6 +465,24 @@ static const struct drm_plane_helper_funcs am_osd_helper_funcs = { .atomic_disable = meson_plane_atomic_disable, }; +int drm_plane_create_premult_en_property(struct drm_plane *plane) +{ + struct drm_device *dev = plane->dev; + struct drm_property *prop; + struct am_osd_plane *osd_plane; + + osd_plane = to_am_osd_plane(plane); + prop = drm_property_create_bool(dev, DRM_MODE_PROP_ATOMIC, + "PREMULT_EN"); + if (!prop) + return -ENOMEM; + + drm_object_attach_property(&plane->base, prop, 0); + osd_plane->prop_premult_en = prop; + + return 0; +} + static struct am_osd_plane *am_plane_create(struct meson_drm *priv, int i) { struct am_osd_plane *osd_plane; @@ -472,10 +496,12 @@ static struct am_osd_plane *am_plane_create(struct meson_drm *priv, int i) if (!osd_plane) return 0; - if (i == 0) + if (i == OSD1) + type = DRM_PLANE_TYPE_OVERLAY; + else if (i == OSD2) type = DRM_PLANE_TYPE_PRIMARY; else - type = DRM_PLANE_TYPE_OVERLAY; + type = DRM_PLANE_TYPE_CURSOR; osd_plane->drv = priv; osd_plane->plane_index = i; @@ -490,6 +516,7 @@ static struct am_osd_plane *am_plane_create(struct meson_drm *priv, int i) format_modifiers, type, plane_name); + drm_plane_create_premult_en_property(plane); drm_plane_helper_add(plane, &am_osd_helper_funcs); osd_drm_debugfs_add(&osd_plane->plane_debugfs_dir, plane_name, osd_plane->plane_index); @@ -510,9 +537,10 @@ int am_meson_plane_create(struct meson_drm *priv) if (!plane) return -ENOMEM; - if (i == 0) + if (i == OSD1) + priv->overlay_plane = &plane->base; + else if (i == OSD2) priv->primary_plane = &plane->base; - priv->planes[priv->num_planes++] = plane; } @@ -520,3 +548,4 @@ int am_meson_plane_create(struct meson_drm *priv) return 0; } +EXPORT_SYMBOL(am_meson_plane_create); diff --git a/drivers/amlogic/drm/meson_plane.h b/drivers/amlogic/drm/meson_plane.h index a1e6f4b..5be8adc 100644 --- a/drivers/amlogic/drm/meson_plane.h +++ b/drivers/amlogic/drm/meson_plane.h @@ -31,6 +31,7 @@ struct am_meson_plane_state { struct drm_plane_state base; + u32 premult_en; }; struct am_osd_plane { @@ -38,6 +39,7 @@ struct am_osd_plane { struct meson_drm *drv; //point to struct parent. struct dentry *plane_debugfs_dir; int plane_index; + struct drm_property *prop_premult_en; }; #define to_am_osd_plane(x) container_of(x, \ diff --git a/drivers/amlogic/drm/meson_vpu.c b/drivers/amlogic/drm/meson_vpu.c index 83caebe..af3262c 100644 --- a/drivers/amlogic/drm/meson_vpu.c +++ b/drivers/amlogic/drm/meson_vpu.c @@ -256,11 +256,9 @@ static struct osd_device_data_s osd_tm2 = { .osd0_sc_independ = 1, }; struct osd_device_data_s osd_meson_dev; -static u32 logo_memsize; -static struct page *logo_page; -static struct delayed_work osd_dwork; static struct platform_device *gp_dev; static unsigned long gem_mem_start, gem_mem_size; +struct am_meson_logo logo; int am_meson_crtc_dts_info_set(const void *dt_match_data) { @@ -337,6 +335,28 @@ char *am_meson_crtc_get_voutmode(struct drm_display_mode *mode) return NULL; } +bool am_meson_crtc_check_mode(struct drm_display_mode *mode, char *outputmode) +{ + int i; + + if (!mode || !outputmode) + return false; + if (!strcmp(mode->name, "panel")) + return true; + + for (i = 0; i < ARRAY_SIZE(am_vout_modes); i++) { + if (!strcmp(am_vout_modes[i].name, outputmode) && + am_vout_modes[i].width == mode->hdisplay && + am_vout_modes[i].height == mode->vdisplay && + am_vout_modes[i].vrefresh == mode->vrefresh && + am_vout_modes[i].flags == + (mode->flags & DRM_MODE_FLAG_INTERLACE)) { + return true; + } + } + return false; +} + void am_meson_crtc_handle_vsync(struct am_meson_crtc *amcrtc) { unsigned long flags; @@ -371,18 +391,26 @@ static irqreturn_t am_meson_vpu_irq(int irq, void *arg) return IRQ_HANDLED; } -static void mem_free_work(struct work_struct *work) +static int am_meson_logo_info_update(struct meson_drm *priv) { - if (logo_memsize > 0) { -#ifdef CONFIG_CMA - pr_info("%s, free memory: addr:0x%x\n", - __func__, logo_memsize); - - dma_release_from_contiguous(&gp_dev->dev, - logo_page, - logo_memsize >> PAGE_SHIFT); -#endif + logo.start = page_to_phys(logo.logo_page); + logo.alloc_flag = 1; + /*config 1080p logo as default*/ + if (!logo.width || !logo.height) { + logo.width = 1920; + logo.height = 1080; + } + if (!logo.bpp) + logo.bpp = 16; + if (!logo.outputmode_t) { + strcpy(logo.outputmode, "1080p60hz"); + } else { + strncpy(logo.outputmode, logo.outputmode_t, VMODE_NAME_LEN_MAX); + logo.outputmode[VMODE_NAME_LEN_MAX - 1] = '\0'; } + priv->logo = &logo; + + return 0; } static int am_meson_vpu_bind(struct device *dev, @@ -399,7 +427,7 @@ static int am_meson_vpu_bind(struct device *dev, int ret, irq; /* Allocate crtc struct */ - pr_info("[%s] in\n", __func__); + DRM_INFO("[%s] in\n", __func__); amcrtc = devm_kzalloc(dev, sizeof(*amcrtc), GFP_KERNEL); if (!amcrtc) @@ -415,41 +443,46 @@ static int am_meson_vpu_bind(struct device *dev, ret = of_reserved_mem_device_init(&pdev->dev); if (ret != 0) { dev_err(dev, "failed to init reserved memory\n"); + } else { #ifdef CONFIG_CMA gp_dev = pdev; cma = dev_get_cma_area(&pdev->dev); if (cma) { - logo_memsize = cma_get_size(cma); - pr_info("reserved memory base:0x%x, size:0x%x\n", - (u32)cma_get_base(cma), logo_memsize); - if (logo_memsize > 0) { - logo_page = + logo.size = cma_get_size(cma); + DRM_INFO("reserved memory base:0x%x, size:0x%x\n", + (u32)cma_get_base(cma), logo.size); + if (logo.size > 0) { + logo.logo_page = dma_alloc_from_contiguous(&pdev->dev, - logo_memsize >> + logo.size >> PAGE_SHIFT, 0); - if (!logo_page) { - pr_err("allocate buffer failed:%d\n", - logo_memsize); - } + if (!logo.logo_page) + DRM_INFO("allocate buffer failed\n"); + else + am_meson_logo_info_update(private); } } else { - pr_info("------ NO CMA\n"); + DRM_INFO("------ NO CMA\n"); } #endif - } else { - dma_declare_coherent_memory(drm_dev->dev, gem_mem_start, - gem_mem_start, gem_mem_size, - DMA_MEMORY_EXCLUSIVE); - pr_info("meson drm mem_start = 0x%x, size = 0x%x\n", - (u32)gem_mem_start, (u32)gem_mem_size); + if (gem_mem_start) { + dma_declare_coherent_memory(drm_dev->dev, + gem_mem_start, + gem_mem_start, + gem_mem_size, + DMA_MEMORY_EXCLUSIVE); + pr_info("meson drm mem_start = 0x%x, size = 0x%x\n", + (u32)gem_mem_start, (u32)gem_mem_size); + } else { + DRM_INFO("------ NO reserved dma\n"); + } } ret = am_meson_plane_create(private); if (ret) return ret; - - ret = am_meson_crtc_create(amcrtc); + ret = am_meson_crtc_create(amcrtc, &osd_meson_dev); if (ret) return ret; @@ -475,9 +508,7 @@ static int am_meson_vpu_bind(struct device *dev, /* IRQ is initially disabled; it gets enabled in crtc_enable */ disable_irq(amcrtc->irq); - INIT_DELAYED_WORK(&osd_dwork, mem_free_work); - schedule_delayed_work(&osd_dwork, msecs_to_jiffies(60 * 1000)); - pr_info("[%s] out\n", __func__); + DRM_INFO("[%s] out\n", __func__); return 0; } diff --git a/drivers/amlogic/drm/meson_vpu.h b/drivers/amlogic/drm/meson_vpu.h index e288a33..594fa34 100644 --- a/drivers/amlogic/drm/meson_vpu.h +++ b/drivers/amlogic/drm/meson_vpu.h @@ -31,7 +31,7 @@ struct am_vout_mode { unsigned int flags; }; -extern struct osd_device_data_s osd_meson_dev; char *am_meson_crtc_get_voutmode(struct drm_display_mode *mode); +bool am_meson_crtc_check_mode(struct drm_display_mode *mode, char *outputmode); #endif /* __AM_MESON_VPU_H */ diff --git a/drivers/amlogic/drm/meson_vpu_pipeline.c b/drivers/amlogic/drm/meson_vpu_pipeline.c index bb1d72c..e5a380c 100644 --- a/drivers/amlogic/drm/meson_vpu_pipeline.c +++ b/drivers/amlogic/drm/meson_vpu_pipeline.c @@ -345,6 +345,7 @@ void vpu_pipeline_init(struct meson_vpu_pipeline *pipeline) VPU_PIPELINE_HW_INIT(&pipeline->postblend->base); } +EXPORT_SYMBOL(vpu_pipeline_init); /* maybe use graph traverse is a good choice */ int vpu_pipeline_update(struct meson_vpu_pipeline *pipeline, diff --git a/drivers/amlogic/drm/meson_vpu_pipeline.h b/drivers/amlogic/drm/meson_vpu_pipeline.h index 8b26bbd..2ce8d9f 100644 --- a/drivers/amlogic/drm/meson_vpu_pipeline.h +++ b/drivers/amlogic/drm/meson_vpu_pipeline.h @@ -39,7 +39,7 @@ #define MESON_BLOCK_MAX_NAME_LEN 32 /*ratio base for scaler calc;maybe need bigger than 1000*/ #define RATIO_BASE 1000 -#define MESON_OSD_INPUT_W_LIMIT 1920 +#define MESON_OSD_INPUT_W_LIMIT 3840 #define MAX_DIN_NUM 4 #define MAX_DOUT_NUM 2 @@ -169,6 +169,7 @@ struct meson_vpu_osd_layer_info { u32 afbc_inter_format; u32 afbc_en; u32 fb_size; + u32 premult_en; }; struct meson_vpu_osd { @@ -205,6 +206,7 @@ struct meson_vpu_osd_state { int r_mode; u32 plane_index; u32 fb_size; + u32 premult_en; }; struct meson_vpu_afbc { diff --git a/drivers/amlogic/drm/meson_vpu_util.c b/drivers/amlogic/drm/meson_vpu_util.c index 9ad172c..1a97940 100644 --- a/drivers/amlogic/drm/meson_vpu_util.c +++ b/drivers/amlogic/drm/meson_vpu_util.c @@ -128,18 +128,3 @@ int meson_drm_clr_reg_mask(u32 addr, u32 mask) return 0; } #endif - -/** canvas config **/ - -void meson_drm_canvas_config(u32 index, unsigned long addr, u32 width, - u32 height, u32 wrap, u32 blkmode) -{ - canvas_config(index, addr, width, height, wrap, blkmode); -} - -int meson_drm_canvas_pool_alloc_table(const char *owner, u32 *table, int size, - enum canvas_map_type_e type) -{ - return canvas_pool_alloc_canvas_table(owner, table, size, type); -} - diff --git a/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.c b/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.c index 96c2579..c70fcd7 100644 --- a/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.c +++ b/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.c @@ -80,6 +80,34 @@ static unsigned int __osd_filter_coefs_bicubic[] = { /* bicubic coef0 */ 0xf84d42f9, 0xf84a45f9, 0xf84848f8 }; +static unsigned int __osd_filter_coefs_2point_binilear[] = { + /* 2 point bilinear, bank_length == 2 coef2 */ + 0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, 0x78080000, 0x760a0000, + 0x740c0000, 0x720e0000, 0x70100000, 0x6e120000, 0x6c140000, 0x6a160000, + 0x68180000, 0x661a0000, 0x641c0000, 0x621e0000, 0x60200000, 0x5e220000, + 0x5c240000, 0x5a260000, 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000, + 0x50300000, 0x4e320000, 0x4c340000, 0x4a360000, 0x48380000, 0x463a0000, + 0x443c0000, 0x423e0000, 0x40400000 +}; + +static unsigned int __osd_filter_coefs_4point_triangle[] = { + 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101, + 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303, + 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505, + 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707, + 0x18382808, 0x18382808, 0x17372909, 0x17372909, + 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b, + 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d, + 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f, + 0x10303010 +}; + +static unsigned int *osd_scaler_filter_table[] = { + __osd_filter_coefs_bicubic, + __osd_filter_coefs_2point_binilear, + __osd_filter_coefs_4point_triangle +}; + /*********vsc config begin**********/ /*vsc phase_step=(v_in << 20)/v_out */ void osd_vsc_phase_step_set(struct osd_scaler_reg_s *reg, u32 phase_step) @@ -309,7 +337,7 @@ void osd_sc_out_vert_set(struct osd_scaler_reg_s *reg, u32 start, u32 end) *1:config horizontal coef *0:config vertical coef */ -void osd_sc_coef_set(struct osd_scaler_reg_s *reg, bool flag) +void osd_sc_coef_set(struct osd_scaler_reg_s *reg, bool flag, u32 *coef) { u8 i; @@ -320,8 +348,7 @@ void osd_sc_coef_set(struct osd_scaler_reg_s *reg, bool flag) (flag << 8) | (0 << 0)/*coef index 7bits*/); for (i = 0; i < 33; i++) - VSYNCOSD_WR_MPEG_REG(reg->vpp_osd_scale_coef, - __osd_filter_coefs_bicubic[i]); + VSYNCOSD_WR_MPEG_REG(reg->vpp_osd_scale_coef, coef[i]); } /*********sc top ctrl end************/ static void f2v_get_vertical_phase( @@ -381,6 +408,8 @@ void osd_scaler_config(struct osd_scaler_reg_s *reg, u32 width_out = scaler_state->output_width; u32 height_out = scaler_state->output_height; u32 scan_mode_out = scaler_state->scan_mode_out; + u32 vsc_double_line_mode; + u32 *coef_h, *coef_v; bool scaler_enable; if (width_in == width_out && height_in == height_out && @@ -389,10 +418,13 @@ void osd_scaler_config(struct osd_scaler_reg_s *reg, else scaler_enable = true; - if (width_out > linebuffer) + if (width_in > linebuffer) { vsc_bank_length = bank_length >> 1; - else + vsc_double_line_mode = 1; + } else { vsc_bank_length = bank_length; + vsc_double_line_mode = 0; + } hsc_init_rec_num = bank_length; hsc_bank_length = bank_length; hsc_init_rpt_p0_num = bank_length / 2 - 1; @@ -432,6 +464,17 @@ void osd_scaler_config(struct osd_scaler_reg_s *reg, phase_step_v <<= (OSD_ZOOM_TOTAL_BITS - OSD_ZOOM_HEIGHT_BITS); phase_step_h = (width_in << OSD_ZOOM_WIDTH_BITS) / width_out; phase_step_h <<= (OSD_ZOOM_TOTAL_BITS - OSD_ZOOM_WIDTH_BITS); + /*check coef*/ + if (scan_mode_out && width_out <= 720) { + coef_h = osd_scaler_filter_table[COEFS_4POINT_TRIANGLE]; + coef_v = osd_scaler_filter_table[COEFS_4POINT_TRIANGLE]; + } else if (vsc_double_line_mode == 1) { + coef_h = osd_scaler_filter_table[COEFS_BICUBIC]; + coef_v = osd_scaler_filter_table[COEFS_2POINT_BINILEAR]; + } else { + coef_h = osd_scaler_filter_table[COEFS_BICUBIC]; + coef_v = osd_scaler_filter_table[COEFS_BICUBIC]; + } /*input size config*/ osd_sc_in_h_set(reg, height_in); @@ -449,13 +492,14 @@ void osd_scaler_config(struct osd_scaler_reg_s *reg, osd_sc_dummy_data_set(reg, 0x80808080); /*h/v coef config*/ - osd_sc_coef_set(reg, 1); - osd_sc_coef_set(reg, 0); + osd_sc_coef_set(reg, OSD_SCALER_COEFF_H, coef_h); + osd_sc_coef_set(reg, OSD_SCALER_COEFF_V, coef_v); /*init recv line num*/ osd_vsc_top_ini_rcv_num_set(reg, vsc_top_init_rec_num); osd_vsc_bot_ini_rcv_num_set(reg, vsc_bot_init_rec_num); osd_hsc_ini_rcv_num0_set(reg, hsc_init_rec_num); + osd_vsc_double_line_mode_set(reg, vsc_double_line_mode); /*repeate line0 num*/ osd_vsc_top_rpt_l0_num_set(reg, vsc_top_rpt_l0_num); @@ -650,9 +694,6 @@ static void scaler_hw_init(struct meson_vpu_block *vblk) scaler->reg = &osd_scaler_reg[vblk->index]; scaler->linebuffer = OSD_SCALE_LINEBUFFER; scaler->bank_length = OSD_SCALE_BANK_LENGTH; - /*disable sc*/ - osd_sc_en_set(scaler->reg, 0); - osd_sc_path_en_set(scaler->reg, 0); DRM_DEBUG("%s hw_init called.\n", scaler->base.name); } diff --git a/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.h b/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.h index 34ebb03..91b3d73 100644 --- a/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.h +++ b/drivers/amlogic/drm/vpu-hw/meson_osd_scaler.h @@ -79,6 +79,15 @@ #define OSD_ZOOM_TOTAL_BITS 24 #define OSD_PHASE_BITS 16 +#define OSD_SCALER_COEFF_H 1 +#define OSD_SCALER_COEFF_V 0 + +enum scaler_coef_e { + COEFS_BICUBIC = 0, + COEFS_2POINT_BINILEAR, + COEFS_4POINT_TRIANGLE +}; + enum f2v_vphase_type_e { F2V_IT2IT = 0, F2V_IB2IB, diff --git a/drivers/amlogic/drm/vpu-hw/meson_vpu_osd_mif.c b/drivers/amlogic/drm/vpu-hw/meson_vpu_osd_mif.c index 487dfe0..473ba6b 100644 --- a/drivers/amlogic/drm/vpu-hw/meson_vpu_osd_mif.c +++ b/drivers/amlogic/drm/vpu-hw/meson_vpu_osd_mif.c @@ -227,9 +227,22 @@ void osd_block_enable(struct osd_mif_reg_s *reg, bool flag) VSYNCOSD_WR_MPEG_REG_BITS(reg->viu_osd_ctrl_stat, flag, 0, 1); } +/*osd alpha_div en + *if input is premult,alpha_div=1,else alpha_div=0 + */ +void osd_alpha_div_enable(struct osd_mif_reg_s *reg, bool flag) +{ + VSYNCOSD_WR_MPEG_REG_BITS(reg->viu_osd_mali_unpack_ctrl, flag, 28, 1); +} + /*osd ctrl config*/ -void osd_ctrl_set(struct osd_mif_reg_s *reg) +void osd_ctrl_set(struct osd_mif_reg_s *reg, u32 osd_idx, u32 canvas_index) { + u32 enable = 1; + + if (osd_idx > OSD2) + enable = 0; + VSYNCOSD_WR_MPEG_REG(reg->viu_osd_ctrl_stat, (0 << 31) |/*osd_cfg_sync_en*/ (0 << 30) |/*Enable free_clk*/ @@ -237,7 +250,8 @@ void osd_ctrl_set(struct osd_mif_reg_s *reg) (0 << 11) |/*TEST_RD_EN*/ (0 << 2) |/*osd_mem_mode 0:canvas_addr*/ (0 << 1) |/*premult_en*/ - (0 << 0)/*OSD_BLK_ENABLE*/); + (enable << 0)/*OSD_BLK_ENABLE*/ + ); VSYNCOSD_WR_MPEG_REG(reg->viu_osd_ctrl_stat2, (1 << 14) |/*replaced_alpha_en*/ (0xff << 6) |/*replaced_alpha*/ @@ -268,7 +282,7 @@ void osd_ctrl_set(struct osd_mif_reg_s *reg) (0 << 30) |/*read from ddr[0]/afbc[1]*/ (0 << 29) |/*y reverse disable*/ (0 << 28) |/*x reverse disable*/ - (osd_canvas[0][0] << 16) |/*canvas index*/ + (canvas_index << 16) | (1 << 15) |/*little endian in ddr*/ (0 << 14) |/*no repeat display y pre line*/ (0 << 12) |/*no interpolation per pixel*/ @@ -277,12 +291,6 @@ void osd_ctrl_set(struct osd_mif_reg_s *reg) (1 << 2) |/*ARGB format for 32bit mode*/ (0 << 1) |/*interlace en*/ (0 << 0)/*output odd/even lines sel*/); - VSYNCOSD_WR_MPEG_REG(reg->viu_osd_blk0_cfg_w1, - (1919 << 16) |/*x_end pixels[13bits]*/ - (0 << 0)/*x_start pixels[13bits]*/); - VSYNCOSD_WR_MPEG_REG(reg->viu_osd_blk0_cfg_w2, - (1079 << 16) |/*y_end pixels[13bits]*/ - (0 << 0)/*y_start pixels[13bits]*/); /*frame addr in linear addr*/ VSYNCOSD_WR_MPEG_REG(reg->viu_osd_blk1_cfg_w4, 0); /*line_stride in linear addr*/ @@ -354,6 +362,7 @@ static int osd_check_state(struct meson_vpu_block *vblk, mvos->phy_addr = plane_info->phy_addr; mvos->pixel_format = plane_info->pixel_format; mvos->fb_size = plane_info->fb_size; + mvos->premult_en = plane_info->premult_en; return 0; } @@ -371,6 +380,7 @@ static void osd_set_state(struct meson_vpu_block *vblk, u32 pixel_format, canvas_index, src_h, byte_stride, phy_addr; struct osd_scope_s scope_src = {0, 1919, 0, 1079}; struct osd_mif_reg_s *reg = osd->reg; + bool alpha_div_en; crtc = vblk->pipeline->crtc; amc = to_am_meson_crtc(crtc); @@ -379,6 +389,7 @@ static void osd_set_state(struct meson_vpu_block *vblk, DRM_DEBUG("set_state break for NULL.\n"); return; } + alpha_div_en = mvos->premult_en ? 1 : 0; src_h = mvos->src_h; byte_stride = mvos->byte_stride; phy_addr = mvos->phy_addr; @@ -388,12 +399,14 @@ static void osd_set_state(struct meson_vpu_block *vblk, scope_src.v_end = mvos->src_y + mvos->src_h - 1; pixel_format = mvos->pixel_format; canvas_index = osd_canvas[vblk->index][osd_canvas_index[vblk->index]]; + /*Toto: need to separate*/ + osd_ctrl_set(osd->reg, vblk->index, canvas_index); canvas_config(canvas_index, phy_addr, byte_stride, src_h, CANVAS_ADDR_NOWRAP, CANVAS_BLKMODE_LINEAR); osd_canvas_index[vblk->index] ^= 1; - osd_canvas_config(reg, canvas_index); osd_input_size_config(reg, scope_src); osd_color_config(reg, pixel_format); + osd_alpha_div_enable(reg, alpha_div_en); DRM_DEBUG("plane_index=%d,HW-OSD=%d\n", mvos->plane_index, vblk->index); DRM_DEBUG("canvas_index[%d]=0x%x,phy_addr=0x%x\n", @@ -519,7 +532,6 @@ static void osd_hw_init(struct meson_vpu_block *vblk) return; } osd->reg = &osd_mif_reg[vblk->index]; - osd_ctrl_set(osd->reg); DRM_DEBUG("%s hw_init done.\n", osd->base.name); } diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 8d9c190..0743321 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -206,6 +206,7 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) /* for compatibility root is always authenticated */ priv->authenticated = capable(CAP_SYS_ADMIN); priv->lock_count = 0; + priv->drm_pid = task_tgid_nr(current); INIT_LIST_HEAD(&priv->lhead); INIT_LIST_HEAD(&priv->fbs); diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 0c4f9c67..72542c3 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -431,6 +431,7 @@ struct drm_file { struct mutex event_read_lock; + pid_t drm_pid; struct drm_prime_file_private prime; }; diff --git a/include/uapi/drm/meson_drm.h b/include/uapi/drm/meson_drm.h index 5b12674..cb1d54a 100644 --- a/include/uapi/drm/meson_drm.h +++ b/include/uapi/drm/meson_drm.h @@ -12,7 +12,11 @@ #ifndef _MESON_DRM_H #define _MESON_DRM_H -#include +#include "drm.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* Use flags */ #define MESON_USE_NONE 0 @@ -25,7 +29,13 @@ #define MESON_USE_CAMERA_WRITE (1ull << 13) #define MESON_USE_CAMERA_READ (1ull << 14) #define MESON_USE_TEXTURE (1ull << 17) +#define MESON_USE_RENDER_VIP (1ull << 18) +#define MESON_USE_OVERLAY (1ull << 19) +/* For Buffer synchronization using dma-buf fence */ +#define MESON_GEM_CPU_PREP_READ (1 << 0) +#define MESON_GEM_CPU_PREP_WRITE (1 << 1) +#define MESON_GEM_CPU_PREP_NOWAIT (1 << 2) /** * User-desired buffer creation information structure. @@ -41,9 +51,57 @@ struct drm_meson_gem_create { __u32 handle; }; +/** + * A structure to gem information. + * + * @handle: a handle to gem object created. + * @flags: flag value including memory type and cache attribute and + * this value would be set by driver. + * @size: size to memory region allocated by gem and this size would + * be set by driver. + */ +struct drm_meson_gem_info { + uint32_t handle; + uint32_t flags; + uint64_t size; +}; + +struct drm_meson_plane_blank { + uint32_t plane_type; + uint32_t onoff; +}; + +struct drm_meson_gem_sync { + uint32_t handle; +}; + +struct drm_meson_gem_cpu_access { + uint32_t handle; + uint32_t flags; +}; + #define DRM_MESON_GEM_CREATE 0x00 +#define DRM_MESON_GEM_GET 0x01 +#define DRM_MESON_SET_BLANK 0x02 +#define DRM_MESON_GEM_SYNC 0x03 +#define DRM_MESON_GEM_CPU_PREP 0x04 +#define DRM_MESON_GEM_CPU_FINI 0x05 #define DRM_IOCTL_MESON_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \ DRM_MESON_GEM_CREATE, struct drm_meson_gem_create) +#define DRM_IOCTL_MESON_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_MESON_GEM_GET, struct drm_meson_gem_info) +#define DRM_IOCTL_MESON_SET_BLANK DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_MESON_SET_BLANK, struct drm_meson_plane_blank) +#define DRM_IOCTL_MESON_GEM_SYNC DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_MESON_GEM_SYNC, struct drm_meson_gem_sync) +#define DRM_IOCTL_MESON_GEM_CPU_PREP DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_MESON_GEM_CPU_PREP, struct drm_meson_gem_cpu_access) +#define DRM_IOCTL_MESON_GEM_CPU_FINI DRM_IOWR(DRM_COMMAND_BASE + \ + DRM_MESON_GEM_CPU_FINI, struct drm_meson_gem_cpu_access) + +#if defined(__cplusplus) +} +#endif #endif /* _MESON_DRM_H */ -- 2.7.4 From 35945cc8e5661e23701ee5ddf414296f363b5570 Mon Sep 17 00:00:00 2001 From: "Sihyun, Park" Date: Mon, 31 May 2021 19:19:37 +0900 Subject: [PATCH 16/16] amlogic: drm: support zpos update Add to support zpos property update. Change-Id: I854c644673b46fbf4f620ce1249e57b7206d6fce Signed-off-by: Sihyun, Park Signed-off-by: Seung-Woo Kim --- drivers/amlogic/drm/meson_plane.c | 7 ++++++- drivers/amlogic/drm/meson_plane.h | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/drivers/amlogic/drm/meson_plane.c b/drivers/amlogic/drm/meson_plane.c index 855e190..78ea0da 100644 --- a/drivers/amlogic/drm/meson_plane.c +++ b/drivers/amlogic/drm/meson_plane.c @@ -487,7 +487,7 @@ static struct am_osd_plane *am_plane_create(struct meson_drm *priv, int i) { struct am_osd_plane *osd_plane; struct drm_plane *plane; - u32 type = 0; + u32 type = 0, zpos; char plane_name[8]; const u64 *format_modifiers = afbc_wb_modifier; @@ -506,6 +506,8 @@ static struct am_osd_plane *am_plane_create(struct meson_drm *priv, int i) osd_plane->drv = priv; osd_plane->plane_index = i; + zpos = osd_plane->plane_index; + plane = &osd_plane->base; sprintf(plane_name, "osd%d", i); @@ -517,6 +519,9 @@ static struct am_osd_plane *am_plane_create(struct meson_drm *priv, int i) type, plane_name); drm_plane_create_premult_en_property(plane); + drm_plane_create_zpos_property(plane, zpos, + MESON_PLANE_BEGIN_ZORDER, + MESON_PLANE_END_ZORDER); drm_plane_helper_add(plane, &am_osd_helper_funcs); osd_drm_debugfs_add(&osd_plane->plane_debugfs_dir, plane_name, osd_plane->plane_index); diff --git a/drivers/amlogic/drm/meson_plane.h b/drivers/amlogic/drm/meson_plane.h index 5be8adc..63e2709 100644 --- a/drivers/amlogic/drm/meson_plane.h +++ b/drivers/amlogic/drm/meson_plane.h @@ -29,6 +29,9 @@ #include "osd_drm.h" #include "meson_fb.h" +#define MESON_PLANE_BEGIN_ZORDER 1 +#define MESON_PLANE_END_ZORDER 65 + struct am_meson_plane_state { struct drm_plane_state base; u32 premult_en; -- 2.7.4