aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/emgd/emgd/video/msvdx/msvdx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/emgd/emgd/video/msvdx/msvdx.c')
-rw-r--r--drivers/gpu/drm/emgd/emgd/video/msvdx/msvdx.c841
1 files changed, 0 insertions, 841 deletions
diff --git a/drivers/gpu/drm/emgd/emgd/video/msvdx/msvdx.c b/drivers/gpu/drm/emgd/emgd/video/msvdx/msvdx.c
deleted file mode 100644
index 74970110443a..000000000000
--- a/drivers/gpu/drm/emgd/emgd/video/msvdx/msvdx.c
+++ /dev/null
@@ -1,841 +0,0 @@
-/* -*- pse-c -*-
- *-----------------------------------------------------------------------------
- * Filename: msvdx.c
- * $Revision: 1.18 $
- *-----------------------------------------------------------------------------
- * Copyright © 2002-2010, Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope 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.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *-----------------------------------------------------------------------------
- * Description:
- * Send commands to the MSVDX video decode engine.
- * The host communicates with the firmware via messages. The following
- * messages are supported:
- * RENDER -> MTX
- * DEBLOCK -> MTX
- * OOLD -> MTX
- * MSG_PADDING -> MTX
- * CMD_COMPLETED <- MTX
- * DEBLOCK_REQUIRED <- MTX
- * CMD_FAILED <- MTX
- * HW_PANIC <- MTX
- *-----------------------------------------------------------------------------
- */
-
-#include <io.h>
-#include <pci.h>
-#include <memmap.h>
-#include <sched.h>
-
-#include <igd.h>
-#include <igd_errno.h>
-#include <igd_init.h>
-
-#include <context.h>
-#include <intelpci.h>
-#include <general.h>
-#include <utils.h>
-#include <msvdx.h>
-
-#include <plb/regs.h>
-#include <plb/context.h>
-#include "services_headers.h"
-#include <drm_emgd_private.h>
-
-
-
-//extern int msvdx_init_plb(void);
-extern void msvdx_reset_plb(igd_context_t *context);
-
-int send_to_mtx(igd_context_t *context, unsigned long *msg);
-int msvdx_poll_mtx_irq(igd_context_t *context);
-void msvdx_mtx_interrupt_plb(igd_context_t *context);
-void populate_fence_id(igd_context_t *context, unsigned long *mtx_msgs,
- unsigned long mtx_msg_cnt);
-int process_mtx_messages(igd_context_t *context,
- unsigned long *mtx_msgs, unsigned long mtx_msg_cnt,
- unsigned long fence);
-#ifdef DEBUG_BUILD_TYPE
-static void debug_mesg_info(igd_context_t *context,
- unsigned long *msg,
- unsigned long num_words);
-/* To eliminate warnings, am temporarily #ifdef'ing this function. Please
- * remove the #ifdef when this function is to be used.
- */
-#ifdef USE_DEBUG_DUMP
-static void debug_dump(igd_context_t *context);
-#endif
-static void lldma_dump(unsigned long *cmd_base, unsigned long offset);
-static void dump_all_messages(igd_context_t *context);
-#define DEBUG_MESG_INFO(a, b, c) debug_mesg_info(a, b, c)
-#define DEBUG_DUMP(a) debug_dump(a)
-#define LLDMA_DUMP(a, b) lldma_dump(a, b)
-#define DUMP_ALL_MESSAGES(a) dump_all_messages(a)
-#else
-#define DEBUG_MESG_INFO(a, b, c)
-#define DEBUG_DUMP(a)
-#define LLDMA_DUMP(a, b)
-#define DUMP_ALL_MESSAGES(a)
-#endif
-
-/* These are used to debug the message buffer */
-unsigned long *save_msg;
-unsigned long save_msg_cnt;
-
-
-int msvdx_dequeue_send(igd_context_t *context)
-{
- platform_context_plb_t *platform;
- struct msvdx_cmd_queue *msvdx_cmd = NULL;
- int ret = 0;
-
- EMGD_TRACE_ENTER;
-
- platform = (platform_context_plb_t *)context->platform_context;
-
- if (list_empty(&platform->msvdx_queue)) {
- //printk(KERN_ERR "MSVDXQUE: msvdx list empty\n");
- platform->msvdx_busy = 0;
- return -EINVAL;
- }
-
- //printk(KERN_INFO "MSVDXQUE: get from the msvdx list\n");
- msvdx_cmd = list_first_entry(&platform->msvdx_queue,
- struct msvdx_cmd_queue, head);
-
- ret = process_mtx_messages(context, msvdx_cmd->cmd, msvdx_cmd->cmd_size, platform->msvdx_fence);
-
- if (ret) {
- printk(KERN_ERR "MSVDXQUE: process_mtx_messages failed\n");
- ret = -EINVAL;
- }
-
- list_del(&msvdx_cmd->head);
- msvdx_cmd->cmd = NULL;
- kfree(msvdx_cmd);
-
- return ret;
-}
-
-void populate_fence_id(igd_context_t *context, unsigned long *mtx_msgs,
- unsigned long mtx_msg_cnt)
-{
- platform_context_plb_t *platform;
- unsigned long submit_size;
- unsigned long submit_id;
- unsigned int msg;
-
- platform = (platform_context_plb_t *)context->platform_context;
-
- for (msg = 0; msg < mtx_msg_cnt; msg++) {
- submit_size = (mtx_msgs[0] & 0x000000ff);
- submit_id = (mtx_msgs[0] & 0x0000ff00) >> 8;
-
- if (submit_id == IGD_MSGID_RENDER) {
- mtx_msgs[4] = ++platform->msvdx_fence;
- //printk(KERN_INFO "Update fence id %lx\n", mtx_msgs[4]);
- }
-
- mtx_msgs += (submit_size / sizeof(unsigned long));
- }
-}
-
-/*
- * The incoming command buffer holds MTX firmware messages, register pairs,
- * and the LLDMA linked lists. There is a simple header at the beginning of
- * the buffer that has the MTX message offset and the number of MTX messages.
- *
- * To process this buffer, find the MTX firmware messages and send each
- * one to the MTX firmware.
- */
-int process_mtx_messages(igd_context_t *context,
- unsigned long *mtx_msgs, unsigned long mtx_msg_cnt,
- unsigned long fence)
-{
- unsigned char *mmio = context->device_context.virt_mmadr;
- unsigned long submit_size;
- unsigned long submit_id;
- unsigned int msg;
- unsigned long skipped_msg_cnt;
-
- EMGD_TRACE_ENTER;
-
- save_msg = mtx_msgs;
- save_msg_cnt = mtx_msg_cnt;
- skipped_msg_cnt = 0;
-
- for (msg = 0; msg < mtx_msg_cnt; msg++) {
- submit_size = (mtx_msgs[0] & 0x000000ff);
- submit_id = (mtx_msgs[0] & 0x0000ff00) >> 8;
-
- if (submit_id != IGD_MSGID_RENDER) {
- /* Error, unknown message id, skip it */
- EMGD_ERROR("Unknown MTX message id 0x%lx", submit_id);
- skipped_msg_cnt++;
- continue;
- }
-
- /* reuse the sgx phy PD */
- mtx_msgs[1] = EMGD_READ32(mmio + PSB_CR_BIF_DIR_LIST_BASE1) | 1;
-
- /*
- * If the send returns busy, then retry sending the message, otherwise
- * move to next message in buffer.
- */
- if (send_to_mtx(context, (unsigned long *)mtx_msgs) != -IGD_ERROR_BUSY) {
- mtx_msgs += (submit_size / sizeof(unsigned long));
- /*
- * msvdx_mtx_interrupt_plb checks the firmware-to-host buffer
- * and if there are messages there, processes them.
- */
- //msvdx_mtx_interrupt_plb(context);
- } else {
- msg--; /* Reset count back to unsent message */
- /* Should this wait a bit? */
- }
- }
-
- EMGD_TRACE_EXIT;
- if (skipped_msg_cnt == mtx_msg_cnt) {
- /* We failed to submit anything; the entire buffer was bad.
- * Just return a failure code so we can unmark the video engine
- * busy bit. */
- return -IGD_ERROR_INVAL;
- } else {
- return 0;
- }
-}
-
-
-
-
-/*
- * This is the function that actually passes the message to the MTX
- * firmware. The contents of the message are opaque to this function.
- *
- * Currently, the only supported message type is RENDER.
- */
-int send_to_mtx(igd_context_t *context, unsigned long *msg)
-{
- unsigned char *mmio = context->device_context.virt_mmadr;
- unsigned long pad_msg;
- unsigned long num_words;
- unsigned long words_free;
- unsigned long read_idx, write_idx;
- platform_context_plb_t *platform =
- (platform_context_plb_t *)context->platform_context;
- int padding_flag = 0;
-
- EMGD_TRACE_ENTER;
-
- /* Enable all clocks before touching VEC local ram */
- EMGD_WRITE32(PSB_CLK_ENABLE_ALL, mmio + PSB_MSVDX_MAN_CLK_ENABLE);
-
- /* The first two longs in the msg have the message ID and size */
- num_words = ((msg[0] & 0xff) + 3) / 4;
-
- /* Is message too big? */
- if (num_words > platform->mtx_buf_size) {
- /* TODO: Error ? */
- EMGD_ERROR("Message is too large (size=%ld, max=%ld).", num_words,
- platform->mtx_buf_size);
- return -IGD_ERROR_INVAL;
- }
-
- /*
- * Safely increment the "number of messages in flight" counter, but only
- * if this isn't a "padding" message.
- */
- /*
- if (((msg[0] & 0xff00) >> 8) != FWRK_MSGID_PADDING) {
- platform->mtx_submitted++;
- }
- */
-
- /*
- * Make sure the MTX is enabled
- */
- EMGD_WRITE32(MSVDX_MTX_ENABLE_MTX_ENABLE_MASK, mmio + PSB_MSVDX_MTX_ENABLE);
-
-
- read_idx = EMGD_READ32(mmio + PSB_MSVDX_COMMS_TO_MTX_RD_INDEX);
- write_idx = EMGD_READ32(mmio + PSB_MSVDX_COMMS_TO_MTX_WRT_INDEX);
-
- EMGD_DEBUG("MTX read = 0x%08lx write = 0x%08lx", read_idx, write_idx);
-
- /*
- * Check to see if there is room for this message, if not send
- * a pad message to use up all the space and wait for the next
- * slot.
- */
- if ((write_idx + num_words) > platform->mtx_buf_size) {
- /*
- * if the read pointer is at zero, then the engine is probably
- * hung and not processing the message. This is bad.
- */
- if (read_idx == 0) {
- platform->msvdx_needs_reset = 1;
- EMGD_ERROR("MSVDX Engine is hung? Aborting send.");
- DUMP_ALL_MESSAGES(context);
- return -IGD_ERROR_BUSY;
- }
-
- /*
- * The message id and size are encoded into the first word of
- * the message.
- * bits 0:7 size (in long words?)
- * bits 8:15 message id
- */
- pad_msg = (platform->mtx_buf_size - write_idx) << 2; /* size */
- pad_msg |= (FWRK_MSGID_PADDING << 8); /* message id */
- EMGD_DEBUG("Sending a pad_mesg: 0x%x, size = %ld", FWRK_MSGID_PADDING,
- (pad_msg & 0xff));
-
- /*
- * Maybe just try writing the message directly here, instead of calling
- * this fuction recursivly??
- */
- EMGD_WRITE32(pad_msg,
- mmio + platform->mtx_buf_offset + (write_idx << 2));
- write_idx = 0;
-
- /* Update the write index to the next free location */
- EMGD_WRITE32(write_idx, mmio + PSB_MSVDX_COMMS_TO_MTX_WRT_INDEX);
- EMGD_READ32(mmio + PSB_MSVDX_COMMS_TO_MTX_WRT_INDEX);
-
- padding_flag = 1;
- }
-
- /* Verify free space available */
- words_free = (write_idx >= read_idx) ?
- platform->mtx_buf_size - (write_idx - read_idx) : read_idx - write_idx;
-
- if (num_words > (words_free - 1)) {
- /* There is no space available, this isn't an error */
-
- if (padding_flag) {
- /* Make sure clocks are enabled before we kick */
- EMGD_WRITE32(PSB_CLK_ENABLE_ALL, mmio + PSB_MSVDX_MAN_CLK_ENABLE);
-
- /* Send an interrupt to the MTX to let it know about the message */
- EMGD_WRITE32(1, mmio + PSB_MSVDX_MTX_KICK);
- }
-
- return - IGD_ERROR_BUSY;
- }
-
- /*
- * DEBUGGING info:
- * Call a function to try and output some debugging info about the message
- */
- /* DEBUG_MESG_INFO(context, msg, num_words); */
-
- /* Write the message to the firmware */
- while (num_words > 0) {
- EMGD_WRITE32(*msg++,
- mmio + platform->mtx_buf_offset + (write_idx << 2));
- num_words--;
- write_idx++;
- }
-
- /* Check for wrap in the buffer */
- if (write_idx == platform->mtx_buf_size) {
- write_idx = 0;
- }
-
- /* Update the write index to the next free location */
- EMGD_WRITE32(write_idx, mmio + PSB_MSVDX_COMMS_TO_MTX_WRT_INDEX);
-
- /* Check for overwrite */
- if (write_idx == read_idx) {
- EMGD_ERROR("Overwrite detected, resetting MSVDX.");
- platform->msvdx_needs_reset = 1;
- }
-
- /* Send an interrupt to the MTX to let it know about the message */
- EMGD_WRITE32(1, mmio + PSB_MSVDX_MTX_KICK);
-
-#if 0
- DEBUG_DUMP(context); /* For lots of additional debugging info */
-#endif
-
- EMGD_TRACE_EXIT;
- return IGD_SUCCESS;
-}
-
-
-/*
- * This function will look at messages sent from the MTX Firmware
- * and decode them.
- */
-
-void msvdx_mtx_interrupt_plb(igd_context_t *context)
-{
- unsigned char *mmio = context->device_context.virt_mmadr;
- unsigned long msg[128];
- unsigned long read_idx, write_idx;
- unsigned long num_words;
- unsigned long msg_offset;
- unsigned long fence = 0;
- unsigned long flags = 0;
- unsigned long status;
- platform_context_plb_t *platform =
- (platform_context_plb_t *)context->platform_context;
-
- /* Check that the clocks are enabled before trying to read message */
- EMGD_WRITE32(PSB_CLK_ENABLE_ALL, mmio + PSB_MSVDX_MAN_CLK_ENABLE);
-
- do {
- read_idx = EMGD_READ32(mmio + PSB_MSVDX_COMMS_TO_HOST_RD_INDEX);
- write_idx = EMGD_READ32(mmio + PSB_MSVDX_COMMS_TO_HOST_WRT_INDEX);
- EMGD_DEBUG("HOST read=0x%lx write=0x%lx", read_idx, write_idx);
-
- if (read_idx != write_idx) {
- /* Read the first waiting message from the buffer */
- msg_offset = 0;
- msg[msg_offset] = EMGD_READ32(mmio + (platform->host_buf_offset +
- (read_idx << 2)));
-
- /* Size of message rounded to nearest number of words */
- num_words = ((msg[0] & 0x000000ff) + 3) / 4;
-
- if (++read_idx >= platform->host_buf_size) {
- read_idx = 0;
- }
-
- for (msg_offset++; msg_offset < num_words; msg_offset++) {
- msg[msg_offset] = EMGD_READ32(mmio + platform->host_buf_offset +
- (read_idx << 2));
-
- if (++read_idx >= platform->host_buf_size) {
- read_idx = 0;
- }
- }
-
- EMGD_WRITE32(read_idx, mmio + PSB_MSVDX_COMMS_TO_HOST_RD_INDEX);
-
- /* Check message ID */
- switch ((msg[0] & 0x0000ff00) >> 8) {
- case IGD_MSGID_CMD_FAILED:
- fence = msg[1]; /* Fence value */
- status = msg[2]; /* Failed IRQ Status */
- printk(KERN_ERR "MSGID_CMD_FAILED, status = 0x%lx, fence = 0x%lx",
- status, fence);
-
- /* This message from MTX is for informational purposes and
- firmware does not expect hardware to be reset */
- platform->msvdx_needs_reset = 1;
-
- if (msg[1] != 0) {
- platform->mtx_completed = fence;
- }
- DUMP_ALL_MESSAGES(context);
- goto done;
- break;
- case IGD_MSGID_CMD_COMPLETED:
- fence = msg[1];
- flags = msg[2];
-
- //printk(KERN_INFO "MSGID_CMD_COMPLETED: fence 0x%lx", fence);
- platform->mtx_completed = fence;
-
- if (flags & FW_VA_RENDER_HOST_INT) {
- spin_lock(&platform->msvdx_lock);
- msvdx_dequeue_send(context);
- spin_unlock(&platform->msvdx_lock);
- }
-
- break;
- case IGD_MSGID_CMD_HW_PANIC:
- fence = msg[1]; /* Fence value */
- status = msg[2]; /* Failed IRQ Status */
- printk(KERN_ERR "MSGID_CMD_HW_PANIC: fence 0x%08lx, Irq 0x%08lx",
- msg[1], msg[2]);
- platform->msvdx_needs_reset = 1;
- platform->mtx_completed = fence;
- DUMP_ALL_MESSAGES(context);
- goto done;
- break;
- default:
- EMGD_ERROR("Unknown message ID 0x%lx response from firmware.", (msg[0] & 0x0000ff00) >> 8);
- break;
- }
-
- }
- } while (read_idx != write_idx);
-
-done:
- if (1) { };
-}
-
-
-/*
- * Simple function to check for a MSVDX interrupt. Clear the interrupt status
- * if one occured. Mostly just ignore them for now.
- */
-
-#define MSVDX_MMU_FAULT_IRQ_MASK 0x00000F00
-#define MSVDX_MTX_IRQ_MASK 0x00004000
-#define MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_MASK 0x00000002
-
-int msvdx_poll_mtx_irq(igd_context_t *context)
-{
- unsigned char *mmio = context->device_context.virt_mmadr;
- unsigned long status;
- platform_context_plb_t *platform =
- (platform_context_plb_t *)context->platform_context;
- int poll_cnt = 100;
-
- EMGD_TRACE_ENTER;
-
- while (poll_cnt) {
- status = EMGD_READ32(mmio + PSB_MSVDX_INTERRUPT_STATUS);
- if (status & MSVDX_MMU_FAULT_IRQ_MASK) {
- EMGD_ERROR("MMU FAULT Interrupt");
- /* Pause the MMU */
- EMGD_WRITE32(MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_MASK,
- mmio + PSB_MSVDX_MMU_CONTROL0);
-
- /* Clear interrupt bit */
- EMGD_WRITE32(MSVDX_MMU_FAULT_IRQ_MASK,
- mmio + PSB_MSVDX_INTERRUPT_CLEAR);
- EMGD_READ32(mmio + PSB_MSVDX_INTERRUPT_CLEAR);
-
- platform->msvdx_needs_reset = 1;
- DUMP_ALL_MESSAGES(context);
- return 0;
- } else if (status & MSVDX_MTX_IRQ_MASK) {
- /* Clear all interrupt bits */
- EMGD_WRITE32(0xffff, mmio + PSB_MSVDX_INTERRUPT_CLEAR);
- EMGD_READ32(mmio + PSB_MSVDX_INTERRUPT_CLEAR);
-
- msvdx_mtx_interrupt_plb(context);
- return 0;
- } else if (status) {
- /* Might want to make this debug only. */
- if (status & 0x00000001) EMGD_DEBUG("IRQ - VEC_END_OF_SLICE");
- if (status & 0x00000002) EMGD_DEBUG("IRQ - VEC_ERROR_DETECTETED_SR");
- if (status & 0x00000004) EMGD_DEBUG("IRQ - VEC_ERROR_DETECTETED_ENTDEC");
- if (status & 0x00000008) EMGD_DEBUG("IRQ - VEC_RENDEC_ERROR");
- if (status & 0x00000010) EMGD_DEBUG("IRQ - VEC_RENDEC_OVERFLOW");
- if (status & 0x00000020) EMGD_DEBUG("IRQ - VEC_RENDEC_UNDERFLOW");
- if (status & 0x00000040) EMGD_DEBUG("IRQ - VEC_RENDEC_MTXBLOCK");
- if (status & 0x00000080) EMGD_DEBUG("IRQ - VEC_RENDEC_END_OF_SLICE");
- if (status & 0x00000100) EMGD_DEBUG("IRQ - MMU_FAULT_IRQ");
- if (status & 0x00000200) EMGD_DEBUG("IRQ - MMU_FAULT_IRQ");
- if (status & 0x00000400) EMGD_DEBUG("IRQ - MMU_FAULT_IRQ");
- if (status & 0x00000800) EMGD_DEBUG("IRQ - MMU_FAULT_IRQ");
- if (status & 0x00001000) EMGD_DEBUG("IRQ - FE_WDT_CM0");
- if (status & 0x00002000) EMGD_DEBUG("IRQ - FE_WDT_CM1");
- if (status & 0x00004000) EMGD_DEBUG("IRQ - MTX_IRQ");
- if (status & 0x00008000) EMGD_DEBUG("IRQ - MTX_GPIO_IRQ");
- if (status & 0x00010000) EMGD_DEBUG("IRQ - VDMC_IRQ");
- if (status & 0x00020000) EMGD_DEBUG("IRQ - VDEB_PICTURE_DONE_IRQ");
- if (status & 0x00040000) EMGD_DEBUG("IRQ - VDEB_SLICE_DONE_IRQ");
- if (status & 0x00080000) EMGD_DEBUG("IRQ - VDEB_FLUSH_DONE_IRQ");
- if (status & 0x00100000) EMGD_DEBUG("IRQ - DMAC_IRQ");
- if (status & 0x00200000) EMGD_DEBUG("IRQ - DMAC_IRQ");
- if (status & 0x00400000) EMGD_DEBUG("IRQ - DMAC_IRQ");
- if (status & 0x00800000) EMGD_DEBUG("IRQ - VDEB_FAULT_IRQ");
- if (status & 0x01000000) EMGD_DEBUG("IRQ - SYS_COMMAND_TIMEOUT_IRQ");
- if (status & 0x02000000) EMGD_DEBUG("IRQ - SYS_READ_TIMEOUT_IRQ");
- if (status & 0x04000000) EMGD_DEBUG("IRQ - MTX_COMMAND_TIMEOUT_IRQ");
- if (status & 0x08000000) EMGD_DEBUG("IRQ - MTX_READ_TIMEOUT_IRQ");
- if (status & 0x10000000) EMGD_DEBUG("IRQ - SYS_WDT");
- if (status & 0x20000000) EMGD_DEBUG("IRQ - BE_WDT_CM0");
- if (status & 0x40000000) EMGD_DEBUG("IRQ - BE_WDT_CM1");
- if (status & 0x80000000) EMGD_DEBUG("IRQ - VEC_RENDEC_SLICE_SKIPPED");
-
- EMGD_DEBUG(" Watchdog Control = 0x%x 0x%x 0x%x",
- EMGD_READ32(mmio + MSVDX_BASE + 0x0670),
- EMGD_READ32(mmio + MSVDX_BASE + 0x0674),
- EMGD_READ32(mmio + MSVDX_BASE + 0x0678));
-
- /* Clear the interrupt */
- EMGD_WRITE32(status, mmio + PSB_MSVDX_INTERRUPT_CLEAR);
- EMGD_READ32(mmio + PSB_MSVDX_INTERRUPT_CLEAR);
- return 0;
- }
-
- poll_cnt--;
- OS_SLEEP(10);
- }
-
- EMGD_ERROR("Timout polling interrupt status.");
- return 1;
-}
-
-
-/*
- * msvdx_mtx_irq
- *
- * Process a MTX interrupt. Look at the interrupt status bits
- * and do the processing dictated by the bits. Currently only
- * two interrupts are really handled:
- * MMU Fault, which pauses the MMU
- * MTX IRQ, which then processes any firmware to hosts messages
- * Other interrupts will output a debugging message. These are fault
- * conditions that are not handled.
- *
- * return 0 if the IRQ was handled
- * return 1 if it wasn't
- */
-//static void msvdx_mtx_irq(struct drm_device *dev)
-IMG_BOOL msvdx_mtx_isr(IMG_VOID *pvData)
-{
- struct drm_device *dev;
- drm_emgd_private *priv;
- igd_context_t *context;
- unsigned char *mmio;
- platform_context_plb_t *platform;
- unsigned long msvdx_stat;
-
- //EMGD_TRACE_ENTER;
- dev = (struct drm_device *)pvData;
- priv = dev->dev_private;
- context = priv->context;
- mmio = context->device_context.virt_mmadr;
- platform = context->platform_context;
-
- msvdx_stat = EMGD_READ32(mmio + PSB_MSVDX_INTERRUPT_STATUS);
-
- //printk(KERN_ALERT "MSVDX_IRQ");
-
- if (msvdx_stat & MSVDX_MMU_FAULT_IRQ_MASK) {
- printk(KERN_ERR "MMU FAULT Interrupt\n");
- /* Pause the MMU */
- EMGD_WRITE32(MSVDX_MMU_CONTROL0_CR_MMU_PAUSE_MASK,
- mmio + PSB_MSVDX_MMU_CONTROL0);
-
-
- EMGD_WRITE32(MSVDX_MMU_FAULT_IRQ_MASK,
- mmio + PSB_MSVDX_INTERRUPT_CLEAR);
-
- printk(KERN_INFO "FAULT ADDR=%x\n", EMGD_READ32(mmio + PSB_MSVDX_MMU_STATUS));
- platform->msvdx_needs_reset = 1;
- DUMP_ALL_MESSAGES(context);
- //return 0;
- } else if (msvdx_stat & MSVDX_MTX_IRQ_MASK) {
- /* Read the firmware to host messages */
-
- EMGD_WRITE32(0xffff, mmio + PSB_MSVDX_INTERRUPT_CLEAR);
- EMGD_READ32(mmio + PSB_MSVDX_INTERRUPT_CLEAR);
- msvdx_mtx_interrupt_plb(context);
- //return 0;
- } else if (msvdx_stat) {
- /*
- * Print a debug message for any other interrupt cases.
- */
- if (msvdx_stat & 0x00000001) printk(KERN_INFO "IRQ - VEC_END_OF_SLICE\n");
- if (msvdx_stat & 0x00000002) printk(KERN_INFO "IRQ - VEC_ERROR_DETECTETED_SR\n");
- if (msvdx_stat & 0x00000004) printk(KERN_INFO "IRQ - VEC_ERROR_DETECTETED_ENTDEC\n");
- if (msvdx_stat & 0x00000008) printk(KERN_INFO "IRQ - VEC_RENDEC_ERROR\n");
- if (msvdx_stat & 0x00000010) printk(KERN_INFO "IRQ - VEC_RENDEC_OVERFLOW\n");
- if (msvdx_stat & 0x00000020) printk(KERN_INFO "IRQ - VEC_RENDEC_UNDERFLOW\n");
- if (msvdx_stat & 0x00000040) printk(KERN_INFO "IRQ - VEC_RENDEC_MTXBLOCK\n");
- if (msvdx_stat & 0x00000080) printk(KERN_INFO "IRQ - VEC_RENDEC_END_OF_SLICE\n");
- if (msvdx_stat & 0x00000100) printk(KERN_INFO "IRQ - MMU_FAULT_IRQ\n");
- if (msvdx_stat & 0x00000200) printk(KERN_INFO "IRQ - MMU_FAULT_IRQ\n");
- if (msvdx_stat & 0x00000400) printk(KERN_INFO "IRQ - MMU_FAULT_IRQ\n");
- if (msvdx_stat & 0x00000800) printk(KERN_INFO "IRQ - MMU_FAULT_IRQ\n");
- if (msvdx_stat & 0x00001000) printk(KERN_INFO "IRQ - FE_WDT_CM0\n");
- if (msvdx_stat & 0x00002000) printk(KERN_INFO "IRQ - FE_WDT_CM1\n");
- if (msvdx_stat & 0x00004000) printk(KERN_INFO "IRQ - MTX_IRQ\n");
- if (msvdx_stat & 0x00008000) printk(KERN_INFO "IRQ - MTX_GPIO_IRQ\n");
- if (msvdx_stat & 0x00010000) printk(KERN_INFO "IRQ - VDMC_IRQ\n");
- if (msvdx_stat & 0x00020000) printk(KERN_INFO "IRQ - VDEB_PICTURE_DONE_IRQ\n");
- if (msvdx_stat & 0x00040000) printk(KERN_INFO "IRQ - VDEB_SLICE_DONE_IRQ\n");
- if (msvdx_stat & 0x00080000) printk(KERN_INFO "IRQ - VDEB_FLUSH_DONE_IRQ\n");
- if (msvdx_stat & 0x00100000) printk(KERN_INFO "IRQ - DMAC_IRQ\n");
- if (msvdx_stat & 0x00200000) printk(KERN_INFO "IRQ - DMAC_IRQ\n");
- if (msvdx_stat & 0x00400000) printk(KERN_INFO "IRQ - DMAC_IRQ\n");
- if (msvdx_stat & 0x00800000) printk(KERN_INFO "IRQ - VDEB_FAULT_IRQ\n");
- if (msvdx_stat & 0x01000000) printk(KERN_INFO "IRQ - SYS_COMMAND_TIMEOUT_IRQ\n");
- if (msvdx_stat & 0x02000000) printk(KERN_INFO "IRQ - SYS_READ_TIMEOUT_IRQ\n");
- if (msvdx_stat & 0x04000000) printk(KERN_INFO "IRQ - MTX_COMMAND_TIMEOUT_IRQ\n");
- if (msvdx_stat & 0x08000000) printk(KERN_INFO "IRQ - MTX_READ_TIMEOUT_IRQ\n");
- if (msvdx_stat & 0x10000000) printk(KERN_INFO "IRQ - SYS_WDT\n");
- if (msvdx_stat & 0x20000000) printk(KERN_INFO "IRQ - BE_WDT_CM0\n");
- if (msvdx_stat & 0x40000000) printk(KERN_INFO "IRQ - BE_WDT_CM1\n");
- if (msvdx_stat & 0x80000000) printk(KERN_INFO "IRQ - VEC_RENDEC_SLICE_SKIPPED\n");
-
- printk(KERN_INFO " Watchdog Control = 0x%x 0x%x 0x%x\n",
- EMGD_READ32(mmio + MSVDX_BASE + 0x0670),
- EMGD_READ32(mmio + MSVDX_BASE + 0x0674),
- EMGD_READ32(mmio + MSVDX_BASE + 0x0678));
-
- return 0;
- }
- /*
- else {
- return ;
- } */
- return IMG_TRUE;
-}
-
-
-#ifdef DEBUG_BUILD_TYPE
-
-static void dump_all_messages(igd_context_t *context)
-{
- unsigned long msg;
- unsigned long submit_size;
- unsigned long num_words;
-
- if (save_msg) {
- for (msg = 0; msg < save_msg_cnt; msg++) {
- submit_size = (save_msg[0] & 0x000000ff);
- num_words = ((save_msg[0] & 0xff) + 3) / 4;
-
- DEBUG_MESG_INFO(context, save_msg, num_words);
-
- save_msg += (submit_size / sizeof(unsigned long));
- }
-
- save_msg = NULL;
- save_msg_cnt = 0;
- }
-}
-
-/*
- * This function is for debugging firmware messages. It should not be part of the
- * production code. Make sure it is removed (if def'ed out) before building a
- * production version.
- */
-
-static void debug_mesg_info(igd_context_t *context,
- unsigned long *msg,
- unsigned long num_words)
-{
- unsigned long msg_size;
- unsigned char msg_id;
- unsigned short buffer_size;
- unsigned long buffer_address;
- unsigned short last_mb;
- unsigned short first_mb;
- unsigned long *cmd_base;
-
- msg_size = (msg[0] & 0xff);
- msg_id = (unsigned char)((msg[0] & 0xff00) >> 8);
- buffer_size = (unsigned short)((msg[0] & 0xffff0000) >> 16);
-
- EMGD_DEBUG("MSG: size = %ld, id = 0x%x, buffer_size = %d",
- msg_size, msg_id, buffer_size);
- if (msg_size > 4) {
- EMGD_DEBUG("MSG: MMUPTD = 0x%08lx", msg[1]);
- }
- if (msg_size > 8) {
- buffer_address = msg[2];
- cmd_base = (unsigned long *)context->dispatch.gmm_map(buffer_address);
- EMGD_DEBUG("MSG: Buffer Offset = 0x%08lx", buffer_address);
- EMGD_DEBUG("MSG: Context id = 0x%lx", msg[3]);
- EMGD_DEBUG("MSG: Fence value = 0x%lx", msg[4]);
- EMGD_DEBUG("MSG: Operating Mode = 0x%lx", msg[5]);
- last_mb = (unsigned short)((msg[6] & 0xffff0000) >> 16);
- first_mb = (unsigned short)(msg[6] & 0x0000ffff);
- EMGD_DEBUG("MSG: First MB = %d, last mb = %d", first_mb, last_mb);
- EMGD_DEBUG("MSG: Flags = 0x%lx", msg[7]);
-
- /* Dump some of the lldma contents here */
- LLDMA_DUMP(cmd_base, buffer_address);
- }
-}
-
-
-/* To eliminate warnings, am temporarily #ifdef'ing this function. Please
- * remove the #ifdef when this function is to be used.
- */
-#ifdef USE_DEBUG_DUMP
-/*
- * This function dumps the to firmware message buffer.
- */
-static void debug_dump(igd_context_t *context)
-{
- unsigned char *mmio = context->device_context.virt_mmadr;
- unsigned long read_idx, write_idx;
- unsigned long i;
- platform_context_plb_t *platform;
-
- platform = (platform_context_plb_t *)context->platform_context;
- read_idx = EMGD_READ32(mmio + PSB_MSVDX_COMMS_TO_HOST_RD_INDEX);
- write_idx = EMGD_READ32(mmio + PSB_MSVDX_COMMS_TO_HOST_WRT_INDEX);
- EMGD_DEBUG("HOST buffer: RDIDX 0x%08lx WRIDX 0x%08lx, %lu",
- read_idx, write_idx, platform->host_buf_size);
- for (i = 0; (i < read_idx || i < write_idx); i++) {
- unsigned long value =
- EMGD_READ32(mmio + platform->host_buf_offset + (i <<2));
- EMGD_DEBUG(" %02lx: 0x%08lx", i, value);
- }
-
- read_idx = EMGD_READ32(mmio + PSB_MSVDX_COMMS_TO_MTX_RD_INDEX);
- write_idx = EMGD_READ32(mmio + PSB_MSVDX_COMMS_TO_MTX_WRT_INDEX);
- EMGD_DEBUG("MTX buffer: RDIDX 0x%08lx WRIDX 0x%08lx, %lu",
- read_idx, write_idx, platform->mtx_buf_size);
- for (i = 0; (i < read_idx || i < write_idx); i++) {
- unsigned long value =
- EMGD_READ32(mmio + platform->mtx_buf_offset + (i <<2));
- EMGD_DEBUG(" %02lx: 0x%08lx", i, value);
- }
-}
-#endif
-
-unsigned long lldma_decode(unsigned long val,
- unsigned long to,
- unsigned long from)
-{
- if (to < 31) {
- val &= ~(0xffffffff << (to + 1));
- }
- val = val >> from;
-
- return val;
-}
-
-static void lldma_dump(unsigned long *cmd_base, unsigned long offset)
-{
- int i;
-
- for (i = 0; i < 8; i++) {
- if (i == 0) {
- EMGD_DEBUG(" 0x%08lx LLDMA: BSWAP = %ld", offset, lldma_decode(*cmd_base, 31, 31));
- EMGD_DEBUG(" LLDMA: DIR = %ld", lldma_decode(*cmd_base, 30, 30));
- EMGD_DEBUG(" LLDMA: PW = %ld", lldma_decode(*cmd_base, 29, 28));
- } else if (i == 1) {
- EMGD_DEBUG(" 0x%08lx LLDMA: List_Fin = %ld", offset+1, lldma_decode(*cmd_base, 31, 31));
- EMGD_DEBUG(" LLDMA: List_INT = %ld", lldma_decode(*cmd_base, 30, 30));
- EMGD_DEBUG(" LLDMA: PI = %ld", lldma_decode(*cmd_base, 18, 17));
- EMGD_DEBUG(" LLDMA: INCR = %ld", lldma_decode(*cmd_base, 16, 16));
- EMGD_DEBUG(" LLDMA: LEN = %ld", lldma_decode(*cmd_base, 15, 0));
- } else if (i == 2) {
- EMGD_DEBUG(" 0x%08lx LLDMA: ADDR = 0x%lx", offset+2, lldma_decode(*cmd_base, 22, 0));
- } else if (i == 3) {
- EMGD_DEBUG(" 0x%08lx LLDMA: ACC_DEL = %ld", offset+3, lldma_decode(*cmd_base, 31, 29));
- EMGD_DEBUG(" LLDMA: BURST = %ld", lldma_decode(*cmd_base, 28, 26));
- EMGD_DEBUG(" LLDMA: EXT_SA = 0x%lx", lldma_decode(*cmd_base, 3, 0));
- } else if (i == 4) {
- EMGD_DEBUG(" 0x%08lx LLDMA: 2D_MODE = %ld", offset+4, lldma_decode(*cmd_base, 16, 16));
- EMGD_DEBUG(" LLDMA: REP_CNT = %ld", lldma_decode(*cmd_base, 10, 0));
- } else if (i == 5) {
- EMGD_DEBUG(" 0x%08lx LLDMA: LINE_ADD = 0x%lx", offset+5, lldma_decode(*cmd_base, 25, 16));
- EMGD_DEBUG(" LLDMA: ROW_LEN = %ld", lldma_decode(*cmd_base, 9, 0));
- } else if (i == 6) {
- EMGD_DEBUG(" 0x%08lx LLDMA: SA = 0x%lx", offset+6, lldma_decode(*cmd_base, 31, 0));
- } else if (i == 7) {
- EMGD_DEBUG(" 0x%08lx LLDMA: LISTPTR = 0x%lx", offset+7, lldma_decode(*cmd_base, 27, 0));
- }
- cmd_base++;
- }
-}
-#endif