| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * OMAP2 Display Subsystem. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 2008 Nokia Corporation | 
					
						
							|  |  |  |  * Written by Andrzej Zaborowski <andrew@openedhand.com> | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License as | 
					
						
							|  |  |  |  * published by the Free Software Foundation; either version 2 or | 
					
						
							|  |  |  |  * (at your option) version 3 of the License. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-01-04 22:05:52 +00:00
										 |  |  |  * You should have received a copy of the GNU General Public License along | 
					
						
							| 
									
										
										
										
											2009-07-16 20:47:01 +00:00
										 |  |  |  * with this program; if not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-01-26 18:17:13 +00:00
										 |  |  | #include "qemu/osdep.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-04 15:40:22 +01:00
										 |  |  | #include "hw/hw.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-12 07:23:42 +02:00
										 |  |  | #include "hw/irq.h"
 | 
					
						
							| 
									
										
										
										
											2012-11-28 12:06:30 +01:00
										 |  |  | #include "ui/console.h"
 | 
					
						
							| 
									
										
										
										
											2013-02-05 17:06:20 +01:00
										 |  |  | #include "hw/arm/omap.h"
 | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct omap_dss_s { | 
					
						
							|  |  |  |     qemu_irq irq; | 
					
						
							|  |  |  |     qemu_irq drq; | 
					
						
							|  |  |  |     DisplayState *state; | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     MemoryRegion iomem_diss1, iomem_disc1, iomem_rfbi1, iomem_venc1, iomem_im3; | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     int autoidle; | 
					
						
							|  |  |  |     int control; | 
					
						
							|  |  |  |     int enable; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct omap_dss_panel_s { | 
					
						
							|  |  |  |         int enable; | 
					
						
							|  |  |  |         int nx; | 
					
						
							|  |  |  |         int ny; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         int x; | 
					
						
							|  |  |  |         int y; | 
					
						
							|  |  |  |     } dig, lcd; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct { | 
					
						
							|  |  |  |         uint32_t idlemode; | 
					
						
							|  |  |  |         uint32_t irqst; | 
					
						
							|  |  |  |         uint32_t irqen; | 
					
						
							|  |  |  |         uint32_t control; | 
					
						
							|  |  |  |         uint32_t config; | 
					
						
							|  |  |  |         uint32_t capable; | 
					
						
							| 
									
										
										
										
											2008-08-22 08:57:19 +00:00
										 |  |  |         uint32_t timing[4]; | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |         int line; | 
					
						
							|  |  |  |         uint32_t bg[2]; | 
					
						
							|  |  |  |         uint32_t trans[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         struct omap_dss_plane_s { | 
					
						
							|  |  |  |             int enable; | 
					
						
							|  |  |  |             int bpp; | 
					
						
							|  |  |  |             int posx; | 
					
						
							|  |  |  |             int posy; | 
					
						
							|  |  |  |             int nx; | 
					
						
							|  |  |  |             int ny; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |             hwaddr addr[3]; | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             uint32_t attr; | 
					
						
							|  |  |  |             uint32_t tresh; | 
					
						
							|  |  |  |             int rowinc; | 
					
						
							|  |  |  |             int colinc; | 
					
						
							|  |  |  |             int wininc; | 
					
						
							|  |  |  |         } l[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         int invalidate; | 
					
						
							|  |  |  |         uint16_t palette[256]; | 
					
						
							|  |  |  |     } dispc; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     struct { | 
					
						
							|  |  |  |         int idlemode; | 
					
						
							|  |  |  |         uint32_t control; | 
					
						
							|  |  |  |         int enable; | 
					
						
							|  |  |  |         int pixels; | 
					
						
							|  |  |  |         int busy; | 
					
						
							|  |  |  |         int skiplines; | 
					
						
							|  |  |  |         uint16_t rxbuf; | 
					
						
							|  |  |  |         uint32_t config[2]; | 
					
						
							|  |  |  |         uint32_t time[4]; | 
					
						
							|  |  |  |         uint32_t data[6]; | 
					
						
							|  |  |  |         uint16_t vsync; | 
					
						
							|  |  |  |         uint16_t hsync; | 
					
						
							|  |  |  |         struct rfbi_chip_s *chip[2]; | 
					
						
							|  |  |  |     } rfbi; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void omap_dispc_interrupt_update(struct omap_dss_s *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     qemu_set_irq(s->irq, s->dispc.irqst & s->dispc.irqen); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void omap_rfbi_reset(struct omap_dss_s *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     s->rfbi.idlemode = 0; | 
					
						
							|  |  |  |     s->rfbi.control = 2; | 
					
						
							|  |  |  |     s->rfbi.enable = 0; | 
					
						
							|  |  |  |     s->rfbi.pixels = 0; | 
					
						
							|  |  |  |     s->rfbi.skiplines = 0; | 
					
						
							|  |  |  |     s->rfbi.busy = 0; | 
					
						
							|  |  |  |     s->rfbi.config[0] = 0x00310000; | 
					
						
							|  |  |  |     s->rfbi.config[1] = 0x00310000; | 
					
						
							|  |  |  |     s->rfbi.time[0] = 0; | 
					
						
							|  |  |  |     s->rfbi.time[1] = 0; | 
					
						
							|  |  |  |     s->rfbi.time[2] = 0; | 
					
						
							|  |  |  |     s->rfbi.time[3] = 0; | 
					
						
							|  |  |  |     s->rfbi.data[0] = 0; | 
					
						
							|  |  |  |     s->rfbi.data[1] = 0; | 
					
						
							|  |  |  |     s->rfbi.data[2] = 0; | 
					
						
							|  |  |  |     s->rfbi.data[3] = 0; | 
					
						
							|  |  |  |     s->rfbi.data[4] = 0; | 
					
						
							|  |  |  |     s->rfbi.data[5] = 0; | 
					
						
							|  |  |  |     s->rfbi.vsync = 0; | 
					
						
							|  |  |  |     s->rfbi.hsync = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void omap_dss_reset(struct omap_dss_s *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     s->autoidle = 0; | 
					
						
							|  |  |  |     s->control = 0; | 
					
						
							|  |  |  |     s->enable = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->dig.enable = 0; | 
					
						
							|  |  |  |     s->dig.nx = 1; | 
					
						
							|  |  |  |     s->dig.ny = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->lcd.enable = 0; | 
					
						
							|  |  |  |     s->lcd.nx = 1; | 
					
						
							|  |  |  |     s->lcd.ny = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->dispc.idlemode = 0; | 
					
						
							|  |  |  |     s->dispc.irqst = 0; | 
					
						
							|  |  |  |     s->dispc.irqen = 0; | 
					
						
							|  |  |  |     s->dispc.control = 0; | 
					
						
							|  |  |  |     s->dispc.config = 0; | 
					
						
							|  |  |  |     s->dispc.capable = 0x161; | 
					
						
							|  |  |  |     s->dispc.timing[0] = 0; | 
					
						
							|  |  |  |     s->dispc.timing[1] = 0; | 
					
						
							|  |  |  |     s->dispc.timing[2] = 0; | 
					
						
							| 
									
										
										
										
											2008-08-22 08:57:19 +00:00
										 |  |  |     s->dispc.timing[3] = 0; | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     s->dispc.line = 0; | 
					
						
							|  |  |  |     s->dispc.bg[0] = 0; | 
					
						
							|  |  |  |     s->dispc.bg[1] = 0; | 
					
						
							|  |  |  |     s->dispc.trans[0] = 0; | 
					
						
							|  |  |  |     s->dispc.trans[1] = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->dispc.l[0].enable = 0; | 
					
						
							|  |  |  |     s->dispc.l[0].bpp = 0; | 
					
						
							|  |  |  |     s->dispc.l[0].addr[0] = 0; | 
					
						
							|  |  |  |     s->dispc.l[0].addr[1] = 0; | 
					
						
							|  |  |  |     s->dispc.l[0].addr[2] = 0; | 
					
						
							|  |  |  |     s->dispc.l[0].posx = 0; | 
					
						
							|  |  |  |     s->dispc.l[0].posy = 0; | 
					
						
							|  |  |  |     s->dispc.l[0].nx = 1; | 
					
						
							|  |  |  |     s->dispc.l[0].ny = 1; | 
					
						
							|  |  |  |     s->dispc.l[0].attr = 0; | 
					
						
							|  |  |  |     s->dispc.l[0].tresh = 0; | 
					
						
							|  |  |  |     s->dispc.l[0].rowinc = 1; | 
					
						
							|  |  |  |     s->dispc.l[0].colinc = 1; | 
					
						
							|  |  |  |     s->dispc.l[0].wininc = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     omap_rfbi_reset(s); | 
					
						
							|  |  |  |     omap_dispc_interrupt_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t omap_diss_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                                unsigned size) | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     struct omap_dss_s *s = (struct omap_dss_s *) opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     if (size != 4) { | 
					
						
							|  |  |  |         return omap_badwidth_read32(opaque, addr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 18:59:50 +00:00
										 |  |  |     switch (addr) { | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     case 0x00:	/* DSS_REVISIONNUMBER */ | 
					
						
							|  |  |  |         return 0x20; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x10:	/* DSS_SYSCONFIG */ | 
					
						
							|  |  |  |         return s->autoidle; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x14:	/* DSS_SYSSTATUS */ | 
					
						
							|  |  |  |         return 1;						/* RESETDONE */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x40:	/* DSS_CONTROL */ | 
					
						
							|  |  |  |         return s->control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x50:	/* DSS_PSA_LCD_REG_1 */ | 
					
						
							|  |  |  |     case 0x54:	/* DSS_PSA_LCD_REG_2 */ | 
					
						
							|  |  |  |     case 0x58:	/* DSS_PSA_VIDEO_REG */ | 
					
						
							|  |  |  |         /* TODO: fake some values when appropriate s->control bits are set */ | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x5c:	/* DSS_STATUS */ | 
					
						
							|  |  |  |         return 1 + (s->control & 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     OMAP_BAD_REG(addr); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void omap_diss_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                             uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     struct omap_dss_s *s = (struct omap_dss_s *) opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     if (size != 4) { | 
					
						
							| 
									
										
										
										
											2015-03-08 19:21:13 +01:00
										 |  |  |         omap_badwidth_write32(opaque, addr, value); | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 18:59:50 +00:00
										 |  |  |     switch (addr) { | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     case 0x00:	/* DSS_REVISIONNUMBER */ | 
					
						
							|  |  |  |     case 0x14:	/* DSS_SYSSTATUS */ | 
					
						
							|  |  |  |     case 0x50:	/* DSS_PSA_LCD_REG_1 */ | 
					
						
							|  |  |  |     case 0x54:	/* DSS_PSA_LCD_REG_2 */ | 
					
						
							|  |  |  |     case 0x58:	/* DSS_PSA_VIDEO_REG */ | 
					
						
							|  |  |  |     case 0x5c:	/* DSS_STATUS */ | 
					
						
							|  |  |  |         OMAP_RO_REG(addr); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x10:	/* DSS_SYSCONFIG */ | 
					
						
							|  |  |  |         if (value & 2)						/* SOFTRESET */ | 
					
						
							|  |  |  |             omap_dss_reset(s); | 
					
						
							|  |  |  |         s->autoidle = value & 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x40:	/* DSS_CONTROL */ | 
					
						
							|  |  |  |         s->control = value & 0x3dd; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         OMAP_BAD_REG(addr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  | static const MemoryRegionOps omap_diss_ops = { | 
					
						
							|  |  |  |     .read = omap_diss_read, | 
					
						
							|  |  |  |     .write = omap_diss_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t omap_disc_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                                unsigned size) | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     struct omap_dss_s *s = (struct omap_dss_s *) opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     if (size != 4) { | 
					
						
							|  |  |  |         return omap_badwidth_read32(opaque, addr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 18:59:50 +00:00
										 |  |  |     switch (addr) { | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     case 0x000:	/* DISPC_REVISION */ | 
					
						
							|  |  |  |         return 0x20; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x010:	/* DISPC_SYSCONFIG */ | 
					
						
							|  |  |  |         return s->dispc.idlemode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x014:	/* DISPC_SYSSTATUS */ | 
					
						
							|  |  |  |         return 1;						/* RESETDONE */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x018:	/* DISPC_IRQSTATUS */ | 
					
						
							|  |  |  |         return s->dispc.irqst; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x01c:	/* DISPC_IRQENABLE */ | 
					
						
							|  |  |  |         return s->dispc.irqen; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x040:	/* DISPC_CONTROL */ | 
					
						
							|  |  |  |         return s->dispc.control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x044:	/* DISPC_CONFIG */ | 
					
						
							|  |  |  |         return s->dispc.config; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x048:	/* DISPC_CAPABLE */ | 
					
						
							|  |  |  |         return s->dispc.capable; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x04c:	/* DISPC_DEFAULT_COLOR0 */ | 
					
						
							|  |  |  |         return s->dispc.bg[0]; | 
					
						
							|  |  |  |     case 0x050:	/* DISPC_DEFAULT_COLOR1 */ | 
					
						
							|  |  |  |         return s->dispc.bg[1]; | 
					
						
							|  |  |  |     case 0x054:	/* DISPC_TRANS_COLOR0 */ | 
					
						
							|  |  |  |         return s->dispc.trans[0]; | 
					
						
							|  |  |  |     case 0x058:	/* DISPC_TRANS_COLOR1 */ | 
					
						
							|  |  |  |         return s->dispc.trans[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x05c:	/* DISPC_LINE_STATUS */ | 
					
						
							|  |  |  |         return 0x7ff; | 
					
						
							|  |  |  |     case 0x060:	/* DISPC_LINE_NUMBER */ | 
					
						
							|  |  |  |         return s->dispc.line; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x064:	/* DISPC_TIMING_H */ | 
					
						
							|  |  |  |         return s->dispc.timing[0]; | 
					
						
							|  |  |  |     case 0x068:	/* DISPC_TIMING_V */ | 
					
						
							|  |  |  |         return s->dispc.timing[1]; | 
					
						
							|  |  |  |     case 0x06c:	/* DISPC_POL_FREQ */ | 
					
						
							|  |  |  |         return s->dispc.timing[2]; | 
					
						
							|  |  |  |     case 0x070:	/* DISPC_DIVISOR */ | 
					
						
							|  |  |  |         return s->dispc.timing[3]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x078:	/* DISPC_SIZE_DIG */ | 
					
						
							|  |  |  |         return ((s->dig.ny - 1) << 16) | (s->dig.nx - 1); | 
					
						
							|  |  |  |     case 0x07c:	/* DISPC_SIZE_LCD */ | 
					
						
							|  |  |  |         return ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x080:	/* DISPC_GFX_BA0 */ | 
					
						
							|  |  |  |         return s->dispc.l[0].addr[0]; | 
					
						
							|  |  |  |     case 0x084:	/* DISPC_GFX_BA1 */ | 
					
						
							|  |  |  |         return s->dispc.l[0].addr[1]; | 
					
						
							|  |  |  |     case 0x088:	/* DISPC_GFX_POSITION */ | 
					
						
							|  |  |  |         return (s->dispc.l[0].posy << 16) | s->dispc.l[0].posx; | 
					
						
							|  |  |  |     case 0x08c:	/* DISPC_GFX_SIZE */ | 
					
						
							|  |  |  |         return ((s->dispc.l[0].ny - 1) << 16) | (s->dispc.l[0].nx - 1); | 
					
						
							|  |  |  |     case 0x0a0:	/* DISPC_GFX_ATTRIBUTES */ | 
					
						
							|  |  |  |         return s->dispc.l[0].attr; | 
					
						
							|  |  |  |     case 0x0a4:	/* DISPC_GFX_FIFO_TRESHOLD */ | 
					
						
							|  |  |  |         return s->dispc.l[0].tresh; | 
					
						
							|  |  |  |     case 0x0a8:	/* DISPC_GFX_FIFO_SIZE_STATUS */ | 
					
						
							|  |  |  |         return 256; | 
					
						
							|  |  |  |     case 0x0ac:	/* DISPC_GFX_ROW_INC */ | 
					
						
							|  |  |  |         return s->dispc.l[0].rowinc; | 
					
						
							|  |  |  |     case 0x0b0:	/* DISPC_GFX_PIXEL_INC */ | 
					
						
							|  |  |  |         return s->dispc.l[0].colinc; | 
					
						
							|  |  |  |     case 0x0b4:	/* DISPC_GFX_WINDOW_SKIP */ | 
					
						
							|  |  |  |         return s->dispc.l[0].wininc; | 
					
						
							|  |  |  |     case 0x0b8:	/* DISPC_GFX_TABLE_BA */ | 
					
						
							|  |  |  |         return s->dispc.l[0].addr[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0bc:	/* DISPC_VID1_BA0 */ | 
					
						
							|  |  |  |     case 0x0c0:	/* DISPC_VID1_BA1 */ | 
					
						
							|  |  |  |     case 0x0c4:	/* DISPC_VID1_POSITION */ | 
					
						
							|  |  |  |     case 0x0c8:	/* DISPC_VID1_SIZE */ | 
					
						
							|  |  |  |     case 0x0cc:	/* DISPC_VID1_ATTRIBUTES */ | 
					
						
							|  |  |  |     case 0x0d0:	/* DISPC_VID1_FIFO_TRESHOLD */ | 
					
						
							|  |  |  |     case 0x0d4:	/* DISPC_VID1_FIFO_SIZE_STATUS */ | 
					
						
							|  |  |  |     case 0x0d8:	/* DISPC_VID1_ROW_INC */ | 
					
						
							|  |  |  |     case 0x0dc:	/* DISPC_VID1_PIXEL_INC */ | 
					
						
							|  |  |  |     case 0x0e0:	/* DISPC_VID1_FIR */ | 
					
						
							|  |  |  |     case 0x0e4:	/* DISPC_VID1_PICTURE_SIZE */ | 
					
						
							|  |  |  |     case 0x0e8:	/* DISPC_VID1_ACCU0 */ | 
					
						
							|  |  |  |     case 0x0ec:	/* DISPC_VID1_ACCU1 */ | 
					
						
							|  |  |  |     case 0x0f0 ... 0x140:	/* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */ | 
					
						
							|  |  |  |     case 0x14c:	/* DISPC_VID2_BA0 */ | 
					
						
							|  |  |  |     case 0x150:	/* DISPC_VID2_BA1 */ | 
					
						
							|  |  |  |     case 0x154:	/* DISPC_VID2_POSITION */ | 
					
						
							|  |  |  |     case 0x158:	/* DISPC_VID2_SIZE */ | 
					
						
							|  |  |  |     case 0x15c:	/* DISPC_VID2_ATTRIBUTES */ | 
					
						
							|  |  |  |     case 0x160:	/* DISPC_VID2_FIFO_TRESHOLD */ | 
					
						
							|  |  |  |     case 0x164:	/* DISPC_VID2_FIFO_SIZE_STATUS */ | 
					
						
							|  |  |  |     case 0x168:	/* DISPC_VID2_ROW_INC */ | 
					
						
							|  |  |  |     case 0x16c:	/* DISPC_VID2_PIXEL_INC */ | 
					
						
							|  |  |  |     case 0x170:	/* DISPC_VID2_FIR */ | 
					
						
							|  |  |  |     case 0x174:	/* DISPC_VID2_PICTURE_SIZE */ | 
					
						
							|  |  |  |     case 0x178:	/* DISPC_VID2_ACCU0 */ | 
					
						
							|  |  |  |     case 0x17c:	/* DISPC_VID2_ACCU1 */ | 
					
						
							|  |  |  |     case 0x180 ... 0x1d0:	/* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */ | 
					
						
							|  |  |  |     case 0x1d4:	/* DISPC_DATA_CYCLE1 */ | 
					
						
							|  |  |  |     case 0x1d8:	/* DISPC_DATA_CYCLE2 */ | 
					
						
							|  |  |  |     case 0x1dc:	/* DISPC_DATA_CYCLE3 */ | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     OMAP_BAD_REG(addr); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void omap_disc_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                             uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     struct omap_dss_s *s = (struct omap_dss_s *) opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     if (size != 4) { | 
					
						
							| 
									
										
										
										
											2015-03-08 19:21:13 +01:00
										 |  |  |         omap_badwidth_write32(opaque, addr, value); | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 18:59:50 +00:00
										 |  |  |     switch (addr) { | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     case 0x010:	/* DISPC_SYSCONFIG */ | 
					
						
							|  |  |  |         if (value & 2)						/* SOFTRESET */ | 
					
						
							|  |  |  |             omap_dss_reset(s); | 
					
						
							|  |  |  |         s->dispc.idlemode = value & 0x301b; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x018:	/* DISPC_IRQSTATUS */ | 
					
						
							|  |  |  |         s->dispc.irqst &= ~value; | 
					
						
							|  |  |  |         omap_dispc_interrupt_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x01c:	/* DISPC_IRQENABLE */ | 
					
						
							|  |  |  |         s->dispc.irqen = value & 0xffff; | 
					
						
							|  |  |  |         omap_dispc_interrupt_update(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x040:	/* DISPC_CONTROL */ | 
					
						
							|  |  |  |         s->dispc.control = value & 0x07ff9fff; | 
					
						
							|  |  |  |         s->dig.enable = (value >> 1) & 1; | 
					
						
							|  |  |  |         s->lcd.enable = (value >> 0) & 1; | 
					
						
							|  |  |  |         if (value & (1 << 12))			/* OVERLAY_OPTIMIZATION */ | 
					
						
							| 
									
										
										
										
											2011-11-09 17:20:06 +00:00
										 |  |  |             if (!((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1)) { | 
					
						
							|  |  |  |                 fprintf(stderr, "%s: Overlay Optimization when no overlay " | 
					
						
							|  |  |  |                         "region effectively exists leads to " | 
					
						
							|  |  |  |                         "unpredictable behaviour!\n", __func__); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |         if (value & (1 << 6)) {				/* GODIGITAL */ | 
					
						
							|  |  |  |             /* XXX: Shadowed fields are:
 | 
					
						
							|  |  |  |              * s->dispc.config | 
					
						
							|  |  |  |              * s->dispc.capable | 
					
						
							|  |  |  |              * s->dispc.bg[0] | 
					
						
							|  |  |  |              * s->dispc.bg[1] | 
					
						
							|  |  |  |              * s->dispc.trans[0] | 
					
						
							|  |  |  |              * s->dispc.trans[1] | 
					
						
							|  |  |  |              * s->dispc.line | 
					
						
							|  |  |  |              * s->dispc.timing[0] | 
					
						
							|  |  |  |              * s->dispc.timing[1] | 
					
						
							|  |  |  |              * s->dispc.timing[2] | 
					
						
							|  |  |  |              * s->dispc.timing[3] | 
					
						
							|  |  |  |              * s->lcd.nx | 
					
						
							|  |  |  |              * s->lcd.ny | 
					
						
							|  |  |  |              * s->dig.nx | 
					
						
							|  |  |  |              * s->dig.ny | 
					
						
							|  |  |  |              * s->dispc.l[0].addr[0] | 
					
						
							|  |  |  |              * s->dispc.l[0].addr[1] | 
					
						
							|  |  |  |              * s->dispc.l[0].addr[2] | 
					
						
							|  |  |  |              * s->dispc.l[0].posx | 
					
						
							|  |  |  |              * s->dispc.l[0].posy | 
					
						
							|  |  |  |              * s->dispc.l[0].nx | 
					
						
							|  |  |  |              * s->dispc.l[0].ny | 
					
						
							|  |  |  |              * s->dispc.l[0].tresh | 
					
						
							|  |  |  |              * s->dispc.l[0].rowinc | 
					
						
							|  |  |  |              * s->dispc.l[0].colinc | 
					
						
							|  |  |  |              * s->dispc.l[0].wininc | 
					
						
							|  |  |  |              * All they need to be loaded here from their shadow registers. | 
					
						
							|  |  |  |              */ | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (value & (1 << 5)) {				/* GOLCD */ | 
					
						
							|  |  |  |              /* XXX: Likewise for LCD here.  */ | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x044:	/* DISPC_CONFIG */ | 
					
						
							|  |  |  |         s->dispc.config = value & 0x3fff; | 
					
						
							|  |  |  |         /* XXX:
 | 
					
						
							|  |  |  |          * bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded | 
					
						
							|  |  |  |          * bits 2:1 (LOADMODE) reset to 2 after set to 3 and palette loaded | 
					
						
							|  |  |  |          */ | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x048:	/* DISPC_CAPABLE */ | 
					
						
							|  |  |  |         s->dispc.capable = value & 0x3ff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x04c:	/* DISPC_DEFAULT_COLOR0 */ | 
					
						
							|  |  |  |         s->dispc.bg[0] = value & 0xffffff; | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x050:	/* DISPC_DEFAULT_COLOR1 */ | 
					
						
							|  |  |  |         s->dispc.bg[1] = value & 0xffffff; | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x054:	/* DISPC_TRANS_COLOR0 */ | 
					
						
							|  |  |  |         s->dispc.trans[0] = value & 0xffffff; | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x058:	/* DISPC_TRANS_COLOR1 */ | 
					
						
							|  |  |  |         s->dispc.trans[1] = value & 0xffffff; | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x060:	/* DISPC_LINE_NUMBER */ | 
					
						
							|  |  |  |         s->dispc.line = value & 0x7ff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x064:	/* DISPC_TIMING_H */ | 
					
						
							|  |  |  |         s->dispc.timing[0] = value & 0x0ff0ff3f; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x068:	/* DISPC_TIMING_V */ | 
					
						
							|  |  |  |         s->dispc.timing[1] = value & 0x0ff0ff3f; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x06c:	/* DISPC_POL_FREQ */ | 
					
						
							|  |  |  |         s->dispc.timing[2] = value & 0x0003ffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x070:	/* DISPC_DIVISOR */ | 
					
						
							|  |  |  |         s->dispc.timing[3] = value & 0x00ff00ff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x078:	/* DISPC_SIZE_DIG */ | 
					
						
							|  |  |  |         s->dig.nx = ((value >>  0) & 0x7ff) + 1;		/* PPL */ | 
					
						
							|  |  |  |         s->dig.ny = ((value >> 16) & 0x7ff) + 1;		/* LPP */ | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x07c:	/* DISPC_SIZE_LCD */ | 
					
						
							|  |  |  |         s->lcd.nx = ((value >>  0) & 0x7ff) + 1;		/* PPL */ | 
					
						
							|  |  |  |         s->lcd.ny = ((value >> 16) & 0x7ff) + 1;		/* LPP */ | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x080:	/* DISPC_GFX_BA0 */ | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |         s->dispc.l[0].addr[0] = (hwaddr) value; | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x084:	/* DISPC_GFX_BA1 */ | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |         s->dispc.l[0].addr[1] = (hwaddr) value; | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x088:	/* DISPC_GFX_POSITION */ | 
					
						
							|  |  |  |         s->dispc.l[0].posx = ((value >>  0) & 0x7ff);		/* GFXPOSX */ | 
					
						
							|  |  |  |         s->dispc.l[0].posy = ((value >> 16) & 0x7ff);		/* GFXPOSY */ | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x08c:	/* DISPC_GFX_SIZE */ | 
					
						
							|  |  |  |         s->dispc.l[0].nx = ((value >>  0) & 0x7ff) + 1;		/* GFXSIZEX */ | 
					
						
							|  |  |  |         s->dispc.l[0].ny = ((value >> 16) & 0x7ff) + 1;		/* GFXSIZEY */ | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0a0:	/* DISPC_GFX_ATTRIBUTES */ | 
					
						
							|  |  |  |         s->dispc.l[0].attr = value & 0x7ff; | 
					
						
							|  |  |  |         if (value & (3 << 9)) | 
					
						
							|  |  |  |             fprintf(stderr, "%s: Big-endian pixel format not supported\n", | 
					
						
							| 
									
										
										
										
											2017-11-08 14:56:31 -08:00
										 |  |  |                             __func__); | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |         s->dispc.l[0].enable = value & 1; | 
					
						
							|  |  |  |         s->dispc.l[0].bpp = (value >> 1) & 0xf; | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0a4:	/* DISPC_GFX_FIFO_TRESHOLD */ | 
					
						
							|  |  |  |         s->dispc.l[0].tresh = value & 0x01ff01ff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0ac:	/* DISPC_GFX_ROW_INC */ | 
					
						
							|  |  |  |         s->dispc.l[0].rowinc = value; | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0b0:	/* DISPC_GFX_PIXEL_INC */ | 
					
						
							|  |  |  |         s->dispc.l[0].colinc = value; | 
					
						
							|  |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0b4:	/* DISPC_GFX_WINDOW_SKIP */ | 
					
						
							|  |  |  |         s->dispc.l[0].wininc = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x0b8:	/* DISPC_GFX_TABLE_BA */ | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |         s->dispc.l[0].addr[2] = (hwaddr) value; | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |         s->dispc.invalidate = 1; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x0bc:	/* DISPC_VID1_BA0 */ | 
					
						
							|  |  |  |     case 0x0c0:	/* DISPC_VID1_BA1 */ | 
					
						
							|  |  |  |     case 0x0c4:	/* DISPC_VID1_POSITION */ | 
					
						
							|  |  |  |     case 0x0c8:	/* DISPC_VID1_SIZE */ | 
					
						
							|  |  |  |     case 0x0cc:	/* DISPC_VID1_ATTRIBUTES */ | 
					
						
							|  |  |  |     case 0x0d0:	/* DISPC_VID1_FIFO_TRESHOLD */ | 
					
						
							|  |  |  |     case 0x0d8:	/* DISPC_VID1_ROW_INC */ | 
					
						
							|  |  |  |     case 0x0dc:	/* DISPC_VID1_PIXEL_INC */ | 
					
						
							|  |  |  |     case 0x0e0:	/* DISPC_VID1_FIR */ | 
					
						
							|  |  |  |     case 0x0e4:	/* DISPC_VID1_PICTURE_SIZE */ | 
					
						
							|  |  |  |     case 0x0e8:	/* DISPC_VID1_ACCU0 */ | 
					
						
							|  |  |  |     case 0x0ec:	/* DISPC_VID1_ACCU1 */ | 
					
						
							|  |  |  |     case 0x0f0 ... 0x140:	/* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */ | 
					
						
							|  |  |  |     case 0x14c:	/* DISPC_VID2_BA0 */ | 
					
						
							|  |  |  |     case 0x150:	/* DISPC_VID2_BA1 */ | 
					
						
							|  |  |  |     case 0x154:	/* DISPC_VID2_POSITION */ | 
					
						
							|  |  |  |     case 0x158:	/* DISPC_VID2_SIZE */ | 
					
						
							|  |  |  |     case 0x15c:	/* DISPC_VID2_ATTRIBUTES */ | 
					
						
							|  |  |  |     case 0x160:	/* DISPC_VID2_FIFO_TRESHOLD */ | 
					
						
							|  |  |  |     case 0x168:	/* DISPC_VID2_ROW_INC */ | 
					
						
							|  |  |  |     case 0x16c:	/* DISPC_VID2_PIXEL_INC */ | 
					
						
							|  |  |  |     case 0x170:	/* DISPC_VID2_FIR */ | 
					
						
							|  |  |  |     case 0x174:	/* DISPC_VID2_PICTURE_SIZE */ | 
					
						
							|  |  |  |     case 0x178:	/* DISPC_VID2_ACCU0 */ | 
					
						
							|  |  |  |     case 0x17c:	/* DISPC_VID2_ACCU1 */ | 
					
						
							|  |  |  |     case 0x180 ... 0x1d0:	/* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */ | 
					
						
							|  |  |  |     case 0x1d4:	/* DISPC_DATA_CYCLE1 */ | 
					
						
							|  |  |  |     case 0x1d8:	/* DISPC_DATA_CYCLE2 */ | 
					
						
							|  |  |  |     case 0x1dc:	/* DISPC_DATA_CYCLE3 */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         OMAP_BAD_REG(addr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  | static const MemoryRegionOps omap_disc_ops = { | 
					
						
							|  |  |  |     .read = omap_disc_read, | 
					
						
							|  |  |  |     .write = omap_disc_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void omap_rfbi_transfer_stop(struct omap_dss_s *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (!s->rfbi.busy) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* TODO: in non-Bypass mode we probably need to just deassert the DRQ.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->rfbi.busy = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void omap_rfbi_transfer_start(struct omap_dss_s *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     void *data; | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |     hwaddr len; | 
					
						
							|  |  |  |     hwaddr data_addr; | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     int pitch; | 
					
						
							| 
									
										
										
										
											2009-04-10 14:29:45 +00:00
										 |  |  |     static void *bounce_buffer; | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |     static hwaddr bounce_len; | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (!s->rfbi.enable || s->rfbi.busy) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (s->rfbi.control & (1 << 1)) {				/* BYPASS */ | 
					
						
							|  |  |  |         /* TODO: in non-Bypass mode we probably need to just assert the
 | 
					
						
							|  |  |  |          * DRQ and wait for DMA to write the pixels.  */ | 
					
						
							| 
									
										
										
										
											2020-05-26 08:22:51 +02:00
										 |  |  |         qemu_log_mask(LOG_UNIMP, "%s: Bypass mode unimplemented\n", __func__); | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!(s->dispc.control & (1 << 11)))			/* RFBIMODE */ | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     /* TODO: check that LCD output is enabled in DISPC.  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     s->rfbi.busy = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-10 14:29:45 +00:00
										 |  |  |     len = s->rfbi.pixels * 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     data_addr = s->dispc.l[0].addr[0]; | 
					
						
							| 
									
										
										
										
											2020-02-19 20:20:42 +01:00
										 |  |  |     data = cpu_physical_memory_map(data_addr, &len, false); | 
					
						
							| 
									
										
										
										
											2009-04-10 14:29:45 +00:00
										 |  |  |     if (data && len != s->rfbi.pixels * 2) { | 
					
						
							|  |  |  |         cpu_physical_memory_unmap(data, len, 0, 0); | 
					
						
							|  |  |  |         data = NULL; | 
					
						
							|  |  |  |         len = s->rfbi.pixels * 2; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (!data) { | 
					
						
							|  |  |  |         if (len > bounce_len) { | 
					
						
							| 
									
										
										
										
											2011-08-20 22:09:37 -05:00
										 |  |  |             bounce_buffer = g_realloc(bounce_buffer, len); | 
					
						
							| 
									
										
										
										
											2009-04-10 14:29:45 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         data = bounce_buffer; | 
					
						
							|  |  |  |         cpu_physical_memory_read(data_addr, data, len); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /* TODO bpp */ | 
					
						
							|  |  |  |     s->rfbi.pixels = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* TODO: negative values */ | 
					
						
							|  |  |  |     pitch = s->dispc.l[0].nx + (s->dispc.l[0].rowinc - 1) / 2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) | 
					
						
							|  |  |  |         s->rfbi.chip[0]->block(s->rfbi.chip[0]->opaque, 1, data, len, pitch); | 
					
						
							|  |  |  |     if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) | 
					
						
							|  |  |  |         s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-10 14:29:45 +00:00
										 |  |  |     if (data != bounce_buffer) { | 
					
						
							|  |  |  |         cpu_physical_memory_unmap(data, len, 0, len); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     omap_rfbi_transfer_stop(s); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* TODO */ | 
					
						
							|  |  |  |     s->dispc.irqst |= 1;					/* FRAMEDONE */ | 
					
						
							|  |  |  |     omap_dispc_interrupt_update(s); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t omap_rfbi_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                                unsigned size) | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     struct omap_dss_s *s = (struct omap_dss_s *) opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     if (size != 4) { | 
					
						
							|  |  |  |         return omap_badwidth_read32(opaque, addr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 18:59:50 +00:00
										 |  |  |     switch (addr) { | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     case 0x00:	/* RFBI_REVISION */ | 
					
						
							|  |  |  |         return 0x10; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x10:	/* RFBI_SYSCONFIG */ | 
					
						
							|  |  |  |         return s->rfbi.idlemode; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x14:	/* RFBI_SYSSTATUS */ | 
					
						
							|  |  |  |         return 1 | (s->rfbi.busy << 8);				/* RESETDONE */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x40:	/* RFBI_CONTROL */ | 
					
						
							|  |  |  |         return s->rfbi.control; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x44:	/* RFBI_PIXELCNT */ | 
					
						
							|  |  |  |         return s->rfbi.pixels; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x48:	/* RFBI_LINE_NUMBER */ | 
					
						
							|  |  |  |         return s->rfbi.skiplines; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x58:	/* RFBI_READ */ | 
					
						
							|  |  |  |     case 0x5c:	/* RFBI_STATUS */ | 
					
						
							|  |  |  |         return s->rfbi.rxbuf; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x60:	/* RFBI_CONFIG0 */ | 
					
						
							|  |  |  |         return s->rfbi.config[0]; | 
					
						
							|  |  |  |     case 0x64:	/* RFBI_ONOFF_TIME0 */ | 
					
						
							|  |  |  |         return s->rfbi.time[0]; | 
					
						
							|  |  |  |     case 0x68:	/* RFBI_CYCLE_TIME0 */ | 
					
						
							|  |  |  |         return s->rfbi.time[1]; | 
					
						
							|  |  |  |     case 0x6c:	/* RFBI_DATA_CYCLE1_0 */ | 
					
						
							|  |  |  |         return s->rfbi.data[0]; | 
					
						
							|  |  |  |     case 0x70:	/* RFBI_DATA_CYCLE2_0 */ | 
					
						
							|  |  |  |         return s->rfbi.data[1]; | 
					
						
							|  |  |  |     case 0x74:	/* RFBI_DATA_CYCLE3_0 */ | 
					
						
							|  |  |  |         return s->rfbi.data[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x78:	/* RFBI_CONFIG1 */ | 
					
						
							|  |  |  |         return s->rfbi.config[1]; | 
					
						
							|  |  |  |     case 0x7c:	/* RFBI_ONOFF_TIME1 */ | 
					
						
							|  |  |  |         return s->rfbi.time[2]; | 
					
						
							|  |  |  |     case 0x80:	/* RFBI_CYCLE_TIME1 */ | 
					
						
							|  |  |  |         return s->rfbi.time[3]; | 
					
						
							|  |  |  |     case 0x84:	/* RFBI_DATA_CYCLE1_1 */ | 
					
						
							|  |  |  |         return s->rfbi.data[3]; | 
					
						
							|  |  |  |     case 0x88:	/* RFBI_DATA_CYCLE2_1 */ | 
					
						
							|  |  |  |         return s->rfbi.data[4]; | 
					
						
							|  |  |  |     case 0x8c:	/* RFBI_DATA_CYCLE3_1 */ | 
					
						
							|  |  |  |         return s->rfbi.data[5]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x90:	/* RFBI_VSYNC_WIDTH */ | 
					
						
							|  |  |  |         return s->rfbi.vsync; | 
					
						
							|  |  |  |     case 0x94:	/* RFBI_HSYNC_WIDTH */ | 
					
						
							|  |  |  |         return s->rfbi.hsync; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     OMAP_BAD_REG(addr); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void omap_rfbi_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                             uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     struct omap_dss_s *s = (struct omap_dss_s *) opaque; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     if (size != 4) { | 
					
						
							| 
									
										
										
										
											2015-03-08 19:21:13 +01:00
										 |  |  |         omap_badwidth_write32(opaque, addr, value); | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 18:59:50 +00:00
										 |  |  |     switch (addr) { | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     case 0x10:	/* RFBI_SYSCONFIG */ | 
					
						
							|  |  |  |         if (value & 2)						/* SOFTRESET */ | 
					
						
							|  |  |  |             omap_rfbi_reset(s); | 
					
						
							|  |  |  |         s->rfbi.idlemode = value & 0x19; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x40:	/* RFBI_CONTROL */ | 
					
						
							|  |  |  |         s->rfbi.control = value & 0xf; | 
					
						
							|  |  |  |         s->rfbi.enable = value & 1; | 
					
						
							|  |  |  |         if (value & (1 << 4) &&					/* ITE */ | 
					
						
							|  |  |  |                         !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc)) | 
					
						
							|  |  |  |             omap_rfbi_transfer_start(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x44:	/* RFBI_PIXELCNT */ | 
					
						
							|  |  |  |         s->rfbi.pixels = value; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x48:	/* RFBI_LINE_NUMBER */ | 
					
						
							|  |  |  |         s->rfbi.skiplines = value & 0x7ff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x4c:	/* RFBI_CMD */ | 
					
						
							|  |  |  |         if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) | 
					
						
							|  |  |  |             s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 0, value & 0xffff); | 
					
						
							|  |  |  |         if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) | 
					
						
							|  |  |  |             s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 0, value & 0xffff); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x50:	/* RFBI_PARAM */ | 
					
						
							|  |  |  |         if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) | 
					
						
							|  |  |  |             s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff); | 
					
						
							|  |  |  |         if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) | 
					
						
							|  |  |  |             s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x54:	/* RFBI_DATA */ | 
					
						
							|  |  |  |         /* TODO: take into account the format set up in s->rfbi.config[?] and
 | 
					
						
							|  |  |  |          * s->rfbi.data[?], but special-case the most usual scenario so that | 
					
						
							|  |  |  |          * speed doesn't suffer.  */ | 
					
						
							|  |  |  |         if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) { | 
					
						
							|  |  |  |             s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff); | 
					
						
							|  |  |  |             s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value >> 16); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) { | 
					
						
							|  |  |  |             s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff); | 
					
						
							|  |  |  |             s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value >> 16); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (!-- s->rfbi.pixels) | 
					
						
							|  |  |  |             omap_rfbi_transfer_stop(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x58:	/* RFBI_READ */ | 
					
						
							|  |  |  |         if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) | 
					
						
							|  |  |  |             s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1); | 
					
						
							|  |  |  |         else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) | 
					
						
							| 
									
										
										
										
											2012-01-07 11:59:59 +00:00
										 |  |  |             s->rfbi.rxbuf = s->rfbi.chip[1]->read(s->rfbi.chip[1]->opaque, 1); | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |         if (!-- s->rfbi.pixels) | 
					
						
							|  |  |  |             omap_rfbi_transfer_stop(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x5c:	/* RFBI_STATUS */ | 
					
						
							|  |  |  |         if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) | 
					
						
							|  |  |  |             s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0); | 
					
						
							|  |  |  |         else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) | 
					
						
							| 
									
										
										
										
											2012-01-07 11:59:59 +00:00
										 |  |  |             s->rfbi.rxbuf = s->rfbi.chip[1]->read(s->rfbi.chip[1]->opaque, 0); | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |         if (!-- s->rfbi.pixels) | 
					
						
							|  |  |  |             omap_rfbi_transfer_stop(s); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x60:	/* RFBI_CONFIG0 */ | 
					
						
							|  |  |  |         s->rfbi.config[0] = value & 0x003f1fff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x64:	/* RFBI_ONOFF_TIME0 */ | 
					
						
							|  |  |  |         s->rfbi.time[0] = value & 0x3fffffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x68:	/* RFBI_CYCLE_TIME0 */ | 
					
						
							|  |  |  |         s->rfbi.time[1] = value & 0x0fffffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x6c:	/* RFBI_DATA_CYCLE1_0 */ | 
					
						
							|  |  |  |         s->rfbi.data[0] = value & 0x0f1f0f1f; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x70:	/* RFBI_DATA_CYCLE2_0 */ | 
					
						
							|  |  |  |         s->rfbi.data[1] = value & 0x0f1f0f1f; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x74:	/* RFBI_DATA_CYCLE3_0 */ | 
					
						
							|  |  |  |         s->rfbi.data[2] = value & 0x0f1f0f1f; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x78:	/* RFBI_CONFIG1 */ | 
					
						
							|  |  |  |         s->rfbi.config[1] = value & 0x003f1fff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x7c:	/* RFBI_ONOFF_TIME1 */ | 
					
						
							|  |  |  |         s->rfbi.time[2] = value & 0x3fffffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x80:	/* RFBI_CYCLE_TIME1 */ | 
					
						
							|  |  |  |         s->rfbi.time[3] = value & 0x0fffffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x84:	/* RFBI_DATA_CYCLE1_1 */ | 
					
						
							|  |  |  |         s->rfbi.data[3] = value & 0x0f1f0f1f; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x88:	/* RFBI_DATA_CYCLE2_1 */ | 
					
						
							|  |  |  |         s->rfbi.data[4] = value & 0x0f1f0f1f; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x8c:	/* RFBI_DATA_CYCLE3_1 */ | 
					
						
							|  |  |  |         s->rfbi.data[5] = value & 0x0f1f0f1f; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case 0x90:	/* RFBI_VSYNC_WIDTH */ | 
					
						
							|  |  |  |         s->rfbi.vsync = value & 0xffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 0x94:	/* RFBI_HSYNC_WIDTH */ | 
					
						
							|  |  |  |         s->rfbi.hsync = value & 0xffff; | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         OMAP_BAD_REG(addr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  | static const MemoryRegionOps omap_rfbi_ops = { | 
					
						
							|  |  |  |     .read = omap_rfbi_read, | 
					
						
							|  |  |  |     .write = omap_rfbi_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t omap_venc_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                                unsigned size) | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     if (size != 4) { | 
					
						
							|  |  |  |         return omap_badwidth_read32(opaque, addr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 18:59:50 +00:00
										 |  |  |     switch (addr) { | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     case 0x00:	/* REV_ID */ | 
					
						
							|  |  |  |     case 0x04:	/* STATUS */ | 
					
						
							|  |  |  |     case 0x08:	/* F_CONTROL */ | 
					
						
							|  |  |  |     case 0x10:	/* VIDOUT_CTRL */ | 
					
						
							|  |  |  |     case 0x14:	/* SYNC_CTRL */ | 
					
						
							|  |  |  |     case 0x1c:	/* LLEN */ | 
					
						
							|  |  |  |     case 0x20:	/* FLENS */ | 
					
						
							|  |  |  |     case 0x24:	/* HFLTR_CTRL */ | 
					
						
							|  |  |  |     case 0x28:	/* CC_CARR_WSS_CARR */ | 
					
						
							|  |  |  |     case 0x2c:	/* C_PHASE */ | 
					
						
							|  |  |  |     case 0x30:	/* GAIN_U */ | 
					
						
							|  |  |  |     case 0x34:	/* GAIN_V */ | 
					
						
							|  |  |  |     case 0x38:	/* GAIN_Y */ | 
					
						
							|  |  |  |     case 0x3c:	/* BLACK_LEVEL */ | 
					
						
							|  |  |  |     case 0x40:	/* BLANK_LEVEL */ | 
					
						
							|  |  |  |     case 0x44:	/* X_COLOR */ | 
					
						
							|  |  |  |     case 0x48:	/* M_CONTROL */ | 
					
						
							|  |  |  |     case 0x4c:	/* BSTAMP_WSS_DATA */ | 
					
						
							|  |  |  |     case 0x50:	/* S_CARR */ | 
					
						
							|  |  |  |     case 0x54:	/* LINE21 */ | 
					
						
							|  |  |  |     case 0x58:	/* LN_SEL */ | 
					
						
							|  |  |  |     case 0x5c:	/* L21__WC_CTL */ | 
					
						
							|  |  |  |     case 0x60:	/* HTRIGGER_VTRIGGER */ | 
					
						
							|  |  |  |     case 0x64:	/* SAVID__EAVID */ | 
					
						
							|  |  |  |     case 0x68:	/* FLEN__FAL */ | 
					
						
							|  |  |  |     case 0x6c:	/* LAL__PHASE_RESET */ | 
					
						
							|  |  |  |     case 0x70:	/* HS_INT_START_STOP_X */ | 
					
						
							|  |  |  |     case 0x74:	/* HS_EXT_START_STOP_X */ | 
					
						
							|  |  |  |     case 0x78:	/* VS_INT_START_X */ | 
					
						
							|  |  |  |     case 0x7c:	/* VS_INT_STOP_X__VS_INT_START_Y */ | 
					
						
							|  |  |  |     case 0x80:	/* VS_INT_STOP_Y__VS_INT_START_X */ | 
					
						
							|  |  |  |     case 0x84:	/* VS_EXT_STOP_X__VS_EXT_START_Y */ | 
					
						
							|  |  |  |     case 0x88:	/* VS_EXT_STOP_Y */ | 
					
						
							|  |  |  |     case 0x90:	/* AVID_START_STOP_X */ | 
					
						
							|  |  |  |     case 0x94:	/* AVID_START_STOP_Y */ | 
					
						
							|  |  |  |     case 0xa0:	/* FID_INT_START_X__FID_INT_START_Y */ | 
					
						
							|  |  |  |     case 0xa4:	/* FID_INT_OFFSET_Y__FID_EXT_START_X */ | 
					
						
							|  |  |  |     case 0xa8:	/* FID_EXT_START_Y__FID_EXT_OFFSET_Y */ | 
					
						
							|  |  |  |     case 0xb0:	/* TVDETGP_INT_START_STOP_X */ | 
					
						
							|  |  |  |     case 0xb4:	/* TVDETGP_INT_START_STOP_Y */ | 
					
						
							|  |  |  |     case 0xb8:	/* GEN_CTRL */ | 
					
						
							|  |  |  |     case 0xc4:	/* DAC_TST__DAC_A */ | 
					
						
							|  |  |  |     case 0xc8:	/* DAC_B__DAC_C */ | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     OMAP_BAD_REG(addr); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void omap_venc_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                             uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     if (size != 4) { | 
					
						
							| 
									
										
										
										
											2015-03-08 19:21:13 +01:00
										 |  |  |         omap_badwidth_write32(opaque, addr, size); | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 18:59:50 +00:00
										 |  |  |     switch (addr) { | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     case 0x08:	/* F_CONTROL */ | 
					
						
							|  |  |  |     case 0x10:	/* VIDOUT_CTRL */ | 
					
						
							|  |  |  |     case 0x14:	/* SYNC_CTRL */ | 
					
						
							|  |  |  |     case 0x1c:	/* LLEN */ | 
					
						
							|  |  |  |     case 0x20:	/* FLENS */ | 
					
						
							|  |  |  |     case 0x24:	/* HFLTR_CTRL */ | 
					
						
							|  |  |  |     case 0x28:	/* CC_CARR_WSS_CARR */ | 
					
						
							|  |  |  |     case 0x2c:	/* C_PHASE */ | 
					
						
							|  |  |  |     case 0x30:	/* GAIN_U */ | 
					
						
							|  |  |  |     case 0x34:	/* GAIN_V */ | 
					
						
							|  |  |  |     case 0x38:	/* GAIN_Y */ | 
					
						
							|  |  |  |     case 0x3c:	/* BLACK_LEVEL */ | 
					
						
							|  |  |  |     case 0x40:	/* BLANK_LEVEL */ | 
					
						
							|  |  |  |     case 0x44:	/* X_COLOR */ | 
					
						
							|  |  |  |     case 0x48:	/* M_CONTROL */ | 
					
						
							|  |  |  |     case 0x4c:	/* BSTAMP_WSS_DATA */ | 
					
						
							|  |  |  |     case 0x50:	/* S_CARR */ | 
					
						
							|  |  |  |     case 0x54:	/* LINE21 */ | 
					
						
							|  |  |  |     case 0x58:	/* LN_SEL */ | 
					
						
							|  |  |  |     case 0x5c:	/* L21__WC_CTL */ | 
					
						
							|  |  |  |     case 0x60:	/* HTRIGGER_VTRIGGER */ | 
					
						
							|  |  |  |     case 0x64:	/* SAVID__EAVID */ | 
					
						
							|  |  |  |     case 0x68:	/* FLEN__FAL */ | 
					
						
							|  |  |  |     case 0x6c:	/* LAL__PHASE_RESET */ | 
					
						
							|  |  |  |     case 0x70:	/* HS_INT_START_STOP_X */ | 
					
						
							|  |  |  |     case 0x74:	/* HS_EXT_START_STOP_X */ | 
					
						
							|  |  |  |     case 0x78:	/* VS_INT_START_X */ | 
					
						
							|  |  |  |     case 0x7c:	/* VS_INT_STOP_X__VS_INT_START_Y */ | 
					
						
							|  |  |  |     case 0x80:	/* VS_INT_STOP_Y__VS_INT_START_X */ | 
					
						
							|  |  |  |     case 0x84:	/* VS_EXT_STOP_X__VS_EXT_START_Y */ | 
					
						
							|  |  |  |     case 0x88:	/* VS_EXT_STOP_Y */ | 
					
						
							|  |  |  |     case 0x90:	/* AVID_START_STOP_X */ | 
					
						
							|  |  |  |     case 0x94:	/* AVID_START_STOP_Y */ | 
					
						
							|  |  |  |     case 0xa0:	/* FID_INT_START_X__FID_INT_START_Y */ | 
					
						
							|  |  |  |     case 0xa4:	/* FID_INT_OFFSET_Y__FID_EXT_START_X */ | 
					
						
							|  |  |  |     case 0xa8:	/* FID_EXT_START_Y__FID_EXT_OFFSET_Y */ | 
					
						
							|  |  |  |     case 0xb0:	/* TVDETGP_INT_START_STOP_X */ | 
					
						
							|  |  |  |     case 0xb4:	/* TVDETGP_INT_START_STOP_Y */ | 
					
						
							|  |  |  |     case 0xb8:	/* GEN_CTRL */ | 
					
						
							|  |  |  |     case 0xc4:	/* DAC_TST__DAC_A */ | 
					
						
							|  |  |  |     case 0xc8:	/* DAC_B__DAC_C */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         OMAP_BAD_REG(addr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  | static const MemoryRegionOps omap_venc_ops = { | 
					
						
							|  |  |  |     .read = omap_venc_read, | 
					
						
							|  |  |  |     .write = omap_venc_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static uint64_t omap_im3_read(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                               unsigned size) | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     if (size != 4) { | 
					
						
							|  |  |  |         return omap_badwidth_read32(opaque, addr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 18:59:50 +00:00
										 |  |  |     switch (addr) { | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     case 0x0a8:	/* SBIMERRLOGA */ | 
					
						
							|  |  |  |     case 0x0b0:	/* SBIMERRLOG */ | 
					
						
							|  |  |  |     case 0x190:	/* SBIMSTATE */ | 
					
						
							|  |  |  |     case 0x198:	/* SBTMSTATE_L */ | 
					
						
							|  |  |  |     case 0x19c:	/* SBTMSTATE_H */ | 
					
						
							|  |  |  |     case 0x1a8:	/* SBIMCONFIG_L */ | 
					
						
							|  |  |  |     case 0x1ac:	/* SBIMCONFIG_H */ | 
					
						
							|  |  |  |     case 0x1f8:	/* SBID_L */ | 
					
						
							|  |  |  |     case 0x1fc:	/* SBID_H */ | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     OMAP_BAD_REG(addr); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  | static void omap_im3_write(void *opaque, hwaddr addr, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                            uint64_t value, unsigned size) | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     if (size != 4) { | 
					
						
							| 
									
										
										
										
											2015-03-08 19:21:13 +01:00
										 |  |  |         omap_badwidth_write32(opaque, addr, value); | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-01 18:59:50 +00:00
										 |  |  |     switch (addr) { | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     case 0x0b0:	/* SBIMERRLOG */ | 
					
						
							|  |  |  |     case 0x190:	/* SBIMSTATE */ | 
					
						
							|  |  |  |     case 0x198:	/* SBTMSTATE_L */ | 
					
						
							|  |  |  |     case 0x19c:	/* SBTMSTATE_H */ | 
					
						
							|  |  |  |     case 0x1a8:	/* SBIMCONFIG_L */ | 
					
						
							|  |  |  |     case 0x1ac:	/* SBIMCONFIG_H */ | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         OMAP_BAD_REG(addr); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  | static const MemoryRegionOps omap_im3_ops = { | 
					
						
							|  |  |  |     .read = omap_im3_read, | 
					
						
							|  |  |  |     .write = omap_im3_write, | 
					
						
							|  |  |  |     .endianness = DEVICE_NATIVE_ENDIAN, | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                 MemoryRegion *sysmem, | 
					
						
							| 
									
										
										
										
											2012-10-23 12:30:10 +02:00
										 |  |  |                 hwaddr l3_base, | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |                 qemu_irq irq, qemu_irq drq, | 
					
						
							|  |  |  |                 omap_clk fck1, omap_clk fck2, omap_clk ck54m, | 
					
						
							|  |  |  |                 omap_clk ick1, omap_clk ick2) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
											  
											
												arm: Use g_new() & friends where that makes obvious sense
g_new(T, n) is neater than g_malloc(sizeof(T) * n).  It's also safer,
for two reasons.  One, it catches multiplication overflowing size_t.
Two, it returns T * rather than void *, which lets the compiler catch
more type errors.
This commit only touches allocations with size arguments of the form
sizeof(T).
Coccinelle semantic patch:
    @@
    type T;
    @@
    -g_malloc(sizeof(T))
    +g_new(T, 1)
    @@
    type T;
    @@
    -g_try_malloc(sizeof(T))
    +g_try_new(T, 1)
    @@
    type T;
    @@
    -g_malloc0(sizeof(T))
    +g_new0(T, 1)
    @@
    type T;
    @@
    -g_try_malloc0(sizeof(T))
    +g_try_new0(T, 1)
    @@
    type T;
    expression n;
    @@
    -g_malloc(sizeof(T) * (n))
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc(sizeof(T) * (n))
    +g_try_new(T, n)
    @@
    type T;
    expression n;
    @@
    -g_malloc0(sizeof(T) * (n))
    +g_new0(T, n)
    @@
    type T;
    expression n;
    @@
    -g_try_malloc0(sizeof(T) * (n))
    +g_try_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -g_realloc(p, sizeof(T) * (n))
    +g_renew(T, p, n)
    @@
    type T;
    expression p, n;
    @@
    -g_try_realloc(p, sizeof(T) * (n))
    +g_try_renew(T, p, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new(T, n)
    +g_new(T, n)
    @@
    type T;
    expression n;
    @@
    -(T *)g_new0(T, n)
    +g_new0(T, n)
    @@
    type T;
    expression p, n;
    @@
    -(T *)g_renew(T, p, n)
    +g_renew(T, p, n)
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1440524394-15640-1-git-send-email-armbru@redhat.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
											
										 
											2015-09-07 10:39:27 +01:00
										 |  |  |     struct omap_dss_s *s = g_new0(struct omap_dss_s, 1); | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     s->irq = irq; | 
					
						
							|  |  |  |     s->drq = drq; | 
					
						
							|  |  |  |     omap_dss_reset(s); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->iomem_diss1, NULL, &omap_diss_ops, s, "omap.diss1", | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                           omap_l4_region_size(ta, 0)); | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->iomem_disc1, NULL, &omap_disc_ops, s, "omap.disc1", | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                           omap_l4_region_size(ta, 1)); | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->iomem_rfbi1, NULL, &omap_rfbi_ops, s, "omap.rfbi1", | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                           omap_l4_region_size(ta, 2)); | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->iomem_venc1, NULL, &omap_venc_ops, s, "omap.venc1", | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                           omap_l4_region_size(ta, 3)); | 
					
						
							| 
									
										
										
										
											2013-06-06 05:41:28 -04:00
										 |  |  |     memory_region_init_io(&s->iomem_im3, NULL, &omap_im3_ops, s, | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |                           "omap.im3", 0x1000); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-28 15:40:49 +02:00
										 |  |  |     omap_l4_attach(ta, 0, &s->iomem_diss1); | 
					
						
							|  |  |  |     omap_l4_attach(ta, 1, &s->iomem_disc1); | 
					
						
							|  |  |  |     omap_l4_attach(ta, 2, &s->iomem_rfbi1); | 
					
						
							|  |  |  |     omap_l4_attach(ta, 3, &s->iomem_venc1); | 
					
						
							| 
									
										
										
										
											2011-11-28 13:10:11 +02:00
										 |  |  |     memory_region_add_subregion(sysmem, l3_base, &s->iomem_im3); | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2009-01-16 19:04:14 +00:00
										 |  |  |     s->state = graphic_console_init(omap_update_display, | 
					
						
							|  |  |  |                                     omap_invalidate_display, omap_screen_dump, s); | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return s; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (cs < 0 || cs > 1) | 
					
						
							| 
									
										
										
										
											2017-11-08 14:56:31 -08:00
										 |  |  |         hw_error("%s: wrong CS %i\n", __func__, cs); | 
					
						
							| 
									
										
										
										
											2008-04-14 21:05:22 +00:00
										 |  |  |     s->rfbi.chip[cs] = chip; | 
					
						
							|  |  |  | } |