Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/ingenic: Add dw-hdmi driver specialization for jz4780

A specialisation of the generic Synopsys HDMI driver is employed for
JZ4780 HDMI support. This requires a new driver, plus device tree and
configuration modifications.

Here we add Kconfig DRM_INGENIC_DW_HDMI, Makefile and driver code.

Note that there is no hpd-gpio installed on the CI20 board HDMI
connector. Hence there is no hpd detection by the connector driver
and we have to enable polling in the dw-hdmi core driver.

For that we need to set .poll_enabled but that struct component
can only be accessed by core code. Hence we use the public
setter function drm_kms_helper_hotplug_event() introduced before.

Also note that we disable Color Space Conversion since it is not
working on jz4780.

Signed-off-by: Paul Boddie <paul@boddie.org.uk>
Signed-off-by: Ezequiel Garcia <ezequiel@collabora.com>
Signed-off-by: H. Nikolaus Schaller <hns@goldelico.com>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Link: https://patchwork.freedesktop.org/patch/msgid/e5cdf9cd44bde52cce379cc830f2d6117ea15c32.1649330171.git.hns@goldelico.com

authored by

Paul Boddie and committed by
Paul Cercueil
71f56b27 33e799ed

+113
+9
drivers/gpu/drm/ingenic/Kconfig
··· 24 24 25 25 The Image Processing Unit (IPU) will appear as a second primary plane. 26 26 27 + config DRM_INGENIC_DW_HDMI 28 + tristate "Ingenic specific support for Synopsys DW HDMI" 29 + depends on MACH_JZ4780 30 + select DRM_DW_HDMI 31 + help 32 + Choose this option to enable Synopsys DesignWare HDMI based driver. 33 + If you want to enable HDMI on Ingenic JZ4780 based SoC, you should 34 + select this option. 35 + 27 36 endif
+1
drivers/gpu/drm/ingenic/Makefile
··· 1 1 obj-$(CONFIG_DRM_INGENIC) += ingenic-drm.o 2 2 ingenic-drm-y = ingenic-drm-drv.o 3 3 ingenic-drm-$(CONFIG_DRM_INGENIC_IPU) += ingenic-ipu.o 4 + obj-$(CONFIG_DRM_INGENIC_DW_HDMI) += ingenic-dw-hdmi.o
+103
drivers/gpu/drm/ingenic/ingenic-dw-hdmi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* Copyright (C) 2011-2013 Freescale Semiconductor, Inc. 3 + * Copyright (C) 2019, 2020 Paul Boddie <paul@boddie.org.uk> 4 + * 5 + * Derived from dw_hdmi-imx.c with i.MX portions removed. 6 + */ 7 + 8 + #include <linux/module.h> 9 + #include <linux/of_platform.h> 10 + #include <linux/platform_device.h> 11 + 12 + #include <drm/bridge/dw_hdmi.h> 13 + #include <drm/drm_of.h> 14 + #include <drm/drm_print.h> 15 + 16 + static const struct dw_hdmi_mpll_config ingenic_mpll_cfg[] = { 17 + { 45250000, { { 0x01e0, 0x0000 }, { 0x21e1, 0x0000 }, { 0x41e2, 0x0000 } } }, 18 + { 92500000, { { 0x0140, 0x0005 }, { 0x2141, 0x0005 }, { 0x4142, 0x0005 } } }, 19 + { 148500000, { { 0x00a0, 0x000a }, { 0x20a1, 0x000a }, { 0x40a2, 0x000a } } }, 20 + { 216000000, { { 0x00a0, 0x000a }, { 0x2001, 0x000f }, { 0x4002, 0x000f } } }, 21 + { ~0UL, { { 0x0000, 0x0000 }, { 0x0000, 0x0000 }, { 0x0000, 0x0000 } } } 22 + }; 23 + 24 + static const struct dw_hdmi_curr_ctrl ingenic_cur_ctr[] = { 25 + /*pixelclk bpp8 bpp10 bpp12 */ 26 + { 54000000, { 0x091c, 0x091c, 0x06dc } }, 27 + { 58400000, { 0x091c, 0x06dc, 0x06dc } }, 28 + { 72000000, { 0x06dc, 0x06dc, 0x091c } }, 29 + { 74250000, { 0x06dc, 0x0b5c, 0x091c } }, 30 + { 118800000, { 0x091c, 0x091c, 0x06dc } }, 31 + { 216000000, { 0x06dc, 0x0b5c, 0x091c } }, 32 + { ~0UL, { 0x0000, 0x0000, 0x0000 } }, 33 + }; 34 + 35 + /* 36 + * Resistance term 133Ohm Cfg 37 + * PREEMP config 0.00 38 + * TX/CK level 10 39 + */ 40 + static const struct dw_hdmi_phy_config ingenic_phy_config[] = { 41 + /*pixelclk symbol term vlev */ 42 + { 216000000, 0x800d, 0x0005, 0x01ad}, 43 + { ~0UL, 0x0000, 0x0000, 0x0000} 44 + }; 45 + 46 + static enum drm_mode_status 47 + ingenic_dw_hdmi_mode_valid(struct dw_hdmi *hdmi, void *data, 48 + const struct drm_display_info *info, 49 + const struct drm_display_mode *mode) 50 + { 51 + if (mode->clock < 13500) 52 + return MODE_CLOCK_LOW; 53 + /* FIXME: Hardware is capable of 270MHz, but setup data is missing. */ 54 + if (mode->clock > 216000) 55 + return MODE_CLOCK_HIGH; 56 + 57 + return MODE_OK; 58 + } 59 + 60 + static struct dw_hdmi_plat_data ingenic_dw_hdmi_plat_data = { 61 + .mpll_cfg = ingenic_mpll_cfg, 62 + .cur_ctr = ingenic_cur_ctr, 63 + .phy_config = ingenic_phy_config, 64 + .mode_valid = ingenic_dw_hdmi_mode_valid, 65 + .output_port = 1, 66 + }; 67 + 68 + static const struct of_device_id ingenic_dw_hdmi_dt_ids[] = { 69 + { .compatible = "ingenic,jz4780-dw-hdmi" }, 70 + { /* Sentinel */ }, 71 + }; 72 + MODULE_DEVICE_TABLE(of, ingenic_dw_hdmi_dt_ids); 73 + 74 + static void ingenic_dw_hdmi_cleanup(void *data) 75 + { 76 + struct dw_hdmi *hdmi = (struct dw_hdmi *)data; 77 + 78 + dw_hdmi_remove(hdmi); 79 + } 80 + 81 + static int ingenic_dw_hdmi_probe(struct platform_device *pdev) 82 + { 83 + struct dw_hdmi *hdmi; 84 + 85 + hdmi = dw_hdmi_probe(pdev, &ingenic_dw_hdmi_plat_data); 86 + if (IS_ERR(hdmi)) 87 + return PTR_ERR(hdmi); 88 + 89 + return devm_add_action_or_reset(&pdev->dev, ingenic_dw_hdmi_cleanup, hdmi); 90 + } 91 + 92 + static struct platform_driver ingenic_dw_hdmi_driver = { 93 + .probe = ingenic_dw_hdmi_probe, 94 + .driver = { 95 + .name = "dw-hdmi-ingenic", 96 + .of_match_table = ingenic_dw_hdmi_dt_ids, 97 + }, 98 + }; 99 + module_platform_driver(ingenic_dw_hdmi_driver); 100 + 101 + MODULE_DESCRIPTION("JZ4780 Specific DW-HDMI Driver Extension"); 102 + MODULE_LICENSE("GPL v2"); 103 + MODULE_ALIAS("platform:dw-hdmi-ingenic");