TI LCDC DRM driver
Subsystems (4)
cover TI LCDC DRM driver
One more iteration.. now with more cowbell!
The first patch adds the basic driver and TFP410 DVI output.
The second patch adds support for NXP TDA998x family of i2c connected HDMI encoders. It is split out into an i2c encoder-slave in case someone else has hw with the same HDMI encoder.
The final patch adds support for LCD panels, with timings and panel info coming from device-tree.
The patch set has dependencies on the following patches that I have sent earlier (which have not changed since then so I am not resending):
* drm/cma: add debugfs helpers -
https://patchwork.kernel.org/patch/1876721/ * drm: i2c encoder helper wrappers - https://patchwork.kernel.org/patch/1950971/ * drm/i2c: give i2c it's own Kconfig - https://patchwork.kernel.org/patch/2037181/
In addition, the LCD panel patch also depends on Steffen Trumtrar's OF display helper series. I've moved this patch to last so it can be merged later if needed. Although I really see no reason not to merge the OF display helper series for 3.9.
These patches and their dependencies can also be found here:
git://people.freedesktop.org/~robclark/linux tilcdc-next
http://cgit.freedesktop.org/~robclark/linux/log/?h=tilcdc-next
Rob Clark (4):
drm/tilcdc: add TI LCD Controller DRM driver (v4) drm/i2c: nxp-tda998x (v3)
drm/tilcdc: add encoder slave (v2) drm/tilcdc: add support for LCD panels (v5)
.../devicetree/bindings/drm/tilcdc/panel.txt | 59 ++ .../devicetree/bindings/drm/tilcdc/slave.txt | 19 + .../devicetree/bindings/drm/tilcdc/tfp410.txt | 21 + .../devicetree/bindings/drm/tilcdc/tilcdc.txt | 21 + drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/i2c/Kconfig | 6 + drivers/gpu/drm/i2c/Makefile | 3 + drivers/gpu/drm/i2c/tda998x_drv.c | 906 +++++++++++++++++++++ drivers/gpu/drm/tilcdc/Kconfig | 13 + drivers/gpu/drm/tilcdc/Makefile | 10 + drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 602 ++++++++++++++ drivers/gpu/drm/tilcdc/tilcdc_drv.c | 611 ++++++++++++++ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 150 ++++ drivers/gpu/drm/tilcdc/tilcdc_panel.c | 436 ++++++++++ drivers/gpu/drm/tilcdc/tilcdc_panel.h | 26 + drivers/gpu/drm/tilcdc/tilcdc_regs.h | 154 ++++ drivers/gpu/drm/tilcdc/tilcdc_slave.c | 376 +++++++++ drivers/gpu/drm/tilcdc/tilcdc_slave.h | 26 + drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 419 ++++++++++ drivers/gpu/drm/tilcdc/tilcdc_tfp410.h | 26 + 21 files changed, 3887 insertions(+) create mode 100644 Documentation/devicetree/bindings/drm/tilcdc/panel.txt create mode 100644 Documentation/devicetree/bindings/drm/tilcdc/slave.txt create mode 100644 Documentation/devicetree/bindings/drm/tilcdc/tfp410.txt create mode 100644 Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt create mode 100644 drivers/gpu/drm/i2c/tda998x_drv.c create mode 100644 drivers/gpu/drm/tilcdc/Kconfig create mode 100644 drivers/gpu/drm/tilcdc/Makefile create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_crtc.c create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_drv.c create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_drv.h create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_panel.c create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_panel.h create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_regs.h create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave.c create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave.h create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.h
Signature · 1 line
1.8.1
PATCH 1/4 drm/tilcdc: add TI LCD Controller DRM driver (v4)
A simple DRM/KMS driver for the TI LCD Controller found in various smaller TI parts (AM33xx, OMAPL138, etc). This driver uses the CMA helpers. Currently only the TFP410 DVI encoder is supported (tested with beaglebone + DVI cape). There are also various LCD displays, for which support can be added (as I get hw to test on), and an external i2c HDMI encoder found on some boards.
The display controller supports a single CRTC. And the encoder+ connector are split out into sub-devices. Depending on which LCD or external encoder is actually present, the appropriate output module(s) will be loaded.
v1: original
v2: fix fb refcnting and few other cleanups
v3: get +/- vsync/hsync from timings rather than panel-info, add
option DT max-bandwidth field so driver doesn't attempt to pick a display mode with too high memory bandwidth, and other small cleanups
v4: remove some unneeded stuff from panel-info struct, properly
set high bits for hfp/hsw/hbp for rev 2, add DT bindings docs
--- .../devicetree/bindings/drm/tilcdc/tfp410.txt | 21 + .../devicetree/bindings/drm/tilcdc/tilcdc.txt | 21 + drivers/gpu/drm/Kconfig | 2 + drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/tilcdc/Kconfig | 10 + drivers/gpu/drm/tilcdc/Makefile | 8 + drivers/gpu/drm/tilcdc/tilcdc_crtc.c | 602 ++++++++++++++++++++ drivers/gpu/drm/tilcdc/tilcdc_drv.c | 605 +++++++++++++++++++++ drivers/gpu/drm/tilcdc/tilcdc_drv.h | 150 +++++ drivers/gpu/drm/tilcdc/tilcdc_regs.h | 154 ++++++ drivers/gpu/drm/tilcdc/tilcdc_tfp410.c | 419 ++++++++++++++ drivers/gpu/drm/tilcdc/tilcdc_tfp410.h | 26 + 12 files changed, 2019 insertions(+) create mode 100644 Documentation/devicetree/bindings/drm/tilcdc/tfp410.txt create mode 100644 Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt create mode 100644 drivers/gpu/drm/tilcdc/Kconfig create mode 100644 drivers/gpu/drm/tilcdc/Makefile create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_crtc.c create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_drv.c create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_drv.h create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_regs.h create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.c create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_tfp410.h
Documentation/devicetree/bindings/drm/tilcdc/tfp410.txt new file +21 -0
@@ -0,0 +1,21 @@ +Device-Tree bindings for tilcdc DRM TFP410 output driver + +Required properties: + - compatible: value should be "tilcdc,tfp410". + - i2c: the phandle for the i2c device to use for DDC + +Recommended properties: + - pinctrl-names, pinctrl-0: the pincontrol settings to configure + muxing properly for pins that connect to TFP410 device + - powerdn-gpio: the powerdown GPIO, pulled low to power down the + TFP410 device (for DPMS_OFF) + +Example: + + dvicape { + compatible = "tilcdc,tfp410"; + i2c = <&i2c2>; + pinctrl-names = "default"; + pinctrl-0 = <&bone_dvi_cape_dvi_00A1_pins>; + powerdn-gpio = <&gpio2 31 0>; + };
Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt new file +21 -0
@@ -0,0 +1,21 @@ +Device-Tree bindings for tilcdc DRM driver + +Required properties: + - compatible: value should be "ti,am33xx-tilcdc". + - interrupts: the interrupt number + - reg: base address and size of the LCDC device + +Recommended properties: + - interrupt-parent: the phandle for the interrupt controller that + services interrupts for this device. + - ti,hwmods: Name of the hwmod associated to the LCDC + +Example: + + fb: fb@4830e000 { + compatible = "ti,am33xx-tilcdc"; + reg = <0x4830e000 0x1000>; + interrupt-parent = <&intc>; + interrupts = <36>; + ti,hwmods = "lcdc"; + };
drivers/gpu/drm/Kconfig +2 -0
@@ -214,3 +214,5 @@ source "drivers/gpu/drm/cirrus/Kconfig" source "drivers/gpu/drm/shmobile/Kconfig" source "drivers/gpu/drm/tegra/Kconfig" + +source "drivers/gpu/drm/tilcdc/Kconfig"
drivers/gpu/drm/Makefile +1 -0
@@ -50,4 +50,5 @@ obj-$(CONFIG_DRM_UDL) += udl/ obj-$(CONFIG_DRM_AST) += ast/ obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ obj-$(CONFIG_DRM_TEGRA) += tegra/ +obj-$(CONFIG_DRM_TILCDC) += tilcdc/ obj-y += i2c/
drivers/gpu/drm/tilcdc/Kconfig new file +10 -0
@@ -0,0 +1,10 @@ +config DRM_TILCDC + tristate "DRM Support for TI LCDC Display Controller" + depends on DRM && OF + select DRM_KMS_HELPER + select DRM_KMS_CMA_HELPER + select DRM_GEM_CMA_HELPER + help + Choose this option if you have an TI SoC with LCDC display + controller, for example AM33xx in beagle-bone, DA8xx, or + OMAP-L1xx. This driver replaces the FB_DA8XX fbdev driver.
drivers/gpu/drm/tilcdc/Makefile new file +8 -0
@@ -0,0 +1,8 @@ +ccflags-y := -Iinclude/drm -Werror + +tilcdc-y := \ + tilcdc_crtc.o \ + tilcdc_tfp410.o \ + tilcdc_drv.o + +obj-$(CONFIG_DRM_TILCDC) += tilcdc.o
drivers/gpu/drm/tilcdc/tilcdc_crtc.c new file +602 -0
602 lines not on this page · raw message
drivers/gpu/drm/tilcdc/tilcdc_drv.c new file +605 -0
605 lines not on this page · raw message
drivers/gpu/drm/tilcdc/tilcdc_drv.h new file +150 -0
150 lines not on this page · raw message
drivers/gpu/drm/tilcdc/tilcdc_regs.h new file +154 -0
154 lines not on this page · raw message
drivers/gpu/drm/tilcdc/tilcdc_tfp410.c new file +419 -0
419 lines not on this page · raw message
drivers/gpu/drm/tilcdc/tilcdc_tfp410.h new file +26 -0
@@ -0,0 +1,26 @@ +/* +* Copyright (C) 2012 Texas Instruments +* Author: Rob Clark <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 as published by +* the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __TILCDC_TFP410_H__ +#define __TILCDC_TFP410_H__ + +/* sub-module for tfp410 dvi adaptor */ + +int tilcdc_tfp410_init (void ); +void tilcdc_tfp410_fini (void ); + +#endif /* __TILCDC_TFP410_H__ */
Signature · 1 line
1.8.1
PATCH 2/4 drm/i2c: nxp-tda998x (v3)
In reply to Rob ClarkDriver for the NXP TDA998X i2c hdmi encoder slave.
v1: original
v2: fix npix/nline programming
v3: add Kconfig, fix dup'd MODULE_DESCRIPTION
--- drivers/gpu/drm/i2c/Kconfig | 6 + drivers/gpu/drm/i2c/Makefile | 3 + drivers/gpu/drm/i2c/tda998x_drv.c | 906 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 915 insertions(+) create mode 100644 drivers/gpu/drm/i2c/tda998x_drv.c
drivers/gpu/drm/i2c/Kconfig +6 -0
@@ -19,4 +19,10 @@ config DRM_I2C_SIL164 when used in pairs) TMDS transmitters, used in some nVidia video cards. +config DRM_I2C_NXP_TDA998X + tristate "NXP Semiconductors TDA998X HDMI encoder" + default m if DRM_TILCDC + help + Support for NXP Semiconductors TDA998X HDMI encoders. + endmenu
drivers/gpu/drm/i2c/Makefile +3 -0
@@ -5,3 +5,6 @@ obj-$(CONFIG_DRM_I2C_CH7006) += ch7006.o sil164-y := sil164_drv.o obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o + +tda998x-y := tda998x_drv.o +obj-$(CONFIG_DRM_I2C_NXP_TDA998X) += tda998x.o
drivers/gpu/drm/i2c/tda998x_drv.c new file +906 -0
906 lines not on this page · raw message
Signature · 1 line
1.8.1
Re: [PATCH 2/4] drm/i2c: nxp-tda998x (v3)
Quoted 1 line · Rob Clark
Driver for the NXP TDA998X i2c hdmi encoder slave.
Rob,
good to see a driver for TDA998x comming! I'd love to test it on CuBox (mach-dove) but there is no gpu driver I can hook up, yet. Anyway, I will make some comments how I think the driver should be improved.
drivers/gpu/drm/i2c/Kconfig config DRM_I2C_SIL164 · line 26
Quoted 13 lines
drivers/gpu/drm/i2c/Kconfig +5
-0@@ -19,4 +19,10 @@ config DRM_I2C_SIL164 when used in pairs) TMDS transmitters, used in some nVidia video cards. +config DRM_I2C_NXP_TDA998X + tristate "NXP Semiconductors TDA998X HDMI encoder" + default m if DRM_TILCDC + help + Support for NXP Semiconductors TDA998X HDMI encoders.
Maybe nit-picking but later down you actually support TDA9989, TDA19988, and TDA19989. The latter ones don't fit in TDA998x, so at least the Kconfig entry should reflect TDA9989/TDA1998x.
Quoted 9 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +2
-0@@ -0,0 +1,906 @@ +/* +* Copyright (C) 2012 Texas Instruments
drivers/gpu/drm/i2c/tda998x_drv.c line 43
Quoted 10 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +9
-0+* Author: Rob Clark<[email protected]> +* + + +/* The TDA9988 series of devices use a paged register scheme.. to simplify +* things we encode the page # in upper bits of the register #. To read/ +* write a given register, we need to make sure CURPAGE register is set +* appropriately. Which implies reads/writes are not atomic. Fun! +*/
Please have a look at regmap-i2c, it also supports paged i2c registers and will save you _a lot_ of the i2c handling.
drivers/gpu/drm/i2c/tda998x_drv.c line 263
Quoted 7 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +6
-0+ +/* Device versions: */ +#define TDA9989N2 0x0101 +#define TDA19989 0x0201 +#define TDA19989N2 0x0202 +#define TDA19988 0x0301
Maybe split this into device_version/revision? What does N2 stand for or is this the name NXP uses for that device?
drivers/gpu/drm/i2c/tda998x_drv.c line 275
Quoted 12 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +11
-0+static void +cec_write (struct drm_encoder *encoder,uint16_t addr,uint8_t val) +{ +struct i2c_client *client =to_tda998x_priv (encoder)->cec; +uint8_t buf[] = {addr, val}; +int ret; + + ret =i2c_master_send (client, buf,ARRAY_SIZE (buf)); +if (ret<0 ) +dev_err (&client->dev,"Error %d writing to cec:0x%x\n" , ret, addr); +}
Has there been any decision on how to split/integrate cec from drm? Or is there display stuff located in cec i2c slave (I see HPD in ..._detect below)?
drivers/gpu/drm/i2c/tda998x_drv.c line 474
Quoted 12 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +11
-0+static void +tda998x_encoder_save (struct drm_encoder *encoder) +{ +DBG ("" ); +} + +static void +tda998x_encoder_restore (struct drm_encoder *encoder) +{ +DBG ("" ); +}
Hmmm, these DBG("") shouldn't be in upstream kernel code?
Quoted 4 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +4
-0+static bool +tda998x_encoder_mode_fixup (struct drm_encoder *encoder, +const struct drm_display_mode *mode, +struct drm_display_mode *adjusted_mode)
drivers/gpu/drm/i2c/tda998x_drv.c line 489
Quoted 10 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +10
-0+{ +return true; +} + +static int +tda998x_encoder_mode_valid (struct drm_encoder *encoder, +struct drm_display_mode *mode) +{ +return MODE_OK ; +}
At least a note would be helpful to see what callbacks are not yet done. I guess there will be some kind of mode check someday?
drivers/gpu/drm/i2c/tda998x_drv.c line 625
Quoted 9 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +8
-0+static enum drm_connector_status +tda998x_encoder_detect (struct drm_encoder *encoder, +struct drm_connector *connector) +{ +uint8_t val =cec_read (encoder,REG_CEC_RXSHPDLEV ); +return (val&CEC_RXSHPDLEV_HPD ) ? connector_status_connected : + connector_status_disconnected; +}
This is where cec slave gets called from hdmi i2c driver. Any chance there is HPD status in hdmi registers, too?
drivers/gpu/drm/i2c/tda998x_drv.c line 796
Quoted 13 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +13
-0+/* I2C driver functions */ + +static int +tda998x_probe (struct i2c_client *client,const struct i2c_device_id *id) +{ +return 0 ; +} + +static int +tda998x_remove (struct i2c_client *client) +{ +return 0 ; +}
Hmm, empty _probe and _remove? Maybe these should get some code from _init below?
Quoted 21 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +21
-0+static int +tda998x_encoder_init (struct i2c_client *client, +struct drm_device *dev, +struct drm_encoder_slave *encoder_slave) +{ +struct drm_encoder *encoder =&encoder_slave->base; +struct tda998x_priv *priv; + + priv =kzalloc (sizeof (*priv),GFP_KERNEL ); +if (!priv) +return -ENOMEM ; + + priv->current_page =0 ; + priv->cec =i2c_new_dummy (client->adapter,0x34 ); + priv->dpms =DRM_MODE_DPMS_OFF ; + + encoder_slave->slave_priv = priv; + encoder_slave->slave_funcs =&tda998x_encoder_funcs; + +/* wake up the device: */ + cec_write(encoder, REG_CEC_ENAMODS,
drivers/gpu/drm/i2c/tda998x_drv.c
Quoted 10 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +10
-0+ CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); + +tda998x_reset (encoder); + +/* read version: */ + priv->rev =reg_read (encoder,REG_VERSION_LSB ) | +reg_read (encoder,REG_VERSION_MSB )<<8 ; + +/* mask off feature bits: */ + priv->rev&= ~0x30 ;/* not-hdcp and not-scalar bit */
If revision register contains features, why not save them for later driver improvements?
drivers/gpu/drm/i2c/tda998x_drv.c line 838
Quoted 9 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +9
-0+switch (priv->rev) { +case TDA9989N2 :dev_info (dev->dev,"found TDA9989 n2" );break ; +case TDA19989 :dev_info (dev->dev,"found TDA19989" );break ; +case TDA19989N2 :dev_info (dev->dev,"found TDA19989 n2" );break ; +case TDA19988 :dev_info (dev->dev,"found TDA19988" );break ; +default : +DBG ("found unsupported device: %04x" , priv->rev); + goto fail; + }
I think printing revision is sufficient, no user will care about the actual device or revision.
drivers/gpu/drm/i2c/tda998x_drv.c line 844
Quoted 5 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +5
-0+/* after reset, enable DDC: */ +reg_write (encoder,REG_DDC_DISABLE ,0x00 ); + +/* set clock on DDC channel: */ +reg_write (encoder,REG_TX3 ,39 );
This should be kept disabled as long as there is no monitor attached (HPD!)
Quoted 16 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +16
-0+/* if necessary, disable multi-master: */ +if (priv->rev ==TDA19989 ) +reg_set (encoder,REG_I2C_MASTER ,I2C_MASTER_DIS_MM ); + +cec_write (encoder,REG_CEC_FRO_IM_CLK_CTRL , +CEC_FRO_IM_CLK_CTRL_GHOST_DIS |CEC_FRO_IM_CLK_CTRL_IMCLK_SEL ); + +return 0 ; + +fail: +/* if encoder_init fails, the encoder slave is never registered, +* so cleanup here: +*/ +if (priv->cec) +i2c_unregister_device (priv->cec); +kfree (priv);
drivers/gpu/drm/i2c/tda998x_drv.c line 871
Quoted 10 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +10
-0+ encoder_slave->slave_priv =NULL ; + encoder_slave->slave_funcs =NULL ; +return -ENXIO ; +} + +static struct i2c_device_id tda998x_ids[] = { + {"tda998x" ,0 }, + { } +}; +MODULE_DEVICE_TABLE (i2c, tda998x_ids);
Shouldn't the above carry the hdmi core i2c address at least?
Quoted 21 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +21
-0+static struct drm_i2c_encoder_driver tda998x_driver = { + .i2c_driver = { + .probe = tda998x_probe, + .remove = tda998x_remove, + .driver = { + .name ="tda998x" , + }, + .id_table = tda998x_ids, + }, + .encoder_init = tda998x_encoder_init, +}; + +/* Module initialization */ + +static int __init +tda998x_init (void ) +{ +DBG ("" ); +return drm_i2c_encoder_register (THIS_MODULE ,&tda998x_driver); +} +
drivers/gpu/drm/i2c/tda998x_drv.c line 903
Quoted 10 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +10
-0+static void __exit +tda998x_exit (void ) +{ +DBG ("" ); +drm_i2c_encoder_unregister (&tda998x_driver); +} + +MODULE_AUTHOR ("Rob Clark<[email protected]" ); +MODULE_DESCRIPTION ("NXP Semiconductors TDA998X HDMI Encoder" ); +MODULE_LICENSE ("GPL" );
Maybe stick to one version of "TDA998X" or "TDA998x" ?
Regards,
Sebastian
Re: [PATCH 2/4] drm/i2c: nxp-tda998x (v3)
Quoted 21 lines · Sebastian Hesselbarth
Quoted 2 lines · Rob Clark
Driver for the NXP TDA998X i2c hdmi encoder slave.
Rob,
good to see a driver for TDA998x comming! I'd love to test it on CuBox (mach-dove) but there is no gpu driver I can hook up, yet. Anyway, I will make some comments how I think the driver should be improved.
Quoted 8 lines
drivers/gpu/drm/i2c/Kconfig +0
-0@@ -19,4 +19,10 @@ config DRM_I2C_SIL164 when used in pairs) TMDS transmitters, used in some nVidia video cards.
Quoted 10 lines
drivers/gpu/drm/i2c/Kconfig config DRM_I2C_SIL164 · line 26
Quoted 5 lines
drivers/gpu/drm/i2c/Kconfig +5
-0+config DRM_I2C_NXP_TDA998X + tristate "NXP Semiconductors TDA998X HDMI encoder" + default m if DRM_TILCDC + help + Support for NXP Semiconductors TDA998X HDMI encoders.Maybe nit-picking but later down you actually support TDA9989, TDA19988, and TDA19989. The latter ones don't fit in TDA998x, so at least the
Kconfigentry should reflect TDA9989/TDA1998x.
yeah, it is a bit weird naming scheme, but I'm just copying NXP in referring to the whole family as TDA998x
Quoted 16 lines
Quoted 16 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +5
-0@@ -0,0 +1,906 @@ +/* +* Copyright (C) 2012 Texas Instruments +* Author: Rob Clark<[email protected]> +* +
Quoted 11 lines
Quoted 7 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +2
-0+ +/* The TDA9988 series of devices use a paged register scheme.. to simplify
+ * things we encode the page # in upper bits of the register #. To read/
+ * write a given register, we need to make sure CURPAGE register is set
+ * appropriately. Which implies reads/writes are not atomic. Fun!
+ */Please have a look at regmap-i2c, it also supports paged i2c registers and will save you _a
lot_of the i2c handling.
Yeah, I have looked at it, and will eventually convert over to using it. The problems at the moment are that I don't really have enough documentation about the chip at the register level to properly use the caching modes, and from my digging through the regmap code it looked like paged regmap + non-caching will result in writes to the page register for every transaction. That, and a bit of docs or few more examples of using the paging support in regmap would be nice. For now, I am punting on regmap conversion.
Quoted 12 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 263
Quoted 8 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +6
-0+ +/* Device versions: */ +#define TDA9989N2 0x0101 +#define TDA19989 0x0201 +#define TDA19989N2 0x0202 +#define TDA19988 0x0301Maybe split this into device_version/revision? What does N2 stand for or is this the name NXP uses for that device?
The register names are based on the names used in the NXP out-of-tree driver (the 50kloc monstrosity, if you've seen it).. that was pretty much all the register level documentation I had.
Quoted 11 lines
Quoted 11 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +9
-0+static void +cec_write (struct drm_encoder *encoder,uint16_t addr,uint8_t val) +{ +struct i2c_client *client =to_tda998x_priv (encoder)->cec; +uint8_t buf[] = {addr, val}; +int ret; + + ret =i2c_master_send (client, buf,ARRAY_SIZE (buf)); +if (ret<0 )
Quoted 8 lines
Quoted 3 lines
+ dev_err(&client->dev, "Error %d writing to cec:0x%x\n",
ret, addr);
+}Has there been any decision on how to split/integrate cec from drm? Or is there display stuff located in cec i2c slave (I see HPD in ..._detect below)?
not sure, but at least in this case it can't really be decoupled. I need to use the CEC interface for HPD (as you noticed) and also to power up the HDMI bits..
Quoted 17 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 474
Quoted 13 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +11
-0+static void +tda998x_encoder_save (struct drm_encoder *encoder) +{ +DBG ("" ); +} + +static void +tda998x_encoder_restore (struct drm_encoder *encoder) +{ +DBG ("" ); +}Hmmm, these
DBG("")shouldn't be in upstream kernel code?
yeah, I suppose these traces don't add too much value, I can remove them
Quoted 11 lines
Quoted 11 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +11
-0+static bool +tda998x_encoder_mode_fixup (struct drm_encoder *encoder, +const struct drm_display_mode *mode, +struct drm_display_mode *adjusted_mode) +{ +return true; +} + +static int +tda998x_encoder_mode_valid (struct drm_encoder *encoder, +struct drm_display_mode *mode)
Quoted 8 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 489
Quoted 3 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +3
-0+{ +return MODE_OK ; +}At least a note would be helpful to see what callbacks are not yet done. I guess there will be some kind of mode check someday?
Well, some of these drm will assume the fxn ptrs are not null, so we need something even if it is empty.
I suppose there are must be some upper bounds on pixel clock supported, which could perhaps be added some day in _mode_valid(). On the device I am working on, the limiting factor is the crtc (upstream of the encoder), so I haven't really needed this yet. I expect that as people start using this on some other devices, we'll come across some enhancements needed, some places where we need to add some configuration, etc. I cannot really predict exactly what is needed, so I prefer just to put the driver out there in some form, and then add it it as needed. So, I wouldn't really say that these functions are "TODO", but I also wouldn't say that we won't find some reason to add some code there at some point.
Quoted 14 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 625
Quoted 10 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +8
-0+static enum drm_connector_status +tda998x_encoder_detect (struct drm_encoder *encoder, +struct drm_connector *connector) +{ +uint8_t val =cec_read (encoder,REG_CEC_RXSHPDLEV ); +return (val&CEC_RXSHPDLEV_HPD ) ? connector_status_connected : + connector_status_disconnected; +}This is where cec slave gets called from hdmi i2c driver. Any chance there is HPD status in hdmi registers, too?
Not that I know of. But like I mentioned, we also need to use the CEC interface just to talk to the HDMI interface. Before setting ENAMODS reg via cec address, the hdmi address won't even show up (for ex, on i2cdetect).
Maybe there is some way that this code should register some interface with CEC driver/subsystem? (Is there such a thing? I am not really CEC expert.) But I don't think there is any way to completely split it out.
Quoted 10 lines
Quoted 10 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +9
-0+/* I2C driver functions */ + +static int +tda998x_probe (struct i2c_client *client,const struct i2c_device_id *id) +{ +return 0 ; +} + +static int
Quoted 8 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 796
Quoted 4 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +4
-0+tda998x_remove(struct i2c_client *client) +{ +return 0 ; +}Hmm, empty
_probeand_remove? Maybe these should get some code from_initbelow?
naw, they aren't really used for drm i2c encoder slaves.
Quoted 28 lines
Quoted 28 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +27
-0+static int +tda998x_encoder_init (struct i2c_client *client, +struct drm_device *dev, +struct drm_encoder_slave *encoder_slave) +{ +struct drm_encoder *encoder =&encoder_slave->base; +struct tda998x_priv *priv; + + priv =kzalloc (sizeof (*priv),GFP_KERNEL ); +if (!priv) +return -ENOMEM ; + + priv->current_page =0 ; + priv->cec =i2c_new_dummy (client->adapter,0x34 ); + priv->dpms =DRM_MODE_DPMS_OFF ; + + encoder_slave->slave_priv = priv; + encoder_slave->slave_funcs =&tda998x_encoder_funcs; + +/* wake up the device: */ +cec_write (encoder,REG_CEC_ENAMODS , +CEC_ENAMODS_EN_RXSENS |CEC_ENAMODS_EN_HDMI ); + +tda998x_reset (encoder); + +/* read version: */ + priv->rev = reg_read(encoder, REG_VERSION_LSB) |
Quoted 9 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 828
Quoted 4 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +4
-0+reg_read (encoder,REG_VERSION_MSB )<<8 ; + +/* mask off feature bits: */ + priv->rev &= ~0x30 ;/* not-hdcp and not-scalar bit */ If revision register contains features, why not save them for later driver improvements?
can be added later if the need arises. I prefer to leave out code that only might be used later.. otherwise it is a good way to accumulate cruft.
Quoted 23 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 838
Quoted 10 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +9
-0+switch (priv->rev) { +case TDA9989N2 :dev_info (dev->dev,"found TDA9989 n2" );break ; +case TDA19989 :dev_info (dev->dev,"found TDA19989" );break ; +case TDA19989N2 :dev_info (dev->dev,"found TDA19989 n2" );break ; +case TDA19988 :dev_info (dev->dev,"found TDA19988" );break ; +default : +DBG ("found unsupported device: %04x" , priv->rev); + goto fail; + }I think printing revision is sufficient, no user will care about the actual device or revision.
drivers/gpu/drm/i2c/tda998x_drv.c line 844
Quoted 5 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +5
-0+/* after reset, enable DDC: */ +reg_write (encoder,REG_DDC_DISABLE ,0x00 ); + +/* set clock on DDC channel: */ +reg_write (encoder,REG_TX3 ,39 );
Quoted 3 lines
This should be kept disabled as long as there is no monitor attached (HPD!)
The sequence is based on NXP's driver.. I'll have to go back and check, but IIRC there were a few things I had to turn on just to make HPD work in the first place.
Ofc, if there were actually some decent docs about the part, it would be a bit easier to know what is actually required and what is not. So I don't claim everything in it's current form is optimal.
Quoted 23 lines
Quoted 23 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +6
-0+/* if necessary, disable multi-master: */ +if (priv->rev ==TDA19989 ) +reg_set (encoder,REG_I2C_MASTER ,I2C_MASTER_DIS_MM ); + + cec_write(encoder, REG_CEC_FRO_IM_CLK_CTRL, + CEC_FRO_IM_CLK_CTRL_GHOST_DIS |
CEC_FRO_IM_CLK_CTRL_IMCLK_SEL);drivers/gpu/drm/i2c/tda998x_drv.c new file +15
-0+ +return 0 ; + +fail: +/* if encoder_init fails, the encoder slave is never registered, +* so cleanup here: +*/ +if (priv->cec) +i2c_unregister_device (priv->cec); +kfree (priv); + encoder_slave->slave_priv =NULL ; + encoder_slave->slave_funcs =NULL ; +return -ENXIO ; +} +
Quoted 9 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 871
Quoted 5 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +5
-0+static struct i2c_device_id tda998x_ids[] = { + {"tda998x" ,0 }, + { } +}; +MODULE_DEVICE_TABLE (i2c, tda998x_ids);Shouldn't the above carry the hdmi core i2c address at least?
no, it should come from the user of the encoder slave. Actually the CEC address should too, but current drm i2c encoder slave code sort of assumes the device just has a single address
BR,
-R
Quoted 38 lines
Quoted 22 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +21
-0+static struct drm_i2c_encoder_driver tda998x_driver = { + .i2c_driver = { + .probe = tda998x_probe, + .remove = tda998x_remove, + .driver = { + .name ="tda998x" , + }, + .id_table = tda998x_ids, + }, + .encoder_init = tda998x_encoder_init, +}; + +/* Module initialization */ + +static int __init +tda998x_init (void ) +{ +DBG ("" ); +return drm_i2c_encoder_register (THIS_MODULE ,&tda998x_driver); +} +drivers/gpu/drm/i2c/tda998x_drv.c line 903
Quoted 10 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +10
-0+static void __exit +tda998x_exit (void ) +{ +DBG ("" ); +drm_i2c_encoder_unregister (&tda998x_driver); +} + +MODULE_AUTHOR ("Rob Clark<[email protected]" ); +MODULE_DESCRIPTION ("NXP Semiconductors TDA998X HDMI Encoder" ); +MODULE_LICENSE ("GPL" );Maybe stick to one version of "TDA998X" or "TDA998x" ?
Regards,
Sebastian
Re: [PATCH 2/4] drm/i2c: nxp-tda998x (v3)
Quoted 7 lines · Rob Clark
Quoted 5 lines · Sebastian Hesselbarth
Quoted 2 lines · Rob Clark
Driver for the NXP TDA998X i2c hdmi encoder slave.
Quoted 6 lines
Quoted 6 lines
Rob,
good to see a driver for TDA998x comming! I'd love to test it on CuBox (mach-dove) but there is no gpu driver I can hook up, yet. Anyway, I will make some comments how I think the driver should be improved.
I will eventually pick this up and give it a whirl with my cubox DRM stuff. I've yet to receive my round tuit.
Re: [PATCH 2/4] drm/i2c: nxp-tda998x (v3)
In reply to Rob ClarkQuoted 3 lines · Rob Clark
Quoted 1 line · Sebastian Hesselbarth
On 01/29/2013 06:23 PM, Rob Clark wrote:
[...]
Quoted 11 lines
Quoted 10 lines
Quoted 7 lines
(quoted diff) +2
-0+ +/* The TDA9988 series of devices use a paged register scheme.. tosimplify
+ * things we encode the page # in upper bits of the register #. To read/
+ * write a given register, we need to make sure CURPAGE register is set
+ * appropriately. Which implies reads/writes are not atomic. Fun!
+ */Please have a look at regmap-i2c, it also supports paged i2c registers and will save you _a
lot_of the i2c handling.
Quoted 8 lines
Yeah, I have looked at it, and will eventually convert over to using it. The problems at the moment are that I don't really have enough documentation about the chip at the register level to properly use the caching modes, and from my digging through the regmap code it looked like paged regmap + non-caching will result in writes to the page register for every transaction. That, and a bit of docs or few more examples of using the paging support in regmap would be nice. For now, I am punting on regmap conversion.
Hmm, flipping through the public tda998x sources *sigh* I found a quite complete register list that also states if registers are RO or RW. Even if you are not using all registers you can still prevent regmap from reading/writing to them. But yes, documentation lacks some examples ;)
Quoted 12 lines
Quoted 11 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 263
Quoted 7 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +6
-0+ +/* Device versions: */ +#define TDA9989N2 0x0101 +#define TDA19989 0x0201 +#define TDA19989N2 0x0202 +#define TDA19988 0x0301Maybe split this into device_version/revision? What does N2 stand for or is this the name NXP uses for that device?
Quoted 3 lines
The register names are based on the names used in the NXP out-of-tree driver (the 50kloc monstrosity, if you've seen it).. that was pretty much all the register level documentation I had.
Yeah, but there is a comment about N2, that says the last bit is "not a register bit, but is derived by the driver from the new N5 registers..". I guess you will not see that many i2c devices returning you "N2" version registers..
Quoted 20 lines
Quoted 11 lines
Quoted 11 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +9
-0+static void +cec_write (struct drm_encoder *encoder,uint16_t addr,uint8_t val) +{ +struct i2c_client *client =to_tda998x_priv (encoder)->cec; +uint8_t buf[] = {addr, val}; +int ret; + + ret =i2c_master_send (client, buf,ARRAY_SIZE (buf)); +if (ret<0 )Quoted 8 lines
Quoted 3 lines
+ dev_err(&client->dev, "Error %d writing to cec:0x%x\n",
ret, addr);
+}Has there been any decision on how to split/integrate cec from drm? Or is there display stuff located in cec i2c slave (I see HPD in ..._detect below)?
Quoted 3 lines
not sure, but at least in this case it can't really be decoupled. I need to use the CEC interface for HPD (as you noticed) and also to power up the HDMI bits..
Just to make things clearer here, TDA998x ususally has two i2c slaves at power-up, 0x70 (hdmi slave) and 0x34 (cec slave). Are you actually accessing the cec slave?
[...]
Quoted 20 lines
Quoted 11 lines
Quoted 11 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +11
-0+static bool +tda998x_encoder_mode_fixup (struct drm_encoder *encoder, +const struct drm_display_mode *mode, +struct drm_display_mode *adjusted_mode) +{ +return true; +} + +static int +tda998x_encoder_mode_valid (struct drm_encoder *encoder, +struct drm_display_mode *mode)Quoted 8 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 489
Quoted 3 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +3
-0+{ +return MODE_OK ; +}At least a note would be helpful to see what callbacks are not yet done. I guess there will be some kind of mode check someday?
Quoted 5 lines
Well, some of these drm will assume the fxn ptrs are not null, so we need something even if it is empty.
I suppose there are must be some upper bounds on pixel clock supported, which could perhaps be added some day in
_mode_valid(). On
Depends what drm expects on mode_valid or mode_fixup, I haven't dug into drm encoders, yet. But usually for HDMI/DVI you will only choose between modes supplied by monitor EDID and not choose something "close". Anyway, I just think a note about stuff that is not yet working is helpful.
Quoted 9 lines
the device I am working on, the limiting factor is the crtc (upstream of the encoder), so I haven't really needed this yet. I expect that as people start using this on some other devices, we'll come across some enhancements needed, some places where we need to add some configuration, etc. I cannot really predict exactly what is needed, so I prefer just to put the driver out there in some form, and then add it it as needed. So, I wouldn't really say that these functions are "TODO", but I also wouldn't say that we won't find some reason to add some code there at some point.
Or put it in staging?
Quoted 15 lines
Quoted 14 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 625
Quoted 10 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +8
-0+static enum drm_connector_status +tda998x_encoder_detect (struct drm_encoder *encoder, +struct drm_connector *connector) +{ +uint8_t val =cec_read (encoder,REG_CEC_RXSHPDLEV ); +return (val&CEC_RXSHPDLEV_HPD ) ? connector_status_connected : + connector_status_disconnected; +}This is where cec slave gets called from hdmi i2c driver. Any chance there is HPD status in hdmi registers, too?
Quoted 4 lines
Not that I know of. But like I mentioned, we also need to use the CEC interface just to talk to the HDMI interface. Before setting ENAMODS reg via cec address, the hdmi address won't even show up (for ex, on i2cdetect).
Again, I quickly checked the public sources. The cec slave looks like is only for cec communication, i.e. actually sending/receiving messages. But from your patch it isn't even clear to me, when you access hdmi or cec slave as you are bypassing i2c client subsystem somehow.
Quoted 4 lines
Maybe there is some way that this code should register some interface with CEC driver/subsystem? (Is there such a thing? I am not really CEC expert.) But I don't think there is any way to completely split it out.
When speaking about CEC subsystem you mean sending/receiving cec messages and the corresponding kernel API? That can come later, for now everything this driver needs can IMHO depend on EDID, i.e. DVI-style, only. CEC communication can come later.
Quoted 18 lines
Quoted 9 lines
Quoted 9 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +9
-0+/* I2C driver functions */ + +static int +tda998x_probe (struct i2c_client *client,const struct i2c_device_id *id) +{ +return 0 ; +} + +static intQuoted 8 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 796
Quoted 4 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +4
-0+tda998x_remove(struct i2c_client *client) +{ +return 0 ; +}Hmm, empty
_probeand_remove? Maybe these should get some code from_initbelow?
Quoted 1 line
naw, they aren't really used for drm i2c encoder slaves.
Well, if you use a i2c_client_addr != 0 below, the i2c subsystem will only bother you if it finds e.g. device 0x70 on an i2c bus. So they should be used. The drm API must be clear about what should happen in encoder_init and encoder_probe.
Quoted 38 lines
Quoted 28 lines
Quoted 28 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +27
-0+static int +tda998x_encoder_init (struct i2c_client *client, +struct drm_device *dev, +struct drm_encoder_slave *encoder_slave) +{ +struct drm_encoder *encoder =&encoder_slave->base; +struct tda998x_priv *priv; + + priv =kzalloc (sizeof (*priv),GFP_KERNEL ); +if (!priv) +return -ENOMEM ; + + priv->current_page =0 ; + priv->cec =i2c_new_dummy (client->adapter,0x34 ); + priv->dpms =DRM_MODE_DPMS_OFF ; + + encoder_slave->slave_priv = priv; + encoder_slave->slave_funcs =&tda998x_encoder_funcs; + +/* wake up the device: */ +cec_write (encoder,REG_CEC_ENAMODS , +CEC_ENAMODS_EN_RXSENS |CEC_ENAMODS_EN_HDMI ); + +tda998x_reset (encoder); + +/* read version: */ + priv->rev = reg_read(encoder, REG_VERSION_LSB) |Quoted 9 lines
drivers/gpu/drm/i2c/tda998x_drv.c
Quoted 4 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +4
-0+reg_read (encoder,REG_VERSION_MSB )<<8 ; + +/* mask off feature bits: */ + priv->rev&= ~0x30 ;/* not-hdcp and not-scalar bit */ If revision register contains features, why not save them for later driver improvements?
Quoted 3 lines
can be added later if the need arises. I prefer to leave out code that only might be used later.. otherwise it is a good way to accumulate cruft.
True, but magic masking (~0x30) and some comments don't help either.
Quoted 23 lines
Quoted 23 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 838
Quoted 10 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +9
-0+switch (priv->rev) { +case TDA9989N2 :dev_info (dev->dev,"found TDA9989 n2" );break ; +case TDA19989 :dev_info (dev->dev,"found TDA19989" );break ; +case TDA19989N2 :dev_info (dev->dev,"found TDA19989 n2" );break ; +case TDA19988 :dev_info (dev->dev,"found TDA19988" );break ; +default : +DBG ("found unsupported device: %04x" , priv->rev); + goto fail; + }I think printing revision is sufficient, no user will care about the actual device or revision.
Quoted 5 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +5
-0+/* after reset, enable DDC: */ +reg_write (encoder,REG_DDC_DISABLE ,0x00 ); + +/* set clock on DDC channel: */ +reg_write (encoder,REG_TX3 ,39 );
Quoted 7 lines
Quoted 3 lines
This should be kept disabled as long as there is no monitor attached (HPD!)
The sequence is based on NXP's driver.. I'll have to go back and check, but IIRC there were a few things I had to turn on just to make HPD work in the first place.
Hmm, I have seen a note about issues with some monitors that expect ddc clock to be stable very early. And this looks like the NXP proposed workaround to always clock ddc - but it tells nothing about the reason and more important the note from NXP clearly puts some restrictions on how hdmi tx needs to be clocked by pixclk. Can you ensure a stable pixclk at this point at all?
Quoted 3 lines
Ofc, if there were actually some decent docs about the part, it would be a bit easier to know what is actually required and what is not. So I don't claim everything in it's current form is optimal.
I know, everybody knows I guess. But that is what this list is for, discussing when a driver is ready to be mainlined. And without regmap and proper i2c client handling, I have a feeling that it is not close.
Quoted 32 lines
Quoted 22 lines
Quoted 22 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +6
-0+/* if necessary, disable multi-master: */ +if (priv->rev ==TDA19989 ) +reg_set (encoder,REG_I2C_MASTER ,I2C_MASTER_DIS_MM ); + + cec_write(encoder, REG_CEC_FRO_IM_CLK_CTRL, + CEC_FRO_IM_CLK_CTRL_GHOST_DIS |
CEC_FRO_IM_CLK_CTRL_IMCLK_SEL);drivers/gpu/drm/i2c/tda998x_drv.c new file +15
-0+ +return 0 ; + +fail: +/* if encoder_init fails, the encoder slave is never registered, +* so cleanup here: +*/ +if (priv->cec) +i2c_unregister_device (priv->cec); +kfree (priv); + encoder_slave->slave_priv =NULL ; + encoder_slave->slave_funcs =NULL ; +return -ENXIO ; +} +Quoted 9 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 871
Quoted 5 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +5
-0+static struct i2c_device_id tda998x_ids[] = { + {"tda998x" ,0 }, + { } +}; +MODULE_DEVICE_TABLE (i2c, tda998x_ids);Shouldn't the above carry the hdmi core i2c address at least?
Quoted 3 lines
no, it should come from the user of the encoder slave. Actually the CEC address should too, but current drm i2c encoder slave code sort of assumes the device just has a single address
Hmm, that is a limitation for sure. Well I checked drm_encoder_slave and it is calling i2c_register_driver directly. Passing a valid i2c slave address will work here.
For the cec i2c slave, we at least know that it is on the same i2c bus and can probe it during _init or _probe ourselves.
Sebastian
Re: [PATCH 2/4] drm/i2c: nxp-tda998x (v3)
Quoted 58 lines · Sebastian Hesselbarth
Quoted 5 lines · Rob Clark
Quoted 2 lines · Sebastian Hesselbarth
On 01/29/2013 06:23 PM, Rob Clark wrote:
[...]
Quoted 15 lines
Quoted 13 lines
Quoted 9 lines
(quoted diff) +2
-0+ +/* The TDA9988 series of devices use a paged register scheme.. tosimplify
+ * things we encode the page # in upper bits of the register #. To read/
+ * write a given register, we need to make sure CURPAGE register is set
+ * appropriately. Which implies reads/writes are not atomic. Fun!
+ */Please have a look at regmap-i2c, it also supports paged i2c registers and will save you _a
lot_of the i2c handling.Quoted 8 lines
Yeah, I have looked at it, and will eventually convert over to using it. The problems at the moment are that I don't really have enough documentation about the chip at the register level to properly use the caching modes, and from my digging through the regmap code it looked like paged regmap + non-caching will result in writes to the page register for every transaction. That, and a bit of docs or few more examples of using the paging support in regmap would be nice. For now, I am punting on regmap conversion.
Hmm, flipping through the public tda998x sources *sigh* I found a quite complete register list that also states if registers are RO or RW. Even if you are not using all registers you can still prevent regmap from reading/writing to them. But yes, documentation lacks some examples ;)
Quoted 14 lines
Quoted 4 lines
Quoted 4 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +3
-0+ +/* Device versions: */ +#define TDA9989N2 0x0101Quoted 8 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 263
Quoted 3 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +3
-0+#define TDA19989 0x0201 +#define TDA19989N2 0x0202 +#define TDA19988 0x0301Maybe split this into device_version/revision? What does N2 stand for or is this the name NXP uses for that device?
Quoted 3 lines
The register names are based on the names used in the NXP out-of-tree driver (the 50kloc monstrosity, if you've seen it).. that was pretty much all the register level documentation I had.
Quoted 5 lines
Yeah, but there is a comment about N2, that says the last bit is "not a register bit, but is derived by the driver from the new N5 registers..". I guess you will not see that many i2c devices returning you "N2" version registers..
hmm, maybe you are looking at a different (newer?) version of the nxp code? I did not see this. Perhaps the "n2" stuff isn't too critical, but I figured it would be nice to see if someone is trying to bring up a device with one of these parts and I ask them to send me a boot log with drm traces enabled
Quoted 24 lines
Quoted 24 lines
Quoted 22 lines
Quoted 14 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +10
-0+static void +cec_write (struct drm_encoder *encoder,uint16_t addr,uint8_t val) +{ +struct i2c_client *client =to_tda998x_priv (encoder)->cec; +uint8_t buf[] = {addr, val}; +int ret; + + ret =i2c_master_send (client, buf,ARRAY_SIZE (buf)); +if (ret<0 ) + dev_err(&client->dev, "Error %d writing to cec:0x%x\n",Quoted 2 lines
ret, addr);
+}Has there been any decision on how to split/integrate cec from drm? Or is there display stuff located in cec i2c slave (I see HPD in ..._detect below)?
Quoted 8 lines
Quoted 3 lines
not sure, but at least in this case it can't really be decoupled. I need to use the CEC interface for HPD (as you noticed) and also to power up the HDMI bits..
Just to make things clearer here, TDA998x ususally has two i2c slaves at power-up,
0x70(hdmi slave) and0x34(cec slave). Are you actually accessing the cec slave?
yes, as I mentioned, it is not possible to access the hdmi slave without first accessing the cec slave to enable the hdmi slave
Quoted 27 lines
[...]
Quoted 25 lines
Quoted 12 lines
Quoted 12 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +12
-0+static bool +tda998x_encoder_mode_fixup (struct drm_encoder *encoder, +const struct drm_display_mode *mode, +struct drm_display_mode *adjusted_mode) +{ +return true; +} + +static int +tda998x_encoder_mode_valid (struct drm_encoder *encoder, +struct drm_display_mode *mode) +{Quoted 8 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 489
Quoted 2 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +2
-0+return MODE_OK ; +}At least a note would be helpful to see what callbacks are not yet done. I guess there will be some kind of mode check someday?
Well, some of these drm will assume the fxn ptrs are not null, so we need something even if it is empty.
Quoted 9 lines
Quoted 2 lines
I suppose there are must be some upper bounds on pixel clock supported, which could perhaps be added some day in
_mode_valid(). OnDepends what drm expects on
mode_validormode_fixup, I haven't dug into drm encoders, yet. But usually for HDMI/DVI you will only choose between modes supplied by monitor EDID and not choose something "close". Anyway, I just think a note about stuff that is not yet working is helpful.
I would put a note if there was something that was not working about it ;-)
Currently there is no need to validate or fixup the mode, which is why these functions are empty. DRM has hooks for the drivers at many point. Not always are all of them needed, in this case they are not needed.
Quoted 12 lines
Quoted 10 lines
the device I am working on, the limiting factor is the crtc (upstream of the encoder), so I haven't really needed this yet. I expect that as people start using this on some other devices, we'll come across some enhancements needed, some places where we need to add some configuration, etc. I cannot really predict exactly what is needed, so I prefer just to put the driver out there in some form, and then add it it as needed. So, I wouldn't really say that these functions are "TODO", but I also wouldn't say that we won't find some reason to add some code there at some point.
Quoted 2 lines
Or put it in staging?
that won't work too well if we end up having to add a header and config info struct to be passed in from the driver using the encoder slave
Quoted 24 lines
Quoted 18 lines
Quoted 16 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 625
Quoted 11 lines
[...]
drivers/gpu/drm/i2c/tda998x_drv.c new file +8
-0+static enum drm_connector_status +tda998x_encoder_detect (struct drm_encoder *encoder, +struct drm_connector *connector) +{ +uint8_t val =cec_read (encoder,REG_CEC_RXSHPDLEV ); +return (val&CEC_RXSHPDLEV_HPD ) ? connector_status_connected : + connector_status_disconnected; +}This is where cec slave gets called from hdmi i2c driver. Any chance there is HPD status in hdmi registers, too?
Quoted 4 lines
Not that I know of. But like I mentioned, we also need to use the CEC interface just to talk to the HDMI interface. Before setting ENAMODS reg via cec address, the hdmi address won't even show up (for ex, on i2cdetect).
Quoted 5 lines
Again, I quickly checked the public sources. The cec slave looks like is only for cec communication, i.e. actually sending/receiving messages. But from your patch it isn't even clear to me, when you access hdmi or cec slave as you are bypassing i2c client subsystem somehow.
The cec_read()/cec_write() fxns use the cec i2c_client ptr. They are accessing the cec slave. I'm not really sure how that is unclear. There is not really anything being bypassed here.
Anyways, like I mentioned, the cec slave needs to be accessed before the hdmi slave can be accessed at all.
Quoted 7 lines
Quoted 5 lines
Maybe there is some way that this code should register some interface with CEC driver/subsystem? (Is there such a thing? I am not really CEC expert.) But I don't think there is any way to completely split it out.
Quoted 5 lines
When speaking about CEC subsystem you mean sending/receiving cec messages and the corresponding kernel API? That can come later, for now everything this driver needs can IMHO depend on EDID, i.e. DVI-style, only. CEC communication can come later.
Yes, presumably other than internal use (enabling hdmi subsystem, hpd, etc), the other interesting use for CEC would be to enable sending/receiving CEC messages. If there is some kernel subsystem for this, presumably the i2c encoder slave would need to register some sort of cec_adapter with this subsystem. I haven't really concerned myself with this too much. I expect enabling hdmi audio is probably the more interesting next-feature.
Quoted 22 lines
Quoted 22 lines
Quoted 20 lines
Quoted 6 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +4
-0+/* I2C driver functions */ + +static int +tda998x_probe(struct i2c_client *client, const struct i2c_device_id*id)
drivers/gpu/drm/i2c/tda998x_drv.c line 796
Quoted 9 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +9
-0+{ +return 0 ; +} + +static int +tda998x_remove (struct i2c_client *client) +{ +return 0 ; +}Hmm, empty
_probeand_remove? Maybe these should get some code from_initbelow?
Quoted 7 lines
Quoted 1 line
naw, they aren't really used for drm i2c encoder slaves.
Well, if you use a
i2c_client_addr!= 0 below, the i2c subsystem will only bother you if it finds e.g. device0x70on an i2c bus. So they should be used. The drm API must be clear about what should happen inencoder_initandencoder_probe.
btw, if you haven't already, please look at drm_i2c_encoder_init() to see how the i2c encoder slave is loaded and connected to it's master driver.
I suppose, in theory I could read the device version information in the _probe(). But this can't even be read until accessing the CEC interface to enable hdmi. So I end up reading the revision and potentially failing later. But for this hw, there isn't really a better way because of the goofy way that the hdmi interface cannot be accessed until after it is switched on via cec interface.
Quoted 82 lines
Quoted 40 lines
Quoted 30 lines
Quoted 30 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +28
-0+static int +tda998x_encoder_init (struct i2c_client *client, +struct drm_device *dev, +struct drm_encoder_slave *encoder_slave) +{ +struct drm_encoder *encoder =&encoder_slave->base; +struct tda998x_priv *priv; + + priv =kzalloc (sizeof (*priv),GFP_KERNEL ); +if (!priv) +return -ENOMEM ; + + priv->current_page =0 ; + priv->cec =i2c_new_dummy (client->adapter,0x34 ); + priv->dpms =DRM_MODE_DPMS_OFF ; + + encoder_slave->slave_priv = priv; + encoder_slave->slave_funcs =&tda998x_encoder_funcs; + +/* wake up the device: */ +cec_write (encoder,REG_CEC_ENAMODS , +CEC_ENAMODS_EN_RXSENS |CEC_ENAMODS_EN_HDMI ); + +tda998x_reset (encoder); + +/* read version: */ + priv->rev =reg_read (encoder,REG_VERSION_LSB ) | +reg_read (encoder,REG_VERSION_MSB )<<8 ;Quoted 9 lines
drivers/gpu/drm/i2c/tda998x_drv.c
Quoted 3 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +3
-0+ +/* mask off feature bits: */ + priv->rev&= ~0x30 ;/* not-hdcp and not-scalar bit */ If revision register contains features, why not save them for later driver improvements?
Quoted 3 lines
can be added later if the need arises. I prefer to leave out code that only might be used later.. otherwise it is a good way to accumulate cruft.
True, but magic masking (~0x30) and some comments don't help either.
Quoted 25 lines
Quoted 25 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 838
Quoted 10 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +9
-0+switch (priv->rev) { +case TDA9989N2 :dev_info (dev->dev,"found TDA9989 n2" );break ; +case TDA19989 :dev_info (dev->dev,"found TDA19989" );break ; +case TDA19989N2 :dev_info (dev->dev,"found TDA19989 n2" );break ; +case TDA19988 :dev_info (dev->dev,"found TDA19988" );break ; +default : +DBG ("found unsupported device: %04x" , priv->rev); + goto fail; + }I think printing revision is sufficient, no user will care about the actual device or revision.
Quoted 5 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +5
-0+/* after reset, enable DDC: */ +reg_write (encoder,REG_DDC_DISABLE ,0x00 ); + +/* set clock on DDC channel: */ +reg_write (encoder,REG_TX3 ,39 );Quoted 7 lines
Quoted 3 lines
This should be kept disabled as long as there is no monitor attached (HPD!)
The sequence is based on NXP's driver.. I'll have to go back and check, but IIRC there were a few things I had to turn on just to make HPD work in the first place.
Quoted 7 lines
Hmm, I have seen a note about issues with some monitors that expect ddc clock to be stable very early. And this looks like the NXP proposed workaround to always clock ddc - but it tells nothing about the reason and more important the note from NXP clearly puts some restrictions on how hdmi tx needs to be clocked by pixclk. Can you ensure a stable pixclk at this point at all?
In my experience it is not depending on pixel clock from crtc. Or at least it isn't turned on at this point and doesn't seem to cause issues. The drm core will not enable the crtc until long after the edid is read.
Quoted 10 lines
Quoted 4 lines
Ofc, if there were actually some decent docs about the part, it would be a bit easier to know what is actually required and what is not. So I don't claim everything in it's current form is optimal.
I know, everybody knows I guess. But that is what this list is for, discussing when a driver is ready to be mainlined. And without regmap and proper i2c client handling, I have a feeling that it is not close.
There is not really anything wrong with the i2c client handling, or rather it works the way that drm i2c encoder slave infrastructure expects.
regmap, I'd partially agree.. I'd prefer to use it. But it doesn't really bring that much benefit and the requirements are a bit steep considering what is known / not-known about this hw.
Quoted 39 lines
Quoted 34 lines
Quoted 24 lines
Quoted 24 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +6
-0+/* if necessary, disable multi-master: */ +if (priv->rev ==TDA19989 ) +reg_set (encoder,REG_I2C_MASTER ,I2C_MASTER_DIS_MM ); + + cec_write(encoder, REG_CEC_FRO_IM_CLK_CTRL, + CEC_FRO_IM_CLK_CTRL_GHOST_DIS |
CEC_FRO_IM_CLK_CTRL_IMCLK_SEL);drivers/gpu/drm/i2c/tda998x_drv.c new file +16
-0+ +return 0 ; + +fail: +/* if encoder_init fails, the encoder slave is never registered, +* so cleanup here: +*/ +if (priv->cec) +i2c_unregister_device (priv->cec); +kfree (priv); + encoder_slave->slave_priv =NULL ; + encoder_slave->slave_funcs =NULL ; +return -ENXIO ; +} + +static struct i2c_device_id tda998x_ids[] = {Quoted 9 lines
drivers/gpu/drm/i2c/tda998x_drv.c line 871
Quoted 4 lines
drivers/gpu/drm/i2c/tda998x_drv.c new file +4
-0+ { "tda998x", 0 }, + { } +}; +MODULE_DEVICE_TABLE (i2c, tda998x_ids);Shouldn't the above carry the hdmi core i2c address at least?
Quoted 3 lines
no, it should come from the user of the encoder slave. Actually the CEC address should too, but current drm i2c encoder slave code sort of assumes the device just has a single address
Quoted 4 lines
Hmm, that is a limitation for sure. Well I checked
drm_encoder_slaveand it is callingi2c_register_driverdirectly. Passing a valid i2c slave address
will work here.
note that the hdmi interface cannot be probed until after enabling it via cec interface
BR,
-R
Quoted 4 lines
For the cec i2c slave, we at least know that it is on the same i2c bus and can probe it during
_initor_probeourselves.Sebastian
PATCH 3/4 drm/tilcdc: add encoder slave (v2)
In reply to Rob ClarkAdd output panel driver for i2c encoder slaves.
v1: original
v2: add DT bindings docs, and minor updates for review comments
--- .../devicetree/bindings/drm/tilcdc/slave.txt | 19 ++ drivers/gpu/drm/tilcdc/Makefile | 1 + drivers/gpu/drm/tilcdc/tilcdc_drv.c | 5 +- drivers/gpu/drm/tilcdc/tilcdc_slave.c | 376 +++++++++++++++++++++ drivers/gpu/drm/tilcdc/tilcdc_slave.h | 26 ++ 5 files changed, 426 insertions(+), 1 deletion(-) create mode 100644 Documentation/devicetree/bindings/drm/tilcdc/slave.txt create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave.c create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_slave.h
Documentation/devicetree/bindings/drm/tilcdc/slave.txt new file +19 -0
@@ -0,0 +1,19 @@ +Device-Tree bindings for tilcdc DRM encoder slave output driver + +Required properties: + - compatible: value should be "tilcdc,slave". + - i2c: the phandle for the i2c device the encoder slave is connected to + +Recommended properties: + - pinctrl-names, pinctrl-0: the pincontrol settings to configure + muxing properly for pins that connect to TFP410 device + +Example: + + hdmi { + compatible = "tilcdc,slave"; + i2c = <&i2c0>; + pinctrl-names = "default"; + pinctrl-0 = <&nxp_hdmi_bonelt_pins>; + }; +
drivers/gpu/drm/tilcdc/Makefile +1 -0
@@ -3,6 +3,7 @@ ccflags-y := -Iinclude/drm -Werror tilcdc-y := \ tilcdc_crtc.o \ tilcdc_tfp410.o \ + tilcdc_slave.o \ tilcdc_drv.o obj-$(CONFIG_DRM_TILCDC) += tilcdc.o
drivers/gpu/drm/tilcdc/tilcdc_drv.c +4 -1
@@ -20,6 +20,7 @@#include "tilcdc_drv.h" #include "tilcdc_regs.h" #include "tilcdc_tfp410.h" +#include "tilcdc_slave.h" #include "drm_fb_helper.h"
@@ -587,6 +588,7 @@ static int __init tilcdc_drm_init(void) {DBG ("init" );tilcdc_tfp410_init (); +tilcdc_slave_init ();return platform_driver_register (&tilcdc_platform_driver); }
@@ -594,10 +596,11 @@ static void __exit tilcdc_drm_fini(void) {DBG ("fini" );tilcdc_tfp410_fini (); +tilcdc_slave_fini ();platform_driver_unregister (&tilcdc_platform_driver); } -module_init (tilcdc_drm_init); +late_initcall (tilcdc_drm_init);module_exit (tilcdc_drm_fini);MODULE_AUTHOR ("Rob Clark <[email protected]" );
drivers/gpu/drm/tilcdc/tilcdc_slave.c new file +376 -0
376 lines not on this page · raw message
drivers/gpu/drm/tilcdc/tilcdc_slave.h new file +26 -0
@@ -0,0 +1,26 @@ +/* +* Copyright (C) 2012 Texas Instruments +* Author: Rob Clark <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 as published by +* the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __TILCDC_SLAVE_H__ +#define __TILCDC_SLAVE_H__ + +/* sub-module for i2c slave encoder output */ + +int tilcdc_slave_init (void ); +void tilcdc_slave_fini (void ); + +#endif /* __TILCDC_SLAVE_H__ */
Signature · 1 line
1.8.1
PATCH 4/4 drm/tilcdc: add support for LCD panels (v5)
In reply to Rob ClarkAdd an output panel driver for LCD panels. Tested with LCD3 cape on beaglebone.
v1: original
v2: s/of_find_node_by_name()/of_get_child_by_name()/ from Pantelis
Antoniou
v3: add backlight support
v4: rebase to latest of video timing helpers
v5: remove some unneeded fields from panel-info struct, add DT bindings
docs
--- .../devicetree/bindings/drm/tilcdc/panel.txt | 59 +++ drivers/gpu/drm/tilcdc/Kconfig | 3 + drivers/gpu/drm/tilcdc/Makefile | 1 + drivers/gpu/drm/tilcdc/tilcdc_drv.c | 3 + drivers/gpu/drm/tilcdc/tilcdc_panel.c | 436 +++++++++++++++++++++ drivers/gpu/drm/tilcdc/tilcdc_panel.h | 26 ++ 6 files changed, 528 insertions(+) create mode 100644 Documentation/devicetree/bindings/drm/tilcdc/panel.txt create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_panel.c create mode 100644 drivers/gpu/drm/tilcdc/tilcdc_panel.h
Documentation/devicetree/bindings/drm/tilcdc/panel.txt new file +59 -0
@@ -0,0 +1,59 @@ +Device-Tree bindings for tilcdc DRM generic panel output driver + +Required properties: + - compatible: value should be "tilcdc,panel". + - panel-info: configuration info to configure LCDC correctly for the panel + - ac-bias: AC Bias Pin Frequency + - ac-bias-intrpt: AC Bias Pin Transitions per Interrupt + - dma-burst-sz: DMA burst size + - bpp: Bits per pixel + - fdd: FIFO DMA Request Delay + - sync-edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling + - sync-ctrl: Horizontal and Vertical Sync: Control: 0=ignore + - raster-order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most + - fifo-th: DMA FIFO threshold + - display-timings: typical videomode of lcd panel. Multiple video modes + can be listed if the panel supports multiple timings, but the 'native-mode' + should be the preferred/default resolution. Refer to + Documentation/devicetree/bindings/video/display-timing.txt for display + timing binding details. + +Recommended properties: + - pinctrl-names, pinctrl-0: the pincontrol settings to configure + muxing properly for pins that connect to TFP410 device + +Example: + + /* Settings for CDTech_S035Q01 / LCD3 cape: */ + lcd3 { + compatible = "tilcdc,panel"; + pinctrl-names = "default"; + pinctrl-0 = <&bone_lcd3_cape_lcd_pins>; + panel-info { + ac-bias = <255>; + ac-bias-intrpt = <0>; + dma-burst-sz = <16>; + bpp = <16>; + fdd = <0x80>; + sync-edge = <0>; + sync-ctrl = <1>; + raster-order = <0>; + fifo-th = <0>; + }; + display-timings { + native-mode = <&timing0>; + timing0: 320x240 { + hactive = <320>; + vactive = <240>; + hback-porch = <21>; + hfront-porch = <58>; + hsync-len = <47>; + vback-porch = <11>; + vfront-porch = <23>; + vsync-len = <2>; + clock-frequency = <8000000>; + hsync-active = <0>; + vsync-active = <0>; + }; + }; + };
drivers/gpu/drm/tilcdc/Kconfig +3 -0
@@ -4,6 +4,9 @@ config DRM_TILCDC select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER select DRM_GEM_CMA_HELPER + select OF_VIDEOMODE + select OF_DISPLAY_TIMING + select BACKLIGHT_CLASS_DEVICE help Choose this option if you have an TI SoC with LCDC display controller, for example AM33xx in beagle-bone, DA8xx, or
drivers/gpu/drm/tilcdc/Makefile +1 -0
@@ -4,6 +4,7 @@ tilcdc-y := \ tilcdc_crtc.o \ tilcdc_tfp410.o \ tilcdc_slave.o \ + tilcdc_panel.o \ tilcdc_drv.o obj-$(CONFIG_DRM_TILCDC) += tilcdc.o
drivers/gpu/drm/tilcdc/tilcdc_drv.c +3 -0
@@ -21,6 +21,7 @@#include "tilcdc_regs.h" #include "tilcdc_tfp410.h" #include "tilcdc_slave.h" +#include "tilcdc_panel.h" #include "drm_fb_helper.h"
@@ -589,6 +590,7 @@ static int __init tilcdc_drm_init(void)DBG ("init" );tilcdc_tfp410_init ();tilcdc_slave_init (); +tilcdc_panel_init ();return platform_driver_register (&tilcdc_platform_driver); }
@@ -597,6 +599,7 @@ static void __exit tilcdc_drm_fini(void)DBG ("fini" );tilcdc_tfp410_fini ();tilcdc_slave_fini (); +tilcdc_panel_fini ();platform_driver_unregister (&tilcdc_platform_driver); }
drivers/gpu/drm/tilcdc/tilcdc_panel.c new file +436 -0
436 lines not on this page · raw message
drivers/gpu/drm/tilcdc/tilcdc_panel.h new file +26 -0
@@ -0,0 +1,26 @@ +/* +* Copyright (C) 2012 Texas Instruments +* Author: Rob Clark <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 as published by +* the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along with +* this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __TILCDC_PANEL_H__ +#define __TILCDC_PANEL_H__ + +/* sub-module for generic lcd panel output */ + +int tilcdc_panel_init (void ); +void tilcdc_panel_fini (void ); + +#endif /* __TILCDC_PANEL_H__ */
Signature · 1 line
1.8.1