1 // Copyright 2017 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <ddk/protocol/display/controller.h> 8 #include <ddktl/device.h> 9 #include <ddktl/mmio.h> 10 #include <region-alloc/region-alloc.h> 11 #include <lib/zx/vmo.h> 12 13 #include "gtt.h" 14 #include "pipe.h" 15 #include "power.h" 16 #include "registers-ddi.h" 17 #include "registers-pipe.h" 18 #include "registers-transcoder.h" 19 20 namespace i915 { 21 22 class Controller; 23 class DisplayDevice; 24 25 // Thread safe weak-ref to the DisplayDevice, because the backlight device 26 // lifecycle is managed by devmgr but the DisplayDevice lifecycle is managed 27 // by the display controller class. 28 typedef struct display_ref { 29 mtx_t mtx; 30 DisplayDevice* display_device __TA_GUARDED(mtx); 31 } display_ref_t; 32 33 34 class DisplayDevice { 35 public: 36 DisplayDevice(Controller* device, uint64_t id, registers::Ddi ddi); 37 virtual ~DisplayDevice(); 38 39 bool AttachPipe(Pipe* pipe); 40 void ApplyConfiguration(const display_config_t* config); 41 42 // Query whether or not there is a display attached to this ddi. Does not 43 // actually do any initialization - that is done by Init. 44 virtual bool Query() = 0; 45 // Does display mode agnostic ddi initialization - subclasses implement InitDdi. 46 bool Init(); 47 // Initializes the display backlight for an already initialized display. 48 void InitBacklight(); 49 // Resumes the ddi after suspend. 50 bool Resume(); 51 // Loads ddi state from the hardware at driver startup. 52 void LoadActiveMode(); 53 // Method to allow the display device to handle hotplug events. Returns 54 // true if the device can handle the event without disconnecting. Otherwise 55 // the device will be removed. HandleHotplug(bool long_pulse)56 virtual bool HandleHotplug(bool long_pulse) { return false; } 57 id()58 uint64_t id() const { return id_; } ddi()59 registers::Ddi ddi() const { return ddi_; } controller()60 Controller* controller() { return controller_; } 61 62 virtual uint32_t i2c_bus_id() const = 0; 63 pipe()64 Pipe* pipe() const { return pipe_; } 65 is_hdmi()66 bool is_hdmi() const { return is_hdmi_; } set_is_hdmi(bool is_hdmi)67 void set_is_hdmi(bool is_hdmi) { is_hdmi_ = is_hdmi; } 68 HasBacklight()69 virtual bool HasBacklight() { return false; } SetBacklightState(bool power,uint8_t brightness)70 virtual void SetBacklightState(bool power, uint8_t brightness) {} GetBacklightState(bool * power,uint8_t * brightness)71 virtual void GetBacklightState(bool* power, uint8_t* brightness) {} 72 73 virtual bool CheckPixelRate(uint64_t pixel_rate) = 0; 74 protected: 75 // Attempts to initialize the ddi. 76 virtual bool InitDdi() = 0; InitBacklightHw()77 virtual bool InitBacklightHw() { return false; } 78 79 // Configures the hardware to display content at the given resolution. 80 virtual bool DdiModeset(const display_mode_t& mode, 81 registers::Pipe pipe, registers::Trans trans) = 0; 82 virtual bool ComputeDpllState(uint32_t pixel_clock_10khz, struct dpll_state* config) = 0; 83 // Load the clock rate from hardware if it's necessary when changing the transcoder. 84 virtual uint32_t LoadClockRateForTranscoder(registers::Trans transcoder) = 0; 85 86 // Attaching a pipe to a display or configuring a pipe after display mode change has 87 // 3 steps. The second step is generic pipe configuration, whereas PipeConfigPreamble 88 // and PipeConfigEpilogue are responsible for display-type-specific configuration that 89 // must be done before and after the generic configuration. 90 virtual bool PipeConfigPreamble(const display_mode_t& mode, 91 registers::Pipe pipe, registers::Trans trans) = 0; 92 virtual bool PipeConfigEpilogue(const display_mode_t& mode, 93 registers::Pipe pipe, registers::Trans trans) = 0; 94 95 ddk::MmioBuffer* mmio_space() const; 96 97 private: 98 bool CheckNeedsModeset(const display_mode_t* mode); 99 100 // Borrowed reference to Controller instance 101 Controller* controller_; 102 103 uint64_t id_; 104 registers::Ddi ddi_; 105 106 Pipe* pipe_= nullptr; 107 108 PowerWellRef ddi_power_; 109 110 bool inited_ = false; 111 display_mode_t info_ = {}; 112 bool is_hdmi_ = false; 113 114 zx_device_t* backlight_device_ = nullptr; 115 display_ref_t* display_ref_ = nullptr; 116 }; 117 118 } // namespace i915 119