* [Qemu-devel] [PATCH] scoop: GPRR reports the state of GPIO lines @ 2008-11-02 13:16 Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tc6393xb: initial support for nand Dmitry Baryshkov 2008-11-02 14:45 ` [Qemu-devel] Re: [PATCH] scoop: GPRR reports the state of GPIO lines Dmitry Baryshkov 0 siblings, 2 replies; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 13:16 UTC (permalink / raw) To: qemu-devel; +Cc: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- hw/zaurus.c | 16 +++++++--------- 1 files changed, 7 insertions(+), 9 deletions(-) diff --git a/hw/zaurus.c b/hw/zaurus.c index c475eaa..26e138d 100644 --- a/hw/zaurus.c +++ b/hw/zaurus.c @@ -46,7 +46,6 @@ struct scoop_info_s { uint16_t irr; uint16_t imr; uint16_t isr; - uint16_t gprr; }; #define SCOOP_MCR 0x00 @@ -99,9 +98,8 @@ static uint32_t scoop_readb(void *opaque, target_phys_addr_t addr) case SCOOP_GPCR: return s->gpio_dir; case SCOOP_GPWR: - return s->gpio_level; case SCOOP_GPRR: - return s->gprr; + return s->gpio_level; default: zaurus_printf("Bad register offset " REG_FMT "\n", addr); } @@ -144,12 +142,10 @@ static void scoop_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) scoop_gpio_handler_update(s); break; case SCOOP_GPWR: + case SCOOP_GPRR: // GPRR is probably R/O in real HW s->gpio_level = value & s->gpio_dir; scoop_gpio_handler_update(s); break; - case SCOOP_GPRR: - s->gprr = value; - break; default: zaurus_printf("Bad register offset " REG_FMT "\n", addr); } @@ -194,6 +190,7 @@ void scoop_gpio_out_set(struct scoop_info_s *s, int line, static void scoop_save(QEMUFile *f, void *opaque) { struct scoop_info_s *s = (struct scoop_info_s *) opaque; + uint16_t dummy = 0; qemu_put_be16s(f, &s->status); qemu_put_be16s(f, &s->power); qemu_put_be32s(f, &s->gpio_level); @@ -205,11 +202,11 @@ static void scoop_save(QEMUFile *f, void *opaque) qemu_put_be16s(f, &s->irr); qemu_put_be16s(f, &s->imr); qemu_put_be16s(f, &s->isr); - qemu_put_be16s(f, &s->gprr); } static int scoop_load(QEMUFile *f, void *opaque, int version_id) { + uint16_t dummy; struct scoop_info_s *s = (struct scoop_info_s *) opaque; qemu_get_be16s(f, &s->status); qemu_get_be16s(f, &s->power); @@ -222,7 +219,8 @@ static int scoop_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be16s(f, &s->irr); qemu_get_be16s(f, &s->imr); qemu_get_be16s(f, &s->isr); - qemu_get_be16s(f, &s->gprr); + if (version_id < 1) + qemu_get_be16s(f, &dummy); return 0; } @@ -243,7 +241,7 @@ struct scoop_info_s *scoop_init(struct pxa2xx_state_s *cpu, iomemtype = cpu_register_io_memory(0, scoop_readfn, scoop_writefn, s); cpu_register_physical_memory(s->target_base, 0x1000, iomemtype); - register_savevm("scoop", instance, 0, scoop_save, scoop_load, s); + register_savevm("scoop", instance, 1, scoop_save, scoop_load, s); return s; } -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH] tc6393xb: initial support for nand 2008-11-02 13:16 [Qemu-devel] [PATCH] scoop: GPRR reports the state of GPIO lines Dmitry Baryshkov @ 2008-11-02 13:16 ` Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: support leds Dmitry Baryshkov 2008-11-02 14:45 ` [Qemu-devel] Re: [PATCH] scoop: GPRR reports the state of GPIO lines Dmitry Baryshkov 1 sibling, 1 reply; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 13:16 UTC (permalink / raw) To: qemu-devel; +Cc: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- hw/tc6393xb.c | 244 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 221 insertions(+), 23 deletions(-) diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c index 01ddb11..919a922 100644 --- a/hw/tc6393xb.c +++ b/hw/tc6393xb.c @@ -10,6 +10,15 @@ #include "hw.h" #include "pxa.h" #include "devices.h" +#include "flash.h" + +#define IRQ_TC6393_NAND 0 +#define IRQ_TC6393_MMC 1 +#define IRQ_TC6393_OHCI 2 +#define IRQ_TC6393_SERIAL 3 +#define IRQ_TC6393_FB 4 + +#define TC6393XB_NR_IRQS 8 #define TC6393XB_GPIOS 16 @@ -40,8 +49,37 @@ #define SCR_CONFIG 0xfc /* b Configuration Control */ #define SCR_DEBUG 0xff /* b Debug */ +#define NAND_CFG_COMMAND 0x04 /* w Command */ +#define NAND_CFG_BASE 0x10 /* l Control Base Address */ +#define NAND_CFG_INTP 0x3d /* b Interrupt Pin */ +#define NAND_CFG_INTE 0x48 /* b Int Enable */ +#define NAND_CFG_EC 0x4a /* b Event Control */ +#define NAND_CFG_ICC 0x4c /* b Internal Clock Control */ +#define NAND_CFG_ECCC 0x5b /* b ECC Control */ +#define NAND_CFG_NFTC 0x60 /* b NAND Flash Transaction Control */ +#define NAND_CFG_NFM 0x61 /* b NAND Flash Monitor */ +#define NAND_CFG_NFPSC 0x62 /* b NAND Flash Power Supply Control */ +#define NAND_CFG_NFDC 0x63 /* b NAND Flash Detect Control */ + +#define NAND_DATA 0x00 /* l Data */ +#define NAND_MODE 0x04 /* b Mode */ +#define NAND_STATUS 0x05 /* b Status */ +#define NAND_ISR 0x06 /* b Interrupt Status */ +#define NAND_IMR 0x07 /* b Interrupt Mask */ + +#define NAND_MODE_WP 0x80 +#define NAND_MODE_CE 0x10 +#define NAND_MODE_ALE 0x02 +#define NAND_MODE_CLE 0x01 +#define NAND_MODE_ECC_MASK 0x60 +#define NAND_MODE_ECC_EN 0x20 +#define NAND_MODE_ECC_READ 0x40 +#define NAND_MODE_ECC_RST 0x60 + struct tc6393xb_s { target_phys_addr_t target_base; + qemu_irq irq; + qemu_irq *sub_irqs; struct { uint8_t ISR; uint8_t IMR; @@ -71,6 +109,16 @@ struct tc6393xb_s { uint32_t prev_level; qemu_irq handler[TC6393XB_GPIOS]; qemu_irq *gpio_in; + + struct { + uint8_t mode; + uint8_t isr; + uint8_t imr; + } nand; + int nand_enable; + uint32_t nand_phys; + struct nand_flash_s *flash; + struct ecc_state_s ecc; }; qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s) @@ -116,6 +164,17 @@ static void tc6393xb_gpio_handler_update(struct tc6393xb_s *s) s->prev_level = level; } +static void tc6393xb_sub_irq(void *opaque, int line, int level) { + struct tc6393xb_s *s = opaque; + uint8_t isr = s->scr.ISR; + if (level) + isr |= 1 << line; + else + isr &= ~(1 << line); + s->scr.ISR = isr; + qemu_set_irq(s->irq, isr & s->scr.IMR); +} + #define SCR_REG_B(N) \ case SCR_ ##N: return s->scr.N #define SCR_REG_W(N) \ @@ -131,10 +190,8 @@ static void tc6393xb_gpio_handler_update(struct tc6393xb_s *s) case SCR_ ##N(1): return s->scr.N[1]; \ case SCR_ ##N(2): return s->scr.N[2] -static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) +static uint32_t tc6393xb_scr_readb(struct tc6393xb_s *s, target_phys_addr_t addr) { - struct tc6393xb_s *s = opaque; - addr -= s->target_base; switch (addr) { case SCR_REVID: return 3; @@ -171,7 +228,7 @@ static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) SCR_REG_B(CONFIG); SCR_REG_B(DEBUG); } - fprintf(stderr, "tc6393xb: unhandled read at %08x\n", (uint32_t) addr); + fprintf(stderr, "tc6393xb_scr: unhandled read at %08x\n", (uint32_t) addr); return 0; } #undef SCR_REG_B @@ -180,24 +237,22 @@ static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) #undef SCR_REG_A #define SCR_REG_B(N) \ - case SCR_ ##N: s->scr.N = value; break; + case SCR_ ##N: s->scr.N = value; return; #define SCR_REG_W(N) \ - case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); break; \ - case SCR_ ##N + 1: s->scr.N = (s->scr.N & 0xff) | (value << 8); break + case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); return; \ + case SCR_ ##N + 1: s->scr.N = (s->scr.N & 0xff) | (value << 8); return #define SCR_REG_L(N) \ - case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); break; \ - case SCR_ ##N + 1: s->scr.N = (s->scr.N & ~(0xff << 8)) | (value & (0xff << 8)); break; \ - case SCR_ ##N + 2: s->scr.N = (s->scr.N & ~(0xff << 16)) | (value & (0xff << 16)); break; \ - case SCR_ ##N + 3: s->scr.N = (s->scr.N & ~(0xff << 24)) | (value & (0xff << 24)); break; + case SCR_ ##N: s->scr.N = (s->scr.N & ~0xff) | (value & 0xff); return; \ + case SCR_ ##N + 1: s->scr.N = (s->scr.N & ~(0xff << 8)) | (value & (0xff << 8)); return; \ + case SCR_ ##N + 2: s->scr.N = (s->scr.N & ~(0xff << 16)) | (value & (0xff << 16)); return; \ + case SCR_ ##N + 3: s->scr.N = (s->scr.N & ~(0xff << 24)) | (value & (0xff << 24)); return; #define SCR_REG_A(N) \ - case SCR_ ##N(0): s->scr.N[0] = value; break; \ - case SCR_ ##N(1): s->scr.N[1] = value; break; \ - case SCR_ ##N(2): s->scr.N[2] = value; break + case SCR_ ##N(0): s->scr.N[0] = value; return; \ + case SCR_ ##N(1): s->scr.N[1] = value; return; \ + case SCR_ ##N(2): s->scr.N[2] = value; return -static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) +static void tc6393xb_scr_writeb(struct tc6393xb_s *s, target_phys_addr_t addr, uint32_t value) { - struct tc6393xb_s *s = opaque; - addr -= s->target_base; switch (addr) { SCR_REG_B(ISR); SCR_REG_B(IMR); @@ -212,13 +267,13 @@ static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t valu case SCR_GPO_DSR(2): s->gpio_level = (s->gpio_level & ~(0xff << ((addr - SCR_GPO_DSR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DSR(0))*8)); tc6393xb_gpio_handler_update(s); - break; + return; case SCR_GPO_DOECR(0): case SCR_GPO_DOECR(1): case SCR_GPO_DOECR(2): s->gpio_dir = (s->gpio_dir & ~(0xff << ((addr - SCR_GPO_DOECR(0))*8))) | ((value & 0xff) << ((addr - SCR_GPO_DOECR(0))*8)); tc6393xb_gpio_handler_update(s); - break; + return; SCR_REG_A(GP_IARCR); SCR_REG_A(GP_IARLCR); SCR_REG_A(GPI_BCR); @@ -233,17 +288,155 @@ static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t valu SCR_REG_W(MCR); SCR_REG_B(CONFIG); SCR_REG_B(DEBUG); - default: - fprintf(stderr, "tc6393xb: unhandled write at %08x: %02x\n", - (uint32_t) addr, value & 0xff); - break; } + fprintf(stderr, "tc6393xb_scr: unhandled write at %08x: %02x\n", + (uint32_t) addr, value & 0xff); } #undef SCR_REG_B #undef SCR_REG_W #undef SCR_REG_L #undef SCR_REG_A +static void tc6393xb_nand_irq(struct tc6393xb_s *s) { + qemu_set_irq(s->sub_irqs[IRQ_TC6393_NAND], + (s->nand.imr & 0x80) && (s->nand.imr & s->nand.isr)); +} + +static uint32_t tc6393xb_nand_cfg_readb(struct tc6393xb_s *s, target_phys_addr_t addr) { + switch (addr) { + case NAND_CFG_COMMAND: + return s->nand_enable ? 2 : 0; + case NAND_CFG_BASE: + case NAND_CFG_BASE + 1: + case NAND_CFG_BASE + 2: + case NAND_CFG_BASE + 3: + return s->nand_phys >> (addr - NAND_CFG_BASE); + } + fprintf(stderr, "tc6393xb_nand_cfg: unhandled read at %08x\n", (uint32_t) addr); + return 0; +} +static void tc6393xb_nand_cfg_writeb(struct tc6393xb_s *s, target_phys_addr_t addr, uint32_t value) { + switch (addr) { + case NAND_CFG_COMMAND: + s->nand_enable = (value & 0x2); + return; + case NAND_CFG_BASE: + case NAND_CFG_BASE + 1: + case NAND_CFG_BASE + 2: + case NAND_CFG_BASE + 3: + s->nand_phys &= ~(0xff << ((addr - NAND_CFG_BASE) * 8)); + s->nand_phys |= (value & 0xff) << ((addr - NAND_CFG_BASE) * 8); + return; + } + fprintf(stderr, "tc6393xb_nand_cfg: unhandled write at %08x: %02x\n", + (uint32_t) addr, value & 0xff); +} + +static uint32_t tc6393xb_nand_readb(struct tc6393xb_s *s, target_phys_addr_t addr) { + switch (addr) { + case NAND_DATA + 0: + case NAND_DATA + 1: + case NAND_DATA + 2: + case NAND_DATA + 3: + return nand_getio(s->flash); + case NAND_MODE: + return s->nand.mode; + case NAND_STATUS: + return 0x14; + case NAND_ISR: + return s->nand.isr; + case NAND_IMR: + return s->nand.imr; + } + fprintf(stderr, "tc6393xb_nand: unhandled read at %08x\n", (uint32_t) addr); + return 0; +} +static void tc6393xb_nand_writeb(struct tc6393xb_s *s, target_phys_addr_t addr, uint32_t value) { +// fprintf(stderr, "tc6393xb_nand: write at %08x: %02x\n", +// (uint32_t) addr, value & 0xff); + switch (addr) { + case NAND_DATA + 0: + case NAND_DATA + 1: + case NAND_DATA + 2: + case NAND_DATA + 3: + nand_setio(s->flash, value); + s->nand.isr &= 1; + tc6393xb_nand_irq(s); + return; + case NAND_MODE: + s->nand.mode = value; + nand_setpins(s->flash, + value & NAND_MODE_CLE, + value & NAND_MODE_ALE, + !(value & NAND_MODE_CE), + value & NAND_MODE_WP, + 0); // FIXME: gnd + switch (value & NAND_MODE_ECC_MASK) { + case NAND_MODE_ECC_RST: + ecc_reset(&s->ecc); + break; + case NAND_MODE_ECC_READ: + // FIXME + break; + case NAND_MODE_ECC_EN: + ecc_reset(&s->ecc); + } + return; + case NAND_ISR: + s->nand.isr = value; + tc6393xb_nand_irq(s); + return; + case NAND_IMR: + s->nand.imr = value; + tc6393xb_nand_irq(s); + return; + } + fprintf(stderr, "tc6393xb_nand: unhandled write at %08x: %02x\n", + (uint32_t) addr, value & 0xff); +} + +static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) { + struct tc6393xb_s *s = opaque; + addr -= s->target_base; + + switch (addr >> 8) { + case 0: + return tc6393xb_scr_readb(s, addr & 0xff); + case 1: + return tc6393xb_nand_cfg_readb(s, addr & 0xff); + }; + + if ((addr &~0xff) == s->nand_phys && s->nand_enable) { +// return tc6393xb_nand_readb(s, addr & 0xff); + uint8_t d = tc6393xb_nand_readb(s, addr & 0xff); +// fprintf(stderr, "tc6393xb_nand: read at %08x: %02hhx\n", (uint32_t) addr, d); + return d; + } + +// fprintf(stderr, "tc6393xb: unhandled read at %08x\n", (uint32_t) addr); + return 0; +} + +static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) { + struct tc6393xb_s *s = opaque; + addr -= s->target_base; + + switch (addr >> 8) { + case 0: + tc6393xb_scr_writeb(s, addr & 0xff, value); + return; + case 1: + tc6393xb_nand_cfg_writeb(s, addr & 0xff, value); + return; + }; + + if ((addr &~0xff) == s->nand_phys && s->nand_enable) + tc6393xb_nand_writeb(s, addr & 0xff, value); + else + fprintf(stderr, "tc6393xb: unhandled write at %08x: %02x\n", + (uint32_t) addr, value & 0xff); +} + static uint32_t tc6393xb_readw(void *opaque, target_phys_addr_t addr) { return (tc6393xb_readb(opaque, addr) & 0xff) | @@ -289,8 +482,13 @@ struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq) s = (struct tc6393xb_s *) qemu_mallocz(sizeof(struct tc6393xb_s)); s->target_base = base; + s->irq = irq; s->gpio_in = qemu_allocate_irqs(tc6393xb_gpio_set, s, TC6393XB_GPIOS); + 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); -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH] tosa: support leds 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tc6393xb: initial support for nand Dmitry Baryshkov @ 2008-11-02 13:16 ` Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: basic lcd support Dmitry Baryshkov 0 siblings, 1 reply; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 13:16 UTC (permalink / raw) To: qemu-devel; +Cc: Dmitry Baryshkov Tosa: add support for leds. Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- hw/tosa.c | 35 ++++++++++++++++++++++++++++++++++- 1 files changed, 34 insertions(+), 1 deletions(-) diff --git a/hw/tosa.c b/hw/tosa.c index 75df52e..e629044 100644 --- a/hw/tosa.c +++ b/hw/tosa.c @@ -27,11 +27,17 @@ #define TOSA_GPIO_CF_CD (13) #define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */ -#define TOSA_SCOOP_GPIO_BASE 0 +#define TOSA_SCOOP_GPIO_BASE 1 #define TOSA_GPIO_IR_POWERDWN (TOSA_SCOOP_GPIO_BASE + 2) #define TOSA_GPIO_SD_WP (TOSA_SCOOP_GPIO_BASE + 3) #define TOSA_GPIO_PWR_ON (TOSA_SCOOP_GPIO_BASE + 4) +#define TOSA_SCOOP_JC_GPIO_BASE 1 +#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_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7) + static void tosa_microdrive_attach(struct pxa2xx_state_s *cpu) { struct pcmcia_card_s *md; @@ -48,10 +54,33 @@ static void tosa_microdrive_attach(struct pxa2xx_state_s *cpu) } } +static void tosa_out_switch(void *opaque, int line, int level) +{ + switch (line) { + case 0: + fprintf(stderr, "blue LED %s.\n", level ? "on" : "off"); + break; + case 1: + fprintf(stderr, "green LED %s.\n", level ? "on" : "off"); + break; + case 2: + fprintf(stderr, "amber LED %s.\n", level ? "on" : "off"); + break; + case 3: + fprintf(stderr, "wlan LED %s.\n", level ? "on" : "off"); + break; + default: + fprintf(stderr, "Uhandled out event: %d = %d\n", line, level); + break; + } +} + + static void tosa_gpio_setup(struct pxa2xx_state_s *cpu, struct scoop_info_s *scp0, struct scoop_info_s *scp1) { + qemu_irq *outsignals = qemu_allocate_irqs(tosa_out_switch, cpu, 4); /* MMC/SD host */ pxa2xx_mmci_handlers(cpu->mmc, scoop_gpio_in_get(scp0)[TOSA_GPIO_SD_WP], @@ -69,6 +98,10 @@ static void tosa_gpio_setup(struct pxa2xx_state_s *cpu, pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_JC_CF_IRQ], NULL); + scoop_gpio_out_set(scp1, TOSA_GPIO_BT_LED, outsignals[0]); + 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]); } static struct arm_boot_info tosa_binfo = { -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH] tosa: basic lcd support 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: support leds Dmitry Baryshkov @ 2008-11-02 13:16 ` Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: provide correct IRQ to tc6393xb init Dmitry Baryshkov 2008-11-02 16:09 ` [Qemu-devel] [PATCH] tosa: basic lcd support andrzej zaborowski 0 siblings, 2 replies; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 13:16 UTC (permalink / raw) To: qemu-devel; +Cc: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- hw/tosa.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 74 insertions(+), 0 deletions(-) diff --git a/hw/tosa.c b/hw/tosa.c index e629044..cb0e1da 100644 --- a/hw/tosa.c +++ b/hw/tosa.c @@ -17,6 +17,7 @@ #include "pcmcia.h" #include "block.h" #include "boards.h" +#include "i2c.h" #define TOSA_RAM 0x04000000 #define TOSA_ROM 0x00800000 @@ -38,6 +39,11 @@ #define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2) #define TOSA_GPIO_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7) +#define DAC_BASE 0x4e +#define DAC_CH1 0 +#define DAC_CH2 1 + + static void tosa_microdrive_attach(struct pxa2xx_state_s *cpu) { struct pcmcia_card_s *md; @@ -104,6 +110,72 @@ static void tosa_gpio_setup(struct pxa2xx_state_s *cpu, scoop_gpio_out_set(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]); } +static uint32_t tosa_ssp_read(void *opaque) { + return 0; +} + +static void tosa_ssp_write(void *opaque, uint32_t value) +{ + fprintf(stderr, "TG: %d %02x\n", value >> 5, value & 0x1f); +} + +struct tosa_dac_i2c { + i2c_slave i2c; + int len; + char buf[3]; +}; + +static int tosa_dac_send(i2c_slave *i2c, uint8_t data) +{ + struct tosa_dac_i2c *s = (struct tosa_dac_i2c *)i2c; + s->buf[s->len] = data; + if (s->len ++ > 2) { +#ifdef VERBOSE + fprintf(stderr, "%s: message too long (%i bytes)\n", __FUNCTION__, s->len); +#endif + return 1; + } + + if (s->len == 2) { + fprintf(stderr, "dac: channel %d value 0x%02x\n", + s->buf[0], s->buf[1]); + } + + return 0; +} + +static void tosa_dac_event(i2c_slave *i2c, enum i2c_event event) +{ + struct tosa_dac_i2c *s = (struct tosa_dac_i2c *)i2c; + s->len = 0; + switch (event) { + case I2C_START_SEND: + break; + case I2C_FINISH: +#ifdef VERBOSE + if (s->len < 2) + printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len); + if (s->len > 2) + printf("%s: message too long\n", __FUNCTION__); +#endif + break; + default: + break; + } +} + +static void tosa_tg_init(struct pxa2xx_state_s *cpu) +{ + struct i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]); + struct i2c_slave *dac = i2c_slave_init(bus, 0, sizeof(struct tosa_dac_i2c)); + dac->send = tosa_dac_send; + dac->event = tosa_dac_event; + i2c_set_slave_address(dac, DAC_BASE); + pxa2xx_ssp_attach(cpu->ssp[1], tosa_ssp_read, + tosa_ssp_write, cpu); +} + + static struct arm_boot_info tosa_binfo = { .loader_start = PXA2XX_SDRAM_BASE, .ram_size = 0x04000000, @@ -140,6 +212,8 @@ static void tosa_init(ram_addr_t ram_size, int vga_ram_size, tosa_microdrive_attach(cpu); + tosa_tg_init(cpu); + /* Setup initial (reset) machine state */ cpu->env->regs[15] = tosa_binfo.loader_start; -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH] tosa: provide correct IRQ to tc6393xb init 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: basic lcd support Dmitry Baryshkov @ 2008-11-02 13:16 ` Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: disable pxafb as it's not used on tosa Dmitry Baryshkov 2008-11-02 16:09 ` [Qemu-devel] [PATCH] tosa: basic lcd support andrzej zaborowski 1 sibling, 1 reply; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 13:16 UTC (permalink / raw) To: qemu-devel; +Cc: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- hw/tosa.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/hw/tosa.c b/hw/tosa.c index cb0e1da..1c49509 100644 --- a/hw/tosa.c +++ b/hw/tosa.c @@ -26,6 +26,7 @@ #define TOSA_GPIO_ON_RESET (19) #define TOSA_GPIO_CF_IRQ (21) /* CF slot0 Ready */ #define TOSA_GPIO_CF_CD (13) +#define TOSA_GPIO_TC6393XB_INT (15) #define TOSA_GPIO_JC_CF_IRQ (36) /* CF slot1 Ready */ #define TOSA_SCOOP_GPIO_BASE 1 @@ -203,7 +204,7 @@ 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, NULL); + tc6393xb_init(0x10000000, pxa2xx_gpio_in_get(cpu->gpio)[TOSA_GPIO_TC6393XB_INT]); scp0 = scoop_init(cpu, 0, 0x08800000); scp1 = scoop_init(cpu, 1, 0x14800040); -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH] tosa: disable pxafb as it's not used on tosa. 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: provide correct IRQ to tc6393xb init Dmitry Baryshkov @ 2008-11-02 13:16 ` Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tc6393xb: non-accelerated FB support Dmitry Baryshkov 0 siblings, 1 reply; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 13:16 UTC (permalink / raw) To: qemu-devel; +Cc: Dmitry Baryshkov Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- hw/tosa.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/hw/tosa.c b/hw/tosa.c index 1c49509..711060c 100644 --- a/hw/tosa.c +++ b/hw/tosa.c @@ -199,7 +199,7 @@ static void tosa_init(ram_addr_t ram_size, int vga_ram_size, if (!cpu_model) cpu_model = "pxa255"; - cpu = pxa255_init(tosa_binfo.ram_size, ds); + cpu = pxa255_init(tosa_binfo.ram_size, NULL); cpu_register_physical_memory(0, TOSA_ROM, qemu_ram_alloc(TOSA_ROM) | IO_MEM_ROM); -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [Qemu-devel] [PATCH] tc6393xb: non-accelerated FB support 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: disable pxafb as it's not used on tosa Dmitry Baryshkov @ 2008-11-02 13:16 ` Dmitry Baryshkov 2008-11-02 16:31 ` andrzej zaborowski 0 siblings, 1 reply; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 13:16 UTC (permalink / raw) To: qemu-devel; +Cc: Dmitry Baryshkov [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 8445 bytes --] Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- hw/devices.h | 2 +- hw/tc6393xb.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++- hw/tc6393xb_template.h | 52 +++++++++++++++++++ hw/tosa.c | 4 +- 4 files changed, 187 insertions(+), 3 deletions(-) create mode 100644 hw/tc6393xb_template.h diff --git a/hw/devices.h b/hw/devices.h index 45fead9..e8fed68 100644 --- a/hw/devices.h +++ b/hw/devices.h @@ -66,7 +66,7 @@ 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); +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); diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c index 919a922..e3897ff 100644 --- a/hw/tc6393xb.c +++ b/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,11 @@ struct tc6393xb_s { uint32_t nand_phys; struct nand_flash_s *flash; struct ecc_state_s ecc; + + DisplayState *ds; + QEMUConsole *console; + uint8_t *vram; + uint32_t scr_width, scr_height; /* in pixels */ }; qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s) @@ -395,6 +402,111 @@ static void tc6393xb_nand_writeb(struct tc6393xb_s *s, target_phys_addr_t addr, (uint32_t) addr, value & 0xff); } +#define BITS 8 +#define PIXEL_WIDTH 8 +#include "tc6393xb_template.h" +#define BITS 15 +#define PIXEL_WIDTH 16 +#include "tc6393xb_template.h" +#define BITS 16 +#define PIXEL_WIDTH 16 +#include "tc6393xb_template.h" +#define BITS 24 +#define PIXEL_WIDTH 32 +#include "tc6393xb_template.h" +#define BITS 32 +#define PIXEL_WIDTH 32 +#include "tc6393xb_template.h" + +static void tc6393xb_draw_graphic(struct tc6393xb_s *s) +{ + 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); +} + +#if 0 +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); +} +#endif + +static void tc6393xb_update_display(void *opaque) +{ + struct tc6393xb_s *s = opaque; +#if 0 + int full_update, graphic_mode; +#endif + + if (s->scr_width == 0 || s->scr_height == 0) + return; + +#if 0 + if (s->ctla & CTLA_FORCE_BLANK) + graphic_mode = GMODE_BLANK; + else + graphic_mode = GMODE_GRAPH; + full_update = 0; + if (graphic_mode != s->graphic_mode) { + s->graphic_mode = graphic_mode; + full_update = 1; + } +#endif + if (s->scr_width != s->ds->width || s->scr_height != s->ds->height) { + qemu_console_resize(s->console, s->scr_width, s->scr_height); +#if 0 + full_update = 1; +#endif + } +#if 0 + switch(graphic_mode) { + case GMODE_GRAPH: + tc6393xb_draw_graphic(s, full_update); + break; + case GMODE_BLANK: + default: + tc6393xb_draw_blank(s, full_update); + break; + } +#else + tc6393xb_draw_graphic(s); +#endif +} + + static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) { struct tc6393xb_s *s = opaque; addr -= s->target_base; @@ -404,6 +516,8 @@ static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) { return tc6393xb_scr_readb(s, addr & 0xff); case 1: return tc6393xb_nand_cfg_readb(s, addr & 0xff); + case 0x1000 ... 0x1fff: + return s->vram[addr - 0x100000]; }; if ((addr &~0xff) == s->nand_phys && s->nand_enable) { @@ -428,6 +542,9 @@ static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t valu case 1: tc6393xb_nand_cfg_writeb(s, addr & 0xff, value); return; + case 0x1000 ... 0x1fff: + s->vram[addr - 0x100000] = value&0xff; + return; }; if ((addr &~0xff) == s->nand_phys && s->nand_enable) @@ -465,7 +582,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; @@ -493,6 +610,19 @@ struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq) tc6393xb_writefn, s); cpu_register_physical_memory(s->target_base, 0x200000, iomemtype); + if (ds) { + s->ds = ds; + s->vram = qemu_mallocz(0x100000); + 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; } /* vim:set shiftwidth=4 ts=4 et: */ diff --git a/hw/tc6393xb_template.h b/hw/tc6393xb_template.h new file mode 100644 index 0000000..1e0dcac --- /dev/null +++ b/hw/tc6393xb_template.h @@ -0,0 +1,52 @@ +/* + * 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 + */ + +static void glue(tc6393xb_draw_graphic, BITS)(struct tc6393xb_s *s) +{ + int i, j; + int w_display; + uint16_t *data_buffer; + uint8_t *data_display, *dd; + + data_buffer = (uint16_t*)s->vram; + w_display = s->scr_width * PIXEL_WIDTH / 8; + data_display = s->ds->data; + for(i = 0; i < s->scr_height; i++) { + dd = data_display; + for (j = 0; j < s->scr_width; j++, dd += PIXEL_WIDTH / 8, data_buffer++) { + uint16_t color = *data_buffer; + *((glue(glue(uint, PIXEL_WIDTH), _t) *)dd) = glue(rgb_to_pixel, BITS)( + ((color & 0xf800) * 0x108) >> 11, + ((color & 0x7e0) * 0x41) >> 9, + ((color & 0x1f) * 0x21) >> 2 + ); + } + data_display += s->ds->linesize; + } +} + +#undef PIXEL_WIDTH +#undef BITS + diff --git a/hw/tosa.c b/hw/tosa.c index 711060c..cbb0cb2 100644 --- a/hw/tosa.c +++ b/hw/tosa.c @@ -204,7 +204,9 @@ 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]); + 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); -- 1.5.6.5 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH] tc6393xb: non-accelerated FB support 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tc6393xb: non-accelerated FB support Dmitry Baryshkov @ 2008-11-02 16:31 ` andrzej zaborowski 2008-11-02 17:36 ` Dmitry Baryshkov 0 siblings, 1 reply; 16+ messages in thread From: andrzej zaborowski @ 2008-11-02 16:31 UTC (permalink / raw) To: qemu-devel; +Cc: Dmitry Baryshkov 2008/11/2 Dmitry Baryshkov <dbaryshkov@gmail.com>: > Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> > --- > hw/devices.h | 2 +- > hw/tc6393xb.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++- > hw/tc6393xb_template.h | 52 +++++++++++++++++++ > hw/tosa.c | 4 +- > 4 files changed, 187 insertions(+), 3 deletions(-) > create mode 100644 hw/tc6393xb_template.h > > diff --git a/hw/devices.h b/hw/devices.h > index 45fead9..e8fed68 100644 > --- a/hw/devices.h > +++ b/hw/devices.h > @@ -66,7 +66,7 @@ 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); > +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); > diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c > index 919a922..e3897ff 100644 > --- a/hw/tc6393xb.c > +++ b/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,11 @@ struct tc6393xb_s { > uint32_t nand_phys; > struct nand_flash_s *flash; > struct ecc_state_s ecc; > + > + DisplayState *ds; > + QEMUConsole *console; > + uint8_t *vram; > + uint32_t scr_width, scr_height; /* in pixels */ > }; > > qemu_irq *tc6393xb_gpio_in_get(struct tc6393xb_s *s) > @@ -395,6 +402,111 @@ static void tc6393xb_nand_writeb(struct tc6393xb_s *s, target_phys_addr_t addr, > (uint32_t) addr, value & 0xff); > } > > +#define BITS 8 > +#define PIXEL_WIDTH 8 > +#include "tc6393xb_template.h" > +#define BITS 15 > +#define PIXEL_WIDTH 16 > +#include "tc6393xb_template.h" > +#define BITS 16 > +#define PIXEL_WIDTH 16 > +#include "tc6393xb_template.h" > +#define BITS 24 > +#define PIXEL_WIDTH 32 > +#include "tc6393xb_template.h" > +#define BITS 32 > +#define PIXEL_WIDTH 32 > +#include "tc6393xb_template.h" > + > +static void tc6393xb_draw_graphic(struct tc6393xb_s *s) > +{ > + 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); > +} > + > +#if 0 > +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); > +} > +#endif This assumes in 24bit mode a pixel occupies only 3 bytes (which iirc is correct) and above PIXEL_WIDTH for 24 bits is set to 32. > + > +static void tc6393xb_update_display(void *opaque) > +{ > + struct tc6393xb_s *s = opaque; > +#if 0 > + int full_update, graphic_mode; > +#endif > + > + if (s->scr_width == 0 || s->scr_height == 0) > + return; > + > +#if 0 > + if (s->ctla & CTLA_FORCE_BLANK) > + graphic_mode = GMODE_BLANK; > + else > + graphic_mode = GMODE_GRAPH; > + full_update = 0; > + if (graphic_mode != s->graphic_mode) { > + s->graphic_mode = graphic_mode; > + full_update = 1; > + } > +#endif > + if (s->scr_width != s->ds->width || s->scr_height != s->ds->height) { > + qemu_console_resize(s->console, s->scr_width, s->scr_height); > +#if 0 > + full_update = 1; > +#endif > + } > +#if 0 > + switch(graphic_mode) { > + case GMODE_GRAPH: > + tc6393xb_draw_graphic(s, full_update); > + break; > + case GMODE_BLANK: > + default: > + tc6393xb_draw_blank(s, full_update); > + break; > + } > +#else > + tc6393xb_draw_graphic(s); > +#endif > +} Why's blank mode disabled? > + > + > static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) { > struct tc6393xb_s *s = opaque; > addr -= s->target_base; > @@ -404,6 +516,8 @@ static uint32_t tc6393xb_readb(void *opaque, target_phys_addr_t addr) { > return tc6393xb_scr_readb(s, addr & 0xff); > case 1: > return tc6393xb_nand_cfg_readb(s, addr & 0xff); > + case 0x1000 ... 0x1fff: > + return s->vram[addr - 0x100000]; > }; > > if ((addr &~0xff) == s->nand_phys && s->nand_enable) { > @@ -428,6 +542,9 @@ static void tc6393xb_writeb(void *opaque, target_phys_addr_t addr, uint32_t valu > case 1: > tc6393xb_nand_cfg_writeb(s, addr & 0xff, value); > return; > + case 0x1000 ... 0x1fff: > + s->vram[addr - 0x100000] = value&0xff; > + return; > }; IIRC the page size is 0x400 on qemu-system-arm so you could register this region as RAM, this sould give a speed-up. The indentation is strange. > > if ((addr &~0xff) == s->nand_phys && s->nand_enable) > @@ -465,7 +582,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; > @@ -493,6 +610,19 @@ struct tc6393xb_s *tc6393xb_init(uint32_t base, qemu_irq irq) > tc6393xb_writefn, s); > cpu_register_physical_memory(s->target_base, 0x200000, iomemtype); > > + if (ds) { > + s->ds = ds; > + s->vram = qemu_mallocz(0x100000); > + 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; > } > /* vim:set shiftwidth=4 ts=4 et: */ > diff --git a/hw/tc6393xb_template.h b/hw/tc6393xb_template.h > new file mode 100644 > index 0000000..1e0dcac > --- /dev/null > +++ b/hw/tc6393xb_template.h > @@ -0,0 +1,52 @@ > +/* > + * 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 > + */ > + > +static void glue(tc6393xb_draw_graphic, BITS)(struct tc6393xb_s *s) > +{ > + int i, j; > + int w_display; > + uint16_t *data_buffer; > + uint8_t *data_display, *dd; > + > + data_buffer = (uint16_t*)s->vram; > + w_display = s->scr_width * PIXEL_WIDTH / 8; > + data_display = s->ds->data; > + for(i = 0; i < s->scr_height; i++) { > + dd = data_display; > + for (j = 0; j < s->scr_width; j++, dd += PIXEL_WIDTH / 8, data_buffer++) { > + uint16_t color = *data_buffer; > + *((glue(glue(uint, PIXEL_WIDTH), _t) *)dd) = glue(rgb_to_pixel, BITS)( > + ((color & 0xf800) * 0x108) >> 11, > + ((color & 0x7e0) * 0x41) >> 9, > + ((color & 0x1f) * 0x21) >> 2 > + ); This assumes power of two PIXEL_WIDTH (which is power-of-two but possibly wrongly). For the RGB565 host case you can possibly use memcpy. Cheers ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH] tc6393xb: non-accelerated FB support 2008-11-02 16:31 ` andrzej zaborowski @ 2008-11-02 17:36 ` Dmitry Baryshkov 2008-11-02 19:40 ` Dmitry Baryshkov 0 siblings, 1 reply; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 17:36 UTC (permalink / raw) To: andrzej zaborowski; +Cc: qemu-devel On Sun, Nov 02, 2008 at 05:31:25PM +0100, andrzej zaborowski wrote: > 2008/11/2 Dmitry Baryshkov <dbaryshkov@gmail.com>: > > Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> > > +#if 0 > > +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); > > +} > > +#endif > > This assumes in 24bit mode a pixel occupies only 3 bytes (which iirc > is correct) and above PIXEL_WIDTH for 24 bits is set to 32. This is disabled as it's untested. And about 24bit mode... I'm really not sure. I thought that when used it has 24 bit color, but 32 bit alignment of colors. Otherwise it will be a nightmare to use. > > + > > +static void tc6393xb_update_display(void *opaque) > > +{ > > + struct tc6393xb_s *s = opaque; > > +#if 0 > > + int full_update, graphic_mode; > > +#endif > > + > > + if (s->scr_width == 0 || s->scr_height == 0) > > + return; > > + > > +#if 0 > > + if (s->ctla & CTLA_FORCE_BLANK) > > + graphic_mode = GMODE_BLANK; > > + else > > + graphic_mode = GMODE_GRAPH; > > + full_update = 0; > > + if (graphic_mode != s->graphic_mode) { > > + s->graphic_mode = graphic_mode; > > + full_update = 1; > > + } > > +#endif > > + if (s->scr_width != s->ds->width || s->scr_height != s->ds->height) { > > + qemu_console_resize(s->console, s->scr_width, s->scr_height); > > +#if 0 > > + full_update = 1; > > +#endif > > + } > > +#if 0 > > + switch(graphic_mode) { > > + case GMODE_GRAPH: > > + tc6393xb_draw_graphic(s, full_update); > > + break; > > + case GMODE_BLANK: > > + default: > > + tc6393xb_draw_blank(s, full_update); > > + break; > > + } > > +#else > > + tc6393xb_draw_graphic(s); > > +#endif > > +} > > Why's blank mode disabled? Not Yet Supported. > > IIRC the page size is 0x400 on qemu-system-arm so you could register > this region as RAM, this sould give a speed-up. The indentation is > strange. Hmm. Nice idea. I'll redo this patch anyway then. > > + for(i = 0; i < s->scr_height; i++) { > > + dd = data_display; > > + for (j = 0; j < s->scr_width; j++, dd += PIXEL_WIDTH / 8, data_buffer++) { > > + uint16_t color = *data_buffer; > > + *((glue(glue(uint, PIXEL_WIDTH), _t) *)dd) = glue(rgb_to_pixel, BITS)( > > + ((color & 0xf800) * 0x108) >> 11, > > + ((color & 0x7e0) * 0x41) >> 9, > > + ((color & 0x1f) * 0x21) >> 2 > > + ); > > This assumes power of two PIXEL_WIDTH (which is power-of-two but > possibly wrongly). > For the RGB565 host case you can possibly use memcpy. See above about 24-bit mode. Nice idea for 565 mode :) -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH] tc6393xb: non-accelerated FB support 2008-11-02 17:36 ` Dmitry Baryshkov @ 2008-11-02 19:40 ` Dmitry Baryshkov 2008-11-03 23:46 ` andrzej zaborowski 0 siblings, 1 reply; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 19:40 UTC (permalink / raw) To: andrzej zaborowski; +Cc: qemu-devel On Sun, Nov 02, 2008 at 08:36:19PM +0300, Dmitry Baryshkov wrote: > On Sun, Nov 02, 2008 at 05:31:25PM +0100, andrzej zaborowski wrote: > > 2008/11/2 Dmitry Baryshkov <dbaryshkov@gmail.com>: > > > Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> > > > > +#if 0 > > > +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); > > > +} > > > +#endif > > > > This assumes in 24bit mode a pixel occupies only 3 bytes (which iirc > > is correct) and above PIXEL_WIDTH for 24 bits is set to 32. > > This is disabled as it's untested. And about 24bit mode... I'm really > not sure. I thought that when used it has 24 bit color, but 32 bit > alignment of colors. Otherwise it will be a nightmare to use. > > > > + > > > +static void tc6393xb_update_display(void *opaque) > > > +{ > > > + struct tc6393xb_s *s = opaque; > > > +#if 0 > > > + int full_update, graphic_mode; > > > +#endif > > > + > > > + if (s->scr_width == 0 || s->scr_height == 0) > > > + return; > > > + > > > +#if 0 > > > + if (s->ctla & CTLA_FORCE_BLANK) > > > + graphic_mode = GMODE_BLANK; > > > + else > > > + graphic_mode = GMODE_GRAPH; > > > + full_update = 0; > > > + if (graphic_mode != s->graphic_mode) { > > > + s->graphic_mode = graphic_mode; > > > + full_update = 1; > > > + } > > > +#endif > > > + if (s->scr_width != s->ds->width || s->scr_height != s->ds->height) { > > > + qemu_console_resize(s->console, s->scr_width, s->scr_height); > > > +#if 0 > > > + full_update = 1; > > > +#endif > > > + } > > > +#if 0 > > > + switch(graphic_mode) { > > > + case GMODE_GRAPH: > > > + tc6393xb_draw_graphic(s, full_update); > > > + break; > > > + case GMODE_BLANK: > > > + default: > > > + tc6393xb_draw_blank(s, full_update); > > > + break; > > > + } > > > +#else > > > + tc6393xb_draw_graphic(s); > > > +#endif > > > +} > > > > Why's blank mode disabled? > > Not Yet Supported. > > > > > IIRC the page size is 0x400 on qemu-system-arm so you could register > > this region as RAM, this sould give a speed-up. The indentation is > > strange. > > Hmm. Nice idea. I'll redo this patch anyway then. > > > > + for(i = 0; i < s->scr_height; i++) { > > > + dd = data_display; > > > + for (j = 0; j < s->scr_width; j++, dd += PIXEL_WIDTH / 8, data_buffer++) { > > > + uint16_t color = *data_buffer; > > > + *((glue(glue(uint, PIXEL_WIDTH), _t) *)dd) = glue(rgb_to_pixel, BITS)( > > > + ((color & 0xf800) * 0x108) >> 11, > > > + ((color & 0x7e0) * 0x41) >> 9, > > > + ((color & 0x1f) * 0x21) >> 2 > > > + ); > > > > This assumes power of two PIXEL_WIDTH (which is power-of-two but > > possibly wrongly). > > For the RGB565 host case you can possibly use memcpy. > > See above about 24-bit mode. > Nice idea for 565 mode :) As a second thought I've implemented blanking, implemented your suggestions. Please take a look at the following patch. >From 57cd66fefc31ac18f1f896a8ca53441b01f0d345 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dbaryshkov@gmail.com> Date: Thu, 11 Sep 2008 04:39:15 +0400 Subject: [PATCH] tc6393xb: non-accelerated FB support Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- hw/devices.h | 4 +- hw/tc6393xb.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++- hw/tc6393xb_template.h | 72 +++++++++++++++++++++++++++++ hw/tosa.c | 17 +++++-- 4 files changed, 205 insertions(+), 8 deletions(-) create mode 100644 hw/tc6393xb_template.h diff --git a/hw/devices.h b/hw/devices.h index 45fead9..9572a63 100644 --- a/hw/devices.h +++ b/hw/devices.h @@ -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 diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c index 2c18984..8a3ff18 100644 --- a/hw/tc6393xb.c +++ b/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,16 @@ 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 +415,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 +564,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 +584,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; } diff --git a/hw/tc6393xb_template.h b/hw/tc6393xb_template.h new file mode 100644 index 0000000..c9d4e03 --- /dev/null +++ b/hw/tc6393xb_template.h @@ -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 + diff --git a/hw/tosa.c b/hw/tosa.c index e66ab16..a54390f 100644 --- a/hw/tosa.c +++ b/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 @@ -85,7 +86,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 */ @@ -109,6 +111,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) { @@ -197,9 +201,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); @@ -213,12 +218,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); @@ -239,5 +246,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, }; -- 1.5.6.5 -- With best wishes Dmitry ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH] tc6393xb: non-accelerated FB support 2008-11-02 19:40 ` Dmitry Baryshkov @ 2008-11-03 23:46 ` andrzej zaborowski 2008-11-04 3:14 ` Dmitry 0 siblings, 1 reply; 16+ messages in thread From: andrzej zaborowski @ 2008-11-03 23:46 UTC (permalink / raw) To: Dmitry Baryshkov; +Cc: qemu-devel 2008/11/2 Dmitry Baryshkov <dbaryshkov@gmail.com>: [...] > As a second thought I've implemented blanking, implemented your > suggestions. Please take a look at the following patch. Thanks, this looks better. > > From 57cd66fefc31ac18f1f896a8ca53441b01f0d345 Mon Sep 17 00:00:00 2001 > From: Dmitry Baryshkov <dbaryshkov@gmail.com> > Date: Thu, 11 Sep 2008 04:39:15 +0400 > Subject: [PATCH] tc6393xb: non-accelerated FB support > > Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> > --- > hw/devices.h | 4 +- > hw/tc6393xb.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++- > hw/tc6393xb_template.h | 72 +++++++++++++++++++++++++++++ > hw/tosa.c | 17 +++++-- > 4 files changed, 205 insertions(+), 8 deletions(-) > create mode 100644 hw/tc6393xb_template.h > > diff --git a/hw/devices.h b/hw/devices.h > index 45fead9..9572a63 100644 > --- a/hw/devices.h > +++ b/hw/devices.h > @@ -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 > diff --git a/hw/tc6393xb.c b/hw/tc6393xb.c > index 2c18984..8a3ff18 100644 > --- a/hw/tc6393xb.c > +++ b/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,16 @@ 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 +415,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 +564,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 +584,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; > } > diff --git a/hw/tc6393xb_template.h b/hw/tc6393xb_template.h > new file mode 100644 > index 0000000..c9d4e03 > --- /dev/null > +++ b/hw/tc6393xb_template.h > @@ -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 Hmm.. now when I look at this it triggers an alert because *(uint16_t *) addr = color; and addr[0] = coor; addr[1] = (color) >> 8; do different things on a bigendian host. But I can't tell offhand which one we want here... pxa2xx_template.h and pl110_template.h might have the same problem. > + > + > +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 > + > diff --git a/hw/tosa.c b/hw/tosa.c > index e66ab16..a54390f 100644 > --- a/hw/tosa.c > +++ b/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 > @@ -85,7 +86,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 */ > @@ -109,6 +111,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) { > @@ -197,9 +201,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); > @@ -213,12 +218,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); > > @@ -239,5 +246,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, > }; > -- > 1.5.6.5 > > > -- > With best wishes > Dmitry > > ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH] tc6393xb: non-accelerated FB support 2008-11-03 23:46 ` andrzej zaborowski @ 2008-11-04 3:14 ` Dmitry 0 siblings, 0 replies; 16+ messages in thread From: Dmitry @ 2008-11-04 3:14 UTC (permalink / raw) To: andrzej zaborowski; +Cc: qemu-devel 2008/11/4 andrzej zaborowski <balrogg@gmail.com>: > 2008/11/2 Dmitry Baryshkov <dbaryshkov@gmail.com>: > [...] >> As a second thought I've implemented blanking, implemented your >> suggestions. Please take a look at the following patch. > > Thanks, this looks better. Good! > >> >> From 57cd66fefc31ac18f1f896a8ca53441b01f0d345 Mon Sep 17 00:00:00 2001 >> From: Dmitry Baryshkov <dbaryshkov@gmail.com> >> Date: Thu, 11 Sep 2008 04:39:15 +0400 >> Subject: [PATCH] tc6393xb: non-accelerated FB support >> >> Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> >> --- >> hw/devices.h | 4 +- >> hw/tc6393xb.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++- >> hw/tc6393xb_template.h | 72 +++++++++++++++++++++++++++++ >> hw/tosa.c | 17 +++++-- >> 4 files changed, 205 insertions(+), 8 deletions(-) >> create mode 100644 hw/tc6393xb_template.h >> + >> +#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 > > Hmm.. now when I look at this it triggers an alert because > *(uint16_t *) addr = color; > and > addr[0] = coor; addr[1] = (color) >> 8; > do different things on a bigendian host. But I can't tell offhand > which one we want here... > > pxa2xx_template.h and pl110_template.h might have the same problem. >From a quick glance most other video emulators will suffer from this problem. IMO we can merge this as is and later fix this if the problem really exists on BE hosts. -- With best wishes Dmitry ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH] tosa: basic lcd support 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: basic lcd support Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: provide correct IRQ to tc6393xb init Dmitry Baryshkov @ 2008-11-02 16:09 ` andrzej zaborowski 2008-11-02 17:19 ` Dmitry Baryshkov 1 sibling, 1 reply; 16+ messages in thread From: andrzej zaborowski @ 2008-11-02 16:09 UTC (permalink / raw) To: qemu-devel; +Cc: Dmitry Baryshkov 2008/11/2 Dmitry Baryshkov <dbaryshkov@gmail.com>: > Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> > --- > hw/tosa.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 74 insertions(+), 0 deletions(-) > > diff --git a/hw/tosa.c b/hw/tosa.c > index e629044..cb0e1da 100644 > --- a/hw/tosa.c > +++ b/hw/tosa.c > @@ -17,6 +17,7 @@ > #include "pcmcia.h" > #include "block.h" > #include "boards.h" > +#include "i2c.h" > > #define TOSA_RAM 0x04000000 > #define TOSA_ROM 0x00800000 > @@ -38,6 +39,11 @@ > #define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2) > #define TOSA_GPIO_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7) > > +#define DAC_BASE 0x4e > +#define DAC_CH1 0 > +#define DAC_CH2 1 > + > + > static void tosa_microdrive_attach(struct pxa2xx_state_s *cpu) > { > struct pcmcia_card_s *md; > @@ -104,6 +110,72 @@ static void tosa_gpio_setup(struct pxa2xx_state_s *cpu, > scoop_gpio_out_set(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]); > } > > +static uint32_t tosa_ssp_read(void *opaque) { > + return 0; > +} > + > +static void tosa_ssp_write(void *opaque, uint32_t value) > +{ > + fprintf(stderr, "TG: %d %02x\n", value >> 5, value & 0x1f); > +} > + > +struct tosa_dac_i2c { > + i2c_slave i2c; > + int len; > + char buf[3]; > +}; > + > +static int tosa_dac_send(i2c_slave *i2c, uint8_t data) > +{ > + struct tosa_dac_i2c *s = (struct tosa_dac_i2c *)i2c; > + s->buf[s->len] = data; > + if (s->len ++ > 2) { > +#ifdef VERBOSE > + fprintf(stderr, "%s: message too long (%i bytes)\n", __FUNCTION__, s->len); > +#endif > + return 1; > + } > + > + if (s->len == 2) { > + fprintf(stderr, "dac: channel %d value 0x%02x\n", > + s->buf[0], s->buf[1]); > + } > + > + return 0; > +} > + > +static void tosa_dac_event(i2c_slave *i2c, enum i2c_event event) > +{ > + struct tosa_dac_i2c *s = (struct tosa_dac_i2c *)i2c; > + s->len = 0; > + switch (event) { > + case I2C_START_SEND: > + break; > + case I2C_FINISH: > +#ifdef VERBOSE > + if (s->len < 2) > + printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len); > + if (s->len > 2) > + printf("%s: message too long\n", __FUNCTION__); > +#endif > + break; > + default: > + break; > + } > +} > + > +static void tosa_tg_init(struct pxa2xx_state_s *cpu) > +{ > + struct i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]); > + struct i2c_slave *dac = i2c_slave_init(bus, 0, sizeof(struct tosa_dac_i2c)); > + dac->send = tosa_dac_send; > + dac->event = tosa_dac_event; You should set also .recv to not leave the kernel a possibility to crash qemu. Other than this, looks okay, but does this code help emulation in anyway? I suppose the kernel wants to see some i2c device present? Cheers ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH] tosa: basic lcd support 2008-11-02 16:09 ` [Qemu-devel] [PATCH] tosa: basic lcd support andrzej zaborowski @ 2008-11-02 17:19 ` Dmitry Baryshkov 2008-11-04 9:14 ` andrzej zaborowski 0 siblings, 1 reply; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 17:19 UTC (permalink / raw) To: andrzej zaborowski; +Cc: qemu-devel On Sun, Nov 02, 2008 at 05:09:04PM +0100, andrzej zaborowski wrote: > 2008/11/2 Dmitry Baryshkov <dbaryshkov@gmail.com>: > > +static void tosa_tg_init(struct pxa2xx_state_s *cpu) > > +{ > > + struct i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]); > > + struct i2c_slave *dac = i2c_slave_init(bus, 0, sizeof(struct tosa_dac_i2c)); > > + dac->send = tosa_dac_send; > > + dac->event = tosa_dac_event; > > You should set also .recv to not leave the kernel a possibility to > crash qemu. Other than this, looks okay, but does this code help > emulation in anyway? I suppose the kernel wants to see some i2c > device present? The kernel expects to have the DAC in place. Otherwise I see barfs from it. So adding such simple i2c client is just a matter of preference. Anyway, please check this patch with .recv callback set: >From 411faec51ff4a355eb5d02eecd5936bb0bcc0dc0 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dbaryshkov@gmail.com> Date: Sat, 13 Sep 2008 13:24:23 +0400 Subject: [PATCH] tosa: basic lcd support Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- hw/tosa.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 83 insertions(+), 0 deletions(-) diff --git a/hw/tosa.c b/hw/tosa.c index e629044..5cd3efb 100644 --- a/hw/tosa.c +++ b/hw/tosa.c @@ -17,6 +17,7 @@ #include "pcmcia.h" #include "block.h" #include "boards.h" +#include "i2c.h" #define TOSA_RAM 0x04000000 #define TOSA_ROM 0x00800000 @@ -38,6 +39,11 @@ #define TOSA_GPIO_CHRG_ERR_LED (TOSA_SCOOP_JC_GPIO_BASE + 2) #define TOSA_GPIO_WLAN_LED (TOSA_SCOOP_JC_GPIO_BASE + 7) +#define DAC_BASE 0x4e +#define DAC_CH1 0 +#define DAC_CH2 1 + + static void tosa_microdrive_attach(struct pxa2xx_state_s *cpu) { struct pcmcia_card_s *md; @@ -104,6 +110,81 @@ static void tosa_gpio_setup(struct pxa2xx_state_s *cpu, scoop_gpio_out_set(scp1, TOSA_GPIO_WLAN_LED, outsignals[3]); } +static uint32_t tosa_ssp_read(void *opaque) { + return 0; +} + +static void tosa_ssp_write(void *opaque, uint32_t value) +{ + fprintf(stderr, "TG: %d %02x\n", value >> 5, value & 0x1f); +} + +struct tosa_dac_i2c { + i2c_slave i2c; + int len; + char buf[3]; +}; + +static int tosa_dac_send(i2c_slave *i2c, uint8_t data) +{ + struct tosa_dac_i2c *s = (struct tosa_dac_i2c *)i2c; + s->buf[s->len] = data; + if (s->len ++ > 2) { +#ifdef VERBOSE + fprintf(stderr, "%s: message too long (%i bytes)\n", __FUNCTION__, s->len); +#endif + return 1; + } + + if (s->len == 2) { + fprintf(stderr, "dac: channel %d value 0x%02x\n", + s->buf[0], s->buf[1]); + } + + return 0; +} + +static void tosa_dac_event(i2c_slave *i2c, enum i2c_event event) +{ + struct tosa_dac_i2c *s = (struct tosa_dac_i2c *)i2c; + s->len = 0; + switch (event) { + case I2C_START_SEND: + break; + case I2C_START_RECV: + printf("%s: recv not supported!!!\n", __FUNCTION__); + break; + case I2C_FINISH: +#ifdef VERBOSE + if (s->len < 2) + printf("%s: message too short (%i bytes)\n", __FUNCTION__, s->len); + if (s->len > 2) + printf("%s: message too long\n", __FUNCTION__); +#endif + break; + default: + break; + } +} + +int tosa_dac_recv(i2c_slave *s) { + printf("%s: recv not supported!!!\n", __FUNCTION__); + return -1; +} + +static void tosa_tg_init(struct pxa2xx_state_s *cpu) +{ + struct i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]); + struct i2c_slave *dac = i2c_slave_init(bus, 0, sizeof(struct tosa_dac_i2c)); + dac->send = tosa_dac_send; + dac->event = tosa_dac_event; + dac->recv = tosa_dac_recv; + i2c_set_slave_address(dac, DAC_BASE); + pxa2xx_ssp_attach(cpu->ssp[1], tosa_ssp_read, + tosa_ssp_write, cpu); +} + + static struct arm_boot_info tosa_binfo = { .loader_start = PXA2XX_SDRAM_BASE, .ram_size = 0x04000000, @@ -140,6 +221,8 @@ static void tosa_init(ram_addr_t ram_size, int vga_ram_size, tosa_microdrive_attach(cpu); + tosa_tg_init(cpu); + /* Setup initial (reset) machine state */ cpu->env->regs[15] = tosa_binfo.loader_start; -- 1.5.6.5 -- With best wishes Dmitry ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [Qemu-devel] [PATCH] tosa: basic lcd support 2008-11-02 17:19 ` Dmitry Baryshkov @ 2008-11-04 9:14 ` andrzej zaborowski 0 siblings, 0 replies; 16+ messages in thread From: andrzej zaborowski @ 2008-11-04 9:14 UTC (permalink / raw) To: Dmitry Baryshkov; +Cc: qemu-devel 2008/11/2 Dmitry Baryshkov <dbaryshkov@gmail.com>: > On Sun, Nov 02, 2008 at 05:09:04PM +0100, andrzej zaborowski wrote: >> 2008/11/2 Dmitry Baryshkov <dbaryshkov@gmail.com>: >> > +static void tosa_tg_init(struct pxa2xx_state_s *cpu) >> > +{ >> > + struct i2c_bus *bus = pxa2xx_i2c_bus(cpu->i2c[0]); >> > + struct i2c_slave *dac = i2c_slave_init(bus, 0, sizeof(struct tosa_dac_i2c)); >> > + dac->send = tosa_dac_send; >> > + dac->event = tosa_dac_event; >> >> You should set also .recv to not leave the kernel a possibility to >> crash qemu. Other than this, looks okay, but does this code help >> emulation in anyway? I suppose the kernel wants to see some i2c >> device present? > > The kernel expects to have the DAC in place. Otherwise I see barfs from > it. So adding such simple i2c client is just a matter of preference. > Anyway, please check this patch with .recv callback set: Right, it expects a DAC. What I mean is that this implementation can equally well be a i2c framebuffer or a flux capacitor ;) But I assume you've tested that this already made the kernel happy. Regards ^ permalink raw reply [flat|nested] 16+ messages in thread
* [Qemu-devel] Re: [PATCH] scoop: GPRR reports the state of GPIO lines 2008-11-02 13:16 [Qemu-devel] [PATCH] scoop: GPRR reports the state of GPIO lines Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tc6393xb: initial support for nand Dmitry Baryshkov @ 2008-11-02 14:45 ` Dmitry Baryshkov 1 sibling, 0 replies; 16+ messages in thread From: Dmitry Baryshkov @ 2008-11-02 14:45 UTC (permalink / raw) To: qemu-devel On Sun, Nov 02, 2008 at 04:16:24PM +0300, Dmitry Baryshkov wrote: > Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> Oops... Please use this one instead. >From 73733f4ccc3a8ee776a791f5cba6a4ba046e778c Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov <dbaryshkov@gmail.com> Date: Sat, 31 May 2008 21:07:56 +0400 Subject: [PATCH] scoop: GPRR reports the state of GPIO lines Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com> --- hw/zaurus.c | 15 ++++++--------- 1 files changed, 6 insertions(+), 9 deletions(-) diff --git a/hw/zaurus.c b/hw/zaurus.c index c475eaa..a18453e 100644 --- a/hw/zaurus.c +++ b/hw/zaurus.c @@ -46,7 +46,6 @@ struct scoop_info_s { uint16_t irr; uint16_t imr; uint16_t isr; - uint16_t gprr; }; #define SCOOP_MCR 0x00 @@ -99,9 +98,8 @@ static uint32_t scoop_readb(void *opaque, target_phys_addr_t addr) case SCOOP_GPCR: return s->gpio_dir; case SCOOP_GPWR: - return s->gpio_level; case SCOOP_GPRR: - return s->gprr; + return s->gpio_level; default: zaurus_printf("Bad register offset " REG_FMT "\n", addr); } @@ -144,12 +142,10 @@ static void scoop_writeb(void *opaque, target_phys_addr_t addr, uint32_t value) scoop_gpio_handler_update(s); break; case SCOOP_GPWR: + case SCOOP_GPRR: // GPRR is probably R/O in real HW s->gpio_level = value & s->gpio_dir; scoop_gpio_handler_update(s); break; - case SCOOP_GPRR: - s->gprr = value; - break; default: zaurus_printf("Bad register offset " REG_FMT "\n", addr); } @@ -205,11 +201,11 @@ static void scoop_save(QEMUFile *f, void *opaque) qemu_put_be16s(f, &s->irr); qemu_put_be16s(f, &s->imr); qemu_put_be16s(f, &s->isr); - qemu_put_be16s(f, &s->gprr); } static int scoop_load(QEMUFile *f, void *opaque, int version_id) { + uint16_t dummy; struct scoop_info_s *s = (struct scoop_info_s *) opaque; qemu_get_be16s(f, &s->status); qemu_get_be16s(f, &s->power); @@ -222,7 +218,8 @@ static int scoop_load(QEMUFile *f, void *opaque, int version_id) qemu_get_be16s(f, &s->irr); qemu_get_be16s(f, &s->imr); qemu_get_be16s(f, &s->isr); - qemu_get_be16s(f, &s->gprr); + if (version_id < 1) + qemu_get_be16s(f, &dummy); return 0; } @@ -243,7 +240,7 @@ struct scoop_info_s *scoop_init(struct pxa2xx_state_s *cpu, iomemtype = cpu_register_io_memory(0, scoop_readfn, scoop_writefn, s); cpu_register_physical_memory(s->target_base, 0x1000, iomemtype); - register_savevm("scoop", instance, 0, scoop_save, scoop_load, s); + register_savevm("scoop", instance, 1, scoop_save, scoop_load, s); return s; } -- 1.5.6.5 -- With best wishes Dmitry ^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2008-11-04 9:14 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-11-02 13:16 [Qemu-devel] [PATCH] scoop: GPRR reports the state of GPIO lines Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tc6393xb: initial support for nand Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: support leds Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: basic lcd support Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: provide correct IRQ to tc6393xb init Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tosa: disable pxafb as it's not used on tosa Dmitry Baryshkov 2008-11-02 13:16 ` [Qemu-devel] [PATCH] tc6393xb: non-accelerated FB support Dmitry Baryshkov 2008-11-02 16:31 ` andrzej zaborowski 2008-11-02 17:36 ` Dmitry Baryshkov 2008-11-02 19:40 ` Dmitry Baryshkov 2008-11-03 23:46 ` andrzej zaborowski 2008-11-04 3:14 ` Dmitry 2008-11-02 16:09 ` [Qemu-devel] [PATCH] tosa: basic lcd support andrzej zaborowski 2008-11-02 17:19 ` Dmitry Baryshkov 2008-11-04 9:14 ` andrzej zaborowski 2008-11-02 14:45 ` [Qemu-devel] Re: [PATCH] scoop: GPRR reports the state of GPIO lines Dmitry Baryshkov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).