dev: Fix the Pl111 timings by separating pixel and DMA clock

This patch fixes the Pl111 timings by creating a separate clock for
the pixel timings. The device clock is used for all interactions with
the memory system, just like the AHB clock on the actual module.

The result without this patch is that the module only is allowed to
send one request every tick of the 24MHz clock which causes a huge
backlog.
This commit is contained in:
Andreas Hansson 2013-01-07 13:05:36 -05:00
parent 79b4477302
commit fffdc6a450
3 changed files with 16 additions and 16 deletions

View file

@ -148,8 +148,7 @@ class Pl050(AmbaIntDevice):
class Pl111(AmbaDmaDevice): class Pl111(AmbaDmaDevice):
type = 'Pl111' type = 'Pl111'
cxx_header = "dev/arm/pl111.hh" cxx_header = "dev/arm/pl111.hh"
# Override the default clock pixel_clock = Param.Clock('24MHz', "Pixel clock")
clock = '24MHz'
vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display") vnc = Param.VncInput(Parent.any, "Vnc server for remote frame buffer display")
amba_id = 0x00141111 amba_id = 0x00141111

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010 ARM Limited * Copyright (c) 2010-2012 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * The license below extends only to copyright in the software and shall
@ -64,6 +64,7 @@ Pl111::Pl111(const Params *p)
clcdCrsrCtrl(0), clcdCrsrConfig(0), clcdCrsrPalette0(0), clcdCrsrCtrl(0), clcdCrsrConfig(0), clcdCrsrPalette0(0),
clcdCrsrPalette1(0), clcdCrsrXY(0), clcdCrsrClip(0), clcdCrsrImsc(0), clcdCrsrPalette1(0), clcdCrsrXY(0), clcdCrsrClip(0), clcdCrsrImsc(0),
clcdCrsrIcr(0), clcdCrsrRis(0), clcdCrsrMis(0), clcdCrsrIcr(0), clcdCrsrRis(0), clcdCrsrMis(0),
pixelClock(p->pixel_clock),
vnc(p->vnc), bmp(NULL), width(LcdMaxWidth), height(LcdMaxHeight), vnc(p->vnc), bmp(NULL), width(LcdMaxWidth), height(LcdMaxHeight),
bytesPerPixel(4), startTime(0), startAddr(0), maxAddr(0), curAddr(0), bytesPerPixel(4), startTime(0), startAddr(0), maxAddr(0), curAddr(0),
waterMark(0), dmaPendingNum(0), readEvent(this), fillFifoEvent(this), waterMark(0), dmaPendingNum(0), readEvent(this), fillFifoEvent(this),
@ -440,14 +441,12 @@ Pl111::readFramebuffer()
schedule(intEvent, nextCycle()); schedule(intEvent, nextCycle());
curAddr = 0; curAddr = 0;
startTime = curCycle(); startTime = curTick();
maxAddr = static_cast<Addr>(length * bytesPerPixel); maxAddr = static_cast<Addr>(length * bytesPerPixel);
DPRINTF(PL111, " lcd frame buffer size of %d bytes \n", maxAddr); DPRINTF(PL111, " lcd frame buffer size of %d bytes \n", maxAddr);
dmaPendingNum = 0;
fillFifo(); fillFifo();
} }
@ -475,13 +474,15 @@ Pl111::fillFifo()
void void
Pl111::dmaDone() Pl111::dmaDone()
{ {
Cycles maxFrameTime(lcdTiming2.cpl * height); DPRINTF(PL111, "DMA Done\n");
Tick maxFrameTime = lcdTiming2.cpl * height * pixelClock;
--dmaPendingNum; --dmaPendingNum;
if (maxAddr == curAddr && !dmaPendingNum) { if (maxAddr == curAddr && !dmaPendingNum) {
if ((curCycle() - startTime) > maxFrameTime) { if ((curTick() - startTime) > maxFrameTime) {
warn("CLCD controller buffer underrun, took %d cycles when should" warn("CLCD controller buffer underrun, took %d ticks when should"
" have taken %d\n", curTick() - startTime, maxFrameTime); " have taken %d\n", curTick() - startTime, maxFrameTime);
lcdRis.underflow = 1; lcdRis.underflow = 1;
if (!intEvent.scheduled()) if (!intEvent.scheduled())
@ -500,14 +501,11 @@ Pl111::dmaDone()
// schedule the next read based on when the last frame started // schedule the next read based on when the last frame started
// and the desired fps (i.e. maxFrameTime), we turn the // and the desired fps (i.e. maxFrameTime), we turn the
// argument into a relative number of cycles in the future by // argument into a relative number of cycles in the future
// subtracting curCycle()
if (lcdControl.lcden) if (lcdControl.lcden)
// @todo: This is a terrible way of doing the time schedule(readEvent, clockEdge(ticksToCycles(startTime -
// keeping, make it all relative curTick() +
schedule(readEvent, maxFrameTime)));
clockEdge(Cycles(startTime - curCycle() +
maxFrameTime)));
} }
if (dmaPendingNum > (maxOutstandingDma - waterMark)) if (dmaPendingNum > (maxOutstandingDma - waterMark))

View file

@ -227,6 +227,9 @@ class Pl111: public AmbaDmaDevice
/** Cursor masked interrupt status register - const */ /** Cursor masked interrupt status register - const */
InterruptReg clcdCrsrMis; InterruptReg clcdCrsrMis;
/** Pixel clock */
Tick pixelClock;
/** VNC server */ /** VNC server */
VncInput *vnc; VncInput *vnc;