From patchwork Fri Jan 25 02:21:26 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Airlie X-Patchwork-Id: 2038021 Return-Path: X-Original-To: patchwork-linux-fbdev@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 9278FE020A for ; Fri, 25 Jan 2013 02:21:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755269Ab3AYCVm (ORCPT ); Thu, 24 Jan 2013 21:21:42 -0500 Received: from mx1.redhat.com ([209.132.183.28]:64082 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754706Ab3AYCVh (ORCPT ); Thu, 24 Jan 2013 21:21:37 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r0P2LTqq012572 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 24 Jan 2013 21:21:29 -0500 Received: from prime.bne.redhat.com (dhcp-40-183.bne.redhat.com [10.64.40.183]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id r0P2LRBL022407; Thu, 24 Jan 2013 21:21:27 -0500 From: Dave Airlie To: linux-fbdev@vger.kernel.org Cc: dri-devel@lists.sf.net, linux-kernel@vger.kernel.org, Dave Airlie Subject: [PATCH] vgacon/vt: clear buffer attributes when we load a 512 character font (v2) Date: Fri, 25 Jan 2013 12:21:26 +1000 Message-Id: <1359080486-19164-1-git-send-email-airlied@gmail.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 Sender: linux-fbdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fbdev@vger.kernel.org From: Dave Airlie When we switch from 256->512 byte font rendering mode, it means the current contents of the screen is being reinterpreted. The bit that holds the high bit of the 9-bit font, may have been previously set, and thus the new font misrenders. The problem case we see is grub2 writes spaces with the bit set, so it ends up with data like 0x820, which gets reinterpreted into 0x120 char which the font translates into G with a circumflex. This flashes up on screen at boot and is quite ugly. A current side effect of this patch though is that any rendering on the screen changes color to a slightly darker color, but at least the screen no longer corrupts. v2: as suggested by hpa, always clear the attribute space, whether we are are going to or from 512 chars. Signed-off-by: Dave Airlie f --- drivers/tty/vt/vt.c | 2 +- drivers/video/console/vgacon.c | 22 +++++++++++++++------- include/linux/vt_kern.h | 1 + 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 8fd8968..c8067ae 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -638,7 +638,7 @@ static inline void save_screen(struct vc_data *vc) * Redrawing of screen */ -static void clear_buffer_attributes(struct vc_data *vc) +void clear_buffer_attributes(struct vc_data *vc) { unsigned short *p = (unsigned short *)vc->vc_origin; int count = vc->vc_screenbuf_size / 2; diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index d449a74..5855d17 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -1064,7 +1064,7 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) unsigned short video_port_status = vga_video_port_reg + 6; int font_select = 0x00, beg, i; char *charmap; - + bool clear_attribs = false; if (vga_video_type != VIDEO_TYPE_EGAM) { charmap = (char *) VGA_MAP_MEM(colourmap, 0); beg = 0x0e; @@ -1169,12 +1169,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) /* if 512 char mode is already enabled don't re-enable it. */ if ((set) && (ch512 != vga_512_chars)) { - /* attribute controller */ - for (i = 0; i < MAX_NR_CONSOLES; i++) { - struct vc_data *c = vc_cons[i].d; - if (c && c->vc_sw == &vga_con) - c->vc_hi_font_mask = ch512 ? 0x0800 : 0; - } vga_512_chars = ch512; /* 256-char: enable intensity bit 512-char: disable intensity bit */ @@ -1185,8 +1179,22 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) it means, but it works, and it appears necessary */ inb_p(video_port_status); vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0); + clear_attribs = true; } raw_spin_unlock_irq(&vga_lock); + + if (clear_attribs) { + for (i = 0; i < MAX_NR_CONSOLES; i++) { + struct vc_data *c = vc_cons[i].d; + if (c && c->vc_sw == &vga_con) { + /* force hi font mask to 0, so we always clear + the bit on either transition */ + c->vc_hi_font_mask = 0x00; + clear_buffer_attributes(c); + c->vc_hi_font_mask = ch512 ? 0x0800 : 0; + } + } + } return 0; } diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 50ae7d0..1f55665 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -47,6 +47,7 @@ int con_set_cmap(unsigned char __user *cmap); int con_get_cmap(unsigned char __user *cmap); void scrollback(struct vc_data *vc, int lines); void scrollfront(struct vc_data *vc, int lines); +void clear_buffer_attributes(struct vc_data *vc); void update_region(struct vc_data *vc, unsigned long start, int count); void redraw_screen(struct vc_data *vc, int is_switch); #define update_screen(x) redraw_screen(x, 0)