| Start/ | End/ | |||
| True | False | - | Line | Source |
| 1 | /* | |||
| 2 | * drivers/video/aty/radeon_base.c | |||
| 3 | * | |||
| 4 | * framebuffer driver for ATI Radeon chipset video boards | |||
| 5 | * | |||
| 6 | * Copyright 2003 Ben. Herrenschmidt <benh@kernel.crashing.org> | |||
| 7 | * Copyright 2000 Ani Joshi <ajoshi@kernel.crashing.org> | |||
| 8 | * | |||
| 9 | * i2c bits from Luca Tettamanti <kronos@kronoz.cjb.net> | |||
| 10 | * | |||
| 11 | * Special thanks to ATI DevRel team for their hardware donations. | |||
| 12 | * | |||
| 13 | * ...Insert GPL boilerplate here... | |||
| 14 | * | |||
| 15 | * Significant portions of this driver apdated from XFree86 Radeon | |||
| 16 | * driver which has the following copyright notice: | |||
| 17 | * | |||
| 18 | * Copyright 2000 ATI Technologies Inc., Markham, Ontario, and | |||
| 19 | * VA Linux Systems Inc., Fremont, California. | |||
| 20 | * | |||
| 21 | * All Rights Reserved. | |||
| 22 | * | |||
| 23 | * Permission is hereby granted, free of charge, to any person obtaining | |||
| 24 | * a copy of this software and associated documentation files (the | |||
| 25 | * "Software"), to deal in the Software without restriction, including | |||
| 26 | * without limitation on the rights to use, copy, modify, merge, | |||
| 27 | * publish, distribute, sublicense, and/or sell copies of the Software, | |||
| 28 | * and to permit persons to whom the Software is furnished to do so, | |||
| 29 | * subject to the following conditions: | |||
| 30 | * | |||
| 31 | * The above copyright notice and this permission notice (including the | |||
| 32 | * next paragraph) shall be included in all copies or substantial | |||
| 33 | * portions of the Software. | |||
| 34 | * | |||
| 35 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||
| 36 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||
| 37 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||
| 38 | * NON-INFRINGEMENT. IN NO EVENT SHALL ATI, VA LINUX SYSTEMS AND/OR | |||
| 39 | * THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |||
| 40 | * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
| 41 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||
| 42 | * DEALINGS IN THE SOFTWARE. | |||
| 43 | * | |||
| 44 | * XFree86 driver authors: | |||
| 45 | * | |||
| 46 | * Kevin E. Martin <martin@xfree86.org> | |||
| 47 | * Rickard E. Faith <faith@valinux.com> | |||
| 48 | * Alan Hourihane <alanh@fairlite.demon.co.uk> | |||
| 49 | * | |||
| 50 | */ | |||
| 51 | ||||
| 52 | ||||
| 53 | #define RADEON_VERSION "0.2.0" | |||
| 54 | ||||
| 55 | #include <linux/config.h> | |||
| 56 | #include <linux/module.h> | |||
| 57 | #include <linux/moduleparam.h> | |||
| 58 | #include <linux/kernel.h> | |||
| 59 | #include <linux/errno.h> | |||
| 60 | #include <linux/string.h> | |||
| 61 | #include <linux/mm.h> | |||
| 62 | #include <linux/tty.h> | |||
| 63 | #include <linux/slab.h> | |||
| 64 | #include <linux/delay.h> | |||
| 65 | #include <linux/time.h> | |||
| 66 | #include <linux/fb.h> | |||
| 67 | #include <linux/ioport.h> | |||
| 68 | #include <linux/init.h> | |||
| 69 | #include <linux/pci.h> | |||
| 70 | #include <linux/vmalloc.h> | |||
| 71 | #include <linux/device.h> | |||
| 72 | ||||
| 73 | #include <asm/io.h> | |||
| 74 | #include <asm/uaccess.h> | |||
| 75 | ||||
| 76 | #ifdef CONFIG_PPC_OF | |||
| 77 | ||||
| 78 | #include <asm/pci-bridge.h> | |||
| 79 | #include "../macmodes.h" | |||
| 80 | ||||
| 81 | #ifdef CONFIG_PMAC_BACKLIGHT | |||
| 82 | #include <asm/backlight.h> | |||
| 83 | #endif | |||
| 84 | ||||
| 85 | #ifdef CONFIG_BOOTX_TEXT | |||
| 86 | #include <asm/btext.h> | |||
| 87 | #endif | |||
| 88 | ||||
| 89 | #endif /* CONFIG_PPC_OF */ | |||
| 90 | ||||
| 91 | #ifdef CONFIG_MTRR | |||
| 92 | #include <asm/mtrr.h> | |||
| 93 | #endif | |||
| 94 | ||||
| 95 | #include <video/radeon.h> | |||
| 96 | #include <linux/radeonfb.h> | |||
| 97 | ||||
| 98 | #include "../edid.h" // MOVE THAT TO include/video | |||
| 99 | #include "ati_ids.h" | |||
| 100 | #include "radeonfb.h" | |||
| 101 | ||||
| 102 | #define MAX_MAPPED_VRAM (2048*2048*4) | |||
| 103 | #define MIN_MAPPED_VRAM (1024*768*1) | |||
| 104 | ||||
| 105 | #define CHIP_DEF(id, family, flags) \ | |||
| 106 | { PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) } | |||
| 107 | ||||
| 108 | static struct pci_device_id radeonfb_pci_table[] = { | |||
| 109 | /* Mobility M6 */ | |||
| 110 | CHIP_DEF(PCI_CHIP_RADEON_LY, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 111 | CHIP_DEF(PCI_CHIP_RADEON_LZ, RV100, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 112 | /* Radeon VE/7000 */ | |||
| 113 | CHIP_DEF(PCI_CHIP_RV100_QY, RV100, CHIP_HAS_CRTC2), | |||
| 114 | CHIP_DEF(PCI_CHIP_RV100_QZ, RV100, CHIP_HAS_CRTC2), | |||
| 115 | CHIP_DEF(PCI_CHIP_RN50, RV100, CHIP_HAS_CRTC2), | |||
| 116 | /* Radeon IGP320M (U1) */ | |||
| 117 | CHIP_DEF(PCI_CHIP_RS100_4336, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), | |||
| 118 | /* Radeon IGP320 (A3) */ | |||
| 119 | CHIP_DEF(PCI_CHIP_RS100_4136, RS100, CHIP_HAS_CRTC2 | CHIP_IS_IGP), | |||
| 120 | /* IGP330M/340M/350M (U2) */ | |||
| 121 | CHIP_DEF(PCI_CHIP_RS200_4337, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), | |||
| 122 | /* IGP330/340/350 (A4) */ | |||
| 123 | CHIP_DEF(PCI_CHIP_RS200_4137, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP), | |||
| 124 | /* Mobility 7000 IGP */ | |||
| 125 | CHIP_DEF(PCI_CHIP_RS250_4437, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), | |||
| 126 | /* 7000 IGP (A4+) */ | |||
| 127 | CHIP_DEF(PCI_CHIP_RS250_4237, RS200, CHIP_HAS_CRTC2 | CHIP_IS_IGP), | |||
| 128 | /* 8500 AIW */ | |||
| 129 | CHIP_DEF(PCI_CHIP_R200_BB, R200, CHIP_HAS_CRTC2), | |||
| 130 | CHIP_DEF(PCI_CHIP_R200_BC, R200, CHIP_HAS_CRTC2), | |||
| 131 | /* 8700/8800 */ | |||
| 132 | CHIP_DEF(PCI_CHIP_R200_QH, R200, CHIP_HAS_CRTC2), | |||
| 133 | /* 8500 */ | |||
| 134 | CHIP_DEF(PCI_CHIP_R200_QL, R200, CHIP_HAS_CRTC2), | |||
| 135 | /* 9100 */ | |||
| 136 | CHIP_DEF(PCI_CHIP_R200_QM, R200, CHIP_HAS_CRTC2), | |||
| 137 | /* Mobility M7 */ | |||
| 138 | CHIP_DEF(PCI_CHIP_RADEON_LW, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 139 | CHIP_DEF(PCI_CHIP_RADEON_LX, RV200, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 140 | /* 7500 */ | |||
| 141 | CHIP_DEF(PCI_CHIP_RV200_QW, RV200, CHIP_HAS_CRTC2), | |||
| 142 | CHIP_DEF(PCI_CHIP_RV200_QX, RV200, CHIP_HAS_CRTC2), | |||
| 143 | /* Mobility M9 */ | |||
| 144 | CHIP_DEF(PCI_CHIP_RV250_Ld, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 145 | CHIP_DEF(PCI_CHIP_RV250_Le, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 146 | CHIP_DEF(PCI_CHIP_RV250_Lf, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 147 | CHIP_DEF(PCI_CHIP_RV250_Lg, RV250, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 148 | /* 9000/Pro */ | |||
| 149 | CHIP_DEF(PCI_CHIP_RV250_If, RV250, CHIP_HAS_CRTC2), | |||
| 150 | CHIP_DEF(PCI_CHIP_RV250_Ig, RV250, CHIP_HAS_CRTC2), | |||
| 151 | /* Mobility 9100 IGP (U3) */ | |||
| 152 | CHIP_DEF(PCI_CHIP_RS300_5835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), | |||
| 153 | CHIP_DEF(PCI_CHIP_RS350_7835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), | |||
| 154 | /* 9100 IGP (A5) */ | |||
| 155 | CHIP_DEF(PCI_CHIP_RS300_5834, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP), | |||
| 156 | CHIP_DEF(PCI_CHIP_RS350_7834, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP), | |||
| 157 | /* Mobility 9200 (M9+) */ | |||
| 158 | CHIP_DEF(PCI_CHIP_RV280_5C61, RV280, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 159 | CHIP_DEF(PCI_CHIP_RV280_5C63, RV280, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 160 | /* 9200 */ | |||
| 161 | CHIP_DEF(PCI_CHIP_RV280_5960, RV280, CHIP_HAS_CRTC2), | |||
| 162 | CHIP_DEF(PCI_CHIP_RV280_5961, RV280, CHIP_HAS_CRTC2), | |||
| 163 | CHIP_DEF(PCI_CHIP_RV280_5962, RV280, CHIP_HAS_CRTC2), | |||
| 164 | CHIP_DEF(PCI_CHIP_RV280_5964, RV280, CHIP_HAS_CRTC2), | |||
| 165 | /* 9500 */ | |||
| 166 | CHIP_DEF(PCI_CHIP_R300_AD, R300, CHIP_HAS_CRTC2), | |||
| 167 | CHIP_DEF(PCI_CHIP_R300_AE, R300, CHIP_HAS_CRTC2), | |||
| 168 | /* 9600TX / FireGL Z1 */ | |||
| 169 | CHIP_DEF(PCI_CHIP_R300_AF, R300, CHIP_HAS_CRTC2), | |||
| 170 | CHIP_DEF(PCI_CHIP_R300_AG, R300, CHIP_HAS_CRTC2), | |||
| 171 | /* 9700/9500/Pro/FireGL X1 */ | |||
| 172 | CHIP_DEF(PCI_CHIP_R300_ND, R300, CHIP_HAS_CRTC2), | |||
| 173 | CHIP_DEF(PCI_CHIP_R300_NE, R300, CHIP_HAS_CRTC2), | |||
| 174 | CHIP_DEF(PCI_CHIP_R300_NF, R300, CHIP_HAS_CRTC2), | |||
| 175 | CHIP_DEF(PCI_CHIP_R300_NG, R300, CHIP_HAS_CRTC2), | |||
| 176 | /* Mobility M10/M11 */ | |||
| 177 | CHIP_DEF(PCI_CHIP_RV350_NP, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 178 | CHIP_DEF(PCI_CHIP_RV350_NQ, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 179 | CHIP_DEF(PCI_CHIP_RV350_NR, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 180 | CHIP_DEF(PCI_CHIP_RV350_NS, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 181 | CHIP_DEF(PCI_CHIP_RV350_NT, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 182 | CHIP_DEF(PCI_CHIP_RV350_NV, RV350, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 183 | /* 9600/FireGL T2 */ | |||
| 184 | CHIP_DEF(PCI_CHIP_RV350_AP, RV350, CHIP_HAS_CRTC2), | |||
| 185 | CHIP_DEF(PCI_CHIP_RV350_AQ, RV350, CHIP_HAS_CRTC2), | |||
| 186 | CHIP_DEF(PCI_CHIP_RV360_AR, RV350, CHIP_HAS_CRTC2), | |||
| 187 | CHIP_DEF(PCI_CHIP_RV350_AS, RV350, CHIP_HAS_CRTC2), | |||
| 188 | CHIP_DEF(PCI_CHIP_RV350_AT, RV350, CHIP_HAS_CRTC2), | |||
| 189 | CHIP_DEF(PCI_CHIP_RV350_AV, RV350, CHIP_HAS_CRTC2), | |||
| 190 | /* 9800/Pro/FileGL X2 */ | |||
| 191 | CHIP_DEF(PCI_CHIP_R350_AH, R350, CHIP_HAS_CRTC2), | |||
| 192 | CHIP_DEF(PCI_CHIP_R350_AI, R350, CHIP_HAS_CRTC2), | |||
| 193 | CHIP_DEF(PCI_CHIP_R350_AJ, R350, CHIP_HAS_CRTC2), | |||
| 194 | CHIP_DEF(PCI_CHIP_R350_AK, R350, CHIP_HAS_CRTC2), | |||
| 195 | CHIP_DEF(PCI_CHIP_R350_NH, R350, CHIP_HAS_CRTC2), | |||
| 196 | CHIP_DEF(PCI_CHIP_R350_NI, R350, CHIP_HAS_CRTC2), | |||
| 197 | CHIP_DEF(PCI_CHIP_R360_NJ, R350, CHIP_HAS_CRTC2), | |||
| 198 | CHIP_DEF(PCI_CHIP_R350_NK, R350, CHIP_HAS_CRTC2), | |||
| 199 | /* Newer stuff */ | |||
| 200 | CHIP_DEF(PCI_CHIP_RV380_3E50, RV380, CHIP_HAS_CRTC2), | |||
| 201 | CHIP_DEF(PCI_CHIP_RV380_3E54, RV380, CHIP_HAS_CRTC2), | |||
| 202 | CHIP_DEF(PCI_CHIP_RV380_3150, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 203 | CHIP_DEF(PCI_CHIP_RV380_3154, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 204 | CHIP_DEF(PCI_CHIP_RV370_5B60, RV380, CHIP_HAS_CRTC2), | |||
| 205 | CHIP_DEF(PCI_CHIP_RV370_5B62, RV380, CHIP_HAS_CRTC2), | |||
| 206 | CHIP_DEF(PCI_CHIP_RV370_5B64, RV380, CHIP_HAS_CRTC2), | |||
| 207 | CHIP_DEF(PCI_CHIP_RV370_5B65, RV380, CHIP_HAS_CRTC2), | |||
| 208 | CHIP_DEF(PCI_CHIP_RV370_5460, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 209 | CHIP_DEF(PCI_CHIP_RV370_5464, RV380, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 210 | CHIP_DEF(PCI_CHIP_R420_JH, R420, CHIP_HAS_CRTC2), | |||
| 211 | CHIP_DEF(PCI_CHIP_R420_JI, R420, CHIP_HAS_CRTC2), | |||
| 212 | CHIP_DEF(PCI_CHIP_R420_JJ, R420, CHIP_HAS_CRTC2), | |||
| 213 | CHIP_DEF(PCI_CHIP_R420_JK, R420, CHIP_HAS_CRTC2), | |||
| 214 | CHIP_DEF(PCI_CHIP_R420_JL, R420, CHIP_HAS_CRTC2), | |||
| 215 | CHIP_DEF(PCI_CHIP_R420_JM, R420, CHIP_HAS_CRTC2), | |||
| 216 | CHIP_DEF(PCI_CHIP_R420_JN, R420, CHIP_HAS_CRTC2 | CHIP_IS_MOBILITY), | |||
| 217 | CHIP_DEF(PCI_CHIP_R420_JP, R420, CHIP_HAS_CRTC2), | |||
| 218 | CHIP_DEF(PCI_CHIP_R423_UH, R420, CHIP_HAS_CRTC2), | |||
| 219 | CHIP_DEF(PCI_CHIP_R423_UI, R420, CHIP_HAS_CRTC2), | |||
| 220 | CHIP_DEF(PCI_CHIP_R423_UJ, R420, CHIP_HAS_CRTC2), | |||
| 221 | CHIP_DEF(PCI_CHIP_R423_UK, R420, CHIP_HAS_CRTC2), | |||
| 222 | CHIP_DEF(PCI_CHIP_R423_UQ, R420, CHIP_HAS_CRTC2), | |||
| 223 | CHIP_DEF(PCI_CHIP_R423_UR, R420, CHIP_HAS_CRTC2), | |||
| 224 | CHIP_DEF(PCI_CHIP_R423_UT, R420, CHIP_HAS_CRTC2), | |||
| 225 | CHIP_DEF(PCI_CHIP_R423_5D57, R420, CHIP_HAS_CRTC2), | |||
| 226 | /* Original Radeon/7200 */ | |||
| 227 | CHIP_DEF(PCI_CHIP_RADEON_QD, RADEON, 0), | |||
| 228 | CHIP_DEF(PCI_CHIP_RADEON_QE, RADEON, 0), | |||
| 229 | CHIP_DEF(PCI_CHIP_RADEON_QF, RADEON, 0), | |||
| 230 | CHIP_DEF(PCI_CHIP_RADEON_QG, RADEON, 0), | |||
| 231 | { 0, } | |||
| 232 | }; | |||
| 233 | MODULE_DEVICE_TABLE(pci, radeonfb_pci_table); | |||
| 234 | ||||
| 235 | ||||
| 236 | typedef struct { | |||
| 237 | u16 reg; | |||
| 238 | u32 val; | |||
| 239 | } reg_val; | |||
| 240 | ||||
| 241 | ||||
| 242 | /* these common regs are cleared before mode setting so they do not | |||
| 243 | * interfere with anything | |||
| 244 | */ | |||
| 245 | static reg_val common_regs[] = { | |||
| 246 | { OVR_CLR, 0 }, | |||
| 247 | { OVR_WID_LEFT_RIGHT, 0 }, | |||
| 248 | { OVR_WID_TOP_BOTTOM, 0 }, | |||
| 249 | { OV0_SCALE_CNTL, 0 }, | |||
| 250 | { SUBPIC_CNTL, 0 }, | |||
| 251 | { VIPH_CONTROL, 0 }, | |||
| 252 | { I2C_CNTL_1, 0 }, | |||
| 253 | { GEN_INT_CNTL, 0 }, | |||
| 254 | { CAP0_TRIG_CNTL, 0 }, | |||
| 255 | { CAP1_TRIG_CNTL, 0 }, | |||
| 256 | }; | |||
| 257 | ||||
| 258 | /* | |||
| 259 | * globals | |||
| 260 | */ | |||
| 261 | ||||
| 262 | static char *mode_option; | |||
| 263 | static char *monitor_layout; | |||
| 264 | static int noaccel = 0; | |||
| 265 | static int default_dynclk = -2; | |||
| 266 | static int nomodeset = 0; | |||
| 267 | static int ignore_edid = 0; | |||
| 268 | static int mirror = 0; | |||
| 269 | static int panel_yres = 0; | |||
| 270 | static int force_dfp = 0; | |||
| 271 | static int force_measure_pll = 0; | |||
| 272 | #ifdef CONFIG_MTRR | |||
| 273 | static int nomtrr = 0; | |||
| 274 | #endif | |||
| 275 | ||||
| 276 | /* | |||
| 277 | * prototypes | |||
| 278 | */ | |||
| 279 | ||||
| 280 | ||||
| 281 | #ifdef CONFIG_PPC_OF | |||
| 282 | ||||
| 283 | #ifdef CONFIG_PMAC_BACKLIGHT | |||
| 284 | static int radeon_set_backlight_enable(int on, int level, void *data); | |||
| 285 | static int radeon_set_backlight_level(int level, void *data); | |||
| 286 | static struct backlight_controller radeon_backlight_controller = { | |||
| 287 | radeon_set_backlight_enable, | |||
| 288 | radeon_set_backlight_level | |||
| 289 | }; | |||
| 290 | #endif /* CONFIG_PMAC_BACKLIGHT */ | |||
| 291 | ||||
| 292 | #endif /* CONFIG_PPC_OF */ | |||
| 293 | ||||
| 6 | 6 | 294 | static void radeon_unmap_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) | |
| 295 | { | |||
| 0 | 6 | - | 296 | if (!rinfo->bios_seg) |
| 0 | - | 297 | return; | |
| 298 | pci_unmap_rom(dev, rinfo->bios_seg); | |||
| 299 | } | |||
| 300 | ||||
| 0 | 0 | - | 301 | static int __devinit radeon_map_ROM(struct radeonfb_info *rinfo, struct pci_dev *dev) |
| 302 | { | |||
| 303 | void __iomem *rom; | |||
| 304 | u16 dptr; | |||
| 305 | u8 rom_type; | |||
| 306 | size_t rom_size; | |||
| 307 | ||||
| 308 | /* If this is a primary card, there is a shadow copy of the | |||
| 309 | * ROM somewhere in the first meg. We will just ignore the copy | |||
| 310 | * and use the ROM directly. | |||
| 311 | */ | |||
| 312 | ||||
| 313 | /* Fix from ATI for problem with Radeon hardware not leaving ROM enabled */ | |||
| 314 | unsigned int temp; | |||
| 315 | temp = INREG(MPP_TB_CONFIG); | |||
| 316 | temp &= 0x00ffffffu; | |||
| 317 | temp |= 0x04 << 24; | |||
| 318 | OUTREG(MPP_TB_CONFIG, temp); | |||
| 319 | temp = INREG(MPP_TB_CONFIG); | |||
| 320 | ||||
| 321 | rom = pci_map_rom(dev, &rom_size); | |||
| 0 | 0 | - | 322 | if (!rom) { |
| 323 | printk(KERN_ERR "radeonfb (%s): ROM failed to map\n", | |||
| 324 | pci_name(rinfo->pdev)); | |||
| 0 | - | 325 | return -ENOMEM; | |
| 326 | } | |||
| 327 | ||||
| 328 | rinfo->bios_seg = rom; | |||
| 329 | ||||
| 330 | /* Very simple test to make sure it appeared */ | |||
| 0 | 0 | - | 331 | if (BIOS_IN16(0) != 0xaa55) { |
| 332 | printk(KERN_DEBUG "radeonfb (%s): Invalid ROM signature %x " | |||
| 333 | "should be 0xaa55\n", | |||
| 334 | pci_name(rinfo->pdev), BIOS_IN16(0)); | |||
| 0 | - | 335 | goto failed; | |
| 336 | } | |||
| 337 | /* Look for the PCI data to check the ROM type */ | |||
| 338 | dptr = BIOS_IN16(0x18); | |||
| 339 | ||||
| 340 | /* Check the PCI data signature. If it's wrong, we still assume a normal x86 ROM | |||
| 341 | * for now, until I've verified this works everywhere. The goal here is more | |||
| 342 | * to phase out Open Firmware images. | |||
| 343 | * | |||
| 344 | * Currently, we only look at the first PCI data, we could iteratre and deal with | |||
| 345 | * them all, and we should use fb_bios_start relative to start of image and not | |||
| 346 | * relative start of ROM, but so far, I never found a dual-image ATI card | |||
| 347 | * | |||
| 348 | * typedef struct { | |||
| 349 | * u32 signature; + 0x00 | |||
| 350 | * u16 vendor; + 0x04 | |||
| 351 | * u16 device; + 0x06 | |||
| 352 | * u16 reserved_1; + 0x08 | |||
| 353 | * u16 dlen; + 0x0a | |||
| 354 | * u8 drevision; + 0x0c | |||
| 355 | * u8 class_hi; + 0x0d | |||
| 356 | * u16 class_lo; + 0x0e | |||
| 357 | * u16 ilen; + 0x10 | |||
| 358 | * u16 irevision; + 0x12 | |||
| 359 | * u8 type; + 0x14 | |||
| 360 | * u8 indicator; + 0x15 | |||
| 361 | * u16 reserved_2; + 0x16 | |||
| 362 | * } pci_data_t; | |||
| 363 | */ | |||
| 0 | 0 | - | 364 | if (BIOS_IN32(dptr) != (('R' << 24) | ('I' << 16) | ('C' << 8) | 'P')) { |
| 365 | printk(KERN_WARNING "radeonfb (%s): PCI DATA signature in ROM" | |||
| 366 | "incorrect: %08x\n", pci_name(rinfo->pdev), BIOS_IN32(dptr)); | |||
| 0 | - | 367 | goto anyway; | |
| 368 | } | |||
| 369 | rom_type = BIOS_IN8(dptr + 0x14); | |||
| 370 | switch(rom_type) { | |||
| 0 | - | 371 | case 0: | |
| 372 | printk(KERN_INFO "radeonfb: Found Intel x86 BIOS ROM Image\n"); | |||
| 0 | - | 373 | break; | |
| 0 | - | 374 | case 1: | |
| 375 | printk(KERN_INFO "radeonfb: Found Open Firmware ROM Image\n"); | |||
| 0 | - | 376 | goto failed; | |
| 0 | - | 377 | case 2: | |
| 378 | printk(KERN_INFO "radeonfb: Found HP PA-RISC ROM Image\n"); | |||
| 0 | - | 379 | goto failed; | |
| 0 | - | 380 | default: | |
| 381 | printk(KERN_INFO "radeonfb: Found unknown type %d ROM Image\n", rom_type); | |||
| 0 | - | 382 | goto failed; | |
| 383 | } | |||
| 384 | anyway: | |||
| 385 | /* Locate the flat panel infos, do some sanity checking !!! */ | |||
| 386 | rinfo->fp_bios_start = BIOS_IN16(0x48); | |||
| 0 | - | 387 | return 0; | |
| 388 | ||||
| 389 | failed: | |||
| 390 | rinfo->bios_seg = NULL; | |||
| 391 | radeon_unmap_ROM(rinfo, dev); | |||
| 0 | - | 392 | return -ENXIO; | |
| 393 | } | |||
| 394 | ||||
| 395 | #ifdef CONFIG_X86 | |||
| 6 | 0 | 396 | static int __devinit radeon_find_mem_vbios(struct radeonfb_info *rinfo) | |
| 397 | { | |||
| 398 | /* I simplified this code as we used to miss the signatures in | |||
| 399 | * a lot of case. It's now closer to XFree, we just don't check | |||
| 400 | * for signatures at all... Something better will have to be done | |||
| 401 | * if we end up having conflicts | |||
| 402 | */ | |||
| 403 | u32 segstart; | |||
| 404 | void __iomem *rom_base = NULL; | |||
| 405 | ||||
| 6 | 0 | - | 406 | for(segstart=0x000c0000; segstart<0x000f0000; segstart+=0x00001000) { |
| 407 | rom_base = ioremap(segstart, 0x10000); | |||
| 0 | 6 | - | 408 | if (rom_base == NULL) |
| 0 | - | 409 | return -ENOMEM; | |
| 6 | 0 | - | 410 | if (readb(rom_base) == 0x55 && readb(rom_base + 1) == 0xaa) |
| 6 | 410 | T && T | ||
| 0 | - | 410 | T && F | |
| 0 | - | 410 | F && _ | |
| 6 | 411 | break; | ||
| 412 | iounmap(rom_base); | |||
| 413 | rom_base = NULL; | |||
| 414 | } | |||
| 0 | 6 | - | 415 | if (rom_base == NULL) |
| 0 | - | 416 | return -ENXIO; | |
| 417 | ||||
| 418 | /* Locate the flat panel infos, do some sanity checking !!! */ | |||
| 419 | rinfo->bios_seg = rom_base; | |||
| 420 | rinfo->fp_bios_start = BIOS_IN16(0x48); | |||
| 421 | ||||
| 6 | 422 | return 0; | ||
| 423 | } | |||
| 424 | #endif | |||
| 425 | ||||
| 426 | #ifdef CONFIG_PPC_OF | |||
| 427 | /* | |||
| 428 | * Read XTAL (ref clock), SCLK and MCLK from Open Firmware device | |||
| 429 | * tree. Hopefully, ATI OF driver is kind enough to fill these | |||
| 430 | */ | |||
| 431 | static int __devinit radeon_read_xtal_OF (struct radeonfb_info *rinfo) | |||
| 432 | { | |||
| 433 | struct device_node *dp = rinfo->of_node; | |||
| 434 | u32 *val; | |||
| 435 | ||||
| 436 | if (dp == NULL) | |||
| 437 | return -ENODEV; | |||
| 438 | val = (u32 *) get_property(dp, "ATY,RefCLK", NULL); | |||
| 439 | if (!val || !*val) { | |||
| 440 | printk(KERN_WARNING "radeonfb: No ATY,RefCLK property !\n"); | |||
| 441 | return -EINVAL; | |||
| 442 | } | |||
| 443 | ||||
| 444 | rinfo->pll.ref_clk = (*val) / 10; | |||
| 445 | ||||
| 446 | val = (u32 *) get_property(dp, "ATY,SCLK", NULL); | |||
| 447 | if (val && *val) | |||
| 448 | rinfo->pll.sclk = (*val) / 10; | |||
| 449 | ||||
| 450 | val = (u32 *) get_property(dp, "ATY,MCLK", NULL); | |||
| 451 | if (val && *val) | |||
| 452 | rinfo->pll.mclk = (*val) / 10; | |||
| 453 | ||||
| 454 | return 0; | |||
| 455 | } | |||
| 456 | #endif /* CONFIG_PPC_OF */ | |||
| 457 | ||||
| 458 | /* | |||
| 459 | * Read PLL infos from chip registers | |||
| 460 | */ | |||
| 0 | 0 | - | 461 | static int __devinit radeon_probe_pll_params(struct radeonfb_info *rinfo) |
| 462 | { | |||
| 463 | unsigned char ppll_div_sel; | |||
| 464 | unsigned Ns, Nm, M; | |||
| 465 | unsigned sclk, mclk, tmp, ref_div; | |||
| 466 | int hTotal, vTotal, num, denom, m, n; | |||
| 467 | unsigned long long hz, vclk; | |||
| 468 | long xtal; | |||
| 469 | struct timeval start_tv, stop_tv; | |||
| 470 | long total_secs, total_usecs; | |||
| 471 | int i; | |||
| 472 | ||||
| 473 | /* Ugh, we cut interrupts, bad bad bad, but we want some precision | |||
| 474 | * here, so... --BenH | |||
| 475 | */ | |||
| 476 | ||||
| 477 | /* Flush PCI buffers ? */ | |||
| 478 | tmp = INREG16(DEVICE_ID); | |||
| 479 | ||||
| 480 | local_irq_disable(); | |||
| 481 | ||||
| 0 | 0 | - | 482 | for(i=0; i<1000000; i++) |
| 0 | 0 | - | 483 | if (((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0) |
| 0 | - | 484 | break; | |
| 485 | ||||
| 486 | do_gettimeofday(&start_tv); | |||
| 487 | ||||
| 0 | 0 | - | 488 | for(i=0; i<1000000; i++) |
| 0 | 0 | - | 489 | if (((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) != 0) |
| 0 | - | 490 | break; | |
| 491 | ||||
| 0 | 0 | - | 492 | for(i=0; i<1000000; i++) |
| 0 | 0 | - | 493 | if (((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3ff) == 0) |
| 0 | - | 494 | break; | |
| 495 | ||||
| 496 | do_gettimeofday(&stop_tv); | |||
| 497 | ||||
| 498 | local_irq_enable(); | |||
| 499 | ||||
| 500 | total_secs = stop_tv.tv_sec - start_tv.tv_sec; | |||
| 0 | 0 | - | 501 | if (total_secs > 10) |
| 0 | - | 502 | return -1; | |
| 503 | total_usecs = stop_tv.tv_usec - start_tv.tv_usec; | |||
| 504 | total_usecs += total_secs * 1000000; | |||
| 0 | 0 | - | 505 | if (total_usecs < 0) |
| 506 | total_usecs = -total_usecs; | |||
| 507 | hz = 1000000/total_usecs; | |||
| 508 | ||||
| 509 | hTotal = ((INREG(CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8; | |||
| 510 | vTotal = ((INREG(CRTC_V_TOTAL_DISP) & 0x3ff) + 1); | |||
| 511 | vclk = (long long)hTotal * (long long)vTotal * hz; | |||
| 512 | ||||
| 513 | switch((INPLL(PPLL_REF_DIV) & 0x30000) >> 16) { | |||
| 0 | - | 514 | case 0: | |
| 0 | - | 515 | default: | |
| 516 | num = 1; | |||
| 517 | denom = 1; | |||
| 0 | - | 518 | break; | |
| 0 | - | 519 | case 1: | |
| 520 | n = ((INPLL(M_SPLL_REF_FB_DIV) >> 16) & 0xff); | |||
| 521 | m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff); | |||
| 522 | num = 2*n; | |||
| 523 | denom = 2*m; | |||
| 0 | - | 524 | break; | |
| 0 | - | 525 | case 2: | |
| 526 | n = ((INPLL(M_SPLL_REF_FB_DIV) >> 8) & 0xff); | |||
| 527 | m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff); | |||
| 528 | num = 2*n; | |||
| 529 | denom = 2*m; | |||
| 0 | - | 530 | break; | |
| 531 | } | |||
| 532 | ||||
| 533 | ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3; | |||
| 534 | radeon_pll_errata_after_index(rinfo); | |||
| 535 | ||||
| 536 | n = (INPLL(PPLL_DIV_0 + ppll_div_sel) & 0x7ff); | |||
| 537 | m = (INPLL(PPLL_REF_DIV) & 0x3ff); | |||
| 538 | ||||
| 539 | num *= n; | |||
| 540 | denom *= m; | |||
| 541 | ||||
| 542 | switch ((INPLL(PPLL_DIV_0 + ppll_div_sel) >> 16) & 0x7) { | |||
| 0 | - | 543 | case 1: | |
| 544 | denom *= 2; | |||
| 0 | - | 545 | break; | |
| 0 | - | 546 | case 2: | |
| 547 | denom *= 4; | |||
| 0 | - | 548 | break; | |
| 0 | - | 549 | case 3: | |
| 550 | denom *= 8; | |||
| 0 | - | 551 | break; | |
| 0 | - | 552 | case 4: | |
| 553 | denom *= 3; | |||
| 0 | -< | |||