2
*-----------------------------------------------------------------------------
3
* Filename: msvdx_init.c
5
*-----------------------------------------------------------------------------
6
* Copyright © 2002-2010, Intel Corporation.
8
* This program is free software; you can redistribute it and/or modify it
9
* under the terms and conditions of the GNU General Public License,
10
* version 2, as published by the Free Software Foundation.
12
* This program is distributed in the hope it will be useful, but WITHOUT
13
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17
* You should have received a copy of the GNU General Public License along with
18
* this program; if not, write to the Free Software Foundation, Inc.,
19
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21
*-----------------------------------------------------------------------------
23
* Initialize the MSVDX video engine. This loads the MTX firmware and
24
* starts a MTX thread running the firmware.
25
* The host communicates with the firmware via messages. The following
26
* messages are supported:
33
* CMD_COMPLETED <- MTX
34
* CMD_COMPLTED_BATCH <- MTX
35
* DEBLOCK_REQUIRED <- MTX
36
* TEST_RESPONSE <- MTX
39
*-----------------------------------------------------------------------------
48
#include <igd_errno.h>
58
#include <plb/context.h>
60
#include <drm_emgd_private.h>
64
struct drm_device *gpDrmDevice = NULL;
65
static int init_msvdx_first_time = 1;
67
extern void send_to_mtx(igd_context_t *context, unsigned long *init_msg);
68
extern int process_mtx_messages(igd_context_t *context,
69
unsigned long *mtx_msgs, unsigned long mtx_msg_cnt,
72
extern void populate_fence_id(igd_context_t *context, unsigned long *mtx_msgs,
73
unsigned long mtx_msg_cnt);
74
extern int msvdx_dequeue_send(igd_context_t *context);
75
extern int alloc_ramdec_region(unsigned long *base_addr0, unsigned long *base_addr1,
76
unsigned long size0, unsigned long size1);
78
static int poll_mtx_irq(igd_context_t *context);
79
static int reg_ready_psb(igd_context_t *context, unsigned long reg,
80
unsigned long mask, unsigned long value);
81
static int context_count = 0;
83
void msvdx_reset_plb(igd_context_t *context);
85
static msvdx_fw_t *priv_fw = NULL;
87
extern unsigned long jiffies_at_last_dequeue;
90
int msvdx_query_plb(igd_context_t *context,
91
unsigned long *status)
93
platform_context_plb_t *platform;
97
platform = (platform_context_plb_t *)context->platform_context;
101
*status |= VIDEO_STATE_FW_LOADED;
104
if(!platform->rendec_base0 || !platform->rendec_base1) {
105
*status |= VIDEO_STATE_RENDEC_FREED;
112
int msvdx_pre_init_plb(struct drm_device *dev)
122
int msvdx_init_plb(unsigned long base0, unsigned long base1,
123
void *msvdx_fw, unsigned long msvdx_fw_size)
125
drm_emgd_private *priv;
126
igd_context_t *context;
128
unsigned long ram_bank;
129
unsigned long bank_size;
130
unsigned long current_bank;
131
unsigned long address;
132
unsigned long acc_control;
133
unsigned long base_addr0, base_addr1, size0, size1;
134
unsigned long ram_id;
137
unsigned long fw_size;
138
unsigned long *fw_data;
139
msvdx_fw_t *fw = NULL;
140
platform_context_plb_t *platform = NULL;
142
if (!priv_fw && msvdx_fw) {
143
fw = (msvdx_fw_t *) msvdx_fw;
144
priv_fw = kzalloc(sizeof(msvdx_fw_t), GFP_KERNEL);
145
priv_fw->fw_text_size = fw->fw_text_size;
146
priv_fw->fw_data_size = fw->fw_data_size;
147
priv_fw->fw_version_size = fw->fw_version_size;
148
priv_fw->fw_data_location = fw->fw_data_location;
150
fw_size = sizeof(unsigned long) * fw->fw_text_size;
151
priv_fw->fw_text = kmalloc(fw_size, GFP_KERNEL);
152
memcpy(priv_fw->fw_text, (void *) ((unsigned long) msvdx_fw) +
153
((unsigned long) fw->fw_text), fw_size);
155
fw_size = sizeof(unsigned long) * fw->fw_data_size;
156
priv_fw->fw_data = kmalloc(fw_size, GFP_KERNEL);
157
memcpy(priv_fw->fw_data, (void *) ((unsigned long) msvdx_fw) +
158
((unsigned long) fw->fw_data), fw_size);
160
priv_fw->fw_version = kzalloc(priv_fw->fw_version_size, GFP_KERNEL);
161
strcpy(priv_fw->fw_version, (char *) (((unsigned long) msvdx_fw) +
162
((unsigned long) fw->fw_version)));
163
} else if (!priv_fw) {
164
printk(KERN_INFO "Kernel firmware is not loaded");
169
priv = gpDrmDevice->dev_private;
170
context = priv->context;
171
mmio = context->device_context.virt_mmadr;
173
//init_msvdx_first_time = 1;
174
/* Reset MSVDX engine */
175
EMGD_WRITE32(0x00000100, mmio + PSB_MSVDX_CONTROL);
176
reg_ready_psb(context, PSB_MSVDX_CONTROL, 0x00000100, 0);
179
* Make sure the clock is on.
181
* Clock enable bits are 0 - 6, with each bit controlling one of the
182
* clocks. For this, make sure all the clocks are enabled.
184
EMGD_WRITE32(PSB_CLK_ENABLE_ALL, mmio + PSB_MSVDX_MAN_CLK_ENABLE);
186
/* Set default MMU PTD to the same value used by the SGX */
187
ctrl = EMGD_READ32(mmio + PSB_CR_BIF_DIR_LIST_BASE1);
189
address = EMGD_READ32(mmio + PSB_CR_BIF_DIR_LIST_BASE1);
190
EMGD_WRITE32(address, mmio + PSB_MSVDX_MMU_DIR_LIST_BASE0);
191
EMGD_WRITE32(address, mmio + PSB_MSVDX_MMU_DIR_LIST_BASE1);
192
EMGD_WRITE32(address, mmio + PSB_MSVDX_MMU_DIR_LIST_BASE2);
193
EMGD_WRITE32(address, mmio + PSB_MSVDX_MMU_DIR_LIST_BASE3);
200
* MMU TTE threshold = 12
202
EMGD_WRITE32(0xc070000c, mmio + PSB_MSVDX_MMU_CONTROL1);
205
/* Flush the directory cache */
206
ctrl = EMGD_READ32(mmio + PSB_MSVDX_MMU_CONTROL0) | 0x0C; /* Flush */
207
EMGD_WRITE32(ctrl, mmio + PSB_MSVDX_MMU_CONTROL0);
209
/* Enable MMU by removing all bypass bits */
210
EMGD_WRITE32(0, mmio + PSB_MSVDX_MMU_CONTROL0);
213
/* Set up the RENDEC.
214
* The RENDEC requires two blocks of virtual address space so those
215
* must be allocated and then the RENDEC is initialized using those
219
* bit 3 1 - search MTX_to_MTX header
220
* bit 2 1 - skip next slice
221
* bit 1 1 - flush remaining bit stream
222
* bit 0 1 - initialize RENDEC
225
* bit 24: 1 - enables data to be transferred through ext. memory
226
* bit 19:18 WR burst size (0 = 32 bytes, 1 = 64 bytes, 2 = 128 bytes)
227
* bit 17:16 RD burst size (0 = 32 bytes, 1 = 64 bytes, 2 = 128 bytes)
228
* bit 7: 0 start size (zero)
231
size0 = RENDEC_A_SIZE;
232
size1 = RENDEC_B_SIZE;
235
* These allocations need to be undone when shutting down. Where
236
* should they be saved?
238
if (init_msvdx_first_time) {
242
//printk(KERN_INFO "get the base_addr=%lx, base_addr1=%lx\n", base_addr0,base_addr1);
244
/* Save the offsets so it can be freed and restored later */
245
platform = (platform_context_plb_t *)context->platform_context;
246
platform->rendec_base0 = base_addr0;
247
platform->rendec_base1 = base_addr1;
249
init_msvdx_first_time = 0;
250
INIT_LIST_HEAD(&platform->msvdx_queue);
251
spin_lock_init(&platform->msvdx_lock);
253
/* restore offsets. */
254
platform = (platform_context_plb_t *)context->platform_context;
255
base_addr0 = platform->rendec_base0;
256
base_addr1 = platform->rendec_base1;
258
/* Init link list to fix HSD202831 */
260
INIT_LIST_HEAD(&platform->msvdx_queue);
264
platform->msvdx_busy = 0;
265
EMGD_WRITE32(base_addr0, mmio + PSB_MSVDX_RENDEC_BASE_ADDR0);
266
EMGD_WRITE32(base_addr1, mmio + PSB_MSVDX_RENDEC_BASE_ADDR1);
268
EMGD_WRITE32((((size1 / 4096) << 16) | (size0 / 4096)),
269
mmio + PSB_MSVDX_RENDEC_BUFFER_SIZE);
273
* Burst size R = 4 words
274
* Burst size W = 4 words
275
* External memory enabled
280
EMGD_WRITE32(0x01050000, mmio + PSB_MSVDX_RENDEC_CONTROL1);
282
EMGD_WRITE32(0x00101010, mmio + PSB_MSVDX_RENDEC_CONTEXT0);
283
EMGD_WRITE32(0x00101010, mmio + PSB_MSVDX_RENDEC_CONTEXT1);
284
EMGD_WRITE32(0x00101010, mmio + PSB_MSVDX_RENDEC_CONTEXT2);
285
EMGD_WRITE32(0x00101010, mmio + PSB_MSVDX_RENDEC_CONTEXT3);
286
EMGD_WRITE32(0x00101010, mmio + PSB_MSVDX_RENDEC_CONTEXT4);
287
EMGD_WRITE32(0x00101010, mmio + PSB_MSVDX_RENDEC_CONTEXT5);
289
EMGD_WRITE32(0x00000001, mmio + PSB_MSVDX_RENDEC_CONTROL0);
292
/* Start Firmware Load process */
295
EMGD_WRITE32(0x00000001, mmio + PSB_MSVDX_MTX_SOFT_RESET);
297
/* Reset the counter that looks for MSVDX getting into a bad state */
298
jiffies_at_last_dequeue = 0;
301
* Should this check the core revision and only do this if it is
302
* a specific version or range of versions?
304
* Stepping prior to D0, need to set COMMS_OFFSET_FLAGS to 0
305
* Stepping D0 should set MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D0 (0x222)
306
* Stepping D1 should set MSVDX_DEVICE_NODE_FLAGS_DEFAULT_D1 (0x220)
309
/* If POULSBO_D1 or later use MSVDX_DEVICE_NODE_FLAGS_MMU_HW_INVALIDATION */
310
EMGD_WRITE32(MSVDX_DEVICE_NODE_FLAGS_DEFAULT,
311
mmio + PSB_MSVDX_COMMS_OFFSET_FLAGS);
312
/* Else EMGD_WRITE32(0x00, mmio + PSB_MSVDX_COMMS_OFFSET_FLAGS); */
314
/* Initialize communication control */
315
EMGD_WRITE32(0x00, mmio + PSB_MSVDX_COMMS_MSG_COUNTER);
316
EMGD_WRITE32(0x00, mmio + PSB_MSVDX_COMMS_SIGNATURE);
317
EMGD_WRITE32(0x00, mmio + PSB_MSVDX_COMMS_TO_HOST_RD_INDEX);
318
EMGD_WRITE32(0x00, mmio + PSB_MSVDX_COMMS_TO_HOST_WRT_INDEX);
319
EMGD_WRITE32(0x00, mmio + PSB_MSVDX_COMMS_TO_MTX_RD_INDEX);
320
EMGD_WRITE32(0x00, mmio + PSB_MSVDX_COMMS_TO_MTX_WRT_INDEX);
321
EMGD_WRITE32(0x00, mmio + PSB_MSVDX_COMMS_FW_STATUS);
324
* Get the ram bank size
325
* The banks size seems to be a 4 bit value in the MTX debug register.
326
* Where this is documented other than the UMG code is not clear.
328
ram_bank = EMGD_READ32(mmio + PSB_MSVDX_MTX_RAM_BANK);
329
bank_size = (ram_bank & 0x000f0000) >> 16;
330
bank_size = (1 << (bank_size + 2));
332
/* Firmware version? */
333
printk(KERN_INFO "Firmware version is %s\n", priv_fw->fw_version);
335
/* Save RAM access control register */
336
acc_control = EMGD_READ32(mmio + PSB_MSVDX_MTX_RAM_ACCESS_CONTROL);
338
/* Loop writing text/code to core memory */
340
address = PC_START_ADDRESS - MTX_CODE_BASE;
342
fw_data = priv_fw->fw_text;
343
fw_size = priv_fw->fw_text_size;
345
for (i = 0; i < fw_size; i++) {
346
/* Wait for MCMSTAT to become be idle 1 */
347
if (reg_ready_psb(context, PSB_MSVDX_MTX_RAM_ACCESS_STATUS,
348
0xffffffff, 0x00000001) == 0) {
349
ram_id = MTX_CORE_CODE_MEM + (address / bank_size);
350
if (ram_id != current_bank) {
352
* bits 20:27 - ram bank (CODE_BASE | DATA_BASE)
353
* bits 2:19 - address
354
* bit 1 - enable auto increment addressing mode
356
ctrl = (ram_id << 20) | (((address >> 2) & 0x000ffffc) << 2) |
358
EMGD_WRITE32(ctrl, mmio + PSB_MSVDX_MTX_RAM_ACCESS_CONTROL);
360
current_bank = ram_id;
361
/* Wait for MCMSTAT to become be idle 1 */
362
reg_ready_psb(context, PSB_MSVDX_MTX_RAM_ACCESS_STATUS,
363
0xffffffff, 0x00000001);
367
EMGD_WRITE32(fw_data[i],
368
mmio + PSB_MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER);
370
printk(KERN_ERR "Timeout waiting for MCMSTAT to be idle\n");
374
/* verify firmware upload. */
376
address = PC_START_ADDRESS - MTX_CODE_BASE;
378
for (i = 0; i < fw_size; i++) {
379
if (reg_ready_psb(context, PSB_MSVDX_MTX_RAM_ACCESS_STATUS,
380
0xffffffff, 0x00000001) == 0) {
381
ram_id = MTX_CORE_CODE_MEM + (address / bank_size);
382
if (ram_id != current_bank) {
384
* bits 20:27 - ram bank (CODE_BASE | DATA_BASE)
385
* bits 2:19 - address
386
* bit 1 - enable auto increment addressing mode
388
ctrl = (ram_id << 20) | (((address >> 2) & 0x000ffffc) << 2) |
390
EMGD_WRITE32(ctrl, mmio + PSB_MSVDX_MTX_RAM_ACCESS_CONTROL);
391
current_bank = ram_id;
392
reg_ready_psb(context, PSB_MSVDX_MTX_RAM_ACCESS_STATUS,
393
0xffffffff, 0x00000001);
397
if (EMGD_READ32(mmio + PSB_MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER) !=
399
printk(KERN_ERR "Verify Error at index %ld\n", i);
402
printk(KERN_ERR "Timeout waiting for MCMSTAT to be idle while verifying\n");
406
fw_data = priv_fw->fw_data;
407
fw_size = priv_fw->fw_data_size;
409
/* Loop writing data to core memory */
411
address = priv_fw->fw_data_location - MTX_DATA_BASE;
413
for (i = 0; i < fw_size; i++) {
414
if (reg_ready_psb(context, PSB_MSVDX_MTX_RAM_ACCESS_STATUS,
415
0xffffffff, 0x00000001) == 0) {
416
ram_id = MTX_CORE_DATA_MEM + (address / bank_size);
417
if (ram_id != current_bank) {
419
* bits 20:27 - ram bank (CODE_BASE | DATA_BASE)
420
* bits 2:19 - address
421
* bit 1 - enable auto increment addressing mode
423
ctrl = (ram_id << 20) | (((address >> 2) & 0x000ffffc) << 2) |
425
EMGD_WRITE32(ctrl, mmio + PSB_MSVDX_MTX_RAM_ACCESS_CONTROL);
426
current_bank = ram_id;
427
reg_ready_psb(context, PSB_MSVDX_MTX_RAM_ACCESS_STATUS,
428
0xffffffff, 0x00000001);
432
EMGD_WRITE32(fw_data[i],
433
mmio + PSB_MSVDX_MTX_RAM_ACCESS_DATA_TRANSFER);
435
printk(KERN_ERR "Timeout waiting for MCMSTAT to be idle - data segment\n");
439
/* Restore the RAM access control register */
440
EMGD_WRITE32(acc_control, mmio + PSB_MSVDX_MTX_RAM_ACCESS_CONTROL);
442
/* Start the firmware thread running */
443
EMGD_WRITE32(PC_START_ADDRESS, mmio + PSB_MSVDX_MTX_REGISTER_READ_WRITE_DATA);
444
EMGD_WRITE32(MTX_PC, mmio + PSB_MSVDX_MTX_REGISTER_READ_WRITE_REQUEST);
445
reg_ready_psb(context, PSB_MSVDX_MTX_REGISTER_READ_WRITE_REQUEST,
446
0x80000000, 0x80000000);
449
printk(KERN_INFO "Enabling MTX 0x%x\n", EMGD_READ32(mmio + PSB_MSVDX_MTX_ENABLE));
450
EMGD_WRITE32(MSVDX_MTX_ENABLE_MTX_ENABLE_MASK, mmio + PSB_MSVDX_MTX_ENABLE);
451
printk(KERN_INFO "Enabled MTX 0x%x\n", EMGD_READ32(mmio + PSB_MSVDX_MTX_ENABLE));
454
* Wait for signature value to be written.
456
* This is how the firmware thread notifies us that it is running.
458
if (reg_ready_psb(context, PSB_MSVDX_COMMS_SIGNATURE, 0xffffffff,
460
/* Error initializing firmware.... */
461
EMGD_DEBUG("Error, no MSVDX COMMS Signature");
462
return 0; /* FIXME: return an error code */
464
printk(KERN_INFO "MSVDX COMMS Signature OK\n");
466
/* Locate message buffers */
467
platform->mtx_buf_size = EMGD_READ32(mmio+PSB_MSVDX_COMMS_TO_MTX_BUF_SIZE) & 0xFFFF;
468
platform->host_buf_size = EMGD_READ32(mmio+PSB_MSVDX_COMMS_TO_HOST_BUF_SIZE) & 0xFFFF;
469
platform->mtx_buf_offset = MSVDX_BASE + (EMGD_READ32(mmio+PSB_MSVDX_COMMS_TO_MTX_BUF_SIZE) >> 16) + 0x2000;
470
platform->host_buf_offset = MSVDX_BASE + (EMGD_READ32(mmio+PSB_MSVDX_COMMS_TO_HOST_BUF_SIZE) >> 16) + 0x2000;
472
platform->sequence = 1;
473
platform->mtx_submitted = 0;
475
/* Send initialization message to firmware, newer versions don't */
477
unsigned long init_msg[2];
479
init_msg[0] = 8 | (0x80 << 8);
481
/* physical address of the PD shared by SGX/MSVDX */
482
init_msg[1] = EMGD_READ32(mmio + 0x40c84);
484
send_to_mtx(context, init_msg);
486
/* Check response from MTX firmware */
487
poll_mtx_irq(context);
490
/* Clear the firmware buffer, this is mostly to make debugging easier */
494
for (i = 0; i < platform->mtx_buf_size; i++) {
495
EMGD_WRITE32(0, mmio + platform->mtx_buf_offset + (i <<2));
497
for (i = 0; i < platform->host_buf_size; i++) {
498
EMGD_WRITE32(0, mmio + platform->host_buf_offset + (i <<2));
503
/* Enable minimal clocks */
504
EMGD_WRITE32(PSB_CLK_ENABLE_MIN, mmio + PSB_MSVDX_MAN_CLK_ENABLE);
506
/* Enable MTX interrupts to host */
507
EMGD_WRITE32(1<<14, mmio + PSB_MSVDX_HOST_INTERRUPT_ENABLE);
512
return 0; /* Successfully initialized the MTX firmware */
516
int msvdx_uninit_plb(igd_context_t *context)
521
msvdx_reset_plb(context);
528
int msvdx_close_context(igd_context_t *context)
543
int msvdx_create_context(igd_context_t *context)
553
int process_video_decode_plb(igd_context_t *context, unsigned long offset, void *virt_addr, unsigned long *fence_id)
555
unsigned long *mtx_buf;
556
unsigned long *mtx_msgs;
557
unsigned long mtx_offset;
558
unsigned long mtx_msg_cnt;
559
unsigned long irq_flags;
561
platform_context_plb_t *platform;
566
platform = (platform_context_plb_t *)context->platform_context;
568
mtx_buf = (unsigned long *) virt_addr;
569
mtx_offset = mtx_buf[0];
570
mtx_msg_cnt = mtx_buf[1];
572
// printk(KERN_INFO "process_video_decode_plb where buf=%lx, offset=%lx, cnt=%lx\n",
573
// mtx_buf, offset, mtx_msg_cnt);
574
if (mtx_msg_cnt > 0x20) {
575
printk(KERN_ERR "Message count too big at %ld\n", mtx_msg_cnt);
579
mtx_msgs = mtx_buf + (mtx_offset / sizeof (unsigned long));
580
if (mtx_msg_cnt > 0) {
581
//if ((mtx_buf[0] != 0x8) || (mtx_buf[2] != 0x8504)) {
583
spin_lock_irqsave(&platform->msvdx_lock, irq_flags);
585
if (!platform->msvdx_busy) {
587
platform->msvdx_busy = 1;
588
spin_unlock_irqrestore(&platform->msvdx_lock, irq_flags);
591
if (platform->msvdx_needs_reset) {
592
msvdx_reset_plb(context);
593
msvdx_init_plb(0, 0, NULL, 0);
594
jiffies_at_last_dequeue = 0;
596
// Send message buffer to MSVDX Firmware
598
populate_fence_id(context, mtx_msgs, mtx_msg_cnt);
599
ret = process_mtx_messages(context, mtx_msgs, mtx_msg_cnt, platform->msvdx_fence);
606
struct msvdx_cmd_queue *msvdx_cmd;
608
spin_unlock_irqrestore(&platform->msvdx_lock, irq_flags);
610
msvdx_cmd = kzalloc(sizeof(struct msvdx_cmd_queue), GFP_KERNEL);
611
if (msvdx_cmd == NULL) {
612
printk(KERN_ERR "MSVDXQUE: Out of memory\n");
616
populate_fence_id(context, mtx_msgs, mtx_msg_cnt);
617
msvdx_cmd->cmd = mtx_msgs;
618
msvdx_cmd->cmd_size = mtx_msg_cnt;
619
/* If more than 1000 msec (1 second or 1000 jiffies) passes since
620
* the last time a video cmd has been decoded, MSVDX may be hung
621
* and needing to be reset.
623
if ((jiffies_at_last_dequeue != 0) &&
624
((jiffies - jiffies_at_last_dequeue) > 1000)) {
625
printk(KERN_ERR "Video decode hardware appears to be hung; "
627
platform->msvdx_needs_reset = 1;
629
if (platform->msvdx_needs_reset) {
630
msvdx_reset_plb(context);
631
msvdx_init_plb(0, 0, NULL, 0);
632
platform->msvdx_busy = 0;
633
jiffies_at_last_dequeue = 0;
636
spin_lock_irqsave(&platform->msvdx_lock, irq_flags);
637
list_add_tail(&msvdx_cmd->head, &platform->msvdx_queue);
638
if (!platform->msvdx_busy) {
639
platform->msvdx_busy = 1;
640
msvdx_dequeue_send(context);
643
spin_unlock_irqrestore(&platform->msvdx_lock, irq_flags);
646
*fence_id = platform->msvdx_fence;
648
/* return the fence id even there is no messages to process.
649
* Used this for context id.
651
*fence_id = platform->msvdx_fence;
657
int msvdx_get_fence_id(igd_context_t *context, unsigned long *fence_id)
660
platform_context_plb_t *platform;
662
platform = (platform_context_plb_t *)context->platform_context;
664
*fence_id = platform->mtx_completed;
669
int msvdx_flush_tlb(igd_context_t *context)
671
unsigned char *mmio = context->device_context.virt_mmadr;
672
unsigned long msvdx_mmu;
673
msvdx_mmu = EMGD_READ32(mmio + PSB_MSVDX_MMU_CONTROL0);
674
msvdx_mmu &= 0xFFFFFFF0;
675
msvdx_mmu |= 0x0C; /* MMU_INVALDC + MMU_FLUSH */
676
EMGD_WRITE32(msvdx_mmu, mmio + PSB_MSVDX_MMU_CONTROL0);
678
msvdx_mmu = EMGD_READ32(mmio + PSB_MSVDX_MMU_CONTROL0);
679
msvdx_mmu &= 0xFFFFFF00;
680
EMGD_WRITE32(msvdx_mmu, mmio + PSB_MSVDX_MMU_CONTROL0);
681
EMGD_READ32(mmio + PSB_MSVDX_MMU_CONTROL0);
689
* Resets the MSVDX engine via the soft reset control.
691
* This function is exported.
693
void msvdx_reset_plb(igd_context_t *context)
695
unsigned char *mmio = context->device_context.virt_mmadr;
696
platform_context_plb_t *platform;
700
platform = (platform_context_plb_t *)context->platform_context;
702
/* Reset MSVDX engine */
703
EMGD_WRITE32(0x11111100, mmio + PSB_MSVDX_CONTROL);
704
reg_ready_psb(context, PSB_MSVDX_CONTROL, 0x00000100, 0);
706
/* Clear interrupt and clear pending interrupts */
707
EMGD_WRITE32(0, mmio + PSB_MSVDX_HOST_INTERRUPT_ENABLE);
708
EMGD_WRITE32(0xffffffff, mmio + PSB_MSVDX_INTERRUPT_CLEAR);
710
/* Mark the engine as being reset */
711
platform->msvdx_needs_reset = 0;
716
* When shuting down, need to reset the MSVDX engine too.
718
int msvdx_shutdown_plb(igd_context_t *context)
720
platform_context_plb_t *platform;
723
platform = (platform_context_plb_t *)context->platform_context;
725
/* Reset MSVDX engine */
726
msvdx_reset_plb(context);
728
/* Free RENDEC memory allocations */
729
platform->rendec_base0 = 0;
730
platform->rendec_base1 = 0;
731
init_msvdx_first_time = 1;
737
static int reg_ready_psb(igd_context_t *context,
742
unsigned char *mmio = context->device_context.virt_mmadr;
743
unsigned long status;
747
status = EMGD_READ32(mmio + reg);
748
if ((status & mask) == value) {
755
/* Timeout waiting for RAM ACCESS ready */
756
EMGD_DEBUG("TIMEOUT: Got 0x%08lx while waiting for 0x%08lx", status, value);
761
static int poll_mtx_irq(igd_context_t *context)
763
unsigned char *mmio = context->device_context.virt_mmadr;
765
unsigned long mtx_int;
770
ret = reg_ready_psb(context, PSB_MSVDX_INTERRUPT_STATUS, mtx_int, mtx_int);
772
/* Timeout waiting on interrupt status */
776
/* Clear the interrupt */
777
EMGD_WRITE32(mtx_int, mmio + PSB_MSVDX_INTERRUPT_CLEAR);