qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: [PATCH v2] sh: sm501: add 2D engine support


From: Blue Swirl
Subject: [Qemu-devel] Re: [PATCH v2] sh: sm501: add 2D engine support
Date: Fri, 14 May 2010 23:44:45 +0300

On 5/11/10, Shin-ichiro KAWASAKI <address@hidden> wrote:
> Hello Blue Swirl, and thank you for the review.
>
>  Here's the patch modified according to your comments.
>  abort() is used instead of assert(), and const modifier added for
> CPU*MemoryFunc.

The patch does not apply. It seems to be based on some version before
61d3cf93e2676282ba1a8d568b2406257f208b26.

>
>  Best Regards,
>  Shin-ichiro KAWASAKI
>
> ---------------------------------------------------------------------------
>
>  In linux kernel v2.6.33, sm501 frame buffer driver modified to support
>  2D graphics engine on sm501 chip.  One example is "fill rectangle"
> operation.
>  But current qemu's sm501 emulation doesn't support it.  This results in
>  graphics console disturbance.
>
>  This patch introduces sm501 2D graphics engine emulation and solve this
> problem.
>
>  Signed-off-by: Shin-ichiro KAWASAKI <address@hidden>
>
>     Add SM501 2D hardware engine support.
>          - Add 2D engine register set read/write handlers.
>      - Support 'fill rectangle'. Other operations are left for future work.
>      - Update SM501 support status comment.
>
>  ---
>   hw/sm501.c |  172
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>   1 files changed, 169 insertions(+), 3 deletions(-)
>
>  diff --git a/hw/sm501.c b/hw/sm501.c
>  index cd1f595..ade88ff 100644
>
>  --- a/hw/sm501.c
>  +++ b/hw/sm501.c
>  @@ -29,16 +29,16 @@
>   #include "devices.h"
>   /*
>  - * Status: 2008/11/02
>  + * Status: 2010/05/07
>   *   - Minimum implementation for Linux console : mmio regs and CRT layer.
>  - *   - Always updates full screen.
>  + *   - 2D grapihcs acceleration partially supported : only fill rectangle.
>   *
>   * TODO:
>   *   - Panel support
>  - *   - Hardware cursor support
>   *   - Touch panel support
>   *   - USB support
>   *   - UART support
>  + *   - More 2D graphics engine support
>   *   - Performance tuning
>   */
>   @@ -508,6 +508,18 @@ typedef struct SM501State {
>      uint32_t dc_crt_hwc_color_1_2;
>      uint32_t dc_crt_hwc_color_3;
>   +    uint32_t _2d_destination;
>  +    uint32_t _2d_dimension;
>  +    uint32_t _2d_control;
>  +    uint32_t _2d_pitch;
>  +    uint32_t _2d_foreground;
>  +    uint32_t _2d_stretch;
>  +    uint32_t _2d_color_compare_mask;
>  +    uint32_t _2d_mask;
>  +    uint32_t _2d_window_width;
>  +    uint32_t _2d_source_base;
>  +    uint32_t _2d_destination_base;

While at it, could you remove the underscore prefix from the field names?

>  +
>   } SM501State;
>   static uint32_t get_local_mem_size_index(uint32_t size)
>  @@ -617,6 +629,69 @@ static int
> within_hwc_y_range(SM501State *state, int y, int crt)
>      return (hwc_y <= y && y < hwc_y + SM501_HWC_HEIGHT);
>   }
>   +static void sm501_2d_operation(SM501State * s)
>  +{
>  +    /* obtain operation parameters */
>  +    int operation = (s->_2d_control >> 16) & 0x1f;
>  +    int dst_x = (s->_2d_destination >> 16) & 0x01FFF;
>  +    int dst_y = s->_2d_destination & 0xFFFF;
>  +    int operation_width = (s->_2d_dimension >> 16) & 0x1FFF;
>  +    int operation_height = s->_2d_dimension & 0xFFFF;
>  +    uint32_t color = s->_2d_foreground;
>  +    int format_flags = (s->_2d_stretch >> 20) & 0x3;
>  +    int addressing = (s->_2d_stretch >> 16) & 0xF;
>  +
>  +    /* get frame buffer info */
>  +#if 0 /* for future use */
>  +    uint8_t * src = s->local_mem + (s->_2d_source_base & 0x03FFFFFF);
>  +#endif
>  +    uint8_t * dst = s->local_mem + (s->_2d_destination_base & 0x03FFFFFF);
>  +    int dst_width = (s->dc_crt_h_total & 0x00000FFF) + 1;
>  +
>  +    if (addressing != 0x0) {
>  +        printf("%s: only XY addressing is supported.\n", __func__);
>  +        abort();
>  +    }
>  +
>  +    if ((s->_2d_source_base & 0x08000000) ||
>  +        (s->_2d_destination_base & 0x08000000)) {
>  +        printf("%s: only local memory is supported.\n", __func__);
>  +        abort();
>  +    }
>  +
>  +    switch (operation) {
>  +    case 0x01: /* fill rectangle */
>  +
>  +#define FILL_RECT(_bpp, _pixel_type) {
>  \
>  +        int y, x;
>  \
>  +        for (y = 0; y < operation_height; y++) {
>  \
>  +            for (x = 0; x < operation_width; x++) {
>  \
>  +                int index = ((dst_y + y) * dst_width + dst_x + x) * _bpp;
>  \
>  +                *(_pixel_type*)&dst[index] = (_pixel_type)color;
>  \
>  +            }
>  \
>  +        }
>  \
>  +    }
>  +
>  +        switch (format_flags) {
>  +        case 0:
>  +            FILL_RECT(1, uint8_t);
>  +            break;
>  +        case 1:
>  +            FILL_RECT(2, uint16_t);
>  +            break;
>  +        case 2:
>  +            FILL_RECT(4, uint32_t);
>  +            break;
>  +        }
>  +        break;
>  +
>  +    default:
>  +        printf("non-implemented SM501 2D operation. %d\n", operation);
>  +        abort();
>  +        break;
>  +    }
>  +}
>  +
>   static uint32_t sm501_system_config_read(void *opaque, target_phys_addr_t
> addr)
>   {
>      SM501State * s = (SM501State *)opaque;
>  @@ -967,6 +1042,92 @@ static CPUWriteMemoryFunc * const
> sm501_disp_ctrl_writefn[] = {
>      &sm501_disp_ctrl_write,
>   };
>   +static uint32_t sm501_2d_engine_read(void *opaque, target_phys_addr_t
> addr)
>  +{
>  +    SM501State * s = (SM501State *)opaque;
>  +    uint32_t ret = 0;
>  +    SM501_DPRINTF("sm501 2d engine regs : read addr=%x\n", (int)addr);
>  +
>  +    switch(addr) {
>  +    case SM501_2D_SOURCE_BASE:
>  +        ret = s->_2d_source_base;
>  +        break;
>  +    default:
>  +        printf("sm501 disp ctrl : not implemented register read."
>  +               " addr=%x\n", (int)addr);
>  +        abort();
>
>  +    }
>  +
>  +    return ret;
>  +}
>  +
>  +static void sm501_2d_engine_write(void *opaque,
>  +                                  target_phys_addr_t addr, uint32_t value)
>  +{
>  +    SM501State * s = (SM501State *)opaque;
>  +    SM501_DPRINTF("sm501 2d engine regs : write addr=%x, val=%x\n",
>  +                  addr, value);
>  +
>  +    switch(addr) {
>  +    case SM501_2D_DESTINATION:
>  +        s->_2d_destination = value;
>  +        break;
>  +    case SM501_2D_DIMENSION:
>  +        s->_2d_dimension = value;
>  +        break;
>  +    case SM501_2D_CONTROL:
>  +        s->_2d_control = value;
>  +
>  +        /* do 2d operation if start flag is set. */
>  +        if (value & 0x80000000) {
>  +            sm501_2d_operation(s);
>  +            s->_2d_control &= ~0x80000000; /* start flag down */
>  +        }
>  +
>  +        break;
>  +    case SM501_2D_PITCH:
>  +        s->_2d_pitch = value;
>  +        break;
>  +    case SM501_2D_FOREGROUND:
>  +        s->_2d_foreground = value;
>  +        break;
>  +    case SM501_2D_STRETCH:
>  +        s->_2d_stretch = value;
>  +        break;
>  +    case SM501_2D_COLOR_COMPARE_MASK:
>  +        s->_2d_color_compare_mask = value;
>  +        break;
>  +    case SM501_2D_MASK:
>  +        s->_2d_mask = value;
>  +        break;
>  +    case SM501_2D_WINDOW_WIDTH:
>  +        s->_2d_window_width = value;
>  +        break;
>  +    case SM501_2D_SOURCE_BASE:
>  +        s->_2d_source_base = value;
>  +        break;
>  +    case SM501_2D_DESTINATION_BASE:
>  +        s->_2d_destination_base = value;
>  +        break;
>  +    default:
>  +        printf("sm501 2d engine : not implemented register write."
>  +               " addr=%x, val=%x\n", (int)addr, value);
>  +        abort();
>  +    }
>  +}
>  +
>  +static CPUReadMemoryFunc * const sm501_2d_engine_readfn[] = {
>  +    NULL,
>  +    NULL,
>  +    &sm501_2d_engine_read,
>  +};
>  +
>  +static CPUWriteMemoryFunc * const sm501_2d_engine_writefn[] = {
>  +    NULL,
>  +    NULL,
>  +    &sm501_2d_engine_write,
>  +};
>  +
>   /* draw line functions for all console modes */
>   #include "pixel_ops.h"
>  @@ -1192,6 +1353,7 @@ void sm501_init(uint32_t base, uint32_t
> local_mem_bytes, qemu_irq irq,
>      SM501State * s;
>      int sm501_system_config_index;
>      int sm501_disp_ctrl_index;
>  +    int sm501_2d_engine_index;
>       /* allocate management data region */
>      s = (SM501State *)qemu_mallocz(sizeof(SM501State));
>  @@ -1220,6 +1382,10 @@ void sm501_init(uint32_t base, uint32_t
> local_mem_bytes, qemu_irq irq,
>
>                                                    sm501_disp_ctrl_writefn,
> s);
>      cpu_register_physical_memory(base + MMIO_BASE_OFFSET +
> SM501_DC,
>                                   0x1000, sm501_disp_ctrl_index);
>  +    sm501_2d_engine_index =
> cpu_register_io_memory(sm501_2d_engine_readfn,
>  +
> sm501_2d_engine_writefn, s);
>  +    cpu_register_physical_memory(base + MMIO_BASE_OFFSET
> + SM501_2D_ENGINE,
>  +                                 0x54, sm501_2d_engine_index);
>       /* bridge to usb host emulation module */
>      usb_ohci_init_sm501(base + MMIO_BASE_OFFSET + SM501_USB_HOST, base,
>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]