| @@ -1580,6 +1580,25 @@ unlock: · 1579 unmodified lines |
| 1580 | 1580 | } |
| 1581 | 1581 | EXPORT_SYMBOL(drm_fb_helper_ioctl); |
| 1582 | 1582 | |
| 1583 | +static bool drm_fb_pixel_format_equal(const struct fb_var_screeninfo *var_1, |
| 1584 | + const struct fb_var_screeninfo *var_2) |
| 1585 | +{ |
| 1586 | + return var_1->bits_per_pixel == var_2->bits_per_pixel && |
| 1587 | + var_1->grayscale == var_2->grayscale && |
| 1588 | + var_1->red.offset == var_2->red.offset && |
| 1589 | + var_1->red.length == var_2->red.length && |
| 1590 | + var_1->red.msb_right == var_2->red.msb_right && |
| 1591 | + var_1->green.offset == var_2->green.offset && |
| 1592 | + var_1->green.length == var_2->green.length && |
| 1593 | + var_1->green.msb_right == var_2->green.msb_right && |
| 1594 | + var_1->blue.offset == var_2->blue.offset && |
| 1595 | + var_1->blue.length == var_2->blue.length && |
| 1596 | + var_1->blue.msb_right == var_2->blue.msb_right && |
| 1597 | + var_1->transp.offset == var_2->transp.offset && |
| 1598 | + var_1->transp.length == var_2->transp.length && |
| 1599 | + var_1->transp.msb_right == var_2->transp.msb_right; |
| 1600 | +} |
| 1601 | + |
| 1583 | 1602 | /** |
| 1584 | 1603 | * drm_fb_helper_check_var - implementation for &fb_ops.fb_check_var |
| 1585 | 1604 | * @var: screeninfo to check |
| @@ -1590,7 +1609,6 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, · 4 unmodified lines |
| 1590 | 1609 | { |
| 1591 | 1610 | struct drm_fb_helper *fb_helper = info->par; |
| 1592 | 1611 | struct drm_framebuffer *fb = fb_helper->fb; |
| 1593 | | − int depth; |
| 1594 | 1612 | |
| 1595 | 1613 | if (var->pixclock != 0 || in_dbg_master()) |
| 1596 | 1614 | return -EINVAL; |
| @@ -1610,72 +1628,15 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, · 13 unmodified lines |
| 1610 | 1628 | return -EINVAL; |
| 1611 | 1629 | } |
| 1612 | 1630 | |
| 1613 | | − switch (var->bits_per_pixel) { |
| 1614 | | − case 16: |
| 1615 | | − depth = (var->green.length == 6) ? 16 : 15; |
| 1616 | | − break; |
| 1617 | | − case 32: |
| 1618 | | − depth = (var->transp.length > 0) ? 32 : 24; |
| 1619 | | − break; |
| 1620 | | − default: |
| 1621 | | − depth = var->bits_per_pixel; |
| 1622 | | − break; |
| 1623 | | − } |
| 1624 | | − |
| 1625 | | − switch (depth) { |
| 1626 | | − case 8: |
| 1627 | | − var->red.offset = 0; |
| 1628 | | − var->green.offset = 0; |
| 1629 | | − var->blue.offset = 0; |
| 1630 | | − var->red.length = 8; |
| 1631 | | − var->green.length = 8; |
| 1632 | | − var->blue.length = 8; |
| 1633 | | − var->transp.length = 0; |
| 1634 | | − var->transp.offset = 0; |
| 1635 | | − break; |
| 1636 | | − case 15: |
| 1637 | | − var->red.offset = 10; |
| 1638 | | − var->green.offset = 5; |
| 1639 | | − var->blue.offset = 0; |
| 1640 | | − var->red.length = 5; |
| 1641 | | − var->green.length = 5; |
| 1642 | | − var->blue.length = 5; |
| 1643 | | − var->transp.length = 1; |
| 1644 | | − var->transp.offset = 15; |
| 1645 | | − break; |
| 1646 | | − case 16: |
| 1647 | | − var->red.offset = 11; |
| 1648 | | − var->green.offset = 5; |
| 1649 | | − var->blue.offset = 0; |
| 1650 | | − var->red.length = 5; |
| 1651 | | − var->green.length = 6; |
| 1652 | | − var->blue.length = 5; |
| 1653 | | − var->transp.length = 0; |
| 1654 | | − var->transp.offset = 0; |
| 1655 | | − break; |
| 1656 | | − case 24: |
| 1657 | | − var->red.offset = 16; |
| 1658 | | − var->green.offset = 8; |
| 1659 | | − var->blue.offset = 0; |
| 1660 | | − var->red.length = 8; |
| 1661 | | − var->green.length = 8; |
| 1662 | | − var->blue.length = 8; |
| 1663 | | − var->transp.length = 0; |
| 1664 | | − var->transp.offset = 0; |
| 1665 | | − break; |
| 1666 | | − case 32: |
| 1667 | | − var->red.offset = 16; |
| 1668 | | − var->green.offset = 8; |
| 1669 | | − var->blue.offset = 0; |
| 1670 | | − var->red.length = 8; |
| 1671 | | − var->green.length = 8; |
| 1672 | | − var->blue.length = 8; |
| 1673 | | − var->transp.length = 8; |
| 1674 | | − var->transp.offset = 24; |
| 1675 | | − break; |
| 1676 | | − default: |
| 1631 | + /* |
| 1632 | + * drm fbdev emulation doesn't support changing the pixel format at all, |
| 1633 | + * so reject all pixel format changing requests. |
| 1634 | + */ |
| 1635 | + if (!drm_fb_pixel_format_equal(var, &info->var)) { |
| 1636 | + DRM_DEBUG("fbdev emulation doesn't support changing the pixel format\n"); |
| 1677 | 1637 | return -EINVAL; |
| 1678 | 1638 | } |
| 1639 | + |
| 1679 | 1640 | return 0; |
| 1680 | 1641 | } |
| 1681 | 1642 | EXPORT_SYMBOL(drm_fb_helper_check_var); |