aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/ata/libata-scsi.c2
-rw-r--r--drivers/base/memory.c6
-rw-r--r--drivers/base/node.c91
-rw-r--r--drivers/block/loop.c73
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/agp/Kconfig2
-rw-r--r--drivers/char/drm/Kconfig2
-rw-r--r--drivers/char/drm/radeon_irq.c4
-rw-r--r--drivers/char/mem.c125
-rw-r--r--drivers/char/mspec.c2
-rw-r--r--drivers/char/vt.c13
-rw-r--r--drivers/char/vt_ioctl.c15
-rw-r--r--drivers/dca/Kconfig7
-rw-r--r--drivers/dca/Makefile2
-rw-r--r--drivers/dca/dca-core.c200
-rw-r--r--drivers/dca/dca-sysfs.c88
-rw-r--r--drivers/dma/Kconfig60
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/ioat.c211
-rw-r--r--drivers/dma/ioat_dca.c263
-rw-r--r--drivers/dma/ioat_dma.c (renamed from drivers/dma/ioatdma.c)653
-rw-r--r--drivers/dma/ioatdma.h35
-rw-r--r--drivers/dma/ioatdma_hw.h2
-rw-r--r--drivers/dma/ioatdma_registers.h6
-rw-r--r--drivers/isdn/capi/capidrv.c5
-rw-r--r--drivers/isdn/capi/kcapi.c2
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c9
-rw-r--r--drivers/isdn/gigaset/i4l.c12
-rw-r--r--drivers/isdn/gigaset/proc.c8
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c7
-rw-r--r--drivers/isdn/i4l/isdn_common.c26
-rw-r--r--drivers/message/fusion/mptscsih.c10
-rw-r--r--drivers/mmc/host/mmc_spi.c4
-rw-r--r--drivers/pcmcia/Kconfig6
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c5
-rw-r--r--drivers/pcmcia/cistpl.c48
-rw-r--r--drivers/pcmcia/ds.c4
-rw-r--r--drivers/pcmcia/pxa2xx_base.c2
-rw-r--r--drivers/ps3/ps3av.c387
-rw-r--r--drivers/ps3/ps3av_cmd.c83
-rw-r--r--drivers/rtc/Kconfig11
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/class.c1
-rw-r--r--drivers/rtc/interface.c122
-rw-r--r--drivers/rtc/rtc-cmos.c64
-rw-r--r--drivers/rtc/rtc-dev.c44
-rw-r--r--drivers/rtc/rtc-ds1374.c449
-rw-r--r--drivers/rtc/rtc-ds1553.c2
-rw-r--r--drivers/rtc/rtc-ds1742.c2
-rw-r--r--drivers/rtc/rtc-pcf8583.c3
-rw-r--r--drivers/rtc/rtc-sysfs.c24
-rw-r--r--drivers/scsi/mac_scsi.c9
-rw-r--r--drivers/serial/8250_pci.c120
-rw-r--r--drivers/serial/8250_pnp.c2
-rw-r--r--drivers/serial/crisv10.c67
-rw-r--r--drivers/serial/m32r_sio.c2
-rw-r--r--drivers/serial/m32r_sio.h6
-rw-r--r--drivers/serial/serial_core.c40
-rw-r--r--drivers/serial/serial_cs.c1
-rw-r--r--drivers/serial/serial_txx9.c30
-rw-r--r--drivers/spi/Kconfig13
-rw-r--r--drivers/spi/atmel_spi.c14
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c2
-rw-r--r--drivers/spi/omap2_mcspi.c4
-rw-r--r--drivers/spi/omap_uwire.c9
-rw-r--r--drivers/spi/pxa2xx_spi.c14
-rw-r--r--drivers/spi/spi.c36
-rw-r--r--drivers/spi/spi_bfin5xx.c3
-rw-r--r--drivers/spi/spi_bitbang.c2
-rw-r--r--drivers/spi/spi_imx.c13
-rw-r--r--drivers/spi/spi_lm70llp.c2
-rw-r--r--drivers/spi/spi_mpc83xx.c7
-rw-r--r--drivers/spi/spi_s3c24xx.c9
-rw-r--r--drivers/spi/spi_txx9.c2
-rw-r--r--drivers/usb/core/hub.c6
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c3
-rw-r--r--drivers/video/Kconfig59
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/amifb.c2
-rw-r--r--drivers/video/arcfb.c2
-rw-r--r--drivers/video/atafb.c2
-rw-r--r--drivers/video/aty/ati_ids.h1
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/aty/atyfb.h1
-rw-r--r--drivers/video/aty/atyfb_base.c6
-rw-r--r--drivers/video/aty/mach64_cursor.c1
-rw-r--r--drivers/video/aty/radeon_base.c5
-rw-r--r--drivers/video/aty/radeonfb.h4
-rw-r--r--drivers/video/backlight/cr_bllcd.c1
-rw-r--r--drivers/video/backlight/progear_bl.c1
-rw-r--r--drivers/video/bf54x-lq043fb.c786
-rw-r--r--drivers/video/cfbcopyarea.c103
-rw-r--r--drivers/video/cfbfillrect.c20
-rw-r--r--drivers/video/cfbimgblt.c17
-rw-r--r--drivers/video/cirrusfb.c2050
-rw-r--r--drivers/video/clps711xfb.c2
-rw-r--r--drivers/video/console/fbcon.c5
-rw-r--r--drivers/video/console/font_10x18.c14
-rw-r--r--drivers/video/console/font_6x11.c13
-rw-r--r--drivers/video/console/font_7x14.c12
-rw-r--r--drivers/video/console/font_8x16.c14
-rw-r--r--drivers/video/console/font_8x8.c12
-rw-r--r--drivers/video/console/font_acorn_8x8.c14
-rw-r--r--drivers/video/console/font_mini_4x6.c12
-rw-r--r--drivers/video/console/font_pearl_8x8.c12
-rw-r--r--drivers/video/console/font_sun12x22.c14
-rw-r--r--drivers/video/console/font_sun8x16.c14
-rw-r--r--drivers/video/console/newport_con.c20
-rw-r--r--drivers/video/console/softcursor.c1
-rw-r--r--drivers/video/console/vgacon.c7
-rw-r--r--drivers/video/cyber2000fb.c1
-rw-r--r--drivers/video/epson1355fb.c2
-rw-r--r--drivers/video/fb_defio.c1
-rw-r--r--drivers/video/fb_draw.h94
-rw-r--r--drivers/video/fb_sys_fops.c2
-rw-r--r--drivers/video/fbcmap.c3
-rw-r--r--drivers/video/fbmem.c5
-rw-r--r--drivers/video/fbmon.c4
-rw-r--r--drivers/video/geode/lxfb_core.c7
-rw-r--r--drivers/video/hecubafb.c2
-rw-r--r--drivers/video/imsttfb.c2
-rw-r--r--drivers/video/imxfb.c4
-rw-r--r--drivers/video/intelfb/intelfb.h17
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c60
-rw-r--r--drivers/video/intelfb/intelfbdrv.c178
-rw-r--r--drivers/video/intelfb/intelfbhw.c318
-rw-r--r--drivers/video/intelfb/intelfbhw.h52
-rw-r--r--drivers/video/kyro/fbdev.c2
-rw-r--r--drivers/video/logo/logo.c7
-rw-r--r--drivers/video/matrox/matroxfb_base.c2
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c2
-rw-r--r--drivers/video/matrox/matroxfb_g450.c1
-rw-r--r--drivers/video/matrox/matroxfb_maven.c1
-rw-r--r--drivers/video/mbx/mbxfb.c344
-rw-r--r--drivers/video/mbx/reg_bits.h87
-rw-r--r--drivers/video/mbx/regs.h2
-rw-r--r--drivers/video/modedb.c58
-rw-r--r--drivers/video/neofb.c1
-rw-r--r--drivers/video/nvidia/nv_i2c.c10
-rw-r--r--drivers/video/nvidia/nv_type.h1
-rw-r--r--drivers/video/nvidia/nvidia.c6
-rw-r--r--drivers/video/pm2fb.c883
-rw-r--r--drivers/video/pm3fb.c557
-rw-r--r--drivers/video/pmag-ba-fb.c34
-rw-r--r--drivers/video/pmagb-b-fb.c34
-rw-r--r--drivers/video/pnx4008/pnxrgbfb.c1
-rw-r--r--drivers/video/ps3fb.c511
-rw-r--r--drivers/video/pvr2fb.c2
-rw-r--r--drivers/video/pxafb.c65
-rw-r--r--drivers/video/pxafb.h2
-rw-r--r--drivers/video/s3c2410fb.c783
-rw-r--r--drivers/video/s3c2410fb.h13
-rw-r--r--drivers/video/s3fb.c24
-rw-r--r--drivers/video/sa1100fb.c1
-rw-r--r--drivers/video/savage/savagefb_driver.c1
-rw-r--r--drivers/video/sis/sis_main.c2
-rw-r--r--drivers/video/skeletonfb.c2
-rw-r--r--drivers/video/sm501fb.c49
-rw-r--r--drivers/video/sstfb.c2
-rw-r--r--drivers/video/svgalib.c47
-rw-r--r--drivers/video/tdfxfb.c1255
-rw-r--r--drivers/video/tgafb.c20
-rw-r--r--drivers/video/tridentfb.c1075
-rw-r--r--drivers/video/uvesafb.c2066
-rw-r--r--drivers/video/vermilion/vermilion.c1
-rw-r--r--drivers/video/vfb.c79
168 files changed, 10928 insertions, 4715 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 7bdae47d6b91..4fb134d50da7 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -84,6 +84,8 @@ source "drivers/rtc/Kconfig"
84 84
85source "drivers/dma/Kconfig" 85source "drivers/dma/Kconfig"
86 86
87source "drivers/dca/Kconfig"
88
87source "drivers/auxdisplay/Kconfig" 89source "drivers/auxdisplay/Kconfig"
88 90
89source "drivers/kvm/Kconfig" 91source "drivers/kvm/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index a168eacdcd9c..174c27eb4430 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_CRYPTO) += crypto/
85obj-$(CONFIG_SUPERH) += sh/ 85obj-$(CONFIG_SUPERH) += sh/
86obj-$(CONFIG_GENERIC_TIME) += clocksource/ 86obj-$(CONFIG_GENERIC_TIME) += clocksource/
87obj-$(CONFIG_DMA_ENGINE) += dma/ 87obj-$(CONFIG_DMA_ENGINE) += dma/
88obj-$(CONFIG_DCA) += dca/
88obj-$(CONFIG_HID) += hid/ 89obj-$(CONFIG_HID) += hid/
89obj-$(CONFIG_PPC_PS3) += ps3/ 90obj-$(CONFIG_PPC_PS3) += ps3/
90obj-$(CONFIG_OF) += of/ 91obj-$(CONFIG_OF) += of/
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index ba62d534f32b..9fbb39cd0f58 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3238,7 +3238,7 @@ static void ata_scsi_handle_link_detach(struct ata_link *link)
3238 3238
3239/** 3239/**
3240 * ata_scsi_media_change_notify - send media change event 3240 * ata_scsi_media_change_notify - send media change event
3241 * @atadev: Pointer to the disk device with media change event 3241 * @dev: Pointer to the disk device with media change event
3242 * 3242 *
3243 * Tell the block layer to send a media change notification 3243 * Tell the block layer to send a media change notification
3244 * event. 3244 * event.
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 7a1390cd6aad..c41d0728efe2 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -238,7 +238,7 @@ store_mem_state(struct sys_device *dev, const char *buf, size_t count)
238 mem = container_of(dev, struct memory_block, sysdev); 238 mem = container_of(dev, struct memory_block, sysdev);
239 phys_section_nr = mem->phys_index; 239 phys_section_nr = mem->phys_index;
240 240
241 if (!valid_section_nr(phys_section_nr)) 241 if (!present_section_nr(phys_section_nr))
242 goto out; 242 goto out;
243 243
244 if (!strncmp(buf, "online", min((int)count, 6))) 244 if (!strncmp(buf, "online", min((int)count, 6)))
@@ -418,7 +418,7 @@ int register_new_memory(struct mem_section *section)
418 418
419int unregister_memory_section(struct mem_section *section) 419int unregister_memory_section(struct mem_section *section)
420{ 420{
421 if (!valid_section(section)) 421 if (!present_section(section))
422 return -EINVAL; 422 return -EINVAL;
423 423
424 return remove_memory_block(0, section, 0); 424 return remove_memory_block(0, section, 0);
@@ -443,7 +443,7 @@ int __init memory_dev_init(void)
443 * during boot and have been initialized 443 * during boot and have been initialized
444 */ 444 */
445 for (i = 0; i < NR_MEM_SECTIONS; i++) { 445 for (i = 0; i < NR_MEM_SECTIONS; i++) {
446 if (!valid_section_nr(i)) 446 if (!present_section_nr(i))
447 continue; 447 continue;
448 err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0); 448 err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0);
449 if (!ret) 449 if (!ret)
diff --git a/drivers/base/node.c b/drivers/base/node.c
index cae346ef1b20..88eeed72b5d6 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -12,6 +12,7 @@
12#include <linux/topology.h> 12#include <linux/topology.h>
13#include <linux/nodemask.h> 13#include <linux/nodemask.h>
14#include <linux/cpu.h> 14#include <linux/cpu.h>
15#include <linux/device.h>
15 16
16static struct sysdev_class node_class = { 17static struct sysdev_class node_class = {
17 set_kset_name("node"), 18 set_kset_name("node"),
@@ -232,8 +233,96 @@ void unregister_one_node(int nid)
232 unregister_node(&node_devices[nid]); 233 unregister_node(&node_devices[nid]);
233} 234}
234 235
236/*
237 * node states attributes
238 */
239
240static ssize_t print_nodes_state(enum node_states state, char *buf)
241{
242 int n;
243
244 n = nodelist_scnprintf(buf, PAGE_SIZE, node_states[state]);
245 if (n > 0 && PAGE_SIZE > n + 1) {
246 *(buf + n++) = '\n';
247 *(buf + n++) = '\0';
248 }
249 return n;
250}
251
252static ssize_t print_nodes_possible(struct sysdev_class *class, char *buf)
253{
254 return print_nodes_state(N_POSSIBLE, buf);
255}
256
257static ssize_t print_nodes_online(struct sysdev_class *class, char *buf)
258{
259 return print_nodes_state(N_ONLINE, buf);
260}
261
262static ssize_t print_nodes_has_normal_memory(struct sysdev_class *class,
263 char *buf)
264{
265 return print_nodes_state(N_NORMAL_MEMORY, buf);
266}
267
268static ssize_t print_nodes_has_cpu(struct sysdev_class *class, char *buf)
269{
270 return print_nodes_state(N_CPU, buf);
271}
272
273static SYSDEV_CLASS_ATTR(possible, 0444, print_nodes_possible, NULL);
274static SYSDEV_CLASS_ATTR(online, 0444, print_nodes_online, NULL);
275static SYSDEV_CLASS_ATTR(has_normal_memory, 0444, print_nodes_has_normal_memory,
276 NULL);
277static SYSDEV_CLASS_ATTR(has_cpu, 0444, print_nodes_has_cpu, NULL);
278
279#ifdef CONFIG_HIGHMEM
280static ssize_t print_nodes_has_high_memory(struct sysdev_class *class,
281 char *buf)
282{
283 return print_nodes_state(N_HIGH_MEMORY, buf);
284}
285
286static SYSDEV_CLASS_ATTR(has_high_memory, 0444, print_nodes_has_high_memory,
287 NULL);
288#endif
289
290struct sysdev_class_attribute *node_state_attr[] = {
291 &attr_possible,
292 &attr_online,
293 &attr_has_normal_memory,
294#ifdef CONFIG_HIGHMEM
295 &attr_has_high_memory,
296#endif
297 &attr_has_cpu,
298};
299
300static int node_states_init(void)
301{
302 int i;
303 int err = 0;
304
305 for (i = 0; i < NR_NODE_STATES; i++) {
306 int ret;
307 ret = sysdev_class_create_file(&node_class, node_state_attr[i]);
308 if (!err)
309 err = ret;
310 }
311 return err;
312}
313
235static int __init register_node_type(void) 314static int __init register_node_type(void)
236{ 315{
237 return sysdev_class_register(&node_class); 316 int ret;
317
318 ret = sysdev_class_register(&node_class);
319 if (!ret)
320 ret = node_states_init();
321
322 /*
323 * Note: we're not going to unregister the node class if we fail
324 * to register the node state class attribute files.
325 */
326 return ret;
238} 327}
239postcore_initcall(register_node_type); 328postcore_initcall(register_node_type);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index b9233a06934c..e5a051577a5e 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -204,14 +204,13 @@ lo_do_transfer(struct loop_device *lo, int cmd,
204 * do_lo_send_aops - helper for writing data to a loop device 204 * do_lo_send_aops - helper for writing data to a loop device
205 * 205 *
206 * This is the fast version for backing filesystems which implement the address 206 * This is the fast version for backing filesystems which implement the address
207 * space operations prepare_write and commit_write. 207 * space operations write_begin and write_end.
208 */ 208 */
209static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, 209static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
210 int bsize, loff_t pos, struct page *page) 210 int bsize, loff_t pos, struct page *unused)
211{ 211{
212 struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ 212 struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
213 struct address_space *mapping = file->f_mapping; 213 struct address_space *mapping = file->f_mapping;
214 const struct address_space_operations *aops = mapping->a_ops;
215 pgoff_t index; 214 pgoff_t index;
216 unsigned offset, bv_offs; 215 unsigned offset, bv_offs;
217 int len, ret; 216 int len, ret;
@@ -223,63 +222,45 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
223 len = bvec->bv_len; 222 len = bvec->bv_len;
224 while (len > 0) { 223 while (len > 0) {
225 sector_t IV; 224 sector_t IV;
226 unsigned size; 225 unsigned size, copied;
227 int transfer_result; 226 int transfer_result;
227 struct page *page;
228 void *fsdata;
228 229
229 IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); 230 IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9);
230 size = PAGE_CACHE_SIZE - offset; 231 size = PAGE_CACHE_SIZE - offset;
231 if (size > len) 232 if (size > len)
232 size = len; 233 size = len;
233 page = grab_cache_page(mapping, index); 234
234 if (unlikely(!page)) 235 ret = pagecache_write_begin(file, mapping, pos, size, 0,
236 &page, &fsdata);
237 if (ret)
235 goto fail; 238 goto fail;
236 ret = aops->prepare_write(file, page, offset, 239
237 offset + size);
238 if (unlikely(ret)) {
239 if (ret == AOP_TRUNCATED_PAGE) {
240 page_cache_release(page);
241 continue;
242 }
243 goto unlock;
244 }
245 transfer_result = lo_do_transfer(lo, WRITE, page, offset, 240 transfer_result = lo_do_transfer(lo, WRITE, page, offset,
246 bvec->bv_page, bv_offs, size, IV); 241 bvec->bv_page, bv_offs, size, IV);
247 if (unlikely(transfer_result)) { 242 copied = size;
248 /*
249 * The transfer failed, but we still write the data to
250 * keep prepare/commit calls balanced.
251 */
252 printk(KERN_ERR "loop: transfer error block %llu\n",
253 (unsigned long long)index);
254 zero_user_page(page, offset, size, KM_USER0);
255 }
256 flush_dcache_page(page);
257 ret = aops->commit_write(file, page, offset,
258 offset + size);
259 if (unlikely(ret)) {
260 if (ret == AOP_TRUNCATED_PAGE) {
261 page_cache_release(page);
262 continue;
263 }
264 goto unlock;
265 }
266 if (unlikely(transfer_result)) 243 if (unlikely(transfer_result))
267 goto unlock; 244 copied = 0;
268 bv_offs += size; 245
269 len -= size; 246 ret = pagecache_write_end(file, mapping, pos, size, copied,
247 page, fsdata);
248 if (ret < 0 || ret != copied)
249 goto fail;
250
251 if (unlikely(transfer_result))
252 goto fail;
253
254 bv_offs += copied;
255 len -= copied;
270 offset = 0; 256 offset = 0;
271 index++; 257 index++;
272 pos += size; 258 pos += copied;
273 unlock_page(page);
274 page_cache_release(page);
275 } 259 }
276 ret = 0; 260 ret = 0;
277out: 261out:
278 mutex_unlock(&mapping->host->i_mutex); 262 mutex_unlock(&mapping->host->i_mutex);
279 return ret; 263 return ret;
280unlock:
281 unlock_page(page);
282 page_cache_release(page);
283fail: 264fail:
284 ret = -1; 265 ret = -1;
285 goto out; 266 goto out;
@@ -313,7 +294,7 @@ static int __do_lo_send_write(struct file *file,
313 * do_lo_send_direct_write - helper for writing data to a loop device 294 * do_lo_send_direct_write - helper for writing data to a loop device
314 * 295 *
315 * This is the fast, non-transforming version for backing filesystems which do 296 * This is the fast, non-transforming version for backing filesystems which do
316 * not implement the address space operations prepare_write and commit_write. 297 * not implement the address space operations write_begin and write_end.
317 * It uses the write file operation which should be present on all writeable 298 * It uses the write file operation which should be present on all writeable
318 * filesystems. 299 * filesystems.
319 */ 300 */
@@ -332,7 +313,7 @@ static int do_lo_send_direct_write(struct loop_device *lo,
332 * do_lo_send_write - helper for writing data to a loop device 313 * do_lo_send_write - helper for writing data to a loop device
333 * 314 *
334 * This is the slow, transforming version for filesystems which do not 315 * This is the slow, transforming version for filesystems which do not
335 * implement the address space operations prepare_write and commit_write. It 316 * implement the address space operations write_begin and write_end. It
336 * uses the write file operation which should be present on all writeable 317 * uses the write file operation which should be present on all writeable
337 * filesystems. 318 * filesystems.
338 * 319 *
@@ -780,7 +761,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
780 */ 761 */
781 if (!file->f_op->splice_read) 762 if (!file->f_op->splice_read)
782 goto out_putf; 763 goto out_putf;
783 if (aops->prepare_write && aops->commit_write) 764 if (aops->prepare_write || aops->write_begin)
784 lo_flags |= LO_FLAGS_USE_AOPS; 765 lo_flags |= LO_FLAGS_USE_AOPS;
785 if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write) 766 if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write)
786 lo_flags |= LO_FLAGS_READ_ONLY; 767 lo_flags |= LO_FLAGS_READ_ONLY;
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index b391776e5bf3..f6f8c03047fa 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -896,10 +896,6 @@ config GPIO_TB0219
896 depends on TANBAC_TB022X 896 depends on TANBAC_TB022X
897 select GPIO_VR41XX 897 select GPIO_VR41XX
898 898
899source "drivers/char/agp/Kconfig"
900
901source "drivers/char/drm/Kconfig"
902
903source "drivers/char/pcmcia/Kconfig" 899source "drivers/char/pcmcia/Kconfig"
904 900
905config MWAVE 901config MWAVE
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 713533d8a86e..f22c253bc09f 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -1,4 +1,4 @@
1config AGP 1menuconfig AGP
2 tristate "/dev/agpgart (AGP Support)" 2 tristate "/dev/agpgart (AGP Support)"
3 depends on ALPHA || IA64 || PARISC || PPC || X86 3 depends on ALPHA || IA64 || PARISC || PPC || X86
4 depends on PCI 4 depends on PCI
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index 0b7ffa5191c6..ba3058dd39a7 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -4,7 +4,7 @@
4# This driver provides support for the 4# This driver provides support for the
5# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 5# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
6# 6#
7config DRM 7menuconfig DRM
8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" 8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
9 depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG 9 depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG
10 help 10 help
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index f89e57665b64..2b2407ee490e 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -144,8 +144,8 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
144 return ret; 144 return ret;
145} 145}
146 146
147int radeon_driver_vblank_do_wait(struct drm_device * dev, unsigned int *sequence, 147static int radeon_driver_vblank_do_wait(struct drm_device * dev,
148 int crtc) 148 unsigned int *sequence, int crtc)
149{ 149{
150 drm_radeon_private_t *dev_priv = 150 drm_radeon_private_t *dev_priv =
151 (drm_radeon_private_t *) dev->dev_private; 151 (drm_radeon_private_t *) dev->dev_private;
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index bbee97ff355f..64551ab6be03 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -625,65 +625,10 @@ static ssize_t splice_write_null(struct pipe_inode_info *pipe,struct file *out,
625 return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null); 625 return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
626} 626}
627 627
628#ifdef CONFIG_MMU
629/*
630 * For fun, we are using the MMU for this.
631 */
632static inline size_t read_zero_pagealigned(char __user * buf, size_t size)
633{
634 struct mm_struct *mm;
635 struct vm_area_struct * vma;
636 unsigned long addr=(unsigned long)buf;
637
638 mm = current->mm;
639 /* Oops, this was forgotten before. -ben */
640 down_read(&mm->mmap_sem);
641
642 /* For private mappings, just map in zero pages. */
643 for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
644 unsigned long count;
645
646 if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
647 goto out_up;
648 if (vma->vm_flags & (VM_SHARED | VM_HUGETLB))
649 break;
650 count = vma->vm_end - addr;
651 if (count > size)
652 count = size;
653
654 zap_page_range(vma, addr, count, NULL);
655 if (zeromap_page_range(vma, addr, count, PAGE_COPY))
656 break;
657
658 size -= count;
659 buf += count;
660 addr += count;
661 if (size == 0)
662 goto out_up;
663 }
664
665 up_read(&mm->mmap_sem);
666
667 /* The shared case is hard. Let's do the conventional zeroing. */
668 do {
669 unsigned long unwritten = clear_user(buf, PAGE_SIZE);
670 if (unwritten)
671 return size + unwritten - PAGE_SIZE;
672 cond_resched();
673 buf += PAGE_SIZE;
674 size -= PAGE_SIZE;
675 } while (size);
676
677 return size;
678out_up:
679 up_read(&mm->mmap_sem);
680 return size;
681}
682
683static ssize_t read_zero(struct file * file, char __user * buf, 628static ssize_t read_zero(struct file * file, char __user * buf,
684 size_t count, loff_t *ppos) 629 size_t count, loff_t *ppos)
685{ 630{
686 unsigned long left, unwritten, written = 0; 631 size_t written;
687 632
688 if (!count) 633 if (!count)
689 return 0; 634 return 0;
@@ -691,69 +636,33 @@ static ssize_t read_zero(struct file * file, char __user * buf,
691 if (!access_ok(VERIFY_WRITE, buf, count)) 636 if (!access_ok(VERIFY_WRITE, buf, count))
692 return -EFAULT; 637 return -EFAULT;
693 638
694 left = count; 639 written = 0;
695 640 while (count) {
696 /* do we want to be clever? Arbitrary cut-off */ 641 unsigned long unwritten;
697 if (count >= PAGE_SIZE*4) { 642 size_t chunk = count;
698 unsigned long partial;
699 643
700 /* How much left of the page? */ 644 if (chunk > PAGE_SIZE)
701 partial = (PAGE_SIZE-1) & -(unsigned long) buf; 645 chunk = PAGE_SIZE; /* Just for latency reasons */
702 unwritten = clear_user(buf, partial); 646 unwritten = clear_user(buf, chunk);
703 written = partial - unwritten; 647 written += chunk - unwritten;
704 if (unwritten)
705 goto out;
706 left -= partial;
707 buf += partial;
708 unwritten = read_zero_pagealigned(buf, left & PAGE_MASK);
709 written += (left & PAGE_MASK) - unwritten;
710 if (unwritten) 648 if (unwritten)
711 goto out; 649 break;
712 buf += left & PAGE_MASK;
713 left &= ~PAGE_MASK;
714 }
715 unwritten = clear_user(buf, left);
716 written += left - unwritten;
717out:
718 return written ? written : -EFAULT;
719}
720
721static int mmap_zero(struct file * file, struct vm_area_struct * vma)
722{
723 int err;
724
725 if (vma->vm_flags & VM_SHARED)
726 return shmem_zero_setup(vma);
727 err = zeromap_page_range(vma, vma->vm_start,
728 vma->vm_end - vma->vm_start, vma->vm_page_prot);
729 BUG_ON(err == -EEXIST);
730 return err;
731}
732#else /* CONFIG_MMU */
733static ssize_t read_zero(struct file * file, char * buf,
734 size_t count, loff_t *ppos)
735{
736 size_t todo = count;
737
738 while (todo) {
739 size_t chunk = todo;
740
741 if (chunk > 4096)
742 chunk = 4096; /* Just for latency reasons */
743 if (clear_user(buf, chunk))
744 return -EFAULT;
745 buf += chunk; 650 buf += chunk;
746 todo -= chunk; 651 count -= chunk;
747 cond_resched(); 652 cond_resched();
748 } 653 }
749 return count; 654 return written ? written : -EFAULT;
750} 655}
751 656
752static int mmap_zero(struct file * file, struct vm_area_struct * vma) 657static int mmap_zero(struct file * file, struct vm_area_struct * vma)
753{ 658{
659#ifndef CONFIG_MMU
754 return -ENOSYS; 660 return -ENOSYS;
661#endif
662 if (vma->vm_flags & VM_SHARED)
663 return shmem_zero_setup(vma);
664 return 0;
755} 665}
756#endif /* CONFIG_MMU */
757 666
758static ssize_t write_full(struct file * file, const char __user * buf, 667static ssize_t write_full(struct file * file, const char __user * buf,
759 size_t count, loff_t *ppos) 668 size_t count, loff_t *ppos)
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index 04ac155d3a07..82f2e27dca7d 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -362,7 +362,7 @@ mspec_init(void)
362 is_sn2 = 1; 362 is_sn2 = 1;
363 if (is_shub2()) { 363 if (is_shub2()) {
364 ret = -ENOMEM; 364 ret = -ENOMEM;
365 for_each_online_node(nid) { 365 for_each_node_state(nid, N_ONLINE) {
366 int actual_nid; 366 int actual_nid;
367 int nasid; 367 int nasid;
368 unsigned long phys; 368 unsigned long phys;
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index edb7002a3216..0d56f8fc105c 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -750,13 +750,15 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
750 return 0; 750 return 0;
751} 751}
752 752
753static inline int resize_screen(struct vc_data *vc, int width, int height) 753static inline int resize_screen(struct vc_data *vc, int width, int height,
754 int user)
754{ 755{
755 /* Resizes the resolution of the display adapater */ 756 /* Resizes the resolution of the display adapater */
756 int err = 0; 757 int err = 0;
757 758
758 if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize) 759 if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize)
759 err = vc->vc_sw->con_resize(vc, width, height); 760 err = vc->vc_sw->con_resize(vc, width, height, user);
761
760 return err; 762 return err;
761} 763}
762 764
@@ -772,7 +774,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
772 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; 774 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
773 unsigned int old_cols, old_rows, old_row_size, old_screen_size; 775 unsigned int old_cols, old_rows, old_row_size, old_screen_size;
774 unsigned int new_cols, new_rows, new_row_size, new_screen_size; 776 unsigned int new_cols, new_rows, new_row_size, new_screen_size;
775 unsigned int end; 777 unsigned int end, user;
776 unsigned short *newscreen; 778 unsigned short *newscreen;
777 779
778 WARN_CONSOLE_UNLOCKED(); 780 WARN_CONSOLE_UNLOCKED();
@@ -780,6 +782,9 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
780 if (!vc) 782 if (!vc)
781 return -ENXIO; 783 return -ENXIO;
782 784
785 user = vc->vc_resize_user;
786 vc->vc_resize_user = 0;
787
783 if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW) 788 if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
784 return -EINVAL; 789 return -EINVAL;
785 790
@@ -800,7 +805,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
800 old_row_size = vc->vc_size_row; 805 old_row_size = vc->vc_size_row;
801 old_screen_size = vc->vc_screenbuf_size; 806 old_screen_size = vc->vc_screenbuf_size;
802 807
803 err = resize_screen(vc, new_cols, new_rows); 808 err = resize_screen(vc, new_cols, new_rows, user);
804 if (err) { 809 if (err) {
805 kfree(newscreen); 810 kfree(newscreen);
806 return err; 811 return err;
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 7a61a2a9aafe..f69a8258095c 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -847,14 +847,24 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
847 case VT_RESIZE: 847 case VT_RESIZE:
848 { 848 {
849 struct vt_sizes __user *vtsizes = up; 849 struct vt_sizes __user *vtsizes = up;
850 struct vc_data *vc;
851
850 ushort ll,cc; 852 ushort ll,cc;
851 if (!perm) 853 if (!perm)
852 return -EPERM; 854 return -EPERM;
853 if (get_user(ll, &vtsizes->v_rows) || 855 if (get_user(ll, &vtsizes->v_rows) ||
854 get_user(cc, &vtsizes->v_cols)) 856 get_user(cc, &vtsizes->v_cols))
855 return -EFAULT; 857 return -EFAULT;
856 for (i = 0; i < MAX_NR_CONSOLES; i++) 858
857 vc_lock_resize(vc_cons[i].d, cc, ll); 859 for (i = 0; i < MAX_NR_CONSOLES; i++) {
860 vc = vc_cons[i].d;
861
862 if (vc) {
863 vc->vc_resize_user = 1;
864 vc_lock_resize(vc_cons[i].d, cc, ll);
865 }
866 }
867
858 return 0; 868 return 0;
859 } 869 }
860 870
@@ -900,6 +910,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
900 vc_cons[i].d->vc_scan_lines = vlin; 910 vc_cons[i].d->vc_scan_lines = vlin;
901 if (clin) 911 if (clin)
902 vc_cons[i].d->vc_font.height = clin; 912 vc_cons[i].d->vc_font.height = clin;
913 vc_cons[i].d->vc_resize_user = 1;
903 vc_resize(vc_cons[i].d, cc, ll); 914 vc_resize(vc_cons[i].d, cc, ll);
904 release_console_sem(); 915 release_console_sem();
905 } 916 }
diff --git a/drivers/dca/Kconfig b/drivers/dca/Kconfig
new file mode 100644
index 000000000000..94f0364a0efb
--- /dev/null
+++ b/drivers/dca/Kconfig
@@ -0,0 +1,7 @@
1#
2# DCA server configuration
3#
4
5config DCA
6 tristate
7
diff --git a/drivers/dca/Makefile b/drivers/dca/Makefile
new file mode 100644
index 000000000000..b2db56bb9dde
--- /dev/null
+++ b/drivers/dca/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_DCA) += dca.o
2dca-objs := dca-core.o dca-sysfs.o
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c
new file mode 100644
index 000000000000..bf5b92f86df7
--- /dev/null
+++ b/drivers/dca/dca-core.c
@@ -0,0 +1,200 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59
16 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called COPYING.
20 */
21
22/*
23 * This driver supports an interface for DCA clients and providers to meet.
24 */
25
26#include <linux/kernel.h>
27#include <linux/notifier.h>
28#include <linux/device.h>
29#include <linux/dca.h>
30
31MODULE_LICENSE("GPL");
32
33/* For now we're assuming a single, global, DCA provider for the system. */
34
35static DEFINE_SPINLOCK(dca_lock);
36
37static struct dca_provider *global_dca = NULL;
38
39/**
40 * dca_add_requester - add a dca client to the list
41 * @dev - the device that wants dca service
42 */
43int dca_add_requester(struct device *dev)
44{
45 int err, slot;
46
47 if (!global_dca)
48 return -ENODEV;
49
50 spin_lock(&dca_lock);
51 slot = global_dca->ops->add_requester(global_dca, dev);
52 spin_unlock(&dca_lock);
53 if (slot < 0)
54 return slot;
55
56 err = dca_sysfs_add_req(global_dca, dev, slot);
57 if (err) {
58 spin_lock(&dca_lock);
59 global_dca->ops->remove_requester(global_dca, dev);
60 spin_unlock(&dca_lock);
61 return err;
62 }
63
64 return 0;
65}
66EXPORT_SYMBOL_GPL(dca_add_requester);
67
68/**
69 * dca_remove_requester - remove a dca client from the list
70 * @dev - the device that wants dca service
71 */
72int dca_remove_requester(struct device *dev)
73{
74 int slot;
75 if (!global_dca)
76 return -ENODEV;
77
78 spin_lock(&dca_lock);
79 slot = global_dca->ops->remove_requester(global_dca, dev);
80 spin_unlock(&dca_lock);
81 if (slot < 0)
82 return slot;
83
84 dca_sysfs_remove_req(global_dca, slot);
85 return 0;
86}
87EXPORT_SYMBOL_GPL(dca_remove_requester);
88
89/**
90 * dca_get_tag - return the dca tag for the given cpu
91 * @cpu - the cpuid as returned by get_cpu()
92 */
93u8 dca_get_tag(int cpu)
94{
95 if (!global_dca)
96 return -ENODEV;
97 return global_dca->ops->get_tag(global_dca, cpu);
98}
99EXPORT_SYMBOL_GPL(dca_get_tag);
100
101/**
102 * alloc_dca_provider - get data struct for describing a dca provider
103 * @ops - pointer to struct of dca operation function pointers
104 * @priv_size - size of extra mem to be added for provider's needs
105 */
106struct dca_provider *alloc_dca_provider(struct dca_ops *ops, int priv_size)
107{
108 struct dca_provider *dca;
109 int alloc_size;
110
111 alloc_size = (sizeof(*dca) + priv_size);
112 dca = kzalloc(alloc_size, GFP_KERNEL);
113 if (!dca)
114 return NULL;
115 dca->ops = ops;
116
117 return dca;
118}
119EXPORT_SYMBOL_GPL(alloc_dca_provider);
120
121/**
122 * free_dca_provider - release the dca provider data struct
123 * @ops - pointer to struct of dca operation function pointers
124 * @priv_size - size of extra mem to be added for provider's needs
125 */
126void free_dca_provider(struct dca_provider *dca)
127{
128 kfree(dca);
129}
130EXPORT_SYMBOL_GPL(free_dca_provider);
131
132static BLOCKING_NOTIFIER_HEAD(dca_provider_chain);
133
134/**
135 * register_dca_provider - register a dca provider
136 * @dca - struct created by alloc_dca_provider()
137 * @dev - device providing dca services
138 */
139int register_dca_provider(struct dca_provider *dca, struct device *dev)
140{
141 int err;
142
143 if (global_dca)
144 return -EEXIST;
145 err = dca_sysfs_add_provider(dca, dev);
146 if (err)
147 return err;
148 global_dca = dca;
149 blocking_notifier_call_chain(&dca_provider_chain,
150 DCA_PROVIDER_ADD, NULL);
151 return 0;
152}
153EXPORT_SYMBOL_GPL(register_dca_provider);
154
155/**
156 * unregister_dca_provider - remove a dca provider
157 * @dca - struct created by alloc_dca_provider()
158 */
159void unregister_dca_provider(struct dca_provider *dca)
160{
161 if (!global_dca)
162 return;
163 blocking_notifier_call_chain(&dca_provider_chain,
164 DCA_PROVIDER_REMOVE, NULL);
165 global_dca = NULL;
166 dca_sysfs_remove_provider(dca);
167}
168EXPORT_SYMBOL_GPL(unregister_dca_provider);
169
170/**
171 * dca_register_notify - register a client's notifier callback
172 */
173void dca_register_notify(struct notifier_block *nb)
174{
175 blocking_notifier_chain_register(&dca_provider_chain, nb);
176}
177EXPORT_SYMBOL_GPL(dca_register_notify);
178
179/**
180 * dca_unregister_notify - remove a client's notifier callback
181 */
182void dca_unregister_notify(struct notifier_block *nb)
183{
184 blocking_notifier_chain_unregister(&dca_provider_chain, nb);
185}
186EXPORT_SYMBOL_GPL(dca_unregister_notify);
187
188static int __init dca_init(void)
189{
190 return dca_sysfs_init();
191}
192
193static void __exit dca_exit(void)
194{
195 dca_sysfs_exit();
196}
197
198module_init(dca_init);
199module_exit(dca_exit);
200
diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c
new file mode 100644
index 000000000000..24a263b6844c
--- /dev/null
+++ b/drivers/dca/dca-sysfs.c
@@ -0,0 +1,88 @@
1#include <linux/kernel.h>
2#include <linux/spinlock.h>
3#include <linux/device.h>
4#include <linux/idr.h>
5#include <linux/kdev_t.h>
6#include <linux/err.h>
7#include <linux/dca.h>
8
9static struct class *dca_class;
10static struct idr dca_idr;
11static spinlock_t dca_idr_lock;
12
13int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot)
14{
15 struct class_device *cd;
16
17 cd = class_device_create(dca_class, dca->cd, MKDEV(0, slot + 1),
18 dev, "requester%d", slot);
19 if (IS_ERR(cd))
20 return PTR_ERR(cd);
21 return 0;
22}
23
24void dca_sysfs_remove_req(struct dca_provider *dca, int slot)
25{
26 class_device_destroy(dca_class, MKDEV(0, slot + 1));
27}
28
29int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev)
30{
31 struct class_device *cd;
32 int err = 0;
33
34idr_try_again:
35 if (!idr_pre_get(&dca_idr, GFP_KERNEL))
36 return -ENOMEM;
37 spin_lock(&dca_idr_lock);
38 err = idr_get_new(&dca_idr, dca, &dca->id);
39 spin_unlock(&dca_idr_lock);
40 switch (err) {
41 case 0:
42 break;
43 case -EAGAIN:
44 goto idr_try_again;
45 default:
46 return err;
47 }
48
49 cd = class_device_create(dca_class, NULL, MKDEV(0, 0),
50 dev, "dca%d", dca->id);
51 if (IS_ERR(cd)) {
52 spin_lock(&dca_idr_lock);
53 idr_remove(&dca_idr, dca->id);
54 spin_unlock(&dca_idr_lock);
55 return PTR_ERR(cd);
56 }
57 dca->cd = cd;
58 return 0;
59}
60
61void dca_sysfs_remove_provider(struct dca_provider *dca)
62{
63 class_device_unregister(dca->cd);
64 dca->cd = NULL;
65 spin_lock(&dca_idr_lock);
66 idr_remove(&dca_idr, dca->id);
67 spin_unlock(&dca_idr_lock);
68}
69
70int __init dca_sysfs_init(void)
71{
72 idr_init(&dca_idr);
73 spin_lock_init(&dca_idr_lock);
74
75 dca_class = class_create(THIS_MODULE, "dca");
76 if (IS_ERR(dca_class)) {
77 idr_destroy(&dca_idr);
78 return PTR_ERR(dca_class);
79 }
80 return 0;
81}
82
83void __exit dca_sysfs_exit(void)
84{
85 class_destroy(dca_class);
86 idr_destroy(&dca_idr);
87}
88
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 8f670dae53bb..9c91b0fd134f 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -2,42 +2,52 @@
2# DMA engine configuration 2# DMA engine configuration
3# 3#
4 4
5menu "DMA Engine support" 5menuconfig DMADEVICES
6 depends on HAS_DMA 6 bool "DMA Offload Engine support"
7 depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
8 help
9 Intel(R) offload engines enable offloading memory copies in the
10 network stack and RAID operations in the MD driver.
11
12if DMADEVICES
13
14comment "DMA Devices"
15
16config INTEL_IOATDMA
17 tristate "Intel I/OAT DMA support"
18 depends on PCI && X86
19 select DMA_ENGINE
20 select DCA
21 help
22 Enable support for the Intel(R) I/OAT DMA engine present
23 in recent Intel Xeon chipsets.
24
25 Say Y here if you have such a chipset.
26
27 If unsure, say N.
28
29config INTEL_IOP_ADMA
30 tristate "Intel IOP ADMA support"
31 depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
32 select ASYNC_CORE
33 select DMA_ENGINE
34 help
35 Enable support for the Intel(R) IOP Series RAID engines.
7 36
8config DMA_ENGINE 37config DMA_ENGINE
9 bool "Support for DMA engines" 38 bool
10 ---help---
11 DMA engines offload bulk memory operations from the CPU to dedicated
12 hardware, allowing the operations to happen asynchronously.
13 39
14comment "DMA Clients" 40comment "DMA Clients"
41 depends on DMA_ENGINE
15 42
16config NET_DMA 43config NET_DMA
17 bool "Network: TCP receive copy offload" 44 bool "Network: TCP receive copy offload"
18 depends on DMA_ENGINE && NET 45 depends on DMA_ENGINE && NET
19 default y 46 default y
20 ---help--- 47 help
21 This enables the use of DMA engines in the network stack to 48 This enables the use of DMA engines in the network stack to
22 offload receive copy-to-user operations, freeing CPU cycles. 49 offload receive copy-to-user operations, freeing CPU cycles.
23 Since this is the main user of the DMA engine, it should be enabled; 50 Since this is the main user of the DMA engine, it should be enabled;
24 say Y here. 51 say Y here.
25 52
26comment "DMA Devices" 53endif
27
28config INTEL_IOATDMA
29 tristate "Intel I/OAT DMA support"
30 depends on DMA_ENGINE && PCI
31 default m
32 ---help---
33 Enable support for the Intel(R) I/OAT DMA engine.
34
35config INTEL_IOP_ADMA
36 tristate "Intel IOP ADMA support"
37 depends on DMA_ENGINE && (ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX)
38 select ASYNC_CORE
39 default m
40 ---help---
41 Enable support for the Intel(R) IOP Series RAID engines.
42
43endmenu
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index b3839b687ae0..b152cd84e123 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_DMA_ENGINE) += dmaengine.o 1obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
2obj-$(CONFIG_NET_DMA) += iovlock.o 2obj-$(CONFIG_NET_DMA) += iovlock.o
3obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o 3obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
4ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o
4obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o 5obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
diff --git a/drivers/dma/ioat.c b/drivers/dma/ioat.c
new file mode 100644
index 000000000000..f7276bf2fe7e
--- /dev/null
+++ b/drivers/dma/ioat.c
@@ -0,0 +1,211 @@
1/*
2 * Intel I/OAT DMA Linux driver
3 * Copyright(c) 2007 Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 */
22
23/*
24 * This driver supports an Intel I/OAT DMA engine, which does asynchronous
25 * copy operations.
26 */
27
28#include <linux/init.h>
29#include <linux/module.h>
30#include <linux/pci.h>
31#include <linux/interrupt.h>
32#include <linux/dca.h>
33#include "ioatdma.h"
34#include "ioatdma_registers.h"
35#include "ioatdma_hw.h"
36
37MODULE_VERSION("1.24");
38MODULE_LICENSE("GPL");
39MODULE_AUTHOR("Intel Corporation");
40
41static struct pci_device_id ioat_pci_tbl[] = {
42 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
43 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB) },
44 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SCNB) },
45 { PCI_DEVICE(PCI_VENDOR_ID_UNISYS, PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR) },
46 { 0, }
47};
48
49struct ioat_device {
50 struct pci_dev *pdev;
51 void __iomem *iobase;
52 struct ioatdma_device *dma;
53 struct dca_provider *dca;
54};
55
56static int __devinit ioat_probe(struct pci_dev *pdev,
57 const struct pci_device_id *id);
58#ifdef IOAT_DMA_REMOVE
59static void __devexit ioat_remove(struct pci_dev *pdev);
60#endif
61
62static int ioat_dca_enabled = 1;
63module_param(ioat_dca_enabled, int, 0644);
64MODULE_PARM_DESC(ioat_dca_enabled, "control support of dca service (default: 1)");
65
66static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase)
67{
68 struct ioat_device *device = pci_get_drvdata(pdev);
69 u8 version;
70 int err = 0;
71
72 version = readb(iobase + IOAT_VER_OFFSET);
73 switch (version) {
74 case IOAT_VER_1_2:
75 device->dma = ioat_dma_probe(pdev, iobase);
76 if (ioat_dca_enabled)
77 device->dca = ioat_dca_init(pdev, iobase);
78 break;
79 default:
80 err = -ENODEV;
81 break;
82 }
83 return err;
84}
85
86static void ioat_shutdown_functionality(struct pci_dev *pdev)
87{
88 struct ioat_device *device = pci_get_drvdata(pdev);
89
90 if (device->dma) {
91 ioat_dma_remove(device->dma);
92 device->dma = NULL;
93 }
94
95 if (device->dca) {
96 unregister_dca_provider(device->dca);
97 free_dca_provider(device->dca);
98 device->dca = NULL;
99 }
100
101}
102
103static struct pci_driver ioat_pci_drv = {
104 .name = "ioatdma",
105 .id_table = ioat_pci_tbl,
106 .probe = ioat_probe,
107 .shutdown = ioat_shutdown_functionality,
108#ifdef IOAT_DMA_REMOVE
109 .remove = __devexit_p(ioat_remove),
110#endif
111};
112
113static int __devinit ioat_probe(struct pci_dev *pdev,
114 const struct pci_device_id *id)
115{
116 void __iomem *iobase;
117 struct ioat_device *device;
118 unsigned long mmio_start, mmio_len;
119 int err;
120
121 err = pci_enable_device(pdev);
122 if (err)
123 goto err_enable_device;
124
125 err = pci_request_regions(pdev, ioat_pci_drv.name);
126 if (err)
127 goto err_request_regions;
128
129 err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
130 if (err)
131 err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
132 if (err)
133 goto err_set_dma_mask;
134
135 err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
136 if (err)
137 err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
138 if (err)
139 goto err_set_dma_mask;
140
141 mmio_start = pci_resource_start(pdev, 0);
142 mmio_len = pci_resource_len(pdev, 0);
143 iobase = ioremap(mmio_start, mmio_len);
144 if (!iobase) {
145 err = -ENOMEM;
146 goto err_ioremap;
147 }
148
149 device = kzalloc(sizeof(*device), GFP_KERNEL);
150 if (!device) {
151 err = -ENOMEM;
152 goto err_kzalloc;
153 }
154 device->pdev = pdev;
155 pci_set_drvdata(pdev, device);
156 device->iobase = iobase;
157
158 pci_set_master(pdev);
159
160 err = ioat_setup_functionality(pdev, iobase);
161 if (err)
162 goto err_version;
163
164 return 0;
165
166err_version:
167 kfree(device);
168err_kzalloc:
169 iounmap(iobase);
170err_ioremap:
171err_set_dma_mask:
172 pci_release_regions(pdev);
173 pci_disable_device(pdev);
174err_request_regions:
175err_enable_device:
176 return err;
177}
178
179#ifdef IOAT_DMA_REMOVE
180/*
181 * It is unsafe to remove this module: if removed while a requested
182 * dma is outstanding, esp. from tcp, it is possible to hang while
183 * waiting for something that will never finish, thus hanging at
184 * least one cpu. However, if you're feeling lucky and need to do
185 * some testing, this usually works just fine.
186 */
187static void __devexit ioat_remove(struct pci_dev *pdev)
188{
189 struct ioat_device *device = pci_get_drvdata(pdev);
190
191 ioat_shutdown_functionality(pdev);
192
193 kfree(device);
194
195 iounmap(device->iobase);
196 pci_release_regions(pdev);
197 pci_disable_device(pdev);
198}
199#endif
200
201static int __init ioat_init_module(void)
202{
203 return pci_register_driver(&ioat_pci_drv);
204}
205module_init(ioat_init_module);
206
207static void __exit ioat_exit_module(void)
208{
209 pci_unregister_driver(&ioat_pci_drv);
210}
211module_exit(ioat_exit_module);
diff --git a/drivers/dma/ioat_dca.c b/drivers/dma/ioat_dca.c
new file mode 100644
index 000000000000..2ae04c30edeb
--- /dev/null
+++ b/drivers/dma/ioat_dca.c
@@ -0,0 +1,263 @@
1/*
2 * Intel I/OAT DMA Linux driver
3 * Copyright(c) 2007 Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 */
22
23#include <linux/kernel.h>
24#include <linux/pci.h>
25#include <linux/smp.h>
26#include <linux/interrupt.h>
27#include <linux/dca.h>
28
29/* either a kernel change is needed, or we need something like this in kernel */
30#ifndef CONFIG_SMP
31#include <asm/smp.h>
32#undef cpu_physical_id
33#define cpu_physical_id(cpu) (cpuid_ebx(1) >> 24)
34#endif
35
36#include "ioatdma.h"
37#include "ioatdma_registers.h"
38
39/*
40 * Bit 16 of a tag map entry is the "valid" bit, if it is set then bits 0:15
41 * contain the bit number of the APIC ID to map into the DCA tag. If the valid
42 * bit is not set, then the value must be 0 or 1 and defines the bit in the tag.
43 */
44#define DCA_TAG_MAP_VALID 0x80
45
46/*
47 * "Legacy" DCA systems do not implement the DCA register set in the
48 * I/OAT device. Software needs direct support for their tag mappings.
49 */
50
51#define APICID_BIT(x) (DCA_TAG_MAP_VALID | (x))
52#define IOAT_TAG_MAP_LEN 8
53
54static u8 ioat_tag_map_BNB[IOAT_TAG_MAP_LEN] = {
55 1, APICID_BIT(1), APICID_BIT(2), APICID_BIT(2), };
56static u8 ioat_tag_map_SCNB[IOAT_TAG_MAP_LEN] = {
57 1, APICID_BIT(1), APICID_BIT(2), APICID_BIT(2), };
58static u8 ioat_tag_map_CNB[IOAT_TAG_MAP_LEN] = {
59 1, APICID_BIT(1), APICID_BIT(3), APICID_BIT(4), APICID_BIT(2), };
60static u8 ioat_tag_map_UNISYS[IOAT_TAG_MAP_LEN] = { 0 };
61
62/* pack PCI B/D/F into a u16 */
63static inline u16 dcaid_from_pcidev(struct pci_dev *pci)
64{
65 return (pci->bus->number << 8) | pci->devfn;
66}
67
68static int dca_enabled_in_bios(void)
69{
70 /* CPUID level 9 returns DCA configuration */
71 /* Bit 0 indicates DCA enabled by the BIOS */
72 unsigned long cpuid_level_9;
73 int res;
74
75 cpuid_level_9 = cpuid_eax(9);
76 res = test_bit(0, &cpuid_level_9);
77 if (!res)
78 printk(KERN_ERR "ioat dma: DCA is disabled in BIOS\n");
79
80 return res;
81}
82
83static int system_has_dca_enabled(void)
84{
85 if (boot_cpu_has(X86_FEATURE_DCA))
86 return dca_enabled_in_bios();
87
88 printk(KERN_ERR "ioat dma: boot cpu doesn't have X86_FEATURE_DCA\n");
89 return 0;
90}
91
92struct ioat_dca_slot {
93 struct pci_dev *pdev; /* requester device */
94 u16 rid; /* requester id, as used by IOAT */
95};
96
97#define IOAT_DCA_MAX_REQ 6
98
99struct ioat_dca_priv {
100 void __iomem *iobase;
101 void *dca_base;
102 int max_requesters;
103 int requester_count;
104 u8 tag_map[IOAT_TAG_MAP_LEN];
105 struct ioat_dca_slot req_slots[0];
106};
107
108/* 5000 series chipset DCA Port Requester ID Table Entry Format
109 * [15:8] PCI-Express Bus Number
110 * [7:3] PCI-Express Device Number
111 * [2:0] PCI-Express Function Number
112 *
113 * 5000 series chipset DCA control register format
114 * [7:1] Reserved (0)
115 * [0] Ignore Function Number
116 */
117
118static int ioat_dca_add_requester(struct dca_provider *dca, struct device *dev)
119{
120 struct ioat_dca_priv *ioatdca = dca_priv(dca);
121 struct pci_dev *pdev;
122 int i;
123 u16 id;
124
125 /* This implementation only supports PCI-Express */
126 if (dev->bus != &pci_bus_type)
127 return -ENODEV;
128 pdev = to_pci_dev(dev);
129 id = dcaid_from_pcidev(pdev);
130
131 if (ioatdca->requester_count == ioatdca->max_requesters)
132 return -ENODEV;
133
134 for (i = 0; i < ioatdca->max_requesters; i++) {
135 if (ioatdca->req_slots[i].pdev == NULL) {
136 /* found an empty slot */
137 ioatdca->requester_count++;
138 ioatdca->req_slots[i].pdev = pdev;
139 ioatdca->req_slots[i].rid = id;
140 writew(id, ioatdca->dca_base + (i * 4));
141 /* make sure the ignore function bit is off */
142 writeb(0, ioatdca->dca_base + (i * 4) + 2);
143 return i;
144 }
145 }
146 /* Error, ioatdma->requester_count is out of whack */
147 return -EFAULT;
148}
149
150static int ioat_dca_remove_requester(struct dca_provider *dca,
151 struct device *dev)
152{
153 struct ioat_dca_priv *ioatdca = dca_priv(dca);
154 struct pci_dev *pdev;
155 int i;
156
157 /* This implementation only supports PCI-Express */
158 if (dev->bus != &pci_bus_type)
159 return -ENODEV;
160 pdev = to_pci_dev(dev);
161
162 for (i = 0; i < ioatdca->max_requesters; i++) {
163 if (ioatdca->req_slots[i].pdev == pdev) {
164 writew(0, ioatdca->dca_base + (i * 4));
165 ioatdca->req_slots[i].pdev = NULL;
166 ioatdca->req_slots[i].rid = 0;
167 ioatdca->requester_count--;
168 return i;
169 }
170 }
171 return -ENODEV;
172}
173
174static u8 ioat_dca_get_tag(struct dca_provider *dca, int cpu)
175{
176 struct ioat_dca_priv *ioatdca = dca_priv(dca);
177 int i, apic_id, bit, value;
178 u8 entry, tag;
179
180 tag = 0;
181 apic_id = cpu_physical_id(cpu);
182
183 for (i = 0; i < IOAT_TAG_MAP_LEN; i++) {
184 entry = ioatdca->tag_map[i];
185 if (entry & DCA_TAG_MAP_VALID) {
186 bit = entry & ~DCA_TAG_MAP_VALID;
187 value = (apic_id & (1 << bit)) ? 1 : 0;
188 } else {
189 value = entry ? 1 : 0;
190 }
191 tag |= (value << i);
192 }
193 return tag;
194}
195
196static struct dca_ops ioat_dca_ops = {
197 .add_requester = ioat_dca_add_requester,
198 .remove_requester = ioat_dca_remove_requester,
199 .get_tag = ioat_dca_get_tag,
200};
201
202
203struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase)
204{
205 struct dca_provider *dca;
206 struct ioat_dca_priv *ioatdca;
207 u8 *tag_map = NULL;
208 int i;
209 int err;
210
211 if (!system_has_dca_enabled())
212 return NULL;
213
214 /* I/OAT v1 systems must have a known tag_map to support DCA */
215 switch (pdev->vendor) {
216 case PCI_VENDOR_ID_INTEL:
217 switch (pdev->device) {
218 case PCI_DEVICE_ID_INTEL_IOAT:
219 tag_map = ioat_tag_map_BNB;
220 break;
221 case PCI_DEVICE_ID_INTEL_IOAT_CNB:
222 tag_map = ioat_tag_map_CNB;
223 break;
224 case PCI_DEVICE_ID_INTEL_IOAT_SCNB:
225 tag_map = ioat_tag_map_SCNB;
226 break;
227 }
228 break;
229 case PCI_VENDOR_ID_UNISYS:
230 switch (pdev->device) {
231 case PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR:
232 tag_map = ioat_tag_map_UNISYS;
233 break;
234 }
235 break;
236 }
237 if (tag_map == NULL)
238 return NULL;
239
240 dca = alloc_dca_provider(&ioat_dca_ops,
241 sizeof(*ioatdca) +
242 (sizeof(struct ioat_dca_slot) * IOAT_DCA_MAX_REQ));
243 if (!dca)
244 return NULL;
245
246 ioatdca = dca_priv(dca);
247 ioatdca->max_requesters = IOAT_DCA_MAX_REQ;
248
249 ioatdca->dca_base = iobase + 0x54;
250
251 /* copy over the APIC ID to DCA tag mapping */
252 for (i = 0; i < IOAT_TAG_MAP_LEN; i++)
253 ioatdca->tag_map[i] = tag_map[i];
254
255 err = register_dca_provider(dca, &pdev->dev);
256 if (err) {
257 free_dca_provider(dca);
258 return NULL;
259 }
260
261 return dca;
262}
263
diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioat_dma.c
index 41b18c5a3141..66c5bb53211b 100644
--- a/drivers/dma/ioatdma.c
+++ b/drivers/dma/ioat_dma.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. 2 * Intel I/OAT DMA Linux driver
3 * Copyright(c) 2004 - 2007 Intel Corporation.
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free 6 * under the terms and conditions of the GNU General Public License,
6 * Software Foundation; either version 2 of the License, or (at your option) 7 * version 2, as published by the Free Software Foundation.
7 * any later version.
8 * 8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT 9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@@ -12,11 +12,12 @@
12 * more details. 12 * more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License along with 14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
17 * 20 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called COPYING.
20 */ 21 */
21 22
22/* 23/*
@@ -35,17 +36,77 @@
35#include "ioatdma_registers.h" 36#include "ioatdma_registers.h"
36#include "ioatdma_hw.h" 37#include "ioatdma_hw.h"
37 38
39#define INITIAL_IOAT_DESC_COUNT 128
40
38#define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common) 41#define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common)
39#define to_ioat_device(dev) container_of(dev, struct ioat_device, common) 42#define to_ioatdma_device(dev) container_of(dev, struct ioatdma_device, common)
40#define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node) 43#define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node)
41#define tx_to_ioat_desc(tx) container_of(tx, struct ioat_desc_sw, async_tx) 44#define tx_to_ioat_desc(tx) container_of(tx, struct ioat_desc_sw, async_tx)
42 45
43/* internal functions */ 46/* internal functions */
44static int __devinit ioat_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 47static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan);
45static void ioat_shutdown(struct pci_dev *pdev); 48static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
46static void __devexit ioat_remove(struct pci_dev *pdev);
47 49
48static int enumerate_dma_channels(struct ioat_device *device) 50static struct ioat_dma_chan *ioat_lookup_chan_by_index(struct ioatdma_device *device,
51 int index)
52{
53 return device->idx[index];
54}
55
56/**
57 * ioat_dma_do_interrupt - handler used for single vector interrupt mode
58 * @irq: interrupt id
59 * @data: interrupt data
60 */
61static irqreturn_t ioat_dma_do_interrupt(int irq, void *data)
62{
63 struct ioatdma_device *instance = data;
64 struct ioat_dma_chan *ioat_chan;
65 unsigned long attnstatus;
66 int bit;
67 u8 intrctrl;
68
69 intrctrl = readb(instance->reg_base + IOAT_INTRCTRL_OFFSET);
70
71 if (!(intrctrl & IOAT_INTRCTRL_MASTER_INT_EN))
72 return IRQ_NONE;
73
74 if (!(intrctrl & IOAT_INTRCTRL_INT_STATUS)) {
75 writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
76 return IRQ_NONE;
77 }
78
79 attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET);
80 for_each_bit(bit, &attnstatus, BITS_PER_LONG) {
81 ioat_chan = ioat_lookup_chan_by_index(instance, bit);
82 tasklet_schedule(&ioat_chan->cleanup_task);
83 }
84
85 writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
86 return IRQ_HANDLED;
87}
88
89/**
90 * ioat_dma_do_interrupt_msix - handler used for vector-per-channel interrupt mode
91 * @irq: interrupt id
92 * @data: interrupt data
93 */
94static irqreturn_t ioat_dma_do_interrupt_msix(int irq, void *data)
95{
96 struct ioat_dma_chan *ioat_chan = data;
97
98 tasklet_schedule(&ioat_chan->cleanup_task);
99
100 return IRQ_HANDLED;
101}
102
103static void ioat_dma_cleanup_tasklet(unsigned long data);
104
105/**
106 * ioat_dma_enumerate_channels - find and initialize the device's channels
107 * @device: the device to be enumerated
108 */
109static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
49{ 110{
50 u8 xfercap_scale; 111 u8 xfercap_scale;
51 u32 xfercap; 112 u32 xfercap;
@@ -73,13 +134,19 @@ static int enumerate_dma_channels(struct ioat_device *device)
73 /* This should be made common somewhere in dmaengine.c */ 134 /* This should be made common somewhere in dmaengine.c */
74 ioat_chan->common.device = &device->common; 135 ioat_chan->common.device = &device->common;
75 list_add_tail(&ioat_chan->common.device_node, 136 list_add_tail(&ioat_chan->common.device_node,
76 &device->common.channels); 137 &device->common.channels);
138 device->idx[i] = ioat_chan;
139 tasklet_init(&ioat_chan->cleanup_task,
140 ioat_dma_cleanup_tasklet,
141 (unsigned long) ioat_chan);
142 tasklet_disable(&ioat_chan->cleanup_task);
77 } 143 }
78 return device->common.chancnt; 144 return device->common.chancnt;
79} 145}
80 146
81static void 147static void ioat_set_src(dma_addr_t addr,
82ioat_set_src(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index) 148 struct dma_async_tx_descriptor *tx,
149 int index)
83{ 150{
84 struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx); 151 struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
85 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); 152 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
@@ -93,8 +160,9 @@ ioat_set_src(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
93 160
94} 161}
95 162
96static void 163static void ioat_set_dest(dma_addr_t addr,
97ioat_set_dest(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index) 164 struct dma_async_tx_descriptor *tx,
165 int index)
98{ 166{
99 struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx); 167 struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
100 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); 168 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
@@ -107,8 +175,7 @@ ioat_set_dest(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
107 } 175 }
108} 176}
109 177
110static dma_cookie_t 178static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx)
111ioat_tx_submit(struct dma_async_tx_descriptor *tx)
112{ 179{
113 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); 180 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
114 struct ioat_desc_sw *desc = tx_to_ioat_desc(tx); 181 struct ioat_desc_sw *desc = tx_to_ioat_desc(tx);
@@ -141,27 +208,27 @@ ioat_tx_submit(struct dma_async_tx_descriptor *tx)
141 if (append) 208 if (append)
142 writeb(IOAT_CHANCMD_APPEND, 209 writeb(IOAT_CHANCMD_APPEND,
143 ioat_chan->reg_base + IOAT_CHANCMD_OFFSET); 210 ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
144 211
145 return cookie; 212 return cookie;
146} 213}
147 214
148static struct ioat_desc_sw *ioat_dma_alloc_descriptor( 215static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
149 struct ioat_dma_chan *ioat_chan, 216 struct ioat_dma_chan *ioat_chan,
150 gfp_t flags) 217 gfp_t flags)
151{ 218{
152 struct ioat_dma_descriptor *desc; 219 struct ioat_dma_descriptor *desc;
153 struct ioat_desc_sw *desc_sw; 220 struct ioat_desc_sw *desc_sw;
154 struct ioat_device *ioat_device; 221 struct ioatdma_device *ioatdma_device;
155 dma_addr_t phys; 222 dma_addr_t phys;
156 223
157 ioat_device = to_ioat_device(ioat_chan->common.device); 224 ioatdma_device = to_ioatdma_device(ioat_chan->common.device);
158 desc = pci_pool_alloc(ioat_device->dma_pool, flags, &phys); 225 desc = pci_pool_alloc(ioatdma_device->dma_pool, flags, &phys);
159 if (unlikely(!desc)) 226 if (unlikely(!desc))
160 return NULL; 227 return NULL;
161 228
162 desc_sw = kzalloc(sizeof(*desc_sw), flags); 229 desc_sw = kzalloc(sizeof(*desc_sw), flags);
163 if (unlikely(!desc_sw)) { 230 if (unlikely(!desc_sw)) {
164 pci_pool_free(ioat_device->dma_pool, desc, phys); 231 pci_pool_free(ioatdma_device->dma_pool, desc, phys);
165 return NULL; 232 return NULL;
166 } 233 }
167 234
@@ -177,10 +244,6 @@ static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
177 return desc_sw; 244 return desc_sw;
178} 245}
179 246
180#define INITIAL_IOAT_DESC_COUNT 128
181
182static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan);
183
184/* returns the actual number of allocated descriptors */ 247/* returns the actual number of allocated descriptors */
185static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) 248static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
186{ 249{
@@ -195,15 +258,16 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
195 if (!list_empty(&ioat_chan->free_desc)) 258 if (!list_empty(&ioat_chan->free_desc))
196 return INITIAL_IOAT_DESC_COUNT; 259 return INITIAL_IOAT_DESC_COUNT;
197 260
198 /* Setup register to interrupt and write completion status on error */ 261 /* Setup register to interrupt and write completion status on error */
199 chanctrl = IOAT_CHANCTRL_ERR_INT_EN | 262 chanctrl = IOAT_CHANCTRL_ERR_INT_EN |
200 IOAT_CHANCTRL_ANY_ERR_ABORT_EN | 263 IOAT_CHANCTRL_ANY_ERR_ABORT_EN |
201 IOAT_CHANCTRL_ERR_COMPLETION_EN; 264 IOAT_CHANCTRL_ERR_COMPLETION_EN;
202 writew(chanctrl, ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET); 265 writew(chanctrl, ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET);
203 266
204 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); 267 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
205 if (chanerr) { 268 if (chanerr) {
206 printk("IOAT: CHANERR = %x, clearing\n", chanerr); 269 dev_err(&ioat_chan->device->pdev->dev,
270 "ioatdma: CHANERR = %x, clearing\n", chanerr);
207 writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET); 271 writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
208 } 272 }
209 273
@@ -211,7 +275,8 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
211 for (i = 0; i < INITIAL_IOAT_DESC_COUNT; i++) { 275 for (i = 0; i < INITIAL_IOAT_DESC_COUNT; i++) {
212 desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL); 276 desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
213 if (!desc) { 277 if (!desc) {
214 printk(KERN_ERR "IOAT: Only %d initial descriptors\n", i); 278 dev_err(&ioat_chan->device->pdev->dev,
279 "ioatdma: Only %d initial descriptors\n", i);
215 break; 280 break;
216 } 281 }
217 list_add_tail(&desc->node, &tmp_list); 282 list_add_tail(&desc->node, &tmp_list);
@@ -224,8 +289,8 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
224 /* doing 2 32bit writes to mmio since 1 64b write doesn't work */ 289 /* doing 2 32bit writes to mmio since 1 64b write doesn't work */
225 ioat_chan->completion_virt = 290 ioat_chan->completion_virt =
226 pci_pool_alloc(ioat_chan->device->completion_pool, 291 pci_pool_alloc(ioat_chan->device->completion_pool,
227 GFP_KERNEL, 292 GFP_KERNEL,
228 &ioat_chan->completion_addr); 293 &ioat_chan->completion_addr);
229 memset(ioat_chan->completion_virt, 0, 294 memset(ioat_chan->completion_virt, 0,
230 sizeof(*ioat_chan->completion_virt)); 295 sizeof(*ioat_chan->completion_virt));
231 writel(((u64) ioat_chan->completion_addr) & 0x00000000FFFFFFFF, 296 writel(((u64) ioat_chan->completion_addr) & 0x00000000FFFFFFFF,
@@ -233,54 +298,88 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
233 writel(((u64) ioat_chan->completion_addr) >> 32, 298 writel(((u64) ioat_chan->completion_addr) >> 32,
234 ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH); 299 ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH);
235 300
236 ioat_start_null_desc(ioat_chan); 301 tasklet_enable(&ioat_chan->cleanup_task);
302 ioat_dma_start_null_desc(ioat_chan);
237 return i; 303 return i;
238} 304}
239 305
240static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
241
242static void ioat_dma_free_chan_resources(struct dma_chan *chan) 306static void ioat_dma_free_chan_resources(struct dma_chan *chan)
243{ 307{
244 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); 308 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
245 struct ioat_device *ioat_device = to_ioat_device(chan->device); 309 struct ioatdma_device *ioatdma_device = to_ioatdma_device(chan->device);
246 struct ioat_desc_sw *desc, *_desc; 310 struct ioat_desc_sw *desc, *_desc;
247 u16 chanctrl;
248 int in_use_descs = 0; 311 int in_use_descs = 0;
249 312
313 tasklet_disable(&ioat_chan->cleanup_task);
250 ioat_dma_memcpy_cleanup(ioat_chan); 314 ioat_dma_memcpy_cleanup(ioat_chan);
251 315
316 /* Delay 100ms after reset to allow internal DMA logic to quiesce
317 * before removing DMA descriptor resources.
318 */
252 writeb(IOAT_CHANCMD_RESET, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET); 319 writeb(IOAT_CHANCMD_RESET, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
320 mdelay(100);
253 321
254 spin_lock_bh(&ioat_chan->desc_lock); 322 spin_lock_bh(&ioat_chan->desc_lock);
255 list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) { 323 list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) {
256 in_use_descs++; 324 in_use_descs++;
257 list_del(&desc->node); 325 list_del(&desc->node);
258 pci_pool_free(ioat_device->dma_pool, desc->hw, 326 pci_pool_free(ioatdma_device->dma_pool, desc->hw,
259 desc->async_tx.phys); 327 desc->async_tx.phys);
260 kfree(desc); 328 kfree(desc);
261 } 329 }
262 list_for_each_entry_safe(desc, _desc, &ioat_chan->free_desc, node) { 330 list_for_each_entry_safe(desc, _desc, &ioat_chan->free_desc, node) {
263 list_del(&desc->node); 331 list_del(&desc->node);
264 pci_pool_free(ioat_device->dma_pool, desc->hw, 332 pci_pool_free(ioatdma_device->dma_pool, desc->hw,
265 desc->async_tx.phys); 333 desc->async_tx.phys);
266 kfree(desc); 334 kfree(desc);
267 } 335 }
268 spin_unlock_bh(&ioat_chan->desc_lock); 336 spin_unlock_bh(&ioat_chan->desc_lock);
269 337
270 pci_pool_free(ioat_device->completion_pool, 338 pci_pool_free(ioatdma_device->completion_pool,
271 ioat_chan->completion_virt, 339 ioat_chan->completion_virt,
272 ioat_chan->completion_addr); 340 ioat_chan->completion_addr);
273 341
274 /* one is ok since we left it on there on purpose */ 342 /* one is ok since we left it on there on purpose */
275 if (in_use_descs > 1) 343 if (in_use_descs > 1)
276 printk(KERN_ERR "IOAT: Freeing %d in use descriptors!\n", 344 dev_err(&ioat_chan->device->pdev->dev,
345 "ioatdma: Freeing %d in use descriptors!\n",
277 in_use_descs - 1); 346 in_use_descs - 1);
278 347
279 ioat_chan->last_completion = ioat_chan->completion_addr = 0; 348 ioat_chan->last_completion = ioat_chan->completion_addr = 0;
349 ioat_chan->pending = 0;
350}
351/**
352 * ioat_dma_get_next_descriptor - return the next available descriptor
353 * @ioat_chan: IOAT DMA channel handle
354 *
355 * Gets the next descriptor from the chain, and must be called with the
356 * channel's desc_lock held. Allocates more descriptors if the channel
357 * has run out.
358 */
359static struct ioat_desc_sw *ioat_dma_get_next_descriptor(
360 struct ioat_dma_chan *ioat_chan)
361{
362 struct ioat_desc_sw *new = NULL;
363
364 if (!list_empty(&ioat_chan->free_desc)) {
365 new = to_ioat_desc(ioat_chan->free_desc.next);
366 list_del(&new->node);
367 } else {
368 /* try to get another desc */
369 new = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC);
370 /* will this ever happen? */
371 /* TODO add upper limit on these */
372 BUG_ON(!new);
373 }
374
375 prefetch(new->hw);
376 return new;
280} 377}
281 378
282static struct dma_async_tx_descriptor * 379static struct dma_async_tx_descriptor *ioat_dma_prep_memcpy(
283ioat_dma_prep_memcpy(struct dma_chan *chan, size_t len, int int_en) 380 struct dma_chan *chan,
381 size_t len,
382 int int_en)
284{ 383{
285 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); 384 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
286 struct ioat_desc_sw *first, *prev, *new; 385 struct ioat_desc_sw *first, *prev, *new;
@@ -299,17 +398,7 @@ ioat_dma_prep_memcpy(struct dma_chan *chan, size_t len, int int_en)
299 398
300 spin_lock_bh(&ioat_chan->desc_lock); 399 spin_lock_bh(&ioat_chan->desc_lock);
301 while (len) { 400 while (len) {
302 if (!list_empty(&ioat_chan->free_desc)) { 401 new = ioat_dma_get_next_descriptor(ioat_chan);
303 new = to_ioat_desc(ioat_chan->free_desc.next);
304 list_del(&new->node);
305 } else {
306 /* try to get another desc */
307 new = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC);
308 /* will this ever happen? */
309 /* TODO add upper limit on these */
310 BUG_ON(!new);
311 }
312
313 copy = min((u32) len, ioat_chan->xfercap); 402 copy = min((u32) len, ioat_chan->xfercap);
314 403
315 new->hw->size = copy; 404 new->hw->size = copy;
@@ -343,12 +432,11 @@ ioat_dma_prep_memcpy(struct dma_chan *chan, size_t len, int int_en)
343 return new ? &new->async_tx : NULL; 432 return new ? &new->async_tx : NULL;
344} 433}
345 434
346
347/** 435/**
348 * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended descriptors to hw 436 * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended
437 * descriptors to hw
349 * @chan: DMA channel handle 438 * @chan: DMA channel handle
350 */ 439 */
351
352static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan) 440static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan)
353{ 441{
354 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); 442 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
@@ -360,15 +448,23 @@ static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan)
360 } 448 }
361} 449}
362 450
363static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan) 451static void ioat_dma_cleanup_tasklet(unsigned long data)
452{
453 struct ioat_dma_chan *chan = (void *)data;
454 ioat_dma_memcpy_cleanup(chan);
455 writew(IOAT_CHANCTRL_INT_DISABLE,
456 chan->reg_base + IOAT_CHANCTRL_OFFSET);
457}
458
459static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
364{ 460{
365 unsigned long phys_complete; 461 unsigned long phys_complete;
366 struct ioat_desc_sw *desc, *_desc; 462 struct ioat_desc_sw *desc, *_desc;
367 dma_cookie_t cookie = 0; 463 dma_cookie_t cookie = 0;
368 464
369 prefetch(chan->completion_virt); 465 prefetch(ioat_chan->completion_virt);
370 466
371 if (!spin_trylock(&chan->cleanup_lock)) 467 if (!spin_trylock(&ioat_chan->cleanup_lock))
372 return; 468 return;
373 469
374 /* The completion writeback can happen at any time, 470 /* The completion writeback can happen at any time,
@@ -378,26 +474,28 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan)
378 474
379#if (BITS_PER_LONG == 64) 475#if (BITS_PER_LONG == 64)
380 phys_complete = 476 phys_complete =
381 chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR; 477 ioat_chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
382#else 478#else
383 phys_complete = chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK; 479 phys_complete = ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK;
384#endif 480#endif
385 481
386 if ((chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) == 482 if ((ioat_chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) ==
387 IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) { 483 IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) {
388 printk("IOAT: Channel halted, chanerr = %x\n", 484 dev_err(&ioat_chan->device->pdev->dev,
389 readl(chan->reg_base + IOAT_CHANERR_OFFSET)); 485 "ioatdma: Channel halted, chanerr = %x\n",
486 readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET));
390 487
391 /* TODO do something to salvage the situation */ 488 /* TODO do something to salvage the situation */
392 } 489 }
393 490
394 if (phys_complete == chan->last_completion) { 491 if (phys_complete == ioat_chan->last_completion) {
395 spin_unlock(&chan->cleanup_lock); 492 spin_unlock(&ioat_chan->cleanup_lock);
396 return; 493 return;
397 } 494 }
398 495
399 spin_lock_bh(&chan->desc_lock); 496 cookie = 0;
400 list_for_each_entry_safe(desc, _desc, &chan->used_desc, node) { 497 spin_lock_bh(&ioat_chan->desc_lock);
498 list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) {
401 499
402 /* 500 /*
403 * Incoming DMA requests may use multiple descriptors, due to 501 * Incoming DMA requests may use multiple descriptors, due to
@@ -407,31 +505,36 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan)
407 if (desc->async_tx.cookie) { 505 if (desc->async_tx.cookie) {
408 cookie = desc->async_tx.cookie; 506 cookie = desc->async_tx.cookie;
409 507
410 /* yes we are unmapping both _page and _single alloc'd 508 /*
411 regions with unmap_page. Is this *really* that bad? 509 * yes we are unmapping both _page and _single alloc'd
412 */ 510 * regions with unmap_page. Is this *really* that bad?
413 pci_unmap_page(chan->device->pdev, 511 */
512 pci_unmap_page(ioat_chan->device->pdev,
414 pci_unmap_addr(desc, dst), 513 pci_unmap_addr(desc, dst),
415 pci_unmap_len(desc, len), 514 pci_unmap_len(desc, len),
416 PCI_DMA_FROMDEVICE); 515 PCI_DMA_FROMDEVICE);
417 pci_unmap_page(chan->device->pdev, 516 pci_unmap_page(ioat_chan->device->pdev,
418 pci_unmap_addr(desc, src), 517 pci_unmap_addr(desc, src),
419 pci_unmap_len(desc, len), 518 pci_unmap_len(desc, len),
420 PCI_DMA_TODEVICE); 519 PCI_DMA_TODEVICE);
421 } 520 }
422 521
423 if (desc->async_tx.phys != phys_complete) { 522 if (desc->async_tx.phys != phys_complete) {
424 /* a completed entry, but not the last, so cleanup 523 /*
524 * a completed entry, but not the last, so cleanup
425 * if the client is done with the descriptor 525 * if the client is done with the descriptor
426 */ 526 */
427 if (desc->async_tx.ack) { 527 if (desc->async_tx.ack) {
428 list_del(&desc->node); 528 list_del(&desc->node);
429 list_add_tail(&desc->node, &chan->free_desc); 529 list_add_tail(&desc->node,
530 &ioat_chan->free_desc);
430 } else 531 } else
431 desc->async_tx.cookie = 0; 532 desc->async_tx.cookie = 0;
432 } else { 533 } else {
433 /* last used desc. Do not remove, so we can append from 534 /*
434 it, but don't look at it next time, either */ 535 * last used desc. Do not remove, so we can append from
536 * it, but don't look at it next time, either
537 */
435 desc->async_tx.cookie = 0; 538 desc->async_tx.cookie = 0;
436 539
437 /* TODO check status bits? */ 540 /* TODO check status bits? */
@@ -439,13 +542,13 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan)
439 } 542 }
440 } 543 }
441 544
442 spin_unlock_bh(&chan->desc_lock); 545 spin_unlock_bh(&ioat_chan->desc_lock);
443 546
444 chan->last_completion = phys_complete; 547 ioat_chan->last_completion = phys_complete;
445 if (cookie != 0) 548 if (cookie != 0)
446 chan->completed_cookie = cookie; 549 ioat_chan->completed_cookie = cookie;
447 550
448 spin_unlock(&chan->cleanup_lock); 551 spin_unlock(&ioat_chan->cleanup_lock);
449} 552}
450 553
451static void ioat_dma_dependency_added(struct dma_chan *chan) 554static void ioat_dma_dependency_added(struct dma_chan *chan)
@@ -466,11 +569,10 @@ static void ioat_dma_dependency_added(struct dma_chan *chan)
466 * @done: if not %NULL, updated with last completed transaction 569 * @done: if not %NULL, updated with last completed transaction
467 * @used: if not %NULL, updated with last used transaction 570 * @used: if not %NULL, updated with last used transaction
468 */ 571 */
469
470static enum dma_status ioat_dma_is_complete(struct dma_chan *chan, 572static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
471 dma_cookie_t cookie, 573 dma_cookie_t cookie,
472 dma_cookie_t *done, 574 dma_cookie_t *done,
473 dma_cookie_t *used) 575 dma_cookie_t *used)
474{ 576{
475 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); 577 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
476 dma_cookie_t last_used; 578 dma_cookie_t last_used;
@@ -481,7 +583,7 @@ static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
481 last_complete = ioat_chan->completed_cookie; 583 last_complete = ioat_chan->completed_cookie;
482 584
483 if (done) 585 if (done)
484 *done= last_complete; 586 *done = last_complete;
485 if (used) 587 if (used)
486 *used = last_used; 588 *used = last_used;
487 589
@@ -495,7 +597,7 @@ static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
495 last_complete = ioat_chan->completed_cookie; 597 last_complete = ioat_chan->completed_cookie;
496 598
497 if (done) 599 if (done)
498 *done= last_complete; 600 *done = last_complete;
499 if (used) 601 if (used)
500 *used = last_used; 602 *used = last_used;
501 603
@@ -504,63 +606,13 @@ static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
504 606
505/* PCI API */ 607/* PCI API */
506 608
507static struct pci_device_id ioat_pci_tbl[] = { 609static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
508 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
509 { PCI_DEVICE(PCI_VENDOR_ID_UNISYS,
510 PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR) },
511 { 0, }
512};
513
514static struct pci_driver ioat_pci_driver = {
515 .name = "ioatdma",
516 .id_table = ioat_pci_tbl,
517 .probe = ioat_probe,
518 .shutdown = ioat_shutdown,
519 .remove = __devexit_p(ioat_remove),
520};
521
522static irqreturn_t ioat_do_interrupt(int irq, void *data)
523{
524 struct ioat_device *instance = data;
525 unsigned long attnstatus;
526 u8 intrctrl;
527
528 intrctrl = readb(instance->reg_base + IOAT_INTRCTRL_OFFSET);
529
530 if (!(intrctrl & IOAT_INTRCTRL_MASTER_INT_EN))
531 return IRQ_NONE;
532
533 if (!(intrctrl & IOAT_INTRCTRL_INT_STATUS)) {
534 writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
535 return IRQ_NONE;
536 }
537
538 attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET);
539
540 printk(KERN_ERR "ioatdma error: interrupt! status %lx\n", attnstatus);
541
542 writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
543 return IRQ_HANDLED;
544}
545
546static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan)
547{ 610{
548 struct ioat_desc_sw *desc; 611 struct ioat_desc_sw *desc;
549 612
550 spin_lock_bh(&ioat_chan->desc_lock); 613 spin_lock_bh(&ioat_chan->desc_lock);
551 614
552 if (!list_empty(&ioat_chan->free_desc)) { 615 desc = ioat_dma_get_next_descriptor(ioat_chan);
553 desc = to_ioat_desc(ioat_chan->free_desc.next);
554 list_del(&desc->node);
555 } else {
556 /* try to get another desc */
557 spin_unlock_bh(&ioat_chan->desc_lock);
558 desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
559 spin_lock_bh(&ioat_chan->desc_lock);
560 /* will this ever happen? */
561 BUG_ON(!desc);
562 }
563
564 desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL; 616 desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL;
565 desc->hw->next = 0; 617 desc->hw->next = 0;
566 desc->async_tx.ack = 1; 618 desc->async_tx.ack = 1;
@@ -581,7 +633,11 @@ static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan)
581 */ 633 */
582#define IOAT_TEST_SIZE 2000 634#define IOAT_TEST_SIZE 2000
583 635
584static int ioat_self_test(struct ioat_device *device) 636/**
637 * ioat_dma_self_test - Perform a IOAT transaction to verify the HW works.
638 * @device: device to be tested
639 */
640static int ioat_dma_self_test(struct ioatdma_device *device)
585{ 641{
586 int i; 642 int i;
587 u8 *src; 643 u8 *src;
@@ -607,9 +663,11 @@ static int ioat_self_test(struct ioat_device *device)
607 663
608 /* Start copy, using first DMA channel */ 664 /* Start copy, using first DMA channel */
609 dma_chan = container_of(device->common.channels.next, 665 dma_chan = container_of(device->common.channels.next,
610 struct dma_chan, 666 struct dma_chan,
611 device_node); 667 device_node);
612 if (ioat_dma_alloc_chan_resources(dma_chan) < 1) { 668 if (ioat_dma_alloc_chan_resources(dma_chan) < 1) {
669 dev_err(&device->pdev->dev,
670 "selftest cannot allocate chan resource\n");
613 err = -ENODEV; 671 err = -ENODEV;
614 goto out; 672 goto out;
615 } 673 }
@@ -627,12 +685,14 @@ static int ioat_self_test(struct ioat_device *device)
627 msleep(1); 685 msleep(1);
628 686
629 if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { 687 if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) {
630 printk(KERN_ERR "ioatdma: Self-test copy timed out, disabling\n"); 688 dev_err(&device->pdev->dev,
689 "ioatdma: Self-test copy timed out, disabling\n");
631 err = -ENODEV; 690 err = -ENODEV;
632 goto free_resources; 691 goto free_resources;
633 } 692 }
634 if (memcmp(src, dest, IOAT_TEST_SIZE)) { 693 if (memcmp(src, dest, IOAT_TEST_SIZE)) {
635 printk(KERN_ERR "ioatdma: Self-test copy failed compare, disabling\n"); 694 dev_err(&device->pdev->dev,
695 "ioatdma: Self-test copy failed compare, disabling\n");
636 err = -ENODEV; 696 err = -ENODEV;
637 goto free_resources; 697 goto free_resources;
638 } 698 }
@@ -645,147 +705,252 @@ out:
645 return err; 705 return err;
646} 706}
647 707
648static int __devinit ioat_probe(struct pci_dev *pdev, 708static char ioat_interrupt_style[32] = "msix";
649 const struct pci_device_id *ent) 709module_param_string(ioat_interrupt_style, ioat_interrupt_style,
710 sizeof(ioat_interrupt_style), 0644);
711MODULE_PARM_DESC(ioat_interrupt_style,
712 "set ioat interrupt style: msix (default), "
713 "msix-single-vector, msi, intx)");
714
715/**
716 * ioat_dma_setup_interrupts - setup interrupt handler
717 * @device: ioat device
718 */
719static int ioat_dma_setup_interrupts(struct ioatdma_device *device)
650{ 720{
651 int err; 721 struct ioat_dma_chan *ioat_chan;
652 unsigned long mmio_start, mmio_len; 722 int err, i, j, msixcnt;
653 void __iomem *reg_base; 723 u8 intrctrl = 0;
654 struct ioat_device *device; 724
725 if (!strcmp(ioat_interrupt_style, "msix"))
726 goto msix;
727 if (!strcmp(ioat_interrupt_style, "msix-single-vector"))
728 goto msix_single_vector;
729 if (!strcmp(ioat_interrupt_style, "msi"))
730 goto msi;
731 if (!strcmp(ioat_interrupt_style, "intx"))
732 goto intx;
733
734msix:
735 /* The number of MSI-X vectors should equal the number of channels */
736 msixcnt = device->common.chancnt;
737 for (i = 0; i < msixcnt; i++)
738 device->msix_entries[i].entry = i;
739
740 err = pci_enable_msix(device->pdev, device->msix_entries, msixcnt);
741 if (err < 0)
742 goto msi;
743 if (err > 0)
744 goto msix_single_vector;
745
746 for (i = 0; i < msixcnt; i++) {
747 ioat_chan = ioat_lookup_chan_by_index(device, i);
748 err = request_irq(device->msix_entries[i].vector,
749 ioat_dma_do_interrupt_msix,
750 0, "ioat-msix", ioat_chan);
751 if (err) {
752 for (j = 0; j < i; j++) {
753 ioat_chan =
754 ioat_lookup_chan_by_index(device, j);
755 free_irq(device->msix_entries[j].vector,
756 ioat_chan);
757 }
758 goto msix_single_vector;
759 }
760 }
761 intrctrl |= IOAT_INTRCTRL_MSIX_VECTOR_CONTROL;
762 device->irq_mode = msix_multi_vector;
763 goto done;
655 764
656 err = pci_enable_device(pdev); 765msix_single_vector:
766 device->msix_entries[0].entry = 0;
767 err = pci_enable_msix(device->pdev, device->msix_entries, 1);
657 if (err) 768 if (err)
658 goto err_enable_device; 769 goto msi;
659 770
660 err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); 771 err = request_irq(device->msix_entries[0].vector, ioat_dma_do_interrupt,
661 if (err) 772 0, "ioat-msix", device);
662 err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); 773 if (err) {
774 pci_disable_msix(device->pdev);
775 goto msi;
776 }
777 device->irq_mode = msix_single_vector;
778 goto done;
779
780msi:
781 err = pci_enable_msi(device->pdev);
663 if (err) 782 if (err)
664 goto err_set_dma_mask; 783 goto intx;
665 784
666 err = pci_request_regions(pdev, ioat_pci_driver.name); 785 err = request_irq(device->pdev->irq, ioat_dma_do_interrupt,
786 0, "ioat-msi", device);
787 if (err) {
788 pci_disable_msi(device->pdev);
789 goto intx;
790 }
791 /*
792 * CB 1.2 devices need a bit set in configuration space to enable MSI
793 */
794 if (device->version == IOAT_VER_1_2) {
795 u32 dmactrl;
796 pci_read_config_dword(device->pdev,
797 IOAT_PCI_DMACTRL_OFFSET, &dmactrl);
798 dmactrl |= IOAT_PCI_DMACTRL_MSI_EN;
799 pci_write_config_dword(device->pdev,
800 IOAT_PCI_DMACTRL_OFFSET, dmactrl);
801 }
802 device->irq_mode = msi;
803 goto done;
804
805intx:
806 err = request_irq(device->pdev->irq, ioat_dma_do_interrupt,
807 IRQF_SHARED, "ioat-intx", device);
667 if (err) 808 if (err)
668 goto err_request_regions; 809 goto err_no_irq;
810 device->irq_mode = intx;
669 811
670 mmio_start = pci_resource_start(pdev, 0); 812done:
671 mmio_len = pci_resource_len(pdev, 0); 813 intrctrl |= IOAT_INTRCTRL_MASTER_INT_EN;
814 writeb(intrctrl, device->reg_base + IOAT_INTRCTRL_OFFSET);
815 return 0;
672 816
673 reg_base = ioremap(mmio_start, mmio_len); 817err_no_irq:
674 if (!reg_base) { 818 /* Disable all interrupt generation */
675 err = -ENOMEM; 819 writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET);
676 goto err_ioremap; 820 dev_err(&device->pdev->dev, "no usable interrupts\n");
821 device->irq_mode = none;
822 return -1;
823}
824
825/**
826 * ioat_dma_remove_interrupts - remove whatever interrupts were set
827 * @device: ioat device
828 */
829static void ioat_dma_remove_interrupts(struct ioatdma_device *device)
830{
831 struct ioat_dma_chan *ioat_chan;
832 int i;
833
834 /* Disable all interrupt generation */
835 writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET);
836
837 switch (device->irq_mode) {
838 case msix_multi_vector:
839 for (i = 0; i < device->common.chancnt; i++) {
840 ioat_chan = ioat_lookup_chan_by_index(device, i);
841 free_irq(device->msix_entries[i].vector, ioat_chan);
842 }
843 pci_disable_msix(device->pdev);
844 break;
845 case msix_single_vector:
846 free_irq(device->msix_entries[0].vector, device);
847 pci_disable_msix(device->pdev);
848 break;
849 case msi:
850 free_irq(device->pdev->irq, device);
851 pci_disable_msi(device->pdev);
852 break;
853 case intx:
854 free_irq(device->pdev->irq, device);
855 break;
856 case none:
857 dev_warn(&device->pdev->dev,
858 "call to %s without interrupts setup\n", __func__);
677 } 859 }
860 device->irq_mode = none;
861}
862
863struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
864 void __iomem *iobase)
865{
866 int err;
867 struct ioatdma_device *device;
678 868
679 device = kzalloc(sizeof(*device), GFP_KERNEL); 869 device = kzalloc(sizeof(*device), GFP_KERNEL);
680 if (!device) { 870 if (!device) {
681 err = -ENOMEM; 871 err = -ENOMEM;
682 goto err_kzalloc; 872 goto err_kzalloc;
683 } 873 }
874 device->pdev = pdev;
875 device->reg_base = iobase;
876 device->version = readb(device->reg_base + IOAT_VER_OFFSET);
684 877
685 /* DMA coherent memory pool for DMA descriptor allocations */ 878 /* DMA coherent memory pool for DMA descriptor allocations */
686 device->dma_pool = pci_pool_create("dma_desc_pool", pdev, 879 device->dma_pool = pci_pool_create("dma_desc_pool", pdev,
687 sizeof(struct ioat_dma_descriptor), 64, 0); 880 sizeof(struct ioat_dma_descriptor),
881 64, 0);
688 if (!device->dma_pool) { 882 if (!device->dma_pool) {
689 err = -ENOMEM; 883 err = -ENOMEM;
690 goto err_dma_pool; 884 goto err_dma_pool;
691 } 885 }
692 886
693 device->completion_pool = pci_pool_create("completion_pool", pdev, sizeof(u64), SMP_CACHE_BYTES, SMP_CACHE_BYTES); 887 device->completion_pool = pci_pool_create("completion_pool", pdev,
888 sizeof(u64), SMP_CACHE_BYTES,
889 SMP_CACHE_BYTES);
694 if (!device->completion_pool) { 890 if (!device->completion_pool) {
695 err = -ENOMEM; 891 err = -ENOMEM;
696 goto err_completion_pool; 892 goto err_completion_pool;
697 } 893 }
698 894
699 device->pdev = pdev;
700 pci_set_drvdata(pdev, device);
701#ifdef CONFIG_PCI_MSI
702 if (pci_enable_msi(pdev) == 0) {
703 device->msi = 1;
704 } else {
705 device->msi = 0;
706 }
707#endif
708 err = request_irq(pdev->irq, &ioat_do_interrupt, IRQF_SHARED, "ioat",
709 device);
710 if (err)
711 goto err_irq;
712
713 device->reg_base = reg_base;
714
715 writeb(IOAT_INTRCTRL_MASTER_INT_EN, device->reg_base + IOAT_INTRCTRL_OFFSET);
716 pci_set_master(pdev);
717
718 INIT_LIST_HEAD(&device->common.channels); 895 INIT_LIST_HEAD(&device->common.channels);
719 enumerate_dma_channels(device); 896 ioat_dma_enumerate_channels(device);
720 897
721 dma_cap_set(DMA_MEMCPY, device->common.cap_mask); 898 dma_cap_set(DMA_MEMCPY, device->common.cap_mask);
722 device->common.device_alloc_chan_resources = ioat_dma_alloc_chan_resources; 899 device->common.device_alloc_chan_resources =
723 device->common.device_free_chan_resources = ioat_dma_free_chan_resources; 900 ioat_dma_alloc_chan_resources;
901 device->common.device_free_chan_resources =
902 ioat_dma_free_chan_resources;
724 device->common.device_prep_dma_memcpy = ioat_dma_prep_memcpy; 903 device->common.device_prep_dma_memcpy = ioat_dma_prep_memcpy;
725 device->common.device_is_tx_complete = ioat_dma_is_complete; 904 device->common.device_is_tx_complete = ioat_dma_is_complete;
726 device->common.device_issue_pending = ioat_dma_memcpy_issue_pending; 905 device->common.device_issue_pending = ioat_dma_memcpy_issue_pending;
727 device->common.device_dependency_added = ioat_dma_dependency_added; 906 device->common.device_dependency_added = ioat_dma_dependency_added;
728 device->common.dev = &pdev->dev; 907 device->common.dev = &pdev->dev;
729 printk(KERN_INFO "Intel(R) I/OAT DMA Engine found, %d channels\n", 908 dev_err(&device->pdev->dev,
730 device->common.chancnt); 909 "ioatdma: Intel(R) I/OAT DMA Engine found,"
910 " %d channels, device version 0x%02x\n",
911 device->common.chancnt, device->version);
731 912
732 err = ioat_self_test(device); 913 err = ioat_dma_setup_interrupts(device);
914 if (err)
915 goto err_setup_interrupts;
916
917 err = ioat_dma_self_test(device);
733 if (err) 918 if (err)
734 goto err_self_test; 919 goto err_self_test;
735 920
736 dma_async_device_register(&device->common); 921 dma_async_device_register(&device->common);
737 922
738 return 0; 923 return device;
739 924
740err_self_test: 925err_self_test:
741err_irq: 926 ioat_dma_remove_interrupts(device);
927err_setup_interrupts:
742 pci_pool_destroy(device->completion_pool); 928 pci_pool_destroy(device->completion_pool);
743err_completion_pool: 929err_completion_pool:
744 pci_pool_destroy(device->dma_pool); 930 pci_pool_destroy(device->dma_pool);
745err_dma_pool: 931err_dma_pool:
746 kfree(device); 932 kfree(device);
747err_kzalloc: 933err_kzalloc:
748 iounmap(reg_base); 934 iounmap(iobase);
749err_ioremap: 935 dev_err(&device->pdev->dev,
750 pci_release_regions(pdev); 936 "ioatdma: Intel(R) I/OAT DMA Engine initialization failed\n");
751err_request_regions: 937 return NULL;
752err_set_dma_mask:
753 pci_disable_device(pdev);
754err_enable_device:
755
756 printk(KERN_ERR "Intel(R) I/OAT DMA Engine initialization failed\n");
757
758 return err;
759} 938}
760 939
761static void ioat_shutdown(struct pci_dev *pdev) 940void ioat_dma_remove(struct ioatdma_device *device)
762{ 941{
763 struct ioat_device *device;
764 device = pci_get_drvdata(pdev);
765
766 dma_async_device_unregister(&device->common);
767}
768
769static void __devexit ioat_remove(struct pci_dev *pdev)
770{
771 struct ioat_device *device;
772 struct dma_chan *chan, *_chan; 942 struct dma_chan *chan, *_chan;
773 struct ioat_dma_chan *ioat_chan; 943 struct ioat_dma_chan *ioat_chan;
774 944
775 device = pci_get_drvdata(pdev);
776 dma_async_device_unregister(&device->common); 945 dma_async_device_unregister(&device->common);
777 946
778 free_irq(device->pdev->irq, device); 947 ioat_dma_remove_interrupts(device);
779#ifdef CONFIG_PCI_MSI 948
780 if (device->msi)
781 pci_disable_msi(device->pdev);
782#endif
783 pci_pool_destroy(device->dma_pool); 949 pci_pool_destroy(device->dma_pool);
784 pci_pool_destroy(device->completion_pool); 950 pci_pool_destroy(device->completion_pool);
785 iounmap(device->reg_base); 951
786 pci_release_regions(pdev); 952 list_for_each_entry_safe(chan, _chan,
787 pci_disable_device(pdev); 953 &device->common.channels, device_node) {
788 list_for_each_entry_safe(chan, _chan, &device->common.channels, device_node) {
789 ioat_chan = to_ioat_chan(chan); 954 ioat_chan = to_ioat_chan(chan);
790 list_del(&chan->device_node); 955 list_del(&chan->device_node);
791 kfree(ioat_chan); 956 kfree(ioat_chan);
@@ -793,25 +958,3 @@ static void __devexit ioat_remove(struct pci_dev *pdev)
793 kfree(device); 958 kfree(device);
794} 959}
795 960
796/* MODULE API */
797MODULE_VERSION("1.9");
798MODULE_LICENSE("GPL");
799MODULE_AUTHOR("Intel Corporation");
800
801static int __init ioat_init_module(void)
802{
803 /* it's currently unsafe to unload this module */
804 /* if forced, worst case is that rmmod hangs */
805 __unsafe(THIS_MODULE);
806
807 return pci_register_driver(&ioat_pci_driver);
808}
809
810module_init(ioat_init_module);
811
812static void __exit ioat_exit_module(void)
813{
814 pci_unregister_driver(&ioat_pci_driver);
815}
816
817module_exit(ioat_exit_module);
diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h
index bf4dad70e0f5..2a319e124ece 100644
--- a/drivers/dma/ioatdma.h
+++ b/drivers/dma/ioatdma.h
@@ -28,25 +28,35 @@
28#include <linux/cache.h> 28#include <linux/cache.h>
29#include <linux/pci_ids.h> 29#include <linux/pci_ids.h>
30 30
31enum ioat_interrupt {
32 none = 0,
33 msix_multi_vector = 1,
34 msix_single_vector = 2,
35 msi = 3,
36 intx = 4,
37};
38
31#define IOAT_LOW_COMPLETION_MASK 0xffffffc0 39#define IOAT_LOW_COMPLETION_MASK 0xffffffc0
32 40
33/** 41/**
34 * struct ioat_device - internal representation of a IOAT device 42 * struct ioatdma_device - internal representation of a IOAT device
35 * @pdev: PCI-Express device 43 * @pdev: PCI-Express device
36 * @reg_base: MMIO register space base address 44 * @reg_base: MMIO register space base address
37 * @dma_pool: for allocating DMA descriptors 45 * @dma_pool: for allocating DMA descriptors
38 * @common: embedded struct dma_device 46 * @common: embedded struct dma_device
39 * @msi: Message Signaled Interrupt number 47 * @version: version of ioatdma device
40 */ 48 */
41 49
42struct ioat_device { 50struct ioatdma_device {
43 struct pci_dev *pdev; 51 struct pci_dev *pdev;
44 void __iomem *reg_base; 52 void __iomem *reg_base;
45 struct pci_pool *dma_pool; 53 struct pci_pool *dma_pool;
46 struct pci_pool *completion_pool; 54 struct pci_pool *completion_pool;
47
48 struct dma_device common; 55 struct dma_device common;
49 u8 msi; 56 u8 version;
57 enum ioat_interrupt irq_mode;
58 struct msix_entry msix_entries[4];
59 struct ioat_dma_chan *idx[4];
50}; 60};
51 61
52/** 62/**
@@ -84,7 +94,7 @@ struct ioat_dma_chan {
84 94
85 int pending; 95 int pending;
86 96
87 struct ioat_device *device; 97 struct ioatdma_device *device;
88 struct dma_chan common; 98 struct dma_chan common;
89 99
90 dma_addr_t completion_addr; 100 dma_addr_t completion_addr;
@@ -95,6 +105,7 @@ struct ioat_dma_chan {
95 u32 high; 105 u32 high;
96 }; 106 };
97 } *completion_virt; 107 } *completion_virt;
108 struct tasklet_struct cleanup_task;
98}; 109};
99 110
100/* wrapper around hardware descriptor format + additional software fields */ 111/* wrapper around hardware descriptor format + additional software fields */
@@ -117,4 +128,16 @@ struct ioat_desc_sw {
117 struct dma_async_tx_descriptor async_tx; 128 struct dma_async_tx_descriptor async_tx;
118}; 129};
119 130
131#if defined(CONFIG_INTEL_IOATDMA) || defined(CONFIG_INTEL_IOATDMA_MODULE)
132struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
133 void __iomem *iobase);
134void ioat_dma_remove(struct ioatdma_device *device);
135struct dca_provider *ioat_dca_init(struct pci_dev *pdev,
136 void __iomem *iobase);
137#else
138#define ioat_dma_probe(pdev, iobase) NULL
139#define ioat_dma_remove(device) do { } while (0)
140#define ioat_dca_init(pdev, iobase) NULL
141#endif
142
120#endif /* IOATDMA_H */ 143#endif /* IOATDMA_H */
diff --git a/drivers/dma/ioatdma_hw.h b/drivers/dma/ioatdma_hw.h
index 4d7a12880be3..9e7434e1551f 100644
--- a/drivers/dma/ioatdma_hw.h
+++ b/drivers/dma/ioatdma_hw.h
@@ -27,7 +27,7 @@
27#define IOAT_PCI_RID 0x00 27#define IOAT_PCI_RID 0x00
28#define IOAT_PCI_SVID 0x8086 28#define IOAT_PCI_SVID 0x8086
29#define IOAT_PCI_SID 0x8086 29#define IOAT_PCI_SID 0x8086
30#define IOAT_VER 0x12 /* Version 1.2 */ 30#define IOAT_VER_1_2 0x12 /* Version 1.2 */
31 31
32struct ioat_dma_descriptor { 32struct ioat_dma_descriptor {
33 uint32_t size; 33 uint32_t size;
diff --git a/drivers/dma/ioatdma_registers.h b/drivers/dma/ioatdma_registers.h
index a30c7349075a..baaab5ea146a 100644
--- a/drivers/dma/ioatdma_registers.h
+++ b/drivers/dma/ioatdma_registers.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. 2 * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free 5 * under the terms of the GNU General Public License as published by the Free
@@ -21,6 +21,9 @@
21#ifndef _IOAT_REGISTERS_H_ 21#ifndef _IOAT_REGISTERS_H_
22#define _IOAT_REGISTERS_H_ 22#define _IOAT_REGISTERS_H_
23 23
24#define IOAT_PCI_DMACTRL_OFFSET 0x48
25#define IOAT_PCI_DMACTRL_DMA_EN 0x00000001
26#define IOAT_PCI_DMACTRL_MSI_EN 0x00000002
24 27
25/* MMIO Device Registers */ 28/* MMIO Device Registers */
26#define IOAT_CHANCNT_OFFSET 0x00 /* 8-bit */ 29#define IOAT_CHANCNT_OFFSET 0x00 /* 8-bit */
@@ -39,6 +42,7 @@
39#define IOAT_INTRCTRL_MASTER_INT_EN 0x01 /* Master Interrupt Enable */ 42#define IOAT_INTRCTRL_MASTER_INT_EN 0x01 /* Master Interrupt Enable */
40#define IOAT_INTRCTRL_INT_STATUS 0x02 /* ATTNSTATUS -or- Channel Int */ 43#define IOAT_INTRCTRL_INT_STATUS 0x02 /* ATTNSTATUS -or- Channel Int */
41#define IOAT_INTRCTRL_INT 0x04 /* INT_STATUS -and- MASTER_INT_EN */ 44#define IOAT_INTRCTRL_INT 0x04 /* INT_STATUS -and- MASTER_INT_EN */
45#define IOAT_INTRCTRL_MSIX_VECTOR_CONTROL 0x08 /* Enable all MSI-X vectors */
42 46
43#define IOAT_ATTNSTATUS_OFFSET 0x04 /* Each bit is a channel */ 47#define IOAT_ATTNSTATUS_OFFSET 0x04 /* Each bit is a channel */
44 48
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 23b6f7bc16b7..476012b6dfac 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -506,9 +506,14 @@ static void send_message(capidrv_contr * card, _cmsg * cmsg)
506{ 506{
507 struct sk_buff *skb; 507 struct sk_buff *skb;
508 size_t len; 508 size_t len;
509
509 capi_cmsg2message(cmsg, cmsg->buf); 510 capi_cmsg2message(cmsg, cmsg->buf);
510 len = CAPIMSG_LEN(cmsg->buf); 511 len = CAPIMSG_LEN(cmsg->buf);
511 skb = alloc_skb(len, GFP_ATOMIC); 512 skb = alloc_skb(len, GFP_ATOMIC);
513 if (!skb) {
514 printk(KERN_ERR "capidrv::send_message: can't allocate mem\n");
515 return;
516 }
512 memcpy(skb_put(skb, len), cmsg->buf, len); 517 memcpy(skb_put(skb, len), cmsg->buf, len);
513 if (capi20_put_message(&global.ap, skb) != CAPI_NOERROR) 518 if (capi20_put_message(&global.ap, skb) != CAPI_NOERROR)
514 kfree_skb(skb); 519 kfree_skb(skb);
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index 9f73bc2727c2..f55531869313 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -821,6 +821,8 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
821 return -EFAULT; 821 return -EFAULT;
822 } 822 }
823 card = get_capi_ctr_by_nr(ldef.contr); 823 card = get_capi_ctr_by_nr(ldef.contr);
824 if (!card)
825 return -EINVAL;
824 card = capi_ctr_get(card); 826 card = capi_ctr_get(card);
825 if (!card) 827 if (!card)
826 return -ESRCH; 828 return -ESRCH;
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 00e31609a238..af7648274b38 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -1936,14 +1936,7 @@ static int gigaset_write_room(struct cardstate *cs)
1936 */ 1936 */
1937static int gigaset_chars_in_buffer(struct cardstate *cs) 1937static int gigaset_chars_in_buffer(struct cardstate *cs)
1938{ 1938{
1939 unsigned long flags; 1939 return cs->cmdbytes;
1940 unsigned bytes;
1941
1942 spin_lock_irqsave(&cs->cmdlock, flags);
1943 bytes = cs->cmdbytes;
1944 spin_unlock_irqrestore(&cs->cmdlock, flags);
1945
1946 return bytes;
1947} 1940}
1948 1941
1949/* gigaset_brkchars 1942/* gigaset_brkchars
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 1654fa413575..9e089f06a942 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -109,13 +109,9 @@ EXPORT_SYMBOL_GPL(gigaset_skb_sent);
109static int command_from_LL(isdn_ctrl *cntrl) 109static int command_from_LL(isdn_ctrl *cntrl)
110{ 110{
111 struct cardstate *cs = gigaset_get_cs_by_id(cntrl->driver); 111 struct cardstate *cs = gigaset_get_cs_by_id(cntrl->driver);
112 //isdn_ctrl response;
113 //unsigned long flags;
114 struct bc_state *bcs; 112 struct bc_state *bcs;
115 int retval = 0; 113 int retval = 0;
116 struct setup_parm *sp; 114 struct setup_parm *sp;
117 unsigned param;
118 unsigned long flags;
119 115
120 gigaset_debugdrivers(); 116 gigaset_debugdrivers();
121 117
@@ -162,12 +158,8 @@ static int command_from_LL(isdn_ctrl *cntrl)
162 } 158 }
163 *sp = cntrl->parm.setup; 159 *sp = cntrl->parm.setup;
164 160
165 spin_lock_irqsave(&cs->lock, flags); 161 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp,
166 param = bcs->at_state.seq_index; 162 bcs->at_state.seq_index, NULL)) {
167 spin_unlock_irqrestore(&cs->lock, flags);
168
169 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, param,
170 NULL)) {
171 //FIXME what should we do? 163 //FIXME what should we do?
172 kfree(sp); 164 kfree(sp);
173 gigaset_free_channel(bcs); 165 gigaset_free_channel(bcs);
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index e767afa55abf..da6f3acf9fd0 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -19,15 +19,9 @@
19static ssize_t show_cidmode(struct device *dev, 19static ssize_t show_cidmode(struct device *dev,
20 struct device_attribute *attr, char *buf) 20 struct device_attribute *attr, char *buf)
21{ 21{
22 int ret;
23 unsigned long flags;
24 struct cardstate *cs = dev_get_drvdata(dev); 22 struct cardstate *cs = dev_get_drvdata(dev);
25 23
26 spin_lock_irqsave(&cs->lock, flags); 24 return sprintf(buf, "%u\n", cs->cidmode);
27 ret = sprintf(buf, "%u\n", cs->cidmode);
28 spin_unlock_irqrestore(&cs->lock, flags);
29
30 return ret;
31} 25}
32 26
33static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, 27static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index a1263019df5e..ca4bee173cfb 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -310,7 +310,6 @@ static void gigaset_modem_fill(unsigned long data)
310 struct cardstate *cs = (struct cardstate *) data; 310 struct cardstate *cs = (struct cardstate *) data;
311 struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ 311 struct bc_state *bcs = &cs->bcs[0]; /* only one channel */
312 struct cmdbuf_t *cb; 312 struct cmdbuf_t *cb;
313 unsigned long flags;
314 int again; 313 int again;
315 314
316 gig_dbg(DEBUG_OUTPUT, "modem_fill"); 315 gig_dbg(DEBUG_OUTPUT, "modem_fill");
@@ -323,9 +322,7 @@ static void gigaset_modem_fill(unsigned long data)
323 do { 322 do {
324 again = 0; 323 again = 0;
325 if (!bcs->tx_skb) { /* no skb is being sent */ 324 if (!bcs->tx_skb) { /* no skb is being sent */
326 spin_lock_irqsave(&cs->cmdlock, flags);
327 cb = cs->cmdbuf; 325 cb = cs->cmdbuf;
328 spin_unlock_irqrestore(&cs->cmdlock, flags);
329 if (cb) { /* commands to send? */ 326 if (cb) { /* commands to send? */
330 gig_dbg(DEBUG_OUTPUT, "modem_fill: cb"); 327 gig_dbg(DEBUG_OUTPUT, "modem_fill: cb");
331 if (send_cb(cs, cb) < 0) { 328 if (send_cb(cs, cb) < 0) {
@@ -546,13 +543,9 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
546 543
547static int gigaset_write_room(struct cardstate *cs) 544static int gigaset_write_room(struct cardstate *cs)
548{ 545{
549 unsigned long flags;
550 unsigned bytes; 546 unsigned bytes;
551 547
552 spin_lock_irqsave(&cs->cmdlock, flags);
553 bytes = cs->cmdbytes; 548 bytes = cs->cmdbytes;
554 spin_unlock_irqrestore(&cs->cmdlock, flags);
555
556 return bytes < IF_WRITEBUF ? IF_WRITEBUF - bytes : 0; 549 return bytes < IF_WRITEBUF ? IF_WRITEBUF - bytes : 0;
557} 550}
558 551
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 4910bca52640..c6df2925ebd0 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1365,7 +1365,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1365 } else { 1365 } else {
1366 s = NULL; 1366 s = NULL;
1367 } 1367 }
1368 ret = down_interruptible(&dev->sem); 1368 ret = mutex_lock_interruptible(&dev->mtx);
1369 if( ret ) return ret; 1369 if( ret ) return ret;
1370 if ((s = isdn_net_new(s, NULL))) { 1370 if ((s = isdn_net_new(s, NULL))) {
1371 if (copy_to_user(argp, s, strlen(s) + 1)){ 1371 if (copy_to_user(argp, s, strlen(s) + 1)){
@@ -1375,7 +1375,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1375 } 1375 }
1376 } else 1376 } else
1377 ret = -ENODEV; 1377 ret = -ENODEV;
1378 up(&dev->sem); 1378 mutex_unlock(&dev->mtx);
1379 return ret; 1379 return ret;
1380 case IIOCNETASL: 1380 case IIOCNETASL:
1381 /* Add a slave to a network-interface */ 1381 /* Add a slave to a network-interface */
@@ -1384,7 +1384,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1384 return -EFAULT; 1384 return -EFAULT;
1385 } else 1385 } else
1386 return -EINVAL; 1386 return -EINVAL;
1387 ret = down_interruptible(&dev->sem); 1387 ret = mutex_lock_interruptible(&dev->mtx);
1388 if( ret ) return ret; 1388 if( ret ) return ret;
1389 if ((s = isdn_net_newslave(bname))) { 1389 if ((s = isdn_net_newslave(bname))) {
1390 if (copy_to_user(argp, s, strlen(s) + 1)){ 1390 if (copy_to_user(argp, s, strlen(s) + 1)){
@@ -1394,17 +1394,17 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1394 } 1394 }
1395 } else 1395 } else
1396 ret = -ENODEV; 1396 ret = -ENODEV;
1397 up(&dev->sem); 1397 mutex_unlock(&dev->mtx);
1398 return ret; 1398 return ret;
1399 case IIOCNETDIF: 1399 case IIOCNETDIF:
1400 /* Delete a network-interface */ 1400 /* Delete a network-interface */
1401 if (arg) { 1401 if (arg) {
1402 if (copy_from_user(name, argp, sizeof(name))) 1402 if (copy_from_user(name, argp, sizeof(name)))
1403 return -EFAULT; 1403 return -EFAULT;
1404 ret = down_interruptible(&dev->sem); 1404 ret = mutex_lock_interruptible(&dev->mtx);
1405 if( ret ) return ret; 1405 if( ret ) return ret;
1406 ret = isdn_net_rm(name); 1406 ret = isdn_net_rm(name);
1407 up(&dev->sem); 1407 mutex_unlock(&dev->mtx);
1408 return ret; 1408 return ret;
1409 } else 1409 } else
1410 return -EINVAL; 1410 return -EINVAL;
@@ -1433,10 +1433,10 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1433 if (arg) { 1433 if (arg) {
1434 if (copy_from_user(&phone, argp, sizeof(phone))) 1434 if (copy_from_user(&phone, argp, sizeof(phone)))
1435 return -EFAULT; 1435 return -EFAULT;
1436 ret = down_interruptible(&dev->sem); 1436 ret = mutex_lock_interruptible(&dev->mtx);
1437 if( ret ) return ret; 1437 if( ret ) return ret;
1438 ret = isdn_net_addphone(&phone); 1438 ret = isdn_net_addphone(&phone);
1439 up(&dev->sem); 1439 mutex_unlock(&dev->mtx);
1440 return ret; 1440 return ret;
1441 } else 1441 } else
1442 return -EINVAL; 1442 return -EINVAL;
@@ -1445,10 +1445,10 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1445 if (arg) { 1445 if (arg) {
1446 if (copy_from_user(&phone, argp, sizeof(phone))) 1446 if (copy_from_user(&phone, argp, sizeof(phone)))
1447 return -EFAULT; 1447 return -EFAULT;
1448 ret = down_interruptible(&dev->sem); 1448 ret = mutex_lock_interruptible(&dev->mtx);
1449 if( ret ) return ret; 1449 if( ret ) return ret;
1450 ret = isdn_net_getphones(&phone, argp); 1450 ret = isdn_net_getphones(&phone, argp);
1451 up(&dev->sem); 1451 mutex_unlock(&dev->mtx);
1452 return ret; 1452 return ret;
1453 } else 1453 } else
1454 return -EINVAL; 1454 return -EINVAL;
@@ -1457,10 +1457,10 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1457 if (arg) { 1457 if (arg) {
1458 if (copy_from_user(&phone, argp, sizeof(phone))) 1458 if (copy_from_user(&phone, argp, sizeof(phone)))
1459 return -EFAULT; 1459 return -EFAULT;
1460 ret = down_interruptible(&dev->sem); 1460 ret = mutex_lock_interruptible(&dev->mtx);
1461 if( ret ) return ret; 1461 if( ret ) return ret;
1462 ret = isdn_net_delphone(&phone); 1462 ret = isdn_net_delphone(&phone);
1463 up(&dev->sem); 1463 mutex_unlock(&dev->mtx);
1464 return ret; 1464 return ret;
1465 } else 1465 } else
1466 return -EINVAL; 1466 return -EINVAL;
@@ -2304,7 +2304,7 @@ static int __init isdn_init(void)
2304#ifdef MODULE 2304#ifdef MODULE
2305 dev->owner = THIS_MODULE; 2305 dev->owner = THIS_MODULE;
2306#endif 2306#endif
2307 init_MUTEX(&dev->sem); 2307 mutex_init(&dev->mtx);
2308 init_waitqueue_head(&dev->info_waitq); 2308 init_waitqueue_head(&dev->info_waitq);
2309 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 2309 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
2310 dev->drvmap[i] = -1; 2310 dev->drvmap[i] = -1;
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 3918ebf01e8d..626bb3c9af2b 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -2605,14 +2605,10 @@ mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2605} 2605}
2606 2606
2607/** 2607/**
2608 * SCPNT_TO_LOOKUP_IDX 2608 * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2609 *
2610 * search's for a given scmd in the ScsiLookup[] array list
2611 *
2612 * @ioc: Pointer to MPT_ADAPTER structure 2609 * @ioc: Pointer to MPT_ADAPTER structure
2613 * @scmd: scsi_cmnd pointer 2610 * @sc: scsi_cmnd pointer
2614 * 2611 */
2615 **/
2616static int 2612static int
2617SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc) 2613SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2618{ 2614{
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 254b194e7625..71b986b38c55 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1280,8 +1280,8 @@ static int mmc_spi_probe(struct spi_device *spi)
1280 if (!host->data) 1280 if (!host->data)
1281 goto fail_nobuf1; 1281 goto fail_nobuf1;
1282 1282
1283 if (spi->master->cdev.dev->dma_mask) { 1283 if (spi->master->dev.parent->dma_mask) {
1284 struct device *dev = spi->master->cdev.dev; 1284 struct device *dev = spi->master->dev.parent;
1285 1285
1286 host->dma_dev = dev; 1286 host->dma_dev = dev;
1287 host->ones_dma = dma_map_single(dev, ones, 1287 host->ones_dma = dma_map_single(dev, ones,
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index c0c77f82d051..f201bd673137 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -2,9 +2,7 @@
2# PCCARD (PCMCIA/CardBus) bus subsystem configuration 2# PCCARD (PCMCIA/CardBus) bus subsystem configuration
3# 3#
4 4
5menu "PCCARD (PCMCIA/CardBus) support" 5menuconfig PCCARD
6
7config PCCARD
8 tristate "PCCard (PCMCIA/CardBus) support" 6 tristate "PCCard (PCMCIA/CardBus) support"
9 depends on HOTPLUG 7 depends on HOTPLUG
10 ---help--- 8 ---help---
@@ -278,5 +276,3 @@ config PCCARD_IODYN
278 bool 276 bool
279 277
280endif # PCCARD 278endif # PCCARD
281
282endmenu
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index 01874b0bb03b..ce9d5c44a7b5 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -50,7 +50,10 @@
50 50
51#include <asm/au1000.h> 51#include <asm/au1000.h>
52#include <asm/au1000_pcmcia.h> 52#include <asm/au1000_pcmcia.h>
53#include <asm/xxs1500.h> 53
54#define PCMCIA_MAX_SOCK 0
55#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
56#define PCMCIA_IRQ AU1000_GPIO_4
54 57
55#if 0 58#if 0
56#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args) 59#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args)
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index d154dee76e7f..06a85d7d5aa2 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -25,6 +25,7 @@
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/byteorder.h> 27#include <asm/byteorder.h>
28#include <asm/unaligned.h>
28 29
29#include <pcmcia/cs_types.h> 30#include <pcmcia/cs_types.h>
30#include <pcmcia/ss.h> 31#include <pcmcia/ss.h>
@@ -401,6 +402,15 @@ EXPORT_SYMBOL(pcmcia_replace_cis);
401 402
402======================================================================*/ 403======================================================================*/
403 404
405static inline u16 cis_get_u16(void *ptr)
406{
407 return le16_to_cpu(get_unaligned((__le16 *) ptr));
408}
409static inline u32 cis_get_u32(void *ptr)
410{
411 return le32_to_cpu(get_unaligned((__le32 *) ptr));
412}
413
404typedef struct tuple_flags { 414typedef struct tuple_flags {
405 u_int link_space:4; 415 u_int link_space:4;
406 u_int has_link:1; 416 u_int has_link:1;
@@ -461,7 +471,7 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
461 /* Get indirect link from the MFC tuple */ 471 /* Get indirect link from the MFC tuple */
462 read_cis_cache(s, LINK_SPACE(tuple->Flags), 472 read_cis_cache(s, LINK_SPACE(tuple->Flags),
463 tuple->LinkOffset, 5, link); 473 tuple->LinkOffset, 5, link);
464 ofs = le32_to_cpu(*(__le32 *)(link+1)); 474 ofs = cis_get_u32(link + 1);
465 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); 475 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
466 /* Move to the next indirect link */ 476 /* Move to the next indirect link */
467 tuple->LinkOffset += 5; 477 tuple->LinkOffset += 5;
@@ -668,10 +678,10 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
668 u_char *p; 678 u_char *p;
669 if (tuple->TupleDataLen < 5) 679 if (tuple->TupleDataLen < 5)
670 return CS_BAD_TUPLE; 680 return CS_BAD_TUPLE;
671 p = (u_char *)tuple->TupleData; 681 p = (u_char *) tuple->TupleData;
672 csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(__le16 *)p)-2; 682 csum->addr = tuple->CISOffset + cis_get_u16(p) - 2;
673 csum->len = le16_to_cpu(*(__le16 *)(p + 2)); 683 csum->len = cis_get_u16(p + 2);
674 csum->sum = *(p+4); 684 csum->sum = *(p + 4);
675 return CS_SUCCESS; 685 return CS_SUCCESS;
676} 686}
677 687
@@ -681,7 +691,7 @@ static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
681{ 691{
682 if (tuple->TupleDataLen < 4) 692 if (tuple->TupleDataLen < 4)
683 return CS_BAD_TUPLE; 693 return CS_BAD_TUPLE;
684 link->addr = le32_to_cpu(*(__le32 *)tuple->TupleData); 694 link->addr = cis_get_u32(tuple->TupleData);
685 return CS_SUCCESS; 695 return CS_SUCCESS;
686} 696}
687 697
@@ -700,7 +710,8 @@ static int parse_longlink_mfc(tuple_t *tuple,
700 return CS_BAD_TUPLE; 710 return CS_BAD_TUPLE;
701 for (i = 0; i < link->nfn; i++) { 711 for (i = 0; i < link->nfn; i++) {
702 link->fn[i].space = *p; p++; 712 link->fn[i].space = *p; p++;
703 link->fn[i].addr = le32_to_cpu(*(__le32 *)p); p += 4; 713 link->fn[i].addr = cis_get_u32(p);
714 p += 4;
704 } 715 }
705 return CS_SUCCESS; 716 return CS_SUCCESS;
706} 717}
@@ -787,12 +798,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
787 798
788static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) 799static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
789{ 800{
790 __le16 *p;
791 if (tuple->TupleDataLen < 4) 801 if (tuple->TupleDataLen < 4)
792 return CS_BAD_TUPLE; 802 return CS_BAD_TUPLE;
793 p = (__le16 *)tuple->TupleData; 803 m->manf = cis_get_u16(tuple->TupleData);
794 m->manf = le16_to_cpu(p[0]); 804 m->card = cis_get_u16(tuple->TupleData + 2);
795 m->card = le16_to_cpu(p[1]);
796 return CS_SUCCESS; 805 return CS_SUCCESS;
797} 806}
798 807
@@ -1091,7 +1100,7 @@ static int parse_cftable_entry(tuple_t *tuple,
1091 break; 1100 break;
1092 case 0x20: 1101 case 0x20:
1093 entry->mem.nwin = 1; 1102 entry->mem.nwin = 1;
1094 entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8; 1103 entry->mem.win[0].len = cis_get_u16(p) << 8;
1095 entry->mem.win[0].card_addr = 0; 1104 entry->mem.win[0].card_addr = 0;
1096 entry->mem.win[0].host_addr = 0; 1105 entry->mem.win[0].host_addr = 0;
1097 p += 2; 1106 p += 2;
@@ -1099,9 +1108,8 @@ static int parse_cftable_entry(tuple_t *tuple,
1099 break; 1108 break;
1100 case 0x40: 1109 case 0x40:
1101 entry->mem.nwin = 1; 1110 entry->mem.nwin = 1;
1102 entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8; 1111 entry->mem.win[0].len = cis_get_u16(p) << 8;
1103 entry->mem.win[0].card_addr = 1112 entry->mem.win[0].card_addr = cis_get_u16(p + 2) << 8;
1104 le16_to_cpu(*(__le16 *)(p+2)) << 8;
1105 entry->mem.win[0].host_addr = 0; 1113 entry->mem.win[0].host_addr = 0;
1106 p += 4; 1114 p += 4;
1107 if (p > q) return CS_BAD_TUPLE; 1115 if (p > q) return CS_BAD_TUPLE;
@@ -1138,7 +1146,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
1138 p = (u_char *)tuple->TupleData; 1146 p = (u_char *)tuple->TupleData;
1139 bar->attr = *p; 1147 bar->attr = *p;
1140 p += 2; 1148 p += 2;
1141 bar->size = le32_to_cpu(*(__le32 *)p); 1149 bar->size = cis_get_u32(p);
1142 return CS_SUCCESS; 1150 return CS_SUCCESS;
1143} 1151}
1144 1152
@@ -1151,7 +1159,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
1151 return CS_BAD_TUPLE; 1159 return CS_BAD_TUPLE;
1152 config->last_idx = *(++p); 1160 config->last_idx = *(++p);
1153 p++; 1161 p++;
1154 config->base = le32_to_cpu(*(__le32 *)p); 1162 config->base = cis_get_u32(p);
1155 config->subtuples = tuple->TupleDataLen - 6; 1163 config->subtuples = tuple->TupleDataLen - 6;
1156 return CS_SUCCESS; 1164 return CS_SUCCESS;
1157} 1165}
@@ -1267,7 +1275,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
1267 1275
1268 v2->vers = p[0]; 1276 v2->vers = p[0];
1269 v2->comply = p[1]; 1277 v2->comply = p[1];
1270 v2->dindex = le16_to_cpu(*(__le16 *)(p+2)); 1278 v2->dindex = cis_get_u16(p +2 );
1271 v2->vspec8 = p[6]; 1279 v2->vspec8 = p[6];
1272 v2->vspec9 = p[7]; 1280 v2->vspec9 = p[7];
1273 v2->nhdr = p[8]; 1281 v2->nhdr = p[8];
@@ -1308,8 +1316,8 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
1308 1316
1309 fmt->type = p[0]; 1317 fmt->type = p[0];
1310 fmt->edc = p[1]; 1318 fmt->edc = p[1];
1311 fmt->offset = le32_to_cpu(*(__le32 *)(p+2)); 1319 fmt->offset = cis_get_u32(p + 2);
1312 fmt->length = le32_to_cpu(*(__le32 *)(p+6)); 1320 fmt->length = cis_get_u32(p + 6);
1313 1321
1314 return CS_SUCCESS; 1322 return CS_SUCCESS;
1315} 1323}
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 55baa1f0fcbb..7bf78c127898 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -23,6 +23,7 @@
23#include <linux/crc32.h> 23#include <linux/crc32.h>
24#include <linux/firmware.h> 24#include <linux/firmware.h>
25#include <linux/kref.h> 25#include <linux/kref.h>
26#include <linux/dma-mapping.h>
26 27
27#define IN_CARD_SERVICES 28#define IN_CARD_SERVICES
28#include <pcmcia/cs_types.h> 29#include <pcmcia/cs_types.h>
@@ -670,6 +671,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
670 p_dev->dev.bus = &pcmcia_bus_type; 671 p_dev->dev.bus = &pcmcia_bus_type;
671 p_dev->dev.parent = s->dev.parent; 672 p_dev->dev.parent = s->dev.parent;
672 p_dev->dev.release = pcmcia_release_dev; 673 p_dev->dev.release = pcmcia_release_dev;
674 /* by default don't allow DMA */
675 p_dev->dma_mask = DMA_MASK_NONE;
676 p_dev->dev.dma_mask = &p_dev->dma_mask;
673 bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); 677 bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
674 678
675 p_dev->devname = kmalloc(6 + bus_id_len + 1, GFP_KERNEL); 679 p_dev->devname = kmalloc(6 + bus_id_len + 1, GFP_KERNEL);
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index dca9f8549b32..874923fcb2f9 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -58,7 +58,7 @@ static inline u_int pxa2xx_mcxx_asst(u_int pcmcia_cycle_ns,
58 u_int mem_clk_10khz) 58 u_int mem_clk_10khz)
59{ 59{
60 u_int code = pcmcia_cycle_ns * mem_clk_10khz; 60 u_int code = pcmcia_cycle_ns * mem_clk_10khz;
61 return (code / 300000) + ((code % 300000) ? 1 : 0) - 1; 61 return (code / 300000) + ((code % 300000) ? 1 : 0) + 1;
62} 62}
63 63
64static inline u_int pxa2xx_mcxx_setup(u_int pcmcia_cycle_ns, 64static inline u_int pxa2xx_mcxx_setup(u_int pcmcia_cycle_ns,
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 85e21614f868..397f4ce849dc 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -23,6 +23,7 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/notifier.h> 24#include <linux/notifier.h>
25#include <linux/ioctl.h> 25#include <linux/ioctl.h>
26#include <linux/fb.h>
26 27
27#include <asm/firmware.h> 28#include <asm/firmware.h>
28#include <asm/ps3av.h> 29#include <asm/ps3av.h>
@@ -33,6 +34,8 @@
33#define BUFSIZE 4096 /* vuart buf size */ 34#define BUFSIZE 4096 /* vuart buf size */
34#define PS3AV_BUF_SIZE 512 /* max packet size */ 35#define PS3AV_BUF_SIZE 512 /* max packet size */
35 36
37static int safe_mode;
38
36static int timeout = 5000; /* in msec ( 5 sec ) */ 39static int timeout = 5000; /* in msec ( 5 sec ) */
37module_param(timeout, int, 0644); 40module_param(timeout, int, 0644);
38 41
@@ -491,10 +494,10 @@ static int ps3av_set_videomode(void)
491 return 0; 494 return 0;
492} 495}
493 496
494static void ps3av_set_videomode_cont(u32 id, u32 old_id) 497static void ps3av_set_videomode_packet(u32 id)
495{ 498{
496 struct ps3av_pkt_avb_param avb_param; 499 struct ps3av_pkt_avb_param avb_param;
497 int i; 500 unsigned int i;
498 u32 len = 0, av_video_cs; 501 u32 len = 0, av_video_cs;
499 const struct avset_video_mode *video_mode; 502 const struct avset_video_mode *video_mode;
500 int res; 503 int res;
@@ -507,24 +510,6 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
507 ps3av->av_hw_conf.num_of_avmulti; 510 ps3av->av_hw_conf.num_of_avmulti;
508 avb_param.num_of_av_audio_pkt = 0; 511 avb_param.num_of_av_audio_pkt = 0;
509 512
510 /* video signal off */
511 ps3av_set_video_disable_sig();
512
513 /* Retail PS3 product doesn't support this */
514 if (id & PS3AV_MODE_HDCP_OFF) {
515 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
516 if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
517 dev_dbg(&ps3av->dev->core, "Not supported\n");
518 else if (res)
519 dev_dbg(&ps3av->dev->core,
520 "ps3av_cmd_av_hdmi_mode failed\n");
521 } else if (old_id & PS3AV_MODE_HDCP_OFF) {
522 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
523 if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
524 dev_dbg(&ps3av->dev->core,
525 "ps3av_cmd_av_hdmi_mode failed\n");
526 }
527
528 /* video_pkt */ 513 /* video_pkt */
529 for (i = 0; i < avb_param.num_of_video_pkt; i++) 514 for (i = 0; i < avb_param.num_of_video_pkt; i++)
530 len += ps3av_cmd_set_video_mode(&avb_param.buf[len], 515 len += ps3av_cmd_set_video_mode(&avb_param.buf[len],
@@ -555,6 +540,42 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
555 __func__); 540 __func__);
556 else if (res) 541 else if (res)
557 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n"); 542 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
543}
544
545static void ps3av_set_videomode_cont(u32 id, u32 old_id)
546{
547 static int vesa = 0;
548 int res;
549
550 /* video signal off */
551 ps3av_set_video_disable_sig();
552
553 /*
554 * AV backend needs non-VESA mode setting at least one time
555 * when VESA mode is used.
556 */
557 if (vesa == 0 && (id & PS3AV_MODE_MASK) >= 11) {
558 /* vesa mode */
559 ps3av_set_videomode_packet(2); /* 480P */
560 }
561 vesa = 1;
562
563 /* Retail PS3 product doesn't support this */
564 if (id & PS3AV_MODE_HDCP_OFF) {
565 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
566 if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
567 dev_dbg(&ps3av->dev->core, "Not supported\n");
568 else if (res)
569 dev_dbg(&ps3av->dev->core,
570 "ps3av_cmd_av_hdmi_mode failed\n");
571 } else if (old_id & PS3AV_MODE_HDCP_OFF) {
572 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
573 if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
574 dev_dbg(&ps3av->dev->core,
575 "ps3av_cmd_av_hdmi_mode failed\n");
576 }
577
578 ps3av_set_videomode_packet(id);
558 579
559 msleep(1500); 580 msleep(1500);
560 /* av video mute */ 581 /* av video mute */
@@ -567,165 +588,251 @@ static void ps3avd(struct work_struct *work)
567 complete(&ps3av->done); 588 complete(&ps3av->done);
568} 589}
569 590
570static int ps3av_vid2table_id(int vid) 591#define SHIFT_50 0
571{ 592#define SHIFT_60 4
572 int i; 593#define SHIFT_VESA 8
573 594
574 for (i = 1; i < ARRAY_SIZE(video_mode_table); i++) 595static const struct {
575 if (video_mode_table[i].vid == vid) 596 unsigned mask : 19;
576 return i; 597 unsigned id : 4;
577 return -1; 598} ps3av_preferred_modes[] = {
578} 599 { .mask = PS3AV_RESBIT_WUXGA << SHIFT_VESA, .id = 13 },
600 { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_60, .id = 5 },
601 { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_50, .id = 10 },
602 { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_60, .id = 4 },
603 { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_50, .id = 9 },
604 { .mask = PS3AV_RESBIT_SXGA << SHIFT_VESA, .id = 12 },
605 { .mask = PS3AV_RESBIT_WXGA << SHIFT_VESA, .id = 11 },
606 { .mask = PS3AV_RESBIT_1280x720P << SHIFT_60, .id = 3 },
607 { .mask = PS3AV_RESBIT_1280x720P << SHIFT_50, .id = 8 },
608 { .mask = PS3AV_RESBIT_720x480P << SHIFT_60, .id = 2 },
609 { .mask = PS3AV_RESBIT_720x576P << SHIFT_50, .id = 7 },
610};
579 611
580static int ps3av_resbit2vid(u32 res_50, u32 res_60) 612static int ps3av_resbit2id(u32 res_50, u32 res_60, u32 res_vesa)
581{ 613{
582 int vid = -1; 614 unsigned int i;
615 u32 res_all;
616
617 /*
618 * We mask off the resolution bits we care about and combine the
619 * results in one bitfield, so make sure there's no overlap
620 */
621 BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 &
622 PS3AV_RES_MASK_60 << SHIFT_60);
623 BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 &
624 PS3AV_RES_MASK_VESA << SHIFT_VESA);
625 BUILD_BUG_ON(PS3AV_RES_MASK_60 << SHIFT_60 &
626 PS3AV_RES_MASK_VESA << SHIFT_VESA);
627 res_all = (res_50 & PS3AV_RES_MASK_50) << SHIFT_50 |
628 (res_60 & PS3AV_RES_MASK_60) << SHIFT_60 |
629 (res_vesa & PS3AV_RES_MASK_VESA) << SHIFT_VESA;
630
631 if (!res_all)
632 return 0;
633
634 for (i = 0; i < ARRAY_SIZE(ps3av_preferred_modes); i++)
635 if (res_all & ps3av_preferred_modes[i].mask)
636 return ps3av_preferred_modes[i].id;
583 637
584 if (res_50 > res_60) { /* if res_50 == res_60, res_60 will be used */ 638 return 0;
585 if (res_50 & PS3AV_RESBIT_1920x1080P)
586 vid = PS3AV_CMD_VIDEO_VID_1080P_50HZ;
587 else if (res_50 & PS3AV_RESBIT_1920x1080I)
588 vid = PS3AV_CMD_VIDEO_VID_1080I_50HZ;
589 else if (res_50 & PS3AV_RESBIT_1280x720P)
590 vid = PS3AV_CMD_VIDEO_VID_720P_50HZ;
591 else if (res_50 & PS3AV_RESBIT_720x576P)
592 vid = PS3AV_CMD_VIDEO_VID_576P;
593 else
594 vid = -1;
595 } else {
596 if (res_60 & PS3AV_RESBIT_1920x1080P)
597 vid = PS3AV_CMD_VIDEO_VID_1080P_60HZ;
598 else if (res_60 & PS3AV_RESBIT_1920x1080I)
599 vid = PS3AV_CMD_VIDEO_VID_1080I_60HZ;
600 else if (res_60 & PS3AV_RESBIT_1280x720P)
601 vid = PS3AV_CMD_VIDEO_VID_720P_60HZ;
602 else if (res_60 & PS3AV_RESBIT_720x480P)
603 vid = PS3AV_CMD_VIDEO_VID_480P;
604 else
605 vid = -1;
606 }
607 return vid;
608} 639}
609 640
610static int ps3av_hdmi_get_vid(struct ps3av_info_monitor *info) 641static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info)
611{ 642{
612 u32 res_50, res_60; 643 int id;
613 int vid = -1;
614 644
615 if (info->monitor_type != PS3AV_MONITOR_TYPE_HDMI) 645 if (safe_mode)
616 return -1; 646 return PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
617 647
618 /* check native resolution */ 648 /* check native resolution */
619 res_50 = info->res_50.native & PS3AV_RES_MASK_50; 649 id = ps3av_resbit2id(info->res_50.native, info->res_60.native,
620 res_60 = info->res_60.native & PS3AV_RES_MASK_60; 650 info->res_vesa.native);
621 if (res_50 || res_60) { 651 if (id) {
622 vid = ps3av_resbit2vid(res_50, res_60); 652 pr_debug("%s: Using native mode %d\n", __func__, id);
623 return vid; 653 return id;
624 } 654 }
625 655
626 /* check resolution */ 656 /* check supported resolutions */
627 res_50 = info->res_50.res_bits & PS3AV_RES_MASK_50; 657 id = ps3av_resbit2id(info->res_50.res_bits, info->res_60.res_bits,
628 res_60 = info->res_60.res_bits & PS3AV_RES_MASK_60; 658 info->res_vesa.res_bits);
629 if (res_50 || res_60) { 659 if (id) {
630 vid = ps3av_resbit2vid(res_50, res_60); 660 pr_debug("%s: Using supported mode %d\n", __func__, id);
631 return vid; 661 return id;
632 } 662 }
633 663
634 if (ps3av->region & PS3AV_REGION_60) 664 if (ps3av->region & PS3AV_REGION_60)
635 vid = PS3AV_DEFAULT_HDMI_VID_REG_60; 665 id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
636 else 666 else
637 vid = PS3AV_DEFAULT_HDMI_VID_REG_50; 667 id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_50;
638 return vid; 668 pr_debug("%s: Using default mode %d\n", __func__, id);
669 return id;
639} 670}
640 671
641static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf, 672static void ps3av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info)
642 int boot)
643{ 673{
644 int i, res, vid = -1, dvi = 0, rgb = 0; 674 const struct ps3av_info_monitor *info = &monitor_info->info;
675 const struct ps3av_info_audio *audio = info->audio;
676 char id[sizeof(info->monitor_id)*3+1];
677 int i;
678
679 pr_debug("Monitor Info: size %u\n", monitor_info->send_hdr.size);
680
681 pr_debug("avport: %02x\n", info->avport);
682 for (i = 0; i < sizeof(info->monitor_id); i++)
683 sprintf(&id[i*3], " %02x", info->monitor_id[i]);
684 pr_debug("monitor_id: %s\n", id);
685 pr_debug("monitor_type: %02x\n", info->monitor_type);
686 pr_debug("monitor_name: %.*s\n", (int)sizeof(info->monitor_name),
687 info->monitor_name);
688
689 /* resolution */
690 pr_debug("resolution_60: bits: %08x native: %08x\n",
691 info->res_60.res_bits, info->res_60.native);
692 pr_debug("resolution_50: bits: %08x native: %08x\n",
693 info->res_50.res_bits, info->res_50.native);
694 pr_debug("resolution_other: bits: %08x native: %08x\n",
695 info->res_other.res_bits, info->res_other.native);
696 pr_debug("resolution_vesa: bits: %08x native: %08x\n",
697 info->res_vesa.res_bits, info->res_vesa.native);
698
699 /* color space */
700 pr_debug("color space rgb: %02x\n", info->cs.rgb);
701 pr_debug("color space yuv444: %02x\n", info->cs.yuv444);
702 pr_debug("color space yuv422: %02x\n", info->cs.yuv422);
703
704 /* color info */
705 pr_debug("color info red: X %04x Y %04x\n", info->color.red_x,
706 info->color.red_y);
707 pr_debug("color info green: X %04x Y %04x\n", info->color.green_x,
708 info->color.green_y);
709 pr_debug("color info blue: X %04x Y %04x\n", info->color.blue_x,
710 info->color.blue_y);
711 pr_debug("color info white: X %04x Y %04x\n", info->color.white_x,
712 info->color.white_y);
713 pr_debug("color info gamma: %08x\n", info->color.gamma);
714
715 /* other info */
716 pr_debug("supported_AI: %02x\n", info->supported_ai);
717 pr_debug("speaker_info: %02x\n", info->speaker_info);
718 pr_debug("num of audio: %02x\n", info->num_of_audio_block);
719
720 /* audio block */
721 for (i = 0; i < info->num_of_audio_block; i++) {
722 pr_debug("audio[%d] type: %02x max_ch: %02x fs: %02x sbit: "
723 "%02x\n",
724 i, audio->type, audio->max_num_of_ch, audio->fs,
725 audio->sbit);
726 audio++;
727 }
728}
729
730static const struct ps3av_monitor_quirk {
731 const char *monitor_name;
732 u32 clear_60, clear_50, clear_vesa;
733} ps3av_monitor_quirks[] = {
734 {
735 .monitor_name = "DELL 2007WFP",
736 .clear_60 = PS3AV_RESBIT_1920x1080I
737 }, {
738 .monitor_name = "L226WTQ",
739 .clear_60 = PS3AV_RESBIT_1920x1080I |
740 PS3AV_RESBIT_1920x1080P
741 }, {
742 .monitor_name = "SyncMaster",
743 .clear_60 = PS3AV_RESBIT_1920x1080I
744 }
745};
746
747static void ps3av_fixup_monitor_info(struct ps3av_info_monitor *info)
748{
749 unsigned int i;
750 const struct ps3av_monitor_quirk *quirk;
751
752 for (i = 0; i < ARRAY_SIZE(ps3av_monitor_quirks); i++) {
753 quirk = &ps3av_monitor_quirks[i];
754 if (!strncmp(info->monitor_name, quirk->monitor_name,
755 sizeof(info->monitor_name))) {
756 pr_info("%s: Applying quirk for %s\n", __func__,
757 quirk->monitor_name);
758 info->res_60.res_bits &= ~quirk->clear_60;
759 info->res_60.native &= ~quirk->clear_60;
760 info->res_50.res_bits &= ~quirk->clear_50;
761 info->res_50.native &= ~quirk->clear_50;
762 info->res_vesa.res_bits &= ~quirk->clear_vesa;
763 info->res_vesa.native &= ~quirk->clear_vesa;
764 break;
765 }
766 }
767}
768
769static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf)
770{
771 int i, res, id = 0, dvi = 0, rgb = 0;
645 struct ps3av_pkt_av_get_monitor_info monitor_info; 772 struct ps3av_pkt_av_get_monitor_info monitor_info;
646 struct ps3av_info_monitor *info; 773 struct ps3av_info_monitor *info;
647 774
648 /* get vid for hdmi */ 775 /* get mode id for hdmi */
649 for (i = 0; i < av_hw_conf->num_of_hdmi; i++) { 776 for (i = 0; i < av_hw_conf->num_of_hdmi && !id; i++) {
650 res = ps3av_cmd_video_get_monitor_info(&monitor_info, 777 res = ps3av_cmd_video_get_monitor_info(&monitor_info,
651 PS3AV_CMD_AVPORT_HDMI_0 + 778 PS3AV_CMD_AVPORT_HDMI_0 +
652 i); 779 i);
653 if (res < 0) 780 if (res < 0)
654 return -1; 781 return -1;
655 782
656 ps3av_cmd_av_monitor_info_dump(&monitor_info); 783 ps3av_monitor_info_dump(&monitor_info);
784
657 info = &monitor_info.info; 785 info = &monitor_info.info;
658 /* check DVI */ 786 ps3av_fixup_monitor_info(info);
659 if (info->monitor_type == PS3AV_MONITOR_TYPE_DVI) { 787
788 switch (info->monitor_type) {
789 case PS3AV_MONITOR_TYPE_DVI:
660 dvi = PS3AV_MODE_DVI; 790 dvi = PS3AV_MODE_DVI;
661 break; 791 /* fall through */
662 } 792 case PS3AV_MONITOR_TYPE_HDMI:
663 /* check HDMI */ 793 id = ps3av_hdmi_get_id(info);
664 vid = ps3av_hdmi_get_vid(info);
665 if (vid != -1) {
666 /* got valid vid */
667 break; 794 break;
668 } 795 }
669 } 796 }
670 797
671 if (dvi) { 798 if (!id) {
672 /* DVI mode */
673 vid = PS3AV_DEFAULT_DVI_VID;
674 } else if (vid == -1) {
675 /* no HDMI interface or HDMI is off */ 799 /* no HDMI interface or HDMI is off */
676 if (ps3av->region & PS3AV_REGION_60) 800 if (ps3av->region & PS3AV_REGION_60)
677 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60; 801 id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60;
678 else 802 else
679 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50; 803 id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50;
680 if (ps3av->region & PS3AV_REGION_RGB) 804 if (ps3av->region & PS3AV_REGION_RGB)
681 rgb = PS3AV_MODE_RGB; 805 rgb = PS3AV_MODE_RGB;
682 } else if (boot) { 806 pr_debug("%s: Using avmulti mode %d\n", __func__, id);
683 /* HDMI: using DEFAULT HDMI_VID while booting up */
684 info = &monitor_info.info;
685 if (ps3av->region & PS3AV_REGION_60) {
686 if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
687 vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
688 else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
689 vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
690 else {
691 /* default */
692 vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
693 }
694 } else {
695 if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
696 vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
697 else if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
698 vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
699 else {
700 /* default */
701 vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
702 }
703 }
704 } 807 }
705 808
706 return (ps3av_vid2table_id(vid) | dvi | rgb); 809 return id | dvi | rgb;
707} 810}
708 811
709static int ps3av_get_hw_conf(struct ps3av *ps3av) 812static int ps3av_get_hw_conf(struct ps3av *ps3av)
710{ 813{
711 int i, j, k, res; 814 int i, j, k, res;
815 const struct ps3av_pkt_av_get_hw_conf *hw_conf;
712 816
713 /* get av_hw_conf */ 817 /* get av_hw_conf */
714 res = ps3av_cmd_av_get_hw_conf(&ps3av->av_hw_conf); 818 res = ps3av_cmd_av_get_hw_conf(&ps3av->av_hw_conf);
715 if (res < 0) 819 if (res < 0)
716 return -1; 820 return -1;
717 821
718 ps3av_cmd_av_hw_conf_dump(&ps3av->av_hw_conf); 822 hw_conf = &ps3av->av_hw_conf;
823 pr_debug("av_h_conf: num of hdmi: %u\n", hw_conf->num_of_hdmi);
824 pr_debug("av_h_conf: num of avmulti: %u\n", hw_conf->num_of_avmulti);
825 pr_debug("av_h_conf: num of spdif: %u\n", hw_conf->num_of_spdif);
719 826
720 for (i = 0; i < PS3AV_HEAD_MAX; i++) 827 for (i = 0; i < PS3AV_HEAD_MAX; i++)
721 ps3av->head[i] = PS3AV_CMD_VIDEO_HEAD_A + i; 828 ps3av->head[i] = PS3AV_CMD_VIDEO_HEAD_A + i;
722 for (i = 0; i < PS3AV_OPT_PORT_MAX; i++) 829 for (i = 0; i < PS3AV_OPT_PORT_MAX; i++)
723 ps3av->opt_port[i] = PS3AV_CMD_AVPORT_SPDIF_0 + i; 830 ps3av->opt_port[i] = PS3AV_CMD_AVPORT_SPDIF_0 + i;
724 for (i = 0; i < ps3av->av_hw_conf.num_of_hdmi; i++) 831 for (i = 0; i < hw_conf->num_of_hdmi; i++)
725 ps3av->av_port[i] = PS3AV_CMD_AVPORT_HDMI_0 + i; 832 ps3av->av_port[i] = PS3AV_CMD_AVPORT_HDMI_0 + i;
726 for (j = 0; j < ps3av->av_hw_conf.num_of_avmulti; j++) 833 for (j = 0; j < hw_conf->num_of_avmulti; j++)
727 ps3av->av_port[i + j] = PS3AV_CMD_AVPORT_AVMULTI_0 + j; 834 ps3av->av_port[i + j] = PS3AV_CMD_AVPORT_AVMULTI_0 + j;
728 for (k = 0; k < ps3av->av_hw_conf.num_of_spdif; k++) 835 for (k = 0; k < hw_conf->num_of_spdif; k++)
729 ps3av->av_port[i + j + k] = PS3AV_CMD_AVPORT_SPDIF_0 + k; 836 ps3av->av_port[i + j + k] = PS3AV_CMD_AVPORT_SPDIF_0 + k;
730 837
731 /* set all audio port */ 838 /* set all audio port */
@@ -738,7 +845,7 @@ static int ps3av_get_hw_conf(struct ps3av *ps3av)
738} 845}
739 846
740/* set mode using id */ 847/* set mode using id */
741int ps3av_set_video_mode(u32 id, int boot) 848int ps3av_set_video_mode(u32 id)
742{ 849{
743 int size; 850 int size;
744 u32 option; 851 u32 option;
@@ -752,7 +859,7 @@ int ps3av_set_video_mode(u32 id, int boot)
752 /* auto mode */ 859 /* auto mode */
753 option = id & ~PS3AV_MODE_MASK; 860 option = id & ~PS3AV_MODE_MASK;
754 if ((id & PS3AV_MODE_MASK) == 0) { 861 if ((id & PS3AV_MODE_MASK) == 0) {
755 id = ps3av_auto_videomode(&ps3av->av_hw_conf, boot); 862 id = ps3av_auto_videomode(&ps3av->av_hw_conf);
756 if (id < 1) { 863 if (id < 1) {
757 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); 864 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
758 return -EINVAL; 865 return -EINVAL;
@@ -772,34 +879,13 @@ int ps3av_set_video_mode(u32 id, int boot)
772 879
773EXPORT_SYMBOL_GPL(ps3av_set_video_mode); 880EXPORT_SYMBOL_GPL(ps3av_set_video_mode);
774 881
775int ps3av_get_auto_mode(int boot) 882int ps3av_get_auto_mode(void)
776{ 883{
777 return ps3av_auto_videomode(&ps3av->av_hw_conf, boot); 884 return ps3av_auto_videomode(&ps3av->av_hw_conf);
778} 885}
779 886
780EXPORT_SYMBOL_GPL(ps3av_get_auto_mode); 887EXPORT_SYMBOL_GPL(ps3av_get_auto_mode);
781 888
782int ps3av_set_mode(u32 id, int boot)
783{
784 int res;
785
786 res = ps3av_set_video_mode(id, boot);
787 if (res)
788 return res;
789
790 res = ps3av_set_audio_mode(PS3AV_CMD_AUDIO_NUM_OF_CH_2,
791 PS3AV_CMD_AUDIO_FS_48K,
792 PS3AV_CMD_AUDIO_WORD_BITS_16,
793 PS3AV_CMD_AUDIO_FORMAT_PCM,
794 PS3AV_CMD_AUDIO_SOURCE_SERIAL);
795 if (res)
796 return res;
797
798 return 0;
799}
800
801EXPORT_SYMBOL_GPL(ps3av_set_mode);
802
803int ps3av_get_mode(void) 889int ps3av_get_mode(void)
804{ 890{
805 return ps3av ? ps3av->ps3av_mode : 0; 891 return ps3av ? ps3av->ps3av_mode : 0;
@@ -941,7 +1027,14 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
941 res); 1027 res);
942 1028
943 ps3av_get_hw_conf(ps3av); 1029 ps3av_get_hw_conf(ps3av);
944 id = ps3av_auto_videomode(&ps3av->av_hw_conf, 1); 1030
1031#ifdef CONFIG_FB
1032 if (fb_mode_option && !strcmp(fb_mode_option, "safe"))
1033 safe_mode = 1;
1034#endif /* CONFIG_FB */
1035 id = ps3av_auto_videomode(&ps3av->av_hw_conf);
1036 safe_mode = 0;
1037
945 mutex_lock(&ps3av->mutex); 1038 mutex_lock(&ps3av->mutex);
946 ps3av->ps3av_mode = id; 1039 ps3av->ps3av_mode = id;
947 mutex_unlock(&ps3av->mutex); 1040 mutex_unlock(&ps3av->mutex);
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
index f72f5ddf18e4..7f880c26122f 100644
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -512,7 +512,6 @@ static const u32 ps3av_ns_table[][5] = {
512static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid) 512static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid)
513{ 513{
514 u32 av_vid, ns_val; 514 u32 av_vid, ns_val;
515 u8 *p = ns;
516 int d; 515 int d;
517 516
518 d = ns_val = 0; 517 d = ns_val = 0;
@@ -551,24 +550,22 @@ static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid)
551 else 550 else
552 ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d]; 551 ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d];
553 552
554 *p++ = ns_val & 0x000000FF; 553 *ns++ = ns_val & 0x000000FF;
555 *p++ = (ns_val & 0x0000FF00) >> 8; 554 *ns++ = (ns_val & 0x0000FF00) >> 8;
556 *p = (ns_val & 0x00FF0000) >> 16; 555 *ns = (ns_val & 0x00FF0000) >> 16;
557} 556}
558 557
559#undef BASE 558#undef BASE
560 559
561static u8 ps3av_cnv_enable(u32 source, const u8 *enable) 560static u8 ps3av_cnv_enable(u32 source, const u8 *enable)
562{ 561{
563 const u8 *p;
564 u8 ret = 0; 562 u8 ret = 0;
565 563
566 if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) { 564 if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) {
567 ret = 0x03; 565 ret = 0x03;
568 } else if (source == PS3AV_CMD_AUDIO_SOURCE_SERIAL) { 566 } else if (source == PS3AV_CMD_AUDIO_SOURCE_SERIAL) {
569 p = enable; 567 ret = ((enable[0] << 4) + (enable[1] << 5) + (enable[2] << 6) +
570 ret = ((p[0] << 4) + (p[1] << 5) + (p[2] << 6) + (p[3] << 7)) | 568 (enable[3] << 7)) | 0x01;
571 0x01;
572 } else 569 } else
573 printk(KERN_ERR "%s failed, source:%x\n", __func__, source); 570 printk(KERN_ERR "%s failed, source:%x\n", __func__, source);
574 return ret; 571 return ret;
@@ -576,11 +573,9 @@ static u8 ps3av_cnv_enable(u32 source, const u8 *enable)
576 573
577static u8 ps3av_cnv_fifomap(const u8 *map) 574static u8 ps3av_cnv_fifomap(const u8 *map)
578{ 575{
579 const u8 *p;
580 u8 ret = 0; 576 u8 ret = 0;
581 577
582 p = map; 578 ret = map[0] + (map[1] << 2) + (map[2] << 4) + (map[3] << 6);
583 ret = p[0] + (p[1] << 2) + (p[2] << 4) + (p[3] << 6);
584 return ret; 579 return ret;
585} 580}
586 581
@@ -927,72 +922,6 @@ int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *info,
927 return res; 922 return res;
928} 923}
929 924
930#ifdef PS3AV_DEBUG
931void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *hw_conf)
932{
933 printk("av_h_conf:num of hdmi:%d\n", hw_conf->num_of_hdmi);
934 printk("av_h_conf:num of avmulti:%d\n", hw_conf->num_of_avmulti);
935 printk("av_h_conf:num of spdif:%d\n", hw_conf->num_of_spdif);
936}
937
938void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info)
939{
940 const struct ps3av_info_monitor *info = &monitor_info->info;
941 const struct ps3av_info_audio *audio = info->audio;
942 int i;
943
944 printk("Monitor Info: size%d\n", monitor_info->send_hdr.size);
945
946 printk("avport:%02x\n", info->avport);
947 printk("monitor_id:");
948 for (i = 0; i < 10; i++)
949 printk("%02x ", info->monitor_id[i]);
950 printk("\nmonitor_type:%02x\n", info->monitor_type);
951 printk("monitor_name:");
952 for (i = 0; i < 16; i++)
953 printk("%c", info->monitor_name[i]);
954
955 /* resolution */
956 printk("\nresolution_60: bits:%08x native:%08x\n",
957 info->res_60.res_bits, info->res_60.native);
958 printk("resolution_50: bits:%08x native:%08x\n",
959 info->res_50.res_bits, info->res_50.native);
960 printk("resolution_other: bits:%08x native:%08x\n",
961 info->res_other.res_bits, info->res_other.native);
962 printk("resolution_vesa: bits:%08x native:%08x\n",
963 info->res_vesa.res_bits, info->res_vesa.native);
964
965 /* color space */
966 printk("color space rgb:%02x\n", info->cs.rgb);
967 printk("color space yuv444:%02x\n", info->cs.yuv444);
968 printk("color space yuv422:%02x\n", info->cs.yuv422);
969
970 /* color info */
971 printk("color info red:X %04x Y %04x\n",
972 info->color.red_x, info->color.red_y);
973 printk("color info green:X %04x Y %04x\n",
974 info->color.green_x, info->color.green_y);
975 printk("color info blue:X %04x Y %04x\n",
976 info->color.blue_x, info->color.blue_y);
977 printk("color info white:X %04x Y %04x\n",
978 info->color.white_x, info->color.white_y);
979 printk("color info gamma: %08x\n", info->color.gamma);
980
981 /* other info */
982 printk("supported_AI:%02x\n", info->supported_ai);
983 printk("speaker_info:%02x\n", info->speaker_info);
984 printk("num of audio:%02x\n", info->num_of_audio_block);
985
986 /* audio block */
987 for (i = 0; i < info->num_of_audio_block; i++) {
988 printk("audio[%d] type:%02x max_ch:%02x fs:%02x sbit:%02x\n",
989 i, audio->type, audio->max_num_of_ch, audio->fs,
990 audio->sbit);
991 audio++;
992 }
993}
994#endif /* PS3AV_DEBUG */
995
996#define PS3AV_AV_LAYOUT_0 (PS3AV_CMD_AV_LAYOUT_32 \ 925#define PS3AV_AV_LAYOUT_0 (PS3AV_CMD_AV_LAYOUT_32 \
997 | PS3AV_CMD_AV_LAYOUT_44 \ 926 | PS3AV_CMD_AV_LAYOUT_44 \
998 | PS3AV_CMD_AV_LAYOUT_48) 927 | PS3AV_CMD_AV_LAYOUT_48)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index ff9e35cb308d..6420a90a4a92 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -139,6 +139,17 @@ config RTC_DRV_DS1307
139 This driver can also be built as a module. If so, the module 139 This driver can also be built as a module. If so, the module
140 will be called rtc-ds1307. 140 will be called rtc-ds1307.
141 141
142config RTC_DRV_DS1374
143 tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
144 depends on RTC_CLASS && I2C
145 help
146 If you say yes here you get support for Dallas Semiconductor
147 DS1374 real-time clock chips. If an interrupt is associated
148 with the device, the alarm functionality is supported.
149
150 This driver can also be built as a module. If so, the module
151 will be called rtc-ds1374.
152
142config RTC_DRV_DS1672 153config RTC_DRV_DS1672
143 tristate "Dallas/Maxim DS1672" 154 tristate "Dallas/Maxim DS1672"
144 help 155 help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index d3a33aa2696f..465db4dd50b2 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
23obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o 23obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
24obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o 24obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
25obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o 25obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
26obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o
26obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o 27obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
27obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o 28obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
28obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o 29obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 10ab3b71ffc6..4dfdf019fccc 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -153,6 +153,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
153 mutex_init(&rtc->ops_lock); 153 mutex_init(&rtc->ops_lock);
154 spin_lock_init(&rtc->irq_lock); 154 spin_lock_init(&rtc->irq_lock);
155 spin_lock_init(&rtc->irq_task_lock); 155 spin_lock_init(&rtc->irq_task_lock);
156 init_waitqueue_head(&rtc->irq_queue);
156 157
157 strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); 158 strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
158 snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id); 159 snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id);
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index ad66c6ecf365..de0da545c7a1 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -12,6 +12,7 @@
12*/ 12*/
13 13
14#include <linux/rtc.h> 14#include <linux/rtc.h>
15#include <linux/log2.h>
15 16
16int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) 17int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
17{ 18{
@@ -99,7 +100,7 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
99} 100}
100EXPORT_SYMBOL_GPL(rtc_set_mmss); 101EXPORT_SYMBOL_GPL(rtc_set_mmss);
101 102
102int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 103static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
103{ 104{
104 int err; 105 int err;
105 106
@@ -119,6 +120,87 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
119 mutex_unlock(&rtc->ops_lock); 120 mutex_unlock(&rtc->ops_lock);
120 return err; 121 return err;
121} 122}
123
124int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
125{
126 int err;
127 struct rtc_time before, now;
128 int first_time = 1;
129
130 /* The lower level RTC driver may not be capable of filling
131 * in all fields of the rtc_time struct (eg. rtc-cmos),
132 * and so might instead return -1 in some fields.
133 * We deal with that here by grabbing a current RTC timestamp
134 * and using values from that for any missing (-1) values.
135 *
136 * But this can be racey, because some fields of the RTC timestamp
137 * may have wrapped in the interval since we read the RTC alarm,
138 * which would lead to us inserting inconsistent values in place
139 * of the -1 fields.
140 *
141 * Reading the alarm and timestamp in the reverse sequence
142 * would have the same race condition, and not solve the issue.
143 *
144 * So, we must first read the RTC timestamp,
145 * then read the RTC alarm value,
146 * and then read a second RTC timestamp.
147 *
148 * If any fields of the second timestamp have changed
149 * when compared with the first timestamp, then we know
150 * our timestamp may be inconsistent with that used by
151 * the low-level rtc_read_alarm_internal() function.
152 *
153 * So, when the two timestamps disagree, we just loop and do
154 * the process again to get a fully consistent set of values.
155 *
156 * This could all instead be done in the lower level driver,
157 * but since more than one lower level RTC implementation needs it,
158 * then it's probably best best to do it here instead of there..
159 */
160
161 /* Get the "before" timestamp */
162 err = rtc_read_time(rtc, &before);
163 if (err < 0)
164 return err;
165 do {
166 if (!first_time)
167 memcpy(&before, &now, sizeof(struct rtc_time));
168 first_time = 0;
169
170 /* get the RTC alarm values, which may be incomplete */
171 err = rtc_read_alarm_internal(rtc, alarm);
172 if (err)
173 return err;
174 if (!alarm->enabled)
175 return 0;
176
177 /* get the "after" timestamp, to detect wrapped fields */
178 err = rtc_read_time(rtc, &now);
179 if (err < 0)
180 return err;
181
182 /* note that tm_sec is a "don't care" value here: */
183 } while ( before.tm_min != now.tm_min
184 || before.tm_hour != now.tm_hour
185 || before.tm_mon != now.tm_mon
186 || before.tm_year != now.tm_year
187 || before.tm_isdst != now.tm_isdst);
188
189 /* Fill in any missing alarm fields using the timestamp */
190 if (alarm->time.tm_sec == -1)
191 alarm->time.tm_sec = now.tm_sec;
192 if (alarm->time.tm_min == -1)
193 alarm->time.tm_min = now.tm_min;
194 if (alarm->time.tm_hour == -1)
195 alarm->time.tm_hour = now.tm_hour;
196 if (alarm->time.tm_mday == -1)
197 alarm->time.tm_mday = now.tm_mday;
198 if (alarm->time.tm_mon == -1)
199 alarm->time.tm_mon = now.tm_mon;
200 if (alarm->time.tm_year == -1)
201 alarm->time.tm_year = now.tm_year;
202 return 0;
203}
122EXPORT_SYMBOL_GPL(rtc_read_alarm); 204EXPORT_SYMBOL_GPL(rtc_read_alarm);
123 205
124int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 206int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
@@ -210,6 +292,10 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
210 if (task == NULL || task->func == NULL) 292 if (task == NULL || task->func == NULL)
211 return -EINVAL; 293 return -EINVAL;
212 294
295 /* Cannot register while the char dev is in use */
296 if (!(mutex_trylock(&rtc->char_lock)))
297 return -EBUSY;
298
213 spin_lock_irq(&rtc->irq_task_lock); 299 spin_lock_irq(&rtc->irq_task_lock);
214 if (rtc->irq_task == NULL) { 300 if (rtc->irq_task == NULL) {
215 rtc->irq_task = task; 301 rtc->irq_task = task;
@@ -217,13 +303,14 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
217 } 303 }
218 spin_unlock_irq(&rtc->irq_task_lock); 304 spin_unlock_irq(&rtc->irq_task_lock);
219 305
306 mutex_unlock(&rtc->char_lock);
307
220 return retval; 308 return retval;
221} 309}
222EXPORT_SYMBOL_GPL(rtc_irq_register); 310EXPORT_SYMBOL_GPL(rtc_irq_register);
223 311
224void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task) 312void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
225{ 313{
226
227 spin_lock_irq(&rtc->irq_task_lock); 314 spin_lock_irq(&rtc->irq_task_lock);
228 if (rtc->irq_task == task) 315 if (rtc->irq_task == task)
229 rtc->irq_task = NULL; 316 rtc->irq_task = NULL;
@@ -231,6 +318,16 @@ void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
231} 318}
232EXPORT_SYMBOL_GPL(rtc_irq_unregister); 319EXPORT_SYMBOL_GPL(rtc_irq_unregister);
233 320
321/**
322 * rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs
323 * @rtc: the rtc device
324 * @task: currently registered with rtc_irq_register()
325 * @enabled: true to enable periodic IRQs
326 * Context: any
327 *
328 * Note that rtc_irq_set_freq() should previously have been used to
329 * specify the desired frequency of periodic IRQ task->func() callbacks.
330 */
234int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled) 331int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled)
235{ 332{
236 int err = 0; 333 int err = 0;
@@ -240,8 +337,10 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled
240 return -ENXIO; 337 return -ENXIO;
241 338
242 spin_lock_irqsave(&rtc->irq_task_lock, flags); 339 spin_lock_irqsave(&rtc->irq_task_lock, flags);
340 if (rtc->irq_task != NULL && task == NULL)
341 err = -EBUSY;
243 if (rtc->irq_task != task) 342 if (rtc->irq_task != task)
244 err = -ENXIO; 343 err = -EACCES;
245 spin_unlock_irqrestore(&rtc->irq_task_lock, flags); 344 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
246 345
247 if (err == 0) 346 if (err == 0)
@@ -251,6 +350,16 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled
251} 350}
252EXPORT_SYMBOL_GPL(rtc_irq_set_state); 351EXPORT_SYMBOL_GPL(rtc_irq_set_state);
253 352
353/**
354 * rtc_irq_set_freq - set 2^N Hz periodic IRQ frequency for IRQ
355 * @rtc: the rtc device
356 * @task: currently registered with rtc_irq_register()
357 * @freq: positive frequency with which task->func() will be called
358 * Context: any
359 *
360 * Note that rtc_irq_set_state() is used to enable or disable the
361 * periodic IRQs.
362 */
254int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) 363int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
255{ 364{
256 int err = 0; 365 int err = 0;
@@ -259,9 +368,14 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
259 if (rtc->ops->irq_set_freq == NULL) 368 if (rtc->ops->irq_set_freq == NULL)
260 return -ENXIO; 369 return -ENXIO;
261 370
371 if (!is_power_of_2(freq))
372 return -EINVAL;
373
262 spin_lock_irqsave(&rtc->irq_task_lock, flags); 374 spin_lock_irqsave(&rtc->irq_task_lock, flags);
375 if (rtc->irq_task != NULL && task == NULL)
376 err = -EBUSY;
263 if (rtc->irq_task != task) 377 if (rtc->irq_task != task)
264 err = -ENXIO; 378 err = -EACCES;
265 spin_unlock_irqrestore(&rtc->irq_task_lock, flags); 379 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
266 380
267 if (err == 0) { 381 if (err == 0) {
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 5d760bb6c2cd..e3fe83a23cf7 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -246,11 +246,9 @@ static int cmos_irq_set_freq(struct device *dev, int freq)
246 246
247 /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */ 247 /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */
248 f = ffs(freq); 248 f = ffs(freq);
249 if (f != 0) { 249 if (f-- > 16)
250 if (f-- > 16 || freq != (1 << f)) 250 return -EINVAL;
251 return -EINVAL; 251 f = 16 - f;
252 f = 16 - f;
253 }
254 252
255 spin_lock_irqsave(&rtc_lock, flags); 253 spin_lock_irqsave(&rtc_lock, flags);
256 CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); 254 CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT);
@@ -435,6 +433,19 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
435 if (!ports) 433 if (!ports)
436 return -ENODEV; 434 return -ENODEV;
437 435
436 /* Claim I/O ports ASAP, minimizing conflict with legacy driver.
437 *
438 * REVISIT non-x86 systems may instead use memory space resources
439 * (needing ioremap etc), not i/o space resources like this ...
440 */
441 ports = request_region(ports->start,
442 ports->end + 1 - ports->start,
443 driver_name);
444 if (!ports) {
445 dev_dbg(dev, "i/o registers already in use\n");
446 return -EBUSY;
447 }
448
438 cmos_rtc.irq = rtc_irq; 449 cmos_rtc.irq = rtc_irq;
439 cmos_rtc.iomem = ports; 450 cmos_rtc.iomem = ports;
440 451
@@ -456,24 +467,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
456 467
457 cmos_rtc.rtc = rtc_device_register(driver_name, dev, 468 cmos_rtc.rtc = rtc_device_register(driver_name, dev,
458 &cmos_rtc_ops, THIS_MODULE); 469 &cmos_rtc_ops, THIS_MODULE);
459 if (IS_ERR(cmos_rtc.rtc)) 470 if (IS_ERR(cmos_rtc.rtc)) {
460 return PTR_ERR(cmos_rtc.rtc); 471 retval = PTR_ERR(cmos_rtc.rtc);
472 goto cleanup0;
473 }
461 474
462 cmos_rtc.dev = dev; 475 cmos_rtc.dev = dev;
463 dev_set_drvdata(dev, &cmos_rtc); 476 dev_set_drvdata(dev, &cmos_rtc);
464
465 /* platform and pnp busses handle resources incompatibly.
466 *
467 * REVISIT for non-x86 systems we may need to handle io memory
468 * resources: ioremap them, and request_mem_region().
469 */
470 if (is_pnp()) {
471 retval = request_resource(&ioport_resource, ports);
472 if (retval < 0) {
473 dev_dbg(dev, "i/o registers already in use\n");
474 goto cleanup0;
475 }
476 }
477 rename_region(ports, cmos_rtc.rtc->dev.bus_id); 477 rename_region(ports, cmos_rtc.rtc->dev.bus_id);
478 478
479 spin_lock_irq(&rtc_lock); 479 spin_lock_irq(&rtc_lock);
@@ -536,9 +536,10 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
536 return 0; 536 return 0;
537 537
538cleanup1: 538cleanup1:
539 rename_region(ports, NULL); 539 cmos_rtc.dev = NULL;
540cleanup0:
541 rtc_device_unregister(cmos_rtc.rtc); 540 rtc_device_unregister(cmos_rtc.rtc);
541cleanup0:
542 release_region(ports->start, ports->end + 1 - ports->start);
542 return retval; 543 return retval;
543} 544}
544 545
@@ -557,19 +558,21 @@ static void cmos_do_shutdown(void)
557static void __exit cmos_do_remove(struct device *dev) 558static void __exit cmos_do_remove(struct device *dev)
558{ 559{
559 struct cmos_rtc *cmos = dev_get_drvdata(dev); 560 struct cmos_rtc *cmos = dev_get_drvdata(dev);
561 struct resource *ports;
560 562
561 cmos_do_shutdown(); 563 cmos_do_shutdown();
562 564
563 if (is_pnp())
564 release_resource(cmos->iomem);
565 rename_region(cmos->iomem, NULL);
566
567 if (is_valid_irq(cmos->irq)) 565 if (is_valid_irq(cmos->irq))
568 free_irq(cmos->irq, cmos_rtc.rtc); 566 free_irq(cmos->irq, cmos->rtc);
569 567
570 rtc_device_unregister(cmos_rtc.rtc); 568 rtc_device_unregister(cmos->rtc);
569 cmos->rtc = NULL;
571 570
572 cmos_rtc.dev = NULL; 571 ports = cmos->iomem;
572 release_region(ports->start, ports->end + 1 - ports->start);
573 cmos->iomem = NULL;
574
575 cmos->dev = NULL;
573 dev_set_drvdata(dev, NULL); 576 dev_set_drvdata(dev, NULL);
574} 577}
575 578
@@ -656,7 +659,8 @@ static int cmos_resume(struct device *dev)
656/*----------------------------------------------------------------*/ 659/*----------------------------------------------------------------*/
657 660
658/* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems, 661/* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems,
659 * the device node will always be created as a PNPACPI device. 662 * the device node will always be created as a PNPACPI device. Plus
663 * pre-ACPI PCs probably list it in the PNPBIOS tables.
660 */ 664 */
661 665
662#ifdef CONFIG_PNP 666#ifdef CONFIG_PNP
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 005fff3a3508..814583bd2fe7 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -142,7 +142,7 @@ static int set_uie(struct rtc_device *rtc)
142static ssize_t 142static ssize_t
143rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 143rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
144{ 144{
145 struct rtc_device *rtc = to_rtc_device(file->private_data); 145 struct rtc_device *rtc = file->private_data;
146 146
147 DECLARE_WAITQUEUE(wait, current); 147 DECLARE_WAITQUEUE(wait, current);
148 unsigned long data; 148 unsigned long data;
@@ -196,7 +196,7 @@ rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
196 196
197static unsigned int rtc_dev_poll(struct file *file, poll_table *wait) 197static unsigned int rtc_dev_poll(struct file *file, poll_table *wait)
198{ 198{
199 struct rtc_device *rtc = to_rtc_device(file->private_data); 199 struct rtc_device *rtc = file->private_data;
200 unsigned long data; 200 unsigned long data;
201 201
202 poll_wait(file, &rtc->irq_queue, wait); 202 poll_wait(file, &rtc->irq_queue, wait);
@@ -233,22 +233,12 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
233 break; 233 break;
234 234
235 case RTC_PIE_ON: 235 case RTC_PIE_ON:
236 if (!capable(CAP_SYS_RESOURCE)) 236 if (rtc->irq_freq > rtc->max_user_freq &&
237 !capable(CAP_SYS_RESOURCE))
237 return -EACCES; 238 return -EACCES;
238 break; 239 break;
239 } 240 }
240 241
241 /* avoid conflicting IRQ users */
242 if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
243 spin_lock_irq(&rtc->irq_task_lock);
244 if (rtc->irq_task)
245 err = -EBUSY;
246 spin_unlock_irq(&rtc->irq_task_lock);
247
248 if (err < 0)
249 return err;
250 }
251
252 /* try the driver's ioctl interface */ 242 /* try the driver's ioctl interface */
253 if (ops->ioctl) { 243 if (ops->ioctl) {
254 err = ops->ioctl(rtc->dev.parent, cmd, arg); 244 err = ops->ioctl(rtc->dev.parent, cmd, arg);
@@ -338,18 +328,20 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
338 err = rtc_set_time(rtc, &tm); 328 err = rtc_set_time(rtc, &tm);
339 break; 329 break;
340 330
341 case RTC_IRQP_READ: 331 case RTC_PIE_ON:
342 if (ops->irq_set_freq) 332 err = rtc_irq_set_state(rtc, NULL, 1);
343 err = put_user(rtc->irq_freq, (unsigned long __user *)uarg); 333 break;
344 else 334
345 err = -ENOTTY; 335 case RTC_PIE_OFF:
336 err = rtc_irq_set_state(rtc, NULL, 0);
346 break; 337 break;
347 338
348 case RTC_IRQP_SET: 339 case RTC_IRQP_SET:
349 if (ops->irq_set_freq) 340 err = rtc_irq_set_freq(rtc, NULL, arg);
350 err = rtc_irq_set_freq(rtc, rtc->irq_task, arg); 341 break;
351 else 342
352 err = -ENOTTY; 343 case RTC_IRQP_READ:
344 err = put_user(rtc->irq_freq, (unsigned long __user *)uarg);
353 break; 345 break;
354 346
355#if 0 347#if 0
@@ -405,7 +397,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
405 397
406static int rtc_dev_release(struct inode *inode, struct file *file) 398static int rtc_dev_release(struct inode *inode, struct file *file)
407{ 399{
408 struct rtc_device *rtc = to_rtc_device(file->private_data); 400 struct rtc_device *rtc = file->private_data;
409 401
410#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 402#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
411 clear_uie(rtc); 403 clear_uie(rtc);
@@ -419,7 +411,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
419 411
420static int rtc_dev_fasync(int fd, struct file *file, int on) 412static int rtc_dev_fasync(int fd, struct file *file, int on)
421{ 413{
422 struct rtc_device *rtc = to_rtc_device(file->private_data); 414 struct rtc_device *rtc = file->private_data;
423 return fasync_helper(fd, file, on, &rtc->async_queue); 415 return fasync_helper(fd, file, on, &rtc->async_queue);
424} 416}
425 417
@@ -449,8 +441,6 @@ void rtc_dev_prepare(struct rtc_device *rtc)
449 rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); 441 rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
450 442
451 mutex_init(&rtc->char_lock); 443 mutex_init(&rtc->char_lock);
452 spin_lock_init(&rtc->irq_lock);
453 init_waitqueue_head(&rtc->irq_queue);
454#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 444#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
455 INIT_WORK(&rtc->uie_task, rtc_uie_task); 445 INIT_WORK(&rtc->uie_task, rtc_uie_task);
456 setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); 446 setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc);
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
new file mode 100644
index 000000000000..45bda186befc
--- /dev/null
+++ b/drivers/rtc/rtc-ds1374.c
@@ -0,0 +1,449 @@
1/*
2 * RTC client/driver for the Maxim/Dallas DS1374 Real-Time Clock over I2C
3 *
4 * Based on code by Randy Vinson <rvinson@mvista.com>,
5 * which was based on the m41t00.c by Mark Greer <mgreer@mvista.com>.
6 *
7 * Copyright (C) 2006-2007 Freescale Semiconductor
8 *
9 * 2005 (c) MontaVista Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14/*
15 * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
16 * recommened in .../Documentation/i2c/writing-clients section
17 * "Sending and receiving", using SMBus level communication is preferred.
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/interrupt.h>
23#include <linux/i2c.h>
24#include <linux/rtc.h>
25#include <linux/bcd.h>
26#include <linux/workqueue.h>
27
28#define DS1374_REG_TOD0 0x00 /* Time of Day */
29#define DS1374_REG_TOD1 0x01
30#define DS1374_REG_TOD2 0x02
31#define DS1374_REG_TOD3 0x03
32#define DS1374_REG_WDALM0 0x04 /* Watchdog/Alarm */
33#define DS1374_REG_WDALM1 0x05
34#define DS1374_REG_WDALM2 0x06
35#define DS1374_REG_CR 0x07 /* Control */
36#define DS1374_REG_CR_AIE 0x01 /* Alarm Int. Enable */
37#define DS1374_REG_CR_WDALM 0x20 /* 1=Watchdog, 0=Alarm */
38#define DS1374_REG_CR_WACE 0x40 /* WD/Alarm counter enable */
39#define DS1374_REG_SR 0x08 /* Status */
40#define DS1374_REG_SR_OSF 0x80 /* Oscillator Stop Flag */
41#define DS1374_REG_SR_AF 0x01 /* Alarm Flag */
42#define DS1374_REG_TCR 0x09 /* Trickle Charge */
43
44struct ds1374 {
45 struct i2c_client *client;
46 struct rtc_device *rtc;
47 struct work_struct work;
48
49 /* The mutex protects alarm operations, and prevents a race
50 * between the enable_irq() in the workqueue and the free_irq()
51 * in the remove function.
52 */
53 struct mutex mutex;
54 int exiting;
55};
56
57static struct i2c_driver ds1374_driver;
58
59static int ds1374_read_rtc(struct i2c_client *client, u32 *time,
60 int reg, int nbytes)
61{
62 u8 buf[4];
63 int ret;
64 int i;
65
66 if (nbytes > 4) {
67 WARN_ON(1);
68 return -EINVAL;
69 }
70
71 ret = i2c_smbus_read_i2c_block_data(client, reg, nbytes, buf);
72
73 if (ret < 0)
74 return ret;
75 if (ret < nbytes)
76 return -EIO;
77
78 for (i = nbytes - 1, *time = 0; i >= 0; i--)
79 *time = (*time << 8) | buf[i];
80
81 return 0;
82}
83
84static int ds1374_write_rtc(struct i2c_client *client, u32 time,
85 int reg, int nbytes)
86{
87 u8 buf[4];
88 int i;
89
90 if (nbytes > 4) {
91 WARN_ON(1);
92 return -EINVAL;
93 }
94
95 for (i = 0; i < nbytes; i++) {
96 buf[i] = time & 0xff;
97 time >>= 8;
98 }
99
100 return i2c_smbus_write_i2c_block_data(client, reg, nbytes, buf);
101}
102
103static int ds1374_check_rtc_status(struct i2c_client *client)
104{
105 int ret = 0;
106 int control, stat;
107
108 stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
109 if (stat < 0)
110 return stat;
111
112 if (stat & DS1374_REG_SR_OSF)
113 dev_warn(&client->dev,
114 "oscillator discontinuity flagged, "
115 "time unreliable\n");
116
117 stat &= ~(DS1374_REG_SR_OSF | DS1374_REG_SR_AF);
118
119 ret = i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
120 if (ret < 0)
121 return ret;
122
123 /* If the alarm is pending, clear it before requesting
124 * the interrupt, so an interrupt event isn't reported
125 * before everything is initialized.
126 */
127
128 control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
129 if (control < 0)
130 return control;
131
132 control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
133 return i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
134}
135
136static int ds1374_read_time(struct device *dev, struct rtc_time *time)
137{
138 struct i2c_client *client = to_i2c_client(dev);
139 u32 itime;
140 int ret;
141
142 ret = ds1374_read_rtc(client, &itime, DS1374_REG_TOD0, 4);
143 if (!ret)
144 rtc_time_to_tm(itime, time);
145
146 return ret;
147}
148
149static int ds1374_set_time(struct device *dev, struct rtc_time *time)
150{
151 struct i2c_client *client = to_i2c_client(dev);
152 unsigned long itime;
153
154 rtc_tm_to_time(time, &itime);
155 return ds1374_write_rtc(client, itime, DS1374_REG_TOD0, 4);
156}
157
158/* The ds1374 has a decrementer for an alarm, rather than a comparator.
159 * If the time of day is changed, then the alarm will need to be
160 * reset.
161 */
162static int ds1374_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
163{
164 struct i2c_client *client = to_i2c_client(dev);
165 struct ds1374 *ds1374 = i2c_get_clientdata(client);
166 u32 now, cur_alarm;
167 int cr, sr;
168 int ret = 0;
169
170 if (client->irq < 0)
171 return -EINVAL;
172
173 mutex_lock(&ds1374->mutex);
174
175 cr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
176 if (ret < 0)
177 goto out;
178
179 sr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
180 if (ret < 0)
181 goto out;
182
183 ret = ds1374_read_rtc(client, &now, DS1374_REG_TOD0, 4);
184 if (ret)
185 goto out;
186
187 ret = ds1374_read_rtc(client, &cur_alarm, DS1374_REG_WDALM0, 3);
188 if (ret)
189 goto out;
190
191 rtc_time_to_tm(now + cur_alarm, &alarm->time);
192 alarm->enabled = !!(cr & DS1374_REG_CR_WACE);
193 alarm->pending = !!(sr & DS1374_REG_SR_AF);
194
195out:
196 mutex_unlock(&ds1374->mutex);
197 return ret;
198}
199
200static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
201{
202 struct i2c_client *client = to_i2c_client(dev);
203 struct ds1374 *ds1374 = i2c_get_clientdata(client);
204 struct rtc_time now;
205 unsigned long new_alarm, itime;
206 int cr;
207 int ret = 0;
208
209 if (client->irq < 0)
210 return -EINVAL;
211
212 ret = ds1374_read_time(dev, &now);
213 if (ret < 0)
214 return ret;
215
216 rtc_tm_to_time(&alarm->time, &new_alarm);
217 rtc_tm_to_time(&now, &itime);
218
219 new_alarm -= itime;
220
221 /* This can happen due to races, in addition to dates that are
222 * truly in the past. To avoid requiring the caller to check for
223 * races, dates in the past are assumed to be in the recent past
224 * (i.e. not something that we'd rather the caller know about via
225 * an error), and the alarm is set to go off as soon as possible.
226 */
227 if (new_alarm <= 0)
228 new_alarm = 1;
229
230 mutex_lock(&ds1374->mutex);
231
232 ret = cr = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
233 if (ret < 0)
234 goto out;
235
236 /* Disable any existing alarm before setting the new one
237 * (or lack thereof). */
238 cr &= ~DS1374_REG_CR_WACE;
239
240 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
241 if (ret < 0)
242 goto out;
243
244 ret = ds1374_write_rtc(client, new_alarm, DS1374_REG_WDALM0, 3);
245 if (ret)
246 goto out;
247
248 if (alarm->enabled) {
249 cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
250 cr &= ~DS1374_REG_CR_WDALM;
251
252 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
253 }
254
255out:
256 mutex_unlock(&ds1374->mutex);
257 return ret;
258}
259
260static irqreturn_t ds1374_irq(int irq, void *dev_id)
261{
262 struct i2c_client *client = dev_id;
263 struct ds1374 *ds1374 = i2c_get_clientdata(client);
264
265 disable_irq_nosync(irq);
266 schedule_work(&ds1374->work);
267 return IRQ_HANDLED;
268}
269
270static void ds1374_work(struct work_struct *work)
271{
272 struct ds1374 *ds1374 = container_of(work, struct ds1374, work);
273 struct i2c_client *client = ds1374->client;
274 int stat, control;
275
276 mutex_lock(&ds1374->mutex);
277
278 stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
279 if (stat < 0)
280 return;
281
282 if (stat & DS1374_REG_SR_AF) {
283 stat &= ~DS1374_REG_SR_AF;
284 i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
285
286 control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
287 if (control < 0)
288 goto out;
289
290 control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
291 i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
292
293 /* rtc_update_irq() assumes that it is called
294 * from IRQ-disabled context.
295 */
296 local_irq_disable();
297 rtc_update_irq(ds1374->rtc, 1, RTC_AF | RTC_IRQF);
298 local_irq_enable();
299 }
300
301out:
302 if (!ds1374->exiting)
303 enable_irq(client->irq);
304
305 mutex_unlock(&ds1374->mutex);
306}
307
308static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
309{
310 struct i2c_client *client = to_i2c_client(dev);
311 struct ds1374 *ds1374 = i2c_get_clientdata(client);
312 int ret = -ENOIOCTLCMD;
313
314 mutex_lock(&ds1374->mutex);
315
316 switch (cmd) {
317 case RTC_AIE_OFF:
318 ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
319 if (ret < 0)
320 goto out;
321
322 ret &= ~DS1374_REG_CR_WACE;
323
324 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
325 if (ret < 0)
326 goto out;
327
328 break;
329
330 case RTC_AIE_ON:
331 ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
332 if (ret < 0)
333 goto out;
334
335 ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
336 ret &= ~DS1374_REG_CR_WDALM;
337
338 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
339 if (ret < 0)
340 goto out;
341
342 break;
343 }
344
345out:
346 mutex_unlock(&ds1374->mutex);
347 return ret;
348}
349
350static const struct rtc_class_ops ds1374_rtc_ops = {
351 .read_time = ds1374_read_time,
352 .set_time = ds1374_set_time,
353 .read_alarm = ds1374_read_alarm,
354 .set_alarm = ds1374_set_alarm,
355 .ioctl = ds1374_ioctl,
356};
357
358static int ds1374_probe(struct i2c_client *client)
359{
360 struct ds1374 *ds1374;
361 int ret;
362
363 ds1374 = kzalloc(sizeof(struct ds1374), GFP_KERNEL);
364 if (!ds1374)
365 return -ENOMEM;
366
367 ds1374->client = client;
368 i2c_set_clientdata(client, ds1374);
369
370 INIT_WORK(&ds1374->work, ds1374_work);
371 mutex_init(&ds1374->mutex);
372
373 ret = ds1374_check_rtc_status(client);
374 if (ret)
375 goto out_free;
376
377 if (client->irq >= 0) {
378 ret = request_irq(client->irq, ds1374_irq, 0,
379 "ds1374", client);
380 if (ret) {
381 dev_err(&client->dev, "unable to request IRQ\n");
382 goto out_free;
383 }
384 }
385
386 ds1374->rtc = rtc_device_register(client->name, &client->dev,
387 &ds1374_rtc_ops, THIS_MODULE);
388 if (IS_ERR(ds1374->rtc)) {
389 ret = PTR_ERR(ds1374->rtc);
390 dev_err(&client->dev, "unable to register the class device\n");
391 goto out_irq;
392 }
393
394 return 0;
395
396out_irq:
397 if (client->irq >= 0)
398 free_irq(client->irq, client);
399
400out_free:
401 i2c_set_clientdata(client, NULL);
402 kfree(ds1374);
403 return ret;
404}
405
406static int __devexit ds1374_remove(struct i2c_client *client)
407{
408 struct ds1374 *ds1374 = i2c_get_clientdata(client);
409
410 if (client->irq >= 0) {
411 mutex_lock(&ds1374->mutex);
412 ds1374->exiting = 1;
413 mutex_unlock(&ds1374->mutex);
414
415 free_irq(client->irq, client);
416 flush_scheduled_work();
417 }
418
419 rtc_device_unregister(ds1374->rtc);
420 i2c_set_clientdata(client, NULL);
421 kfree(ds1374);
422 return 0;
423}
424
425static struct i2c_driver ds1374_driver = {
426 .driver = {
427 .name = "rtc-ds1374",
428 .owner = THIS_MODULE,
429 },
430 .probe = ds1374_probe,
431 .remove = __devexit_p(ds1374_remove),
432};
433
434static int __init ds1374_init(void)
435{
436 return i2c_add_driver(&ds1374_driver);
437}
438
439static void __exit ds1374_exit(void)
440{
441 i2c_del_driver(&ds1374_driver);
442}
443
444module_init(ds1374_init);
445module_exit(ds1374_exit);
446
447MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>");
448MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver");
449MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 5ab3492817d1..bb53c09bad16 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -395,7 +395,7 @@ static struct platform_driver ds1553_rtc_driver = {
395 .probe = ds1553_rtc_probe, 395 .probe = ds1553_rtc_probe,
396 .remove = __devexit_p(ds1553_rtc_remove), 396 .remove = __devexit_p(ds1553_rtc_remove),
397 .driver = { 397 .driver = {
398 .name = "ds1553", 398 .name = "rtc-ds1553",
399 .owner = THIS_MODULE, 399 .owner = THIS_MODULE,
400 }, 400 },
401}; 401};
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 67291b0f8283..c535b78698e2 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -251,7 +251,7 @@ static struct platform_driver ds1742_rtc_driver = {
251 .probe = ds1742_rtc_probe, 251 .probe = ds1742_rtc_probe,
252 .remove = __devexit_p(ds1742_rtc_remove), 252 .remove = __devexit_p(ds1742_rtc_remove),
253 .driver = { 253 .driver = {
254 .name = "ds1742", 254 .name = "rtc-ds1742",
255 .owner = THIS_MODULE, 255 .owner = THIS_MODULE,
256 }, 256 },
257}; 257};
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
index d48b03374586..556d0e7da35b 100644
--- a/drivers/rtc/rtc-pcf8583.c
+++ b/drivers/rtc/rtc-pcf8583.c
@@ -332,6 +332,9 @@ static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind)
332 } 332 }
333 }; 333 };
334 334
335 if (!i2c_check_functionality(adap, I2C_FUNC_I2C))
336 return 0;
337
335 pcf = kzalloc(sizeof(*pcf), GFP_KERNEL); 338 pcf = kzalloc(sizeof(*pcf), GFP_KERNEL);
336 if (!pcf) 339 if (!pcf)
337 return -ENOMEM; 340 return -ENOMEM;
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 69df94b44841..6cad0841f3c4 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -73,11 +73,35 @@ rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr,
73 return retval; 73 return retval;
74} 74}
75 75
76static ssize_t
77rtc_sysfs_show_max_user_freq(struct device *dev, struct device_attribute *attr,
78 char *buf)
79{
80 return sprintf(buf, "%d\n", to_rtc_device(dev)->max_user_freq);
81}
82
83static ssize_t
84rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr,
85 const char *buf, size_t n)
86{
87 struct rtc_device *rtc = to_rtc_device(dev);
88 unsigned long val = simple_strtoul(buf, NULL, 0);
89
90 if (val >= 4096 || val == 0)
91 return -EINVAL;
92
93 rtc->max_user_freq = (int)val;
94
95 return n;
96}
97
76static struct device_attribute rtc_attrs[] = { 98static struct device_attribute rtc_attrs[] = {
77 __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL), 99 __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL),
78 __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL), 100 __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL),
79 __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL), 101 __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL),
80 __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL), 102 __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL),
103 __ATTR(max_user_freq, S_IRUGO | S_IWUSR, rtc_sysfs_show_max_user_freq,
104 rtc_sysfs_set_max_user_freq),
81 { }, 105 { },
82}; 106};
83 107
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index cdbcaa5ad6cf..abe2bda6ac37 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -53,6 +53,11 @@
53#include "scsi.h" 53#include "scsi.h"
54#include <scsi/scsi_host.h> 54#include <scsi/scsi_host.h>
55#include "mac_scsi.h" 55#include "mac_scsi.h"
56
57/* These control the behaviour of the generic 5380 core */
58#define AUTOSENSE
59#define PSEUDO_DMA
60
56#include "NCR5380.h" 61#include "NCR5380.h"
57 62
58#if 0 63#if 0
@@ -571,10 +576,6 @@ static int macscsi_pwrite (struct Scsi_Host *instance,
571} 576}
572 577
573 578
574/* These control the behaviour of the generic 5380 core */
575#define AUTOSENSE
576#define PSEUDO_DMA
577
578#include "NCR5380.c" 579#include "NCR5380.c"
579 580
580static struct scsi_host_template driver_template = { 581static struct scsi_host_template driver_template = {
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 1ea1ed82c352..0e357562ce9e 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -1036,6 +1036,7 @@ enum pci_board_num_t {
1036 pbn_b0_2_115200, 1036 pbn_b0_2_115200,
1037 pbn_b0_4_115200, 1037 pbn_b0_4_115200,
1038 pbn_b0_5_115200, 1038 pbn_b0_5_115200,
1039 pbn_b0_8_115200,
1039 1040
1040 pbn_b0_1_921600, 1041 pbn_b0_1_921600,
1041 pbn_b0_2_921600, 1042 pbn_b0_2_921600,
@@ -1172,6 +1173,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
1172 .base_baud = 115200, 1173 .base_baud = 115200,
1173 .uart_offset = 8, 1174 .uart_offset = 8,
1174 }, 1175 },
1176 [pbn_b0_8_115200] = {
1177 .flags = FL_BASE0,
1178 .num_ports = 8,
1179 .base_baud = 115200,
1180 .uart_offset = 8,
1181 },
1175 1182
1176 [pbn_b0_1_921600] = { 1183 [pbn_b0_1_921600] = {
1177 .flags = FL_BASE0, 1184 .flags = FL_BASE0,
@@ -2566,6 +2573,119 @@ static struct pci_device_id serial_pci_tbl[] = {
2566 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, 2573 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
2567 PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, 2574 PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8,
2568 0, 0, pbn_b2_8_921600 }, 2575 0, 0, pbn_b2_8_921600 },
2576
2577 /*
2578 * Mainpine series cards: Fairly standard layout but fools
2579 * parts of the autodetect in some cases and uses otherwise
2580 * unmatched communications subclasses in the PCI Express case
2581 */
2582
2583 { /* RockForceDUO */
2584 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2585 PCI_VENDOR_ID_MAINPINE, 0x0200,
2586 0, 0, pbn_b0_2_115200 },
2587 { /* RockForceQUATRO */
2588 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2589 PCI_VENDOR_ID_MAINPINE, 0x0300,
2590 0, 0, pbn_b0_4_115200 },
2591 { /* RockForceDUO+ */
2592 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2593 PCI_VENDOR_ID_MAINPINE, 0x0400,
2594 0, 0, pbn_b0_2_115200 },
2595 { /* RockForceQUATRO+ */
2596 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2597 PCI_VENDOR_ID_MAINPINE, 0x0500,
2598 0, 0, pbn_b0_4_115200 },
2599 { /* RockForce+ */
2600 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2601 PCI_VENDOR_ID_MAINPINE, 0x0600,
2602 0, 0, pbn_b0_2_115200 },
2603 { /* RockForce+ */
2604 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2605 PCI_VENDOR_ID_MAINPINE, 0x0700,
2606 0, 0, pbn_b0_4_115200 },
2607 { /* RockForceOCTO+ */
2608 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2609 PCI_VENDOR_ID_MAINPINE, 0x0800,
2610 0, 0, pbn_b0_8_115200 },
2611 { /* RockForceDUO+ */
2612 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2613 PCI_VENDOR_ID_MAINPINE, 0x0C00,
2614 0, 0, pbn_b0_2_115200 },
2615 { /* RockForceQUARTRO+ */
2616 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2617 PCI_VENDOR_ID_MAINPINE, 0x0D00,
2618 0, 0, pbn_b0_4_115200 },
2619 { /* RockForceOCTO+ */
2620 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2621 PCI_VENDOR_ID_MAINPINE, 0x1D00,
2622 0, 0, pbn_b0_8_115200 },
2623 { /* RockForceD1 */
2624 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2625 PCI_VENDOR_ID_MAINPINE, 0x2000,
2626 0, 0, pbn_b0_1_115200 },
2627 { /* RockForceF1 */
2628 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2629 PCI_VENDOR_ID_MAINPINE, 0x2100,
2630 0, 0, pbn_b0_1_115200 },
2631 { /* RockForceD2 */
2632 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2633 PCI_VENDOR_ID_MAINPINE, 0x2200,
2634 0, 0, pbn_b0_2_115200 },
2635 { /* RockForceF2 */
2636 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2637 PCI_VENDOR_ID_MAINPINE, 0x2300,
2638 0, 0, pbn_b0_2_115200 },
2639 { /* RockForceD4 */
2640 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2641 PCI_VENDOR_ID_MAINPINE, 0x2400,
2642 0, 0, pbn_b0_4_115200 },
2643 { /* RockForceF4 */
2644 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2645 PCI_VENDOR_ID_MAINPINE, 0x2500,
2646 0, 0, pbn_b0_4_115200 },
2647 { /* RockForceD8 */
2648 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2649 PCI_VENDOR_ID_MAINPINE, 0x2600,
2650 0, 0, pbn_b0_8_115200 },
2651 { /* RockForceF8 */
2652 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2653 PCI_VENDOR_ID_MAINPINE, 0x2700,
2654 0, 0, pbn_b0_8_115200 },
2655 { /* IQ Express D1 */
2656 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2657 PCI_VENDOR_ID_MAINPINE, 0x3000,
2658 0, 0, pbn_b0_1_115200 },
2659 { /* IQ Express F1 */
2660 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2661 PCI_VENDOR_ID_MAINPINE, 0x3100,
2662 0, 0, pbn_b0_1_115200 },
2663 { /* IQ Express D2 */
2664 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2665 PCI_VENDOR_ID_MAINPINE, 0x3200,
2666 0, 0, pbn_b0_2_115200 },
2667 { /* IQ Express F2 */
2668 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2669 PCI_VENDOR_ID_MAINPINE, 0x3300,
2670 0, 0, pbn_b0_2_115200 },
2671 { /* IQ Express D4 */
2672 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2673 PCI_VENDOR_ID_MAINPINE, 0x3400,
2674 0, 0, pbn_b0_4_115200 },
2675 { /* IQ Express F4 */
2676 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2677 PCI_VENDOR_ID_MAINPINE, 0x3500,
2678 0, 0, pbn_b0_4_115200 },
2679 { /* IQ Express D8 */
2680 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2681 PCI_VENDOR_ID_MAINPINE, 0x3C00,
2682 0, 0, pbn_b0_8_115200 },
2683 { /* IQ Express F8 */
2684 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2685 PCI_VENDOR_ID_MAINPINE, 0x3D00,
2686 0, 0, pbn_b0_8_115200 },
2687
2688
2569 /* 2689 /*
2570 * PA Semi PA6T-1682M on-chip UART 2690 * PA Semi PA6T-1682M on-chip UART
2571 */ 2691 */
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 301c8c0be9d7..926f58a674a1 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -327,6 +327,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
327 { "WACF004", 0 }, 327 { "WACF004", 0 },
328 { "WACF005", 0 }, 328 { "WACF005", 0 },
329 { "WACF006", 0 }, 329 { "WACF006", 0 },
330 { "WACF007", 0 },
331 { "WACF008", 0 },
330 /* Compaq touchscreen */ 332 /* Compaq touchscreen */
331 { "FPI2002", 0 }, 333 { "FPI2002", 0 },
332 /* Fujitsu Stylistic touchscreens */ 334 /* Fujitsu Stylistic touchscreens */
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 312bef6bd583..7e8724d3571f 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -514,6 +514,8 @@ struct tty_driver *serial_driver;
514 * TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128 514 * TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128
515 * BUF_SIZE can't be > 128 515 * BUF_SIZE can't be > 128
516 */ 516 */
517#define CRIS_BUF_SIZE 512
518
517/* Currently 16 descriptors x 128 bytes = 2048 bytes */ 519/* Currently 16 descriptors x 128 bytes = 2048 bytes */
518#define SERIAL_DESCR_BUF_SIZE 256 520#define SERIAL_DESCR_BUF_SIZE 256
519 521
@@ -2497,55 +2499,18 @@ static void flush_to_flip_buffer(struct e100_serial *info)
2497 return; 2499 return;
2498 } 2500 }
2499 2501
2500 length = tty->flip.count; 2502 while ((buffer = info->first_recv_buffer) != NULL) {
2501 /* Don't flip more than the ldisc has room for.
2502 * The return value from ldisc.receive_room(tty) - might not be up to
2503 * date, the previous flip of up to TTY_FLIPBUF_SIZE might be on the
2504 * processed and not accounted for yet.
2505 * Since we use DMA, 1 SERIAL_DESCR_BUF_SIZE could be on the way.
2506 * Lets buffer data here and let flow control take care of it.
2507 * Since we normally flip large chunks, the ldisc don't react
2508 * with throttle until too late if we flip to much.
2509 */
2510 max_flip_size = tty->ldisc.receive_room(tty);
2511 if (max_flip_size < 0)
2512 max_flip_size = 0;
2513 if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */
2514 length + info->recv_cnt + /* We have this queued */
2515 2*SERIAL_DESCR_BUF_SIZE + /* This could be on the way */
2516 TTY_THRESHOLD_THROTTLE)) { /* Some slack */
2517 /* check TTY_THROTTLED first so it indicates our state */
2518 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) {
2519 DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles room %lu\n", max_flip_size));
2520 rs_throttle(tty);
2521 }
2522#if 0
2523 else if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */
2524 length + info->recv_cnt + /* We have this queued */
2525 SERIAL_DESCR_BUF_SIZE + /* This could be on the way */
2526 TTY_THRESHOLD_THROTTLE)) { /* Some slack */
2527 DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles again! %lu\n", max_flip_size));
2528 rs_throttle(tty);
2529 }
2530#endif
2531 }
2532
2533 if (max_flip_size > TTY_FLIPBUF_SIZE)
2534 max_flip_size = TTY_FLIPBUF_SIZE;
2535
2536 while ((buffer = info->first_recv_buffer) && length < max_flip_size) {
2537 unsigned int count = buffer->length; 2503 unsigned int count = buffer->length;
2538 2504
2539 if (length + count > max_flip_size) 2505 count = tty_buffer_request_room(tty, count);
2540 count = max_flip_size - length; 2506 if (count == 0) /* Throttle ?? */
2507 break;
2541 2508
2542 memcpy(tty->flip.char_buf_ptr + length, buffer->buffer, count); 2509 if (count > 1)
2543 memset(tty->flip.flag_buf_ptr + length, TTY_NORMAL, count); 2510 tty_insert_flip_strings(tty, buffer->buffer, count - 1);
2544 tty->flip.flag_buf_ptr[length] = buffer->error; 2511 tty_insert_flip_char(tty, buffer->buffer[count-1], buffer->error);
2545 2512
2546 length += count;
2547 info->recv_cnt -= count; 2513 info->recv_cnt -= count;
2548 DFLIP(DEBUG_LOG(info->line,"flip: %i\n", length));
2549 2514
2550 if (count == buffer->length) { 2515 if (count == buffer->length) {
2551 info->first_recv_buffer = buffer->next; 2516 info->first_recv_buffer = buffer->next;
@@ -2560,14 +2525,6 @@ static void flush_to_flip_buffer(struct e100_serial *info)
2560 if (!info->first_recv_buffer) 2525 if (!info->first_recv_buffer)
2561 info->last_recv_buffer = NULL; 2526 info->last_recv_buffer = NULL;
2562 2527
2563 tty->flip.count = length;
2564 DFLIP(if (tty->ldisc.chars_in_buffer(tty) > 3500) {
2565 DEBUG_LOG(info->line, "ldisc %lu\n",
2566 tty->ldisc.chars_in_buffer(tty));
2567 DEBUG_LOG(info->line, "flip.count %lu\n",
2568 tty->flip.count);
2569 }
2570 );
2571 restore_flags(flags); 2528 restore_flags(flags);
2572 2529
2573 DFLIP( 2530 DFLIP(
@@ -2722,17 +2679,17 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
2722 printk("!NO TTY!\n"); 2679 printk("!NO TTY!\n");
2723 return info; 2680 return info;
2724 } 2681 }
2725 if (tty->flip.count >= TTY_FLIPBUF_SIZE - TTY_THRESHOLD_THROTTLE) { 2682 if (tty->flip.count >= CRIS_BUF_SIZE - TTY_THRESHOLD_THROTTLE) {
2726 /* check TTY_THROTTLED first so it indicates our state */ 2683 /* check TTY_THROTTLED first so it indicates our state */
2727 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) { 2684 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) {
2728 DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count)); 2685 DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count));
2729 rs_throttle(tty); 2686 rs_throttle(tty);
2730 } 2687 }
2731 } 2688 }
2732 if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 2689 if (tty->flip.count >= CRIS_BUF_SIZE) {
2733 DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count); 2690 DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count);
2734 tty->flip.work.func((void *) tty); 2691 tty->flip.work.func((void *) tty);
2735 if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 2692 if (tty->flip.count >= CRIS_BUF_SIZE) {
2736 DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count); 2693 DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count);
2737 return info; /* if TTY_DONT_FLIP is set */ 2694 return info; /* if TTY_DONT_FLIP is set */
2738 } 2695 }
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 6e09c8b395e8..348ee2c19b58 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -539,7 +539,7 @@ static void serial_do_unlink(struct irq_info *i, struct uart_sio_port *up)
539static int serial_link_irq_chain(struct uart_sio_port *up) 539static int serial_link_irq_chain(struct uart_sio_port *up)
540{ 540{
541 struct irq_info *i = irq_lists + up->port.irq; 541 struct irq_info *i = irq_lists + up->port.irq;
542 int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; 542 int ret, irq_flags = 0;
543 543
544 spin_lock_irq(&i->lock); 544 spin_lock_irq(&i->lock);
545 545
diff --git a/drivers/serial/m32r_sio.h b/drivers/serial/m32r_sio.h
index 849f1b2c2531..e9b7e11793b1 100644
--- a/drivers/serial/m32r_sio.h
+++ b/drivers/serial/m32r_sio.h
@@ -46,9 +46,3 @@ struct old_serial_port {
46#define PROBE_ANY (~0) 46#define PROBE_ANY (~0)
47 47
48#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) 48#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
49
50#ifdef CONFIG_SERIAL_SIO_SHARE_IRQ
51#define M32R_SIO_SHARE_IRQS 1
52#else
53#define M32R_SIO_SHARE_IRQS 0
54#endif
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index a3bd3a3f41f3..68aa4da01865 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1938,9 +1938,24 @@ static void uart_change_pm(struct uart_state *state, int pm_state)
1938 } 1938 }
1939} 1939}
1940 1940
1941struct uart_match {
1942 struct uart_port *port;
1943 struct uart_driver *driver;
1944};
1945
1946static int serial_match_port(struct device *dev, void *data)
1947{
1948 struct uart_match *match = data;
1949 dev_t devt = MKDEV(match->driver->major, match->driver->minor) + match->port->line;
1950
1951 return dev->devt == devt; /* Actually, only one tty per port */
1952}
1953
1941int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) 1954int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
1942{ 1955{
1943 struct uart_state *state = drv->state + port->line; 1956 struct uart_state *state = drv->state + port->line;
1957 struct device *tty_dev;
1958 struct uart_match match = {port, drv};
1944 1959
1945 mutex_lock(&state->mutex); 1960 mutex_lock(&state->mutex);
1946 1961
@@ -1951,6 +1966,15 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
1951 } 1966 }
1952#endif 1967#endif
1953 1968
1969 tty_dev = device_find_child(port->dev, &match, serial_match_port);
1970 if (device_may_wakeup(tty_dev)) {
1971 enable_irq_wake(port->irq);
1972 put_device(tty_dev);
1973 mutex_unlock(&state->mutex);
1974 return 0;
1975 }
1976 port->suspended = 1;
1977
1954 if (state->info && state->info->flags & UIF_INITIALIZED) { 1978 if (state->info && state->info->flags & UIF_INITIALIZED) {
1955 const struct uart_ops *ops = port->ops; 1979 const struct uart_ops *ops = port->ops;
1956 1980
@@ -1999,6 +2023,13 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
1999 } 2023 }
2000#endif 2024#endif
2001 2025
2026 if (!port->suspended) {
2027 disable_irq_wake(port->irq);
2028 mutex_unlock(&state->mutex);
2029 return 0;
2030 }
2031 port->suspended = 0;
2032
2002 uart_change_pm(state, 0); 2033 uart_change_pm(state, 0);
2003 2034
2004 /* 2035 /*
@@ -2278,6 +2309,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
2278{ 2309{
2279 struct uart_state *state; 2310 struct uart_state *state;
2280 int ret = 0; 2311 int ret = 0;
2312 struct device *tty_dev;
2281 2313
2282 BUG_ON(in_interrupt()); 2314 BUG_ON(in_interrupt());
2283 2315
@@ -2314,7 +2346,13 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
2314 * Register the port whether it's detected or not. This allows 2346 * Register the port whether it's detected or not. This allows
2315 * setserial to be used to alter this ports parameters. 2347 * setserial to be used to alter this ports parameters.
2316 */ 2348 */
2317 tty_register_device(drv->tty_driver, port->line, port->dev); 2349 tty_dev = tty_register_device(drv->tty_driver, port->line, port->dev);
2350 if (likely(!IS_ERR(tty_dev))) {
2351 device_can_wakeup(tty_dev) = 1;
2352 device_set_wakeup_enable(tty_dev, 0);
2353 } else
2354 printk(KERN_ERR "Cannot register tty device on line %d\n",
2355 port->line);
2318 2356
2319 /* 2357 /*
2320 * Ensure UPF_DEAD is not set. 2358 * Ensure UPF_DEAD is not set.
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 7c8d78fbbbfb..5afcb2fa7cd3 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -911,6 +911,7 @@ static struct pcmcia_device_id serial_ids[] = {
911 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"), 911 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
912 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"), 912 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
913 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"), 913 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
914 PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
914 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ 915 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
915 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ 916 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
916 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ 917 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 0930e2a85514..6846a6c38b6d 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -25,19 +25,15 @@
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/console.h> 27#include <linux/console.h>
28#include <linux/sysrq.h>
29#include <linux/delay.h> 28#include <linux/delay.h>
30#include <linux/platform_device.h> 29#include <linux/platform_device.h>
31#include <linux/pci.h> 30#include <linux/pci.h>
32#include <linux/tty.h>
33#include <linux/tty_flip.h>
34#include <linux/serial_core.h> 31#include <linux/serial_core.h>
35#include <linux/serial.h> 32#include <linux/serial.h>
36#include <linux/mutex.h>
37 33
38#include <asm/io.h> 34#include <asm/io.h>
39 35
40static char *serial_version = "1.10"; 36static char *serial_version = "1.11";
41static char *serial_name = "TX39/49 Serial driver"; 37static char *serial_name = "TX39/49 Serial driver";
42 38
43#define PASS_LIMIT 256 39#define PASS_LIMIT 256
@@ -68,8 +64,6 @@ static char *serial_name = "TX39/49 Serial driver";
68 */ 64 */
69#define UART_NR CONFIG_SERIAL_TXX9_NR_UARTS 65#define UART_NR CONFIG_SERIAL_TXX9_NR_UARTS
70 66
71#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
72
73struct uart_txx9_port { 67struct uart_txx9_port {
74 struct uart_port port; 68 struct uart_port port;
75 /* No additional info for now */ 69 /* No additional info for now */
@@ -756,21 +750,6 @@ static void serial_txx9_config_port(struct uart_port *port, int uflags)
756 serial_txx9_initialize(port); 750 serial_txx9_initialize(port);
757} 751}
758 752
759static int
760serial_txx9_verify_port(struct uart_port *port, struct serial_struct *ser)
761{
762 unsigned long new_port = ser->port;
763 if (HIGH_BITS_OFFSET)
764 new_port += (unsigned long)ser->port_high << HIGH_BITS_OFFSET;
765 if (ser->type != port->type ||
766 ser->irq != port->irq ||
767 ser->io_type != port->iotype ||
768 new_port != port->iobase ||
769 (unsigned long)ser->iomem_base != port->mapbase)
770 return -EINVAL;
771 return 0;
772}
773
774static const char * 753static const char *
775serial_txx9_type(struct uart_port *port) 754serial_txx9_type(struct uart_port *port)
776{ 755{
@@ -794,7 +773,6 @@ static struct uart_ops serial_txx9_pops = {
794 .release_port = serial_txx9_release_port, 773 .release_port = serial_txx9_release_port,
795 .request_port = serial_txx9_request_port, 774 .request_port = serial_txx9_request_port,
796 .config_port = serial_txx9_config_port, 775 .config_port = serial_txx9_config_port,
797 .verify_port = serial_txx9_verify_port,
798}; 776};
799 777
800static struct uart_txx9_port serial_txx9_ports[UART_NR]; 778static struct uart_txx9_port serial_txx9_ports[UART_NR];
@@ -950,7 +928,8 @@ int __init early_serial_txx9_setup(struct uart_port *port)
950 928
951 serial_txx9_ports[port->line].port = *port; 929 serial_txx9_ports[port->line].port = *port;
952 serial_txx9_ports[port->line].port.ops = &serial_txx9_pops; 930 serial_txx9_ports[port->line].port.ops = &serial_txx9_pops;
953 serial_txx9_ports[port->line].port.flags |= UPF_BOOT_AUTOCONF; 931 serial_txx9_ports[port->line].port.flags |=
932 UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
954 return 0; 933 return 0;
955} 934}
956 935
@@ -995,7 +974,8 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
995 uart->port.irq = port->irq; 974 uart->port.irq = port->irq;
996 uart->port.uartclk = port->uartclk; 975 uart->port.uartclk = port->uartclk;
997 uart->port.iotype = port->iotype; 976 uart->port.iotype = port->iotype;
998 uart->port.flags = port->flags | UPF_BOOT_AUTOCONF; 977 uart->port.flags = port->flags
978 | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
999 uart->port.mapbase = port->mapbase; 979 uart->port.mapbase = port->mapbase;
1000 if (port->dev) 980 if (port->dev)
1001 uart->port.dev = port->dev; 981 uart->port.dev = port->dev;
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index b91571122daa..a77ede598d34 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -124,16 +124,17 @@ config SPI_MPC52xx_PSC
124 Controller in master SPI mode. 124 Controller in master SPI mode.
125 125
126config SPI_MPC83xx 126config SPI_MPC83xx
127 tristate "Freescale MPC83xx SPI controller" 127 tristate "Freescale MPC83xx/QUICC Engine SPI controller"
128 depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL 128 depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
129 select SPI_BITBANG 129 select SPI_BITBANG
130 help 130 help
131 This enables using the Freescale MPC83xx SPI controller in master 131 This enables using the Freescale MPC83xx and QUICC Engine SPI
132 mode. 132 controllers in master mode.
133 133
134 Note, this driver uniquely supports the SPI controller on the MPC83xx 134 Note, this driver uniquely supports the SPI controller on the MPC83xx
135 family of PowerPC processors. The MPC83xx uses a simple set of shift 135 family of PowerPC processors, plus processors with QUICC Engine
136 registers for data (opposed to the CPM based descriptor model). 136 technology. This driver uses a simple set of shift registers for data
137 (opposed to the CPM based descriptor model).
137 138
138config SPI_OMAP_UWIRE 139config SPI_OMAP_UWIRE
139 tristate "OMAP1 MicroWire" 140 tristate "OMAP1 MicroWire"
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index b0469749310a..0d342dcdd302 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -211,7 +211,7 @@ static void atmel_spi_next_message(struct spi_master *master)
211 msg = list_entry(as->queue.next, struct spi_message, queue); 211 msg = list_entry(as->queue.next, struct spi_message, queue);
212 spi = msg->spi; 212 spi = msg->spi;
213 213
214 dev_dbg(master->cdev.dev, "start message %p for %s\n", 214 dev_dbg(master->dev.parent, "start message %p for %s\n",
215 msg, spi->dev.bus_id); 215 msg, spi->dev.bus_id);
216 216
217 /* select chip if it's not still active */ 217 /* select chip if it's not still active */
@@ -266,10 +266,10 @@ static void atmel_spi_dma_unmap_xfer(struct spi_master *master,
266 struct spi_transfer *xfer) 266 struct spi_transfer *xfer)
267{ 267{
268 if (xfer->tx_dma != INVALID_DMA_ADDRESS) 268 if (xfer->tx_dma != INVALID_DMA_ADDRESS)
269 dma_unmap_single(master->cdev.dev, xfer->tx_dma, 269 dma_unmap_single(master->dev.parent, xfer->tx_dma,
270 xfer->len, DMA_TO_DEVICE); 270 xfer->len, DMA_TO_DEVICE);
271 if (xfer->rx_dma != INVALID_DMA_ADDRESS) 271 if (xfer->rx_dma != INVALID_DMA_ADDRESS)
272 dma_unmap_single(master->cdev.dev, xfer->rx_dma, 272 dma_unmap_single(master->dev.parent, xfer->rx_dma,
273 xfer->len, DMA_FROM_DEVICE); 273 xfer->len, DMA_FROM_DEVICE);
274} 274}
275 275
@@ -285,7 +285,7 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,
285 list_del(&msg->queue); 285 list_del(&msg->queue);
286 msg->status = status; 286 msg->status = status;
287 287
288 dev_dbg(master->cdev.dev, 288 dev_dbg(master->dev.parent,
289 "xfer complete: %u bytes transferred\n", 289 "xfer complete: %u bytes transferred\n",
290 msg->actual_length); 290 msg->actual_length);
291 291
@@ -348,7 +348,7 @@ atmel_spi_interrupt(int irq, void *dev_id)
348 if (xfer->delay_usecs) 348 if (xfer->delay_usecs)
349 udelay(xfer->delay_usecs); 349 udelay(xfer->delay_usecs);
350 350
351 dev_warn(master->cdev.dev, "fifo overrun (%u/%u remaining)\n", 351 dev_warn(master->dev.parent, "fifo overrun (%u/%u remaining)\n",
352 spi_readl(as, TCR), spi_readl(as, RCR)); 352 spi_readl(as, TCR), spi_readl(as, RCR));
353 353
354 /* 354 /*
@@ -363,7 +363,7 @@ atmel_spi_interrupt(int irq, void *dev_id)
363 if (spi_readl(as, SR) & SPI_BIT(TXEMPTY)) 363 if (spi_readl(as, SR) & SPI_BIT(TXEMPTY))
364 break; 364 break;
365 if (!timeout) 365 if (!timeout)
366 dev_warn(master->cdev.dev, 366 dev_warn(master->dev.parent,
367 "timeout waiting for TXEMPTY"); 367 "timeout waiting for TXEMPTY");
368 while (spi_readl(as, SR) & SPI_BIT(RDRF)) 368 while (spi_readl(as, SR) & SPI_BIT(RDRF))
369 spi_readl(as, RDR); 369 spi_readl(as, RDR);
@@ -526,7 +526,7 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
526 struct atmel_spi *as; 526 struct atmel_spi *as;
527 struct spi_transfer *xfer; 527 struct spi_transfer *xfer;
528 unsigned long flags; 528 unsigned long flags;
529 struct device *controller = spi->master->cdev.dev; 529 struct device *controller = spi->master->dev.parent;
530 530
531 as = spi_master_get_devdata(spi->master); 531 as = spi_master_get_devdata(spi->master);
532 532
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index d2a4b2bdb07b..e9aba932f217 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -503,7 +503,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
503 INIT_LIST_HEAD(&mps->queue); 503 INIT_LIST_HEAD(&mps->queue);
504 504
505 mps->workqueue = create_singlethread_workqueue( 505 mps->workqueue = create_singlethread_workqueue(
506 master->cdev.dev->bus_id); 506 master->dev.parent->bus_id);
507 if (mps->workqueue == NULL) { 507 if (mps->workqueue == NULL) {
508 ret = -EBUSY; 508 ret = -EBUSY;
509 goto free_irq; 509 goto free_irq;
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 6b357cdb9ea3..3cdab131c4a9 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -645,7 +645,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
645 645
646 clk_enable(mcspi->ick); 646 clk_enable(mcspi->ick);
647 clk_enable(mcspi->fck); 647 clk_enable(mcspi->fck);
648 ret = omap2_mcspi_setup_transfer(spi, NULL); 648 ret = omap2_mcspi_setup_transfer(spi, NULL);
649 clk_disable(mcspi->fck); 649 clk_disable(mcspi->fck);
650 clk_disable(mcspi->ick); 650 clk_disable(mcspi->ick);
651 651
@@ -693,7 +693,6 @@ static void omap2_mcspi_work(struct work_struct *work)
693 struct spi_device *spi; 693 struct spi_device *spi;
694 struct spi_transfer *t = NULL; 694 struct spi_transfer *t = NULL;
695 int cs_active = 0; 695 int cs_active = 0;
696 struct omap2_mcspi_device_config *conf;
697 struct omap2_mcspi_cs *cs; 696 struct omap2_mcspi_cs *cs;
698 int par_override = 0; 697 int par_override = 0;
699 int status = 0; 698 int status = 0;
@@ -706,7 +705,6 @@ static void omap2_mcspi_work(struct work_struct *work)
706 spin_unlock_irq(&mcspi->lock); 705 spin_unlock_irq(&mcspi->lock);
707 706
708 spi = m->spi; 707 spi = m->spi;
709 conf = spi->controller_data;
710 cs = spi->controller_state; 708 cs = spi->controller_state;
711 709
712 omap2_mcspi_set_enable(spi, 1); 710 omap2_mcspi_set_enable(spi, 1);
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index d275c615a73e..8245b5153f30 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -481,7 +481,7 @@ static void uwire_off(struct uwire_spi *uwire)
481 spi_master_put(uwire->bitbang.master); 481 spi_master_put(uwire->bitbang.master);
482} 482}
483 483
484static int uwire_probe(struct platform_device *pdev) 484static int __init uwire_probe(struct platform_device *pdev)
485{ 485{
486 struct spi_master *master; 486 struct spi_master *master;
487 struct uwire_spi *uwire; 487 struct uwire_spi *uwire;
@@ -525,7 +525,7 @@ static int uwire_probe(struct platform_device *pdev)
525 return status; 525 return status;
526} 526}
527 527
528static int uwire_remove(struct platform_device *pdev) 528static int __exit uwire_remove(struct platform_device *pdev)
529{ 529{
530 struct uwire_spi *uwire = dev_get_drvdata(&pdev->dev); 530 struct uwire_spi *uwire = dev_get_drvdata(&pdev->dev);
531 int status; 531 int status;
@@ -543,8 +543,7 @@ static struct platform_driver uwire_driver = {
543 .bus = &platform_bus_type, 543 .bus = &platform_bus_type,
544 .owner = THIS_MODULE, 544 .owner = THIS_MODULE,
545 }, 545 },
546 .probe = uwire_probe, 546 .remove = __exit_p(uwire_remove),
547 .remove = uwire_remove,
548 // suspend ... unuse ck 547 // suspend ... unuse ck
549 // resume ... use ck 548 // resume ... use ck
550}; 549};
@@ -566,7 +565,7 @@ static int __init omap_uwire_init(void)
566 omap_writel(val | 0x00AAA000, OMAP730_IO_CONF_9); 565 omap_writel(val | 0x00AAA000, OMAP730_IO_CONF_9);
567 } 566 }
568 567
569 return platform_driver_register(&uwire_driver); 568 return platform_driver_probe(&uwire_driver, uwire_probe);
570} 569}
571 570
572static void __exit omap_uwire_exit(void) 571static void __exit omap_uwire_exit(void)
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index e51311b2da0b..5f3d808cbc29 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -26,7 +26,6 @@
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include <linux/errno.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
31 30
32#include <asm/io.h> 31#include <asm/io.h>
@@ -1230,7 +1229,7 @@ static void cleanup(struct spi_device *spi)
1230 kfree(chip); 1229 kfree(chip);
1231} 1230}
1232 1231
1233static int init_queue(struct driver_data *drv_data) 1232static int __init init_queue(struct driver_data *drv_data)
1234{ 1233{
1235 INIT_LIST_HEAD(&drv_data->queue); 1234 INIT_LIST_HEAD(&drv_data->queue);
1236 spin_lock_init(&drv_data->lock); 1235 spin_lock_init(&drv_data->lock);
@@ -1243,7 +1242,7 @@ static int init_queue(struct driver_data *drv_data)
1243 1242
1244 INIT_WORK(&drv_data->pump_messages, pump_messages); 1243 INIT_WORK(&drv_data->pump_messages, pump_messages);
1245 drv_data->workqueue = create_singlethread_workqueue( 1244 drv_data->workqueue = create_singlethread_workqueue(
1246 drv_data->master->cdev.dev->bus_id); 1245 drv_data->master->dev.parent->bus_id);
1247 if (drv_data->workqueue == NULL) 1246 if (drv_data->workqueue == NULL)
1248 return -EBUSY; 1247 return -EBUSY;
1249 1248
@@ -1318,7 +1317,7 @@ static int destroy_queue(struct driver_data *drv_data)
1318 return 0; 1317 return 0;
1319} 1318}
1320 1319
1321static int pxa2xx_spi_probe(struct platform_device *pdev) 1320static int __init pxa2xx_spi_probe(struct platform_device *pdev)
1322{ 1321{
1323 struct device *dev = &pdev->dev; 1322 struct device *dev = &pdev->dev;
1324 struct pxa2xx_spi_master *platform_info; 1323 struct pxa2xx_spi_master *platform_info;
@@ -1622,8 +1621,7 @@ static struct platform_driver driver = {
1622 .bus = &platform_bus_type, 1621 .bus = &platform_bus_type,
1623 .owner = THIS_MODULE, 1622 .owner = THIS_MODULE,
1624 }, 1623 },
1625 .probe = pxa2xx_spi_probe, 1624 .remove = pxa2xx_spi_remove,
1626 .remove = __devexit_p(pxa2xx_spi_remove),
1627 .shutdown = pxa2xx_spi_shutdown, 1625 .shutdown = pxa2xx_spi_shutdown,
1628 .suspend = pxa2xx_spi_suspend, 1626 .suspend = pxa2xx_spi_suspend,
1629 .resume = pxa2xx_spi_resume, 1627 .resume = pxa2xx_spi_resume,
@@ -1631,9 +1629,7 @@ static struct platform_driver driver = {
1631 1629
1632static int __init pxa2xx_spi_init(void) 1630static int __init pxa2xx_spi_init(void)
1633{ 1631{
1634 platform_driver_register(&driver); 1632 return platform_driver_probe(&driver, pxa2xx_spi_probe);
1635
1636 return 0;
1637} 1633}
1638module_init(pxa2xx_spi_init); 1634module_init(pxa2xx_spi_init);
1639 1635
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index bcb8dd5fb0b4..89769ce16f88 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -204,7 +204,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
204 struct spi_board_info *chip) 204 struct spi_board_info *chip)
205{ 205{
206 struct spi_device *proxy; 206 struct spi_device *proxy;
207 struct device *dev = master->cdev.dev; 207 struct device *dev = master->dev.parent;
208 int status; 208 int status;
209 209
210 /* NOTE: caller did any chip->bus_num checks necessary. 210 /* NOTE: caller did any chip->bus_num checks necessary.
@@ -239,7 +239,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
239 proxy->modalias = chip->modalias; 239 proxy->modalias = chip->modalias;
240 240
241 snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id, 241 snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id,
242 "%s.%u", master->cdev.class_id, 242 "%s.%u", master->dev.bus_id,
243 chip->chip_select); 243 chip->chip_select);
244 proxy->dev.parent = dev; 244 proxy->dev.parent = dev;
245 proxy->dev.bus = &spi_bus_type; 245 proxy->dev.bus = &spi_bus_type;
@@ -338,18 +338,18 @@ static void scan_boardinfo(struct spi_master *master)
338 338
339/*-------------------------------------------------------------------------*/ 339/*-------------------------------------------------------------------------*/
340 340
341static void spi_master_release(struct class_device *cdev) 341static void spi_master_release(struct device *dev)
342{ 342{
343 struct spi_master *master; 343 struct spi_master *master;
344 344
345 master = container_of(cdev, struct spi_master, cdev); 345 master = container_of(dev, struct spi_master, dev);
346 kfree(master); 346 kfree(master);
347} 347}
348 348
349static struct class spi_master_class = { 349static struct class spi_master_class = {
350 .name = "spi_master", 350 .name = "spi_master",
351 .owner = THIS_MODULE, 351 .owner = THIS_MODULE,
352 .release = spi_master_release, 352 .dev_release = spi_master_release,
353}; 353};
354 354
355 355
@@ -357,7 +357,7 @@ static struct class spi_master_class = {
357 * spi_alloc_master - allocate SPI master controller 357 * spi_alloc_master - allocate SPI master controller
358 * @dev: the controller, possibly using the platform_bus 358 * @dev: the controller, possibly using the platform_bus
359 * @size: how much zeroed driver-private data to allocate; the pointer to this 359 * @size: how much zeroed driver-private data to allocate; the pointer to this
360 * memory is in the class_data field of the returned class_device, 360 * memory is in the driver_data field of the returned device,
361 * accessible with spi_master_get_devdata(). 361 * accessible with spi_master_get_devdata().
362 * Context: can sleep 362 * Context: can sleep
363 * 363 *
@@ -383,9 +383,9 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
383 if (!master) 383 if (!master)
384 return NULL; 384 return NULL;
385 385
386 class_device_initialize(&master->cdev); 386 device_initialize(&master->dev);
387 master->cdev.class = &spi_master_class; 387 master->dev.class = &spi_master_class;
388 master->cdev.dev = get_device(dev); 388 master->dev.parent = get_device(dev);
389 spi_master_set_devdata(master, &master[1]); 389 spi_master_set_devdata(master, &master[1]);
390 390
391 return master; 391 return master;
@@ -415,7 +415,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master);
415int spi_register_master(struct spi_master *master) 415int spi_register_master(struct spi_master *master)
416{ 416{
417 static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1); 417 static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
418 struct device *dev = master->cdev.dev; 418 struct device *dev = master->dev.parent;
419 int status = -ENODEV; 419 int status = -ENODEV;
420 int dynamic = 0; 420 int dynamic = 0;
421 421
@@ -440,12 +440,12 @@ int spi_register_master(struct spi_master *master)
440 /* register the device, then userspace will see it. 440 /* register the device, then userspace will see it.
441 * registration fails if the bus ID is in use. 441 * registration fails if the bus ID is in use.
442 */ 442 */
443 snprintf(master->cdev.class_id, sizeof master->cdev.class_id, 443 snprintf(master->dev.bus_id, sizeof master->dev.bus_id,
444 "spi%u", master->bus_num); 444 "spi%u", master->bus_num);
445 status = class_device_add(&master->cdev); 445 status = device_add(&master->dev);
446 if (status < 0) 446 if (status < 0)
447 goto done; 447 goto done;
448 dev_dbg(dev, "registered master %s%s\n", master->cdev.class_id, 448 dev_dbg(dev, "registered master %s%s\n", master->dev.bus_id,
449 dynamic ? " (dynamic)" : ""); 449 dynamic ? " (dynamic)" : "");
450 450
451 /* populate children from any spi device tables */ 451 /* populate children from any spi device tables */
@@ -478,8 +478,8 @@ void spi_unregister_master(struct spi_master *master)
478{ 478{
479 int dummy; 479 int dummy;
480 480
481 dummy = device_for_each_child(master->cdev.dev, NULL, __unregister); 481 dummy = device_for_each_child(master->dev.parent, NULL, __unregister);
482 class_device_unregister(&master->cdev); 482 device_unregister(&master->dev);
483} 483}
484EXPORT_SYMBOL_GPL(spi_unregister_master); 484EXPORT_SYMBOL_GPL(spi_unregister_master);
485 485
@@ -495,13 +495,13 @@ EXPORT_SYMBOL_GPL(spi_unregister_master);
495 */ 495 */
496struct spi_master *spi_busnum_to_master(u16 bus_num) 496struct spi_master *spi_busnum_to_master(u16 bus_num)
497{ 497{
498 struct class_device *cdev; 498 struct device *dev;
499 struct spi_master *master = NULL; 499 struct spi_master *master = NULL;
500 struct spi_master *m; 500 struct spi_master *m;
501 501
502 down(&spi_master_class.sem); 502 down(&spi_master_class.sem);
503 list_for_each_entry(cdev, &spi_master_class.children, node) { 503 list_for_each_entry(dev, &spi_master_class.children, node) {
504 m = container_of(cdev, struct spi_master, cdev); 504 m = container_of(dev, struct spi_master, dev);
505 if (m->bus_num == bus_num) { 505 if (m->bus_num == bus_num) {
506 master = spi_master_get(m); 506 master = spi_master_get(m);
507 break; 507 break;
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index f540ed77a102..6cb71d74738f 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -39,7 +39,6 @@
39#include <linux/dma-mapping.h> 39#include <linux/dma-mapping.h>
40#include <linux/spi/spi.h> 40#include <linux/spi/spi.h>
41#include <linux/workqueue.h> 41#include <linux/workqueue.h>
42#include <linux/errno.h>
43#include <linux/delay.h> 42#include <linux/delay.h>
44 43
45#include <asm/io.h> 44#include <asm/io.h>
@@ -1107,7 +1106,7 @@ static inline int init_queue(struct driver_data *drv_data)
1107 /* init messages workqueue */ 1106 /* init messages workqueue */
1108 INIT_WORK(&drv_data->pump_messages, pump_messages); 1107 INIT_WORK(&drv_data->pump_messages, pump_messages);
1109 drv_data->workqueue = 1108 drv_data->workqueue =
1110 create_singlethread_workqueue(drv_data->master->cdev.dev->bus_id); 1109 create_singlethread_workqueue(drv_data->master->dev.parent->bus_id);
1111 if (drv_data->workqueue == NULL) 1110 if (drv_data->workqueue == NULL)
1112 return -EBUSY; 1111 return -EBUSY;
1113 1112
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index 0c85c984ccb4..81639c6be1c7 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -472,7 +472,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
472 /* this task is the only thing to touch the SPI bits */ 472 /* this task is the only thing to touch the SPI bits */
473 bitbang->busy = 0; 473 bitbang->busy = 0;
474 bitbang->workqueue = create_singlethread_workqueue( 474 bitbang->workqueue = create_singlethread_workqueue(
475 bitbang->master->cdev.dev->bus_id); 475 bitbang->master->dev.parent->bus_id);
476 if (bitbang->workqueue == NULL) { 476 if (bitbang->workqueue == NULL) {
477 status = -EBUSY; 477 status = -EBUSY;
478 goto err1; 478 goto err1;
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index bd9177f51de9..3b4650ae6f1a 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -1361,7 +1361,7 @@ static void cleanup(struct spi_device *spi)
1361 kfree(spi_get_ctldata(spi)); 1361 kfree(spi_get_ctldata(spi));
1362} 1362}
1363 1363
1364static int init_queue(struct driver_data *drv_data) 1364static int __init init_queue(struct driver_data *drv_data)
1365{ 1365{
1366 INIT_LIST_HEAD(&drv_data->queue); 1366 INIT_LIST_HEAD(&drv_data->queue);
1367 spin_lock_init(&drv_data->lock); 1367 spin_lock_init(&drv_data->lock);
@@ -1374,7 +1374,7 @@ static int init_queue(struct driver_data *drv_data)
1374 1374
1375 INIT_WORK(&drv_data->work, pump_messages); 1375 INIT_WORK(&drv_data->work, pump_messages);
1376 drv_data->workqueue = create_singlethread_workqueue( 1376 drv_data->workqueue = create_singlethread_workqueue(
1377 drv_data->master->cdev.dev->bus_id); 1377 drv_data->master->dev.parent->bus_id);
1378 if (drv_data->workqueue == NULL) 1378 if (drv_data->workqueue == NULL)
1379 return -EBUSY; 1379 return -EBUSY;
1380 1380
@@ -1444,7 +1444,7 @@ static int destroy_queue(struct driver_data *drv_data)
1444 return 0; 1444 return 0;
1445} 1445}
1446 1446
1447static int spi_imx_probe(struct platform_device *pdev) 1447static int __init spi_imx_probe(struct platform_device *pdev)
1448{ 1448{
1449 struct device *dev = &pdev->dev; 1449 struct device *dev = &pdev->dev;
1450 struct spi_imx_master *platform_info; 1450 struct spi_imx_master *platform_info;
@@ -1622,7 +1622,7 @@ err_no_mem:
1622 return status; 1622 return status;
1623} 1623}
1624 1624
1625static int __devexit spi_imx_remove(struct platform_device *pdev) 1625static int __exit spi_imx_remove(struct platform_device *pdev)
1626{ 1626{
1627 struct driver_data *drv_data = platform_get_drvdata(pdev); 1627 struct driver_data *drv_data = platform_get_drvdata(pdev);
1628 int irq; 1628 int irq;
@@ -1739,8 +1739,7 @@ static struct platform_driver driver = {
1739 .bus = &platform_bus_type, 1739 .bus = &platform_bus_type,
1740 .owner = THIS_MODULE, 1740 .owner = THIS_MODULE,
1741 }, 1741 },
1742 .probe = spi_imx_probe, 1742 .remove = __exit_p(spi_imx_remove),
1743 .remove = __devexit_p(spi_imx_remove),
1744 .shutdown = spi_imx_shutdown, 1743 .shutdown = spi_imx_shutdown,
1745 .suspend = spi_imx_suspend, 1744 .suspend = spi_imx_suspend,
1746 .resume = spi_imx_resume, 1745 .resume = spi_imx_resume,
@@ -1748,7 +1747,7 @@ static struct platform_driver driver = {
1748 1747
1749static int __init spi_imx_init(void) 1748static int __init spi_imx_init(void)
1750{ 1749{
1751 return platform_driver_register(&driver); 1750 return platform_driver_probe(&driver, spi_imx_probe);
1752} 1751}
1753module_init(spi_imx_init); 1752module_init(spi_imx_init);
1754 1753
diff --git a/drivers/spi/spi_lm70llp.c b/drivers/spi/spi_lm70llp.c
index 4ea68ac16115..39d8d8ad65c0 100644
--- a/drivers/spi/spi_lm70llp.c
+++ b/drivers/spi/spi_lm70llp.c
@@ -82,7 +82,7 @@ struct spi_lm70llp {
82 struct pardevice *pd; 82 struct pardevice *pd;
83 struct spi_device *spidev_lm70; 83 struct spi_device *spidev_lm70;
84 struct spi_board_info info; 84 struct spi_board_info info;
85 struct class_device *cdev; 85 //struct device *dev;
86}; 86};
87 87
88/* REVISIT : ugly global ; provides "exclusive open" facility */ 88/* REVISIT : ugly global ; provides "exclusive open" facility */
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 32cda77b31cd..4580b9cf625d 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -511,7 +511,7 @@ err:
511 return ret; 511 return ret;
512} 512}
513 513
514static int __devexit mpc83xx_spi_remove(struct platform_device *dev) 514static int __exit mpc83xx_spi_remove(struct platform_device *dev)
515{ 515{
516 struct mpc83xx_spi *mpc83xx_spi; 516 struct mpc83xx_spi *mpc83xx_spi;
517 struct spi_master *master; 517 struct spi_master *master;
@@ -529,8 +529,7 @@ static int __devexit mpc83xx_spi_remove(struct platform_device *dev)
529 529
530MODULE_ALIAS("mpc83xx_spi"); /* for platform bus hotplug */ 530MODULE_ALIAS("mpc83xx_spi"); /* for platform bus hotplug */
531static struct platform_driver mpc83xx_spi_driver = { 531static struct platform_driver mpc83xx_spi_driver = {
532 .probe = mpc83xx_spi_probe, 532 .remove = __exit_p(mpc83xx_spi_remove),
533 .remove = __devexit_p(mpc83xx_spi_remove),
534 .driver = { 533 .driver = {
535 .name = "mpc83xx_spi", 534 .name = "mpc83xx_spi",
536 }, 535 },
@@ -538,7 +537,7 @@ static struct platform_driver mpc83xx_spi_driver = {
538 537
539static int __init mpc83xx_spi_init(void) 538static int __init mpc83xx_spi_init(void)
540{ 539{
541 return platform_driver_register(&mpc83xx_spi_driver); 540 return platform_driver_probe(&mpc83xx_spi_driver, mpc83xx_spi_probe);
542} 541}
543 542
544static void __exit mpc83xx_spi_exit(void) 543static void __exit mpc83xx_spi_exit(void)
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index e9b683f7d7b3..89d6685a5ca4 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -233,7 +233,7 @@ static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
233 return IRQ_HANDLED; 233 return IRQ_HANDLED;
234} 234}
235 235
236static int s3c24xx_spi_probe(struct platform_device *pdev) 236static int __init s3c24xx_spi_probe(struct platform_device *pdev)
237{ 237{
238 struct s3c24xx_spi *hw; 238 struct s3c24xx_spi *hw;
239 struct spi_master *master; 239 struct spi_master *master;
@@ -382,7 +382,7 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
382 return err; 382 return err;
383} 383}
384 384
385static int s3c24xx_spi_remove(struct platform_device *dev) 385static int __exit s3c24xx_spi_remove(struct platform_device *dev)
386{ 386{
387 struct s3c24xx_spi *hw = platform_get_drvdata(dev); 387 struct s3c24xx_spi *hw = platform_get_drvdata(dev);
388 388
@@ -429,8 +429,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev)
429 429
430MODULE_ALIAS("s3c2410_spi"); /* for platform bus hotplug */ 430MODULE_ALIAS("s3c2410_spi"); /* for platform bus hotplug */
431static struct platform_driver s3c24xx_spidrv = { 431static struct platform_driver s3c24xx_spidrv = {
432 .probe = s3c24xx_spi_probe, 432 .remove = __exit_p(s3c24xx_spi_remove),
433 .remove = s3c24xx_spi_remove,
434 .suspend = s3c24xx_spi_suspend, 433 .suspend = s3c24xx_spi_suspend,
435 .resume = s3c24xx_spi_resume, 434 .resume = s3c24xx_spi_resume,
436 .driver = { 435 .driver = {
@@ -441,7 +440,7 @@ static struct platform_driver s3c24xx_spidrv = {
441 440
442static int __init s3c24xx_spi_init(void) 441static int __init s3c24xx_spi_init(void)
443{ 442{
444 return platform_driver_register(&s3c24xx_spidrv); 443 return platform_driver_probe(&s3c24xx_spidrv, s3c24xx_spi_probe);
445} 444}
446 445
447static void __exit s3c24xx_spi_exit(void) 446static void __exit s3c24xx_spi_exit(void)
diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c
index b7f4bb239eaf..cc5094f37dd3 100644
--- a/drivers/spi/spi_txx9.c
+++ b/drivers/spi/spi_txx9.c
@@ -400,7 +400,7 @@ static int __init txx9spi_probe(struct platform_device *dev)
400 goto exit; 400 goto exit;
401 } 401 }
402 402
403 c->workqueue = create_singlethread_workqueue(master->cdev.dev->bus_id); 403 c->workqueue = create_singlethread_workqueue(master->dev.parent->bus_id);
404 if (!c->workqueue) 404 if (!c->workqueue)
405 goto exit; 405 goto exit;
406 c->last_chipselect = -1; 406 c->last_chipselect = -1;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index d20cb545a6e4..60a8f55a0cc7 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1407,7 +1407,11 @@ fail:
1407 1407
1408 1408
1409/** 1409/**
1410 * Similar to usb_disconnect() 1410 * usb_deauthorize_device - deauthorize a device (usbcore-internal)
1411 * @usb_dev: USB device
1412 *
1413 * Move the USB device to a very basic state where interfaces are disabled
1414 * and the device is in fact unconfigured and unusable.
1411 * 1415 *
1412 * We share a lock (that we have) with device_del(), so we need to 1416 * We share a lock (that we have) with device_del(), so we need to
1413 * defer its call. 1417 * defer its call.
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 43722e5a49d1..b624320df903 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -1042,7 +1042,8 @@ sisusbcon_set_origin(struct vc_data *c)
1042 1042
1043/* Interface routine */ 1043/* Interface routine */
1044static int 1044static int
1045sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows) 1045sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows,
1046 unsigned int user)
1046{ 1047{
1047 struct sisusb_usb_data *sisusb; 1048 struct sisusb_usb_data *sisusb;
1048 int fh; 1049 int fh;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 5216c11d4dec..efe474e2cc3b 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -5,8 +5,9 @@
5menu "Graphics support" 5menu "Graphics support"
6 depends on HAS_IOMEM 6 depends on HAS_IOMEM
7 7
8source "drivers/video/backlight/Kconfig" 8source "drivers/char/agp/Kconfig"
9source "drivers/video/display/Kconfig" 9
10source "drivers/char/drm/Kconfig"
10 11
11config VGASTATE 12config VGASTATE
12 tristate 13 tristate
@@ -19,7 +20,7 @@ config VIDEO_OUTPUT_CONTROL
19 This framework adds support for low-level control of the video 20 This framework adds support for low-level control of the video
20 output switch. 21 output switch.
21 22
22config FB 23menuconfig FB
23 tristate "Support for frame buffer devices" 24 tristate "Support for frame buffer devices"
24 ---help--- 25 ---help---
25 The frame buffer device provides an abstraction for the graphics 26 The frame buffer device provides an abstraction for the graphics
@@ -103,6 +104,15 @@ config FB_CFB_IMAGEBLIT
103 blitting. This is used by drivers that don't provide their own 104 blitting. This is used by drivers that don't provide their own
104 (accelerated) version. 105 (accelerated) version.
105 106
107config FB_CFB_REV_PIXELS_IN_BYTE
108 bool
109 depends on FB
110 default n
111 ---help---
112 Allow generic frame-buffer functions to work on displays with 1, 2
113 and 4 bits per pixel depths which has opposite order of pixels in
114 byte order to bytes in long order.
115
106config FB_SYS_FILLRECT 116config FB_SYS_FILLRECT
107 tristate 117 tristate
108 depends on FB 118 depends on FB
@@ -535,6 +545,15 @@ config FB_VGA16
535 To compile this driver as a module, choose M here: the 545 To compile this driver as a module, choose M here: the
536 module will be called vga16fb. 546 module will be called vga16fb.
537 547
548config FB_BF54X_LQ043
549 tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)"
550 depends on FB && (BF54x)
551 select FB_CFB_FILLRECT
552 select FB_CFB_COPYAREA
553 select FB_CFB_IMAGEBLIT
554 help
555 This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD
556
538config FB_STI 557config FB_STI
539 tristate "HP STI frame buffer device support" 558 tristate "HP STI frame buffer device support"
540 depends on FB && PARISC 559 depends on FB && PARISC
@@ -592,6 +611,24 @@ config FB_TGA
592 611
593 Say Y if you have one of those. 612 Say Y if you have one of those.
594 613
614config FB_UVESA
615 tristate "Userspace VESA VGA graphics support"
616 depends on FB && CONNECTOR
617 select FB_CFB_FILLRECT
618 select FB_CFB_COPYAREA
619 select FB_CFB_IMAGEBLIT
620 select FB_MODE_HELPERS
621 help
622 This is the frame buffer driver for generic VBE 2.0 compliant
623 graphic cards. It can also take advantage of VBE 3.0 features,
624 such as refresh rate adjustment.
625
626 This driver generally provides more features than vesafb but
627 requires a userspace helper application called 'v86d'. See
628 <file:Documentation/fb/uvesafb.txt> for more information.
629
630 If unsure, say N.
631
595config FB_VESA 632config FB_VESA
596 bool "VESA VGA graphics support" 633 bool "VESA VGA graphics support"
597 depends on (FB = y) && X86 634 depends on (FB = y) && X86
@@ -1625,7 +1662,7 @@ config FB_PMAG_BA
1625 1662
1626config FB_PMAGB_B 1663config FB_PMAGB_B
1627 tristate "PMAGB-B TURBOchannel framebuffer support" 1664 tristate "PMAGB-B TURBOchannel framebuffer support"
1628 depends on TC 1665 depends on FB && TC
1629 select FB_CFB_FILLRECT 1666 select FB_CFB_FILLRECT
1630 select FB_CFB_COPYAREA 1667 select FB_CFB_COPYAREA
1631 select FB_CFB_IMAGEBLIT 1668 select FB_CFB_IMAGEBLIT
@@ -1793,7 +1830,7 @@ config FB_PNX4008_DUM_RGB
1793 1830
1794config FB_IBM_GXT4500 1831config FB_IBM_GXT4500
1795 tristate "Framebuffer support for IBM GXT4500P adaptor" 1832 tristate "Framebuffer support for IBM GXT4500P adaptor"
1796 depends on PPC 1833 depends on FB && PPC
1797 select FB_CFB_FILLRECT 1834 select FB_CFB_FILLRECT
1798 select FB_CFB_COPYAREA 1835 select FB_CFB_COPYAREA
1799 select FB_CFB_IMAGEBLIT 1836 select FB_CFB_IMAGEBLIT
@@ -1833,10 +1870,6 @@ config FB_XILINX
1833 framebuffer. ML300 carries a 640*480 LCD display on the board, 1870 framebuffer. ML300 carries a 640*480 LCD display on the board,
1834 ML403 uses a standard DB15 VGA connector. 1871 ML403 uses a standard DB15 VGA connector.
1835 1872
1836if ARCH_OMAP
1837 source "drivers/video/omap/Kconfig"
1838endif
1839
1840config FB_VIRTUAL 1873config FB_VIRTUAL
1841 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 1874 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
1842 depends on FB 1875 depends on FB
@@ -1860,6 +1893,13 @@ config FB_VIRTUAL
1860 1893
1861 If unsure, say N. 1894 If unsure, say N.
1862 1895
1896if ARCH_OMAP
1897 source "drivers/video/omap/Kconfig"
1898endif
1899
1900source "drivers/video/backlight/Kconfig"
1901source "drivers/video/display/Kconfig"
1902
1863if VT 1903if VT
1864 source "drivers/video/console/Kconfig" 1904 source "drivers/video/console/Kconfig"
1865endif 1905endif
@@ -1869,4 +1909,3 @@ if FB || SGI_NEWPORT_CONSOLE
1869endif 1909endif
1870 1910
1871endmenu 1911endmenu
1872
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 06eec7b182b7..59d6c45a910d 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -115,10 +115,12 @@ obj-$(CONFIG_FB_XILINX) += xilinxfb.o
115obj-$(CONFIG_FB_OMAP) += omap/ 115obj-$(CONFIG_FB_OMAP) += omap/
116 116
117# Platform or fallback drivers go here 117# Platform or fallback drivers go here
118obj-$(CONFIG_FB_UVESA) += uvesafb.o
118obj-$(CONFIG_FB_VESA) += vesafb.o 119obj-$(CONFIG_FB_VESA) += vesafb.o
119obj-$(CONFIG_FB_IMAC) += imacfb.o 120obj-$(CONFIG_FB_IMAC) += imacfb.o
120obj-$(CONFIG_FB_VGA16) += vga16fb.o 121obj-$(CONFIG_FB_VGA16) += vga16fb.o
121obj-$(CONFIG_FB_OF) += offb.o 122obj-$(CONFIG_FB_OF) += offb.o
123obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
122 124
123# the test framebuffer is last 125# the test framebuffer is last
124obj-$(CONFIG_FB_VIRTUAL) += vfb.o 126obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 1a849b870bcc..f2e243c353f9 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -52,7 +52,7 @@
52#include <linux/init.h> 52#include <linux/init.h>
53#include <linux/ioport.h> 53#include <linux/ioport.h>
54 54
55#include <asm/uaccess.h> 55#include <linux/uaccess.h>
56#include <asm/system.h> 56#include <asm/system.h>
57#include <asm/irq.h> 57#include <asm/irq.h>
58#include <asm/amigahw.h> 58#include <asm/amigahw.h>
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index db15baca3f7b..c3431691c9f2 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -48,7 +48,7 @@
48#include <linux/arcfb.h> 48#include <linux/arcfb.h>
49#include <linux/platform_device.h> 49#include <linux/platform_device.h>
50 50
51#include <asm/uaccess.h> 51#include <linux/uaccess.h>
52 52
53#define floor8(a) (a&(~0x07)) 53#define floor8(a) (a&(~0x07))
54#define floorXres(a,xres) (a&(~(xres - 1))) 54#define floorXres(a,xres) (a&(~(xres - 1)))
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 0038a0541c7e..5d4fbaa53a6c 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -58,7 +58,7 @@
58#include <linux/interrupt.h> 58#include <linux/interrupt.h>
59 59
60#include <asm/setup.h> 60#include <asm/setup.h>
61#include <asm/uaccess.h> 61#include <linux/uaccess.h>
62#include <asm/pgtable.h> 62#include <asm/pgtable.h>
63#include <asm/irq.h> 63#include <asm/irq.h>
64#include <asm/io.h> 64#include <asm/io.h>
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h
index dca2eb8f2dde..3e9d28bcd9f8 100644
--- a/drivers/video/aty/ati_ids.h
+++ b/drivers/video/aty/ati_ids.h
@@ -188,6 +188,7 @@
188#define PCI_CHIP_MACH64VT 0x5654 188#define PCI_CHIP_MACH64VT 0x5654
189#define PCI_CHIP_MACH64VU 0x5655 189#define PCI_CHIP_MACH64VU 0x5655
190#define PCI_CHIP_MACH64VV 0x5656 190#define PCI_CHIP_MACH64VV 0x5656
191#define PCI_CHIP_RC410_5A62 0x5A62
191#define PCI_CHIP_RS300_5834 0x5834 192#define PCI_CHIP_RS300_5834 0x5834
192#define PCI_CHIP_RS300_5835 0x5835 193#define PCI_CHIP_RS300_5835 0x5835
193#define PCI_CHIP_RS300_5836 0x5836 194#define PCI_CHIP_RS300_5836 0x5836
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index cfcbe37d2d70..cbd3308b6690 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -56,7 +56,7 @@
56#include <linux/vmalloc.h> 56#include <linux/vmalloc.h>
57#include <linux/delay.h> 57#include <linux/delay.h>
58#include <linux/interrupt.h> 58#include <linux/interrupt.h>
59#include <asm/uaccess.h> 59#include <linux/uaccess.h>
60#include <linux/fb.h> 60#include <linux/fb.h>
61#include <linux/init.h> 61#include <linux/init.h>
62#include <linux/pci.h> 62#include <linux/pci.h>
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
index dc62f8e282b4..7691e73823d3 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/aty/atyfb.h
@@ -126,6 +126,7 @@ union aty_pll {
126 */ 126 */
127 127
128struct atyfb_par { 128struct atyfb_par {
129 u32 pseudo_palette[16];
129 struct { u8 red, green, blue; } palette[256]; 130 struct { u8 red, green, blue; } palette[256];
130 const struct aty_dac_ops *dac_ops; 131 const struct aty_dac_ops *dac_ops;
131 const struct aty_pll_ops *pll_ops; 132 const struct aty_pll_ops *pll_ops;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index bc6f0096aa04..abe0c435a664 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -68,7 +68,7 @@
68#include <linux/backlight.h> 68#include <linux/backlight.h>
69 69
70#include <asm/io.h> 70#include <asm/io.h>
71#include <asm/uaccess.h> 71#include <linux/uaccess.h>
72 72
73#include <video/mach64.h> 73#include <video/mach64.h>
74#include "atyfb.h" 74#include "atyfb.h"
@@ -541,8 +541,6 @@ static char ram_off[] __devinitdata = "OFF";
541#endif /* CONFIG_FB_ATY_CT */ 541#endif /* CONFIG_FB_ATY_CT */
542 542
543 543
544static u32 pseudo_palette[16];
545
546#ifdef CONFIG_FB_ATY_GX 544#ifdef CONFIG_FB_ATY_GX
547static char *aty_gx_ram[8] __devinitdata = { 545static char *aty_gx_ram[8] __devinitdata = {
548 ram_dram, ram_vram, ram_vram, ram_dram, 546 ram_dram, ram_vram, ram_vram, ram_dram,
@@ -2577,7 +2575,7 @@ static int __devinit aty_init(struct fb_info *info)
2577#endif 2575#endif
2578 2576
2579 info->fbops = &atyfb_ops; 2577 info->fbops = &atyfb_ops;
2580 info->pseudo_palette = pseudo_palette; 2578 info->pseudo_palette = par->pseudo_palette;
2581 info->flags = FBINFO_DEFAULT | 2579 info->flags = FBINFO_DEFAULT |
2582 FBINFO_HWACCEL_IMAGEBLIT | 2580 FBINFO_HWACCEL_IMAGEBLIT |
2583 FBINFO_HWACCEL_FILLRECT | 2581 FBINFO_HWACCEL_FILLRECT |
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index fe2c6ad01a8d..faf95da8fcbc 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -8,7 +8,6 @@
8#include <linux/string.h> 8#include <linux/string.h>
9 9
10#include <asm/io.h> 10#include <asm/io.h>
11#include <asm/uaccess.h>
12 11
13#ifdef __sparc__ 12#ifdef __sparc__
14#include <asm/fbio.h> 13#include <asm/fbio.h>
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 4b747bdaeea6..1e32b3d13f2e 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -69,7 +69,7 @@
69#include <linux/device.h> 69#include <linux/device.h>
70 70
71#include <asm/io.h> 71#include <asm/io.h>
72#include <asm/uaccess.h> 72#include <linux/uaccess.h>
73 73
74#ifdef CONFIG_PPC_OF 74#ifdef CONFIG_PPC_OF
75 75
@@ -145,6 +145,8 @@ static struct pci_device_id radeonfb_pci_table[] = {
145 /* 9000/Pro */ 145 /* 9000/Pro */
146 CHIP_DEF(PCI_CHIP_RV250_If, RV250, CHIP_HAS_CRTC2), 146 CHIP_DEF(PCI_CHIP_RV250_If, RV250, CHIP_HAS_CRTC2),
147 CHIP_DEF(PCI_CHIP_RV250_Ig, RV250, CHIP_HAS_CRTC2), 147 CHIP_DEF(PCI_CHIP_RV250_Ig, RV250, CHIP_HAS_CRTC2),
148
149 CHIP_DEF(PCI_CHIP_RC410_5A62, RC410, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
148 /* Mobility 9100 IGP (U3) */ 150 /* Mobility 9100 IGP (U3) */
149 CHIP_DEF(PCI_CHIP_RS300_5835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), 151 CHIP_DEF(PCI_CHIP_RS300_5835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
150 CHIP_DEF(PCI_CHIP_RS350_7835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), 152 CHIP_DEF(PCI_CHIP_RS350_7835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
@@ -1999,6 +2001,7 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
1999 if ((rinfo->family == CHIP_FAMILY_RS100) || 2001 if ((rinfo->family == CHIP_FAMILY_RS100) ||
2000 (rinfo->family == CHIP_FAMILY_RS200) || 2002 (rinfo->family == CHIP_FAMILY_RS200) ||
2001 (rinfo->family == CHIP_FAMILY_RS300) || 2003 (rinfo->family == CHIP_FAMILY_RS300) ||
2004 (rinfo->family == CHIP_FAMILY_RC410) ||
2002 (rinfo->family == CHIP_FAMILY_RS480) ) { 2005 (rinfo->family == CHIP_FAMILY_RS480) ) {
2003 u32 tom = INREG(NB_TOM); 2006 u32 tom = INREG(NB_TOM);
2004 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); 2007 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 7c922c7b460b..5eac1ce52e72 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -48,6 +48,7 @@ enum radeon_family {
48 CHIP_FAMILY_RV350, 48 CHIP_FAMILY_RV350,
49 CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ 49 CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
50 CHIP_FAMILY_R420, /* R420/R423/M18 */ 50 CHIP_FAMILY_R420, /* R420/R423/M18 */
51 CHIP_FAMILY_RC410,
51 CHIP_FAMILY_RS480, 52 CHIP_FAMILY_RS480,
52 CHIP_FAMILY_LAST, 53 CHIP_FAMILY_LAST,
53}; 54};
@@ -66,7 +67,8 @@ enum radeon_family {
66 ((rinfo)->family == CHIP_FAMILY_R350) || \ 67 ((rinfo)->family == CHIP_FAMILY_R350) || \
67 ((rinfo)->family == CHIP_FAMILY_RV380) || \ 68 ((rinfo)->family == CHIP_FAMILY_RV380) || \
68 ((rinfo)->family == CHIP_FAMILY_R420) || \ 69 ((rinfo)->family == CHIP_FAMILY_R420) || \
69 ((rinfo)->family == CHIP_FAMILY_RS480) ) 70 ((rinfo)->family == CHIP_FAMILY_RC410) || \
71 ((rinfo)->family == CHIP_FAMILY_RS480))
70 72
71/* 73/*
72 * Chip flags 74 * Chip flags
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index 92e201e81fbd..26add8898605 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -36,7 +36,6 @@
36#include <linux/backlight.h> 36#include <linux/backlight.h>
37#include <linux/lcd.h> 37#include <linux/lcd.h>
38#include <linux/pci.h> 38#include <linux/pci.h>
39#include <asm/uaccess.h>
40 39
41/* The LVDS- and panel power controls sits on the 40/* The LVDS- and panel power controls sits on the
42 * GPIO port of the ISA bridge. 41 * GPIO port of the ISA bridge.
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
index 836ab4df0ef2..15fb4d58b5bc 100644
--- a/drivers/video/backlight/progear_bl.c
+++ b/drivers/video/backlight/progear_bl.c
@@ -23,7 +23,6 @@
23#include <linux/fb.h> 23#include <linux/fb.h>
24#include <linux/backlight.h> 24#include <linux/backlight.h>
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <asm/uaccess.h>
27 26
28#define PMU_LPCR 0xB0 27#define PMU_LPCR 0xB0
29#define SB_MPS1 0x61 28#define SB_MPS1 0x61
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
new file mode 100644
index 000000000000..74d11c318987
--- /dev/null
+++ b/drivers/video/bf54x-lq043fb.c
@@ -0,0 +1,786 @@
1/*
2 * File: drivers/video/bf54x-lq043.c
3 * Based on:
4 * Author: Michael Hennerich <hennerich@blackfin.uclinux.org>
5 *
6 * Created:
7 * Description: ADSP-BF54x Framebufer driver
8 *
9 *
10 * Modified:
11 * Copyright 2004-2007 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/errno.h>
34#include <linux/string.h>
35#include <linux/mm.h>
36#include <linux/tty.h>
37#include <linux/slab.h>
38#include <linux/delay.h>
39#include <linux/fb.h>
40#include <linux/ioport.h>
41#include <linux/init.h>
42#include <linux/types.h>
43#include <linux/interrupt.h>
44#include <linux/sched.h>
45#include <linux/timer.h>
46#include <linux/device.h>
47#include <linux/backlight.h>
48#include <linux/lcd.h>
49#include <linux/spinlock.h>
50#include <linux/dma-mapping.h>
51#include <linux/platform_device.h>
52
53#include <asm/blackfin.h>
54#include <asm/irq.h>
55#include <asm/dpmc.h>
56#include <asm/dma-mapping.h>
57#include <asm/dma.h>
58#include <asm/gpio.h>
59#include <asm/portmux.h>
60
61#include <asm/mach/bf54x-lq043.h>
62
63#define NO_BL_SUPPORT
64
65#define DRIVER_NAME "bf54x-lq043"
66static char driver_name[] = DRIVER_NAME;
67
68#define BFIN_LCD_NBR_PALETTE_ENTRIES 256
69
70#define EPPI0_18 {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, \
71 P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, \
72 P_PPI0_D11, P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15, P_PPI0_D16, P_PPI0_D17, 0}
73
74#define EPPI0_24 {P_PPI0_D18, P_PPI0_D19, P_PPI0_D20, P_PPI0_D21, P_PPI0_D22, P_PPI0_D23, 0}
75
76struct bfin_bf54xfb_info {
77 struct fb_info *fb;
78 struct device *dev;
79
80 struct bfin_bf54xfb_mach_info *mach_info;
81
82 unsigned char *fb_buffer; /* RGB Buffer */
83
84 dma_addr_t dma_handle;
85 int lq043_mmap;
86 int lq043_open_cnt;
87 int irq;
88 spinlock_t lock; /* lock */
89};
90
91static int nocursor;
92module_param(nocursor, int, 0644);
93MODULE_PARM_DESC(nocursor, "cursor enable/disable");
94
95static int outp_rgb666;
96module_param(outp_rgb666, int, 0);
97MODULE_PARM_DESC(outp_rgb666, "Output 18-bit RGB666");
98
99#define LCD_X_RES 480 /*Horizontal Resolution */
100#define LCD_Y_RES 272 /* Vertical Resolution */
101
102#define LCD_BPP 24 /* Bit Per Pixel */
103#define DMA_BUS_SIZE 32
104
105/* -- Horizontal synchronizing --
106 *
107 * Timing characteristics taken from the SHARP LQ043T1DG01 datasheet
108 * (LCY-W-06602A Page 9 of 22)
109 *
110 * Clock Frequency 1/Tc Min 7.83 Typ 9.00 Max 9.26 MHz
111 *
112 * Period TH - 525 - Clock
113 * Pulse width THp - 41 - Clock
114 * Horizontal period THd - 480 - Clock
115 * Back porch THb - 2 - Clock
116 * Front porch THf - 2 - Clock
117 *
118 * -- Vertical synchronizing --
119 * Period TV - 286 - Line
120 * Pulse width TVp - 10 - Line
121 * Vertical period TVd - 272 - Line
122 * Back porch TVb - 2 - Line
123 * Front porch TVf - 2 - Line
124 */
125
126#define LCD_CLK (8*1000*1000) /* 8MHz */
127
128/* # active data to transfer after Horizontal Delay clock */
129#define EPPI_HCOUNT LCD_X_RES
130
131/* # active lines to transfer after Vertical Delay clock */
132#define EPPI_VCOUNT LCD_Y_RES
133
134/* Samples per Line = 480 (active data) + 45 (padding) */
135#define EPPI_LINE 525
136
137/* Lines per Frame = 272 (active data) + 14 (padding) */
138#define EPPI_FRAME 286
139
140/* FS1 (Hsync) Width (Typical)*/
141#define EPPI_FS1W_HBL 41
142
143/* FS1 (Hsync) Period (Typical) */
144#define EPPI_FS1P_AVPL EPPI_LINE
145
146/* Horizontal Delay clock after assertion of Hsync (Typical) */
147#define EPPI_HDELAY 43
148
149/* FS2 (Vsync) Width = FS1 (Hsync) Period * 10 */
150#define EPPI_FS2W_LVB (EPPI_LINE * 10)
151
152 /* FS2 (Vsync) Period = FS1 (Hsync) Period * Lines per Frame */
153#define EPPI_FS2P_LAVF (EPPI_LINE * EPPI_FRAME)
154
155/* Vertical Delay after assertion of Vsync (2 Lines) */
156#define EPPI_VDELAY 12
157
158#define EPPI_CLIP 0xFF00FF00
159
160/* EPPI Control register configuration value for RGB out
161 * - EPPI as Output
162 * GP 2 frame sync mode,
163 * Internal Clock generation disabled, Internal FS generation enabled,
164 * Receives samples on EPPI_CLK raising edge, Transmits samples on EPPI_CLK falling edge,
165 * FS1 & FS2 are active high,
166 * DLEN = 6 (24 bits for RGB888 out) or 5 (18 bits for RGB666 out)
167 * DMA Unpacking disabled when RGB Formating is enabled, otherwise DMA unpacking enabled
168 * Swapping Enabled,
169 * One (DMA) Channel Mode,
170 * RGB Formatting Enabled for RGB666 output, disabled for RGB888 output
171 * Regular watermark - when FIFO is 100% full,
172 * Urgent watermark - when FIFO is 75% full
173 */
174
175#define EPPI_CONTROL (0x20136E2E | SWAPEN)
176
177static inline u16 get_eppi_clkdiv(u32 target_ppi_clk)
178{
179 u32 sclk = get_sclk();
180
181 /* EPPI_CLK = (SCLK) / (2 * (EPPI_CLKDIV[15:0] + 1)) */
182
183 return (((sclk / target_ppi_clk) / 2) - 1);
184}
185
186static void config_ppi(struct bfin_bf54xfb_info *fbi)
187{
188
189 u16 eppi_clkdiv = get_eppi_clkdiv(LCD_CLK);
190
191 bfin_write_EPPI0_FS1W_HBL(EPPI_FS1W_HBL);
192 bfin_write_EPPI0_FS1P_AVPL(EPPI_FS1P_AVPL);
193 bfin_write_EPPI0_FS2W_LVB(EPPI_FS2W_LVB);
194 bfin_write_EPPI0_FS2P_LAVF(EPPI_FS2P_LAVF);
195 bfin_write_EPPI0_CLIP(EPPI_CLIP);
196
197 bfin_write_EPPI0_FRAME(EPPI_FRAME);
198 bfin_write_EPPI0_LINE(EPPI_LINE);
199
200 bfin_write_EPPI0_HCOUNT(EPPI_HCOUNT);
201 bfin_write_EPPI0_HDELAY(EPPI_HDELAY);
202 bfin_write_EPPI0_VCOUNT(EPPI_VCOUNT);
203 bfin_write_EPPI0_VDELAY(EPPI_VDELAY);
204
205 bfin_write_EPPI0_CLKDIV(eppi_clkdiv);
206
207/*
208 * DLEN = 6 (24 bits for RGB888 out) or 5 (18 bits for RGB666 out)
209 * RGB Formatting Enabled for RGB666 output, disabled for RGB888 output
210 */
211 if (outp_rgb666)
212 bfin_write_EPPI0_CONTROL((EPPI_CONTROL & ~DLENGTH) | DLEN_18 |
213 RGB_FMT_EN);
214 else
215 bfin_write_EPPI0_CONTROL(((EPPI_CONTROL & ~DLENGTH) | DLEN_24) &
216 ~RGB_FMT_EN);
217
218
219}
220
221static int config_dma(struct bfin_bf54xfb_info *fbi)
222{
223
224 set_dma_config(CH_EPPI0,
225 set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO,
226 INTR_DISABLE, DIMENSION_2D,
227 DATA_SIZE_32));
228 set_dma_x_count(CH_EPPI0, (LCD_X_RES * LCD_BPP) / DMA_BUS_SIZE);
229 set_dma_x_modify(CH_EPPI0, DMA_BUS_SIZE / 8);
230 set_dma_y_count(CH_EPPI0, LCD_Y_RES);
231 set_dma_y_modify(CH_EPPI0, DMA_BUS_SIZE / 8);
232 set_dma_start_addr(CH_EPPI0, (unsigned long)fbi->fb_buffer);
233
234 return 0;
235}
236
237static int request_ports(struct bfin_bf54xfb_info *fbi)
238{
239
240 u16 eppi_req_18[] = EPPI0_18;
241 u16 disp = fbi->mach_info->disp;
242
243 if (gpio_request(disp, NULL)) {
244 printk(KERN_ERR "Requesting GPIO %d faild\n", disp);
245 return -EFAULT;
246 }
247
248 if (peripheral_request_list(eppi_req_18, DRIVER_NAME)) {
249 printk(KERN_ERR "Requesting Peripherals faild\n");
250 gpio_free(disp);
251 return -EFAULT;
252 }
253
254 if (!outp_rgb666) {
255
256 u16 eppi_req_24[] = EPPI0_24;
257
258 if (peripheral_request_list(eppi_req_24, DRIVER_NAME)) {
259 printk(KERN_ERR "Requesting Peripherals faild\n");
260 peripheral_free_list(eppi_req_18);
261 gpio_free(disp);
262 return -EFAULT;
263 }
264 }
265
266 gpio_direction_output(disp);
267 gpio_set_value(disp, 1);
268
269 return 0;
270}
271
272static void free_ports(struct bfin_bf54xfb_info *fbi)
273{
274
275 u16 eppi_req_18[] = EPPI0_18;
276
277 gpio_free(fbi->mach_info->disp);
278
279 peripheral_free_list(eppi_req_18);
280
281 if (!outp_rgb666) {
282 u16 eppi_req_24[] = EPPI0_24;
283 peripheral_free_list(eppi_req_24);
284 }
285}
286
287static int bfin_bf54x_fb_open(struct fb_info *info, int user)
288{
289 struct bfin_bf54xfb_info *fbi = info->par;
290
291 spin_lock(&fbi->lock);
292 fbi->lq043_open_cnt++;
293
294 if (fbi->lq043_open_cnt <= 1) {
295
296 bfin_write_EPPI0_CONTROL(0);
297 SSYNC();
298
299 config_dma(fbi);
300 config_ppi(fbi);
301
302 /* start dma */
303 enable_dma(CH_EPPI0);
304 bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
305 }
306
307 spin_unlock(&fbi->lock);
308
309 return 0;
310}
311
312static int bfin_bf54x_fb_release(struct fb_info *info, int user)
313{
314 struct bfin_bf54xfb_info *fbi = info->par;
315
316 spin_lock(&fbi->lock);
317
318 fbi->lq043_open_cnt--;
319 fbi->lq043_mmap = 0;
320
321 if (fbi->lq043_open_cnt <= 0) {
322
323 bfin_write_EPPI0_CONTROL(0);
324 SSYNC();
325 disable_dma(CH_EPPI0);
326 memset(fbi->fb_buffer, 0, info->fix.smem_len);
327 }
328
329 spin_unlock(&fbi->lock);
330
331 return 0;
332}
333
334static int bfin_bf54x_fb_check_var(struct fb_var_screeninfo *var,
335 struct fb_info *info)
336{
337
338 if (var->bits_per_pixel != LCD_BPP) {
339 pr_debug("%s: depth not supported: %u BPP\n", __FUNCTION__,
340 var->bits_per_pixel);
341 return -EINVAL;
342 }
343
344 if (info->var.xres != var->xres || info->var.yres != var->yres ||
345 info->var.xres_virtual != var->xres_virtual ||
346 info->var.yres_virtual != var->yres_virtual) {
347 pr_debug("%s: Resolution not supported: X%u x Y%u \n",
348 __FUNCTION__, var->xres, var->yres);
349 return -EINVAL;
350 }
351
352 /*
353 * Memory limit
354 */
355
356 if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) {
357 pr_debug("%s: Memory Limit requested yres_virtual = %u\n",
358 __FUNCTION__, var->yres_virtual);
359 return -ENOMEM;
360 }
361
362 return 0;
363}
364
365static int bfin_bf54x_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
366{
367
368 struct bfin_bf54xfb_info *fbi = info->par;
369
370 if (fbi->lq043_mmap)
371 return -1;
372
373 spin_lock(&fbi->lock);
374 fbi->lq043_mmap = 1;
375 spin_unlock(&fbi->lock);
376
377 vma->vm_start = (unsigned long)(fbi->fb_buffer);
378
379 vma->vm_end = vma->vm_start + info->fix.smem_len;
380 /* For those who don't understand how mmap works, go read
381 * Documentation/nommu-mmap.txt.
382 * For those that do, you will know that the VM_MAYSHARE flag
383 * must be set in the vma->vm_flags structure on noMMU
384 * Other flags can be set, and are documented in
385 * include/linux/mm.h
386 */
387 vma->vm_flags |= VM_MAYSHARE;
388
389 return 0;
390}
391
392int bfin_bf54x_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
393{
394 if (nocursor)
395 return 0;
396 else
397 return -EINVAL; /* just to force soft_cursor() call */
398}
399
400static int bfin_bf54x_fb_setcolreg(u_int regno, u_int red, u_int green,
401 u_int blue, u_int transp,
402 struct fb_info *info)
403{
404 if (regno >= BFIN_LCD_NBR_PALETTE_ENTRIES)
405 return -EINVAL;
406
407 if (info->var.grayscale) {
408 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
409 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
410 }
411
412 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
413
414 u32 value;
415 /* Place color in the pseudopalette */
416 if (regno > 16)
417 return -EINVAL;
418
419 red >>= (16 - info->var.red.length);
420 green >>= (16 - info->var.green.length);
421 blue >>= (16 - info->var.blue.length);
422
423 value = (red << info->var.red.offset) |
424 (green << info->var.green.offset) |
425 (blue << info->var.blue.offset);
426 value &= 0xFFFFFF;
427
428 ((u32 *) (info->pseudo_palette))[regno] = value;
429
430 }
431
432 return 0;
433}
434
435static struct fb_ops bfin_bf54x_fb_ops = {
436 .owner = THIS_MODULE,
437 .fb_open = bfin_bf54x_fb_open,
438 .fb_release = bfin_bf54x_fb_release,
439 .fb_check_var = bfin_bf54x_fb_check_var,
440 .fb_fillrect = cfb_fillrect,
441 .fb_copyarea = cfb_copyarea,
442 .fb_imageblit = cfb_imageblit,
443 .fb_mmap = bfin_bf54x_fb_mmap,
444 .fb_cursor = bfin_bf54x_fb_cursor,
445 .fb_setcolreg = bfin_bf54x_fb_setcolreg,
446};
447
448#ifndef NO_BL_SUPPORT
449static int bl_get_brightness(struct backlight_device *bd)
450{
451 return 0;
452}
453
454static struct backlight_ops bfin_lq043fb_bl_ops = {
455 .get_brightness = bl_get_brightness,
456};
457
458static struct backlight_device *bl_dev;
459
460static int bfin_lcd_get_power(struct lcd_device *dev)
461{
462 return 0;
463}
464
465static int bfin_lcd_set_power(struct lcd_device *dev, int power)
466{
467 return 0;
468}
469
470static int bfin_lcd_get_contrast(struct lcd_device *dev)
471{
472 return 0;
473}
474
475static int bfin_lcd_set_contrast(struct lcd_device *dev, int contrast)
476{
477
478 return 0;
479}
480
481static int bfin_lcd_check_fb(struct fb_info *fi)
482{
483 if (!fi || (fi == &bfin_bf54x_fb))
484 return 1;
485 return 0;
486}
487
488static struct lcd_ops bfin_lcd_ops = {
489 .get_power = bfin_lcd_get_power,
490 .set_power = bfin_lcd_set_power,
491 .get_contrast = bfin_lcd_get_contrast,
492 .set_contrast = bfin_lcd_set_contrast,
493 .check_fb = bfin_lcd_check_fb,
494};
495
496static struct lcd_device *lcd_dev;
497#endif
498
499static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id)
500{
501
502 /*struct bfin_bf54xfb_info *info = (struct bfin_bf54xfb_info *)dev_id;*/
503
504 u16 status = bfin_read_EPPI0_STATUS();
505
506 bfin_write_EPPI0_STATUS(0xFFFF);
507
508 if (status) {
509 bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() & ~EPPI_EN);
510 disable_dma(CH_EPPI0);
511
512 /* start dma */
513 enable_dma(CH_EPPI0);
514 bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
515 bfin_write_EPPI0_STATUS(0xFFFF);
516 }
517
518 return IRQ_HANDLED;
519}
520
521static int __init bfin_bf54x_probe(struct platform_device *pdev)
522{
523 struct bfin_bf54xfb_info *info;
524 struct fb_info *fbinfo;
525 int ret;
526
527 printk(KERN_INFO DRIVER_NAME ": FrameBuffer initializing...\n");
528
529 if (request_dma(CH_EPPI0, "CH_EPPI0") < 0) {
530 printk(KERN_ERR DRIVER_NAME
531 ": couldn't request CH_EPPI0 DMA\n");
532 ret = -EFAULT;
533 goto out1;
534 }
535
536 fbinfo =
537 framebuffer_alloc(sizeof(struct bfin_bf54xfb_info), &pdev->dev);
538 if (!fbinfo) {
539 ret = -ENOMEM;
540 goto out2;
541 }
542
543 info = fbinfo->par;
544 info->fb = fbinfo;
545 info->dev = &pdev->dev;
546
547 platform_set_drvdata(pdev, fbinfo);
548
549 strcpy(fbinfo->fix.id, driver_name);
550
551 info->mach_info = pdev->dev.platform_data;
552
553 if (info->mach_info == NULL) {
554 dev_err(&pdev->dev,
555 "no platform data for lcd, cannot attach\n");
556 ret = -EINVAL;
557 goto out3;
558 }
559
560 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
561 fbinfo->fix.type_aux = 0;
562 fbinfo->fix.xpanstep = 0;
563 fbinfo->fix.ypanstep = 0;
564 fbinfo->fix.ywrapstep = 0;
565 fbinfo->fix.accel = FB_ACCEL_NONE;
566 fbinfo->fix.visual = FB_VISUAL_TRUECOLOR;
567
568 fbinfo->var.nonstd = 0;
569 fbinfo->var.activate = FB_ACTIVATE_NOW;
570 fbinfo->var.height = info->mach_info->height;
571 fbinfo->var.width = info->mach_info->width;
572 fbinfo->var.accel_flags = 0;
573 fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
574
575 fbinfo->fbops = &bfin_bf54x_fb_ops;
576 fbinfo->flags = FBINFO_FLAG_DEFAULT;
577
578 fbinfo->var.xres = info->mach_info->xres.defval;
579 fbinfo->var.xres_virtual = info->mach_info->xres.defval;
580 fbinfo->var.yres = info->mach_info->yres.defval;
581 fbinfo->var.yres_virtual = info->mach_info->yres.defval;
582 fbinfo->var.bits_per_pixel = info->mach_info->bpp.defval;
583
584 fbinfo->var.upper_margin = 0;
585 fbinfo->var.lower_margin = 0;
586 fbinfo->var.vsync_len = 0;
587
588 fbinfo->var.left_margin = 0;
589 fbinfo->var.right_margin = 0;
590 fbinfo->var.hsync_len = 0;
591
592 fbinfo->var.red.offset = 16;
593 fbinfo->var.green.offset = 8;
594 fbinfo->var.blue.offset = 0;
595 fbinfo->var.transp.offset = 0;
596 fbinfo->var.red.length = 8;
597 fbinfo->var.green.length = 8;
598 fbinfo->var.blue.length = 8;
599 fbinfo->var.transp.length = 0;
600 fbinfo->fix.smem_len = info->mach_info->xres.max *
601 info->mach_info->yres.max * info->mach_info->bpp.max / 8;
602
603 fbinfo->fix.line_length = fbinfo->var.xres_virtual *
604 fbinfo->var.bits_per_pixel / 8;
605
606 info->fb_buffer =
607 dma_alloc_coherent(NULL, fbinfo->fix.smem_len, &info->dma_handle,
608 GFP_KERNEL);
609
610 if (NULL == info->fb_buffer) {
611 printk(KERN_ERR DRIVER_NAME
612 ": couldn't allocate dma buffer.\n");
613 ret = -ENOMEM;
614 goto out3;
615 }
616
617 memset(info->fb_buffer, 0, fbinfo->fix.smem_len);
618
619 fbinfo->screen_base = (void *)info->fb_buffer;
620 fbinfo->fix.smem_start = (int)info->fb_buffer;
621
622 fbinfo->fbops = &bfin_bf54x_fb_ops;
623
624 fbinfo->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
625 if (!fbinfo->pseudo_palette) {
626 printk(KERN_ERR DRIVER_NAME
627 "Fail to allocate pseudo_palette\n");
628
629 ret = -ENOMEM;
630 goto out4;
631 }
632
633 memset(fbinfo->pseudo_palette, 0, sizeof(u32) * 16);
634
635 if (fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0)
636 < 0) {
637 printk(KERN_ERR DRIVER_NAME
638 "Fail to allocate colormap (%d entries)\n",
639 BFIN_LCD_NBR_PALETTE_ENTRIES);
640 ret = -EFAULT;
641 goto out5;
642 }
643
644 if (request_ports(info)) {
645 printk(KERN_ERR DRIVER_NAME ": couldn't request gpio port.\n");
646 ret = -EFAULT;
647 goto out6;
648 }
649
650 info->irq = platform_get_irq(pdev, 0);
651 if (info->irq < 0) {
652 ret = -EINVAL;
653 goto out7;
654 }
655
656 if (request_irq(info->irq, (void *)bfin_bf54x_irq_error, IRQF_DISABLED,
657 "PPI ERROR", info) < 0) {
658 printk(KERN_ERR DRIVER_NAME
659 ": unable to request PPI ERROR IRQ\n");
660 ret = -EFAULT;
661 goto out7;
662 }
663
664 if (register_framebuffer(fbinfo) < 0) {
665 printk(KERN_ERR DRIVER_NAME
666 ": unable to register framebuffer.\n");
667 ret = -EINVAL;
668 goto out8;
669 }
670#ifndef NO_BL_SUPPORT
671 bl_dev =
672 backlight_device_register("bf54x-bl", NULL, NULL,
673 &bfin_lq043fb_bl_ops);
674 bl_dev->props.max_brightness = 255;
675
676 lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops);
677 lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
678#endif
679
680 return 0;
681
682out8:
683 free_irq(info->irq, info);
684out7:
685 free_ports(info);
686out6:
687 fb_dealloc_cmap(&fbinfo->cmap);
688out5:
689 kfree(fbinfo->pseudo_palette);
690out4:
691 dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
692 info->dma_handle);
693out3:
694 framebuffer_release(fbinfo);
695out2:
696 free_dma(CH_EPPI0);
697out1:
698 platform_set_drvdata(pdev, NULL);
699
700 return ret;
701}
702
703static int bfin_bf54x_remove(struct platform_device *pdev)
704{
705
706 struct fb_info *fbinfo = platform_get_drvdata(pdev);
707 struct bfin_bf54xfb_info *info = fbinfo->par;
708
709 free_dma(CH_EPPI0);
710 free_irq(info->irq, info);
711
712 if (info->fb_buffer != NULL)
713 dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
714 info->dma_handle);
715
716 kfree(fbinfo->pseudo_palette);
717 fb_dealloc_cmap(&fbinfo->cmap);
718
719#ifndef NO_BL_SUPPORT
720 lcd_device_unregister(lcd_dev);
721 backlight_device_unregister(bl_dev);
722#endif
723
724 unregister_framebuffer(fbinfo);
725
726 free_ports(info);
727
728 printk(KERN_INFO DRIVER_NAME ": Unregister LCD driver.\n");
729
730 return 0;
731}
732
733#ifdef CONFIG_PM
734static int bfin_bf54x_suspend(struct platform_device *pdev, pm_message_t state)
735{
736 struct fb_info *fbinfo = platform_get_drvdata(pdev);
737 struct bfin_bf54xfb_info *info = fbinfo->par;
738
739 bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() & ~EPPI_EN);
740 disable_dma(CH_EPPI0);
741 bfin_write_EPPI0_STATUS(0xFFFF);
742
743 return 0;
744}
745
746static int bfin_bf54x_resume(struct platform_device *pdev)
747{
748 struct fb_info *fbinfo = platform_get_drvdata(pdev);
749 struct bfin_bf54xfb_info *info = fbinfo->par;
750
751 enable_dma(CH_EPPI0);
752 bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
753
754 return 0;
755}
756#else
757#define bfin_bf54x_suspend NULL
758#define bfin_bf54x_resume NULL
759#endif
760
761static struct platform_driver bfin_bf54x_driver = {
762 .probe = bfin_bf54x_probe,
763 .remove = bfin_bf54x_remove,
764 .suspend = bfin_bf54x_suspend,
765 .resume = bfin_bf54x_resume,
766 .driver = {
767 .name = DRIVER_NAME,
768 .owner = THIS_MODULE,
769 },
770};
771
772static int __devinit bfin_bf54x_driver_init(void)
773{
774 return platform_driver_register(&bfin_bf54x_driver);
775}
776
777static void __exit bfin_bf54x_driver_cleanup(void)
778{
779 platform_driver_unregister(&bfin_bf54x_driver);
780}
781
782MODULE_DESCRIPTION("Blackfin BF54x TFT LCD Driver");
783MODULE_LICENSE("GPL");
784
785module_init(bfin_bf54x_driver_init);
786module_exit(bfin_bf54x_driver_cleanup);
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 032210f45be3..b07e419b12d2 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -45,14 +45,14 @@
45 45
46static void 46static void
47bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src, 47bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src,
48 int src_idx, int bits, unsigned n) 48 int src_idx, int bits, unsigned n, u32 bswapmask)
49{ 49{
50 unsigned long first, last; 50 unsigned long first, last;
51 int const shift = dst_idx-src_idx; 51 int const shift = dst_idx-src_idx;
52 int left, right; 52 int left, right;
53 53
54 first = FB_SHIFT_HIGH(~0UL, dst_idx); 54 first = fb_shifted_pixels_mask_long(dst_idx, bswapmask);
55 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); 55 last = ~fb_shifted_pixels_mask_long((dst_idx+n) % bits, bswapmask);
56 56
57 if (!shift) { 57 if (!shift) {
58 // Same alignment for source and dest 58 // Same alignment for source and dest
@@ -94,29 +94,34 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
94 FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst); 94 FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst);
95 } 95 }
96 } else { 96 } else {
97 /* Different alignment for source and dest */
97 unsigned long d0, d1; 98 unsigned long d0, d1;
98 int m; 99 int m;
99 // Different alignment for source and dest
100 100
101 right = shift & (bits - 1); 101 right = shift & (bits - 1);
102 left = -shift & (bits - 1); 102 left = -shift & (bits - 1);
103 bswapmask &= shift;
103 104
104 if (dst_idx+n <= bits) { 105 if (dst_idx+n <= bits) {
105 // Single destination word 106 // Single destination word
106 if (last) 107 if (last)
107 first &= last; 108 first &= last;
109 d0 = FB_READL(src);
110 d0 = fb_rev_pixels_in_long(d0, bswapmask);
108 if (shift > 0) { 111 if (shift > 0) {
109 // Single source word 112 // Single source word
110 FB_WRITEL( comp( FB_READL(src) >> right, FB_READL(dst), first), dst); 113 d0 >>= right;
111 } else if (src_idx+n <= bits) { 114 } else if (src_idx+n <= bits) {
112 // Single source word 115 // Single source word
113 FB_WRITEL( comp(FB_READL(src) << left, FB_READL(dst), first), dst); 116 d0 <<= left;;
114 } else { 117 } else {
115 // 2 source words 118 // 2 source words
116 d0 = FB_READL(src++); 119 d1 = FB_READL(src + 1);
117 d1 = FB_READL(src); 120 d1 = fb_rev_pixels_in_long(d1, bswapmask);
118 FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), first), dst); 121 d0 = d0<<left | d1>>right;
119 } 122 }
123 d0 = fb_rev_pixels_in_long(d0, bswapmask);
124 FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
120 } else { 125 } else {
121 // Multiple destination words 126 // Multiple destination words
122 /** We must always remember the last value read, because in case 127 /** We must always remember the last value read, because in case
@@ -125,25 +130,31 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
125 overlap with the current long from SRC. We store this value in 130 overlap with the current long from SRC. We store this value in
126 'd0'. */ 131 'd0'. */
127 d0 = FB_READL(src++); 132 d0 = FB_READL(src++);
133 d0 = fb_rev_pixels_in_long(d0, bswapmask);
128 // Leading bits 134 // Leading bits
129 if (shift > 0) { 135 if (shift > 0) {
130 // Single source word 136 // Single source word
131 FB_WRITEL( comp(d0 >> right, FB_READL(dst), first), dst); 137 d1 = d0;
138 d0 >>= right;
132 dst++; 139 dst++;
133 n -= bits - dst_idx; 140 n -= bits - dst_idx;
134 } else { 141 } else {
135 // 2 source words 142 // 2 source words
136 d1 = FB_READL(src++); 143 d1 = FB_READL(src++);
137 FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), first), dst); 144 d1 = fb_rev_pixels_in_long(d1, bswapmask);
138 d0 = d1; 145
146 d0 = d0<<left | d1>>right;
139 dst++; 147 dst++;
140 n -= bits - dst_idx; 148 n -= bits - dst_idx;
141 } 149 }
150 d0 = fb_rev_pixels_in_long(d0, bswapmask);
151 FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
152 d0 = d1;
142 153
143 // Main chunk 154 // Main chunk
144 m = n % bits; 155 m = n % bits;
145 n /= bits; 156 n /= bits;
146 while (n >= 4) { 157 while ((n >= 4) && !bswapmask) {
147 d1 = FB_READL(src++); 158 d1 = FB_READL(src++);
148 FB_WRITEL(d0 << left | d1 >> right, dst++); 159 FB_WRITEL(d0 << left | d1 >> right, dst++);
149 d0 = d1; 160 d0 = d1;
@@ -160,7 +171,10 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
160 } 171 }
161 while (n--) { 172 while (n--) {
162 d1 = FB_READL(src++); 173 d1 = FB_READL(src++);
163 FB_WRITEL(d0 << left | d1 >> right, dst++); 174 d1 = fb_rev_pixels_in_long(d1, bswapmask);
175 d0 = d0 << left | d1 >> right;
176 d0 = fb_rev_pixels_in_long(d0, bswapmask);
177 FB_WRITEL(d0, dst++);
164 d0 = d1; 178 d0 = d1;
165 } 179 }
166 180
@@ -168,12 +182,16 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
168 if (last) { 182 if (last) {
169 if (m <= right) { 183 if (m <= right) {
170 // Single source word 184 // Single source word
171 FB_WRITEL( comp(d0 << left, FB_READL(dst), last), dst); 185 d0 <<= left;
172 } else { 186 } else {
173 // 2 source words 187 // 2 source words
174 d1 = FB_READL(src); 188 d1 = FB_READL(src);
175 FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), last), dst); 189 d1 = fb_rev_pixels_in_long(d1,
190 bswapmask);
191 d0 = d0<<left | d1>>right;
176 } 192 }
193 d0 = fb_rev_pixels_in_long(d0, bswapmask);
194 FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
177 } 195 }
178 } 196 }
179 } 197 }
@@ -185,7 +203,7 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
185 203
186static void 204static void
187bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src, 205bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src,
188 int src_idx, int bits, unsigned n) 206 int src_idx, int bits, unsigned n, u32 bswapmask)
189{ 207{
190 unsigned long first, last; 208 unsigned long first, last;
191 int shift; 209 int shift;
@@ -203,8 +221,8 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
203 221
204 shift = dst_idx-src_idx; 222 shift = dst_idx-src_idx;
205 223
206 first = FB_SHIFT_LOW(~0UL, bits - 1 - dst_idx); 224 first = fb_shifted_pixels_mask_long(bits - 1 - dst_idx, bswapmask);
207 last = ~(FB_SHIFT_LOW(~0UL, bits - 1 - ((dst_idx-n) % bits))); 225 last = ~fb_shifted_pixels_mask_long(bits - 1 - ((dst_idx-n) % bits), bswapmask);
208 226
209 if (!shift) { 227 if (!shift) {
210 // Same alignment for source and dest 228 // Same alignment for source and dest
@@ -247,24 +265,32 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
247 } 265 }
248 } else { 266 } else {
249 // Different alignment for source and dest 267 // Different alignment for source and dest
268 unsigned long d0, d1;
269 int m;
250 270
251 int const left = -shift & (bits-1); 271 int const left = -shift & (bits-1);
252 int const right = shift & (bits-1); 272 int const right = shift & (bits-1);
273 bswapmask &= shift;
253 274
254 if ((unsigned long)dst_idx+1 >= n) { 275 if ((unsigned long)dst_idx+1 >= n) {
255 // Single destination word 276 // Single destination word
256 if (last) 277 if (last)
257 first &= last; 278 first &= last;
279 d0 = FB_READL(src);
258 if (shift < 0) { 280 if (shift < 0) {
259 // Single source word 281 // Single source word
260 FB_WRITEL( comp( FB_READL(src)<<left, FB_READL(dst), first), dst); 282 d0 <<= left;
261 } else if (1+(unsigned long)src_idx >= n) { 283 } else if (1+(unsigned long)src_idx >= n) {
262 // Single source word 284 // Single source word
263 FB_WRITEL( comp( FB_READL(src)>>right, FB_READL(dst), first), dst); 285 d0 >>= right;
264 } else { 286 } else {
265 // 2 source words 287 // 2 source words
266 FB_WRITEL( comp( (FB_READL(src)>>right | FB_READL(src-1)<<left), FB_READL(dst), first), dst); 288 d1 = FB_READL(src - 1);
289 d1 = fb_rev_pixels_in_long(d1, bswapmask);
290 d0 = d0>>right | d1<<left;
267 } 291 }
292 d0 = fb_rev_pixels_in_long(d0, bswapmask);
293 FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
268 } else { 294 } else {
269 // Multiple destination words 295 // Multiple destination words
270 /** We must always remember the last value read, because in case 296 /** We must always remember the last value read, because in case
@@ -272,27 +298,30 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
272 1bpp), we always collect one full long for DST and that might 298 1bpp), we always collect one full long for DST and that might
273 overlap with the current long from SRC. We store this value in 299 overlap with the current long from SRC. We store this value in
274 'd0'. */ 300 'd0'. */
275 unsigned long d0, d1;
276 int m;
277 301
278 d0 = FB_READL(src--); 302 d0 = FB_READL(src--);
303 d0 = fb_rev_pixels_in_long(d0, bswapmask);
279 // Leading bits 304 // Leading bits
280 if (shift < 0) { 305 if (shift < 0) {
281 // Single source word 306 // Single source word
282 FB_WRITEL( comp( (d0 << left), FB_READL(dst), first), dst); 307 d1 = d0;
308 d0 <<= left;
283 } else { 309 } else {
284 // 2 source words 310 // 2 source words
285 d1 = FB_READL(src--); 311 d1 = FB_READL(src--);
286 FB_WRITEL( comp( (d0>>right | d1<<left), FB_READL(dst), first), dst); 312 d1 = fb_rev_pixels_in_long(d1, bswapmask);
287 d0 = d1; 313 d0 = d0>>right | d1<<left;
288 } 314 }
315 d0 = fb_rev_pixels_in_long(d0, bswapmask);
316 FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
317 d0 = d1;
289 dst--; 318 dst--;
290 n -= dst_idx+1; 319 n -= dst_idx+1;
291 320
292 // Main chunk 321 // Main chunk
293 m = n % bits; 322 m = n % bits;
294 n /= bits; 323 n /= bits;
295 while (n >= 4) { 324 while ((n >= 4) && !bswapmask) {
296 d1 = FB_READL(src--); 325 d1 = FB_READL(src--);
297 FB_WRITEL(d0 >> right | d1 << left, dst--); 326 FB_WRITEL(d0 >> right | d1 << left, dst--);
298 d0 = d1; 327 d0 = d1;
@@ -309,7 +338,10 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
309 } 338 }
310 while (n--) { 339 while (n--) {
311 d1 = FB_READL(src--); 340 d1 = FB_READL(src--);
312 FB_WRITEL(d0 >> right | d1 << left, dst--); 341 d1 = fb_rev_pixels_in_long(d1, bswapmask);
342 d0 = d0 >> right | d1 << left;
343 d0 = fb_rev_pixels_in_long(d0, bswapmask);
344 FB_WRITEL(d0, dst--);
313 d0 = d1; 345 d0 = d1;
314 } 346 }
315 347
@@ -317,12 +349,16 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
317 if (last) { 349 if (last) {
318 if (m <= left) { 350 if (m <= left) {
319 // Single source word 351 // Single source word
320 FB_WRITEL( comp(d0 >> right, FB_READL(dst), last), dst); 352 d0 >>= right;
321 } else { 353 } else {
322 // 2 source words 354 // 2 source words
323 d1 = FB_READL(src); 355 d1 = FB_READL(src);
324 FB_WRITEL( comp(d0>>right | d1<<left, FB_READL(dst), last), dst); 356 d1 = fb_rev_pixels_in_long(d1,
357 bswapmask);
358 d0 = d0>>right | d1<<left;
325 } 359 }
360 d0 = fb_rev_pixels_in_long(d0, bswapmask);
361 FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
326 } 362 }
327 } 363 }
328 } 364 }
@@ -336,6 +372,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
336 unsigned long __iomem *dst = NULL, *src = NULL; 372 unsigned long __iomem *dst = NULL, *src = NULL;
337 int bits = BITS_PER_LONG, bytes = bits >> 3; 373 int bits = BITS_PER_LONG, bytes = bits >> 3;
338 int dst_idx = 0, src_idx = 0, rev_copy = 0; 374 int dst_idx = 0, src_idx = 0, rev_copy = 0;
375 u32 bswapmask = fb_compute_bswapmask(p);
339 376
340 if (p->state != FBINFO_STATE_RUNNING) 377 if (p->state != FBINFO_STATE_RUNNING)
341 return; 378 return;
@@ -368,7 +405,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
368 src += src_idx >> (ffs(bits) - 1); 405 src += src_idx >> (ffs(bits) - 1);
369 src_idx &= (bytes - 1); 406 src_idx &= (bytes - 1);
370 bitcpy_rev(dst, dst_idx, src, src_idx, bits, 407 bitcpy_rev(dst, dst_idx, src, src_idx, bits,
371 width*p->var.bits_per_pixel); 408 width*p->var.bits_per_pixel, bswapmask);
372 } 409 }
373 } else { 410 } else {
374 while (height--) { 411 while (height--) {
@@ -377,7 +414,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
377 src += src_idx >> (ffs(bits) - 1); 414 src += src_idx >> (ffs(bits) - 1);
378 src_idx &= (bytes - 1); 415 src_idx &= (bytes - 1);
379 bitcpy(dst, dst_idx, src, src_idx, bits, 416 bitcpy(dst, dst_idx, src, src_idx, bits,
380 width*p->var.bits_per_pixel); 417 width*p->var.bits_per_pixel, bswapmask);
381 dst_idx += bits_per_line; 418 dst_idx += bits_per_line;
382 src_idx += bits_per_line; 419 src_idx += bits_per_line;
383 } 420 }
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index 71623b4f8ca2..23d70a12e4da 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -36,15 +36,16 @@
36 */ 36 */
37 37
38static void 38static void
39bitfill_aligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat, unsigned n, int bits) 39bitfill_aligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
40 unsigned n, int bits, u32 bswapmask)
40{ 41{
41 unsigned long first, last; 42 unsigned long first, last;
42 43
43 if (!n) 44 if (!n)
44 return; 45 return;
45 46
46 first = FB_SHIFT_HIGH(~0UL, dst_idx); 47 first = fb_shifted_pixels_mask_long(dst_idx, bswapmask);
47 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); 48 last = ~fb_shifted_pixels_mask_long((dst_idx+n) % bits, bswapmask);
48 49
49 if (dst_idx+n <= bits) { 50 if (dst_idx+n <= bits) {
50 // Single word 51 // Single word
@@ -146,7 +147,8 @@ bitfill_unaligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
146 * Aligned pattern invert using 32/64-bit memory accesses 147 * Aligned pattern invert using 32/64-bit memory accesses
147 */ 148 */
148static void 149static void
149bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat, unsigned n, int bits) 150bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
151 unsigned n, int bits, u32 bswapmask)
150{ 152{
151 unsigned long val = pat, dat; 153 unsigned long val = pat, dat;
152 unsigned long first, last; 154 unsigned long first, last;
@@ -154,8 +156,8 @@ bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
154 if (!n) 156 if (!n)
155 return; 157 return;
156 158
157 first = FB_SHIFT_HIGH(~0UL, dst_idx); 159 first = fb_shifted_pixels_mask_long(dst_idx, bswapmask);
158 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); 160 last = ~fb_shifted_pixels_mask_long((dst_idx+n) % bits, bswapmask);
159 161
160 if (dst_idx+n <= bits) { 162 if (dst_idx+n <= bits) {
161 // Single word 163 // Single word
@@ -303,8 +305,10 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
303 if (p->fbops->fb_sync) 305 if (p->fbops->fb_sync)
304 p->fbops->fb_sync(p); 306 p->fbops->fb_sync(p);
305 if (!left) { 307 if (!left) {
308 u32 bswapmask = fb_compute_bswapmask(p);
306 void (*fill_op32)(unsigned long __iomem *dst, int dst_idx, 309 void (*fill_op32)(unsigned long __iomem *dst, int dst_idx,
307 unsigned long pat, unsigned n, int bits) = NULL; 310 unsigned long pat, unsigned n, int bits,
311 u32 bswapmask) = NULL;
308 312
309 switch (rect->rop) { 313 switch (rect->rop) {
310 case ROP_XOR: 314 case ROP_XOR:
@@ -321,7 +325,7 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
321 while (height--) { 325 while (height--) {
322 dst += dst_idx >> (ffs(bits) - 1); 326 dst += dst_idx >> (ffs(bits) - 1);
323 dst_idx &= (bits - 1); 327 dst_idx &= (bits - 1);
324 fill_op32(dst, dst_idx, pat, width*bpp, bits); 328 fill_op32(dst, dst_idx, pat, width*bpp, bits, bswapmask);
325 dst_idx += p->fix.line_length*8; 329 dst_idx += p->fix.line_length*8;
326 } 330 }
327 } else { 331 } else {
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 261004473c8e..f598907b42ad 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -33,6 +33,7 @@
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/fb.h> 34#include <linux/fb.h>
35#include <asm/types.h> 35#include <asm/types.h>
36#include "fb_draw.h"
36 37
37#define DEBUG 38#define DEBUG
38 39
@@ -87,6 +88,7 @@ static inline void color_imageblit(const struct fb_image *image,
87 u32 null_bits = 32 - bpp; 88 u32 null_bits = 32 - bpp;
88 u32 *palette = (u32 *) p->pseudo_palette; 89 u32 *palette = (u32 *) p->pseudo_palette;
89 const u8 *src = image->data; 90 const u8 *src = image->data;
91 u32 bswapmask = fb_compute_bswapmask(p);
90 92
91 dst2 = (u32 __iomem *) dst1; 93 dst2 = (u32 __iomem *) dst1;
92 for (i = image->height; i--; ) { 94 for (i = image->height; i--; ) {
@@ -96,7 +98,7 @@ static inline void color_imageblit(const struct fb_image *image,
96 val = 0; 98 val = 0;
97 99
98 if (start_index) { 100 if (start_index) {
99 u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0, start_index)); 101 u32 start_mask = ~fb_shifted_pixels_mask_u32(start_index, bswapmask);
100 val = FB_READL(dst) & start_mask; 102 val = FB_READL(dst) & start_mask;
101 shift = start_index; 103 shift = start_index;
102 } 104 }
@@ -107,7 +109,7 @@ static inline void color_imageblit(const struct fb_image *image,
107 else 109 else
108 color = *src; 110 color = *src;
109 color <<= FB_LEFT_POS(bpp); 111 color <<= FB_LEFT_POS(bpp);
110 val |= FB_SHIFT_HIGH(color, shift); 112 val |= FB_SHIFT_HIGH(color, shift ^ bswapmask);
111 if (shift >= null_bits) { 113 if (shift >= null_bits) {
112 FB_WRITEL(val, dst++); 114 FB_WRITEL(val, dst++);
113 115
@@ -119,7 +121,7 @@ static inline void color_imageblit(const struct fb_image *image,
119 src++; 121 src++;
120 } 122 }
121 if (shift) { 123 if (shift) {
122 u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift); 124 u32 end_mask = fb_shifted_pixels_mask_u32(shift, bswapmask);
123 125
124 FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); 126 FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
125 } 127 }
@@ -147,7 +149,8 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
147 u32 spitch = (image->width+7)/8; 149 u32 spitch = (image->width+7)/8;
148 const u8 *src = image->data, *s; 150 const u8 *src = image->data, *s;
149 u32 i, j, l; 151 u32 i, j, l;
150 152 u32 bswapmask = fb_compute_bswapmask(p);
153
151 dst2 = (u32 __iomem *) dst1; 154 dst2 = (u32 __iomem *) dst1;
152 fgcolor <<= FB_LEFT_POS(bpp); 155 fgcolor <<= FB_LEFT_POS(bpp);
153 bgcolor <<= FB_LEFT_POS(bpp); 156 bgcolor <<= FB_LEFT_POS(bpp);
@@ -161,7 +164,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
161 164
162 /* write leading bits */ 165 /* write leading bits */
163 if (start_index) { 166 if (start_index) {
164 u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index)); 167 u32 start_mask = ~fb_shifted_pixels_mask_u32(start_index, bswapmask);
165 val = FB_READL(dst) & start_mask; 168 val = FB_READL(dst) & start_mask;
166 shift = start_index; 169 shift = start_index;
167 } 170 }
@@ -169,7 +172,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
169 while (j--) { 172 while (j--) {
170 l--; 173 l--;
171 color = (*s & (1 << l)) ? fgcolor : bgcolor; 174 color = (*s & (1 << l)) ? fgcolor : bgcolor;
172 val |= FB_SHIFT_HIGH(color, shift); 175 val |= FB_SHIFT_HIGH(color, shift ^ bswapmask);
173 176
174 /* Did the bitshift spill bits to the next long? */ 177 /* Did the bitshift spill bits to the next long? */
175 if (shift >= null_bits) { 178 if (shift >= null_bits) {
@@ -184,7 +187,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
184 187
185 /* write trailing bits */ 188 /* write trailing bits */
186 if (shift) { 189 if (shift) {
187 u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift); 190 u32 end_mask = fb_shifted_pixels_mask_u32(shift, bswapmask);
188 191
189 FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); 192 FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
190 } 193 }
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 8269d704ab2a..ce22bf5de350 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -45,7 +45,6 @@
45#include <linux/delay.h> 45#include <linux/delay.h>
46#include <linux/fb.h> 46#include <linux/fb.h>
47#include <linux/init.h> 47#include <linux/init.h>
48#include <linux/selection.h>
49#include <asm/pgtable.h> 48#include <asm/pgtable.h>
50 49
51#ifdef CONFIG_ZORRO 50#ifdef CONFIG_ZORRO
@@ -59,14 +58,13 @@
59#endif 58#endif
60#ifdef CONFIG_PPC_PREP 59#ifdef CONFIG_PPC_PREP
61#include <asm/machdep.h> 60#include <asm/machdep.h>
62#define isPReP (machine_is(prep)) 61#define isPReP machine_is(prep)
63#else 62#else
64#define isPReP 0 63#define isPReP 0
65#endif 64#endif
66 65
67#include "video/vga.h" 66#include <video/vga.h>
68#include "video/cirrus.h" 67#include <video/cirrus.h>
69
70 68
71/***************************************************************** 69/*****************************************************************
72 * 70 *
@@ -82,7 +80,8 @@
82 80
83/* debug output */ 81/* debug output */
84#ifdef CIRRUSFB_DEBUG 82#ifdef CIRRUSFB_DEBUG
85#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) 83#define DPRINTK(fmt, args...) \
84 printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
86#else 85#else
87#define DPRINTK(fmt, args...) 86#define DPRINTK(fmt, args...)
88#endif 87#endif
@@ -90,19 +89,15 @@
90/* debugging assertions */ 89/* debugging assertions */
91#ifndef CIRRUSFB_NDEBUG 90#ifndef CIRRUSFB_NDEBUG
92#define assert(expr) \ 91#define assert(expr) \
93 if(!(expr)) { \ 92 if (!(expr)) { \
94 printk( "Assertion failed! %s,%s,%s,line=%d\n",\ 93 printk("Assertion failed! %s,%s,%s,line=%d\n", \
95 #expr,__FILE__,__FUNCTION__,__LINE__); \ 94 #expr, __FILE__, __FUNCTION__, __LINE__); \
96 } 95 }
97#else 96#else
98#define assert(expr) 97#define assert(expr)
99#endif 98#endif
100 99
101#define MB_ (1024*1024) 100#define MB_ (1024 * 1024)
102#define KB_ (1024)
103
104#define MAX_NUM_BOARDS 7
105
106 101
107/***************************************************************** 102/*****************************************************************
108 * 103 *
@@ -111,7 +106,7 @@
111 */ 106 */
112 107
113/* board types */ 108/* board types */
114typedef enum { 109enum cirrus_board {
115 BT_NONE = 0, 110 BT_NONE = 0,
116 BT_SD64, 111 BT_SD64,
117 BT_PICCOLO, 112 BT_PICCOLO,
@@ -121,13 +116,12 @@ typedef enum {
121 BT_ALPINE, /* GD543x/4x */ 116 BT_ALPINE, /* GD543x/4x */
122 BT_GD5480, 117 BT_GD5480,
123 BT_LAGUNA, /* GD546x */ 118 BT_LAGUNA, /* GD546x */
124} cirrusfb_board_t; 119};
125
126 120
127/* 121/*
128 * per-board-type information, used for enumerating and abstracting 122 * per-board-type information, used for enumerating and abstracting
129 * chip-specific information 123 * chip-specific information
130 * NOTE: MUST be in the same order as cirrusfb_board_t in order to 124 * NOTE: MUST be in the same order as enum cirrus_board in order to
131 * use direct indexing on this array 125 * use direct indexing on this array
132 * NOTE: '__initdata' cannot be used as some of this info 126 * NOTE: '__initdata' cannot be used as some of this info
133 * is required at runtime. Maybe separate into an init-only and 127 * is required at runtime. Maybe separate into an init-only and
@@ -139,7 +133,8 @@ static const struct cirrusfb_board_info_rec {
139 /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */ 133 /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
140 bool init_sr07 : 1; /* init SR07 during init_vgachip() */ 134 bool init_sr07 : 1; /* init SR07 during init_vgachip() */
141 bool init_sr1f : 1; /* write SR1F during init_vgachip() */ 135 bool init_sr1f : 1; /* write SR1F during init_vgachip() */
142 bool scrn_start_bit19 : 1; /* construct bit 19 of screen start address */ 136 /* construct bit 19 of screen start address */
137 bool scrn_start_bit19 : 1;
143 138
144 /* initial SR07 value, then for each mode */ 139 /* initial SR07 value, then for each mode */
145 unsigned char sr07; 140 unsigned char sr07;
@@ -261,30 +256,28 @@ static const struct cirrusfb_board_info_rec {
261 } 256 }
262}; 257};
263 258
264
265#ifdef CONFIG_PCI 259#ifdef CONFIG_PCI
266#define CHIP(id, btype) \ 260#define CHIP(id, btype) \
267 { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) } 261 { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
268 262
269static struct pci_device_id cirrusfb_pci_table[] = { 263static struct pci_device_id cirrusfb_pci_table[] = {
270 CHIP( PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE ), 264 CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
271 CHIP( PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE ), 265 CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE),
272 CHIP( PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE ), 266 CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE),
273 CHIP( PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE ), /* GD-5440 is same id */ 267 CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
274 CHIP( PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE ), 268 CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
275 CHIP( PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE ), 269 CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
276 CHIP( PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480 ), /* MacPicasso likely */ 270 CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */
277 CHIP( PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is 5446 */ 271 CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
278 CHIP( PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */ 272 CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
279 CHIP( PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */ 273 CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
280 CHIP( PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/ 274 CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA), /* CL Laguna 3DA*/
281 { 0, } 275 { 0, }
282}; 276};
283MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); 277MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
284#undef CHIP 278#undef CHIP
285#endif /* CONFIG_PCI */ 279#endif /* CONFIG_PCI */
286 280
287
288#ifdef CONFIG_ZORRO 281#ifdef CONFIG_ZORRO
289static const struct zorro_device_id cirrusfb_zorro_table[] = { 282static const struct zorro_device_id cirrusfb_zorro_table[] = {
290 { 283 {
@@ -294,7 +287,7 @@ static const struct zorro_device_id cirrusfb_zorro_table[] = {
294 .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM, 287 .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
295 .driver_data = BT_PICCOLO, 288 .driver_data = BT_PICCOLO,
296 }, { 289 }, {
297 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM, 290 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
298 .driver_data = BT_PICASSO, 291 .driver_data = BT_PICASSO,
299 }, { 292 }, {
300 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM, 293 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
@@ -333,12 +326,7 @@ static const struct {
333}; 326};
334#endif /* CONFIG_ZORRO */ 327#endif /* CONFIG_ZORRO */
335 328
336
337struct cirrusfb_regs { 329struct cirrusfb_regs {
338 __u32 line_length; /* in BYTES! */
339 __u32 visual;
340 __u32 type;
341
342 long freq; 330 long freq;
343 long nom; 331 long nom;
344 long den; 332 long den;
@@ -364,37 +352,23 @@ struct cirrusfb_regs {
364 long VertBlankEnd; 352 long VertBlankEnd;
365}; 353};
366 354
367
368
369#ifdef CIRRUSFB_DEBUG 355#ifdef CIRRUSFB_DEBUG
370typedef enum { 356enum cirrusfb_dbg_reg_class {
371 CRT, 357 CRT,
372 SEQ 358 SEQ
373} cirrusfb_dbg_reg_class_t; 359};
374#endif /* CIRRUSFB_DEBUG */ 360#endif /* CIRRUSFB_DEBUG */
375
376
377
378 361
379/* info about board */ 362/* info about board */
380struct cirrusfb_info { 363struct cirrusfb_info {
381 struct fb_info *info;
382
383 u8 __iomem *fbmem;
384 u8 __iomem *regbase; 364 u8 __iomem *regbase;
385 u8 __iomem *mem; 365 enum cirrus_board btype;
386 unsigned long size;
387 cirrusfb_board_t btype;
388 unsigned char SFR; /* Shadow of special function register */ 366 unsigned char SFR; /* Shadow of special function register */
389 367
390 unsigned long fbmem_phys;
391 unsigned long fbregs_phys;
392
393 struct cirrusfb_regs currentmode; 368 struct cirrusfb_regs currentmode;
394 int blank_mode; 369 int blank_mode;
395 370
396 u32 pseudo_palette[16]; 371 u32 pseudo_palette[16];
397 struct { u8 red, green, blue, pad; } palette[256];
398 372
399#ifdef CONFIG_ZORRO 373#ifdef CONFIG_ZORRO
400 struct zorro_dev *zdev; 374 struct zorro_dev *zdev;
@@ -402,12 +376,11 @@ struct cirrusfb_info {
402#ifdef CONFIG_PCI 376#ifdef CONFIG_PCI
403 struct pci_dev *pdev; 377 struct pci_dev *pdev;
404#endif 378#endif
405 void (*unmap)(struct cirrusfb_info *cinfo); 379 void (*unmap)(struct fb_info *info);
406}; 380};
407 381
408
409static unsigned cirrusfb_def_mode = 1; 382static unsigned cirrusfb_def_mode = 1;
410static int noaccel = 0; 383static int noaccel;
411 384
412/* 385/*
413 * Predefined Video Modes 386 * Predefined Video Modes
@@ -441,7 +414,7 @@ static const struct {
441 .lower_margin = 8, 414 .lower_margin = 8,
442 .hsync_len = 96, 415 .hsync_len = 96,
443 .vsync_len = 4, 416 .vsync_len = 4,
444 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 417 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
445 .vmode = FB_VMODE_NONINTERLACED 418 .vmode = FB_VMODE_NONINTERLACED
446 } 419 }
447 }, { 420 }, {
@@ -502,27 +475,29 @@ static const struct {
502/****************************************************************************/ 475/****************************************************************************/
503/**** BEGIN PROTOTYPES ******************************************************/ 476/**** BEGIN PROTOTYPES ******************************************************/
504 477
505
506/*--- Interface used by the world ------------------------------------------*/ 478/*--- Interface used by the world ------------------------------------------*/
507static int cirrusfb_init (void); 479static int cirrusfb_init(void);
508#ifndef MODULE 480#ifndef MODULE
509static int cirrusfb_setup (char *options); 481static int cirrusfb_setup(char *options);
510#endif 482#endif
511 483
512static int cirrusfb_open (struct fb_info *info, int user); 484static int cirrusfb_open(struct fb_info *info, int user);
513static int cirrusfb_release (struct fb_info *info, int user); 485static int cirrusfb_release(struct fb_info *info, int user);
514static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, 486static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
515 unsigned blue, unsigned transp, 487 unsigned blue, unsigned transp,
516 struct fb_info *info); 488 struct fb_info *info);
517static int cirrusfb_check_var (struct fb_var_screeninfo *var, 489static int cirrusfb_check_var(struct fb_var_screeninfo *var,
518 struct fb_info *info); 490 struct fb_info *info);
519static int cirrusfb_set_par (struct fb_info *info); 491static int cirrusfb_set_par(struct fb_info *info);
520static int cirrusfb_pan_display (struct fb_var_screeninfo *var, 492static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
521 struct fb_info *info); 493 struct fb_info *info);
522static int cirrusfb_blank (int blank_mode, struct fb_info *info); 494static int cirrusfb_blank(int blank_mode, struct fb_info *info);
523static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region); 495static void cirrusfb_fillrect(struct fb_info *info,
524static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); 496 const struct fb_fillrect *region);
525static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image); 497static void cirrusfb_copyarea(struct fb_info *info,
498 const struct fb_copyarea *area);
499static void cirrusfb_imageblit(struct fb_info *info,
500 const struct fb_image *image);
526 501
527/* function table of the above functions */ 502/* function table of the above functions */
528static struct fb_ops cirrusfb_ops = { 503static struct fb_ops cirrusfb_ops = {
@@ -540,68 +515,68 @@ static struct fb_ops cirrusfb_ops = {
540}; 515};
541 516
542/*--- Hardware Specific Routines -------------------------------------------*/ 517/*--- Hardware Specific Routines -------------------------------------------*/
543static int cirrusfb_decode_var (const struct fb_var_screeninfo *var, 518static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
544 struct cirrusfb_regs *regs, 519 struct cirrusfb_regs *regs,
545 const struct fb_info *info); 520 struct fb_info *info);
546/*--- Internal routines ----------------------------------------------------*/ 521/*--- Internal routines ----------------------------------------------------*/
547static void init_vgachip (struct cirrusfb_info *cinfo); 522static void init_vgachip(struct fb_info *info);
548static void switch_monitor (struct cirrusfb_info *cinfo, int on); 523static void switch_monitor(struct cirrusfb_info *cinfo, int on);
549static void WGen (const struct cirrusfb_info *cinfo, 524static void WGen(const struct cirrusfb_info *cinfo,
550 int regnum, unsigned char val); 525 int regnum, unsigned char val);
551static unsigned char RGen (const struct cirrusfb_info *cinfo, int regnum); 526static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
552static void AttrOn (const struct cirrusfb_info *cinfo); 527static void AttrOn(const struct cirrusfb_info *cinfo);
553static void WHDR (const struct cirrusfb_info *cinfo, unsigned char val); 528static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
554static void WSFR (struct cirrusfb_info *cinfo, unsigned char val); 529static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
555static void WSFR2 (struct cirrusfb_info *cinfo, unsigned char val); 530static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
556static void WClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red, 531static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
557 unsigned char green, 532 unsigned char red, unsigned char green, unsigned char blue);
558 unsigned char blue);
559#if 0 533#if 0
560static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red, 534static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
561 unsigned char *green, 535 unsigned char *red, unsigned char *green,
562 unsigned char *blue); 536 unsigned char *blue);
563#endif 537#endif
564static void cirrusfb_WaitBLT (u8 __iomem *regbase); 538static void cirrusfb_WaitBLT(u8 __iomem *regbase);
565static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel, 539static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
566 u_short curx, u_short cury, 540 u_short curx, u_short cury,
567 u_short destx, u_short desty, 541 u_short destx, u_short desty,
568 u_short width, u_short height, 542 u_short width, u_short height,
569 u_short line_length); 543 u_short line_length);
570static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel, 544static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
571 u_short x, u_short y, 545 u_short x, u_short y,
572 u_short width, u_short height, 546 u_short width, u_short height,
573 u_char color, u_short line_length); 547 u_char color, u_short line_length);
574 548
575static void bestclock (long freq, long *best, 549static void bestclock(long freq, long *best,
576 long *nom, long *den, 550 long *nom, long *den,
577 long *div, long maxfreq); 551 long *div, long maxfreq);
578 552
579#ifdef CIRRUSFB_DEBUG 553#ifdef CIRRUSFB_DEBUG
580static void cirrusfb_dump (void); 554static void cirrusfb_dump(void);
581static void cirrusfb_dbg_reg_dump (caddr_t regbase); 555static void cirrusfb_dbg_reg_dump(caddr_t regbase);
582static void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_class,...); 556static void cirrusfb_dbg_print_regs(caddr_t regbase,
583static void cirrusfb_dbg_print_byte (const char *name, unsigned char val); 557 enum cirrusfb_dbg_reg_class reg_class, ...);
558static void cirrusfb_dbg_print_byte(const char *name, unsigned char val);
584#endif /* CIRRUSFB_DEBUG */ 559#endif /* CIRRUSFB_DEBUG */
585 560
586/*** END PROTOTYPES ********************************************************/ 561/*** END PROTOTYPES ********************************************************/
587/*****************************************************************************/ 562/*****************************************************************************/
588/*** BEGIN Interface Used by the World ***************************************/ 563/*** BEGIN Interface Used by the World ***************************************/
589 564
590static int opencount = 0; 565static int opencount;
591 566
592/*--- Open /dev/fbx ---------------------------------------------------------*/ 567/*--- Open /dev/fbx ---------------------------------------------------------*/
593static int cirrusfb_open (struct fb_info *info, int user) 568static int cirrusfb_open(struct fb_info *info, int user)
594{ 569{
595 if (opencount++ == 0) 570 if (opencount++ == 0)
596 switch_monitor (info->par, 1); 571 switch_monitor(info->par, 1);
597 return 0; 572 return 0;
598} 573}
599 574
600/*--- Close /dev/fbx --------------------------------------------------------*/ 575/*--- Close /dev/fbx --------------------------------------------------------*/
601static int cirrusfb_release (struct fb_info *info, int user) 576static int cirrusfb_release(struct fb_info *info, int user)
602{ 577{
603 if (--opencount == 0) 578 if (--opencount == 0)
604 switch_monitor (info->par, 0); 579 switch_monitor(info->par, 0);
605 return 0; 580 return 0;
606} 581}
607 582
@@ -610,11 +585,11 @@ static int cirrusfb_release (struct fb_info *info, int user)
610/**** BEGIN Hardware specific Routines **************************************/ 585/**** BEGIN Hardware specific Routines **************************************/
611 586
612/* Get a good MCLK value */ 587/* Get a good MCLK value */
613static long cirrusfb_get_mclk (long freq, int bpp, long *div) 588static long cirrusfb_get_mclk(long freq, int bpp, long *div)
614{ 589{
615 long mclk; 590 long mclk;
616 591
617 assert (div != NULL); 592 assert(div != NULL);
618 593
619 /* Calculate MCLK, in case VCLK is high enough to require > 50MHz. 594 /* Calculate MCLK, in case VCLK is high enough to require > 50MHz.
620 * Assume a 64-bit data path for now. The formula is: 595 * Assume a 64-bit data path for now. The formula is:
@@ -624,23 +599,23 @@ static long cirrusfb_get_mclk (long freq, int bpp, long *div)
624 mclk = (mclk * 12) / 10; 599 mclk = (mclk * 12) / 10;
625 if (mclk < 50000) 600 if (mclk < 50000)
626 mclk = 50000; 601 mclk = 50000;
627 DPRINTK ("Use MCLK of %ld kHz\n", mclk); 602 DPRINTK("Use MCLK of %ld kHz\n", mclk);
628 603
629 /* Calculate value for SR1F. Multiply by 2 so we can round up. */ 604 /* Calculate value for SR1F. Multiply by 2 so we can round up. */
630 mclk = ((mclk * 16) / 14318); 605 mclk = ((mclk * 16) / 14318);
631 mclk = (mclk + 1) / 2; 606 mclk = (mclk + 1) / 2;
632 DPRINTK ("Set SR1F[5:0] to 0x%lx\n", mclk); 607 DPRINTK("Set SR1F[5:0] to 0x%lx\n", mclk);
633 608
634 /* Determine if we should use MCLK instead of VCLK, and if so, what we 609 /* Determine if we should use MCLK instead of VCLK, and if so, what we
635 * should divide it by to get VCLK */ 610 * should divide it by to get VCLK */
636 switch (freq) { 611 switch (freq) {
637 case 24751 ... 25249: 612 case 24751 ... 25249:
638 *div = 2; 613 *div = 2;
639 DPRINTK ("Using VCLK = MCLK/2\n"); 614 DPRINTK("Using VCLK = MCLK/2\n");
640 break; 615 break;
641 case 49501 ... 50499: 616 case 49501 ... 50499:
642 *div = 1; 617 *div = 1;
643 DPRINTK ("Using VCLK = MCLK\n"); 618 DPRINTK("Using VCLK = MCLK\n");
644 break; 619 break;
645 default: 620 default:
646 *div = 0; 621 *div = 0;
@@ -653,7 +628,6 @@ static long cirrusfb_get_mclk (long freq, int bpp, long *div)
653static int cirrusfb_check_var(struct fb_var_screeninfo *var, 628static int cirrusfb_check_var(struct fb_var_screeninfo *var,
654 struct fb_info *info) 629 struct fb_info *info)
655{ 630{
656 struct cirrusfb_info *cinfo = info->par;
657 int nom, den; /* translyting from pixels->bytes */ 631 int nom, den; /* translyting from pixels->bytes */
658 int yres, i; 632 int yres, i;
659 static struct { int xres, yres; } modes[] = 633 static struct { int xres, yres; } modes[] =
@@ -665,63 +639,55 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
665 { -1, -1 } }; 639 { -1, -1 } };
666 640
667 switch (var->bits_per_pixel) { 641 switch (var->bits_per_pixel) {
668 case 0 ... 1: 642 case 1:
669 var->bits_per_pixel = 1;
670 nom = 4; 643 nom = 4;
671 den = 8; 644 den = 8;
672 break; /* 8 pixel per byte, only 1/4th of mem usable */ 645 break; /* 8 pixel per byte, only 1/4th of mem usable */
673 case 2 ... 8: 646 case 8:
674 var->bits_per_pixel = 8; 647 case 16:
675 nom = 1; 648 case 24:
649 case 32:
650 nom = var->bits_per_pixel / 8;
676 den = 1; 651 den = 1;
677 break; /* 1 pixel == 1 byte */ 652 break; /* 1 pixel == 1 byte */
678 case 9 ... 16:
679 var->bits_per_pixel = 16;
680 nom = 2;
681 den = 1;
682 break; /* 2 bytes per pixel */
683 case 17 ... 24:
684 var->bits_per_pixel = 24;
685 nom = 3;
686 den = 1;
687 break; /* 3 bytes per pixel */
688 case 25 ... 32:
689 var->bits_per_pixel = 32;
690 nom = 4;
691 den = 1;
692 break; /* 4 bytes per pixel */
693 default: 653 default:
694 printk ("cirrusfb: mode %dx%dx%d rejected...color depth not supported.\n", 654 printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
655 "color depth not supported.\n",
695 var->xres, var->yres, var->bits_per_pixel); 656 var->xres, var->yres, var->bits_per_pixel);
696 DPRINTK ("EXIT - EINVAL error\n"); 657 DPRINTK("EXIT - EINVAL error\n");
697 return -EINVAL; 658 return -EINVAL;
698 } 659 }
699 660
700 if (var->xres * nom / den * var->yres > cinfo->size) { 661 if (var->xres * nom / den * var->yres > info->screen_size) {
701 printk ("cirrusfb: mode %dx%dx%d rejected...resolution too high to fit into video memory!\n", 662 printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
663 "resolution too high to fit into video memory!\n",
702 var->xres, var->yres, var->bits_per_pixel); 664 var->xres, var->yres, var->bits_per_pixel);
703 DPRINTK ("EXIT - EINVAL error\n"); 665 DPRINTK("EXIT - EINVAL error\n");
704 return -EINVAL; 666 return -EINVAL;
705 } 667 }
706 668
707 /* use highest possible virtual resolution */ 669 /* use highest possible virtual resolution */
708 if (var->xres_virtual == -1 && 670 if (var->xres_virtual == -1 &&
709 var->yres_virtual == -1) { 671 var->yres_virtual == -1) {
710 printk ("cirrusfb: using maximum available virtual resolution\n"); 672 printk(KERN_INFO
673 "cirrusfb: using maximum available virtual resolution\n");
711 for (i = 0; modes[i].xres != -1; i++) { 674 for (i = 0; modes[i].xres != -1; i++) {
712 if (modes[i].xres * nom / den * modes[i].yres < cinfo->size / 2) 675 int size = modes[i].xres * nom / den * modes[i].yres;
676 if (size < info->screen_size / 2)
713 break; 677 break;
714 } 678 }
715 if (modes[i].xres == -1) { 679 if (modes[i].xres == -1) {
716 printk ("cirrusfb: could not find a virtual resolution that fits into video memory!!\n"); 680 printk(KERN_ERR "cirrusfb: could not find a virtual "
717 DPRINTK ("EXIT - EINVAL error\n"); 681 "resolution that fits into video memory!!\n");
682 DPRINTK("EXIT - EINVAL error\n");
718 return -EINVAL; 683 return -EINVAL;
719 } 684 }
720 var->xres_virtual = modes[i].xres; 685 var->xres_virtual = modes[i].xres;
721 var->yres_virtual = modes[i].yres; 686 var->yres_virtual = modes[i].yres;
722 687
723 printk ("cirrusfb: virtual resolution set to maximum of %dx%d\n", 688 printk(KERN_INFO "cirrusfb: virtual resolution set to "
724 var->xres_virtual, var->yres_virtual); 689 "maximum of %dx%d\n", var->xres_virtual,
690 var->yres_virtual);
725 } 691 }
726 692
727 if (var->xres_virtual < var->xres) 693 if (var->xres_virtual < var->xres)
@@ -744,23 +710,19 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
744 case 1: 710 case 1:
745 var->red.offset = 0; 711 var->red.offset = 0;
746 var->red.length = 1; 712 var->red.length = 1;
747 var->green.offset = 0; 713 var->green = var->red;
748 var->green.length = 1; 714 var->blue = var->red;
749 var->blue.offset = 0;
750 var->blue.length = 1;
751 break; 715 break;
752 716
753 case 8: 717 case 8:
754 var->red.offset = 0; 718 var->red.offset = 0;
755 var->red.length = 6; 719 var->red.length = 6;
756 var->green.offset = 0; 720 var->green = var->red;
757 var->green.length = 6; 721 var->blue = var->red;
758 var->blue.offset = 0;
759 var->blue.length = 6;
760 break; 722 break;
761 723
762 case 16: 724 case 16:
763 if(isPReP) { 725 if (isPReP) {
764 var->red.offset = 2; 726 var->red.offset = 2;
765 var->green.offset = -3; 727 var->green.offset = -3;
766 var->blue.offset = 8; 728 var->blue.offset = 8;
@@ -775,22 +737,8 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
775 break; 737 break;
776 738
777 case 24: 739 case 24:
778 if(isPReP) {
779 var->red.offset = 8;
780 var->green.offset = 16;
781 var->blue.offset = 24;
782 } else {
783 var->red.offset = 16;
784 var->green.offset = 8;
785 var->blue.offset = 0;
786 }
787 var->red.length = 8;
788 var->green.length = 8;
789 var->blue.length = 8;
790 break;
791
792 case 32: 740 case 32:
793 if(isPReP) { 741 if (isPReP) {
794 var->red.offset = 8; 742 var->red.offset = 8;
795 var->green.offset = 16; 743 var->green.offset = 16;
796 var->blue.offset = 24; 744 var->blue.offset = 24;
@@ -825,54 +773,42 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
825 yres = (yres + 1) / 2; 773 yres = (yres + 1) / 2;
826 774
827 if (yres >= 1280) { 775 if (yres >= 1280) {
828 printk (KERN_WARNING "cirrusfb: ERROR: VerticalTotal >= 1280; special treatment required! (TODO)\n"); 776 printk(KERN_ERR "cirrusfb: ERROR: VerticalTotal >= 1280; "
829 DPRINTK ("EXIT - EINVAL error\n"); 777 "special treatment required! (TODO)\n");
778 DPRINTK("EXIT - EINVAL error\n");
830 return -EINVAL; 779 return -EINVAL;
831 } 780 }
832 781
833 return 0; 782 return 0;
834} 783}
835 784
836static int cirrusfb_decode_var (const struct fb_var_screeninfo *var, 785static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
837 struct cirrusfb_regs *regs, 786 struct cirrusfb_regs *regs,
838 const struct fb_info *info) 787 struct fb_info *info)
839{ 788{
840 long freq; 789 long freq;
841 long maxclock; 790 long maxclock;
842 int maxclockidx = 0; 791 int maxclockidx = var->bits_per_pixel >> 3;
843 struct cirrusfb_info *cinfo = info->par; 792 struct cirrusfb_info *cinfo = info->par;
844 int xres, hfront, hsync, hback; 793 int xres, hfront, hsync, hback;
845 int yres, vfront, vsync, vback; 794 int yres, vfront, vsync, vback;
846 795
847 switch(var->bits_per_pixel) { 796 switch (var->bits_per_pixel) {
848 case 1: 797 case 1:
849 regs->line_length = var->xres_virtual / 8; 798 info->fix.line_length = var->xres_virtual / 8;
850 regs->visual = FB_VISUAL_MONO10; 799 info->fix.visual = FB_VISUAL_MONO10;
851 maxclockidx = 0;
852 break; 800 break;
853 801
854 case 8: 802 case 8:
855 regs->line_length = var->xres_virtual; 803 info->fix.line_length = var->xres_virtual;
856 regs->visual = FB_VISUAL_PSEUDOCOLOR; 804 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
857 maxclockidx = 1;
858 break; 805 break;
859 806
860 case 16: 807 case 16:
861 regs->line_length = var->xres_virtual * 2;
862 regs->visual = FB_VISUAL_DIRECTCOLOR;
863 maxclockidx = 2;
864 break;
865
866 case 24: 808 case 24:
867 regs->line_length = var->xres_virtual * 3;
868 regs->visual = FB_VISUAL_DIRECTCOLOR;
869 maxclockidx = 3;
870 break;
871
872 case 32: 809 case 32:
873 regs->line_length = var->xres_virtual * 4; 810 info->fix.line_length = var->xres_virtual * maxclockidx;
874 regs->visual = FB_VISUAL_DIRECTCOLOR; 811 info->fix.visual = FB_VISUAL_DIRECTCOLOR;
875 maxclockidx = 4;
876 break; 812 break;
877 813
878 default: 814 default:
@@ -882,12 +818,12 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
882 break; 818 break;
883 } 819 }
884 820
885 regs->type = FB_TYPE_PACKED_PIXELS; 821 info->fix.type = FB_TYPE_PACKED_PIXELS;
886 822
887 /* convert from ps to kHz */ 823 /* convert from ps to kHz */
888 freq = 1000000000 / var->pixclock; 824 freq = PICOS2KHZ(var->pixclock);
889 825
890 DPRINTK ("desired pixclock: %ld kHz\n", freq); 826 DPRINTK("desired pixclock: %ld kHz\n", freq);
891 827
892 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx]; 828 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
893 regs->multiplexing = 0; 829 regs->multiplexing = 0;
@@ -902,8 +838,9 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
902 break; 838 break;
903 839
904 default: 840 default:
905 printk (KERN_WARNING "cirrusfb: ERROR: Frequency greater than maxclock (%ld kHz)\n", maxclock); 841 printk(KERN_ERR "cirrusfb: Frequency greater "
906 DPRINTK ("EXIT - return -EINVAL\n"); 842 "than maxclock (%ld kHz)\n", maxclock);
843 DPRINTK("EXIT - return -EINVAL\n");
907 return -EINVAL; 844 return -EINVAL;
908 } 845 }
909 } 846 }
@@ -914,14 +851,16 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
914 case 16: 851 case 16:
915 case 32: 852 case 32:
916 if (regs->HorizRes <= 800) 853 if (regs->HorizRes <= 800)
917 freq /= 2; /* Xbh has this type of clock for 32-bit */ 854 /* Xbh has this type of clock for 32-bit */
855 freq /= 2;
918 break; 856 break;
919 } 857 }
920#endif 858#endif
921 859
922 bestclock (freq, &regs->freq, &regs->nom, &regs->den, &regs->div, 860 bestclock(freq, &regs->freq, &regs->nom, &regs->den, &regs->div,
923 maxclock); 861 maxclock);
924 regs->mclk = cirrusfb_get_mclk (freq, var->bits_per_pixel, &regs->divMCLK); 862 regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel,
863 &regs->divMCLK);
925 864
926 xres = var->xres; 865 xres = var->xres;
927 hfront = var->right_margin; 866 hfront = var->right_margin;
@@ -948,7 +887,8 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
948 regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5; 887 regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
949 regs->HorizDispEnd = xres / 8 - 1; 888 regs->HorizDispEnd = xres / 8 - 1;
950 regs->HorizBlankStart = xres / 8; 889 regs->HorizBlankStart = xres / 8;
951 regs->HorizBlankEnd = regs->HorizTotal + 5; /* does not count with "-5" */ 890 /* does not count with "-5" */
891 regs->HorizBlankEnd = regs->HorizTotal + 5;
952 regs->HorizSyncStart = (xres + hfront) / 8 + 1; 892 regs->HorizSyncStart = (xres + hfront) / 8 + 1;
953 regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1; 893 regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
954 894
@@ -976,23 +916,23 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
976 return 0; 916 return 0;
977} 917}
978 918
979 919static void cirrusfb_set_mclk(const struct cirrusfb_info *cinfo, int val,
980static void cirrusfb_set_mclk (const struct cirrusfb_info *cinfo, int val, int div) 920 int div)
981{ 921{
982 assert (cinfo != NULL); 922 assert(cinfo != NULL);
983 923
984 if (div == 2) { 924 if (div == 2) {
985 /* VCLK = MCLK/2 */ 925 /* VCLK = MCLK/2 */
986 unsigned char old = vga_rseq (cinfo->regbase, CL_SEQR1E); 926 unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
987 vga_wseq (cinfo->regbase, CL_SEQR1E, old | 0x1); 927 vga_wseq(cinfo->regbase, CL_SEQR1E, old | 0x1);
988 vga_wseq (cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f)); 928 vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
989 } else if (div == 1) { 929 } else if (div == 1) {
990 /* VCLK = MCLK */ 930 /* VCLK = MCLK */
991 unsigned char old = vga_rseq (cinfo->regbase, CL_SEQR1E); 931 unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
992 vga_wseq (cinfo->regbase, CL_SEQR1E, old & ~0x1); 932 vga_wseq(cinfo->regbase, CL_SEQR1E, old & ~0x1);
993 vga_wseq (cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f)); 933 vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
994 } else { 934 } else {
995 vga_wseq (cinfo->regbase, CL_SEQR1F, val & 0x3f); 935 vga_wseq(cinfo->regbase, CL_SEQR1F, val & 0x3f);
996 } 936 }
997} 937}
998 938
@@ -1001,7 +941,7 @@ static void cirrusfb_set_mclk (const struct cirrusfb_info *cinfo, int val, int d
1001 941
1002 actually writes the values for a new video mode into the hardware, 942 actually writes the values for a new video mode into the hardware,
1003**************************************************************************/ 943**************************************************************************/
1004static int cirrusfb_set_par_foo (struct fb_info *info) 944static int cirrusfb_set_par_foo(struct fb_info *info)
1005{ 945{
1006 struct cirrusfb_info *cinfo = info->par; 946 struct cirrusfb_info *cinfo = info->par;
1007 struct fb_var_screeninfo *var = &info->var; 947 struct fb_var_screeninfo *var = &info->var;
@@ -1011,15 +951,15 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1011 int offset = 0, err; 951 int offset = 0, err;
1012 const struct cirrusfb_board_info_rec *bi; 952 const struct cirrusfb_board_info_rec *bi;
1013 953
1014 DPRINTK ("ENTER\n"); 954 DPRINTK("ENTER\n");
1015 DPRINTK ("Requested mode: %dx%dx%d\n", 955 DPRINTK("Requested mode: %dx%dx%d\n",
1016 var->xres, var->yres, var->bits_per_pixel); 956 var->xres, var->yres, var->bits_per_pixel);
1017 DPRINTK ("pixclock: %d\n", var->pixclock); 957 DPRINTK("pixclock: %d\n", var->pixclock);
1018 958
1019 init_vgachip (cinfo); 959 init_vgachip(info);
1020 960
1021 err = cirrusfb_decode_var(var, &regs, info); 961 err = cirrusfb_decode_var(var, &regs, info);
1022 if(err) { 962 if (err) {
1023 /* should never happen */ 963 /* should never happen */
1024 DPRINTK("mode change aborted. invalid var.\n"); 964 DPRINTK("mode change aborted. invalid var.\n");
1025 return -EINVAL; 965 return -EINVAL;
@@ -1027,34 +967,35 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1027 967
1028 bi = &cirrusfb_board_info[cinfo->btype]; 968 bi = &cirrusfb_board_info[cinfo->btype];
1029 969
1030
1031 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ 970 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
1032 vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ 971 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
1033 972
1034 /* if debugging is enabled, all parameters get output before writing */ 973 /* if debugging is enabled, all parameters get output before writing */
1035 DPRINTK ("CRT0: %ld\n", regs.HorizTotal); 974 DPRINTK("CRT0: %ld\n", regs.HorizTotal);
1036 vga_wcrt (regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal); 975 vga_wcrt(regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal);
1037 976
1038 DPRINTK ("CRT1: %ld\n", regs.HorizDispEnd); 977 DPRINTK("CRT1: %ld\n", regs.HorizDispEnd);
1039 vga_wcrt (regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd); 978 vga_wcrt(regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd);
1040 979
1041 DPRINTK ("CRT2: %ld\n", regs.HorizBlankStart); 980 DPRINTK("CRT2: %ld\n", regs.HorizBlankStart);
1042 vga_wcrt (regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart); 981 vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart);
1043 982
1044 DPRINTK ("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32); /* + 128: Compatible read */ 983 /* + 128: Compatible read */
1045 vga_wcrt (regbase, VGA_CRTC_H_BLANK_END, 128 + (regs.HorizBlankEnd % 32)); 984 DPRINTK("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32);
985 vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
986 128 + (regs.HorizBlankEnd % 32));
1046 987
1047 DPRINTK ("CRT4: %ld\n", regs.HorizSyncStart); 988 DPRINTK("CRT4: %ld\n", regs.HorizSyncStart);
1048 vga_wcrt (regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart); 989 vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart);
1049 990
1050 tmp = regs.HorizSyncEnd % 32; 991 tmp = regs.HorizSyncEnd % 32;
1051 if (regs.HorizBlankEnd & 32) 992 if (regs.HorizBlankEnd & 32)
1052 tmp += 128; 993 tmp += 128;
1053 DPRINTK ("CRT5: %d\n", tmp); 994 DPRINTK("CRT5: %d\n", tmp);
1054 vga_wcrt (regbase, VGA_CRTC_H_SYNC_END, tmp); 995 vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
1055 996
1056 DPRINTK ("CRT6: %ld\n", regs.VertTotal & 0xff); 997 DPRINTK("CRT6: %ld\n", regs.VertTotal & 0xff);
1057 vga_wcrt (regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff)); 998 vga_wcrt(regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff));
1058 999
1059 tmp = 16; /* LineCompare bit #9 */ 1000 tmp = 16; /* LineCompare bit #9 */
1060 if (regs.VertTotal & 256) 1001 if (regs.VertTotal & 256)
@@ -1071,34 +1012,34 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1071 tmp |= 64; 1012 tmp |= 64;
1072 if (regs.VertSyncStart & 512) 1013 if (regs.VertSyncStart & 512)
1073 tmp |= 128; 1014 tmp |= 128;
1074 DPRINTK ("CRT7: %d\n", tmp); 1015 DPRINTK("CRT7: %d\n", tmp);
1075 vga_wcrt (regbase, VGA_CRTC_OVERFLOW, tmp); 1016 vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
1076 1017
1077 tmp = 0x40; /* LineCompare bit #8 */ 1018 tmp = 0x40; /* LineCompare bit #8 */
1078 if (regs.VertBlankStart & 512) 1019 if (regs.VertBlankStart & 512)
1079 tmp |= 0x20; 1020 tmp |= 0x20;
1080 if (var->vmode & FB_VMODE_DOUBLE) 1021 if (var->vmode & FB_VMODE_DOUBLE)
1081 tmp |= 0x80; 1022 tmp |= 0x80;
1082 DPRINTK ("CRT9: %d\n", tmp); 1023 DPRINTK("CRT9: %d\n", tmp);
1083 vga_wcrt (regbase, VGA_CRTC_MAX_SCAN, tmp); 1024 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
1084 1025
1085 DPRINTK ("CRT10: %ld\n", regs.VertSyncStart & 0xff); 1026 DPRINTK("CRT10: %ld\n", regs.VertSyncStart & 0xff);
1086 vga_wcrt (regbase, VGA_CRTC_V_SYNC_START, (regs.VertSyncStart & 0xff)); 1027 vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, regs.VertSyncStart & 0xff);
1087 1028
1088 DPRINTK ("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16); 1029 DPRINTK("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16);
1089 vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, (regs.VertSyncEnd % 16 + 64 + 32)); 1030 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, regs.VertSyncEnd % 16 + 64 + 32);
1090 1031
1091 DPRINTK ("CRT12: %ld\n", regs.VertDispEnd & 0xff); 1032 DPRINTK("CRT12: %ld\n", regs.VertDispEnd & 0xff);
1092 vga_wcrt (regbase, VGA_CRTC_V_DISP_END, (regs.VertDispEnd & 0xff)); 1033 vga_wcrt(regbase, VGA_CRTC_V_DISP_END, regs.VertDispEnd & 0xff);
1093 1034
1094 DPRINTK ("CRT15: %ld\n", regs.VertBlankStart & 0xff); 1035 DPRINTK("CRT15: %ld\n", regs.VertBlankStart & 0xff);
1095 vga_wcrt (regbase, VGA_CRTC_V_BLANK_START, (regs.VertBlankStart & 0xff)); 1036 vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, regs.VertBlankStart & 0xff);
1096 1037
1097 DPRINTK ("CRT16: %ld\n", regs.VertBlankEnd & 0xff); 1038 DPRINTK("CRT16: %ld\n", regs.VertBlankEnd & 0xff);
1098 vga_wcrt (regbase, VGA_CRTC_V_BLANK_END, (regs.VertBlankEnd & 0xff)); 1039 vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, regs.VertBlankEnd & 0xff);
1099 1040
1100 DPRINTK ("CRT18: 0xff\n"); 1041 DPRINTK("CRT18: 0xff\n");
1101 vga_wcrt (regbase, VGA_CRTC_LINE_COMPARE, 0xff); 1042 vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
1102 1043
1103 tmp = 0; 1044 tmp = 0;
1104 if (var->vmode & FB_VMODE_INTERLACED) 1045 if (var->vmode & FB_VMODE_INTERLACED)
@@ -1112,57 +1053,63 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1112 if (regs.VertBlankEnd & 512) 1053 if (regs.VertBlankEnd & 512)
1113 tmp |= 128; 1054 tmp |= 128;
1114 1055
1115 DPRINTK ("CRT1a: %d\n", tmp); 1056 DPRINTK("CRT1a: %d\n", tmp);
1116 vga_wcrt (regbase, CL_CRT1A, tmp); 1057 vga_wcrt(regbase, CL_CRT1A, tmp);
1117 1058
1118 /* set VCLK0 */ 1059 /* set VCLK0 */
1119 /* hardware RefClock: 14.31818 MHz */ 1060 /* hardware RefClock: 14.31818 MHz */
1120 /* formula: VClk = (OSC * N) / (D * (1+P)) */ 1061 /* formula: VClk = (OSC * N) / (D * (1+P)) */
1121 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ 1062 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
1122 1063
1123 vga_wseq (regbase, CL_SEQRB, regs.nom); 1064 vga_wseq(regbase, CL_SEQRB, regs.nom);
1124 tmp = regs.den << 1; 1065 tmp = regs.den << 1;
1125 if (regs.div != 0) 1066 if (regs.div != 0)
1126 tmp |= 1; 1067 tmp |= 1;
1127 1068
1069 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
1128 if ((cinfo->btype == BT_SD64) || 1070 if ((cinfo->btype == BT_SD64) ||
1129 (cinfo->btype == BT_ALPINE) || 1071 (cinfo->btype == BT_ALPINE) ||
1130 (cinfo->btype == BT_GD5480)) 1072 (cinfo->btype == BT_GD5480))
1131 tmp |= 0x80; /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ 1073 tmp |= 0x80;
1132 1074
1133 DPRINTK ("CL_SEQR1B: %ld\n", (long) tmp); 1075 DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
1134 vga_wseq (regbase, CL_SEQR1B, tmp); 1076 vga_wseq(regbase, CL_SEQR1B, tmp);
1135 1077
1136 if (regs.VertRes >= 1024) 1078 if (regs.VertRes >= 1024)
1137 /* 1280x1024 */ 1079 /* 1280x1024 */
1138 vga_wcrt (regbase, VGA_CRTC_MODE, 0xc7); 1080 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
1139 else 1081 else
1140 /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit 1082 /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
1141 * address wrap, no compat. */ 1083 * address wrap, no compat. */
1142 vga_wcrt (regbase, VGA_CRTC_MODE, 0xc3); 1084 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
1143 1085
1144/* HAEH? vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, 0x20); * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */ 1086/* HAEH? vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);
1087 * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */
1145 1088
1146 /* don't know if it would hurt to also program this if no interlaced */ 1089 /* don't know if it would hurt to also program this if no interlaced */
1147 /* mode is used, but I feel better this way.. :-) */ 1090 /* mode is used, but I feel better this way.. :-) */
1148 if (var->vmode & FB_VMODE_INTERLACED) 1091 if (var->vmode & FB_VMODE_INTERLACED)
1149 vga_wcrt (regbase, VGA_CRTC_REGS, regs.HorizTotal / 2); 1092 vga_wcrt(regbase, VGA_CRTC_REGS, regs.HorizTotal / 2);
1150 else 1093 else
1151 vga_wcrt (regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ 1094 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
1152 1095
1153 vga_wseq (regbase, VGA_SEQ_CHARACTER_MAP, 0); 1096 vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0);
1154 1097
1155 /* adjust horizontal/vertical sync type (low/high) */ 1098 /* adjust horizontal/vertical sync type (low/high) */
1156 tmp = 0x03; /* enable display memory & CRTC I/O address for color mode */ 1099 /* enable display memory & CRTC I/O address for color mode */
1100 tmp = 0x03;
1157 if (var->sync & FB_SYNC_HOR_HIGH_ACT) 1101 if (var->sync & FB_SYNC_HOR_HIGH_ACT)
1158 tmp |= 0x40; 1102 tmp |= 0x40;
1159 if (var->sync & FB_SYNC_VERT_HIGH_ACT) 1103 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
1160 tmp |= 0x80; 1104 tmp |= 0x80;
1161 WGen (cinfo, VGA_MIS_W, tmp); 1105 WGen(cinfo, VGA_MIS_W, tmp);
1162 1106
1163 vga_wcrt (regbase, VGA_CRTC_PRESET_ROW, 0); /* Screen A Preset Row-Scan register */ 1107 /* Screen A Preset Row-Scan register */
1164 vga_wcrt (regbase, VGA_CRTC_CURSOR_START, 0); /* text cursor on and start line */ 1108 vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
1165 vga_wcrt (regbase, VGA_CRTC_CURSOR_END, 31); /* text cursor end line */ 1109 /* text cursor on and start line */
1110 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
1111 /* text cursor end line */
1112 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
1166 1113
1167 /****************************************************** 1114 /******************************************************
1168 * 1115 *
@@ -1172,8 +1119,8 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1172 1119
1173 /* programming for different color depths */ 1120 /* programming for different color depths */
1174 if (var->bits_per_pixel == 1) { 1121 if (var->bits_per_pixel == 1) {
1175 DPRINTK ("cirrusfb: preparing for 1 bit deep display\n"); 1122 DPRINTK("cirrusfb: preparing for 1 bit deep display\n");
1176 vga_wgfx (regbase, VGA_GFX_MODE, 0); /* mode register */ 1123 vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */
1177 1124
1178 /* SR07 */ 1125 /* SR07 */
1179 switch (cinfo->btype) { 1126 switch (cinfo->btype) {
@@ -1184,71 +1131,77 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1184 case BT_PICASSO4: 1131 case BT_PICASSO4:
1185 case BT_ALPINE: 1132 case BT_ALPINE:
1186 case BT_GD5480: 1133 case BT_GD5480:
1187 DPRINTK (" (for GD54xx)\n"); 1134 DPRINTK(" (for GD54xx)\n");
1188 vga_wseq (regbase, CL_SEQR7, 1135 vga_wseq(regbase, CL_SEQR7,
1189 regs.multiplexing ? 1136 regs.multiplexing ?
1190 bi->sr07_1bpp_mux : bi->sr07_1bpp); 1137 bi->sr07_1bpp_mux : bi->sr07_1bpp);
1191 break; 1138 break;
1192 1139
1193 case BT_LAGUNA: 1140 case BT_LAGUNA:
1194 DPRINTK (" (for GD546x)\n"); 1141 DPRINTK(" (for GD546x)\n");
1195 vga_wseq (regbase, CL_SEQR7, 1142 vga_wseq(regbase, CL_SEQR7,
1196 vga_rseq (regbase, CL_SEQR7) & ~0x01); 1143 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1197 break; 1144 break;
1198 1145
1199 default: 1146 default:
1200 printk (KERN_WARNING "cirrusfb: unknown Board\n"); 1147 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1201 break; 1148 break;
1202 } 1149 }
1203 1150
1204 /* Extended Sequencer Mode */ 1151 /* Extended Sequencer Mode */
1205 switch (cinfo->btype) { 1152 switch (cinfo->btype) {
1206 case BT_SD64: 1153 case BT_SD64:
1207 /* setting the SEQRF on SD64 is not necessary (only during init) */ 1154 /* setting the SEQRF on SD64 is not necessary
1208 DPRINTK ("(for SD64)\n"); 1155 * (only during init)
1209 vga_wseq (regbase, CL_SEQR1F, 0x1a); /* MCLK select */ 1156 */
1157 DPRINTK("(for SD64)\n");
1158 /* MCLK select */
1159 vga_wseq(regbase, CL_SEQR1F, 0x1a);
1210 break; 1160 break;
1211 1161
1212 case BT_PICCOLO: 1162 case BT_PICCOLO:
1213 DPRINTK ("(for Piccolo)\n"); 1163 case BT_SPECTRUM:
1214/* ### ueberall 0x22? */ 1164 DPRINTK("(for Piccolo/Spectrum)\n");
1215 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ##vorher 1c MCLK select */ 1165 /* ### ueberall 0x22? */
1216 vga_wseq (regbase, CL_SEQRF, 0xb0); /* evtl d0 bei 1 bit? avoid FIFO underruns..? */ 1166 /* ##vorher 1c MCLK select */
1167 vga_wseq(regbase, CL_SEQR1F, 0x22);
1168 /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
1169 vga_wseq(regbase, CL_SEQRF, 0xb0);
1217 break; 1170 break;
1218 1171
1219 case BT_PICASSO: 1172 case BT_PICASSO:
1220 DPRINTK ("(for Picasso)\n"); 1173 DPRINTK("(for Picasso)\n");
1221 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ##vorher 22 MCLK select */ 1174 /* ##vorher 22 MCLK select */
1222 vga_wseq (regbase, CL_SEQRF, 0xd0); /* ## vorher d0 avoid FIFO underruns..? */ 1175 vga_wseq(regbase, CL_SEQR1F, 0x22);
1223 break; 1176 /* ## vorher d0 avoid FIFO underruns..? */
1224 1177 vga_wseq(regbase, CL_SEQRF, 0xd0);
1225 case BT_SPECTRUM:
1226 DPRINTK ("(for Spectrum)\n");
1227/* ### ueberall 0x22? */
1228 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ##vorher 1c MCLK select */
1229 vga_wseq (regbase, CL_SEQRF, 0xb0); /* evtl d0? avoid FIFO underruns..? */
1230 break; 1178 break;
1231 1179
1232 case BT_PICASSO4: 1180 case BT_PICASSO4:
1233 case BT_ALPINE: 1181 case BT_ALPINE:
1234 case BT_GD5480: 1182 case BT_GD5480:
1235 case BT_LAGUNA: 1183 case BT_LAGUNA:
1236 DPRINTK (" (for GD54xx)\n"); 1184 DPRINTK(" (for GD54xx)\n");
1237 /* do nothing */ 1185 /* do nothing */
1238 break; 1186 break;
1239 1187
1240 default: 1188 default:
1241 printk (KERN_WARNING "cirrusfb: unknown Board\n"); 1189 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1242 break; 1190 break;
1243 } 1191 }
1244 1192
1245 WGen (cinfo, VGA_PEL_MSK, 0x01); /* pixel mask: pass-through for first plane */ 1193 /* pixel mask: pass-through for first plane */
1194 WGen(cinfo, VGA_PEL_MSK, 0x01);
1246 if (regs.multiplexing) 1195 if (regs.multiplexing)
1247 WHDR (cinfo, 0x4a); /* hidden dac reg: 1280x1024 */ 1196 /* hidden dac reg: 1280x1024 */
1197 WHDR(cinfo, 0x4a);
1248 else 1198 else
1249 WHDR (cinfo, 0); /* hidden dac: nothing */ 1199 /* hidden dac: nothing */
1250 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x06); /* memory mode: odd/even, ext. memory */ 1200 WHDR(cinfo, 0);
1251 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0x01); /* plane mask: only write to first plane */ 1201 /* memory mode: odd/even, ext. memory */
1202 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1203 /* plane mask: only write to first plane */
1204 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1252 offset = var->xres_virtual / 16; 1205 offset = var->xres_virtual / 16;
1253 } 1206 }
1254 1207
@@ -1259,7 +1212,7 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1259 */ 1212 */
1260 1213
1261 else if (var->bits_per_pixel == 8) { 1214 else if (var->bits_per_pixel == 8) {
1262 DPRINTK ("cirrusfb: preparing for 8 bit deep display\n"); 1215 DPRINTK("cirrusfb: preparing for 8 bit deep display\n");
1263 switch (cinfo->btype) { 1216 switch (cinfo->btype) {
1264 case BT_SD64: 1217 case BT_SD64:
1265 case BT_PICCOLO: 1218 case BT_PICCOLO:
@@ -1268,75 +1221,77 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1268 case BT_PICASSO4: 1221 case BT_PICASSO4:
1269 case BT_ALPINE: 1222 case BT_ALPINE:
1270 case BT_GD5480: 1223 case BT_GD5480:
1271 DPRINTK (" (for GD54xx)\n"); 1224 DPRINTK(" (for GD54xx)\n");
1272 vga_wseq (regbase, CL_SEQR7, 1225 vga_wseq(regbase, CL_SEQR7,
1273 regs.multiplexing ? 1226 regs.multiplexing ?
1274 bi->sr07_8bpp_mux : bi->sr07_8bpp); 1227 bi->sr07_8bpp_mux : bi->sr07_8bpp);
1275 break; 1228 break;
1276 1229
1277 case BT_LAGUNA: 1230 case BT_LAGUNA:
1278 DPRINTK (" (for GD546x)\n"); 1231 DPRINTK(" (for GD546x)\n");
1279 vga_wseq (regbase, CL_SEQR7, 1232 vga_wseq(regbase, CL_SEQR7,
1280 vga_rseq (regbase, CL_SEQR7) | 0x01); 1233 vga_rseq(regbase, CL_SEQR7) | 0x01);
1281 break; 1234 break;
1282 1235
1283 default: 1236 default:
1284 printk (KERN_WARNING "cirrusfb: unknown Board\n"); 1237 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1285 break; 1238 break;
1286 } 1239 }
1287 1240
1288 switch (cinfo->btype) { 1241 switch (cinfo->btype) {
1289 case BT_SD64: 1242 case BT_SD64:
1290 vga_wseq (regbase, CL_SEQR1F, 0x1d); /* MCLK select */ 1243 /* MCLK select */
1244 vga_wseq(regbase, CL_SEQR1F, 0x1d);
1291 break; 1245 break;
1292 1246
1293 case BT_PICCOLO: 1247 case BT_PICCOLO:
1294 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */
1295 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
1296 break;
1297
1298 case BT_PICASSO: 1248 case BT_PICASSO:
1299 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */
1300 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
1301 break;
1302
1303 case BT_SPECTRUM: 1249 case BT_SPECTRUM:
1304 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */ 1250 /* ### vorher 1c MCLK select */
1305 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */ 1251 vga_wseq(regbase, CL_SEQR1F, 0x22);
1252 /* Fast Page-Mode writes */
1253 vga_wseq(regbase, CL_SEQRF, 0xb0);
1306 break; 1254 break;
1307 1255
1308 case BT_PICASSO4: 1256 case BT_PICASSO4:
1309#ifdef CONFIG_ZORRO 1257#ifdef CONFIG_ZORRO
1310 vga_wseq (regbase, CL_SEQRF, 0xb8); /* ### INCOMPLETE!! */ 1258 /* ### INCOMPLETE!! */
1259 vga_wseq(regbase, CL_SEQRF, 0xb8);
1311#endif 1260#endif
1312/* vga_wseq (regbase, CL_SEQR1F, 0x1c); */ 1261/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1313 break; 1262 break;
1314 1263
1315 case BT_ALPINE: 1264 case BT_ALPINE:
1316 DPRINTK (" (for GD543x)\n"); 1265 DPRINTK(" (for GD543x)\n");
1317 cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK); 1266 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1318 /* We already set SRF and SR1F */ 1267 /* We already set SRF and SR1F */
1319 break; 1268 break;
1320 1269
1321 case BT_GD5480: 1270 case BT_GD5480:
1322 case BT_LAGUNA: 1271 case BT_LAGUNA:
1323 DPRINTK (" (for GD54xx)\n"); 1272 DPRINTK(" (for GD54xx)\n");
1324 /* do nothing */ 1273 /* do nothing */
1325 break; 1274 break;
1326 1275
1327 default: 1276 default:
1328 printk (KERN_WARNING "cirrusfb: unknown Board\n"); 1277 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1329 break; 1278 break;
1330 } 1279 }
1331 1280
1332 vga_wgfx (regbase, VGA_GFX_MODE, 64); /* mode register: 256 color mode */ 1281 /* mode register: 256 color mode */
1333 WGen (cinfo, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */ 1282 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1283 /* pixel mask: pass-through all planes */
1284 WGen(cinfo, VGA_PEL_MSK, 0xff);
1334 if (regs.multiplexing) 1285 if (regs.multiplexing)
1335 WHDR (cinfo, 0x4a); /* hidden dac reg: 1280x1024 */ 1286 /* hidden dac reg: 1280x1024 */
1287 WHDR(cinfo, 0x4a);
1336 else 1288 else
1337 WHDR (cinfo, 0); /* hidden dac: nothing */ 1289 /* hidden dac: nothing */
1338 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */ 1290 WHDR(cinfo, 0);
1339 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */ 1291 /* memory mode: chain4, ext. memory */
1292 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1293 /* plane mask: enable writing to all 4 planes */
1294 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1340 offset = var->xres_virtual / 8; 1295 offset = var->xres_virtual / 8;
1341 } 1296 }
1342 1297
@@ -1347,72 +1302,77 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1347 */ 1302 */
1348 1303
1349 else if (var->bits_per_pixel == 16) { 1304 else if (var->bits_per_pixel == 16) {
1350 DPRINTK ("cirrusfb: preparing for 16 bit deep display\n"); 1305 DPRINTK("cirrusfb: preparing for 16 bit deep display\n");
1351 switch (cinfo->btype) { 1306 switch (cinfo->btype) {
1352 case BT_SD64: 1307 case BT_SD64:
1353 vga_wseq (regbase, CL_SEQR7, 0xf7); /* Extended Sequencer Mode: 256c col. mode */ 1308 /* Extended Sequencer Mode: 256c col. mode */
1354 vga_wseq (regbase, CL_SEQR1F, 0x1e); /* MCLK select */ 1309 vga_wseq(regbase, CL_SEQR7, 0xf7);
1310 /* MCLK select */
1311 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1355 break; 1312 break;
1356 1313
1357 case BT_PICCOLO: 1314 case BT_PICCOLO:
1358 vga_wseq (regbase, CL_SEQR7, 0x87); 1315 case BT_SPECTRUM:
1359 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */ 1316 vga_wseq(regbase, CL_SEQR7, 0x87);
1360 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */ 1317 /* Fast Page-Mode writes */
1318 vga_wseq(regbase, CL_SEQRF, 0xb0);
1319 /* MCLK select */
1320 vga_wseq(regbase, CL_SEQR1F, 0x22);
1361 break; 1321 break;
1362 1322
1363 case BT_PICASSO: 1323 case BT_PICASSO:
1364 vga_wseq (regbase, CL_SEQR7, 0x27); 1324 vga_wseq(regbase, CL_SEQR7, 0x27);
1365 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */ 1325 /* Fast Page-Mode writes */
1366 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */ 1326 vga_wseq(regbase, CL_SEQRF, 0xb0);
1367 break; 1327 /* MCLK select */
1368 1328 vga_wseq(regbase, CL_SEQR1F, 0x22);
1369 case BT_SPECTRUM:
1370 vga_wseq (regbase, CL_SEQR7, 0x87);
1371 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
1372 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */
1373 break; 1329 break;
1374 1330
1375 case BT_PICASSO4: 1331 case BT_PICASSO4:
1376 vga_wseq (regbase, CL_SEQR7, 0x27); 1332 vga_wseq(regbase, CL_SEQR7, 0x27);
1377/* vga_wseq (regbase, CL_SEQR1F, 0x1c); */ 1333/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1378 break; 1334 break;
1379 1335
1380 case BT_ALPINE: 1336 case BT_ALPINE:
1381 DPRINTK (" (for GD543x)\n"); 1337 DPRINTK(" (for GD543x)\n");
1382 if (regs.HorizRes >= 1024) 1338 if (regs.HorizRes >= 1024)
1383 vga_wseq (regbase, CL_SEQR7, 0xa7); 1339 vga_wseq(regbase, CL_SEQR7, 0xa7);
1384 else 1340 else
1385 vga_wseq (regbase, CL_SEQR7, 0xa3); 1341 vga_wseq(regbase, CL_SEQR7, 0xa3);
1386 cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK); 1342 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1387 break; 1343 break;
1388 1344
1389 case BT_GD5480: 1345 case BT_GD5480:
1390 DPRINTK (" (for GD5480)\n"); 1346 DPRINTK(" (for GD5480)\n");
1391 vga_wseq (regbase, CL_SEQR7, 0x17); 1347 vga_wseq(regbase, CL_SEQR7, 0x17);
1392 /* We already set SRF and SR1F */ 1348 /* We already set SRF and SR1F */
1393 break; 1349 break;
1394 1350
1395 case BT_LAGUNA: 1351 case BT_LAGUNA:
1396 DPRINTK (" (for GD546x)\n"); 1352 DPRINTK(" (for GD546x)\n");
1397 vga_wseq (regbase, CL_SEQR7, 1353 vga_wseq(regbase, CL_SEQR7,
1398 vga_rseq (regbase, CL_SEQR7) & ~0x01); 1354 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1399 break; 1355 break;
1400 1356
1401 default: 1357 default:
1402 printk (KERN_WARNING "CIRRUSFB: unknown Board\n"); 1358 printk(KERN_WARNING "CIRRUSFB: unknown Board\n");
1403 break; 1359 break;
1404 } 1360 }
1405 1361
1406 vga_wgfx (regbase, VGA_GFX_MODE, 64); /* mode register: 256 color mode */ 1362 /* mode register: 256 color mode */
1407 WGen (cinfo, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */ 1363 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1364 /* pixel mask: pass-through all planes */
1365 WGen(cinfo, VGA_PEL_MSK, 0xff);
1408#ifdef CONFIG_PCI 1366#ifdef CONFIG_PCI
1409 WHDR (cinfo, 0xc0); /* Copy Xbh */ 1367 WHDR(cinfo, 0xc0); /* Copy Xbh */
1410#elif defined(CONFIG_ZORRO) 1368#elif defined(CONFIG_ZORRO)
1411 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */ 1369 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1412 WHDR (cinfo, 0xa0); /* hidden dac reg: nothing special */ 1370 WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
1413#endif 1371#endif
1414 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */ 1372 /* memory mode: chain4, ext. memory */
1415 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */ 1373 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1374 /* plane mask: enable writing to all 4 planes */
1375 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1416 offset = var->xres_virtual / 4; 1376 offset = var->xres_virtual / 4;
1417 } 1377 }
1418 1378
@@ -1423,64 +1383,70 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1423 */ 1383 */
1424 1384
1425 else if (var->bits_per_pixel == 32) { 1385 else if (var->bits_per_pixel == 32) {
1426 DPRINTK ("cirrusfb: preparing for 24/32 bit deep display\n"); 1386 DPRINTK("cirrusfb: preparing for 24/32 bit deep display\n");
1427 switch (cinfo->btype) { 1387 switch (cinfo->btype) {
1428 case BT_SD64: 1388 case BT_SD64:
1429 vga_wseq (regbase, CL_SEQR7, 0xf9); /* Extended Sequencer Mode: 256c col. mode */ 1389 /* Extended Sequencer Mode: 256c col. mode */
1430 vga_wseq (regbase, CL_SEQR1F, 0x1e); /* MCLK select */ 1390 vga_wseq(regbase, CL_SEQR7, 0xf9);
1391 /* MCLK select */
1392 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1431 break; 1393 break;
1432 1394
1433 case BT_PICCOLO: 1395 case BT_PICCOLO:
1434 vga_wseq (regbase, CL_SEQR7, 0x85); 1396 case BT_SPECTRUM:
1435 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */ 1397 vga_wseq(regbase, CL_SEQR7, 0x85);
1436 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */ 1398 /* Fast Page-Mode writes */
1399 vga_wseq(regbase, CL_SEQRF, 0xb0);
1400 /* MCLK select */
1401 vga_wseq(regbase, CL_SEQR1F, 0x22);
1437 break; 1402 break;
1438 1403
1439 case BT_PICASSO: 1404 case BT_PICASSO:
1440 vga_wseq (regbase, CL_SEQR7, 0x25); 1405 vga_wseq(regbase, CL_SEQR7, 0x25);
1441 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */ 1406 /* Fast Page-Mode writes */
1442 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */ 1407 vga_wseq(regbase, CL_SEQRF, 0xb0);
1443 break; 1408 /* MCLK select */
1444 1409 vga_wseq(regbase, CL_SEQR1F, 0x22);
1445 case BT_SPECTRUM:
1446 vga_wseq (regbase, CL_SEQR7, 0x85);
1447 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
1448 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */
1449 break; 1410 break;
1450 1411
1451 case BT_PICASSO4: 1412 case BT_PICASSO4:
1452 vga_wseq (regbase, CL_SEQR7, 0x25); 1413 vga_wseq(regbase, CL_SEQR7, 0x25);
1453/* vga_wseq (regbase, CL_SEQR1F, 0x1c); */ 1414/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1454 break; 1415 break;
1455 1416
1456 case BT_ALPINE: 1417 case BT_ALPINE:
1457 DPRINTK (" (for GD543x)\n"); 1418 DPRINTK(" (for GD543x)\n");
1458 vga_wseq (regbase, CL_SEQR7, 0xa9); 1419 vga_wseq(regbase, CL_SEQR7, 0xa9);
1459 cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK); 1420 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1460 break; 1421 break;
1461 1422
1462 case BT_GD5480: 1423 case BT_GD5480:
1463 DPRINTK (" (for GD5480)\n"); 1424 DPRINTK(" (for GD5480)\n");
1464 vga_wseq (regbase, CL_SEQR7, 0x19); 1425 vga_wseq(regbase, CL_SEQR7, 0x19);
1465 /* We already set SRF and SR1F */ 1426 /* We already set SRF and SR1F */
1466 break; 1427 break;
1467 1428
1468 case BT_LAGUNA: 1429 case BT_LAGUNA:
1469 DPRINTK (" (for GD546x)\n"); 1430 DPRINTK(" (for GD546x)\n");
1470 vga_wseq (regbase, CL_SEQR7, 1431 vga_wseq(regbase, CL_SEQR7,
1471 vga_rseq (regbase, CL_SEQR7) & ~0x01); 1432 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1472 break; 1433 break;
1473 1434
1474 default: 1435 default:
1475 printk (KERN_WARNING "cirrusfb: unknown Board\n"); 1436 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1476 break; 1437 break;
1477 } 1438 }
1478 1439
1479 vga_wgfx (regbase, VGA_GFX_MODE, 64); /* mode register: 256 color mode */ 1440 /* mode register: 256 color mode */
1480 WGen (cinfo, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */ 1441 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1481 WHDR (cinfo, 0xc5); /* hidden dac reg: 8-8-8 mode (24 or 32) */ 1442 /* pixel mask: pass-through all planes */
1482 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */ 1443 WGen(cinfo, VGA_PEL_MSK, 0xff);
1483 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */ 1444 /* hidden dac reg: 8-8-8 mode (24 or 32) */
1445 WHDR(cinfo, 0xc5);
1446 /* memory mode: chain4, ext. memory */
1447 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1448 /* plane mask: enable writing to all 4 planes */
1449 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1484 offset = var->xres_virtual / 4; 1450 offset = var->xres_virtual / 4;
1485 } 1451 }
1486 1452
@@ -1490,48 +1456,67 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1490 * 1456 *
1491 */ 1457 */
1492 1458
1493 else { 1459 else
1494 printk (KERN_ERR "cirrusfb: What's this?? requested color depth == %d.\n", 1460 printk(KERN_ERR "cirrusfb: What's this?? "
1461 " requested color depth == %d.\n",
1495 var->bits_per_pixel); 1462 var->bits_per_pixel);
1496 }
1497 1463
1498 vga_wcrt (regbase, VGA_CRTC_OFFSET, offset & 0xff); 1464 vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff);
1499 tmp = 0x22; 1465 tmp = 0x22;
1500 if (offset & 0x100) 1466 if (offset & 0x100)
1501 tmp |= 0x10; /* offset overflow bit */ 1467 tmp |= 0x10; /* offset overflow bit */
1502 1468
1503 vga_wcrt (regbase, CL_CRT1B, tmp); /* screen start addr #16-18, fastpagemode cycles */ 1469 /* screen start addr #16-18, fastpagemode cycles */
1470 vga_wcrt(regbase, CL_CRT1B, tmp);
1504 1471
1505 if (cinfo->btype == BT_SD64 || 1472 if (cinfo->btype == BT_SD64 ||
1506 cinfo->btype == BT_PICASSO4 || 1473 cinfo->btype == BT_PICASSO4 ||
1507 cinfo->btype == BT_ALPINE || 1474 cinfo->btype == BT_ALPINE ||
1508 cinfo->btype == BT_GD5480) 1475 cinfo->btype == BT_GD5480)
1509 vga_wcrt (regbase, CL_CRT1D, 0x00); /* screen start address bit 19 */ 1476 /* screen start address bit 19 */
1510 1477 vga_wcrt(regbase, CL_CRT1D, 0x00);
1511 vga_wcrt (regbase, VGA_CRTC_CURSOR_HI, 0); /* text cursor location high */ 1478
1512 vga_wcrt (regbase, VGA_CRTC_CURSOR_LO, 0); /* text cursor location low */ 1479 /* text cursor location high */
1513 vga_wcrt (regbase, VGA_CRTC_UNDERLINE, 0); /* underline row scanline = at very bottom */ 1480 vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0);
1514 1481 /* text cursor location low */
1515 vga_wattr (regbase, VGA_ATC_MODE, 1); /* controller mode */ 1482 vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0);
1516 vga_wattr (regbase, VGA_ATC_OVERSCAN, 0); /* overscan (border) color */ 1483 /* underline row scanline = at very bottom */
1517 vga_wattr (regbase, VGA_ATC_PLANE_ENABLE, 15); /* color plane enable */ 1484 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
1518 vga_wattr (regbase, CL_AR33, 0); /* pixel panning */ 1485
1519 vga_wattr (regbase, VGA_ATC_COLOR_PAGE, 0); /* color select */ 1486 /* controller mode */
1487 vga_wattr(regbase, VGA_ATC_MODE, 1);
1488 /* overscan (border) color */
1489 vga_wattr(regbase, VGA_ATC_OVERSCAN, 0);
1490 /* color plane enable */
1491 vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15);
1492 /* pixel panning */
1493 vga_wattr(regbase, CL_AR33, 0);
1494 /* color select */
1495 vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0);
1520 1496
1521 /* [ EGS: SetOffset(); ] */ 1497 /* [ EGS: SetOffset(); ] */
1522 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */ 1498 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1523 AttrOn (cinfo); 1499 AttrOn(cinfo);
1524 1500
1525 vga_wgfx (regbase, VGA_GFX_SR_VALUE, 0); /* set/reset register */ 1501 /* set/reset register */
1526 vga_wgfx (regbase, VGA_GFX_SR_ENABLE, 0); /* set/reset enable */ 1502 vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0);
1527 vga_wgfx (regbase, VGA_GFX_COMPARE_VALUE, 0); /* color compare */ 1503 /* set/reset enable */
1528 vga_wgfx (regbase, VGA_GFX_DATA_ROTATE, 0); /* data rotate */ 1504 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0);
1529 vga_wgfx (regbase, VGA_GFX_PLANE_READ, 0); /* read map select */ 1505 /* color compare */
1530 vga_wgfx (regbase, VGA_GFX_MISC, 1); /* miscellaneous register */ 1506 vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0);
1531 vga_wgfx (regbase, VGA_GFX_COMPARE_MASK, 15); /* color don't care */ 1507 /* data rotate */
1532 vga_wgfx (regbase, VGA_GFX_BIT_MASK, 255); /* bit mask */ 1508 vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0);
1533 1509 /* read map select */
1534 vga_wseq (regbase, CL_SEQR12, 0x0); /* graphics cursor attributes: nothing special */ 1510 vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0);
1511 /* miscellaneous register */
1512 vga_wgfx(regbase, VGA_GFX_MISC, 1);
1513 /* color don't care */
1514 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15);
1515 /* bit mask */
1516 vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255);
1517
1518 /* graphics cursor attributes: nothing special */
1519 vga_wseq(regbase, CL_SEQR12, 0x0);
1535 1520
1536 /* finally, turn on everything - turn off "FullBandwidth" bit */ 1521 /* finally, turn on everything - turn off "FullBandwidth" bit */
1537 /* also, set "DotClock%2" bit where requested */ 1522 /* also, set "DotClock%2" bit where requested */
@@ -1542,36 +1527,33 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1542 tmp |= 0x08; 1527 tmp |= 0x08;
1543*/ 1528*/
1544 1529
1545 vga_wseq (regbase, VGA_SEQ_CLOCK_MODE, tmp); 1530 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1546 DPRINTK ("CL_SEQR1: %d\n", tmp); 1531 DPRINTK("CL_SEQR1: %d\n", tmp);
1547 1532
1548 cinfo->currentmode = regs; 1533 cinfo->currentmode = regs;
1549 info->fix.type = regs.type;
1550 info->fix.visual = regs.visual;
1551 info->fix.line_length = regs.line_length;
1552 1534
1553 /* pan to requested offset */ 1535 /* pan to requested offset */
1554 cirrusfb_pan_display (var, info); 1536 cirrusfb_pan_display(var, info);
1555 1537
1556#ifdef CIRRUSFB_DEBUG 1538#ifdef CIRRUSFB_DEBUG
1557 cirrusfb_dump (); 1539 cirrusfb_dump();
1558#endif 1540#endif
1559 1541
1560 DPRINTK ("EXIT\n"); 1542 DPRINTK("EXIT\n");
1561 return 0; 1543 return 0;
1562} 1544}
1563 1545
1564/* for some reason incomprehensible to me, cirrusfb requires that you write 1546/* for some reason incomprehensible to me, cirrusfb requires that you write
1565 * the registers twice for the settings to take..grr. -dte */ 1547 * the registers twice for the settings to take..grr. -dte */
1566static int cirrusfb_set_par (struct fb_info *info) 1548static int cirrusfb_set_par(struct fb_info *info)
1567{ 1549{
1568 cirrusfb_set_par_foo (info); 1550 cirrusfb_set_par_foo(info);
1569 return cirrusfb_set_par_foo (info); 1551 return cirrusfb_set_par_foo(info);
1570} 1552}
1571 1553
1572static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, 1554static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1573 unsigned blue, unsigned transp, 1555 unsigned blue, unsigned transp,
1574 struct fb_info *info) 1556 struct fb_info *info)
1575{ 1557{
1576 struct cirrusfb_info *cinfo = info->par; 1558 struct cirrusfb_info *cinfo = info->par;
1577 1559
@@ -1584,34 +1566,18 @@ static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
1584 green >>= (16 - info->var.green.length); 1566 green >>= (16 - info->var.green.length);
1585 blue >>= (16 - info->var.blue.length); 1567 blue >>= (16 - info->var.blue.length);
1586 1568
1587 if (regno>=16) 1569 if (regno >= 16)
1588 return 1; 1570 return 1;
1589 v = (red << info->var.red.offset) | 1571 v = (red << info->var.red.offset) |
1590 (green << info->var.green.offset) | 1572 (green << info->var.green.offset) |
1591 (blue << info->var.blue.offset); 1573 (blue << info->var.blue.offset);
1592 1574
1593 switch (info->var.bits_per_pixel) { 1575 cinfo->pseudo_palette[regno] = v;
1594 case 8:
1595 cinfo->pseudo_palette[regno] = v;
1596 break;
1597 case 16:
1598 cinfo->pseudo_palette[regno] = v;
1599 break;
1600 case 24:
1601 case 32:
1602 cinfo->pseudo_palette[regno] = v;
1603 break;
1604 }
1605 return 0; 1576 return 0;
1606 } 1577 }
1607 1578
1608 cinfo->palette[regno].red = red; 1579 if (info->var.bits_per_pixel == 8)
1609 cinfo->palette[regno].green = green; 1580 WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
1610 cinfo->palette[regno].blue = blue;
1611
1612 if (info->var.bits_per_pixel == 8) {
1613 WClut (cinfo, regno, red >> 10, green >> 10, blue >> 10);
1614 }
1615 1581
1616 return 0; 1582 return 0;
1617 1583
@@ -1622,8 +1588,8 @@ static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
1622 1588
1623 performs display panning - provided hardware permits this 1589 performs display panning - provided hardware permits this
1624**************************************************************************/ 1590**************************************************************************/
1625static int cirrusfb_pan_display (struct fb_var_screeninfo *var, 1591static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1626 struct fb_info *info) 1592 struct fb_info *info)
1627{ 1593{
1628 int xoffset = 0; 1594 int xoffset = 0;
1629 int yoffset = 0; 1595 int yoffset = 0;
@@ -1631,8 +1597,8 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
1631 unsigned char tmp = 0, tmp2 = 0, xpix; 1597 unsigned char tmp = 0, tmp2 = 0, xpix;
1632 struct cirrusfb_info *cinfo = info->par; 1598 struct cirrusfb_info *cinfo = info->par;
1633 1599
1634 DPRINTK ("ENTER\n"); 1600 DPRINTK("ENTER\n");
1635 DPRINTK ("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset); 1601 DPRINTK("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
1636 1602
1637 /* no range checks for xoffset and yoffset, */ 1603 /* no range checks for xoffset and yoffset, */
1638 /* as fb_pan_display has already done this */ 1604 /* as fb_pan_display has already done this */
@@ -1645,7 +1611,7 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
1645 xoffset = var->xoffset * info->var.bits_per_pixel / 8; 1611 xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1646 yoffset = var->yoffset; 1612 yoffset = var->yoffset;
1647 1613
1648 base = yoffset * cinfo->currentmode.line_length + xoffset; 1614 base = yoffset * info->fix.line_length + xoffset;
1649 1615
1650 if (info->var.bits_per_pixel == 1) { 1616 if (info->var.bits_per_pixel == 1) {
1651 /* base is already correct */ 1617 /* base is already correct */
@@ -1655,11 +1621,13 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
1655 xpix = (unsigned char) ((xoffset % 4) * 2); 1621 xpix = (unsigned char) ((xoffset % 4) * 2);
1656 } 1622 }
1657 1623
1658 cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */ 1624 cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */
1659 1625
1660 /* lower 8 + 8 bits of screen start address */ 1626 /* lower 8 + 8 bits of screen start address */
1661 vga_wcrt (cinfo->regbase, VGA_CRTC_START_LO, (unsigned char) (base & 0xff)); 1627 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO,
1662 vga_wcrt (cinfo->regbase, VGA_CRTC_START_HI, (unsigned char) (base >> 8)); 1628 (unsigned char) (base & 0xff));
1629 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI,
1630 (unsigned char) (base >> 8));
1663 1631
1664 /* construct bits 16, 17 and 18 of screen start address */ 1632 /* construct bits 16, 17 and 18 of screen start address */
1665 if (base & 0x10000) 1633 if (base & 0x10000)
@@ -1669,50 +1637,49 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
1669 if (base & 0x40000) 1637 if (base & 0x40000)
1670 tmp |= 0x08; 1638 tmp |= 0x08;
1671 1639
1672 tmp2 = (vga_rcrt (cinfo->regbase, CL_CRT1B) & 0xf2) | tmp; /* 0xf2 is %11110010, exclude tmp bits */ 1640 /* 0xf2 is %11110010, exclude tmp bits */
1673 vga_wcrt (cinfo->regbase, CL_CRT1B, tmp2); 1641 tmp2 = (vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2) | tmp;
1642 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2);
1674 1643
1675 /* construct bit 19 of screen start address */ 1644 /* construct bit 19 of screen start address */
1676 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) { 1645 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1677 tmp2 = 0; 1646 vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
1678 if (base & 0x80000)
1679 tmp2 = 0x80;
1680 vga_wcrt (cinfo->regbase, CL_CRT1D, tmp2);
1681 }
1682 1647
1683 /* write pixel panning value to AR33; this does not quite work in 8bpp */ 1648 /* write pixel panning value to AR33; this does not quite work in 8bpp
1684 /* ### Piccolo..? Will this work? */ 1649 *
1650 * ### Piccolo..? Will this work?
1651 */
1685 if (info->var.bits_per_pixel == 1) 1652 if (info->var.bits_per_pixel == 1)
1686 vga_wattr (cinfo->regbase, CL_AR33, xpix); 1653 vga_wattr(cinfo->regbase, CL_AR33, xpix);
1687 1654
1688 cirrusfb_WaitBLT (cinfo->regbase); 1655 cirrusfb_WaitBLT(cinfo->regbase);
1689 1656
1690 DPRINTK ("EXIT\n"); 1657 DPRINTK("EXIT\n");
1691 return (0); 1658 return 0;
1692} 1659}
1693 1660
1694 1661static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1695static int cirrusfb_blank (int blank_mode, struct fb_info *info)
1696{ 1662{
1697 /* 1663 /*
1698 * Blank the screen if blank_mode != 0, else unblank. If blank == NULL 1664 * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
1699 * then the caller blanks by setting the CLUT (Color Look Up Table) to all 1665 * then the caller blanks by setting the CLUT (Color Look Up Table)
1700 * black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due 1666 * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
1701 * to e.g. a video mode which doesn't support it. Implements VESA suspend 1667 * failed due to e.g. a video mode which doesn't support it.
1702 * and powerdown modes on hardware that supports disabling hsync/vsync: 1668 * Implements VESA suspend and powerdown modes on hardware that
1703 * blank_mode == 2: suspend vsync 1669 * supports disabling hsync/vsync:
1704 * blank_mode == 3: suspend hsync 1670 * blank_mode == 2: suspend vsync
1705 * blank_mode == 4: powerdown 1671 * blank_mode == 3: suspend hsync
1672 * blank_mode == 4: powerdown
1706 */ 1673 */
1707 unsigned char val; 1674 unsigned char val;
1708 struct cirrusfb_info *cinfo = info->par; 1675 struct cirrusfb_info *cinfo = info->par;
1709 int current_mode = cinfo->blank_mode; 1676 int current_mode = cinfo->blank_mode;
1710 1677
1711 DPRINTK ("ENTER, blank mode = %d\n", blank_mode); 1678 DPRINTK("ENTER, blank mode = %d\n", blank_mode);
1712 1679
1713 if (info->state != FBINFO_STATE_RUNNING || 1680 if (info->state != FBINFO_STATE_RUNNING ||
1714 current_mode == blank_mode) { 1681 current_mode == blank_mode) {
1715 DPRINTK ("EXIT, returning 0\n"); 1682 DPRINTK("EXIT, returning 0\n");
1716 return 0; 1683 return 0;
1717 } 1684 }
1718 1685
@@ -1720,17 +1687,19 @@ static int cirrusfb_blank (int blank_mode, struct fb_info *info)
1720 if (current_mode == FB_BLANK_NORMAL || 1687 if (current_mode == FB_BLANK_NORMAL ||
1721 current_mode == FB_BLANK_UNBLANK) { 1688 current_mode == FB_BLANK_UNBLANK) {
1722 /* unblank the screen */ 1689 /* unblank the screen */
1723 val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE); 1690 val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
1724 vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf); /* clear "FullBandwidth" bit */ 1691 /* clear "FullBandwidth" bit */
1692 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf);
1725 /* and undo VESA suspend trickery */ 1693 /* and undo VESA suspend trickery */
1726 vga_wgfx (cinfo->regbase, CL_GRE, 0x00); 1694 vga_wgfx(cinfo->regbase, CL_GRE, 0x00);
1727 } 1695 }
1728 1696
1729 /* set new */ 1697 /* set new */
1730 if(blank_mode > FB_BLANK_NORMAL) { 1698 if (blank_mode > FB_BLANK_NORMAL) {
1731 /* blank the screen */ 1699 /* blank the screen */
1732 val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE); 1700 val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
1733 vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20); /* set "FullBandwidth" bit */ 1701 /* set "FullBandwidth" bit */
1702 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20);
1734 } 1703 }
1735 1704
1736 switch (blank_mode) { 1705 switch (blank_mode) {
@@ -1738,21 +1707,21 @@ static int cirrusfb_blank (int blank_mode, struct fb_info *info)
1738 case FB_BLANK_NORMAL: 1707 case FB_BLANK_NORMAL:
1739 break; 1708 break;
1740 case FB_BLANK_VSYNC_SUSPEND: 1709 case FB_BLANK_VSYNC_SUSPEND:
1741 vga_wgfx (cinfo->regbase, CL_GRE, 0x04); 1710 vga_wgfx(cinfo->regbase, CL_GRE, 0x04);
1742 break; 1711 break;
1743 case FB_BLANK_HSYNC_SUSPEND: 1712 case FB_BLANK_HSYNC_SUSPEND:
1744 vga_wgfx (cinfo->regbase, CL_GRE, 0x02); 1713 vga_wgfx(cinfo->regbase, CL_GRE, 0x02);
1745 break; 1714 break;
1746 case FB_BLANK_POWERDOWN: 1715 case FB_BLANK_POWERDOWN:
1747 vga_wgfx (cinfo->regbase, CL_GRE, 0x06); 1716 vga_wgfx(cinfo->regbase, CL_GRE, 0x06);
1748 break; 1717 break;
1749 default: 1718 default:
1750 DPRINTK ("EXIT, returning 1\n"); 1719 DPRINTK("EXIT, returning 1\n");
1751 return 1; 1720 return 1;
1752 } 1721 }
1753 1722
1754 cinfo->blank_mode = blank_mode; 1723 cinfo->blank_mode = blank_mode;
1755 DPRINTK ("EXIT, returning 0\n"); 1724 DPRINTK("EXIT, returning 0\n");
1756 1725
1757 /* Let fbcon do a soft blank for us */ 1726 /* Let fbcon do a soft blank for us */
1758 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0; 1727 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
@@ -1761,45 +1730,51 @@ static int cirrusfb_blank (int blank_mode, struct fb_info *info)
1761/****************************************************************************/ 1730/****************************************************************************/
1762/**** BEGIN Internal Routines ***********************************************/ 1731/**** BEGIN Internal Routines ***********************************************/
1763 1732
1764static void init_vgachip (struct cirrusfb_info *cinfo) 1733static void init_vgachip(struct fb_info *info)
1765{ 1734{
1735 struct cirrusfb_info *cinfo = info->par;
1766 const struct cirrusfb_board_info_rec *bi; 1736 const struct cirrusfb_board_info_rec *bi;
1767 1737
1768 DPRINTK ("ENTER\n"); 1738 DPRINTK("ENTER\n");
1769 1739
1770 assert (cinfo != NULL); 1740 assert(cinfo != NULL);
1771 1741
1772 bi = &cirrusfb_board_info[cinfo->btype]; 1742 bi = &cirrusfb_board_info[cinfo->btype];
1773 1743
1774 /* reset board globally */ 1744 /* reset board globally */
1775 switch (cinfo->btype) { 1745 switch (cinfo->btype) {
1776 case BT_PICCOLO: 1746 case BT_PICCOLO:
1777 WSFR (cinfo, 0x01); 1747 WSFR(cinfo, 0x01);
1778 udelay (500); 1748 udelay(500);
1779 WSFR (cinfo, 0x51); 1749 WSFR(cinfo, 0x51);
1780 udelay (500); 1750 udelay(500);
1781 break; 1751 break;
1782 case BT_PICASSO: 1752 case BT_PICASSO:
1783 WSFR2 (cinfo, 0xff); 1753 WSFR2(cinfo, 0xff);
1784 udelay (500); 1754 udelay(500);
1785 break; 1755 break;
1786 case BT_SD64: 1756 case BT_SD64:
1787 case BT_SPECTRUM: 1757 case BT_SPECTRUM:
1788 WSFR (cinfo, 0x1f); 1758 WSFR(cinfo, 0x1f);
1789 udelay (500); 1759 udelay(500);
1790 WSFR (cinfo, 0x4f); 1760 WSFR(cinfo, 0x4f);
1791 udelay (500); 1761 udelay(500);
1792 break; 1762 break;
1793 case BT_PICASSO4: 1763 case BT_PICASSO4:
1794 vga_wcrt (cinfo->regbase, CL_CRT51, 0x00); /* disable flickerfixer */ 1764 /* disable flickerfixer */
1795 mdelay (100); 1765 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1796 vga_wgfx (cinfo->regbase, CL_GR2F, 0x00); /* from Klaus' NetBSD driver: */ 1766 mdelay(100);
1797 vga_wgfx (cinfo->regbase, CL_GR33, 0x00); /* put blitter into 542x compat */ 1767 /* from Klaus' NetBSD driver: */
1798 vga_wgfx (cinfo->regbase, CL_GR31, 0x00); /* mode */ 1768 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1769 /* put blitter into 542x compat */
1770 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1771 /* mode */
1772 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1799 break; 1773 break;
1800 1774
1801 case BT_GD5480: 1775 case BT_GD5480:
1802 vga_wgfx (cinfo->regbase, CL_GR2F, 0x00); /* from Klaus' NetBSD driver: */ 1776 /* from Klaus' NetBSD driver: */
1777 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1803 break; 1778 break;
1804 1779
1805 case BT_ALPINE: 1780 case BT_ALPINE:
@@ -1807,153 +1782,208 @@ static void init_vgachip (struct cirrusfb_info *cinfo)
1807 break; 1782 break;
1808 1783
1809 default: 1784 default:
1810 printk (KERN_ERR "cirrusfb: Warning: Unknown board type\n"); 1785 printk(KERN_ERR "cirrusfb: Warning: Unknown board type\n");
1811 break; 1786 break;
1812 } 1787 }
1813 1788
1814 assert (cinfo->size > 0); /* make sure RAM size set by this point */ 1789 /* make sure RAM size set by this point */
1790 assert(info->screen_size > 0);
1815 1791
1816 /* the P4 is not fully initialized here; I rely on it having been */ 1792 /* the P4 is not fully initialized here; I rely on it having been */
1817 /* inited under AmigaOS already, which seems to work just fine */ 1793 /* inited under AmigaOS already, which seems to work just fine */
1818 /* (Klaus advised to do it this way) */ 1794 /* (Klaus advised to do it this way) */
1819 1795
1820 if (cinfo->btype != BT_PICASSO4) { 1796 if (cinfo->btype != BT_PICASSO4) {
1821 WGen (cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */ 1797 WGen(cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */
1822 WGen (cinfo, CL_POS102, 0x01); 1798 WGen(cinfo, CL_POS102, 0x01);
1823 WGen (cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */ 1799 WGen(cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */
1824 1800
1825 if (cinfo->btype != BT_SD64) 1801 if (cinfo->btype != BT_SD64)
1826 WGen (cinfo, CL_VSSM2, 0x01); 1802 WGen(cinfo, CL_VSSM2, 0x01);
1827 1803
1828 vga_wseq (cinfo->regbase, CL_SEQR0, 0x03); /* reset sequencer logic */ 1804 /* reset sequencer logic */
1805 vga_wseq(cinfo->regbase, CL_SEQR0, 0x03);
1829 1806
1830 vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21); /* FullBandwidth (video off) and 8/9 dot clock */ 1807 /* FullBandwidth (video off) and 8/9 dot clock */
1831 WGen (cinfo, VGA_MIS_W, 0xc1); /* polarity (-/-), disable access to display memory, VGA_CRTC_START_HI base address: color */ 1808 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1809 /* polarity (-/-), disable access to display memory,
1810 * VGA_CRTC_START_HI base address: color
1811 */
1812 WGen(cinfo, VGA_MIS_W, 0xc1);
1832 1813
1833/* vga_wgfx (cinfo->regbase, CL_GRA, 0xce); "magic cookie" - doesn't make any sense to me.. */ 1814 /* "magic cookie" - doesn't make any sense to me.. */
1834 vga_wseq (cinfo->regbase, CL_SEQR6, 0x12); /* unlock all extension registers */ 1815/* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */
1816 /* unlock all extension registers */
1817 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1835 1818
1836 vga_wgfx (cinfo->regbase, CL_GR31, 0x04); /* reset blitter */ 1819 /* reset blitter */
1820 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1837 1821
1838 switch (cinfo->btype) { 1822 switch (cinfo->btype) {
1839 case BT_GD5480: 1823 case BT_GD5480:
1840 vga_wseq (cinfo->regbase, CL_SEQRF, 0x98); 1824 vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1841 break; 1825 break;
1842 case BT_ALPINE: 1826 case BT_ALPINE:
1843 break; 1827 break;
1844 case BT_SD64: 1828 case BT_SD64:
1845 vga_wseq (cinfo->regbase, CL_SEQRF, 0xb8); 1829 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1846 break; 1830 break;
1847 default: 1831 default:
1848 vga_wseq (cinfo->regbase, CL_SEQR16, 0x0f); 1832 vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1849 vga_wseq (cinfo->regbase, CL_SEQRF, 0xb0); 1833 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1850 break; 1834 break;
1851 } 1835 }
1852 } 1836 }
1853 vga_wseq (cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: nothing */ 1837 /* plane mask: nothing */
1854 vga_wseq (cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00); /* character map select: doesn't even matter in gx mode */ 1838 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1855 vga_wseq (cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e); /* memory mode: chain-4, no odd/even, ext. memory */ 1839 /* character map select: doesn't even matter in gx mode */
1840 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1841 /* memory mode: chain-4, no odd/even, ext. memory */
1842 vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);
1856 1843
1857 /* controller-internal base address of video memory */ 1844 /* controller-internal base address of video memory */
1858 if (bi->init_sr07) 1845 if (bi->init_sr07)
1859 vga_wseq (cinfo->regbase, CL_SEQR7, bi->sr07); 1846 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1860 1847
1861 /* vga_wseq (cinfo->regbase, CL_SEQR8, 0x00); *//* EEPROM control: shouldn't be necessary to write to this at all.. */ 1848 /* vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1849 /* EEPROM control: shouldn't be necessary to write to this at all.. */
1862 1850
1863 vga_wseq (cinfo->regbase, CL_SEQR10, 0x00); /* graphics cursor X position (incomplete; position gives rem. 3 bits */ 1851 /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1864 vga_wseq (cinfo->regbase, CL_SEQR11, 0x00); /* graphics cursor Y position (..."... ) */ 1852 vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1865 vga_wseq (cinfo->regbase, CL_SEQR12, 0x00); /* graphics cursor attributes */ 1853 /* graphics cursor Y position (..."... ) */
1866 vga_wseq (cinfo->regbase, CL_SEQR13, 0x00); /* graphics cursor pattern address */ 1854 vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1855 /* graphics cursor attributes */
1856 vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1857 /* graphics cursor pattern address */
1858 vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1867 1859
1868 /* writing these on a P4 might give problems.. */ 1860 /* writing these on a P4 might give problems.. */
1869 if (cinfo->btype != BT_PICASSO4) { 1861 if (cinfo->btype != BT_PICASSO4) {
1870 vga_wseq (cinfo->regbase, CL_SEQR17, 0x00); /* configuration readback and ext. color */ 1862 /* configuration readback and ext. color */
1871 vga_wseq (cinfo->regbase, CL_SEQR18, 0x02); /* signature generator */ 1863 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1864 /* signature generator */
1865 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1872 } 1866 }
1873 1867
1874 /* MCLK select etc. */ 1868 /* MCLK select etc. */
1875 if (bi->init_sr1f) 1869 if (bi->init_sr1f)
1876 vga_wseq (cinfo->regbase, CL_SEQR1F, bi->sr1f); 1870 vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
1877 1871
1878 vga_wcrt (cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00); /* Screen A preset row scan: none */ 1872 /* Screen A preset row scan: none */
1879 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20); /* Text cursor start: disable text cursor */ 1873 vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1880 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00); /* Text cursor end: - */ 1874 /* Text cursor start: disable text cursor */
1881 vga_wcrt (cinfo->regbase, VGA_CRTC_START_HI, 0x00); /* Screen start address high: 0 */ 1875 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1882 vga_wcrt (cinfo->regbase, VGA_CRTC_START_LO, 0x00); /* Screen start address low: 0 */ 1876 /* Text cursor end: - */
1883 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00); /* text cursor location high: 0 */ 1877 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1884 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00); /* text cursor location low: 0 */ 1878 /* Screen start address high: 0 */
1885 1879 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);
1886 vga_wcrt (cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00); /* Underline Row scanline: - */ 1880 /* Screen start address low: 0 */
1887 vga_wcrt (cinfo->regbase, VGA_CRTC_MODE, 0xc3); /* mode control: timing enable, byte mode, no compat modes */ 1881 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);
1888 vga_wcrt (cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00); /* Line Compare: not needed */ 1882 /* text cursor location high: 0 */
1883 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1884 /* text cursor location low: 0 */
1885 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1886
1887 /* Underline Row scanline: - */
1888 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1889 /* mode control: timing enable, byte mode, no compat modes */
1890 vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);
1891 /* Line Compare: not needed */
1892 vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
1889 /* ### add 0x40 for text modes with > 30 MHz pixclock */ 1893 /* ### add 0x40 for text modes with > 30 MHz pixclock */
1890 vga_wcrt (cinfo->regbase, CL_CRT1B, 0x02); /* ext. display controls: ext.adr. wrap */ 1894 /* ext. display controls: ext.adr. wrap */
1891 1895 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1892 vga_wgfx (cinfo->regbase, VGA_GFX_SR_VALUE, 0x00); /* Set/Reset registes: - */ 1896
1893 vga_wgfx (cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00); /* Set/Reset enable: - */ 1897 /* Set/Reset registes: - */
1894 vga_wgfx (cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00); /* Color Compare: - */ 1898 vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1895 vga_wgfx (cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00); /* Data Rotate: - */ 1899 /* Set/Reset enable: - */
1896 vga_wgfx (cinfo->regbase, VGA_GFX_PLANE_READ, 0x00); /* Read Map Select: - */ 1900 vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1897 vga_wgfx (cinfo->regbase, VGA_GFX_MODE, 0x00); /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */ 1901 /* Color Compare: - */
1898 vga_wgfx (cinfo->regbase, VGA_GFX_MISC, 0x01); /* Miscellaneous: memory map base address, graphics mode */ 1902 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1899 vga_wgfx (cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f); /* Color Don't care: involve all planes */ 1903 /* Data Rotate: - */
1900 vga_wgfx (cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); /* Bit Mask: no mask at all */ 1904 vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1905 /* Read Map Select: - */
1906 vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1907 /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1908 vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1909 /* Miscellaneous: memory map base address, graphics mode */
1910 vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1911 /* Color Don't care: involve all planes */
1912 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1913 /* Bit Mask: no mask at all */
1914 vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1901 if (cinfo->btype == BT_ALPINE) 1915 if (cinfo->btype == BT_ALPINE)
1902 vga_wgfx (cinfo->regbase, CL_GRB, 0x20); /* (5434 can't have bit 3 set for bitblt) */ 1916 /* (5434 can't have bit 3 set for bitblt) */
1917 vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1903 else 1918 else
1904 vga_wgfx (cinfo->regbase, CL_GRB, 0x28); /* Graphics controller mode extensions: finer granularity, 8byte data latches */ 1919 /* Graphics controller mode extensions: finer granularity,
1905 1920 * 8byte data latches
1906 vga_wgfx (cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */ 1921 */
1907 vga_wgfx (cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */ 1922 vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1908 vga_wgfx (cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */ 1923
1909 /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); *//* Background color byte 1: - */ 1924 vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1910/* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */ 1925 vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1911 1926 vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1912 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE0, 0x00); /* Attribute Controller palette registers: "identity mapping" */ 1927 /* Background color byte 1: - */
1913 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE1, 0x01); 1928 /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1914 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE2, 0x02); 1929 /* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1915 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE3, 0x03); 1930
1916 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE4, 0x04); 1931 /* Attribute Controller palette registers: "identity mapping" */
1917 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE5, 0x05); 1932 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1918 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE6, 0x06); 1933 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1919 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE7, 0x07); 1934 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1920 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE8, 0x08); 1935 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1921 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE9, 0x09); 1936 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1922 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEA, 0x0a); 1937 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1923 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEB, 0x0b); 1938 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1924 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEC, 0x0c); 1939 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1925 vga_wattr (cinfo->regbase, VGA_ATC_PALETTED, 0x0d); 1940 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1926 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEE, 0x0e); 1941 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1927 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEF, 0x0f); 1942 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1928 1943 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1929 vga_wattr (cinfo->regbase, VGA_ATC_MODE, 0x01); /* Attribute Controller mode: graphics mode */ 1944 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1930 vga_wattr (cinfo->regbase, VGA_ATC_OVERSCAN, 0x00); /* Overscan color reg.: reg. 0 */ 1945 vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1931 vga_wattr (cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f); /* Color Plane enable: Enable all 4 planes */ 1946 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1932/* ### vga_wattr (cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */ 1947 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1933 vga_wattr (cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00); /* Color Select: - */ 1948
1934 1949 /* Attribute Controller mode: graphics mode */
1935 WGen (cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */ 1950 vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1951 /* Overscan color reg.: reg. 0 */
1952 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1953 /* Color Plane enable: Enable all 4 planes */
1954 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1955/* ### vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
1956 /* Color Select: - */
1957 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1958
1959 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1936 1960
1937 if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480) 1961 if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
1938 WGen (cinfo, VGA_MIS_W, 0xc3); /* polarity (-/-), enable display mem, VGA_CRTC_START_HI i/o base = color */ 1962 /* polarity (-/-), enable display mem,
1963 * VGA_CRTC_START_HI i/o base = color
1964 */
1965 WGen(cinfo, VGA_MIS_W, 0xc3);
1939 1966
1940 vga_wgfx (cinfo->regbase, CL_GR31, 0x04); /* BLT Start/status: Blitter reset */ 1967 /* BLT Start/status: Blitter reset */
1941 vga_wgfx (cinfo->regbase, CL_GR31, 0x00); /* - " - : "end-of-reset" */ 1968 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1969 /* - " - : "end-of-reset" */
1970 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1942 1971
1943 /* misc... */ 1972 /* misc... */
1944 WHDR (cinfo, 0); /* Hidden DAC register: - */ 1973 WHDR(cinfo, 0); /* Hidden DAC register: - */
1945 1974
1946 printk (KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n", cinfo->size); 1975 printk(KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n",
1947 DPRINTK ("EXIT\n"); 1976 info->screen_size);
1977 DPRINTK("EXIT\n");
1948 return; 1978 return;
1949} 1979}
1950 1980
1951static void switch_monitor (struct cirrusfb_info *cinfo, int on) 1981static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1952{ 1982{
1953#ifdef CONFIG_ZORRO /* only works on Zorro boards */ 1983#ifdef CONFIG_ZORRO /* only works on Zorro boards */
1954 static int IsOn = 0; /* XXX not ok for multiple boards */ 1984 static int IsOn = 0; /* XXX not ok for multiple boards */
1955 1985
1956 DPRINTK ("ENTER\n"); 1986 DPRINTK("ENTER\n");
1957 1987
1958 if (cinfo->btype == BT_PICASSO4) 1988 if (cinfo->btype == BT_PICASSO4)
1959 return; /* nothing to switch */ 1989 return; /* nothing to switch */
@@ -1963,77 +1993,56 @@ static void switch_monitor (struct cirrusfb_info *cinfo, int on)
1963 return; /* nothing to switch */ 1993 return; /* nothing to switch */
1964 if (cinfo->btype == BT_PICASSO) { 1994 if (cinfo->btype == BT_PICASSO) {
1965 if ((on && !IsOn) || (!on && IsOn)) 1995 if ((on && !IsOn) || (!on && IsOn))
1966 WSFR (cinfo, 0xff); 1996 WSFR(cinfo, 0xff);
1967 1997
1968 DPRINTK ("EXIT\n"); 1998 DPRINTK("EXIT\n");
1969 return; 1999 return;
1970 } 2000 }
1971 if (on) { 2001 if (on) {
1972 switch (cinfo->btype) { 2002 switch (cinfo->btype) {
1973 case BT_SD64: 2003 case BT_SD64:
1974 WSFR (cinfo, cinfo->SFR | 0x21); 2004 WSFR(cinfo, cinfo->SFR | 0x21);
1975 break; 2005 break;
1976 case BT_PICCOLO: 2006 case BT_PICCOLO:
1977 WSFR (cinfo, cinfo->SFR | 0x28); 2007 WSFR(cinfo, cinfo->SFR | 0x28);
1978 break; 2008 break;
1979 case BT_SPECTRUM: 2009 case BT_SPECTRUM:
1980 WSFR (cinfo, 0x6f); 2010 WSFR(cinfo, 0x6f);
1981 break; 2011 break;
1982 default: /* do nothing */ break; 2012 default: /* do nothing */ break;
1983 } 2013 }
1984 } else { 2014 } else {
1985 switch (cinfo->btype) { 2015 switch (cinfo->btype) {
1986 case BT_SD64: 2016 case BT_SD64:
1987 WSFR (cinfo, cinfo->SFR & 0xde); 2017 WSFR(cinfo, cinfo->SFR & 0xde);
1988 break; 2018 break;
1989 case BT_PICCOLO: 2019 case BT_PICCOLO:
1990 WSFR (cinfo, cinfo->SFR & 0xd7); 2020 WSFR(cinfo, cinfo->SFR & 0xd7);
1991 break; 2021 break;
1992 case BT_SPECTRUM: 2022 case BT_SPECTRUM:
1993 WSFR (cinfo, 0x4f); 2023 WSFR(cinfo, 0x4f);
1994 break; 2024 break;
1995 default: /* do nothing */ break; 2025 default: /* do nothing */ break;
1996 } 2026 }
1997 } 2027 }
1998 2028
1999 DPRINTK ("EXIT\n"); 2029 DPRINTK("EXIT\n");
2000#endif /* CONFIG_ZORRO */ 2030#endif /* CONFIG_ZORRO */
2001} 2031}
2002 2032
2003
2004/******************************************/ 2033/******************************************/
2005/* Linux 2.6-style accelerated functions */ 2034/* Linux 2.6-style accelerated functions */
2006/******************************************/ 2035/******************************************/
2007 2036
2008static void cirrusfb_prim_fillrect(struct cirrusfb_info *cinfo, 2037static void cirrusfb_fillrect(struct fb_info *info,
2009 const struct fb_fillrect *region) 2038 const struct fb_fillrect *region)
2010{
2011 int m; /* bytes per pixel */
2012 u32 color = (cinfo->info->fix.visual == FB_VISUAL_TRUECOLOR) ?
2013 cinfo->pseudo_palette[region->color] : region->color;
2014
2015 if(cinfo->info->var.bits_per_pixel == 1) {
2016 cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2017 region->dx / 8, region->dy,
2018 region->width / 8, region->height,
2019 color,
2020 cinfo->currentmode.line_length);
2021 } else {
2022 m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
2023 cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2024 region->dx * m, region->dy,
2025 region->width * m, region->height,
2026 color,
2027 cinfo->currentmode.line_length);
2028 }
2029 return;
2030}
2031
2032static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region)
2033{ 2039{
2034 struct cirrusfb_info *cinfo = info->par;
2035 struct fb_fillrect modded; 2040 struct fb_fillrect modded;
2036 int vxres, vyres; 2041 int vxres, vyres;
2042 struct cirrusfb_info *cinfo = info->par;
2043 int m = info->var.bits_per_pixel;
2044 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
2045 cinfo->pseudo_palette[region->color] : region->color;
2037 2046
2038 if (info->state != FBINFO_STATE_RUNNING) 2047 if (info->state != FBINFO_STATE_RUNNING)
2039 return; 2048 return;
@@ -2047,49 +2056,30 @@ static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *r
2047 2056
2048 memcpy(&modded, region, sizeof(struct fb_fillrect)); 2057 memcpy(&modded, region, sizeof(struct fb_fillrect));
2049 2058
2050 if(!modded.width || !modded.height || 2059 if (!modded.width || !modded.height ||
2051 modded.dx >= vxres || modded.dy >= vyres) 2060 modded.dx >= vxres || modded.dy >= vyres)
2052 return; 2061 return;
2053 2062
2054 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; 2063 if (modded.dx + modded.width > vxres)
2055 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; 2064 modded.width = vxres - modded.dx;
2056 2065 if (modded.dy + modded.height > vyres)
2057 cirrusfb_prim_fillrect(cinfo, &modded); 2066 modded.height = vyres - modded.dy;
2058} 2067
2059 2068 cirrusfb_RectFill(cinfo->regbase,
2060static void cirrusfb_prim_copyarea(struct cirrusfb_info *cinfo, 2069 info->var.bits_per_pixel,
2061 const struct fb_copyarea *area) 2070 (region->dx * m) / 8, region->dy,
2062{ 2071 (region->width * m) / 8, region->height,
2063 int m; /* bytes per pixel */ 2072 color,
2064 if(cinfo->info->var.bits_per_pixel == 1) { 2073 info->fix.line_length);
2065 cirrusfb_BitBLT(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2066 area->sx / 8, area->sy,
2067 area->dx / 8, area->dy,
2068 area->width / 8, area->height,
2069 cinfo->currentmode.line_length);
2070 } else {
2071 m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
2072 cirrusfb_BitBLT(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2073 area->sx * m, area->sy,
2074 area->dx * m, area->dy,
2075 area->width * m, area->height,
2076 cinfo->currentmode.line_length);
2077 }
2078 return;
2079} 2074}
2080 2075
2081 2076static void cirrusfb_copyarea(struct fb_info *info,
2082static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 2077 const struct fb_copyarea *area)
2083{ 2078{
2084 struct cirrusfb_info *cinfo = info->par;
2085 struct fb_copyarea modded; 2079 struct fb_copyarea modded;
2086 u32 vxres, vyres; 2080 u32 vxres, vyres;
2087 modded.sx = area->sx; 2081 struct cirrusfb_info *cinfo = info->par;
2088 modded.sy = area->sy; 2082 int m = info->var.bits_per_pixel;
2089 modded.dx = area->dx;
2090 modded.dy = area->dy;
2091 modded.width = area->width;
2092 modded.height = area->height;
2093 2083
2094 if (info->state != FBINFO_STATE_RUNNING) 2084 if (info->state != FBINFO_STATE_RUNNING)
2095 return; 2085 return;
@@ -2100,90 +2090,106 @@ static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *ar
2100 2090
2101 vxres = info->var.xres_virtual; 2091 vxres = info->var.xres_virtual;
2102 vyres = info->var.yres_virtual; 2092 vyres = info->var.yres_virtual;
2093 memcpy(&modded, area, sizeof(struct fb_copyarea));
2103 2094
2104 if(!modded.width || !modded.height || 2095 if (!modded.width || !modded.height ||
2105 modded.sx >= vxres || modded.sy >= vyres || 2096 modded.sx >= vxres || modded.sy >= vyres ||
2106 modded.dx >= vxres || modded.dy >= vyres) 2097 modded.dx >= vxres || modded.dy >= vyres)
2107 return; 2098 return;
2108 2099
2109 if(modded.sx + modded.width > vxres) modded.width = vxres - modded.sx; 2100 if (modded.sx + modded.width > vxres)
2110 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; 2101 modded.width = vxres - modded.sx;
2111 if(modded.sy + modded.height > vyres) modded.height = vyres - modded.sy; 2102 if (modded.dx + modded.width > vxres)
2112 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; 2103 modded.width = vxres - modded.dx;
2104 if (modded.sy + modded.height > vyres)
2105 modded.height = vyres - modded.sy;
2106 if (modded.dy + modded.height > vyres)
2107 modded.height = vyres - modded.dy;
2108
2109 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
2110 (area->sx * m) / 8, area->sy,
2111 (area->dx * m) / 8, area->dy,
2112 (area->width * m) / 8, area->height,
2113 info->fix.line_length);
2113 2114
2114 cirrusfb_prim_copyarea(cinfo, &modded);
2115} 2115}
2116 2116
2117static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image) 2117static void cirrusfb_imageblit(struct fb_info *info,
2118 const struct fb_image *image)
2118{ 2119{
2119 struct cirrusfb_info *cinfo = info->par; 2120 struct cirrusfb_info *cinfo = info->par;
2120 2121
2121 cirrusfb_WaitBLT(cinfo->regbase); 2122 cirrusfb_WaitBLT(cinfo->regbase);
2122 cfb_imageblit(info, image); 2123 cfb_imageblit(info, image);
2123} 2124}
2124 2125
2125
2126#ifdef CONFIG_PPC_PREP 2126#ifdef CONFIG_PPC_PREP
2127#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000) 2127#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
2128#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000) 2128#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
2129static void get_prep_addrs (unsigned long *display, unsigned long *registers) 2129static void get_prep_addrs(unsigned long *display, unsigned long *registers)
2130{ 2130{
2131 DPRINTK ("ENTER\n"); 2131 DPRINTK("ENTER\n");
2132 2132
2133 *display = PREP_VIDEO_BASE; 2133 *display = PREP_VIDEO_BASE;
2134 *registers = (unsigned long) PREP_IO_BASE; 2134 *registers = (unsigned long) PREP_IO_BASE;
2135 2135
2136 DPRINTK ("EXIT\n"); 2136 DPRINTK("EXIT\n");
2137} 2137}
2138 2138
2139#endif /* CONFIG_PPC_PREP */ 2139#endif /* CONFIG_PPC_PREP */
2140 2140
2141
2142#ifdef CONFIG_PCI 2141#ifdef CONFIG_PCI
2143static int release_io_ports = 0; 2142static int release_io_ports;
2144 2143
2145/* Pulled the logic from XFree86 Cirrus driver to get the memory size, 2144/* Pulled the logic from XFree86 Cirrus driver to get the memory size,
2146 * based on the DRAM bandwidth bit and DRAM bank switching bit. This 2145 * based on the DRAM bandwidth bit and DRAM bank switching bit. This
2147 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards 2146 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
2148 * seem to have. */ 2147 * seem to have. */
2149static unsigned int cirrusfb_get_memsize (u8 __iomem *regbase) 2148static unsigned int cirrusfb_get_memsize(u8 __iomem *regbase)
2150{ 2149{
2151 unsigned long mem; 2150 unsigned long mem;
2152 unsigned char SRF; 2151 unsigned char SRF;
2153 2152
2154 DPRINTK ("ENTER\n"); 2153 DPRINTK("ENTER\n");
2155 2154
2156 SRF = vga_rseq (regbase, CL_SEQRF); 2155 SRF = vga_rseq(regbase, CL_SEQRF);
2157 switch ((SRF & 0x18)) { 2156 switch ((SRF & 0x18)) {
2158 case 0x08: mem = 512 * 1024; break; 2157 case 0x08:
2159 case 0x10: mem = 1024 * 1024; break; 2158 mem = 512 * 1024;
2160 /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory 2159 break;
2161 * on the 5430. */ 2160 case 0x10:
2162 case 0x18: mem = 2048 * 1024; break; 2161 mem = 1024 * 1024;
2163 default: printk ("CLgenfb: Unknown memory size!\n"); 2162 break;
2163 /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory
2164 * on the 5430.
2165 */
2166 case 0x18:
2167 mem = 2048 * 1024;
2168 break;
2169 default:
2170 printk(KERN_WARNING "CLgenfb: Unknown memory size!\n");
2164 mem = 1024 * 1024; 2171 mem = 1024 * 1024;
2165 } 2172 }
2166 if (SRF & 0x80) { 2173 if (SRF & 0x80)
2167 /* If DRAM bank switching is enabled, there must be twice as much 2174 /* If DRAM bank switching is enabled, there must be twice as much
2168 * memory installed. (4MB on the 5434) */ 2175 * memory installed. (4MB on the 5434)
2176 */
2169 mem *= 2; 2177 mem *= 2;
2170 } 2178
2171 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */ 2179 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
2172 2180
2173 DPRINTK ("EXIT\n"); 2181 DPRINTK("EXIT\n");
2174 return mem; 2182 return mem;
2175} 2183}
2176 2184
2177 2185static void get_pci_addrs(const struct pci_dev *pdev,
2178 2186 unsigned long *display, unsigned long *registers)
2179static void get_pci_addrs (const struct pci_dev *pdev,
2180 unsigned long *display, unsigned long *registers)
2181{ 2187{
2182 assert (pdev != NULL); 2188 assert(pdev != NULL);
2183 assert (display != NULL); 2189 assert(display != NULL);
2184 assert (registers != NULL); 2190 assert(registers != NULL);
2185 2191
2186 DPRINTK ("ENTER\n"); 2192 DPRINTK("ENTER\n");
2187 2193
2188 *display = 0; 2194 *display = 0;
2189 *registers = 0; 2195 *registers = 0;
@@ -2198,51 +2204,47 @@ static void get_pci_addrs (const struct pci_dev *pdev,
2198 *registers = pci_resource_start(pdev, 1); 2204 *registers = pci_resource_start(pdev, 1);
2199 } 2205 }
2200 2206
2201 assert (*display != 0); 2207 assert(*display != 0);
2202 2208
2203 DPRINTK ("EXIT\n"); 2209 DPRINTK("EXIT\n");
2204} 2210}
2205 2211
2206 2212static void cirrusfb_pci_unmap(struct fb_info *info)
2207static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo)
2208{ 2213{
2214 struct cirrusfb_info *cinfo = info->par;
2209 struct pci_dev *pdev = cinfo->pdev; 2215 struct pci_dev *pdev = cinfo->pdev;
2210 2216
2211 iounmap(cinfo->fbmem); 2217 iounmap(info->screen_base);
2212#if 0 /* if system didn't claim this region, we would... */ 2218#if 0 /* if system didn't claim this region, we would... */
2213 release_mem_region(0xA0000, 65535); 2219 release_mem_region(0xA0000, 65535);
2214#endif 2220#endif
2215 if (release_io_ports) 2221 if (release_io_ports)
2216 release_region(0x3C0, 32); 2222 release_region(0x3C0, 32);
2217 pci_release_regions(pdev); 2223 pci_release_regions(pdev);
2218 framebuffer_release(cinfo->info);
2219} 2224}
2220#endif /* CONFIG_PCI */ 2225#endif /* CONFIG_PCI */
2221 2226
2222
2223#ifdef CONFIG_ZORRO 2227#ifdef CONFIG_ZORRO
2224static void __devexit cirrusfb_zorro_unmap (struct cirrusfb_info *cinfo) 2228static void __devexit cirrusfb_zorro_unmap(struct cirrusfb_info *cinfo)
2225{ 2229{
2226 zorro_release_device(cinfo->zdev); 2230 zorro_release_device(cinfo->zdev);
2227 2231
2228 if (cinfo->btype == BT_PICASSO4) { 2232 if (cinfo->btype == BT_PICASSO4) {
2229 cinfo->regbase -= 0x600000; 2233 cinfo->regbase -= 0x600000;
2230 iounmap ((void *)cinfo->regbase); 2234 iounmap((void *)cinfo->regbase);
2231 iounmap ((void *)cinfo->fbmem); 2235 iounmap(info->screen_base);
2232 } else { 2236 } else {
2233 if (zorro_resource_start(cinfo->zdev) > 0x01000000) 2237 if (zorro_resource_start(cinfo->zdev) > 0x01000000)
2234 iounmap ((void *)cinfo->fbmem); 2238 iounmap(info->screen_base);
2235 } 2239 }
2236 framebuffer_release(cinfo->info);
2237} 2240}
2238#endif /* CONFIG_ZORRO */ 2241#endif /* CONFIG_ZORRO */
2239 2242
2240static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo) 2243static int cirrusfb_set_fbinfo(struct fb_info *info)
2241{ 2244{
2242 struct fb_info *info = cinfo->info; 2245 struct cirrusfb_info *cinfo = info->par;
2243 struct fb_var_screeninfo *var = &info->var; 2246 struct fb_var_screeninfo *var = &info->var;
2244 2247
2245 info->par = cinfo;
2246 info->pseudo_palette = cinfo->pseudo_palette; 2248 info->pseudo_palette = cinfo->pseudo_palette;
2247 info->flags = FBINFO_DEFAULT 2249 info->flags = FBINFO_DEFAULT
2248 | FBINFO_HWACCEL_XPAN 2250 | FBINFO_HWACCEL_XPAN
@@ -2252,7 +2254,6 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
2252 if (noaccel) 2254 if (noaccel)
2253 info->flags |= FBINFO_HWACCEL_DISABLED; 2255 info->flags |= FBINFO_HWACCEL_DISABLED;
2254 info->fbops = &cirrusfb_ops; 2256 info->fbops = &cirrusfb_ops;
2255 info->screen_base = cinfo->fbmem;
2256 if (cinfo->btype == BT_GD5480) { 2257 if (cinfo->btype == BT_GD5480) {
2257 if (var->bits_per_pixel == 16) 2258 if (var->bits_per_pixel == 16)
2258 info->screen_base += 1 * MB_; 2259 info->screen_base += 1 * MB_;
@@ -2266,18 +2267,15 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
2266 2267
2267 /* monochrome: only 1 memory plane */ 2268 /* monochrome: only 1 memory plane */
2268 /* 8 bit and above: Use whole memory area */ 2269 /* 8 bit and above: Use whole memory area */
2269 info->fix.smem_start = cinfo->fbmem_phys; 2270 info->fix.smem_len = info->screen_size;
2270 info->fix.smem_len = (var->bits_per_pixel == 1) ? cinfo->size / 4 : cinfo->size; 2271 if (var->bits_per_pixel == 1)
2271 info->fix.type = cinfo->currentmode.type; 2272 info->fix.smem_len /= 4;
2272 info->fix.type_aux = 0; 2273 info->fix.type_aux = 0;
2273 info->fix.visual = cinfo->currentmode.visual;
2274 info->fix.xpanstep = 1; 2274 info->fix.xpanstep = 1;
2275 info->fix.ypanstep = 1; 2275 info->fix.ypanstep = 1;
2276 info->fix.ywrapstep = 0; 2276 info->fix.ywrapstep = 0;
2277 info->fix.line_length = cinfo->currentmode.line_length;
2278 2277
2279 /* FIXME: map region at 0xB8000 if available, fill in here */ 2278 /* FIXME: map region at 0xB8000 if available, fill in here */
2280 info->fix.mmio_start = cinfo->fbregs_phys;
2281 info->fix.mmio_len = 0; 2279 info->fix.mmio_len = 0;
2282 info->fix.accel = FB_ACCEL_NONE; 2280 info->fix.accel = FB_ACCEL_NONE;
2283 2281
@@ -2286,23 +2284,23 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
2286 return 0; 2284 return 0;
2287} 2285}
2288 2286
2289static int cirrusfb_register(struct cirrusfb_info *cinfo) 2287static int cirrusfb_register(struct fb_info *info)
2290{ 2288{
2291 struct fb_info *info; 2289 struct cirrusfb_info *cinfo = info->par;
2292 int err; 2290 int err;
2293 cirrusfb_board_t btype; 2291 enum cirrus_board btype;
2294 2292
2295 DPRINTK ("ENTER\n"); 2293 DPRINTK("ENTER\n");
2296 2294
2297 printk (KERN_INFO "cirrusfb: Driver for Cirrus Logic based graphic boards, v" CIRRUSFB_VERSION "\n"); 2295 printk(KERN_INFO "cirrusfb: Driver for Cirrus Logic based "
2296 "graphic boards, v" CIRRUSFB_VERSION "\n");
2298 2297
2299 info = cinfo->info;
2300 btype = cinfo->btype; 2298 btype = cinfo->btype;
2301 2299
2302 /* sanity checks */ 2300 /* sanity checks */
2303 assert (btype != BT_NONE); 2301 assert(btype != BT_NONE);
2304 2302
2305 DPRINTK ("cirrusfb: (RAM start set to: 0x%p)\n", cinfo->fbmem); 2303 DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
2306 2304
2307 /* Make pretend we've set the var so our structures are in a "good" */ 2305 /* Make pretend we've set the var so our structures are in a "good" */
2308 /* state, even though we haven't written the mode to the hw yet... */ 2306 /* state, even though we haven't written the mode to the hw yet... */
@@ -2317,47 +2315,49 @@ static int cirrusfb_register(struct cirrusfb_info *cinfo)
2317 } 2315 }
2318 2316
2319 /* set all the vital stuff */ 2317 /* set all the vital stuff */
2320 cirrusfb_set_fbinfo(cinfo); 2318 cirrusfb_set_fbinfo(info);
2321 2319
2322 err = register_framebuffer(info); 2320 err = register_framebuffer(info);
2323 if (err < 0) { 2321 if (err < 0) {
2324 printk (KERN_ERR "cirrusfb: could not register fb device; err = %d!\n", err); 2322 printk(KERN_ERR "cirrusfb: could not register "
2323 "fb device; err = %d!\n", err);
2325 goto err_dealloc_cmap; 2324 goto err_dealloc_cmap;
2326 } 2325 }
2327 2326
2328 DPRINTK ("EXIT, returning 0\n"); 2327 DPRINTK("EXIT, returning 0\n");
2329 return 0; 2328 return 0;
2330 2329
2331err_dealloc_cmap: 2330err_dealloc_cmap:
2332 fb_dealloc_cmap(&info->cmap); 2331 fb_dealloc_cmap(&info->cmap);
2333err_unmap_cirrusfb: 2332err_unmap_cirrusfb:
2334 cinfo->unmap(cinfo); 2333 cinfo->unmap(info);
2334 framebuffer_release(info);
2335 return err; 2335 return err;
2336} 2336}
2337 2337
2338static void __devexit cirrusfb_cleanup (struct fb_info *info) 2338static void __devexit cirrusfb_cleanup(struct fb_info *info)
2339{ 2339{
2340 struct cirrusfb_info *cinfo = info->par; 2340 struct cirrusfb_info *cinfo = info->par;
2341 DPRINTK ("ENTER\n"); 2341 DPRINTK("ENTER\n");
2342 2342
2343 switch_monitor (cinfo, 0); 2343 switch_monitor(cinfo, 0);
2344 2344
2345 unregister_framebuffer (info); 2345 unregister_framebuffer(info);
2346 fb_dealloc_cmap (&info->cmap); 2346 fb_dealloc_cmap(&info->cmap);
2347 printk ("Framebuffer unregistered\n"); 2347 printk("Framebuffer unregistered\n");
2348 cinfo->unmap(cinfo); 2348 cinfo->unmap(info);
2349 framebuffer_release(info);
2349 2350
2350 DPRINTK ("EXIT\n"); 2351 DPRINTK("EXIT\n");
2351} 2352}
2352 2353
2353
2354#ifdef CONFIG_PCI 2354#ifdef CONFIG_PCI
2355static int cirrusfb_pci_register (struct pci_dev *pdev, 2355static int cirrusfb_pci_register(struct pci_dev *pdev,
2356 const struct pci_device_id *ent) 2356 const struct pci_device_id *ent)
2357{ 2357{
2358 struct cirrusfb_info *cinfo; 2358 struct cirrusfb_info *cinfo;
2359 struct fb_info *info; 2359 struct fb_info *info;
2360 cirrusfb_board_t btype; 2360 enum cirrus_board btype;
2361 unsigned long board_addr, board_size; 2361 unsigned long board_addr, board_size;
2362 int ret; 2362 int ret;
2363 2363
@@ -2375,35 +2375,37 @@ static int cirrusfb_pci_register (struct pci_dev *pdev,
2375 } 2375 }
2376 2376
2377 cinfo = info->par; 2377 cinfo = info->par;
2378 cinfo->info = info;
2379 cinfo->pdev = pdev; 2378 cinfo->pdev = pdev;
2380 cinfo->btype = btype = (cirrusfb_board_t) ent->driver_data; 2379 cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
2381 2380
2382 DPRINTK (" Found PCI device, base address 0 is 0x%lx, btype set to %d\n", 2381 DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",
2383 pdev->resource[0].start, btype); 2382 pdev->resource[0].start, btype);
2384 DPRINTK (" base address 1 is 0x%lx\n", pdev->resource[1].start); 2383 DPRINTK(" base address 1 is 0x%x\n", pdev->resource[1].start);
2385 2384
2386 if(isPReP) { 2385 if (isPReP) {
2387 pci_write_config_dword (pdev, PCI_BASE_ADDRESS_0, 0x00000000); 2386 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
2388#ifdef CONFIG_PPC_PREP 2387#ifdef CONFIG_PPC_PREP
2389 get_prep_addrs (&board_addr, &cinfo->fbregs_phys); 2388 get_prep_addrs(&board_addr, &info->fix.mmio_start);
2390#endif 2389#endif
2391 /* PReP dies if we ioremap the IO registers, but it works w/out... */ 2390 /* PReP dies if we ioremap the IO registers, but it works w/out... */
2392 cinfo->regbase = (char __iomem *) cinfo->fbregs_phys; 2391 cinfo->regbase = (char __iomem *) info->fix.mmio_start;
2393 } else { 2392 } else {
2394 DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n"); 2393 DPRINTK("Attempt to get PCI info for Cirrus Graphics Card\n");
2395 get_pci_addrs (pdev, &board_addr, &cinfo->fbregs_phys); 2394 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2396 cinfo->regbase = NULL; /* FIXME: this forces VGA. alternatives? */ 2395 /* FIXME: this forces VGA. alternatives? */
2396 cinfo->regbase = NULL;
2397 } 2397 }
2398 2398
2399 DPRINTK ("Board address: 0x%lx, register address: 0x%lx\n", board_addr, cinfo->fbregs_phys); 2399 DPRINTK("Board address: 0x%lx, register address: 0x%lx\n",
2400 board_addr, info->fix.mmio_start);
2400 2401
2401 board_size = (btype == BT_GD5480) ? 2402 board_size = (btype == BT_GD5480) ?
2402 32 * MB_ : cirrusfb_get_memsize (cinfo->regbase); 2403 32 * MB_ : cirrusfb_get_memsize(cinfo->regbase);
2403 2404
2404 ret = pci_request_regions(pdev, "cirrusfb"); 2405 ret = pci_request_regions(pdev, "cirrusfb");
2405 if (ret <0) { 2406 if (ret < 0) {
2406 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n", 2407 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
2408 "abort\n",
2407 board_addr); 2409 board_addr);
2408 goto err_release_fb; 2410 goto err_release_fb;
2409 } 2411 }
@@ -2419,23 +2421,24 @@ static int cirrusfb_pci_register (struct pci_dev *pdev,
2419 if (request_region(0x3C0, 32, "cirrusfb")) 2421 if (request_region(0x3C0, 32, "cirrusfb"))
2420 release_io_ports = 1; 2422 release_io_ports = 1;
2421 2423
2422 cinfo->fbmem = ioremap(board_addr, board_size); 2424 info->screen_base = ioremap(board_addr, board_size);
2423 if (!cinfo->fbmem) { 2425 if (!info->screen_base) {
2424 ret = -EIO; 2426 ret = -EIO;
2425 goto err_release_legacy; 2427 goto err_release_legacy;
2426 } 2428 }
2427 2429
2428 cinfo->fbmem_phys = board_addr; 2430 info->fix.smem_start = board_addr;
2429 cinfo->size = board_size; 2431 info->screen_size = board_size;
2430 cinfo->unmap = cirrusfb_pci_unmap; 2432 cinfo->unmap = cirrusfb_pci_unmap;
2431 2433
2432 printk (" RAM (%lu kB) at 0xx%lx, ", cinfo->size / KB_, board_addr); 2434 printk(KERN_INFO " RAM (%lu kB) at 0xx%lx, ",
2433 printk ("Cirrus Logic chipset on PCI bus\n"); 2435 info->screen_size >> 10, board_addr);
2436 printk(KERN_INFO "Cirrus Logic chipset on PCI bus\n");
2434 pci_set_drvdata(pdev, info); 2437 pci_set_drvdata(pdev, info);
2435 2438
2436 ret = cirrusfb_register(cinfo); 2439 ret = cirrusfb_register(info);
2437 if (ret) 2440 if (ret)
2438 iounmap(cinfo->fbmem); 2441 iounmap(info->screen_base);
2439 return ret; 2442 return ret;
2440 2443
2441err_release_legacy: 2444err_release_legacy:
@@ -2453,14 +2456,14 @@ err_out:
2453 return ret; 2456 return ret;
2454} 2457}
2455 2458
2456static void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev) 2459static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
2457{ 2460{
2458 struct fb_info *info = pci_get_drvdata(pdev); 2461 struct fb_info *info = pci_get_drvdata(pdev);
2459 DPRINTK ("ENTER\n"); 2462 DPRINTK("ENTER\n");
2460 2463
2461 cirrusfb_cleanup (info); 2464 cirrusfb_cleanup(info);
2462 2465
2463 DPRINTK ("EXIT\n"); 2466 DPRINTK("EXIT\n");
2464} 2467}
2465 2468
2466static struct pci_driver cirrusfb_pci_driver = { 2469static struct pci_driver cirrusfb_pci_driver = {
@@ -2477,14 +2480,13 @@ static struct pci_driver cirrusfb_pci_driver = {
2477}; 2480};
2478#endif /* CONFIG_PCI */ 2481#endif /* CONFIG_PCI */
2479 2482
2480
2481#ifdef CONFIG_ZORRO 2483#ifdef CONFIG_ZORRO
2482static int cirrusfb_zorro_register(struct zorro_dev *z, 2484static int cirrusfb_zorro_register(struct zorro_dev *z,
2483 const struct zorro_device_id *ent) 2485 const struct zorro_device_id *ent)
2484{ 2486{
2485 struct cirrusfb_info *cinfo; 2487 struct cirrusfb_info *cinfo;
2486 struct fb_info *info; 2488 struct fb_info *info;
2487 cirrusfb_board_t btype; 2489 enum cirrus_board btype;
2488 struct zorro_dev *z2 = NULL; 2490 struct zorro_dev *z2 = NULL;
2489 unsigned long board_addr, board_size, size; 2491 unsigned long board_addr, board_size, size;
2490 int ret; 2492 int ret;
@@ -2498,83 +2500,86 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
2498 2500
2499 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); 2501 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2500 if (!info) { 2502 if (!info) {
2501 printk (KERN_ERR "cirrusfb: could not allocate memory\n"); 2503 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2502 ret = -ENOMEM; 2504 ret = -ENOMEM;
2503 goto err_out; 2505 goto err_out;
2504 } 2506 }
2505 2507
2506 cinfo = info->par; 2508 cinfo = info->par;
2507 cinfo->info = info;
2508 cinfo->btype = btype; 2509 cinfo->btype = btype;
2509 2510
2510 assert (z > 0); 2511 assert(z > 0);
2511 assert (z2 >= 0); 2512 assert(z2 >= 0);
2512 assert (btype != BT_NONE); 2513 assert(btype != BT_NONE);
2513 2514
2514 cinfo->zdev = z; 2515 cinfo->zdev = z;
2515 board_addr = zorro_resource_start(z); 2516 board_addr = zorro_resource_start(z);
2516 board_size = zorro_resource_len(z); 2517 board_size = zorro_resource_len(z);
2517 cinfo->size = size; 2518 info->screen_size = size;
2518 2519
2519 if (!zorro_request_device(z, "cirrusfb")) { 2520 if (!zorro_request_device(z, "cirrusfb")) {
2520 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n", 2521 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
2522 "abort\n",
2521 board_addr); 2523 board_addr);
2522 ret = -EBUSY; 2524 ret = -EBUSY;
2523 goto err_release_fb; 2525 goto err_release_fb;
2524 } 2526 }
2525 2527
2526 printk (" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr); 2528 printk(" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
2527 2529
2528 ret = -EIO; 2530 ret = -EIO;
2529 2531
2530 if (btype == BT_PICASSO4) { 2532 if (btype == BT_PICASSO4) {
2531 printk (" REG at $%lx\n", board_addr + 0x600000); 2533 printk(KERN_INFO " REG at $%lx\n", board_addr + 0x600000);
2532 2534
2533 /* To be precise, for the P4 this is not the */ 2535 /* To be precise, for the P4 this is not the */
2534 /* begin of the board, but the begin of RAM. */ 2536 /* begin of the board, but the begin of RAM. */
2535 /* for P4, map in its address space in 2 chunks (### TEST! ) */ 2537 /* for P4, map in its address space in 2 chunks (### TEST! ) */
2536 /* (note the ugly hardcoded 16M number) */ 2538 /* (note the ugly hardcoded 16M number) */
2537 cinfo->regbase = ioremap (board_addr, 16777216); 2539 cinfo->regbase = ioremap(board_addr, 16777216);
2538 if (!cinfo->regbase) 2540 if (!cinfo->regbase)
2539 goto err_release_region; 2541 goto err_release_region;
2540 2542
2541 DPRINTK ("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase); 2543 DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
2544 cinfo->regbase);
2542 cinfo->regbase += 0x600000; 2545 cinfo->regbase += 0x600000;
2543 cinfo->fbregs_phys = board_addr + 0x600000; 2546 info->fix.mmio_start = board_addr + 0x600000;
2544 2547
2545 cinfo->fbmem_phys = board_addr + 16777216; 2548 info->fix.smem_start = board_addr + 16777216;
2546 cinfo->fbmem = ioremap (cinfo->fbmem_phys, 16777216); 2549 info->screen_base = ioremap(info->fix.smem_start, 16777216);
2547 if (!cinfo->fbmem) 2550 if (!info->screen_base)
2548 goto err_unmap_regbase; 2551 goto err_unmap_regbase;
2549 } else { 2552 } else {
2550 printk (" REG at $%lx\n", (unsigned long) z2->resource.start); 2553 printk(KERN_INFO " REG at $%lx\n",
2554 (unsigned long) z2->resource.start);
2551 2555
2552 cinfo->fbmem_phys = board_addr; 2556 info->fix.smem_start = board_addr;
2553 if (board_addr > 0x01000000) 2557 if (board_addr > 0x01000000)
2554 cinfo->fbmem = ioremap (board_addr, board_size); 2558 info->screen_base = ioremap(board_addr, board_size);
2555 else 2559 else
2556 cinfo->fbmem = (caddr_t) ZTWO_VADDR (board_addr); 2560 info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
2557 if (!cinfo->fbmem) 2561 if (!info->screen_base)
2558 goto err_release_region; 2562 goto err_release_region;
2559 2563
2560 /* set address for REG area of board */ 2564 /* set address for REG area of board */
2561 cinfo->regbase = (caddr_t) ZTWO_VADDR (z2->resource.start); 2565 cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
2562 cinfo->fbregs_phys = z2->resource.start; 2566 info->fix.mmio_start = z2->resource.start;
2563 2567
2564 DPRINTK ("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase); 2568 DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
2569 cinfo->regbase);
2565 } 2570 }
2566 cinfo->unmap = cirrusfb_zorro_unmap; 2571 cinfo->unmap = cirrusfb_zorro_unmap;
2567 2572
2568 printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n"); 2573 printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
2569 zorro_set_drvdata(z, info); 2574 zorro_set_drvdata(z, info);
2570 2575
2571 ret = cirrusfb_register(cinfo); 2576 ret = cirrusfb_register(cinfo);
2572 if (ret) { 2577 if (ret) {
2573 if (btype == BT_PICASSO4) { 2578 if (btype == BT_PICASSO4) {
2574 iounmap(cinfo->fbmem); 2579 iounmap(info->screen_base);
2575 iounmap(cinfo->regbase - 0x600000); 2580 iounmap(cinfo->regbase - 0x600000);
2576 } else if (board_addr > 0x01000000) 2581 } else if (board_addr > 0x01000000)
2577 iounmap(cinfo->fbmem); 2582 iounmap(info->screen_base);
2578 } 2583 }
2579 return ret; 2584 return ret;
2580 2585
@@ -2592,11 +2597,11 @@ err_out:
2592void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z) 2597void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2593{ 2598{
2594 struct fb_info *info = zorro_get_drvdata(z); 2599 struct fb_info *info = zorro_get_drvdata(z);
2595 DPRINTK ("ENTER\n"); 2600 DPRINTK("ENTER\n");
2596 2601
2597 cirrusfb_cleanup (info); 2602 cirrusfb_cleanup(info);
2598 2603
2599 DPRINTK ("EXIT\n"); 2604 DPRINTK("EXIT\n");
2600} 2605}
2601 2606
2602static struct zorro_driver cirrusfb_zorro_driver = { 2607static struct zorro_driver cirrusfb_zorro_driver = {
@@ -2628,26 +2633,24 @@ static int __init cirrusfb_init(void)
2628 return error; 2633 return error;
2629} 2634}
2630 2635
2631
2632
2633#ifndef MODULE 2636#ifndef MODULE
2634static int __init cirrusfb_setup(char *options) { 2637static int __init cirrusfb_setup(char *options) {
2635 char *this_opt, s[32]; 2638 char *this_opt, s[32];
2636 int i; 2639 int i;
2637 2640
2638 DPRINTK ("ENTER\n"); 2641 DPRINTK("ENTER\n");
2639 2642
2640 if (!options || !*options) 2643 if (!options || !*options)
2641 return 0; 2644 return 0;
2642 2645
2643 while ((this_opt = strsep (&options, ",")) != NULL) { 2646 while ((this_opt = strsep(&options, ",")) != NULL) {
2644 if (!*this_opt) continue; 2647 if (!*this_opt) continue;
2645 2648
2646 DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); 2649 DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
2647 2650
2648 for (i = 0; i < NUM_TOTAL_MODES; i++) { 2651 for (i = 0; i < NUM_TOTAL_MODES; i++) {
2649 sprintf (s, "mode:%s", cirrusfb_predefined[i].name); 2652 sprintf(s, "mode:%s", cirrusfb_predefined[i].name);
2650 if (strcmp (this_opt, s) == 0) 2653 if (strcmp(this_opt, s) == 0)
2651 cirrusfb_def_mode = i; 2654 cirrusfb_def_mode = i;
2652 } 2655 }
2653 if (!strcmp(this_opt, "noaccel")) 2656 if (!strcmp(this_opt, "noaccel"))
@@ -2657,7 +2660,6 @@ static int __init cirrusfb_setup(char *options) {
2657} 2660}
2658#endif 2661#endif
2659 2662
2660
2661 /* 2663 /*
2662 * Modularization 2664 * Modularization
2663 */ 2665 */
@@ -2666,7 +2668,7 @@ MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2666MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips"); 2668MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2667MODULE_LICENSE("GPL"); 2669MODULE_LICENSE("GPL");
2668 2670
2669static void __exit cirrusfb_exit (void) 2671static void __exit cirrusfb_exit(void)
2670{ 2672{
2671#ifdef CONFIG_PCI 2673#ifdef CONFIG_PCI
2672 pci_unregister_driver(&cirrusfb_pci_driver); 2674 pci_unregister_driver(&cirrusfb_pci_driver);
@@ -2682,66 +2684,67 @@ module_init(cirrusfb_init);
2682module_exit(cirrusfb_exit); 2684module_exit(cirrusfb_exit);
2683#endif 2685#endif
2684 2686
2685
2686/**********************************************************************/ 2687/**********************************************************************/
2687/* about the following functions - I have used the same names for the */ 2688/* about the following functions - I have used the same names for the */
2688/* functions as Markus Wild did in his Retina driver for NetBSD as */ 2689/* functions as Markus Wild did in his Retina driver for NetBSD as */
2689/* they just made sense for this purpose. Apart from that, I wrote */ 2690/* they just made sense for this purpose. Apart from that, I wrote */
2690/* these functions myself. */ 2691/* these functions myself. */
2691/**********************************************************************/ 2692/**********************************************************************/
2692 2693
2693/*** WGen() - write into one of the external/general registers ***/ 2694/*** WGen() - write into one of the external/general registers ***/
2694static void WGen (const struct cirrusfb_info *cinfo, 2695static void WGen(const struct cirrusfb_info *cinfo,
2695 int regnum, unsigned char val) 2696 int regnum, unsigned char val)
2696{ 2697{
2697 unsigned long regofs = 0; 2698 unsigned long regofs = 0;
2698 2699
2699 if (cinfo->btype == BT_PICASSO) { 2700 if (cinfo->btype == BT_PICASSO) {
2700 /* Picasso II specific hack */ 2701 /* Picasso II specific hack */
2701/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */ 2702/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2703 regnum == CL_VSSM2) */
2702 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D) 2704 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2703 regofs = 0xfff; 2705 regofs = 0xfff;
2704 } 2706 }
2705 2707
2706 vga_w (cinfo->regbase, regofs + regnum, val); 2708 vga_w(cinfo->regbase, regofs + regnum, val);
2707} 2709}
2708 2710
2709/*** RGen() - read out one of the external/general registers ***/ 2711/*** RGen() - read out one of the external/general registers ***/
2710static unsigned char RGen (const struct cirrusfb_info *cinfo, int regnum) 2712static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2711{ 2713{
2712 unsigned long regofs = 0; 2714 unsigned long regofs = 0;
2713 2715
2714 if (cinfo->btype == BT_PICASSO) { 2716 if (cinfo->btype == BT_PICASSO) {
2715 /* Picasso II specific hack */ 2717 /* Picasso II specific hack */
2716/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */ 2718/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2719 regnum == CL_VSSM2) */
2717 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D) 2720 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2718 regofs = 0xfff; 2721 regofs = 0xfff;
2719 } 2722 }
2720 2723
2721 return vga_r (cinfo->regbase, regofs + regnum); 2724 return vga_r(cinfo->regbase, regofs + regnum);
2722} 2725}
2723 2726
2724/*** AttrOn() - turn on VideoEnable for Attribute controller ***/ 2727/*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2725static void AttrOn (const struct cirrusfb_info *cinfo) 2728static void AttrOn(const struct cirrusfb_info *cinfo)
2726{ 2729{
2727 assert (cinfo != NULL); 2730 assert(cinfo != NULL);
2728 2731
2729 DPRINTK ("ENTER\n"); 2732 DPRINTK("ENTER\n");
2730 2733
2731 if (vga_rcrt (cinfo->regbase, CL_CRT24) & 0x80) { 2734 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2732 /* if we're just in "write value" mode, write back the */ 2735 /* if we're just in "write value" mode, write back the */
2733 /* same value as before to not modify anything */ 2736 /* same value as before to not modify anything */
2734 vga_w (cinfo->regbase, VGA_ATT_IW, 2737 vga_w(cinfo->regbase, VGA_ATT_IW,
2735 vga_r (cinfo->regbase, VGA_ATT_R)); 2738 vga_r(cinfo->regbase, VGA_ATT_R));
2736 } 2739 }
2737 /* turn on video bit */ 2740 /* turn on video bit */
2738/* vga_w (cinfo->regbase, VGA_ATT_IW, 0x20); */ 2741/* vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2739 vga_w (cinfo->regbase, VGA_ATT_IW, 0x33); 2742 vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2740 2743
2741 /* dummy write on Reg0 to be on "write index" mode next time */ 2744 /* dummy write on Reg0 to be on "write index" mode next time */
2742 vga_w (cinfo->regbase, VGA_ATT_IW, 0x00); 2745 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2743 2746
2744 DPRINTK ("EXIT\n"); 2747 DPRINTK("EXIT\n");
2745} 2748}
2746 2749
2747/*** WHDR() - write into the Hidden DAC register ***/ 2750/*** WHDR() - write into the Hidden DAC register ***/
@@ -2750,119 +2753,115 @@ static void AttrOn (const struct cirrusfb_info *cinfo)
2750 * registers of their functional group) here is a specialized routine for 2753 * registers of their functional group) here is a specialized routine for
2751 * accessing the HDR 2754 * accessing the HDR
2752 */ 2755 */
2753static void WHDR (const struct cirrusfb_info *cinfo, unsigned char val) 2756static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2754{ 2757{
2755 unsigned char dummy; 2758 unsigned char dummy;
2756 2759
2757 if (cinfo->btype == BT_PICASSO) { 2760 if (cinfo->btype == BT_PICASSO) {
2758 /* Klaus' hint for correct access to HDR on some boards */ 2761 /* Klaus' hint for correct access to HDR on some boards */
2759 /* first write 0 to pixel mask (3c6) */ 2762 /* first write 0 to pixel mask (3c6) */
2760 WGen (cinfo, VGA_PEL_MSK, 0x00); 2763 WGen(cinfo, VGA_PEL_MSK, 0x00);
2761 udelay (200); 2764 udelay(200);
2762 /* next read dummy from pixel address (3c8) */ 2765 /* next read dummy from pixel address (3c8) */
2763 dummy = RGen (cinfo, VGA_PEL_IW); 2766 dummy = RGen(cinfo, VGA_PEL_IW);
2764 udelay (200); 2767 udelay(200);
2765 } 2768 }
2766 /* now do the usual stuff to access the HDR */ 2769 /* now do the usual stuff to access the HDR */
2767 2770
2768 dummy = RGen (cinfo, VGA_PEL_MSK); 2771 dummy = RGen(cinfo, VGA_PEL_MSK);
2769 udelay (200); 2772 udelay(200);
2770 dummy = RGen (cinfo, VGA_PEL_MSK); 2773 dummy = RGen(cinfo, VGA_PEL_MSK);
2771 udelay (200); 2774 udelay(200);
2772 dummy = RGen (cinfo, VGA_PEL_MSK); 2775 dummy = RGen(cinfo, VGA_PEL_MSK);
2773 udelay (200); 2776 udelay(200);
2774 dummy = RGen (cinfo, VGA_PEL_MSK); 2777 dummy = RGen(cinfo, VGA_PEL_MSK);
2775 udelay (200); 2778 udelay(200);
2776 2779
2777 WGen (cinfo, VGA_PEL_MSK, val); 2780 WGen(cinfo, VGA_PEL_MSK, val);
2778 udelay (200); 2781 udelay(200);
2779 2782
2780 if (cinfo->btype == BT_PICASSO) { 2783 if (cinfo->btype == BT_PICASSO) {
2781 /* now first reset HDR access counter */ 2784 /* now first reset HDR access counter */
2782 dummy = RGen (cinfo, VGA_PEL_IW); 2785 dummy = RGen(cinfo, VGA_PEL_IW);
2783 udelay (200); 2786 udelay(200);
2784 2787
2785 /* and at the end, restore the mask value */ 2788 /* and at the end, restore the mask value */
2786 /* ## is this mask always 0xff? */ 2789 /* ## is this mask always 0xff? */
2787 WGen (cinfo, VGA_PEL_MSK, 0xff); 2790 WGen(cinfo, VGA_PEL_MSK, 0xff);
2788 udelay (200); 2791 udelay(200);
2789 } 2792 }
2790} 2793}
2791 2794
2792
2793/*** WSFR() - write to the "special function register" (SFR) ***/ 2795/*** WSFR() - write to the "special function register" (SFR) ***/
2794static void WSFR (struct cirrusfb_info *cinfo, unsigned char val) 2796static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2795{ 2797{
2796#ifdef CONFIG_ZORRO 2798#ifdef CONFIG_ZORRO
2797 assert (cinfo->regbase != NULL); 2799 assert(cinfo->regbase != NULL);
2798 cinfo->SFR = val; 2800 cinfo->SFR = val;
2799 z_writeb (val, cinfo->regbase + 0x8000); 2801 z_writeb(val, cinfo->regbase + 0x8000);
2800#endif 2802#endif
2801} 2803}
2802 2804
2803/* The Picasso has a second register for switching the monitor bit */ 2805/* The Picasso has a second register for switching the monitor bit */
2804static void WSFR2 (struct cirrusfb_info *cinfo, unsigned char val) 2806static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2805{ 2807{
2806#ifdef CONFIG_ZORRO 2808#ifdef CONFIG_ZORRO
2807 /* writing an arbitrary value to this one causes the monitor switcher */ 2809 /* writing an arbitrary value to this one causes the monitor switcher */
2808 /* to flip to Amiga display */ 2810 /* to flip to Amiga display */
2809 assert (cinfo->regbase != NULL); 2811 assert(cinfo->regbase != NULL);
2810 cinfo->SFR = val; 2812 cinfo->SFR = val;
2811 z_writeb (val, cinfo->regbase + 0x9000); 2813 z_writeb(val, cinfo->regbase + 0x9000);
2812#endif 2814#endif
2813} 2815}
2814 2816
2815
2816/*** WClut - set CLUT entry (range: 0..63) ***/ 2817/*** WClut - set CLUT entry (range: 0..63) ***/
2817static void WClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red, 2818static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2818 unsigned char green, unsigned char blue) 2819 unsigned char green, unsigned char blue)
2819{ 2820{
2820 unsigned int data = VGA_PEL_D; 2821 unsigned int data = VGA_PEL_D;
2821 2822
2822 /* address write mode register is not translated.. */ 2823 /* address write mode register is not translated.. */
2823 vga_w (cinfo->regbase, VGA_PEL_IW, regnum); 2824 vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2824 2825
2825 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2826 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2826 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) { 2827 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2827 /* but DAC data register IS, at least for Picasso II */ 2828 /* but DAC data register IS, at least for Picasso II */
2828 if (cinfo->btype == BT_PICASSO) 2829 if (cinfo->btype == BT_PICASSO)
2829 data += 0xfff; 2830 data += 0xfff;
2830 vga_w (cinfo->regbase, data, red); 2831 vga_w(cinfo->regbase, data, red);
2831 vga_w (cinfo->regbase, data, green); 2832 vga_w(cinfo->regbase, data, green);
2832 vga_w (cinfo->regbase, data, blue); 2833 vga_w(cinfo->regbase, data, blue);
2833 } else { 2834 } else {
2834 vga_w (cinfo->regbase, data, blue); 2835 vga_w(cinfo->regbase, data, blue);
2835 vga_w (cinfo->regbase, data, green); 2836 vga_w(cinfo->regbase, data, green);
2836 vga_w (cinfo->regbase, data, red); 2837 vga_w(cinfo->regbase, data, red);
2837 } 2838 }
2838} 2839}
2839 2840
2840
2841#if 0 2841#if 0
2842/*** RClut - read CLUT entry (range 0..63) ***/ 2842/*** RClut - read CLUT entry (range 0..63) ***/
2843static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red, 2843static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2844 unsigned char *green, unsigned char *blue) 2844 unsigned char *green, unsigned char *blue)
2845{ 2845{
2846 unsigned int data = VGA_PEL_D; 2846 unsigned int data = VGA_PEL_D;
2847 2847
2848 vga_w (cinfo->regbase, VGA_PEL_IR, regnum); 2848 vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2849 2849
2850 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2850 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2851 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) { 2851 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2852 if (cinfo->btype == BT_PICASSO) 2852 if (cinfo->btype == BT_PICASSO)
2853 data += 0xfff; 2853 data += 0xfff;
2854 *red = vga_r (cinfo->regbase, data); 2854 *red = vga_r(cinfo->regbase, data);
2855 *green = vga_r (cinfo->regbase, data); 2855 *green = vga_r(cinfo->regbase, data);
2856 *blue = vga_r (cinfo->regbase, data); 2856 *blue = vga_r(cinfo->regbase, data);
2857 } else { 2857 } else {
2858 *blue = vga_r (cinfo->regbase, data); 2858 *blue = vga_r(cinfo->regbase, data);
2859 *green = vga_r (cinfo->regbase, data); 2859 *green = vga_r(cinfo->regbase, data);
2860 *red = vga_r (cinfo->regbase, data); 2860 *red = vga_r(cinfo->regbase, data);
2861 } 2861 }
2862} 2862}
2863#endif 2863#endif
2864 2864
2865
2866/******************************************************************* 2865/*******************************************************************
2867 cirrusfb_WaitBLT() 2866 cirrusfb_WaitBLT()
2868 2867
@@ -2870,10 +2869,10 @@ static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned c
2870*********************************************************************/ 2869*********************************************************************/
2871 2870
2872/* FIXME: use interrupts instead */ 2871/* FIXME: use interrupts instead */
2873static void cirrusfb_WaitBLT (u8 __iomem *regbase) 2872static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2874{ 2873{
2875 /* now busy-wait until we're done */ 2874 /* now busy-wait until we're done */
2876 while (vga_rgfx (regbase, CL_GR31) & 0x08) 2875 while (vga_rgfx(regbase, CL_GR31) & 0x08)
2877 /* do nothing */ ; 2876 /* do nothing */ ;
2878} 2877}
2879 2878
@@ -2883,15 +2882,17 @@ static void cirrusfb_WaitBLT (u8 __iomem *regbase)
2883 perform accelerated "scrolling" 2882 perform accelerated "scrolling"
2884********************************************************************/ 2883********************************************************************/
2885 2884
2886static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel, 2885static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2887 u_short curx, u_short cury, u_short destx, u_short desty, 2886 u_short curx, u_short cury,
2888 u_short width, u_short height, u_short line_length) 2887 u_short destx, u_short desty,
2888 u_short width, u_short height,
2889 u_short line_length)
2889{ 2890{
2890 u_short nwidth, nheight; 2891 u_short nwidth, nheight;
2891 u_long nsrc, ndest; 2892 u_long nsrc, ndest;
2892 u_char bltmode; 2893 u_char bltmode;
2893 2894
2894 DPRINTK ("ENTER\n"); 2895 DPRINTK("ENTER\n");
2895 2896
2896 nwidth = width - 1; 2897 nwidth = width - 1;
2897 nheight = height - 1; 2898 nheight = height - 1;
@@ -2911,9 +2912,13 @@ static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
2911 nsrc = (cury * line_length) + curx; 2912 nsrc = (cury * line_length) + curx;
2912 ndest = (desty * line_length) + destx; 2913 ndest = (desty * line_length) + destx;
2913 } else { 2914 } else {
2914 /* this means start addresses are at the end, counting backwards */ 2915 /* this means start addresses are at the end,
2915 nsrc = cury * line_length + curx + nheight * line_length + nwidth; 2916 * counting backwards
2916 ndest = desty * line_length + destx + nheight * line_length + nwidth; 2917 */
2918 nsrc = cury * line_length + curx +
2919 nheight * line_length + nwidth;
2920 ndest = desty * line_length + destx +
2921 nheight * line_length + nwidth;
2917 } 2922 }
2918 2923
2919 /* 2924 /*
@@ -2929,52 +2934,65 @@ static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
2929 start/stop 2934 start/stop
2930 */ 2935 */
2931 2936
2932 cirrusfb_WaitBLT(regbase); 2937 cirrusfb_WaitBLT(regbase);
2933 2938
2934 /* pitch: set to line_length */ 2939 /* pitch: set to line_length */
2935 vga_wgfx (regbase, CL_GR24, line_length & 0xff); /* dest pitch low */ 2940 /* dest pitch low */
2936 vga_wgfx (regbase, CL_GR25, (line_length >> 8)); /* dest pitch hi */ 2941 vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2937 vga_wgfx (regbase, CL_GR26, line_length & 0xff); /* source pitch low */ 2942 /* dest pitch hi */
2938 vga_wgfx (regbase, CL_GR27, (line_length >> 8)); /* source pitch hi */ 2943 vga_wgfx(regbase, CL_GR25, line_length >> 8);
2944 /* source pitch low */
2945 vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2946 /* source pitch hi */
2947 vga_wgfx(regbase, CL_GR27, line_length >> 8);
2939 2948
2940 /* BLT width: actual number of pixels - 1 */ 2949 /* BLT width: actual number of pixels - 1 */
2941 vga_wgfx (regbase, CL_GR20, nwidth & 0xff); /* BLT width low */ 2950 /* BLT width low */
2942 vga_wgfx (regbase, CL_GR21, (nwidth >> 8)); /* BLT width hi */ 2951 vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2952 /* BLT width hi */
2953 vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2943 2954
2944 /* BLT height: actual number of lines -1 */ 2955 /* BLT height: actual number of lines -1 */
2945 vga_wgfx (regbase, CL_GR22, nheight & 0xff); /* BLT height low */ 2956 /* BLT height low */
2946 vga_wgfx (regbase, CL_GR23, (nheight >> 8)); /* BLT width hi */ 2957 vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2958 /* BLT width hi */
2959 vga_wgfx(regbase, CL_GR23, nheight >> 8);
2947 2960
2948 /* BLT destination */ 2961 /* BLT destination */
2949 vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff)); /* BLT dest low */ 2962 /* BLT dest low */
2950 vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8)); /* BLT dest mid */ 2963 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2951 vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16)); /* BLT dest hi */ 2964 /* BLT dest mid */
2965 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2966 /* BLT dest hi */
2967 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2952 2968
2953 /* BLT source */ 2969 /* BLT source */
2954 vga_wgfx (regbase, CL_GR2C, (u_char) (nsrc & 0xff)); /* BLT src low */ 2970 /* BLT src low */
2955 vga_wgfx (regbase, CL_GR2D, (u_char) (nsrc >> 8)); /* BLT src mid */ 2971 vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2956 vga_wgfx (regbase, CL_GR2E, (u_char) (nsrc >> 16)); /* BLT src hi */ 2972 /* BLT src mid */
2973 vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2974 /* BLT src hi */
2975 vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2957 2976
2958 /* BLT mode */ 2977 /* BLT mode */
2959 vga_wgfx (regbase, CL_GR30, bltmode); /* BLT mode */ 2978 vga_wgfx(regbase, CL_GR30, bltmode); /* BLT mode */
2960 2979
2961 /* BLT ROP: SrcCopy */ 2980 /* BLT ROP: SrcCopy */
2962 vga_wgfx (regbase, CL_GR32, 0x0d); /* BLT ROP */ 2981 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
2963 2982
2964 /* and finally: GO! */ 2983 /* and finally: GO! */
2965 vga_wgfx (regbase, CL_GR31, 0x02); /* BLT Start/status */ 2984 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
2966 2985
2967 DPRINTK ("EXIT\n"); 2986 DPRINTK("EXIT\n");
2968} 2987}
2969 2988
2970
2971/******************************************************************* 2989/*******************************************************************
2972 cirrusfb_RectFill() 2990 cirrusfb_RectFill()
2973 2991
2974 perform accelerated rectangle fill 2992 perform accelerated rectangle fill
2975********************************************************************/ 2993********************************************************************/
2976 2994
2977static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel, 2995static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2978 u_short x, u_short y, u_short width, u_short height, 2996 u_short x, u_short y, u_short width, u_short height,
2979 u_char color, u_short line_length) 2997 u_char color, u_short line_length)
2980{ 2998{
@@ -2982,93 +3000,95 @@ static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel,
2982 u_long ndest; 3000 u_long ndest;
2983 u_char op; 3001 u_char op;
2984 3002
2985 DPRINTK ("ENTER\n"); 3003 DPRINTK("ENTER\n");
2986 3004
2987 nwidth = width - 1; 3005 nwidth = width - 1;
2988 nheight = height - 1; 3006 nheight = height - 1;
2989 3007
2990 ndest = (y * line_length) + x; 3008 ndest = (y * line_length) + x;
2991 3009
2992 cirrusfb_WaitBLT(regbase); 3010 cirrusfb_WaitBLT(regbase);
2993 3011
2994 /* pitch: set to line_length */ 3012 /* pitch: set to line_length */
2995 vga_wgfx (regbase, CL_GR24, line_length & 0xff); /* dest pitch low */ 3013 vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
2996 vga_wgfx (regbase, CL_GR25, (line_length >> 8)); /* dest pitch hi */ 3014 vga_wgfx(regbase, CL_GR25, line_length >> 8); /* dest pitch hi */
2997 vga_wgfx (regbase, CL_GR26, line_length & 0xff); /* source pitch low */ 3015 vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */
2998 vga_wgfx (regbase, CL_GR27, (line_length >> 8)); /* source pitch hi */ 3016 vga_wgfx(regbase, CL_GR27, line_length >> 8); /* source pitch hi */
2999 3017
3000 /* BLT width: actual number of pixels - 1 */ 3018 /* BLT width: actual number of pixels - 1 */
3001 vga_wgfx (regbase, CL_GR20, nwidth & 0xff); /* BLT width low */ 3019 vga_wgfx(regbase, CL_GR20, nwidth & 0xff); /* BLT width low */
3002 vga_wgfx (regbase, CL_GR21, (nwidth >> 8)); /* BLT width hi */ 3020 vga_wgfx(regbase, CL_GR21, nwidth >> 8); /* BLT width hi */
3003 3021
3004 /* BLT height: actual number of lines -1 */ 3022 /* BLT height: actual number of lines -1 */
3005 vga_wgfx (regbase, CL_GR22, nheight & 0xff); /* BLT height low */ 3023 vga_wgfx(regbase, CL_GR22, nheight & 0xff); /* BLT height low */
3006 vga_wgfx (regbase, CL_GR23, (nheight >> 8)); /* BLT width hi */ 3024 vga_wgfx(regbase, CL_GR23, nheight >> 8); /* BLT width hi */
3007 3025
3008 /* BLT destination */ 3026 /* BLT destination */
3009 vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff)); /* BLT dest low */ 3027 /* BLT dest low */
3010 vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8)); /* BLT dest mid */ 3028 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
3011 vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16)); /* BLT dest hi */ 3029 /* BLT dest mid */
3030 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
3031 /* BLT dest hi */
3032 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
3012 3033
3013 /* BLT source: set to 0 (is a dummy here anyway) */ 3034 /* BLT source: set to 0 (is a dummy here anyway) */
3014 vga_wgfx (regbase, CL_GR2C, 0x00); /* BLT src low */ 3035 vga_wgfx(regbase, CL_GR2C, 0x00); /* BLT src low */
3015 vga_wgfx (regbase, CL_GR2D, 0x00); /* BLT src mid */ 3036 vga_wgfx(regbase, CL_GR2D, 0x00); /* BLT src mid */
3016 vga_wgfx (regbase, CL_GR2E, 0x00); /* BLT src hi */ 3037 vga_wgfx(regbase, CL_GR2E, 0x00); /* BLT src hi */
3017 3038
3018 /* This is a ColorExpand Blt, using the */ 3039 /* This is a ColorExpand Blt, using the */
3019 /* same color for foreground and background */ 3040 /* same color for foreground and background */
3020 vga_wgfx (regbase, VGA_GFX_SR_VALUE, color); /* foreground color */ 3041 vga_wgfx(regbase, VGA_GFX_SR_VALUE, color); /* foreground color */
3021 vga_wgfx (regbase, VGA_GFX_SR_ENABLE, color); /* background color */ 3042 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color); /* background color */
3022 3043
3023 op = 0xc0; 3044 op = 0xc0;
3024 if (bits_per_pixel == 16) { 3045 if (bits_per_pixel == 16) {
3025 vga_wgfx (regbase, CL_GR10, color); /* foreground color */ 3046 vga_wgfx(regbase, CL_GR10, color); /* foreground color */
3026 vga_wgfx (regbase, CL_GR11, color); /* background color */ 3047 vga_wgfx(regbase, CL_GR11, color); /* background color */
3027 op = 0x50; 3048 op = 0x50;
3028 op = 0xd0; 3049 op = 0xd0;
3029 } else if (bits_per_pixel == 32) { 3050 } else if (bits_per_pixel == 32) {
3030 vga_wgfx (regbase, CL_GR10, color); /* foreground color */ 3051 vga_wgfx(regbase, CL_GR10, color); /* foreground color */
3031 vga_wgfx (regbase, CL_GR11, color); /* background color */ 3052 vga_wgfx(regbase, CL_GR11, color); /* background color */
3032 vga_wgfx (regbase, CL_GR12, color); /* foreground color */ 3053 vga_wgfx(regbase, CL_GR12, color); /* foreground color */
3033 vga_wgfx (regbase, CL_GR13, color); /* background color */ 3054 vga_wgfx(regbase, CL_GR13, color); /* background color */
3034 vga_wgfx (regbase, CL_GR14, 0); /* foreground color */ 3055 vga_wgfx(regbase, CL_GR14, 0); /* foreground color */
3035 vga_wgfx (regbase, CL_GR15, 0); /* background color */ 3056 vga_wgfx(regbase, CL_GR15, 0); /* background color */
3036 op = 0x50; 3057 op = 0x50;
3037 op = 0xf0; 3058 op = 0xf0;
3038 } 3059 }
3039 /* BLT mode: color expand, Enable 8x8 copy (faster?) */ 3060 /* BLT mode: color expand, Enable 8x8 copy (faster?) */
3040 vga_wgfx (regbase, CL_GR30, op); /* BLT mode */ 3061 vga_wgfx(regbase, CL_GR30, op); /* BLT mode */
3041 3062
3042 /* BLT ROP: SrcCopy */ 3063 /* BLT ROP: SrcCopy */
3043 vga_wgfx (regbase, CL_GR32, 0x0d); /* BLT ROP */ 3064 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
3044 3065
3045 /* and finally: GO! */ 3066 /* and finally: GO! */
3046 vga_wgfx (regbase, CL_GR31, 0x02); /* BLT Start/status */ 3067 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
3047 3068
3048 DPRINTK ("EXIT\n"); 3069 DPRINTK("EXIT\n");
3049} 3070}
3050 3071
3051
3052/************************************************************************** 3072/**************************************************************************
3053 * bestclock() - determine closest possible clock lower(?) than the 3073 * bestclock() - determine closest possible clock lower(?) than the
3054 * desired pixel clock 3074 * desired pixel clock
3055 **************************************************************************/ 3075 **************************************************************************/
3056static void bestclock (long freq, long *best, long *nom, 3076static void bestclock(long freq, long *best, long *nom,
3057 long *den, long *div, long maxfreq) 3077 long *den, long *div, long maxfreq)
3058{ 3078{
3059 long n, h, d, f; 3079 long n, h, d, f;
3060 3080
3061 assert (best != NULL); 3081 assert(best != NULL);
3062 assert (nom != NULL); 3082 assert(nom != NULL);
3063 assert (den != NULL); 3083 assert(den != NULL);
3064 assert (div != NULL); 3084 assert(div != NULL);
3065 assert (maxfreq > 0); 3085 assert(maxfreq > 0);
3066 3086
3067 *nom = 0; 3087 *nom = 0;
3068 *den = 0; 3088 *den = 0;
3069 *div = 0; 3089 *div = 0;
3070 3090
3071 DPRINTK ("ENTER\n"); 3091 DPRINTK("ENTER\n");
3072 3092
3073 if (freq < 8000) 3093 if (freq < 8000)
3074 freq = 8000; 3094 freq = 8000;
@@ -3085,7 +3105,7 @@ static void bestclock (long freq, long *best, long *nom,
3085 if (d > 31) 3105 if (d > 31)
3086 d = (d / 2) * 2; 3106 d = (d / 2) * 2;
3087 h = (14318 * n) / d; 3107 h = (14318 * n) / d;
3088 if (abs (h - freq) < abs (*best - freq)) { 3108 if (abs(h - freq) < abs(*best - freq)) {
3089 *best = h; 3109 *best = h;
3090 *nom = n; 3110 *nom = n;
3091 if (d < 32) { 3111 if (d < 32) {
@@ -3102,7 +3122,7 @@ static void bestclock (long freq, long *best, long *nom,
3102 if (d > 31) 3122 if (d > 31)
3103 d = (d / 2) * 2; 3123 d = (d / 2) * 2;
3104 h = (14318 * n) / d; 3124 h = (14318 * n) / d;
3105 if (abs (h - freq) < abs (*best - freq)) { 3125 if (abs(h - freq) < abs(*best - freq)) {
3106 *best = h; 3126 *best = h;
3107 *nom = n; 3127 *nom = n;
3108 if (d < 32) { 3128 if (d < 32) {
@@ -3116,14 +3136,13 @@ static void bestclock (long freq, long *best, long *nom,
3116 } 3136 }
3117 } 3137 }
3118 3138
3119 DPRINTK ("Best possible values for given frequency:\n"); 3139 DPRINTK("Best possible values for given frequency:\n");
3120 DPRINTK (" best: %ld kHz nom: %ld den: %ld div: %ld\n", 3140 DPRINTK(" best: %ld kHz nom: %ld den: %ld div: %ld\n",
3121 freq, *nom, *den, *div); 3141 freq, *nom, *den, *div);
3122 3142
3123 DPRINTK ("EXIT\n"); 3143 DPRINTK("EXIT\n");
3124} 3144}
3125 3145
3126
3127/* ------------------------------------------------------------------------- 3146/* -------------------------------------------------------------------------
3128 * 3147 *
3129 * debugging functions 3148 * debugging functions
@@ -3145,21 +3164,20 @@ static void bestclock (long freq, long *best, long *nom,
3145 */ 3164 */
3146 3165
3147static 3166static
3148void cirrusfb_dbg_print_byte (const char *name, unsigned char val) 3167void cirrusfb_dbg_print_byte(const char *name, unsigned char val)
3149{ 3168{
3150 DPRINTK ("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n", 3169 DPRINTK("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
3151 name, val, 3170 name, val,
3152 val & 0x80 ? '1' : '0', 3171 val & 0x80 ? '1' : '0',
3153 val & 0x40 ? '1' : '0', 3172 val & 0x40 ? '1' : '0',
3154 val & 0x20 ? '1' : '0', 3173 val & 0x20 ? '1' : '0',
3155 val & 0x10 ? '1' : '0', 3174 val & 0x10 ? '1' : '0',
3156 val & 0x08 ? '1' : '0', 3175 val & 0x08 ? '1' : '0',
3157 val & 0x04 ? '1' : '0', 3176 val & 0x04 ? '1' : '0',
3158 val & 0x02 ? '1' : '0', 3177 val & 0x02 ? '1' : '0',
3159 val & 0x01 ? '1' : '0'); 3178 val & 0x01 ? '1' : '0');
3160} 3179}
3161 3180
3162
3163/** 3181/**
3164 * cirrusfb_dbg_print_regs 3182 * cirrusfb_dbg_print_regs
3165 * @base: If using newmmio, the newmmio base address, otherwise %NULL 3183 * @base: If using newmmio, the newmmio base address, otherwise %NULL
@@ -3172,25 +3190,26 @@ void cirrusfb_dbg_print_byte (const char *name, unsigned char val)
3172 */ 3190 */
3173 3191
3174static 3192static
3175void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_class,...) 3193void cirrusfb_dbg_print_regs(caddr_t regbase,
3194 enum cirrusfb_dbg_reg_class reg_class, ...)
3176{ 3195{
3177 va_list list; 3196 va_list list;
3178 unsigned char val = 0; 3197 unsigned char val = 0;
3179 unsigned reg; 3198 unsigned reg;
3180 char *name; 3199 char *name;
3181 3200
3182 va_start (list, reg_class); 3201 va_start(list, reg_class);
3183 3202
3184 name = va_arg (list, char *); 3203 name = va_arg(list, char *);
3185 while (name != NULL) { 3204 while (name != NULL) {
3186 reg = va_arg (list, int); 3205 reg = va_arg(list, int);
3187 3206
3188 switch (reg_class) { 3207 switch (reg_class) {
3189 case CRT: 3208 case CRT:
3190 val = vga_rcrt (regbase, (unsigned char) reg); 3209 val = vga_rcrt(regbase, (unsigned char) reg);
3191 break; 3210 break;
3192 case SEQ: 3211 case SEQ:
3193 val = vga_rseq (regbase, (unsigned char) reg); 3212 val = vga_rseq(regbase, (unsigned char) reg);
3194 break; 3213 break;
3195 default: 3214 default:
3196 /* should never occur */ 3215 /* should never occur */
@@ -3198,15 +3217,14 @@ void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_clas
3198 break; 3217 break;
3199 } 3218 }
3200 3219
3201 cirrusfb_dbg_print_byte (name, val); 3220 cirrusfb_dbg_print_byte(name, val);
3202 3221
3203 name = va_arg (list, char *); 3222 name = va_arg(list, char *);
3204 } 3223 }
3205 3224
3206 va_end (list); 3225 va_end(list);
3207} 3226}
3208 3227
3209
3210/** 3228/**
3211 * cirrusfb_dump 3229 * cirrusfb_dump
3212 * @cirrusfbinfo: 3230 * @cirrusfbinfo:
@@ -3214,13 +3232,11 @@ void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_clas
3214 * DESCRIPTION: 3232 * DESCRIPTION:
3215 */ 3233 */
3216 3234
3217static 3235static void cirrusfb_dump(void)
3218void cirrusfb_dump (void)
3219{ 3236{
3220 cirrusfb_dbg_reg_dump (NULL); 3237 cirrusfb_dbg_reg_dump(NULL);
3221} 3238}
3222 3239
3223
3224/** 3240/**
3225 * cirrusfb_dbg_reg_dump 3241 * cirrusfb_dbg_reg_dump
3226 * @base: If using newmmio, the newmmio base address, otherwise %NULL 3242 * @base: If using newmmio, the newmmio base address, otherwise %NULL
@@ -3232,11 +3248,11 @@ void cirrusfb_dump (void)
3232 */ 3248 */
3233 3249
3234static 3250static
3235void cirrusfb_dbg_reg_dump (caddr_t regbase) 3251void cirrusfb_dbg_reg_dump(caddr_t regbase)
3236{ 3252{
3237 DPRINTK ("CIRRUSFB VGA CRTC register dump:\n"); 3253 DPRINTK("CIRRUSFB VGA CRTC register dump:\n");
3238 3254
3239 cirrusfb_dbg_print_regs (regbase, CRT, 3255 cirrusfb_dbg_print_regs(regbase, CRT,
3240 "CR00", 0x00, 3256 "CR00", 0x00,
3241 "CR01", 0x01, 3257 "CR01", 0x01,
3242 "CR02", 0x02, 3258 "CR02", 0x02,
@@ -3286,11 +3302,11 @@ void cirrusfb_dbg_reg_dump (caddr_t regbase)
3286 "CR3F", 0x3F, 3302 "CR3F", 0x3F,
3287 NULL); 3303 NULL);
3288 3304
3289 DPRINTK ("\n"); 3305 DPRINTK("\n");
3290 3306
3291 DPRINTK ("CIRRUSFB VGA SEQ register dump:\n"); 3307 DPRINTK("CIRRUSFB VGA SEQ register dump:\n");
3292 3308
3293 cirrusfb_dbg_print_regs (regbase, SEQ, 3309 cirrusfb_dbg_print_regs(regbase, SEQ,
3294 "SR00", 0x00, 3310 "SR00", 0x00,
3295 "SR01", 0x01, 3311 "SR01", 0x01,
3296 "SR02", 0x02, 3312 "SR02", 0x02,
@@ -3319,7 +3335,7 @@ void cirrusfb_dbg_reg_dump (caddr_t regbase)
3319 "SR1F", 0x1F, 3335 "SR1F", 0x1F,
3320 NULL); 3336 NULL);
3321 3337
3322 DPRINTK ("\n"); 3338 DPRINTK("\n");
3323} 3339}
3324 3340
3325#endif /* CIRRUSFB_DEBUG */ 3341#endif /* CIRRUSFB_DEBUG */
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index dea6579941b7..17b5267f44d7 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -29,7 +29,7 @@
29 29
30#include <asm/hardware.h> 30#include <asm/hardware.h>
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <asm/uaccess.h> 32#include <linux/uaccess.h>
33 33
34#include <asm/hardware/clps7111.h> 34#include <asm/hardware/clps7111.h>
35#include <asm/arch/syspld.h> 35#include <asm/arch/syspld.h>
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index e58c87b3e3a0..0f32f4a00b2d 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -78,7 +78,6 @@
78#include <asm/fb.h> 78#include <asm/fb.h>
79#include <asm/irq.h> 79#include <asm/irq.h>
80#include <asm/system.h> 80#include <asm/system.h>
81#include <asm/uaccess.h>
82#ifdef CONFIG_ATARI 81#ifdef CONFIG_ATARI
83#include <asm/atariints.h> 82#include <asm/atariints.h>
84#endif 83#endif
@@ -2169,7 +2168,7 @@ static __inline__ void updatescrollmode(struct display *p,
2169} 2168}
2170 2169
2171static int fbcon_resize(struct vc_data *vc, unsigned int width, 2170static int fbcon_resize(struct vc_data *vc, unsigned int width,
2172 unsigned int height) 2171 unsigned int height, unsigned int user)
2173{ 2172{
2174 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2173 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2175 struct fbcon_ops *ops = info->fbcon_par; 2174 struct fbcon_ops *ops = info->fbcon_par;
@@ -2406,7 +2405,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
2406 update_screen(vc); 2405 update_screen(vc);
2407 } 2406 }
2408 2407
2409 if (fbcon_is_inactive(vc, info) || 2408 if (mode_switch || fbcon_is_inactive(vc, info) ||
2410 ops->blank_state != FB_BLANK_UNBLANK) 2409 ops->blank_state != FB_BLANK_UNBLANK)
2411 fbcon_del_cursor_timer(info); 2410 fbcon_del_cursor_timer(info);
2412 else 2411 else
diff --git a/drivers/video/console/font_10x18.c b/drivers/video/console/font_10x18.c
index e6aa0eab5bb6..6be72bb218ee 100644
--- a/drivers/video/console/font_10x18.c
+++ b/drivers/video/console/font_10x18.c
@@ -5133,14 +5133,14 @@ static const unsigned char fontdata_10x18[FONTDATAMAX] = {
5133 5133
5134 5134
5135const struct font_desc font_10x18 = { 5135const struct font_desc font_10x18 = {
5136 FONT10x18_IDX, 5136 .idx = FONT10x18_IDX,
5137 "10x18", 5137 .name = "10x18",
5138 10, 5138 .width = 10,
5139 18, 5139 .height = 18,
5140 fontdata_10x18, 5140 .data = fontdata_10x18,
5141#ifdef __sparc__ 5141#ifdef __sparc__
5142 5 5142 .pref = 5,
5143#else 5143#else
5144 -1 5144 .pref = -1,
5145#endif 5145#endif
5146}; 5146};
diff --git a/drivers/video/console/font_6x11.c b/drivers/video/console/font_6x11.c
index 89976cd97494..46e86e67aa6a 100644
--- a/drivers/video/console/font_6x11.c
+++ b/drivers/video/console/font_6x11.c
@@ -3342,10 +3342,11 @@ static const unsigned char fontdata_6x11[FONTDATAMAX] = {
3342 3342
3343 3343
3344const struct font_desc font_vga_6x11 = { 3344const struct font_desc font_vga_6x11 = {
3345 VGA6x11_IDX, 3345 .idx = VGA6x11_IDX,
3346 "ProFont6x11", 3346 .name = "ProFont6x11",
3347 6, 3347 .width = 6,
3348 11, 3348 .height = 11,
3349 fontdata_6x11, 3349 .data = fontdata_6x11,
3350 -2000 /* Try avoiding this font if possible unless on MAC */ 3350 /* Try avoiding this font if possible unless on MAC */
3351 .pref = -2000,
3351}; 3352};
diff --git a/drivers/video/console/font_7x14.c b/drivers/video/console/font_7x14.c
index bbf116647397..3b7dbf9c060b 100644
--- a/drivers/video/console/font_7x14.c
+++ b/drivers/video/console/font_7x14.c
@@ -4109,10 +4109,10 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
4109 4109
4110 4110
4111const struct font_desc font_7x14 = { 4111const struct font_desc font_7x14 = {
4112 FONT7x14_IDX, 4112 .idx = FONT7x14_IDX,
4113 "7x14", 4113 .name = "7x14",
4114 7, 4114 .width = 7,
4115 14, 4115 .height = 14,
4116 fontdata_7x14, 4116 .data = fontdata_7x14,
4117 0 4117 .pref = 0,
4118}; 4118};
diff --git a/drivers/video/console/font_8x16.c b/drivers/video/console/font_8x16.c
index 74fe86f28ff4..00a0c67a5c7d 100644
--- a/drivers/video/console/font_8x16.c
+++ b/drivers/video/console/font_8x16.c
@@ -5,6 +5,7 @@
5/**********************************************/ 5/**********************************************/
6 6
7#include <linux/font.h> 7#include <linux/font.h>
8#include <linux/module.h>
8 9
9#define FONTDATAMAX 4096 10#define FONTDATAMAX 4096
10 11
@@ -4622,10 +4623,11 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
4622 4623
4623 4624
4624const struct font_desc font_vga_8x16 = { 4625const struct font_desc font_vga_8x16 = {
4625 VGA8x16_IDX, 4626 .idx = VGA8x16_IDX,
4626 "VGA8x16", 4627 .name = "VGA8x16",
4627 8, 4628 .width = 8,
4628 16, 4629 .height = 16,
4629 fontdata_8x16, 4630 .data = fontdata_8x16,
4630 0 4631 .pref = 0,
4631}; 4632};
4633EXPORT_SYMBOL(font_vga_8x16);
diff --git a/drivers/video/console/font_8x8.c b/drivers/video/console/font_8x8.c
index 26199f8ee908..9f56efe2cee7 100644
--- a/drivers/video/console/font_8x8.c
+++ b/drivers/video/console/font_8x8.c
@@ -2574,10 +2574,10 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
2574 2574
2575 2575
2576const struct font_desc font_vga_8x8 = { 2576const struct font_desc font_vga_8x8 = {
2577 VGA8x8_IDX, 2577 .idx = VGA8x8_IDX,
2578 "VGA8x8", 2578 .name = "VGA8x8",
2579 8, 2579 .width = 8,
2580 8, 2580 .height = 8,
2581 fontdata_8x8, 2581 .data = fontdata_8x8,
2582 0 2582 .pref = 0,
2583}; 2583};
diff --git a/drivers/video/console/font_acorn_8x8.c b/drivers/video/console/font_acorn_8x8.c
index 40f3d4eeb198..639e31ae1100 100644
--- a/drivers/video/console/font_acorn_8x8.c
+++ b/drivers/video/console/font_acorn_8x8.c
@@ -262,14 +262,14 @@ static const unsigned char acorndata_8x8[] = {
262}; 262};
263 263
264const struct font_desc font_acorn_8x8 = { 264const struct font_desc font_acorn_8x8 = {
265 ACORN8x8_IDX, 265 .idx = ACORN8x8_IDX,
266 "Acorn8x8", 266 .name = "Acorn8x8",
267 8, 267 .width = 8,
268 8, 268 .height = 8,
269 acorndata_8x8, 269 .data = acorndata_8x8,
270#ifdef CONFIG_ARCH_ACORN 270#ifdef CONFIG_ARCH_ACORN
271 20 271 .pref = 20,
272#else 272#else
273 0 273 .pref = 0,
274#endif 274#endif
275}; 275};
diff --git a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
index d818234fdf11..a19a7f33133e 100644
--- a/drivers/video/console/font_mini_4x6.c
+++ b/drivers/video/console/font_mini_4x6.c
@@ -2148,11 +2148,11 @@ static const unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
2148}; 2148};
2149 2149
2150const struct font_desc font_mini_4x6 = { 2150const struct font_desc font_mini_4x6 = {
2151 MINI4x6_IDX, 2151 .idx = MINI4x6_IDX,
2152 "MINI4x6", 2152 .name = "MINI4x6",
2153 4, 2153 .width = 4,
2154 6, 2154 .height = 6,
2155 fontdata_mini_4x6, 2155 .data = fontdata_mini_4x6,
2156 3 2156 .pref = 3,
2157}; 2157};
2158 2158
diff --git a/drivers/video/console/font_pearl_8x8.c b/drivers/video/console/font_pearl_8x8.c
index e646c88f55c7..dc6ad539ca4e 100644
--- a/drivers/video/console/font_pearl_8x8.c
+++ b/drivers/video/console/font_pearl_8x8.c
@@ -2578,10 +2578,10 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
2578}; 2578};
2579 2579
2580const struct font_desc font_pearl_8x8 = { 2580const struct font_desc font_pearl_8x8 = {
2581 PEARL8x8_IDX, 2581 .idx = PEARL8x8_IDX,
2582 "PEARL8x8", 2582 .name = "PEARL8x8",
2583 8, 2583 .width = 8,
2584 8, 2584 .height = 8,
2585 fontdata_pearl8x8, 2585 .data = fontdata_pearl8x8,
2586 2 2586 .pref = 2,
2587}; 2587};
diff --git a/drivers/video/console/font_sun12x22.c b/drivers/video/console/font_sun12x22.c
index ab5eb93407b4..d3643853c33a 100644
--- a/drivers/video/console/font_sun12x22.c
+++ b/drivers/video/console/font_sun12x22.c
@@ -6152,14 +6152,14 @@ static const unsigned char fontdata_sun12x22[FONTDATAMAX] = {
6152 6152
6153 6153
6154const struct font_desc font_sun_12x22 = { 6154const struct font_desc font_sun_12x22 = {
6155 SUN12x22_IDX, 6155 .idx = SUN12x22_IDX,
6156 "SUN12x22", 6156 .name = "SUN12x22",
6157 12, 6157 .width = 12,
6158 22, 6158 .height = 22,
6159 fontdata_sun12x22, 6159 .data = fontdata_sun12x22,
6160#ifdef __sparc__ 6160#ifdef __sparc__
6161 5 6161 .pref = 5,
6162#else 6162#else
6163 -1 6163 .pref = -1,
6164#endif 6164#endif
6165}; 6165};
diff --git a/drivers/video/console/font_sun8x16.c b/drivers/video/console/font_sun8x16.c
index 41f910f5529c..5abf290c6eb7 100644
--- a/drivers/video/console/font_sun8x16.c
+++ b/drivers/video/console/font_sun8x16.c
@@ -262,14 +262,14 @@ static const unsigned char fontdata_sun8x16[FONTDATAMAX] = {
262}; 262};
263 263
264const struct font_desc font_sun_8x16 = { 264const struct font_desc font_sun_8x16 = {
265 SUN8x16_IDX, 265 .idx = SUN8x16_IDX,
266 "SUN8x16", 266 .name = "SUN8x16",
267 8, 267 .width = 8,
268 16, 268 .height = 16,
269 fontdata_sun8x16, 269 .data = fontdata_sun8x16,
270#ifdef __sparc__ 270#ifdef __sparc__
271 10 271 .pref = 10,
272#else 272#else
273 -1 273 .pref = -1,
274#endif 274#endif
275}; 275};
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index dda0586ab3f3..f57d7b2758b7 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -98,14 +98,19 @@ static inline void newport_init_cmap(void)
98 } 98 }
99} 99}
100 100
101static void newport_show_logo(void) 101static struct linux_logo *newport_show_logo(void)
102{ 102{
103#ifdef CONFIG_LOGO_SGI_CLUT224 103#ifdef CONFIG_LOGO_SGI_CLUT224
104 const struct linux_logo *logo = fb_find_logo(8); 104 const struct linux_logo *logo = fb_find_logo(8);
105 const unsigned char *clut = logo->clut; 105 const unsigned char *clut;
106 const unsigned char *data = logo->data; 106 const unsigned char *data;
107 unsigned long i; 107 unsigned long i;
108 108
109 if (!logo)
110 return NULL;
111 *clut = logo->clut;
112 *data = logo->data;
113
109 for (i = 0; i < logo->clutsize; i++) { 114 for (i = 0; i < logo->clutsize; i++) {
110 newport_bfwait(npregs); 115 newport_bfwait(npregs);
111 newport_cmap_setaddr(npregs, i + 0x20); 116 newport_cmap_setaddr(npregs, i + 0x20);
@@ -123,6 +128,8 @@ static void newport_show_logo(void)
123 128
124 for (i = 0; i < logo->width*logo->height; i++) 129 for (i = 0; i < logo->width*logo->height; i++)
125 npregs->go.hostrw0 = *data++ << 24; 130 npregs->go.hostrw0 = *data++ << 24;
131
132 return logo;
126#endif /* CONFIG_LOGO_SGI_CLUT224 */ 133#endif /* CONFIG_LOGO_SGI_CLUT224 */
127} 134}
128 135
@@ -465,9 +472,10 @@ static int newport_switch(struct vc_data *vc)
465 npregs->cset.topscan = 0x3ff; 472 npregs->cset.topscan = 0x3ff;
466 473
467 if (!logo_drawn) { 474 if (!logo_drawn) {
468 newport_show_logo(); 475 if (newport_show_logo()) {
469 logo_drawn = 1; 476 logo_drawn = 1;
470 logo_active = 1; 477 logo_active = 1;
478 }
471 } 479 }
472 480
473 return 1; 481 return 1;
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 03cfb7ac5733..25f835bf3d72 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -15,7 +15,6 @@
15#include <linux/fb.h> 15#include <linux/fb.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17 17
18#include <asm/uaccess.h>
19#include <asm/io.h> 18#include <asm/io.h>
20 19
21#include "fbcon.h" 20#include "fbcon.h"
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d18b73aafa0d..e9afb7ebd566 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1278,13 +1278,14 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font)
1278#endif 1278#endif
1279 1279
1280static int vgacon_resize(struct vc_data *c, unsigned int width, 1280static int vgacon_resize(struct vc_data *c, unsigned int width,
1281 unsigned int height) 1281 unsigned int height, unsigned int user)
1282{ 1282{
1283 if (width % 2 || width > ORIG_VIDEO_COLS || 1283 if (width % 2 || width > ORIG_VIDEO_COLS ||
1284 height > (ORIG_VIDEO_LINES * vga_default_font_height)/ 1284 height > (ORIG_VIDEO_LINES * vga_default_font_height)/
1285 c->vc_font.height) 1285 c->vc_font.height)
1286 /* let svgatextmode tinker with video timings */ 1286 /* let svgatextmode tinker with video timings and
1287 return 0; 1287 return success */
1288 return (user) ? 0 : -EINVAL;
1288 1289
1289 if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */ 1290 if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */
1290 vgacon_doresize(c, width, height); 1291 vgacon_doresize(c, width, height);
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 30ede6e8830f..9bb2cbfe4a3d 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -50,7 +50,6 @@
50#include <asm/io.h> 50#include <asm/io.h>
51#include <asm/pgtable.h> 51#include <asm/pgtable.h>
52#include <asm/system.h> 52#include <asm/system.h>
53#include <asm/uaccess.h>
54 53
55#ifdef __arm__ 54#ifdef __arm__
56#include <asm/mach-types.h> 55#include <asm/mach-types.h>
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 33be46ccb54f..cc2810ef5de5 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -57,7 +57,7 @@
57 57
58#include <asm/types.h> 58#include <asm/types.h>
59#include <asm/io.h> 59#include <asm/io.h>
60#include <asm/uaccess.h> 60#include <linux/uaccess.h>
61 61
62#include <video/epson1355.h> 62#include <video/epson1355.h>
63 63
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 1a8643f053d8..a0c5d9d90d74 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -19,7 +19,6 @@
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/fb.h> 20#include <linux/fb.h>
21#include <linux/list.h> 21#include <linux/list.h>
22#include <asm/uaccess.h>
23 22
24/* to support deferred IO */ 23/* to support deferred IO */
25#include <linux/rmap.h> 24#include <linux/rmap.h>
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h
index c5c45203833b..cdafbe14ef1f 100644
--- a/drivers/video/fb_draw.h
+++ b/drivers/video/fb_draw.h
@@ -2,6 +2,7 @@
2#define _FB_DRAW_H 2#define _FB_DRAW_H
3 3
4#include <asm/types.h> 4#include <asm/types.h>
5#include <linux/fb.h>
5 6
6 /* 7 /*
7 * Compose two values, using a bitmask as decision value 8 * Compose two values, using a bitmask as decision value
@@ -69,4 +70,97 @@ pixel_to_pat( u32 bpp, u32 pixel)
69 } 70 }
70} 71}
71#endif 72#endif
73
74#ifdef CONFIG_FB_CFB_REV_PIXELS_IN_BYTE
75#if BITS_PER_LONG == 64
76#define REV_PIXELS_MASK1 0x5555555555555555ul
77#define REV_PIXELS_MASK2 0x3333333333333333ul
78#define REV_PIXELS_MASK4 0x0f0f0f0f0f0f0f0ful
79#else
80#define REV_PIXELS_MASK1 0x55555555ul
81#define REV_PIXELS_MASK2 0x33333333ul
82#define REV_PIXELS_MASK4 0x0f0f0f0ful
83#endif
84
85static inline unsigned long fb_rev_pixels_in_long(unsigned long val,
86 u32 bswapmask)
87{
88 if (bswapmask & 1)
89 val = comp(val >> 1, val << 1, REV_PIXELS_MASK1);
90 if (bswapmask & 2)
91 val = comp(val >> 2, val << 2, REV_PIXELS_MASK2);
92 if (bswapmask & 3)
93 val = comp(val >> 4, val << 4, REV_PIXELS_MASK4);
94}
95
96static inline u32 fb_shifted_pixels_mask_u32(u32 index, u32 bswapmask)
97{
98 u32 mask;
99
100 if (!bswapmask) {
101 mask = FB_SHIFT_HIGH(~(u32)0, index);
102 } else {
103 mask = 0xff << FB_LEFT_POS(8);
104 mask = FB_SHIFT_LOW(mask, index & (bswapmask)) & mask;
105 mask = FB_SHIFT_HIGH(mask, index & ~(bswapmask));
106#if defined(__i386__) || defined(__x86_64__)
107 /* Shift argument is limited to 0 - 31 on x86 based CPU's */
108 if(index + bswapmask < 32)
109#endif
110 mask |= FB_SHIFT_HIGH(~(u32)0,
111 (index + bswapmask) & ~(bswapmask));
112 }
113 return mask;
114}
115
116static inline unsigned long fb_shifted_pixels_mask_long(u32 index, u32 bswapmask)
117{
118 unsigned long mask;
119
120 if (!bswapmask) {
121 mask = FB_SHIFT_HIGH(~0UL, index);
122 } else {
123 mask = 0xff << FB_LEFT_POS(8);
124 mask = FB_SHIFT_LOW(mask, index & (bswapmask)) & mask;
125 mask = FB_SHIFT_HIGH(mask, index & ~(bswapmask));
126#if defined(__i386__) || defined(__x86_64__)
127 /* Shift argument is limited to 0 - 31 on x86 based CPU's */
128 if(index + bswapmask < BITS_PER_LONG)
129#endif
130 mask |= FB_SHIFT_HIGH(~0UL,
131 (index + bswapmask) & ~(bswapmask));
132 }
133 return mask;
134}
135
136
137static inline u32 fb_compute_bswapmask(struct fb_info *info)
138{
139 u32 bswapmask = 0;
140 unsigned bpp = info->var.bits_per_pixel;
141
142 if ((bpp < 8) && (info->var.nonstd & FB_NONSTD_REV_PIX_IN_B)) {
143 /*
144 * Reversed order of pixel layout in bytes
145 * works only for 1, 2 and 4 bpp
146 */
147 bswapmask = 7 - bpp + 1;
148 }
149 return bswapmask;
150}
151
152#else /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
153
154static inline unsigned long fb_rev_pixels_in_long(unsigned long val,
155 u32 bswapmask)
156{
157 return val;
158}
159
160#define fb_shifted_pixels_mask_u32(i, b) FB_SHIFT_HIGH(~(u32)0, (i))
161#define fb_shifted_pixels_mask_long(i, b) FB_SHIFT_HIGH(~0UL, (i))
162#define fb_compute_bswapmask(...) 0
163
164#endif /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
165
72#endif /* FB_DRAW_H */ 166#endif /* FB_DRAW_H */
diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fb_sys_fops.c
index cf2538d669cd..ff275d7f3eaf 100644
--- a/drivers/video/fb_sys_fops.c
+++ b/drivers/video/fb_sys_fops.c
@@ -11,7 +11,7 @@
11 */ 11 */
12#include <linux/fb.h> 12#include <linux/fb.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <asm/uaccess.h> 14#include <linux/uaccess.h>
15 15
16ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count, 16ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
17 loff_t *ppos) 17 loff_t *ppos)
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 148108afdd51..91b78e691505 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -15,8 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/fb.h> 16#include <linux/fb.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18 18#include <linux/uaccess.h>
19#include <asm/uaccess.h>
20 19
21static u16 red2[] __read_mostly = { 20static u16 red2[] __read_mostly = {
22 0x0000, 0xaaaa 21 0x0000, 0xaaaa
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 074027204702..1194f5e060ea 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1567,8 +1567,6 @@ int fb_new_modelist(struct fb_info *info)
1567static char *video_options[FB_MAX] __read_mostly; 1567static char *video_options[FB_MAX] __read_mostly;
1568static int ofonly __read_mostly; 1568static int ofonly __read_mostly;
1569 1569
1570extern const char *global_mode_option;
1571
1572/** 1570/**
1573 * fb_get_options - get kernel boot parameters 1571 * fb_get_options - get kernel boot parameters
1574 * @name: framebuffer name as it would appear in 1572 * @name: framebuffer name as it would appear in
@@ -1636,7 +1634,7 @@ static int __init video_setup(char *options)
1636 } 1634 }
1637 1635
1638 if (!global && !strstr(options, "fb:")) { 1636 if (!global && !strstr(options, "fb:")) {
1639 global_mode_option = options; 1637 fb_mode_option = options;
1640 global = 1; 1638 global = 1;
1641 } 1639 }
1642 1640
@@ -1663,7 +1661,6 @@ EXPORT_SYMBOL(register_framebuffer);
1663EXPORT_SYMBOL(unregister_framebuffer); 1661EXPORT_SYMBOL(unregister_framebuffer);
1664EXPORT_SYMBOL(num_registered_fb); 1662EXPORT_SYMBOL(num_registered_fb);
1665EXPORT_SYMBOL(registered_fb); 1663EXPORT_SYMBOL(registered_fb);
1666EXPORT_SYMBOL(fb_prepare_logo);
1667EXPORT_SYMBOL(fb_show_logo); 1664EXPORT_SYMBOL(fb_show_logo);
1668EXPORT_SYMBOL(fb_set_var); 1665EXPORT_SYMBOL(fb_set_var);
1669EXPORT_SYMBOL(fb_blank); 1666EXPORT_SYMBOL(fb_blank);
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 438b9411905c..4ba9c0894416 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -591,7 +591,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
591{ 591{
592 struct fb_videomode *mode, *m; 592 struct fb_videomode *mode, *m;
593 unsigned char *block; 593 unsigned char *block;
594 int num = 0, i; 594 int num = 0, i, first = 1;
595 595
596 mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); 596 mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
597 if (mode == NULL) 597 if (mode == NULL)
@@ -608,8 +608,6 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
608 DPRINTK(" Detailed Timings\n"); 608 DPRINTK(" Detailed Timings\n");
609 block = edid + DETAILED_TIMING_DESCRIPTIONS_START; 609 block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
610 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { 610 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
611 int first = 1;
612
613 if (!(block[0] == 0x00 && block[1] == 0x00)) { 611 if (!(block[0] == 0x00 && block[1] == 0x00)) {
614 get_detailed_timing(block, &mode[num]); 612 get_detailed_timing(block, &mode[num]);
615 if (first) { 613 if (first) {
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c
index 5e30b40c8c0f..583185fd7c94 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/geode/lxfb_core.c
@@ -566,12 +566,7 @@ static int __init lxfb_setup(char *options)
566 if (!options || !*options) 566 if (!options || !*options)
567 return 0; 567 return 0;
568 568
569 while (1) { 569 while ((opt = strsep(&options, ",")) != NULL) {
570 char *opt = strsep(&options, ",");
571
572 if (opt == NULL)
573 break;
574
575 if (!*opt) 570 if (!*opt)
576 continue; 571 continue;
577 572
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index abfcb50364c8..94e0df8a6f60 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -45,7 +45,7 @@
45#include <linux/init.h> 45#include <linux/init.h>
46#include <linux/platform_device.h> 46#include <linux/platform_device.h>
47#include <linux/list.h> 47#include <linux/list.h>
48#include <asm/uaccess.h> 48#include <linux/uaccess.h>
49 49
50/* Apollo controller specific defines */ 50/* Apollo controller specific defines */
51#define APOLLO_START_NEW_IMG 0xA0 51#define APOLLO_START_NEW_IMG 0xA0
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 94f4511023d8..3ab91bf21576 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -29,7 +29,7 @@
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <asm/io.h> 31#include <asm/io.h>
32#include <asm/uaccess.h> 32#include <linux/uaccess.h>
33 33
34#if defined(CONFIG_PPC) 34#if defined(CONFIG_PPC)
35#include <linux/nvram.h> 35#include <linux/nvram.h>
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index a12589898597..11609552a387 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -34,7 +34,6 @@
34 34
35#include <asm/hardware.h> 35#include <asm/hardware.h>
36#include <asm/io.h> 36#include <asm/io.h>
37#include <asm/uaccess.h>
38#include <asm/arch/imxfb.h> 37#include <asm/arch/imxfb.h>
39 38
40/* 39/*
@@ -467,7 +466,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
467 info->var.vmode = FB_VMODE_NONINTERLACED; 466 info->var.vmode = FB_VMODE_NONINTERLACED;
468 467
469 info->fbops = &imxfb_ops; 468 info->fbops = &imxfb_ops;
470 info->flags = FBINFO_FLAG_DEFAULT; 469 info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
471 470
472 fbi->rgb[RGB_16] = &def_rgb_16; 471 fbi->rgb[RGB_16] = &def_rgb_16;
473 fbi->rgb[RGB_8] = &def_rgb_8; 472 fbi->rgb[RGB_8] = &def_rgb_8;
@@ -480,6 +479,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
480 info->var.yres_virtual = inf->yres; 479 info->var.yres_virtual = inf->yres;
481 fbi->max_bpp = inf->bpp; 480 fbi->max_bpp = inf->bpp;
482 info->var.bits_per_pixel = inf->bpp; 481 info->var.bits_per_pixel = inf->bpp;
482 info->var.nonstd = inf->nonstd;
483 info->var.pixclock = inf->pixclock; 483 info->var.pixclock = inf->pixclock;
484 info->var.hsync_len = inf->hsync_len; 484 info->var.hsync_len = inf->hsync_len;
485 info->var.left_margin = inf->left_margin; 485 info->var.left_margin = inf->left_margin;
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 6148300fadd6..2fe3f7def530 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -231,8 +231,8 @@ struct intelfb_hwstate {
231struct intelfb_heap_data { 231struct intelfb_heap_data {
232 u32 physical; 232 u32 physical;
233 u8 __iomem *virtual; 233 u8 __iomem *virtual;
234 u32 offset; // in GATT pages 234 u32 offset; /* in GATT pages */
235 u32 size; // in bytes 235 u32 size; /* in bytes */
236}; 236};
237 237
238#ifdef CONFIG_FB_INTEL_I2C 238#ifdef CONFIG_FB_INTEL_I2C
@@ -270,9 +270,9 @@ struct intelfb_info {
270 struct intelfb_hwstate save_state; 270 struct intelfb_hwstate save_state;
271 271
272 /* agpgart structs */ 272 /* agpgart structs */
273 struct agp_memory *gtt_fb_mem; // use all stolen memory or vram 273 struct agp_memory *gtt_fb_mem; /* use all stolen memory or vram */
274 struct agp_memory *gtt_ring_mem; // ring buffer 274 struct agp_memory *gtt_ring_mem; /* ring buffer */
275 struct agp_memory *gtt_cursor_mem; // hw cursor 275 struct agp_memory *gtt_cursor_mem; /* hw cursor */
276 276
277 /* use a gart reserved fb mem */ 277 /* use a gart reserved fb mem */
278 u8 fbmem_gart; 278 u8 fbmem_gart;
@@ -346,7 +346,7 @@ struct intelfb_info {
346 346
347 /* driver registered */ 347 /* driver registered */
348 int registered; 348 int registered;
349 349
350 /* index into plls */ 350 /* index into plls */
351 int pll_index; 351 int pll_index;
352 352
@@ -355,7 +355,10 @@ struct intelfb_info {
355 struct intelfb_output_rec output[MAX_OUTPUTS]; 355 struct intelfb_output_rec output[MAX_OUTPUTS];
356}; 356};
357 357
358#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM)) 358#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G) || \
359 ((dinfo)->chipset == INTEL_915GM) || \
360 ((dinfo)->chipset == INTEL_945G) || \
361 ((dinfo)->chipset==INTEL_945GM))
359 362
360#ifndef FBIO_WAITFORVSYNC 363#ifndef FBIO_WAITFORVSYNC
361#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) 364#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
index 61e4c8759b23..94c08bb5acf1 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -58,7 +58,8 @@ static void intelfb_gpio_setscl(void *data, int state)
58 struct intelfb_info *dinfo = chan->dinfo; 58 struct intelfb_info *dinfo = chan->dinfo;
59 u32 val; 59 u32 val;
60 60
61 OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK); 61 OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) |
62 SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK);
62 val = INREG(chan->reg); 63 val = INREG(chan->reg);
63} 64}
64 65
@@ -68,7 +69,8 @@ static void intelfb_gpio_setsda(void *data, int state)
68 struct intelfb_info *dinfo = chan->dinfo; 69 struct intelfb_info *dinfo = chan->dinfo;
69 u32 val; 70 u32 val;
70 71
71 OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK); 72 OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) |
73 SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK);
72 val = INREG(chan->reg); 74 val = INREG(chan->reg);
73} 75}
74 76
@@ -97,26 +99,26 @@ static int intelfb_gpio_getsda(void *data)
97} 99}
98 100
99static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo, 101static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
100 struct intelfb_i2c_chan *chan, 102 struct intelfb_i2c_chan *chan,
101 const u32 reg, const char *name) 103 const u32 reg, const char *name)
102{ 104{
103 int rc; 105 int rc;
104 106
105 chan->dinfo = dinfo; 107 chan->dinfo = dinfo;
106 chan->reg = reg; 108 chan->reg = reg;
107 snprintf(chan->adapter.name, sizeof(chan->adapter.name), 109 snprintf(chan->adapter.name, sizeof(chan->adapter.name),
108 "intelfb %s", name); 110 "intelfb %s", name);
109 chan->adapter.owner = THIS_MODULE; 111 chan->adapter.owner = THIS_MODULE;
110 chan->adapter.id = I2C_HW_B_INTELFB; 112 chan->adapter.id = I2C_HW_B_INTELFB;
111 chan->adapter.algo_data = &chan->algo; 113 chan->adapter.algo_data = &chan->algo;
112 chan->adapter.dev.parent = &chan->dinfo->pdev->dev; 114 chan->adapter.dev.parent = &chan->dinfo->pdev->dev;
113 chan->algo.setsda = intelfb_gpio_setsda; 115 chan->algo.setsda = intelfb_gpio_setsda;
114 chan->algo.setscl = intelfb_gpio_setscl; 116 chan->algo.setscl = intelfb_gpio_setscl;
115 chan->algo.getsda = intelfb_gpio_getsda; 117 chan->algo.getsda = intelfb_gpio_getsda;
116 chan->algo.getscl = intelfb_gpio_getscl; 118 chan->algo.getscl = intelfb_gpio_getscl;
117 chan->algo.udelay = 40; 119 chan->algo.udelay = 40;
118 chan->algo.timeout = 20; 120 chan->algo.timeout = 20;
119 chan->algo.data = chan; 121 chan->algo.data = chan;
120 122
121 i2c_set_adapdata(&chan->adapter, chan); 123 i2c_set_adapdata(&chan->adapter, chan);
122 124
@@ -142,40 +144,44 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
142 dinfo->output[i].type = INTELFB_OUTPUT_ANALOG; 144 dinfo->output[i].type = INTELFB_OUTPUT_ANALOG;
143 145
144 /* setup the DDC bus for analog output */ 146 /* setup the DDC bus for analog output */
145 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA, "CRTDDC_A"); 147 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA,
148 "CRTDDC_A");
146 i++; 149 i++;
147 150
148 /* need to add the output busses for each device 151 /* need to add the output busses for each device
149 - this function is very incomplete 152 - this function is very incomplete
150 - i915GM has LVDS and TVOUT for example 153 - i915GM has LVDS and TVOUT for example
151 */ 154 */
152 switch(dinfo->chipset) { 155 switch(dinfo->chipset) {
153 case INTEL_830M: 156 case INTEL_830M:
154 case INTEL_845G: 157 case INTEL_845G:
155 case INTEL_855GM: 158 case INTEL_855GM:
156 case INTEL_865G: 159 case INTEL_865G:
157 dinfo->output[i].type = INTELFB_OUTPUT_DVO; 160 dinfo->output[i].type = INTELFB_OUTPUT_DVO;
158 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOD, "DVODDC_D"); 161 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus,
159 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "DVOI2C_E"); 162 GPIOD, "DVODDC_D");
163 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus,
164 GPIOE, "DVOI2C_E");
160 i++; 165 i++;
161 break; 166 break;
162 case INTEL_915G: 167 case INTEL_915G:
163 case INTEL_915GM: 168 case INTEL_915GM:
164 /* has some LVDS + tv-out */ 169 /* has some LVDS + tv-out */
165 case INTEL_945G: 170 case INTEL_945G:
166 case INTEL_945GM: 171 case INTEL_945GM:
167 /* SDVO ports have a single control bus - 2 devices */ 172 /* SDVO ports have a single control bus - 2 devices */
168 dinfo->output[i].type = INTELFB_OUTPUT_SDVO; 173 dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
169 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "SDVOCTRL_E"); 174 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus,
175 GPIOE, "SDVOCTRL_E");
170 /* TODO: initialize the SDVO */ 176 /* TODO: initialize the SDVO */
171// I830SDVOInit(pScrn, i, DVOB); 177 /* I830SDVOInit(pScrn, i, DVOB); */
172 i++; 178 i++;
173 179
174 /* set up SDVOC */ 180 /* set up SDVOC */
175 dinfo->output[i].type = INTELFB_OUTPUT_SDVO; 181 dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
176 dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus; 182 dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus;
177 /* TODO: initialize the SDVO */ 183 /* TODO: initialize the SDVO */
178// I830SDVOInit(pScrn, i, DVOC); 184 /* I830SDVOInit(pScrn, i, DVOC); */
179 i++; 185 i++;
180 break; 186 break;
181 } 187 }
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index b75eda84858f..0428f211f192 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -99,13 +99,6 @@
99 * Add vram option to reserve more memory than stolen by BIOS 99 * Add vram option to reserve more memory than stolen by BIOS
100 * Fix intelfbhw_pan_display typo 100 * Fix intelfbhw_pan_display typo
101 * Add __initdata annotations 101 * Add __initdata annotations
102 *
103 * TODO:
104 *
105 *
106 * Wish List:
107 *
108 *
109 */ 102 */
110 103
111#include <linux/module.h> 104#include <linux/module.h>
@@ -222,8 +215,8 @@ static struct pci_driver intelfb_driver = {
222/* Module description/parameters */ 215/* Module description/parameters */
223MODULE_AUTHOR("David Dawes <dawes@tungstengraphics.com>, " 216MODULE_AUTHOR("David Dawes <dawes@tungstengraphics.com>, "
224 "Sylvain Meyer <sylvain.meyer@worldonline.fr>"); 217 "Sylvain Meyer <sylvain.meyer@worldonline.fr>");
225MODULE_DESCRIPTION( 218MODULE_DESCRIPTION("Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS
226 "Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS " chipsets"); 219 " chipsets");
227MODULE_LICENSE("Dual BSD/GPL"); 220MODULE_LICENSE("Dual BSD/GPL");
228MODULE_DEVICE_TABLE(pci, intelfb_pci_table); 221MODULE_DEVICE_TABLE(pci, intelfb_pci_table);
229 222
@@ -271,8 +264,7 @@ MODULE_PARM_DESC(mode,
271#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0) 264#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0)
272#define OPT_STRVAL(opt, name) (opt + strlen(name)) 265#define OPT_STRVAL(opt, name) (opt + strlen(name))
273 266
274static __inline__ char * 267static __inline__ char * get_opt_string(const char *this_opt, const char *name)
275get_opt_string(const char *this_opt, const char *name)
276{ 268{
277 const char *p; 269 const char *p;
278 int i; 270 int i;
@@ -290,8 +282,8 @@ get_opt_string(const char *this_opt, const char *name)
290 return ret; 282 return ret;
291} 283}
292 284
293static __inline__ int 285static __inline__ int get_opt_int(const char *this_opt, const char *name,
294get_opt_int(const char *this_opt, const char *name, int *ret) 286 int *ret)
295{ 287{
296 if (!ret) 288 if (!ret)
297 return 0; 289 return 0;
@@ -303,8 +295,8 @@ get_opt_int(const char *this_opt, const char *name, int *ret)
303 return 1; 295 return 1;
304} 296}
305 297
306static __inline__ int 298static __inline__ int get_opt_bool(const char *this_opt, const char *name,
307get_opt_bool(const char *this_opt, const char *name, int *ret) 299 int *ret)
308{ 300{
309 if (!ret) 301 if (!ret)
310 return 0; 302 return 0;
@@ -324,8 +316,7 @@ get_opt_bool(const char *this_opt, const char *name, int *ret)
324 return 1; 316 return 1;
325} 317}
326 318
327static int __init 319static int __init intelfb_setup(char *options)
328intelfb_setup(char *options)
329{ 320{
330 char *this_opt; 321 char *this_opt;
331 322
@@ -355,7 +346,7 @@ intelfb_setup(char *options)
355 continue; 346 continue;
356 if (get_opt_bool(this_opt, "accel", &accel)) 347 if (get_opt_bool(this_opt, "accel", &accel))
357 ; 348 ;
358 else if (get_opt_int(this_opt, "vram", &vram)) 349 else if (get_opt_int(this_opt, "vram", &vram))
359 ; 350 ;
360 else if (get_opt_bool(this_opt, "hwcursor", &hwcursor)) 351 else if (get_opt_bool(this_opt, "hwcursor", &hwcursor))
361 ; 352 ;
@@ -376,8 +367,7 @@ intelfb_setup(char *options)
376 367
377#endif 368#endif
378 369
379static int __init 370static int __init intelfb_init(void)
380intelfb_init(void)
381{ 371{
382#ifndef MODULE 372#ifndef MODULE
383 char *option = NULL; 373 char *option = NULL;
@@ -401,8 +391,7 @@ intelfb_init(void)
401 return pci_register_driver(&intelfb_driver); 391 return pci_register_driver(&intelfb_driver);
402} 392}
403 393
404static void __exit 394static void __exit intelfb_exit(void)
405intelfb_exit(void)
406{ 395{
407 DBG_MSG("intelfb_exit\n"); 396 DBG_MSG("intelfb_exit\n");
408 pci_unregister_driver(&intelfb_driver); 397 pci_unregister_driver(&intelfb_driver);
@@ -428,8 +417,8 @@ static inline void __devinit set_mtrr(struct intelfb_info *dinfo)
428} 417}
429static inline void unset_mtrr(struct intelfb_info *dinfo) 418static inline void unset_mtrr(struct intelfb_info *dinfo)
430{ 419{
431 if (dinfo->has_mtrr) 420 if (dinfo->has_mtrr)
432 mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical, 421 mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical,
433 dinfo->aperture.size); 422 dinfo->aperture.size);
434} 423}
435#else 424#else
@@ -442,8 +431,7 @@ static inline void unset_mtrr(struct intelfb_info *dinfo)
442 * driver init / cleanup * 431 * driver init / cleanup *
443 ***************************************************************/ 432 ***************************************************************/
444 433
445static void 434static void cleanup(struct intelfb_info *dinfo)
446cleanup(struct intelfb_info *dinfo)
447{ 435{
448 DBG_MSG("cleanup\n"); 436 DBG_MSG("cleanup\n");
449 437
@@ -499,8 +487,8 @@ cleanup(struct intelfb_info *dinfo)
499} while (0) 487} while (0)
500 488
501 489
502static int __devinit 490static int __devinit intelfb_pci_register(struct pci_dev *pdev,
503intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) 491 const struct pci_device_id *ent)
504{ 492{
505 struct fb_info *info; 493 struct fb_info *info;
506 struct intelfb_info *dinfo; 494 struct intelfb_info *dinfo;
@@ -510,8 +498,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
510 int agp_memtype; 498 int agp_memtype;
511 const char *s; 499 const char *s;
512 struct agp_bridge_data *bridge; 500 struct agp_bridge_data *bridge;
513 int aperture_bar = 0; 501 int aperture_bar = 0;
514 int mmio_bar = 1; 502 int mmio_bar = 1;
515 int offset; 503 int offset;
516 504
517 DBG_MSG("intelfb_pci_register\n"); 505 DBG_MSG("intelfb_pci_register\n");
@@ -637,9 +625,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
637 dinfo->ring.size = RINGBUFFER_SIZE; 625 dinfo->ring.size = RINGBUFFER_SIZE;
638 dinfo->ring_tail_mask = dinfo->ring.size - 1; 626 dinfo->ring_tail_mask = dinfo->ring.size - 1;
639 } 627 }
640 if (dinfo->hwcursor) { 628 if (dinfo->hwcursor)
641 dinfo->cursor.size = HW_CURSOR_SIZE; 629 dinfo->cursor.size = HW_CURSOR_SIZE;
642 }
643 630
644 /* Use agpgart to manage the GATT */ 631 /* Use agpgart to manage the GATT */
645 if (!(bridge = agp_backend_acquire(pdev))) { 632 if (!(bridge = agp_backend_acquire(pdev))) {
@@ -662,18 +649,15 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
662 offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE; 649 offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
663 650
664 /* set the mem offsets - set them after the already used pages */ 651 /* set the mem offsets - set them after the already used pages */
665 if (dinfo->accel) { 652 if (dinfo->accel)
666 dinfo->ring.offset = offset + gtt_info.current_memory; 653 dinfo->ring.offset = offset + gtt_info.current_memory;
667 } 654 if (dinfo->hwcursor)
668 if (dinfo->hwcursor) {
669 dinfo->cursor.offset = offset + 655 dinfo->cursor.offset = offset +
670 + gtt_info.current_memory + (dinfo->ring.size >> 12); 656 + gtt_info.current_memory + (dinfo->ring.size >> 12);
671 } 657 if (dinfo->fbmem_gart)
672 if (dinfo->fbmem_gart) {
673 dinfo->fb.offset = offset + 658 dinfo->fb.offset = offset +
674 + gtt_info.current_memory + (dinfo->ring.size >> 12) 659 + gtt_info.current_memory + (dinfo->ring.size >> 12)
675 + (dinfo->cursor.size >> 12); 660 + (dinfo->cursor.size >> 12);
676 }
677 661
678 /* Allocate memories (which aren't stolen) */ 662 /* Allocate memories (which aren't stolen) */
679 /* Map the fb and MMIO regions */ 663 /* Map the fb and MMIO regions */
@@ -689,7 +673,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
689 673
690 dinfo->mmio_base = 674 dinfo->mmio_base =
691 (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys, 675 (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys,
692 INTEL_REG_SIZE); 676 INTEL_REG_SIZE);
693 if (!dinfo->mmio_base) { 677 if (!dinfo->mmio_base) {
694 ERR_MSG("Cannot remap MMIO region.\n"); 678 ERR_MSG("Cannot remap MMIO region.\n");
695 cleanup(dinfo); 679 cleanup(dinfo);
@@ -837,10 +821,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
837 if (bailearly == 3) 821 if (bailearly == 3)
838 bailout(dinfo); 822 bailout(dinfo);
839 823
840 if (FIXED_MODE(dinfo)) { 824 if (FIXED_MODE(dinfo)) /* remap fb address */
841 /* remap fb address */
842 update_dinfo(dinfo, &dinfo->initial_var); 825 update_dinfo(dinfo, &dinfo->initial_var);
843 }
844 826
845 if (bailearly == 4) 827 if (bailearly == 4)
846 bailout(dinfo); 828 bailout(dinfo);
@@ -939,8 +921,7 @@ intelfb_pci_unregister(struct pci_dev *pdev)
939 * helper functions * 921 * helper functions *
940 ***************************************************************/ 922 ***************************************************************/
941 923
942int __inline__ 924int __inline__ intelfb_var_to_depth(const struct fb_var_screeninfo *var)
943intelfb_var_to_depth(const struct fb_var_screeninfo *var)
944{ 925{
945 DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n", 926 DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n",
946 var->bits_per_pixel, var->green.length); 927 var->bits_per_pixel, var->green.length);
@@ -956,8 +937,7 @@ intelfb_var_to_depth(const struct fb_var_screeninfo *var)
956} 937}
957 938
958 939
959static __inline__ int 940static __inline__ int var_to_refresh(const struct fb_var_screeninfo *var)
960var_to_refresh(const struct fb_var_screeninfo *var)
961{ 941{
962 int xtot = var->xres + var->left_margin + var->right_margin + 942 int xtot = var->xres + var->left_margin + var->right_margin +
963 var->hsync_len; 943 var->hsync_len;
@@ -971,8 +951,7 @@ var_to_refresh(const struct fb_var_screeninfo *var)
971 * Various intialisation functions * 951 * Various intialisation functions *
972 ***************************************************************/ 952 ***************************************************************/
973 953
974static void __devinit 954static void __devinit get_initial_mode(struct intelfb_info *dinfo)
975get_initial_mode(struct intelfb_info *dinfo)
976{ 955{
977 struct fb_var_screeninfo *var; 956 struct fb_var_screeninfo *var;
978 int xtot, ytot; 957 int xtot, ytot;
@@ -1039,8 +1018,7 @@ get_initial_mode(struct intelfb_info *dinfo)
1039 } 1018 }
1040} 1019}
1041 1020
1042static int __devinit 1021static int __devinit intelfb_init_var(struct intelfb_info *dinfo)
1043intelfb_init_var(struct intelfb_info *dinfo)
1044{ 1022{
1045 struct fb_var_screeninfo *var; 1023 struct fb_var_screeninfo *var;
1046 int msrc = 0; 1024 int msrc = 0;
@@ -1087,10 +1065,9 @@ intelfb_init_var(struct intelfb_info *dinfo)
1087 1065
1088 } 1066 }
1089 1067
1090 if (!msrc) { 1068 if (!msrc)
1091 msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE, 1069 msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE,
1092 NULL, 0, NULL, 0); 1070 NULL, 0, NULL, 0);
1093 }
1094 } 1071 }
1095 1072
1096 if (!msrc) { 1073 if (!msrc) {
@@ -1122,8 +1099,7 @@ intelfb_init_var(struct intelfb_info *dinfo)
1122 return 0; 1099 return 0;
1123} 1100}
1124 1101
1125static int __devinit 1102static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo)
1126intelfb_set_fbinfo(struct intelfb_info *dinfo)
1127{ 1103{
1128 struct fb_info *info = dinfo->info; 1104 struct fb_info *info = dinfo->info;
1129 1105
@@ -1159,8 +1135,8 @@ intelfb_set_fbinfo(struct intelfb_info *dinfo)
1159} 1135}
1160 1136
1161/* Update dinfo to match the active video mode. */ 1137/* Update dinfo to match the active video mode. */
1162static void 1138static void update_dinfo(struct intelfb_info *dinfo,
1163update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var) 1139 struct fb_var_screeninfo *var)
1164{ 1140{
1165 DBG_MSG("update_dinfo\n"); 1141 DBG_MSG("update_dinfo\n");
1166 1142
@@ -1208,36 +1184,32 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
1208 * fbdev interface * 1184 * fbdev interface *
1209 ***************************************************************/ 1185 ***************************************************************/
1210 1186
1211static int 1187static int intelfb_open(struct fb_info *info, int user)
1212intelfb_open(struct fb_info *info, int user)
1213{ 1188{
1214 struct intelfb_info *dinfo = GET_DINFO(info); 1189 struct intelfb_info *dinfo = GET_DINFO(info);
1215 1190
1216 if (user) { 1191 if (user)
1217 dinfo->open++; 1192 dinfo->open++;
1218 }
1219 1193
1220 return 0; 1194 return 0;
1221} 1195}
1222 1196
1223static int 1197static int intelfb_release(struct fb_info *info, int user)
1224intelfb_release(struct fb_info *info, int user)
1225{ 1198{
1226 struct intelfb_info *dinfo = GET_DINFO(info); 1199 struct intelfb_info *dinfo = GET_DINFO(info);
1227 1200
1228 if (user) { 1201 if (user) {
1229 dinfo->open--; 1202 dinfo->open--;
1230 msleep(1); 1203 msleep(1);
1231 if (!dinfo->open) { 1204 if (!dinfo->open)
1232 intelfbhw_disable_irq(dinfo); 1205 intelfbhw_disable_irq(dinfo);
1233 }
1234 } 1206 }
1235 1207
1236 return 0; 1208 return 0;
1237} 1209}
1238 1210
1239static int 1211static int intelfb_check_var(struct fb_var_screeninfo *var,
1240intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 1212 struct fb_info *info)
1241{ 1213{
1242 int change_var = 0; 1214 int change_var = 0;
1243 struct fb_var_screeninfo v; 1215 struct fb_var_screeninfo v;
@@ -1271,15 +1243,15 @@ intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1271 } 1243 }
1272 1244
1273 /* Check for a supported bpp. */ 1245 /* Check for a supported bpp. */
1274 if (v.bits_per_pixel <= 8) { 1246 if (v.bits_per_pixel <= 8)
1275 v.bits_per_pixel = 8; 1247 v.bits_per_pixel = 8;
1276 } else if (v.bits_per_pixel <= 16) { 1248 else if (v.bits_per_pixel <= 16) {
1277 if (v.bits_per_pixel == 16) 1249 if (v.bits_per_pixel == 16)
1278 v.green.length = 6; 1250 v.green.length = 6;
1279 v.bits_per_pixel = 16; 1251 v.bits_per_pixel = 16;
1280 } else if (v.bits_per_pixel <= 32) { 1252 } else if (v.bits_per_pixel <= 32)
1281 v.bits_per_pixel = 32; 1253 v.bits_per_pixel = 32;
1282 } else 1254 else
1283 return -EINVAL; 1255 return -EINVAL;
1284 1256
1285 change_var = ((info->var.xres != var->xres) || 1257 change_var = ((info->var.xres != var->xres) ||
@@ -1361,10 +1333,9 @@ intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1361 return 0; 1333 return 0;
1362} 1334}
1363 1335
1364static int 1336static int intelfb_set_par(struct fb_info *info)
1365intelfb_set_par(struct fb_info *info)
1366{ 1337{
1367 struct intelfb_hwstate *hw; 1338 struct intelfb_hwstate *hw;
1368 struct intelfb_info *dinfo = GET_DINFO(info); 1339 struct intelfb_info *dinfo = GET_DINFO(info);
1369 1340
1370 if (FIXED_MODE(dinfo)) { 1341 if (FIXED_MODE(dinfo)) {
@@ -1372,9 +1343,9 @@ intelfb_set_par(struct fb_info *info)
1372 return -EINVAL; 1343 return -EINVAL;
1373 } 1344 }
1374 1345
1375 hw = kmalloc(sizeof(*hw), GFP_ATOMIC); 1346 hw = kmalloc(sizeof(*hw), GFP_ATOMIC);
1376 if (!hw) 1347 if (!hw)
1377 return -ENOMEM; 1348 return -ENOMEM;
1378 1349
1379 DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres, 1350 DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres,
1380 info->var.yres, info->var.bits_per_pixel); 1351 info->var.yres, info->var.bits_per_pixel);
@@ -1384,15 +1355,15 @@ intelfb_set_par(struct fb_info *info)
1384 if (ACCEL(dinfo, info)) 1355 if (ACCEL(dinfo, info))
1385 intelfbhw_2d_stop(dinfo); 1356 intelfbhw_2d_stop(dinfo);
1386 1357
1387 memcpy(hw, &dinfo->save_state, sizeof(*hw)); 1358 memcpy(hw, &dinfo->save_state, sizeof(*hw));
1388 if (intelfbhw_mode_to_hw(dinfo, hw, &info->var)) 1359 if (intelfbhw_mode_to_hw(dinfo, hw, &info->var))
1389 goto invalid_mode; 1360 goto invalid_mode;
1390 if (intelfbhw_program_mode(dinfo, hw, 0)) 1361 if (intelfbhw_program_mode(dinfo, hw, 0))
1391 goto invalid_mode; 1362 goto invalid_mode;
1392 1363
1393#if REGDUMP > 0 1364#if REGDUMP > 0
1394 intelfbhw_read_hw_state(dinfo, hw, 0); 1365 intelfbhw_read_hw_state(dinfo, hw, 0);
1395 intelfbhw_print_hw_state(dinfo, hw); 1366 intelfbhw_print_hw_state(dinfo, hw);
1396#endif 1367#endif
1397 1368
1398 update_dinfo(dinfo, &info->var); 1369 update_dinfo(dinfo, &info->var);
@@ -1408,9 +1379,9 @@ intelfb_set_par(struct fb_info *info)
1408 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | 1379 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
1409 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | 1380 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
1410 FBINFO_HWACCEL_IMAGEBLIT; 1381 FBINFO_HWACCEL_IMAGEBLIT;
1411 } else { 1382 } else
1412 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1383 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1413 } 1384
1414 kfree(hw); 1385 kfree(hw);
1415 return 0; 1386 return 0;
1416invalid_mode: 1387invalid_mode:
@@ -1418,9 +1389,9 @@ invalid_mode:
1418 return -EINVAL; 1389 return -EINVAL;
1419} 1390}
1420 1391
1421static int 1392static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1422intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, 1393 unsigned blue, unsigned transp,
1423 unsigned blue, unsigned transp, struct fb_info *info) 1394 struct fb_info *info)
1424{ 1395{
1425 struct intelfb_info *dinfo = GET_DINFO(info); 1396 struct intelfb_info *dinfo = GET_DINFO(info);
1426 1397
@@ -1463,23 +1434,22 @@ intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1463 return 0; 1434 return 0;
1464} 1435}
1465 1436
1466static int 1437static int intelfb_blank(int blank, struct fb_info *info)
1467intelfb_blank(int blank, struct fb_info *info)
1468{ 1438{
1469 intelfbhw_do_blank(blank, info); 1439 intelfbhw_do_blank(blank, info);
1470 return 0; 1440 return 0;
1471} 1441}
1472 1442
1473static int 1443static int intelfb_pan_display(struct fb_var_screeninfo *var,
1474intelfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 1444 struct fb_info *info)
1475{ 1445{
1476 intelfbhw_pan_display(var, info); 1446 intelfbhw_pan_display(var, info);
1477 return 0; 1447 return 0;
1478} 1448}
1479 1449
1480/* When/if we have our own ioctls. */ 1450/* When/if we have our own ioctls. */
1481static int 1451static int intelfb_ioctl(struct fb_info *info, unsigned int cmd,
1482intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 1452 unsigned long arg)
1483{ 1453{
1484 int retval = 0; 1454 int retval = 0;
1485 struct intelfb_info *dinfo = GET_DINFO(info); 1455 struct intelfb_info *dinfo = GET_DINFO(info);
@@ -1499,8 +1469,8 @@ intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
1499 return retval; 1469 return retval;
1500} 1470}
1501 1471
1502static void 1472static void intelfb_fillrect (struct fb_info *info,
1503intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect) 1473 const struct fb_fillrect *rect)
1504{ 1474{
1505 struct intelfb_info *dinfo = GET_DINFO(info); 1475 struct intelfb_info *dinfo = GET_DINFO(info);
1506 u32 rop, color; 1476 u32 rop, color;
@@ -1514,7 +1484,7 @@ intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect)
1514 1484
1515 if (rect->rop == ROP_COPY) 1485 if (rect->rop == ROP_COPY)
1516 rop = PAT_ROP_GXCOPY; 1486 rop = PAT_ROP_GXCOPY;
1517 else // ROP_XOR 1487 else /* ROP_XOR */
1518 rop = PAT_ROP_GXXOR; 1488 rop = PAT_ROP_GXXOR;
1519 1489
1520 if (dinfo->depth != 8) 1490 if (dinfo->depth != 8)
@@ -1528,8 +1498,8 @@ intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect)
1528 rop); 1498 rop);
1529} 1499}
1530 1500
1531static void 1501static void intelfb_copyarea(struct fb_info *info,
1532intelfb_copyarea(struct fb_info *info, const struct fb_copyarea *region) 1502 const struct fb_copyarea *region)
1533{ 1503{
1534 struct intelfb_info *dinfo = GET_DINFO(info); 1504 struct intelfb_info *dinfo = GET_DINFO(info);
1535 1505
@@ -1545,8 +1515,8 @@ intelfb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1545 dinfo->pitch, info->var.bits_per_pixel); 1515 dinfo->pitch, info->var.bits_per_pixel);
1546} 1516}
1547 1517
1548static void 1518static void intelfb_imageblit(struct fb_info *info,
1549intelfb_imageblit(struct fb_info *info, const struct fb_image *image) 1519 const struct fb_image *image)
1550{ 1520{
1551 struct intelfb_info *dinfo = GET_DINFO(info); 1521 struct intelfb_info *dinfo = GET_DINFO(info);
1552 u32 fgcolor, bgcolor; 1522 u32 fgcolor, bgcolor;
@@ -1574,8 +1544,7 @@ intelfb_imageblit(struct fb_info *info, const struct fb_image *image)
1574 return cfb_imageblit(info, image); 1544 return cfb_imageblit(info, image);
1575} 1545}
1576 1546
1577static int 1547static int intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1578intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1579{ 1548{
1580 struct intelfb_info *dinfo = GET_DINFO(info); 1549 struct intelfb_info *dinfo = GET_DINFO(info);
1581 u32 physical; 1550 u32 physical;
@@ -1689,8 +1658,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1689 return 0; 1658 return 0;
1690} 1659}
1691 1660
1692static int 1661static int intelfb_sync(struct fb_info *info)
1693intelfb_sync(struct fb_info *info)
1694{ 1662{
1695 struct intelfb_info *dinfo = GET_DINFO(info); 1663 struct intelfb_info *dinfo = GET_DINFO(info);
1696 1664
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 6a47682d8614..2a0e32074f7d 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -56,17 +56,16 @@ static struct pll_min_max plls[PLLS_MAX] = {
56 6, 16, 3, 16, 56 6, 16, 3, 16,
57 4, 128, 0, 31, 57 4, 128, 0, 31,
58 930000, 1400000, 165000, 48000, 58 930000, 1400000, 165000, 48000,
59 4, 2 }, //I8xx 59 4, 2 }, /* I8xx */
60 60
61 { 75, 120, 10, 20, 61 { 75, 120, 10, 20,
62 5, 9, 4, 7, 62 5, 9, 4, 7,
63 5, 80, 1, 8, 63 5, 80, 1, 8,
64 1400000, 2800000, 200000, 96000, 64 1400000, 2800000, 200000, 96000,
65 10, 5 } //I9xx 65 10, 5 } /* I9xx */
66}; 66};
67 67
68int 68int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
69intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
70{ 69{
71 u32 tmp; 70 u32 tmp;
72 if (!pdev || !dinfo) 71 if (!pdev || !dinfo)
@@ -149,9 +148,8 @@ intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
149 } 148 }
150} 149}
151 150
152int 151int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
153intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, 152 int *stolen_size)
154 int *stolen_size)
155{ 153{
156 struct pci_dev *bridge_dev; 154 struct pci_dev *bridge_dev;
157 u16 tmp; 155 u16 tmp;
@@ -254,8 +252,7 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
254 } 252 }
255} 253}
256 254
257int 255int intelfbhw_check_non_crt(struct intelfb_info *dinfo)
258intelfbhw_check_non_crt(struct intelfb_info *dinfo)
259{ 256{
260 int dvo = 0; 257 int dvo = 0;
261 258
@@ -271,8 +268,7 @@ intelfbhw_check_non_crt(struct intelfb_info *dinfo)
271 return dvo; 268 return dvo;
272} 269}
273 270
274const char * 271const char * intelfbhw_dvo_to_string(int dvo)
275intelfbhw_dvo_to_string(int dvo)
276{ 272{
277 if (dvo & DVOA_PORT) 273 if (dvo & DVOA_PORT)
278 return "DVO port A"; 274 return "DVO port A";
@@ -287,9 +283,8 @@ intelfbhw_dvo_to_string(int dvo)
287} 283}
288 284
289 285
290int 286int intelfbhw_validate_mode(struct intelfb_info *dinfo,
291intelfbhw_validate_mode(struct intelfb_info *dinfo, 287 struct fb_var_screeninfo *var)
292 struct fb_var_screeninfo *var)
293{ 288{
294 int bytes_per_pixel; 289 int bytes_per_pixel;
295 int tmp; 290 int tmp;
@@ -322,17 +317,26 @@ intelfbhw_validate_mode(struct intelfb_info *dinfo,
322 var->yres, VACTIVE_MASK + 1); 317 var->yres, VACTIVE_MASK + 1);
323 return 1; 318 return 1;
324 } 319 }
325 320 if (var->xres < 4) {
326 /* Check for interlaced/doublescan modes. */ 321 WRN_MSG("X resolution too small (%d vs 4).\n", var->xres);
327 if (var->vmode & FB_VMODE_INTERLACED) { 322 return 1;
328 WRN_MSG("Mode is interlaced.\n"); 323 }
324 if (var->yres < 4) {
325 WRN_MSG("Y resolution too small (%d vs 4).\n", var->yres);
329 return 1; 326 return 1;
330 } 327 }
328
329 /* Check for doublescan modes. */
331 if (var->vmode & FB_VMODE_DOUBLE) { 330 if (var->vmode & FB_VMODE_DOUBLE) {
332 WRN_MSG("Mode is double-scan.\n"); 331 WRN_MSG("Mode is double-scan.\n");
333 return 1; 332 return 1;
334 } 333 }
335 334
335 if ((var->vmode & FB_VMODE_INTERLACED) && (var->yres & 1)) {
336 WRN_MSG("Odd number of lines in interlaced mode\n");
337 return 1;
338 }
339
336 /* Check if clock is OK. */ 340 /* Check if clock is OK. */
337 tmp = 1000000000 / var->pixclock; 341 tmp = 1000000000 / var->pixclock;
338 if (tmp < MIN_CLOCK) { 342 if (tmp < MIN_CLOCK) {
@@ -349,8 +353,7 @@ intelfbhw_validate_mode(struct intelfb_info *dinfo,
349 return 0; 353 return 0;
350} 354}
351 355
352int 356int intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
353intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
354{ 357{
355 struct intelfb_info *dinfo = GET_DINFO(info); 358 struct intelfb_info *dinfo = GET_DINFO(info);
356 u32 offset, xoffset, yoffset; 359 u32 offset, xoffset, yoffset;
@@ -372,9 +375,10 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
372 offset += dinfo->fb.offset << 12; 375 offset += dinfo->fb.offset << 12;
373 376
374 dinfo->vsync.pan_offset = offset; 377 dinfo->vsync.pan_offset = offset;
375 if ((var->activate & FB_ACTIVATE_VBL) && !intelfbhw_enable_irq(dinfo, 0)) { 378 if ((var->activate & FB_ACTIVATE_VBL) &&
379 !intelfbhw_enable_irq(dinfo))
376 dinfo->vsync.pan_display = 1; 380 dinfo->vsync.pan_display = 1;
377 } else { 381 else {
378 dinfo->vsync.pan_display = 0; 382 dinfo->vsync.pan_display = 0;
379 OUTREG(DSPABASE, offset); 383 OUTREG(DSPABASE, offset);
380 } 384 }
@@ -383,8 +387,7 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
383} 387}
384 388
385/* Blank the screen. */ 389/* Blank the screen. */
386void 390void intelfbhw_do_blank(int blank, struct fb_info *info)
387intelfbhw_do_blank(int blank, struct fb_info *info)
388{ 391{
389 struct intelfb_info *dinfo = GET_DINFO(info); 392 struct intelfb_info *dinfo = GET_DINFO(info);
390 u32 tmp; 393 u32 tmp;
@@ -409,11 +412,10 @@ intelfbhw_do_blank(int blank, struct fb_info *info)
409 DBG_MSG("cursor_on is %d\n", dinfo->cursor_on); 412 DBG_MSG("cursor_on is %d\n", dinfo->cursor_on);
410#endif 413#endif
411 if (dinfo->cursor_on) { 414 if (dinfo->cursor_on) {
412 if (blank) { 415 if (blank)
413 intelfbhw_cursor_hide(dinfo); 416 intelfbhw_cursor_hide(dinfo);
414 } else { 417 else
415 intelfbhw_cursor_show(dinfo); 418 intelfbhw_cursor_show(dinfo);
416 }
417 dinfo->cursor_on = 1; 419 dinfo->cursor_on = 1;
418 } 420 }
419 dinfo->cursor_blanked = blank; 421 dinfo->cursor_blanked = blank;
@@ -441,19 +443,18 @@ intelfbhw_do_blank(int blank, struct fb_info *info)
441} 443}
442 444
443 445
444void 446void intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno,
445intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno, 447 unsigned red, unsigned green, unsigned blue,
446 unsigned red, unsigned green, unsigned blue, 448 unsigned transp)
447 unsigned transp)
448{ 449{
450 u32 palette_reg = (dinfo->pipe == PIPE_A) ?
451 PALETTE_A : PALETTE_B;
452
449#if VERBOSE > 0 453#if VERBOSE > 0
450 DBG_MSG("intelfbhw_setcolreg: %d: (%d, %d, %d)\n", 454 DBG_MSG("intelfbhw_setcolreg: %d: (%d, %d, %d)\n",
451 regno, red, green, blue); 455 regno, red, green, blue);
452#endif 456#endif
453 457
454 u32 palette_reg = (dinfo->pipe == PIPE_A) ?
455 PALETTE_A : PALETTE_B;
456
457 OUTREG(palette_reg + (regno << 2), 458 OUTREG(palette_reg + (regno << 2),
458 (red << PALETTE_8_RED_SHIFT) | 459 (red << PALETTE_8_RED_SHIFT) |
459 (green << PALETTE_8_GREEN_SHIFT) | 460 (green << PALETTE_8_GREEN_SHIFT) |
@@ -461,9 +462,8 @@ intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno,
461} 462}
462 463
463 464
464int 465int intelfbhw_read_hw_state(struct intelfb_info *dinfo,
465intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, 466 struct intelfb_hwstate *hw, int flag)
466 int flag)
467{ 467{
468 int i; 468 int i;
469 469
@@ -610,7 +610,8 @@ static int calc_vclock3(int index, int m, int n, int p)
610 return plls[index].ref_clk * m / n / p; 610 return plls[index].ref_clk * m / n / p;
611} 611}
612 612
613static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvds) 613static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2,
614 int lvds)
614{ 615{
615 struct pll_min_max *pll = &plls[index]; 616 struct pll_min_max *pll = &plls[index];
616 u32 m, vco, p; 617 u32 m, vco, p;
@@ -619,17 +620,16 @@ static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvd
619 n += 2; 620 n += 2;
620 vco = pll->ref_clk * m / n; 621 vco = pll->ref_clk * m / n;
621 622
622 if (index == PLLS_I8xx) { 623 if (index == PLLS_I8xx)
623 p = ((p1 + 2) * (1 << (p2 + 1))); 624 p = ((p1 + 2) * (1 << (p2 + 1)));
624 } else { 625 else
625 p = ((p1) * (p2 ? 5 : 10)); 626 p = ((p1) * (p2 ? 5 : 10));
626 }
627 return vco / p; 627 return vco / p;
628} 628}
629 629
630#if REGDUMP 630#if REGDUMP
631static void 631static void intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll,
632intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2) 632 int *o_p1, int *o_p2)
633{ 633{
634 int p1, p2; 634 int p1, p2;
635 635
@@ -638,7 +638,7 @@ intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
638 p1 = 1; 638 p1 = 1;
639 else 639 else
640 p1 = (dpll >> DPLL_P1_SHIFT) & 0xff; 640 p1 = (dpll >> DPLL_P1_SHIFT) & 0xff;
641 641
642 p1 = ffs(p1); 642 p1 = ffs(p1);
643 643
644 p2 = (dpll >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK; 644 p2 = (dpll >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK;
@@ -656,8 +656,8 @@ intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
656#endif 656#endif
657 657
658 658
659void 659void intelfbhw_print_hw_state(struct intelfb_info *dinfo,
660intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) 660 struct intelfb_hwstate *hw)
661{ 661{
662#if REGDUMP 662#if REGDUMP
663 int i, m1, m2, n, p1, p2; 663 int i, m1, m2, n, p1, p2;
@@ -670,7 +670,7 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
670 printk("hw state dump start\n"); 670 printk("hw state dump start\n");
671 printk(" VGA0_DIVISOR: 0x%08x\n", hw->vga0_divisor); 671 printk(" VGA0_DIVISOR: 0x%08x\n", hw->vga0_divisor);
672 printk(" VGA1_DIVISOR: 0x%08x\n", hw->vga1_divisor); 672 printk(" VGA1_DIVISOR: 0x%08x\n", hw->vga1_divisor);
673 printk(" VGAPD: 0x%08x\n", hw->vga_pd); 673 printk(" VGAPD: 0x%08x\n", hw->vga_pd);
674 n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 674 n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
675 m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 675 m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
676 m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 676 m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
@@ -689,7 +689,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
689 intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2); 689 intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2);
690 printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 690 printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
691 m1, m2, n, p1, p2); 691 m1, m2, n, p1, p2);
692 printk(" VGA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); 692 printk(" VGA1: clock is %d\n",
693 calc_vclock(index, m1, m2, n, p1, p2, 0));
693 694
694 printk(" DPLL_A: 0x%08x\n", hw->dpll_a); 695 printk(" DPLL_A: 0x%08x\n", hw->dpll_a);
695 printk(" DPLL_B: 0x%08x\n", hw->dpll_b); 696 printk(" DPLL_B: 0x%08x\n", hw->dpll_b);
@@ -706,7 +707,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
706 707
707 printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 708 printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
708 m1, m2, n, p1, p2); 709 m1, m2, n, p1, p2);
709 printk(" PLLA0: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); 710 printk(" PLLA0: clock is %d\n",
711 calc_vclock(index, m1, m2, n, p1, p2, 0));
710 712
711 n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 713 n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
712 m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 714 m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
@@ -716,7 +718,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
716 718
717 printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 719 printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
718 m1, m2, n, p1, p2); 720 m1, m2, n, p1, p2);
719 printk(" PLLA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); 721 printk(" PLLA1: clock is %d\n",
722 calc_vclock(index, m1, m2, n, p1, p2, 0));
720 723
721#if 0 724#if 0
722 printk(" PALETTE_A:\n"); 725 printk(" PALETTE_A:\n");
@@ -821,8 +824,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
821 824
822 825
823/* Split the M parameter into M1 and M2. */ 826/* Split the M parameter into M1 and M2. */
824static int 827static int splitm(int index, unsigned int m, unsigned int *retm1,
825splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2) 828 unsigned int *retm2)
826{ 829{
827 int m1, m2; 830 int m1, m2;
828 int testm; 831 int testm;
@@ -843,8 +846,8 @@ splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2)
843} 846}
844 847
845/* Split the P parameter into P1 and P2. */ 848/* Split the P parameter into P1 and P2. */
846static int 849static int splitp(int index, unsigned int p, unsigned int *retp1,
847splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2) 850 unsigned int *retp2)
848{ 851{
849 int p1, p2; 852 int p1, p2;
850 struct pll_min_max *pll = &plls[index]; 853 struct pll_min_max *pll = &plls[index];
@@ -878,9 +881,8 @@ splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2)
878 } 881 }
879} 882}
880 883
881static int 884static int calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2,
882calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, 885 u32 *retn, u32 *retp1, u32 *retp2, u32 *retclock)
883 u32 *retp2, u32 *retclock)
884{ 886{
885 u32 m1, m2, n, p1, p2, n1, testm; 887 u32 m1, m2, n, p1, p2, n1, testm;
886 u32 f_vco, p, p_best = 0, m, f_out = 0; 888 u32 f_vco, p, p_best = 0, m, f_out = 0;
@@ -975,8 +977,8 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re
975 return 0; 977 return 0;
976} 978}
977 979
978static __inline__ int 980static __inline__ int check_overflow(u32 value, u32 limit,
979check_overflow(u32 value, u32 limit, const char *description) 981 const char *description)
980{ 982{
981 if (value > limit) { 983 if (value > limit) {
982 WRN_MSG("%s value %d exceeds limit %d\n", 984 WRN_MSG("%s value %d exceeds limit %d\n",
@@ -987,9 +989,9 @@ check_overflow(u32 value, u32 limit, const char *description)
987} 989}
988 990
989/* It is assumed that hw is filled in with the initial state information. */ 991/* It is assumed that hw is filled in with the initial state information. */
990int 992int intelfbhw_mode_to_hw(struct intelfb_info *dinfo,
991intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, 993 struct intelfb_hwstate *hw,
992 struct fb_var_screeninfo *var) 994 struct fb_var_screeninfo *var)
993{ 995{
994 int pipe = PIPE_A; 996 int pipe = PIPE_A;
995 u32 *dpll, *fp0, *fp1; 997 u32 *dpll, *fp0, *fp1;
@@ -1093,9 +1095,8 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
1093 if (IS_I9XX(dinfo)) { 1095 if (IS_I9XX(dinfo)) {
1094 *dpll |= (p2 << DPLL_I9XX_P2_SHIFT); 1096 *dpll |= (p2 << DPLL_I9XX_P2_SHIFT);
1095 *dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT; 1097 *dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT;
1096 } else { 1098 } else
1097 *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); 1099 *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT);
1098 }
1099 1100
1100 *fp0 = (n << FP_N_DIVISOR_SHIFT) | 1101 *fp0 = (n << FP_N_DIVISOR_SHIFT) |
1101 (m1 << FP_M1_DIVISOR_SHIFT) | 1102 (m1 << FP_M1_DIVISOR_SHIFT) |
@@ -1139,6 +1140,8 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
1139 hblank_end); 1140 hblank_end);
1140 1141
1141 vactive = var->yres; 1142 vactive = var->yres;
1143 if (var->vmode & FB_VMODE_INTERLACED)
1144 vactive--; /* the chip adds 2 halflines automatically */
1142 vsync_start = vactive + var->lower_margin; 1145 vsync_start = vactive + var->lower_margin;
1143 vsync_end = vsync_start + var->vsync_len; 1146 vsync_end = vsync_start + var->vsync_len;
1144 vtotal = vsync_end + var->upper_margin; 1147 vtotal = vsync_end + var->upper_margin;
@@ -1220,19 +1223,24 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
1220 1223
1221 /* Set the palette to 8-bit mode. */ 1224 /* Set the palette to 8-bit mode. */
1222 *pipe_conf &= ~PIPECONF_GAMMA; 1225 *pipe_conf &= ~PIPECONF_GAMMA;
1226
1227 if (var->vmode & FB_VMODE_INTERLACED)
1228 *pipe_conf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
1229 else
1230 *pipe_conf &= ~PIPECONF_INTERLACE_MASK;
1231
1223 return 0; 1232 return 0;
1224} 1233}
1225 1234
1226/* Program a (non-VGA) video mode. */ 1235/* Program a (non-VGA) video mode. */
1227int 1236int intelfbhw_program_mode(struct intelfb_info *dinfo,
1228intelfbhw_program_mode(struct intelfb_info *dinfo, 1237 const struct intelfb_hwstate *hw, int blank)
1229 const struct intelfb_hwstate *hw, int blank)
1230{ 1238{
1231 int pipe = PIPE_A; 1239 int pipe = PIPE_A;
1232 u32 tmp; 1240 u32 tmp;
1233 const u32 *dpll, *fp0, *fp1, *pipe_conf; 1241 const u32 *dpll, *fp0, *fp1, *pipe_conf;
1234 const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss; 1242 const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss;
1235 u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg; 1243 u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg, pipe_stat_reg;
1236 u32 hsync_reg, htotal_reg, hblank_reg; 1244 u32 hsync_reg, htotal_reg, hblank_reg;
1237 u32 vsync_reg, vtotal_reg, vblank_reg; 1245 u32 vsync_reg, vtotal_reg, vblank_reg;
1238 u32 src_size_reg; 1246 u32 src_size_reg;
@@ -1273,6 +1281,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1273 fp0_reg = FPB0; 1281 fp0_reg = FPB0;
1274 fp1_reg = FPB1; 1282 fp1_reg = FPB1;
1275 pipe_conf_reg = PIPEBCONF; 1283 pipe_conf_reg = PIPEBCONF;
1284 pipe_stat_reg = PIPEBSTAT;
1276 hsync_reg = HSYNC_B; 1285 hsync_reg = HSYNC_B;
1277 htotal_reg = HTOTAL_B; 1286 htotal_reg = HTOTAL_B;
1278 hblank_reg = HBLANK_B; 1287 hblank_reg = HBLANK_B;
@@ -1296,6 +1305,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1296 fp0_reg = FPA0; 1305 fp0_reg = FPA0;
1297 fp1_reg = FPA1; 1306 fp1_reg = FPA1;
1298 pipe_conf_reg = PIPEACONF; 1307 pipe_conf_reg = PIPEACONF;
1308 pipe_stat_reg = PIPEASTAT;
1299 hsync_reg = HSYNC_A; 1309 hsync_reg = HSYNC_A;
1300 htotal_reg = HTOTAL_A; 1310 htotal_reg = HTOTAL_A;
1301 hblank_reg = HBLANK_A; 1311 hblank_reg = HBLANK_A;
@@ -1312,8 +1322,8 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1312 1322
1313 count = 0; 1323 count = 0;
1314 do { 1324 do {
1315 tmp_val[count%3] = INREG(0x70000); 1325 tmp_val[count % 3] = INREG(PIPEA_DSL);
1316 if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1]==tmp_val[2])) 1326 if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1] == tmp_val[2]))
1317 break; 1327 break;
1318 count++; 1328 count++;
1319 udelay(1); 1329 udelay(1);
@@ -1322,7 +1332,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1322 tmp &= ~PIPECONF_ENABLE; 1332 tmp &= ~PIPECONF_ENABLE;
1323 OUTREG(pipe_conf_reg, tmp); 1333 OUTREG(pipe_conf_reg, tmp);
1324 } 1334 }
1325 } while(count < 2000); 1335 } while (count < 2000);
1326 1336
1327 OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); 1337 OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE);
1328 1338
@@ -1382,6 +1392,17 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1382 OUTREG(vtotal_reg, *vt); 1392 OUTREG(vtotal_reg, *vt);
1383 OUTREG(src_size_reg, *ss); 1393 OUTREG(src_size_reg, *ss);
1384 1394
1395 switch (dinfo->info->var.vmode & (FB_VMODE_INTERLACED |
1396 FB_VMODE_ODD_FLD_FIRST)) {
1397 case FB_VMODE_INTERLACED | FB_VMODE_ODD_FLD_FIRST:
1398 OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_ODD_EN);
1399 break;
1400 case FB_VMODE_INTERLACED: /* even lines first */
1401 OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_EVEN_EN);
1402 break;
1403 default: /* non-interlaced */
1404 OUTREG(pipe_stat_reg, 0xFFFF); /* clear all status bits only */
1405 }
1385 /* Enable pipe */ 1406 /* Enable pipe */
1386 OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE); 1407 OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE);
1387 1408
@@ -1446,8 +1467,7 @@ static u32 get_ring_space(struct intelfb_info *dinfo)
1446 return ring_space; 1467 return ring_space;
1447} 1468}
1448 1469
1449static int 1470static int wait_ring(struct intelfb_info *dinfo, int n)
1450wait_ring(struct intelfb_info *dinfo, int n)
1451{ 1471{
1452 int i = 0; 1472 int i = 0;
1453 unsigned long end; 1473 unsigned long end;
@@ -1489,16 +1509,15 @@ wait_ring(struct intelfb_info *dinfo, int n)
1489 return i; 1509 return i;
1490} 1510}
1491 1511
1492static void 1512static void do_flush(struct intelfb_info *dinfo)
1493do_flush(struct intelfb_info *dinfo) { 1513{
1494 START_RING(2); 1514 START_RING(2);
1495 OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); 1515 OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
1496 OUT_RING(MI_NOOP); 1516 OUT_RING(MI_NOOP);
1497 ADVANCE_RING(); 1517 ADVANCE_RING();
1498} 1518}
1499 1519
1500void 1520void intelfbhw_do_sync(struct intelfb_info *dinfo)
1501intelfbhw_do_sync(struct intelfb_info *dinfo)
1502{ 1521{
1503#if VERBOSE > 0 1522#if VERBOSE > 0
1504 DBG_MSG("intelfbhw_do_sync\n"); 1523 DBG_MSG("intelfbhw_do_sync\n");
@@ -1517,8 +1536,7 @@ intelfbhw_do_sync(struct intelfb_info *dinfo)
1517 dinfo->ring_space = dinfo->ring.size - RING_MIN_FREE; 1536 dinfo->ring_space = dinfo->ring.size - RING_MIN_FREE;
1518} 1537}
1519 1538
1520static void 1539static void refresh_ring(struct intelfb_info *dinfo)
1521refresh_ring(struct intelfb_info *dinfo)
1522{ 1540{
1523#if VERBOSE > 0 1541#if VERBOSE > 0
1524 DBG_MSG("refresh_ring\n"); 1542 DBG_MSG("refresh_ring\n");
@@ -1529,8 +1547,7 @@ refresh_ring(struct intelfb_info *dinfo)
1529 dinfo->ring_space = get_ring_space(dinfo); 1547 dinfo->ring_space = get_ring_space(dinfo);
1530} 1548}
1531 1549
1532static void 1550static void reset_state(struct intelfb_info *dinfo)
1533reset_state(struct intelfb_info *dinfo)
1534{ 1551{
1535 int i; 1552 int i;
1536 u32 tmp; 1553 u32 tmp;
@@ -1560,12 +1577,11 @@ reset_state(struct intelfb_info *dinfo)
1560} 1577}
1561 1578
1562/* Stop the 2D engine, and turn off the ring buffer. */ 1579/* Stop the 2D engine, and turn off the ring buffer. */
1563void 1580void intelfbhw_2d_stop(struct intelfb_info *dinfo)
1564intelfbhw_2d_stop(struct intelfb_info *dinfo)
1565{ 1581{
1566#if VERBOSE > 0 1582#if VERBOSE > 0
1567 DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n", dinfo->accel, 1583 DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n",
1568 dinfo->ring_active); 1584 dinfo->accel, dinfo->ring_active);
1569#endif 1585#endif
1570 1586
1571 if (!dinfo->accel) 1587 if (!dinfo->accel)
@@ -1580,8 +1596,7 @@ intelfbhw_2d_stop(struct intelfb_info *dinfo)
1580 * It is assumed that the graphics engine has been stopped by previously 1596 * It is assumed that the graphics engine has been stopped by previously
1581 * calling intelfb_2d_stop(). 1597 * calling intelfb_2d_stop().
1582 */ 1598 */
1583void 1599void intelfbhw_2d_start(struct intelfb_info *dinfo)
1584intelfbhw_2d_start(struct intelfb_info *dinfo)
1585{ 1600{
1586#if VERBOSE > 0 1601#if VERBOSE > 0
1587 DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n", 1602 DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n",
@@ -1605,9 +1620,8 @@ intelfbhw_2d_start(struct intelfb_info *dinfo)
1605} 1620}
1606 1621
1607/* 2D fillrect (solid fill or invert) */ 1622/* 2D fillrect (solid fill or invert) */
1608void 1623void intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w,
1609intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w, u32 h, 1624 u32 h, u32 color, u32 pitch, u32 bpp, u32 rop)
1610 u32 color, u32 pitch, u32 bpp, u32 rop)
1611{ 1625{
1612 u32 br00, br09, br13, br14, br16; 1626 u32 br00, br09, br13, br14, br16;
1613 1627
@@ -1696,9 +1710,9 @@ intelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury,
1696 ADVANCE_RING(); 1710 ADVANCE_RING();
1697} 1711}
1698 1712
1699int 1713int intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w,
1700intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w, 1714 u32 h, const u8* cdat, u32 x, u32 y, u32 pitch,
1701 u32 h, const u8* cdat, u32 x, u32 y, u32 pitch, u32 bpp) 1715 u32 bpp)
1702{ 1716{
1703 int nbytes, ndwords, pad, tmp; 1717 int nbytes, ndwords, pad, tmp;
1704 u32 br00, br09, br13, br18, br19, br22, br23; 1718 u32 br00, br09, br13, br18, br19, br22, br23;
@@ -1785,8 +1799,7 @@ intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w,
1785} 1799}
1786 1800
1787/* HW cursor functions. */ 1801/* HW cursor functions. */
1788void 1802void intelfbhw_cursor_init(struct intelfb_info *dinfo)
1789intelfbhw_cursor_init(struct intelfb_info *dinfo)
1790{ 1803{
1791 u32 tmp; 1804 u32 tmp;
1792 1805
@@ -1817,8 +1830,7 @@ intelfbhw_cursor_init(struct intelfb_info *dinfo)
1817 } 1830 }
1818} 1831}
1819 1832
1820void 1833void intelfbhw_cursor_hide(struct intelfb_info *dinfo)
1821intelfbhw_cursor_hide(struct intelfb_info *dinfo)
1822{ 1834{
1823 u32 tmp; 1835 u32 tmp;
1824 1836
@@ -1843,8 +1855,7 @@ intelfbhw_cursor_hide(struct intelfb_info *dinfo)
1843 } 1855 }
1844} 1856}
1845 1857
1846void 1858void intelfbhw_cursor_show(struct intelfb_info *dinfo)
1847intelfbhw_cursor_show(struct intelfb_info *dinfo)
1848{ 1859{
1849 u32 tmp; 1860 u32 tmp;
1850 1861
@@ -1873,8 +1884,7 @@ intelfbhw_cursor_show(struct intelfb_info *dinfo)
1873 } 1884 }
1874} 1885}
1875 1886
1876void 1887void intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
1877intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
1878{ 1888{
1879 u32 tmp; 1889 u32 tmp;
1880 1890
@@ -1892,13 +1902,11 @@ intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
1892 ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); 1902 ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
1893 OUTREG(CURSOR_A_POSITION, tmp); 1903 OUTREG(CURSOR_A_POSITION, tmp);
1894 1904
1895 if (IS_I9XX(dinfo)) { 1905 if (IS_I9XX(dinfo))
1896 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1906 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
1897 }
1898} 1907}
1899 1908
1900void 1909void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
1901intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
1902{ 1910{
1903#if VERBOSE > 0 1911#if VERBOSE > 0
1904 DBG_MSG("intelfbhw_cursor_setcolor\n"); 1912 DBG_MSG("intelfbhw_cursor_setcolor\n");
@@ -1910,9 +1918,8 @@ intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
1910 OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK); 1918 OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK);
1911} 1919}
1912 1920
1913void 1921void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height,
1914intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height, 1922 u8 *data)
1915 u8 *data)
1916{ 1923{
1917 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual; 1924 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual;
1918 int i, j, w = width / 8; 1925 int i, j, w = width / 8;
@@ -1940,8 +1947,8 @@ intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height,
1940 } 1947 }
1941} 1948}
1942 1949
1943void 1950void intelfbhw_cursor_reset(struct intelfb_info *dinfo)
1944intelfbhw_cursor_reset(struct intelfb_info *dinfo) { 1951{
1945 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual; 1952 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual;
1946 int i, j; 1953 int i, j;
1947 1954
@@ -1961,72 +1968,72 @@ intelfbhw_cursor_reset(struct intelfb_info *dinfo) {
1961 } 1968 }
1962} 1969}
1963 1970
1964static irqreturn_t 1971static irqreturn_t intelfbhw_irq(int irq, void *dev_id)
1965intelfbhw_irq(int irq, void *dev_id) { 1972{
1966 int handled = 0;
1967 u16 tmp; 1973 u16 tmp;
1968 struct intelfb_info *dinfo = (struct intelfb_info *)dev_id; 1974 struct intelfb_info *dinfo = (struct intelfb_info *)dev_id;
1969 1975
1970 spin_lock(&dinfo->int_lock); 1976 spin_lock(&dinfo->int_lock);
1971 1977
1972 tmp = INREG16(IIR); 1978 tmp = INREG16(IIR);
1973 tmp &= VSYNC_PIPE_A_INTERRUPT; 1979 if (dinfo->info->var.vmode & FB_VMODE_INTERLACED)
1980 tmp &= PIPE_A_EVENT_INTERRUPT;
1981 else
1982 tmp &= VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */
1974 1983
1975 if (tmp == 0) { 1984 if (tmp == 0) {
1976 spin_unlock(&dinfo->int_lock); 1985 spin_unlock(&dinfo->int_lock);
1977 return IRQ_RETVAL(handled); 1986 return IRQ_RETVAL(0); /* not us */
1978 } 1987 }
1979 1988
1980 OUTREG16(IIR, tmp); 1989 /* clear status bits 0-15 ASAP and don't touch bits 16-31 */
1990 OUTREG(PIPEASTAT, INREG(PIPEASTAT));
1981 1991
1982 if (tmp & VSYNC_PIPE_A_INTERRUPT) { 1992 OUTREG16(IIR, tmp);
1983 dinfo->vsync.count++; 1993 if (dinfo->vsync.pan_display) {
1984 if (dinfo->vsync.pan_display) { 1994 dinfo->vsync.pan_display = 0;
1985 dinfo->vsync.pan_display = 0; 1995 OUTREG(DSPABASE, dinfo->vsync.pan_offset);
1986 OUTREG(DSPABASE, dinfo->vsync.pan_offset);
1987 }
1988 wake_up_interruptible(&dinfo->vsync.wait);
1989 handled = 1;
1990 } 1996 }
1991 1997
1998 dinfo->vsync.count++;
1999 wake_up_interruptible(&dinfo->vsync.wait);
2000
1992 spin_unlock(&dinfo->int_lock); 2001 spin_unlock(&dinfo->int_lock);
1993 2002
1994 return IRQ_RETVAL(handled); 2003 return IRQ_RETVAL(1);
1995} 2004}
1996 2005
1997int 2006int intelfbhw_enable_irq(struct intelfb_info *dinfo)
1998intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable) { 2007{
1999 2008 u16 tmp;
2000 if (!test_and_set_bit(0, &dinfo->irq_flags)) { 2009 if (!test_and_set_bit(0, &dinfo->irq_flags)) {
2001 if (request_irq(dinfo->pdev->irq, intelfbhw_irq, IRQF_SHARED, 2010 if (request_irq(dinfo->pdev->irq, intelfbhw_irq, IRQF_SHARED,
2002 "intelfb", dinfo)) { 2011 "intelfb", dinfo)) {
2003 clear_bit(0, &dinfo->irq_flags); 2012 clear_bit(0, &dinfo->irq_flags);
2004 return -EINVAL; 2013 return -EINVAL;
2005 } 2014 }
2006 2015
2007 spin_lock_irq(&dinfo->int_lock); 2016 spin_lock_irq(&dinfo->int_lock);
2008 OUTREG16(HWSTAM, 0xfffe); 2017 OUTREG16(HWSTAM, 0xfffe); /* i830 DRM uses ffff */
2009 OUTREG16(IMR, 0x0); 2018 OUTREG16(IMR, 0);
2010 OUTREG16(IER, VSYNC_PIPE_A_INTERRUPT); 2019 } else
2011 spin_unlock_irq(&dinfo->int_lock);
2012 } else if (reenable) {
2013 u16 ier;
2014
2015 spin_lock_irq(&dinfo->int_lock); 2020 spin_lock_irq(&dinfo->int_lock);
2016 ier = INREG16(IER); 2021
2017 if ((ier & VSYNC_PIPE_A_INTERRUPT)) { 2022 if (dinfo->info->var.vmode & FB_VMODE_INTERLACED)
2018 DBG_MSG("someone disabled the IRQ [%08X]\n", ier); 2023 tmp = PIPE_A_EVENT_INTERRUPT;
2019 OUTREG(IER, VSYNC_PIPE_A_INTERRUPT); 2024 else
2020 } 2025 tmp = VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */
2021 spin_unlock_irq(&dinfo->int_lock); 2026 if (tmp != INREG16(IER)) {
2027 DBG_MSG("changing IER to 0x%X\n", tmp);
2028 OUTREG16(IER, tmp);
2022 } 2029 }
2030
2031 spin_unlock_irq(&dinfo->int_lock);
2023 return 0; 2032 return 0;
2024} 2033}
2025 2034
2026void 2035void intelfbhw_disable_irq(struct intelfb_info *dinfo)
2027intelfbhw_disable_irq(struct intelfb_info *dinfo) { 2036{
2028 u16 tmp;
2029
2030 if (test_and_clear_bit(0, &dinfo->irq_flags)) { 2037 if (test_and_clear_bit(0, &dinfo->irq_flags)) {
2031 if (dinfo->vsync.pan_display) { 2038 if (dinfo->vsync.pan_display) {
2032 dinfo->vsync.pan_display = 0; 2039 dinfo->vsync.pan_display = 0;
@@ -2037,16 +2044,15 @@ intelfbhw_disable_irq(struct intelfb_info *dinfo) {
2037 OUTREG16(IMR, 0xffff); 2044 OUTREG16(IMR, 0xffff);
2038 OUTREG16(IER, 0x0); 2045 OUTREG16(IER, 0x0);
2039 2046
2040 tmp = INREG16(IIR); 2047 OUTREG16(IIR, INREG16(IIR)); /* clear IRQ requests */
2041 OUTREG16(IIR, tmp);
2042 spin_unlock_irq(&dinfo->int_lock); 2048 spin_unlock_irq(&dinfo->int_lock);
2043 2049
2044 free_irq(dinfo->pdev->irq, dinfo); 2050 free_irq(dinfo->pdev->irq, dinfo);
2045 } 2051 }
2046} 2052}
2047 2053
2048int 2054int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe)
2049intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) { 2055{
2050 struct intelfb_vsync *vsync; 2056 struct intelfb_vsync *vsync;
2051 unsigned int count; 2057 unsigned int count;
2052 int ret; 2058 int ret;
@@ -2059,18 +2065,16 @@ intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) {
2059 return -ENODEV; 2065 return -ENODEV;
2060 } 2066 }
2061 2067
2062 ret = intelfbhw_enable_irq(dinfo, 0); 2068 ret = intelfbhw_enable_irq(dinfo);
2063 if (ret) { 2069 if (ret)
2064 return ret; 2070 return ret;
2065 }
2066 2071
2067 count = vsync->count; 2072 count = vsync->count;
2068 ret = wait_event_interruptible_timeout(vsync->wait, count != vsync->count, HZ/10); 2073 ret = wait_event_interruptible_timeout(vsync->wait,
2069 if (ret < 0) { 2074 count != vsync->count, HZ / 10);
2075 if (ret < 0)
2070 return ret; 2076 return ret;
2071 }
2072 if (ret == 0) { 2077 if (ret == 0) {
2073 intelfbhw_enable_irq(dinfo, 1);
2074 DBG_MSG("wait_for_vsync timed out!\n"); 2078 DBG_MSG("wait_for_vsync timed out!\n");
2075 return -ETIMEDOUT; 2079 return -ETIMEDOUT;
2076 } 2080 }
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h
index 8c54ba8fbdda..0b076bac321b 100644
--- a/drivers/video/intelfb/intelfbhw.h
+++ b/drivers/video/intelfb/intelfbhw.h
@@ -83,7 +83,7 @@
83 */ 83 */
84#define RING_MIN_FREE 64 84#define RING_MIN_FREE 64
85 85
86#define IPEHR 0x2088 86#define IPEHR 0x2088
87 87
88#define INSTDONE 0x2090 88#define INSTDONE 0x2090
89#define PRI_RING_EMPTY 1 89#define PRI_RING_EMPTY 1
@@ -93,7 +93,7 @@
93#define IIR 0x20A4 93#define IIR 0x20A4
94#define IMR 0x20A8 94#define IMR 0x20A8
95#define VSYNC_PIPE_A_INTERRUPT (1 << 7) 95#define VSYNC_PIPE_A_INTERRUPT (1 << 7)
96#define PIPE_A_EVENT_INTERRUPT (1 << 4) 96#define PIPE_A_EVENT_INTERRUPT (1 << 6)
97#define VSYNC_PIPE_B_INTERRUPT (1 << 5) 97#define VSYNC_PIPE_B_INTERRUPT (1 << 5)
98#define PIPE_B_EVENT_INTERRUPT (1 << 4) 98#define PIPE_B_EVENT_INTERRUPT (1 << 4)
99#define HOST_PORT_EVENT_INTERRUPT (1 << 3) 99#define HOST_PORT_EVENT_INTERRUPT (1 << 3)
@@ -128,9 +128,9 @@
128 128
129#define GPIOA 0x5010 129#define GPIOA 0x5010
130#define GPIOB 0x5014 130#define GPIOB 0x5014
131#define GPIOC 0x5018 // this may be external DDC on i830 131#define GPIOC 0x5018 /* this may be external DDC on i830 */
132#define GPIOD 0x501C // this is DVO DDC 132#define GPIOD 0x501C /* this is DVO DDC */
133#define GPIOE 0x5020 // this is DVO i2C 133#define GPIOE 0x5020 /* this is DVO i2C */
134#define GPIOF 0x5024 134#define GPIOF 0x5024
135 135
136/* PLL registers */ 136/* PLL registers */
@@ -269,15 +269,20 @@
269#define PORT_ENABLE (1 << 31) 269#define PORT_ENABLE (1 << 31)
270#define PORT_PIPE_SELECT_SHIFT 30 270#define PORT_PIPE_SELECT_SHIFT 30
271#define PORT_TV_FLAGS_MASK 0xFF 271#define PORT_TV_FLAGS_MASK 0xFF
272#define PORT_TV_FLAGS 0xC4 // ripped from my BIOS 272#define PORT_TV_FLAGS 0xC4 /* ripped from my BIOS
273 // to understand and correct 273 to understand and correct */
274 274
275#define DVOA_SRCDIM 0x61124 275#define DVOA_SRCDIM 0x61124
276#define DVOB_SRCDIM 0x61144 276#define DVOB_SRCDIM 0x61144
277#define DVOC_SRCDIM 0x61164 277#define DVOC_SRCDIM 0x61164
278 278
279#define PIPEA_DSL 0x70000
280#define PIPEB_DSL 0x71000
279#define PIPEACONF 0x70008 281#define PIPEACONF 0x70008
280#define PIPEBCONF 0x71008 282#define PIPEBCONF 0x71008
283#define PIPEASTAT 0x70024 /* bits 0-15 are "write 1 to clear" */
284#define PIPEBSTAT 0x71024
285
281#define PIPECONF_ENABLE (1 << 31) 286#define PIPECONF_ENABLE (1 << 31)
282#define PIPECONF_DISABLE 0 287#define PIPECONF_DISABLE 0
283#define PIPECONF_DOUBLE_WIDE (1 << 30) 288#define PIPECONF_DOUBLE_WIDE (1 << 30)
@@ -286,6 +291,35 @@
286#define PIPECONF_UNLOCKED 0 291#define PIPECONF_UNLOCKED 0
287#define PIPECONF_GAMMA (1 << 24) 292#define PIPECONF_GAMMA (1 << 24)
288#define PIPECONF_PALETTE 0 293#define PIPECONF_PALETTE 0
294#define PIPECONF_PROGRESSIVE (0 << 21)
295#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
296#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
297#define PIPECONF_INTERLACE_MASK (7 << 21)
298
299/* enable bits, write 1 to enable */
300#define PIPESTAT_FIFO_UNDERRUN (1 << 31)
301#define PIPESTAT_CRC_ERROR_EN (1 << 29)
302#define PIPESTAT_CRC_DONE_EN (1 << 28)
303#define PIPESTAT_HOTPLUG_EN (1 << 26)
304#define PIPESTAT_VERTICAL_SYNC_EN (1 << 25)
305#define PIPESTAT_DISPLINE_COMP_EN (1 << 24)
306#define PIPESTAT_FLD_EVT_ODD_EN (1 << 21)
307#define PIPESTAT_FLD_EVT_EVEN_EN (1 << 20)
308#define PIPESTAT_TV_HOTPLUG_EN (1 << 18)
309#define PIPESTAT_VBLANK_EN (1 << 17)
310#define PIPESTAT_OVL_UPDATE_EN (1 << 16)
311/* status bits, write 1 to clear */
312#define PIPESTAT_HOTPLUG_STATE (1 << 15)
313#define PIPESTAT_CRC_ERROR (1 << 13)
314#define PIPESTAT_CRC_DONE (1 << 12)
315#define PIPESTAT_HOTPLUG (1 << 10)
316#define PIPESTAT_VSYNC (1 << 9)
317#define PIPESTAT_DISPLINE_COMP (1 << 8)
318#define PIPESTAT_FLD_EVT_ODD (1 << 5)
319#define PIPESTAT_FLD_EVT_EVEN (1 << 4)
320#define PIPESTAT_TV_HOTPLUG (1 << 2)
321#define PIPESTAT_VBLANK (1 << 1)
322#define PIPESTAT_OVL_UPDATE (1 << 0)
289 323
290#define DISPARB 0x70030 324#define DISPARB 0x70030
291#define DISPARB_AEND_MASK 0x1ff 325#define DISPARB_AEND_MASK 0x1ff
@@ -365,7 +399,7 @@
365#define DISPPLANE_8BPP (0x2<<26) 399#define DISPPLANE_8BPP (0x2<<26)
366#define DISPPLANE_15_16BPP (0x4<<26) 400#define DISPPLANE_15_16BPP (0x4<<26)
367#define DISPPLANE_16BPP (0x5<<26) 401#define DISPPLANE_16BPP (0x5<<26)
368#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) 402#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
369#define DISPPLANE_32BPP (0x7<<26) 403#define DISPPLANE_32BPP (0x7<<26)
370#define DISPPLANE_STEREO_ENABLE (1<<25) 404#define DISPPLANE_STEREO_ENABLE (1<<25)
371#define DISPPLANE_STEREO_DISABLE 0 405#define DISPPLANE_STEREO_DISABLE 0
@@ -567,7 +601,7 @@ extern void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg,
567extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, 601extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width,
568 int height, u8 *data); 602 int height, u8 *data);
569extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo); 603extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo);
570extern int intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable); 604extern int intelfbhw_enable_irq(struct intelfb_info *dinfo);
571extern void intelfbhw_disable_irq(struct intelfb_info *dinfo); 605extern void intelfbhw_disable_irq(struct intelfb_info *dinfo);
572extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe); 606extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe);
573 607
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index 1c5579907397..acb9370fdb14 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -21,7 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <asm/io.h> 23#include <asm/io.h>
24#include <asm/uaccess.h> 24#include <linux/uaccess.h>
25#ifdef CONFIG_MTRR 25#ifdef CONFIG_MTRR
26#include <asm/mtrr.h> 26#include <asm/mtrr.h>
27#endif 27#endif
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index 2b0f799aa8da..a9283bae7790 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -34,6 +34,10 @@ extern const struct linux_logo logo_superh_vga16;
34extern const struct linux_logo logo_superh_clut224; 34extern const struct linux_logo logo_superh_clut224;
35extern const struct linux_logo logo_m32r_clut224; 35extern const struct linux_logo logo_m32r_clut224;
36 36
37static int nologo;
38module_param(nologo, bool, 0);
39MODULE_PARM_DESC(nologo, "Disables startup logo");
40
37/* logo's are marked __initdata. Use __init_refok to tell 41/* logo's are marked __initdata. Use __init_refok to tell
38 * modpost that it is intended that this function uses data 42 * modpost that it is intended that this function uses data
39 * marked __initdata. 43 * marked __initdata.
@@ -42,6 +46,9 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
42{ 46{
43 const struct linux_logo *logo = NULL; 47 const struct linux_logo *logo = NULL;
44 48
49 if (nologo)
50 return NULL;
51
45 if (depth >= 1) { 52 if (depth >= 1) {
46#ifdef CONFIG_LOGO_LINUX_MONO 53#ifdef CONFIG_LOGO_LINUX_MONO
47 /* Generic Linux logo */ 54 /* Generic Linux logo */
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 86ca7b179000..b25972ac6eeb 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -113,7 +113,7 @@
113#include "matroxfb_g450.h" 113#include "matroxfb_g450.h"
114#include <linux/matroxfb.h> 114#include <linux/matroxfb.h>
115#include <linux/interrupt.h> 115#include <linux/interrupt.h>
116#include <asm/uaccess.h> 116#include <linux/uaccess.h>
117 117
118#ifdef CONFIG_PPC_PMAC 118#ifdef CONFIG_PPC_PMAC
119#include <asm/machdep.h> 119#include <asm/machdep.h>
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 4b3344e03695..a6ab5b6a58d0 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -15,7 +15,7 @@
15#include "matroxfb_misc.h" 15#include "matroxfb_misc.h"
16#include "matroxfb_DAC1064.h" 16#include "matroxfb_DAC1064.h"
17#include <linux/matroxfb.h> 17#include <linux/matroxfb.h>
18#include <asm/uaccess.h> 18#include <linux/uaccess.h>
19 19
20/* **************************************************** */ 20/* **************************************************** */
21 21
diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/matrox/matroxfb_g450.c
index 4d610b405d45..6209a761f674 100644
--- a/drivers/video/matrox/matroxfb_g450.c
+++ b/drivers/video/matrox/matroxfb_g450.c
@@ -17,7 +17,6 @@
17#include "matroxfb_DAC1064.h" 17#include "matroxfb_DAC1064.h"
18#include "g450_pll.h" 18#include "g450_pll.h"
19#include <linux/matroxfb.h> 19#include <linux/matroxfb.h>
20#include <asm/uaccess.h>
21#include <asm/div64.h> 20#include <asm/div64.h>
22 21
23#include "matroxfb_g450.h" 22#include "matroxfb_g450.h"
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index de0d755f9019..49cd53e46c0a 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -18,7 +18,6 @@
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/matroxfb.h> 19#include <linux/matroxfb.h>
20#include <asm/div64.h> 20#include <asm/div64.h>
21#include <asm/uaccess.h>
22 21
23#define MAVEN_I2CID (0x1B) 22#define MAVEN_I2CID (0x1B)
24 23
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index 980d5f623902..80cd117ca65c 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/video/mbx/mbxfb.c 2 * linux/drivers/video/mbx/mbxfb.c
3 * 3 *
4 * Copyright (C) 2006 8D Technologies inc 4 * Copyright (C) 2006-2007 8D Technologies inc
5 * Raphael Assenat <raph@8d.com> 5 * Raphael Assenat <raph@8d.com>
6 * - Added video overlay support 6 * - Added video overlay support
7 * - Various improvements 7 * - Various improvements
@@ -334,8 +334,8 @@ static int mbxfb_blank(int blank, struct fb_info *info)
334 334
335static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) 335static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
336{ 336{
337 u32 vsctrl, vbbase, vscadr, vsadr; 337 u32 vsctrl, vscadr, vsadr;
338 u32 sssize, spoctrl, svctrl, shctrl; 338 u32 sssize, spoctrl, shctrl;
339 u32 vubase, vvbase; 339 u32 vubase, vvbase;
340 u32 vovrclk; 340 u32 vovrclk;
341 341
@@ -349,13 +349,11 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
349 vscadr = readl(VSCADR); 349 vscadr = readl(VSCADR);
350 vubase = readl(VUBASE); 350 vubase = readl(VUBASE);
351 vvbase = readl(VVBASE); 351 vvbase = readl(VVBASE);
352 shctrl = readl(SHCTRL);
352 353
353 spoctrl = readl(SPOCTRL); 354 spoctrl = readl(SPOCTRL);
354 sssize = readl(SSSIZE); 355 sssize = readl(SSSIZE);
355 356
356
357 vbbase = Vbbase_Glalpha(set->alpha);
358
359 vsctrl &= ~( FMsk(VSCTRL_VSWIDTH) | 357 vsctrl &= ~( FMsk(VSCTRL_VSWIDTH) |
360 FMsk(VSCTRL_VSHEIGHT) | 358 FMsk(VSCTRL_VSHEIGHT) |
361 FMsk(VSCTRL_VPIXFMT) | 359 FMsk(VSCTRL_VPIXFMT) |
@@ -364,38 +362,41 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
364 vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) | 362 vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) |
365 VSCTRL_CSC_EN; 363 VSCTRL_CSC_EN;
366 364
367 vscadr &= ~(VSCADR_STR_EN | VSCADR_COLKEY_EN | VSCADR_COLKEYSRC | 365 vscadr &= ~(VSCADR_STR_EN | FMsk(VSCADR_VBASE_ADR) );
368 FMsk(VSCADR_BLEND_M) | FMsk(VSCADR_BLEND_POS) |
369 FMsk(VSCADR_VBASE_ADR) );
370 vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR)); 366 vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR));
371 vvbase &= ~(FMsk(VVBASE_VBASE_ADR)); 367 vvbase &= ~(FMsk(VVBASE_VBASE_ADR));
372 368
373 switch (set->fmt) 369 switch (set->fmt) {
374 { 370 case MBXFB_FMT_YUV16:
375 case MBXFB_FMT_YUV12: 371 vsctrl |= VSCTRL_VPIXFMT_YUV12;
376 vsctrl |= VSCTRL_VPIXFMT_YUV12;
377 372
378 set->Y_stride = ((set->width) + 0xf ) & ~0xf; 373 set->Y_stride = ((set->width) + 0xf ) & ~0xf;
374 break;
375 case MBXFB_FMT_YUV12:
376 vsctrl |= VSCTRL_VPIXFMT_YUV12;
379 377
378 set->Y_stride = ((set->width) + 0xf ) & ~0xf;
379 vubase |= VUBASE_UVHALFSTR;
380
381 break;
382 case MBXFB_FMT_UY0VY1:
383 vsctrl |= VSCTRL_VPIXFMT_UY0VY1;
384 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
385 break;
386 case MBXFB_FMT_VY0UY1:
387 vsctrl |= VSCTRL_VPIXFMT_VY0UY1;
388 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
389 break;
390 case MBXFB_FMT_Y0UY1V:
391 vsctrl |= VSCTRL_VPIXFMT_Y0UY1V;
392 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
393 break;
394 case MBXFB_FMT_Y0VY1U:
395 vsctrl |= VSCTRL_VPIXFMT_Y0VY1U;
396 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
380 break; 397 break;
381 case MBXFB_FMT_UY0VY1: 398 default:
382 vsctrl |= VSCTRL_VPIXFMT_UY0VY1; 399 return -EINVAL;
383 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
384 break;
385 case MBXFB_FMT_VY0UY1:
386 vsctrl |= VSCTRL_VPIXFMT_VY0UY1;
387 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
388 break;
389 case MBXFB_FMT_Y0UY1V:
390 vsctrl |= VSCTRL_VPIXFMT_Y0UY1V;
391 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
392 break;
393 case MBXFB_FMT_Y0VY1U:
394 vsctrl |= VSCTRL_VPIXFMT_Y0VY1U;
395 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
396 break;
397 default:
398 return -EINVAL;
399 } 400 }
400 401
401 /* VSCTRL has the bits which sets the Video Pixel Format. 402 /* VSCTRL has the bits which sets the Video Pixel Format.
@@ -417,8 +418,7 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
417 (0x60000 + set->mem_offset + set->V_offset)>>3); 418 (0x60000 + set->mem_offset + set->V_offset)>>3);
418 419
419 420
420 vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_GLOB | 421 vscadr |= Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4);
421 Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4);
422 422
423 if (set->enable) 423 if (set->enable)
424 vscadr |= VSCADR_STR_EN; 424 vscadr |= VSCADR_STR_EN;
@@ -433,9 +433,8 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
433 433
434 spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP | 434 spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP |
435 SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C | 435 SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C |
436 FMsk(SPOCTRL_VORDER) | FMsk(SPOCTRL_VPITCH)); 436 FMsk(SPOCTRL_VPITCH));
437 spoctrl = Spoctrl_Vpitch((set->height<<11)/set->scaled_height) 437 spoctrl |= Spoctrl_Vpitch((set->height<<11)/set->scaled_height);
438 | SPOCTRL_VORDER_2TAP;
439 438
440 /* Bypass horiz/vert scaler when same size */ 439 /* Bypass horiz/vert scaler when same size */
441 if (set->scaled_width == set->width) 440 if (set->scaled_width == set->width)
@@ -443,14 +442,11 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
443 if (set->scaled_height == set->height) 442 if (set->scaled_height == set->height)
444 spoctrl |= SPOCTRL_V_SC_BP; 443 spoctrl |= SPOCTRL_V_SC_BP;
445 444
446 svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10); 445 shctrl &= ~(FMsk(SHCTRL_HPITCH) | SHCTRL_HDECIM);
447 446 shctrl |= Shctrl_Hpitch((set->width<<11)/set->scaled_width);
448 shctrl = Shctrl_Hinitial(4<<11)
449 | Shctrl_Hpitch((set->width<<11)/set->scaled_width);
450 447
451 /* Video plane registers */ 448 /* Video plane registers */
452 write_reg(vsctrl, VSCTRL); 449 write_reg(vsctrl, VSCTRL);
453 write_reg(vbbase, VBBASE);
454 write_reg(vscadr, VSCADR); 450 write_reg(vscadr, VSCADR);
455 write_reg(vubase, VUBASE); 451 write_reg(vubase, VUBASE);
456 write_reg(vvbase, VVBASE); 452 write_reg(vvbase, VVBASE);
@@ -459,28 +455,8 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
459 /* Video scaler registers */ 455 /* Video scaler registers */
460 write_reg(sssize, SSSIZE); 456 write_reg(sssize, SSSIZE);
461 write_reg(spoctrl, SPOCTRL); 457 write_reg(spoctrl, SPOCTRL);
462 write_reg(svctrl, SVCTRL);
463 write_reg(shctrl, SHCTRL); 458 write_reg(shctrl, SHCTRL);
464 459
465 /* RAPH: Using those coefficients, the scaled
466 * image is quite blurry. I dont know how
467 * to improve them ; The chip documentation
468 * was not helpful.. */
469 write_reg(0x21212121, VSCOEFF0);
470 write_reg(0x21212121, VSCOEFF1);
471 write_reg(0x21212121, VSCOEFF2);
472 write_reg(0x21212121, VSCOEFF3);
473 write_reg(0x21212121, VSCOEFF4);
474 write_reg(0x00000000, HSCOEFF0);
475 write_reg(0x00000000, HSCOEFF1);
476 write_reg(0x00000000, HSCOEFF2);
477 write_reg(0x03020201, HSCOEFF3);
478 write_reg(0x09070604, HSCOEFF4);
479 write_reg(0x0f0e0c0a, HSCOEFF5);
480 write_reg(0x15141211, HSCOEFF6);
481 write_reg(0x19181716, HSCOEFF7);
482 write_reg(0x00000019, HSCOEFF8);
483
484 /* Clock */ 460 /* Clock */
485 if (set->enable) 461 if (set->enable)
486 vovrclk |= 1; 462 vovrclk |= 1;
@@ -492,27 +468,206 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
492 return 0; 468 return 0;
493} 469}
494 470
471static int mbxfb_ioctl_planeorder(struct mbxfb_planeorder *porder)
472{
473 unsigned long gscadr, vscadr;
474
475 if (porder->bottom == porder->top)
476 return -EINVAL;
477
478 gscadr = readl(GSCADR);
479 vscadr = readl(VSCADR);
480
481 gscadr &= ~(FMsk(GSCADR_BLEND_POS));
482 vscadr &= ~(FMsk(VSCADR_BLEND_POS));
483
484 switch (porder->bottom) {
485 case MBXFB_PLANE_GRAPHICS:
486 gscadr |= GSCADR_BLEND_GFX;
487 break;
488 case MBXFB_PLANE_VIDEO:
489 vscadr |= VSCADR_BLEND_GFX;
490 break;
491 default:
492 return -EINVAL;
493 }
494
495 switch (porder->top) {
496 case MBXFB_PLANE_GRAPHICS:
497 gscadr |= GSCADR_BLEND_VID;
498 break;
499 case MBXFB_PLANE_VIDEO:
500 vscadr |= GSCADR_BLEND_VID;
501 break;
502 default:
503 return -EINVAL;
504 }
505
506 write_reg_dly(vscadr, VSCADR);
507 write_reg_dly(gscadr, GSCADR);
508
509 return 0;
510
511}
512
513static int mbxfb_ioctl_alphactl(struct mbxfb_alphaCtl *alpha)
514{
515 unsigned long vscadr, vbbase, vcmsk;
516 unsigned long gscadr, gbbase, gdrctrl;
517
518 vbbase = Vbbase_Glalpha(alpha->overlay_global_alpha) |
519 Vbbase_Colkey(alpha->overlay_colorkey);
520
521 gbbase = Gbbase_Glalpha(alpha->graphics_global_alpha) |
522 Gbbase_Colkey(alpha->graphics_colorkey);
523
524 vcmsk = readl(VCMSK);
525 vcmsk &= ~(FMsk(VCMSK_COLKEY_M));
526 vcmsk |= Vcmsk_colkey_m(alpha->overlay_colorkey_mask);
527
528 gdrctrl = readl(GDRCTRL);
529 gdrctrl &= ~(FMsk(GDRCTRL_COLKEYM));
530 gdrctrl |= Gdrctrl_Colkeym(alpha->graphics_colorkey_mask);
531
532 vscadr = readl(VSCADR);
533 vscadr &= ~(FMsk(VSCADR_BLEND_M) | VSCADR_COLKEYSRC | VSCADR_COLKEY_EN);
534
535 gscadr = readl(GSCADR);
536 gscadr &= ~(FMsk(GSCADR_BLEND_M) | GSCADR_COLKEY_EN | GSCADR_COLKEYSRC);
537
538 switch (alpha->overlay_colorkey_mode) {
539 case MBXFB_COLORKEY_DISABLED:
540 break;
541 case MBXFB_COLORKEY_PREVIOUS:
542 vscadr |= VSCADR_COLKEY_EN;
543 break;
544 case MBXFB_COLORKEY_CURRENT:
545 vscadr |= VSCADR_COLKEY_EN | VSCADR_COLKEYSRC;
546 break;
547 default:
548 return -EINVAL;
549 }
550
551 switch (alpha->overlay_blend_mode) {
552 case MBXFB_ALPHABLEND_NONE:
553 vscadr |= VSCADR_BLEND_NONE;
554 break;
555 case MBXFB_ALPHABLEND_GLOBAL:
556 vscadr |= VSCADR_BLEND_GLOB;
557 break;
558 case MBXFB_ALPHABLEND_PIXEL:
559 vscadr |= VSCADR_BLEND_PIX;
560 break;
561 default:
562 return -EINVAL;
563 }
564
565 switch (alpha->graphics_colorkey_mode) {
566 case MBXFB_COLORKEY_DISABLED:
567 break;
568 case MBXFB_COLORKEY_PREVIOUS:
569 gscadr |= GSCADR_COLKEY_EN;
570 break;
571 case MBXFB_COLORKEY_CURRENT:
572 gscadr |= GSCADR_COLKEY_EN | GSCADR_COLKEYSRC;
573 break;
574 default:
575 return -EINVAL;
576 }
577
578 switch (alpha->graphics_blend_mode) {
579 case MBXFB_ALPHABLEND_NONE:
580 gscadr |= GSCADR_BLEND_NONE;
581 break;
582 case MBXFB_ALPHABLEND_GLOBAL:
583 gscadr |= GSCADR_BLEND_GLOB;
584 break;
585 case MBXFB_ALPHABLEND_PIXEL:
586 gscadr |= GSCADR_BLEND_PIX;
587 break;
588 default:
589 return -EINVAL;
590 }
591
592 write_reg_dly(vbbase, VBBASE);
593 write_reg_dly(gbbase, GBBASE);
594 write_reg_dly(vcmsk, VCMSK);
595 write_reg_dly(gdrctrl, GDRCTRL);
596 write_reg_dly(gscadr, GSCADR);
597 write_reg_dly(vscadr, VSCADR);
598
599 return 0;
600}
601
495static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd, 602static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,
496 unsigned long arg) 603 unsigned long arg)
497{ 604{
498 struct mbxfb_overlaySetup setup; 605 struct mbxfb_overlaySetup setup;
606 struct mbxfb_planeorder porder;
607 struct mbxfb_alphaCtl alpha;
608 struct mbxfb_reg reg;
499 int res; 609 int res;
610 __u32 tmp;
500 611
501 if (cmd == MBXFB_IOCX_OVERLAY) 612 switch (cmd)
502 { 613 {
503 if (copy_from_user(&setup, (void __user*)arg, 614 case MBXFB_IOCX_OVERLAY:
504 sizeof(struct mbxfb_overlaySetup))) 615 if (copy_from_user(&setup, (void __user*)arg,
616 sizeof(struct mbxfb_overlaySetup)))
617 return -EFAULT;
618
619 res = mbxfb_setupOverlay(&setup);
620 if (res)
621 return res;
622
623 if (copy_to_user((void __user*)arg, &setup,
624 sizeof(struct mbxfb_overlaySetup)))
625 return -EFAULT;
626
627 return 0;
628
629 case MBXFB_IOCS_PLANEORDER:
630 if (copy_from_user(&porder, (void __user*)arg,
631 sizeof(struct mbxfb_planeorder)))
505 return -EFAULT; 632 return -EFAULT;
506 633
507 res = mbxfb_setupOverlay(&setup); 634 return mbxfb_ioctl_planeorder(&porder);
508 if (res)
509 return res;
510 635
511 if (copy_to_user((void __user*)arg, &setup, 636 case MBXFB_IOCS_ALPHA:
512 sizeof(struct mbxfb_overlaySetup))) 637 if (copy_from_user(&alpha, (void __user*)arg,
638 sizeof(struct mbxfb_alphaCtl)))
513 return -EFAULT; 639 return -EFAULT;
514 640
515 return 0; 641 return mbxfb_ioctl_alphactl(&alpha);
642
643 case MBXFB_IOCS_REG:
644 if (copy_from_user(&reg, (void __user*)arg,
645 sizeof(struct mbxfb_reg)))
646 return -EFAULT;
647
648 if (reg.addr >= 0x10000) /* regs are from 0x3fe0000 to 0x3feffff */
649 return -EINVAL;
650
651 tmp = readl(virt_base_2700 + reg.addr);
652 tmp &= ~reg.mask;
653 tmp |= reg.val & reg.mask;
654 writel(tmp, virt_base_2700 + reg.addr);
655
656 return 0;
657 case MBXFB_IOCX_REG:
658 if (copy_from_user(&reg, (void __user*)arg,
659 sizeof(struct mbxfb_reg)))
660 return -EFAULT;
661
662 if (reg.addr >= 0x10000) /* regs are from 0x3fe0000 to 0x3feffff */
663 return -EINVAL;
664 reg.val = readl(virt_base_2700 + reg.addr);
665
666 if (copy_to_user((void __user*)arg, &reg,
667 sizeof(struct mbxfb_reg)))
668 return -EFAULT;
669
670 return 0;
516 } 671 }
517 return -EINVAL; 672 return -EINVAL;
518} 673}
@@ -558,7 +713,6 @@ static void __devinit setup_memc(struct fb_info *fbi)
558 LMTYPE); 713 LMTYPE);
559 /* enable memory controller */ 714 /* enable memory controller */
560 write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR); 715 write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);
561
562 /* perform dummy reads */ 716 /* perform dummy reads */
563 for ( i = 0; i < 16; i++ ) { 717 for ( i = 0; i < 16; i++ ) {
564 tmp = readl(fbi->screen_base); 718 tmp = readl(fbi->screen_base);
@@ -588,8 +742,8 @@ static void enable_clocks(struct fb_info *fbi)
588 write_reg_dly(0x00000000, VOVRCLK); 742 write_reg_dly(0x00000000, VOVRCLK);
589 write_reg_dly(PIXCLK_EN, PIXCLK); 743 write_reg_dly(PIXCLK_EN, PIXCLK);
590 write_reg_dly(MEMCLK_EN, MEMCLK); 744 write_reg_dly(MEMCLK_EN, MEMCLK);
591 write_reg_dly(0x00000006, M24CLK); 745 write_reg_dly(0x00000001, M24CLK);
592 write_reg_dly(0x00000006, MBXCLK); 746 write_reg_dly(0x00000001, MBXCLK);
593 write_reg_dly(SDCLK_EN, SDCLK); 747 write_reg_dly(SDCLK_EN, SDCLK);
594 write_reg_dly(0x00000001, PIXCLKDIV); 748 write_reg_dly(0x00000001, PIXCLKDIV);
595} 749}
@@ -597,6 +751,7 @@ static void enable_clocks(struct fb_info *fbi)
597static void __devinit setup_graphics(struct fb_info *fbi) 751static void __devinit setup_graphics(struct fb_info *fbi)
598{ 752{
599 unsigned long gsctrl; 753 unsigned long gsctrl;
754 unsigned long vscadr;
600 755
601 gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) | 756 gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) |
602 Gsctrl_Height(fbi->var.yres); 757 Gsctrl_Height(fbi->var.yres);
@@ -620,6 +775,11 @@ static void __devinit setup_graphics(struct fb_info *fbi)
620 write_reg_dly(0x00ffffff, GDRCTRL); 775 write_reg_dly(0x00ffffff, GDRCTRL);
621 write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR); 776 write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
622 write_reg_dly(0x00000000, GPLUT); 777 write_reg_dly(0x00000000, GPLUT);
778
779 vscadr = readl(VSCADR);
780 vscadr &= ~(FMsk(VSCADR_BLEND_POS) | FMsk(VSCADR_BLEND_M));
781 vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_NONE;
782 write_reg_dly(vscadr, VSCADR);
623} 783}
624 784
625static void __devinit setup_display(struct fb_info *fbi) 785static void __devinit setup_display(struct fb_info *fbi)
@@ -638,13 +798,47 @@ static void __devinit setup_display(struct fb_info *fbi)
638 798
639static void __devinit enable_controller(struct fb_info *fbi) 799static void __devinit enable_controller(struct fb_info *fbi)
640{ 800{
801 u32 svctrl, shctrl;
802
641 write_reg_dly(SYSRST_RST, SYSRST); 803 write_reg_dly(SYSRST_RST, SYSRST);
642 804
805 /* setup a timeout, raise drive strength */
806 write_reg_dly(0xffffff0c, SYSCFG);
643 807
644 enable_clocks(fbi); 808 enable_clocks(fbi);
645 setup_memc(fbi); 809 setup_memc(fbi);
646 setup_graphics(fbi); 810 setup_graphics(fbi);
647 setup_display(fbi); 811 setup_display(fbi);
812
813 shctrl = readl(SHCTRL);
814 shctrl &= ~(FMsk(SHCTRL_HINITIAL));
815 shctrl |= Shctrl_Hinitial(4<<11);
816 writel(shctrl, SHCTRL);
817
818 svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10);
819 writel(svctrl, SVCTRL);
820
821 writel(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP | SPOCTRL_VORDER_4TAP
822 , SPOCTRL);
823
824 /* Those coefficients are good for scaling up. For scaling
825 * down, the application has to calculate them. */
826 write_reg(0xff000100, VSCOEFF0);
827 write_reg(0xfdfcfdfe, VSCOEFF1);
828 write_reg(0x170d0500, VSCOEFF2);
829 write_reg(0x3d372d22, VSCOEFF3);
830 write_reg(0x00000040, VSCOEFF4);
831
832 write_reg(0xff010100, HSCOEFF0);
833 write_reg(0x00000000, HSCOEFF1);
834 write_reg(0x02010000, HSCOEFF2);
835 write_reg(0x01020302, HSCOEFF3);
836 write_reg(0xf9fbfe00, HSCOEFF4);
837 write_reg(0xfbf7f6f7, HSCOEFF5);
838 write_reg(0x1c110700, HSCOEFF6);
839 write_reg(0x3e393127, HSCOEFF7);
840 write_reg(0x00000040, HSCOEFF8);
841
648} 842}
649 843
650#ifdef CONFIG_PM 844#ifdef CONFIG_PM
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h
index 9a24fb0c7d48..5f14b4befd71 100644
--- a/drivers/video/mbx/reg_bits.h
+++ b/drivers/video/mbx/reg_bits.h
@@ -215,7 +215,7 @@
215/* GSCADR graphics stream control address register fields */ 215/* GSCADR graphics stream control address register fields */
216#define GSCADR_STR_EN (1 << 31) 216#define GSCADR_STR_EN (1 << 31)
217#define GSCADR_COLKEY_EN (1 << 30) 217#define GSCADR_COLKEY_EN (1 << 30)
218#define GSCADR_COLKEYSCR (1 << 29) 218#define GSCADR_COLKEYSRC (1 << 29)
219#define GSCADR_BLEND_M Fld(2,27) 219#define GSCADR_BLEND_M Fld(2,27)
220#define GSCADR_BLEND_NONE ((0x0) << FShft(GSCADR_BLEND_M)) 220#define GSCADR_BLEND_NONE ((0x0) << FShft(GSCADR_BLEND_M))
221#define GSCADR_BLEND_INV ((0x1) << FShft(GSCADR_BLEND_M)) 221#define GSCADR_BLEND_INV ((0x1) << FShft(GSCADR_BLEND_M))
@@ -303,6 +303,67 @@
303#define VSADR_YSTART Fld(11,0) 303#define VSADR_YSTART Fld(11,0)
304#define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART)) 304#define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART))
305 305
306/* VSCTRL - Video Surface Control Register */
307#define VSCTRL_VPIXFMT Fld(4,27)
308#define VSCTRL_VPIXFMT_YUV12 ((0x9) << FShft(VSCTRL_VPIXFMT))
309#define VSCTRL_VPIXFMT_UY0VY1 ((0xc) << FShft(VSCTRL_VPIXFMT))
310#define VSCTRL_VPIXFMT_VY0UY1 ((0xd) << FShft(VSCTRL_VPIXFMT))
311#define VSCTRL_VPIXFMT_Y0UY1V ((0xe) << FShft(VSCTRL_VPIXFMT))
312#define VSCTRL_VPIXFMT_Y0VY1U ((0xf) << FShft(VSCTRL_VPIXFMT))
313#define VSCTRL_GAMMA_EN (1 << 26)
314#define VSCTRL_CSC_EN (1 << 25)
315#define VSCTRL_COSITED (1 << 22)
316#define VSCTRL_VSWIDTH Fld(11,11)
317#define Vsctrl_Width(Pixels) /* Video Width [1-2048] */ \
318 (((Pixels) - 1) << FShft(VSCTRL_VSWIDTH))
319#define VSCTRL_VSHEIGHT Fld(11,0)
320#define Vsctrl_Height(Pixels) /* Video Height [1-2048] */ \
321 (((Pixels) - 1) << FShft(VSCTRL_VSHEIGHT))
322
323/* VBBASE - Video Blending Base Register */
324#define VBBASE_GLALPHA Fld(8,24)
325#define Vbbase_Glalpha(x) ((x) << FShft(VBBASE_GLALPHA))
326
327#define VBBASE_COLKEY Fld(24,0)
328#define Vbbase_Colkey(x) ((x) << FShft(VBBASE_COLKEY))
329
330/* VCMSK - Video Color Key Mask Register */
331#define VCMSK_COLKEY_M Fld(24,0)
332#define Vcmsk_colkey_m(x) ((x) << FShft(VCMSK_COLKEY_M))
333
334/* VSCADR - Video Stream Control Rddress Register */
335#define VSCADR_STR_EN (1 << 31)
336#define VSCADR_COLKEY_EN (1 << 30)
337#define VSCADR_COLKEYSRC (1 << 29)
338#define VSCADR_BLEND_M Fld(2,27)
339#define VSCADR_BLEND_NONE ((0x0) << FShft(VSCADR_BLEND_M))
340#define VSCADR_BLEND_INV ((0x1) << FShft(VSCADR_BLEND_M))
341#define VSCADR_BLEND_GLOB ((0x2) << FShft(VSCADR_BLEND_M))
342#define VSCADR_BLEND_PIX ((0x3) << FShft(VSCADR_BLEND_M))
343#define VSCADR_BLEND_POS Fld(2,24)
344#define VSCADR_BLEND_GFX ((0x0) << FShft(VSCADR_BLEND_POS))
345#define VSCADR_BLEND_VID ((0x1) << FShft(VSCADR_BLEND_POS))
346#define VSCADR_BLEND_CUR ((0x2) << FShft(VSCADR_BLEND_POS))
347#define VSCADR_VBASE_ADR Fld(23,0)
348#define Vscadr_Vbase_Adr(x) ((x) << FShft(VSCADR_VBASE_ADR))
349
350/* VUBASE - Video U Base Register */
351#define VUBASE_UVHALFSTR (1 << 31)
352#define VUBASE_UBASE_ADR Fld(24,0)
353#define Vubase_Ubase_Adr(x) ((x) << FShft(VUBASE_UBASE_ADR))
354
355/* VVBASE - Video V Base Register */
356#define VVBASE_VBASE_ADR Fld(24,0)
357#define Vvbase_Vbase_Adr(x) ((x) << FShft(VVBASE_VBASE_ADR))
358
359/* VSADR - Video Stride Address Register */
360#define VSADR_SRCSTRIDE Fld(10,22)
361#define Vsadr_Srcstride(x) ((x) << FShft(VSADR_SRCSTRIDE))
362#define VSADR_XSTART Fld(11,11)
363#define Vsadr_Xstart(x) ((x) << FShft(VSADR_XSTART))
364#define VSADR_YSTART Fld(11,0)
365#define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART))
366
306/* HCCTRL - Hardware Cursor Register fields */ 367/* HCCTRL - Hardware Cursor Register fields */
307#define HCCTRL_CUR_EN (1 << 31) 368#define HCCTRL_CUR_EN (1 << 31)
308#define HCCTRL_COLKEY_EN (1 << 29) 369#define HCCTRL_COLKEY_EN (1 << 29)
@@ -479,6 +540,30 @@
479#define DINTRE_HBLNK1_EN (1 << 1) 540#define DINTRE_HBLNK1_EN (1 << 1)
480#define DINTRE_HBLNK0_EN (1 << 0) 541#define DINTRE_HBLNK0_EN (1 << 0)
481 542
543/* DINTRS - Display Interrupt Status Register */
544#define DINTRS_CUR_OR_S (1 << 18)
545#define DINTRS_STR2_OR_S (1 << 17)
546#define DINTRS_STR1_OR_S (1 << 16)
547#define DINTRS_CUR_UR_S (1 << 6)
548#define DINTRS_STR2_UR_S (1 << 5)
549#define DINTRS_STR1_UR_S (1 << 4)
550#define DINTRS_VEVENT1_S (1 << 3)
551#define DINTRS_VEVENT0_S (1 << 2)
552#define DINTRS_HBLNK1_S (1 << 1)
553#define DINTRS_HBLNK0_S (1 << 0)
554
555/* DINTRE - Display Interrupt Enable Register */
556#define DINTRE_CUR_OR_EN (1 << 18)
557#define DINTRE_STR2_OR_EN (1 << 17)
558#define DINTRE_STR1_OR_EN (1 << 16)
559#define DINTRE_CUR_UR_EN (1 << 6)
560#define DINTRE_STR2_UR_EN (1 << 5)
561#define DINTRE_STR1_UR_EN (1 << 4)
562#define DINTRE_VEVENT1_EN (1 << 3)
563#define DINTRE_VEVENT0_EN (1 << 2)
564#define DINTRE_HBLNK1_EN (1 << 1)
565#define DINTRE_HBLNK0_EN (1 << 0)
566
482 567
483/* DLSTS - display load status register */ 568/* DLSTS - display load status register */
484#define DLSTS_RLD_ADONE (1 << 23) 569#define DLSTS_RLD_ADONE (1 << 23)
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h
index a7c63d865aad..063099d48839 100644
--- a/drivers/video/mbx/regs.h
+++ b/drivers/video/mbx/regs.h
@@ -30,7 +30,7 @@
30#define VOVRCLK __REG_2700G(0x00000044) 30#define VOVRCLK __REG_2700G(0x00000044)
31#define PIXCLK __REG_2700G(0x00000048) 31#define PIXCLK __REG_2700G(0x00000048)
32#define MEMCLK __REG_2700G(0x0000004c) 32#define MEMCLK __REG_2700G(0x0000004c)
33#define M24CLK __REG_2700G(0x00000054) 33#define M24CLK __REG_2700G(0x00000050)
34#define MBXCLK __REG_2700G(0x00000054) 34#define MBXCLK __REG_2700G(0x00000054)
35#define SDCLK __REG_2700G(0x00000058) 35#define SDCLK __REG_2700G(0x00000058)
36#define PIXCLKDIV __REG_2700G(0x0000005c) 36#define PIXCLKDIV __REG_2700G(0x0000005c)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 3741ad729401..42f5d76a8777 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -27,7 +27,7 @@
27#define DPRINTK(fmt, args...) 27#define DPRINTK(fmt, args...)
28#endif 28#endif
29 29
30const char *global_mode_option; 30const char *fb_mode_option;
31 31
32 /* 32 /*
33 * Standard video mode definitions (taken from XFree86) 33 * Standard video mode definitions (taken from XFree86)
@@ -72,7 +72,7 @@ static const struct fb_videomode modedb[] = {
72 0, FB_VMODE_NONINTERLACED 72 0, FB_VMODE_NONINTERLACED
73 }, { 73 }, {
74 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ 74 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
75 NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, 75 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
76 0, FB_VMODE_INTERLACED 76 0, FB_VMODE_INTERLACED
77 }, { 77 }, {
78 /* 800x600 @ 72 Hz, 48.0 kHz hsync */ 78 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
@@ -120,11 +120,11 @@ static const struct fb_videomode modedb[] = {
120 0, FB_VMODE_NONINTERLACED 120 0, FB_VMODE_NONINTERLACED
121 }, { 121 }, {
122 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */ 122 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
123 NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, 123 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
124 0, FB_VMODE_NONINTERLACED 124 0, FB_VMODE_NONINTERLACED
125 }, { 125 }, {
126 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ 126 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
127 NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3, 127 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
128 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 128 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
129 }, { 129 }, {
130 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ 130 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
@@ -253,7 +253,7 @@ static const struct fb_videomode modedb[] = {
253 FB_VMODE_NONINTERLACED 253 FB_VMODE_NONINTERLACED
254 }, { 254 }, {
255 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */ 255 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
256 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6, 256 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
257 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 257 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
258 }, { 258 }, {
259 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */ 259 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
@@ -306,7 +306,7 @@ const struct fb_videomode vesa_modes[] = {
306 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 306 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
307 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 307 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
308 /* 12 1024x768i-43 VESA */ 308 /* 12 1024x768i-43 VESA */
309 { NULL, 53, 1024, 768, 22271, 56, 8, 41, 0, 176, 8, 309 { NULL, 43, 1024, 768, 22271, 56, 8, 41, 0, 176, 8,
310 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 310 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
311 FB_VMODE_INTERLACED, FB_MODE_IS_VESA }, 311 FB_VMODE_INTERLACED, FB_MODE_IS_VESA },
312 /* 13 1024x768-60 VESA */ 312 /* 13 1024x768-60 VESA */
@@ -383,7 +383,7 @@ const struct fb_videomode vesa_modes[] = {
383 { NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 200, 3, 383 { NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 200, 3,
384 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 384 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
385 /* 33 1920x1440-75 VESA */ 385 /* 33 1920x1440-75 VESA */
386 { NULL, 60, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3, 386 { NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
387 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 387 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
388}; 388};
389EXPORT_SYMBOL(vesa_modes); 389EXPORT_SYMBOL(vesa_modes);
@@ -510,7 +510,7 @@ int fb_find_mode(struct fb_var_screeninfo *var,
510 default_bpp = 8; 510 default_bpp = 8;
511 511
512 /* Did the user specify a video mode? */ 512 /* Did the user specify a video mode? */
513 if (mode_option || (mode_option = global_mode_option)) { 513 if (mode_option || (mode_option = fb_mode_option)) {
514 const char *name = mode_option; 514 const char *name = mode_option;
515 unsigned int namelen = strlen(name); 515 unsigned int namelen = strlen(name);
516 int res_specified = 0, bpp_specified = 0, refresh_specified = 0; 516 int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
@@ -606,26 +606,43 @@ done:
606 DPRINTK("Trying specified video mode%s %ix%i\n", 606 DPRINTK("Trying specified video mode%s %ix%i\n",
607 refresh_specified ? "" : " (ignoring refresh rate)", xres, yres); 607 refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
608 608
609 diff = refresh; 609 if (!refresh_specified) {
610 /*
611 * If the caller has provided a custom mode database and a
612 * valid monspecs structure, we look for the mode with the
613 * highest refresh rate. Otherwise we play it safe it and
614 * try to find a mode with a refresh rate closest to the
615 * standard 60 Hz.
616 */
617 if (db != modedb &&
618 info->monspecs.vfmin && info->monspecs.vfmax &&
619 info->monspecs.hfmin && info->monspecs.hfmax &&
620 info->monspecs.dclkmax) {
621 refresh = 1000;
622 } else {
623 refresh = 60;
624 }
625 }
626
627 diff = -1;
610 best = -1; 628 best = -1;
611 for (i = 0; i < dbsize; i++) { 629 for (i = 0; i < dbsize; i++) {
612 if (name_matches(db[i], name, namelen) || 630 if ((name_matches(db[i], name, namelen) ||
613 (res_specified && res_matches(db[i], xres, yres))) { 631 (res_specified && res_matches(db[i], xres, yres))) &&
614 if(!fb_try_mode(var, info, &db[i], bpp)) { 632 !fb_try_mode(var, info, &db[i], bpp)) {
615 if(!refresh_specified || db[i].refresh == refresh) 633 if (refresh_specified && db[i].refresh == refresh) {
616 return 1; 634 return 1;
617 else { 635 } else {
618 if(diff > abs(db[i].refresh - refresh)) { 636 if (abs(db[i].refresh - refresh) < diff) {
619 diff = abs(db[i].refresh - refresh); 637 diff = abs(db[i].refresh - refresh);
620 best = i; 638 best = i;
621 }
622 } 639 }
623 } 640 }
624 } 641 }
625 } 642 }
626 if (best != -1) { 643 if (best != -1) {
627 fb_try_mode(var, info, &db[best], bpp); 644 fb_try_mode(var, info, &db[best], bpp);
628 return 2; 645 return (refresh_specified) ? 2 : 1;
629 } 646 }
630 647
631 diff = xres + yres; 648 diff = xres + yres;
@@ -938,6 +955,7 @@ void fb_destroy_modelist(struct list_head *head)
938 kfree(pos); 955 kfree(pos);
939 } 956 }
940} 957}
958EXPORT_SYMBOL_GPL(fb_destroy_modelist);
941 959
942/** 960/**
943 * fb_videomode_to_modelist: convert mode array to mode list 961 * fb_videomode_to_modelist: convert mode array to mode list
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 731d7a5c5aa2..4b6a99b5be0d 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -72,7 +72,6 @@
72#include <asm/irq.h> 72#include <asm/irq.h>
73#include <asm/pgtable.h> 73#include <asm/pgtable.h>
74#include <asm/system.h> 74#include <asm/system.h>
75#include <asm/uaccess.h>
76 75
77#ifdef CONFIG_MTRR 76#ifdef CONFIG_MTRR
78#include <asm/mtrr.h> 77#include <asm/mtrr.h>
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index afe4567e1ff4..6fd7cb8f9b8e 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -125,11 +125,13 @@ void nvidia_create_i2c_busses(struct nvidia_par *par)
125 par->chan[1].par = par; 125 par->chan[1].par = par;
126 par->chan[2].par = par; 126 par->chan[2].par = par;
127 127
128 par->chan[0].ddc_base = 0x36; 128 par->chan[0].ddc_base = (par->reverse_i2c) ? 0x36 : 0x3e;
129 nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0", I2C_CLASS_HWMON); 129 nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0",
130 (par->reverse_i2c) ? I2C_CLASS_HWMON : 0);
130 131
131 par->chan[1].ddc_base = 0x3e; 132 par->chan[1].ddc_base = (par->reverse_i2c) ? 0x3e : 0x36;
132 nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1", 0); 133 nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1",
134 (par->reverse_i2c) ? 0 : I2C_CLASS_HWMON);
133 135
134 par->chan[2].ddc_base = 0x50; 136 par->chan[2].ddc_base = 0x50;
135 nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2", 0); 137 nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2", 0);
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index 2fdf77ec39fc..f132aab8c5de 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -135,6 +135,7 @@ struct nvidia_par {
135 int paneltweak; 135 int paneltweak;
136 int LVDS; 136 int LVDS;
137 int pm_state; 137 int pm_state;
138 int reverse_i2c;
138 u32 crtcSync_read; 139 u32 crtcSync_read;
139 u32 fpSyncs; 140 u32 fpSyncs;
140 u32 dmaPut; 141 u32 dmaPut;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index a7fe214f0f77..30e14eb1f51e 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -79,6 +79,7 @@ static int noscale __devinitdata = 0;
79static int paneltweak __devinitdata = 0; 79static int paneltweak __devinitdata = 0;
80static int vram __devinitdata = 0; 80static int vram __devinitdata = 0;
81static int bpp __devinitdata = 8; 81static int bpp __devinitdata = 8;
82static int reverse_i2c __devinitdata;
82#ifdef CONFIG_MTRR 83#ifdef CONFIG_MTRR
83static int nomtrr __devinitdata = 0; 84static int nomtrr __devinitdata = 0;
84#endif 85#endif
@@ -1305,6 +1306,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1305 par->CRTCnumber = forceCRTC; 1306 par->CRTCnumber = forceCRTC;
1306 par->FpScale = (!noscale); 1307 par->FpScale = (!noscale);
1307 par->paneltweak = paneltweak; 1308 par->paneltweak = paneltweak;
1309 par->reverse_i2c = reverse_i2c;
1308 1310
1309 /* enable IO and mem if not already done */ 1311 /* enable IO and mem if not already done */
1310 pci_read_config_word(pd, PCI_COMMAND, &cmd); 1312 pci_read_config_word(pd, PCI_COMMAND, &cmd);
@@ -1486,6 +1488,8 @@ static int __devinit nvidiafb_setup(char *options)
1486 noaccel = 1; 1488 noaccel = 1;
1487 } else if (!strncmp(this_opt, "noscale", 7)) { 1489 } else if (!strncmp(this_opt, "noscale", 7)) {
1488 noscale = 1; 1490 noscale = 1;
1491 } else if (!strncmp(this_opt, "reverse_i2c", 11)) {
1492 reverse_i2c = 1;
1489 } else if (!strncmp(this_opt, "paneltweak:", 11)) { 1493 } else if (!strncmp(this_opt, "paneltweak:", 11)) {
1490 paneltweak = simple_strtoul(this_opt+11, NULL, 0); 1494 paneltweak = simple_strtoul(this_opt+11, NULL, 0);
1491 } else if (!strncmp(this_opt, "vram:", 5)) { 1495 } else if (!strncmp(this_opt, "vram:", 5)) {
@@ -1582,6 +1586,8 @@ MODULE_PARM_DESC(mode_option, "Specify initial video mode");
1582module_param(bpp, int, 0); 1586module_param(bpp, int, 0);
1583MODULE_PARM_DESC(bpp, "pixel width in bits" 1587MODULE_PARM_DESC(bpp, "pixel width in bits"
1584 "(default=8)"); 1588 "(default=8)");
1589module_param(reverse_i2c, int, 0);
1590MODULE_PARM_DESC(reverse_i2c, "reverse port assignment of the i2c bus");
1585#ifdef CONFIG_MTRR 1591#ifdef CONFIG_MTRR
1586module_param(nomtrr, bool, 0); 1592module_param(nomtrr, bool, 0);
1587MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " 1593MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 10c0cc6e93fc..5591dfb22b18 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -11,7 +11,7 @@
11 * and additional input from James Simmon's port of Hannu Mallat's tdfx 11 * and additional input from James Simmon's port of Hannu Mallat's tdfx
12 * driver. 12 * driver.
13 * 13 *
14 * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86. I 14 * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86. I
15 * have no access to other pm2fb implementations. Sparc (and thus 15 * have no access to other pm2fb implementations. Sparc (and thus
16 * hopefully other big-endian) devices now work, thanks to a lot of 16 * hopefully other big-endian) devices now work, thanks to a lot of
17 * testing work by Ron Murray. I have no access to CVision hardware, 17 * testing work by Ron Murray. I have no access to CVision hardware,
@@ -38,6 +38,9 @@
38#include <linux/fb.h> 38#include <linux/fb.h>
39#include <linux/init.h> 39#include <linux/init.h>
40#include <linux/pci.h> 40#include <linux/pci.h>
41#ifdef CONFIG_MTRR
42#include <asm/mtrr.h>
43#endif
41 44
42#include <video/permedia2.h> 45#include <video/permedia2.h>
43#include <video/cvisionppc.h> 46#include <video/cvisionppc.h>
@@ -52,15 +55,19 @@
52 55
53#undef PM2FB_MASTER_DEBUG 56#undef PM2FB_MASTER_DEBUG
54#ifdef PM2FB_MASTER_DEBUG 57#ifdef PM2FB_MASTER_DEBUG
55#define DPRINTK(a,b...) printk(KERN_DEBUG "pm2fb: %s: " a, __FUNCTION__ , ## b) 58#define DPRINTK(a, b...) \
59 printk(KERN_DEBUG "pm2fb: %s: " a, __FUNCTION__ , ## b)
56#else 60#else
57#define DPRINTK(a,b...) 61#define DPRINTK(a, b...)
58#endif 62#endif
59 63
64#define PM2_PIXMAP_SIZE (1600 * 4)
65
60/* 66/*
61 * Driver data 67 * Driver data
62 */ 68 */
63static char *mode __devinitdata = NULL; 69static int hwcursor = 1;
70static char *mode __devinitdata;
64 71
65/* 72/*
66 * The XFree GLINT driver will (I think to implement hardware cursor 73 * The XFree GLINT driver will (I think to implement hardware cursor
@@ -73,6 +80,11 @@ static char *mode __devinitdata = NULL;
73 */ 80 */
74static int lowhsync; 81static int lowhsync;
75static int lowvsync; 82static int lowvsync;
83static int noaccel __devinitdata;
84/* mtrr option */
85#ifdef CONFIG_MTRR
86static int nomtrr __devinitdata;
87#endif
76 88
77/* 89/*
78 * The hardware state of the graphics card that isn't part of the 90 * The hardware state of the graphics card that isn't part of the
@@ -88,6 +100,7 @@ struct pm2fb_par
88 u32 mem_control; /* MemControl reg at probe */ 100 u32 mem_control; /* MemControl reg at probe */
89 u32 boot_address; /* BootAddress reg at probe */ 101 u32 boot_address; /* BootAddress reg at probe */
90 u32 palette[16]; 102 u32 palette[16];
103 int mtrr_handle;
91}; 104};
92 105
93/* 106/*
@@ -135,60 +148,39 @@ static struct fb_var_screeninfo pm2fb_var __devinitdata = {
135 * Utility functions 148 * Utility functions
136 */ 149 */
137 150
138static inline u32 RD32(unsigned char __iomem *base, s32 off) 151static inline u32 pm2_RD(struct pm2fb_par *p, s32 off)
139{
140 return fb_readl(base + off);
141}
142
143static inline void WR32(unsigned char __iomem *base, s32 off, u32 v)
144{ 152{
145 fb_writel(v, base + off); 153 return fb_readl(p->v_regs + off);
146} 154}
147 155
148static inline u32 pm2_RD(struct pm2fb_par* p, s32 off) 156static inline void pm2_WR(struct pm2fb_par *p, s32 off, u32 v)
149{ 157{
150 return RD32(p->v_regs, off); 158 fb_writel(v, p->v_regs + off);
151} 159}
152 160
153static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v) 161static inline u32 pm2_RDAC_RD(struct pm2fb_par *p, s32 idx)
154{ 162{
155 WR32(p->v_regs, off, v); 163 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
164 mb();
165 return pm2_RD(p, PM2R_RD_INDEXED_DATA);
156} 166}
157 167
158static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx) 168static inline u32 pm2v_RDAC_RD(struct pm2fb_par *p, s32 idx)
159{ 169{
160 int index = PM2R_RD_INDEXED_DATA; 170 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
161 switch (p->type) {
162 case PM2_TYPE_PERMEDIA2:
163 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
164 break;
165 case PM2_TYPE_PERMEDIA2V:
166 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
167 index = PM2VR_RD_INDEXED_DATA;
168 break;
169 }
170 mb(); 171 mb();
171 return pm2_RD(p, index); 172 return pm2_RD(p, PM2VR_RD_INDEXED_DATA);
172} 173}
173 174
174static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) 175static inline void pm2_RDAC_WR(struct pm2fb_par *p, s32 idx, u32 v)
175{ 176{
176 int index = PM2R_RD_INDEXED_DATA; 177 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
177 switch (p->type) {
178 case PM2_TYPE_PERMEDIA2:
179 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
180 break;
181 case PM2_TYPE_PERMEDIA2V:
182 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
183 index = PM2VR_RD_INDEXED_DATA;
184 break;
185 }
186 wmb(); 178 wmb();
187 pm2_WR(p, index, v); 179 pm2_WR(p, PM2R_RD_INDEXED_DATA, v);
188 wmb(); 180 wmb();
189} 181}
190 182
191static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) 183static inline void pm2v_RDAC_WR(struct pm2fb_par *p, s32 idx, u32 v)
192{ 184{
193 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff); 185 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
194 wmb(); 186 wmb();
@@ -199,10 +191,10 @@ static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
199#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT 191#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
200#define WAIT_FIFO(p, a) 192#define WAIT_FIFO(p, a)
201#else 193#else
202static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a) 194static inline void WAIT_FIFO(struct pm2fb_par *p, u32 a)
203{ 195{
204 while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a ); 196 while (pm2_RD(p, PM2R_IN_FIFO_SPACE) < a)
205 mb(); 197 cpu_relax();
206} 198}
207#endif 199#endif
208 200
@@ -238,7 +230,7 @@ static u32 partprod(u32 xres)
238 230
239 for (i = 0; pp_table[i].width && pp_table[i].width != xres; i++) 231 for (i = 0; pp_table[i].width && pp_table[i].width != xres; i++)
240 ; 232 ;
241 if ( pp_table[i].width == 0 ) 233 if (pp_table[i].width == 0)
242 DPRINTK("invalid width %u\n", xres); 234 DPRINTK("invalid width %u\n", xres);
243 return pp_table[i].pp; 235 return pp_table[i].pp;
244} 236}
@@ -246,25 +238,22 @@ static u32 partprod(u32 xres)
246static u32 to3264(u32 timing, int bpp, int is64) 238static u32 to3264(u32 timing, int bpp, int is64)
247{ 239{
248 switch (bpp) { 240 switch (bpp) {
241 case 24:
242 timing *= 3;
249 case 8: 243 case 8:
250 timing >>= 2 + is64; 244 timing >>= 1;
251 break;
252 case 16: 245 case 16:
253 timing >>= 1 + is64; 246 timing >>= 1;
254 break;
255 case 24:
256 timing = (timing * 3) >> (2 + is64);
257 break;
258 case 32: 247 case 32:
259 if (is64)
260 timing >>= 1;
261 break; 248 break;
262 } 249 }
250 if (is64)
251 timing >>= 1;
263 return timing; 252 return timing;
264} 253}
265 254
266static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn, 255static void pm2_mnp(u32 clk, unsigned char *mm, unsigned char *nn,
267 unsigned char* pp) 256 unsigned char *pp)
268{ 257{
269 unsigned char m; 258 unsigned char m;
270 unsigned char n; 259 unsigned char n;
@@ -278,13 +267,13 @@ static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
278 for (m = 2; m; m++) { 267 for (m = 2; m; m++) {
279 f = PM2_REFERENCE_CLOCK * m / n; 268 f = PM2_REFERENCE_CLOCK * m / n;
280 if (f >= 150000 && f <= 300000) { 269 if (f >= 150000 && f <= 300000) {
281 for ( p = 0; p < 5; p++, f >>= 1) { 270 for (p = 0; p < 5; p++, f >>= 1) {
282 curr = ( clk > f ) ? clk - f : f - clk; 271 curr = (clk > f) ? clk - f : f - clk;
283 if ( curr < delta ) { 272 if (curr < delta) {
284 delta=curr; 273 delta = curr;
285 *mm=m; 274 *mm = m;
286 *nn=n; 275 *nn = n;
287 *pp=p; 276 *pp = p;
288 } 277 }
289 } 278 }
290 } 279 }
@@ -292,8 +281,8 @@ static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
292 } 281 }
293} 282}
294 283
295static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn, 284static void pm2v_mnp(u32 clk, unsigned char *mm, unsigned char *nn,
296 unsigned char* pp) 285 unsigned char *pp)
297{ 286{
298 unsigned char m; 287 unsigned char m;
299 unsigned char n; 288 unsigned char n;
@@ -302,23 +291,24 @@ static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
302 s32 delta = 1000; 291 s32 delta = 1000;
303 292
304 *mm = *nn = *pp = 0; 293 *mm = *nn = *pp = 0;
305 for ( m = 1; m < 128; m++) { 294 for (m = 1; m < 128; m++) {
306 for (n = 2 * m + 1; n; n++) { 295 for (n = 2 * m + 1; n; n++) {
307 for ( p = 0; p < 2; p++) { 296 for (p = 0; p < 2; p++) {
308 f = ( PM2_REFERENCE_CLOCK >> ( p + 1 )) * n / m; 297 f = (PM2_REFERENCE_CLOCK >> (p + 1)) * n / m;
309 if ( clk > f - delta && clk < f + delta ) { 298 if (clk > f - delta && clk < f + delta) {
310 delta = ( clk > f ) ? clk - f : f - clk; 299 delta = (clk > f) ? clk - f : f - clk;
311 *mm=m; 300 *mm = m;
312 *nn=n; 301 *nn = n;
313 *pp=p; 302 *pp = p;
314 } 303 }
315 } 304 }
316 } 305 }
317 } 306 }
318} 307}
319 308
320static void clear_palette(struct pm2fb_par* p) { 309static void clear_palette(struct pm2fb_par *p)
321 int i=256; 310{
311 int i = 256;
322 312
323 WAIT_FIFO(p, 1); 313 WAIT_FIFO(p, 1);
324 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, 0); 314 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, 0);
@@ -331,14 +321,14 @@ static void clear_palette(struct pm2fb_par* p) {
331 } 321 }
332} 322}
333 323
334static void reset_card(struct pm2fb_par* p) 324static void reset_card(struct pm2fb_par *p)
335{ 325{
336 if (p->type == PM2_TYPE_PERMEDIA2V) 326 if (p->type == PM2_TYPE_PERMEDIA2V)
337 pm2_WR(p, PM2VR_RD_INDEX_HIGH, 0); 327 pm2_WR(p, PM2VR_RD_INDEX_HIGH, 0);
338 pm2_WR(p, PM2R_RESET_STATUS, 0); 328 pm2_WR(p, PM2R_RESET_STATUS, 0);
339 mb(); 329 mb();
340 while (pm2_RD(p, PM2R_RESET_STATUS) & PM2F_BEING_RESET) 330 while (pm2_RD(p, PM2R_RESET_STATUS) & PM2F_BEING_RESET)
341 ; 331 cpu_relax();
342 mb(); 332 mb();
343#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT 333#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
344 DPRINTK("FIFO disconnect enabled\n"); 334 DPRINTK("FIFO disconnect enabled\n");
@@ -354,11 +344,11 @@ static void reset_card(struct pm2fb_par* p)
354 pm2_WR(p, PM2R_MEM_CONFIG, p->mem_config); 344 pm2_WR(p, PM2R_MEM_CONFIG, p->mem_config);
355} 345}
356 346
357static void reset_config(struct pm2fb_par* p) 347static void reset_config(struct pm2fb_par *p)
358{ 348{
359 WAIT_FIFO(p, 52); 349 WAIT_FIFO(p, 53);
360 pm2_WR(p, PM2R_CHIP_CONFIG, pm2_RD(p, PM2R_CHIP_CONFIG) & 350 pm2_WR(p, PM2R_CHIP_CONFIG, pm2_RD(p, PM2R_CHIP_CONFIG) &
361 ~(PM2F_VGA_ENABLE|PM2F_VGA_FIXED)); 351 ~(PM2F_VGA_ENABLE | PM2F_VGA_FIXED));
362 pm2_WR(p, PM2R_BYPASS_WRITE_MASK, ~(0L)); 352 pm2_WR(p, PM2R_BYPASS_WRITE_MASK, ~(0L));
363 pm2_WR(p, PM2R_FRAMEBUFFER_WRITE_MASK, ~(0L)); 353 pm2_WR(p, PM2R_FRAMEBUFFER_WRITE_MASK, ~(0L));
364 pm2_WR(p, PM2R_FIFO_CONTROL, 0); 354 pm2_WR(p, PM2R_FIFO_CONTROL, 0);
@@ -393,31 +383,32 @@ static void reset_config(struct pm2fb_par* p)
393 pm2_WR(p, PM2R_STATISTICS_MODE, 0); 383 pm2_WR(p, PM2R_STATISTICS_MODE, 0);
394 pm2_WR(p, PM2R_SCISSOR_MODE, 0); 384 pm2_WR(p, PM2R_SCISSOR_MODE, 0);
395 pm2_WR(p, PM2R_FILTER_MODE, PM2F_SYNCHRONIZATION); 385 pm2_WR(p, PM2R_FILTER_MODE, PM2F_SYNCHRONIZATION);
386 pm2_WR(p, PM2R_RD_PIXEL_MASK, 0xff);
396 switch (p->type) { 387 switch (p->type) {
397 case PM2_TYPE_PERMEDIA2: 388 case PM2_TYPE_PERMEDIA2:
398 pm2_RDAC_WR(p, PM2I_RD_MODE_CONTROL, 0); /* no overlay */ 389 pm2_RDAC_WR(p, PM2I_RD_MODE_CONTROL, 0); /* no overlay */
399 pm2_RDAC_WR(p, PM2I_RD_CURSOR_CONTROL, 0); 390 pm2_RDAC_WR(p, PM2I_RD_CURSOR_CONTROL, 0);
400 pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, PM2F_RD_PALETTE_WIDTH_8); 391 pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, PM2F_RD_PALETTE_WIDTH_8);
392 pm2_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0);
393 pm2_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0);
394 pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0);
395 pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0);
396 pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0);
401 break; 397 break;
402 case PM2_TYPE_PERMEDIA2V: 398 case PM2_TYPE_PERMEDIA2V:
403 pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1); /* 8bit */ 399 pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1); /* 8bit */
404 break; 400 break;
405 } 401 }
406 pm2_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0);
407 pm2_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0);
408 pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0);
409 pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0);
410 pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0);
411} 402}
412 403
413static void set_aperture(struct pm2fb_par* p, u32 depth) 404static void set_aperture(struct pm2fb_par *p, u32 depth)
414{ 405{
415 /* 406 /*
416 * The hardware is little-endian. When used in big-endian 407 * The hardware is little-endian. When used in big-endian
417 * hosts, the on-chip aperture settings are used where 408 * hosts, the on-chip aperture settings are used where
418 * possible to translate from host to card byte order. 409 * possible to translate from host to card byte order.
419 */ 410 */
420 WAIT_FIFO(p, 4); 411 WAIT_FIFO(p, 2);
421#ifdef __LITTLE_ENDIAN 412#ifdef __LITTLE_ENDIAN
422 pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD); 413 pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD);
423#else 414#else
@@ -440,11 +431,11 @@ static void set_aperture(struct pm2fb_par* p, u32 depth)
440 } 431 }
441#endif 432#endif
442 433
443 // We don't use aperture two, so this may be superflous 434 /* We don't use aperture two, so this may be superflous */
444 pm2_WR(p, PM2R_APERTURE_TWO, PM2F_APERTURE_STANDARD); 435 pm2_WR(p, PM2R_APERTURE_TWO, PM2F_APERTURE_STANDARD);
445} 436}
446 437
447static void set_color(struct pm2fb_par* p, unsigned char regno, 438static void set_color(struct pm2fb_par *p, unsigned char regno,
448 unsigned char r, unsigned char g, unsigned char b) 439 unsigned char r, unsigned char g, unsigned char b)
449{ 440{
450 WAIT_FIFO(p, 4); 441 WAIT_FIFO(p, 4);
@@ -457,7 +448,7 @@ static void set_color(struct pm2fb_par* p, unsigned char regno,
457 pm2_WR(p, PM2R_RD_PALETTE_DATA, b); 448 pm2_WR(p, PM2R_RD_PALETTE_DATA, b);
458} 449}
459 450
460static void set_memclock(struct pm2fb_par* par, u32 clk) 451static void set_memclock(struct pm2fb_par *par, u32 clk)
461{ 452{
462 int i; 453 int i;
463 unsigned char m, n, p; 454 unsigned char m, n, p;
@@ -465,7 +456,7 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
465 switch (par->type) { 456 switch (par->type) {
466 case PM2_TYPE_PERMEDIA2V: 457 case PM2_TYPE_PERMEDIA2V:
467 pm2v_mnp(clk/2, &m, &n, &p); 458 pm2v_mnp(clk/2, &m, &n, &p);
468 WAIT_FIFO(par, 8); 459 WAIT_FIFO(par, 12);
469 pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8); 460 pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8);
470 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0); 461 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0);
471 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m); 462 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m);
@@ -473,10 +464,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
473 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p); 464 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p);
474 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1); 465 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1);
475 rmb(); 466 rmb();
476 for (i = 256; 467 for (i = 256; i; i--)
477 i && !(pm2_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2); 468 if (pm2v_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2)
478 i--) 469 break;
479 ;
480 pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0); 470 pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
481 break; 471 break;
482 case PM2_TYPE_PERMEDIA2: 472 case PM2_TYPE_PERMEDIA2:
@@ -488,15 +478,14 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
488 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p); 478 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
489 pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS); 479 pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
490 rmb(); 480 rmb();
491 for (i = 256; 481 for (i = 256; i; i--)
492 i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED); 482 if (pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED)
493 i--) 483 break;
494 ;
495 break; 484 break;
496 } 485 }
497} 486}
498 487
499static void set_pixclock(struct pm2fb_par* par, u32 clk) 488static void set_pixclock(struct pm2fb_par *par, u32 clk)
500{ 489{
501 int i; 490 int i;
502 unsigned char m, n, p; 491 unsigned char m, n, p;
@@ -504,17 +493,16 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk)
504 switch (par->type) { 493 switch (par->type) {
505 case PM2_TYPE_PERMEDIA2: 494 case PM2_TYPE_PERMEDIA2:
506 pm2_mnp(clk, &m, &n, &p); 495 pm2_mnp(clk, &m, &n, &p);
507 WAIT_FIFO(par, 8); 496 WAIT_FIFO(par, 10);
508 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0); 497 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0);
509 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m); 498 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m);
510 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n); 499 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n);
511 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p); 500 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
512 pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS); 501 pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS);
513 rmb(); 502 rmb();
514 for (i = 256; 503 for (i = 256; i; i--)
515 i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED); 504 if (pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED)
516 i--) 505 break;
517 ;
518 break; 506 break;
519 case PM2_TYPE_PERMEDIA2V: 507 case PM2_TYPE_PERMEDIA2V:
520 pm2v_mnp(clk/2, &m, &n, &p); 508 pm2v_mnp(clk/2, &m, &n, &p);
@@ -528,11 +516,10 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk)
528 } 516 }
529} 517}
530 518
531static void set_video(struct pm2fb_par* p, u32 video) { 519static void set_video(struct pm2fb_par *p, u32 video)
520{
532 u32 tmp; 521 u32 tmp;
533 u32 vsync; 522 u32 vsync = video;
534
535 vsync = video;
536 523
537 DPRINTK("video = 0x%x\n", video); 524 DPRINTK("video = 0x%x\n", video);
538 525
@@ -542,10 +529,10 @@ static void set_video(struct pm2fb_par* p, u32 video) {
542 * driver may well. So always set +hsync/+vsync and then set 529 * driver may well. So always set +hsync/+vsync and then set
543 * the RAMDAC to invert the sync if necessary. 530 * the RAMDAC to invert the sync if necessary.
544 */ 531 */
545 vsync &= ~(PM2F_HSYNC_MASK|PM2F_VSYNC_MASK); 532 vsync &= ~(PM2F_HSYNC_MASK | PM2F_VSYNC_MASK);
546 vsync |= PM2F_HSYNC_ACT_HIGH|PM2F_VSYNC_ACT_HIGH; 533 vsync |= PM2F_HSYNC_ACT_HIGH | PM2F_VSYNC_ACT_HIGH;
547 534
548 WAIT_FIFO(p, 5); 535 WAIT_FIFO(p, 3);
549 pm2_WR(p, PM2R_VIDEO_CONTROL, vsync); 536 pm2_WR(p, PM2R_VIDEO_CONTROL, vsync);
550 537
551 switch (p->type) { 538 switch (p->type) {
@@ -564,16 +551,11 @@ static void set_video(struct pm2fb_par* p, u32 video) {
564 if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW) 551 if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW)
565 tmp |= 4; /* invert vsync */ 552 tmp |= 4; /* invert vsync */
566 pm2v_RDAC_WR(p, PM2VI_RD_SYNC_CONTROL, tmp); 553 pm2v_RDAC_WR(p, PM2VI_RD_SYNC_CONTROL, tmp);
567 pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1);
568 break; 554 break;
569 } 555 }
570} 556}
571 557
572/* 558/*
573 *
574 */
575
576/**
577 * pm2fb_check_var - Optional function. Validates a var passed in. 559 * pm2fb_check_var - Optional function. Validates a var passed in.
578 * @var: frame buffer variable screen structure 560 * @var: frame buffer variable screen structure
579 * @info: frame buffer structure that represents a single frame buffer 561 * @info: frame buffer structure that represents a single frame buffer
@@ -594,15 +576,22 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
594 } 576 }
595 577
596 if (var->xres != var->xres_virtual) { 578 if (var->xres != var->xres_virtual) {
597 DPRINTK("virtual x resolution != physical x resolution not supported\n"); 579 DPRINTK("virtual x resolution != "
580 "physical x resolution not supported\n");
598 return -EINVAL; 581 return -EINVAL;
599 } 582 }
600 583
601 if (var->yres > var->yres_virtual) { 584 if (var->yres > var->yres_virtual) {
602 DPRINTK("virtual y resolution < physical y resolution not possible\n"); 585 DPRINTK("virtual y resolution < "
586 "physical y resolution not possible\n");
603 return -EINVAL; 587 return -EINVAL;
604 } 588 }
605 589
590 /* permedia cannot blit over 2048 */
591 if (var->yres_virtual > 2047) {
592 var->yres_virtual = 2047;
593 }
594
606 if (var->xoffset) { 595 if (var->xoffset) {
607 DPRINTK("xoffset not supported\n"); 596 DPRINTK("xoffset not supported\n");
608 return -EINVAL; 597 return -EINVAL;
@@ -614,7 +603,7 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
614 } 603 }
615 604
616 var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */ 605 var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */
617 lpitch = var->xres * ((var->bits_per_pixel + 7)>>3); 606 lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
618 607
619 if (var->xres < 320 || var->xres > 1600) { 608 if (var->xres < 320 || var->xres > 1600) {
620 DPRINTK("width not supported: %u\n", var->xres); 609 DPRINTK("width not supported: %u\n", var->xres);
@@ -633,15 +622,18 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
633 } 622 }
634 623
635 if (PICOS2KHZ(var->pixclock) > PM2_MAX_PIXCLOCK) { 624 if (PICOS2KHZ(var->pixclock) > PM2_MAX_PIXCLOCK) {
636 DPRINTK("pixclock too high (%ldKHz)\n", PICOS2KHZ(var->pixclock)); 625 DPRINTK("pixclock too high (%ldKHz)\n",
626 PICOS2KHZ(var->pixclock));
637 return -EINVAL; 627 return -EINVAL;
638 } 628 }
639 629
640 var->transp.offset = 0; 630 var->transp.offset = 0;
641 var->transp.length = 0; 631 var->transp.length = 0;
642 switch(var->bits_per_pixel) { 632 switch (var->bits_per_pixel) {
643 case 8: 633 case 8:
644 var->red.length = var->green.length = var->blue.length = 8; 634 var->red.length = 8;
635 var->green.length = 8;
636 var->blue.length = 8;
645 break; 637 break;
646 case 16: 638 case 16:
647 var->red.offset = 11; 639 var->red.offset = 11;
@@ -657,7 +649,9 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
657 var->red.offset = 16; 649 var->red.offset = 16;
658 var->green.offset = 8; 650 var->green.offset = 8;
659 var->blue.offset = 0; 651 var->blue.offset = 0;
660 var->red.length = var->green.length = var->blue.length = 8; 652 var->red.length = 8;
653 var->green.length = 8;
654 var->blue.length = 8;
661 break; 655 break;
662 case 24: 656 case 24:
663#ifdef __BIG_ENDIAN 657#ifdef __BIG_ENDIAN
@@ -668,10 +662,13 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
668 var->blue.offset = 0; 662 var->blue.offset = 0;
669#endif 663#endif
670 var->green.offset = 8; 664 var->green.offset = 8;
671 var->red.length = var->green.length = var->blue.length = 8; 665 var->red.length = 8;
666 var->green.length = 8;
667 var->blue.length = 8;
672 break; 668 break;
673 } 669 }
674 var->height = var->width = -1; 670 var->height = -1;
671 var->width = -1;
675 672
676 var->accel_flags = 0; /* Can't mmap if this is on */ 673 var->accel_flags = 0; /* Can't mmap if this is on */
677 674
@@ -691,7 +688,9 @@ static int pm2fb_set_par(struct fb_info *info)
691{ 688{
692 struct pm2fb_par *par = info->par; 689 struct pm2fb_par *par = info->par;
693 u32 pixclock; 690 u32 pixclock;
694 u32 width, height, depth; 691 u32 width = (info->var.xres_virtual + 7) & ~7;
692 u32 height = info->var.yres_virtual;
693 u32 depth = (info->var.bits_per_pixel + 7) & ~7;
695 u32 hsstart, hsend, hbend, htotal; 694 u32 hsstart, hsend, hbend, htotal;
696 u32 vsstart, vsend, vbend, vtotal; 695 u32 vsstart, vsend, vbend, vtotal;
697 u32 stride; 696 u32 stride;
@@ -701,22 +700,19 @@ static int pm2fb_set_par(struct fb_info *info)
701 u32 txtmap = 0; 700 u32 txtmap = 0;
702 u32 pixsize = 0; 701 u32 pixsize = 0;
703 u32 clrformat = 0; 702 u32 clrformat = 0;
704 u32 xres; 703 u32 misc = 1; /* 8-bit DAC */
704 u32 xres = (info->var.xres + 31) & ~31;
705 int data64; 705 int data64;
706 706
707 reset_card(par); 707 reset_card(par);
708 reset_config(par); 708 reset_config(par);
709 clear_palette(par); 709 clear_palette(par);
710 if ( par->memclock ) 710 if (par->memclock)
711 set_memclock(par, par->memclock); 711 set_memclock(par, par->memclock);
712 712
713 width = (info->var.xres_virtual + 7) & ~7;
714 height = info->var.yres_virtual;
715 depth = (info->var.bits_per_pixel + 7) & ~7;
716 depth = (depth > 32) ? 32 : depth; 713 depth = (depth > 32) ? 32 : depth;
717 data64 = depth > 8 || par->type == PM2_TYPE_PERMEDIA2V; 714 data64 = depth > 8 || par->type == PM2_TYPE_PERMEDIA2V;
718 715
719 xres = (info->var.xres + 31) & ~31;
720 pixclock = PICOS2KHZ(info->var.pixclock); 716 pixclock = PICOS2KHZ(info->var.pixclock);
721 if (pixclock > PM2_MAX_PIXCLOCK) { 717 if (pixclock > PM2_MAX_PIXCLOCK) {
722 DPRINTK("pixclock too high (%uKHz)\n", pixclock); 718 DPRINTK("pixclock too high (%uKHz)\n", pixclock);
@@ -731,7 +727,8 @@ static int pm2fb_set_par(struct fb_info *info)
731 ? info->var.lower_margin - 1 727 ? info->var.lower_margin - 1
732 : 0; /* FIXME! */ 728 : 0; /* FIXME! */
733 vsend = info->var.lower_margin + info->var.vsync_len - 1; 729 vsend = info->var.lower_margin + info->var.vsync_len - 1;
734 vbend = info->var.lower_margin + info->var.vsync_len + info->var.upper_margin; 730 vbend = info->var.lower_margin + info->var.vsync_len +
731 info->var.upper_margin;
735 vtotal = info->var.yres + vbend - 1; 732 vtotal = info->var.yres + vbend - 1;
736 stride = to3264(width, depth, 1); 733 stride = to3264(width, depth, 1);
737 base = to3264(info->var.yoffset * xres + info->var.xoffset, depth, 1); 734 base = to3264(info->var.yoffset * xres + info->var.xoffset, depth, 1);
@@ -744,25 +741,25 @@ static int pm2fb_set_par(struct fb_info *info)
744 video |= PM2F_HSYNC_ACT_LOW; 741 video |= PM2F_HSYNC_ACT_LOW;
745 } else 742 } else
746 video |= PM2F_HSYNC_ACT_HIGH; 743 video |= PM2F_HSYNC_ACT_HIGH;
747 } 744 } else
748 else
749 video |= PM2F_HSYNC_ACT_LOW; 745 video |= PM2F_HSYNC_ACT_LOW;
746
750 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) { 747 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) {
751 if (lowvsync) { 748 if (lowvsync) {
752 DPRINTK("ignoring +vsync, using -vsync.\n"); 749 DPRINTK("ignoring +vsync, using -vsync.\n");
753 video |= PM2F_VSYNC_ACT_LOW; 750 video |= PM2F_VSYNC_ACT_LOW;
754 } else 751 } else
755 video |= PM2F_VSYNC_ACT_HIGH; 752 video |= PM2F_VSYNC_ACT_HIGH;
756 } 753 } else
757 else
758 video |= PM2F_VSYNC_ACT_LOW; 754 video |= PM2F_VSYNC_ACT_LOW;
759 if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_INTERLACED) { 755
756 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
760 DPRINTK("interlaced not supported\n"); 757 DPRINTK("interlaced not supported\n");
761 return -EINVAL; 758 return -EINVAL;
762 } 759 }
763 if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE) 760 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
764 video |= PM2F_LINE_DOUBLE; 761 video |= PM2F_LINE_DOUBLE;
765 if ((info->var.activate & FB_ACTIVATE_MASK)==FB_ACTIVATE_NOW) 762 if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
766 video |= PM2F_VIDEO_ENABLE; 763 video |= PM2F_VIDEO_ENABLE;
767 par->video = video; 764 par->video = video;
768 765
@@ -783,12 +780,10 @@ static int pm2fb_set_par(struct fb_info *info)
783 780
784 mb(); 781 mb();
785 WAIT_FIFO(par, 19); 782 WAIT_FIFO(par, 19);
786 pm2_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL,
787 ( depth == 8 ) ? 0 : PM2F_COLOR_KEY_TEST_OFF);
788 switch (depth) { 783 switch (depth) {
789 case 8: 784 case 8:
790 pm2_WR(par, PM2R_FB_READ_PIXEL, 0); 785 pm2_WR(par, PM2R_FB_READ_PIXEL, 0);
791 clrformat = 0x0e; 786 clrformat = 0x2e;
792 break; 787 break;
793 case 16: 788 case 16:
794 pm2_WR(par, PM2R_FB_READ_PIXEL, 1); 789 pm2_WR(par, PM2R_FB_READ_PIXEL, 1);
@@ -796,6 +791,7 @@ static int pm2fb_set_par(struct fb_info *info)
796 txtmap = PM2F_TEXTEL_SIZE_16; 791 txtmap = PM2F_TEXTEL_SIZE_16;
797 pixsize = 1; 792 pixsize = 1;
798 clrformat = 0x70; 793 clrformat = 0x70;
794 misc |= 8;
799 break; 795 break;
800 case 32: 796 case 32:
801 pm2_WR(par, PM2R_FB_READ_PIXEL, 2); 797 pm2_WR(par, PM2R_FB_READ_PIXEL, 2);
@@ -803,6 +799,7 @@ static int pm2fb_set_par(struct fb_info *info)
803 txtmap = PM2F_TEXTEL_SIZE_32; 799 txtmap = PM2F_TEXTEL_SIZE_32;
804 pixsize = 2; 800 pixsize = 2;
805 clrformat = 0x20; 801 clrformat = 0x20;
802 misc |= 8;
806 break; 803 break;
807 case 24: 804 case 24:
808 pm2_WR(par, PM2R_FB_READ_PIXEL, 4); 805 pm2_WR(par, PM2R_FB_READ_PIXEL, 4);
@@ -810,6 +807,7 @@ static int pm2fb_set_par(struct fb_info *info)
810 txtmap = PM2F_TEXTEL_SIZE_24; 807 txtmap = PM2F_TEXTEL_SIZE_24;
811 pixsize = 4; 808 pixsize = 4;
812 clrformat = 0x20; 809 clrformat = 0x20;
810 misc |= 8;
813 break; 811 break;
814 } 812 }
815 pm2_WR(par, PM2R_FB_WRITE_MODE, PM2F_FB_WRITE_ENABLE); 813 pm2_WR(par, PM2R_FB_WRITE_MODE, PM2F_FB_WRITE_ENABLE);
@@ -834,14 +832,19 @@ static int pm2fb_set_par(struct fb_info *info)
834 pm2_WR(par, PM2R_SCREEN_BASE, base); 832 pm2_WR(par, PM2R_SCREEN_BASE, base);
835 wmb(); 833 wmb();
836 set_video(par, video); 834 set_video(par, video);
837 WAIT_FIFO(par, 4); 835 WAIT_FIFO(par, 10);
838 switch (par->type) { 836 switch (par->type) {
839 case PM2_TYPE_PERMEDIA2: 837 case PM2_TYPE_PERMEDIA2:
840 pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE, clrmode); 838 pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE, clrmode);
839 pm2_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL,
840 (depth == 8) ? 0 : PM2F_COLOR_KEY_TEST_OFF);
841 break; 841 break;
842 case PM2_TYPE_PERMEDIA2V: 842 case PM2_TYPE_PERMEDIA2V:
843 pm2v_RDAC_WR(par, PM2VI_RD_DAC_CONTROL, 0);
843 pm2v_RDAC_WR(par, PM2VI_RD_PIXEL_SIZE, pixsize); 844 pm2v_RDAC_WR(par, PM2VI_RD_PIXEL_SIZE, pixsize);
844 pm2v_RDAC_WR(par, PM2VI_RD_COLOR_FORMAT, clrformat); 845 pm2v_RDAC_WR(par, PM2VI_RD_COLOR_FORMAT, clrformat);
846 pm2v_RDAC_WR(par, PM2VI_RD_MISC_CONTROL, misc);
847 pm2v_RDAC_WR(par, PM2VI_RD_OVERLAY_KEY, 0);
845 break; 848 break;
846 } 849 }
847 set_pixclock(par, pixclock); 850 set_pixclock(par, pixclock);
@@ -872,16 +875,15 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
872 struct pm2fb_par *par = info->par; 875 struct pm2fb_par *par = info->par;
873 876
874 if (regno >= info->cmap.len) /* no. of hw registers */ 877 if (regno >= info->cmap.len) /* no. of hw registers */
875 return 1; 878 return -EINVAL;
876 /* 879 /*
877 * Program hardware... do anything you want with transp 880 * Program hardware... do anything you want with transp
878 */ 881 */
879 882
880 /* grayscale works only partially under directcolor */ 883 /* grayscale works only partially under directcolor */
881 if (info->var.grayscale) { 884 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
882 /* grayscale = 0.30*R + 0.59*G + 0.11*B */ 885 if (info->var.grayscale)
883 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; 886 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
884 }
885 887
886 /* Directcolor: 888 /* Directcolor:
887 * var->{color}.offset contains start of bitfield 889 * var->{color}.offset contains start of bitfield
@@ -931,7 +933,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
931 u32 v; 933 u32 v;
932 934
933 if (regno >= 16) 935 if (regno >= 16)
934 return 1; 936 return -EINVAL;
935 937
936 v = (red << info->var.red.offset) | 938 v = (red << info->var.red.offset) |
937 (green << info->var.green.offset) | 939 (green << info->var.green.offset) |
@@ -948,8 +950,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
948 break; 950 break;
949 } 951 }
950 return 0; 952 return 0;
951 } 953 } else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
952 else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
953 set_color(par, regno, red, green, blue); 954 set_color(par, regno, red, green, blue);
954 955
955 return 0; 956 return 0;
@@ -972,11 +973,9 @@ static int pm2fb_pan_display(struct fb_var_screeninfo *var,
972{ 973{
973 struct pm2fb_par *p = info->par; 974 struct pm2fb_par *p = info->par;
974 u32 base; 975 u32 base;
975 u32 depth; 976 u32 depth = (var->bits_per_pixel + 7) & ~7;
976 u32 xres; 977 u32 xres = (var->xres + 31) & ~31;
977 978
978 xres = (var->xres + 31) & ~31;
979 depth = (var->bits_per_pixel + 7) & ~7;
980 depth = (depth > 32) ? 32 : depth; 979 depth = (depth > 32) ? 32 : depth;
981 base = to3264(var->yoffset * xres + var->xoffset, depth, 1); 980 base = to3264(var->yoffset * xres + var->xoffset, depth, 1);
982 WAIT_FIFO(p, 1); 981 WAIT_FIFO(p, 1);
@@ -1018,15 +1017,15 @@ static int pm2fb_blank(int blank_mode, struct fb_info *info)
1018 break; 1017 break;
1019 case FB_BLANK_VSYNC_SUSPEND: 1018 case FB_BLANK_VSYNC_SUSPEND:
1020 /* VSync: Off */ 1019 /* VSync: Off */
1021 video &= ~(PM2F_VSYNC_MASK | PM2F_BLANK_LOW ); 1020 video &= ~(PM2F_VSYNC_MASK | PM2F_BLANK_LOW);
1022 break; 1021 break;
1023 case FB_BLANK_HSYNC_SUSPEND: 1022 case FB_BLANK_HSYNC_SUSPEND:
1024 /* HSync: Off */ 1023 /* HSync: Off */
1025 video &= ~(PM2F_HSYNC_MASK | PM2F_BLANK_LOW ); 1024 video &= ~(PM2F_HSYNC_MASK | PM2F_BLANK_LOW);
1026 break; 1025 break;
1027 case FB_BLANK_POWERDOWN: 1026 case FB_BLANK_POWERDOWN:
1028 /* HSync: Off, VSync: Off */ 1027 /* HSync: Off, VSync: Off */
1029 video &= ~(PM2F_VSYNC_MASK | PM2F_HSYNC_MASK| PM2F_BLANK_LOW); 1028 video &= ~(PM2F_VSYNC_MASK | PM2F_HSYNC_MASK | PM2F_BLANK_LOW);
1030 break; 1029 break;
1031 } 1030 }
1032 set_video(par, video); 1031 set_video(par, video);
@@ -1042,48 +1041,20 @@ static int pm2fb_sync(struct fb_info *info)
1042 mb(); 1041 mb();
1043 do { 1042 do {
1044 while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0) 1043 while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0)
1045 udelay(10); 1044 cpu_relax();
1046 rmb();
1047 } while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC)); 1045 } while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC));
1048 1046
1049 return 0; 1047 return 0;
1050} 1048}
1051 1049
1052/* 1050static void pm2fb_fillrect(struct fb_info *info,
1053 * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
1054 */
1055static void pm2fb_block_op(struct fb_info* info, int copy,
1056 s32 xsrc, s32 ysrc,
1057 s32 x, s32 y, s32 w, s32 h,
1058 u32 color) {
1059 struct pm2fb_par *par = info->par;
1060
1061 if (!w || !h)
1062 return;
1063 WAIT_FIFO(par, 5);
1064 pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
1065 PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
1066 if (copy)
1067 pm2_WR(par, PM2R_FB_SOURCE_DELTA,
1068 ((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff));
1069 else
1070 pm2_WR(par, PM2R_FB_BLOCK_COLOR, color);
1071 pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (y << 16) | x);
1072 pm2_WR(par, PM2R_RECTANGLE_SIZE, (h << 16) | w);
1073 wmb();
1074 pm2_WR(par, PM2R_RENDER, PM2F_RENDER_RECTANGLE |
1075 (x<xsrc ? PM2F_INCREASE_X : 0) |
1076 (y<ysrc ? PM2F_INCREASE_Y : 0) |
1077 (copy ? 0 : PM2F_RENDER_FASTFILL));
1078}
1079
1080static void pm2fb_fillrect (struct fb_info *info,
1081 const struct fb_fillrect *region) 1051 const struct fb_fillrect *region)
1082{ 1052{
1053 struct pm2fb_par *par = info->par;
1083 struct fb_fillrect modded; 1054 struct fb_fillrect modded;
1084 int vxres, vyres; 1055 int vxres, vyres;
1085 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? 1056 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1086 ((u32*)info->pseudo_palette)[region->color] : region->color; 1057 ((u32 *)info->pseudo_palette)[region->color] : region->color;
1087 1058
1088 if (info->state != FBINFO_STATE_RUNNING) 1059 if (info->state != FBINFO_STATE_RUNNING)
1089 return; 1060 return;
@@ -1098,31 +1069,46 @@ static void pm2fb_fillrect (struct fb_info *info,
1098 1069
1099 memcpy(&modded, region, sizeof(struct fb_fillrect)); 1070 memcpy(&modded, region, sizeof(struct fb_fillrect));
1100 1071
1101 if(!modded.width || !modded.height || 1072 if (!modded.width || !modded.height ||
1102 modded.dx >= vxres || modded.dy >= vyres) 1073 modded.dx >= vxres || modded.dy >= vyres)
1103 return; 1074 return;
1104 1075
1105 if(modded.dx + modded.width > vxres) 1076 if (modded.dx + modded.width > vxres)
1106 modded.width = vxres - modded.dx; 1077 modded.width = vxres - modded.dx;
1107 if(modded.dy + modded.height > vyres) 1078 if (modded.dy + modded.height > vyres)
1108 modded.height = vyres - modded.dy; 1079 modded.height = vyres - modded.dy;
1109 1080
1110 if(info->var.bits_per_pixel == 8) 1081 if (info->var.bits_per_pixel == 8)
1111 color |= color << 8; 1082 color |= color << 8;
1112 if(info->var.bits_per_pixel <= 16) 1083 if (info->var.bits_per_pixel <= 16)
1113 color |= color << 16; 1084 color |= color << 16;
1114 1085
1115 if(info->var.bits_per_pixel != 24) 1086 WAIT_FIFO(par, 3);
1116 pm2fb_block_op(info, 0, 0, 0, 1087 pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE);
1117 modded.dx, modded.dy, 1088 pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (modded.dy << 16) | modded.dx);
1118 modded.width, modded.height, color); 1089 pm2_WR(par, PM2R_RECTANGLE_SIZE, (modded.height << 16) | modded.width);
1119 else 1090 if (info->var.bits_per_pixel != 24) {
1120 cfb_fillrect(info, region); 1091 WAIT_FIFO(par, 2);
1092 pm2_WR(par, PM2R_FB_BLOCK_COLOR, color);
1093 wmb();
1094 pm2_WR(par, PM2R_RENDER,
1095 PM2F_RENDER_RECTANGLE | PM2F_RENDER_FASTFILL);
1096 } else {
1097 WAIT_FIFO(par, 4);
1098 pm2_WR(par, PM2R_COLOR_DDA_MODE, 1);
1099 pm2_WR(par, PM2R_CONSTANT_COLOR, color);
1100 wmb();
1101 pm2_WR(par, PM2R_RENDER,
1102 PM2F_RENDER_RECTANGLE |
1103 PM2F_INCREASE_X | PM2F_INCREASE_Y );
1104 pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
1105 }
1121} 1106}
1122 1107
1123static void pm2fb_copyarea(struct fb_info *info, 1108static void pm2fb_copyarea(struct fb_info *info,
1124 const struct fb_copyarea *area) 1109 const struct fb_copyarea *area)
1125{ 1110{
1111 struct pm2fb_par *par = info->par;
1126 struct fb_copyarea modded; 1112 struct fb_copyarea modded;
1127 u32 vxres, vyres; 1113 u32 vxres, vyres;
1128 1114
@@ -1138,23 +1124,359 @@ static void pm2fb_copyarea(struct fb_info *info,
1138 vxres = info->var.xres_virtual; 1124 vxres = info->var.xres_virtual;
1139 vyres = info->var.yres_virtual; 1125 vyres = info->var.yres_virtual;
1140 1126
1141 if(!modded.width || !modded.height || 1127 if (!modded.width || !modded.height ||
1142 modded.sx >= vxres || modded.sy >= vyres || 1128 modded.sx >= vxres || modded.sy >= vyres ||
1143 modded.dx >= vxres || modded.dy >= vyres) 1129 modded.dx >= vxres || modded.dy >= vyres)
1144 return; 1130 return;
1145 1131
1146 if(modded.sx + modded.width > vxres) 1132 if (modded.sx + modded.width > vxres)
1147 modded.width = vxres - modded.sx; 1133 modded.width = vxres - modded.sx;
1148 if(modded.dx + modded.width > vxres) 1134 if (modded.dx + modded.width > vxres)
1149 modded.width = vxres - modded.dx; 1135 modded.width = vxres - modded.dx;
1150 if(modded.sy + modded.height > vyres) 1136 if (modded.sy + modded.height > vyres)
1151 modded.height = vyres - modded.sy; 1137 modded.height = vyres - modded.sy;
1152 if(modded.dy + modded.height > vyres) 1138 if (modded.dy + modded.height > vyres)
1153 modded.height = vyres - modded.dy; 1139 modded.height = vyres - modded.dy;
1154 1140
1155 pm2fb_block_op(info, 1, modded.sx, modded.sy, 1141 WAIT_FIFO(par, 5);
1156 modded.dx, modded.dy, 1142 pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
1157 modded.width, modded.height, 0); 1143 PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
1144 pm2_WR(par, PM2R_FB_SOURCE_DELTA,
1145 ((modded.sy - modded.dy) & 0xfff) << 16 |
1146 ((modded.sx - modded.dx) & 0xfff));
1147 pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (modded.dy << 16) | modded.dx);
1148 pm2_WR(par, PM2R_RECTANGLE_SIZE, (modded.height << 16) | modded.width);
1149 wmb();
1150 pm2_WR(par, PM2R_RENDER, PM2F_RENDER_RECTANGLE |
1151 (modded.dx < modded.sx ? PM2F_INCREASE_X : 0) |
1152 (modded.dy < modded.sy ? PM2F_INCREASE_Y : 0));
1153}
1154
1155static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image)
1156{
1157 struct pm2fb_par *par = info->par;
1158 u32 height = image->height;
1159 u32 fgx, bgx;
1160 const u32 *src = (const u32 *)image->data;
1161 u32 xres = (info->var.xres + 31) & ~31;
1162
1163 if (info->state != FBINFO_STATE_RUNNING)
1164 return;
1165 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) {
1166 cfb_imageblit(info, image);
1167 return;
1168 }
1169 switch (info->fix.visual) {
1170 case FB_VISUAL_PSEUDOCOLOR:
1171 fgx = image->fg_color;
1172 bgx = image->bg_color;
1173 break;
1174 case FB_VISUAL_TRUECOLOR:
1175 default:
1176 fgx = par->palette[image->fg_color];
1177 bgx = par->palette[image->bg_color];
1178 break;
1179 }
1180 if (info->var.bits_per_pixel == 8) {
1181 fgx |= fgx << 8;
1182 bgx |= bgx << 8;
1183 }
1184 if (info->var.bits_per_pixel <= 16) {
1185 fgx |= fgx << 16;
1186 bgx |= bgx << 16;
1187 }
1188
1189 WAIT_FIFO(par, 13);
1190 pm2_WR(par, PM2R_FB_READ_MODE, partprod(xres));
1191 pm2_WR(par, PM2R_SCISSOR_MIN_XY,
1192 ((image->dy & 0xfff) << 16) | (image->dx & 0x0fff));
1193 pm2_WR(par, PM2R_SCISSOR_MAX_XY,
1194 (((image->dy + image->height) & 0x0fff) << 16) |
1195 ((image->dx + image->width) & 0x0fff));
1196 pm2_WR(par, PM2R_SCISSOR_MODE, 1);
1197 /* GXcopy & UNIT_ENABLE */
1198 pm2_WR(par, PM2R_LOGICAL_OP_MODE, (0x3 << 1) | 1);
1199 pm2_WR(par, PM2R_RECTANGLE_ORIGIN,
1200 ((image->dy & 0xfff) << 16) | (image->dx & 0x0fff));
1201 pm2_WR(par, PM2R_RECTANGLE_SIZE,
1202 ((image->height & 0x0fff) << 16) |
1203 ((image->width) & 0x0fff));
1204 if (info->var.bits_per_pixel == 24) {
1205 pm2_WR(par, PM2R_COLOR_DDA_MODE, 1);
1206 /* clear area */
1207 pm2_WR(par, PM2R_CONSTANT_COLOR, bgx);
1208 pm2_WR(par, PM2R_RENDER,
1209 PM2F_RENDER_RECTANGLE |
1210 PM2F_INCREASE_X | PM2F_INCREASE_Y);
1211 /* BitMapPackEachScanline & invert bits and byte order*/
1212 /* force background */
1213 pm2_WR(par, PM2R_RASTERIZER_MODE, (1 << 9) | 1 | (3 << 7));
1214 pm2_WR(par, PM2R_CONSTANT_COLOR, fgx);
1215 pm2_WR(par, PM2R_RENDER,
1216 PM2F_RENDER_RECTANGLE |
1217 PM2F_INCREASE_X | PM2F_INCREASE_Y |
1218 PM2F_RENDER_SYNC_ON_BIT_MASK);
1219 } else {
1220 pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
1221 /* clear area */
1222 pm2_WR(par, PM2R_FB_BLOCK_COLOR, bgx);
1223 pm2_WR(par, PM2R_RENDER,
1224 PM2F_RENDER_RECTANGLE |
1225 PM2F_RENDER_FASTFILL |
1226 PM2F_INCREASE_X | PM2F_INCREASE_Y);
1227 /* invert bits and byte order*/
1228 pm2_WR(par, PM2R_RASTERIZER_MODE, 1 | (3 << 7));
1229 pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx);
1230 pm2_WR(par, PM2R_RENDER,
1231 PM2F_RENDER_RECTANGLE |
1232 PM2F_INCREASE_X | PM2F_INCREASE_Y |
1233 PM2F_RENDER_FASTFILL |
1234 PM2F_RENDER_SYNC_ON_BIT_MASK);
1235 }
1236
1237 while (height--) {
1238 int width = ((image->width + 7) >> 3)
1239 + info->pixmap.scan_align - 1;
1240 width >>= 2;
1241 WAIT_FIFO(par, width);
1242 while (width--) {
1243 pm2_WR(par, PM2R_BIT_MASK_PATTERN, *src);
1244 src++;
1245 }
1246 }
1247 WAIT_FIFO(par, 3);
1248 pm2_WR(par, PM2R_RASTERIZER_MODE, 0);
1249 pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
1250 pm2_WR(par, PM2R_SCISSOR_MODE, 0);
1251}
1252
1253/*
1254 * Hardware cursor support.
1255 */
1256static const u8 cursor_bits_lookup[16] = {
1257 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
1258 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
1259};
1260
1261static int pm2vfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1262{
1263 struct pm2fb_par *par = info->par;
1264 u8 mode = PM2F_CURSORMODE_TYPE_X;
1265 int x = cursor->image.dx - info->var.xoffset;
1266 int y = cursor->image.dy - info->var.yoffset;
1267
1268 if (cursor->enable)
1269 mode |= PM2F_CURSORMODE_CURSOR_ENABLE;
1270
1271 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_MODE, mode);
1272
1273 if (!cursor->enable)
1274 x = 2047; /* push it outside display */
1275 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_X_LOW, x & 0xff);
1276 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_X_HIGH, (x >> 8) & 0xf);
1277 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_Y_LOW, y & 0xff);
1278 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_Y_HIGH, (y >> 8) & 0xf);
1279
1280 /*
1281 * If the cursor is not be changed this means either we want the
1282 * current cursor state (if enable is set) or we want to query what
1283 * we can do with the cursor (if enable is not set)
1284 */
1285 if (!cursor->set)
1286 return 0;
1287
1288 if (cursor->set & FB_CUR_SETHOT) {
1289 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_X_HOT,
1290 cursor->hot.x & 0x3f);
1291 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_Y_HOT,
1292 cursor->hot.y & 0x3f);
1293 }
1294
1295 if (cursor->set & FB_CUR_SETCMAP) {
1296 u32 fg_idx = cursor->image.fg_color;
1297 u32 bg_idx = cursor->image.bg_color;
1298 struct fb_cmap cmap = info->cmap;
1299
1300 /* the X11 driver says one should use these color registers */
1301 pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_CURSOR_PALETTE >> 8);
1302 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 0,
1303 cmap.red[bg_idx] >> 8 );
1304 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 1,
1305 cmap.green[bg_idx] >> 8 );
1306 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 2,
1307 cmap.blue[bg_idx] >> 8 );
1308
1309 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 3,
1310 cmap.red[fg_idx] >> 8 );
1311 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 4,
1312 cmap.green[fg_idx] >> 8 );
1313 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 5,
1314 cmap.blue[fg_idx] >> 8 );
1315 pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
1316 }
1317
1318 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
1319 u8 *bitmap = (u8 *)cursor->image.data;
1320 u8 *mask = (u8 *)cursor->mask;
1321 int i;
1322 int pos = PM2VI_RD_CURSOR_PATTERN;
1323
1324 for (i = 0; i < cursor->image.height; i++) {
1325 int j = (cursor->image.width + 7) >> 3;
1326 int k = 8 - j;
1327
1328 pm2_WR(par, PM2VR_RD_INDEX_HIGH, pos >> 8);
1329
1330 for (; j > 0; j--) {
1331 u8 data = *bitmap ^ *mask;
1332
1333 if (cursor->rop == ROP_COPY)
1334 data = *mask & *bitmap;
1335 /* Upper 4 bits of bitmap data */
1336 pm2v_RDAC_WR(par, pos++,
1337 cursor_bits_lookup[data >> 4] |
1338 (cursor_bits_lookup[*mask >> 4] << 1));
1339 /* Lower 4 bits of bitmap */
1340 pm2v_RDAC_WR(par, pos++,
1341 cursor_bits_lookup[data & 0xf] |
1342 (cursor_bits_lookup[*mask & 0xf] << 1));
1343 bitmap++;
1344 mask++;
1345 }
1346 for (; k > 0; k--) {
1347 pm2v_RDAC_WR(par, pos++, 0);
1348 pm2v_RDAC_WR(par, pos++, 0);
1349 }
1350 }
1351
1352 while (pos < (1024 + PM2VI_RD_CURSOR_PATTERN)) {
1353 pm2_WR(par, PM2VR_RD_INDEX_HIGH, pos >> 8);
1354 pm2v_RDAC_WR(par, pos++, 0);
1355 }
1356
1357 pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
1358 }
1359 return 0;
1360}
1361
1362static int pm2fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1363{
1364 struct pm2fb_par *par = info->par;
1365 u8 mode;
1366
1367 if (!hwcursor)
1368 return -EINVAL; /* just to force soft_cursor() call */
1369
1370 /* Too large of a cursor or wrong bpp :-( */
1371 if (cursor->image.width > 64 ||
1372 cursor->image.height > 64 ||
1373 cursor->image.depth > 1)
1374 return -EINVAL;
1375
1376 if (par->type == PM2_TYPE_PERMEDIA2V)
1377 return pm2vfb_cursor(info, cursor);
1378
1379 mode = 0x40;
1380 if (cursor->enable)
1381 mode = 0x43;
1382
1383 pm2_RDAC_WR(par, PM2I_RD_CURSOR_CONTROL, mode);
1384
1385 /*
1386 * If the cursor is not be changed this means either we want the
1387 * current cursor state (if enable is set) or we want to query what
1388 * we can do with the cursor (if enable is not set)
1389 */
1390 if (!cursor->set)
1391 return 0;
1392
1393 if (cursor->set & FB_CUR_SETPOS) {
1394 int x = cursor->image.dx - info->var.xoffset + 63;
1395 int y = cursor->image.dy - info->var.yoffset + 63;
1396
1397 WAIT_FIFO(par, 4);
1398 pm2_WR(par, PM2R_RD_CURSOR_X_LSB, x & 0xff);
1399 pm2_WR(par, PM2R_RD_CURSOR_X_MSB, (x >> 8) & 0x7);
1400 pm2_WR(par, PM2R_RD_CURSOR_Y_LSB, y & 0xff);
1401 pm2_WR(par, PM2R_RD_CURSOR_Y_MSB, (y >> 8) & 0x7);
1402 }
1403
1404 if (cursor->set & FB_CUR_SETCMAP) {
1405 u32 fg_idx = cursor->image.fg_color;
1406 u32 bg_idx = cursor->image.bg_color;
1407
1408 WAIT_FIFO(par, 7);
1409 pm2_WR(par, PM2R_RD_CURSOR_COLOR_ADDRESS, 1);
1410 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1411 info->cmap.red[bg_idx] >> 8);
1412 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1413 info->cmap.green[bg_idx] >> 8);
1414 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1415 info->cmap.blue[bg_idx] >> 8);
1416
1417 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1418 info->cmap.red[fg_idx] >> 8);
1419 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1420 info->cmap.green[fg_idx] >> 8);
1421 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1422 info->cmap.blue[fg_idx] >> 8);
1423 }
1424
1425 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
1426 u8 *bitmap = (u8 *)cursor->image.data;
1427 u8 *mask = (u8 *)cursor->mask;
1428 int i;
1429
1430 WAIT_FIFO(par, 1);
1431 pm2_WR(par, PM2R_RD_PALETTE_WRITE_ADDRESS, 0);
1432
1433 for (i = 0; i < cursor->image.height; i++) {
1434 int j = (cursor->image.width + 7) >> 3;
1435 int k = 8 - j;
1436
1437 WAIT_FIFO(par, 8);
1438 for (; j > 0; j--) {
1439 u8 data = *bitmap ^ *mask;
1440
1441 if (cursor->rop == ROP_COPY)
1442 data = *mask & *bitmap;
1443 /* bitmap data */
1444 pm2_WR(par, PM2R_RD_CURSOR_DATA, data);
1445 bitmap++;
1446 mask++;
1447 }
1448 for (; k > 0; k--)
1449 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1450 }
1451 for (; i < 64; i++) {
1452 int j = 8;
1453 WAIT_FIFO(par, 8);
1454 while (j-- > 0)
1455 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1456 }
1457
1458 mask = (u8 *)cursor->mask;
1459 for (i = 0; i < cursor->image.height; i++) {
1460 int j = (cursor->image.width + 7) >> 3;
1461 int k = 8 - j;
1462
1463 WAIT_FIFO(par, 8);
1464 for (; j > 0; j--) {
1465 /* mask */
1466 pm2_WR(par, PM2R_RD_CURSOR_DATA, *mask);
1467 mask++;
1468 }
1469 for (; k > 0; k--)
1470 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1471 }
1472 for (; i < 64; i++) {
1473 int j = 8;
1474 WAIT_FIFO(par, 8);
1475 while (j-- > 0)
1476 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1477 }
1478 }
1479 return 0;
1158} 1480}
1159 1481
1160/* ------------ Hardware Independent Functions ------------ */ 1482/* ------------ Hardware Independent Functions ------------ */
@@ -1172,8 +1494,9 @@ static struct fb_ops pm2fb_ops = {
1172 .fb_pan_display = pm2fb_pan_display, 1494 .fb_pan_display = pm2fb_pan_display,
1173 .fb_fillrect = pm2fb_fillrect, 1495 .fb_fillrect = pm2fb_fillrect,
1174 .fb_copyarea = pm2fb_copyarea, 1496 .fb_copyarea = pm2fb_copyarea,
1175 .fb_imageblit = cfb_imageblit, 1497 .fb_imageblit = pm2fb_imageblit,
1176 .fb_sync = pm2fb_sync, 1498 .fb_sync = pm2fb_sync,
1499 .fb_cursor = pm2fb_cursor,
1177}; 1500};
1178 1501
1179/* 1502/*
@@ -1194,16 +1517,17 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1194{ 1517{
1195 struct pm2fb_par *default_par; 1518 struct pm2fb_par *default_par;
1196 struct fb_info *info; 1519 struct fb_info *info;
1197 int err, err_retval = -ENXIO; 1520 int err;
1521 int retval = -ENXIO;
1198 1522
1199 err = pci_enable_device(pdev); 1523 err = pci_enable_device(pdev);
1200 if ( err ) { 1524 if (err) {
1201 printk(KERN_WARNING "pm2fb: Can't enable pdev: %d\n", err); 1525 printk(KERN_WARNING "pm2fb: Can't enable pdev: %d\n", err);
1202 return err; 1526 return err;
1203 } 1527 }
1204 1528
1205 info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev); 1529 info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev);
1206 if ( !info ) 1530 if (!info)
1207 return -ENOMEM; 1531 return -ENOMEM;
1208 default_par = info->par; 1532 default_par = info->par;
1209 1533
@@ -1236,14 +1560,14 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1236 DPRINTK("Register base at 0x%lx\n", pm2fb_fix.mmio_start); 1560 DPRINTK("Register base at 0x%lx\n", pm2fb_fix.mmio_start);
1237 1561
1238 /* Registers - request region and map it. */ 1562 /* Registers - request region and map it. */
1239 if ( !request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len, 1563 if (!request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len,
1240 "pm2fb regbase") ) { 1564 "pm2fb regbase")) {
1241 printk(KERN_WARNING "pm2fb: Can't reserve regbase.\n"); 1565 printk(KERN_WARNING "pm2fb: Can't reserve regbase.\n");
1242 goto err_exit_neither; 1566 goto err_exit_neither;
1243 } 1567 }
1244 default_par->v_regs = 1568 default_par->v_regs =
1245 ioremap_nocache(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len); 1569 ioremap_nocache(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
1246 if ( !default_par->v_regs ) { 1570 if (!default_par->v_regs) {
1247 printk(KERN_WARNING "pm2fb: Can't remap %s register area.\n", 1571 printk(KERN_WARNING "pm2fb: Can't remap %s register area.\n",
1248 pm2fb_fix.id); 1572 pm2fb_fix.id);
1249 release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len); 1573 release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
@@ -1258,72 +1582,101 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1258 default_par->mem_control, default_par->boot_address, 1582 default_par->mem_control, default_par->boot_address,
1259 default_par->mem_config); 1583 default_par->mem_config);
1260 1584
1261 if(default_par->mem_control == 0 && 1585 if (default_par->mem_control == 0 &&
1262 default_par->boot_address == 0x31 && 1586 default_par->boot_address == 0x31 &&
1263 default_par->mem_config == 0x259fffff) { 1587 default_par->mem_config == 0x259fffff) {
1264 default_par->memclock = CVPPC_MEMCLOCK; 1588 default_par->memclock = CVPPC_MEMCLOCK;
1265 default_par->mem_control=0; 1589 default_par->mem_control = 0;
1266 default_par->boot_address=0x20; 1590 default_par->boot_address = 0x20;
1267 default_par->mem_config=0xe6002021; 1591 default_par->mem_config = 0xe6002021;
1268 if (pdev->subsystem_vendor == 0x1048 && 1592 if (pdev->subsystem_vendor == 0x1048 &&
1269 pdev->subsystem_device == 0x0a31) { 1593 pdev->subsystem_device == 0x0a31) {
1270 DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n", 1594 DPRINTK("subsystem_vendor: %04x, "
1595 "subsystem_device: %04x\n",
1271 pdev->subsystem_vendor, pdev->subsystem_device); 1596 pdev->subsystem_vendor, pdev->subsystem_device);
1272 DPRINTK("We have not been initialized by VGA BIOS " 1597 DPRINTK("We have not been initialized by VGA BIOS and "
1273 "and are running on an Elsa Winner 2000 Office\n"); 1598 "are running on an Elsa Winner 2000 Office\n");
1274 DPRINTK("Initializing card timings manually...\n"); 1599 DPRINTK("Initializing card timings manually...\n");
1275 default_par->memclock=70000; 1600 default_par->memclock = 100000;
1276 } 1601 }
1277 if (pdev->subsystem_vendor == 0x3d3d && 1602 if (pdev->subsystem_vendor == 0x3d3d &&
1278 pdev->subsystem_device == 0x0100) { 1603 pdev->subsystem_device == 0x0100) {
1279 DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n", 1604 DPRINTK("subsystem_vendor: %04x, "
1605 "subsystem_device: %04x\n",
1280 pdev->subsystem_vendor, pdev->subsystem_device); 1606 pdev->subsystem_vendor, pdev->subsystem_device);
1281 DPRINTK("We have not been initialized by VGA BIOS " 1607 DPRINTK("We have not been initialized by VGA BIOS and "
1282 "and are running on an 3dlabs reference board\n"); 1608 "are running on an 3dlabs reference board\n");
1283 DPRINTK("Initializing card timings manually...\n"); 1609 DPRINTK("Initializing card timings manually...\n");
1284 default_par->memclock=74894; 1610 default_par->memclock = 74894;
1285 } 1611 }
1286 } 1612 }
1287 1613
1288 /* Now work out how big lfb is going to be. */ 1614 /* Now work out how big lfb is going to be. */
1289 switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) { 1615 switch (default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
1290 case PM2F_MEM_BANKS_1: 1616 case PM2F_MEM_BANKS_1:
1291 pm2fb_fix.smem_len=0x200000; 1617 pm2fb_fix.smem_len = 0x200000;
1292 break; 1618 break;
1293 case PM2F_MEM_BANKS_2: 1619 case PM2F_MEM_BANKS_2:
1294 pm2fb_fix.smem_len=0x400000; 1620 pm2fb_fix.smem_len = 0x400000;
1295 break; 1621 break;
1296 case PM2F_MEM_BANKS_3: 1622 case PM2F_MEM_BANKS_3:
1297 pm2fb_fix.smem_len=0x600000; 1623 pm2fb_fix.smem_len = 0x600000;
1298 break; 1624 break;
1299 case PM2F_MEM_BANKS_4: 1625 case PM2F_MEM_BANKS_4:
1300 pm2fb_fix.smem_len=0x800000; 1626 pm2fb_fix.smem_len = 0x800000;
1301 break; 1627 break;
1302 } 1628 }
1303 pm2fb_fix.smem_start = pci_resource_start(pdev, 1); 1629 pm2fb_fix.smem_start = pci_resource_start(pdev, 1);
1304 1630
1305 /* Linear frame buffer - request region and map it. */ 1631 /* Linear frame buffer - request region and map it. */
1306 if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len, 1632 if (!request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len,
1307 "pm2fb smem") ) { 1633 "pm2fb smem")) {
1308 printk(KERN_WARNING "pm2fb: Can't reserve smem.\n"); 1634 printk(KERN_WARNING "pm2fb: Can't reserve smem.\n");
1309 goto err_exit_mmio; 1635 goto err_exit_mmio;
1310 } 1636 }
1311 info->screen_base = 1637 info->screen_base =
1312 ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len); 1638 ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
1313 if ( !info->screen_base ) { 1639 if (!info->screen_base) {
1314 printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n"); 1640 printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n");
1315 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); 1641 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
1316 goto err_exit_mmio; 1642 goto err_exit_mmio;
1317 } 1643 }
1318 1644
1645#ifdef CONFIG_MTRR
1646 default_par->mtrr_handle = -1;
1647 if (!nomtrr)
1648 default_par->mtrr_handle =
1649 mtrr_add(pm2fb_fix.smem_start,
1650 pm2fb_fix.smem_len,
1651 MTRR_TYPE_WRCOMB, 1);
1652#endif
1653
1319 info->fbops = &pm2fb_ops; 1654 info->fbops = &pm2fb_ops;
1320 info->fix = pm2fb_fix; 1655 info->fix = pm2fb_fix;
1321 info->pseudo_palette = default_par->palette; 1656 info->pseudo_palette = default_par->palette;
1322 info->flags = FBINFO_DEFAULT | 1657 info->flags = FBINFO_DEFAULT |
1323 FBINFO_HWACCEL_YPAN | 1658 FBINFO_HWACCEL_YPAN |
1324 FBINFO_HWACCEL_COPYAREA | 1659 FBINFO_HWACCEL_COPYAREA |
1660 FBINFO_HWACCEL_IMAGEBLIT |
1325 FBINFO_HWACCEL_FILLRECT; 1661 FBINFO_HWACCEL_FILLRECT;
1326 1662
1663 info->pixmap.addr = kmalloc(PM2_PIXMAP_SIZE, GFP_KERNEL);
1664 if (!info->pixmap.addr) {
1665 retval = -ENOMEM;
1666 goto err_exit_pixmap;
1667 }
1668 info->pixmap.size = PM2_PIXMAP_SIZE;
1669 info->pixmap.buf_align = 4;
1670 info->pixmap.scan_align = 4;
1671 info->pixmap.access_align = 32;
1672 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1673
1674 if (noaccel) {
1675 printk(KERN_DEBUG "disabling acceleration\n");
1676 info->flags |= FBINFO_HWACCEL_DISABLED;
1677 info->pixmap.scan_align = 1;
1678 }
1679
1327 if (!mode) 1680 if (!mode)
1328 mode = "640x480@60"; 1681 mode = "640x480@60";
1329 1682
@@ -1350,6 +1703,8 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1350 err_exit_all: 1703 err_exit_all:
1351 fb_dealloc_cmap(&info->cmap); 1704 fb_dealloc_cmap(&info->cmap);
1352 err_exit_both: 1705 err_exit_both:
1706 kfree(info->pixmap.addr);
1707 err_exit_pixmap:
1353 iounmap(info->screen_base); 1708 iounmap(info->screen_base);
1354 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); 1709 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
1355 err_exit_mmio: 1710 err_exit_mmio:
@@ -1357,7 +1712,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1357 release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len); 1712 release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
1358 err_exit_neither: 1713 err_exit_neither:
1359 framebuffer_release(info); 1714 framebuffer_release(info);
1360 return err_retval; 1715 return retval;
1361} 1716}
1362 1717
1363/** 1718/**
@@ -1369,34 +1724,34 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1369 */ 1724 */
1370static void __devexit pm2fb_remove(struct pci_dev *pdev) 1725static void __devexit pm2fb_remove(struct pci_dev *pdev)
1371{ 1726{
1372 struct fb_info* info = pci_get_drvdata(pdev); 1727 struct fb_info *info = pci_get_drvdata(pdev);
1373 struct fb_fix_screeninfo* fix = &info->fix; 1728 struct fb_fix_screeninfo *fix = &info->fix;
1374 struct pm2fb_par *par = info->par; 1729 struct pm2fb_par *par = info->par;
1375 1730
1376 unregister_framebuffer(info); 1731 unregister_framebuffer(info);
1377 1732
1733#ifdef CONFIG_MTRR
1734 if (par->mtrr_handle >= 0)
1735 mtrr_del(par->mtrr_handle, info->fix.smem_start,
1736 info->fix.smem_len);
1737#endif /* CONFIG_MTRR */
1378 iounmap(info->screen_base); 1738 iounmap(info->screen_base);
1379 release_mem_region(fix->smem_start, fix->smem_len); 1739 release_mem_region(fix->smem_start, fix->smem_len);
1380 iounmap(par->v_regs); 1740 iounmap(par->v_regs);
1381 release_mem_region(fix->mmio_start, fix->mmio_len); 1741 release_mem_region(fix->mmio_start, fix->mmio_len);
1382 1742
1383 pci_set_drvdata(pdev, NULL); 1743 pci_set_drvdata(pdev, NULL);
1744 kfree(info->pixmap.addr);
1384 kfree(info); 1745 kfree(info);
1385} 1746}
1386 1747
1387static struct pci_device_id pm2fb_id_table[] = { 1748static struct pci_device_id pm2fb_id_table[] = {
1388 { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TVP4020, 1749 { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TVP4020,
1389 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, 1750 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
1390 0xff0000, 0 },
1391 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2, 1751 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2,
1392 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, 1752 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
1393 0xff0000, 0 },
1394 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
1395 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
1396 0xff0000, 0 },
1397 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V, 1753 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
1398 PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA << 8, 1754 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
1399 0xff00, 0 },
1400 { 0, } 1755 { 0, }
1401}; 1756};
1402 1757
@@ -1418,7 +1773,7 @@ MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
1418 */ 1773 */
1419static int __init pm2fb_setup(char *options) 1774static int __init pm2fb_setup(char *options)
1420{ 1775{
1421 char* this_opt; 1776 char *this_opt;
1422 1777
1423 if (!options || !*options) 1778 if (!options || !*options)
1424 return 0; 1779 return 0;
@@ -1426,13 +1781,20 @@ static int __init pm2fb_setup(char *options)
1426 while ((this_opt = strsep(&options, ",")) != NULL) { 1781 while ((this_opt = strsep(&options, ",")) != NULL) {
1427 if (!*this_opt) 1782 if (!*this_opt)
1428 continue; 1783 continue;
1429 if(!strcmp(this_opt, "lowhsync")) { 1784 if (!strcmp(this_opt, "lowhsync"))
1430 lowhsync = 1; 1785 lowhsync = 1;
1431 } else if(!strcmp(this_opt, "lowvsync")) { 1786 else if (!strcmp(this_opt, "lowvsync"))
1432 lowvsync = 1; 1787 lowvsync = 1;
1433 } else { 1788 else if (!strncmp(this_opt, "hwcursor=", 9))
1789 hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
1790#ifdef CONFIG_MTRR
1791 else if (!strncmp(this_opt, "nomtrr", 6))
1792 nomtrr = 1;
1793#endif
1794 else if (!strncmp(this_opt, "noaccel", 7))
1795 noaccel = 1;
1796 else
1434 mode = this_opt; 1797 mode = this_opt;
1435 }
1436 } 1798 }
1437 return 0; 1799 return 0;
1438} 1800}
@@ -1474,6 +1836,15 @@ module_param(lowhsync, bool, 0);
1474MODULE_PARM_DESC(lowhsync, "Force horizontal sync low regardless of mode"); 1836MODULE_PARM_DESC(lowhsync, "Force horizontal sync low regardless of mode");
1475module_param(lowvsync, bool, 0); 1837module_param(lowvsync, bool, 0);
1476MODULE_PARM_DESC(lowvsync, "Force vertical sync low regardless of mode"); 1838MODULE_PARM_DESC(lowvsync, "Force vertical sync low regardless of mode");
1839module_param(noaccel, bool, 0);
1840MODULE_PARM_DESC(noaccel, "Disable acceleration");
1841module_param(hwcursor, int, 0644);
1842MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
1843 "(1=enable, 0=disable, default=1)");
1844#ifdef CONFIG_MTRR
1845module_param(nomtrr, bool, 0);
1846MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
1847#endif
1477 1848
1478MODULE_AUTHOR("Jim Hague <jim.hague@acm.org>"); 1849MODULE_AUTHOR("Jim Hague <jim.hague@acm.org>");
1479MODULE_DESCRIPTION("Permedia2 framebuffer device driver"); 1850MODULE_DESCRIPTION("Permedia2 framebuffer device driver");
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 5b3f54c0918e..070659992c18 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -32,6 +32,9 @@
32#include <linux/fb.h> 32#include <linux/fb.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/pci.h> 34#include <linux/pci.h>
35#ifdef CONFIG_MTRR
36#include <asm/mtrr.h>
37#endif
35 38
36#include <video/pm3fb.h> 39#include <video/pm3fb.h>
37 40
@@ -41,15 +44,25 @@
41 44
42#undef PM3FB_MASTER_DEBUG 45#undef PM3FB_MASTER_DEBUG
43#ifdef PM3FB_MASTER_DEBUG 46#ifdef PM3FB_MASTER_DEBUG
44#define DPRINTK(a,b...) printk(KERN_DEBUG "pm3fb: %s: " a, __FUNCTION__ , ## b) 47#define DPRINTK(a, b...) \
48 printk(KERN_DEBUG "pm3fb: %s: " a, __FUNCTION__ , ## b)
45#else 49#else
46#define DPRINTK(a,b...) 50#define DPRINTK(a, b...)
47#endif 51#endif
48 52
53#define PM3_PIXMAP_SIZE (2048 * 4)
54
49/* 55/*
50 * Driver data 56 * Driver data
51 */ 57 */
58static int hwcursor = 1;
52static char *mode_option __devinitdata; 59static char *mode_option __devinitdata;
60static int noaccel __devinitdata;
61
62/* mtrr option */
63#ifdef CONFIG_MTRR
64static int nomtrr __devinitdata;
65#endif
53 66
54/* 67/*
55 * This structure defines the hardware state of the graphics card. Normally 68 * This structure defines the hardware state of the graphics card. Normally
@@ -61,8 +74,9 @@ static char *mode_option __devinitdata;
61struct pm3_par { 74struct pm3_par {
62 unsigned char __iomem *v_regs;/* virtual address of p_regs */ 75 unsigned char __iomem *v_regs;/* virtual address of p_regs */
63 u32 video; /* video flags before blanking */ 76 u32 video; /* video flags before blanking */
64 u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */ 77 u32 base; /* screen base in 128 bits unit */
65 u32 palette[16]; 78 u32 palette[16];
79 int mtrr_handle;
66}; 80};
67 81
68/* 82/*
@@ -96,7 +110,8 @@ static inline void PM3_WRITE_REG(struct pm3_par *par, s32 off, u32 v)
96 110
97static inline void PM3_WAIT(struct pm3_par *par, u32 n) 111static inline void PM3_WAIT(struct pm3_par *par, u32 n)
98{ 112{
99 while (PM3_READ_REG(par, PM3InFIFOSpace) < n); 113 while (PM3_READ_REG(par, PM3InFIFOSpace) < n)
114 cpu_relax();
100} 115}
101 116
102static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v) 117static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v)
@@ -133,7 +148,7 @@ static void pm3fb_clear_colormap(struct pm3_par *par,
133 148
134} 149}
135 150
136/* Calculating various clock parameter */ 151/* Calculating various clock parameters */
137static void pm3fb_calculate_clock(unsigned long reqclock, 152static void pm3fb_calculate_clock(unsigned long reqclock,
138 unsigned char *prescale, 153 unsigned char *prescale,
139 unsigned char *feedback, 154 unsigned char *feedback,
@@ -164,7 +179,7 @@ static void pm3fb_calculate_clock(unsigned long reqclock,
164 179
165static inline int pm3fb_depth(const struct fb_var_screeninfo *var) 180static inline int pm3fb_depth(const struct fb_var_screeninfo *var)
166{ 181{
167 if ( var->bits_per_pixel == 16 ) 182 if (var->bits_per_pixel == 16)
168 return var->red.length + var->green.length 183 return var->red.length + var->green.length
169 + var->blue.length; 184 + var->blue.length;
170 185
@@ -195,8 +210,8 @@ static int pm3fb_sync(struct fb_info *info)
195 PM3_WRITE_REG(par, PM3Sync, 0); 210 PM3_WRITE_REG(par, PM3Sync, 0);
196 mb(); 211 mb();
197 do { 212 do {
198 while ((PM3_READ_REG(par, PM3OutFIFOWords)) == 0); 213 while ((PM3_READ_REG(par, PM3OutFIFOWords)) == 0)
199 rmb(); 214 cpu_relax();
200 } while ((PM3_READ_REG(par, PM3OutputFifo)) != PM3Sync_Tag); 215 } while ((PM3_READ_REG(par, PM3OutputFifo)) != PM3Sync_Tag);
201 216
202 return 0; 217 return 0;
@@ -276,15 +291,22 @@ static void pm3fb_init_engine(struct fb_info *info)
276 291
277 PM3_WAIT(par, 2); 292 PM3_WAIT(par, 2);
278 { 293 {
279 unsigned long rm = 1; 294 /* invert bits in bitmask */
295 unsigned long rm = 1 | (3 << 7);
280 switch (info->var.bits_per_pixel) { 296 switch (info->var.bits_per_pixel) {
281 case 8: 297 case 8:
282 PM3_WRITE_REG(par, PM3PixelSize, 298 PM3_WRITE_REG(par, PM3PixelSize,
283 PM3PixelSize_GLOBAL_8BIT); 299 PM3PixelSize_GLOBAL_8BIT);
300#ifdef __BIG_ENDIAN
301 rm |= 3 << 15;
302#endif
284 break; 303 break;
285 case 16: 304 case 16:
286 PM3_WRITE_REG(par, PM3PixelSize, 305 PM3_WRITE_REG(par, PM3PixelSize,
287 PM3PixelSize_GLOBAL_16BIT); 306 PM3PixelSize_GLOBAL_16BIT);
307#ifdef __BIG_ENDIAN
308 rm |= 2 << 15;
309#endif
288 break; 310 break;
289 case 32: 311 case 32:
290 PM3_WRITE_REG(par, PM3PixelSize, 312 PM3_WRITE_REG(par, PM3PixelSize,
@@ -342,7 +364,7 @@ static void pm3fb_init_engine(struct fb_info *info)
342 364
343 PM3_WRITE_REG(par, PM3dXDom, 0x0); 365 PM3_WRITE_REG(par, PM3dXDom, 0x0);
344 PM3_WRITE_REG(par, PM3dXSub, 0x0); 366 PM3_WRITE_REG(par, PM3dXSub, 0x0);
345 PM3_WRITE_REG(par, PM3dY, (1 << 16)); 367 PM3_WRITE_REG(par, PM3dY, 1 << 16);
346 PM3_WRITE_REG(par, PM3StartXDom, 0x0); 368 PM3_WRITE_REG(par, PM3StartXDom, 0x0);
347 PM3_WRITE_REG(par, PM3StartXSub, 0x0); 369 PM3_WRITE_REG(par, PM3StartXSub, 0x0);
348 PM3_WRITE_REG(par, PM3StartY, 0x0); 370 PM3_WRITE_REG(par, PM3StartY, 0x0);
@@ -357,71 +379,350 @@ static void pm3fb_init_engine(struct fb_info *info)
357 pm3fb_sync(info); 379 pm3fb_sync(info);
358} 380}
359 381
360static void pm3fb_fillrect (struct fb_info *info, 382static void pm3fb_fillrect(struct fb_info *info,
361 const struct fb_fillrect *region) 383 const struct fb_fillrect *region)
362{ 384{
363 struct pm3_par *par = info->par; 385 struct pm3_par *par = info->par;
364 struct fb_fillrect modded; 386 struct fb_fillrect modded;
365 int vxres, vyres; 387 int vxres, vyres;
388 int rop;
366 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? 389 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
367 ((u32*)info->pseudo_palette)[region->color] : region->color; 390 ((u32 *)info->pseudo_palette)[region->color] : region->color;
368 391
369 if (info->state != FBINFO_STATE_RUNNING) 392 if (info->state != FBINFO_STATE_RUNNING)
370 return; 393 return;
371 if ((info->flags & FBINFO_HWACCEL_DISABLED) || 394 if (info->flags & FBINFO_HWACCEL_DISABLED) {
372 region->rop != ROP_COPY ) {
373 cfb_fillrect(info, region); 395 cfb_fillrect(info, region);
374 return; 396 return;
375 } 397 }
398 if (region->rop == ROP_COPY )
399 rop = PM3Config2D_ForegroundROP(0x3); /* GXcopy */
400 else
401 rop = PM3Config2D_ForegroundROP(0x6) | /* GXxor */
402 PM3Config2D_FBDestReadEnable;
376 403
377 vxres = info->var.xres_virtual; 404 vxres = info->var.xres_virtual;
378 vyres = info->var.yres_virtual; 405 vyres = info->var.yres_virtual;
379 406
380 memcpy(&modded, region, sizeof(struct fb_fillrect)); 407 memcpy(&modded, region, sizeof(struct fb_fillrect));
381 408
382 if(!modded.width || !modded.height || 409 if (!modded.width || !modded.height ||
383 modded.dx >= vxres || modded.dy >= vyres) 410 modded.dx >= vxres || modded.dy >= vyres)
384 return; 411 return;
385 412
386 if(modded.dx + modded.width > vxres) 413 if (modded.dx + modded.width > vxres)
387 modded.width = vxres - modded.dx; 414 modded.width = vxres - modded.dx;
388 if(modded.dy + modded.height > vyres) 415 if (modded.dy + modded.height > vyres)
389 modded.height = vyres - modded.dy; 416 modded.height = vyres - modded.dy;
390 417
391 if(info->var.bits_per_pixel == 8) 418 if (info->var.bits_per_pixel == 8)
392 color |= color << 8; 419 color |= color << 8;
393 if(info->var.bits_per_pixel <= 16) 420 if (info->var.bits_per_pixel <= 16)
394 color |= color << 16; 421 color |= color << 16;
395 422
396 PM3_WAIT(par, 4); 423 PM3_WAIT(par, 4);
397 424 /* ROP Ox3 is GXcopy */
398 PM3_WRITE_REG(par, PM3Config2D, 425 PM3_WRITE_REG(par, PM3Config2D,
399 PM3Config2D_UseConstantSource | 426 PM3Config2D_UseConstantSource |
400 PM3Config2D_ForegroundROPEnable | 427 PM3Config2D_ForegroundROPEnable |
401 (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */ 428 rop |
402 PM3Config2D_FBWriteEnable); 429 PM3Config2D_FBWriteEnable);
403 430
404 PM3_WRITE_REG(par, PM3ForegroundColor, color); 431 PM3_WRITE_REG(par, PM3ForegroundColor, color);
405 432
406 PM3_WRITE_REG(par, PM3RectanglePosition, 433 PM3_WRITE_REG(par, PM3RectanglePosition,
407 (PM3RectanglePosition_XOffset(modded.dx)) | 434 PM3RectanglePosition_XOffset(modded.dx) |
408 (PM3RectanglePosition_YOffset(modded.dy))); 435 PM3RectanglePosition_YOffset(modded.dy));
409 436
410 PM3_WRITE_REG(par, PM3Render2D, 437 PM3_WRITE_REG(par, PM3Render2D,
411 PM3Render2D_XPositive | 438 PM3Render2D_XPositive |
412 PM3Render2D_YPositive | 439 PM3Render2D_YPositive |
413 PM3Render2D_Operation_Normal | 440 PM3Render2D_Operation_Normal |
414 PM3Render2D_SpanOperation | 441 PM3Render2D_SpanOperation |
415 (PM3Render2D_Width(modded.width)) | 442 PM3Render2D_Width(modded.width) |
416 (PM3Render2D_Height(modded.height))); 443 PM3Render2D_Height(modded.height));
444}
445
446static void pm3fb_copyarea(struct fb_info *info,
447 const struct fb_copyarea *area)
448{
449 struct pm3_par *par = info->par;
450 struct fb_copyarea modded;
451 u32 vxres, vyres;
452 int x_align, o_x, o_y;
453
454 if (info->state != FBINFO_STATE_RUNNING)
455 return;
456 if (info->flags & FBINFO_HWACCEL_DISABLED) {
457 cfb_copyarea(info, area);
458 return;
459 }
460
461 memcpy(&modded, area, sizeof(struct fb_copyarea));
462
463 vxres = info->var.xres_virtual;
464 vyres = info->var.yres_virtual;
465
466 if (!modded.width || !modded.height ||
467 modded.sx >= vxres || modded.sy >= vyres ||
468 modded.dx >= vxres || modded.dy >= vyres)
469 return;
470
471 if (modded.sx + modded.width > vxres)
472 modded.width = vxres - modded.sx;
473 if (modded.dx + modded.width > vxres)
474 modded.width = vxres - modded.dx;
475 if (modded.sy + modded.height > vyres)
476 modded.height = vyres - modded.sy;
477 if (modded.dy + modded.height > vyres)
478 modded.height = vyres - modded.dy;
479
480 o_x = modded.sx - modded.dx; /*(sx > dx ) ? (sx - dx) : (dx - sx); */
481 o_y = modded.sy - modded.dy; /*(sy > dy ) ? (sy - dy) : (dy - sy); */
482
483 x_align = (modded.sx & 0x1f);
484
485 PM3_WAIT(par, 6);
486
487 PM3_WRITE_REG(par, PM3Config2D,
488 PM3Config2D_UserScissorEnable |
489 PM3Config2D_ForegroundROPEnable |
490 PM3Config2D_Blocking |
491 PM3Config2D_ForegroundROP(0x3) | /* Ox3 is GXcopy */
492 PM3Config2D_FBWriteEnable);
493
494 PM3_WRITE_REG(par, PM3ScissorMinXY,
495 ((modded.dy & 0x0fff) << 16) | (modded.dx & 0x0fff));
496 PM3_WRITE_REG(par, PM3ScissorMaxXY,
497 (((modded.dy + modded.height) & 0x0fff) << 16) |
498 ((modded.dx + modded.width) & 0x0fff));
499
500 PM3_WRITE_REG(par, PM3FBSourceReadBufferOffset,
501 PM3FBSourceReadBufferOffset_XOffset(o_x) |
502 PM3FBSourceReadBufferOffset_YOffset(o_y));
503
504 PM3_WRITE_REG(par, PM3RectanglePosition,
505 PM3RectanglePosition_XOffset(modded.dx - x_align) |
506 PM3RectanglePosition_YOffset(modded.dy));
507
508 PM3_WRITE_REG(par, PM3Render2D,
509 ((modded.sx > modded.dx) ? PM3Render2D_XPositive : 0) |
510 ((modded.sy > modded.dy) ? PM3Render2D_YPositive : 0) |
511 PM3Render2D_Operation_Normal |
512 PM3Render2D_SpanOperation |
513 PM3Render2D_FBSourceReadEnable |
514 PM3Render2D_Width(modded.width + x_align) |
515 PM3Render2D_Height(modded.height));
516}
517
518static void pm3fb_imageblit(struct fb_info *info, const struct fb_image *image)
519{
520 struct pm3_par *par = info->par;
521 u32 height = image->height;
522 u32 fgx, bgx;
523 const u32 *src = (const u32 *)image->data;
524
525 if (info->state != FBINFO_STATE_RUNNING)
526 return;
527 if (info->flags & FBINFO_HWACCEL_DISABLED) {
528 cfb_imageblit(info, image);
529 return;
530 }
531 switch (info->fix.visual) {
532 case FB_VISUAL_PSEUDOCOLOR:
533 fgx = image->fg_color;
534 bgx = image->bg_color;
535 break;
536 case FB_VISUAL_TRUECOLOR:
537 default:
538 fgx = par->palette[image->fg_color];
539 bgx = par->palette[image->bg_color];
540 break;
541 }
542 if (image->depth != 1)
543 return cfb_imageblit(info, image);
544
545 if (info->var.bits_per_pixel == 8) {
546 fgx |= fgx << 8;
547 bgx |= bgx << 8;
548 }
549 if (info->var.bits_per_pixel <= 16) {
550 fgx |= fgx << 16;
551 bgx |= bgx << 16;
552 }
553
554 PM3_WAIT(par, 7);
555
556 PM3_WRITE_REG(par, PM3ForegroundColor, fgx);
557 PM3_WRITE_REG(par, PM3BackgroundColor, bgx);
558
559 /* ROP Ox3 is GXcopy */
560 PM3_WRITE_REG(par, PM3Config2D,
561 PM3Config2D_UserScissorEnable |
562 PM3Config2D_UseConstantSource |
563 PM3Config2D_ForegroundROPEnable |
564 PM3Config2D_ForegroundROP(0x3) |
565 PM3Config2D_OpaqueSpan |
566 PM3Config2D_FBWriteEnable);
567 PM3_WRITE_REG(par, PM3ScissorMinXY,
568 ((image->dy & 0x0fff) << 16) | (image->dx & 0x0fff));
569 PM3_WRITE_REG(par, PM3ScissorMaxXY,
570 (((image->dy + image->height) & 0x0fff) << 16) |
571 ((image->dx + image->width) & 0x0fff));
572 PM3_WRITE_REG(par, PM3RectanglePosition,
573 PM3RectanglePosition_XOffset(image->dx) |
574 PM3RectanglePosition_YOffset(image->dy));
575 PM3_WRITE_REG(par, PM3Render2D,
576 PM3Render2D_XPositive |
577 PM3Render2D_YPositive |
578 PM3Render2D_Operation_SyncOnBitMask |
579 PM3Render2D_SpanOperation |
580 PM3Render2D_Width(image->width) |
581 PM3Render2D_Height(image->height));
582
583
584 while (height--) {
585 int width = ((image->width + 7) >> 3)
586 + info->pixmap.scan_align - 1;
587 width >>= 2;
588
589 while (width >= PM3_FIFO_SIZE) {
590 int i = PM3_FIFO_SIZE - 1;
591
592 PM3_WAIT(par, PM3_FIFO_SIZE);
593 while (i--) {
594 PM3_WRITE_REG(par, PM3BitMaskPattern, *src);
595 src++;
596 }
597 width -= PM3_FIFO_SIZE - 1;
598 }
599
600 PM3_WAIT(par, width + 1);
601 while (width--) {
602 PM3_WRITE_REG(par, PM3BitMaskPattern, *src);
603 src++;
604 }
605 }
417} 606}
418/* end of acceleration functions */ 607/* end of acceleration functions */
419 608
609/*
610 * Hardware Cursor support.
611 */
612static const u8 cursor_bits_lookup[16] = {
613 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
614 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
615};
616
617static int pm3fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
618{
619 struct pm3_par *par = info->par;
620 u8 mode;
621
622 if (!hwcursor)
623 return -EINVAL; /* just to force soft_cursor() call */
624
625 /* Too large of a cursor or wrong bpp :-( */
626 if (cursor->image.width > 64 ||
627 cursor->image.height > 64 ||
628 cursor->image.depth > 1)
629 return -EINVAL;
630
631 mode = PM3RD_CursorMode_TYPE_X;
632 if (cursor->enable)
633 mode |= PM3RD_CursorMode_CURSOR_ENABLE;
634
635 PM3_WRITE_DAC_REG(par, PM3RD_CursorMode, mode);
636
637 /*
638 * If the cursor is not be changed this means either we want the
639 * current cursor state (if enable is set) or we want to query what
640 * we can do with the cursor (if enable is not set)
641 */
642 if (!cursor->set)
643 return 0;
644
645 if (cursor->set & FB_CUR_SETPOS) {
646 int x = cursor->image.dx - info->var.xoffset;
647 int y = cursor->image.dy - info->var.yoffset;
648
649 PM3_WRITE_DAC_REG(par, PM3RD_CursorXLow, x & 0xff);
650 PM3_WRITE_DAC_REG(par, PM3RD_CursorXHigh, (x >> 8) & 0xf);
651 PM3_WRITE_DAC_REG(par, PM3RD_CursorYLow, y & 0xff);
652 PM3_WRITE_DAC_REG(par, PM3RD_CursorYHigh, (y >> 8) & 0xf);
653 }
654
655 if (cursor->set & FB_CUR_SETHOT) {
656 PM3_WRITE_DAC_REG(par, PM3RD_CursorHotSpotX,
657 cursor->hot.x & 0x3f);
658 PM3_WRITE_DAC_REG(par, PM3RD_CursorHotSpotY,
659 cursor->hot.y & 0x3f);
660 }
661
662 if (cursor->set & FB_CUR_SETCMAP) {
663 u32 fg_idx = cursor->image.fg_color;
664 u32 bg_idx = cursor->image.bg_color;
665 struct fb_cmap cmap = info->cmap;
666
667 /* the X11 driver says one should use these color registers */
668 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(39),
669 cmap.red[fg_idx] >> 8 );
670 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(40),
671 cmap.green[fg_idx] >> 8 );
672 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(41),
673 cmap.blue[fg_idx] >> 8 );
674
675 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(42),
676 cmap.red[bg_idx] >> 8 );
677 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(43),
678 cmap.green[bg_idx] >> 8 );
679 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(44),
680 cmap.blue[bg_idx] >> 8 );
681 }
682
683 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
684 u8 *bitmap = (u8 *)cursor->image.data;
685 u8 *mask = (u8 *)cursor->mask;
686 int i;
687 int pos = PM3RD_CursorPattern(0);
688
689 for (i = 0; i < cursor->image.height; i++) {
690 int j = (cursor->image.width + 7) >> 3;
691 int k = 8 - j;
692
693 for (; j > 0; j--) {
694 u8 data = *bitmap ^ *mask;
695
696 if (cursor->rop == ROP_COPY)
697 data = *mask & *bitmap;
698 /* Upper 4 bits of bitmap data */
699 PM3_WRITE_DAC_REG(par, pos++,
700 cursor_bits_lookup[data >> 4] |
701 (cursor_bits_lookup[*mask >> 4] << 1));
702 /* Lower 4 bits of bitmap */
703 PM3_WRITE_DAC_REG(par, pos++,
704 cursor_bits_lookup[data & 0xf] |
705 (cursor_bits_lookup[*mask & 0xf] << 1));
706 bitmap++;
707 mask++;
708 }
709 for (; k > 0; k--) {
710 PM3_WRITE_DAC_REG(par, pos++, 0);
711 PM3_WRITE_DAC_REG(par, pos++, 0);
712 }
713 }
714 while (pos < PM3RD_CursorPattern(1024))
715 PM3_WRITE_DAC_REG(par, pos++, 0);
716 }
717 return 0;
718}
719
420/* write the mode to registers */ 720/* write the mode to registers */
421static void pm3fb_write_mode(struct fb_info *info) 721static void pm3fb_write_mode(struct fb_info *info)
422{ 722{
423 struct pm3_par *par = info->par; 723 struct pm3_par *par = info->par;
424 char tempsync = 0x00, tempmisc = 0x00; 724 char tempsync = 0x00;
725 char tempmisc = 0x00;
425 const u32 hsstart = info->var.right_margin; 726 const u32 hsstart = info->var.right_margin;
426 const u32 hsend = hsstart + info->var.hsync_len; 727 const u32 hsend = hsstart + info->var.hsync_len;
427 const u32 hbend = hsend + info->var.left_margin; 728 const u32 hbend = hsend + info->var.left_margin;
@@ -618,47 +919,57 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
618 unsigned bpp = var->red.length + var->green.length 919 unsigned bpp = var->red.length + var->green.length
619 + var->blue.length + var->transp.length; 920 + var->blue.length + var->transp.length;
620 921
621 if ( bpp != var->bits_per_pixel ) { 922 if (bpp != var->bits_per_pixel) {
622 /* set predefined mode for bits_per_pixel settings */ 923 /* set predefined mode for bits_per_pixel settings */
623 924
624 switch(var->bits_per_pixel) { 925 switch (var->bits_per_pixel) {
625 case 8: 926 case 8:
626 var->red.length = var->green.length = var->blue.length = 8; 927 var->red.length = 8;
627 var->red.offset = var->green.offset = var->blue.offset = 0; 928 var->green.length = 8;
929 var->blue.length = 8;
930 var->red.offset = 0;
931 var->green.offset = 0;
932 var->blue.offset = 0;
628 var->transp.offset = 0; 933 var->transp.offset = 0;
629 var->transp.length = 0; 934 var->transp.length = 0;
630 break; 935 break;
631 case 16: 936 case 16:
632 var->red.length = var->blue.length = 5; 937 var->red.length = 5;
938 var->blue.length = 5;
633 var->green.length = 6; 939 var->green.length = 6;
634 var->transp.length = 0; 940 var->transp.length = 0;
635 break; 941 break;
636 case 32: 942 case 32:
637 var->red.length = var->green.length = var->blue.length = 8; 943 var->red.length = 8;
944 var->green.length = 8;
945 var->blue.length = 8;
638 var->transp.length = 8; 946 var->transp.length = 8;
639 break; 947 break;
640 default: 948 default:
641 DPRINTK("depth not supported: %u\n", var->bits_per_pixel); 949 DPRINTK("depth not supported: %u\n",
950 var->bits_per_pixel);
642 return -EINVAL; 951 return -EINVAL;
643 } 952 }
644 } 953 }
645 /* it is assumed BGRA order */ 954 /* it is assumed BGRA order */
646 if (var->bits_per_pixel > 8 ) 955 if (var->bits_per_pixel > 8 ) {
647 {
648 var->blue.offset = 0; 956 var->blue.offset = 0;
649 var->green.offset = var->blue.length; 957 var->green.offset = var->blue.length;
650 var->red.offset = var->green.offset + var->green.length; 958 var->red.offset = var->green.offset + var->green.length;
651 var->transp.offset = var->red.offset + var->red.length; 959 var->transp.offset = var->red.offset + var->red.length;
652 } 960 }
653 var->height = var->width = -1; 961 var->height = -1;
962 var->width = -1;
654 963
655 if (var->xres != var->xres_virtual) { 964 if (var->xres != var->xres_virtual) {
656 DPRINTK("virtual x resolution != physical x resolution not supported\n"); 965 DPRINTK("virtual x resolution != "
966 "physical x resolution not supported\n");
657 return -EINVAL; 967 return -EINVAL;
658 } 968 }
659 969
660 if (var->yres > var->yres_virtual) { 970 if (var->yres > var->yres_virtual) {
661 DPRINTK("virtual y resolution < physical y resolution not possible\n"); 971 DPRINTK("virtual y resolution < "
972 "physical y resolution not possible\n");
662 return -EINVAL; 973 return -EINVAL;
663 } 974 }
664 975
@@ -673,7 +984,7 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
673 } 984 }
674 985
675 var->xres = (var->xres + 31) & ~31; /* could sometimes be 8 */ 986 var->xres = (var->xres + 31) & ~31; /* could sometimes be 8 */
676 lpitch = var->xres * ((var->bits_per_pixel + 7)>>3); 987 lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
677 988
678 if (var->xres < 200 || var->xres > 2048) { 989 if (var->xres < 200 || var->xres > 2048) {
679 DPRINTK("width not supported: %u\n", var->xres); 990 DPRINTK("width not supported: %u\n", var->xres);
@@ -692,7 +1003,8 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
692 } 1003 }
693 1004
694 if (PICOS2KHZ(var->pixclock) > PM3_MAX_PIXCLOCK) { 1005 if (PICOS2KHZ(var->pixclock) > PM3_MAX_PIXCLOCK) {
695 DPRINTK("pixclock too high (%ldKHz)\n", PICOS2KHZ(var->pixclock)); 1006 DPRINTK("pixclock too high (%ldKHz)\n",
1007 PICOS2KHZ(var->pixclock));
696 return -EINVAL; 1008 return -EINVAL;
697 } 1009 }
698 1010
@@ -709,7 +1021,7 @@ static int pm3fb_set_par(struct fb_info *info)
709 const u32 xres = (info->var.xres + 31) & ~31; 1021 const u32 xres = (info->var.xres + 31) & ~31;
710 const unsigned bpp = info->var.bits_per_pixel; 1022 const unsigned bpp = info->var.bits_per_pixel;
711 1023
712 par->base = pm3fb_shift_bpp(bpp,(info->var.yoffset * xres) 1024 par->base = pm3fb_shift_bpp(bpp, (info->var.yoffset * xres)
713 + info->var.xoffset); 1025 + info->var.xoffset);
714 par->video = 0; 1026 par->video = 0;
715 1027
@@ -725,15 +1037,12 @@ static int pm3fb_set_par(struct fb_info *info)
725 1037
726 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) 1038 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
727 par->video |= PM3VideoControl_LINE_DOUBLE_ON; 1039 par->video |= PM3VideoControl_LINE_DOUBLE_ON;
728 else
729 par->video |= PM3VideoControl_LINE_DOUBLE_OFF;
730 1040
731 if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) 1041 if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
732 par->video |= PM3VideoControl_ENABLE; 1042 par->video |= PM3VideoControl_ENABLE;
733 else { 1043 else
734 par->video |= PM3VideoControl_DISABLE;
735 DPRINTK("PM3Video disabled\n"); 1044 DPRINTK("PM3Video disabled\n");
736 } 1045
737 switch (bpp) { 1046 switch (bpp) {
738 case 8: 1047 case 8:
739 par->video |= PM3VideoControl_PIXELSIZE_8BIT; 1048 par->video |= PM3VideoControl_PIXELSIZE_8BIT;
@@ -751,13 +1060,11 @@ static int pm3fb_set_par(struct fb_info *info)
751 1060
752 info->fix.visual = 1061 info->fix.visual =
753 (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 1062 (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
754 info->fix.line_length = ((info->var.xres_virtual + 7) & ~7) 1063 info->fix.line_length = ((info->var.xres_virtual + 7) >> 3) * bpp;
755 * bpp / 8;
756 1064
757/* pm3fb_clear_memory(info, 0);*/ 1065/* pm3fb_clear_memory(info, 0);*/
758 pm3fb_clear_colormap(par, 0, 0, 0); 1066 pm3fb_clear_colormap(par, 0, 0, 0);
759 PM3_WRITE_DAC_REG(par, PM3RD_CursorMode, 1067 PM3_WRITE_DAC_REG(par, PM3RD_CursorMode, 0);
760 PM3RD_CursorMode_CURSOR_DISABLE);
761 pm3fb_init_engine(info); 1068 pm3fb_init_engine(info);
762 pm3fb_write_mode(info); 1069 pm3fb_write_mode(info);
763 return 0; 1070 return 0;
@@ -773,10 +1080,9 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
773 return -EINVAL; 1080 return -EINVAL;
774 1081
775 /* grayscale works only partially under directcolor */ 1082 /* grayscale works only partially under directcolor */
776 if (info->var.grayscale) { 1083 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
777 /* grayscale = 0.30*R + 0.59*G + 0.11*B */ 1084 if (info->var.grayscale)
778 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; 1085 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
779 }
780 1086
781 /* Directcolor: 1087 /* Directcolor:
782 * var->{color}.offset contains start of bitfield 1088 * var->{color}.offset contains start of bitfield
@@ -790,8 +1096,8 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
790 * 1096 *
791 * Pseudocolor: 1097 * Pseudocolor:
792 * var->{color}.offset is 0 1098 * var->{color}.offset is 0
793 * var->{color}.length contains width of DAC or the number of unique 1099 * var->{color}.length contains width of DAC or the number
794 * colors available (color depth) 1100 * of unique colors available (color depth)
795 * pseudo_palette is not used 1101 * pseudo_palette is not used
796 * RAMDAC[X] is programmed to (red, green, blue) 1102 * RAMDAC[X] is programmed to (red, green, blue)
797 * color depth = var->{color}.length 1103 * color depth = var->{color}.length
@@ -801,7 +1107,7 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
801 * This is the point where the color is converted to something that 1107 * This is the point where the color is converted to something that
802 * is acceptable by the hardware. 1108 * is acceptable by the hardware.
803 */ 1109 */
804#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) 1110#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
805 red = CNVT_TOHW(red, info->var.red.length); 1111 red = CNVT_TOHW(red, info->var.red.length);
806 green = CNVT_TOHW(green, info->var.green.length); 1112 green = CNVT_TOHW(green, info->var.green.length);
807 blue = CNVT_TOHW(blue, info->var.blue.length); 1113 blue = CNVT_TOHW(blue, info->var.blue.length);
@@ -825,12 +1131,11 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
825 break; 1131 break;
826 case 16: 1132 case 16:
827 case 32: 1133 case 32:
828 ((u32*)(info->pseudo_palette))[regno] = v; 1134 ((u32 *)(info->pseudo_palette))[regno] = v;
829 break; 1135 break;
830 } 1136 }
831 return 0; 1137 return 0;
832 } 1138 } else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
833 else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
834 pm3fb_set_color(par, regno, red, green, blue); 1139 pm3fb_set_color(par, regno, red, green, blue);
835 1140
836 return 0; 1141 return 0;
@@ -871,7 +1176,7 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
871 video |= PM3VideoControl_ENABLE; 1176 video |= PM3VideoControl_ENABLE;
872 break; 1177 break;
873 case FB_BLANK_NORMAL: 1178 case FB_BLANK_NORMAL:
874 video &= ~(PM3VideoControl_ENABLE); 1179 video &= ~PM3VideoControl_ENABLE;
875 break; 1180 break;
876 case FB_BLANK_HSYNC_SUSPEND: 1181 case FB_BLANK_HSYNC_SUSPEND:
877 video &= ~(PM3VideoControl_HSYNC_MASK | 1182 video &= ~(PM3VideoControl_HSYNC_MASK |
@@ -892,7 +1197,7 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
892 } 1197 }
893 1198
894 PM3_WAIT(par, 1); 1199 PM3_WAIT(par, 1);
895 PM3_WRITE_REG(par,PM3VideoControl, video); 1200 PM3_WRITE_REG(par, PM3VideoControl, video);
896 return 0; 1201 return 0;
897} 1202}
898 1203
@@ -907,10 +1212,11 @@ static struct fb_ops pm3fb_ops = {
907 .fb_setcolreg = pm3fb_setcolreg, 1212 .fb_setcolreg = pm3fb_setcolreg,
908 .fb_pan_display = pm3fb_pan_display, 1213 .fb_pan_display = pm3fb_pan_display,
909 .fb_fillrect = pm3fb_fillrect, 1214 .fb_fillrect = pm3fb_fillrect,
910 .fb_copyarea = cfb_copyarea, 1215 .fb_copyarea = pm3fb_copyarea,
911 .fb_imageblit = cfb_imageblit, 1216 .fb_imageblit = pm3fb_imageblit,
912 .fb_blank = pm3fb_blank, 1217 .fb_blank = pm3fb_blank,
913 .fb_sync = pm3fb_sync, 1218 .fb_sync = pm3fb_sync,
1219 .fb_cursor = pm3fb_cursor,
914}; 1220};
915 1221
916/* ------------------------------------------------------------------------- */ 1222/* ------------------------------------------------------------------------- */
@@ -923,7 +1229,8 @@ static struct fb_ops pm3fb_ops = {
923/* the pm3fb_fix.smem_start is also set */ 1229/* the pm3fb_fix.smem_start is also set */
924static unsigned long pm3fb_size_memory(struct pm3_par *par) 1230static unsigned long pm3fb_size_memory(struct pm3_par *par)
925{ 1231{
926 unsigned long memsize = 0, tempBypass, i, temp1, temp2; 1232 unsigned long memsize = 0;
1233 unsigned long tempBypass, i, temp1, temp2;
927 unsigned char __iomem *screen_mem; 1234 unsigned char __iomem *screen_mem;
928 1235
929 pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */ 1236 pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */
@@ -951,7 +1258,9 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
951 PM3_WAIT(par, 1); 1258 PM3_WAIT(par, 1);
952 PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF); 1259 PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
953 1260
954 /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */ 1261 /* pm3 split up memory, replicates, and do a lot of
1262 * nasty stuff IMHO ;-)
1263 */
955 for (i = 0; i < 32; i++) { 1264 for (i = 0; i < 32; i++) {
956 fb_writel(i * 0x00345678, 1265 fb_writel(i * 0x00345678,
957 (screen_mem + (i * 1048576))); 1266 (screen_mem + (i * 1048576)));
@@ -1008,8 +1317,9 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1008{ 1317{
1009 struct fb_info *info; 1318 struct fb_info *info;
1010 struct pm3_par *par; 1319 struct pm3_par *par;
1011 struct device* device = &dev->dev; /* for pci drivers */ 1320 struct device *device = &dev->dev; /* for pci drivers */
1012 int err, retval = -ENXIO; 1321 int err;
1322 int retval = -ENXIO;
1013 1323
1014 err = pci_enable_device(dev); 1324 err = pci_enable_device(dev);
1015 if (err) { 1325 if (err) {
@@ -1031,6 +1341,10 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1031 */ 1341 */
1032 pm3fb_fix.mmio_start = pci_resource_start(dev, 0); 1342 pm3fb_fix.mmio_start = pci_resource_start(dev, 0);
1033 pm3fb_fix.mmio_len = PM3_REGS_SIZE; 1343 pm3fb_fix.mmio_len = PM3_REGS_SIZE;
1344#if defined(__BIG_ENDIAN)
1345 pm3fb_fix.mmio_start += PM3_REGS_SIZE;
1346 DPRINTK("Adjusting register base for big-endian.\n");
1347#endif
1034 1348
1035 /* Registers - request region and map it. */ 1349 /* Registers - request region and map it. */
1036 if (!request_mem_region(pm3fb_fix.mmio_start, pm3fb_fix.mmio_len, 1350 if (!request_mem_region(pm3fb_fix.mmio_start, pm3fb_fix.mmio_len,
@@ -1047,15 +1361,10 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1047 goto err_exit_neither; 1361 goto err_exit_neither;
1048 } 1362 }
1049 1363
1050#if defined(__BIG_ENDIAN)
1051 pm3fb_fix.mmio_start += PM3_REGS_SIZE;
1052 DPRINTK("Adjusting register base for big-endian.\n");
1053#endif
1054 /* Linear frame buffer - request region and map it. */ 1364 /* Linear frame buffer - request region and map it. */
1055 pm3fb_fix.smem_start = pci_resource_start(dev, 1); 1365 pm3fb_fix.smem_start = pci_resource_start(dev, 1);
1056 pm3fb_fix.smem_len = pm3fb_size_memory(par); 1366 pm3fb_fix.smem_len = pm3fb_size_memory(par);
1057 if (!pm3fb_fix.smem_len) 1367 if (!pm3fb_fix.smem_len) {
1058 {
1059 printk(KERN_WARNING "pm3fb: Can't find memory on board.\n"); 1368 printk(KERN_WARNING "pm3fb: Can't find memory on board.\n");
1060 goto err_exit_mmio; 1369 goto err_exit_mmio;
1061 } 1370 }
@@ -1073,6 +1382,12 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1073 } 1382 }
1074 info->screen_size = pm3fb_fix.smem_len; 1383 info->screen_size = pm3fb_fix.smem_len;
1075 1384
1385#ifdef CONFIG_MTRR
1386 if (!nomtrr)
1387 par->mtrr_handle = mtrr_add(pm3fb_fix.smem_start,
1388 pm3fb_fix.smem_len,
1389 MTRR_TYPE_WRCOMB, 1);
1390#endif
1076 info->fbops = &pm3fb_ops; 1391 info->fbops = &pm3fb_ops;
1077 1392
1078 par->video = PM3_READ_REG(par, PM3VideoControl); 1393 par->video = PM3_READ_REG(par, PM3VideoControl);
@@ -1080,7 +1395,26 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1080 info->fix = pm3fb_fix; 1395 info->fix = pm3fb_fix;
1081 info->pseudo_palette = par->palette; 1396 info->pseudo_palette = par->palette;
1082 info->flags = FBINFO_DEFAULT | 1397 info->flags = FBINFO_DEFAULT |
1083 FBINFO_HWACCEL_FILLRECT;/* | FBINFO_HWACCEL_YPAN;*/ 1398 FBINFO_HWACCEL_XPAN |
1399 FBINFO_HWACCEL_YPAN |
1400 FBINFO_HWACCEL_COPYAREA |
1401 FBINFO_HWACCEL_IMAGEBLIT |
1402 FBINFO_HWACCEL_FILLRECT;
1403
1404 if (noaccel) {
1405 printk(KERN_DEBUG "disabling acceleration\n");
1406 info->flags |= FBINFO_HWACCEL_DISABLED;
1407 }
1408 info->pixmap.addr = kmalloc(PM3_PIXMAP_SIZE, GFP_KERNEL);
1409 if (!info->pixmap.addr) {
1410 retval = -ENOMEM;
1411 goto err_exit_pixmap;
1412 }
1413 info->pixmap.size = PM3_PIXMAP_SIZE;
1414 info->pixmap.buf_align = 4;
1415 info->pixmap.scan_align = 4;
1416 info->pixmap.access_align = 32;
1417 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1084 1418
1085 /* 1419 /*
1086 * This should give a reasonable default video mode. The following is 1420 * This should give a reasonable default video mode. The following is
@@ -1118,6 +1452,8 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1118 err_exit_all: 1452 err_exit_all:
1119 fb_dealloc_cmap(&info->cmap); 1453 fb_dealloc_cmap(&info->cmap);
1120 err_exit_both: 1454 err_exit_both:
1455 kfree(info->pixmap.addr);
1456 err_exit_pixmap:
1121 iounmap(info->screen_base); 1457 iounmap(info->screen_base);
1122 release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len); 1458 release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
1123 err_exit_mmio: 1459 err_exit_mmio:
@@ -1142,12 +1478,18 @@ static void __devexit pm3fb_remove(struct pci_dev *dev)
1142 unregister_framebuffer(info); 1478 unregister_framebuffer(info);
1143 fb_dealloc_cmap(&info->cmap); 1479 fb_dealloc_cmap(&info->cmap);
1144 1480
1481#ifdef CONFIG_MTRR
1482 if (par->mtrr_handle >= 0)
1483 mtrr_del(par->mtrr_handle, info->fix.smem_start,
1484 info->fix.smem_len);
1485#endif /* CONFIG_MTRR */
1145 iounmap(info->screen_base); 1486 iounmap(info->screen_base);
1146 release_mem_region(fix->smem_start, fix->smem_len); 1487 release_mem_region(fix->smem_start, fix->smem_len);
1147 iounmap(par->v_regs); 1488 iounmap(par->v_regs);
1148 release_mem_region(fix->mmio_start, fix->mmio_len); 1489 release_mem_region(fix->mmio_start, fix->mmio_len);
1149 1490
1150 pci_set_drvdata(dev, NULL); 1491 pci_set_drvdata(dev, NULL);
1492 kfree(info->pixmap.addr);
1151 framebuffer_release(info); 1493 framebuffer_release(info);
1152 } 1494 }
1153} 1495}
@@ -1168,21 +1510,76 @@ static struct pci_driver pm3fb_driver = {
1168 1510
1169MODULE_DEVICE_TABLE(pci, pm3fb_id_table); 1511MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
1170 1512
1513#ifndef MODULE
1514 /*
1515 * Setup
1516 */
1517
1518/*
1519 * Only necessary if your driver takes special options,
1520 * otherwise we fall back on the generic fb_setup().
1521 */
1522static int __init pm3fb_setup(char *options)
1523{
1524 char *this_opt;
1525
1526 /* Parse user speficied options (`video=pm3fb:') */
1527 if (!options || !*options)
1528 return 0;
1529
1530 while ((this_opt = strsep(&options, ",")) != NULL) {
1531 if (!*this_opt)
1532 continue;
1533 else if (!strncmp(this_opt, "noaccel", 7))
1534 noaccel = 1;
1535 else if (!strncmp(this_opt, "hwcursor=", 9))
1536 hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
1537#ifdef CONFIG_MTRR
1538 else if (!strncmp(this_opt, "nomtrr", 6))
1539 nomtrr = 1;
1540#endif
1541 else
1542 mode_option = this_opt;
1543 }
1544 return 0;
1545}
1546#endif /* MODULE */
1547
1171static int __init pm3fb_init(void) 1548static int __init pm3fb_init(void)
1172{ 1549{
1550 /*
1551 * For kernel boot options (in 'video=pm3fb:<options>' format)
1552 */
1173#ifndef MODULE 1553#ifndef MODULE
1174 if (fb_get_options("pm3fb", NULL)) 1554 char *option = NULL;
1555
1556 if (fb_get_options("pm3fb", &option))
1175 return -ENODEV; 1557 return -ENODEV;
1558 pm3fb_setup(option);
1176#endif 1559#endif
1560
1177 return pci_register_driver(&pm3fb_driver); 1561 return pci_register_driver(&pm3fb_driver);
1178} 1562}
1179 1563
1564#ifdef MODULE
1180static void __exit pm3fb_exit(void) 1565static void __exit pm3fb_exit(void)
1181{ 1566{
1182 pci_unregister_driver(&pm3fb_driver); 1567 pci_unregister_driver(&pm3fb_driver);
1183} 1568}
1184 1569
1185module_init(pm3fb_init);
1186module_exit(pm3fb_exit); 1570module_exit(pm3fb_exit);
1571#endif
1572module_init(pm3fb_init);
1573
1574module_param(noaccel, bool, 0);
1575MODULE_PARM_DESC(noaccel, "Disable acceleration");
1576module_param(hwcursor, int, 0644);
1577MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
1578 "(1=enable, 0=disable, default=1)");
1579#ifdef CONFIG_MTRR
1580module_param(nomtrr, bool, 0);
1581MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
1582#endif
1187 1583
1584MODULE_DESCRIPTION("Permedia3 framebuffer device driver");
1188MODULE_LICENSE("GPL"); 1585MODULE_LICENSE("GPL");
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index 264d37243fad..3a3f80f65219 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -147,16 +147,23 @@ static int __init pmagbafb_probe(struct device *dev)
147 resource_size_t start, len; 147 resource_size_t start, len;
148 struct fb_info *info; 148 struct fb_info *info;
149 struct pmagbafb_par *par; 149 struct pmagbafb_par *par;
150 int err;
150 151
151 info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev); 152 info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev);
152 if (!info) 153 if (!info) {
154 printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
153 return -ENOMEM; 155 return -ENOMEM;
156 }
154 157
155 par = info->par; 158 par = info->par;
156 dev_set_drvdata(dev, info); 159 dev_set_drvdata(dev, info);
157 160
158 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) 161 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
162 printk(KERN_ERR "%s: Cannot allocate color map\n",
163 dev->bus_id);
164 err = -ENOMEM;
159 goto err_alloc; 165 goto err_alloc;
166 }
160 167
161 info->fbops = &pmagbafb_ops; 168 info->fbops = &pmagbafb_ops;
162 info->fix = pmagbafb_fix; 169 info->fix = pmagbafb_fix;
@@ -166,28 +173,41 @@ static int __init pmagbafb_probe(struct device *dev)
166 /* Request the I/O MEM resource. */ 173 /* Request the I/O MEM resource. */
167 start = tdev->resource.start; 174 start = tdev->resource.start;
168 len = tdev->resource.end - start + 1; 175 len = tdev->resource.end - start + 1;
169 if (!request_mem_region(start, len, dev->bus_id)) 176 if (!request_mem_region(start, len, dev->bus_id)) {
177 printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
178 err = -EBUSY;
170 goto err_cmap; 179 goto err_cmap;
180 }
171 181
172 /* MMIO mapping setup. */ 182 /* MMIO mapping setup. */
173 info->fix.mmio_start = start; 183 info->fix.mmio_start = start;
174 par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); 184 par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
175 if (!par->mmio) 185 if (!par->mmio) {
186 printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
187 err = -ENOMEM;
176 goto err_resource; 188 goto err_resource;
189 }
177 par->dac = par->mmio + PMAG_BA_BT459; 190 par->dac = par->mmio + PMAG_BA_BT459;
178 191
179 /* Frame buffer mapping setup. */ 192 /* Frame buffer mapping setup. */
180 info->fix.smem_start = start + PMAG_BA_FBMEM; 193 info->fix.smem_start = start + PMAG_BA_FBMEM;
181 info->screen_base = ioremap_nocache(info->fix.smem_start, 194 info->screen_base = ioremap_nocache(info->fix.smem_start,
182 info->fix.smem_len); 195 info->fix.smem_len);
183 if (!info->screen_base) 196 if (!info->screen_base) {
197 printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
198 err = -ENOMEM;
184 goto err_mmio_map; 199 goto err_mmio_map;
200 }
185 info->screen_size = info->fix.smem_len; 201 info->screen_size = info->fix.smem_len;
186 202
187 pmagbafb_erase_cursor(info); 203 pmagbafb_erase_cursor(info);
188 204
189 if (register_framebuffer(info) < 0) 205 err = register_framebuffer(info);
206 if (err < 0) {
207 printk(KERN_ERR "%s: Cannot register framebuffer\n",
208 dev->bus_id);
190 goto err_smem_map; 209 goto err_smem_map;
210 }
191 211
192 get_device(dev); 212 get_device(dev);
193 213
@@ -211,7 +231,7 @@ err_cmap:
211 231
212err_alloc: 232err_alloc:
213 framebuffer_release(info); 233 framebuffer_release(info);
214 return -ENXIO; 234 return err;
215} 235}
216 236
217static int __exit pmagbafb_remove(struct device *dev) 237static int __exit pmagbafb_remove(struct device *dev)
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 7a0ce7d5af6b..9b80597241b0 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -254,16 +254,23 @@ static int __init pmagbbfb_probe(struct device *dev)
254 struct pmagbbfb_par *par; 254 struct pmagbbfb_par *par;
255 char freq0[12], freq1[12]; 255 char freq0[12], freq1[12];
256 u32 vid_base; 256 u32 vid_base;
257 int err;
257 258
258 info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev); 259 info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev);
259 if (!info) 260 if (!info) {
261 printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
260 return -ENOMEM; 262 return -ENOMEM;
263 }
261 264
262 par = info->par; 265 par = info->par;
263 dev_set_drvdata(dev, info); 266 dev_set_drvdata(dev, info);
264 267
265 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) 268 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
269 printk(KERN_ERR "%s: Cannot allocate color map\n",
270 dev->bus_id);
271 err = -ENOMEM;
266 goto err_alloc; 272 goto err_alloc;
273 }
267 274
268 info->fbops = &pmagbbfb_ops; 275 info->fbops = &pmagbbfb_ops;
269 info->fix = pmagbbfb_fix; 276 info->fix = pmagbbfb_fix;
@@ -273,22 +280,31 @@ static int __init pmagbbfb_probe(struct device *dev)
273 /* Request the I/O MEM resource. */ 280 /* Request the I/O MEM resource. */
274 start = tdev->resource.start; 281 start = tdev->resource.start;
275 len = tdev->resource.end - start + 1; 282 len = tdev->resource.end - start + 1;
276 if (!request_mem_region(start, len, dev->bus_id)) 283 if (!request_mem_region(start, len, dev->bus_id)) {
284 printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
285 err = -EBUSY;
277 goto err_cmap; 286 goto err_cmap;
287 }
278 288
279 /* MMIO mapping setup. */ 289 /* MMIO mapping setup. */
280 info->fix.mmio_start = start; 290 info->fix.mmio_start = start;
281 par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); 291 par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
282 if (!par->mmio) 292 if (!par->mmio) {
293 printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
294 err = -ENOMEM;
283 goto err_resource; 295 goto err_resource;
296 }
284 par->sfb = par->mmio + PMAGB_B_SFB; 297 par->sfb = par->mmio + PMAGB_B_SFB;
285 par->dac = par->mmio + PMAGB_B_BT459; 298 par->dac = par->mmio + PMAGB_B_BT459;
286 299
287 /* Frame buffer mapping setup. */ 300 /* Frame buffer mapping setup. */
288 info->fix.smem_start = start + PMAGB_B_FBMEM; 301 info->fix.smem_start = start + PMAGB_B_FBMEM;
289 par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len); 302 par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
290 if (!par->smem) 303 if (!par->smem) {
304 printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
305 err = -ENOMEM;
291 goto err_mmio_map; 306 goto err_mmio_map;
307 }
292 vid_base = sfb_read(par, SFB_REG_VID_BASE); 308 vid_base = sfb_read(par, SFB_REG_VID_BASE);
293 info->screen_base = (void __iomem *)par->smem + vid_base * 0x1000; 309 info->screen_base = (void __iomem *)par->smem + vid_base * 0x1000;
294 info->screen_size = info->fix.smem_len - 2 * vid_base * 0x1000; 310 info->screen_size = info->fix.smem_len - 2 * vid_base * 0x1000;
@@ -297,8 +313,12 @@ static int __init pmagbbfb_probe(struct device *dev)
297 pmagbbfb_screen_setup(info); 313 pmagbbfb_screen_setup(info);
298 pmagbbfb_osc_setup(info); 314 pmagbbfb_osc_setup(info);
299 315
300 if (register_framebuffer(info) < 0) 316 err = register_framebuffer(info);
317 if (err < 0) {
318 printk(KERN_ERR "%s: Cannot register framebuffer\n",
319 dev->bus_id);
301 goto err_smem_map; 320 goto err_smem_map;
321 }
302 322
303 get_device(dev); 323 get_device(dev);
304 324
@@ -330,7 +350,7 @@ err_cmap:
330 350
331err_alloc: 351err_alloc:
332 framebuffer_release(info); 352 framebuffer_release(info);
333 return -ENXIO; 353 return err;
334} 354}
335 355
336static int __exit pmagbbfb_remove(struct device *dev) 356static int __exit pmagbbfb_remove(struct device *dev)
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
index f29e66e2d774..685761a0732c 100644
--- a/drivers/video/pnx4008/pnxrgbfb.c
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -26,7 +26,6 @@
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28 28
29#include <asm/uaccess.h>
30#include "sdum.h" 29#include "sdum.h"
31#include "fbcommon.h" 30#include "fbcommon.h"
32 31
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 646ec823c168..b3463ddcfd60 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -22,22 +22,14 @@
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/string.h> 23#include <linux/string.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/tty.h>
26#include <linux/slab.h>
27#include <linux/vmalloc.h>
28#include <linux/delay.h>
29#include <linux/interrupt.h> 25#include <linux/interrupt.h>
30#include <linux/console.h> 26#include <linux/console.h>
31#include <linux/ioctl.h> 27#include <linux/ioctl.h>
32#include <linux/notifier.h>
33#include <linux/reboot.h>
34#include <linux/kthread.h> 28#include <linux/kthread.h>
35#include <linux/freezer.h> 29#include <linux/freezer.h>
36 30#include <linux/uaccess.h>
37#include <asm/uaccess.h>
38#include <linux/fb.h> 31#include <linux/fb.h>
39#include <linux/init.h> 32#include <linux/init.h>
40#include <asm/time.h>
41 33
42#include <asm/abs_addr.h> 34#include <asm/abs_addr.h>
43#include <asm/lv1call.h> 35#include <asm/lv1call.h>
@@ -48,12 +40,6 @@
48 40
49#define DEVICE_NAME "ps3fb" 41#define DEVICE_NAME "ps3fb"
50 42
51#ifdef PS3FB_DEBUG
52#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args)
53#else
54#define DPRINTK(fmt, args...)
55#endif
56
57#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101 43#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101
58#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102 44#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102
59#define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600 45#define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600
@@ -66,8 +52,10 @@
66#define L1GPU_DISPLAY_SYNC_VSYNC 2 52#define L1GPU_DISPLAY_SYNC_VSYNC 2
67 53
68#define DDR_SIZE (0) /* used no ddr */ 54#define DDR_SIZE (0) /* used no ddr */
69#define GPU_OFFSET (64 * 1024) 55#define GPU_CMD_BUF_SIZE (64 * 1024)
70#define GPU_IOIF (0x0d000000UL) 56#define GPU_IOIF (0x0d000000UL)
57#define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64)
58#define GPU_MAX_LINE_LENGTH (65536 - 64)
71 59
72#define PS3FB_FULL_MODE_BIT 0x80 60#define PS3FB_FULL_MODE_BIT 0x80
73 61
@@ -131,13 +119,12 @@ struct ps3fb_priv {
131 119
132 u64 context_handle, memory_handle; 120 u64 context_handle, memory_handle;
133 void *xdr_ea; 121 void *xdr_ea;
122 size_t xdr_size;
134 struct gpu_driver_info *dinfo; 123 struct gpu_driver_info *dinfo;
135 u32 res_index;
136 124
137 u64 vblank_count; /* frame count */ 125 u64 vblank_count; /* frame count */
138 wait_queue_head_t wait_vsync; 126 wait_queue_head_t wait_vsync;
139 127
140 u32 num_frames; /* num of frame buffers */
141 atomic_t ext_flip; /* on/off flip with vsync */ 128 atomic_t ext_flip; /* on/off flip with vsync */
142 atomic_t f_count; /* fb_open count */ 129 atomic_t f_count; /* fb_open count */
143 int is_blanked; 130 int is_blanked;
@@ -146,6 +133,18 @@ struct ps3fb_priv {
146}; 133};
147static struct ps3fb_priv ps3fb; 134static struct ps3fb_priv ps3fb;
148 135
136struct ps3fb_par {
137 u32 pseudo_palette[16];
138 int mode_id, new_mode_id;
139 int res_index;
140 unsigned int num_frames; /* num of frame buffers */
141 unsigned int width;
142 unsigned int height;
143 unsigned long full_offset; /* start of fullscreen DDR fb */
144 unsigned long fb_offset; /* start of actual DDR fb */
145 unsigned long pan_offset;
146};
147
149struct ps3fb_res_table { 148struct ps3fb_res_table {
150 u32 xres; 149 u32 xres;
151 u32 yres; 150 u32 yres;
@@ -294,29 +293,31 @@ static const struct fb_videomode ps3fb_modedb[] = {
294#define Y_OFF(i) (ps3fb_res[i].yoff) /* top/bottom margin (pixel) */ 293#define Y_OFF(i) (ps3fb_res[i].yoff) /* top/bottom margin (pixel) */
295#define WIDTH(i) (ps3fb_res[i].xres) /* width of FB */ 294#define WIDTH(i) (ps3fb_res[i].xres) /* width of FB */
296#define HEIGHT(i) (ps3fb_res[i].yres) /* height of FB */ 295#define HEIGHT(i) (ps3fb_res[i].yres) /* height of FB */
297#define BPP 4 /* number of bytes per pixel */ 296#define BPP 4 /* number of bytes per pixel */
298#define VP_OFF(i) (WIDTH(i) * Y_OFF(i) * BPP + X_OFF(i) * BPP) 297
299#define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET) 298/* Start of the virtual frame buffer (relative to fullscreen ) */
299#define VP_OFF(i) ((WIDTH(i) * Y_OFF(i) + X_OFF(i)) * BPP)
300
300 301
301static int ps3fb_mode; 302static int ps3fb_mode;
302module_param(ps3fb_mode, int, 0); 303module_param(ps3fb_mode, int, 0);
303 304
304static char *mode_option __devinitdata; 305static char *mode_option __devinitdata;
305 306
306static int ps3fb_get_res_table(u32 xres, u32 yres) 307static int ps3fb_get_res_table(u32 xres, u32 yres, int mode)
307{ 308{
308 int full_mode; 309 int full_mode;
309 unsigned int i; 310 unsigned int i;
310 u32 x, y, f; 311 u32 x, y, f;
311 312
312 full_mode = (ps3fb_mode & PS3FB_FULL_MODE_BIT) ? PS3FB_RES_FULL : 0; 313 full_mode = (mode & PS3FB_FULL_MODE_BIT) ? PS3FB_RES_FULL : 0;
313 for (i = 0;; i++) { 314 for (i = 0;; i++) {
314 x = ps3fb_res[i].xres; 315 x = ps3fb_res[i].xres;
315 y = ps3fb_res[i].yres; 316 y = ps3fb_res[i].yres;
316 f = ps3fb_res[i].type; 317 f = ps3fb_res[i].type;
317 318
318 if (!x) { 319 if (!x) {
319 DPRINTK("ERROR: ps3fb_get_res_table()\n"); 320 pr_debug("ERROR: ps3fb_get_res_table()\n");
320 return -1; 321 return -1;
321 } 322 }
322 323
@@ -335,7 +336,7 @@ static int ps3fb_get_res_table(u32 xres, u32 yres)
335} 336}
336 337
337static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var, 338static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
338 u32 *line_length) 339 u32 *ddr_line_length, u32 *xdr_line_length)
339{ 340{
340 unsigned int i, mode; 341 unsigned int i, mode;
341 342
@@ -350,31 +351,41 @@ static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
350 var->upper_margin == ps3fb_modedb[i].upper_margin && 351 var->upper_margin == ps3fb_modedb[i].upper_margin &&
351 var->lower_margin == ps3fb_modedb[i].lower_margin && 352 var->lower_margin == ps3fb_modedb[i].lower_margin &&
352 var->sync == ps3fb_modedb[i].sync && 353 var->sync == ps3fb_modedb[i].sync &&
353 (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode) { 354 (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode)
354 /* Cropped broadcast modes use the full line_length */ 355 goto found;
355 *line_length =
356 ps3fb_modedb[i < 10 ? i + 13 : i].xres * 4;
357 /* Full broadcast modes have the full mode bit set */
358 mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
359
360 DPRINTK("ps3fb_find_mode: mode %u\n", mode);
361 return mode;
362 }
363 356
364 DPRINTK("ps3fb_find_mode: mode not found\n"); 357 pr_debug("ps3fb_find_mode: mode not found\n");
365 return 0; 358 return 0;
366 359
360found:
361 /* Cropped broadcast modes use the full line length */
362 *ddr_line_length = ps3fb_modedb[i < 10 ? i + 13 : i].xres * BPP;
363
364 if (ps3_compare_firmware_version(1, 9, 0) >= 0) {
365 *xdr_line_length = GPU_ALIGN_UP(max(var->xres,
366 var->xres_virtual) * BPP);
367 if (*xdr_line_length > GPU_MAX_LINE_LENGTH)
368 *xdr_line_length = GPU_MAX_LINE_LENGTH;
369 } else
370 *xdr_line_length = *ddr_line_length;
371
372 /* Full broadcast modes have the full mode bit set */
373 mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
374
375 pr_debug("ps3fb_find_mode: mode %u\n", mode);
376
377 return mode;
367} 378}
368 379
369static const struct fb_videomode *ps3fb_default_mode(void) 380static const struct fb_videomode *ps3fb_default_mode(int id)
370{ 381{
371 u32 mode = ps3fb_mode & PS3AV_MODE_MASK; 382 u32 mode = id & PS3AV_MODE_MASK;
372 u32 flags; 383 u32 flags;
373 384
374 if (mode < 1 || mode > 13) 385 if (mode < 1 || mode > 13)
375 return NULL; 386 return NULL;
376 387
377 flags = ps3fb_mode & ~PS3AV_MODE_MASK; 388 flags = id & ~PS3AV_MODE_MASK;
378 389
379 if (mode <= 10 && flags & PS3FB_FULL_MODE_BIT) { 390 if (mode <= 10 && flags & PS3FB_FULL_MODE_BIT) {
380 /* Full broadcast mode */ 391 /* Full broadcast mode */
@@ -384,55 +395,77 @@ static const struct fb_videomode *ps3fb_default_mode(void)
384 return &ps3fb_modedb[mode - 1]; 395 return &ps3fb_modedb[mode - 1];
385} 396}
386 397
387static int ps3fb_sync(u32 frame) 398static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
399 u64 dst_offset, u64 src_offset, u32 width,
400 u32 height, u32 dst_line_length,
401 u32 src_line_length)
388{ 402{
389 int i, status; 403 int status;
390 u32 xres, yres; 404 u64 line_length;
391 u64 fb_ioif, offset;
392
393 i = ps3fb.res_index;
394 xres = ps3fb_res[i].xres;
395 yres = ps3fb_res[i].yres;
396 405
397 if (frame > ps3fb.num_frames - 1) { 406 line_length = dst_line_length;
398 printk(KERN_WARNING "%s: invalid frame number (%u)\n", 407 if (src_line_length != dst_line_length)
399 __func__, frame); 408 line_length |= (u64)src_line_length << 32;
400 return -EINVAL;
401 }
402 offset = xres * yres * BPP * frame;
403 409
404 fb_ioif = GPU_IOIF + FB_OFF(i) + offset;
405 status = lv1_gpu_context_attribute(ps3fb.context_handle, 410 status = lv1_gpu_context_attribute(ps3fb.context_handle,
406 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 411 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
407 offset, fb_ioif, 412 dst_offset, GPU_IOIF + src_offset,
408 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION | 413 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
409 (xres << 16) | yres, 414 (width << 16) | height,
410 xres * BPP); /* line_length */ 415 line_length);
411 if (status) 416 if (status)
412 printk(KERN_ERR 417 dev_err(dev,
413 "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n", 418 "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
414 __func__, status); 419 __func__, status);
415#ifdef HEAD_A 420#ifdef HEAD_A
416 status = lv1_gpu_context_attribute(ps3fb.context_handle, 421 status = lv1_gpu_context_attribute(ps3fb.context_handle,
417 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 422 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
418 0, offset, 0, 0); 423 0, frame_offset, 0, 0);
419 if (status) 424 if (status)
420 printk(KERN_ERR 425 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
421 "%s: lv1_gpu_context_attribute FLIP failed: %d\n", 426 __func__, status);
422 __func__, status);
423#endif 427#endif
424#ifdef HEAD_B 428#ifdef HEAD_B
425 status = lv1_gpu_context_attribute(ps3fb.context_handle, 429 status = lv1_gpu_context_attribute(ps3fb.context_handle,
426 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 430 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
427 1, offset, 0, 0); 431 1, frame_offset, 0, 0);
428 if (status) 432 if (status)
429 printk(KERN_ERR 433 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
430 "%s: lv1_gpu_context_attribute FLIP failed: %d\n", 434 __func__, status);
431 __func__, status);
432#endif 435#endif
433 return 0;
434} 436}
435 437
438static int ps3fb_sync(struct fb_info *info, u32 frame)
439{
440 struct ps3fb_par *par = info->par;
441 int i, error = 0;
442 u32 ddr_line_length, xdr_line_length;
443 u64 ddr_base, xdr_base;
444
445 acquire_console_sem();
446
447 if (frame > par->num_frames - 1) {
448 dev_dbg(info->device, "%s: invalid frame number (%u)\n",
449 __func__, frame);
450 error = -EINVAL;
451 goto out;
452 }
453
454 i = par->res_index;
455 xdr_line_length = info->fix.line_length;
456 ddr_line_length = ps3fb_res[i].xres * BPP;
457 xdr_base = frame * info->var.yres_virtual * xdr_line_length;
458 ddr_base = frame * ps3fb_res[i].yres * ddr_line_length;
459
460 ps3fb_sync_image(info->device, ddr_base + par->full_offset,
461 ddr_base + par->fb_offset, xdr_base + par->pan_offset,
462 par->width, par->height, ddr_line_length,
463 xdr_line_length);
464
465out:
466 release_console_sem();
467 return error;
468}
436 469
437static int ps3fb_open(struct fb_info *info, int user) 470static int ps3fb_open(struct fb_info *info, int user)
438{ 471{
@@ -445,7 +478,7 @@ static int ps3fb_release(struct fb_info *info, int user)
445 if (atomic_dec_and_test(&ps3fb.f_count)) { 478 if (atomic_dec_and_test(&ps3fb.f_count)) {
446 if (atomic_read(&ps3fb.ext_flip)) { 479 if (atomic_read(&ps3fb.ext_flip)) {
447 atomic_set(&ps3fb.ext_flip, 0); 480 atomic_set(&ps3fb.ext_flip, 0);
448 ps3fb_sync(0); /* single buffer */ 481 ps3fb_sync(info, 0); /* single buffer */
449 } 482 }
450 } 483 }
451 return 0; 484 return 0;
@@ -461,39 +494,37 @@ static int ps3fb_release(struct fb_info *info, int user)
461 494
462static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 495static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
463{ 496{
464 u32 line_length; 497 u32 xdr_line_length, ddr_line_length;
465 int mode; 498 int mode;
466 int i;
467 499
468 DPRINTK("var->xres:%u info->var.xres:%u\n", var->xres, info->var.xres); 500 dev_dbg(info->device, "var->xres:%u info->var.xres:%u\n", var->xres,
469 DPRINTK("var->yres:%u info->var.yres:%u\n", var->yres, info->var.yres); 501 info->var.xres);
502 dev_dbg(info->device, "var->yres:%u info->var.yres:%u\n", var->yres,
503 info->var.yres);
470 504
471 /* FIXME For now we do exact matches only */ 505 /* FIXME For now we do exact matches only */
472 mode = ps3fb_find_mode(var, &line_length); 506 mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length);
473 if (!mode) 507 if (!mode)
474 return -EINVAL; 508 return -EINVAL;
475 509
476 /* 510 /* Virtual screen */
477 * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal! 511 if (var->xres_virtual < var->xres)
478 * as FB_VMODE_SMOOTH_XPAN is only used internally 512 var->xres_virtual = var->xres;
479 */ 513 if (var->yres_virtual < var->yres)
514 var->yres_virtual = var->yres;
480 515
481 if (var->vmode & FB_VMODE_CONUPDATE) { 516 if (var->xres_virtual > xdr_line_length / BPP) {
482 var->vmode |= FB_VMODE_YWRAP; 517 dev_dbg(info->device,
483 var->xoffset = info->var.xoffset; 518 "Horizontal virtual screen size too large\n");
484 var->yoffset = info->var.yoffset; 519 return -EINVAL;
485 } 520 }
486 521
487 /* Virtual screen and panning are not supported */ 522 if (var->xoffset + var->xres > var->xres_virtual ||
488 if (var->xres_virtual > var->xres || var->yres_virtual > var->yres || 523 var->yoffset + var->yres > var->yres_virtual) {
489 var->xoffset || var->yoffset) { 524 dev_dbg(info->device, "panning out-of-range\n");
490 DPRINTK("Virtual screen and panning are not supported\n");
491 return -EINVAL; 525 return -EINVAL;
492 } 526 }
493 527
494 var->xres_virtual = var->xres;
495 var->yres_virtual = var->yres;
496
497 /* We support ARGB8888 only */ 528 /* We support ARGB8888 only */
498 if (var->bits_per_pixel > 32 || var->grayscale || 529 if (var->bits_per_pixel > 32 || var->grayscale ||
499 var->red.offset > 16 || var->green.offset > 8 || 530 var->red.offset > 16 || var->green.offset > 8 ||
@@ -502,7 +533,7 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
502 var->blue.length > 8 || var->transp.length > 8 || 533 var->blue.length > 8 || var->transp.length > 8 ||
503 var->red.msb_right || var->green.msb_right || 534 var->red.msb_right || var->green.msb_right ||
504 var->blue.msb_right || var->transp.msb_right || var->nonstd) { 535 var->blue.msb_right || var->transp.msb_right || var->nonstd) {
505 DPRINTK("We support ARGB8888 only\n"); 536 dev_dbg(info->device, "We support ARGB8888 only\n");
506 return -EINVAL; 537 return -EINVAL;
507 } 538 }
508 539
@@ -522,14 +553,13 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
522 553
523 /* Rotation is not supported */ 554 /* Rotation is not supported */
524 if (var->rotate) { 555 if (var->rotate) {
525 DPRINTK("Rotation is not supported\n"); 556 dev_dbg(info->device, "Rotation is not supported\n");
526 return -EINVAL; 557 return -EINVAL;
527 } 558 }
528 559
529 /* Memory limit */ 560 /* Memory limit */
530 i = ps3fb_get_res_table(var->xres, var->yres); 561 if (var->yres_virtual * xdr_line_length > ps3fb.xdr_size) {
531 if (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP > ps3fb_videomemory.size) { 562 dev_dbg(info->device, "Not enough memory\n");
532 DPRINTK("Not enough memory\n");
533 return -ENOMEM; 563 return -ENOMEM;
534 } 564 }
535 565
@@ -545,36 +575,69 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
545 575
546static int ps3fb_set_par(struct fb_info *info) 576static int ps3fb_set_par(struct fb_info *info)
547{ 577{
548 unsigned int mode; 578 struct ps3fb_par *par = info->par;
579 unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines;
549 int i; 580 int i;
550 unsigned long offset; 581 unsigned long offset;
551 static int first = 1; 582 u64 dst;
552 583
553 DPRINTK("xres:%d xv:%d yres:%d yv:%d clock:%d\n", 584 dev_dbg(info->device, "xres:%d xv:%d yres:%d yv:%d clock:%d\n",
554 info->var.xres, info->var.xres_virtual, 585 info->var.xres, info->var.xres_virtual,
555 info->var.yres, info->var.yres_virtual, info->var.pixclock); 586 info->var.yres, info->var.yres_virtual, info->var.pixclock);
556 i = ps3fb_get_res_table(info->var.xres, info->var.yres);
557 ps3fb.res_index = i;
558 587
559 mode = ps3fb_find_mode(&info->var, &info->fix.line_length); 588 mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length);
560 if (!mode) 589 if (!mode)
561 return -EINVAL; 590 return -EINVAL;
562 591
563 offset = FB_OFF(i) + VP_OFF(i); 592 i = ps3fb_get_res_table(info->var.xres, info->var.yres, mode);
564 info->fix.smem_len = ps3fb_videomemory.size - offset; 593 par->res_index = i;
565 info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset; 594
566 memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size); 595 info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
596 info->fix.smem_len = ps3fb.xdr_size;
597 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
598 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
599 info->fix.line_length = xdr_line_length;
600
601 info->screen_base = (char __iomem *)ps3fb.xdr_ea;
567 602
568 ps3fb.num_frames = ps3fb_videomemory.size/ 603 par->num_frames = ps3fb.xdr_size /
569 (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP); 604 max(ps3fb_res[i].yres * ddr_line_length,
605 info->var.yres_virtual * xdr_line_length);
570 606
571 /* Keep the special bits we cannot set using fb_var_screeninfo */ 607 /* Keep the special bits we cannot set using fb_var_screeninfo */
572 ps3fb_mode = (ps3fb_mode & ~PS3AV_MODE_MASK) | mode; 608 par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode;
609
610 par->width = info->var.xres;
611 par->height = info->var.yres;
612 offset = VP_OFF(i);
613 par->fb_offset = GPU_ALIGN_UP(offset);
614 par->full_offset = par->fb_offset - offset;
615 par->pan_offset = info->var.yoffset * xdr_line_length +
616 info->var.xoffset * BPP;
617
618 if (par->new_mode_id != par->mode_id) {
619 if (ps3av_set_video_mode(par->new_mode_id)) {
620 par->new_mode_id = par->mode_id;
621 return -EINVAL;
622 }
623 par->mode_id = par->new_mode_id;
624 }
573 625
574 if (ps3av_set_video_mode(ps3fb_mode, first)) 626 /* Clear XDR frame buffer memory */
575 return -EINVAL; 627 memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size);
628
629 /* Clear DDR frame buffer memory */
630 lines = ps3fb_res[i].yres * par->num_frames;
631 if (par->full_offset)
632 lines++;
633 maxlines = ps3fb.xdr_size / ddr_line_length;
634 for (dst = 0; lines; dst += maxlines * ddr_line_length) {
635 unsigned int l = min(lines, maxlines);
636 ps3fb_sync_image(info->device, 0, dst, 0, ps3fb_res[i].xres, l,
637 ddr_line_length, ddr_line_length);
638 lines -= l;
639 }
576 640
577 first = 0;
578 return 0; 641 return 0;
579} 642}
580 643
@@ -601,6 +664,16 @@ static int ps3fb_setcolreg(unsigned int regno, unsigned int red,
601 return 0; 664 return 0;
602} 665}
603 666
667static int ps3fb_pan_display(struct fb_var_screeninfo *var,
668 struct fb_info *info)
669{
670 struct ps3fb_par *par = info->par;
671
672 par->pan_offset = var->yoffset * info->fix.line_length +
673 var->xoffset * BPP;
674 return 0;
675}
676
604 /* 677 /*
605 * As we have a virtual frame buffer, we need our own mmap function 678 * As we have a virtual frame buffer, we need our own mmap function
606 */ 679 */
@@ -608,24 +681,19 @@ static int ps3fb_setcolreg(unsigned int regno, unsigned int red,
608static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma) 681static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
609{ 682{
610 unsigned long size, offset; 683 unsigned long size, offset;
611 int i;
612
613 i = ps3fb_get_res_table(info->var.xres, info->var.yres);
614 if (i == -1)
615 return -EINVAL;
616 684
617 size = vma->vm_end - vma->vm_start; 685 size = vma->vm_end - vma->vm_start;
618 offset = vma->vm_pgoff << PAGE_SHIFT; 686 offset = vma->vm_pgoff << PAGE_SHIFT;
619 if (offset + size > info->fix.smem_len) 687 if (offset + size > info->fix.smem_len)
620 return -EINVAL; 688 return -EINVAL;
621 689
622 offset += info->fix.smem_start + FB_OFF(i) + VP_OFF(i); 690 offset += info->fix.smem_start;
623 if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT, 691 if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
624 size, vma->vm_page_prot)) 692 size, vma->vm_page_prot))
625 return -EAGAIN; 693 return -EAGAIN;
626 694
627 printk(KERN_DEBUG "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n", offset, 695 dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n",
628 vma->vm_start); 696 offset, vma->vm_start);
629 return 0; 697 return 0;
630} 698}
631 699
@@ -637,7 +705,7 @@ static int ps3fb_blank(int blank, struct fb_info *info)
637{ 705{
638 int retval; 706 int retval;
639 707
640 DPRINTK("%s: blank:%d\n", __func__, blank); 708 dev_dbg(info->device, "%s: blank:%d\n", __func__, blank);
641 switch (blank) { 709 switch (blank) {
642 case FB_BLANK_POWERDOWN: 710 case FB_BLANK_POWERDOWN:
643 case FB_BLANK_HSYNC_SUSPEND: 711 case FB_BLANK_HSYNC_SUSPEND:
@@ -664,7 +732,7 @@ static int ps3fb_get_vblank(struct fb_vblank *vblank)
664 return 0; 732 return 0;
665} 733}
666 734
667int ps3fb_wait_for_vsync(u32 crtc) 735static int ps3fb_wait_for_vsync(u32 crtc)
668{ 736{
669 int ret; 737 int ret;
670 u64 count; 738 u64 count;
@@ -679,9 +747,7 @@ int ps3fb_wait_for_vsync(u32 crtc)
679 return 0; 747 return 0;
680} 748}
681 749
682EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync); 750static void ps3fb_flip_ctl(int on, void *data)
683
684void ps3fb_flip_ctl(int on, void *data)
685{ 751{
686 struct ps3fb_priv *priv = data; 752 struct ps3fb_priv *priv = data;
687 if (on) 753 if (on)
@@ -699,14 +765,14 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
699 unsigned long arg) 765 unsigned long arg)
700{ 766{
701 void __user *argp = (void __user *)arg; 767 void __user *argp = (void __user *)arg;
702 u32 val, old_mode; 768 u32 val;
703 int retval = -EFAULT; 769 int retval = -EFAULT;
704 770
705 switch (cmd) { 771 switch (cmd) {
706 case FBIOGET_VBLANK: 772 case FBIOGET_VBLANK:
707 { 773 {
708 struct fb_vblank vblank; 774 struct fb_vblank vblank;
709 DPRINTK("FBIOGET_VBLANK:\n"); 775 dev_dbg(info->device, "FBIOGET_VBLANK:\n");
710 retval = ps3fb_get_vblank(&vblank); 776 retval = ps3fb_get_vblank(&vblank);
711 if (retval) 777 if (retval)
712 break; 778 break;
@@ -719,7 +785,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
719 case FBIO_WAITFORVSYNC: 785 case FBIO_WAITFORVSYNC:
720 { 786 {
721 u32 crt; 787 u32 crt;
722 DPRINTK("FBIO_WAITFORVSYNC:\n"); 788 dev_dbg(info->device, "FBIO_WAITFORVSYNC:\n");
723 if (get_user(crt, (u32 __user *) arg)) 789 if (get_user(crt, (u32 __user *) arg))
724 break; 790 break;
725 791
@@ -729,6 +795,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
729 795
730 case PS3FB_IOCTL_SETMODE: 796 case PS3FB_IOCTL_SETMODE:
731 { 797 {
798 struct ps3fb_par *par = info->par;
732 const struct fb_videomode *mode; 799 const struct fb_videomode *mode;
733 struct fb_var_screeninfo var; 800 struct fb_var_screeninfo var;
734 801
@@ -736,15 +803,13 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
736 break; 803 break;
737 804
738 if (!(val & PS3AV_MODE_MASK)) { 805 if (!(val & PS3AV_MODE_MASK)) {
739 u32 id = ps3av_get_auto_mode(0); 806 u32 id = ps3av_get_auto_mode();
740 if (id > 0) 807 if (id > 0)
741 val = (val & ~PS3AV_MODE_MASK) | id; 808 val = (val & ~PS3AV_MODE_MASK) | id;
742 } 809 }
743 DPRINTK("PS3FB_IOCTL_SETMODE:%x\n", val); 810 dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val);
744 retval = -EINVAL; 811 retval = -EINVAL;
745 old_mode = ps3fb_mode; 812 mode = ps3fb_default_mode(val);
746 ps3fb_mode = val;
747 mode = ps3fb_default_mode();
748 if (mode) { 813 if (mode) {
749 var = info->var; 814 var = info->var;
750 fb_videomode_to_var(&var, mode); 815 fb_videomode_to_var(&var, mode);
@@ -752,45 +817,44 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
752 info->flags |= FBINFO_MISC_USEREVENT; 817 info->flags |= FBINFO_MISC_USEREVENT;
753 /* Force, in case only special bits changed */ 818 /* Force, in case only special bits changed */
754 var.activate |= FB_ACTIVATE_FORCE; 819 var.activate |= FB_ACTIVATE_FORCE;
820 par->new_mode_id = val;
755 retval = fb_set_var(info, &var); 821 retval = fb_set_var(info, &var);
756 info->flags &= ~FBINFO_MISC_USEREVENT; 822 info->flags &= ~FBINFO_MISC_USEREVENT;
757 release_console_sem(); 823 release_console_sem();
758 } 824 }
759 if (retval)
760 ps3fb_mode = old_mode;
761 break; 825 break;
762 } 826 }
763 827
764 case PS3FB_IOCTL_GETMODE: 828 case PS3FB_IOCTL_GETMODE:
765 val = ps3av_get_mode(); 829 val = ps3av_get_mode();
766 DPRINTK("PS3FB_IOCTL_GETMODE:%x\n", val); 830 dev_dbg(info->device, "PS3FB_IOCTL_GETMODE:%x\n", val);
767 if (!copy_to_user(argp, &val, sizeof(val))) 831 if (!copy_to_user(argp, &val, sizeof(val)))
768 retval = 0; 832 retval = 0;
769 break; 833 break;
770 834
771 case PS3FB_IOCTL_SCREENINFO: 835 case PS3FB_IOCTL_SCREENINFO:
772 { 836 {
837 struct ps3fb_par *par = info->par;
773 struct ps3fb_ioctl_res res; 838 struct ps3fb_ioctl_res res;
774 int i = ps3fb.res_index; 839 dev_dbg(info->device, "PS3FB_IOCTL_SCREENINFO:\n");
775 DPRINTK("PS3FB_IOCTL_SCREENINFO:\n"); 840 res.xres = info->fix.line_length / BPP;
776 res.xres = ps3fb_res[i].xres; 841 res.yres = info->var.yres_virtual;
777 res.yres = ps3fb_res[i].yres; 842 res.xoff = (res.xres - info->var.xres) / 2;
778 res.xoff = ps3fb_res[i].xoff; 843 res.yoff = (res.yres - info->var.yres) / 2;
779 res.yoff = ps3fb_res[i].yoff; 844 res.num_frames = par->num_frames;
780 res.num_frames = ps3fb.num_frames;
781 if (!copy_to_user(argp, &res, sizeof(res))) 845 if (!copy_to_user(argp, &res, sizeof(res)))
782 retval = 0; 846 retval = 0;
783 break; 847 break;
784 } 848 }
785 849
786 case PS3FB_IOCTL_ON: 850 case PS3FB_IOCTL_ON:
787 DPRINTK("PS3FB_IOCTL_ON:\n"); 851 dev_dbg(info->device, "PS3FB_IOCTL_ON:\n");
788 atomic_inc(&ps3fb.ext_flip); 852 atomic_inc(&ps3fb.ext_flip);
789 retval = 0; 853 retval = 0;
790 break; 854 break;
791 855
792 case PS3FB_IOCTL_OFF: 856 case PS3FB_IOCTL_OFF:
793 DPRINTK("PS3FB_IOCTL_OFF:\n"); 857 dev_dbg(info->device, "PS3FB_IOCTL_OFF:\n");
794 atomic_dec_if_positive(&ps3fb.ext_flip); 858 atomic_dec_if_positive(&ps3fb.ext_flip);
795 retval = 0; 859 retval = 0;
796 break; 860 break;
@@ -799,8 +863,8 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
799 if (copy_from_user(&val, argp, sizeof(val))) 863 if (copy_from_user(&val, argp, sizeof(val)))
800 break; 864 break;
801 865
802 DPRINTK("PS3FB_IOCTL_FSEL:%d\n", val); 866 dev_dbg(info->device, "PS3FB_IOCTL_FSEL:%d\n", val);
803 retval = ps3fb_sync(val); 867 retval = ps3fb_sync(info, val);
804 break; 868 break;
805 869
806 default: 870 default:
@@ -812,13 +876,15 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
812 876
813static int ps3fbd(void *arg) 877static int ps3fbd(void *arg)
814{ 878{
879 struct fb_info *info = arg;
880
815 set_freezable(); 881 set_freezable();
816 while (!kthread_should_stop()) { 882 while (!kthread_should_stop()) {
817 try_to_freeze(); 883 try_to_freeze();
818 set_current_state(TASK_INTERRUPTIBLE); 884 set_current_state(TASK_INTERRUPTIBLE);
819 if (ps3fb.is_kicked) { 885 if (ps3fb.is_kicked) {
820 ps3fb.is_kicked = 0; 886 ps3fb.is_kicked = 0;
821 ps3fb_sync(0); /* single buffer */ 887 ps3fb_sync(info, 0); /* single buffer */
822 } 888 }
823 schedule(); 889 schedule();
824 } 890 }
@@ -827,14 +893,15 @@ static int ps3fbd(void *arg)
827 893
828static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr) 894static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
829{ 895{
896 struct device *dev = ptr;
830 u64 v1; 897 u64 v1;
831 int status; 898 int status;
832 struct display_head *head = &ps3fb.dinfo->display_head[1]; 899 struct display_head *head = &ps3fb.dinfo->display_head[1];
833 900
834 status = lv1_gpu_context_intr(ps3fb.context_handle, &v1); 901 status = lv1_gpu_context_intr(ps3fb.context_handle, &v1);
835 if (status) { 902 if (status) {
836 printk(KERN_ERR "%s: lv1_gpu_context_intr failed: %d\n", 903 dev_err(dev, "%s: lv1_gpu_context_intr failed: %d\n", __func__,
837 __func__, status); 904 status);
838 return IRQ_NONE; 905 return IRQ_NONE;
839 } 906 }
840 907
@@ -854,35 +921,35 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
854 921
855 922
856static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, 923static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
857 struct ps3_system_bus_device *dev) 924 struct device *dev)
858{ 925{
859 int error; 926 int error;
860 927
861 DPRINTK("version_driver:%x\n", dinfo->version_driver); 928 dev_dbg(dev, "version_driver:%x\n", dinfo->version_driver);
862 DPRINTK("irq outlet:%x\n", dinfo->irq.irq_outlet); 929 dev_dbg(dev, "irq outlet:%x\n", dinfo->irq.irq_outlet);
863 DPRINTK("version_gpu:%x memory_size:%x ch:%x core_freq:%d mem_freq:%d\n", 930 dev_dbg(dev,
931 "version_gpu: %x memory_size: %x ch: %x core_freq: %d "
932 "mem_freq:%d\n",
864 dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel, 933 dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel,
865 dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000); 934 dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000);
866 935
867 if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) { 936 if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
868 printk(KERN_ERR "%s: version_driver err:%x\n", __func__, 937 dev_err(dev, "%s: version_driver err:%x\n", __func__,
869 dinfo->version_driver); 938 dinfo->version_driver);
870 return -EINVAL; 939 return -EINVAL;
871 } 940 }
872 941
873 error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet, 942 error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
874 &ps3fb.irq_no); 943 &ps3fb.irq_no);
875 if (error) { 944 if (error) {
876 printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __func__, 945 dev_err(dev, "%s: ps3_alloc_irq failed %d\n", __func__, error);
877 error);
878 return error; 946 return error;
879 } 947 }
880 948
881 error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED, 949 error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
882 DEVICE_NAME, dev); 950 DEVICE_NAME, dev);
883 if (error) { 951 if (error) {
884 printk(KERN_ERR "%s: request_irq failed %d\n", __func__, 952 dev_err(dev, "%s: request_irq failed %d\n", __func__, error);
885 error);
886 ps3_irq_plug_destroy(ps3fb.irq_no); 953 ps3_irq_plug_destroy(ps3fb.irq_no);
887 return error; 954 return error;
888 } 955 }
@@ -892,29 +959,31 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
892 return 0; 959 return 0;
893} 960}
894 961
895static int ps3fb_xdr_settings(u64 xdr_lpar) 962static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev)
896{ 963{
897 int status; 964 int status;
898 965
899 status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, 966 status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
900 xdr_lpar, ps3fb_videomemory.size, 0); 967 xdr_lpar, ps3fb_videomemory.size, 0);
901 if (status) { 968 if (status) {
902 printk(KERN_ERR "%s: lv1_gpu_context_iomap failed: %d\n", 969 dev_err(dev, "%s: lv1_gpu_context_iomap failed: %d\n",
903 __func__, status); 970 __func__, status);
904 return -ENXIO; 971 return -ENXIO;
905 } 972 }
906 DPRINTK("video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n", 973 dev_dbg(dev,
974 "video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n",
907 ps3fb_videomemory.address, ps3fb.xdr_ea, GPU_IOIF, xdr_lpar, 975 ps3fb_videomemory.address, ps3fb.xdr_ea, GPU_IOIF, xdr_lpar,
908 virt_to_abs(ps3fb.xdr_ea), ps3fb_videomemory.size); 976 virt_to_abs(ps3fb.xdr_ea), ps3fb_videomemory.size);
909 977
910 status = lv1_gpu_context_attribute(ps3fb.context_handle, 978 status = lv1_gpu_context_attribute(ps3fb.context_handle,
911 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP, 979 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
912 xdr_lpar, ps3fb_videomemory.size, 980 xdr_lpar + ps3fb.xdr_size,
913 GPU_IOIF, 0); 981 GPU_CMD_BUF_SIZE,
982 GPU_IOIF + ps3fb.xdr_size, 0);
914 if (status) { 983 if (status) {
915 printk(KERN_ERR 984 dev_err(dev,
916 "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n", 985 "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
917 __func__, status); 986 __func__, status);
918 return -ENXIO; 987 return -ENXIO;
919 } 988 }
920 return 0; 989 return 0;
@@ -928,6 +997,7 @@ static struct fb_ops ps3fb_ops = {
928 .fb_check_var = ps3fb_check_var, 997 .fb_check_var = ps3fb_check_var,
929 .fb_set_par = ps3fb_set_par, 998 .fb_set_par = ps3fb_set_par,
930 .fb_setcolreg = ps3fb_setcolreg, 999 .fb_setcolreg = ps3fb_setcolreg,
1000 .fb_pan_display = ps3fb_pan_display,
931 .fb_fillrect = sys_fillrect, 1001 .fb_fillrect = sys_fillrect,
932 .fb_copyarea = sys_copyarea, 1002 .fb_copyarea = sys_copyarea,
933 .fb_imageblit = sys_imageblit, 1003 .fb_imageblit = sys_imageblit,
@@ -944,7 +1014,7 @@ static struct fb_fix_screeninfo ps3fb_fix __initdata = {
944 .accel = FB_ACCEL_NONE, 1014 .accel = FB_ACCEL_NONE,
945}; 1015};
946 1016
947static int ps3fb_set_sync(void) 1017static int ps3fb_set_sync(struct device *dev)
948{ 1018{
949 int status; 1019 int status;
950 1020
@@ -953,8 +1023,10 @@ static int ps3fb_set_sync(void)
953 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 1023 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
954 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); 1024 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
955 if (status) { 1025 if (status) {
956 printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_SYNC " 1026 dev_err(dev,
957 "failed: %d\n", __func__, status); 1027 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
1028 "%d\n",
1029 __func__, status);
958 return -1; 1030 return -1;
959 } 1031 }
960#endif 1032#endif
@@ -964,8 +1036,10 @@ static int ps3fb_set_sync(void)
964 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); 1036 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
965 1037
966 if (status) { 1038 if (status) {
967 printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_MODE " 1039 dev_err(dev,
968 "failed: %d\n", __func__, status); 1040 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
1041 "%d\n",
1042 __func__, status);
969 return -1; 1043 return -1;
970 } 1044 }
971#endif 1045#endif
@@ -975,6 +1049,7 @@ static int ps3fb_set_sync(void)
975static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) 1049static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
976{ 1050{
977 struct fb_info *info; 1051 struct fb_info *info;
1052 struct ps3fb_par *par;
978 int retval = -ENOMEM; 1053 int retval = -ENOMEM;
979 u32 xres, yres; 1054 u32 xres, yres;
980 u64 ddr_lpar = 0; 1055 u64 ddr_lpar = 0;
@@ -983,98 +1058,106 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
983 u64 lpar_reports = 0; 1058 u64 lpar_reports = 0;
984 u64 lpar_reports_size = 0; 1059 u64 lpar_reports_size = 0;
985 u64 xdr_lpar; 1060 u64 xdr_lpar;
986 int status; 1061 int status, res_index;
987 unsigned long offset;
988 struct task_struct *task; 1062 struct task_struct *task;
989 1063
990 status = ps3_open_hv_device(dev); 1064 status = ps3_open_hv_device(dev);
991 if (status) { 1065 if (status) {
992 printk(KERN_ERR "%s: ps3_open_hv_device failed\n", __func__); 1066 dev_err(&dev->core, "%s: ps3_open_hv_device failed\n",
1067 __func__);
993 goto err; 1068 goto err;
994 } 1069 }
995 1070
996 if (!ps3fb_mode) 1071 if (!ps3fb_mode)
997 ps3fb_mode = ps3av_get_mode(); 1072 ps3fb_mode = ps3av_get_mode();
998 DPRINTK("ps3av_mode:%d\n", ps3fb_mode); 1073 dev_dbg(&dev->core, "ps3av_mode:%d\n", ps3fb_mode);
999 1074
1000 if (ps3fb_mode > 0 && 1075 if (ps3fb_mode > 0 &&
1001 !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) { 1076 !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
1002 ps3fb.res_index = ps3fb_get_res_table(xres, yres); 1077 res_index = ps3fb_get_res_table(xres, yres, ps3fb_mode);
1003 DPRINTK("res_index:%d\n", ps3fb.res_index); 1078 dev_dbg(&dev->core, "res_index:%d\n", res_index);
1004 } else 1079 } else
1005 ps3fb.res_index = GPU_RES_INDEX; 1080 res_index = GPU_RES_INDEX;
1006 1081
1007 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */ 1082 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
1008 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ 1083 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
1009 init_waitqueue_head(&ps3fb.wait_vsync); 1084 init_waitqueue_head(&ps3fb.wait_vsync);
1010 ps3fb.num_frames = 1;
1011 1085
1012 ps3fb_set_sync(); 1086 ps3fb_set_sync(&dev->core);
1013 1087
1014 /* get gpu context handle */ 1088 /* get gpu context handle */
1015 status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0, 1089 status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
1016 &ps3fb.memory_handle, &ddr_lpar); 1090 &ps3fb.memory_handle, &ddr_lpar);
1017 if (status) { 1091 if (status) {
1018 printk(KERN_ERR "%s: lv1_gpu_memory_allocate failed: %d\n", 1092 dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
1019 __func__, status); 1093 __func__, status);
1020 goto err; 1094 goto err;
1021 } 1095 }
1022 DPRINTK("ddr:lpar:0x%lx\n", ddr_lpar); 1096 dev_dbg(&dev->core, "ddr:lpar:0x%lx\n", ddr_lpar);
1023 1097
1024 status = lv1_gpu_context_allocate(ps3fb.memory_handle, 0, 1098 status = lv1_gpu_context_allocate(ps3fb.memory_handle, 0,
1025 &ps3fb.context_handle, 1099 &ps3fb.context_handle,
1026 &lpar_dma_control, &lpar_driver_info, 1100 &lpar_dma_control, &lpar_driver_info,
1027 &lpar_reports, &lpar_reports_size); 1101 &lpar_reports, &lpar_reports_size);
1028 if (status) { 1102 if (status) {
1029 printk(KERN_ERR "%s: lv1_gpu_context_attribute failed: %d\n", 1103 dev_err(&dev->core,
1030 __func__, status); 1104 "%s: lv1_gpu_context_attribute failed: %d\n", __func__,
1105 status);
1031 goto err_gpu_memory_free; 1106 goto err_gpu_memory_free;
1032 } 1107 }
1033 1108
1034 /* vsync interrupt */ 1109 /* vsync interrupt */
1035 ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024); 1110 ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024);
1036 if (!ps3fb.dinfo) { 1111 if (!ps3fb.dinfo) {
1037 printk(KERN_ERR "%s: ioremap failed\n", __func__); 1112 dev_err(&dev->core, "%s: ioremap failed\n", __func__);
1038 goto err_gpu_context_free; 1113 goto err_gpu_context_free;
1039 } 1114 }
1040 1115
1041 retval = ps3fb_vsync_settings(ps3fb.dinfo, dev); 1116 retval = ps3fb_vsync_settings(ps3fb.dinfo, &dev->core);
1042 if (retval) 1117 if (retval)
1043 goto err_iounmap_dinfo; 1118 goto err_iounmap_dinfo;
1044 1119
1045 /* xdr frame buffer */ 1120 /* XDR frame buffer */
1046 ps3fb.xdr_ea = ps3fb_videomemory.address; 1121 ps3fb.xdr_ea = ps3fb_videomemory.address;
1047 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea)); 1122 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea));
1048 retval = ps3fb_xdr_settings(xdr_lpar); 1123
1124 /* Clear memory to prevent kernel info leakage into userspace */
1125 memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
1126
1127 /* The GPU command buffer is at the end of video memory */
1128 ps3fb.xdr_size = ps3fb_videomemory.size - GPU_CMD_BUF_SIZE;
1129
1130 retval = ps3fb_xdr_settings(xdr_lpar, &dev->core);
1049 if (retval) 1131 if (retval)
1050 goto err_free_irq; 1132 goto err_free_irq;
1051 1133
1052 /* 1134 info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core);
1053 * ps3fb must clear memory to prevent kernel info
1054 * leakage into userspace
1055 */
1056 memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
1057 info = framebuffer_alloc(sizeof(u32) * 16, &dev->core);
1058 if (!info) 1135 if (!info)
1059 goto err_free_irq; 1136 goto err_free_irq;
1060 1137
1061 offset = FB_OFF(ps3fb.res_index) + VP_OFF(ps3fb.res_index); 1138 par = info->par;
1062 info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset; 1139 par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */
1140 par->new_mode_id = ps3fb_mode;
1141 par->res_index = res_index;
1142 par->num_frames = 1;
1143
1144 info->screen_base = (char __iomem *)ps3fb.xdr_ea;
1063 info->fbops = &ps3fb_ops; 1145 info->fbops = &ps3fb_ops;
1064 1146
1065 info->fix = ps3fb_fix; 1147 info->fix = ps3fb_fix;
1066 info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea); 1148 info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
1067 info->fix.smem_len = ps3fb_videomemory.size - offset; 1149 info->fix.smem_len = ps3fb.xdr_size;
1068 info->pseudo_palette = info->par; 1150 info->pseudo_palette = par->pseudo_palette;
1069 info->par = NULL; 1151 info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
1070 info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST; 1152 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
1071 1153
1072 retval = fb_alloc_cmap(&info->cmap, 256, 0); 1154 retval = fb_alloc_cmap(&info->cmap, 256, 0);
1073 if (retval < 0) 1155 if (retval < 0)
1074 goto err_framebuffer_release; 1156 goto err_framebuffer_release;
1075 1157
1076 if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb, 1158 if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb,
1077 ARRAY_SIZE(ps3fb_modedb), ps3fb_default_mode(), 32)) { 1159 ARRAY_SIZE(ps3fb_modedb),
1160 ps3fb_default_mode(par->new_mode_id), 32)) {
1078 retval = -EINVAL; 1161 retval = -EINVAL;
1079 goto err_fb_dealloc; 1162 goto err_fb_dealloc;
1080 } 1163 }
@@ -1088,9 +1171,9 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1088 1171
1089 dev->core.driver_data = info; 1172 dev->core.driver_data = info;
1090 1173
1091 printk(KERN_INFO 1174 dev_info(info->device, "%s %s, using %lu KiB of video memory\n",
1092 "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n", 1175 dev_driver_string(info->dev), info->dev->bus_id,
1093 info->node, ps3fb_videomemory.size >> 10); 1176 ps3fb.xdr_size >> 10);
1094 1177
1095 task = kthread_run(ps3fbd, info, DEVICE_NAME); 1178 task = kthread_run(ps3fbd, info, DEVICE_NAME);
1096 if (IS_ERR(task)) { 1179 if (IS_ERR(task)) {
@@ -1127,7 +1210,7 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1127 int status; 1210 int status;
1128 struct fb_info *info = dev->core.driver_data; 1211 struct fb_info *info = dev->core.driver_data;
1129 1212
1130 DPRINTK(" -> %s:%d\n", __func__, __LINE__); 1213 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
1131 1214
1132 ps3fb_flip_ctl(0, &ps3fb); /* flip off */ 1215 ps3fb_flip_ctl(0, &ps3fb); /* flip off */
1133 ps3fb.dinfo->irq.mask = 0; 1216 ps3fb.dinfo->irq.mask = 0;
@@ -1152,14 +1235,16 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1152 1235
1153 status = lv1_gpu_context_free(ps3fb.context_handle); 1236 status = lv1_gpu_context_free(ps3fb.context_handle);
1154 if (status) 1237 if (status)
1155 DPRINTK("lv1_gpu_context_free failed: %d\n", status); 1238 dev_dbg(&dev->core, "lv1_gpu_context_free failed: %d\n",
1239 status);
1156 1240
1157 status = lv1_gpu_memory_free(ps3fb.memory_handle); 1241 status = lv1_gpu_memory_free(ps3fb.memory_handle);
1158 if (status) 1242 if (status)
1159 DPRINTK("lv1_gpu_memory_free failed: %d\n", status); 1243 dev_dbg(&dev->core, "lv1_gpu_memory_free failed: %d\n",
1244 status);
1160 1245
1161 ps3_close_hv_device(dev); 1246 ps3_close_hv_device(dev);
1162 DPRINTK(" <- %s:%d\n", __func__, __LINE__); 1247 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
1163 1248
1164 return 0; 1249 return 0;
1165} 1250}
@@ -1212,9 +1297,9 @@ static int __init ps3fb_init(void)
1212 1297
1213static void __exit ps3fb_exit(void) 1298static void __exit ps3fb_exit(void)
1214{ 1299{
1215 DPRINTK(" -> %s:%d\n", __func__, __LINE__); 1300 pr_debug(" -> %s:%d\n", __func__, __LINE__);
1216 ps3_system_bus_driver_unregister(&ps3fb_driver); 1301 ps3_system_bus_driver_unregister(&ps3fb_driver);
1217 DPRINTK(" <- %s:%d\n", __func__, __LINE__); 1302 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1218} 1303}
1219 1304
1220module_init(ps3fb_init); 1305module_init(ps3fb_init);
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 06805c9b237b..6a3d0b574897 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -72,7 +72,7 @@
72#endif 72#endif
73 73
74#ifdef CONFIG_SH_STORE_QUEUES 74#ifdef CONFIG_SH_STORE_QUEUES
75#include <asm/uaccess.h> 75#include <linux/uaccess.h>
76#include <asm/cpu/sq.h> 76#include <asm/cpu/sq.h>
77#endif 77#endif
78 78
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index f9b12ab59642..10f912df2dad 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -43,7 +43,6 @@
43#include <asm/hardware.h> 43#include <asm/hardware.h>
44#include <asm/io.h> 44#include <asm/io.h>
45#include <asm/irq.h> 45#include <asm/irq.h>
46#include <asm/uaccess.h>
47#include <asm/div64.h> 46#include <asm/div64.h>
48#include <asm/arch/pxa-regs.h> 47#include <asm/arch/pxa-regs.h>
49#include <asm/arch/bitfield.h> 48#include <asm/arch/bitfield.h>
@@ -108,20 +107,38 @@ pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
108 u_int trans, struct fb_info *info) 107 u_int trans, struct fb_info *info)
109{ 108{
110 struct pxafb_info *fbi = (struct pxafb_info *)info; 109 struct pxafb_info *fbi = (struct pxafb_info *)info;
111 u_int val, ret = 1; 110 u_int val;
112 111
113 if (regno < fbi->palette_size) { 112 if (regno >= fbi->palette_size)
114 if (fbi->fb.var.grayscale) { 113 return 1;
115 val = ((blue >> 8) & 0x00ff); 114
116 } else { 115 if (fbi->fb.var.grayscale) {
117 val = ((red >> 0) & 0xf800); 116 fbi->palette_cpu[regno] = ((blue >> 8) & 0x00ff);
118 val |= ((green >> 5) & 0x07e0); 117 return 0;
119 val |= ((blue >> 11) & 0x001f); 118 }
120 } 119
120 switch (fbi->lccr4 & LCCR4_PAL_FOR_MASK) {
121 case LCCR4_PAL_FOR_0:
122 val = ((red >> 0) & 0xf800);
123 val |= ((green >> 5) & 0x07e0);
124 val |= ((blue >> 11) & 0x001f);
121 fbi->palette_cpu[regno] = val; 125 fbi->palette_cpu[regno] = val;
122 ret = 0; 126 break;
127 case LCCR4_PAL_FOR_1:
128 val = ((red << 8) & 0x00f80000);
129 val |= ((green >> 0) & 0x0000fc00);
130 val |= ((blue >> 8) & 0x000000f8);
131 ((u32*)(fbi->palette_cpu))[regno] = val;
132 break;
133 case LCCR4_PAL_FOR_2:
134 val = ((red << 8) & 0x00fc0000);
135 val |= ((green >> 0) & 0x0000fc00);
136 val |= ((blue >> 8) & 0x000000fc);
137 ((u32*)(fbi->palette_cpu))[regno] = val;
138 break;
123 } 139 }
124 return ret; 140
141 return 0;
125} 142}
126 143
127static int 144static int
@@ -363,7 +380,10 @@ static int pxafb_set_par(struct fb_info *info)
363 else 380 else
364 fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel; 381 fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel;
365 382
366 palette_mem_size = fbi->palette_size * sizeof(u16); 383 if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
384 palette_mem_size = fbi->palette_size * sizeof(u16);
385 else
386 palette_mem_size = fbi->palette_size * sizeof(u32);
367 387
368 pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size); 388 pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
369 389
@@ -680,7 +700,13 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
680 700
681 fbi->dmadesc_palette_cpu->fsadr = fbi->palette_dma; 701 fbi->dmadesc_palette_cpu->fsadr = fbi->palette_dma;
682 fbi->dmadesc_palette_cpu->fidr = 0; 702 fbi->dmadesc_palette_cpu->fidr = 0;
683 fbi->dmadesc_palette_cpu->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL; 703 if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
704 fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
705 sizeof(u16);
706 else
707 fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
708 sizeof(u32);
709 fbi->dmadesc_palette_cpu->ldcmd |= LDCMD_PAL;
684 710
685 if (var->bits_per_pixel == 16) { 711 if (var->bits_per_pixel == 16) {
686 /* palette shouldn't be loaded in true-color mode */ 712 /* palette shouldn't be loaded in true-color mode */
@@ -719,6 +745,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
719 fbi->reg_lccr1 = new_regs.lccr1; 745 fbi->reg_lccr1 = new_regs.lccr1;
720 fbi->reg_lccr2 = new_regs.lccr2; 746 fbi->reg_lccr2 = new_regs.lccr2;
721 fbi->reg_lccr3 = new_regs.lccr3; 747 fbi->reg_lccr3 = new_regs.lccr3;
748 fbi->reg_lccr4 = LCCR4 & (~LCCR4_PAL_FOR_MASK);
749 fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
722 set_hsync_time(fbi, pcd); 750 set_hsync_time(fbi, pcd);
723 local_irq_restore(flags); 751 local_irq_restore(flags);
724 752
@@ -825,6 +853,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
825 pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1); 853 pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1);
826 pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2); 854 pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2);
827 pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3); 855 pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3);
856 pr_debug("LCCR4 0x%08x\n", (unsigned int) LCCR4);
828} 857}
829 858
830static void pxafb_disable_controller(struct pxafb_info *fbi) 859static void pxafb_disable_controller(struct pxafb_info *fbi)
@@ -1094,10 +1123,13 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
1094 * dma_writecombine_mmap) 1123 * dma_writecombine_mmap)
1095 */ 1124 */
1096 fbi->fb.fix.smem_start = fbi->screen_dma; 1125 fbi->fb.fix.smem_start = fbi->screen_dma;
1097
1098 fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16; 1126 fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16;
1099 1127
1100 palette_mem_size = fbi->palette_size * sizeof(u16); 1128 if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
1129 palette_mem_size = fbi->palette_size * sizeof(u16);
1130 else
1131 palette_mem_size = fbi->palette_size * sizeof(u32);
1132
1101 pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size); 1133 pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
1102 1134
1103 fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); 1135 fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
@@ -1160,6 +1192,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
1160 1192
1161 fbi->lccr0 = inf->lccr0; 1193 fbi->lccr0 = inf->lccr0;
1162 fbi->lccr3 = inf->lccr3; 1194 fbi->lccr3 = inf->lccr3;
1195 fbi->lccr4 = inf->lccr4;
1163 fbi->state = C_STARTUP; 1196 fbi->state = C_STARTUP;
1164 fbi->task_state = (u_char)-1; 1197 fbi->task_state = (u_char)-1;
1165 1198
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index f8605b807b0a..d920b8a14c35 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -71,6 +71,7 @@ struct pxafb_info {
71 71
72 u_int lccr0; 72 u_int lccr0;
73 u_int lccr3; 73 u_int lccr3;
74 u_int lccr4;
74 u_int cmap_inverse:1, 75 u_int cmap_inverse:1,
75 cmap_static:1, 76 cmap_static:1,
76 unused:30; 77 unused:30;
@@ -79,6 +80,7 @@ struct pxafb_info {
79 u_int reg_lccr1; 80 u_int reg_lccr1;
80 u_int reg_lccr2; 81 u_int reg_lccr2;
81 u_int reg_lccr3; 82 u_int reg_lccr3;
83 u_int reg_lccr4;
82 84
83 unsigned long hsync_time; 85 unsigned long hsync_time;
84 86
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 8a4c6470d799..ae08d4587091 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -20,7 +20,7 @@
20 * 20 *
21 * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org> 21 * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org>
22 * - Added the possibility to set on or off the 22 * - Added the possibility to set on or off the
23 * debugging mesaages 23 * debugging messages
24 * - Replaced 0 and 1 by on or off when reading the 24 * - Replaced 0 and 1 by on or off when reading the
25 * /sys files 25 * /sys files
26 * 26 *
@@ -31,8 +31,8 @@
31 * - add pixel clock divisor control 31 * - add pixel clock divisor control
32 * 32 *
33 * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org> 33 * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org>
34 * - Removed the use of currcon as it no more exist 34 * - Removed the use of currcon as it no more exists
35 * - Added LCD power sysfs interface 35 * - Added LCD power sysfs interface
36 * 36 *
37 * 2004-11-03: Ben Dooks <ben-linux@fluff.org> 37 * 2004-11-03: Ben Dooks <ben-linux@fluff.org>
38 * - minor cleanups 38 * - minor cleanups
@@ -49,12 +49,12 @@
49 * - Suppress command line options 49 * - Suppress command line options
50 * 50 *
51 * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org> 51 * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org>
52 * - code cleanup 52 * - code cleanup
53 * 53 *
54 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org> 54 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
55 * - Renamed from h1940fb.c to s3c2410fb.c 55 * - Renamed from h1940fb.c to s3c2410fb.c
56 * - Add support for different devices 56 * - Add support for different devices
57 * - Backlight support 57 * - Backlight support
58 * 58 *
59 * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at> 59 * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
60 * - added clock (de-)allocation code 60 * - added clock (de-)allocation code
@@ -82,13 +82,10 @@
82#include <linux/init.h> 82#include <linux/init.h>
83#include <linux/dma-mapping.h> 83#include <linux/dma-mapping.h>
84#include <linux/interrupt.h> 84#include <linux/interrupt.h>
85#include <linux/workqueue.h>
86#include <linux/wait.h>
87#include <linux/platform_device.h> 85#include <linux/platform_device.h>
88#include <linux/clk.h> 86#include <linux/clk.h>
89 87
90#include <asm/io.h> 88#include <asm/io.h>
91#include <asm/uaccess.h>
92#include <asm/div64.h> 89#include <asm/div64.h>
93 90
94#include <asm/mach/map.h> 91#include <asm/mach/map.h>
@@ -102,14 +99,11 @@
102 99
103#include "s3c2410fb.h" 100#include "s3c2410fb.h"
104 101
105
106static struct s3c2410fb_mach_info *mach_info;
107
108/* Debugging stuff */ 102/* Debugging stuff */
109#ifdef CONFIG_FB_S3C2410_DEBUG 103#ifdef CONFIG_FB_S3C2410_DEBUG
110static int debug = 1; 104static int debug = 1;
111#else 105#else
112static int debug = 0; 106static int debug = 0;
113#endif 107#endif
114 108
115#define dprintk(msg...) if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); } 109#define dprintk(msg...) if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); }
@@ -119,48 +113,48 @@ static int debug = 0;
119/* s3c2410fb_set_lcdaddr 113/* s3c2410fb_set_lcdaddr
120 * 114 *
121 * initialise lcd controller address pointers 115 * initialise lcd controller address pointers
122*/ 116 */
123 117static void s3c2410fb_set_lcdaddr(struct fb_info *info)
124static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi)
125{ 118{
126 struct fb_var_screeninfo *var = &fbi->fb->var;
127 unsigned long saddr1, saddr2, saddr3; 119 unsigned long saddr1, saddr2, saddr3;
120 struct s3c2410fb_info *fbi = info->par;
121 void __iomem *regs = fbi->io;
128 122
129 saddr1 = fbi->fb->fix.smem_start >> 1; 123 saddr1 = info->fix.smem_start >> 1;
130 saddr2 = fbi->fb->fix.smem_start; 124 saddr2 = info->fix.smem_start;
131 saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8; 125 saddr2 += info->fix.line_length * info->var.yres;
132 saddr2>>= 1; 126 saddr2 >>= 1;
133 127
134 saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH((var->xres * var->bits_per_pixel / 16) & 0x3ff); 128 saddr3 = S3C2410_OFFSIZE(0) |
129 S3C2410_PAGEWIDTH((info->fix.line_length / 2) & 0x3ff);
135 130
136 dprintk("LCDSADDR1 = 0x%08lx\n", saddr1); 131 dprintk("LCDSADDR1 = 0x%08lx\n", saddr1);
137 dprintk("LCDSADDR2 = 0x%08lx\n", saddr2); 132 dprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
138 dprintk("LCDSADDR3 = 0x%08lx\n", saddr3); 133 dprintk("LCDSADDR3 = 0x%08lx\n", saddr3);
139 134
140 writel(saddr1, S3C2410_LCDSADDR1); 135 writel(saddr1, regs + S3C2410_LCDSADDR1);
141 writel(saddr2, S3C2410_LCDSADDR2); 136 writel(saddr2, regs + S3C2410_LCDSADDR2);
142 writel(saddr3, S3C2410_LCDSADDR3); 137 writel(saddr3, regs + S3C2410_LCDSADDR3);
143} 138}
144 139
145/* s3c2410fb_calc_pixclk() 140/* s3c2410fb_calc_pixclk()
146 * 141 *
147 * calculate divisor for clk->pixclk 142 * calculate divisor for clk->pixclk
148*/ 143 */
149
150static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi, 144static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi,
151 unsigned long pixclk) 145 unsigned long pixclk)
152{ 146{
153 unsigned long clk = clk_get_rate(fbi->clk); 147 unsigned long clk = clk_get_rate(fbi->clk);
154 unsigned long long div; 148 unsigned long long div;
155 149
156 /* pixclk is in picoseoncds, our clock is in Hz 150 /* pixclk is in picoseconds, our clock is in Hz
157 * 151 *
158 * Hz -> picoseconds is / 10^-12 152 * Hz -> picoseconds is / 10^-12
159 */ 153 */
160 154
161 div = (unsigned long long)clk * pixclk; 155 div = (unsigned long long)clk * pixclk;
162 do_div(div,1000000UL); 156 div >>= 12; /* div / 2^12 */
163 do_div(div,1000000UL); 157 do_div(div, 625 * 625UL * 625); /* div / 5^12 */
164 158
165 dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div); 159 dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div);
166 return div; 160 return div;
@@ -176,246 +170,278 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
176 struct fb_info *info) 170 struct fb_info *info)
177{ 171{
178 struct s3c2410fb_info *fbi = info->par; 172 struct s3c2410fb_info *fbi = info->par;
173 struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
174 struct s3c2410fb_display *display = NULL;
175 struct s3c2410fb_display *default_display = mach_info->displays +
176 mach_info->default_display;
177 int type = default_display->type;
178 unsigned i;
179 179
180 dprintk("check_var(var=%p, info=%p)\n", var, info); 180 dprintk("check_var(var=%p, info=%p)\n", var, info);
181 181
182 /* validate x/y resolution */ 182 /* validate x/y resolution */
183 /* choose default mode if possible */
184 if (var->yres == default_display->yres &&
185 var->xres == default_display->xres &&
186 var->bits_per_pixel == default_display->bpp)
187 display = default_display;
188 else
189 for (i = 0; i < mach_info->num_displays; i++)
190 if (type == mach_info->displays[i].type &&
191 var->yres == mach_info->displays[i].yres &&
192 var->xres == mach_info->displays[i].xres &&
193 var->bits_per_pixel == mach_info->displays[i].bpp) {
194 display = mach_info->displays + i;
195 break;
196 }
183 197
184 if (var->yres > fbi->mach_info->yres.max) 198 if (!display) {
185 var->yres = fbi->mach_info->yres.max; 199 dprintk("wrong resolution or depth %dx%d at %d bpp\n",
186 else if (var->yres < fbi->mach_info->yres.min) 200 var->xres, var->yres, var->bits_per_pixel);
187 var->yres = fbi->mach_info->yres.min; 201 return -EINVAL;
188 202 }
189 if (var->xres > fbi->mach_info->xres.max)
190 var->yres = fbi->mach_info->xres.max;
191 else if (var->xres < fbi->mach_info->xres.min)
192 var->xres = fbi->mach_info->xres.min;
193
194 /* validate bpp */
195
196 if (var->bits_per_pixel > fbi->mach_info->bpp.max)
197 var->bits_per_pixel = fbi->mach_info->bpp.max;
198 else if (var->bits_per_pixel < fbi->mach_info->bpp.min)
199 var->bits_per_pixel = fbi->mach_info->bpp.min;
200 203
204 /* it is always the size as the display */
205 var->xres_virtual = display->xres;
206 var->yres_virtual = display->yres;
207 var->height = display->height;
208 var->width = display->width;
209
210 /* copy lcd settings */
211 var->pixclock = display->pixclock;
212 var->left_margin = display->left_margin;
213 var->right_margin = display->right_margin;
214 var->upper_margin = display->upper_margin;
215 var->lower_margin = display->lower_margin;
216 var->vsync_len = display->vsync_len;
217 var->hsync_len = display->hsync_len;
218
219 fbi->regs.lcdcon5 = display->lcdcon5;
220 /* set display type */
221 fbi->regs.lcdcon1 = display->type;
222
223 var->transp.offset = 0;
224 var->transp.length = 0;
201 /* set r/g/b positions */ 225 /* set r/g/b positions */
202 switch (var->bits_per_pixel) { 226 switch (var->bits_per_pixel) {
203 case 1: 227 case 1:
204 case 2: 228 case 2:
205 case 4: 229 case 4:
206 var->red.offset = 0; 230 var->red.offset = 0;
207 var->red.length = var->bits_per_pixel; 231 var->red.length = var->bits_per_pixel;
208 var->green = var->red; 232 var->green = var->red;
209 var->blue = var->red; 233 var->blue = var->red;
210 var->transp.offset = 0; 234 break;
211 var->transp.length = 0; 235 case 8:
212 break; 236 if (display->type != S3C2410_LCDCON1_TFT) {
213 case 8: 237 /* 8 bpp 332 */
214 if ( fbi->mach_info->type != S3C2410_LCDCON1_TFT ) { 238 var->red.length = 3;
215 /* 8 bpp 332 */ 239 var->red.offset = 5;
216 var->red.length = 3; 240 var->green.length = 3;
217 var->red.offset = 5; 241 var->green.offset = 2;
218 var->green.length = 3; 242 var->blue.length = 2;
219 var->green.offset = 2;
220 var->blue.length = 2;
221 var->blue.offset = 0;
222 var->transp.length = 0;
223 } else {
224 var->red.offset = 0;
225 var->red.length = var->bits_per_pixel;
226 var->green = var->red;
227 var->blue = var->red;
228 var->transp.offset = 0;
229 var->transp.length = 0;
230 }
231 break;
232 case 12:
233 /* 12 bpp 444 */
234 var->red.length = 4;
235 var->red.offset = 8;
236 var->green.length = 4;
237 var->green.offset = 4;
238 var->blue.length = 4;
239 var->blue.offset = 0; 243 var->blue.offset = 0;
240 var->transp.length = 0; 244 } else {
241 break; 245 var->red.offset = 0;
242
243 default:
244 case 16:
245 if (fbi->regs.lcdcon5 & S3C2410_LCDCON5_FRM565 ) {
246 /* 16 bpp, 565 format */
247 var->red.offset = 11;
248 var->green.offset = 5;
249 var->blue.offset = 0;
250 var->red.length = 5;
251 var->green.length = 6;
252 var->blue.length = 5;
253 var->transp.length = 0;
254 } else {
255 /* 16 bpp, 5551 format */
256 var->red.offset = 11;
257 var->green.offset = 6;
258 var->blue.offset = 1;
259 var->red.length = 5;
260 var->green.length = 5;
261 var->blue.length = 5;
262 var->transp.length = 0;
263 }
264 break;
265 case 24:
266 /* 24 bpp 888 */
267 var->red.length = 8; 246 var->red.length = 8;
268 var->red.offset = 16; 247 var->green = var->red;
269 var->green.length = 8; 248 var->blue = var->red;
270 var->green.offset = 8; 249 }
271 var->blue.length = 8; 250 break;
272 var->blue.offset = 0; 251 case 12:
273 var->transp.length = 0; 252 /* 12 bpp 444 */
274 break; 253 var->red.length = 4;
275 254 var->red.offset = 8;
255 var->green.length = 4;
256 var->green.offset = 4;
257 var->blue.length = 4;
258 var->blue.offset = 0;
259 break;
276 260
261 default:
262 case 16:
263 if (display->lcdcon5 & S3C2410_LCDCON5_FRM565) {
264 /* 16 bpp, 565 format */
265 var->red.offset = 11;
266 var->green.offset = 5;
267 var->blue.offset = 0;
268 var->red.length = 5;
269 var->green.length = 6;
270 var->blue.length = 5;
271 } else {
272 /* 16 bpp, 5551 format */
273 var->red.offset = 11;
274 var->green.offset = 6;
275 var->blue.offset = 1;
276 var->red.length = 5;
277 var->green.length = 5;
278 var->blue.length = 5;
279 }
280 break;
281 case 32:
282 /* 24 bpp 888 and 8 dummy */
283 var->red.length = 8;
284 var->red.offset = 16;
285 var->green.length = 8;
286 var->green.offset = 8;
287 var->blue.length = 8;
288 var->blue.offset = 0;
289 break;
277 } 290 }
278 return 0; 291 return 0;
279} 292}
280 293
281 294/* s3c2410fb_calculate_stn_lcd_regs
282/* s3c2410fb_activate_var
283 * 295 *
284 * activate (set) the controller from the given framebuffer 296 * calculate register values from var settings
285 * information 297 */
286*/ 298static void s3c2410fb_calculate_stn_lcd_regs(const struct fb_info *info,
287 299 struct s3c2410fb_hw *regs)
288static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
289 struct fb_var_screeninfo *var)
290{ 300{
291 int hs; 301 const struct s3c2410fb_info *fbi = info->par;
302 const struct fb_var_screeninfo *var = &info->var;
303 int type = regs->lcdcon1 & ~S3C2410_LCDCON1_TFT;
304 int hs = var->xres >> 2;
305 unsigned wdly = (var->left_margin >> 4) - 1;
306 unsigned wlh = (var->hsync_len >> 4) - 1;
292 307
293 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK; 308 if (type != S3C2410_LCDCON1_STN4)
294 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_TFT; 309 hs >>= 1;
295 310
296 dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres); 311 switch (var->bits_per_pixel) {
297 dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres); 312 case 1:
298 dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel); 313 regs->lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
314 break;
315 case 2:
316 regs->lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
317 break;
318 case 4:
319 regs->lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
320 break;
321 case 8:
322 regs->lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
323 hs *= 3;
324 break;
325 case 12:
326 regs->lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
327 hs *= 3;
328 break;
299 329
300 fbi->regs.lcdcon1 |= fbi->mach_info->type; 330 default:
301 331 /* invalid pixel depth */
302 if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) 332 dev_err(fbi->dev, "invalid bpp %d\n",
303 switch (var->bits_per_pixel) { 333 var->bits_per_pixel);
304 case 1: 334 }
305 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP; 335 /* update X/Y info */
306 break; 336 dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
307 case 2: 337 var->left_margin, var->right_margin, var->hsync_len);
308 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
309 break;
310 case 4:
311 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
312 break;
313 case 8:
314 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
315 break;
316 case 16:
317 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
318 break;
319
320 default:
321 /* invalid pixel depth */
322 dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
323 }
324 else
325 switch (var->bits_per_pixel) {
326 case 1:
327 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
328 break;
329 case 2:
330 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
331 break;
332 case 4:
333 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
334 break;
335 case 8:
336 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
337 break;
338 case 12:
339 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
340 break;
341
342 default:
343 /* invalid pixel depth */
344 dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
345 }
346 338
347 /* check to see if we need to update sync/borders */ 339 regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1);
348 340
349 if (!fbi->mach_info->fixed_syncs) { 341 if (wdly > 3)
350 dprintk("setting vert: up=%d, low=%d, sync=%d\n", 342 wdly = 3;
351 var->upper_margin, var->lower_margin,
352 var->vsync_len);
353 343
354 dprintk("setting horz: lft=%d, rt=%d, sync=%d\n", 344 if (wlh > 3)
355 var->left_margin, var->right_margin, 345 wlh = 3;
356 var->hsync_len);
357 346
358 fbi->regs.lcdcon2 = 347 regs->lcdcon3 = S3C2410_LCDCON3_WDLY(wdly) |
359 S3C2410_LCDCON2_VBPD(var->upper_margin - 1) | 348 S3C2410_LCDCON3_LINEBLANK(var->right_margin / 8) |
360 S3C2410_LCDCON2_VFPD(var->lower_margin - 1) | 349 S3C2410_LCDCON3_HOZVAL(hs - 1);
361 S3C2410_LCDCON2_VSPW(var->vsync_len - 1);
362 350
363 fbi->regs.lcdcon3 = 351 regs->lcdcon4 = S3C2410_LCDCON4_WLH(wlh);
364 S3C2410_LCDCON3_HBPD(var->right_margin - 1) | 352}
365 S3C2410_LCDCON3_HFPD(var->left_margin - 1);
366 353
367 fbi->regs.lcdcon4 &= ~S3C2410_LCDCON4_HSPW(0xff); 354/* s3c2410fb_calculate_tft_lcd_regs
368 fbi->regs.lcdcon4 |= S3C2410_LCDCON4_HSPW(var->hsync_len - 1); 355 *
369 } 356 * calculate register values from var settings
357 */
358static void s3c2410fb_calculate_tft_lcd_regs(const struct fb_info *info,
359 struct s3c2410fb_hw *regs)
360{
361 const struct s3c2410fb_info *fbi = info->par;
362 const struct fb_var_screeninfo *var = &info->var;
370 363
364 switch (var->bits_per_pixel) {
365 case 1:
366 regs->lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
367 break;
368 case 2:
369 regs->lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
370 break;
371 case 4:
372 regs->lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
373 break;
374 case 8:
375 regs->lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
376 regs->lcdcon5 |= S3C2410_LCDCON5_BSWP |
377 S3C2410_LCDCON5_FRM565;
378 regs->lcdcon5 &= ~S3C2410_LCDCON5_HWSWP;
379 break;
380 case 16:
381 regs->lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
382 regs->lcdcon5 &= ~S3C2410_LCDCON5_BSWP;
383 regs->lcdcon5 |= S3C2410_LCDCON5_HWSWP;
384 break;
385 case 32:
386 regs->lcdcon1 |= S3C2410_LCDCON1_TFT24BPP;
387 regs->lcdcon5 &= ~(S3C2410_LCDCON5_BSWP |
388 S3C2410_LCDCON5_HWSWP |
389 S3C2410_LCDCON5_BPP24BL);
390 break;
391 default:
392 /* invalid pixel depth */
393 dev_err(fbi->dev, "invalid bpp %d\n",
394 var->bits_per_pixel);
395 }
371 /* update X/Y info */ 396 /* update X/Y info */
397 dprintk("setting vert: up=%d, low=%d, sync=%d\n",
398 var->upper_margin, var->lower_margin, var->vsync_len);
372 399
373 fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff); 400 dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
374 fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1); 401 var->left_margin, var->right_margin, var->hsync_len);
375
376 switch(fbi->mach_info->type) {
377 case S3C2410_LCDCON1_DSCAN4:
378 case S3C2410_LCDCON1_STN8:
379 hs = var->xres / 8;
380 break;
381 case S3C2410_LCDCON1_STN4:
382 hs = var->xres / 4;
383 break;
384 default:
385 case S3C2410_LCDCON1_TFT:
386 hs = var->xres;
387 break;
388
389 }
390 402
391 /* Special cases : STN color displays */ 403 regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1) |
392 if ( ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN8BPP) \ 404 S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |
393 || ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN12BPP) ) { 405 S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |
394 hs = hs * 3; 406 S3C2410_LCDCON2_VSPW(var->vsync_len - 1);
395 }
396 407
408 regs->lcdcon3 = S3C2410_LCDCON3_HBPD(var->right_margin - 1) |
409 S3C2410_LCDCON3_HFPD(var->left_margin - 1) |
410 S3C2410_LCDCON3_HOZVAL(var->xres - 1);
397 411
398 fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff); 412 regs->lcdcon4 = S3C2410_LCDCON4_HSPW(var->hsync_len - 1);
399 fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(hs - 1); 413}
400 414
401 if (var->pixclock > 0) { 415/* s3c2410fb_activate_var
402 int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock); 416 *
417 * activate (set) the controller from the given framebuffer
418 * information
419 */
420static void s3c2410fb_activate_var(struct fb_info *info)
421{
422 struct s3c2410fb_info *fbi = info->par;
423 void __iomem *regs = fbi->io;
424 int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT;
425 struct fb_var_screeninfo *var = &info->var;
426 int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock) / 2;
403 427
404 if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) { 428 dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres);
405 clkdiv = (clkdiv / 2) -1; 429 dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
406 if (clkdiv < 0) 430 dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
407 clkdiv = 0;
408 }
409 else {
410 clkdiv = (clkdiv / 2);
411 if (clkdiv < 2)
412 clkdiv = 2;
413 }
414 431
415 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_CLKVAL(0x3ff); 432 if (type == S3C2410_LCDCON1_TFT) {
416 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv); 433 s3c2410fb_calculate_tft_lcd_regs(info, &fbi->regs);
434 --clkdiv;
435 if (clkdiv < 0)
436 clkdiv = 0;
437 } else {
438 s3c2410fb_calculate_stn_lcd_regs(info, &fbi->regs);
439 if (clkdiv < 2)
440 clkdiv = 2;
417 } 441 }
418 442
443 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);
444
419 /* write new registers */ 445 /* write new registers */
420 446
421 dprintk("new register set:\n"); 447 dprintk("new register set:\n");
@@ -425,47 +451,48 @@ static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
425 dprintk("lcdcon[4] = 0x%08lx\n", fbi->regs.lcdcon4); 451 dprintk("lcdcon[4] = 0x%08lx\n", fbi->regs.lcdcon4);
426 dprintk("lcdcon[5] = 0x%08lx\n", fbi->regs.lcdcon5); 452 dprintk("lcdcon[5] = 0x%08lx\n", fbi->regs.lcdcon5);
427 453
428 writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1); 454 writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID,
429 writel(fbi->regs.lcdcon2, S3C2410_LCDCON2); 455 regs + S3C2410_LCDCON1);
430 writel(fbi->regs.lcdcon3, S3C2410_LCDCON3); 456 writel(fbi->regs.lcdcon2, regs + S3C2410_LCDCON2);
431 writel(fbi->regs.lcdcon4, S3C2410_LCDCON4); 457 writel(fbi->regs.lcdcon3, regs + S3C2410_LCDCON3);
432 writel(fbi->regs.lcdcon5, S3C2410_LCDCON5); 458 writel(fbi->regs.lcdcon4, regs + S3C2410_LCDCON4);
459 writel(fbi->regs.lcdcon5, regs + S3C2410_LCDCON5);
433 460
434 /* set lcd address pointers */ 461 /* set lcd address pointers */
435 s3c2410fb_set_lcdaddr(fbi); 462 s3c2410fb_set_lcdaddr(info);
436 463
437 writel(fbi->regs.lcdcon1, S3C2410_LCDCON1); 464 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID,
465 writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
438} 466}
439 467
440
441/* 468/*
442 * s3c2410fb_set_par - Optional function. Alters the hardware state. 469 * s3c2410fb_set_par - Alters the hardware state.
443 * @info: frame buffer structure that represents a single frame buffer 470 * @info: frame buffer structure that represents a single frame buffer
444 * 471 *
445 */ 472 */
446static int s3c2410fb_set_par(struct fb_info *info) 473static int s3c2410fb_set_par(struct fb_info *info)
447{ 474{
448 struct s3c2410fb_info *fbi = info->par;
449 struct fb_var_screeninfo *var = &info->var; 475 struct fb_var_screeninfo *var = &info->var;
450 476
451 switch (var->bits_per_pixel) 477 switch (var->bits_per_pixel) {
452 { 478 case 32:
453 case 16: 479 case 16:
454 fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR; 480 case 12:
455 break; 481 info->fix.visual = FB_VISUAL_TRUECOLOR;
456 case 1: 482 break;
457 fbi->fb->fix.visual = FB_VISUAL_MONO01; 483 case 1:
458 break; 484 info->fix.visual = FB_VISUAL_MONO01;
459 default: 485 break;
460 fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR; 486 default:
461 break; 487 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
488 break;
462 } 489 }
463 490
464 fbi->fb->fix.line_length = (var->width*var->bits_per_pixel)/8; 491 info->fix.line_length = (var->width * var->bits_per_pixel) / 8;
465 492
466 /* activate this new configuration */ 493 /* activate this new configuration */
467 494
468 s3c2410fb_activate_var(fbi, var); 495 s3c2410fb_activate_var(info);
469 return 0; 496 return 0;
470} 497}
471 498
@@ -493,7 +520,8 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
493} 520}
494 521
495/* from pxafb.c */ 522/* from pxafb.c */
496static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf) 523static inline unsigned int chan_to_field(unsigned int chan,
524 struct fb_bitfield *bf)
497{ 525{
498 chan &= 0xffff; 526 chan &= 0xffff;
499 chan >>= 16 - bf->length; 527 chan >>= 16 - bf->length;
@@ -505,20 +533,22 @@ static int s3c2410fb_setcolreg(unsigned regno,
505 unsigned transp, struct fb_info *info) 533 unsigned transp, struct fb_info *info)
506{ 534{
507 struct s3c2410fb_info *fbi = info->par; 535 struct s3c2410fb_info *fbi = info->par;
536 void __iomem *regs = fbi->io;
508 unsigned int val; 537 unsigned int val;
509 538
510 /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n", regno, red, green, blue); */ 539 /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n",
540 regno, red, green, blue); */
511 541
512 switch (fbi->fb->fix.visual) { 542 switch (info->fix.visual) {
513 case FB_VISUAL_TRUECOLOR: 543 case FB_VISUAL_TRUECOLOR:
514 /* true-colour, use pseuo-palette */ 544 /* true-colour, use pseudo-palette */
515 545
516 if (regno < 16) { 546 if (regno < 16) {
517 u32 *pal = fbi->fb->pseudo_palette; 547 u32 *pal = info->pseudo_palette;
518 548
519 val = chan_to_field(red, &fbi->fb->var.red); 549 val = chan_to_field(red, &info->var.red);
520 val |= chan_to_field(green, &fbi->fb->var.green); 550 val |= chan_to_field(green, &info->var.green);
521 val |= chan_to_field(blue, &fbi->fb->var.blue); 551 val |= chan_to_field(blue, &info->var.blue);
522 552
523 pal[regno] = val; 553 pal[regno] = val;
524 } 554 }
@@ -528,25 +558,24 @@ static int s3c2410fb_setcolreg(unsigned regno,
528 if (regno < 256) { 558 if (regno < 256) {
529 /* currently assume RGB 5-6-5 mode */ 559 /* currently assume RGB 5-6-5 mode */
530 560
531 val = ((red >> 0) & 0xf800); 561 val = (red >> 0) & 0xf800;
532 val |= ((green >> 5) & 0x07e0); 562 val |= (green >> 5) & 0x07e0;
533 val |= ((blue >> 11) & 0x001f); 563 val |= (blue >> 11) & 0x001f;
534 564
535 writel(val, S3C2410_TFTPAL(regno)); 565 writel(val, regs + S3C2410_TFTPAL(regno));
536 schedule_palette_update(fbi, regno, val); 566 schedule_palette_update(fbi, regno, val);
537 } 567 }
538 568
539 break; 569 break;
540 570
541 default: 571 default:
542 return 1; /* unknown type */ 572 return 1; /* unknown type */
543 } 573 }
544 574
545 return 0; 575 return 0;
546} 576}
547 577
548 578/*
549/**
550 * s3c2410fb_blank 579 * s3c2410fb_blank
551 * @blank_mode: the blank mode we want. 580 * @blank_mode: the blank mode we want.
552 * @info: frame buffer structure that represents a single frame buffer 581 * @info: frame buffer structure that represents a single frame buffer
@@ -564,31 +593,31 @@ static int s3c2410fb_setcolreg(unsigned regno,
564 */ 593 */
565static int s3c2410fb_blank(int blank_mode, struct fb_info *info) 594static int s3c2410fb_blank(int blank_mode, struct fb_info *info)
566{ 595{
567 dprintk("blank(mode=%d, info=%p)\n", blank_mode, info); 596 struct s3c2410fb_info *fbi = info->par;
597 void __iomem *regs = fbi->io;
568 598
569 if (mach_info == NULL) 599 dprintk("blank(mode=%d, info=%p)\n", blank_mode, info);
570 return -EINVAL;
571 600
572 if (blank_mode == FB_BLANK_UNBLANK) 601 if (blank_mode == FB_BLANK_UNBLANK)
573 writel(0x0, S3C2410_TPAL); 602 writel(0x0, regs + S3C2410_TPAL);
574 else { 603 else {
575 dprintk("setting TPAL to output 0x000000\n"); 604 dprintk("setting TPAL to output 0x000000\n");
576 writel(S3C2410_TPAL_EN, S3C2410_TPAL); 605 writel(S3C2410_TPAL_EN, regs + S3C2410_TPAL);
577 } 606 }
578 607
579 return 0; 608 return 0;
580} 609}
581 610
582static int s3c2410fb_debug_show(struct device *dev, struct device_attribute *attr, char *buf) 611static int s3c2410fb_debug_show(struct device *dev,
612 struct device_attribute *attr, char *buf)
583{ 613{
584 return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off"); 614 return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off");
585} 615}
586static int s3c2410fb_debug_store(struct device *dev, struct device_attribute *attr,
587 const char *buf, size_t len)
588{
589 if (mach_info == NULL)
590 return -EINVAL;
591 616
617static int s3c2410fb_debug_store(struct device *dev,
618 struct device_attribute *attr,
619 const char *buf, size_t len)
620{
592 if (len < 1) 621 if (len < 1)
593 return -EINVAL; 622 return -EINVAL;
594 623
@@ -607,10 +636,7 @@ static int s3c2410fb_debug_store(struct device *dev, struct device_attribute *at
607 return len; 636 return len;
608} 637}
609 638
610 639static DEVICE_ATTR(debug, 0666, s3c2410fb_debug_show, s3c2410fb_debug_store);
611static DEVICE_ATTR(debug, 0666,
612 s3c2410fb_debug_show,
613 s3c2410fb_debug_store);
614 640
615static struct fb_ops s3c2410fb_ops = { 641static struct fb_ops s3c2410fb_ops = {
616 .owner = THIS_MODULE, 642 .owner = THIS_MODULE,
@@ -623,7 +649,6 @@ static struct fb_ops s3c2410fb_ops = {
623 .fb_imageblit = cfb_imageblit, 649 .fb_imageblit = cfb_imageblit,
624}; 650};
625 651
626
627/* 652/*
628 * s3c2410fb_map_video_memory(): 653 * s3c2410fb_map_video_memory():
629 * Allocates the DRAM memory for the frame buffer. This buffer is 654 * Allocates the DRAM memory for the frame buffer. This buffer is
@@ -632,36 +657,38 @@ static struct fb_ops s3c2410fb_ops = {
632 * cache. Once this area is remapped, all virtual memory 657 * cache. Once this area is remapped, all virtual memory
633 * access to the video memory should occur at the new region. 658 * access to the video memory should occur at the new region.
634 */ 659 */
635static int __init s3c2410fb_map_video_memory(struct s3c2410fb_info *fbi) 660static int __init s3c2410fb_map_video_memory(struct fb_info *info)
636{ 661{
637 dprintk("map_video_memory(fbi=%p)\n", fbi); 662 struct s3c2410fb_info *fbi = info->par;
663 dma_addr_t map_dma;
664 unsigned map_size = PAGE_ALIGN(info->fix.smem_len);
638 665
639 fbi->map_size = PAGE_ALIGN(fbi->fb->fix.smem_len + PAGE_SIZE); 666 dprintk("map_video_memory(fbi=%p)\n", fbi);
640 fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
641 &fbi->map_dma, GFP_KERNEL);
642 667
643 fbi->map_size = fbi->fb->fix.smem_len; 668 info->screen_base = dma_alloc_writecombine(fbi->dev, map_size,
669 &map_dma, GFP_KERNEL);
644 670
645 if (fbi->map_cpu) { 671 if (info->screen_base) {
646 /* prevent initial garbage on screen */ 672 /* prevent initial garbage on screen */
647 dprintk("map_video_memory: clear %p:%08x\n", 673 dprintk("map_video_memory: clear %p:%08x\n",
648 fbi->map_cpu, fbi->map_size); 674 info->screen_base, map_size);
649 memset(fbi->map_cpu, 0xf0, fbi->map_size); 675 memset(info->screen_base, 0xf0, map_size);
650 676
651 fbi->screen_dma = fbi->map_dma; 677 info->fix.smem_start = map_dma;
652 fbi->fb->screen_base = fbi->map_cpu;
653 fbi->fb->fix.smem_start = fbi->screen_dma;
654 678
655 dprintk("map_video_memory: dma=%08x cpu=%p size=%08x\n", 679 dprintk("map_video_memory: dma=%08lx cpu=%p size=%08x\n",
656 fbi->map_dma, fbi->map_cpu, fbi->fb->fix.smem_len); 680 info->fix.smem_start, info->screen_base, map_size);
657 } 681 }
658 682
659 return fbi->map_cpu ? 0 : -ENOMEM; 683 return info->screen_base ? 0 : -ENOMEM;
660} 684}
661 685
662static inline void s3c2410fb_unmap_video_memory(struct s3c2410fb_info *fbi) 686static inline void s3c2410fb_unmap_video_memory(struct fb_info *info)
663{ 687{
664 dma_free_writecombine(fbi->dev,fbi->map_size,fbi->map_cpu, fbi->map_dma); 688 struct s3c2410fb_info *fbi = info->par;
689
690 dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
691 info->screen_base, info->fix.smem_start);
665} 692}
666 693
667static inline void modify_gpio(void __iomem *reg, 694static inline void modify_gpio(void __iomem *reg,
@@ -673,13 +700,13 @@ static inline void modify_gpio(void __iomem *reg,
673 writel(tmp | set, reg); 700 writel(tmp | set, reg);
674} 701}
675 702
676
677/* 703/*
678 * s3c2410fb_init_registers - Initialise all LCD-related registers 704 * s3c2410fb_init_registers - Initialise all LCD-related registers
679 */ 705 */
680 706static int s3c2410fb_init_registers(struct fb_info *info)
681static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
682{ 707{
708 struct s3c2410fb_info *fbi = info->par;
709 struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
683 unsigned long flags; 710 unsigned long flags;
684 void __iomem *regs = fbi->io; 711 void __iomem *regs = fbi->io;
685 712
@@ -696,14 +723,6 @@ static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
696 723
697 local_irq_restore(flags); 724 local_irq_restore(flags);
698 725
699 writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
700 writel(fbi->regs.lcdcon2, regs + S3C2410_LCDCON2);
701 writel(fbi->regs.lcdcon3, regs + S3C2410_LCDCON3);
702 writel(fbi->regs.lcdcon4, regs + S3C2410_LCDCON4);
703 writel(fbi->regs.lcdcon5, regs + S3C2410_LCDCON5);
704
705 s3c2410fb_set_lcdaddr(fbi);
706
707 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel); 726 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel);
708 writel(mach_info->lpcsel, regs + S3C2410_LPCSEL); 727 writel(mach_info->lpcsel, regs + S3C2410_LPCSEL);
709 728
@@ -712,22 +731,19 @@ static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
712 /* ensure temporary palette disabled */ 731 /* ensure temporary palette disabled */
713 writel(0x00, regs + S3C2410_TPAL); 732 writel(0x00, regs + S3C2410_TPAL);
714 733
715 /* Enable video by setting the ENVID bit to 1 */
716 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID;
717 writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
718 return 0; 734 return 0;
719} 735}
720 736
721static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi) 737static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
722{ 738{
723 unsigned int i; 739 unsigned int i;
724 unsigned long ent;
725 void __iomem *regs = fbi->io; 740 void __iomem *regs = fbi->io;
726 741
727 fbi->palette_ready = 0; 742 fbi->palette_ready = 0;
728 743
729 for (i = 0; i < 256; i++) { 744 for (i = 0; i < 256; i++) {
730 if ((ent = fbi->palette_buffer[i]) == PALETTE_BUFF_CLEAR) 745 unsigned long ent = fbi->palette_buffer[i];
746 if (ent == PALETTE_BUFF_CLEAR)
731 continue; 747 continue;
732 748
733 writel(ent, regs + S3C2410_TFTPAL(i)); 749 writel(ent, regs + S3C2410_TFTPAL(i));
@@ -761,13 +777,14 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
761 return IRQ_HANDLED; 777 return IRQ_HANDLED;
762} 778}
763 779
764static char driver_name[]="s3c2410fb"; 780static char driver_name[] = "s3c2410fb";
765 781
766static int __init s3c2410fb_probe(struct platform_device *pdev) 782static int __init s3c2410fb_probe(struct platform_device *pdev)
767{ 783{
768 struct s3c2410fb_info *info; 784 struct s3c2410fb_info *info;
769 struct fb_info *fbinfo; 785 struct s3c2410fb_display *display;
770 struct s3c2410fb_hw *mregs; 786 struct fb_info *fbinfo;
787 struct s3c2410fb_mach_info *mach_info;
771 struct resource *res; 788 struct resource *res;
772 int ret; 789 int ret;
773 int irq; 790 int irq;
@@ -777,11 +794,12 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
777 794
778 mach_info = pdev->dev.platform_data; 795 mach_info = pdev->dev.platform_data;
779 if (mach_info == NULL) { 796 if (mach_info == NULL) {
780 dev_err(&pdev->dev,"no platform data for lcd, cannot attach\n"); 797 dev_err(&pdev->dev,
798 "no platform data for lcd, cannot attach\n");
781 return -EINVAL; 799 return -EINVAL;
782 } 800 }
783 801
784 mregs = &mach_info->regs; 802 display = mach_info->displays + mach_info->default_display;
785 803
786 irq = platform_get_irq(pdev, 0); 804 irq = platform_get_irq(pdev, 0);
787 if (irq < 0) { 805 if (irq < 0) {
@@ -790,22 +808,22 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
790 } 808 }
791 809
792 fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev); 810 fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev);
793 if (!fbinfo) { 811 if (!fbinfo)
794 return -ENOMEM; 812 return -ENOMEM;
795 } 813
814 platform_set_drvdata(pdev, fbinfo);
796 815
797 info = fbinfo->par; 816 info = fbinfo->par;
798 info->fb = fbinfo;
799 info->dev = &pdev->dev; 817 info->dev = &pdev->dev;
800 818
801 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 819 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
802 if (res == NULL) { 820 if (res == NULL) {
803 dev_err(&pdev->dev, "failed to get memory registersn"); 821 dev_err(&pdev->dev, "failed to get memory registers\n");
804 ret = -ENXIO; 822 ret = -ENXIO;
805 goto dealloc_fb; 823 goto dealloc_fb;
806 } 824 }
807 825
808 size = (res->end - res->start)+1; 826 size = (res->end - res->start) + 1;
809 info->mem = request_mem_region(res->start, size, pdev->name); 827 info->mem = request_mem_region(res->start, size, pdev->name);
810 if (info->mem == NULL) { 828 if (info->mem == NULL) {
811 dev_err(&pdev->dev, "failed to get memory region\n"); 829 dev_err(&pdev->dev, "failed to get memory region\n");
@@ -820,21 +838,14 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
820 goto release_mem; 838 goto release_mem;
821 } 839 }
822 840
823 platform_set_drvdata(pdev, fbinfo);
824
825 dprintk("devinit\n"); 841 dprintk("devinit\n");
826 842
827 strcpy(fbinfo->fix.id, driver_name); 843 strcpy(fbinfo->fix.id, driver_name);
828 844
829 memcpy(&info->regs, &mach_info->regs, sizeof(info->regs)); 845 /* Stop the video */
830
831 /* Stop the video and unset ENVID if set */
832 info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
833 lcdcon1 = readl(info->io + S3C2410_LCDCON1); 846 lcdcon1 = readl(info->io + S3C2410_LCDCON1);
834 writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1); 847 writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1);
835 848
836 info->mach_info = pdev->dev.platform_data;
837
838 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; 849 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
839 fbinfo->fix.type_aux = 0; 850 fbinfo->fix.type_aux = 0;
840 fbinfo->fix.xpanstep = 0; 851 fbinfo->fix.xpanstep = 0;
@@ -844,8 +855,6 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
844 855
845 fbinfo->var.nonstd = 0; 856 fbinfo->var.nonstd = 0;
846 fbinfo->var.activate = FB_ACTIVATE_NOW; 857 fbinfo->var.activate = FB_ACTIVATE_NOW;
847 fbinfo->var.height = mach_info->height;
848 fbinfo->var.width = mach_info->width;
849 fbinfo->var.accel_flags = 0; 858 fbinfo->var.accel_flags = 0;
850 fbinfo->var.vmode = FB_VMODE_NONINTERLACED; 859 fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
851 860
@@ -853,32 +862,6 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
853 fbinfo->flags = FBINFO_FLAG_DEFAULT; 862 fbinfo->flags = FBINFO_FLAG_DEFAULT;
854 fbinfo->pseudo_palette = &info->pseudo_pal; 863 fbinfo->pseudo_palette = &info->pseudo_pal;
855 864
856 fbinfo->var.xres = mach_info->xres.defval;
857 fbinfo->var.xres_virtual = mach_info->xres.defval;
858 fbinfo->var.yres = mach_info->yres.defval;
859 fbinfo->var.yres_virtual = mach_info->yres.defval;
860 fbinfo->var.bits_per_pixel = mach_info->bpp.defval;
861
862 fbinfo->var.upper_margin = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1;
863 fbinfo->var.lower_margin = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) + 1;
864 fbinfo->var.vsync_len = S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1;
865
866 fbinfo->var.left_margin = S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1;
867 fbinfo->var.right_margin = S3C2410_LCDCON3_GET_HBPD(mregs->lcdcon3) + 1;
868 fbinfo->var.hsync_len = S3C2410_LCDCON4_GET_HSPW(mregs->lcdcon4) + 1;
869
870 fbinfo->var.red.offset = 11;
871 fbinfo->var.green.offset = 5;
872 fbinfo->var.blue.offset = 0;
873 fbinfo->var.transp.offset = 0;
874 fbinfo->var.red.length = 5;
875 fbinfo->var.green.length = 6;
876 fbinfo->var.blue.length = 5;
877 fbinfo->var.transp.length = 0;
878 fbinfo->fix.smem_len = mach_info->xres.max *
879 mach_info->yres.max *
880 mach_info->bpp.max / 8;
881
882 for (i = 0; i < 256; i++) 865 for (i = 0; i < 256; i++)
883 info->palette_buffer[i] = PALETTE_BUFF_CLEAR; 866 info->palette_buffer[i] = PALETTE_BUFF_CLEAR;
884 867
@@ -901,23 +884,39 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
901 884
902 msleep(1); 885 msleep(1);
903 886
887 /* find maximum required memory size for display */
888 for (i = 0; i < mach_info->num_displays; i++) {
889 unsigned long smem_len = mach_info->displays[i].xres;
890
891 smem_len *= mach_info->displays[i].yres;
892 smem_len *= mach_info->displays[i].bpp;
893 smem_len >>= 3;
894 if (fbinfo->fix.smem_len < smem_len)
895 fbinfo->fix.smem_len = smem_len;
896 }
897
904 /* Initialize video memory */ 898 /* Initialize video memory */
905 ret = s3c2410fb_map_video_memory(info); 899 ret = s3c2410fb_map_video_memory(fbinfo);
906 if (ret) { 900 if (ret) {
907 printk( KERN_ERR "Failed to allocate video RAM: %d\n", ret); 901 printk(KERN_ERR "Failed to allocate video RAM: %d\n", ret);
908 ret = -ENOMEM; 902 ret = -ENOMEM;
909 goto release_clock; 903 goto release_clock;
910 } 904 }
911 905
912 dprintk("got video memory\n"); 906 dprintk("got video memory\n");
913 907
914 ret = s3c2410fb_init_registers(info); 908 fbinfo->var.xres = display->xres;
909 fbinfo->var.yres = display->yres;
910 fbinfo->var.bits_per_pixel = display->bpp;
911
912 s3c2410fb_init_registers(fbinfo);
915 913
916 ret = s3c2410fb_check_var(&fbinfo->var, fbinfo); 914 s3c2410fb_check_var(&fbinfo->var, fbinfo);
917 915
918 ret = register_framebuffer(fbinfo); 916 ret = register_framebuffer(fbinfo);
919 if (ret < 0) { 917 if (ret < 0) {
920 printk(KERN_ERR "Failed to register framebuffer device: %d\n", ret); 918 printk(KERN_ERR "Failed to register framebuffer device: %d\n",
919 ret);
921 goto free_video_memory; 920 goto free_video_memory;
922 } 921 }
923 922
@@ -930,18 +929,19 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
930 return 0; 929 return 0;
931 930
932free_video_memory: 931free_video_memory:
933 s3c2410fb_unmap_video_memory(info); 932 s3c2410fb_unmap_video_memory(fbinfo);
934release_clock: 933release_clock:
935 clk_disable(info->clk); 934 clk_disable(info->clk);
936 clk_put(info->clk); 935 clk_put(info->clk);
937release_irq: 936release_irq:
938 free_irq(irq,info); 937 free_irq(irq, info);
939release_regs: 938release_regs:
940 iounmap(info->io); 939 iounmap(info->io);
941release_mem: 940release_mem:
942 release_resource(info->mem); 941 release_resource(info->mem);
943 kfree(info->mem); 942 kfree(info->mem);
944dealloc_fb: 943dealloc_fb:
944 platform_set_drvdata(pdev, NULL);
945 framebuffer_release(fbinfo); 945 framebuffer_release(fbinfo);
946 return ret; 946 return ret;
947} 947}
@@ -949,8 +949,7 @@ dealloc_fb:
949/* s3c2410fb_stop_lcd 949/* s3c2410fb_stop_lcd
950 * 950 *
951 * shutdown the lcd controller 951 * shutdown the lcd controller
952*/ 952 */
953
954static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi) 953static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi)
955{ 954{
956 unsigned long flags; 955 unsigned long flags;
@@ -968,28 +967,33 @@ static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi)
968 */ 967 */
969static int s3c2410fb_remove(struct platform_device *pdev) 968static int s3c2410fb_remove(struct platform_device *pdev)
970{ 969{
971 struct fb_info *fbinfo = platform_get_drvdata(pdev); 970 struct fb_info *fbinfo = platform_get_drvdata(pdev);
972 struct s3c2410fb_info *info = fbinfo->par; 971 struct s3c2410fb_info *info = fbinfo->par;
973 int irq; 972 int irq;
974 973
974 unregister_framebuffer(fbinfo);
975
975 s3c2410fb_stop_lcd(info); 976 s3c2410fb_stop_lcd(info);
976 msleep(1); 977 msleep(1);
977 978
978 s3c2410fb_unmap_video_memory(info); 979 s3c2410fb_unmap_video_memory(fbinfo);
979 980
980 if (info->clk) { 981 if (info->clk) {
981 clk_disable(info->clk); 982 clk_disable(info->clk);
982 clk_put(info->clk); 983 clk_put(info->clk);
983 info->clk = NULL; 984 info->clk = NULL;
984 } 985 }
985 986
986 irq = platform_get_irq(pdev, 0); 987 irq = platform_get_irq(pdev, 0);
987 free_irq(irq,info); 988 free_irq(irq, info);
989
990 iounmap(info->io);
988 991
989 release_resource(info->mem); 992 release_resource(info->mem);
990 kfree(info->mem); 993 kfree(info->mem);
991 iounmap(info->io); 994
992 unregister_framebuffer(fbinfo); 995 platform_set_drvdata(pdev, NULL);
996 framebuffer_release(fbinfo);
993 997
994 return 0; 998 return 0;
995} 999}
@@ -997,7 +1001,6 @@ static int s3c2410fb_remove(struct platform_device *pdev)
997#ifdef CONFIG_PM 1001#ifdef CONFIG_PM
998 1002
999/* suspend and resume support for the lcd controller */ 1003/* suspend and resume support for the lcd controller */
1000
1001static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) 1004static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
1002{ 1005{
1003 struct fb_info *fbinfo = platform_get_drvdata(dev); 1006 struct fb_info *fbinfo = platform_get_drvdata(dev);
@@ -1044,7 +1047,7 @@ static struct platform_driver s3c2410fb_driver = {
1044 }, 1047 },
1045}; 1048};
1046 1049
1047int __devinit s3c2410fb_init(void) 1050int __init s3c2410fb_init(void)
1048{ 1051{
1049 return platform_driver_register(&s3c2410fb_driver); 1052 return platform_driver_register(&s3c2410fb_driver);
1050} 1053}
@@ -1054,10 +1057,10 @@ static void __exit s3c2410fb_cleanup(void)
1054 platform_driver_unregister(&s3c2410fb_driver); 1057 platform_driver_unregister(&s3c2410fb_driver);
1055} 1058}
1056 1059
1057
1058module_init(s3c2410fb_init); 1060module_init(s3c2410fb_init);
1059module_exit(s3c2410fb_cleanup); 1061module_exit(s3c2410fb_cleanup);
1060 1062
1061MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, Ben Dooks <ben-linux@fluff.org>"); 1063MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, "
1064 "Ben Dooks <ben-linux@fluff.org>");
1062MODULE_DESCRIPTION("Framebuffer driver for the s3c2410"); 1065MODULE_DESCRIPTION("Framebuffer driver for the s3c2410");
1063MODULE_LICENSE("GPL"); 1066MODULE_LICENSE("GPL");
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h
index 17c7915b7acd..6ce5dc26c5f7 100644
--- a/drivers/video/s3c2410fb.h
+++ b/drivers/video/s3c2410fb.h
@@ -16,7 +16,7 @@
16 * 16 *
17 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org> 17 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
18 * - Renamed from h1940fb.h to s3c2410fb.h 18 * - Renamed from h1940fb.h to s3c2410fb.h
19 * - Chenged h1940 to s3c2410 19 * - Changed h1940 to s3c2410
20 * 20 *
21 * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org> 21 * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
22 * - First version 22 * - First version
@@ -26,25 +26,14 @@
26#define __S3C2410FB_H 26#define __S3C2410FB_H
27 27
28struct s3c2410fb_info { 28struct s3c2410fb_info {
29 struct fb_info *fb;
30 struct device *dev; 29 struct device *dev;
31 struct clk *clk; 30 struct clk *clk;
32 31
33 struct resource *mem; 32 struct resource *mem;
34 void __iomem *io; 33 void __iomem *io;
35 34
36 struct s3c2410fb_mach_info *mach_info;
37
38 /* raw memory addresses */
39 dma_addr_t map_dma; /* physical */
40 u_char * map_cpu; /* virtual */
41 u_int map_size;
42
43 struct s3c2410fb_hw regs; 35 struct s3c2410fb_hw regs;
44 36
45 /* addresses of pieces placed in raw buffer */
46 u_char * screen_cpu; /* virtual address of buffer */
47 dma_addr_t screen_dma; /* physical address of buffer */
48 unsigned int palette_ready; 37 unsigned int palette_ready;
49 38
50 /* keep these registers in case we need to re-write palette */ 39 /* keep these registers in case we need to re-write palette */
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index d11735895a01..7d53bc23b9c7 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -400,11 +400,17 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
400{ 400{
401 struct s3fb_info *par = info->par; 401 struct s3fb_info *par = info->par;
402 int rv, mem, step; 402 int rv, mem, step;
403 u16 m, n, r;
403 404
404 /* Find appropriate format */ 405 /* Find appropriate format */
405 rv = svga_match_format (s3fb_formats, var, NULL); 406 rv = svga_match_format (s3fb_formats, var, NULL);
406 if ((rv < 0) || ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 7) : (rv == 6))) 407
407 { /* 24bpp on VIRGE VX, 32bpp on others */ 408 /* 32bpp mode is not supported on VIRGE VX,
409 24bpp is not supported on others */
410 if ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 7) : (rv == 6))
411 rv = -EINVAL;
412
413 if (rv < 0) {
408 printk(KERN_ERR "fb%d: unsupported mode requested\n", info->node); 414 printk(KERN_ERR "fb%d: unsupported mode requested\n", info->node);
409 return rv; 415 return rv;
410 } 416 }
@@ -422,20 +428,26 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
422 428
423 /* Check whether have enough memory */ 429 /* Check whether have enough memory */
424 mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual; 430 mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual;
425 if (mem > info->screen_size) 431 if (mem > info->screen_size) {
426 {
427 printk(KERN_ERR "fb%d: not enough framebuffer memory (%d kB requested , %d kB available)\n", 432 printk(KERN_ERR "fb%d: not enough framebuffer memory (%d kB requested , %d kB available)\n",
428 info->node, mem >> 10, (unsigned int) (info->screen_size >> 10)); 433 info->node, mem >> 10, (unsigned int) (info->screen_size >> 10));
429 return -EINVAL; 434 return -EINVAL;
430 } 435 }
431 436
432 rv = svga_check_timings (&s3_timing_regs, var, info->node); 437 rv = svga_check_timings (&s3_timing_regs, var, info->node);
433 if (rv < 0) 438 if (rv < 0) {
434 {
435 printk(KERN_ERR "fb%d: invalid timings requested\n", info->node); 439 printk(KERN_ERR "fb%d: invalid timings requested\n", info->node);
436 return rv; 440 return rv;
437 } 441 }
438 442
443 rv = svga_compute_pll(&s3_pll, PICOS2KHZ(var->pixclock), &m, &n, &r,
444 info->node);
445 if (rv < 0) {
446 printk(KERN_ERR "fb%d: invalid pixclock value requested\n",
447 info->node);
448 return rv;
449 }
450
439 return 0; 451 return 0;
440} 452}
441 453
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 5d2a4a4b731c..ab2b2110478b 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -178,7 +178,6 @@
178#include <asm/hardware.h> 178#include <asm/hardware.h>
179#include <asm/io.h> 179#include <asm/io.h>
180#include <asm/mach-types.h> 180#include <asm/mach-types.h>
181#include <asm/uaccess.h>
182#include <asm/arch/assabet.h> 181#include <asm/arch/assabet.h>
183#include <asm/arch/shannon.h> 182#include <asm/arch/shannon.h>
184 183
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index b855f4a34afe..37b135d5d12e 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -57,7 +57,6 @@
57#include <asm/irq.h> 57#include <asm/irq.h>
58#include <asm/pgtable.h> 58#include <asm/pgtable.h>
59#include <asm/system.h> 59#include <asm/system.h>
60#include <asm/uaccess.h>
61 60
62#ifdef CONFIG_MTRR 61#ifdef CONFIG_MTRR
63#include <asm/mtrr.h> 62#include <asm/mtrr.h>
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index e8ccace01252..bc7d23683735 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -58,7 +58,7 @@
58#include <linux/capability.h> 58#include <linux/capability.h>
59#include <linux/fs.h> 59#include <linux/fs.h>
60#include <linux/types.h> 60#include <linux/types.h>
61#include <asm/uaccess.h> 61#include <linux/uaccess.h>
62#include <asm/io.h> 62#include <asm/io.h>
63#ifdef CONFIG_MTRR 63#ifdef CONFIG_MTRR
64#include <asm/mtrr.h> 64#include <asm/mtrr.h>
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 64779e70408f..62321458f71a 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -780,7 +780,7 @@ static int __devinit xxxfb_probe(struct pci_dev *dev,
780 * 780 *
781 * NOTE: This field is currently unused. 781 * NOTE: This field is currently unused.
782 */ 782 */
783 info->pixmap.scan_align = 32; 783 info->pixmap.access_align = 32;
784/***************************** End optional stage ***************************/ 784/***************************** End optional stage ***************************/
785 785
786 /* 786 /*
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index c86df126f93a..1be95a68d696 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -28,6 +28,7 @@
28#include <linux/wait.h> 28#include <linux/wait.h>
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30#include <linux/clk.h> 30#include <linux/clk.h>
31#include <linux/console.h>
31 32
32#include <asm/io.h> 33#include <asm/io.h>
33#include <asm/uaccess.h> 34#include <asm/uaccess.h>
@@ -62,6 +63,8 @@ struct sm501fb_info {
62 struct resource *regs_res; /* registers resource */ 63 struct resource *regs_res; /* registers resource */
63 struct sm501_platdata_fb *pdata; /* our platform data */ 64 struct sm501_platdata_fb *pdata; /* our platform data */
64 65
66 unsigned long pm_crt_ctrl; /* pm: crt ctrl save */
67
65 int irq; 68 int irq;
66 int swap_endian; /* set to swap rgb=>bgr */ 69 int swap_endian; /* set to swap rgb=>bgr */
67 void __iomem *regs; /* remapped registers */ 70 void __iomem *regs; /* remapped registers */
@@ -774,6 +777,11 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
774 writel(control, fbi->regs + SM501_DC_PANEL_CONTROL); 777 writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
775 sm501fb_sync_regs(fbi); 778 sm501fb_sync_regs(fbi);
776 779
780 /* ensure the panel interface is not tristated at this point */
781
782 sm501_modify_reg(fbi->dev->parent, SM501_SYSTEM_CONTROL,
783 0, SM501_SYSCTRL_PANEL_TRISTATE);
784
777 /* power the panel up */ 785 /* power the panel up */
778 sm501fb_panel_power(fbi, 1); 786 sm501fb_panel_power(fbi, 1);
779 return 0; 787 return 0;
@@ -1687,19 +1695,25 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info,
1687 goto err_nocursor; 1695 goto err_nocursor;
1688 } 1696 }
1689 1697
1698 dev_dbg(info->dev, "suspending screen to %p\n", par->store_fb);
1699 dev_dbg(info->dev, "suspending cursor to %p\n", par->store_cursor);
1700
1690 memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size); 1701 memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size);
1691 memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size); 1702 memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size);
1692
1693 /* blank the relevant interface to ensure unit power minimised */ 1703 /* blank the relevant interface to ensure unit power minimised */
1694 (par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi); 1704 (par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi);
1695 1705
1706 acquire_console_sem();
1707 fb_set_suspend(fbi, 1);
1708 release_console_sem();
1709
1696 return 0; 1710 return 0;
1697 1711
1698 err_nocursor: 1712 err_nocursor:
1699 vfree(par->store_fb); 1713 vfree(par->store_fb);
1714 par->store_fb = NULL;
1700 1715
1701 return -ENOMEM; 1716 return -ENOMEM;
1702
1703} 1717}
1704 1718
1705static void sm501fb_resume_fb(struct sm501fb_info *info, 1719static void sm501fb_resume_fb(struct sm501fb_info *info,
@@ -1717,8 +1731,20 @@ static void sm501fb_resume_fb(struct sm501fb_info *info,
1717 1731
1718 /* restore the data */ 1732 /* restore the data */
1719 1733
1720 memcpy_toio(par->screen.k_addr, par->store_fb, par->screen.size); 1734 dev_dbg(info->dev, "restoring screen from %p\n", par->store_fb);
1721 memcpy_toio(par->cursor.k_addr, par->store_cursor, par->cursor.size); 1735 dev_dbg(info->dev, "restoring cursor from %p\n", par->store_cursor);
1736
1737 if (par->store_fb)
1738 memcpy_toio(par->screen.k_addr, par->store_fb,
1739 par->screen.size);
1740
1741 if (par->store_cursor)
1742 memcpy_toio(par->cursor.k_addr, par->store_cursor,
1743 par->cursor.size);
1744
1745 acquire_console_sem();
1746 fb_set_suspend(fbi, 0);
1747 release_console_sem();
1722 1748
1723 vfree(par->store_fb); 1749 vfree(par->store_fb);
1724 vfree(par->store_cursor); 1750 vfree(par->store_cursor);
@@ -1731,6 +1757,9 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
1731{ 1757{
1732 struct sm501fb_info *info = platform_get_drvdata(pdev); 1758 struct sm501fb_info *info = platform_get_drvdata(pdev);
1733 1759
1760 /* store crt control to resume with */
1761 info->pm_crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
1762
1734 sm501fb_suspend_fb(info, HEAD_CRT); 1763 sm501fb_suspend_fb(info, HEAD_CRT);
1735 sm501fb_suspend_fb(info, HEAD_PANEL); 1764 sm501fb_suspend_fb(info, HEAD_PANEL);
1736 1765
@@ -1740,12 +1769,24 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
1740 return 0; 1769 return 0;
1741} 1770}
1742 1771
1772#define SM501_CRT_CTRL_SAVE (SM501_DC_CRT_CONTROL_TVP | \
1773 SM501_DC_CRT_CONTROL_SEL)
1774
1775
1743static int sm501fb_resume(struct platform_device *pdev) 1776static int sm501fb_resume(struct platform_device *pdev)
1744{ 1777{
1745 struct sm501fb_info *info = platform_get_drvdata(pdev); 1778 struct sm501fb_info *info = platform_get_drvdata(pdev);
1779 unsigned long crt_ctrl;
1746 1780
1747 sm501_unit_power(info->dev->parent, SM501_GATE_DISPLAY, 1); 1781 sm501_unit_power(info->dev->parent, SM501_GATE_DISPLAY, 1);
1748 1782
1783 /* restore the items we want to be saved for crt control */
1784
1785 crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
1786 crt_ctrl &= ~SM501_CRT_CTRL_SAVE;
1787 crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE;
1788 writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
1789
1749 sm501fb_resume_fb(info, HEAD_CRT); 1790 sm501fb_resume_fb(info, HEAD_CRT);
1750 sm501fb_resume_fb(info, HEAD_PANEL); 1791 sm501fb_resume_fb(info, HEAD_PANEL);
1751 1792
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 5eff28ce4f4d..97784f9c184d 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -88,7 +88,7 @@
88#include <linux/init.h> 88#include <linux/init.h>
89#include <linux/slab.h> 89#include <linux/slab.h>
90#include <asm/io.h> 90#include <asm/io.h>
91#include <asm/uaccess.h> 91#include <linux/uaccess.h>
92#include <video/sstfb.h> 92#include <video/sstfb.h>
93 93
94 94
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index 25df928d37d8..9c7106701572 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -598,9 +598,11 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
598/* ------------------------------------------------------------------------- */ 598/* ------------------------------------------------------------------------- */
599 599
600 600
601int svga_match_format(const struct svga_fb_format *frm, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix) 601static inline int match_format(const struct svga_fb_format *frm,
602 struct fb_var_screeninfo *var)
602{ 603{
603 int i = 0; 604 int i = 0;
605 int stored = -EINVAL;
604 606
605 while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL) 607 while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL)
606 { 608 {
@@ -609,25 +611,38 @@ int svga_match_format(const struct svga_fb_format *frm, struct fb_var_screeninfo
609 (var->green.length <= frm->green.length) && 611 (var->green.length <= frm->green.length) &&
610 (var->blue.length <= frm->blue.length) && 612 (var->blue.length <= frm->blue.length) &&
611 (var->transp.length <= frm->transp.length) && 613 (var->transp.length <= frm->transp.length) &&
612 (var->nonstd == frm->nonstd)) { 614 (var->nonstd == frm->nonstd))
613 var->bits_per_pixel = frm->bits_per_pixel;
614 var->red = frm->red;
615 var->green = frm->green;
616 var->blue = frm->blue;
617 var->transp = frm->transp;
618 var->nonstd = frm->nonstd;
619 if (fix != NULL) {
620 fix->type = frm->type;
621 fix->type_aux = frm->type_aux;
622 fix->visual = frm->visual;
623 fix->xpanstep = frm->xpanstep;
624 }
625 return i; 615 return i;
626 } 616 if (var->bits_per_pixel == frm->bits_per_pixel)
617 stored = i;
627 i++; 618 i++;
628 frm++; 619 frm++;
629 } 620 }
630 return -EINVAL; 621 return stored;
622}
623
624int svga_match_format(const struct svga_fb_format *frm,
625 struct fb_var_screeninfo *var,
626 struct fb_fix_screeninfo *fix)
627{
628 int i = match_format(frm, var);
629
630 if (i >= 0) {
631 var->bits_per_pixel = frm[i].bits_per_pixel;
632 var->red = frm[i].red;
633 var->green = frm[i].green;
634 var->blue = frm[i].blue;
635 var->transp = frm[i].transp;
636 var->nonstd = frm[i].nonstd;
637 if (fix != NULL) {
638 fix->type = frm[i].type;
639 fix->type_aux = frm[i].type_aux;
640 fix->visual = frm[i].visual;
641 fix->xpanstep = frm[i].xpanstep;
642 }
643 }
644
645 return i;
631} 646}
632 647
633 648
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 689ce0270b81..057bdd593800 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -4,13 +4,13 @@
4 * 4 *
5 * Author: Hannu Mallat <hmallat@cc.hut.fi> 5 * Author: Hannu Mallat <hmallat@cc.hut.fi>
6 * 6 *
7 * Copyright © 1999 Hannu Mallat 7 * Copyright © 1999 Hannu Mallat
8 * All rights reserved 8 * All rights reserved
9 * 9 *
10 * Created : Thu Sep 23 18:17:43 1999, hmallat 10 * Created : Thu Sep 23 18:17:43 1999, hmallat
11 * Last modified: Tue Nov 2 21:19:47 1999, hmallat 11 * Last modified: Tue Nov 2 21:19:47 1999, hmallat
12 * 12 *
13 * Lots of the information here comes from the Daryll Strauss' Banshee 13 * Lots of the information here comes from the Daryll Strauss' Banshee
14 * patches to the XF86 server, and the rest comes from the 3dfx 14 * patches to the XF86 server, and the rest comes from the 3dfx
15 * Banshee specification. I'm very much indebted to Daryll for his 15 * Banshee specification. I'm very much indebted to Daryll for his
16 * work on the X server. 16 * work on the X server.
@@ -23,7 +23,7 @@
23 * behave very differently from the Voodoo3/4/5. For anyone wanting to 23 * behave very differently from the Voodoo3/4/5. For anyone wanting to
24 * use frame buffer on the Voodoo1/2, see the sstfb driver (which is 24 * use frame buffer on the Voodoo1/2, see the sstfb driver (which is
25 * located at http://www.sourceforge.net/projects/sstfb). 25 * located at http://www.sourceforge.net/projects/sstfb).
26 * 26 *
27 * While I _am_ grateful to 3Dfx for releasing the specs for Banshee, 27 * While I _am_ grateful to 3Dfx for releasing the specs for Banshee,
28 * I do wish the next version is a bit more complete. Without the XF86 28 * I do wish the next version is a bit more complete. Without the XF86
29 * patches I couldn't have gotten even this far... for instance, the 29 * patches I couldn't have gotten even this far... for instance, the
@@ -33,9 +33,8 @@
33 * 33 *
34 * The structure of this driver comes pretty much from the Permedia 34 * The structure of this driver comes pretty much from the Permedia
35 * driver by Ilario Nardinocchi, which in turn is based on skeletonfb. 35 * driver by Ilario Nardinocchi, which in turn is based on skeletonfb.
36 * 36 *
37 * TODO: 37 * TODO:
38 * - support for 16/32 bpp needs fixing (funky bootup penguin)
39 * - multihead support (basically need to support an array of fb_infos) 38 * - multihead support (basically need to support an array of fb_infos)
40 * - support other architectures (PPC, Alpha); does the fact that the VGA 39 * - support other architectures (PPC, Alpha); does the fact that the VGA
41 * core can be accessed only thru I/O (not memory mapped) complicate 40 * core can be accessed only thru I/O (not memory mapped) complicate
@@ -43,18 +42,18 @@
43 * 42 *
44 * Version history: 43 * Version history:
45 * 44 *
46 * 0.1.4 (released 2002-05-28) ported over to new fbdev api by James Simmons 45 * 0.1.4 (released 2002-05-28) ported over to new fbdev api by James Simmons
47 * 46 *
48 * 0.1.3 (released 1999-11-02) added Attila's panning support, code 47 * 0.1.3 (released 1999-11-02) added Attila's panning support, code
49 * reorg, hwcursor address page size alignment 48 * reorg, hwcursor address page size alignment
50 * (for mmaping both frame buffer and regs), 49 * (for mmaping both frame buffer and regs),
51 * and my changes to get rid of hardcoded 50 * and my changes to get rid of hardcoded
52 * VGA i/o register locations (uses PCI 51 * VGA i/o register locations (uses PCI
53 * configuration info now) 52 * configuration info now)
54 * 0.1.2 (released 1999-10-19) added Attila Kesmarki's bug fixes and 53 * 0.1.2 (released 1999-10-19) added Attila Kesmarki's bug fixes and
55 * improvements 54 * improvements
56 * 0.1.1 (released 1999-10-07) added Voodoo3 support by Harold Oga. 55 * 0.1.1 (released 1999-10-07) added Voodoo3 support by Harold Oga.
57 * 0.1.0 (released 1999-10-06) initial version 56 * 0.1.0 (released 1999-10-06) initial version
58 * 57 *
59 */ 58 */
60 59
@@ -64,24 +63,32 @@
64#include <linux/string.h> 63#include <linux/string.h>
65#include <linux/mm.h> 64#include <linux/mm.h>
66#include <linux/slab.h> 65#include <linux/slab.h>
67#include <linux/delay.h>
68#include <linux/interrupt.h>
69#include <linux/fb.h> 66#include <linux/fb.h>
70#include <linux/init.h> 67#include <linux/init.h>
71#include <linux/pci.h> 68#include <linux/pci.h>
72#include <linux/nvram.h>
73#include <asm/io.h> 69#include <asm/io.h>
74#include <linux/timer.h>
75#include <linux/spinlock.h>
76 70
77#include <video/tdfx.h> 71#include <video/tdfx.h>
78 72
79#undef TDFXFB_DEBUG 73#define DPRINTK(a, b...) pr_debug("fb: %s: " a, __FUNCTION__ , ## b)
80#ifdef TDFXFB_DEBUG 74
81#define DPRINTK(a,b...) printk(KERN_DEBUG "fb: %s: " a, __FUNCTION__ , ## b) 75#ifdef CONFIG_MTRR
76#include <asm/mtrr.h>
82#else 77#else
83#define DPRINTK(a,b...) 78/* duplicate asm/mtrr.h defines to work on archs without mtrr */
84#endif 79#define MTRR_TYPE_WRCOMB 1
80
81static inline int mtrr_add(unsigned long base, unsigned long size,
82 unsigned int type, char increment)
83{
84 return -ENODEV;
85}
86static inline int mtrr_del(int reg, unsigned long base,
87 unsigned long size)
88{
89 return -ENODEV;
90}
91#endif
85 92
86#define BANSHEE_MAX_PIXCLOCK 270000 93#define BANSHEE_MAX_PIXCLOCK 270000
87#define VOODOO3_MAX_PIXCLOCK 300000 94#define VOODOO3_MAX_PIXCLOCK 300000
@@ -90,9 +97,9 @@
90static struct fb_fix_screeninfo tdfx_fix __devinitdata = { 97static struct fb_fix_screeninfo tdfx_fix __devinitdata = {
91 .id = "3Dfx", 98 .id = "3Dfx",
92 .type = FB_TYPE_PACKED_PIXELS, 99 .type = FB_TYPE_PACKED_PIXELS,
93 .visual = FB_VISUAL_PSEUDOCOLOR, 100 .visual = FB_VISUAL_PSEUDOCOLOR,
94 .ypanstep = 1, 101 .ypanstep = 1,
95 .ywrapstep = 1, 102 .ywrapstep = 1,
96 .accel = FB_ACCEL_3DFX_BANSHEE 103 .accel = FB_ACCEL_3DFX_BANSHEE
97}; 104};
98 105
@@ -102,7 +109,7 @@ static struct fb_var_screeninfo tdfx_var __devinitdata = {
102 .yres = 480, 109 .yres = 480,
103 .xres_virtual = 640, 110 .xres_virtual = 640,
104 .yres_virtual = 1024, 111 .yres_virtual = 1024,
105 .bits_per_pixel =8, 112 .bits_per_pixel = 8,
106 .red = {0, 8, 0}, 113 .red = {0, 8, 0},
107 .blue = {0, 8, 0}, 114 .blue = {0, 8, 0},
108 .green = {0, 8, 0}, 115 .green = {0, 8, 0},
@@ -142,103 +149,79 @@ static struct pci_device_id tdfxfb_id_table[] = {
142 149
143static struct pci_driver tdfxfb_driver = { 150static struct pci_driver tdfxfb_driver = {
144 .name = "tdfxfb", 151 .name = "tdfxfb",
145 .id_table = tdfxfb_id_table, 152 .id_table = tdfxfb_id_table,
146 .probe = tdfxfb_probe, 153 .probe = tdfxfb_probe,
147 .remove = __devexit_p(tdfxfb_remove), 154 .remove = __devexit_p(tdfxfb_remove),
148}; 155};
149 156
150MODULE_DEVICE_TABLE(pci, tdfxfb_id_table); 157MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
151 158
152/* 159/*
153 * Frame buffer device API 160 * Driver data
154 */ 161 */
155static int tdfxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb); 162static int nopan;
156static int tdfxfb_set_par(struct fb_info *info); 163static int nowrap = 1; /* not implemented (yet) */
157static int tdfxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 164static int hwcursor = 1;
158 u_int transp, struct fb_info *info); 165static char *mode_option __devinitdata;
159static int tdfxfb_blank(int blank, struct fb_info *info); 166/* mtrr option */
160static int tdfxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); 167static int nomtrr __devinitdata;
161static int banshee_wait_idle(struct fb_info *info); 168
162#ifdef CONFIG_FB_3DFX_ACCEL 169/* -------------------------------------------------------------------------
163static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); 170 * Hardware-specific funcions
164static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
165static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image);
166#endif /* CONFIG_FB_3DFX_ACCEL */
167
168static struct fb_ops tdfxfb_ops = {
169 .owner = THIS_MODULE,
170 .fb_check_var = tdfxfb_check_var,
171 .fb_set_par = tdfxfb_set_par,
172 .fb_setcolreg = tdfxfb_setcolreg,
173 .fb_blank = tdfxfb_blank,
174 .fb_pan_display = tdfxfb_pan_display,
175 .fb_sync = banshee_wait_idle,
176#ifdef CONFIG_FB_3DFX_ACCEL
177 .fb_fillrect = tdfxfb_fillrect,
178 .fb_copyarea = tdfxfb_copyarea,
179 .fb_imageblit = tdfxfb_imageblit,
180#else
181 .fb_fillrect = cfb_fillrect,
182 .fb_copyarea = cfb_copyarea,
183 .fb_imageblit = cfb_imageblit,
184#endif
185};
186
187/*
188 * do_xxx: Hardware-specific functions
189 */
190static u32 do_calc_pll(int freq, int *freq_out);
191static void do_write_regs(struct fb_info *info, struct banshee_reg *reg);
192static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short);
193
194/*
195 * Driver data
196 */
197static int nopan = 0;
198static int nowrap = 1; // not implemented (yet)
199static char *mode_option __devinitdata = NULL;
200
201/* -------------------------------------------------------------------------
202 * Hardware-specific funcions
203 * ------------------------------------------------------------------------- */ 171 * ------------------------------------------------------------------------- */
204 172
205#ifdef VGA_REG_IO 173static inline u8 vga_inb(struct tdfx_par *par, u32 reg)
206static inline u8 vga_inb(struct tdfx_par *par, u32 reg) { return inb(reg); } 174{
207 175 return inb(par->iobase + reg - 0x300);
208static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val) { outb(val, reg); }
209#else
210static inline u8 vga_inb(struct tdfx_par *par, u32 reg) {
211 return inb(par->iobase + reg - 0x300);
212} 176}
213static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val) { 177
214 outb(val, par->iobase + reg - 0x300); 178static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val)
179{
180 outb(val, par->iobase + reg - 0x300);
215} 181}
216#endif
217 182
218static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val) { 183static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val)
219 vga_outb(par, GRA_I, idx); vga_outb(par, GRA_D, val); 184{
185 vga_outb(par, GRA_I, idx);
186 wmb();
187 vga_outb(par, GRA_D, val);
188 wmb();
220} 189}
221 190
222static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val) { 191static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val)
223 vga_outb(par, SEQ_I, idx); vga_outb(par, SEQ_D, val); 192{
193 vga_outb(par, SEQ_I, idx);
194 wmb();
195 vga_outb(par, SEQ_D, val);
196 wmb();
224} 197}
225 198
226static inline u8 seq_inb(struct tdfx_par *par, u32 idx) { 199static inline u8 seq_inb(struct tdfx_par *par, u32 idx)
227 vga_outb(par, SEQ_I, idx); return vga_inb(par, SEQ_D); 200{
201 vga_outb(par, SEQ_I, idx);
202 mb();
203 return vga_inb(par, SEQ_D);
228} 204}
229 205
230static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val) { 206static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val)
231 vga_outb(par, CRT_I, idx); vga_outb(par, CRT_D, val); 207{
208 vga_outb(par, CRT_I, idx);
209 wmb();
210 vga_outb(par, CRT_D, val);
211 wmb();
232} 212}
233 213
234static inline u8 crt_inb(struct tdfx_par *par, u32 idx) { 214static inline u8 crt_inb(struct tdfx_par *par, u32 idx)
235 vga_outb(par, CRT_I, idx); return vga_inb(par, CRT_D); 215{
216 vga_outb(par, CRT_I, idx);
217 mb();
218 return vga_inb(par, CRT_D);
236} 219}
237 220
238static inline void att_outb(struct tdfx_par *par, u32 idx, u8 val) 221static inline void att_outb(struct tdfx_par *par, u32 idx, u8 val)
239{ 222{
240 unsigned char tmp; 223 unsigned char tmp;
241 224
242 tmp = vga_inb(par, IS1_R); 225 tmp = vga_inb(par, IS1_R);
243 vga_outb(par, ATT_IW, idx); 226 vga_outb(par, ATT_IW, idx);
244 vga_outb(par, ATT_IW, val); 227 vga_outb(par, ATT_IW, val);
@@ -267,10 +250,11 @@ static inline void vga_enable_video(struct tdfx_par *par)
267static inline void vga_enable_palette(struct tdfx_par *par) 250static inline void vga_enable_palette(struct tdfx_par *par)
268{ 251{
269 vga_inb(par, IS1_R); 252 vga_inb(par, IS1_R);
253 mb();
270 vga_outb(par, ATT_IW, 0x20); 254 vga_outb(par, ATT_IW, 0x20);
271} 255}
272 256
273static inline u32 tdfx_inl(struct tdfx_par *par, unsigned int reg) 257static inline u32 tdfx_inl(struct tdfx_par *par, unsigned int reg)
274{ 258{
275 return readl(par->regbase_virt + reg); 259 return readl(par->regbase_virt + reg);
276} 260}
@@ -284,9 +268,10 @@ static inline void banshee_make_room(struct tdfx_par *par, int size)
284{ 268{
285 /* Note: The Voodoo3's onboard FIFO has 32 slots. This loop 269 /* Note: The Voodoo3's onboard FIFO has 32 slots. This loop
286 * won't quit if you ask for more. */ 270 * won't quit if you ask for more. */
287 while((tdfx_inl(par, STATUS) & 0x1f) < size-1); 271 while ((tdfx_inl(par, STATUS) & 0x1f) < size - 1)
272 cpu_relax();
288} 273}
289 274
290static int banshee_wait_idle(struct fb_info *info) 275static int banshee_wait_idle(struct fb_info *info)
291{ 276{
292 struct tdfx_par *par = info->par; 277 struct tdfx_par *par = info->par;
@@ -295,28 +280,31 @@ static int banshee_wait_idle(struct fb_info *info)
295 banshee_make_room(par, 1); 280 banshee_make_room(par, 1);
296 tdfx_outl(par, COMMAND_3D, COMMAND_3D_NOP); 281 tdfx_outl(par, COMMAND_3D, COMMAND_3D_NOP);
297 282
298 while(1) { 283 do {
299 i = (tdfx_inl(par, STATUS) & STATUS_BUSY) ? 0 : i + 1; 284 if ((tdfx_inl(par, STATUS) & STATUS_BUSY) == 0)
300 if(i == 3) break; 285 i++;
301 } 286 } while (i < 3);
287
302 return 0; 288 return 0;
303} 289}
304 290
305/* 291/*
306 * Set the color of a palette entry in 8bpp mode 292 * Set the color of a palette entry in 8bpp mode
307 */ 293 */
308static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c) 294static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c)
309{ 295{
310 banshee_make_room(par, 2); 296 banshee_make_room(par, 2);
311 tdfx_outl(par, DACADDR, regno); 297 tdfx_outl(par, DACADDR, regno);
298 /* read after write makes it working */
299 tdfx_inl(par, DACADDR);
312 tdfx_outl(par, DACDATA, c); 300 tdfx_outl(par, DACDATA, c);
313} 301}
314 302
315static u32 do_calc_pll(int freq, int* freq_out) 303static u32 do_calc_pll(int freq, int *freq_out)
316{ 304{
317 int m, n, k, best_m, best_n, best_k, best_error; 305 int m, n, k, best_m, best_n, best_k, best_error;
318 int fref = 14318; 306 int fref = 14318;
319 307
320 best_error = freq; 308 best_error = freq;
321 best_n = best_m = best_k = 0; 309 best_n = best_m = best_k = 0;
322 310
@@ -326,27 +314,28 @@ static u32 do_calc_pll(int freq, int* freq_out)
326 * Estimate value of n that produces target frequency 314 * Estimate value of n that produces target frequency
327 * with current m and k 315 * with current m and k
328 */ 316 */
329 int n_estimated = (freq * (m + 2) * (1 << k) / fref) - 2; 317 int n_estimated = ((freq * (m + 2) << k) / fref) - 2;
330 318
331 /* Search neighborhood of estimated n */ 319 /* Search neighborhood of estimated n */
332 for (n = max(0, n_estimated - 1); 320 for (n = max(0, n_estimated);
333 n <= min(255, n_estimated + 1); n++) { 321 n <= min(255, n_estimated + 1);
322 n++) {
334 /* 323 /*
335 * Calculate PLL freqency with current m, k and 324 * Calculate PLL freqency with current m, k and
336 * estimated n 325 * estimated n
337 */ 326 */
338 int f = fref * (n + 2) / (m + 2) / (1 << k); 327 int f = (fref * (n + 2) / (m + 2)) >> k;
339 int error = abs (f - freq); 328 int error = abs(f - freq);
340 329
341 /* 330 /*
342 * If this is the closest we've come to the 331 * If this is the closest we've come to the
343 * target frequency then remember n, m and k 332 * target frequency then remember n, m and k
344 */ 333 */
345 if (error < best_error) { 334 if (error < best_error) {
346 best_error = error; 335 best_error = error;
347 best_n = n; 336 best_n = n;
348 best_m = m; 337 best_m = m;
349 best_k = k; 338 best_k = k;
350 } 339 }
351 } 340 }
352 } 341 }
@@ -355,12 +344,12 @@ static u32 do_calc_pll(int freq, int* freq_out)
355 n = best_n; 344 n = best_n;
356 m = best_m; 345 m = best_m;
357 k = best_k; 346 k = best_k;
358 *freq_out = fref*(n + 2)/(m + 2)/(1 << k); 347 *freq_out = (fref * (n + 2) / (m + 2)) >> k;
359 348
360 return (n << 8) | (m << 2) | k; 349 return (n << 8) | (m << 2) | k;
361} 350}
362 351
363static void do_write_regs(struct fb_info *info, struct banshee_reg* reg) 352static void do_write_regs(struct fb_info *info, struct banshee_reg *reg)
364{ 353{
365 struct tdfx_par *par = info->par; 354 struct tdfx_par *par = info->par;
366 int i; 355 int i;
@@ -372,13 +361,13 @@ static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
372 crt_outb(par, 0x11, crt_inb(par, 0x11) & 0x7f); /* CRT unprotect */ 361 crt_outb(par, 0x11, crt_inb(par, 0x11) & 0x7f); /* CRT unprotect */
373 362
374 banshee_make_room(par, 3); 363 banshee_make_room(par, 3);
375 tdfx_outl(par, VGAINIT1, reg->vgainit1 & 0x001FFFFF); 364 tdfx_outl(par, VGAINIT1, reg->vgainit1 & 0x001FFFFF);
376 tdfx_outl(par, VIDPROCCFG, reg->vidcfg & ~0x00000001); 365 tdfx_outl(par, VIDPROCCFG, reg->vidcfg & ~0x00000001);
377#if 0 366#if 0
378 tdfx_outl(par, PLLCTRL1, reg->mempll); 367 tdfx_outl(par, PLLCTRL1, reg->mempll);
379 tdfx_outl(par, PLLCTRL2, reg->gfxpll); 368 tdfx_outl(par, PLLCTRL2, reg->gfxpll);
380#endif 369#endif
381 tdfx_outl(par, PLLCTRL0, reg->vidpll); 370 tdfx_outl(par, PLLCTRL0, reg->vidpll);
382 371
383 vga_outb(par, MISC_W, reg->misc[0x00] | 0x01); 372 vga_outb(par, MISC_W, reg->misc[0x00] | 0x01);
384 373
@@ -400,72 +389,65 @@ static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
400 vga_enable_palette(par); 389 vga_enable_palette(par);
401 vga_enable_video(par); 390 vga_enable_video(par);
402 391
403 banshee_make_room(par, 11); 392 banshee_make_room(par, 9);
404 tdfx_outl(par, VGAINIT0, reg->vgainit0); 393 tdfx_outl(par, VGAINIT0, reg->vgainit0);
405 tdfx_outl(par, DACMODE, reg->dacmode); 394 tdfx_outl(par, DACMODE, reg->dacmode);
406 tdfx_outl(par, VIDDESKSTRIDE, reg->stride); 395 tdfx_outl(par, VIDDESKSTRIDE, reg->stride);
407 tdfx_outl(par, HWCURPATADDR, 0); 396 tdfx_outl(par, HWCURPATADDR, reg->curspataddr);
408 397
409 tdfx_outl(par, VIDSCREENSIZE,reg->screensize); 398 tdfx_outl(par, VIDSCREENSIZE, reg->screensize);
410 tdfx_outl(par, VIDDESKSTART, reg->startaddr); 399 tdfx_outl(par, VIDDESKSTART, reg->startaddr);
411 tdfx_outl(par, VIDPROCCFG, reg->vidcfg); 400 tdfx_outl(par, VIDPROCCFG, reg->vidcfg);
412 tdfx_outl(par, VGAINIT1, reg->vgainit1); 401 tdfx_outl(par, VGAINIT1, reg->vgainit1);
413 tdfx_outl(par, MISCINIT0, reg->miscinit0); 402 tdfx_outl(par, MISCINIT0, reg->miscinit0);
414 403
415 banshee_make_room(par, 8); 404 banshee_make_room(par, 8);
416 tdfx_outl(par, SRCBASE, reg->srcbase); 405 tdfx_outl(par, SRCBASE, reg->startaddr);
417 tdfx_outl(par, DSTBASE, reg->dstbase); 406 tdfx_outl(par, DSTBASE, reg->startaddr);
418 tdfx_outl(par, COMMANDEXTRA_2D, 0); 407 tdfx_outl(par, COMMANDEXTRA_2D, 0);
419 tdfx_outl(par, CLIP0MIN, 0); 408 tdfx_outl(par, CLIP0MIN, 0);
420 tdfx_outl(par, CLIP0MAX, 0x0fff0fff); 409 tdfx_outl(par, CLIP0MAX, 0x0fff0fff);
421 tdfx_outl(par, CLIP1MIN, 0); 410 tdfx_outl(par, CLIP1MIN, 0);
422 tdfx_outl(par, CLIP1MAX, 0x0fff0fff); 411 tdfx_outl(par, CLIP1MAX, 0x0fff0fff);
423 tdfx_outl(par, SRCXY, 0); 412 tdfx_outl(par, SRCXY, 0);
424 413
425 banshee_wait_idle(info); 414 banshee_wait_idle(info);
426} 415}
427 416
428static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) 417static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id)
429{ 418{
430 u32 draminit0; 419 u32 draminit0 = tdfx_inl(par, DRAMINIT0);
431 u32 draminit1; 420 u32 draminit1 = tdfx_inl(par, DRAMINIT1);
432 u32 miscinit1; 421 u32 miscinit1;
433 422 int num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4;
434 int num_chips;
435 int chip_size; /* in MB */ 423 int chip_size; /* in MB */
436 u32 lfbsize; 424 int has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM;
437 int has_sgram;
438 425
439 draminit0 = tdfx_inl(par, DRAMINIT0);
440 draminit1 = tdfx_inl(par, DRAMINIT1);
441
442 num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4;
443
444 if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) { 426 if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) {
445 /* Banshee/Voodoo3 */ 427 /* Banshee/Voodoo3 */
446 has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM; 428 chip_size = 2;
447 chip_size = has_sgram ? ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 2 : 1) 429 if (has_sgram && (draminit0 & DRAMINIT0_SGRAM_TYPE))
448 : 2; 430 chip_size = 1;
449 } else { 431 } else {
450 /* Voodoo4/5 */ 432 /* Voodoo4/5 */
451 has_sgram = 0; 433 has_sgram = 0;
452 chip_size = 1 << ((draminit0 & DRAMINIT0_SGRAM_TYPE_MASK) >> DRAMINIT0_SGRAM_TYPE_SHIFT); 434 chip_size = draminit0 & DRAMINIT0_SGRAM_TYPE_MASK;
435 chip_size = 1 << (chip_size >> DRAMINIT0_SGRAM_TYPE_SHIFT);
453 } 436 }
454 lfbsize = num_chips * chip_size * 1024 * 1024;
455 437
456 /* disable block writes for SDRAM */ 438 /* disable block writes for SDRAM */
457 miscinit1 = tdfx_inl(par, MISCINIT1); 439 miscinit1 = tdfx_inl(par, MISCINIT1);
458 miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS; 440 miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS;
459 miscinit1 |= MISCINIT1_CLUT_INV; 441 miscinit1 |= MISCINIT1_CLUT_INV;
460 442
461 banshee_make_room(par, 1); 443 banshee_make_room(par, 1);
462 tdfx_outl(par, MISCINIT1, miscinit1); 444 tdfx_outl(par, MISCINIT1, miscinit1);
463 return lfbsize; 445 return num_chips * chip_size * 1024l * 1024;
464} 446}
465 447
466/* ------------------------------------------------------------------------- */ 448/* ------------------------------------------------------------------------- */
467 449
468static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info) 450static int tdfxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
469{ 451{
470 struct tdfx_par *par = info->par; 452 struct tdfx_par *par = info->par;
471 u32 lpitch; 453 u32 lpitch;
@@ -486,103 +468,113 @@ static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info)
486 DPRINTK("xoffset not supported\n"); 468 DPRINTK("xoffset not supported\n");
487 return -EINVAL; 469 return -EINVAL;
488 } 470 }
471 var->yoffset = 0;
489 472
490 /* Banshee doesn't support interlace, but Voodoo4/5 and probably Voodoo3 do. */ 473 /*
491 /* no direct information about device id now? use max_pixclock for this... */ 474 * Banshee doesn't support interlace, but Voodoo4/5 and probably
475 * Voodoo3 do.
476 * no direct information about device id now?
477 * use max_pixclock for this...
478 */
492 if (((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) && 479 if (((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) &&
493 (par->max_pixclock < VOODOO3_MAX_PIXCLOCK)) { 480 (par->max_pixclock < VOODOO3_MAX_PIXCLOCK)) {
494 DPRINTK("interlace not supported\n"); 481 DPRINTK("interlace not supported\n");
495 return -EINVAL; 482 return -EINVAL;
496 } 483 }
497 484
498 var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */ 485 var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */
499 lpitch = var->xres * ((var->bits_per_pixel + 7)>>3); 486 lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
500 487
501 if (var->xres < 320 || var->xres > 2048) { 488 if (var->xres < 320 || var->xres > 2048) {
502 DPRINTK("width not supported: %u\n", var->xres); 489 DPRINTK("width not supported: %u\n", var->xres);
503 return -EINVAL; 490 return -EINVAL;
504 } 491 }
505 492
506 if (var->yres < 200 || var->yres > 2048) { 493 if (var->yres < 200 || var->yres > 2048) {
507 DPRINTK("height not supported: %u\n", var->yres); 494 DPRINTK("height not supported: %u\n", var->yres);
508 return -EINVAL; 495 return -EINVAL;
509 } 496 }
510 497
511 if (lpitch * var->yres_virtual > info->fix.smem_len) { 498 if (lpitch * var->yres_virtual > info->fix.smem_len) {
512 var->yres_virtual = info->fix.smem_len/lpitch; 499 var->yres_virtual = info->fix.smem_len / lpitch;
513 if (var->yres_virtual < var->yres) { 500 if (var->yres_virtual < var->yres) {
514 DPRINTK("no memory for screen (%ux%ux%u)\n", 501 DPRINTK("no memory for screen (%ux%ux%u)\n",
515 var->xres, var->yres_virtual, var->bits_per_pixel); 502 var->xres, var->yres_virtual,
503 var->bits_per_pixel);
516 return -EINVAL; 504 return -EINVAL;
517 } 505 }
518 } 506 }
519 507
520 if (PICOS2KHZ(var->pixclock) > par->max_pixclock) { 508 if (PICOS2KHZ(var->pixclock) > par->max_pixclock) {
521 DPRINTK("pixclock too high (%ldKHz)\n",PICOS2KHZ(var->pixclock)); 509 DPRINTK("pixclock too high (%ldKHz)\n",
510 PICOS2KHZ(var->pixclock));
522 return -EINVAL; 511 return -EINVAL;
523 } 512 }
524 513
525 switch(var->bits_per_pixel) { 514 var->transp.offset = 0;
526 case 8: 515 var->transp.length = 0;
527 var->red.length = var->green.length = var->blue.length = 8; 516 switch (var->bits_per_pixel) {
528 break; 517 case 8:
529 case 16: 518 var->red.length = 8;
530 var->red.offset = 11; 519 var->red.offset = 0;
531 var->red.length = 5; 520 var->green = var->red;
532 var->green.offset = 5; 521 var->blue = var->red;
533 var->green.length = 6; 522 break;
534 var->blue.offset = 0; 523 case 16:
535 var->blue.length = 5; 524 var->red.offset = 11;
536 break; 525 var->red.length = 5;
537 case 24: 526 var->green.offset = 5;
538 var->red.offset=16; 527 var->green.length = 6;
539 var->green.offset=8; 528 var->blue.offset = 0;
540 var->blue.offset=0; 529 var->blue.length = 5;
541 var->red.length = var->green.length = var->blue.length = 8; 530 break;
542 case 32: 531 case 32:
543 var->red.offset = 16; 532 var->transp.offset = 24;
544 var->green.offset = 8; 533 var->transp.length = 8;
545 var->blue.offset = 0; 534 case 24:
546 var->red.length = var->green.length = var->blue.length = 8; 535 var->red.offset = 16;
547 break; 536 var->green.offset = 8;
537 var->blue.offset = 0;
538 var->red.length = var->green.length = var->blue.length = 8;
539 break;
548 } 540 }
549 var->height = var->width = -1; 541 var->width = -1;
550 542 var->height = -1;
543
551 var->accel_flags = FB_ACCELF_TEXT; 544 var->accel_flags = FB_ACCELF_TEXT;
552 545
553 DPRINTK("Checking graphics mode at %dx%d depth %d\n", var->xres, var->yres, var->bits_per_pixel); 546 DPRINTK("Checking graphics mode at %dx%d depth %d\n",
547 var->xres, var->yres, var->bits_per_pixel);
554 return 0; 548 return 0;
555} 549}
556 550
557static int tdfxfb_set_par(struct fb_info *info) 551static int tdfxfb_set_par(struct fb_info *info)
558{ 552{
559 struct tdfx_par *par = info->par; 553 struct tdfx_par *par = info->par;
560 u32 hdispend, hsyncsta, hsyncend, htotal; 554 u32 hdispend = info->var.xres;
555 u32 hsyncsta = hdispend + info->var.right_margin;
556 u32 hsyncend = hsyncsta + info->var.hsync_len;
557 u32 htotal = hsyncend + info->var.left_margin;
561 u32 hd, hs, he, ht, hbs, hbe; 558 u32 hd, hs, he, ht, hbs, hbe;
562 u32 vd, vs, ve, vt, vbs, vbe; 559 u32 vd, vs, ve, vt, vbs, vbe;
563 struct banshee_reg reg; 560 struct banshee_reg reg;
564 int fout, freq; 561 int fout, freq;
565 u32 wd, cpp; 562 u32 wd;
566 563 u32 cpp = (info->var.bits_per_pixel + 7) >> 3;
567 par->baseline = 0; 564
568
569 memset(&reg, 0, sizeof(reg)); 565 memset(&reg, 0, sizeof(reg));
570 cpp = (info->var.bits_per_pixel + 7)/8; 566
571 567 reg.vidcfg = VIDCFG_VIDPROC_ENABLE | VIDCFG_DESK_ENABLE |
572 reg.vidcfg = VIDCFG_VIDPROC_ENABLE | VIDCFG_DESK_ENABLE | VIDCFG_CURS_X11 | ((cpp - 1) << VIDCFG_PIXFMT_SHIFT) | (cpp != 1 ? VIDCFG_CLUT_BYPASS : 0); 568 VIDCFG_CURS_X11 |
569 ((cpp - 1) << VIDCFG_PIXFMT_SHIFT) |
570 (cpp != 1 ? VIDCFG_CLUT_BYPASS : 0);
573 571
574 /* PLL settings */ 572 /* PLL settings */
575 freq = PICOS2KHZ(info->var.pixclock); 573 freq = PICOS2KHZ(info->var.pixclock);
576 574
577 reg.dacmode = 0; 575 reg.vidcfg &= ~VIDCFG_2X;
578 reg.vidcfg &= ~VIDCFG_2X;
579
580 hdispend = info->var.xres;
581 hsyncsta = hdispend + info->var.right_margin;
582 hsyncend = hsyncsta + info->var.hsync_len;
583 htotal = hsyncend + info->var.left_margin;
584 576
585 if (freq > par->max_pixclock/2) { 577 if (freq > par->max_pixclock / 2) {
586 freq = freq > par->max_pixclock ? par->max_pixclock : freq; 578 freq = freq > par->max_pixclock ? par->max_pixclock : freq;
587 reg.dacmode |= DACMODE_2X; 579 reg.dacmode |= DACMODE_2X;
588 reg.vidcfg |= VIDCFG_2X; 580 reg.vidcfg |= VIDCFG_2X;
@@ -591,8 +583,9 @@ static int tdfxfb_set_par(struct fb_info *info)
591 hsyncend >>= 1; 583 hsyncend >>= 1;
592 htotal >>= 1; 584 htotal >>= 1;
593 } 585 }
594 586
595 hd = wd = (hdispend >> 3) - 1; 587 wd = (hdispend >> 3) - 1;
588 hd = wd;
596 hs = (hsyncsta >> 3) - 1; 589 hs = (hsyncsta >> 3) - 1;
597 he = (hsyncend >> 3) - 1; 590 he = (hsyncend >> 3) - 1;
598 ht = (htotal >> 3) - 1; 591 ht = (htotal >> 3) - 1;
@@ -600,28 +593,30 @@ static int tdfxfb_set_par(struct fb_info *info)
600 hbe = ht; 593 hbe = ht;
601 594
602 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { 595 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
603 vbs = vd = (info->var.yres << 1) - 1; 596 vd = (info->var.yres << 1) - 1;
604 vs = vd + (info->var.lower_margin << 1); 597 vs = vd + (info->var.lower_margin << 1);
605 ve = vs + (info->var.vsync_len << 1); 598 ve = vs + (info->var.vsync_len << 1);
606 vbe = vt = ve + (info->var.upper_margin << 1) - 1; 599 vt = ve + (info->var.upper_margin << 1) - 1;
600 reg.screensize = info->var.xres | (info->var.yres << 13);
601 reg.vidcfg |= VIDCFG_HALF_MODE;
602 reg.crt[0x09] = 0x80;
607 } else { 603 } else {
608 vbs = vd = info->var.yres - 1; 604 vd = info->var.yres - 1;
609 vs = vd + info->var.lower_margin; 605 vs = vd + info->var.lower_margin;
610 ve = vs + info->var.vsync_len; 606 ve = vs + info->var.vsync_len;
611 vbe = vt = ve + info->var.upper_margin - 1; 607 vt = ve + info->var.upper_margin - 1;
608 reg.screensize = info->var.xres | (info->var.yres << 12);
609 reg.vidcfg &= ~VIDCFG_HALF_MODE;
612 } 610 }
613 611 vbs = vd;
612 vbe = vt;
613
614 /* this is all pretty standard VGA register stuffing */ 614 /* this is all pretty standard VGA register stuffing */
615 reg.misc[0x00] = 0x0f | 615 reg.misc[0x00] = 0x0f |
616 (info->var.xres < 400 ? 0xa0 : 616 (info->var.xres < 400 ? 0xa0 :
617 info->var.xres < 480 ? 0x60 : 617 info->var.xres < 480 ? 0x60 :
618 info->var.xres < 768 ? 0xe0 : 0x20); 618 info->var.xres < 768 ? 0xe0 : 0x20);
619 619
620 reg.gra[0x00] = 0x00;
621 reg.gra[0x01] = 0x00;
622 reg.gra[0x02] = 0x00;
623 reg.gra[0x03] = 0x00;
624 reg.gra[0x04] = 0x00;
625 reg.gra[0x05] = 0x40; 620 reg.gra[0x05] = 0x40;
626 reg.gra[0x06] = 0x05; 621 reg.gra[0x06] = 0x05;
627 reg.gra[0x07] = 0x0f; 622 reg.gra[0x07] = 0x0f;
@@ -644,10 +639,7 @@ static int tdfxfb_set_par(struct fb_info *info)
644 reg.att[0x0e] = 0x0e; 639 reg.att[0x0e] = 0x0e;
645 reg.att[0x0f] = 0x0f; 640 reg.att[0x0f] = 0x0f;
646 reg.att[0x10] = 0x41; 641 reg.att[0x10] = 0x41;
647 reg.att[0x11] = 0x00;
648 reg.att[0x12] = 0x0f; 642 reg.att[0x12] = 0x0f;
649 reg.att[0x13] = 0x00;
650 reg.att[0x14] = 0x00;
651 643
652 reg.seq[0x00] = 0x03; 644 reg.seq[0x00] = 0x03;
653 reg.seq[0x01] = 0x01; /* fixme: clkdiv2? */ 645 reg.seq[0x01] = 0x01; /* fixme: clkdiv2? */
@@ -660,146 +652,133 @@ static int tdfxfb_set_par(struct fb_info *info)
660 reg.crt[0x02] = hbs; 652 reg.crt[0x02] = hbs;
661 reg.crt[0x03] = 0x80 | (hbe & 0x1f); 653 reg.crt[0x03] = 0x80 | (hbe & 0x1f);
662 reg.crt[0x04] = hs; 654 reg.crt[0x04] = hs;
663 reg.crt[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f); 655 reg.crt[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
664 reg.crt[0x06] = vt; 656 reg.crt[0x06] = vt;
665 reg.crt[0x07] = ((vs & 0x200) >> 2) | 657 reg.crt[0x07] = ((vs & 0x200) >> 2) |
666 ((vd & 0x200) >> 3) | 658 ((vd & 0x200) >> 3) |
667 ((vt & 0x200) >> 4) | 0x10 | 659 ((vt & 0x200) >> 4) | 0x10 |
668 ((vbs & 0x100) >> 5) | 660 ((vbs & 0x100) >> 5) |
669 ((vs & 0x100) >> 6) | 661 ((vs & 0x100) >> 6) |
670 ((vd & 0x100) >> 7) | 662 ((vd & 0x100) >> 7) |
671 ((vt & 0x100) >> 8); 663 ((vt & 0x100) >> 8);
672 reg.crt[0x08] = 0x00; 664 reg.crt[0x09] |= 0x40 | ((vbs & 0x200) >> 4);
673 reg.crt[0x09] = 0x40 | ((vbs & 0x200) >> 4);
674 reg.crt[0x0a] = 0x00;
675 reg.crt[0x0b] = 0x00;
676 reg.crt[0x0c] = 0x00;
677 reg.crt[0x0d] = 0x00;
678 reg.crt[0x0e] = 0x00;
679 reg.crt[0x0f] = 0x00;
680 reg.crt[0x10] = vs; 665 reg.crt[0x10] = vs;
681 reg.crt[0x11] = (ve & 0x0f) | 0x20; 666 reg.crt[0x11] = (ve & 0x0f) | 0x20;
682 reg.crt[0x12] = vd; 667 reg.crt[0x12] = vd;
683 reg.crt[0x13] = wd; 668 reg.crt[0x13] = wd;
684 reg.crt[0x14] = 0x00;
685 reg.crt[0x15] = vbs; 669 reg.crt[0x15] = vbs;
686 reg.crt[0x16] = vbe + 1; 670 reg.crt[0x16] = vbe + 1;
687 reg.crt[0x17] = 0xc3; 671 reg.crt[0x17] = 0xc3;
688 reg.crt[0x18] = 0xff; 672 reg.crt[0x18] = 0xff;
689 673
690 /* Banshee's nonvga stuff */ 674 /* Banshee's nonvga stuff */
691 reg.ext[0x00] = (((ht & 0x100) >> 8) | 675 reg.ext[0x00] = (((ht & 0x100) >> 8) |
692 ((hd & 0x100) >> 6) | 676 ((hd & 0x100) >> 6) |
693 ((hbs & 0x100) >> 4) | 677 ((hbs & 0x100) >> 4) |
694 ((hbe & 0x40) >> 1) | 678 ((hbe & 0x40) >> 1) |
695 ((hs & 0x100) >> 2) | 679 ((hs & 0x100) >> 2) |
696 ((he & 0x20) << 2)); 680 ((he & 0x20) << 2));
697 reg.ext[0x01] = (((vt & 0x400) >> 10) | 681 reg.ext[0x01] = (((vt & 0x400) >> 10) |
698 ((vd & 0x400) >> 8) | 682 ((vd & 0x400) >> 8) |
699 ((vbs & 0x400) >> 6) | 683 ((vbs & 0x400) >> 6) |
700 ((vbe & 0x400) >> 4)); 684 ((vbe & 0x400) >> 4));
701 685
702 reg.vgainit0 = VGAINIT0_8BIT_DAC | 686 reg.vgainit0 = VGAINIT0_8BIT_DAC |
703 VGAINIT0_EXT_ENABLE | 687 VGAINIT0_EXT_ENABLE |
704 VGAINIT0_WAKEUP_3C3 | 688 VGAINIT0_WAKEUP_3C3 |
705 VGAINIT0_ALT_READBACK | 689 VGAINIT0_ALT_READBACK |
706 VGAINIT0_EXTSHIFTOUT; 690 VGAINIT0_EXTSHIFTOUT;
707 reg.vgainit1 = tdfx_inl(par, VGAINIT1) & 0x1fffff; 691 reg.vgainit1 = tdfx_inl(par, VGAINIT1) & 0x1fffff;
708 692
693 if (hwcursor)
694 reg.curspataddr = info->fix.smem_len;
695
709 reg.cursloc = 0; 696 reg.cursloc = 0;
710 697
711 reg.cursc0 = 0; 698 reg.cursc0 = 0;
712 reg.cursc1 = 0xffffff; 699 reg.cursc1 = 0xffffff;
713
714 reg.stride = info->var.xres * cpp;
715 reg.startaddr = par->baseline * reg.stride;
716 reg.srcbase = reg.startaddr;
717 reg.dstbase = reg.startaddr;
718 700
719 /* PLL settings */ 701 reg.stride = info->var.xres * cpp;
720 freq = PICOS2KHZ(info->var.pixclock); 702 reg.startaddr = info->var.yoffset * reg.stride
703 + info->var.xoffset * cpp;
721 704
722 reg.dacmode &= ~DACMODE_2X;
723 reg.vidcfg &= ~VIDCFG_2X;
724 if (freq > par->max_pixclock/2) {
725 freq = freq > par->max_pixclock ? par->max_pixclock : freq;
726 reg.dacmode |= DACMODE_2X;
727 reg.vidcfg |= VIDCFG_2X;
728 }
729 reg.vidpll = do_calc_pll(freq, &fout); 705 reg.vidpll = do_calc_pll(freq, &fout);
730#if 0 706#if 0
731 reg.mempll = do_calc_pll(..., &fout); 707 reg.mempll = do_calc_pll(..., &fout);
732 reg.gfxpll = do_calc_pll(..., &fout); 708 reg.gfxpll = do_calc_pll(..., &fout);
733#endif 709#endif
734 710
735 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
736 reg.screensize = info->var.xres | (info->var.yres << 13);
737 reg.vidcfg |= VIDCFG_HALF_MODE;
738 reg.crt[0x09] |= 0x80;
739 } else {
740 reg.screensize = info->var.xres | (info->var.yres << 12);
741 reg.vidcfg &= ~VIDCFG_HALF_MODE;
742 }
743 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) 711 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
744 reg.vidcfg |= VIDCFG_INTERLACE; 712 reg.vidcfg |= VIDCFG_INTERLACE;
745 reg.miscinit0 = tdfx_inl(par, MISCINIT0); 713 reg.miscinit0 = tdfx_inl(par, MISCINIT0);
746 714
747#if defined(__BIG_ENDIAN) 715#if defined(__BIG_ENDIAN)
748 switch (info->var.bits_per_pixel) { 716 switch (info->var.bits_per_pixel) {
749 case 8: 717 case 8:
750 case 24: 718 case 24:
751 reg.miscinit0 &= ~(1 << 30); 719 reg.miscinit0 &= ~(1 << 30);
752 reg.miscinit0 &= ~(1 << 31); 720 reg.miscinit0 &= ~(1 << 31);
753 break; 721 break;
754 case 16: 722 case 16:
755 reg.miscinit0 |= (1 << 30); 723 reg.miscinit0 |= (1 << 30);
756 reg.miscinit0 |= (1 << 31); 724 reg.miscinit0 |= (1 << 31);
757 break; 725 break;
758 case 32: 726 case 32:
759 reg.miscinit0 |= (1 << 30); 727 reg.miscinit0 |= (1 << 30);
760 reg.miscinit0 &= ~(1 << 31); 728 reg.miscinit0 &= ~(1 << 31);
761 break; 729 break;
762 } 730 }
763#endif 731#endif
764 do_write_regs(info, &reg); 732 do_write_regs(info, &reg);
765 733
766 /* Now change fb_fix_screeninfo according to changes in par */ 734 /* Now change fb_fix_screeninfo according to changes in par */
767 info->fix.line_length = info->var.xres * ((info->var.bits_per_pixel + 7)>>3); 735 info->fix.line_length = reg.stride;
768 info->fix.visual = (info->var.bits_per_pixel == 8) 736 info->fix.visual = (info->var.bits_per_pixel == 8)
769 ? FB_VISUAL_PSEUDOCOLOR 737 ? FB_VISUAL_PSEUDOCOLOR
770 : FB_VISUAL_TRUECOLOR; 738 : FB_VISUAL_TRUECOLOR;
771 DPRINTK("Graphics mode is now set at %dx%d depth %d\n", info->var.xres, info->var.yres, info->var.bits_per_pixel); 739 DPRINTK("Graphics mode is now set at %dx%d depth %d\n",
772 return 0; 740 info->var.xres, info->var.yres, info->var.bits_per_pixel);
741 return 0;
773} 742}
774 743
775/* A handy macro shamelessly pinched from matroxfb */ 744/* A handy macro shamelessly pinched from matroxfb */
776#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) 745#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
777 746
778static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, 747static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
779 unsigned blue,unsigned transp,struct fb_info *info) 748 unsigned blue, unsigned transp,
749 struct fb_info *info)
780{ 750{
781 struct tdfx_par *par = info->par; 751 struct tdfx_par *par = info->par;
782 u32 rgbcol; 752 u32 rgbcol;
783 753
784 if (regno >= info->cmap.len || regno > 255) return 1; 754 if (regno >= info->cmap.len || regno > 255)
785 755 return 1;
756
757 /* grayscale works only partially under directcolor */
758 if (info->var.grayscale) {
759 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
760 blue = (red * 77 + green * 151 + blue * 28) >> 8;
761 green = blue;
762 red = blue;
763 }
764
786 switch (info->fix.visual) { 765 switch (info->fix.visual) {
787 case FB_VISUAL_PSEUDOCOLOR: 766 case FB_VISUAL_PSEUDOCOLOR:
788 rgbcol =(((u32)red & 0xff00) << 8) | 767 rgbcol = (((u32)red & 0xff00) << 8) |
789 (((u32)green & 0xff00) << 0) | 768 (((u32)green & 0xff00) << 0) |
790 (((u32)blue & 0xff00) >> 8); 769 (((u32)blue & 0xff00) >> 8);
791 do_setpalentry(par, regno, rgbcol); 770 do_setpalentry(par, regno, rgbcol);
792 break; 771 break;
793 /* Truecolor has no hardware color palettes. */ 772 /* Truecolor has no hardware color palettes. */
794 case FB_VISUAL_TRUECOLOR: 773 case FB_VISUAL_TRUECOLOR:
795 if (regno < 16) { 774 if (regno < 16) {
796 rgbcol = (CNVT_TOHW( red, info->var.red.length) << 775 rgbcol = (CNVT_TOHW(red, info->var.red.length) <<
797 info->var.red.offset) | 776 info->var.red.offset) |
798 (CNVT_TOHW( green, info->var.green.length) << 777 (CNVT_TOHW(green, info->var.green.length) <<
799 info->var.green.offset) | 778 info->var.green.offset) |
800 (CNVT_TOHW( blue, info->var.blue.length) << 779 (CNVT_TOHW(blue, info->var.blue.length) <<
801 info->var.blue.offset) | 780 info->var.blue.offset) |
802 (CNVT_TOHW( transp, info->var.transp.length) << 781 (CNVT_TOHW(transp, info->var.transp.length) <<
803 info->var.transp.offset); 782 info->var.transp.offset);
804 par->palette[regno] = rgbcol; 783 par->palette[regno] = rgbcol;
805 } 784 }
@@ -815,287 +794,325 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
815 794
816/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ 795/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
817static int tdfxfb_blank(int blank, struct fb_info *info) 796static int tdfxfb_blank(int blank, struct fb_info *info)
818{ 797{
819 struct tdfx_par *par = info->par; 798 struct tdfx_par *par = info->par;
820 u32 dacmode, state = 0, vgablank = 0; 799 int vgablank = 1;
800 u32 dacmode = tdfx_inl(par, DACMODE);
821 801
822 dacmode = tdfx_inl(par, DACMODE); 802 dacmode &= ~(BIT(1) | BIT(3));
823 803
824 switch (blank) { 804 switch (blank) {
825 case FB_BLANK_UNBLANK: /* Screen: On; HSync: On, VSync: On */ 805 case FB_BLANK_UNBLANK: /* Screen: On; HSync: On, VSync: On */
826 state = 0; 806 vgablank = 0;
827 vgablank = 0; 807 break;
828 break; 808 case FB_BLANK_NORMAL: /* Screen: Off; HSync: On, VSync: On */
829 case FB_BLANK_NORMAL: /* Screen: Off; HSync: On, VSync: On */ 809 break;
830 state = 0; 810 case FB_BLANK_VSYNC_SUSPEND: /* Screen: Off; HSync: On, VSync: Off */
831 vgablank = 1; 811 dacmode |= BIT(3);
832 break; 812 break;
833 case FB_BLANK_VSYNC_SUSPEND: /* Screen: Off; HSync: On, VSync: Off */ 813 case FB_BLANK_HSYNC_SUSPEND: /* Screen: Off; HSync: Off, VSync: On */
834 state = BIT(3); 814 dacmode |= BIT(1);
835 vgablank = 1; 815 break;
836 break; 816 case FB_BLANK_POWERDOWN: /* Screen: Off; HSync: Off, VSync: Off */
837 case FB_BLANK_HSYNC_SUSPEND: /* Screen: Off; HSync: Off, VSync: On */ 817 dacmode |= BIT(1) | BIT(3);
838 state = BIT(1); 818 break;
839 vgablank = 1;
840 break;
841 case FB_BLANK_POWERDOWN: /* Screen: Off; HSync: Off, VSync: Off */
842 state = BIT(1) | BIT(3);
843 vgablank = 1;
844 break;
845 } 819 }
846 820
847 dacmode &= ~(BIT(1) | BIT(3)); 821 banshee_make_room(par, 1);
848 dacmode |= state;
849 banshee_make_room(par, 1);
850 tdfx_outl(par, DACMODE, dacmode); 822 tdfx_outl(par, DACMODE, dacmode);
851 if (vgablank) 823 if (vgablank)
852 vga_disable_video(par); 824 vga_disable_video(par);
853 else 825 else
854 vga_enable_video(par); 826 vga_enable_video(par);
855 return 0; 827 return 0;
856} 828}
857 829
858/* 830/*
859 * Set the starting position of the visible screen to var->yoffset 831 * Set the starting position of the visible screen to var->yoffset
860 */ 832 */
861static int tdfxfb_pan_display(struct fb_var_screeninfo *var, 833static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
862 struct fb_info *info) 834 struct fb_info *info)
863{ 835{
864 struct tdfx_par *par = info->par; 836 struct tdfx_par *par = info->par;
865 u32 addr; 837 u32 addr = var->yoffset * info->fix.line_length;
866 838
867 if (nopan || var->xoffset || (var->yoffset > var->yres_virtual)) 839 if (nopan || var->xoffset || (var->yoffset > var->yres_virtual))
868 return -EINVAL; 840 return -EINVAL;
869 if ((var->yoffset + var->yres > var->yres_virtual && nowrap)) 841 if ((var->yoffset + var->yres > var->yres_virtual && nowrap))
870 return -EINVAL; 842 return -EINVAL;
871 843
872 addr = var->yoffset * info->fix.line_length;
873 banshee_make_room(par, 1); 844 banshee_make_room(par, 1);
874 tdfx_outl(par, VIDDESKSTART, addr); 845 tdfx_outl(par, VIDDESKSTART, addr);
875 846
876 info->var.xoffset = var->xoffset; 847 info->var.xoffset = var->xoffset;
877 info->var.yoffset = var->yoffset; 848 info->var.yoffset = var->yoffset;
878 return 0; 849 return 0;
879} 850}
880 851
881#ifdef CONFIG_FB_3DFX_ACCEL 852#ifdef CONFIG_FB_3DFX_ACCEL
882/* 853/*
883 * FillRect 2D command (solidfill or invert (via ROP_XOR)) 854 * FillRect 2D command (solidfill or invert (via ROP_XOR))
884 */ 855 */
885static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 856static void tdfxfb_fillrect(struct fb_info *info,
857 const struct fb_fillrect *rect)
886{ 858{
887 struct tdfx_par *par = info->par; 859 struct tdfx_par *par = info->par;
888 u32 bpp = info->var.bits_per_pixel; 860 u32 bpp = info->var.bits_per_pixel;
889 u32 stride = info->fix.line_length; 861 u32 stride = info->fix.line_length;
890 u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 862 u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
891 int tdfx_rop; 863 int tdfx_rop;
892 864 u32 dx = rect->dx;
893 if (rect->rop == ROP_COPY) 865 u32 dy = rect->dy;
866 u32 dstbase = 0;
867
868 if (rect->rop == ROP_COPY)
894 tdfx_rop = TDFX_ROP_COPY; 869 tdfx_rop = TDFX_ROP_COPY;
895 else 870 else
896 tdfx_rop = TDFX_ROP_XOR; 871 tdfx_rop = TDFX_ROP_XOR;
897 872
898 banshee_make_room(par, 5); 873 /* asume always rect->height < 4096 */
899 tdfx_outl(par, DSTFORMAT, fmt); 874 if (dy + rect->height > 4095) {
875 dstbase = stride * dy;
876 dy = 0;
877 }
878 /* asume always rect->width < 4096 */
879 if (dx + rect->width > 4095) {
880 dstbase += dx * bpp >> 3;
881 dx = 0;
882 }
883 banshee_make_room(par, 6);
884 tdfx_outl(par, DSTFORMAT, fmt);
900 if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) { 885 if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
901 tdfx_outl(par, COLORFORE, rect->color); 886 tdfx_outl(par, COLORFORE, rect->color);
902 } else { /* FB_VISUAL_TRUECOLOR */ 887 } else { /* FB_VISUAL_TRUECOLOR */
903 tdfx_outl(par, COLORFORE, par->palette[rect->color]); 888 tdfx_outl(par, COLORFORE, par->palette[rect->color]);
904 } 889 }
905 tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24)); 890 tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
906 tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16)); 891 tdfx_outl(par, DSTBASE, dstbase);
907 tdfx_outl(par, LAUNCH_2D, rect->dx | (rect->dy << 16)); 892 tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16));
893 tdfx_outl(par, LAUNCH_2D, dx | (dy << 16));
908} 894}
909 895
910/* 896/*
911 * Screen-to-Screen BitBlt 2D command (for the bmove fb op.) 897 * Screen-to-Screen BitBlt 2D command (for the bmove fb op.)
912 */ 898 */
913static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 899static void tdfxfb_copyarea(struct fb_info *info,
900 const struct fb_copyarea *area)
914{ 901{
915 struct tdfx_par *par = info->par; 902 struct tdfx_par *par = info->par;
916 u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy; 903 u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
917 u32 bpp = info->var.bits_per_pixel; 904 u32 bpp = info->var.bits_per_pixel;
918 u32 stride = info->fix.line_length; 905 u32 stride = info->fix.line_length;
919 u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24); 906 u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24);
920 u32 fmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 907 u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
921 908 u32 dstbase = 0;
909 u32 srcbase = 0;
910
911 /* asume always area->height < 4096 */
912 if (sy + area->height > 4095) {
913 srcbase = stride * sy;
914 sy = 0;
915 }
916 /* asume always area->width < 4096 */
917 if (sx + area->width > 4095) {
918 srcbase += sx * bpp >> 3;
919 sx = 0;
920 }
921 /* asume always area->height < 4096 */
922 if (dy + area->height > 4095) {
923 dstbase = stride * dy;
924 dy = 0;
925 }
926 /* asume always area->width < 4096 */
927 if (dx + area->width > 4095) {
928 dstbase += dx * bpp >> 3;
929 dx = 0;
930 }
931
922 if (area->sx <= area->dx) { 932 if (area->sx <= area->dx) {
923 //-X 933 /* -X */
924 blitcmd |= BIT(14); 934 blitcmd |= BIT(14);
925 sx += area->width - 1; 935 sx += area->width - 1;
926 dx += area->width - 1; 936 dx += area->width - 1;
927 } 937 }
928 if (area->sy <= area->dy) { 938 if (area->sy <= area->dy) {
929 //-Y 939 /* -Y */
930 blitcmd |= BIT(15); 940 blitcmd |= BIT(15);
931 sy += area->height - 1; 941 sy += area->height - 1;
932 dy += area->height - 1; 942 dy += area->height - 1;
933 } 943 }
934
935 banshee_make_room(par, 6);
936 944
937 tdfx_outl(par, SRCFORMAT, fmt); 945 banshee_make_room(par, 8);
938 tdfx_outl(par, DSTFORMAT, fmt); 946
939 tdfx_outl(par, COMMAND_2D, blitcmd); 947 tdfx_outl(par, SRCFORMAT, fmt);
940 tdfx_outl(par, DSTSIZE, area->width | (area->height << 16)); 948 tdfx_outl(par, DSTFORMAT, fmt);
941 tdfx_outl(par, DSTXY, dx | (dy << 16)); 949 tdfx_outl(par, COMMAND_2D, blitcmd);
942 tdfx_outl(par, LAUNCH_2D, sx | (sy << 16)); 950 tdfx_outl(par, DSTSIZE, area->width | (area->height << 16));
951 tdfx_outl(par, DSTXY, dx | (dy << 16));
952 tdfx_outl(par, SRCBASE, srcbase);
953 tdfx_outl(par, DSTBASE, dstbase);
954 tdfx_outl(par, LAUNCH_2D, sx | (sy << 16));
943} 955}
944 956
945static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) 957static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image)
946{ 958{
947 struct tdfx_par *par = info->par; 959 struct tdfx_par *par = info->par;
948 int size = image->height * ((image->width * image->depth + 7)>>3); 960 int size = image->height * ((image->width * image->depth + 7) >> 3);
949 int fifo_free; 961 int fifo_free;
950 int i, stride = info->fix.line_length; 962 int i, stride = info->fix.line_length;
951 u32 bpp = info->var.bits_per_pixel; 963 u32 bpp = info->var.bits_per_pixel;
952 u32 dstfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 964 u32 dstfmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
953 u8 *chardata = (u8 *) image->data; 965 u8 *chardata = (u8 *) image->data;
954 u32 srcfmt; 966 u32 srcfmt;
967 u32 dx = image->dx;
968 u32 dy = image->dy;
969 u32 dstbase = 0;
955 970
956 if (image->depth != 1) { 971 if (image->depth != 1) {
957 //banshee_make_room(par, 6 + ((size + 3) >> 2)); 972#ifdef BROKEN_CODE
958 //srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000; 973 banshee_make_room(par, 6 + ((size + 3) >> 2));
974 srcfmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13) |
975 0x400000;
976#else
959 cfb_imageblit(info, image); 977 cfb_imageblit(info, image);
978#endif
960 return; 979 return;
961 } else { 980 }
962 banshee_make_room(par, 8); 981 banshee_make_room(par, 9);
963 switch (info->fix.visual) { 982 switch (info->fix.visual) {
964 case FB_VISUAL_PSEUDOCOLOR: 983 case FB_VISUAL_PSEUDOCOLOR:
965 tdfx_outl(par, COLORFORE, image->fg_color); 984 tdfx_outl(par, COLORFORE, image->fg_color);
966 tdfx_outl(par, COLORBACK, image->bg_color); 985 tdfx_outl(par, COLORBACK, image->bg_color);
967 break; 986 break;
968 case FB_VISUAL_TRUECOLOR: 987 case FB_VISUAL_TRUECOLOR:
969 default: 988 default:
970 tdfx_outl(par, COLORFORE, 989 tdfx_outl(par, COLORFORE,
971 par->palette[image->fg_color]); 990 par->palette[image->fg_color]);
972 tdfx_outl(par, COLORBACK, 991 tdfx_outl(par, COLORBACK,
973 par->palette[image->bg_color]); 992 par->palette[image->bg_color]);
974 } 993 }
975#ifdef __BIG_ENDIAN 994#ifdef __BIG_ENDIAN
976 srcfmt = 0x400000 | BIT(20); 995 srcfmt = 0x400000 | BIT(20);
977#else 996#else
978 srcfmt = 0x400000; 997 srcfmt = 0x400000;
979#endif 998#endif
980 } 999 /* asume always image->height < 4096 */
1000 if (dy + image->height > 4095) {
1001 dstbase = stride * dy;
1002 dy = 0;
1003 }
1004 /* asume always image->width < 4096 */
1005 if (dx + image->width > 4095) {
1006 dstbase += dx * bpp >> 3;
1007 dx = 0;
1008 }
981 1009
982 tdfx_outl(par, SRCXY, 0); 1010 tdfx_outl(par, DSTBASE, dstbase);
983 tdfx_outl(par, DSTXY, image->dx | (image->dy << 16)); 1011 tdfx_outl(par, SRCXY, 0);
984 tdfx_outl(par, COMMAND_2D, COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24)); 1012 tdfx_outl(par, DSTXY, dx | (dy << 16));
985 tdfx_outl(par, SRCFORMAT, srcfmt); 1013 tdfx_outl(par, COMMAND_2D,
986 tdfx_outl(par, DSTFORMAT, dstfmt); 1014 COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
987 tdfx_outl(par, DSTSIZE, image->width | (image->height << 16)); 1015 tdfx_outl(par, SRCFORMAT, srcfmt);
1016 tdfx_outl(par, DSTFORMAT, dstfmt);
1017 tdfx_outl(par, DSTSIZE, image->width | (image->height << 16));
988 1018
989 /* A count of how many free FIFO entries we've requested. 1019 /* A count of how many free FIFO entries we've requested.
990 * When this goes negative, we need to request more. */ 1020 * When this goes negative, we need to request more. */
991 fifo_free = 0; 1021 fifo_free = 0;
992 1022
993 /* Send four bytes at a time of data */ 1023 /* Send four bytes at a time of data */
994 for (i = (size >> 2) ; i > 0; i--) { 1024 for (i = (size >> 2); i > 0; i--) {
995 if(--fifo_free < 0) { 1025 if (--fifo_free < 0) {
996 fifo_free=31; 1026 fifo_free = 31;
997 banshee_make_room(par,fifo_free); 1027 banshee_make_room(par, fifo_free);
998 } 1028 }
999 tdfx_outl(par, LAUNCH_2D,*(u32*)chardata); 1029 tdfx_outl(par, LAUNCH_2D, *(u32 *)chardata);
1000 chardata += 4; 1030 chardata += 4;
1001 } 1031 }
1002 1032
1003 /* Send the leftovers now */ 1033 /* Send the leftovers now */
1004 banshee_make_room(par,3); 1034 banshee_make_room(par, 3);
1005 i = size%4; 1035 switch (size % 4) {
1006 switch (i) { 1036 case 0:
1007 case 0: break; 1037 break;
1008 case 1: tdfx_outl(par, LAUNCH_2D,*chardata); break; 1038 case 1:
1009 case 2: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata); break; 1039 tdfx_outl(par, LAUNCH_2D, *chardata);
1010 case 3: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break; 1040 break;
1041 case 2:
1042 tdfx_outl(par, LAUNCH_2D, *(u16 *)chardata);
1043 break;
1044 case 3:
1045 tdfx_outl(par, LAUNCH_2D,
1046 *(u16 *)chardata | (chardata[3] << 24));
1047 break;
1011 } 1048 }
1012} 1049}
1013#endif /* CONFIG_FB_3DFX_ACCEL */ 1050#endif /* CONFIG_FB_3DFX_ACCEL */
1014 1051
1015#ifdef TDFX_HARDWARE_CURSOR
1016static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1052static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1017{ 1053{
1018 struct tdfx_par *par = info->par; 1054 struct tdfx_par *par = info->par;
1019 unsigned long flags; 1055 u32 vidcfg;
1020 1056
1021 /* 1057 if (!hwcursor)
1022 * If the cursor is not be changed this means either we want the 1058 return -EINVAL; /* just to force soft_cursor() call */
1023 * current cursor state (if enable is set) or we want to query what
1024 * we can do with the cursor (if enable is not set)
1025 */
1026 if (!cursor->set) return 0;
1027 1059
1028 /* Too large of a cursor :-( */ 1060 /* Too large of a cursor or wrong bpp :-( */
1029 if (cursor->image.width > 64 || cursor->image.height > 64) 1061 if (cursor->image.width > 64 ||
1030 return -ENXIO; 1062 cursor->image.height > 64 ||
1063 cursor->image.depth > 1)
1064 return -EINVAL;
1031 1065
1032 /* 1066 vidcfg = tdfx_inl(par, VIDPROCCFG);
1033 * If we are going to be changing things we should disable 1067 if (cursor->enable)
1034 * the cursor first 1068 tdfx_outl(par, VIDPROCCFG, vidcfg | VIDCFG_HWCURSOR_ENABLE);
1035 */ 1069 else
1036 if (info->cursor.enable) { 1070 tdfx_outl(par, VIDPROCCFG, vidcfg & ~VIDCFG_HWCURSOR_ENABLE);
1037 spin_lock_irqsave(&par->DAClock, flags);
1038 info->cursor.enable = 0;
1039 del_timer(&(par->hwcursor.timer));
1040 tdfx_outl(par, VIDPROCCFG, par->hwcursor.disable);
1041 spin_unlock_irqrestore(&par->DAClock, flags);
1042 }
1043 1071
1044 /* Disable the Cursor */ 1072 /*
1045 if ((cursor->set && FB_CUR_SETCUR) && !cursor->enable) 1073 * If the cursor is not be changed this means either we want the
1074 * current cursor state (if enable is set) or we want to query what
1075 * we can do with the cursor (if enable is not set)
1076 */
1077 if (!cursor->set)
1046 return 0; 1078 return 0;
1047 1079
1048 /* fix cursor color - XFree86 forgets to restore it properly */ 1080 /* fix cursor color - XFree86 forgets to restore it properly */
1049 if (cursor->set && FB_CUR_SETCMAP) { 1081 if (cursor->set & FB_CUR_SETCMAP) {
1050 struct fb_cmap cmap = cursor->image.cmap; 1082 struct fb_cmap cmap = info->cmap;
1083 u32 bg_idx = cursor->image.bg_color;
1084 u32 fg_idx = cursor->image.fg_color;
1051 unsigned long bg_color, fg_color; 1085 unsigned long bg_color, fg_color;
1052 1086
1053 cmap.len = 2; /* Voodoo 3+ only support 2 color cursors */ 1087 fg_color = (((u32)cmap.red[fg_idx] & 0xff00) << 8) |
1054 fg_color = ((cmap.red[cmap.start] << 16) | 1088 (((u32)cmap.green[fg_idx] & 0xff00) << 0) |
1055 (cmap.green[cmap.start] << 8) | 1089 (((u32)cmap.blue[fg_idx] & 0xff00) >> 8);
1056 (cmap.blue[cmap.start])); 1090 bg_color = (((u32)cmap.red[bg_idx] & 0xff00) << 8) |
1057 bg_color = ((cmap.red[cmap.start+1] << 16) | 1091 (((u32)cmap.green[bg_idx] & 0xff00) << 0) |
1058 (cmap.green[cmap.start+1] << 8) | 1092 (((u32)cmap.blue[bg_idx] & 0xff00) >> 8);
1059 (cmap.blue[cmap.start+1]));
1060 fb_copy_cmap(&cmap, &info->cursor.image.cmap);
1061 spin_lock_irqsave(&par->DAClock, flags);
1062 banshee_make_room(par, 2); 1093 banshee_make_room(par, 2);
1063 tdfx_outl(par, HWCURC0, bg_color); 1094 tdfx_outl(par, HWCURC0, bg_color);
1064 tdfx_outl(par, HWCURC1, fg_color); 1095 tdfx_outl(par, HWCURC1, fg_color);
1065 spin_unlock_irqrestore(&par->DAClock, flags);
1066 } 1096 }
1067 1097
1068 if (cursor->set && FB_CUR_SETPOS) { 1098 if (cursor->set & FB_CUR_SETPOS) {
1069 int x, y; 1099 int x = cursor->image.dx;
1100 int y = cursor->image.dy - info->var.yoffset;
1070 1101
1071 x = cursor->image.dx;
1072 y = cursor->image.dy;
1073 y -= info->var.yoffset;
1074 info->cursor.image.dx = x;
1075 info->cursor.image.dy = y;
1076 x += 63; 1102 x += 63;
1077 y += 63; 1103 y += 63;
1078 spin_lock_irqsave(&par->DAClock, flags);
1079 banshee_make_room(par, 1); 1104 banshee_make_room(par, 1);
1080 tdfx_outl(par, HWCURLOC, (y << 16) + x); 1105 tdfx_outl(par, HWCURLOC, (y << 16) + x);
1081 spin_unlock_irqrestore(&par->DAClock, flags);
1082 } 1106 }
1083 1107 if (cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE)) {
1084 /* Not supported so we fake it */
1085 if (cursor->set && FB_CUR_SETHOT) {
1086 info->cursor.hot.x = cursor->hot.x;
1087 info->cursor.hot.y = cursor->hot.y;
1088 }
1089
1090 if (cursor->set && FB_CUR_SETSHAPE) {
1091 /* 1108 /*
1092 * Voodoo 3 and above cards use 2 monochrome cursor patterns. 1109 * Voodoo 3 and above cards use 2 monochrome cursor patterns.
1093 * The reason is so the card can fetch 8 words at a time 1110 * The reason is so the card can fetch 8 words at a time
1094 * and are stored on chip for use for the next 8 scanlines. 1111 * and are stored on chip for use for the next 8 scanlines.
1095 * This reduces the number of times for access to draw the 1112 * This reduces the number of times for access to draw the
1096 * cursor for each screen refresh. 1113 * cursor for each screen refresh.
1097 * Each pattern is a bitmap of 64 bit wide and 64 bit high 1114 * Each pattern is a bitmap of 64 bit wide and 64 bit high
1098 * (total of 8192 bits or 1024 Kbytes). The two patterns are 1115 * (total of 8192 bits or 1024 bytes). The two patterns are
1099 * stored in such a way that pattern 0 always resides in the 1116 * stored in such a way that pattern 0 always resides in the
1100 * lower half (least significant 64 bits) of a 128 bit word 1117 * lower half (least significant 64 bits) of a 128 bit word
1101 * and pattern 1 the upper half. If you examine the data of 1118 * and pattern 1 the upper half. If you examine the data of
@@ -1106,50 +1123,54 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1106 * (128 bits) which is the maximum cursor width times two for 1123 * (128 bits) which is the maximum cursor width times two for
1107 * the two monochrome patterns. 1124 * the two monochrome patterns.
1108 */ 1125 */
1109 u8 *cursorbase = (u8 *) info->cursor.image.data; 1126 u8 __iomem *cursorbase = info->screen_base + info->fix.smem_len;
1110 char *bitmap = (char *)cursor->image.data; 1127 u8 *bitmap = (u8 *)cursor->image.data;
1111 char *mask = (char *) cursor->mask; 1128 u8 *mask = (u8 *)cursor->mask;
1112 int i, j, k, h = 0; 1129 int i;
1113 1130
1114 for (i = 0; i < 64; i++) { 1131 fb_memset(cursorbase, 0, 1024);
1115 if (i < cursor->image.height) { 1132
1116 j = (cursor->image.width + 7) >> 3; 1133 for (i = 0; i < cursor->image.height; i++) {
1117 k = 8 - j; 1134 int h = 0;
1118 1135 int j = (cursor->image.width + 7) >> 3;
1119 for (;j > 0; j--) { 1136
1120 /* Pattern 0. Copy the cursor bitmap to it */ 1137 for (; j > 0; j--) {
1121 fb_writeb(*bitmap, cursorbase + h); 1138 u8 data = *mask ^ *bitmap;
1122 bitmap++; 1139 if (cursor->rop == ROP_COPY)
1123 /* Pattern 1. Copy the cursor mask to it */ 1140 data = *mask & *bitmap;
1124 fb_writeb(*mask, cursorbase + h + 8); 1141 /* Pattern 0. Copy the cursor mask to it */
1125 mask++; 1142 fb_writeb(*mask, cursorbase + h);
1126 h++; 1143 mask++;
1127 } 1144 /* Pattern 1. Copy the cursor bitmap to it */
1128 for (;k > 0; k--) { 1145 fb_writeb(data, cursorbase + h + 8);
1129 fb_writeb(0, cursorbase + h); 1146 bitmap++;
1130 fb_writeb(~0, cursorbase + h + 8); 1147 h++;
1131 h++;
1132 }
1133 } else {
1134 fb_writel(0, cursorbase + h);
1135 fb_writel(0, cursorbase + h + 4);
1136 fb_writel(~0, cursorbase + h + 8);
1137 fb_writel(~0, cursorbase + h + 12);
1138 h += 16;
1139 } 1148 }
1149 cursorbase += 16;
1140 } 1150 }
1141 } 1151 }
1142 /* Turn the cursor on */
1143 cursor->enable = 1;
1144 info->cursor = *cursor;
1145 mod_timer(&par->hwcursor.timer, jiffies+HZ/2);
1146 spin_lock_irqsave(&par->DAClock, flags);
1147 banshee_make_room(par, 1);
1148 tdfx_outl(par, VIDPROCCFG, par->hwcursor.enable);
1149 spin_unlock_irqrestore(&par->DAClock, flags);
1150 return 0; 1152 return 0;
1151} 1153}
1154
1155static struct fb_ops tdfxfb_ops = {
1156 .owner = THIS_MODULE,
1157 .fb_check_var = tdfxfb_check_var,
1158 .fb_set_par = tdfxfb_set_par,
1159 .fb_setcolreg = tdfxfb_setcolreg,
1160 .fb_blank = tdfxfb_blank,
1161 .fb_pan_display = tdfxfb_pan_display,
1162 .fb_sync = banshee_wait_idle,
1163 .fb_cursor = tdfxfb_cursor,
1164#ifdef CONFIG_FB_3DFX_ACCEL
1165 .fb_fillrect = tdfxfb_fillrect,
1166 .fb_copyarea = tdfxfb_copyarea,
1167 .fb_imageblit = tdfxfb_imageblit,
1168#else
1169 .fb_fillrect = cfb_fillrect,
1170 .fb_copyarea = cfb_copyarea,
1171 .fb_imageblit = cfb_imageblit,
1152#endif 1172#endif
1173};
1153 1174
1154/** 1175/**
1155 * tdfxfb_probe - Device Initializiation 1176 * tdfxfb_probe - Device Initializiation
@@ -1161,14 +1182,15 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1161 * 1182 *
1162 */ 1183 */
1163static int __devinit tdfxfb_probe(struct pci_dev *pdev, 1184static int __devinit tdfxfb_probe(struct pci_dev *pdev,
1164 const struct pci_device_id *id) 1185 const struct pci_device_id *id)
1165{ 1186{
1166 struct tdfx_par *default_par; 1187 struct tdfx_par *default_par;
1167 struct fb_info *info; 1188 struct fb_info *info;
1168 int err, lpitch; 1189 int err, lpitch;
1169 1190
1170 if ((err = pci_enable_device(pdev))) { 1191 err = pci_enable_device(pdev);
1171 printk(KERN_WARNING "tdfxfb: Can't enable pdev: %d\n", err); 1192 if (err) {
1193 printk(KERN_ERR "tdfxfb: Can't enable pdev: %d\n", err);
1172 return err; 1194 return err;
1173 } 1195 }
1174 1196
@@ -1176,139 +1198,145 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
1176 1198
1177 if (!info) 1199 if (!info)
1178 return -ENOMEM; 1200 return -ENOMEM;
1179 1201
1180 default_par = info->par; 1202 default_par = info->par;
1181 1203
1182 /* Configure the default fb_fix_screeninfo first */ 1204 /* Configure the default fb_fix_screeninfo first */
1183 switch (pdev->device) { 1205 switch (pdev->device) {
1184 case PCI_DEVICE_ID_3DFX_BANSHEE: 1206 case PCI_DEVICE_ID_3DFX_BANSHEE:
1185 strcat(tdfx_fix.id, " Banshee"); 1207 strcat(tdfx_fix.id, " Banshee");
1186 default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK; 1208 default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
1187 break; 1209 break;
1188 case PCI_DEVICE_ID_3DFX_VOODOO3: 1210 case PCI_DEVICE_ID_3DFX_VOODOO3:
1189 strcat(tdfx_fix.id, " Voodoo3"); 1211 strcat(tdfx_fix.id, " Voodoo3");
1190 default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK; 1212 default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
1191 break; 1213 break;
1192 case PCI_DEVICE_ID_3DFX_VOODOO5: 1214 case PCI_DEVICE_ID_3DFX_VOODOO5:
1193 strcat(tdfx_fix.id, " Voodoo5"); 1215 strcat(tdfx_fix.id, " Voodoo5");
1194 default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK; 1216 default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
1195 break; 1217 break;
1196 } 1218 }
1197 1219
1198 tdfx_fix.mmio_start = pci_resource_start(pdev, 0); 1220 tdfx_fix.mmio_start = pci_resource_start(pdev, 0);
1199 tdfx_fix.mmio_len = pci_resource_len(pdev, 0); 1221 tdfx_fix.mmio_len = pci_resource_len(pdev, 0);
1200 default_par->regbase_virt = ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len); 1222 if (!request_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len,
1201 if (!default_par->regbase_virt) { 1223 "tdfx regbase")) {
1202 printk("fb: Can't remap %s register area.\n", tdfx_fix.id); 1224 printk(KERN_ERR "tdfxfb: Can't reserve regbase\n");
1203 goto out_err; 1225 goto out_err;
1204 } 1226 }
1205 1227
1206 if (!request_mem_region(pci_resource_start(pdev, 0), 1228 default_par->regbase_virt =
1207 pci_resource_len(pdev, 0), "tdfx regbase")) { 1229 ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
1208 printk(KERN_WARNING "tdfxfb: Can't reserve regbase\n"); 1230 if (!default_par->regbase_virt) {
1209 goto out_err; 1231 printk(KERN_ERR "fb: Can't remap %s register area.\n",
1210 } 1232 tdfx_fix.id);
1233 goto out_err_regbase;
1234 }
1211 1235
1212 tdfx_fix.smem_start = pci_resource_start(pdev, 1); 1236 tdfx_fix.smem_start = pci_resource_start(pdev, 1);
1213 if (!(tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device))) { 1237 tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device);
1214 printk("fb: Can't count %s memory.\n", tdfx_fix.id); 1238 if (!tdfx_fix.smem_len) {
1215 release_mem_region(pci_resource_start(pdev, 0), 1239 printk(KERN_ERR "fb: Can't count %s memory.\n", tdfx_fix.id);
1216 pci_resource_len(pdev, 0)); 1240 goto out_err_regbase;
1217 goto out_err;
1218 } 1241 }
1219 1242
1220 if (!request_mem_region(pci_resource_start(pdev, 1), 1243 if (!request_mem_region(tdfx_fix.smem_start,
1221 pci_resource_len(pdev, 1), "tdfx smem")) { 1244 pci_resource_len(pdev, 1), "tdfx smem")) {
1222 printk(KERN_WARNING "tdfxfb: Can't reserve smem\n"); 1245 printk(KERN_ERR "tdfxfb: Can't reserve smem\n");
1223 release_mem_region(pci_resource_start(pdev, 0), 1246 goto out_err_regbase;
1224 pci_resource_len(pdev, 0));
1225 goto out_err;
1226 } 1247 }
1227 1248
1228 info->screen_base = ioremap_nocache(tdfx_fix.smem_start, 1249 info->screen_base = ioremap_nocache(tdfx_fix.smem_start,
1229 tdfx_fix.smem_len); 1250 tdfx_fix.smem_len);
1230 if (!info->screen_base) { 1251 if (!info->screen_base) {
1231 printk("fb: Can't remap %s framebuffer.\n", tdfx_fix.id); 1252 printk(KERN_ERR "fb: Can't remap %s framebuffer.\n",
1232 release_mem_region(pci_resource_start(pdev, 1), 1253 tdfx_fix.id);
1233 pci_resource_len(pdev, 1)); 1254 goto out_err_screenbase;
1234 release_mem_region(pci_resource_start(pdev, 0),
1235 pci_resource_len(pdev, 0));
1236 goto out_err;
1237 } 1255 }
1238 1256
1239 default_par->iobase = pci_resource_start(pdev, 2); 1257 default_par->iobase = pci_resource_start(pdev, 2);
1240 1258
1241 if (!request_region(pci_resource_start(pdev, 2), 1259 if (!request_region(pci_resource_start(pdev, 2),
1242 pci_resource_len(pdev, 2), "tdfx iobase")) { 1260 pci_resource_len(pdev, 2), "tdfx iobase")) {
1243 printk(KERN_WARNING "tdfxfb: Can't reserve iobase\n"); 1261 printk(KERN_ERR "tdfxfb: Can't reserve iobase\n");
1244 release_mem_region(pci_resource_start(pdev, 1), 1262 goto out_err_screenbase;
1245 pci_resource_len(pdev, 1));
1246 release_mem_region(pci_resource_start(pdev, 0),
1247 pci_resource_len(pdev, 0));
1248 goto out_err;
1249 } 1263 }
1250 1264
1251 printk("fb: %s memory = %dK\n", tdfx_fix.id, tdfx_fix.smem_len >> 10); 1265 printk(KERN_INFO "fb: %s memory = %dK\n", tdfx_fix.id,
1266 tdfx_fix.smem_len >> 10);
1267
1268 default_par->mtrr_handle = -1;
1269 if (!nomtrr)
1270 default_par->mtrr_handle =
1271 mtrr_add(tdfx_fix.smem_start, tdfx_fix.smem_len,
1272 MTRR_TYPE_WRCOMB, 1);
1252 1273
1253 tdfx_fix.ypanstep = nopan ? 0 : 1; 1274 tdfx_fix.ypanstep = nopan ? 0 : 1;
1254 tdfx_fix.ywrapstep = nowrap ? 0 : 1; 1275 tdfx_fix.ywrapstep = nowrap ? 0 : 1;
1255 1276
1256 info->fbops = &tdfxfb_ops; 1277 info->fbops = &tdfxfb_ops;
1257 info->fix = tdfx_fix; 1278 info->fix = tdfx_fix;
1258 info->pseudo_palette = default_par->palette; 1279 info->pseudo_palette = default_par->palette;
1259 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1280 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1260#ifdef CONFIG_FB_3DFX_ACCEL 1281#ifdef CONFIG_FB_3DFX_ACCEL
1261 info->flags |= FBINFO_HWACCEL_FILLRECT | 1282 info->flags |= FBINFO_HWACCEL_FILLRECT |
1262 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_IMAGEBLIT; 1283 FBINFO_HWACCEL_COPYAREA |
1284 FBINFO_HWACCEL_IMAGEBLIT |
1285 FBINFO_READS_FAST;
1263#endif 1286#endif
1287 /* reserve 8192 bits for cursor */
1288 /* the 2.4 driver says PAGE_MASK boundary is not enough for Voodoo4 */
1289 if (hwcursor)
1290 info->fix.smem_len = (info->fix.smem_len - 1024) &
1291 (PAGE_MASK << 1);
1264 1292
1265 if (!mode_option) 1293 if (!mode_option)
1266 mode_option = "640x480@60"; 1294 mode_option = "640x480@60";
1267 1295
1268 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); 1296 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
1269 if (!err || err == 4) 1297 if (!err || err == 4)
1270 info->var = tdfx_var; 1298 info->var = tdfx_var;
1271 1299
1272 /* maximize virtual vertical length */ 1300 /* maximize virtual vertical length */
1273 lpitch = info->var.xres_virtual * ((info->var.bits_per_pixel + 7) >> 3); 1301 lpitch = info->var.xres_virtual * ((info->var.bits_per_pixel + 7) >> 3);
1274 info->var.yres_virtual = info->fix.smem_len/lpitch; 1302 info->var.yres_virtual = info->fix.smem_len / lpitch;
1275 if (info->var.yres_virtual < info->var.yres) 1303 if (info->var.yres_virtual < info->var.yres)
1276 goto out_err; 1304 goto out_err_iobase;
1277
1278#ifdef CONFIG_FB_3DFX_ACCEL
1279 /*
1280 * FIXME: Limit var->yres_virtual to 4096 because of screen artifacts
1281 * during scrolling. This is only present if 2D acceleration is
1282 * enabled.
1283 */
1284 if (info->var.yres_virtual > 4096)
1285 info->var.yres_virtual = 4096;
1286#endif /* CONFIG_FB_3DFX_ACCEL */
1287 1305
1288 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { 1306 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
1289 printk(KERN_WARNING "tdfxfb: Can't allocate color map\n"); 1307 printk(KERN_ERR "tdfxfb: Can't allocate color map\n");
1290 goto out_err; 1308 goto out_err_iobase;
1291 } 1309 }
1292 1310
1293 if (register_framebuffer(info) < 0) { 1311 if (register_framebuffer(info) < 0) {
1294 printk("tdfxfb: can't register framebuffer\n"); 1312 printk(KERN_ERR "tdfxfb: can't register framebuffer\n");
1295 fb_dealloc_cmap(&info->cmap); 1313 fb_dealloc_cmap(&info->cmap);
1296 goto out_err; 1314 goto out_err_iobase;
1297 } 1315 }
1298 /* 1316 /*
1299 * Our driver data 1317 * Our driver data
1300 */ 1318 */
1301 pci_set_drvdata(pdev, info); 1319 pci_set_drvdata(pdev, info);
1302 return 0; 1320 return 0;
1303 1321
1304out_err: 1322out_err_iobase:
1323 if (default_par->mtrr_handle >= 0)
1324 mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
1325 info->fix.smem_len);
1326 release_mem_region(pci_resource_start(pdev, 2),
1327 pci_resource_len(pdev, 2));
1328out_err_screenbase:
1329 if (info->screen_base)
1330 iounmap(info->screen_base);
1331 release_mem_region(tdfx_fix.smem_start, pci_resource_len(pdev, 1));
1332out_err_regbase:
1305 /* 1333 /*
1306 * Cleanup after anything that was remapped/allocated. 1334 * Cleanup after anything that was remapped/allocated.
1307 */ 1335 */
1308 if (default_par->regbase_virt) 1336 if (default_par->regbase_virt)
1309 iounmap(default_par->regbase_virt); 1337 iounmap(default_par->regbase_virt);
1310 if (info->screen_base) 1338 release_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
1311 iounmap(info->screen_base); 1339out_err:
1312 framebuffer_release(info); 1340 framebuffer_release(info);
1313 return -ENXIO; 1341 return -ENXIO;
1314} 1342}
@@ -1316,7 +1344,7 @@ out_err:
1316#ifndef MODULE 1344#ifndef MODULE
1317static void tdfxfb_setup(char *options) 1345static void tdfxfb_setup(char *options)
1318{ 1346{
1319 char* this_opt; 1347 char *this_opt;
1320 1348
1321 if (!options || !*options) 1349 if (!options || !*options)
1322 return; 1350 return;
@@ -1324,10 +1352,16 @@ static void tdfxfb_setup(char *options)
1324 while ((this_opt = strsep(&options, ",")) != NULL) { 1352 while ((this_opt = strsep(&options, ",")) != NULL) {
1325 if (!*this_opt) 1353 if (!*this_opt)
1326 continue; 1354 continue;
1327 if(!strcmp(this_opt, "nopan")) { 1355 if (!strcmp(this_opt, "nopan")) {
1328 nopan = 1; 1356 nopan = 1;
1329 } else if(!strcmp(this_opt, "nowrap")) { 1357 } else if (!strcmp(this_opt, "nowrap")) {
1330 nowrap = 1; 1358 nowrap = 1;
1359 } else if (!strncmp(this_opt, "hwcursor=", 9)) {
1360 hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
1361#ifdef CONFIG_MTRR
1362 } else if (!strncmp(this_opt, "nomtrr", 6)) {
1363 nomtrr = 1;
1364#endif
1331 } else { 1365 } else {
1332 mode_option = this_opt; 1366 mode_option = this_opt;
1333 } 1367 }
@@ -1350,6 +1384,9 @@ static void __devexit tdfxfb_remove(struct pci_dev *pdev)
1350 struct tdfx_par *par = info->par; 1384 struct tdfx_par *par = info->par;
1351 1385
1352 unregister_framebuffer(info); 1386 unregister_framebuffer(info);
1387 if (par->mtrr_handle >= 0)
1388 mtrr_del(par->mtrr_handle, info->fix.smem_start,
1389 info->fix.smem_len);
1353 iounmap(par->regbase_virt); 1390 iounmap(par->regbase_virt);
1354 iounmap(info->screen_base); 1391 iounmap(info->screen_base);
1355 1392
@@ -1374,17 +1411,25 @@ static int __init tdfxfb_init(void)
1374 1411
1375 tdfxfb_setup(option); 1412 tdfxfb_setup(option);
1376#endif 1413#endif
1377 return pci_register_driver(&tdfxfb_driver); 1414 return pci_register_driver(&tdfxfb_driver);
1378} 1415}
1379 1416
1380static void __exit tdfxfb_exit(void) 1417static void __exit tdfxfb_exit(void)
1381{ 1418{
1382 pci_unregister_driver(&tdfxfb_driver); 1419 pci_unregister_driver(&tdfxfb_driver);
1383} 1420}
1384 1421
1385MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>"); 1422MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>");
1386MODULE_DESCRIPTION("3Dfx framebuffer device driver"); 1423MODULE_DESCRIPTION("3Dfx framebuffer device driver");
1387MODULE_LICENSE("GPL"); 1424MODULE_LICENSE("GPL");
1388 1425
1426module_param(hwcursor, int, 0644);
1427MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
1428 "(1=enable, 0=disable, default=1)");
1429#ifdef CONFIG_MTRR
1430module_param(nomtrr, bool, 0);
1431MODULE_PARM_DESC(nomtrr, "Disable MTRR support (default: enabled)");
1432#endif
1433
1389module_init(tdfxfb_init); 1434module_init(tdfxfb_init);
1390module_exit(tdfxfb_exit); 1435module_exit(tdfxfb_exit);
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index d292a37ec7d6..680642c089c9 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -5,7 +5,7 @@
5 * Copyright (C) 1997 Geert Uytterhoeven 5 * Copyright (C) 1997 Geert Uytterhoeven
6 * Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha 6 * Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha
7 * Copyright (C) 2002 Richard Henderson 7 * Copyright (C) 2002 Richard Henderson
8 * Copyright (C) 2006 Maciej W. Rozycki 8 * Copyright (C) 2006, 2007 Maciej W. Rozycki
9 * 9 *
10 * This file is subject to the terms and conditions of the GNU General Public 10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive for 11 * License. See the file COPYING in the main directory of this archive for
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/bitrev.h> 15#include <linux/bitrev.h>
16#include <linux/compiler.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/device.h> 18#include <linux/device.h>
18#include <linux/errno.h> 19#include <linux/errno.h>
@@ -636,15 +637,6 @@ tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
636 637
637 is8bpp = info->var.bits_per_pixel == 8; 638 is8bpp = info->var.bits_per_pixel == 8;
638 639
639 /* For copies that aren't pixel expansion, there's little we
640 can do better than the generic code. */
641 /* ??? There is a DMA write mode; I wonder if that could be
642 made to pull the data from the image buffer... */
643 if (image->depth > 1) {
644 cfb_imageblit(info, image);
645 return;
646 }
647
648 dx = image->dx; 640 dx = image->dx;
649 dy = image->dy; 641 dy = image->dy;
650 width = image->width; 642 width = image->width;
@@ -654,6 +646,9 @@ tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
654 line_length = info->fix.line_length; 646 line_length = info->fix.line_length;
655 rincr = (width + 7) / 8; 647 rincr = (width + 7) / 8;
656 648
649 /* A shift below cannot cope with. */
650 if (unlikely(width == 0))
651 return;
657 /* Crop the image to the screen. */ 652 /* Crop the image to the screen. */
658 if (dx > vxres || dy > vyres) 653 if (dx > vxres || dy > vyres)
659 return; 654 return;
@@ -709,9 +704,10 @@ tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
709 unsigned long bwidth; 704 unsigned long bwidth;
710 705
711 /* Handle common case of imaging a single character, in 706 /* Handle common case of imaging a single character, in
712 a font less than 32 pixels wide. */ 707 a font less than or 32 pixels wide. */
713 708
714 pixelmask = (1 << width) - 1; 709 /* Avoid a shift by 32; width > 0 implied. */
710 pixelmask = (2ul << (width - 1)) - 1;
715 pixelmask <<= shift; 711 pixelmask <<= shift;
716 __raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG); 712 __raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);
717 wmb(); 713 wmb();
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index c699864b6f4a..70fb4ee2b421 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1,18 +1,19 @@
1/* 1/*
2 * Frame buffer driver for Trident Blade and Image series 2 * Frame buffer driver for Trident Blade and Image series
3 * 3 *
4 * Copyright 2001,2002 - Jani Monoses <jani@iv.ro> 4 * Copyright 2001, 2002 - Jani Monoses <jani@iv.ro>
5 * 5 *
6 * 6 *
7 * CREDITS:(in order of appearance) 7 * CREDITS:(in order of appearance)
8 * skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video 8 * skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
9 * Special thanks ;) to Mattia Crivellini <tia@mclink.it> 9 * Special thanks ;) to Mattia Crivellini <tia@mclink.it>
10 * much inspired by the XFree86 4.x Trident driver sources by Alan Hourihane 10 * much inspired by the XFree86 4.x Trident driver sources
11 * the FreeVGA project 11 * by Alan Hourihane the FreeVGA project
12 * Francesco Salvestrini <salvestrini@users.sf.net> XP support,code,suggestions 12 * Francesco Salvestrini <salvestrini@users.sf.net> XP support,
13 * code, suggestions
13 * TODO: 14 * TODO:
14 * timing value tweaking so it looks good on every monitor in every mode 15 * timing value tweaking so it looks good on every monitor in every mode
15 * TGUI acceleration 16 * TGUI acceleration
16 */ 17 */
17 18
18#include <linux/module.h> 19#include <linux/module.h>
@@ -26,11 +27,11 @@
26#define VERSION "0.7.8-NEWAPI" 27#define VERSION "0.7.8-NEWAPI"
27 28
28struct tridentfb_par { 29struct tridentfb_par {
29 int vclk; //in MHz 30 int vclk; /* in MHz */
30 void __iomem * io_virt; //iospace virtual memory address 31 void __iomem *io_virt; /* iospace virtual memory address */
31}; 32};
32 33
33static unsigned char eng_oper; //engine operation... 34static unsigned char eng_oper; /* engine operation... */
34static struct fb_ops tridentfb_ops; 35static struct fb_ops tridentfb_ops;
35 36
36static struct tridentfb_par default_par; 37static struct tridentfb_par default_par;
@@ -39,11 +40,10 @@ static struct tridentfb_par default_par;
39static struct fb_info fb_info; 40static struct fb_info fb_info;
40static u32 pseudo_pal[16]; 41static u32 pseudo_pal[16];
41 42
42
43static struct fb_var_screeninfo default_var; 43static struct fb_var_screeninfo default_var;
44 44
45static struct fb_fix_screeninfo tridentfb_fix = { 45static struct fb_fix_screeninfo tridentfb_fix = {
46 .id = "Trident", 46 .id = "Trident",
47 .type = FB_TYPE_PACKED_PIXELS, 47 .type = FB_TYPE_PACKED_PIXELS,
48 .ypanstep = 1, 48 .ypanstep = 1,
49 .visual = FB_VISUAL_PSEUDOCOLOR, 49 .visual = FB_VISUAL_PSEUDOCOLOR,
@@ -55,11 +55,10 @@ static int chip_id;
55static int defaultaccel; 55static int defaultaccel;
56static int displaytype; 56static int displaytype;
57 57
58
59/* defaults which are normally overriden by user values */ 58/* defaults which are normally overriden by user values */
60 59
61/* video mode */ 60/* video mode */
62static char * mode = "640x480"; 61static char *mode = "640x480";
63static int bpp = 8; 62static int bpp = 8;
64 63
65static int noaccel; 64static int noaccel;
@@ -74,7 +73,6 @@ static int memsize;
74static int memdiff; 73static int memdiff;
75static int nativex; 74static int nativex;
76 75
77
78module_param(mode, charp, 0); 76module_param(mode, charp, 0);
79module_param(bpp, int, 0); 77module_param(bpp, int, 0);
80module_param(center, int, 0); 78module_param(center, int, 0);
@@ -86,88 +84,85 @@ module_param(nativex, int, 0);
86module_param(fp, int, 0); 84module_param(fp, int, 0);
87module_param(crt, int, 0); 85module_param(crt, int, 0);
88 86
89
90static int chip3D; 87static int chip3D;
91static int chipcyber; 88static int chipcyber;
92 89
93static int is3Dchip(int id) 90static int is3Dchip(int id)
94{ 91{
95 return ((id == BLADE3D) || (id == CYBERBLADEE4) || 92 return ((id == BLADE3D) || (id == CYBERBLADEE4) ||
96 (id == CYBERBLADEi7) || (id == CYBERBLADEi7D) || 93 (id == CYBERBLADEi7) || (id == CYBERBLADEi7D) ||
97 (id == CYBER9397) || (id == CYBER9397DVD) || 94 (id == CYBER9397) || (id == CYBER9397DVD) ||
98 (id == CYBER9520) || (id == CYBER9525DVD) || 95 (id == CYBER9520) || (id == CYBER9525DVD) ||
99 (id == IMAGE975) || (id == IMAGE985) || 96 (id == IMAGE975) || (id == IMAGE985) ||
100 (id == CYBERBLADEi1) || (id == CYBERBLADEi1D) || 97 (id == CYBERBLADEi1) || (id == CYBERBLADEi1D) ||
101 (id == CYBERBLADEAi1) || (id == CYBERBLADEAi1D) || 98 (id == CYBERBLADEAi1) || (id == CYBERBLADEAi1D) ||
102 (id == CYBERBLADEXPm8) || (id == CYBERBLADEXPm16) || 99 (id == CYBERBLADEXPm8) || (id == CYBERBLADEXPm16) ||
103 (id == CYBERBLADEXPAi1)); 100 (id == CYBERBLADEXPAi1));
104} 101}
105 102
106static int iscyber(int id) 103static int iscyber(int id)
107{ 104{
108 switch (id) { 105 switch (id) {
109 case CYBER9388: 106 case CYBER9388:
110 case CYBER9382: 107 case CYBER9382:
111 case CYBER9385: 108 case CYBER9385:
112 case CYBER9397: 109 case CYBER9397:
113 case CYBER9397DVD: 110 case CYBER9397DVD:
114 case CYBER9520: 111 case CYBER9520:
115 case CYBER9525DVD: 112 case CYBER9525DVD:
116 case CYBERBLADEE4: 113 case CYBERBLADEE4:
117 case CYBERBLADEi7D: 114 case CYBERBLADEi7D:
118 case CYBERBLADEi1: 115 case CYBERBLADEi1:
119 case CYBERBLADEi1D: 116 case CYBERBLADEi1D:
120 case CYBERBLADEAi1: 117 case CYBERBLADEAi1:
121 case CYBERBLADEAi1D: 118 case CYBERBLADEAi1D:
122 case CYBERBLADEXPAi1: 119 case CYBERBLADEXPAi1:
123 return 1; 120 return 1;
124
125 case CYBER9320:
126 case TGUI9660:
127 case IMAGE975:
128 case IMAGE985:
129 case BLADE3D:
130 case CYBERBLADEi7: /* VIA MPV4 integrated version */
131 121
132 default: 122 case CYBER9320:
133 /* case CYBERBLDAEXPm8: Strange */ 123 case TGUI9660:
134 /* case CYBERBLDAEXPm16: Strange */ 124 case IMAGE975:
135 return 0; 125 case IMAGE985:
126 case BLADE3D:
127 case CYBERBLADEi7: /* VIA MPV4 integrated version */
128
129 default:
130 /* case CYBERBLDAEXPm8: Strange */
131 /* case CYBERBLDAEXPm16: Strange */
132 return 0;
136 } 133 }
137} 134}
138 135
139#define CRT 0x3D0 //CRTC registers offset for color display 136#define CRT 0x3D0 /* CRTC registers offset for color display */
140 137
141#ifndef TRIDENT_MMIO 138#ifndef TRIDENT_MMIO
142 #define TRIDENT_MMIO 1 139 #define TRIDENT_MMIO 1
143#endif 140#endif
144 141
145#if TRIDENT_MMIO 142#if TRIDENT_MMIO
146 #define t_outb(val,reg) writeb(val,((struct tridentfb_par *)(fb_info.par))->io_virt + reg) 143 #define t_outb(val, reg) writeb(val,((struct tridentfb_par *)(fb_info.par))->io_virt + reg)
147 #define t_inb(reg) readb(((struct tridentfb_par*)(fb_info.par))->io_virt + reg) 144 #define t_inb(reg) readb(((struct tridentfb_par*)(fb_info.par))->io_virt + reg)
148#else 145#else
149 #define t_outb(val,reg) outb(val,reg) 146 #define t_outb(val, reg) outb(val, reg)
150 #define t_inb(reg) inb(reg) 147 #define t_inb(reg) inb(reg)
151#endif 148#endif
152 149
153 150
154static struct accel_switch { 151static struct accel_switch {
155 void (*init_accel)(int,int); 152 void (*init_accel) (int, int);
156 void (*wait_engine)(void); 153 void (*wait_engine) (void);
157 void (*fill_rect)(__u32,__u32,__u32,__u32,__u32,__u32); 154 void (*fill_rect) (u32, u32, u32, u32, u32, u32);
158 void (*copy_rect)(__u32,__u32,__u32,__u32,__u32,__u32); 155 void (*copy_rect) (u32, u32, u32, u32, u32, u32);
159} *acc; 156} *acc;
160 157
161#define writemmr(r,v) writel(v, ((struct tridentfb_par *)fb_info.par)->io_virt + r) 158#define writemmr(r, v) writel(v, ((struct tridentfb_par *)fb_info.par)->io_virt + r)
162#define readmmr(r) readl(((struct tridentfb_par *)fb_info.par)->io_virt + r) 159#define readmmr(r) readl(((struct tridentfb_par *)fb_info.par)->io_virt + r)
163 160
164
165
166/* 161/*
167 * Blade specific acceleration. 162 * Blade specific acceleration.
168 */ 163 */
169 164
170#define point(x,y) ((y)<<16|(x)) 165#define point(x, y) ((y) << 16 | (x))
171#define STA 0x2120 166#define STA 0x2120
172#define CMD 0x2144 167#define CMD 0x2144
173#define ROP 0x2148 168#define ROP 0x2148
@@ -179,64 +174,71 @@ static struct accel_switch {
179 174
180#define ROP_S 0xCC 175#define ROP_S 0xCC
181 176
182static void blade_init_accel(int pitch,int bpp) 177static void blade_init_accel(int pitch, int bpp)
183{ 178{
184 int v1 = (pitch>>3)<<20; 179 int v1 = (pitch >> 3) << 20;
185 int tmp = 0,v2; 180 int tmp = 0, v2;
186 switch (bpp) { 181 switch (bpp) {
187 case 8:tmp = 0;break; 182 case 8:
188 case 15:tmp = 5;break; 183 tmp = 0;
189 case 16:tmp = 1;break; 184 break;
190 case 24: 185 case 15:
191 case 32:tmp = 2;break; 186 tmp = 5;
187 break;
188 case 16:
189 tmp = 1;
190 break;
191 case 24:
192 case 32:
193 tmp = 2;
194 break;
192 } 195 }
193 v2 = v1 | (tmp<<29); 196 v2 = v1 | (tmp << 29);
194 writemmr(0x21C0,v2); 197 writemmr(0x21C0, v2);
195 writemmr(0x21C4,v2); 198 writemmr(0x21C4, v2);
196 writemmr(0x21B8,v2); 199 writemmr(0x21B8, v2);
197 writemmr(0x21BC,v2); 200 writemmr(0x21BC, v2);
198 writemmr(0x21D0,v1); 201 writemmr(0x21D0, v1);
199 writemmr(0x21D4,v1); 202 writemmr(0x21D4, v1);
200 writemmr(0x21C8,v1); 203 writemmr(0x21C8, v1);
201 writemmr(0x21CC,v1); 204 writemmr(0x21CC, v1);
202 writemmr(0x216C,0); 205 writemmr(0x216C, 0);
203} 206}
204 207
205static void blade_wait_engine(void) 208static void blade_wait_engine(void)
206{ 209{
207 while(readmmr(STA) & 0xFA800000); 210 while (readmmr(STA) & 0xFA800000) ;
208} 211}
209 212
210static void blade_fill_rect(__u32 x,__u32 y,__u32 w,__u32 h,__u32 c,__u32 rop) 213static void blade_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
211{ 214{
212 writemmr(CLR,c); 215 writemmr(CLR, c);
213 writemmr(ROP,rop ? 0x66:ROP_S); 216 writemmr(ROP, rop ? 0x66 : ROP_S);
214 writemmr(CMD,0x20000000|1<<19|1<<4|2<<2); 217 writemmr(CMD, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2);
215 218
216 writemmr(DR1,point(x,y)); 219 writemmr(DR1, point(x, y));
217 writemmr(DR2,point(x+w-1,y+h-1)); 220 writemmr(DR2, point(x + w - 1, y + h - 1));
218} 221}
219 222
220static void blade_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h) 223static void blade_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
221{ 224{
222 __u32 s1,s2,d1,d2; 225 u32 s1, s2, d1, d2;
223 int direction = 2; 226 int direction = 2;
224 s1 = point(x1,y1); 227 s1 = point(x1, y1);
225 s2 = point(x1+w-1,y1+h-1); 228 s2 = point(x1 + w - 1, y1 + h - 1);
226 d1 = point(x2,y2); 229 d1 = point(x2, y2);
227 d2 = point(x2+w-1,y2+h-1); 230 d2 = point(x2 + w - 1, y2 + h - 1);
228 231
229 if ((y1 > y2) || ((y1 == y2) && (x1 > x2))) 232 if ((y1 > y2) || ((y1 == y2) && (x1 > x2)))
230 direction = 0; 233 direction = 0;
231
232 234
233 writemmr(ROP,ROP_S); 235 writemmr(ROP, ROP_S);
234 writemmr(CMD,0xE0000000|1<<19|1<<4|1<<2|direction); 236 writemmr(CMD, 0xE0000000 | 1 << 19 | 1 << 4 | 1 << 2 | direction);
235 237
236 writemmr(SR1,direction?s2:s1); 238 writemmr(SR1, direction ? s2 : s1);
237 writemmr(SR2,direction?s1:s2); 239 writemmr(SR2, direction ? s1 : s2);
238 writemmr(DR1,direction?d2:d1); 240 writemmr(DR1, direction ? d2 : d1);
239 writemmr(DR2,direction?d1:d2); 241 writemmr(DR2, direction ? d1 : d2);
240} 242}
241 243
242static struct accel_switch accel_blade = { 244static struct accel_switch accel_blade = {
@@ -246,51 +248,72 @@ static struct accel_switch accel_blade = {
246 blade_copy_rect, 248 blade_copy_rect,
247}; 249};
248 250
249
250/* 251/*
251 * BladeXP specific acceleration functions 252 * BladeXP specific acceleration functions
252 */ 253 */
253 254
254#define ROP_P 0xF0 255#define ROP_P 0xF0
255#define masked_point(x,y) ((y & 0xffff)<<16|(x & 0xffff)) 256#define masked_point(x, y) ((y & 0xffff)<<16|(x & 0xffff))
256 257
257static void xp_init_accel(int pitch,int bpp) 258static void xp_init_accel(int pitch, int bpp)
258{ 259{
259 int tmp = 0,v1; 260 int tmp = 0, v1;
260 unsigned char x = 0; 261 unsigned char x = 0;
261 262
262 switch (bpp) { 263 switch (bpp) {
263 case 8: x = 0; break; 264 case 8:
264 case 16: x = 1; break; 265 x = 0;
265 case 24: x = 3; break; 266 break;
266 case 32: x = 2; break; 267 case 16:
268 x = 1;
269 break;
270 case 24:
271 x = 3;
272 break;
273 case 32:
274 x = 2;
275 break;
267 } 276 }
268 277
269 switch (pitch << (bpp >> 3)) { 278 switch (pitch << (bpp >> 3)) {
270 case 8192: 279 case 8192:
271 case 512: x |= 0x00; break; 280 case 512:
272 case 1024: x |= 0x04; break; 281 x |= 0x00;
273 case 2048: x |= 0x08; break; 282 break;
274 case 4096: x |= 0x0C; break; 283 case 1024:
284 x |= 0x04;
285 break;
286 case 2048:
287 x |= 0x08;
288 break;
289 case 4096:
290 x |= 0x0C;
291 break;
275 } 292 }
276 293
277 t_outb(x,0x2125); 294 t_outb(x, 0x2125);
278 295
279 eng_oper = x | 0x40; 296 eng_oper = x | 0x40;
280 297
281 switch (bpp) { 298 switch (bpp) {
282 case 8: tmp = 18; break; 299 case 8:
283 case 15: 300 tmp = 18;
284 case 16: tmp = 19; break; 301 break;
285 case 24: 302 case 15:
286 case 32: tmp = 20; break; 303 case 16:
304 tmp = 19;
305 break;
306 case 24:
307 case 32:
308 tmp = 20;
309 break;
287 } 310 }
288 311
289 v1 = pitch << tmp; 312 v1 = pitch << tmp;
290 313
291 writemmr(0x2154,v1); 314 writemmr(0x2154, v1);
292 writemmr(0x2150,v1); 315 writemmr(0x2150, v1);
293 t_outb(3,0x2126); 316 t_outb(3, 0x2126);
294} 317}
295 318
296static void xp_wait_engine(void) 319static void xp_wait_engine(void)
@@ -318,24 +341,24 @@ static void xp_wait_engine(void)
318 } 341 }
319} 342}
320 343
321static void xp_fill_rect(__u32 x,__u32 y,__u32 w,__u32 h,__u32 c,__u32 rop) 344static void xp_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
322{ 345{
323 writemmr(0x2127,ROP_P); 346 writemmr(0x2127, ROP_P);
324 writemmr(0x2158,c); 347 writemmr(0x2158, c);
325 writemmr(0x2128,0x4000); 348 writemmr(0x2128, 0x4000);
326 writemmr(0x2140,masked_point(h,w)); 349 writemmr(0x2140, masked_point(h, w));
327 writemmr(0x2138,masked_point(y,x)); 350 writemmr(0x2138, masked_point(y, x));
328 t_outb(0x01,0x2124); 351 t_outb(0x01, 0x2124);
329 t_outb(eng_oper,0x2125); 352 t_outb(eng_oper, 0x2125);
330} 353}
331 354
332static void xp_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h) 355static void xp_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
333{ 356{
334 int direction; 357 int direction;
335 __u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp; 358 u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp;
336 359
337 direction = 0x0004; 360 direction = 0x0004;
338 361
339 if ((x1 < x2) && (y1 == y2)) { 362 if ((x1 < x2) && (y1 == y2)) {
340 direction |= 0x0200; 363 direction |= 0x0200;
341 x1_tmp = x1 + w - 1; 364 x1_tmp = x1 + w - 1;
@@ -344,53 +367,60 @@ static void xp_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h)
344 x1_tmp = x1; 367 x1_tmp = x1;
345 x2_tmp = x2; 368 x2_tmp = x2;
346 } 369 }
347 370
348 if (y1 < y2) { 371 if (y1 < y2) {
349 direction |= 0x0100; 372 direction |= 0x0100;
350 y1_tmp = y1 + h - 1; 373 y1_tmp = y1 + h - 1;
351 y2_tmp = y2 + h - 1; 374 y2_tmp = y2 + h - 1;
352 } else { 375 } else {
353 y1_tmp = y1; 376 y1_tmp = y1;
354 y2_tmp = y2; 377 y2_tmp = y2;
355 } 378 }
356 379
357 writemmr(0x2128,direction); 380 writemmr(0x2128, direction);
358 t_outb(ROP_S,0x2127); 381 t_outb(ROP_S, 0x2127);
359 writemmr(0x213C,masked_point(y1_tmp,x1_tmp)); 382 writemmr(0x213C, masked_point(y1_tmp, x1_tmp));
360 writemmr(0x2138,masked_point(y2_tmp,x2_tmp)); 383 writemmr(0x2138, masked_point(y2_tmp, x2_tmp));
361 writemmr(0x2140,masked_point(h,w)); 384 writemmr(0x2140, masked_point(h, w));
362 t_outb(0x01,0x2124); 385 t_outb(0x01, 0x2124);
363} 386}
364 387
365static struct accel_switch accel_xp = { 388static struct accel_switch accel_xp = {
366 xp_init_accel, 389 xp_init_accel,
367 xp_wait_engine, 390 xp_wait_engine,
368 xp_fill_rect, 391 xp_fill_rect,
369 xp_copy_rect, 392 xp_copy_rect,
370}; 393};
371 394
372
373/* 395/*
374 * Image specific acceleration functions 396 * Image specific acceleration functions
375 */ 397 */
376static void image_init_accel(int pitch,int bpp) 398static void image_init_accel(int pitch, int bpp)
377{ 399{
378 int tmp = 0; 400 int tmp = 0;
379 switch (bpp) { 401 switch (bpp) {
380 case 8:tmp = 0;break; 402 case 8:
381 case 15:tmp = 5;break; 403 tmp = 0;
382 case 16:tmp = 1;break; 404 break;
383 case 24: 405 case 15:
384 case 32:tmp = 2;break; 406 tmp = 5;
407 break;
408 case 16:
409 tmp = 1;
410 break;
411 case 24:
412 case 32:
413 tmp = 2;
414 break;
385 } 415 }
386 writemmr(0x2120, 0xF0000000); 416 writemmr(0x2120, 0xF0000000);
387 writemmr(0x2120, 0x40000000|tmp); 417 writemmr(0x2120, 0x40000000 | tmp);
388 writemmr(0x2120, 0x80000000); 418 writemmr(0x2120, 0x80000000);
389 writemmr(0x2144, 0x00000000); 419 writemmr(0x2144, 0x00000000);
390 writemmr(0x2148, 0x00000000); 420 writemmr(0x2148, 0x00000000);
391 writemmr(0x2150, 0x00000000); 421 writemmr(0x2150, 0x00000000);
392 writemmr(0x2154, 0x00000000); 422 writemmr(0x2154, 0x00000000);
393 writemmr(0x2120, 0x60000000|(pitch<<16) |pitch); 423 writemmr(0x2120, 0x60000000 | (pitch << 16) | pitch);
394 writemmr(0x216C, 0x00000000); 424 writemmr(0x216C, 0x00000000);
395 writemmr(0x2170, 0x00000000); 425 writemmr(0x2170, 0x00000000);
396 writemmr(0x217C, 0x00000000); 426 writemmr(0x217C, 0x00000000);
@@ -400,44 +430,43 @@ static void image_init_accel(int pitch,int bpp)
400 430
401static void image_wait_engine(void) 431static void image_wait_engine(void)
402{ 432{
403 while(readmmr(0x2164) & 0xF0000000); 433 while (readmmr(0x2164) & 0xF0000000) ;
404} 434}
405 435
406static void image_fill_rect(__u32 x, __u32 y, __u32 w, __u32 h, __u32 c, __u32 rop) 436static void image_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
407{ 437{
408 writemmr(0x2120,0x80000000); 438 writemmr(0x2120, 0x80000000);
409 writemmr(0x2120,0x90000000|ROP_S); 439 writemmr(0x2120, 0x90000000 | ROP_S);
410 440
411 writemmr(0x2144,c); 441 writemmr(0x2144, c);
412 442
413 writemmr(DR1,point(x,y)); 443 writemmr(DR1, point(x, y));
414 writemmr(DR2,point(x+w-1,y+h-1)); 444 writemmr(DR2, point(x + w - 1, y + h - 1));
415 445
416 writemmr(0x2124,0x80000000|3<<22|1<<10|1<<9); 446 writemmr(0x2124, 0x80000000 | 3 << 22 | 1 << 10 | 1 << 9);
417} 447}
418 448
419static void image_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h) 449static void image_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
420{ 450{
421 __u32 s1,s2,d1,d2; 451 u32 s1, s2, d1, d2;
422 int direction = 2; 452 int direction = 2;
423 s1 = point(x1,y1); 453 s1 = point(x1, y1);
424 s2 = point(x1+w-1,y1+h-1); 454 s2 = point(x1 + w - 1, y1 + h - 1);
425 d1 = point(x2,y2); 455 d1 = point(x2, y2);
426 d2 = point(x2+w-1,y2+h-1); 456 d2 = point(x2 + w - 1, y2 + h - 1);
427
428 if ((y1 > y2) || ((y1 == y2) && (x1 >x2)))
429 direction = 0;
430
431 writemmr(0x2120,0x80000000);
432 writemmr(0x2120,0x90000000|ROP_S);
433
434 writemmr(SR1,direction?s2:s1);
435 writemmr(SR2,direction?s1:s2);
436 writemmr(DR1,direction?d2:d1);
437 writemmr(DR2,direction?d1:d2);
438 writemmr(0x2124,0x80000000|1<<22|1<<10|1<<7|direction);
439}
440 457
458 if ((y1 > y2) || ((y1 == y2) && (x1 > x2)))
459 direction = 0;
460
461 writemmr(0x2120, 0x80000000);
462 writemmr(0x2120, 0x90000000 | ROP_S);
463
464 writemmr(SR1, direction ? s2 : s1);
465 writemmr(SR2, direction ? s1 : s2);
466 writemmr(DR1, direction ? d2 : d1);
467 writemmr(DR2, direction ? d1 : d2);
468 writemmr(0x2124, 0x80000000 | 1 << 22 | 1 << 10 | 1 << 7 | direction);
469}
441 470
442static struct accel_switch accel_image = { 471static struct accel_switch accel_image = {
443 image_init_accel, 472 image_init_accel,
@@ -450,30 +479,34 @@ static struct accel_switch accel_image = {
450 * Accel functions called by the upper layers 479 * Accel functions called by the upper layers
451 */ 480 */
452#ifdef CONFIG_FB_TRIDENT_ACCEL 481#ifdef CONFIG_FB_TRIDENT_ACCEL
453static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr) 482static void tridentfb_fillrect(struct fb_info *info,
483 const struct fb_fillrect *fr)
454{ 484{
455 int bpp = info->var.bits_per_pixel; 485 int bpp = info->var.bits_per_pixel;
456 int col = 0; 486 int col = 0;
457 487
458 switch (bpp) { 488 switch (bpp) {
459 default: 489 default:
460 case 8: col |= fr->color; 490 case 8:
461 col |= col << 8; 491 col |= fr->color;
462 col |= col << 16; 492 col |= col << 8;
463 break; 493 col |= col << 16;
464 case 16: col = ((u32 *)(info->pseudo_palette))[fr->color]; 494 break;
465 495 case 16:
466 break; 496 col = ((u32 *)(info->pseudo_palette))[fr->color];
467 case 32: col = ((u32 *)(info->pseudo_palette))[fr->color]; 497 break;
468 break; 498 case 32:
469 } 499 col = ((u32 *)(info->pseudo_palette))[fr->color];
470 500 break;
501 }
502
471 acc->fill_rect(fr->dx, fr->dy, fr->width, fr->height, col, fr->rop); 503 acc->fill_rect(fr->dx, fr->dy, fr->width, fr->height, col, fr->rop);
472 acc->wait_engine(); 504 acc->wait_engine();
473} 505}
474static void tridentfb_copyarea(struct fb_info *info, const struct fb_copyarea *ca) 506static void tridentfb_copyarea(struct fb_info *info,
507 const struct fb_copyarea *ca)
475{ 508{
476 acc->copy_rect(ca->sx,ca->sy,ca->dx,ca->dy,ca->width,ca->height); 509 acc->copy_rect(ca->sx, ca->sy, ca->dx, ca->dy, ca->width, ca->height);
477 acc->wait_engine(); 510 acc->wait_engine();
478} 511}
479#else /* !CONFIG_FB_TRIDENT_ACCEL */ 512#else /* !CONFIG_FB_TRIDENT_ACCEL */
@@ -488,14 +521,14 @@ static void tridentfb_copyarea(struct fb_info *info, const struct fb_copyarea *c
488 521
489static inline unsigned char read3X4(int reg) 522static inline unsigned char read3X4(int reg)
490{ 523{
491 struct tridentfb_par * par = (struct tridentfb_par *)fb_info.par; 524 struct tridentfb_par *par = (struct tridentfb_par *)fb_info.par;
492 writeb(reg, par->io_virt + CRT + 4); 525 writeb(reg, par->io_virt + CRT + 4);
493 return readb( par->io_virt + CRT + 5); 526 return readb(par->io_virt + CRT + 5);
494} 527}
495 528
496static inline void write3X4(int reg, unsigned char val) 529static inline void write3X4(int reg, unsigned char val)
497{ 530{
498 struct tridentfb_par * par = (struct tridentfb_par *)fb_info.par; 531 struct tridentfb_par *par = (struct tridentfb_par *)fb_info.par;
499 writeb(reg, par->io_virt + CRT + 4); 532 writeb(reg, par->io_virt + CRT + 4);
500 writeb(val, par->io_virt + CRT + 5); 533 writeb(val, par->io_virt + CRT + 5);
501} 534}
@@ -520,7 +553,7 @@ static inline unsigned char read3CE(int reg)
520 553
521static inline void writeAttr(int reg, unsigned char val) 554static inline void writeAttr(int reg, unsigned char val)
522{ 555{
523 readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A); //flip-flop to index 556 readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A); /* flip-flop to index */
524 t_outb(reg, 0x3C0); 557 t_outb(reg, 0x3C0);
525 t_outb(val, 0x3C0); 558 t_outb(val, 0x3C0);
526} 559}
@@ -540,32 +573,41 @@ static inline void enable_mmio(void)
540 /* Unprotect registers */ 573 /* Unprotect registers */
541 outb(NewMode1, 0x3C4); 574 outb(NewMode1, 0x3C4);
542 outb(0x80, 0x3C5); 575 outb(0x80, 0x3C5);
543 576
544 /* Enable MMIO */ 577 /* Enable MMIO */
545 outb(PCIReg, 0x3D4); 578 outb(PCIReg, 0x3D4);
546 outb(inb(0x3D5) | 0x01, 0x3D5); 579 outb(inb(0x3D5) | 0x01, 0x3D5);
547} 580}
548 581
549
550#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) 582#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
551 583
552/* Return flat panel's maximum x resolution */ 584/* Return flat panel's maximum x resolution */
553static int __devinit get_nativex(void) 585static int __devinit get_nativex(void)
554{ 586{
555 int x,y,tmp; 587 int x, y, tmp;
556 588
557 if (nativex) 589 if (nativex)
558 return nativex; 590 return nativex;
559 591
560 tmp = (read3CE(VertStretch) >> 4) & 3; 592 tmp = (read3CE(VertStretch) >> 4) & 3;
561 593
562 switch (tmp) { 594 switch (tmp) {
563 case 0: x = 1280; y = 1024; break; 595 case 0:
564 case 2: x = 1024; y = 768; break; 596 x = 1280; y = 1024;
565 case 3: x = 800; y = 600; break; 597 break;
566 case 4: x = 1400; y = 1050; break; 598 case 2:
567 case 1: 599 x = 1024; y = 768;
568 default:x = 640; y = 480; break; 600 break;
601 case 3:
602 x = 800; y = 600;
603 break;
604 case 4:
605 x = 1400; y = 1050;
606 break;
607 case 1:
608 default:
609 x = 640; y = 480;
610 break;
569 } 611 }
570 612
571 output("%dx%d flat panel found\n", x, y); 613 output("%dx%d flat panel found\n", x, y);
@@ -576,25 +618,26 @@ static int __devinit get_nativex(void)
576static void set_lwidth(int width) 618static void set_lwidth(int width)
577{ 619{
578 write3X4(Offset, width & 0xFF); 620 write3X4(Offset, width & 0xFF);
579 write3X4(AddColReg, (read3X4(AddColReg) & 0xCF) | ((width & 0x300) >>4)); 621 write3X4(AddColReg,
622 (read3X4(AddColReg) & 0xCF) | ((width & 0x300) >> 4));
580} 623}
581 624
582/* For resolutions smaller than FP resolution stretch */ 625/* For resolutions smaller than FP resolution stretch */
583static void screen_stretch(void) 626static void screen_stretch(void)
584{ 627{
585 if (chip_id != CYBERBLADEXPAi1) 628 if (chip_id != CYBERBLADEXPAi1)
586 write3CE(BiosReg,0); 629 write3CE(BiosReg, 0);
587 else 630 else
588 write3CE(BiosReg,8); 631 write3CE(BiosReg, 8);
589 write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 1); 632 write3CE(VertStretch, (read3CE(VertStretch) & 0x7C) | 1);
590 write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 1); 633 write3CE(HorStretch, (read3CE(HorStretch) & 0x7C) | 1);
591} 634}
592 635
593/* For resolutions smaller than FP resolution center */ 636/* For resolutions smaller than FP resolution center */
594static void screen_center(void) 637static void screen_center(void)
595{ 638{
596 write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 0x80); 639 write3CE(VertStretch, (read3CE(VertStretch) & 0x7C) | 0x80);
597 write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 0x80); 640 write3CE(HorStretch, (read3CE(HorStretch) & 0x7C) | 0x80);
598} 641}
599 642
600/* Address of first shown pixel in display memory */ 643/* Address of first shown pixel in display memory */
@@ -602,40 +645,42 @@ static void set_screen_start(int base)
602{ 645{
603 write3X4(StartAddrLow, base & 0xFF); 646 write3X4(StartAddrLow, base & 0xFF);
604 write3X4(StartAddrHigh, (base & 0xFF00) >> 8); 647 write3X4(StartAddrHigh, (base & 0xFF00) >> 8);
605 write3X4(CRTCModuleTest, (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11)); 648 write3X4(CRTCModuleTest,
606 write3X4(CRTHiOrd, (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17)); 649 (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11));
650 write3X4(CRTHiOrd,
651 (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17));
607} 652}
608 653
609/* Use 20.12 fixed-point for NTSC value and frequency calculation */ 654/* Use 20.12 fixed-point for NTSC value and frequency calculation */
610#define calc_freq(n,m,k) ( ((unsigned long)0xE517 * (n+8) / ((m+2)*(1<<k))) >> 12 ) 655#define calc_freq(n, m, k) ( ((unsigned long)0xE517 * (n + 8) / ((m + 2) * (1 << k))) >> 12 )
611 656
612/* Set dotclock frequency */ 657/* Set dotclock frequency */
613static void set_vclk(int freq) 658static void set_vclk(int freq)
614{ 659{
615 int m,n,k; 660 int m, n, k;
616 int f,fi,d,di; 661 int f, fi, d, di;
617 unsigned char lo=0,hi=0; 662 unsigned char lo = 0, hi = 0;
618 663
619 d = 20; 664 d = 20;
620 for(k = 2;k>=0;k--) 665 for (k = 2; k >= 0; k--)
621 for(m = 0;m<63;m++) 666 for (m = 0; m < 63; m++)
622 for(n = 0;n<128;n++) { 667 for (n = 0; n < 128; n++) {
623 fi = calc_freq(n,m,k); 668 fi = calc_freq(n, m, k);
624 if ((di = abs(fi - freq)) < d) { 669 if ((di = abs(fi - freq)) < d) {
625 d = di; 670 d = di;
626 f = fi; 671 f = fi;
627 lo = n; 672 lo = n;
628 hi = (k<<6) | m; 673 hi = (k << 6) | m;
629 } 674 }
630 } 675 }
631 if (chip3D) { 676 if (chip3D) {
632 write3C4(ClockHigh,hi); 677 write3C4(ClockHigh, hi);
633 write3C4(ClockLow,lo); 678 write3C4(ClockLow, lo);
634 } else { 679 } else {
635 outb(lo,0x43C8); 680 outb(lo, 0x43C8);
636 outb(hi,0x43C9); 681 outb(hi, 0x43C9);
637 } 682 }
638 debug("VCLK = %X %X\n",hi,lo); 683 debug("VCLK = %X %X\n", hi, lo);
639} 684}
640 685
641/* Set number of lines for flat panels*/ 686/* Set number of lines for flat panels*/
@@ -663,7 +708,7 @@ static unsigned int __devinit get_displaytype(void)
663 return DISPLAY_FP; 708 return DISPLAY_FP;
664 if (crt || !chipcyber) 709 if (crt || !chipcyber)
665 return DISPLAY_CRT; 710 return DISPLAY_CRT;
666 return (read3CE(FPConfig) & 0x10)?DISPLAY_FP:DISPLAY_CRT; 711 return (read3CE(FPConfig) & 0x10) ? DISPLAY_FP : DISPLAY_CRT;
667} 712}
668 713
669/* Try detecting the video memory size */ 714/* Try detecting the video memory size */
@@ -676,100 +721,136 @@ static unsigned int __devinit get_memsize(void)
676 if (memsize) 721 if (memsize)
677 k = memsize * Kb; 722 k = memsize * Kb;
678 else 723 else
679 switch (chip_id) { 724 switch (chip_id) {
680 case CYBER9525DVD: k = 2560 * Kb; break; 725 case CYBER9525DVD:
726 k = 2560 * Kb;
727 break;
681 default: 728 default:
682 tmp = read3X4(SPR) & 0x0F; 729 tmp = read3X4(SPR) & 0x0F;
683 switch (tmp) { 730 switch (tmp) {
684 731
685 case 0x01: k = 512; break; 732 case 0x01:
686 case 0x02: k = 6 * Mb; break; /* XP */ 733 k = 512;
687 case 0x03: k = 1 * Mb; break; 734 break;
688 case 0x04: k = 8 * Mb; break; 735 case 0x02:
689 case 0x06: k = 10 * Mb; break; /* XP */ 736 k = 6 * Mb; /* XP */
690 case 0x07: k = 2 * Mb; break; 737 break;
691 case 0x08: k = 12 * Mb; break; /* XP */ 738 case 0x03:
692 case 0x0A: k = 14 * Mb; break; /* XP */ 739 k = 1 * Mb;
693 case 0x0C: k = 16 * Mb; break; /* XP */ 740 break;
694 case 0x0E: /* XP */ 741 case 0x04:
695 742 k = 8 * Mb;
696 tmp2 = read3C4(0xC1); 743 break;
697 switch (tmp2) { 744 case 0x06:
698 case 0x00: k = 20 * Mb; break; 745 k = 10 * Mb; /* XP */
699 case 0x01: k = 24 * Mb; break; 746 break;
700 case 0x10: k = 28 * Mb; break; 747 case 0x07:
701 case 0x11: k = 32 * Mb; break; 748 k = 2 * Mb;
702 default: k = 1 * Mb; break; 749 break;
703 } 750 case 0x08:
751 k = 12 * Mb; /* XP */
752 break;
753 case 0x0A:
754 k = 14 * Mb; /* XP */
755 break;
756 case 0x0C:
757 k = 16 * Mb; /* XP */
758 break;
759 case 0x0E: /* XP */
760
761 tmp2 = read3C4(0xC1);
762 switch (tmp2) {
763 case 0x00:
764 k = 20 * Mb;
765 break;
766 case 0x01:
767 k = 24 * Mb;
768 break;
769 case 0x10:
770 k = 28 * Mb;
771 break;
772 case 0x11:
773 k = 32 * Mb;
774 break;
775 default:
776 k = 1 * Mb;
777 break;
778 }
779 break;
780
781 case 0x0F:
782 k = 4 * Mb;
783 break;
784 default:
785 k = 1 * Mb;
704 break; 786 break;
705
706 case 0x0F: k = 4 * Mb; break;
707 default: k = 1 * Mb;
708 } 787 }
709 } 788 }
710 789
711 k -= memdiff * Kb; 790 k -= memdiff * Kb;
712 output("framebuffer size = %d Kb\n", k/Kb); 791 output("framebuffer size = %d Kb\n", k / Kb);
713 return k; 792 return k;
714} 793}
715 794
716/* See if we can handle the video mode described in var */ 795/* See if we can handle the video mode described in var */
717static int tridentfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 796static int tridentfb_check_var(struct fb_var_screeninfo *var,
797 struct fb_info *info)
718{ 798{
719 int bpp = var->bits_per_pixel; 799 int bpp = var->bits_per_pixel;
720 debug("enter\n"); 800 debug("enter\n");
721 801
722 /* check color depth */ 802 /* check color depth */
723 if (bpp == 24 ) 803 if (bpp == 24)
724 bpp = var->bits_per_pixel = 32; 804 bpp = var->bits_per_pixel = 32;
725 /* check whether resolution fits on panel and in memory*/ 805 /* check whether resolution fits on panel and in memory */
726 if (flatpanel && nativex && var->xres > nativex) 806 if (flatpanel && nativex && var->xres > nativex)
727 return -EINVAL; 807 return -EINVAL;
728 if (var->xres * var->yres_virtual * bpp/8 > info->fix.smem_len) 808 if (var->xres * var->yres_virtual * bpp / 8 > info->fix.smem_len)
729 return -EINVAL; 809 return -EINVAL;
730 810
731 switch (bpp) { 811 switch (bpp) {
732 case 8: 812 case 8:
733 var->red.offset = 0; 813 var->red.offset = 0;
734 var->green.offset = 0; 814 var->green.offset = 0;
735 var->blue.offset = 0; 815 var->blue.offset = 0;
736 var->red.length = 6; 816 var->red.length = 6;
737 var->green.length = 6; 817 var->green.length = 6;
738 var->blue.length = 6; 818 var->blue.length = 6;
739 break; 819 break;
740 case 16: 820 case 16:
741 var->red.offset = 11; 821 var->red.offset = 11;
742 var->green.offset = 5; 822 var->green.offset = 5;
743 var->blue.offset = 0; 823 var->blue.offset = 0;
744 var->red.length = 5; 824 var->red.length = 5;
745 var->green.length = 6; 825 var->green.length = 6;
746 var->blue.length = 5; 826 var->blue.length = 5;
747 break; 827 break;
748 case 32: 828 case 32:
749 var->red.offset = 16; 829 var->red.offset = 16;
750 var->green.offset = 8; 830 var->green.offset = 8;
751 var->blue.offset = 0; 831 var->blue.offset = 0;
752 var->red.length = 8; 832 var->red.length = 8;
753 var->green.length = 8; 833 var->green.length = 8;
754 var->blue.length = 8; 834 var->blue.length = 8;
755 break; 835 break;
756 default: 836 default:
757 return -EINVAL; 837 return -EINVAL;
758 } 838 }
759 debug("exit\n"); 839 debug("exit\n");
760 840
761 return 0; 841 return 0;
762 842
763} 843}
844
764/* Pan the display */ 845/* Pan the display */
765static int tridentfb_pan_display(struct fb_var_screeninfo *var, 846static int tridentfb_pan_display(struct fb_var_screeninfo *var,
766 struct fb_info *info) 847 struct fb_info *info)
767{ 848{
768 unsigned int offset; 849 unsigned int offset;
769 850
770 debug("enter\n"); 851 debug("enter\n");
771 offset = (var->xoffset + (var->yoffset * var->xres)) 852 offset = (var->xoffset + (var->yoffset * var->xres))
772 * var->bits_per_pixel/32; 853 * var->bits_per_pixel / 32;
773 info->var.xoffset = var->xoffset; 854 info->var.xoffset = var->xoffset;
774 info->var.yoffset = var->yoffset; 855 info->var.yoffset = var->yoffset;
775 set_screen_start(offset); 856 set_screen_start(offset);
@@ -777,36 +858,38 @@ static int tridentfb_pan_display(struct fb_var_screeninfo *var,
777 return 0; 858 return 0;
778} 859}
779 860
780#define shadowmode_on() write3CE(CyberControl,read3CE(CyberControl) | 0x81) 861#define shadowmode_on() write3CE(CyberControl, read3CE(CyberControl) | 0x81)
781#define shadowmode_off() write3CE(CyberControl,read3CE(CyberControl) & 0x7E) 862#define shadowmode_off() write3CE(CyberControl, read3CE(CyberControl) & 0x7E)
782 863
783/* Set the hardware to the requested video mode */ 864/* Set the hardware to the requested video mode */
784static int tridentfb_set_par(struct fb_info *info) 865static int tridentfb_set_par(struct fb_info *info)
785{ 866{
786 struct tridentfb_par * par = (struct tridentfb_par *)(info->par); 867 struct tridentfb_par *par = (struct tridentfb_par *)(info->par);
787 u32 htotal,hdispend,hsyncstart,hsyncend,hblankstart,hblankend, 868 u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend;
788 vtotal,vdispend,vsyncstart,vsyncend,vblankstart,vblankend; 869 u32 vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend;
789 struct fb_var_screeninfo *var = &info->var; 870 struct fb_var_screeninfo *var = &info->var;
790 int bpp = var->bits_per_pixel; 871 int bpp = var->bits_per_pixel;
791 unsigned char tmp; 872 unsigned char tmp;
792 debug("enter\n"); 873 debug("enter\n");
793 htotal = (var->xres + var->left_margin + var->right_margin + var->hsync_len)/8 - 10; 874 hdispend = var->xres / 8 - 1;
794 hdispend = var->xres/8 - 1; 875 hsyncstart = (var->xres + var->right_margin) / 8;
795 hsyncstart = (var->xres + var->right_margin)/8; 876 hsyncend = var->hsync_len / 8;
796 hsyncend = var->hsync_len/8; 877 htotal =
878 (var->xres + var->left_margin + var->right_margin +
879 var->hsync_len) / 8 - 10;
797 hblankstart = hdispend + 1; 880 hblankstart = hdispend + 1;
798 hblankend = htotal + 5; 881 hblankend = htotal + 5;
799 882
800 vtotal = var->yres + var->upper_margin + var->lower_margin + var->vsync_len - 2;
801 vdispend = var->yres - 1; 883 vdispend = var->yres - 1;
802 vsyncstart = var->yres + var->lower_margin; 884 vsyncstart = var->yres + var->lower_margin;
803 vsyncend = var->vsync_len; 885 vsyncend = var->vsync_len;
886 vtotal = var->upper_margin + vsyncstart + vsyncend - 2;
804 vblankstart = var->yres; 887 vblankstart = var->yres;
805 vblankend = vtotal + 2; 888 vblankend = vtotal + 2;
806 889
807 enable_mmio(); 890 enable_mmio();
808 crtc_unlock(); 891 crtc_unlock();
809 write3CE(CyberControl,8); 892 write3CE(CyberControl, 8);
810 893
811 if (flatpanel && var->xres < nativex) { 894 if (flatpanel && var->xres < nativex) {
812 /* 895 /*
@@ -814,18 +897,18 @@ static int tridentfb_set_par(struct fb_info *info)
814 * than requested resolution decide whether 897 * than requested resolution decide whether
815 * we stretch or center 898 * we stretch or center
816 */ 899 */
817 t_outb(0xEB,0x3C2); 900 t_outb(0xEB, 0x3C2);
818 901
819 shadowmode_on(); 902 shadowmode_on();
820 903
821 if (center) 904 if (center)
822 screen_center(); 905 screen_center();
823 else if (stretch) 906 else if (stretch)
824 screen_stretch(); 907 screen_stretch();
825 908
826 } else { 909 } else {
827 t_outb(0x2B,0x3C2); 910 t_outb(0x2B, 0x3C2);
828 write3CE(CyberControl,8); 911 write3CE(CyberControl, 8);
829 } 912 }
830 913
831 /* vertical timing values */ 914 /* vertical timing values */
@@ -834,15 +917,15 @@ static int tridentfb_set_par(struct fb_info *info)
834 write3X4(CRTVSyncStart, vsyncstart & 0xFF); 917 write3X4(CRTVSyncStart, vsyncstart & 0xFF);
835 write3X4(CRTVSyncEnd, (vsyncend & 0x0F)); 918 write3X4(CRTVSyncEnd, (vsyncend & 0x0F));
836 write3X4(CRTVBlankStart, vblankstart & 0xFF); 919 write3X4(CRTVBlankStart, vblankstart & 0xFF);
837 write3X4(CRTVBlankEnd, 0/*p->vblankend & 0xFF*/); 920 write3X4(CRTVBlankEnd, 0 /* p->vblankend & 0xFF */ );
838 921
839 /* horizontal timing values */ 922 /* horizontal timing values */
840 write3X4(CRTHTotal, htotal & 0xFF); 923 write3X4(CRTHTotal, htotal & 0xFF);
841 write3X4(CRTHDispEnd, hdispend & 0xFF); 924 write3X4(CRTHDispEnd, hdispend & 0xFF);
842 write3X4(CRTHSyncStart, hsyncstart & 0xFF); 925 write3X4(CRTHSyncStart, hsyncstart & 0xFF);
843 write3X4(CRTHSyncEnd, (hsyncend & 0x1F) | ((hblankend & 0x20)<<2)); 926 write3X4(CRTHSyncEnd, (hsyncend & 0x1F) | ((hblankend & 0x20) << 2));
844 write3X4(CRTHBlankStart, hblankstart & 0xFF); 927 write3X4(CRTHBlankStart, hblankstart & 0xFF);
845 write3X4(CRTHBlankEnd, 0/*(p->hblankend & 0x1F)*/); 928 write3X4(CRTHBlankEnd, 0 /* (p->hblankend & 0x1F) */ );
846 929
847 /* higher bits of vertical timing values */ 930 /* higher bits of vertical timing values */
848 tmp = 0x10; 931 tmp = 0x10;
@@ -856,7 +939,7 @@ static int tridentfb_set_par(struct fb_info *info)
856 if (vsyncstart & 0x200) tmp |= 0x80; 939 if (vsyncstart & 0x200) tmp |= 0x80;
857 write3X4(CRTOverflow, tmp); 940 write3X4(CRTOverflow, tmp);
858 941
859 tmp = read3X4(CRTHiOrd) | 0x08; //line compare bit 10 942 tmp = read3X4(CRTHiOrd) | 0x08; /* line compare bit 10 */
860 if (vtotal & 0x400) tmp |= 0x80; 943 if (vtotal & 0x400) tmp |= 0x80;
861 if (vblankstart & 0x400) tmp |= 0x40; 944 if (vblankstart & 0x400) tmp |= 0x40;
862 if (vsyncstart & 0x400) tmp |= 0x20; 945 if (vsyncstart & 0x400) tmp |= 0x20;
@@ -867,84 +950,100 @@ static int tridentfb_set_par(struct fb_info *info)
867 if (htotal & 0x800) tmp |= 0x800 >> 11; 950 if (htotal & 0x800) tmp |= 0x800 >> 11;
868 if (hblankstart & 0x800) tmp |= 0x800 >> 7; 951 if (hblankstart & 0x800) tmp |= 0x800 >> 7;
869 write3X4(HorizOverflow, tmp); 952 write3X4(HorizOverflow, tmp);
870 953
871 tmp = 0x40; 954 tmp = 0x40;
872 if (vblankstart & 0x200) tmp |= 0x20; 955 if (vblankstart & 0x200) tmp |= 0x20;
873//FIXME if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; //double scan for 200 line modes 956//FIXME if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; /* double scan for 200 line modes */
874 write3X4(CRTMaxScanLine, tmp); 957 write3X4(CRTMaxScanLine, tmp);
875 958
876 write3X4(CRTLineCompare,0xFF); 959 write3X4(CRTLineCompare, 0xFF);
877 write3X4(CRTPRowScan,0); 960 write3X4(CRTPRowScan, 0);
878 write3X4(CRTModeControl,0xC3); 961 write3X4(CRTModeControl, 0xC3);
879 962
880 write3X4(LinearAddReg,0x20); //enable linear addressing 963 write3X4(LinearAddReg, 0x20); /* enable linear addressing */
881 964
882 tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84:0x80; 965 tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80;
883 write3X4(CRTCModuleTest,tmp); //enable access extended memory 966 write3X4(CRTCModuleTest, tmp); /* enable access extended memory */
884 967
885 write3X4(GraphEngReg, 0x80); //enable GE for text acceleration 968 write3X4(GraphEngReg, 0x80); /* enable GE for text acceleration */
886 969
887#ifdef CONFIG_FB_TRIDENT_ACCEL 970#ifdef CONFIG_FB_TRIDENT_ACCEL
888 acc->init_accel(info->var.xres,bpp); 971 acc->init_accel(info->var.xres, bpp);
889#endif 972#endif
890 973
891 switch (bpp) { 974 switch (bpp) {
892 case 8: tmp = 0x00; break; 975 case 8:
893 case 16: tmp = 0x05; break; 976 tmp = 0x00;
894 case 24: tmp = 0x29; break; 977 break;
895 case 32: tmp = 0x09; 978 case 16:
979 tmp = 0x05;
980 break;
981 case 24:
982 tmp = 0x29;
983 break;
984 case 32:
985 tmp = 0x09;
986 break;
896 } 987 }
897 988
898 write3X4(PixelBusReg, tmp); 989 write3X4(PixelBusReg, tmp);
899 990
900 tmp = 0x10; 991 tmp = 0x10;
901 if (chipcyber) 992 if (chipcyber)
902 tmp |= 0x20; 993 tmp |= 0x20;
903 write3X4(DRAMControl, tmp); //both IO,linear enable 994 write3X4(DRAMControl, tmp); /* both IO, linear enable */
904 995
905 write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40); 996 write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40);
906 write3X4(Performance,0x92); 997 write3X4(Performance, 0x92);
907 write3X4(PCIReg,0x07); //MMIO & PCI read and write burst enable 998 write3X4(PCIReg, 0x07); /* MMIO & PCI read and write burst enable */
908 999
909 /* convert from picoseconds to MHz */ 1000 /* convert from picoseconds to MHz */
910 par->vclk = 1000000/info->var.pixclock; 1001 par->vclk = 1000000 / info->var.pixclock;
911 if (bpp == 32) 1002 if (bpp == 32)
912 par->vclk *=2; 1003 par->vclk *= 2;
913 set_vclk(par->vclk); 1004 set_vclk(par->vclk);
914 1005
915 write3C4(0,3); 1006 write3C4(0, 3);
916 write3C4(1,1); //set char clock 8 dots wide 1007 write3C4(1, 1); /* set char clock 8 dots wide */
917 write3C4(2,0x0F); //enable 4 maps because needed in chain4 mode 1008 write3C4(2, 0x0F); /* enable 4 maps because needed in chain4 mode */
918 write3C4(3,0); 1009 write3C4(3, 0);
919 write3C4(4,0x0E); //memory mode enable bitmaps ?? 1010 write3C4(4, 0x0E); /* memory mode enable bitmaps ?? */
920 1011
921 write3CE(MiscExtFunc,(bpp==32)?0x1A:0x12); //divide clock by 2 if 32bpp 1012 write3CE(MiscExtFunc, (bpp == 32) ? 0x1A : 0x12); /* divide clock by 2 if 32bpp */
922 //chain4 mode display and CPU path 1013 /* chain4 mode display and CPU path */
923 write3CE(0x5,0x40); //no CGA compat,allow 256 col 1014 write3CE(0x5, 0x40); /* no CGA compat, allow 256 col */
924 write3CE(0x6,0x05); //graphics mode 1015 write3CE(0x6, 0x05); /* graphics mode */
925 write3CE(0x7,0x0F); //planes? 1016 write3CE(0x7, 0x0F); /* planes? */
926 1017
927 if (chip_id == CYBERBLADEXPAi1) { 1018 if (chip_id == CYBERBLADEXPAi1) {
928 /* This fixes snow-effect in 32 bpp */ 1019 /* This fixes snow-effect in 32 bpp */
929 write3X4(CRTHSyncStart,0x84); 1020 write3X4(CRTHSyncStart, 0x84);
930 } 1021 }
931 1022
932 writeAttr(0x10,0x41); //graphics mode and support 256 color modes 1023 writeAttr(0x10, 0x41); /* graphics mode and support 256 color modes */
933 writeAttr(0x12,0x0F); //planes 1024 writeAttr(0x12, 0x0F); /* planes */
934 writeAttr(0x13,0); //horizontal pel panning 1025 writeAttr(0x13, 0); /* horizontal pel panning */
935 1026
936 //colors 1027 /* colors */
937 for(tmp = 0;tmp < 0x10;tmp++) 1028 for (tmp = 0; tmp < 0x10; tmp++)
938 writeAttr(tmp,tmp); 1029 writeAttr(tmp, tmp);
939 readb(par->io_virt + CRT + 0x0A); //flip-flop to index 1030 readb(par->io_virt + CRT + 0x0A); /* flip-flop to index */
940 t_outb(0x20, 0x3C0); //enable attr 1031 t_outb(0x20, 0x3C0); /* enable attr */
941 1032
942 switch (bpp) { 1033 switch (bpp) {
943 case 8: tmp = 0;break; //256 colors 1034 case 8:
944 case 15: tmp = 0x10;break; 1035 tmp = 0;
945 case 16: tmp = 0x30;break; //hicolor 1036 break;
946 case 24: //truecolor 1037 case 15:
947 case 32: tmp = 0xD0;break; 1038 tmp = 0x10;
1039 break;
1040 case 16:
1041 tmp = 0x30;
1042 break;
1043 case 24:
1044 case 32:
1045 tmp = 0xD0;
1046 break;
948 } 1047 }
949 1048
950 t_inb(0x3C8); 1049 t_inb(0x3C8);
@@ -952,37 +1051,36 @@ static int tridentfb_set_par(struct fb_info *info)
952 t_inb(0x3C6); 1051 t_inb(0x3C6);
953 t_inb(0x3C6); 1052 t_inb(0x3C6);
954 t_inb(0x3C6); 1053 t_inb(0x3C6);
955 t_outb(tmp,0x3C6); 1054 t_outb(tmp, 0x3C6);
956 t_inb(0x3C8); 1055 t_inb(0x3C8);
957 1056
958 if (flatpanel) 1057 if (flatpanel)
959 set_number_of_lines(info->var.yres); 1058 set_number_of_lines(info->var.yres);
960 set_lwidth(info->var.xres * bpp/(4*16)); 1059 set_lwidth(info->var.xres * bpp / (4 * 16));
961 info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 1060 info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
962 info->fix.line_length = info->var.xres * (bpp >> 3); 1061 info->fix.line_length = info->var.xres * (bpp >> 3);
963 info->cmap.len = (bpp == 8) ? 256: 16; 1062 info->cmap.len = (bpp == 8) ? 256 : 16;
964 debug("exit\n"); 1063 debug("exit\n");
965 return 0; 1064 return 0;
966} 1065}
967 1066
968/* Set one color register */ 1067/* Set one color register */
969static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green, 1068static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
970 unsigned blue, unsigned transp, 1069 unsigned blue, unsigned transp,
971 struct fb_info *info) 1070 struct fb_info *info)
972{ 1071{
973 int bpp = info->var.bits_per_pixel; 1072 int bpp = info->var.bits_per_pixel;
974 1073
975 if (regno >= info->cmap.len) 1074 if (regno >= info->cmap.len)
976 return 1; 1075 return 1;
977 1076
978
979 if (bpp == 8) { 1077 if (bpp == 8) {
980 t_outb(0xFF,0x3C6); 1078 t_outb(0xFF, 0x3C6);
981 t_outb(regno,0x3C8); 1079 t_outb(regno, 0x3C8);
982 1080
983 t_outb(red>>10,0x3C9); 1081 t_outb(red >> 10, 0x3C9);
984 t_outb(green>>10,0x3C9); 1082 t_outb(green >> 10, 0x3C9);
985 t_outb(blue>>10,0x3C9); 1083 t_outb(blue >> 10, 0x3C9);
986 1084
987 } else if (regno < 16) { 1085 } else if (regno < 16) {
988 if (bpp == 16) { /* RGB 565 */ 1086 if (bpp == 16) { /* RGB 565 */
@@ -994,29 +1092,28 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
994 ((u32 *)(info->pseudo_palette))[regno] = col; 1092 ((u32 *)(info->pseudo_palette))[regno] = col;
995 } else if (bpp == 32) /* ARGB 8888 */ 1093 } else if (bpp == 32) /* ARGB 8888 */
996 ((u32*)info->pseudo_palette)[regno] = 1094 ((u32*)info->pseudo_palette)[regno] =
997 ((transp & 0xFF00) <<16) | 1095 ((transp & 0xFF00) << 16) |
998 ((red & 0xFF00) << 8) | 1096 ((red & 0xFF00) << 8) |
999 ((green & 0xFF00)) | 1097 ((green & 0xFF00)) |
1000 ((blue & 0xFF00)>>8); 1098 ((blue & 0xFF00) >> 8);
1001 } 1099 }
1002 1100
1003// debug("exit\n"); 1101/* debug("exit\n"); */
1004 return 0; 1102 return 0;
1005} 1103}
1006 1104
1007/* Try blanking the screen.For flat panels it does nothing */ 1105/* Try blanking the screen.For flat panels it does nothing */
1008static int tridentfb_blank(int blank_mode, struct fb_info *info) 1106static int tridentfb_blank(int blank_mode, struct fb_info *info)
1009{ 1107{
1010 unsigned char PMCont,DPMSCont; 1108 unsigned char PMCont, DPMSCont;
1011 1109
1012 debug("enter\n"); 1110 debug("enter\n");
1013 if (flatpanel) 1111 if (flatpanel)
1014 return 0; 1112 return 0;
1015 t_outb(0x04,0x83C8); /* Read DPMS Control */ 1113 t_outb(0x04, 0x83C8); /* Read DPMS Control */
1016 PMCont = t_inb(0x83C6) & 0xFC; 1114 PMCont = t_inb(0x83C6) & 0xFC;
1017 DPMSCont = read3CE(PowerStatus) & 0xFC; 1115 DPMSCont = read3CE(PowerStatus) & 0xFC;
1018 switch (blank_mode) 1116 switch (blank_mode) {
1019 {
1020 case FB_BLANK_UNBLANK: 1117 case FB_BLANK_UNBLANK:
1021 /* Screen: On, HSync: On, VSync: On */ 1118 /* Screen: On, HSync: On, VSync: On */
1022 case FB_BLANK_NORMAL: 1119 case FB_BLANK_NORMAL:
@@ -1039,11 +1136,11 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info)
1039 PMCont |= 0x00; 1136 PMCont |= 0x00;
1040 DPMSCont |= 0x03; 1137 DPMSCont |= 0x03;
1041 break; 1138 break;
1042 } 1139 }
1043 1140
1044 write3CE(PowerStatus,DPMSCont); 1141 write3CE(PowerStatus, DPMSCont);
1045 t_outb(4,0x83C8); 1142 t_outb(4, 0x83C8);
1046 t_outb(PMCont,0x83C6); 1143 t_outb(PMCont, 0x83C6);
1047 1144
1048 debug("exit\n"); 1145 debug("exit\n");
1049 1146
@@ -1051,7 +1148,20 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info)
1051 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0; 1148 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1052} 1149}
1053 1150
1054static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_device_id * id) 1151static struct fb_ops tridentfb_ops = {
1152 .owner = THIS_MODULE,
1153 .fb_setcolreg = tridentfb_setcolreg,
1154 .fb_pan_display = tridentfb_pan_display,
1155 .fb_blank = tridentfb_blank,
1156 .fb_check_var = tridentfb_check_var,
1157 .fb_set_par = tridentfb_set_par,
1158 .fb_fillrect = tridentfb_fillrect,
1159 .fb_copyarea = tridentfb_copyarea,
1160 .fb_imageblit = cfb_imageblit,
1161};
1162
1163static int __devinit trident_pci_probe(struct pci_dev * dev,
1164 const struct pci_device_id * id)
1055{ 1165{
1056 int err; 1166 int err;
1057 unsigned char revision; 1167 unsigned char revision;
@@ -1062,31 +1172,42 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1062 1172
1063 chip_id = id->device; 1173 chip_id = id->device;
1064 1174
1065 if(chip_id == CYBERBLADEi1) 1175 if (chip_id == CYBERBLADEi1)
1066 output("*** Please do use cyblafb, Cyberblade/i1 support " 1176 output("*** Please do use cyblafb, Cyberblade/i1 support "
1067 "will soon be removed from tridentfb!\n"); 1177 "will soon be removed from tridentfb!\n");
1068 1178
1069 1179
1070 /* If PCI id is 0x9660 then further detect chip type */ 1180 /* If PCI id is 0x9660 then further detect chip type */
1071 1181
1072 if (chip_id == TGUI9660) { 1182 if (chip_id == TGUI9660) {
1073 outb(RevisionID,0x3C4); 1183 outb(RevisionID, 0x3C4);
1074 revision = inb(0x3C5); 1184 revision = inb(0x3C5);
1075 1185
1076 switch (revision) { 1186 switch (revision) {
1077 case 0x22: 1187 case 0x22:
1078 case 0x23: chip_id = CYBER9397;break; 1188 case 0x23:
1079 case 0x2A: chip_id = CYBER9397DVD;break; 1189 chip_id = CYBER9397;
1080 case 0x30: 1190 break;
1081 case 0x33: 1191 case 0x2A:
1082 case 0x34: 1192 chip_id = CYBER9397DVD;
1083 case 0x35: 1193 break;
1084 case 0x38: 1194 case 0x30:
1085 case 0x3A: 1195 case 0x33:
1086 case 0xB3: chip_id = CYBER9385;break; 1196 case 0x34:
1087 case 0x40 ... 0x43: chip_id = CYBER9382;break; 1197 case 0x35:
1088 case 0x4A: chip_id = CYBER9388;break; 1198 case 0x38:
1089 default:break; 1199 case 0x3A:
1200 case 0xB3:
1201 chip_id = CYBER9385;
1202 break;
1203 case 0x40 ... 0x43:
1204 chip_id = CYBER9382;
1205 break;
1206 case 0x4A:
1207 chip_id = CYBER9388;
1208 break;
1209 default:
1210 break;
1090 } 1211 }
1091 } 1212 }
1092 1213
@@ -1095,8 +1216,7 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1095 1216
1096 if (is_xp(chip_id)) { 1217 if (is_xp(chip_id)) {
1097 acc = &accel_xp; 1218 acc = &accel_xp;
1098 } else 1219 } else if (is_blade(chip_id)) {
1099 if (is_blade(chip_id)) {
1100 acc = &accel_blade; 1220 acc = &accel_blade;
1101 } else { 1221 } else {
1102 acc = &accel_image; 1222 acc = &accel_image;
@@ -1108,8 +1228,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1108 fb_info.par = &default_par; 1228 fb_info.par = &default_par;
1109 1229
1110 /* setup MMIO region */ 1230 /* setup MMIO region */
1111 tridentfb_fix.mmio_start = pci_resource_start(dev,1); 1231 tridentfb_fix.mmio_start = pci_resource_start(dev, 1);
1112 tridentfb_fix.mmio_len = chip3D ? 0x20000:0x10000; 1232 tridentfb_fix.mmio_len = chip3D ? 0x20000 : 0x10000;
1113 1233
1114 if (!request_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len, "tridentfb")) { 1234 if (!request_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len, "tridentfb")) {
1115 debug("request_region failed!\n"); 1235 debug("request_region failed!\n");
@@ -1125,11 +1245,11 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1125 } 1245 }
1126 1246
1127 enable_mmio(); 1247 enable_mmio();
1128 1248
1129 /* setup framebuffer memory */ 1249 /* setup framebuffer memory */
1130 tridentfb_fix.smem_start = pci_resource_start(dev,0); 1250 tridentfb_fix.smem_start = pci_resource_start(dev, 0);
1131 tridentfb_fix.smem_len = get_memsize(); 1251 tridentfb_fix.smem_len = get_memsize();
1132 1252
1133 if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { 1253 if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) {
1134 debug("request_mem_region failed!\n"); 1254 debug("request_mem_region failed!\n");
1135 err = -1; 1255 err = -1;
@@ -1137,7 +1257,7 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1137 } 1257 }
1138 1258
1139 fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, 1259 fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start,
1140 tridentfb_fix.smem_len); 1260 tridentfb_fix.smem_len);
1141 1261
1142 if (!fb_info.screen_base) { 1262 if (!fb_info.screen_base) {
1143 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); 1263 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
@@ -1147,13 +1267,13 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1147 } 1267 }
1148 1268
1149 output("%s board found\n", pci_name(dev)); 1269 output("%s board found\n", pci_name(dev));
1150#if 0 1270#if 0
1151 output("Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X\n", 1271 output("Trident board found : mem = %X, io = %X, mem_v = %X, io_v = %X\n",
1152 tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt); 1272 tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt);
1153#endif 1273#endif
1154 displaytype = get_displaytype(); 1274 displaytype = get_displaytype();
1155 1275
1156 if(flatpanel) 1276 if (flatpanel)
1157 nativex = get_nativex(); 1277 nativex = get_nativex();
1158 1278
1159 fb_info.fix = tridentfb_fix; 1279 fb_info.fix = tridentfb_fix;
@@ -1166,11 +1286,11 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1166#endif 1286#endif
1167 fb_info.pseudo_palette = pseudo_pal; 1287 fb_info.pseudo_palette = pseudo_pal;
1168 1288
1169 if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp)) { 1289 if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) {
1170 err = -EINVAL; 1290 err = -EINVAL;
1171 goto out_unmap; 1291 goto out_unmap;
1172 } 1292 }
1173 fb_alloc_cmap(&fb_info.cmap,256,0); 1293 fb_alloc_cmap(&fb_info.cmap, 256, 0);
1174 if (defaultaccel && acc) 1294 if (defaultaccel && acc)
1175 default_var.accel_flags |= FB_ACCELF_TEXT; 1295 default_var.accel_flags |= FB_ACCELF_TEXT;
1176 else 1296 else
@@ -1184,8 +1304,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1184 goto out_unmap; 1304 goto out_unmap;
1185 } 1305 }
1186 output("fb%d: %s frame buffer device %dx%d-%dbpp\n", 1306 output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
1187 fb_info.node, fb_info.fix.id,default_var.xres, 1307 fb_info.node, fb_info.fix.id, default_var.xres,
1188 default_var.yres,default_var.bits_per_pixel); 1308 default_var.yres, default_var.bits_per_pixel);
1189 return 0; 1309 return 0;
1190 1310
1191out_unmap: 1311out_unmap:
@@ -1196,7 +1316,7 @@ out_unmap:
1196 return err; 1316 return err;
1197} 1317}
1198 1318
1199static void __devexit trident_pci_remove(struct pci_dev * dev) 1319static void __devexit trident_pci_remove(struct pci_dev *dev)
1200{ 1320{
1201 struct tridentfb_par *par = (struct tridentfb_par*)fb_info.par; 1321 struct tridentfb_par *par = (struct tridentfb_par*)fb_info.par;
1202 unregister_framebuffer(&fb_info); 1322 unregister_framebuffer(&fb_info);
@@ -1208,69 +1328,70 @@ static void __devexit trident_pci_remove(struct pci_dev * dev)
1208 1328
1209/* List of boards that we are trying to support */ 1329/* List of boards that we are trying to support */
1210static struct pci_device_id trident_devices[] = { 1330static struct pci_device_id trident_devices[] = {
1211 {PCI_VENDOR_ID_TRIDENT, BLADE3D, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1331 {PCI_VENDOR_ID_TRIDENT, BLADE3D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1212 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1332 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1213 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7D, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1333 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1214 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1334 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1215 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1335 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1216 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1336 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1217 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1337 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1218 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEE4, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1338 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEE4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1219 {PCI_VENDOR_ID_TRIDENT, TGUI9660, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1339 {PCI_VENDOR_ID_TRIDENT, TGUI9660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1220 {PCI_VENDOR_ID_TRIDENT, IMAGE975, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1340 {PCI_VENDOR_ID_TRIDENT, IMAGE975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1221 {PCI_VENDOR_ID_TRIDENT, IMAGE985, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1341 {PCI_VENDOR_ID_TRIDENT, IMAGE985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1222 {PCI_VENDOR_ID_TRIDENT, CYBER9320, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1342 {PCI_VENDOR_ID_TRIDENT, CYBER9320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1223 {PCI_VENDOR_ID_TRIDENT, CYBER9388, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1343 {PCI_VENDOR_ID_TRIDENT, CYBER9388, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1224 {PCI_VENDOR_ID_TRIDENT, CYBER9520, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1344 {PCI_VENDOR_ID_TRIDENT, CYBER9520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1225 {PCI_VENDOR_ID_TRIDENT, CYBER9525DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1345 {PCI_VENDOR_ID_TRIDENT, CYBER9525DVD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1226 {PCI_VENDOR_ID_TRIDENT, CYBER9397, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1346 {PCI_VENDOR_ID_TRIDENT, CYBER9397, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1227 {PCI_VENDOR_ID_TRIDENT, CYBER9397DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1347 {PCI_VENDOR_ID_TRIDENT, CYBER9397DVD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1228 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1348 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPAi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1229 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm8, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1349 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1230 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm16, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1350 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm16, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1231 {0,} 1351 {0,}
1232}; 1352};
1233 1353
1234MODULE_DEVICE_TABLE(pci,trident_devices); 1354MODULE_DEVICE_TABLE(pci, trident_devices);
1235 1355
1236static struct pci_driver tridentfb_pci_driver = { 1356static struct pci_driver tridentfb_pci_driver = {
1237 .name = "tridentfb", 1357 .name = "tridentfb",
1238 .id_table = trident_devices, 1358 .id_table = trident_devices,
1239 .probe = trident_pci_probe, 1359 .probe = trident_pci_probe,
1240 .remove = __devexit_p(trident_pci_remove) 1360 .remove = __devexit_p(trident_pci_remove)
1241}; 1361};
1242 1362
1243/* 1363/*
1244 * Parse user specified options (`video=trident:') 1364 * Parse user specified options (`video=trident:')
1245 * example: 1365 * example:
1246 * video=trident:800x600,bpp=16,noaccel 1366 * video=trident:800x600,bpp=16,noaccel
1247 */ 1367 */
1248#ifndef MODULE 1368#ifndef MODULE
1249static int tridentfb_setup(char *options) 1369static int tridentfb_setup(char *options)
1250{ 1370{
1251 char * opt; 1371 char *opt;
1252 if (!options || !*options) 1372 if (!options || !*options)
1253 return 0; 1373 return 0;
1254 while((opt = strsep(&options,",")) != NULL ) { 1374 while ((opt = strsep(&options, ",")) != NULL) {
1255 if (!*opt) continue; 1375 if (!*opt)
1256 if (!strncmp(opt,"noaccel",7)) 1376 continue;
1377 if (!strncmp(opt, "noaccel", 7))
1257 noaccel = 1; 1378 noaccel = 1;
1258 else if (!strncmp(opt,"fp",2)) 1379 else if (!strncmp(opt, "fp", 2))
1259 displaytype = DISPLAY_FP; 1380 displaytype = DISPLAY_FP;
1260 else if (!strncmp(opt,"crt",3)) 1381 else if (!strncmp(opt, "crt", 3))
1261 displaytype = DISPLAY_CRT; 1382 displaytype = DISPLAY_CRT;
1262 else if (!strncmp(opt,"bpp=",4)) 1383 else if (!strncmp(opt, "bpp=", 4))
1263 bpp = simple_strtoul(opt+4,NULL,0); 1384 bpp = simple_strtoul(opt + 4, NULL, 0);
1264 else if (!strncmp(opt,"center",6)) 1385 else if (!strncmp(opt, "center", 6))
1265 center = 1; 1386 center = 1;
1266 else if (!strncmp(opt,"stretch",7)) 1387 else if (!strncmp(opt, "stretch", 7))
1267 stretch = 1; 1388 stretch = 1;
1268 else if (!strncmp(opt,"memsize=",8)) 1389 else if (!strncmp(opt, "memsize=", 8))
1269 memsize = simple_strtoul(opt+8,NULL,0); 1390 memsize = simple_strtoul(opt + 8, NULL, 0);
1270 else if (!strncmp(opt,"memdiff=",8)) 1391 else if (!strncmp(opt, "memdiff=", 8))
1271 memdiff = simple_strtoul(opt+8,NULL,0); 1392 memdiff = simple_strtoul(opt + 8, NULL, 0);
1272 else if (!strncmp(opt,"nativex=",8)) 1393 else if (!strncmp(opt, "nativex=", 8))
1273 nativex = simple_strtoul(opt+8,NULL,0); 1394 nativex = simple_strtoul(opt + 8, NULL, 0);
1274 else 1395 else
1275 mode = opt; 1396 mode = opt;
1276 } 1397 }
@@ -1296,18 +1417,6 @@ static void __exit tridentfb_exit(void)
1296 pci_unregister_driver(&tridentfb_pci_driver); 1417 pci_unregister_driver(&tridentfb_pci_driver);
1297} 1418}
1298 1419
1299static struct fb_ops tridentfb_ops = {
1300 .owner = THIS_MODULE,
1301 .fb_setcolreg = tridentfb_setcolreg,
1302 .fb_pan_display = tridentfb_pan_display,
1303 .fb_blank = tridentfb_blank,
1304 .fb_check_var = tridentfb_check_var,
1305 .fb_set_par = tridentfb_set_par,
1306 .fb_fillrect = tridentfb_fillrect,
1307 .fb_copyarea= tridentfb_copyarea,
1308 .fb_imageblit = cfb_imageblit,
1309};
1310
1311module_init(tridentfb_init); 1420module_init(tridentfb_init);
1312module_exit(tridentfb_exit); 1421module_exit(tridentfb_exit);
1313 1422
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
new file mode 100644
index 000000000000..b983d262ab78
--- /dev/null
+++ b/drivers/video/uvesafb.c
@@ -0,0 +1,2066 @@
1/*
2 * A framebuffer driver for VBE 2.0+ compliant video cards
3 *
4 * (c) 2007 Michal Januszewski <spock@gentoo.org>
5 * Loosely based upon the vesafb driver.
6 *
7 */
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/moduleparam.h>
11#include <linux/skbuff.h>
12#include <linux/timer.h>
13#include <linux/completion.h>
14#include <linux/connector.h>
15#include <linux/random.h>
16#include <linux/platform_device.h>
17#include <linux/limits.h>
18#include <linux/fb.h>
19#include <linux/io.h>
20#include <linux/mutex.h>
21#include <video/edid.h>
22#include <video/uvesafb.h>
23#ifdef CONFIG_X86
24#include <video/vga.h>
25#endif
26#ifdef CONFIG_MTRR
27#include <asm/mtrr.h>
28#endif
29#include "edid.h"
30
31static struct cb_id uvesafb_cn_id = {
32 .idx = CN_IDX_V86D,
33 .val = CN_VAL_V86D_UVESAFB
34};
35static char v86d_path[PATH_MAX] = "/sbin/v86d";
36static char v86d_started; /* has v86d been started by uvesafb? */
37
38static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
39 .id = "VESA VGA",
40 .type = FB_TYPE_PACKED_PIXELS,
41 .accel = FB_ACCEL_NONE,
42 .visual = FB_VISUAL_TRUECOLOR,
43};
44
45static int mtrr __devinitdata = 3; /* enable mtrr by default */
46static int blank __devinitdata = 1; /* enable blanking by default */
47static int ypan __devinitdata = 1; /* 0: scroll, 1: ypan, 2: ywrap */
48static int pmi_setpal __devinitdata = 1; /* use PMI for palette changes */
49static int nocrtc __devinitdata; /* ignore CRTC settings */
50static int noedid __devinitdata; /* don't try DDC transfers */
51static int vram_remap __devinitdata; /* set amt. of memory to be used */
52static int vram_total __devinitdata; /* set total amount of memory */
53static u16 maxclk __devinitdata; /* maximum pixel clock */
54static u16 maxvf __devinitdata; /* maximum vertical frequency */
55static u16 maxhf __devinitdata; /* maximum horizontal frequency */
56static u16 vbemode __devinitdata; /* force use of a specific VBE mode */
57static char *mode_option __devinitdata;
58
59static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
60static DEFINE_MUTEX(uvfb_lock);
61
62/*
63 * A handler for replies from userspace.
64 *
65 * Make sure each message passes consistency checks and if it does,
66 * find the kernel part of the task struct, copy the registers and
67 * the buffer contents and then complete the task.
68 */
69static void uvesafb_cn_callback(void *data)
70{
71 struct cn_msg *msg = data;
72 struct uvesafb_task *utask;
73 struct uvesafb_ktask *task;
74
75 if (msg->seq >= UVESAFB_TASKS_MAX)
76 return;
77
78 mutex_lock(&uvfb_lock);
79 task = uvfb_tasks[msg->seq];
80
81 if (!task || msg->ack != task->ack) {
82 mutex_unlock(&uvfb_lock);
83 return;
84 }
85
86 utask = (struct uvesafb_task *)msg->data;
87
88 /* Sanity checks for the buffer length. */
89 if (task->t.buf_len < utask->buf_len ||
90 utask->buf_len > msg->len - sizeof(*utask)) {
91 mutex_unlock(&uvfb_lock);
92 return;
93 }
94
95 uvfb_tasks[msg->seq] = NULL;
96 mutex_unlock(&uvfb_lock);
97
98 memcpy(&task->t, utask, sizeof(*utask));
99
100 if (task->t.buf_len && task->buf)
101 memcpy(task->buf, utask + 1, task->t.buf_len);
102
103 complete(task->done);
104 return;
105}
106
107static int uvesafb_helper_start(void)
108{
109 char *envp[] = {
110 "HOME=/",
111 "PATH=/sbin:/bin",
112 NULL,
113 };
114
115 char *argv[] = {
116 v86d_path,
117 NULL,
118 };
119
120 return call_usermodehelper(v86d_path, argv, envp, 1);
121}
122
123/*
124 * Execute a uvesafb task.
125 *
126 * Returns 0 if the task is executed successfully.
127 *
128 * A message sent to the userspace consists of the uvesafb_task
129 * struct and (optionally) a buffer. The uvesafb_task struct is
130 * a simplified version of uvesafb_ktask (its kernel counterpart)
131 * containing only the register values, flags and the length of
132 * the buffer.
133 *
134 * Each message is assigned a sequence number (increased linearly)
135 * and a random ack number. The sequence number is used as a key
136 * for the uvfb_tasks array which holds pointers to uvesafb_ktask
137 * structs for all requests.
138 */
139static int uvesafb_exec(struct uvesafb_ktask *task)
140{
141 static int seq;
142 struct cn_msg *m;
143 int err;
144 int len = sizeof(task->t) + task->t.buf_len;
145
146 /*
147 * Check whether the message isn't longer than the maximum
148 * allowed by connector.
149 */
150 if (sizeof(*m) + len > CONNECTOR_MAX_MSG_SIZE) {
151 printk(KERN_WARNING "uvesafb: message too long (%d), "
152 "can't execute task\n", (int)(sizeof(*m) + len));
153 return -E2BIG;
154 }
155
156 m = kzalloc(sizeof(*m) + len, GFP_KERNEL);
157 if (!m)
158 return -ENOMEM;
159
160 init_completion(task->done);
161
162 memcpy(&m->id, &uvesafb_cn_id, sizeof(m->id));
163 m->seq = seq;
164 m->len = len;
165 m->ack = random32();
166
167 /* uvesafb_task structure */
168 memcpy(m + 1, &task->t, sizeof(task->t));
169
170 /* Buffer */
171 memcpy((u8 *)(m + 1) + sizeof(task->t), task->buf, task->t.buf_len);
172
173 /*
174 * Save the message ack number so that we can find the kernel
175 * part of this task when a reply is received from userspace.
176 */
177 task->ack = m->ack;
178
179 mutex_lock(&uvfb_lock);
180
181 /* If all slots are taken -- bail out. */
182 if (uvfb_tasks[seq]) {
183 mutex_unlock(&uvfb_lock);
184 return -EBUSY;
185 }
186
187 /* Save a pointer to the kernel part of the task struct. */
188 uvfb_tasks[seq] = task;
189 mutex_unlock(&uvfb_lock);
190
191 err = cn_netlink_send(m, 0, gfp_any());
192 if (err == -ESRCH) {
193 /*
194 * Try to start the userspace helper if sending
195 * the request failed the first time.
196 */
197 err = uvesafb_helper_start();
198 if (err) {
199 printk(KERN_ERR "uvesafb: failed to execute %s\n",
200 v86d_path);
201 printk(KERN_ERR "uvesafb: make sure that the v86d "
202 "helper is installed and executable\n");
203 } else {
204 v86d_started = 1;
205 err = cn_netlink_send(m, 0, gfp_any());
206 }
207 }
208 kfree(m);
209
210 if (!err && !(task->t.flags & TF_EXIT))
211 err = !wait_for_completion_timeout(task->done,
212 msecs_to_jiffies(UVESAFB_TIMEOUT));
213
214 mutex_lock(&uvfb_lock);
215 uvfb_tasks[seq] = NULL;
216 mutex_unlock(&uvfb_lock);
217
218 seq++;
219 if (seq >= UVESAFB_TASKS_MAX)
220 seq = 0;
221
222 return err;
223}
224
225/*
226 * Free a uvesafb_ktask struct.
227 */
228static void uvesafb_free(struct uvesafb_ktask *task)
229{
230 if (task) {
231 if (task->done)
232 kfree(task->done);
233 kfree(task);
234 }
235}
236
237/*
238 * Prepare a uvesafb_ktask struct to be used again.
239 */
240static void uvesafb_reset(struct uvesafb_ktask *task)
241{
242 struct completion *cpl = task->done;
243
244 memset(task, 0, sizeof(*task));
245 task->done = cpl;
246}
247
248/*
249 * Allocate and prepare a uvesafb_ktask struct.
250 */
251static struct uvesafb_ktask *uvesafb_prep(void)
252{
253 struct uvesafb_ktask *task;
254
255 task = kzalloc(sizeof(*task), GFP_KERNEL);
256 if (task) {
257 task->done = kzalloc(sizeof(*task->done), GFP_KERNEL);
258 if (!task->done) {
259 kfree(task);
260 task = NULL;
261 }
262 }
263 return task;
264}
265
266static void uvesafb_setup_var(struct fb_var_screeninfo *var,
267 struct fb_info *info, struct vbe_mode_ib *mode)
268{
269 struct uvesafb_par *par = info->par;
270
271 var->vmode = FB_VMODE_NONINTERLACED;
272 var->sync = FB_SYNC_VERT_HIGH_ACT;
273
274 var->xres = mode->x_res;
275 var->yres = mode->y_res;
276 var->xres_virtual = mode->x_res;
277 var->yres_virtual = (par->ypan) ?
278 info->fix.smem_len / mode->bytes_per_scan_line :
279 mode->y_res;
280 var->xoffset = 0;
281 var->yoffset = 0;
282 var->bits_per_pixel = mode->bits_per_pixel;
283
284 if (var->bits_per_pixel == 15)
285 var->bits_per_pixel = 16;
286
287 if (var->bits_per_pixel > 8) {
288 var->red.offset = mode->red_off;
289 var->red.length = mode->red_len;
290 var->green.offset = mode->green_off;
291 var->green.length = mode->green_len;
292 var->blue.offset = mode->blue_off;
293 var->blue.length = mode->blue_len;
294 var->transp.offset = mode->rsvd_off;
295 var->transp.length = mode->rsvd_len;
296 } else {
297 var->red.offset = 0;
298 var->green.offset = 0;
299 var->blue.offset = 0;
300 var->transp.offset = 0;
301
302 /*
303 * We're assuming that we can switch the DAC to 8 bits. If
304 * this proves to be incorrect, we'll update the fields
305 * later in set_par().
306 */
307 if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC) {
308 var->red.length = 8;
309 var->green.length = 8;
310 var->blue.length = 8;
311 var->transp.length = 0;
312 } else {
313 var->red.length = 6;
314 var->green.length = 6;
315 var->blue.length = 6;
316 var->transp.length = 0;
317 }
318 }
319}
320
321static int uvesafb_vbe_find_mode(struct uvesafb_par *par,
322 int xres, int yres, int depth, unsigned char flags)
323{
324 int i, match = -1, h = 0, d = 0x7fffffff;
325
326 for (i = 0; i < par->vbe_modes_cnt; i++) {
327 h = abs(par->vbe_modes[i].x_res - xres) +
328 abs(par->vbe_modes[i].y_res - yres) +
329 abs(depth - par->vbe_modes[i].depth);
330
331 /*
332 * We have an exact match in terms of resolution
333 * and depth.
334 */
335 if (h == 0)
336 return i;
337
338 if (h < d || (h == d && par->vbe_modes[i].depth > depth)) {
339 d = h;
340 match = i;
341 }
342 }
343 i = 1;
344
345 if (flags & UVESAFB_EXACT_DEPTH &&
346 par->vbe_modes[match].depth != depth)
347 i = 0;
348
349 if (flags & UVESAFB_EXACT_RES && d > 24)
350 i = 0;
351
352 if (i != 0)
353 return match;
354 else
355 return -1;
356}
357
358static u8 *uvesafb_vbe_state_save(struct uvesafb_par *par)
359{
360 struct uvesafb_ktask *task;
361 u8 *state;
362 int err;
363
364 if (!par->vbe_state_size)
365 return NULL;
366
367 state = kmalloc(par->vbe_state_size, GFP_KERNEL);
368 if (!state)
369 return NULL;
370
371 task = uvesafb_prep();
372 if (!task) {
373 kfree(state);
374 return NULL;
375 }
376
377 task->t.regs.eax = 0x4f04;
378 task->t.regs.ecx = 0x000f;
379 task->t.regs.edx = 0x0001;
380 task->t.flags = TF_BUF_RET | TF_BUF_ESBX;
381 task->t.buf_len = par->vbe_state_size;
382 task->buf = state;
383 err = uvesafb_exec(task);
384
385 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
386 printk(KERN_WARNING "uvesafb: VBE get state call "
387 "failed (eax=0x%x, err=%d)\n",
388 task->t.regs.eax, err);
389 kfree(state);
390 state = NULL;
391 }
392
393 uvesafb_free(task);
394 return state;
395}
396
397static void uvesafb_vbe_state_restore(struct uvesafb_par *par, u8 *state_buf)
398{
399 struct uvesafb_ktask *task;
400 int err;
401
402 if (!state_buf)
403 return;
404
405 task = uvesafb_prep();
406 if (!task)
407 return;
408
409 task->t.regs.eax = 0x4f04;
410 task->t.regs.ecx = 0x000f;
411 task->t.regs.edx = 0x0002;
412 task->t.buf_len = par->vbe_state_size;
413 task->t.flags = TF_BUF_ESBX;
414 task->buf = state_buf;
415
416 err = uvesafb_exec(task);
417 if (err || (task->t.regs.eax & 0xffff) != 0x004f)
418 printk(KERN_WARNING "uvesafb: VBE state restore call "
419 "failed (eax=0x%x, err=%d)\n",
420 task->t.regs.eax, err);
421
422 uvesafb_free(task);
423}
424
425static int __devinit uvesafb_vbe_getinfo(struct uvesafb_ktask *task,
426 struct uvesafb_par *par)
427{
428 int err;
429
430 task->t.regs.eax = 0x4f00;
431 task->t.flags = TF_VBEIB;
432 task->t.buf_len = sizeof(struct vbe_ib);
433 task->buf = &par->vbe_ib;
434 strncpy(par->vbe_ib.vbe_signature, "VBE2", 4);
435
436 err = uvesafb_exec(task);
437 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
438 printk(KERN_ERR "uvesafb: Getting VBE info block failed "
439 "(eax=0x%x, err=%d)\n", (u32)task->t.regs.eax,
440 err);
441 return -EINVAL;
442 }
443
444 if (par->vbe_ib.vbe_version < 0x0200) {
445 printk(KERN_ERR "uvesafb: Sorry, pre-VBE 2.0 cards are "
446 "not supported.\n");
447 return -EINVAL;
448 }
449
450 if (!par->vbe_ib.mode_list_ptr) {
451 printk(KERN_ERR "uvesafb: Missing mode list!\n");
452 return -EINVAL;
453 }
454
455 printk(KERN_INFO "uvesafb: ");
456
457 /*
458 * Convert string pointers and the mode list pointer into
459 * usable addresses. Print informational messages about the
460 * video adapter and its vendor.
461 */
462 if (par->vbe_ib.oem_vendor_name_ptr)
463 printk("%s, ",
464 ((char *)task->buf) + par->vbe_ib.oem_vendor_name_ptr);
465
466 if (par->vbe_ib.oem_product_name_ptr)
467 printk("%s, ",
468 ((char *)task->buf) + par->vbe_ib.oem_product_name_ptr);
469
470 if (par->vbe_ib.oem_product_rev_ptr)
471 printk("%s, ",
472 ((char *)task->buf) + par->vbe_ib.oem_product_rev_ptr);
473
474 if (par->vbe_ib.oem_string_ptr)
475 printk("OEM: %s, ",
476 ((char *)task->buf) + par->vbe_ib.oem_string_ptr);
477
478 printk("VBE v%d.%d\n", ((par->vbe_ib.vbe_version & 0xff00) >> 8),
479 par->vbe_ib.vbe_version & 0xff);
480
481 return 0;
482}
483
484static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
485 struct uvesafb_par *par)
486{
487 int off = 0, err;
488 u16 *mode;
489
490 par->vbe_modes_cnt = 0;
491
492 /* Count available modes. */
493 mode = (u16 *) (((u8 *)&par->vbe_ib) + par->vbe_ib.mode_list_ptr);
494 while (*mode != 0xffff) {
495 par->vbe_modes_cnt++;
496 mode++;
497 }
498
499 par->vbe_modes = kzalloc(sizeof(struct vbe_mode_ib) *
500 par->vbe_modes_cnt, GFP_KERNEL);
501 if (!par->vbe_modes)
502 return -ENOMEM;
503
504 /* Get info about all available modes. */
505 mode = (u16 *) (((u8 *)&par->vbe_ib) + par->vbe_ib.mode_list_ptr);
506 while (*mode != 0xffff) {
507 struct vbe_mode_ib *mib;
508
509 uvesafb_reset(task);
510 task->t.regs.eax = 0x4f01;
511 task->t.regs.ecx = (u32) *mode;
512 task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
513 task->t.buf_len = sizeof(struct vbe_mode_ib);
514 task->buf = par->vbe_modes + off;
515
516 err = uvesafb_exec(task);
517 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
518 printk(KERN_ERR "uvesafb: Getting mode info block "
519 "for mode 0x%x failed (eax=0x%x, err=%d)\n",
520 *mode, (u32)task->t.regs.eax, err);
521 return -EINVAL;
522 }
523
524 mib = task->buf;
525 mib->mode_id = *mode;
526
527 /*
528 * We only want modes that are supported with the current
529 * hardware configuration, color, graphics and that have
530 * support for the LFB.
531 */
532 if ((mib->mode_attr & VBE_MODE_MASK) == VBE_MODE_MASK &&
533 mib->bits_per_pixel >= 8)
534 off++;
535 else
536 par->vbe_modes_cnt--;
537
538 mode++;
539 mib->depth = mib->red_len + mib->green_len + mib->blue_len;
540
541 /*
542 * Handle 8bpp modes and modes with broken color component
543 * lengths.
544 */
545 if (mib->depth == 0 || (mib->depth == 24 &&
546 mib->bits_per_pixel == 32))
547 mib->depth = mib->bits_per_pixel;
548 }
549
550 return 0;
551}
552
553/*
554 * The Protected Mode Interface is 32-bit x86 code, so we only run it on
555 * x86 and not x86_64.
556 */
557#ifdef CONFIG_X86_32
558static int __devinit uvesafb_vbe_getpmi(struct uvesafb_ktask *task,
559 struct uvesafb_par *par)
560{
561 int i, err;
562
563 uvesafb_reset(task);
564 task->t.regs.eax = 0x4f0a;
565 task->t.regs.ebx = 0x0;
566 err = uvesafb_exec(task);
567
568 if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
569 par->pmi_setpal = par->ypan = 0;
570 } else {
571 par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
572 + task->t.regs.edi);
573 par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
574 par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
575 printk(KERN_INFO "uvesafb: protected mode interface info at "
576 "%04x:%04x\n",
577 (u16)task->t.regs.es, (u16)task->t.regs.edi);
578 printk(KERN_INFO "uvesafb: pmi: set display start = %p, "
579 "set palette = %p\n", par->pmi_start,
580 par->pmi_pal);
581
582 if (par->pmi_base[3]) {
583 printk(KERN_INFO "uvesafb: pmi: ports = ");
584 for (i = par->pmi_base[3]/2;
585 par->pmi_base[i] != 0xffff; i++)
586 printk("%x ", par->pmi_base[i]);
587 printk("\n");
588
589 if (par->pmi_base[i] != 0xffff) {
590 printk(KERN_INFO "uvesafb: can't handle memory"
591 " requests, pmi disabled\n");
592 par->ypan = par->pmi_setpal = 0;
593 }
594 }
595 }
596 return 0;
597}
598#endif /* CONFIG_X86_32 */
599
600/*
601 * Check whether a video mode is supported by the Video BIOS and is
602 * compatible with the monitor limits.
603 */
604static int __devinit uvesafb_is_valid_mode(struct fb_videomode *mode,
605 struct fb_info *info)
606{
607 if (info->monspecs.gtf) {
608 fb_videomode_to_var(&info->var, mode);
609 if (fb_validate_mode(&info->var, info))
610 return 0;
611 }
612
613 if (uvesafb_vbe_find_mode(info->par, mode->xres, mode->yres, 8,
614 UVESAFB_EXACT_RES) == -1)
615 return 0;
616
617 return 1;
618}
619
620static int __devinit uvesafb_vbe_getedid(struct uvesafb_ktask *task,
621 struct fb_info *info)
622{
623 struct uvesafb_par *par = info->par;
624 int err = 0;
625
626 if (noedid || par->vbe_ib.vbe_version < 0x0300)
627 return -EINVAL;
628
629 task->t.regs.eax = 0x4f15;
630 task->t.regs.ebx = 0;
631 task->t.regs.ecx = 0;
632 task->t.buf_len = 0;
633 task->t.flags = 0;
634
635 err = uvesafb_exec(task);
636
637 if ((task->t.regs.eax & 0xffff) != 0x004f || err)
638 return -EINVAL;
639
640 if ((task->t.regs.ebx & 0x3) == 3) {
641 printk(KERN_INFO "uvesafb: VBIOS/hardware supports both "
642 "DDC1 and DDC2 transfers\n");
643 } else if ((task->t.regs.ebx & 0x3) == 2) {
644 printk(KERN_INFO "uvesafb: VBIOS/hardware supports DDC2 "
645 "transfers\n");
646 } else if ((task->t.regs.ebx & 0x3) == 1) {
647 printk(KERN_INFO "uvesafb: VBIOS/hardware supports DDC1 "
648 "transfers\n");
649 } else {
650 printk(KERN_INFO "uvesafb: VBIOS/hardware doesn't support "
651 "DDC transfers\n");
652 return -EINVAL;
653 }
654
655 task->t.regs.eax = 0x4f15;
656 task->t.regs.ebx = 1;
657 task->t.regs.ecx = task->t.regs.edx = 0;
658 task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
659 task->t.buf_len = EDID_LENGTH;
660 task->buf = kzalloc(EDID_LENGTH, GFP_KERNEL);
661
662 err = uvesafb_exec(task);
663
664 if ((task->t.regs.eax & 0xffff) == 0x004f && !err) {
665 fb_edid_to_monspecs(task->buf, &info->monspecs);
666
667 if (info->monspecs.vfmax && info->monspecs.hfmax) {
668 /*
669 * If the maximum pixel clock wasn't specified in
670 * the EDID block, set it to 300 MHz.
671 */
672 if (info->monspecs.dclkmax == 0)
673 info->monspecs.dclkmax = 300 * 1000000;
674 info->monspecs.gtf = 1;
675 }
676 } else {
677 err = -EINVAL;
678 }
679
680 kfree(task->buf);
681 return err;
682}
683
684static void __devinit uvesafb_vbe_getmonspecs(struct uvesafb_ktask *task,
685 struct fb_info *info)
686{
687 struct uvesafb_par *par = info->par;
688 int i;
689
690 memset(&info->monspecs, 0, sizeof(info->monspecs));
691
692 /*
693 * If we don't get all necessary data from the EDID block,
694 * mark it as incompatible with the GTF and set nocrtc so
695 * that we always use the default BIOS refresh rate.
696 */
697 if (uvesafb_vbe_getedid(task, info)) {
698 info->monspecs.gtf = 0;
699 par->nocrtc = 1;
700 }
701
702 /* Kernel command line overrides. */
703 if (maxclk)
704 info->monspecs.dclkmax = maxclk * 1000000;
705 if (maxvf)
706 info->monspecs.vfmax = maxvf;
707 if (maxhf)
708 info->monspecs.hfmax = maxhf * 1000;
709
710 /*
711 * In case DDC transfers are not supported, the user can provide
712 * monitor limits manually. Lower limits are set to "safe" values.
713 */
714 if (info->monspecs.gtf == 0 && maxclk && maxvf && maxhf) {
715 info->monspecs.dclkmin = 0;
716 info->monspecs.vfmin = 60;
717 info->monspecs.hfmin = 29000;
718 info->monspecs.gtf = 1;
719 par->nocrtc = 0;
720 }
721
722 if (info->monspecs.gtf)
723 printk(KERN_INFO
724 "uvesafb: monitor limits: vf = %d Hz, hf = %d kHz, "
725 "clk = %d MHz\n", info->monspecs.vfmax,
726 (int)(info->monspecs.hfmax / 1000),
727 (int)(info->monspecs.dclkmax / 1000000));
728 else
729 printk(KERN_INFO "uvesafb: no monitor limits have been set, "
730 "default refresh rate will be used\n");
731
732 /* Add VBE modes to the modelist. */
733 for (i = 0; i < par->vbe_modes_cnt; i++) {
734 struct fb_var_screeninfo var;
735 struct vbe_mode_ib *mode;
736 struct fb_videomode vmode;
737
738 mode = &par->vbe_modes[i];
739 memset(&var, 0, sizeof(var));
740
741 var.xres = mode->x_res;
742 var.yres = mode->y_res;
743
744 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, &var, info);
745 fb_var_to_videomode(&vmode, &var);
746 fb_add_videomode(&vmode, &info->modelist);
747 }
748
749 /* Add valid VESA modes to our modelist. */
750 for (i = 0; i < VESA_MODEDB_SIZE; i++) {
751 if (uvesafb_is_valid_mode((struct fb_videomode *)
752 &vesa_modes[i], info))
753 fb_add_videomode(&vesa_modes[i], &info->modelist);
754 }
755
756 for (i = 0; i < info->monspecs.modedb_len; i++) {
757 if (uvesafb_is_valid_mode(&info->monspecs.modedb[i], info))
758 fb_add_videomode(&info->monspecs.modedb[i],
759 &info->modelist);
760 }
761
762 return;
763}
764
765static void __devinit uvesafb_vbe_getstatesize(struct uvesafb_ktask *task,
766 struct uvesafb_par *par)
767{
768 int err;
769
770 uvesafb_reset(task);
771
772 /*
773 * Get the VBE state buffer size. We want all available
774 * hardware state data (CL = 0x0f).
775 */
776 task->t.regs.eax = 0x4f04;
777 task->t.regs.ecx = 0x000f;
778 task->t.regs.edx = 0x0000;
779 task->t.flags = 0;
780
781 err = uvesafb_exec(task);
782
783 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
784 printk(KERN_WARNING "uvesafb: VBE state buffer size "
785 "cannot be determined (eax=0x%x, err=%d)\n",
786 task->t.regs.eax, err);
787 par->vbe_state_size = 0;
788 return;
789 }
790
791 par->vbe_state_size = 64 * (task->t.regs.ebx & 0xffff);
792}
793
794static int __devinit uvesafb_vbe_init(struct fb_info *info)
795{
796 struct uvesafb_ktask *task = NULL;
797 struct uvesafb_par *par = info->par;
798 int err;
799
800 task = uvesafb_prep();
801 if (!task)
802 return -ENOMEM;
803
804 err = uvesafb_vbe_getinfo(task, par);
805 if (err)
806 goto out;
807
808 err = uvesafb_vbe_getmodes(task, par);
809 if (err)
810 goto out;
811
812 par->nocrtc = nocrtc;
813#ifdef CONFIG_X86_32
814 par->pmi_setpal = pmi_setpal;
815 par->ypan = ypan;
816
817 if (par->pmi_setpal || par->ypan)
818 uvesafb_vbe_getpmi(task, par);
819#else
820 /* The protected mode interface is not available on non-x86. */
821 par->pmi_setpal = par->ypan = 0;
822#endif
823
824 INIT_LIST_HEAD(&info->modelist);
825 uvesafb_vbe_getmonspecs(task, info);
826 uvesafb_vbe_getstatesize(task, par);
827
828out: uvesafb_free(task);
829 return err;
830}
831
832static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
833{
834 struct list_head *pos;
835 struct fb_modelist *modelist;
836 struct fb_videomode *mode;
837 struct uvesafb_par *par = info->par;
838 int i, modeid;
839
840 /* Has the user requested a specific VESA mode? */
841 if (vbemode) {
842 for (i = 0; i < par->vbe_modes_cnt; i++) {
843 if (par->vbe_modes[i].mode_id == vbemode) {
844 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
845 &info->var, info);
846 /*
847 * With pixclock set to 0, the default BIOS
848 * timings will be used in set_par().
849 */
850 info->var.pixclock = 0;
851 modeid = i;
852 goto gotmode;
853 }
854 }
855 printk(KERN_INFO "uvesafb: requested VBE mode 0x%x is "
856 "unavailable\n", vbemode);
857 vbemode = 0;
858 }
859
860 /* Count the modes in the modelist */
861 i = 0;
862 list_for_each(pos, &info->modelist)
863 i++;
864
865 /*
866 * Convert the modelist into a modedb so that we can use it with
867 * fb_find_mode().
868 */
869 mode = kzalloc(i * sizeof(*mode), GFP_KERNEL);
870 if (mode) {
871 i = 0;
872 list_for_each(pos, &info->modelist) {
873 modelist = list_entry(pos, struct fb_modelist, list);
874 mode[i] = modelist->mode;
875 i++;
876 }
877
878 if (!mode_option)
879 mode_option = UVESAFB_DEFAULT_MODE;
880
881 i = fb_find_mode(&info->var, info, mode_option, mode, i,
882 NULL, 8);
883
884 kfree(mode);
885 }
886
887 /* fb_find_mode() failed */
888 if (i == 0 || i >= 3) {
889 info->var.xres = 640;
890 info->var.yres = 480;
891 mode = (struct fb_videomode *)
892 fb_find_best_mode(&info->var, &info->modelist);
893
894 if (mode) {
895 fb_videomode_to_var(&info->var, mode);
896 } else {
897 modeid = par->vbe_modes[0].mode_id;
898 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
899 &info->var, info);
900 goto gotmode;
901 }
902 }
903
904 /* Look for a matching VBE mode. */
905 modeid = uvesafb_vbe_find_mode(par, info->var.xres, info->var.yres,
906 info->var.bits_per_pixel, UVESAFB_EXACT_RES);
907
908 if (modeid == -1)
909 return -EINVAL;
910
911gotmode:
912 uvesafb_setup_var(&info->var, info, &par->vbe_modes[modeid]);
913
914 /*
915 * If we are not VBE3.0+ compliant, we're done -- the BIOS will
916 * ignore our timings anyway.
917 */
918 if (par->vbe_ib.vbe_version < 0x0300 || par->nocrtc)
919 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
920 &info->var, info);
921
922 return modeid;
923}
924
925static int uvesafb_setpalette(struct uvesafb_pal_entry *entries, int count,
926 int start, struct fb_info *info)
927{
928 struct uvesafb_ktask *task;
929 struct uvesafb_par *par = info->par;
930 int i = par->mode_idx;
931 int err = 0;
932
933 /*
934 * We support palette modifications for 8 bpp modes only, so
935 * there can never be more than 256 entries.
936 */
937 if (start + count > 256)
938 return -EINVAL;
939
940#ifdef CONFIG_X86
941 /* Use VGA registers if mode is VGA-compatible. */
942 if (i >= 0 && i < par->vbe_modes_cnt &&
943 par->vbe_modes[i].mode_attr & VBE_MODE_VGACOMPAT) {
944 for (i = 0; i < count; i++) {
945 outb_p(start + i, dac_reg);
946 outb_p(entries[i].red, dac_val);
947 outb_p(entries[i].green, dac_val);
948 outb_p(entries[i].blue, dac_val);
949 }
950 }
951#ifdef CONFIG_X86_32
952 else if (par->pmi_setpal) {
953 __asm__ __volatile__(
954 "call *(%%esi)"
955 : /* no return value */
956 : "a" (0x4f09), /* EAX */
957 "b" (0), /* EBX */
958 "c" (count), /* ECX */
959 "d" (start), /* EDX */
960 "D" (entries), /* EDI */
961 "S" (&par->pmi_pal)); /* ESI */
962 }
963#endif /* CONFIG_X86_32 */
964 else
965#endif /* CONFIG_X86 */
966 {
967 task = uvesafb_prep();
968 if (!task)
969 return -ENOMEM;
970
971 task->t.regs.eax = 0x4f09;
972 task->t.regs.ebx = 0x0;
973 task->t.regs.ecx = count;
974 task->t.regs.edx = start;
975 task->t.flags = TF_BUF_ESDI;
976 task->t.buf_len = sizeof(struct uvesafb_pal_entry) * count;
977 task->buf = entries;
978
979 err = uvesafb_exec(task);
980 if ((task->t.regs.eax & 0xffff) != 0x004f)
981 err = 1;
982
983 uvesafb_free(task);
984 }
985 return err;
986}
987
988static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
989 unsigned blue, unsigned transp,
990 struct fb_info *info)
991{
992 struct uvesafb_pal_entry entry;
993 int shift = 16 - info->var.green.length;
994 int err = 0;
995
996 if (regno >= info->cmap.len)
997 return -EINVAL;
998
999 if (info->var.bits_per_pixel == 8) {
1000 entry.red = red >> shift;
1001 entry.green = green >> shift;
1002 entry.blue = blue >> shift;
1003 entry.pad = 0;
1004
1005 err = uvesafb_setpalette(&entry, 1, regno, info);
1006 } else if (regno < 16) {
1007 switch (info->var.bits_per_pixel) {
1008 case 16:
1009 if (info->var.red.offset == 10) {
1010 /* 1:5:5:5 */
1011 ((u32 *) (info->pseudo_palette))[regno] =
1012 ((red & 0xf800) >> 1) |
1013 ((green & 0xf800) >> 6) |
1014 ((blue & 0xf800) >> 11);
1015 } else {
1016 /* 0:5:6:5 */
1017 ((u32 *) (info->pseudo_palette))[regno] =
1018 ((red & 0xf800) ) |
1019 ((green & 0xfc00) >> 5) |
1020 ((blue & 0xf800) >> 11);
1021 }
1022 break;
1023
1024 case 24:
1025 case 32:
1026 red >>= 8;
1027 green >>= 8;
1028 blue >>= 8;
1029 ((u32 *)(info->pseudo_palette))[regno] =
1030 (red << info->var.red.offset) |
1031 (green << info->var.green.offset) |
1032 (blue << info->var.blue.offset);
1033 break;
1034 }
1035 }
1036 return err;
1037}
1038
1039static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
1040{
1041 struct uvesafb_pal_entry *entries;
1042 int shift = 16 - info->var.green.length;
1043 int i, err = 0;
1044
1045 if (info->var.bits_per_pixel == 8) {
1046 if (cmap->start + cmap->len > info->cmap.start +
1047 info->cmap.len || cmap->start < info->cmap.start)
1048 return -EINVAL;
1049
1050 entries = kmalloc(sizeof(*entries) * cmap->len, GFP_KERNEL);
1051 if (!entries)
1052 return -ENOMEM;
1053
1054 for (i = 0; i < cmap->len; i++) {
1055 entries[i].red = cmap->red[i] >> shift;
1056 entries[i].green = cmap->green[i] >> shift;
1057 entries[i].blue = cmap->blue[i] >> shift;
1058 entries[i].pad = 0;
1059 }
1060 err = uvesafb_setpalette(entries, cmap->len, cmap->start, info);
1061 kfree(entries);
1062 } else {
1063 /*
1064 * For modes with bpp > 8, we only set the pseudo palette in
1065 * the fb_info struct. We rely on uvesafb_setcolreg to do all
1066 * sanity checking.
1067 */
1068 for (i = 0; i < cmap->len; i++) {
1069 err |= uvesafb_setcolreg(cmap->start + i, cmap->red[i],
1070 cmap->green[i], cmap->blue[i],
1071 0, info);
1072 }
1073 }
1074 return err;
1075}
1076
1077static int uvesafb_pan_display(struct fb_var_screeninfo *var,
1078 struct fb_info *info)
1079{
1080#ifdef CONFIG_X86_32
1081 int offset;
1082 struct uvesafb_par *par = info->par;
1083
1084 offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;
1085
1086 /*
1087 * It turns out it's not the best idea to do panning via vm86,
1088 * so we only allow it if we have a PMI.
1089 */
1090 if (par->pmi_start) {
1091 __asm__ __volatile__(
1092 "call *(%%edi)"
1093 : /* no return value */
1094 : "a" (0x4f07), /* EAX */
1095 "b" (0), /* EBX */
1096 "c" (offset), /* ECX */
1097 "d" (offset >> 16), /* EDX */
1098 "D" (&par->pmi_start)); /* EDI */
1099 }
1100#endif
1101 return 0;
1102}
1103
1104static int uvesafb_blank(int blank, struct fb_info *info)
1105{
1106 struct uvesafb_par *par = info->par;
1107 struct uvesafb_ktask *task;
1108 int err = 1;
1109
1110#ifdef CONFIG_X86
1111 if (par->vbe_ib.capabilities & VBE_CAP_VGACOMPAT) {
1112 int loop = 10000;
1113 u8 seq = 0, crtc17 = 0;
1114
1115 if (blank == FB_BLANK_POWERDOWN) {
1116 seq = 0x20;
1117 crtc17 = 0x00;
1118 err = 0;
1119 } else {
1120 seq = 0x00;
1121 crtc17 = 0x80;
1122 err = (blank == FB_BLANK_UNBLANK) ? 0 : -EINVAL;
1123 }
1124
1125 vga_wseq(NULL, 0x00, 0x01);
1126 seq |= vga_rseq(NULL, 0x01) & ~0x20;
1127 vga_wseq(NULL, 0x00, seq);
1128
1129 crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80;
1130 while (loop--);
1131 vga_wcrt(NULL, 0x17, crtc17);
1132 vga_wseq(NULL, 0x00, 0x03);
1133 } else
1134#endif /* CONFIG_X86 */
1135 {
1136 task = uvesafb_prep();
1137 if (!task)
1138 return -ENOMEM;
1139
1140 task->t.regs.eax = 0x4f10;
1141 switch (blank) {
1142 case FB_BLANK_UNBLANK:
1143 task->t.regs.ebx = 0x0001;
1144 break;
1145 case FB_BLANK_NORMAL:
1146 task->t.regs.ebx = 0x0101; /* standby */
1147 break;
1148 case FB_BLANK_POWERDOWN:
1149 task->t.regs.ebx = 0x0401; /* powerdown */
1150 break;
1151 default:
1152 goto out;
1153 }
1154
1155 err = uvesafb_exec(task);
1156 if (err || (task->t.regs.eax & 0xffff) != 0x004f)
1157 err = 1;
1158out: uvesafb_free(task);
1159 }
1160 return err;
1161}
1162
1163static int uvesafb_open(struct fb_info *info, int user)
1164{
1165 struct uvesafb_par *par = info->par;
1166 int cnt = atomic_read(&par->ref_count);
1167
1168 if (!cnt && par->vbe_state_size)
1169 par->vbe_state_orig = uvesafb_vbe_state_save(par);
1170
1171 atomic_inc(&par->ref_count);
1172 return 0;
1173}
1174
1175static int uvesafb_release(struct fb_info *info, int user)
1176{
1177 struct uvesafb_ktask *task = NULL;
1178 struct uvesafb_par *par = info->par;
1179 int cnt = atomic_read(&par->ref_count);
1180
1181 if (!cnt)
1182 return -EINVAL;
1183
1184 if (cnt != 1)
1185 goto out;
1186
1187 task = uvesafb_prep();
1188 if (!task)
1189 goto out;
1190
1191 /* First, try to set the standard 80x25 text mode. */
1192 task->t.regs.eax = 0x0003;
1193 uvesafb_exec(task);
1194
1195 /*
1196 * Now try to restore whatever hardware state we might have
1197 * saved when the fb device was first opened.
1198 */
1199 uvesafb_vbe_state_restore(par, par->vbe_state_orig);
1200out:
1201 atomic_dec(&par->ref_count);
1202 if (task)
1203 uvesafb_free(task);
1204 return 0;
1205}
1206
1207static int uvesafb_set_par(struct fb_info *info)
1208{
1209 struct uvesafb_par *par = info->par;
1210 struct uvesafb_ktask *task = NULL;
1211 struct vbe_crtc_ib *crtc = NULL;
1212 struct vbe_mode_ib *mode = NULL;
1213 int i, err = 0, depth = info->var.bits_per_pixel;
1214
1215 if (depth > 8 && depth != 32)
1216 depth = info->var.red.length + info->var.green.length +
1217 info->var.blue.length;
1218
1219 i = uvesafb_vbe_find_mode(par, info->var.xres, info->var.yres, depth,
1220 UVESAFB_EXACT_RES | UVESAFB_EXACT_DEPTH);
1221 if (i >= 0)
1222 mode = &par->vbe_modes[i];
1223 else
1224 return -EINVAL;
1225
1226 task = uvesafb_prep();
1227 if (!task)
1228 return -ENOMEM;
1229setmode:
1230 task->t.regs.eax = 0x4f02;
1231 task->t.regs.ebx = mode->mode_id | 0x4000; /* use LFB */
1232
1233 if (par->vbe_ib.vbe_version >= 0x0300 && !par->nocrtc &&
1234 info->var.pixclock != 0) {
1235 task->t.regs.ebx |= 0x0800; /* use CRTC data */
1236 task->t.flags = TF_BUF_ESDI;
1237 crtc = kzalloc(sizeof(struct vbe_crtc_ib), GFP_KERNEL);
1238 if (!crtc) {
1239 err = -ENOMEM;
1240 goto out;
1241 }
1242 crtc->horiz_start = info->var.xres + info->var.right_margin;
1243 crtc->horiz_end = crtc->horiz_start + info->var.hsync_len;
1244 crtc->horiz_total = crtc->horiz_end + info->var.left_margin;
1245
1246 crtc->vert_start = info->var.yres + info->var.lower_margin;
1247 crtc->vert_end = crtc->vert_start + info->var.vsync_len;
1248 crtc->vert_total = crtc->vert_end + info->var.upper_margin;
1249
1250 crtc->pixel_clock = PICOS2KHZ(info->var.pixclock) * 1000;
1251 crtc->refresh_rate = (u16)(100 * (crtc->pixel_clock /
1252 (crtc->vert_total * crtc->horiz_total)));
1253
1254 if (info->var.vmode & FB_VMODE_DOUBLE)
1255 crtc->flags |= 0x1;
1256 if (info->var.vmode & FB_VMODE_INTERLACED)
1257 crtc->flags |= 0x2;
1258 if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
1259 crtc->flags |= 0x4;
1260 if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
1261 crtc->flags |= 0x8;
1262 memcpy(&par->crtc, crtc, sizeof(*crtc));
1263 } else {
1264 memset(&par->crtc, 0, sizeof(*crtc));
1265 }
1266
1267 task->t.buf_len = sizeof(struct vbe_crtc_ib);
1268 task->buf = &par->crtc;
1269
1270 err = uvesafb_exec(task);
1271 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
1272 /*
1273 * The mode switch might have failed because we tried to
1274 * use our own timings. Try again with the default timings.
1275 */
1276 if (crtc != NULL) {
1277 printk(KERN_WARNING "uvesafb: mode switch failed "
1278 "(eax=0x%x, err=%d). Trying again with "
1279 "default timings.\n", task->t.regs.eax, err);
1280 uvesafb_reset(task);
1281 kfree(crtc);
1282 crtc = NULL;
1283 info->var.pixclock = 0;
1284 goto setmode;
1285 } else {
1286 printk(KERN_ERR "uvesafb: mode switch failed (eax="
1287 "0x%x, err=%d)\n", task->t.regs.eax, err);
1288 err = -EINVAL;
1289 goto out;
1290 }
1291 }
1292 par->mode_idx = i;
1293
1294 /* For 8bpp modes, always try to set the DAC to 8 bits. */
1295 if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC &&
1296 mode->bits_per_pixel <= 8) {
1297 uvesafb_reset(task);
1298 task->t.regs.eax = 0x4f08;
1299 task->t.regs.ebx = 0x0800;
1300
1301 err = uvesafb_exec(task);
1302 if (err || (task->t.regs.eax & 0xffff) != 0x004f ||
1303 ((task->t.regs.ebx & 0xff00) >> 8) != 8) {
1304 /*
1305 * We've failed to set the DAC palette format -
1306 * time to correct var.
1307 */
1308 info->var.red.length = 6;
1309 info->var.green.length = 6;
1310 info->var.blue.length = 6;
1311 }
1312 }
1313
1314 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1315 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
1316 info->fix.line_length = mode->bytes_per_scan_line;
1317
1318out: if (crtc != NULL)
1319 kfree(crtc);
1320 uvesafb_free(task);
1321
1322 return err;
1323}
1324
1325static void uvesafb_check_limits(struct fb_var_screeninfo *var,
1326 struct fb_info *info)
1327{
1328 const struct fb_videomode *mode;
1329 struct uvesafb_par *par = info->par;
1330
1331 /*
1332 * If pixclock is set to 0, then we're using default BIOS timings
1333 * and thus don't have to perform any checks here.
1334 */
1335 if (!var->pixclock)
1336 return;
1337
1338 if (par->vbe_ib.vbe_version < 0x0300) {
1339 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, var, info);
1340 return;
1341 }
1342
1343 if (!fb_validate_mode(var, info))
1344 return;
1345
1346 mode = fb_find_best_mode(var, &info->modelist);
1347 if (mode) {
1348 if (mode->xres == var->xres && mode->yres == var->yres &&
1349 !(mode->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE))) {
1350 fb_videomode_to_var(var, mode);
1351 return;
1352 }
1353 }
1354
1355 if (info->monspecs.gtf && !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1356 return;
1357 /* Use default refresh rate */
1358 var->pixclock = 0;
1359}
1360
1361static int uvesafb_check_var(struct fb_var_screeninfo *var,
1362 struct fb_info *info)
1363{
1364 struct uvesafb_par *par = info->par;
1365 struct vbe_mode_ib *mode = NULL;
1366 int match = -1;
1367 int depth = var->red.length + var->green.length + var->blue.length;
1368
1369 /*
1370 * Various apps will use bits_per_pixel to set the color depth,
1371 * which is theoretically incorrect, but which we'll try to handle
1372 * here.
1373 */
1374 if (depth == 0 || abs(depth - var->bits_per_pixel) >= 8)
1375 depth = var->bits_per_pixel;
1376
1377 match = uvesafb_vbe_find_mode(par, var->xres, var->yres, depth,
1378 UVESAFB_EXACT_RES);
1379 if (match == -1)
1380 return -EINVAL;
1381
1382 mode = &par->vbe_modes[match];
1383 uvesafb_setup_var(var, info, mode);
1384
1385 /*
1386 * Check whether we have remapped enough memory for this mode.
1387 * We might be called at an early stage, when we haven't remapped
1388 * any memory yet, in which case we simply skip the check.
1389 */
1390 if (var->yres * mode->bytes_per_scan_line > info->fix.smem_len
1391 && info->fix.smem_len)
1392 return -EINVAL;
1393
1394 if ((var->vmode & FB_VMODE_DOUBLE) &&
1395 !(par->vbe_modes[match].mode_attr & 0x100))
1396 var->vmode &= ~FB_VMODE_DOUBLE;
1397
1398 if ((var->vmode & FB_VMODE_INTERLACED) &&
1399 !(par->vbe_modes[match].mode_attr & 0x200))
1400 var->vmode &= ~FB_VMODE_INTERLACED;
1401
1402 uvesafb_check_limits(var, info);
1403
1404 var->xres_virtual = var->xres;
1405 var->yres_virtual = (par->ypan) ?
1406 info->fix.smem_len / mode->bytes_per_scan_line :
1407 var->yres;
1408 return 0;
1409}
1410
1411static void uvesafb_save_state(struct fb_info *info)
1412{
1413 struct uvesafb_par *par = info->par;
1414
1415 if (par->vbe_state_saved)
1416 kfree(par->vbe_state_saved);
1417
1418 par->vbe_state_saved = uvesafb_vbe_state_save(par);
1419}
1420
1421static void uvesafb_restore_state(struct fb_info *info)
1422{
1423 struct uvesafb_par *par = info->par;
1424
1425 uvesafb_vbe_state_restore(par, par->vbe_state_saved);
1426}
1427
1428static struct fb_ops uvesafb_ops = {
1429 .owner = THIS_MODULE,
1430 .fb_open = uvesafb_open,
1431 .fb_release = uvesafb_release,
1432 .fb_setcolreg = uvesafb_setcolreg,
1433 .fb_setcmap = uvesafb_setcmap,
1434 .fb_pan_display = uvesafb_pan_display,
1435 .fb_blank = uvesafb_blank,
1436 .fb_fillrect = cfb_fillrect,
1437 .fb_copyarea = cfb_copyarea,
1438 .fb_imageblit = cfb_imageblit,
1439 .fb_check_var = uvesafb_check_var,
1440 .fb_set_par = uvesafb_set_par,
1441 .fb_save_state = uvesafb_save_state,
1442 .fb_restore_state = uvesafb_restore_state,
1443};
1444
1445static void __devinit uvesafb_init_info(struct fb_info *info,
1446 struct vbe_mode_ib *mode)
1447{
1448 unsigned int size_vmode;
1449 unsigned int size_remap;
1450 unsigned int size_total;
1451 struct uvesafb_par *par = info->par;
1452 int i, h;
1453
1454 info->pseudo_palette = ((u8 *)info->par + sizeof(struct uvesafb_par));
1455 info->fix = uvesafb_fix;
1456 info->fix.ypanstep = par->ypan ? 1 : 0;
1457 info->fix.ywrapstep = (par->ypan > 1) ? 1 : 0;
1458
1459 /*
1460 * If we were unable to get the state buffer size, disable
1461 * functions for saving and restoring the hardware state.
1462 */
1463 if (par->vbe_state_size == 0) {
1464 info->fbops->fb_save_state = NULL;
1465 info->fbops->fb_restore_state = NULL;
1466 }
1467
1468 /* Disable blanking if the user requested so. */
1469 if (!blank)
1470 info->fbops->fb_blank = NULL;
1471
1472 /*
1473 * Find out how much IO memory is required for the mode with
1474 * the highest resolution.
1475 */
1476 size_remap = 0;
1477 for (i = 0; i < par->vbe_modes_cnt; i++) {
1478 h = par->vbe_modes[i].bytes_per_scan_line *
1479 par->vbe_modes[i].y_res;
1480 if (h > size_remap)
1481 size_remap = h;
1482 }
1483 size_remap *= 2;
1484
1485 /*
1486 * size_vmode -- that is the amount of memory needed for the
1487 * used video mode, i.e. the minimum amount of
1488 * memory we need.
1489 */
1490 if (mode != NULL) {
1491 size_vmode = info->var.yres * mode->bytes_per_scan_line;
1492 } else {
1493 size_vmode = info->var.yres * info->var.xres *
1494 ((info->var.bits_per_pixel + 7) >> 3);
1495 }
1496
1497 /*
1498 * size_total -- all video memory we have. Used for mtrr
1499 * entries, resource allocation and bounds
1500 * checking.
1501 */
1502 size_total = par->vbe_ib.total_memory * 65536;
1503 if (vram_total)
1504 size_total = vram_total * 1024 * 1024;
1505 if (size_total < size_vmode)
1506 size_total = size_vmode;
1507
1508 /*
1509 * size_remap -- the amount of video memory we are going to
1510 * use for vesafb. With modern cards it is no
1511 * option to simply use size_total as th
1512 * wastes plenty of kernel address space.
1513 */
1514 if (vram_remap)
1515 size_remap = vram_remap * 1024 * 1024;
1516 if (size_remap < size_vmode)
1517 size_remap = size_vmode;
1518 if (size_remap > size_total)
1519 size_remap = size_total;
1520
1521 info->fix.smem_len = size_remap;
1522 info->fix.smem_start = mode->phys_base_ptr;
1523
1524 /*
1525 * We have to set yres_virtual here because when setup_var() was
1526 * called, smem_len wasn't defined yet.
1527 */
1528 info->var.yres_virtual = info->fix.smem_len /
1529 mode->bytes_per_scan_line;
1530
1531 if (par->ypan && info->var.yres_virtual > info->var.yres) {
1532 printk(KERN_INFO "uvesafb: scrolling: %s "
1533 "using protected mode interface, "
1534 "yres_virtual=%d\n",
1535 (par->ypan > 1) ? "ywrap" : "ypan",
1536 info->var.yres_virtual);
1537 } else {
1538 printk(KERN_INFO "uvesafb: scrolling: redraw\n");
1539 info->var.yres_virtual = info->var.yres;
1540 par->ypan = 0;
1541 }
1542
1543 info->flags = FBINFO_FLAG_DEFAULT |
1544 (par->ypan) ? FBINFO_HWACCEL_YPAN : 0;
1545
1546 if (!par->ypan)
1547 info->fbops->fb_pan_display = NULL;
1548}
1549
1550static void uvesafb_init_mtrr(struct fb_info *info)
1551{
1552#ifdef CONFIG_MTRR
1553 if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
1554 int temp_size = info->fix.smem_len;
1555 unsigned int type = 0;
1556
1557 switch (mtrr) {
1558 case 1:
1559 type = MTRR_TYPE_UNCACHABLE;
1560 break;
1561 case 2:
1562 type = MTRR_TYPE_WRBACK;
1563 break;
1564 case 3:
1565 type = MTRR_TYPE_WRCOMB;
1566 break;
1567 case 4:
1568 type = MTRR_TYPE_WRTHROUGH;
1569 break;
1570 default:
1571 type = 0;
1572 break;
1573 }
1574
1575 if (type) {
1576 int rc;
1577
1578 /* Find the largest power-of-two */
1579 while (temp_size & (temp_size - 1))
1580 temp_size &= (temp_size - 1);
1581
1582 /* Try and find a power of two to add */
1583 do {
1584 rc = mtrr_add(info->fix.smem_start,
1585 temp_size, type, 1);
1586 temp_size >>= 1;
1587 } while (temp_size >= PAGE_SIZE && rc == -EINVAL);
1588 }
1589 }
1590#endif /* CONFIG_MTRR */
1591}
1592
1593
1594static ssize_t uvesafb_show_vbe_ver(struct device *dev,
1595 struct device_attribute *attr, char *buf)
1596{
1597 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1598 struct uvesafb_par *par = info->par;
1599
1600 return snprintf(buf, PAGE_SIZE, "%.4x\n", par->vbe_ib.vbe_version);
1601}
1602
1603static DEVICE_ATTR(vbe_version, S_IRUGO, uvesafb_show_vbe_ver, NULL);
1604
1605static ssize_t uvesafb_show_vbe_modes(struct device *dev,
1606 struct device_attribute *attr, char *buf)
1607{
1608 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1609 struct uvesafb_par *par = info->par;
1610 int ret = 0, i;
1611
1612 for (i = 0; i < par->vbe_modes_cnt && ret < PAGE_SIZE; i++) {
1613 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1614 "%dx%d-%d, 0x%.4x\n",
1615 par->vbe_modes[i].x_res, par->vbe_modes[i].y_res,
1616 par->vbe_modes[i].depth, par->vbe_modes[i].mode_id);
1617 }
1618
1619 return ret;
1620}
1621
1622static DEVICE_ATTR(vbe_modes, S_IRUGO, uvesafb_show_vbe_modes, NULL);
1623
1624static ssize_t uvesafb_show_vendor(struct device *dev,
1625 struct device_attribute *attr, char *buf)
1626{
1627 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1628 struct uvesafb_par *par = info->par;
1629
1630 if (par->vbe_ib.oem_vendor_name_ptr)
1631 return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1632 (&par->vbe_ib) + par->vbe_ib.oem_vendor_name_ptr);
1633 else
1634 return 0;
1635}
1636
1637static DEVICE_ATTR(oem_vendor, S_IRUGO, uvesafb_show_vendor, NULL);
1638
1639static ssize_t uvesafb_show_product_name(struct device *dev,
1640 struct device_attribute *attr, char *buf)
1641{
1642 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1643 struct uvesafb_par *par = info->par;
1644
1645 if (par->vbe_ib.oem_product_name_ptr)
1646 return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1647 (&par->vbe_ib) + par->vbe_ib.oem_product_name_ptr);
1648 else
1649 return 0;
1650}
1651
1652static DEVICE_ATTR(oem_product_name, S_IRUGO, uvesafb_show_product_name, NULL);
1653
1654static ssize_t uvesafb_show_product_rev(struct device *dev,
1655 struct device_attribute *attr, char *buf)
1656{
1657 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1658 struct uvesafb_par *par = info->par;
1659
1660 if (par->vbe_ib.oem_product_rev_ptr)
1661 return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1662 (&par->vbe_ib) + par->vbe_ib.oem_product_rev_ptr);
1663 else
1664 return 0;
1665}
1666
1667static DEVICE_ATTR(oem_product_rev, S_IRUGO, uvesafb_show_product_rev, NULL);
1668
1669static ssize_t uvesafb_show_oem_string(struct device *dev,
1670 struct device_attribute *attr, char *buf)
1671{
1672 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1673 struct uvesafb_par *par = info->par;
1674
1675 if (par->vbe_ib.oem_string_ptr)
1676 return snprintf(buf, PAGE_SIZE, "%s\n",
1677 (char *)(&par->vbe_ib) + par->vbe_ib.oem_string_ptr);
1678 else
1679 return 0;
1680}
1681
1682static DEVICE_ATTR(oem_string, S_IRUGO, uvesafb_show_oem_string, NULL);
1683
1684static ssize_t uvesafb_show_nocrtc(struct device *dev,
1685 struct device_attribute *attr, char *buf)
1686{
1687 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1688 struct uvesafb_par *par = info->par;
1689
1690 return snprintf(buf, PAGE_SIZE, "%d\n", par->nocrtc);
1691}
1692
1693static ssize_t uvesafb_store_nocrtc(struct device *dev,
1694 struct device_attribute *attr, const char *buf, size_t count)
1695{
1696 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1697 struct uvesafb_par *par = info->par;
1698
1699 if (count > 0) {
1700 if (buf[0] == '0')
1701 par->nocrtc = 0;
1702 else
1703 par->nocrtc = 1;
1704 }
1705 return count;
1706}
1707
1708static DEVICE_ATTR(nocrtc, S_IRUGO | S_IWUSR, uvesafb_show_nocrtc,
1709 uvesafb_store_nocrtc);
1710
1711static struct attribute *uvesafb_dev_attrs[] = {
1712 &dev_attr_vbe_version.attr,
1713 &dev_attr_vbe_modes.attr,
1714 &dev_attr_oem_vendor.attr,
1715 &dev_attr_oem_product_name.attr,
1716 &dev_attr_oem_product_rev.attr,
1717 &dev_attr_oem_string.attr,
1718 &dev_attr_nocrtc.attr,
1719 NULL,
1720};
1721
1722static struct attribute_group uvesafb_dev_attgrp = {
1723 .name = NULL,
1724 .attrs = uvesafb_dev_attrs,
1725};
1726
1727static int __devinit uvesafb_probe(struct platform_device *dev)
1728{
1729 struct fb_info *info;
1730 struct vbe_mode_ib *mode = NULL;
1731 struct uvesafb_par *par;
1732 int err = 0, i;
1733
1734 info = framebuffer_alloc(sizeof(*par) + sizeof(u32) * 256, &dev->dev);
1735 if (!info)
1736 return -ENOMEM;
1737
1738 par = info->par;
1739
1740 err = uvesafb_vbe_init(info);
1741 if (err) {
1742 printk(KERN_ERR "uvesafb: vbe_init() failed with %d\n", err);
1743 goto out;
1744 }
1745
1746 info->fbops = &uvesafb_ops;
1747
1748 i = uvesafb_vbe_init_mode(info);
1749 if (i < 0) {
1750 err = -EINVAL;
1751 goto out;
1752 } else {
1753 mode = &par->vbe_modes[i];
1754 }
1755
1756 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
1757 err = -ENXIO;
1758 goto out;
1759 }
1760
1761 uvesafb_init_info(info, mode);
1762
1763 if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
1764 "uvesafb")) {
1765 printk(KERN_ERR "uvesafb: cannot reserve video memory at "
1766 "0x%lx\n", info->fix.smem_start);
1767 err = -EIO;
1768 goto out_mode;
1769 }
1770
1771 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1772
1773 if (!info->screen_base) {
1774 printk(KERN_ERR
1775 "uvesafb: abort, cannot ioremap 0x%x bytes of video "
1776 "memory at 0x%lx\n",
1777 info->fix.smem_len, info->fix.smem_start);
1778 err = -EIO;
1779 goto out_mem;
1780 }
1781
1782 if (!request_region(0x3c0, 32, "uvesafb")) {
1783 printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
1784 err = -EIO;
1785 goto out_unmap;
1786 }
1787
1788 uvesafb_init_mtrr(info);
1789 platform_set_drvdata(dev, info);
1790
1791 if (register_framebuffer(info) < 0) {
1792 printk(KERN_ERR
1793 "uvesafb: failed to register framebuffer device\n");
1794 err = -EINVAL;
1795 goto out_reg;
1796 }
1797
1798 printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
1799 "using %dk, total %dk\n", info->fix.smem_start,
1800 info->screen_base, info->fix.smem_len/1024,
1801 par->vbe_ib.total_memory * 64);
1802 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
1803 info->fix.id);
1804
1805 err = sysfs_create_group(&dev->dev.kobj, &uvesafb_dev_attgrp);
1806 if (err != 0)
1807 printk(KERN_WARNING "fb%d: failed to register attributes\n",
1808 info->node);
1809
1810 return 0;
1811
1812out_reg:
1813 release_region(0x3c0, 32);
1814out_unmap:
1815 iounmap(info->screen_base);
1816out_mem:
1817 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1818out_mode:
1819 if (!list_empty(&info->modelist))
1820 fb_destroy_modelist(&info->modelist);
1821 fb_destroy_modedb(info->monspecs.modedb);
1822 fb_dealloc_cmap(&info->cmap);
1823out:
1824 if (par->vbe_modes)
1825 kfree(par->vbe_modes);
1826
1827 framebuffer_release(info);
1828 return err;
1829}
1830
1831static int uvesafb_remove(struct platform_device *dev)
1832{
1833 struct fb_info *info = platform_get_drvdata(dev);
1834
1835 if (info) {
1836 struct uvesafb_par *par = info->par;
1837
1838 sysfs_remove_group(&dev->dev.kobj, &uvesafb_dev_attgrp);
1839 unregister_framebuffer(info);
1840 release_region(0x3c0, 32);
1841 iounmap(info->screen_base);
1842 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1843 fb_destroy_modedb(info->monspecs.modedb);
1844 fb_dealloc_cmap(&info->cmap);
1845
1846 if (par) {
1847 if (par->vbe_modes)
1848 kfree(par->vbe_modes);
1849 if (par->vbe_state_orig)
1850 kfree(par->vbe_state_orig);
1851 if (par->vbe_state_saved)
1852 kfree(par->vbe_state_saved);
1853 }
1854
1855 framebuffer_release(info);
1856 }
1857 return 0;
1858}
1859
1860static struct platform_driver uvesafb_driver = {
1861 .probe = uvesafb_probe,
1862 .remove = uvesafb_remove,
1863 .driver = {
1864 .name = "uvesafb",
1865 },
1866};
1867
1868static struct platform_device *uvesafb_device;
1869
1870#ifndef MODULE
1871static int __devinit uvesafb_setup(char *options)
1872{
1873 char *this_opt;
1874
1875 if (!options || !*options)
1876 return 0;
1877
1878 while ((this_opt = strsep(&options, ",")) != NULL) {
1879 if (!*this_opt) continue;
1880
1881 if (!strcmp(this_opt, "redraw"))
1882 ypan = 0;
1883 else if (!strcmp(this_opt, "ypan"))
1884 ypan = 1;
1885 else if (!strcmp(this_opt, "ywrap"))
1886 ypan = 2;
1887 else if (!strcmp(this_opt, "vgapal"))
1888 pmi_setpal = 0;
1889 else if (!strcmp(this_opt, "pmipal"))
1890 pmi_setpal = 1;
1891 else if (!strncmp(this_opt, "mtrr:", 5))
1892 mtrr = simple_strtoul(this_opt+5, NULL, 0);
1893 else if (!strcmp(this_opt, "nomtrr"))
1894 mtrr = 0;
1895 else if (!strcmp(this_opt, "nocrtc"))
1896 nocrtc = 1;
1897 else if (!strcmp(this_opt, "noedid"))
1898 noedid = 1;
1899 else if (!strcmp(this_opt, "noblank"))
1900 blank = 0;
1901 else if (!strncmp(this_opt, "vtotal:", 7))
1902 vram_total = simple_strtoul(this_opt + 7, NULL, 0);
1903 else if (!strncmp(this_opt, "vremap:", 7))
1904 vram_remap = simple_strtoul(this_opt + 7, NULL, 0);
1905 else if (!strncmp(this_opt, "maxhf:", 6))
1906 maxhf = simple_strtoul(this_opt + 6, NULL, 0);
1907 else if (!strncmp(this_opt, "maxvf:", 6))
1908 maxvf = simple_strtoul(this_opt + 6, NULL, 0);
1909 else if (!strncmp(this_opt, "maxclk:", 7))
1910 maxclk = simple_strtoul(this_opt + 7, NULL, 0);
1911 else if (!strncmp(this_opt, "vbemode:", 8))
1912 vbemode = simple_strtoul(this_opt + 8, NULL, 0);
1913 else if (this_opt[0] >= '0' && this_opt[0] <= '9') {
1914 mode_option = this_opt;
1915 } else {
1916 printk(KERN_WARNING
1917 "uvesafb: unrecognized option %s\n", this_opt);
1918 }
1919 }
1920
1921 return 0;
1922}
1923#endif /* !MODULE */
1924
1925static ssize_t show_v86d(struct device_driver *dev, char *buf)
1926{
1927 return snprintf(buf, PAGE_SIZE, "%s\n", v86d_path);
1928}
1929
1930static ssize_t store_v86d(struct device_driver *dev, const char *buf,
1931 size_t count)
1932{
1933 strncpy(v86d_path, buf, PATH_MAX);
1934 return count;
1935}
1936
1937static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d);
1938
1939static int __devinit uvesafb_init(void)
1940{
1941 int err;
1942
1943#ifndef MODULE
1944 char *option = NULL;
1945
1946 if (fb_get_options("uvesafb", &option))
1947 return -ENODEV;
1948 uvesafb_setup(option);
1949#endif
1950 err = cn_add_callback(&uvesafb_cn_id, "uvesafb", uvesafb_cn_callback);
1951 if (err)
1952 return err;
1953
1954 err = platform_driver_register(&uvesafb_driver);
1955
1956 if (!err) {
1957 uvesafb_device = platform_device_alloc("uvesafb", 0);
1958 if (uvesafb_device)
1959 err = platform_device_add(uvesafb_device);
1960 else
1961 err = -ENOMEM;
1962
1963 if (err) {
1964 platform_device_put(uvesafb_device);
1965 platform_driver_unregister(&uvesafb_driver);
1966 cn_del_callback(&uvesafb_cn_id);
1967 return err;
1968 }
1969
1970 err = driver_create_file(&uvesafb_driver.driver,
1971 &driver_attr_v86d);
1972 if (err) {
1973 printk(KERN_WARNING "uvesafb: failed to register "
1974 "attributes\n");
1975 err = 0;
1976 }
1977 }
1978 return err;
1979}
1980
1981module_init(uvesafb_init);
1982
1983static void __devexit uvesafb_exit(void)
1984{
1985 struct uvesafb_ktask *task;
1986
1987 if (v86d_started) {
1988 task = uvesafb_prep();
1989 if (task) {
1990 task->t.flags = TF_EXIT;
1991 uvesafb_exec(task);
1992 uvesafb_free(task);
1993 }
1994 }
1995
1996 cn_del_callback(&uvesafb_cn_id);
1997 driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
1998 platform_device_unregister(uvesafb_device);
1999 platform_driver_unregister(&uvesafb_driver);
2000}
2001
2002module_exit(uvesafb_exit);
2003
2004static inline int param_get_scroll(char *buffer, struct kernel_param *kp)
2005{
2006 return 0;
2007}
2008
2009static inline int param_set_scroll(const char *val, struct kernel_param *kp)
2010{
2011 ypan = 0;
2012
2013 if (!strcmp(val, "redraw"))
2014 ypan = 0;
2015 else if (!strcmp(val, "ypan"))
2016 ypan = 1;
2017 else if (!strcmp(val, "ywrap"))
2018 ypan = 2;
2019
2020 return 0;
2021}
2022
2023#define param_check_scroll(name, p) __param_check(name, p, void);
2024
2025module_param_named(scroll, ypan, scroll, 0);
2026MODULE_PARM_DESC(scroll,
2027 "Scrolling mode, set to 'redraw', ''ypan' or 'ywrap'");
2028module_param_named(vgapal, pmi_setpal, invbool, 0);
2029MODULE_PARM_DESC(vgapal, "Set palette using VGA registers");
2030module_param_named(pmipal, pmi_setpal, bool, 0);
2031MODULE_PARM_DESC(pmipal, "Set palette using PMI calls");
2032module_param(mtrr, uint, 0);
2033MODULE_PARM_DESC(mtrr,
2034 "Memory Type Range Registers setting. Use 0 to disable.");
2035module_param(blank, bool, 0);
2036MODULE_PARM_DESC(blank, "Enable hardware blanking");
2037module_param(nocrtc, bool, 0);
2038MODULE_PARM_DESC(nocrtc, "Ignore CRTC timings when setting modes");
2039module_param(noedid, bool, 0);
2040MODULE_PARM_DESC(noedid,
2041 "Ignore EDID-provided monitor limits when setting modes");
2042module_param(vram_remap, uint, 0);
2043MODULE_PARM_DESC(vram_remap, "Set amount of video memory to be used [MiB]");
2044module_param(vram_total, uint, 0);
2045MODULE_PARM_DESC(vram_total, "Set total amount of video memoery [MiB]");
2046module_param(maxclk, ushort, 0);
2047MODULE_PARM_DESC(maxclk, "Maximum pixelclock [MHz], overrides EDID data");
2048module_param(maxhf, ushort, 0);
2049MODULE_PARM_DESC(maxhf,
2050 "Maximum horizontal frequency [kHz], overrides EDID data");
2051module_param(maxvf, ushort, 0);
2052MODULE_PARM_DESC(maxvf,
2053 "Maximum vertical frequency [Hz], overrides EDID data");
2054module_param_named(mode, mode_option, charp, 0);
2055MODULE_PARM_DESC(mode,
2056 "Specify initial video mode as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
2057module_param(vbemode, ushort, 0);
2058MODULE_PARM_DESC(vbemode,
2059 "VBE mode number to set, overrides the 'mode' option");
2060module_param_string(v86d, v86d_path, PATH_MAX, 0660);
2061MODULE_PARM_DESC(v86d, "Path to the v86d userspace helper.");
2062
2063MODULE_LICENSE("GPL");
2064MODULE_AUTHOR("Michal Januszewski <spock@gentoo.org>");
2065MODULE_DESCRIPTION("Framebuffer driver for VBE2.0+ compliant graphics boards");
2066
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index de531c907718..ff9e805c43bc 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -39,7 +39,6 @@
39#include <asm/cacheflush.h> 39#include <asm/cacheflush.h>
40#include <asm/tlbflush.h> 40#include <asm/tlbflush.h>
41#include <linux/mmzone.h> 41#include <linux/mmzone.h>
42#include <asm/uaccess.h>
43 42
44/* #define VERMILION_DEBUG */ 43/* #define VERMILION_DEBUG */
45 44
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 64ee78c3c12b..072638a9528a 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -21,7 +21,6 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23 23
24#include <asm/uaccess.h>
25#include <linux/fb.h> 24#include <linux/fb.h>
26#include <linux/init.h> 25#include <linux/init.h>
27 26
@@ -38,6 +37,48 @@ static void *videomemory;
38static u_long videomemorysize = VIDEOMEMSIZE; 37static u_long videomemorysize = VIDEOMEMSIZE;
39module_param(videomemorysize, ulong, 0); 38module_param(videomemorysize, ulong, 0);
40 39
40/**********************************************************************
41 *
42 * Memory management
43 *
44 **********************************************************************/
45static void *rvmalloc(unsigned long size)
46{
47 void *mem;
48 unsigned long adr;
49
50 size = PAGE_ALIGN(size);
51 mem = vmalloc_32(size);
52 if (!mem)
53 return NULL;
54
55 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
56 adr = (unsigned long) mem;
57 while (size > 0) {
58 SetPageReserved(vmalloc_to_page((void *)adr));
59 adr += PAGE_SIZE;
60 size -= PAGE_SIZE;
61 }
62
63 return mem;
64}
65
66static void rvfree(void *mem, unsigned long size)
67{
68 unsigned long adr;
69
70 if (!mem)
71 return;
72
73 adr = (unsigned long) mem;
74 while ((long) size > 0) {
75 ClearPageReserved(vmalloc_to_page((void *)adr));
76 adr += PAGE_SIZE;
77 size -= PAGE_SIZE;
78 }
79 vfree(mem);
80}
81
41static struct fb_var_screeninfo vfb_default __initdata = { 82static struct fb_var_screeninfo vfb_default __initdata = {
42 .xres = 640, 83 .xres = 640,
43 .yres = 480, 84 .yres = 480,
@@ -372,7 +413,33 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
372static int vfb_mmap(struct fb_info *info, 413static int vfb_mmap(struct fb_info *info,
373 struct vm_area_struct *vma) 414 struct vm_area_struct *vma)
374{ 415{
375 return -EINVAL; 416 unsigned long start = vma->vm_start;
417 unsigned long size = vma->vm_end - vma->vm_start;
418 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
419 unsigned long page, pos;
420
421 if (offset + size > info->fix.smem_len) {
422 return -EINVAL;
423 }
424
425 pos = (unsigned long)info->fix.smem_start + offset;
426
427 while (size > 0) {
428 page = vmalloc_to_pfn((void *)pos);
429 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
430 return -EAGAIN;
431 }
432 start += PAGE_SIZE;
433 pos += PAGE_SIZE;
434 if (size > PAGE_SIZE)
435 size -= PAGE_SIZE;
436 else
437 size = 0;
438 }
439
440 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
441 return 0;
442
376} 443}
377 444
378#ifndef MODULE 445#ifndef MODULE
@@ -407,7 +474,7 @@ static int __init vfb_probe(struct platform_device *dev)
407 /* 474 /*
408 * For real video cards we use ioremap. 475 * For real video cards we use ioremap.
409 */ 476 */
410 if (!(videomemory = vmalloc(videomemorysize))) 477 if (!(videomemory = rvmalloc(videomemorysize)))
411 return retval; 478 return retval;
412 479
413 /* 480 /*
@@ -430,6 +497,8 @@ static int __init vfb_probe(struct platform_device *dev)
430 497
431 if (!retval || (retval == 4)) 498 if (!retval || (retval == 4))
432 info->var = vfb_default; 499 info->var = vfb_default;
500 vfb_fix.smem_start = (unsigned long) videomemory;
501 vfb_fix.smem_len = videomemorysize;
433 info->fix = vfb_fix; 502 info->fix = vfb_fix;
434 info->pseudo_palette = info->par; 503 info->pseudo_palette = info->par;
435 info->par = NULL; 504 info->par = NULL;
@@ -453,7 +522,7 @@ err2:
453err1: 522err1:
454 framebuffer_release(info); 523 framebuffer_release(info);
455err: 524err:
456 vfree(videomemory); 525 rvfree(videomemory, videomemorysize);
457 return retval; 526 return retval;
458} 527}
459 528
@@ -463,7 +532,7 @@ static int vfb_remove(struct platform_device *dev)
463 532
464 if (info) { 533 if (info) {
465 unregister_framebuffer(info); 534 unregister_framebuffer(info);
466 vfree(videomemory); 535 rvfree(videomemory, videomemorysize);
467 framebuffer_release(info); 536 framebuffer_release(info);
468 } 537 }
469 return 0; 538 return 0;