From 5e92c39bf79c43508f6808f6f539c159000ce4c0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 25 Feb 2013 20:46:23 -0800 Subject: [PATCH] 3.8-stable patches added patches: drm-radeon-dce6-fix-display-powergating.patch drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch drm-radeon-properly-validate-the-atpx-interface.patch drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch drm-udl-disable-fb_defio-by-default.patch drm-udl-make-usage-as-a-console-safer.patch vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch --- ...-radeon-dce6-fix-display-powergating.patch | 50 +++++++ ...power-profile-stability-on-btc-asics.patch | 52 ++++++++ ...properly-validate-the-atpx-interface.patch | 121 +++++++++++++++++ ...overzealous-warning-in-hdmi-handling.patch | 32 +++++ .../drm-udl-disable-fb_defio-by-default.patch | 35 +++++ ...rm-udl-make-usage-as-a-console-safer.patch | 124 ++++++++++++++++++ queue-3.8/series | 7 + ...when-we-load-a-512-character-font-v2.patch | 103 +++++++++++++++ 8 files changed, 524 insertions(+) create mode 100644 queue-3.8/drm-radeon-dce6-fix-display-powergating.patch create mode 100644 queue-3.8/drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch create mode 100644 queue-3.8/drm-radeon-properly-validate-the-atpx-interface.patch create mode 100644 queue-3.8/drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch create mode 100644 queue-3.8/drm-udl-disable-fb_defio-by-default.patch create mode 100644 queue-3.8/drm-udl-make-usage-as-a-console-safer.patch create mode 100644 queue-3.8/vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch diff --git a/queue-3.8/drm-radeon-dce6-fix-display-powergating.patch b/queue-3.8/drm-radeon-dce6-fix-display-powergating.patch new file mode 100644 index 00000000000..07f676f480c --- /dev/null +++ b/queue-3.8/drm-radeon-dce6-fix-display-powergating.patch @@ -0,0 +1,50 @@ +From 0e3d50bfcbd338254795a700dcff429a96cba1a6 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 5 Feb 2013 11:47:09 -0500 +Subject: drm/radeon/dce6: fix display powergating + +From: Alex Deucher + +commit 0e3d50bfcbd338254795a700dcff429a96cba1a6 upstream. + +Only enable it when we disable the display rather than +at DPMS time since enabling it requires a full modeset +to restore the display state. Fixes blank screens in +certain cases. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/atombios_crtc.c | 6 ++---- + 1 file changed, 2 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/radeon/atombios_crtc.c ++++ b/drivers/gpu/drm/radeon/atombios_crtc.c +@@ -252,8 +252,6 @@ void atombios_crtc_dpms(struct drm_crtc + radeon_crtc->enabled = true; + /* adjust pm to dpms changes BEFORE enabling crtcs */ + radeon_pm_compute_clocks(rdev); +- if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) +- atombios_powergate_crtc(crtc, ATOM_DISABLE); + atombios_enable_crtc(crtc, ATOM_ENABLE); + if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) + atombios_enable_crtc_memreq(crtc, ATOM_ENABLE); +@@ -271,8 +269,6 @@ void atombios_crtc_dpms(struct drm_crtc + atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); + atombios_enable_crtc(crtc, ATOM_DISABLE); + radeon_crtc->enabled = false; +- if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) +- atombios_powergate_crtc(crtc, ATOM_ENABLE); + /* adjust pm to dpms changes AFTER disabling crtcs */ + radeon_pm_compute_clocks(rdev); + break; +@@ -1844,6 +1840,8 @@ static void atombios_crtc_disable(struct + int i; + + atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); ++ if (ASIC_IS_DCE6(rdev)) ++ atombios_powergate_crtc(crtc, ATOM_ENABLE); + + for (i = 0; i < rdev->num_crtc; i++) { + if (rdev->mode_info.crtcs[i] && diff --git a/queue-3.8/drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch b/queue-3.8/drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch new file mode 100644 index 00000000000..97b5c23ed95 --- /dev/null +++ b/queue-3.8/drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch @@ -0,0 +1,52 @@ +From 7ae764b11ed63279e9dcf25be972ff4ca21a9875 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Mon, 11 Feb 2013 08:44:48 -0500 +Subject: drm/radeon: fix multi-head power profile stability on BTC+ asics + +From: Alex Deucher + +commit 7ae764b11ed63279e9dcf25be972ff4ca21a9875 upstream. + +vddci needs to track mclk for multi-head. + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/evergreen.c | 13 +++++++++++++ + drivers/gpu/drm/radeon/radeon_pm.c | 2 +- + 2 files changed, 14 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/evergreen.c ++++ b/drivers/gpu/drm/radeon/evergreen.c +@@ -403,6 +403,19 @@ void evergreen_pm_misc(struct radeon_dev + rdev->pm.current_vddc = voltage->voltage; + DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); + } ++ ++ /* starting with BTC, there is one state that is used for both ++ * MH and SH. Difference is that we always use the high clock index for ++ * mclk and vddci. ++ */ ++ if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && ++ (rdev->family >= CHIP_BARTS) && ++ rdev->pm.active_crtc_count && ++ ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) || ++ (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX))) ++ voltage = &rdev->pm.power_state[req_ps_idx]. ++ clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].voltage; ++ + /* 0xff01 is a flag rather then an actual voltage */ + if (voltage->vddci == 0xff01) + return; +--- a/drivers/gpu/drm/radeon/radeon_pm.c ++++ b/drivers/gpu/drm/radeon/radeon_pm.c +@@ -169,7 +169,7 @@ static void radeon_set_power_state(struc + + /* starting with BTC, there is one state that is used for both + * MH and SH. Difference is that we always use the high clock index for +- * mclk. ++ * mclk and vddci. + */ + if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && + (rdev->family >= CHIP_BARTS) && diff --git a/queue-3.8/drm-radeon-properly-validate-the-atpx-interface.patch b/queue-3.8/drm-radeon-properly-validate-the-atpx-interface.patch new file mode 100644 index 00000000000..9ccba10cf82 --- /dev/null +++ b/queue-3.8/drm-radeon-properly-validate-the-atpx-interface.patch @@ -0,0 +1,121 @@ +From 43a23aa450cc19fe8996caf09e7e21ae5f6e56e8 Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 19 Feb 2013 12:55:52 -0500 +Subject: drm/radeon: properly validate the atpx interface + +From: Alex Deucher + +commit 43a23aa450cc19fe8996caf09e7e21ae5f6e56e8 upstream. + +Some bioses don't set the function mask correctly +which caused required functions to be disabled. + +Fixes: +https://bugzilla.kernel.org/show_bug.cgi?id=53111 + +Signed-off-by: Alex Deucher +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/radeon_atpx_handler.c | 73 ++++++++++++++++++++++++++- + 1 file changed, 71 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c ++++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c +@@ -43,6 +43,12 @@ struct atpx_verify_interface { + u32 function_bits; /* supported functions bit vector */ + } __packed; + ++struct atpx_px_params { ++ u16 size; /* structure size in bytes (includes size field) */ ++ u32 valid_flags; /* which flags are valid */ ++ u32 flags; /* flags */ ++} __packed; ++ + struct atpx_power_control { + u16 size; + u8 dgpu_state; +@@ -123,9 +129,61 @@ static void radeon_atpx_parse_functions( + } + + /** ++ * radeon_atpx_validate_functions - validate ATPX functions ++ * ++ * @atpx: radeon atpx struct ++ * ++ * Validate that required functions are enabled (all asics). ++ * returns 0 on success, error on failure. ++ */ ++static int radeon_atpx_validate(struct radeon_atpx *atpx) ++{ ++ /* make sure required functions are enabled */ ++ /* dGPU power control is required */ ++ atpx->functions.power_cntl = true; ++ ++ if (atpx->functions.px_params) { ++ union acpi_object *info; ++ struct atpx_px_params output; ++ size_t size; ++ u32 valid_bits; ++ ++ info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL); ++ if (!info) ++ return -EIO; ++ ++ memset(&output, 0, sizeof(output)); ++ ++ size = *(u16 *) info->buffer.pointer; ++ if (size < 10) { ++ printk("ATPX buffer is too small: %zu\n", size); ++ kfree(info); ++ return -EINVAL; ++ } ++ size = min(sizeof(output), size); ++ ++ memcpy(&output, info->buffer.pointer, size); ++ ++ valid_bits = output.flags & output.valid_flags; ++ /* if separate mux flag is set, mux controls are required */ ++ if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) { ++ atpx->functions.i2c_mux_cntl = true; ++ atpx->functions.disp_mux_cntl = true; ++ } ++ /* if any outputs are muxed, mux controls are required */ ++ if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED | ++ ATPX_TV_SIGNAL_MUXED | ++ ATPX_DFP_SIGNAL_MUXED)) ++ atpx->functions.disp_mux_cntl = true; ++ ++ kfree(info); ++ } ++ return 0; ++} ++ ++/** + * radeon_atpx_verify_interface - verify ATPX + * +- * @handle: acpi handle + * @atpx: radeon atpx struct + * + * Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function +@@ -406,8 +464,19 @@ static bool radeon_atpx_pci_probe_handle + */ + static int radeon_atpx_init(void) + { ++ int r; ++ + /* set up the ATPX handle */ +- return radeon_atpx_verify_interface(&radeon_atpx_priv.atpx); ++ r = radeon_atpx_verify_interface(&radeon_atpx_priv.atpx); ++ if (r) ++ return r; ++ ++ /* validate the atpx setup */ ++ r = radeon_atpx_validate(&radeon_atpx_priv.atpx); ++ if (r) ++ return r; ++ ++ return 0; + } + + /** diff --git a/queue-3.8/drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch b/queue-3.8/drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch new file mode 100644 index 00000000000..b8af7349c94 --- /dev/null +++ b/queue-3.8/drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch @@ -0,0 +1,32 @@ +From c944b2abb067130542055666f23409fd5e1afc8e Mon Sep 17 00:00:00 2001 +From: Alex Deucher +Date: Tue, 12 Feb 2013 08:39:10 -0500 +Subject: drm/radeon: remove overzealous warning in hdmi handling + +From: Alex Deucher + +commit c944b2abb067130542055666f23409fd5e1afc8e upstream. + +hdmi audio works fine. The warning just confuses users. + +fixes: +https://bugzilla.kernel.org/show_bug.cgi?id=44341 + +Signed-off-by: Alex Deucher +Reviewed-by: Jerome Glisse +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/radeon/r600_hdmi.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/gpu/drm/radeon/r600_hdmi.c ++++ b/drivers/gpu/drm/radeon/r600_hdmi.c +@@ -544,7 +544,6 @@ void r600_hdmi_disable(struct drm_encode + + /* Called for ATOM_ENCODER_MODE_HDMI only */ + if (!dig || !dig->afmt) { +- WARN_ON(1); + return; + } + if (!dig->afmt->enabled) diff --git a/queue-3.8/drm-udl-disable-fb_defio-by-default.patch b/queue-3.8/drm-udl-disable-fb_defio-by-default.patch new file mode 100644 index 00000000000..1da6b5a097d --- /dev/null +++ b/queue-3.8/drm-udl-disable-fb_defio-by-default.patch @@ -0,0 +1,35 @@ +From 677d23b70bf949f75746c80cbae92c233c6b5e2a Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Thu, 7 Feb 2013 12:30:25 +1000 +Subject: drm/udl: disable fb_defio by default + +From: Dave Airlie + +commit 677d23b70bf949f75746c80cbae92c233c6b5e2a upstream. + +There seems to be a bad interaction between gem/shmem and defio on top, +I get list corruption on the page lru in the shmem code. + +Turn it off for now until we get some more digging done. + +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/udl/udl_fb.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/udl/udl_fb.c ++++ b/drivers/gpu/drm/udl/udl_fb.c +@@ -22,9 +22,9 @@ + + #include + +-#define DL_DEFIO_WRITE_DELAY 5 /* fb_deferred_io.delay in jiffies */ ++#define DL_DEFIO_WRITE_DELAY (HZ/20) /* fb_deferred_io.delay in jiffies */ + +-static int fb_defio = 1; /* Optionally enable experimental fb_defio mmap support */ ++static int fb_defio = 0; /* Optionally enable experimental fb_defio mmap support */ + static int fb_bpp = 16; + + module_param(fb_bpp, int, S_IWUSR | S_IRUSR | S_IWGRP | S_IRGRP); diff --git a/queue-3.8/drm-udl-make-usage-as-a-console-safer.patch b/queue-3.8/drm-udl-make-usage-as-a-console-safer.patch new file mode 100644 index 00000000000..9e7f3291922 --- /dev/null +++ b/queue-3.8/drm-udl-make-usage-as-a-console-safer.patch @@ -0,0 +1,124 @@ +From bcb39af4486be07e896fc374a2336bad3104ae0a Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Thu, 7 Feb 2013 11:19:15 +1000 +Subject: drm/udl: make usage as a console safer + +From: Dave Airlie + +commit bcb39af4486be07e896fc374a2336bad3104ae0a upstream. + +Okay you don't really want to use udl devices as your console, but if +you are unlucky enough to do so, you run into a lot of schedule while atomic +due to printk being called from all sorts of funky places. So check if we +are in an atomic context, and queue the damage for later, the next printk +should cause it to appear. This isn't ideal, but it is simple, and seems to +work okay in my testing here. + +(dirty area idea came from xenfb) + +fixes a bunch of sleeping while atomic issues running fbcon on udl devices. + +Signed-off-by: Dave Airlie +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/udl/udl_drv.h | 2 + + drivers/gpu/drm/udl/udl_fb.c | 44 ++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 42 insertions(+), 4 deletions(-) + +--- a/drivers/gpu/drm/udl/udl_drv.h ++++ b/drivers/gpu/drm/udl/udl_drv.h +@@ -75,6 +75,8 @@ struct udl_framebuffer { + struct drm_framebuffer base; + struct udl_gem_object *obj; + bool active_16; /* active on the 16-bit channel */ ++ int x1, y1, x2, y2; /* dirty rect */ ++ spinlock_t dirty_lock; + }; + + #define to_udl_fb(x) container_of(x, struct udl_framebuffer, base) +--- a/drivers/gpu/drm/udl/udl_fb.c ++++ b/drivers/gpu/drm/udl/udl_fb.c +@@ -153,6 +153,9 @@ int udl_handle_damage(struct udl_framebu + struct urb *urb; + int aligned_x; + int bpp = (fb->base.bits_per_pixel / 8); ++ int x2, y2; ++ bool store_for_later = false; ++ unsigned long flags; + + if (!fb->active_16) + return 0; +@@ -169,8 +172,6 @@ int udl_handle_damage(struct udl_framebu + } + } + +- start_cycles = get_cycles(); +- + aligned_x = DL_ALIGN_DOWN(x, sizeof(unsigned long)); + width = DL_ALIGN_UP(width + (x-aligned_x), sizeof(unsigned long)); + x = aligned_x; +@@ -180,19 +181,53 @@ int udl_handle_damage(struct udl_framebu + (y + height > fb->base.height)) + return -EINVAL; + ++ /* if we are in atomic just store the info ++ can't test inside spin lock */ ++ if (in_atomic()) ++ store_for_later = true; ++ ++ x2 = x + width - 1; ++ y2 = y + height - 1; ++ ++ spin_lock_irqsave(&fb->dirty_lock, flags); ++ ++ if (fb->y1 < y) ++ y = fb->y1; ++ if (fb->y2 > y2) ++ y2 = fb->y2; ++ if (fb->x1 < x) ++ x = fb->x1; ++ if (fb->x2 > x2) ++ x2 = fb->x2; ++ ++ if (store_for_later) { ++ fb->x1 = x; ++ fb->x2 = x2; ++ fb->y1 = y; ++ fb->y2 = y2; ++ spin_unlock_irqrestore(&fb->dirty_lock, flags); ++ return 0; ++ } ++ ++ fb->x1 = fb->y1 = INT_MAX; ++ fb->x2 = fb->y2 = 0; ++ ++ spin_unlock_irqrestore(&fb->dirty_lock, flags); ++ start_cycles = get_cycles(); ++ + urb = udl_get_urb(dev); + if (!urb) + return 0; + cmd = urb->transfer_buffer; + +- for (i = y; i < y + height ; i++) { ++ for (i = y; i <= y2 ; i++) { + const int line_offset = fb->base.pitches[0] * i; + const int byte_offset = line_offset + (x * bpp); + const int dev_byte_offset = (fb->base.width * bpp * i) + (x * bpp); + if (udl_render_hline(dev, bpp, &urb, + (char *) fb->obj->vmapping, + &cmd, byte_offset, dev_byte_offset, +- width * bpp, ++ (x2 - x + 1) * bpp, + &bytes_identical, &bytes_sent)) + goto error; + } +@@ -434,6 +469,7 @@ udl_framebuffer_init(struct drm_device * + { + int ret; + ++ spin_lock_init(&ufb->dirty_lock); + ufb->obj = obj; + ret = drm_framebuffer_init(dev, &ufb->base, &udlfb_funcs); + drm_helper_mode_fill_fb_struct(&ufb->base, mode_cmd); diff --git a/queue-3.8/series b/queue-3.8/series index 3468409af89..ce18b5c4038 100644 --- a/queue-3.8/series +++ b/queue-3.8/series @@ -61,3 +61,10 @@ sparc64-fix-gfp_flags-setting-in-tsb_grow.patch sparc64-handle-hugepage-tsb-being-null.patch sparc64-fix-tsb_grow-in-atomic-context.patch sparc64-fix-huge-pmd-to-pte-translation-for-sun4u-in-tlb-miss-handler.patch +drm-radeon-dce6-fix-display-powergating.patch +drm-radeon-fix-multi-head-power-profile-stability-on-btc-asics.patch +drm-radeon-remove-overzealous-warning-in-hdmi-handling.patch +drm-radeon-properly-validate-the-atpx-interface.patch +drm-udl-make-usage-as-a-console-safer.patch +drm-udl-disable-fb_defio-by-default.patch +vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch diff --git a/queue-3.8/vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch b/queue-3.8/vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch new file mode 100644 index 00000000000..3e0e9efb0df --- /dev/null +++ b/queue-3.8/vgacon-vt-clear-buffer-attributes-when-we-load-a-512-character-font-v2.patch @@ -0,0 +1,103 @@ +From 2a2483072393b27f4336ab068a1f48ca19ff1c1e Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Thu, 24 Jan 2013 14:14:19 +1000 +Subject: vgacon/vt: clear buffer attributes when we load a 512 character font (v2) + +From: Dave Airlie + +commit 2a2483072393b27f4336ab068a1f48ca19ff1c1e upstream. + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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(-) + +--- a/drivers/tty/vt/vt.c ++++ b/drivers/tty/vt/vt.c +@@ -638,7 +638,7 @@ static inline void save_screen(struct 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; +--- a/drivers/video/console/vgacon.c ++++ b/drivers/video/console/vgacon.c +@@ -1064,7 +1064,7 @@ static int vgacon_do_font_op(struct vgas + 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 vgas + + /* 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 vgas + 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; + } + +--- a/include/linux/vt_kern.h ++++ b/include/linux/vt_kern.h +@@ -47,6 +47,7 @@ int con_set_cmap(unsigned char __user *c + 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) -- 2.47.3