aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2010-06-30 15:39:25 -0400
committerMatt Turner <mattst88@gmail.com>2010-08-13 19:49:46 -0400
commit248befa5a7593ee172a8abc7d3787465b635829f (patch)
tree0d17f2df479f1ca8252611a50c71974144317f34
parent1a8d33433c7663ffd52d8cbaa188dc7527e30a3a (diff)
downloadglint-248befa5a7593ee172a8abc7d3787465b635829f.tar.gz
drm/glint: initial CRTC work
Signed-off-by: Matt Turner <mattst88@gmail.com>
-rw-r--r--drivers/gpu/drm/glint/Makefile3
-rw-r--r--drivers/gpu/drm/glint/glint.h4
-rw-r--r--drivers/gpu/drm/glint/glint_crtc.c88
-rw-r--r--drivers/gpu/drm/glint/glint_device.c1
-rw-r--r--drivers/gpu/drm/glint/glint_display.c21
-rw-r--r--drivers/gpu/drm/glint/glint_drv.h7
-rw-r--r--drivers/gpu/drm/glint/glint_mode.h24
7 files changed, 147 insertions, 1 deletions
diff --git a/drivers/gpu/drm/glint/Makefile b/drivers/gpu/drm/glint/Makefile
index 867349dbe76dee..c6bc2bd41d4e5a 100644
--- a/drivers/gpu/drm/glint/Makefile
+++ b/drivers/gpu/drm/glint/Makefile
@@ -3,6 +3,7 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm
-glint-y := glint_display.o glint_device.o glint_drv.o glint_irq.o glint_kms.o
+glint-y := glint_crtc.o glint_display.o glint_device.o glint_drv.o \
+ glint_irq.o glint_kms.o
obj-$(CONFIG_DRM_GLINT) += glint.o
diff --git a/drivers/gpu/drm/glint/glint.h b/drivers/gpu/drm/glint/glint.h
index 51c8f2c7a0d15a..e4fda7166c1807 100644
--- a/drivers/gpu/drm/glint/glint.h
+++ b/drivers/gpu/drm/glint/glint.h
@@ -2,6 +2,7 @@
#define __GLINT_H__
#include "glint_family.h"
+#include "glint_mode.h"
struct glint_mc {
resource_size_t aper_size;
@@ -21,6 +22,9 @@ struct glint_device {
void *rmmio;
struct glint_mc mc;
+ struct glint_mode_info mode_info;
+
+ int num_crtc;
};
#endif /* __GLINT_H__ */
diff --git a/drivers/gpu/drm/glint/glint_crtc.c b/drivers/gpu/drm/glint/glint_crtc.c
new file mode 100644
index 00000000000000..126a0e8e767f00
--- /dev/null
+++ b/drivers/gpu/drm/glint/glint_crtc.c
@@ -0,0 +1,88 @@
+#include "drmP.h"
+#include "drm.h"
+#include "drm_crtc_helper.h"
+
+#include <video/pm3fb.h>
+
+#include "glint.h"
+#include "glint_drv.h"
+#include "glint_mode.h"
+
+static void glint_crtc_load_lut(struct drm_crtc *crtc)
+{
+ struct glint_crtc *glint_crtc = to_glint_crtc(crtc);
+ struct drm_device *dev = crtc->dev;
+ struct glint_device *gdev = dev->dev_private;
+ int i;
+
+ if (!crtc->enabled)
+ return;
+
+ for (i = 0; i < 256; i++) {
+ WREG8(PM3RD_PaletteWriteAddress, i);
+ WREG8(PM3RD_PaletteData, glint_crtc->lut_r[i]);
+ WREG8(PM3RD_PaletteData, glint_crtc->lut_b[i]);
+ WREG8(PM3RD_PaletteData, glint_crtc->lut_g[i]);
+ }
+}
+
+static void glint_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
+ u16 *blue, uint32_t size)
+{
+ struct glint_crtc *glint_crtc = to_glint_crtc(crtc);
+ int i;
+
+ if (size != 256) {
+ return;
+ }
+
+ for (i = 0; i < 256; i++) {
+ glint_crtc->lut_r[i] = red[i];
+ glint_crtc->lut_g[i] = green[i];
+ glint_crtc->lut_b[i] = blue[i];
+ }
+ glint_crtc_load_lut(crtc);
+}
+
+static void glint_crtc_destroy(struct drm_crtc *crtc)
+{
+ struct glint_crtc *glint_crtc = to_glint_crtc(crtc);
+
+ drm_crtc_cleanup(crtc);
+ kfree(glint_crtc);
+}
+
+static const struct drm_crtc_funcs glint_crtc_funcs = {
+ /*
+ .cursor_set = glint_crtc_cursor_set,
+ .cursor_move = glint_crtc_cursor_move,
+ */
+ .cursor_set = NULL,
+ .cursor_move = NULL,
+ .gamma_set = glint_crtc_gamma_set,
+ .set_config = drm_crtc_helper_set_config,
+ .destroy = glint_crtc_destroy,
+};
+
+void glint_crtc_init(struct drm_device *dev, int index)
+{
+ struct glint_device *gdev = dev->dev_private;
+ struct glint_crtc *glint_crtc;
+ int i;
+
+ glint_crtc = kzalloc(sizeof(struct glint_crtc) + (GLINTFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
+ if (glint_crtc == NULL)
+ return;
+
+ drm_crtc_init(dev, &glint_crtc->base, &glint_crtc_funcs);
+
+ drm_mode_crtc_set_gamma_size(&glint_crtc->base, 256);
+ glint_crtc->crtc_id = index;
+ gdev->mode_info.crtcs[index] = glint_crtc;
+
+ for (i = 0; i < 256; i++) {
+ glint_crtc->lut_r[i] = i;
+ glint_crtc->lut_g[i] = i;
+ glint_crtc->lut_b[i] = i;
+ }
+}
diff --git a/drivers/gpu/drm/glint/glint_device.c b/drivers/gpu/drm/glint/glint_device.c
index 2cf207a9f7601f..125df20bb05882 100644
--- a/drivers/gpu/drm/glint/glint_device.c
+++ b/drivers/gpu/drm/glint/glint_device.c
@@ -83,6 +83,7 @@ int glint_device_init(struct glint_device *gdev,
gdev->ddev = ddev;
gdev->pdev = pdev;
gdev->flags = flags;
+ gdev->num_crtc = 2;
/* Registers mapping */
/* TODO: block userspace mapping of io register */
diff --git a/drivers/gpu/drm/glint/glint_display.c b/drivers/gpu/drm/glint/glint_display.c
index 174e269c2c2c00..a8061ea041976e 100644
--- a/drivers/gpu/drm/glint/glint_display.c
+++ b/drivers/gpu/drm/glint/glint_display.c
@@ -1,13 +1,34 @@
#include "drmP.h"
#include "drm.h"
+#include "drm_crtc_helper.h"
#include "glint.h"
+#include "glint_drv.h"
int glint_modeset_init(struct glint_device *gdev)
{
+ int i;
+
+ drm_mode_config_init(gdev->ddev);
+ gdev->mode_info.mode_config_initialized = true;
+
+ gdev->ddev->mode_config.max_width = GLINT_MAX_FB_WIDTH;
+ gdev->ddev->mode_config.max_height = GLINT_MAX_FB_HEIGHT;
+
+ gdev->ddev->mode_config.fb_base = gdev->mc.aper_base;
+
+ /* allocate crtcs */
+ for (i = 0; i < gdev->num_crtc; i++) {
+ glint_crtc_init(gdev->ddev, i);
+ }
+
return 0;
}
void glint_modeset_fini(struct glint_device *gdev)
{
+ if (gdev->mode_info.mode_config_initialized) {
+ drm_mode_config_cleanup(gdev->ddev);
+ gdev->mode_info.mode_config_initialized = false;
+ }
}
diff --git a/drivers/gpu/drm/glint/glint_drv.h b/drivers/gpu/drm/glint/glint_drv.h
index b3f7d5501553d0..5c419f779a8b71 100644
--- a/drivers/gpu/drm/glint/glint_drv.h
+++ b/drivers/gpu/drm/glint/glint_drv.h
@@ -14,6 +14,10 @@
#define GLINT_INFO(fmt, arg...) DRM_INFO(DRIVER_NAME ": " fmt, ##arg)
#define GLINT_ERROR(fmt, arg...) DRM_ERROR(DRIVER_NAME ": " fmt, ##arg)
+#define GLINTFB_CONN_LIMIT 4
+
+#define RREG8(reg) ioread8(((void __iomem *)gdev->rmmio) + (reg))
+#define WREG8(reg, v) iowrite8(v, ((void __iomem *)gdev->rmmio) + (reg))
#define RREG32(reg) ioread32(((void __iomem *)gdev->rmmio) + (reg))
#define WREG32(reg, v) iowrite32(v, ((void __iomem *)gdev->rmmio) + (reg))
@@ -21,6 +25,9 @@
#include "glint.h"
+ /* glint_crtc.c */
+void glint_crtc_init(struct drm_device *dev, int index);
+
/* glint_device.c */
int glint_device_init(struct glint_device *gdev,
struct drm_device *ddev,
diff --git a/drivers/gpu/drm/glint/glint_mode.h b/drivers/gpu/drm/glint/glint_mode.h
new file mode 100644
index 00000000000000..151bc444ad8972
--- /dev/null
+++ b/drivers/gpu/drm/glint/glint_mode.h
@@ -0,0 +1,24 @@
+#ifndef __GLINT_MODE_H__
+#define __GLINT_MODE_H__
+
+#include "drmP.h"
+#include "drm.h"
+
+#define GLINT_MAX_FB_HEIGHT 4096
+#define GLINT_MAX_FB_WIDTH 4096
+
+#define to_glint_crtc(x) container_of(x, struct glint_crtc, base)
+
+struct glint_crtc {
+ struct drm_crtc base;
+ u8 lut_r[256], lut_g[256], lut_b[256];
+ int crtc_id;
+ bool enabled;
+};
+
+struct glint_mode_info {
+ bool mode_config_initialized;
+ struct glint_crtc *crtcs[2]; /* FIXME: how many CRTCs? */
+};
+
+#endif /* __GLINT_MODE_H__ */