23 #include <linux/pci.h>
25 #include <linux/slab.h>
27 #include <linux/module.h>
29 #include <linux/screen_info.h>
82 .line_length = 800 * 3,
97 static struct vesa_mode vesa_mode_table[] = {
98 {
"0x301", 640, 480, 8},
99 {
"0x303", 800, 600, 8},
100 {
"0x305", 1024, 768, 8},
101 {
"0x307", 1280, 1024, 8},
103 {
"0x311", 640, 480, 16},
104 {
"0x314", 800, 600, 16},
105 {
"0x317", 1024, 768, 16},
106 {
"0x31A", 1280, 1024, 16},
108 {
"0x312", 640, 480, 24},
109 {
"0x315", 800, 600, 24},
110 {
"0x318", 1024, 768, 24},
111 {
"0x31B", 1280, 1024, 24},
121 if (!options || !*options)
128 pr_debug(
"sm7xx_vga_setup = %s\n", options);
130 for (i = 0; i <
ARRAY_SIZE(vesa_mode_table); i++) {
141 __setup(
"vga=", sm7xx_vga_setup);
143 static void sm712_setpalette(
int regno,
unsigned red,
unsigned green,
147 smtc_seqw(0x66, (smtc_seqr(0x66) & 0xC3) | 0x10);
162 static inline unsigned int chan_to_field(
unsigned int chan,
167 return chan << bf->
offset;
170 static int smtc_blank(
int blank_mode,
struct fb_info *info)
173 switch (blank_mode) {
176 smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
177 smtc_seqw(0x6a, 0x16);
178 smtc_seqw(0x6b, 0x02);
179 smtc_seqw(0x21, (smtc_seqr(0x21) & 0x77));
180 smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
181 smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
182 smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
183 smtc_seqw(0x31, (smtc_seqr(0x31) | 0x03));
187 smtc_seqw(0x01, (smtc_seqr(0x01) & (~0x20)));
188 smtc_seqw(0x6a, 0x16);
189 smtc_seqw(0x6b, 0x02);
190 smtc_seqw(0x22, (smtc_seqr(0x22) & (~0x30)));
191 smtc_seqw(0x23, (smtc_seqr(0x23) & (~0xc0)));
192 smtc_seqw(0x24, (smtc_seqr(0x24) | 0x01));
193 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
197 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
198 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
199 smtc_seqw(0x6a, 0x0c);
200 smtc_seqw(0x6b, 0x02);
201 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
202 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x20));
203 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0x20));
204 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
205 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
206 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
210 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
211 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
212 smtc_seqw(0x6a, 0x0c);
213 smtc_seqw(0x6b, 0x02);
214 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
215 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x10));
216 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
217 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
218 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
219 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
223 smtc_seqw(0x01, (smtc_seqr(0x01) | 0x20));
224 smtc_seqw(0x20, (smtc_seqr(0x20) & (~0xB0)));
225 smtc_seqw(0x6a, 0x0c);
226 smtc_seqw(0x6b, 0x02);
227 smtc_seqw(0x21, (smtc_seqr(0x21) | 0x88));
228 smtc_seqw(0x22, ((smtc_seqr(0x22) & (~0x30)) | 0x30));
229 smtc_seqw(0x23, ((smtc_seqr(0x23) & (~0xc0)) | 0xD8));
230 smtc_seqw(0x24, (smtc_seqr(0x24) & (~0x01)));
231 smtc_seqw(0x31, ((smtc_seqr(0x31) & (~0x07)) | 0x00));
232 smtc_seqw(0x34, (smtc_seqr(0x34) | 0x80));
241 static int smtc_setcolreg(
unsigned regno,
unsigned red,
unsigned green,
252 switch (sfb->
fb.fix.visual) {
259 if (sfb->
fb.var.bits_per_pixel == 16) {
261 val = chan_to_field(red, &sfb->
fb.var.red);
262 val |= chan_to_field(green, \
264 val |= chan_to_field(blue, &sfb->
fb.var.blue);
267 ((red & 0xf800) >> 8) |
268 ((green & 0xe000) >> 13) |
269 ((green & 0x1c00) << 3) |
270 ((blue & 0xf800) >> 3);
276 val = chan_to_field(red, &sfb->
fb.var.red);
277 val |= chan_to_field(green, \
279 val |= chan_to_field(blue, &sfb->
fb.var.blue);
282 (val & 0xff00ff00 >> 8) |
283 (val & 0x00ff00ff << 8);
292 sm712_setpalette(regno, red, green, blue, info);
307 unsigned long p = *ppos;
323 total_size = info->
fix.smem_len;
328 if (count >= total_size)
331 if (count + p > total_size)
332 count = total_size -
p;
340 if (info->
fbops->fb_sync)
341 info->
fbops->fb_sync(info);
346 for (i = c >> 2; i--;) {
349 (*dst & 0xff00ff00 >> 8) |
350 (*dst & 0x00ff00ff << 8);
354 u8 *dst8 = (
u8 *) dst;
357 for (i = c & 3; i--;) {
384 smtcfb_write(
struct fb_info *info,
const char __user *buf,
size_t count,
387 unsigned long p = *ppos;
391 int c,
i, cnt = 0,
err = 0;
403 total_size = info->
fix.smem_len;
408 if (count > total_size) {
413 if (count + p > total_size) {
417 count = total_size -
p;
426 if (info->
fbops->fb_sync)
427 info->
fbops->fb_sync(info);
438 for (i = c >> 2; i--;) {
440 (*src & 0x00ff00ff << 8), dst++);
444 u8 *src8 = (
u8 *) src;
447 for (i = c & 3; i--;) {
466 return (cnt) ? cnt :
err;
470 static void sm7xx_set_timing(
struct smtcfb_info *sfb)
476 "sfb->width=%d sfb->height=%d "
477 "sfb->fb.var.bits_per_pixel=%d sfb->hz=%d\n",
483 VGAMode[
j].bpp == sfb->
fb.var.bits_per_pixel &&
487 "VGAMode[j].mmSizeX=%d VGAMode[j].mmSizeY=%d "
488 "VGAMode[j].bpp=%d VGAMode[j].hz=%d\n",
502 smtc_seqw(i,
VGAMode[
j].Init_SR00_SR04[i]);
511 if (((i + 0x30) != 0x62) \
512 && ((i + 0x30) != 0x6a) \
513 && ((i + 0x30) != 0x6b))
529 smtc_grphw(i,
VGAMode[
j].Init_GR00_GR08[i]);
533 smtc_attrw(i,
VGAMode[
j].Init_AR00_AR14[i]);
537 smtc_crtcw(i,
VGAMode[
j].Init_CR00_CR18[i]);
558 (sfb->
width * sfb->
fb.var.bits_per_pixel) / 64;
559 switch (sfb->
fb.var.bits_per_pixel) {
573 writel((
u32) (((m_nScreenStride + 2) << 16) | m_nScreenStride),
578 static void smtc_set_timing(
struct smtcfb_info *sfb)
584 sm7xx_set_timing(sfb);
591 switch (sfb->
fb.var.bits_per_pixel) {
594 sfb->
fb.fix.line_length = sfb->
fb.var.xres * 4;
595 sfb->
fb.var.red.length = 8;
596 sfb->
fb.var.green.length = 8;
597 sfb->
fb.var.blue.length = 8;
598 sfb->
fb.var.red.offset = 16;
599 sfb->
fb.var.green.offset = 8;
600 sfb->
fb.var.blue.offset = 0;
604 sfb->
fb.fix.line_length = sfb->
fb.var.xres * 3;
605 sfb->
fb.var.red.length = 8;
606 sfb->
fb.var.green.length = 8;
607 sfb->
fb.var.blue.length = 8;
608 sfb->
fb.var.red.offset = 16;
609 sfb->
fb.var.green.offset = 8;
610 sfb->
fb.var.blue.offset = 0;
614 sfb->
fb.fix.line_length = sfb->
fb.var.xres;
615 sfb->
fb.var.red.length = 3;
616 sfb->
fb.var.green.length = 3;
617 sfb->
fb.var.blue.length = 2;
618 sfb->
fb.var.red.offset = 5;
619 sfb->
fb.var.green.offset = 2;
620 sfb->
fb.var.blue.offset = 0;
625 sfb->
fb.fix.line_length = sfb->
fb.var.xres * 2;
626 sfb->
fb.var.red.length = 5;
627 sfb->
fb.var.green.length = 6;
628 sfb->
fb.var.blue.length = 5;
629 sfb->
fb.var.red.offset = 11;
630 sfb->
fb.var.green.offset = 5;
631 sfb->
fb.var.blue.offset = 0;
638 smtc_set_timing(sfb);
658 static int smtc_set_par(
struct fb_info *info)
665 static struct fb_ops smtcfb_ops = {
667 .fb_check_var = smtc_check_var,
668 .fb_set_par = smtc_set_par,
669 .fb_setcolreg = smtc_setcolreg,
670 .fb_blank = smtc_blank,
675 .fb_read = smtcfb_read,
676 .fb_write = smtcfb_write,
695 sfb->
fb.fbops = &smtcfb_ops;
696 sfb->
fb.fix = smtcfb_fix;
697 sfb->
fb.var = smtcfb_var;
698 sfb->
fb.pseudo_palette = sfb->
colreg;
707 static void smtc_free_fb_info(
struct smtcfb_info *sfb)
716 static void smtc_unmap_mmio(
struct smtcfb_info *sfb)
733 if (sfb->
fb.var.bits_per_pixel == 32)
734 sfb->
fb.fix.smem_start += 0x800000;
737 sfb->
fb.fix.smem_len = smem_len;
739 sfb->
fb.screen_base = sfb->
lfb;
741 if (!sfb->
fb.screen_base) {
743 "%s: unable to map screen memory\n", sfb->
fb.fix.id);
754 static void smtc_unmap_smem(
struct smtcfb_info *sfb)
756 if (sfb && sfb->
fb.screen_base) {
758 sfb->
fb.screen_base =
NULL;
765 static inline void sm7xx_init_hw(
void)
775 u_long smem_size = 0x00800000;
779 dev_info(&pdev->
dev,
"Silicon Motion display driver.");
787 sfb = smtc_alloc_fb_info(pdev);
796 pci_set_drvdata(pdev, sfb);
813 if (sfb->
fb.var.bits_per_pixel == 24)
823 sfb->
fb.fix.mmio_start = mmio_base + 0x00400000;
824 sfb->
fb.fix.mmio_len = 0x00400000;
832 sfb->
lfb + 0x00700000);
836 if (sfb->
fb.var.bits_per_pixel == 32) {
837 sfb->
lfb += 0x800000;
843 "%s: unable to map memory mapped IO!",
850 smtc_seqw(0x6a, 0x16);
851 smtc_seqw(0x6b, 0x02);
852 smtc_seqw(0x62, 0x3e);
854 smtc_seqw(0x17, 0x20);
857 if (sfb->
fb.var.bits_per_pixel == 32)
858 smtc_seqw(0x17, 0x30);
863 sfb->
fb.fix.mmio_len = 0x00200000;
871 smtc_seqw(0x62, 0xff);
872 smtc_seqw(0x6a, 0x0d);
873 smtc_seqw(0x6b, 0x02);
877 "No valid Silicon Motion display chip was detected!");
883 if (15 == sfb->
fb.var.bits_per_pixel)
884 sfb->
fb.var.bits_per_pixel = 16;
886 sfb->
fb.var.xres_virtual = sfb->
fb.var.xres;
887 sfb->
fb.var.yres_virtual = sfb->
fb.var.yres;
888 err = smtc_map_smem(sfb, pdev, smem_size);
899 "Silicon Motion SM%X Rev%X primary display mode %dx%d-%d Init Complete.",
901 sfb->
fb.var.yres, sfb->
fb.var.bits_per_pixel);
906 dev_err(&pdev->
dev,
"Silicon Motion, Inc. primary display init fail.");
908 smtc_unmap_smem(sfb);
909 smtc_unmap_mmio(sfb);
911 smtc_free_fb_info(sfb);
935 sfb = pci_get_drvdata(pdev);
936 pci_set_drvdata(pdev,
NULL);
937 smtc_unmap_smem(sfb);
938 smtc_unmap_mmio(sfb);
940 smtc_free_fb_info(sfb);
949 sfb = pci_get_drvdata(pdev);
954 smtc_seqw(0x20, (smtc_seqr(0x20) | 0xc0));
955 smtc_seqw(0x69, (smtc_seqr(0x69) & 0xf7));
962 smtc_seqw(0x21, 0xff);
967 static int smtcfb_pci_resume(
struct device *device)
972 sfb = pci_get_drvdata(pdev);
980 smtc_seqw(0x6a, 0x16);
981 smtc_seqw(0x6b, 0x02);
982 smtc_seqw(0x62, 0x3e);
984 smtc_seqw(0x17, 0x20);
986 if (sfb->
fb.var.bits_per_pixel == 32)
987 smtc_seqw(0x17, 0x30);
991 smtc_seqw(0x62, 0xff);
992 smtc_seqw(0x6a, 0x0d);
993 smtc_seqw(0x6b, 0x02);
997 smtc_seqw(0x34, (smtc_seqr(0x34) | 0xc0));
998 smtc_seqw(0x33, ((smtc_seqr(0x33) | 0x08) & 0xfb));
1009 static const struct dev_pm_ops sm7xx_pm_ops = {
1010 .
suspend = smtcfb_pci_suspend,
1011 .resume = smtcfb_pci_resume,
1012 .freeze = smtcfb_pci_suspend,
1013 .thaw = smtcfb_pci_resume,
1014 .poweroff = smtcfb_pci_suspend,
1015 .restore = smtcfb_pci_resume,
1018 #define SM7XX_PM_OPS (&sm7xx_pm_ops)
1022 #define SM7XX_PM_OPS NULL
1028 .id_table = smtcfb_pci_table,
1029 .probe = smtcfb_pci_probe,