From cba3a125e1b7af015a736d44ab84a36129ee6890 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Sat, 23 May 2015 13:37:04 +0100 Subject: arm: Workaround incorrect HDLCD register order in kernel Some versions of the kernel incorrectly swap the red and blue color select registers. This changeset adds a workaround for that by swapping them when instantiating a PixelConverter. --- src/dev/arm/RealView.py | 2 ++ src/dev/arm/hdlcd.cc | 24 +++++++++++++++++++----- src/dev/arm/hdlcd.hh | 2 ++ 3 files changed, 23 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py index 95edb9d53..9ff642cb1 100644 --- a/src/dev/arm/RealView.py +++ b/src/dev/arm/RealView.py @@ -175,6 +175,8 @@ class HDLcd(AmbaDmaDevice): vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer " "display") amba_id = 0x00141000 + workaround_swap_rb = Param.Bool(True, "Workaround incorrect color " + "selector order in some kernels") enable_capture = Param.Bool(True, "capture frame to system.framebuffer.bmp") class RealView(Platform): diff --git a/src/dev/arm/hdlcd.cc b/src/dev/arm/hdlcd.cc index b1c1c450b..3fc30f16d 100644 --- a/src/dev/arm/hdlcd.cc +++ b/src/dev/arm/hdlcd.cc @@ -74,7 +74,8 @@ HDLcd::HDLcd(const Params *p) fillPixelBufferEvent(this), intEvent(this), dmaDoneEventAll(MAX_OUTSTANDING_DMA_REQ_CAPACITY, this), dmaDoneEventFree(MAX_OUTSTANDING_DMA_REQ_CAPACITY), - enableCapture(p->enable_capture) + enableCapture(p->enable_capture), + workaround_swap_rb(p->workaround_swap_rb) { pioSize = 0xFFFF; @@ -504,11 +505,24 @@ HDLcd::renderPixel() PixelConverter HDLcd::pixelConverter() const { - return PixelConverter( - bytesPerPixel(), - red_select.offset, green_select.offset, blue_select.offset, - red_select.size, green_select.size, blue_select.size, + ByteOrder byte_order( pixel_format.big_endian ? BigEndianByteOrder : LittleEndianByteOrder); + + /* Some Linux kernels have a broken driver that swaps the red and + * blue color select registers. */ + if (!workaround_swap_rb) { + return PixelConverter( + bytesPerPixel(), + red_select.offset, green_select.offset, blue_select.offset, + red_select.size, green_select.size, blue_select.size, + byte_order); + } else { + return PixelConverter( + bytesPerPixel(), + blue_select.offset, green_select.offset, red_select.offset, + blue_select.size, green_select.size, red_select.size, + byte_order); + } } void diff --git a/src/dev/arm/hdlcd.hh b/src/dev/arm/hdlcd.hh index 61d2dc5d7..519afeba6 100644 --- a/src/dev/arm/hdlcd.hh +++ b/src/dev/arm/hdlcd.hh @@ -486,6 +486,8 @@ class HDLcd: public AmbaDmaDevice bool enableCapture; + const bool workaround_swap_rb; + public: typedef HDLcdParams Params; -- cgit v1.2.3