diff options
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
| -rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 133 |
1 files changed, 79 insertions, 54 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index d3af098b0922..d73703a695e8 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
| @@ -1621,6 +1621,64 @@ static bool drm_fb_pixel_format_equal(const struct fb_var_screeninfo *var_1, | |||
| 1621 | var_1->transp.msb_right == var_2->transp.msb_right; | 1621 | var_1->transp.msb_right == var_2->transp.msb_right; |
| 1622 | } | 1622 | } |
| 1623 | 1623 | ||
| 1624 | static void drm_fb_helper_fill_pixel_fmt(struct fb_var_screeninfo *var, | ||
| 1625 | u8 depth) | ||
| 1626 | { | ||
| 1627 | switch (depth) { | ||
| 1628 | case 8: | ||
| 1629 | var->red.offset = 0; | ||
| 1630 | var->green.offset = 0; | ||
| 1631 | var->blue.offset = 0; | ||
| 1632 | var->red.length = 8; /* 8bit DAC */ | ||
| 1633 | var->green.length = 8; | ||
| 1634 | var->blue.length = 8; | ||
| 1635 | var->transp.offset = 0; | ||
| 1636 | var->transp.length = 0; | ||
| 1637 | break; | ||
| 1638 | case 15: | ||
| 1639 | var->red.offset = 10; | ||
| 1640 | var->green.offset = 5; | ||
| 1641 | var->blue.offset = 0; | ||
| 1642 | var->red.length = 5; | ||
| 1643 | var->green.length = 5; | ||
| 1644 | var->blue.length = 5; | ||
| 1645 | var->transp.offset = 15; | ||
| 1646 | var->transp.length = 1; | ||
| 1647 | break; | ||
| 1648 | case 16: | ||
| 1649 | var->red.offset = 11; | ||
| 1650 | var->green.offset = 5; | ||
| 1651 | var->blue.offset = 0; | ||
| 1652 | var->red.length = 5; | ||
| 1653 | var->green.length = 6; | ||
| 1654 | var->blue.length = 5; | ||
| 1655 | var->transp.offset = 0; | ||
| 1656 | break; | ||
| 1657 | case 24: | ||
| 1658 | var->red.offset = 16; | ||
| 1659 | var->green.offset = 8; | ||
| 1660 | var->blue.offset = 0; | ||
| 1661 | var->red.length = 8; | ||
| 1662 | var->green.length = 8; | ||
| 1663 | var->blue.length = 8; | ||
| 1664 | var->transp.offset = 0; | ||
| 1665 | var->transp.length = 0; | ||
| 1666 | break; | ||
| 1667 | case 32: | ||
| 1668 | var->red.offset = 16; | ||
| 1669 | var->green.offset = 8; | ||
| 1670 | var->blue.offset = 0; | ||
| 1671 | var->red.length = 8; | ||
| 1672 | var->green.length = 8; | ||
| 1673 | var->blue.length = 8; | ||
| 1674 | var->transp.offset = 24; | ||
| 1675 | var->transp.length = 8; | ||
| 1676 | break; | ||
| 1677 | default: | ||
| 1678 | break; | ||
| 1679 | } | ||
| 1680 | } | ||
| 1681 | |||
| 1624 | /** | 1682 | /** |
| 1625 | * drm_fb_helper_check_var - implementation for &fb_ops.fb_check_var | 1683 | * drm_fb_helper_check_var - implementation for &fb_ops.fb_check_var |
| 1626 | * @var: screeninfo to check | 1684 | * @var: screeninfo to check |
| @@ -1632,9 +1690,14 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, | |||
| 1632 | struct drm_fb_helper *fb_helper = info->par; | 1690 | struct drm_fb_helper *fb_helper = info->par; |
| 1633 | struct drm_framebuffer *fb = fb_helper->fb; | 1691 | struct drm_framebuffer *fb = fb_helper->fb; |
| 1634 | 1692 | ||
| 1635 | if (var->pixclock != 0 || in_dbg_master()) | 1693 | if (in_dbg_master()) |
| 1636 | return -EINVAL; | 1694 | return -EINVAL; |
| 1637 | 1695 | ||
| 1696 | if (var->pixclock != 0) { | ||
| 1697 | DRM_DEBUG("fbdev emulation doesn't support changing the pixel clock, value of pixclock is ignored\n"); | ||
| 1698 | var->pixclock = 0; | ||
| 1699 | } | ||
| 1700 | |||
| 1638 | if ((drm_format_info_block_width(fb->format, 0) > 1) || | 1701 | if ((drm_format_info_block_width(fb->format, 0) > 1) || |
| 1639 | (drm_format_info_block_height(fb->format, 0) > 1)) | 1702 | (drm_format_info_block_height(fb->format, 0) > 1)) |
| 1640 | return -EINVAL; | 1703 | return -EINVAL; |
| @@ -1655,6 +1718,20 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, | |||
| 1655 | } | 1718 | } |
| 1656 | 1719 | ||
| 1657 | /* | 1720 | /* |
| 1721 | * Workaround for SDL 1.2, which is known to be setting all pixel format | ||
| 1722 | * fields values to zero in some cases. We treat this situation as a | ||
| 1723 | * kind of "use some reasonable autodetected values". | ||
| 1724 | */ | ||
| 1725 | if (!var->red.offset && !var->green.offset && | ||
| 1726 | !var->blue.offset && !var->transp.offset && | ||
| 1727 | !var->red.length && !var->green.length && | ||
| 1728 | !var->blue.length && !var->transp.length && | ||
| 1729 | !var->red.msb_right && !var->green.msb_right && | ||
| 1730 | !var->blue.msb_right && !var->transp.msb_right) { | ||
| 1731 | drm_fb_helper_fill_pixel_fmt(var, fb->format->depth); | ||
| 1732 | } | ||
| 1733 | |||
| 1734 | /* | ||
| 1658 | * drm fbdev emulation doesn't support changing the pixel format at all, | 1735 | * drm fbdev emulation doesn't support changing the pixel format at all, |
| 1659 | * so reject all pixel format changing requests. | 1736 | * so reject all pixel format changing requests. |
| 1660 | */ | 1737 | */ |
| @@ -1967,59 +2044,7 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe | |||
| 1967 | info->var.yoffset = 0; | 2044 | info->var.yoffset = 0; |
| 1968 | info->var.activate = FB_ACTIVATE_NOW; | 2045 | info->var.activate = FB_ACTIVATE_NOW; |
| 1969 | 2046 | ||
| 1970 | switch (fb->format->depth) { | 2047 | drm_fb_helper_fill_pixel_fmt(&info->var, fb->format->depth); |
| 1971 | case 8: | ||
| 1972 | info->var.red.offset = 0; | ||
| 1973 | info->var.green.offset = 0; | ||
| 1974 | info->var.blue.offset = 0; | ||
| 1975 | info->var.red.length = 8; /* 8bit DAC */ | ||
| 1976 | info->var.green.length = 8; | ||
| 1977 | info->var.blue.length = 8; | ||
| 1978 | info->var.transp.offset = 0; | ||
| 1979 | info->var.transp.length = 0; | ||
| 1980 | break; | ||
| 1981 | case 15: | ||
| 1982 | info->var.red.offset = 10; | ||
| 1983 | info->var.green.offset = 5; | ||
| 1984 | info->var.blue.offset = 0; | ||
| 1985 | info->var.red.length = 5; | ||
| 1986 | info->var.green.length = 5; | ||
| 1987 | info->var.blue.length = 5; | ||
| 1988 | info->var.transp.offset = 15; | ||
| 1989 | info->var.transp.length = 1; | ||
| 1990 | break; | ||
| 1991 | case 16: | ||
| 1992 | info->var.red.offset = 11; | ||
| 1993 | info->var.green.offset = 5; | ||
| 1994 | info->var.blue.offset = 0; | ||
| 1995 | info->var.red.length = 5; | ||
| 1996 | info->var.green.length = 6; | ||
| 1997 | info->var.blue.length = 5; | ||
| 1998 | info->var.transp.offset = 0; | ||
| 1999 | break; | ||
| 2000 | case 24: | ||
| 2001 | info->var.red.offset = 16; | ||
| 2002 | info->var.green.offset = 8; | ||
| 2003 | info->var.blue.offset = 0; | ||
| 2004 | info->var.red.length = 8; | ||
| 2005 | info->var.green.length = 8; | ||
| 2006 | info->var.blue.length = 8; | ||
| 2007 | info->var.transp.offset = 0; | ||
| 2008 | info->var.transp.length = 0; | ||
| 2009 | break; | ||
| 2010 | case 32: | ||
| 2011 | info->var.red.offset = 16; | ||
| 2012 | info->var.green.offset = 8; | ||
| 2013 | info->var.blue.offset = 0; | ||
| 2014 | info->var.red.length = 8; | ||
| 2015 | info->var.green.length = 8; | ||
| 2016 | info->var.blue.length = 8; | ||
| 2017 | info->var.transp.offset = 24; | ||
| 2018 | info->var.transp.length = 8; | ||
| 2019 | break; | ||
| 2020 | default: | ||
| 2021 | break; | ||
| 2022 | } | ||
| 2023 | 2048 | ||
| 2024 | info->var.xres = fb_width; | 2049 | info->var.xres = fb_width; |
| 2025 | info->var.yres = fb_height; | 2050 | info->var.yres = fb_height; |
