aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorAlan Cox <alan@linux.intel.com>2011-07-15 12:32:13 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2011-07-15 13:05:06 -0400
commitbd7b9f91ddc2d08381a853bd33b3ce7d0012b1df (patch)
tree59eeafe297d904397a3ce11bdc002874e4f921dc /drivers/staging
parentc5c44531ad00ed87078e799f0932c220031aa1c9 (diff)
gma500: Move the 2D operations into DRM
We currently have a test hack framebuffer mode ioctl, turn that into a DRM interface. Signed-off-by: Alan Cox <alan@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/gma500/accel_2d.c60
-rw-r--r--drivers/staging/gma500/framebuffer.c25
-rw-r--r--drivers/staging/gma500/psb_drm.h13
-rw-r--r--drivers/staging/gma500/psb_drv.c9
-rw-r--r--drivers/staging/gma500/psb_drv.h7
5 files changed, 82 insertions, 32 deletions
diff --git a/drivers/staging/gma500/accel_2d.c b/drivers/staging/gma500/accel_2d.c
index c719017e9db3..14400fcfe8a7 100644
--- a/drivers/staging/gma500/accel_2d.c
+++ b/drivers/staging/gma500/accel_2d.c
@@ -105,19 +105,20 @@ static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
105 * Issue one or more 2D commands to the accelerator. This needs to be 105 * Issue one or more 2D commands to the accelerator. This needs to be
106 * serialized later when we add the GEM interfaces for acceleration 106 * serialized later when we add the GEM interfaces for acceleration
107 */ 107 */
108int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, 108static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
109 unsigned size) 109 unsigned size)
110{ 110{
111 int ret = 0; 111 int ret = 0;
112 int i; 112 int i;
113 unsigned submit_size; 113 unsigned submit_size;
114 114
115 mutex_lock(&dev_priv->mutex_2d);
115 while (size > 0) { 116 while (size > 0) {
116 submit_size = (size < 0x60) ? size : 0x60; 117 submit_size = (size < 0x60) ? size : 0x60;
117 size -= submit_size; 118 size -= submit_size;
118 ret = psb_2d_wait_available(dev_priv, submit_size); 119 ret = psb_2d_wait_available(dev_priv, submit_size);
119 if (ret) 120 if (ret)
120 return ret; 121 break;
121 122
122 submit_size <<= 2; 123 submit_size <<= 2;
123 124
@@ -126,7 +127,8 @@ int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
126 127
127 (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4); 128 (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4);
128 } 129 }
129 return 0; 130 mutex_unlock(&dev_priv->mutex_2d);
131 return ret;
130} 132}
131 133
132 134
@@ -326,6 +328,7 @@ int psbfb_sync(struct fb_info *info)
326 unsigned long _end = jiffies + DRM_HZ; 328 unsigned long _end = jiffies + DRM_HZ;
327 int busy = 0; 329 int busy = 0;
328 330
331 mutex_lock(&dev_priv->mutex_2d);
329 /* 332 /*
330 * First idle the 2D engine. 333 * First idle the 2D engine.
331 */ 334 */
@@ -354,5 +357,56 @@ int psbfb_sync(struct fb_info *info)
354 _PSB_C2B_STATUS_BUSY) != 0); 357 _PSB_C2B_STATUS_BUSY) != 0);
355 358
356out: 359out:
360 mutex_unlock(&dev_priv->mutex_2d);
357 return (busy) ? -EBUSY : 0; 361 return (busy) ? -EBUSY : 0;
358} 362}
363
364int psb_accel_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
365{
366 struct drm_psb_private *dev_priv = dev->dev_private;
367 struct drm_psb_2d_op *op = data;
368 u32 *op_ptr = &op->cmd[0];
369 int i;
370 struct drm_gem_object *obj;
371 struct gtt_range *gtt;
372 int err = -EINVAL;
373
374 if (!dev_priv->ops->accel_2d)
375 return -EOPNOTSUPP;
376 if (op->size > PSB_2D_OP_BUFLEN)
377 return -EINVAL;
378
379 /* The GEM object being used. We need to support separate src/dst/etc
380 in the end but for now keep them all the same */
381 obj = drm_gem_object_lookup(dev, file, op->src);
382 if (obj == NULL)
383 return -ENOENT;
384 gtt = container_of(obj, struct gtt_range, gem);
385
386 if (psb_gtt_pin(gtt) < 0)
387 goto bad_2;
388 for (i = 0; i < op->size; i++, op_ptr++) {
389 u32 r = *op_ptr & 0xF0000000;
390 /* Fill in the GTT offsets for the command buffer */
391 if (r == PSB_2D_SRC_SURF_BH ||
392 r == PSB_2D_DST_SURF_BH ||
393 r == PSB_2D_MASK_SURF_BH ||
394 r == PSB_2D_PAT_SURF_BH) {
395 i++;
396 op_ptr++;
397 if (i == op->size)
398 goto bad;
399 if (*op_ptr)
400 goto bad;
401 *op_ptr = gtt->offset;
402 continue;
403 }
404 }
405 psbfb_2d_submit(dev_priv, op->cmd, op->size);
406 err = 0;
407bad:
408 psb_gtt_unpin(gtt);
409bad_2:
410 drm_gem_object_unreference(obj);
411 return err;
412}
diff --git a/drivers/staging/gma500/framebuffer.c b/drivers/staging/gma500/framebuffer.c
index 76b986f4180d..d890a5091cd2 100644
--- a/drivers/staging/gma500/framebuffer.c
+++ b/drivers/staging/gma500/framebuffer.c
@@ -200,30 +200,7 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
200static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, 200static int psbfb_ioctl(struct fb_info *info, unsigned int cmd,
201 unsigned long arg) 201 unsigned long arg)
202{ 202{
203 struct psb_fbdev *fbdev = info->par; 203 return -ENOTTY;
204 struct psb_framebuffer *psbfb = &fbdev->pfb;
205 struct drm_device *dev = psbfb->base.dev;
206 struct drm_psb_private *dev_priv = dev->dev_private;
207 u32 __user *p = (u32 __user *)arg;
208 u32 l;
209 u32 buf[32];
210 switch (cmd) {
211 case 0x12345678:
212 if (!capable(CAP_SYS_RAWIO))
213 return -EPERM;
214 if (!dev_priv->ops->accel_2d)
215 return -EOPNOTSUPP;
216 if (get_user(l, p))
217 return -EFAULT;
218 if (l > 32)
219 return -EMSGSIZE;
220 if (copy_from_user(buf, p + 1, l * sizeof(u32)))
221 return -EFAULT;
222 psbfb_2d_submit(dev_priv, buf, l);
223 return 0;
224 default:
225 return -ENOTTY;
226 }
227} 204}
228 205
229static struct fb_ops psbfb_ops = { 206static struct fb_ops psbfb_ops = {
diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h
index 717511714318..eef53f3e6a85 100644
--- a/drivers/staging/gma500/psb_drm.h
+++ b/drivers/staging/gma500/psb_drm.h
@@ -161,6 +161,7 @@ struct drm_psb_register_rw_arg {
161 */ 161 */
162 162
163#define DRM_PSB_GEM_CREATE 0x10 163#define DRM_PSB_GEM_CREATE 0x10
164#define DRM_PSB_2D_OP 0x11
164#define DRM_PSB_DPST 0x1B 165#define DRM_PSB_DPST 0x1B
165#define DRM_PSB_GAMMA 0x1C 166#define DRM_PSB_GAMMA 0x1C
166#define DRM_PSB_DPST_BL 0x1D 167#define DRM_PSB_DPST_BL 0x1D
@@ -190,4 +191,16 @@ struct drm_psb_gem_create {
190 __u32 pad; 191 __u32 pad;
191}; 192};
192 193
194#define PSB_2D_OP_BUFLEN 16
195
196struct drm_psb_2d_op {
197 __u32 src; /* Handles, only src supported right now */
198 __u32 dst;
199 __u32 mask;
200 __u32 pat;
201 __u32 size; /* In dwords of command */
202 __u32 spare; /* And bumps array to u64 align */
203 __u32 cmd[PSB_2D_OP_BUFLEN];
204};
205
193#endif 206#endif
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index a75397711ff7..36bb716a934a 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -124,6 +124,9 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
124#define DRM_IOCTL_PSB_GEM_CREATE \ 124#define DRM_IOCTL_PSB_GEM_CREATE \
125 DRM_IOWR(DRM_PSB_GEM_CREATE + DRM_COMMAND_BASE, \ 125 DRM_IOWR(DRM_PSB_GEM_CREATE + DRM_COMMAND_BASE, \
126 struct drm_psb_gem_create) 126 struct drm_psb_gem_create)
127#define DRM_IOCTL_PSB_2D_OP \
128 DRM_IOW(DRM_PSB_2D_OP + DRM_COMMAND_BASE, \
129 struct drm_psb_2d_op)
127 130
128static int psb_sizes_ioctl(struct drm_device *dev, void *data, 131static int psb_sizes_ioctl(struct drm_device *dev, void *data,
129 struct drm_file *file_priv); 132 struct drm_file *file_priv);
@@ -164,7 +167,7 @@ static struct drm_ioctl_desc psb_ioctls[] = {
164 psb_intel_get_pipe_from_crtc_id, 0), 167 psb_intel_get_pipe_from_crtc_id, 0),
165 PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_CREATE, psb_gem_create_ioctl, 168 PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_CREATE, psb_gem_create_ioctl,
166 DRM_UNLOCKED | DRM_AUTH), 169 DRM_UNLOCKED | DRM_AUTH),
167 170 PSB_IOCTL_DEF(DRM_IOCTL_PSB_2D_OP, psb_accel_ioctl, DRM_UNLOCKED),
168}; 171};
169 172
170static void psb_lastclose(struct drm_device *dev) 173static void psb_lastclose(struct drm_device *dev)
@@ -179,8 +182,7 @@ static void psb_do_takedown(struct drm_device *dev)
179 182
180static int psb_do_init(struct drm_device *dev) 183static int psb_do_init(struct drm_device *dev)
181{ 184{
182 struct drm_psb_private *dev_priv = 185 struct drm_psb_private *dev_priv = dev->dev_private;
183 (struct drm_psb_private *) dev->dev_private;
184 struct psb_gtt *pg = &dev_priv->gtt; 186 struct psb_gtt *pg = &dev_priv->gtt;
185 187
186 uint32_t stolen_gtt; 188 uint32_t stolen_gtt;
@@ -221,6 +223,7 @@ static int psb_do_init(struct drm_device *dev)
221 223
222 224
223 spin_lock_init(&dev_priv->irqmask_lock); 225 spin_lock_init(&dev_priv->irqmask_lock);
226 mutex_init(&dev_priv->mutex_2d);
224 227
225 PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0); 228 PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
226 PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1); 229 PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index 12d13aed39db..db3e356d2860 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -599,6 +599,9 @@ struct drm_psb_private {
599 bool dsr_enable; 599 bool dsr_enable;
600 void (*exit_idle)(struct drm_device *dev, u32 update_src, void *p_surfaceAddr, bool check_hw_on_only); 600 void (*exit_idle)(struct drm_device *dev, u32 update_src, void *p_surfaceAddr, bool check_hw_on_only);
601 601
602 /* 2D acceleration */
603 struct mutex mutex_2d;
604
602 /* FIXME: Arrays anyone ? */ 605 /* FIXME: Arrays anyone ? */
603 struct mdfld_dsi_encoder *encoder0; 606 struct mdfld_dsi_encoder *encoder0;
604 struct mdfld_dsi_encoder *encoder2; 607 struct mdfld_dsi_encoder *encoder2;
@@ -744,8 +747,8 @@ extern void psbfb_copyarea(struct fb_info *info,
744 const struct fb_copyarea *region); 747 const struct fb_copyarea *region);
745extern int psbfb_sync(struct fb_info *info); 748extern int psbfb_sync(struct fb_info *info);
746extern void psb_spank(struct drm_psb_private *dev_priv); 749extern void psb_spank(struct drm_psb_private *dev_priv);
747extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, 750extern int psb_accel_ioctl(struct drm_device *dev, void *data,
748 unsigned size); 751 struct drm_file *file);
749 752
750/* 753/*
751 * psb_reset.c 754 * psb_reset.c