hdlcd.hh (10905:a6ca6831e775) | hdlcd.hh (11090:f37a6b82f98f) |
---|---|
1/* 2 * Copyright (c) 2010-2013, 2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 21 unchanged lines hidden (view full) --- 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Chris Emmons | 1/* 2 * Copyright (c) 2010-2013, 2015 ARM Limited 3 * All rights reserved 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software --- 21 unchanged lines hidden (view full) --- 30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 * 37 * Authors: Chris Emmons |
38 * Andreas Sandberg |
|
38 */ 39 40 41/** @file 42 * Implementiation of the ARM HDLcd controller. 43 * 44 * This implementation aims to have sufficient detail such that underrun 45 * conditions are reasonable / behave similar to reality. There are two --- 10 unchanged lines hidden (view full) --- 56 * condition is different than the real hardware; while the user will see 57 * artifacts (previous frame mixed with current frame), it is not the same 58 * behavior as real hardware which repeats the last pixel value for the rest 59 * of the current frame. This compromise was made to save on memory and 60 * complexity and assumes that it is not important to accurately model the 61 * content of an underrun frame. 62 * 63 * KNOWN ISSUES | 39 */ 40 41 42/** @file 43 * Implementiation of the ARM HDLcd controller. 44 * 45 * This implementation aims to have sufficient detail such that underrun 46 * conditions are reasonable / behave similar to reality. There are two --- 10 unchanged lines hidden (view full) --- 57 * condition is different than the real hardware; while the user will see 58 * artifacts (previous frame mixed with current frame), it is not the same 59 * behavior as real hardware which repeats the last pixel value for the rest 60 * of the current frame. This compromise was made to save on memory and 61 * complexity and assumes that it is not important to accurately model the 62 * content of an underrun frame. 63 * 64 * KNOWN ISSUES |
64 * 1. The default kernel driver used in testing sets the line count to one 65 * less than the expected 768. However, it also sets the v_count to 767. 66 * The controller specifies that 1 should be added to v_count but does not 67 * specify adding 1 to the line count. The driver is probably wrong. 68 * However, to sync these two numbers up, this model uses fb_line_count and 69 * fb_line_length rather than using v_data or h_data values to determine the 70 * width and height of the frame; those values are ignored. 71 * 2. The HDLcd is implemented here as an AmbaDmaDevice, but it doesn't have 72 * an AMBA ID as far as I know. That is the only bit of the AmbaDmaDevice 73 * interface that is irrelevant to it, so a fake AMBA ID is used for now. 74 * I didn't think inserting an extra layer of hierachy between AmbaDmaDevice 75 * and DmaDevice would be helpful to anyone else, but that may be the right 76 * answer. 77 * 3. The internal buffer size is either 1 or 2 KB depending on which 78 * specification is referenced for the different Versatile Express tiles. 79 * This implementation uses the larger 2 KB buffer by default. | 65 * <ul> 66 * <li>The HDLcd is implemented here as an AmbaDmaDevice, but it 67 * doesn't have an AMBA ID as far as I know. That is the only 68 * bit of the AmbaDmaDevice interface that is irrelevant to it, 69 * so a fake AMBA ID is used for now. I didn't think inserting 70 * an extra layer of hierachy between AmbaDmaDevice and 71 * DmaDevice would be helpful to anyone else, but that may be 72 * the right answer. 73 * </ul> |
80 */ 81 82#ifndef __DEV_ARM_HDLCD_HH__ 83#define __DEV_ARM_HDLCD_HH__ 84 85#include <fstream> 86#include <memory> 87 88#include "base/bitmap.hh" 89#include "base/framebuffer.hh" 90#include "dev/arm/amba_device.hh" | 74 */ 75 76#ifndef __DEV_ARM_HDLCD_HH__ 77#define __DEV_ARM_HDLCD_HH__ 78 79#include <fstream> 80#include <memory> 81 82#include "base/bitmap.hh" 83#include "base/framebuffer.hh" 84#include "dev/arm/amba_device.hh" |
91#include "params/HDLcd.hh" | 85#include "dev/pixelpump.hh" |
92#include "sim/serialize.hh" 93 94class VncInput; | 86#include "sim/serialize.hh" 87 88class VncInput; |
89struct HDLcdParams; 90class HDLcdPixelPump; |
|
95 96class HDLcd: public AmbaDmaDevice 97{ | 91 92class HDLcd: public AmbaDmaDevice 93{ |
98 protected: 99 /** fake AMBA ID -- unused */ 100 static const uint64_t AMBA_ID = ULL(0xb105f00d00141000); | 94 public: 95 HDLcd(const HDLcdParams *p); 96 ~HDLcd(); |
101 | 97 |
98 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 99 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; 100 101 void drainResume() M5_ATTR_OVERRIDE; 102 103 public: // IO device interface 104 Tick read(PacketPtr pkt) M5_ATTR_OVERRIDE; 105 Tick write(PacketPtr pkt) M5_ATTR_OVERRIDE; 106 107 AddrRangeList getAddrRanges() const M5_ATTR_OVERRIDE { return addrRanges; } 108 109 protected: // Parameters 110 VncInput *vnc; 111 const bool workaroundSwapRB; 112 const bool workaroundDmaLineCount; 113 const AddrRangeList addrRanges; 114 const bool enableCapture; 115 const Addr pixelBufferSize; 116 117 protected: // Register handling |
|
102 /** ARM HDLcd register offsets */ 103 enum RegisterOffset { 104 Version = 0x0000, 105 Int_RawStat = 0x0010, 106 Int_Clear = 0x0014, 107 Int_Mask = 0x0018, 108 Int_Status = 0x001C, 109 Fb_Base = 0x0100, --- 9 unchanged lines hidden (view full) --- 119 H_Back_Porch = 0x0214, 120 H_Data = 0x0218, 121 H_Front_Porch = 0x021C, 122 Polarities = 0x0220, 123 Command = 0x0230, 124 Pixel_Format = 0x0240, 125 Red_Select = 0x0244, 126 Green_Select = 0x0248, | 118 /** ARM HDLcd register offsets */ 119 enum RegisterOffset { 120 Version = 0x0000, 121 Int_RawStat = 0x0010, 122 Int_Clear = 0x0014, 123 Int_Mask = 0x0018, 124 Int_Status = 0x001C, 125 Fb_Base = 0x0100, --- 9 unchanged lines hidden (view full) --- 135 H_Back_Porch = 0x0214, 136 H_Data = 0x0218, 137 H_Front_Porch = 0x021C, 138 Polarities = 0x0220, 139 Command = 0x0230, 140 Pixel_Format = 0x0240, 141 Red_Select = 0x0244, 142 Green_Select = 0x0248, |
127 Blue_Select = 0x024C }; | 143 Blue_Select = 0x024C, 144 }; |
128 129 /** Reset value for Bus_Options register */ | 145 146 /** Reset value for Bus_Options register */ |
130 static const size_t BUS_OPTIONS_RESETV = 0x408; | 147 static constexpr size_t BUS_OPTIONS_RESETV = 0x408; |
131 132 /** Reset value for Version register */ | 148 149 /** Reset value for Version register */ |
133 static const size_t VERSION_RESETV = 0x1CDC0000; | 150 static constexpr size_t VERSION_RESETV = 0x1CDC0000; |
134 | 151 |
135 /** max number of outstanding DMA requests possible */ 136 static const size_t MAX_OUTSTANDING_DMA_REQ_CAPACITY = 16; | 152 /** AXI port width in bytes */ 153 static constexpr size_t AXI_PORT_WIDTH = 8; |
137 138 /** max number of beats delivered in one dma burst */ | 154 155 /** max number of beats delivered in one dma burst */ |
139 static const size_t MAX_BURST_LEN = 16; | 156 static constexpr size_t MAX_BURST_LEN = 16; |
140 | 157 |
141 /** size of internal buffer in bytes */ 142 static const size_t PIXEL_BUFFER_CAPACITY = 2048; | 158 /** Maximum number of bytes per pixel */ 159 static constexpr size_t MAX_PIXEL_SIZE = 4; |
143 | 160 |
144 /** AXI port width in bytes */ 145 static const size_t AXI_PORT_WIDTH = 8; 146 147 static const size_t MAX_BURST_SIZE = MAX_BURST_LEN * AXI_PORT_WIDTH; 148 | |
149 /** 150 * @name RegisterFieldLayouts 151 * Bit layout declarations for multi-field registers. 152 */ 153 /**@{*/ 154 BitUnion32(VersionReg) 155 Bitfield<7,0> version_minor; 156 Bitfield<15,8> version_major; 157 Bitfield<31,16> product_id; 158 EndBitUnion(VersionReg) 159 | 161 /** 162 * @name RegisterFieldLayouts 163 * Bit layout declarations for multi-field registers. 164 */ 165 /**@{*/ 166 BitUnion32(VersionReg) 167 Bitfield<7,0> version_minor; 168 Bitfield<15,8> version_major; 169 Bitfield<31,16> product_id; 170 EndBitUnion(VersionReg) 171 |
160 BitUnion32(InterruptReg) 161 Bitfield<0> dma_end; 162 Bitfield<1> bus_error; 163 Bitfield<2> vsync; 164 Bitfield<3> underrun; 165 EndBitUnion(InterruptReg) | 172 static constexpr uint32_t INT_DMA_END = (1UL << 0); 173 static constexpr uint32_t INT_BUS_ERROR = (1UL << 1); 174 static constexpr uint32_t INT_VSYNC = (1UL << 2); 175 static constexpr uint32_t INT_UNDERRUN = (1UL << 3); |
166 167 BitUnion32(FbLineCountReg) 168 Bitfield<11,0> fb_line_count; 169 Bitfield<31,12> reserved_31_12; 170 EndBitUnion(FbLineCountReg) 171 172 BitUnion32(BusOptsReg) 173 Bitfield<4,0> burst_len; --- 38 unchanged lines hidden (view full) --- 212 EndBitUnion(ColorSelectReg) 213 /**@}*/ 214 215 /** 216 * @name HDLCDRegisters 217 * HDLCD register contents. 218 */ 219 /**@{*/ | 176 177 BitUnion32(FbLineCountReg) 178 Bitfield<11,0> fb_line_count; 179 Bitfield<31,12> reserved_31_12; 180 EndBitUnion(FbLineCountReg) 181 182 BitUnion32(BusOptsReg) 183 Bitfield<4,0> burst_len; --- 38 unchanged lines hidden (view full) --- 222 EndBitUnion(ColorSelectReg) 223 /**@}*/ 224 225 /** 226 * @name HDLCDRegisters 227 * HDLCD register contents. 228 */ 229 /**@{*/ |
220 VersionReg version; /**< Version register */ 221 InterruptReg int_rawstat; /**< Interrupt raw status register */ 222 InterruptReg int_clear; /**< Interrupt clear register */ 223 InterruptReg int_mask; /**< Interrupt mask register */ 224 InterruptReg int_status; /**< Interrupt status register */ | 230 const VersionReg version; /**< Version register */ 231 uint32_t int_rawstat; /**< Interrupt raw status register */ 232 uint32_t int_mask; /**< Interrupt mask register */ |
225 uint32_t fb_base; /**< Frame buffer base address register */ 226 uint32_t fb_line_length; /**< Frame buffer Line length register */ 227 FbLineCountReg fb_line_count; /**< Frame buffer Line count register */ | 233 uint32_t fb_base; /**< Frame buffer base address register */ 234 uint32_t fb_line_length; /**< Frame buffer Line length register */ 235 FbLineCountReg fb_line_count; /**< Frame buffer Line count register */ |
228 uint32_t fb_line_pitch; /**< Frame buffer Line pitch register */ | 236 int32_t fb_line_pitch; /**< Frame buffer Line pitch register */ |
229 BusOptsReg bus_options; /**< Bus options register */ 230 TimingReg v_sync; /**< Vertical sync width register */ 231 TimingReg v_back_porch; /**< Vertical back porch width register */ 232 TimingReg v_data; /**< Vertical data width register */ 233 TimingReg v_front_porch; /**< Vertical front porch width register */ 234 TimingReg h_sync; /**< Horizontal sync width register */ 235 TimingReg h_back_porch; /**< Horizontal back porch width register */ 236 TimingReg h_data; /**< Horizontal data width register */ 237 TimingReg h_front_porch; /**< Horizontal front porch width reg */ 238 PolaritiesReg polarities; /**< Polarities register */ 239 CommandReg command; /**< Command register */ 240 PixelFormatReg pixel_format; /**< Pixel format register */ 241 ColorSelectReg red_select; /**< Red color select register */ 242 ColorSelectReg green_select; /**< Green color select register */ 243 ColorSelectReg blue_select; /**< Blue color select register */ 244 /** @} */ 245 | 237 BusOptsReg bus_options; /**< Bus options register */ 238 TimingReg v_sync; /**< Vertical sync width register */ 239 TimingReg v_back_porch; /**< Vertical back porch width register */ 240 TimingReg v_data; /**< Vertical data width register */ 241 TimingReg v_front_porch; /**< Vertical front porch width register */ 242 TimingReg h_sync; /**< Horizontal sync width register */ 243 TimingReg h_back_porch; /**< Horizontal back porch width register */ 244 TimingReg h_data; /**< Horizontal data width register */ 245 TimingReg h_front_porch; /**< Horizontal front porch width reg */ 246 PolaritiesReg polarities; /**< Polarities register */ 247 CommandReg command; /**< Command register */ 248 PixelFormatReg pixel_format; /**< Pixel format register */ 249 ColorSelectReg red_select; /**< Red color select register */ 250 ColorSelectReg green_select; /**< Green color select register */ 251 ColorSelectReg blue_select; /**< Blue color select register */ 252 /** @} */ 253 |
246 /** Pixel clock period */ 247 const Tick pixelClock; | 254 uint32_t readReg(Addr offset); 255 void writeReg(Addr offset, uint32_t value); |
248 | 256 |
249 FrameBuffer fb; | 257 PixelConverter pixelConverter() const; 258 DisplayTimings displayTimings() const; |
250 | 259 |
251 /** VNC server */ 252 VncInput *vnc; | 260 void createDmaEngine(); |
253 | 261 |
254 /** Helper to write out bitmaps */ 255 Bitmap bmp; | 262 void cmdEnable(); 263 void cmdDisable(); |
256 | 264 |
257 /** Picture of what the current frame buffer looks like */ 258 std::ostream *pic; | 265 bool enabled() const { return command.enable; } |
259 | 266 |
260 /** 261 * Event wrapper for dmaDone() 262 * 263 * This event call pushes its this pointer onto the freeDoneEvent vector 264 * and calls dmaDone() when triggered. While most of the time the burst 265 * length of a transaction will be the max burst length set by the driver, 266 * any trailing bytes must be handled with smaller lengths thus requiring 267 * the configurable burst length option. 268 */ 269 class DmaDoneEvent : public Event 270 { 271 private: 272 /** Reference to HDLCD that issued the corresponding DMA transaction */ 273 HDLcd &obj; | 267 public: // Pixel pump callbacks 268 bool pxlNext(Pixel &p); 269 void pxlVSyncBegin(); 270 void pxlVSyncEnd(); 271 void pxlUnderrun(); 272 void pxlFrameDone(); |
274 | 273 |
275 /** Transaction size */ 276 size_t transSize; 277 278 public: 279 /** 280 * Constructor. 281 * 282 * @param _obj HDLCD that issued the corresponding DMA transaction 283 */ 284 DmaDoneEvent(HDLcd *_obj) 285 : Event(), obj(*_obj), transSize(0) {} 286 287 /** 288 * Sets the size of this transaction. 289 * 290 * @param len size of the transaction in bytes 291 */ 292 void setTransactionSize(size_t len) { 293 transSize = len; 294 } 295 296 /** 297 * Gets the size of this transaction. 298 * 299 * @return size of this transaction in bytes 300 */ 301 size_t getTransactionSize() const { 302 return transSize; 303 } 304 305 void process() { 306 obj.dmaDone(this); 307 } 308 309 const std::string name() const { 310 return obj.name() + ".DmaDoneEvent"; 311 } 312 }; 313 314 /** Start time for frame buffer dma read */ 315 Tick frameReadStartTime; 316 317 /** Starting address for the current frame */ 318 Addr dmaStartAddr; 319 320 /** Next address the dma should read from */ 321 Addr dmaCurAddr; 322 323 /** One byte past the address of the last byte the dma should read 324 * from */ 325 Addr dmaMaxAddr; 326 327 /** Number of pending dma reads */ 328 size_t dmaPendingNum; 329 330 /** Flag indicating whether current frame has underrun */ 331 bool frameUnderrun; 332 333 /** HDLcd virtual display buffer */ 334 std::vector<uint8_t> virtualDisplayBuffer; 335 336 /** Size of the pixel buffer */ 337 size_t pixelBufferSize; 338 339 /** Index of the next pixel to render */ 340 size_t pixelIndex; 341 342 /** Flag indicating whether video parameters need updating */ 343 bool doUpdateParams; 344 345 /** Flag indicating whether a frame read / display is in progress */ 346 bool frameUnderway; 347 | 274 protected: // Interrupt handling |
348 /** | 275 /** |
349 * Number of bytes in flight from DMA that have not reached the pixel 350 * buffer yet 351 */ 352 uint32_t dmaBytesInFlight; 353 354 /** 355 * Gets the number of oustanding DMA transactions allowed on the bus at a 356 * time. | 276 * Assign new interrupt values and update interrupt signals |
357 * | 277 * |
358 * @return gets the driver-specified number of outstanding DMA transactions 359 * from the hdlcd controller that are allowed on the bus at a time 360 */ 361 inline uint16_t maxOutstandingDma() const { 362 return bus_options.max_outstanding; 363 } 364 365 /** 366 * Gets the number of bytes free in the pixel buffer. | 278 * A new interrupt is scheduled signalled if the set of unmasked 279 * interrupts goes empty to non-empty. Conversely, if the set of 280 * unmasked interrupts goes from non-empty to empty, the interrupt 281 * signal is cleared. |
367 * | 282 * |
368 * @return number of bytes free in the internal pixel buffer | 283 * @param ints New <i>raw</i> interrupt status 284 * @param mask New interrupt mask |
369 */ | 285 */ |
370 inline uint32_t bytesFreeInPixelBuffer() const { 371 return PIXEL_BUFFER_CAPACITY - (pixelBufferSize + dmaBytesInFlight); 372 } | 286 void setInterrupts(uint32_t ints, uint32_t mask); |
373 374 /** | 287 288 /** |
375 * Gets the number of beats-per-burst for bus transactions. | 289 * Convenience function to update the interrupt mask |
376 * | 290 * |
377 * @return number of beats-per-burst per HDLcd DMA transaction | 291 * @see setInterrupts 292 * @param mask New interrupt mask |
378 */ | 293 */ |
379 inline size_t dmaBurstLength() const { 380 assert(bus_options.burst_len <= MAX_BURST_LEN); 381 return bus_options.burst_len; 382 } | 294 void intMask(uint32_t mask) { setInterrupts(int_rawstat, mask); } |
383 384 /** | 295 296 /** |
385 * Gets the number of bytes per pixel. | 297 * Convenience function to raise a new interrupt |
386 * | 298 * |
387 * @return bytes per pixel | 299 * @see setInterrupts 300 * @param ints Set of interrupts to raise |
388 */ | 301 */ |
389 inline size_t bytesPerPixel() const { 390 return pixel_format.bytes_per_pixel + 1; | 302 void intRaise(uint32_t ints) { 303 setInterrupts(int_rawstat | ints, int_mask); |
391 } 392 393 /** | 304 } 305 306 /** |
394 * Gets frame buffer width. | 307 * Convenience function to clear interrupts |
395 * | 308 * |
396 * @return frame buffer width (pixels per line) | 309 * @see setInterrupts 310 * @param ints Set of interrupts to clear |
397 */ | 311 */ |
398 inline size_t width() const { 399 return fb_line_length / bytesPerPixel(); | 312 void intClear(uint32_t ints) { 313 setInterrupts(int_rawstat & ~ints, int_mask); |
400 } 401 | 314 } 315 |
402 /** 403 * Gets frame buffer height. 404 * 405 * @return frame buffer height (lines per panel) 406 */ 407 inline size_t height() const { 408 return fb_line_count.fb_line_count; 409 } | 316 /** Masked interrupt status register */ 317 const uint32_t intStatus() const { return int_rawstat & int_mask; } |
410 | 318 |
411 inline size_t area() const { return height() * width(); } | 319 protected: // Pixel output 320 class PixelPump : public BasePixelPump 321 { 322 public: 323 PixelPump(HDLcd &p, ClockDomain &pxl_clk, unsigned pixel_chunk) 324 : BasePixelPump(p, pxl_clk, pixel_chunk), parent(p) {} |
412 | 325 |
413 /** 414 * Gets the total number of pixel clocks per display line. 415 * 416 * @return number of pixel clocks per display line including porch delays 417 * and horizontal sync time 418 */ 419 inline uint64_t PClksPerLine() const { 420 return h_back_porch.val + 1 + 421 h_data.val + 1 + 422 h_front_porch.val + 1 + 423 h_sync.val + 1; 424 } | 326 void dumpSettings(); |
425 | 327 |
426 /** Send updated parameters to the vnc server */ 427 void updateVideoParams(bool unserializing); | 328 protected: 329 bool nextPixel(Pixel &p) M5_ATTR_OVERRIDE { return parent.pxlNext(p); } |
428 | 330 |
429 /** Generates an interrupt */ 430 void generateInterrupt(); | 331 void onVSyncBegin() M5_ATTR_OVERRIDE { return parent.pxlVSyncBegin(); } 332 void onVSyncEnd() M5_ATTR_OVERRIDE { return parent.pxlVSyncEnd(); } |
431 | 333 |
432 /** Start reading the next frame */ 433 void startFrame(); | 334 void onUnderrun(unsigned x, unsigned y) M5_ATTR_OVERRIDE { 335 parent.pxlUnderrun(); 336 } |
434 | 337 |
435 /** End of frame reached */ 436 void endFrame(); | 338 void onFrameDone() M5_ATTR_OVERRIDE { parent.pxlFrameDone(); } |
437 | 339 |
438 /** Generate DMA read requests from frame buffer into pixel buffer */ 439 void fillPixelBuffer(); | 340 protected: 341 HDLcd &parent; 342 }; |
440 | 343 |
441 /** DMA done event */ 442 void dmaDone(DmaDoneEvent *event); | 344 /** Helper to write out bitmaps */ 345 Bitmap bmp; |
443 | 346 |
444 /** Called when it is time to render a pixel */ 445 void renderPixel(); | 347 /** Picture of what the current frame buffer looks like */ 348 std::ostream *pic; |
446 | 349 |
447 PixelConverter pixelConverter() const; | 350 /** Cached pixel converter, set when the converter is enabled. */ 351 PixelConverter conv; |
448 | 352 |
449 /** Start of frame event */ 450 EventWrapper<HDLcd, &HDLcd::startFrame> startFrameEvent; | 353 PixelPump pixelPump; |
451 | 354 |
452 /** End of frame event */ 453 EventWrapper<HDLcd, &HDLcd::endFrame> endFrameEvent; | 355 protected: // DMA handling 356 class DmaEngine : public DmaReadFifo 357 { 358 public: 359 DmaEngine(HDLcd &_parent, size_t size, 360 unsigned request_size, unsigned max_pending, 361 size_t line_size, ssize_t line_pitch, unsigned num_lines); |
454 | 362 |
455 /** Pixel render event */ 456 EventWrapper<HDLcd, &HDLcd::renderPixel> renderPixelEvent; | 363 void startFrame(Addr fb_base); 364 void abortFrame(); 365 void dumpSettings(); |
457 | 366 |
458 /** Fill fifo */ 459 EventWrapper<HDLcd, &HDLcd::fillPixelBuffer> fillPixelBufferEvent; | 367 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 368 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; |
460 | 369 |
461 /** Wrapper to create an event out of the interrupt */ 462 EventWrapper<HDLcd, &HDLcd::generateInterrupt> intEvent; | 370 protected: 371 void onEndOfBlock() M5_ATTR_OVERRIDE; 372 void onIdle() M5_ATTR_OVERRIDE; |
463 | 373 |
464 /**@{*/ 465 /** 466 * All pre-allocated DMA done events 467 * 468 * The HDLCD model preallocates maxOutstandingDma() number of 469 * DmaDoneEvents to avoid having to heap allocate every single 470 * event when it is needed. In order to keep track of which events 471 * are in flight and which are ready to be used, we use two 472 * different vectors. dmaDoneEventAll contains <i>all</i> 473 * DmaDoneEvents that the object may use, while dmaDoneEventFree 474 * contains a list of currently <i>unused</i> events. When an 475 * event needs to be scheduled, the last element of the 476 * dmaDoneEventFree is used and removed from the list. When an 477 * event fires, it is added to the end of the 478 * dmaEventFreeList. dmaDoneEventAll is never used except for in 479 * initialization and serialization. 480 */ 481 std::vector<DmaDoneEvent> dmaDoneEventAll; | 374 HDLcd &parent; 375 const size_t lineSize; 376 const ssize_t linePitch; 377 const unsigned numLines; |
482 | 378 |
483 /** Unused DMA done events that are ready to be scheduled */ 484 std::vector<DmaDoneEvent *> dmaDoneEventFree; 485 /**@}*/ | 379 Addr nextLineAddr; 380 Addr frameEnd; 381 }; |
486 | 382 |
487 bool enableCapture; 488 489 const bool workaround_swap_rb; 490 491 public: 492 typedef HDLcdParams Params; 493 494 const Params * 495 params() const 496 { 497 return dynamic_cast<const Params *>(_params); 498 } 499 HDLcd(const Params *p); 500 ~HDLcd(); 501 502 virtual Tick read(PacketPtr pkt); 503 virtual Tick write(PacketPtr pkt); 504 505 void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE; 506 void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE; 507 508 /** 509 * Determine the address ranges that this device responds to. 510 * 511 * @return a list of non-overlapping address ranges 512 */ 513 AddrRangeList getAddrRanges() const; | 383 std::unique_ptr<DmaEngine> dmaEngine; |
514}; 515 516#endif | 384}; 385 386#endif |