aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/ps3fb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/ps3fb.c')
-rw-r--r--drivers/video/ps3fb.c64
1 files changed, 27 insertions, 37 deletions
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index d552610603b2..8e19eb1e98b6 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -116,8 +116,6 @@ struct ps3fb_priv {
116 unsigned int irq_no; 116 unsigned int irq_no;
117 117
118 u64 context_handle, memory_handle; 118 u64 context_handle, memory_handle;
119 void *xdr_ea;
120 size_t xdr_size;
121 struct gpu_driver_info *dinfo; 119 struct gpu_driver_info *dinfo;
122 120
123 u64 vblank_count; /* frame count */ 121 u64 vblank_count; /* frame count */
@@ -598,7 +596,7 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
598 } 596 }
599 597
600 /* Memory limit */ 598 /* Memory limit */
601 if (var->yres_virtual * xdr_line_length > ps3fb.xdr_size) { 599 if (var->yres_virtual * xdr_line_length > info->fix.smem_len) {
602 dev_dbg(info->device, "Not enough memory\n"); 600 dev_dbg(info->device, "Not enough memory\n");
603 return -ENOMEM; 601 return -ENOMEM;
604 } 602 }
@@ -627,19 +625,15 @@ static int ps3fb_set_par(struct fb_info *info)
627 625
628 vmode = ps3fb_native_vmode(mode & PS3AV_MODE_MASK); 626 vmode = ps3fb_native_vmode(mode & PS3AV_MODE_MASK);
629 627
630 info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
631 info->fix.smem_len = ps3fb.xdr_size;
632 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; 628 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
633 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; 629 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
634 info->fix.line_length = xdr_line_length; 630 info->fix.line_length = xdr_line_length;
635 631
636 info->screen_base = (char __iomem *)ps3fb.xdr_ea;
637
638 par->ddr_line_length = ddr_line_length; 632 par->ddr_line_length = ddr_line_length;
639 par->ddr_frame_size = vmode->yres * ddr_line_length; 633 par->ddr_frame_size = vmode->yres * ddr_line_length;
640 par->xdr_frame_size = info->var.yres_virtual * xdr_line_length; 634 par->xdr_frame_size = info->var.yres_virtual * xdr_line_length;
641 635
642 par->num_frames = ps3fb.xdr_size / 636 par->num_frames = info->fix.smem_len /
643 max(par->ddr_frame_size, par->xdr_frame_size); 637 max(par->ddr_frame_size, par->xdr_frame_size);
644 638
645 /* Keep the special bits we cannot set using fb_var_screeninfo */ 639 /* Keep the special bits we cannot set using fb_var_screeninfo */
@@ -667,13 +661,13 @@ static int ps3fb_set_par(struct fb_info *info)
667 } 661 }
668 662
669 /* Clear XDR frame buffer memory */ 663 /* Clear XDR frame buffer memory */
670 memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size); 664 memset((void __force *)info->screen_base, 0, info->fix.smem_len);
671 665
672 /* Clear DDR frame buffer memory */ 666 /* Clear DDR frame buffer memory */
673 lines = vmode->yres * par->num_frames; 667 lines = vmode->yres * par->num_frames;
674 if (par->full_offset) 668 if (par->full_offset)
675 lines++; 669 lines++;
676 maxlines = ps3fb.xdr_size / ddr_line_length; 670 maxlines = info->fix.smem_len / ddr_line_length;
677 for (dst = 0; lines; dst += maxlines * ddr_line_length) { 671 for (dst = 0; lines; dst += maxlines * ddr_line_length) {
678 unsigned int l = min(lines, maxlines); 672 unsigned int l = min(lines, maxlines);
679 ps3fb_sync_image(info->device, 0, dst, 0, vmode->xres, l, 673 ps3fb_sync_image(info->device, 0, dst, 0, vmode->xres, l,
@@ -1017,10 +1011,9 @@ static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev)
1017 __func__, status); 1011 __func__, status);
1018 return -ENXIO; 1012 return -ENXIO;
1019 } 1013 }
1020 dev_dbg(dev, 1014 dev_dbg(dev, "video:%p ioif:%lx lpar:%lx size:%lx\n",
1021 "video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n", 1015 ps3fb_videomemory.address, GPU_IOIF, xdr_lpar,
1022 ps3fb_videomemory.address, ps3fb.xdr_ea, GPU_IOIF, xdr_lpar, 1016 ps3fb_videomemory.size);
1023 virt_to_abs(ps3fb.xdr_ea), ps3fb_videomemory.size);
1024 1017
1025 status = lv1_gpu_context_attribute(ps3fb.context_handle, 1018 status = lv1_gpu_context_attribute(ps3fb.context_handle,
1026 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP, 1019 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
@@ -1103,6 +1096,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1103 u64 lpar_reports = 0; 1096 u64 lpar_reports = 0;
1104 u64 lpar_reports_size = 0; 1097 u64 lpar_reports_size = 0;
1105 u64 xdr_lpar; 1098 u64 xdr_lpar;
1099 void *fb_start;
1106 int status; 1100 int status;
1107 struct task_struct *task; 1101 struct task_struct *task;
1108 unsigned long max_ps3fb_size; 1102 unsigned long max_ps3fb_size;
@@ -1158,7 +1152,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1158 } 1152 }
1159 1153
1160 /* vsync interrupt */ 1154 /* vsync interrupt */
1161 ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024); 1155 ps3fb.dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024);
1162 if (!ps3fb.dinfo) { 1156 if (!ps3fb.dinfo) {
1163 dev_err(&dev->core, "%s: ioremap failed\n", __func__); 1157 dev_err(&dev->core, "%s: ioremap failed\n", __func__);
1164 goto err_gpu_context_free; 1158 goto err_gpu_context_free;
@@ -1168,22 +1162,10 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1168 if (retval) 1162 if (retval)
1169 goto err_iounmap_dinfo; 1163 goto err_iounmap_dinfo;
1170 1164
1171 /* XDR frame buffer */
1172 ps3fb.xdr_ea = ps3fb_videomemory.address;
1173 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea));
1174
1175 /* Clear memory to prevent kernel info leakage into userspace */ 1165 /* Clear memory to prevent kernel info leakage into userspace */
1176 memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size); 1166 memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size);
1177
1178 /*
1179 * The GPU command buffer is at the start of video memory
1180 * As we don't use the full command buffer, we can put the actual
1181 * frame buffer at offset GPU_FB_START and save some precious XDR
1182 * memory
1183 */
1184 ps3fb.xdr_ea += GPU_FB_START;
1185 ps3fb.xdr_size = ps3fb_videomemory.size - GPU_FB_START;
1186 1167
1168 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address));
1187 retval = ps3fb_xdr_settings(xdr_lpar, &dev->core); 1169 retval = ps3fb_xdr_settings(xdr_lpar, &dev->core);
1188 if (retval) 1170 if (retval)
1189 goto err_free_irq; 1171 goto err_free_irq;
@@ -1197,12 +1179,20 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1197 par->new_mode_id = ps3fb_mode; 1179 par->new_mode_id = ps3fb_mode;
1198 par->num_frames = 1; 1180 par->num_frames = 1;
1199 1181
1200 info->screen_base = (char __iomem *)ps3fb.xdr_ea;
1201 info->fbops = &ps3fb_ops; 1182 info->fbops = &ps3fb_ops;
1202
1203 info->fix = ps3fb_fix; 1183 info->fix = ps3fb_fix;
1204 info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea); 1184
1205 info->fix.smem_len = ps3fb.xdr_size; 1185 /*
1186 * The GPU command buffer is at the start of video memory
1187 * As we don't use the full command buffer, we can put the actual
1188 * frame buffer at offset GPU_FB_START and save some precious XDR
1189 * memory
1190 */
1191 fb_start = ps3fb_videomemory.address + GPU_FB_START;
1192 info->screen_base = (char __force __iomem *)fb_start;
1193 info->fix.smem_start = virt_to_abs(fb_start);
1194 info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START;
1195
1206 info->pseudo_palette = par->pseudo_palette; 1196 info->pseudo_palette = par->pseudo_palette;
1207 info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST | 1197 info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
1208 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; 1198 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
@@ -1227,9 +1217,9 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1227 1217
1228 dev->core.driver_data = info; 1218 dev->core.driver_data = info;
1229 1219
1230 dev_info(info->device, "%s %s, using %lu KiB of video memory\n", 1220 dev_info(info->device, "%s %s, using %u KiB of video memory\n",
1231 dev_driver_string(info->dev), info->dev->bus_id, 1221 dev_driver_string(info->dev), info->dev->bus_id,
1232 ps3fb.xdr_size >> 10); 1222 info->fix.smem_len >> 10);
1233 1223
1234 task = kthread_run(ps3fbd, info, DEVICE_NAME); 1224 task = kthread_run(ps3fbd, info, DEVICE_NAME);
1235 if (IS_ERR(task)) { 1225 if (IS_ERR(task)) {
@@ -1252,7 +1242,7 @@ err_free_irq:
1252 free_irq(ps3fb.irq_no, &dev->core); 1242 free_irq(ps3fb.irq_no, &dev->core);
1253 ps3_irq_plug_destroy(ps3fb.irq_no); 1243 ps3_irq_plug_destroy(ps3fb.irq_no);
1254err_iounmap_dinfo: 1244err_iounmap_dinfo:
1255 iounmap((u8 __iomem *)ps3fb.dinfo); 1245 iounmap((u8 __force __iomem *)ps3fb.dinfo);
1256err_gpu_context_free: 1246err_gpu_context_free:
1257 lv1_gpu_context_free(ps3fb.context_handle); 1247 lv1_gpu_context_free(ps3fb.context_handle);
1258err_gpu_memory_free: 1248err_gpu_memory_free:
@@ -1287,7 +1277,7 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1287 framebuffer_release(info); 1277 framebuffer_release(info);
1288 info = dev->core.driver_data = NULL; 1278 info = dev->core.driver_data = NULL;
1289 } 1279 }
1290 iounmap((u8 __iomem *)ps3fb.dinfo); 1280 iounmap((u8 __force __iomem *)ps3fb.dinfo);
1291 1281
1292 status = lv1_gpu_context_free(ps3fb.context_handle); 1282 status = lv1_gpu_context_free(ps3fb.context_handle);
1293 if (status) 1283 if (status)