[POWERPC] PS3: Frame buffer system-bus rework
Convert the ps3fb device from a platform device to a PS3 system bus device. Fix the remove and shutdown methods to support kexec and to make ps3fb a loadable module. Signed-off-by: Geert Uytterhoeven <Geert.Uytterhoeven@sonycom.com> Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
parent
13a5e30cf7
commit
9e6b99bd44
|
@ -107,7 +107,7 @@ static void ps3_panic(char *str)
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FB_PS3
|
#if defined(CONFIG_FB_PS3) || defined(CONFIG_FB_PS3_MODULE)
|
||||||
static void prealloc(struct ps3_prealloc *p)
|
static void prealloc(struct ps3_prealloc *p)
|
||||||
{
|
{
|
||||||
if (!p->size)
|
if (!p->size)
|
||||||
|
@ -125,10 +125,11 @@ static void prealloc(struct ps3_prealloc *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ps3_prealloc ps3fb_videomemory = {
|
struct ps3_prealloc ps3fb_videomemory = {
|
||||||
.name = "ps3fb videomemory",
|
.name = "ps3fb videomemory",
|
||||||
.size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
|
.size = CONFIG_FB_PS3_DEFAULT_SIZE_M*1024*1024,
|
||||||
.align = 1024*1024 /* the GPU requires 1 MiB alignment */
|
.align = 1024*1024 /* the GPU requires 1 MiB alignment */
|
||||||
};
|
};
|
||||||
|
EXPORT_SYMBOL_GPL(ps3fb_videomemory);
|
||||||
#define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory)
|
#define prealloc_ps3fb_videomemory() prealloc(&ps3fb_videomemory)
|
||||||
|
|
||||||
static int __init early_parse_ps3fb(char *p)
|
static int __init early_parse_ps3fb(char *p)
|
||||||
|
|
|
@ -1790,8 +1790,8 @@ config FB_IBM_GXT4500
|
||||||
adaptor, found on some IBM System P (pSeries) machines.
|
adaptor, found on some IBM System P (pSeries) machines.
|
||||||
|
|
||||||
config FB_PS3
|
config FB_PS3
|
||||||
bool "PS3 GPU framebuffer driver"
|
tristate "PS3 GPU framebuffer driver"
|
||||||
depends on (FB = y) && PS3_PS3AV
|
depends on FB && PS3_PS3AV
|
||||||
select FB_SYS_FILLRECT
|
select FB_SYS_FILLRECT
|
||||||
select FB_SYS_COPYAREA
|
select FB_SYS_COPYAREA
|
||||||
select FB_SYS_IMAGEBLIT
|
select FB_SYS_IMAGEBLIT
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/platform_device.h>
|
|
||||||
#include <linux/console.h>
|
#include <linux/console.h>
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
#include <linux/notifier.h>
|
#include <linux/notifier.h>
|
||||||
|
@ -46,6 +45,9 @@
|
||||||
#include <asm/ps3fb.h>
|
#include <asm/ps3fb.h>
|
||||||
#include <asm/ps3.h>
|
#include <asm/ps3.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define DEVICE_NAME "ps3fb"
|
||||||
|
|
||||||
#ifdef PS3FB_DEBUG
|
#ifdef PS3FB_DEBUG
|
||||||
#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args)
|
#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args)
|
||||||
#else
|
#else
|
||||||
|
@ -126,7 +128,6 @@ struct gpu_driver_info {
|
||||||
|
|
||||||
struct ps3fb_priv {
|
struct ps3fb_priv {
|
||||||
unsigned int irq_no;
|
unsigned int irq_no;
|
||||||
void *dev;
|
|
||||||
|
|
||||||
u64 context_handle, memory_handle;
|
u64 context_handle, memory_handle;
|
||||||
void *xdr_ea;
|
void *xdr_ea;
|
||||||
|
@ -171,7 +172,7 @@ static const struct ps3fb_res_table ps3fb_res[] = {
|
||||||
{ 0, 0, 0, 0 , 0} };
|
{ 0, 0, 0, 0 , 0} };
|
||||||
|
|
||||||
/* default resolution */
|
/* default resolution */
|
||||||
#define GPU_RES_INDEX 0 /* 720 x 480 */
|
#define GPU_RES_INDEX 0 /* 720 x 480 */
|
||||||
|
|
||||||
static const struct fb_videomode ps3fb_modedb[] = {
|
static const struct fb_videomode ps3fb_modedb[] = {
|
||||||
/* 60 Hz broadcast modes (modes "1" to "5") */
|
/* 60 Hz broadcast modes (modes "1" to "5") */
|
||||||
|
@ -298,10 +299,9 @@ static const struct fb_videomode ps3fb_modedb[] = {
|
||||||
#define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET)
|
#define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET)
|
||||||
|
|
||||||
static int ps3fb_mode;
|
static int ps3fb_mode;
|
||||||
module_param(ps3fb_mode, bool, 0);
|
module_param(ps3fb_mode, int, 0);
|
||||||
|
|
||||||
static char *mode_option __initdata;
|
|
||||||
|
|
||||||
|
static char *mode_option __devinitdata;
|
||||||
|
|
||||||
static int ps3fb_get_res_table(u32 xres, u32 yres)
|
static int ps3fb_get_res_table(u32 xres, u32 yres)
|
||||||
{
|
{
|
||||||
|
@ -681,15 +681,15 @@ int ps3fb_wait_for_vsync(u32 crtc)
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync);
|
EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync);
|
||||||
|
|
||||||
void ps3fb_flip_ctl(int on)
|
void ps3fb_flip_ctl(int on, void *data)
|
||||||
{
|
{
|
||||||
|
struct ps3fb_priv *priv = data;
|
||||||
if (on)
|
if (on)
|
||||||
atomic_dec_if_positive(&ps3fb.ext_flip);
|
atomic_dec_if_positive(&priv->ext_flip);
|
||||||
else
|
else
|
||||||
atomic_inc(&ps3fb.ext_flip);
|
atomic_inc(&priv->ext_flip);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ps3fb_flip_ctl);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ioctl
|
* ioctl
|
||||||
|
@ -851,37 +851,9 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MODULE
|
|
||||||
static int __init ps3fb_setup(char *options)
|
|
||||||
{
|
|
||||||
char *this_opt;
|
|
||||||
int mode = 0;
|
|
||||||
|
|
||||||
if (!options || !*options)
|
static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
|
||||||
return 0; /* no options */
|
struct ps3_system_bus_device *dev)
|
||||||
|
|
||||||
while ((this_opt = strsep(&options, ",")) != NULL) {
|
|
||||||
if (!*this_opt)
|
|
||||||
continue;
|
|
||||||
if (!strncmp(this_opt, "mode:", 5))
|
|
||||||
mode = simple_strtoul(this_opt + 5, NULL, 0);
|
|
||||||
else
|
|
||||||
mode_option = this_opt;
|
|
||||||
}
|
|
||||||
return mode;
|
|
||||||
}
|
|
||||||
#endif /* MODULE */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialisation
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void ps3fb_platform_release(struct device *device)
|
|
||||||
{
|
|
||||||
/* This is called when the reference count goes to zero. */
|
|
||||||
}
|
|
||||||
|
|
||||||
static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
|
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -897,7 +869,6 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ps3fb.dev = dev;
|
|
||||||
error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
|
error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
|
||||||
&ps3fb.irq_no);
|
&ps3fb.irq_no);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -907,7 +878,7 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, void *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
|
error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
|
||||||
"ps3fb vsync", ps3fb.dev);
|
DEVICE_NAME, dev);
|
||||||
if (error) {
|
if (error) {
|
||||||
printk(KERN_ERR "%s: request_irq failed %d\n", __func__,
|
printk(KERN_ERR "%s: request_irq failed %d\n", __func__,
|
||||||
error);
|
error);
|
||||||
|
@ -966,16 +937,45 @@ static struct fb_ops ps3fb_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct fb_fix_screeninfo ps3fb_fix __initdata = {
|
static struct fb_fix_screeninfo ps3fb_fix __initdata = {
|
||||||
.id = "PS3 FB",
|
.id = DEVICE_NAME,
|
||||||
.type = FB_TYPE_PACKED_PIXELS,
|
.type = FB_TYPE_PACKED_PIXELS,
|
||||||
.visual = FB_VISUAL_TRUECOLOR,
|
.visual = FB_VISUAL_TRUECOLOR,
|
||||||
.accel = FB_ACCEL_NONE,
|
.accel = FB_ACCEL_NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int __init ps3fb_probe(struct platform_device *dev)
|
static int ps3fb_set_sync(void)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
#ifdef HEAD_A
|
||||||
|
status = lv1_gpu_context_attribute(0x0,
|
||||||
|
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
|
||||||
|
0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
|
||||||
|
if (status) {
|
||||||
|
printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_SYNC "
|
||||||
|
"failed: %d\n", __func__, status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef HEAD_B
|
||||||
|
status = lv1_gpu_context_attribute(0x0,
|
||||||
|
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
|
||||||
|
1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_MODE "
|
||||||
|
"failed: %d\n", __func__, status);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
|
||||||
{
|
{
|
||||||
struct fb_info *info;
|
struct fb_info *info;
|
||||||
int retval = -ENOMEM;
|
int retval = -ENOMEM;
|
||||||
|
u32 xres, yres;
|
||||||
u64 ddr_lpar = 0;
|
u64 ddr_lpar = 0;
|
||||||
u64 lpar_dma_control = 0;
|
u64 lpar_dma_control = 0;
|
||||||
u64 lpar_driver_info = 0;
|
u64 lpar_driver_info = 0;
|
||||||
|
@ -986,6 +986,30 @@ static int __init ps3fb_probe(struct platform_device *dev)
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
struct task_struct *task;
|
struct task_struct *task;
|
||||||
|
|
||||||
|
status = ps3_open_hv_device(dev);
|
||||||
|
if (status) {
|
||||||
|
printk(KERN_ERR "%s: ps3_open_hv_device failed\n", __func__);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ps3fb_mode)
|
||||||
|
ps3fb_mode = ps3av_get_mode();
|
||||||
|
DPRINTK("ps3av_mode:%d\n", ps3fb_mode);
|
||||||
|
|
||||||
|
if (ps3fb_mode > 0 &&
|
||||||
|
!ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
|
||||||
|
ps3fb.res_index = ps3fb_get_res_table(xres, yres);
|
||||||
|
DPRINTK("res_index:%d\n", ps3fb.res_index);
|
||||||
|
} else
|
||||||
|
ps3fb.res_index = GPU_RES_INDEX;
|
||||||
|
|
||||||
|
atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
|
||||||
|
atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
|
||||||
|
init_waitqueue_head(&ps3fb.wait_vsync);
|
||||||
|
ps3fb.num_frames = 1;
|
||||||
|
|
||||||
|
ps3fb_set_sync();
|
||||||
|
|
||||||
/* get gpu context handle */
|
/* get gpu context handle */
|
||||||
status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
|
status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
|
||||||
&ps3fb.memory_handle, &ddr_lpar);
|
&ps3fb.memory_handle, &ddr_lpar);
|
||||||
|
@ -1029,7 +1053,7 @@ static int __init ps3fb_probe(struct platform_device *dev)
|
||||||
* leakage into userspace
|
* leakage into userspace
|
||||||
*/
|
*/
|
||||||
memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
|
memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
|
||||||
info = framebuffer_alloc(sizeof(u32) * 16, &dev->dev);
|
info = framebuffer_alloc(sizeof(u32) * 16, &dev->core);
|
||||||
if (!info)
|
if (!info)
|
||||||
goto err_free_irq;
|
goto err_free_irq;
|
||||||
|
|
||||||
|
@ -1061,19 +1085,20 @@ static int __init ps3fb_probe(struct platform_device *dev)
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto err_fb_dealloc;
|
goto err_fb_dealloc;
|
||||||
|
|
||||||
platform_set_drvdata(dev, info);
|
dev->core.driver_data = info;
|
||||||
|
|
||||||
printk(KERN_INFO
|
printk(KERN_INFO
|
||||||
"fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
|
"fb%d: PS3 frame buffer device, using %ld KiB of video memory\n",
|
||||||
info->node, ps3fb_videomemory.size >> 10);
|
info->node, ps3fb_videomemory.size >> 10);
|
||||||
|
|
||||||
task = kthread_run(ps3fbd, info, "ps3fbd");
|
task = kthread_run(ps3fbd, info, DEVICE_NAME);
|
||||||
if (IS_ERR(task)) {
|
if (IS_ERR(task)) {
|
||||||
retval = PTR_ERR(task);
|
retval = PTR_ERR(task);
|
||||||
goto err_unregister_framebuffer;
|
goto err_unregister_framebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ps3fb.task = task;
|
ps3fb.task = task;
|
||||||
|
ps3av_register_flip_ctl(ps3fb_flip_ctl, &ps3fb);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1084,7 +1109,7 @@ err_fb_dealloc:
|
||||||
err_framebuffer_release:
|
err_framebuffer_release:
|
||||||
framebuffer_release(info);
|
framebuffer_release(info);
|
||||||
err_free_irq:
|
err_free_irq:
|
||||||
free_irq(ps3fb.irq_no, ps3fb.dev);
|
free_irq(ps3fb.irq_no, dev);
|
||||||
ps3_irq_plug_destroy(ps3fb.irq_no);
|
ps3_irq_plug_destroy(ps3fb.irq_no);
|
||||||
err_iounmap_dinfo:
|
err_iounmap_dinfo:
|
||||||
iounmap((u8 __iomem *)ps3fb.dinfo);
|
iounmap((u8 __iomem *)ps3fb.dinfo);
|
||||||
|
@ -1096,26 +1121,30 @@ err:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ps3fb_shutdown(struct platform_device *dev)
|
static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
|
||||||
{
|
|
||||||
ps3fb_flip_ctl(0); /* flip off */
|
|
||||||
ps3fb.dinfo->irq.mask = 0;
|
|
||||||
free_irq(ps3fb.irq_no, ps3fb.dev);
|
|
||||||
ps3_irq_plug_destroy(ps3fb.irq_no);
|
|
||||||
iounmap((u8 __iomem *)ps3fb.dinfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ps3fb_cleanup(void)
|
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
struct fb_info *info = dev->core.driver_data;
|
||||||
|
|
||||||
|
DPRINTK(" -> %s:%d\n", __func__, __LINE__);
|
||||||
|
|
||||||
|
ps3fb_flip_ctl(0, &ps3fb); /* flip off */
|
||||||
|
ps3fb.dinfo->irq.mask = 0;
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
unregister_framebuffer(info);
|
||||||
|
fb_dealloc_cmap(&info->cmap);
|
||||||
|
framebuffer_release(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
ps3av_register_flip_ctl(NULL, NULL);
|
||||||
if (ps3fb.task) {
|
if (ps3fb.task) {
|
||||||
struct task_struct *task = ps3fb.task;
|
struct task_struct *task = ps3fb.task;
|
||||||
ps3fb.task = NULL;
|
ps3fb.task = NULL;
|
||||||
kthread_stop(task);
|
kthread_stop(task);
|
||||||
}
|
}
|
||||||
if (ps3fb.irq_no) {
|
if (ps3fb.irq_no) {
|
||||||
free_irq(ps3fb.irq_no, ps3fb.dev);
|
free_irq(ps3fb.irq_no, dev);
|
||||||
ps3_irq_plug_destroy(ps3fb.irq_no);
|
ps3_irq_plug_destroy(ps3fb.irq_no);
|
||||||
}
|
}
|
||||||
iounmap((u8 __iomem *)ps3fb.dinfo);
|
iounmap((u8 __iomem *)ps3fb.dinfo);
|
||||||
|
@ -1128,134 +1157,69 @@ void ps3fb_cleanup(void)
|
||||||
if (status)
|
if (status)
|
||||||
DPRINTK("lv1_gpu_memory_free failed: %d\n", status);
|
DPRINTK("lv1_gpu_memory_free failed: %d\n", status);
|
||||||
|
|
||||||
ps3av_dev_close();
|
ps3_close_hv_device(dev);
|
||||||
}
|
DPRINTK(" <- %s:%d\n", __func__, __LINE__);
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ps3fb_cleanup);
|
|
||||||
|
|
||||||
static int ps3fb_remove(struct platform_device *dev)
|
|
||||||
{
|
|
||||||
struct fb_info *info = platform_get_drvdata(dev);
|
|
||||||
|
|
||||||
if (info) {
|
|
||||||
unregister_framebuffer(info);
|
|
||||||
fb_dealloc_cmap(&info->cmap);
|
|
||||||
framebuffer_release(info);
|
|
||||||
}
|
|
||||||
ps3fb_cleanup();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver ps3fb_driver = {
|
static struct ps3_system_bus_driver ps3fb_driver = {
|
||||||
.probe = ps3fb_probe,
|
.match_id = PS3_MATCH_ID_GRAPHICS,
|
||||||
.remove = ps3fb_remove,
|
.core.name = DEVICE_NAME,
|
||||||
.shutdown = ps3fb_shutdown,
|
.core.owner = THIS_MODULE,
|
||||||
.driver = { .name = "ps3fb" }
|
.probe = ps3fb_probe,
|
||||||
|
.remove = ps3fb_shutdown,
|
||||||
|
.shutdown = ps3fb_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct platform_device ps3fb_device = {
|
static int __init ps3fb_setup(void)
|
||||||
.name = "ps3fb",
|
|
||||||
.id = 0,
|
|
||||||
.dev = { .release = ps3fb_platform_release }
|
|
||||||
};
|
|
||||||
|
|
||||||
int ps3fb_set_sync(void)
|
|
||||||
{
|
{
|
||||||
int status;
|
char *options;
|
||||||
|
|
||||||
#ifdef HEAD_A
|
#ifdef MODULE
|
||||||
status = lv1_gpu_context_attribute(0x0,
|
return 0;
|
||||||
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
|
|
||||||
0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
|
|
||||||
if (status) {
|
|
||||||
printk(KERN_ERR
|
|
||||||
"%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: %d\n",
|
|
||||||
__func__, status);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef HEAD_B
|
|
||||||
status = lv1_gpu_context_attribute(0x0,
|
|
||||||
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
|
|
||||||
1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
|
|
||||||
|
|
||||||
if (status) {
|
if (fb_get_options(DEVICE_NAME, &options))
|
||||||
printk(KERN_ERR
|
return -ENXIO;
|
||||||
"%s: lv1_gpu_context_attribute DISPLAY_MODE failed: %d\n",
|
|
||||||
__func__, status);
|
if (!options || !*options)
|
||||||
return -1;
|
return 0;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
char *this_opt = strsep(&options, ",");
|
||||||
|
|
||||||
|
if (!this_opt)
|
||||||
|
break;
|
||||||
|
if (!*this_opt)
|
||||||
|
continue;
|
||||||
|
if (!strncmp(this_opt, "mode:", 5))
|
||||||
|
ps3fb_mode = simple_strtoul(this_opt + 5, NULL, 0);
|
||||||
|
else
|
||||||
|
mode_option = this_opt;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(ps3fb_set_sync);
|
|
||||||
|
|
||||||
static int __init ps3fb_init(void)
|
static int __init ps3fb_init(void)
|
||||||
{
|
{
|
||||||
int error;
|
if (!ps3fb_videomemory.address || ps3fb_setup())
|
||||||
#ifndef MODULE
|
return -ENXIO;
|
||||||
int mode;
|
|
||||||
char *option = NULL;
|
|
||||||
|
|
||||||
if (fb_get_options("ps3fb", &option))
|
return ps3_system_bus_driver_register(&ps3fb_driver);
|
||||||
goto err;
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!ps3fb_videomemory.address)
|
static void __exit ps3fb_exit(void)
|
||||||
goto err;
|
{
|
||||||
|
DPRINTK(" -> %s:%d\n", __func__, __LINE__);
|
||||||
error = ps3av_dev_open();
|
ps3_system_bus_driver_unregister(&ps3fb_driver);
|
||||||
if (error) {
|
DPRINTK(" <- %s:%d\n", __func__, __LINE__);
|
||||||
printk(KERN_ERR "%s: ps3av_dev_open failed\n", __func__);
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ps3fb_mode = ps3av_get_mode();
|
|
||||||
DPRINTK("ps3av_mode:%d\n", ps3fb_mode);
|
|
||||||
#ifndef MODULE
|
|
||||||
mode = ps3fb_setup(option); /* check boot option */
|
|
||||||
if (mode)
|
|
||||||
ps3fb_mode = mode;
|
|
||||||
#endif
|
|
||||||
if (ps3fb_mode > 0) {
|
|
||||||
u32 xres, yres;
|
|
||||||
ps3av_video_mode2res(ps3fb_mode, &xres, &yres);
|
|
||||||
ps3fb.res_index = ps3fb_get_res_table(xres, yres);
|
|
||||||
DPRINTK("res_index:%d\n", ps3fb.res_index);
|
|
||||||
} else
|
|
||||||
ps3fb.res_index = GPU_RES_INDEX;
|
|
||||||
|
|
||||||
atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
|
|
||||||
atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
|
|
||||||
init_waitqueue_head(&ps3fb.wait_vsync);
|
|
||||||
ps3fb.num_frames = 1;
|
|
||||||
|
|
||||||
error = platform_driver_register(&ps3fb_driver);
|
|
||||||
if (!error) {
|
|
||||||
error = platform_device_register(&ps3fb_device);
|
|
||||||
if (error)
|
|
||||||
platform_driver_unregister(&ps3fb_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
ps3fb_set_sync();
|
|
||||||
|
|
||||||
return error;
|
|
||||||
|
|
||||||
err:
|
|
||||||
return -ENXIO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(ps3fb_init);
|
module_init(ps3fb_init);
|
||||||
|
|
||||||
#ifdef MODULE
|
|
||||||
static void __exit ps3fb_exit(void)
|
|
||||||
{
|
|
||||||
platform_device_unregister(&ps3fb_device);
|
|
||||||
platform_driver_unregister(&ps3fb_driver);
|
|
||||||
}
|
|
||||||
|
|
||||||
module_exit(ps3fb_exit);
|
module_exit(ps3fb_exit);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
#endif /* MODULE */
|
MODULE_DESCRIPTION("PS3 GPU Frame Buffer Driver");
|
||||||
|
MODULE_AUTHOR("Sony Computer Entertainment Inc.");
|
||||||
|
MODULE_ALIAS(PS3_MODULE_ALIAS_GRAPHICS);
|
||||||
|
|
|
@ -41,16 +41,4 @@ struct ps3fb_ioctl_res {
|
||||||
__u32 num_frames; /* num of frame buffers */
|
__u32 num_frames; /* num of frame buffers */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __KERNEL__
|
|
||||||
|
|
||||||
#ifdef CONFIG_FB_PS3
|
|
||||||
extern void ps3fb_flip_ctl(int on);
|
|
||||||
extern void ps3fb_cleanup(void);
|
|
||||||
#else
|
|
||||||
static inline void ps3fb_flip_ctl(int on) {}
|
|
||||||
static inline void ps3fb_cleanup(void) {}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_PS3FB_H_ */
|
#endif /* _ASM_POWERPC_PS3FB_H_ */
|
||||||
|
|
Loading…
Reference in New Issue