From: Arnd Bergmann <arnd@xxxxxxxx> The zte zx platform is getting removed, so this driver is no longer needed. Cc: Jun Nie <jun.nie@xxxxxxxxxx> Cc: Shawn Guo <shawnguo@xxxxxxxxxx> Link: https://lore.kernel.org/linux-arm-kernel/20210120124812.2800027-1-arnd@xxxxxxxxxx/T/ Signed-off-by: Arnd Bergmann <arnd@xxxxxxxx> --- .../devicetree/bindings/display/zte,vou.txt | 120 --- drivers/gpu/drm/Kconfig | 2 - drivers/gpu/drm/Makefile | 1 - drivers/gpu/drm/zte/Kconfig | 11 - drivers/gpu/drm/zte/Makefile | 10 - drivers/gpu/drm/zte/zx_common_regs.h | 28 - drivers/gpu/drm/zte/zx_drm_drv.c | 190 ---- drivers/gpu/drm/zte/zx_drm_drv.h | 34 - drivers/gpu/drm/zte/zx_hdmi.c | 760 --------------- drivers/gpu/drm/zte/zx_hdmi_regs.h | 66 -- drivers/gpu/drm/zte/zx_plane.c | 533 ---------- drivers/gpu/drm/zte/zx_plane.h | 26 - drivers/gpu/drm/zte/zx_plane_regs.h | 120 --- drivers/gpu/drm/zte/zx_tvenc.c | 400 -------- drivers/gpu/drm/zte/zx_tvenc_regs.h | 27 - drivers/gpu/drm/zte/zx_vga.c | 527 ---------- drivers/gpu/drm/zte/zx_vga_regs.h | 33 - drivers/gpu/drm/zte/zx_vou.c | 921 ------------------ drivers/gpu/drm/zte/zx_vou.h | 64 -- drivers/gpu/drm/zte/zx_vou_regs.h | 212 ---- 20 files changed, 4085 deletions(-) delete mode 100644 Documentation/devicetree/bindings/display/zte,vou.txt delete mode 100644 drivers/gpu/drm/zte/Kconfig delete mode 100644 drivers/gpu/drm/zte/Makefile delete mode 100644 drivers/gpu/drm/zte/zx_common_regs.h delete mode 100644 drivers/gpu/drm/zte/zx_drm_drv.c delete mode 100644 drivers/gpu/drm/zte/zx_drm_drv.h delete mode 100644 drivers/gpu/drm/zte/zx_hdmi.c delete mode 100644 drivers/gpu/drm/zte/zx_hdmi_regs.h delete mode 100644 drivers/gpu/drm/zte/zx_plane.c delete mode 100644 drivers/gpu/drm/zte/zx_plane.h delete mode 100644 drivers/gpu/drm/zte/zx_plane_regs.h delete mode 100644 drivers/gpu/drm/zte/zx_tvenc.c delete mode 100644 drivers/gpu/drm/zte/zx_tvenc_regs.h delete mode 100644 drivers/gpu/drm/zte/zx_vga.c delete mode 100644 drivers/gpu/drm/zte/zx_vga_regs.h delete mode 100644 drivers/gpu/drm/zte/zx_vou.c delete mode 100644 drivers/gpu/drm/zte/zx_vou.h delete mode 100644 drivers/gpu/drm/zte/zx_vou_regs.h diff --git a/Documentation/devicetree/bindings/display/zte,vou.txt b/Documentation/devicetree/bindings/display/zte,vou.txt deleted file mode 100644 index 38476475fd60..000000000000 --- a/Documentation/devicetree/bindings/display/zte,vou.txt +++ /dev/null @@ -1,120 +0,0 @@ -ZTE VOU Display Controller - -This is a display controller found on ZTE ZX296718 SoC. It includes multiple -Graphic Layer (GL) and Video Layer (VL), two Mixers/Channels, and a few blocks -handling scaling, color space conversion etc. VOU also integrates the support -for typical output devices, like HDMI, TV Encoder, VGA, and RGB LCD. - -* Master VOU node - -It must be the parent node of all the sub-device nodes. - -Required properties: - - compatible: should be "zte,zx296718-vou" - - #address-cells: should be <1> - - #size-cells: should be <1> - - ranges: list of address translations between VOU and sub-devices - -* VOU DPC device - -Required properties: - - compatible: should be "zte,zx296718-dpc" - - reg: Physical base address and length of DPC register regions, one for each - entry in 'reg-names' - - reg-names: The names of register regions. The following regions are required: - "osd" - "timing_ctrl" - "dtrc" - "vou_ctrl" - "otfppu" - - interrupts: VOU DPC interrupt number to CPU - - clocks: A list of phandle + clock-specifier pairs, one for each entry - in 'clock-names' - - clock-names: A list of clock names. The following clocks are required: - "aclk" - "ppu_wclk" - "main_wclk" - "aux_wclk" - -* HDMI output device - -Required properties: - - compatible: should be "zte,zx296718-hdmi" - - reg: Physical base address and length of the HDMI device IO region - - interrupts : HDMI interrupt number to CPU - - clocks: A list of phandle + clock-specifier pairs, one for each entry - in 'clock-names' - - clock-names: A list of clock names. The following clocks are required: - "osc_cec" - "osc_clk" - "xclk" - -* TV Encoder output device - -Required properties: - - compatible: should be "zte,zx296718-tvenc" - - reg: Physical base address and length of the TVENC device IO region - - zte,tvenc-power-control: the phandle to SYSCTRL block followed by two - integer cells. The first cell is the offset of SYSCTRL register used - to control TV Encoder DAC power, and the second cell is the bit mask. - -* VGA output device - -Required properties: - - compatible: should be "zte,zx296718-vga" - - reg: Physical base address and length of the VGA device IO region - - interrupts : VGA interrupt number to CPU - - clocks: Phandle with clock-specifier pointing to VGA I2C clock. - - clock-names: Must be "i2c_wclk". - - zte,vga-power-control: the phandle to SYSCTRL block followed by two - integer cells. The first cell is the offset of SYSCTRL register used - to control VGA DAC power, and the second cell is the bit mask. - -Example: - -vou: vou@1440000 { - compatible = "zte,zx296718-vou"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 0x1440000 0x10000>; - - dpc: dpc@0 { - compatible = "zte,zx296718-dpc"; - reg = <0x0000 0x1000>, <0x1000 0x1000>, - <0x5000 0x1000>, <0x6000 0x1000>, - <0xa000 0x1000>; - reg-names = "osd", "timing_ctrl", - "dtrc", "vou_ctrl", - "otfppu"; - interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&topcrm VOU_ACLK>, <&topcrm VOU_PPU_WCLK>, - <&topcrm VOU_MAIN_WCLK>, <&topcrm VOU_AUX_WCLK>; - clock-names = "aclk", "ppu_wclk", - "main_wclk", "aux_wclk"; - }; - - vga: vga@8000 { - compatible = "zte,zx296718-vga"; - reg = <0x8000 0x1000>; - interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&topcrm VGA_I2C_WCLK>; - clock-names = "i2c_wclk"; - zte,vga-power-control = <&sysctrl 0x170 0xe0>; - }; - - hdmi: hdmi@c000 { - compatible = "zte,zx296718-hdmi"; - reg = <0xc000 0x4000>; - interrupts = <GIC_SPI 82 IRQ_TYPE_EDGE_RISING>; - clocks = <&topcrm HDMI_OSC_CEC>, - <&topcrm HDMI_OSC_CLK>, - <&topcrm HDMI_XCLK>; - clock-names = "osc_cec", "osc_clk", "xclk"; - }; - - tvenc: tvenc@2000 { - compatible = "zte,zx296718-tvenc"; - reg = <0x2000 0x1000>; - zte,tvenc-power-control = <&sysctrl 0x170 0x10>; - }; -}; diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 0973f408d75f..6b76b036219a 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -358,8 +358,6 @@ source "drivers/gpu/drm/hisilicon/Kconfig" source "drivers/gpu/drm/mediatek/Kconfig" -source "drivers/gpu/drm/zte/Kconfig" - source "drivers/gpu/drm/mxsfb/Kconfig" source "drivers/gpu/drm/meson/Kconfig" diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index fefaff4c832d..025db1c9f15e 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -112,7 +112,6 @@ obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/ obj-$(CONFIG_DRM_ETNAVIV) += etnaviv/ obj-$(CONFIG_DRM_ARCPGU)+= arc/ obj-y += hisilicon/ -obj-$(CONFIG_DRM_ZTE) += zte/ obj-$(CONFIG_DRM_MXSFB) += mxsfb/ obj-y += tiny/ obj-$(CONFIG_DRM_PL111) += pl111/ diff --git a/drivers/gpu/drm/zte/Kconfig b/drivers/gpu/drm/zte/Kconfig deleted file mode 100644 index 90ebaedc11fd..000000000000 --- a/drivers/gpu/drm/zte/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config DRM_ZTE - tristate "DRM Support for ZTE SoCs" - depends on DRM && ARCH_ZX - select DRM_KMS_CMA_HELPER - select DRM_KMS_FB_HELPER - select DRM_KMS_HELPER - select SND_SOC_HDMI_CODEC if SND_SOC - select VIDEOMODE_HELPERS - help - Choose this option to enable DRM on ZTE ZX SoCs. diff --git a/drivers/gpu/drm/zte/Makefile b/drivers/gpu/drm/zte/Makefile deleted file mode 100644 index b6d966d849dd..000000000000 --- a/drivers/gpu/drm/zte/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -zxdrm-y := \ - zx_drm_drv.o \ - zx_hdmi.o \ - zx_plane.o \ - zx_tvenc.o \ - zx_vga.o \ - zx_vou.o - -obj-$(CONFIG_DRM_ZTE) += zxdrm.o diff --git a/drivers/gpu/drm/zte/zx_common_regs.h b/drivers/gpu/drm/zte/zx_common_regs.h deleted file mode 100644 index b7b996db129d..000000000000 --- a/drivers/gpu/drm/zte/zx_common_regs.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - */ - -#ifndef __ZX_COMMON_REGS_H__ -#define __ZX_COMMON_REGS_H__ - -/* CSC registers */ -#define CSC_CTRL0 0x30 -#define CSC_COV_MODE_SHIFT 16 -#define CSC_COV_MODE_MASK (0xffff << CSC_COV_MODE_SHIFT) -#define CSC_BT601_IMAGE_RGB2YCBCR 0 -#define CSC_BT601_IMAGE_YCBCR2RGB 1 -#define CSC_BT601_VIDEO_RGB2YCBCR 2 -#define CSC_BT601_VIDEO_YCBCR2RGB 3 -#define CSC_BT709_IMAGE_RGB2YCBCR 4 -#define CSC_BT709_IMAGE_YCBCR2RGB 5 -#define CSC_BT709_VIDEO_RGB2YCBCR 6 -#define CSC_BT709_VIDEO_YCBCR2RGB 7 -#define CSC_BT2020_IMAGE_RGB2YCBCR 8 -#define CSC_BT2020_IMAGE_YCBCR2RGB 9 -#define CSC_BT2020_VIDEO_RGB2YCBCR 10 -#define CSC_BT2020_VIDEO_YCBCR2RGB 11 -#define CSC_WORK_ENABLE BIT(0) - -#endif /* __ZX_COMMON_REGS_H__ */ diff --git a/drivers/gpu/drm/zte/zx_drm_drv.c b/drivers/gpu/drm/zte/zx_drm_drv.c deleted file mode 100644 index 5506336594e2..000000000000 --- a/drivers/gpu/drm/zte/zx_drm_drv.c +++ /dev/null @@ -1,190 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2016 Linaro Ltd. - * Copyright 2016 ZTE Corporation. - */ - -#include <linux/clk.h> -#include <linux/component.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/of_graph.h> -#include <linux/of_platform.h> -#include <linux/spinlock.h> - -#include <drm/drm_atomic_helper.h> -#include <drm/drm_crtc.h> -#include <drm/drm_drv.h> -#include <drm/drm_fb_cma_helper.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_gem_cma_helper.h> -#include <drm/drm_gem_framebuffer_helper.h> -#include <drm/drm_of.h> -#include <drm/drm_probe_helper.h> -#include <drm/drm_vblank.h> - -#include "zx_drm_drv.h" -#include "zx_vou.h" - -static const struct drm_mode_config_funcs zx_drm_mode_config_funcs = { - .fb_create = drm_gem_fb_create, - .atomic_check = drm_atomic_helper_check, - .atomic_commit = drm_atomic_helper_commit, -}; - -DEFINE_DRM_GEM_CMA_FOPS(zx_drm_fops); - -static const struct drm_driver zx_drm_driver = { - .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, - DRM_GEM_CMA_DRIVER_OPS, - .fops = &zx_drm_fops, - .name = "zx-vou", - .desc = "ZTE VOU Controller DRM", - .date = "20160811", - .major = 1, - .minor = 0, -}; - -static int zx_drm_bind(struct device *dev) -{ - struct drm_device *drm; - int ret; - - drm = drm_dev_alloc(&zx_drm_driver, dev); - if (IS_ERR(drm)) - return PTR_ERR(drm); - - dev_set_drvdata(dev, drm); - - drm_mode_config_init(drm); - drm->mode_config.min_width = 16; - drm->mode_config.min_height = 16; - drm->mode_config.max_width = 4096; - drm->mode_config.max_height = 4096; - drm->mode_config.funcs = &zx_drm_mode_config_funcs; - - ret = component_bind_all(dev, drm); - if (ret) { - DRM_DEV_ERROR(dev, "failed to bind all components: %d\n", ret); - goto out_unregister; - } - - ret = drm_vblank_init(drm, drm->mode_config.num_crtc); - if (ret < 0) { - DRM_DEV_ERROR(dev, "failed to init vblank: %d\n", ret); - goto out_unbind; - } - - /* - * We will manage irq handler on our own. In this case, irq_enabled - * need to be true for using vblank core support. - */ - drm->irq_enabled = true; - - drm_mode_config_reset(drm); - drm_kms_helper_poll_init(drm); - - ret = drm_dev_register(drm, 0); - if (ret) - goto out_poll_fini; - - drm_fbdev_generic_setup(drm, 32); - - return 0; - -out_poll_fini: - drm_kms_helper_poll_fini(drm); - drm_mode_config_cleanup(drm); -out_unbind: - component_unbind_all(dev, drm); -out_unregister: - dev_set_drvdata(dev, NULL); - drm_dev_put(drm); - return ret; -} - -static void zx_drm_unbind(struct device *dev) -{ - struct drm_device *drm = dev_get_drvdata(dev); - - drm_dev_unregister(drm); - drm_kms_helper_poll_fini(drm); - drm_atomic_helper_shutdown(drm); - drm_mode_config_cleanup(drm); - component_unbind_all(dev, drm); - dev_set_drvdata(dev, NULL); - drm_dev_put(drm); -} - -static const struct component_master_ops zx_drm_master_ops = { - .bind = zx_drm_bind, - .unbind = zx_drm_unbind, -}; - -static int compare_of(struct device *dev, void *data) -{ - return dev->of_node == data; -} - -static int zx_drm_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct device_node *parent = dev->of_node; - struct device_node *child; - struct component_match *match = NULL; - int ret; - - ret = devm_of_platform_populate(dev); - if (ret) - return ret; - - for_each_available_child_of_node(parent, child) - component_match_add(dev, &match, compare_of, child); - - return component_master_add_with_match(dev, &zx_drm_master_ops, match); -} - -static int zx_drm_remove(struct platform_device *pdev) -{ - component_master_del(&pdev->dev, &zx_drm_master_ops); - return 0; -} - -static const struct of_device_id zx_drm_of_match[] = { - { .compatible = "zte,zx296718-vou", }, - { /* end */ }, -}; -MODULE_DEVICE_TABLE(of, zx_drm_of_match); - -static struct platform_driver zx_drm_platform_driver = { - .probe = zx_drm_probe, - .remove = zx_drm_remove, - .driver = { - .name = "zx-drm", - .of_match_table = zx_drm_of_match, - }, -}; - -static struct platform_driver *drivers[] = { - &zx_crtc_driver, - &zx_hdmi_driver, - &zx_tvenc_driver, - &zx_vga_driver, - &zx_drm_platform_driver, -}; - -static int zx_drm_init(void) -{ - return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); -} -module_init(zx_drm_init); - -static void zx_drm_exit(void) -{ - platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); -} -module_exit(zx_drm_exit); - -MODULE_AUTHOR("Shawn Guo <shawn.guo@xxxxxxxxxx>"); -MODULE_DESCRIPTION("ZTE ZX VOU DRM driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/zte/zx_drm_drv.h b/drivers/gpu/drm/zte/zx_drm_drv.h deleted file mode 100644 index 80cdaf479c74..000000000000 --- a/drivers/gpu/drm/zte/zx_drm_drv.h +++ /dev/null @@ -1,34 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2016 Linaro Ltd. - * Copyright 2016 ZTE Corporation. - */ - -#ifndef __ZX_DRM_DRV_H__ -#define __ZX_DRM_DRV_H__ - -extern struct platform_driver zx_crtc_driver; -extern struct platform_driver zx_hdmi_driver; -extern struct platform_driver zx_tvenc_driver; -extern struct platform_driver zx_vga_driver; - -static inline u32 zx_readl(void __iomem *reg) -{ - return readl_relaxed(reg); -} - -static inline void zx_writel(void __iomem *reg, u32 val) -{ - writel_relaxed(val, reg); -} - -static inline void zx_writel_mask(void __iomem *reg, u32 mask, u32 val) -{ - u32 tmp; - - tmp = zx_readl(reg); - tmp = (tmp & ~mask) | (val & mask); - zx_writel(reg, tmp); -} - -#endif /* __ZX_DRM_DRV_H__ */ diff --git a/drivers/gpu/drm/zte/zx_hdmi.c b/drivers/gpu/drm/zte/zx_hdmi.c deleted file mode 100644 index cd79ca0a92a9..000000000000 --- a/drivers/gpu/drm/zte/zx_hdmi.c +++ /dev/null @@ -1,760 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2016 Linaro Ltd. - * Copyright 2016 ZTE Corporation. - */ - -#include <linux/clk.h> -#include <linux/component.h> -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/hdmi.h> -#include <linux/irq.h> -#include <linux/mfd/syscon.h> -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/of_device.h> - -#include <drm/drm_atomic_helper.h> -#include <drm/drm_edid.h> -#include <drm/drm_of.h> -#include <drm/drm_probe_helper.h> -#include <drm/drm_print.h> -#include <drm/drm_simple_kms_helper.h> - -#include <sound/hdmi-codec.h> - -#include "zx_hdmi_regs.h" -#include "zx_vou.h" - -#define ZX_HDMI_INFOFRAME_SIZE 31 -#define DDC_SEGMENT_ADDR 0x30 - -struct zx_hdmi_i2c { - struct i2c_adapter adap; - struct mutex lock; -}; - -struct zx_hdmi { - struct drm_connector connector; - struct drm_encoder encoder; - struct zx_hdmi_i2c *ddc; - struct device *dev; - struct drm_device *drm; - void __iomem *mmio; - struct clk *cec_clk; - struct clk *osc_clk; - struct clk *xclk; - bool sink_is_hdmi; - bool sink_has_audio; - struct platform_device *audio_pdev; -}; - -#define to_zx_hdmi(x) container_of(x, struct zx_hdmi, x) - -static inline u8 hdmi_readb(struct zx_hdmi *hdmi, u16 offset) -{ - return readl_relaxed(hdmi->mmio + offset * 4); -} - -static inline void hdmi_writeb(struct zx_hdmi *hdmi, u16 offset, u8 val) -{ - writel_relaxed(val, hdmi->mmio + offset * 4); -} - -static inline void hdmi_writeb_mask(struct zx_hdmi *hdmi, u16 offset, - u8 mask, u8 val) -{ - u8 tmp; - - tmp = hdmi_readb(hdmi, offset); - tmp = (tmp & ~mask) | (val & mask); - hdmi_writeb(hdmi, offset, tmp); -} - -static int zx_hdmi_infoframe_trans(struct zx_hdmi *hdmi, - union hdmi_infoframe *frame, u8 fsel) -{ - u8 buffer[ZX_HDMI_INFOFRAME_SIZE]; - int num; - int i; - - hdmi_writeb(hdmi, TPI_INFO_FSEL, fsel); - - num = hdmi_infoframe_pack(frame, buffer, ZX_HDMI_INFOFRAME_SIZE); - if (num < 0) { - DRM_DEV_ERROR(hdmi->dev, "failed to pack infoframe: %d\n", num); - return num; - } - - for (i = 0; i < num; i++) - hdmi_writeb(hdmi, TPI_INFO_B0 + i, buffer[i]); - - hdmi_writeb_mask(hdmi, TPI_INFO_EN, TPI_INFO_TRANS_RPT, - TPI_INFO_TRANS_RPT); - hdmi_writeb_mask(hdmi, TPI_INFO_EN, TPI_INFO_TRANS_EN, - TPI_INFO_TRANS_EN); - - return num; -} - -static int zx_hdmi_config_video_vsi(struct zx_hdmi *hdmi, - struct drm_display_mode *mode) -{ - union hdmi_infoframe frame; - int ret; - - ret = drm_hdmi_vendor_infoframe_from_display_mode(&frame.vendor.hdmi, - &hdmi->connector, - mode); - if (ret) { - DRM_DEV_ERROR(hdmi->dev, "failed to get vendor infoframe: %d\n", - ret); - return ret; - } - - return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_VSIF); -} - -static int zx_hdmi_config_video_avi(struct zx_hdmi *hdmi, - struct drm_display_mode *mode) -{ - union hdmi_infoframe frame; - int ret; - - ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi, - &hdmi->connector, - mode); - if (ret) { - DRM_DEV_ERROR(hdmi->dev, "failed to get avi infoframe: %d\n", - ret); - return ret; - } - - /* We always use YUV444 for HDMI output. */ - frame.avi.colorspace = HDMI_COLORSPACE_YUV444; - - return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_AVI); -} - -static void zx_hdmi_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) -{ - struct zx_hdmi *hdmi = to_zx_hdmi(encoder); - - if (hdmi->sink_is_hdmi) { - zx_hdmi_config_video_avi(hdmi, mode); - zx_hdmi_config_video_vsi(hdmi, mode); - } -} - -static void zx_hdmi_phy_start(struct zx_hdmi *hdmi) -{ - /* Copy from ZTE BSP code */ - hdmi_writeb(hdmi, 0x222, 0x0); - hdmi_writeb(hdmi, 0x224, 0x4); - hdmi_writeb(hdmi, 0x909, 0x0); - hdmi_writeb(hdmi, 0x7b0, 0x90); - hdmi_writeb(hdmi, 0x7b1, 0x00); - hdmi_writeb(hdmi, 0x7b2, 0xa7); - hdmi_writeb(hdmi, 0x7b8, 0xaa); - hdmi_writeb(hdmi, 0x7b2, 0xa7); - hdmi_writeb(hdmi, 0x7b3, 0x0f); - hdmi_writeb(hdmi, 0x7b4, 0x0f); - hdmi_writeb(hdmi, 0x7b5, 0x55); - hdmi_writeb(hdmi, 0x7b7, 0x03); - hdmi_writeb(hdmi, 0x7b9, 0x12); - hdmi_writeb(hdmi, 0x7ba, 0x32); - hdmi_writeb(hdmi, 0x7bc, 0x68); - hdmi_writeb(hdmi, 0x7be, 0x40); - hdmi_writeb(hdmi, 0x7bf, 0x84); - hdmi_writeb(hdmi, 0x7c1, 0x0f); - hdmi_writeb(hdmi, 0x7c8, 0x02); - hdmi_writeb(hdmi, 0x7c9, 0x03); - hdmi_writeb(hdmi, 0x7ca, 0x40); - hdmi_writeb(hdmi, 0x7dc, 0x31); - hdmi_writeb(hdmi, 0x7e2, 0x04); - hdmi_writeb(hdmi, 0x7e0, 0x06); - hdmi_writeb(hdmi, 0x7cb, 0x68); - hdmi_writeb(hdmi, 0x7f9, 0x02); - hdmi_writeb(hdmi, 0x7b6, 0x02); - hdmi_writeb(hdmi, 0x7f3, 0x0); -} - -static void zx_hdmi_hw_enable(struct zx_hdmi *hdmi) -{ - /* Enable pclk */ - hdmi_writeb_mask(hdmi, CLKPWD, CLKPWD_PDIDCK, CLKPWD_PDIDCK); - - /* Enable HDMI for TX */ - hdmi_writeb_mask(hdmi, FUNC_SEL, FUNC_HDMI_EN, FUNC_HDMI_EN); - - /* Enable deep color packet */ - hdmi_writeb_mask(hdmi, P2T_CTRL, P2T_DC_PKT_EN, P2T_DC_PKT_EN); - - /* Enable HDMI/MHL mode for output */ - hdmi_writeb_mask(hdmi, TEST_TXCTRL, TEST_TXCTRL_HDMI_MODE, - TEST_TXCTRL_HDMI_MODE); - - /* Configure reg_qc_sel */ - hdmi_writeb(hdmi, HDMICTL4, 0x3); - - /* Enable interrupt */ - hdmi_writeb_mask(hdmi, INTR1_MASK, INTR1_MONITOR_DETECT, - INTR1_MONITOR_DETECT); - - /* Start up phy */ - zx_hdmi_phy_start(hdmi); -} - -static void zx_hdmi_hw_disable(struct zx_hdmi *hdmi) -{ - /* Disable interrupt */ - hdmi_writeb_mask(hdmi, INTR1_MASK, INTR1_MONITOR_DETECT, 0); - - /* Disable deep color packet */ - hdmi_writeb_mask(hdmi, P2T_CTRL, P2T_DC_PKT_EN, P2T_DC_PKT_EN); - - /* Disable HDMI for TX */ - hdmi_writeb_mask(hdmi, FUNC_SEL, FUNC_HDMI_EN, 0); - - /* Disable pclk */ - hdmi_writeb_mask(hdmi, CLKPWD, CLKPWD_PDIDCK, 0); -} - -static void zx_hdmi_encoder_enable(struct drm_encoder *encoder) -{ - struct zx_hdmi *hdmi = to_zx_hdmi(encoder); - - clk_prepare_enable(hdmi->cec_clk); - clk_prepare_enable(hdmi->osc_clk); - clk_prepare_enable(hdmi->xclk); - - zx_hdmi_hw_enable(hdmi); - - vou_inf_enable(VOU_HDMI, encoder->crtc); -} - -static void zx_hdmi_encoder_disable(struct drm_encoder *encoder) -{ - struct zx_hdmi *hdmi = to_zx_hdmi(encoder); - - vou_inf_disable(VOU_HDMI, encoder->crtc); - - zx_hdmi_hw_disable(hdmi); - - clk_disable_unprepare(hdmi->xclk); - clk_disable_unprepare(hdmi->osc_clk); - clk_disable_unprepare(hdmi->cec_clk); -} - -static const struct drm_encoder_helper_funcs zx_hdmi_encoder_helper_funcs = { - .enable = zx_hdmi_encoder_enable, - .disable = zx_hdmi_encoder_disable, - .mode_set = zx_hdmi_encoder_mode_set, -}; - -static int zx_hdmi_connector_get_modes(struct drm_connector *connector) -{ - struct zx_hdmi *hdmi = to_zx_hdmi(connector); - struct edid *edid; - int ret; - - edid = drm_get_edid(connector, &hdmi->ddc->adap); - if (!edid) - return 0; - - hdmi->sink_is_hdmi = drm_detect_hdmi_monitor(edid); - hdmi->sink_has_audio = drm_detect_monitor_audio(edid); - drm_connector_update_edid_property(connector, edid); - ret = drm_add_edid_modes(connector, edid); - kfree(edid); - - return ret; -} - -static enum drm_mode_status -zx_hdmi_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - return MODE_OK; -} - -static struct drm_connector_helper_funcs zx_hdmi_connector_helper_funcs = { - .get_modes = zx_hdmi_connector_get_modes, - .mode_valid = zx_hdmi_connector_mode_valid, -}; - -static enum drm_connector_status -zx_hdmi_connector_detect(struct drm_connector *connector, bool force) -{ - struct zx_hdmi *hdmi = to_zx_hdmi(connector); - - return (hdmi_readb(hdmi, TPI_HPD_RSEN) & TPI_HPD_CONNECTION) ? - connector_status_connected : connector_status_disconnected; -} - -static const struct drm_connector_funcs zx_hdmi_connector_funcs = { - .fill_modes = drm_helper_probe_single_connector_modes, - .detect = zx_hdmi_connector_detect, - .destroy = drm_connector_cleanup, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static int zx_hdmi_register(struct drm_device *drm, struct zx_hdmi *hdmi) -{ - struct drm_encoder *encoder = &hdmi->encoder; - - encoder->possible_crtcs = VOU_CRTC_MASK; - - drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); - drm_encoder_helper_add(encoder, &zx_hdmi_encoder_helper_funcs); - - hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; - - drm_connector_init_with_ddc(drm, &hdmi->connector, - &zx_hdmi_connector_funcs, - DRM_MODE_CONNECTOR_HDMIA, - &hdmi->ddc->adap); - drm_connector_helper_add(&hdmi->connector, - &zx_hdmi_connector_helper_funcs); - - drm_connector_attach_encoder(&hdmi->connector, encoder); - - return 0; -} - -static irqreturn_t zx_hdmi_irq_thread(int irq, void *dev_id) -{ - struct zx_hdmi *hdmi = dev_id; - - drm_helper_hpd_irq_event(hdmi->connector.dev); - - return IRQ_HANDLED; -} - -static irqreturn_t zx_hdmi_irq_handler(int irq, void *dev_id) -{ - struct zx_hdmi *hdmi = dev_id; - u8 lstat; - - lstat = hdmi_readb(hdmi, L1_INTR_STAT); - - /* Monitor detect/HPD interrupt */ - if (lstat & L1_INTR_STAT_INTR1) { - u8 stat; - - stat = hdmi_readb(hdmi, INTR1_STAT); - hdmi_writeb(hdmi, INTR1_STAT, stat); - - if (stat & INTR1_MONITOR_DETECT) - return IRQ_WAKE_THREAD; - } - - return IRQ_NONE; -} - -static int zx_hdmi_audio_startup(struct device *dev, void *data) -{ - struct zx_hdmi *hdmi = dev_get_drvdata(dev); - struct drm_encoder *encoder = &hdmi->encoder; - - vou_inf_hdmi_audio_sel(encoder->crtc, VOU_HDMI_AUD_SPDIF); - - return 0; -} - -static void zx_hdmi_audio_shutdown(struct device *dev, void *data) -{ - struct zx_hdmi *hdmi = dev_get_drvdata(dev); - - /* Disable audio input */ - hdmi_writeb_mask(hdmi, AUD_EN, AUD_IN_EN, 0); -} - -static inline int zx_hdmi_audio_get_n(unsigned int fs) -{ - unsigned int n; - - if (fs && (fs % 44100) == 0) - n = 6272 * (fs / 44100); - else - n = fs * 128 / 1000; - - return n; -} - -static int zx_hdmi_audio_hw_params(struct device *dev, - void *data, - struct hdmi_codec_daifmt *daifmt, - struct hdmi_codec_params *params) -{ - struct zx_hdmi *hdmi = dev_get_drvdata(dev); - struct hdmi_audio_infoframe *cea = ¶ms->cea; - union hdmi_infoframe frame; - int n; - - /* We only support spdif for now */ - if (daifmt->fmt != HDMI_SPDIF) { - DRM_DEV_ERROR(hdmi->dev, "invalid daifmt %d\n", daifmt->fmt); - return -EINVAL; - } - - switch (params->sample_width) { - case 16: - hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK, - SPDIF_SAMPLE_SIZE_16BIT); - break; - case 20: - hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK, - SPDIF_SAMPLE_SIZE_20BIT); - break; - case 24: - hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, SPDIF_SAMPLE_SIZE_MASK, - SPDIF_SAMPLE_SIZE_24BIT); - break; - default: - DRM_DEV_ERROR(hdmi->dev, "invalid sample width %d\n", - params->sample_width); - return -EINVAL; - } - - /* CTS is calculated by hardware, and we only need to take care of N */ - n = zx_hdmi_audio_get_n(params->sample_rate); - hdmi_writeb(hdmi, N_SVAL1, n & 0xff); - hdmi_writeb(hdmi, N_SVAL2, (n >> 8) & 0xff); - hdmi_writeb(hdmi, N_SVAL3, (n >> 16) & 0xf); - - /* Enable spdif mode */ - hdmi_writeb_mask(hdmi, AUD_MODE, SPDIF_EN, SPDIF_EN); - - /* Enable audio input */ - hdmi_writeb_mask(hdmi, AUD_EN, AUD_IN_EN, AUD_IN_EN); - - memcpy(&frame.audio, cea, sizeof(*cea)); - - return zx_hdmi_infoframe_trans(hdmi, &frame, FSEL_AUDIO); -} - -static int zx_hdmi_audio_mute(struct device *dev, void *data, - bool enable, int direction) -{ - struct zx_hdmi *hdmi = dev_get_drvdata(dev); - - if (enable) - hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, TPI_AUD_MUTE, - TPI_AUD_MUTE); - else - hdmi_writeb_mask(hdmi, TPI_AUD_CONFIG, TPI_AUD_MUTE, 0); - - return 0; -} - -static int zx_hdmi_audio_get_eld(struct device *dev, void *data, - uint8_t *buf, size_t len) -{ - struct zx_hdmi *hdmi = dev_get_drvdata(dev); - struct drm_connector *connector = &hdmi->connector; - - memcpy(buf, connector->eld, min(sizeof(connector->eld), len)); - - return 0; -} - -static const struct hdmi_codec_ops zx_hdmi_codec_ops = { - .audio_startup = zx_hdmi_audio_startup, - .hw_params = zx_hdmi_audio_hw_params, - .audio_shutdown = zx_hdmi_audio_shutdown, - .mute_stream = zx_hdmi_audio_mute, - .get_eld = zx_hdmi_audio_get_eld, - .no_capture_mute = 1, -}; - -static struct hdmi_codec_pdata zx_hdmi_codec_pdata = { - .ops = &zx_hdmi_codec_ops, - .spdif = 1, -}; - -static int zx_hdmi_audio_register(struct zx_hdmi *hdmi) -{ - struct platform_device *pdev; - - pdev = platform_device_register_data(hdmi->dev, HDMI_CODEC_DRV_NAME, - PLATFORM_DEVID_AUTO, - &zx_hdmi_codec_pdata, - sizeof(zx_hdmi_codec_pdata)); - if (IS_ERR(pdev)) - return PTR_ERR(pdev); - - hdmi->audio_pdev = pdev; - - return 0; -} - -static int zx_hdmi_i2c_read(struct zx_hdmi *hdmi, struct i2c_msg *msg) -{ - int len = msg->len; - u8 *buf = msg->buf; - int retry = 0; - int ret = 0; - - /* Bits [9:8] of bytes */ - hdmi_writeb(hdmi, ZX_DDC_DIN_CNT2, (len >> 8) & 0xff); - /* Bits [7:0] of bytes */ - hdmi_writeb(hdmi, ZX_DDC_DIN_CNT1, len & 0xff); - - /* Clear FIFO */ - hdmi_writeb_mask(hdmi, ZX_DDC_CMD, DDC_CMD_MASK, DDC_CMD_CLEAR_FIFO); - - /* Kick off the read */ - hdmi_writeb_mask(hdmi, ZX_DDC_CMD, DDC_CMD_MASK, - DDC_CMD_SEQUENTIAL_READ); - - while (len > 0) { - int cnt, i; - - /* FIFO needs some time to get ready */ - usleep_range(500, 1000); - - cnt = hdmi_readb(hdmi, ZX_DDC_DOUT_CNT) & DDC_DOUT_CNT_MASK; - if (cnt == 0) { - if (++retry > 5) { - DRM_DEV_ERROR(hdmi->dev, - "DDC FIFO read timed out!"); - return -ETIMEDOUT; - } - continue; - } - - for (i = 0; i < cnt; i++) - *buf++ = hdmi_readb(hdmi, ZX_DDC_DATA); - len -= cnt; - } - - return ret; -} - -static int zx_hdmi_i2c_write(struct zx_hdmi *hdmi, struct i2c_msg *msg) -{ - /* - * The DDC I2C adapter is only for reading EDID data, so we assume - * that the write to this adapter must be the EDID data offset. - */ - if ((msg->len != 1) || - ((msg->addr != DDC_ADDR) && (msg->addr != DDC_SEGMENT_ADDR))) - return -EINVAL; - - if (msg->addr == DDC_SEGMENT_ADDR) - hdmi_writeb(hdmi, ZX_DDC_SEGM, msg->addr << 1); - else if (msg->addr == DDC_ADDR) - hdmi_writeb(hdmi, ZX_DDC_ADDR, msg->addr << 1); - - hdmi_writeb(hdmi, ZX_DDC_OFFSET, msg->buf[0]); - - return 0; -} - -static int zx_hdmi_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, - int num) -{ - struct zx_hdmi *hdmi = i2c_get_adapdata(adap); - struct zx_hdmi_i2c *ddc = hdmi->ddc; - int i, ret = 0; - - mutex_lock(&ddc->lock); - - /* Enable DDC master access */ - hdmi_writeb_mask(hdmi, TPI_DDC_MASTER_EN, HW_DDC_MASTER, HW_DDC_MASTER); - - for (i = 0; i < num; i++) { - DRM_DEV_DEBUG(hdmi->dev, - "xfer: num: %d/%d, len: %d, flags: %#x\n", - i + 1, num, msgs[i].len, msgs[i].flags); - - if (msgs[i].flags & I2C_M_RD) - ret = zx_hdmi_i2c_read(hdmi, &msgs[i]); - else - ret = zx_hdmi_i2c_write(hdmi, &msgs[i]); - - if (ret < 0) - break; - } - - if (!ret) - ret = num; - - /* Disable DDC master access */ - hdmi_writeb_mask(hdmi, TPI_DDC_MASTER_EN, HW_DDC_MASTER, 0); - - mutex_unlock(&ddc->lock); - - return ret; -} - -static u32 zx_hdmi_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -static const struct i2c_algorithm zx_hdmi_algorithm = { - .master_xfer = zx_hdmi_i2c_xfer, - .functionality = zx_hdmi_i2c_func, -}; - -static int zx_hdmi_ddc_register(struct zx_hdmi *hdmi) -{ - struct i2c_adapter *adap; - struct zx_hdmi_i2c *ddc; - int ret; - - ddc = devm_kzalloc(hdmi->dev, sizeof(*ddc), GFP_KERNEL); - if (!ddc) - return -ENOMEM; - - hdmi->ddc = ddc; - mutex_init(&ddc->lock); - - adap = &ddc->adap; - adap->owner = THIS_MODULE; - adap->class = I2C_CLASS_DDC; - adap->dev.parent = hdmi->dev; - adap->algo = &zx_hdmi_algorithm; - snprintf(adap->name, sizeof(adap->name), "zx hdmi i2c"); - - ret = i2c_add_adapter(adap); - if (ret) { - DRM_DEV_ERROR(hdmi->dev, "failed to add I2C adapter: %d\n", - ret); - return ret; - } - - i2c_set_adapdata(adap, hdmi); - - return 0; -} - -static int zx_hdmi_bind(struct device *dev, struct device *master, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - struct drm_device *drm = data; - struct resource *res; - struct zx_hdmi *hdmi; - int irq; - int ret; - - hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); - if (!hdmi) - return -ENOMEM; - - hdmi->dev = dev; - hdmi->drm = drm; - - dev_set_drvdata(dev, hdmi); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hdmi->mmio = devm_ioremap_resource(dev, res); - if (IS_ERR(hdmi->mmio)) { - ret = PTR_ERR(hdmi->mmio); - DRM_DEV_ERROR(dev, "failed to remap hdmi region: %d\n", ret); - return ret; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - hdmi->cec_clk = devm_clk_get(hdmi->dev, "osc_cec"); - if (IS_ERR(hdmi->cec_clk)) { - ret = PTR_ERR(hdmi->cec_clk); - DRM_DEV_ERROR(dev, "failed to get cec_clk: %d\n", ret); - return ret; - } - - hdmi->osc_clk = devm_clk_get(hdmi->dev, "osc_clk"); - if (IS_ERR(hdmi->osc_clk)) { - ret = PTR_ERR(hdmi->osc_clk); - DRM_DEV_ERROR(dev, "failed to get osc_clk: %d\n", ret); - return ret; - } - - hdmi->xclk = devm_clk_get(hdmi->dev, "xclk"); - if (IS_ERR(hdmi->xclk)) { - ret = PTR_ERR(hdmi->xclk); - DRM_DEV_ERROR(dev, "failed to get xclk: %d\n", ret); - return ret; - } - - ret = zx_hdmi_ddc_register(hdmi); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register ddc: %d\n", ret); - return ret; - } - - ret = zx_hdmi_audio_register(hdmi); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register audio: %d\n", ret); - return ret; - } - - ret = zx_hdmi_register(drm, hdmi); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register hdmi: %d\n", ret); - return ret; - } - - ret = devm_request_threaded_irq(dev, irq, zx_hdmi_irq_handler, - zx_hdmi_irq_thread, IRQF_SHARED, - dev_name(dev), hdmi); - if (ret) { - DRM_DEV_ERROR(dev, "failed to request threaded irq: %d\n", ret); - return ret; - } - - return 0; -} - -static void zx_hdmi_unbind(struct device *dev, struct device *master, - void *data) -{ - struct zx_hdmi *hdmi = dev_get_drvdata(dev); - - hdmi->connector.funcs->destroy(&hdmi->connector); - hdmi->encoder.funcs->destroy(&hdmi->encoder); - - if (hdmi->audio_pdev) - platform_device_unregister(hdmi->audio_pdev); -} - -static const struct component_ops zx_hdmi_component_ops = { - .bind = zx_hdmi_bind, - .unbind = zx_hdmi_unbind, -}; - -static int zx_hdmi_probe(struct platform_device *pdev) -{ - return component_add(&pdev->dev, &zx_hdmi_component_ops); -} - -static int zx_hdmi_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &zx_hdmi_component_ops); - return 0; -} - -static const struct of_device_id zx_hdmi_of_match[] = { - { .compatible = "zte,zx296718-hdmi", }, - { /* end */ }, -}; -MODULE_DEVICE_TABLE(of, zx_hdmi_of_match); - -struct platform_driver zx_hdmi_driver = { - .probe = zx_hdmi_probe, - .remove = zx_hdmi_remove, - .driver = { - .name = "zx-hdmi", - .of_match_table = zx_hdmi_of_match, - }, -}; diff --git a/drivers/gpu/drm/zte/zx_hdmi_regs.h b/drivers/gpu/drm/zte/zx_hdmi_regs.h deleted file mode 100644 index 397949e64eff..000000000000 --- a/drivers/gpu/drm/zte/zx_hdmi_regs.h +++ /dev/null @@ -1,66 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2016 Linaro Ltd. - * Copyright 2016 ZTE Corporation. - */ - -#ifndef __ZX_HDMI_REGS_H__ -#define __ZX_HDMI_REGS_H__ - -#define FUNC_SEL 0x000b -#define FUNC_HDMI_EN BIT(0) -#define CLKPWD 0x000d -#define CLKPWD_PDIDCK BIT(2) -#define P2T_CTRL 0x0066 -#define P2T_DC_PKT_EN BIT(7) -#define L1_INTR_STAT 0x007e -#define L1_INTR_STAT_INTR1 BIT(0) -#define INTR1_STAT 0x008f -#define INTR1_MASK 0x0095 -#define INTR1_MONITOR_DETECT (BIT(5) | BIT(6)) -#define ZX_DDC_ADDR 0x00ed -#define ZX_DDC_SEGM 0x00ee -#define ZX_DDC_OFFSET 0x00ef -#define ZX_DDC_DIN_CNT1 0x00f0 -#define ZX_DDC_DIN_CNT2 0x00f1 -#define ZX_DDC_CMD 0x00f3 -#define DDC_CMD_MASK 0xf -#define DDC_CMD_CLEAR_FIFO 0x9 -#define DDC_CMD_SEQUENTIAL_READ 0x2 -#define ZX_DDC_DATA 0x00f4 -#define ZX_DDC_DOUT_CNT 0x00f5 -#define DDC_DOUT_CNT_MASK 0x1f -#define TEST_TXCTRL 0x00f7 -#define TEST_TXCTRL_HDMI_MODE BIT(1) -#define HDMICTL4 0x0235 -#define TPI_HPD_RSEN 0x063b -#define TPI_HPD_CONNECTION (BIT(1) | BIT(2)) -#define TPI_INFO_FSEL 0x06bf -#define FSEL_AVI 0 -#define FSEL_GBD 1 -#define FSEL_AUDIO 2 -#define FSEL_SPD 3 -#define FSEL_MPEG 4 -#define FSEL_VSIF 5 -#define TPI_INFO_B0 0x06c0 -#define TPI_INFO_EN 0x06df -#define TPI_INFO_TRANS_EN BIT(7) -#define TPI_INFO_TRANS_RPT BIT(6) -#define TPI_DDC_MASTER_EN 0x06f8 -#define HW_DDC_MASTER BIT(7) -#define N_SVAL1 0xa03 -#define N_SVAL2 0xa04 -#define N_SVAL3 0xa05 -#define AUD_EN 0xa13 -#define AUD_IN_EN BIT(0) -#define AUD_MODE 0xa14 -#define SPDIF_EN BIT(1) -#define TPI_AUD_CONFIG 0xa62 -#define SPDIF_SAMPLE_SIZE_SHIFT 6 -#define SPDIF_SAMPLE_SIZE_MASK (0x3 << SPDIF_SAMPLE_SIZE_SHIFT) -#define SPDIF_SAMPLE_SIZE_16BIT (0x1 << SPDIF_SAMPLE_SIZE_SHIFT) -#define SPDIF_SAMPLE_SIZE_20BIT (0x2 << SPDIF_SAMPLE_SIZE_SHIFT) -#define SPDIF_SAMPLE_SIZE_24BIT (0x3 << SPDIF_SAMPLE_SIZE_SHIFT) -#define TPI_AUD_MUTE BIT(4) - -#endif /* __ZX_HDMI_REGS_H__ */ diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c deleted file mode 100644 index c8f7b21fa09e..000000000000 --- a/drivers/gpu/drm/zte/zx_plane.c +++ /dev/null @@ -1,533 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2016 Linaro Ltd. - * Copyright 2016 ZTE Corporation. - */ - -#include <drm/drm_atomic.h> -#include <drm/drm_atomic_helper.h> -#include <drm/drm_fb_cma_helper.h> -#include <drm/drm_fourcc.h> -#include <drm/drm_gem_cma_helper.h> -#include <drm/drm_modeset_helper_vtables.h> -#include <drm/drm_plane_helper.h> - -#include "zx_common_regs.h" -#include "zx_drm_drv.h" -#include "zx_plane.h" -#include "zx_plane_regs.h" -#include "zx_vou.h" - -static const uint32_t gl_formats[] = { - DRM_FORMAT_ARGB8888, - DRM_FORMAT_XRGB8888, - DRM_FORMAT_RGB888, - DRM_FORMAT_RGB565, - DRM_FORMAT_ARGB1555, - DRM_FORMAT_ARGB4444, -}; - -static const uint32_t vl_formats[] = { - DRM_FORMAT_NV12, /* Semi-planar YUV420 */ - DRM_FORMAT_YUV420, /* Planar YUV420 */ - DRM_FORMAT_YUYV, /* Packed YUV422 */ - DRM_FORMAT_YVYU, - DRM_FORMAT_UYVY, - DRM_FORMAT_VYUY, - DRM_FORMAT_YUV444, /* YUV444 8bit */ - /* - * TODO: add formats below that HW supports: - * - YUV420 P010 - * - YUV420 Hantro - * - YUV444 10bit - */ -}; - -#define FRAC_16_16(mult, div) (((mult) << 16) / (div)) - -static int zx_vl_plane_atomic_check(struct drm_plane *plane, - struct drm_plane_state *plane_state) -{ - struct drm_framebuffer *fb = plane_state->fb; - struct drm_crtc *crtc = plane_state->crtc; - struct drm_crtc_state *crtc_state; - int min_scale = FRAC_16_16(1, 8); - int max_scale = FRAC_16_16(8, 1); - - if (!crtc || WARN_ON(!fb)) - return 0; - - crtc_state = drm_atomic_get_existing_crtc_state(plane_state->state, - crtc); - if (WARN_ON(!crtc_state)) - return -EINVAL; - - /* nothing to check when disabling or disabled */ - if (!crtc_state->enable) - return 0; - - /* plane must be enabled */ - if (!plane_state->crtc) - return -EINVAL; - - return drm_atomic_helper_check_plane_state(plane_state, crtc_state, - min_scale, max_scale, - true, true); -} - -static int zx_vl_get_fmt(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_NV12: - return VL_FMT_YUV420; - case DRM_FORMAT_YUV420: - return VL_YUV420_PLANAR | VL_FMT_YUV420; - case DRM_FORMAT_YUYV: - return VL_YUV422_YUYV | VL_FMT_YUV422; - case DRM_FORMAT_YVYU: - return VL_YUV422_YVYU | VL_FMT_YUV422; - case DRM_FORMAT_UYVY: - return VL_YUV422_UYVY | VL_FMT_YUV422; - case DRM_FORMAT_VYUY: - return VL_YUV422_VYUY | VL_FMT_YUV422; - case DRM_FORMAT_YUV444: - return VL_FMT_YUV444_8BIT; - default: - WARN_ONCE(1, "invalid pixel format %d\n", format); - return -EINVAL; - } -} - -static inline void zx_vl_set_update(struct zx_plane *zplane) -{ - void __iomem *layer = zplane->layer; - - zx_writel_mask(layer + VL_CTRL0, VL_UPDATE, VL_UPDATE); -} - -static inline void zx_vl_rsz_set_update(struct zx_plane *zplane) -{ - zx_writel(zplane->rsz + RSZ_VL_ENABLE_CFG, 1); -} - -static int zx_vl_rsz_get_fmt(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_NV12: - case DRM_FORMAT_YUV420: - return RSZ_VL_FMT_YCBCR420; - case DRM_FORMAT_YUYV: - case DRM_FORMAT_YVYU: - case DRM_FORMAT_UYVY: - case DRM_FORMAT_VYUY: - return RSZ_VL_FMT_YCBCR422; - case DRM_FORMAT_YUV444: - return RSZ_VL_FMT_YCBCR444; - default: - WARN_ONCE(1, "invalid pixel format %d\n", format); - return -EINVAL; - } -} - -static inline u32 rsz_step_value(u32 src, u32 dst) -{ - u32 val = 0; - - if (src == dst) - val = 0; - else if (src < dst) - val = RSZ_PARA_STEP((src << 16) / dst); - else if (src > dst) - val = RSZ_DATA_STEP(src / dst) | - RSZ_PARA_STEP(((src << 16) / dst) & 0xffff); - - return val; -} - -static void zx_vl_rsz_setup(struct zx_plane *zplane, uint32_t format, - u32 src_w, u32 src_h, u32 dst_w, u32 dst_h) -{ - void __iomem *rsz = zplane->rsz; - u32 src_chroma_w = src_w; - u32 src_chroma_h = src_h; - int fmt; - - /* Set up source and destination resolution */ - zx_writel(rsz + RSZ_SRC_CFG, RSZ_VER(src_h - 1) | RSZ_HOR(src_w - 1)); - zx_writel(rsz + RSZ_DEST_CFG, RSZ_VER(dst_h - 1) | RSZ_HOR(dst_w - 1)); - - /* Configure data format for VL RSZ */ - fmt = zx_vl_rsz_get_fmt(format); - if (fmt >= 0) - zx_writel_mask(rsz + RSZ_VL_CTRL_CFG, RSZ_VL_FMT_MASK, fmt); - - /* Calculate Chroma height and width */ - if (fmt == RSZ_VL_FMT_YCBCR420) { - src_chroma_w = src_w >> 1; - src_chroma_h = src_h >> 1; - } else if (fmt == RSZ_VL_FMT_YCBCR422) { - src_chroma_w = src_w >> 1; - } - - /* Set up Luma and Chroma step registers */ - zx_writel(rsz + RSZ_VL_LUMA_HOR, rsz_step_value(src_w, dst_w)); - zx_writel(rsz + RSZ_VL_LUMA_VER, rsz_step_value(src_h, dst_h)); - zx_writel(rsz + RSZ_VL_CHROMA_HOR, rsz_step_value(src_chroma_w, dst_w)); - zx_writel(rsz + RSZ_VL_CHROMA_VER, rsz_step_value(src_chroma_h, dst_h)); - - zx_vl_rsz_set_update(zplane); -} - -static void zx_vl_plane_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct zx_plane *zplane = to_zx_plane(plane); - struct drm_plane_state *state = plane->state; - struct drm_framebuffer *fb = state->fb; - struct drm_rect *src = &state->src; - struct drm_rect *dst = &state->dst; - struct drm_gem_cma_object *cma_obj; - void __iomem *layer = zplane->layer; - void __iomem *hbsc = zplane->hbsc; - void __iomem *paddr_reg; - dma_addr_t paddr; - u32 src_x, src_y, src_w, src_h; - u32 dst_x, dst_y, dst_w, dst_h; - uint32_t format; - int fmt; - int i; - - if (!fb) - return; - - format = fb->format->format; - - src_x = src->x1 >> 16; - src_y = src->y1 >> 16; - src_w = drm_rect_width(src) >> 16; - src_h = drm_rect_height(src) >> 16; - - dst_x = dst->x1; - dst_y = dst->y1; - dst_w = drm_rect_width(dst); - dst_h = drm_rect_height(dst); - - /* Set up data address registers for Y, Cb and Cr planes */ - paddr_reg = layer + VL_Y; - for (i = 0; i < fb->format->num_planes; i++) { - cma_obj = drm_fb_cma_get_gem_obj(fb, i); - paddr = cma_obj->paddr + fb->offsets[i]; - paddr += src_y * fb->pitches[i]; - paddr += src_x * fb->format->cpp[i]; - zx_writel(paddr_reg, paddr); - paddr_reg += 4; - } - - /* Set up source height/width register */ - zx_writel(layer + VL_SRC_SIZE, GL_SRC_W(src_w) | GL_SRC_H(src_h)); - - /* Set up start position register */ - zx_writel(layer + VL_POS_START, GL_POS_X(dst_x) | GL_POS_Y(dst_y)); - - /* Set up end position register */ - zx_writel(layer + VL_POS_END, - GL_POS_X(dst_x + dst_w) | GL_POS_Y(dst_y + dst_h)); - - /* Strides of Cb and Cr planes should be identical */ - zx_writel(layer + VL_STRIDE, LUMA_STRIDE(fb->pitches[0]) | - CHROMA_STRIDE(fb->pitches[1])); - - /* Set up video layer data format */ - fmt = zx_vl_get_fmt(format); - if (fmt >= 0) - zx_writel(layer + VL_CTRL1, fmt); - - /* Always use scaler since it exists (set for not bypass) */ - zx_writel_mask(layer + VL_CTRL2, VL_SCALER_BYPASS_MODE, - VL_SCALER_BYPASS_MODE); - - zx_vl_rsz_setup(zplane, format, src_w, src_h, dst_w, dst_h); - - /* Enable HBSC block */ - zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, HBSC_CTRL_EN); - - zx_vou_layer_enable(plane); - - zx_vl_set_update(zplane); -} - -static void zx_plane_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct zx_plane *zplane = to_zx_plane(plane); - void __iomem *hbsc = zplane->hbsc; - - zx_vou_layer_disable(plane, old_state); - - /* Disable HBSC block */ - zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, 0); -} - -static const struct drm_plane_helper_funcs zx_vl_plane_helper_funcs = { - .atomic_check = zx_vl_plane_atomic_check, - .atomic_update = zx_vl_plane_atomic_update, - .atomic_disable = zx_plane_atomic_disable, -}; - -static int zx_gl_plane_atomic_check(struct drm_plane *plane, - struct drm_plane_state *plane_state) -{ - struct drm_framebuffer *fb = plane_state->fb; - struct drm_crtc *crtc = plane_state->crtc; - struct drm_crtc_state *crtc_state; - - if (!crtc || WARN_ON(!fb)) - return 0; - - crtc_state = drm_atomic_get_existing_crtc_state(plane_state->state, - crtc); - if (WARN_ON(!crtc_state)) - return -EINVAL; - - /* nothing to check when disabling or disabled */ - if (!crtc_state->enable) - return 0; - - /* plane must be enabled */ - if (!plane_state->crtc) - return -EINVAL; - - return drm_atomic_helper_check_plane_state(plane_state, crtc_state, - DRM_PLANE_HELPER_NO_SCALING, - DRM_PLANE_HELPER_NO_SCALING, - false, true); -} - -static int zx_gl_get_fmt(uint32_t format) -{ - switch (format) { - case DRM_FORMAT_ARGB8888: - case DRM_FORMAT_XRGB8888: - return GL_FMT_ARGB8888; - case DRM_FORMAT_RGB888: - return GL_FMT_RGB888; - case DRM_FORMAT_RGB565: - return GL_FMT_RGB565; - case DRM_FORMAT_ARGB1555: - return GL_FMT_ARGB1555; - case DRM_FORMAT_ARGB4444: - return GL_FMT_ARGB4444; - default: - WARN_ONCE(1, "invalid pixel format %d\n", format); - return -EINVAL; - } -} - -static inline void zx_gl_set_update(struct zx_plane *zplane) -{ - void __iomem *layer = zplane->layer; - - zx_writel_mask(layer + GL_CTRL0, GL_UPDATE, GL_UPDATE); -} - -static inline void zx_gl_rsz_set_update(struct zx_plane *zplane) -{ - zx_writel(zplane->rsz + RSZ_ENABLE_CFG, 1); -} - -static void zx_gl_rsz_setup(struct zx_plane *zplane, u32 src_w, u32 src_h, - u32 dst_w, u32 dst_h) -{ - void __iomem *rsz = zplane->rsz; - - zx_writel(rsz + RSZ_SRC_CFG, RSZ_VER(src_h - 1) | RSZ_HOR(src_w - 1)); - zx_writel(rsz + RSZ_DEST_CFG, RSZ_VER(dst_h - 1) | RSZ_HOR(dst_w - 1)); - - zx_gl_rsz_set_update(zplane); -} - -static void zx_gl_plane_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct zx_plane *zplane = to_zx_plane(plane); - struct drm_framebuffer *fb = plane->state->fb; - struct drm_gem_cma_object *cma_obj; - void __iomem *layer = zplane->layer; - void __iomem *csc = zplane->csc; - void __iomem *hbsc = zplane->hbsc; - u32 src_x, src_y, src_w, src_h; - u32 dst_x, dst_y, dst_w, dst_h; - unsigned int bpp; - uint32_t format; - dma_addr_t paddr; - u32 stride; - int fmt; - - if (!fb) - return; - - format = fb->format->format; - stride = fb->pitches[0]; - - src_x = plane->state->src_x >> 16; - src_y = plane->state->src_y >> 16; - src_w = plane->state->src_w >> 16; - src_h = plane->state->src_h >> 16; - - dst_x = plane->state->crtc_x; - dst_y = plane->state->crtc_y; - dst_w = plane->state->crtc_w; - dst_h = plane->state->crtc_h; - - bpp = fb->format->cpp[0]; - - cma_obj = drm_fb_cma_get_gem_obj(fb, 0); - paddr = cma_obj->paddr + fb->offsets[0]; - paddr += src_y * stride + src_x * bpp / 8; - zx_writel(layer + GL_ADDR, paddr); - - /* Set up source height/width register */ - zx_writel(layer + GL_SRC_SIZE, GL_SRC_W(src_w) | GL_SRC_H(src_h)); - - /* Set up start position register */ - zx_writel(layer + GL_POS_START, GL_POS_X(dst_x) | GL_POS_Y(dst_y)); - - /* Set up end position register */ - zx_writel(layer + GL_POS_END, - GL_POS_X(dst_x + dst_w) | GL_POS_Y(dst_y + dst_h)); - - /* Set up stride register */ - zx_writel(layer + GL_STRIDE, stride & 0xffff); - - /* Set up graphic layer data format */ - fmt = zx_gl_get_fmt(format); - if (fmt >= 0) - zx_writel_mask(layer + GL_CTRL1, GL_DATA_FMT_MASK, - fmt << GL_DATA_FMT_SHIFT); - - /* Initialize global alpha with a sane value */ - zx_writel_mask(layer + GL_CTRL2, GL_GLOBAL_ALPHA_MASK, - 0xff << GL_GLOBAL_ALPHA_SHIFT); - - /* Setup CSC for the GL */ - if (dst_h > 720) - zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK, - CSC_BT709_IMAGE_RGB2YCBCR << CSC_COV_MODE_SHIFT); - else - zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK, - CSC_BT601_IMAGE_RGB2YCBCR << CSC_COV_MODE_SHIFT); - zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, CSC_WORK_ENABLE); - - /* Always use scaler since it exists (set for not bypass) */ - zx_writel_mask(layer + GL_CTRL3, GL_SCALER_BYPASS_MODE, - GL_SCALER_BYPASS_MODE); - - zx_gl_rsz_setup(zplane, src_w, src_h, dst_w, dst_h); - - /* Enable HBSC block */ - zx_writel_mask(hbsc + HBSC_CTRL0, HBSC_CTRL_EN, HBSC_CTRL_EN); - - zx_vou_layer_enable(plane); - - zx_gl_set_update(zplane); -} - -static const struct drm_plane_helper_funcs zx_gl_plane_helper_funcs = { - .atomic_check = zx_gl_plane_atomic_check, - .atomic_update = zx_gl_plane_atomic_update, - .atomic_disable = zx_plane_atomic_disable, -}; - -static void zx_plane_destroy(struct drm_plane *plane) -{ - drm_plane_cleanup(plane); -} - -static const struct drm_plane_funcs zx_plane_funcs = { - .update_plane = drm_atomic_helper_update_plane, - .disable_plane = drm_atomic_helper_disable_plane, - .destroy = zx_plane_destroy, - .reset = drm_atomic_helper_plane_reset, - .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_plane_destroy_state, -}; - -void zx_plane_set_update(struct drm_plane *plane) -{ - struct zx_plane *zplane = to_zx_plane(plane); - - /* Do nothing if the plane is not enabled */ - if (!plane->state->crtc) - return; - - switch (plane->type) { - case DRM_PLANE_TYPE_PRIMARY: - zx_gl_rsz_set_update(zplane); - zx_gl_set_update(zplane); - break; - case DRM_PLANE_TYPE_OVERLAY: - zx_vl_rsz_set_update(zplane); - zx_vl_set_update(zplane); - break; - default: - WARN_ONCE(1, "unsupported plane type %d\n", plane->type); - } -} - -static void zx_plane_hbsc_init(struct zx_plane *zplane) -{ - void __iomem *hbsc = zplane->hbsc; - - /* - * Initialize HBSC block with a sane configuration per recommedation - * from ZTE BSP code. - */ - zx_writel(hbsc + HBSC_SATURATION, 0x200); - zx_writel(hbsc + HBSC_HUE, 0x0); - zx_writel(hbsc + HBSC_BRIGHT, 0x0); - zx_writel(hbsc + HBSC_CONTRAST, 0x200); - - zx_writel(hbsc + HBSC_THRESHOLD_COL1, (0x3ac << 16) | 0x40); - zx_writel(hbsc + HBSC_THRESHOLD_COL2, (0x3c0 << 16) | 0x40); - zx_writel(hbsc + HBSC_THRESHOLD_COL3, (0x3c0 << 16) | 0x40); -} - -int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane, - enum drm_plane_type type) -{ - const struct drm_plane_helper_funcs *helper; - struct drm_plane *plane = &zplane->plane; - struct device *dev = zplane->dev; - const uint32_t *formats; - unsigned int format_count; - int ret; - - zx_plane_hbsc_init(zplane); - - switch (type) { - case DRM_PLANE_TYPE_PRIMARY: - helper = &zx_gl_plane_helper_funcs; - formats = gl_formats; - format_count = ARRAY_SIZE(gl_formats); - break; - case DRM_PLANE_TYPE_OVERLAY: - helper = &zx_vl_plane_helper_funcs; - formats = vl_formats; - format_count = ARRAY_SIZE(vl_formats); - break; - default: - return -ENODEV; - } - - ret = drm_universal_plane_init(drm, plane, VOU_CRTC_MASK, - &zx_plane_funcs, formats, format_count, - NULL, type, NULL); - if (ret) { - DRM_DEV_ERROR(dev, "failed to init universal plane: %d\n", ret); - return ret; - } - - drm_plane_helper_add(plane, helper); - - return 0; -} diff --git a/drivers/gpu/drm/zte/zx_plane.h b/drivers/gpu/drm/zte/zx_plane.h deleted file mode 100644 index 5a7cc8b3b985..000000000000 --- a/drivers/gpu/drm/zte/zx_plane.h +++ /dev/null @@ -1,26 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2016 Linaro Ltd. - * Copyright 2016 ZTE Corporation. - */ - -#ifndef __ZX_PLANE_H__ -#define __ZX_PLANE_H__ - -struct zx_plane { - struct drm_plane plane; - struct device *dev; - void __iomem *layer; - void __iomem *csc; - void __iomem *hbsc; - void __iomem *rsz; - const struct vou_layer_bits *bits; -}; - -#define to_zx_plane(plane) container_of(plane, struct zx_plane, plane) - -int zx_plane_init(struct drm_device *drm, struct zx_plane *zplane, - enum drm_plane_type type); -void zx_plane_set_update(struct drm_plane *plane); - -#endif /* __ZX_PLANE_H__ */ diff --git a/drivers/gpu/drm/zte/zx_plane_regs.h b/drivers/gpu/drm/zte/zx_plane_regs.h deleted file mode 100644 index ce830637a92d..000000000000 --- a/drivers/gpu/drm/zte/zx_plane_regs.h +++ /dev/null @@ -1,120 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2016 Linaro Ltd. - * Copyright 2016 ZTE Corporation. - */ - -#ifndef __ZX_PLANE_REGS_H__ -#define __ZX_PLANE_REGS_H__ - -/* GL registers */ -#define GL_CTRL0 0x00 -#define GL_UPDATE BIT(5) -#define GL_CTRL1 0x04 -#define GL_DATA_FMT_SHIFT 0 -#define GL_DATA_FMT_MASK (0xf << GL_DATA_FMT_SHIFT) -#define GL_FMT_ARGB8888 0 -#define GL_FMT_RGB888 1 -#define GL_FMT_RGB565 2 -#define GL_FMT_ARGB1555 3 -#define GL_FMT_ARGB4444 4 -#define GL_CTRL2 0x08 -#define GL_GLOBAL_ALPHA_SHIFT 8 -#define GL_GLOBAL_ALPHA_MASK (0xff << GL_GLOBAL_ALPHA_SHIFT) -#define GL_CTRL3 0x0c -#define GL_SCALER_BYPASS_MODE BIT(0) -#define GL_STRIDE 0x18 -#define GL_ADDR 0x1c -#define GL_SRC_SIZE 0x38 -#define GL_SRC_W_SHIFT 16 -#define GL_SRC_W_MASK (0x3fff << GL_SRC_W_SHIFT) -#define GL_SRC_H_SHIFT 0 -#define GL_SRC_H_MASK (0x3fff << GL_SRC_H_SHIFT) -#define GL_POS_START 0x9c -#define GL_POS_END 0xa0 -#define GL_POS_X_SHIFT 16 -#define GL_POS_X_MASK (0x1fff << GL_POS_X_SHIFT) -#define GL_POS_Y_SHIFT 0 -#define GL_POS_Y_MASK (0x1fff << GL_POS_Y_SHIFT) - -#define GL_SRC_W(x) (((x) << GL_SRC_W_SHIFT) & GL_SRC_W_MASK) -#define GL_SRC_H(x) (((x) << GL_SRC_H_SHIFT) & GL_SRC_H_MASK) -#define GL_POS_X(x) (((x) << GL_POS_X_SHIFT) & GL_POS_X_MASK) -#define GL_POS_Y(x) (((x) << GL_POS_Y_SHIFT) & GL_POS_Y_MASK) - -/* VL registers */ -#define VL_CTRL0 0x00 -#define VL_UPDATE BIT(3) -#define VL_CTRL1 0x04 -#define VL_YUV420_PLANAR BIT(5) -#define VL_YUV422_SHIFT 3 -#define VL_YUV422_YUYV (0 << VL_YUV422_SHIFT) -#define VL_YUV422_YVYU (1 << VL_YUV422_SHIFT) -#define VL_YUV422_UYVY (2 << VL_YUV422_SHIFT) -#define VL_YUV422_VYUY (3 << VL_YUV422_SHIFT) -#define VL_FMT_YUV420 0 -#define VL_FMT_YUV422 1 -#define VL_FMT_YUV420_P010 2 -#define VL_FMT_YUV420_HANTRO 3 -#define VL_FMT_YUV444_8BIT 4 -#define VL_FMT_YUV444_10BIT 5 -#define VL_CTRL2 0x08 -#define VL_SCALER_BYPASS_MODE BIT(0) -#define VL_STRIDE 0x0c -#define LUMA_STRIDE_SHIFT 16 -#define LUMA_STRIDE_MASK (0xffff << LUMA_STRIDE_SHIFT) -#define CHROMA_STRIDE_SHIFT 0 -#define CHROMA_STRIDE_MASK (0xffff << CHROMA_STRIDE_SHIFT) -#define VL_SRC_SIZE 0x10 -#define VL_Y 0x14 -#define VL_POS_START 0x30 -#define VL_POS_END 0x34 - -#define LUMA_STRIDE(x) (((x) << LUMA_STRIDE_SHIFT) & LUMA_STRIDE_MASK) -#define CHROMA_STRIDE(x) (((x) << CHROMA_STRIDE_SHIFT) & CHROMA_STRIDE_MASK) - -/* RSZ registers */ -#define RSZ_SRC_CFG 0x00 -#define RSZ_DEST_CFG 0x04 -#define RSZ_ENABLE_CFG 0x14 - -#define RSZ_VL_LUMA_HOR 0x08 -#define RSZ_VL_LUMA_VER 0x0c -#define RSZ_VL_CHROMA_HOR 0x10 -#define RSZ_VL_CHROMA_VER 0x14 -#define RSZ_VL_CTRL_CFG 0x18 -#define RSZ_VL_FMT_SHIFT 3 -#define RSZ_VL_FMT_MASK (0x3 << RSZ_VL_FMT_SHIFT) -#define RSZ_VL_FMT_YCBCR420 (0x0 << RSZ_VL_FMT_SHIFT) -#define RSZ_VL_FMT_YCBCR422 (0x1 << RSZ_VL_FMT_SHIFT) -#define RSZ_VL_FMT_YCBCR444 (0x2 << RSZ_VL_FMT_SHIFT) -#define RSZ_VL_ENABLE_CFG 0x1c - -#define RSZ_VER_SHIFT 16 -#define RSZ_VER_MASK (0xffff << RSZ_VER_SHIFT) -#define RSZ_HOR_SHIFT 0 -#define RSZ_HOR_MASK (0xffff << RSZ_HOR_SHIFT) - -#define RSZ_VER(x) (((x) << RSZ_VER_SHIFT) & RSZ_VER_MASK) -#define RSZ_HOR(x) (((x) << RSZ_HOR_SHIFT) & RSZ_HOR_MASK) - -#define RSZ_DATA_STEP_SHIFT 16 -#define RSZ_DATA_STEP_MASK (0xffff << RSZ_DATA_STEP_SHIFT) -#define RSZ_PARA_STEP_SHIFT 0 -#define RSZ_PARA_STEP_MASK (0xffff << RSZ_PARA_STEP_SHIFT) - -#define RSZ_DATA_STEP(x) (((x) << RSZ_DATA_STEP_SHIFT) & RSZ_DATA_STEP_MASK) -#define RSZ_PARA_STEP(x) (((x) << RSZ_PARA_STEP_SHIFT) & RSZ_PARA_STEP_MASK) - -/* HBSC registers */ -#define HBSC_SATURATION 0x00 -#define HBSC_HUE 0x04 -#define HBSC_BRIGHT 0x08 -#define HBSC_CONTRAST 0x0c -#define HBSC_THRESHOLD_COL1 0x10 -#define HBSC_THRESHOLD_COL2 0x14 -#define HBSC_THRESHOLD_COL3 0x18 -#define HBSC_CTRL0 0x28 -#define HBSC_CTRL_EN BIT(2) - -#endif /* __ZX_PLANE_REGS_H__ */ diff --git a/drivers/gpu/drm/zte/zx_tvenc.c b/drivers/gpu/drm/zte/zx_tvenc.c deleted file mode 100644 index d8a89ba383bc..000000000000 --- a/drivers/gpu/drm/zte/zx_tvenc.c +++ /dev/null @@ -1,400 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2017 Linaro Ltd. - * Copyright 2017 ZTE Corporation. - */ - -#include <linux/clk.h> -#include <linux/component.h> -#include <linux/mfd/syscon.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/regmap.h> - -#include <drm/drm_atomic_helper.h> -#include <drm/drm_print.h> -#include <drm/drm_probe_helper.h> -#include <drm/drm_simple_kms_helper.h> - -#include "zx_drm_drv.h" -#include "zx_tvenc_regs.h" -#include "zx_vou.h" - -struct zx_tvenc_pwrctrl { - struct regmap *regmap; - u32 reg; - u32 mask; -}; - -struct zx_tvenc { - struct drm_connector connector; - struct drm_encoder encoder; - struct device *dev; - void __iomem *mmio; - const struct vou_inf *inf; - struct zx_tvenc_pwrctrl pwrctrl; -}; - -#define to_zx_tvenc(x) container_of(x, struct zx_tvenc, x) - -struct zx_tvenc_mode { - struct drm_display_mode mode; - u32 video_info; - u32 video_res; - u32 field1_param; - u32 field2_param; - u32 burst_line_odd1; - u32 burst_line_even1; - u32 burst_line_odd2; - u32 burst_line_even2; - u32 line_timing_param; - u32 weight_value; - u32 blank_black_level; - u32 burst_level; - u32 control_param; - u32 sub_carrier_phase1; - u32 phase_line_incr_cvbs; -}; - -/* - * The CRM cannot directly provide a suitable frequency, and we have to - * ask a multiplied rate from CRM and use the divider in VOU to get the - * desired one. - */ -#define TVENC_CLOCK_MULTIPLIER 4 - -static const struct zx_tvenc_mode tvenc_mode_pal = { - .mode = { - .clock = 13500 * TVENC_CLOCK_MULTIPLIER, - .hdisplay = 720, - .hsync_start = 720 + 12, - .hsync_end = 720 + 12 + 2, - .htotal = 720 + 12 + 2 + 130, - .vdisplay = 576, - .vsync_start = 576 + 2, - .vsync_end = 576 + 2 + 2, - .vtotal = 576 + 2 + 2 + 20, - .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE, - }, - .video_info = 0x00040040, - .video_res = 0x05a9c760, - .field1_param = 0x0004d416, - .field2_param = 0x0009b94f, - .burst_line_odd1 = 0x0004d406, - .burst_line_even1 = 0x0009b53e, - .burst_line_odd2 = 0x0004d805, - .burst_line_even2 = 0x0009b93f, - .line_timing_param = 0x06a96fdf, - .weight_value = 0x00c188a0, - .blank_black_level = 0x0000fcfc, - .burst_level = 0x00001595, - .control_param = 0x00000001, - .sub_carrier_phase1 = 0x1504c566, - .phase_line_incr_cvbs = 0xc068db8c, -}; - -static const struct zx_tvenc_mode tvenc_mode_ntsc = { - .mode = { - .clock = 13500 * TVENC_CLOCK_MULTIPLIER, - .hdisplay = 720, - .hsync_start = 720 + 16, - .hsync_end = 720 + 16 + 2, - .htotal = 720 + 16 + 2 + 120, - .vdisplay = 480, - .vsync_start = 480 + 3, - .vsync_end = 480 + 3 + 2, - .vtotal = 480 + 3 + 2 + 17, - .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | - DRM_MODE_FLAG_INTERLACE, - }, - .video_info = 0x00040080, - .video_res = 0x05a8375a, - .field1_param = 0x00041817, - .field2_param = 0x0008351e, - .burst_line_odd1 = 0x00041006, - .burst_line_even1 = 0x0008290d, - .burst_line_odd2 = 0x00000000, - .burst_line_even2 = 0x00000000, - .line_timing_param = 0x06a8ef9e, - .weight_value = 0x00b68197, - .blank_black_level = 0x0000f0f0, - .burst_level = 0x0000009c, - .control_param = 0x00000001, - .sub_carrier_phase1 = 0x10f83e10, - .phase_line_incr_cvbs = 0x80000000, -}; - -static const struct zx_tvenc_mode *tvenc_modes[] = { - &tvenc_mode_pal, - &tvenc_mode_ntsc, -}; - -static const struct zx_tvenc_mode * -zx_tvenc_find_zmode(struct drm_display_mode *mode) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(tvenc_modes); i++) { - const struct zx_tvenc_mode *zmode = tvenc_modes[i]; - - if (drm_mode_equal(mode, &zmode->mode)) - return zmode; - } - - return NULL; -} - -static void zx_tvenc_encoder_mode_set(struct drm_encoder *encoder, - struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) -{ - struct zx_tvenc *tvenc = to_zx_tvenc(encoder); - const struct zx_tvenc_mode *zmode; - struct vou_div_config configs[] = { - { VOU_DIV_INF, VOU_DIV_4 }, - { VOU_DIV_TVENC, VOU_DIV_1 }, - { VOU_DIV_LAYER, VOU_DIV_2 }, - }; - - zx_vou_config_dividers(encoder->crtc, configs, ARRAY_SIZE(configs)); - - zmode = zx_tvenc_find_zmode(mode); - if (!zmode) { - DRM_DEV_ERROR(tvenc->dev, "failed to find zmode\n"); - return; - } - - zx_writel(tvenc->mmio + VENC_VIDEO_INFO, zmode->video_info); - zx_writel(tvenc->mmio + VENC_VIDEO_RES, zmode->video_res); - zx_writel(tvenc->mmio + VENC_FIELD1_PARAM, zmode->field1_param); - zx_writel(tvenc->mmio + VENC_FIELD2_PARAM, zmode->field2_param); - zx_writel(tvenc->mmio + VENC_LINE_O_1, zmode->burst_line_odd1); - zx_writel(tvenc->mmio + VENC_LINE_E_1, zmode->burst_line_even1); - zx_writel(tvenc->mmio + VENC_LINE_O_2, zmode->burst_line_odd2); - zx_writel(tvenc->mmio + VENC_LINE_E_2, zmode->burst_line_even2); - zx_writel(tvenc->mmio + VENC_LINE_TIMING_PARAM, - zmode->line_timing_param); - zx_writel(tvenc->mmio + VENC_WEIGHT_VALUE, zmode->weight_value); - zx_writel(tvenc->mmio + VENC_BLANK_BLACK_LEVEL, - zmode->blank_black_level); - zx_writel(tvenc->mmio + VENC_BURST_LEVEL, zmode->burst_level); - zx_writel(tvenc->mmio + VENC_CONTROL_PARAM, zmode->control_param); - zx_writel(tvenc->mmio + VENC_SUB_CARRIER_PHASE1, - zmode->sub_carrier_phase1); - zx_writel(tvenc->mmio + VENC_PHASE_LINE_INCR_CVBS, - zmode->phase_line_incr_cvbs); -} - -static void zx_tvenc_encoder_enable(struct drm_encoder *encoder) -{ - struct zx_tvenc *tvenc = to_zx_tvenc(encoder); - struct zx_tvenc_pwrctrl *pwrctrl = &tvenc->pwrctrl; - - /* Set bit to power up TVENC DAC */ - regmap_update_bits(pwrctrl->regmap, pwrctrl->reg, pwrctrl->mask, - pwrctrl->mask); - - vou_inf_enable(VOU_TV_ENC, encoder->crtc); - - zx_writel(tvenc->mmio + VENC_ENABLE, 1); -} - -static void zx_tvenc_encoder_disable(struct drm_encoder *encoder) -{ - struct zx_tvenc *tvenc = to_zx_tvenc(encoder); - struct zx_tvenc_pwrctrl *pwrctrl = &tvenc->pwrctrl; - - zx_writel(tvenc->mmio + VENC_ENABLE, 0); - - vou_inf_disable(VOU_TV_ENC, encoder->crtc); - - /* Clear bit to power down TVENC DAC */ - regmap_update_bits(pwrctrl->regmap, pwrctrl->reg, pwrctrl->mask, 0); -} - -static const struct drm_encoder_helper_funcs zx_tvenc_encoder_helper_funcs = { - .enable = zx_tvenc_encoder_enable, - .disable = zx_tvenc_encoder_disable, - .mode_set = zx_tvenc_encoder_mode_set, -}; - -static int zx_tvenc_connector_get_modes(struct drm_connector *connector) -{ - struct zx_tvenc *tvenc = to_zx_tvenc(connector); - struct device *dev = tvenc->dev; - int i; - - for (i = 0; i < ARRAY_SIZE(tvenc_modes); i++) { - const struct zx_tvenc_mode *zmode = tvenc_modes[i]; - struct drm_display_mode *mode; - - mode = drm_mode_duplicate(connector->dev, &zmode->mode); - if (!mode) { - DRM_DEV_ERROR(dev, "failed to duplicate drm mode\n"); - continue; - } - - drm_mode_set_name(mode); - drm_mode_probed_add(connector, mode); - } - - return i; -} - -static enum drm_mode_status -zx_tvenc_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - struct zx_tvenc *tvenc = to_zx_tvenc(connector); - const struct zx_tvenc_mode *zmode; - - zmode = zx_tvenc_find_zmode(mode); - if (!zmode) { - DRM_DEV_ERROR(tvenc->dev, "unsupported mode: %s\n", mode->name); - return MODE_NOMODE; - } - - return MODE_OK; -} - -static struct drm_connector_helper_funcs zx_tvenc_connector_helper_funcs = { - .get_modes = zx_tvenc_connector_get_modes, - .mode_valid = zx_tvenc_connector_mode_valid, -}; - -static const struct drm_connector_funcs zx_tvenc_connector_funcs = { - .fill_modes = drm_helper_probe_single_connector_modes, - .destroy = drm_connector_cleanup, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static int zx_tvenc_register(struct drm_device *drm, struct zx_tvenc *tvenc) -{ - struct drm_encoder *encoder = &tvenc->encoder; - struct drm_connector *connector = &tvenc->connector; - - /* - * The tvenc is designed to use aux channel, as there is a deflicker - * block for the channel. - */ - encoder->possible_crtcs = BIT(1); - - drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TVDAC); - drm_encoder_helper_add(encoder, &zx_tvenc_encoder_helper_funcs); - - connector->interlace_allowed = true; - - drm_connector_init(drm, connector, &zx_tvenc_connector_funcs, - DRM_MODE_CONNECTOR_Composite); - drm_connector_helper_add(connector, &zx_tvenc_connector_helper_funcs); - - drm_connector_attach_encoder(connector, encoder); - - return 0; -} - -static int zx_tvenc_pwrctrl_init(struct zx_tvenc *tvenc) -{ - struct zx_tvenc_pwrctrl *pwrctrl = &tvenc->pwrctrl; - struct device *dev = tvenc->dev; - struct of_phandle_args out_args; - struct regmap *regmap; - int ret; - - ret = of_parse_phandle_with_fixed_args(dev->of_node, - "zte,tvenc-power-control", 2, 0, &out_args); - if (ret) - return ret; - - regmap = syscon_node_to_regmap(out_args.np); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); - goto out; - } - - pwrctrl->regmap = regmap; - pwrctrl->reg = out_args.args[0]; - pwrctrl->mask = out_args.args[1]; - -out: - of_node_put(out_args.np); - return ret; -} - -static int zx_tvenc_bind(struct device *dev, struct device *master, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - struct drm_device *drm = data; - struct resource *res; - struct zx_tvenc *tvenc; - int ret; - - tvenc = devm_kzalloc(dev, sizeof(*tvenc), GFP_KERNEL); - if (!tvenc) - return -ENOMEM; - - tvenc->dev = dev; - dev_set_drvdata(dev, tvenc); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - tvenc->mmio = devm_ioremap_resource(dev, res); - if (IS_ERR(tvenc->mmio)) { - ret = PTR_ERR(tvenc->mmio); - DRM_DEV_ERROR(dev, "failed to remap tvenc region: %d\n", ret); - return ret; - } - - ret = zx_tvenc_pwrctrl_init(tvenc); - if (ret) { - DRM_DEV_ERROR(dev, "failed to init power control: %d\n", ret); - return ret; - } - - ret = zx_tvenc_register(drm, tvenc); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register tvenc: %d\n", ret); - return ret; - } - - return 0; -} - -static void zx_tvenc_unbind(struct device *dev, struct device *master, - void *data) -{ - /* Nothing to do */ -} - -static const struct component_ops zx_tvenc_component_ops = { - .bind = zx_tvenc_bind, - .unbind = zx_tvenc_unbind, -}; - -static int zx_tvenc_probe(struct platform_device *pdev) -{ - return component_add(&pdev->dev, &zx_tvenc_component_ops); -} - -static int zx_tvenc_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &zx_tvenc_component_ops); - return 0; -} - -static const struct of_device_id zx_tvenc_of_match[] = { - { .compatible = "zte,zx296718-tvenc", }, - { /* end */ }, -}; -MODULE_DEVICE_TABLE(of, zx_tvenc_of_match); - -struct platform_driver zx_tvenc_driver = { - .probe = zx_tvenc_probe, - .remove = zx_tvenc_remove, - .driver = { - .name = "zx-tvenc", - .of_match_table = zx_tvenc_of_match, - }, -}; diff --git a/drivers/gpu/drm/zte/zx_tvenc_regs.h b/drivers/gpu/drm/zte/zx_tvenc_regs.h deleted file mode 100644 index 40f033109374..000000000000 --- a/drivers/gpu/drm/zte/zx_tvenc_regs.h +++ /dev/null @@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2017 Linaro Ltd. - * Copyright 2017 ZTE Corporation. - */ - -#ifndef __ZX_TVENC_REGS_H__ -#define __ZX_TVENC_REGS_H__ - -#define VENC_VIDEO_INFO 0x04 -#define VENC_VIDEO_RES 0x08 -#define VENC_FIELD1_PARAM 0x10 -#define VENC_FIELD2_PARAM 0x14 -#define VENC_LINE_O_1 0x18 -#define VENC_LINE_E_1 0x1c -#define VENC_LINE_O_2 0x20 -#define VENC_LINE_E_2 0x24 -#define VENC_LINE_TIMING_PARAM 0x28 -#define VENC_WEIGHT_VALUE 0x2c -#define VENC_BLANK_BLACK_LEVEL 0x30 -#define VENC_BURST_LEVEL 0x34 -#define VENC_CONTROL_PARAM 0x3c -#define VENC_SUB_CARRIER_PHASE1 0x40 -#define VENC_PHASE_LINE_INCR_CVBS 0x48 -#define VENC_ENABLE 0xa8 - -#endif /* __ZX_TVENC_REGS_H__ */ diff --git a/drivers/gpu/drm/zte/zx_vga.c b/drivers/gpu/drm/zte/zx_vga.c deleted file mode 100644 index 0f9bbb7e3b8d..000000000000 --- a/drivers/gpu/drm/zte/zx_vga.c +++ /dev/null @@ -1,527 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - */ - -#include <linux/clk.h> -#include <linux/component.h> -#include <linux/mfd/syscon.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/regmap.h> - -#include <drm/drm_atomic_helper.h> -#include <drm/drm_print.h> -#include <drm/drm_probe_helper.h> -#include <drm/drm_simple_kms_helper.h> - -#include "zx_drm_drv.h" -#include "zx_vga_regs.h" -#include "zx_vou.h" - -struct zx_vga_pwrctrl { - struct regmap *regmap; - u32 reg; - u32 mask; -}; - -struct zx_vga_i2c { - struct i2c_adapter adap; - struct mutex lock; -}; - -struct zx_vga { - struct drm_connector connector; - struct drm_encoder encoder; - struct zx_vga_i2c *ddc; - struct device *dev; - void __iomem *mmio; - struct clk *i2c_wclk; - struct zx_vga_pwrctrl pwrctrl; - struct completion complete; - bool connected; -}; - -#define to_zx_vga(x) container_of(x, struct zx_vga, x) - -static void zx_vga_encoder_enable(struct drm_encoder *encoder) -{ - struct zx_vga *vga = to_zx_vga(encoder); - struct zx_vga_pwrctrl *pwrctrl = &vga->pwrctrl; - - /* Set bit to power up VGA DACs */ - regmap_update_bits(pwrctrl->regmap, pwrctrl->reg, pwrctrl->mask, - pwrctrl->mask); - - vou_inf_enable(VOU_VGA, encoder->crtc); -} - -static void zx_vga_encoder_disable(struct drm_encoder *encoder) -{ - struct zx_vga *vga = to_zx_vga(encoder); - struct zx_vga_pwrctrl *pwrctrl = &vga->pwrctrl; - - vou_inf_disable(VOU_VGA, encoder->crtc); - - /* Clear bit to power down VGA DACs */ - regmap_update_bits(pwrctrl->regmap, pwrctrl->reg, pwrctrl->mask, 0); -} - -static const struct drm_encoder_helper_funcs zx_vga_encoder_helper_funcs = { - .enable = zx_vga_encoder_enable, - .disable = zx_vga_encoder_disable, -}; - -static int zx_vga_connector_get_modes(struct drm_connector *connector) -{ - struct zx_vga *vga = to_zx_vga(connector); - struct edid *edid; - int ret; - - /* - * Clear both detection bits to switch I2C bus from device - * detecting to EDID reading. - */ - zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, 0); - - edid = drm_get_edid(connector, &vga->ddc->adap); - if (!edid) { - /* - * If EDID reading fails, we set the device state into - * disconnected. Locking is not required here, since the - * VGA_AUTO_DETECT_SEL register write in irq handler cannot - * be triggered when both detection bits are cleared as above. - */ - zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, - VGA_DETECT_SEL_NO_DEVICE); - vga->connected = false; - return 0; - } - - /* - * As edid reading succeeds, device must be connected, so we set - * up detection bit for unplug interrupt here. - */ - zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, VGA_DETECT_SEL_HAS_DEVICE); - - drm_connector_update_edid_property(connector, edid); - ret = drm_add_edid_modes(connector, edid); - kfree(edid); - - return ret; -} - -static enum drm_mode_status -zx_vga_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - return MODE_OK; -} - -static struct drm_connector_helper_funcs zx_vga_connector_helper_funcs = { - .get_modes = zx_vga_connector_get_modes, - .mode_valid = zx_vga_connector_mode_valid, -}; - -static enum drm_connector_status -zx_vga_connector_detect(struct drm_connector *connector, bool force) -{ - struct zx_vga *vga = to_zx_vga(connector); - - return vga->connected ? connector_status_connected : - connector_status_disconnected; -} - -static const struct drm_connector_funcs zx_vga_connector_funcs = { - .fill_modes = drm_helper_probe_single_connector_modes, - .detect = zx_vga_connector_detect, - .destroy = drm_connector_cleanup, - .reset = drm_atomic_helper_connector_reset, - .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, -}; - -static int zx_vga_register(struct drm_device *drm, struct zx_vga *vga) -{ - struct drm_encoder *encoder = &vga->encoder; - struct drm_connector *connector = &vga->connector; - struct device *dev = vga->dev; - int ret; - - encoder->possible_crtcs = VOU_CRTC_MASK; - - ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_DAC); - if (ret) { - DRM_DEV_ERROR(dev, "failed to init encoder: %d\n", ret); - return ret; - } - - drm_encoder_helper_add(encoder, &zx_vga_encoder_helper_funcs); - - vga->connector.polled = DRM_CONNECTOR_POLL_HPD; - - ret = drm_connector_init_with_ddc(drm, connector, - &zx_vga_connector_funcs, - DRM_MODE_CONNECTOR_VGA, - &vga->ddc->adap); - if (ret) { - DRM_DEV_ERROR(dev, "failed to init connector: %d\n", ret); - goto clean_encoder; - } - - drm_connector_helper_add(connector, &zx_vga_connector_helper_funcs); - - ret = drm_connector_attach_encoder(connector, encoder); - if (ret) { - DRM_DEV_ERROR(dev, "failed to attach encoder: %d\n", ret); - goto clean_connector; - } - - return 0; - -clean_connector: - drm_connector_cleanup(connector); -clean_encoder: - drm_encoder_cleanup(encoder); - return ret; -} - -static int zx_vga_pwrctrl_init(struct zx_vga *vga) -{ - struct zx_vga_pwrctrl *pwrctrl = &vga->pwrctrl; - struct device *dev = vga->dev; - struct of_phandle_args out_args; - struct regmap *regmap; - int ret; - - ret = of_parse_phandle_with_fixed_args(dev->of_node, - "zte,vga-power-control", 2, 0, &out_args); - if (ret) - return ret; - - regmap = syscon_node_to_regmap(out_args.np); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); - goto out; - } - - pwrctrl->regmap = regmap; - pwrctrl->reg = out_args.args[0]; - pwrctrl->mask = out_args.args[1]; - -out: - of_node_put(out_args.np); - return ret; -} - -static int zx_vga_i2c_read(struct zx_vga *vga, struct i2c_msg *msg) -{ - int len = msg->len; - u8 *buf = msg->buf; - u32 offset = 0; - int i; - - reinit_completion(&vga->complete); - - /* Select combo write */ - zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_COMBO, VGA_CMD_COMBO); - zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_RW, 0); - - while (len > 0) { - u32 cnt; - - /* Clear RX FIFO */ - zx_writel_mask(vga->mmio + VGA_RXF_CTRL, VGA_RX_FIFO_CLEAR, - VGA_RX_FIFO_CLEAR); - - /* Data offset to read from */ - zx_writel(vga->mmio + VGA_SUB_ADDR, offset); - - /* Kick off the transfer */ - zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_TRANS, - VGA_CMD_TRANS); - - if (!wait_for_completion_timeout(&vga->complete, - msecs_to_jiffies(1000))) { - DRM_DEV_ERROR(vga->dev, "transfer timeout\n"); - return -ETIMEDOUT; - } - - cnt = zx_readl(vga->mmio + VGA_RXF_STATUS); - cnt = (cnt & VGA_RXF_COUNT_MASK) >> VGA_RXF_COUNT_SHIFT; - /* FIFO status may report more data than we need to read */ - cnt = min_t(u32, len, cnt); - - for (i = 0; i < cnt; i++) - *buf++ = zx_readl(vga->mmio + VGA_DATA); - - len -= cnt; - offset += cnt; - } - - return 0; -} - -static int zx_vga_i2c_write(struct zx_vga *vga, struct i2c_msg *msg) -{ - /* - * The DDC I2C adapter is only for reading EDID data, so we assume - * that the write to this adapter must be the EDID data offset. - */ - if ((msg->len != 1) || ((msg->addr != DDC_ADDR))) - return -EINVAL; - - /* Hardware will take care of the slave address shifting */ - zx_writel(vga->mmio + VGA_DEVICE_ADDR, msg->addr); - - return 0; -} - -static int zx_vga_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, - int num) -{ - struct zx_vga *vga = i2c_get_adapdata(adap); - struct zx_vga_i2c *ddc = vga->ddc; - int ret = 0; - int i; - - mutex_lock(&ddc->lock); - - for (i = 0; i < num; i++) { - if (msgs[i].flags & I2C_M_RD) - ret = zx_vga_i2c_read(vga, &msgs[i]); - else - ret = zx_vga_i2c_write(vga, &msgs[i]); - - if (ret < 0) - break; - } - - if (!ret) - ret = num; - - mutex_unlock(&ddc->lock); - - return ret; -} - -static u32 zx_vga_i2c_func(struct i2c_adapter *adapter) -{ - return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; -} - -static const struct i2c_algorithm zx_vga_algorithm = { - .master_xfer = zx_vga_i2c_xfer, - .functionality = zx_vga_i2c_func, -}; - -static int zx_vga_ddc_register(struct zx_vga *vga) -{ - struct device *dev = vga->dev; - struct i2c_adapter *adap; - struct zx_vga_i2c *ddc; - int ret; - - ddc = devm_kzalloc(dev, sizeof(*ddc), GFP_KERNEL); - if (!ddc) - return -ENOMEM; - - vga->ddc = ddc; - mutex_init(&ddc->lock); - - adap = &ddc->adap; - adap->owner = THIS_MODULE; - adap->class = I2C_CLASS_DDC; - adap->dev.parent = dev; - adap->algo = &zx_vga_algorithm; - snprintf(adap->name, sizeof(adap->name), "zx vga i2c"); - - ret = i2c_add_adapter(adap); - if (ret) { - DRM_DEV_ERROR(dev, "failed to add I2C adapter: %d\n", ret); - return ret; - } - - i2c_set_adapdata(adap, vga); - - return 0; -} - -static irqreturn_t zx_vga_irq_thread(int irq, void *dev_id) -{ - struct zx_vga *vga = dev_id; - - drm_helper_hpd_irq_event(vga->connector.dev); - - return IRQ_HANDLED; -} - -static irqreturn_t zx_vga_irq_handler(int irq, void *dev_id) -{ - struct zx_vga *vga = dev_id; - u32 status; - - status = zx_readl(vga->mmio + VGA_I2C_STATUS); - - /* Clear interrupt status */ - zx_writel_mask(vga->mmio + VGA_I2C_STATUS, VGA_CLEAR_IRQ, - VGA_CLEAR_IRQ); - - if (status & VGA_DEVICE_CONNECTED) { - /* - * Since VGA_DETECT_SEL bits need to be reset for switching DDC - * bus from device detection to EDID read, rather than setting - * up HAS_DEVICE bit here, we need to do that in .get_modes - * hook for unplug detecting after EDID read succeeds. - */ - vga->connected = true; - return IRQ_WAKE_THREAD; - } - - if (status & VGA_DEVICE_DISCONNECTED) { - zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, - VGA_DETECT_SEL_NO_DEVICE); - vga->connected = false; - return IRQ_WAKE_THREAD; - } - - if (status & VGA_TRANS_DONE) { - complete(&vga->complete); - return IRQ_HANDLED; - } - - return IRQ_NONE; -} - -static void zx_vga_hw_init(struct zx_vga *vga) -{ - unsigned long ref = clk_get_rate(vga->i2c_wclk); - int div; - - /* - * Set up I2C fast speed divider per formula below to get 400kHz. - * scl = ref / ((div + 1) * 4) - */ - div = DIV_ROUND_UP(ref / 1000, 400 * 4) - 1; - zx_writel(vga->mmio + VGA_CLK_DIV_FS, div); - - /* Set up device detection */ - zx_writel(vga->mmio + VGA_AUTO_DETECT_PARA, 0x80); - zx_writel(vga->mmio + VGA_AUTO_DETECT_SEL, VGA_DETECT_SEL_NO_DEVICE); - - /* - * We need to poke monitor via DDC bus to get connection irq - * start working. - */ - zx_writel(vga->mmio + VGA_DEVICE_ADDR, DDC_ADDR); - zx_writel_mask(vga->mmio + VGA_CMD_CFG, VGA_CMD_TRANS, VGA_CMD_TRANS); -} - -static int zx_vga_bind(struct device *dev, struct device *master, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - struct drm_device *drm = data; - struct resource *res; - struct zx_vga *vga; - int irq; - int ret; - - vga = devm_kzalloc(dev, sizeof(*vga), GFP_KERNEL); - if (!vga) - return -ENOMEM; - - vga->dev = dev; - dev_set_drvdata(dev, vga); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - vga->mmio = devm_ioremap_resource(dev, res); - if (IS_ERR(vga->mmio)) - return PTR_ERR(vga->mmio); - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - vga->i2c_wclk = devm_clk_get(dev, "i2c_wclk"); - if (IS_ERR(vga->i2c_wclk)) { - ret = PTR_ERR(vga->i2c_wclk); - DRM_DEV_ERROR(dev, "failed to get i2c_wclk: %d\n", ret); - return ret; - } - - ret = zx_vga_pwrctrl_init(vga); - if (ret) { - DRM_DEV_ERROR(dev, "failed to init power control: %d\n", ret); - return ret; - } - - ret = zx_vga_ddc_register(vga); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register ddc: %d\n", ret); - return ret; - } - - ret = zx_vga_register(drm, vga); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register vga: %d\n", ret); - return ret; - } - - init_completion(&vga->complete); - - ret = devm_request_threaded_irq(dev, irq, zx_vga_irq_handler, - zx_vga_irq_thread, IRQF_SHARED, - dev_name(dev), vga); - if (ret) { - DRM_DEV_ERROR(dev, "failed to request threaded irq: %d\n", ret); - return ret; - } - - ret = clk_prepare_enable(vga->i2c_wclk); - if (ret) - return ret; - - zx_vga_hw_init(vga); - - return 0; -} - -static void zx_vga_unbind(struct device *dev, struct device *master, - void *data) -{ - struct zx_vga *vga = dev_get_drvdata(dev); - - clk_disable_unprepare(vga->i2c_wclk); -} - -static const struct component_ops zx_vga_component_ops = { - .bind = zx_vga_bind, - .unbind = zx_vga_unbind, -}; - -static int zx_vga_probe(struct platform_device *pdev) -{ - return component_add(&pdev->dev, &zx_vga_component_ops); -} - -static int zx_vga_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &zx_vga_component_ops); - return 0; -} - -static const struct of_device_id zx_vga_of_match[] = { - { .compatible = "zte,zx296718-vga", }, - { /* end */ }, -}; -MODULE_DEVICE_TABLE(of, zx_vga_of_match); - -struct platform_driver zx_vga_driver = { - .probe = zx_vga_probe, - .remove = zx_vga_remove, - .driver = { - .name = "zx-vga", - .of_match_table = zx_vga_of_match, - }, -}; diff --git a/drivers/gpu/drm/zte/zx_vga_regs.h b/drivers/gpu/drm/zte/zx_vga_regs.h deleted file mode 100644 index 1e8825ae70a5..000000000000 --- a/drivers/gpu/drm/zte/zx_vga_regs.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (C) 2017 Sanechips Technology Co., Ltd. - * Copyright 2017 Linaro Ltd. - */ - -#ifndef __ZX_VGA_REGS_H__ -#define __ZX_VGA_REGS_H__ - -#define VGA_CMD_CFG 0x04 -#define VGA_CMD_TRANS BIT(6) -#define VGA_CMD_COMBO BIT(5) -#define VGA_CMD_RW BIT(4) -#define VGA_SUB_ADDR 0x0c -#define VGA_DEVICE_ADDR 0x10 -#define VGA_CLK_DIV_FS 0x14 -#define VGA_RXF_CTRL 0x20 -#define VGA_RX_FIFO_CLEAR BIT(7) -#define VGA_DATA 0x24 -#define VGA_I2C_STATUS 0x28 -#define VGA_DEVICE_DISCONNECTED BIT(7) -#define VGA_DEVICE_CONNECTED BIT(6) -#define VGA_CLEAR_IRQ BIT(4) -#define VGA_TRANS_DONE BIT(0) -#define VGA_RXF_STATUS 0x30 -#define VGA_RXF_COUNT_SHIFT 2 -#define VGA_RXF_COUNT_MASK GENMASK(7, 2) -#define VGA_AUTO_DETECT_PARA 0x34 -#define VGA_AUTO_DETECT_SEL 0x38 -#define VGA_DETECT_SEL_HAS_DEVICE BIT(1) -#define VGA_DETECT_SEL_NO_DEVICE BIT(0) - -#endif /* __ZX_VGA_REGS_H__ */ diff --git a/drivers/gpu/drm/zte/zx_vou.c b/drivers/gpu/drm/zte/zx_vou.c deleted file mode 100644 index 904f62f3bfc1..000000000000 --- a/drivers/gpu/drm/zte/zx_vou.c +++ /dev/null @@ -1,921 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright 2016 Linaro Ltd. - * Copyright 2016 ZTE Corporation. - */ - -#include <linux/clk.h> -#include <linux/component.h> -#include <linux/module.h> -#include <linux/of_address.h> -#include <linux/platform_device.h> - -#include <video/videomode.h> - -#include <drm/drm_atomic_helper.h> -#include <drm/drm_crtc.h> -#include <drm/drm_fb_cma_helper.h> -#include <drm/drm_fb_helper.h> -#include <drm/drm_gem_cma_helper.h> -#include <drm/drm_of.h> -#include <drm/drm_plane_helper.h> -#include <drm/drm_probe_helper.h> -#include <drm/drm_vblank.h> - -#include "zx_common_regs.h" -#include "zx_drm_drv.h" -#include "zx_plane.h" -#include "zx_vou.h" -#include "zx_vou_regs.h" - -#define GL_NUM 2 -#define VL_NUM 3 - -enum vou_chn_type { - VOU_CHN_MAIN, - VOU_CHN_AUX, -}; - -struct zx_crtc_regs { - u32 fir_active; - u32 fir_htiming; - u32 fir_vtiming; - u32 sec_vtiming; - u32 timing_shift; - u32 timing_pi_shift; -}; - -static const struct zx_crtc_regs main_crtc_regs = { - .fir_active = FIR_MAIN_ACTIVE, - .fir_htiming = FIR_MAIN_H_TIMING, - .fir_vtiming = FIR_MAIN_V_TIMING, - .sec_vtiming = SEC_MAIN_V_TIMING, - .timing_shift = TIMING_MAIN_SHIFT, - .timing_pi_shift = TIMING_MAIN_PI_SHIFT, -}; - -static const struct zx_crtc_regs aux_crtc_regs = { - .fir_active = FIR_AUX_ACTIVE, - .fir_htiming = FIR_AUX_H_TIMING, - .fir_vtiming = FIR_AUX_V_TIMING, - .sec_vtiming = SEC_AUX_V_TIMING, - .timing_shift = TIMING_AUX_SHIFT, - .timing_pi_shift = TIMING_AUX_PI_SHIFT, -}; - -struct zx_crtc_bits { - u32 polarity_mask; - u32 polarity_shift; - u32 int_frame_mask; - u32 tc_enable; - u32 sec_vactive_shift; - u32 sec_vactive_mask; - u32 interlace_select; - u32 pi_enable; - u32 div_vga_shift; - u32 div_pic_shift; - u32 div_tvenc_shift; - u32 div_hdmi_pnx_shift; - u32 div_hdmi_shift; - u32 div_inf_shift; - u32 div_layer_shift; -}; - -static const struct zx_crtc_bits main_crtc_bits = { - .polarity_mask = MAIN_POL_MASK, - .polarity_shift = MAIN_POL_SHIFT, - .int_frame_mask = TIMING_INT_MAIN_FRAME, - .tc_enable = MAIN_TC_EN, - .sec_vactive_shift = SEC_VACT_MAIN_SHIFT, - .sec_vactive_mask = SEC_VACT_MAIN_MASK, - .interlace_select = MAIN_INTERLACE_SEL, - .pi_enable = MAIN_PI_EN, - .div_vga_shift = VGA_MAIN_DIV_SHIFT, - .div_pic_shift = PIC_MAIN_DIV_SHIFT, - .div_tvenc_shift = TVENC_MAIN_DIV_SHIFT, - .div_hdmi_pnx_shift = HDMI_MAIN_PNX_DIV_SHIFT, - .div_hdmi_shift = HDMI_MAIN_DIV_SHIFT, - .div_inf_shift = INF_MAIN_DIV_SHIFT, - .div_layer_shift = LAYER_MAIN_DIV_SHIFT, -}; - -static const struct zx_crtc_bits aux_crtc_bits = { - .polarity_mask = AUX_POL_MASK, - .polarity_shift = AUX_POL_SHIFT, - .int_frame_mask = TIMING_INT_AUX_FRAME, - .tc_enable = AUX_TC_EN, - .sec_vactive_shift = SEC_VACT_AUX_SHIFT, - .sec_vactive_mask = SEC_VACT_AUX_MASK, - .interlace_select = AUX_INTERLACE_SEL, - .pi_enable = AUX_PI_EN, - .div_vga_shift = VGA_AUX_DIV_SHIFT, - .div_pic_shift = PIC_AUX_DIV_SHIFT, - .div_tvenc_shift = TVENC_AUX_DIV_SHIFT, - .div_hdmi_pnx_shift = HDMI_AUX_PNX_DIV_SHIFT, - .div_hdmi_shift = HDMI_AUX_DIV_SHIFT, - .div_inf_shift = INF_AUX_DIV_SHIFT, - .div_layer_shift = LAYER_AUX_DIV_SHIFT, -}; - -struct zx_crtc { - struct drm_crtc crtc; - struct drm_plane *primary; - struct zx_vou_hw *vou; - void __iomem *chnreg; - void __iomem *chncsc; - void __iomem *dither; - const struct zx_crtc_regs *regs; - const struct zx_crtc_bits *bits; - enum vou_chn_type chn_type; - struct clk *pixclk; -}; - -#define to_zx_crtc(x) container_of(x, struct zx_crtc, crtc) - -struct vou_layer_bits { - u32 enable; - u32 chnsel; - u32 clksel; -}; - -static const struct vou_layer_bits zx_gl_bits[GL_NUM] = { - { - .enable = OSD_CTRL0_GL0_EN, - .chnsel = OSD_CTRL0_GL0_SEL, - .clksel = VOU_CLK_GL0_SEL, - }, { - .enable = OSD_CTRL0_GL1_EN, - .chnsel = OSD_CTRL0_GL1_SEL, - .clksel = VOU_CLK_GL1_SEL, - }, -}; - -static const struct vou_layer_bits zx_vl_bits[VL_NUM] = { - { - .enable = OSD_CTRL0_VL0_EN, - .chnsel = OSD_CTRL0_VL0_SEL, - .clksel = VOU_CLK_VL0_SEL, - }, { - .enable = OSD_CTRL0_VL1_EN, - .chnsel = OSD_CTRL0_VL1_SEL, - .clksel = VOU_CLK_VL1_SEL, - }, { - .enable = OSD_CTRL0_VL2_EN, - .chnsel = OSD_CTRL0_VL2_SEL, - .clksel = VOU_CLK_VL2_SEL, - }, -}; - -struct zx_vou_hw { - struct device *dev; - void __iomem *osd; - void __iomem *timing; - void __iomem *vouctl; - void __iomem *otfppu; - void __iomem *dtrc; - struct clk *axi_clk; - struct clk *ppu_clk; - struct clk *main_clk; - struct clk *aux_clk; - struct zx_crtc *main_crtc; - struct zx_crtc *aux_crtc; -}; - -enum vou_inf_data_sel { - VOU_YUV444 = 0, - VOU_RGB_101010 = 1, - VOU_RGB_888 = 2, - VOU_RGB_666 = 3, -}; - -struct vou_inf { - enum vou_inf_id id; - enum vou_inf_data_sel data_sel; - u32 clocks_en_bits; - u32 clocks_sel_bits; -}; - -static struct vou_inf vou_infs[] = { - [VOU_HDMI] = { - .data_sel = VOU_YUV444, - .clocks_en_bits = BIT(24) | BIT(18) | BIT(6), - .clocks_sel_bits = BIT(13) | BIT(2), - }, - [VOU_TV_ENC] = { - .data_sel = VOU_YUV444, - .clocks_en_bits = BIT(15), - .clocks_sel_bits = BIT(11) | BIT(0), - }, - [VOU_VGA] = { - .data_sel = VOU_RGB_888, - .clocks_en_bits = BIT(1), - .clocks_sel_bits = BIT(10), - }, -}; - -static inline struct zx_vou_hw *crtc_to_vou(struct drm_crtc *crtc) -{ - struct zx_crtc *zcrtc = to_zx_crtc(crtc); - - return zcrtc->vou; -} - -void vou_inf_hdmi_audio_sel(struct drm_crtc *crtc, - enum vou_inf_hdmi_audio aud) -{ - struct zx_crtc *zcrtc = to_zx_crtc(crtc); - struct zx_vou_hw *vou = zcrtc->vou; - - zx_writel_mask(vou->vouctl + VOU_INF_HDMI_CTRL, VOU_HDMI_AUD_MASK, aud); -} - -void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc) -{ - struct zx_crtc *zcrtc = to_zx_crtc(crtc); - struct zx_vou_hw *vou = zcrtc->vou; - struct vou_inf *inf = &vou_infs[id]; - void __iomem *dither = zcrtc->dither; - void __iomem *csc = zcrtc->chncsc; - bool is_main = zcrtc->chn_type == VOU_CHN_MAIN; - u32 data_sel_shift = id << 1; - - if (inf->data_sel != VOU_YUV444) { - /* Enable channel CSC for RGB output */ - zx_writel_mask(csc + CSC_CTRL0, CSC_COV_MODE_MASK, - CSC_BT709_IMAGE_YCBCR2RGB << CSC_COV_MODE_SHIFT); - zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, - CSC_WORK_ENABLE); - - /* Bypass Dither block for RGB output */ - zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS, - DITHER_BYSPASS); - } else { - zx_writel_mask(csc + CSC_CTRL0, CSC_WORK_ENABLE, 0); - zx_writel_mask(dither + OSD_DITHER_CTRL0, DITHER_BYSPASS, 0); - } - - /* Select data format */ - zx_writel_mask(vou->vouctl + VOU_INF_DATA_SEL, 0x3 << data_sel_shift, - inf->data_sel << data_sel_shift); - - /* Select channel */ - zx_writel_mask(vou->vouctl + VOU_INF_CH_SEL, 0x1 << id, - zcrtc->chn_type << id); - - /* Select interface clocks */ - zx_writel_mask(vou->vouctl + VOU_CLK_SEL, inf->clocks_sel_bits, - is_main ? 0 : inf->clocks_sel_bits); - - /* Enable interface clocks */ - zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, - inf->clocks_en_bits); - - /* Enable the device */ - zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 1 << id); -} - -void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc) -{ - struct zx_vou_hw *vou = crtc_to_vou(crtc); - struct vou_inf *inf = &vou_infs[id]; - - /* Disable the device */ - zx_writel_mask(vou->vouctl + VOU_INF_EN, 1 << id, 0); - - /* Disable interface clocks */ - zx_writel_mask(vou->vouctl + VOU_CLK_EN, inf->clocks_en_bits, 0); -} - -void zx_vou_config_dividers(struct drm_crtc *crtc, - struct vou_div_config *configs, int num) -{ - struct zx_crtc *zcrtc = to_zx_crtc(crtc); - struct zx_vou_hw *vou = zcrtc->vou; - const struct zx_crtc_bits *bits = zcrtc->bits; - int i; - - /* Clear update flag bit */ - zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, 0); - - for (i = 0; i < num; i++) { - struct vou_div_config *cfg = configs + i; - u32 reg, shift; - - switch (cfg->id) { - case VOU_DIV_VGA: - reg = VOU_CLK_SEL; - shift = bits->div_vga_shift; - break; - case VOU_DIV_PIC: - reg = VOU_CLK_SEL; - shift = bits->div_pic_shift; - break; - case VOU_DIV_TVENC: - reg = VOU_DIV_PARA; - shift = bits->div_tvenc_shift; - break; - case VOU_DIV_HDMI_PNX: - reg = VOU_DIV_PARA; - shift = bits->div_hdmi_pnx_shift; - break; - case VOU_DIV_HDMI: - reg = VOU_DIV_PARA; - shift = bits->div_hdmi_shift; - break; - case VOU_DIV_INF: - reg = VOU_DIV_PARA; - shift = bits->div_inf_shift; - break; - case VOU_DIV_LAYER: - reg = VOU_DIV_PARA; - shift = bits->div_layer_shift; - break; - default: - continue; - } - - /* Each divider occupies 3 bits */ - zx_writel_mask(vou->vouctl + reg, 0x7 << shift, - cfg->val << shift); - } - - /* Set update flag bit to get dividers effected */ - zx_writel_mask(vou->vouctl + VOU_DIV_PARA, DIV_PARA_UPDATE, - DIV_PARA_UPDATE); -} - -static inline void vou_chn_set_update(struct zx_crtc *zcrtc) -{ - zx_writel(zcrtc->chnreg + CHN_UPDATE, 1); -} - -static void zx_crtc_atomic_enable(struct drm_crtc *crtc, - struct drm_atomic_state *state) -{ - struct drm_display_mode *mode = &crtc->state->adjusted_mode; - bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; - struct zx_crtc *zcrtc = to_zx_crtc(crtc); - struct zx_vou_hw *vou = zcrtc->vou; - const struct zx_crtc_regs *regs = zcrtc->regs; - const struct zx_crtc_bits *bits = zcrtc->bits; - struct videomode vm; - u32 scan_mask; - u32 pol = 0; - u32 val; - int ret; - - drm_display_mode_to_videomode(mode, &vm); - - /* Set up timing parameters */ - val = V_ACTIVE((interlaced ? vm.vactive / 2 : vm.vactive) - 1); - val |= H_ACTIVE(vm.hactive - 1); - zx_writel(vou->timing + regs->fir_active, val); - - val = SYNC_WIDE(vm.hsync_len - 1); - val |= BACK_PORCH(vm.hback_porch - 1); - val |= FRONT_PORCH(vm.hfront_porch - 1); - zx_writel(vou->timing + regs->fir_htiming, val); - - val = SYNC_WIDE(vm.vsync_len - 1); - val |= BACK_PORCH(vm.vback_porch - 1); - val |= FRONT_PORCH(vm.vfront_porch - 1); - zx_writel(vou->timing + regs->fir_vtiming, val); - - if (interlaced) { - u32 shift = bits->sec_vactive_shift; - u32 mask = bits->sec_vactive_mask; - - val = zx_readl(vou->timing + SEC_V_ACTIVE); - val &= ~mask; - val |= ((vm.vactive / 2 - 1) << shift) & mask; - zx_writel(vou->timing + SEC_V_ACTIVE, val); - - val = SYNC_WIDE(vm.vsync_len - 1); - /* - * The vback_porch for the second field needs to shift one on - * the value for the first field. - */ - val |= BACK_PORCH(vm.vback_porch); - val |= FRONT_PORCH(vm.vfront_porch - 1); - zx_writel(vou->timing + regs->sec_vtiming, val); - } - - /* Set up polarities */ - if (vm.flags & DISPLAY_FLAGS_VSYNC_LOW) - pol |= 1 << POL_VSYNC_SHIFT; - if (vm.flags & DISPLAY_FLAGS_HSYNC_LOW) - pol |= 1 << POL_HSYNC_SHIFT; - - zx_writel_mask(vou->timing + TIMING_CTRL, bits->polarity_mask, - pol << bits->polarity_shift); - - /* Setup SHIFT register by following what ZTE BSP does */ - val = H_SHIFT_VAL; - if (interlaced) - val |= V_SHIFT_VAL << 16; - zx_writel(vou->timing + regs->timing_shift, val); - zx_writel(vou->timing + regs->timing_pi_shift, H_PI_SHIFT_VAL); - - /* Progressive or interlace scan select */ - scan_mask = bits->interlace_select | bits->pi_enable; - zx_writel_mask(vou->timing + SCAN_CTRL, scan_mask, - interlaced ? scan_mask : 0); - - /* Enable TIMING_CTRL */ - zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable, - bits->tc_enable); - - /* Configure channel screen size */ - zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_W_MASK, - vm.hactive << CHN_SCREEN_W_SHIFT); - zx_writel_mask(zcrtc->chnreg + CHN_CTRL1, CHN_SCREEN_H_MASK, - vm.vactive << CHN_SCREEN_H_SHIFT); - - /* Configure channel interlace buffer control */ - zx_writel_mask(zcrtc->chnreg + CHN_INTERLACE_BUF_CTRL, CHN_INTERLACE_EN, - interlaced ? CHN_INTERLACE_EN : 0); - - /* Update channel */ - vou_chn_set_update(zcrtc); - - /* Enable channel */ - zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, CHN_ENABLE); - - drm_crtc_vblank_on(crtc); - - ret = clk_set_rate(zcrtc->pixclk, mode->clock * 1000); - if (ret) { - DRM_DEV_ERROR(vou->dev, "failed to set pixclk rate: %d\n", ret); - return; - } - - ret = clk_prepare_enable(zcrtc->pixclk); - if (ret) - DRM_DEV_ERROR(vou->dev, "failed to enable pixclk: %d\n", ret); -} - -static void zx_crtc_atomic_disable(struct drm_crtc *crtc, - struct drm_atomic_state *state) -{ - struct zx_crtc *zcrtc = to_zx_crtc(crtc); - const struct zx_crtc_bits *bits = zcrtc->bits; - struct zx_vou_hw *vou = zcrtc->vou; - - clk_disable_unprepare(zcrtc->pixclk); - - drm_crtc_vblank_off(crtc); - - /* Disable channel */ - zx_writel_mask(zcrtc->chnreg + CHN_CTRL0, CHN_ENABLE, 0); - - /* Disable TIMING_CTRL */ - zx_writel_mask(vou->timing + TIMING_TC_ENABLE, bits->tc_enable, 0); -} - -static void zx_crtc_atomic_flush(struct drm_crtc *crtc, - struct drm_atomic_state *state) -{ - struct drm_pending_vblank_event *event = crtc->state->event; - - if (!event) - return; - - crtc->state->event = NULL; - - spin_lock_irq(&crtc->dev->event_lock); - if (drm_crtc_vblank_get(crtc) == 0) - drm_crtc_arm_vblank_event(crtc, event); - else - drm_crtc_send_vblank_event(crtc, event); - spin_unlock_irq(&crtc->dev->event_lock); -} - -static const struct drm_crtc_helper_funcs zx_crtc_helper_funcs = { - .atomic_flush = zx_crtc_atomic_flush, - .atomic_enable = zx_crtc_atomic_enable, - .atomic_disable = zx_crtc_atomic_disable, -}; - -static int zx_vou_enable_vblank(struct drm_crtc *crtc) -{ - struct zx_crtc *zcrtc = to_zx_crtc(crtc); - struct zx_vou_hw *vou = crtc_to_vou(crtc); - u32 int_frame_mask = zcrtc->bits->int_frame_mask; - - zx_writel_mask(vou->timing + TIMING_INT_CTRL, int_frame_mask, - int_frame_mask); - - return 0; -} - -static void zx_vou_disable_vblank(struct drm_crtc *crtc) -{ - struct zx_crtc *zcrtc = to_zx_crtc(crtc); - struct zx_vou_hw *vou = crtc_to_vou(crtc); - - zx_writel_mask(vou->timing + TIMING_INT_CTRL, - zcrtc->bits->int_frame_mask, 0); -} - -static const struct drm_crtc_funcs zx_crtc_funcs = { - .destroy = drm_crtc_cleanup, - .set_config = drm_atomic_helper_set_config, - .page_flip = drm_atomic_helper_page_flip, - .reset = drm_atomic_helper_crtc_reset, - .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state, - .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state, - .enable_vblank = zx_vou_enable_vblank, - .disable_vblank = zx_vou_disable_vblank, -}; - -static int zx_crtc_init(struct drm_device *drm, struct zx_vou_hw *vou, - enum vou_chn_type chn_type) -{ - struct device *dev = vou->dev; - struct zx_plane *zplane; - struct zx_crtc *zcrtc; - int ret; - - zcrtc = devm_kzalloc(dev, sizeof(*zcrtc), GFP_KERNEL); - if (!zcrtc) - return -ENOMEM; - - zcrtc->vou = vou; - zcrtc->chn_type = chn_type; - - zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL); - if (!zplane) - return -ENOMEM; - - zplane->dev = dev; - - if (chn_type == VOU_CHN_MAIN) { - zplane->layer = vou->osd + MAIN_GL_OFFSET; - zplane->csc = vou->osd + MAIN_GL_CSC_OFFSET; - zplane->hbsc = vou->osd + MAIN_HBSC_OFFSET; - zplane->rsz = vou->otfppu + MAIN_RSZ_OFFSET; - zplane->bits = &zx_gl_bits[0]; - zcrtc->chnreg = vou->osd + OSD_MAIN_CHN; - zcrtc->chncsc = vou->osd + MAIN_CHN_CSC_OFFSET; - zcrtc->dither = vou->osd + MAIN_DITHER_OFFSET; - zcrtc->regs = &main_crtc_regs; - zcrtc->bits = &main_crtc_bits; - } else { - zplane->layer = vou->osd + AUX_GL_OFFSET; - zplane->csc = vou->osd + AUX_GL_CSC_OFFSET; - zplane->hbsc = vou->osd + AUX_HBSC_OFFSET; - zplane->rsz = vou->otfppu + AUX_RSZ_OFFSET; - zplane->bits = &zx_gl_bits[1]; - zcrtc->chnreg = vou->osd + OSD_AUX_CHN; - zcrtc->chncsc = vou->osd + AUX_CHN_CSC_OFFSET; - zcrtc->dither = vou->osd + AUX_DITHER_OFFSET; - zcrtc->regs = &aux_crtc_regs; - zcrtc->bits = &aux_crtc_bits; - } - - zcrtc->pixclk = devm_clk_get(dev, (chn_type == VOU_CHN_MAIN) ? - "main_wclk" : "aux_wclk"); - if (IS_ERR(zcrtc->pixclk)) { - ret = PTR_ERR(zcrtc->pixclk); - DRM_DEV_ERROR(dev, "failed to get pix clk: %d\n", ret); - return ret; - } - - ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_PRIMARY); - if (ret) { - DRM_DEV_ERROR(dev, "failed to init primary plane: %d\n", ret); - return ret; - } - - zcrtc->primary = &zplane->plane; - - ret = drm_crtc_init_with_planes(drm, &zcrtc->crtc, zcrtc->primary, NULL, - &zx_crtc_funcs, NULL); - if (ret) { - DRM_DEV_ERROR(dev, "failed to init drm crtc: %d\n", ret); - return ret; - } - - drm_crtc_helper_add(&zcrtc->crtc, &zx_crtc_helper_funcs); - - if (chn_type == VOU_CHN_MAIN) - vou->main_crtc = zcrtc; - else - vou->aux_crtc = zcrtc; - - return 0; -} - -void zx_vou_layer_enable(struct drm_plane *plane) -{ - struct zx_crtc *zcrtc = to_zx_crtc(plane->state->crtc); - struct zx_vou_hw *vou = zcrtc->vou; - struct zx_plane *zplane = to_zx_plane(plane); - const struct vou_layer_bits *bits = zplane->bits; - - if (zcrtc->chn_type == VOU_CHN_MAIN) { - zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, 0); - zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, 0); - } else { - zx_writel_mask(vou->osd + OSD_CTRL0, bits->chnsel, - bits->chnsel); - zx_writel_mask(vou->vouctl + VOU_CLK_SEL, bits->clksel, - bits->clksel); - } - - zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, bits->enable); -} - -void zx_vou_layer_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) -{ - struct zx_crtc *zcrtc = to_zx_crtc(old_state->crtc); - struct zx_vou_hw *vou = zcrtc->vou; - struct zx_plane *zplane = to_zx_plane(plane); - const struct vou_layer_bits *bits = zplane->bits; - - zx_writel_mask(vou->osd + OSD_CTRL0, bits->enable, 0); -} - -static void zx_overlay_init(struct drm_device *drm, struct zx_vou_hw *vou) -{ - struct device *dev = vou->dev; - struct zx_plane *zplane; - int i; - int ret; - - /* - * VL0 has some quirks on scaling support which need special handling. - * Let's leave it out for now. - */ - for (i = 1; i < VL_NUM; i++) { - zplane = devm_kzalloc(dev, sizeof(*zplane), GFP_KERNEL); - if (!zplane) { - DRM_DEV_ERROR(dev, "failed to allocate zplane %d\n", i); - return; - } - - zplane->layer = vou->osd + OSD_VL_OFFSET(i); - zplane->hbsc = vou->osd + HBSC_VL_OFFSET(i); - zplane->rsz = vou->otfppu + RSZ_VL_OFFSET(i); - zplane->bits = &zx_vl_bits[i]; - - ret = zx_plane_init(drm, zplane, DRM_PLANE_TYPE_OVERLAY); - if (ret) { - DRM_DEV_ERROR(dev, "failed to init overlay %d\n", i); - continue; - } - } -} - -static inline void zx_osd_int_update(struct zx_crtc *zcrtc) -{ - struct drm_crtc *crtc = &zcrtc->crtc; - struct drm_plane *plane; - - vou_chn_set_update(zcrtc); - - drm_for_each_plane_mask(plane, crtc->dev, crtc->state->plane_mask) - zx_plane_set_update(plane); -} - -static irqreturn_t vou_irq_handler(int irq, void *dev_id) -{ - struct zx_vou_hw *vou = dev_id; - u32 state; - - /* Handle TIMING_CTRL frame interrupts */ - state = zx_readl(vou->timing + TIMING_INT_STATE); - zx_writel(vou->timing + TIMING_INT_STATE, state); - - if (state & TIMING_INT_MAIN_FRAME) - drm_crtc_handle_vblank(&vou->main_crtc->crtc); - - if (state & TIMING_INT_AUX_FRAME) - drm_crtc_handle_vblank(&vou->aux_crtc->crtc); - - /* Handle OSD interrupts */ - state = zx_readl(vou->osd + OSD_INT_STA); - zx_writel(vou->osd + OSD_INT_CLRSTA, state); - - if (state & OSD_INT_MAIN_UPT) - zx_osd_int_update(vou->main_crtc); - - if (state & OSD_INT_AUX_UPT) - zx_osd_int_update(vou->aux_crtc); - - if (state & OSD_INT_ERROR) - DRM_DEV_ERROR(vou->dev, "OSD ERROR: 0x%08x!\n", state); - - return IRQ_HANDLED; -} - -static void vou_dtrc_init(struct zx_vou_hw *vou) -{ - /* Clear bit for bypass by ID */ - zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL, - TILE2RASTESCAN_BYPASS_MODE, 0); - - /* Select ARIDR mode */ - zx_writel_mask(vou->dtrc + DTRC_DETILE_CTRL, DETILE_ARIDR_MODE_MASK, - DETILE_ARID_IN_ARIDR); - - /* Bypass decompression for both frames */ - zx_writel_mask(vou->dtrc + DTRC_F0_CTRL, DTRC_DECOMPRESS_BYPASS, - DTRC_DECOMPRESS_BYPASS); - zx_writel_mask(vou->dtrc + DTRC_F1_CTRL, DTRC_DECOMPRESS_BYPASS, - DTRC_DECOMPRESS_BYPASS); - - /* Set up ARID register */ - zx_writel(vou->dtrc + DTRC_ARID, DTRC_ARID3(0xf) | DTRC_ARID2(0xe) | - DTRC_ARID1(0xf) | DTRC_ARID0(0xe)); -} - -static void vou_hw_init(struct zx_vou_hw *vou) -{ - /* Release reset for all VOU modules */ - zx_writel(vou->vouctl + VOU_SOFT_RST, ~0); - - /* Enable all VOU module clocks */ - zx_writel(vou->vouctl + VOU_CLK_EN, ~0); - - /* Clear both OSD and TIMING_CTRL interrupt state */ - zx_writel(vou->osd + OSD_INT_CLRSTA, ~0); - zx_writel(vou->timing + TIMING_INT_STATE, ~0); - - /* Enable OSD and TIMING_CTRL interrrupts */ - zx_writel(vou->osd + OSD_INT_MSK, OSD_INT_ENABLE); - zx_writel(vou->timing + TIMING_INT_CTRL, TIMING_INT_ENABLE); - - /* Select GPC as input to gl/vl scaler as a sane default setting */ - zx_writel(vou->otfppu + OTFPPU_RSZ_DATA_SOURCE, 0x2a); - - /* - * Needs to reset channel and layer logic per frame when frame starts - * to get VOU work properly. - */ - zx_writel_mask(vou->osd + OSD_RST_CLR, RST_PER_FRAME, RST_PER_FRAME); - - vou_dtrc_init(vou); -} - -static int zx_crtc_bind(struct device *dev, struct device *master, void *data) -{ - struct platform_device *pdev = to_platform_device(dev); - struct drm_device *drm = data; - struct zx_vou_hw *vou; - struct resource *res; - int irq; - int ret; - - vou = devm_kzalloc(dev, sizeof(*vou), GFP_KERNEL); - if (!vou) - return -ENOMEM; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "osd"); - vou->osd = devm_ioremap_resource(dev, res); - if (IS_ERR(vou->osd)) { - ret = PTR_ERR(vou->osd); - DRM_DEV_ERROR(dev, "failed to remap osd region: %d\n", ret); - return ret; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "timing_ctrl"); - vou->timing = devm_ioremap_resource(dev, res); - if (IS_ERR(vou->timing)) { - ret = PTR_ERR(vou->timing); - DRM_DEV_ERROR(dev, "failed to remap timing_ctrl region: %d\n", - ret); - return ret; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dtrc"); - vou->dtrc = devm_ioremap_resource(dev, res); - if (IS_ERR(vou->dtrc)) { - ret = PTR_ERR(vou->dtrc); - DRM_DEV_ERROR(dev, "failed to remap dtrc region: %d\n", ret); - return ret; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vou_ctrl"); - vou->vouctl = devm_ioremap_resource(dev, res); - if (IS_ERR(vou->vouctl)) { - ret = PTR_ERR(vou->vouctl); - DRM_DEV_ERROR(dev, "failed to remap vou_ctrl region: %d\n", - ret); - return ret; - } - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "otfppu"); - vou->otfppu = devm_ioremap_resource(dev, res); - if (IS_ERR(vou->otfppu)) { - ret = PTR_ERR(vou->otfppu); - DRM_DEV_ERROR(dev, "failed to remap otfppu region: %d\n", ret); - return ret; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - vou->axi_clk = devm_clk_get(dev, "aclk"); - if (IS_ERR(vou->axi_clk)) { - ret = PTR_ERR(vou->axi_clk); - DRM_DEV_ERROR(dev, "failed to get axi_clk: %d\n", ret); - return ret; - } - - vou->ppu_clk = devm_clk_get(dev, "ppu_wclk"); - if (IS_ERR(vou->ppu_clk)) { - ret = PTR_ERR(vou->ppu_clk); - DRM_DEV_ERROR(dev, "failed to get ppu_clk: %d\n", ret); - return ret; - } - - ret = clk_prepare_enable(vou->axi_clk); - if (ret) { - DRM_DEV_ERROR(dev, "failed to enable axi_clk: %d\n", ret); - return ret; - } - - clk_prepare_enable(vou->ppu_clk); - if (ret) { - DRM_DEV_ERROR(dev, "failed to enable ppu_clk: %d\n", ret); - goto disable_axi_clk; - } - - vou->dev = dev; - dev_set_drvdata(dev, vou); - - vou_hw_init(vou); - - ret = devm_request_irq(dev, irq, vou_irq_handler, 0, "zx_vou", vou); - if (ret < 0) { - DRM_DEV_ERROR(dev, "failed to request vou irq: %d\n", ret); - goto disable_ppu_clk; - } - - ret = zx_crtc_init(drm, vou, VOU_CHN_MAIN); - if (ret) { - DRM_DEV_ERROR(dev, "failed to init main channel crtc: %d\n", - ret); - goto disable_ppu_clk; - } - - ret = zx_crtc_init(drm, vou, VOU_CHN_AUX); - if (ret) { - DRM_DEV_ERROR(dev, "failed to init aux channel crtc: %d\n", - ret); - goto disable_ppu_clk; - } - - zx_overlay_init(drm, vou); - - return 0; - -disable_ppu_clk: - clk_disable_unprepare(vou->ppu_clk); -disable_axi_clk: - clk_disable_unprepare(vou->axi_clk); - return ret; -} - -static void zx_crtc_unbind(struct device *dev, struct device *master, - void *data) -{ - struct zx_vou_hw *vou = dev_get_drvdata(dev); - - clk_disable_unprepare(vou->axi_clk); - clk_disable_unprepare(vou->ppu_clk); -} - -static const struct component_ops zx_crtc_component_ops = { - .bind = zx_crtc_bind, - .unbind = zx_crtc_unbind, -}; - -static int zx_crtc_probe(struct platform_device *pdev) -{ - return component_add(&pdev->dev, &zx_crtc_component_ops); -} - -static int zx_crtc_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &zx_crtc_component_ops); - return 0; -} - -static const struct of_device_id zx_crtc_of_match[] = { - { .compatible = "zte,zx296718-dpc", }, - { /* end */ }, -}; -MODULE_DEVICE_TABLE(of, zx_crtc_of_match); - -struct platform_driver zx_crtc_driver = { - .probe = zx_crtc_probe, - .remove = zx_crtc_remove, - .driver = { - .name = "zx-crtc", - .of_match_table = zx_crtc_of_match, - }, -}; diff --git a/drivers/gpu/drm/zte/zx_vou.h b/drivers/gpu/drm/zte/zx_vou.h deleted file mode 100644 index b25f34f865ae..000000000000 --- a/drivers/gpu/drm/zte/zx_vou.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2016 Linaro Ltd. - * Copyright 2016 ZTE Corporation. - */ - -#ifndef __ZX_VOU_H__ -#define __ZX_VOU_H__ - -#define VOU_CRTC_MASK 0x3 - -/* VOU output interfaces */ -enum vou_inf_id { - VOU_HDMI = 0, - VOU_RGB_LCD = 1, - VOU_TV_ENC = 2, - VOU_MIPI_DSI = 3, - VOU_LVDS = 4, - VOU_VGA = 5, -}; - -enum vou_inf_hdmi_audio { - VOU_HDMI_AUD_SPDIF = BIT(0), - VOU_HDMI_AUD_I2S = BIT(1), - VOU_HDMI_AUD_DSD = BIT(2), - VOU_HDMI_AUD_HBR = BIT(3), - VOU_HDMI_AUD_PARALLEL = BIT(4), -}; - -void vou_inf_hdmi_audio_sel(struct drm_crtc *crtc, - enum vou_inf_hdmi_audio aud); -void vou_inf_enable(enum vou_inf_id id, struct drm_crtc *crtc); -void vou_inf_disable(enum vou_inf_id id, struct drm_crtc *crtc); - -enum vou_div_id { - VOU_DIV_VGA, - VOU_DIV_PIC, - VOU_DIV_TVENC, - VOU_DIV_HDMI_PNX, - VOU_DIV_HDMI, - VOU_DIV_INF, - VOU_DIV_LAYER, -}; - -enum vou_div_val { - VOU_DIV_1 = 0, - VOU_DIV_2 = 1, - VOU_DIV_4 = 3, - VOU_DIV_8 = 7, -}; - -struct vou_div_config { - enum vou_div_id id; - enum vou_div_val val; -}; - -void zx_vou_config_dividers(struct drm_crtc *crtc, - struct vou_div_config *configs, int num); - -void zx_vou_layer_enable(struct drm_plane *plane); -void zx_vou_layer_disable(struct drm_plane *plane, - struct drm_plane_state *old_state); - -#endif /* __ZX_VOU_H__ */ diff --git a/drivers/gpu/drm/zte/zx_vou_regs.h b/drivers/gpu/drm/zte/zx_vou_regs.h deleted file mode 100644 index 2ddb199cb912..000000000000 --- a/drivers/gpu/drm/zte/zx_vou_regs.h +++ /dev/null @@ -1,212 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2016 Linaro Ltd. - * Copyright 2016 ZTE Corporation. - */ - -#ifndef __ZX_VOU_REGS_H__ -#define __ZX_VOU_REGS_H__ - -/* Sub-module offset */ -#define MAIN_GL_OFFSET 0x130 -#define MAIN_GL_CSC_OFFSET 0x580 -#define MAIN_CHN_CSC_OFFSET 0x6c0 -#define MAIN_HBSC_OFFSET 0x820 -#define MAIN_DITHER_OFFSET 0x960 -#define MAIN_RSZ_OFFSET 0x600 /* OTFPPU sub-module */ - -#define AUX_GL_OFFSET 0x200 -#define AUX_GL_CSC_OFFSET 0x5d0 -#define AUX_CHN_CSC_OFFSET 0x710 -#define AUX_HBSC_OFFSET 0x860 -#define AUX_DITHER_OFFSET 0x970 -#define AUX_RSZ_OFFSET 0x800 - -#define OSD_VL0_OFFSET 0x040 -#define OSD_VL_OFFSET(i) (OSD_VL0_OFFSET + 0x050 * (i)) - -#define HBSC_VL0_OFFSET 0x760 -#define HBSC_VL_OFFSET(i) (HBSC_VL0_OFFSET + 0x040 * (i)) - -#define RSZ_VL1_U0 0xa00 -#define RSZ_VL_OFFSET(i) (RSZ_VL1_U0 + 0x200 * (i)) - -/* OSD (GPC_GLOBAL) registers */ -#define OSD_INT_STA 0x04 -#define OSD_INT_CLRSTA 0x08 -#define OSD_INT_MSK 0x0c -#define OSD_INT_AUX_UPT BIT(14) -#define OSD_INT_MAIN_UPT BIT(13) -#define OSD_INT_GL1_LBW BIT(10) -#define OSD_INT_GL0_LBW BIT(9) -#define OSD_INT_VL2_LBW BIT(8) -#define OSD_INT_VL1_LBW BIT(7) -#define OSD_INT_VL0_LBW BIT(6) -#define OSD_INT_BUS_ERR BIT(3) -#define OSD_INT_CFG_ERR BIT(2) -#define OSD_INT_ERROR (\ - OSD_INT_GL1_LBW | OSD_INT_GL0_LBW | \ - OSD_INT_VL2_LBW | OSD_INT_VL1_LBW | OSD_INT_VL0_LBW | \ - OSD_INT_BUS_ERR | OSD_INT_CFG_ERR \ -) -#define OSD_INT_ENABLE (OSD_INT_ERROR | OSD_INT_AUX_UPT | OSD_INT_MAIN_UPT) -#define OSD_CTRL0 0x10 -#define OSD_CTRL0_VL0_EN BIT(13) -#define OSD_CTRL0_VL0_SEL BIT(12) -#define OSD_CTRL0_VL1_EN BIT(11) -#define OSD_CTRL0_VL1_SEL BIT(10) -#define OSD_CTRL0_VL2_EN BIT(9) -#define OSD_CTRL0_VL2_SEL BIT(8) -#define OSD_CTRL0_GL0_EN BIT(7) -#define OSD_CTRL0_GL0_SEL BIT(6) -#define OSD_CTRL0_GL1_EN BIT(5) -#define OSD_CTRL0_GL1_SEL BIT(4) -#define OSD_RST_CLR 0x1c -#define RST_PER_FRAME BIT(19) - -/* Main/Aux channel registers */ -#define OSD_MAIN_CHN 0x470 -#define OSD_AUX_CHN 0x4d0 -#define CHN_CTRL0 0x00 -#define CHN_ENABLE BIT(0) -#define CHN_CTRL1 0x04 -#define CHN_SCREEN_W_SHIFT 18 -#define CHN_SCREEN_W_MASK (0x1fff << CHN_SCREEN_W_SHIFT) -#define CHN_SCREEN_H_SHIFT 5 -#define CHN_SCREEN_H_MASK (0x1fff << CHN_SCREEN_H_SHIFT) -#define CHN_UPDATE 0x08 -#define CHN_INTERLACE_BUF_CTRL 0x24 -#define CHN_INTERLACE_EN BIT(2) - -/* Dither registers */ -#define OSD_DITHER_CTRL0 0x00 -#define DITHER_BYSPASS BIT(31) - -/* TIMING_CTRL registers */ -#define TIMING_TC_ENABLE 0x04 -#define AUX_TC_EN BIT(1) -#define MAIN_TC_EN BIT(0) -#define FIR_MAIN_ACTIVE 0x08 -#define FIR_AUX_ACTIVE 0x0c -#define V_ACTIVE_SHIFT 16 -#define V_ACTIVE_MASK (0xffff << V_ACTIVE_SHIFT) -#define H_ACTIVE_SHIFT 0 -#define H_ACTIVE_MASK (0xffff << H_ACTIVE_SHIFT) -#define FIR_MAIN_H_TIMING 0x10 -#define FIR_MAIN_V_TIMING 0x14 -#define FIR_AUX_H_TIMING 0x18 -#define FIR_AUX_V_TIMING 0x1c -#define SYNC_WIDE_SHIFT 22 -#define SYNC_WIDE_MASK (0x3ff << SYNC_WIDE_SHIFT) -#define BACK_PORCH_SHIFT 11 -#define BACK_PORCH_MASK (0x7ff << BACK_PORCH_SHIFT) -#define FRONT_PORCH_SHIFT 0 -#define FRONT_PORCH_MASK (0x7ff << FRONT_PORCH_SHIFT) -#define TIMING_CTRL 0x20 -#define AUX_POL_SHIFT 3 -#define AUX_POL_MASK (0x7 << AUX_POL_SHIFT) -#define MAIN_POL_SHIFT 0 -#define MAIN_POL_MASK (0x7 << MAIN_POL_SHIFT) -#define POL_DE_SHIFT 2 -#define POL_VSYNC_SHIFT 1 -#define POL_HSYNC_SHIFT 0 -#define TIMING_INT_CTRL 0x24 -#define TIMING_INT_STATE 0x28 -#define TIMING_INT_AUX_FRAME BIT(3) -#define TIMING_INT_MAIN_FRAME BIT(1) -#define TIMING_INT_AUX_FRAME_SEL_VSW (0x2 << 10) -#define TIMING_INT_MAIN_FRAME_SEL_VSW (0x2 << 6) -#define TIMING_INT_ENABLE (\ - TIMING_INT_MAIN_FRAME_SEL_VSW | TIMING_INT_AUX_FRAME_SEL_VSW | \ - TIMING_INT_MAIN_FRAME | TIMING_INT_AUX_FRAME \ -) -#define TIMING_MAIN_SHIFT 0x2c -#define TIMING_AUX_SHIFT 0x30 -#define H_SHIFT_VAL 0x0048 -#define V_SHIFT_VAL 0x0001 -#define SCAN_CTRL 0x34 -#define AUX_PI_EN BIT(19) -#define MAIN_PI_EN BIT(18) -#define AUX_INTERLACE_SEL BIT(1) -#define MAIN_INTERLACE_SEL BIT(0) -#define SEC_V_ACTIVE 0x38 -#define SEC_VACT_MAIN_SHIFT 0 -#define SEC_VACT_MAIN_MASK (0xffff << SEC_VACT_MAIN_SHIFT) -#define SEC_VACT_AUX_SHIFT 16 -#define SEC_VACT_AUX_MASK (0xffff << SEC_VACT_AUX_SHIFT) -#define SEC_MAIN_V_TIMING 0x3c -#define SEC_AUX_V_TIMING 0x40 -#define TIMING_MAIN_PI_SHIFT 0x68 -#define TIMING_AUX_PI_SHIFT 0x6c -#define H_PI_SHIFT_VAL 0x000f - -#define V_ACTIVE(x) (((x) << V_ACTIVE_SHIFT) & V_ACTIVE_MASK) -#define H_ACTIVE(x) (((x) << H_ACTIVE_SHIFT) & H_ACTIVE_MASK) - -#define SYNC_WIDE(x) (((x) << SYNC_WIDE_SHIFT) & SYNC_WIDE_MASK) -#define BACK_PORCH(x) (((x) << BACK_PORCH_SHIFT) & BACK_PORCH_MASK) -#define FRONT_PORCH(x) (((x) << FRONT_PORCH_SHIFT) & FRONT_PORCH_MASK) - -/* DTRC registers */ -#define DTRC_F0_CTRL 0x2c -#define DTRC_F1_CTRL 0x5c -#define DTRC_DECOMPRESS_BYPASS BIT(17) -#define DTRC_DETILE_CTRL 0x68 -#define TILE2RASTESCAN_BYPASS_MODE BIT(30) -#define DETILE_ARIDR_MODE_MASK (0x3 << 0) -#define DETILE_ARID_ALL 0 -#define DETILE_ARID_IN_ARIDR 1 -#define DETILE_ARID_BYP_BUT_ARIDR 2 -#define DETILE_ARID_IN_ARIDR2 3 -#define DTRC_ARID 0x6c -#define DTRC_ARID3_SHIFT 24 -#define DTRC_ARID3_MASK (0xff << DTRC_ARID3_SHIFT) -#define DTRC_ARID2_SHIFT 16 -#define DTRC_ARID2_MASK (0xff << DTRC_ARID2_SHIFT) -#define DTRC_ARID1_SHIFT 8 -#define DTRC_ARID1_MASK (0xff << DTRC_ARID1_SHIFT) -#define DTRC_ARID0_SHIFT 0 -#define DTRC_ARID0_MASK (0xff << DTRC_ARID0_SHIFT) -#define DTRC_DEC2DDR_ARID 0x70 - -#define DTRC_ARID3(x) (((x) << DTRC_ARID3_SHIFT) & DTRC_ARID3_MASK) -#define DTRC_ARID2(x) (((x) << DTRC_ARID2_SHIFT) & DTRC_ARID2_MASK) -#define DTRC_ARID1(x) (((x) << DTRC_ARID1_SHIFT) & DTRC_ARID1_MASK) -#define DTRC_ARID0(x) (((x) << DTRC_ARID0_SHIFT) & DTRC_ARID0_MASK) - -/* VOU_CTRL registers */ -#define VOU_INF_EN 0x00 -#define VOU_INF_CH_SEL 0x04 -#define VOU_INF_DATA_SEL 0x08 -#define VOU_SOFT_RST 0x14 -#define VOU_CLK_SEL 0x18 -#define VGA_AUX_DIV_SHIFT 29 -#define VGA_MAIN_DIV_SHIFT 26 -#define PIC_MAIN_DIV_SHIFT 23 -#define PIC_AUX_DIV_SHIFT 20 -#define VOU_CLK_VL2_SEL BIT(8) -#define VOU_CLK_VL1_SEL BIT(7) -#define VOU_CLK_VL0_SEL BIT(6) -#define VOU_CLK_GL1_SEL BIT(5) -#define VOU_CLK_GL0_SEL BIT(4) -#define VOU_DIV_PARA 0x1c -#define DIV_PARA_UPDATE BIT(31) -#define TVENC_AUX_DIV_SHIFT 28 -#define HDMI_AUX_PNX_DIV_SHIFT 25 -#define HDMI_MAIN_PNX_DIV_SHIFT 22 -#define HDMI_AUX_DIV_SHIFT 19 -#define HDMI_MAIN_DIV_SHIFT 16 -#define TVENC_MAIN_DIV_SHIFT 13 -#define INF_AUX_DIV_SHIFT 9 -#define INF_MAIN_DIV_SHIFT 6 -#define LAYER_AUX_DIV_SHIFT 3 -#define LAYER_MAIN_DIV_SHIFT 0 -#define VOU_CLK_REQEN 0x20 -#define VOU_CLK_EN 0x24 -#define VOU_INF_HDMI_CTRL 0x30 -#define VOU_HDMI_AUD_MASK 0x1f - -/* OTFPPU_CTRL registers */ -#define OTFPPU_RSZ_DATA_SOURCE 0x04 - -#endif /* __ZX_VOU_REGS_H__ */ -- 2.29.2 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel