Commit 2b6c53b1 authored by Jon Medhurst (Tixy)'s avatar Jon Medhurst (Tixy) Committed by Tomi Valkeinen

video: ARM CLCD: Fix calculation of bits-per-pixel

If the device-tree specifies a max-memory-bandwidth property then the
CLCD driver uses that to calculate the bits-per-pixel supported,
however, this calculation is faulty for two reasons.

1. It doesn't ensure that the result is a sane value, i.e. a power of 2
   and <= 32 as the rest of the code assumes.

2. It uses the displayed resolution and calculates the average bandwidth
   across the whole frame. It should instead calculate the peak
   bandwidth based on the pixel clock.

This patch fixes both the above.
Signed-off-by: default avatarJon Medhurst <tixy@linaro.org>
Acked-by: default avatarPawel Moll <pawel.moll@arm.com>
Signed-off-by: default avatarTomi Valkeinen <tomi.valkeinen@ti.com>
parent 754d561a
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/amba/bus.h> #include <linux/amba/bus.h>
#include <linux/amba/clcd.h> #include <linux/amba/clcd.h>
#include <linux/bitops.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/hardirq.h> #include <linux/hardirq.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
...@@ -650,6 +651,7 @@ static int clcdfb_of_init_display(struct clcd_fb *fb) ...@@ -650,6 +651,7 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
{ {
struct device_node *endpoint; struct device_node *endpoint;
int err; int err;
unsigned int bpp;
u32 max_bandwidth; u32 max_bandwidth;
u32 tft_r0b0g0[3]; u32 tft_r0b0g0[3];
...@@ -667,11 +669,22 @@ static int clcdfb_of_init_display(struct clcd_fb *fb) ...@@ -667,11 +669,22 @@ static int clcdfb_of_init_display(struct clcd_fb *fb)
err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth", err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth",
&max_bandwidth); &max_bandwidth);
if (!err) if (!err) {
fb->panel->bpp = 8 * max_bandwidth / (fb->panel->mode.xres * /*
fb->panel->mode.yres * fb->panel->mode.refresh); * max_bandwidth is in bytes per second and pixclock in
else * pico-seconds, so the maximum allowed bits per pixel is
fb->panel->bpp = 32; * 8 * max_bandwidth / (PICOS2KHZ(pixclock) * 1000)
* Rearrange this calculation to avoid overflow and then ensure
* result is a valid format.
*/
bpp = max_bandwidth / (1000 / 8)
/ PICOS2KHZ(fb->panel->mode.pixclock);
bpp = rounddown_pow_of_two(bpp);
if (bpp > 32)
bpp = 32;
} else
bpp = 32;
fb->panel->bpp = bpp;
#ifdef CONFIG_CPU_BIG_ENDIAN #ifdef CONFIG_CPU_BIG_ENDIAN
fb->panel->cntl |= CNTL_BEBO; fb->panel->cntl |= CNTL_BEBO;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment