Commit d7f1642c90ab5eb2d7c48af0581c993094f97e1a

Authored by Joonyoung Shim
Committed by Inki Dae
1 parent 8dcb96b628

drm/exynos: add G2D driver

Changelog v3:
- use __u64 instead of pointer in ioctl struct.

The G2D is a 2D graphic accelerator that supports Bit Block Transfer.
This G2D driver is exynos drm specific and supports only G2D(version
4.1) of later Exynos series from Exynos4X12 because supporting DMA.

The G2D is performed by two tasks simply.
1. Configures the rendering parameters, such as foreground color and
   coordinates data by setting the drawing context registers.
2. Start the rendering process by setting thre relevant command
   registers accordingly.

The G2D version 4.1 supports DMA mode as host interface. User can make
command list to reduce HOST(ARM) loads. The contents of The command list
is setted to relevant registers of G2D by DMA.

The command list is composed Header and command sets and Tail.
- Header: The number of command set(4Bytes)
- Command set: Register offset(4Bytes) + Register data(4Bytes)
- Tail: Pointer of base address of the other command list(4Bytes)

By Tail field, the G2D can process many command lists without halt at
one go.

The G2D has following the rendering pipeline.
--> Primitive Drawing --> Rotation --> Clipping --> Bilinear Sampling
--> Color Key --> ROP --> Mask Operation --> Alpha Blending -->
Dithering --> FrameBuffer

And supports various operations from the rendering pipeline.
- copy
- fast solid color fill
- window clipping
- rotation
- flip
- 4 operand raster operation(ROP4)
- masking operation
- alpha blending
- color key
- dithering
- etc

User should make the command list to data and registers needed by
operation to use. The Exynos G2D driver only manages the command lists
received from user. Some registers needs memory base address(physical
address) of image. User doesn't know its physical address, so fills the
gem handle of that memory than address to command sets, then G2D driver
converts it to memory base address.

We adds three ioctls and one event for Exynos G2D.

- ioctls
DRM_EXYNOS_G2D_GET_VER: get the G2D hardware version
DRM_EXYNOS_G2D_SET_CMDLIST: set the command list from user to driver
DRM_EXYNOS_G2D_EXEC: execute the command lists setted to driver

- event
DRM_EXYNOS_G2D_EVENT: event to give notification completion of the
		      command list to user

Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>

Showing 7 changed files with 1079 additions and 0 deletions Inline Diff

drivers/gpu/drm/exynos/Kconfig
1 config DRM_EXYNOS 1 config 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 select DRM_KMS_HELPER 4 select DRM_KMS_HELPER
5 select FB_CFB_FILLRECT 5 select FB_CFB_FILLRECT
6 select FB_CFB_COPYAREA 6 select FB_CFB_COPYAREA
7 select FB_CFB_IMAGEBLIT 7 select FB_CFB_IMAGEBLIT
8 select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE 8 select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
9 help 9 help
10 Choose this option if you have a Samsung SoC EXYNOS chipset. 10 Choose this option if you have a Samsung SoC EXYNOS chipset.
11 If M is selected the module will be called exynosdrm. 11 If M is selected the module will be called exynosdrm.
12 12
13 config DRM_EXYNOS_DMABUF 13 config DRM_EXYNOS_DMABUF
14 bool "EXYNOS DRM DMABUF" 14 bool "EXYNOS DRM DMABUF"
15 depends on DRM_EXYNOS 15 depends on DRM_EXYNOS
16 help 16 help
17 Choose this option if you want to use DMABUF feature for DRM. 17 Choose this option if you want to use DMABUF feature for DRM.
18 18
19 config DRM_EXYNOS_FIMD 19 config DRM_EXYNOS_FIMD
20 bool "Exynos DRM FIMD" 20 bool "Exynos DRM FIMD"
21 depends on DRM_EXYNOS && !FB_S3C 21 depends on DRM_EXYNOS && !FB_S3C
22 help 22 help
23 Choose this option if you want to use Exynos FIMD for DRM. 23 Choose this option if you want to use Exynos FIMD for DRM.
24 24
25 config DRM_EXYNOS_HDMI 25 config DRM_EXYNOS_HDMI
26 bool "Exynos DRM HDMI" 26 bool "Exynos DRM HDMI"
27 depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV 27 depends on DRM_EXYNOS && !VIDEO_SAMSUNG_S5P_TV
28 help 28 help
29 Choose this option if you want to use Exynos HDMI for DRM. 29 Choose this option if you want to use Exynos HDMI for DRM.
30 30
31 config DRM_EXYNOS_VIDI 31 config DRM_EXYNOS_VIDI
32 bool "Exynos DRM Virtual Display" 32 bool "Exynos DRM Virtual Display"
33 depends on DRM_EXYNOS 33 depends on DRM_EXYNOS
34 help 34 help
35 Choose this option if you want to use Exynos VIDI for DRM. 35 Choose this option if you want to use Exynos VIDI for DRM.
36
37 config DRM_EXYNOS_G2D
38 bool "Exynos DRM G2D"
39 depends on DRM_EXYNOS
40 help
41 Choose this option if you want to use Exynos G2D for DRM.
36 42
drivers/gpu/drm/exynos/Makefile
1 # 1 #
2 # Makefile for the drm device driver. This driver provides support for the 2 # Makefile for the drm device driver. This driver provides support for the
3 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 3 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
4 4
5 ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos 5 ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
6 exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o exynos_drm_connector.o \ 6 exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o exynos_drm_connector.o \
7 exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \ 7 exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.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
11 exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o 11 exynosdrm-$(CONFIG_DRM_EXYNOS_DMABUF) += exynos_drm_dmabuf.o
12 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o 12 exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
13 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o \ 13 exynosdrm-$(CONFIG_DRM_EXYNOS_HDMI) += exynos_hdmi.o exynos_mixer.o \
14 exynos_ddc.o exynos_hdmiphy.o \ 14 exynos_ddc.o exynos_hdmiphy.o \
15 exynos_drm_hdmi.o 15 exynos_drm_hdmi.o
16 exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o 16 exynosdrm-$(CONFIG_DRM_EXYNOS_VIDI) += exynos_drm_vidi.o
17 exynosdrm-$(CONFIG_DRM_EXYNOS_G2D) += exynos_drm_g2d.o
17 18
18 obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o 19 obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o
19 20
drivers/gpu/drm/exynos/exynos_drm_drv.c
1 /* 1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 2 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
3 * Authors: 3 * Authors:
4 * Inki Dae <inki.dae@samsung.com> 4 * Inki Dae <inki.dae@samsung.com>
5 * Joonyoung Shim <jy0922.shim@samsung.com> 5 * Joonyoung Shim <jy0922.shim@samsung.com>
6 * Seung-Woo Kim <sw0312.kim@samsung.com> 6 * Seung-Woo Kim <sw0312.kim@samsung.com>
7 * 7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a 8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"), 9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation 10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 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 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: 13 * Software is furnished to do so, subject to the following conditions:
14 * 14 *
15 * The above copyright notice and this permission notice (including the next 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 16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software. 17 * Software.
18 * 18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 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, 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 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 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, 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 24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE. 25 * OTHER DEALINGS IN THE SOFTWARE.
26 */ 26 */
27 27
28 #include "drmP.h" 28 #include "drmP.h"
29 #include "drm.h" 29 #include "drm.h"
30 #include "drm_crtc_helper.h" 30 #include "drm_crtc_helper.h"
31 31
32 #include <drm/exynos_drm.h> 32 #include <drm/exynos_drm.h>
33 33
34 #include "exynos_drm_drv.h" 34 #include "exynos_drm_drv.h"
35 #include "exynos_drm_crtc.h" 35 #include "exynos_drm_crtc.h"
36 #include "exynos_drm_encoder.h" 36 #include "exynos_drm_encoder.h"
37 #include "exynos_drm_fbdev.h" 37 #include "exynos_drm_fbdev.h"
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 #include "exynos_drm_vidi.h"
42 #include "exynos_drm_dmabuf.h" 42 #include "exynos_drm_dmabuf.h"
43 #include "exynos_drm_g2d.h"
43 44
44 #define DRIVER_NAME "exynos" 45 #define DRIVER_NAME "exynos"
45 #define DRIVER_DESC "Samsung SoC DRM" 46 #define DRIVER_DESC "Samsung SoC DRM"
46 #define DRIVER_DATE "20110530" 47 #define DRIVER_DATE "20110530"
47 #define DRIVER_MAJOR 1 48 #define DRIVER_MAJOR 1
48 #define DRIVER_MINOR 0 49 #define DRIVER_MINOR 0
49 50
50 #define VBLANK_OFF_DELAY 50000 51 #define VBLANK_OFF_DELAY 50000
51 52
52 static int exynos_drm_load(struct drm_device *dev, unsigned long flags) 53 static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
53 { 54 {
54 struct exynos_drm_private *private; 55 struct exynos_drm_private *private;
55 int ret; 56 int ret;
56 int nr; 57 int nr;
57 58
58 DRM_DEBUG_DRIVER("%s\n", __FILE__); 59 DRM_DEBUG_DRIVER("%s\n", __FILE__);
59 60
60 private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL); 61 private = kzalloc(sizeof(struct exynos_drm_private), GFP_KERNEL);
61 if (!private) { 62 if (!private) {
62 DRM_ERROR("failed to allocate private\n"); 63 DRM_ERROR("failed to allocate private\n");
63 return -ENOMEM; 64 return -ENOMEM;
64 } 65 }
65 66
66 INIT_LIST_HEAD(&private->pageflip_event_list); 67 INIT_LIST_HEAD(&private->pageflip_event_list);
67 dev->dev_private = (void *)private; 68 dev->dev_private = (void *)private;
68 69
69 drm_mode_config_init(dev); 70 drm_mode_config_init(dev);
70 71
71 /* init kms poll for handling hpd */ 72 /* init kms poll for handling hpd */
72 drm_kms_helper_poll_init(dev); 73 drm_kms_helper_poll_init(dev);
73 74
74 exynos_drm_mode_config_init(dev); 75 exynos_drm_mode_config_init(dev);
75 76
76 /* 77 /*
77 * EXYNOS4 is enough to have two CRTCs and each crtc would be used 78 * EXYNOS4 is enough to have two CRTCs and each crtc would be used
78 * without dependency of hardware. 79 * without dependency of hardware.
79 */ 80 */
80 for (nr = 0; nr < MAX_CRTC; nr++) { 81 for (nr = 0; nr < MAX_CRTC; nr++) {
81 ret = exynos_drm_crtc_create(dev, nr); 82 ret = exynos_drm_crtc_create(dev, nr);
82 if (ret) 83 if (ret)
83 goto err_crtc; 84 goto err_crtc;
84 } 85 }
85 86
86 for (nr = 0; nr < MAX_PLANE; nr++) { 87 for (nr = 0; nr < MAX_PLANE; nr++) {
87 ret = exynos_plane_init(dev, nr); 88 ret = exynos_plane_init(dev, nr);
88 if (ret) 89 if (ret)
89 goto err_crtc; 90 goto err_crtc;
90 } 91 }
91 92
92 ret = drm_vblank_init(dev, MAX_CRTC); 93 ret = drm_vblank_init(dev, MAX_CRTC);
93 if (ret) 94 if (ret)
94 goto err_crtc; 95 goto err_crtc;
95 96
96 /* 97 /*
97 * probe sub drivers such as display controller and hdmi driver, 98 * probe sub drivers such as display controller and hdmi driver,
98 * that were registered at probe() of platform driver 99 * that were registered at probe() of platform driver
99 * to the sub driver and create encoder and connector for them. 100 * to the sub driver and create encoder and connector for them.
100 */ 101 */
101 ret = exynos_drm_device_register(dev); 102 ret = exynos_drm_device_register(dev);
102 if (ret) 103 if (ret)
103 goto err_vblank; 104 goto err_vblank;
104 105
105 /* setup possible_clones. */ 106 /* setup possible_clones. */
106 exynos_drm_encoder_setup(dev); 107 exynos_drm_encoder_setup(dev);
107 108
108 /* 109 /*
109 * create and configure fb helper and also exynos specific 110 * create and configure fb helper and also exynos specific
110 * fbdev object. 111 * fbdev object.
111 */ 112 */
112 ret = exynos_drm_fbdev_init(dev); 113 ret = exynos_drm_fbdev_init(dev);
113 if (ret) { 114 if (ret) {
114 DRM_ERROR("failed to initialize drm fbdev\n"); 115 DRM_ERROR("failed to initialize drm fbdev\n");
115 goto err_drm_device; 116 goto err_drm_device;
116 } 117 }
117 118
118 drm_vblank_offdelay = VBLANK_OFF_DELAY; 119 drm_vblank_offdelay = VBLANK_OFF_DELAY;
119 120
120 return 0; 121 return 0;
121 122
122 err_drm_device: 123 err_drm_device:
123 exynos_drm_device_unregister(dev); 124 exynos_drm_device_unregister(dev);
124 err_vblank: 125 err_vblank:
125 drm_vblank_cleanup(dev); 126 drm_vblank_cleanup(dev);
126 err_crtc: 127 err_crtc:
127 drm_mode_config_cleanup(dev); 128 drm_mode_config_cleanup(dev);
128 kfree(private); 129 kfree(private);
129 130
130 return ret; 131 return ret;
131 } 132 }
132 133
133 static int exynos_drm_unload(struct drm_device *dev) 134 static int exynos_drm_unload(struct drm_device *dev)
134 { 135 {
135 DRM_DEBUG_DRIVER("%s\n", __FILE__); 136 DRM_DEBUG_DRIVER("%s\n", __FILE__);
136 137
137 exynos_drm_fbdev_fini(dev); 138 exynos_drm_fbdev_fini(dev);
138 exynos_drm_device_unregister(dev); 139 exynos_drm_device_unregister(dev);
139 drm_vblank_cleanup(dev); 140 drm_vblank_cleanup(dev);
140 drm_kms_helper_poll_fini(dev); 141 drm_kms_helper_poll_fini(dev);
141 drm_mode_config_cleanup(dev); 142 drm_mode_config_cleanup(dev);
142 kfree(dev->dev_private); 143 kfree(dev->dev_private);
143 144
144 dev->dev_private = NULL; 145 dev->dev_private = NULL;
145 146
146 return 0; 147 return 0;
147 } 148 }
148 149
149 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) 150 static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
150 { 151 {
152 struct drm_exynos_file_private *file_priv;
153
151 DRM_DEBUG_DRIVER("%s\n", __FILE__); 154 DRM_DEBUG_DRIVER("%s\n", __FILE__);
152 155
156 file_priv = kzalloc(sizeof(*file_priv), GFP_KERNEL);
157 if (!file_priv)
158 return -ENOMEM;
159
153 drm_prime_init_file_private(&file->prime); 160 drm_prime_init_file_private(&file->prime);
161 file->driver_priv = file_priv;
154 162
155 return exynos_drm_subdrv_open(dev, file); 163 return exynos_drm_subdrv_open(dev, file);
156 } 164 }
157 165
158 static void exynos_drm_preclose(struct drm_device *dev, 166 static void exynos_drm_preclose(struct drm_device *dev,
159 struct drm_file *file) 167 struct drm_file *file)
160 { 168 {
161 struct exynos_drm_private *private = dev->dev_private; 169 struct exynos_drm_private *private = dev->dev_private;
162 struct drm_pending_vblank_event *e, *t; 170 struct drm_pending_vblank_event *e, *t;
163 unsigned long flags; 171 unsigned long flags;
164 172
165 DRM_DEBUG_DRIVER("%s\n", __FILE__); 173 DRM_DEBUG_DRIVER("%s\n", __FILE__);
166 174
167 /* release events of current file */ 175 /* release events of current file */
168 spin_lock_irqsave(&dev->event_lock, flags); 176 spin_lock_irqsave(&dev->event_lock, flags);
169 list_for_each_entry_safe(e, t, &private->pageflip_event_list, 177 list_for_each_entry_safe(e, t, &private->pageflip_event_list,
170 base.link) { 178 base.link) {
171 if (e->base.file_priv == file) { 179 if (e->base.file_priv == file) {
172 list_del(&e->base.link); 180 list_del(&e->base.link);
173 e->base.destroy(&e->base); 181 e->base.destroy(&e->base);
174 } 182 }
175 } 183 }
176 drm_prime_destroy_file_private(&file->prime); 184 drm_prime_destroy_file_private(&file->prime);
177 spin_unlock_irqrestore(&dev->event_lock, flags); 185 spin_unlock_irqrestore(&dev->event_lock, flags);
178 186
179 exynos_drm_subdrv_close(dev, file); 187 exynos_drm_subdrv_close(dev, file);
180 } 188 }
181 189
182 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) 190 static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
183 { 191 {
184 DRM_DEBUG_DRIVER("%s\n", __FILE__); 192 DRM_DEBUG_DRIVER("%s\n", __FILE__);
185 193
186 if (!file->driver_priv) 194 if (!file->driver_priv)
187 return; 195 return;
188 196
189 kfree(file->driver_priv); 197 kfree(file->driver_priv);
190 file->driver_priv = NULL; 198 file->driver_priv = NULL;
191 } 199 }
192 200
193 static void exynos_drm_lastclose(struct drm_device *dev) 201 static void exynos_drm_lastclose(struct drm_device *dev)
194 { 202 {
195 DRM_DEBUG_DRIVER("%s\n", __FILE__); 203 DRM_DEBUG_DRIVER("%s\n", __FILE__);
196 204
197 exynos_drm_fbdev_restore_mode(dev); 205 exynos_drm_fbdev_restore_mode(dev);
198 } 206 }
199 207
200 static struct vm_operations_struct exynos_drm_gem_vm_ops = { 208 static struct vm_operations_struct exynos_drm_gem_vm_ops = {
201 .fault = exynos_drm_gem_fault, 209 .fault = exynos_drm_gem_fault,
202 .open = drm_gem_vm_open, 210 .open = drm_gem_vm_open,
203 .close = drm_gem_vm_close, 211 .close = drm_gem_vm_close,
204 }; 212 };
205 213
206 static struct drm_ioctl_desc exynos_ioctls[] = { 214 static struct drm_ioctl_desc exynos_ioctls[] = {
207 DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl, 215 DRM_IOCTL_DEF_DRV(EXYNOS_GEM_CREATE, exynos_drm_gem_create_ioctl,
208 DRM_UNLOCKED | DRM_AUTH), 216 DRM_UNLOCKED | DRM_AUTH),
209 DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP_OFFSET, 217 DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MAP_OFFSET,
210 exynos_drm_gem_map_offset_ioctl, DRM_UNLOCKED | 218 exynos_drm_gem_map_offset_ioctl, DRM_UNLOCKED |
211 DRM_AUTH), 219 DRM_AUTH),
212 DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MMAP, 220 DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MMAP,
213 exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH), 221 exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
214 DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET, 222 DRM_IOCTL_DEF_DRV(EXYNOS_GEM_GET,
215 exynos_drm_gem_get_ioctl, DRM_UNLOCKED), 223 exynos_drm_gem_get_ioctl, DRM_UNLOCKED),
216 DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl, 224 DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
217 DRM_UNLOCKED | DRM_AUTH), 225 DRM_UNLOCKED | DRM_AUTH),
218 DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION, 226 DRM_IOCTL_DEF_DRV(EXYNOS_VIDI_CONNECTION,
219 vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH), 227 vidi_connection_ioctl, DRM_UNLOCKED | DRM_AUTH),
228 DRM_IOCTL_DEF_DRV(EXYNOS_G2D_GET_VER,
229 exynos_g2d_get_ver_ioctl, DRM_UNLOCKED | DRM_AUTH),
230 DRM_IOCTL_DEF_DRV(EXYNOS_G2D_SET_CMDLIST,
231 exynos_g2d_set_cmdlist_ioctl, DRM_UNLOCKED | DRM_AUTH),
232 DRM_IOCTL_DEF_DRV(EXYNOS_G2D_EXEC,
233 exynos_g2d_exec_ioctl, DRM_UNLOCKED | DRM_AUTH),
220 }; 234 };
221 235
222 static const struct file_operations exynos_drm_driver_fops = { 236 static const struct file_operations exynos_drm_driver_fops = {
223 .owner = THIS_MODULE, 237 .owner = THIS_MODULE,
224 .open = drm_open, 238 .open = drm_open,
225 .mmap = exynos_drm_gem_mmap, 239 .mmap = exynos_drm_gem_mmap,
226 .poll = drm_poll, 240 .poll = drm_poll,
227 .read = drm_read, 241 .read = drm_read,
228 .unlocked_ioctl = drm_ioctl, 242 .unlocked_ioctl = drm_ioctl,
229 .release = drm_release, 243 .release = drm_release,
230 }; 244 };
231 245
232 static struct drm_driver exynos_drm_driver = { 246 static struct drm_driver exynos_drm_driver = {
233 .driver_features = DRIVER_HAVE_IRQ | DRIVER_BUS_PLATFORM | 247 .driver_features = DRIVER_HAVE_IRQ | DRIVER_BUS_PLATFORM |
234 DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, 248 DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME,
235 .load = exynos_drm_load, 249 .load = exynos_drm_load,
236 .unload = exynos_drm_unload, 250 .unload = exynos_drm_unload,
237 .open = exynos_drm_open, 251 .open = exynos_drm_open,
238 .preclose = exynos_drm_preclose, 252 .preclose = exynos_drm_preclose,
239 .lastclose = exynos_drm_lastclose, 253 .lastclose = exynos_drm_lastclose,
240 .postclose = exynos_drm_postclose, 254 .postclose = exynos_drm_postclose,
241 .get_vblank_counter = drm_vblank_count, 255 .get_vblank_counter = drm_vblank_count,
242 .enable_vblank = exynos_drm_crtc_enable_vblank, 256 .enable_vblank = exynos_drm_crtc_enable_vblank,
243 .disable_vblank = exynos_drm_crtc_disable_vblank, 257 .disable_vblank = exynos_drm_crtc_disable_vblank,
244 .gem_init_object = exynos_drm_gem_init_object, 258 .gem_init_object = exynos_drm_gem_init_object,
245 .gem_free_object = exynos_drm_gem_free_object, 259 .gem_free_object = exynos_drm_gem_free_object,
246 .gem_vm_ops = &exynos_drm_gem_vm_ops, 260 .gem_vm_ops = &exynos_drm_gem_vm_ops,
247 .dumb_create = exynos_drm_gem_dumb_create, 261 .dumb_create = exynos_drm_gem_dumb_create,
248 .dumb_map_offset = exynos_drm_gem_dumb_map_offset, 262 .dumb_map_offset = exynos_drm_gem_dumb_map_offset,
249 .dumb_destroy = exynos_drm_gem_dumb_destroy, 263 .dumb_destroy = exynos_drm_gem_dumb_destroy,
250 .prime_handle_to_fd = drm_gem_prime_handle_to_fd, 264 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
251 .prime_fd_to_handle = drm_gem_prime_fd_to_handle, 265 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
252 .gem_prime_export = exynos_dmabuf_prime_export, 266 .gem_prime_export = exynos_dmabuf_prime_export,
253 .gem_prime_import = exynos_dmabuf_prime_import, 267 .gem_prime_import = exynos_dmabuf_prime_import,
254 .ioctls = exynos_ioctls, 268 .ioctls = exynos_ioctls,
255 .fops = &exynos_drm_driver_fops, 269 .fops = &exynos_drm_driver_fops,
256 .name = DRIVER_NAME, 270 .name = DRIVER_NAME,
257 .desc = DRIVER_DESC, 271 .desc = DRIVER_DESC,
258 .date = DRIVER_DATE, 272 .date = DRIVER_DATE,
259 .major = DRIVER_MAJOR, 273 .major = DRIVER_MAJOR,
260 .minor = DRIVER_MINOR, 274 .minor = DRIVER_MINOR,
261 }; 275 };
262 276
263 static int exynos_drm_platform_probe(struct platform_device *pdev) 277 static int exynos_drm_platform_probe(struct platform_device *pdev)
264 { 278 {
265 DRM_DEBUG_DRIVER("%s\n", __FILE__); 279 DRM_DEBUG_DRIVER("%s\n", __FILE__);
266 280
267 exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls); 281 exynos_drm_driver.num_ioctls = DRM_ARRAY_SIZE(exynos_ioctls);
268 282
269 return drm_platform_init(&exynos_drm_driver, pdev); 283 return drm_platform_init(&exynos_drm_driver, pdev);
270 } 284 }
271 285
272 static int exynos_drm_platform_remove(struct platform_device *pdev) 286 static int exynos_drm_platform_remove(struct platform_device *pdev)
273 { 287 {
274 DRM_DEBUG_DRIVER("%s\n", __FILE__); 288 DRM_DEBUG_DRIVER("%s\n", __FILE__);
275 289
276 drm_platform_exit(&exynos_drm_driver, pdev); 290 drm_platform_exit(&exynos_drm_driver, pdev);
277 291
278 return 0; 292 return 0;
279 } 293 }
280 294
281 static struct platform_driver exynos_drm_platform_driver = { 295 static struct platform_driver exynos_drm_platform_driver = {
282 .probe = exynos_drm_platform_probe, 296 .probe = exynos_drm_platform_probe,
283 .remove = __devexit_p(exynos_drm_platform_remove), 297 .remove = __devexit_p(exynos_drm_platform_remove),
284 .driver = { 298 .driver = {
285 .owner = THIS_MODULE, 299 .owner = THIS_MODULE,
286 .name = "exynos-drm", 300 .name = "exynos-drm",
287 }, 301 },
288 }; 302 };
289 303
290 static int __init exynos_drm_init(void) 304 static int __init exynos_drm_init(void)
291 { 305 {
292 int ret; 306 int ret;
293 307
294 DRM_DEBUG_DRIVER("%s\n", __FILE__); 308 DRM_DEBUG_DRIVER("%s\n", __FILE__);
295 309
296 #ifdef CONFIG_DRM_EXYNOS_FIMD 310 #ifdef CONFIG_DRM_EXYNOS_FIMD
297 ret = platform_driver_register(&fimd_driver); 311 ret = platform_driver_register(&fimd_driver);
298 if (ret < 0) 312 if (ret < 0)
299 goto out_fimd; 313 goto out_fimd;
300 #endif 314 #endif
301 315
302 #ifdef CONFIG_DRM_EXYNOS_HDMI 316 #ifdef CONFIG_DRM_EXYNOS_HDMI
303 ret = platform_driver_register(&hdmi_driver); 317 ret = platform_driver_register(&hdmi_driver);
304 if (ret < 0) 318 if (ret < 0)
305 goto out_hdmi; 319 goto out_hdmi;
306 ret = platform_driver_register(&mixer_driver); 320 ret = platform_driver_register(&mixer_driver);
307 if (ret < 0) 321 if (ret < 0)
308 goto out_mixer; 322 goto out_mixer;
309 ret = platform_driver_register(&exynos_drm_common_hdmi_driver); 323 ret = platform_driver_register(&exynos_drm_common_hdmi_driver);
310 if (ret < 0) 324 if (ret < 0)
311 goto out_common_hdmi; 325 goto out_common_hdmi;
312 #endif 326 #endif
313 327
314 #ifdef CONFIG_DRM_EXYNOS_VIDI 328 #ifdef CONFIG_DRM_EXYNOS_VIDI
315 ret = platform_driver_register(&vidi_driver); 329 ret = platform_driver_register(&vidi_driver);
316 if (ret < 0) 330 if (ret < 0)
317 goto out_vidi; 331 goto out_vidi;
318 #endif 332 #endif
319 333
334 #ifdef CONFIG_DRM_EXYNOS_G2D
335 ret = platform_driver_register(&g2d_driver);
336 if (ret < 0)
337 goto out_g2d;
338 #endif
339
320 ret = platform_driver_register(&exynos_drm_platform_driver); 340 ret = platform_driver_register(&exynos_drm_platform_driver);
321 if (ret < 0) 341 if (ret < 0)
322 goto out; 342 goto out;
323 343
324 return 0; 344 return 0;
325 345
326 out: 346 out:
347 #ifdef CONFIG_DRM_EXYNOS_G2D
348 platform_driver_unregister(&g2d_driver);
349 out_g2d:
350 #endif
351
327 #ifdef CONFIG_DRM_EXYNOS_VIDI 352 #ifdef CONFIG_DRM_EXYNOS_VIDI
328 out_vidi: 353 out_vidi:
329 platform_driver_unregister(&vidi_driver); 354 platform_driver_unregister(&vidi_driver);
330 #endif 355 #endif
331 356
332 #ifdef CONFIG_DRM_EXYNOS_HDMI 357 #ifdef CONFIG_DRM_EXYNOS_HDMI
333 platform_driver_unregister(&exynos_drm_common_hdmi_driver); 358 platform_driver_unregister(&exynos_drm_common_hdmi_driver);
334 out_common_hdmi: 359 out_common_hdmi:
335 platform_driver_unregister(&mixer_driver); 360 platform_driver_unregister(&mixer_driver);
336 out_mixer: 361 out_mixer:
337 platform_driver_unregister(&hdmi_driver); 362 platform_driver_unregister(&hdmi_driver);
338 out_hdmi: 363 out_hdmi:
339 #endif 364 #endif
340 365
341 #ifdef CONFIG_DRM_EXYNOS_FIMD 366 #ifdef CONFIG_DRM_EXYNOS_FIMD
342 platform_driver_unregister(&fimd_driver); 367 platform_driver_unregister(&fimd_driver);
343 out_fimd: 368 out_fimd:
344 #endif 369 #endif
345 return ret; 370 return ret;
346 } 371 }
347 372
348 static void __exit exynos_drm_exit(void) 373 static void __exit exynos_drm_exit(void)
349 { 374 {
350 DRM_DEBUG_DRIVER("%s\n", __FILE__); 375 DRM_DEBUG_DRIVER("%s\n", __FILE__);
351 376
352 platform_driver_unregister(&exynos_drm_platform_driver); 377 platform_driver_unregister(&exynos_drm_platform_driver);
378
379 #ifdef CONFIG_DRM_EXYNOS_G2D
380 platform_driver_unregister(&g2d_driver);
381 #endif
353 382
354 #ifdef CONFIG_DRM_EXYNOS_HDMI 383 #ifdef CONFIG_DRM_EXYNOS_HDMI
355 platform_driver_unregister(&exynos_drm_common_hdmi_driver); 384 platform_driver_unregister(&exynos_drm_common_hdmi_driver);
356 platform_driver_unregister(&mixer_driver); 385 platform_driver_unregister(&mixer_driver);
357 platform_driver_unregister(&hdmi_driver); 386 platform_driver_unregister(&hdmi_driver);
358 #endif 387 #endif
359 388
360 #ifdef CONFIG_DRM_EXYNOS_VIDI 389 #ifdef CONFIG_DRM_EXYNOS_VIDI
361 platform_driver_unregister(&vidi_driver); 390 platform_driver_unregister(&vidi_driver);
362 #endif 391 #endif
363 392
364 #ifdef CONFIG_DRM_EXYNOS_FIMD 393 #ifdef CONFIG_DRM_EXYNOS_FIMD
365 platform_driver_unregister(&fimd_driver); 394 platform_driver_unregister(&fimd_driver);
366 #endif 395 #endif
367 } 396 }
368 397
369 module_init(exynos_drm_init); 398 module_init(exynos_drm_init);
370 module_exit(exynos_drm_exit); 399 module_exit(exynos_drm_exit);
371 400
372 MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); 401 MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
373 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 402 MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
374 MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>"); 403 MODULE_AUTHOR("Seung-Woo Kim <sw0312.kim@samsung.com>");
375 MODULE_DESCRIPTION("Samsung SoC DRM Driver"); 404 MODULE_DESCRIPTION("Samsung SoC DRM Driver");
376 MODULE_LICENSE("GPL"); 405 MODULE_LICENSE("GPL");
377 406
drivers/gpu/drm/exynos/exynos_drm_drv.h
1 /* exynos_drm_drv.h 1 /* exynos_drm_drv.h
2 * 2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * Authors: 4 * Authors:
5 * Inki Dae <inki.dae@samsung.com> 5 * Inki Dae <inki.dae@samsung.com>
6 * Joonyoung Shim <jy0922.shim@samsung.com> 6 * Joonyoung Shim <jy0922.shim@samsung.com>
7 * Seung-Woo Kim <sw0312.kim@samsung.com> 7 * Seung-Woo Kim <sw0312.kim@samsung.com>
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a 9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"), 10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation 11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the 13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions: 14 * Software is furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice (including the next 16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the 17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software. 18 * Software.
19 * 19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 23 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 * OTHER DEALINGS IN THE SOFTWARE. 26 * OTHER DEALINGS IN THE SOFTWARE.
27 */ 27 */
28 28
29 #ifndef _EXYNOS_DRM_DRV_H_ 29 #ifndef _EXYNOS_DRM_DRV_H_
30 #define _EXYNOS_DRM_DRV_H_ 30 #define _EXYNOS_DRM_DRV_H_
31 31
32 #include <linux/module.h> 32 #include <linux/module.h>
33 #include "drm.h" 33 #include "drm.h"
34 34
35 #define MAX_CRTC 3 35 #define MAX_CRTC 3
36 #define MAX_PLANE 5 36 #define MAX_PLANE 5
37 #define MAX_FB_BUFFER 4 37 #define MAX_FB_BUFFER 4
38 #define DEFAULT_ZPOS -1 38 #define DEFAULT_ZPOS -1
39 39
40 struct drm_device; 40 struct drm_device;
41 struct exynos_drm_overlay; 41 struct exynos_drm_overlay;
42 struct drm_connector; 42 struct drm_connector;
43 43
44 extern unsigned int drm_vblank_offdelay; 44 extern unsigned int drm_vblank_offdelay;
45 45
46 /* this enumerates display type. */ 46 /* this enumerates display type. */
47 enum exynos_drm_output_type { 47 enum exynos_drm_output_type {
48 EXYNOS_DISPLAY_TYPE_NONE, 48 EXYNOS_DISPLAY_TYPE_NONE,
49 /* RGB or CPU Interface. */ 49 /* RGB or CPU Interface. */
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. */ 53 /* Virtual Display Interface. */
54 EXYNOS_DISPLAY_TYPE_VIDI, 54 EXYNOS_DISPLAY_TYPE_VIDI,
55 }; 55 };
56 56
57 /* 57 /*
58 * Exynos drm overlay ops structure. 58 * Exynos drm overlay ops structure.
59 * 59 *
60 * @mode_set: copy drm overlay info to hw specific overlay info. 60 * @mode_set: copy drm overlay info to hw specific overlay info.
61 * @commit: apply hardware specific overlay data to registers. 61 * @commit: apply hardware specific overlay data to registers.
62 * @disable: disable hardware specific overlay. 62 * @disable: disable hardware specific overlay.
63 */ 63 */
64 struct exynos_drm_overlay_ops { 64 struct exynos_drm_overlay_ops {
65 void (*mode_set)(struct device *subdrv_dev, 65 void (*mode_set)(struct device *subdrv_dev,
66 struct exynos_drm_overlay *overlay); 66 struct exynos_drm_overlay *overlay);
67 void (*commit)(struct device *subdrv_dev, int zpos); 67 void (*commit)(struct device *subdrv_dev, int zpos);
68 void (*disable)(struct device *subdrv_dev, int zpos); 68 void (*disable)(struct device *subdrv_dev, int zpos);
69 }; 69 };
70 70
71 /* 71 /*
72 * Exynos drm common overlay structure. 72 * Exynos drm common overlay structure.
73 * 73 *
74 * @fb_x: offset x on a framebuffer to be displayed. 74 * @fb_x: offset x on a framebuffer to be displayed.
75 * - the unit is screen coordinates. 75 * - the unit is screen coordinates.
76 * @fb_y: offset y on a framebuffer to be displayed. 76 * @fb_y: offset y on a framebuffer to be displayed.
77 * - the unit is screen coordinates. 77 * - the unit is screen coordinates.
78 * @fb_width: width of a framebuffer. 78 * @fb_width: width of a framebuffer.
79 * @fb_height: height of a framebuffer. 79 * @fb_height: height of a framebuffer.
80 * @src_width: width of a partial image to be displayed from framebuffer. 80 * @src_width: width of a partial image to be displayed from framebuffer.
81 * @src_height: height of a partial image to be displayed from framebuffer. 81 * @src_height: height of a partial image to be displayed from framebuffer.
82 * @crtc_x: offset x on hardware screen. 82 * @crtc_x: offset x on hardware screen.
83 * @crtc_y: offset y on hardware screen. 83 * @crtc_y: offset y on hardware screen.
84 * @crtc_width: window width to be displayed (hardware screen). 84 * @crtc_width: window width to be displayed (hardware screen).
85 * @crtc_height: window height to be displayed (hardware screen). 85 * @crtc_height: window height to be displayed (hardware screen).
86 * @mode_width: width of screen mode. 86 * @mode_width: width of screen mode.
87 * @mode_height: height of screen mode. 87 * @mode_height: height of screen mode.
88 * @refresh: refresh rate. 88 * @refresh: refresh rate.
89 * @scan_flag: interlace or progressive way. 89 * @scan_flag: interlace or progressive way.
90 * (it could be DRM_MODE_FLAG_*) 90 * (it could be DRM_MODE_FLAG_*)
91 * @bpp: pixel size.(in bit) 91 * @bpp: pixel size.(in bit)
92 * @pixel_format: fourcc pixel format of this overlay 92 * @pixel_format: fourcc pixel format of this overlay
93 * @dma_addr: array of bus(accessed by dma) address to the memory region 93 * @dma_addr: array of bus(accessed by dma) address to the memory region
94 * allocated for a overlay. 94 * allocated for a overlay.
95 * @vaddr: array of virtual memory addresss to this overlay. 95 * @vaddr: array of virtual memory addresss to this overlay.
96 * @zpos: order of overlay layer(z position). 96 * @zpos: order of overlay layer(z position).
97 * @default_win: a window to be enabled. 97 * @default_win: a window to be enabled.
98 * @color_key: color key on or off. 98 * @color_key: color key on or off.
99 * @index_color: if using color key feature then this value would be used 99 * @index_color: if using color key feature then this value would be used
100 * as index color. 100 * as index color.
101 * @local_path: in case of lcd type, local path mode on or off. 101 * @local_path: in case of lcd type, local path mode on or off.
102 * @transparency: transparency on or off. 102 * @transparency: transparency on or off.
103 * @activated: activated or not. 103 * @activated: activated or not.
104 * 104 *
105 * this structure is common to exynos SoC and its contents would be copied 105 * this structure is common to exynos SoC and its contents would be copied
106 * to hardware specific overlay info. 106 * to hardware specific overlay info.
107 */ 107 */
108 struct exynos_drm_overlay { 108 struct exynos_drm_overlay {
109 unsigned int fb_x; 109 unsigned int fb_x;
110 unsigned int fb_y; 110 unsigned int fb_y;
111 unsigned int fb_width; 111 unsigned int fb_width;
112 unsigned int fb_height; 112 unsigned int fb_height;
113 unsigned int src_width; 113 unsigned int src_width;
114 unsigned int src_height; 114 unsigned int src_height;
115 unsigned int crtc_x; 115 unsigned int crtc_x;
116 unsigned int crtc_y; 116 unsigned int crtc_y;
117 unsigned int crtc_width; 117 unsigned int crtc_width;
118 unsigned int crtc_height; 118 unsigned int crtc_height;
119 unsigned int mode_width; 119 unsigned int mode_width;
120 unsigned int mode_height; 120 unsigned int mode_height;
121 unsigned int refresh; 121 unsigned int refresh;
122 unsigned int scan_flag; 122 unsigned int scan_flag;
123 unsigned int bpp; 123 unsigned int bpp;
124 unsigned int pitch; 124 unsigned int pitch;
125 uint32_t pixel_format; 125 uint32_t pixel_format;
126 dma_addr_t dma_addr[MAX_FB_BUFFER]; 126 dma_addr_t dma_addr[MAX_FB_BUFFER];
127 void __iomem *vaddr[MAX_FB_BUFFER]; 127 void __iomem *vaddr[MAX_FB_BUFFER];
128 int zpos; 128 int zpos;
129 129
130 bool default_win; 130 bool default_win;
131 bool color_key; 131 bool color_key;
132 unsigned int index_color; 132 unsigned int index_color;
133 bool local_path; 133 bool local_path;
134 bool transparency; 134 bool transparency;
135 bool activated; 135 bool activated;
136 }; 136 };
137 137
138 /* 138 /*
139 * Exynos DRM Display Structure. 139 * Exynos DRM Display Structure.
140 * - this structure is common to analog tv, digital tv and lcd panel. 140 * - this structure is common to analog tv, digital tv and lcd panel.
141 * 141 *
142 * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. 142 * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
143 * @is_connected: check for that display is connected or not. 143 * @is_connected: check for that display is connected or not.
144 * @get_edid: get edid modes from display driver. 144 * @get_edid: get edid modes from display driver.
145 * @get_panel: get panel object from display driver. 145 * @get_panel: get panel object from display driver.
146 * @check_timing: check if timing is valid or not. 146 * @check_timing: check if timing is valid or not.
147 * @power_on: display device on or off. 147 * @power_on: display device on or off.
148 */ 148 */
149 struct exynos_drm_display_ops { 149 struct exynos_drm_display_ops {
150 enum exynos_drm_output_type type; 150 enum exynos_drm_output_type type;
151 bool (*is_connected)(struct device *dev); 151 bool (*is_connected)(struct device *dev);
152 int (*get_edid)(struct device *dev, struct drm_connector *connector, 152 int (*get_edid)(struct device *dev, struct drm_connector *connector,
153 u8 *edid, int len); 153 u8 *edid, int len);
154 void *(*get_panel)(struct device *dev); 154 void *(*get_panel)(struct device *dev);
155 int (*check_timing)(struct device *dev, void *timing); 155 int (*check_timing)(struct device *dev, void *timing);
156 int (*power_on)(struct device *dev, int mode); 156 int (*power_on)(struct device *dev, int mode);
157 }; 157 };
158 158
159 /* 159 /*
160 * Exynos drm manager ops 160 * Exynos drm manager ops
161 * 161 *
162 * @dpms: control device power. 162 * @dpms: control device power.
163 * @apply: set timing, vblank and overlay data to registers. 163 * @apply: set timing, vblank and overlay data to registers.
164 * @mode_fixup: fix mode data comparing to hw specific display mode. 164 * @mode_fixup: fix mode data comparing to hw specific display mode.
165 * @mode_set: convert drm_display_mode to hw specific display mode and 165 * @mode_set: convert drm_display_mode to hw specific display mode and
166 * would be called by encoder->mode_set(). 166 * would be called by encoder->mode_set().
167 * @get_max_resol: get maximum resolution to specific hardware. 167 * @get_max_resol: get maximum resolution to specific hardware.
168 * @commit: set current hw specific display mode to hw. 168 * @commit: set current hw specific display mode to hw.
169 * @enable_vblank: specific driver callback for enabling vblank interrupt. 169 * @enable_vblank: specific driver callback for enabling vblank interrupt.
170 * @disable_vblank: specific driver callback for disabling vblank interrupt. 170 * @disable_vblank: specific driver callback for disabling vblank interrupt.
171 */ 171 */
172 struct exynos_drm_manager_ops { 172 struct exynos_drm_manager_ops {
173 void (*dpms)(struct device *subdrv_dev, int mode); 173 void (*dpms)(struct device *subdrv_dev, int mode);
174 void (*apply)(struct device *subdrv_dev); 174 void (*apply)(struct device *subdrv_dev);
175 void (*mode_fixup)(struct device *subdrv_dev, 175 void (*mode_fixup)(struct device *subdrv_dev,
176 struct drm_connector *connector, 176 struct drm_connector *connector,
177 struct drm_display_mode *mode, 177 struct drm_display_mode *mode,
178 struct drm_display_mode *adjusted_mode); 178 struct drm_display_mode *adjusted_mode);
179 void (*mode_set)(struct device *subdrv_dev, void *mode); 179 void (*mode_set)(struct device *subdrv_dev, void *mode);
180 void (*get_max_resol)(struct device *subdrv_dev, unsigned int *width, 180 void (*get_max_resol)(struct device *subdrv_dev, unsigned int *width,
181 unsigned int *height); 181 unsigned int *height);
182 void (*commit)(struct device *subdrv_dev); 182 void (*commit)(struct device *subdrv_dev);
183 int (*enable_vblank)(struct device *subdrv_dev); 183 int (*enable_vblank)(struct device *subdrv_dev);
184 void (*disable_vblank)(struct device *subdrv_dev); 184 void (*disable_vblank)(struct device *subdrv_dev);
185 }; 185 };
186 186
187 /* 187 /*
188 * Exynos drm common manager structure. 188 * Exynos drm common manager structure.
189 * 189 *
190 * @dev: pointer to device object for subdrv device driver. 190 * @dev: pointer to device object for subdrv device driver.
191 * sub drivers such as display controller or hdmi driver, 191 * sub drivers such as display controller or hdmi driver,
192 * have their own device object. 192 * have their own device object.
193 * @ops: pointer to callbacks for exynos drm specific framebuffer. 193 * @ops: pointer to callbacks for exynos drm specific framebuffer.
194 * these callbacks should be set by specific drivers such fimd 194 * these callbacks should be set by specific drivers such fimd
195 * or hdmi driver and are used to control hardware global registers. 195 * or hdmi driver and are used to control hardware global registers.
196 * @overlay_ops: pointer to callbacks for exynos drm specific framebuffer. 196 * @overlay_ops: pointer to callbacks for exynos drm specific framebuffer.
197 * these callbacks should be set by specific drivers such fimd 197 * these callbacks should be set by specific drivers such fimd
198 * or hdmi driver and are used to control hardware overlay reigsters. 198 * or hdmi driver and are used to control hardware overlay reigsters.
199 * @display: pointer to callbacks for exynos drm specific framebuffer. 199 * @display: pointer to callbacks for exynos drm specific framebuffer.
200 * these callbacks should be set by specific drivers such fimd 200 * these callbacks should be set by specific drivers such fimd
201 * or hdmi driver and are used to control display devices such as 201 * or hdmi driver and are used to control display devices such as
202 * analog tv, digital tv and lcd panel and also get timing data for them. 202 * analog tv, digital tv and lcd panel and also get timing data for them.
203 */ 203 */
204 struct exynos_drm_manager { 204 struct exynos_drm_manager {
205 struct device *dev; 205 struct device *dev;
206 int pipe; 206 int pipe;
207 struct exynos_drm_manager_ops *ops; 207 struct exynos_drm_manager_ops *ops;
208 struct exynos_drm_overlay_ops *overlay_ops; 208 struct exynos_drm_overlay_ops *overlay_ops;
209 struct exynos_drm_display_ops *display_ops; 209 struct exynos_drm_display_ops *display_ops;
210 }; 210 };
211 211
212 struct exynos_drm_g2d_private {
213 struct device *dev;
214 struct list_head inuse_cmdlist;
215 struct list_head event_list;
216 struct list_head gem_list;
217 unsigned int gem_nr;
218 };
219
220 struct drm_exynos_file_private {
221 struct exynos_drm_g2d_private *g2d_priv;
222 };
223
212 /* 224 /*
213 * Exynos drm private structure. 225 * Exynos drm private structure.
214 */ 226 */
215 struct exynos_drm_private { 227 struct exynos_drm_private {
216 struct drm_fb_helper *fb_helper; 228 struct drm_fb_helper *fb_helper;
217 229
218 /* list head for new event to be added. */ 230 /* list head for new event to be added. */
219 struct list_head pageflip_event_list; 231 struct list_head pageflip_event_list;
220 232
221 /* 233 /*
222 * created crtc object would be contained at this array and 234 * created crtc object would be contained at this array and
223 * this array is used to be aware of which crtc did it request vblank. 235 * this array is used to be aware of which crtc did it request vblank.
224 */ 236 */
225 struct drm_crtc *crtc[MAX_CRTC]; 237 struct drm_crtc *crtc[MAX_CRTC];
226 }; 238 };
227 239
228 /* 240 /*
229 * Exynos drm sub driver structure. 241 * Exynos drm sub driver structure.
230 * 242 *
231 * @list: sub driver has its own list object to register to exynos drm driver. 243 * @list: sub driver has its own list object to register to exynos drm driver.
232 * @dev: pointer to device object for subdrv device driver. 244 * @dev: pointer to device object for subdrv device driver.
233 * @drm_dev: pointer to drm_device and this pointer would be set 245 * @drm_dev: pointer to drm_device and this pointer would be set
234 * when sub driver calls exynos_drm_subdrv_register(). 246 * when sub driver calls exynos_drm_subdrv_register().
235 * @manager: subdrv has its own manager to control a hardware appropriately 247 * @manager: subdrv has its own manager to control a hardware appropriately
236 * and we can access a hardware drawing on this manager. 248 * and we can access a hardware drawing on this manager.
237 * @probe: this callback would be called by exynos drm driver after 249 * @probe: this callback would be called by exynos drm driver after
238 * subdrv is registered to it. 250 * subdrv is registered to it.
239 * @remove: this callback is used to release resources created 251 * @remove: this callback is used to release resources created
240 * by probe callback. 252 * by probe callback.
241 * @open: this would be called with drm device file open. 253 * @open: this would be called with drm device file open.
242 * @close: this would be called with drm device file close. 254 * @close: this would be called with drm device file close.
243 * @encoder: encoder object owned by this sub driver. 255 * @encoder: encoder object owned by this sub driver.
244 * @connector: connector object owned by this sub driver. 256 * @connector: connector object owned by this sub driver.
245 */ 257 */
246 struct exynos_drm_subdrv { 258 struct exynos_drm_subdrv {
247 struct list_head list; 259 struct list_head list;
248 struct device *dev; 260 struct device *dev;
249 struct drm_device *drm_dev; 261 struct drm_device *drm_dev;
250 struct exynos_drm_manager *manager; 262 struct exynos_drm_manager *manager;
251 263
252 int (*probe)(struct drm_device *drm_dev, struct device *dev); 264 int (*probe)(struct drm_device *drm_dev, struct device *dev);
253 void (*remove)(struct drm_device *dev); 265 void (*remove)(struct drm_device *dev);
254 int (*open)(struct drm_device *drm_dev, struct device *dev, 266 int (*open)(struct drm_device *drm_dev, struct device *dev,
255 struct drm_file *file); 267 struct drm_file *file);
256 void (*close)(struct drm_device *drm_dev, struct device *dev, 268 void (*close)(struct drm_device *drm_dev, struct device *dev,
257 struct drm_file *file); 269 struct drm_file *file);
258 270
259 struct drm_encoder *encoder; 271 struct drm_encoder *encoder;
260 struct drm_connector *connector; 272 struct drm_connector *connector;
261 }; 273 };
262 274
263 /* 275 /*
264 * this function calls a probe callback registered to sub driver list and 276 * this function calls a probe callback registered to sub driver list and
265 * create its own encoder and connector and then set drm_device object 277 * create its own encoder and connector and then set drm_device object
266 * to global one. 278 * to global one.
267 */ 279 */
268 int exynos_drm_device_register(struct drm_device *dev); 280 int exynos_drm_device_register(struct drm_device *dev);
269 /* 281 /*
270 * this function calls a remove callback registered to sub driver list and 282 * this function calls a remove callback registered to sub driver list and
271 * destroy its own encoder and connetor. 283 * destroy its own encoder and connetor.
272 */ 284 */
273 int exynos_drm_device_unregister(struct drm_device *dev); 285 int exynos_drm_device_unregister(struct drm_device *dev);
274 286
275 /* 287 /*
276 * this function would be called by sub drivers such as display controller 288 * this function would be called by sub drivers such as display controller
277 * or hdmi driver to register this sub driver object to exynos drm driver 289 * or hdmi driver to register this sub driver object to exynos drm driver
278 * and when a sub driver is registered to exynos drm driver a probe callback 290 * and when a sub driver is registered to exynos drm driver a probe callback
279 * of the sub driver is called and creates its own encoder and connector. 291 * of the sub driver is called and creates its own encoder and connector.
280 */ 292 */
281 int exynos_drm_subdrv_register(struct exynos_drm_subdrv *drm_subdrv); 293 int exynos_drm_subdrv_register(struct exynos_drm_subdrv *drm_subdrv);
282 294
283 /* this function removes subdrv list from exynos drm driver */ 295 /* this function removes subdrv list from exynos drm driver */
284 int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv); 296 int exynos_drm_subdrv_unregister(struct exynos_drm_subdrv *drm_subdrv);
285 297
286 int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file); 298 int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
287 void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file); 299 void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
288 300
289 extern struct platform_driver fimd_driver; 301 extern struct platform_driver fimd_driver;
290 extern struct platform_driver hdmi_driver; 302 extern struct platform_driver hdmi_driver;
291 extern struct platform_driver mixer_driver; 303 extern struct platform_driver mixer_driver;
292 extern struct platform_driver exynos_drm_common_hdmi_driver; 304 extern struct platform_driver exynos_drm_common_hdmi_driver;
293 extern struct platform_driver vidi_driver; 305 extern struct platform_driver vidi_driver;
306 extern struct platform_driver g2d_driver;
294 #endif 307 #endif
295 308
drivers/gpu/drm/exynos/exynos_drm_g2d.c
File was created 1 /*
2 * Copyright (C) 2012 Samsung Electronics Co.Ltd
3 * Authors: Joonyoung Shim <jy0922.shim@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundationr
8 */
9
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/clk.h>
13 #include <linux/err.h>
14 #include <linux/interrupt.h>
15 #include <linux/io.h>
16 #include <linux/platform_device.h>
17 #include <linux/pm_runtime.h>
18 #include <linux/slab.h>
19 #include <linux/workqueue.h>
20
21 #include "drmP.h"
22 #include "exynos_drm.h"
23 #include "exynos_drm_drv.h"
24 #include "exynos_drm_gem.h"
25
26 #define G2D_HW_MAJOR_VER 4
27 #define G2D_HW_MINOR_VER 1
28
29 /* vaild register range set from user: 0x0104 ~ 0x0880 */
30 #define G2D_VALID_START 0x0104
31 #define G2D_VALID_END 0x0880
32
33 /* general registers */
34 #define G2D_SOFT_RESET 0x0000
35 #define G2D_INTEN 0x0004
36 #define G2D_INTC_PEND 0x000C
37 #define G2D_DMA_SFR_BASE_ADDR 0x0080
38 #define G2D_DMA_COMMAND 0x0084
39 #define G2D_DMA_STATUS 0x008C
40 #define G2D_DMA_HOLD_CMD 0x0090
41
42 /* command registers */
43 #define G2D_BITBLT_START 0x0100
44
45 /* registers for base address */
46 #define G2D_SRC_BASE_ADDR 0x0304
47 #define G2D_SRC_PLANE2_BASE_ADDR 0x0318
48 #define G2D_DST_BASE_ADDR 0x0404
49 #define G2D_DST_PLANE2_BASE_ADDR 0x0418
50 #define G2D_PAT_BASE_ADDR 0x0500
51 #define G2D_MSK_BASE_ADDR 0x0520
52
53 /* G2D_SOFT_RESET */
54 #define G2D_SFRCLEAR (1 << 1)
55 #define G2D_R (1 << 0)
56
57 /* G2D_INTEN */
58 #define G2D_INTEN_ACF (1 << 3)
59 #define G2D_INTEN_UCF (1 << 2)
60 #define G2D_INTEN_GCF (1 << 1)
61 #define G2D_INTEN_SCF (1 << 0)
62
63 /* G2D_INTC_PEND */
64 #define G2D_INTP_ACMD_FIN (1 << 3)
65 #define G2D_INTP_UCMD_FIN (1 << 2)
66 #define G2D_INTP_GCMD_FIN (1 << 1)
67 #define G2D_INTP_SCMD_FIN (1 << 0)
68
69 /* G2D_DMA_COMMAND */
70 #define G2D_DMA_HALT (1 << 2)
71 #define G2D_DMA_CONTINUE (1 << 1)
72 #define G2D_DMA_START (1 << 0)
73
74 /* G2D_DMA_STATUS */
75 #define G2D_DMA_LIST_DONE_COUNT (0xFF << 17)
76 #define G2D_DMA_BITBLT_DONE_COUNT (0xFFFF << 1)
77 #define G2D_DMA_DONE (1 << 0)
78 #define G2D_DMA_LIST_DONE_COUNT_OFFSET 17
79
80 /* G2D_DMA_HOLD_CMD */
81 #define G2D_USET_HOLD (1 << 2)
82 #define G2D_LIST_HOLD (1 << 1)
83 #define G2D_BITBLT_HOLD (1 << 0)
84
85 /* G2D_BITBLT_START */
86 #define G2D_START_CASESEL (1 << 2)
87 #define G2D_START_NHOLT (1 << 1)
88 #define G2D_START_BITBLT (1 << 0)
89
90 #define G2D_CMDLIST_SIZE (PAGE_SIZE / 4)
91 #define G2D_CMDLIST_NUM 64
92 #define G2D_CMDLIST_POOL_SIZE (G2D_CMDLIST_SIZE * G2D_CMDLIST_NUM)
93 #define G2D_CMDLIST_DATA_NUM (G2D_CMDLIST_SIZE / sizeof(u32) - 2)
94
95 /* cmdlist data structure */
96 struct g2d_cmdlist {
97 u32 head;
98 u32 data[G2D_CMDLIST_DATA_NUM];
99 u32 last; /* last data offset */
100 };
101
102 struct drm_exynos_pending_g2d_event {
103 struct drm_pending_event base;
104 struct drm_exynos_g2d_event event;
105 };
106
107 struct g2d_gem_node {
108 struct list_head list;
109 unsigned int handle;
110 };
111
112 struct g2d_cmdlist_node {
113 struct list_head list;
114 struct g2d_cmdlist *cmdlist;
115 unsigned int gem_nr;
116 dma_addr_t dma_addr;
117
118 struct drm_exynos_pending_g2d_event *event;
119 };
120
121 struct g2d_runqueue_node {
122 struct list_head list;
123 struct list_head run_cmdlist;
124 struct list_head event_list;
125 struct completion complete;
126 int async;
127 };
128
129 struct g2d_data {
130 struct device *dev;
131 struct clk *gate_clk;
132 struct resource *regs_res;
133 void __iomem *regs;
134 int irq;
135 struct workqueue_struct *g2d_workq;
136 struct work_struct runqueue_work;
137 struct exynos_drm_subdrv subdrv;
138 bool suspended;
139
140 /* cmdlist */
141 struct g2d_cmdlist_node *cmdlist_node;
142 struct list_head free_cmdlist;
143 struct mutex cmdlist_mutex;
144 dma_addr_t cmdlist_pool;
145 void *cmdlist_pool_virt;
146
147 /* runqueue*/
148 struct g2d_runqueue_node *runqueue_node;
149 struct list_head runqueue;
150 struct mutex runqueue_mutex;
151 struct kmem_cache *runqueue_slab;
152 };
153
154 static int g2d_init_cmdlist(struct g2d_data *g2d)
155 {
156 struct device *dev = g2d->dev;
157 struct g2d_cmdlist_node *node = g2d->cmdlist_node;
158 int nr;
159 int ret;
160
161 g2d->cmdlist_pool_virt = dma_alloc_coherent(dev, G2D_CMDLIST_POOL_SIZE,
162 &g2d->cmdlist_pool, GFP_KERNEL);
163 if (!g2d->cmdlist_pool_virt) {
164 dev_err(dev, "failed to allocate dma memory\n");
165 return -ENOMEM;
166 }
167
168 node = kcalloc(G2D_CMDLIST_NUM, G2D_CMDLIST_NUM * sizeof(*node),
169 GFP_KERNEL);
170 if (!node) {
171 dev_err(dev, "failed to allocate memory\n");
172 ret = -ENOMEM;
173 goto err;
174 }
175
176 for (nr = 0; nr < G2D_CMDLIST_NUM; nr++) {
177 node[nr].cmdlist =
178 g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE;
179 node[nr].dma_addr =
180 g2d->cmdlist_pool + nr * G2D_CMDLIST_SIZE;
181
182 list_add_tail(&node[nr].list, &g2d->free_cmdlist);
183 }
184
185 return 0;
186
187 err:
188 dma_free_coherent(dev, G2D_CMDLIST_POOL_SIZE, g2d->cmdlist_pool_virt,
189 g2d->cmdlist_pool);
190 return ret;
191 }
192
193 static void g2d_fini_cmdlist(struct g2d_data *g2d)
194 {
195 struct device *dev = g2d->dev;
196
197 kfree(g2d->cmdlist_node);
198 dma_free_coherent(dev, G2D_CMDLIST_POOL_SIZE, g2d->cmdlist_pool_virt,
199 g2d->cmdlist_pool);
200 }
201
202 static struct g2d_cmdlist_node *g2d_get_cmdlist(struct g2d_data *g2d)
203 {
204 struct device *dev = g2d->dev;
205 struct g2d_cmdlist_node *node;
206
207 mutex_lock(&g2d->cmdlist_mutex);
208 if (list_empty(&g2d->free_cmdlist)) {
209 dev_err(dev, "there is no free cmdlist\n");
210 mutex_unlock(&g2d->cmdlist_mutex);
211 return NULL;
212 }
213
214 node = list_first_entry(&g2d->free_cmdlist, struct g2d_cmdlist_node,
215 list);
216 list_del_init(&node->list);
217 mutex_unlock(&g2d->cmdlist_mutex);
218
219 return node;
220 }
221
222 static void g2d_put_cmdlist(struct g2d_data *g2d, struct g2d_cmdlist_node *node)
223 {
224 mutex_lock(&g2d->cmdlist_mutex);
225 list_move_tail(&node->list, &g2d->free_cmdlist);
226 mutex_unlock(&g2d->cmdlist_mutex);
227 }
228
229 static void g2d_add_cmdlist_to_inuse(struct exynos_drm_g2d_private *g2d_priv,
230 struct g2d_cmdlist_node *node)
231 {
232 struct g2d_cmdlist_node *lnode;
233
234 if (list_empty(&g2d_priv->inuse_cmdlist))
235 goto add_to_list;
236
237 /* this links to base address of new cmdlist */
238 lnode = list_entry(g2d_priv->inuse_cmdlist.prev,
239 struct g2d_cmdlist_node, list);
240 lnode->cmdlist->data[lnode->cmdlist->last] = node->dma_addr;
241
242 add_to_list:
243 list_add_tail(&node->list, &g2d_priv->inuse_cmdlist);
244
245 if (node->event)
246 list_add_tail(&node->event->base.link, &g2d_priv->event_list);
247 }
248
249 static int g2d_get_cmdlist_gem(struct drm_device *drm_dev,
250 struct drm_file *file,
251 struct g2d_cmdlist_node *node)
252 {
253 struct drm_exynos_file_private *file_priv = file->driver_priv;
254 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
255 struct g2d_cmdlist *cmdlist = node->cmdlist;
256 dma_addr_t *addr;
257 int offset;
258 int i;
259
260 for (i = 0; i < node->gem_nr; i++) {
261 struct g2d_gem_node *gem_node;
262
263 gem_node = kzalloc(sizeof(*gem_node), GFP_KERNEL);
264 if (!gem_node) {
265 dev_err(g2d_priv->dev, "failed to allocate gem node\n");
266 return -ENOMEM;
267 }
268
269 offset = cmdlist->last - (i * 2 + 1);
270 gem_node->handle = cmdlist->data[offset];
271
272 addr = exynos_drm_gem_get_dma_addr(drm_dev, gem_node->handle,
273 file);
274 if (IS_ERR(addr)) {
275 node->gem_nr = i;
276 kfree(gem_node);
277 return PTR_ERR(addr);
278 }
279
280 cmdlist->data[offset] = *addr;
281 list_add_tail(&gem_node->list, &g2d_priv->gem_list);
282 g2d_priv->gem_nr++;
283 }
284
285 return 0;
286 }
287
288 static void g2d_put_cmdlist_gem(struct drm_device *drm_dev,
289 struct drm_file *file,
290 unsigned int nr)
291 {
292 struct drm_exynos_file_private *file_priv = file->driver_priv;
293 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
294 struct g2d_gem_node *node, *n;
295
296 list_for_each_entry_safe_reverse(node, n, &g2d_priv->gem_list, list) {
297 if (!nr)
298 break;
299
300 exynos_drm_gem_put_dma_addr(drm_dev, node->handle, file);
301 list_del_init(&node->list);
302 kfree(node);
303 nr--;
304 }
305 }
306
307 static void g2d_dma_start(struct g2d_data *g2d,
308 struct g2d_runqueue_node *runqueue_node)
309 {
310 struct g2d_cmdlist_node *node =
311 list_first_entry(&runqueue_node->run_cmdlist,
312 struct g2d_cmdlist_node, list);
313
314 pm_runtime_get_sync(g2d->dev);
315 clk_enable(g2d->gate_clk);
316
317 /* interrupt enable */
318 writel_relaxed(G2D_INTEN_ACF | G2D_INTEN_UCF | G2D_INTEN_GCF,
319 g2d->regs + G2D_INTEN);
320
321 writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR);
322 writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND);
323 }
324
325 static struct g2d_runqueue_node *g2d_get_runqueue_node(struct g2d_data *g2d)
326 {
327 struct g2d_runqueue_node *runqueue_node;
328
329 if (list_empty(&g2d->runqueue))
330 return NULL;
331
332 runqueue_node = list_first_entry(&g2d->runqueue,
333 struct g2d_runqueue_node, list);
334 list_del_init(&runqueue_node->list);
335 return runqueue_node;
336 }
337
338 static void g2d_free_runqueue_node(struct g2d_data *g2d,
339 struct g2d_runqueue_node *runqueue_node)
340 {
341 if (!runqueue_node)
342 return;
343
344 mutex_lock(&g2d->cmdlist_mutex);
345 list_splice_tail_init(&runqueue_node->run_cmdlist, &g2d->free_cmdlist);
346 mutex_unlock(&g2d->cmdlist_mutex);
347
348 kmem_cache_free(g2d->runqueue_slab, runqueue_node);
349 }
350
351 static void g2d_exec_runqueue(struct g2d_data *g2d)
352 {
353 g2d->runqueue_node = g2d_get_runqueue_node(g2d);
354 if (g2d->runqueue_node)
355 g2d_dma_start(g2d, g2d->runqueue_node);
356 }
357
358 static void g2d_runqueue_worker(struct work_struct *work)
359 {
360 struct g2d_data *g2d = container_of(work, struct g2d_data,
361 runqueue_work);
362
363
364 mutex_lock(&g2d->runqueue_mutex);
365 clk_disable(g2d->gate_clk);
366 pm_runtime_put_sync(g2d->dev);
367
368 complete(&g2d->runqueue_node->complete);
369 if (g2d->runqueue_node->async)
370 g2d_free_runqueue_node(g2d, g2d->runqueue_node);
371
372 if (g2d->suspended)
373 g2d->runqueue_node = NULL;
374 else
375 g2d_exec_runqueue(g2d);
376 mutex_unlock(&g2d->runqueue_mutex);
377 }
378
379 static void g2d_finish_event(struct g2d_data *g2d, u32 cmdlist_no)
380 {
381 struct drm_device *drm_dev = g2d->subdrv.drm_dev;
382 struct g2d_runqueue_node *runqueue_node = g2d->runqueue_node;
383 struct drm_exynos_pending_g2d_event *e;
384 struct timeval now;
385 unsigned long flags;
386
387 if (list_empty(&runqueue_node->event_list))
388 return;
389
390 e = list_first_entry(&runqueue_node->event_list,
391 struct drm_exynos_pending_g2d_event, base.link);
392
393 do_gettimeofday(&now);
394 e->event.tv_sec = now.tv_sec;
395 e->event.tv_usec = now.tv_usec;
396 e->event.cmdlist_no = cmdlist_no;
397
398 spin_lock_irqsave(&drm_dev->event_lock, flags);
399 list_move_tail(&e->base.link, &e->base.file_priv->event_list);
400 wake_up_interruptible(&e->base.file_priv->event_wait);
401 spin_unlock_irqrestore(&drm_dev->event_lock, flags);
402 }
403
404 static irqreturn_t g2d_irq_handler(int irq, void *dev_id)
405 {
406 struct g2d_data *g2d = dev_id;
407 u32 pending;
408
409 pending = readl_relaxed(g2d->regs + G2D_INTC_PEND);
410 if (pending)
411 writel_relaxed(pending, g2d->regs + G2D_INTC_PEND);
412
413 if (pending & G2D_INTP_GCMD_FIN) {
414 u32 cmdlist_no = readl_relaxed(g2d->regs + G2D_DMA_STATUS);
415
416 cmdlist_no = (cmdlist_no & G2D_DMA_LIST_DONE_COUNT) >>
417 G2D_DMA_LIST_DONE_COUNT_OFFSET;
418
419 g2d_finish_event(g2d, cmdlist_no);
420
421 writel_relaxed(0, g2d->regs + G2D_DMA_HOLD_CMD);
422 if (!(pending & G2D_INTP_ACMD_FIN)) {
423 writel_relaxed(G2D_DMA_CONTINUE,
424 g2d->regs + G2D_DMA_COMMAND);
425 }
426 }
427
428 if (pending & G2D_INTP_ACMD_FIN)
429 queue_work(g2d->g2d_workq, &g2d->runqueue_work);
430
431 return IRQ_HANDLED;
432 }
433
434 static int g2d_check_reg_offset(struct device *dev, struct g2d_cmdlist *cmdlist,
435 int nr, bool for_addr)
436 {
437 int reg_offset;
438 int index;
439 int i;
440
441 for (i = 0; i < nr; i++) {
442 index = cmdlist->last - 2 * (i + 1);
443 reg_offset = cmdlist->data[index] & ~0xfffff000;
444
445 if (reg_offset < G2D_VALID_START || reg_offset > G2D_VALID_END)
446 goto err;
447 if (reg_offset % 4)
448 goto err;
449
450 switch (reg_offset) {
451 case G2D_SRC_BASE_ADDR:
452 case G2D_SRC_PLANE2_BASE_ADDR:
453 case G2D_DST_BASE_ADDR:
454 case G2D_DST_PLANE2_BASE_ADDR:
455 case G2D_PAT_BASE_ADDR:
456 case G2D_MSK_BASE_ADDR:
457 if (!for_addr)
458 goto err;
459 break;
460 default:
461 if (for_addr)
462 goto err;
463 break;
464 }
465 }
466
467 return 0;
468
469 err:
470 dev_err(dev, "Bad register offset: 0x%x\n", cmdlist->data[index]);
471 return -EINVAL;
472 }
473
474 /* ioctl functions */
475 int exynos_g2d_get_ver_ioctl(struct drm_device *drm_dev, void *data,
476 struct drm_file *file)
477 {
478 struct drm_exynos_g2d_get_ver *ver = data;
479
480 ver->major = G2D_HW_MAJOR_VER;
481 ver->minor = G2D_HW_MINOR_VER;
482
483 return 0;
484 }
485 EXPORT_SYMBOL_GPL(exynos_g2d_get_ver_ioctl);
486
487 int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data,
488 struct drm_file *file)
489 {
490 struct drm_exynos_file_private *file_priv = file->driver_priv;
491 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
492 struct device *dev = g2d_priv->dev;
493 struct g2d_data *g2d;
494 struct drm_exynos_g2d_set_cmdlist *req = data;
495 struct drm_exynos_g2d_cmd *cmd;
496 struct drm_exynos_pending_g2d_event *e;
497 struct g2d_cmdlist_node *node;
498 struct g2d_cmdlist *cmdlist;
499 unsigned long flags;
500 int size;
501 int ret;
502
503 if (!dev)
504 return -ENODEV;
505
506 g2d = dev_get_drvdata(dev);
507 if (!g2d)
508 return -EFAULT;
509
510 node = g2d_get_cmdlist(g2d);
511 if (!node)
512 return -ENOMEM;
513
514 node->event = NULL;
515
516 if (req->event_type != G2D_EVENT_NOT) {
517 spin_lock_irqsave(&drm_dev->event_lock, flags);
518 if (file->event_space < sizeof(e->event)) {
519 spin_unlock_irqrestore(&drm_dev->event_lock, flags);
520 ret = -ENOMEM;
521 goto err;
522 }
523 file->event_space -= sizeof(e->event);
524 spin_unlock_irqrestore(&drm_dev->event_lock, flags);
525
526 e = kzalloc(sizeof(*node->event), GFP_KERNEL);
527 if (!e) {
528 dev_err(dev, "failed to allocate event\n");
529
530 spin_lock_irqsave(&drm_dev->event_lock, flags);
531 file->event_space += sizeof(e->event);
532 spin_unlock_irqrestore(&drm_dev->event_lock, flags);
533
534 ret = -ENOMEM;
535 goto err;
536 }
537
538 e->event.base.type = DRM_EXYNOS_G2D_EVENT;
539 e->event.base.length = sizeof(e->event);
540 e->event.user_data = req->user_data;
541 e->base.event = &e->event.base;
542 e->base.file_priv = file;
543 e->base.destroy = (void (*) (struct drm_pending_event *)) kfree;
544
545 node->event = e;
546 }
547
548 cmdlist = node->cmdlist;
549
550 cmdlist->last = 0;
551
552 /*
553 * If don't clear SFR registers, the cmdlist is affected by register
554 * values of previous cmdlist. G2D hw executes SFR clear command and
555 * a next command at the same time then the next command is ignored and
556 * is executed rightly from next next command, so needs a dummy command
557 * to next command of SFR clear command.
558 */
559 cmdlist->data[cmdlist->last++] = G2D_SOFT_RESET;
560 cmdlist->data[cmdlist->last++] = G2D_SFRCLEAR;
561 cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR;
562 cmdlist->data[cmdlist->last++] = 0;
563
564 if (node->event) {
565 cmdlist->data[cmdlist->last++] = G2D_DMA_HOLD_CMD;
566 cmdlist->data[cmdlist->last++] = G2D_LIST_HOLD;
567 }
568
569 /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */
570 size = cmdlist->last + req->cmd_nr * 2 + req->cmd_gem_nr * 2 + 2;
571 if (size > G2D_CMDLIST_DATA_NUM) {
572 dev_err(dev, "cmdlist size is too big\n");
573 ret = -EINVAL;
574 goto err_free_event;
575 }
576
577 cmd = (struct drm_exynos_g2d_cmd *)(uint32_t)req->cmd;
578
579 if (copy_from_user(cmdlist->data + cmdlist->last,
580 (void __user *)cmd,
581 sizeof(*cmd) * req->cmd_nr)) {
582 ret = -EFAULT;
583 goto err_free_event;
584 }
585 cmdlist->last += req->cmd_nr * 2;
586
587 ret = g2d_check_reg_offset(dev, cmdlist, req->cmd_nr, false);
588 if (ret < 0)
589 goto err_free_event;
590
591 node->gem_nr = req->cmd_gem_nr;
592 if (req->cmd_gem_nr) {
593 struct drm_exynos_g2d_cmd *cmd_gem;
594
595 cmd_gem = (struct drm_exynos_g2d_cmd *)(uint32_t)req->cmd_gem;
596
597 if (copy_from_user(cmdlist->data + cmdlist->last,
598 (void __user *)cmd_gem,
599 sizeof(*cmd_gem) * req->cmd_gem_nr)) {
600 ret = -EFAULT;
601 goto err_free_event;
602 }
603 cmdlist->last += req->cmd_gem_nr * 2;
604
605 ret = g2d_check_reg_offset(dev, cmdlist, req->cmd_gem_nr, true);
606 if (ret < 0)
607 goto err_free_event;
608
609 ret = g2d_get_cmdlist_gem(drm_dev, file, node);
610 if (ret < 0)
611 goto err_unmap;
612 }
613
614 cmdlist->data[cmdlist->last++] = G2D_BITBLT_START;
615 cmdlist->data[cmdlist->last++] = G2D_START_BITBLT;
616
617 /* head */
618 cmdlist->head = cmdlist->last / 2;
619
620 /* tail */
621 cmdlist->data[cmdlist->last] = 0;
622
623 g2d_add_cmdlist_to_inuse(g2d_priv, node);
624
625 return 0;
626
627 err_unmap:
628 g2d_put_cmdlist_gem(drm_dev, file, node->gem_nr);
629 err_free_event:
630 if (node->event) {
631 spin_lock_irqsave(&drm_dev->event_lock, flags);
632 file->event_space += sizeof(e->event);
633 spin_unlock_irqrestore(&drm_dev->event_lock, flags);
634 kfree(node->event);
635 }
636 err:
637 g2d_put_cmdlist(g2d, node);
638 return ret;
639 }
640 EXPORT_SYMBOL_GPL(exynos_g2d_set_cmdlist_ioctl);
641
642 int exynos_g2d_exec_ioctl(struct drm_device *drm_dev, void *data,
643 struct drm_file *file)
644 {
645 struct drm_exynos_file_private *file_priv = file->driver_priv;
646 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
647 struct device *dev = g2d_priv->dev;
648 struct g2d_data *g2d;
649 struct drm_exynos_g2d_exec *req = data;
650 struct g2d_runqueue_node *runqueue_node;
651 struct list_head *run_cmdlist;
652 struct list_head *event_list;
653
654 if (!dev)
655 return -ENODEV;
656
657 g2d = dev_get_drvdata(dev);
658 if (!g2d)
659 return -EFAULT;
660
661 runqueue_node = kmem_cache_alloc(g2d->runqueue_slab, GFP_KERNEL);
662 if (!runqueue_node) {
663 dev_err(dev, "failed to allocate memory\n");
664 return -ENOMEM;
665 }
666 run_cmdlist = &runqueue_node->run_cmdlist;
667 event_list = &runqueue_node->event_list;
668 INIT_LIST_HEAD(run_cmdlist);
669 INIT_LIST_HEAD(event_list);
670 init_completion(&runqueue_node->complete);
671 runqueue_node->async = req->async;
672
673 list_splice_init(&g2d_priv->inuse_cmdlist, run_cmdlist);
674 list_splice_init(&g2d_priv->event_list, event_list);
675
676 if (list_empty(run_cmdlist)) {
677 dev_err(dev, "there is no inuse cmdlist\n");
678 kmem_cache_free(g2d->runqueue_slab, runqueue_node);
679 return -EPERM;
680 }
681
682 mutex_lock(&g2d->runqueue_mutex);
683 list_add_tail(&runqueue_node->list, &g2d->runqueue);
684 if (!g2d->runqueue_node)
685 g2d_exec_runqueue(g2d);
686 mutex_unlock(&g2d->runqueue_mutex);
687
688 if (runqueue_node->async)
689 goto out;
690
691 wait_for_completion(&runqueue_node->complete);
692 g2d_free_runqueue_node(g2d, runqueue_node);
693
694 out:
695 return 0;
696 }
697 EXPORT_SYMBOL_GPL(exynos_g2d_exec_ioctl);
698
699 static int g2d_open(struct drm_device *drm_dev, struct device *dev,
700 struct drm_file *file)
701 {
702 struct drm_exynos_file_private *file_priv = file->driver_priv;
703 struct exynos_drm_g2d_private *g2d_priv;
704
705 g2d_priv = kzalloc(sizeof(*g2d_priv), GFP_KERNEL);
706 if (!g2d_priv) {
707 dev_err(dev, "failed to allocate g2d private data\n");
708 return -ENOMEM;
709 }
710
711 g2d_priv->dev = dev;
712 file_priv->g2d_priv = g2d_priv;
713
714 INIT_LIST_HEAD(&g2d_priv->inuse_cmdlist);
715 INIT_LIST_HEAD(&g2d_priv->event_list);
716 INIT_LIST_HEAD(&g2d_priv->gem_list);
717
718 return 0;
719 }
720
721 static void g2d_close(struct drm_device *drm_dev, struct device *dev,
722 struct drm_file *file)
723 {
724 struct drm_exynos_file_private *file_priv = file->driver_priv;
725 struct exynos_drm_g2d_private *g2d_priv = file_priv->g2d_priv;
726 struct g2d_data *g2d;
727 struct g2d_cmdlist_node *node, *n;
728
729 if (!dev)
730 return;
731
732 g2d = dev_get_drvdata(dev);
733 if (!g2d)
734 return;
735
736 mutex_lock(&g2d->cmdlist_mutex);
737 list_for_each_entry_safe(node, n, &g2d_priv->inuse_cmdlist, list)
738 list_move_tail(&node->list, &g2d->free_cmdlist);
739 mutex_unlock(&g2d->cmdlist_mutex);
740
741 g2d_put_cmdlist_gem(drm_dev, file, g2d_priv->gem_nr);
742
743 kfree(file_priv->g2d_priv);
744 }
745
746 static int __devinit g2d_probe(struct platform_device *pdev)
747 {
748 struct device *dev = &pdev->dev;
749 struct resource *res;
750 struct g2d_data *g2d;
751 struct exynos_drm_subdrv *subdrv;
752 int ret;
753
754 g2d = kzalloc(sizeof(*g2d), GFP_KERNEL);
755 if (!g2d) {
756 dev_err(dev, "failed to allocate driver data\n");
757 return -ENOMEM;
758 }
759
760 g2d->runqueue_slab = kmem_cache_create("g2d_runqueue_slab",
761 sizeof(struct g2d_runqueue_node), 0, 0, NULL);
762 if (!g2d->runqueue_slab) {
763 ret = -ENOMEM;
764 goto err_free_mem;
765 }
766
767 g2d->dev = dev;
768
769 g2d->g2d_workq = create_singlethread_workqueue("g2d");
770 if (!g2d->g2d_workq) {
771 dev_err(dev, "failed to create workqueue\n");
772 ret = -EINVAL;
773 goto err_destroy_slab;
774 }
775
776 INIT_WORK(&g2d->runqueue_work, g2d_runqueue_worker);
777 INIT_LIST_HEAD(&g2d->free_cmdlist);
778 INIT_LIST_HEAD(&g2d->runqueue);
779
780 mutex_init(&g2d->cmdlist_mutex);
781 mutex_init(&g2d->runqueue_mutex);
782
783 ret = g2d_init_cmdlist(g2d);
784 if (ret < 0)
785 goto err_destroy_workqueue;
786
787 g2d->gate_clk = clk_get(dev, "fimg2d");
788 if (IS_ERR(g2d->gate_clk)) {
789 dev_err(dev, "failed to get gate clock\n");
790 ret = PTR_ERR(g2d->gate_clk);
791 goto err_fini_cmdlist;
792 }
793
794 pm_runtime_enable(dev);
795
796 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
797 if (!res) {
798 dev_err(dev, "failed to get I/O memory\n");
799 ret = -ENOENT;
800 goto err_put_clk;
801 }
802
803 g2d->regs_res = request_mem_region(res->start, resource_size(res),
804 dev_name(dev));
805 if (!g2d->regs_res) {
806 dev_err(dev, "failed to request I/O memory\n");
807 ret = -ENOENT;
808 goto err_put_clk;
809 }
810
811 g2d->regs = ioremap(res->start, resource_size(res));
812 if (!g2d->regs) {
813 dev_err(dev, "failed to remap I/O memory\n");
814 ret = -ENXIO;
815 goto err_release_res;
816 }
817
818 g2d->irq = platform_get_irq(pdev, 0);
819 if (g2d->irq < 0) {
820 dev_err(dev, "failed to get irq\n");
821 ret = g2d->irq;
822 goto err_unmap_base;
823 }
824
825 ret = request_irq(g2d->irq, g2d_irq_handler, 0, "drm_g2d", g2d);
826 if (ret < 0) {
827 dev_err(dev, "irq request failed\n");
828 goto err_unmap_base;
829 }
830
831 platform_set_drvdata(pdev, g2d);
832
833 subdrv = &g2d->subdrv;
834 subdrv->dev = dev;
835 subdrv->open = g2d_open;
836 subdrv->close = g2d_close;
837
838 ret = exynos_drm_subdrv_register(subdrv);
839 if (ret < 0) {
840 dev_err(dev, "failed to register drm g2d device\n");
841 goto err_free_irq;
842 }
843
844 dev_info(dev, "The exynos g2d(ver %d.%d) successfully probed\n",
845 G2D_HW_MAJOR_VER, G2D_HW_MINOR_VER);
846
847 return 0;
848
849 err_free_irq:
850 free_irq(g2d->irq, g2d);
851 err_unmap_base:
852 iounmap(g2d->regs);
853 err_release_res:
854 release_resource(g2d->regs_res);
855 kfree(g2d->regs_res);
856 err_put_clk:
857 pm_runtime_disable(dev);
858 clk_put(g2d->gate_clk);
859 err_fini_cmdlist:
860 g2d_fini_cmdlist(g2d);
861 err_destroy_workqueue:
862 destroy_workqueue(g2d->g2d_workq);
863 err_destroy_slab:
864 kmem_cache_destroy(g2d->runqueue_slab);
865 err_free_mem:
866 kfree(g2d);
867 return ret;
868 }
869
870 static int __devexit g2d_remove(struct platform_device *pdev)
871 {
872 struct g2d_data *g2d = platform_get_drvdata(pdev);
873
874 cancel_work_sync(&g2d->runqueue_work);
875 exynos_drm_subdrv_unregister(&g2d->subdrv);
876 free_irq(g2d->irq, g2d);
877
878 while (g2d->runqueue_node) {
879 g2d_free_runqueue_node(g2d, g2d->runqueue_node);
880 g2d->runqueue_node = g2d_get_runqueue_node(g2d);
881 }
882
883 iounmap(g2d->regs);
884 release_resource(g2d->regs_res);
885 kfree(g2d->regs_res);
886
887 pm_runtime_disable(&pdev->dev);
888 clk_put(g2d->gate_clk);
889
890 g2d_fini_cmdlist(g2d);
891 destroy_workqueue(g2d->g2d_workq);
892 kmem_cache_destroy(g2d->runqueue_slab);
893 kfree(g2d);
894
895 return 0;
896 }
897
898 #ifdef CONFIG_PM_SLEEP
899 static int g2d_suspend(struct device *dev)
900 {
901 struct g2d_data *g2d = dev_get_drvdata(dev);
902
903 mutex_lock(&g2d->runqueue_mutex);
904 g2d->suspended = true;
905 mutex_unlock(&g2d->runqueue_mutex);
906
907 while (g2d->runqueue_node)
908 /* FIXME: good range? */
909 usleep_range(500, 1000);
910
911 flush_work_sync(&g2d->runqueue_work);
912
913 return 0;
914 }
915
916 static int g2d_resume(struct device *dev)
917 {
918 struct g2d_data *g2d = dev_get_drvdata(dev);
919
920 g2d->suspended = false;
921 g2d_exec_runqueue(g2d);
922
923 return 0;
924 }
925 #endif
926
927 SIMPLE_DEV_PM_OPS(g2d_pm_ops, g2d_suspend, g2d_resume);
928
929 struct platform_driver g2d_driver = {
930 .probe = g2d_probe,
931 .remove = __devexit_p(g2d_remove),
932 .driver = {
933 .name = "s5p-g2d",
934 .owner = THIS_MODULE,
935 .pm = &g2d_pm_ops,
936 },
937 };
938
drivers/gpu/drm/exynos/exynos_drm_g2d.h
File was created 1 /*
2 * Copyright (C) 2012 Samsung Electronics Co.Ltd
3 * Authors: Joonyoung Shim <jy0922.shim@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundationr
8 */
9
10 #ifdef CONFIG_DRM_EXYNOS_G2D
11 extern int exynos_g2d_get_ver_ioctl(struct drm_device *dev, void *data,
12 struct drm_file *file_priv);
13 extern int exynos_g2d_set_cmdlist_ioctl(struct drm_device *dev, void *data,
14 struct drm_file *file_priv);
15 extern int exynos_g2d_exec_ioctl(struct drm_device *dev, void *data,
16 struct drm_file *file_priv);
17 #else
18 static inline int exynos_g2d_get_ver_ioctl(struct drm_device *dev, void *data,
19 struct drm_file *file_priv)
20 {
21 return -ENODEV;
22 }
23
24 static inline int exynos_g2d_set_cmdlist_ioctl(struct drm_device *dev,
25 void *data,
26 struct drm_file *file_priv)
27 {
28 return -ENODEV;
29 }
30
31 static inline int exynos_g2d_exec_ioctl(struct drm_device *dev, void *data,
32 struct drm_file *file_priv)
33 {
34 return -ENODEV;
35 }
36 #endif
37
include/drm/exynos_drm.h
1 /* exynos_drm.h 1 /* exynos_drm.h
2 * 2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd. 3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * Authors: 4 * Authors:
5 * Inki Dae <inki.dae@samsung.com> 5 * Inki Dae <inki.dae@samsung.com>
6 * Joonyoung Shim <jy0922.shim@samsung.com> 6 * Joonyoung Shim <jy0922.shim@samsung.com>
7 * Seung-Woo Kim <sw0312.kim@samsung.com> 7 * Seung-Woo Kim <sw0312.kim@samsung.com>
8 * 8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a 9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"), 10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation 11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the 13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions: 14 * Software is furnished to do so, subject to the following conditions:
15 * 15 *
16 * The above copyright notice and this permission notice (including the next 16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the 17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software. 18 * Software.
19 * 19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 23 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26 * OTHER DEALINGS IN THE SOFTWARE. 26 * OTHER DEALINGS IN THE SOFTWARE.
27 */ 27 */
28 28
29 #ifndef _EXYNOS_DRM_H_ 29 #ifndef _EXYNOS_DRM_H_
30 #define _EXYNOS_DRM_H_ 30 #define _EXYNOS_DRM_H_
31 31
32 #include "drm.h"
33
32 /** 34 /**
33 * User-desired buffer creation information structure. 35 * User-desired buffer creation information structure.
34 * 36 *
35 * @size: user-desired memory allocation size. 37 * @size: user-desired memory allocation size.
36 * - this size value would be page-aligned internally. 38 * - this size value would be page-aligned internally.
37 * @flags: user request for setting memory type or cache attributes. 39 * @flags: user request for setting memory type or cache attributes.
38 * @handle: returned a handle to created gem object. 40 * @handle: returned a handle to created gem object.
39 * - this handle will be set by gem module of kernel side. 41 * - this handle will be set by gem module of kernel side.
40 */ 42 */
41 struct drm_exynos_gem_create { 43 struct drm_exynos_gem_create {
42 uint64_t size; 44 uint64_t size;
43 unsigned int flags; 45 unsigned int flags;
44 unsigned int handle; 46 unsigned int handle;
45 }; 47 };
46 48
47 /** 49 /**
48 * A structure for getting buffer offset. 50 * A structure for getting buffer offset.
49 * 51 *
50 * @handle: a pointer to gem object created. 52 * @handle: a pointer to gem object created.
51 * @pad: just padding to be 64-bit aligned. 53 * @pad: just padding to be 64-bit aligned.
52 * @offset: relatived offset value of the memory region allocated. 54 * @offset: relatived offset value of the memory region allocated.
53 * - this value should be set by user. 55 * - this value should be set by user.
54 */ 56 */
55 struct drm_exynos_gem_map_off { 57 struct drm_exynos_gem_map_off {
56 unsigned int handle; 58 unsigned int handle;
57 unsigned int pad; 59 unsigned int pad;
58 uint64_t offset; 60 uint64_t offset;
59 }; 61 };
60 62
61 /** 63 /**
62 * A structure for mapping buffer. 64 * A structure for mapping buffer.
63 * 65 *
64 * @handle: a handle to gem object created. 66 * @handle: a handle to gem object created.
65 * @size: memory size to be mapped. 67 * @size: memory size to be mapped.
66 * @mapped: having user virtual address mmaped. 68 * @mapped: having user virtual address mmaped.
67 * - this variable would be filled by exynos gem module 69 * - this variable would be filled by exynos gem module
68 * of kernel side with user virtual address which is allocated 70 * of kernel side with user virtual address which is allocated
69 * by do_mmap(). 71 * by do_mmap().
70 */ 72 */
71 struct drm_exynos_gem_mmap { 73 struct drm_exynos_gem_mmap {
72 unsigned int handle; 74 unsigned int handle;
73 unsigned int size; 75 unsigned int size;
74 uint64_t mapped; 76 uint64_t mapped;
75 }; 77 };
76 78
77 /** 79 /**
78 * A structure to gem information. 80 * A structure to gem information.
79 * 81 *
80 * @handle: a handle to gem object created. 82 * @handle: a handle to gem object created.
81 * @flags: flag value including memory type and cache attribute and 83 * @flags: flag value including memory type and cache attribute and
82 * this value would be set by driver. 84 * this value would be set by driver.
83 * @size: size to memory region allocated by gem and this size would 85 * @size: size to memory region allocated by gem and this size would
84 * be set by driver. 86 * be set by driver.
85 */ 87 */
86 struct drm_exynos_gem_info { 88 struct drm_exynos_gem_info {
87 unsigned int handle; 89 unsigned int handle;
88 unsigned int flags; 90 unsigned int flags;
89 uint64_t size; 91 uint64_t size;
90 }; 92 };
91 93
92 /** 94 /**
93 * A structure for user connection request of virtual display. 95 * A structure for user connection request of virtual display.
94 * 96 *
95 * @connection: indicate whether doing connetion or not by user. 97 * @connection: indicate whether doing connetion or not by user.
96 * @extensions: if this value is 1 then the vidi driver would need additional 98 * @extensions: if this value is 1 then the vidi driver would need additional
97 * 128bytes edid data. 99 * 128bytes edid data.
98 * @edid: the edid data pointer from user side. 100 * @edid: the edid data pointer from user side.
99 */ 101 */
100 struct drm_exynos_vidi_connection { 102 struct drm_exynos_vidi_connection {
101 unsigned int connection; 103 unsigned int connection;
102 unsigned int extensions; 104 unsigned int extensions;
103 uint64_t edid; 105 uint64_t edid;
104 }; 106 };
105 107
106 struct drm_exynos_plane_set_zpos { 108 struct drm_exynos_plane_set_zpos {
107 __u32 plane_id; 109 __u32 plane_id;
108 __s32 zpos; 110 __s32 zpos;
109 }; 111 };
110 112
111 /* memory type definitions. */ 113 /* memory type definitions. */
112 enum e_drm_exynos_gem_mem_type { 114 enum e_drm_exynos_gem_mem_type {
113 /* Physically Continuous memory and used as default. */ 115 /* Physically Continuous memory and used as default. */
114 EXYNOS_BO_CONTIG = 0 << 0, 116 EXYNOS_BO_CONTIG = 0 << 0,
115 /* Physically Non-Continuous memory. */ 117 /* Physically Non-Continuous memory. */
116 EXYNOS_BO_NONCONTIG = 1 << 0, 118 EXYNOS_BO_NONCONTIG = 1 << 0,
117 /* non-cachable mapping and used as default. */ 119 /* non-cachable mapping and used as default. */
118 EXYNOS_BO_NONCACHABLE = 0 << 1, 120 EXYNOS_BO_NONCACHABLE = 0 << 1,
119 /* cachable mapping. */ 121 /* cachable mapping. */
120 EXYNOS_BO_CACHABLE = 1 << 1, 122 EXYNOS_BO_CACHABLE = 1 << 1,
121 /* write-combine mapping. */ 123 /* write-combine mapping. */
122 EXYNOS_BO_WC = 1 << 2, 124 EXYNOS_BO_WC = 1 << 2,
123 EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE | 125 EXYNOS_BO_MASK = EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE |
124 EXYNOS_BO_WC 126 EXYNOS_BO_WC
125 }; 127 };
126 128
129 struct drm_exynos_g2d_get_ver {
130 __u32 major;
131 __u32 minor;
132 };
133
134 struct drm_exynos_g2d_cmd {
135 __u32 offset;
136 __u32 data;
137 };
138
139 enum drm_exynos_g2d_event_type {
140 G2D_EVENT_NOT,
141 G2D_EVENT_NONSTOP,
142 G2D_EVENT_STOP, /* not yet */
143 };
144
145 struct drm_exynos_g2d_set_cmdlist {
146 __u64 cmd;
147 __u64 cmd_gem;
148 __u32 cmd_nr;
149 __u32 cmd_gem_nr;
150
151 /* for g2d event */
152 __u64 event_type;
153 __u64 user_data;
154 };
155
156 struct drm_exynos_g2d_exec {
157 __u64 async;
158 };
159
127 #define DRM_EXYNOS_GEM_CREATE 0x00 160 #define DRM_EXYNOS_GEM_CREATE 0x00
128 #define DRM_EXYNOS_GEM_MAP_OFFSET 0x01 161 #define DRM_EXYNOS_GEM_MAP_OFFSET 0x01
129 #define DRM_EXYNOS_GEM_MMAP 0x02 162 #define DRM_EXYNOS_GEM_MMAP 0x02
130 /* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */ 163 /* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */
131 #define DRM_EXYNOS_GEM_GET 0x04 164 #define DRM_EXYNOS_GEM_GET 0x04
132 #define DRM_EXYNOS_PLANE_SET_ZPOS 0x06 165 #define DRM_EXYNOS_PLANE_SET_ZPOS 0x06
133 #define DRM_EXYNOS_VIDI_CONNECTION 0x07 166 #define DRM_EXYNOS_VIDI_CONNECTION 0x07
134 167
168 /* G2D */
169 #define DRM_EXYNOS_G2D_GET_VER 0x20
170 #define DRM_EXYNOS_G2D_SET_CMDLIST 0x21
171 #define DRM_EXYNOS_G2D_EXEC 0x22
172
135 #define DRM_IOCTL_EXYNOS_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \ 173 #define DRM_IOCTL_EXYNOS_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
136 DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create) 174 DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
137 175
138 #define DRM_IOCTL_EXYNOS_GEM_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \ 176 #define DRM_IOCTL_EXYNOS_GEM_MAP_OFFSET DRM_IOWR(DRM_COMMAND_BASE + \
139 DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off) 177 DRM_EXYNOS_GEM_MAP_OFFSET, struct drm_exynos_gem_map_off)
140 178
141 #define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \ 179 #define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
142 DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap) 180 DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
143 181
144 #define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \ 182 #define DRM_IOCTL_EXYNOS_GEM_GET DRM_IOWR(DRM_COMMAND_BASE + \
145 DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info) 183 DRM_EXYNOS_GEM_GET, struct drm_exynos_gem_info)
146 184
147 #define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \ 185 #define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \
148 DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos) 186 DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
149 187
150 #define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \ 188 #define DRM_IOCTL_EXYNOS_VIDI_CONNECTION DRM_IOWR(DRM_COMMAND_BASE + \
151 DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection) 189 DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
190
191 #define DRM_IOCTL_EXYNOS_G2D_GET_VER DRM_IOWR(DRM_COMMAND_BASE + \
192 DRM_EXYNOS_G2D_GET_VER, struct drm_exynos_g2d_get_ver)
193 #define DRM_IOCTL_EXYNOS_G2D_SET_CMDLIST DRM_IOWR(DRM_COMMAND_BASE + \
194 DRM_EXYNOS_G2D_SET_CMDLIST, struct drm_exynos_g2d_set_cmdlist)
195 #define DRM_IOCTL_EXYNOS_G2D_EXEC DRM_IOWR(DRM_COMMAND_BASE + \
196 DRM_EXYNOS_G2D_EXEC, struct drm_exynos_g2d_exec)
197
198 /* EXYNOS specific events */
199 #define DRM_EXYNOS_G2D_EVENT 0x80000000
200
201 struct drm_exynos_g2d_event {
202 struct drm_event base;
203 __u64 user_data;
204 __u32 tv_sec;
205 __u32 tv_usec;
206 __u32 cmdlist_no;
207 __u32 reserved;
208 };
152 209
153 #ifdef __KERNEL__ 210 #ifdef __KERNEL__
154 211
155 /** 212 /**
156 * A structure for lcd panel information. 213 * A structure for lcd panel information.
157 * 214 *
158 * @timing: default video mode for initializing 215 * @timing: default video mode for initializing
159 * @width_mm: physical size of lcd width. 216 * @width_mm: physical size of lcd width.
160 * @height_mm: physical size of lcd height. 217 * @height_mm: physical size of lcd height.
161 */ 218 */
162 struct exynos_drm_panel_info { 219 struct exynos_drm_panel_info {
163 struct fb_videomode timing; 220 struct fb_videomode timing;
164 u32 width_mm; 221 u32 width_mm;
165 u32 height_mm; 222 u32 height_mm;
166 }; 223 };
167 224
168 /** 225 /**
169 * Platform Specific Structure for DRM based FIMD. 226 * Platform Specific Structure for DRM based FIMD.
170 * 227 *
171 * @panel: default panel info for initializing 228 * @panel: default panel info for initializing
172 * @default_win: default window layer number to be used for UI. 229 * @default_win: default window layer number to be used for UI.
173 * @bpp: default bit per pixel. 230 * @bpp: default bit per pixel.
174 */ 231 */
175 struct exynos_drm_fimd_pdata { 232 struct exynos_drm_fimd_pdata {
176 struct exynos_drm_panel_info panel; 233 struct exynos_drm_panel_info panel;
177 u32 vidcon0; 234 u32 vidcon0;
178 u32 vidcon1; 235 u32 vidcon1;
179 unsigned int default_win; 236 unsigned int default_win;
180 unsigned int bpp; 237 unsigned int bpp;
181 }; 238 };
182 239
183 /** 240 /**
184 * Platform Specific Structure for DRM based HDMI. 241 * Platform Specific Structure for DRM based HDMI.
185 * 242 *
186 * @hdmi_dev: device point to specific hdmi driver. 243 * @hdmi_dev: device point to specific hdmi driver.
187 * @mixer_dev: device point to specific mixer driver. 244 * @mixer_dev: device point to specific mixer driver.
188 * 245 *
189 * this structure is used for common hdmi driver and each device object 246 * this structure is used for common hdmi driver and each device object
190 * would be used to access specific device driver(hdmi or mixer driver) 247 * would be used to access specific device driver(hdmi or mixer driver)
191 */ 248 */
192 struct exynos_drm_common_hdmi_pd { 249 struct exynos_drm_common_hdmi_pd {
193 struct device *hdmi_dev; 250 struct device *hdmi_dev;
194 struct device *mixer_dev; 251 struct device *mixer_dev;
195 }; 252 };
196 253
197 /** 254 /**
198 * Platform Specific Structure for DRM based HDMI core. 255 * Platform Specific Structure for DRM based HDMI core.
199 * 256 *
200 * @is_v13: set if hdmi version 13 is. 257 * @is_v13: set if hdmi version 13 is.
201 * @cfg_hpd: function pointer to configure hdmi hotplug detection pin 258 * @cfg_hpd: function pointer to configure hdmi hotplug detection pin
202 * @get_hpd: function pointer to get value of hdmi hotplug detection pin 259 * @get_hpd: function pointer to get value of hdmi hotplug detection pin
203 */ 260 */
204 struct exynos_drm_hdmi_pdata { 261 struct exynos_drm_hdmi_pdata {
205 bool is_v13; 262 bool is_v13;
206 void (*cfg_hpd)(bool external); 263 void (*cfg_hpd)(bool external);
207 int (*get_hpd)(void); 264 int (*get_hpd)(void);
208 }; 265 };
209 266
210 #endif /* __KERNEL__ */ 267 #endif /* __KERNEL__ */
211 #endif /* _EXYNOS_DRM_H_ */ 268 #endif /* _EXYNOS_DRM_H_ */
212 269