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

Merge branch 'tilcdc-next' of git://people.freedesktop.org/~robclark/linux into drm-next

KMS driver for TI LCD controller

* 'tilcdc-next' of git://people.freedesktop.org/~robclark/linux:
drm/tilcdc: add support for LCD panels (v5)
drm/tilcdc: add encoder slave (v2)
drm/i2c: nxp-tda998x (v3)
drm/tilcdc: add TI LCD Controller DRM driver (v4)
drm/nouveau: use i2c encoder helper wrappers
drm: i2c encoder helper wrappers
drm/cma: add debugfs helpers
drm: small fix in drm_send_vblank_event()
drm: Don't set the plane->fb to NULL on successfull set_plane
drm/cma-helper: fixup compilation

Conflicts:
drivers/gpu/drm/Kconfig
drivers/gpu/drm/Makefile
drivers/gpu/drm/drm_fb_cma_helper.c

+4066 -26
+59
Documentation/devicetree/bindings/drm/tilcdc/panel.txt
··· 1 + Device-Tree bindings for tilcdc DRM generic panel output driver 2 + 3 + Required properties: 4 + - compatible: value should be "ti,tilcdc,panel". 5 + - panel-info: configuration info to configure LCDC correctly for the panel 6 + - ac-bias: AC Bias Pin Frequency 7 + - ac-bias-intrpt: AC Bias Pin Transitions per Interrupt 8 + - dma-burst-sz: DMA burst size 9 + - bpp: Bits per pixel 10 + - fdd: FIFO DMA Request Delay 11 + - sync-edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling 12 + - sync-ctrl: Horizontal and Vertical Sync: Control: 0=ignore 13 + - raster-order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most 14 + - fifo-th: DMA FIFO threshold 15 + - display-timings: typical videomode of lcd panel. Multiple video modes 16 + can be listed if the panel supports multiple timings, but the 'native-mode' 17 + should be the preferred/default resolution. Refer to 18 + Documentation/devicetree/bindings/video/display-timing.txt for display 19 + timing binding details. 20 + 21 + Recommended properties: 22 + - pinctrl-names, pinctrl-0: the pincontrol settings to configure 23 + muxing properly for pins that connect to TFP410 device 24 + 25 + Example: 26 + 27 + /* Settings for CDTech_S035Q01 / LCD3 cape: */ 28 + lcd3 { 29 + compatible = "ti,tilcdc,panel"; 30 + pinctrl-names = "default"; 31 + pinctrl-0 = <&bone_lcd3_cape_lcd_pins>; 32 + panel-info { 33 + ac-bias = <255>; 34 + ac-bias-intrpt = <0>; 35 + dma-burst-sz = <16>; 36 + bpp = <16>; 37 + fdd = <0x80>; 38 + sync-edge = <0>; 39 + sync-ctrl = <1>; 40 + raster-order = <0>; 41 + fifo-th = <0>; 42 + }; 43 + display-timings { 44 + native-mode = <&timing0>; 45 + timing0: 320x240 { 46 + hactive = <320>; 47 + vactive = <240>; 48 + hback-porch = <21>; 49 + hfront-porch = <58>; 50 + hsync-len = <47>; 51 + vback-porch = <11>; 52 + vfront-porch = <23>; 53 + vsync-len = <2>; 54 + clock-frequency = <8000000>; 55 + hsync-active = <0>; 56 + vsync-active = <0>; 57 + }; 58 + }; 59 + };
+18
Documentation/devicetree/bindings/drm/tilcdc/slave.txt
··· 1 + Device-Tree bindings for tilcdc DRM encoder slave output driver 2 + 3 + Required properties: 4 + - compatible: value should be "ti,tilcdc,slave". 5 + - i2c: the phandle for the i2c device the encoder slave is connected to 6 + 7 + Recommended properties: 8 + - pinctrl-names, pinctrl-0: the pincontrol settings to configure 9 + muxing properly for pins that connect to TFP410 device 10 + 11 + Example: 12 + 13 + hdmi { 14 + compatible = "ti,tilcdc,slave"; 15 + i2c = <&i2c0>; 16 + pinctrl-names = "default"; 17 + pinctrl-0 = <&nxp_hdmi_bonelt_pins>; 18 + };
+21
Documentation/devicetree/bindings/drm/tilcdc/tfp410.txt
··· 1 + Device-Tree bindings for tilcdc DRM TFP410 output driver 2 + 3 + Required properties: 4 + - compatible: value should be "ti,tilcdc,tfp410". 5 + - i2c: the phandle for the i2c device to use for DDC 6 + 7 + Recommended properties: 8 + - pinctrl-names, pinctrl-0: the pincontrol settings to configure 9 + muxing properly for pins that connect to TFP410 device 10 + - powerdn-gpio: the powerdown GPIO, pulled low to power down the 11 + TFP410 device (for DPMS_OFF) 12 + 13 + Example: 14 + 15 + dvicape { 16 + compatible = "ti,tilcdc,tfp410"; 17 + i2c = <&i2c2>; 18 + pinctrl-names = "default"; 19 + pinctrl-0 = <&bone_dvi_cape_dvi_00A1_pins>; 20 + powerdn-gpio = <&gpio2 31 0>; 21 + };
+21
Documentation/devicetree/bindings/drm/tilcdc/tilcdc.txt
··· 1 + Device-Tree bindings for tilcdc DRM driver 2 + 3 + Required properties: 4 + - compatible: value should be "ti,am33xx-tilcdc". 5 + - interrupts: the interrupt number 6 + - reg: base address and size of the LCDC device 7 + 8 + Recommended properties: 9 + - interrupt-parent: the phandle for the interrupt controller that 10 + services interrupts for this device. 11 + - ti,hwmods: Name of the hwmod associated to the LCDC 12 + 13 + Example: 14 + 15 + fb: fb@4830e000 { 16 + compatible = "ti,am33xx-tilcdc"; 17 + reg = <0x4830e000 0x1000>; 18 + interrupt-parent = <&intc>; 19 + interrupts = <36>; 20 + ti,hwmods = "lcdc"; 21 + };
+2
drivers/gpu/drm/Kconfig
··· 217 217 source "drivers/gpu/drm/tegra/Kconfig" 218 218 219 219 source "drivers/gpu/drm/omapdrm/Kconfig" 220 + 221 + source "drivers/gpu/drm/tilcdc/Kconfig"
+1
drivers/gpu/drm/Makefile
··· 51 51 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/ 52 52 obj-$(CONFIG_DRM_TEGRA) += tegra/ 53 53 obj-$(CONFIG_DRM_OMAP) += omapdrm/ 54 + obj-$(CONFIG_DRM_TILCDC) += tilcdc/ 54 55 obj-y += i2c/
+63
drivers/gpu/drm/drm_encoder_slave.c
··· 123 123 module_put(module); 124 124 } 125 125 EXPORT_SYMBOL(drm_i2c_encoder_destroy); 126 + 127 + /* 128 + * Wrapper fxns which can be plugged in to drm_encoder_helper_funcs: 129 + */ 130 + 131 + static inline struct drm_encoder_slave_funcs * 132 + get_slave_funcs(struct drm_encoder *enc) 133 + { 134 + return to_encoder_slave(enc)->slave_funcs; 135 + } 136 + 137 + void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode) 138 + { 139 + get_slave_funcs(encoder)->dpms(encoder, mode); 140 + } 141 + EXPORT_SYMBOL(drm_i2c_encoder_dpms); 142 + 143 + bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder, 144 + const struct drm_display_mode *mode, 145 + struct drm_display_mode *adjusted_mode) 146 + { 147 + return get_slave_funcs(encoder)->mode_fixup(encoder, mode, adjusted_mode); 148 + } 149 + EXPORT_SYMBOL(drm_i2c_encoder_mode_fixup); 150 + 151 + void drm_i2c_encoder_prepare(struct drm_encoder *encoder) 152 + { 153 + drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); 154 + } 155 + EXPORT_SYMBOL(drm_i2c_encoder_prepare); 156 + 157 + void drm_i2c_encoder_commit(struct drm_encoder *encoder) 158 + { 159 + drm_i2c_encoder_dpms(encoder, DRM_MODE_DPMS_ON); 160 + } 161 + EXPORT_SYMBOL(drm_i2c_encoder_commit); 162 + 163 + void drm_i2c_encoder_mode_set(struct drm_encoder *encoder, 164 + struct drm_display_mode *mode, 165 + struct drm_display_mode *adjusted_mode) 166 + { 167 + get_slave_funcs(encoder)->mode_set(encoder, mode, adjusted_mode); 168 + } 169 + EXPORT_SYMBOL(drm_i2c_encoder_mode_set); 170 + 171 + enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder, 172 + struct drm_connector *connector) 173 + { 174 + return get_slave_funcs(encoder)->detect(encoder, connector); 175 + } 176 + EXPORT_SYMBOL(drm_i2c_encoder_detect); 177 + 178 + void drm_i2c_encoder_save(struct drm_encoder *encoder) 179 + { 180 + get_slave_funcs(encoder)->save(encoder); 181 + } 182 + EXPORT_SYMBOL(drm_i2c_encoder_save); 183 + 184 + void drm_i2c_encoder_restore(struct drm_encoder *encoder) 185 + { 186 + get_slave_funcs(encoder)->restore(encoder); 187 + } 188 + EXPORT_SYMBOL(drm_i2c_encoder_restore);
+53
drivers/gpu/drm/drm_fb_cma_helper.c
··· 180 180 } 181 181 EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj); 182 182 183 + #ifdef CONFIG_DEBUG_FS 184 + /** 185 + * drm_fb_cma_describe() - Helper to dump information about a single 186 + * CMA framebuffer object 187 + */ 188 + void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m) 189 + { 190 + struct drm_fb_cma *fb_cma = to_fb_cma(fb); 191 + int i, n = drm_format_num_planes(fb->pixel_format); 192 + 193 + seq_printf(m, "fb: %dx%d@%4.4s\n", fb->width, fb->height, 194 + (char *)&fb->pixel_format); 195 + 196 + for (i = 0; i < n; i++) { 197 + seq_printf(m, " %d: offset=%d pitch=%d, obj: ", 198 + i, fb->offsets[i], fb->pitches[i]); 199 + drm_gem_cma_describe(fb_cma->obj[i], m); 200 + } 201 + } 202 + EXPORT_SYMBOL_GPL(drm_fb_cma_describe); 203 + 204 + /** 205 + * drm_fb_cma_debugfs_show() - Helper to list CMA framebuffer objects 206 + * in debugfs. 207 + */ 208 + int drm_fb_cma_debugfs_show(struct seq_file *m, void *arg) 209 + { 210 + struct drm_info_node *node = (struct drm_info_node *) m->private; 211 + struct drm_device *dev = node->minor->dev; 212 + struct drm_framebuffer *fb; 213 + int ret; 214 + 215 + ret = mutex_lock_interruptible(&dev->mode_config.mutex); 216 + if (ret) 217 + return ret; 218 + 219 + ret = mutex_lock_interruptible(&dev->struct_mutex); 220 + if (ret) { 221 + mutex_unlock(&dev->mode_config.mutex); 222 + return ret; 223 + } 224 + 225 + list_for_each_entry(fb, &dev->mode_config.fb_list, head) 226 + drm_fb_cma_describe(fb, m); 227 + 228 + mutex_unlock(&dev->struct_mutex); 229 + mutex_unlock(&dev->mode_config.mutex); 230 + 231 + return 0; 232 + } 233 + EXPORT_SYMBOL_GPL(drm_fb_cma_debugfs_show); 234 + #endif 235 + 183 236 static struct fb_ops drm_fbdev_cma_ops = { 184 237 .owner = THIS_MODULE, 185 238 .fb_fillrect = sys_fillrect,
+21
drivers/gpu/drm/drm_gem_cma_helper.c
··· 249 249 return drm_gem_handle_delete(file_priv, handle); 250 250 } 251 251 EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_destroy); 252 + 253 + #ifdef CONFIG_DEBUG_FS 254 + void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m) 255 + { 256 + struct drm_gem_object *obj = &cma_obj->base; 257 + struct drm_device *dev = obj->dev; 258 + uint64_t off = 0; 259 + 260 + WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 261 + 262 + if (obj->map_list.map) 263 + off = (uint64_t)obj->map_list.hash.key; 264 + 265 + seq_printf(m, "%2d (%2d) %08llx %08Zx %p %d", 266 + obj->name, obj->refcount.refcount.counter, 267 + off, cma_obj->paddr, cma_obj->vaddr, obj->size); 268 + 269 + seq_printf(m, "\n"); 270 + } 271 + EXPORT_SYMBOL_GPL(drm_gem_cma_describe); 272 + #endif
+1
drivers/gpu/drm/drm_irq.c
··· 867 867 868 868 now = get_drm_timestamp(); 869 869 } 870 + e->pipe = crtc; 870 871 send_vblank_event(dev, e, seq, &now); 871 872 } 872 873 EXPORT_SYMBOL(drm_send_vblank_event);
+6
drivers/gpu/drm/i2c/Kconfig
··· 19 19 when used in pairs) TMDS transmitters, used in some nVidia 20 20 video cards. 21 21 22 + config DRM_I2C_NXP_TDA998X 23 + tristate "NXP Semiconductors TDA998X HDMI encoder" 24 + default m if DRM_TILCDC 25 + help 26 + Support for NXP Semiconductors TDA998X HDMI encoders. 27 + 22 28 endmenu
+3
drivers/gpu/drm/i2c/Makefile
··· 5 5 6 6 sil164-y := sil164_drv.o 7 7 obj-$(CONFIG_DRM_I2C_SIL164) += sil164.o 8 + 9 + tda998x-y := tda998x_drv.o 10 + obj-$(CONFIG_DRM_I2C_NXP_TDA998X) += tda998x.o
+906
drivers/gpu/drm/i2c/tda998x_drv.c
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + 19 + 20 + #include <linux/module.h> 21 + 22 + #include <drm/drmP.h> 23 + #include <drm/drm_crtc_helper.h> 24 + #include <drm/drm_encoder_slave.h> 25 + #include <drm/drm_edid.h> 26 + 27 + 28 + #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 29 + 30 + struct tda998x_priv { 31 + struct i2c_client *cec; 32 + uint16_t rev; 33 + uint8_t current_page; 34 + int dpms; 35 + }; 36 + 37 + #define to_tda998x_priv(x) ((struct tda998x_priv *)to_encoder_slave(x)->slave_priv) 38 + 39 + /* The TDA9988 series of devices use a paged register scheme.. to simplify 40 + * things we encode the page # in upper bits of the register #. To read/ 41 + * write a given register, we need to make sure CURPAGE register is set 42 + * appropriately. Which implies reads/writes are not atomic. Fun! 43 + */ 44 + 45 + #define REG(page, addr) (((page) << 8) | (addr)) 46 + #define REG2ADDR(reg) ((reg) & 0xff) 47 + #define REG2PAGE(reg) (((reg) >> 8) & 0xff) 48 + 49 + #define REG_CURPAGE 0xff /* write */ 50 + 51 + 52 + /* Page 00h: General Control */ 53 + #define REG_VERSION_LSB REG(0x00, 0x00) /* read */ 54 + #define REG_MAIN_CNTRL0 REG(0x00, 0x01) /* read/write */ 55 + # define MAIN_CNTRL0_SR (1 << 0) 56 + # define MAIN_CNTRL0_DECS (1 << 1) 57 + # define MAIN_CNTRL0_DEHS (1 << 2) 58 + # define MAIN_CNTRL0_CECS (1 << 3) 59 + # define MAIN_CNTRL0_CEHS (1 << 4) 60 + # define MAIN_CNTRL0_SCALER (1 << 7) 61 + #define REG_VERSION_MSB REG(0x00, 0x02) /* read */ 62 + #define REG_SOFTRESET REG(0x00, 0x0a) /* write */ 63 + # define SOFTRESET_AUDIO (1 << 0) 64 + # define SOFTRESET_I2C_MASTER (1 << 1) 65 + #define REG_DDC_DISABLE REG(0x00, 0x0b) /* read/write */ 66 + #define REG_CCLK_ON REG(0x00, 0x0c) /* read/write */ 67 + #define REG_I2C_MASTER REG(0x00, 0x0d) /* read/write */ 68 + # define I2C_MASTER_DIS_MM (1 << 0) 69 + # define I2C_MASTER_DIS_FILT (1 << 1) 70 + # define I2C_MASTER_APP_STRT_LAT (1 << 2) 71 + #define REG_INT_FLAGS_0 REG(0x00, 0x0f) /* read/write */ 72 + #define REG_INT_FLAGS_1 REG(0x00, 0x10) /* read/write */ 73 + #define REG_INT_FLAGS_2 REG(0x00, 0x11) /* read/write */ 74 + # define INT_FLAGS_2_EDID_BLK_RD (1 << 1) 75 + #define REG_ENA_VP_0 REG(0x00, 0x18) /* read/write */ 76 + #define REG_ENA_VP_1 REG(0x00, 0x19) /* read/write */ 77 + #define REG_ENA_VP_2 REG(0x00, 0x1a) /* read/write */ 78 + #define REG_ENA_AP REG(0x00, 0x1e) /* read/write */ 79 + #define REG_VIP_CNTRL_0 REG(0x00, 0x20) /* write */ 80 + # define VIP_CNTRL_0_MIRR_A (1 << 7) 81 + # define VIP_CNTRL_0_SWAP_A(x) (((x) & 7) << 4) 82 + # define VIP_CNTRL_0_MIRR_B (1 << 3) 83 + # define VIP_CNTRL_0_SWAP_B(x) (((x) & 7) << 0) 84 + #define REG_VIP_CNTRL_1 REG(0x00, 0x21) /* write */ 85 + # define VIP_CNTRL_1_MIRR_C (1 << 7) 86 + # define VIP_CNTRL_1_SWAP_C(x) (((x) & 7) << 4) 87 + # define VIP_CNTRL_1_MIRR_D (1 << 3) 88 + # define VIP_CNTRL_1_SWAP_D(x) (((x) & 7) << 0) 89 + #define REG_VIP_CNTRL_2 REG(0x00, 0x22) /* write */ 90 + # define VIP_CNTRL_2_MIRR_E (1 << 7) 91 + # define VIP_CNTRL_2_SWAP_E(x) (((x) & 7) << 4) 92 + # define VIP_CNTRL_2_MIRR_F (1 << 3) 93 + # define VIP_CNTRL_2_SWAP_F(x) (((x) & 7) << 0) 94 + #define REG_VIP_CNTRL_3 REG(0x00, 0x23) /* write */ 95 + # define VIP_CNTRL_3_X_TGL (1 << 0) 96 + # define VIP_CNTRL_3_H_TGL (1 << 1) 97 + # define VIP_CNTRL_3_V_TGL (1 << 2) 98 + # define VIP_CNTRL_3_EMB (1 << 3) 99 + # define VIP_CNTRL_3_SYNC_DE (1 << 4) 100 + # define VIP_CNTRL_3_SYNC_HS (1 << 5) 101 + # define VIP_CNTRL_3_DE_INT (1 << 6) 102 + # define VIP_CNTRL_3_EDGE (1 << 7) 103 + #define REG_VIP_CNTRL_4 REG(0x00, 0x24) /* write */ 104 + # define VIP_CNTRL_4_BLC(x) (((x) & 3) << 0) 105 + # define VIP_CNTRL_4_BLANKIT(x) (((x) & 3) << 2) 106 + # define VIP_CNTRL_4_CCIR656 (1 << 4) 107 + # define VIP_CNTRL_4_656_ALT (1 << 5) 108 + # define VIP_CNTRL_4_TST_656 (1 << 6) 109 + # define VIP_CNTRL_4_TST_PAT (1 << 7) 110 + #define REG_VIP_CNTRL_5 REG(0x00, 0x25) /* write */ 111 + # define VIP_CNTRL_5_CKCASE (1 << 0) 112 + # define VIP_CNTRL_5_SP_CNT(x) (((x) & 3) << 1) 113 + #define REG_MAT_CONTRL REG(0x00, 0x80) /* write */ 114 + # define MAT_CONTRL_MAT_SC(x) (((x) & 3) << 0) 115 + # define MAT_CONTRL_MAT_BP (1 << 2) 116 + #define REG_VIDFORMAT REG(0x00, 0xa0) /* write */ 117 + #define REG_REFPIX_MSB REG(0x00, 0xa1) /* write */ 118 + #define REG_REFPIX_LSB REG(0x00, 0xa2) /* write */ 119 + #define REG_REFLINE_MSB REG(0x00, 0xa3) /* write */ 120 + #define REG_REFLINE_LSB REG(0x00, 0xa4) /* write */ 121 + #define REG_NPIX_MSB REG(0x00, 0xa5) /* write */ 122 + #define REG_NPIX_LSB REG(0x00, 0xa6) /* write */ 123 + #define REG_NLINE_MSB REG(0x00, 0xa7) /* write */ 124 + #define REG_NLINE_LSB REG(0x00, 0xa8) /* write */ 125 + #define REG_VS_LINE_STRT_1_MSB REG(0x00, 0xa9) /* write */ 126 + #define REG_VS_LINE_STRT_1_LSB REG(0x00, 0xaa) /* write */ 127 + #define REG_VS_PIX_STRT_1_MSB REG(0x00, 0xab) /* write */ 128 + #define REG_VS_PIX_STRT_1_LSB REG(0x00, 0xac) /* write */ 129 + #define REG_VS_LINE_END_1_MSB REG(0x00, 0xad) /* write */ 130 + #define REG_VS_LINE_END_1_LSB REG(0x00, 0xae) /* write */ 131 + #define REG_VS_PIX_END_1_MSB REG(0x00, 0xaf) /* write */ 132 + #define REG_VS_PIX_END_1_LSB REG(0x00, 0xb0) /* write */ 133 + #define REG_VS_PIX_STRT_2_MSB REG(0x00, 0xb3) /* write */ 134 + #define REG_VS_PIX_STRT_2_LSB REG(0x00, 0xb4) /* write */ 135 + #define REG_VS_PIX_END_2_MSB REG(0x00, 0xb7) /* write */ 136 + #define REG_VS_PIX_END_2_LSB REG(0x00, 0xb8) /* write */ 137 + #define REG_HS_PIX_START_MSB REG(0x00, 0xb9) /* write */ 138 + #define REG_HS_PIX_START_LSB REG(0x00, 0xba) /* write */ 139 + #define REG_HS_PIX_STOP_MSB REG(0x00, 0xbb) /* write */ 140 + #define REG_HS_PIX_STOP_LSB REG(0x00, 0xbc) /* write */ 141 + #define REG_VWIN_START_1_MSB REG(0x00, 0xbd) /* write */ 142 + #define REG_VWIN_START_1_LSB REG(0x00, 0xbe) /* write */ 143 + #define REG_VWIN_END_1_MSB REG(0x00, 0xbf) /* write */ 144 + #define REG_VWIN_END_1_LSB REG(0x00, 0xc0) /* write */ 145 + #define REG_DE_START_MSB REG(0x00, 0xc5) /* write */ 146 + #define REG_DE_START_LSB REG(0x00, 0xc6) /* write */ 147 + #define REG_DE_STOP_MSB REG(0x00, 0xc7) /* write */ 148 + #define REG_DE_STOP_LSB REG(0x00, 0xc8) /* write */ 149 + #define REG_TBG_CNTRL_0 REG(0x00, 0xca) /* write */ 150 + # define TBG_CNTRL_0_FRAME_DIS (1 << 5) 151 + # define TBG_CNTRL_0_SYNC_MTHD (1 << 6) 152 + # define TBG_CNTRL_0_SYNC_ONCE (1 << 7) 153 + #define REG_TBG_CNTRL_1 REG(0x00, 0xcb) /* write */ 154 + # define TBG_CNTRL_1_VH_TGL_0 (1 << 0) 155 + # define TBG_CNTRL_1_VH_TGL_1 (1 << 1) 156 + # define TBG_CNTRL_1_VH_TGL_2 (1 << 2) 157 + # define TBG_CNTRL_1_VHX_EXT_DE (1 << 3) 158 + # define TBG_CNTRL_1_VHX_EXT_HS (1 << 4) 159 + # define TBG_CNTRL_1_VHX_EXT_VS (1 << 5) 160 + # define TBG_CNTRL_1_DWIN_DIS (1 << 6) 161 + #define REG_ENABLE_SPACE REG(0x00, 0xd6) /* write */ 162 + #define REG_HVF_CNTRL_0 REG(0x00, 0xe4) /* write */ 163 + # define HVF_CNTRL_0_SM (1 << 7) 164 + # define HVF_CNTRL_0_RWB (1 << 6) 165 + # define HVF_CNTRL_0_PREFIL(x) (((x) & 3) << 2) 166 + # define HVF_CNTRL_0_INTPOL(x) (((x) & 3) << 0) 167 + #define REG_HVF_CNTRL_1 REG(0x00, 0xe5) /* write */ 168 + # define HVF_CNTRL_1_FOR (1 << 0) 169 + # define HVF_CNTRL_1_YUVBLK (1 << 1) 170 + # define HVF_CNTRL_1_VQR(x) (((x) & 3) << 2) 171 + # define HVF_CNTRL_1_PAD(x) (((x) & 3) << 4) 172 + # define HVF_CNTRL_1_SEMI_PLANAR (1 << 6) 173 + #define REG_RPT_CNTRL REG(0x00, 0xf0) /* write */ 174 + 175 + 176 + /* Page 02h: PLL settings */ 177 + #define REG_PLL_SERIAL_1 REG(0x02, 0x00) /* read/write */ 178 + # define PLL_SERIAL_1_SRL_FDN (1 << 0) 179 + # define PLL_SERIAL_1_SRL_IZ(x) (((x) & 3) << 1) 180 + # define PLL_SERIAL_1_SRL_MAN_IZ (1 << 6) 181 + #define REG_PLL_SERIAL_2 REG(0x02, 0x01) /* read/write */ 182 + # define PLL_SERIAL_2_SRL_NOSC(x) (((x) & 3) << 0) 183 + # define PLL_SERIAL_2_SRL_PR(x) (((x) & 0xf) << 4) 184 + #define REG_PLL_SERIAL_3 REG(0x02, 0x02) /* read/write */ 185 + # define PLL_SERIAL_3_SRL_CCIR (1 << 0) 186 + # define PLL_SERIAL_3_SRL_DE (1 << 2) 187 + # define PLL_SERIAL_3_SRL_PXIN_SEL (1 << 4) 188 + #define REG_SERIALIZER REG(0x02, 0x03) /* read/write */ 189 + #define REG_BUFFER_OUT REG(0x02, 0x04) /* read/write */ 190 + #define REG_PLL_SCG1 REG(0x02, 0x05) /* read/write */ 191 + #define REG_PLL_SCG2 REG(0x02, 0x06) /* read/write */ 192 + #define REG_PLL_SCGN1 REG(0x02, 0x07) /* read/write */ 193 + #define REG_PLL_SCGN2 REG(0x02, 0x08) /* read/write */ 194 + #define REG_PLL_SCGR1 REG(0x02, 0x09) /* read/write */ 195 + #define REG_PLL_SCGR2 REG(0x02, 0x0a) /* read/write */ 196 + #define REG_AUDIO_DIV REG(0x02, 0x0e) /* read/write */ 197 + #define REG_SEL_CLK REG(0x02, 0x11) /* read/write */ 198 + # define SEL_CLK_SEL_CLK1 (1 << 0) 199 + # define SEL_CLK_SEL_VRF_CLK(x) (((x) & 3) << 1) 200 + # define SEL_CLK_ENA_SC_CLK (1 << 3) 201 + #define REG_ANA_GENERAL REG(0x02, 0x12) /* read/write */ 202 + 203 + 204 + /* Page 09h: EDID Control */ 205 + #define REG_EDID_DATA_0 REG(0x09, 0x00) /* read */ 206 + /* next 127 successive registers are the EDID block */ 207 + #define REG_EDID_CTRL REG(0x09, 0xfa) /* read/write */ 208 + #define REG_DDC_ADDR REG(0x09, 0xfb) /* read/write */ 209 + #define REG_DDC_OFFS REG(0x09, 0xfc) /* read/write */ 210 + #define REG_DDC_SEGM_ADDR REG(0x09, 0xfd) /* read/write */ 211 + #define REG_DDC_SEGM REG(0x09, 0xfe) /* read/write */ 212 + 213 + 214 + /* Page 10h: information frames and packets */ 215 + 216 + 217 + /* Page 11h: audio settings and content info packets */ 218 + #define REG_AIP_CNTRL_0 REG(0x11, 0x00) /* read/write */ 219 + # define AIP_CNTRL_0_RST_FIFO (1 << 0) 220 + # define AIP_CNTRL_0_SWAP (1 << 1) 221 + # define AIP_CNTRL_0_LAYOUT (1 << 2) 222 + # define AIP_CNTRL_0_ACR_MAN (1 << 5) 223 + # define AIP_CNTRL_0_RST_CTS (1 << 6) 224 + #define REG_ENC_CNTRL REG(0x11, 0x0d) /* read/write */ 225 + # define ENC_CNTRL_RST_ENC (1 << 0) 226 + # define ENC_CNTRL_RST_SEL (1 << 1) 227 + # define ENC_CNTRL_CTL_CODE(x) (((x) & 3) << 2) 228 + 229 + 230 + /* Page 12h: HDCP and OTP */ 231 + #define REG_TX3 REG(0x12, 0x9a) /* read/write */ 232 + #define REG_TX33 REG(0x12, 0xb8) /* read/write */ 233 + # define TX33_HDMI (1 << 1) 234 + 235 + 236 + /* Page 13h: Gamut related metadata packets */ 237 + 238 + 239 + 240 + /* CEC registers: (not paged) 241 + */ 242 + #define REG_CEC_FRO_IM_CLK_CTRL 0xfb /* read/write */ 243 + # define CEC_FRO_IM_CLK_CTRL_GHOST_DIS (1 << 7) 244 + # define CEC_FRO_IM_CLK_CTRL_ENA_OTP (1 << 6) 245 + # define CEC_FRO_IM_CLK_CTRL_IMCLK_SEL (1 << 1) 246 + # define CEC_FRO_IM_CLK_CTRL_FRO_DIV (1 << 0) 247 + #define REG_CEC_RXSHPDLEV 0xfe /* read */ 248 + # define CEC_RXSHPDLEV_RXSENS (1 << 0) 249 + # define CEC_RXSHPDLEV_HPD (1 << 1) 250 + 251 + #define REG_CEC_ENAMODS 0xff /* read/write */ 252 + # define CEC_ENAMODS_DIS_FRO (1 << 6) 253 + # define CEC_ENAMODS_DIS_CCLK (1 << 5) 254 + # define CEC_ENAMODS_EN_RXSENS (1 << 2) 255 + # define CEC_ENAMODS_EN_HDMI (1 << 1) 256 + # define CEC_ENAMODS_EN_CEC (1 << 0) 257 + 258 + 259 + /* Device versions: */ 260 + #define TDA9989N2 0x0101 261 + #define TDA19989 0x0201 262 + #define TDA19989N2 0x0202 263 + #define TDA19988 0x0301 264 + 265 + static void 266 + cec_write(struct drm_encoder *encoder, uint16_t addr, uint8_t val) 267 + { 268 + struct i2c_client *client = to_tda998x_priv(encoder)->cec; 269 + uint8_t buf[] = {addr, val}; 270 + int ret; 271 + 272 + ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 273 + if (ret < 0) 274 + dev_err(&client->dev, "Error %d writing to cec:0x%x\n", ret, addr); 275 + } 276 + 277 + static uint8_t 278 + cec_read(struct drm_encoder *encoder, uint8_t addr) 279 + { 280 + struct i2c_client *client = to_tda998x_priv(encoder)->cec; 281 + uint8_t val; 282 + int ret; 283 + 284 + ret = i2c_master_send(client, &addr, sizeof(addr)); 285 + if (ret < 0) 286 + goto fail; 287 + 288 + ret = i2c_master_recv(client, &val, sizeof(val)); 289 + if (ret < 0) 290 + goto fail; 291 + 292 + return val; 293 + 294 + fail: 295 + dev_err(&client->dev, "Error %d reading from cec:0x%x\n", ret, addr); 296 + return 0; 297 + } 298 + 299 + static void 300 + set_page(struct drm_encoder *encoder, uint16_t reg) 301 + { 302 + struct tda998x_priv *priv = to_tda998x_priv(encoder); 303 + 304 + if (REG2PAGE(reg) != priv->current_page) { 305 + struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 306 + uint8_t buf[] = { 307 + REG_CURPAGE, REG2PAGE(reg) 308 + }; 309 + int ret = i2c_master_send(client, buf, sizeof(buf)); 310 + if (ret < 0) 311 + dev_err(&client->dev, "Error %d writing to REG_CURPAGE\n", ret); 312 + 313 + priv->current_page = REG2PAGE(reg); 314 + } 315 + } 316 + 317 + static int 318 + reg_read_range(struct drm_encoder *encoder, uint16_t reg, char *buf, int cnt) 319 + { 320 + struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 321 + uint8_t addr = REG2ADDR(reg); 322 + int ret; 323 + 324 + set_page(encoder, reg); 325 + 326 + ret = i2c_master_send(client, &addr, sizeof(addr)); 327 + if (ret < 0) 328 + goto fail; 329 + 330 + ret = i2c_master_recv(client, buf, cnt); 331 + if (ret < 0) 332 + goto fail; 333 + 334 + return ret; 335 + 336 + fail: 337 + dev_err(&client->dev, "Error %d reading from 0x%x\n", ret, reg); 338 + return ret; 339 + } 340 + 341 + static uint8_t 342 + reg_read(struct drm_encoder *encoder, uint16_t reg) 343 + { 344 + uint8_t val = 0; 345 + reg_read_range(encoder, reg, &val, sizeof(val)); 346 + return val; 347 + } 348 + 349 + static void 350 + reg_write(struct drm_encoder *encoder, uint16_t reg, uint8_t val) 351 + { 352 + struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 353 + uint8_t buf[] = {REG2ADDR(reg), val}; 354 + int ret; 355 + 356 + set_page(encoder, reg); 357 + 358 + ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 359 + if (ret < 0) 360 + dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); 361 + } 362 + 363 + static void 364 + reg_write16(struct drm_encoder *encoder, uint16_t reg, uint16_t val) 365 + { 366 + struct i2c_client *client = drm_i2c_encoder_get_client(encoder); 367 + uint8_t buf[] = {REG2ADDR(reg), val >> 8, val}; 368 + int ret; 369 + 370 + set_page(encoder, reg); 371 + 372 + ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 373 + if (ret < 0) 374 + dev_err(&client->dev, "Error %d writing to 0x%x\n", ret, reg); 375 + } 376 + 377 + static void 378 + reg_set(struct drm_encoder *encoder, uint16_t reg, uint8_t val) 379 + { 380 + reg_write(encoder, reg, reg_read(encoder, reg) | val); 381 + } 382 + 383 + static void 384 + reg_clear(struct drm_encoder *encoder, uint16_t reg, uint8_t val) 385 + { 386 + reg_write(encoder, reg, reg_read(encoder, reg) & ~val); 387 + } 388 + 389 + static void 390 + tda998x_reset(struct drm_encoder *encoder) 391 + { 392 + /* reset audio and i2c master: */ 393 + reg_set(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); 394 + msleep(50); 395 + reg_clear(encoder, REG_SOFTRESET, SOFTRESET_AUDIO | SOFTRESET_I2C_MASTER); 396 + msleep(50); 397 + 398 + /* reset transmitter: */ 399 + reg_set(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); 400 + reg_clear(encoder, REG_MAIN_CNTRL0, MAIN_CNTRL0_SR); 401 + 402 + /* PLL registers common configuration */ 403 + reg_write(encoder, REG_PLL_SERIAL_1, 0x00); 404 + reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(1)); 405 + reg_write(encoder, REG_PLL_SERIAL_3, 0x00); 406 + reg_write(encoder, REG_SERIALIZER, 0x00); 407 + reg_write(encoder, REG_BUFFER_OUT, 0x00); 408 + reg_write(encoder, REG_PLL_SCG1, 0x00); 409 + reg_write(encoder, REG_AUDIO_DIV, 0x03); 410 + reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); 411 + reg_write(encoder, REG_PLL_SCGN1, 0xfa); 412 + reg_write(encoder, REG_PLL_SCGN2, 0x00); 413 + reg_write(encoder, REG_PLL_SCGR1, 0x5b); 414 + reg_write(encoder, REG_PLL_SCGR2, 0x00); 415 + reg_write(encoder, REG_PLL_SCG2, 0x10); 416 + } 417 + 418 + /* DRM encoder functions */ 419 + 420 + static void 421 + tda998x_encoder_set_config(struct drm_encoder *encoder, void *params) 422 + { 423 + } 424 + 425 + static void 426 + tda998x_encoder_dpms(struct drm_encoder *encoder, int mode) 427 + { 428 + struct tda998x_priv *priv = to_tda998x_priv(encoder); 429 + 430 + /* we only care about on or off: */ 431 + if (mode != DRM_MODE_DPMS_ON) 432 + mode = DRM_MODE_DPMS_OFF; 433 + 434 + if (mode == priv->dpms) 435 + return; 436 + 437 + switch (mode) { 438 + case DRM_MODE_DPMS_ON: 439 + /* enable audio and video ports */ 440 + reg_write(encoder, REG_ENA_AP, 0xff); 441 + reg_write(encoder, REG_ENA_VP_0, 0xff); 442 + reg_write(encoder, REG_ENA_VP_1, 0xff); 443 + reg_write(encoder, REG_ENA_VP_2, 0xff); 444 + /* set muxing after enabling ports: */ 445 + reg_write(encoder, REG_VIP_CNTRL_0, 446 + VIP_CNTRL_0_SWAP_A(2) | VIP_CNTRL_0_SWAP_B(3)); 447 + reg_write(encoder, REG_VIP_CNTRL_1, 448 + VIP_CNTRL_1_SWAP_C(0) | VIP_CNTRL_1_SWAP_D(1)); 449 + reg_write(encoder, REG_VIP_CNTRL_2, 450 + VIP_CNTRL_2_SWAP_E(4) | VIP_CNTRL_2_SWAP_F(5)); 451 + break; 452 + case DRM_MODE_DPMS_OFF: 453 + /* disable audio and video ports */ 454 + reg_write(encoder, REG_ENA_AP, 0x00); 455 + reg_write(encoder, REG_ENA_VP_0, 0x00); 456 + reg_write(encoder, REG_ENA_VP_1, 0x00); 457 + reg_write(encoder, REG_ENA_VP_2, 0x00); 458 + break; 459 + } 460 + 461 + priv->dpms = mode; 462 + } 463 + 464 + static void 465 + tda998x_encoder_save(struct drm_encoder *encoder) 466 + { 467 + DBG(""); 468 + } 469 + 470 + static void 471 + tda998x_encoder_restore(struct drm_encoder *encoder) 472 + { 473 + DBG(""); 474 + } 475 + 476 + static bool 477 + tda998x_encoder_mode_fixup(struct drm_encoder *encoder, 478 + const struct drm_display_mode *mode, 479 + struct drm_display_mode *adjusted_mode) 480 + { 481 + return true; 482 + } 483 + 484 + static int 485 + tda998x_encoder_mode_valid(struct drm_encoder *encoder, 486 + struct drm_display_mode *mode) 487 + { 488 + return MODE_OK; 489 + } 490 + 491 + static void 492 + tda998x_encoder_mode_set(struct drm_encoder *encoder, 493 + struct drm_display_mode *mode, 494 + struct drm_display_mode *adjusted_mode) 495 + { 496 + struct tda998x_priv *priv = to_tda998x_priv(encoder); 497 + uint16_t hs_start, hs_end, line_start, line_end; 498 + uint16_t vwin_start, vwin_end, de_start, de_end; 499 + uint16_t ref_pix, ref_line, pix_start2; 500 + uint8_t reg, div, rep; 501 + 502 + hs_start = mode->hsync_start - mode->hdisplay; 503 + hs_end = mode->hsync_end - mode->hdisplay; 504 + line_start = 1; 505 + line_end = 1 + mode->vsync_end - mode->vsync_start; 506 + vwin_start = mode->vtotal - mode->vsync_start; 507 + vwin_end = vwin_start + mode->vdisplay; 508 + de_start = mode->htotal - mode->hdisplay; 509 + de_end = mode->htotal; 510 + 511 + pix_start2 = 0; 512 + if (mode->flags & DRM_MODE_FLAG_INTERLACE) 513 + pix_start2 = (mode->htotal / 2) + hs_start; 514 + 515 + /* TODO how is this value calculated? It is 2 for all common 516 + * formats in the tables in out of tree nxp driver (assuming 517 + * I've properly deciphered their byzantine table system) 518 + */ 519 + ref_line = 2; 520 + 521 + /* this might changes for other color formats from the CRTC: */ 522 + ref_pix = 3 + hs_start; 523 + 524 + div = 148500 / mode->clock; 525 + 526 + DBG("clock=%d, div=%u", mode->clock, div); 527 + DBG("hs_start=%u, hs_end=%u, line_start=%u, line_end=%u", 528 + hs_start, hs_end, line_start, line_end); 529 + DBG("vwin_start=%u, vwin_end=%u, de_start=%u, de_end=%u", 530 + vwin_start, vwin_end, de_start, de_end); 531 + DBG("ref_line=%u, ref_pix=%u, pix_start2=%u", 532 + ref_line, ref_pix, pix_start2); 533 + 534 + /* mute the audio FIFO: */ 535 + reg_set(encoder, REG_AIP_CNTRL_0, AIP_CNTRL_0_RST_FIFO); 536 + 537 + /* set HDMI HDCP mode off: */ 538 + reg_set(encoder, REG_TBG_CNTRL_1, TBG_CNTRL_1_DWIN_DIS); 539 + reg_clear(encoder, REG_TX33, TX33_HDMI); 540 + 541 + reg_write(encoder, REG_ENC_CNTRL, ENC_CNTRL_CTL_CODE(0)); 542 + /* no pre-filter or interpolator: */ 543 + reg_write(encoder, REG_HVF_CNTRL_0, HVF_CNTRL_0_PREFIL(0) | 544 + HVF_CNTRL_0_INTPOL(0)); 545 + reg_write(encoder, REG_VIP_CNTRL_5, VIP_CNTRL_5_SP_CNT(0)); 546 + reg_write(encoder, REG_VIP_CNTRL_4, VIP_CNTRL_4_BLANKIT(0) | 547 + VIP_CNTRL_4_BLC(0)); 548 + reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_CCIR); 549 + 550 + reg_clear(encoder, REG_PLL_SERIAL_1, PLL_SERIAL_1_SRL_MAN_IZ); 551 + reg_clear(encoder, REG_PLL_SERIAL_3, PLL_SERIAL_3_SRL_DE); 552 + reg_write(encoder, REG_SERIALIZER, 0); 553 + reg_write(encoder, REG_HVF_CNTRL_1, HVF_CNTRL_1_VQR(0)); 554 + 555 + /* TODO enable pixel repeat for pixel rates less than 25Msamp/s */ 556 + rep = 0; 557 + reg_write(encoder, REG_RPT_CNTRL, 0); 558 + reg_write(encoder, REG_SEL_CLK, SEL_CLK_SEL_VRF_CLK(0) | 559 + SEL_CLK_SEL_CLK1 | SEL_CLK_ENA_SC_CLK); 560 + 561 + reg_write(encoder, REG_PLL_SERIAL_2, PLL_SERIAL_2_SRL_NOSC(div) | 562 + PLL_SERIAL_2_SRL_PR(rep)); 563 + 564 + reg_write16(encoder, REG_VS_PIX_STRT_2_MSB, pix_start2); 565 + reg_write16(encoder, REG_VS_PIX_END_2_MSB, pix_start2); 566 + 567 + /* set color matrix bypass flag: */ 568 + reg_set(encoder, REG_MAT_CONTRL, MAT_CONTRL_MAT_BP); 569 + 570 + /* set BIAS tmds value: */ 571 + reg_write(encoder, REG_ANA_GENERAL, 0x09); 572 + 573 + reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_MTHD); 574 + 575 + reg_write(encoder, REG_VIP_CNTRL_3, 0); 576 + reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_SYNC_HS); 577 + if (mode->flags & DRM_MODE_FLAG_NVSYNC) 578 + reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_V_TGL); 579 + 580 + if (mode->flags & DRM_MODE_FLAG_NHSYNC) 581 + reg_set(encoder, REG_VIP_CNTRL_3, VIP_CNTRL_3_H_TGL); 582 + 583 + reg_write(encoder, REG_VIDFORMAT, 0x00); 584 + reg_write16(encoder, REG_NPIX_MSB, mode->hdisplay - 1); 585 + reg_write16(encoder, REG_NLINE_MSB, mode->vdisplay - 1); 586 + reg_write16(encoder, REG_VS_LINE_STRT_1_MSB, line_start); 587 + reg_write16(encoder, REG_VS_LINE_END_1_MSB, line_end); 588 + reg_write16(encoder, REG_VS_PIX_STRT_1_MSB, hs_start); 589 + reg_write16(encoder, REG_VS_PIX_END_1_MSB, hs_start); 590 + reg_write16(encoder, REG_HS_PIX_START_MSB, hs_start); 591 + reg_write16(encoder, REG_HS_PIX_STOP_MSB, hs_end); 592 + reg_write16(encoder, REG_VWIN_START_1_MSB, vwin_start); 593 + reg_write16(encoder, REG_VWIN_END_1_MSB, vwin_end); 594 + reg_write16(encoder, REG_DE_START_MSB, de_start); 595 + reg_write16(encoder, REG_DE_STOP_MSB, de_end); 596 + 597 + if (priv->rev == TDA19988) { 598 + /* let incoming pixels fill the active space (if any) */ 599 + reg_write(encoder, REG_ENABLE_SPACE, 0x01); 600 + } 601 + 602 + reg_write16(encoder, REG_REFPIX_MSB, ref_pix); 603 + reg_write16(encoder, REG_REFLINE_MSB, ref_line); 604 + 605 + reg = TBG_CNTRL_1_VHX_EXT_DE | 606 + TBG_CNTRL_1_VHX_EXT_HS | 607 + TBG_CNTRL_1_VHX_EXT_VS | 608 + TBG_CNTRL_1_DWIN_DIS | /* HDCP off */ 609 + TBG_CNTRL_1_VH_TGL_2; 610 + if (mode->flags & (DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC)) 611 + reg |= TBG_CNTRL_1_VH_TGL_0; 612 + reg_set(encoder, REG_TBG_CNTRL_1, reg); 613 + 614 + /* must be last register set: */ 615 + reg_clear(encoder, REG_TBG_CNTRL_0, TBG_CNTRL_0_SYNC_ONCE); 616 + } 617 + 618 + static enum drm_connector_status 619 + tda998x_encoder_detect(struct drm_encoder *encoder, 620 + struct drm_connector *connector) 621 + { 622 + uint8_t val = cec_read(encoder, REG_CEC_RXSHPDLEV); 623 + return (val & CEC_RXSHPDLEV_HPD) ? connector_status_connected : 624 + connector_status_disconnected; 625 + } 626 + 627 + static int 628 + read_edid_block(struct drm_encoder *encoder, uint8_t *buf, int blk) 629 + { 630 + uint8_t offset, segptr; 631 + int ret, i; 632 + 633 + /* enable EDID read irq: */ 634 + reg_set(encoder, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); 635 + 636 + offset = (blk & 1) ? 128 : 0; 637 + segptr = blk / 2; 638 + 639 + reg_write(encoder, REG_DDC_ADDR, 0xa0); 640 + reg_write(encoder, REG_DDC_OFFS, offset); 641 + reg_write(encoder, REG_DDC_SEGM_ADDR, 0x60); 642 + reg_write(encoder, REG_DDC_SEGM, segptr); 643 + 644 + /* enable reading EDID: */ 645 + reg_write(encoder, REG_EDID_CTRL, 0x1); 646 + 647 + /* flag must be cleared by sw: */ 648 + reg_write(encoder, REG_EDID_CTRL, 0x0); 649 + 650 + /* wait for block read to complete: */ 651 + for (i = 100; i > 0; i--) { 652 + uint8_t val = reg_read(encoder, REG_INT_FLAGS_2); 653 + if (val & INT_FLAGS_2_EDID_BLK_RD) 654 + break; 655 + msleep(1); 656 + } 657 + 658 + if (i == 0) 659 + return -ETIMEDOUT; 660 + 661 + ret = reg_read_range(encoder, REG_EDID_DATA_0, buf, EDID_LENGTH); 662 + if (ret != EDID_LENGTH) { 663 + dev_err(encoder->dev->dev, "failed to read edid block %d: %d", 664 + blk, ret); 665 + return ret; 666 + } 667 + 668 + reg_clear(encoder, REG_INT_FLAGS_2, INT_FLAGS_2_EDID_BLK_RD); 669 + 670 + return 0; 671 + } 672 + 673 + static uint8_t * 674 + do_get_edid(struct drm_encoder *encoder) 675 + { 676 + int j = 0, valid_extensions = 0; 677 + uint8_t *block, *new; 678 + bool print_bad_edid = drm_debug & DRM_UT_KMS; 679 + 680 + if ((block = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL) 681 + return NULL; 682 + 683 + /* base block fetch */ 684 + if (read_edid_block(encoder, block, 0)) 685 + goto fail; 686 + 687 + if (!drm_edid_block_valid(block, 0, print_bad_edid)) 688 + goto fail; 689 + 690 + /* if there's no extensions, we're done */ 691 + if (block[0x7e] == 0) 692 + return block; 693 + 694 + new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL); 695 + if (!new) 696 + goto fail; 697 + block = new; 698 + 699 + for (j = 1; j <= block[0x7e]; j++) { 700 + uint8_t *ext_block = block + (valid_extensions + 1) * EDID_LENGTH; 701 + if (read_edid_block(encoder, ext_block, j)) 702 + goto fail; 703 + 704 + if (!drm_edid_block_valid(ext_block, j, print_bad_edid)) 705 + goto fail; 706 + 707 + valid_extensions++; 708 + } 709 + 710 + if (valid_extensions != block[0x7e]) { 711 + block[EDID_LENGTH-1] += block[0x7e] - valid_extensions; 712 + block[0x7e] = valid_extensions; 713 + new = krealloc(block, (valid_extensions + 1) * EDID_LENGTH, GFP_KERNEL); 714 + if (!new) 715 + goto fail; 716 + block = new; 717 + } 718 + 719 + return block; 720 + 721 + fail: 722 + dev_warn(encoder->dev->dev, "failed to read EDID\n"); 723 + kfree(block); 724 + return NULL; 725 + } 726 + 727 + static int 728 + tda998x_encoder_get_modes(struct drm_encoder *encoder, 729 + struct drm_connector *connector) 730 + { 731 + struct edid *edid = (struct edid *)do_get_edid(encoder); 732 + int n = 0; 733 + 734 + if (edid) { 735 + drm_mode_connector_update_edid_property(connector, edid); 736 + n = drm_add_edid_modes(connector, edid); 737 + kfree(edid); 738 + } 739 + 740 + return n; 741 + } 742 + 743 + static int 744 + tda998x_encoder_create_resources(struct drm_encoder *encoder, 745 + struct drm_connector *connector) 746 + { 747 + DBG(""); 748 + return 0; 749 + } 750 + 751 + static int 752 + tda998x_encoder_set_property(struct drm_encoder *encoder, 753 + struct drm_connector *connector, 754 + struct drm_property *property, 755 + uint64_t val) 756 + { 757 + DBG(""); 758 + return 0; 759 + } 760 + 761 + static void 762 + tda998x_encoder_destroy(struct drm_encoder *encoder) 763 + { 764 + struct tda998x_priv *priv = to_tda998x_priv(encoder); 765 + drm_i2c_encoder_destroy(encoder); 766 + kfree(priv); 767 + } 768 + 769 + static struct drm_encoder_slave_funcs tda998x_encoder_funcs = { 770 + .set_config = tda998x_encoder_set_config, 771 + .destroy = tda998x_encoder_destroy, 772 + .dpms = tda998x_encoder_dpms, 773 + .save = tda998x_encoder_save, 774 + .restore = tda998x_encoder_restore, 775 + .mode_fixup = tda998x_encoder_mode_fixup, 776 + .mode_valid = tda998x_encoder_mode_valid, 777 + .mode_set = tda998x_encoder_mode_set, 778 + .detect = tda998x_encoder_detect, 779 + .get_modes = tda998x_encoder_get_modes, 780 + .create_resources = tda998x_encoder_create_resources, 781 + .set_property = tda998x_encoder_set_property, 782 + }; 783 + 784 + /* I2C driver functions */ 785 + 786 + static int 787 + tda998x_probe(struct i2c_client *client, const struct i2c_device_id *id) 788 + { 789 + return 0; 790 + } 791 + 792 + static int 793 + tda998x_remove(struct i2c_client *client) 794 + { 795 + return 0; 796 + } 797 + 798 + static int 799 + tda998x_encoder_init(struct i2c_client *client, 800 + struct drm_device *dev, 801 + struct drm_encoder_slave *encoder_slave) 802 + { 803 + struct drm_encoder *encoder = &encoder_slave->base; 804 + struct tda998x_priv *priv; 805 + 806 + priv = kzalloc(sizeof(*priv), GFP_KERNEL); 807 + if (!priv) 808 + return -ENOMEM; 809 + 810 + priv->current_page = 0; 811 + priv->cec = i2c_new_dummy(client->adapter, 0x34); 812 + priv->dpms = DRM_MODE_DPMS_OFF; 813 + 814 + encoder_slave->slave_priv = priv; 815 + encoder_slave->slave_funcs = &tda998x_encoder_funcs; 816 + 817 + /* wake up the device: */ 818 + cec_write(encoder, REG_CEC_ENAMODS, 819 + CEC_ENAMODS_EN_RXSENS | CEC_ENAMODS_EN_HDMI); 820 + 821 + tda998x_reset(encoder); 822 + 823 + /* read version: */ 824 + priv->rev = reg_read(encoder, REG_VERSION_LSB) | 825 + reg_read(encoder, REG_VERSION_MSB) << 8; 826 + 827 + /* mask off feature bits: */ 828 + priv->rev &= ~0x30; /* not-hdcp and not-scalar bit */ 829 + 830 + switch (priv->rev) { 831 + case TDA9989N2: dev_info(dev->dev, "found TDA9989 n2"); break; 832 + case TDA19989: dev_info(dev->dev, "found TDA19989"); break; 833 + case TDA19989N2: dev_info(dev->dev, "found TDA19989 n2"); break; 834 + case TDA19988: dev_info(dev->dev, "found TDA19988"); break; 835 + default: 836 + DBG("found unsupported device: %04x", priv->rev); 837 + goto fail; 838 + } 839 + 840 + /* after reset, enable DDC: */ 841 + reg_write(encoder, REG_DDC_DISABLE, 0x00); 842 + 843 + /* set clock on DDC channel: */ 844 + reg_write(encoder, REG_TX3, 39); 845 + 846 + /* if necessary, disable multi-master: */ 847 + if (priv->rev == TDA19989) 848 + reg_set(encoder, REG_I2C_MASTER, I2C_MASTER_DIS_MM); 849 + 850 + cec_write(encoder, REG_CEC_FRO_IM_CLK_CTRL, 851 + CEC_FRO_IM_CLK_CTRL_GHOST_DIS | CEC_FRO_IM_CLK_CTRL_IMCLK_SEL); 852 + 853 + return 0; 854 + 855 + fail: 856 + /* if encoder_init fails, the encoder slave is never registered, 857 + * so cleanup here: 858 + */ 859 + if (priv->cec) 860 + i2c_unregister_device(priv->cec); 861 + kfree(priv); 862 + encoder_slave->slave_priv = NULL; 863 + encoder_slave->slave_funcs = NULL; 864 + return -ENXIO; 865 + } 866 + 867 + static struct i2c_device_id tda998x_ids[] = { 868 + { "tda998x", 0 }, 869 + { } 870 + }; 871 + MODULE_DEVICE_TABLE(i2c, tda998x_ids); 872 + 873 + static struct drm_i2c_encoder_driver tda998x_driver = { 874 + .i2c_driver = { 875 + .probe = tda998x_probe, 876 + .remove = tda998x_remove, 877 + .driver = { 878 + .name = "tda998x", 879 + }, 880 + .id_table = tda998x_ids, 881 + }, 882 + .encoder_init = tda998x_encoder_init, 883 + }; 884 + 885 + /* Module initialization */ 886 + 887 + static int __init 888 + tda998x_init(void) 889 + { 890 + DBG(""); 891 + return drm_i2c_encoder_register(THIS_MODULE, &tda998x_driver); 892 + } 893 + 894 + static void __exit 895 + tda998x_exit(void) 896 + { 897 + DBG(""); 898 + drm_i2c_encoder_unregister(&tda998x_driver); 899 + } 900 + 901 + MODULE_AUTHOR("Rob Clark <robdclark@gmail.com"); 902 + MODULE_DESCRIPTION("NXP Semiconductors TDA998X HDMI Encoder"); 903 + MODULE_LICENSE("GPL"); 904 + 905 + module_init(tda998x_init); 906 + module_exit(tda998x_exit);
+13 -26
drivers/gpu/drm/nouveau/nv04_tv.c
··· 184 184 .destroy = nv04_tv_destroy, 185 185 }; 186 186 187 + static const struct drm_encoder_helper_funcs nv04_tv_helper_funcs = { 188 + .dpms = nv04_tv_dpms, 189 + .save = drm_i2c_encoder_save, 190 + .restore = drm_i2c_encoder_restore, 191 + .mode_fixup = drm_i2c_encoder_mode_fixup, 192 + .prepare = nv04_tv_prepare, 193 + .commit = nv04_tv_commit, 194 + .mode_set = nv04_tv_mode_set, 195 + .detect = drm_i2c_encoder_detect, 196 + }; 197 + 187 198 int 188 199 nv04_tv_create(struct drm_connector *connector, struct dcb_output *entry) 189 200 { 190 201 struct nouveau_encoder *nv_encoder; 191 202 struct drm_encoder *encoder; 192 203 struct drm_device *dev = connector->dev; 193 - struct drm_encoder_helper_funcs *hfuncs; 194 - struct drm_encoder_slave_funcs *sfuncs; 195 204 struct nouveau_drm *drm = nouveau_drm(dev); 196 205 struct nouveau_i2c *i2c = nouveau_i2c(drm->device); 197 206 struct nouveau_i2c_port *port = i2c->find(i2c, entry->i2c_index); ··· 216 207 if (!nv_encoder) 217 208 return -ENOMEM; 218 209 219 - hfuncs = kzalloc(sizeof(*hfuncs), GFP_KERNEL); 220 - if (!hfuncs) { 221 - ret = -ENOMEM; 222 - goto fail_free; 223 - } 224 - 225 210 /* Initialize the common members */ 226 211 encoder = to_drm_encoder(nv_encoder); 227 212 228 213 drm_encoder_init(dev, encoder, &nv04_tv_funcs, DRM_MODE_ENCODER_TVDAC); 229 - drm_encoder_helper_add(encoder, hfuncs); 214 + drm_encoder_helper_add(encoder, &nv04_tv_helper_funcs); 230 215 231 216 encoder->possible_crtcs = entry->heads; 232 217 encoder->possible_clones = 0; ··· 233 230 if (ret < 0) 234 231 goto fail_cleanup; 235 232 236 - /* Fill the function pointers */ 237 - sfuncs = get_slave_funcs(encoder); 238 - 239 - *hfuncs = (struct drm_encoder_helper_funcs) { 240 - .dpms = nv04_tv_dpms, 241 - .save = sfuncs->save, 242 - .restore = sfuncs->restore, 243 - .mode_fixup = sfuncs->mode_fixup, 244 - .prepare = nv04_tv_prepare, 245 - .commit = nv04_tv_commit, 246 - .mode_set = nv04_tv_mode_set, 247 - .detect = sfuncs->detect, 248 - }; 249 - 250 233 /* Attach it to the specified connector. */ 251 - sfuncs->create_resources(encoder, connector); 234 + get_slave_funcs(encoder)->create_resources(encoder, connector); 252 235 drm_mode_connector_attach_encoder(connector, encoder); 253 236 254 237 return 0; 255 238 256 239 fail_cleanup: 257 240 drm_encoder_cleanup(encoder); 258 - kfree(hfuncs); 259 - fail_free: 260 241 kfree(nv_encoder); 261 242 return ret; 262 243 }
+13
drivers/gpu/drm/tilcdc/Kconfig
··· 1 + config DRM_TILCDC 2 + tristate "DRM Support for TI LCDC Display Controller" 3 + depends on DRM && OF 4 + select DRM_KMS_HELPER 5 + select DRM_KMS_CMA_HELPER 6 + select DRM_GEM_CMA_HELPER 7 + select OF_VIDEOMODE 8 + select OF_DISPLAY_TIMING 9 + select BACKLIGHT_CLASS_DEVICE 10 + help 11 + Choose this option if you have an TI SoC with LCDC display 12 + controller, for example AM33xx in beagle-bone, DA8xx, or 13 + OMAP-L1xx. This driver replaces the FB_DA8XX fbdev driver.
+10
drivers/gpu/drm/tilcdc/Makefile
··· 1 + ccflags-y := -Iinclude/drm -Werror 2 + 3 + tilcdc-y := \ 4 + tilcdc_crtc.o \ 5 + tilcdc_tfp410.o \ 6 + tilcdc_slave.o \ 7 + tilcdc_panel.o \ 8 + tilcdc_drv.o 9 + 10 + obj-$(CONFIG_DRM_TILCDC) += tilcdc.o
+602
drivers/gpu/drm/tilcdc/tilcdc_crtc.c
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #include <linux/kfifo.h> 19 + 20 + #include "tilcdc_drv.h" 21 + #include "tilcdc_regs.h" 22 + 23 + struct tilcdc_crtc { 24 + struct drm_crtc base; 25 + 26 + const struct tilcdc_panel_info *info; 27 + uint32_t dirty; 28 + dma_addr_t start, end; 29 + struct drm_pending_vblank_event *event; 30 + int dpms; 31 + wait_queue_head_t frame_done_wq; 32 + bool frame_done; 33 + 34 + /* fb currently set to scanout 0/1: */ 35 + struct drm_framebuffer *scanout[2]; 36 + 37 + /* for deferred fb unref's: */ 38 + DECLARE_KFIFO_PTR(unref_fifo, struct drm_framebuffer *); 39 + struct work_struct work; 40 + }; 41 + #define to_tilcdc_crtc(x) container_of(x, struct tilcdc_crtc, base) 42 + 43 + static void unref_worker(struct work_struct *work) 44 + { 45 + struct tilcdc_crtc *tilcdc_crtc = container_of(work, struct tilcdc_crtc, work); 46 + struct drm_device *dev = tilcdc_crtc->base.dev; 47 + struct drm_framebuffer *fb; 48 + 49 + mutex_lock(&dev->mode_config.mutex); 50 + while (kfifo_get(&tilcdc_crtc->unref_fifo, &fb)) 51 + drm_framebuffer_unreference(fb); 52 + mutex_unlock(&dev->mode_config.mutex); 53 + } 54 + 55 + static void set_scanout(struct drm_crtc *crtc, int n) 56 + { 57 + static const uint32_t base_reg[] = { 58 + LCDC_DMA_FB_BASE_ADDR_0_REG, LCDC_DMA_FB_BASE_ADDR_1_REG, 59 + }; 60 + static const uint32_t ceil_reg[] = { 61 + LCDC_DMA_FB_CEILING_ADDR_0_REG, LCDC_DMA_FB_CEILING_ADDR_1_REG, 62 + }; 63 + static const uint32_t stat[] = { 64 + LCDC_END_OF_FRAME0, LCDC_END_OF_FRAME1, 65 + }; 66 + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 67 + struct drm_device *dev = crtc->dev; 68 + 69 + pm_runtime_get_sync(dev->dev); 70 + tilcdc_write(dev, base_reg[n], tilcdc_crtc->start); 71 + tilcdc_write(dev, ceil_reg[n], tilcdc_crtc->end); 72 + if (tilcdc_crtc->scanout[n]) { 73 + if (kfifo_put(&tilcdc_crtc->unref_fifo, 74 + (const struct drm_framebuffer **)&tilcdc_crtc->scanout[n])) { 75 + struct tilcdc_drm_private *priv = dev->dev_private; 76 + queue_work(priv->wq, &tilcdc_crtc->work); 77 + } else { 78 + dev_err(dev->dev, "unref fifo full!\n"); 79 + drm_framebuffer_unreference(tilcdc_crtc->scanout[n]); 80 + } 81 + } 82 + tilcdc_crtc->scanout[n] = crtc->fb; 83 + drm_framebuffer_reference(tilcdc_crtc->scanout[n]); 84 + tilcdc_crtc->dirty &= ~stat[n]; 85 + pm_runtime_put_sync(dev->dev); 86 + } 87 + 88 + static void update_scanout(struct drm_crtc *crtc) 89 + { 90 + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 91 + struct drm_device *dev = crtc->dev; 92 + struct drm_framebuffer *fb = crtc->fb; 93 + struct drm_gem_cma_object *gem; 94 + unsigned int depth, bpp; 95 + 96 + drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp); 97 + gem = drm_fb_cma_get_gem_obj(fb, 0); 98 + 99 + tilcdc_crtc->start = gem->paddr + fb->offsets[0] + 100 + (crtc->y * fb->pitches[0]) + (crtc->x * bpp/8); 101 + 102 + tilcdc_crtc->end = tilcdc_crtc->start + 103 + (crtc->mode.vdisplay * fb->pitches[0]); 104 + 105 + if (tilcdc_crtc->dpms == DRM_MODE_DPMS_ON) { 106 + /* already enabled, so just mark the frames that need 107 + * updating and they will be updated on vblank: 108 + */ 109 + tilcdc_crtc->dirty |= LCDC_END_OF_FRAME0 | LCDC_END_OF_FRAME1; 110 + drm_vblank_get(dev, 0); 111 + } else { 112 + /* not enabled yet, so update registers immediately: */ 113 + set_scanout(crtc, 0); 114 + set_scanout(crtc, 1); 115 + } 116 + } 117 + 118 + static void start(struct drm_crtc *crtc) 119 + { 120 + struct drm_device *dev = crtc->dev; 121 + struct tilcdc_drm_private *priv = dev->dev_private; 122 + 123 + if (priv->rev == 2) { 124 + tilcdc_set(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); 125 + msleep(1); 126 + tilcdc_clear(dev, LCDC_CLK_RESET_REG, LCDC_CLK_MAIN_RESET); 127 + msleep(1); 128 + } 129 + 130 + tilcdc_set(dev, LCDC_DMA_CTRL_REG, LCDC_DUAL_FRAME_BUFFER_ENABLE); 131 + tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_PALETTE_LOAD_MODE(DATA_ONLY)); 132 + tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); 133 + } 134 + 135 + static void stop(struct drm_crtc *crtc) 136 + { 137 + struct drm_device *dev = crtc->dev; 138 + 139 + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ENABLE); 140 + } 141 + 142 + static void tilcdc_crtc_destroy(struct drm_crtc *crtc) 143 + { 144 + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 145 + 146 + WARN_ON(tilcdc_crtc->dpms == DRM_MODE_DPMS_ON); 147 + 148 + drm_crtc_cleanup(crtc); 149 + WARN_ON(!kfifo_is_empty(&tilcdc_crtc->unref_fifo)); 150 + kfifo_free(&tilcdc_crtc->unref_fifo); 151 + kfree(tilcdc_crtc); 152 + } 153 + 154 + static int tilcdc_crtc_page_flip(struct drm_crtc *crtc, 155 + struct drm_framebuffer *fb, 156 + struct drm_pending_vblank_event *event) 157 + { 158 + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 159 + struct drm_device *dev = crtc->dev; 160 + 161 + if (tilcdc_crtc->event) { 162 + dev_err(dev->dev, "already pending page flip!\n"); 163 + return -EBUSY; 164 + } 165 + 166 + crtc->fb = fb; 167 + tilcdc_crtc->event = event; 168 + update_scanout(crtc); 169 + 170 + return 0; 171 + } 172 + 173 + static void tilcdc_crtc_dpms(struct drm_crtc *crtc, int mode) 174 + { 175 + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 176 + struct drm_device *dev = crtc->dev; 177 + struct tilcdc_drm_private *priv = dev->dev_private; 178 + 179 + /* we really only care about on or off: */ 180 + if (mode != DRM_MODE_DPMS_ON) 181 + mode = DRM_MODE_DPMS_OFF; 182 + 183 + if (tilcdc_crtc->dpms == mode) 184 + return; 185 + 186 + tilcdc_crtc->dpms = mode; 187 + 188 + pm_runtime_get_sync(dev->dev); 189 + 190 + if (mode == DRM_MODE_DPMS_ON) { 191 + pm_runtime_forbid(dev->dev); 192 + start(crtc); 193 + } else { 194 + tilcdc_crtc->frame_done = false; 195 + stop(crtc); 196 + 197 + /* if necessary wait for framedone irq which will still come 198 + * before putting things to sleep.. 199 + */ 200 + if (priv->rev == 2) { 201 + int ret = wait_event_timeout( 202 + tilcdc_crtc->frame_done_wq, 203 + tilcdc_crtc->frame_done, 204 + msecs_to_jiffies(50)); 205 + if (ret == 0) 206 + dev_err(dev->dev, "timeout waiting for framedone\n"); 207 + } 208 + pm_runtime_allow(dev->dev); 209 + } 210 + 211 + pm_runtime_put_sync(dev->dev); 212 + } 213 + 214 + static bool tilcdc_crtc_mode_fixup(struct drm_crtc *crtc, 215 + const struct drm_display_mode *mode, 216 + struct drm_display_mode *adjusted_mode) 217 + { 218 + return true; 219 + } 220 + 221 + static void tilcdc_crtc_prepare(struct drm_crtc *crtc) 222 + { 223 + tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 224 + } 225 + 226 + static void tilcdc_crtc_commit(struct drm_crtc *crtc) 227 + { 228 + tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 229 + } 230 + 231 + static int tilcdc_crtc_mode_set(struct drm_crtc *crtc, 232 + struct drm_display_mode *mode, 233 + struct drm_display_mode *adjusted_mode, 234 + int x, int y, 235 + struct drm_framebuffer *old_fb) 236 + { 237 + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 238 + struct drm_device *dev = crtc->dev; 239 + struct tilcdc_drm_private *priv = dev->dev_private; 240 + const struct tilcdc_panel_info *info = tilcdc_crtc->info; 241 + uint32_t reg, hbp, hfp, hsw, vbp, vfp, vsw; 242 + int ret; 243 + 244 + ret = tilcdc_crtc_mode_valid(crtc, mode); 245 + if (WARN_ON(ret)) 246 + return ret; 247 + 248 + if (WARN_ON(!info)) 249 + return -EINVAL; 250 + 251 + pm_runtime_get_sync(dev->dev); 252 + 253 + /* Configure the Burst Size and fifo threshold of DMA: */ 254 + reg = tilcdc_read(dev, LCDC_DMA_CTRL_REG) & ~0x00000770; 255 + switch (info->dma_burst_sz) { 256 + case 1: 257 + reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_1); 258 + break; 259 + case 2: 260 + reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_2); 261 + break; 262 + case 4: 263 + reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_4); 264 + break; 265 + case 8: 266 + reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_8); 267 + break; 268 + case 16: 269 + reg |= LCDC_DMA_BURST_SIZE(LCDC_DMA_BURST_16); 270 + break; 271 + default: 272 + return -EINVAL; 273 + } 274 + reg |= (info->fifo_th << 8); 275 + tilcdc_write(dev, LCDC_DMA_CTRL_REG, reg); 276 + 277 + /* Configure timings: */ 278 + hbp = mode->htotal - mode->hsync_end; 279 + hfp = mode->hsync_start - mode->hdisplay; 280 + hsw = mode->hsync_end - mode->hsync_start; 281 + vbp = mode->vtotal - mode->vsync_end; 282 + vfp = mode->vsync_start - mode->vdisplay; 283 + vsw = mode->vsync_end - mode->vsync_start; 284 + 285 + DBG("%dx%d, hbp=%u, hfp=%u, hsw=%u, vbp=%u, vfp=%u, vsw=%u", 286 + mode->hdisplay, mode->vdisplay, hbp, hfp, hsw, vbp, vfp, vsw); 287 + 288 + /* Configure the AC Bias Period and Number of Transitions per Interrupt: */ 289 + reg = tilcdc_read(dev, LCDC_RASTER_TIMING_2_REG) & ~0x000fff00; 290 + reg |= LCDC_AC_BIAS_FREQUENCY(info->ac_bias) | 291 + LCDC_AC_BIAS_TRANSITIONS_PER_INT(info->ac_bias_intrpt); 292 + if (priv->rev == 2) { 293 + reg |= (hfp & 0x300) >> 8; 294 + reg |= (hbp & 0x300) >> 4; 295 + reg |= (hsw & 0x3c0) << 21; 296 + } 297 + tilcdc_write(dev, LCDC_RASTER_TIMING_2_REG, reg); 298 + 299 + reg = (((mode->hdisplay >> 4) - 1) << 4) | 300 + ((hbp & 0xff) << 24) | 301 + ((hfp & 0xff) << 16) | 302 + ((hsw & 0x3f) << 10); 303 + if (priv->rev == 2) 304 + reg |= (((mode->hdisplay >> 4) - 1) & 0x40) >> 3; 305 + tilcdc_write(dev, LCDC_RASTER_TIMING_0_REG, reg); 306 + 307 + reg = ((mode->vdisplay - 1) & 0x3ff) | 308 + ((vbp & 0xff) << 24) | 309 + ((vfp & 0xff) << 16) | 310 + ((vsw & 0x3f) << 10); 311 + tilcdc_write(dev, LCDC_RASTER_TIMING_1_REG, reg); 312 + 313 + /* Configure display type: */ 314 + reg = tilcdc_read(dev, LCDC_RASTER_CTRL_REG) & 315 + ~(LCDC_TFT_MODE | LCDC_MONO_8BIT_MODE | LCDC_MONOCHROME_MODE | 316 + LCDC_V2_TFT_24BPP_MODE | LCDC_V2_TFT_24BPP_UNPACK | 0x000ff000); 317 + reg |= LCDC_TFT_MODE; /* no monochrome/passive support */ 318 + if (info->tft_alt_mode) 319 + reg |= LCDC_TFT_ALT_ENABLE; 320 + if (priv->rev == 2) { 321 + unsigned int depth, bpp; 322 + 323 + drm_fb_get_bpp_depth(crtc->fb->pixel_format, &depth, &bpp); 324 + switch (bpp) { 325 + case 16: 326 + break; 327 + case 32: 328 + reg |= LCDC_V2_TFT_24BPP_UNPACK; 329 + /* fallthrough */ 330 + case 24: 331 + reg |= LCDC_V2_TFT_24BPP_MODE; 332 + break; 333 + default: 334 + dev_err(dev->dev, "invalid pixel format\n"); 335 + return -EINVAL; 336 + } 337 + } 338 + reg |= info->fdd < 12; 339 + tilcdc_write(dev, LCDC_RASTER_CTRL_REG, reg); 340 + 341 + if (info->invert_pxl_clk) 342 + tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_PIXEL_CLOCK); 343 + else 344 + tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_PIXEL_CLOCK); 345 + 346 + if (info->sync_ctrl) 347 + tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_CTRL); 348 + else 349 + tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_CTRL); 350 + 351 + if (info->sync_edge) 352 + tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE); 353 + else 354 + tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_SYNC_EDGE); 355 + 356 + if (mode->flags & DRM_MODE_FLAG_NHSYNC) 357 + tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC); 358 + else 359 + tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_HSYNC); 360 + 361 + if (mode->flags & DRM_MODE_FLAG_NVSYNC) 362 + tilcdc_set(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_VSYNC); 363 + else 364 + tilcdc_clear(dev, LCDC_RASTER_TIMING_2_REG, LCDC_INVERT_VSYNC); 365 + 366 + if (info->raster_order) 367 + tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ORDER); 368 + else 369 + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, LCDC_RASTER_ORDER); 370 + 371 + 372 + update_scanout(crtc); 373 + tilcdc_crtc_update_clk(crtc); 374 + 375 + pm_runtime_put_sync(dev->dev); 376 + 377 + return 0; 378 + } 379 + 380 + static int tilcdc_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 381 + struct drm_framebuffer *old_fb) 382 + { 383 + update_scanout(crtc); 384 + return 0; 385 + } 386 + 387 + static void tilcdc_crtc_load_lut(struct drm_crtc *crtc) 388 + { 389 + } 390 + 391 + static const struct drm_crtc_funcs tilcdc_crtc_funcs = { 392 + .destroy = tilcdc_crtc_destroy, 393 + .set_config = drm_crtc_helper_set_config, 394 + .page_flip = tilcdc_crtc_page_flip, 395 + }; 396 + 397 + static const struct drm_crtc_helper_funcs tilcdc_crtc_helper_funcs = { 398 + .dpms = tilcdc_crtc_dpms, 399 + .mode_fixup = tilcdc_crtc_mode_fixup, 400 + .prepare = tilcdc_crtc_prepare, 401 + .commit = tilcdc_crtc_commit, 402 + .mode_set = tilcdc_crtc_mode_set, 403 + .mode_set_base = tilcdc_crtc_mode_set_base, 404 + .load_lut = tilcdc_crtc_load_lut, 405 + }; 406 + 407 + int tilcdc_crtc_max_width(struct drm_crtc *crtc) 408 + { 409 + struct drm_device *dev = crtc->dev; 410 + struct tilcdc_drm_private *priv = dev->dev_private; 411 + int max_width = 0; 412 + 413 + if (priv->rev == 1) 414 + max_width = 1024; 415 + else if (priv->rev == 2) 416 + max_width = 2048; 417 + 418 + return max_width; 419 + } 420 + 421 + int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode) 422 + { 423 + struct tilcdc_drm_private *priv = crtc->dev->dev_private; 424 + unsigned int bandwidth; 425 + 426 + if (mode->hdisplay > tilcdc_crtc_max_width(crtc)) 427 + return MODE_VIRTUAL_X; 428 + 429 + /* width must be multiple of 16 */ 430 + if (mode->hdisplay & 0xf) 431 + return MODE_VIRTUAL_X; 432 + 433 + if (mode->vdisplay > 2048) 434 + return MODE_VIRTUAL_Y; 435 + 436 + /* filter out modes that would require too much memory bandwidth: */ 437 + bandwidth = mode->hdisplay * mode->vdisplay * drm_mode_vrefresh(mode); 438 + if (bandwidth > priv->max_bandwidth) 439 + return MODE_BAD; 440 + 441 + return MODE_OK; 442 + } 443 + 444 + void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc, 445 + const struct tilcdc_panel_info *info) 446 + { 447 + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 448 + tilcdc_crtc->info = info; 449 + } 450 + 451 + void tilcdc_crtc_update_clk(struct drm_crtc *crtc) 452 + { 453 + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 454 + struct drm_device *dev = crtc->dev; 455 + struct tilcdc_drm_private *priv = dev->dev_private; 456 + int dpms = tilcdc_crtc->dpms; 457 + unsigned int lcd_clk, div; 458 + int ret; 459 + 460 + pm_runtime_get_sync(dev->dev); 461 + 462 + if (dpms == DRM_MODE_DPMS_ON) 463 + tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); 464 + 465 + /* in raster mode, minimum divisor is 2: */ 466 + ret = clk_set_rate(priv->disp_clk, crtc->mode.clock * 1000 * 2); 467 + if (ret) { 468 + dev_err(dev->dev, "failed to set display clock rate to: %d\n", 469 + crtc->mode.clock); 470 + goto out; 471 + } 472 + 473 + lcd_clk = clk_get_rate(priv->clk); 474 + div = lcd_clk / (crtc->mode.clock * 1000); 475 + 476 + DBG("lcd_clk=%u, mode clock=%d, div=%u", lcd_clk, crtc->mode.clock, div); 477 + DBG("fck=%lu, dpll_disp_ck=%lu", clk_get_rate(priv->clk), clk_get_rate(priv->disp_clk)); 478 + 479 + /* Configure the LCD clock divisor. */ 480 + tilcdc_write(dev, LCDC_CTRL_REG, LCDC_CLK_DIVISOR(div) | 481 + LCDC_RASTER_MODE); 482 + 483 + if (priv->rev == 2) 484 + tilcdc_set(dev, LCDC_CLK_ENABLE_REG, 485 + LCDC_V2_DMA_CLK_EN | LCDC_V2_LIDD_CLK_EN | 486 + LCDC_V2_CORE_CLK_EN); 487 + 488 + if (dpms == DRM_MODE_DPMS_ON) 489 + tilcdc_crtc_dpms(crtc, DRM_MODE_DPMS_ON); 490 + 491 + out: 492 + pm_runtime_put_sync(dev->dev); 493 + } 494 + 495 + irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc) 496 + { 497 + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 498 + struct drm_device *dev = crtc->dev; 499 + struct tilcdc_drm_private *priv = dev->dev_private; 500 + uint32_t stat = tilcdc_read_irqstatus(dev); 501 + 502 + if ((stat & LCDC_SYNC_LOST) && (stat & LCDC_FIFO_UNDERFLOW)) { 503 + stop(crtc); 504 + dev_err(dev->dev, "error: %08x\n", stat); 505 + tilcdc_clear_irqstatus(dev, stat); 506 + start(crtc); 507 + } else if (stat & LCDC_PL_LOAD_DONE) { 508 + tilcdc_clear_irqstatus(dev, stat); 509 + } else { 510 + struct drm_pending_vblank_event *event; 511 + unsigned long flags; 512 + uint32_t dirty = tilcdc_crtc->dirty & stat; 513 + 514 + tilcdc_clear_irqstatus(dev, stat); 515 + 516 + if (dirty & LCDC_END_OF_FRAME0) 517 + set_scanout(crtc, 0); 518 + 519 + if (dirty & LCDC_END_OF_FRAME1) 520 + set_scanout(crtc, 1); 521 + 522 + drm_handle_vblank(dev, 0); 523 + 524 + spin_lock_irqsave(&dev->event_lock, flags); 525 + event = tilcdc_crtc->event; 526 + tilcdc_crtc->event = NULL; 527 + if (event) 528 + drm_send_vblank_event(dev, 0, event); 529 + spin_unlock_irqrestore(&dev->event_lock, flags); 530 + 531 + if (dirty && !tilcdc_crtc->dirty) 532 + drm_vblank_put(dev, 0); 533 + } 534 + 535 + if (priv->rev == 2) { 536 + if (stat & LCDC_FRAME_DONE) { 537 + tilcdc_crtc->frame_done = true; 538 + wake_up(&tilcdc_crtc->frame_done_wq); 539 + } 540 + tilcdc_write(dev, LCDC_END_OF_INT_IND_REG, 0); 541 + } 542 + 543 + return IRQ_HANDLED; 544 + } 545 + 546 + void tilcdc_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) 547 + { 548 + struct tilcdc_crtc *tilcdc_crtc = to_tilcdc_crtc(crtc); 549 + struct drm_pending_vblank_event *event; 550 + struct drm_device *dev = crtc->dev; 551 + unsigned long flags; 552 + 553 + /* Destroy the pending vertical blanking event associated with the 554 + * pending page flip, if any, and disable vertical blanking interrupts. 555 + */ 556 + spin_lock_irqsave(&dev->event_lock, flags); 557 + event = tilcdc_crtc->event; 558 + if (event && event->base.file_priv == file) { 559 + tilcdc_crtc->event = NULL; 560 + event->base.destroy(&event->base); 561 + drm_vblank_put(dev, 0); 562 + } 563 + spin_unlock_irqrestore(&dev->event_lock, flags); 564 + } 565 + 566 + struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev) 567 + { 568 + struct tilcdc_crtc *tilcdc_crtc; 569 + struct drm_crtc *crtc; 570 + int ret; 571 + 572 + tilcdc_crtc = kzalloc(sizeof(*tilcdc_crtc), GFP_KERNEL); 573 + if (!tilcdc_crtc) { 574 + dev_err(dev->dev, "allocation failed\n"); 575 + return NULL; 576 + } 577 + 578 + crtc = &tilcdc_crtc->base; 579 + 580 + tilcdc_crtc->dpms = DRM_MODE_DPMS_OFF; 581 + init_waitqueue_head(&tilcdc_crtc->frame_done_wq); 582 + 583 + ret = kfifo_alloc(&tilcdc_crtc->unref_fifo, 16, GFP_KERNEL); 584 + if (ret) { 585 + dev_err(dev->dev, "could not allocate unref FIFO\n"); 586 + goto fail; 587 + } 588 + 589 + INIT_WORK(&tilcdc_crtc->work, unref_worker); 590 + 591 + ret = drm_crtc_init(dev, crtc, &tilcdc_crtc_funcs); 592 + if (ret < 0) 593 + goto fail; 594 + 595 + drm_crtc_helper_add(crtc, &tilcdc_crtc_helper_funcs); 596 + 597 + return crtc; 598 + 599 + fail: 600 + tilcdc_crtc_destroy(crtc); 601 + return NULL; 602 + }
+611
drivers/gpu/drm/tilcdc/tilcdc_drv.c
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + /* LCDC DRM driver, based on da8xx-fb */ 19 + 20 + #include "tilcdc_drv.h" 21 + #include "tilcdc_regs.h" 22 + #include "tilcdc_tfp410.h" 23 + #include "tilcdc_slave.h" 24 + #include "tilcdc_panel.h" 25 + 26 + #include "drm_fb_helper.h" 27 + 28 + static LIST_HEAD(module_list); 29 + 30 + void tilcdc_module_init(struct tilcdc_module *mod, const char *name, 31 + const struct tilcdc_module_ops *funcs) 32 + { 33 + mod->name = name; 34 + mod->funcs = funcs; 35 + INIT_LIST_HEAD(&mod->list); 36 + list_add(&mod->list, &module_list); 37 + } 38 + 39 + void tilcdc_module_cleanup(struct tilcdc_module *mod) 40 + { 41 + list_del(&mod->list); 42 + } 43 + 44 + static struct of_device_id tilcdc_of_match[]; 45 + 46 + static struct drm_framebuffer *tilcdc_fb_create(struct drm_device *dev, 47 + struct drm_file *file_priv, struct drm_mode_fb_cmd2 *mode_cmd) 48 + { 49 + return drm_fb_cma_create(dev, file_priv, mode_cmd); 50 + } 51 + 52 + static void tilcdc_fb_output_poll_changed(struct drm_device *dev) 53 + { 54 + struct tilcdc_drm_private *priv = dev->dev_private; 55 + if (priv->fbdev) 56 + drm_fbdev_cma_hotplug_event(priv->fbdev); 57 + } 58 + 59 + static const struct drm_mode_config_funcs mode_config_funcs = { 60 + .fb_create = tilcdc_fb_create, 61 + .output_poll_changed = tilcdc_fb_output_poll_changed, 62 + }; 63 + 64 + static int modeset_init(struct drm_device *dev) 65 + { 66 + struct tilcdc_drm_private *priv = dev->dev_private; 67 + struct tilcdc_module *mod; 68 + 69 + drm_mode_config_init(dev); 70 + 71 + priv->crtc = tilcdc_crtc_create(dev); 72 + 73 + list_for_each_entry(mod, &module_list, list) { 74 + DBG("loading module: %s", mod->name); 75 + mod->funcs->modeset_init(mod, dev); 76 + } 77 + 78 + if ((priv->num_encoders = 0) || (priv->num_connectors == 0)) { 79 + /* oh nos! */ 80 + dev_err(dev->dev, "no encoders/connectors found\n"); 81 + return -ENXIO; 82 + } 83 + 84 + dev->mode_config.min_width = 0; 85 + dev->mode_config.min_height = 0; 86 + dev->mode_config.max_width = tilcdc_crtc_max_width(priv->crtc); 87 + dev->mode_config.max_height = 2048; 88 + dev->mode_config.funcs = &mode_config_funcs; 89 + 90 + return 0; 91 + } 92 + 93 + #ifdef CONFIG_CPU_FREQ 94 + static int cpufreq_transition(struct notifier_block *nb, 95 + unsigned long val, void *data) 96 + { 97 + struct tilcdc_drm_private *priv = container_of(nb, 98 + struct tilcdc_drm_private, freq_transition); 99 + if (val == CPUFREQ_POSTCHANGE) { 100 + if (priv->lcd_fck_rate != clk_get_rate(priv->clk)) { 101 + priv->lcd_fck_rate = clk_get_rate(priv->clk); 102 + tilcdc_crtc_update_clk(priv->crtc); 103 + } 104 + } 105 + 106 + return 0; 107 + } 108 + #endif 109 + 110 + /* 111 + * DRM operations: 112 + */ 113 + 114 + static int tilcdc_unload(struct drm_device *dev) 115 + { 116 + struct tilcdc_drm_private *priv = dev->dev_private; 117 + struct tilcdc_module *mod, *cur; 118 + 119 + drm_kms_helper_poll_fini(dev); 120 + drm_mode_config_cleanup(dev); 121 + drm_vblank_cleanup(dev); 122 + 123 + pm_runtime_get_sync(dev->dev); 124 + drm_irq_uninstall(dev); 125 + pm_runtime_put_sync(dev->dev); 126 + 127 + #ifdef CONFIG_CPU_FREQ 128 + cpufreq_unregister_notifier(&priv->freq_transition, 129 + CPUFREQ_TRANSITION_NOTIFIER); 130 + #endif 131 + 132 + if (priv->clk) 133 + clk_put(priv->clk); 134 + 135 + if (priv->mmio) 136 + iounmap(priv->mmio); 137 + 138 + flush_workqueue(priv->wq); 139 + destroy_workqueue(priv->wq); 140 + 141 + dev->dev_private = NULL; 142 + 143 + pm_runtime_disable(dev->dev); 144 + 145 + list_for_each_entry_safe(mod, cur, &module_list, list) { 146 + DBG("destroying module: %s", mod->name); 147 + mod->funcs->destroy(mod); 148 + } 149 + 150 + kfree(priv); 151 + 152 + return 0; 153 + } 154 + 155 + static int tilcdc_load(struct drm_device *dev, unsigned long flags) 156 + { 157 + struct platform_device *pdev = dev->platformdev; 158 + struct device_node *node = pdev->dev.of_node; 159 + struct tilcdc_drm_private *priv; 160 + struct resource *res; 161 + int ret; 162 + 163 + priv = kzalloc(sizeof(*priv), GFP_KERNEL); 164 + if (!priv) { 165 + dev_err(dev->dev, "failed to allocate private data\n"); 166 + return -ENOMEM; 167 + } 168 + 169 + dev->dev_private = priv; 170 + 171 + priv->wq = alloc_ordered_workqueue("tilcdc", 0); 172 + 173 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 174 + if (!res) { 175 + dev_err(dev->dev, "failed to get memory resource\n"); 176 + ret = -EINVAL; 177 + goto fail; 178 + } 179 + 180 + priv->mmio = ioremap_nocache(res->start, resource_size(res)); 181 + if (!priv->mmio) { 182 + dev_err(dev->dev, "failed to ioremap\n"); 183 + ret = -ENOMEM; 184 + goto fail; 185 + } 186 + 187 + priv->clk = clk_get(dev->dev, "fck"); 188 + if (IS_ERR(priv->clk)) { 189 + dev_err(dev->dev, "failed to get functional clock\n"); 190 + ret = -ENODEV; 191 + goto fail; 192 + } 193 + 194 + priv->disp_clk = clk_get(dev->dev, "dpll_disp_ck"); 195 + if (IS_ERR(priv->clk)) { 196 + dev_err(dev->dev, "failed to get display clock\n"); 197 + ret = -ENODEV; 198 + goto fail; 199 + } 200 + 201 + #ifdef CONFIG_CPU_FREQ 202 + priv->lcd_fck_rate = clk_get_rate(priv->clk); 203 + priv->freq_transition.notifier_call = cpufreq_transition; 204 + ret = cpufreq_register_notifier(&priv->freq_transition, 205 + CPUFREQ_TRANSITION_NOTIFIER); 206 + if (ret) { 207 + dev_err(dev->dev, "failed to register cpufreq notifier\n"); 208 + goto fail; 209 + } 210 + #endif 211 + 212 + if (of_property_read_u32(node, "max-bandwidth", &priv->max_bandwidth)) 213 + priv->max_bandwidth = 1280 * 1024 * 60; 214 + 215 + pm_runtime_enable(dev->dev); 216 + 217 + /* Determine LCD IP Version */ 218 + pm_runtime_get_sync(dev->dev); 219 + switch (tilcdc_read(dev, LCDC_PID_REG)) { 220 + case 0x4c100102: 221 + priv->rev = 1; 222 + break; 223 + case 0x4f200800: 224 + case 0x4f201000: 225 + priv->rev = 2; 226 + break; 227 + default: 228 + dev_warn(dev->dev, "Unknown PID Reg value 0x%08x, " 229 + "defaulting to LCD revision 1\n", 230 + tilcdc_read(dev, LCDC_PID_REG)); 231 + priv->rev = 1; 232 + break; 233 + } 234 + 235 + pm_runtime_put_sync(dev->dev); 236 + 237 + ret = modeset_init(dev); 238 + if (ret < 0) { 239 + dev_err(dev->dev, "failed to initialize mode setting\n"); 240 + goto fail; 241 + } 242 + 243 + ret = drm_vblank_init(dev, 1); 244 + if (ret < 0) { 245 + dev_err(dev->dev, "failed to initialize vblank\n"); 246 + goto fail; 247 + } 248 + 249 + pm_runtime_get_sync(dev->dev); 250 + ret = drm_irq_install(dev); 251 + pm_runtime_put_sync(dev->dev); 252 + if (ret < 0) { 253 + dev_err(dev->dev, "failed to install IRQ handler\n"); 254 + goto fail; 255 + } 256 + 257 + platform_set_drvdata(pdev, dev); 258 + 259 + priv->fbdev = drm_fbdev_cma_init(dev, 16, 260 + dev->mode_config.num_crtc, 261 + dev->mode_config.num_connector); 262 + 263 + drm_kms_helper_poll_init(dev); 264 + 265 + return 0; 266 + 267 + fail: 268 + tilcdc_unload(dev); 269 + return ret; 270 + } 271 + 272 + static void tilcdc_preclose(struct drm_device *dev, struct drm_file *file) 273 + { 274 + struct tilcdc_drm_private *priv = dev->dev_private; 275 + 276 + tilcdc_crtc_cancel_page_flip(priv->crtc, file); 277 + } 278 + 279 + static void tilcdc_lastclose(struct drm_device *dev) 280 + { 281 + struct tilcdc_drm_private *priv = dev->dev_private; 282 + drm_fbdev_cma_restore_mode(priv->fbdev); 283 + } 284 + 285 + static irqreturn_t tilcdc_irq(DRM_IRQ_ARGS) 286 + { 287 + struct drm_device *dev = arg; 288 + struct tilcdc_drm_private *priv = dev->dev_private; 289 + return tilcdc_crtc_irq(priv->crtc); 290 + } 291 + 292 + static void tilcdc_irq_preinstall(struct drm_device *dev) 293 + { 294 + tilcdc_clear_irqstatus(dev, 0xffffffff); 295 + } 296 + 297 + static int tilcdc_irq_postinstall(struct drm_device *dev) 298 + { 299 + struct tilcdc_drm_private *priv = dev->dev_private; 300 + 301 + /* enable FIFO underflow irq: */ 302 + if (priv->rev == 1) { 303 + tilcdc_set(dev, LCDC_RASTER_CTRL_REG, LCDC_V1_UNDERFLOW_INT_ENA); 304 + } else { 305 + tilcdc_set(dev, LCDC_INT_ENABLE_SET_REG, LCDC_V2_UNDERFLOW_INT_ENA); 306 + } 307 + 308 + return 0; 309 + } 310 + 311 + static void tilcdc_irq_uninstall(struct drm_device *dev) 312 + { 313 + struct tilcdc_drm_private *priv = dev->dev_private; 314 + 315 + /* disable irqs that we might have enabled: */ 316 + if (priv->rev == 1) { 317 + tilcdc_clear(dev, LCDC_RASTER_CTRL_REG, 318 + LCDC_V1_UNDERFLOW_INT_ENA | LCDC_V1_PL_INT_ENA); 319 + tilcdc_clear(dev, LCDC_DMA_CTRL_REG, LCDC_V1_END_OF_FRAME_INT_ENA); 320 + } else { 321 + tilcdc_clear(dev, LCDC_INT_ENABLE_SET_REG, 322 + LCDC_V2_UNDERFLOW_INT_ENA | LCDC_V2_PL_INT_ENA | 323 + LCDC_V2_END_OF_FRAME0_INT_ENA | LCDC_V2_END_OF_FRAME1_INT_ENA | 324 + LCDC_FRAME_DONE); 325 + } 326 + 327 + } 328 + 329 + static void enable_vblank(struct drm_device *dev, bool enable) 330 + { 331 + struct tilcdc_drm_private *priv = dev->dev_private; 332 + u32 reg, mask; 333 + 334 + if (priv->rev == 1) { 335 + reg = LCDC_DMA_CTRL_REG; 336 + mask = LCDC_V1_END_OF_FRAME_INT_ENA; 337 + } else { 338 + reg = LCDC_INT_ENABLE_SET_REG; 339 + mask = LCDC_V2_END_OF_FRAME0_INT_ENA | 340 + LCDC_V2_END_OF_FRAME1_INT_ENA | LCDC_FRAME_DONE; 341 + } 342 + 343 + if (enable) 344 + tilcdc_set(dev, reg, mask); 345 + else 346 + tilcdc_clear(dev, reg, mask); 347 + } 348 + 349 + static int tilcdc_enable_vblank(struct drm_device *dev, int crtc) 350 + { 351 + enable_vblank(dev, true); 352 + return 0; 353 + } 354 + 355 + static void tilcdc_disable_vblank(struct drm_device *dev, int crtc) 356 + { 357 + enable_vblank(dev, false); 358 + } 359 + 360 + #if defined(CONFIG_DEBUG_FS) || defined(CONFIG_PM_SLEEP) 361 + static const struct { 362 + const char *name; 363 + uint8_t rev; 364 + uint8_t save; 365 + uint32_t reg; 366 + } registers[] = { 367 + #define REG(rev, save, reg) { #reg, rev, save, reg } 368 + /* exists in revision 1: */ 369 + REG(1, false, LCDC_PID_REG), 370 + REG(1, true, LCDC_CTRL_REG), 371 + REG(1, false, LCDC_STAT_REG), 372 + REG(1, true, LCDC_RASTER_CTRL_REG), 373 + REG(1, true, LCDC_RASTER_TIMING_0_REG), 374 + REG(1, true, LCDC_RASTER_TIMING_1_REG), 375 + REG(1, true, LCDC_RASTER_TIMING_2_REG), 376 + REG(1, true, LCDC_DMA_CTRL_REG), 377 + REG(1, true, LCDC_DMA_FB_BASE_ADDR_0_REG), 378 + REG(1, true, LCDC_DMA_FB_CEILING_ADDR_0_REG), 379 + REG(1, true, LCDC_DMA_FB_BASE_ADDR_1_REG), 380 + REG(1, true, LCDC_DMA_FB_CEILING_ADDR_1_REG), 381 + /* new in revision 2: */ 382 + REG(2, false, LCDC_RAW_STAT_REG), 383 + REG(2, false, LCDC_MASKED_STAT_REG), 384 + REG(2, false, LCDC_INT_ENABLE_SET_REG), 385 + REG(2, false, LCDC_INT_ENABLE_CLR_REG), 386 + REG(2, false, LCDC_END_OF_INT_IND_REG), 387 + REG(2, true, LCDC_CLK_ENABLE_REG), 388 + REG(2, true, LCDC_INT_ENABLE_SET_REG), 389 + #undef REG 390 + }; 391 + #endif 392 + 393 + #ifdef CONFIG_DEBUG_FS 394 + static int tilcdc_regs_show(struct seq_file *m, void *arg) 395 + { 396 + struct drm_info_node *node = (struct drm_info_node *) m->private; 397 + struct drm_device *dev = node->minor->dev; 398 + struct tilcdc_drm_private *priv = dev->dev_private; 399 + unsigned i; 400 + 401 + pm_runtime_get_sync(dev->dev); 402 + 403 + seq_printf(m, "revision: %d\n", priv->rev); 404 + 405 + for (i = 0; i < ARRAY_SIZE(registers); i++) 406 + if (priv->rev >= registers[i].rev) 407 + seq_printf(m, "%s:\t %08x\n", registers[i].name, 408 + tilcdc_read(dev, registers[i].reg)); 409 + 410 + pm_runtime_put_sync(dev->dev); 411 + 412 + return 0; 413 + } 414 + 415 + static int tilcdc_mm_show(struct seq_file *m, void *arg) 416 + { 417 + struct drm_info_node *node = (struct drm_info_node *) m->private; 418 + struct drm_device *dev = node->minor->dev; 419 + return drm_mm_dump_table(m, dev->mm_private); 420 + } 421 + 422 + static struct drm_info_list tilcdc_debugfs_list[] = { 423 + { "regs", tilcdc_regs_show, 0 }, 424 + { "mm", tilcdc_mm_show, 0 }, 425 + { "fb", drm_fb_cma_debugfs_show, 0 }, 426 + }; 427 + 428 + static int tilcdc_debugfs_init(struct drm_minor *minor) 429 + { 430 + struct drm_device *dev = minor->dev; 431 + struct tilcdc_module *mod; 432 + int ret; 433 + 434 + ret = drm_debugfs_create_files(tilcdc_debugfs_list, 435 + ARRAY_SIZE(tilcdc_debugfs_list), 436 + minor->debugfs_root, minor); 437 + 438 + list_for_each_entry(mod, &module_list, list) 439 + if (mod->funcs->debugfs_init) 440 + mod->funcs->debugfs_init(mod, minor); 441 + 442 + if (ret) { 443 + dev_err(dev->dev, "could not install tilcdc_debugfs_list\n"); 444 + return ret; 445 + } 446 + 447 + return ret; 448 + } 449 + 450 + static void tilcdc_debugfs_cleanup(struct drm_minor *minor) 451 + { 452 + struct tilcdc_module *mod; 453 + drm_debugfs_remove_files(tilcdc_debugfs_list, 454 + ARRAY_SIZE(tilcdc_debugfs_list), minor); 455 + 456 + list_for_each_entry(mod, &module_list, list) 457 + if (mod->funcs->debugfs_cleanup) 458 + mod->funcs->debugfs_cleanup(mod, minor); 459 + } 460 + #endif 461 + 462 + static const struct file_operations fops = { 463 + .owner = THIS_MODULE, 464 + .open = drm_open, 465 + .release = drm_release, 466 + .unlocked_ioctl = drm_ioctl, 467 + #ifdef CONFIG_COMPAT 468 + .compat_ioctl = drm_compat_ioctl, 469 + #endif 470 + .poll = drm_poll, 471 + .read = drm_read, 472 + .fasync = drm_fasync, 473 + .llseek = no_llseek, 474 + .mmap = drm_gem_cma_mmap, 475 + }; 476 + 477 + static struct drm_driver tilcdc_driver = { 478 + .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET, 479 + .load = tilcdc_load, 480 + .unload = tilcdc_unload, 481 + .preclose = tilcdc_preclose, 482 + .lastclose = tilcdc_lastclose, 483 + .irq_handler = tilcdc_irq, 484 + .irq_preinstall = tilcdc_irq_preinstall, 485 + .irq_postinstall = tilcdc_irq_postinstall, 486 + .irq_uninstall = tilcdc_irq_uninstall, 487 + .get_vblank_counter = drm_vblank_count, 488 + .enable_vblank = tilcdc_enable_vblank, 489 + .disable_vblank = tilcdc_disable_vblank, 490 + .gem_free_object = drm_gem_cma_free_object, 491 + .gem_vm_ops = &drm_gem_cma_vm_ops, 492 + .dumb_create = drm_gem_cma_dumb_create, 493 + .dumb_map_offset = drm_gem_cma_dumb_map_offset, 494 + .dumb_destroy = drm_gem_cma_dumb_destroy, 495 + #ifdef CONFIG_DEBUG_FS 496 + .debugfs_init = tilcdc_debugfs_init, 497 + .debugfs_cleanup = tilcdc_debugfs_cleanup, 498 + #endif 499 + .fops = &fops, 500 + .name = "tilcdc", 501 + .desc = "TI LCD Controller DRM", 502 + .date = "20121205", 503 + .major = 1, 504 + .minor = 0, 505 + }; 506 + 507 + /* 508 + * Power management: 509 + */ 510 + 511 + #ifdef CONFIG_PM_SLEEP 512 + static int tilcdc_pm_suspend(struct device *dev) 513 + { 514 + struct drm_device *ddev = dev_get_drvdata(dev); 515 + struct tilcdc_drm_private *priv = ddev->dev_private; 516 + unsigned i, n = 0; 517 + 518 + drm_kms_helper_poll_disable(ddev); 519 + 520 + /* Save register state: */ 521 + for (i = 0; i < ARRAY_SIZE(registers); i++) 522 + if (registers[i].save && (priv->rev >= registers[i].rev)) 523 + priv->saved_register[n++] = tilcdc_read(ddev, registers[i].reg); 524 + 525 + return 0; 526 + } 527 + 528 + static int tilcdc_pm_resume(struct device *dev) 529 + { 530 + struct drm_device *ddev = dev_get_drvdata(dev); 531 + struct tilcdc_drm_private *priv = ddev->dev_private; 532 + unsigned i, n = 0; 533 + 534 + /* Restore register state: */ 535 + for (i = 0; i < ARRAY_SIZE(registers); i++) 536 + if (registers[i].save && (priv->rev >= registers[i].rev)) 537 + tilcdc_write(ddev, registers[i].reg, priv->saved_register[n++]); 538 + 539 + drm_kms_helper_poll_enable(ddev); 540 + 541 + return 0; 542 + } 543 + #endif 544 + 545 + static const struct dev_pm_ops tilcdc_pm_ops = { 546 + SET_SYSTEM_SLEEP_PM_OPS(tilcdc_pm_suspend, tilcdc_pm_resume) 547 + }; 548 + 549 + /* 550 + * Platform driver: 551 + */ 552 + 553 + static int tilcdc_pdev_probe(struct platform_device *pdev) 554 + { 555 + /* bail out early if no DT data: */ 556 + if (!pdev->dev.of_node) { 557 + dev_err(&pdev->dev, "device-tree data is missing\n"); 558 + return -ENXIO; 559 + } 560 + 561 + return drm_platform_init(&tilcdc_driver, pdev); 562 + } 563 + 564 + static int tilcdc_pdev_remove(struct platform_device *pdev) 565 + { 566 + drm_platform_exit(&tilcdc_driver, pdev); 567 + 568 + return 0; 569 + } 570 + 571 + static struct of_device_id tilcdc_of_match[] = { 572 + { .compatible = "ti,am33xx-tilcdc", }, 573 + { }, 574 + }; 575 + MODULE_DEVICE_TABLE(of, tilcdc_of_match); 576 + 577 + static struct platform_driver tilcdc_platform_driver = { 578 + .probe = tilcdc_pdev_probe, 579 + .remove = tilcdc_pdev_remove, 580 + .driver = { 581 + .owner = THIS_MODULE, 582 + .name = "tilcdc", 583 + .pm = &tilcdc_pm_ops, 584 + .of_match_table = tilcdc_of_match, 585 + }, 586 + }; 587 + 588 + static int __init tilcdc_drm_init(void) 589 + { 590 + DBG("init"); 591 + tilcdc_tfp410_init(); 592 + tilcdc_slave_init(); 593 + tilcdc_panel_init(); 594 + return platform_driver_register(&tilcdc_platform_driver); 595 + } 596 + 597 + static void __exit tilcdc_drm_fini(void) 598 + { 599 + DBG("fini"); 600 + tilcdc_tfp410_fini(); 601 + tilcdc_slave_fini(); 602 + tilcdc_panel_fini(); 603 + platform_driver_unregister(&tilcdc_platform_driver); 604 + } 605 + 606 + late_initcall(tilcdc_drm_init); 607 + module_exit(tilcdc_drm_fini); 608 + 609 + MODULE_AUTHOR("Rob Clark <robdclark@gmail.com"); 610 + MODULE_DESCRIPTION("TI LCD Controller DRM Driver"); 611 + MODULE_LICENSE("GPL");
+150
drivers/gpu/drm/tilcdc/tilcdc_drv.h
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #ifndef __TILCDC_DRV_H__ 19 + #define __TILCDC_DRV_H__ 20 + 21 + #include <linux/clk.h> 22 + #include <linux/cpufreq.h> 23 + #include <linux/module.h> 24 + #include <linux/platform_device.h> 25 + #include <linux/pm.h> 26 + #include <linux/pm_runtime.h> 27 + #include <linux/slab.h> 28 + #include <linux/of.h> 29 + #include <linux/of_device.h> 30 + #include <linux/list.h> 31 + 32 + #include <drm/drmP.h> 33 + #include <drm/drm_crtc_helper.h> 34 + #include <drm/drm_gem_cma_helper.h> 35 + #include <drm/drm_fb_cma_helper.h> 36 + 37 + struct tilcdc_drm_private { 38 + void __iomem *mmio; 39 + 40 + struct clk *disp_clk; /* display dpll */ 41 + struct clk *clk; /* functional clock */ 42 + int rev; /* IP revision */ 43 + 44 + /* don't attempt resolutions w/ higher W * H * Hz: */ 45 + uint32_t max_bandwidth; 46 + 47 + /* register contents saved across suspend/resume: */ 48 + u32 saved_register[12]; 49 + 50 + #ifdef CONFIG_CPU_FREQ 51 + struct notifier_block freq_transition; 52 + unsigned int lcd_fck_rate; 53 + #endif 54 + 55 + struct workqueue_struct *wq; 56 + 57 + struct drm_fbdev_cma *fbdev; 58 + 59 + struct drm_crtc *crtc; 60 + 61 + unsigned int num_encoders; 62 + struct drm_encoder *encoders[8]; 63 + 64 + unsigned int num_connectors; 65 + struct drm_connector *connectors[8]; 66 + }; 67 + 68 + /* Sub-module for display. Since we don't know at compile time what panels 69 + * or display adapter(s) might be present (for ex, off chip dvi/tfp410, 70 + * hdmi encoder, various lcd panels), the connector/encoder(s) are split into 71 + * separate drivers. If they are probed and found to be present, they 72 + * register themselves with tilcdc_register_module(). 73 + */ 74 + struct tilcdc_module; 75 + 76 + struct tilcdc_module_ops { 77 + /* create appropriate encoders/connectors: */ 78 + int (*modeset_init)(struct tilcdc_module *mod, struct drm_device *dev); 79 + void (*destroy)(struct tilcdc_module *mod); 80 + #ifdef CONFIG_DEBUG_FS 81 + /* create debugfs nodes (can be NULL): */ 82 + int (*debugfs_init)(struct tilcdc_module *mod, struct drm_minor *minor); 83 + /* cleanup debugfs nodes (can be NULL): */ 84 + void (*debugfs_cleanup)(struct tilcdc_module *mod, struct drm_minor *minor); 85 + #endif 86 + }; 87 + 88 + struct tilcdc_module { 89 + const char *name; 90 + struct list_head list; 91 + const struct tilcdc_module_ops *funcs; 92 + }; 93 + 94 + void tilcdc_module_init(struct tilcdc_module *mod, const char *name, 95 + const struct tilcdc_module_ops *funcs); 96 + void tilcdc_module_cleanup(struct tilcdc_module *mod); 97 + 98 + 99 + /* Panel config that needs to be set in the crtc, but is not coming from 100 + * the mode timings. The display module is expected to call 101 + * tilcdc_crtc_set_panel_info() to set this during modeset. 102 + */ 103 + struct tilcdc_panel_info { 104 + 105 + /* AC Bias Pin Frequency */ 106 + uint32_t ac_bias; 107 + 108 + /* AC Bias Pin Transitions per Interrupt */ 109 + uint32_t ac_bias_intrpt; 110 + 111 + /* DMA burst size */ 112 + uint32_t dma_burst_sz; 113 + 114 + /* Bits per pixel */ 115 + uint32_t bpp; 116 + 117 + /* FIFO DMA Request Delay */ 118 + uint32_t fdd; 119 + 120 + /* TFT Alternative Signal Mapping (Only for active) */ 121 + bool tft_alt_mode; 122 + 123 + /* Invert pixel clock */ 124 + bool invert_pxl_clk; 125 + 126 + /* Horizontal and Vertical Sync Edge: 0=rising 1=falling */ 127 + uint32_t sync_edge; 128 + 129 + /* Horizontal and Vertical Sync: Control: 0=ignore */ 130 + uint32_t sync_ctrl; 131 + 132 + /* Raster Data Order Select: 1=Most-to-least 0=Least-to-most */ 133 + uint32_t raster_order; 134 + 135 + /* DMA FIFO threshold */ 136 + uint32_t fifo_th; 137 + }; 138 + 139 + #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) 140 + 141 + struct drm_crtc *tilcdc_crtc_create(struct drm_device *dev); 142 + void tilcdc_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); 143 + irqreturn_t tilcdc_crtc_irq(struct drm_crtc *crtc); 144 + void tilcdc_crtc_update_clk(struct drm_crtc *crtc); 145 + void tilcdc_crtc_set_panel_info(struct drm_crtc *crtc, 146 + const struct tilcdc_panel_info *info); 147 + int tilcdc_crtc_mode_valid(struct drm_crtc *crtc, struct drm_display_mode *mode); 148 + int tilcdc_crtc_max_width(struct drm_crtc *crtc); 149 + 150 + #endif /* __TILCDC_DRV_H__ */
+436
drivers/gpu/drm/tilcdc/tilcdc_panel.c
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #include <linux/pinctrl/pinmux.h> 19 + #include <linux/pinctrl/consumer.h> 20 + #include <linux/backlight.h> 21 + #include <video/display_timing.h> 22 + #include <video/of_display_timing.h> 23 + #include <video/videomode.h> 24 + 25 + #include "tilcdc_drv.h" 26 + 27 + struct panel_module { 28 + struct tilcdc_module base; 29 + struct tilcdc_panel_info *info; 30 + struct display_timings *timings; 31 + struct backlight_device *backlight; 32 + }; 33 + #define to_panel_module(x) container_of(x, struct panel_module, base) 34 + 35 + 36 + /* 37 + * Encoder: 38 + */ 39 + 40 + struct panel_encoder { 41 + struct drm_encoder base; 42 + struct panel_module *mod; 43 + }; 44 + #define to_panel_encoder(x) container_of(x, struct panel_encoder, base) 45 + 46 + 47 + static void panel_encoder_destroy(struct drm_encoder *encoder) 48 + { 49 + struct panel_encoder *panel_encoder = to_panel_encoder(encoder); 50 + drm_encoder_cleanup(encoder); 51 + kfree(panel_encoder); 52 + } 53 + 54 + static void panel_encoder_dpms(struct drm_encoder *encoder, int mode) 55 + { 56 + struct panel_encoder *panel_encoder = to_panel_encoder(encoder); 57 + struct backlight_device *backlight = panel_encoder->mod->backlight; 58 + 59 + if (!backlight) 60 + return; 61 + 62 + backlight->props.power = mode == DRM_MODE_DPMS_ON 63 + ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; 64 + backlight_update_status(backlight); 65 + } 66 + 67 + static bool panel_encoder_mode_fixup(struct drm_encoder *encoder, 68 + const struct drm_display_mode *mode, 69 + struct drm_display_mode *adjusted_mode) 70 + { 71 + /* nothing needed */ 72 + return true; 73 + } 74 + 75 + static void panel_encoder_prepare(struct drm_encoder *encoder) 76 + { 77 + struct panel_encoder *panel_encoder = to_panel_encoder(encoder); 78 + panel_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); 79 + tilcdc_crtc_set_panel_info(encoder->crtc, panel_encoder->mod->info); 80 + } 81 + 82 + static void panel_encoder_commit(struct drm_encoder *encoder) 83 + { 84 + panel_encoder_dpms(encoder, DRM_MODE_DPMS_ON); 85 + } 86 + 87 + static void panel_encoder_mode_set(struct drm_encoder *encoder, 88 + struct drm_display_mode *mode, 89 + struct drm_display_mode *adjusted_mode) 90 + { 91 + /* nothing needed */ 92 + } 93 + 94 + static const struct drm_encoder_funcs panel_encoder_funcs = { 95 + .destroy = panel_encoder_destroy, 96 + }; 97 + 98 + static const struct drm_encoder_helper_funcs panel_encoder_helper_funcs = { 99 + .dpms = panel_encoder_dpms, 100 + .mode_fixup = panel_encoder_mode_fixup, 101 + .prepare = panel_encoder_prepare, 102 + .commit = panel_encoder_commit, 103 + .mode_set = panel_encoder_mode_set, 104 + }; 105 + 106 + static struct drm_encoder *panel_encoder_create(struct drm_device *dev, 107 + struct panel_module *mod) 108 + { 109 + struct panel_encoder *panel_encoder; 110 + struct drm_encoder *encoder; 111 + int ret; 112 + 113 + panel_encoder = kzalloc(sizeof(*panel_encoder), GFP_KERNEL); 114 + if (!panel_encoder) { 115 + dev_err(dev->dev, "allocation failed\n"); 116 + return NULL; 117 + } 118 + 119 + panel_encoder->mod = mod; 120 + 121 + encoder = &panel_encoder->base; 122 + encoder->possible_crtcs = 1; 123 + 124 + ret = drm_encoder_init(dev, encoder, &panel_encoder_funcs, 125 + DRM_MODE_ENCODER_LVDS); 126 + if (ret < 0) 127 + goto fail; 128 + 129 + drm_encoder_helper_add(encoder, &panel_encoder_helper_funcs); 130 + 131 + return encoder; 132 + 133 + fail: 134 + panel_encoder_destroy(encoder); 135 + return NULL; 136 + } 137 + 138 + /* 139 + * Connector: 140 + */ 141 + 142 + struct panel_connector { 143 + struct drm_connector base; 144 + 145 + struct drm_encoder *encoder; /* our connected encoder */ 146 + struct panel_module *mod; 147 + }; 148 + #define to_panel_connector(x) container_of(x, struct panel_connector, base) 149 + 150 + 151 + static void panel_connector_destroy(struct drm_connector *connector) 152 + { 153 + struct panel_connector *panel_connector = to_panel_connector(connector); 154 + drm_connector_cleanup(connector); 155 + kfree(panel_connector); 156 + } 157 + 158 + static enum drm_connector_status panel_connector_detect( 159 + struct drm_connector *connector, 160 + bool force) 161 + { 162 + return connector_status_connected; 163 + } 164 + 165 + static int panel_connector_get_modes(struct drm_connector *connector) 166 + { 167 + struct drm_device *dev = connector->dev; 168 + struct panel_connector *panel_connector = to_panel_connector(connector); 169 + struct display_timings *timings = panel_connector->mod->timings; 170 + int i; 171 + 172 + for (i = 0; i < timings->num_timings; i++) { 173 + struct drm_display_mode *mode = drm_mode_create(dev); 174 + struct videomode vm; 175 + 176 + if (videomode_from_timing(timings, &vm, i)) 177 + break; 178 + 179 + drm_display_mode_from_videomode(&vm, mode); 180 + 181 + mode->type = DRM_MODE_TYPE_DRIVER; 182 + 183 + if (timings->native_mode == i) 184 + mode->type |= DRM_MODE_TYPE_PREFERRED; 185 + 186 + drm_mode_set_name(mode); 187 + drm_mode_probed_add(connector, mode); 188 + } 189 + 190 + return i; 191 + } 192 + 193 + static int panel_connector_mode_valid(struct drm_connector *connector, 194 + struct drm_display_mode *mode) 195 + { 196 + struct tilcdc_drm_private *priv = connector->dev->dev_private; 197 + /* our only constraints are what the crtc can generate: */ 198 + return tilcdc_crtc_mode_valid(priv->crtc, mode); 199 + } 200 + 201 + static struct drm_encoder *panel_connector_best_encoder( 202 + struct drm_connector *connector) 203 + { 204 + struct panel_connector *panel_connector = to_panel_connector(connector); 205 + return panel_connector->encoder; 206 + } 207 + 208 + static const struct drm_connector_funcs panel_connector_funcs = { 209 + .destroy = panel_connector_destroy, 210 + .dpms = drm_helper_connector_dpms, 211 + .detect = panel_connector_detect, 212 + .fill_modes = drm_helper_probe_single_connector_modes, 213 + }; 214 + 215 + static const struct drm_connector_helper_funcs panel_connector_helper_funcs = { 216 + .get_modes = panel_connector_get_modes, 217 + .mode_valid = panel_connector_mode_valid, 218 + .best_encoder = panel_connector_best_encoder, 219 + }; 220 + 221 + static struct drm_connector *panel_connector_create(struct drm_device *dev, 222 + struct panel_module *mod, struct drm_encoder *encoder) 223 + { 224 + struct panel_connector *panel_connector; 225 + struct drm_connector *connector; 226 + int ret; 227 + 228 + panel_connector = kzalloc(sizeof(*panel_connector), GFP_KERNEL); 229 + if (!panel_connector) { 230 + dev_err(dev->dev, "allocation failed\n"); 231 + return NULL; 232 + } 233 + 234 + panel_connector->encoder = encoder; 235 + panel_connector->mod = mod; 236 + 237 + connector = &panel_connector->base; 238 + 239 + drm_connector_init(dev, connector, &panel_connector_funcs, 240 + DRM_MODE_CONNECTOR_LVDS); 241 + drm_connector_helper_add(connector, &panel_connector_helper_funcs); 242 + 243 + connector->interlace_allowed = 0; 244 + connector->doublescan_allowed = 0; 245 + 246 + ret = drm_mode_connector_attach_encoder(connector, encoder); 247 + if (ret) 248 + goto fail; 249 + 250 + drm_sysfs_connector_add(connector); 251 + 252 + return connector; 253 + 254 + fail: 255 + panel_connector_destroy(connector); 256 + return NULL; 257 + } 258 + 259 + /* 260 + * Module: 261 + */ 262 + 263 + static int panel_modeset_init(struct tilcdc_module *mod, struct drm_device *dev) 264 + { 265 + struct panel_module *panel_mod = to_panel_module(mod); 266 + struct tilcdc_drm_private *priv = dev->dev_private; 267 + struct drm_encoder *encoder; 268 + struct drm_connector *connector; 269 + 270 + encoder = panel_encoder_create(dev, panel_mod); 271 + if (!encoder) 272 + return -ENOMEM; 273 + 274 + connector = panel_connector_create(dev, panel_mod, encoder); 275 + if (!connector) 276 + return -ENOMEM; 277 + 278 + priv->encoders[priv->num_encoders++] = encoder; 279 + priv->connectors[priv->num_connectors++] = connector; 280 + 281 + return 0; 282 + } 283 + 284 + static void panel_destroy(struct tilcdc_module *mod) 285 + { 286 + struct panel_module *panel_mod = to_panel_module(mod); 287 + 288 + if (panel_mod->timings) { 289 + display_timings_release(panel_mod->timings); 290 + kfree(panel_mod->timings); 291 + } 292 + 293 + tilcdc_module_cleanup(mod); 294 + kfree(panel_mod->info); 295 + kfree(panel_mod); 296 + } 297 + 298 + static const struct tilcdc_module_ops panel_module_ops = { 299 + .modeset_init = panel_modeset_init, 300 + .destroy = panel_destroy, 301 + }; 302 + 303 + /* 304 + * Device: 305 + */ 306 + 307 + /* maybe move this somewhere common if it is needed by other outputs? */ 308 + static struct tilcdc_panel_info * of_get_panel_info(struct device_node *np) 309 + { 310 + struct device_node *info_np; 311 + struct tilcdc_panel_info *info; 312 + int ret = 0; 313 + 314 + if (!np) { 315 + pr_err("%s: no devicenode given\n", __func__); 316 + return NULL; 317 + } 318 + 319 + info_np = of_get_child_by_name(np, "panel-info"); 320 + if (!info_np) { 321 + pr_err("%s: could not find panel-info node\n", __func__); 322 + return NULL; 323 + } 324 + 325 + info = kzalloc(sizeof(*info), GFP_KERNEL); 326 + if (!info) { 327 + pr_err("%s: allocation failed\n", __func__); 328 + return NULL; 329 + } 330 + 331 + ret |= of_property_read_u32(info_np, "ac-bias", &info->ac_bias); 332 + ret |= of_property_read_u32(info_np, "ac-bias-intrpt", &info->ac_bias_intrpt); 333 + ret |= of_property_read_u32(info_np, "dma-burst-sz", &info->dma_burst_sz); 334 + ret |= of_property_read_u32(info_np, "bpp", &info->bpp); 335 + ret |= of_property_read_u32(info_np, "fdd", &info->fdd); 336 + ret |= of_property_read_u32(info_np, "sync-edge", &info->sync_edge); 337 + ret |= of_property_read_u32(info_np, "sync-ctrl", &info->sync_ctrl); 338 + ret |= of_property_read_u32(info_np, "raster-order", &info->raster_order); 339 + ret |= of_property_read_u32(info_np, "fifo-th", &info->fifo_th); 340 + 341 + /* optional: */ 342 + info->tft_alt_mode = of_property_read_bool(info_np, "tft-alt-mode"); 343 + info->invert_pxl_clk = of_property_read_bool(info_np, "invert-pxl-clk"); 344 + 345 + if (ret) { 346 + pr_err("%s: error reading panel-info properties\n", __func__); 347 + kfree(info); 348 + return NULL; 349 + } 350 + 351 + return info; 352 + } 353 + 354 + static struct of_device_id panel_of_match[]; 355 + 356 + static int panel_probe(struct platform_device *pdev) 357 + { 358 + struct device_node *node = pdev->dev.of_node; 359 + struct panel_module *panel_mod; 360 + struct tilcdc_module *mod; 361 + struct pinctrl *pinctrl; 362 + int ret = -EINVAL; 363 + 364 + 365 + /* bail out early if no DT data: */ 366 + if (!node) { 367 + dev_err(&pdev->dev, "device-tree data is missing\n"); 368 + return -ENXIO; 369 + } 370 + 371 + panel_mod = kzalloc(sizeof(*panel_mod), GFP_KERNEL); 372 + if (!panel_mod) 373 + return -ENOMEM; 374 + 375 + mod = &panel_mod->base; 376 + 377 + tilcdc_module_init(mod, "panel", &panel_module_ops); 378 + 379 + pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 380 + if (IS_ERR(pinctrl)) 381 + dev_warn(&pdev->dev, "pins are not configured\n"); 382 + 383 + 384 + panel_mod->timings = of_get_display_timings(node); 385 + if (!panel_mod->timings) { 386 + dev_err(&pdev->dev, "could not get panel timings\n"); 387 + goto fail; 388 + } 389 + 390 + panel_mod->info = of_get_panel_info(node); 391 + if (!panel_mod->info) { 392 + dev_err(&pdev->dev, "could not get panel info\n"); 393 + goto fail; 394 + } 395 + 396 + panel_mod->backlight = of_find_backlight_by_node(node); 397 + if (panel_mod->backlight) 398 + dev_info(&pdev->dev, "found backlight\n"); 399 + 400 + return 0; 401 + 402 + fail: 403 + panel_destroy(mod); 404 + return ret; 405 + } 406 + 407 + static int panel_remove(struct platform_device *pdev) 408 + { 409 + return 0; 410 + } 411 + 412 + static struct of_device_id panel_of_match[] = { 413 + { .compatible = "ti,tilcdc,panel", }, 414 + { }, 415 + }; 416 + MODULE_DEVICE_TABLE(of, panel_of_match); 417 + 418 + struct platform_driver panel_driver = { 419 + .probe = panel_probe, 420 + .remove = panel_remove, 421 + .driver = { 422 + .owner = THIS_MODULE, 423 + .name = "panel", 424 + .of_match_table = panel_of_match, 425 + }, 426 + }; 427 + 428 + int __init tilcdc_panel_init(void) 429 + { 430 + return platform_driver_register(&panel_driver); 431 + } 432 + 433 + void __exit tilcdc_panel_fini(void) 434 + { 435 + platform_driver_unregister(&panel_driver); 436 + }
+26
drivers/gpu/drm/tilcdc/tilcdc_panel.h
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #ifndef __TILCDC_PANEL_H__ 19 + #define __TILCDC_PANEL_H__ 20 + 21 + /* sub-module for generic lcd panel output */ 22 + 23 + int tilcdc_panel_init(void); 24 + void tilcdc_panel_fini(void); 25 + 26 + #endif /* __TILCDC_PANEL_H__ */
+154
drivers/gpu/drm/tilcdc/tilcdc_regs.h
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #ifndef __TILCDC_REGS_H__ 19 + #define __TILCDC_REGS_H__ 20 + 21 + /* LCDC register definitions, based on da8xx-fb */ 22 + 23 + #include <linux/bitops.h> 24 + 25 + #include "tilcdc_drv.h" 26 + 27 + /* LCDC Status Register */ 28 + #define LCDC_END_OF_FRAME1 BIT(9) 29 + #define LCDC_END_OF_FRAME0 BIT(8) 30 + #define LCDC_PL_LOAD_DONE BIT(6) 31 + #define LCDC_FIFO_UNDERFLOW BIT(5) 32 + #define LCDC_SYNC_LOST BIT(2) 33 + #define LCDC_FRAME_DONE BIT(0) 34 + 35 + /* LCDC DMA Control Register */ 36 + #define LCDC_DMA_BURST_SIZE(x) ((x) << 4) 37 + #define LCDC_DMA_BURST_1 0x0 38 + #define LCDC_DMA_BURST_2 0x1 39 + #define LCDC_DMA_BURST_4 0x2 40 + #define LCDC_DMA_BURST_8 0x3 41 + #define LCDC_DMA_BURST_16 0x4 42 + #define LCDC_V1_END_OF_FRAME_INT_ENA BIT(2) 43 + #define LCDC_V2_END_OF_FRAME0_INT_ENA BIT(8) 44 + #define LCDC_V2_END_OF_FRAME1_INT_ENA BIT(9) 45 + #define LCDC_DUAL_FRAME_BUFFER_ENABLE BIT(0) 46 + 47 + /* LCDC Control Register */ 48 + #define LCDC_CLK_DIVISOR(x) ((x) << 8) 49 + #define LCDC_RASTER_MODE 0x01 50 + 51 + /* LCDC Raster Control Register */ 52 + #define LCDC_PALETTE_LOAD_MODE(x) ((x) << 20) 53 + #define PALETTE_AND_DATA 0x00 54 + #define PALETTE_ONLY 0x01 55 + #define DATA_ONLY 0x02 56 + 57 + #define LCDC_MONO_8BIT_MODE BIT(9) 58 + #define LCDC_RASTER_ORDER BIT(8) 59 + #define LCDC_TFT_MODE BIT(7) 60 + #define LCDC_V1_UNDERFLOW_INT_ENA BIT(6) 61 + #define LCDC_V2_UNDERFLOW_INT_ENA BIT(5) 62 + #define LCDC_V1_PL_INT_ENA BIT(4) 63 + #define LCDC_V2_PL_INT_ENA BIT(6) 64 + #define LCDC_MONOCHROME_MODE BIT(1) 65 + #define LCDC_RASTER_ENABLE BIT(0) 66 + #define LCDC_TFT_ALT_ENABLE BIT(23) 67 + #define LCDC_STN_565_ENABLE BIT(24) 68 + #define LCDC_V2_DMA_CLK_EN BIT(2) 69 + #define LCDC_V2_LIDD_CLK_EN BIT(1) 70 + #define LCDC_V2_CORE_CLK_EN BIT(0) 71 + #define LCDC_V2_LPP_B10 26 72 + #define LCDC_V2_TFT_24BPP_MODE BIT(25) 73 + #define LCDC_V2_TFT_24BPP_UNPACK BIT(26) 74 + 75 + /* LCDC Raster Timing 2 Register */ 76 + #define LCDC_AC_BIAS_TRANSITIONS_PER_INT(x) ((x) << 16) 77 + #define LCDC_AC_BIAS_FREQUENCY(x) ((x) << 8) 78 + #define LCDC_SYNC_CTRL BIT(25) 79 + #define LCDC_SYNC_EDGE BIT(24) 80 + #define LCDC_INVERT_PIXEL_CLOCK BIT(22) 81 + #define LCDC_INVERT_HSYNC BIT(21) 82 + #define LCDC_INVERT_VSYNC BIT(20) 83 + 84 + /* LCDC Block */ 85 + #define LCDC_PID_REG 0x0 86 + #define LCDC_CTRL_REG 0x4 87 + #define LCDC_STAT_REG 0x8 88 + #define LCDC_RASTER_CTRL_REG 0x28 89 + #define LCDC_RASTER_TIMING_0_REG 0x2c 90 + #define LCDC_RASTER_TIMING_1_REG 0x30 91 + #define LCDC_RASTER_TIMING_2_REG 0x34 92 + #define LCDC_DMA_CTRL_REG 0x40 93 + #define LCDC_DMA_FB_BASE_ADDR_0_REG 0x44 94 + #define LCDC_DMA_FB_CEILING_ADDR_0_REG 0x48 95 + #define LCDC_DMA_FB_BASE_ADDR_1_REG 0x4c 96 + #define LCDC_DMA_FB_CEILING_ADDR_1_REG 0x50 97 + 98 + /* Interrupt Registers available only in Version 2 */ 99 + #define LCDC_RAW_STAT_REG 0x58 100 + #define LCDC_MASKED_STAT_REG 0x5c 101 + #define LCDC_INT_ENABLE_SET_REG 0x60 102 + #define LCDC_INT_ENABLE_CLR_REG 0x64 103 + #define LCDC_END_OF_INT_IND_REG 0x68 104 + 105 + /* Clock registers available only on Version 2 */ 106 + #define LCDC_CLK_ENABLE_REG 0x6c 107 + #define LCDC_CLK_RESET_REG 0x70 108 + #define LCDC_CLK_MAIN_RESET BIT(3) 109 + 110 + 111 + /* 112 + * Helpers: 113 + */ 114 + 115 + static inline void tilcdc_write(struct drm_device *dev, u32 reg, u32 data) 116 + { 117 + struct tilcdc_drm_private *priv = dev->dev_private; 118 + iowrite32(data, priv->mmio + reg); 119 + } 120 + 121 + static inline u32 tilcdc_read(struct drm_device *dev, u32 reg) 122 + { 123 + struct tilcdc_drm_private *priv = dev->dev_private; 124 + return ioread32(priv->mmio + reg); 125 + } 126 + 127 + static inline void tilcdc_set(struct drm_device *dev, u32 reg, u32 mask) 128 + { 129 + tilcdc_write(dev, reg, tilcdc_read(dev, reg) | mask); 130 + } 131 + 132 + static inline void tilcdc_clear(struct drm_device *dev, u32 reg, u32 mask) 133 + { 134 + tilcdc_write(dev, reg, tilcdc_read(dev, reg) & ~mask); 135 + } 136 + 137 + /* the register to read/clear irqstatus differs between v1 and v2 of the IP */ 138 + static inline u32 tilcdc_irqstatus_reg(struct drm_device *dev) 139 + { 140 + struct tilcdc_drm_private *priv = dev->dev_private; 141 + return (priv->rev == 2) ? LCDC_MASKED_STAT_REG : LCDC_STAT_REG; 142 + } 143 + 144 + static inline u32 tilcdc_read_irqstatus(struct drm_device *dev) 145 + { 146 + return tilcdc_read(dev, tilcdc_irqstatus_reg(dev)); 147 + } 148 + 149 + static inline void tilcdc_clear_irqstatus(struct drm_device *dev, u32 mask) 150 + { 151 + tilcdc_write(dev, tilcdc_irqstatus_reg(dev), mask); 152 + } 153 + 154 + #endif /* __TILCDC_REGS_H__ */
+376
drivers/gpu/drm/tilcdc/tilcdc_slave.c
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #include <linux/i2c.h> 19 + #include <linux/of_i2c.h> 20 + #include <linux/pinctrl/pinmux.h> 21 + #include <linux/pinctrl/consumer.h> 22 + #include <drm/drm_encoder_slave.h> 23 + 24 + #include "tilcdc_drv.h" 25 + 26 + struct slave_module { 27 + struct tilcdc_module base; 28 + struct i2c_adapter *i2c; 29 + }; 30 + #define to_slave_module(x) container_of(x, struct slave_module, base) 31 + 32 + static const struct tilcdc_panel_info slave_info = { 33 + .bpp = 16, 34 + .ac_bias = 255, 35 + .ac_bias_intrpt = 0, 36 + .dma_burst_sz = 16, 37 + .fdd = 0x80, 38 + .tft_alt_mode = 0, 39 + .sync_edge = 0, 40 + .sync_ctrl = 1, 41 + .raster_order = 0, 42 + }; 43 + 44 + 45 + /* 46 + * Encoder: 47 + */ 48 + 49 + struct slave_encoder { 50 + struct drm_encoder_slave base; 51 + struct slave_module *mod; 52 + }; 53 + #define to_slave_encoder(x) container_of(to_encoder_slave(x), struct slave_encoder, base) 54 + 55 + static inline struct drm_encoder_slave_funcs * 56 + get_slave_funcs(struct drm_encoder *enc) 57 + { 58 + return to_encoder_slave(enc)->slave_funcs; 59 + } 60 + 61 + static void slave_encoder_destroy(struct drm_encoder *encoder) 62 + { 63 + struct slave_encoder *slave_encoder = to_slave_encoder(encoder); 64 + if (get_slave_funcs(encoder)) 65 + get_slave_funcs(encoder)->destroy(encoder); 66 + drm_encoder_cleanup(encoder); 67 + kfree(slave_encoder); 68 + } 69 + 70 + static void slave_encoder_prepare(struct drm_encoder *encoder) 71 + { 72 + drm_i2c_encoder_prepare(encoder); 73 + tilcdc_crtc_set_panel_info(encoder->crtc, &slave_info); 74 + } 75 + 76 + static const struct drm_encoder_funcs slave_encoder_funcs = { 77 + .destroy = slave_encoder_destroy, 78 + }; 79 + 80 + static const struct drm_encoder_helper_funcs slave_encoder_helper_funcs = { 81 + .dpms = drm_i2c_encoder_dpms, 82 + .mode_fixup = drm_i2c_encoder_mode_fixup, 83 + .prepare = slave_encoder_prepare, 84 + .commit = drm_i2c_encoder_commit, 85 + .mode_set = drm_i2c_encoder_mode_set, 86 + .save = drm_i2c_encoder_save, 87 + .restore = drm_i2c_encoder_restore, 88 + }; 89 + 90 + static const struct i2c_board_info info = { 91 + I2C_BOARD_INFO("tda998x", 0x70) 92 + }; 93 + 94 + static struct drm_encoder *slave_encoder_create(struct drm_device *dev, 95 + struct slave_module *mod) 96 + { 97 + struct slave_encoder *slave_encoder; 98 + struct drm_encoder *encoder; 99 + int ret; 100 + 101 + slave_encoder = kzalloc(sizeof(*slave_encoder), GFP_KERNEL); 102 + if (!slave_encoder) { 103 + dev_err(dev->dev, "allocation failed\n"); 104 + return NULL; 105 + } 106 + 107 + slave_encoder->mod = mod; 108 + 109 + encoder = &slave_encoder->base.base; 110 + encoder->possible_crtcs = 1; 111 + 112 + ret = drm_encoder_init(dev, encoder, &slave_encoder_funcs, 113 + DRM_MODE_ENCODER_TMDS); 114 + if (ret) 115 + goto fail; 116 + 117 + drm_encoder_helper_add(encoder, &slave_encoder_helper_funcs); 118 + 119 + ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), mod->i2c, &info); 120 + if (ret) 121 + goto fail; 122 + 123 + return encoder; 124 + 125 + fail: 126 + slave_encoder_destroy(encoder); 127 + return NULL; 128 + } 129 + 130 + /* 131 + * Connector: 132 + */ 133 + 134 + struct slave_connector { 135 + struct drm_connector base; 136 + 137 + struct drm_encoder *encoder; /* our connected encoder */ 138 + struct slave_module *mod; 139 + }; 140 + #define to_slave_connector(x) container_of(x, struct slave_connector, base) 141 + 142 + static void slave_connector_destroy(struct drm_connector *connector) 143 + { 144 + struct slave_connector *slave_connector = to_slave_connector(connector); 145 + drm_connector_cleanup(connector); 146 + kfree(slave_connector); 147 + } 148 + 149 + static enum drm_connector_status slave_connector_detect( 150 + struct drm_connector *connector, 151 + bool force) 152 + { 153 + struct drm_encoder *encoder = to_slave_connector(connector)->encoder; 154 + return get_slave_funcs(encoder)->detect(encoder, connector); 155 + } 156 + 157 + static int slave_connector_get_modes(struct drm_connector *connector) 158 + { 159 + struct drm_encoder *encoder = to_slave_connector(connector)->encoder; 160 + return get_slave_funcs(encoder)->get_modes(encoder, connector); 161 + } 162 + 163 + static int slave_connector_mode_valid(struct drm_connector *connector, 164 + struct drm_display_mode *mode) 165 + { 166 + struct drm_encoder *encoder = to_slave_connector(connector)->encoder; 167 + struct tilcdc_drm_private *priv = connector->dev->dev_private; 168 + int ret; 169 + 170 + ret = tilcdc_crtc_mode_valid(priv->crtc, mode); 171 + if (ret != MODE_OK) 172 + return ret; 173 + 174 + return get_slave_funcs(encoder)->mode_valid(encoder, mode); 175 + } 176 + 177 + static struct drm_encoder *slave_connector_best_encoder( 178 + struct drm_connector *connector) 179 + { 180 + struct slave_connector *slave_connector = to_slave_connector(connector); 181 + return slave_connector->encoder; 182 + } 183 + 184 + static int slave_connector_set_property(struct drm_connector *connector, 185 + struct drm_property *property, uint64_t value) 186 + { 187 + struct drm_encoder *encoder = to_slave_connector(connector)->encoder; 188 + return get_slave_funcs(encoder)->set_property(encoder, 189 + connector, property, value); 190 + } 191 + 192 + static const struct drm_connector_funcs slave_connector_funcs = { 193 + .destroy = slave_connector_destroy, 194 + .dpms = drm_helper_connector_dpms, 195 + .detect = slave_connector_detect, 196 + .fill_modes = drm_helper_probe_single_connector_modes, 197 + .set_property = slave_connector_set_property, 198 + }; 199 + 200 + static const struct drm_connector_helper_funcs slave_connector_helper_funcs = { 201 + .get_modes = slave_connector_get_modes, 202 + .mode_valid = slave_connector_mode_valid, 203 + .best_encoder = slave_connector_best_encoder, 204 + }; 205 + 206 + static struct drm_connector *slave_connector_create(struct drm_device *dev, 207 + struct slave_module *mod, struct drm_encoder *encoder) 208 + { 209 + struct slave_connector *slave_connector; 210 + struct drm_connector *connector; 211 + int ret; 212 + 213 + slave_connector = kzalloc(sizeof(*slave_connector), GFP_KERNEL); 214 + if (!slave_connector) { 215 + dev_err(dev->dev, "allocation failed\n"); 216 + return NULL; 217 + } 218 + 219 + slave_connector->encoder = encoder; 220 + slave_connector->mod = mod; 221 + 222 + connector = &slave_connector->base; 223 + 224 + drm_connector_init(dev, connector, &slave_connector_funcs, 225 + DRM_MODE_CONNECTOR_HDMIA); 226 + drm_connector_helper_add(connector, &slave_connector_helper_funcs); 227 + 228 + connector->polled = DRM_CONNECTOR_POLL_CONNECT | 229 + DRM_CONNECTOR_POLL_DISCONNECT; 230 + 231 + connector->interlace_allowed = 0; 232 + connector->doublescan_allowed = 0; 233 + 234 + get_slave_funcs(encoder)->create_resources(encoder, connector); 235 + 236 + ret = drm_mode_connector_attach_encoder(connector, encoder); 237 + if (ret) 238 + goto fail; 239 + 240 + drm_sysfs_connector_add(connector); 241 + 242 + return connector; 243 + 244 + fail: 245 + slave_connector_destroy(connector); 246 + return NULL; 247 + } 248 + 249 + /* 250 + * Module: 251 + */ 252 + 253 + static int slave_modeset_init(struct tilcdc_module *mod, struct drm_device *dev) 254 + { 255 + struct slave_module *slave_mod = to_slave_module(mod); 256 + struct tilcdc_drm_private *priv = dev->dev_private; 257 + struct drm_encoder *encoder; 258 + struct drm_connector *connector; 259 + 260 + encoder = slave_encoder_create(dev, slave_mod); 261 + if (!encoder) 262 + return -ENOMEM; 263 + 264 + connector = slave_connector_create(dev, slave_mod, encoder); 265 + if (!connector) 266 + return -ENOMEM; 267 + 268 + priv->encoders[priv->num_encoders++] = encoder; 269 + priv->connectors[priv->num_connectors++] = connector; 270 + 271 + return 0; 272 + } 273 + 274 + static void slave_destroy(struct tilcdc_module *mod) 275 + { 276 + struct slave_module *slave_mod = to_slave_module(mod); 277 + 278 + tilcdc_module_cleanup(mod); 279 + kfree(slave_mod); 280 + } 281 + 282 + static const struct tilcdc_module_ops slave_module_ops = { 283 + .modeset_init = slave_modeset_init, 284 + .destroy = slave_destroy, 285 + }; 286 + 287 + /* 288 + * Device: 289 + */ 290 + 291 + static struct of_device_id slave_of_match[]; 292 + 293 + static int slave_probe(struct platform_device *pdev) 294 + { 295 + struct device_node *node = pdev->dev.of_node; 296 + struct device_node *i2c_node; 297 + struct slave_module *slave_mod; 298 + struct tilcdc_module *mod; 299 + struct pinctrl *pinctrl; 300 + uint32_t i2c_phandle; 301 + int ret = -EINVAL; 302 + 303 + /* bail out early if no DT data: */ 304 + if (!node) { 305 + dev_err(&pdev->dev, "device-tree data is missing\n"); 306 + return -ENXIO; 307 + } 308 + 309 + slave_mod = kzalloc(sizeof(*slave_mod), GFP_KERNEL); 310 + if (!slave_mod) 311 + return -ENOMEM; 312 + 313 + mod = &slave_mod->base; 314 + 315 + tilcdc_module_init(mod, "slave", &slave_module_ops); 316 + 317 + pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 318 + if (IS_ERR(pinctrl)) 319 + dev_warn(&pdev->dev, "pins are not configured\n"); 320 + 321 + if (of_property_read_u32(node, "i2c", &i2c_phandle)) { 322 + dev_err(&pdev->dev, "could not get i2c bus phandle\n"); 323 + goto fail; 324 + } 325 + 326 + i2c_node = of_find_node_by_phandle(i2c_phandle); 327 + if (!i2c_node) { 328 + dev_err(&pdev->dev, "could not get i2c bus node\n"); 329 + goto fail; 330 + } 331 + 332 + slave_mod->i2c = of_find_i2c_adapter_by_node(i2c_node); 333 + if (!slave_mod->i2c) { 334 + dev_err(&pdev->dev, "could not get i2c\n"); 335 + goto fail; 336 + } 337 + 338 + of_node_put(i2c_node); 339 + 340 + return 0; 341 + 342 + fail: 343 + slave_destroy(mod); 344 + return ret; 345 + } 346 + 347 + static int slave_remove(struct platform_device *pdev) 348 + { 349 + return 0; 350 + } 351 + 352 + static struct of_device_id slave_of_match[] = { 353 + { .compatible = "ti,tilcdc,slave", }, 354 + { }, 355 + }; 356 + MODULE_DEVICE_TABLE(of, slave_of_match); 357 + 358 + struct platform_driver slave_driver = { 359 + .probe = slave_probe, 360 + .remove = slave_remove, 361 + .driver = { 362 + .owner = THIS_MODULE, 363 + .name = "slave", 364 + .of_match_table = slave_of_match, 365 + }, 366 + }; 367 + 368 + int __init tilcdc_slave_init(void) 369 + { 370 + return platform_driver_register(&slave_driver); 371 + } 372 + 373 + void __exit tilcdc_slave_fini(void) 374 + { 375 + platform_driver_unregister(&slave_driver); 376 + }
+26
drivers/gpu/drm/tilcdc/tilcdc_slave.h
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #ifndef __TILCDC_SLAVE_H__ 19 + #define __TILCDC_SLAVE_H__ 20 + 21 + /* sub-module for i2c slave encoder output */ 22 + 23 + int tilcdc_slave_init(void); 24 + void tilcdc_slave_fini(void); 25 + 26 + #endif /* __TILCDC_SLAVE_H__ */
+419
drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #include <linux/i2c.h> 19 + #include <linux/of_i2c.h> 20 + #include <linux/gpio.h> 21 + #include <linux/of_gpio.h> 22 + #include <linux/pinctrl/pinmux.h> 23 + #include <linux/pinctrl/consumer.h> 24 + 25 + #include "tilcdc_drv.h" 26 + 27 + struct tfp410_module { 28 + struct tilcdc_module base; 29 + struct i2c_adapter *i2c; 30 + int gpio; 31 + }; 32 + #define to_tfp410_module(x) container_of(x, struct tfp410_module, base) 33 + 34 + 35 + static const struct tilcdc_panel_info dvi_info = { 36 + .ac_bias = 255, 37 + .ac_bias_intrpt = 0, 38 + .dma_burst_sz = 16, 39 + .bpp = 16, 40 + .fdd = 0x80, 41 + .tft_alt_mode = 0, 42 + .sync_edge = 0, 43 + .sync_ctrl = 1, 44 + .raster_order = 0, 45 + }; 46 + 47 + /* 48 + * Encoder: 49 + */ 50 + 51 + struct tfp410_encoder { 52 + struct drm_encoder base; 53 + struct tfp410_module *mod; 54 + int dpms; 55 + }; 56 + #define to_tfp410_encoder(x) container_of(x, struct tfp410_encoder, base) 57 + 58 + 59 + static void tfp410_encoder_destroy(struct drm_encoder *encoder) 60 + { 61 + struct tfp410_encoder *tfp410_encoder = to_tfp410_encoder(encoder); 62 + drm_encoder_cleanup(encoder); 63 + kfree(tfp410_encoder); 64 + } 65 + 66 + static void tfp410_encoder_dpms(struct drm_encoder *encoder, int mode) 67 + { 68 + struct tfp410_encoder *tfp410_encoder = to_tfp410_encoder(encoder); 69 + 70 + if (tfp410_encoder->dpms == mode) 71 + return; 72 + 73 + if (mode == DRM_MODE_DPMS_ON) { 74 + DBG("Power on"); 75 + gpio_direction_output(tfp410_encoder->mod->gpio, 1); 76 + } else { 77 + DBG("Power off"); 78 + gpio_direction_output(tfp410_encoder->mod->gpio, 0); 79 + } 80 + 81 + tfp410_encoder->dpms = mode; 82 + } 83 + 84 + static bool tfp410_encoder_mode_fixup(struct drm_encoder *encoder, 85 + const struct drm_display_mode *mode, 86 + struct drm_display_mode *adjusted_mode) 87 + { 88 + /* nothing needed */ 89 + return true; 90 + } 91 + 92 + static void tfp410_encoder_prepare(struct drm_encoder *encoder) 93 + { 94 + tfp410_encoder_dpms(encoder, DRM_MODE_DPMS_OFF); 95 + tilcdc_crtc_set_panel_info(encoder->crtc, &dvi_info); 96 + } 97 + 98 + static void tfp410_encoder_commit(struct drm_encoder *encoder) 99 + { 100 + tfp410_encoder_dpms(encoder, DRM_MODE_DPMS_ON); 101 + } 102 + 103 + static void tfp410_encoder_mode_set(struct drm_encoder *encoder, 104 + struct drm_display_mode *mode, 105 + struct drm_display_mode *adjusted_mode) 106 + { 107 + /* nothing needed */ 108 + } 109 + 110 + static const struct drm_encoder_funcs tfp410_encoder_funcs = { 111 + .destroy = tfp410_encoder_destroy, 112 + }; 113 + 114 + static const struct drm_encoder_helper_funcs tfp410_encoder_helper_funcs = { 115 + .dpms = tfp410_encoder_dpms, 116 + .mode_fixup = tfp410_encoder_mode_fixup, 117 + .prepare = tfp410_encoder_prepare, 118 + .commit = tfp410_encoder_commit, 119 + .mode_set = tfp410_encoder_mode_set, 120 + }; 121 + 122 + static struct drm_encoder *tfp410_encoder_create(struct drm_device *dev, 123 + struct tfp410_module *mod) 124 + { 125 + struct tfp410_encoder *tfp410_encoder; 126 + struct drm_encoder *encoder; 127 + int ret; 128 + 129 + tfp410_encoder = kzalloc(sizeof(*tfp410_encoder), GFP_KERNEL); 130 + if (!tfp410_encoder) { 131 + dev_err(dev->dev, "allocation failed\n"); 132 + return NULL; 133 + } 134 + 135 + tfp410_encoder->dpms = DRM_MODE_DPMS_OFF; 136 + tfp410_encoder->mod = mod; 137 + 138 + encoder = &tfp410_encoder->base; 139 + encoder->possible_crtcs = 1; 140 + 141 + ret = drm_encoder_init(dev, encoder, &tfp410_encoder_funcs, 142 + DRM_MODE_ENCODER_TMDS); 143 + if (ret < 0) 144 + goto fail; 145 + 146 + drm_encoder_helper_add(encoder, &tfp410_encoder_helper_funcs); 147 + 148 + return encoder; 149 + 150 + fail: 151 + tfp410_encoder_destroy(encoder); 152 + return NULL; 153 + } 154 + 155 + /* 156 + * Connector: 157 + */ 158 + 159 + struct tfp410_connector { 160 + struct drm_connector base; 161 + 162 + struct drm_encoder *encoder; /* our connected encoder */ 163 + struct tfp410_module *mod; 164 + }; 165 + #define to_tfp410_connector(x) container_of(x, struct tfp410_connector, base) 166 + 167 + 168 + static void tfp410_connector_destroy(struct drm_connector *connector) 169 + { 170 + struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector); 171 + drm_connector_cleanup(connector); 172 + kfree(tfp410_connector); 173 + } 174 + 175 + static enum drm_connector_status tfp410_connector_detect( 176 + struct drm_connector *connector, 177 + bool force) 178 + { 179 + struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector); 180 + 181 + if (drm_probe_ddc(tfp410_connector->mod->i2c)) 182 + return connector_status_connected; 183 + 184 + return connector_status_unknown; 185 + } 186 + 187 + static int tfp410_connector_get_modes(struct drm_connector *connector) 188 + { 189 + struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector); 190 + struct edid *edid; 191 + int ret = 0; 192 + 193 + edid = drm_get_edid(connector, tfp410_connector->mod->i2c); 194 + 195 + drm_mode_connector_update_edid_property(connector, edid); 196 + 197 + if (edid) { 198 + ret = drm_add_edid_modes(connector, edid); 199 + kfree(edid); 200 + } 201 + 202 + return ret; 203 + } 204 + 205 + static int tfp410_connector_mode_valid(struct drm_connector *connector, 206 + struct drm_display_mode *mode) 207 + { 208 + struct tilcdc_drm_private *priv = connector->dev->dev_private; 209 + /* our only constraints are what the crtc can generate: */ 210 + return tilcdc_crtc_mode_valid(priv->crtc, mode); 211 + } 212 + 213 + static struct drm_encoder *tfp410_connector_best_encoder( 214 + struct drm_connector *connector) 215 + { 216 + struct tfp410_connector *tfp410_connector = to_tfp410_connector(connector); 217 + return tfp410_connector->encoder; 218 + } 219 + 220 + static const struct drm_connector_funcs tfp410_connector_funcs = { 221 + .destroy = tfp410_connector_destroy, 222 + .dpms = drm_helper_connector_dpms, 223 + .detect = tfp410_connector_detect, 224 + .fill_modes = drm_helper_probe_single_connector_modes, 225 + }; 226 + 227 + static const struct drm_connector_helper_funcs tfp410_connector_helper_funcs = { 228 + .get_modes = tfp410_connector_get_modes, 229 + .mode_valid = tfp410_connector_mode_valid, 230 + .best_encoder = tfp410_connector_best_encoder, 231 + }; 232 + 233 + static struct drm_connector *tfp410_connector_create(struct drm_device *dev, 234 + struct tfp410_module *mod, struct drm_encoder *encoder) 235 + { 236 + struct tfp410_connector *tfp410_connector; 237 + struct drm_connector *connector; 238 + int ret; 239 + 240 + tfp410_connector = kzalloc(sizeof(*tfp410_connector), GFP_KERNEL); 241 + if (!tfp410_connector) { 242 + dev_err(dev->dev, "allocation failed\n"); 243 + return NULL; 244 + } 245 + 246 + tfp410_connector->encoder = encoder; 247 + tfp410_connector->mod = mod; 248 + 249 + connector = &tfp410_connector->base; 250 + 251 + drm_connector_init(dev, connector, &tfp410_connector_funcs, 252 + DRM_MODE_CONNECTOR_DVID); 253 + drm_connector_helper_add(connector, &tfp410_connector_helper_funcs); 254 + 255 + connector->polled = DRM_CONNECTOR_POLL_CONNECT | 256 + DRM_CONNECTOR_POLL_DISCONNECT; 257 + 258 + connector->interlace_allowed = 0; 259 + connector->doublescan_allowed = 0; 260 + 261 + ret = drm_mode_connector_attach_encoder(connector, encoder); 262 + if (ret) 263 + goto fail; 264 + 265 + drm_sysfs_connector_add(connector); 266 + 267 + return connector; 268 + 269 + fail: 270 + tfp410_connector_destroy(connector); 271 + return NULL; 272 + } 273 + 274 + /* 275 + * Module: 276 + */ 277 + 278 + static int tfp410_modeset_init(struct tilcdc_module *mod, struct drm_device *dev) 279 + { 280 + struct tfp410_module *tfp410_mod = to_tfp410_module(mod); 281 + struct tilcdc_drm_private *priv = dev->dev_private; 282 + struct drm_encoder *encoder; 283 + struct drm_connector *connector; 284 + 285 + encoder = tfp410_encoder_create(dev, tfp410_mod); 286 + if (!encoder) 287 + return -ENOMEM; 288 + 289 + connector = tfp410_connector_create(dev, tfp410_mod, encoder); 290 + if (!connector) 291 + return -ENOMEM; 292 + 293 + priv->encoders[priv->num_encoders++] = encoder; 294 + priv->connectors[priv->num_connectors++] = connector; 295 + 296 + return 0; 297 + } 298 + 299 + static void tfp410_destroy(struct tilcdc_module *mod) 300 + { 301 + struct tfp410_module *tfp410_mod = to_tfp410_module(mod); 302 + 303 + if (tfp410_mod->i2c) 304 + i2c_put_adapter(tfp410_mod->i2c); 305 + 306 + if (!IS_ERR_VALUE(tfp410_mod->gpio)) 307 + gpio_free(tfp410_mod->gpio); 308 + 309 + tilcdc_module_cleanup(mod); 310 + kfree(tfp410_mod); 311 + } 312 + 313 + static const struct tilcdc_module_ops tfp410_module_ops = { 314 + .modeset_init = tfp410_modeset_init, 315 + .destroy = tfp410_destroy, 316 + }; 317 + 318 + /* 319 + * Device: 320 + */ 321 + 322 + static struct of_device_id tfp410_of_match[]; 323 + 324 + static int tfp410_probe(struct platform_device *pdev) 325 + { 326 + struct device_node *node = pdev->dev.of_node; 327 + struct device_node *i2c_node; 328 + struct tfp410_module *tfp410_mod; 329 + struct tilcdc_module *mod; 330 + struct pinctrl *pinctrl; 331 + uint32_t i2c_phandle; 332 + int ret = -EINVAL; 333 + 334 + /* bail out early if no DT data: */ 335 + if (!node) { 336 + dev_err(&pdev->dev, "device-tree data is missing\n"); 337 + return -ENXIO; 338 + } 339 + 340 + tfp410_mod = kzalloc(sizeof(*tfp410_mod), GFP_KERNEL); 341 + if (!tfp410_mod) 342 + return -ENOMEM; 343 + 344 + mod = &tfp410_mod->base; 345 + 346 + tilcdc_module_init(mod, "tfp410", &tfp410_module_ops); 347 + 348 + pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 349 + if (IS_ERR(pinctrl)) 350 + dev_warn(&pdev->dev, "pins are not configured\n"); 351 + 352 + if (of_property_read_u32(node, "i2c", &i2c_phandle)) { 353 + dev_err(&pdev->dev, "could not get i2c bus phandle\n"); 354 + goto fail; 355 + } 356 + 357 + i2c_node = of_find_node_by_phandle(i2c_phandle); 358 + if (!i2c_node) { 359 + dev_err(&pdev->dev, "could not get i2c bus node\n"); 360 + goto fail; 361 + } 362 + 363 + tfp410_mod->i2c = of_find_i2c_adapter_by_node(i2c_node); 364 + if (!tfp410_mod->i2c) { 365 + dev_err(&pdev->dev, "could not get i2c\n"); 366 + goto fail; 367 + } 368 + 369 + of_node_put(i2c_node); 370 + 371 + tfp410_mod->gpio = of_get_named_gpio_flags(node, "powerdn-gpio", 372 + 0, NULL); 373 + if (IS_ERR_VALUE(tfp410_mod->gpio)) { 374 + dev_warn(&pdev->dev, "No power down GPIO\n"); 375 + } else { 376 + ret = gpio_request(tfp410_mod->gpio, "DVI_PDn"); 377 + if (ret) { 378 + dev_err(&pdev->dev, "could not get DVI_PDn gpio\n"); 379 + goto fail; 380 + } 381 + } 382 + 383 + return 0; 384 + 385 + fail: 386 + tfp410_destroy(mod); 387 + return ret; 388 + } 389 + 390 + static int tfp410_remove(struct platform_device *pdev) 391 + { 392 + return 0; 393 + } 394 + 395 + static struct of_device_id tfp410_of_match[] = { 396 + { .compatible = "ti,tilcdc,tfp410", }, 397 + { }, 398 + }; 399 + MODULE_DEVICE_TABLE(of, tfp410_of_match); 400 + 401 + struct platform_driver tfp410_driver = { 402 + .probe = tfp410_probe, 403 + .remove = tfp410_remove, 404 + .driver = { 405 + .owner = THIS_MODULE, 406 + .name = "tfp410", 407 + .of_match_table = tfp410_of_match, 408 + }, 409 + }; 410 + 411 + int __init tilcdc_tfp410_init(void) 412 + { 413 + return platform_driver_register(&tfp410_driver); 414 + } 415 + 416 + void __exit tilcdc_tfp410_fini(void) 417 + { 418 + platform_driver_unregister(&tfp410_driver); 419 + }
+26
drivers/gpu/drm/tilcdc/tilcdc_tfp410.h
··· 1 + /* 2 + * Copyright (C) 2012 Texas Instruments 3 + * Author: Rob Clark <robdclark@gmail.com> 4 + * 5 + * This program is free software; you can redistribute it and/or modify it 6 + * under the terms of the GNU General Public License version 2 as published by 7 + * the Free Software Foundation. 8 + * 9 + * This program is distributed in the hope that it will be useful, but WITHOUT 10 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 + * more details. 13 + * 14 + * You should have received a copy of the GNU General Public License along with 15 + * this program. If not, see <http://www.gnu.org/licenses/>. 16 + */ 17 + 18 + #ifndef __TILCDC_TFP410_H__ 19 + #define __TILCDC_TFP410_H__ 20 + 21 + /* sub-module for tfp410 dvi adaptor */ 22 + 23 + int tilcdc_tfp410_init(void); 24 + void tilcdc_tfp410_fini(void); 25 + 26 + #endif /* __TILCDC_TFP410_H__ */
+20
include/drm/drm_encoder_slave.h
··· 159 159 160 160 void drm_i2c_encoder_destroy(struct drm_encoder *encoder); 161 161 162 + 163 + /* 164 + * Wrapper fxns which can be plugged in to drm_encoder_helper_funcs: 165 + */ 166 + 167 + void drm_i2c_encoder_dpms(struct drm_encoder *encoder, int mode); 168 + bool drm_i2c_encoder_mode_fixup(struct drm_encoder *encoder, 169 + const struct drm_display_mode *mode, 170 + struct drm_display_mode *adjusted_mode); 171 + void drm_i2c_encoder_prepare(struct drm_encoder *encoder); 172 + void drm_i2c_encoder_commit(struct drm_encoder *encoder); 173 + void drm_i2c_encoder_mode_set(struct drm_encoder *encoder, 174 + struct drm_display_mode *mode, 175 + struct drm_display_mode *adjusted_mode); 176 + enum drm_connector_status drm_i2c_encoder_detect(struct drm_encoder *encoder, 177 + struct drm_connector *connector); 178 + void drm_i2c_encoder_save(struct drm_encoder *encoder); 179 + void drm_i2c_encoder_restore(struct drm_encoder *encoder); 180 + 181 + 162 182 #endif
+5
include/drm/drm_fb_cma_helper.h
··· 23 23 struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb, 24 24 unsigned int plane); 25 25 26 + #ifdef CONFIG_DEBUG_FS 27 + void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m); 28 + int drm_fb_cma_debugfs_show(struct seq_file *m, void *arg); 29 + #endif 30 + 26 31 #endif 27 32
+4
include/drm/drm_gem_cma_helper.h
··· 41 41 42 42 extern const struct vm_operations_struct drm_gem_cma_vm_ops; 43 43 44 + #ifdef CONFIG_DEBUG_FS 45 + void drm_gem_cma_describe(struct drm_gem_cma_object *obj, struct seq_file *m); 46 + #endif 47 + 44 48 #endif /* __DRM_GEM_CMA_HELPER_H__ */