Skip to contentSkip to conversation

gma500: Cursor interface

PATCH In review Alan Cox 2 participants 16 messages Jul 15, 2011 Staging

lore
Share & tools
lore

Alan Cox

author
#0 lore raw

PATCH 1/15 gma500: Cursor interface

From: Alan Cox <[email protected]>

We need to provide an interface to create additional buffers for the cursor

---

 drivers/staging/gma500/gem.c     |   11 +++++++++++
 drivers/staging/gma500/psb_drm.h |   15 +++++++--------
 drivers/staging/gma500/psb_drv.c |    5 +++++
 drivers/staging/gma500/psb_drv.h |    8 +++++---
 4 files changed, 28 insertions(+), 11 deletions(-)
drivers/staging/gma500/gem.c +11 -0
index a63ad9e..68ecd5f 100644
@@ -250,3 +250,14 @@ fail:
 		return VM_FAULT_SIGBUS;
 	}
 }
+
+/*
+ *	GEM interfaces for our specific client
+ */
+int psb_gem_create_ioctl(struct drm_device *dev, void *data,
+					struct drm_file *file)
+{
+	struct drm_psb_gem_create *args = data;
+	return psb_gem_create(file, dev, args->size, &args->handle);
+}
+
drivers/staging/gma500/psb_drm.h +7 -8
index 5dcf045..7175117 100644
@@ -159,18 +159,11 @@ struct drm_psb_register_rw_arg {
  * corresponding defines where they're
  * defined elsewhere.
  */
-#define DRM_PVR_RESERVED1	0x12
-#define DRM_PVR_RESERVED2	0x13
-#define DRM_PVR_RESERVED3	0x14
-#define DRM_PVR_RESERVED4	0x15
-#define DRM_PVR_RESERVED5	0x16
 
+#define DRM_PSB_GEM_CREATE	0x10
 #define DRM_PSB_DPST		0x1B
 #define DRM_PSB_GAMMA		0x1C
 #define DRM_PSB_DPST_BL		0x1D
-
-#define DRM_PVR_RESERVED6	0x1E
-
 #define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F
 
 #define PSB_MODE_OPERATION_MODE_VALID	0x01
@@ -191,4 +184,10 @@ struct psb_drm_dpu_rect {
 	int width, height;    
 };  
 
+struct drm_psb_gem_create {
+	__u64 size;
+	__u32 handle;
+	__u32 pad;
+};
+
 #endif
drivers/staging/gma500/psb_drv.c +5 -0
index f626480..a753977 100644
@@ -121,6 +121,9 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
 #define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID	\
 		DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
 			 struct drm_psb_get_pipe_from_crtc_id_arg)
+#define DRM_IOCTL_PSB_GEM_CREATE	\
+		DRM_IOWR(DRM_PSB_GEM_CREATE + DRM_COMMAND_BASE, \
+			 struct drm_psb_gem_create)
 
 static int psb_sizes_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv);
@@ -159,6 +162,8 @@ static struct drm_ioctl_desc psb_ioctls[] = {
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
 	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID,
 					psb_intel_get_pipe_from_crtc_id, 0),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_CREATE, psb_gem_create_ioctl,
+						DRM_UNLOCKED | DRM_AUTH),
 
 };
 
drivers/staging/gma500/psb_drv.h +5 -3
index 50a4f17..12d13ae 100644
@@ -782,18 +782,20 @@ extern const struct drm_connector_helper_funcs
 					psb_intel_lvds_connector_helper_funcs;
 extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs;
 
-/* psb_gem.c */
+/* gem.c */
 extern int psb_gem_init_object(struct drm_gem_object *obj);
 extern void psb_gem_free_object(struct drm_gem_object *obj);
 extern int psb_gem_get_aperture(struct drm_device *dev, void *data,
-				struct drm_file *file);
+			struct drm_file *file);
 extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
 			struct drm_mode_create_dumb *args);
 extern int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
 			uint32_t handle);
 extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
-			 uint32_t handle, uint64_t *offset);
+			uint32_t handle, uint64_t *offset);
 extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
+extern int psb_gem_create_ioctl(struct drm_device *dev, void *data,
+			struct drm_file *file);
 
 /* psb_device.c */
 extern const struct psb_ops psb_chip_ops;
author
#1 lore raw

PATCH 2/15 gma500: Move the 2D operations into DRM

From: Alan Cox <[email protected]>

We currently have a test hack framebuffer mode ioctl, turn that into a DRM interface.

---

 drivers/staging/gma500/accel_2d.c    |   60 ++++++++++++++++++++++++++++++++--
 drivers/staging/gma500/framebuffer.c |   25 +-------------
 drivers/staging/gma500/psb_drm.h     |   13 +++++++
 drivers/staging/gma500/psb_drv.c     |    9 +++--
 drivers/staging/gma500/psb_drv.h     |    7 +++-
 5 files changed, 82 insertions(+), 32 deletions(-)
drivers/staging/gma500/accel_2d.c +57 -3
index c719017..ed00854 100644
@@ -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;
+}
drivers/staging/gma500/framebuffer.c +1 -24
index 76b986f..d890a50 100644
@@ -200,30 +200,7 @@ 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;
-	}
+	return -ENOTTY;
 }
 
 static struct fb_ops psbfb_ops = {
drivers/staging/gma500/psb_drm.h +13 -0
index 7175117..eef53f3 100644
@@ -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
drivers/staging/gma500/psb_drv.c +6 -3
index a753977..36bb716 100644
@@ -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);
drivers/staging/gma500/psb_drv.h +5 -2
index 12d13ae..db3e356 100644
@@ -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
author
#2 lore raw

PATCH 3/15 gma500: add an mmap ioctl

In reply to Alan Cox

From: Alan Cox <[email protected]>

This does the same as the dumb mmap but we want them separated in the ABI in case a future extension to the dumb interface means we can't treat them the same way.

---

 drivers/staging/gma500/gem.c     |    8 ++++++++
 drivers/staging/gma500/psb_drm.h |   12 ++++++++++++
 drivers/staging/gma500/psb_drv.c |    8 +++++++-
 drivers/staging/gma500/psb_drv.h |    2 ++
 4 files changed, 29 insertions(+), 1 deletions(-)
drivers/staging/gma500/gem.c +8 -0
index 68ecd5f..d7b74b6 100644
@@ -261,3 +261,11 @@ int psb_gem_create_ioctl(struct drm_device *dev, void *data,
 	return psb_gem_create(file, dev, args->size, &args->handle);
 }
 
+int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
+					struct drm_file *file)
+{
+	struct drm_psb_gem_mmap *args = data;
+	return dev->driver->dumb_map_offset(file, dev,
+						args->handle, &args->offset);
+}
+
drivers/staging/gma500/psb_drm.h +12 -0
index eef53f3..70115a9 100644
@@ -162,6 +162,7 @@ struct drm_psb_register_rw_arg {
 
 #define DRM_PSB_GEM_CREATE	0x10
 #define DRM_PSB_2D_OP		0x11
+#define DRM_PSB_GEM_MMAP	0x12
 #define DRM_PSB_DPST		0x1B
 #define DRM_PSB_GAMMA		0x1C
 #define DRM_PSB_DPST_BL		0x1D
@@ -203,4 +204,15 @@ struct drm_psb_2d_op {
 	__u32 cmd[PSB_2D_OP_BUFLEN];
 };
 
+struct drm_psb_gem_mmap {
+	__u32 handle;
+	__u32 pad;
+	/**
+	 * Fake offset to use for subsequent mmap call
+	 *
+	 * This is a fixed-size type for 32/64 compatibility.
+	 */
+	__u64 offset;
+};
+
 #endif
drivers/staging/gma500/psb_drv.c +7 -1
index 36bb716..b8b9864 100644
@@ -127,6 +127,9 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
 #define DRM_IOCTL_PSB_2D_OP	\
 		DRM_IOW(DRM_PSB_2D_OP + DRM_COMMAND_BASE, \
 			 struct drm_psb_2d_op)
+#define DRM_IOCTL_PSB_GEM_MMAP	\
+		DRM_IOWR(DRM_PSB_GEM_MMAP + DRM_COMMAND_BASE, \
+			 struct drm_psb_gem_mmap)
 
 static int psb_sizes_ioctl(struct drm_device *dev, void *data,
 			   struct drm_file *file_priv);
@@ -167,7 +170,10 @@ 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),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_2D_OP, psb_accel_ioctl,
+						DRM_UNLOCKED| DRM_AUTH),
+	PSB_IOCTL_DEF(DRM_IOCTL_PSB_GEM_MMAP, psb_gem_mmap_ioctl,
+						DRM_UNLOCKED | DRM_AUTH),
 };
 
 static void psb_lastclose(struct drm_device *dev)
drivers/staging/gma500/psb_drv.h +2 -0
index db3e356..daf3ca5 100644
@@ -799,6 +799,8 @@ extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
 extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 extern int psb_gem_create_ioctl(struct drm_device *dev, void *data,
 			struct drm_file *file);
+extern int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
+					struct drm_file *file);
 
 /* psb_device.c */
 extern const struct psb_ops psb_chip_ops;
author
#3 lore raw

PATCH 4/15 gma500: allow the creation of 'stolen' memory objects

In reply to Alan Cox

From: Alan Cox <[email protected]>

For things like cursors and many kinds of framebuffer set up we are actually best using the stolen memory when possible.

---

 drivers/staging/gma500/gem.c     |   24 ++++++++++++++++++++++++
 drivers/staging/gma500/psb_drm.h |    3 ++-
 2 files changed, 26 insertions(+), 1 deletions(-)
drivers/staging/gma500/gem.c +24 -0
index d7b74b6..65fdd6b 100644
@@ -251,6 +251,21 @@ fail:
 	}
 }
 
+static int psb_gem_create_stolen(struct drm_file *file, struct drm_device *dev,
+						int size, u32 *handle)
+{
+	struct gtt_range *gtt = psb_gtt_alloc_range(dev, size, "gem", 1);
+	if (gtt == NULL)
+		return -ENOMEM;
+	if (drm_gem_private_object_init(dev, &gtt->gem, size) != 0)
+		goto free_gtt;
+	if (drm_gem_handle_create(file, &gtt->gem, handle) == 0)
+		return 0;
+free_gtt:
+	psb_gtt_free_range(dev, gtt);
+	return -ENOMEM;
+}
+
 /*
  *	GEM interfaces for our specific client
  */
@@ -258,6 +273,15 @@ int psb_gem_create_ioctl(struct drm_device *dev, void *data,
 					struct drm_file *file)
 {
 	struct drm_psb_gem_create *args = data;
+	int ret;
+	if (args->flags & PSB_GEM_CREATE_STOLEN) {
+		ret = psb_gem_create_stolen(file, dev, args->size,
+							&args->handle);
+		if (ret == 0)
+			return 0;
+		/* Fall throguh */
+		args->flags &= ~PSB_GEM_CREATE_STOLEN;
+	}
 	return psb_gem_create(file, dev, args->size, &args->handle);
 }
 
drivers/staging/gma500/psb_drm.h +2 -1
index 70115a9..0da8468 100644
@@ -189,7 +189,8 @@ struct psb_drm_dpu_rect {
 struct drm_psb_gem_create {
 	__u64 size;
 	__u32 handle;
-	__u32 pad;
+	__u32 flags;
+#define PSB_GEM_CREATE_STOLEN		1	/* Stolen memory can be used */
 };
 
 #define PSB_2D_OP_BUFLEN		16
author
#4 lore raw

PATCH 5/15 gma500: remove the legacy PM method

In reply to Alan Cox

From: Octavian Purdila <[email protected]>

PCI core only prefer one of legacy PM and new PM. And since runtime pm is implemented, which requires the new PM method, we should remove the legacy PM method.

---

 drivers/staging/gma500/power.c   |    9 +++++----
 drivers/staging/gma500/power.h   |    4 ++--
 drivers/staging/gma500/psb_drv.c |    6 ++----
 3 files changed, 9 insertions(+), 10 deletions(-)
drivers/staging/gma500/power.c +5 -4
index 5cd5023..972bea7 100644
@@ -185,8 +185,9 @@ static bool gma_resume_pci(struct pci_dev *pdev)
  *	perform the necessary shut down steps and save enough state that
  *	we can undo this when resume is called.
  */
-int gma_power_suspend(struct pci_dev *pdev, pm_message_t state)
+int gma_power_suspend(struct device *_dev)
 {
+	struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev);
 	struct drm_device *dev = pci_get_drvdata(pdev);
 	struct drm_psb_private *dev_priv = dev->dev_private;
 
@@ -210,8 +211,9 @@ int gma_power_suspend(struct pci_dev *pdev, pm_message_t state)
  *
  *	Resume the PCI side of the graphics and then the displays
  */
-int gma_power_resume(struct pci_dev *pdev)
+int gma_power_resume(struct device *_dev)
 {
+	struct pci_dev *pdev = container_of(_dev, struct pci_dev, dev);
 	struct drm_device *dev = pci_get_drvdata(pdev);
 
 	mutex_lock(&power_mutex);
@@ -295,8 +297,7 @@ void gma_power_end(struct drm_device *dev)
 
 int psb_runtime_suspend(struct device *dev)
 {
-	static pm_message_t dummy;
-	return gma_power_suspend(to_pci_dev(dev), dummy);
+	return gma_power_suspend(dev);
 }
 
 int psb_runtime_resume(struct device *dev)
drivers/staging/gma500/power.h +2 -2
index 333b28d..1969d2e 100644
@@ -39,8 +39,8 @@ void gma_power_uninit(struct drm_device *dev);
 /*
  * The kernel bus power management  will call these functions
  */
-int gma_power_suspend(struct pci_dev *pdev, pm_message_t state);
-int gma_power_resume(struct pci_dev *pdev);
+int gma_power_suspend(struct device *dev);
+int gma_power_resume(struct device *dev);
 
 /*
  * These are the functions the driver should use to wrap all hw access
drivers/staging/gma500/psb_drv.c +2 -4
index b8b9864..f96a619 100644
@@ -1144,6 +1144,8 @@ static void psb_remove(struct pci_dev *pdev)
 }
 
 static const struct dev_pm_ops psb_pm_ops = {
+	.resume = gma_power_resume,
+	.suspend = gma_power_suspend,
 	.runtime_suspend = psb_runtime_suspend,
 	.runtime_resume = psb_runtime_resume,
 	.runtime_idle = psb_runtime_idle,
@@ -1205,13 +1207,9 @@ static struct drm_driver driver = {
 static struct pci_driver psb_pci_driver = {
 	.name = DRIVER_NAME,
 	.id_table = pciidlist,
-	.resume = gma_power_resume,
-	.suspend = gma_power_suspend,
 	.probe = psb_probe,
 	.remove = psb_remove,
-#ifdef CONFIG_PM
 	.driver.pm = &psb_pm_ops,
-#endif
 };
 
 static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
author
#5 lore raw

PATCH 6/15 gma500: Make crtc count a property of the device

In reply to Alan Cox

From: Alan Cox <[email protected]>

Octavian Purdila posted a patch that sets num_crtc to 1 for Moorestown, but Oaktrail has 2 so we need to split Oaktrail/Moorestown more sensibly, and also cope with some other differences later on.

---

 drivers/staging/gma500/framebuffer.c  |    2 +-
 drivers/staging/gma500/mdfld_device.c |    1 +
 drivers/staging/gma500/mrst_device.c  |   41 +++++++++++++++++++++++++++++++++
 drivers/staging/gma500/psb_device.c   |    1 +
 drivers/staging/gma500/psb_drv.h      |    1 +
 5 files changed, 45 insertions(+), 1 deletions(-)
drivers/staging/gma500/framebuffer.c +1 -1
index d890a50..ebfde13 100644
@@ -578,7 +578,7 @@ int psb_fbdev_init(struct drm_device *dev)
 	dev_priv->fbdev = fbdev;
 	fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs;
 
-	drm_fb_helper_init(dev, &fbdev->psb_fb_helper, 2,
+	drm_fb_helper_init(dev, &fbdev->psb_fb_helper, dev_priv->ops->crtcs,
 							INTELFB_CONN_LIMIT);
 
 	drm_fb_helper_single_add_all_connectors(&fbdev->psb_fb_helper);
drivers/staging/gma500/mdfld_device.c +1 -0
index f258b06..f47aeb7 100644
@@ -691,6 +691,7 @@ const struct psb_ops mdfld_chip_ops = {
 	.name = "Medfield",
 	.accel_2d = 0,
 	.pipes = 3,
+	.crtcs = 2,
 	.sgx_offset = MRST_SGX_OFFSET,
 
 	.chip_setup = mid_chip_setup,
drivers/staging/gma500/mrst_device.c +41 -0

60 lines not on this page · raw message

drivers/staging/gma500/psb_device.c +1 -0
index 1e117f0..4659132 100644
@@ -331,6 +331,7 @@ const struct psb_ops psb_chip_ops = {
 	.name = "Poulsbo",
 	.accel_2d = 1,
 	.pipes = 2,
+	.crtcs = 2,
 	.sgx_offset = PSB_SGX_OFFSET,
 	.chip_setup = psb_chip_setup,
 
drivers/staging/gma500/psb_drv.h +1 -0
index daf3ca5..8184c23 100644
@@ -622,6 +622,7 @@ struct psb_ops {
 	const char *name;
 	unsigned int accel_2d:1;
 	int pipes;		/* Number of output pipes */
+	int crtcs;		/* Number of CRTCs */
 	int sgx_offset;		/* Base offset of SGX device */
 
 	/* Sub functions */
author
#6 lore raw

PATCH 7/15 gma500: fix compile warnings when CONFIG_BACKLIGHT_CLASS_DEVICE is not defined

In reply to Alan Cox

From: Octavian Purdila <[email protected]>

[Fixed up for other changes, and tidied some existing variable names]

---

 drivers/staging/gma500/backlight.c        |    2 ++
 drivers/staging/gma500/mdfld_dsi_output.c |    5 ++---
 drivers/staging/gma500/psb_drv.c          |   28 +++++++++++++---------------
 drivers/staging/gma500/psb_intel_lvds.c   |   19 +++++++------------
 4 files changed, 24 insertions(+), 30 deletions(-)
drivers/staging/gma500/backlight.c +2 -0
index d3e698b..2079395 100644
@@ -31,6 +31,8 @@ int gma_backlight_init(struct drm_device *dev)
 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	return dev_priv->ops->backlight_init(dev);
+#else
+	return 0;
 #endif
 }
 
drivers/staging/gma500/mdfld_dsi_output.c +2 -3
index e911ef2..ff75ece 100644
@@ -467,8 +467,6 @@ static int mdfld_dsi_connector_set_property(struct drm_connector * connector,
 											uint64_t value)
 {
 	struct drm_encoder * encoder = connector->encoder;
-	struct backlight_device * psb_bd;
-	struct drm_psb_private * dev_priv = encoder->dev->dev_private;
 
 	if (!strcmp(property->name, "scaling mode") && encoder) {
 		struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc);
@@ -515,13 +513,14 @@ static int mdfld_dsi_connector_set_property(struct drm_connector * connector,
 		}
 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
 	} else if (!strcmp(property->name, "backlight") && encoder) {
+		struct drm_psb_private *dev_priv = encoder->dev->dev_private;
+		struct backlight_device *psb_bd = dev_priv->backlight_device;
 		dev_dbg(encoder->dev->dev, "backlight level = %d\n", (int)value);
 		if (drm_connector_property_set_value(connector, property, value))
 			goto set_prop_error;
 		else {
 			dev_dbg(encoder->dev->dev,
 			                "set brightness to %d", (int)value);
-			psb_bd = dev_priv->backlight_device;
 			if (psb_bd) {
 				psb_bd->props.brightness = value;
 				backlight_update_status(psb_bd);
drivers/staging/gma500/psb_drv.c +13 -15
index f96a619..6b03951ebd 100644
@@ -536,20 +536,24 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
 	return -EINVAL;
 }
 
-static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
-		       struct drm_file *file_priv)
+static inline void get_brightness(struct backlight_device *bd)
 {
-	struct drm_psb_private *dev_priv = psb_priv(dev);
-	uint32_t *arg = data;
-	struct backlight_device *bd = dev_priv->backlight_device;
-	dev_priv->blc_adj2 = *arg;
-
 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
 	if (bd) {
 		bd->props.brightness = bd->ops->get_brightness(bd);
 		backlight_update_status(bd);
 	}
 #endif
+}
+
+static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
+		       struct drm_file *file_priv)
+{
+	struct drm_psb_private *dev_priv = psb_priv(dev);
+	uint32_t *arg = data;
+
+	dev_priv->blc_adj2 = *arg;
+	get_brightness(dev_priv->backlight_device);
 	return 0;
 }
 
@@ -558,15 +562,9 @@ static int psb_adb_ioctl(struct drm_device *dev, void *data,
 {
 	struct drm_psb_private *dev_priv = psb_priv(dev);
 	uint32_t *arg = data;
-	struct backlight_device *bd = dev_priv->backlight_device;
-	dev_priv->blc_adj1 = *arg;
 
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-	if (bd) {
-		bd->props.brightness = bd->ops->get_brightness(bd);
-		backlight_update_status(bd);
-	}
-#endif
+	dev_priv->blc_adj1 = *arg;
+	get_brightness(dev_priv->backlight_device);
 	return 0;
 }
 
drivers/staging/gma500/psb_intel_lvds.c +7 -12
index 03132a4..da6f5c8 100644
@@ -467,8 +467,6 @@ static void psb_intel_lvds_mode_set(struct drm_encoder *encoder,
 				struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode)
 {
-	struct psb_intel_mode_device *mode_dev =
-	    enc_to_psb_intel_output(encoder)->mode_dev;
 	struct drm_device *dev = encoder->dev;
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	u32 pfit_control;
@@ -571,17 +569,14 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
 				       uint64_t value)
 {
 	struct drm_encoder *encoder = connector->encoder;
-	struct drm_psb_private *dev_priv;
 
 	if (!encoder)
 		return -1;
 
-	dev_priv = encoder->dev->dev_private;
-
 	if (!strcmp(property->name, "scaling mode")) {
 		struct psb_intel_crtc *crtc =
 					to_psb_intel_crtc(encoder->crtc);
-		uint64_t curValue;
+		uint64_t curval;
 
 		if (!crtc)
 			goto set_prop_error;
@@ -599,10 +594,10 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
 
 		if (drm_connector_property_get_value(connector,
 						     property,
-						     &curValue))
+						     &curval))
 			goto set_prop_error;
 
-		if (curValue == value)
+		if (curval == value)
 			goto set_prop_done;
 
 		if (drm_connector_property_set_value(connector,
@@ -626,8 +621,8 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
 			goto set_prop_error;
 		else {
 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
-			struct backlight_device *bd =
-					dev_priv->backlight_device;
+			struct drm_psb_private *devp = encoder->dev->dev_private;
+			struct backlight_device *bd = devp->backlight_device;
 			if (bd) {
 				bd->props.brightness = value;
 				backlight_update_status(bd);
@@ -635,9 +630,9 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
 #endif
 		}
 	} else if (!strcmp(property->name, "DPMS")) {
-		struct drm_encoder_helper_funcs *pEncHFuncs
+		struct drm_encoder_helper_funcs *hfuncs
 						= encoder->helper_private;
-		pEncHFuncs->dpms(encoder, value);
+		hfuncs->dpms(encoder, value);
 	}
 
 set_prop_done:
author
#7 lore raw

PATCH 8/15 gma500: skip getting modes via DDC on Moorestown

In reply to Alan Cox

From: Octavian Purdila <[email protected]>

Moorestown does not have a DDC bus, skip getting modes via DDC. This fixes the following bug:

BUG: unable to handle kernel NULL pointer dereference at 00000010
IP: [<c1172ff7>] i2c_transfer+0x17/0xb0
*pde = 00000000
Oops: 0000 [#1]

Call Trace:
 [<c1153ae9>] drm_do_probe_ddc_edid+0x59/0x90
 [<c1153cb4>] drm_get_edid+0x24/0x250
 [<c11805d2>] psb_intel_ddc_get_modes+0x22/0x60
 [<c117fe11>] psb_intel_lvds_get_modes+0x21/0x80

---

 drivers/staging/gma500/psb_intel_lvds.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/staging/gma500/psb_intel_lvds.c +2 -1
index da6f5c8..53803b2 100644
@@ -521,7 +521,8 @@ static int psb_intel_lvds_get_modes(struct drm_connector *connector)
 					psb_intel_output->mode_dev;
 	int ret = 0;
 
-	ret = psb_intel_ddc_get_modes(psb_intel_output);
+	if (!IS_MRST(dev))
+		ret = psb_intel_ddc_get_modes(psb_intel_output);
 
 	if (ret)
 		return ret;
author
#8 lore raw

PATCH 9/15 gma500: Fix cdv warning on unused variable

In reply to Alan Cox

From: Alan Cox <[email protected]>

---

 drivers/staging/gma500/cdv_intel_lvds.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)
drivers/staging/gma500/cdv_intel_lvds.c +0 -2
index d9478d5..988b2d0 100644
@@ -353,8 +353,6 @@ static void cdv_intel_lvds_mode_set(struct drm_encoder *encoder,
 				struct drm_display_mode *mode,
 				struct drm_display_mode *adjusted_mode)
 {
-	struct psb_intel_mode_device *mode_dev =
-	    enc_to_psb_intel_output(encoder)->mode_dev;
 	struct drm_device *dev = encoder->dev;
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	u32 pfit_control;
author
#9 lore raw

PATCH 10/15 gma500: Add the Oaktrail HDMI support

In reply to Alan Cox

From: Alan Cox <[email protected]>

This differs enough from the Cedarview HDMI sufficiently to want to keep them separated.

We need to sort out the power management for Oaktrail/Moorestown in order to plumb this lot into the register handling logic.

---

 drivers/staging/gma500/Makefile        |    4 
 drivers/staging/gma500/mrst.h          |   35 +
 drivers/staging/gma500/mrst_device.c   |  246 +++++++--
 drivers/staging/gma500/mrst_hdmi.c     |  852 ++++++++++++++++++++++++++++++++
 drivers/staging/gma500/mrst_hdmi_i2c.c |  327 ++++++++++++
 drivers/staging/gma500/psb_drv.c       |    2 
 drivers/staging/gma500/psb_drv.h       |    4 
 7 files changed, 1401 insertions(+), 69 deletions(-)
 create mode 100644 drivers/staging/gma500/mrst_hdmi.c
 create mode 100644 drivers/staging/gma500/mrst_hdmi_i2c.c
drivers/staging/gma500/Makefile +3 -1
index e515edf..fe34f18 100644
@@ -32,7 +32,9 @@ psb_gfx-$(CONFIG_DRM_PSB_CDV) +=  cdv_device.o \
 
 psb_gfx-$(CONFIG_DRM_PSB_MRST) += mrst_device.o \
 	  mrst_crtc.o \
-	  mrst_lvds.o
+	  mrst_lvds.o \
+	  mrst_hdmi.o \
+	  mrst_hdmi_i2c.o
 
 psb_gfx-$(CONFIG_DRM_PSB_MFLD) += mdfld_device.o \
 	  mdfld_output.o \
drivers/staging/gma500/mrst.h +35 -0
index 7bacb9a..b563dbc 100644
@@ -215,3 +215,38 @@ struct mrst_gct_data {
 
 #define GCT_R10_HEADER_SIZE		16
 #define GCT_R10_DISPLAY_DESC_SIZE	28
+
+/*
+ *	Moorestown HDMI interfaces
+ */
+
+struct mrst_hdmi_dev {
+	struct pci_dev *dev;
+	void __iomem *regs;
+	unsigned int mmio, mmio_len;
+	int dpms_mode;
+	struct hdmi_i2c_dev *i2c_dev;
+
+	/* register state */
+	u32 saveDPLL_CTRL;
+	u32 saveDPLL_DIV_CTRL;
+	u32 saveDPLL_ADJUST;
+	u32 saveDPLL_UPDATE;
+	u32 saveDPLL_CLK_ENABLE;
+	u32 savePCH_HTOTAL_B;
+	u32 savePCH_HBLANK_B;
+	u32 savePCH_HSYNC_B;
+	u32 savePCH_VTOTAL_B;
+	u32 savePCH_VBLANK_B;
+	u32 savePCH_VSYNC_B;
+	u32 savePCH_PIPEBCONF;
+	u32 savePCH_PIPEBSRC;
+};
+
+extern void mrst_hdmi_setup(struct drm_device *dev);
+extern void mrst_hdmi_teardown(struct drm_device *dev);
+extern int  mrst_hdmi_i2c_init(struct pci_dev *dev);
+extern void mrst_hdmi_i2c_exit(struct pci_dev *dev);
+extern void mrst_hdmi_save(struct drm_device *dev);
+extern void mrst_hdmi_restore(struct drm_device *dev);
+extern void mrst_hdmi_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev);
drivers/staging/gma500/mrst_device.c +178 -68

302 lines not on this page · raw message

drivers/staging/gma500/mrst_hdmi.c new file +852 -0

852 lines not on this page · raw message

drivers/staging/gma500/mrst_hdmi_i2c.c new file +327 -0

327 lines not on this page · raw message

drivers/staging/gma500/psb_drv.c +2 -0
index 6b03951ebd..4b740aa 100644
@@ -261,6 +261,8 @@ static int psb_driver_unload(struct drm_device *dev)
 		psb_lid_timer_takedown(dev_priv);
 		gma_intel_opregion_exit(dev);
 
+		if (dev_priv->ops->chip_teardown)
+			dev_priv->ops->chip_teardown(dev);
 		psb_do_takedown(dev);
 
 
drivers/staging/gma500/psb_drv.h +4 -0
index 8184c23..25275f7 100644
@@ -375,6 +375,9 @@ struct drm_psb_private {
 	bool dbi_panel_on2;	/* The DBI panel power is on */
 	u32 dsr_fb_update;	/* DSR FB update counter */
 
+	/* Moorestown HDMI state */
+	struct mrst_hdmi_dev *hdmi_priv;
+
 	/* Moorestown pipe config register value cache */
 	uint32_t pipeconf;
 	uint32_t pipeconf1;
@@ -631,6 +634,7 @@ struct psb_ops {
 
 	/* Setup hooks */
 	int (*chip_setup)(struct drm_device *dev);
+	void (*chip_teardown)(struct drm_device *dev);
 
 	/* Display management hooks */
 	int (*output_init)(struct drm_device *dev);
author
#10 lore raw

PATCH 11/15 gma500: More Moorestown muddle meddling means MM maybe might modeset

In reply to Alan Cox

From: Alan Cox <[email protected]>

There are a least three different species we need to deal with and right now it seems the only way to sort them out is via DMI. Encapsulate the entire pile somewhere private and out of the way.

Hopefully a saner method will emerge later.

---

 drivers/staging/gma500/mrst_device.c |  150 +++++++++++++++++++++++++++++-----
 drivers/staging/gma500/mrst_lvds.c   |    5 +
 drivers/staging/gma500/psb_drv.h     |    8 ++
 3 files changed, 141 insertions(+), 22 deletions(-)
drivers/staging/gma500/mrst_device.c +129 -21
index 20677f9..573142f 100644
@@ -18,6 +18,8 @@
  **************************************************************************/
 
 #include <linux/backlight.h>
+#include <linux/module.h>
+#include <linux/dmi.h>
 #include <drm/drmP.h>
 #include <drm/drm.h>
 #include "psb_drm.h"
@@ -28,7 +30,33 @@
 #include <asm/intel_scu_ipc.h>
 #include "mid_bios.h"
 
-static const struct psb_ops oaktrail_chip_ops;
+static int devtype;
+
+module_param_named(type, devtype, int, 0600);
+MODULE_PARM_DESC(type, "Moorestown/Oaktrail device type");
+
+#define DEVICE_MOORESTOWN		1
+#define DEVICE_OAKTRAIL			2
+#define DEVICE_MOORESTOWN_MM		3
+
+static int mrst_device_ident(struct drm_device *dev)
+{
+	/* User forced */
+	if (devtype)
+		return devtype;
+	if (dmi_match(DMI_PRODUCT_NAME, "OakTrail") ||
+		dmi_match(DMI_PRODUCT_NAME, "OakTrail platform"))
+		return DEVICE_OAKTRAIL;
+#if defined(CONFIG_X86_MRST)
+	if (dmi_match(DMI_PRODUCT_NAME, "MM") ||
+		dmi_match(DMI_PRODUCT_NAME, "MM 10"))
+		return DEVICE_MOORESTOWN_MM;
+	if (mrst_identify_cpu())
+		return DEVICE_MOORESTOWN;
+#endif
+	return DEVICE_OAKTRAIL;
+}
+
 
 /* IPC message and command defines used to enable/disable mipi panel voltages */
 #define IPC_MSG_PANEL_ON_OFF    0xE9
@@ -266,8 +294,10 @@ static int mrst_save_display_registers(struct drm_device *dev)
 	dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
 
 	/* DPST registers */
-	dev_priv->saveHISTOGRAM_INT_CONTROL_REG = PSB_RVDC32(HISTOGRAM_INT_CONTROL);
-	dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG = PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
+	dev_priv->saveHISTOGRAM_INT_CONTROL_REG =
+					PSB_RVDC32(HISTOGRAM_INT_CONTROL);
+	dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG =
+					PSB_RVDC32(HISTOGRAM_LOGIC_CONTROL);
 	dev_priv->savePWM_CONTROL_LOGIC = PSB_RVDC32(PWM_CONTROL_LOGIC);
 
 	if (dev_priv->iLVDS_enable) {
@@ -282,7 +312,7 @@ static int mrst_save_display_registers(struct drm_device *dev)
 		PSB_WVDC32(0x58000000, DSPACNTR);
 		/* Trigger the plane disable */
 		PSB_WVDC32(0, DSPASURF);
-		
+
 		/* Wait ~4 ticks */
 		msleep(4);
 
@@ -401,8 +431,10 @@ static int mrst_restore_display_registers(struct drm_device *dev)
 	PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
 
 	/* DPST registers */
-	PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG, HISTOGRAM_INT_CONTROL);
-	PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG, HISTOGRAM_LOGIC_CONTROL);
+	PSB_WVDC32(dev_priv->saveHISTOGRAM_INT_CONTROL_REG,
+						HISTOGRAM_INT_CONTROL);
+	PSB_WVDC32(dev_priv->saveHISTOGRAM_LOGIC_CONTROL_REG,
+						HISTOGRAM_LOGIC_CONTROL);
 	PSB_WVDC32(dev_priv->savePWM_CONTROL_LOGIC, PWM_CONTROL_LOGIC);
 
 	return 0;
@@ -458,38 +490,44 @@ static int mrst_power_up(struct drm_device *dev)
 	return 0;
 }
 
-static int mrst_chip_setup(struct drm_device *dev)
+#if defined(CONFIG_X86_MRST)
+static void mrst_lvds_cache_bl(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
 
-#if defined(CONFIG_X86_MRST)
-	if (mrst_identify_cpu())
-		return mid_chip_setup(dev);
-#endif
-	dev_priv->ops = &oaktrail_chip_ops;
-	mrst_hdmi_setup(dev);
-	/* Check - may be better to go via BIOS paths ? */
-	return mid_chip_setup(dev);
+	intel_scu_ipc_ioread8(0x28, &(dev_priv->saveBKLTCNT));
+	intel_scu_ipc_ioread8(0x29, &(dev_priv->saveBKLTREQ));
+	intel_scu_ipc_ioread8(0x2A, &(dev_priv->saveBKLTBRTL));
 }
 
-static void oaktrail_teardown(struct drm_device *dev)
+static void mrst_mm_bl_power(struct drm_device *dev, bool on)
 {
-	mrst_hdmi_teardown(dev);
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	if (on) {
+		intel_scu_ipc_iowrite8(0x2A, dev_priv->saveBKLTBRTL);
+		intel_scu_ipc_iowrite8(0x28, dev_priv->saveBKLTCNT);
+		intel_scu_ipc_iowrite8(0x29, dev_priv->saveBKLTREQ);
+	} else {
+		intel_scu_ipc_iowrite8(0x2A, 0);
+		intel_scu_ipc_iowrite8(0x28, 0);
+		intel_scu_ipc_iowrite8(0x29, 0);
+	}
 }
-	
-const struct psb_ops mrst_chip_ops = {
-	.name = "Moorestown",
+
+static const struct psb_ops mrst_mm_chip_ops = {
+	.name = "Moorestown MM ",
 	.accel_2d = 1,
 	.pipes = 1,
 	.crtcs = 1,
 	.sgx_offset = MRST_SGX_OFFSET,
 
-	.chip_setup = mrst_chip_setup,
 	.crtc_helper = &mrst_helper_funcs,
 	.crtc_funcs = &psb_intel_crtc_funcs,
 
 	.output_init = mrst_output_init,
 
+	.lvds_bl_power = mrst_mm_bl_power,
 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
 	.backlight_init = mrst_backlight_init,
 #endif
@@ -499,8 +537,17 @@ const struct psb_ops mrst_chip_ops = {
 	.restore_regs = mrst_restore_display_registers,
 	.power_down = mrst_power_down,
 	.power_up = mrst_power_up,
+
+	.i2c_bus = 0,
 };
 
+#endif
+
+static void oaktrail_teardown(struct drm_device *dev)
+{
+	mrst_hdmi_teardown(dev);
+}
+
 static const struct psb_ops oaktrail_chip_ops = {
 	.name = "Oaktrail",
 	.accel_2d = 1,
@@ -524,5 +571,66 @@ static const struct psb_ops oaktrail_chip_ops = {
 	.restore_regs = mrst_restore_display_registers,
 	.power_down = mrst_power_down,
 	.power_up = mrst_power_up,
+
+	.i2c_bus = 1,
+};
+
+/**
+ *	mrst_chip_setup		-	perform the initial chip init
+ *	@dev: Our drm_device
+ *
+ *	Figure out which incarnation we are and then scan the firmware for
+ *	tables and information.
+ */
+static int mrst_chip_setup(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+
+	switch (mrst_device_ident(dev)) {
+	case DEVICE_OAKTRAIL:
+		/* Dual CRTC, PC compatible, HDMI, I2C #2 */
+		dev_priv->ops = &oaktrail_chip_ops;
+		mrst_hdmi_setup(dev);
+		return mid_chip_setup(dev);
+#if defined(CONFIG_X86_MRST)
+	case DEVICE_MOORESTOWN_MM:
+		/* Single CRTC, No HDMI, I2C #0, BL control */
+		mrst_lvds_cache_bl(dev);
+		dev_priv->ops = &mrst_mm_chip_ops;
+		return mid_chip_setup(dev);
+	case DEVICE_MOORESTOWN:
+		/* Dual CRTC, No HDMI(?), I2C #1 */
+		return mid_chip_setup(dev);
+#endif
+	default:
+		dev_err(dev->dev, "unsupported device type.\n");
+		return -ENODEV;
+	}
+}
+
+const struct psb_ops mrst_chip_ops = {
+	.name = "Moorestown",
+	.accel_2d = 1,
+	.pipes = 2,
+	.crtcs = 2,
+	.sgx_offset = MRST_SGX_OFFSET,
+
+	.chip_setup = mrst_chip_setup,
+	.crtc_helper = &mrst_helper_funcs,
+	.crtc_funcs = &psb_intel_crtc_funcs,
+
+	.output_init = mrst_output_init,
+
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+	.backlight_init = mrst_backlight_init,
+#endif
+
+	.init_pm = mrst_init_pm,
+	.save_regs = mrst_save_display_registers,
+	.restore_regs = mrst_restore_display_registers,
+	.power_down = mrst_power_down,
+	.power_up = mrst_power_up,
+
+	.i2c_bus = 2,
 };
 
drivers/staging/gma500/mrst_lvds.c +4 -1
index 3e15ecd..108f245 100644
@@ -58,7 +58,11 @@ static void mrst_lvds_set_power(struct drm_device *dev,
 			pp_status = REG_READ(PP_STATUS);
 		} while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
 		dev_priv->is_lvds_on = true;
+	        if (dev_priv->ops->lvds_bl_power)
+	                dev_priv->ops->lvds_bl_power(dev, true);
 	} else {
+	        if (dev_priv->ops->lvds_bl_power)
+	                dev_priv->ops->lvds_bl_power(dev, false);
 		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
 			  ~POWER_TARGET_ON);
 		do {
@@ -67,7 +71,6 @@ static void mrst_lvds_set_power(struct drm_device *dev,
 		dev_priv->is_lvds_on = false;
 		pm_request_idle(&dev->pdev->dev);
 	}
-
 	gma_power_end(dev);
 }
 
drivers/staging/gma500/psb_drv.h +8 -0
index 25275f7..829657b 100644
@@ -388,6 +388,11 @@ struct drm_psb_private {
 	uint32_t dspcntr1;
 	uint32_t dspcntr2;
 
+	/* Moorestown MM backlight cache */
+	uint8_t saveBKLTCNT;
+	uint8_t saveBKLTREQ;
+	uint8_t saveBKLTBRTL;
+
 	/*
 	 * Register state
 	 */
@@ -644,10 +649,13 @@ struct psb_ops {
 	int (*restore_regs)(struct drm_device *dev);
 	int (*power_up)(struct drm_device *dev);
 	int (*power_down)(struct drm_device *dev);
+
+	void (*lvds_bl_power)(struct drm_device *dev, bool on);
 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
 	/* Backlight */
 	int (*backlight_init)(struct drm_device *dev);
 #endif
+	int i2c_bus;		/* I2C bus identifier for Moorestown */
 };
 
 
author
#11 lore raw

PATCH 12/15 gma500@ Fix backlight range error

In reply to Alan Cox

From: Alan Cox <[email protected]>

If we go out of range we break the pm counts on the error path

---

 drivers/staging/gma500/mrst_device.c |   12 +++++-------
 1 files changed, 5 insertions(+), 7 deletions(-)
drivers/staging/gma500/mrst_device.c +5 -7
index 573142f..6707faf 100644
@@ -157,14 +157,12 @@ static int device_backlight_init(struct drm_device *dev)
 	value /= bl_max_freq;
 	value /= blc_pwm_precision_factor;
 
+	if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ)
+			return -ERANGE;
+
 	if (gma_power_begin(dev, false)) {
-		if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ)
-				return -ERANGE;
-		else {
-			REG_WRITE(BLC_PWM_CTL2,
-					(0x80000000 | REG_READ(BLC_PWM_CTL2)));
-			REG_WRITE(BLC_PWM_CTL, value | (value << 16));
-		}
+		REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
+		REG_WRITE(BLC_PWM_CTL, value | (value << 16));
 		gma_power_end(dev);
 	}
 	return 0;
author
#12 lore raw

PATCH 13/15 gma500: Use the mrst helpers and power control for mode commit

In reply to Alan Cox

From: Alan Cox <[email protected]>

We want to hit the MM panel backlight when appropriate

---

 drivers/staging/gma500/mrst_lvds.c      |   29 +++++++++++++++++++++++++++--
 drivers/staging/gma500/psb_drv.h        |    2 --
 drivers/staging/gma500/psb_intel_lvds.c |    4 ++--
 3 files changed, 29 insertions(+), 6 deletions(-)
drivers/staging/gma500/mrst_lvds.c +27 -2
index 108f245..25fde4c 100644
@@ -147,13 +147,38 @@ static void mrst_lvds_mode_set(struct drm_encoder *encoder,
 	gma_power_end(dev);
 }
 
+static void mrst_lvds_prepare(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+
+	if (!gma_power_begin(dev, true))
+		return;
+
+	mode_dev->saveBLC_PWM_CTL = REG_READ(BLC_PWM_CTL);
+	mode_dev->backlight_duty_cycle = (mode_dev->saveBLC_PWM_CTL &
+					  BACKLIGHT_DUTY_CYCLE_MASK);
+	mrst_lvds_set_power(dev, output, false);
+	gma_power_end(dev);
+}
+
+static void mrst_lvds_commit(struct drm_encoder *encoder)
+{
+	struct drm_device *dev = encoder->dev;
+	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+
+	if (mode_dev->backlight_duty_cycle == 0)
+		mode_dev->backlight_duty_cycle =
+		    psb_intel_lvds_get_max_backlight(dev);
+	mrst_lvds_set_power(dev, output, true);
+}
 
 static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = {
 	.dpms = mrst_lvds_dpms,
 	.mode_fixup = psb_intel_lvds_mode_fixup,
-	.prepare = psb_intel_lvds_prepare,
+	.prepare = mrst_intel_lvds_prepare,
 	.mode_set = mrst_lvds_mode_set,
-	.commit = psb_intel_lvds_commit,
+	.commit = mrst_intel_lvds_commit,
 };
 
 static struct drm_display_mode lvds_configuration_modes[] = {
drivers/staging/gma500/psb_drv.h +0 -2
index 829657b..194c64f 100644
@@ -792,8 +792,6 @@ extern const struct drm_crtc_helper_funcs psb_intel_helper_funcs;
 extern const struct drm_crtc_funcs psb_intel_crtc_funcs;
 
 /* psb_intel_lvds.c */
-extern void psb_intel_lvds_prepare(struct drm_encoder *encoder);
-extern void psb_intel_lvds_commit(struct drm_encoder *encoder);
 extern const struct drm_connector_helper_funcs
 					psb_intel_lvds_connector_helper_funcs;
 extern const struct drm_connector_funcs psb_intel_lvds_connector_funcs;
drivers/staging/gma500/psb_intel_lvds.c +2 -2
index 53803b2..c6436da 100644
@@ -432,7 +432,7 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
 	return true;
 }
 
-void psb_intel_lvds_prepare(struct drm_encoder *encoder)
+static void psb_intel_lvds_prepare(struct drm_encoder *encoder)
 {
 	struct drm_device *dev = encoder->dev;
 	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
@@ -450,7 +450,7 @@ void psb_intel_lvds_prepare(struct drm_encoder *encoder)
 	gma_power_end(dev);
 }
 
-void psb_intel_lvds_commit(struct drm_encoder *encoder)
+static void psb_intel_lvds_commit(struct drm_encoder *encoder)
 {
 	struct drm_device *dev = encoder->dev;
 	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
author
#13 lore raw

PATCH 14/15 gma500: resync with Medfield progress

In reply to Alan Cox

From: Alan Cox <[email protected]>

---

 drivers/staging/gma500/mdfld_dsi_dbi.c        |  369 ++++++++---------------
 drivers/staging/gma500/mdfld_dsi_dbi.h        |   21 -
 drivers/staging/gma500/mdfld_dsi_dbi_dpu.h    |    3 
 drivers/staging/gma500/mdfld_dsi_dpi.c        |  319 ++++----------------
 drivers/staging/gma500/mdfld_dsi_dpi.h        |    6 
 drivers/staging/gma500/mdfld_dsi_output.c     |  250 +++++++++-------
 drivers/staging/gma500/mdfld_dsi_output.h     |  203 -------------
 drivers/staging/gma500/mdfld_dsi_pkg_sender.c |  403 +++++++++++++++++++++++++
 drivers/staging/gma500/mdfld_dsi_pkg_sender.h |   26 ++
 drivers/staging/gma500/mdfld_intel_display.c  |    6 
 drivers/staging/gma500/mdfld_output.c         |    8 
 drivers/staging/gma500/mdfld_output.h         |   41 ---
 drivers/staging/gma500/mdfld_pyr_cmd.c        |   18 -
 drivers/staging/gma500/mdfld_tmd_vid.c        |   62 ++++
 drivers/staging/gma500/mdfld_tpo_cmd.c        |   64 +++-
 drivers/staging/gma500/mrst_lvds.c            |   35 ++
 drivers/staging/gma500/psb_drv.h              |    7 
 17 files changed, 917 insertions(+), 924 deletions(-)
drivers/staging/gma500/mdfld_dsi_dbi.c +134 -235
index 1421f49..06424f9 100644
@@ -39,29 +39,10 @@ extern int gfxrtdelay;
 int enter_dsr;
 struct mdfld_dsi_dbi_output *gdbi_output;
 extern bool gbgfxsuspended;
+extern int enable_gfx_rtpm;
 extern int gfxrtdelay;
 
-#ifdef CONFIG_GFX_RTPM
-static void psb_runtimepm_wq_handler(struct work_struct *work);
-DECLARE_DELAYED_WORK(rtpm_work, psb_runtimepm_wq_handler);
-
-void psb_runtimepm_wq_handler(struct work_struct *work)
-{
-	struct drm_psb_private *dev_priv =  gpDrmDevice->dev_private;
-
-	if (drm_psb_ospm && !enable_gfx_rtpm) {
-		pr_info("Enable GFX runtime_pm\n");
-		dev_priv->rpm_enabled = 1;
-		enable_gfx_rtpm = 1;
-
-		pm_runtime_enable(&gpDrmDevice->pdev->dev);
-		pm_runtime_set_active(&gpDrmDevice->pdev->dev);
-
-		pm_runtime_allow(&gpDrmDevice->pdev->dev);
-	}
-}
-#endif
-
+#define MDFLD_DSR_MAX_IDLE_COUNT	2
 
 /*
  * set refreshing area
@@ -80,8 +61,8 @@ int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
 		return -EINVAL;
 	}
 
-	/*set column*/
-	cmd = set_column_address;
+	/* Set column */
+	cmd = DCS_SET_COLUMN_ADDRESS;
 	param[0] = x1 >> 8;
 	param[1] = x1;
 	param[2] = x2 >> 8;
@@ -98,8 +79,8 @@ int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
 		goto err_out;
 	}
 
-	/*set page*/
-	cmd = set_page_addr;
+	/* Set page */
+	cmd = DCS_SET_PAGE_ADDRESS;
 	param[0] = y1 >> 8;
 	param[1] = y1;
 	param[2] = y2 >> 8;
@@ -139,56 +120,46 @@ int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
 								int mode)
 {
 	struct drm_device *dev = dbi_output->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
 	struct mdfld_dsi_pkg_sender *sender =
 		mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
 	u8 param = 0;
 	u32 err = 0;
 
-	if (!dev_priv->dispstatus && mode != DRM_MODE_DPMS_ON) {
-		dev_err(dev->dev, "%s: already OFF ignoring\n", __func__);
-		return 0;
-	}
-	if (dev_priv->dispstatus && mode == DRM_MODE_DPMS_ON) {
-		dev_err(dev->dev, "%s: already ON ignoring\n", __func__);
-		return 0;
-	}
-
 	if (!sender) {
 		WARN_ON(1);
 		return -EINVAL;
 	}
 
 	if (mode == DRM_MODE_DPMS_ON) {
-		/*exit sleep mode*/
+		/* Exit sleep mode */
 		err = mdfld_dsi_send_dcs(sender,
-					 exit_sleep_mode,
+					 DCS_EXIT_SLEEP_MODE,
 					 NULL,
 					 0,
 					 CMD_DATA_SRC_SYSTEM_MEM,
 					 MDFLD_DSI_QUEUE_PACKAGE);
 		if (err) {
 			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-						exit_sleep_mode);
+						DCS_EXIT_SLEEP_MODE);
 			goto power_err;
 		}
 
-		/*set display on*/
+		/* Set display on */
 		err = mdfld_dsi_send_dcs(sender,
-					 set_display_on,
+					 DCS_SET_DISPLAY_ON,
 					 NULL,
 					 0,
 					 CMD_DATA_SRC_SYSTEM_MEM,
 					 MDFLD_DSI_QUEUE_PACKAGE);
 		if (err) {
 			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-							set_display_on);
+							DCS_SET_DISPLAY_ON);
 			goto power_err;
 		}
 
 		/* set tear effect on */
 		err = mdfld_dsi_send_dcs(sender,
-					 set_tear_on,
+					 DCS_SET_TEAR_ON,
 					 &param,
 					 1,
 					 CMD_DATA_SRC_SYSTEM_MEM,
@@ -203,53 +174,53 @@ int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
 		 * FIXME: remove this later
 		 */
 		err = mdfld_dsi_send_dcs(sender,
-					 write_mem_start,
+					 DCS_WRITE_MEM_START,
 					 NULL,
 					 0,
 					 CMD_DATA_SRC_PIPE,
 					 MDFLD_DSI_QUEUE_PACKAGE);
 		if (err) {
 			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-							set_display_on);
+						DCS_WRITE_MEM_START);
 			goto power_err;
 		}
 	} else {
-		/*set tear effect off */
+		/* Set tear effect off */
 		err = mdfld_dsi_send_dcs(sender,
-					 set_tear_off,
+					 DCS_SET_TEAR_OFF,
 					 NULL,
 					 0,
 					 CMD_DATA_SRC_SYSTEM_MEM,
 					 MDFLD_DSI_QUEUE_PACKAGE);
 		if (err) {
 			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-							set_tear_off);
+							DCS_SET_TEAR_OFF);
 			goto power_err;
 		}
 
-		/*set display off*/
+		/* Turn display off */
 		err = mdfld_dsi_send_dcs(sender,
-					 set_display_off,
+					 DCS_SET_DISPLAY_OFF,
 					 NULL,
 					 0,
 					 CMD_DATA_SRC_SYSTEM_MEM,
 					 MDFLD_DSI_QUEUE_PACKAGE);
 		if (err) {
 			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-							set_display_off);
+						DCS_SET_DISPLAY_OFF);
 			goto power_err;
 		}
 
-		/*enter sleep mode*/
+		/* Now enter sleep mode */
 		err = mdfld_dsi_send_dcs(sender,
-					 enter_sleep_mode,
+					 DCS_ENTER_SLEEP_MODE,
 					 NULL,
 					 0,
 					 CMD_DATA_SRC_SYSTEM_MEM,
 					 MDFLD_DSI_QUEUE_PACKAGE);
 		if (err) {
 			dev_err(dev->dev, "DCS 0x%x sent failed\n",
-							enter_sleep_mode);
+							DCS_ENTER_SLEEP_MODE);
 			goto power_err;
 		}
 	}
@@ -283,7 +254,6 @@ int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
 	return ret;
 }
 
-
 /*
  * Enter DSR
  */
@@ -299,11 +269,12 @@ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
 	u32 pipeconf_reg = PIPEACONF;
 	u32 dspcntr_reg = DSPACNTR;
 
-	dev_priv->is_in_idle = true;
-
 	if (!dbi_output)
 		return;
 
+	/* FIXME check if can go */
+	dev_priv->is_in_idle = true;
+
 	gdbi_output = dbi_output;
 	if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
 		(psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
@@ -319,16 +290,17 @@ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
 		dev_err(dev->dev, "hw begin failed\n");
 		return;
 	}
-	/*disable te interrupts. */
+	/* Disable te interrupts */
 	mdfld_disable_te(dev, pipe);
 
-	/*disable plane*/
+	/* Disable plane */
 	reg_val = REG_READ(dspcntr_reg);
 	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
 		REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE);
 		REG_READ(dspcntr_reg);
 	}
-	/*disable pipe*/
+
+	/* Disable pipe */
 	reg_val = REG_READ(pipeconf_reg);
 	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
 		reg_val &= ~DISPLAY_PLANE_ENABLE;
@@ -338,7 +310,7 @@ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
 		mdfldWaitForPipeDisable(dev, pipe);
 	}
 
-	/*disable DPLL*/
+	/* Disable DPLL */
 	reg_val = REG_READ(dpll_reg);
 	if (!(reg_val & DPLL_VCO_ENABLE)) {
 		reg_val &= ~DPLL_VCO_ENABLE;
@@ -357,10 +329,9 @@ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
 
 #ifndef CONFIG_MDFLD_DSI_DPU
 static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
-			int pipe, void *p_surfaceAddr, bool check_hw_on_only)
+			int pipe)
 {
 	struct drm_device *dev = dbi_output->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
 	struct drm_crtc *crtc = dbi_output->base.base.crtc;
 	struct psb_intel_crtc *psb_crtc = (crtc) ?
 					to_psb_intel_crtc(crtc) : NULL;
@@ -368,7 +339,6 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
 	u32 dpll_reg = MRST_DPLL_A;
 	u32 pipeconf_reg = PIPEACONF;
 	u32 dspcntr_reg = DSPACNTR;
-	u32 dspsurf_reg = DSPASURF;
 	u32 reg_offset = 0;
 
 	/*if mode setting on-going, back off*/
@@ -380,24 +350,17 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
 		dpll_reg = MRST_DPLL_A;
 		pipeconf_reg = PIPECCONF;
 		dspcntr_reg = DSPCCNTR;
-		dspsurf_reg = DSPCSURF;
 		reg_offset = MIPIC_REG_OFFSET;
 	}
 
-	if (check_hw_on_only) {
-		if (0/* FIXME!ospm_power_is_hw_on(_DISPLAY_ISLAND)*/) {
-			dev_err(dev->dev, "hw begin failed\n");
-			return;
-		}
-	} else if (!gma_power_begin(dev, true)) {
+	if (!gma_power_begin(dev, true)) {
 		dev_err(dev->dev, "hw begin failed\n");
 		return;
 	}
 
-	/*enable DPLL*/
+	/* Enable DPLL */
 	reg_val = REG_READ(dpll_reg);
 	if (!(reg_val & DPLL_VCO_ENABLE)) {
-
 		if (reg_val & MDFLD_PWR_GATE_EN) {
 			reg_val &= ~MDFLD_PWR_GATE_EN;
 			REG_WRITE(dpll_reg, reg_val);
@@ -415,7 +378,7 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
 			cpu_relax();
 	}
 
-	/*enable pipe*/
+	/* Enable pipe */
 	reg_val = REG_READ(pipeconf_reg);
 	if (!(reg_val & PIPEACONF_ENABLE)) {
 		reg_val |= PIPEACONF_ENABLE;
@@ -425,7 +388,7 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
 		mdfldWaitForPipeEnable(dev, pipe);
 	}
 
-	/*enable plane*/
+	/* Enable plane */
 	reg_val = REG_READ(dspcntr_reg);
 	if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
 		reg_val |= DISPLAY_PLANE_ENABLE;
@@ -434,15 +397,9 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
 		udelay(500);
 	}
 
-	/* update the surface base address. */
-	if (p_surfaceAddr)
-		REG_WRITE(dspsurf_reg, *((u32 *)p_surfaceAddr));
-
-	if (!check_hw_on_only)
-		gma_power_end(dev);
-
-	/*enable TE interrupt on this pipe*/
+	/* Enable TE interrupt on this pipe */
 	mdfld_enable_te(dev, pipe);
+	gma_power_end(dev);
 
 	/*clean IN_DSR flag*/
 	dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
@@ -451,33 +408,33 @@ static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
 /*
  * Exit from DSR
  */
-void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src,
-				void *p_surfaceAddr, bool check_hw_on_only)
+void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
 	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
 	struct mdfld_dsi_dbi_output **dbi_output;
 	int i;
+	int pipe;
 
+	/* FIXME can go ? */
 	dev_priv->is_in_idle = false;
 	dbi_output = dsr_info->dbi_outputs;
 
 #ifdef CONFIG_PM_RUNTIME
 	 if (!enable_gfx_rtpm) {
 /*                pm_runtime_allow(&gpDrmDevice->pdev->dev); */
-/*		schedule_delayed_work(&rtpm_work, 120 * 1000); */
+/*		schedule_delayed_work(&rtpm_work, 30 * 1000);*/ /* FIXME: HZ ? */
 	}
 #endif
 
-	/*for each output, exit dsr*/
+	/* For each output, exit dsr */
 	for (i = 0; i < dsr_info->dbi_output_num; i++) {
-		/*if panel has been turned off, skip*/
-		if (!dbi_output[i]->dbi_panel_on)
+		/* If panel has been turned off, skip */
+		if (!dbi_output[i] || !dbi_output[i]->dbi_panel_on)
 			continue;
-		if (dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR) {
-			enter_dsr = 0;
-			mdfld_dbi_output_exit_dsr(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0, p_surfaceAddr, check_hw_on_only);
-		}
+		pipe = dbi_output[i]->channel_num ? 2 : 0;
+		enter_dsr = 0;
+		mdfld_dbi_output_exit_dsr(dbi_output[i], pipe);
 	}
 	dev_priv->dsr_fb_update |= update_src;
 }
@@ -496,7 +453,7 @@ static bool mdfld_dbi_is_in_dsr(struct drm_device *dev)
 	return true;
 }
 
-/* Perodically update dbi panel */
+/* Periodically update dbi panel */
 void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
@@ -504,8 +461,8 @@ void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
 	struct mdfld_dsi_dbi_output **dbi_outputs;
 	struct mdfld_dsi_dbi_output *dbi_output;
 	int i;
-	int enter_dsr = 0;
-	u32 damage_mask = 0;
+	int can_enter_dsr = 0;
+	u32 damage_mask;
 
 	dbi_outputs = dsr_info->dbi_outputs;
 	dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0];
@@ -514,13 +471,13 @@ void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
 		return;
 
 	if (pipe == 0)
-		damage_mask = dev_priv->dsr_fb_update & (MDFLD_DSR_DAMAGE_MASK_0);
+		damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_0;
 	else if (pipe == 2)
-		damage_mask = dev_priv->dsr_fb_update & (MDFLD_DSR_DAMAGE_MASK_2);
+		damage_mask = dev_priv->dsr_fb_update & MDFLD_DSR_DAMAGE_MASK_2;
 	else
 		return;
 
-	/*if FB is damaged and panel is on update on-panel FB*/
+	/* If FB is damaged and panel is on update on-panel FB */
 	if (damage_mask && dbi_output->dbi_panel_on) {
 		dbi_output->dsr_fb_update_done = false;
 
@@ -538,11 +495,24 @@ void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
 		dbi_output->dsr_idle_count++;
 	}
 
-	/*try to enter DSR*/
-	if (dbi_outputs[0]->dsr_idle_count > 1
-	    && dbi_outputs[1]->dsr_idle_count > 1) {
+	switch (dsr_info->dbi_output_num) {
+	case 1:
+		if (dbi_output->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT)
+			can_enter_dsr = 1;
+		break;
+	case 2:
+		if (dbi_outputs[0]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT
+		   && dbi_outputs[1]->dsr_idle_count > MDFLD_DSR_MAX_IDLE_COUNT)
+			can_enter_dsr = 1;
+		break;
+	default:
+		DRM_ERROR("Wrong DBI output number\n");
+	}
+
+	/* Try to enter DSR */
+	if (can_enter_dsr) {
 		for (i = 0; i < dsr_info->dbi_output_num; i++) {
-			if (!mdfld_dbi_is_in_dsr(dev) &&
+			if (!mdfld_dbi_is_in_dsr(dev) && dbi_outputs[i] &&
 			   !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) {
 				mdfld_dsi_dbi_enter_dsr(dbi_outputs[i],
 					dbi_outputs[i]->channel_num ? 2 : 0);
@@ -565,61 +535,6 @@ void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
 	}
 }
 
-/*timers for DSR*/
-static void mdfld_dsi_dbi_dsr_timer_func(unsigned long data)
-{
-	struct drm_device *dev = (struct drm_device *)data;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-	struct timer_list *dsr_timer = &dsr_info->dsr_timer;
-	unsigned long flags;
-
-	mdfld_dbi_update_panel(dev, 0);
-
-	if (dsr_info->dsr_idle_count > 1)
-		return;
-
-	spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
-	if (!timer_pending(dsr_timer)) {
-		dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
-		add_timer(dsr_timer);
-	}
-	spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
-}
-
-static int mdfld_dsi_dbi_dsr_timer_init(struct drm_device *dev)
-{
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
-	struct timer_list *dsr_timer = &dsr_info->dsr_timer;
-	unsigned long flags;
-
-	spin_lock_init(&dsr_info->dsr_timer_lock);
-	spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
-
-	init_timer(dsr_timer);
-
-	dsr_timer->data = (unsigned long)dev;
-	dsr_timer->function = mdfld_dsi_dbi_dsr_timer_func;
-	dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
-
-	spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
-	return 0;
-}
-
-void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info *dsr_info)
-{
-	struct timer_list *dsr_timer = &dsr_info->dsr_timer;
-	unsigned long flags;
-
-	spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
-	if (!timer_pending(dsr_timer)) {
-		dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
-		add_timer(dsr_timer);
-	}
-	spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
-}
-
 int mdfld_dbi_dsr_init(struct drm_device *dev)
 {
 	struct drm_psb_private *dev_priv = dev->dev_private;
@@ -643,7 +558,6 @@ void mdfld_dbi_dsr_exit(struct drm_device *dev)
 	struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
 
 	if (dsr_info) {
-		del_timer_sync(&dsr_info->dsr_timer);
 		kfree(dsr_info);
 		dev_priv->dbi_dsr_info = NULL;
 	}
@@ -660,13 +574,13 @@ void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
 
 	dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
 
-	/*un-ready device*/
+	/* Un-ready device */
 	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
 
-	/*init dsi adapter before kicking off*/
+	/* Init dsi adapter before kicking off */
 	REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
 
-	/*TODO: figure out how to setup these registers*/
+	/* TODO: figure out how to setup these registers */
 	REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
 	REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset),
 							0x000a0014);
@@ -674,16 +588,16 @@ void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
 	REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
 	REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
 
-	/*enable all interrupts*/
+	/* Enable all interrupts */
 	REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
-	/*max value: 20 clock cycles of txclkesc*/
+	/* Max value: 20 clock cycles of txclkesc */
 	REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
-	/*min 21 txclkesc, max: ffffh*/
+	/* Min 21 txclkesc, max: ffffh */
 	REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
-	/*min: 7d0 max: 4e20*/
+	/* Min: 7d0 max: 4e20 */
 	REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
 
-	/*set up func_prg*/
+	/* Set up func_prg */
 	val |= lane_count;
 	val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
 	val |= DSI_DBI_COLOR_FORMAT_OPTION2;
@@ -692,7 +606,7 @@ void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
 	REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
 	REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
 
-	/*de-assert dbi_stall when half of DBI FIFO is empty*/
+	/* De-assert dbi_stall when half of DBI FIFO is empty */
 	/* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
 
 	REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
@@ -718,42 +632,6 @@ static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
 
 #endif
 
-static int mdfld_dbi_panel_reset(struct mdfld_dsi_dbi_output *output)
-{
-	unsigned gpio;
-	int ret;
-
-	switch (output->channel_num) {
-	case 0:
-		gpio = 128;
-		break;
-	case 1:
-		gpio = 34;
-		break;
-	default:
-		pr_err("Invalid output\n");
-		return -EINVAL;
-	}
-
-	ret = gpio_request(gpio, "gfx");
-	if (ret) {
-		pr_err("gpio_rqueset failed\n");
-		return ret;
-	}
-
-	ret = gpio_direction_output(gpio, 1);
-	if (ret) {
-		pr_err("gpio_direction_output failed\n");
-		goto gpio_error;
-	}
-	gpio_get_value(128);
-gpio_error:
-	if (gpio_is_valid(gpio))
-		gpio_free(gpio);
-
-	return ret;
-}
-
 /*
  * Init DSI DBI encoder.
  * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
@@ -776,13 +654,44 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
 #else
 	struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL;
 #endif
+	u32 data = 0;
+	int pipe;
 	int ret;
 
-	if (!pg || !dsi_connector) {
+	if (!pg || !dsi_connector || !p_funcs) {
 		WARN_ON(1);
 		return NULL;
 	}
 
+	dsi_config = mdfld_dsi_get_config(dsi_connector);
+	pipe = dsi_connector->pipe;
+
+	/*panel hard-reset*/
+	if (p_funcs->reset) {
+		ret = p_funcs->reset(pipe);
+		if (ret) {
+			DRM_ERROR("Panel %d hard-reset failed\n", pipe);
+			return NULL;
+		}
+	}
+	/* Panel drvIC init */
+	if (p_funcs->drv_ic_init)
+		p_funcs->drv_ic_init(dsi_config, pipe);
+
+	/* Panel power mode detect */
+	ret = mdfld_dsi_get_power_mode(dsi_config,
+				       &data,
+				       MDFLD_DSI_HS_TRANSMISSION);
+	if (ret) {
+		DRM_ERROR("Panel %d get power mode failed\n", pipe);
+		dsi_connector->status = connector_status_disconnected;
+	} else {
+		DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
+		dsi_connector->status = connector_status_connected;
+	}
+
+	/*TODO: get panel info from DDB*/
+
 	dbi_output = kzalloc(sizeof(struct mdfld_dsi_dbi_output), GFP_KERNEL);
 	if (!dbi_output) {
 		dev_err(dev->dev, "No memory\n");
@@ -802,23 +711,10 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
 
 	dbi_output->dev = dev;
 	dbi_output->p_funcs = p_funcs;
-
-	/*panel reset*/
-	ret = mdfld_dbi_panel_reset(dbi_output);
-	if (ret) {
-		dev_err(dev->dev, "reset panel error\n");
-		goto out_err1;
-	}
-
-	/*TODO: get panel info from DDB*/
-
-	/*get fixed mode*/
-	dsi_config = mdfld_dsi_get_config(dsi_connector);
 	fixed_mode = dsi_config->fixed_mode;
-
 	dbi_output->panel_fixed_mode = fixed_mode;
 
-	/*create drm encoder object*/
+	/* Create drm encoder object */
 	connector = &dsi_connector->base.base;
 	encoder = &dbi_output->base.base;
 	drm_encoder_init(dev,
@@ -827,10 +723,10 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
 			DRM_MODE_ENCODER_MIPI);
 	drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs);
 
-	/*attach to given connector*/
+	/* Attach to given connector */
 	drm_mode_connector_attach_encoder(connector, encoder);
 
-	/*set possible crtcs and clones*/
+	/* Set possible CRTCs and clones */
 	if (dsi_connector->pipe) {
 		encoder->possible_crtcs = (1 << 2);
 		encoder->possible_clones = (1 << 1);
@@ -842,28 +738,31 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
 	dev_priv->dsr_fb_update = 0;
 	dev_priv->dsr_enable = false;
 	dev_priv->exit_idle = mdfld_dsi_dbi_exit_dsr;
-#if defined(CONFIG_MDFLD_DSI_DPU) || defined(CONFIG_MDFLD_DSI_DSR)
-	dev_priv->dsr_enable_config = false;
-#endif /*CONFIG_MDFLD_DSI_DSR*/
 
 	dbi_output->first_boot = true;
 	dbi_output->mode_flags = MODE_SETTING_IN_ENCODER;
 
 #ifdef CONFIG_MDFLD_DSI_DPU
-	/*add this output to dpu_info*/
-	if (dsi_connector->pipe == 0)
-		dpu_info->dbi_outputs[0] = dbi_output;
-	} else {
-		dpu_info->dbi_outputs[1] = dbi_output;
+	/* Add this output to dpu_info */
+	if (dsi_connector->status == connector_status_connected) {
+		if (dsi_connector->pipe == 0)
+			dpu_info->dbi_outputs[0] = dbi_output;
+		else
+			dpu_info->dbi_outputs[1] = dbi_output;
+
+		dpu_info->dbi_output_num++;
 	}
-	dpu_info->dbi_output_num++;
+
 #else /*CONFIG_MDFLD_DSI_DPU*/
-	/*add this output to dsr_info*/
-	if (dsi_connector->pipe == 0)
-		dsr_info->dbi_outputs[0] = dbi_output;
-	else
-		dsr_info->dbi_outputs[1] = dbi_output;
-	dsr_info->dbi_output_num++;
+	if (dsi_connector->status == connector_status_connected) {
+		/* Add this output to dsr_info */
+		if (dsi_connector->pipe == 0)
+			dsr_info->dbi_outputs[0] = dbi_output;
+		else
+			dsr_info->dbi_outputs[1] = dbi_output;
+
+		dsr_info->dbi_output_num++;
+	}
 #endif
 	return &dbi_output->base;
 out_err1:
drivers/staging/gma500/mdfld_dsi_dbi.h +2 -19
index a51e2f8..a2ec6fd 100644
@@ -59,9 +59,6 @@ struct mdfld_dsi_dbi_output {
 	/* Backlight operations */
 
 	/* DSR timer */
-	spinlock_t dsr_timer_lock;
-	struct timer_list dsr_timer;
-	void(*dsi_timer_func)(unsigned long data);
 	u32 dsr_idle_count;
 	bool dsr_fb_update_done;
 
@@ -81,22 +78,11 @@ struct mdfld_dbi_dsr_info {
 	int dbi_output_num;
 	struct mdfld_dsi_dbi_output *dbi_outputs[2];
 
-	spinlock_t dsr_timer_lock;
-	struct timer_list dsr_timer;
 	u32 dsr_idle_count;
 };
 
 #define DBI_CB_TIMEOUT_COUNT	0xffff
 
-/* DCS commands */
-#define enter_sleep_mode	0x10
-#define exit_sleep_mode		0x11
-#define set_display_off		0x28
-#define	set_dispaly_on		0x29
-#define set_column_address	0x2a
-#define set_page_addr		0x2b
-#define write_mem_start		0x2c
-
 /* Offsets */
 #define CMD_MEM_ADDR_OFFSET	0
 
@@ -132,7 +118,7 @@ static inline int mdfld_dsi_dbi_cmd_sent(struct mdfld_dsi_dbi_output *dbi_output
 
 	/* Query the command execution status */
 	while (retry--)
-		if (!(REG_READ(MIPIA_CMD_ADD_REG + reg_offset) & (1 << 10)))
+		if (!(REG_READ(MIPIA_CMD_ADD_REG + reg_offset) & (1 << 0)))
 			break;
 
 	if (!retry) {
@@ -164,13 +150,11 @@ static inline int mdfld_dsi_dbi_cb_ready(struct mdfld_dsi_dbi_output *dbi_output
 
 extern void mdfld_dsi_dbi_output_init(struct drm_device *dev,
 			struct psb_intel_mode_device *mode_dev, int pipe);
-extern void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src,
-			void *p_surfaceAddr, bool check_hw_on_only);
+extern void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src);
 extern void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output,
 			int pipe);
 extern int mdfld_dbi_dsr_init(struct drm_device *dev);
 extern void mdfld_dbi_dsr_exit(struct drm_device *dev);
-extern void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info *dsr_info);
 extern struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
 			struct mdfld_dsi_connector *dsi_connector,
 			struct panel_funcs *p_funcs);
@@ -178,7 +162,6 @@ extern int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
 			u8 dcs, u8 *param, u32 num, u8 data_src);
 extern int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
 			u16 x1, u16 y1, u16 x2, u16 y2);
-extern void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info *dsr_info);
 extern int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
 			int mode);
 extern void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
drivers/staging/gma500/mdfld_dsi_dbi_dpu.h +0 -3
index 4ca9682..42367ed 100644
@@ -90,9 +90,6 @@ static inline int mdfld_dpu_region_extent(struct psb_drm_dpu_rect *origin,
 {
 	int x1, y1, x2, y2;
 
-	/* PSB_DEBUG_ENTRY("rect (%d, %d, %d, %d)\n",
-		rect->x, rect->y, rect->width, rect->height); */
-
 	x1 = origin->x + origin->width;
 	y1 = origin->y + origin->height;
 
drivers/staging/gma500/mdfld_dsi_dpi.c +64 -255

452 lines not on this page · raw message

drivers/staging/gma500/mdfld_dsi_dpi.h +2 -4
index 68e65cc..ed92d45 100644
@@ -47,6 +47,8 @@ struct mdfld_dsi_dpi_output {
 
 	int panel_on;
 	int first_boot;
+
+	struct panel_funcs *p_funcs;
 };
 
 #define MDFLD_DSI_DPI_OUTPUT(dsi_encoder) \
@@ -73,8 +75,4 @@ extern void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output,
 			int pipe);
 extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *si_config,
 			int pipe);
-extern void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe);
-extern void psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe,
-			u32 mask);
-
 #endif /*__MDFLD_DSI_DPI_H__*/
drivers/staging/gma500/mdfld_dsi_output.c +141 -109

438 lines not on this page · raw message

drivers/staging/gma500/mdfld_dsi_output.h +7 -196

214 lines not on this page · raw message

drivers/staging/gma500/mdfld_dsi_pkg_sender.c +395 -8

483 lines not on this page · raw message

drivers/staging/gma500/mdfld_dsi_pkg_sender.h +26 -0
index 296b1ea..f24abc7 100644
@@ -36,9 +36,13 @@ enum {
 	MDFLD_DSI_PKG_GEN_SHORT_WRITE_0 = 0x03,
 	MDFLD_DSI_PKG_GEN_SHORT_WRITE_1 = 0x13,
 	MDFLD_DSI_PKG_GEN_SHORT_WRITE_2 = 0x23,
+	MDFLD_DSI_PKG_GEN_READ_0 = 0x04,
+	MDFLD_DSI_PKG_GEN_READ_1 = 0x14,
+	MDFLD_DSI_PKG_GEN_READ_2 = 0x24,
 	MDFLD_DSI_PKG_GEN_LONG_WRITE = 0x29,
 	MDFLD_DSI_PKG_MCS_SHORT_WRITE_0 = 0x05,
 	MDFLD_DSI_PKG_MCS_SHORT_WRITE_1 = 0x15,
+	MDFLD_DSI_PKG_MCS_READ = 0x06,
 	MDFLD_DSI_PKG_MCS_LONG_WRITE = 0x39,
 };
 
@@ -132,6 +136,18 @@ struct mdfld_dsi_pkg_sender {
 	u32 mipi_cmd_len_reg;
 };
 
+/* DCS definitions */
+#define DCS_SOFT_RESET			0x01
+#define DCS_ENTER_SLEEP_MODE		0x10
+#define DCS_EXIT_SLEEP_MODE		0x11
+#define DCS_SET_DISPLAY_OFF		0x28
+#define DCS_SET_DISPLAY_ON		0x29
+#define DCS_SET_COLUMN_ADDRESS		0x2a
+#define DCS_SET_PAGE_ADDRESS		0x2b
+#define DCS_WRITE_MEM_START		0x2c
+#define DCS_SET_TEAR_OFF		0x34
+#define DCS_SET_TEAR_ON 		0x35
+
 extern int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
 			int pipe);
 extern void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender);
@@ -153,6 +169,16 @@ extern int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender,
 			u32 *data, u32 len, int delay);
 extern int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender,
 			u32 *data, u32 len, int delay);
+
+extern int mdfld_dsi_read_gen_hs(struct mdfld_dsi_pkg_sender *sender,
+			u8 param0, u8 param1, u8 param_num, u32 *data, u16 len);
+extern int mdfld_dsi_read_gen_lp(struct mdfld_dsi_pkg_sender *sender,
+			u8 param0, u8 param1, u8 param_num, u32 *data, u16 len);
+extern int mdfld_dsi_read_mcs_hs(struct mdfld_dsi_pkg_sender *sender,
+			u8 cmd, u32 *data, u16 len);
+extern int mdfld_dsi_read_mcs_lp(struct mdfld_dsi_pkg_sender *sender,
+			u8 cmd, u32 *data, u16 len);
+
 extern void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender);
 
 #endif /* __MDFLD_DSI_PKG_SENDER_H__ */
drivers/staging/gma500/mdfld_intel_display.c +2 -4
index fa84990..ac74a8d 100644
@@ -140,7 +140,6 @@ static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
 				 uint32_t width, uint32_t height)
 {
 	struct drm_device *dev = crtc->dev;
-	struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
 	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 	int pipe = psb_intel_crtc->pipe;
 	uint32_t control = CURACNTR;
@@ -263,7 +262,7 @@ static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 	case 0:
 #ifndef CONFIG_MDFLD_DSI_DPU
 		if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_0))
-			mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_CURSOR_0, 0, 0);
+			mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_CURSOR_0);
 #else /*CONFIG_MDFLD_DSI_DPU*/
 		rect.x = x;
 		rect.y = y;
@@ -279,7 +278,7 @@ static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 	case 2:
 #ifndef CONFIG_MDFLD_DSI_DPU
 		if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_2))
-			mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_CURSOR_2, 0, 0);
+			mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_CURSOR_2);
 #else /*CONFIG_MDFLD_DSI_DPU*/
 		mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORC, &rect);
 		mdfld_dpu_exit_dsr(dev);
@@ -354,7 +353,6 @@ int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_f
 	/* struct drm_i915_master_private *master_priv; */
 	struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 	struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
-	struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
 	int pipe = psb_intel_crtc->pipe;
 	unsigned long start, offset;
 	int dsplinoff = DSPALINOFF;
drivers/staging/gma500/mdfld_output.c +6 -2
index 7e11401..ffa2c1f 100644
@@ -100,7 +100,6 @@ static int init_panel(struct drm_device *dev, int mipi_pipe, int p_type)
 		mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
 		break;
 	case PYR_VID:
-		/*pyr_vid_init(dev, p_vid_funcs); */
 		mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
 		break;
 	case TPO:	/* TPO panel supports both cmd & vid interfaces */
@@ -135,10 +134,15 @@ int mdfld_output_init(struct drm_device *dev)
 	dev_info(dev->dev, "panel 1: type is %d\n", type);
 	init_panel(dev, 0, type);
 
+#ifdef CONFIG_MDFD_DUAL_MIPI
 	/* MIPI panel 2 */
 	type = mdfld_get_panel_type(dev, 2);
 	dev_info(dev->dev, "panel 2: type is %d\n", type);
 	init_panel(dev, 2, type);
-
+#endif
+#ifdef CONFIG_MDFD_HDMI
+	/* HDMI panel */
+	init_panel(dev, 0, HDMI);
+#endif
 	return 0;
 }
drivers/staging/gma500/mdfld_output.h +0 -41

47 lines not on this page · raw message

drivers/staging/gma500/mdfld_pyr_cmd.c +3 -15
index 0d89384..5f38e8d 100644
@@ -188,7 +188,7 @@ static void pyr_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
 
 	dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
 
-	/* In-ready device */
+	/* Un-ready device */
 	REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
 
 	/* Init dsi adapter before kicking off */
@@ -394,25 +394,13 @@ static void pyr_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
 	struct mdfld_dsi_dbi_output *dbi_output =
 					MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
 	struct drm_device *dev = dbi_output->dev;
-	struct drm_psb_private *dev_priv = dev->dev_private;
-	static bool bdispoff;
 
 	dev_dbg(dev->dev, "%s\n",  (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
 
-	if (mode == DRM_MODE_DPMS_ON) {
-		if (/*gbgfxsuspended && */bdispoff) {
-			bdispoff = false;
-			dev_priv->dispstatus = true;
-			/*gbgfxsuspended = false;
-			*/
-			mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D, 0, 0);
-		}
+	if (mode == DRM_MODE_DPMS_ON)
 		pyr_dsi_dbi_set_power(encoder, true);
-	} else {
-		bdispoff = true;
-		dev_priv->dispstatus = false;
+	else
 		pyr_dsi_dbi_set_power(encoder, false);
-	}
 }
 
 /*
drivers/staging/gma500/mdfld_tmd_vid.c +62 -0

72 lines not on this page · raw message

drivers/staging/gma500/mdfld_tpo_cmd.c +41 -23

134 lines not on this page · raw message

drivers/staging/gma500/mrst_lvds.c +28 -7
index 25fde4c..ac791c4 100644
@@ -58,11 +58,11 @@ static void mrst_lvds_set_power(struct drm_device *dev,
 			pp_status = REG_READ(PP_STATUS);
 		} while ((pp_status & (PP_ON | PP_READY)) == PP_READY);
 		dev_priv->is_lvds_on = true;
-	        if (dev_priv->ops->lvds_bl_power)
-	                dev_priv->ops->lvds_bl_power(dev, true);
+		if (dev_priv->ops->lvds_bl_power)
+			dev_priv->ops->lvds_bl_power(dev, true);
 	} else {
-	        if (dev_priv->ops->lvds_bl_power)
-	                dev_priv->ops->lvds_bl_power(dev, false);
+		if (dev_priv->ops->lvds_bl_power)
+			dev_priv->ops->lvds_bl_power(dev, false);
 		REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) &
 			  ~POWER_TARGET_ON);
 		do {
@@ -151,6 +151,7 @@ static void mrst_lvds_prepare(struct drm_encoder *encoder)
 {
 	struct drm_device *dev = encoder->dev;
 	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+	struct psb_intel_mode_device *mode_dev = output->mode_dev;
 
 	if (!gma_power_begin(dev, true))
 		return;
@@ -162,23 +163,43 @@ static void mrst_lvds_prepare(struct drm_encoder *encoder)
 	gma_power_end(dev);
 }
 
+static u32 mrst_lvds_get_max_backlight(struct drm_device *dev)
+{
+	struct drm_psb_private *dev_priv = dev->dev_private;
+	u32 ret;
+
+	if (gma_power_begin(dev, false)) {
+		ret = ((REG_READ(BLC_PWM_CTL) &
+			  BACKLIGHT_MODULATION_FREQ_MASK) >>
+			  BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
+
+		gma_power_end(dev);
+	} else
+		ret = ((dev_priv->saveBLC_PWM_CTL &
+			  BACKLIGHT_MODULATION_FREQ_MASK) >>
+			  BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
+
+	return ret;
+}
+
 static void mrst_lvds_commit(struct drm_encoder *encoder)
 {
 	struct drm_device *dev = encoder->dev;
 	struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
+	struct psb_intel_mode_device *mode_dev = output->mode_dev;
 
 	if (mode_dev->backlight_duty_cycle == 0)
 		mode_dev->backlight_duty_cycle =
-		    psb_intel_lvds_get_max_backlight(dev);
+					mrst_lvds_get_max_backlight(dev);
 	mrst_lvds_set_power(dev, output, true);
 }
 
 static const struct drm_encoder_helper_funcs mrst_lvds_helper_funcs = {
 	.dpms = mrst_lvds_dpms,
 	.mode_fixup = psb_intel_lvds_mode_fixup,
-	.prepare = mrst_intel_lvds_prepare,
+	.prepare = mrst_lvds_prepare,
 	.mode_set = mrst_lvds_mode_set,
-	.commit = mrst_intel_lvds_commit,
+	.commit = mrst_lvds_commit,
 };
 
 static struct drm_display_mode lvds_configuration_modes[] = {
drivers/staging/gma500/psb_drv.h +4 -3
index 194c64f..72f487a 100644
@@ -31,6 +31,7 @@
 #include "gtt.h"
 #include "power.h"
 #include "mrst.h"
+#include "medfield.h"
 
 /* Append new drm mode definition here, align with libdrm definition */
 #define DRM_MODE_SCALE_NO_SCALE   	2
@@ -216,8 +217,8 @@ enum {
 #define MDFLD_DSR_OVERLAY_0 	(1 << 4)
 #define MDFLD_DSR_OVERLAY_2 	(1 << 5)
 #define MDFLD_DSR_MIPI_CONTROL	(1 << 6)
-#define MDFLD_DSR_DAMAGE_MASK_0	(1 << 0) | (1 << 2) | (1 << 4)
-#define MDFLD_DSR_DAMAGE_MASK_2	(1 << 1) | (1 << 3) | (1 << 5)
+#define MDFLD_DSR_DAMAGE_MASK_0	((1 << 0) | (1 << 2) | (1 << 4))
+#define MDFLD_DSR_DAMAGE_MASK_2	((1 << 1) | (1 << 3) | (1 << 5))
 #define MDFLD_DSR_2D_3D 	(MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2)
 
 #define MDFLD_DSR_RR		45
@@ -605,7 +606,7 @@ struct drm_psb_private {
 	uint32_t dsr_idle_count;
 	bool is_in_idle;
 	bool dsr_enable;
-	void (*exit_idle)(struct drm_device *dev, u32 update_src, void *p_surfaceAddr, bool check_hw_on_only);
+	void (*exit_idle)(struct drm_device *dev, u32 update_src);
 
 	/* 2D acceleration */
 	struct mutex mutex_2d;
author
#14 lore raw

PATCH 15/15 gma500: Clean up the DPU config and make it runtime

In reply to Alan Cox

From: Alan Cox <[email protected]>

We really don't want this all done by ifdeffery - and this isn't any need as it's fairly easy to sort out.

---

 drivers/staging/gma500/Makefile              |    1 
 drivers/staging/gma500/mdfld_dsi_dbi.c       |   19 -
 drivers/staging/gma500/mdfld_dsi_dbi_dpu.c   |  778 ++++++++++++++++++++++++++
 drivers/staging/gma500/mdfld_dsi_output.c    |    8 
 drivers/staging/gma500/mdfld_intel_display.c |   49 +-
 drivers/staging/gma500/mdfld_output.c        |   42 +
 drivers/staging/gma500/mdfld_output.h        |    2 
 drivers/staging/gma500/mdfld_pyr_cmd.c       |    7 
 drivers/staging/gma500/mdfld_tpo_cmd.c       |    6 
 drivers/staging/gma500/psb_drv.c             |   11 
 10 files changed, 845 insertions(+), 78 deletions(-)
 create mode 100644 drivers/staging/gma500/mdfld_dsi_dbi_dpu.c
drivers/staging/gma500/Makefile +1 -0
index fe34f18..c729868 100644
@@ -46,6 +46,7 @@ psb_gfx-$(CONFIG_DRM_PSB_MFLD) += mdfld_device.o \
 	  mdfld_dsi_dpi.o \
 	  mdfld_dsi_output.o \
 	  mdfld_dsi_dbi.o \
+	  mdfld_dsi_dbi_dpu.o \
 	  mdfld_intel_display.o
 
 obj-$(CONFIG_DRM_PSB) += psb_gfx.o
drivers/staging/gma500/mdfld_dsi_dbi.c +4 -15
index 06424f9..02e17c9 100644
@@ -327,7 +327,6 @@ void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
 	}
 }
 
-#ifndef CONFIG_MDFLD_DSI_DPU
 static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
 			int pipe)
 {
@@ -562,7 +561,6 @@ void mdfld_dbi_dsr_exit(struct drm_device *dev)
 		dev_priv->dbi_dsr_info = NULL;
 	}
 }
-#endif
 
 void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
 								int pipe)
@@ -648,12 +646,8 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
 	struct drm_encoder *encoder = NULL;
 	struct drm_display_mode *fixed_mode = NULL;
 	struct psb_gtt *pg = dev_priv ? (&dev_priv->gtt) : NULL;
-
-#ifdef CONFIG_MDFLD_DSI_DPU
 	struct mdfld_dbi_dpu_info *dpu_info = dev_priv ? (dev_priv->dbi_dpu_info) : NULL;
-#else
 	struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL;
-#endif
 	u32 data = 0;
 	int pipe;
 	int ret;
@@ -742,20 +736,16 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
 	dbi_output->first_boot = true;
 	dbi_output->mode_flags = MODE_SETTING_IN_ENCODER;
 
-#ifdef CONFIG_MDFLD_DSI_DPU
-	/* Add this output to dpu_info */
-	if (dsi_connector->status == connector_status_connected) {
+	/* Add this output to dpu_info if in DPU mode */
+	if (dpu_info && dsi_connector->status == connector_status_connected) {
 		if (dsi_connector->pipe == 0)
 			dpu_info->dbi_outputs[0] = dbi_output;
 		else
 			dpu_info->dbi_outputs[1] = dbi_output;
 
 		dpu_info->dbi_output_num++;
-	}
-
-#else /*CONFIG_MDFLD_DSI_DPU*/
-	if (dsi_connector->status == connector_status_connected) {
-		/* Add this output to dsr_info */
+	} else if (dsi_connector->status == connector_status_connected) {
+		/* Add this output to dsr_info if not */
 		if (dsi_connector->pipe == 0)
 			dsr_info->dbi_outputs[0] = dbi_output;
 		else
@@ -763,7 +753,6 @@ struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
 
 		dsr_info->dbi_output_num++;
 	}
-#endif
 	return &dbi_output->base;
 out_err1:
 	kfree(dbi_output);
drivers/staging/gma500/mdfld_dsi_dbi_dpu.c new file +778 -0

778 lines not on this page · raw message

drivers/staging/gma500/mdfld_dsi_output.c +4 -4
index 3286c3d..7536095 100644
@@ -46,7 +46,7 @@ module_param (LABC_control, int, 0644);
  * we don't need 'movl' everytime we send them.
  * FIXME: these datas were provided by OEM, we should get them from GCT.
  **/
-static const u32 mdfld_dbi_mcs_hysteresis[] = {
+static u32 mdfld_dbi_mcs_hysteresis[] = {
 	0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff,
 	0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
 	0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff,
@@ -54,16 +54,16 @@ static const u32 mdfld_dbi_mcs_hysteresis[] = {
 	0x000000ff,
 };
 
-static const u32 mdfld_dbi_mcs_display_profile[] = {
+static u32 mdfld_dbi_mcs_display_profile[] = {
 	0x50281450, 0x0000c882, 0x00000000, 0x00000000,
 	0x00000000,
 };
 
-static const u32 mdfld_dbi_mcs_kbbc_profile[] = {
+static u32 mdfld_dbi_mcs_kbbc_profile[] = {
 	0x00ffcc60, 0x00000000, 0x00000000, 0x00000000,
 }; 
 	
-static const u32 mdfld_dbi_mcs_gamma_profile[] = {
+static u32 mdfld_dbi_mcs_gamma_profile[] = {
 	0x81111158, 0x88888888, 0x88888888,
 }; 
 
drivers/staging/gma500/mdfld_intel_display.c +20 -29

84 lines not on this page · raw message

drivers/staging/gma500/mdfld_output.c +32 -10

60 lines not on this page · raw message

drivers/staging/gma500/mdfld_output.h +2 -0
index e747fdb..daf33e7 100644
@@ -36,4 +36,6 @@ void mdfld_disable_crtc (struct drm_device *dev, int pipe);
 extern const struct drm_crtc_helper_funcs mdfld_helper_funcs;
 extern const struct drm_crtc_funcs mdfld_intel_crtc_funcs;
 
+extern void mdfld_output_setup(struct drm_device *dev);
+
 #endif
drivers/staging/gma500/mdfld_pyr_cmd.c +1 -6
index 5f38e8d..523f2d8 100644
@@ -29,7 +29,7 @@
 #include "mdfld_dsi_dpi.h"
 #include "mdfld_dsi_output.h"
 #include "mdfld_output.h"
-
+#include "mdfld_dsi_dbi_dpu.h"
 #include "mdfld_dsi_pkg_sender.h"
 
 #include "displays/pyr_cmd.h"
@@ -374,16 +374,11 @@ static void pyr_dsi_dbi_commit(struct drm_encoder *encoder)
 
 	if (dbi_output->channel_num == 1) {
 		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
-#ifdef CONFIG_MDFLD_DSI_DPU
 		/* If DPU enabled report a fullscreen damage */
 		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
-#endif
 	} else {
 		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
-
-#ifdef CONFIG_MDFLD_DSI_DPU
 		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
-#endif
 	}
 	dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
 }
drivers/staging/gma500/mdfld_tpo_cmd.c +1 -5
index 4cf7647..c7f7c9c 100644
@@ -29,7 +29,7 @@
 #include "mdfld_dsi_dpi.h"
 #include "mdfld_dsi_output.h"
 #include "mdfld_output.h"
-
+#include "mdfld_dsi_dbi_dpu.h"
 #include "mdfld_dsi_pkg_sender.h"
 
 #include "displays/tpo_cmd.h"
@@ -359,15 +359,11 @@ static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder)
 
 	if (dbi_output->channel_num == 1) {
 		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
-#ifdef CONFIG_MDFLD_DSI_DPU
 		/*if dpu enabled report a fullscreen damage*/
 		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
-#endif
 	} else {
 		dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
-#ifdef CONFIG_MDFLD_DSI_DPU
 		mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
-#endif
 	}
 	dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
 }
drivers/staging/gma500/psb_drv.c +2 -9
index 4b740aa..b2cdce7 100644
@@ -421,15 +421,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
 
 #if defined(CONFIG_DRM_PSB_MFLD)
 	/* FIXME: this is not the right place for this stuff ! */
-	if (IS_MFLD(dev)) {
-#ifdef CONFIG_MDFLD_DSI_DPU
-		/*init dpu info*/
-		mdfld_dbi_dpu_init(dev);
-#else
-		mdfld_dbi_dsr_init(dev);
-#endif /*CONFIG_MDFLD_DSI_DPU*/
-		/* INIT_WORK(&dev_priv->te_work, mdfld_te_handler_work);*/
-	}
+	mdfld_output_setup(dev);
 #endif
 	if (drm_psb_no_fb == 0) {
 		psb_modeset_init(dev);
@@ -444,6 +436,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
 
 		switch (psb_intel_output->type) {
 		case INTEL_OUTPUT_LVDS:
+		case INTEL_OUTPUT_MIPI:
 			ret = gma_backlight_init(dev);
 			break;
 		}
#15 lore raw
In reply to Alan Cox

After this series applied, I get:
drivers/staging/gma500/psb_drv.h:34:22: fatal error: medfield.h: No such file or directory

:(