pl111.cc revision 9648
11060SN/A/*
212107SRekai.GonzalezAlberquilla@arm.com * Copyright (c) 2010-2012 ARM Limited
39920Syasuko.eckert@amd.com * All rights reserved
47944SGiacomo.Gabrielli@arm.com *
57944SGiacomo.Gabrielli@arm.com * The license below extends only to copyright in the software and shall
67944SGiacomo.Gabrielli@arm.com * not be construed as granting a license to any other intellectual
77944SGiacomo.Gabrielli@arm.com * property including but not limited to intellectual property relating
87944SGiacomo.Gabrielli@arm.com * to a hardware implementation of the functionality of the software
97944SGiacomo.Gabrielli@arm.com * licensed hereunder.  You may use the software subject to the license
107944SGiacomo.Gabrielli@arm.com * terms below provided that you ensure that this notice is replicated
117944SGiacomo.Gabrielli@arm.com * unmodified and in its entirety in all distributions of the software,
127944SGiacomo.Gabrielli@arm.com * modified or unmodified, in source code or in binary form.
137944SGiacomo.Gabrielli@arm.com *
147944SGiacomo.Gabrielli@arm.com * Redistribution and use in source and binary forms, with or without
152702Sktlim@umich.edu * modification, are permitted provided that the following conditions are
166973Stjones1@inf.ed.ac.uk * met: redistributions of source code must retain the above copyright
171060SN/A * notice, this list of conditions and the following disclaimer;
181060SN/A * redistributions in binary form must reproduce the above copyright
191060SN/A * notice, this list of conditions and the following disclaimer in the
201060SN/A * documentation and/or other materials provided with the distribution;
211060SN/A * neither the name of the copyright holders nor the names of its
221060SN/A * contributors may be used to endorse or promote products derived from
231060SN/A * this software without specific prior written permission.
241060SN/A *
251060SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
261060SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
271060SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
281060SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
291060SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
301060SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
311060SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
321060SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
331060SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
341060SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
351060SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
361060SN/A *
371060SN/A * Authors: William Wang
381060SN/A *          Ali Saidi
391060SN/A */
401060SN/A
412665Ssaidi@eecs.umich.edu#include "base/vnc/vncinput.hh"
422665Ssaidi@eecs.umich.edu#include "base/bitmap.hh"
436973Stjones1@inf.ed.ac.uk#include "base/output.hh"
441060SN/A#include "base/trace.hh"
451060SN/A#include "debug/PL111.hh"
461464SN/A#include "debug/Uart.hh"
471464SN/A#include "dev/arm/amba_device.hh"
481060SN/A#include "dev/arm/base_gic.hh"
4910835Sandreas.hansson@arm.com#include "dev/arm/pl111.hh"
502731Sktlim@umich.edu#include "mem/packet.hh"
5112109SRekai.GonzalezAlberquilla@arm.com#include "mem/packet_access.hh"
522292SN/A#include "sim/system.hh"
531464SN/A
541060SN/A// clang complains about std::set being overloaded with Packet::set if
5510687SAndreas.Sandberg@ARM.com// we open up the entire namespace std
567720Sgblack@eecs.umich.eduusing std::vector;
571060SN/A
586658Snate@binkert.orgusing namespace AmbaDev;
598887Sgeoffrey.blake@arm.com
6010319SAndreas.Sandberg@ARM.com// initialize clcd registers
611464SN/APl111::Pl111(const Params *p)
6212107SRekai.GonzalezAlberquilla@arm.com    : AmbaDmaDevice(p), lcdTiming0(0), lcdTiming1(0), lcdTiming2(0),
631464SN/A      lcdTiming3(0), lcdUpbase(0), lcdLpbase(0), lcdControl(0), lcdImsc(0),
6412107SRekai.GonzalezAlberquilla@arm.com      lcdRis(0), lcdMis(0),
652669Sktlim@umich.edu      clcdCrsrCtrl(0), clcdCrsrConfig(0), clcdCrsrPalette0(0),
661060SN/A      clcdCrsrPalette1(0), clcdCrsrXY(0), clcdCrsrClip(0), clcdCrsrImsc(0),
676973Stjones1@inf.ed.ac.uk      clcdCrsrIcr(0), clcdCrsrRis(0), clcdCrsrMis(0),
682669Sktlim@umich.edu      pixelClock(p->pixel_clock), vnc(p->vnc), bmp(NULL), pic(NULL),
6911608Snikos.nikoleris@arm.com      width(LcdMaxWidth), height(LcdMaxHeight),
707678Sgblack@eecs.umich.edu      bytesPerPixel(4), startTime(0), startAddr(0), maxAddr(0), curAddr(0),
712292SN/A      waterMark(0), dmaPendingNum(0), readEvent(this), fillFifoEvent(this),
721060SN/A      dmaDoneEventAll(maxOutstandingDma, this),
731060SN/A      dmaDoneEventFree(maxOutstandingDma),
741060SN/A      intEvent(this)
751060SN/A{
761060SN/A    pioSize = 0xFFFF;
771060SN/A
781060SN/A    dmaBuffer = new uint8_t[buffer_size];
7910319SAndreas.Sandberg@ARM.com
801060SN/A    memset(lcdPalette, 0, sizeof(lcdPalette));
811060SN/A    memset(cursorImage, 0, sizeof(cursorImage));
821060SN/A    memset(dmaBuffer, 0, buffer_size);
832733Sktlim@umich.edu
842733Sktlim@umich.edu    for (int i = 0; i < maxOutstandingDma; ++i)
8512109SRekai.GonzalezAlberquilla@arm.com        dmaDoneEventFree[i] = &dmaDoneEventAll[i];
861060SN/A
872292SN/A    if (vnc)
882292SN/A        vnc->setFramebufferAddr(dmaBuffer);
898486Sgblack@eecs.umich.edu}
902292SN/A
912292SN/APl111::~Pl111()
922292SN/A{
932292SN/A    delete[] dmaBuffer;
941060SN/A}
955543Ssaidi@eecs.umich.edu
968902Sandreas.hansson@arm.com// read registers and frame buffer
971060SN/ATick
981060SN/APl111::read(PacketPtr pkt)
999046SAli.Saidi@ARM.com{
1009046SAli.Saidi@ARM.com    // use a temporary data since the LCD registers are read/written with
1019046SAli.Saidi@ARM.com    // different size operations
1029046SAli.Saidi@ARM.com
1039046SAli.Saidi@ARM.com    uint32_t data = 0;
1049046SAli.Saidi@ARM.com
1059046SAli.Saidi@ARM.com    assert(pkt->getAddr() >= pioAddr &&
1069046SAli.Saidi@ARM.com           pkt->getAddr() < pioAddr + pioSize);
1079046SAli.Saidi@ARM.com
1089046SAli.Saidi@ARM.com    Addr daddr = pkt->getAddr() - pioAddr;
1099046SAli.Saidi@ARM.com    pkt->allocate();
1109046SAli.Saidi@ARM.com
1119046SAli.Saidi@ARM.com    DPRINTF(PL111, " read register %#x size=%d\n", daddr, pkt->getSize());
1129046SAli.Saidi@ARM.com
1139046SAli.Saidi@ARM.com    switch (daddr) {
1149046SAli.Saidi@ARM.com      case LcdTiming0:
1159046SAli.Saidi@ARM.com        data = lcdTiming0;
1169046SAli.Saidi@ARM.com        break;
1179046SAli.Saidi@ARM.com      case LcdTiming1:
1189046SAli.Saidi@ARM.com        data = lcdTiming1;
1199046SAli.Saidi@ARM.com        break;
1209046SAli.Saidi@ARM.com      case LcdTiming2:
1219046SAli.Saidi@ARM.com        data = lcdTiming2;
1229046SAli.Saidi@ARM.com        break;
1239046SAli.Saidi@ARM.com      case LcdTiming3:
1249046SAli.Saidi@ARM.com        data = lcdTiming3;
1259046SAli.Saidi@ARM.com        break;
1269046SAli.Saidi@ARM.com      case LcdUpBase:
12712421Sgabeblack@google.com        data = lcdUpbase;
1289046SAli.Saidi@ARM.com        break;
1299046SAli.Saidi@ARM.com      case LcdLpBase:
1309046SAli.Saidi@ARM.com        data = lcdLpbase;
1319046SAli.Saidi@ARM.com        break;
1329046SAli.Saidi@ARM.com      case LcdControl:
1339046SAli.Saidi@ARM.com        data = lcdControl;
1349046SAli.Saidi@ARM.com        break;
1359046SAli.Saidi@ARM.com      case LcdImsc:
13610824SAndreas.Sandberg@ARM.com        data = lcdImsc;
1379046SAli.Saidi@ARM.com        break;
1389046SAli.Saidi@ARM.com      case LcdRis:
1399046SAli.Saidi@ARM.com        data = lcdRis;
1409046SAli.Saidi@ARM.com        break;
1419046SAli.Saidi@ARM.com      case LcdMis:
1429046SAli.Saidi@ARM.com        data = lcdMis;
1439046SAli.Saidi@ARM.com        break;
1449046SAli.Saidi@ARM.com      case LcdIcr:
1459046SAli.Saidi@ARM.com        panic("LCD register at offset %#x is Write-Only\n", daddr);
1462292SN/A        break;
14710417Sandreas.hansson@arm.com      case LcdUpCurr:
1489046SAli.Saidi@ARM.com        data = curAddr;
1499046SAli.Saidi@ARM.com        break;
1509046SAli.Saidi@ARM.com      case LcdLpCurr:
1519046SAli.Saidi@ARM.com        data = curAddr;
15210030SAli.Saidi@ARM.com        break;
15310030SAli.Saidi@ARM.com      case ClcdCrsrCtrl:
1549046SAli.Saidi@ARM.com        data = clcdCrsrCtrl;
1559046SAli.Saidi@ARM.com        break;
1569046SAli.Saidi@ARM.com      case ClcdCrsrConfig:
1579046SAli.Saidi@ARM.com        data = clcdCrsrConfig;
1589046SAli.Saidi@ARM.com        break;
1599046SAli.Saidi@ARM.com      case ClcdCrsrPalette0:
1609046SAli.Saidi@ARM.com        data = clcdCrsrPalette0;
1619046SAli.Saidi@ARM.com        break;
1629046SAli.Saidi@ARM.com      case ClcdCrsrPalette1:
1639046SAli.Saidi@ARM.com        data = clcdCrsrPalette1;
1649046SAli.Saidi@ARM.com        break;
1659046SAli.Saidi@ARM.com      case ClcdCrsrXY:
1669046SAli.Saidi@ARM.com        data = clcdCrsrXY;
16712107SRekai.GonzalezAlberquilla@arm.com        break;
1689046SAli.Saidi@ARM.com      case ClcdCrsrClip:
1699046SAli.Saidi@ARM.com        data = clcdCrsrClip;
1709046SAli.Saidi@ARM.com        break;
1719046SAli.Saidi@ARM.com      case ClcdCrsrImsc:
1729046SAli.Saidi@ARM.com        data = clcdCrsrImsc;
1739046SAli.Saidi@ARM.com        break;
1749046SAli.Saidi@ARM.com      case ClcdCrsrIcr:
1759046SAli.Saidi@ARM.com        panic("CLCD register at offset %#x is Write-Only\n", daddr);
1769046SAli.Saidi@ARM.com        break;
1779046SAli.Saidi@ARM.com      case ClcdCrsrRis:
1789046SAli.Saidi@ARM.com        data = clcdCrsrRis;
1799046SAli.Saidi@ARM.com        break;
1809046SAli.Saidi@ARM.com      case ClcdCrsrMis:
1819046SAli.Saidi@ARM.com        data = clcdCrsrMis;
1829046SAli.Saidi@ARM.com        break;
1839046SAli.Saidi@ARM.com      default:
1849046SAli.Saidi@ARM.com        if (AmbaDev::readId(pkt, AMBA_ID, pioAddr)) {
1859046SAli.Saidi@ARM.com            // Hack for variable size accesses
1869046SAli.Saidi@ARM.com            data = pkt->get<uint32_t>();
1879046SAli.Saidi@ARM.com            break;
1889046SAli.Saidi@ARM.com        } else if (daddr >= CrsrImage && daddr <= 0xBFC) {
1899046SAli.Saidi@ARM.com            // CURSOR IMAGE
1909046SAli.Saidi@ARM.com            int index;
1919046SAli.Saidi@ARM.com            index = (daddr - CrsrImage) >> 2;
1929046SAli.Saidi@ARM.com            data= cursorImage[index];
1939046SAli.Saidi@ARM.com            break;
1949046SAli.Saidi@ARM.com        } else if (daddr >= LcdPalette && daddr <= 0x3FC) {
19510417Sandreas.hansson@arm.com            // LCD Palette
1961060SN/A            int index;
1979046SAli.Saidi@ARM.com            index = (daddr - LcdPalette) >> 2;
1989046SAli.Saidi@ARM.com            data = lcdPalette[index];
1999046SAli.Saidi@ARM.com            break;
2009046SAli.Saidi@ARM.com        } else {
2019046SAli.Saidi@ARM.com            panic("Tried to read CLCD register at offset %#x that \
2029046SAli.Saidi@ARM.com                       doesn't exist\n", daddr);
2039046SAli.Saidi@ARM.com            break;
2049046SAli.Saidi@ARM.com        }
2059046SAli.Saidi@ARM.com    }
20611097Songal@cs.wisc.edu
20711097Songal@cs.wisc.edu    switch(pkt->getSize()) {
20811097Songal@cs.wisc.edu      case 1:
20911097Songal@cs.wisc.edu        pkt->set<uint8_t>(data);
21011097Songal@cs.wisc.edu        break;
21111097Songal@cs.wisc.edu      case 2:
2129046SAli.Saidi@ARM.com        pkt->set<uint16_t>(data);
2139046SAli.Saidi@ARM.com        break;
2149046SAli.Saidi@ARM.com      case 4:
2159046SAli.Saidi@ARM.com        pkt->set<uint32_t>(data);
2169046SAli.Saidi@ARM.com        break;
2179046SAli.Saidi@ARM.com      default:
2189046SAli.Saidi@ARM.com        panic("CLCD controller read size too big?\n");
2199046SAli.Saidi@ARM.com        break;
2209046SAli.Saidi@ARM.com    }
2219046SAli.Saidi@ARM.com
2229046SAli.Saidi@ARM.com    pkt->makeAtomicResponse();
2239046SAli.Saidi@ARM.com    return pioDelay;
2249046SAli.Saidi@ARM.com}
2259046SAli.Saidi@ARM.com
2269046SAli.Saidi@ARM.com// write registers and frame buffer
2279046SAli.Saidi@ARM.comTick
2289046SAli.Saidi@ARM.comPl111::write(PacketPtr pkt)
2299046SAli.Saidi@ARM.com{
2309046SAli.Saidi@ARM.com    // use a temporary data since the LCD registers are read/written with
2319046SAli.Saidi@ARM.com    // different size operations
2329046SAli.Saidi@ARM.com    //
2339046SAli.Saidi@ARM.com    uint32_t data = 0;
2349046SAli.Saidi@ARM.com
2359046SAli.Saidi@ARM.com    switch(pkt->getSize()) {
2369046SAli.Saidi@ARM.com      case 1:
2379046SAli.Saidi@ARM.com        data = pkt->get<uint8_t>();
2389046SAli.Saidi@ARM.com        break;
2399046SAli.Saidi@ARM.com      case 2:
2409046SAli.Saidi@ARM.com        data = pkt->get<uint16_t>();
2419046SAli.Saidi@ARM.com        break;
2429046SAli.Saidi@ARM.com      case 4:
2439046SAli.Saidi@ARM.com        data = pkt->get<uint32_t>();
2449046SAli.Saidi@ARM.com        break;
2459046SAli.Saidi@ARM.com      default:
2469046SAli.Saidi@ARM.com        panic("PL111 CLCD controller write size too big?\n");
2479046SAli.Saidi@ARM.com        break;
2489046SAli.Saidi@ARM.com    }
24912104Snathanael.premillieu@arm.com
2509046SAli.Saidi@ARM.com    assert(pkt->getAddr() >= pioAddr &&
2519046SAli.Saidi@ARM.com           pkt->getAddr() < pioAddr + pioSize);
2529046SAli.Saidi@ARM.com
2539046SAli.Saidi@ARM.com    Addr daddr = pkt->getAddr() - pioAddr;
25412105Snathanael.premillieu@arm.com
2559046SAli.Saidi@ARM.com    DPRINTF(PL111, " write register %#x value %#x size=%d\n", daddr,
2569046SAli.Saidi@ARM.com            pkt->get<uint8_t>(), pkt->getSize());
2579046SAli.Saidi@ARM.com
2589046SAli.Saidi@ARM.com    switch (daddr) {
25912105Snathanael.premillieu@arm.com      case LcdTiming0:
2609046SAli.Saidi@ARM.com        lcdTiming0 = data;
2619046SAli.Saidi@ARM.com        // width = 16 * (PPL+1)
2629046SAli.Saidi@ARM.com        width = (lcdTiming0.ppl + 1) << 4;
2639046SAli.Saidi@ARM.com        break;
26412105Snathanael.premillieu@arm.com      case LcdTiming1:
2659046SAli.Saidi@ARM.com        lcdTiming1 = data;
2669046SAli.Saidi@ARM.com        // height = LPP + 1
2679046SAli.Saidi@ARM.com        height = (lcdTiming1.lpp) + 1;
2689046SAli.Saidi@ARM.com        break;
2699046SAli.Saidi@ARM.com      case LcdTiming2:
2709046SAli.Saidi@ARM.com        lcdTiming2 = data;
2719046SAli.Saidi@ARM.com        break;
2729046SAli.Saidi@ARM.com      case LcdTiming3:
2739046SAli.Saidi@ARM.com        lcdTiming3 = data;
2749046SAli.Saidi@ARM.com        break;
2759046SAli.Saidi@ARM.com      case LcdUpBase:
2769046SAli.Saidi@ARM.com        lcdUpbase = data;
2779046SAli.Saidi@ARM.com        DPRINTF(PL111, "####### Upper panel base set to: %#x #######\n", lcdUpbase);
27812421Sgabeblack@google.com        break;
27912421Sgabeblack@google.com      case LcdLpBase:
28012421Sgabeblack@google.com        warn_once("LCD dual screen mode not supported\n");
2819046SAli.Saidi@ARM.com        lcdLpbase = data;
2821060SN/A        DPRINTF(PL111, "###### Lower panel base set to: %#x #######\n", lcdLpbase);
2831060SN/A        break;
2841060SN/A      case LcdControl:
2851060SN/A        int old_lcdpwr;
2861060SN/A        old_lcdpwr = lcdControl.lcdpwr;
2871060SN/A        lcdControl = data;
2885358Sgblack@eecs.umich.edu
2895358Sgblack@eecs.umich.edu        DPRINTF(PL111, "LCD power is:%d\n", lcdControl.lcdpwr);
2905358Sgblack@eecs.umich.edu
2915358Sgblack@eecs.umich.edu        // LCD power enable
2925358Sgblack@eecs.umich.edu        if (lcdControl.lcdpwr && !old_lcdpwr) {
2935358Sgblack@eecs.umich.edu            updateVideoParams();
2945358Sgblack@eecs.umich.edu            DPRINTF(PL111, " lcd size: height %d width %d\n", height, width);
2955358Sgblack@eecs.umich.edu            waterMark = lcdControl.watermark ? 8 : 4;
2965358Sgblack@eecs.umich.edu            startDma();
2975358Sgblack@eecs.umich.edu        }
2985358Sgblack@eecs.umich.edu        break;
2995358Sgblack@eecs.umich.edu      case LcdImsc:
3005358Sgblack@eecs.umich.edu        lcdImsc = data;
30111608Snikos.nikoleris@arm.com        if (lcdImsc.vcomp)
3027520Sgblack@eecs.umich.edu            panic("Interrupting on vcomp not supported\n");
30311608Snikos.nikoleris@arm.com
30411608Snikos.nikoleris@arm.com        lcdMis = lcdImsc & lcdRis;
3057520Sgblack@eecs.umich.edu
3066974Stjones1@inf.ed.ac.uk        if (!lcdMis)
3076974Stjones1@inf.ed.ac.uk            gic->clearInt(intNum);
3086974Stjones1@inf.ed.ac.uk
3096974Stjones1@inf.ed.ac.uk         break;
3106973Stjones1@inf.ed.ac.uk      case LcdRis:
3116974Stjones1@inf.ed.ac.uk        panic("LCD register at offset %#x is Read-Only\n", daddr);
3126974Stjones1@inf.ed.ac.uk        break;
3136973Stjones1@inf.ed.ac.uk      case LcdMis:
3146973Stjones1@inf.ed.ac.uk        panic("LCD register at offset %#x is Read-Only\n", daddr);
3156973Stjones1@inf.ed.ac.uk        break;
3166973Stjones1@inf.ed.ac.uk      case LcdIcr:
3171060SN/A        lcdRis = lcdRis & ~data;
3187944SGiacomo.Gabrielli@arm.com        lcdMis = lcdImsc & lcdRis;
3199046SAli.Saidi@ARM.com
3209046SAli.Saidi@ARM.com        if (!lcdMis)
3217944SGiacomo.Gabrielli@arm.com            gic->clearInt(intNum);
3227944SGiacomo.Gabrielli@arm.com
3239046SAli.Saidi@ARM.com        break;
3249046SAli.Saidi@ARM.com      case LcdUpCurr:
3257944SGiacomo.Gabrielli@arm.com        panic("LCD register at offset %#x is Read-Only\n", daddr);
3268545Ssaidi@eecs.umich.edu        break;
3278545Ssaidi@eecs.umich.edu      case LcdLpCurr:
3288545Ssaidi@eecs.umich.edu        panic("LCD register at offset %#x is Read-Only\n", daddr);
3298545Ssaidi@eecs.umich.edu        break;
3308545Ssaidi@eecs.umich.edu      case ClcdCrsrCtrl:
3319046SAli.Saidi@ARM.com        clcdCrsrCtrl = data;
3329046SAli.Saidi@ARM.com        break;
3338545Ssaidi@eecs.umich.edu      case ClcdCrsrConfig:
3348545Ssaidi@eecs.umich.edu        clcdCrsrConfig = data;
3358545Ssaidi@eecs.umich.edu        break;
3368545Ssaidi@eecs.umich.edu      case ClcdCrsrPalette0:
3378545Ssaidi@eecs.umich.edu        clcdCrsrPalette0 = data;
3389046SAli.Saidi@ARM.com        break;
3399046SAli.Saidi@ARM.com      case ClcdCrsrPalette1:
3408545Ssaidi@eecs.umich.edu        clcdCrsrPalette1 = data;
3417944SGiacomo.Gabrielli@arm.com        break;
3427944SGiacomo.Gabrielli@arm.com      case ClcdCrsrXY:
3437944SGiacomo.Gabrielli@arm.com        clcdCrsrXY = data;
3447944SGiacomo.Gabrielli@arm.com        break;
3457944SGiacomo.Gabrielli@arm.com      case ClcdCrsrClip:
3467944SGiacomo.Gabrielli@arm.com        clcdCrsrClip = data;
3479046SAli.Saidi@ARM.com        break;
3487944SGiacomo.Gabrielli@arm.com      case ClcdCrsrImsc:
3497944SGiacomo.Gabrielli@arm.com        clcdCrsrImsc = data;
3501060SN/A        break;
3512292SN/A      case ClcdCrsrIcr:
3522292SN/A        clcdCrsrIcr = data;
3532292SN/A        break;
3542292SN/A      case ClcdCrsrRis:
3553770Sgblack@eecs.umich.edu        panic("CLCD register at offset %#x is Read-Only\n", daddr);
3563770Sgblack@eecs.umich.edu        break;
3573770Sgblack@eecs.umich.edu      case ClcdCrsrMis:
35812105Snathanael.premillieu@arm.com        panic("CLCD register at offset %#x is Read-Only\n", daddr);
3593770Sgblack@eecs.umich.edu        break;
3603770Sgblack@eecs.umich.edu      default:
3613770Sgblack@eecs.umich.edu        if (daddr >= CrsrImage && daddr <= 0xBFC) {
3623770Sgblack@eecs.umich.edu            // CURSOR IMAGE
3633770Sgblack@eecs.umich.edu            int index;
36412105Snathanael.premillieu@arm.com            index = (daddr - CrsrImage) >> 2;
3653770Sgblack@eecs.umich.edu            cursorImage[index] = data;
3669046SAli.Saidi@ARM.com            break;
3673770Sgblack@eecs.umich.edu        } else if (daddr >= LcdPalette && daddr <= 0x3FC) {
3683770Sgblack@eecs.umich.edu            // LCD Palette
3693770Sgblack@eecs.umich.edu            int index;
3703770Sgblack@eecs.umich.edu            index = (daddr - LcdPalette) >> 2;
3713770Sgblack@eecs.umich.edu            lcdPalette[index] = data;
3723770Sgblack@eecs.umich.edu            break;
37312106SRekai.GonzalezAlberquilla@arm.com        } else {
3743770Sgblack@eecs.umich.edu            panic("Tried to write PL111 register at offset %#x that \
3753770Sgblack@eecs.umich.edu                       doesn't exist\n", daddr);
3763770Sgblack@eecs.umich.edu            break;
3773770Sgblack@eecs.umich.edu        }
3783770Sgblack@eecs.umich.edu    }
3793770Sgblack@eecs.umich.edu
3803770Sgblack@eecs.umich.edu    pkt->makeAtomicResponse();
38112105Snathanael.premillieu@arm.com    return pioDelay;
3823770Sgblack@eecs.umich.edu}
3833770Sgblack@eecs.umich.edu
3843770Sgblack@eecs.umich.eduvoid
3853770Sgblack@eecs.umich.eduPl111::updateVideoParams()
3863770Sgblack@eecs.umich.edu{
3873770Sgblack@eecs.umich.edu        if (lcdControl.lcdbpp == bpp24) {
3883770Sgblack@eecs.umich.edu            bytesPerPixel = 4;
3893770Sgblack@eecs.umich.edu        } else if (lcdControl.lcdbpp == bpp16m565) {
39012105Snathanael.premillieu@arm.com            bytesPerPixel = 2;
39112105Snathanael.premillieu@arm.com        }
3923770Sgblack@eecs.umich.edu
3933770Sgblack@eecs.umich.edu        if (vnc) {
3943770Sgblack@eecs.umich.edu            if (lcdControl.lcdbpp == bpp24 && lcdControl.bgr)
3953770Sgblack@eecs.umich.edu                vnc->setFrameBufferParams(VideoConvert::bgr8888, width,
3963770Sgblack@eecs.umich.edu                       height);
3973770Sgblack@eecs.umich.edu            else if (lcdControl.lcdbpp == bpp24 && !lcdControl.bgr)
3983770Sgblack@eecs.umich.edu                vnc->setFrameBufferParams(VideoConvert::rgb8888, width,
3993770Sgblack@eecs.umich.edu                       height);
4003770Sgblack@eecs.umich.edu            else if (lcdControl.lcdbpp == bpp16m565 && lcdControl.bgr)
40112105Snathanael.premillieu@arm.com                vnc->setFrameBufferParams(VideoConvert::bgr565, width,
4023770Sgblack@eecs.umich.edu                       height);
4033770Sgblack@eecs.umich.edu            else if (lcdControl.lcdbpp == bpp16m565 && !lcdControl.bgr)
4043770Sgblack@eecs.umich.edu                vnc->setFrameBufferParams(VideoConvert::rgb565, width,
4053770Sgblack@eecs.umich.edu                       height);
4063770Sgblack@eecs.umich.edu            else
4073770Sgblack@eecs.umich.edu                panic("Unimplemented video mode\n");
4083770Sgblack@eecs.umich.edu        }
40912106SRekai.GonzalezAlberquilla@arm.com
4103770Sgblack@eecs.umich.edu        if (bmp)
4113770Sgblack@eecs.umich.edu            delete bmp;
4123770Sgblack@eecs.umich.edu
4134636Sgblack@eecs.umich.edu        if (lcdControl.lcdbpp == bpp24 && lcdControl.bgr)
4144636Sgblack@eecs.umich.edu            bmp = new Bitmap(VideoConvert::bgr8888, width, height, dmaBuffer);
4157720Sgblack@eecs.umich.edu        else if (lcdControl.lcdbpp == bpp24 && !lcdControl.bgr)
4167720Sgblack@eecs.umich.edu            bmp = new Bitmap(VideoConvert::rgb8888, width, height, dmaBuffer);
4174636Sgblack@eecs.umich.edu        else if (lcdControl.lcdbpp == bpp16m565 && lcdControl.bgr)
4184636Sgblack@eecs.umich.edu            bmp = new Bitmap(VideoConvert::bgr565, width, height, dmaBuffer);
4194636Sgblack@eecs.umich.edu        else if (lcdControl.lcdbpp == bpp16m565 && !lcdControl.bgr)
42010417Sandreas.hansson@arm.com            bmp = new Bitmap(VideoConvert::rgb565, width, height, dmaBuffer);
4218502Sgblack@eecs.umich.edu        else
4228502Sgblack@eecs.umich.edu            panic("Unimplemented video mode\n");
4233770Sgblack@eecs.umich.edu}
4242292SN/A
4252292SN/Avoid
4262292SN/APl111::startDma()
42710417Sandreas.hansson@arm.com{
4281060SN/A    if (dmaPendingNum != 0 || readEvent.scheduled())
4291060SN/A        return;
4301060SN/A    readFramebuffer();
4311060SN/A}
4321464SN/A
4331684SN/Avoid
4341464SN/APl111::readFramebuffer()
4351060SN/A{
4361464SN/A    // initialization for dma read from frame buffer to dma buffer
4371060SN/A    uint32_t length = height * width;
4381060SN/A    if (startAddr != lcdUpbase)
4391060SN/A        startAddr = lcdUpbase;
4401060SN/A
4411060SN/A    // Updating base address, interrupt if we're supposed to
4421060SN/A    lcdRis.baseaddr = 1;
4433326Sktlim@umich.edu    if (!intEvent.scheduled())
44410110Sandreas.hansson@arm.com        schedule(intEvent, clockEdge());
4453326Sktlim@umich.edu
44610190Sakash.bagdia@arm.com    curAddr = 0;
44710190Sakash.bagdia@arm.com    startTime = curTick();
44810190Sakash.bagdia@arm.com
4498832SAli.Saidi@ARM.com    maxAddr = static_cast<Addr>(length * bytesPerPixel);
45010110Sandreas.hansson@arm.com
4518832SAli.Saidi@ARM.com    DPRINTF(PL111, " lcd frame buffer size of %d bytes \n", maxAddr);
4525714Shsul@eecs.umich.edu
45311005Sandreas.sandberg@arm.com    fillFifo();
4545714Shsul@eecs.umich.edu}
4551060SN/A
45610110Sandreas.hansson@arm.comvoid
4571060SN/APl111::fillFifo()
4581060SN/A{
4591060SN/A    while ((dmaPendingNum < maxOutstandingDma) && (maxAddr >= curAddr + dmaSize )) {
4601060SN/A        // concurrent dma reads need different dma done events
4612292SN/A        // due to assertion in scheduling state
4621060SN/A        ++dmaPendingNum;
4631060SN/A
4641060SN/A        assert(!dmaDoneEventFree.empty());
4657720Sgblack@eecs.umich.edu        DmaDoneEvent *event(dmaDoneEventFree.back());
4667720Sgblack@eecs.umich.edu        dmaDoneEventFree.pop_back();
4673965Sgblack@eecs.umich.edu        assert(!event->scheduled());
4687720Sgblack@eecs.umich.edu
4693965Sgblack@eecs.umich.edu        // We use a uncachable request here because the requests from the CPU
4702935Sksewell@umich.edu        // will be uncacheable as well. If we have uncacheable and cacheable
4717720Sgblack@eecs.umich.edu        // requests in the memory system for the same address it won't be
4721060SN/A        // pleased
4733794Sgblack@eecs.umich.edu        dmaPort.dmaAction(MemCmd::ReadReq, curAddr + startAddr, dmaSize,
4747720Sgblack@eecs.umich.edu                          event, curAddr + dmaBuffer,
4753794Sgblack@eecs.umich.edu                          0, Request::UNCACHEABLE);
4763794Sgblack@eecs.umich.edu        curAddr += dmaSize;
4777720Sgblack@eecs.umich.edu    }
4781060SN/A}
4794636Sgblack@eecs.umich.edu
4807720Sgblack@eecs.umich.eduvoid
4814636Sgblack@eecs.umich.eduPl111::dmaDone()
4821060SN/A{
4833794Sgblack@eecs.umich.edu    DPRINTF(PL111, "DMA Done\n");
4843794Sgblack@eecs.umich.edu
4859046SAli.Saidi@ARM.com    Tick maxFrameTime = lcdTiming2.cpl * height * pixelClock;
4863794Sgblack@eecs.umich.edu
4873794Sgblack@eecs.umich.edu    --dmaPendingNum;
4883794Sgblack@eecs.umich.edu
4893794Sgblack@eecs.umich.edu    if (maxAddr == curAddr && !dmaPendingNum) {
4909046SAli.Saidi@ARM.com        if ((curTick() - startTime) > maxFrameTime) {
4913794Sgblack@eecs.umich.edu            warn("CLCD controller buffer underrun, took %d ticks when should"
4921060SN/A                 " have taken %d\n", curTick() - startTime, maxFrameTime);
4931060SN/A            lcdRis.underflow = 1;
4942935Sksewell@umich.edu            if (!intEvent.scheduled())
4953794Sgblack@eecs.umich.edu                schedule(intEvent, clockEdge());
4967720Sgblack@eecs.umich.edu        }
4977720Sgblack@eecs.umich.edu
4987720Sgblack@eecs.umich.edu        assert(!readEvent.scheduled());
4993794Sgblack@eecs.umich.edu        if (vnc)
5003794Sgblack@eecs.umich.edu            vnc->setDirty();
5011060SN/A
5021060SN/A        DPRINTF(PL111, "-- write out frame buffer into bmp\n");
5031060SN/A
5045543Ssaidi@eecs.umich.edu        if (!pic)
5055543Ssaidi@eecs.umich.edu            pic = simout.create(csprintf("%s.framebuffer.bmp", sys->name()), true);
5065543Ssaidi@eecs.umich.edu
5075543Ssaidi@eecs.umich.edu        assert(bmp);
5082336SN/A        assert(pic);
5092336SN/A        pic->seekp(0);
5101060SN/A        bmp->write(pic);
5111060SN/A
5125543Ssaidi@eecs.umich.edu        // schedule the next read based on when the last frame started
5135543Ssaidi@eecs.umich.edu        // and the desired fps (i.e. maxFrameTime), we turn the
51412110SRekai.GonzalezAlberquilla@arm.com        // argument into a relative number of cycles in the future
5155543Ssaidi@eecs.umich.edu        if (lcdControl.lcden)
5165543Ssaidi@eecs.umich.edu            schedule(readEvent, clockEdge(ticksToCycles(startTime -
5175543Ssaidi@eecs.umich.edu                                                        curTick() +
5185543Ssaidi@eecs.umich.edu                                                        maxFrameTime)));
5191060SN/A    }
5205543Ssaidi@eecs.umich.edu
5215543Ssaidi@eecs.umich.edu    if (dmaPendingNum > (maxOutstandingDma - waterMark))
5222935Sksewell@umich.edu        return;
5231060SN/A
5241060SN/A    if (!fillFifoEvent.scheduled())
5252292SN/A        schedule(fillFifoEvent, clockEdge());
5262731Sktlim@umich.edu}
5272292SN/A
5282731Sktlim@umich.eduvoid
5297784SAli.Saidi@ARM.comPl111::serialize(std::ostream &os)
5301060SN/A{
5311060SN/A    DPRINTF(PL111, "Serializing ARM PL111\n");
5321060SN/A
5332292SN/A    uint32_t lcdTiming0_serial = lcdTiming0;
5342336SN/A    SERIALIZE_SCALAR(lcdTiming0_serial);
5352308SN/A
5364828Sgblack@eecs.umich.edu    uint32_t lcdTiming1_serial = lcdTiming1;
5374654Sgblack@eecs.umich.edu    SERIALIZE_SCALAR(lcdTiming1_serial);
5384654Sgblack@eecs.umich.edu
5394636Sgblack@eecs.umich.edu    uint32_t lcdTiming2_serial = lcdTiming2;
5404654Sgblack@eecs.umich.edu    SERIALIZE_SCALAR(lcdTiming2_serial);
5414654Sgblack@eecs.umich.edu
5424636Sgblack@eecs.umich.edu    uint32_t lcdTiming3_serial = lcdTiming3;
5432292SN/A    SERIALIZE_SCALAR(lcdTiming3_serial);
5442292SN/A
5452731Sktlim@umich.edu    SERIALIZE_SCALAR(lcdUpbase);
5462292SN/A    SERIALIZE_SCALAR(lcdLpbase);
5472292SN/A
5482731Sktlim@umich.edu    uint32_t lcdControl_serial = lcdControl;
5492292SN/A    SERIALIZE_SCALAR(lcdControl_serial);
5502292SN/A
5512731Sktlim@umich.edu    uint8_t lcdImsc_serial = lcdImsc;
5522292SN/A    SERIALIZE_SCALAR(lcdImsc_serial);
5532292SN/A
5542731Sktlim@umich.edu    uint8_t lcdRis_serial = lcdRis;
5552292SN/A    SERIALIZE_SCALAR(lcdRis_serial);
5562292SN/A
5572731Sktlim@umich.edu    uint8_t lcdMis_serial = lcdMis;
5582292SN/A    SERIALIZE_SCALAR(lcdMis_serial);
5592292SN/A
5602731Sktlim@umich.edu    SERIALIZE_ARRAY(lcdPalette, LcdPaletteSize);
5612292SN/A    SERIALIZE_ARRAY(cursorImage, CrsrImageSize);
5622731Sktlim@umich.edu
5632731Sktlim@umich.edu    SERIALIZE_SCALAR(clcdCrsrCtrl);
5642292SN/A    SERIALIZE_SCALAR(clcdCrsrConfig);
5652292SN/A    SERIALIZE_SCALAR(clcdCrsrPalette0);
5662292SN/A    SERIALIZE_SCALAR(clcdCrsrPalette1);
5672292SN/A    SERIALIZE_SCALAR(clcdCrsrXY);
5682292SN/A    SERIALIZE_SCALAR(clcdCrsrClip);
5692292SN/A
5702731Sktlim@umich.edu    uint8_t clcdCrsrImsc_serial = clcdCrsrImsc;
5711060SN/A    SERIALIZE_SCALAR(clcdCrsrImsc_serial);
5721464SN/A
5731464SN/A    uint8_t clcdCrsrIcr_serial = clcdCrsrIcr;
5741464SN/A    SERIALIZE_SCALAR(clcdCrsrIcr_serial);
5751464SN/A
5767720Sgblack@eecs.umich.edu    uint8_t clcdCrsrRis_serial = clcdCrsrRis;
5777720Sgblack@eecs.umich.edu    SERIALIZE_SCALAR(clcdCrsrRis_serial);
5781464SN/A
5792292SN/A    uint8_t clcdCrsrMis_serial = clcdCrsrMis;
5805543Ssaidi@eecs.umich.edu    SERIALIZE_SCALAR(clcdCrsrMis_serial);
5811684SN/A
5822292SN/A    SERIALIZE_SCALAR(height);
5831060SN/A    SERIALIZE_SCALAR(width);
5841060SN/A    SERIALIZE_SCALAR(bytesPerPixel);
5851060SN/A
5861060SN/A    SERIALIZE_ARRAY(dmaBuffer, buffer_size);
5871060SN/A    SERIALIZE_SCALAR(startTime);
5881060SN/A    SERIALIZE_SCALAR(startAddr);
58910715SRekai.GonzalezAlberquilla@arm.com    SERIALIZE_SCALAR(maxAddr);
59012109SRekai.GonzalezAlberquilla@arm.com    SERIALIZE_SCALAR(curAddr);
59112109SRekai.GonzalezAlberquilla@arm.com    SERIALIZE_SCALAR(waterMark);
59212109SRekai.GonzalezAlberquilla@arm.com    SERIALIZE_SCALAR(dmaPendingNum);
59312109SRekai.GonzalezAlberquilla@arm.com
5941060SN/A    Tick int_event_time = 0;
5951060SN/A    Tick read_event_time = 0;
59612106SRekai.GonzalezAlberquilla@arm.com    Tick fill_fifo_event_time = 0;
5971060SN/A
5981060SN/A    if (readEvent.scheduled())
59912106SRekai.GonzalezAlberquilla@arm.com        read_event_time = readEvent.when();
6001060SN/A    if (fillFifoEvent.scheduled())
60112107SRekai.GonzalezAlberquilla@arm.com        fill_fifo_event_time = fillFifoEvent.when();
60212107SRekai.GonzalezAlberquilla@arm.com    if (intEvent.scheduled())
60312107SRekai.GonzalezAlberquilla@arm.com        int_event_time = intEvent.when();
60412107SRekai.GonzalezAlberquilla@arm.com
60512107SRekai.GonzalezAlberquilla@arm.com    SERIALIZE_SCALAR(read_event_time);
60612107SRekai.GonzalezAlberquilla@arm.com    SERIALIZE_SCALAR(fill_fifo_event_time);
60712107SRekai.GonzalezAlberquilla@arm.com    SERIALIZE_SCALAR(int_event_time);
6088733Sgeoffrey.blake@arm.com
6098733Sgeoffrey.blake@arm.com    vector<Tick> dma_done_event_tick;
61012107SRekai.GonzalezAlberquilla@arm.com    dma_done_event_tick.resize(maxOutstandingDma);
6118733Sgeoffrey.blake@arm.com    for (int x = 0; x < maxOutstandingDma; x++) {
61212107SRekai.GonzalezAlberquilla@arm.com        dma_done_event_tick[x] = dmaDoneEventAll[x].scheduled() ?
6138733Sgeoffrey.blake@arm.com            dmaDoneEventAll[x].when() : 0;
61412107SRekai.GonzalezAlberquilla@arm.com    }
6158733Sgeoffrey.blake@arm.com    arrayParamOut(os, "dma_done_event_tick", dma_done_event_tick);
6161684SN/A}
61712107SRekai.GonzalezAlberquilla@arm.com
61812109SRekai.GonzalezAlberquilla@arm.comvoid
61912109SRekai.GonzalezAlberquilla@arm.comPl111::unserialize(Checkpoint *cp, const std::string &section)
62012107SRekai.GonzalezAlberquilla@arm.com{
62112107SRekai.GonzalezAlberquilla@arm.com    DPRINTF(PL111, "Unserializing ARM PL111\n");
6228733Sgeoffrey.blake@arm.com
6239046SAli.Saidi@ARM.com    uint32_t lcdTiming0_serial;
62412107SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(lcdTiming0_serial);
62512107SRekai.GonzalezAlberquilla@arm.com    lcdTiming0 = lcdTiming0_serial;
6268733Sgeoffrey.blake@arm.com
6278733Sgeoffrey.blake@arm.com    uint32_t lcdTiming1_serial;
6281060SN/A    UNSERIALIZE_SCALAR(lcdTiming1_serial);
62912109SRekai.GonzalezAlberquilla@arm.com    lcdTiming1 = lcdTiming1_serial;
63012109SRekai.GonzalezAlberquilla@arm.com
63112109SRekai.GonzalezAlberquilla@arm.com    uint32_t lcdTiming2_serial;
63212109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(lcdTiming2_serial);
63312109SRekai.GonzalezAlberquilla@arm.com    lcdTiming2 = lcdTiming2_serial;
63412109SRekai.GonzalezAlberquilla@arm.com
63512109SRekai.GonzalezAlberquilla@arm.com    uint32_t lcdTiming3_serial;
63612109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(lcdTiming3_serial);
63712109SRekai.GonzalezAlberquilla@arm.com    lcdTiming3 = lcdTiming3_serial;
63812109SRekai.GonzalezAlberquilla@arm.com
63912109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(lcdUpbase);
64012109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(lcdLpbase);
64112109SRekai.GonzalezAlberquilla@arm.com
64212109SRekai.GonzalezAlberquilla@arm.com    uint32_t lcdControl_serial;
64312109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(lcdControl_serial);
64412109SRekai.GonzalezAlberquilla@arm.com    lcdControl = lcdControl_serial;
64512109SRekai.GonzalezAlberquilla@arm.com
64612109SRekai.GonzalezAlberquilla@arm.com    uint8_t lcdImsc_serial;
64712109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(lcdImsc_serial);
64812109SRekai.GonzalezAlberquilla@arm.com    lcdImsc = lcdImsc_serial;
64912109SRekai.GonzalezAlberquilla@arm.com
6502702Sktlim@umich.edu    uint8_t lcdRis_serial;
65110319SAndreas.Sandberg@ARM.com    UNSERIALIZE_SCALAR(lcdRis_serial);
6521060SN/A    lcdRis = lcdRis_serial;
65312107SRekai.GonzalezAlberquilla@arm.com
6541060SN/A    uint8_t lcdMis_serial;
6551060SN/A    UNSERIALIZE_SCALAR(lcdMis_serial);
6569920Syasuko.eckert@amd.com    lcdMis = lcdMis_serial;
65710319SAndreas.Sandberg@ARM.com
6589920Syasuko.eckert@amd.com    UNSERIALIZE_ARRAY(lcdPalette, LcdPaletteSize);
65912107SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_ARRAY(cursorImage, CrsrImageSize);
6609920Syasuko.eckert@amd.com
6619920Syasuko.eckert@amd.com    UNSERIALIZE_SCALAR(clcdCrsrCtrl);
6622702Sktlim@umich.edu    UNSERIALIZE_SCALAR(clcdCrsrConfig);
6633735Sstever@eecs.umich.edu    UNSERIALIZE_SCALAR(clcdCrsrPalette0);
6641060SN/A    UNSERIALIZE_SCALAR(clcdCrsrPalette1);
66512107SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(clcdCrsrXY);
6662308SN/A    UNSERIALIZE_SCALAR(clcdCrsrClip);
6671060SN/A
66812109SRekai.GonzalezAlberquilla@arm.com    uint8_t clcdCrsrImsc_serial;
66912109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(clcdCrsrImsc_serial);
67012109SRekai.GonzalezAlberquilla@arm.com    clcdCrsrImsc = clcdCrsrImsc_serial;
67112109SRekai.GonzalezAlberquilla@arm.com
67212109SRekai.GonzalezAlberquilla@arm.com    uint8_t clcdCrsrIcr_serial;
67312109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(clcdCrsrIcr_serial);
67412109SRekai.GonzalezAlberquilla@arm.com    clcdCrsrIcr = clcdCrsrIcr_serial;
6752702Sktlim@umich.edu
67612107SRekai.GonzalezAlberquilla@arm.com    uint8_t clcdCrsrRis_serial;
67712107SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(clcdCrsrRis_serial);
6782308SN/A    clcdCrsrRis = clcdCrsrRis_serial;
67912107SRekai.GonzalezAlberquilla@arm.com
6801060SN/A    uint8_t clcdCrsrMis_serial;
6811060SN/A    UNSERIALIZE_SCALAR(clcdCrsrMis_serial);
68212109SRekai.GonzalezAlberquilla@arm.com    clcdCrsrMis = clcdCrsrMis_serial;
68312109SRekai.GonzalezAlberquilla@arm.com
68412109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(height);
68512109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(width);
68612109SRekai.GonzalezAlberquilla@arm.com    UNSERIALIZE_SCALAR(bytesPerPixel);
68712109SRekai.GonzalezAlberquilla@arm.com
6882190SN/A    UNSERIALIZE_ARRAY(dmaBuffer, buffer_size);
6892292SN/A    UNSERIALIZE_SCALAR(startTime);
6902190SN/A    UNSERIALIZE_SCALAR(startAddr);
6912331SN/A    UNSERIALIZE_SCALAR(maxAddr);
6922292SN/A    UNSERIALIZE_SCALAR(curAddr);
6932190SN/A    UNSERIALIZE_SCALAR(waterMark);
6941684SN/A    UNSERIALIZE_SCALAR(dmaPendingNum);
6951464SN/A
6961464SN/A    Tick int_event_time = 0;
6971464SN/A    Tick read_event_time = 0;
6981464SN/A    Tick fill_fifo_event_time = 0;
6991464SN/A
7001684SN/A    UNSERIALIZE_SCALAR(read_event_time);
7012731Sktlim@umich.edu    UNSERIALIZE_SCALAR(fill_fifo_event_time);
7021464SN/A    UNSERIALIZE_SCALAR(int_event_time);
7032292SN/A
7042731Sktlim@umich.edu    if (int_event_time)
7051464SN/A        schedule(intEvent, int_event_time);
7062731Sktlim@umich.edu    if (read_event_time)
7072731Sktlim@umich.edu        schedule(readEvent, read_event_time);
7082308SN/A    if (fill_fifo_event_time)
7092731Sktlim@umich.edu        schedule(fillFifoEvent, fill_fifo_event_time);
7102731Sktlim@umich.edu
7112308SN/A    vector<Tick> dma_done_event_tick;
7121060SN/A    dma_done_event_tick.resize(maxOutstandingDma);
7132731Sktlim@umich.edu    arrayParamIn(cp, section, "dma_done_event_tick", dma_done_event_tick);
7141060SN/A    dmaDoneEventFree.clear();
7151060SN/A    for (int x = 0; x < maxOutstandingDma; x++) {
7162731Sktlim@umich.edu        if (dma_done_event_tick[x])
7171060SN/A            schedule(dmaDoneEventAll[x], dma_done_event_tick[x]);
7184032Sktlim@umich.edu        else
7194032Sktlim@umich.edu            dmaDoneEventFree.push_back(&dmaDoneEventAll[x]);
7204032Sktlim@umich.edu    }
7211060SN/A    assert(maxOutstandingDma - dmaDoneEventFree.size() == dmaPendingNum);
7222731Sktlim@umich.edu
7231060SN/A    if (lcdControl.lcdpwr) {
7241060SN/A        updateVideoParams();
7252731Sktlim@umich.edu        if (vnc)
7261060SN/A            vnc->setDirty();
7274032Sktlim@umich.edu    }
7284032Sktlim@umich.edu}
7294032Sktlim@umich.edu
7301060SN/Avoid
7312731Sktlim@umich.eduPl111::generateInterrupt()
7321060SN/A{
7331060SN/A    DPRINTF(PL111, "Generate Interrupt: lcdImsc=0x%x lcdRis=0x%x lcdMis=0x%x\n",
7342731Sktlim@umich.edu            (uint32_t)lcdImsc, (uint32_t)lcdRis, (uint32_t)lcdMis);
7351060SN/A    lcdMis = lcdImsc & lcdRis;
7361060SN/A
7372731Sktlim@umich.edu    if (lcdMis.underflow || lcdMis.baseaddr || lcdMis.vcomp || lcdMis.ahbmaster) {
7381060SN/A        gic->sendInt(intNum);
7391061SN/A        DPRINTF(PL111, " -- Generated\n");
7402731Sktlim@umich.edu    }
7411061SN/A}
7421060SN/A
7432731Sktlim@umich.eduAddrRangeList
7442731Sktlim@umich.eduPl111::getAddrRanges() const
7452731Sktlim@umich.edu{
7462731Sktlim@umich.edu    AddrRangeList ranges;
7472731Sktlim@umich.edu    ranges.push_back(RangeSize(pioAddr, pioSize));
7481060SN/A    return ranges;
7492292SN/A}
7502731Sktlim@umich.edu
7512292SN/APl111 *
7522292SN/APl111Params::create()
7532731Sktlim@umich.edu{
7542292SN/A    return new Pl111(this);
7551060SN/A}
7562731Sktlim@umich.edu
7571060SN/A
7581060SN/A