Commit bd7b9f91 authored by Alan Cox's avatar Alan Cox Committed by Greg Kroah-Hartman
Browse files

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: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent c5c44531
Loading
Loading
Loading
Loading
+57 −3
Original line number Diff line number Diff line
@@ -105,19 +105,20 @@ static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
 *	Issue one or more 2D commands to the accelerator. This needs to be
 *	serialized later when we add the GEM interfaces for acceleration
 */
int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
								unsigned size)
{
	int ret = 0;
	int i;
	unsigned submit_size;

	mutex_lock(&dev_priv->mutex_2d);
	while (size > 0) {
		submit_size = (size < 0x60) ? size : 0x60;
		size -= submit_size;
		ret = psb_2d_wait_available(dev_priv, submit_size);
		if (ret)
			return ret;
		        break;

		submit_size <<= 2;

@@ -126,7 +127,8 @@ int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,

		(void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4);
	}
	return 0;
	mutex_unlock(&dev_priv->mutex_2d);
	return ret;
}


@@ -326,6 +328,7 @@ int psbfb_sync(struct fb_info *info)
	unsigned long _end = jiffies + DRM_HZ;
	int busy = 0;

	mutex_lock(&dev_priv->mutex_2d);
	/*
	 * First idle the 2D engine.
	 */
@@ -354,5 +357,56 @@ int psbfb_sync(struct fb_info *info)
					_PSB_C2B_STATUS_BUSY) != 0);

out:
	mutex_unlock(&dev_priv->mutex_2d);
	return (busy) ? -EBUSY : 0;
}

int psb_accel_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct drm_psb_2d_op *op = data;
	u32 *op_ptr = &op->cmd[0];
	int i;
	struct drm_gem_object *obj;
	struct gtt_range *gtt;
	int err = -EINVAL;

	if (!dev_priv->ops->accel_2d)
		return -EOPNOTSUPP;
	if (op->size > PSB_2D_OP_BUFLEN)
		return -EINVAL;

	/* The GEM object being used. We need to support separate src/dst/etc
	   in the end but for now keep them all the same */
	obj = drm_gem_object_lookup(dev, file, op->src);
	if (obj == NULL)
		return -ENOENT;
	gtt = container_of(obj, struct gtt_range, gem);

	if (psb_gtt_pin(gtt) < 0)
		goto bad_2;
	for (i = 0; i < op->size; i++, op_ptr++) {
		u32 r = *op_ptr & 0xF0000000;
		/* Fill in the GTT offsets for the command buffer */
        	if (r == PSB_2D_SRC_SURF_BH ||
			r == PSB_2D_DST_SURF_BH || 
			r == PSB_2D_MASK_SURF_BH ||
			r == PSB_2D_PAT_SURF_BH) {
			i++;
			op_ptr++;
			if (i == op->size)
				goto bad;
                        if (*op_ptr)
				goto bad;
                        *op_ptr = gtt->offset;
                        continue;
                }
	}
	psbfb_2d_submit(dev_priv, op->cmd, op->size);
	err = 0;
bad:
	psb_gtt_unpin(gtt);
bad_2:
	drm_gem_object_unreference(obj);
	return err;
}
+1 −24
Original line number Diff line number Diff line
@@ -200,31 +200,8 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
static int psbfb_ioctl(struct fb_info *info, unsigned int cmd,
						unsigned long arg)
{
	struct psb_fbdev *fbdev = info->par;
	struct psb_framebuffer *psbfb = &fbdev->pfb;
	struct drm_device *dev = psbfb->base.dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	u32 __user *p = (u32 __user *)arg;
	u32 l;
	u32 buf[32];
	switch (cmd) {
	case 0x12345678:
		if (!capable(CAP_SYS_RAWIO))
			return -EPERM;
		if (!dev_priv->ops->accel_2d)
			return -EOPNOTSUPP;
		if (get_user(l, p))
			return -EFAULT;
		if (l > 32)
			return -EMSGSIZE;
		if (copy_from_user(buf, p + 1, l * sizeof(u32)))
			return -EFAULT;
		psbfb_2d_submit(dev_priv, buf, l);
		return 0;
	default:
	return -ENOTTY;
}
}

static struct fb_ops psbfb_ops = {
	.owner = THIS_MODULE,
+13 −0
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ struct drm_psb_register_rw_arg {
 */

#define DRM_PSB_GEM_CREATE	0x10
#define DRM_PSB_2D_OP		0x11
#define DRM_PSB_DPST		0x1B
#define DRM_PSB_GAMMA		0x1C
#define DRM_PSB_DPST_BL		0x1D
@@ -190,4 +191,16 @@ struct drm_psb_gem_create {
	__u32 pad;
};

#define PSB_2D_OP_BUFLEN		16

struct drm_psb_2d_op {
	__u32 src;		/* Handles, only src supported right now */
	__u32 dst;
	__u32 mask;
	__u32 pat;
	__u32 size;		/* In dwords of command */
	__u32 spare;		/* And bumps array to u64 align */
	__u32 cmd[PSB_2D_OP_BUFLEN];
};

#endif
+6 −3
Original line number Diff line number Diff line
@@ -124,6 +124,9 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
#define DRM_IOCTL_PSB_GEM_CREATE	\
		DRM_IOWR(DRM_PSB_GEM_CREATE + DRM_COMMAND_BASE, \
			 struct drm_psb_gem_create)
#define DRM_IOCTL_PSB_2D_OP	\
		DRM_IOW(DRM_PSB_2D_OP + DRM_COMMAND_BASE, \
			 struct drm_psb_2d_op)

static int psb_sizes_ioctl(struct drm_device *dev, void *data,
			   struct drm_file *file_priv);
@@ -164,7 +167,7 @@ static struct drm_ioctl_desc psb_ioctls[] = {
					psb_intel_get_pipe_from_crtc_id, 0),
	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_CREATE, psb_gem_create_ioctl,
						DRM_UNLOCKED | DRM_AUTH),

	PSB_IOCTL_DEF(DRM_IOCTL_PSB_2D_OP, psb_accel_ioctl, DRM_UNLOCKED),
};

static void psb_lastclose(struct drm_device *dev)
@@ -179,8 +182,7 @@ static void psb_do_takedown(struct drm_device *dev)

static int psb_do_init(struct drm_device *dev)
{
	struct drm_psb_private *dev_priv =
	    (struct drm_psb_private *) dev->dev_private;
	struct drm_psb_private *dev_priv = dev->dev_private;
	struct psb_gtt *pg = &dev_priv->gtt;

	uint32_t stolen_gtt;
@@ -221,6 +223,7 @@ static int psb_do_init(struct drm_device *dev)


	spin_lock_init(&dev_priv->irqmask_lock);
	mutex_init(&dev_priv->mutex_2d);

	PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
	PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
+5 −2
Original line number Diff line number Diff line
@@ -599,6 +599,9 @@ struct drm_psb_private {
	bool dsr_enable;
	void (*exit_idle)(struct drm_device *dev, u32 update_src, void *p_surfaceAddr, bool check_hw_on_only);

	/* 2D acceleration */
	struct mutex mutex_2d;

	/* FIXME: Arrays anyone ? */
	struct mdfld_dsi_encoder *encoder0;	
	struct mdfld_dsi_encoder *encoder2;	
@@ -744,8 +747,8 @@ extern void psbfb_copyarea(struct fb_info *info,
					const struct fb_copyarea *region);
extern int psbfb_sync(struct fb_info *info);
extern void psb_spank(struct drm_psb_private *dev_priv);
extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
					unsigned size);
extern int psb_accel_ioctl(struct drm_device *dev, void *data,
							struct drm_file *file);

/*
 * psb_reset.c