1b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* 2b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * linux/drivers/video/omap2/omapfb-main.c 3b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * 4b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * Copyright (C) 2008 Nokia Corporation 5b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 6b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * 7b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * Some code and ideas taken from drivers/video/omap/ driver 8b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * by Imre Deak. 9b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * 10b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * This program is free software; you can redistribute it and/or modify it 11b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * under the terms of the GNU General Public License version 2 as published by 12b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * the Free Software Foundation. 13b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * 14b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * This program is distributed in the hope that it will be useful, but WITHOUT 15b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * more details. 18b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * 19b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * You should have received a copy of the GNU General Public License along with 20b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * this program. If not, see <http://www.gnu.org/licenses/>. 21b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen */ 22b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 23b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/module.h> 24b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/delay.h> 255a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 26b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/fb.h> 27b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/dma-mapping.h> 28b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/vmalloc.h> 29b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/device.h> 30b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/platform_device.h> 31b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <linux/omapfb.h> 32b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 33a0b38cc4d35e095f14ab0f486135f8a619ebfc14Tomi Valkeinen#include <video/omapdss.h> 34b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <plat/vram.h> 35b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include <plat/vrfb.h> 36b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 37b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#include "omapfb.h" 38b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 39b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#define MODULE_NAME "omapfb" 40b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 41b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#define OMAPFB_PLANE_XRES_MIN 8 42b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#define OMAPFB_PLANE_YRES_MIN 8 43b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 44b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic char *def_mode; 45b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic char *def_vram; 4690ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool def_vrfb; 47b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int def_rotate; 4890ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool def_mirror; 4927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinenstatic bool auto_update; 5027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinenstatic unsigned int auto_update_freq; 5127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinenmodule_param(auto_update, bool, 0); 5227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinenmodule_param(auto_update_freq, uint, 0644); 53b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 54b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#ifdef DEBUG 5590ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellbool omapfb_debug; 56b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenmodule_param_named(debug, omapfb_debug, bool, 0644); 5790ab5ee94171b3e28de6bb42ee30b527014e0be7Rusty Russellstatic bool omapfb_test_pattern; 58b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenmodule_param_named(test, omapfb_test_pattern, bool, 0644); 59b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#endif 60b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 61b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi); 62a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinenstatic int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev, 63a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen struct omap_dss_device *dssdev); 64b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 65b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#ifdef DEBUG 66b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color) 67b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 68b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var = &fbi->var; 69b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_fix_screeninfo *fix = &fbi->fix; 70b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen void __iomem *addr = fbi->screen_base; 71b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen const unsigned bytespp = var->bits_per_pixel >> 3; 72b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen const unsigned line_len = fix->line_length / bytespp; 73b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 74b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r = (color >> 16) & 0xff; 75b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int g = (color >> 8) & 0xff; 76b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int b = (color >> 0) & 0xff; 77b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 78b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->bits_per_pixel == 16) { 79b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u16 __iomem *p = (u16 __iomem *)addr; 80b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen p += y * line_len + x; 81b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 82b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = r * 32 / 256; 83b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen g = g * 64 / 256; 84b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen b = b * 32 / 256; 85b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 86b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __raw_writew((r << 11) | (g << 5) | (b << 0), p); 87b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else if (var->bits_per_pixel == 24) { 88b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u8 __iomem *p = (u8 __iomem *)addr; 89b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen p += (y * line_len + x) * 3; 90b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 91b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __raw_writeb(b, p + 0); 92b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __raw_writeb(g, p + 1); 93b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __raw_writeb(r, p + 2); 94b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else if (var->bits_per_pixel == 32) { 95b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u32 __iomem *p = (u32 __iomem *)addr; 96b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen p += y * line_len + x; 97b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen __raw_writel(color, p); 98b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 99b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 100b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 101b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void fill_fb(struct fb_info *fbi) 102b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 103b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var = &fbi->var; 104b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen const short w = var->xres_virtual; 105b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen const short h = var->yres_virtual; 106b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen void __iomem *addr = fbi->screen_base; 107b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int y, x; 108b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 109b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!addr) 110b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return; 111b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 112b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("fill_fb %dx%d, line_len %d bytes\n", w, h, fbi->fix.line_length); 113b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 114b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (y = 0; y < h; y++) { 115b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (x = 0; x < w; x++) { 116b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (x < 20 && y < 20) 117b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen draw_pixel(fbi, x, y, 0xffffff); 118b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (x < 20 && (y > 20 && y < h - 20)) 119b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen draw_pixel(fbi, x, y, 0xff); 120b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (y < 20 && (x > 20 && x < w - 20)) 121b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen draw_pixel(fbi, x, y, 0xff00); 122b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (x > w - 20 && (y > 20 && y < h - 20)) 123b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen draw_pixel(fbi, x, y, 0xff0000); 124b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (y > h - 20 && (x > 20 && x < w - 20)) 125b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen draw_pixel(fbi, x, y, 0xffff00); 126b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (x == 20 || x == w - 20 || 127b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen y == 20 || y == h - 20) 128b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen draw_pixel(fbi, x, y, 0xffffff); 129b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (x == y || w - x == h - y) 130b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen draw_pixel(fbi, x, y, 0xff00ff); 131b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (w - x == y || x == h - y) 132b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen draw_pixel(fbi, x, y, 0x00ffff); 133b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (x > 20 && y > 20 && x < w - 20 && y < h - 20) { 134b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int t = x * 3 / w; 135b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned r = 0, g = 0, b = 0; 136b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned c; 137b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->bits_per_pixel == 16) { 138b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (t == 0) 139b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen b = (y % 32) * 256 / 32; 140b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (t == 1) 141b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen g = (y % 64) * 256 / 64; 142b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (t == 2) 143b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = (y % 32) * 256 / 32; 144b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 145b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (t == 0) 146b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen b = (y % 256); 147b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (t == 1) 148b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen g = (y % 256); 149b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (t == 2) 150b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = (y % 256); 151b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 152b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen c = (r << 16) | (g << 8) | (b << 0); 153b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen draw_pixel(fbi, x, y, c); 154b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 155b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen draw_pixel(fbi, x, y, 0); 156b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 157b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 158b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 159b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 160b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#endif 161b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 162a4c1a148a0c4c690b95938e9577be9e461bc5e5aVille Syrjälästatic unsigned omapfb_get_vrfb_offset(const struct omapfb_info *ofbi, int rot) 163b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 164078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä const struct vrfb *vrfb = &ofbi->region->vrfb; 165b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned offset; 166b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 167b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen switch (rot) { 168b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case FB_ROTATE_UR: 169b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset = 0; 170b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 171b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case FB_ROTATE_CW: 172b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset = vrfb->yoffset; 173b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 174b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case FB_ROTATE_UD: 175b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset = vrfb->yoffset * OMAP_VRFB_LINE_LEN + vrfb->xoffset; 176b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 177b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case FB_ROTATE_CCW: 178b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset = vrfb->xoffset * OMAP_VRFB_LINE_LEN; 179b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 180b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen default: 181b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen BUG(); 182b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 183b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 184b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset *= vrfb->bytespp; 185b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 186b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return offset; 187b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 188b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 189a4c1a148a0c4c690b95938e9577be9e461bc5e5aVille Syrjälästatic u32 omapfb_get_region_rot_paddr(const struct omapfb_info *ofbi, int rot) 190b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 191b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 192078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä return ofbi->region->vrfb.paddr[rot] 193b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen + omapfb_get_vrfb_offset(ofbi, rot); 194b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 195078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä return ofbi->region->paddr; 196b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 197b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 198b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 199a4c1a148a0c4c690b95938e9577be9e461bc5e5aVille Syrjälästatic u32 omapfb_get_region_paddr(const struct omapfb_info *ofbi) 200b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 201b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 202078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä return ofbi->region->vrfb.paddr[0]; 203b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else 204078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä return ofbi->region->paddr; 205b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 206b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 207a4c1a148a0c4c690b95938e9577be9e461bc5e5aVille Syrjälästatic void __iomem *omapfb_get_region_vaddr(const struct omapfb_info *ofbi) 208b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 209b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 210078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä return ofbi->region->vrfb.vaddr[0]; 211b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else 212078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä return ofbi->region->vaddr; 213b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 214b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 215b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic struct omapfb_colormode omapfb_colormodes[] = { 216b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen { 217b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .dssmode = OMAP_DSS_COLOR_UYVY, 218b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .bits_per_pixel = 16, 219b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .nonstd = OMAPFB_COLOR_YUV422, 220b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen }, { 221b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .dssmode = OMAP_DSS_COLOR_YUV2, 222b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .bits_per_pixel = 16, 223b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .nonstd = OMAPFB_COLOR_YUY422, 224b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen }, { 225b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .dssmode = OMAP_DSS_COLOR_ARGB16, 226b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .bits_per_pixel = 16, 227b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .red = { .length = 4, .offset = 8, .msb_right = 0 }, 228b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .green = { .length = 4, .offset = 4, .msb_right = 0 }, 229b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .blue = { .length = 4, .offset = 0, .msb_right = 0 }, 230b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .transp = { .length = 4, .offset = 12, .msb_right = 0 }, 231b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen }, { 232b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .dssmode = OMAP_DSS_COLOR_RGB16, 233b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .bits_per_pixel = 16, 234b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .red = { .length = 5, .offset = 11, .msb_right = 0 }, 235b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .green = { .length = 6, .offset = 5, .msb_right = 0 }, 236b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .blue = { .length = 5, .offset = 0, .msb_right = 0 }, 237b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .transp = { .length = 0, .offset = 0, .msb_right = 0 }, 238b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen }, { 239b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .dssmode = OMAP_DSS_COLOR_RGB24P, 240b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .bits_per_pixel = 24, 241b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .red = { .length = 8, .offset = 16, .msb_right = 0 }, 242b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .green = { .length = 8, .offset = 8, .msb_right = 0 }, 243b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .blue = { .length = 8, .offset = 0, .msb_right = 0 }, 244b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .transp = { .length = 0, .offset = 0, .msb_right = 0 }, 245b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen }, { 246b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .dssmode = OMAP_DSS_COLOR_RGB24U, 247b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .bits_per_pixel = 32, 248b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .red = { .length = 8, .offset = 16, .msb_right = 0 }, 249b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .green = { .length = 8, .offset = 8, .msb_right = 0 }, 250b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .blue = { .length = 8, .offset = 0, .msb_right = 0 }, 251b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .transp = { .length = 0, .offset = 0, .msb_right = 0 }, 252b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen }, { 253b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .dssmode = OMAP_DSS_COLOR_ARGB32, 254b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .bits_per_pixel = 32, 255b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .red = { .length = 8, .offset = 16, .msb_right = 0 }, 256b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .green = { .length = 8, .offset = 8, .msb_right = 0 }, 257b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .blue = { .length = 8, .offset = 0, .msb_right = 0 }, 258b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .transp = { .length = 8, .offset = 24, .msb_right = 0 }, 259b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen }, { 260b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .dssmode = OMAP_DSS_COLOR_RGBA32, 261b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .bits_per_pixel = 32, 262b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .red = { .length = 8, .offset = 24, .msb_right = 0 }, 263b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .green = { .length = 8, .offset = 16, .msb_right = 0 }, 264b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .blue = { .length = 8, .offset = 8, .msb_right = 0 }, 265b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .transp = { .length = 8, .offset = 0, .msb_right = 0 }, 266b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen }, { 267b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .dssmode = OMAP_DSS_COLOR_RGBX32, 268b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .bits_per_pixel = 32, 269b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .red = { .length = 8, .offset = 24, .msb_right = 0 }, 270b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .green = { .length = 8, .offset = 16, .msb_right = 0 }, 271b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .blue = { .length = 8, .offset = 8, .msb_right = 0 }, 272b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .transp = { .length = 0, .offset = 0, .msb_right = 0 }, 273b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen }, 274b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen}; 275b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 276b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic bool cmp_var_to_colormode(struct fb_var_screeninfo *var, 277b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_colormode *color) 278b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 279b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen bool cmp_component(struct fb_bitfield *f1, struct fb_bitfield *f2) 280b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen { 281b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return f1->length == f2->length && 282b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen f1->offset == f2->offset && 283b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen f1->msb_right == f2->msb_right; 284b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 285b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 286b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->bits_per_pixel == 0 || 287b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->red.length == 0 || 288b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->blue.length == 0 || 289b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->green.length == 0) 290b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 291b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 292b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return var->bits_per_pixel == color->bits_per_pixel && 293b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen cmp_component(&var->red, &color->red) && 294b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen cmp_component(&var->green, &color->green) && 295b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen cmp_component(&var->blue, &color->blue) && 296b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen cmp_component(&var->transp, &color->transp); 297b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 298b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 299b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void assign_colormode_to_var(struct fb_var_screeninfo *var, 300b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_colormode *color) 301b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 302b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->bits_per_pixel = color->bits_per_pixel; 303b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->nonstd = color->nonstd; 304b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->red = color->red; 305b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->green = color->green; 306b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->blue = color->blue; 307b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->transp = color->transp; 308b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 309b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 310b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int fb_mode_to_dss_mode(struct fb_var_screeninfo *var, 311b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen enum omap_color_mode *mode) 312b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 313b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen enum omap_color_mode dssmode; 314b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 315b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 316b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* first match with nonstd field */ 317b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->nonstd) { 318b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) { 319b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_colormode *m = &omapfb_colormodes[i]; 320b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->nonstd == m->nonstd) { 321b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen assign_colormode_to_var(var, m); 322b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen *mode = m->dssmode; 323b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 324b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 325b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 326b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 327b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 328b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 329b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 330b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* then try exact match of bpp and colors */ 331b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) { 332b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_colormode *m = &omapfb_colormodes[i]; 333b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (cmp_var_to_colormode(var, m)) { 334b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen assign_colormode_to_var(var, m); 335b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen *mode = m->dssmode; 336b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 337b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 338b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 339b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 340b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* match with bpp if user has not filled color fields 341b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * properly */ 342b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen switch (var->bits_per_pixel) { 343b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 1: 344b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dssmode = OMAP_DSS_COLOR_CLUT1; 345b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 346b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 2: 347b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dssmode = OMAP_DSS_COLOR_CLUT2; 348b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 349b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 4: 350b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dssmode = OMAP_DSS_COLOR_CLUT4; 351b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 352b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 8: 353b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dssmode = OMAP_DSS_COLOR_CLUT8; 354b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 355b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 12: 356b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dssmode = OMAP_DSS_COLOR_RGB12U; 357b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 358b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 16: 359b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dssmode = OMAP_DSS_COLOR_RGB16; 360b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 361b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 24: 362b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dssmode = OMAP_DSS_COLOR_RGB24P; 363b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 364b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 32: 365b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dssmode = OMAP_DSS_COLOR_RGB24U; 366b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 367b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen default: 368b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 369b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 370b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 371b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) { 372b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_colormode *m = &omapfb_colormodes[i]; 373b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (dssmode == m->dssmode) { 374b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen assign_colormode_to_var(var, m); 375b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen *mode = m->dssmode; 376b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 377b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 378b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 379b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 380b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 381b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 382b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 383b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int check_fb_res_bounds(struct fb_var_screeninfo *var) 384b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 385b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int xres_min = OMAPFB_PLANE_XRES_MIN; 386b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int xres_max = 2048; 387b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int yres_min = OMAPFB_PLANE_YRES_MIN; 388b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int yres_max = 2048; 389b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 390b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* XXX: some applications seem to set virtual res to 0. */ 391b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->xres_virtual == 0) 392b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres_virtual = var->xres; 393b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 394b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->yres_virtual == 0) 395b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres_virtual = var->yres; 396b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 397b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->xres_virtual < xres_min || var->yres_virtual < yres_min) 398b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 399b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 400b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->xres < xres_min) 401b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres = xres_min; 402b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->yres < yres_min) 403b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres = yres_min; 404b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->xres > xres_max) 405b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres = xres_max; 406b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->yres > yres_max) 407b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres = yres_max; 408b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 409b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->xres > var->xres_virtual) 410b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres = var->xres_virtual; 411b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->yres > var->yres_virtual) 412b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres = var->yres_virtual; 413b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 414b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 415b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 416b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 417b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void shrink_height(unsigned long max_frame_size, 418b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var) 419b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 420b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("can't fit FB into memory, reducing y\n"); 421b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres_virtual = max_frame_size / 422b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen (var->xres_virtual * var->bits_per_pixel >> 3); 423b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 424b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->yres_virtual < OMAPFB_PLANE_YRES_MIN) 425b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres_virtual = OMAPFB_PLANE_YRES_MIN; 426b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 427b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->yres > var->yres_virtual) 428b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres = var->yres_virtual; 429b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 430b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 431b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void shrink_width(unsigned long max_frame_size, 432b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var) 433b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 434b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("can't fit FB into memory, reducing x\n"); 435b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres_virtual = max_frame_size / var->yres_virtual / 436b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen (var->bits_per_pixel >> 3); 437b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 438b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->xres_virtual < OMAPFB_PLANE_XRES_MIN) 439b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres_virtual = OMAPFB_PLANE_XRES_MIN; 440b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 441b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->xres > var->xres_virtual) 442b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres = var->xres_virtual; 443b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 444b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 445b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int check_vrfb_fb_size(unsigned long region_size, 446b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen const struct fb_var_screeninfo *var) 447b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 448b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long min_phys_size = omap_vrfb_min_phys_size(var->xres_virtual, 449b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres_virtual, var->bits_per_pixel >> 3); 450b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 451b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return min_phys_size > region_size ? -EINVAL : 0; 452b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 453b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 454b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int check_fb_size(const struct omapfb_info *ofbi, 455b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var) 456b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 457078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä unsigned long max_frame_size = ofbi->region->size; 458b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int bytespp = var->bits_per_pixel >> 3; 459b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long line_size = var->xres_virtual * bytespp; 460b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 461b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 462b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* One needs to check for both VRFB and OMAPFB limitations. */ 463b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (check_vrfb_fb_size(max_frame_size, var)) 464b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen shrink_height(omap_vrfb_max_height( 465b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen max_frame_size, var->xres_virtual, bytespp) * 466b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen line_size, var); 467b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 468b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (check_vrfb_fb_size(max_frame_size, var)) { 469b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("cannot fit FB to memory\n"); 470b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 471b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 472b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 473b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 474b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 475b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 476b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("max frame size %lu, line size %lu\n", max_frame_size, line_size); 477b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 478b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (line_size * var->yres_virtual > max_frame_size) 479b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen shrink_height(max_frame_size, var); 480b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 481b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (line_size * var->yres_virtual > max_frame_size) { 482b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen shrink_width(max_frame_size, var); 483b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen line_size = var->xres_virtual * bytespp; 484b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 485b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 486b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (line_size * var->yres_virtual > max_frame_size) { 487b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("cannot fit FB to memory\n"); 488b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 489b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 490b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 491b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 492b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 493b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 494b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* 495b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * Consider if VRFB assisted rotation is in use and if the virtual space for 496b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * the zero degree view needs to be mapped. The need for mapping also acts as 497b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * the trigger for setting up the hardware on the context in question. This 498b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * ensures that one does not attempt to access the virtual view before the 499b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * hardware is serving the address translations. 500b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen */ 501b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int setup_vrfb_rotation(struct fb_info *fbi) 502b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 503b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 504078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä struct omapfb2_mem_region *rg = ofbi->region; 505b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct vrfb *vrfb = &rg->vrfb; 506b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var = &fbi->var; 507b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_fix_screeninfo *fix = &fbi->fix; 508b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned bytespp; 509b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen bool yuv_mode; 510b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen enum omap_color_mode mode; 511b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 512b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen bool reconf; 513b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 514b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!rg->size || ofbi->rotation_type != OMAP_DSS_ROT_VRFB) 515b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 516b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 517b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("setup_vrfb_rotation\n"); 518b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 519b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = fb_mode_to_dss_mode(var, &mode); 520b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 521b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 522b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 523b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen bytespp = var->bits_per_pixel >> 3; 524b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 525b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen yuv_mode = mode == OMAP_DSS_COLOR_YUV2 || mode == OMAP_DSS_COLOR_UYVY; 526b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 527b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* We need to reconfigure VRFB if the resolution changes, if yuv mode 528b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * is enabled/disabled, or if bytes per pixel changes */ 529b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 530b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* XXX we shouldn't allow this when framebuffer is mmapped */ 531b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 532b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen reconf = false; 533b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 534b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (yuv_mode != vrfb->yuv_mode) 535b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen reconf = true; 536b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (bytespp != vrfb->bytespp) 537b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen reconf = true; 538b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (vrfb->xres != var->xres_virtual || 539b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen vrfb->yres != var->yres_virtual) 540b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen reconf = true; 541b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 542b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (vrfb->vaddr[0] && reconf) { 543b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbi->screen_base = NULL; 544b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->smem_start = 0; 545b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->smem_len = 0; 546b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen iounmap(vrfb->vaddr[0]); 547b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen vrfb->vaddr[0] = NULL; 548b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("setup_vrfb_rotation: reset fb\n"); 549b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 550b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 551b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (vrfb->vaddr[0]) 552b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 553b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 554b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omap_vrfb_setup(&rg->vrfb, rg->paddr, 555b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres_virtual, 556b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres_virtual, 557b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen bytespp, yuv_mode); 558b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 559b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* Now one can ioremap the 0 angle view */ 560b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omap_vrfb_map_angle(vrfb, var->yres_virtual, 0); 561b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 562b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 563b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 564b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* used by open/write in fbmem.c */ 565078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä fbi->screen_base = ofbi->region->vrfb.vaddr[0]; 566b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 567078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä fix->smem_start = ofbi->region->vrfb.paddr[0]; 568b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 569b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen switch (var->nonstd) { 570b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_YUV422: 571b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_YUY422: 572b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->line_length = 573b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 2; 574b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 575b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen default: 576b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->line_length = 577b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3; 578b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 579b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 580b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 581b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->smem_len = var->yres_virtual * fix->line_length; 582b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 583b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 584b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 585b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 586b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenint dss_mode_to_fb_mode(enum omap_color_mode dssmode, 587b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var) 588b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 589b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 590b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 591b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < ARRAY_SIZE(omapfb_colormodes); ++i) { 592b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_colormode *mode = &omapfb_colormodes[i]; 593b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (dssmode == mode->dssmode) { 594b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen assign_colormode_to_var(var, mode); 595b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 596b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 597b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 598b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -ENOENT; 599b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 600b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 601b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenvoid set_fb_fix(struct fb_info *fbi) 602b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 603b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_fix_screeninfo *fix = &fbi->fix; 604b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var = &fbi->var; 605b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 606078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä struct omapfb2_mem_region *rg = ofbi->region; 607b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 608b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("set_fb_fix\n"); 609b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 610b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* used by open/write in fbmem.c */ 611b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi); 612b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 613b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* used by mmap in fbmem.c */ 614b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 615b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen switch (var->nonstd) { 616b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_YUV422: 617b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_YUY422: 618b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->line_length = 619b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 2; 620b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 621b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen default: 622b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->line_length = 623b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3; 624b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 625b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 626b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 627b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->smem_len = var->yres_virtual * fix->line_length; 628b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 629b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->line_length = 630b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen (var->xres_virtual * var->bits_per_pixel) >> 3; 631b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->smem_len = rg->size; 632b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 633b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 634b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->smem_start = omapfb_get_region_paddr(ofbi); 635b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 636b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->type = FB_TYPE_PACKED_PIXELS; 637b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 638b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->nonstd) 639b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->visual = FB_VISUAL_PSEUDOCOLOR; 640b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else { 641b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen switch (var->bits_per_pixel) { 642b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 32: 643b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 24: 644b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 16: 645b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 12: 646b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->visual = FB_VISUAL_TRUECOLOR; 647b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* 12bpp is stored in 16 bits */ 648b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 649b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 1: 650b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 2: 651b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 4: 652b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 8: 653b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->visual = FB_VISUAL_PSEUDOCOLOR; 654b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 655b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 656b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 657b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 658b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->accel = FB_ACCEL_NONE; 659b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 660b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->xpanstep = 1; 661b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->ypanstep = 1; 662b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 663b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 664b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* check new var and possibly modify it to be ok */ 665b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenint check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var) 666b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 667b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 668b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_dss_device *display = fb2display(fbi); 669b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen enum omap_color_mode mode = 0; 670b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 671b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 672b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 673b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("check_fb_var %d\n", ofbi->id); 674b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 6751ceafc00910439c8e5450fae189b69427725992cVille Syrjälä WARN_ON(!atomic_read(&ofbi->region->lock_count)); 6761ceafc00910439c8e5450fae189b69427725992cVille Syrjälä 677b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = fb_mode_to_dss_mode(var, &mode); 678b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 679b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("cannot convert var to omap dss mode\n"); 680b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 681b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 682b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 683b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < ofbi->num_overlays; ++i) { 684b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if ((ofbi->overlays[i]->supported_modes & mode) == 0) { 685b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("invalid mode\n"); 686b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 687b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 688b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 689b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 69086f2d7dd72e1ff4656107e42a12c999a7b9c26d4Jani Nikula if (var->rotate > 3) 691b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 692b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 693b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (check_fb_res_bounds(var)) 694b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 695b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 696276a1d4337c9c261f42d5a7f813d96ca18f67c2bVille Syrjälä /* When no memory is allocated ignore the size check */ 697078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä if (ofbi->region->size != 0 && check_fb_size(ofbi, var)) 698b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 699b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 700b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->xres + var->xoffset > var->xres_virtual) 701b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xoffset = var->xres_virtual - var->xres; 702b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->yres + var->yoffset > var->yres_virtual) 703b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yoffset = var->yres_virtual - var->yres; 704b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 705b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("xres = %d, yres = %d, vxres = %d, vyres = %d\n", 706b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres, var->yres, 707b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres_virtual, var->yres_virtual); 708b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 7097a0987bf2cf2683901d0cd7f1504023da2584c5fJani Nikula if (display && display->driver->get_dimensions) { 7107a0987bf2cf2683901d0cd7f1504023da2584c5fJani Nikula u32 w, h; 7117a0987bf2cf2683901d0cd7f1504023da2584c5fJani Nikula display->driver->get_dimensions(display, &w, &h); 7127a0987bf2cf2683901d0cd7f1504023da2584c5fJani Nikula var->width = DIV_ROUND_CLOSEST(w, 1000); 7137a0987bf2cf2683901d0cd7f1504023da2584c5fJani Nikula var->height = DIV_ROUND_CLOSEST(h, 1000); 7147a0987bf2cf2683901d0cd7f1504023da2584c5fJani Nikula } else { 7157a0987bf2cf2683901d0cd7f1504023da2584c5fJani Nikula var->height = -1; 7167a0987bf2cf2683901d0cd7f1504023da2584c5fJani Nikula var->width = -1; 7177a0987bf2cf2683901d0cd7f1504023da2584c5fJani Nikula } 7187a0987bf2cf2683901d0cd7f1504023da2584c5fJani Nikula 719b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->grayscale = 0; 720b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 72169b2048f44ead2d278e25d12adf0494b469ffb1cTomi Valkeinen if (display && display->driver->get_timings) { 722b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_video_timings timings; 72369b2048f44ead2d278e25d12adf0494b469ffb1cTomi Valkeinen display->driver->get_timings(display, &timings); 724b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 725b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* pixclock in ps, the rest in pixclock */ 726b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->pixclock = timings.pixel_clock != 0 ? 727b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen KHZ2PICOS(timings.pixel_clock) : 728b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 0; 72987ba8288670c53f66ce41d8ce292c64674de821eTasslehoff Kjappfot var->left_margin = timings.hbp; 73087ba8288670c53f66ce41d8ce292c64674de821eTasslehoff Kjappfot var->right_margin = timings.hfp; 73187ba8288670c53f66ce41d8ce292c64674de821eTasslehoff Kjappfot var->upper_margin = timings.vbp; 73287ba8288670c53f66ce41d8ce292c64674de821eTasslehoff Kjappfot var->lower_margin = timings.vfp; 733b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->hsync_len = timings.hsw; 734b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->vsync_len = timings.vsw; 735b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 736b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->pixclock = 0; 737b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->left_margin = 0; 738b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->right_margin = 0; 739b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->upper_margin = 0; 740b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->lower_margin = 0; 741b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->hsync_len = 0; 742b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->vsync_len = 0; 743b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 744b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 745b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* TODO: get these from panel->config */ 746b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->vmode = FB_VMODE_NONINTERLACED; 747b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->sync = 0; 748b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 749b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 750b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 751b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 752b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* 753b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * --------------------------------------------------------------------------- 754b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * fbdev framework callbacks 755b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * --------------------------------------------------------------------------- 756b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen */ 757b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_open(struct fb_info *fbi, int user) 758b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 759b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 760b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 761b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 762b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_release(struct fb_info *fbi, int user) 763b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 764b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 765b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 766b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 767a4c1a148a0c4c690b95938e9577be9e461bc5e5aVille Syrjälästatic unsigned calc_rotation_offset_dma(const struct fb_var_screeninfo *var, 768a4c1a148a0c4c690b95938e9577be9e461bc5e5aVille Syrjälä const struct fb_fix_screeninfo *fix, int rotation) 769b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 770b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned offset; 771b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 772b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset = var->yoffset * fix->line_length + 773b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xoffset * (var->bits_per_pixel >> 3); 774b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 775b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return offset; 776b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 777b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 778a4c1a148a0c4c690b95938e9577be9e461bc5e5aVille Syrjälästatic unsigned calc_rotation_offset_vrfb(const struct fb_var_screeninfo *var, 779a4c1a148a0c4c690b95938e9577be9e461bc5e5aVille Syrjälä const struct fb_fix_screeninfo *fix, int rotation) 780b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 781b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned offset; 782b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 783b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rotation == FB_ROTATE_UD) 784b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset = (var->yres_virtual - var->yres) * 785b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fix->line_length; 786b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (rotation == FB_ROTATE_CW) 787b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset = (var->yres_virtual - var->yres) * 788b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen (var->bits_per_pixel >> 3); 789b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else 790b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset = 0; 791b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 792b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rotation == FB_ROTATE_UR) 793b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset += var->yoffset * fix->line_length + 794b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xoffset * (var->bits_per_pixel >> 3); 795b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (rotation == FB_ROTATE_UD) 796b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset -= var->yoffset * fix->line_length + 797b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xoffset * (var->bits_per_pixel >> 3); 798b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (rotation == FB_ROTATE_CW) 799b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset -= var->xoffset * fix->line_length + 800b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yoffset * (var->bits_per_pixel >> 3); 801b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else if (rotation == FB_ROTATE_CCW) 802b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen offset += var->xoffset * fix->line_length + 803b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yoffset * (var->bits_per_pixel >> 3); 804b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 805b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return offset; 806b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 807b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 80846d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälästatic void omapfb_calc_addr(const struct omapfb_info *ofbi, 80946d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä const struct fb_var_screeninfo *var, 81046d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä const struct fb_fix_screeninfo *fix, 811212b0d50e2eb7fc60f7bea1e90e5867b5fc0647dTomi Valkeinen int rotation, u32 *paddr) 81246d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä{ 81346d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä u32 data_start_p; 81446d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä int offset; 81546d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä 816212b0d50e2eb7fc60f7bea1e90e5867b5fc0647dTomi Valkeinen if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 81746d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä data_start_p = omapfb_get_region_rot_paddr(ofbi, rotation); 818212b0d50e2eb7fc60f7bea1e90e5867b5fc0647dTomi Valkeinen else 81946d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä data_start_p = omapfb_get_region_paddr(ofbi); 82046d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä 82146d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 82246d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä offset = calc_rotation_offset_vrfb(var, fix, rotation); 82346d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä else 82446d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä offset = calc_rotation_offset_dma(var, fix, rotation); 82546d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä 82646d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä data_start_p += offset; 82746d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä 82846d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä if (offset) 82946d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä DBG("offset %d, %d = %d\n", 83046d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä var->xoffset, var->yoffset, offset); 83146d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä 832212b0d50e2eb7fc60f7bea1e90e5867b5fc0647dTomi Valkeinen DBG("paddr %x\n", data_start_p); 83346d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä 83446d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä *paddr = data_start_p; 83546d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä} 836b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 837b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* setup overlay according to the fb */ 838078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjäläint omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl, 839b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u16 posx, u16 posy, u16 outw, u16 outh) 840b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 841b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r = 0; 842b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 843b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var = &fbi->var; 844b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_fix_screeninfo *fix = &fbi->fix; 845b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen enum omap_color_mode mode = 0; 84646d3524a1b9155dd9cd57ea28e00db08c7a95c1aVille Syrjälä u32 data_start_p = 0; 847b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_overlay_info info; 848b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int xres, yres; 849b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int screen_width; 850b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int mirror; 851b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int rotation = var->rotate; 852b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 853b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 8541ceafc00910439c8e5450fae189b69427725992cVille Syrjälä WARN_ON(!atomic_read(&ofbi->region->lock_count)); 8551ceafc00910439c8e5450fae189b69427725992cVille Syrjälä 856b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < ofbi->num_overlays; i++) { 857b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ovl != ofbi->overlays[i]) 858b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen continue; 859b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 860b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rotation = (rotation + ofbi->rotation[i]) % 4; 861b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 862b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 863b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 864b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("setup_overlay %d, posx %d, posy %d, outw %d, outh %d\n", ofbi->id, 865b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen posx, posy, outw, outh); 866b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 867b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rotation == FB_ROTATE_CW || rotation == FB_ROTATE_CCW) { 868b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen xres = var->yres; 869b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen yres = var->xres; 870b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 871b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen xres = var->xres; 872b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen yres = var->yres; 873b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 874b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 875078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä if (ofbi->region->size) 876212b0d50e2eb7fc60f7bea1e90e5867b5fc0647dTomi Valkeinen omapfb_calc_addr(ofbi, var, fix, rotation, &data_start_p); 877b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 878b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = fb_mode_to_dss_mode(var, &mode); 879b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 880b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("fb_mode_to_dss_mode failed"); 881b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err; 882b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 883b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 884b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen switch (var->nonstd) { 885b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_YUV422: 886b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_YUY422: 887b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 888b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen screen_width = fix->line_length 889b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen / (var->bits_per_pixel >> 2); 890b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 891b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 892b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen default: 893b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen screen_width = fix->line_length / (var->bits_per_pixel >> 3); 894b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 895b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 896b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 897b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ovl->get_overlay_info(ovl, &info); 898b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 899b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) 900b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen mirror = 0; 901b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen else 902b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen mirror = ofbi->mirror; 903b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 904b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.paddr = data_start_p; 905b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.screen_width = screen_width; 906b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.width = xres; 907b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.height = yres; 908b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.color_mode = mode; 909b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.rotation_type = ofbi->rotation_type; 910b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.rotation = rotation; 911b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.mirror = mirror; 912b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 913b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.pos_x = posx; 914b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.pos_y = posy; 915b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.out_width = outw; 916b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen info.out_height = outh; 917b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 918b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = ovl->set_overlay_info(ovl, &info); 919b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 920b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("ovl->setup_overlay_info failed\n"); 921b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err; 922b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 923b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 924b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 925b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 926b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenerr: 927b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("setup_overlay failed\n"); 928b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 929b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 930b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 931b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* apply var to the overlay */ 932b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenint omapfb_apply_changes(struct fb_info *fbi, int init) 933b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 934b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r = 0; 935b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 936b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var = &fbi->var; 937b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_overlay *ovl; 938b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u16 posx, posy; 939b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u16 outw, outh; 940b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 941b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 942b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#ifdef DEBUG 943b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (omapfb_test_pattern) 944b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fill_fb(fbi); 945b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#endif 946b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 9471ceafc00910439c8e5450fae189b69427725992cVille Syrjälä WARN_ON(!atomic_read(&ofbi->region->lock_count)); 9481ceafc00910439c8e5450fae189b69427725992cVille Syrjälä 949b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < ofbi->num_overlays; i++) { 950b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ovl = ofbi->overlays[i]; 951b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 952b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id); 953b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 954078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä if (ofbi->region->size == 0) { 955b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* the fb is not available. disable the overlay */ 956b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_overlay_enable(ovl, 0); 957b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!init && ovl->manager) 958b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ovl->manager->apply(ovl->manager); 959b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen continue; 960b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 961b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 962b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (init || (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { 963b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int rotation = (var->rotate + ofbi->rotation[i]) % 4; 964b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rotation == FB_ROTATE_CW || 965b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rotation == FB_ROTATE_CCW) { 966b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen outw = var->yres; 967b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen outh = var->xres; 968b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 969b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen outw = var->xres; 970b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen outh = var->yres; 971b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 972b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 973c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen struct omap_overlay_info info; 974c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen ovl->get_overlay_info(ovl, &info); 975c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen outw = info.out_width; 976c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen outh = info.out_height; 977b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 978b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 979b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (init) { 980b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen posx = 0; 981b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen posy = 0; 982b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 983c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen struct omap_overlay_info info; 984c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen ovl->get_overlay_info(ovl, &info); 985c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen posx = info.pos_x; 986c1a9febfafa2a9a9ac09b2de4c80aa96b41a03d1Tomi Valkeinen posy = info.pos_y; 987b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 988b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 989b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_setup_overlay(fbi, ovl, posx, posy, outw, outh); 990b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 991b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err; 992b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 993b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!init && ovl->manager) 994b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ovl->manager->apply(ovl->manager); 995b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 996b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 997b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenerr: 998b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("apply_changes failed\n"); 999b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1000b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1001b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1002b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* checks var and eventually tweaks it to something supported, 1003b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * DO NOT MODIFY PAR */ 1004b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) 1005b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1006430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä struct omapfb_info *ofbi = FB2OFB(fbi); 1007b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 1008b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1009b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("check_var(%d)\n", FB2OFB(fbi)->id); 1010b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1011430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(ofbi->region); 1012430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1013b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = check_fb_var(fbi, var); 1014b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1015430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(ofbi->region); 1016430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1017b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1018b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1019b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1020b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* set the video mode according to info->var */ 1021b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_set_par(struct fb_info *fbi) 1022b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1023430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä struct omapfb_info *ofbi = FB2OFB(fbi); 1024b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 1025b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1026b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("set_par(%d)\n", FB2OFB(fbi)->id); 1027b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1028430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(ofbi->region); 1029430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1030b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen set_fb_fix(fbi); 1031b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1032b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = setup_vrfb_rotation(fbi); 1033b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 1034430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä goto out; 1035b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1036b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_apply_changes(fbi, 0); 1037b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1038430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä out: 1039430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(ofbi->region); 1040430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1041b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1042b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1043b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1044b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_pan_display(struct fb_var_screeninfo *var, 1045b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi) 1046b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1047430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä struct omapfb_info *ofbi = FB2OFB(fbi); 1048b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo new_var; 1049b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 1050b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1051b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("pan_display(%d)\n", FB2OFB(fbi)->id); 1052b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1053b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (var->xoffset == fbi->var.xoffset && 1054b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yoffset == fbi->var.yoffset) 1055b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1056b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1057b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen new_var = fbi->var; 1058b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen new_var.xoffset = var->xoffset; 1059b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen new_var.yoffset = var->yoffset; 1060b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1061b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbi->var = new_var; 1062b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1063430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(ofbi->region); 1064430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1065b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_apply_changes(fbi, 0); 1066b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1067430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(ofbi->region); 1068430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1069b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1070b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1071b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1072b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void mmap_user_open(struct vm_area_struct *vma) 1073b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1074078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä struct omapfb2_mem_region *rg = vma->vm_private_data; 1075b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1076430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(rg); 1077078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä atomic_inc(&rg->map_count); 1078430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(rg); 1079b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1080b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1081b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void mmap_user_close(struct vm_area_struct *vma) 1082b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1083078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä struct omapfb2_mem_region *rg = vma->vm_private_data; 1084b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1085430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(rg); 1086078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä atomic_dec(&rg->map_count); 1087430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(rg); 1088b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1089b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1090b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic struct vm_operations_struct mmap_user_ops = { 1091b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .open = mmap_user_open, 1092b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .close = mmap_user_close, 1093b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen}; 1094b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1095b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma) 1096b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1097b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 1098b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_fix_screeninfo *fix = &fbi->fix; 1099078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä struct omapfb2_mem_region *rg; 1100b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long off; 1101b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long start; 1102b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u32 len; 1103430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä int r = -EINVAL; 1104b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1105b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (vma->vm_end - vma->vm_start == 0) 1106b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1107b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) 1108b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 1109b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen off = vma->vm_pgoff << PAGE_SHIFT; 1110b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1111430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä rg = omapfb_get_mem_region(ofbi->region); 1112078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä 1113b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen start = omapfb_get_region_paddr(ofbi); 1114b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen len = fix->smem_len; 1115b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (off >= len) 1116430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä goto error; 1117b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if ((vma->vm_end - vma->vm_start + off) > len) 1118430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä goto error; 1119b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1120b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen off += start; 1121b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1122b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("user mmap region start %lx, len %d, off %lx\n", start, len, off); 1123b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1124b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen vma->vm_pgoff = off >> PAGE_SHIFT; 1125b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen vma->vm_flags |= VM_IO | VM_RESERVED; 1126b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 1127b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen vma->vm_ops = &mmap_user_ops; 1128078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä vma->vm_private_data = rg; 1129b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT, 1130430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä vma->vm_end - vma->vm_start, 1131430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä vma->vm_page_prot)) { 1132430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä r = -EAGAIN; 1133430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä goto error; 1134430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä } 1135430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1136b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* vm_ops.open won't be called for mmap itself. */ 1137078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä atomic_inc(&rg->map_count); 1138430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1139430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(rg); 1140430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1141b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1142430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1143430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä error: 1144430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(ofbi->region); 1145430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1146430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä return r; 1147b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1148b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1149b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* Store a single color palette entry into a pseudo palette or the hardware 1150b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * palette if one is available. For now we support only 16bpp and thus store 1151b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * the entry only to the pseudo palette. 1152b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen */ 1153b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green, 1154b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u_int blue, u_int transp, int update_hw_pal) 1155b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1156b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /*struct omapfb_info *ofbi = FB2OFB(fbi);*/ 1157b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /*struct omapfb2_device *fbdev = ofbi->fbdev;*/ 1158b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var = &fbi->var; 1159b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r = 0; 1160b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1161b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen enum omapfb_color_format mode = OMAPFB_COLOR_RGB24U; /* XXX */ 1162b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1163b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /*switch (plane->color_mode) {*/ 1164b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen switch (mode) { 1165b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_YUV422: 1166b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_YUV420: 1167b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_YUY422: 1168b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 1169b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1170b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_CLUT_8BPP: 1171b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_CLUT_4BPP: 1172b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_CLUT_2BPP: 1173b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_CLUT_1BPP: 1174b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* 1175b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (fbdev->ctrl->setcolreg) 1176b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = fbdev->ctrl->setcolreg(regno, red, green, blue, 1177b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen transp, update_hw_pal); 1178b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen */ 1179b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* Fallthrough */ 1180b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 1181b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1182b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_RGB565: 1183b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_RGB444: 1184b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_RGB24P: 1185b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case OMAPFB_COLOR_RGB24U: 1186b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r != 0) 1187b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1188b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1189b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (regno < 16) { 1190b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u16 pal; 1191b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen pal = ((red >> (16 - var->red.length)) << 1192b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->red.offset) | 1193b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ((green >> (16 - var->green.length)) << 1194b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->green.offset) | 1195b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen (blue >> (16 - var->blue.length)); 1196b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ((u32 *)(fbi->pseudo_palette))[regno] = pal; 1197b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1198b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1199b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen default: 1200b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen BUG(); 1201b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1202b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1203b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1204b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1205b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 1206b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u_int transp, struct fb_info *info) 1207b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1208b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("setcolreg\n"); 1209b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1210b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return _setcolreg(info, regno, red, green, blue, transp, 1); 1211b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1212b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1213b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_setcmap(struct fb_cmap *cmap, struct fb_info *info) 1214b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1215b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int count, index, r; 1216b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u16 *red, *green, *blue, *transp; 1217b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u16 trans = 0xffff; 1218b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1219b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("setcmap\n"); 1220b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1221b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen red = cmap->red; 1222b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen green = cmap->green; 1223b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen blue = cmap->blue; 1224b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen transp = cmap->transp; 1225b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen index = cmap->start; 1226b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1227b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (count = 0; count < cmap->len; count++) { 1228b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (transp) 1229b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen trans = *transp++; 1230b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = _setcolreg(info, index++, *red++, *green++, *blue++, trans, 1231b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen count == cmap->len - 1); 1232b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r != 0) 1233b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1234b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1235b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1236b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1237b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1238b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1239b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_blank(int blank, struct fb_info *fbi) 1240b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1241b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 1242b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_device *fbdev = ofbi->fbdev; 1243b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_dss_device *display = fb2display(fbi); 124427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omapfb_display_data *d; 1245b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r = 0; 1246b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 12479325588757aa7d08bf2ca9c63b669d0d7aa2fc40Jani Nikula if (!display) 12489325588757aa7d08bf2ca9c63b669d0d7aa2fc40Jani Nikula return -EINVAL; 12499325588757aa7d08bf2ca9c63b669d0d7aa2fc40Jani Nikula 1250b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_lock(fbdev); 1251b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 125227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d = get_display_data(fbdev, display); 125327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 1254b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen switch (blank) { 1255b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case FB_BLANK_UNBLANK: 1256b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) 1257b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto exit; 1258b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 125937ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen if (display->driver->resume) 126037ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen r = display->driver->resume(display); 1261b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 126227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if ((display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) && 126327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d->update_mode == OMAPFB_AUTO_UPDATE && 126427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen !d->auto_update_work_enabled) 126527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen omapfb_start_auto_update(fbdev, display); 126627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 1267b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1268b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1269b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case FB_BLANK_NORMAL: 1270b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* FB_BLANK_NORMAL could be implemented. 1271b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * Needs DSS additions. */ 1272b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case FB_BLANK_VSYNC_SUSPEND: 1273b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case FB_BLANK_HSYNC_SUSPEND: 1274b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case FB_BLANK_POWERDOWN: 1275b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (display->state != OMAP_DSS_DISPLAY_ACTIVE) 1276b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto exit; 1277b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 127827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (d->auto_update_work_enabled) 127927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen omapfb_stop_auto_update(fbdev, display); 128027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 128137ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen if (display->driver->suspend) 128237ac60e414052f1d9301368437db8f0cb9e323feTomi Valkeinen r = display->driver->suspend(display); 1283b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1284b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1285b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1286b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen default: 1287b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 1288b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1289b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1290b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenexit: 1291b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_unlock(fbdev); 1292b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1293b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1294b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1295b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1296b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#if 0 1297b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* XXX fb_read and fb_write are needed for VRFB */ 1298b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenssize_t omapfb_write(struct fb_info *info, const char __user *buf, 1299b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen size_t count, loff_t *ppos) 1300b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1301b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("omapfb_write %d, %lu\n", count, (unsigned long)*ppos); 1302b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* XXX needed for VRFB */ 1303b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return count; 1304b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1305b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#endif 1306b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1307b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic struct fb_ops omapfb_ops = { 1308b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .owner = THIS_MODULE, 1309b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_open = omapfb_open, 1310b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_release = omapfb_release, 1311b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_fillrect = cfb_fillrect, 1312b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_copyarea = cfb_copyarea, 1313b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_imageblit = cfb_imageblit, 1314b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_blank = omapfb_blank, 1315b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_ioctl = omapfb_ioctl, 1316b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_check_var = omapfb_check_var, 1317b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_set_par = omapfb_set_par, 1318b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_pan_display = omapfb_pan_display, 1319b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_mmap = omapfb_mmap, 1320b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_setcolreg = omapfb_setcolreg, 1321b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .fb_setcmap = omapfb_setcmap, 1322b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /*.fb_write = omapfb_write,*/ 1323b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen}; 1324b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1325b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void omapfb_free_fbmem(struct fb_info *fbi) 1326b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1327b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 1328b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_device *fbdev = ofbi->fbdev; 1329b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_mem_region *rg; 1330b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1331078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä rg = ofbi->region; 1332078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä 1333078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä WARN_ON(atomic_read(&rg->map_count)); 1334b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1335b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rg->paddr) 1336b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (omap_vram_free(rg->paddr, rg->size)) 1337b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "VRAM FREE failed\n"); 1338b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1339b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rg->vaddr) 1340b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen iounmap(rg->vaddr); 1341b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1342b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 1343b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* unmap the 0 angle rotation */ 1344b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rg->vrfb.vaddr[0]) { 1345b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen iounmap(rg->vrfb.vaddr[0]); 1346b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omap_vrfb_release_ctx(&rg->vrfb); 1347f3a82d11d478a9eb5ff0cfa83796f0ba8149d841Tomi Valkeinen rg->vrfb.vaddr[0] = NULL; 1348b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1349b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1350b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1351b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->vaddr = NULL; 1352b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->paddr = 0; 1353b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->alloc = 0; 1354b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->size = 0; 1355b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1356b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1357b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void clear_fb_info(struct fb_info *fbi) 1358b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1359b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen memset(&fbi->var, 0, sizeof(fbi->var)); 1360b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen memset(&fbi->fix, 0, sizeof(fbi->fix)); 1361b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen strlcpy(fbi->fix.id, MODULE_NAME, sizeof(fbi->fix.id)); 1362b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1363b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1364b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_free_all_fbmem(struct omapfb2_device *fbdev) 1365b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1366b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 1367b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1368b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("free all fbmem\n"); 1369b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1370b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) { 1371b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi = fbdev->fbs[i]; 1372b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_free_fbmem(fbi); 1373b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen clear_fb_info(fbi); 1374b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1375b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1376b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1377b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1378b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1379b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size, 1380b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long paddr) 1381b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1382b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 1383b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_device *fbdev = ofbi->fbdev; 1384b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_mem_region *rg; 1385b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen void __iomem *vaddr; 1386b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 1387b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1388078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä rg = ofbi->region; 1389078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä 1390078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä rg->paddr = 0; 1391078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä rg->vaddr = NULL; 1392078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä memset(&rg->vrfb, 0, sizeof rg->vrfb); 1393078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä rg->size = 0; 1394078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä rg->type = 0; 1395078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä rg->alloc = false; 1396078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä rg->map = false; 1397b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1398b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen size = PAGE_ALIGN(size); 1399b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1400b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!paddr) { 1401b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("allocating %lu bytes for fb %d\n", size, ofbi->id); 14022a803c887b654bad7d6699f1270eaac31361afc9Tomi Valkeinen r = omap_vram_alloc(size, &paddr); 1403b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 1404b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr, 1405b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->id); 1406b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omap_vram_reserve(paddr, size); 1407b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1408b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1409b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 1410b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "failed to allocate framebuffer\n"); 1411b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -ENOMEM; 1412b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1413b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1414b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation_type != OMAP_DSS_ROT_VRFB) { 1415b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen vaddr = ioremap_wc(paddr, size); 1416b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1417b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!vaddr) { 1418b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "failed to ioremap framebuffer\n"); 1419b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omap_vram_free(paddr, size); 1420b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -ENOMEM; 1421b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1422b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1423b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr); 1424b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 1425b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omap_vrfb_request_ctx(&rg->vrfb); 1426b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 1427b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "vrfb create ctx failed\n"); 1428b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1429b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1430b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1431b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen vaddr = NULL; 1432b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1433b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1434b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->paddr = paddr; 1435b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->vaddr = vaddr; 1436b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->size = size; 1437b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->alloc = 1; 1438b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1439b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1440b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1441b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1442b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* allocate fbmem using display resolution as reference */ 1443b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size, 1444b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long paddr) 1445b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1446b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 1447a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen struct omapfb2_device *fbdev = ofbi->fbdev; 1448b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_dss_device *display; 1449b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int bytespp; 1450b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1451b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen display = fb2display(fbi); 1452b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1453b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!display) 1454b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1455b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1456a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen switch (omapfb_get_recommended_bpp(fbdev, display)) { 1457b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 16: 1458b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen bytespp = 2; 1459b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1460b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 24: 1461b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen bytespp = 4; 1462b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1463b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen default: 1464b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen bytespp = 4; 1465b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1466b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1467b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1468b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!size) { 1469b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u16 w, h; 1470b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 147196adceceedefff9b849d25ff582bc6f516903994Tomi Valkeinen display->driver->get_resolution(display, &w, &h); 1472b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1473b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) { 1474b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen size = max(omap_vrfb_min_phys_size(w, h, bytespp), 1475b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omap_vrfb_min_phys_size(h, w, bytespp)); 1476b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1477b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("adjusting fb mem size for VRFB, %u -> %lu\n", 1478b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen w * h * bytespp, size); 1479b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 1480b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen size = w * h * bytespp; 1481b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1482b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1483b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1484b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!size) 1485b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1486b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1487b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return omapfb_alloc_fbmem(fbi, size, paddr); 1488b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1489b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1490b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_parse_vram_param(const char *param, int max_entries, 1491b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long *sizes, unsigned long *paddrs) 1492b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1493b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int fbnum; 1494b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long size; 1495b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long paddr = 0; 1496b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen char *p, *start; 1497b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1498b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen start = (char *)param; 1499b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1500b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen while (1) { 1501b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen p = start; 1502b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1503b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbnum = simple_strtoul(p, &p, 10); 1504b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1505b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (p == param) 1506b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 1507b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1508b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (*p != ':') 1509b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 1510b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1511b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (fbnum >= max_entries) 1512b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 1513b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1514b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen size = memparse(p + 1, &p); 1515b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1516b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!size) 1517b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 1518b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1519b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen paddr = 0; 1520b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1521b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (*p == '@') { 1522b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen paddr = simple_strtoul(p + 1, &p, 16); 1523b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1524b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!paddr) 1525b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 1526b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1527b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1528b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1529b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen paddrs[fbnum] = paddr; 1530b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen sizes[fbnum] = size; 1531b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1532b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (*p == 0) 1533b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1534b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1535b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (*p != ',') 1536b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 1537b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1538b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ++p; 1539b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1540b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen start = p; 1541b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1542b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1543b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1544b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1545b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1546b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev) 1547b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1548b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i, r; 1549b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long vram_sizes[10]; 1550b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long vram_paddrs[10]; 1551b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1552b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen memset(&vram_sizes, 0, sizeof(vram_sizes)); 1553b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen memset(&vram_paddrs, 0, sizeof(vram_paddrs)); 1554b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1555b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (def_vram && omapfb_parse_vram_param(def_vram, 10, 1556b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen vram_sizes, vram_paddrs)) { 1557b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "failed to parse vram parameter\n"); 1558b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1559b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen memset(&vram_sizes, 0, sizeof(vram_sizes)); 1560b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen memset(&vram_paddrs, 0, sizeof(vram_paddrs)); 1561b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1562b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1563b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) { 1564b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* allocate memory automatically only for fb0, or if 1565b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * excplicitly defined with vram or plat data option */ 1566b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (i == 0 || vram_sizes[i] != 0) { 1567b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_alloc_fbmem_display(fbdev->fbs[i], 1568b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen vram_sizes[i], vram_paddrs[i]); 1569b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1570b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 1571b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1572b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1573b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1574b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1575b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) { 1576b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); 1577b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_mem_region *rg; 1578078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä rg = ofbi->region; 1579b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1580b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("region%d phys %08x virt %p size=%lu\n", 1581b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen i, 1582b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->paddr, 1583b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->vaddr, 1584b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rg->size); 1585b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1586b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1587b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1588b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1589b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1590b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenint omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type) 1591b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1592b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 1593b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_device *fbdev = ofbi->fbdev; 1594b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_dss_device *display = fb2display(fbi); 1595078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä struct omapfb2_mem_region *rg = ofbi->region; 1596b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long old_size = rg->size; 1597b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unsigned long old_paddr = rg->paddr; 1598b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int old_type = rg->type; 1599b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 1600b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 16012a803c887b654bad7d6699f1270eaac31361afc9Tomi Valkeinen if (type != OMAPFB_MEMTYPE_SDRAM) 1602b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 1603b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1604b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen size = PAGE_ALIGN(size); 1605b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1606b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (old_size == size && old_type == type) 1607b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1608b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 160918946f62c6cc8cf051bafca8b7fa72309e8a1067Tomi Valkeinen if (display && display->driver->sync) 161018946f62c6cc8cf051bafca8b7fa72309e8a1067Tomi Valkeinen display->driver->sync(display); 1611b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1612b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_free_fbmem(fbi); 1613b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1614b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (size == 0) { 1615b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen clear_fb_info(fbi); 1616b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1617b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1618b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1619b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_alloc_fbmem(fbi, size, 0); 1620b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1621b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 1622b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (old_size) 1623b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_alloc_fbmem(fbi, old_size, old_paddr); 1624b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1625b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rg->size == 0) 1626b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen clear_fb_info(fbi); 1627b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1628b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1629b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1630b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1631b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (old_size == size) 1632b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1633b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1634b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (old_size == 0) { 1635b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("initializing fb %d\n", ofbi->id); 1636b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_fb_init(fbdev, fbi); 1637b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 1638b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("omapfb_fb_init failed\n"); 1639b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err; 1640b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1641b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_apply_changes(fbi, 1); 1642b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 1643b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("omapfb_apply_changes failed\n"); 1644b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err; 1645b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1646b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 1647b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo new_var; 1648b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen memcpy(&new_var, &fbi->var, sizeof(new_var)); 1649b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = check_fb_var(fbi, &new_var); 1650b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 1651b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err; 1652b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen memcpy(&fbi->var, &new_var, sizeof(fbi->var)); 1653b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen set_fb_fix(fbi); 1654b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = setup_vrfb_rotation(fbi); 1655b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 1656b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err; 1657b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1658b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1659b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1660b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenerr: 1661b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_free_fbmem(fbi); 1662b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen clear_fb_info(fbi); 1663b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1664b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1665b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 166627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinenstatic void omapfb_auto_update_work(struct work_struct *work) 166727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen{ 166827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omap_dss_device *dssdev; 166927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omap_dss_driver *dssdrv; 167027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omapfb_display_data *d; 167127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen u16 w, h; 167227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen unsigned int freq; 167327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omapfb2_device *fbdev; 167427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 167527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d = container_of(work, struct omapfb_display_data, 167627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen auto_update_work.work); 167727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 167827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen dssdev = d->dssdev; 167927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen dssdrv = dssdev->driver; 168027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen fbdev = d->fbdev; 168127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 168227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (!dssdrv || !dssdrv->update) 168327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen return; 168427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 168527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (dssdrv->sync) 168627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen dssdrv->sync(dssdev); 168727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 168827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen dssdrv->get_resolution(dssdev, &w, &h); 168927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen dssdrv->update(dssdev, 0, 0, w, h); 169027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 169127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen freq = auto_update_freq; 169227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (freq == 0) 169327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen freq = 20; 169427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen queue_delayed_work(fbdev->auto_update_wq, 169527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen &d->auto_update_work, HZ / freq); 169627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen} 169727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 169827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinenvoid omapfb_start_auto_update(struct omapfb2_device *fbdev, 169927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omap_dss_device *display) 170027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen{ 170127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omapfb_display_data *d; 170227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 170327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (fbdev->auto_update_wq == NULL) { 170427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct workqueue_struct *wq; 170527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 170627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen wq = create_singlethread_workqueue("omapfb_auto_update"); 170727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 170827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (wq == NULL) { 170927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen dev_err(fbdev->dev, "Failed to create workqueue for " 171027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen "auto-update\n"); 171127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen return; 171227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen } 171327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 171427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen fbdev->auto_update_wq = wq; 171527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen } 171627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 171727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d = get_display_data(fbdev, display); 171827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 171927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen INIT_DELAYED_WORK(&d->auto_update_work, omapfb_auto_update_work); 172027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 172127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d->auto_update_work_enabled = true; 172227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 172327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen omapfb_auto_update_work(&d->auto_update_work.work); 172427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen} 172527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 172627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinenvoid omapfb_stop_auto_update(struct omapfb2_device *fbdev, 172727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omap_dss_device *display) 172827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen{ 172927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omapfb_display_data *d; 173027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 173127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d = get_display_data(fbdev, display); 173227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 173327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen cancel_delayed_work_sync(&d->auto_update_work); 173427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 173527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d->auto_update_work_enabled = false; 173627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen} 173727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 1738b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* initialize fb_info, var, fix to something sane based on the display */ 1739b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi) 1740b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1741b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_var_screeninfo *var = &fbi->var; 1742b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_dss_device *display = fb2display(fbi); 1743b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbi); 1744b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r = 0; 1745b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1746b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbi->fbops = &omapfb_ops; 1747b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbi->flags = FBINFO_FLAG_DEFAULT; 1748b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbi->pseudo_palette = fbdev->pseudo_palette; 1749b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1750078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä if (ofbi->region->size == 0) { 1751b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen clear_fb_info(fbi); 1752b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1753b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1754b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1755b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->nonstd = 0; 1756b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->bits_per_pixel = 0; 1757b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1758b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->rotate = def_rotate; 1759b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1760b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (display) { 1761b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u16 w, h; 1762b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int rotation = (var->rotate + ofbi->rotation[0]) % 4; 1763b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 176496adceceedefff9b849d25ff582bc6f516903994Tomi Valkeinen display->driver->get_resolution(display, &w, &h); 1765b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1766b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (rotation == FB_ROTATE_CW || 1767b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen rotation == FB_ROTATE_CCW) { 1768b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres = h; 1769b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres = w; 1770b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 1771b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres = w; 1772b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres = h; 1773b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1774b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1775b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres_virtual = var->xres; 1776b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres_virtual = var->yres; 1777b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1778b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!var->bits_per_pixel) { 1779a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen switch (omapfb_get_recommended_bpp(fbdev, display)) { 1780b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 16: 1781b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->bits_per_pixel = 16; 1782b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1783b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen case 24: 1784b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->bits_per_pixel = 32; 1785b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 1786b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen default: 1787b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "illegal display " 1788b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen "bpp\n"); 1789b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -EINVAL; 1790b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1791b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1792b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else { 1793b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* if there's no display, let's just guess some basic values */ 1794b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres = 320; 1795b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres = 240; 1796b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->xres_virtual = var->xres; 1797b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->yres_virtual = var->yres; 1798b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!var->bits_per_pixel) 1799b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen var->bits_per_pixel = 16; 1800b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1801b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1802b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = check_fb_var(fbi, var); 1803b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 1804b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err; 1805b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1806b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen set_fb_fix(fbi); 1807b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = setup_vrfb_rotation(fbi); 1808b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 1809b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err; 1810b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1811b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = fb_alloc_cmap(&fbi->cmap, 256, 0); 1812b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 1813b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "unable to allocate color map memory\n"); 1814b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1815b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenerr: 1816b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1817b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1818b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1819b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void fbinfo_cleanup(struct omapfb2_device *fbdev, struct fb_info *fbi) 1820b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1821b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fb_dealloc_cmap(&fbi->cmap); 1822b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1823b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1824b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1825b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void omapfb_free_resources(struct omapfb2_device *fbdev) 1826b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1827b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 1828b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1829b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("free_resources\n"); 1830b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1831b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (fbdev == NULL) 1832b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return; 1833b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1834b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) 1835b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen unregister_framebuffer(fbdev->fbs[i]); 1836b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1837b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* free the reserved fbmem */ 1838b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_free_all_fbmem(fbdev); 1839b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1840b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) { 1841b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbinfo_cleanup(fbdev, fbdev->fbs[i]); 1842b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen framebuffer_release(fbdev->fbs[i]); 1843b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1844b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1845b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_displays; i++) { 1846065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; 184727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 184827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (fbdev->displays[i].auto_update_work_enabled) 184927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen omapfb_stop_auto_update(fbdev, dssdev); 185027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 1851065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) 1852065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen dssdev->driver->disable(dssdev); 1853b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1854065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen omap_dss_put_device(dssdev); 1855b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1856b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 185727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (fbdev->auto_update_wq != NULL) { 185827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen flush_workqueue(fbdev->auto_update_wq); 185927cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen destroy_workqueue(fbdev->auto_update_wq); 186027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen fbdev->auto_update_wq = NULL; 186127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen } 186227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 1863b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_set_drvdata(fbdev->dev, NULL); 1864b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen kfree(fbdev); 1865b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1866b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1867b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_create_framebuffers(struct omapfb2_device *fbdev) 1868b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1869b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r, i; 1870b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1871b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev->num_fbs = 0; 1872b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1873b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("create %d framebuffers\n", CONFIG_FB_OMAP2_NUM_FBS); 1874b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1875b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* allocate fb_infos */ 1876b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < CONFIG_FB_OMAP2_NUM_FBS; i++) { 1877b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct fb_info *fbi; 1878b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi; 1879b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1880b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbi = framebuffer_alloc(sizeof(struct omapfb_info), 1881b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev->dev); 1882b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1883b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (fbi == NULL) { 1884b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, 1885b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen "unable to allocate memory for plane info\n"); 1886b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -ENOMEM; 1887b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1888b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1889b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen clear_fb_info(fbi); 1890b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1891b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev->fbs[i] = fbi; 1892b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1893b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi = FB2OFB(fbi); 1894b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->fbdev = fbdev; 1895b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->id = i; 1896b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1897078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä ofbi->region = &fbdev->regions[i]; 1898078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä ofbi->region->id = i; 18992f642a17503838e256b8b7e9f1153512e2efc38bVille Syrjälä init_rwsem(&ofbi->region->lock); 1900078ff546a806b2c2ab74c25c8edd4c6d4680656aVille Syrjälä 1901b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* assign these early, so that fb alloc can use them */ 1902b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->rotation_type = def_vrfb ? OMAP_DSS_ROT_VRFB : 1903b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen OMAP_DSS_ROT_DMA; 1904b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->mirror = def_mirror; 1905b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1906b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev->num_fbs++; 1907b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1908b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1909b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("fb_infos allocated\n"); 1910b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1911b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* assign overlays for the fbs */ 1912b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < min(fbdev->num_fbs, fbdev->num_overlays); i++) { 1913b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]); 1914b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1915b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->overlays[0] = fbdev->overlays[i]; 1916b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen ofbi->num_overlays = 1; 1917b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1918b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1919b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* allocate fb memories */ 1920b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_allocate_all_fbs(fbdev); 1921b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 1922b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "failed to allocate fbmem\n"); 1923b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1924b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1925b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1926b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("fbmems allocated\n"); 1927b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1928b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* setup fb_infos */ 1929b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) { 1930430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä struct fb_info *fbi = fbdev->fbs[i]; 1931430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä struct omapfb_info *ofbi = FB2OFB(fbi); 1932430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1933430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(ofbi->region); 1934430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä r = omapfb_fb_init(fbdev, fbi); 1935430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(ofbi->region); 1936430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1937b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 1938b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "failed to setup fb_info\n"); 1939b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1940b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1941b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1942b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1943b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("fb_infos initialized\n"); 1944b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1945b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) { 1946b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = register_framebuffer(fbdev->fbs[i]); 1947b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r != 0) { 1948b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, 1949b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen "registering framebuffer %d failed\n", i); 1950b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1951b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1952b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1953b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1954b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("framebuffers registered\n"); 1955b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1956b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_fbs; i++) { 1957430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä struct fb_info *fbi = fbdev->fbs[i]; 1958430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä struct omapfb_info *ofbi = FB2OFB(fbi); 1959430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1960430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_get_mem_region(ofbi->region); 1961430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä r = omapfb_apply_changes(fbi, 1); 1962430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä omapfb_put_mem_region(ofbi->region); 1963430571d59a0b51c6541c153ad8b08e72fef26098Ville Syrjälä 1964b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 1965b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, "failed to change mode\n"); 1966b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1967b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1968b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1969b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1970b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* Enable fb0 */ 1971b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (fbdev->num_fbs > 0) { 1972b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]); 1973b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1974b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (ofbi->num_overlays > 0) { 1975b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_overlay *ovl = ofbi->overlays[0]; 1976b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1977aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen ovl->manager->apply(ovl->manager); 1978aaa874a985158383c4b394c687c716ef26288741Tomi Valkeinen 1979b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_overlay_enable(ovl, 1); 1980b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1981b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) { 1982b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(fbdev->dev, 1983b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen "failed to enable overlay\n"); 1984b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 1985b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1986b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1987b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 1988b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1989b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("create_framebuffers done\n"); 1990b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1991b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 1992b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 1993b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 1994b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_mode_to_timings(const char *mode_str, 1995b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_video_timings *timings, u8 *bpp) 1996b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 1997897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen struct fb_info *fbi; 1998897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen struct fb_var_screeninfo *var; 1999897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen struct fb_ops *fbops; 2000b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 2001b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2002b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#ifdef CONFIG_OMAP2_DSS_VENC 2003b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (strcmp(mode_str, "pal") == 0) { 2004b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen *timings = omap_dss_pal_timings; 2005e8c66dcf5aa8df2d1b1f249519c920d3a45dd613Maurus Cuelenaere *bpp = 24; 2006b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 2007b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } else if (strcmp(mode_str, "ntsc") == 0) { 2008b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen *timings = omap_dss_ntsc_timings; 2009e8c66dcf5aa8df2d1b1f249519c920d3a45dd613Maurus Cuelenaere *bpp = 24; 2010b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 2011b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2012b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen#endif 2013b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2014b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* this is quite a hack, but I wanted to use the modedb and for 2015b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * that we need fb_info and var, so we create dummy ones */ 2016b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2017897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen *bpp = 0; 2018897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen fbi = NULL; 2019897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen var = NULL; 2020897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen fbops = NULL; 2021b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2022897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen fbi = kzalloc(sizeof(*fbi), GFP_KERNEL); 2023897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen if (fbi == NULL) { 2024897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen r = -ENOMEM; 2025897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen goto err; 2026897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen } 2027897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen 2028897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen var = kzalloc(sizeof(*var), GFP_KERNEL); 2029897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen if (var == NULL) { 2030897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen r = -ENOMEM; 2031897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen goto err; 2032897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen } 2033897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen 2034897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen fbops = kzalloc(sizeof(*fbops), GFP_KERNEL); 2035897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen if (fbops == NULL) { 2036897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen r = -ENOMEM; 2037897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen goto err; 2038897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen } 2039897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen 2040897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen fbi->fbops = fbops; 2041897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen 2042897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen r = fb_find_mode(var, fbi, mode_str, NULL, 0, NULL, 24); 2043897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen if (r == 0) { 2044897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen r = -EINVAL; 2045897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen goto err; 2046b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2047897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen 2048897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen timings->pixel_clock = PICOS2KHZ(var->pixclock); 2049897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen timings->hbp = var->left_margin; 2050897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen timings->hfp = var->right_margin; 2051897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen timings->vbp = var->upper_margin; 2052897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen timings->vfp = var->lower_margin; 2053897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen timings->hsw = var->hsync_len; 2054897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen timings->vsw = var->vsync_len; 2055897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen timings->x_res = var->xres; 2056897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen timings->y_res = var->yres; 2057897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen 2058897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen switch (var->bits_per_pixel) { 2059897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen case 16: 2060897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen *bpp = 16; 2061897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen break; 2062897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen case 24: 2063897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen case 32: 2064897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen default: 2065897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen *bpp = 24; 2066897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen break; 2067897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen } 2068897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen 2069897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen r = 0; 2070897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen 2071897044e99e437e908eef566d910692830546c2d9Tomi Valkeinenerr: 2072897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen kfree(fbi); 2073897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen kfree(var); 2074897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen kfree(fbops); 2075897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen 2076897044e99e437e908eef566d910692830546c2d9Tomi Valkeinen return r; 2077b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 2078b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2079a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinenstatic int omapfb_set_def_mode(struct omapfb2_device *fbdev, 2080a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen struct omap_dss_device *display, char *mode_str) 2081b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 2082b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r; 2083b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen u8 bpp; 2084371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar struct omap_video_timings timings, temp_timings; 2085065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen struct omapfb_display_data *d; 2086b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2087b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_mode_to_timings(mode_str, &timings, &bpp); 2088b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 2089b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 2090b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2091065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen d = get_display_data(fbdev, display); 2092065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen d->bpp_override = bpp; 2093b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2094371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar if (display->driver->check_timings) { 2095371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar r = display->driver->check_timings(display, &timings); 2096371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar if (r) 2097371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar return r; 2098371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar } else { 2099371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar /* If check_timings is not present compare xres and yres */ 2100371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar if (display->driver->get_timings) { 2101371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar display->driver->get_timings(display, &temp_timings); 2102b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2103371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar if (temp_timings.x_res != timings.x_res || 2104371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar temp_timings.y_res != timings.y_res) 2105371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar return -EINVAL; 2106371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar } 2107371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar } 2108b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2109371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar if (display->driver->set_timings) 2110371e2081447ce2bc6a25c20b513b9ba33cf5769eMayuresh Janorkar display->driver->set_timings(display, &timings); 2111b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2112b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 2113b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 2114b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2115a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinenstatic int omapfb_get_recommended_bpp(struct omapfb2_device *fbdev, 2116a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen struct omap_dss_device *dssdev) 2117a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen{ 2118065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen struct omapfb_display_data *d; 2119a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen 2120a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen BUG_ON(dssdev->driver->get_recommended_bpp == NULL); 2121a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen 2122065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen d = get_display_data(fbdev, dssdev); 2123065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen 2124065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen if (d->bpp_override != 0) 2125065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen return d->bpp_override; 2126a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen 2127a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen return dssdev->driver->get_recommended_bpp(dssdev); 2128a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen} 2129a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen 2130b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_parse_def_modes(struct omapfb2_device *fbdev) 2131b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 2132b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen char *str, *options, *this_opt; 2133b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r = 0; 2134b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 213536e8c27f3bee5e58f96b0a79d65922fa9e53b030Samreen str = kstrdup(def_mode, GFP_KERNEL); 213636e8c27f3bee5e58f96b0a79d65922fa9e53b030Samreen if (!str) 213736e8c27f3bee5e58f96b0a79d65922fa9e53b030Samreen return -ENOMEM; 2138b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen options = str; 2139b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2140b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen while (!r && (this_opt = strsep(&options, ",")) != NULL) { 2141b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen char *p, *display_str, *mode_str; 2142b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_dss_device *display; 2143b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 2144b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2145b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen p = strchr(this_opt, ':'); 2146b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!p) { 2147b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 2148b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 2149b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2150b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2151b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen *p = 0; 2152b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen display_str = this_opt; 2153b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen mode_str = p + 1; 2154b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2155b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen display = NULL; 2156b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_displays; ++i) { 2157065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen if (strcmp(fbdev->displays[i].dssdev->name, 2158b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen display_str) == 0) { 2159065a40bd461d3709a2c36adf0ec383581cc692a7Tomi Valkeinen display = fbdev->displays[i].dssdev; 2160b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 2161b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2162b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2163b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2164b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (!display) { 2165b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 2166b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 2167b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2168b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2169a269950405ab17ce3a604ddcd939709a4a7a747cTomi Valkeinen r = omapfb_set_def_mode(fbdev, display, mode_str); 2170b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 2171b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen break; 2172b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2173b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2174b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen kfree(str); 2175b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2176b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 2177b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 2178b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2179dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinenstatic void fb_videomode_to_omap_timings(struct fb_videomode *m, 2180dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen struct omap_video_timings *t) 2181dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen{ 2182dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen t->x_res = m->xres; 2183dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen t->y_res = m->yres; 2184dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen t->pixel_clock = PICOS2KHZ(m->pixclock); 2185dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen t->hsw = m->hsync_len; 2186dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen t->hfp = m->right_margin; 2187dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen t->hbp = m->left_margin; 2188dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen t->vsw = m->vsync_len; 2189dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen t->vfp = m->lower_margin; 2190dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen t->vbp = m->upper_margin; 2191dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen} 2192dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2193dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinenstatic int omapfb_find_best_mode(struct omap_dss_device *display, 2194dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen struct omap_video_timings *timings) 2195dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen{ 2196dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen struct fb_monspecs *specs; 2197dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen u8 *edid; 2198dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen int r, i, best_xres, best_idx, len; 2199dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2200dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen if (!display->driver->read_edid) 2201dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen return -ENODEV; 2202dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2203dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen len = 0x80 * 2; 2204dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen edid = kmalloc(len, GFP_KERNEL); 2205dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2206dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen r = display->driver->read_edid(display, edid, len); 2207dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen if (r < 0) 2208dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen goto err1; 2209dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2210dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen specs = kzalloc(sizeof(*specs), GFP_KERNEL); 2211dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2212dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen fb_edid_to_monspecs(edid, specs); 2213dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2214dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen if (edid[126] > 0) 2215dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen fb_edid_add_monspecs(edid + 0x80, specs); 2216dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2217dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen best_xres = 0; 2218dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen best_idx = -1; 2219dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2220dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen for (i = 0; i < specs->modedb_len; ++i) { 2221dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen struct fb_videomode *m; 2222dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen struct omap_video_timings t; 2223dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2224dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen m = &specs->modedb[i]; 2225dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2226dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen if (m->pixclock == 0) 2227dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen continue; 2228dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2229dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen /* skip repeated pixel modes */ 2230dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen if (m->xres == 2880 || m->xres == 1440) 2231dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen continue; 2232dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2233dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen fb_videomode_to_omap_timings(m, &t); 2234dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2235dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen r = display->driver->check_timings(display, &t); 2236dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen if (r == 0 && best_xres < m->xres) { 2237dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen best_xres = m->xres; 2238dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen best_idx = i; 2239dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen } 2240dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen } 2241dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2242dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen if (best_xres == 0) { 2243dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen r = -ENOENT; 2244dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen goto err2; 2245dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen } 2246dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2247dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen fb_videomode_to_omap_timings(&specs->modedb[best_idx], timings); 2248dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2249dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen r = 0; 2250dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2251dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinenerr2: 2252dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen fb_destroy_modedb(specs->modedb); 2253dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen kfree(specs); 2254dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinenerr1: 2255dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen kfree(edid); 2256dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2257dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen return r; 2258dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen} 2259dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 226091ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinenstatic int omapfb_init_display(struct omapfb2_device *fbdev, 226191ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen struct omap_dss_device *dssdev) 226291ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen{ 226391ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen struct omap_dss_driver *dssdrv = dssdev->driver; 226427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omapfb_display_data *d; 226591ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen int r; 226691ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen 226791ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen r = dssdrv->enable(dssdev); 226891ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen if (r) { 226991ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen dev_warn(fbdev->dev, "Failed to enable display '%s'\n", 227091ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen dssdev->name); 227191ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen return r; 227291ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen } 227391ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen 227427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d = get_display_data(fbdev, dssdev); 227527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 227627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d->fbdev = fbdev; 227727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 227891ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) { 227991ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen u16 w, h; 228027cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 228127cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (auto_update) { 228227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen omapfb_start_auto_update(fbdev, dssdev); 228327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d->update_mode = OMAPFB_AUTO_UPDATE; 228427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen } else { 228527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d->update_mode = OMAPFB_MANUAL_UPDATE; 228627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen } 228727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 228891ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen if (dssdrv->enable_te) { 228991ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen r = dssdrv->enable_te(dssdev, 1); 229091ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen if (r) { 229191ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen dev_err(fbdev->dev, "Failed to set TE\n"); 229291ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen return r; 229391ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen } 229491ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen } 229591ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen 229691ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen dssdrv->get_resolution(dssdev, &w, &h); 229791ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen r = dssdrv->update(dssdev, 0, 0, w, h); 229891ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen if (r) { 229991ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen dev_err(fbdev->dev, 230091ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen "Failed to update display\n"); 230191ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen return r; 230291ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen } 230391ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen } else { 230427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d->update_mode = OMAPFB_AUTO_UPDATE; 230591ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen } 230691ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen 230791ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen return 0; 230891ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen} 230991ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen 2310b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_probe(struct platform_device *pdev) 2311b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 2312b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_device *fbdev = NULL; 2313b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int r = 0; 2314b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen int i; 2315b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_overlay *ovl; 2316b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_dss_device *def_display; 2317b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_dss_device *dssdev; 2318b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2319b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("omapfb_probe\n"); 2320b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2321b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (pdev->num_resources != 0) { 2322b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(&pdev->dev, "probed for an unknown device\n"); 2323b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -ENODEV; 2324b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err0; 2325b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2326b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2327b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev = kzalloc(sizeof(struct omapfb2_device), GFP_KERNEL); 2328b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (fbdev == NULL) { 2329b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -ENOMEM; 2330b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto err0; 2331b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2332b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 233341814cfc01b059df33011d929837558c22f3c0e0Senthilvadivu Guruswamy /* TODO : Replace cpu check with omap_has_vrfb once HAS_FEATURE 233441814cfc01b059df33011d929837558c22f3c0e0Senthilvadivu Guruswamy * available for OMAP2 and OMAP3 233541814cfc01b059df33011d929837558c22f3c0e0Senthilvadivu Guruswamy */ 233641814cfc01b059df33011d929837558c22f3c0e0Senthilvadivu Guruswamy if (def_vrfb && !cpu_is_omap24xx() && !cpu_is_omap34xx()) { 233741814cfc01b059df33011d929837558c22f3c0e0Senthilvadivu Guruswamy def_vrfb = 0; 233841814cfc01b059df33011d929837558c22f3c0e0Senthilvadivu Guruswamy dev_warn(&pdev->dev, "VRFB is not supported on this hardware, " 233941814cfc01b059df33011d929837558c22f3c0e0Senthilvadivu Guruswamy "ignoring the module parameter vrfb=y\n"); 234041814cfc01b059df33011d929837558c22f3c0e0Senthilvadivu Guruswamy } 234141814cfc01b059df33011d929837558c22f3c0e0Senthilvadivu Guruswamy 234241814cfc01b059df33011d929837558c22f3c0e0Senthilvadivu Guruswamy 2343b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen mutex_init(&fbdev->mtx); 2344b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2345b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev->dev = &pdev->dev; 2346b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen platform_set_drvdata(pdev, fbdev); 2347b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2348b3f91eb8d8d17ad3ca5da4fa9f20d2e46133fd99Tomi Valkeinen r = 0; 2349b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev->num_displays = 0; 2350b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dssdev = NULL; 2351b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for_each_dss_dev(dssdev) { 235227cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen struct omapfb_display_data *d; 235327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen 2354b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omap_dss_get_device(dssdev); 2355b3f91eb8d8d17ad3ca5da4fa9f20d2e46133fd99Tomi Valkeinen 2356807a7515aea421f2b340140482ed4c8811c523c6Tomi Valkeinen if (!dssdev->driver) { 2357bab59b4417ea1380578358bedaeb714de6f1f6a7Tomi Valkeinen dev_warn(&pdev->dev, "no driver for display: %s\n", 2358c5f18d7babcb5a0822377f24d478bdaed6241770Andy Doan dssdev->name); 2359bab59b4417ea1380578358bedaeb714de6f1f6a7Tomi Valkeinen omap_dss_put_device(dssdev); 2360bab59b4417ea1380578358bedaeb714de6f1f6a7Tomi Valkeinen continue; 2361807a7515aea421f2b340140482ed4c8811c523c6Tomi Valkeinen } 2362b3f91eb8d8d17ad3ca5da4fa9f20d2e46133fd99Tomi Valkeinen 236327cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d = &fbdev->displays[fbdev->num_displays++]; 236427cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d->dssdev = dssdev; 236527cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) 236627cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d->update_mode = OMAPFB_MANUAL_UPDATE; 236727cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen else 236827cc213ea7dde929692df46a64c8d8ef74663e48Tomi Valkeinen d->update_mode = OMAPFB_AUTO_UPDATE; 2369b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2370b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2371b3f91eb8d8d17ad3ca5da4fa9f20d2e46133fd99Tomi Valkeinen if (r) 2372b3f91eb8d8d17ad3ca5da4fa9f20d2e46133fd99Tomi Valkeinen goto cleanup; 2373b3f91eb8d8d17ad3ca5da4fa9f20d2e46133fd99Tomi Valkeinen 2374b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (fbdev->num_displays == 0) { 2375b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(&pdev->dev, "no displays\n"); 2376b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = -EINVAL; 2377b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto cleanup; 2378b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2379b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2380b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev->num_overlays = omap_dss_get_num_overlays(); 2381b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_overlays; i++) 2382b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev->overlays[i] = omap_dss_get_overlay(i); 2383b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2384b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev->num_managers = omap_dss_get_num_overlay_managers(); 2385b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_managers; i++) 2386b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen fbdev->managers[i] = omap_dss_get_overlay_manager(i); 2387b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2388dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen /* gfx overlay should be the default one. find a display 2389dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen * connected to that, and use it as default display */ 2390dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen ovl = omap_dss_get_overlay(0); 2391dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen if (ovl->manager && ovl->manager->device) { 2392dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen def_display = ovl->manager->device; 2393dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen } else { 2394dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen dev_warn(&pdev->dev, "cannot find default display\n"); 2395dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen def_display = NULL; 2396dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen } 2397dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2398b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (def_mode && strlen(def_mode) > 0) { 2399b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (omapfb_parse_def_modes(fbdev)) 2400b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_warn(&pdev->dev, "cannot parse default modes\n"); 2401dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen } else if (def_display && def_display->driver->set_timings && 2402dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen def_display->driver->check_timings) { 2403dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen struct omap_video_timings t; 2404dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2405dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen r = omapfb_find_best_mode(def_display, &t); 2406dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen 2407dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen if (r == 0) 2408dc891fab115380d9dfddcd252df45a941ff9cb4eTomi Valkeinen def_display->driver->set_timings(def_display, &t); 2409b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2410b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2411b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = omapfb_create_framebuffers(fbdev); 2412b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 2413b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen goto cleanup; 2414b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2415b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen for (i = 0; i < fbdev->num_managers; i++) { 2416b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omap_overlay_manager *mgr; 2417b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen mgr = fbdev->managers[i]; 2418b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen r = mgr->apply(mgr); 2419b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (r) 2420b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_warn(fbdev->dev, "failed to apply dispc config\n"); 2421b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2422b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2423b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("mgr->apply'ed\n"); 2424b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2425b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (def_display) { 242691ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen r = omapfb_init_display(fbdev, def_display); 24276d2e0bd60848e97756f40e49da207e862f4f3851Tomi Valkeinen if (r) { 242891ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen dev_err(fbdev->dev, 242991ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen "failed to initialize default " 243091ac27a6879df3865e160adf979960a14f17d1aaTomi Valkeinen "display\n"); 24316d2e0bd60848e97756f40e49da207e862f4f3851Tomi Valkeinen goto cleanup; 24326d2e0bd60848e97756f40e49da207e862f4f3851Tomi Valkeinen } 2433b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2434b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2435e26ed44c950ed9d1feb7719100f475e4e80f1419Afzal Mohammed DBG("create sysfs for fbs\n"); 2436e26ed44c950ed9d1feb7719100f475e4e80f1419Afzal Mohammed r = omapfb_create_sysfs(fbdev); 2437e26ed44c950ed9d1feb7719100f475e4e80f1419Afzal Mohammed if (r) { 2438e26ed44c950ed9d1feb7719100f475e4e80f1419Afzal Mohammed dev_err(fbdev->dev, "failed to create sysfs entries\n"); 2439e26ed44c950ed9d1feb7719100f475e4e80f1419Afzal Mohammed goto cleanup; 2440e26ed44c950ed9d1feb7719100f475e4e80f1419Afzal Mohammed } 2441e26ed44c950ed9d1feb7719100f475e4e80f1419Afzal Mohammed 2442b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 2443b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2444b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinencleanup: 2445b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_free_resources(fbdev); 2446b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenerr0: 2447b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen dev_err(&pdev->dev, "failed to setup omapfb\n"); 2448b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return r; 2449b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 2450b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2451b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int omapfb_remove(struct platform_device *pdev) 2452b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 2453b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen struct omapfb2_device *fbdev = platform_get_drvdata(pdev); 2454b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2455b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen /* FIXME: wait till completion of pending events */ 2456b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2457b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_remove_sysfs(fbdev); 2458b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2459b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen omapfb_free_resources(fbdev); 2460b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2461b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 2462b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 2463b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2464b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic struct platform_driver omapfb_driver = { 2465b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .probe = omapfb_probe, 2466b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .remove = omapfb_remove, 2467b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .driver = { 2468b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .name = "omapfb", 2469b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen .owner = THIS_MODULE, 2470b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen }, 2471b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen}; 2472b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2473b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic int __init omapfb_init(void) 2474b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 2475b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("omapfb_init\n"); 2476b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2477b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen if (platform_driver_register(&omapfb_driver)) { 2478b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen printk(KERN_ERR "failed to register omapfb driver\n"); 2479b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return -ENODEV; 2480b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen } 2481b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2482b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen return 0; 2483b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 2484b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2485b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenstatic void __exit omapfb_exit(void) 2486b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen{ 2487b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen DBG("omapfb_exit\n"); 2488b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen platform_driver_unregister(&omapfb_driver); 2489b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen} 2490b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2491b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenmodule_param_named(mode, def_mode, charp, 0); 2492b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenmodule_param_named(vram, def_vram, charp, 0); 2493b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenmodule_param_named(rotate, def_rotate, int, 0); 2494b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenmodule_param_named(vrfb, def_vrfb, bool, 0); 2495b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenmodule_param_named(mirror, def_mirror, bool, 0); 2496b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2497b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/* late_initcall to let panel/ctrl drivers loaded first. 2498b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * I guess better option would be a more dynamic approach, 2499b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen * so that omapfb reacts to new panels when they are loaded */ 2500b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenlate_initcall(omapfb_init); 2501b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen/*module_init(omapfb_init);*/ 2502b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinenmodule_exit(omapfb_exit); 2503b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi Valkeinen 2504b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi ValkeinenMODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>"); 2505b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi ValkeinenMODULE_DESCRIPTION("OMAP2/3 Framebuffer"); 2506b39a982ddecf1d95ed96f8457c39d3ea11df93f6Tomi ValkeinenMODULE_LICENSE("GPL v2"); 2507