* 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
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "hw.h"
#include "console.h"
#include "omap.h"
struct omap_dss_s {
- target_phys_addr_t diss_base;
- target_phys_addr_t disc_base;
- target_phys_addr_t rfbi_base;
- target_phys_addr_t venc_base;
- target_phys_addr_t im3_base;
qemu_irq irq;
qemu_irq drq;
DisplayState *state;
uint32_t control;
uint32_t config;
uint32_t capable;
- uint32_t timing[3];
+ uint32_t timing[4];
int line;
uint32_t bg[2];
uint32_t trans[2];
s->dispc.timing[0] = 0;
s->dispc.timing[1] = 0;
s->dispc.timing[2] = 0;
+ s->dispc.timing[3] = 0;
s->dispc.line = 0;
s->dispc.bg[0] = 0;
s->dispc.bg[1] = 0;
static uint32_t omap_diss_read(void *opaque, target_phys_addr_t addr)
{
struct omap_dss_s *s = (struct omap_dss_s *) opaque;
- int offset = addr - s->diss_base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* DSS_REVISIONNUMBER */
return 0x20;
uint32_t value)
{
struct omap_dss_s *s = (struct omap_dss_s *) opaque;
- int offset = addr - s->diss_base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* DSS_REVISIONNUMBER */
case 0x14: /* DSS_SYSSTATUS */
case 0x50: /* DSS_PSA_LCD_REG_1 */
static uint32_t omap_disc_read(void *opaque, target_phys_addr_t addr)
{
struct omap_dss_s *s = (struct omap_dss_s *) opaque;
- int offset = addr - s->disc_base;
- switch (offset) {
+ switch (addr) {
case 0x000: /* DISPC_REVISION */
return 0x20;
uint32_t value)
{
struct omap_dss_s *s = (struct omap_dss_s *) opaque;
- int offset = addr - s->disc_base;
- switch (offset) {
+ switch (addr) {
case 0x010: /* DISPC_SYSCONFIG */
if (value & 2) /* SOFTRESET */
omap_dss_reset(s);
omap_disc_write,
};
-static void *omap_rfbi_get_buffer(struct omap_dss_s *s)
-{
- target_phys_addr_t fb;
- uint32_t pd;
-
- /* TODO */
- fb = s->dispc.l[0].addr[0];
-
- pd = cpu_get_physical_page_desc(fb);
- if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
- /* TODO */
- cpu_abort(cpu_single_env, "%s: framebuffer outside RAM!\n",
- __FUNCTION__);
- else
- return phys_ram_base +
- (pd & TARGET_PAGE_MASK) +
- (fb & ~TARGET_PAGE_MASK);
-}
-
static void omap_rfbi_transfer_stop(struct omap_dss_s *s)
{
if (!s->rfbi.busy)
static void omap_rfbi_transfer_start(struct omap_dss_s *s)
{
void *data;
- size_t len;
+ target_phys_addr_t len;
+ target_phys_addr_t data_addr;
int pitch;
+ static void *bounce_buffer;
+ static target_phys_addr_t bounce_len;
if (!s->rfbi.enable || s->rfbi.busy)
return;
s->rfbi.busy = 1;
- data = omap_rfbi_get_buffer(s);
+ len = s->rfbi.pixels * 2;
+
+ data_addr = s->dispc.l[0].addr[0];
+ data = cpu_physical_memory_map(data_addr, &len, 0);
+ if (data && len != s->rfbi.pixels * 2) {
+ cpu_physical_memory_unmap(data, len, 0, 0);
+ data = NULL;
+ len = s->rfbi.pixels * 2;
+ }
+ if (!data) {
+ if (len > bounce_len) {
+ bounce_buffer = qemu_realloc(bounce_buffer, len);
+ }
+ data = bounce_buffer;
+ cpu_physical_memory_read(data_addr, data, len);
+ }
/* TODO bpp */
- len = s->rfbi.pixels * 2;
s->rfbi.pixels = 0;
/* TODO: negative values */
if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch);
+ if (data != bounce_buffer) {
+ cpu_physical_memory_unmap(data, len, 0, len);
+ }
+
omap_rfbi_transfer_stop(s);
/* TODO */
static uint32_t omap_rfbi_read(void *opaque, target_phys_addr_t addr)
{
struct omap_dss_s *s = (struct omap_dss_s *) opaque;
- int offset = addr - s->rfbi_base;
- switch (offset) {
+ switch (addr) {
case 0x00: /* RFBI_REVISION */
return 0x10;
uint32_t value)
{
struct omap_dss_s *s = (struct omap_dss_s *) opaque;
- int offset = addr - s->rfbi_base;
- switch (offset) {
+ switch (addr) {
case 0x10: /* RFBI_SYSCONFIG */
if (value & 2) /* SOFTRESET */
omap_rfbi_reset(s);
static uint32_t omap_venc_read(void *opaque, target_phys_addr_t addr)
{
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
- int offset = addr - s->venc_base;
-
- switch (offset) {
+ switch (addr) {
case 0x00: /* REV_ID */
case 0x04: /* STATUS */
case 0x08: /* F_CONTROL */
static void omap_venc_write(void *opaque, target_phys_addr_t addr,
uint32_t value)
{
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
- int offset = addr - s->venc_base;
-
- switch (offset) {
+ switch (addr) {
case 0x08: /* F_CONTROL */
case 0x10: /* VIDOUT_CTRL */
case 0x14: /* SYNC_CTRL */
static uint32_t omap_im3_read(void *opaque, target_phys_addr_t addr)
{
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
- int offset = addr - s->im3_base;
-
- switch (offset) {
+ switch (addr) {
case 0x0a8: /* SBIMERRLOGA */
case 0x0b0: /* SBIMERRLOG */
case 0x190: /* SBIMSTATE */
static void omap_im3_write(void *opaque, target_phys_addr_t addr,
uint32_t value)
{
- struct omap_dss_s *s = (struct omap_dss_s *) opaque;
- int offset = addr - s->im3_base;
-
- switch (offset) {
+ switch (addr) {
case 0x0b0: /* SBIMERRLOG */
case 0x190: /* SBIMSTATE */
case 0x198: /* SBTMSTATE_L */
};
struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
- target_phys_addr_t l3_base, DisplayState *ds,
+ target_phys_addr_t l3_base,
qemu_irq irq, qemu_irq drq,
omap_clk fck1, omap_clk fck2, omap_clk ck54m,
omap_clk ick1, omap_clk ick2)
s->irq = irq;
s->drq = drq;
- s->state = ds;
omap_dss_reset(s);
iomemtype[0] = l4_register_io_memory(0, omap_diss1_readfn,
omap_venc1_writefn, s);
iomemtype[4] = cpu_register_io_memory(0, omap_im3_readfn,
omap_im3_writefn, s);
- s->diss_base = omap_l4_attach(ta, 0, iomemtype[0]);
- s->disc_base = omap_l4_attach(ta, 1, iomemtype[1]);
- s->rfbi_base = omap_l4_attach(ta, 2, iomemtype[2]);
- s->venc_base = omap_l4_attach(ta, 3, iomemtype[3]);
- s->im3_base = l3_base;
- cpu_register_physical_memory(s->im3_base, 0x1000, iomemtype[4]);
+ omap_l4_attach(ta, 0, iomemtype[0]);
+ omap_l4_attach(ta, 1, iomemtype[1]);
+ omap_l4_attach(ta, 2, iomemtype[2]);
+ omap_l4_attach(ta, 3, iomemtype[3]);
+ cpu_register_physical_memory(l3_base, 0x1000, iomemtype[4]);
#if 0
- if (ds)
- graphic_console_init(ds, omap_update_display,
- omap_invalidate_display, omap_screen_dump, s);
+ s->state = graphic_console_init(omap_update_display,
+ omap_invalidate_display, omap_screen_dump, s);
#endif
return s;
void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip)
{
if (cs < 0 || cs > 1)
- cpu_abort(cpu_single_env, "%s: wrong CS %i\n", __FUNCTION__, cs);
+ hw_error("%s: wrong CS %i\n", __FUNCTION__, cs);
s->rfbi.chip[cs] = chip;
}