From 357352a3f8f717222f98b13338ae7eb6beda664f Mon Sep 17 00:00:00 2001 From: Thomas White Date: Wed, 28 Apr 2010 00:09:00 +0200 Subject: Almost make rotation work Signed-off-by: Thomas White --- drivers/mfd/glamo/glamo-display.c | 171 ++++++++++++++++++++++++++++---------- 1 file changed, 129 insertions(+), 42 deletions(-) diff --git a/drivers/mfd/glamo/glamo-display.c b/drivers/mfd/glamo/glamo-display.c index a5519689476..75ad73497f4 100644 --- a/drivers/mfd/glamo/glamo-display.c +++ b/drivers/mfd/glamo/glamo-display.c @@ -298,6 +298,7 @@ static int glamo_crtc_mode_set(struct drm_crtc *crtc, struct glamodrm_handle *gdrm; struct glamo_crtc *gcrtc; int retr_start, retr_end, disp_start, disp_end; + int rot; /* Dig out our handle */ gcrtc = to_glamo_crtc(crtc); @@ -310,49 +311,135 @@ static int glamo_crtc_mode_set(struct drm_crtc *crtc, msleep(500); } + /* Rotate? */ + if ( (mode->hdisplay == 640) && (mode->vdisplay == 480) ) { + rot = GLAMO_LCD_ROT_MODE_90; + } else if ( (mode->hdisplay == 480) && (mode->vdisplay == 640) ) { + rot = GLAMO_LCD_ROT_MODE_0; + } else if ( (mode->hdisplay == 320) && (mode->vdisplay == 240) ) { + rot = GLAMO_LCD_ROT_MODE_90; + } else if ( (mode->hdisplay == 240) && (mode->vdisplay == 320) ) { + rot = GLAMO_LCD_ROT_MODE_0; + } else { + printk(KERN_WARNING "[glamo-drm] Couldn't choose rotation.\n"); + rot = GLAMO_LCD_ROT_MODE_0; + } + glamo_lcd_cmd_mode(gdrm, 1); - glamo_engine_reclock(gdrm->glamo_core, GLAMO_ENGINE_LCD, mode->clock); - gdrm->saved_clock = mode->clock; + /* Set dimensions */ + if ( rot == GLAMO_LCD_ROT_MODE_0 ) { + + glamo_engine_reclock(gdrm->glamo_core, GLAMO_ENGINE_LCD, + mode->clock); + + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_WIDTH, + GLAMO_LCD_WIDTH_MASK, mode->hdisplay); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HEIGHT, + GLAMO_LCD_HEIGHT_MASK, mode->vdisplay); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_PITCH, + GLAMO_LCD_PITCH_MASK, mode->hdisplay*2); + + /* Set rotation */ + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_WIDTH, + GLAMO_LCD_ROT_MODE_MASK, rot); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_MODE1, + GLAMO_LCD_MODE1_ROTATE_EN, + (rot != GLAMO_LCD_ROT_MODE_0) ? + GLAMO_LCD_MODE1_ROTATE_EN : 0); + + /* Convert "X modeline timings" into "Glamo timings" */ + retr_start = 0; + retr_end = retr_start + mode->hsync_end - mode->hsync_start; + disp_start = mode->htotal - mode->hsync_start; + disp_end = disp_start + mode->hdisplay; + + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_TOTAL, + GLAMO_LCD_HV_TOTAL_MASK, mode->htotal); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_START, + GLAMO_LCD_HV_RETR_START_MASK, retr_start); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_END, + GLAMO_LCD_HV_RETR_END_MASK, retr_end); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_START, + GLAMO_LCD_HV_RETR_DISP_START_MASK, disp_start); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_END, + GLAMO_LCD_HV_RETR_DISP_END_MASK, disp_end); + + /* The same in the vertical direction */ + retr_start = 0; + retr_end = retr_start + mode->vsync_end - mode->vsync_start; + disp_start = mode->vtotal - mode->vsync_start; + disp_end = disp_start + mode->vdisplay; + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_TOTAL, + GLAMO_LCD_HV_TOTAL_MASK, mode->vtotal); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_START, + GLAMO_LCD_HV_RETR_START_MASK, retr_start); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_END, + GLAMO_LCD_HV_RETR_END_MASK, retr_end); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_START, + GLAMO_LCD_HV_RETR_DISP_START_MASK, + disp_start); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_END, + GLAMO_LCD_HV_RETR_DISP_END_MASK, disp_end); + + } else { + + glamo_engine_reclock(gdrm->glamo_core, GLAMO_ENGINE_LCD, + mode->clock/2); + + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_WIDTH, + GLAMO_LCD_WIDTH_MASK, mode->vdisplay); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HEIGHT, + GLAMO_LCD_HEIGHT_MASK, mode->hdisplay); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_PITCH, + GLAMO_LCD_PITCH_MASK, mode->hdisplay*2); + + /* Set rotation */ + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_WIDTH, + GLAMO_LCD_ROT_MODE_MASK, rot); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_MODE1, + GLAMO_LCD_MODE1_ROTATE_EN, + (rot != GLAMO_LCD_ROT_MODE_0) ? + GLAMO_LCD_MODE1_ROTATE_EN : 0); + + /* Apply "vertical" numbers to the horizontal registers */ + retr_start = 0; + retr_end = retr_start + mode->vsync_end - mode->vsync_start; + disp_start = mode->vtotal - mode->vsync_start; + disp_end = disp_start + mode->vdisplay; + + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_TOTAL, + GLAMO_LCD_HV_TOTAL_MASK, mode->vtotal); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_START, + GLAMO_LCD_HV_RETR_START_MASK, retr_start); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_END, + GLAMO_LCD_HV_RETR_END_MASK, retr_end); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_START, + GLAMO_LCD_HV_RETR_DISP_START_MASK, + disp_start); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_END, + GLAMO_LCD_HV_RETR_DISP_END_MASK, disp_end); + + /* Apply "horizontal" numbers to the vertical registers */ + retr_start = 0; + retr_end = retr_start + mode->hsync_end - mode->hsync_start; + disp_start = mode->htotal - mode->hsync_start; + disp_end = disp_start + mode->hdisplay; + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_TOTAL, + GLAMO_LCD_HV_TOTAL_MASK, mode->htotal); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_START, + GLAMO_LCD_HV_RETR_START_MASK, retr_start); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_END, + GLAMO_LCD_HV_RETR_END_MASK, retr_end); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_START, + GLAMO_LCD_HV_RETR_DISP_START_MASK, + disp_start); + reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_END, + GLAMO_LCD_HV_RETR_DISP_END_MASK, disp_end); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_WIDTH, - GLAMO_LCD_WIDTH_MASK, mode->hdisplay); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HEIGHT, - GLAMO_LCD_HEIGHT_MASK, mode->vdisplay); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_PITCH, - GLAMO_LCD_PITCH_MASK, mode->hdisplay*2); - - /* Convert "X modeline timings" into "Glamo timings" */ - retr_start = 0; - retr_end = retr_start + mode->hsync_end - mode->hsync_start; - disp_start = mode->htotal - mode->hsync_start; - disp_end = disp_start + mode->hdisplay; - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_TOTAL, - GLAMO_LCD_HV_TOTAL_MASK, mode->htotal); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_START, - GLAMO_LCD_HV_RETR_START_MASK, retr_start); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_RETR_END, - GLAMO_LCD_HV_RETR_END_MASK, retr_end); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_START, - GLAMO_LCD_HV_RETR_DISP_START_MASK, disp_start); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_HORIZ_DISP_END, - GLAMO_LCD_HV_RETR_DISP_END_MASK, disp_end); - - /* The same in the vertical direction */ - retr_start = 0; - retr_end = retr_start + mode->vsync_end - mode->vsync_start; - disp_start = mode->vtotal - mode->vsync_start; - disp_end = disp_start + mode->vdisplay; - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_TOTAL, - GLAMO_LCD_HV_TOTAL_MASK, mode->vtotal); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_START, - GLAMO_LCD_HV_RETR_START_MASK, retr_start); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_RETR_END, - GLAMO_LCD_HV_RETR_END_MASK, retr_end); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_START, - GLAMO_LCD_HV_RETR_DISP_START_MASK, disp_start); - reg_set_bit_mask_lcd(gdrm, GLAMO_REG_LCD_VERT_DISP_END, - GLAMO_LCD_HV_RETR_DISP_END_MASK, disp_end); + } + + gdrm->saved_clock = mode->clock; glamo_lcd_cmd_mode(gdrm, 0); @@ -747,8 +834,8 @@ int glamo_display_init(struct drm_device *dev) drm_mode_config_init(dev); dev->mode_config.min_width = 240; - dev->mode_config.min_height = 320; - dev->mode_config.max_width = 480; + dev->mode_config.min_height = 240; + dev->mode_config.max_width = 640; dev->mode_config.max_height = 640; dev->mode_config.funcs = (void *)&glamo_mode_funcs; -- cgit v1.2.3