diff options
-rw-r--r-- | drivers/video/ps3fb.c | 64 |
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); |
1254 | err_iounmap_dinfo: | 1244 | err_iounmap_dinfo: |
1255 | iounmap((u8 __iomem *)ps3fb.dinfo); | 1245 | iounmap((u8 __force __iomem *)ps3fb.dinfo); |
1256 | err_gpu_context_free: | 1246 | err_gpu_context_free: |
1257 | lv1_gpu_context_free(ps3fb.context_handle); | 1247 | lv1_gpu_context_free(ps3fb.context_handle); |
1258 | err_gpu_memory_free: | 1248 | err_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) |