hwc.c revision 2b86fd0cbeb42123fc20b1f646ee81299e831d16
1c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/* 2c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Copyright (C) Texas Instruments - http://www.ti.com/ 3c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * 4c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License"); 5c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * you may not use this file except in compliance with the License. 6c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * You may obtain a copy of the License at 7c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * 8c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * http://www.apache.org/licenses/LICENSE-2.0 9c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * 10c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Unless required by applicable law or agreed to in writing, software 11c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS, 12c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * See the License for the specific language governing permissions and 14c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * limitations under the License. 15c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */ 16c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 17c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <errno.h> 18c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <malloc.h> 19c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <stdlib.h> 20c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <stdarg.h> 212125fa148686edfa389121f946377aedaa3d9483Lajos Molnar#include <fcntl.h> 2202150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian#include <poll.h> 232125fa148686edfa389121f946377aedaa3d9483Lajos Molnar#include <sys/ioctl.h> 242125fa148686edfa389121f946377aedaa3d9483Lajos Molnar#include <linux/fb.h> 25c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 26c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <cutils/properties.h> 27c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <cutils/log.h> 28c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <cutils/native_handle.h> 29c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <hardware/hardware.h> 30c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <hardware/hwcomposer.h> 31c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <EGL/egl.h> 32c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <utils/Timers.h> 332125fa148686edfa389121f946377aedaa3d9483Lajos Molnar#include <hardware_legacy/uevent.h> 34c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 35ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar#define ASPECT_RATIO_TOLERANCE 0.02f 36ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar 37a02dce1ac438e0538fbcef1c663092035c5f4348Lajos Molnar#ifndef FBIO_WAITFORVSYNC 38b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) 39a02dce1ac438e0538fbcef1c663092035c5f4348Lajos Molnar#endif 40a02dce1ac438e0538fbcef1c663092035c5f4348Lajos Molnar 4178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar#define min(a, b) ( { typeof(a) __a = (a), __b = (b); __a < __b ? __a : __b; } ) 4278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar#define max(a, b) ( { typeof(a) __a = (a), __b = (b); __a > __b ? __a : __b; } ) 43d4599029522592f46eccf9d57add7ebd7d23fdd1Lajos Molnar#define swap(a, b) do { typeof(a) __a = (a); (a) = (b); (b) = __a; } while (0) 4478fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 452704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar#define WIDTH(rect) ((rect).right - (rect).left) 462704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar#define HEIGHT(rect) ((rect).bottom - (rect).top) 472704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar 48c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <video/dsscomp.h> 49c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 50c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "hal_public.h" 51c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 52c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define MAX_HW_OVERLAYS 4 5378fce72baff38f488a0117591d4241d278a48b1bLajos Molnar#define NUM_NONSCALING_OVERLAYS 1 54b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar#define HAL_PIXEL_FORMAT_BGRX_8888 0x1FF 55b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar#define HAL_PIXEL_FORMAT_TI_NV12 0x100 56c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define HAL_PIXEL_FORMAT_TI_NV12_PADDED 0x101 5738934f125a600817dded7aeba9639c6a75afe358Lajos Molnar#define MAX_TILER_SLOT (16 << 20) 58c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 59ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnarstruct ext_transform_t { 60ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar __u8 rotation : 3; /* 90-degree clockwise rotations */ 61ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar __u8 hflip : 1; /* flip l-r (after rotation) */ 62ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar __u8 enabled : 1; /* cloning enabled */ 63ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar __u8 docking : 1; /* docking vs. mirroring - used for state */ 64ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar}; 65ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 66ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar/* cloning support and state */ 67ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnarstruct omap4_hwc_ext { 68ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar /* support */ 69ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar struct ext_transform_t mirror; /* mirroring settings */ 70ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar struct ext_transform_t dock; /* docking settings */ 713797fa989f5fee97caea2bbadf433a5a9ac03d8dLajos Molnar float lcd_xpy; /* pixel ratio for UI */ 724e635e537afaa9f1416fa5bdbfd1b03afd8b7e6aLajos Molnar __u8 avoid_mode_change; /* use HDMI mode used for mirroring if possible */ 732b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar __u8 force_dock; /* must dock */ 742b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar __u8 hdmi_state; /* whether HDMI is connected */ 75ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 76ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar /* state */ 77ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar __u8 on_tv; /* using a tv */ 78ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar struct ext_transform_t current; /* current settings */ 79ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar struct ext_transform_t last; /* last-used settings */ 80ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 81ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar /* configuration */ 821b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar __u32 last_xres_used; /* resolution and pixel ratio used for mode selection */ 83ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar __u32 last_yres_used; 844cb51e55fa79a592d50d94c0700660e42c988a0bLajos Molnar __u32 last_mode; /* 2-s complement of last HDMI mode set, 0 if none */ 854e635e537afaa9f1416fa5bdbfd1b03afd8b7e6aLajos Molnar __u32 mirror_mode; /* 2-s complement of mode used when mirroring */ 861b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar float last_xpy; 87ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar __u16 width; /* external screen dimensions */ 88ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar __u16 height; 89ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar __u32 xres; /* external screen resolution */ 90ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar __u32 yres; 91ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar float m[2][3]; /* external transformation matrix */ 928d546610cba3698c62af537d97e38a7368362f1aLajos Molnar hwc_rect_t mirror_region; /* region of screen to mirror */ 93ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar}; 94ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnartypedef struct omap4_hwc_ext omap4_hwc_ext_t; 95ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 96ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar/* used by property settings */ 9778fce72baff38f488a0117591d4241d278a48b1bLajos Molnarenum { 9878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar EXT_ROTATION = 3, /* rotation while mirroring */ 9978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar EXT_HFLIP = (1 << 2), /* flip l-r on output (after rotation) */ 10078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar}; 10178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 102c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstruct omap4_hwc_module { 103c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_module_t base; 104c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 105c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev IMG_framebuffer_device_public_t *fb_dev; 106c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}; 107c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevtypedef struct omap4_hwc_module omap4_hwc_module_t; 108c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 109c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstruct omap4_hwc_device { 11000d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar /* static data */ 111c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_composer_device_t base; 1122125fa148686edfa389121f946377aedaa3d9483Lajos Molnar hwc_procs_t *procs; 1132125fa148686edfa389121f946377aedaa3d9483Lajos Molnar pthread_t hdmi_thread; 1142125fa148686edfa389121f946377aedaa3d9483Lajos Molnar pthread_mutex_t lock; 115c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 116c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev IMG_framebuffer_device_public_t *fb_dev; 117d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar struct dsscomp_display_info fb_dis; 11800d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int fb_fd; /* file descriptor for /dev/fb0 */ 11900d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int dsscomp_fd; /* file descriptor for /dev/dsscomp */ 12000d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int hdmi_fb_fd; /* file descriptor for /dev/fb1 */ 12100d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int pipe_fds[2]; /* pipe to event thread */ 12200d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar 12300d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int flags_rgb_order; 12400d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int flags_nv12_only; 125c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 12600d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int force_sgx; 12700d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar omap4_hwc_ext_t ext; /* external mirroring data */ 12800d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int idle; 12900d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int ovls_blending; 130ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 13100d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar /* composition data */ 13200d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar struct dsscomp_setup_dispc_data dsscomp_data; 133c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev buffer_handle_t *buffers; 134c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int use_sgx; 13578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar int swap_rb; 13678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar unsigned int post2_layers; 13700d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int ext_ovls; /* # of overlays on external display for current composition */ 13800d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int ext_ovls_wanted; /* # of overlays that should be on external display for current composition */ 13900d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar int last_ext_ovls; /* # of overlays on external/internal display for last composition */ 14078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar int last_int_ovls; 141c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}; 142c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevtypedef struct omap4_hwc_device omap4_hwc_device_t; 143c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 144734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar#define HAL_FMT(f) ((f) == HAL_PIXEL_FORMAT_TI_NV12 ? "NV12" : \ 145734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar (f) == HAL_PIXEL_FORMAT_YV12 ? "YV12" : \ 146734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar (f) == HAL_PIXEL_FORMAT_BGRX_8888 ? "xRGB32" : \ 147734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar (f) == HAL_PIXEL_FORMAT_RGBX_8888 ? "xBGR32" : \ 148734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar (f) == HAL_PIXEL_FORMAT_BGRA_8888 ? "ARGB32" : \ 149734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar (f) == HAL_PIXEL_FORMAT_RGBA_8888 ? "ABGR32" : \ 150734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar (f) == HAL_PIXEL_FORMAT_RGB_565 ? "RGB565" : "??") 151734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar 152734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar#define DSS_FMT(f) ((f) == OMAP_DSS_COLOR_NV12 ? "NV12" : \ 153734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar (f) == OMAP_DSS_COLOR_RGB24U ? "xRGB32" : \ 154734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar (f) == OMAP_DSS_COLOR_ARGB32 ? "ARGB32" : \ 155734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar (f) == OMAP_DSS_COLOR_RGB16 ? "RGB565" : "??") 156734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar 157c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic int debug = 0; 158c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 159c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic void dump_layer(hwc_layer_t const* l) 160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}", 162b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar l->compositionType, l->flags, l->handle, l->transform, l->blending, 163b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar l->sourceCrop.left, 164b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar l->sourceCrop.top, 165b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar l->sourceCrop.right, 166b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar l->sourceCrop.bottom, 167b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar l->displayFrame.left, 168b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar l->displayFrame.top, 169b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar l->displayFrame.right, 170b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar l->displayFrame.bottom); 171c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 172c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 173c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic void dump_dsscomp(struct dsscomp_setup_dispc_data *d) 174c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 17578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar unsigned i; 176c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 17778fce72baff38f488a0117591d4241d278a48b1bLajos Molnar LOGD("[%08x] set: %c%c%c %d ovls\n", 178c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev d->sync_id, 179c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev (d->mode & DSSCOMP_SETUP_MODE_APPLY) ? 'A' : '-', 180c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev (d->mode & DSSCOMP_SETUP_MODE_DISPLAY) ? 'D' : '-', 181c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev (d->mode & DSSCOMP_SETUP_MODE_CAPTURE) ? 'C' : '-', 182c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev d->num_ovls); 183c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 18478fce72baff38f488a0117591d4241d278a48b1bLajos Molnar for (i = 0; i < d->num_mgrs; i++) { 18500d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar struct dss2_mgr_info *mi = &d->mgrs[i]; 18678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar LOGD(" (dis%d alpha=%d col=%08x ilace=%d)\n", 187b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar mi->ix, 188b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar mi->alpha_blending, mi->default_color, 189b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar mi->interlaced); 19078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar } 19178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 192c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev for (i = 0; i < d->num_ovls; i++) { 19300d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar struct dss2_ovl_info *oi = &d->ovls[i]; 194b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar struct dss2_ovl_cfg *c = &oi->cfg; 195b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar if (c->zonly) 196b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar LOGD("ovl%d(%s z%d)\n", 197b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar c->ix, c->enabled ? "ON" : "off", c->zorder); 198b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar else 199b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar LOGD("ovl%d(%s z%d %s%s *%d%% %d*%d:%d,%d+%d,%d rot%d%s => %d,%d+%d,%d %p/%p|%d)\n", 200b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar c->ix, c->enabled ? "ON" : "off", c->zorder, DSS_FMT(c->color_mode), 201b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar c->pre_mult_alpha ? " premult" : "", 202b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar (c->global_alpha * 100 + 128) / 255, 203b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar c->width, c->height, c->crop.x, c->crop.y, 204b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar c->crop.w, c->crop.h, 205b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar c->rotation, c->mirror ? "+mir" : "", 206b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar c->win.x, c->win.y, c->win.w, c->win.h, 207b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar (void *) oi->ba, (void *) oi->uv, c->stride); 208c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 209c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 210c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 211734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnarstruct dump_buf { 212734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar char *buf; 213734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar int buf_len; 214734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar int len; 215734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar}; 216734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar 217734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnarstatic void dump_printf(struct dump_buf *buf, const char *fmt, ...) 218734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar{ 219734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar va_list ap; 220734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar 221734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar va_start(ap, fmt); 222734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar buf->len += vsnprintf(buf->buf + buf->len, buf->buf_len - buf->len, fmt, ap); 223734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar va_end(ap); 224734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar} 225734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar 226734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnarstatic void dump_set_info(omap4_hwc_device_t *hwc_dev, hwc_layer_list_t* list) 227734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar{ 228734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 229734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar char logbuf[1024]; 230734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar struct dump_buf log = { 231734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar .buf = logbuf, 232734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar .buf_len = sizeof(logbuf), 233734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar }; 234734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar unsigned int i; 235734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar 236734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "set H{"); 237734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar for (i = 0; list && i < list->numHwLayers; i++) { 238734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar if (i) 239734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " "); 240734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar hwc_layer_t *layer = &list->hwLayers[i]; 241734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 242734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "%p:%s,", handle, layer->compositionType == HWC_OVERLAY ? "DSS" : "SGX"); 243734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar if ((layer->flags & HWC_SKIP_LAYER) || !handle) { 244734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "SKIP"); 245734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar continue; 246734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar } 247734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar if (layer->flags & HWC_HINT_CLEAR_FB) 248734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "CLR,"); 249734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "%d*%d(%s)", handle->iWidth, handle->iHeight, HAL_FMT(handle->iFormat)); 250734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar if (layer->transform) 251734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "~%d", layer->transform); 252734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar } 253734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "} D{"); 254734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar for (i = 0; i < dsscomp->num_ovls; i++) { 255734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar if (i) 256734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " "); 257734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "%d=", dsscomp->ovls[i].cfg.ix); 258734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar if (dsscomp->ovls[i].cfg.enabled) 259734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "%08x:%d*%d,%s", 260734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dsscomp->ovls[i].ba, 261734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dsscomp->ovls[i].cfg.width, 262734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dsscomp->ovls[i].cfg.height, 263734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar DSS_FMT(dsscomp->ovls[i].cfg.color_mode)); 264734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar else 265734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "-"); 266734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar } 267734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "} L{"); 268734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar for (i = 0; i < hwc_dev->post2_layers; i++) { 269734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar if (i) 270734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " "); 271734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "%p", hwc_dev->buffers[i]); 272734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar } 273734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "}%s\n", hwc_dev->use_sgx ? " swap" : ""); 274734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar 275734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar LOGD("%s", log.buf); 276734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar} 277734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar 2785706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnarstatic int sync_id = 0; 2795706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar 280c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic int omap4_hwc_is_valid_format(int format) 281c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 282c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev switch(format) { 283c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_RGB_565: 284c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_RGBX_8888: 285c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_RGBA_8888: 286c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_BGRA_8888: 287c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_BGRX_8888: 288c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_TI_NV12: 289c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_TI_NV12_PADDED: 290c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return 1; 291c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 292c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev default: 293c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return 0; 294c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 295c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 296c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 297c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic int scaled(hwc_layer_t *layer) 298c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 2992704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar int w = WIDTH(layer->sourceCrop); 3002704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar int h = HEIGHT(layer->sourceCrop); 301d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 302d4599029522592f46eccf9d57add7ebd7d23fdd1Lajos Molnar if (layer->transform & HWC_TRANSFORM_ROT_90) 303d4599029522592f46eccf9d57add7ebd7d23fdd1Lajos Molnar swap(w, h); 304d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 3052704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar return WIDTH(layer->displayFrame) != w || HEIGHT(layer->displayFrame) != h; 306c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 307c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 3085706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnarstatic int is_protected(hwc_layer_t *layer) 3094ce532200f33ca2c77cd66de924c83decaf7fa30Sunita Nadampalli{ 3104ce532200f33ca2c77cd66de924c83decaf7fa30Sunita Nadampalli IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 3114ce532200f33ca2c77cd66de924c83decaf7fa30Sunita Nadampalli 3124ce532200f33ca2c77cd66de924c83decaf7fa30Sunita Nadampalli return (handle->usage & GRALLOC_USAGE_PROTECTED); 3134ce532200f33ca2c77cd66de924c83decaf7fa30Sunita Nadampalli} 3144ce532200f33ca2c77cd66de924c83decaf7fa30Sunita Nadampalli 3155706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar#define is_BLENDED(layer) ((layer)->blending != HWC_BLENDING_NONE) 3165706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar 3175706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnarstatic int is_RGB(IMG_native_handle_t *handle) 3185706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar{ 3195706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar switch(handle->iFormat) 3205706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar { 3215706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar case HAL_PIXEL_FORMAT_BGRA_8888: 3225706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar case HAL_PIXEL_FORMAT_BGRX_8888: 3235706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar case HAL_PIXEL_FORMAT_RGB_565: 3245706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar return 1; 3255706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar default: 3265706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar return 0; 3275706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar } 3285706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar} 329c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 3305706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnarstatic int is_BGR_format(int format) 3315706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar{ 3325706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar switch (format) { 3335706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar case HAL_PIXEL_FORMAT_RGBX_8888: 3345706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar case HAL_PIXEL_FORMAT_RGBA_8888: 3355706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar return 1; 3365706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar default: 3375706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar return 0; 3385706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar } 3395706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar} 340a3a76c576a0a1706c102570697b4fc0017eb46fbMathias Agopian 3415706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnarstatic int is_BGR(IMG_native_handle_t *handle) 3425706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar{ 3435706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar return is_BGR_format(handle->iFormat); 3445706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar} 3455706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar 3465706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnarstatic int is_NV12(IMG_native_handle_t *handle) 3475706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar{ 3485706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar switch(handle->iFormat) 3495706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar { 3505706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar case HAL_PIXEL_FORMAT_TI_NV12: 3515706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar case HAL_PIXEL_FORMAT_TI_NV12_PADDED: 3525706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar return 1; 3535706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar default: 3545706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar return 0; 3555706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar } 3565706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar} 357c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 358834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnarstatic int dockable(hwc_layer_t *layer) 359834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar{ 360834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 361834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar 362834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar return (handle->usage & GRALLOC_USAGE_EXTERNAL_DISP); 363834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar} 364834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar 36538934f125a600817dded7aeba9639c6a75afe358Lajos Molnarstatic unsigned int mem1d(IMG_native_handle_t *handle) 36638934f125a600817dded7aeba9639c6a75afe358Lajos Molnar{ 3675706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar if (handle == NULL || is_NV12(handle)) 368b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar return 0; 36938934f125a600817dded7aeba9639c6a75afe358Lajos Molnar 3705706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar int bpp = handle->iFormat == HAL_PIXEL_FORMAT_RGB_565 ? 2 : 4; 37138934f125a600817dded7aeba9639c6a75afe358Lajos Molnar int stride = ALIGN(handle->iWidth, HW_ALIGN) * bpp; 37238934f125a600817dded7aeba9639c6a75afe358Lajos Molnar return stride * handle->iHeight; 37338934f125a600817dded7aeba9639c6a75afe358Lajos Molnar} 37438934f125a600817dded7aeba9639c6a75afe358Lajos Molnar 375c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic void 3765706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnaromap4_hwc_setup_layer_base(struct dss2_ovl_cfg *oc, int index, int format, int blended, int width, int height) 377c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 378c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev unsigned int bits_per_pixel; 379c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 380c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* YUV2RGB conversion */ 381c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev const struct omap_dss_cconv_coefs ctbl_bt601_5 = { 382c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 298, 409, 0, 298, -208, -100, 298, 0, 517, 0, 383c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev }; 384c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 385c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* convert color format */ 386c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev switch (format) { 387c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_RGBA_8888: 388c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_BGRA_8888: 389c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->color_mode = OMAP_DSS_COLOR_ARGB32; 390c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev bits_per_pixel = 32; 3915706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar if (blended) 3925706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar break; 393c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 3945706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar case HAL_PIXEL_FORMAT_RGBX_8888: 395c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_BGRX_8888: 396c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->color_mode = OMAP_DSS_COLOR_RGB24U; 397c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev bits_per_pixel = 32; 398c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev break; 399c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 400c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_RGB_565: 401c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->color_mode = OMAP_DSS_COLOR_RGB16; 402c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev bits_per_pixel = 16; 403c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev break; 404c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 405c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_TI_NV12: 406c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case HAL_PIXEL_FORMAT_TI_NV12_PADDED: 407c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->color_mode = OMAP_DSS_COLOR_NV12; 408c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev bits_per_pixel = 8; 409c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->cconv = ctbl_bt601_5; 410c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev break; 411c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 412c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev default: 413c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* Should have been filtered out */ 414c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOGV("Unsupported pixel format"); 415c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return; 416c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 417c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 418c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->width = width; 419c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->height = height; 420c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->stride = ALIGN(width, HW_ALIGN) * bits_per_pixel / 8; 421c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 422c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->enabled = 1; 423c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->global_alpha = 255; 424c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->zorder = index; 425c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->ix = 0; 426c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 427c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* defaults for SGX framebuffer renders */ 428c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->crop.w = oc->win.w = width; 429c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->crop.h = oc->win.h = height; 430c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 431c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* for now interlacing and vc1 info is not supplied */ 432c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->ilace = OMAP_DSS_ILACE_NONE; 433c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->vc1.enable = 0; 434c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 435c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 436c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic void 437c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevomap4_hwc_setup_layer(omap4_hwc_device_t *hwc_dev, struct dss2_ovl_info *ovl, 438c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_layer_t *layer, int index, 439c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int format, int width, int height) 440c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 441c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev struct dss2_ovl_cfg *oc = &ovl->cfg; 442c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 443c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev //dump_layer(layer); 444c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 4455706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar omap4_hwc_setup_layer_base(oc, index, format, is_BLENDED(layer), width, height); 446c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 447c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* convert transformation - assuming 0-set config */ 448c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (layer->transform & HWC_TRANSFORM_FLIP_H) 449c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->mirror = 1; 450c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (layer->transform & HWC_TRANSFORM_FLIP_V) { 451c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->rotation = 2; 45278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar oc->mirror = !oc->mirror; 453c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 454c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (layer->transform & HWC_TRANSFORM_ROT_90) { 455c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->rotation += oc->mirror ? -1 : 1; 456c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->rotation &= 3; 457c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 458c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 459c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->pre_mult_alpha = layer->blending == HWC_BLENDING_PREMULT; 460c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 461c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* display position */ 462c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->win.x = layer->displayFrame.left; 463c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->win.y = layer->displayFrame.top; 4642704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar oc->win.w = WIDTH(layer->displayFrame); 4652704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar oc->win.h = HEIGHT(layer->displayFrame); 466c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 467c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* crop */ 468c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->crop.x = layer->sourceCrop.left; 469c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev oc->crop.y = layer->sourceCrop.top; 4702704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar oc->crop.w = WIDTH(layer->sourceCrop); 4712704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar oc->crop.h = HEIGHT(layer->sourceCrop); 472c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 473c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 4742952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnarconst float m_unit[2][3] = { { 1., 0., 0. }, { 0., 1., 0. } }; 4752952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 4762952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnarstatic inline void m_translate(float m[2][3], int dx, int dy) 4772952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar{ 4782952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar m[0][2] += dx; 4792952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar m[1][2] += dy; 4802952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar} 4812952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 4822952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnarstatic inline void m_scale1(float m[3], int from, int to) 4832952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar{ 4842952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar m[0] = m[0] * to / from; 4852952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar m[1] = m[1] * to / from; 4862952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar m[2] = m[2] * to / from; 4872952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar} 4882952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 4892952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnarstatic inline void m_scale(float m[2][3], int x_from, int x_to, int y_from, int y_to) 4902952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar{ 4912952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar m_scale1(m[0], x_from, x_to); 4922952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar m_scale1(m[1], y_from, y_to); 4932952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar} 4942952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 4952952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnarstatic void m_rotate(float m[2][3], int quarter_turns) 4962952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar{ 4972952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar if (quarter_turns & 2) 4982952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar m_scale(m, 1, -1, 1, -1); 4992952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar if (quarter_turns & 1) { 5002952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar int q; 5012952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar q = m[0][0]; m[0][0] = -m[1][0]; m[1][0] = q; 5022952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar q = m[0][1]; m[0][1] = -m[1][1]; m[1][1] = q; 5032952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar q = m[0][2]; m[0][2] = -m[1][2]; m[1][2] = q; 5042952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar } 5052952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar} 5062952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 5072952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnarstatic inline int m_round(float x) 5082952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar{ 5092952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar /* int truncates towards 0 */ 5102952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar return (int) (x < 0 ? x - 0.5 : x + 0.5); 5112952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar} 5122952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 513ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar/* 5141b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar * assuming xpy (xratio:yratio) original pixel ratio, calculate the adjusted width 515ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar * and height for a screen of xres/yres and physical size of width/height. 516ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar * The adjusted size is the largest that fits into the screen. 517ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar */ 518ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnarstatic void get_max_dimensions(__u32 orig_xres, __u32 orig_yres, 5191b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar float xpy, 520ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar __u32 scr_xres, __u32 scr_yres, 521ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar __u32 scr_width, __u32 scr_height, 522ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar __u32 *adj_xres, __u32 *adj_yres) 523ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar{ 524ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar /* assume full screen (largest size)*/ 525ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar *adj_xres = scr_xres; 526ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar *adj_yres = scr_yres; 527ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar 528ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar /* assume 1:1 pixel ratios if none supplied */ 529ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar if (!scr_width || !scr_height) { 530ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar scr_width = scr_xres; 531ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar scr_height = scr_yres; 532ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar } 533ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar 534ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar /* trim to keep aspect ratio */ 5351b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar float x_factor = orig_xres * xpy * scr_height; 5361b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar float y_factor = orig_yres * scr_width; 537ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar 538ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar /* allow for tolerance so we avoid scaling if framebuffer is standard size */ 539ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar if (x_factor < y_factor * (1.f - ASPECT_RATIO_TOLERANCE)) 540ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar *adj_xres = (__u32) (x_factor * *adj_xres / y_factor + 0.5); 541ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar else if (x_factor * (1.f - ASPECT_RATIO_TOLERANCE) > y_factor) 542ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar *adj_yres = (__u32) (y_factor * *adj_yres / x_factor + 0.5); 543ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar} 544ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar 5458d546610cba3698c62af537d97e38a7368362f1aLajos Molnarstatic void set_ext_matrix(omap4_hwc_ext_t *ext, struct hwc_rect region) 5462952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar{ 5478d546610cba3698c62af537d97e38a7368362f1aLajos Molnar int orig_w = WIDTH(region); 5488d546610cba3698c62af537d97e38a7368362f1aLajos Molnar int orig_h = HEIGHT(region); 5493797fa989f5fee97caea2bbadf433a5a9ac03d8dLajos Molnar float xpy = ext->lcd_xpy; 5502952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 5512952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar /* reorientation matrix is: 5522952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar m = (center-from-target-center) * (scale-to-target) * (mirror) * (rotate) * (center-to-original-center) */ 5532952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 554ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar memcpy(ext->m, m_unit, sizeof(m_unit)); 5558d546610cba3698c62af537d97e38a7368362f1aLajos Molnar m_translate(ext->m, -(orig_w >> 1) - region.left, -(orig_h >> 1) - region.top); 556ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar m_rotate(ext->m, ext->current.rotation); 557ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar if (ext->current.hflip) 558ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar m_scale(ext->m, 1, -1, 1, 1); 5592952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 560ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar if (ext->current.rotation & 1) { 561d4599029522592f46eccf9d57add7ebd7d23fdd1Lajos Molnar swap(orig_w, orig_h); 5621b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar xpy = 1. / xpy; 5632952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar } 5642952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 565ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar /* get target size */ 566ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar __u32 adj_xres, adj_yres; 5671b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar get_max_dimensions(orig_w, orig_h, xpy, 568ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->xres, ext->yres, ext->width, ext->height, 569ae5ccc208800debb41acfc45096d318847e8db50Lajos Molnar &adj_xres, &adj_yres); 5702952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 571ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar m_scale(ext->m, orig_w, adj_xres, orig_h, adj_yres); 572ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar m_translate(ext->m, ext->xres >> 1, ext->yres >> 1); 5732952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar} 5742952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 5758d546610cba3698c62af537d97e38a7368362f1aLajos Molnarstatic int 5768d546610cba3698c62af537d97e38a7368362f1aLajos Molnarcrop_to_rect(struct dss2_ovl_cfg *cfg, struct hwc_rect vis_rect) 5778d546610cba3698c62af537d97e38a7368362f1aLajos Molnar{ 5788d546610cba3698c62af537d97e38a7368362f1aLajos Molnar struct { 5798d546610cba3698c62af537d97e38a7368362f1aLajos Molnar int xy[2]; 5808d546610cba3698c62af537d97e38a7368362f1aLajos Molnar int wh[2]; 5818d546610cba3698c62af537d97e38a7368362f1aLajos Molnar } crop, win; 5828d546610cba3698c62af537d97e38a7368362f1aLajos Molnar struct { 5838d546610cba3698c62af537d97e38a7368362f1aLajos Molnar int lt[2]; 5848d546610cba3698c62af537d97e38a7368362f1aLajos Molnar int rb[2]; 5858d546610cba3698c62af537d97e38a7368362f1aLajos Molnar } vis; 5868d546610cba3698c62af537d97e38a7368362f1aLajos Molnar win.xy[0] = cfg->win.x; win.xy[1] = cfg->win.y; 5878d546610cba3698c62af537d97e38a7368362f1aLajos Molnar win.wh[0] = cfg->win.w; win.wh[1] = cfg->win.h; 5888d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.xy[0] = cfg->crop.x; crop.xy[1] = cfg->crop.y; 5898d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.wh[0] = cfg->crop.w; crop.wh[1] = cfg->crop.h; 5908d546610cba3698c62af537d97e38a7368362f1aLajos Molnar vis.lt[0] = vis_rect.left; vis.lt[1] = vis_rect.top; 5918d546610cba3698c62af537d97e38a7368362f1aLajos Molnar vis.rb[0] = vis_rect.right; vis.rb[1] = vis_rect.bottom; 5928d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 5938d546610cba3698c62af537d97e38a7368362f1aLajos Molnar int c, swap = cfg->rotation & 1; 5948d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 5958d546610cba3698c62af537d97e38a7368362f1aLajos Molnar /* align crop window with display coordinates */ 5968d546610cba3698c62af537d97e38a7368362f1aLajos Molnar if (swap) 5978d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.xy[1] -= (crop.wh[1] = -crop.wh[1]); 5988d546610cba3698c62af537d97e38a7368362f1aLajos Molnar if (cfg->rotation & 2) 5998d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.xy[!swap] -= (crop.wh[!swap] = -crop.wh[!swap]); 6008d546610cba3698c62af537d97e38a7368362f1aLajos Molnar if ((!cfg->mirror) ^ !(cfg->rotation & 2)) 6018d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.xy[swap] -= (crop.wh[swap] = -crop.wh[swap]); 6028d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 6038d546610cba3698c62af537d97e38a7368362f1aLajos Molnar for (c = 0; c < 2; c++) { 6048d546610cba3698c62af537d97e38a7368362f1aLajos Molnar /* see if complete buffer is outside the vis or it is 6058d546610cba3698c62af537d97e38a7368362f1aLajos Molnar fully cropped or scaled to 0 */ 6068d546610cba3698c62af537d97e38a7368362f1aLajos Molnar if (win.wh[c] <= 0 || vis.rb[c] <= vis.lt[c] || 6078d546610cba3698c62af537d97e38a7368362f1aLajos Molnar win.xy[c] + win.wh[c] <= vis.lt[c] || 6088d546610cba3698c62af537d97e38a7368362f1aLajos Molnar win.xy[c] >= vis.rb[c] || 6098d546610cba3698c62af537d97e38a7368362f1aLajos Molnar !crop.wh[c ^ swap]) 6108d546610cba3698c62af537d97e38a7368362f1aLajos Molnar return -ENOENT; 6118d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 6128d546610cba3698c62af537d97e38a7368362f1aLajos Molnar /* crop left/top */ 6138d546610cba3698c62af537d97e38a7368362f1aLajos Molnar if (win.xy[c] < vis.lt[c]) { 6148d546610cba3698c62af537d97e38a7368362f1aLajos Molnar /* correction term */ 6158d546610cba3698c62af537d97e38a7368362f1aLajos Molnar int a = (vis.lt[c] - win.xy[c]) * crop.wh[c ^ swap] / win.wh[c]; 6168d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.xy[c ^ swap] += a; 6178d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.wh[c ^ swap] -= a; 6188d546610cba3698c62af537d97e38a7368362f1aLajos Molnar win.wh[c] -= vis.lt[c] - win.xy[c]; 6198d546610cba3698c62af537d97e38a7368362f1aLajos Molnar win.xy[c] = vis.lt[c]; 6208d546610cba3698c62af537d97e38a7368362f1aLajos Molnar } 6218d546610cba3698c62af537d97e38a7368362f1aLajos Molnar /* crop right/bottom */ 6228d546610cba3698c62af537d97e38a7368362f1aLajos Molnar if (win.xy[c] + win.wh[c] > vis.rb[c]) { 6238d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.wh[c ^ swap] = crop.wh[c ^ swap] * (vis.rb[c] - win.xy[c]) / win.wh[c]; 6248d546610cba3698c62af537d97e38a7368362f1aLajos Molnar win.wh[c] = vis.rb[c] - win.xy[c]; 6258d546610cba3698c62af537d97e38a7368362f1aLajos Molnar } 6268d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 6278d546610cba3698c62af537d97e38a7368362f1aLajos Molnar if (!crop.wh[c ^ swap] || !win.wh[c]) 6288d546610cba3698c62af537d97e38a7368362f1aLajos Molnar return -ENOENT; 6298d546610cba3698c62af537d97e38a7368362f1aLajos Molnar } 6308d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 6318d546610cba3698c62af537d97e38a7368362f1aLajos Molnar /* realign crop window to buffer coordinates */ 6328d546610cba3698c62af537d97e38a7368362f1aLajos Molnar if (cfg->rotation & 2) 6338d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.xy[!swap] -= (crop.wh[!swap] = -crop.wh[!swap]); 6348d546610cba3698c62af537d97e38a7368362f1aLajos Molnar if ((!cfg->mirror) ^ !(cfg->rotation & 2)) 6358d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.xy[swap] -= (crop.wh[swap] = -crop.wh[swap]); 6368d546610cba3698c62af537d97e38a7368362f1aLajos Molnar if (swap) 6378d546610cba3698c62af537d97e38a7368362f1aLajos Molnar crop.xy[1] -= (crop.wh[1] = -crop.wh[1]); 6388d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 6398d546610cba3698c62af537d97e38a7368362f1aLajos Molnar cfg->win.x = win.xy[0]; cfg->win.y = win.xy[1]; 6408d546610cba3698c62af537d97e38a7368362f1aLajos Molnar cfg->win.w = win.wh[0]; cfg->win.h = win.wh[1]; 6418d546610cba3698c62af537d97e38a7368362f1aLajos Molnar cfg->crop.x = crop.xy[0]; cfg->crop.y = crop.xy[1]; 6428d546610cba3698c62af537d97e38a7368362f1aLajos Molnar cfg->crop.w = crop.wh[0]; cfg->crop.h = crop.wh[1]; 6438d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 6448d546610cba3698c62af537d97e38a7368362f1aLajos Molnar return 0; 6458d546610cba3698c62af537d97e38a7368362f1aLajos Molnar} 6468d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 6472952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnarstatic void 648ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnaromap4_hwc_adjust_ext_layer(omap4_hwc_ext_t *ext, struct dss2_ovl_info *ovl) 6492952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar{ 6502952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar struct dss2_ovl_cfg *oc = &ovl->cfg; 6512952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar float x, y, w, h; 6522952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 6531b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar /* crop to clone region if mirroring */ 6541b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar if (!ext->current.docking && 6551b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar crop_to_rect(&ovl->cfg, ext->mirror_region) != 0) { 6568d546610cba3698c62af537d97e38a7368362f1aLajos Molnar ovl->cfg.enabled = 0; 6578d546610cba3698c62af537d97e38a7368362f1aLajos Molnar return; 6588d546610cba3698c62af537d97e38a7368362f1aLajos Molnar } 6598d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 6602952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar /* display position */ 661ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar x = ext->m[0][0] * oc->win.x + ext->m[0][1] * oc->win.y + ext->m[0][2]; 662ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar y = ext->m[1][0] * oc->win.x + ext->m[1][1] * oc->win.y + ext->m[1][2]; 663ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar w = ext->m[0][0] * oc->win.w + ext->m[0][1] * oc->win.h; 664ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar h = ext->m[1][0] * oc->win.w + ext->m[1][1] * oc->win.h; 6652952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar oc->win.x = m_round(w > 0 ? x : x + w); 6662952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar oc->win.y = m_round(h > 0 ? y : y + h); 6672952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar oc->win.w = m_round(w > 0 ? w : -w); 6682952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar oc->win.h = m_round(h > 0 ? h : -h); 6692952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 6702952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar /* combining transformations: F^a*R^b*F^i*R^j = F^(a+b)*R^(j+b*(-1)^i), because F*R = R^(-1)*F */ 671ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar oc->rotation += (oc->mirror ? -1 : 1) * ext->current.rotation; 6722952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar oc->rotation &= 3; 673ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar if (ext->current.hflip) 6742952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar oc->mirror = !oc->mirror; 6752952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar} 6762952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar 677d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnarstatic struct dsscomp_dispc_limitations { 678d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar __u8 max_xdecim_2d; 679d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar __u8 max_ydecim_2d; 680d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar __u8 max_xdecim_1d; 681d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar __u8 max_ydecim_1d; 682d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar __u32 fclk; 683d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar __u8 max_downscale; 684d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar __u8 min_width; 685d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar __u16 integer_scale_ratio_limit; 686d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar} limits = { 687d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar .max_xdecim_1d = 16, 688d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar .max_xdecim_2d = 16, 689d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar .max_ydecim_1d = 16, 690d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar .max_ydecim_2d = 2, 691d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar .fclk = 170666666, 692d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar .max_downscale = 4, 693d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar .min_width = 2, 694d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar .integer_scale_ratio_limit = 2048, 695d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar}; 696d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 697e055e4bf77e6c429d7a159e8e853974d9dfc57adLajos Molnarstatic int omap4_hwc_can_scale(__u32 src_w, __u32 src_h, __u32 dst_w, __u32 dst_h, int is_2d, 6984ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar struct dsscomp_display_info *dis, struct dsscomp_dispc_limitations *limits, 6994ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar __u32 pclk) 700d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar{ 701d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar __u32 fclk = limits->fclk / 1000; 702d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 703d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar /* ERRATAs */ 704d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar /* cannot render 1-width layers on DSI video mode panels - we just disallow all 1-width LCD layers */ 705d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar if (dis->channel != OMAP_DSS_CHANNEL_DIGIT && dst_w < limits->min_width) 706d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar return 0; 707d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 708d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar /* NOTE: no support for checking YUV422 layers that are tricky to scale */ 709d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 710d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar /* max downscale */ 711f4524c063d4cc4afeb19b08966f51b42257d3acdLajos Molnar if (dst_h < src_h / limits->max_downscale / (is_2d ? limits->max_ydecim_2d : limits->max_ydecim_1d)) 712d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar return 0; 713d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 7144ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar /* for manual panels pclk is 0, and there are no pclk based scaling limits */ 7154ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar if (!pclk) 716f4524c063d4cc4afeb19b08966f51b42257d3acdLajos Molnar return (dst_w < src_w / limits->max_downscale / (is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d)); 7174ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar 718d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar /* :HACK: limit horizontal downscale well below theoretical limit as we saw display artifacts */ 719d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar if (dst_w < src_w / 4) 720d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar return 0; 721d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 722d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar /* max horizontal downscale is 4, or the fclk/pixclk */ 723d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar if (fclk > pclk * limits->max_downscale) 724d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar fclk = pclk * limits->max_downscale; 725d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar /* for small parts, we need to use integer fclk/pixclk */ 726d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar if (src_w < limits->integer_scale_ratio_limit) 727d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar fclk = fclk / pclk * pclk; 728e055e4bf77e6c429d7a159e8e853974d9dfc57adLajos Molnar if ((__u32) dst_w < src_w * pclk / fclk / (is_2d ? limits->max_xdecim_2d : limits->max_xdecim_1d)) 729d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar return 0; 730d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 731d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar return 1; 732d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar} 733d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 734d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnarstatic int omap4_hwc_can_scale_layer(omap4_hwc_device_t *hwc_dev, hwc_layer_t *layer, IMG_native_handle_t *handle) 735d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar{ 7362704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar int src_w = WIDTH(layer->sourceCrop); 7372704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar int src_h = HEIGHT(layer->sourceCrop); 7382704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar int dst_w = WIDTH(layer->displayFrame); 7392704d381ccfba0fe96e61cd368507506c3adfacaLajos Molnar int dst_h = HEIGHT(layer->displayFrame); 740d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 741d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar /* account for 90-degree rotation */ 742d4599029522592f46eccf9d57add7ebd7d23fdd1Lajos Molnar if (layer->transform & HWC_TRANSFORM_ROT_90) 743d4599029522592f46eccf9d57add7ebd7d23fdd1Lajos Molnar swap(src_w, src_h); 744d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 7454ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar /* NOTE: layers should be able to be scaled externally since 7464ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar framebuffer is able to be scaled on selected external resolution */ 7475706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar return omap4_hwc_can_scale(src_w, src_h, dst_w, dst_h, is_NV12(handle), &hwc_dev->fb_dis, &limits, 7484ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar hwc_dev->fb_dis.timings.pixel_clock); 749d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar} 750d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 751d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnarstatic int omap4_hwc_is_valid_layer(omap4_hwc_device_t *hwc_dev, 752d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar hwc_layer_t *layer, 753c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev IMG_native_handle_t *handle) 754c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 755c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* Skip layers are handled by SF */ 756c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ((layer->flags & HWC_SKIP_LAYER) || !handle) 757c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return 0; 758c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 759c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (!omap4_hwc_is_valid_format(handle->iFormat)) 760c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return 0; 761c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 762c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* 1D buffers: no transform, must fit in TILER slot */ 7635706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar if (!is_NV12(handle)) { 764c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (layer->transform) 765c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return 0; 76638934f125a600817dded7aeba9639c6a75afe358Lajos Molnar if (mem1d(handle) > MAX_TILER_SLOT) 767c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return 0; 768c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 769d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 770d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar return omap4_hwc_can_scale_layer(hwc_dev, layer, handle); 771c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 772c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 773e14d52936107e390e2464df1e6653efde5409096Lajos Molnarstatic __u32 add_scaling_score(__u32 score, 774e14d52936107e390e2464df1e6653efde5409096Lajos Molnar __u32 xres, __u32 yres, __u32 refresh, 775e14d52936107e390e2464df1e6653efde5409096Lajos Molnar __u32 ext_xres, __u32 ext_yres, 776e14d52936107e390e2464df1e6653efde5409096Lajos Molnar __u32 mode_xres, __u32 mode_yres, __u32 mode_refresh) 777e14d52936107e390e2464df1e6653efde5409096Lajos Molnar{ 778e14d52936107e390e2464df1e6653efde5409096Lajos Molnar __u32 area = xres * yres; 779e14d52936107e390e2464df1e6653efde5409096Lajos Molnar __u32 ext_area = ext_xres * ext_yres; 780e14d52936107e390e2464df1e6653efde5409096Lajos Molnar __u32 mode_area = mode_xres * mode_yres; 781e14d52936107e390e2464df1e6653efde5409096Lajos Molnar 782e14d52936107e390e2464df1e6653efde5409096Lajos Molnar /* prefer to upscale (1% tolerance) [0..1] (insert after 1st bit) */ 783e14d52936107e390e2464df1e6653efde5409096Lajos Molnar int upscale = (ext_xres >= xres * 99 / 100 && ext_yres >= yres * 99 / 100); 784e14d52936107e390e2464df1e6653efde5409096Lajos Molnar score = (((score & ~1) | upscale) << 1) | (score & 1); 785e14d52936107e390e2464df1e6653efde5409096Lajos Molnar 786e14d52936107e390e2464df1e6653efde5409096Lajos Molnar /* pick minimum scaling [0..16] */ 787e14d52936107e390e2464df1e6653efde5409096Lajos Molnar if (ext_area > area) 788e14d52936107e390e2464df1e6653efde5409096Lajos Molnar score = (score << 5) | (16 * area / ext_area); 789e14d52936107e390e2464df1e6653efde5409096Lajos Molnar else 790e14d52936107e390e2464df1e6653efde5409096Lajos Molnar score = (score << 5) | (16 * ext_area / area); 791e14d52936107e390e2464df1e6653efde5409096Lajos Molnar 792e14d52936107e390e2464df1e6653efde5409096Lajos Molnar /* pick smallest leftover area [0..16] */ 793e14d52936107e390e2464df1e6653efde5409096Lajos Molnar score = (score << 5) | ((16 * ext_area + (mode_area >> 1)) / mode_area); 794e14d52936107e390e2464df1e6653efde5409096Lajos Molnar 795e14d52936107e390e2464df1e6653efde5409096Lajos Molnar /* adjust mode refresh rate */ 796e14d52936107e390e2464df1e6653efde5409096Lajos Molnar mode_refresh += mode_refresh % 6 == 5; 797e14d52936107e390e2464df1e6653efde5409096Lajos Molnar 798e14d52936107e390e2464df1e6653efde5409096Lajos Molnar /* prefer same or higher frame rate */ 799e14d52936107e390e2464df1e6653efde5409096Lajos Molnar upscale = (mode_refresh >= refresh); 800e14d52936107e390e2464df1e6653efde5409096Lajos Molnar score = (score << 1) | upscale; 801e14d52936107e390e2464df1e6653efde5409096Lajos Molnar 802e14d52936107e390e2464df1e6653efde5409096Lajos Molnar /* pick closest frame rate */ 803e14d52936107e390e2464df1e6653efde5409096Lajos Molnar if (mode_refresh > refresh) 804e14d52936107e390e2464df1e6653efde5409096Lajos Molnar score = (score << 8) | (240 * refresh / mode_refresh); 805e14d52936107e390e2464df1e6653efde5409096Lajos Molnar else 806e14d52936107e390e2464df1e6653efde5409096Lajos Molnar score = (score << 8) | (240 * mode_refresh / refresh); 807e14d52936107e390e2464df1e6653efde5409096Lajos Molnar 808e14d52936107e390e2464df1e6653efde5409096Lajos Molnar return score; 809e14d52936107e390e2464df1e6653efde5409096Lajos Molnar} 810e14d52936107e390e2464df1e6653efde5409096Lajos Molnar 81104c7041e0dc1e9c7d2c4e1be1e78a092de993c27Lajos Molnarstatic int omap4_hwc_set_best_hdmi_mode(omap4_hwc_device_t *hwc_dev, __u32 xres, __u32 yres, 8121b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar float xpy) 813bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar{ 814bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar struct _qdis { 815bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar struct dsscomp_display_info dis; 816bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar struct dsscomp_videomode modedb[16]; 817bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar } d = { .dis = { .ix = 1 } }; 818ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar omap4_hwc_ext_t *ext = &hwc_dev->ext; 819bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 820bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar d.dis.modedb_len = sizeof(d.modedb) / sizeof(*d.modedb); 821cb64c2be21ad9550b1f5d2b4a8361e997b9be757Lajos Molnar int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &d); 822bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar if (ret) 823bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar return ret; 824bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 8256c12df17d9a51d20ca799ca22ffee6818d438c94Lajos Molnar if (d.dis.timings.x_res * d.dis.timings.y_res == 0 || 8266c12df17d9a51d20ca799ca22ffee6818d438c94Lajos Molnar xres * yres == 0) 8276c12df17d9a51d20ca799ca22ffee6818d438c94Lajos Molnar return -EINVAL; 8286c12df17d9a51d20ca799ca22ffee6818d438c94Lajos Molnar 829bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar __u32 i, best = ~0, best_score = 0; 830ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->width = d.dis.width_in_mm; 831ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->height = d.dis.height_in_mm; 832ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->xres = d.dis.timings.x_res; 833ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->yres = d.dis.timings.y_res; 8343837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 8353837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar /* use VGA external resolution as default */ 8363837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (!ext->xres || !ext->yres) { 8373837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar ext->xres = 640; 8383837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar ext->yres = 480; 8393837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar } 8403837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 841bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar __u32 ext_fb_xres, ext_fb_yres; 842bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar for (i = 0; i < d.dis.modedb_len; i++) { 843bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar __u32 score = 0; 844e14d52936107e390e2464df1e6653efde5409096Lajos Molnar __u32 mode_xres = d.modedb[i].xres; 845e14d52936107e390e2464df1e6653efde5409096Lajos Molnar __u32 mode_yres = d.modedb[i].yres; 846bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar __u32 ext_width = d.dis.width_in_mm; 847bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar __u32 ext_height = d.dis.height_in_mm; 848bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 849bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar if (d.modedb[i].flag & FB_FLAG_RATIO_4_3) { 850bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar ext_width = 4; 851bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar ext_height = 3; 852bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar } else if (d.modedb[i].flag & FB_FLAG_RATIO_16_9) { 853bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar ext_width = 16; 854bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar ext_height = 9; 855bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar } 856bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 857e14d52936107e390e2464df1e6653efde5409096Lajos Molnar if (!mode_xres || !mode_yres) 8586c12df17d9a51d20ca799ca22ffee6818d438c94Lajos Molnar continue; 8596c12df17d9a51d20ca799ca22ffee6818d438c94Lajos Molnar 860e14d52936107e390e2464df1e6653efde5409096Lajos Molnar get_max_dimensions(xres, yres, xpy, mode_xres, mode_yres, 861bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar ext_width, ext_height, &ext_fb_xres, &ext_fb_yres); 862bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 863f4524c063d4cc4afeb19b08966f51b42257d3acdLajos Molnar /* we need to ensure that even TILER2D buffers can be scaled */ 8644ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar if (!d.modedb[i].pixclock || 8650f28098bbd8976f5a182604226da293747ac824bLajos Molnar d.modedb[i].vmode || 8664ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar !omap4_hwc_can_scale(xres, yres, ext_fb_xres, ext_fb_yres, 867ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 1, &d.dis, &limits, 8684ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar 1000000000 / d.modedb[i].pixclock)) 869bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar continue; 870bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 871bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar /* prefer CEA modes */ 872bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar if (d.modedb[i].flag & (FB_FLAG_RATIO_4_3 | FB_FLAG_RATIO_16_9)) 8734e635e537afaa9f1416fa5bdbfd1b03afd8b7e6aLajos Molnar score = 1; 874bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 8754e635e537afaa9f1416fa5bdbfd1b03afd8b7e6aLajos Molnar /* prefer the same mode as we use for mirroring to avoid mode change */ 876e14d52936107e390e2464df1e6653efde5409096Lajos Molnar score = (score << 1) | (i == ~ext->mirror_mode && ext->avoid_mode_change); 877bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 878e14d52936107e390e2464df1e6653efde5409096Lajos Molnar score = add_scaling_score(score, xres, yres, 60, ext_fb_xres, ext_fb_yres, 879e14d52936107e390e2464df1e6653efde5409096Lajos Molnar mode_xres, mode_yres, d.modedb[i].refresh ? : 1); 880bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 881e14d52936107e390e2464df1e6653efde5409096Lajos Molnar LOGD("#%d: %dx%d %dHz", i, mode_xres, mode_yres, d.modedb[i].refresh); 882bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar if (debug) 883e14d52936107e390e2464df1e6653efde5409096Lajos Molnar LOGD(" score=0x%x adj.res=%dx%d", score, ext_fb_xres, ext_fb_yres); 884bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar if (best_score < score) { 885ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->width = ext_width; 886ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->height = ext_height; 887e14d52936107e390e2464df1e6653efde5409096Lajos Molnar ext->xres = mode_xres; 888e14d52936107e390e2464df1e6653efde5409096Lajos Molnar ext->yres = mode_yres; 889bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar best = i; 890bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar best_score = score; 891bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar } 892bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar } 893bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar if (~best) { 894bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar struct dsscomp_setup_display_data sdis = { .ix = 1, }; 895bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar sdis.mode = d.dis.modedb[best]; 896bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar LOGD("picking #%d", best); 8974cb51e55fa79a592d50d94c0700660e42c988a0bLajos Molnar /* only reconfigure on change */ 8984cb51e55fa79a592d50d94c0700660e42c988a0bLajos Molnar if (ext->last_mode != ~best) 899cb64c2be21ad9550b1f5d2b4a8361e997b9be757Lajos Molnar ioctl(hwc_dev->dsscomp_fd, DSSCIOC_SETUP_DISPLAY, &sdis); 9004cb51e55fa79a592d50d94c0700660e42c988a0bLajos Molnar ext->last_mode = ~best; 901bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar } else { 902bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar __u32 ext_width = d.dis.width_in_mm; 903bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar __u32 ext_height = d.dis.height_in_mm; 904bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar __u32 ext_fb_xres, ext_fb_yres; 905bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 9061b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar get_max_dimensions(xres, yres, xpy, d.dis.timings.x_res, d.dis.timings.y_res, 907bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar ext_width, ext_height, &ext_fb_xres, &ext_fb_yres); 9084ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar if (!d.dis.timings.pixel_clock || 9090f28098bbd8976f5a182604226da293747ac824bLajos Molnar d.dis.mgr.interlaced || 9104ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar !omap4_hwc_can_scale(xres, yres, ext_fb_xres, ext_fb_yres, 911ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 1, &d.dis, &limits, 9124ceb627d195b2efb8cfa3612f38cee211436a7a2Lajos Molnar d.dis.timings.pixel_clock)) { 913734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar LOGW("DSS scaler cannot support HDMI cloning"); 914bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar return -1; 915bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar } 916bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar } 917ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->last_xres_used = xres; 918ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->last_yres_used = yres; 9191b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar ext->last_xpy = xpy; 920bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar if (d.dis.channel == OMAP_DSS_CHANNEL_DIGIT) 921ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->on_tv = 1; 922bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar return 0; 923bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar} 924bd43f27d21c976df59645759598e530ba1a8e01eLajos Molnar 92578fce72baff38f488a0117591d4241d278a48b1bLajos Molnarstruct counts { 92678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar unsigned int possible_overlay_layers; 92778fce72baff38f488a0117591d4241d278a48b1bLajos Molnar unsigned int composited_layers; 92878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar unsigned int scaled_layers; 92978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar unsigned int RGB; 93078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar unsigned int BGR; 93178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar unsigned int NV12; 932834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar unsigned int dockable; 93344a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar unsigned int protected; 934b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar 93578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar unsigned int max_hw_overlays; 93678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar unsigned int max_scaling_overlays; 93738934f125a600817dded7aeba9639c6a75afe358Lajos Molnar unsigned int mem; 93878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar}; 93978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 94044a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnarstatic void gather_layer_statistics(omap4_hwc_device_t *hwc_dev, struct counts *num, hwc_layer_list_t *list) 94144a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar{ 94244a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar unsigned int i; 94344a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 94444a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar /* Figure out how many layers we can support via DSS */ 94544a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar for (i = 0; list && i < list->numHwLayers; i++) { 94644a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar hwc_layer_t *layer = &list->hwLayers[i]; 94744a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 94844a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 94944a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar layer->compositionType = HWC_FRAMEBUFFER; 95044a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 95144a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar if (omap4_hwc_is_valid_layer(hwc_dev, layer, handle)) { 95244a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num->possible_overlay_layers++; 95344a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 95444a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar /* NV12 layers can only be rendered on scaling overlays */ 95544a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar if (scaled(layer) || is_NV12(handle)) 95644a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num->scaled_layers++; 95744a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 95844a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar if (is_BGR(handle)) 95944a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num->BGR++; 96044a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar else if (is_RGB(handle)) 96144a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num->RGB++; 96244a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar else if (is_NV12(handle)) 96344a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num->NV12++; 96444a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 96544a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar if (dockable(layer)) 96644a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num->dockable++; 96744a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 96844a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar if (is_protected(layer)) 96944a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num->protected++; 97044a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 97144a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num->mem += mem1d(handle); 97244a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar } 97344a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar } 97444a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar} 97544a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 97644a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnarstatic void decide_supported_cloning(omap4_hwc_device_t *hwc_dev, struct counts *num) 97778fce72baff38f488a0117591d4241d278a48b1bLajos Molnar{ 978ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar omap4_hwc_ext_t *ext = &hwc_dev->ext; 97978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar int nonscaling_ovls = NUM_NONSCALING_OVERLAYS; 98078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar num->max_hw_overlays = MAX_HW_OVERLAYS; 98178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 98278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* 98378fce72baff38f488a0117591d4241d278a48b1bLajos Molnar * We cannot atomically switch overlays from one display to another. First, they 98478fce72baff38f488a0117591d4241d278a48b1bLajos Molnar * have to be disabled, and the disabling has to take effect on the current display. 98578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar * We keep track of the available number of overlays here. 98678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar */ 987ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar if (ext->dock.enabled && !(ext->mirror.enabled && !num->dockable)) { 98878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* some overlays may already be used by the external display, so we account for this */ 98978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 99078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* reserve just a video pipeline for HDMI if docking */ 991834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar hwc_dev->ext_ovls = num->dockable ? 1 : 0; 99278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar num->max_hw_overlays -= max(hwc_dev->ext_ovls, hwc_dev->last_ext_ovls); 9931b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar 9941b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar /* use mirroring transform if we are auto-switching to docking mode while mirroring*/ 9951b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar if (ext->mirror.enabled) { 9961b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar ext->current = ext->mirror; 9971b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar ext->current.docking = 1; 9981b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar } else { 9991b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar ext->current = ext->dock; 10001b24d08333d1f847e6211aaa1b81f5792aca2704Lajos Molnar } 1001ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar } else if (ext->mirror.enabled) { 100278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* 100378fce72baff38f488a0117591d4241d278a48b1bLajos Molnar * otherwise, manage just from half the pipelines. NOTE: there is 100478fce72baff38f488a0117591d4241d278a48b1bLajos Molnar * no danger of having used too many overlays for external display here. 100578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar */ 100678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar num->max_hw_overlays >>= 1; 100778fce72baff38f488a0117591d4241d278a48b1bLajos Molnar nonscaling_ovls >>= 1; 100878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar hwc_dev->ext_ovls = MAX_HW_OVERLAYS - num->max_hw_overlays; 1009ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->current = ext->mirror; 101078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar } else { 101178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar num->max_hw_overlays -= hwc_dev->last_ext_ovls; 101278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar hwc_dev->ext_ovls = 0; 1013ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->current.enabled = 0; 101478fce72baff38f488a0117591d4241d278a48b1bLajos Molnar } 101578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 101678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* 101778fce72baff38f488a0117591d4241d278a48b1bLajos Molnar * :TRICKY: We may not have enough overlays on the external display. We "reserve" them 101878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar * here to figure out if mirroring is supported, but may not do mirroring for the first 101978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar * frame while the overlays required for it are cleared. 102078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar */ 1021bd0fe036293115c9f9b182ed2a911bdd557ea491Lajos Molnar hwc_dev->ext_ovls_wanted = hwc_dev->ext_ovls; 102278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar hwc_dev->ext_ovls = min(MAX_HW_OVERLAYS - hwc_dev->last_int_ovls, hwc_dev->ext_ovls); 102378fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 1024ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar /* if mirroring, we are limited by both internal and external overlays. However, 1025ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext_ovls is always <= MAX_HW_OVERLAYS / 2 <= max_hw_overlays */ 1026ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar if (hwc_dev->ext_ovls && ext->current.enabled && !ext->current.docking) 1027b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar num->max_hw_overlays = hwc_dev->ext_ovls; 102878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 102978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar num->max_scaling_overlays = num->max_hw_overlays - nonscaling_ovls; 103044a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar} 103178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 103244a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnarstatic int can_dss_render_all(omap4_hwc_device_t *hwc_dev, struct counts *num) 103344a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar{ 103444a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar omap4_hwc_ext_t *ext = &hwc_dev->ext; 103544a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar int on_tv = ext->on_tv && ext->current.enabled; 103644a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar int tform = ext->current.enabled && (ext->current.rotation || ext->current.hflip); 1037ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 10384b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar return !hwc_dev->force_sgx && 10394b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar /* must have at least one layer if using composition bypass to get sync object */ 104078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar num->possible_overlay_layers && 104178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar num->possible_overlay_layers <= num->max_hw_overlays && 104278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar num->possible_overlay_layers == num->composited_layers && 104378fce72baff38f488a0117591d4241d278a48b1bLajos Molnar num->scaled_layers <= num->max_scaling_overlays && 10444af5978e0677b13118611721f265e2dbaba849ffLajos Molnar num->NV12 <= num->max_scaling_overlays && 104538934f125a600817dded7aeba9639c6a75afe358Lajos Molnar /* fits into TILER slot */ 104638934f125a600817dded7aeba9639c6a75afe358Lajos Molnar num->mem <= MAX_TILER_SLOT && 104778fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* we cannot clone non-NV12 transformed layers */ 104878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar (!tform || num->NV12 == num->possible_overlay_layers) && 104978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* HDMI cannot display BGR */ 1050ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar (num->BGR == 0 || (num->RGB == 0 && !on_tv) || !hwc_dev->flags_rgb_order); 105178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar} 105278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 105378fce72baff38f488a0117591d4241d278a48b1bLajos Molnarstatic inline int can_dss_render_layer(omap4_hwc_device_t *hwc_dev, 105478fce72baff38f488a0117591d4241d278a48b1bLajos Molnar hwc_layer_t *layer) 105578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar{ 105678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 105778fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 105844a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar omap4_hwc_ext_t *ext = &hwc_dev->ext; 105944a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar int on_tv = ext->on_tv && ext->current.enabled; 106044a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar int tform = ext->current.enabled && (ext->current.rotation || ext->current.hflip); 106178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 1062d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar return omap4_hwc_is_valid_layer(hwc_dev, layer, handle) && 10632952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar /* cannot rotate non-NV12 layers on external display */ 10645706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar (!tform || is_NV12(handle)) && 106578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* skip non-NV12 layers if also using SGX (if nv12_only flag is set) */ 10665706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar (!hwc_dev->flags_nv12_only || (!hwc_dev->use_sgx || is_NV12(handle))) && 106778fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* make sure RGB ordering is consistent (if rgb_order flag is set) */ 10685706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar (!(hwc_dev->swap_rb ? is_RGB(handle) : is_BGR(handle)) || 106978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar !hwc_dev->flags_rgb_order) && 107078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* TV can only render RGB */ 10715706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar !(on_tv && is_BGR(handle)); 107278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar} 107378fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 1074834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnarstatic inline int display_area(struct dss2_ovl_info *o) 1075834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar{ 1076834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar return o->cfg.win.w * o->cfg.win.h; 1077834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar} 1078834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar 10793837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnarstatic int clone_layer(omap4_hwc_device_t *hwc_dev, int ix) { 10803837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 10813837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar omap4_hwc_ext_t *ext = &hwc_dev->ext; 10823837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar int ext_ovl_ix = dsscomp->num_ovls - hwc_dev->post2_layers; 10833837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar struct dss2_ovl_info *o = &dsscomp->ovls[dsscomp->num_ovls]; 10843837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 10853837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (dsscomp->num_ovls >= MAX_HW_OVERLAYS) { 10863837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar LOGE("**** cannot clone layer #%d. using all %d overlays.", ix, dsscomp->num_ovls); 10873837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar return -EBUSY; 10883837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar } 10893837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 10903837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar memcpy(o, dsscomp->ovls + ix, sizeof(*o)); 10913837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 10923837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar /* reserve overlays at end for other display */ 10933837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar o->cfg.ix = MAX_HW_OVERLAYS - 1 - ext_ovl_ix; 10943837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar o->cfg.mgr_ix = 1; 10953837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar o->ba = ix; 10963837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 10973837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar /* use distinct z values (to simplify z-order checking) */ 10983837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar o->cfg.zorder += hwc_dev->post2_layers; 10993837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 11003837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar omap4_hwc_adjust_ext_layer(&hwc_dev->ext, o); 11013837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar dsscomp->num_ovls++; 11023837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar return 0; 11033837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar} 11043837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 11053837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnarstatic int clone_external_layer(omap4_hwc_device_t *hwc_dev, int ix) { 11063837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 11073837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar omap4_hwc_ext_t *ext = &hwc_dev->ext; 11083837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 11093837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar /* mirror only 1 external layer */ 11103837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar struct dss2_ovl_info *o = &dsscomp->ovls[ix]; 11113837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 11123837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar /* full screen video after transformation */ 11133837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar __u32 xres = o->cfg.crop.w, yres = o->cfg.crop.h; 11143837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if ((ext->current.rotation + o->cfg.rotation) & 1) 11153837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar swap(xres, yres); 11163837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar float xpy = ext->lcd_xpy * o->cfg.win.w / o->cfg.win.h; 11173837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (o->cfg.rotation & 1) 11183837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar xpy = o->cfg.crop.h / xpy / o->cfg.crop.w; 11193837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar else 11203837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar xpy = o->cfg.crop.h * xpy / o->cfg.crop.w; 11213837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (ext->current.rotation & 1) 11223837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar xpy = 1. / xpy; 11233837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 11243837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar /* adjust hdmi mode based on resolution */ 11253837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (xres != ext->last_xres_used || 11263837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar yres != ext->last_yres_used || 11273837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar xpy < ext->last_xpy * (1.f - ASPECT_RATIO_TOLERANCE) || 11283837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar xpy * (1.f - ASPECT_RATIO_TOLERANCE) > ext->last_xpy) { 11293837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar LOGD("set up HDMI for %d*%d\n", xres, yres); 11303837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, xpy)) { 11313837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar ext->current.enabled = 0; 11323837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar return -ENODEV; 11333837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar } 11343837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar } 11353837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 11363837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar struct hwc_rect region = { 11373837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar .left = o->cfg.win.x, .top = o->cfg.win.y, 11383837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar .right = o->cfg.win.x + o->cfg.win.w, 11393837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar .bottom = o->cfg.win.y + o->cfg.win.h 11403837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar }; 11413837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar set_ext_matrix(&hwc_dev->ext, region); 11423837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 11433837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar return clone_layer(hwc_dev, ix); 11443837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar} 11453837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 11463837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnarstatic int setup_mirroring(omap4_hwc_device_t *hwc_dev) 11473837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar{ 11483837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar omap4_hwc_ext_t *ext = &hwc_dev->ext; 11493837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 11503837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar __u32 xres = WIDTH(ext->mirror_region); 11513837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar __u32 yres = HEIGHT(ext->mirror_region); 11523837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (ext->current.rotation & 1) 11533837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar swap(xres, yres); 11543837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (omap4_hwc_set_best_hdmi_mode(hwc_dev, xres, yres, ext->lcd_xpy)) 11553837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar return -ENODEV; 11563837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar set_ext_matrix(ext, ext->mirror_region); 11573837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar return 0; 11583837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar} 11593837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 1160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic int omap4_hwc_prepare(struct hwc_composer_device *dev, hwc_layer_list_t* list) 1161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 1162c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev; 1163c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 11640b62b7ca3c6430caaebb2d3815642b2ff80f527aLajos Molnar struct counts num = { .composited_layers = list ? list->numHwLayers : 0 }; 11653837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar unsigned int i, ix; 1166c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 11672125fa148686edfa389121f946377aedaa3d9483Lajos Molnar pthread_mutex_lock(&hwc_dev->lock); 1168c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev memset(dsscomp, 0x0, sizeof(*dsscomp)); 1169c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dsscomp->sync_id = sync_id++; 1170c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 117144a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar gather_layer_statistics(hwc_dev, &num, list); 1172834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar 117344a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar decide_supported_cloning(hwc_dev, &num); 1174c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 11754b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar /* Disable the forced SGX rendering if there is only one layer */ 11764b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar if (hwc_dev->force_sgx && num.composited_layers <= 1) 11774b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar hwc_dev->force_sgx = 0; 11784b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar 117978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* phase 3 logic */ 11804b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar if (can_dss_render_all(hwc_dev, &num)) { 1181c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* All layers can be handled by the DSS -- don't use SGX for composition */ 1182c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->use_sgx = 0; 118378fce72baff38f488a0117591d4241d278a48b1bLajos Molnar hwc_dev->swap_rb = num.BGR != 0; 1184c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } else { 1185c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* Use SGX for composition plus first 3 layers that are DSS renderable */ 1186c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->use_sgx = 1; 11875706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar hwc_dev->swap_rb = is_BGR_format(hwc_dev->fb_dev->base.format); 1188c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1189c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1190c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* setup pipes */ 1191c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dsscomp->num_ovls = hwc_dev->use_sgx; 1192c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int z = 0; 1193a51ba32b3ed323a74235d28a6cb0f31e51d8e514Lajos Molnar int fb_z = -1; 1194c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int scaled_gfx = 0; 1195834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar int ix_docking = -1; 1196c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1197c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* set up if DSS layers */ 119838934f125a600817dded7aeba9639c6a75afe358Lajos Molnar unsigned int mem_used = 0; 1199b81fb68ce4c70170ebc9e41f9fe4540cc05685d5Lajos Molnar hwc_dev->ovls_blending = 0; 1200a1be32cc5c3978f9bac62c3b40a257bba2315861Lajos Molnar for (i = 0; list && i < list->numHwLayers; i++) { 1201c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_layer_t *layer = &list->hwLayers[i]; 1202c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev IMG_native_handle_t *handle = (IMG_native_handle_t *)layer->handle; 1203c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 12044b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar if (dsscomp->num_ovls < num.max_hw_overlays && 1205a1be32cc5c3978f9bac62c3b40a257bba2315861Lajos Molnar can_dss_render_layer(hwc_dev, layer) && 12064b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar (!hwc_dev->force_sgx || 12074b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar /* render protected and dockable layers via DSS */ 12085706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar is_protected(layer) || 12094b267e18b9e98b788d2b1bf2f1268ed25e5b726dLajos Molnar (hwc_dev->ext.current.docking && hwc_dev->ext.current.enabled && dockable(layer))) && 121038934f125a600817dded7aeba9639c6a75afe358Lajos Molnar mem_used + mem1d(handle) < MAX_TILER_SLOT && 1211c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* can't have a transparent overlay in the middle of the framebuffer stack */ 12125706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar !(is_BLENDED(layer) && fb_z >= 0)) { 12135706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar 1214c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* render via DSS overlay */ 121538934f125a600817dded7aeba9639c6a75afe358Lajos Molnar mem_used += mem1d(handle); 1216c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev layer->compositionType = HWC_OVERLAY; 1217b81fb68ce4c70170ebc9e41f9fe4540cc05685d5Lajos Molnar 1218b81fb68ce4c70170ebc9e41f9fe4540cc05685d5Lajos Molnar /* clear FB above all opaque layers if rendering via SGX */ 1219b81fb68ce4c70170ebc9e41f9fe4540cc05685d5Lajos Molnar if (hwc_dev->use_sgx && !is_BLENDED(layer)) 1220b81fb68ce4c70170ebc9e41f9fe4540cc05685d5Lajos Molnar layer->hints |= HWC_HINT_CLEAR_FB; 1221b81fb68ce4c70170ebc9e41f9fe4540cc05685d5Lajos Molnar /* see if any of the (non-backmost) overlays are doing blending */ 1222b81fb68ce4c70170ebc9e41f9fe4540cc05685d5Lajos Molnar else if (is_BLENDED(layer) && i > 0) 1223b81fb68ce4c70170ebc9e41f9fe4540cc05685d5Lajos Molnar hwc_dev->ovls_blending = 1; 1224b81fb68ce4c70170ebc9e41f9fe4540cc05685d5Lajos Molnar 1225e055e4bf77e6c429d7a159e8e853974d9dfc57adLajos Molnar hwc_dev->buffers[dsscomp->num_ovls] = layer->handle; 1226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev omap4_hwc_setup_layer(hwc_dev, 1228c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev &dsscomp->ovls[dsscomp->num_ovls], 1229f1e357b2cf26fa5a50789061e068e4f0bd4ea772Mathias Agopian layer, 1230c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev z, 1231c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev handle->iFormat, 1232c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev handle->iWidth, 1233c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev handle->iHeight); 1234d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 1235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dsscomp->ovls[dsscomp->num_ovls].cfg.ix = dsscomp->num_ovls; 1236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* just marking dss layers */ 1237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dsscomp->ovls[dsscomp->num_ovls].address = (void *) (dsscomp->num_ovls * 4096 + 0xA0000000); 1238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dsscomp->ovls[dsscomp->num_ovls].uv = (__u32) hwc_dev->buffers[dsscomp->num_ovls]; 1239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* ensure GFX layer is never scaled */ 1241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (dsscomp->num_ovls == 0) { 12425706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar scaled_gfx = scaled(layer) || is_NV12(handle); 12435706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar } else if (scaled_gfx && !scaled(layer) && !is_NV12(handle)) { 1244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* swap GFX layer with this one */ 1245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dsscomp->ovls[dsscomp->num_ovls].cfg.ix = 0; 1246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dsscomp->ovls[0].cfg.ix = dsscomp->num_ovls; 1247c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev scaled_gfx = 0; 1248c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1249c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1250834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar /* remember largest dockable layer */ 1251834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar if (dockable(layer) && 1252834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar (ix_docking < 0 || 125300d8485d3d319633f410e52cab1562fe165af1e3Lajos Molnar display_area(&dsscomp->ovls[dsscomp->num_ovls]) > display_area(&dsscomp->ovls[ix_docking]))) 1254834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar ix_docking = dsscomp->num_ovls; 125578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 1256c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dsscomp->num_ovls++; 1257c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev z++; 1258c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } else if (hwc_dev->use_sgx) { 1259c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (fb_z < 0) { 1260c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* NOTE: we are not handling transparent cutout for now */ 1261a51ba32b3ed323a74235d28a6cb0f31e51d8e514Lajos Molnar fb_z = z; 1262c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev z++; 1263c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } else { 1264c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* move fb z-order up (by lowering dss layers) */ 1265a51ba32b3ed323a74235d28a6cb0f31e51d8e514Lajos Molnar while (fb_z < z - 1) 1266a51ba32b3ed323a74235d28a6cb0f31e51d8e514Lajos Molnar dsscomp->ovls[1 + fb_z++].cfg.zorder--; 1267c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1268c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1269c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1270c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1271c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* if scaling GFX (e.g. only 1 scaled surface) use a VID pipe */ 1272c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (scaled_gfx) 12734af5978e0677b13118611721f265e2dbaba849ffLajos Molnar dsscomp->ovls[0].cfg.ix = dsscomp->num_ovls; 1274c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1275c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (hwc_dev->use_sgx) { 1276b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar /* assign a z-layer for fb */ 1277b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar if (fb_z < 0) 1278b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar LOGE("**** should have assigned z-layer for fb"); 1279b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar 1280c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->buffers[0] = NULL; 1281c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev omap4_hwc_setup_layer_base(&dsscomp->ovls[0].cfg, fb_z, 1282c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->fb_dev->base.format, 12835706ba0da054830e63b82b195ec32a97c390bd2cLajos Molnar 1, /* FB is always premultiplied */ 1284c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->fb_dev->base.width, 1285c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->fb_dev->base.height); 1286c35f8ef2dc4bf1606f2b27f750057b12e51cb99aErik Gilling dsscomp->ovls[0].cfg.pre_mult_alpha = 1; 1287c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1288c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 128978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar /* mirror layers */ 129078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar hwc_dev->post2_layers = dsscomp->num_ovls; 12913837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar 12923837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar omap4_hwc_ext_t *ext = &hwc_dev->ext; 12933837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (ext->current.enabled && hwc_dev->ext_ovls) { 12943837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (ext->current.docking && ix_docking >= 0) { 12953837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (clone_external_layer(hwc_dev, ix_docking) == 0) 12963837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar z++; 12973837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar } else if (!ext->current.docking) { 12983837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar int res = 0; 1299834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar 1300834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar /* reset mode if we are coming from docking */ 13013837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (ext->last.docking) 13023837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar res = setup_mirroring(hwc_dev); 1303c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 13043837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar /* mirror all layers */ 13053837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar for (ix = 0; res == 0 && ix < hwc_dev->post2_layers; ix++) { 13063837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (clone_layer(hwc_dev, ix)) 13073837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar break; 13083837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar z++; 13092952fd7510718abf21a5fc6d683fd1b4a6025171Lajos Molnar } 131078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar } 131178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar } 13123837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar ext->last = ext->current; 131378fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 131478fce72baff38f488a0117591d4241d278a48b1bLajos Molnar if (z != dsscomp->num_ovls || dsscomp->num_ovls > MAX_HW_OVERLAYS) 131578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar LOGE("**** used %d z-layers for %d overlays\n", z, dsscomp->num_ovls); 131678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 131744a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar /* verify all z-orders and overlay indices are distinct */ 131844a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar for (i = z = ix = 0; i < dsscomp->num_ovls; i++) { 131944a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar struct dss2_ovl_cfg *c = &dsscomp->ovls[i].cfg; 132044a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 132144a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar if (z & (1 << c->zorder)) 132244a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar LOGE("**** used z-order #%d multiple times", c->zorder); 132344a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar if (ix & (1 << c->ix)) 132444a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar LOGE("**** used ovl index #%d multiple times", c->ix); 132544a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar z |= 1 << c->zorder; 132644a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar ix |= 1 << c->ix; 132744a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar } 132878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar dsscomp->mode = DSSCOMP_SETUP_DISPLAY; 132978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar dsscomp->mgrs[0].ix = 0; 133078fce72baff38f488a0117591d4241d278a48b1bLajos Molnar dsscomp->mgrs[0].alpha_blending = 1; 133178fce72baff38f488a0117591d4241d278a48b1bLajos Molnar dsscomp->mgrs[0].swap_rb = hwc_dev->swap_rb; 133278fce72baff38f488a0117591d4241d278a48b1bLajos Molnar dsscomp->num_mgrs = 1; 133378fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 13343837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (ext->current.enabled || hwc_dev->last_ext_ovls) { 133578fce72baff38f488a0117591d4241d278a48b1bLajos Molnar dsscomp->mgrs[1] = dsscomp->mgrs[0]; 133678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar dsscomp->mgrs[1].ix = 1; 133778fce72baff38f488a0117591d4241d278a48b1bLajos Molnar dsscomp->num_mgrs++; 133878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar hwc_dev->ext_ovls = dsscomp->num_ovls - hwc_dev->post2_layers; 133978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar } 134044a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 134144a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar if (debug) { 134244a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar LOGD("prepare (%d) - %s (comp=%d, poss=%d/%d scaled, RGB=%d,BGR=%d,NV12=%d) (ext=%s%s%ddeg%s %dex/%dmx (last %dex,%din)\n", 134344a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar dsscomp->sync_id, 134444a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar hwc_dev->use_sgx ? "SGX+OVL" : "all-OVL", 134544a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num.composited_layers, 134644a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num.possible_overlay_layers, num.scaled_layers, 134744a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar num.RGB, num.BGR, num.NV12, 134844a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar ext->on_tv ? "tv+" : "", 134944a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar ext->current.enabled ? ext->current.docking ? "dock+" : "mirror+" : "OFF+", 135044a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar ext->current.rotation * 90, 135144a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar ext->current.hflip ? "+hflip" : "", 135244a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar hwc_dev->ext_ovls, num.max_hw_overlays, hwc_dev->last_ext_ovls, hwc_dev->last_int_ovls); 135344a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar } 135444a0023db5b752a81fb0bd3badd4cca1a1c4edc0Lajos Molnar 13552125fa148686edfa389121f946377aedaa3d9483Lajos Molnar pthread_mutex_unlock(&hwc_dev->lock); 1356c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return 0; 1357c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 1358c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 135924a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnarstatic void omap4_hwc_reset_screen(omap4_hwc_device_t *hwc_dev) 136024a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar{ 136124a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar static int first_set = 1; 136224a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar int ret; 136324a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar 136424a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar if (first_set) { 136524a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar first_set = 0; 136624a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar struct dsscomp_setup_dispc_data d = { 1367b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar .num_mgrs = 1, 136824a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar }; 136924a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar /* remove bootloader image from the screen as blank/unblank does not change the composition */ 1370cb64c2be21ad9550b1f5d2b4a8361e997b9be757Lajos Molnar ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_SETUP_DISPC, &d); 137124a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar if (ret) 137224a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar LOGW("failed to remove bootloader image"); 137324a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar 137424a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar /* blank and unblank fd to make sure display is properly programmed on boot. 137524a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar * This is needed because the bootloader can not be trusted. 137624a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar */ 137724a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar ret = ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_POWERDOWN); 137824a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar if (ret) 137924a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar LOGW("failed to blank display"); 138024a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar 138124a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar ret = ioctl(hwc_dev->fb_fd, FBIOBLANK, FB_BLANK_UNBLANK); 138224a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar if (ret) 138324a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar LOGW("failed to blank display"); 138424a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar } 138524a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar} 138624a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar 1387c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic int omap4_hwc_set(struct hwc_composer_device *dev, hwc_display_t dpy, 1388c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_surface_t sur, hwc_layer_list_t* list) 1389c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 1390c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev; 1391c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 1392ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar int err = 0; 1393bd0fe036293115c9f9b182ed2a911bdd557ea491Lajos Molnar int invalidate; 1394c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 13952125fa148686edfa389121f946377aedaa3d9483Lajos Molnar pthread_mutex_lock(&hwc_dev->lock); 139624a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar 139724a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar omap4_hwc_reset_screen(hwc_dev); 139824a18d2f746877f2abd63e95b4be9c54dac4472eLajos Molnar 1399bd0fe036293115c9f9b182ed2a911bdd557ea491Lajos Molnar invalidate = hwc_dev->ext_ovls_wanted && !hwc_dev->ext_ovls; 1400bd0fe036293115c9f9b182ed2a911bdd557ea491Lajos Molnar 1401734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar if (debug) 1402734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_set_info(hwc_dev, list); 1403c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1404ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar if (dpy && sur) { 1405e37a11c21bcac1fbcac995cd34884eac37492b95Mathias Agopian // list can be NULL which means hwc is temporarily disabled. 1406e37a11c21bcac1fbcac995cd34884eac37492b95Mathias Agopian // however, if dpy and sur are null it means we're turning the 1407e37a11c21bcac1fbcac995cd34884eac37492b95Mathias Agopian // screen off. no shall not call eglSwapBuffers() in that case. 1408ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar 1409ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar if (hwc_dev->use_sgx) { 1410ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar if (!eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur)) { 1411ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar LOGE("eglSwapBuffers error"); 1412ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar err = HWC_EGL_ERROR; 1413ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar goto err_out; 1414ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar } 1415c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1416c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1417ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar //dump_dsscomp(dsscomp); 1418c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 141902150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian // signal the event thread that a post has happened 142002150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian write(hwc_dev->pipe_fds[1], "s", 1); 142102150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian if (hwc_dev->force_sgx > 0) 142202150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian hwc_dev->force_sgx--; 142302150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian 1424ee0725d529a6adced20dd0182f9fd470607ce495Lajos Molnar err = hwc_dev->fb_dev->Post2((framebuffer_device_t *)hwc_dev->fb_dev, 1425c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->buffers, 142678fce72baff38f488a0117591d4241d278a48b1bLajos Molnar hwc_dev->post2_layers, 1427c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dsscomp, sizeof(*dsscomp)); 142878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar 14297f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar if (!hwc_dev->use_sgx) { 14307f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar __u32 crt = 0; 14317f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar int err2 = ioctl(hwc_dev->fb_fd, FBIO_WAITFORVSYNC, &crt); 14327f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar if (err2) { 14337f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar LOGE("failed to wait for vsync (%d)", errno); 14347f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar err = err ? : -errno; 14357f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar } 14367f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar } 14377f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar } 143878fce72baff38f488a0117591d4241d278a48b1bLajos Molnar hwc_dev->last_ext_ovls = hwc_dev->ext_ovls; 143978fce72baff38f488a0117591d4241d278a48b1bLajos Molnar hwc_dev->last_int_ovls = hwc_dev->post2_layers; 1440c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (err) 1441c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOGE("Post2 error"); 1442c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1443c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malcheverr_out: 14442125fa148686edfa389121f946377aedaa3d9483Lajos Molnar pthread_mutex_unlock(&hwc_dev->lock); 1445bd0fe036293115c9f9b182ed2a911bdd557ea491Lajos Molnar 1446bd0fe036293115c9f9b182ed2a911bdd557ea491Lajos Molnar if (invalidate && hwc_dev->procs && hwc_dev->procs->invalidate) 1447bd0fe036293115c9f9b182ed2a911bdd557ea491Lajos Molnar hwc_dev->procs->invalidate(hwc_dev->procs); 1448bd0fe036293115c9f9b182ed2a911bdd557ea491Lajos Molnar 1449c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return err; 1450c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 1451c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1452c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic void omap4_hwc_dump(struct hwc_composer_device *dev, char *buff, int buff_len) 1453c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 1454c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *)dev; 1455c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev struct dsscomp_setup_dispc_data *dsscomp = &hwc_dev->dsscomp_data; 1456734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar struct dump_buf log = { 1457734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar .buf = buff, 1458734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar .buf_len = buff_len, 1459734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar }; 1460c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int i; 1461c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1462734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, "omap4_hwc %d:\n", dsscomp->num_ovls); 1463734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " idle timeout: %dms\n", hwc_dev->idle); 1464c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1465c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev for (i = 0; i < dsscomp->num_ovls; i++) { 1466c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev struct dss2_ovl_cfg *cfg = &dsscomp->ovls[i].cfg; 1467c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1468734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " layer %d:\n", i); 1469734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " enabled: %s\n", 1470c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev cfg->enabled ? "true" : "false"); 1471734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " buff: %p %dx%d stride: %d\n", 1472f1e357b2cf26fa5a50789061e068e4f0bd4ea772Mathias Agopian hwc_dev->buffers[i], cfg->width, cfg->height, cfg->stride); 1473734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " src: (%d,%d) %dx%d\n", 1474c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev cfg->crop.x, cfg->crop.y, cfg->crop.w, cfg->crop.h); 1475734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " dst: (%d,%d) %dx%d\n", 1476c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev cfg->win.x, cfg->win.y, cfg->win.w, cfg->win.h); 1477734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " ix: %d\n", cfg->ix); 1478734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar dump_printf(&log, " zorder: %d\n\n", cfg->zorder); 1479c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1480c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 1481c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1482c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1483c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic int omap4_hwc_device_close(hw_device_t* device) 1484c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 1485c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) device;; 1486c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 14872125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (hwc_dev) { 14882125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (hwc_dev->dsscomp_fd >= 0) 14892125fa148686edfa389121f946377aedaa3d9483Lajos Molnar close(hwc_dev->dsscomp_fd); 14902125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (hwc_dev->hdmi_fb_fd >= 0) 14912125fa148686edfa389121f946377aedaa3d9483Lajos Molnar close(hwc_dev->hdmi_fb_fd); 14927f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar if (hwc_dev->fb_fd >= 0) 14937f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar close(hwc_dev->fb_fd); 14942125fa148686edfa389121f946377aedaa3d9483Lajos Molnar /* pthread will get killed when parent process exits */ 14952125fa148686edfa389121f946377aedaa3d9483Lajos Molnar pthread_mutex_destroy(&hwc_dev->lock); 1496c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev free(hwc_dev); 14972125fa148686edfa389121f946377aedaa3d9483Lajos Molnar } 1498c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1499c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return 0; 1500c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 1501c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1502c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic int omap4_hwc_open_fb_hal(IMG_framebuffer_device_public_t **fb_dev) 1503c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 1504e055e4bf77e6c429d7a159e8e853974d9dfc57adLajos Molnar const struct hw_module_t *psModule; 1505c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev IMG_gralloc_module_public_t *psGrallocModule; 1506c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int err; 1507c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1508e055e4bf77e6c429d7a159e8e853974d9dfc57adLajos Molnar err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &psModule); 1509e055e4bf77e6c429d7a159e8e853974d9dfc57adLajos Molnar psGrallocModule = (IMG_gralloc_module_public_t *) psModule; 1510e055e4bf77e6c429d7a159e8e853974d9dfc57adLajos Molnar 1511c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(err) 1512c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev goto err_out; 1513c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1514b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar if (strcmp(psGrallocModule->base.common.author, "Imagination Technologies")) { 1515c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev err = -EINVAL; 1516c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev goto err_out; 1517c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1518c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1519c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *fb_dev = psGrallocModule->psFrameBufferDevice; 1520c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1521c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return 0; 1522c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1523c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malcheverr_out: 1524c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOGE("Composer HAL failed to load compatible Graphics HAL"); 1525c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return err; 1526c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 1527c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 15282b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnarstatic void handle_hotplug(omap4_hwc_device_t *hwc_dev) 15292125fa148686edfa389121f946377aedaa3d9483Lajos Molnar{ 1530ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar omap4_hwc_ext_t *ext = &hwc_dev->ext; 15312b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar __u8 state = ext->hdmi_state; 1532ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 15332125fa148686edfa389121f946377aedaa3d9483Lajos Molnar pthread_mutex_lock(&hwc_dev->lock); 1534ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->dock.enabled = ext->mirror.enabled = 0; 15352125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (state) { 153641bb71e35280943ebe07ecfe1cf9e015918164e8Lajos Molnar /* check whether we can clone and/or dock */ 153741bb71e35280943ebe07ecfe1cf9e015918164e8Lajos Molnar char value[PROPERTY_VALUE_MAX]; 1538aa9be8a14744cae50a8f99e6cbb44be0d0c2c938Erik Gilling property_get("persist.hwc.docking.enabled", value, "1"); 1539ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->dock.enabled = atoi(value) > 0; 1540aa9be8a14744cae50a8f99e6cbb44be0d0c2c938Erik Gilling property_get("persist.hwc.mirroring.enabled", value, "1"); 1541ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->mirror.enabled = atoi(value) > 0; 15424e635e537afaa9f1416fa5bdbfd1b03afd8b7e6aLajos Molnar property_get("persist.hwc.avoid_mode_change", value, "1"); 15434e635e537afaa9f1416fa5bdbfd1b03afd8b7e6aLajos Molnar ext->avoid_mode_change = atoi(value) > 0; 154441bb71e35280943ebe07ecfe1cf9e015918164e8Lajos Molnar 154541bb71e35280943ebe07ecfe1cf9e015918164e8Lajos Molnar /* get cloning transformation */ 1546aa9be8a14744cae50a8f99e6cbb44be0d0c2c938Erik Gilling property_get("persist.hwc.docking.transform", value, "0"); 1547ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->dock.rotation = atoi(value) & EXT_ROTATION; 1548ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->dock.hflip = (atoi(value) & EXT_HFLIP) > 0; 1549ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->dock.docking = 1; 1550aa9be8a14744cae50a8f99e6cbb44be0d0c2c938Erik Gilling property_get("persist.hwc.mirroring.transform", value, hwc_dev->fb_dev->base.height > hwc_dev->fb_dev->base.width ? "3" : "0"); 1551ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->mirror.rotation = atoi(value) & EXT_ROTATION; 1552ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->mirror.hflip = (atoi(value) & EXT_HFLIP) > 0; 1553ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->mirror.docking = 0; 1554ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 15552b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar if (ext->force_dock) { 15562b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar /* restrict to docking with no transform */ 15572b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar ext->mirror.enabled = 0; 15582b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar ext->dock.rotation = 0; 15592b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar ext->dock.hflip = 0; 15602b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar } 15612b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar 1562ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar /* select best mode for mirroring */ 1563ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar if (ext->mirror.enabled) { 15643837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar ext->current = ext->mirror; 15653797fa989f5fee97caea2bbadf433a5a9ac03d8dLajos Molnar ext->mirror_mode = 0; 15663837de4ff6b7562965758dd2a7af5550af1bd869Lajos Molnar if (setup_mirroring(hwc_dev) == 0) { 15674e635e537afaa9f1416fa5bdbfd1b03afd8b7e6aLajos Molnar ext->mirror_mode = ext->last_mode; 1568ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ioctl(hwc_dev->hdmi_fb_fd, FBIOBLANK, FB_BLANK_UNBLANK); 15694e635e537afaa9f1416fa5bdbfd1b03afd8b7e6aLajos Molnar } else 1570ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->mirror.enabled = 0; 1571ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar } 15724cb51e55fa79a592d50d94c0700660e42c988a0bLajos Molnar } else { 15734cb51e55fa79a592d50d94c0700660e42c988a0bLajos Molnar ext->last_mode = 0; 15742125fa148686edfa389121f946377aedaa3d9483Lajos Molnar } 15752b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar LOGI("external display changed (state=%d, mirror={%s tform=%ddeg%s}, dock={%s tform=%ddeg%s%s}, tv=%d", state, 1576ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->mirror.enabled ? "enabled" : "disabled", 1577ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->mirror.rotation * 90, 1578ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->mirror.hflip ? "+hflip" : "", 1579ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->dock.enabled ? "enabled" : "disabled", 1580ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->dock.rotation * 90, 1581ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->dock.hflip ? "+hflip" : "", 15822b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar ext->force_dock ? " forced" : "", 1583ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar ext->on_tv); 1584ffa0d75e7fa7142eb289ccc9c7dc04e4cedb7c46Lajos Molnar 1585bd0fe036293115c9f9b182ed2a911bdd557ea491Lajos Molnar pthread_mutex_unlock(&hwc_dev->lock); 1586834b8ba01376239a2f286a3766c14bdeeb166498Lajos Molnar 1587bd0fe036293115c9f9b182ed2a911bdd557ea491Lajos Molnar if (hwc_dev->procs && hwc_dev->procs->invalidate) 15882125fa148686edfa389121f946377aedaa3d9483Lajos Molnar hwc_dev->procs->invalidate(hwc_dev->procs); 15892125fa148686edfa389121f946377aedaa3d9483Lajos Molnar} 15902125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 15912125fa148686edfa389121f946377aedaa3d9483Lajos Molnarstatic void handle_uevents(omap4_hwc_device_t *hwc_dev, const char *s) 15922125fa148686edfa389121f946377aedaa3d9483Lajos Molnar{ 15932b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar int dock = !strcmp(s, "change@/devices/virtual/switch/dock"); 15942b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar if (!dock && 15952b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar strcmp(s, "change@/devices/virtual/switch/hdmi")) 15962125fa148686edfa389121f946377aedaa3d9483Lajos Molnar return; 15972125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 15982125fa148686edfa389121f946377aedaa3d9483Lajos Molnar s += strlen(s) + 1; 15992125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 16002125fa148686edfa389121f946377aedaa3d9483Lajos Molnar while(*s) { 16012125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (!strncmp(s, "SWITCH_STATE=", strlen("SWITCH_STATE="))) { 16022125fa148686edfa389121f946377aedaa3d9483Lajos Molnar int state = atoi(s + strlen("SWITCH_STATE=")); 16032b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar if (dock) 16042b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar hwc_dev->ext.force_dock = state == 1; 16052b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar else 16062b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar hwc_dev->ext.hdmi_state = state == 1; 16072b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar handle_hotplug(hwc_dev); 16082125fa148686edfa389121f946377aedaa3d9483Lajos Molnar } 16092125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 16102125fa148686edfa389121f946377aedaa3d9483Lajos Molnar s += strlen(s) + 1; 16112125fa148686edfa389121f946377aedaa3d9483Lajos Molnar } 16122125fa148686edfa389121f946377aedaa3d9483Lajos Molnar} 16132125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 16142125fa148686edfa389121f946377aedaa3d9483Lajos Molnarstatic void *omap4_hwc_hdmi_thread(void *data) 16152125fa148686edfa389121f946377aedaa3d9483Lajos Molnar{ 16162125fa148686edfa389121f946377aedaa3d9483Lajos Molnar omap4_hwc_device_t *hwc_dev = data; 16172125fa148686edfa389121f946377aedaa3d9483Lajos Molnar static char uevent_desc[4096]; 161802150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian struct pollfd fds[2]; 1619b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis int invalidate = 0; 162002150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian int timeout; 162102150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian int err; 162202150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian 16232125fa148686edfa389121f946377aedaa3d9483Lajos Molnar uevent_init(); 16242125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 162502150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian fds[0].fd = uevent_get_fd(); 162602150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian fds[0].events = POLLIN; 162702150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian fds[1].fd = hwc_dev->pipe_fds[0]; 162802150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian fds[1].events = POLLIN; 162902150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian 163002150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian timeout = hwc_dev->idle ? hwc_dev->idle : -1; 163102150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian 16322125fa148686edfa389121f946377aedaa3d9483Lajos Molnar memset(uevent_desc, 0, sizeof(uevent_desc)); 16332125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 16342125fa148686edfa389121f946377aedaa3d9483Lajos Molnar do { 163502150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian err = poll(fds, hwc_dev->idle ? 2 : 1, timeout); 163602150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian 163702150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian if (err == 0) { 163802150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian if (hwc_dev->idle) { 1639b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis if (hwc_dev->procs && hwc_dev->procs->invalidate) { 1640b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis pthread_mutex_lock(&hwc_dev->lock); 1641b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis invalidate = !hwc_dev->force_sgx && hwc_dev->ovls_blending; 1642b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis if (invalidate) { 1643b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis hwc_dev->force_sgx = 2; 1644b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis } 1645b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis pthread_mutex_unlock(&hwc_dev->lock); 1646b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis 1647b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis if (invalidate) { 1648b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis hwc_dev->procs->invalidate(hwc_dev->procs); 1649b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis timeout = -1; 1650b1c5d8ef7fc96ef49a1eaef0d81ff35dc4d2e4e7Jamie Gennis } 165102150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian } 165202150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian 165302150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian continue; 165402150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian } 165502150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian } 165602150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian 165702150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian if (err == -1) { 165802150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian if (errno != EINTR) 165902150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian LOGE("event error: %m"); 166002150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian continue; 166102150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian } 166202150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian 166302150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian if (hwc_dev->idle && fds[1].revents & POLLIN) { 166402150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian char c; 166502150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian read(hwc_dev->pipe_fds[0], &c, 1); 166602150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian if (!hwc_dev->force_sgx) 166702150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian timeout = hwc_dev->idle ? hwc_dev->idle : -1; 166802150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian } 166902150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian 167002150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian if (fds[0].revents & POLLIN) { 167102150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian /* keep last 2 zeroes to ensure double 0 termination */ 167202150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2); 167302150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian handle_uevents(hwc_dev, uevent_desc); 167402150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian } 16752125fa148686edfa389121f946377aedaa3d9483Lajos Molnar } while (1); 16762125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 16772125fa148686edfa389121f946377aedaa3d9483Lajos Molnar return NULL; 16782125fa148686edfa389121f946377aedaa3d9483Lajos Molnar} 16792125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 16802125fa148686edfa389121f946377aedaa3d9483Lajos Molnarstatic void omap4_hwc_registerProcs(struct hwc_composer_device* dev, 16812125fa148686edfa389121f946377aedaa3d9483Lajos Molnar hwc_procs_t const* procs) 16822125fa148686edfa389121f946377aedaa3d9483Lajos Molnar{ 1683b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar omap4_hwc_device_t *hwc_dev = (omap4_hwc_device_t *) dev; 16842125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 1685b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar hwc_dev->procs = (typeof(hwc_dev->procs)) procs; 16862125fa148686edfa389121f946377aedaa3d9483Lajos Molnar} 16872125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 1688c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic int omap4_hwc_device_open(const hw_module_t* module, const char* name, 1689c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hw_device_t** device) 1690c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 1691c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev omap4_hwc_module_t *hwc_mod = (omap4_hwc_module_t *)module; 1692c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev omap4_hwc_device_t *hwc_dev; 16932125fa148686edfa389121f946377aedaa3d9483Lajos Molnar int err = 0; 1694c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1695c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (strcmp(name, HWC_HARDWARE_COMPOSER)) { 1696c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 1697c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1698c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1699c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (!hwc_mod->fb_dev) { 1700c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev err = omap4_hwc_open_fb_hal(&hwc_mod->fb_dev); 1701c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (err) 1702c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return err; 1703c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1704c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (!hwc_mod->fb_dev) { 1705c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOGE("Framebuffer HAL not opened before HWC"); 1706c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EFAULT; 1707c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1708c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_mod->fb_dev->bBypassPost = 1; 1709c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1710c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1711c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev = (omap4_hwc_device_t *)malloc(sizeof(*hwc_dev)); 1712c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (hwc_dev == NULL) 1713c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -ENOMEM; 1714c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1715c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev memset(hwc_dev, 0, sizeof(*hwc_dev)); 1716c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1717c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->base.common.tag = HARDWARE_DEVICE_TAG; 1718c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->base.common.version = HWC_API_VERSION; 1719c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->base.common.module = (hw_module_t *)module; 1720c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->base.common.close = omap4_hwc_device_close; 1721c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->base.prepare = omap4_hwc_prepare; 1722c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->base.set = omap4_hwc_set; 1723c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->base.dump = omap4_hwc_dump; 17242125fa148686edfa389121f946377aedaa3d9483Lajos Molnar hwc_dev->base.registerProcs = omap4_hwc_registerProcs; 1725c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->fb_dev = hwc_mod->fb_dev; 1726c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *device = &hwc_dev->base.common; 1727c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 17282125fa148686edfa389121f946377aedaa3d9483Lajos Molnar hwc_dev->dsscomp_fd = open("/dev/dsscomp", O_RDWR); 17297f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar if (hwc_dev->dsscomp_fd < 0) { 17307f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar LOGE("failed to open dsscomp (%d)", errno); 17317f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar err = -errno; 17327f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar goto done; 17337f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar } 17342125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 17352125fa148686edfa389121f946377aedaa3d9483Lajos Molnar hwc_dev->hdmi_fb_fd = open("/dev/graphics/fb1", O_RDWR); 17367f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar if (hwc_dev->hdmi_fb_fd < 0) { 17377f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar LOGE("failed to open hdmi fb (%d)", errno); 17387f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar err = -errno; 17397f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar goto done; 17407f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar } 17417f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar 17427f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar hwc_dev->fb_fd = open("/dev/graphics/fb0", O_RDWR); 17437f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar if (hwc_dev->fb_fd < 0) { 17447f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar LOGE("failed to open fb (%d)", errno); 17457f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar err = -errno; 17467f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar goto done; 17477f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar } 17482125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 1749c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->buffers = malloc(sizeof(buffer_handle_t) * MAX_HW_OVERLAYS); 1750c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (!hwc_dev->buffers) { 17512125fa148686edfa389121f946377aedaa3d9483Lajos Molnar err = -ENOMEM; 17522125fa148686edfa389121f946377aedaa3d9483Lajos Molnar goto done; 17532125fa148686edfa389121f946377aedaa3d9483Lajos Molnar } 17542125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 1755cb64c2be21ad9550b1f5d2b4a8361e997b9be757Lajos Molnar int ret = ioctl(hwc_dev->dsscomp_fd, DSSCIOC_QUERY_DISPLAY, &hwc_dev->fb_dis); 1756d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar if (ret) { 1757d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar LOGE("failed to get display info (%d): %m", errno); 1758d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar err = -errno; 1759d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar goto done; 1760d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar } 17613797fa989f5fee97caea2bbadf433a5a9ac03d8dLajos Molnar hwc_dev->ext.lcd_xpy = (float) hwc_dev->fb_dis.width_in_mm / hwc_dev->fb_dis.timings.x_res / 17623797fa989f5fee97caea2bbadf433a5a9ac03d8dLajos Molnar hwc_dev->fb_dis.height_in_mm * hwc_dev->fb_dis.timings.y_res; 1763d98920b36b52ca1784742cbd053c631ae62ca1c4Lajos Molnar 176402150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian if (pipe(hwc_dev->pipe_fds) == -1) { 176502150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian LOGE("failed to event pipe (%d): %m", errno); 176602150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian err = -errno; 176702150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian goto done; 176802150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian } 176902150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian 17702125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (pthread_mutex_init(&hwc_dev->lock, NULL)) { 1771b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar LOGE("failed to create mutex (%d): %m", errno); 1772b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar err = -errno; 1773b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar goto done; 17742125fa148686edfa389121f946377aedaa3d9483Lajos Molnar } 17752125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (pthread_create(&hwc_dev->hdmi_thread, NULL, omap4_hwc_hdmi_thread, hwc_dev)) 17762125fa148686edfa389121f946377aedaa3d9483Lajos Molnar { 1777b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar LOGE("failed to create HDMI listening thread (%d): %m", errno); 1778b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar err = -errno; 1779b79b42d125e488c0bcf101edfd3b1f30bafae53eLajos Molnar goto done; 1780c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 1781c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1782c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* get debug properties */ 1783c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1784c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* see if hwc is enabled at all */ 1785c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev char value[PROPERTY_VALUE_MAX]; 1786c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev property_get("debug.hwc.rgb_order", value, "1"); 1787c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->flags_rgb_order = atoi(value); 1788c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev property_get("debug.hwc.nv12_only", value, "0"); 1789c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->flags_nv12_only = atoi(value); 179002150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian property_get("debug.hwc.idle", value, "250"); 179102150d77cba303ea6c532fa740910fbab5e3e1ccMathias Agopian hwc_dev->idle = atoi(value); 17922125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 17938d546610cba3698c62af537d97e38a7368362f1aLajos Molnar /* get the board specific clone properties */ 17948d546610cba3698c62af537d97e38a7368362f1aLajos Molnar /* 0:0:1280:720 */ 1795dd922b9387f70e24b3462afe1bdc86ceb7541d4bLajos Molnar if (property_get("persist.hwc.mirroring.region", value, "") <= 0 || 17968d546610cba3698c62af537d97e38a7368362f1aLajos Molnar sscanf(value, "%d:%d:%d:%d", 17978d546610cba3698c62af537d97e38a7368362f1aLajos Molnar &hwc_dev->ext.mirror_region.left, &hwc_dev->ext.mirror_region.top, 17988d546610cba3698c62af537d97e38a7368362f1aLajos Molnar &hwc_dev->ext.mirror_region.right, &hwc_dev->ext.mirror_region.bottom) != 4 || 17998d546610cba3698c62af537d97e38a7368362f1aLajos Molnar hwc_dev->ext.mirror_region.left >= hwc_dev->ext.mirror_region.right || 18008d546610cba3698c62af537d97e38a7368362f1aLajos Molnar hwc_dev->ext.mirror_region.top >= hwc_dev->ext.mirror_region.bottom) { 18018d546610cba3698c62af537d97e38a7368362f1aLajos Molnar struct hwc_rect fb_region = { .right = hwc_dev->fb_dev->base.width, .bottom = hwc_dev->fb_dev->base.height }; 18028d546610cba3698c62af537d97e38a7368362f1aLajos Molnar hwc_dev->ext.mirror_region = fb_region; 18038d546610cba3698c62af537d97e38a7368362f1aLajos Molnar } 18048d546610cba3698c62af537d97e38a7368362f1aLajos Molnar LOGI("clone region is set to (%d,%d) to (%d,%d)", 18058d546610cba3698c62af537d97e38a7368362f1aLajos Molnar hwc_dev->ext.mirror_region.left, hwc_dev->ext.mirror_region.top, 18068d546610cba3698c62af537d97e38a7368362f1aLajos Molnar hwc_dev->ext.mirror_region.right, hwc_dev->ext.mirror_region.bottom); 18078d546610cba3698c62af537d97e38a7368362f1aLajos Molnar 18082125fa148686edfa389121f946377aedaa3d9483Lajos Molnar /* read switch state */ 18092125fa148686edfa389121f946377aedaa3d9483Lajos Molnar int sw_fd = open("/sys/class/switch/hdmi/state", O_RDONLY); 18102125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (sw_fd >= 0) { 18112125fa148686edfa389121f946377aedaa3d9483Lajos Molnar char value; 18122125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (read(sw_fd, &value, 1) == 1) 18132b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar hwc_dev->ext.hdmi_state = value == '1'; 18142b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar close(sw_fd); 18152b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar } 18162b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar sw_fd = open("/sys/class/switch/dock/state", O_RDONLY); 18172b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar if (sw_fd >= 0) { 18182b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar char value; 18192b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar if (read(sw_fd, &value, 1) == 1) 18202b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar hwc_dev->ext.force_dock = value == '1'; 18212125fa148686edfa389121f946377aedaa3d9483Lajos Molnar close(sw_fd); 18222125fa148686edfa389121f946377aedaa3d9483Lajos Molnar } 18232b86fd0cbeb42123fc20b1f646ee81299e831d16Lajos Molnar handle_hotplug(hwc_dev); 18242125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 1825734de7a7631e5f115ee89c5b2f35c7c484098779Lajos Molnar LOGI("omap4_hwc_device_open(rgb_order=%d nv12_only=%d)", 1826c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev hwc_dev->flags_rgb_order, hwc_dev->flags_nv12_only); 1827c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 18282125fa148686edfa389121f946377aedaa3d9483Lajos Molnardone: 18292125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (err && hwc_dev) { 18302125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (hwc_dev->dsscomp_fd >= 0) 18312125fa148686edfa389121f946377aedaa3d9483Lajos Molnar close(hwc_dev->dsscomp_fd); 18322125fa148686edfa389121f946377aedaa3d9483Lajos Molnar if (hwc_dev->hdmi_fb_fd >= 0) 18332125fa148686edfa389121f946377aedaa3d9483Lajos Molnar close(hwc_dev->hdmi_fb_fd); 18347f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar if (hwc_dev->fb_fd >= 0) 18357f2cbf97908a26e0b463d4fa20040b129216f86eLajos Molnar close(hwc_dev->fb_fd); 18362125fa148686edfa389121f946377aedaa3d9483Lajos Molnar pthread_mutex_destroy(&hwc_dev->lock); 18372125fa148686edfa389121f946377aedaa3d9483Lajos Molnar free(hwc_dev->buffers); 18382125fa148686edfa389121f946377aedaa3d9483Lajos Molnar free(hwc_dev); 18392125fa148686edfa389121f946377aedaa3d9483Lajos Molnar } 18402125fa148686edfa389121f946377aedaa3d9483Lajos Molnar 18412125fa148686edfa389121f946377aedaa3d9483Lajos Molnar return err; 1842c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 1843c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1844c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic struct hw_module_methods_t omap4_hwc_module_methods = { 1845c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev .open = omap4_hwc_device_open, 1846c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}; 1847c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 1848c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevomap4_hwc_module_t HAL_MODULE_INFO_SYM = { 1849c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev .base = { 1850c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev .common = { 1851c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev .tag = HARDWARE_MODULE_TAG, 1852c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev .version_major = 1, 1853c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev .version_minor = 0, 1854c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev .id = HWC_HARDWARE_MODULE_ID, 1855c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev .name = "OMAP 44xx Hardware Composer HAL", 1856c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev .author = "Texas Instruments", 1857c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev .methods = &omap4_hwc_module_methods, 1858c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev }, 1859c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev }, 1860c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}; 1861