18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * omap_voutlib.c 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Copyright (C) 2005-2010 Texas Instruments. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This file is licensed under the terms of the GNU General Public License 78c2ecf20Sopenharmony_ci * version 2. This program is licensed "as is" without any warranty of any 88c2ecf20Sopenharmony_ci * kind, whether express or implied. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Based on the OMAP2 camera driver 118c2ecf20Sopenharmony_ci * Video-for-Linux (Version 2) camera capture driver for 128c2ecf20Sopenharmony_ci * the OMAP24xx camera controller. 138c2ecf20Sopenharmony_ci * 148c2ecf20Sopenharmony_ci * Author: Andy Lowe (source@mvista.com) 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * Copyright (C) 2004 MontaVista Software, Inc. 178c2ecf20Sopenharmony_ci * Copyright (C) 2010 Texas Instruments. 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci */ 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include <linux/module.h> 228c2ecf20Sopenharmony_ci#include <linux/errno.h> 238c2ecf20Sopenharmony_ci#include <linux/kernel.h> 248c2ecf20Sopenharmony_ci#include <linux/types.h> 258c2ecf20Sopenharmony_ci#include <linux/videodev2.h> 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h> 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci#include <video/omapfb_dss.h> 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci#include "omap_voutlib.h" 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ciMODULE_AUTHOR("Texas Instruments"); 348c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("OMAP Video library"); 358c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci/* Return the default overlay cropping rectangle in crop given the image 388c2ecf20Sopenharmony_ci * size in pix and the video display size in fbuf. The default 398c2ecf20Sopenharmony_ci * cropping rectangle is the largest rectangle no larger than the capture size 408c2ecf20Sopenharmony_ci * that will fit on the display. The default cropping rectangle is centered in 418c2ecf20Sopenharmony_ci * the image. All dimensions and offsets are rounded down to even numbers. 428c2ecf20Sopenharmony_ci */ 438c2ecf20Sopenharmony_civoid omap_vout_default_crop(struct v4l2_pix_format *pix, 448c2ecf20Sopenharmony_ci struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop) 458c2ecf20Sopenharmony_ci{ 468c2ecf20Sopenharmony_ci crop->width = (pix->width < fbuf->fmt.width) ? 478c2ecf20Sopenharmony_ci pix->width : fbuf->fmt.width; 488c2ecf20Sopenharmony_ci crop->height = (pix->height < fbuf->fmt.height) ? 498c2ecf20Sopenharmony_ci pix->height : fbuf->fmt.height; 508c2ecf20Sopenharmony_ci crop->width &= ~1; 518c2ecf20Sopenharmony_ci crop->height &= ~1; 528c2ecf20Sopenharmony_ci crop->left = ((pix->width - crop->width) >> 1) & ~1; 538c2ecf20Sopenharmony_ci crop->top = ((pix->height - crop->height) >> 1) & ~1; 548c2ecf20Sopenharmony_ci} 558c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(omap_vout_default_crop); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci/* Given a new render window in new_win, adjust the window to the 588c2ecf20Sopenharmony_ci * nearest supported configuration. The adjusted window parameters are 598c2ecf20Sopenharmony_ci * returned in new_win. 608c2ecf20Sopenharmony_ci * Returns zero if successful, or -EINVAL if the requested window is 618c2ecf20Sopenharmony_ci * impossible and cannot reasonably be adjusted. 628c2ecf20Sopenharmony_ci */ 638c2ecf20Sopenharmony_ciint omap_vout_try_window(struct v4l2_framebuffer *fbuf, 648c2ecf20Sopenharmony_ci struct v4l2_window *new_win) 658c2ecf20Sopenharmony_ci{ 668c2ecf20Sopenharmony_ci struct v4l2_rect try_win; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci /* make a working copy of the new_win rectangle */ 698c2ecf20Sopenharmony_ci try_win = new_win->w; 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci /* adjust the preview window so it fits on the display by clipping any 728c2ecf20Sopenharmony_ci * offscreen areas 738c2ecf20Sopenharmony_ci */ 748c2ecf20Sopenharmony_ci if (try_win.left < 0) { 758c2ecf20Sopenharmony_ci try_win.width += try_win.left; 768c2ecf20Sopenharmony_ci try_win.left = 0; 778c2ecf20Sopenharmony_ci } 788c2ecf20Sopenharmony_ci if (try_win.top < 0) { 798c2ecf20Sopenharmony_ci try_win.height += try_win.top; 808c2ecf20Sopenharmony_ci try_win.top = 0; 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci try_win.width = (try_win.width < fbuf->fmt.width) ? 838c2ecf20Sopenharmony_ci try_win.width : fbuf->fmt.width; 848c2ecf20Sopenharmony_ci try_win.height = (try_win.height < fbuf->fmt.height) ? 858c2ecf20Sopenharmony_ci try_win.height : fbuf->fmt.height; 868c2ecf20Sopenharmony_ci if (try_win.left + try_win.width > fbuf->fmt.width) 878c2ecf20Sopenharmony_ci try_win.width = fbuf->fmt.width - try_win.left; 888c2ecf20Sopenharmony_ci if (try_win.top + try_win.height > fbuf->fmt.height) 898c2ecf20Sopenharmony_ci try_win.height = fbuf->fmt.height - try_win.top; 908c2ecf20Sopenharmony_ci try_win.width &= ~1; 918c2ecf20Sopenharmony_ci try_win.height &= ~1; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci if (try_win.width <= 0 || try_win.height <= 0) 948c2ecf20Sopenharmony_ci return -EINVAL; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci /* We now have a valid preview window, so go with it */ 978c2ecf20Sopenharmony_ci new_win->w = try_win; 988c2ecf20Sopenharmony_ci new_win->field = V4L2_FIELD_NONE; 998c2ecf20Sopenharmony_ci new_win->clips = NULL; 1008c2ecf20Sopenharmony_ci new_win->clipcount = 0; 1018c2ecf20Sopenharmony_ci new_win->bitmap = NULL; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci return 0; 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(omap_vout_try_window); 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci/* Given a new render window in new_win, adjust the window to the 1088c2ecf20Sopenharmony_ci * nearest supported configuration. The image cropping window in crop 1098c2ecf20Sopenharmony_ci * will also be adjusted if necessary. Preference is given to keeping the 1108c2ecf20Sopenharmony_ci * the window as close to the requested configuration as possible. If 1118c2ecf20Sopenharmony_ci * successful, new_win, vout->win, and crop are updated. 1128c2ecf20Sopenharmony_ci * Returns zero if successful, or -EINVAL if the requested preview window is 1138c2ecf20Sopenharmony_ci * impossible and cannot reasonably be adjusted. 1148c2ecf20Sopenharmony_ci */ 1158c2ecf20Sopenharmony_ciint omap_vout_new_window(struct v4l2_rect *crop, 1168c2ecf20Sopenharmony_ci struct v4l2_window *win, struct v4l2_framebuffer *fbuf, 1178c2ecf20Sopenharmony_ci struct v4l2_window *new_win) 1188c2ecf20Sopenharmony_ci{ 1198c2ecf20Sopenharmony_ci int err; 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci err = omap_vout_try_window(fbuf, new_win); 1228c2ecf20Sopenharmony_ci if (err) 1238c2ecf20Sopenharmony_ci return err; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci /* update our preview window */ 1268c2ecf20Sopenharmony_ci win->w = new_win->w; 1278c2ecf20Sopenharmony_ci win->field = new_win->field; 1288c2ecf20Sopenharmony_ci win->chromakey = new_win->chromakey; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci /* Adjust the cropping window to allow for resizing limitation */ 1318c2ecf20Sopenharmony_ci if (omap_vout_dss_omap24xx()) { 1328c2ecf20Sopenharmony_ci /* For 24xx limit is 8x to 1/2x scaling. */ 1338c2ecf20Sopenharmony_ci if ((crop->height/win->w.height) >= 2) 1348c2ecf20Sopenharmony_ci crop->height = win->w.height * 2; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci if ((crop->width/win->w.width) >= 2) 1378c2ecf20Sopenharmony_ci crop->width = win->w.width * 2; 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci if (crop->width > 768) { 1408c2ecf20Sopenharmony_ci /* The OMAP2420 vertical resizing line buffer is 768 1418c2ecf20Sopenharmony_ci * pixels wide. If the cropped image is wider than 1428c2ecf20Sopenharmony_ci * 768 pixels then it cannot be vertically resized. 1438c2ecf20Sopenharmony_ci */ 1448c2ecf20Sopenharmony_ci if (crop->height != win->w.height) 1458c2ecf20Sopenharmony_ci crop->width = 768; 1468c2ecf20Sopenharmony_ci } 1478c2ecf20Sopenharmony_ci } else if (omap_vout_dss_omap34xx()) { 1488c2ecf20Sopenharmony_ci /* For 34xx limit is 8x to 1/4x scaling. */ 1498c2ecf20Sopenharmony_ci if ((crop->height/win->w.height) >= 4) 1508c2ecf20Sopenharmony_ci crop->height = win->w.height * 4; 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci if ((crop->width/win->w.width) >= 4) 1538c2ecf20Sopenharmony_ci crop->width = win->w.width * 4; 1548c2ecf20Sopenharmony_ci } 1558c2ecf20Sopenharmony_ci return 0; 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(omap_vout_new_window); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci/* Given a new cropping rectangle in new_crop, adjust the cropping rectangle to 1608c2ecf20Sopenharmony_ci * the nearest supported configuration. The image render window in win will 1618c2ecf20Sopenharmony_ci * also be adjusted if necessary. The preview window is adjusted such that the 1628c2ecf20Sopenharmony_ci * horizontal and vertical rescaling ratios stay constant. If the render 1638c2ecf20Sopenharmony_ci * window would fall outside the display boundaries, the cropping rectangle 1648c2ecf20Sopenharmony_ci * will also be adjusted to maintain the rescaling ratios. If successful, crop 1658c2ecf20Sopenharmony_ci * and win are updated. 1668c2ecf20Sopenharmony_ci * Returns zero if successful, or -EINVAL if the requested cropping rectangle is 1678c2ecf20Sopenharmony_ci * impossible and cannot reasonably be adjusted. 1688c2ecf20Sopenharmony_ci */ 1698c2ecf20Sopenharmony_ciint omap_vout_new_crop(struct v4l2_pix_format *pix, 1708c2ecf20Sopenharmony_ci struct v4l2_rect *crop, struct v4l2_window *win, 1718c2ecf20Sopenharmony_ci struct v4l2_framebuffer *fbuf, const struct v4l2_rect *new_crop) 1728c2ecf20Sopenharmony_ci{ 1738c2ecf20Sopenharmony_ci struct v4l2_rect try_crop; 1748c2ecf20Sopenharmony_ci unsigned long vresize, hresize; 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci /* make a working copy of the new_crop rectangle */ 1778c2ecf20Sopenharmony_ci try_crop = *new_crop; 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci /* adjust the cropping rectangle so it fits in the image */ 1808c2ecf20Sopenharmony_ci if (try_crop.left < 0) { 1818c2ecf20Sopenharmony_ci try_crop.width += try_crop.left; 1828c2ecf20Sopenharmony_ci try_crop.left = 0; 1838c2ecf20Sopenharmony_ci } 1848c2ecf20Sopenharmony_ci if (try_crop.top < 0) { 1858c2ecf20Sopenharmony_ci try_crop.height += try_crop.top; 1868c2ecf20Sopenharmony_ci try_crop.top = 0; 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci try_crop.width = (try_crop.width < pix->width) ? 1898c2ecf20Sopenharmony_ci try_crop.width : pix->width; 1908c2ecf20Sopenharmony_ci try_crop.height = (try_crop.height < pix->height) ? 1918c2ecf20Sopenharmony_ci try_crop.height : pix->height; 1928c2ecf20Sopenharmony_ci if (try_crop.left + try_crop.width > pix->width) 1938c2ecf20Sopenharmony_ci try_crop.width = pix->width - try_crop.left; 1948c2ecf20Sopenharmony_ci if (try_crop.top + try_crop.height > pix->height) 1958c2ecf20Sopenharmony_ci try_crop.height = pix->height - try_crop.top; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci try_crop.width &= ~1; 1988c2ecf20Sopenharmony_ci try_crop.height &= ~1; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci if (try_crop.width <= 0 || try_crop.height <= 0) 2018c2ecf20Sopenharmony_ci return -EINVAL; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci if (omap_vout_dss_omap24xx()) { 2048c2ecf20Sopenharmony_ci if (try_crop.height != win->w.height) { 2058c2ecf20Sopenharmony_ci /* If we're resizing vertically, we can't support a 2068c2ecf20Sopenharmony_ci * crop width wider than 768 pixels. 2078c2ecf20Sopenharmony_ci */ 2088c2ecf20Sopenharmony_ci if (try_crop.width > 768) 2098c2ecf20Sopenharmony_ci try_crop.width = 768; 2108c2ecf20Sopenharmony_ci } 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci /* vertical resizing */ 2138c2ecf20Sopenharmony_ci vresize = (1024 * try_crop.height) / win->w.height; 2148c2ecf20Sopenharmony_ci if (omap_vout_dss_omap24xx() && (vresize > 2048)) 2158c2ecf20Sopenharmony_ci vresize = 2048; 2168c2ecf20Sopenharmony_ci else if (omap_vout_dss_omap34xx() && (vresize > 4096)) 2178c2ecf20Sopenharmony_ci vresize = 4096; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci win->w.height = ((1024 * try_crop.height) / vresize) & ~1; 2208c2ecf20Sopenharmony_ci if (win->w.height == 0) 2218c2ecf20Sopenharmony_ci win->w.height = 2; 2228c2ecf20Sopenharmony_ci if (win->w.height + win->w.top > fbuf->fmt.height) { 2238c2ecf20Sopenharmony_ci /* We made the preview window extend below the bottom of the 2248c2ecf20Sopenharmony_ci * display, so clip it to the display boundary and resize the 2258c2ecf20Sopenharmony_ci * cropping height to maintain the vertical resizing ratio. 2268c2ecf20Sopenharmony_ci */ 2278c2ecf20Sopenharmony_ci win->w.height = (fbuf->fmt.height - win->w.top) & ~1; 2288c2ecf20Sopenharmony_ci if (try_crop.height == 0) 2298c2ecf20Sopenharmony_ci try_crop.height = 2; 2308c2ecf20Sopenharmony_ci } 2318c2ecf20Sopenharmony_ci /* horizontal resizing */ 2328c2ecf20Sopenharmony_ci hresize = (1024 * try_crop.width) / win->w.width; 2338c2ecf20Sopenharmony_ci if (omap_vout_dss_omap24xx() && (hresize > 2048)) 2348c2ecf20Sopenharmony_ci hresize = 2048; 2358c2ecf20Sopenharmony_ci else if (omap_vout_dss_omap34xx() && (hresize > 4096)) 2368c2ecf20Sopenharmony_ci hresize = 4096; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci win->w.width = ((1024 * try_crop.width) / hresize) & ~1; 2398c2ecf20Sopenharmony_ci if (win->w.width == 0) 2408c2ecf20Sopenharmony_ci win->w.width = 2; 2418c2ecf20Sopenharmony_ci if (win->w.width + win->w.left > fbuf->fmt.width) { 2428c2ecf20Sopenharmony_ci /* We made the preview window extend past the right side of the 2438c2ecf20Sopenharmony_ci * display, so clip it to the display boundary and resize the 2448c2ecf20Sopenharmony_ci * cropping width to maintain the horizontal resizing ratio. 2458c2ecf20Sopenharmony_ci */ 2468c2ecf20Sopenharmony_ci win->w.width = (fbuf->fmt.width - win->w.left) & ~1; 2478c2ecf20Sopenharmony_ci if (try_crop.width == 0) 2488c2ecf20Sopenharmony_ci try_crop.width = 2; 2498c2ecf20Sopenharmony_ci } 2508c2ecf20Sopenharmony_ci if (omap_vout_dss_omap24xx()) { 2518c2ecf20Sopenharmony_ci if ((try_crop.height/win->w.height) >= 2) 2528c2ecf20Sopenharmony_ci try_crop.height = win->w.height * 2; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci if ((try_crop.width/win->w.width) >= 2) 2558c2ecf20Sopenharmony_ci try_crop.width = win->w.width * 2; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci if (try_crop.width > 768) { 2588c2ecf20Sopenharmony_ci /* The OMAP2420 vertical resizing line buffer is 2598c2ecf20Sopenharmony_ci * 768 pixels wide. If the cropped image is wider 2608c2ecf20Sopenharmony_ci * than 768 pixels then it cannot be vertically resized. 2618c2ecf20Sopenharmony_ci */ 2628c2ecf20Sopenharmony_ci if (try_crop.height != win->w.height) 2638c2ecf20Sopenharmony_ci try_crop.width = 768; 2648c2ecf20Sopenharmony_ci } 2658c2ecf20Sopenharmony_ci } else if (omap_vout_dss_omap34xx()) { 2668c2ecf20Sopenharmony_ci if ((try_crop.height/win->w.height) >= 4) 2678c2ecf20Sopenharmony_ci try_crop.height = win->w.height * 4; 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci if ((try_crop.width/win->w.width) >= 4) 2708c2ecf20Sopenharmony_ci try_crop.width = win->w.width * 4; 2718c2ecf20Sopenharmony_ci } 2728c2ecf20Sopenharmony_ci /* update our cropping rectangle and we're done */ 2738c2ecf20Sopenharmony_ci *crop = try_crop; 2748c2ecf20Sopenharmony_ci return 0; 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(omap_vout_new_crop); 2778c2ecf20Sopenharmony_ci 2788c2ecf20Sopenharmony_ci/* Given a new format in pix and fbuf, crop and win 2798c2ecf20Sopenharmony_ci * structures are initialized to default values. crop 2808c2ecf20Sopenharmony_ci * is initialized to the largest window size that will fit on the display. The 2818c2ecf20Sopenharmony_ci * crop window is centered in the image. win is initialized to 2828c2ecf20Sopenharmony_ci * the same size as crop and is centered on the display. 2838c2ecf20Sopenharmony_ci * All sizes and offsets are constrained to be even numbers. 2848c2ecf20Sopenharmony_ci */ 2858c2ecf20Sopenharmony_civoid omap_vout_new_format(struct v4l2_pix_format *pix, 2868c2ecf20Sopenharmony_ci struct v4l2_framebuffer *fbuf, struct v4l2_rect *crop, 2878c2ecf20Sopenharmony_ci struct v4l2_window *win) 2888c2ecf20Sopenharmony_ci{ 2898c2ecf20Sopenharmony_ci /* crop defines the preview source window in the image capture 2908c2ecf20Sopenharmony_ci * buffer 2918c2ecf20Sopenharmony_ci */ 2928c2ecf20Sopenharmony_ci omap_vout_default_crop(pix, fbuf, crop); 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci /* win defines the preview target window on the display */ 2958c2ecf20Sopenharmony_ci win->w.width = crop->width; 2968c2ecf20Sopenharmony_ci win->w.height = crop->height; 2978c2ecf20Sopenharmony_ci win->w.left = ((fbuf->fmt.width - win->w.width) >> 1) & ~1; 2988c2ecf20Sopenharmony_ci win->w.top = ((fbuf->fmt.height - win->w.height) >> 1) & ~1; 2998c2ecf20Sopenharmony_ci} 3008c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(omap_vout_new_format); 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci/* 3038c2ecf20Sopenharmony_ci * Allocate buffers 3048c2ecf20Sopenharmony_ci */ 3058c2ecf20Sopenharmony_ciunsigned long omap_vout_alloc_buffer(u32 buf_size, u32 *phys_addr) 3068c2ecf20Sopenharmony_ci{ 3078c2ecf20Sopenharmony_ci u32 order, size; 3088c2ecf20Sopenharmony_ci unsigned long virt_addr, addr; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci size = PAGE_ALIGN(buf_size); 3118c2ecf20Sopenharmony_ci order = get_order(size); 3128c2ecf20Sopenharmony_ci virt_addr = __get_free_pages(GFP_KERNEL, order); 3138c2ecf20Sopenharmony_ci addr = virt_addr; 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci if (virt_addr) { 3168c2ecf20Sopenharmony_ci while (size > 0) { 3178c2ecf20Sopenharmony_ci SetPageReserved(virt_to_page(addr)); 3188c2ecf20Sopenharmony_ci addr += PAGE_SIZE; 3198c2ecf20Sopenharmony_ci size -= PAGE_SIZE; 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci } 3228c2ecf20Sopenharmony_ci *phys_addr = (u32) virt_to_phys((void *) virt_addr); 3238c2ecf20Sopenharmony_ci return virt_addr; 3248c2ecf20Sopenharmony_ci} 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci/* 3278c2ecf20Sopenharmony_ci * Free buffers 3288c2ecf20Sopenharmony_ci */ 3298c2ecf20Sopenharmony_civoid omap_vout_free_buffer(unsigned long virtaddr, u32 buf_size) 3308c2ecf20Sopenharmony_ci{ 3318c2ecf20Sopenharmony_ci u32 order, size; 3328c2ecf20Sopenharmony_ci unsigned long addr = virtaddr; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci size = PAGE_ALIGN(buf_size); 3358c2ecf20Sopenharmony_ci order = get_order(size); 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci while (size > 0) { 3388c2ecf20Sopenharmony_ci ClearPageReserved(virt_to_page(addr)); 3398c2ecf20Sopenharmony_ci addr += PAGE_SIZE; 3408c2ecf20Sopenharmony_ci size -= PAGE_SIZE; 3418c2ecf20Sopenharmony_ci } 3428c2ecf20Sopenharmony_ci free_pages((unsigned long) virtaddr, order); 3438c2ecf20Sopenharmony_ci} 3448c2ecf20Sopenharmony_ci 3458c2ecf20Sopenharmony_cibool omap_vout_dss_omap24xx(void) 3468c2ecf20Sopenharmony_ci{ 3478c2ecf20Sopenharmony_ci return omapdss_get_version() == OMAPDSS_VER_OMAP24xx; 3488c2ecf20Sopenharmony_ci} 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_cibool omap_vout_dss_omap34xx(void) 3518c2ecf20Sopenharmony_ci{ 3528c2ecf20Sopenharmony_ci switch (omapdss_get_version()) { 3538c2ecf20Sopenharmony_ci case OMAPDSS_VER_OMAP34xx_ES1: 3548c2ecf20Sopenharmony_ci case OMAPDSS_VER_OMAP34xx_ES3: 3558c2ecf20Sopenharmony_ci case OMAPDSS_VER_OMAP3630: 3568c2ecf20Sopenharmony_ci case OMAPDSS_VER_AM35xx: 3578c2ecf20Sopenharmony_ci return true; 3588c2ecf20Sopenharmony_ci default: 3598c2ecf20Sopenharmony_ci return false; 3608c2ecf20Sopenharmony_ci } 3618c2ecf20Sopenharmony_ci} 362