static irqreturn_t vmjpeg_isr(int irq, void *dev_id)
{
    u32 reg, offset, pts, pts_valid = 0;
    vframe_t *vf;

    WRITE_MPEG_REG(ASSIST_MBOX1_CLR_REG, 1);

    reg = READ_MPEG_REG(MREG_FROM_AMRISC);

    if (reg & PICINFO_BUF_IDX_MASK) {
        offset = READ_MPEG_REG(MREG_FRAME_OFFSET);

        if (pts_lookup_offset(PTS_TYPE_VIDEO, offset, &pts, 0) == 0) {
            pts_valid = 1;
        }

        if ((reg & PICINFO_INTERLACE) == 0) {
            u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3;

            vfpool_idx[fill_ptr] = index;
            vf = &vfpool[fill_ptr];

            set_frame_info(vf);

            vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
            vf->canvas0Addr = vf->canvas1Addr = index2canvas0(index);
            vf->pts = (pts_valid) ? pts : 0;

            vfbuf_use[index]++;

            INCPTR(fill_ptr);
		vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL);               

        } else {
            u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3;

            vfpool_idx[fill_ptr] = index;
            vf = &vfpool[fill_ptr];

            set_frame_info(vf);

#if 0
            if (reg & PICINFO_AVI1) {
                /* AVI1 format */
                if (reg & PICINFO_INTERLACE_AVI1_BOT) {
                    vf->type = VIDTYPE_INTERLACE_BOTTOM | VIDTYPE_INTERLACE_FIRST;
                } else {
                    vf->type = VIDTYPE_INTERLACE_TOP;
                }
            } else {
                if (reg & PICINFO_INTERLACE_FIRST) {
                    vf->type = VIDTYPE_INTERLACE_TOP | VIDTYPE_INTERLACE_FIRST;
                } else {
                    vf->type = VIDTYPE_INTERLACE_BOTTOM;
                }
            }

            vf->type |= VIDTYPE_VIU_FIELD;
            vf->duration >>= 1;
            vf->canvas0Addr = vf->canvas1Addr = index2canvas0(index);

            if ((vf->type & VIDTYPE_INTERLACE_FIRST) && (pts_valid)) {
                vf->pts = pts;
            } else {
                vf->pts = 0;
            }

            vfbuf_use[index]++;

            INCPTR(fill_ptr);
#else
            /* send whole frame by weaving top & bottom field */
            vf->type = VIDTYPE_PROGRESSIVE;
            vf->canvas0Addr = index2canvas0(index);
            vf->canvas1Addr = index2canvas1(index);

            if (pts_valid) {
                vf->pts = pts;
            } else {
                vf->pts = 0;
            }

            vfbuf_use[index]++;

            INCPTR(fill_ptr);
		vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL);            
#endif
        }

        WRITE_MPEG_REG(MREG_FROM_AMRISC, 0);
    }
Esempio n. 2
0
static irqreturn_t vmjpeg_isr(int irq, void *dev_id)
{
    u32 reg, offset, pts, pts_valid = 0;
    vframe_t *vf = NULL;

    WRITE_VREG(ASSIST_MBOX1_CLR_REG, 1);

    reg = READ_VREG(MREG_FROM_AMRISC);

    if (reg & PICINFO_BUF_IDX_MASK) {
        offset = READ_VREG(MREG_FRAME_OFFSET);

        if (pts_lookup_offset(PTS_TYPE_VIDEO, offset, &pts, 0) == 0) {
            pts_valid = 1;
        }

        if ((reg & PICINFO_INTERLACE) == 0) {
            u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3;

            if (index >= DECODE_BUFFER_NUM_MAX) {
                printk("fatal error, invalid buffer index.");
                return IRQ_HANDLED;
            }

            if (kfifo_get(&newframe_q, &vf) == 0) {
                printk("fatal error, no available buffer slot.");
                return IRQ_HANDLED;
            }

            set_frame_info(vf);

            vf->index = index;
#ifdef NV21
            vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD | VIDTYPE_VIU_NV21;
#else
            vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_FIELD;
#endif
            vf->canvas0Addr = vf->canvas1Addr = index2canvas0(index);
            vf->pts = (pts_valid) ? pts : 0;
			vf->orientation = 0 ;
            vfbuf_use[index]++;

            kfifo_put(&display_q, (const vframe_t **)&vf);

            vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL);               

        } else {
            u32 index = ((reg & PICINFO_BUF_IDX_MASK) - 1) & 3;

            if (index >= DECODE_BUFFER_NUM_MAX) {
                printk("fatal error, invalid buffer index.");
                return IRQ_HANDLED;
            }

            if (kfifo_get(&newframe_q, &vf) == 0) {
                printk("fatal error, no available buffer slot.");
                return IRQ_HANDLED;
            }

            set_frame_info(vf);

            vf->index = index;
#if 0
            if (reg & PICINFO_AVI1) {
                /* AVI1 format */
                if (reg & PICINFO_INTERLACE_AVI1_BOT) {
                    vf->type = VIDTYPE_INTERLACE_BOTTOM | VIDTYPE_INTERLACE_FIRST;
                } else {
                    vf->type = VIDTYPE_INTERLACE_TOP;
                }
            } else {
                if (reg & PICINFO_INTERLACE_FIRST) {
                    vf->type = VIDTYPE_INTERLACE_TOP | VIDTYPE_INTERLACE_FIRST;
                } else {
                    vf->type = VIDTYPE_INTERLACE_BOTTOM;
                }
            }

            vf->type |= VIDTYPE_VIU_FIELD;
#ifdef NV21
            vf->type |= VIDTYPE_VIU_NV21;
#endif
            vf->duration >>= 1;
            vf->canvas0Addr = vf->canvas1Addr = index2canvas0(index);
			vf->orientation = 0 ;
            if ((vf->type & VIDTYPE_INTERLACE_FIRST) && (pts_valid)) {
                vf->pts = pts;
            } else {
                vf->pts = 0;
            }

            vfbuf_use[index]++;

            kfifo_put(&display_q, (const vframe_t **)&vf);
#else
            /* send whole frame by weaving top & bottom field */
#ifdef NV21
            vf->type = VIDTYPE_PROGRESSIVE | VIDTYPE_VIU_NV21;
#else
            vf->type = VIDTYPE_PROGRESSIVE;
#endif
            vf->canvas0Addr = index2canvas0(index);
            vf->canvas1Addr = index2canvas1(index);
			vf->orientation = 0 ;
            if (pts_valid) {
                vf->pts = pts;
            } else {
                vf->pts = 0;
            }

            vfbuf_use[index]++;

            kfifo_put(&display_q, (const vframe_t **)&vf);
            
		    vf_notify_receiver(PROVIDER_NAME,VFRAME_EVENT_PROVIDER_VFRAME_READY,NULL);            
#endif
        }

        WRITE_VREG(MREG_FROM_AMRISC, 0);
    }