| /* |
| * Copyright (c) 2017, The Linux Foundation. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are |
| * met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above |
| * copyright notice, this list of conditions and the following |
| * disclaimer in the documentation and/or other materials provided |
| * with the distribution. |
| * * Neither the name of The Linux Foundation nor the names of its |
| * contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "hw_tv_drm.h" |
| #include <utils/debug.h> |
| #include <utils/sys.h> |
| #include <utils/formats.h> |
| #include <drm_lib_loader.h> |
| #include <drm_master.h> |
| #include <drm_res_mgr.h> |
| #include <stdio.h> |
| #include <unistd.h> |
| #include <string> |
| #include <vector> |
| #include <map> |
| #include <utility> |
| |
| |
| #define __CLASS__ "HWTVDRM" |
| |
| using drm_utils::DRMMaster; |
| using drm_utils::DRMResMgr; |
| using drm_utils::DRMLibLoader; |
| using drm_utils::DRMBuffer; |
| using sde_drm::GetDRMManager; |
| using sde_drm::DestroyDRMManager; |
| using sde_drm::DRMDisplayType; |
| using sde_drm::DRMDisplayToken; |
| using sde_drm::DRMConnectorInfo; |
| using sde_drm::DRMPPFeatureInfo; |
| using sde_drm::DRMOps; |
| using sde_drm::DRMTopology; |
| using sde_drm::DRMPowerMode; |
| |
| namespace sdm { |
| |
| HWTVDRM::HWTVDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator, |
| HWInfoInterface *hw_info_intf) |
| : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) { |
| disp_type_ = DRMDisplayType::TV; |
| device_name_ = "TV Display Device"; |
| } |
| |
| DisplayError HWTVDRM::SetDisplayAttributes(uint32_t index) { |
| if (index >= connector_info_.modes.size()) { |
| DLOGE("Invalid mode index %d mode size %d", index, UINT32(connector_info_.modes.size())); |
| return kErrorNotSupported; |
| } |
| |
| current_mode_index_ = index; |
| PopulateHWPanelInfo(); |
| UpdateMixerAttributes(); |
| |
| DLOGI("Display attributes[%d]: WxH: %dx%d, DPI: %fx%f, FPS: %d, LM_SPLIT: %d, V_BACK_PORCH: %d," \ |
| " V_FRONT_PORCH: %d, V_PULSE_WIDTH: %d, V_TOTAL: %d, H_TOTAL: %d, CLK: %dKHZ, TOPOLOGY: %d", |
| index, display_attributes_[index].x_pixels, display_attributes_[index].y_pixels, |
| display_attributes_[index].x_dpi, display_attributes_[index].y_dpi, |
| display_attributes_[index].fps, display_attributes_[index].is_device_split, |
| display_attributes_[index].v_back_porch, display_attributes_[index].v_front_porch, |
| display_attributes_[index].v_pulse_width, display_attributes_[index].v_total, |
| display_attributes_[index].h_total, display_attributes_[index].clock_khz, |
| display_attributes_[index].topology); |
| |
| return kErrorNone; |
| } |
| |
| DisplayError HWTVDRM::GetConfigIndex(char *mode, uint32_t *index) { |
| uint32_t width = 0, height = 0, fps = 0, format = 0; |
| std::string str(mode); |
| |
| // mode should be in width:height:fps:format |
| // TODO(user): it is not fully robust, User needs to provide in above format only |
| if (str.length() != 0) { |
| width = UINT32(stoi(str)); |
| height = UINT32(stoi(str.substr(str.find(':') + 1))); |
| std::string str3 = str.substr(str.find(':') + 1); |
| fps = UINT32(stoi(str3.substr(str3.find(':') + 1))); |
| std::string str4 = str3.substr(str3.find(':') + 1); |
| format = UINT32(stoi(str4.substr(str4.find(':') + 1))); |
| } |
| |
| for (size_t idex = 0; idex < connector_info_.modes.size(); idex ++) { |
| if ((height == connector_info_.modes[idex].mode.vdisplay) && |
| (width == connector_info_.modes[idex].mode.hdisplay) && |
| (fps == connector_info_.modes[idex].mode.vrefresh)) { |
| if ((format >> 1) & (connector_info_.modes[idex].mode.flags >> kBitYUV)) { |
| *index = UINT32(idex); |
| break; |
| } |
| |
| if (format & (connector_info_.modes[idex].mode.flags >> kBitRGB)) { |
| *index = UINT32(idex); |
| break; |
| } |
| } |
| } |
| |
| return kErrorNone; |
| } |
| |
| DisplayError HWTVDRM::PowerOff() { |
| DTRACE_SCOPED(); |
| |
| int ret = drm_atomic_intf_->Commit(true /* synchronous */, false /* retain_planes*/); |
| if (ret) { |
| DLOGE("%s failed with error %d", __FUNCTION__, ret); |
| return kErrorHardware; |
| } |
| |
| return kErrorNone; |
| } |
| |
| DisplayError HWTVDRM::Doze() { |
| return kErrorNone; |
| } |
| |
| DisplayError HWTVDRM::DozeSuspend() { |
| return kErrorNone; |
| } |
| |
| DisplayError HWTVDRM::Standby() { |
| return kErrorNone; |
| } |
| |
| } // namespace sdm |
| |