diff options
Diffstat (limited to 'drivers/video/via/hw.c')
-rw-r--r-- | drivers/video/via/hw.c | 127 |
1 files changed, 84 insertions, 43 deletions
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index c28ae2e85ef6..bd28e13f83d4 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c | |||
@@ -1430,6 +1430,70 @@ static u32 vx855_encode_pll(struct pll_config pll) | |||
1430 | | pll.multiplier; | 1430 | | pll.multiplier; |
1431 | } | 1431 | } |
1432 | 1432 | ||
1433 | static inline void cle266_set_primary_pll_encoded(u32 data) | ||
1434 | { | ||
1435 | via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ | ||
1436 | via_write_reg(VIASR, 0x46, data & 0xFF); | ||
1437 | via_write_reg(VIASR, 0x47, (data >> 8) & 0xFF); | ||
1438 | via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ | ||
1439 | } | ||
1440 | |||
1441 | static inline void k800_set_primary_pll_encoded(u32 data) | ||
1442 | { | ||
1443 | via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ | ||
1444 | via_write_reg(VIASR, 0x44, data & 0xFF); | ||
1445 | via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); | ||
1446 | via_write_reg(VIASR, 0x46, (data >> 16) & 0xFF); | ||
1447 | via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ | ||
1448 | } | ||
1449 | |||
1450 | static inline void cle266_set_secondary_pll_encoded(u32 data) | ||
1451 | { | ||
1452 | via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ | ||
1453 | via_write_reg(VIASR, 0x44, data & 0xFF); | ||
1454 | via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); | ||
1455 | via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ | ||
1456 | } | ||
1457 | |||
1458 | static inline void k800_set_secondary_pll_encoded(u32 data) | ||
1459 | { | ||
1460 | via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ | ||
1461 | via_write_reg(VIASR, 0x4A, data & 0xFF); | ||
1462 | via_write_reg(VIASR, 0x4B, (data >> 8) & 0xFF); | ||
1463 | via_write_reg(VIASR, 0x4C, (data >> 16) & 0xFF); | ||
1464 | via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ | ||
1465 | } | ||
1466 | |||
1467 | static void cle266_set_primary_pll(struct pll_config config) | ||
1468 | { | ||
1469 | cle266_set_primary_pll_encoded(cle266_encode_pll(config)); | ||
1470 | } | ||
1471 | |||
1472 | static void k800_set_primary_pll(struct pll_config config) | ||
1473 | { | ||
1474 | k800_set_primary_pll_encoded(k800_encode_pll(config)); | ||
1475 | } | ||
1476 | |||
1477 | static void vx855_set_primary_pll(struct pll_config config) | ||
1478 | { | ||
1479 | k800_set_primary_pll_encoded(vx855_encode_pll(config)); | ||
1480 | } | ||
1481 | |||
1482 | static void cle266_set_secondary_pll(struct pll_config config) | ||
1483 | { | ||
1484 | cle266_set_secondary_pll_encoded(cle266_encode_pll(config)); | ||
1485 | } | ||
1486 | |||
1487 | static void k800_set_secondary_pll(struct pll_config config) | ||
1488 | { | ||
1489 | k800_set_secondary_pll_encoded(k800_encode_pll(config)); | ||
1490 | } | ||
1491 | |||
1492 | static void vx855_set_secondary_pll(struct pll_config config) | ||
1493 | { | ||
1494 | k800_set_secondary_pll_encoded(vx855_encode_pll(config)); | ||
1495 | } | ||
1496 | |||
1433 | static inline u32 get_pll_internal_frequency(u32 ref_freq, | 1497 | static inline u32 get_pll_internal_frequency(u32 ref_freq, |
1434 | struct pll_config pll) | 1498 | struct pll_config pll) |
1435 | { | 1499 | { |
@@ -1474,21 +1538,21 @@ static struct pll_config get_pll_config(struct pll_limit *limits, int size, | |||
1474 | return best; | 1538 | return best; |
1475 | } | 1539 | } |
1476 | 1540 | ||
1477 | static u32 viafb_get_clk_value(int clk) | 1541 | static struct pll_config get_best_pll_config(int clk) |
1478 | { | 1542 | { |
1479 | u32 value = 0; | 1543 | struct pll_config config; |
1480 | 1544 | ||
1481 | switch (viaparinfo->chip_info->gfx_chip_name) { | 1545 | switch (viaparinfo->chip_info->gfx_chip_name) { |
1482 | case UNICHROME_CLE266: | 1546 | case UNICHROME_CLE266: |
1483 | case UNICHROME_K400: | 1547 | case UNICHROME_K400: |
1484 | value = cle266_encode_pll(get_pll_config(cle266_pll_limits, | 1548 | config = get_pll_config(cle266_pll_limits, |
1485 | ARRAY_SIZE(cle266_pll_limits), clk)); | 1549 | ARRAY_SIZE(cle266_pll_limits), clk); |
1486 | break; | 1550 | break; |
1487 | case UNICHROME_K800: | 1551 | case UNICHROME_K800: |
1488 | case UNICHROME_PM800: | 1552 | case UNICHROME_PM800: |
1489 | case UNICHROME_CN700: | 1553 | case UNICHROME_CN700: |
1490 | value = k800_encode_pll(get_pll_config(k800_pll_limits, | 1554 | config = get_pll_config(k800_pll_limits, |
1491 | ARRAY_SIZE(k800_pll_limits), clk)); | 1555 | ARRAY_SIZE(k800_pll_limits), clk); |
1492 | break; | 1556 | break; |
1493 | case UNICHROME_CX700: | 1557 | case UNICHROME_CX700: |
1494 | case UNICHROME_CN750: | 1558 | case UNICHROME_CN750: |
@@ -1496,38 +1560,31 @@ static u32 viafb_get_clk_value(int clk) | |||
1496 | case UNICHROME_P4M890: | 1560 | case UNICHROME_P4M890: |
1497 | case UNICHROME_P4M900: | 1561 | case UNICHROME_P4M900: |
1498 | case UNICHROME_VX800: | 1562 | case UNICHROME_VX800: |
1499 | value = k800_encode_pll(get_pll_config(cx700_pll_limits, | 1563 | config = get_pll_config(cx700_pll_limits, |
1500 | ARRAY_SIZE(cx700_pll_limits), clk)); | 1564 | ARRAY_SIZE(cx700_pll_limits), clk); |
1501 | break; | 1565 | break; |
1502 | case UNICHROME_VX855: | 1566 | case UNICHROME_VX855: |
1503 | case UNICHROME_VX900: | 1567 | case UNICHROME_VX900: |
1504 | value = vx855_encode_pll(get_pll_config(vx855_pll_limits, | 1568 | config = get_pll_config(vx855_pll_limits, |
1505 | ARRAY_SIZE(vx855_pll_limits), clk)); | 1569 | ARRAY_SIZE(vx855_pll_limits), clk); |
1506 | break; | 1570 | break; |
1507 | } | 1571 | } |
1508 | 1572 | ||
1509 | return value; | 1573 | return config; |
1510 | } | 1574 | } |
1511 | 1575 | ||
1512 | /* Set VCLK*/ | 1576 | /* Set VCLK*/ |
1513 | void viafb_set_vclock(u32 clk, int set_iga) | 1577 | void viafb_set_vclock(u32 clk, int set_iga) |
1514 | { | 1578 | { |
1515 | u32 value = viafb_get_clk_value(clk); | 1579 | struct pll_config config = get_best_pll_config(clk); |
1516 | |||
1517 | DEBUG_MSG(KERN_INFO "PLL=0x%x", value); | ||
1518 | |||
1519 | /* H.W. Reset : ON */ | ||
1520 | viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); | ||
1521 | 1580 | ||
1522 | if (set_iga == IGA1) { | 1581 | if (set_iga == IGA1) { |
1523 | /* Change D,N FOR VCLK */ | 1582 | /* Change D,N FOR VCLK */ |
1524 | switch (viaparinfo->chip_info->gfx_chip_name) { | 1583 | switch (viaparinfo->chip_info->gfx_chip_name) { |
1525 | case UNICHROME_CLE266: | 1584 | case UNICHROME_CLE266: |
1526 | case UNICHROME_K400: | 1585 | case UNICHROME_K400: |
1527 | via_write_reg(VIASR, SR46, (value & 0x00FF)); | 1586 | cle266_set_primary_pll(config); |
1528 | via_write_reg(VIASR, SR47, (value & 0xFF00) >> 8); | ||
1529 | break; | 1587 | break; |
1530 | |||
1531 | case UNICHROME_K800: | 1588 | case UNICHROME_K800: |
1532 | case UNICHROME_PM800: | 1589 | case UNICHROME_PM800: |
1533 | case UNICHROME_CN700: | 1590 | case UNICHROME_CN700: |
@@ -1537,11 +1594,11 @@ void viafb_set_vclock(u32 clk, int set_iga) | |||
1537 | case UNICHROME_P4M890: | 1594 | case UNICHROME_P4M890: |
1538 | case UNICHROME_P4M900: | 1595 | case UNICHROME_P4M900: |
1539 | case UNICHROME_VX800: | 1596 | case UNICHROME_VX800: |
1597 | k800_set_primary_pll(config); | ||
1598 | break; | ||
1540 | case UNICHROME_VX855: | 1599 | case UNICHROME_VX855: |
1541 | case UNICHROME_VX900: | 1600 | case UNICHROME_VX900: |
1542 | via_write_reg(VIASR, SR44, (value & 0x0000FF)); | 1601 | vx855_set_primary_pll(config); |
1543 | via_write_reg(VIASR, SR45, (value & 0x00FF00) >> 8); | ||
1544 | via_write_reg(VIASR, SR46, (value & 0xFF0000) >> 16); | ||
1545 | break; | 1602 | break; |
1546 | } | 1603 | } |
1547 | } | 1604 | } |
@@ -1551,10 +1608,8 @@ void viafb_set_vclock(u32 clk, int set_iga) | |||
1551 | switch (viaparinfo->chip_info->gfx_chip_name) { | 1608 | switch (viaparinfo->chip_info->gfx_chip_name) { |
1552 | case UNICHROME_CLE266: | 1609 | case UNICHROME_CLE266: |
1553 | case UNICHROME_K400: | 1610 | case UNICHROME_K400: |
1554 | via_write_reg(VIASR, SR44, (value & 0x00FF)); | 1611 | cle266_set_secondary_pll(config); |
1555 | via_write_reg(VIASR, SR45, (value & 0xFF00) >> 8); | ||
1556 | break; | 1612 | break; |
1557 | |||
1558 | case UNICHROME_K800: | 1613 | case UNICHROME_K800: |
1559 | case UNICHROME_PM800: | 1614 | case UNICHROME_PM800: |
1560 | case UNICHROME_CN700: | 1615 | case UNICHROME_CN700: |
@@ -1564,29 +1619,15 @@ void viafb_set_vclock(u32 clk, int set_iga) | |||
1564 | case UNICHROME_P4M890: | 1619 | case UNICHROME_P4M890: |
1565 | case UNICHROME_P4M900: | 1620 | case UNICHROME_P4M900: |
1566 | case UNICHROME_VX800: | 1621 | case UNICHROME_VX800: |
1622 | k800_set_secondary_pll(config); | ||
1623 | break; | ||
1567 | case UNICHROME_VX855: | 1624 | case UNICHROME_VX855: |
1568 | case UNICHROME_VX900: | 1625 | case UNICHROME_VX900: |
1569 | via_write_reg(VIASR, SR4A, (value & 0x0000FF)); | 1626 | vx855_set_secondary_pll(config); |
1570 | via_write_reg(VIASR, SR4B, (value & 0x00FF00) >> 8); | ||
1571 | via_write_reg(VIASR, SR4C, (value & 0xFF0000) >> 16); | ||
1572 | break; | 1627 | break; |
1573 | } | 1628 | } |
1574 | } | 1629 | } |
1575 | 1630 | ||
1576 | /* H.W. Reset : OFF */ | ||
1577 | viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); | ||
1578 | |||
1579 | /* Reset PLL */ | ||
1580 | if (set_iga == IGA1) { | ||
1581 | viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); | ||
1582 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); | ||
1583 | } | ||
1584 | |||
1585 | if (set_iga == IGA2) { | ||
1586 | viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2); | ||
1587 | viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2); | ||
1588 | } | ||
1589 | |||
1590 | /* Fire! */ | 1631 | /* Fire! */ |
1591 | via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ | 1632 | via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ |
1592 | } | 1633 | } |