aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/exynos
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 16:08:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-03-22 16:08:22 -0400
commitbe53bfdb8088e9d1924199cc1a96e113756b1075 (patch)
tree8c65eb9d82ca4c0f11c17cfdc44d5263820b415b /drivers/gpu/drm/exynos
parentb2094ef840697bc8ca5d17a83b7e30fad5f1e9fa (diff)
parent5466c7b1683a23dbbcfb7ee4a71c4f23886001c7 (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm main changes from Dave Airlie: "This is the main drm pull request, I'm probably going to send two more smaller ones, will explain below. This contains a patch that is also in the fbdev tree, but it should be the same patch, it added an API for hot unplugging framebuffer devices, and I need that API for a new driver. It also contains some changes to the i2c tree which Jean has acked, and one change to moorestown platform stuff in x86. Highlights: - new drivers: UDL driver for USB displaylink devices, kms only, should support correct hotplug operations. - core: i2c speedups + better hotplug support, EDID overriding via firmware interface - allows user to load a firmware for a broken monitor/kvm from userspace, it even has documentation for it. - exynos: new HDMI audio + hdmi 1.4 + virtual output driver - gma500: code cleanup - radeon: cleanups, CS optimisations, streamout support and pageflip fix - nouveau: NVD9 displayport support + more reclocking work - i915: re-enabling GMBUS, finish gpu patch (might help hibernation who knows), missed irq fixes, stencil tiling fixes, interlaced support, aliasesd PPGTT support for SNB/IVB, swizzling for SNB/IVB, semaphore fixes As well as the usual bunch of cleanups and fixes all over the place. I've got two things I'd like to merge a bit later: a) AMD support for all their new radeonhd 7000 series GPU and APUs. AMD dropped this a bit late due to insane internal review processes, (please AMD just follow Intel and let open source guys ship stuff early) however I don't want to penalise people who own this hardware (since its been on sale for 3-4 months and GPU hw doesn't exactly have a lifetime in years) and consign them to using closed drivers for longer than necessary. The changes are well contained and just plug into the driver new gpu functionality so they should be fairly regression proof. I just want to give them a bit of a run on the hw AMD kindly sent me. b) drm prime/dma-buf interface code. This is just infrastructure code to expose the dma-buf stuff to drm drivers and to userspace. I'm not planning on pushing any driver support in this cycle (except maybe exynos), but I'd like to get the infrastructure code in so for the next cycle I can start getting the driver support into the individual drivers. We have started driver support for i915, nouveau and udl along with I think exynos and omap in staging. However this code relies on the dma-buf tree being pulled into your tree first since it needs the latest interfaces from that tree. I'll push to get that tree sent asap. (oh and any warnings you see in i915 are gcc's fault from what anyone can see)." Fix up trivial conflicts in arch/x86/platform/mrst/mrst.c due to the new msic_thermal_platform_data() thermal function being added next to the tc35876x_platform_data() i2c device function.. * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (326 commits) drm/i915: use DDC_ADDR instead of hard-coding it drm/radeon: use DDC_ADDR instead of hard-coding it drm: remove unneeded redefinition of DDC_ADDR drm/exynos: added virtual display driver. drm: allow loading an EDID as firmware to override broken monitor drm/exynos: enable hdmi audio feature drm/exynos: add default pixel format for plane drm/exynos: cleanup exynos_hdmi.h drm/exynos: add is_local member in exynos_drm_subdrv struct drm/exynos: add subdrv open/close functions drm/exynos: remove module of exynos drm subdrv drm/exynos: release pending pageflip events when closed drm/exynos: added new funtion to get/put dma address. drm/exynos: update gem and buffer framework. drm/exynos: added mode_fixup feature and code clean. drm/exynos: add HDMI version 1.4 support drm/exynos: remove exynos_mixer.h gma500: Fix mmap frambuffer drm/radeon: Drop radeon_gem_object_(un)pin. drm/radeon: Restrict offset for legacy display engine. ...
Diffstat (limited to 'drivers/gpu/drm/exynos')
-rw-r--r--drivers/gpu/drm/exynos/Kconfig14
-rw-r--r--drivers/gpu/drm/exynos/Makefile11
-rw-r--r--drivers/gpu/drm/exynos/exynos_ddc.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_buf.c191
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_buf.h22
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_connector.c35
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_core.c140
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c12
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c94
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h38
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c24
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fb.c6
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c90
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c20
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c364
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.h29
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.c115
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_hdmi.h5
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.c676
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_vidi.h36
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.c1437
-rw-r--r--drivers/gpu/drm/exynos/exynos_hdmi.h50
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c57
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.h92
-rw-r--r--drivers/gpu/drm/exynos/regs-hdmi.h488
26 files changed, 3339 insertions, 716 deletions
diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index b9e5266c341b..3343ac437fe5 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -1,7 +1,6 @@
1config DRM_EXYNOS 1config DRM_EXYNOS
2 tristate "DRM Support for Samsung SoC EXYNOS Series" 2 tristate "DRM Support for Samsung SoC EXYNOS Series"
3 depends on DRM && PLAT_SAMSUNG 3 depends on DRM && PLAT_SAMSUNG
4 default n
5 select DRM_KMS_HELPER 4 select DRM_KMS_HELPER
6 select FB_CFB_FILLRECT 5 select FB_CFB_FILLRECT
7 select FB_CFB_COPYAREA 6 select FB_CFB_COPYAREA
@@ -12,16 +11,19 @@ config DRM_EXYNOS
12 If M is selected the module will be called exynosdrm. 11 If M is selected the module will be called exynosdrm.
13 12
14config DRM_EXYNOS_FIMD 13config DRM_EXYNOS_FIMD
15 tristate "Exynos DRM FIMD" 14 bool "Exynos DRM FIMD"
16 depends on DRM_EXYNOS && !FB_S3C 15 depends on DRM_EXYNOS && !FB_S3C
17 default n
18 help 16 help
19 Choose this option if you want to use Exynos FIMD for DRM. 17 Choose this option if you want to use Exynos FIMD for DRM.
20 If M is selected, the module will be called exynos_drm_fimd
21 18
22config DRM_EXYNOS_HDMI 19config DRM_EXYNOS_HDMI
23 tristate "Exynos DRM HDMI" 20 bool "Exynos DRM HDMI"
24 depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV 21 depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV
25 help 22 help
26 Choose this option if you want to use Exynos HDMI for DRM. 23 Choose this option if you want to use Exynos HDMI for DRM.
27 If M is selected, the module will be called exynos_drm_hdmi 24
25config DRM_EXYNOS_VIDI
26 bool "Exynos DRM Virtual Display"
27 depends on DRM_EXYNOS
28 help
29 Choose this option if you want to use Exynos VIDI for DRM.
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 395e69c9a96e..9e0bff8badf9 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -8,7 +8,10 @@ exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o exynos_drm_connector.o \
8 exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \ 8 exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
9 exynos_drm_plane.o 9 exynos_drm_plane.o
10 10
11obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o 11exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
12obj-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o 12exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o \
13obj-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o exynos_ddc.o \ 13 exynos_ddc.o exynos_hdmiphy.o \
14 exynos_hdmiphy.o exynos_drm_hdmi.o 14 exynos_drm_hdmi.o
15exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o
16
17obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o
diff --git a/drivers/gpu/drm/exynos/exynos_ddc.c b/drivers/gpu/drm/exynos/exynos_ddc.c
index 84b614fe26fd..7e1051d07f1f 100644
--- a/drivers/gpu/drm/exynos/exynos_ddc.c
+++ b/drivers/gpu/drm/exynos/exynos_ddc.c
@@ -55,4 +55,3 @@ struct i2c_driver ddc_driver = {
55 .remove = __devexit_p(s5p_ddc_remove), 55 .remove = __devexit_p(s5p_ddc_remove),
56 .command = NULL, 56 .command = NULL,
57}; 57};
58EXPORT_SYMBOL(ddc_driver);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c
index 3cf785c58186..4a3a5f72ed4a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c
@@ -25,45 +25,161 @@
25 25
26#include "drmP.h" 26#include "drmP.h"
27#include "drm.h" 27#include "drm.h"
28#include "exynos_drm.h"
28 29
29#include "exynos_drm_drv.h" 30#include "exynos_drm_drv.h"
30#include "exynos_drm_gem.h" 31#include "exynos_drm_gem.h"
31#include "exynos_drm_buf.h" 32#include "exynos_drm_buf.h"
32 33
33static int lowlevel_buffer_allocate(struct drm_device *dev, 34static int lowlevel_buffer_allocate(struct drm_device *dev,
34 struct exynos_drm_gem_buf *buffer) 35 unsigned int flags, struct exynos_drm_gem_buf *buf)
35{ 36{
37 dma_addr_t start_addr, end_addr;
38 unsigned int npages, page_size, i = 0;
39 struct scatterlist *sgl;
40 int ret = 0;
41
36 DRM_DEBUG_KMS("%s\n", __FILE__); 42 DRM_DEBUG_KMS("%s\n", __FILE__);
37 43
38 buffer->kvaddr = dma_alloc_writecombine(dev->dev, buffer->size, 44 if (flags & EXYNOS_BO_NONCONTIG) {
39 &buffer->dma_addr, GFP_KERNEL); 45 DRM_DEBUG_KMS("not support allocation type.\n");
40 if (!buffer->kvaddr) { 46 return -EINVAL;
41 DRM_ERROR("failed to allocate buffer.\n"); 47 }
48
49 if (buf->dma_addr) {
50 DRM_DEBUG_KMS("already allocated.\n");
51 return 0;
52 }
53
54 if (buf->size >= SZ_1M) {
55 npages = (buf->size >> SECTION_SHIFT) + 1;
56 page_size = SECTION_SIZE;
57 } else if (buf->size >= SZ_64K) {
58 npages = (buf->size >> 16) + 1;
59 page_size = SZ_64K;
60 } else {
61 npages = (buf->size >> PAGE_SHIFT) + 1;
62 page_size = PAGE_SIZE;
63 }
64
65 buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
66 if (!buf->sgt) {
67 DRM_ERROR("failed to allocate sg table.\n");
42 return -ENOMEM; 68 return -ENOMEM;
43 } 69 }
44 70
45 DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", 71 ret = sg_alloc_table(buf->sgt, npages, GFP_KERNEL);
46 (unsigned long)buffer->kvaddr, 72 if (ret < 0) {
47 (unsigned long)buffer->dma_addr, 73 DRM_ERROR("failed to initialize sg table.\n");
48 buffer->size); 74 kfree(buf->sgt);
75 buf->sgt = NULL;
76 return -ENOMEM;
77 }
49 78
50 return 0; 79 buf->kvaddr = dma_alloc_writecombine(dev->dev, buf->size,
80 &buf->dma_addr, GFP_KERNEL);
81 if (!buf->kvaddr) {
82 DRM_ERROR("failed to allocate buffer.\n");
83 ret = -ENOMEM;
84 goto err1;
85 }
86
87 start_addr = buf->dma_addr;
88 end_addr = buf->dma_addr + buf->size;
89
90 buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
91 if (!buf->pages) {
92 DRM_ERROR("failed to allocate pages.\n");
93 ret = -ENOMEM;
94 goto err2;
95 }
96
97 start_addr = buf->dma_addr;
98 end_addr = buf->dma_addr + buf->size;
99
100 buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL);
101 if (!buf->pages) {
102 DRM_ERROR("failed to allocate pages.\n");
103 ret = -ENOMEM;
104 goto err2;
105 }
106
107 sgl = buf->sgt->sgl;
108
109 while (i < npages) {
110 buf->pages[i] = phys_to_page(start_addr);
111 sg_set_page(sgl, buf->pages[i], page_size, 0);
112 sg_dma_address(sgl) = start_addr;
113 start_addr += page_size;
114 if (end_addr - start_addr < page_size)
115 break;
116 sgl = sg_next(sgl);
117 i++;
118 }
119
120 buf->pages[i] = phys_to_page(start_addr);
121
122 sgl = sg_next(sgl);
123 sg_set_page(sgl, buf->pages[i+1], end_addr - start_addr, 0);
124
125 DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
126 (unsigned long)buf->kvaddr,
127 (unsigned long)buf->dma_addr,
128 buf->size);
129
130 return ret;
131err2:
132 dma_free_writecombine(dev->dev, buf->size, buf->kvaddr,
133 (dma_addr_t)buf->dma_addr);
134 buf->dma_addr = (dma_addr_t)NULL;
135err1:
136 sg_free_table(buf->sgt);
137 kfree(buf->sgt);
138 buf->sgt = NULL;
139
140 return ret;
51} 141}
52 142
53static void lowlevel_buffer_deallocate(struct drm_device *dev, 143static void lowlevel_buffer_deallocate(struct drm_device *dev,
54 struct exynos_drm_gem_buf *buffer) 144 unsigned int flags, struct exynos_drm_gem_buf *buf)
55{ 145{
56 DRM_DEBUG_KMS("%s.\n", __FILE__); 146 DRM_DEBUG_KMS("%s.\n", __FILE__);
57 147
58 if (buffer->dma_addr && buffer->size) 148 /*
59 dma_free_writecombine(dev->dev, buffer->size, buffer->kvaddr, 149 * release only physically continuous memory and
60 (dma_addr_t)buffer->dma_addr); 150 * non-continuous memory would be released by exynos
61 else 151 * gem framework.
62 DRM_DEBUG_KMS("buffer data are invalid.\n"); 152 */
153 if (flags & EXYNOS_BO_NONCONTIG) {
154 DRM_DEBUG_KMS("not support allocation type.\n");
155 return;
156 }
157
158 if (!buf->dma_addr) {
159 DRM_DEBUG_KMS("dma_addr is invalid.\n");
160 return;
161 }
162
163 DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n",
164 (unsigned long)buf->kvaddr,
165 (unsigned long)buf->dma_addr,
166 buf->size);
167
168 sg_free_table(buf->sgt);
169
170 kfree(buf->sgt);
171 buf->sgt = NULL;
172
173 kfree(buf->pages);
174 buf->pages = NULL;
175
176 dma_free_writecombine(dev->dev, buf->size, buf->kvaddr,
177 (dma_addr_t)buf->dma_addr);
178 buf->dma_addr = (dma_addr_t)NULL;
63} 179}
64 180
65struct exynos_drm_gem_buf *exynos_drm_buf_create(struct drm_device *dev, 181struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev,
66 unsigned int size) 182 unsigned int size)
67{ 183{
68 struct exynos_drm_gem_buf *buffer; 184 struct exynos_drm_gem_buf *buffer;
69 185
@@ -77,21 +193,11 @@ struct exynos_drm_gem_buf *exynos_drm_buf_create(struct drm_device *dev,
77 } 193 }
78 194
79 buffer->size = size; 195 buffer->size = size;
80
81 /*
82 * allocate memory region with size and set the memory information
83 * to vaddr and dma_addr of a buffer object.
84 */
85 if (lowlevel_buffer_allocate(dev, buffer) < 0) {
86 kfree(buffer);
87 return NULL;
88 }
89
90 return buffer; 196 return buffer;
91} 197}
92 198
93void exynos_drm_buf_destroy(struct drm_device *dev, 199void exynos_drm_fini_buf(struct drm_device *dev,
94 struct exynos_drm_gem_buf *buffer) 200 struct exynos_drm_gem_buf *buffer)
95{ 201{
96 DRM_DEBUG_KMS("%s.\n", __FILE__); 202 DRM_DEBUG_KMS("%s.\n", __FILE__);
97 203
@@ -100,12 +206,27 @@ void exynos_drm_buf_destroy(struct drm_device *dev,
100 return; 206 return;
101 } 207 }
102 208
103 lowlevel_buffer_deallocate(dev, buffer);
104
105 kfree(buffer); 209 kfree(buffer);
106 buffer = NULL; 210 buffer = NULL;
107} 211}
108 212
109MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); 213int exynos_drm_alloc_buf(struct drm_device *dev,
110MODULE_DESCRIPTION("Samsung SoC DRM Buffer Management Module"); 214 struct exynos_drm_gem_buf *buf, unsigned int flags)
111MODULE_LICENSE("GPL"); 215{
216
217 /*
218 * allocate memory region and set the memory information
219 * to vaddr and dma_addr of a buffer object.
220 */
221 if (lowlevel_buffer_allocate(dev, flags, buf) < 0)
222 return -ENOMEM;
223
224 return 0;
225}
226
227void exynos_drm_free_buf(struct drm_device *dev,
228 unsigned int flags, struct exynos_drm_gem_buf *buffer)
229{
230
231 lowlevel_buffer_deallocate(dev, flags, buffer);
232}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.h b/drivers/gpu/drm/exynos/exynos_drm_buf.h
index c913f2bad760..3388e4eb4ba2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_buf.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_buf.h
@@ -26,12 +26,22 @@
26#ifndef _EXYNOS_DRM_BUF_H_ 26#ifndef _EXYNOS_DRM_BUF_H_
27#define _EXYNOS_DRM_BUF_H_ 27#define _EXYNOS_DRM_BUF_H_
28 28
29/* allocate physical memory. */ 29/* create and initialize buffer object. */
30struct exynos_drm_gem_buf *exynos_drm_buf_create(struct drm_device *dev, 30struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev,
31 unsigned int size); 31 unsigned int size);
32 32
33/* remove allocated physical memory. */ 33/* destroy buffer object. */
34void exynos_drm_buf_destroy(struct drm_device *dev, 34void exynos_drm_fini_buf(struct drm_device *dev,
35 struct exynos_drm_gem_buf *buffer); 35 struct exynos_drm_gem_buf *buffer);
36
37/* allocate physical memory region and setup sgt and pages. */
38int exynos_drm_alloc_buf(struct drm_device *dev,
39 struct exynos_drm_gem_buf *buf,
40 unsigned int flags);
41
42/* release physical memory region, sgt and pages. */
43void exynos_drm_free_buf(struct drm_device *dev,
44 unsigned int flags,
45 struct exynos_drm_gem_buf *buffer);
36 46
37#endif 47#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index 99d5527b2ca6..bf791fa0e50d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -225,6 +225,29 @@ static struct drm_connector_helper_funcs exynos_connector_helper_funcs = {
225 .best_encoder = exynos_drm_best_encoder, 225 .best_encoder = exynos_drm_best_encoder,
226}; 226};
227 227
228static int exynos_drm_connector_fill_modes(struct drm_connector *connector,
229 unsigned int max_width, unsigned int max_height)
230{
231 struct exynos_drm_connector *exynos_connector =
232 to_exynos_connector(connector);
233 struct exynos_drm_manager *manager = exynos_connector->manager;
234 struct exynos_drm_manager_ops *ops = manager->ops;
235 unsigned int width, height;
236
237 width = max_width;
238 height = max_height;
239
240 /*
241 * if specific driver want to find desired_mode using maxmum
242 * resolution then get max width and height from that driver.
243 */
244 if (ops && ops->get_max_resol)
245 ops->get_max_resol(manager->dev, &width, &height);
246
247 return drm_helper_probe_single_connector_modes(connector, width,
248 height);
249}
250
228/* get detection status of display device. */ 251/* get detection status of display device. */
229static enum drm_connector_status 252static enum drm_connector_status
230exynos_drm_connector_detect(struct drm_connector *connector, bool force) 253exynos_drm_connector_detect(struct drm_connector *connector, bool force)
@@ -262,7 +285,7 @@ static void exynos_drm_connector_destroy(struct drm_connector *connector)
262 285
263static struct drm_connector_funcs exynos_connector_funcs = { 286static struct drm_connector_funcs exynos_connector_funcs = {
264 .dpms = drm_helper_connector_dpms, 287 .dpms = drm_helper_connector_dpms,
265 .fill_modes = drm_helper_probe_single_connector_modes, 288 .fill_modes = exynos_drm_connector_fill_modes,
266 .detect = exynos_drm_connector_detect, 289 .detect = exynos_drm_connector_detect,
267 .destroy = exynos_drm_connector_destroy, 290 .destroy = exynos_drm_connector_destroy,
268}; 291};
@@ -292,6 +315,10 @@ struct drm_connector *exynos_drm_connector_create(struct drm_device *dev,
292 connector->interlace_allowed = true; 315 connector->interlace_allowed = true;
293 connector->polled = DRM_CONNECTOR_POLL_HPD; 316 connector->polled = DRM_CONNECTOR_POLL_HPD;
294 break; 317 break;
318 case EXYNOS_DISPLAY_TYPE_VIDI:
319 type = DRM_MODE_CONNECTOR_VIRTUAL;
320 connector->polled = DRM_CONNECTOR_POLL_HPD;
321 break;
295 default: 322 default:
296 type = DRM_MODE_CONNECTOR_Unknown; 323 type = DRM_MODE_CONNECTOR_Unknown;
297 break; 324 break;
@@ -325,9 +352,3 @@ err_connector:
325 kfree(exynos_connector); 352 kfree(exynos_connector);
326 return NULL; 353 return NULL;
327} 354}
328
329MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
330MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
331MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
332MODULE_DESCRIPTION("Samsung SoC DRM Connector Driver");
333MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index d08a55896d50..411832e8e17a 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -32,7 +32,6 @@
32#include "exynos_drm_connector.h" 32#include "exynos_drm_connector.h"
33#include "exynos_drm_fbdev.h" 33#include "exynos_drm_fbdev.h"
34 34
35static DEFINE_MUTEX(exynos_drm_mutex);
36static LIST_HEAD(exynos_drm_subdrv_list); 35static LIST_HEAD(exynos_drm_subdrv_list);
37static struct drm_device *drm_dev; 36static struct drm_device *drm_dev;
38 37
@@ -60,6 +59,9 @@ static int exynos_drm_subdrv_probe(struct drm_device *dev,
60 return ret; 59 return ret;
61 } 60 }
62 61
62 if (subdrv->is_local)
63 return 0;
64
63 /* create and initialize a encoder for this sub driver. */ 65 /* create and initialize a encoder for this sub driver. */
64 encoder = exynos_drm_encoder_create(dev, &subdrv->manager, 66 encoder = exynos_drm_encoder_create(dev, &subdrv->manager,
65 (1 << MAX_CRTC) - 1); 67 (1 << MAX_CRTC) - 1);
@@ -116,13 +118,10 @@ int exynos_drm_device_register(struct drm_device *dev)
116 if (!dev) 118 if (!dev)
117 return -EINVAL; 119 return -EINVAL;
118 120
119 if (drm_dev) { 121 drm_dev = dev;
120 DRM_ERROR("Already drm device were registered\n");
121 return -EBUSY;
122 }
123 122
124 mutex_lock(&exynos_drm_mutex);
125 list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) { 123 list_for_each_entry_safe(subdrv, n, &exynos_drm_subdrv_list, list) {
124 subdrv->drm_dev = dev;
126 err = exynos_drm_subdrv_probe(dev, subdrv); 125 err = exynos_drm_subdrv_probe(dev, subdrv);
127 if (err) { 126 if (err) {
128 DRM_DEBUG("exynos drm subdrv probe failed.\n"); 127 DRM_DEBUG("exynos drm subdrv probe failed.\n");
@@ -130,9 +129,6 @@ int exynos_drm_device_register(struct drm_device *dev)
130 } 129 }
131 } 130 }
132 131
133 drm_dev = dev;
134 mutex_unlock(&exynos_drm_mutex);
135
136 return 0; 132 return 0;
137} 133}
138EXPORT_SYMBOL_GPL(exynos_drm_device_register); 134EXPORT_SYMBOL_GPL(exynos_drm_device_register);
@@ -143,86 +139,28 @@ int exynos_drm_device_unregister(struct drm_device *dev)
143 139
144 DRM_DEBUG_DRIVER("%s\n", __FILE__); 140 DRM_DEBUG_DRIVER("%s\n", __FILE__);
145 141
146 if (!dev || dev != drm_dev) { 142 if (!dev) {
147 WARN(1, "Unexpected drm device unregister!\n"); 143 WARN(1, "Unexpected drm device unregister!\n");
148 return -EINVAL; 144 return -EINVAL;
149 } 145 }
150 146
151 mutex_lock(&exynos_drm_mutex);
152 list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) 147 list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list)
153 exynos_drm_subdrv_remove(dev, subdrv); 148 exynos_drm_subdrv_remove(dev, subdrv);
154 149
155 drm_dev = NULL; 150 drm_dev = NULL;
156 mutex_unlock(&exynos_drm_mutex);
157 151
158 return 0; 152 return 0;
159} 153}
160EXPORT_SYMBOL_GPL(exynos_drm_device_unregister); 154EXPORT_SYMBOL_GPL(exynos_drm_device_unregister);
161 155
162static int exynos_drm_mode_group_reinit(struct drm_device *dev)
163{
164 struct drm_mode_group *group = &dev->primary->mode_group;
165 uint32_t *id_list = group->id_list;
166 int ret;
167
168 DRM_DEBUG_DRIVER("%s\n", __FILE__);
169
170 ret = drm_mode_group_init_legacy_group(dev, group);
171 if (ret < 0)
172 return ret;
173
174 kfree(id_list);
175 return 0;
176}
177
178int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv) 156int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
179{ 157{
180 int err;
181
182 DRM_DEBUG_DRIVER("%s\n", __FILE__); 158 DRM_DEBUG_DRIVER("%s\n", __FILE__);
183 159
184 if (!subdrv) 160 if (!subdrv)
185 return -EINVAL; 161 return -EINVAL;
186 162
187 mutex_lock(&exynos_drm_mutex);
188 if (drm_dev) {
189 err = exynos_drm_subdrv_probe(drm_dev, subdrv);
190 if (err) {
191 DRM_ERROR("failed to probe exynos drm subdrv\n");
192 mutex_unlock(&exynos_drm_mutex);
193 return err;
194 }
195
196 /* setup possible_clones. */
197 exynos_drm_encoder_setup(drm_dev);
198
199 /*
200 * if any specific driver such as fimd or hdmi driver called
201 * exynos_drm_subdrv_register() later than drm_load(),
202 * the fb helper should be re-initialized and re-configured.
203 */
204 err = exynos_drm_fbdev_reinit(drm_dev);
205 if (err) {
206 DRM_ERROR("failed to reinitialize exynos drm fbdev\n");
207 exynos_drm_subdrv_remove(drm_dev, subdrv);
208 mutex_unlock(&exynos_drm_mutex);
209 return err;
210 }
211
212 err = exynos_drm_mode_group_reinit(drm_dev);
213 if (err) {
214 DRM_ERROR("failed to reinitialize mode group\n");
215 exynos_drm_fbdev_fini(drm_dev);
216 exynos_drm_subdrv_remove(drm_dev, subdrv);
217 mutex_unlock(&exynos_drm_mutex);
218 return err;
219 }
220 }
221
222 subdrv->drm_dev = drm_dev;
223
224 list_add_tail(&subdrv->list, &exynos_drm_subdrv_list); 163 list_add_tail(&subdrv->list, &exynos_drm_subdrv_list);
225 mutex_unlock(&exynos_drm_mutex);
226 164
227 return 0; 165 return 0;
228} 166}
@@ -230,46 +168,48 @@ EXPORT_SYMBOL_GPL(exynos_drm_subdrv_register);
230 168
231int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv) 169int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *subdrv)
232{ 170{
233 int ret = -EFAULT;
234
235 DRM_DEBUG_DRIVER("%s\n", __FILE__); 171 DRM_DEBUG_DRIVER("%s\n", __FILE__);
236 172
237 if (!subdrv) { 173 if (!subdrv)
238 DRM_DEBUG("Unexpected exynos drm subdrv unregister!\n"); 174 return -EINVAL;
239 return ret;
240 }
241 175
242 mutex_lock(&exynos_drm_mutex); 176 list_del(&subdrv->list);
243 if (drm_dev) {
244 exynos_drm_subdrv_remove(drm_dev, subdrv);
245 list_del(&subdrv->list);
246 177
247 /* 178 return 0;
248 * fb helper should be updated once a sub driver is released 179}
249 * to re-configure crtc and connector and also to re-setup 180EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister);
250 * drm framebuffer.
251 */
252 ret = exynos_drm_fbdev_reinit(drm_dev);
253 if (ret < 0) {
254 DRM_ERROR("failed fb helper reinit.\n");
255 goto fail;
256 }
257 181
258 ret = exynos_drm_mode_group_reinit(drm_dev); 182int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
259 if (ret < 0) { 183{
260 DRM_ERROR("failed drm mode group reinit.\n"); 184 struct exynos_drm_subdrv *subdrv;
261 goto fail; 185 int ret;
186
187 list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
188 if (subdrv->open) {
189 ret = subdrv->open(dev, subdrv->manager.dev, file);
190 if (ret)
191 goto err;
262 } 192 }
263 } 193 }
264 194
265fail: 195 return 0;
266 mutex_unlock(&exynos_drm_mutex); 196
197err:
198 list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
199 if (subdrv->close)
200 subdrv->close(dev, subdrv->manager.dev, file);
201 }
267 return ret; 202 return ret;
268} 203}
269EXPORT_SYMBOL_GPL(exynos_drm_subdrv_unregister); 204EXPORT_SYMBOL_GPL(exynos_drm_subdrv_open);
205
206void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file)
207{
208 struct exynos_drm_subdrv *subdrv;
270 209
271MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); 210 list_for_each_entry(subdrv, &exynos_drm_subdrv_list, list) {
272MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 211 if (subdrv->close)
273MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>"); 212 subdrv->close(dev, subdrv->manager.dev, file);
274MODULE_DESCRIPTION("Samsung SoC DRM Core Driver"); 213 }
275MODULE_LICENSE("GPL"); 214}
215EXPORT_SYMBOL_GPL(exynos_drm_subdrv_close);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index de818831a511..3486ffed0bf0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -249,7 +249,11 @@ exynos_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
249{ 249{
250 DRM_DEBUG_KMS("%s\n", __FILE__); 250 DRM_DEBUG_KMS("%s\n", __FILE__);
251 251
252 mode = adjusted_mode; 252 /*
253 * copy the mode data adjusted by mode_fixup() into crtc->mode
254 * so that hardware can be seet to proper mode.
255 */
256 memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));
253 257
254 return exynos_drm_crtc_update(crtc); 258 return exynos_drm_crtc_update(crtc);
255} 259}
@@ -426,9 +430,3 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)
426 exynos_drm_fn_encoder(private->crtc[crtc], &crtc, 430 exynos_drm_fn_encoder(private->crtc[crtc], &crtc,
427 exynos_drm_disable_vblank); 431 exynos_drm_disable_vblank);
428} 432}
429
430MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
431MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
432MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
433MODULE_DESCRIPTION("Samsung SoC DRM CRTC Driver");
434MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 09cc13f791b3..a6819b5f8428 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -38,6 +38,7 @@
38#include "exynos_drm_fb.h" 38#include "exynos_drm_fb.h"
39#include "exynos_drm_gem.h" 39#include "exynos_drm_gem.h"
40#include "exynos_drm_plane.h" 40#include "exynos_drm_plane.h"
41#include "exynos_drm_vidi.h"
41 42
42#define DRIVER_NAME "exynos" 43#define DRIVER_NAME "exynos"
43#define DRIVER_DESC "Samsung SoC DRM" 44#define DRIVER_DESC "Samsung SoC DRM"
@@ -144,11 +145,34 @@ static int exynos_drm_unload(struct drm_device *dev)
144 return 0; 145 return 0;
145} 146}
146 147
148static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
149{
150 DRM_DEBUG_DRIVER("%s\n", __FILE__);
151
152 return exynos_drm_subdrv_open(dev, file);
153}
154
147static void exynos_drm_preclose(struct drm_device *dev, 155static void exynos_drm_preclose(struct drm_device *dev,
148 struct drm_file *file) 156 struct drm_file *file)
149{ 157{
158 struct exynos_drm_private *private = dev->dev_private;
159 struct drm_pending_vblank_event *e, *t;
160 unsigned long flags;
161
150 DRM_DEBUG_DRIVER("%s\n", __FILE__); 162 DRM_DEBUG_DRIVER("%s\n", __FILE__);
151 163
164 /* release events of current file */
165 spin_lock_irqsave(&dev->event_lock, flags);
166 list_for_each_entry_safe(e, t, &private->pageflip_event_list,
167 base.link) {
168 if (e->base.file_priv == file) {
169 list_del(&e->base.link);
170 e->base.destroy(&e->base);
171 }
172 }
173 spin_unlock_irqrestore(&dev->event_lock, flags);
174
175 exynos_drm_subdrv_close(dev, file);
152} 176}
153 177
154static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) 178static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
@@ -185,6 +209,8 @@ static struct drm_ioctl_desc exynos_ioctls[] = {
185 exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH), 209 exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
186 DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl, 210 DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
187 DRM_UNLOCKED | DRM_AUTH), 211 DRM_UNLOCKED | DRM_AUTH),
212 DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION,
213 vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH),
188}; 214};
189 215
190static const struct file_operations exynos_drm_driver_fops = { 216static const struct file_operations exynos_drm_driver_fops = {
@@ -202,6 +228,7 @@ static struct drm_driver exynos_drm_driver = {
202 DRIVER_MODESET | DRIVER_GEM, 228 DRIVER_MODESET | DRIVER_GEM,
203 .load = exynos_drm_load, 229 .load = exynos_drm_load,
204 .unload = exynos_drm_unload, 230 .unload = exynos_drm_unload,
231 .open = exynos_drm_open,
205 .preclose = exynos_drm_preclose, 232 .preclose = exynos_drm_preclose,
206 .lastclose = exynos_drm_lastclose, 233 .lastclose = exynos_drm_lastclose,
207 .postclose = exynos_drm_postclose, 234 .postclose = exynos_drm_postclose,
@@ -252,9 +279,60 @@ static struct platform_driver exynos_drm_platform_driver = {
252 279
253static int __init exynos_drm_init(void) 280static int __init exynos_drm_init(void)
254{ 281{
282 int ret;
283
255 DRM_DEBUG_DRIVER("%s\n", __FILE__); 284 DRM_DEBUG_DRIVER("%s\n", __FILE__);
256 285
257 return platform_driver_register(&exynos_drm_platform_driver); 286#ifdef CONFIG_DRM_EXYNOS_FIMD
287 ret = platform_driver_register(&fimd_driver);
288 if (ret < 0)
289 goto out_fimd;
290#endif
291
292#ifdef CONFIG_DRM_EXYNOS_HDMI
293 ret = platform_driver_register(&hdmi_driver);
294 if (ret < 0)
295 goto out_hdmi;
296 ret = platform_driver_register(&mixer_driver);
297 if (ret < 0)
298 goto out_mixer;
299 ret = platform_driver_register(&exynos_drm_common_hdmi_driver);
300 if (ret < 0)
301 goto out_common_hdmi;
302#endif
303
304#ifdef CONFIG_DRM_EXYNOS_VIDI
305 ret = platform_driver_register(&vidi_driver);
306 if (ret < 0)
307 goto out_vidi;
308#endif
309
310 ret = platform_driver_register(&exynos_drm_platform_driver);
311 if (ret < 0)
312 goto out;
313
314 return 0;
315
316out:
317#ifdef CONFIG_DRM_EXYNOS_VIDI
318out_vidi:
319 platform_driver_unregister(&vidi_driver);
320#endif
321
322#ifdef CONFIG_DRM_EXYNOS_HDMI
323 platform_driver_unregister(&exynos_drm_common_hdmi_driver);
324out_common_hdmi:
325 platform_driver_unregister(&mixer_driver);
326out_mixer:
327 platform_driver_unregister(&hdmi_driver);
328out_hdmi:
329#endif
330
331#ifdef CONFIG_DRM_EXYNOS_FIMD
332 platform_driver_unregister(&fimd_driver);
333out_fimd:
334#endif
335 return ret;
258} 336}
259 337
260static void __exit exynos_drm_exit(void) 338static void __exit exynos_drm_exit(void)
@@ -262,6 +340,20 @@ static void __exit exynos_drm_exit(void)
262 DRM_DEBUG_DRIVER("%s\n", __FILE__); 340 DRM_DEBUG_DRIVER("%s\n", __FILE__);
263 341
264 platform_driver_unregister(&exynos_drm_platform_driver); 342 platform_driver_unregister(&exynos_drm_platform_driver);
343
344#ifdef CONFIG_DRM_EXYNOS_HDMI
345 platform_driver_unregister(&exynos_drm_common_hdmi_driver);
346 platform_driver_unregister(&mixer_driver);
347 platform_driver_unregister(&hdmi_driver);
348#endif
349
350#ifdef CONFIG_DRM_EXYNOS_VIDI
351 platform_driver_unregister(&vidi_driver);
352#endif
353
354#ifdef CONFIG_DRM_EXYNOS_FIMD
355 platform_driver_unregister(&fimd_driver);
356#endif
265} 357}
266 358
267module_init(exynos_drm_init); 359module_init(exynos_drm_init);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 13540de90bfc..fbd0a232c93d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -32,9 +32,9 @@
32#include <linux/module.h> 32#include <linux/module.h>
33#include "drm.h" 33#include "drm.h"
34 34
35#define MAX_CRTC 2 35#define MAX_CRTC 3
36#define MAX_PLANE 5 36#define MAX_PLANE 5
37#define MAX_FB_BUFFER 3 37#define MAX_FB_BUFFER 4
38#define DEFAULT_ZPOS -1 38#define DEFAULT_ZPOS -1
39 39
40struct drm_device; 40struct drm_device;
@@ -50,6 +50,8 @@ enum exynos_drm_output_type {
50 EXYNOS_DISPLAY_TYPE_LCD, 50 EXYNOS_DISPLAY_TYPE_LCD,
51 /* HDMI Interface. */ 51 /* HDMI Interface. */
52 EXYNOS_DISPLAY_TYPE_HDMI, 52 EXYNOS_DISPLAY_TYPE_HDMI,
53 /* Virtual Display Interface. */
54 EXYNOS_DISPLAY_TYPE_VIDI,
53}; 55};
54 56
55/* 57/*
@@ -155,8 +157,10 @@ struct exynos_drm_display_ops {
155 * 157 *
156 * @dpms: control device power. 158 * @dpms: control device power.
157 * @apply: set timing, vblank and overlay data to registers. 159 * @apply: set timing, vblank and overlay data to registers.
160 * @mode_fixup: fix mode data comparing to hw specific display mode.
158 * @mode_set: convert drm_display_mode to hw specific display mode and 161 * @mode_set: convert drm_display_mode to hw specific display mode and
159 * would be called by encoder->mode_set(). 162 * would be called by encoder->mode_set().
163 * @get_max_resol: get maximum resolution to specific hardware.
160 * @commit: set current hw specific display mode to hw. 164 * @commit: set current hw specific display mode to hw.
161 * @enable_vblank: specific driver callback for enabling vblank interrupt. 165 * @enable_vblank: specific driver callback for enabling vblank interrupt.
162 * @disable_vblank: specific driver callback for disabling vblank interrupt. 166 * @disable_vblank: specific driver callback for disabling vblank interrupt.
@@ -164,7 +168,13 @@ struct exynos_drm_display_ops {
164struct exynos_drm_manager_ops { 168struct exynos_drm_manager_ops {
165 void (*dpms)(struct device *subdrv_dev, int mode); 169 void (*dpms)(struct device *subdrv_dev, int mode);
166 void (*apply)(struct device *subdrv_dev); 170 void (*apply)(struct device *subdrv_dev);
171 void (*mode_fixup)(struct device *subdrv_dev,
172 struct drm_connector *connector,
173 struct drm_display_mode *mode,
174 struct drm_display_mode *adjusted_mode);
167 void (*mode_set)(struct device *subdrv_dev, void *mode); 175 void (*mode_set)(struct device *subdrv_dev, void *mode);
176 void (*get_max_resol)(struct device *subdrv_dev, unsigned int *width,
177 unsigned int *height);
168 void (*commit)(struct device *subdrv_dev); 178 void (*commit)(struct device *subdrv_dev);
169 int (*enable_vblank)(struct device *subdrv_dev); 179 int (*enable_vblank)(struct device *subdrv_dev);
170 void (*disable_vblank)(struct device *subdrv_dev); 180 void (*disable_vblank)(struct device *subdrv_dev);
@@ -217,10 +227,13 @@ struct exynos_drm_private {
217 * @list: sub driver has its own list object to register to exynos drm driver. 227 * @list: sub driver has its own list object to register to exynos drm driver.
218 * @drm_dev: pointer to drm_device and this pointer would be set 228 * @drm_dev: pointer to drm_device and this pointer would be set
219 * when sub driver calls exynos_drm_subdrv_register(). 229 * when sub driver calls exynos_drm_subdrv_register().
230 * @is_local: appear encoder and connector disrelated device.
220 * @probe: this callback would be called by exynos drm driver after 231 * @probe: this callback would be called by exynos drm driver after
221 * subdrv is registered to it. 232 * subdrv is registered to it.
222 * @remove: this callback is used to release resources created 233 * @remove: this callback is used to release resources created
223 * by probe callback. 234 * by probe callback.
235 * @open: this would be called with drm device file open.
236 * @close: this would be called with drm device file close.
224 * @manager: subdrv has its own manager to control a hardware appropriately 237 * @manager: subdrv has its own manager to control a hardware appropriately
225 * and we can access a hardware drawing on this manager. 238 * and we can access a hardware drawing on this manager.
226 * @encoder: encoder object owned by this sub driver. 239 * @encoder: encoder object owned by this sub driver.
@@ -229,9 +242,14 @@ struct exynos_drm_private {
229struct exynos_drm_subdrv { 242struct exynos_drm_subdrv {
230 struct list_head list; 243 struct list_head list;
231 struct drm_device *drm_dev; 244 struct drm_device *drm_dev;
245 bool is_local;
232 246
233 int (*probe)(struct drm_device *drm_dev, struct device *dev); 247 int (*probe)(struct drm_device *drm_dev, struct device *dev);
234 void (*remove)(struct drm_device *dev); 248 void (*remove)(struct drm_device *dev);
249 int (*open)(struct drm_device *drm_dev, struct device *dev,
250 struct drm_file *file);
251 void (*close)(struct drm_device *drm_dev, struct device *dev,
252 struct drm_file *file);
235 253
236 struct exynos_drm_manager manager; 254 struct exynos_drm_manager manager;
237 struct drm_encoder *encoder; 255 struct drm_encoder *encoder;
@@ -254,15 +272,19 @@ int exynos_drm_device_unregister(struct drm_device *dev);
254 * this function would be called by sub drivers such as display controller 272 * this function would be called by sub drivers such as display controller
255 * or hdmi driver to register this sub driver object to exynos drm driver 273 * or hdmi driver to register this sub driver object to exynos drm driver
256 * and when a sub driver is registered to exynos drm driver a probe callback 274 * and when a sub driver is registered to exynos drm driver a probe callback
257 * of the sub driver is called and creates its own encoder and connector 275 * of the sub driver is called and creates its own encoder and connector.
258 * and then fb helper and drm mode group would be re-initialized.
259 */ 276 */
260int exynos_drm_subdrv_register(struct exynos_drm_subdrv *drm_subdrv); 277int exynos_drm_subdrv_register(struct exynos_drm_subdrv *drm_subdrv);
261 278
262/* 279/* this function removes subdrv list from exynos drm driver */
263 * this function removes subdrv list from exynos drm driver and fb helper
264 * and drm mode group would be re-initialized.
265 */
266int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv); 280int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv);
267 281
282int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
283void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
284
285extern struct platform_driver fimd_driver;
286extern struct platform_driver hdmi_driver;
287extern struct platform_driver mixer_driver;
288extern struct platform_driver exynos_drm_common_hdmi_driver;
289extern struct platform_driver vidi_driver;
268#endif 290#endif
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index ef4754f1519b..6e9ac7bd1dcf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -111,9 +111,19 @@ exynos_drm_encoder_mode_fixup(struct drm_encoder *encoder,
111 struct drm_display_mode *mode, 111 struct drm_display_mode *mode,
112 struct drm_display_mode *adjusted_mode) 112 struct drm_display_mode *adjusted_mode)
113{ 113{
114 struct drm_device *dev = encoder->dev;
115 struct drm_connector *connector;
116 struct exynos_drm_manager *manager = exynos_drm_get_manager(encoder);
117 struct exynos_drm_manager_ops *manager_ops = manager->ops;
118
114 DRM_DEBUG_KMS("%s\n", __FILE__); 119 DRM_DEBUG_KMS("%s\n", __FILE__);
115 120
116 /* drm framework doesn't check NULL. */ 121 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
122 if (connector->encoder == encoder)
123 if (manager_ops && manager_ops->mode_fixup)
124 manager_ops->mode_fixup(manager->dev, connector,
125 mode, adjusted_mode);
126 }
117 127
118 return true; 128 return true;
119} 129}
@@ -132,12 +142,11 @@ static void exynos_drm_encoder_mode_set(struct drm_encoder *encoder,
132 142
133 DRM_DEBUG_KMS("%s\n", __FILE__); 143 DRM_DEBUG_KMS("%s\n", __FILE__);
134 144
135 mode = adjusted_mode;
136
137 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 145 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
138 if (connector->encoder == encoder) { 146 if (connector->encoder == encoder) {
139 if (manager_ops && manager_ops->mode_set) 147 if (manager_ops && manager_ops->mode_set)
140 manager_ops->mode_set(manager->dev, mode); 148 manager_ops->mode_set(manager->dev,
149 adjusted_mode);
141 150
142 if (overlay_ops && overlay_ops->mode_set) 151 if (overlay_ops && overlay_ops->mode_set)
143 overlay_ops->mode_set(manager->dev, overlay); 152 overlay_ops->mode_set(manager->dev, overlay);
@@ -209,6 +218,7 @@ static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder)
209 switch (display_ops->type) { 218 switch (display_ops->type) {
210 case EXYNOS_DISPLAY_TYPE_LCD: 219 case EXYNOS_DISPLAY_TYPE_LCD:
211 case EXYNOS_DISPLAY_TYPE_HDMI: 220 case EXYNOS_DISPLAY_TYPE_HDMI:
221 case EXYNOS_DISPLAY_TYPE_VIDI:
212 clone_mask |= (1 << (cnt++)); 222 clone_mask |= (1 << (cnt++));
213 break; 223 break;
214 default: 224 default:
@@ -433,9 +443,3 @@ void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data)
433 if (overlay_ops && overlay_ops->disable) 443 if (overlay_ops && overlay_ops->disable)
434 overlay_ops->disable(manager->dev, zpos); 444 overlay_ops->disable(manager->dev, zpos);
435} 445}
436
437MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
438MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
439MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
440MODULE_DESCRIPTION("Samsung SoC DRM Encoder Driver");
441MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 3733fe6723d3..c38c8f468fa3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -211,9 +211,3 @@ void exynos_drm_mode_config_init(struct drm_device *dev)
211 211
212 dev->mode_config.funcs = &exynos_drm_mode_config_funcs; 212 dev->mode_config.funcs = &exynos_drm_mode_config_funcs;
213} 213}
214
215MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
216MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
217MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
218MODULE_DESCRIPTION("Samsung SoC DRM FB Driver");
219MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index 54f8f074822f..d5586cc75163 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -125,7 +125,9 @@ static int exynos_drm_fbdev_create(struct drm_fb_helper *helper,
125 } 125 }
126 126
127 size = mode_cmd.pitches[0] * mode_cmd.height; 127 size = mode_cmd.pitches[0] * mode_cmd.height;
128 exynos_gem_obj = exynos_drm_gem_create(dev, size); 128
129 /* 0 means to allocate physically continuous memory */
130 exynos_gem_obj = exynos_drm_gem_create(dev, 0, size);
129 if (IS_ERR(exynos_gem_obj)) { 131 if (IS_ERR(exynos_gem_obj)) {
130 ret = PTR_ERR(exynos_gem_obj); 132 ret = PTR_ERR(exynos_gem_obj);
131 goto out; 133 goto out;
@@ -314,89 +316,3 @@ void exynos_drm_fbdev_restore_mode(struct drm_device *dev)
314 316
315 drm_fb_helper_restore_fbdev_mode(private->fb_helper); 317 drm_fb_helper_restore_fbdev_mode(private->fb_helper);
316} 318}
317
318int exynos_drm_fbdev_reinit(struct drm_device *dev)
319{
320 struct exynos_drm_private *private = dev->dev_private;
321 struct drm_fb_helper *fb_helper;
322 int ret;
323
324 if (!private)
325 return -EINVAL;
326
327 /*
328 * if all sub drivers were unloaded then num_connector is 0
329 * so at this time, the framebuffers also should be destroyed.
330 */
331 if (!dev->mode_config.num_connector) {
332 exynos_drm_fbdev_fini(dev);
333 return 0;
334 }
335
336 fb_helper = private->fb_helper;
337
338 if (fb_helper) {
339 struct list_head temp_list;
340
341 INIT_LIST_HEAD(&temp_list);
342
343 /*
344 * fb_helper is reintialized but kernel fb is reused
345 * so kernel_fb_list need to be backuped and restored
346 */
347 if (!list_empty(&fb_helper->kernel_fb_list))
348 list_replace_init(&fb_helper->kernel_fb_list,
349 &temp_list);
350
351 drm_fb_helper_fini(fb_helper);
352
353 ret = drm_fb_helper_init(dev, fb_helper,
354 dev->mode_config.num_crtc, MAX_CONNECTOR);
355 if (ret < 0) {
356 DRM_ERROR("failed to initialize drm fb helper\n");
357 return ret;
358 }
359
360 if (!list_empty(&temp_list))
361 list_replace(&temp_list, &fb_helper->kernel_fb_list);
362
363 ret = drm_fb_helper_single_add_all_connectors(fb_helper);
364 if (ret < 0) {
365 DRM_ERROR("failed to add fb helper to connectors\n");
366 goto err;
367 }
368
369 ret = drm_fb_helper_initial_config(fb_helper, PREFERRED_BPP);
370 if (ret < 0) {
371 DRM_ERROR("failed to set up hw configuration.\n");
372 goto err;
373 }
374 } else {
375 /*
376 * if drm_load() failed whem drm load() was called prior
377 * to specific drivers, fb_helper must be NULL and so
378 * this fuction should be called again to re-initialize and
379 * re-configure the fb helper. it means that this function
380 * has been called by the specific drivers.
381 */
382 ret = exynos_drm_fbdev_init(dev);
383 }
384
385 return ret;
386
387err:
388 /*
389 * if drm_load() failed when drm load() was called prior
390 * to specific drivers, the fb_helper must be NULL and so check it.
391 */
392 if (fb_helper)
393 drm_fb_helper_fini(fb_helper);
394
395 return ret;
396}
397
398MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
399MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
400MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
401MODULE_DESCRIPTION("Samsung SoC DRM FBDEV Driver");
402MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 56458eea0501..ecb6db229700 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -1007,7 +1007,7 @@ static const struct dev_pm_ops fimd_pm_ops = {
1007 SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL) 1007 SET_RUNTIME_PM_OPS(fimd_runtime_suspend, fimd_runtime_resume, NULL)
1008}; 1008};
1009 1009
1010static struct platform_driver fimd_driver = { 1010struct platform_driver fimd_driver = {
1011 .probe = fimd_probe, 1011 .probe = fimd_probe,
1012 .remove = __devexit_p(fimd_remove), 1012 .remove = __devexit_p(fimd_remove),
1013 .driver = { 1013 .driver = {
@@ -1016,21 +1016,3 @@ static struct platform_driver fimd_driver = {
1016 .pm = &fimd_pm_ops, 1016 .pm = &fimd_pm_ops,
1017 }, 1017 },
1018}; 1018};
1019
1020static int __init fimd_init(void)
1021{
1022 return platform_driver_register(&fimd_driver);
1023}
1024
1025static void __exit fimd_exit(void)
1026{
1027 platform_driver_unregister(&fimd_driver);
1028}
1029
1030module_init(fimd_init);
1031module_exit(fimd_exit);
1032
1033MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
1034MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
1035MODULE_DESCRIPTION("Samsung DRM FIMD Driver");
1036MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 025abb3e3b67..fa1aa94a3d8e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -26,6 +26,7 @@
26#include "drmP.h" 26#include "drmP.h"
27#include "drm.h" 27#include "drm.h"
28 28
29#include <linux/shmem_fs.h>
29#include <drm/exynos_drm.h> 30#include <drm/exynos_drm.h>
30 31
31#include "exynos_drm_drv.h" 32#include "exynos_drm_drv.h"
@@ -55,6 +56,178 @@ static unsigned int convert_to_vm_err_msg(int msg)
55 return out_msg; 56 return out_msg;
56} 57}
57 58
59static unsigned int mask_gem_flags(unsigned int flags)
60{
61 return flags &= EXYNOS_BO_NONCONTIG;
62}
63
64static struct page **exynos_gem_get_pages(struct drm_gem_object *obj,
65 gfp_t gfpmask)
66{
67 struct inode *inode;
68 struct address_space *mapping;
69 struct page *p, **pages;
70 int i, npages;
71
72 /* This is the shared memory object that backs the GEM resource */
73 inode = obj->filp->f_path.dentry->d_inode;
74 mapping = inode->i_mapping;
75
76 npages = obj->size >> PAGE_SHIFT;
77
78 pages = drm_malloc_ab(npages, sizeof(struct page *));
79 if (pages == NULL)
80 return ERR_PTR(-ENOMEM);
81
82 gfpmask |= mapping_gfp_mask(mapping);
83
84 for (i = 0; i < npages; i++) {
85 p = shmem_read_mapping_page_gfp(mapping, i, gfpmask);
86 if (IS_ERR(p))
87 goto fail;
88 pages[i] = p;
89 }
90
91 return pages;
92
93fail:
94 while (i--)
95 page_cache_release(pages[i]);
96
97 drm_free_large(pages);
98 return ERR_PTR(PTR_ERR(p));
99}
100
101static void exynos_gem_put_pages(struct drm_gem_object *obj,
102 struct page **pages,
103 bool dirty, bool accessed)
104{
105 int i, npages;
106
107 npages = obj->size >> PAGE_SHIFT;
108
109 for (i = 0; i < npages; i++) {
110 if (dirty)
111 set_page_dirty(pages[i]);
112
113 if (accessed)
114 mark_page_accessed(pages[i]);
115
116 /* Undo the reference we took when populating the table */
117 page_cache_release(pages[i]);
118 }
119
120 drm_free_large(pages);
121}
122
123static int exynos_drm_gem_map_pages(struct drm_gem_object *obj,
124 struct vm_area_struct *vma,
125 unsigned long f_vaddr,
126 pgoff_t page_offset)
127{
128 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
129 struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
130 unsigned long pfn;
131
132 if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
133 unsigned long usize = buf->size;
134
135 if (!buf->pages)
136 return -EINTR;
137
138 while (usize > 0) {
139 pfn = page_to_pfn(buf->pages[page_offset++]);
140 vm_insert_mixed(vma, f_vaddr, pfn);
141 f_vaddr += PAGE_SIZE;
142 usize -= PAGE_SIZE;
143 }
144
145 return 0;
146 }
147
148 pfn = (buf->dma_addr >> PAGE_SHIFT) + page_offset;
149
150 return vm_insert_mixed(vma, f_vaddr, pfn);
151}
152
153static int exynos_drm_gem_get_pages(struct drm_gem_object *obj)
154{
155 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
156 struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
157 struct scatterlist *sgl;
158 struct page **pages;
159 unsigned int npages, i = 0;
160 int ret;
161
162 if (buf->pages) {
163 DRM_DEBUG_KMS("already allocated.\n");
164 return -EINVAL;
165 }
166
167 pages = exynos_gem_get_pages(obj, GFP_KERNEL);
168 if (IS_ERR(pages)) {
169 DRM_ERROR("failed to get pages.\n");
170 return PTR_ERR(pages);
171 }
172
173 npages = obj->size >> PAGE_SHIFT;
174
175 buf->sgt = kzalloc(sizeof(struct sg_table), GFP_KERNEL);
176 if (!buf->sgt) {
177 DRM_ERROR("failed to allocate sg table.\n");
178 ret = -ENOMEM;
179 goto err;
180 }
181
182 ret = sg_alloc_table(buf->sgt, npages, GFP_KERNEL);
183 if (ret < 0) {
184 DRM_ERROR("failed to initialize sg table.\n");
185 ret = -EFAULT;
186 goto err1;
187 }
188
189 sgl = buf->sgt->sgl;
190
191 /* set all pages to sg list. */
192 while (i < npages) {
193 sg_set_page(sgl, pages[i], PAGE_SIZE, 0);
194 sg_dma_address(sgl) = page_to_phys(pages[i]);
195 i++;
196 sgl = sg_next(sgl);
197 }
198
199 /* add some codes for UNCACHED type here. TODO */
200
201 buf->pages = pages;
202 return ret;
203err1:
204 kfree(buf->sgt);
205 buf->sgt = NULL;
206err:
207 exynos_gem_put_pages(obj, pages, true, false);
208 return ret;
209
210}
211
212static void exynos_drm_gem_put_pages(struct drm_gem_object *obj)
213{
214 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
215 struct exynos_drm_gem_buf *buf = exynos_gem_obj->buffer;
216
217 /*
218 * if buffer typs is EXYNOS_BO_NONCONTIG then release all pages
219 * allocated at gem fault handler.
220 */
221 sg_free_table(buf->sgt);
222 kfree(buf->sgt);
223 buf->sgt = NULL;
224
225 exynos_gem_put_pages(obj, buf->pages, true, false);
226 buf->pages = NULL;
227
228 /* add some codes for UNCACHED type here. TODO */
229}
230
58static int exynos_drm_gem_handle_create(struct drm_gem_object *obj, 231static int exynos_drm_gem_handle_create(struct drm_gem_object *obj,
59 struct drm_file *file_priv, 232 struct drm_file *file_priv,
60 unsigned int *handle) 233 unsigned int *handle)
@@ -90,7 +263,15 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj)
90 263
91 DRM_DEBUG_KMS("handle count = %d\n", atomic_read(&obj->handle_count)); 264 DRM_DEBUG_KMS("handle count = %d\n", atomic_read(&obj->handle_count));
92 265
93 exynos_drm_buf_destroy(obj->dev, exynos_gem_obj->buffer); 266 if ((exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) &&
267 exynos_gem_obj->buffer->pages)
268 exynos_drm_gem_put_pages(obj);
269 else
270 exynos_drm_free_buf(obj->dev, exynos_gem_obj->flags,
271 exynos_gem_obj->buffer);
272
273 exynos_drm_fini_buf(obj->dev, exynos_gem_obj->buffer);
274 exynos_gem_obj->buffer = NULL;
94 275
95 if (obj->map_list.map) 276 if (obj->map_list.map)
96 drm_gem_free_mmap_offset(obj); 277 drm_gem_free_mmap_offset(obj);
@@ -99,6 +280,7 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj)
99 drm_gem_object_release(obj); 280 drm_gem_object_release(obj);
100 281
101 kfree(exynos_gem_obj); 282 kfree(exynos_gem_obj);
283 exynos_gem_obj = NULL;
102} 284}
103 285
104static struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev, 286static struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev,
@@ -114,6 +296,7 @@ static struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev,
114 return NULL; 296 return NULL;
115 } 297 }
116 298
299 exynos_gem_obj->size = size;
117 obj = &exynos_gem_obj->base; 300 obj = &exynos_gem_obj->base;
118 301
119 ret = drm_gem_object_init(dev, obj, size); 302 ret = drm_gem_object_init(dev, obj, size);
@@ -129,27 +312,55 @@ static struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev,
129} 312}
130 313
131struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, 314struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
132 unsigned long size) 315 unsigned int flags,
316 unsigned long size)
133{ 317{
134 struct exynos_drm_gem_buf *buffer;
135 struct exynos_drm_gem_obj *exynos_gem_obj; 318 struct exynos_drm_gem_obj *exynos_gem_obj;
319 struct exynos_drm_gem_buf *buf;
320 int ret;
136 321
137 size = roundup(size, PAGE_SIZE); 322 size = roundup(size, PAGE_SIZE);
138 DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size); 323 DRM_DEBUG_KMS("%s: size = 0x%lx\n", __FILE__, size);
139 324
140 buffer = exynos_drm_buf_create(dev, size); 325 flags = mask_gem_flags(flags);
141 if (!buffer) 326
327 buf = exynos_drm_init_buf(dev, size);
328 if (!buf)
142 return ERR_PTR(-ENOMEM); 329 return ERR_PTR(-ENOMEM);
143 330
144 exynos_gem_obj = exynos_drm_gem_init(dev, size); 331 exynos_gem_obj = exynos_drm_gem_init(dev, size);
145 if (!exynos_gem_obj) { 332 if (!exynos_gem_obj) {
146 exynos_drm_buf_destroy(dev, buffer); 333 ret = -ENOMEM;
147 return ERR_PTR(-ENOMEM); 334 goto err;
148 } 335 }
149 336
150 exynos_gem_obj->buffer = buffer; 337 exynos_gem_obj->buffer = buf;
338
339 /* set memory type and cache attribute from user side. */
340 exynos_gem_obj->flags = flags;
341
342 /*
343 * allocate all pages as desired size if user wants to allocate
344 * physically non-continuous memory.
345 */
346 if (flags & EXYNOS_BO_NONCONTIG) {
347 ret = exynos_drm_gem_get_pages(&exynos_gem_obj->base);
348 if (ret < 0) {
349 drm_gem_object_release(&exynos_gem_obj->base);
350 goto err;
351 }
352 } else {
353 ret = exynos_drm_alloc_buf(dev, buf, flags);
354 if (ret < 0) {
355 drm_gem_object_release(&exynos_gem_obj->base);
356 goto err;
357 }
358 }
151 359
152 return exynos_gem_obj; 360 return exynos_gem_obj;
361err:
362 exynos_drm_fini_buf(dev, buf);
363 return ERR_PTR(ret);
153} 364}
154 365
155int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, 366int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
@@ -161,7 +372,7 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
161 372
162 DRM_DEBUG_KMS("%s\n", __FILE__); 373 DRM_DEBUG_KMS("%s\n", __FILE__);
163 374
164 exynos_gem_obj = exynos_drm_gem_create(dev, args->size); 375 exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);
165 if (IS_ERR(exynos_gem_obj)) 376 if (IS_ERR(exynos_gem_obj))
166 return PTR_ERR(exynos_gem_obj); 377 return PTR_ERR(exynos_gem_obj);
167 378
@@ -175,6 +386,64 @@ int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
175 return 0; 386 return 0;
176} 387}
177 388
389void *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
390 unsigned int gem_handle,
391 struct drm_file *file_priv)
392{
393 struct exynos_drm_gem_obj *exynos_gem_obj;
394 struct drm_gem_object *obj;
395
396 obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
397 if (!obj) {
398 DRM_ERROR("failed to lookup gem object.\n");
399 return ERR_PTR(-EINVAL);
400 }
401
402 exynos_gem_obj = to_exynos_gem_obj(obj);
403
404 if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
405 DRM_DEBUG_KMS("not support NONCONTIG type.\n");
406 drm_gem_object_unreference_unlocked(obj);
407
408 /* TODO */
409 return ERR_PTR(-EINVAL);
410 }
411
412 return &exynos_gem_obj->buffer->dma_addr;
413}
414
415void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
416 unsigned int gem_handle,
417 struct drm_file *file_priv)
418{
419 struct exynos_drm_gem_obj *exynos_gem_obj;
420 struct drm_gem_object *obj;
421
422 obj = drm_gem_object_lookup(dev, file_priv, gem_handle);
423 if (!obj) {
424 DRM_ERROR("failed to lookup gem object.\n");
425 return;
426 }
427
428 exynos_gem_obj = to_exynos_gem_obj(obj);
429
430 if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
431 DRM_DEBUG_KMS("not support NONCONTIG type.\n");
432 drm_gem_object_unreference_unlocked(obj);
433
434 /* TODO */
435 return;
436 }
437
438 drm_gem_object_unreference_unlocked(obj);
439
440 /*
441 * decrease obj->refcount one more time because we has already
442 * increased it at exynos_drm_gem_get_dma_addr().
443 */
444 drm_gem_object_unreference_unlocked(obj);
445}
446
178int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data, 447int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
179 struct drm_file *file_priv) 448 struct drm_file *file_priv)
180{ 449{
@@ -200,7 +469,8 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
200 struct drm_gem_object *obj = filp->private_data; 469 struct drm_gem_object *obj = filp->private_data;
201 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); 470 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
202 struct exynos_drm_gem_buf *buffer; 471 struct exynos_drm_gem_buf *buffer;
203 unsigned long pfn, vm_size; 472 unsigned long pfn, vm_size, usize, uaddr = vma->vm_start;
473 int ret;
204 474
205 DRM_DEBUG_KMS("%s\n", __FILE__); 475 DRM_DEBUG_KMS("%s\n", __FILE__);
206 476
@@ -208,9 +478,9 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
208 478
209 /* in case of direct mapping, always having non-cachable attribute */ 479 /* in case of direct mapping, always having non-cachable attribute */
210 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 480 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
211 vma->vm_file = filp;
212 481
213 vm_size = vma->vm_end - vma->vm_start; 482 vm_size = usize = vma->vm_end - vma->vm_start;
483
214 /* 484 /*
215 * a buffer contains information to physically continuous memory 485 * a buffer contains information to physically continuous memory
216 * allocated by user request or at framebuffer creation. 486 * allocated by user request or at framebuffer creation.
@@ -221,18 +491,37 @@ static int exynos_drm_gem_mmap_buffer(struct file *filp,
221 if (vm_size > buffer->size) 491 if (vm_size > buffer->size)
222 return -EINVAL; 492 return -EINVAL;
223 493
224 /* 494 if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
225 * get page frame number to physical memory to be mapped 495 int i = 0;
226 * to user space. 496
227 */ 497 if (!buffer->pages)
228 pfn = ((unsigned long)exynos_gem_obj->buffer->dma_addr) >> PAGE_SHIFT; 498 return -EINVAL;
229 499
230 DRM_DEBUG_KMS("pfn = 0x%lx\n", pfn); 500 do {
231 501 ret = vm_insert_page(vma, uaddr, buffer->pages[i++]);
232 if (remap_pfn_range(vma, vma->vm_start, pfn, vm_size, 502 if (ret) {
233 vma->vm_page_prot)) { 503 DRM_ERROR("failed to remap user space.\n");
234 DRM_ERROR("failed to remap pfn range.\n"); 504 return ret;
235 return -EAGAIN; 505 }
506
507 uaddr += PAGE_SIZE;
508 usize -= PAGE_SIZE;
509 } while (usize > 0);
510 } else {
511 /*
512 * get page frame number to physical memory to be mapped
513 * to user space.
514 */
515 pfn = ((unsigned long)exynos_gem_obj->buffer->dma_addr) >>
516 PAGE_SHIFT;
517
518 DRM_DEBUG_KMS("pfn = 0x%lx\n", pfn);
519
520 if (remap_pfn_range(vma, vma->vm_start, pfn, vm_size,
521 vma->vm_page_prot)) {
522 DRM_ERROR("failed to remap pfn range.\n");
523 return -EAGAIN;
524 }
236 } 525 }
237 526
238 return 0; 527 return 0;
@@ -312,9 +601,9 @@ int exynos_drm_gem_dumb_create(struct drm_file *file_priv,
312 */ 601 */
313 602
314 args->pitch = args->width * args->bpp >> 3; 603 args->pitch = args->width * args->bpp >> 3;
315 args->size = args->pitch * args->height; 604 args->size = PAGE_ALIGN(args->pitch * args->height);
316 605
317 exynos_gem_obj = exynos_drm_gem_create(dev, args->size); 606 exynos_gem_obj = exynos_drm_gem_create(dev, args->flags, args->size);
318 if (IS_ERR(exynos_gem_obj)) 607 if (IS_ERR(exynos_gem_obj))
319 return PTR_ERR(exynos_gem_obj); 608 return PTR_ERR(exynos_gem_obj);
320 609
@@ -398,20 +687,31 @@ int exynos_drm_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
398 struct drm_gem_object *obj = vma->vm_private_data; 687 struct drm_gem_object *obj = vma->vm_private_data;
399 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj); 688 struct exynos_drm_gem_obj *exynos_gem_obj = to_exynos_gem_obj(obj);
400 struct drm_device *dev = obj->dev; 689 struct drm_device *dev = obj->dev;
401 unsigned long pfn; 690 unsigned long f_vaddr;
402 pgoff_t page_offset; 691 pgoff_t page_offset;
403 int ret; 692 int ret;
404 693
405 page_offset = ((unsigned long)vmf->virtual_address - 694 page_offset = ((unsigned long)vmf->virtual_address -
406 vma->vm_start) >> PAGE_SHIFT; 695 vma->vm_start) >> PAGE_SHIFT;
696 f_vaddr = (unsigned long)vmf->virtual_address;
407 697
408 mutex_lock(&dev->struct_mutex); 698 mutex_lock(&dev->struct_mutex);
409 699
410 pfn = (((unsigned long)exynos_gem_obj->buffer->dma_addr) >> 700 /*
411 PAGE_SHIFT) + page_offset; 701 * allocate all pages as desired size if user wants to allocate
702 * physically non-continuous memory.
703 */
704 if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) {
705 ret = exynos_drm_gem_get_pages(obj);
706 if (ret < 0)
707 goto err;
708 }
412 709
413 ret = vm_insert_mixed(vma, (unsigned long)vmf->virtual_address, pfn); 710 ret = exynos_drm_gem_map_pages(obj, vma, f_vaddr, page_offset);
711 if (ret < 0)
712 DRM_ERROR("failed to map pages.\n");
414 713
714err:
415 mutex_unlock(&dev->struct_mutex); 715 mutex_unlock(&dev->struct_mutex);
416 716
417 return convert_to_vm_err_msg(ret); 717 return convert_to_vm_err_msg(ret);
@@ -435,7 +735,3 @@ int exynos_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
435 735
436 return ret; 736 return ret;
437} 737}
438
439MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
440MODULE_DESCRIPTION("Samsung SoC DRM GEM Module");
441MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h
index 67cdc9168708..e40fbad8b705 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h
@@ -36,11 +36,15 @@
36 * @dma_addr: bus address(accessed by dma) to allocated memory region. 36 * @dma_addr: bus address(accessed by dma) to allocated memory region.
37 * - this address could be physical address without IOMMU and 37 * - this address could be physical address without IOMMU and
38 * device address with IOMMU. 38 * device address with IOMMU.
39 * @sgt: sg table to transfer page data.
40 * @pages: contain all pages to allocated memory region.
39 * @size: size of allocated memory region. 41 * @size: size of allocated memory region.
40 */ 42 */
41struct exynos_drm_gem_buf { 43struct exynos_drm_gem_buf {
42 void __iomem *kvaddr; 44 void __iomem *kvaddr;
43 dma_addr_t dma_addr; 45 dma_addr_t dma_addr;
46 struct sg_table *sgt;
47 struct page **pages;
44 unsigned long size; 48 unsigned long size;
45}; 49};
46 50
@@ -55,6 +59,8 @@ struct exynos_drm_gem_buf {
55 * by user request or at framebuffer creation. 59 * by user request or at framebuffer creation.
56 * continuous memory region allocated by user request 60 * continuous memory region allocated by user request
57 * or at framebuffer creation. 61 * or at framebuffer creation.
62 * @size: total memory size to physically non-continuous memory region.
63 * @flags: indicate memory type to allocated buffer and cache attruibute.
58 * 64 *
59 * P.S. this object would be transfered to user as kms_bo.handle so 65 * P.S. this object would be transfered to user as kms_bo.handle so
60 * user can access the buffer through kms_bo.handle. 66 * user can access the buffer through kms_bo.handle.
@@ -62,6 +68,8 @@ struct exynos_drm_gem_buf {
62struct exynos_drm_gem_obj { 68struct exynos_drm_gem_obj {
63 struct drm_gem_object base; 69 struct drm_gem_object base;
64 struct exynos_drm_gem_buf *buffer; 70 struct exynos_drm_gem_buf *buffer;
71 unsigned long size;
72 unsigned int flags;
65}; 73};
66 74
67/* destroy a buffer with gem object */ 75/* destroy a buffer with gem object */
@@ -69,7 +77,8 @@ void exynos_drm_gem_destroy(struct exynos_drm_gem_obj *exynos_gem_obj);
69 77
70/* create a new buffer with gem object */ 78/* create a new buffer with gem object */
71struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev, 79struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
72 unsigned long size); 80 unsigned int flags,
81 unsigned long size);
73 82
74/* 83/*
75 * request gem object creation and buffer allocation as the size 84 * request gem object creation and buffer allocation as the size
@@ -79,6 +88,24 @@ struct exynos_drm_gem_obj *exynos_drm_gem_create(struct drm_device *dev,
79int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data, 88int exynos_drm_gem_create_ioctl(struct drm_device *dev, void *data,
80 struct drm_file *file_priv); 89 struct drm_file *file_priv);
81 90
91/*
92 * get dma address from gem handle and this function could be used for
93 * other drivers such as 2d/3d acceleration drivers.
94 * with this function call, gem object reference count would be increased.
95 */
96void *exynos_drm_gem_get_dma_addr(struct drm_device *dev,
97 unsigned int gem_handle,
98 struct drm_file *file_priv);
99
100/*
101 * put dma address from gem handle and this function could be used for
102 * other drivers such as 2d/3d acceleration drivers.
103 * with this function call, gem object reference count would be decreased.
104 */
105void exynos_drm_gem_put_dma_addr(struct drm_device *dev,
106 unsigned int gem_handle,
107 struct drm_file *file_priv);
108
82/* get buffer offset to map to user space. */ 109/* get buffer offset to map to user space. */
83int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data, 110int exynos_drm_gem_map_offset_ioctl(struct drm_device *dev, void *data,
84 struct drm_file *file_priv); 111 struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
index ed8a319ed84b..14eb26b0ba1c 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c
@@ -38,7 +38,6 @@ struct drm_hdmi_context {
38 struct exynos_drm_subdrv subdrv; 38 struct exynos_drm_subdrv subdrv;
39 struct exynos_drm_hdmi_context *hdmi_ctx; 39 struct exynos_drm_hdmi_context *hdmi_ctx;
40 struct exynos_drm_hdmi_context *mixer_ctx; 40 struct exynos_drm_hdmi_context *mixer_ctx;
41 struct work_struct work;
42}; 41};
43 42
44void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops 43void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
@@ -49,7 +48,6 @@ void exynos_drm_display_ops_register(struct exynos_hdmi_display_ops
49 if (display_ops) 48 if (display_ops)
50 hdmi_display_ops = display_ops; 49 hdmi_display_ops = display_ops;
51} 50}
52EXPORT_SYMBOL(exynos_drm_display_ops_register);
53 51
54void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops 52void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
55 *manager_ops) 53 *manager_ops)
@@ -59,7 +57,6 @@ void exynos_drm_manager_ops_register(struct exynos_hdmi_manager_ops
59 if (manager_ops) 57 if (manager_ops)
60 hdmi_manager_ops = manager_ops; 58 hdmi_manager_ops = manager_ops;
61} 59}
62EXPORT_SYMBOL(exynos_drm_manager_ops_register);
63 60
64void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops 61void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
65 *overlay_ops) 62 *overlay_ops)
@@ -69,7 +66,6 @@ void exynos_drm_overlay_ops_register(struct exynos_hdmi_overlay_ops
69 if (overlay_ops) 66 if (overlay_ops)
70 hdmi_overlay_ops = overlay_ops; 67 hdmi_overlay_ops = overlay_ops;
71} 68}
72EXPORT_SYMBOL(exynos_drm_overlay_ops_register);
73 69
74static bool drm_hdmi_is_connected(struct device *dev) 70static bool drm_hdmi_is_connected(struct device *dev)
75{ 71{
@@ -155,6 +151,20 @@ static void drm_hdmi_disable_vblank(struct device *subdrv_dev)
155 return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx); 151 return hdmi_overlay_ops->disable_vblank(ctx->mixer_ctx->ctx);
156} 152}
157 153
154static void drm_hdmi_mode_fixup(struct device *subdrv_dev,
155 struct drm_connector *connector,
156 struct drm_display_mode *mode,
157 struct drm_display_mode *adjusted_mode)
158{
159 struct drm_hdmi_context *ctx = to_context(subdrv_dev);
160
161 DRM_DEBUG_KMS("%s\n", __FILE__);
162
163 if (hdmi_manager_ops && hdmi_manager_ops->mode_fixup)
164 hdmi_manager_ops->mode_fixup(ctx->hdmi_ctx->ctx, connector,
165 mode, adjusted_mode);
166}
167
158static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode) 168static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
159{ 169{
160 struct drm_hdmi_context *ctx = to_context(subdrv_dev); 170 struct drm_hdmi_context *ctx = to_context(subdrv_dev);
@@ -165,6 +175,18 @@ static void drm_hdmi_mode_set(struct device *subdrv_dev, void *mode)
165 hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode); 175 hdmi_manager_ops->mode_set(ctx->hdmi_ctx->ctx, mode);
166} 176}
167 177
178static void drm_hdmi_get_max_resol(struct device *subdrv_dev,
179 unsigned int *width, unsigned int *height)
180{
181 struct drm_hdmi_context *ctx = to_context(subdrv_dev);
182
183 DRM_DEBUG_KMS("%s\n", __FILE__);
184
185 if (hdmi_manager_ops && hdmi_manager_ops->get_max_resol)
186 hdmi_manager_ops->get_max_resol(ctx->hdmi_ctx->ctx, width,
187 height);
188}
189
168static void drm_hdmi_commit(struct device *subdrv_dev) 190static void drm_hdmi_commit(struct device *subdrv_dev)
169{ 191{
170 struct drm_hdmi_context *ctx = to_context(subdrv_dev); 192 struct drm_hdmi_context *ctx = to_context(subdrv_dev);
@@ -200,7 +222,9 @@ static struct exynos_drm_manager_ops drm_hdmi_manager_ops = {
200 .dpms = drm_hdmi_dpms, 222 .dpms = drm_hdmi_dpms,
201 .enable_vblank = drm_hdmi_enable_vblank, 223 .enable_vblank = drm_hdmi_enable_vblank,
202 .disable_vblank = drm_hdmi_disable_vblank, 224 .disable_vblank = drm_hdmi_disable_vblank,
225 .mode_fixup = drm_hdmi_mode_fixup,
203 .mode_set = drm_hdmi_mode_set, 226 .mode_set = drm_hdmi_mode_set,
227 .get_max_resol = drm_hdmi_get_max_resol,
204 .commit = drm_hdmi_commit, 228 .commit = drm_hdmi_commit,
205}; 229};
206 230
@@ -249,7 +273,6 @@ static int hdmi_subdrv_probe(struct drm_device *drm_dev,
249 struct drm_hdmi_context *ctx; 273 struct drm_hdmi_context *ctx;
250 struct platform_device *pdev = to_platform_device(dev); 274 struct platform_device *pdev = to_platform_device(dev);
251 struct exynos_drm_common_hdmi_pd *pd; 275 struct exynos_drm_common_hdmi_pd *pd;
252 int ret;
253 276
254 DRM_DEBUG_KMS("%s\n", __FILE__); 277 DRM_DEBUG_KMS("%s\n", __FILE__);
255 278
@@ -270,26 +293,13 @@ static int hdmi_subdrv_probe(struct drm_device *drm_dev,
270 return -EFAULT; 293 return -EFAULT;
271 } 294 }
272 295
273 ret = platform_driver_register(&hdmi_driver);
274 if (ret) {
275 DRM_DEBUG_KMS("failed to register hdmi driver.\n");
276 return ret;
277 }
278
279 ret = platform_driver_register(&mixer_driver);
280 if (ret) {
281 DRM_DEBUG_KMS("failed to register mixer driver.\n");
282 goto err_hdmidrv;
283 }
284
285 ctx = get_ctx_from_subdrv(subdrv); 296 ctx = get_ctx_from_subdrv(subdrv);
286 297
287 ctx->hdmi_ctx = (struct exynos_drm_hdmi_context *) 298 ctx->hdmi_ctx = (struct exynos_drm_hdmi_context *)
288 to_context(pd->hdmi_dev); 299 to_context(pd->hdmi_dev);
289 if (!ctx->hdmi_ctx) { 300 if (!ctx->hdmi_ctx) {
290 DRM_DEBUG_KMS("hdmi context is null.\n"); 301 DRM_DEBUG_KMS("hdmi context is null.\n");
291 ret = -EFAULT; 302 return -EFAULT;
292 goto err_mixerdrv;
293 } 303 }
294 304
295 ctx->hdmi_ctx->drm_dev = drm_dev; 305 ctx->hdmi_ctx->drm_dev = drm_dev;
@@ -298,42 +308,12 @@ static int hdmi_subdrv_probe(struct drm_device *drm_dev,
298 to_context(pd->mixer_dev); 308 to_context(pd->mixer_dev);
299 if (!ctx->mixer_ctx) { 309 if (!ctx->mixer_ctx) {
300 DRM_DEBUG_KMS("mixer context is null.\n"); 310 DRM_DEBUG_KMS("mixer context is null.\n");
301 ret = -EFAULT; 311 return -EFAULT;
302 goto err_mixerdrv;
303 } 312 }
304 313
305 ctx->mixer_ctx->drm_dev = drm_dev; 314 ctx->mixer_ctx->drm_dev = drm_dev;
306 315
307 return 0; 316 return 0;
308
309err_mixerdrv:
310 platform_driver_unregister(&mixer_driver);
311err_hdmidrv:
312 platform_driver_unregister(&hdmi_driver);
313 return ret;
314}
315
316static void hdmi_subdrv_remove(struct drm_device *drm_dev)
317{
318 DRM_DEBUG_KMS("%s\n", __FILE__);
319
320 platform_driver_unregister(&hdmi_driver);
321 platform_driver_unregister(&mixer_driver);
322}
323
324static void exynos_drm_hdmi_late_probe(struct work_struct *work)
325{
326 struct drm_hdmi_context *ctx = container_of(work,
327 struct drm_hdmi_context, work);
328
329 /*
330 * this function calls subdrv->probe() so this must be called
331 * after probe context.
332 *
333 * PS. subdrv->probe() will call platform_driver_register() to probe
334 * hdmi and mixer driver.
335 */
336 exynos_drm_subdrv_register(&ctx->subdrv);
337} 317}
338 318
339static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev) 319static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
@@ -353,7 +333,6 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
353 subdrv = &ctx->subdrv; 333 subdrv = &ctx->subdrv;
354 334
355 subdrv->probe = hdmi_subdrv_probe; 335 subdrv->probe = hdmi_subdrv_probe;
356 subdrv->remove = hdmi_subdrv_remove;
357 subdrv->manager.pipe = -1; 336 subdrv->manager.pipe = -1;
358 subdrv->manager.ops = &drm_hdmi_manager_ops; 337 subdrv->manager.ops = &drm_hdmi_manager_ops;
359 subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops; 338 subdrv->manager.overlay_ops = &drm_hdmi_overlay_ops;
@@ -362,9 +341,7 @@ static int __devinit exynos_drm_hdmi_probe(struct platform_device *pdev)
362 341
363 platform_set_drvdata(pdev, subdrv); 342 platform_set_drvdata(pdev, subdrv);
364 343
365 INIT_WORK(&ctx->work, exynos_drm_hdmi_late_probe); 344 exynos_drm_subdrv_register(subdrv);
366
367 schedule_work(&ctx->work);
368 345
369 return 0; 346 return 0;
370} 347}
@@ -400,7 +377,7 @@ static int __devexit exynos_drm_hdmi_remove(struct platform_device *pdev)
400 return 0; 377 return 0;
401} 378}
402 379
403static struct platform_driver exynos_drm_common_hdmi_driver = { 380struct platform_driver exynos_drm_common_hdmi_driver = {
404 .probe = exynos_drm_hdmi_probe, 381 .probe = exynos_drm_hdmi_probe,
405 .remove = __devexit_p(exynos_drm_hdmi_remove), 382 .remove = __devexit_p(exynos_drm_hdmi_remove),
406 .driver = { 383 .driver = {
@@ -409,31 +386,3 @@ static struct platform_driver exynos_drm_common_hdmi_driver = {
409 .pm = &hdmi_pm_ops, 386 .pm = &hdmi_pm_ops,
410 }, 387 },
411}; 388};
412
413static int __init exynos_drm_hdmi_init(void)
414{
415 int ret;
416
417 DRM_DEBUG_KMS("%s\n", __FILE__);
418
419 ret = platform_driver_register(&exynos_drm_common_hdmi_driver);
420 if (ret) {
421 DRM_DEBUG_KMS("failed to register hdmi common driver.\n");
422 return ret;
423 }
424
425 return ret;
426}
427
428static void __exit exynos_drm_hdmi_exit(void)
429{
430 platform_driver_unregister(&exynos_drm_common_hdmi_driver);
431}
432
433module_init(exynos_drm_hdmi_init);
434module_exit(exynos_drm_hdmi_exit);
435
436MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
437MODULE_AUTHOR("Seung-Woo Kim, <sw0312.kim@samsung.com>");
438MODULE_DESCRIPTION("Samsung SoC DRM HDMI Driver");
439MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
index 3c29f790ee45..44497cfb6c74 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h
@@ -47,7 +47,12 @@ struct exynos_hdmi_display_ops {
47}; 47};
48 48
49struct exynos_hdmi_manager_ops { 49struct exynos_hdmi_manager_ops {
50 void (*mode_fixup)(void *ctx, struct drm_connector *connector,
51 struct drm_display_mode *mode,
52 struct drm_display_mode *adjusted_mode);
50 void (*mode_set)(void *ctx, void *mode); 53 void (*mode_set)(void *ctx, void *mode);
54 void (*get_max_resol)(void *ctx, unsigned int *width,
55 unsigned int *height);
51 void (*commit)(void *ctx); 56 void (*commit)(void *ctx);
52 void (*disable)(void *ctx); 57 void (*disable)(void *ctx);
53}; 58};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
index bdcf770aa22e..c277a3a445f5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_plane.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -22,6 +22,10 @@ struct exynos_plane {
22 bool enabled; 22 bool enabled;
23}; 23};
24 24
25static const uint32_t formats[] = {
26 DRM_FORMAT_XRGB8888,
27};
28
25static int 29static int
26exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, 30exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
27 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 31 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
@@ -115,9 +119,9 @@ int exynos_plane_init(struct drm_device *dev, unsigned int nr)
115 119
116 exynos_plane->overlay.zpos = DEFAULT_ZPOS; 120 exynos_plane->overlay.zpos = DEFAULT_ZPOS;
117 121
118 /* TODO: format */
119 return drm_plane_init(dev, &exynos_plane->base, possible_crtcs, 122 return drm_plane_init(dev, &exynos_plane->base, possible_crtcs,
120 &exynos_plane_funcs, NULL, 0, false); 123 &exynos_plane_funcs, formats, ARRAY_SIZE(formats),
124 false);
121} 125}
122 126
123int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data, 127int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
new file mode 100644
index 000000000000..8e1339f9fe1f
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
@@ -0,0 +1,676 @@
1/* exynos_drm_vidi.c
2 *
3 * Copyright (C) 2012 Samsung Electronics Co.Ltd
4 * Authors:
5 * Inki Dae <inki.dae@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13#include "drmP.h"
14
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/platform_device.h>
18
19#include <drm/exynos_drm.h>
20
21#include "drm_edid.h"
22#include "drm_crtc_helper.h"
23
24#include "exynos_drm_drv.h"
25#include "exynos_drm_crtc.h"
26#include "exynos_drm_encoder.h"
27
28/* vidi has totally three virtual windows. */
29#define WINDOWS_NR 3
30
31#define get_vidi_context(dev) platform_get_drvdata(to_platform_device(dev))
32
33struct vidi_win_data {
34 unsigned int offset_x;
35 unsigned int offset_y;
36 unsigned int ovl_width;
37 unsigned int ovl_height;
38 unsigned int fb_width;
39 unsigned int fb_height;
40 unsigned int bpp;
41 dma_addr_t dma_addr;
42 void __iomem *vaddr;
43 unsigned int buf_offsize;
44 unsigned int line_size; /* bytes */
45 bool enabled;
46};
47
48struct vidi_context {
49 struct exynos_drm_subdrv subdrv;
50 struct drm_crtc *crtc;
51 struct vidi_win_data win_data[WINDOWS_NR];
52 struct edid *raw_edid;
53 unsigned int clkdiv;
54 unsigned int default_win;
55 unsigned long irq_flags;
56 unsigned int connected;
57 bool vblank_on;
58 bool suspended;
59 struct work_struct work;
60 struct mutex lock;
61};
62
63static const char fake_edid_info[] = {
64 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05,
65 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78,
66 0x0a, 0xee, 0x91, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f, 0x50, 0x54, 0xbd,
67 0xee, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
68 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x66, 0x21, 0x50, 0xb0, 0x51, 0x00,
69 0x1b, 0x30, 0x40, 0x70, 0x36, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e,
70 0x01, 0x1d, 0x00, 0x72, 0x51, 0xd0, 0x1e, 0x20, 0x6e, 0x28, 0x55, 0x00,
71 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x18,
72 0x4b, 0x1a, 0x44, 0x17, 0x00, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
73 0x00, 0x00, 0x00, 0xfc, 0x00, 0x53, 0x41, 0x4d, 0x53, 0x55, 0x4e, 0x47,
74 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xbc, 0x02, 0x03, 0x1e, 0xf1,
75 0x46, 0x84, 0x05, 0x03, 0x10, 0x20, 0x22, 0x23, 0x09, 0x07, 0x07, 0x83,
76 0x01, 0x00, 0x00, 0xe2, 0x00, 0x0f, 0x67, 0x03, 0x0c, 0x00, 0x10, 0x00,
77 0xb8, 0x2d, 0x01, 0x1d, 0x80, 0x18, 0x71, 0x1c, 0x16, 0x20, 0x58, 0x2c,
78 0x25, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x9e, 0x8c, 0x0a, 0xd0, 0x8a,
79 0x20, 0xe0, 0x2d, 0x10, 0x10, 0x3e, 0x96, 0x00, 0xa0, 0x5a, 0x00, 0x00,
80 0x00, 0x18, 0x02, 0x3a, 0x80, 0x18, 0x71, 0x38, 0x2d, 0x40, 0x58, 0x2c,
81 0x45, 0x00, 0xa0, 0x5a, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x06
86};
87
88static void vidi_fake_vblank_handler(struct work_struct *work);
89
90static bool vidi_display_is_connected(struct device *dev)
91{
92 struct vidi_context *ctx = get_vidi_context(dev);
93
94 DRM_DEBUG_KMS("%s\n", __FILE__);
95
96 /*
97 * connection request would come from user side
98 * to do hotplug through specific ioctl.
99 */
100 return ctx->connected ? true : false;
101}
102
103static int vidi_get_edid(struct device *dev, struct drm_connector *connector,
104 u8 *edid, int len)
105{
106 struct vidi_context *ctx = get_vidi_context(dev);
107 struct edid *raw_edid;
108
109 DRM_DEBUG_KMS("%s\n", __FILE__);
110
111 /*
112 * the edid data comes from user side and it would be set
113 * to ctx->raw_edid through specific ioctl.
114 */
115 if (!ctx->raw_edid) {
116 DRM_DEBUG_KMS("raw_edid is null.\n");
117 return -EFAULT;
118 }
119
120 raw_edid = kzalloc(len, GFP_KERNEL);
121 if (!raw_edid) {
122 DRM_DEBUG_KMS("failed to allocate raw_edid.\n");
123 return -ENOMEM;
124 }
125
126 memcpy(raw_edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions)
127 * EDID_LENGTH, len));
128
129 /* attach the edid data to connector. */
130 connector->display_info.raw_edid = (char *)raw_edid;
131
132 memcpy(edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions)
133 * EDID_LENGTH, len));
134
135 return 0;
136}
137
138static void *vidi_get_panel(struct device *dev)
139{
140 DRM_DEBUG_KMS("%s\n", __FILE__);
141
142 /* TODO. */
143
144 return NULL;
145}
146
147static int vidi_check_timing(struct device *dev, void *timing)
148{
149 DRM_DEBUG_KMS("%s\n", __FILE__);
150
151 /* TODO. */
152
153 return 0;
154}
155
156static int vidi_display_power_on(struct device *dev, int mode)
157{
158 DRM_DEBUG_KMS("%s\n", __FILE__);
159
160 /* TODO */
161
162 return 0;
163}
164
165static struct exynos_drm_display_ops vidi_display_ops = {
166 .type = EXYNOS_DISPLAY_TYPE_VIDI,
167 .is_connected = vidi_display_is_connected,
168 .get_edid = vidi_get_edid,
169 .get_panel = vidi_get_panel,
170 .check_timing = vidi_check_timing,
171 .power_on = vidi_display_power_on,
172};
173
174static void vidi_dpms(struct device *subdrv_dev, int mode)
175{
176 struct vidi_context *ctx = get_vidi_context(subdrv_dev);
177
178 DRM_DEBUG_KMS("%s, %d\n", __FILE__, mode);
179
180 mutex_lock(&ctx->lock);
181
182 switch (mode) {
183 case DRM_MODE_DPMS_ON:
184 /* TODO. */
185 break;
186 case DRM_MODE_DPMS_STANDBY:
187 case DRM_MODE_DPMS_SUSPEND:
188 case DRM_MODE_DPMS_OFF:
189 /* TODO. */
190 break;
191 default:
192 DRM_DEBUG_KMS("unspecified mode %d\n", mode);
193 break;
194 }
195
196 mutex_unlock(&ctx->lock);
197}
198
199static void vidi_apply(struct device *subdrv_dev)
200{
201 struct vidi_context *ctx = get_vidi_context(subdrv_dev);
202 struct exynos_drm_manager *mgr = &ctx->subdrv.manager;
203 struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
204 struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
205 struct vidi_win_data *win_data;
206 int i;
207
208 DRM_DEBUG_KMS("%s\n", __FILE__);
209
210 for (i = 0; i < WINDOWS_NR; i++) {
211 win_data = &ctx->win_data[i];
212 if (win_data->enabled && (ovl_ops && ovl_ops->commit))
213 ovl_ops->commit(subdrv_dev, i);
214 }
215
216 if (mgr_ops && mgr_ops->commit)
217 mgr_ops->commit(subdrv_dev);
218}
219
220static void vidi_commit(struct device *dev)
221{
222 struct vidi_context *ctx = get_vidi_context(dev);
223
224 DRM_DEBUG_KMS("%s\n", __FILE__);
225
226 if (ctx->suspended)
227 return;
228}
229
230static int vidi_enable_vblank(struct device *dev)
231{
232 struct vidi_context *ctx = get_vidi_context(dev);
233
234 DRM_DEBUG_KMS("%s\n", __FILE__);
235
236 if (ctx->suspended)
237 return -EPERM;
238
239 if (!test_and_set_bit(0, &ctx->irq_flags))
240 ctx->vblank_on = true;
241
242 return 0;
243}
244
245static void vidi_disable_vblank(struct device *dev)
246{
247 struct vidi_context *ctx = get_vidi_context(dev);
248
249 DRM_DEBUG_KMS("%s\n", __FILE__);
250
251 if (ctx->suspended)
252 return;
253
254 if (test_and_clear_bit(0, &ctx->irq_flags))
255 ctx->vblank_on = false;
256}
257
258static struct exynos_drm_manager_ops vidi_manager_ops = {
259 .dpms = vidi_dpms,
260 .apply = vidi_apply,
261 .commit = vidi_commit,
262 .enable_vblank = vidi_enable_vblank,
263 .disable_vblank = vidi_disable_vblank,
264};
265
266static void vidi_win_mode_set(struct device *dev,
267 struct exynos_drm_overlay *overlay)
268{
269 struct vidi_context *ctx = get_vidi_context(dev);
270 struct vidi_win_data *win_data;
271 int win;
272 unsigned long offset;
273
274 DRM_DEBUG_KMS("%s\n", __FILE__);
275
276 if (!overlay) {
277 dev_err(dev, "overlay is NULL\n");
278 return;
279 }
280
281 win = overlay->zpos;
282 if (win == DEFAULT_ZPOS)
283 win = ctx->default_win;
284
285 if (win < 0 || win > WINDOWS_NR)
286 return;
287
288 offset = overlay->fb_x * (overlay->bpp >> 3);
289 offset += overlay->fb_y * overlay->pitch;
290
291 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch);
292
293 win_data = &ctx->win_data[win];
294
295 win_data->offset_x = overlay->crtc_x;
296 win_data->offset_y = overlay->crtc_y;
297 win_data->ovl_width = overlay->crtc_width;
298 win_data->ovl_height = overlay->crtc_height;
299 win_data->fb_width = overlay->fb_width;
300 win_data->fb_height = overlay->fb_height;
301 win_data->dma_addr = overlay->dma_addr[0] + offset;
302 win_data->vaddr = overlay->vaddr[0] + offset;
303 win_data->bpp = overlay->bpp;
304 win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) *
305 (overlay->bpp >> 3);
306 win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3);
307
308 /*
309 * some parts of win_data should be transferred to user side
310 * through specific ioctl.
311 */
312
313 DRM_DEBUG_KMS("offset_x = %d, offset_y = %d\n",
314 win_data->offset_x, win_data->offset_y);
315 DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
316 win_data->ovl_width, win_data->ovl_height);
317 DRM_DEBUG_KMS("paddr = 0x%lx, vaddr = 0x%lx\n",
318 (unsigned long)win_data->dma_addr,
319 (unsigned long)win_data->vaddr);
320 DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
321 overlay->fb_width, overlay->crtc_width);
322}
323
324static void vidi_win_commit(struct device *dev, int zpos)
325{
326 struct vidi_context *ctx = get_vidi_context(dev);
327 struct vidi_win_data *win_data;
328 int win = zpos;
329
330 DRM_DEBUG_KMS("%s\n", __FILE__);
331
332 if (ctx->suspended)
333 return;
334
335 if (win == DEFAULT_ZPOS)
336 win = ctx->default_win;
337
338 if (win < 0 || win > WINDOWS_NR)
339 return;
340
341 win_data = &ctx->win_data[win];
342
343 win_data->enabled = true;
344
345 DRM_DEBUG_KMS("dma_addr = 0x%x\n", win_data->dma_addr);
346
347 if (ctx->vblank_on)
348 schedule_work(&ctx->work);
349}
350
351static void vidi_win_disable(struct device *dev, int zpos)
352{
353 struct vidi_context *ctx = get_vidi_context(dev);
354 struct vidi_win_data *win_data;
355 int win = zpos;
356
357 DRM_DEBUG_KMS("%s\n", __FILE__);
358
359 if (win == DEFAULT_ZPOS)
360 win = ctx->default_win;
361
362 if (win < 0 || win > WINDOWS_NR)
363 return;
364
365 win_data = &ctx->win_data[win];
366 win_data->enabled = false;
367
368 /* TODO. */
369}
370
371static struct exynos_drm_overlay_ops vidi_overlay_ops = {
372 .mode_set = vidi_win_mode_set,
373 .commit = vidi_win_commit,
374 .disable = vidi_win_disable,
375};
376
377static void vidi_finish_pageflip(struct drm_device *drm_dev, int crtc)
378{
379 struct exynos_drm_private *dev_priv = drm_dev->dev_private;
380 struct drm_pending_vblank_event *e, *t;
381 struct timeval now;
382 unsigned long flags;
383 bool is_checked = false;
384
385 spin_lock_irqsave(&drm_dev->event_lock, flags);
386
387 list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
388 base.link) {
389 /* if event's pipe isn't same as crtc then ignore it. */
390 if (crtc != e->pipe)
391 continue;
392
393 is_checked = true;
394
395 do_gettimeofday(&now);
396 e->event.sequence = 0;
397 e->event.tv_sec = now.tv_sec;
398 e->event.tv_usec = now.tv_usec;
399
400 list_move_tail(&e->base.link, &e->base.file_priv->event_list);
401 wake_up_interruptible(&e->base.file_priv->event_wait);
402 }
403
404 if (is_checked) {
405 /*
406 * call drm_vblank_put only in case that drm_vblank_get was
407 * called.
408 */
409 if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0)
410 drm_vblank_put(drm_dev, crtc);
411
412 /*
413 * don't off vblank if vblank_disable_allowed is 1,
414 * because vblank would be off by timer handler.
415 */
416 if (!drm_dev->vblank_disable_allowed)
417 drm_vblank_off(drm_dev, crtc);
418 }
419
420 spin_unlock_irqrestore(&drm_dev->event_lock, flags);
421}
422
423static void vidi_fake_vblank_handler(struct work_struct *work)
424{
425 struct vidi_context *ctx = container_of(work, struct vidi_context,
426 work);
427 struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
428 struct exynos_drm_manager *manager = &subdrv->manager;
429
430 if (manager->pipe < 0)
431 return;
432
433 /* refresh rate is about 50Hz. */
434 usleep_range(16000, 20000);
435
436 drm_handle_vblank(subdrv->drm_dev, manager->pipe);
437 vidi_finish_pageflip(subdrv->drm_dev, manager->pipe);
438}
439
440static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
441{
442 DRM_DEBUG_KMS("%s\n", __FILE__);
443
444 /*
445 * enable drm irq mode.
446 * - with irq_enabled = 1, we can use the vblank feature.
447 *
448 * P.S. note that we wouldn't use drm irq handler but
449 * just specific driver own one instead because
450 * drm framework supports only one irq handler.
451 */
452 drm_dev->irq_enabled = 1;
453
454 /*
455 * with vblank_disable_allowed = 1, vblank interrupt will be disabled
456 * by drm timer once a current process gives up ownership of
457 * vblank event.(after drm_vblank_put function is called)
458 */
459 drm_dev->vblank_disable_allowed = 1;
460
461 return 0;
462}
463
464static void vidi_subdrv_remove(struct drm_device *drm_dev)
465{
466 DRM_DEBUG_KMS("%s\n", __FILE__);
467
468 /* TODO. */
469}
470
471static int vidi_power_on(struct vidi_context *ctx, bool enable)
472{
473 struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
474 struct device *dev = subdrv->manager.dev;
475
476 DRM_DEBUG_KMS("%s\n", __FILE__);
477
478 if (enable != false && enable != true)
479 return -EINVAL;
480
481 if (enable) {
482 ctx->suspended = false;
483
484 /* if vblank was enabled status, enable it again. */
485 if (test_and_clear_bit(0, &ctx->irq_flags))
486 vidi_enable_vblank(dev);
487
488 vidi_apply(dev);
489 } else {
490 ctx->suspended = true;
491 }
492
493 return 0;
494}
495
496static int vidi_show_connection(struct device *dev,
497 struct device_attribute *attr, char *buf)
498{
499 int rc;
500 struct vidi_context *ctx = get_vidi_context(dev);
501
502 mutex_lock(&ctx->lock);
503
504 rc = sprintf(buf, "%d\n", ctx->connected);
505
506 mutex_unlock(&ctx->lock);
507
508 return rc;
509}
510
511static int vidi_store_connection(struct device *dev,
512 struct device_attribute *attr,
513 const char *buf, size_t len)
514{
515 struct vidi_context *ctx = get_vidi_context(dev);
516 int ret;
517
518 DRM_DEBUG_KMS("%s\n", __FILE__);
519
520 ret = kstrtoint(buf, 0, &ctx->connected);
521 if (ret)
522 return ret;
523
524 if (ctx->connected > 1)
525 return -EINVAL;
526
527 DRM_DEBUG_KMS("requested connection.\n");
528
529 drm_helper_hpd_irq_event(ctx->subdrv.drm_dev);
530
531 return len;
532}
533
534static DEVICE_ATTR(connection, 0644, vidi_show_connection,
535 vidi_store_connection);
536
537int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
538 struct drm_file *file_priv)
539{
540 struct vidi_context *ctx = NULL;
541 struct drm_encoder *encoder;
542 struct exynos_drm_manager *manager;
543 struct exynos_drm_display_ops *display_ops;
544 struct drm_exynos_vidi_connection *vidi = data;
545
546 DRM_DEBUG_KMS("%s\n", __FILE__);
547
548 if (!vidi) {
549 DRM_DEBUG_KMS("user data for vidi is null.\n");
550 return -EINVAL;
551 }
552
553 if (!vidi->edid) {
554 DRM_DEBUG_KMS("edid data is null.\n");
555 return -EINVAL;
556 }
557
558 if (vidi->connection > 1) {
559 DRM_DEBUG_KMS("connection should be 0 or 1.\n");
560 return -EINVAL;
561 }
562
563 list_for_each_entry(encoder, &drm_dev->mode_config.encoder_list,
564 head) {
565 manager = exynos_drm_get_manager(encoder);
566 display_ops = manager->display_ops;
567
568 if (display_ops->type == EXYNOS_DISPLAY_TYPE_VIDI) {
569 ctx = get_vidi_context(manager->dev);
570 break;
571 }
572 }
573
574 if (!ctx) {
575 DRM_DEBUG_KMS("not found virtual device type encoder.\n");
576 return -EINVAL;
577 }
578
579 if (ctx->connected == vidi->connection) {
580 DRM_DEBUG_KMS("same connection request.\n");
581 return -EINVAL;
582 }
583
584 if (vidi->connection)
585 ctx->raw_edid = (struct edid *)vidi->edid;
586
587 ctx->connected = vidi->connection;
588 drm_helper_hpd_irq_event(ctx->subdrv.drm_dev);
589
590 return 0;
591}
592
593static int __devinit vidi_probe(struct platform_device *pdev)
594{
595 struct device *dev = &pdev->dev;
596 struct vidi_context *ctx;
597 struct exynos_drm_subdrv *subdrv;
598 int ret;
599
600 DRM_DEBUG_KMS("%s\n", __FILE__);
601
602 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
603 if (!ctx)
604 return -ENOMEM;
605
606 ctx->default_win = 0;
607
608 INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
609
610 /* for test */
611 ctx->raw_edid = (struct edid *)fake_edid_info;
612
613 subdrv = &ctx->subdrv;
614 subdrv->probe = vidi_subdrv_probe;
615 subdrv->remove = vidi_subdrv_remove;
616 subdrv->manager.pipe = -1;
617 subdrv->manager.ops = &vidi_manager_ops;
618 subdrv->manager.overlay_ops = &vidi_overlay_ops;
619 subdrv->manager.display_ops = &vidi_display_ops;
620 subdrv->manager.dev = dev;
621
622 mutex_init(&ctx->lock);
623
624 platform_set_drvdata(pdev, ctx);
625
626 ret = device_create_file(&pdev->dev, &dev_attr_connection);
627 if (ret < 0)
628 DRM_INFO("failed to create connection sysfs.\n");
629
630 exynos_drm_subdrv_register(subdrv);
631
632 return 0;
633}
634
635static int __devexit vidi_remove(struct platform_device *pdev)
636{
637 struct vidi_context *ctx = platform_get_drvdata(pdev);
638
639 DRM_DEBUG_KMS("%s\n", __FILE__);
640
641 exynos_drm_subdrv_unregister(&ctx->subdrv);
642
643 kfree(ctx);
644
645 return 0;
646}
647
648#ifdef CONFIG_PM_SLEEP
649static int vidi_suspend(struct device *dev)
650{
651 struct vidi_context *ctx = get_vidi_context(dev);
652
653 return vidi_power_on(ctx, false);
654}
655
656static int vidi_resume(struct device *dev)
657{
658 struct vidi_context *ctx = get_vidi_context(dev);
659
660 return vidi_power_on(ctx, true);
661}
662#endif
663
664static const struct dev_pm_ops vidi_pm_ops = {
665 SET_SYSTEM_SLEEP_PM_OPS(vidi_suspend, vidi_resume)
666};
667
668struct platform_driver vidi_driver = {
669 .probe = vidi_probe,
670 .remove = __devexit_p(vidi_remove),
671 .driver = {
672 .name = "exynos-drm-vidi",
673 .owner = THIS_MODULE,
674 .pm = &vidi_pm_ops,
675 },
676};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.h b/drivers/gpu/drm/exynos/exynos_drm_vidi.h
new file mode 100644
index 000000000000..a4babe4e65d7
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.h
@@ -0,0 +1,36 @@
1/* exynos_drm_vidi.h
2 *
3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 * Author: Inki Dae <inki.dae@samsung.com>
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef _EXYNOS_DRM_VIDI_H_
27#define _EXYNOS_DRM_VIDI_H_
28
29#ifdef CONFIG_DRM_EXYNOS_VIDI
30int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
31 struct drm_file *file_priv);
32#else
33#define vidi_connection_ioctl NULL
34#endif
35
36#endif
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c
index 3429d3fd93f3..575a8cbd3533 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.c
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.c
@@ -41,44 +41,83 @@
41#include "exynos_hdmi.h" 41#include "exynos_hdmi.h"
42 42
43#define HDMI_OVERLAY_NUMBER 3 43#define HDMI_OVERLAY_NUMBER 3
44#define MAX_WIDTH 1920
45#define MAX_HEIGHT 1080
44#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev)) 46#define get_hdmi_context(dev) platform_get_drvdata(to_platform_device(dev))
45 47
46static const u8 hdmiphy_conf27[32] = { 48struct hdmi_resources {
49 struct clk *hdmi;
50 struct clk *sclk_hdmi;
51 struct clk *sclk_pixel;
52 struct clk *sclk_hdmiphy;
53 struct clk *hdmiphy;
54 struct regulator_bulk_data *regul_bulk;
55 int regul_count;
56};
57
58struct hdmi_context {
59 struct device *dev;
60 struct drm_device *drm_dev;
61 struct fb_videomode *default_timing;
62 unsigned int is_v13:1;
63 unsigned int default_win;
64 unsigned int default_bpp;
65 bool hpd_handle;
66 bool enabled;
67
68 struct resource *regs_res;
69 void __iomem *regs;
70 unsigned int irq;
71 struct workqueue_struct *wq;
72 struct work_struct hotplug_work;
73
74 struct i2c_client *ddc_port;
75 struct i2c_client *hdmiphy_port;
76
77 /* current hdmiphy conf index */
78 int cur_conf;
79
80 struct hdmi_resources res;
81 void *parent_ctx;
82};
83
84/* HDMI Version 1.3 */
85static const u8 hdmiphy_v13_conf27[32] = {
47 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40, 86 0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
48 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, 87 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
49 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, 88 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
50 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, 89 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
51}; 90};
52 91
53static const u8 hdmiphy_conf27_027[32] = { 92static const u8 hdmiphy_v13_conf27_027[32] = {
54 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64, 93 0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
55 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87, 94 0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
56 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, 95 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
57 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00, 96 0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x00,
58}; 97};
59 98
60static const u8 hdmiphy_conf74_175[32] = { 99static const u8 hdmiphy_v13_conf74_175[32] = {
61 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B, 100 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
62 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9, 101 0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
63 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0, 102 0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
64 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00, 103 0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
65}; 104};
66 105
67static const u8 hdmiphy_conf74_25[32] = { 106static const u8 hdmiphy_v13_conf74_25[32] = {
68 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40, 107 0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
69 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba, 108 0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
70 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0, 109 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xe0,
71 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00, 110 0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
72}; 111};
73 112
74static const u8 hdmiphy_conf148_5[32] = { 113static const u8 hdmiphy_v13_conf148_5[32] = {
75 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40, 114 0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
76 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba, 115 0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
77 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0, 116 0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
78 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00, 117 0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
79}; 118};
80 119
81struct hdmi_tg_regs { 120struct hdmi_v13_tg_regs {
82 u8 cmd; 121 u8 cmd;
83 u8 h_fsz_l; 122 u8 h_fsz_l;
84 u8 h_fsz_h; 123 u8 h_fsz_h;
@@ -110,7 +149,7 @@ struct hdmi_tg_regs {
110 u8 field_bot_hdmi_h; 149 u8 field_bot_hdmi_h;
111}; 150};
112 151
113struct hdmi_core_regs { 152struct hdmi_v13_core_regs {
114 u8 h_blank[2]; 153 u8 h_blank[2];
115 u8 v_blank[3]; 154 u8 v_blank[3];
116 u8 h_v_line[3]; 155 u8 h_v_line[3];
@@ -123,12 +162,21 @@ struct hdmi_core_regs {
123 u8 v_sync_gen3[3]; 162 u8 v_sync_gen3[3];
124}; 163};
125 164
126struct hdmi_preset_conf { 165struct hdmi_v13_preset_conf {
127 struct hdmi_core_regs core; 166 struct hdmi_v13_core_regs core;
128 struct hdmi_tg_regs tg; 167 struct hdmi_v13_tg_regs tg;
129}; 168};
130 169
131static const struct hdmi_preset_conf hdmi_conf_480p = { 170struct hdmi_v13_conf {
171 int width;
172 int height;
173 int vrefresh;
174 bool interlace;
175 const u8 *hdmiphy_data;
176 const struct hdmi_v13_preset_conf *conf;
177};
178
179static const struct hdmi_v13_preset_conf hdmi_v13_conf_480p = {
132 .core = { 180 .core = {
133 .h_blank = {0x8a, 0x00}, 181 .h_blank = {0x8a, 0x00},
134 .v_blank = {0x0d, 0x6a, 0x01}, 182 .v_blank = {0x0d, 0x6a, 0x01},
@@ -154,7 +202,7 @@ static const struct hdmi_preset_conf hdmi_conf_480p = {
154 }, 202 },
155}; 203};
156 204
157static const struct hdmi_preset_conf hdmi_conf_720p60 = { 205static const struct hdmi_v13_preset_conf hdmi_v13_conf_720p60 = {
158 .core = { 206 .core = {
159 .h_blank = {0x72, 0x01}, 207 .h_blank = {0x72, 0x01},
160 .v_blank = {0xee, 0xf2, 0x00}, 208 .v_blank = {0xee, 0xf2, 0x00},
@@ -182,7 +230,7 @@ static const struct hdmi_preset_conf hdmi_conf_720p60 = {
182 }, 230 },
183}; 231};
184 232
185static const struct hdmi_preset_conf hdmi_conf_1080i50 = { 233static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i50 = {
186 .core = { 234 .core = {
187 .h_blank = {0xd0, 0x02}, 235 .h_blank = {0xd0, 0x02},
188 .v_blank = {0x32, 0xB2, 0x00}, 236 .v_blank = {0x32, 0xB2, 0x00},
@@ -210,7 +258,7 @@ static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
210 }, 258 },
211}; 259};
212 260
213static const struct hdmi_preset_conf hdmi_conf_1080p50 = { 261static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p50 = {
214 .core = { 262 .core = {
215 .h_blank = {0xd0, 0x02}, 263 .h_blank = {0xd0, 0x02},
216 .v_blank = {0x65, 0x6c, 0x01}, 264 .v_blank = {0x65, 0x6c, 0x01},
@@ -238,7 +286,7 @@ static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
238 }, 286 },
239}; 287};
240 288
241static const struct hdmi_preset_conf hdmi_conf_1080i60 = { 289static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080i60 = {
242 .core = { 290 .core = {
243 .h_blank = {0x18, 0x01}, 291 .h_blank = {0x18, 0x01},
244 .v_blank = {0x32, 0xB2, 0x00}, 292 .v_blank = {0x32, 0xB2, 0x00},
@@ -266,7 +314,7 @@ static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
266 }, 314 },
267}; 315};
268 316
269static const struct hdmi_preset_conf hdmi_conf_1080p60 = { 317static const struct hdmi_v13_preset_conf hdmi_v13_conf_1080p60 = {
270 .core = { 318 .core = {
271 .h_blank = {0x18, 0x01}, 319 .h_blank = {0x18, 0x01},
272 .v_blank = {0x65, 0x6c, 0x01}, 320 .v_blank = {0x65, 0x6c, 0x01},
@@ -294,13 +342,530 @@ static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
294 }, 342 },
295}; 343};
296 344
345static const struct hdmi_v13_conf hdmi_v13_confs[] = {
346 { 1280, 720, 60, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
347 { 1280, 720, 50, false, hdmiphy_v13_conf74_25, &hdmi_v13_conf_720p60 },
348 { 720, 480, 60, false, hdmiphy_v13_conf27_027, &hdmi_v13_conf_480p },
349 { 1920, 1080, 50, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i50 },
350 { 1920, 1080, 50, false, hdmiphy_v13_conf148_5,
351 &hdmi_v13_conf_1080p50 },
352 { 1920, 1080, 60, true, hdmiphy_v13_conf74_25, &hdmi_v13_conf_1080i60 },
353 { 1920, 1080, 60, false, hdmiphy_v13_conf148_5,
354 &hdmi_v13_conf_1080p60 },
355};
356
357/* HDMI Version 1.4 */
358static const u8 hdmiphy_conf27_027[32] = {
359 0x01, 0xd1, 0x2d, 0x72, 0x40, 0x64, 0x12, 0x08,
360 0x43, 0xa0, 0x0e, 0xd9, 0x45, 0xa0, 0xac, 0x80,
361 0x08, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
362 0x54, 0xe3, 0x24, 0x00, 0x00, 0x00, 0x01, 0x00,
363};
364
365static const u8 hdmiphy_conf74_25[32] = {
366 0x01, 0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0x08,
367 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
368 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
369 0x54, 0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x00,
370};
371
372static const u8 hdmiphy_conf148_5[32] = {
373 0x01, 0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0x08,
374 0x81, 0xa0, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80,
375 0x3c, 0x80, 0x11, 0x04, 0x02, 0x22, 0x44, 0x86,
376 0x54, 0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x00,
377};
378
379struct hdmi_tg_regs {
380 u8 cmd;
381 u8 h_fsz_l;
382 u8 h_fsz_h;
383 u8 hact_st_l;
384 u8 hact_st_h;
385 u8 hact_sz_l;
386 u8 hact_sz_h;
387 u8 v_fsz_l;
388 u8 v_fsz_h;
389 u8 vsync_l;
390 u8 vsync_h;
391 u8 vsync2_l;
392 u8 vsync2_h;
393 u8 vact_st_l;
394 u8 vact_st_h;
395 u8 vact_sz_l;
396 u8 vact_sz_h;
397 u8 field_chg_l;
398 u8 field_chg_h;
399 u8 vact_st2_l;
400 u8 vact_st2_h;
401 u8 vact_st3_l;
402 u8 vact_st3_h;
403 u8 vact_st4_l;
404 u8 vact_st4_h;
405 u8 vsync_top_hdmi_l;
406 u8 vsync_top_hdmi_h;
407 u8 vsync_bot_hdmi_l;
408 u8 vsync_bot_hdmi_h;
409 u8 field_top_hdmi_l;
410 u8 field_top_hdmi_h;
411 u8 field_bot_hdmi_l;
412 u8 field_bot_hdmi_h;
413 u8 tg_3d;
414};
415
416struct hdmi_core_regs {
417 u8 h_blank[2];
418 u8 v2_blank[2];
419 u8 v1_blank[2];
420 u8 v_line[2];
421 u8 h_line[2];
422 u8 hsync_pol[1];
423 u8 vsync_pol[1];
424 u8 int_pro_mode[1];
425 u8 v_blank_f0[2];
426 u8 v_blank_f1[2];
427 u8 h_sync_start[2];
428 u8 h_sync_end[2];
429 u8 v_sync_line_bef_2[2];
430 u8 v_sync_line_bef_1[2];
431 u8 v_sync_line_aft_2[2];
432 u8 v_sync_line_aft_1[2];
433 u8 v_sync_line_aft_pxl_2[2];
434 u8 v_sync_line_aft_pxl_1[2];
435 u8 v_blank_f2[2]; /* for 3D mode */
436 u8 v_blank_f3[2]; /* for 3D mode */
437 u8 v_blank_f4[2]; /* for 3D mode */
438 u8 v_blank_f5[2]; /* for 3D mode */
439 u8 v_sync_line_aft_3[2];
440 u8 v_sync_line_aft_4[2];
441 u8 v_sync_line_aft_5[2];
442 u8 v_sync_line_aft_6[2];
443 u8 v_sync_line_aft_pxl_3[2];
444 u8 v_sync_line_aft_pxl_4[2];
445 u8 v_sync_line_aft_pxl_5[2];
446 u8 v_sync_line_aft_pxl_6[2];
447 u8 vact_space_1[2];
448 u8 vact_space_2[2];
449 u8 vact_space_3[2];
450 u8 vact_space_4[2];
451 u8 vact_space_5[2];
452 u8 vact_space_6[2];
453};
454
455struct hdmi_preset_conf {
456 struct hdmi_core_regs core;
457 struct hdmi_tg_regs tg;
458};
459
460struct hdmi_conf {
461 int width;
462 int height;
463 int vrefresh;
464 bool interlace;
465 const u8 *hdmiphy_data;
466 const struct hdmi_preset_conf *conf;
467};
468
469static const struct hdmi_preset_conf hdmi_conf_480p60 = {
470 .core = {
471 .h_blank = {0x8a, 0x00},
472 .v2_blank = {0x0d, 0x02},
473 .v1_blank = {0x2d, 0x00},
474 .v_line = {0x0d, 0x02},
475 .h_line = {0x5a, 0x03},
476 .hsync_pol = {0x01},
477 .vsync_pol = {0x01},
478 .int_pro_mode = {0x00},
479 .v_blank_f0 = {0xff, 0xff},
480 .v_blank_f1 = {0xff, 0xff},
481 .h_sync_start = {0x0e, 0x00},
482 .h_sync_end = {0x4c, 0x00},
483 .v_sync_line_bef_2 = {0x0f, 0x00},
484 .v_sync_line_bef_1 = {0x09, 0x00},
485 .v_sync_line_aft_2 = {0xff, 0xff},
486 .v_sync_line_aft_1 = {0xff, 0xff},
487 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
488 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
489 .v_blank_f2 = {0xff, 0xff},
490 .v_blank_f3 = {0xff, 0xff},
491 .v_blank_f4 = {0xff, 0xff},
492 .v_blank_f5 = {0xff, 0xff},
493 .v_sync_line_aft_3 = {0xff, 0xff},
494 .v_sync_line_aft_4 = {0xff, 0xff},
495 .v_sync_line_aft_5 = {0xff, 0xff},
496 .v_sync_line_aft_6 = {0xff, 0xff},
497 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
498 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
499 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
500 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
501 .vact_space_1 = {0xff, 0xff},
502 .vact_space_2 = {0xff, 0xff},
503 .vact_space_3 = {0xff, 0xff},
504 .vact_space_4 = {0xff, 0xff},
505 .vact_space_5 = {0xff, 0xff},
506 .vact_space_6 = {0xff, 0xff},
507 /* other don't care */
508 },
509 .tg = {
510 0x00, /* cmd */
511 0x5a, 0x03, /* h_fsz */
512 0x8a, 0x00, 0xd0, 0x02, /* hact */
513 0x0d, 0x02, /* v_fsz */
514 0x01, 0x00, 0x33, 0x02, /* vsync */
515 0x2d, 0x00, 0xe0, 0x01, /* vact */
516 0x33, 0x02, /* field_chg */
517 0x48, 0x02, /* vact_st2 */
518 0x00, 0x00, /* vact_st3 */
519 0x00, 0x00, /* vact_st4 */
520 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
521 0x01, 0x00, 0x33, 0x02, /* field top/bot */
522 0x00, /* 3d FP */
523 },
524};
525
526static const struct hdmi_preset_conf hdmi_conf_720p50 = {
527 .core = {
528 .h_blank = {0xbc, 0x02},
529 .v2_blank = {0xee, 0x02},
530 .v1_blank = {0x1e, 0x00},
531 .v_line = {0xee, 0x02},
532 .h_line = {0xbc, 0x07},
533 .hsync_pol = {0x00},
534 .vsync_pol = {0x00},
535 .int_pro_mode = {0x00},
536 .v_blank_f0 = {0xff, 0xff},
537 .v_blank_f1 = {0xff, 0xff},
538 .h_sync_start = {0xb6, 0x01},
539 .h_sync_end = {0xde, 0x01},
540 .v_sync_line_bef_2 = {0x0a, 0x00},
541 .v_sync_line_bef_1 = {0x05, 0x00},
542 .v_sync_line_aft_2 = {0xff, 0xff},
543 .v_sync_line_aft_1 = {0xff, 0xff},
544 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
545 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
546 .v_blank_f2 = {0xff, 0xff},
547 .v_blank_f3 = {0xff, 0xff},
548 .v_blank_f4 = {0xff, 0xff},
549 .v_blank_f5 = {0xff, 0xff},
550 .v_sync_line_aft_3 = {0xff, 0xff},
551 .v_sync_line_aft_4 = {0xff, 0xff},
552 .v_sync_line_aft_5 = {0xff, 0xff},
553 .v_sync_line_aft_6 = {0xff, 0xff},
554 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
555 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
556 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
557 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
558 .vact_space_1 = {0xff, 0xff},
559 .vact_space_2 = {0xff, 0xff},
560 .vact_space_3 = {0xff, 0xff},
561 .vact_space_4 = {0xff, 0xff},
562 .vact_space_5 = {0xff, 0xff},
563 .vact_space_6 = {0xff, 0xff},
564 /* other don't care */
565 },
566 .tg = {
567 0x00, /* cmd */
568 0xbc, 0x07, /* h_fsz */
569 0xbc, 0x02, 0x00, 0x05, /* hact */
570 0xee, 0x02, /* v_fsz */
571 0x01, 0x00, 0x33, 0x02, /* vsync */
572 0x1e, 0x00, 0xd0, 0x02, /* vact */
573 0x33, 0x02, /* field_chg */
574 0x48, 0x02, /* vact_st2 */
575 0x00, 0x00, /* vact_st3 */
576 0x00, 0x00, /* vact_st4 */
577 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
578 0x01, 0x00, 0x33, 0x02, /* field top/bot */
579 0x00, /* 3d FP */
580 },
581};
582
583static const struct hdmi_preset_conf hdmi_conf_720p60 = {
584 .core = {
585 .h_blank = {0x72, 0x01},
586 .v2_blank = {0xee, 0x02},
587 .v1_blank = {0x1e, 0x00},
588 .v_line = {0xee, 0x02},
589 .h_line = {0x72, 0x06},
590 .hsync_pol = {0x00},
591 .vsync_pol = {0x00},
592 .int_pro_mode = {0x00},
593 .v_blank_f0 = {0xff, 0xff},
594 .v_blank_f1 = {0xff, 0xff},
595 .h_sync_start = {0x6c, 0x00},
596 .h_sync_end = {0x94, 0x00},
597 .v_sync_line_bef_2 = {0x0a, 0x00},
598 .v_sync_line_bef_1 = {0x05, 0x00},
599 .v_sync_line_aft_2 = {0xff, 0xff},
600 .v_sync_line_aft_1 = {0xff, 0xff},
601 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
602 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
603 .v_blank_f2 = {0xff, 0xff},
604 .v_blank_f3 = {0xff, 0xff},
605 .v_blank_f4 = {0xff, 0xff},
606 .v_blank_f5 = {0xff, 0xff},
607 .v_sync_line_aft_3 = {0xff, 0xff},
608 .v_sync_line_aft_4 = {0xff, 0xff},
609 .v_sync_line_aft_5 = {0xff, 0xff},
610 .v_sync_line_aft_6 = {0xff, 0xff},
611 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
612 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
613 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
614 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
615 .vact_space_1 = {0xff, 0xff},
616 .vact_space_2 = {0xff, 0xff},
617 .vact_space_3 = {0xff, 0xff},
618 .vact_space_4 = {0xff, 0xff},
619 .vact_space_5 = {0xff, 0xff},
620 .vact_space_6 = {0xff, 0xff},
621 /* other don't care */
622 },
623 .tg = {
624 0x00, /* cmd */
625 0x72, 0x06, /* h_fsz */
626 0x72, 0x01, 0x00, 0x05, /* hact */
627 0xee, 0x02, /* v_fsz */
628 0x01, 0x00, 0x33, 0x02, /* vsync */
629 0x1e, 0x00, 0xd0, 0x02, /* vact */
630 0x33, 0x02, /* field_chg */
631 0x48, 0x02, /* vact_st2 */
632 0x00, 0x00, /* vact_st3 */
633 0x00, 0x00, /* vact_st4 */
634 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
635 0x01, 0x00, 0x33, 0x02, /* field top/bot */
636 0x00, /* 3d FP */
637 },
638};
639
640static const struct hdmi_preset_conf hdmi_conf_1080i50 = {
641 .core = {
642 .h_blank = {0xd0, 0x02},
643 .v2_blank = {0x32, 0x02},
644 .v1_blank = {0x16, 0x00},
645 .v_line = {0x65, 0x04},
646 .h_line = {0x50, 0x0a},
647 .hsync_pol = {0x00},
648 .vsync_pol = {0x00},
649 .int_pro_mode = {0x01},
650 .v_blank_f0 = {0x49, 0x02},
651 .v_blank_f1 = {0x65, 0x04},
652 .h_sync_start = {0x0e, 0x02},
653 .h_sync_end = {0x3a, 0x02},
654 .v_sync_line_bef_2 = {0x07, 0x00},
655 .v_sync_line_bef_1 = {0x02, 0x00},
656 .v_sync_line_aft_2 = {0x39, 0x02},
657 .v_sync_line_aft_1 = {0x34, 0x02},
658 .v_sync_line_aft_pxl_2 = {0x38, 0x07},
659 .v_sync_line_aft_pxl_1 = {0x38, 0x07},
660 .v_blank_f2 = {0xff, 0xff},
661 .v_blank_f3 = {0xff, 0xff},
662 .v_blank_f4 = {0xff, 0xff},
663 .v_blank_f5 = {0xff, 0xff},
664 .v_sync_line_aft_3 = {0xff, 0xff},
665 .v_sync_line_aft_4 = {0xff, 0xff},
666 .v_sync_line_aft_5 = {0xff, 0xff},
667 .v_sync_line_aft_6 = {0xff, 0xff},
668 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
669 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
670 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
671 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
672 .vact_space_1 = {0xff, 0xff},
673 .vact_space_2 = {0xff, 0xff},
674 .vact_space_3 = {0xff, 0xff},
675 .vact_space_4 = {0xff, 0xff},
676 .vact_space_5 = {0xff, 0xff},
677 .vact_space_6 = {0xff, 0xff},
678 /* other don't care */
679 },
680 .tg = {
681 0x00, /* cmd */
682 0x50, 0x0a, /* h_fsz */
683 0xd0, 0x02, 0x80, 0x07, /* hact */
684 0x65, 0x04, /* v_fsz */
685 0x01, 0x00, 0x33, 0x02, /* vsync */
686 0x16, 0x00, 0x1c, 0x02, /* vact */
687 0x33, 0x02, /* field_chg */
688 0x49, 0x02, /* vact_st2 */
689 0x00, 0x00, /* vact_st3 */
690 0x00, 0x00, /* vact_st4 */
691 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
692 0x01, 0x00, 0x33, 0x02, /* field top/bot */
693 0x00, /* 3d FP */
694 },
695};
696
697static const struct hdmi_preset_conf hdmi_conf_1080i60 = {
698 .core = {
699 .h_blank = {0x18, 0x01},
700 .v2_blank = {0x32, 0x02},
701 .v1_blank = {0x16, 0x00},
702 .v_line = {0x65, 0x04},
703 .h_line = {0x98, 0x08},
704 .hsync_pol = {0x00},
705 .vsync_pol = {0x00},
706 .int_pro_mode = {0x01},
707 .v_blank_f0 = {0x49, 0x02},
708 .v_blank_f1 = {0x65, 0x04},
709 .h_sync_start = {0x56, 0x00},
710 .h_sync_end = {0x82, 0x00},
711 .v_sync_line_bef_2 = {0x07, 0x00},
712 .v_sync_line_bef_1 = {0x02, 0x00},
713 .v_sync_line_aft_2 = {0x39, 0x02},
714 .v_sync_line_aft_1 = {0x34, 0x02},
715 .v_sync_line_aft_pxl_2 = {0xa4, 0x04},
716 .v_sync_line_aft_pxl_1 = {0xa4, 0x04},
717 .v_blank_f2 = {0xff, 0xff},
718 .v_blank_f3 = {0xff, 0xff},
719 .v_blank_f4 = {0xff, 0xff},
720 .v_blank_f5 = {0xff, 0xff},
721 .v_sync_line_aft_3 = {0xff, 0xff},
722 .v_sync_line_aft_4 = {0xff, 0xff},
723 .v_sync_line_aft_5 = {0xff, 0xff},
724 .v_sync_line_aft_6 = {0xff, 0xff},
725 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
726 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
727 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
728 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
729 .vact_space_1 = {0xff, 0xff},
730 .vact_space_2 = {0xff, 0xff},
731 .vact_space_3 = {0xff, 0xff},
732 .vact_space_4 = {0xff, 0xff},
733 .vact_space_5 = {0xff, 0xff},
734 .vact_space_6 = {0xff, 0xff},
735 /* other don't care */
736 },
737 .tg = {
738 0x00, /* cmd */
739 0x98, 0x08, /* h_fsz */
740 0x18, 0x01, 0x80, 0x07, /* hact */
741 0x65, 0x04, /* v_fsz */
742 0x01, 0x00, 0x33, 0x02, /* vsync */
743 0x16, 0x00, 0x1c, 0x02, /* vact */
744 0x33, 0x02, /* field_chg */
745 0x49, 0x02, /* vact_st2 */
746 0x00, 0x00, /* vact_st3 */
747 0x00, 0x00, /* vact_st4 */
748 0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
749 0x01, 0x00, 0x33, 0x02, /* field top/bot */
750 0x00, /* 3d FP */
751 },
752};
753
754static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
755 .core = {
756 .h_blank = {0xd0, 0x02},
757 .v2_blank = {0x65, 0x04},
758 .v1_blank = {0x2d, 0x00},
759 .v_line = {0x65, 0x04},
760 .h_line = {0x50, 0x0a},
761 .hsync_pol = {0x00},
762 .vsync_pol = {0x00},
763 .int_pro_mode = {0x00},
764 .v_blank_f0 = {0xff, 0xff},
765 .v_blank_f1 = {0xff, 0xff},
766 .h_sync_start = {0x0e, 0x02},
767 .h_sync_end = {0x3a, 0x02},
768 .v_sync_line_bef_2 = {0x09, 0x00},
769 .v_sync_line_bef_1 = {0x04, 0x00},
770 .v_sync_line_aft_2 = {0xff, 0xff},
771 .v_sync_line_aft_1 = {0xff, 0xff},
772 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
773 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
774 .v_blank_f2 = {0xff, 0xff},
775 .v_blank_f3 = {0xff, 0xff},
776 .v_blank_f4 = {0xff, 0xff},
777 .v_blank_f5 = {0xff, 0xff},
778 .v_sync_line_aft_3 = {0xff, 0xff},
779 .v_sync_line_aft_4 = {0xff, 0xff},
780 .v_sync_line_aft_5 = {0xff, 0xff},
781 .v_sync_line_aft_6 = {0xff, 0xff},
782 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
783 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
784 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
785 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
786 .vact_space_1 = {0xff, 0xff},
787 .vact_space_2 = {0xff, 0xff},
788 .vact_space_3 = {0xff, 0xff},
789 .vact_space_4 = {0xff, 0xff},
790 .vact_space_5 = {0xff, 0xff},
791 .vact_space_6 = {0xff, 0xff},
792 /* other don't care */
793 },
794 .tg = {
795 0x00, /* cmd */
796 0x50, 0x0a, /* h_fsz */
797 0xd0, 0x02, 0x80, 0x07, /* hact */
798 0x65, 0x04, /* v_fsz */
799 0x01, 0x00, 0x33, 0x02, /* vsync */
800 0x2d, 0x00, 0x38, 0x04, /* vact */
801 0x33, 0x02, /* field_chg */
802 0x48, 0x02, /* vact_st2 */
803 0x00, 0x00, /* vact_st3 */
804 0x00, 0x00, /* vact_st4 */
805 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
806 0x01, 0x00, 0x33, 0x02, /* field top/bot */
807 0x00, /* 3d FP */
808 },
809};
810
811static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
812 .core = {
813 .h_blank = {0x18, 0x01},
814 .v2_blank = {0x65, 0x04},
815 .v1_blank = {0x2d, 0x00},
816 .v_line = {0x65, 0x04},
817 .h_line = {0x98, 0x08},
818 .hsync_pol = {0x00},
819 .vsync_pol = {0x00},
820 .int_pro_mode = {0x00},
821 .v_blank_f0 = {0xff, 0xff},
822 .v_blank_f1 = {0xff, 0xff},
823 .h_sync_start = {0x56, 0x00},
824 .h_sync_end = {0x82, 0x00},
825 .v_sync_line_bef_2 = {0x09, 0x00},
826 .v_sync_line_bef_1 = {0x04, 0x00},
827 .v_sync_line_aft_2 = {0xff, 0xff},
828 .v_sync_line_aft_1 = {0xff, 0xff},
829 .v_sync_line_aft_pxl_2 = {0xff, 0xff},
830 .v_sync_line_aft_pxl_1 = {0xff, 0xff},
831 .v_blank_f2 = {0xff, 0xff},
832 .v_blank_f3 = {0xff, 0xff},
833 .v_blank_f4 = {0xff, 0xff},
834 .v_blank_f5 = {0xff, 0xff},
835 .v_sync_line_aft_3 = {0xff, 0xff},
836 .v_sync_line_aft_4 = {0xff, 0xff},
837 .v_sync_line_aft_5 = {0xff, 0xff},
838 .v_sync_line_aft_6 = {0xff, 0xff},
839 .v_sync_line_aft_pxl_3 = {0xff, 0xff},
840 .v_sync_line_aft_pxl_4 = {0xff, 0xff},
841 .v_sync_line_aft_pxl_5 = {0xff, 0xff},
842 .v_sync_line_aft_pxl_6 = {0xff, 0xff},
843 /* other don't care */
844 },
845 .tg = {
846 0x00, /* cmd */
847 0x98, 0x08, /* h_fsz */
848 0x18, 0x01, 0x80, 0x07, /* hact */
849 0x65, 0x04, /* v_fsz */
850 0x01, 0x00, 0x33, 0x02, /* vsync */
851 0x2d, 0x00, 0x38, 0x04, /* vact */
852 0x33, 0x02, /* field_chg */
853 0x48, 0x02, /* vact_st2 */
854 0x00, 0x00, /* vact_st3 */
855 0x00, 0x00, /* vact_st4 */
856 0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
857 0x01, 0x00, 0x33, 0x02, /* field top/bot */
858 0x00, /* 3d FP */
859 },
860};
861
297static const struct hdmi_conf hdmi_confs[] = { 862static const struct hdmi_conf hdmi_confs[] = {
863 { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p60 },
864 { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p50 },
298 { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 }, 865 { 1280, 720, 60, false, hdmiphy_conf74_25, &hdmi_conf_720p60 },
299 { 1280, 720, 50, false, hdmiphy_conf74_25, &hdmi_conf_720p60 },
300 { 720, 480, 60, false, hdmiphy_conf27_027, &hdmi_conf_480p },
301 { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 }, 866 { 1920, 1080, 50, true, hdmiphy_conf74_25, &hdmi_conf_1080i50 },
302 { 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
303 { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 }, 867 { 1920, 1080, 60, true, hdmiphy_conf74_25, &hdmi_conf_1080i60 },
868 { 1920, 1080, 50, false, hdmiphy_conf148_5, &hdmi_conf_1080p50 },
304 { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 }, 869 { 1920, 1080, 60, false, hdmiphy_conf148_5, &hdmi_conf_1080p60 },
305}; 870};
306 871
@@ -324,7 +889,7 @@ static inline void hdmi_reg_writemask(struct hdmi_context *hdata,
324 writel(value, hdata->regs + reg_id); 889 writel(value, hdata->regs + reg_id);
325} 890}
326 891
327static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix) 892static void hdmi_v13_regs_dump(struct hdmi_context *hdata, char *prefix)
328{ 893{
329#define DUMPREG(reg_id) \ 894#define DUMPREG(reg_id) \
330 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \ 895 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
@@ -333,6 +898,101 @@ static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
333 DUMPREG(HDMI_INTC_FLAG); 898 DUMPREG(HDMI_INTC_FLAG);
334 DUMPREG(HDMI_INTC_CON); 899 DUMPREG(HDMI_INTC_CON);
335 DUMPREG(HDMI_HPD_STATUS); 900 DUMPREG(HDMI_HPD_STATUS);
901 DUMPREG(HDMI_V13_PHY_RSTOUT);
902 DUMPREG(HDMI_V13_PHY_VPLL);
903 DUMPREG(HDMI_V13_PHY_CMU);
904 DUMPREG(HDMI_V13_CORE_RSTOUT);
905
906 DRM_DEBUG_KMS("%s: ---- CORE REGISTERS ----\n", prefix);
907 DUMPREG(HDMI_CON_0);
908 DUMPREG(HDMI_CON_1);
909 DUMPREG(HDMI_CON_2);
910 DUMPREG(HDMI_SYS_STATUS);
911 DUMPREG(HDMI_V13_PHY_STATUS);
912 DUMPREG(HDMI_STATUS_EN);
913 DUMPREG(HDMI_HPD);
914 DUMPREG(HDMI_MODE_SEL);
915 DUMPREG(HDMI_V13_HPD_GEN);
916 DUMPREG(HDMI_V13_DC_CONTROL);
917 DUMPREG(HDMI_V13_VIDEO_PATTERN_GEN);
918
919 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
920 DUMPREG(HDMI_H_BLANK_0);
921 DUMPREG(HDMI_H_BLANK_1);
922 DUMPREG(HDMI_V13_V_BLANK_0);
923 DUMPREG(HDMI_V13_V_BLANK_1);
924 DUMPREG(HDMI_V13_V_BLANK_2);
925 DUMPREG(HDMI_V13_H_V_LINE_0);
926 DUMPREG(HDMI_V13_H_V_LINE_1);
927 DUMPREG(HDMI_V13_H_V_LINE_2);
928 DUMPREG(HDMI_VSYNC_POL);
929 DUMPREG(HDMI_INT_PRO_MODE);
930 DUMPREG(HDMI_V13_V_BLANK_F_0);
931 DUMPREG(HDMI_V13_V_BLANK_F_1);
932 DUMPREG(HDMI_V13_V_BLANK_F_2);
933 DUMPREG(HDMI_V13_H_SYNC_GEN_0);
934 DUMPREG(HDMI_V13_H_SYNC_GEN_1);
935 DUMPREG(HDMI_V13_H_SYNC_GEN_2);
936 DUMPREG(HDMI_V13_V_SYNC_GEN_1_0);
937 DUMPREG(HDMI_V13_V_SYNC_GEN_1_1);
938 DUMPREG(HDMI_V13_V_SYNC_GEN_1_2);
939 DUMPREG(HDMI_V13_V_SYNC_GEN_2_0);
940 DUMPREG(HDMI_V13_V_SYNC_GEN_2_1);
941 DUMPREG(HDMI_V13_V_SYNC_GEN_2_2);
942 DUMPREG(HDMI_V13_V_SYNC_GEN_3_0);
943 DUMPREG(HDMI_V13_V_SYNC_GEN_3_1);
944 DUMPREG(HDMI_V13_V_SYNC_GEN_3_2);
945
946 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
947 DUMPREG(HDMI_TG_CMD);
948 DUMPREG(HDMI_TG_H_FSZ_L);
949 DUMPREG(HDMI_TG_H_FSZ_H);
950 DUMPREG(HDMI_TG_HACT_ST_L);
951 DUMPREG(HDMI_TG_HACT_ST_H);
952 DUMPREG(HDMI_TG_HACT_SZ_L);
953 DUMPREG(HDMI_TG_HACT_SZ_H);
954 DUMPREG(HDMI_TG_V_FSZ_L);
955 DUMPREG(HDMI_TG_V_FSZ_H);
956 DUMPREG(HDMI_TG_VSYNC_L);
957 DUMPREG(HDMI_TG_VSYNC_H);
958 DUMPREG(HDMI_TG_VSYNC2_L);
959 DUMPREG(HDMI_TG_VSYNC2_H);
960 DUMPREG(HDMI_TG_VACT_ST_L);
961 DUMPREG(HDMI_TG_VACT_ST_H);
962 DUMPREG(HDMI_TG_VACT_SZ_L);
963 DUMPREG(HDMI_TG_VACT_SZ_H);
964 DUMPREG(HDMI_TG_FIELD_CHG_L);
965 DUMPREG(HDMI_TG_FIELD_CHG_H);
966 DUMPREG(HDMI_TG_VACT_ST2_L);
967 DUMPREG(HDMI_TG_VACT_ST2_H);
968 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
969 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
970 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
971 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
972 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
973 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
974 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
975 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
976#undef DUMPREG
977}
978
979static void hdmi_v14_regs_dump(struct hdmi_context *hdata, char *prefix)
980{
981 int i;
982
983#define DUMPREG(reg_id) \
984 DRM_DEBUG_KMS("%s:" #reg_id " = %08x\n", prefix, \
985 readl(hdata->regs + reg_id))
986
987 DRM_DEBUG_KMS("%s: ---- CONTROL REGISTERS ----\n", prefix);
988 DUMPREG(HDMI_INTC_CON);
989 DUMPREG(HDMI_INTC_FLAG);
990 DUMPREG(HDMI_HPD_STATUS);
991 DUMPREG(HDMI_INTC_CON_1);
992 DUMPREG(HDMI_INTC_FLAG_1);
993 DUMPREG(HDMI_PHY_STATUS_0);
994 DUMPREG(HDMI_PHY_STATUS_PLL);
995 DUMPREG(HDMI_PHY_CON_0);
336 DUMPREG(HDMI_PHY_RSTOUT); 996 DUMPREG(HDMI_PHY_RSTOUT);
337 DUMPREG(HDMI_PHY_VPLL); 997 DUMPREG(HDMI_PHY_VPLL);
338 DUMPREG(HDMI_PHY_CMU); 998 DUMPREG(HDMI_PHY_CMU);
@@ -343,40 +1003,93 @@ static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
343 DUMPREG(HDMI_CON_1); 1003 DUMPREG(HDMI_CON_1);
344 DUMPREG(HDMI_CON_2); 1004 DUMPREG(HDMI_CON_2);
345 DUMPREG(HDMI_SYS_STATUS); 1005 DUMPREG(HDMI_SYS_STATUS);
346 DUMPREG(HDMI_PHY_STATUS); 1006 DUMPREG(HDMI_PHY_STATUS_0);
347 DUMPREG(HDMI_STATUS_EN); 1007 DUMPREG(HDMI_STATUS_EN);
348 DUMPREG(HDMI_HPD); 1008 DUMPREG(HDMI_HPD);
349 DUMPREG(HDMI_MODE_SEL); 1009 DUMPREG(HDMI_MODE_SEL);
350 DUMPREG(HDMI_HPD_GEN); 1010 DUMPREG(HDMI_ENC_EN);
351 DUMPREG(HDMI_DC_CONTROL); 1011 DUMPREG(HDMI_DC_CONTROL);
352 DUMPREG(HDMI_VIDEO_PATTERN_GEN); 1012 DUMPREG(HDMI_VIDEO_PATTERN_GEN);
353 1013
354 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix); 1014 DRM_DEBUG_KMS("%s: ---- CORE SYNC REGISTERS ----\n", prefix);
355 DUMPREG(HDMI_H_BLANK_0); 1015 DUMPREG(HDMI_H_BLANK_0);
356 DUMPREG(HDMI_H_BLANK_1); 1016 DUMPREG(HDMI_H_BLANK_1);
357 DUMPREG(HDMI_V_BLANK_0); 1017 DUMPREG(HDMI_V2_BLANK_0);
358 DUMPREG(HDMI_V_BLANK_1); 1018 DUMPREG(HDMI_V2_BLANK_1);
359 DUMPREG(HDMI_V_BLANK_2); 1019 DUMPREG(HDMI_V1_BLANK_0);
360 DUMPREG(HDMI_H_V_LINE_0); 1020 DUMPREG(HDMI_V1_BLANK_1);
361 DUMPREG(HDMI_H_V_LINE_1); 1021 DUMPREG(HDMI_V_LINE_0);
362 DUMPREG(HDMI_H_V_LINE_2); 1022 DUMPREG(HDMI_V_LINE_1);
1023 DUMPREG(HDMI_H_LINE_0);
1024 DUMPREG(HDMI_H_LINE_1);
1025 DUMPREG(HDMI_HSYNC_POL);
1026
363 DUMPREG(HDMI_VSYNC_POL); 1027 DUMPREG(HDMI_VSYNC_POL);
364 DUMPREG(HDMI_INT_PRO_MODE); 1028 DUMPREG(HDMI_INT_PRO_MODE);
365 DUMPREG(HDMI_V_BLANK_F_0); 1029 DUMPREG(HDMI_V_BLANK_F0_0);
366 DUMPREG(HDMI_V_BLANK_F_1); 1030 DUMPREG(HDMI_V_BLANK_F0_1);
367 DUMPREG(HDMI_V_BLANK_F_2); 1031 DUMPREG(HDMI_V_BLANK_F1_0);
368 DUMPREG(HDMI_H_SYNC_GEN_0); 1032 DUMPREG(HDMI_V_BLANK_F1_1);
369 DUMPREG(HDMI_H_SYNC_GEN_1); 1033
370 DUMPREG(HDMI_H_SYNC_GEN_2); 1034 DUMPREG(HDMI_H_SYNC_START_0);
371 DUMPREG(HDMI_V_SYNC_GEN_1_0); 1035 DUMPREG(HDMI_H_SYNC_START_1);
372 DUMPREG(HDMI_V_SYNC_GEN_1_1); 1036 DUMPREG(HDMI_H_SYNC_END_0);
373 DUMPREG(HDMI_V_SYNC_GEN_1_2); 1037 DUMPREG(HDMI_H_SYNC_END_1);
374 DUMPREG(HDMI_V_SYNC_GEN_2_0); 1038
375 DUMPREG(HDMI_V_SYNC_GEN_2_1); 1039 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_0);
376 DUMPREG(HDMI_V_SYNC_GEN_2_2); 1040 DUMPREG(HDMI_V_SYNC_LINE_BEF_2_1);
377 DUMPREG(HDMI_V_SYNC_GEN_3_0); 1041 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_0);
378 DUMPREG(HDMI_V_SYNC_GEN_3_1); 1042 DUMPREG(HDMI_V_SYNC_LINE_BEF_1_1);
379 DUMPREG(HDMI_V_SYNC_GEN_3_2); 1043
1044 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_0);
1045 DUMPREG(HDMI_V_SYNC_LINE_AFT_2_1);
1046 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_0);
1047 DUMPREG(HDMI_V_SYNC_LINE_AFT_1_1);
1048
1049 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_0);
1050 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_2_1);
1051 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_0);
1052 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_1_1);
1053
1054 DUMPREG(HDMI_V_BLANK_F2_0);
1055 DUMPREG(HDMI_V_BLANK_F2_1);
1056 DUMPREG(HDMI_V_BLANK_F3_0);
1057 DUMPREG(HDMI_V_BLANK_F3_1);
1058 DUMPREG(HDMI_V_BLANK_F4_0);
1059 DUMPREG(HDMI_V_BLANK_F4_1);
1060 DUMPREG(HDMI_V_BLANK_F5_0);
1061 DUMPREG(HDMI_V_BLANK_F5_1);
1062
1063 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_0);
1064 DUMPREG(HDMI_V_SYNC_LINE_AFT_3_1);
1065 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_0);
1066 DUMPREG(HDMI_V_SYNC_LINE_AFT_4_1);
1067 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_0);
1068 DUMPREG(HDMI_V_SYNC_LINE_AFT_5_1);
1069 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_0);
1070 DUMPREG(HDMI_V_SYNC_LINE_AFT_6_1);
1071
1072 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_0);
1073 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_3_1);
1074 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_0);
1075 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_4_1);
1076 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_0);
1077 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_5_1);
1078 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_0);
1079 DUMPREG(HDMI_V_SYNC_LINE_AFT_PXL_6_1);
1080
1081 DUMPREG(HDMI_VACT_SPACE_1_0);
1082 DUMPREG(HDMI_VACT_SPACE_1_1);
1083 DUMPREG(HDMI_VACT_SPACE_2_0);
1084 DUMPREG(HDMI_VACT_SPACE_2_1);
1085 DUMPREG(HDMI_VACT_SPACE_3_0);
1086 DUMPREG(HDMI_VACT_SPACE_3_1);
1087 DUMPREG(HDMI_VACT_SPACE_4_0);
1088 DUMPREG(HDMI_VACT_SPACE_4_1);
1089 DUMPREG(HDMI_VACT_SPACE_5_0);
1090 DUMPREG(HDMI_VACT_SPACE_5_1);
1091 DUMPREG(HDMI_VACT_SPACE_6_0);
1092 DUMPREG(HDMI_VACT_SPACE_6_1);
380 1093
381 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix); 1094 DRM_DEBUG_KMS("%s: ---- TG REGISTERS ----\n", prefix);
382 DUMPREG(HDMI_TG_CMD); 1095 DUMPREG(HDMI_TG_CMD);
@@ -400,6 +1113,10 @@ static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
400 DUMPREG(HDMI_TG_FIELD_CHG_H); 1113 DUMPREG(HDMI_TG_FIELD_CHG_H);
401 DUMPREG(HDMI_TG_VACT_ST2_L); 1114 DUMPREG(HDMI_TG_VACT_ST2_L);
402 DUMPREG(HDMI_TG_VACT_ST2_H); 1115 DUMPREG(HDMI_TG_VACT_ST2_H);
1116 DUMPREG(HDMI_TG_VACT_ST3_L);
1117 DUMPREG(HDMI_TG_VACT_ST3_H);
1118 DUMPREG(HDMI_TG_VACT_ST4_L);
1119 DUMPREG(HDMI_TG_VACT_ST4_H);
403 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L); 1120 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
404 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H); 1121 DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
405 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L); 1122 DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
@@ -408,10 +1125,49 @@ static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
408 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H); 1125 DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
409 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L); 1126 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
410 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H); 1127 DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
1128 DUMPREG(HDMI_TG_3D);
1129
1130 DRM_DEBUG_KMS("%s: ---- PACKET REGISTERS ----\n", prefix);
1131 DUMPREG(HDMI_AVI_CON);
1132 DUMPREG(HDMI_AVI_HEADER0);
1133 DUMPREG(HDMI_AVI_HEADER1);
1134 DUMPREG(HDMI_AVI_HEADER2);
1135 DUMPREG(HDMI_AVI_CHECK_SUM);
1136 DUMPREG(HDMI_VSI_CON);
1137 DUMPREG(HDMI_VSI_HEADER0);
1138 DUMPREG(HDMI_VSI_HEADER1);
1139 DUMPREG(HDMI_VSI_HEADER2);
1140 for (i = 0; i < 7; ++i)
1141 DUMPREG(HDMI_VSI_DATA(i));
1142
411#undef DUMPREG 1143#undef DUMPREG
412} 1144}
413 1145
414static int hdmi_conf_index(struct drm_display_mode *mode) 1146static void hdmi_regs_dump(struct hdmi_context *hdata, char *prefix)
1147{
1148 if (hdata->is_v13)
1149 hdmi_v13_regs_dump(hdata, prefix);
1150 else
1151 hdmi_v14_regs_dump(hdata, prefix);
1152}
1153
1154static int hdmi_v13_conf_index(struct drm_display_mode *mode)
1155{
1156 int i;
1157
1158 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
1159 if (hdmi_v13_confs[i].width == mode->hdisplay &&
1160 hdmi_v13_confs[i].height == mode->vdisplay &&
1161 hdmi_v13_confs[i].vrefresh == mode->vrefresh &&
1162 hdmi_v13_confs[i].interlace ==
1163 ((mode->flags & DRM_MODE_FLAG_INTERLACE) ?
1164 true : false))
1165 return i;
1166
1167 return -EINVAL;
1168}
1169
1170static int hdmi_v14_conf_index(struct drm_display_mode *mode)
415{ 1171{
416 int i; 1172 int i;
417 1173
@@ -424,7 +1180,16 @@ static int hdmi_conf_index(struct drm_display_mode *mode)
424 true : false)) 1180 true : false))
425 return i; 1181 return i;
426 1182
427 return -1; 1183 return -EINVAL;
1184}
1185
1186static int hdmi_conf_index(struct hdmi_context *hdata,
1187 struct drm_display_mode *mode)
1188{
1189 if (hdata->is_v13)
1190 return hdmi_v13_conf_index(mode);
1191
1192 return hdmi_v14_conf_index(mode);
428} 1193}
429 1194
430static bool hdmi_is_connected(void *ctx) 1195static bool hdmi_is_connected(void *ctx)
@@ -462,29 +1227,69 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector,
462 return 0; 1227 return 0;
463} 1228}
464 1229
465static int hdmi_check_timing(void *ctx, void *timing) 1230static int hdmi_v13_check_timing(struct fb_videomode *check_timing)
466{ 1231{
467 struct fb_videomode *check_timing = timing;
468 int i; 1232 int i;
469 1233
470 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1234 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1235 check_timing->xres, check_timing->yres,
1236 check_timing->refresh, (check_timing->vmode &
1237 FB_VMODE_INTERLACED) ? true : false);
471 1238
472 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres, 1239 for (i = 0; i < ARRAY_SIZE(hdmi_v13_confs); ++i)
473 check_timing->yres, check_timing->refresh, 1240 if (hdmi_v13_confs[i].width == check_timing->xres &&
474 check_timing->vmode); 1241 hdmi_v13_confs[i].height == check_timing->yres &&
1242 hdmi_v13_confs[i].vrefresh == check_timing->refresh &&
1243 hdmi_v13_confs[i].interlace ==
1244 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
1245 true : false))
1246 return 0;
475 1247
476 for (i = 0; i < ARRAY_SIZE(hdmi_confs); ++i) 1248 /* TODO */
1249
1250 return -EINVAL;
1251}
1252
1253static int hdmi_v14_check_timing(struct fb_videomode *check_timing)
1254{
1255 int i;
1256
1257 DRM_DEBUG_KMS("valid mode : xres=%d, yres=%d, refresh=%d, intl=%d\n",
1258 check_timing->xres, check_timing->yres,
1259 check_timing->refresh, (check_timing->vmode &
1260 FB_VMODE_INTERLACED) ? true : false);
1261
1262 for (i = 0; i < ARRAY_SIZE(hdmi_confs); i++)
477 if (hdmi_confs[i].width == check_timing->xres && 1263 if (hdmi_confs[i].width == check_timing->xres &&
478 hdmi_confs[i].height == check_timing->yres && 1264 hdmi_confs[i].height == check_timing->yres &&
479 hdmi_confs[i].vrefresh == check_timing->refresh && 1265 hdmi_confs[i].vrefresh == check_timing->refresh &&
480 hdmi_confs[i].interlace == 1266 hdmi_confs[i].interlace ==
481 ((check_timing->vmode & FB_VMODE_INTERLACED) ? 1267 ((check_timing->vmode & FB_VMODE_INTERLACED) ?
482 true : false)) 1268 true : false))
483 return 0; 1269 return 0;
1270
1271 /* TODO */
484 1272
485 return -EINVAL; 1273 return -EINVAL;
486} 1274}
487 1275
1276static int hdmi_check_timing(void *ctx, void *timing)
1277{
1278 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1279 struct fb_videomode *check_timing = timing;
1280
1281 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1282
1283 DRM_DEBUG_KMS("[%d]x[%d] [%d]Hz [%x]\n", check_timing->xres,
1284 check_timing->yres, check_timing->refresh,
1285 check_timing->vmode);
1286
1287 if (hdata->is_v13)
1288 return hdmi_v13_check_timing(check_timing);
1289 else
1290 return hdmi_v14_check_timing(check_timing);
1291}
1292
488static int hdmi_display_power_on(void *ctx, int mode) 1293static int hdmi_display_power_on(void *ctx, int mode)
489{ 1294{
490 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1295 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
@@ -514,15 +1319,185 @@ static struct exynos_hdmi_display_ops display_ops = {
514 .power_on = hdmi_display_power_on, 1319 .power_on = hdmi_display_power_on,
515}; 1320};
516 1321
1322static void hdmi_set_acr(u32 freq, u8 *acr)
1323{
1324 u32 n, cts;
1325
1326 switch (freq) {
1327 case 32000:
1328 n = 4096;
1329 cts = 27000;
1330 break;
1331 case 44100:
1332 n = 6272;
1333 cts = 30000;
1334 break;
1335 case 88200:
1336 n = 12544;
1337 cts = 30000;
1338 break;
1339 case 176400:
1340 n = 25088;
1341 cts = 30000;
1342 break;
1343 case 48000:
1344 n = 6144;
1345 cts = 27000;
1346 break;
1347 case 96000:
1348 n = 12288;
1349 cts = 27000;
1350 break;
1351 case 192000:
1352 n = 24576;
1353 cts = 27000;
1354 break;
1355 default:
1356 n = 0;
1357 cts = 0;
1358 break;
1359 }
1360
1361 acr[1] = cts >> 16;
1362 acr[2] = cts >> 8 & 0xff;
1363 acr[3] = cts & 0xff;
1364
1365 acr[4] = n >> 16;
1366 acr[5] = n >> 8 & 0xff;
1367 acr[6] = n & 0xff;
1368}
1369
1370static void hdmi_reg_acr(struct hdmi_context *hdata, u8 *acr)
1371{
1372 hdmi_reg_writeb(hdata, HDMI_ACR_N0, acr[6]);
1373 hdmi_reg_writeb(hdata, HDMI_ACR_N1, acr[5]);
1374 hdmi_reg_writeb(hdata, HDMI_ACR_N2, acr[4]);
1375 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS0, acr[3]);
1376 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS1, acr[2]);
1377 hdmi_reg_writeb(hdata, HDMI_ACR_MCTS2, acr[1]);
1378 hdmi_reg_writeb(hdata, HDMI_ACR_CTS0, acr[3]);
1379 hdmi_reg_writeb(hdata, HDMI_ACR_CTS1, acr[2]);
1380 hdmi_reg_writeb(hdata, HDMI_ACR_CTS2, acr[1]);
1381
1382 if (hdata->is_v13)
1383 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 4);
1384 else
1385 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 4);
1386}
1387
1388static void hdmi_audio_init(struct hdmi_context *hdata)
1389{
1390 u32 sample_rate, bits_per_sample, frame_size_code;
1391 u32 data_num, bit_ch, sample_frq;
1392 u32 val;
1393 u8 acr[7];
1394
1395 sample_rate = 44100;
1396 bits_per_sample = 16;
1397 frame_size_code = 0;
1398
1399 switch (bits_per_sample) {
1400 case 20:
1401 data_num = 2;
1402 bit_ch = 1;
1403 break;
1404 case 24:
1405 data_num = 3;
1406 bit_ch = 1;
1407 break;
1408 default:
1409 data_num = 1;
1410 bit_ch = 0;
1411 break;
1412 }
1413
1414 hdmi_set_acr(sample_rate, acr);
1415 hdmi_reg_acr(hdata, acr);
1416
1417 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CON, HDMI_I2S_IN_DISABLE
1418 | HDMI_I2S_AUD_I2S | HDMI_I2S_CUV_I2S_ENABLE
1419 | HDMI_I2S_MUX_ENABLE);
1420
1421 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CH, HDMI_I2S_CH0_EN
1422 | HDMI_I2S_CH1_EN | HDMI_I2S_CH2_EN);
1423
1424 hdmi_reg_writeb(hdata, HDMI_I2S_MUX_CUV, HDMI_I2S_CUV_RL_EN);
1425
1426 sample_frq = (sample_rate == 44100) ? 0 :
1427 (sample_rate == 48000) ? 2 :
1428 (sample_rate == 32000) ? 3 :
1429 (sample_rate == 96000) ? 0xa : 0x0;
1430
1431 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_DIS);
1432 hdmi_reg_writeb(hdata, HDMI_I2S_CLK_CON, HDMI_I2S_CLK_EN);
1433
1434 val = hdmi_reg_read(hdata, HDMI_I2S_DSD_CON) | 0x01;
1435 hdmi_reg_writeb(hdata, HDMI_I2S_DSD_CON, val);
1436
1437 /* Configuration I2S input ports. Configure I2S_PIN_SEL_0~4 */
1438 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_0, HDMI_I2S_SEL_SCLK(5)
1439 | HDMI_I2S_SEL_LRCK(6));
1440 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_1, HDMI_I2S_SEL_SDATA1(1)
1441 | HDMI_I2S_SEL_SDATA2(4));
1442 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_2, HDMI_I2S_SEL_SDATA3(1)
1443 | HDMI_I2S_SEL_SDATA2(2));
1444 hdmi_reg_writeb(hdata, HDMI_I2S_PIN_SEL_3, HDMI_I2S_SEL_DSD(0));
1445
1446 /* I2S_CON_1 & 2 */
1447 hdmi_reg_writeb(hdata, HDMI_I2S_CON_1, HDMI_I2S_SCLK_FALLING_EDGE
1448 | HDMI_I2S_L_CH_LOW_POL);
1449 hdmi_reg_writeb(hdata, HDMI_I2S_CON_2, HDMI_I2S_MSB_FIRST_MODE
1450 | HDMI_I2S_SET_BIT_CH(bit_ch)
1451 | HDMI_I2S_SET_SDATA_BIT(data_num)
1452 | HDMI_I2S_BASIC_FORMAT);
1453
1454 /* Configure register related to CUV information */
1455 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_0, HDMI_I2S_CH_STATUS_MODE_0
1456 | HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH
1457 | HDMI_I2S_COPYRIGHT
1458 | HDMI_I2S_LINEAR_PCM
1459 | HDMI_I2S_CONSUMER_FORMAT);
1460 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_1, HDMI_I2S_CD_PLAYER);
1461 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_2, HDMI_I2S_SET_SOURCE_NUM(0));
1462 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_3, HDMI_I2S_CLK_ACCUR_LEVEL_2
1463 | HDMI_I2S_SET_SMP_FREQ(sample_frq));
1464 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_4,
1465 HDMI_I2S_ORG_SMP_FREQ_44_1
1466 | HDMI_I2S_WORD_LEN_MAX24_24BITS
1467 | HDMI_I2S_WORD_LEN_MAX_24BITS);
1468
1469 hdmi_reg_writeb(hdata, HDMI_I2S_CH_ST_CON, HDMI_I2S_CH_STATUS_RELOAD);
1470}
1471
1472static void hdmi_audio_control(struct hdmi_context *hdata, bool onoff)
1473{
1474 u32 mod;
1475
1476 mod = hdmi_reg_read(hdata, HDMI_MODE_SEL);
1477 if (mod & HDMI_DVI_MODE_EN)
1478 return;
1479
1480 hdmi_reg_writeb(hdata, HDMI_AUI_CON, onoff ? 2 : 0);
1481 hdmi_reg_writemask(hdata, HDMI_CON_0, onoff ?
1482 HDMI_ASP_EN : HDMI_ASP_DIS, HDMI_ASP_MASK);
1483}
1484
517static void hdmi_conf_reset(struct hdmi_context *hdata) 1485static void hdmi_conf_reset(struct hdmi_context *hdata)
518{ 1486{
1487 u32 reg;
1488
519 /* disable hpd handle for drm */ 1489 /* disable hpd handle for drm */
520 hdata->hpd_handle = false; 1490 hdata->hpd_handle = false;
521 1491
1492 if (hdata->is_v13)
1493 reg = HDMI_V13_CORE_RSTOUT;
1494 else
1495 reg = HDMI_CORE_RSTOUT;
1496
522 /* resetting HDMI core */ 1497 /* resetting HDMI core */
523 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, 0, HDMI_CORE_SW_RSTOUT); 1498 hdmi_reg_writemask(hdata, reg, 0, HDMI_CORE_SW_RSTOUT);
524 mdelay(10); 1499 mdelay(10);
525 hdmi_reg_writemask(hdata, HDMI_CORE_RSTOUT, ~0, HDMI_CORE_SW_RSTOUT); 1500 hdmi_reg_writemask(hdata, reg, ~0, HDMI_CORE_SW_RSTOUT);
526 mdelay(10); 1501 mdelay(10);
527 1502
528 /* enable hpd handle for drm */ 1503 /* enable hpd handle for drm */
@@ -546,27 +1521,126 @@ static void hdmi_conf_init(struct hdmi_context *hdata)
546 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK); 1521 HDMI_MODE_HDMI_EN, HDMI_MODE_MASK);
547 /* disable bluescreen */ 1522 /* disable bluescreen */
548 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN); 1523 hdmi_reg_writemask(hdata, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
549 /* choose bluescreen (fecal) color */ 1524
550 hdmi_reg_writeb(hdata, HDMI_BLUE_SCREEN_0, 0x12); 1525 if (hdata->is_v13) {
551 hdmi_reg_writeb(hdata, HDMI_BLUE_SCREEN_1, 0x34); 1526 /* choose bluescreen (fecal) color */
552 hdmi_reg_writeb(hdata, HDMI_BLUE_SCREEN_2, 0x56); 1527 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_0, 0x12);
553 /* enable AVI packet every vsync, fixes purple line problem */ 1528 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_1, 0x34);
554 hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02); 1529 hdmi_reg_writeb(hdata, HDMI_V13_BLUE_SCREEN_2, 0x56);
555 /* force RGB, look to CEA-861-D, table 7 for more detail */ 1530
556 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(0), 0 << 5); 1531 /* enable AVI packet every vsync, fixes purple line problem */
557 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5); 1532 hdmi_reg_writeb(hdata, HDMI_V13_AVI_CON, 0x02);
558 1533 /* force RGB, look to CEA-861-D, table 7 for more detail */
559 hdmi_reg_writeb(hdata, HDMI_SPD_CON, 0x02); 1534 hdmi_reg_writeb(hdata, HDMI_V13_AVI_BYTE(0), 0 << 5);
560 hdmi_reg_writeb(hdata, HDMI_AUI_CON, 0x02); 1535 hdmi_reg_writemask(hdata, HDMI_CON_1, 0x10 << 5, 0x11 << 5);
561 hdmi_reg_writeb(hdata, HDMI_ACR_CON, 0x04); 1536
1537 hdmi_reg_writeb(hdata, HDMI_V13_SPD_CON, 0x02);
1538 hdmi_reg_writeb(hdata, HDMI_V13_AUI_CON, 0x02);
1539 hdmi_reg_writeb(hdata, HDMI_V13_ACR_CON, 0x04);
1540 } else {
1541 /* enable AVI packet every vsync, fixes purple line problem */
1542 hdmi_reg_writeb(hdata, HDMI_AVI_CON, 0x02);
1543 hdmi_reg_writeb(hdata, HDMI_AVI_BYTE(1), 2 << 5);
1544 hdmi_reg_writemask(hdata, HDMI_CON_1, 2, 3 << 5);
1545 }
562 1546
563 /* enable hpd handle for drm */ 1547 /* enable hpd handle for drm */
564 hdata->hpd_handle = true; 1548 hdata->hpd_handle = true;
565} 1549}
566 1550
567static void hdmi_timing_apply(struct hdmi_context *hdata, 1551static void hdmi_v13_timing_apply(struct hdmi_context *hdata)
568 const struct hdmi_preset_conf *conf)
569{ 1552{
1553 const struct hdmi_v13_preset_conf *conf =
1554 hdmi_v13_confs[hdata->cur_conf].conf;
1555 const struct hdmi_v13_core_regs *core = &conf->core;
1556 const struct hdmi_v13_tg_regs *tg = &conf->tg;
1557 int tries;
1558
1559 /* setting core registers */
1560 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
1561 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
1562 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_0, core->v_blank[0]);
1563 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_1, core->v_blank[1]);
1564 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_2, core->v_blank[2]);
1565 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_0, core->h_v_line[0]);
1566 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_1, core->h_v_line[1]);
1567 hdmi_reg_writeb(hdata, HDMI_V13_H_V_LINE_2, core->h_v_line[2]);
1568 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
1569 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
1570 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_0, core->v_blank_f[0]);
1571 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_1, core->v_blank_f[1]);
1572 hdmi_reg_writeb(hdata, HDMI_V13_V_BLANK_F_2, core->v_blank_f[2]);
1573 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_0, core->h_sync_gen[0]);
1574 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_1, core->h_sync_gen[1]);
1575 hdmi_reg_writeb(hdata, HDMI_V13_H_SYNC_GEN_2, core->h_sync_gen[2]);
1576 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
1577 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
1578 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
1579 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
1580 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
1581 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
1582 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
1583 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
1584 hdmi_reg_writeb(hdata, HDMI_V13_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
1585 /* Timing generator registers */
1586 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
1587 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
1588 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_L, tg->hact_st_l);
1589 hdmi_reg_writeb(hdata, HDMI_TG_HACT_ST_H, tg->hact_st_h);
1590 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
1591 hdmi_reg_writeb(hdata, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
1592 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
1593 hdmi_reg_writeb(hdata, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
1594 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_L, tg->vsync_l);
1595 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_H, tg->vsync_h);
1596 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_L, tg->vsync2_l);
1597 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC2_H, tg->vsync2_h);
1598 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_L, tg->vact_st_l);
1599 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST_H, tg->vact_st_h);
1600 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
1601 hdmi_reg_writeb(hdata, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
1602 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
1603 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
1604 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
1605 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1606 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
1607 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
1608 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
1609 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
1610 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
1611 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
1612 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
1613 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1614
1615 /* waiting for HDMIPHY's PLL to get to steady state */
1616 for (tries = 100; tries; --tries) {
1617 u32 val = hdmi_reg_read(hdata, HDMI_V13_PHY_STATUS);
1618 if (val & HDMI_PHY_STATUS_READY)
1619 break;
1620 mdelay(1);
1621 }
1622 /* steady state not achieved */
1623 if (tries == 0) {
1624 DRM_ERROR("hdmiphy's pll could not reach steady state.\n");
1625 hdmi_regs_dump(hdata, "timing apply");
1626 }
1627
1628 clk_disable(hdata->res.sclk_hdmi);
1629 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_hdmiphy);
1630 clk_enable(hdata->res.sclk_hdmi);
1631
1632 /* enable HDMI and timing generator */
1633 hdmi_reg_writemask(hdata, HDMI_CON_0, ~0, HDMI_EN);
1634 if (core->int_pro_mode[0])
1635 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN |
1636 HDMI_FIELD_EN);
1637 else
1638 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
1639}
1640
1641static void hdmi_v14_timing_apply(struct hdmi_context *hdata)
1642{
1643 const struct hdmi_preset_conf *conf = hdmi_confs[hdata->cur_conf].conf;
570 const struct hdmi_core_regs *core = &conf->core; 1644 const struct hdmi_core_regs *core = &conf->core;
571 const struct hdmi_tg_regs *tg = &conf->tg; 1645 const struct hdmi_tg_regs *tg = &conf->tg;
572 int tries; 1646 int tries;
@@ -574,29 +1648,102 @@ static void hdmi_timing_apply(struct hdmi_context *hdata,
574 /* setting core registers */ 1648 /* setting core registers */
575 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]); 1649 hdmi_reg_writeb(hdata, HDMI_H_BLANK_0, core->h_blank[0]);
576 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]); 1650 hdmi_reg_writeb(hdata, HDMI_H_BLANK_1, core->h_blank[1]);
577 hdmi_reg_writeb(hdata, HDMI_V_BLANK_0, core->v_blank[0]); 1651 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_0, core->v2_blank[0]);
578 hdmi_reg_writeb(hdata, HDMI_V_BLANK_1, core->v_blank[1]); 1652 hdmi_reg_writeb(hdata, HDMI_V2_BLANK_1, core->v2_blank[1]);
579 hdmi_reg_writeb(hdata, HDMI_V_BLANK_2, core->v_blank[2]); 1653 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_0, core->v1_blank[0]);
580 hdmi_reg_writeb(hdata, HDMI_H_V_LINE_0, core->h_v_line[0]); 1654 hdmi_reg_writeb(hdata, HDMI_V1_BLANK_1, core->v1_blank[1]);
581 hdmi_reg_writeb(hdata, HDMI_H_V_LINE_1, core->h_v_line[1]); 1655 hdmi_reg_writeb(hdata, HDMI_V_LINE_0, core->v_line[0]);
582 hdmi_reg_writeb(hdata, HDMI_H_V_LINE_2, core->h_v_line[2]); 1656 hdmi_reg_writeb(hdata, HDMI_V_LINE_1, core->v_line[1]);
1657 hdmi_reg_writeb(hdata, HDMI_H_LINE_0, core->h_line[0]);
1658 hdmi_reg_writeb(hdata, HDMI_H_LINE_1, core->h_line[1]);
1659 hdmi_reg_writeb(hdata, HDMI_HSYNC_POL, core->hsync_pol[0]);
583 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]); 1660 hdmi_reg_writeb(hdata, HDMI_VSYNC_POL, core->vsync_pol[0]);
584 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]); 1661 hdmi_reg_writeb(hdata, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
585 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F_0, core->v_blank_f[0]); 1662 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_0, core->v_blank_f0[0]);
586 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F_1, core->v_blank_f[1]); 1663 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F0_1, core->v_blank_f0[1]);
587 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F_2, core->v_blank_f[2]); 1664 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_0, core->v_blank_f1[0]);
588 hdmi_reg_writeb(hdata, HDMI_H_SYNC_GEN_0, core->h_sync_gen[0]); 1665 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F1_1, core->v_blank_f1[1]);
589 hdmi_reg_writeb(hdata, HDMI_H_SYNC_GEN_1, core->h_sync_gen[1]); 1666 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_0, core->h_sync_start[0]);
590 hdmi_reg_writeb(hdata, HDMI_H_SYNC_GEN_2, core->h_sync_gen[2]); 1667 hdmi_reg_writeb(hdata, HDMI_H_SYNC_START_1, core->h_sync_start[1]);
591 hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_1_0, core->v_sync_gen1[0]); 1668 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_0, core->h_sync_end[0]);
592 hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_1_1, core->v_sync_gen1[1]); 1669 hdmi_reg_writeb(hdata, HDMI_H_SYNC_END_1, core->h_sync_end[1]);
593 hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_1_2, core->v_sync_gen1[2]); 1670 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_0,
594 hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_2_0, core->v_sync_gen2[0]); 1671 core->v_sync_line_bef_2[0]);
595 hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_2_1, core->v_sync_gen2[1]); 1672 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_2_1,
596 hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_2_2, core->v_sync_gen2[2]); 1673 core->v_sync_line_bef_2[1]);
597 hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_3_0, core->v_sync_gen3[0]); 1674 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_0,
598 hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_3_1, core->v_sync_gen3[1]); 1675 core->v_sync_line_bef_1[0]);
599 hdmi_reg_writeb(hdata, HDMI_V_SYNC_GEN_3_2, core->v_sync_gen3[2]); 1676 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_BEF_1_1,
1677 core->v_sync_line_bef_1[1]);
1678 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_0,
1679 core->v_sync_line_aft_2[0]);
1680 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_2_1,
1681 core->v_sync_line_aft_2[1]);
1682 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_0,
1683 core->v_sync_line_aft_1[0]);
1684 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_1_1,
1685 core->v_sync_line_aft_1[1]);
1686 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_0,
1687 core->v_sync_line_aft_pxl_2[0]);
1688 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_2_1,
1689 core->v_sync_line_aft_pxl_2[1]);
1690 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_0,
1691 core->v_sync_line_aft_pxl_1[0]);
1692 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_1_1,
1693 core->v_sync_line_aft_pxl_1[1]);
1694 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_0, core->v_blank_f2[0]);
1695 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F2_1, core->v_blank_f2[1]);
1696 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_0, core->v_blank_f3[0]);
1697 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F3_1, core->v_blank_f3[1]);
1698 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_0, core->v_blank_f4[0]);
1699 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F4_1, core->v_blank_f4[1]);
1700 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_0, core->v_blank_f5[0]);
1701 hdmi_reg_writeb(hdata, HDMI_V_BLANK_F5_1, core->v_blank_f5[1]);
1702 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_0,
1703 core->v_sync_line_aft_3[0]);
1704 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_3_1,
1705 core->v_sync_line_aft_3[1]);
1706 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_0,
1707 core->v_sync_line_aft_4[0]);
1708 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_4_1,
1709 core->v_sync_line_aft_4[1]);
1710 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_0,
1711 core->v_sync_line_aft_5[0]);
1712 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_5_1,
1713 core->v_sync_line_aft_5[1]);
1714 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_0,
1715 core->v_sync_line_aft_6[0]);
1716 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_6_1,
1717 core->v_sync_line_aft_6[1]);
1718 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_0,
1719 core->v_sync_line_aft_pxl_3[0]);
1720 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_3_1,
1721 core->v_sync_line_aft_pxl_3[1]);
1722 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_0,
1723 core->v_sync_line_aft_pxl_4[0]);
1724 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_4_1,
1725 core->v_sync_line_aft_pxl_4[1]);
1726 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_0,
1727 core->v_sync_line_aft_pxl_5[0]);
1728 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_5_1,
1729 core->v_sync_line_aft_pxl_5[1]);
1730 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_0,
1731 core->v_sync_line_aft_pxl_6[0]);
1732 hdmi_reg_writeb(hdata, HDMI_V_SYNC_LINE_AFT_PXL_6_1,
1733 core->v_sync_line_aft_pxl_6[1]);
1734 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_0, core->vact_space_1[0]);
1735 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_1_1, core->vact_space_1[1]);
1736 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_0, core->vact_space_2[0]);
1737 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_2_1, core->vact_space_2[1]);
1738 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_0, core->vact_space_3[0]);
1739 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_3_1, core->vact_space_3[1]);
1740 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_0, core->vact_space_4[0]);
1741 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_4_1, core->vact_space_4[1]);
1742 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_0, core->vact_space_5[0]);
1743 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_5_1, core->vact_space_5[1]);
1744 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_0, core->vact_space_6[0]);
1745 hdmi_reg_writeb(hdata, HDMI_VACT_SPACE_6_1, core->vact_space_6[1]);
1746
600 /* Timing generator registers */ 1747 /* Timing generator registers */
601 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l); 1748 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
602 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h); 1749 hdmi_reg_writeb(hdata, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
@@ -618,6 +1765,10 @@ static void hdmi_timing_apply(struct hdmi_context *hdata,
618 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h); 1765 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
619 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l); 1766 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
620 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h); 1767 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
1768 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_L, tg->vact_st3_l);
1769 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST3_H, tg->vact_st3_h);
1770 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_L, tg->vact_st4_l);
1771 hdmi_reg_writeb(hdata, HDMI_TG_VACT_ST4_H, tg->vact_st4_h);
621 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l); 1772 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
622 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h); 1773 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
623 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l); 1774 hdmi_reg_writeb(hdata, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
@@ -626,10 +1777,11 @@ static void hdmi_timing_apply(struct hdmi_context *hdata,
626 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h); 1777 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
627 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l); 1778 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
628 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h); 1779 hdmi_reg_writeb(hdata, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
1780 hdmi_reg_writeb(hdata, HDMI_TG_3D, tg->tg_3d);
629 1781
630 /* waiting for HDMIPHY's PLL to get to steady state */ 1782 /* waiting for HDMIPHY's PLL to get to steady state */
631 for (tries = 100; tries; --tries) { 1783 for (tries = 100; tries; --tries) {
632 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS); 1784 u32 val = hdmi_reg_read(hdata, HDMI_PHY_STATUS_0);
633 if (val & HDMI_PHY_STATUS_READY) 1785 if (val & HDMI_PHY_STATUS_READY)
634 break; 1786 break;
635 mdelay(1); 1787 mdelay(1);
@@ -653,9 +1805,18 @@ static void hdmi_timing_apply(struct hdmi_context *hdata,
653 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN); 1805 hdmi_reg_writemask(hdata, HDMI_TG_CMD, ~0, HDMI_TG_EN);
654} 1806}
655 1807
1808static void hdmi_timing_apply(struct hdmi_context *hdata)
1809{
1810 if (hdata->is_v13)
1811 hdmi_v13_timing_apply(hdata);
1812 else
1813 hdmi_v14_timing_apply(hdata);
1814}
1815
656static void hdmiphy_conf_reset(struct hdmi_context *hdata) 1816static void hdmiphy_conf_reset(struct hdmi_context *hdata)
657{ 1817{
658 u8 buffer[2]; 1818 u8 buffer[2];
1819 u32 reg;
659 1820
660 clk_disable(hdata->res.sclk_hdmi); 1821 clk_disable(hdata->res.sclk_hdmi);
661 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel); 1822 clk_set_parent(hdata->res.sclk_hdmi, hdata->res.sclk_pixel);
@@ -668,15 +1829,21 @@ static void hdmiphy_conf_reset(struct hdmi_context *hdata)
668 if (hdata->hdmiphy_port) 1829 if (hdata->hdmiphy_port)
669 i2c_master_send(hdata->hdmiphy_port, buffer, 2); 1830 i2c_master_send(hdata->hdmiphy_port, buffer, 2);
670 1831
1832 if (hdata->is_v13)
1833 reg = HDMI_V13_PHY_RSTOUT;
1834 else
1835 reg = HDMI_PHY_RSTOUT;
1836
671 /* reset hdmiphy */ 1837 /* reset hdmiphy */
672 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT); 1838 hdmi_reg_writemask(hdata, reg, ~0, HDMI_PHY_SW_RSTOUT);
673 mdelay(10); 1839 mdelay(10);
674 hdmi_reg_writemask(hdata, HDMI_PHY_RSTOUT, 0, HDMI_PHY_SW_RSTOUT); 1840 hdmi_reg_writemask(hdata, reg, 0, HDMI_PHY_SW_RSTOUT);
675 mdelay(10); 1841 mdelay(10);
676} 1842}
677 1843
678static void hdmiphy_conf_apply(struct hdmi_context *hdata) 1844static void hdmiphy_conf_apply(struct hdmi_context *hdata)
679{ 1845{
1846 const u8 *hdmiphy_data;
680 u8 buffer[32]; 1847 u8 buffer[32];
681 u8 operation[2]; 1848 u8 operation[2];
682 u8 read_buffer[32] = {0, }; 1849 u8 read_buffer[32] = {0, };
@@ -689,7 +1856,12 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
689 } 1856 }
690 1857
691 /* pixel clock */ 1858 /* pixel clock */
692 memcpy(buffer, hdmi_confs[hdata->cur_conf].hdmiphy_data, 32); 1859 if (hdata->is_v13)
1860 hdmiphy_data = hdmi_v13_confs[hdata->cur_conf].hdmiphy_data;
1861 else
1862 hdmiphy_data = hdmi_confs[hdata->cur_conf].hdmiphy_data;
1863
1864 memcpy(buffer, hdmiphy_data, 32);
693 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32); 1865 ret = i2c_master_send(hdata->hdmiphy_port, buffer, 32);
694 if (ret != 32) { 1866 if (ret != 32) {
695 DRM_ERROR("failed to configure HDMIPHY via I2C\n"); 1867 DRM_ERROR("failed to configure HDMIPHY via I2C\n");
@@ -721,9 +1893,6 @@ static void hdmiphy_conf_apply(struct hdmi_context *hdata)
721 1893
722static void hdmi_conf_apply(struct hdmi_context *hdata) 1894static void hdmi_conf_apply(struct hdmi_context *hdata)
723{ 1895{
724 const struct hdmi_preset_conf *conf =
725 hdmi_confs[hdata->cur_conf].conf;
726
727 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1896 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
728 1897
729 hdmiphy_conf_reset(hdata); 1898 hdmiphy_conf_reset(hdata);
@@ -731,13 +1900,55 @@ static void hdmi_conf_apply(struct hdmi_context *hdata)
731 1900
732 hdmi_conf_reset(hdata); 1901 hdmi_conf_reset(hdata);
733 hdmi_conf_init(hdata); 1902 hdmi_conf_init(hdata);
1903 hdmi_audio_init(hdata);
734 1904
735 /* setting core registers */ 1905 /* setting core registers */
736 hdmi_timing_apply(hdata, conf); 1906 hdmi_timing_apply(hdata);
1907 hdmi_audio_control(hdata, true);
737 1908
738 hdmi_regs_dump(hdata, "start"); 1909 hdmi_regs_dump(hdata, "start");
739} 1910}
740 1911
1912static void hdmi_mode_fixup(void *ctx, struct drm_connector *connector,
1913 struct drm_display_mode *mode,
1914 struct drm_display_mode *adjusted_mode)
1915{
1916 struct drm_display_mode *m;
1917 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
1918 int index;
1919
1920 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1921
1922 drm_mode_set_crtcinfo(adjusted_mode, 0);
1923
1924 if (hdata->is_v13)
1925 index = hdmi_v13_conf_index(adjusted_mode);
1926 else
1927 index = hdmi_v14_conf_index(adjusted_mode);
1928
1929 /* just return if user desired mode exists. */
1930 if (index >= 0)
1931 return;
1932
1933 /*
1934 * otherwise, find the most suitable mode among modes and change it
1935 * to adjusted_mode.
1936 */
1937 list_for_each_entry(m, &connector->modes, head) {
1938 if (hdata->is_v13)
1939 index = hdmi_v13_conf_index(m);
1940 else
1941 index = hdmi_v14_conf_index(m);
1942
1943 if (index >= 0) {
1944 DRM_INFO("desired mode doesn't exist so\n");
1945 DRM_INFO("use the most suitable mode among modes.\n");
1946 memcpy(adjusted_mode, m, sizeof(*m));
1947 break;
1948 }
1949 }
1950}
1951
741static void hdmi_mode_set(void *ctx, void *mode) 1952static void hdmi_mode_set(void *ctx, void *mode)
742{ 1953{
743 struct hdmi_context *hdata = (struct hdmi_context *)ctx; 1954 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
@@ -745,13 +1956,22 @@ static void hdmi_mode_set(void *ctx, void *mode)
745 1956
746 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1957 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
747 1958
748 conf_idx = hdmi_conf_index(mode); 1959 conf_idx = hdmi_conf_index(hdata, mode);
749 if (conf_idx >= 0 && conf_idx < ARRAY_SIZE(hdmi_confs)) 1960 if (conf_idx >= 0)
750 hdata->cur_conf = conf_idx; 1961 hdata->cur_conf = conf_idx;
751 else 1962 else
752 DRM_DEBUG_KMS("not supported mode\n"); 1963 DRM_DEBUG_KMS("not supported mode\n");
753} 1964}
754 1965
1966static void hdmi_get_max_resol(void *ctx, unsigned int *width,
1967 unsigned int *height)
1968{
1969 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
1970
1971 *width = MAX_WIDTH;
1972 *height = MAX_HEIGHT;
1973}
1974
755static void hdmi_commit(void *ctx) 1975static void hdmi_commit(void *ctx)
756{ 1976{
757 struct hdmi_context *hdata = (struct hdmi_context *)ctx; 1977 struct hdmi_context *hdata = (struct hdmi_context *)ctx;
@@ -770,13 +1990,16 @@ static void hdmi_disable(void *ctx)
770 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); 1990 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
771 1991
772 if (hdata->enabled) { 1992 if (hdata->enabled) {
1993 hdmi_audio_control(hdata, false);
773 hdmiphy_conf_reset(hdata); 1994 hdmiphy_conf_reset(hdata);
774 hdmi_conf_reset(hdata); 1995 hdmi_conf_reset(hdata);
775 } 1996 }
776} 1997}
777 1998
778static struct exynos_hdmi_manager_ops manager_ops = { 1999static struct exynos_hdmi_manager_ops manager_ops = {
2000 .mode_fixup = hdmi_mode_fixup,
779 .mode_set = hdmi_mode_set, 2001 .mode_set = hdmi_mode_set,
2002 .get_max_resol = hdmi_get_max_resol,
780 .commit = hdmi_commit, 2003 .commit = hdmi_commit,
781 .disable = hdmi_disable, 2004 .disable = hdmi_disable,
782}; 2005};
@@ -926,7 +2149,7 @@ static void hdmi_resource_poweron(struct hdmi_context *hdata)
926 hdmiphy_conf_reset(hdata); 2149 hdmiphy_conf_reset(hdata);
927 hdmi_conf_reset(hdata); 2150 hdmi_conf_reset(hdata);
928 hdmi_conf_init(hdata); 2151 hdmi_conf_init(hdata);
929 2152 hdmi_audio_init(hdata);
930} 2153}
931 2154
932static void hdmi_resource_poweroff(struct hdmi_context *hdata) 2155static void hdmi_resource_poweroff(struct hdmi_context *hdata)
@@ -978,14 +2201,12 @@ void hdmi_attach_ddc_client(struct i2c_client *ddc)
978 if (ddc) 2201 if (ddc)
979 hdmi_ddc = ddc; 2202 hdmi_ddc = ddc;
980} 2203}
981EXPORT_SYMBOL(hdmi_attach_ddc_client);
982 2204
983void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy) 2205void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy)
984{ 2206{
985 if (hdmiphy) 2207 if (hdmiphy)
986 hdmi_hdmiphy = hdmiphy; 2208 hdmi_hdmiphy = hdmiphy;
987} 2209}
988EXPORT_SYMBOL(hdmi_attach_hdmiphy_client);
989 2210
990static int __devinit hdmi_probe(struct platform_device *pdev) 2211static int __devinit hdmi_probe(struct platform_device *pdev)
991{ 2212{
@@ -1022,6 +2243,7 @@ static int __devinit hdmi_probe(struct platform_device *pdev)
1022 2243
1023 platform_set_drvdata(pdev, drm_hdmi_ctx); 2244 platform_set_drvdata(pdev, drm_hdmi_ctx);
1024 2245
2246 hdata->is_v13 = pdata->is_v13;
1025 hdata->default_win = pdata->default_win; 2247 hdata->default_win = pdata->default_win;
1026 hdata->default_timing = &pdata->timing; 2248 hdata->default_timing = &pdata->timing;
1027 hdata->default_bpp = pdata->bpp; 2249 hdata->default_bpp = pdata->bpp;
@@ -1167,10 +2389,3 @@ struct platform_driver hdmi_driver = {
1167 .pm = &hdmi_pm_ops, 2389 .pm = &hdmi_pm_ops,
1168 }, 2390 },
1169}; 2391};
1170EXPORT_SYMBOL(hdmi_driver);
1171
1172MODULE_AUTHOR("Seung-Woo Kim, <sw0312.kim@samsung.com>");
1173MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
1174MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
1175MODULE_DESCRIPTION("Samsung DRM HDMI core Driver");
1176MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.h b/drivers/gpu/drm/exynos/exynos_hdmi.h
index 31d6cf84c1aa..1c3b6d8f1fe7 100644
--- a/drivers/gpu/drm/exynos/exynos_hdmi.h
+++ b/drivers/gpu/drm/exynos/exynos_hdmi.h
@@ -28,56 +28,6 @@
28#ifndef _EXYNOS_HDMI_H_ 28#ifndef _EXYNOS_HDMI_H_
29#define _EXYNOS_HDMI_H_ 29#define _EXYNOS_HDMI_H_
30 30
31struct hdmi_conf {
32 int width;
33 int height;
34 int vrefresh;
35 bool interlace;
36 const u8 *hdmiphy_data;
37 const struct hdmi_preset_conf *conf;
38};
39
40struct hdmi_resources {
41 struct clk *hdmi;
42 struct clk *sclk_hdmi;
43 struct clk *sclk_pixel;
44 struct clk *sclk_hdmiphy;
45 struct clk *hdmiphy;
46 struct regulator_bulk_data *regul_bulk;
47 int regul_count;
48};
49
50struct hdmi_context {
51 struct device *dev;
52 struct drm_device *drm_dev;
53 struct fb_videomode *default_timing;
54 unsigned int default_win;
55 unsigned int default_bpp;
56 bool hpd_handle;
57 bool enabled;
58
59 struct resource *regs_res;
60 /** base address of HDMI registers */
61 void __iomem *regs;
62 /** HDMI hotplug interrupt */
63 unsigned int irq;
64 /** workqueue for delayed work */
65 struct workqueue_struct *wq;
66 /** hotplug handling work */
67 struct work_struct hotplug_work;
68
69 struct i2c_client *ddc_port;
70 struct i2c_client *hdmiphy_port;
71
72 /** current hdmiphy conf index */
73 int cur_conf;
74 /** other resources */
75 struct hdmi_resources res;
76
77 void *parent_ctx;
78};
79
80
81void hdmi_attach_ddc_client(struct i2c_client *ddc); 31void hdmi_attach_ddc_client(struct i2c_client *ddc);
82void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy); 32void hdmi_attach_hdmiphy_client(struct i2c_client *hdmiphy);
83 33
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index 93846e810e38..4d5f41e19527 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -36,11 +36,57 @@
36 36
37#include "exynos_drm_drv.h" 37#include "exynos_drm_drv.h"
38#include "exynos_drm_hdmi.h" 38#include "exynos_drm_hdmi.h"
39#include "exynos_hdmi.h" 39
40#include "exynos_mixer.h" 40#define HDMI_OVERLAY_NUMBER 3
41 41
42#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev)) 42#define get_mixer_context(dev) platform_get_drvdata(to_platform_device(dev))
43 43
44struct hdmi_win_data {
45 dma_addr_t dma_addr;
46 void __iomem *vaddr;
47 dma_addr_t chroma_dma_addr;
48 void __iomem *chroma_vaddr;
49 uint32_t pixel_format;
50 unsigned int bpp;
51 unsigned int crtc_x;
52 unsigned int crtc_y;
53 unsigned int crtc_width;
54 unsigned int crtc_height;
55 unsigned int fb_x;
56 unsigned int fb_y;
57 unsigned int fb_width;
58 unsigned int fb_height;
59 unsigned int mode_width;
60 unsigned int mode_height;
61 unsigned int scan_flags;
62};
63
64struct mixer_resources {
65 struct device *dev;
66 int irq;
67 void __iomem *mixer_regs;
68 void __iomem *vp_regs;
69 spinlock_t reg_slock;
70 struct clk *mixer;
71 struct clk *vp;
72 struct clk *sclk_mixer;
73 struct clk *sclk_hdmi;
74 struct clk *sclk_dac;
75};
76
77struct mixer_context {
78 struct fb_videomode *default_timing;
79 unsigned int default_win;
80 unsigned int default_bpp;
81 unsigned int irq;
82 int pipe;
83 bool interlace;
84 bool vp_enabled;
85
86 struct mixer_resources mixer_res;
87 struct hdmi_win_data win_data[HDMI_OVERLAY_NUMBER];
88};
89
44static const u8 filter_y_horiz_tap8[] = { 90static const u8 filter_y_horiz_tap8[] = {
45 0, -1, -1, -1, -1, -1, -1, -1, 91 0, -1, -1, -1, -1, -1, -1, -1,
46 -1, -1, -1, -1, -1, 0, 0, 0, 92 -1, -1, -1, -1, -1, 0, 0, 0,
@@ -1066,10 +1112,3 @@ struct platform_driver mixer_driver = {
1066 .probe = mixer_probe, 1112 .probe = mixer_probe,
1067 .remove = __devexit_p(mixer_remove), 1113 .remove = __devexit_p(mixer_remove),
1068}; 1114};
1069EXPORT_SYMBOL(mixer_driver);
1070
1071MODULE_AUTHOR("Seung-Woo Kim, <sw0312.kim@samsung.com>");
1072MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
1073MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
1074MODULE_DESCRIPTION("Samsung DRM HDMI mixer Driver");
1075MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.h b/drivers/gpu/drm/exynos/exynos_mixer.h
deleted file mode 100644
index cebacfefc077..000000000000
--- a/drivers/gpu/drm/exynos/exynos_mixer.h
+++ /dev/null
@@ -1,92 +0,0 @@
1/*
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * Authors:
5 * Seung-Woo Kim <sw0312.kim@samsung.com>
6 * Inki Dae <inki.dae@samsung.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28#ifndef _EXYNOS_MIXER_H_
29#define _EXYNOS_MIXER_H_
30
31#define HDMI_OVERLAY_NUMBER 3
32
33struct hdmi_win_data {
34 dma_addr_t dma_addr;
35 void __iomem *vaddr;
36 dma_addr_t chroma_dma_addr;
37 void __iomem *chroma_vaddr;
38 uint32_t pixel_format;
39 unsigned int bpp;
40 unsigned int crtc_x;
41 unsigned int crtc_y;
42 unsigned int crtc_width;
43 unsigned int crtc_height;
44 unsigned int fb_x;
45 unsigned int fb_y;
46 unsigned int fb_width;
47 unsigned int fb_height;
48 unsigned int mode_width;
49 unsigned int mode_height;
50 unsigned int scan_flags;
51};
52
53struct mixer_resources {
54 struct device *dev;
55 /** interrupt index */
56 int irq;
57 /** pointer to Mixer registers */
58 void __iomem *mixer_regs;
59 /** pointer to Video Processor registers */
60 void __iomem *vp_regs;
61 /** spinlock for protection of registers */
62 spinlock_t reg_slock;
63 /** other resources */
64 struct clk *mixer;
65 struct clk *vp;
66 struct clk *sclk_mixer;
67 struct clk *sclk_hdmi;
68 struct clk *sclk_dac;
69};
70
71struct mixer_context {
72 unsigned int default_win;
73 struct fb_videomode *default_timing;
74 unsigned int default_bpp;
75
76 /** mixer interrupt */
77 unsigned int irq;
78 /** current crtc pipe for vblank */
79 int pipe;
80 /** interlace scan mode */
81 bool interlace;
82 /** vp enabled status */
83 bool vp_enabled;
84
85 /** mixer and vp resources */
86 struct mixer_resources mixer_res;
87
88 /** overlay window data */
89 struct hdmi_win_data win_data[HDMI_OVERLAY_NUMBER];
90};
91
92#endif
diff --git a/drivers/gpu/drm/exynos/regs-hdmi.h b/drivers/gpu/drm/exynos/regs-hdmi.h
index 72e6b52be740..3c04bea842ce 100644
--- a/drivers/gpu/drm/exynos/regs-hdmi.h
+++ b/drivers/gpu/drm/exynos/regs-hdmi.h
@@ -19,64 +19,67 @@
19 * Register part 19 * Register part
20*/ 20*/
21 21
22/* HDMI Version 1.3 & Common */
22#define HDMI_CTRL_BASE(x) ((x) + 0x00000000) 23#define HDMI_CTRL_BASE(x) ((x) + 0x00000000)
23#define HDMI_CORE_BASE(x) ((x) + 0x00010000) 24#define HDMI_CORE_BASE(x) ((x) + 0x00010000)
25#define HDMI_I2S_BASE(x) ((x) + 0x00040000)
24#define HDMI_TG_BASE(x) ((x) + 0x00050000) 26#define HDMI_TG_BASE(x) ((x) + 0x00050000)
25 27
26/* Control registers */ 28/* Control registers */
27#define HDMI_INTC_CON HDMI_CTRL_BASE(0x0000) 29#define HDMI_INTC_CON HDMI_CTRL_BASE(0x0000)
28#define HDMI_INTC_FLAG HDMI_CTRL_BASE(0x0004) 30#define HDMI_INTC_FLAG HDMI_CTRL_BASE(0x0004)
29#define HDMI_HPD_STATUS HDMI_CTRL_BASE(0x000C) 31#define HDMI_HPD_STATUS HDMI_CTRL_BASE(0x000C)
30#define HDMI_PHY_RSTOUT HDMI_CTRL_BASE(0x0014) 32#define HDMI_V13_PHY_RSTOUT HDMI_CTRL_BASE(0x0014)
31#define HDMI_PHY_VPLL HDMI_CTRL_BASE(0x0018) 33#define HDMI_V13_PHY_VPLL HDMI_CTRL_BASE(0x0018)
32#define HDMI_PHY_CMU HDMI_CTRL_BASE(0x001C) 34#define HDMI_V13_PHY_CMU HDMI_CTRL_BASE(0x001C)
33#define HDMI_CORE_RSTOUT HDMI_CTRL_BASE(0x0020) 35#define HDMI_V13_CORE_RSTOUT HDMI_CTRL_BASE(0x0020)
34 36
35/* Core registers */ 37/* Core registers */
36#define HDMI_CON_0 HDMI_CORE_BASE(0x0000) 38#define HDMI_CON_0 HDMI_CORE_BASE(0x0000)
37#define HDMI_CON_1 HDMI_CORE_BASE(0x0004) 39#define HDMI_CON_1 HDMI_CORE_BASE(0x0004)
38#define HDMI_CON_2 HDMI_CORE_BASE(0x0008) 40#define HDMI_CON_2 HDMI_CORE_BASE(0x0008)
39#define HDMI_SYS_STATUS HDMI_CORE_BASE(0x0010) 41#define HDMI_SYS_STATUS HDMI_CORE_BASE(0x0010)
40#define HDMI_PHY_STATUS HDMI_CORE_BASE(0x0014) 42#define HDMI_V13_PHY_STATUS HDMI_CORE_BASE(0x0014)
41#define HDMI_STATUS_EN HDMI_CORE_BASE(0x0020) 43#define HDMI_STATUS_EN HDMI_CORE_BASE(0x0020)
42#define HDMI_HPD HDMI_CORE_BASE(0x0030) 44#define HDMI_HPD HDMI_CORE_BASE(0x0030)
43#define HDMI_MODE_SEL HDMI_CORE_BASE(0x0040) 45#define HDMI_MODE_SEL HDMI_CORE_BASE(0x0040)
44#define HDMI_BLUE_SCREEN_0 HDMI_CORE_BASE(0x0050) 46#define HDMI_ENC_EN HDMI_CORE_BASE(0x0044)
45#define HDMI_BLUE_SCREEN_1 HDMI_CORE_BASE(0x0054) 47#define HDMI_V13_BLUE_SCREEN_0 HDMI_CORE_BASE(0x0050)
46#define HDMI_BLUE_SCREEN_2 HDMI_CORE_BASE(0x0058) 48#define HDMI_V13_BLUE_SCREEN_1 HDMI_CORE_BASE(0x0054)
49#define HDMI_V13_BLUE_SCREEN_2 HDMI_CORE_BASE(0x0058)
47#define HDMI_H_BLANK_0 HDMI_CORE_BASE(0x00A0) 50#define HDMI_H_BLANK_0 HDMI_CORE_BASE(0x00A0)
48#define HDMI_H_BLANK_1 HDMI_CORE_BASE(0x00A4) 51#define HDMI_H_BLANK_1 HDMI_CORE_BASE(0x00A4)
49#define HDMI_V_BLANK_0 HDMI_CORE_BASE(0x00B0) 52#define HDMI_V13_V_BLANK_0 HDMI_CORE_BASE(0x00B0)
50#define HDMI_V_BLANK_1 HDMI_CORE_BASE(0x00B4) 53#define HDMI_V13_V_BLANK_1 HDMI_CORE_BASE(0x00B4)
51#define HDMI_V_BLANK_2 HDMI_CORE_BASE(0x00B8) 54#define HDMI_V13_V_BLANK_2 HDMI_CORE_BASE(0x00B8)
52#define HDMI_H_V_LINE_0 HDMI_CORE_BASE(0x00C0) 55#define HDMI_V13_H_V_LINE_0 HDMI_CORE_BASE(0x00C0)
53#define HDMI_H_V_LINE_1 HDMI_CORE_BASE(0x00C4) 56#define HDMI_V13_H_V_LINE_1 HDMI_CORE_BASE(0x00C4)
54#define HDMI_H_V_LINE_2 HDMI_CORE_BASE(0x00C8) 57#define HDMI_V13_H_V_LINE_2 HDMI_CORE_BASE(0x00C8)
55#define HDMI_VSYNC_POL HDMI_CORE_BASE(0x00E4) 58#define HDMI_VSYNC_POL HDMI_CORE_BASE(0x00E4)
56#define HDMI_INT_PRO_MODE HDMI_CORE_BASE(0x00E8) 59#define HDMI_INT_PRO_MODE HDMI_CORE_BASE(0x00E8)
57#define HDMI_V_BLANK_F_0 HDMI_CORE_BASE(0x0110) 60#define HDMI_V13_V_BLANK_F_0 HDMI_CORE_BASE(0x0110)
58#define HDMI_V_BLANK_F_1 HDMI_CORE_BASE(0x0114) 61#define HDMI_V13_V_BLANK_F_1 HDMI_CORE_BASE(0x0114)
59#define HDMI_V_BLANK_F_2 HDMI_CORE_BASE(0x0118) 62#define HDMI_V13_V_BLANK_F_2 HDMI_CORE_BASE(0x0118)
60#define HDMI_H_SYNC_GEN_0 HDMI_CORE_BASE(0x0120) 63#define HDMI_V13_H_SYNC_GEN_0 HDMI_CORE_BASE(0x0120)
61#define HDMI_H_SYNC_GEN_1 HDMI_CORE_BASE(0x0124) 64#define HDMI_V13_H_SYNC_GEN_1 HDMI_CORE_BASE(0x0124)
62#define HDMI_H_SYNC_GEN_2 HDMI_CORE_BASE(0x0128) 65#define HDMI_V13_H_SYNC_GEN_2 HDMI_CORE_BASE(0x0128)
63#define HDMI_V_SYNC_GEN_1_0 HDMI_CORE_BASE(0x0130) 66#define HDMI_V13_V_SYNC_GEN_1_0 HDMI_CORE_BASE(0x0130)
64#define HDMI_V_SYNC_GEN_1_1 HDMI_CORE_BASE(0x0134) 67#define HDMI_V13_V_SYNC_GEN_1_1 HDMI_CORE_BASE(0x0134)
65#define HDMI_V_SYNC_GEN_1_2 HDMI_CORE_BASE(0x0138) 68#define HDMI_V13_V_SYNC_GEN_1_2 HDMI_CORE_BASE(0x0138)
66#define HDMI_V_SYNC_GEN_2_0 HDMI_CORE_BASE(0x0140) 69#define HDMI_V13_V_SYNC_GEN_2_0 HDMI_CORE_BASE(0x0140)
67#define HDMI_V_SYNC_GEN_2_1 HDMI_CORE_BASE(0x0144) 70#define HDMI_V13_V_SYNC_GEN_2_1 HDMI_CORE_BASE(0x0144)
68#define HDMI_V_SYNC_GEN_2_2 HDMI_CORE_BASE(0x0148) 71#define HDMI_V13_V_SYNC_GEN_2_2 HDMI_CORE_BASE(0x0148)
69#define HDMI_V_SYNC_GEN_3_0 HDMI_CORE_BASE(0x0150) 72#define HDMI_V13_V_SYNC_GEN_3_0 HDMI_CORE_BASE(0x0150)
70#define HDMI_V_SYNC_GEN_3_1 HDMI_CORE_BASE(0x0154) 73#define HDMI_V13_V_SYNC_GEN_3_1 HDMI_CORE_BASE(0x0154)
71#define HDMI_V_SYNC_GEN_3_2 HDMI_CORE_BASE(0x0158) 74#define HDMI_V13_V_SYNC_GEN_3_2 HDMI_CORE_BASE(0x0158)
72#define HDMI_ACR_CON HDMI_CORE_BASE(0x0180) 75#define HDMI_V13_ACR_CON HDMI_CORE_BASE(0x0180)
73#define HDMI_AVI_CON HDMI_CORE_BASE(0x0300) 76#define HDMI_V13_AVI_CON HDMI_CORE_BASE(0x0300)
74#define HDMI_AVI_BYTE(n) HDMI_CORE_BASE(0x0320 + 4 * (n)) 77#define HDMI_V13_AVI_BYTE(n) HDMI_CORE_BASE(0x0320 + 4 * (n))
75#define HDMI_DC_CONTROL HDMI_CORE_BASE(0x05C0) 78#define HDMI_V13_DC_CONTROL HDMI_CORE_BASE(0x05C0)
76#define HDMI_VIDEO_PATTERN_GEN HDMI_CORE_BASE(0x05C4) 79#define HDMI_V13_VIDEO_PATTERN_GEN HDMI_CORE_BASE(0x05C4)
77#define HDMI_HPD_GEN HDMI_CORE_BASE(0x05C8) 80#define HDMI_V13_HPD_GEN HDMI_CORE_BASE(0x05C8)
78#define HDMI_AUI_CON HDMI_CORE_BASE(0x0360) 81#define HDMI_V13_AUI_CON HDMI_CORE_BASE(0x0360)
79#define HDMI_SPD_CON HDMI_CORE_BASE(0x0400) 82#define HDMI_V13_SPD_CON HDMI_CORE_BASE(0x0400)
80 83
81/* Timing generator registers */ 84/* Timing generator registers */
82#define HDMI_TG_CMD HDMI_TG_BASE(0x0000) 85#define HDMI_TG_CMD HDMI_TG_BASE(0x0000)
@@ -130,6 +133,9 @@
130 133
131/* HDMI_CON_0 */ 134/* HDMI_CON_0 */
132#define HDMI_BLUE_SCR_EN (1 << 5) 135#define HDMI_BLUE_SCR_EN (1 << 5)
136#define HDMI_ASP_EN (1 << 2)
137#define HDMI_ASP_DIS (0 << 2)
138#define HDMI_ASP_MASK (1 << 2)
133#define HDMI_EN (1 << 0) 139#define HDMI_EN (1 << 0)
134 140
135/* HDMI_PHY_STATUS */ 141/* HDMI_PHY_STATUS */
@@ -138,10 +144,418 @@
138/* HDMI_MODE_SEL */ 144/* HDMI_MODE_SEL */
139#define HDMI_MODE_HDMI_EN (1 << 1) 145#define HDMI_MODE_HDMI_EN (1 << 1)
140#define HDMI_MODE_DVI_EN (1 << 0) 146#define HDMI_MODE_DVI_EN (1 << 0)
147#define HDMI_DVI_MODE_EN (1)
148#define HDMI_DVI_MODE_DIS (0)
141#define HDMI_MODE_MASK (3 << 0) 149#define HDMI_MODE_MASK (3 << 0)
142 150
143/* HDMI_TG_CMD */ 151/* HDMI_TG_CMD */
144#define HDMI_TG_EN (1 << 0) 152#define HDMI_TG_EN (1 << 0)
145#define HDMI_FIELD_EN (1 << 1) 153#define HDMI_FIELD_EN (1 << 1)
146 154
155
156/* HDMI Version 1.4 */
157/* Control registers */
158/* #define HDMI_INTC_CON HDMI_CTRL_BASE(0x0000) */
159/* #define HDMI_INTC_FLAG HDMI_CTRL_BASE(0x0004) */
160#define HDMI_HDCP_KEY_LOAD HDMI_CTRL_BASE(0x0008)
161/* #define HDMI_HPD_STATUS HDMI_CTRL_BASE(0x000C) */
162#define HDMI_INTC_CON_1 HDMI_CTRL_BASE(0x0010)
163#define HDMI_INTC_FLAG_1 HDMI_CTRL_BASE(0x0014)
164#define HDMI_PHY_STATUS_0 HDMI_CTRL_BASE(0x0020)
165#define HDMI_PHY_STATUS_CMU HDMI_CTRL_BASE(0x0024)
166#define HDMI_PHY_STATUS_PLL HDMI_CTRL_BASE(0x0028)
167#define HDMI_PHY_CON_0 HDMI_CTRL_BASE(0x0030)
168#define HDMI_HPD_CTRL HDMI_CTRL_BASE(0x0040)
169#define HDMI_HPD_ST HDMI_CTRL_BASE(0x0044)
170#define HDMI_HPD_TH_X HDMI_CTRL_BASE(0x0050)
171#define HDMI_AUDIO_CLKSEL HDMI_CTRL_BASE(0x0070)
172#define HDMI_PHY_RSTOUT HDMI_CTRL_BASE(0x0074)
173#define HDMI_PHY_VPLL HDMI_CTRL_BASE(0x0078)
174#define HDMI_PHY_CMU HDMI_CTRL_BASE(0x007C)
175#define HDMI_CORE_RSTOUT HDMI_CTRL_BASE(0x0080)
176
177/* Video related registers */
178#define HDMI_YMAX HDMI_CORE_BASE(0x0060)
179#define HDMI_YMIN HDMI_CORE_BASE(0x0064)
180#define HDMI_CMAX HDMI_CORE_BASE(0x0068)
181#define HDMI_CMIN HDMI_CORE_BASE(0x006C)
182
183#define HDMI_V2_BLANK_0 HDMI_CORE_BASE(0x00B0)
184#define HDMI_V2_BLANK_1 HDMI_CORE_BASE(0x00B4)
185#define HDMI_V1_BLANK_0 HDMI_CORE_BASE(0x00B8)
186#define HDMI_V1_BLANK_1 HDMI_CORE_BASE(0x00BC)
187
188#define HDMI_V_LINE_0 HDMI_CORE_BASE(0x00C0)
189#define HDMI_V_LINE_1 HDMI_CORE_BASE(0x00C4)
190#define HDMI_H_LINE_0 HDMI_CORE_BASE(0x00C8)
191#define HDMI_H_LINE_1 HDMI_CORE_BASE(0x00CC)
192
193#define HDMI_HSYNC_POL HDMI_CORE_BASE(0x00E0)
194
195#define HDMI_V_BLANK_F0_0 HDMI_CORE_BASE(0x0110)
196#define HDMI_V_BLANK_F0_1 HDMI_CORE_BASE(0x0114)
197#define HDMI_V_BLANK_F1_0 HDMI_CORE_BASE(0x0118)
198#define HDMI_V_BLANK_F1_1 HDMI_CORE_BASE(0x011C)
199
200#define HDMI_H_SYNC_START_0 HDMI_CORE_BASE(0x0120)
201#define HDMI_H_SYNC_START_1 HDMI_CORE_BASE(0x0124)
202#define HDMI_H_SYNC_END_0 HDMI_CORE_BASE(0x0128)
203#define HDMI_H_SYNC_END_1 HDMI_CORE_BASE(0x012C)
204
205#define HDMI_V_SYNC_LINE_BEF_2_0 HDMI_CORE_BASE(0x0130)
206#define HDMI_V_SYNC_LINE_BEF_2_1 HDMI_CORE_BASE(0x0134)
207#define HDMI_V_SYNC_LINE_BEF_1_0 HDMI_CORE_BASE(0x0138)
208#define HDMI_V_SYNC_LINE_BEF_1_1 HDMI_CORE_BASE(0x013C)
209
210#define HDMI_V_SYNC_LINE_AFT_2_0 HDMI_CORE_BASE(0x0140)
211#define HDMI_V_SYNC_LINE_AFT_2_1 HDMI_CORE_BASE(0x0144)
212#define HDMI_V_SYNC_LINE_AFT_1_0 HDMI_CORE_BASE(0x0148)
213#define HDMI_V_SYNC_LINE_AFT_1_1 HDMI_CORE_BASE(0x014C)
214
215#define HDMI_V_SYNC_LINE_AFT_PXL_2_0 HDMI_CORE_BASE(0x0150)
216#define HDMI_V_SYNC_LINE_AFT_PXL_2_1 HDMI_CORE_BASE(0x0154)
217#define HDMI_V_SYNC_LINE_AFT_PXL_1_0 HDMI_CORE_BASE(0x0158)
218#define HDMI_V_SYNC_LINE_AFT_PXL_1_1 HDMI_CORE_BASE(0x015C)
219
220#define HDMI_V_BLANK_F2_0 HDMI_CORE_BASE(0x0160)
221#define HDMI_V_BLANK_F2_1 HDMI_CORE_BASE(0x0164)
222#define HDMI_V_BLANK_F3_0 HDMI_CORE_BASE(0x0168)
223#define HDMI_V_BLANK_F3_1 HDMI_CORE_BASE(0x016C)
224#define HDMI_V_BLANK_F4_0 HDMI_CORE_BASE(0x0170)
225#define HDMI_V_BLANK_F4_1 HDMI_CORE_BASE(0x0174)
226#define HDMI_V_BLANK_F5_0 HDMI_CORE_BASE(0x0178)
227#define HDMI_V_BLANK_F5_1 HDMI_CORE_BASE(0x017C)
228
229#define HDMI_V_SYNC_LINE_AFT_3_0 HDMI_CORE_BASE(0x0180)
230#define HDMI_V_SYNC_LINE_AFT_3_1 HDMI_CORE_BASE(0x0184)
231#define HDMI_V_SYNC_LINE_AFT_4_0 HDMI_CORE_BASE(0x0188)
232#define HDMI_V_SYNC_LINE_AFT_4_1 HDMI_CORE_BASE(0x018C)
233#define HDMI_V_SYNC_LINE_AFT_5_0 HDMI_CORE_BASE(0x0190)
234#define HDMI_V_SYNC_LINE_AFT_5_1 HDMI_CORE_BASE(0x0194)
235#define HDMI_V_SYNC_LINE_AFT_6_0 HDMI_CORE_BASE(0x0198)
236#define HDMI_V_SYNC_LINE_AFT_6_1 HDMI_CORE_BASE(0x019C)
237
238#define HDMI_V_SYNC_LINE_AFT_PXL_3_0 HDMI_CORE_BASE(0x01A0)
239#define HDMI_V_SYNC_LINE_AFT_PXL_3_1 HDMI_CORE_BASE(0x01A4)
240#define HDMI_V_SYNC_LINE_AFT_PXL_4_0 HDMI_CORE_BASE(0x01A8)
241#define HDMI_V_SYNC_LINE_AFT_PXL_4_1 HDMI_CORE_BASE(0x01AC)
242#define HDMI_V_SYNC_LINE_AFT_PXL_5_0 HDMI_CORE_BASE(0x01B0)
243#define HDMI_V_SYNC_LINE_AFT_PXL_5_1 HDMI_CORE_BASE(0x01B4)
244#define HDMI_V_SYNC_LINE_AFT_PXL_6_0 HDMI_CORE_BASE(0x01B8)
245#define HDMI_V_SYNC_LINE_AFT_PXL_6_1 HDMI_CORE_BASE(0x01BC)
246
247#define HDMI_VACT_SPACE_1_0 HDMI_CORE_BASE(0x01C0)
248#define HDMI_VACT_SPACE_1_1 HDMI_CORE_BASE(0x01C4)
249#define HDMI_VACT_SPACE_2_0 HDMI_CORE_BASE(0x01C8)
250#define HDMI_VACT_SPACE_2_1 HDMI_CORE_BASE(0x01CC)
251#define HDMI_VACT_SPACE_3_0 HDMI_CORE_BASE(0x01D0)
252#define HDMI_VACT_SPACE_3_1 HDMI_CORE_BASE(0x01D4)
253#define HDMI_VACT_SPACE_4_0 HDMI_CORE_BASE(0x01D8)
254#define HDMI_VACT_SPACE_4_1 HDMI_CORE_BASE(0x01DC)
255#define HDMI_VACT_SPACE_5_0 HDMI_CORE_BASE(0x01E0)
256#define HDMI_VACT_SPACE_5_1 HDMI_CORE_BASE(0x01E4)
257#define HDMI_VACT_SPACE_6_0 HDMI_CORE_BASE(0x01E8)
258#define HDMI_VACT_SPACE_6_1 HDMI_CORE_BASE(0x01EC)
259
260#define HDMI_GCP_CON HDMI_CORE_BASE(0x0200)
261#define HDMI_GCP_BYTE1 HDMI_CORE_BASE(0x0210)
262#define HDMI_GCP_BYTE2 HDMI_CORE_BASE(0x0214)
263#define HDMI_GCP_BYTE3 HDMI_CORE_BASE(0x0218)
264
265/* Audio related registers */
266#define HDMI_ASP_CON HDMI_CORE_BASE(0x0300)
267#define HDMI_ASP_SP_FLAT HDMI_CORE_BASE(0x0304)
268#define HDMI_ASP_CHCFG0 HDMI_CORE_BASE(0x0310)
269#define HDMI_ASP_CHCFG1 HDMI_CORE_BASE(0x0314)
270#define HDMI_ASP_CHCFG2 HDMI_CORE_BASE(0x0318)
271#define HDMI_ASP_CHCFG3 HDMI_CORE_BASE(0x031C)
272
273#define HDMI_ACR_CON HDMI_CORE_BASE(0x0400)
274#define HDMI_ACR_MCTS0 HDMI_CORE_BASE(0x0410)
275#define HDMI_ACR_MCTS1 HDMI_CORE_BASE(0x0414)
276#define HDMI_ACR_MCTS2 HDMI_CORE_BASE(0x0418)
277#define HDMI_ACR_CTS0 HDMI_CORE_BASE(0x0420)
278#define HDMI_ACR_CTS1 HDMI_CORE_BASE(0x0424)
279#define HDMI_ACR_CTS2 HDMI_CORE_BASE(0x0428)
280#define HDMI_ACR_N0 HDMI_CORE_BASE(0x0430)
281#define HDMI_ACR_N1 HDMI_CORE_BASE(0x0434)
282#define HDMI_ACR_N2 HDMI_CORE_BASE(0x0438)
283
284/* Packet related registers */
285#define HDMI_ACP_CON HDMI_CORE_BASE(0x0500)
286#define HDMI_ACP_TYPE HDMI_CORE_BASE(0x0514)
287#define HDMI_ACP_DATA(n) HDMI_CORE_BASE(0x0520 + 4 * (n))
288
289#define HDMI_ISRC_CON HDMI_CORE_BASE(0x0600)
290#define HDMI_ISRC1_HEADER1 HDMI_CORE_BASE(0x0614)
291#define HDMI_ISRC1_DATA(n) HDMI_CORE_BASE(0x0620 + 4 * (n))
292#define HDMI_ISRC2_DATA(n) HDMI_CORE_BASE(0x06A0 + 4 * (n))
293
294#define HDMI_AVI_CON HDMI_CORE_BASE(0x0700)
295#define HDMI_AVI_HEADER0 HDMI_CORE_BASE(0x0710)
296#define HDMI_AVI_HEADER1 HDMI_CORE_BASE(0x0714)
297#define HDMI_AVI_HEADER2 HDMI_CORE_BASE(0x0718)
298#define HDMI_AVI_CHECK_SUM HDMI_CORE_BASE(0x071C)
299#define HDMI_AVI_BYTE(n) HDMI_CORE_BASE(0x0720 + 4 * (n))
300
301#define HDMI_AUI_CON HDMI_CORE_BASE(0x0800)
302#define HDMI_AUI_HEADER0 HDMI_CORE_BASE(0x0810)
303#define HDMI_AUI_HEADER1 HDMI_CORE_BASE(0x0814)
304#define HDMI_AUI_HEADER2 HDMI_CORE_BASE(0x0818)
305#define HDMI_AUI_CHECK_SUM HDMI_CORE_BASE(0x081C)
306#define HDMI_AUI_BYTE(n) HDMI_CORE_BASE(0x0820 + 4 * (n))
307
308#define HDMI_MPG_CON HDMI_CORE_BASE(0x0900)
309#define HDMI_MPG_CHECK_SUM HDMI_CORE_BASE(0x091C)
310#define HDMI_MPG_DATA(n) HDMI_CORE_BASE(0x0920 + 4 * (n))
311
312#define HDMI_SPD_CON HDMI_CORE_BASE(0x0A00)
313#define HDMI_SPD_HEADER0 HDMI_CORE_BASE(0x0A10)
314#define HDMI_SPD_HEADER1 HDMI_CORE_BASE(0x0A14)
315#define HDMI_SPD_HEADER2 HDMI_CORE_BASE(0x0A18)
316#define HDMI_SPD_DATA(n) HDMI_CORE_BASE(0x0A20 + 4 * (n))
317
318#define HDMI_GAMUT_CON HDMI_CORE_BASE(0x0B00)
319#define HDMI_GAMUT_HEADER0 HDMI_CORE_BASE(0x0B10)
320#define HDMI_GAMUT_HEADER1 HDMI_CORE_BASE(0x0B14)
321#define HDMI_GAMUT_HEADER2 HDMI_CORE_BASE(0x0B18)
322#define HDMI_GAMUT_METADATA(n) HDMI_CORE_BASE(0x0B20 + 4 * (n))
323
324#define HDMI_VSI_CON HDMI_CORE_BASE(0x0C00)
325#define HDMI_VSI_HEADER0 HDMI_CORE_BASE(0x0C10)
326#define HDMI_VSI_HEADER1 HDMI_CORE_BASE(0x0C14)
327#define HDMI_VSI_HEADER2 HDMI_CORE_BASE(0x0C18)
328#define HDMI_VSI_DATA(n) HDMI_CORE_BASE(0x0C20 + 4 * (n))
329
330#define HDMI_DC_CONTROL HDMI_CORE_BASE(0x0D00)
331#define HDMI_VIDEO_PATTERN_GEN HDMI_CORE_BASE(0x0D04)
332
333#define HDMI_AN_SEED_SEL HDMI_CORE_BASE(0x0E48)
334#define HDMI_AN_SEED_0 HDMI_CORE_BASE(0x0E58)
335#define HDMI_AN_SEED_1 HDMI_CORE_BASE(0x0E5C)
336#define HDMI_AN_SEED_2 HDMI_CORE_BASE(0x0E60)
337#define HDMI_AN_SEED_3 HDMI_CORE_BASE(0x0E64)
338
339/* HDCP related registers */
340#define HDMI_HDCP_SHA1(n) HDMI_CORE_BASE(0x7000 + 4 * (n))
341#define HDMI_HDCP_KSV_LIST(n) HDMI_CORE_BASE(0x7050 + 4 * (n))
342
343#define HDMI_HDCP_KSV_LIST_CON HDMI_CORE_BASE(0x7064)
344#define HDMI_HDCP_SHA_RESULT HDMI_CORE_BASE(0x7070)
345#define HDMI_HDCP_CTRL1 HDMI_CORE_BASE(0x7080)
346#define HDMI_HDCP_CTRL2 HDMI_CORE_BASE(0x7084)
347#define HDMI_HDCP_CHECK_RESULT HDMI_CORE_BASE(0x7090)
348#define HDMI_HDCP_BKSV(n) HDMI_CORE_BASE(0x70A0 + 4 * (n))
349#define HDMI_HDCP_AKSV(n) HDMI_CORE_BASE(0x70C0 + 4 * (n))
350#define HDMI_HDCP_AN(n) HDMI_CORE_BASE(0x70E0 + 4 * (n))
351
352#define HDMI_HDCP_BCAPS HDMI_CORE_BASE(0x7100)
353#define HDMI_HDCP_BSTATUS_0 HDMI_CORE_BASE(0x7110)
354#define HDMI_HDCP_BSTATUS_1 HDMI_CORE_BASE(0x7114)
355#define HDMI_HDCP_RI_0 HDMI_CORE_BASE(0x7140)
356#define HDMI_HDCP_RI_1 HDMI_CORE_BASE(0x7144)
357#define HDMI_HDCP_I2C_INT HDMI_CORE_BASE(0x7180)
358#define HDMI_HDCP_AN_INT HDMI_CORE_BASE(0x7190)
359#define HDMI_HDCP_WDT_INT HDMI_CORE_BASE(0x71A0)
360#define HDMI_HDCP_RI_INT HDMI_CORE_BASE(0x71B0)
361#define HDMI_HDCP_RI_COMPARE_0 HDMI_CORE_BASE(0x71D0)
362#define HDMI_HDCP_RI_COMPARE_1 HDMI_CORE_BASE(0x71D4)
363#define HDMI_HDCP_FRAME_COUNT HDMI_CORE_BASE(0x71E0)
364
365#define HDMI_RGB_ROUND_EN HDMI_CORE_BASE(0xD500)
366#define HDMI_VACT_SPACE_R_0 HDMI_CORE_BASE(0xD504)
367#define HDMI_VACT_SPACE_R_1 HDMI_CORE_BASE(0xD508)
368#define HDMI_VACT_SPACE_G_0 HDMI_CORE_BASE(0xD50C)
369#define HDMI_VACT_SPACE_G_1 HDMI_CORE_BASE(0xD510)
370#define HDMI_VACT_SPACE_B_0 HDMI_CORE_BASE(0xD514)
371#define HDMI_VACT_SPACE_B_1 HDMI_CORE_BASE(0xD518)
372
373#define HDMI_BLUE_SCREEN_B_0 HDMI_CORE_BASE(0xD520)
374#define HDMI_BLUE_SCREEN_B_1 HDMI_CORE_BASE(0xD524)
375#define HDMI_BLUE_SCREEN_G_0 HDMI_CORE_BASE(0xD528)
376#define HDMI_BLUE_SCREEN_G_1 HDMI_CORE_BASE(0xD52C)
377#define HDMI_BLUE_SCREEN_R_0 HDMI_CORE_BASE(0xD530)
378#define HDMI_BLUE_SCREEN_R_1 HDMI_CORE_BASE(0xD534)
379
380/* HDMI I2S register */
381#define HDMI_I2S_CLK_CON HDMI_I2S_BASE(0x000)
382#define HDMI_I2S_CON_1 HDMI_I2S_BASE(0x004)
383#define HDMI_I2S_CON_2 HDMI_I2S_BASE(0x008)
384#define HDMI_I2S_PIN_SEL_0 HDMI_I2S_BASE(0x00c)
385#define HDMI_I2S_PIN_SEL_1 HDMI_I2S_BASE(0x010)
386#define HDMI_I2S_PIN_SEL_2 HDMI_I2S_BASE(0x014)
387#define HDMI_I2S_PIN_SEL_3 HDMI_I2S_BASE(0x018)
388#define HDMI_I2S_DSD_CON HDMI_I2S_BASE(0x01c)
389#define HDMI_I2S_MUX_CON HDMI_I2S_BASE(0x020)
390#define HDMI_I2S_CH_ST_CON HDMI_I2S_BASE(0x024)
391#define HDMI_I2S_CH_ST_0 HDMI_I2S_BASE(0x028)
392#define HDMI_I2S_CH_ST_1 HDMI_I2S_BASE(0x02c)
393#define HDMI_I2S_CH_ST_2 HDMI_I2S_BASE(0x030)
394#define HDMI_I2S_CH_ST_3 HDMI_I2S_BASE(0x034)
395#define HDMI_I2S_CH_ST_4 HDMI_I2S_BASE(0x038)
396#define HDMI_I2S_CH_ST_SH_0 HDMI_I2S_BASE(0x03c)
397#define HDMI_I2S_CH_ST_SH_1 HDMI_I2S_BASE(0x040)
398#define HDMI_I2S_CH_ST_SH_2 HDMI_I2S_BASE(0x044)
399#define HDMI_I2S_CH_ST_SH_3 HDMI_I2S_BASE(0x048)
400#define HDMI_I2S_CH_ST_SH_4 HDMI_I2S_BASE(0x04c)
401#define HDMI_I2S_MUX_CH HDMI_I2S_BASE(0x054)
402#define HDMI_I2S_MUX_CUV HDMI_I2S_BASE(0x058)
403
404/* I2S bit definition */
405
406/* I2S_CLK_CON */
407#define HDMI_I2S_CLK_DIS (0)
408#define HDMI_I2S_CLK_EN (1)
409
410/* I2S_CON_1 */
411#define HDMI_I2S_SCLK_FALLING_EDGE (0 << 1)
412#define HDMI_I2S_SCLK_RISING_EDGE (1 << 1)
413#define HDMI_I2S_L_CH_LOW_POL (0)
414#define HDMI_I2S_L_CH_HIGH_POL (1)
415
416/* I2S_CON_2 */
417#define HDMI_I2S_MSB_FIRST_MODE (0 << 6)
418#define HDMI_I2S_LSB_FIRST_MODE (1 << 6)
419#define HDMI_I2S_BIT_CH_32FS (0 << 4)
420#define HDMI_I2S_BIT_CH_48FS (1 << 4)
421#define HDMI_I2S_BIT_CH_RESERVED (2 << 4)
422#define HDMI_I2S_SDATA_16BIT (1 << 2)
423#define HDMI_I2S_SDATA_20BIT (2 << 2)
424#define HDMI_I2S_SDATA_24BIT (3 << 2)
425#define HDMI_I2S_BASIC_FORMAT (0)
426#define HDMI_I2S_L_JUST_FORMAT (2)
427#define HDMI_I2S_R_JUST_FORMAT (3)
428#define HDMI_I2S_CON_2_CLR (~(0xFF))
429#define HDMI_I2S_SET_BIT_CH(x) (((x) & 0x7) << 4)
430#define HDMI_I2S_SET_SDATA_BIT(x) (((x) & 0x7) << 2)
431
432/* I2S_PIN_SEL_0 */
433#define HDMI_I2S_SEL_SCLK(x) (((x) & 0x7) << 4)
434#define HDMI_I2S_SEL_LRCK(x) ((x) & 0x7)
435
436/* I2S_PIN_SEL_1 */
437#define HDMI_I2S_SEL_SDATA1(x) (((x) & 0x7) << 4)
438#define HDMI_I2S_SEL_SDATA2(x) ((x) & 0x7)
439
440/* I2S_PIN_SEL_2 */
441#define HDMI_I2S_SEL_SDATA3(x) (((x) & 0x7) << 4)
442#define HDMI_I2S_SEL_SDATA2(x) ((x) & 0x7)
443
444/* I2S_PIN_SEL_3 */
445#define HDMI_I2S_SEL_DSD(x) ((x) & 0x7)
446
447/* I2S_DSD_CON */
448#define HDMI_I2S_DSD_CLK_RI_EDGE (1 << 1)
449#define HDMI_I2S_DSD_CLK_FA_EDGE (0 << 1)
450#define HDMI_I2S_DSD_ENABLE (1)
451#define HDMI_I2S_DSD_DISABLE (0)
452
453/* I2S_MUX_CON */
454#define HDMI_I2S_NOISE_FILTER_ZERO (0 << 5)
455#define HDMI_I2S_NOISE_FILTER_2_STAGE (1 << 5)
456#define HDMI_I2S_NOISE_FILTER_3_STAGE (2 << 5)
457#define HDMI_I2S_NOISE_FILTER_4_STAGE (3 << 5)
458#define HDMI_I2S_NOISE_FILTER_5_STAGE (4 << 5)
459#define HDMI_I2S_IN_DISABLE (1 << 4)
460#define HDMI_I2S_IN_ENABLE (0 << 4)
461#define HDMI_I2S_AUD_SPDIF (0 << 2)
462#define HDMI_I2S_AUD_I2S (1 << 2)
463#define HDMI_I2S_AUD_DSD (2 << 2)
464#define HDMI_I2S_CUV_SPDIF_ENABLE (0 << 1)
465#define HDMI_I2S_CUV_I2S_ENABLE (1 << 1)
466#define HDMI_I2S_MUX_DISABLE (0)
467#define HDMI_I2S_MUX_ENABLE (1)
468#define HDMI_I2S_MUX_CON_CLR (~(0xFF))
469
470/* I2S_CH_ST_CON */
471#define HDMI_I2S_CH_STATUS_RELOAD (1)
472#define HDMI_I2S_CH_ST_CON_CLR (~(1))
473
474/* I2S_CH_ST_0 / I2S_CH_ST_SH_0 */
475#define HDMI_I2S_CH_STATUS_MODE_0 (0 << 6)
476#define HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH (0 << 3)
477#define HDMI_I2S_2AUD_CH_WITH_PREEMPH (1 << 3)
478#define HDMI_I2S_DEFAULT_EMPHASIS (0 << 3)
479#define HDMI_I2S_COPYRIGHT (0 << 2)
480#define HDMI_I2S_NO_COPYRIGHT (1 << 2)
481#define HDMI_I2S_LINEAR_PCM (0 << 1)
482#define HDMI_I2S_NO_LINEAR_PCM (1 << 1)
483#define HDMI_I2S_CONSUMER_FORMAT (0)
484#define HDMI_I2S_PROF_FORMAT (1)
485#define HDMI_I2S_CH_ST_0_CLR (~(0xFF))
486
487/* I2S_CH_ST_1 / I2S_CH_ST_SH_1 */
488#define HDMI_I2S_CD_PLAYER (0x00)
489#define HDMI_I2S_DAT_PLAYER (0x03)
490#define HDMI_I2S_DCC_PLAYER (0x43)
491#define HDMI_I2S_MINI_DISC_PLAYER (0x49)
492
493/* I2S_CH_ST_2 / I2S_CH_ST_SH_2 */
494#define HDMI_I2S_CHANNEL_NUM_MASK (0xF << 4)
495#define HDMI_I2S_SOURCE_NUM_MASK (0xF)
496#define HDMI_I2S_SET_CHANNEL_NUM(x) (((x) & (0xF)) << 4)
497#define HDMI_I2S_SET_SOURCE_NUM(x) ((x) & (0xF))
498
499/* I2S_CH_ST_3 / I2S_CH_ST_SH_3 */
500#define HDMI_I2S_CLK_ACCUR_LEVEL_1 (1 << 4)
501#define HDMI_I2S_CLK_ACCUR_LEVEL_2 (0 << 4)
502#define HDMI_I2S_CLK_ACCUR_LEVEL_3 (2 << 4)
503#define HDMI_I2S_SMP_FREQ_44_1 (0x0)
504#define HDMI_I2S_SMP_FREQ_48 (0x2)
505#define HDMI_I2S_SMP_FREQ_32 (0x3)
506#define HDMI_I2S_SMP_FREQ_96 (0xA)
507#define HDMI_I2S_SET_SMP_FREQ(x) ((x) & (0xF))
508
509/* I2S_CH_ST_4 / I2S_CH_ST_SH_4 */
510#define HDMI_I2S_ORG_SMP_FREQ_44_1 (0xF << 4)
511#define HDMI_I2S_ORG_SMP_FREQ_88_2 (0x7 << 4)
512#define HDMI_I2S_ORG_SMP_FREQ_22_05 (0xB << 4)
513#define HDMI_I2S_ORG_SMP_FREQ_176_4 (0x3 << 4)
514#define HDMI_I2S_WORD_LEN_NOT_DEFINE (0x0 << 1)
515#define HDMI_I2S_WORD_LEN_MAX24_20BITS (0x1 << 1)
516#define HDMI_I2S_WORD_LEN_MAX24_22BITS (0x2 << 1)
517#define HDMI_I2S_WORD_LEN_MAX24_23BITS (0x4 << 1)
518#define HDMI_I2S_WORD_LEN_MAX24_24BITS (0x5 << 1)
519#define HDMI_I2S_WORD_LEN_MAX24_21BITS (0x6 << 1)
520#define HDMI_I2S_WORD_LEN_MAX20_16BITS (0x1 << 1)
521#define HDMI_I2S_WORD_LEN_MAX20_18BITS (0x2 << 1)
522#define HDMI_I2S_WORD_LEN_MAX20_19BITS (0x4 << 1)
523#define HDMI_I2S_WORD_LEN_MAX20_20BITS (0x5 << 1)
524#define HDMI_I2S_WORD_LEN_MAX20_17BITS (0x6 << 1)
525#define HDMI_I2S_WORD_LEN_MAX_24BITS (1)
526#define HDMI_I2S_WORD_LEN_MAX_20BITS (0)
527
528/* I2S_MUX_CH */
529#define HDMI_I2S_CH3_R_EN (1 << 7)
530#define HDMI_I2S_CH3_L_EN (1 << 6)
531#define HDMI_I2S_CH3_EN (3 << 6)
532#define HDMI_I2S_CH2_R_EN (1 << 5)
533#define HDMI_I2S_CH2_L_EN (1 << 4)
534#define HDMI_I2S_CH2_EN (3 << 4)
535#define HDMI_I2S_CH1_R_EN (1 << 3)
536#define HDMI_I2S_CH1_L_EN (1 << 2)
537#define HDMI_I2S_CH1_EN (3 << 2)
538#define HDMI_I2S_CH0_R_EN (1 << 1)
539#define HDMI_I2S_CH0_L_EN (1)
540#define HDMI_I2S_CH0_EN (3)
541#define HDMI_I2S_CH_ALL_EN (0xFF)
542#define HDMI_I2S_MUX_CH_CLR (~HDMI_I2S_CH_ALL_EN)
543
544/* I2S_MUX_CUV */
545#define HDMI_I2S_CUV_R_EN (1 << 1)
546#define HDMI_I2S_CUV_L_EN (1)
547#define HDMI_I2S_CUV_RL_EN (0x03)
548
549/* I2S_CUV_L_R */
550#define HDMI_I2S_CUV_R_DATA_MASK (0x7 << 4)
551#define HDMI_I2S_CUV_L_DATA_MASK (0x7)
552
553/* Timing generator registers */
554/* TG configure/status registers */
555#define HDMI_TG_VACT_ST3_L HDMI_TG_BASE(0x0068)
556#define HDMI_TG_VACT_ST3_H HDMI_TG_BASE(0x006c)
557#define HDMI_TG_VACT_ST4_L HDMI_TG_BASE(0x0070)
558#define HDMI_TG_VACT_ST4_H HDMI_TG_BASE(0x0074)
559#define HDMI_TG_3D HDMI_TG_BASE(0x00F0)
560
147#endif /* SAMSUNG_REGS_HDMI_H */ 561#endif /* SAMSUNG_REGS_HDMI_H */