mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/benh/powerpc: (38 commits) ps3flash: Always read chunks of 256 KiB, and cache them ps3flash: Cache the last accessed FLASH chunk ps3: Replace direct file operations by callback ps3: Switch ps3_os_area_[gs]et_rtc_diff to EXPORT_SYMBOL_GPL() ps3: Correct debug message in dma_ioc0_map_pages() drivers/ps3: Add missing annotations ps3fb: Use ps3_system_bus_[gs]et_drvdata() instead of direct access ps3flash: Use ps3_system_bus_[gs]et_drvdata() instead of direct access ps3: shorten ps3_system_bus_[gs]et_driver_data to ps3_system_bus_[gs]et_drvdata ps3: Use dev_[gs]et_drvdata() instead of direct access for system bus devices block/ps3: remove driver_data direct access of struct device ps3vram: Make ps3vram_priv.reports a void * ps3vram: Remove no longer used ps3vram_priv.ddr_base ps3vram: Replace mutex by spinlock + bio_list block: Add bio_list_peek() powerpc: Use generic atomic64_t implementation on 32-bit processors lib: Provide generic atomic64_t implementation powerpc: Add compiler memory barrier to mtmsr macro powerpc/iseries: Mark signal_vsp_instruction() as maybe unused powerpc/iseries: Fix unused function warning in iSeries DT code ...
This commit is contained in:
commit
609106b9ac
37 changed files with 873 additions and 527 deletions
|
|
@ -32,25 +32,16 @@
|
|||
#include <linux/init.h>
|
||||
|
||||
#include <asm/abs_addr.h>
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/lv1call.h>
|
||||
#include <asm/ps3av.h>
|
||||
#include <asm/ps3fb.h>
|
||||
#include <asm/ps3.h>
|
||||
#include <asm/ps3gpu.h>
|
||||
|
||||
|
||||
#define DEVICE_NAME "ps3fb"
|
||||
|
||||
#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 GPU_CMD_BUF_SIZE (2 * 1024 * 1024)
|
||||
#define GPU_FB_START (64 * 1024)
|
||||
#define GPU_IOIF (0x0d000000UL)
|
||||
|
|
@ -462,33 +453,27 @@ static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
|
|||
src_offset += GPU_FB_START;
|
||||
|
||||
mutex_lock(&ps3_gpu_mutex);
|
||||
status = lv1_gpu_context_attribute(ps3fb.context_handle,
|
||||
L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
|
||||
dst_offset, GPU_IOIF + src_offset,
|
||||
L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
|
||||
(width << 16) | height,
|
||||
line_length);
|
||||
status = lv1_gpu_fb_blit(ps3fb.context_handle, dst_offset,
|
||||
GPU_IOIF + src_offset,
|
||||
L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
|
||||
(width << 16) | height,
|
||||
line_length);
|
||||
mutex_unlock(&ps3_gpu_mutex);
|
||||
|
||||
if (status)
|
||||
dev_err(dev,
|
||||
"%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
|
||||
__func__, status);
|
||||
dev_err(dev, "%s: lv1_gpu_fb_blit failed: %d\n", __func__,
|
||||
status);
|
||||
#ifdef HEAD_A
|
||||
status = lv1_gpu_context_attribute(ps3fb.context_handle,
|
||||
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
|
||||
0, frame_offset, 0, 0);
|
||||
status = lv1_gpu_display_flip(ps3fb.context_handle, 0, frame_offset);
|
||||
if (status)
|
||||
dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
|
||||
__func__, status);
|
||||
dev_err(dev, "%s: lv1_gpu_display_flip failed: %d\n", __func__,
|
||||
status);
|
||||
#endif
|
||||
#ifdef HEAD_B
|
||||
status = lv1_gpu_context_attribute(ps3fb.context_handle,
|
||||
L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
|
||||
1, frame_offset, 0, 0);
|
||||
status = lv1_gpu_display_flip(ps3fb.context_handle, 1, frame_offset);
|
||||
if (status)
|
||||
dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
|
||||
__func__, status);
|
||||
dev_err(dev, "%s: lv1_gpu_display_flip failed: %d\n", __func__,
|
||||
status);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -956,73 +941,6 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
|
|||
}
|
||||
|
||||
|
||||
static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
|
||||
struct device *dev)
|
||||
{
|
||||
int error;
|
||||
|
||||
dev_dbg(dev, "version_driver:%x\n", dinfo->version_driver);
|
||||
dev_dbg(dev, "irq outlet:%x\n", dinfo->irq.irq_outlet);
|
||||
dev_dbg(dev,
|
||||
"version_gpu: %x memory_size: %x ch: %x core_freq: %d "
|
||||
"mem_freq:%d\n",
|
||||
dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel,
|
||||
dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000);
|
||||
|
||||
if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
|
||||
dev_err(dev, "%s: version_driver err:%x\n", __func__,
|
||||
dinfo->version_driver);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
|
||||
&ps3fb.irq_no);
|
||||
if (error) {
|
||||
dev_err(dev, "%s: ps3_alloc_irq failed %d\n", __func__, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
|
||||
DEVICE_NAME, dev);
|
||||
if (error) {
|
||||
dev_err(dev, "%s: request_irq failed %d\n", __func__, error);
|
||||
ps3_irq_plug_destroy(ps3fb.irq_no);
|
||||
return error;
|
||||
}
|
||||
|
||||
dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) |
|
||||
(1 << GPU_INTR_STATUS_FLIP_1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
|
||||
xdr_lpar, ps3fb_videomemory.size, 0);
|
||||
if (status) {
|
||||
dev_err(dev, "%s: lv1_gpu_context_iomap failed: %d\n",
|
||||
__func__, status);
|
||||
return -ENXIO;
|
||||
}
|
||||
dev_dbg(dev, "video:%p ioif:%lx lpar:%llx size:%lx\n",
|
||||
ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
|
||||
ps3fb_videomemory.size);
|
||||
|
||||
status = lv1_gpu_context_attribute(ps3fb.context_handle,
|
||||
L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
|
||||
xdr_lpar, GPU_CMD_BUF_SIZE,
|
||||
GPU_IOIF, 0);
|
||||
if (status) {
|
||||
dev_err(dev,
|
||||
"%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
|
||||
__func__, status);
|
||||
return -ENXIO;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fb_ops ps3fb_ops = {
|
||||
.fb_open = ps3fb_open,
|
||||
.fb_release = ps3fb_release,
|
||||
|
|
@ -1048,49 +966,18 @@ static struct fb_fix_screeninfo ps3fb_fix __initdata = {
|
|||
.accel = FB_ACCEL_NONE,
|
||||
};
|
||||
|
||||
static int ps3fb_set_sync(struct device *dev)
|
||||
{
|
||||
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) {
|
||||
dev_err(dev,
|
||||
"%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) {
|
||||
dev_err(dev,
|
||||
"%s: lv1_gpu_context_attribute DISPLAY_SYNC 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 ps3fb_par *par;
|
||||
int retval = -ENOMEM;
|
||||
int retval;
|
||||
u64 ddr_lpar = 0;
|
||||
u64 lpar_dma_control = 0;
|
||||
u64 lpar_driver_info = 0;
|
||||
u64 lpar_reports = 0;
|
||||
u64 lpar_reports_size = 0;
|
||||
u64 xdr_lpar;
|
||||
struct gpu_driver_info *dinfo;
|
||||
void *fb_start;
|
||||
int status;
|
||||
struct task_struct *task;
|
||||
|
|
@ -1101,8 +988,8 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
status = ps3_open_hv_device(dev);
|
||||
if (status) {
|
||||
retval = ps3_open_hv_device(dev);
|
||||
if (retval) {
|
||||
dev_err(&dev->core, "%s: ps3_open_hv_device failed\n",
|
||||
__func__);
|
||||
goto err;
|
||||
|
|
@ -1116,7 +1003,24 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
|
|||
atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
|
||||
init_waitqueue_head(&ps3fb.wait_vsync);
|
||||
|
||||
ps3fb_set_sync(&dev->core);
|
||||
#ifdef HEAD_A
|
||||
status = lv1_gpu_display_sync(0x0, 0, L1GPU_DISPLAY_SYNC_VSYNC);
|
||||
if (status) {
|
||||
dev_err(&dev->core, "%s: lv1_gpu_display_sync failed: %d\n",
|
||||
__func__, status);
|
||||
retval = -ENODEV;
|
||||
goto err_close_device;
|
||||
}
|
||||
#endif
|
||||
#ifdef HEAD_B
|
||||
status = lv1_gpu_display_sync(0x0, 1, L1GPU_DISPLAY_SYNC_VSYNC);
|
||||
if (status) {
|
||||
dev_err(&dev->core, "%s: lv1_gpu_display_sync failed: %d\n",
|
||||
__func__, status);
|
||||
retval = -ENODEV;
|
||||
goto err_close_device;
|
||||
}
|
||||
#endif
|
||||
|
||||
max_ps3fb_size = _ALIGN_UP(GPU_IOIF, 256*1024*1024) - GPU_IOIF;
|
||||
if (ps3fb_videomemory.size > max_ps3fb_size) {
|
||||
|
|
@ -1131,7 +1035,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
|
|||
if (status) {
|
||||
dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
|
||||
__func__, status);
|
||||
goto err;
|
||||
goto err_close_device;
|
||||
}
|
||||
dev_dbg(&dev->core, "ddr:lpar:0x%llx\n", ddr_lpar);
|
||||
|
||||
|
|
@ -1141,33 +1045,85 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
|
|||
&lpar_reports, &lpar_reports_size);
|
||||
if (status) {
|
||||
dev_err(&dev->core,
|
||||
"%s: lv1_gpu_context_attribute failed: %d\n", __func__,
|
||||
"%s: lv1_gpu_context_allocate failed: %d\n", __func__,
|
||||
status);
|
||||
goto err_gpu_memory_free;
|
||||
}
|
||||
|
||||
/* vsync interrupt */
|
||||
ps3fb.dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024);
|
||||
if (!ps3fb.dinfo) {
|
||||
dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024);
|
||||
if (!dinfo) {
|
||||
dev_err(&dev->core, "%s: ioremap failed\n", __func__);
|
||||
goto err_gpu_context_free;
|
||||
}
|
||||
|
||||
retval = ps3fb_vsync_settings(ps3fb.dinfo, &dev->core);
|
||||
if (retval)
|
||||
ps3fb.dinfo = dinfo;
|
||||
dev_dbg(&dev->core, "version_driver:%x\n", dinfo->version_driver);
|
||||
dev_dbg(&dev->core, "irq outlet:%x\n", dinfo->irq.irq_outlet);
|
||||
dev_dbg(&dev->core, "version_gpu: %x memory_size: %x ch: %x "
|
||||
"core_freq: %d mem_freq:%d\n", dinfo->version_gpu,
|
||||
dinfo->memory_size, dinfo->hardware_channel,
|
||||
dinfo->nvcore_frequency/1000000,
|
||||
dinfo->memory_frequency/1000000);
|
||||
|
||||
if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
|
||||
dev_err(&dev->core, "%s: version_driver err:%x\n", __func__,
|
||||
dinfo->version_driver);
|
||||
retval = -EINVAL;
|
||||
goto err_iounmap_dinfo;
|
||||
}
|
||||
|
||||
retval = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
|
||||
&ps3fb.irq_no);
|
||||
if (retval) {
|
||||
dev_err(&dev->core, "%s: ps3_alloc_irq failed %d\n", __func__,
|
||||
retval);
|
||||
goto err_iounmap_dinfo;
|
||||
}
|
||||
|
||||
retval = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt,
|
||||
IRQF_DISABLED, DEVICE_NAME, &dev->core);
|
||||
if (retval) {
|
||||
dev_err(&dev->core, "%s: request_irq failed %d\n", __func__,
|
||||
retval);
|
||||
goto err_destroy_plug;
|
||||
}
|
||||
|
||||
dinfo->irq.mask = (1 << GPU_INTR_STATUS_VSYNC_1) |
|
||||
(1 << GPU_INTR_STATUS_FLIP_1);
|
||||
|
||||
/* Clear memory to prevent kernel info leakage into userspace */
|
||||
memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size);
|
||||
|
||||
xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address));
|
||||
retval = ps3fb_xdr_settings(xdr_lpar, &dev->core);
|
||||
if (retval)
|
||||
|
||||
status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
|
||||
xdr_lpar, ps3fb_videomemory.size,
|
||||
CBE_IOPTE_PP_W | CBE_IOPTE_PP_R |
|
||||
CBE_IOPTE_M);
|
||||
if (status) {
|
||||
dev_err(&dev->core, "%s: lv1_gpu_context_iomap failed: %d\n",
|
||||
__func__, status);
|
||||
retval = -ENXIO;
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
dev_dbg(&dev->core, "video:%p ioif:%lx lpar:%llx size:%lx\n",
|
||||
ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
|
||||
ps3fb_videomemory.size);
|
||||
|
||||
status = lv1_gpu_fb_setup(ps3fb.context_handle, xdr_lpar,
|
||||
GPU_CMD_BUF_SIZE, GPU_IOIF);
|
||||
if (status) {
|
||||
dev_err(&dev->core, "%s: lv1_gpu_fb_setup failed: %d\n",
|
||||
__func__, status);
|
||||
retval = -ENXIO;
|
||||
goto err_context_unmap;
|
||||
}
|
||||
|
||||
info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core);
|
||||
if (!info)
|
||||
goto err_free_irq;
|
||||
goto err_context_fb_close;
|
||||
|
||||
par = info->par;
|
||||
par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */
|
||||
|
|
@ -1210,7 +1166,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
|
|||
if (retval < 0)
|
||||
goto err_fb_dealloc;
|
||||
|
||||
dev->core.driver_data = info;
|
||||
ps3_system_bus_set_drvdata(dev, info);
|
||||
|
||||
dev_info(info->device, "%s %s, using %u KiB of video memory\n",
|
||||
dev_driver_string(info->dev), dev_name(info->dev),
|
||||
|
|
@ -1232,8 +1188,14 @@ err_fb_dealloc:
|
|||
fb_dealloc_cmap(&info->cmap);
|
||||
err_framebuffer_release:
|
||||
framebuffer_release(info);
|
||||
err_context_fb_close:
|
||||
lv1_gpu_fb_close(ps3fb.context_handle);
|
||||
err_context_unmap:
|
||||
lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, xdr_lpar,
|
||||
ps3fb_videomemory.size, CBE_IOPTE_M);
|
||||
err_free_irq:
|
||||
free_irq(ps3fb.irq_no, &dev->core);
|
||||
err_destroy_plug:
|
||||
ps3_irq_plug_destroy(ps3fb.irq_no);
|
||||
err_iounmap_dinfo:
|
||||
iounmap((u8 __force __iomem *)ps3fb.dinfo);
|
||||
|
|
@ -1241,14 +1203,16 @@ err_gpu_context_free:
|
|||
lv1_gpu_context_free(ps3fb.context_handle);
|
||||
err_gpu_memory_free:
|
||||
lv1_gpu_memory_free(ps3fb.memory_handle);
|
||||
err_close_device:
|
||||
ps3_close_hv_device(dev);
|
||||
err:
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
|
||||
{
|
||||
int status;
|
||||
struct fb_info *info = dev->core.driver_data;
|
||||
struct fb_info *info = ps3_system_bus_get_drvdata(dev);
|
||||
u64 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address));
|
||||
|
||||
dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
|
||||
|
||||
|
|
@ -1268,20 +1232,14 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
|
|||
unregister_framebuffer(info);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
framebuffer_release(info);
|
||||
info = dev->core.driver_data = NULL;
|
||||
ps3_system_bus_set_drvdata(dev, NULL);
|
||||
}
|
||||
iounmap((u8 __force __iomem *)ps3fb.dinfo);
|
||||
|
||||
status = lv1_gpu_context_free(ps3fb.context_handle);
|
||||
if (status)
|
||||
dev_dbg(&dev->core, "lv1_gpu_context_free failed: %d\n",
|
||||
status);
|
||||
|
||||
status = lv1_gpu_memory_free(ps3fb.memory_handle);
|
||||
if (status)
|
||||
dev_dbg(&dev->core, "lv1_gpu_memory_free failed: %d\n",
|
||||
status);
|
||||
|
||||
lv1_gpu_fb_close(ps3fb.context_handle);
|
||||
lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, xdr_lpar,
|
||||
ps3fb_videomemory.size, CBE_IOPTE_M);
|
||||
lv1_gpu_context_free(ps3fb.context_handle);
|
||||
lv1_gpu_memory_free(ps3fb.memory_handle);
|
||||
ps3_close_hv_device(dev);
|
||||
dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue