aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas White <taw@bitwiz.org.uk>2009-07-02 23:44:07 +0100
committerThomas White <taw@bitwiz.org.uk>2009-07-02 23:44:07 +0100
commit791916962183d648d71f9b45125fa656696084fd (patch)
treeddccaf8f4d7a3dae52b04f605f217447755cd0e8
parentab1292a80b414632d78f457b904890605244a98c (diff)
Initial suspend/resume
Doesn't work yet... Signed-off-by: Thomas White <taw@bitwiz.org.uk>
-rw-r--r--drivers/mfd/glamo/glamo-cmdq.c12
-rw-r--r--drivers/mfd/glamo/glamo-cmdq.h2
-rw-r--r--drivers/mfd/glamo/glamo-display.c66
-rw-r--r--drivers/mfd/glamo/glamo-display.h6
-rw-r--r--drivers/mfd/glamo/glamo-drm-drv.c14
-rw-r--r--drivers/mfd/glamo/glamo-drm-private.h20
-rw-r--r--drivers/mfd/glamo/glamo-kms-fb.c13
-rw-r--r--drivers/mfd/glamo/glamo-kms-fb.h4
8 files changed, 135 insertions, 2 deletions
diff --git a/drivers/mfd/glamo/glamo-cmdq.c b/drivers/mfd/glamo/glamo-cmdq.c
index f24d6814849..bdae9859854 100644
--- a/drivers/mfd/glamo/glamo-cmdq.c
+++ b/drivers/mfd/glamo/glamo-cmdq.c
@@ -385,3 +385,15 @@ int glamo_cmdq_init(struct glamodrm_handle *gdrm)
return 0;
}
+
+
+void glamo_cmdq_suspend(struct glamodrm_handle *gdrm)
+{
+ /* Placeholder... */
+}
+
+
+void glamo_cmdq_resume(struct glamodrm_handle *gdrm)
+{
+ glamo_cmdq_init(gdrm);
+}
diff --git a/drivers/mfd/glamo/glamo-cmdq.h b/drivers/mfd/glamo/glamo-cmdq.h
index f5d5ce6ae5a..4bc6b717115 100644
--- a/drivers/mfd/glamo/glamo-cmdq.h
+++ b/drivers/mfd/glamo/glamo-cmdq.h
@@ -34,6 +34,8 @@ extern int glamo_ioctl_cmdbuf(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int glamo_cmdq_init(struct glamodrm_handle *gdrm);
+extern void glamo_cmdq_suspend(struct glamodrm_handle *gdrm);
+extern void glamo_cmdq_resume(struct glamodrm_handle *gdrm);
#endif /* __GLAMO_CMDQ_H */
diff --git a/drivers/mfd/glamo/glamo-display.c b/drivers/mfd/glamo/glamo-display.c
index 4a39534dfdf..a5be9236b66 100644
--- a/drivers/mfd/glamo/glamo-display.c
+++ b/drivers/mfd/glamo/glamo-display.c
@@ -319,6 +319,7 @@ static void glamo_crtc_mode_set(struct drm_crtc *crtc,
glamo_lcd_cmd_mode(gdrm, 1);
glamo_engine_reclock(gdrm->glamo_core, GLAMO_ENGINE_LCD, mode->clock);
+ gdrm->saved_clock = mode->clock;
reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_WIDTH,
GLAMO_LCD_WIDTH_MASK, mode->hdisplay);
@@ -831,3 +832,68 @@ int glamo_display_init(struct drm_device *dev)
return 0;
}
+
+
+void glamo_display_suspend(struct glamodrm_handle *gdrm)
+{
+ jbt6k74_action(0);
+
+ gdrm->saved_width = reg_read_lcd(gdrm, GLAMO_REG_LCD_WIDTH);
+ gdrm->saved_height = reg_read_lcd(gdrm, GLAMO_REG_LCD_HEIGHT);
+ gdrm->saved_pitch = reg_read_lcd(gdrm, GLAMO_REG_LCD_PITCH);
+ gdrm->saved_htotal = reg_read_lcd(gdrm, GLAMO_REG_LCD_HORIZ_TOTAL);
+ gdrm->saved_hrtrst = reg_read_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_START);
+ gdrm->saved_hrtren = reg_read_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_END);
+ gdrm->saved_hdspst = reg_read_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_START);
+ gdrm->saved_hdspen = reg_read_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_END);
+ gdrm->saved_vtotal = reg_read_lcd(gdrm, GLAMO_REG_LCD_VERT_TOTAL);
+ gdrm->saved_vrtrst = reg_read_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_START);
+ gdrm->saved_vrtren = reg_read_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_END);
+ gdrm->saved_vdspst = reg_read_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_START);
+ gdrm->saved_vdspen = reg_read_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_END);
+}
+
+
+void glamo_display_resume(struct glamodrm_handle *gdrm)
+{
+ /* Reinitialise the LCD controller */
+ jbt6k74_action(0);
+ mdelay(5);
+
+ glamo_engine_enable(gdrm->glamo_core, GLAMO_ENGINE_LCD);
+ glamo_engine_reset(gdrm->glamo_core, GLAMO_ENGINE_LCD);
+ glamo_run_lcd_script(gdrm, lcd_init_script,
+ ARRAY_SIZE(lcd_init_script));
+
+ /* Restore timings */
+ glamo_lcd_cmd_mode(gdrm, 1);
+ glamo_engine_reclock(gdrm->glamo_core, GLAMO_ENGINE_LCD,
+ gdrm->saved_clock);
+ reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_TOTAL,
+ GLAMO_LCD_HV_TOTAL_MASK, gdrm->saved_htotal);
+ reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_START,
+ GLAMO_LCD_HV_RETR_START_MASK, gdrm->saved_vrtrst);
+ reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_END,
+ GLAMO_LCD_HV_RETR_END_MASK, gdrm->saved_vrtren);
+ reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_START,
+ GLAMO_LCD_HV_RETR_DISP_START_MASK,
+ gdrm->saved_hdspst);
+ reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_END,
+ GLAMO_LCD_HV_RETR_DISP_END_MASK,
+ gdrm->saved_hdspen);
+ reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_TOTAL,
+ GLAMO_LCD_HV_TOTAL_MASK, gdrm->saved_vtotal);
+ reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_START,
+ GLAMO_LCD_HV_RETR_START_MASK, gdrm->saved_vrtrst);
+ reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_END,
+ GLAMO_LCD_HV_RETR_END_MASK, gdrm->saved_vrtren);
+ reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_START,
+ GLAMO_LCD_HV_RETR_DISP_START_MASK,
+ gdrm->saved_vdspst);
+ reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_END,
+ GLAMO_LCD_HV_RETR_DISP_END_MASK,
+ gdrm->saved_vdspen);
+ glamo_lcd_cmd_mode(gdrm, 0);
+
+ jbt6k74_action(1);
+}
diff --git a/drivers/mfd/glamo/glamo-display.h b/drivers/mfd/glamo/glamo-display.h
index c8f526d747d..d6f21bcb0c0 100644
--- a/drivers/mfd/glamo/glamo-display.h
+++ b/drivers/mfd/glamo/glamo-display.h
@@ -24,6 +24,7 @@
#define __GLAMO_DISPLAY_H
#include <drm/drmP.h>
+#include "glamo-drm-private.h"
extern int glamo_display_init(struct drm_device *dev);
@@ -31,5 +32,8 @@ extern int glamo_framebuffer_create(struct drm_device *dev,
struct drm_mode_fb_cmd *mode_cmd,
struct drm_framebuffer **fb,
struct drm_gem_object *obj);
-
+
+extern void glamo_display_suspend(struct glamodrm_handle *gdrm);
+extern void glamo_display_resume(struct glamodrm_handle *gdrm);
+
#endif /* __GLAMO_DISPLAY_H */
diff --git a/drivers/mfd/glamo/glamo-drm-drv.c b/drivers/mfd/glamo/glamo-drm-drv.c
index 97d058f57d6..d71da8850ac 100644
--- a/drivers/mfd/glamo/glamo-drm-drv.c
+++ b/drivers/mfd/glamo/glamo-drm-drv.c
@@ -33,6 +33,7 @@
#include "glamo-buffer.h"
#include "glamo-drm-private.h"
#include "glamo-display.h"
+#include "glamo-kms-fb.h"
#define DRIVER_AUTHOR "Openmoko, Inc."
#define DRIVER_NAME "glamo-drm"
@@ -354,7 +355,14 @@ static int glamodrm_remove(struct platform_device *pdev)
static int glamodrm_suspend(struct platform_device *pdev, pm_message_t state)
{
+ struct glamodrm_handle *gdrm = platform_get_drvdata(pdev);
+
+ glamo_kmsfb_suspend(gdrm);
+ glamo_display_suspend(gdrm);
+ glamo_cmdq_suspend(gdrm);
+
/* glamo_core.c will suspend the engines for us */
+
return 0;
}
@@ -362,7 +370,11 @@ static int glamodrm_suspend(struct platform_device *pdev, pm_message_t state)
static int glamodrm_resume(struct platform_device *pdev)
{
struct glamodrm_handle *gdrm = platform_get_drvdata(pdev);
- glamo_cmdq_init(gdrm);
+
+ glamo_cmdq_resume(gdrm);
+ glamo_display_resume(gdrm);
+ glamo_kmsfb_resume(gdrm);
+
return 0;
}
diff --git a/drivers/mfd/glamo/glamo-drm-private.h b/drivers/mfd/glamo/glamo-drm-private.h
index ec4b67c084d..b7a9932e6ca 100644
--- a/drivers/mfd/glamo/glamo-drm-private.h
+++ b/drivers/mfd/glamo/glamo-drm-private.h
@@ -37,9 +37,13 @@ struct glamodrm_handle {
/* This device */
struct device *dev;
+
/* The parent device handle */
struct glamo_core *glamo_core;
+ /* Framebuffer handle for the console (i.e. /dev/fb0) */
+ struct fb_info *fb;
+
/* Command queue registers */
struct resource *reg;
char __iomem *reg_base;
@@ -60,6 +64,22 @@ struct glamodrm_handle {
/* Memory management */
struct drm_mm *mmgr;
+
+ /* Saved state */
+ u_int16_t saved_clock;
+ u_int16_t saved_width;
+ u_int16_t saved_height;
+ u_int16_t saved_pitch;
+ u_int16_t saved_htotal;
+ u_int16_t saved_hrtrst;
+ u_int16_t saved_hrtren;
+ u_int16_t saved_hdspst;
+ u_int16_t saved_hdspen;
+ u_int16_t saved_vtotal;
+ u_int16_t saved_vrtrst;
+ u_int16_t saved_vrtren;
+ u_int16_t saved_vdspst;
+ u_int16_t saved_vdspen;
};
diff --git a/drivers/mfd/glamo/glamo-kms-fb.c b/drivers/mfd/glamo/glamo-kms-fb.c
index 0c828831bb0..13dce09d615 100644
--- a/drivers/mfd/glamo/glamo-kms-fb.c
+++ b/drivers/mfd/glamo/glamo-kms-fb.c
@@ -522,6 +522,7 @@ int glamofb_create(struct drm_device *dev, uint32_t fb_width,
fb->fbdev = info;
par->glamo_fb = glamo_fb;
par->dev = dev;
+ gdrm->fb = info;
info->var.pixclock = -1;
@@ -536,3 +537,15 @@ out_unref:
out:
return ret;
}
+
+
+void glamo_kmsfb_suspend(struct glamodrm_handle *gdrm)
+{
+ fb_set_suspend(gdrm->fb, 1);
+}
+
+
+void glamo_kmsfb_resume(struct glamodrm_handle *gdrm)
+{
+ fb_set_suspend(gdrm->fb, 0);
+}
diff --git a/drivers/mfd/glamo/glamo-kms-fb.h b/drivers/mfd/glamo/glamo-kms-fb.h
index f98bf6540aa..9ae597bd366 100644
--- a/drivers/mfd/glamo/glamo-kms-fb.h
+++ b/drivers/mfd/glamo/glamo-kms-fb.h
@@ -28,10 +28,14 @@
#define __GLAMO_KMS_FB_H
#include <drm/drmP.h>
+#include "glamo-drm-private.h"
extern int glamofb_create(struct drm_device *dev, uint32_t fb_width,
uint32_t fb_height, uint32_t surface_width,
uint32_t surface_height,
struct glamo_framebuffer **glamo_fb_p);
+extern void glamo_kmsfb_suspend(struct glamodrm_handle *gdrm);
+extern void glamo_kmsfb_resume(struct glamodrm_handle *gdrm);
+
#endif /* __GLAMO_KMS_FB_H */