19682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* 29682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * SDL - Simple DirectMedia Layer 39682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * CELL BE Support for PS3 Framebuffer 49682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Copyright (C) 2008, 2009 International Business Machines Corporation 59682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 69682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This library is free software; you can redistribute it and/or modify it 79682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * under the terms of the GNU Lesser General Public License as published 89682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * by the Free Software Foundation; either version 2.1 of the License, or 99682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * (at your option) any later version. 109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * This library is distributed in the hope that it will be useful, but 129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * WITHOUT ANY WARRANTY; without even the implied warranty of 139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Lesser General Public License for more details. 159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * You should have received a copy of the GNU Lesser General Public 179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * License along with this library; if not, write to the Free Software 189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * USA 209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * 219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Martin Lowinski <lowinski [at] de [dot] ibm [ibm] com> 229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Dirk Herrendoerfer <d.herrendoerfer [at] de [dot] ibm [dot] com> 239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * SPE code based on research by: 249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Rene Becker 259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall * Thimo Emmerich 269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall */ 279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include "spu_common.h" 299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <spu_intrinsics.h> 319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <spu_mfcio.h> 329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <stdio.h> 339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#include <string.h> 349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall// Debugging 369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall//#define DEBUG 379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#ifdef DEBUG 399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define deprintf(fmt, args... ) \ 409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fprintf( stdout, fmt, ##args ); \ 419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fflush( stdout ); 429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#else 439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#define deprintf( fmt, args... ) 449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall#endif 459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid cpy_to_fb(unsigned int); 479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* fb_writer_spu parms */ 499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallstatic volatile struct fb_writer_parms_t parms __attribute__ ((aligned(128))); 509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall/* Code running on SPU */ 529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallint main(unsigned long long spe_id __attribute__ ((unused)), unsigned long long argp __attribute__ ((unused))) 539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] fb_writer_spu is up... (on SPE #%llu)\n", spe_id); 559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uint32_t ea_mfc, mbox; 569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // send ready message 579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_write_out_mbox(SPU_READY); 589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall while (1) { 609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Check mailbox */ 619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mbox = spu_read_in_mbox(); 629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] Message is %u\n", mbox); 639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall switch (mbox) { 649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SPU_EXIT: 659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] fb_writer goes down...\n"); 669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall case SPU_START: 689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall break; 699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall default: 709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] Cannot handle message\n"); 719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall continue; 729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Tag Manager setup */ 759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int tags; 769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tags = mfc_multi_tag_reserve(5); 779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall if (tags == MFC_TAG_INVALID) { 789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] Failed to reserve mfc tags on fb_writer\n"); 799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Framebuffer parms */ 839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall ea_mfc = spu_read_in_mbox(); 849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] Message on fb_writer is %u\n", ea_mfc); 859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_mfcdma32(&parms, (unsigned int)ea_mfc, 869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall sizeof(struct fb_writer_parms_t), tags, 879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall MFC_GET_CMD); 889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] argp = %u\n", (unsigned int)argp); 899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tags); 909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Copy parms->data to framebuffer */ 929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] Copying to framebuffer started\n"); 939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall cpy_to_fb(tags); 949682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] Copying to framebuffer done!\n"); 959682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 969682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall mfc_multi_tag_release(tags, 5); 979682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] fb_writer_spu... done!\n"); 989682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Send FIN msg */ 999682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_write_out_mbox(SPU_FIN); 1009682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1019682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1029682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall return 0; 1039682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1049682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1059682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hallvoid cpy_to_fb(unsigned int tag_id_base) 1069682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall{ 1079682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned int i; 1089682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall unsigned char current_buf; 1099682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uint8_t *in = parms.data; 1109682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1119682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Align fb pointer which was centered before */ 1129682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uint8_t *fb = 1139682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall (unsigned char *)((unsigned int)parms.center & 0xFFFFFFF0); 1149682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1159682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uint32_t bounded_input_height = parms.bounded_input_height; 1169682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uint32_t bounded_input_width = parms.bounded_input_width; 1179682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uint32_t fb_pixel_size = parms.fb_pixel_size; 1189682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1199682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uint32_t out_line_stride = parms.out_line_stride; 1209682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uint32_t in_line_stride = parms.in_line_stride; 1219682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall uint32_t in_line_size = bounded_input_width * fb_pixel_size; 1229682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1239682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall current_buf = 0; 1249682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1259682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* Local store buffer */ 1269682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall static volatile uint8_t buf[4][BUFFER_SIZE] 1279682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall __attribute__ ((aligned(128))); 1289682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* do 4-times multibuffering using DMA list, process in two steps */ 1299682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall for (i = 0; i < bounded_input_height >> 2; i++) { 1309682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* first buffer */ 1319682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 1); 1329682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // retrieve buffer 1339682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_mfcdma32(buf[0], (unsigned int)in, in_line_size, 1349682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tag_id_base + 1, MFC_GETB_CMD); 1359682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 1); 1369682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // store buffer 1379682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_mfcdma32(buf[0], (unsigned int)fb, in_line_size, 1389682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tag_id_base + 1, MFC_PUTB_CMD); 1399682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall in += in_line_stride; 1409682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fb += out_line_stride; 1419682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] 1st buffer copied in=0x%x, fb=0x%x\n", in, 1429682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fb); 1439682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1449682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* second buffer */ 1459682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 2); 1469682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // retrieve buffer 1479682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_mfcdma32(buf[1], (unsigned int)in, in_line_size, 1489682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tag_id_base + 2, MFC_GETB_CMD); 1499682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 2); 1509682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // store buffer 1519682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_mfcdma32(buf[1], (unsigned int)fb, in_line_size, 1529682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tag_id_base + 2, MFC_PUTB_CMD); 1539682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall in += in_line_stride; 1549682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fb += out_line_stride; 1559682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] 2nd buffer copied in=0x%x, fb=0x%x\n", in, 1569682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fb); 1579682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1589682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* third buffer */ 1599682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 3); 1609682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // retrieve buffer 1619682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_mfcdma32(buf[2], (unsigned int)in, in_line_size, 1629682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tag_id_base + 3, MFC_GETB_CMD); 1639682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 3); 1649682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // store buffer 1659682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_mfcdma32(buf[2], (unsigned int)fb, in_line_size, 1669682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tag_id_base + 3, MFC_PUTB_CMD); 1679682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall in += in_line_stride; 1689682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fb += out_line_stride; 1699682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] 3rd buffer copied in=0x%x, fb=0x%x\n", in, 1709682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fb); 1719682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1729682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall /* fourth buffer */ 1739682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 4); 1749682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // retrieve buffer 1759682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_mfcdma32(buf[3], (unsigned int)in, in_line_size, 1769682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tag_id_base + 4, MFC_GETB_CMD); 1779682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 4); 1789682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall // store buffer 1799682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall spu_mfcdma32(buf[3], (unsigned int)fb, in_line_size, 1809682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall tag_id_base + 4, MFC_PUTB_CMD); 1819682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall in += in_line_stride; 1829682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fb += out_line_stride; 1839682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] 4th buffer copied in=0x%x, fb=0x%x\n", in, 1849682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall fb); 1859682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall deprintf("[SPU] Loop #%i, bounded_input_height=%i\n", i, 1869682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall bounded_input_height >> 2); 1879682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall } 1889682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 2); 1899682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 3); 1909682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall DMA_WAIT_TAG(tag_id_base + 4); 1919682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall} 1929682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 1939682c8870b8ff5e4ac2e4c70b759f791c6f38c1fJesse Hall 194