1/* 2 * Copyright (C) 2013 Red Hat 3 * Author: Rob Clark <robdclark@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18#ifndef __MDP5_KMS_H__ 19#define __MDP5_KMS_H__ 20 21#include "msm_drv.h" 22#include "msm_kms.h" 23#include "mdp/mdp_kms.h" 24/* dynamic offsets used by mdp5.xml.h (initialized in mdp5_kms.c) */ 25#define MDP5_MAX_BASES 8 26struct mdp5_sub_block { 27 int count; 28 uint32_t base[MDP5_MAX_BASES]; 29}; 30struct mdp5_config { 31 char *name; 32 struct mdp5_sub_block ctl; 33 struct mdp5_sub_block pipe_vig; 34 struct mdp5_sub_block pipe_rgb; 35 struct mdp5_sub_block pipe_dma; 36 struct mdp5_sub_block lm; 37 struct mdp5_sub_block dspp; 38 struct mdp5_sub_block ad; 39 struct mdp5_sub_block intf; 40}; 41extern const struct mdp5_config *mdp5_cfg; 42#include "mdp5.xml.h" 43#include "mdp5_smp.h" 44 45struct mdp5_kms { 46 struct mdp_kms base; 47 48 struct drm_device *dev; 49 50 int rev; 51 const struct mdp5_config *hw_cfg; 52 53 /* mapper-id used to request GEM buffer mapped for scanout: */ 54 int id; 55 struct msm_mmu *mmu; 56 57 /* for tracking smp allocation amongst pipes: */ 58 mdp5_smp_state_t smp_state; 59 struct mdp5_client_smp_state smp_client_state[CID_MAX]; 60 int smp_blk_cnt; 61 62 /* io/register spaces: */ 63 void __iomem *mmio, *vbif; 64 65 struct regulator *vdd; 66 67 struct clk *axi_clk; 68 struct clk *ahb_clk; 69 struct clk *src_clk; 70 struct clk *core_clk; 71 struct clk *lut_clk; 72 struct clk *vsync_clk; 73 74 struct hdmi *hdmi; 75 76 struct mdp_irq error_handler; 77}; 78#define to_mdp5_kms(x) container_of(x, struct mdp5_kms, base) 79 80/* platform config data (ie. from DT, or pdata) */ 81struct mdp5_platform_config { 82 struct iommu_domain *iommu; 83 uint32_t max_clk; 84 int smp_blk_cnt; 85}; 86 87static inline void mdp5_write(struct mdp5_kms *mdp5_kms, u32 reg, u32 data) 88{ 89 msm_writel(data, mdp5_kms->mmio + reg); 90} 91 92static inline u32 mdp5_read(struct mdp5_kms *mdp5_kms, u32 reg) 93{ 94 return msm_readl(mdp5_kms->mmio + reg); 95} 96 97static inline const char *pipe2name(enum mdp5_pipe pipe) 98{ 99 static const char *names[] = { 100#define NAME(n) [SSPP_ ## n] = #n 101 NAME(VIG0), NAME(VIG1), NAME(VIG2), 102 NAME(RGB0), NAME(RGB1), NAME(RGB2), 103 NAME(DMA0), NAME(DMA1), 104 NAME(VIG3), NAME(RGB3), 105#undef NAME 106 }; 107 return names[pipe]; 108} 109 110static inline uint32_t pipe2flush(enum mdp5_pipe pipe) 111{ 112 switch (pipe) { 113 case SSPP_VIG0: return MDP5_CTL_FLUSH_VIG0; 114 case SSPP_VIG1: return MDP5_CTL_FLUSH_VIG1; 115 case SSPP_VIG2: return MDP5_CTL_FLUSH_VIG2; 116 case SSPP_RGB0: return MDP5_CTL_FLUSH_RGB0; 117 case SSPP_RGB1: return MDP5_CTL_FLUSH_RGB1; 118 case SSPP_RGB2: return MDP5_CTL_FLUSH_RGB2; 119 case SSPP_DMA0: return MDP5_CTL_FLUSH_DMA0; 120 case SSPP_DMA1: return MDP5_CTL_FLUSH_DMA1; 121 case SSPP_VIG3: return MDP5_CTL_FLUSH_VIG3; 122 case SSPP_RGB3: return MDP5_CTL_FLUSH_RGB3; 123 default: return 0; 124 } 125} 126 127static inline int pipe2nclients(enum mdp5_pipe pipe) 128{ 129 switch (pipe) { 130 case SSPP_RGB0: 131 case SSPP_RGB1: 132 case SSPP_RGB2: 133 case SSPP_RGB3: 134 return 1; 135 default: 136 return 3; 137 } 138} 139 140static inline enum mdp5_client_id pipe2client(enum mdp5_pipe pipe, int plane) 141{ 142 WARN_ON(plane >= pipe2nclients(pipe)); 143 switch (pipe) { 144 case SSPP_VIG0: return CID_VIG0_Y + plane; 145 case SSPP_VIG1: return CID_VIG1_Y + plane; 146 case SSPP_VIG2: return CID_VIG2_Y + plane; 147 case SSPP_RGB0: return CID_RGB0; 148 case SSPP_RGB1: return CID_RGB1; 149 case SSPP_RGB2: return CID_RGB2; 150 case SSPP_DMA0: return CID_DMA0_Y + plane; 151 case SSPP_DMA1: return CID_DMA1_Y + plane; 152 case SSPP_VIG3: return CID_VIG3_Y + plane; 153 case SSPP_RGB3: return CID_RGB3; 154 default: return CID_UNUSED; 155 } 156} 157 158static inline uint32_t mixer2flush(int lm) 159{ 160 switch (lm) { 161 case 0: return MDP5_CTL_FLUSH_LM0; 162 case 1: return MDP5_CTL_FLUSH_LM1; 163 case 2: return MDP5_CTL_FLUSH_LM2; 164 default: return 0; 165 } 166} 167 168static inline uint32_t intf2err(int intf) 169{ 170 switch (intf) { 171 case 0: return MDP5_IRQ_INTF0_UNDER_RUN; 172 case 1: return MDP5_IRQ_INTF1_UNDER_RUN; 173 case 2: return MDP5_IRQ_INTF2_UNDER_RUN; 174 case 3: return MDP5_IRQ_INTF3_UNDER_RUN; 175 default: return 0; 176 } 177} 178 179static inline uint32_t intf2vblank(int intf) 180{ 181 switch (intf) { 182 case 0: return MDP5_IRQ_INTF0_VSYNC; 183 case 1: return MDP5_IRQ_INTF1_VSYNC; 184 case 2: return MDP5_IRQ_INTF2_VSYNC; 185 case 3: return MDP5_IRQ_INTF3_VSYNC; 186 default: return 0; 187 } 188} 189 190int mdp5_disable(struct mdp5_kms *mdp5_kms); 191int mdp5_enable(struct mdp5_kms *mdp5_kms); 192 193void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask); 194void mdp5_irq_preinstall(struct msm_kms *kms); 195int mdp5_irq_postinstall(struct msm_kms *kms); 196void mdp5_irq_uninstall(struct msm_kms *kms); 197irqreturn_t mdp5_irq(struct msm_kms *kms); 198int mdp5_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); 199void mdp5_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); 200 201static inline 202uint32_t mdp5_get_formats(enum mdp5_pipe pipe, uint32_t *pixel_formats, 203 uint32_t max_formats) 204{ 205 /* TODO when we have YUV, we need to filter supported formats 206 * based on pipe id.. 207 */ 208 return mdp_get_formats(pixel_formats, max_formats); 209} 210 211void mdp5_plane_install_properties(struct drm_plane *plane, 212 struct drm_mode_object *obj); 213void mdp5_plane_set_scanout(struct drm_plane *plane, 214 struct drm_framebuffer *fb); 215int mdp5_plane_mode_set(struct drm_plane *plane, 216 struct drm_crtc *crtc, struct drm_framebuffer *fb, 217 int crtc_x, int crtc_y, 218 unsigned int crtc_w, unsigned int crtc_h, 219 uint32_t src_x, uint32_t src_y, 220 uint32_t src_w, uint32_t src_h); 221void mdp5_plane_complete_flip(struct drm_plane *plane); 222enum mdp5_pipe mdp5_plane_pipe(struct drm_plane *plane); 223struct drm_plane *mdp5_plane_init(struct drm_device *dev, 224 enum mdp5_pipe pipe, bool private_plane); 225 226uint32_t mdp5_crtc_vblank(struct drm_crtc *crtc); 227 228void mdp5_crtc_cancel_pending_flip(struct drm_crtc *crtc, struct drm_file *file); 229void mdp5_crtc_set_intf(struct drm_crtc *crtc, int intf, 230 enum mdp5_intf intf_id); 231void mdp5_crtc_attach(struct drm_crtc *crtc, struct drm_plane *plane); 232void mdp5_crtc_detach(struct drm_crtc *crtc, struct drm_plane *plane); 233struct drm_crtc *mdp5_crtc_init(struct drm_device *dev, 234 struct drm_plane *plane, int id); 235 236struct drm_encoder *mdp5_encoder_init(struct drm_device *dev, int intf, 237 enum mdp5_intf intf_id); 238 239#endif /* __MDP5_KMS_H__ */ 240