1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Copyright (C) 2013 Red Hat 4 * Author: Rob Clark <robdclark@gmail.com> 5 */ 6 7 #ifndef __MDP4_KMS_H__ 8 #define __MDP4_KMS_H__ 9 10 #include <drm/drm_panel.h> 11 12 #include "msm_drv.h" 13 #include "msm_kms.h" 14 #include "disp/mdp_kms.h" 15 #include "mdp4.xml.h" 16 17 struct device_node; 18 19 struct mdp4_kms { 20 struct mdp_kms base; 21 22 struct drm_device *dev; 23 24 int rev; 25 26 void __iomem *mmio; 27 28 struct regulator *vdd; 29 30 struct clk *clk; 31 struct clk *pclk; 32 struct clk *lut_clk; 33 struct clk *axi_clk; 34 35 struct mdp_irq error_handler; 36 37 bool rpm_enabled; 38 39 /* empty/blank cursor bo to use when cursor is "disabled" */ 40 struct drm_gem_object *blank_cursor_bo; 41 uint64_t blank_cursor_iova; 42 }; 43 #define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base) 44 45 static inline void mdp4_write(struct mdp4_kms *mdp4_kms, u32 reg, u32 data) 46 { 47 writel(data, mdp4_kms->mmio + reg); 48 } 49 50 static inline u32 mdp4_read(struct mdp4_kms *mdp4_kms, u32 reg) 51 { 52 return readl(mdp4_kms->mmio + reg); 53 } 54 55 static inline uint32_t pipe2flush(enum mdp4_pipe pipe) 56 { 57 switch (pipe) { 58 case VG1: return MDP4_OVERLAY_FLUSH_VG1; 59 case VG2: return MDP4_OVERLAY_FLUSH_VG2; 60 case RGB1: return MDP4_OVERLAY_FLUSH_RGB1; 61 case RGB2: return MDP4_OVERLAY_FLUSH_RGB2; 62 default: return 0; 63 } 64 } 65 66 static inline uint32_t ovlp2flush(int ovlp) 67 { 68 switch (ovlp) { 69 case 0: return MDP4_OVERLAY_FLUSH_OVLP0; 70 case 1: return MDP4_OVERLAY_FLUSH_OVLP1; 71 default: return 0; 72 } 73 } 74 75 static inline uint32_t dma2irq(enum mdp4_dma dma) 76 { 77 switch (dma) { 78 case DMA_P: return MDP4_IRQ_DMA_P_DONE; 79 case DMA_S: return MDP4_IRQ_DMA_S_DONE; 80 case DMA_E: return MDP4_IRQ_DMA_E_DONE; 81 default: return 0; 82 } 83 } 84 85 static inline uint32_t dma2err(enum mdp4_dma dma) 86 { 87 switch (dma) { 88 case DMA_P: return MDP4_IRQ_PRIMARY_INTF_UDERRUN; 89 case DMA_S: return 0; // ??? 90 case DMA_E: return MDP4_IRQ_EXTERNAL_INTF_UDERRUN; 91 default: return 0; 92 } 93 } 94 95 static inline uint32_t mixercfg(uint32_t mixer_cfg, int mixer, 96 enum mdp4_pipe pipe, enum mdp_mixer_stage_id stage) 97 { 98 switch (pipe) { 99 case VG1: 100 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE0__MASK | 101 MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1); 102 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE0(stage) | 103 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1); 104 break; 105 case VG2: 106 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE1__MASK | 107 MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1); 108 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE1(stage) | 109 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1); 110 break; 111 case RGB1: 112 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE2__MASK | 113 MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1); 114 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE2(stage) | 115 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1); 116 break; 117 case RGB2: 118 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE3__MASK | 119 MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1); 120 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE3(stage) | 121 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1); 122 break; 123 case RGB3: 124 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE4__MASK | 125 MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1); 126 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE4(stage) | 127 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1); 128 break; 129 case VG3: 130 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE5__MASK | 131 MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1); 132 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE5(stage) | 133 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1); 134 break; 135 case VG4: 136 mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE6__MASK | 137 MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1); 138 mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE6(stage) | 139 COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1); 140 break; 141 default: 142 WARN(1, "invalid pipe"); 143 break; 144 } 145 146 return mixer_cfg; 147 } 148 149 int mdp4_disable(struct mdp4_kms *mdp4_kms); 150 int mdp4_enable(struct mdp4_kms *mdp4_kms); 151 152 void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask, 153 uint32_t old_irqmask); 154 void mdp4_irq_preinstall(struct msm_kms *kms); 155 int mdp4_irq_postinstall(struct msm_kms *kms); 156 void mdp4_irq_uninstall(struct msm_kms *kms); 157 irqreturn_t mdp4_irq(struct msm_kms *kms); 158 int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); 159 void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); 160 161 static inline uint32_t mdp4_pipe_caps(enum mdp4_pipe pipe) 162 { 163 switch (pipe) { 164 case VG1: 165 case VG2: 166 case VG3: 167 case VG4: 168 return MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP | 169 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC; 170 case RGB1: 171 case RGB2: 172 case RGB3: 173 return MDP_PIPE_CAP_SCALE; 174 default: 175 return 0; 176 } 177 } 178 179 enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane); 180 struct drm_plane *mdp4_plane_init(struct drm_device *dev, 181 enum mdp4_pipe pipe_id, bool private_plane); 182 183 uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc); 184 void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config); 185 void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer); 186 void mdp4_crtc_wait_for_commit_done(struct drm_crtc *crtc); 187 struct drm_crtc *mdp4_crtc_init(struct drm_device *dev, 188 struct drm_plane *plane, int id, int ovlp_id, 189 enum mdp4_dma dma_id); 190 191 long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate); 192 struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev); 193 194 long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate); 195 struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev, 196 struct device_node *panel_node); 197 198 struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev, 199 struct device_node *panel_node, struct drm_encoder *encoder); 200 201 #ifdef CONFIG_DRM_MSM_DSI 202 struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev); 203 #else 204 static inline struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev) 205 { 206 return ERR_PTR(-ENODEV); 207 } 208 #endif 209 210 #ifdef CONFIG_COMMON_CLK 211 struct clk *mpd4_lvds_pll_init(struct drm_device *dev); 212 #else 213 static inline struct clk *mpd4_lvds_pll_init(struct drm_device *dev) 214 { 215 return ERR_PTR(-ENODEV); 216 } 217 #endif 218 219 #endif /* __MDP4_KMS_H__ */ 220