1d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* 21c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed* Copyright (c) 2015 - 2016, The Linux Foundation. All rights reserved. 3d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* 4d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* Redistribution and use in source and binary forms, with or without 5d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* modification, are permitted provided that the following conditions are 6d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* met: 7d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* * Redistributions of source code must retain the above copyright 8d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* notice, this list of conditions and the following disclaimer. 9d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* * Redistributions in binary form must reproduce the above 10d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* copyright notice, this list of conditions and the following 11d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* disclaimer in the documentation and/or other materials provided 12d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* with the distribution. 13d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* * Neither the name of The Linux Foundation nor the names of its 14d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* contributors may be used to endorse or promote products derived 15d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* from this software without specific prior written permission. 16d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* 17d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin*/ 29d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 30d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <stdio.h> 31d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <unistd.h> 32d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <string.h> 33d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <pthread.h> 34d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <fcntl.h> 35d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/prctl.h> 36d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/ioctl.h> 37d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/time.h> 38d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/resource.h> 39d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <utils/debug.h> 40d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <utils/sys.h> 41d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <core/display_interface.h> 42d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 43d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <string> 44d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 45d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include "hw_primary.h" 46d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include "hw_color_manager.h" 47d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 48d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define __CLASS__ "HWPrimary" 49d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 50d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinnamespace sdm { 51d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 52d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinusing std::string; 53d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 54d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::Create(HWInterface **intf, HWInfoInterface *hw_info_intf, 55d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin BufferSyncHandler *buffer_sync_handler, 56d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin HWEventHandler *eventhandler) { 57d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DisplayError error = kErrorNone; 58d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin HWPrimary *hw_primary = NULL; 59d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 60d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin hw_primary = new HWPrimary(buffer_sync_handler, hw_info_intf); 61d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin error = hw_primary->Init(eventhandler); 62d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (error != kErrorNone) { 63d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin delete hw_primary; 64d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } else { 65d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *intf = hw_primary; 66d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 67d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 68d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return error; 69d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 70d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 71d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::Destroy(HWInterface *intf) { 72d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin HWPrimary *hw_primary = static_cast<HWPrimary *>(intf); 73d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin hw_primary->Deinit(); 74d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin delete hw_primary; 75d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 76d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 77d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 78d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 79d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinHWPrimary::HWPrimary(BufferSyncHandler *buffer_sync_handler, HWInfoInterface *hw_info_intf) 80d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin : HWDevice(buffer_sync_handler) { 81d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin HWDevice::device_type_ = kDevicePrimary; 82d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin HWDevice::device_name_ = "Primary Display Device"; 83d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin HWDevice::hw_info_intf_ = hw_info_intf; 84d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 85d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 86d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::Init(HWEventHandler *eventhandler) { 87d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DisplayError error = kErrorNone; 88d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char node_path[kMaxStringLength] = { 0 }; 89d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char data[kMaxStringLength] = { 0 }; 90d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin const char *event_name[kNumDisplayEvents] = {"vsync_event", "show_blank_event", "idle_notify", 91d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin "msm_fb_thermal_level"}; 92d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 93d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin error = HWDevice::Init(eventhandler); 94d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (error != kErrorNone) { 95d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin goto CleanupOnError; 96d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 97d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 98d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin error = PopulateDisplayAttributes(); 99d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (error != kErrorNone) { 100d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin goto CleanupOnError; 101d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 102d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 103d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Open nodes for polling 104d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin for (int event = 0; event < kNumDisplayEvents; event++) { 105d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin poll_fds_[event].fd = -1; 106d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 107d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 108d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (!fake_vsync_) { 109d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin for (int event = 0; event < kNumDisplayEvents; event++) { 110d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pollfd &poll_fd = poll_fds_[event]; 111d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 112d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin snprintf(node_path, sizeof(node_path), "%s%d/%s", fb_path_, fb_node_index_, 113d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin event_name[event]); 114d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 115d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin poll_fd.fd = Sys::open_(node_path, O_RDONLY); 116d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (poll_fd.fd < 0) { 117d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGE("open failed for event=%d, error=%s", event, strerror(errno)); 118d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin error = kErrorHardware; 119d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin goto CleanupOnError; 120d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 121d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 122d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Read once on all fds to clear data on all fds. 123d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::pread_(poll_fd.fd, data , kMaxStringLength, 0); 124d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin poll_fd.events = POLLPRI | POLLERR; 125d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 126d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 127d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 128d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Start the Event thread 129d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (pthread_create(&event_thread_, NULL, &DisplayEventThread, this) < 0) { 130d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGE("Failed to start %s, error = %s", event_thread_name_); 131d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin error = kErrorResources; 132d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin goto CleanupOnError; 133d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 134d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 135d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Disable HPD at start if HDMI is external, it will be enabled later when the display powers on 136d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // This helps for framework reboot or adb shell stop/start 137d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin EnableHotPlugDetection(0); 138d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin InitializeConfigs(); 139d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 140d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 141d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 142d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinCleanupOnError: 143d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Close all poll fds 144d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin for (int event = 0; event < kNumDisplayEvents; event++) { 145d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int &fd = poll_fds_[event].fd; 146d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (fd >= 0) { 147d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::close_(fd); 148d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 149d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 150d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 151d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return error; 152d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 153d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 154d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinbool HWPrimary::GetCurrentModeFromSysfs(size_t *curr_x_pixels, size_t *curr_y_pixels) { 155d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin bool ret = false; 156d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin size_t len = kPageSize; 157d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin string mode_path = string(fb_path_) + string("0/mode"); 158d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 159d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin FILE *fd = Sys::fopen_(mode_path.c_str(), "r"); 160d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (fd) { 161d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char *buffer = static_cast<char *>(calloc(len, sizeof(char))); 162d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 163d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (buffer == NULL) { 164d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGW("Failed to allocate memory"); 165d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::fclose_(fd); 166d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return false; 167d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 168d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 169d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (Sys::getline_(&buffer, &len, fd) > 0) { 170d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // String is of form "U:1600x2560p-0". Documentation/fb/modedb.txt in 171d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // kernel has more info on the format. 172d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin size_t xpos = string(buffer).find(':'); 173d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin size_t ypos = string(buffer).find('x'); 174d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 175d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (xpos == string::npos || ypos == string::npos) { 176d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGI("Resolution switch not supported"); 177d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } else { 1781c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed *curr_x_pixels = static_cast<size_t>(atoi(buffer + xpos + 1)); 1791c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed *curr_y_pixels = static_cast<size_t>(atoi(buffer + ypos + 1)); 180d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGI("Current Config: %u x %u", *curr_x_pixels, *curr_y_pixels); 181d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ret = true; 182d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 183d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 184d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 185d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin free(buffer); 186d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::fclose_(fd); 187d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 188d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 189d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return ret; 190d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 191d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 192d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWPrimary::InitializeConfigs() { 193d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin size_t curr_x_pixels = 0; 194d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin size_t curr_y_pixels = 0; 195d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin size_t len = kPageSize; 196d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin string modes_path = string(fb_path_) + string("0/modes"); 197d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 198d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (!GetCurrentModeFromSysfs(&curr_x_pixels, &curr_y_pixels)) { 199d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return; 200d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 201d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 202d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin FILE *fd = Sys::fopen_(modes_path.c_str(), "r"); 203d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (fd) { 204d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char *buffer = static_cast<char *>(calloc(len, sizeof(char))); 205d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 206d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (buffer == NULL) { 207d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGW("Failed to allocate memory"); 208d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::fclose_(fd); 209d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return; 210d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 211d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 212d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin while (Sys::getline_(&buffer, &len, fd) > 0) { 213d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DisplayConfigVariableInfo config; 214d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin size_t xpos = string(buffer).find(':'); 215d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin size_t ypos = string(buffer).find('x'); 216d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 217d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (xpos == string::npos || ypos == string::npos) { 218d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin continue; 219d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 220d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 2211c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed config.x_pixels = UINT32(atoi(buffer + xpos + 1)); 2221c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed config.y_pixels = UINT32(atoi(buffer + ypos + 1)); 223d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGI("Found mode %d x %d", config.x_pixels, config.y_pixels); 224d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_configs_.push_back(config); 225d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_config_strings_.push_back(string(buffer)); 226d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 227d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (curr_x_pixels == config.x_pixels && curr_y_pixels == config.y_pixels) { 2281c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed active_config_index_ = UINT32(display_configs_.size() - 1); 229d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGI("Active config index %u", active_config_index_); 230d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 231d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 232d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 233d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin free(buffer); 234d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::fclose_(fd); 235d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } else { 236d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGI("Unable to process modes"); 237d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 238d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 239d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 240d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::Deinit() { 241d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin exit_threads_ = true; 242d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::pthread_cancel_(event_thread_); 243d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pthread_join(event_thread_, NULL); 244d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 245d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin for (int event = 0; event < kNumDisplayEvents; event++) { 246d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int &fd = poll_fds_[event].fd; 247d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (fd >= 0) { 248d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::close_(fd); 249d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 250d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 251d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 252d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return HWDevice::Deinit(); 253d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 254d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 255d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::GetNumDisplayAttributes(uint32_t *count) { 2561c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed *count = IsResolutionSwitchEnabled() ? UINT32(display_configs_.size()) : 1; 257d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 258d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 259d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 260d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::GetActiveConfig(uint32_t *active_config_index) { 261d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *active_config_index = active_config_index_; 262d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 263d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 264d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 265d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::GetDisplayAttributes(uint32_t index, 266d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin HWDisplayAttributes *display_attributes) { 267d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (!display_attributes) { 268d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorParameters; 269d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 270d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 271d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (IsResolutionSwitchEnabled() && index >= display_configs_.size()) { 272d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorParameters; 273d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 274d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 275d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *display_attributes = display_attributes_; 276d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (IsResolutionSwitchEnabled()) { 277d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Overwrite only the parent portion of object 278d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes->x_pixels = display_configs_.at(index).x_pixels; 279d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes->y_pixels = display_configs_.at(index).y_pixels; 280d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 281d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 282d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 283d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 284d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 285d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::PopulateDisplayAttributes() { 286d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DTRACE_SCOPED(); 287d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 288d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Variable screen info 289d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin STRUCT_VAR(fb_var_screeninfo, var_screeninfo); 290d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 291d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (Sys::ioctl_(device_fd_, FBIOGET_VSCREENINFO, &var_screeninfo) < 0) { 292d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin IOCTL_LOGE(FBIOGET_VSCREENINFO, device_type_); 293d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorHardware; 294d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 295d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 296d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Frame rate 297d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin STRUCT_VAR(msmfb_metadata, meta_data); 298d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin meta_data.op = metadata_op_frame_rate; 299d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (Sys::ioctl_(device_fd_, MSMFB_METADATA_GET, &meta_data) < 0) { 300d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin IOCTL_LOGE(MSMFB_METADATA_GET, device_type_); 301d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorHardware; 302d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 303d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 304d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // If driver doesn't return width/height information, default to 160 dpi 305d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (INT(var_screeninfo.width) <= 0 || INT(var_screeninfo.height) <= 0) { 3061c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed var_screeninfo.width = UINT32(((FLOAT(var_screeninfo.xres) * 25.4f)/160.0f) + 0.5f); 3071c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed var_screeninfo.height = UINT32(((FLOAT(var_screeninfo.yres) * 25.4f)/160.0f) + 0.5f); 308d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 309d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 310d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.x_pixels = var_screeninfo.xres; 311d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.y_pixels = var_screeninfo.yres; 312d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.v_front_porch = var_screeninfo.lower_margin; 313d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.v_back_porch = var_screeninfo.upper_margin; 314d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.v_pulse_width = var_screeninfo.vsync_len; 315d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin uint32_t h_blanking = var_screeninfo.right_margin + var_screeninfo.left_margin + 316d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin var_screeninfo.hsync_len; 317d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.h_total = var_screeninfo.xres + h_blanking; 318d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.x_dpi = 319d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin (FLOAT(var_screeninfo.xres) * 25.4f) / FLOAT(var_screeninfo.width); 320d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.y_dpi = 321d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin (FLOAT(var_screeninfo.yres) * 25.4f) / FLOAT(var_screeninfo.height); 322d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.fps = meta_data.data.panel_frame_rate; 323d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.vsync_period_ns = UINT32(1000000000L / display_attributes_.fps); 324d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.is_device_split = (hw_panel_info_.split_info.left_split || 325d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin (var_screeninfo.xres > hw_resource_.max_mixer_width)) ? true : false; 326d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.split_left = hw_panel_info_.split_info.left_split ? 327d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin hw_panel_info_.split_info.left_split : display_attributes_.x_pixels / 2; 328d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_attributes_.h_total += display_attributes_.is_device_split ? h_blanking : 0; 329d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 330d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 331d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 332d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 333d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::SetDisplayAttributes(uint32_t index) { 334d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DisplayError ret = kErrorNone; 335d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 336d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (!IsResolutionSwitchEnabled()) { 337d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNotSupported; 338d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 339d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 340d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (index >= display_configs_.size()) { 341d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorParameters; 342d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 343d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 344d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin string mode_path = string(fb_path_) + string("0/mode"); 345d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int fd = Sys::open_(mode_path.c_str(), O_WRONLY); 346d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 347d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (fd < 0) { 348d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGE("Opening mode failed"); 349d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNotSupported; 350d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 351d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 352d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ssize_t written = Sys::pwrite_(fd, display_config_strings_.at(index).c_str(), 353d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin display_config_strings_.at(index).length(), 0); 354d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (written > 0) { 355d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGI("Successfully set config %u", index); 356d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin PopulateHWPanelInfo(); 357d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin PopulateDisplayAttributes(); 358d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin active_config_index_ = index; 359d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } else { 360d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGE("Writing config index %u failed with error: %s", index, strerror(errno)); 361d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ret = kErrorParameters; 362d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 363d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 364d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::close_(fd); 365d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 366d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return ret; 367d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 368d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 369d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::SetRefreshRate(uint32_t refresh_rate) { 370d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char node_path[kMaxStringLength] = {0}; 371d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 372d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (refresh_rate == display_attributes_.fps) { 373d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 374d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 375d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 376d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin snprintf(node_path, sizeof(node_path), "%s%d/dynamic_fps", fb_path_, fb_node_index_); 377d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 378d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int fd = Sys::open_(node_path, O_WRONLY); 379d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (fd < 0) { 380d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGE("Failed to open %s with error %s", node_path, strerror(errno)); 381d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorFileDescriptor; 382d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 383d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 384d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char refresh_rate_string[kMaxStringLength]; 385d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin snprintf(refresh_rate_string, sizeof(refresh_rate_string), "%d", refresh_rate); 386d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGI_IF(kTagDriverConfig, "Setting refresh rate = %d", refresh_rate); 387d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ssize_t len = Sys::pwrite_(fd, refresh_rate_string, strlen(refresh_rate_string), 0); 388d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (len < 0) { 389d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGE("Failed to write %d with error %s", refresh_rate, strerror(errno)); 390d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::close_(fd); 391d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorUndefined; 392d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 393d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::close_(fd); 394d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 395d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DisplayError error = PopulateDisplayAttributes(); 396d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (error != kErrorNone) { 397d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return error; 398d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 399d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 400d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 401d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 402d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 403d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::GetConfigIndex(uint32_t mode, uint32_t *index) { 404d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return HWDevice::GetConfigIndex(mode, index); 405d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 406d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 407d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::PowerOff() { 408d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_POWERDOWN) < 0) { 409d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin IOCTL_LOGE(FB_BLANK_POWERDOWN, device_type_); 410d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorHardware; 411d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 412d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 413d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 414d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 415d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 416d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::Doze() { 417d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_NORMAL) < 0) { 418d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin IOCTL_LOGE(FB_BLANK_NORMAL, device_type_); 419d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorHardware; 420d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 421d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 422d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 423d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 424d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 425d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::DozeSuspend() { 426d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (Sys::ioctl_(device_fd_, FBIOBLANK, FB_BLANK_VSYNC_SUSPEND) < 0) { 427d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin IOCTL_LOGE(FB_BLANK_VSYNC_SUSPEND, device_type_); 428d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorHardware; 429d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 430d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 431d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 432d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 433d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 434d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::Validate(HWLayers *hw_layers) { 435d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin HWDevice::ResetDisplayParams(); 436d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 437d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1; 438d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 439d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin LayerRect left_roi = hw_layers->info.left_partial_update; 440d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin LayerRect right_roi = hw_layers->info.right_partial_update; 4411c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed mdp_commit.left_roi.x = UINT32(left_roi.left); 4421c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed mdp_commit.left_roi.y = UINT32(left_roi.top); 4431c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed mdp_commit.left_roi.w = UINT32(left_roi.right - left_roi.left); 4441c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed mdp_commit.left_roi.h = UINT32(left_roi.bottom - left_roi.top); 445d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 446d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // SDM treats ROI as one full coordinate system. 447d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // In case source split is disabled, However, Driver assumes Mixer to operate in 448d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // different co-ordinate system. 449d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (!hw_resource_.is_src_split) { 4501c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed mdp_commit.right_roi.x = UINT32(right_roi.left) - hw_panel_info_.split_info.left_split; 4511c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed mdp_commit.right_roi.y = UINT32(right_roi.top); 4521c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed mdp_commit.right_roi.w = UINT32(right_roi.right - right_roi.left); 4531c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed mdp_commit.right_roi.h = UINT32(right_roi.bottom - right_roi.top); 454d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 455d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 456d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return HWDevice::Validate(hw_layers); 457d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 458d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 459d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid* HWPrimary::DisplayEventThread(void *context) { 460d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (context) { 461d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return reinterpret_cast<HWPrimary *>(context)->DisplayEventThreadHandler(); 462d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 463d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 464d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return NULL; 465d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 466d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 467d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid* HWPrimary::DisplayEventThreadHandler() { 468d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char data[kMaxStringLength] = {0}; 469d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 470d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin prctl(PR_SET_NAME, event_thread_name_, 0, 0, 0); 471d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin setpriority(PRIO_PROCESS, 0, kThreadPriorityUrgent); 472d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 473d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (fake_vsync_) { 474d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin while (!exit_threads_) { 475d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Fake vsync is used only when set explicitly through a property(todo) or when 476d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // the vsync timestamp node cannot be opened at bootup. There is no 477d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // fallback to fake vsync from the true vsync loop, ever, as the 478d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // condition can easily escape detection. 479d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Also, fake vsync is delivered only for the primary display. 480d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin usleep(16666); 481d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin STRUCT_VAR(timeval, time_now); 482d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin gettimeofday(&time_now, NULL); 4831c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed int64_t ts = int64_t(time_now.tv_sec)*1000000000LL +int64_t(time_now.tv_usec)*1000LL; 484d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 485d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Send Vsync event for primary display(0) 486d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin event_handler_->VSync(ts); 487d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 488d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 489d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pthread_exit(0); 490d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 491d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 492d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin typedef void (HWPrimary::*EventHandler)(char*); 493d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin EventHandler event_handler[kNumDisplayEvents] = { &HWPrimary::HandleVSync, 494d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin &HWPrimary::HandleBlank, 495d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin &HWPrimary::HandleIdleTimeout, 496d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin &HWPrimary::HandleThermal }; 497d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 498d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin while (!exit_threads_) { 499d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int error = Sys::poll_(poll_fds_, kNumDisplayEvents, -1); 500d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (error <= 0) { 501d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGW("poll failed. error = %s", strerror(errno)); 502d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin continue; 503d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 504d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 505d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin for (int event = 0; event < kNumDisplayEvents; event++) { 506d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pollfd &poll_fd = poll_fds_[event]; 507d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 508d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (poll_fd.revents & POLLPRI) { 509d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (Sys::pread_(poll_fd.fd, data, kMaxStringLength, 0) > 0) { 510d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin (this->*event_handler[event])(data); 511d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 512d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 513d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 514d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 515d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 516d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin pthread_exit(0); 517d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 518d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return NULL; 519d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 520d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 521d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWPrimary::HandleVSync(char *data) { 522d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int64_t timestamp = 0; 523d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (!strncmp(data, "VSYNC=", strlen("VSYNC="))) { 5241c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed timestamp = strtoll(data + strlen("VSYNC="), NULL, 0); 525d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 526d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin event_handler_->VSync(timestamp); 527d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 528d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 529d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWPrimary::HandleBlank(char *data) { 530d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // TODO(user): Need to send blank Event 531d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 532d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 533d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWPrimary::HandleIdleTimeout(char *data) { 534d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin event_handler_->IdleTimeout(); 535d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 536d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 537d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWPrimary::HandleThermal(char *data) { 538d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int64_t thermal_level = 0; 539d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (!strncmp(data, "thermal_level=", strlen("thermal_level="))) { 5401c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed thermal_level = strtoll(data + strlen("thermal_level="), NULL, 0); 541d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 542d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 543d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGI("Received thermal notification with thermal level = %d", thermal_level); 544d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 545d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin event_handler_->ThermalEvent(thermal_level); 546d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 547d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 548d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinvoid HWPrimary::SetIdleTimeoutMs(uint32_t timeout_ms) { 549d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char node_path[kMaxStringLength] = {0}; 550d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 551d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGI_IF(kTagDriverConfig, "Setting idle timeout to = %d ms", timeout_ms); 552d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 553d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin snprintf(node_path, sizeof(node_path), "%s%d/idle_time", fb_path_, fb_node_index_); 554d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 555d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Open a sysfs node to send the timeout value to driver. 556d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int fd = Sys::open_(node_path, O_WRONLY); 557d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (fd < 0) { 558d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGE("Unable to open %s, node %s", node_path, strerror(errno)); 559d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return; 560d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 561d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 562d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char timeout_string[64]; 563d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin snprintf(timeout_string, sizeof(timeout_string), "%d", timeout_ms); 564d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 565d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Notify driver about the timeout value 566d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ssize_t length = Sys::pwrite_(fd, timeout_string, strlen(timeout_string), 0); 567d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (length <= 0) { 568d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGE("Unable to write into %s, node %s", node_path, strerror(errno)); 569d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 570d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 571d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::close_(fd); 572d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 573d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 574d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::SetVSyncState(bool enable) { 575d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DTRACE_SCOPED(); 576d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 577d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int vsync_on = enable ? 1 : 0; 578d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (Sys::ioctl_(device_fd_, MSMFB_OVERLAY_VSYNC_CTRL, &vsync_on) < 0) { 579d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin IOCTL_LOGE(MSMFB_OVERLAY_VSYNC_CTRL, device_type_); 580d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorHardware; 581d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 582d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 583d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 584d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 585d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 586d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::SetDisplayMode(const HWDisplayMode hw_display_mode) { 5871c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed uint32_t mode = kModeDefault; 588d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 589d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin switch (hw_display_mode) { 590d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin case kModeVideo: 591d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin mode = kModeLPMVideo; 592d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin break; 593d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin case kModeCommand: 594d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin mode = kModeLPMCommand; 595d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin break; 596d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin default: 597d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGW("Failed to translate SDE display mode %d to a MSMFB_LPM_ENABLE mode", 598d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin hw_display_mode); 599d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorParameters; 600d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 601d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 6021c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed if (Sys::ioctl_(device_fd_, INT(MSMFB_LPM_ENABLE), &mode) < 0) { 603d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin IOCTL_LOGE(MSMFB_LPM_ENABLE, device_type_); 604d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorHardware; 605d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 606d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 607d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGI("Triggering display mode change to %d on next commit.", hw_display_mode); 608d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin synchronous_commit_ = true; 609d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 610d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 611d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 612d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 613d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::SetPanelBrightness(int level) { 614d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char buffer[MAX_SYSFS_COMMAND_LENGTH] = {0}; 615d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 616d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGV_IF(kTagDriverConfig, "Set brightness level to %d", level); 617d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int fd = Sys::open_(kBrightnessNode, O_RDWR); 618d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (fd < 0) { 619d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGV_IF(kTagDriverConfig, "Failed to open node = %s, error = %s ", kBrightnessNode, 620d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin strerror(errno)); 621d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorFileDescriptor; 622d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 623d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 624d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int32_t bytes = snprintf(buffer, MAX_SYSFS_COMMAND_LENGTH, "%d\n", level); 625d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (bytes < 0) { 626d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGV_IF(kTagDriverConfig, "Failed to copy new brightness level = %d", level); 627d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::close_(fd); 628d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorUndefined; 629d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 630d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 6311c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed ssize_t ret = Sys::pwrite_(fd, buffer, static_cast<size_t>(bytes), 0); 632d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (ret <= 0) { 633d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGV_IF(kTagDriverConfig, "Failed to write to node = %s, error = %s ", kBrightnessNode, 634d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin strerror(errno)); 635d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::close_(fd); 636d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorUndefined; 637d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 638d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::close_(fd); 639d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 640d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 641d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 642d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 643d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::GetPanelBrightness(int *level) { 644d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char brightness[kMaxStringLength] = {0}; 645d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 646d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (!level) { 647d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGV_IF(kTagDriverConfig, "Invalid input, null pointer."); 648d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorParameters; 649d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 650d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 651d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int fd = Sys::open_(kBrightnessNode, O_RDWR); 652d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (fd < 0) { 653d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGV_IF(kTagDriverConfig, "Failed to open brightness node = %s, error = %s", kBrightnessNode, 654d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin strerror(errno)); 655d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorFileDescriptor; 656d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 657d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 658d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (Sys::pread_(fd, brightness, sizeof(brightness), 0) > 0) { 659d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *level = atoi(brightness); 660d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGV_IF(kTagDriverConfig, "Brightness level = %d", *level); 661d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 662d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin Sys::close_(fd); 663d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 664d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 665d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 666d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 667d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::SetAutoRefresh(bool enable) { 668d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin const int kWriteLength = 2; 669d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin char buffer[kWriteLength] = {'\0'}; 670d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ssize_t bytes = snprintf(buffer, kWriteLength, "%d", enable); 671d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 672829790261efb161bff68251b0a1baceae6610430Mekala Natarajan if (enable == auto_refresh_) { 673829790261efb161bff68251b0a1baceae6610430Mekala Natarajan return kErrorNone; 674829790261efb161bff68251b0a1baceae6610430Mekala Natarajan } 675829790261efb161bff68251b0a1baceae6610430Mekala Natarajan 676d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (HWDevice::SysFsWrite(kAutoRefreshNode, buffer, bytes) <= 0) { // Returns bytes written 677d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorUndefined; 678d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 679d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 680829790261efb161bff68251b0a1baceae6610430Mekala Natarajan auto_refresh_ = enable; 681829790261efb161bff68251b0a1baceae6610430Mekala Natarajan 682d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 683d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 684d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 685d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::GetPPFeaturesVersion(PPFeatureVersion *vers) { 686d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin STRUCT_VAR(mdp_pp_feature_version, version); 687d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 688d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin uint32_t feature_id_mapping[kMaxNumPPFeatures] = { PCC, IGC, GC, GC, PA, DITHER, GAMUT }; 689d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 690d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin for (int i(0); i < kMaxNumPPFeatures; i++) { 691d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin version.pp_feature = feature_id_mapping[i]; 692d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 6931c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed if (Sys::ioctl_(device_fd_, INT(MSMFB_MDP_PP_GET_FEATURE_VERSION), &version) < 0) { 694d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin IOCTL_LOGE(MSMFB_MDP_PP_GET_FEATURE_VERSION, device_type_); 695d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorHardware; 696d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 697d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin vers->version[i] = version.version_info; 698d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 699d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 700d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 701d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 702d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 703d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin// It was entered with PPFeaturesConfig::locker_ being hold. 704d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinDisplayError HWPrimary::SetPPFeatures(PPFeaturesConfig *feature_list) { 705d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin STRUCT_VAR(msmfb_mdp_pp, kernel_params); 706d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin int ret = 0; 707d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin PPFeatureInfo *feature = NULL; 708d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 709d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin while (true) { 710d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin ret = feature_list->RetrieveNextFeature(&feature); 711d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (ret) 712d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin break; 713d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 714d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if (feature) { 715d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin DLOGV_IF(kTagDriverConfig, "feature_id = %d", feature->feature_id_); 716d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 717d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin if ((feature->feature_id_ < kMaxNumPPFeatures)) { 718d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin HWColorManager::SetFeature[feature->feature_id_](*feature, &kernel_params); 7191c83c9c682ae9a6a43bd7e1a199355333c70a8cdNaseer Ahmed if (Sys::ioctl_(device_fd_, INT(MSMFB_MDP_PP), &kernel_params) < 0) { 720d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin IOCTL_LOGE(MSMFB_MDP_PP, device_type_); 721d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 722d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin feature_list->Reset(); 723d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorHardware; 724d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 725d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 726d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } 727d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin } // while(true) 728d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 729d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Once all features were consumed, then destroy all feature instance from feature_list, 730d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin // Then mark it as non-dirty of PPFeaturesConfig cache. 731d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin feature_list->Reset(); 732d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 733d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin return kErrorNone; 734d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} 735d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 736d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin} // namespace sdm 737d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin 738