diff options
Diffstat (limited to 'drivers/mfd/glamo')
-rw-r--r-- | drivers/mfd/glamo/glamo-display.c | 116 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-display.h | 2 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-drm-private.h | 10 | ||||
-rw-r--r-- | drivers/mfd/glamo/glamo-kms-fb.c | 54 |
4 files changed, 79 insertions, 103 deletions
diff --git a/drivers/mfd/glamo/glamo-display.c b/drivers/mfd/glamo/glamo-display.c index 34a665a6430..a384c8be5c9 100644 --- a/drivers/mfd/glamo/glamo-display.c +++ b/drivers/mfd/glamo/glamo-display.c @@ -239,14 +239,6 @@ static int glamo_run_lcd_script(struct glamodrm_handle *gdrm, } -extern void jbt6k74_action(int val); - -/* Power on/off */ -static void glamo_crtc_dpms(struct drm_crtc *crtc, int mode) -{ -} - - static bool glamo_crtc_mode_fixup(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode) @@ -275,6 +267,12 @@ static int glamo_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, gcrtc = to_glamo_crtc(crtc); gdrm = gcrtc->gdrm; /* Here it is! */ + if ( !gcrtc->pixel_clock_on ) { + printk(KERN_WARNING "[glamo-drm] Refusing to set base while " + "pixel clock is off.\n"); + return -EBUSY; + } + gfb = to_glamo_framebuffer(crtc->fb); obj = gfb->obj; gobj = obj->driver_private; @@ -306,6 +304,12 @@ static int glamo_crtc_mode_set(struct drm_crtc *crtc, gcrtc = to_glamo_crtc(crtc); gdrm = gcrtc->gdrm; /* Here it is! */ + if ( !gcrtc->pixel_clock_on ) { + printk(KERN_WARNING "[glamo-drm] Refusing to set mode while " + "pixel clock is off.\n"); + return -EBUSY; + } + glamo_lcd_cmd_mode(gdrm, 1); glamo_engine_reclock(gdrm->glamo_core, GLAMO_ENGINE_LCD, mode->clock); @@ -354,10 +358,47 @@ static int glamo_crtc_mode_set(struct drm_crtc *crtc, glamo_crtc_mode_set_base(crtc, 0, 0, old_fb); + gcrtc->current_mode = *mode; + gcrtc->current_mode_set = 1; + gcrtc->current_fb = old_fb; + return 0; } +extern void jbt6k74_action(int val); + +/* This is not the right place to switch power on/off, because the helper + * stuff ends up calling this before/after setting the mode. We can't + * set modes with the display off (although backlight off would be OK) */ +static void glamo_crtc_dpms(struct drm_crtc *crtc, int mode) +{ + /* do nothing */ +} + + +void glamo_lcd_power(struct glamodrm_handle *gdrm, int mode) +{ + struct drm_crtc *crtc = gdrm->crtc; + struct glamo_crtc *gcrtc = to_glamo_crtc(crtc); + + if ( mode ) { + glamo_engine_enable(gdrm->glamo_core, GLAMO_ENGINE_LCD); + gcrtc->pixel_clock_on = 1; + jbt6k74_action(1); + if ( gcrtc->current_mode_set ) { + glamo_crtc_mode_set(crtc, &gcrtc->current_mode, + &gcrtc->current_mode, 0, 0, + gcrtc->current_fb); + } + } else { + jbt6k74_action(0); + glamo_engine_suspend(gdrm->glamo_core, GLAMO_ENGINE_LCD); + gcrtc->pixel_clock_on = 0; + } +} + + static void glamo_crtc_prepare(struct drm_crtc *crtc) { } @@ -725,6 +766,8 @@ int glamo_display_init(struct drm_device *dev) + sizeof(struct drm_connector *), GFP_KERNEL); if (glamo_crtc == NULL) return 1; glamo_crtc->gdrm = gdrm; + gdrm->crtc = (struct drm_crtc *)glamo_crtc; + glamo_crtc->pixel_clock_on = 1; glamo_crtc->blank_mode = DRM_MODE_DPMS_OFF; drm_crtc_init(dev, &glamo_crtc->base, &glamo_crtc_funcs); drm_crtc_helper_add(&glamo_crtc->base, &glamo_crtc_helper_funcs); @@ -808,62 +851,23 @@ int glamo_display_init(struct drm_device *dev) void glamo_display_suspend(struct glamodrm_handle *gdrm) { - 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); + /* do nothing */ } void glamo_display_resume(struct glamodrm_handle *gdrm) { + struct drm_crtc *crtc = gdrm->crtc; + struct glamo_crtc *gcrtc = to_glamo_crtc(crtc); + 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_WIDTH, GLAMO_LCD_WIDTH_MASK, - gdrm->saved_width); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HEIGHT, GLAMO_LCD_HEIGHT_MASK, - gdrm->saved_height); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_PITCH, GLAMO_LCD_PITCH_MASK, - gdrm->saved_pitch); - 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_hrtrst); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_END, - GLAMO_LCD_HV_RETR_END_MASK, gdrm->saved_hrtren); - 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); + if ( gcrtc->current_mode_set ) { + glamo_crtc_mode_set(crtc, &gcrtc->current_mode, + &gcrtc->current_mode, 0, 0, + gcrtc->current_fb); + } } diff --git a/drivers/mfd/glamo/glamo-display.h b/drivers/mfd/glamo/glamo-display.h index d6f21bcb0c0..728bba56a37 100644 --- a/drivers/mfd/glamo/glamo-display.h +++ b/drivers/mfd/glamo/glamo-display.h @@ -36,4 +36,6 @@ extern int glamo_framebuffer_create(struct drm_device *dev, extern void glamo_display_suspend(struct glamodrm_handle *gdrm); extern void glamo_display_resume(struct glamodrm_handle *gdrm); +extern void glamo_lcd_power(struct glamodrm_handle *gdrm, int mode); + #endif /* __GLAMO_DISPLAY_H */ diff --git a/drivers/mfd/glamo/glamo-drm-private.h b/drivers/mfd/glamo/glamo-drm-private.h index 7949a2e47b9..4e24019672e 100644 --- a/drivers/mfd/glamo/glamo-drm-private.h +++ b/drivers/mfd/glamo/glamo-drm-private.h @@ -106,6 +106,9 @@ struct glamodrm_handle { /* A scratch block */ struct drm_mm_node *scratch; + + /* We only have one */ + struct drm_crtc *crtc; }; @@ -118,11 +121,18 @@ struct drm_glamo_gem_object { struct glamo_crtc { + struct drm_crtc base; struct glamodrm_handle *gdrm; /* a mode_set for fbdev users on this crtc */ struct drm_mode_set mode_set; int blank_mode; + + int pixel_clock_on; + + int current_mode_set; + struct drm_display_mode current_mode; + struct drm_framebuffer *current_fb; }; diff --git a/drivers/mfd/glamo/glamo-kms-fb.c b/drivers/mfd/glamo/glamo-kms-fb.c index 61cd6054eb8..57680eddccc 100644 --- a/drivers/mfd/glamo/glamo-kms-fb.c +++ b/drivers/mfd/glamo/glamo-kms-fb.c @@ -253,64 +253,24 @@ static void glamofb_on(struct fb_info *info) { struct glamofb_par *par = info->par; struct drm_device *dev = par->dev; - struct drm_crtc *crtc; - struct drm_encoder *encoder; - int i; + struct glamodrm_handle *gdrm = dev->dev_private; - /* - * For each CRTC in this fb, find all associated encoders - * and turn them off, then turn off the CRTC. - */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; + printk(KERN_CRIT "Turning on display...\n"); - for (i = 0; i < par->crtc_count; i++) - if (crtc->base.id == par->crtc_ids[i]) - break; - - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); + gdrm = dev->dev_private; - /* Found a CRTC on this fb, now find encoders */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - struct drm_encoder_helper_funcs *encoder_funcs; - encoder_funcs = encoder->helper_private; - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); - } - } - } + glamo_lcd_power(gdrm, 1); } static void glamofb_off(struct fb_info *info, int dpms_mode) { struct glamofb_par *par = info->par; struct drm_device *dev = par->dev; - struct drm_crtc *crtc; - struct drm_encoder *encoder; - int i; + struct glamodrm_handle *gdrm = dev->dev_private; - /* - * For each CRTC in this fb, find all associated encoders - * and turn them off, then turn off the CRTC. - */ - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; - - for (i = 0; i < par->crtc_count; i++) - if (crtc->base.id == par->crtc_ids[i]) - break; + printk(KERN_CRIT "Turning off display...\n"); - /* Found a CRTC on this fb, now find encoders */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - struct drm_encoder_helper_funcs *encoder_funcs; - encoder_funcs = encoder->helper_private; - encoder_funcs->dpms(encoder, dpms_mode); - } - } - if (dpms_mode == DRM_MODE_DPMS_OFF) - crtc_funcs->dpms(crtc, dpms_mode); - } + glamo_lcd_power(gdrm, 0); } static int glamofb_blank(int blank, struct fb_info *info) |