* [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
* [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
* 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] 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] 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] 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 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
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).