comparison drivers/radeon/radeonfb.c @ 2142:8939341c5187

Some fixes
author nick
date Tue, 09 Oct 2001 07:44:10 +0000
parents f13d61fde30d
children 81f16b270b8b
comparison
equal deleted inserted replaced
2141:fa62c11857e8 2142:8939341c5187
65 #include <linux/console.h> 65 #include <linux/console.h>
66 #include <linux/selection.h> 66 #include <linux/selection.h>
67 #include <linux/ioport.h> 67 #include <linux/ioport.h>
68 #include <linux/init.h> 68 #include <linux/init.h>
69 #include <linux/pci.h> 69 #include <linux/pci.h>
70 #include <linux/unistd.h>
70 71
71 #include <asm/io.h> 72 #include <asm/io.h>
72 73
73 #include <video/fbcon.h> 74 #include <video/fbcon.h>
74 #include <video/fbcon-cfb8.h> 75 #include <video/fbcon-cfb8.h>
1499 * mode corruption. 1500 * mode corruption.
1500 if (save->bus_cntl & (BUS_READ_BURST)) 1501 if (save->bus_cntl & (BUS_READ_BURST))
1501 save->bus_cntl |= BUS_RD_DISCARD_EN; 1502 save->bus_cntl |= BUS_RD_DISCARD_EN;
1502 */ 1503 */
1503 } 1504 }
1504 #if 0 1505
1505 static int radeon_init_crtc_regs(struct radeonfb_info *rinfo, 1506 static int radeon_init_crtc_regs(struct radeonfb_info *rinfo,
1506 struct radeon_regs *save, 1507 struct radeon_regs *save,
1507 struct fb_var_screeninfo *mode) 1508 struct fb_var_screeninfo *mode)
1508 { 1509 {
1509 int format;
1510 int hsync_start;
1511 int hsync_wid;
1512 int hsync_fudge;
1513 int vsync_wid;
1514 int bytpp;
1515 int hsync_fudge_default[] = { 0x00, 0x12, 0x09, 0x09, 0x06, 0x05 };
1516 int hsync_fudge_fp[] = { 0x02, 0x02, 0x00, 0x00, 0x05, 0x05 };
1517 int prim_mon;
1518 int hTotal, vTotal, hSyncStart, hSyncEnd;
1519 int vSyncStart, vSyncEnd;
1520 RTRACE("radeonfb: radeon_init_crtc_regs is called\n");
1521
1522 switch (mode->bits_per_pixel) {
1523 case 8: format = 2; bytpp = 1; break;
1524 case 16: format = 4; bytpp = 2; break; /* 565 */
1525 case 24: format = 5; bytpp = 3; break; /* RGB */
1526 case 32: format = 6; bytpp = 4; break; /* xRGB */
1527 default:
1528 printk("radeonfb: Unsupported pixel depth (%d)\n", mode->bits_per_pixel);
1529 return 0;
1530 }
1531 prim_mon = PRIMARY_MONITOR(rinfo);
1532 if ((prim_mon == MT_DFP) || (prim_mon == MT_LCD))
1533 hsync_fudge = hsync_fudge_fp[format-1];
1534 else
1535 hsync_fudge = hsync_fudge_default[format-1];
1536
1537 save->crtc_gen_cntl = (CRTC_EXT_DISP_EN
1538 | CRTC_EN
1539 | (format << 8)
1540 /* | CRTC_DBL_SCAN_EN*/);
1541
1542 if((prim_mon == MT_DFP) || (prim_mon == MT_LCD))
1543 {
1544 save->crtc_ext_cntl = VGA_ATI_LINEAR |
1545 XCRT_CNT_EN;
1546 save->crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
1547 CRTC_INTERLACE_EN);
1548 }
1549 else
1550 save->crtc_ext_cntl = VGA_ATI_LINEAR |
1551 XCRT_CNT_EN |
1552 CRTC_CRT_ON;
1553
1554 save->dac_cntl = (DAC_MASK_ALL
1555 | DAC_VGA_ADR_EN
1556 | DAC_8BIT_EN);
1557
1558 rinfo->xres = mode->xres;
1559 rinfo->yres = mode->yres;
1560 rinfo->pixclock = mode->pixclock;
1561
1562 hSyncStart = mode->xres + mode->right_margin;
1563 hSyncEnd = hSyncStart + mode->hsync_len;
1564 hTotal = hSyncEnd + mode->left_margin;
1565
1566 vSyncStart = mode->yres + mode->lower_margin;
1567 vSyncEnd = vSyncStart + mode->vsync_len;
1568 vTotal = vSyncEnd + mode->upper_margin;
1569
1570 if(((prim_mon == MT_DFP) || (prim_mon == MT_LCD)))
1571 {
1572 if(rinfo->PanelXRes < mode->xres)
1573 rinfo->xres = mode->xres = rinfo->PanelXRes;
1574 if(rinfo->PanelYRes < mode->yres)
1575 rinfo->yres = mode->yres = rinfo->PanelYRes;
1576 hTotal = mode->xres + rinfo->HBlank + mode->left_margin;
1577 hSyncStart = mode->xres + rinfo->HOverPlus + mode->right_margin;
1578 hSyncEnd = hSyncStart + rinfo->HSyncWidth + mode->hsync_len;
1579 vTotal = mode->yres + rinfo->VBlank + mode->upper_margin;
1580 vSyncStart = mode->yres + rinfo->VOverPlus + mode->lower_margin;
1581 vSyncEnd = vSyncStart + rinfo->VSyncWidth + mode->vsync_len;
1582 }
1583
1584 save->crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff)
1585 | ((((mode->xres / 8) - 1) & 0x1ff) << 16));
1586
1587 hsync_wid = (hSyncEnd - hSyncStart) / 8;
1588 if (!hsync_wid) hsync_wid = 1;
1589 if (hsync_wid > 0x3f) hsync_wid = 0x3f;
1590 hsync_start = hSyncStart - 8 + hsync_fudge;
1591
1592 save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
1593 | (hsync_wid << 16)
1594 | ((mode->sync & FB_SYNC_HOR_HIGH_ACT)
1595 ? 0
1596 : CRTC_H_SYNC_POL));
1597
1598 /* This works for double scan mode. */
1599 save->crtc_v_total_disp = (((vTotal - 1) & 0xffff)
1600 | ((mode->yres - 1) << 16));
1601
1602 vsync_wid = vSyncEnd - vSyncStart;
1603 if (!vsync_wid) vsync_wid = 1;
1604 if (vsync_wid > 0x1f) vsync_wid = 0x1f;
1605
1606 save->crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff)
1607 | (vsync_wid << 16)
1608 | ((mode->sync & FB_SYNC_VERT_HIGH_ACT)
1609 ? 0
1610 : CRTC_V_SYNC_POL));
1611
1612 save->crtc_offset = 0;
1613 save->crtc_offset_cntl = 0;
1614
1615 save->crtc_pitch = ((mode->xres * bytpp) +
1616 ((mode->bits_per_pixel) - 1)) /
1617 (mode->bits_per_pixel);
1618 save->crtc_pitch |= save->crtc_pitch << 16;
1619
1620 save->xres = mode->xres;
1621 save->yres = mode->yres;
1622
1623 RTRACE("radeonfb: radeon_init_crtc_regs returns SUCCESS\n");
1624 return 1;
1625 }
1626 #endif
1627 static int radeon_init_crtc_regs(struct radeonfb_info *rinfo,
1628 struct radeon_regs *save,
1629 struct fb_var_screeninfo *mode)
1630 {
1631 int hTotal, vTotal, hSyncStart, hSyncEnd, 1510 int hTotal, vTotal, hSyncStart, hSyncEnd,
1632 hSyncPol, vSyncStart, vSyncEnd, vSyncPol, cSync; 1511 vSyncStart, vSyncEnd, cSync;
1633 u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5}; 1512 u8 hsync_adj_tab[] = {0, 0x12, 9, 9, 6, 5};
1634 u8 hsync_fudge_fp[] = { 2, 2, 0, 0, 5, 5 }; 1513 u8 hsync_fudge_fp[] = { 2, 2, 0, 0, 5, 5 };
1635 u32 sync, h_sync_pol, v_sync_pol; 1514 u32 sync;
1636 int format = 0; 1515 int format = 0;
1637 int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid; 1516 int hsync_start, hsync_fudge, bytpp, hsync_wid, vsync_wid;
1638 int prim_mon; 1517 int prim_mon;
1639 1518
1640 prim_mon = PRIMARY_MONITOR(rinfo); 1519 prim_mon = PRIMARY_MONITOR(rinfo);
1664 vSyncStart = mode->yres + rinfo->VOverPlus + mode->lower_margin; 1543 vSyncStart = mode->yres + rinfo->VOverPlus + mode->lower_margin;
1665 vSyncEnd = vSyncStart + rinfo->VSyncWidth + mode->vsync_len; 1544 vSyncEnd = vSyncStart + rinfo->VSyncWidth + mode->vsync_len;
1666 } 1545 }
1667 1546
1668 sync = mode->sync; 1547 sync = mode->sync;
1669 h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
1670 v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
1671 1548
1672 RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n", 1549 RTRACE("hStart = %d, hEnd = %d, hTotal = %d\n",
1673 hSyncStart, hSyncEnd, hTotal); 1550 hSyncStart, hSyncEnd, hTotal);
1674 RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n", 1551 RTRACE("vStart = %d, vEnd = %d, vTotal = %d\n",
1675 vSyncStart, vSyncEnd, vTotal); 1552 vSyncStart, vSyncEnd, vTotal);
1683 vsync_wid = mode->vsync_len; 1560 vsync_wid = mode->vsync_len;
1684 if (vsync_wid == 0) 1561 if (vsync_wid == 0)
1685 vsync_wid = 1; 1562 vsync_wid = 1;
1686 else if (vsync_wid > 0x1f) /* max */ 1563 else if (vsync_wid > 0x1f) /* max */
1687 vsync_wid = 0x1f; 1564 vsync_wid = 0x1f;
1688
1689 hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
1690 vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
1691 1565
1692 cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0; 1566 cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
1693 1567
1694 switch (mode->bits_per_pixel) { 1568 switch (mode->bits_per_pixel) {
1695 case 8: 1569 case 8:
1706 break; 1580 break;
1707 case 32: 1581 case 32:
1708 format = DST_32BPP; 1582 format = DST_32BPP;
1709 bytpp = 4; 1583 bytpp = 4;
1710 break; 1584 break;
1585 default:
1586 printk("radeonfb: Unsupported pixel depth (%d)\n", mode->bits_per_pixel);
1587 return 0;
1711 } 1588 }
1712 1589
1713 if ((prim_mon == MT_DFP) || (prim_mon == MT_LCD)) 1590 if ((prim_mon == MT_DFP) || (prim_mon == MT_LCD))
1714 hsync_fudge = hsync_fudge_fp[format-1]; 1591 hsync_fudge = hsync_fudge_fp[format-1];
1715 else 1592 else
1719 save->crtc_gen_cntl = (CRTC_EXT_DISP_EN 1596 save->crtc_gen_cntl = (CRTC_EXT_DISP_EN
1720 | CRTC_EN 1597 | CRTC_EN
1721 | (format << 8) 1598 | (format << 8)
1722 /* | CRTC_DBL_SCAN_EN*/); 1599 /* | CRTC_DBL_SCAN_EN*/);
1723 1600
1724 if((prim_mon == MT_DFP) || (prim_mon == MT_LCD)) 1601 if((prim_mon == MT_DFP) || (prim_mon == MT_LCD)) {
1725 {
1726 save->crtc_ext_cntl = VGA_ATI_LINEAR | 1602 save->crtc_ext_cntl = VGA_ATI_LINEAR |
1727 XCRT_CNT_EN; 1603 XCRT_CNT_EN;
1728 save->crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN | 1604 save->crtc_gen_cntl &= ~(CRTC_DBL_SCAN_EN |
1729 CRTC_INTERLACE_EN); 1605 CRTC_INTERLACE_EN);
1730 } 1606 }
1731 else 1607 else
1732 save->crtc_ext_cntl = VGA_ATI_LINEAR | 1608 save->crtc_ext_cntl = VGA_ATI_LINEAR |
1733 XCRT_CNT_EN | 1609 XCRT_CNT_EN |
1734 CRTC_CRT_ON; 1610 CRTC_CRT_ON;
1735 1611
1736 save->dac_cntl = (DAC_MASK_ALL 1612 save->dac_cntl = (DAC_MASK_ALL
1737 | DAC_VGA_ADR_EN 1613 | DAC_VGA_ADR_EN
1738 | DAC_8BIT_EN); 1614 | DAC_8BIT_EN);
1739 1615
1740 save->crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) | 1616 save->crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) |
1741 ((((mode->xres / 8) - 1) & 0x1ff) << 16)); 1617 ((((mode->xres / 8) - 1) & 0x1ff) << 16));
1742 1618
1743 save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) |
1744 (hsync_wid << 16) | (h_sync_pol << 23));
1745
1746 save->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | 1619 save->crtc_v_total_disp = ((vTotal - 1) & 0xffff) |
1747 ((mode->yres - 1) << 16); 1620 ((mode->yres - 1) << 16);
1748 1621
1749 save->crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | 1622 save->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff)
1750 (vsync_wid << 16) | (v_sync_pol << 23)); 1623 | (hsync_wid << 16)
1751 1624 | (mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0
1752 save->crtc_pitch = (mode->xres >> 3); 1625 : CRTC_H_SYNC_POL));
1626
1627 save->crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff)
1628 | (vsync_wid << 16)
1629 | (mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0
1630 : CRTC_V_SYNC_POL));
1631
1632 save->crtc_pitch = ((mode->xres * bytpp) +
1633 ((mode->bits_per_pixel) - 1)) /
1634 (mode->bits_per_pixel);
1635 save->crtc_pitch |= save->crtc_pitch<<16;
1753 1636
1754 #if defined(__BIG_ENDIAN) 1637 #if defined(__BIG_ENDIAN)
1755 save->surface_cntl = SURF_TRANSLATION_DIS; 1638 save->surface_cntl = SURF_TRANSLATION_DIS;
1756 switch (mode->bits_per_pixel) { 1639 switch (mode->bits_per_pixel) {
1757 case 16: 1640 case 16:
1766 1649
1767 rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f) 1650 rinfo->pitch = ((mode->xres * ((mode->bits_per_pixel + 1) / 8) + 0x3f)
1768 & ~(0x3f)) / 64; 1651 & ~(0x3f)) / 64;
1769 1652
1770 RTRACE("h_total_disp = 0x%x\t hsync_strt_wid = 0x%x\n", 1653 RTRACE("h_total_disp = 0x%x\t hsync_strt_wid = 0x%x\n",
1771 newmode.crtc_h_total_disp, newmode.crtc_h_sync_strt_wid); 1654 save->crtc_h_total_disp, save->crtc_h_sync_strt_wid);
1772 RTRACE("v_total_disp = 0x%x\t vsync_strt_wid = 0x%x\n", 1655 RTRACE("v_total_disp = 0x%x\t vsync_strt_wid = 0x%x\n",
1773 newmode.crtc_v_total_disp, newmode.crtc_v_sync_strt_wid); 1656 save->crtc_v_total_disp, save->crtc_v_sync_strt_wid);
1774 1657
1775 save->xres = mode->xres; 1658 save->xres = mode->xres;
1776 save->yres = mode->yres; 1659 save->yres = mode->yres;
1777 1660
1778 save->crtc_offset = 0; 1661 save->crtc_offset = 0;
2001 save->ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16); 1884 save->ppll_div_3 = rinfo->fb_div | (post_div->bitvalue << 16);
2002 save->htotal_cntl = 0; 1885 save->htotal_cntl = 0;
2003 1886
2004 RTRACE("post div = 0x%x\n", rinfo->post_div); 1887 RTRACE("post div = 0x%x\n", rinfo->post_div);
2005 RTRACE("fb_div = 0x%x\n", rinfo->fb_div); 1888 RTRACE("fb_div = 0x%x\n", rinfo->fb_div);
2006 RTRACE("ppll_div_3 = 0x%x\n", newmode.ppll_div_3); 1889 RTRACE("ppll_div_3 = 0x%x\n", save->ppll_div_3);
2007 } 1890 }
2008 1891
2009 static void radeon_init_pll2_regs(struct radeonfb_info *rinfo, 1892 static void radeon_init_pll2_regs(struct radeonfb_info *rinfo,
2010 struct radeon_regs *save, 1893 struct radeon_regs *save,
2011 struct fb_var_screeninfo *mode) 1894 struct fb_var_screeninfo *mode)
2736 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | 2619 val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS |
2737 CRTC_VSYNC_DIS); 2620 CRTC_VSYNC_DIS);
2738 2621
2739 switch (blank) { 2622 switch (blank) {
2740 case VESA_NO_BLANKING: 2623 case VESA_NO_BLANKING:
2624 if(DUAL_MONITOR(rinfo)) {
2625 OUTREGP(CRTC2_GEN_CNTL,
2626 0,
2627 ~(CRTC2_DISP_DIS |
2628 CRTC2_VSYNC_DIS |
2629 CRTC2_HSYNC_DIS));
2630 }
2631 switch(PRIMARY_MONITOR(rinfo)) {
2632 case MT_LCD:
2633 OUTREGP(LVDS_GEN_CNTL, 0,
2634 ~LVDS_DISPLAY_DIS);
2635 case MT_CRT:
2636 case MT_DFP:
2637 OUTREGP(CRTC_EXT_CNTL,
2638 CRTC_CRT_ON,
2639 ~(CRTC_DISPLAY_DIS |
2640 CRTC_VSYNC_DIS |
2641 CRTC_HSYNC_DIS));
2642 break;
2643 case MT_NONE:
2644 default:
2645 break;
2646
2647 }
2741 break; 2648 break;
2742 case VESA_VSYNC_SUSPEND: 2649 case VESA_VSYNC_SUSPEND:
2743 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS); 2650 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
2744 break; 2651 break;
2745 case VESA_HSYNC_SUSPEND: 2652 case VESA_HSYNC_SUSPEND:
2748 case VESA_POWERDOWN: 2655 case VESA_POWERDOWN:
2749 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | 2656 val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS |
2750 CRTC_HSYNC_DIS); 2657 CRTC_HSYNC_DIS);
2751 break; 2658 break;
2752 } 2659 }
2753 if(blank == VESA_NO_BLANKING && rinfo->hasCRTC2) 2660 if(blank != VESA_NO_BLANKING) OUTREG(CRTC_EXT_CNTL, val);
2754 OUTREGP(CRTC_EXT_CNTL,CRTC_CRT_ON, val);
2755 else OUTREG(CRTC_EXT_CNTL, val);
2756 } 2661 }
2757 2662
2758 2663
2759 2664
2760 static int radeon_get_cmap_len (const struct fb_var_screeninfo *var) 2665 static int radeon_get_cmap_len (const struct fb_var_screeninfo *var)
3089 OUTREG(LVDS_GEN_CNTL, restore->lvds_gen_cntl); 2994 OUTREG(LVDS_GEN_CNTL, restore->lvds_gen_cntl);
3090 } 2995 }
3091 } 2996 }
3092 else { 2997 else {
3093 if (restore->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) { 2998 if (restore->lvds_gen_cntl & (LVDS_ON | LVDS_BLON)) {
3094 #if 0 2999 udelay(rinfo->PanelPwrDly * 1000);
3095 /* TODO it later */
3096 usleep(rinfo->PanelPwrDly * 1000);
3097 #endif
3098 OUTREG(LVDS_GEN_CNTL, restore->lvds_gen_cntl); 3000 OUTREG(LVDS_GEN_CNTL, restore->lvds_gen_cntl);
3099 } 3001 }
3100 else { 3002 else {
3101 OUTREG(LVDS_GEN_CNTL, 3003 OUTREG(LVDS_GEN_CNTL,
3102 restore->lvds_gen_cntl | LVDS_BLON); 3004 restore->lvds_gen_cntl | LVDS_BLON);
3103 #if 0 3005 udelay(rinfo->PanelPwrDly * 1000);
3104 /* TODO it later */
3105 usleep(rinfo->PanelPwrDly * 1000);
3106 #endif
3107 OUTREG(LVDS_GEN_CNTL, restore->lvds_gen_cntl); 3006 OUTREG(LVDS_GEN_CNTL, restore->lvds_gen_cntl);
3108 } 3007 }
3109 } 3008 }
3110 } 3009 }
3111 3010