1eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen/* 2eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * linux/drivers/video/omap2/dss/overlay.c 3eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * 4eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * Copyright (C) 2009 Nokia Corporation 5eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com> 6eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * 7eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * Some code and ideas taken from drivers/video/omap/ driver 8eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * by Imre Deak. 9eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * 10eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * This program is free software; you can redistribute it and/or modify it 11eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * under the terms of the GNU General Public License version 2 as published by 12eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * the Free Software Foundation. 13eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * 14eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * This program is distributed in the hope that it will be useful, but WITHOUT 15eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * more details. 18eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * 19eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * You should have received a copy of the GNU General Public License along with 20eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen * this program. If not, see <http://www.gnu.org/licenses/>. 21eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen */ 22eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 23eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen#define DSS_SUBSYS_NAME "OVERLAY" 24eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 25eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen#include <linux/kernel.h> 26eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen#include <linux/module.h> 27eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen#include <linux/err.h> 28eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen#include <linux/sysfs.h> 29eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen#include <linux/platform_device.h> 30eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen#include <linux/delay.h> 315a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 32eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 33a0b38cc4d35e095f14ab0f486135f8a619ebfc14Tomi Valkeinen#include <video/omapdss.h> 34eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 35eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen#include "dss.h" 36a0acb5574b01f1a82dc5d863b4d89d84397aeafaArchit Taneja#include "dss_features.h" 37eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 38eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinenstatic int num_overlays; 3958452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinenstatic struct omap_overlay *overlays; 40eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 41eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinenint omap_dss_get_num_overlays(void) 42eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen{ 43eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen return num_overlays; 44eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen} 45eed07e0ed5367aede8d32758524f2dc2d252a291Tomi ValkeinenEXPORT_SYMBOL(omap_dss_get_num_overlays); 46eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 47eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinenstruct omap_overlay *omap_dss_get_overlay(int num) 48eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen{ 4958452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen if (num >= num_overlays) 5058452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen return NULL; 51eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 5258452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen return &overlays[num]; 53eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen} 54eed07e0ed5367aede8d32758524f2dc2d252a291Tomi ValkeinenEXPORT_SYMBOL(omap_dss_get_overlay); 55eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 56eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinenvoid dss_init_overlays(struct platform_device *pdev) 57eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen{ 58eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen int i, r; 59eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 6058452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen num_overlays = dss_feat_get_num_ovls(); 61eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 6258452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen overlays = kzalloc(sizeof(struct omap_overlay) * num_overlays, 6358452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen GFP_KERNEL); 64eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 6558452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen BUG_ON(overlays == NULL); 66eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 6758452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen for (i = 0; i < num_overlays; ++i) { 6858452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen struct omap_overlay *ovl = &overlays[i]; 69eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 70eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen switch (i) { 71eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen case 0: 72eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen ovl->name = "gfx"; 73eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen ovl->id = OMAP_DSS_GFX; 74eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen break; 75eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen case 1: 76eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen ovl->name = "vid1"; 77eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen ovl->id = OMAP_DSS_VIDEO1; 78eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen break; 79eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen case 2: 80eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen ovl->name = "vid2"; 81eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen ovl->id = OMAP_DSS_VIDEO2; 82eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen break; 83b8c095b4d62f90ed8da0cca7116125863b1d8befArchit Taneja case 3: 84b8c095b4d62f90ed8da0cca7116125863b1d8befArchit Taneja ovl->name = "vid3"; 85b8c095b4d62f90ed8da0cca7116125863b1d8befArchit Taneja ovl->id = OMAP_DSS_VIDEO3; 86b8c095b4d62f90ed8da0cca7116125863b1d8befArchit Taneja break; 87eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen } 88eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 8967019db86450b8b279a8c4be6f138e716f9bfdcaTomi Valkeinen ovl->caps = dss_feat_get_overlay_caps(ovl->id); 90a0acb5574b01f1a82dc5d863b4d89d84397aeafaArchit Taneja ovl->supported_modes = 91a0acb5574b01f1a82dc5d863b4d89d84397aeafaArchit Taneja dss_feat_get_supported_color_modes(ovl->id); 92a0acb5574b01f1a82dc5d863b4d89d84397aeafaArchit Taneja 93916915161d6a6995275dd41c580b3c9e16a859dfTomi Valkeinen r = dss_overlay_kobj_init(ovl, pdev); 9458452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen if (r) 95eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen DSSERR("failed to create sysfs file\n"); 96eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen } 97eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen} 98eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 99eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinenvoid dss_uninit_overlays(struct platform_device *pdev) 100eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen{ 10158452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen int i; 10258452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen 10358452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen for (i = 0; i < num_overlays; ++i) { 10458452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen struct omap_overlay *ovl = &overlays[i]; 105916915161d6a6995275dd41c580b3c9e16a859dfTomi Valkeinen dss_overlay_kobj_uninit(ovl); 106eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen } 107eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 10858452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen kfree(overlays); 10958452341265844d830ef5d0e705ee7577461bc45Tomi Valkeinen overlays = NULL; 110eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen num_overlays = 0; 111eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen} 112eed07e0ed5367aede8d32758524f2dc2d252a291Tomi Valkeinen 11354540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinenint dss_ovl_simple_check(struct omap_overlay *ovl, 11454540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen const struct omap_overlay_info *info) 11554540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen{ 11654540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { 11754540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen if (info->out_width != 0 && info->width != info->out_width) { 11854540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen DSSERR("check_overlay: overlay %d doesn't support " 11954540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen "scaling\n", ovl->id); 12054540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen return -EINVAL; 12154540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen } 12254540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen 12354540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen if (info->out_height != 0 && info->height != info->out_height) { 12454540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen DSSERR("check_overlay: overlay %d doesn't support " 12554540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen "scaling\n", ovl->id); 12654540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen return -EINVAL; 12754540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen } 12854540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen } 12954540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen 13054540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen if ((ovl->supported_modes & info->color_mode) == 0) { 13154540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen DSSERR("check_overlay: overlay %d doesn't support mode %d\n", 13254540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen ovl->id, info->color_mode); 13354540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen return -EINVAL; 13454540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen } 13554540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen 13654540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen if (info->zorder >= omap_dss_get_num_overlays()) { 13754540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen DSSERR("check_overlay: zorder %d too high\n", info->zorder); 13854540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen return -EINVAL; 13954540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen } 14054540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen 14165e006ff4bb06d42b532f866a846db6e4e637723Chandrabhanu Mahapatra if (dss_feat_rotation_type_supported(info->rotation_type) == 0) { 14265e006ff4bb06d42b532f866a846db6e4e637723Chandrabhanu Mahapatra DSSERR("check_overlay: rotation type %d not supported\n", 14365e006ff4bb06d42b532f866a846db6e4e637723Chandrabhanu Mahapatra info->rotation_type); 14465e006ff4bb06d42b532f866a846db6e4e637723Chandrabhanu Mahapatra return -EINVAL; 14565e006ff4bb06d42b532f866a846db6e4e637723Chandrabhanu Mahapatra } 14665e006ff4bb06d42b532f866a846db6e4e637723Chandrabhanu Mahapatra 14754540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen return 0; 14854540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen} 14954540d41aaad0ed3245d3e99db014ab03a219c5aTomi Valkeinen 150228b21349db4ca5636ec1efdb3b3d54fe18092deArchit Tanejaint dss_ovl_check(struct omap_overlay *ovl, struct omap_overlay_info *info, 151228b21349db4ca5636ec1efdb3b3d54fe18092deArchit Taneja const struct omap_video_timings *mgr_timings) 1526ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen{ 1536ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen u16 outw, outh; 1546ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen u16 dw, dh; 1556ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen 156228b21349db4ca5636ec1efdb3b3d54fe18092deArchit Taneja dw = mgr_timings->x_res; 157228b21349db4ca5636ec1efdb3b3d54fe18092deArchit Taneja dh = mgr_timings->y_res; 1586ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen 1596ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) { 1606ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen outw = info->width; 1616ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen outh = info->height; 1626ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen } else { 1636ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen if (info->out_width == 0) 1646ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen outw = info->width; 1656ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen else 1666ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen outw = info->out_width; 1676ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen 1686ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen if (info->out_height == 0) 1696ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen outh = info->height; 1706ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen else 1716ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen outh = info->out_height; 1726ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen } 1736ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen 1746ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen if (dw < info->pos_x + outw) { 1756ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen DSSERR("overlay %d horizontally not inside the display area " 1766ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen "(%d + %d >= %d)\n", 1776ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen ovl->id, info->pos_x, outw, dw); 1786ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen return -EINVAL; 1796ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen } 1806ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen 1816ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen if (dh < info->pos_y + outh) { 1826ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen DSSERR("overlay %d vertically not inside the display area " 1836ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen "(%d + %d >= %d)\n", 1846ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen ovl->id, info->pos_y, outh, dh); 1856ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen return -EINVAL; 1866ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen } 1876ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen 1886ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen return 0; 1896ac48d1e3ac788ad1d54895acd83be26cefb4fe9Tomi Valkeinen} 1906c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja 1916c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja/* 1926c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja * Checks if replication logic should be used. Only use when overlay is in 1936c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja * RGB12U or RGB16 mode, and video port width interface is 18bpp or 24bpp 1946c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja */ 1956c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Tanejabool dss_ovl_use_replication(struct dss_lcd_mgr_config config, 1966c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja enum omap_color_mode mode) 1976c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja{ 1986c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja if (mode != OMAP_DSS_COLOR_RGB12U && mode != OMAP_DSS_COLOR_RGB16) 1996c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja return false; 2006c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja 2016c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja return config.video_port_width > 16; 2026c6f510afb86e3c77c351dfa20cbb8ca834abad9Archit Taneja} 203