arm: Workaround incorrect HDLCD register order in kernel
authorAndreas Sandberg <andreas.sandberg@arm.com>
Sat, 23 May 2015 12:37:04 +0000 (13:37 +0100)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Sat, 23 May 2015 12:37:04 +0000 (13:37 +0100)
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
src/dev/arm/hdlcd.cc
src/dev/arm/hdlcd.hh

index 95edb9d5317a3b5776b99edfea12889e739ee7ed..9ff642cb1db0448bc21ade0e57ca0d4189bb44ef 100644 (file)
@@ -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):
index b1c1c450ba945b4ab3e18d556b7bfa7b6231b20c..3fc30f16d8048d96f488b68d39aa38df50dfff4e 100644 (file)
@@ -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
index 61d2dc5d7c87de5a771bd44699cdaea3e37fe277..519afeba69f84128a12d5b8dd69955f3d0ce0589 100644 (file)
@@ -486,6 +486,8 @@ class HDLcd: public AmbaDmaDevice
 
     bool enableCapture;
 
+    const bool workaround_swap_rb;
+
   public:
     typedef HDLcdParams Params;