aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_fb_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_fb_helper.c')
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c133
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
1624static 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;