tc6393xb: non-accelerated FB support (Dmitry Baryshkov).
Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5617 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									4ea29f749d
								
							
						
					
					
						commit
						64b40bc54a
					
				| @ -66,9 +66,11 @@ void tusb6010_power(struct tusb_s *s, int on); | ||||
| 
 | ||||
| /* tc6393xb.c */ | ||||
| struct tc6393xb_s; | ||||
| struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq); | ||||
| #define TC6393XB_RAM	0x110000 /* amount of ram for Video and USB */ | ||||
| struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq, DisplayState *ds); | ||||
| void tc6393xb_gpio_out_set(struct tc6393xb_s *s, int line, | ||||
|                     qemu_irq handler); | ||||
| qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s); | ||||
| qemu_irq tc6393xb_l3v_get(struct tc6393xb_s *s); | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										122
									
								
								hw/tc6393xb.c
									
									
									
									
									
								
							
							
						
						
									
										122
									
								
								hw/tc6393xb.c
									
									
									
									
									
								
							| @ -11,6 +11,8 @@ | ||||
| #include "pxa.h" | ||||
| #include "devices.h" | ||||
| #include "flash.h" | ||||
| #include "console.h" | ||||
| #include "pixel_ops.h" | ||||
| 
 | ||||
| #define IRQ_TC6393_NAND		0 | ||||
| #define IRQ_TC6393_MMC		1 | ||||
| @ -119,6 +121,14 @@ struct tc6393xb_s { | ||||
|     uint32_t nand_phys; | ||||
|     struct nand_flash_s *flash; | ||||
|     struct ecc_state_s ecc; | ||||
| 
 | ||||
|     DisplayState *ds; | ||||
|     QEMUConsole *console; | ||||
|     ram_addr_t vram_addr; | ||||
|     uint32_t scr_width, scr_height; /* in pixels */ | ||||
|     qemu_irq l3v; | ||||
|     unsigned blank : 1, | ||||
|              blanked : 1; | ||||
| }; | ||||
| 
 | ||||
| qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s) | ||||
| @ -164,6 +174,18 @@ static void tc6393xb_gpio_handler_update(struct tc6393xb_s *s) | ||||
|     s->prev_level = level; | ||||
| } | ||||
| 
 | ||||
| qemu_irq tc6393xb_l3v_get(struct tc6393xb_s *s) | ||||
| { | ||||
|     return s->l3v; | ||||
| } | ||||
| 
 | ||||
| static void tc6393xb_l3v(void *opaque, int line, int level) | ||||
| { | ||||
|     struct tc6393xb_s *s = opaque; | ||||
|     s->blank = !level; | ||||
|     fprintf(stderr, "L3V: %d\n", level); | ||||
| } | ||||
| 
 | ||||
| static void tc6393xb_sub_irq(void *opaque, int line, int level) { | ||||
|     struct tc6393xb_s *s = opaque; | ||||
|     uint8_t isr = s->scr.ISR; | ||||
| @ -395,6 +417,85 @@ static void tc6393xb_nand_writeb(struct tc6393xb_s *s, target_phys_addr_t addr, | ||||
| 					(uint32_t) addr, value & 0xff); | ||||
| } | ||||
| 
 | ||||
| #define BITS 8 | ||||
| #include "tc6393xb_template.h" | ||||
| #define BITS 15 | ||||
| #include "tc6393xb_template.h" | ||||
| #define BITS 16 | ||||
| #include "tc6393xb_template.h" | ||||
| #define BITS 24 | ||||
| #include "tc6393xb_template.h" | ||||
| #define BITS 32 | ||||
| #include "tc6393xb_template.h" | ||||
| 
 | ||||
| static void tc6393xb_draw_graphic(struct tc6393xb_s *s, int full_update) | ||||
| { | ||||
|     switch (s->ds->depth) { | ||||
|         case 8: | ||||
|             tc6393xb_draw_graphic8(s); | ||||
|             break; | ||||
|         case 15: | ||||
|             tc6393xb_draw_graphic15(s); | ||||
|             break; | ||||
|         case 16: | ||||
|             tc6393xb_draw_graphic16(s); | ||||
|             break; | ||||
|         case 24: | ||||
|             tc6393xb_draw_graphic24(s); | ||||
|             break; | ||||
|         case 32: | ||||
|             tc6393xb_draw_graphic32(s); | ||||
|             break; | ||||
|         default: | ||||
|             printf("tc6393xb: unknown depth %d\n", s->ds->depth); | ||||
|             return; | ||||
|     } | ||||
| 
 | ||||
|     dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height); | ||||
| } | ||||
| 
 | ||||
| static void tc6393xb_draw_blank(struct tc6393xb_s *s, int full_update) | ||||
| { | ||||
|     int i, w; | ||||
|     uint8_t *d; | ||||
| 
 | ||||
|     if (!full_update) | ||||
|         return; | ||||
| 
 | ||||
|     w = s->scr_width * ((s->ds->depth + 7) >> 3); | ||||
|     d = s->ds->data; | ||||
|     for(i = 0; i < s->scr_height; i++) { | ||||
|         memset(d, 0, w); | ||||
|         d += s->ds->linesize; | ||||
|     } | ||||
| 
 | ||||
|     dpy_update(s->ds, 0, 0, s->scr_width, s->scr_height); | ||||
| } | ||||
| 
 | ||||
| static void tc6393xb_update_display(void *opaque) | ||||
| { | ||||
|     struct tc6393xb_s *s = opaque; | ||||
|     int full_update; | ||||
| 
 | ||||
|     if (s->scr_width == 0 || s->scr_height == 0) | ||||
|         return; | ||||
| 
 | ||||
|     full_update = 0; | ||||
|     if (s->blanked != s->blank) { | ||||
|         s->blanked = s->blank; | ||||
|         full_update = 1; | ||||
|     } | ||||
|     if (s->scr_width != s->ds->width || s->scr_height != s->ds->height) { | ||||
|         qemu_console_resize(s->console, s->scr_width, s->scr_height); | ||||
|         full_update = 1; | ||||
|     } | ||||
|     if (s->blanked) | ||||
|         tc6393xb_draw_blank(s, full_update); | ||||
|     else | ||||
|         tc6393xb_draw_graphic(s, full_update); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) { | ||||
|     struct tc6393xb_s *s = opaque; | ||||
|     addr -= s->target_base; | ||||
| @ -465,7 +566,7 @@ static void tc6393xb_writel(void *opaque, target_phys_addr_t addr, uint32_t valu | ||||
|     tc6393xb_writeb(opaque, addr + 3, value >> 24); | ||||
| } | ||||
| 
 | ||||
| struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq) | ||||
| struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq, DisplayState *ds) | ||||
| { | ||||
|     int iomemtype; | ||||
|     struct tc6393xb_s *s; | ||||
| @ -485,13 +586,30 @@ struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq) | ||||
|     s->irq = irq; | ||||
|     s->gpio_in = qemu_allocate_irqs(tc6393xb_gpio_set, s, TC6393XB_GPIOS); | ||||
| 
 | ||||
|     s->l3v = *qemu_allocate_irqs(tc6393xb_l3v, s, 1); | ||||
|     s->blanked = 1; | ||||
| 
 | ||||
|     s->sub_irqs = qemu_allocate_irqs(tc6393xb_sub_irq, s, TC6393XB_NR_IRQS); | ||||
| 
 | ||||
|     s->flash = nand_init(NAND_MFR_TOSHIBA, 0x76); | ||||
| 
 | ||||
|     iomemtype = cpu_register_io_memory(0, tc6393xb_readfn, | ||||
|                     tc6393xb_writefn, s); | ||||
|     cpu_register_physical_memory(s->target_base, 0x200000, iomemtype); | ||||
|     cpu_register_physical_memory(s->target_base, 0x10000, iomemtype); | ||||
| 
 | ||||
|     if (ds) { | ||||
|         s->ds = ds; | ||||
|         s->vram_addr = qemu_ram_alloc(0x100000); | ||||
|         cpu_register_physical_memory(s->target_base + 0x100000, 0x100000, s->vram_addr); | ||||
|         s->scr_width = 480; | ||||
|         s->scr_height = 640; | ||||
|         s->console = graphic_console_init(ds, | ||||
|                 tc6393xb_update_display, | ||||
|                 NULL, /* invalidate */ | ||||
|                 NULL, /* screen_dump */ | ||||
|                 NULL, /* text_update */ | ||||
|                 s); | ||||
|     } | ||||
| 
 | ||||
|     return s; | ||||
| } | ||||
|  | ||||
							
								
								
									
										72
									
								
								hw/tc6393xb_template.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								hw/tc6393xb_template.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | ||||
| /*
 | ||||
|  * Toshiba TC6393XB I/O Controller. | ||||
|  * Found in Sharp Zaurus SL-6000 (tosa) or some | ||||
|  * Toshiba e-Series PDAs. | ||||
|  * | ||||
|  * FB support code. Based on G364 fb emulator | ||||
|  * | ||||
|  * Copyright (c) 2007 Hervé Poussineau | ||||
|  * | ||||
|  * 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 of | ||||
|  * the License, or (at your option) any later version. | ||||
|  * | ||||
|  * 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. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||||
|  * MA 02111-1307 USA | ||||
|  */ | ||||
| 
 | ||||
| #if BITS == 8 | ||||
| # define SET_PIXEL(addr, color)	*(uint8_t*)addr = color; | ||||
| #elif BITS == 15 || BITS == 16 | ||||
| # define SET_PIXEL(addr, color)	*(uint16_t*)addr = color; | ||||
| #elif BITS == 24 | ||||
| # define SET_PIXEL(addr, color)	\ | ||||
|     addr[0] = color; addr[1] = (color) >> 8; addr[2] = (color) >> 16; | ||||
| #elif BITS == 32 | ||||
| # define SET_PIXEL(addr, color)	*(uint32_t*)addr = color; | ||||
| #else | ||||
| # error unknown bit depth | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| static void glue(tc6393xb_draw_graphic, BITS)(struct tc6393xb_s *s) | ||||
| { | ||||
|     int i; | ||||
|     int w_display; | ||||
|     uint16_t *data_buffer; | ||||
|     uint8_t *data_display; | ||||
| 
 | ||||
|     data_buffer = (uint16_t*)(phys_ram_base + s->vram_addr); | ||||
|     w_display = s->scr_width * BITS / 8; | ||||
|     data_display = s->ds->data; | ||||
|     for(i = 0; i < s->scr_height; i++) { | ||||
| #if (BITS == 16) | ||||
|         memcpy(data_display, data_buffer, s->scr_width * 2); | ||||
|         data_buffer += s->scr_width; | ||||
|         data_display += s->ds->linesize; | ||||
| #else | ||||
|         int j; | ||||
|         for (j = 0; j < s->scr_width; j++, data_display += BITS / 8, data_buffer++) { | ||||
|             uint16_t color = *data_buffer; | ||||
|             uint32_t dest_color = glue(rgb_to_pixel, BITS)( | ||||
|                            ((color & 0xf800) * 0x108) >> 11, | ||||
|                            ((color & 0x7e0) * 0x41) >> 9, | ||||
|                            ((color & 0x1f) * 0x21) >> 2 | ||||
|                            ); | ||||
|             SET_PIXEL(data_display, dest_color); | ||||
|         } | ||||
| #endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #undef BITS | ||||
| #undef SET_PIXEL | ||||
| 
 | ||||
							
								
								
									
										17
									
								
								hw/tosa.c
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								hw/tosa.c
									
									
									
									
									
								
							| @ -38,6 +38,7 @@ | ||||
| #define TOSA_GPIO_BT_LED		(TOSA_SCOOP_JC_GPIO_BASE + 0) | ||||
| #define TOSA_GPIO_NOTE_LED		(TOSA_SCOOP_JC_GPIO_BASE + 1) | ||||
| #define TOSA_GPIO_CHRG_ERR_LED		(TOSA_SCOOP_JC_GPIO_BASE + 2) | ||||
| #define TOSA_GPIO_TC6393XB_L3V_ON	(TOSA_SCOOP_JC_GPIO_BASE + 5) | ||||
| #define TOSA_GPIO_WLAN_LED		(TOSA_SCOOP_JC_GPIO_BASE + 7) | ||||
| 
 | ||||
| #define	DAC_BASE	0x4e | ||||
| @ -84,7 +85,8 @@ static void tosa_out_switch(void *opaque, int line, int level) | ||||
| 
 | ||||
| static void tosa_gpio_setup(struct pxa2xx_state_s *cpu, | ||||
|                 struct scoop_info_s *scp0, | ||||
|                 struct scoop_info_s *scp1) | ||||
|                 struct scoop_info_s *scp1, | ||||
|                 struct tc6393xb_s *tmio) | ||||
| { | ||||
|     qemu_irq *outsignals = qemu_allocate_irqs(tosa_out_switch, cpu, 4); | ||||
|     /* MMC/SD host */ | ||||
| @ -108,6 +110,8 @@ static void tosa_gpio_setup(struct pxa2xx_state_s *cpu, | ||||
|     scoop_gpio_out_set(scp1, TOSA_GPIO_NOTE_LED, outsignals[1]); | ||||
|     scoop_gpio_out_set(scp1, TOSA_GPIO_CHRG_ERR_LED, outsignals[2]); | ||||
|     scoop_gpio_out_set(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]); | ||||
| 
 | ||||
|     scoop_gpio_out_set(scp1, TOSA_GPIO_TC6393XB_L3V_ON, tc6393xb_l3v_get(tmio)); | ||||
| } | ||||
| 
 | ||||
| static uint32_t tosa_ssp_read(void *opaque) | ||||
| @ -198,9 +202,10 @@ static void tosa_init(ram_addr_t ram_size, int vga_ram_size, | ||||
|                 const char *initrd_filename, const char *cpu_model) | ||||
| { | ||||
|     struct pxa2xx_state_s *cpu; | ||||
|     struct tc6393xb_s *tmio; | ||||
|     struct scoop_info_s *scp0, *scp1; | ||||
| 
 | ||||
|     if (ram_size < (TOSA_RAM + TOSA_ROM + PXA2XX_INTERNAL_SIZE)) { | ||||
|     if (ram_size < (TOSA_RAM + TOSA_ROM + PXA2XX_INTERNAL_SIZE + TC6393XB_RAM)) { | ||||
|         fprintf(stderr, "This platform requires %i bytes of memory\n", | ||||
|                 TOSA_RAM + TOSA_ROM + PXA2XX_INTERNAL_SIZE); | ||||
|         exit(1); | ||||
| @ -214,12 +219,14 @@ static void tosa_init(ram_addr_t ram_size, int vga_ram_size, | ||||
|     cpu_register_physical_memory(0, TOSA_ROM, | ||||
|                     qemu_ram_alloc(TOSA_ROM) | IO_MEM_ROM); | ||||
| 
 | ||||
|     tc6393xb_init(0x10000000, pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_TC6393XB_INT]); | ||||
|     tmio = tc6393xb_init(0x10000000, | ||||
|             pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_TC6393XB_INT], | ||||
|             ds); | ||||
| 
 | ||||
|     scp0 = scoop_init(cpu, 0, 0x08800000); | ||||
|     scp1 = scoop_init(cpu, 1, 0x14800040); | ||||
| 
 | ||||
|     tosa_gpio_setup(cpu, scp0, scp1); | ||||
|     tosa_gpio_setup(cpu, scp0, scp1, tmio); | ||||
| 
 | ||||
|     tosa_microdrive_attach(cpu); | ||||
| 
 | ||||
| @ -240,5 +247,5 @@ QEMUMachine tosapda_machine = { | ||||
|     .name = "tosa", | ||||
|     .desc = "Tosa PDA (PXA255)", | ||||
|     .init = tosa_init, | ||||
|     .ram_require = TOSA_RAM + TOSA_ROM + PXA2XX_INTERNAL_SIZE + RAMSIZE_FIXED, | ||||
|     .ram_require = TOSA_RAM + TOSA_ROM + PXA2XX_INTERNAL_SIZE + RAMSIZE_FIXED + TC6393XB_RAM, | ||||
| }; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 balrog
						balrog