/*
* linux/drivers/video/ps3fb.c -- PS3 GPU frame buffer device
*
* Copyright (C) 2006 Sony Computer Entertainment Inc.
* Copyright 2006, 2007 Sony Corporation
*
* This file is based on :
*
* linux/drivers/video/vfb.c -- Virtual frame buffer device
*
* Copyright (C) 2002 James Simmons
*
* Copyright (C) 1997 Geert Uytterhoeven
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/tty.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/console.h>
#include <linux/ioctl.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <asm/uaccess.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <asm/time.h>
#include <asm/abs_addr.h>
#include <asm/lv1call.h>
#include <asm/ps3av.h>
#include <asm/ps3fb.h>
#include <asm/ps3.h>
#ifdef PS3FB_DEBUG
#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ##args)
#else
#define DPRINTK(fmt, args...)
#endif
#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101
#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102
#define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600
#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601
#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT_SYNC 0x602
#define L1GPU_FB_BLIT_WAIT_FOR_COMPLETION (1ULL << 32)
#define L1GPU_DISPLAY_SYNC_HSYNC 1
#define L1GPU_DISPLAY_SYNC_VSYNC 2
#define DDR_SIZE (0) /* used no ddr */
#define GPU_OFFSET (64 * 1024)
#define GPU_IOIF (0x0d000000UL)
#define PS3FB_FULL_MODE_BIT 0x80
#define GPU_INTR_STATUS_VSYNC_0 0 /* vsync on head A */
#define GPU_INTR_STATUS_VSYNC_1 1 /* vsync on head B */
#define GPU_INTR_STATUS_FLIP_0 3 /* flip head A */
#define GPU_INTR_STATUS_FLIP_1 4 /* flip head B */
#define GPU_INTR_STATUS_QUEUE_0 5 /* queue head A */
#define GPU_INTR_STATUS_QUEUE_1 6 /* queue head B */
#define GPU_DRIVER_INFO_VERSION 0x211
/* gpu internals */
struct display_head {
u64 be_time_stamp;
u32 status;
u32 offset;
u32 res1;
u32 res2;
u32 field;
u32 reserved1;
u64 res3;
u32 raster;
u64 vblank_count;
u32 field_vsync;
u32 reserved2;
};
struct gpu_irq {
u32 irq_outlet;
u32 status;
u32 mask;
u32 video_cause;
u32 graph_cause;
u32 user_cause;
u32 res1;
u64 res2;
u32 reserved[4];
};
struct gpu_driver_info {
u32 version_driver;
u32 version_gpu;
u32 memory_size;
u32 hardware_channel;
u32 nvcore_frequency;
u32 memory_frequency;
u32 reserved[1063];
struct display_head display_head[8];
struct gpu_irq irq;
};
struct ps3fb_priv {
unsigned int irq_no;
void *dev;
u64 context_handle, memory_handle;
void *xdr_ea;
struct gpu_driver_info *dinfo;
struct semaphore sem;
u32 res_index;
u64 vblank_count; /* frame count */
wait_queue_head_t wait_vsync;
u32 num_frames; /* num of frame buffers */
atomic_t ext_flip; /* on/off flip with vsync */
atomic_t f_count; /* fb_open count */
int is_blanked;
};
static struct ps3fb_priv ps3fb;
struct ps3fb_res_table {
u32 xres;
u32 yres;
u32 xoff;
u32 yoff;
u32 type;
};
#define PS3FB_RES_FULL 1
static const struct ps3fb_res_table ps3fb_res[] = {
/* res_x,y margin_x,y full */
{ 720, 480, 72, 48 , 0},
{ 720, 576, 72, 58