diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-12-17 20:04:45 +0000 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-12-17 20:04:45 +0000 |
commit | c613bbba6f39c8804f1f26e96fb68a117cc9e282 (patch) | |
tree | 85fbc24f26b61ce4e7a908d18952e3abc1f5cd10 /drivers | |
parent | cd4348339c21f4a15c01f3f120e92b3224a0a7da (diff) | |
parent | 80eee6bca4069c48247005aa07cb5e8e86042aa3 (diff) |
Merge branch 'mxc-pu-imxfb' of git://pasiphae.extern.pengutronix.de/git/imx/linux-2.6 into devel
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/toshiba_acpi.c | 54 | ||||
-rw-r--r-- | drivers/cdrom/cdrom.c | 16 | ||||
-rw-r--r-- | drivers/char/cp437.uni | 12 | ||||
-rw-r--r-- | drivers/char/vt.c | 2 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-highlander.c | 4 | ||||
-rw-r--r-- | drivers/i2c/busses/i2c-pmcmsp.c | 2 | ||||
-rw-r--r-- | drivers/net/e1000e/ich8lan.c | 9 | ||||
-rw-r--r-- | drivers/net/sungem.c | 144 | ||||
-rw-r--r-- | drivers/pcmcia/bfin_cf_pcmcia.c | 2 | ||||
-rw-r--r-- | drivers/scsi/device_handler/scsi_dh_hp_sw.c | 12 | ||||
-rw-r--r-- | drivers/video/aty/radeon_accel.c | 295 | ||||
-rw-r--r-- | drivers/video/aty/radeon_backlight.c | 2 | ||||
-rw-r--r-- | drivers/video/aty/radeon_base.c | 46 | ||||
-rw-r--r-- | drivers/video/aty/radeon_pm.c | 6 | ||||
-rw-r--r-- | drivers/video/aty/radeonfb.h | 40 | ||||
-rw-r--r-- | drivers/video/imxfb.c | 468 | ||||
-rw-r--r-- | drivers/video/imxfb.h | 73 |
17 files changed, 542 insertions, 645 deletions
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index 25f531d892d..40e60fc2e59 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c @@ -824,32 +824,36 @@ static int __init toshiba_acpi_init(void) toshiba_acpi_exit(); return -ENOMEM; } - } - /* Register input device for kill switch */ - toshiba_acpi.poll_dev = input_allocate_polled_device(); - if (!toshiba_acpi.poll_dev) { - printk(MY_ERR "unable to allocate kill-switch input device\n"); - toshiba_acpi_exit(); - return -ENOMEM; - } - toshiba_acpi.poll_dev->private = &toshiba_acpi; - toshiba_acpi.poll_dev->poll = bt_poll_rfkill; - toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */ - - toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name; - toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST; - toshiba_acpi.poll_dev->input->id.vendor = 0x0930; /* Toshiba USB ID */ - set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit); - set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit); - input_report_switch(toshiba_acpi.poll_dev->input, SW_RFKILL_ALL, TRUE); - input_sync(toshiba_acpi.poll_dev->input); - - ret = input_register_polled_device(toshiba_acpi.poll_dev); - if (ret) { - printk(MY_ERR "unable to register kill-switch input device\n"); - toshiba_acpi_exit(); - return ret; + /* Register input device for kill switch */ + toshiba_acpi.poll_dev = input_allocate_polled_device(); + if (!toshiba_acpi.poll_dev) { + printk(MY_ERR + "unable to allocate kill-switch input device\n"); + toshiba_acpi_exit(); + return -ENOMEM; + } + toshiba_acpi.poll_dev->private = &toshiba_acpi; + toshiba_acpi.poll_dev->poll = bt_poll_rfkill; + toshiba_acpi.poll_dev->poll_interval = 1000; /* msecs */ + + toshiba_acpi.poll_dev->input->name = toshiba_acpi.rfk_name; + toshiba_acpi.poll_dev->input->id.bustype = BUS_HOST; + /* Toshiba USB ID */ + toshiba_acpi.poll_dev->input->id.vendor = 0x0930; + set_bit(EV_SW, toshiba_acpi.poll_dev->input->evbit); + set_bit(SW_RFKILL_ALL, toshiba_acpi.poll_dev->input->swbit); + input_report_switch(toshiba_acpi.poll_dev->input, + SW_RFKILL_ALL, TRUE); + input_sync(toshiba_acpi.poll_dev->input); + + ret = input_register_polled_device(toshiba_acpi.poll_dev); + if (ret) { + printk(MY_ERR + "unable to register kill-switch input device\n"); + toshiba_acpi_exit(); + return ret; + } } return 0; diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index d16b02423d6..7d2e91cccb1 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -2081,10 +2081,6 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, if (!q) return -ENXIO; - rq = blk_get_request(q, READ, GFP_KERNEL); - if (!rq) - return -ENOMEM; - cdi->last_sense = 0; while (nframes) { @@ -2096,9 +2092,17 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, len = nr * CD_FRAMESIZE_RAW; + rq = blk_get_request(q, READ, GFP_KERNEL); + if (!rq) { + ret = -ENOMEM; + break; + } + ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL); - if (ret) + if (ret) { + blk_put_request(rq); break; + } rq->cmd[0] = GPCMD_READ_CD; rq->cmd[1] = 1 << 2; @@ -2124,6 +2128,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, if (blk_rq_unmap_user(bio)) ret = -EFAULT; + blk_put_request(rq); if (ret) break; @@ -2133,7 +2138,6 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf, ubuf += len; } - blk_put_request(rq); return ret; } diff --git a/drivers/char/cp437.uni b/drivers/char/cp437.uni index 1f06889a96b..bc6163484f6 100644 --- a/drivers/char/cp437.uni +++ b/drivers/char/cp437.uni @@ -27,7 +27,7 @@ 0x0c U+2640 0x0d U+266a 0x0e U+266b -0x0f U+263c +0x0f U+263c U+00a4 0x10 U+25b6 U+25ba 0x11 U+25c0 U+25c4 0x12 U+2195 @@ -55,7 +55,7 @@ 0x24 U+0024 0x25 U+0025 0x26 U+0026 -0x27 U+0027 +0x27 U+0027 U+00b4 0x28 U+0028 0x29 U+0029 0x2a U+002a @@ -84,7 +84,7 @@ 0x41 U+0041 U+00c0 U+00c1 U+00c2 U+00c3 0x42 U+0042 0x43 U+0043 U+00a9 -0x44 U+0044 +0x44 U+0044 U+00d0 0x45 U+0045 U+00c8 U+00ca U+00cb 0x46 U+0046 0x47 U+0047 @@ -140,7 +140,7 @@ 0x79 U+0079 U+00fd 0x7a U+007a 0x7b U+007b -0x7c U+007c U+00a5 +0x7c U+007c U+00a6 0x7d U+007d 0x7e U+007e # @@ -263,10 +263,10 @@ 0xe8 U+03a6 U+00d8 0xe9 U+0398 0xea U+03a9 U+2126 -0xeb U+03b4 +0xeb U+03b4 U+00f0 0xec U+221e 0xed U+03c6 U+00f8 -0xee U+03b5 +0xee U+03b5 U+2208 0xef U+2229 0xf0 U+2261 0xf1 U+00b1 diff --git a/drivers/char/vt.c b/drivers/char/vt.c index a5af6072e2b..008176edbd6 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -2274,7 +2274,7 @@ rescan_last_byte: continue; /* nothing to display */ } /* Glyph not found */ - if ((!(vc->vc_utf && !vc->vc_disp_ctrl) || c < 128) && !(c & ~charmask)) { + if ((!(vc->vc_utf && !vc->vc_disp_ctrl) && c < 128) && !(c & ~charmask)) { /* In legacy mode use the glyph we get by a 1:1 mapping. This would make absolutely no sense with Unicode in mind, but do this for ASCII characters since a font may lack diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c index f4d22ae9d29..e5a8dae4a28 100644 --- a/drivers/i2c/busses/i2c-highlander.c +++ b/drivers/i2c/busses/i2c-highlander.c @@ -92,7 +92,7 @@ static void highlander_i2c_setup(struct highlander_i2c_dev *dev) static void smbus_write_data(u8 *src, u16 *dst, int len) { for (; len > 1; len -= 2) { - *dst++ = be16_to_cpup((u16 *)src); + *dst++ = be16_to_cpup((__be16 *)src); src += 2; } @@ -103,7 +103,7 @@ static void smbus_write_data(u8 *src, u16 *dst, int len) static void smbus_read_data(u16 *src, u8 *dst, int len) { for (; len > 1; len -= 2) { - *(u16 *)dst = cpu_to_be16p(src++); + *(__be16 *)dst = cpu_to_be16p(src++); dst += 2; } diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c index dcf2045b522..0bdb2d7f057 100644 --- a/drivers/i2c/busses/i2c-pmcmsp.c +++ b/drivers/i2c/busses/i2c-pmcmsp.c @@ -486,7 +486,7 @@ static enum pmcmsptwi_xfer_result pmcmsptwi_xfer_cmd( if (cmd->type == MSP_TWI_CMD_WRITE || cmd->type == MSP_TWI_CMD_WRITE_READ) { - __be64 tmp = cpu_to_be64p((u64 *)cmd->write_data); + u64 tmp = be64_to_cpup((__be64 *)cmd->write_data); tmp >>= (MSP_MAX_BYTES_PER_RW - cmd->write_len) * 8; dev_dbg(&pmcmsptwi_adapter.dev, "Writing 0x%016llx\n", tmp); pmcmsptwi_writel(tmp & 0x00000000ffffffffLL, diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 523b9716a54..d115a6d30f2 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -1893,12 +1893,17 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ctrl |= E1000_CTRL_PHY_RST; } ret_val = e1000_acquire_swflag_ich8lan(hw); + /* Whether or not the swflag was acquired, we need to reset the part */ hw_dbg(hw, "Issuing a global reset to ich8lan"); ew32(CTRL, (ctrl | E1000_CTRL_RST)); msleep(20); - /* release the swflag because it is not reset by hardware reset */ - e1000_release_swflag_ich8lan(hw); + if (!ret_val) { + /* release the swflag because it is not reset by + * hardware reset + */ + e1000_release_swflag_ich8lan(hw); + } ret_val = e1000e_get_auto_rd_done(hw); if (ret_val) { diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c index 1349e419673..fed7eba65ea 100644 --- a/drivers/net/sungem.c +++ b/drivers/net/sungem.c @@ -1142,6 +1142,70 @@ static int gem_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } +static void gem_pcs_reset(struct gem *gp) +{ + int limit; + u32 val; + + /* Reset PCS unit. */ + val = readl(gp->regs + PCS_MIICTRL); + val |= PCS_MIICTRL_RST; + writel(val, gp->regs + PCS_MIICTRL); + + limit = 32; + while (readl(gp->regs + PCS_MIICTRL) & PCS_MIICTRL_RST) { + udelay(100); + if (limit-- <= 0) + break; + } + if (limit <= 0) + printk(KERN_WARNING "%s: PCS reset bit would not clear.\n", + gp->dev->name); +} + +static void gem_pcs_reinit_adv(struct gem *gp) +{ + u32 val; + + /* Make sure PCS is disabled while changing advertisement + * configuration. + */ + val = readl(gp->regs + PCS_CFG); + val &= ~(PCS_CFG_ENABLE | PCS_CFG_TO); + writel(val, gp->regs + PCS_CFG); + + /* Advertise all capabilities except assymetric + * pause. + */ + val = readl(gp->regs + PCS_MIIADV); + val |= (PCS_MIIADV_FD | PCS_MIIADV_HD | + PCS_MIIADV_SP | PCS_MIIADV_AP); + writel(val, gp->regs + PCS_MIIADV); + + /* Enable and restart auto-negotiation, disable wrapback/loopback, + * and re-enable PCS. + */ + val = readl(gp->regs + PCS_MIICTRL); + val |= (PCS_MIICTRL_RAN | PCS_MIICTRL_ANE); + val &= ~PCS_MIICTRL_WB; + writel(val, gp->regs + PCS_MIICTRL); + + val = readl(gp->regs + PCS_CFG); + val |= PCS_CFG_ENABLE; + writel(val, gp->regs + PCS_CFG); + + /* Make sure serialink loopback is off. The meaning + * of this bit is logically inverted based upon whether + * you are in Serialink or SERDES mode. + */ + val = readl(gp->regs + PCS_SCTRL); + if (gp->phy_type == phy_serialink) + val &= ~PCS_SCTRL_LOOP; + else + val |= PCS_SCTRL_LOOP; + writel(val, gp->regs + PCS_SCTRL); +} + #define STOP_TRIES 32 /* Must be invoked under gp->lock and gp->tx_lock. */ @@ -1168,6 +1232,9 @@ static void gem_reset(struct gem *gp) if (limit <= 0) printk(KERN_ERR "%s: SW reset is ghetto.\n", gp->dev->name); + + if (gp->phy_type == phy_serialink || gp->phy_type == phy_serdes) + gem_pcs_reinit_adv(gp); } /* Must be invoked under gp->lock and gp->tx_lock. */ @@ -1324,7 +1391,7 @@ static int gem_set_link_modes(struct gem *gp) gp->phy_type == phy_serdes) { u32 pcs_lpa = readl(gp->regs + PCS_MIILP); - if (pcs_lpa & PCS_MIIADV_FD) + if ((pcs_lpa & PCS_MIIADV_FD) || gp->phy_type == phy_serdes) full_duplex = 1; speed = SPEED_1000; } @@ -1488,6 +1555,9 @@ static void gem_link_timer(unsigned long data) val = readl(gp->regs + PCS_MIISTAT); if ((val & PCS_MIISTAT_LS) != 0) { + if (gp->lstate == link_up) + goto restart; + gp->lstate = link_up; netif_carrier_on(gp->dev); (void)gem_set_link_modes(gp); @@ -1708,61 +1778,8 @@ static void gem_init_phy(struct gem *gp) if (gp->phy_mii.def && gp->phy_mii.def->ops->init) gp->phy_mii.def->ops->init(&gp->phy_mii); } else { - u32 val; - int limit; - - /* Reset PCS unit. */ - val = readl(gp->regs + PCS_MIICTRL); - val |= PCS_MIICTRL_RST; - writel(val, gp->regs + PCS_MIICTRL); - - limit = 32; - while (readl(gp->regs + PCS_MIICTRL) & PCS_MIICTRL_RST) { - udelay(100); - if (limit-- <= 0) - break; - } - if (limit <= 0) - printk(KERN_WARNING "%s: PCS reset bit would not clear.\n", - gp->dev->name); - - /* Make sure PCS is disabled while changing advertisement - * configuration. - */ - val = readl(gp->regs + PCS_CFG); - val &= ~(PCS_CFG_ENABLE | PCS_CFG_TO); - writel(val, gp->regs + PCS_CFG); - - /* Advertise all capabilities except assymetric - * pause. - */ - val = readl(gp->regs + PCS_MIIADV); - val |= (PCS_MIIADV_FD | PCS_MIIADV_HD | - PCS_MIIADV_SP | PCS_MIIADV_AP); - writel(val, gp->regs + PCS_MIIADV); - - /* Enable and restart auto-negotiation, disable wrapback/loopback, - * and re-enable PCS. - */ - val = readl(gp->regs + PCS_MIICTRL); - val |= (PCS_MIICTRL_RAN | PCS_MIICTRL_ANE); - val &= ~PCS_MIICTRL_WB; - writel(val, gp->regs + PCS_MIICTRL); - - val = readl(gp->regs + PCS_CFG); - val |= PCS_CFG_ENABLE; - writel(val, gp->regs + PCS_CFG); - - /* Make sure serialink loopback is off. The meaning - * of this bit is logically inverted based upon whether - * you are in Serialink or SERDES mode. - */ - val = readl(gp->regs + PCS_SCTRL); - if (gp->phy_type == phy_serialink) - val &= ~PCS_SCTRL_LOOP; - else - val |= PCS_SCTRL_LOOP; - writel(val, gp->regs + PCS_SCTRL); + gem_pcs_reset(gp); + gem_pcs_reinit_adv(gp); } /* Default aneg parameters */ @@ -2680,6 +2697,21 @@ static int gem_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->speed = 0; cmd->duplex = cmd->port = cmd->phy_address = cmd->transceiver = cmd->autoneg = 0; + + /* serdes means usually a Fibre connector, with most fixed */ + if (gp->phy_type == phy_serdes) { + cmd->port = PORT_FIBRE; + cmd->supported = (SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full | + SUPPORTED_FIBRE | SUPPORTED_Autoneg | + SUPPORTED_Pause | SUPPORTED_Asym_Pause); + cmd->advertising = cmd->supported; + cmd->transceiver = XCVR_INTERNAL; + if (gp->lstate == link_up) + cmd->speed = SPEED_1000; + cmd->duplex = DUPLEX_FULL; + cmd->autoneg = 1; + } } cmd->maxtxpkt = cmd->maxrxpkt = 0; diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c index bb7338863fb..b59d4115d20 100644 --- a/drivers/pcmcia/bfin_cf_pcmcia.c +++ b/drivers/pcmcia/bfin_cf_pcmcia.c @@ -334,6 +334,6 @@ static void __exit bfin_cf_exit(void) module_init(bfin_cf_init); module_exit(bfin_cf_exit); -MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>") +MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); MODULE_DESCRIPTION("BFIN CF/PCMCIA Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 9aec4ca64e5..f7da7530875 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c @@ -107,6 +107,7 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h) struct request *req; int ret; +retry: req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); if (!req) return SCSI_DH_RES_TEMP_UNAVAIL; @@ -121,7 +122,6 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h) memset(req->sense, 0, SCSI_SENSE_BUFFERSIZE); req->sense_len = 0; -retry: ret = blk_execute_rq(req->q, NULL, req, 1); if (ret == -EIO) { if (req->sense_len > 0) { @@ -136,8 +136,10 @@ retry: h->path_state = HP_SW_PATH_ACTIVE; ret = SCSI_DH_OK; } - if (ret == SCSI_DH_IMM_RETRY) + if (ret == SCSI_DH_IMM_RETRY) { + blk_put_request(req); goto retry; + } if (ret == SCSI_DH_DEV_OFFLINED) { h->path_state = HP_SW_PATH_PASSIVE; ret = SCSI_DH_OK; @@ -200,6 +202,7 @@ static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h) struct request *req; int ret, retry; +retry: req = blk_get_request(sdev->request_queue, WRITE, GFP_NOIO); if (!req) return SCSI_DH_RES_TEMP_UNAVAIL; @@ -216,7 +219,6 @@ static int hp_sw_start_stop(struct scsi_device *sdev, struct hp_sw_dh_data *h) req->sense_len = 0; retry = h->retries; -retry: ret = blk_execute_rq(req->q, NULL, req, 1); if (ret == -EIO) { if (req->sense_len > 0) { @@ -231,8 +233,10 @@ retry: ret = SCSI_DH_OK; if (ret == SCSI_DH_RETRY) { - if (--retry) + if (--retry) { + blk_put_request(req); goto retry; + } ret = SCSI_DH_IO; } diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/aty/radeon_accel.c index 8da5e5ab854..a469a3d6edc 100644 --- a/drivers/video/aty/radeon_accel.c +++ b/drivers/video/aty/radeon_accel.c @@ -5,61 +5,61 @@ * --dte */ -#define FLUSH_CACHE_WORKAROUND 1 - -void radeon_fifo_update_and_wait(struct radeonfb_info *rinfo, int entries) +static void radeon_fixup_offset(struct radeonfb_info *rinfo) { - int i; + u32 local_base; + + /* *** Ugly workaround *** */ + /* + * On some platforms, the video memory is mapped at 0 in radeon chip space + * (like PPCs) by the firmware. X will always move it up so that it's seen + * by the chip to be at the same address as the PCI BAR. + * That means that when switching back from X, there is a mismatch between + * the offsets programmed into the engine. This means that potentially, + * accel operations done before radeonfb has a chance to re-init the engine + * will have incorrect offsets, and potentially trash system memory ! + * + * The correct fix is for fbcon to never call any accel op before the engine + * has properly been re-initialized (by a call to set_var), but this is a + * complex fix. This workaround in the meantime, called before every accel + * operation, makes sure the offsets are in sync. + */ - for (i=0; i<2000000; i++) { - rinfo->fifo_free = INREG(RBBM_STATUS) & 0x7f; - if (rinfo->fifo_free >= entries) - return; - udelay(10); - } - printk(KERN_ERR "radeonfb: FIFO Timeout !\n"); - /* XXX Todo: attempt to reset the engine */ -} + radeon_fifo_wait (1); + local_base = INREG(MC_FB_LOCATION) << 16; + if (local_base == rinfo->fb_local_base) + return; -static inline void radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) -{ - if (entries <= rinfo->fifo_free) - rinfo->fifo_free -= entries; - else - radeon_fifo_update_and_wait(rinfo, entries); -} + rinfo->fb_local_base = local_base; -static inline void radeonfb_set_creg(struct radeonfb_info *rinfo, u32 reg, - u32 *cache, u32 new_val) -{ - if (new_val == *cache) - return; - *cache = new_val; - radeon_fifo_wait(rinfo, 1); - OUTREG(reg, new_val); + radeon_fifo_wait (3); + OUTREG(DEFAULT_PITCH_OFFSET, (rinfo->pitch << 0x16) | + (rinfo->fb_local_base >> 10)); + OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); + OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); } static void radeonfb_prim_fillrect(struct radeonfb_info *rinfo, const struct fb_fillrect *region) { - radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, - rinfo->dp_gui_mc_base | GMC_BRUSH_SOLID_COLOR | ROP3_P); - radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, - DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); - radeonfb_set_creg(rinfo, DP_BRUSH_FRGD_CLR, &rinfo->dp_brush_fg_cache, - region->color); - - /* Ensure the dst cache is flushed and the engine idle before - * issuing the operation. - * - * This works around engine lockups on some cards - */ -#if FLUSH_CACHE_WORKAROUND - radeon_fifo_wait(rinfo, 2); + radeon_fifo_wait(4); + + OUTREG(DP_GUI_MASTER_CNTL, + rinfo->dp_gui_master_cntl /* contains, like GMC_DST_32BPP */ + | GMC_BRUSH_SOLID_COLOR + | ROP3_P); + if (radeon_get_dstbpp(rinfo->depth) != DST_8BPP) + OUTREG(DP_BRUSH_FRGD_CLR, rinfo->pseudo_palette[region->color]); + else + OUTREG(DP_BRUSH_FRGD_CLR, region->color); + OUTREG(DP_WRITE_MSK, 0xffffffff); + OUTREG(DP_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM)); + + radeon_fifo_wait(2); OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); -#endif - radeon_fifo_wait(rinfo, 2); + + radeon_fifo_wait(2); OUTREG(DST_Y_X, (region->dy << 16) | region->dx); OUTREG(DST_WIDTH_HEIGHT, (region->width << 16) | region->height); } @@ -70,14 +70,15 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) struct fb_fillrect modded; int vxres, vyres; - WARN_ON(rinfo->gfx_mode); - if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) + if (info->state != FBINFO_STATE_RUNNING) return; if (info->flags & FBINFO_HWACCEL_DISABLED) { cfb_fillrect(info, region); return; } + radeon_fixup_offset(rinfo); + vxres = info->var.xres_virtual; vyres = info->var.yres_virtual; @@ -90,10 +91,6 @@ void radeonfb_fillrect(struct fb_info *info, const struct fb_fillrect *region) if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR ) - modded.color = ((u32 *) (info->pseudo_palette))[region->color]; - radeonfb_prim_fillrect(rinfo, &modded); } @@ -112,22 +109,22 @@ static void radeonfb_prim_copyarea(struct radeonfb_info *rinfo, if ( xdir < 0 ) { sx += w-1; dx += w-1; } if ( ydir < 0 ) { sy += h-1; dy += h-1; } - radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, - rinfo->dp_gui_mc_base | - GMC_BRUSH_NONE | - GMC_SRC_DATATYPE_COLOR | - ROP3_S | - DP_SRC_SOURCE_MEMORY); - radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, - (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) | - (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); - -#if FLUSH_CACHE_WORKAROUND - radeon_fifo_wait(rinfo, 2); + radeon_fifo_wait(3); + OUTREG(DP_GUI_MASTER_CNTL, + rinfo->dp_gui_master_cntl /* i.e. GMC_DST_32BPP */ + | GMC_BRUSH_NONE + | GMC_SRC_DSTCOLOR + | ROP3_S + | DP_SRC_SOURCE_MEMORY ); + OUTREG(DP_WRITE_MSK, 0xffffffff); + OUTREG(DP_CNTL, (xdir>=0 ? DST_X_LEFT_TO_RIGHT : 0) + | (ydir>=0 ? DST_Y_TOP_TO_BOTTOM : 0)); + + radeon_fifo_wait(2); OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); -#endif - radeon_fifo_wait(rinfo, 3); + + radeon_fifo_wait(3); OUTREG(SRC_Y_X, (sy << 16) | sx); OUTREG(DST_Y_X, (dy << 16) | dx); OUTREG(DST_HEIGHT_WIDTH, (h << 16) | w); @@ -146,14 +143,15 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) modded.width = area->width; modded.height = area->height; - WARN_ON(rinfo->gfx_mode); - if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) + if (info->state != FBINFO_STATE_RUNNING) return; if (info->flags & FBINFO_HWACCEL_DISABLED) { cfb_copyarea(info, area); return; } + radeon_fixup_offset(rinfo); + vxres = info->var.xres_virtual; vyres = info->var.yres_virtual; @@ -170,116 +168,13 @@ void radeonfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) radeonfb_prim_copyarea(rinfo, &modded); } -static void radeonfb_prim_imageblit(struct radeonfb_info *rinfo, - const struct fb_image *image, - u32 fg, u32 bg) -{ - unsigned int dwords; - u32 *bits; - - radeonfb_set_creg(rinfo, DP_GUI_MASTER_CNTL, &rinfo->dp_gui_mc_cache, - rinfo->dp_gui_mc_base | - GMC_BRUSH_NONE | GMC_DST_CLIP_LEAVE | - GMC_SRC_DATATYPE_MONO_FG_BG | - ROP3_S | - GMC_BYTE_ORDER_MSB_TO_LSB | - DP_SRC_SOURCE_HOST_DATA); - radeonfb_set_creg(rinfo, DP_CNTL, &rinfo->dp_cntl_cache, - DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM); - radeonfb_set_creg(rinfo, DP_SRC_FRGD_CLR, &rinfo->dp_src_fg_cache, fg); - radeonfb_set_creg(rinfo, DP_SRC_BKGD_CLR, &rinfo->dp_src_bg_cache, bg); - - /* Ensure the dst cache is flushed and the engine idle before - * issuing the operation. - * - * This works around engine lockups on some cards - */ -#if FLUSH_CACHE_WORKAROUND - radeon_fifo_wait(rinfo, 2); - OUTREG(DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL); - OUTREG(WAIT_UNTIL, (WAIT_2D_IDLECLEAN | WAIT_DMA_GUI_IDLE)); -#endif - - /* X here pads width to a multiple of 32 and uses the clipper to - * adjust the result. Is that really necessary ? Things seem to - * work ok for me without that and the doco doesn't seem to imply] - * there is such a restriction. - */ - radeon_fifo_wait(rinfo, 4); - OUTREG(SC_TOP_LEFT, (image->dy << 16) | image->dx); - OUTREG(SC_BOTTOM_RIGHT, ((image->dy + image->height) << 16) | - (image->dx + image->width)); - OUTREG(DST_Y_X, (image->dy << 16) | image->dx); - - OUTREG(DST_HEIGHT_WIDTH, (image->height << 16) | ((image->width + 31) & ~31)); - - dwords = (image->width + 31) >> 5; - dwords *= image->height; - bits = (u32*)(image->data); - - while(dwords >= 8) { - radeon_fifo_wait(rinfo, 8); -#if BITS_PER_LONG == 64 - __raw_writeq(*((u64 *)(bits)), rinfo->mmio_base + HOST_DATA0); - __raw_writeq(*((u64 *)(bits+2)), rinfo->mmio_base + HOST_DATA2); - __raw_writeq(*((u64 *)(bits+4)), rinfo->mmio_base + HOST_DATA4); - __raw_writeq(*((u64 *)(bits+6)), rinfo->mmio_base + HOST_DATA6); - bits += 8; -#else - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA1); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA2); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA3); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA4); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA5); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA6); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA7); -#endif - dwords -= 8; - } - while(dwords--) { - radeon_fifo_wait(rinfo, 1); - __raw_writel(*(bits++), rinfo->mmio_base + HOST_DATA0); - } -} - void radeonfb_imageblit(struct fb_info *info, const struct fb_image *image) { struct radeonfb_info *rinfo = info->par; - u32 fg, bg; - WARN_ON(rinfo->gfx_mode); - if (info->state != FBINFO_STATE_RUNNING || rinfo->gfx_mode) - return; - - if (!image->width || !image->height) + if (info->state != FBINFO_STATE_RUNNING) return; - - /* We only do 1 bpp color expansion for now */ - if (!accel_cexp || - (info->flags & FBINFO_HWACCEL_DISABLED) || image->depth != 1) - goto fallback; - - /* Fallback if running out of the screen. We may do clipping - * in the future */ - if ((image->dx + image->width) > info->var.xres_virtual || - (image->dy + image->height) > info->var.yres_virtual) - goto fallback; - - if (info->fix.visual == FB_VISUAL_TRUECOLOR || - info->fix.visual == FB_VISUAL_DIRECTCOLOR) { - fg = ((u32*)(info->pseudo_palette))[image->fg_color]; - bg = ((u32*)(info->pseudo_palette))[image->bg_color]; - } else { - fg = image->fg_color; - bg = image->bg_color; - } - - radeonfb_prim_imageblit(rinfo, image, fg, bg); - return; - - fallback: - radeon_engine_idle(rinfo); + radeon_engine_idle(); cfb_imageblit(info, image); } @@ -290,8 +185,7 @@ int radeonfb_sync(struct fb_info *info) if (info->state != FBINFO_STATE_RUNNING) return 0; - - radeon_engine_idle(rinfo); + radeon_engine_idle(); return 0; } @@ -367,10 +261,9 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo) /* disable 3D engine */ OUTREG(RB3D_CNTL, 0); - rinfo->fifo_free = 0; radeonfb_engine_reset(rinfo); - radeon_fifo_wait(rinfo, 1); + radeon_fifo_wait (1); if (IS_R300_VARIANT(rinfo)) { OUTREG(RB2D_DSTCACHE_MODE, INREG(RB2D_DSTCACHE_MODE) | RB2D_DC_AUTOFLUSH_ENABLE | @@ -384,7 +277,7 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo) OUTREG(RB2D_DSTCACHE_MODE, 0); } - radeon_fifo_wait(rinfo, 3); + radeon_fifo_wait (3); /* We re-read MC_FB_LOCATION from card as it can have been * modified by XFree drivers (ouch !) */ @@ -395,57 +288,41 @@ void radeonfb_engine_init (struct radeonfb_info *rinfo) OUTREG(DST_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); OUTREG(SRC_PITCH_OFFSET, (rinfo->pitch << 0x16) | (rinfo->fb_local_base >> 10)); - radeon_fifo_wait(rinfo, 1); -#ifdef __BIG_ENDIAN + radeon_fifo_wait (1); +#if defined(__BIG_ENDIAN) OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); #else OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); #endif - radeon_fifo_wait(rinfo, 2); + radeon_fifo_wait (2); OUTREG(DEFAULT_SC_TOP_LEFT, 0); OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | DEFAULT_SC_BOTTOM_MAX)); - /* set default DP_GUI_MASTER_CNTL */ temp = radeon_get_dstbpp(rinfo->depth); - rinfo->dp_gui_mc_base = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); + rinfo->dp_gui_master_cntl = ((temp << 8) | GMC_CLR_CMP_CNTL_DIS); - rinfo->dp_gui_mc_cache = rinfo->dp_gui_mc_base | - GMC_BRUSH_SOLID_COLOR | - GMC_SRC_DATATYPE_COLOR; - radeon_fifo_wait(rinfo, 1); - OUTREG(DP_GUI_MASTER_CNTL, rinfo->dp_gui_mc_cache); + radeon_fifo_wait (1); + OUTREG(DP_GUI_MASTER_CNTL, (rinfo->dp_gui_master_cntl | + GMC_BRUSH_SOLID_COLOR | + GMC_SRC_DATATYPE_COLOR)); + radeon_fifo_wait (7); /* clear line drawing regs */ - radeon_fifo_wait(rinfo, 2); OUTREG(DST_LINE_START, 0); OUTREG(DST_LINE_END, 0); - /* set brush and source color regs */ - rinfo->dp_brush_fg_cache = 0xffffffff; - rinfo->dp_brush_bg_cache = 0x00000000; - rinfo->dp_src_fg_cache = 0xffffffff; - rinfo->dp_src_bg_cache = 0x00000000; - radeon_fifo_wait(rinfo, 4); - OUTREG(DP_BRUSH_FRGD_CLR, rinfo->dp_brush_fg_cache); - OUTREG(DP_BRUSH_BKGD_CLR, rinfo->dp_brush_bg_cache); - OUTREG(DP_SRC_FRGD_CLR, rinfo->dp_src_fg_cache); - OUTREG(DP_SRC_BKGD_CLR, rinfo->dp_src_bg_cache); - - /* Default direction */ - rinfo->dp_cntl_cache = DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM; - radeon_fifo_wait(rinfo, 1); - OUTREG(DP_CNTL, rinfo->dp_cntl_cache); + /* set brush color regs */ + OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff); + OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000); + + /* set source color regs */ + OUTREG(DP_SRC_FRGD_CLR, 0xffffffff); + OUTREG(DP_SRC_BKGD_CLR, 0x00000000); /* default write mask */ - radeon_fifo_wait(rinfo, 1); OUTREG(DP_WRITE_MSK, 0xffffffff); - /* Default to no swapping of host data */ - radeon_fifo_wait(rinfo, 1); - OUTREG(RBBM_ |