~ubuntu-branches/ubuntu/trusty/linux-linaro-omap/trusty

« back to all changes in this revision

Viewing changes to drivers/video/s3fb.c

  • Committer: Package Import Robot
  • Author(s): John Rigby, John Rigby
  • Date: 2011-09-26 10:44:23 UTC
  • Revision ID: package-import@ubuntu.com-20110926104423-57i0gl3v99b3lkfg
Tags: 3.0.0-1007.9
[ John Rigby ]

Enable crypto modules and remove crypto-modules from
exclude-module files
LP: #826021

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include <linux/console.h> /* Why should fb driver call console functions? because console_lock() */
26
26
#include <video/vga.h>
27
27
 
 
28
#include <linux/i2c.h>
 
29
#include <linux/i2c-algo-bit.h>
 
30
 
28
31
#ifdef CONFIG_MTRR
29
32
#include <asm/mtrr.h>
30
33
#endif
36
39
        struct mutex open_lock;
37
40
        unsigned int ref_count;
38
41
        u32 pseudo_palette[16];
 
42
#ifdef CONFIG_FB_S3_DDC
 
43
        u8 __iomem *mmio;
 
44
        bool ddc_registered;
 
45
        struct i2c_adapter ddc_adapter;
 
46
        struct i2c_algo_bit_data ddc_algo;
 
47
#endif
39
48
};
40
49
 
41
50
 
105
114
#define CHIP_UNDECIDED_FLAG     0x80
106
115
#define CHIP_MASK               0xFF
107
116
 
 
117
#define MMIO_OFFSET             0x1000000
 
118
#define MMIO_SIZE               0x10000
 
119
 
108
120
/* CRT timing register sets */
109
121
 
110
122
static const struct vga_regset s3_h_total_regs[]        = {{0x00, 0, 7}, {0x5D, 0, 0}, VGA_REGSET_END};
140
152
/* Module parameters */
141
153
 
142
154
 
143
 
static char *mode_option __devinitdata = "640x480-8@60";
 
155
static char *mode_option __devinitdata;
144
156
 
145
157
#ifdef CONFIG_MTRR
146
158
static int mtrr __devinitdata = 1;
169
181
 
170
182
/* ------------------------------------------------------------------------- */
171
183
 
 
184
#ifdef CONFIG_FB_S3_DDC
 
185
 
 
186
#define DDC_REG         0xaa            /* Trio 3D/1X/2X */
 
187
#define DDC_MMIO_REG    0xff20          /* all other chips */
 
188
#define DDC_SCL_OUT     (1 << 0)
 
189
#define DDC_SDA_OUT     (1 << 1)
 
190
#define DDC_SCL_IN      (1 << 2)
 
191
#define DDC_SDA_IN      (1 << 3)
 
192
#define DDC_DRIVE_EN    (1 << 4)
 
193
 
 
194
static bool s3fb_ddc_needs_mmio(int chip)
 
195
{
 
196
        return !(chip == CHIP_360_TRIO3D_1X  ||
 
197
                 chip == CHIP_362_TRIO3D_2X  ||
 
198
                 chip == CHIP_368_TRIO3D_2X);
 
199
}
 
200
 
 
201
static u8 s3fb_ddc_read(struct s3fb_info *par)
 
202
{
 
203
        if (s3fb_ddc_needs_mmio(par->chip))
 
204
                return readb(par->mmio + DDC_MMIO_REG);
 
205
        else
 
206
                return vga_rcrt(par->state.vgabase, DDC_REG);
 
207
}
 
208
 
 
209
static void s3fb_ddc_write(struct s3fb_info *par, u8 val)
 
210
{
 
211
        if (s3fb_ddc_needs_mmio(par->chip))
 
212
                writeb(val, par->mmio + DDC_MMIO_REG);
 
213
        else
 
214
                vga_wcrt(par->state.vgabase, DDC_REG, val);
 
215
}
 
216
 
 
217
static void s3fb_ddc_setscl(void *data, int val)
 
218
{
 
219
        struct s3fb_info *par = data;
 
220
        unsigned char reg;
 
221
 
 
222
        reg = s3fb_ddc_read(par) | DDC_DRIVE_EN;
 
223
        if (val)
 
224
                reg |= DDC_SCL_OUT;
 
225
        else
 
226
                reg &= ~DDC_SCL_OUT;
 
227
        s3fb_ddc_write(par, reg);
 
228
}
 
229
 
 
230
static void s3fb_ddc_setsda(void *data, int val)
 
231
{
 
232
        struct s3fb_info *par = data;
 
233
        unsigned char reg;
 
234
 
 
235
        reg = s3fb_ddc_read(par) | DDC_DRIVE_EN;
 
236
        if (val)
 
237
                reg |= DDC_SDA_OUT;
 
238
        else
 
239
                reg &= ~DDC_SDA_OUT;
 
240
        s3fb_ddc_write(par, reg);
 
241
}
 
242
 
 
243
static int s3fb_ddc_getscl(void *data)
 
244
{
 
245
        struct s3fb_info *par = data;
 
246
 
 
247
        return !!(s3fb_ddc_read(par) & DDC_SCL_IN);
 
248
}
 
249
 
 
250
static int s3fb_ddc_getsda(void *data)
 
251
{
 
252
        struct s3fb_info *par = data;
 
253
 
 
254
        return !!(s3fb_ddc_read(par) & DDC_SDA_IN);
 
255
}
 
256
 
 
257
static int __devinit s3fb_setup_ddc_bus(struct fb_info *info)
 
258
{
 
259
        struct s3fb_info *par = info->par;
 
260
 
 
261
        strlcpy(par->ddc_adapter.name, info->fix.id,
 
262
                sizeof(par->ddc_adapter.name));
 
263
        par->ddc_adapter.owner          = THIS_MODULE;
 
264
        par->ddc_adapter.class          = I2C_CLASS_DDC;
 
265
        par->ddc_adapter.algo_data      = &par->ddc_algo;
 
266
        par->ddc_adapter.dev.parent     = info->device;
 
267
        par->ddc_algo.setsda            = s3fb_ddc_setsda;
 
268
        par->ddc_algo.setscl            = s3fb_ddc_setscl;
 
269
        par->ddc_algo.getsda            = s3fb_ddc_getsda;
 
270
        par->ddc_algo.getscl            = s3fb_ddc_getscl;
 
271
        par->ddc_algo.udelay            = 10;
 
272
        par->ddc_algo.timeout           = 20;
 
273
        par->ddc_algo.data              = par;
 
274
 
 
275
        i2c_set_adapdata(&par->ddc_adapter, par);
 
276
 
 
277
        /*
 
278
         * some Virge cards have external MUX to switch chip I2C bus between
 
279
         * DDC and extension pins - switch it do DDC
 
280
         */
 
281
/*      vga_wseq(par->state.vgabase, 0x08, 0x06); - not needed, already unlocked */
 
282
        if (par->chip == CHIP_357_VIRGE_GX2 ||
 
283
            par->chip == CHIP_359_VIRGE_GX2P)
 
284
                svga_wseq_mask(par->state.vgabase, 0x0d, 0x01, 0x03);
 
285
        else
 
286
                svga_wseq_mask(par->state.vgabase, 0x0d, 0x00, 0x03);
 
287
        /* some Virge need this or the DDC is ignored */
 
288
        svga_wcrt_mask(par->state.vgabase, 0x5c, 0x03, 0x03);
 
289
 
 
290
        return i2c_bit_add_bus(&par->ddc_adapter);
 
291
}
 
292
#endif /* CONFIG_FB_S3_DDC */
 
293
 
 
294
 
 
295
/* ------------------------------------------------------------------------- */
 
296
 
172
297
/* Set font in S3 fast text mode */
173
298
 
174
299
static void s3fb_settile_fast(struct fb_info *info, struct fb_tilemap *map)
994
1119
        struct s3fb_info *par;
995
1120
        int rc;
996
1121
        u8 regval, cr38, cr39;
 
1122
        bool found = false;
997
1123
 
998
1124
        /* Ignore secondary VGA device because there is no VGA arbitration */
999
1125
        if (! svga_primary_device(dev)) {
1110
1236
        info->fix.ypanstep = 0;
1111
1237
        info->fix.accel = FB_ACCEL_NONE;
1112
1238
        info->pseudo_palette = (void*) (par->pseudo_palette);
 
1239
        info->var.bits_per_pixel = 8;
 
1240
 
 
1241
#ifdef CONFIG_FB_S3_DDC
 
1242
        /* Enable MMIO if needed */
 
1243
        if (s3fb_ddc_needs_mmio(par->chip)) {
 
1244
                par->mmio = ioremap(info->fix.smem_start + MMIO_OFFSET, MMIO_SIZE);
 
1245
                if (par->mmio)
 
1246
                        svga_wcrt_mask(par->state.vgabase, 0x53, 0x08, 0x08);   /* enable MMIO */
 
1247
                else
 
1248
                        dev_err(info->device, "unable to map MMIO at 0x%lx, disabling DDC",
 
1249
                                info->fix.smem_start + MMIO_OFFSET);
 
1250
        }
 
1251
        if (!s3fb_ddc_needs_mmio(par->chip) || par->mmio)
 
1252
                if (s3fb_setup_ddc_bus(info) == 0) {
 
1253
                        u8 *edid = fb_ddc_read(&par->ddc_adapter);
 
1254
                        par->ddc_registered = true;
 
1255
                        if (edid) {
 
1256
                                fb_edid_to_monspecs(edid, &info->monspecs);
 
1257
                                kfree(edid);
 
1258
                                if (!info->monspecs.modedb)
 
1259
                                        dev_err(info->device, "error getting mode database\n");
 
1260
                                else {
 
1261
                                        const struct fb_videomode *m;
 
1262
 
 
1263
                                        fb_videomode_to_modelist(info->monspecs.modedb,
 
1264
                                                                 info->monspecs.modedb_len,
 
1265
                                                                 &info->modelist);
 
1266
                                        m = fb_find_best_display(&info->monspecs, &info->modelist);
 
1267
                                        if (m) {
 
1268
                                                fb_videomode_to_var(&info->var, m);
 
1269
                                                /* fill all other info->var's fields */
 
1270
                                                if (s3fb_check_var(&info->var, info) == 0)
 
1271
                                                        found = true;
 
1272
                                        }
 
1273
                                }
 
1274
                        }
 
1275
                }
 
1276
#endif
 
1277
        if (!mode_option && !found)
 
1278
                mode_option = "640x480-8@60";
1113
1279
 
1114
1280
        /* Prepare startup mode */
1115
 
        rc = fb_find_mode(&(info->var), info, mode_option, NULL, 0, NULL, 8);
1116
 
        if (! ((rc == 1) || (rc == 2))) {
1117
 
                rc = -EINVAL;
1118
 
                dev_err(info->device, "mode %s not found\n", mode_option);
 
1281
        if (mode_option) {
 
1282
                rc = fb_find_mode(&info->var, info, mode_option,
 
1283
                                   info->monspecs.modedb, info->monspecs.modedb_len,
 
1284
                                   NULL, info->var.bits_per_pixel);
 
1285
                if (!rc || rc == 4) {
 
1286
                        rc = -EINVAL;
 
1287
                        dev_err(info->device, "mode %s not found\n", mode_option);
 
1288
                        fb_destroy_modedb(info->monspecs.modedb);
 
1289
                        info->monspecs.modedb = NULL;
 
1290
                        goto err_find_mode;
 
1291
                }
 
1292
        }
 
1293
 
 
1294
        fb_destroy_modedb(info->monspecs.modedb);
 
1295
        info->monspecs.modedb = NULL;
 
1296
 
 
1297
        /* maximize virtual vertical size for fast scrolling */
 
1298
        info->var.yres_virtual = info->fix.smem_len * 8 /
 
1299
                        (info->var.bits_per_pixel * info->var.xres_virtual);
 
1300
        if (info->var.yres_virtual < info->var.yres) {
 
1301
                dev_err(info->device, "virtual vertical size smaller than real\n");
1119
1302
                goto err_find_mode;
1120
1303
        }
1121
1304
 
1164
1347
        fb_dealloc_cmap(&info->cmap);
1165
1348
err_alloc_cmap:
1166
1349
err_find_mode:
 
1350
#ifdef CONFIG_FB_S3_DDC
 
1351
        if (par->ddc_registered)
 
1352
                i2c_del_adapter(&par->ddc_adapter);
 
1353
        if (par->mmio)
 
1354
                iounmap(par->mmio);
 
1355
#endif
1167
1356
        pci_iounmap(dev, info->screen_base);
1168
1357
err_iomap:
1169
1358
        pci_release_regions(dev);
1180
1369
static void __devexit s3_pci_remove(struct pci_dev *dev)
1181
1370
{
1182
1371
        struct fb_info *info = pci_get_drvdata(dev);
 
1372
        struct s3fb_info __maybe_unused *par = info->par;
1183
1373
 
1184
1374
        if (info) {
1185
1375
 
1186
1376
#ifdef CONFIG_MTRR
1187
 
                struct s3fb_info *par = info->par;
1188
 
 
1189
1377
                if (par->mtrr_reg >= 0) {
1190
1378
                        mtrr_del(par->mtrr_reg, 0, 0);
1191
1379
                        par->mtrr_reg = -1;
1195
1383
                unregister_framebuffer(info);
1196
1384
                fb_dealloc_cmap(&info->cmap);
1197
1385
 
 
1386
#ifdef CONFIG_FB_S3_DDC
 
1387
                if (par->ddc_registered)
 
1388
                        i2c_del_adapter(&par->ddc_adapter);
 
1389
                if (par->mmio)
 
1390
                        iounmap(par->mmio);
 
1391
#endif
 
1392
 
1198
1393
                pci_iounmap(dev, info->screen_base);
1199
1394
                pci_release_regions(dev);
1200
1395
/*              pci_disable_device(dev); */