Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  * Copyright (C) 2013 Red Hat
0004  * Author: Rob Clark <robdclark@gmail.com>
0005  */
0006 
0007 #ifndef __MDP4_KMS_H__
0008 #define __MDP4_KMS_H__
0009 
0010 #include <drm/drm_panel.h>
0011 
0012 #include "msm_drv.h"
0013 #include "msm_kms.h"
0014 #include "disp/mdp_kms.h"
0015 #include "mdp4.xml.h"
0016 
0017 struct device_node;
0018 
0019 struct mdp4_kms {
0020     struct mdp_kms base;
0021 
0022     struct drm_device *dev;
0023 
0024     int rev;
0025 
0026     void __iomem *mmio;
0027 
0028     struct regulator *vdd;
0029 
0030     struct clk *clk;
0031     struct clk *pclk;
0032     struct clk *lut_clk;
0033     struct clk *axi_clk;
0034 
0035     struct mdp_irq error_handler;
0036 
0037     bool rpm_enabled;
0038 
0039     /* empty/blank cursor bo to use when cursor is "disabled" */
0040     struct drm_gem_object *blank_cursor_bo;
0041     uint64_t blank_cursor_iova;
0042 };
0043 #define to_mdp4_kms(x) container_of(x, struct mdp4_kms, base)
0044 
0045 static inline void mdp4_write(struct mdp4_kms *mdp4_kms, u32 reg, u32 data)
0046 {
0047     msm_writel(data, mdp4_kms->mmio + reg);
0048 }
0049 
0050 static inline u32 mdp4_read(struct mdp4_kms *mdp4_kms, u32 reg)
0051 {
0052     return msm_readl(mdp4_kms->mmio + reg);
0053 }
0054 
0055 static inline uint32_t pipe2flush(enum mdp4_pipe pipe)
0056 {
0057     switch (pipe) {
0058     case VG1:      return MDP4_OVERLAY_FLUSH_VG1;
0059     case VG2:      return MDP4_OVERLAY_FLUSH_VG2;
0060     case RGB1:     return MDP4_OVERLAY_FLUSH_RGB1;
0061     case RGB2:     return MDP4_OVERLAY_FLUSH_RGB2;
0062     default:       return 0;
0063     }
0064 }
0065 
0066 static inline uint32_t ovlp2flush(int ovlp)
0067 {
0068     switch (ovlp) {
0069     case 0:        return MDP4_OVERLAY_FLUSH_OVLP0;
0070     case 1:        return MDP4_OVERLAY_FLUSH_OVLP1;
0071     default:       return 0;
0072     }
0073 }
0074 
0075 static inline uint32_t dma2irq(enum mdp4_dma dma)
0076 {
0077     switch (dma) {
0078     case DMA_P:    return MDP4_IRQ_DMA_P_DONE;
0079     case DMA_S:    return MDP4_IRQ_DMA_S_DONE;
0080     case DMA_E:    return MDP4_IRQ_DMA_E_DONE;
0081     default:       return 0;
0082     }
0083 }
0084 
0085 static inline uint32_t dma2err(enum mdp4_dma dma)
0086 {
0087     switch (dma) {
0088     case DMA_P:    return MDP4_IRQ_PRIMARY_INTF_UDERRUN;
0089     case DMA_S:    return 0;  // ???
0090     case DMA_E:    return MDP4_IRQ_EXTERNAL_INTF_UDERRUN;
0091     default:       return 0;
0092     }
0093 }
0094 
0095 static inline uint32_t mixercfg(uint32_t mixer_cfg, int mixer,
0096         enum mdp4_pipe pipe, enum mdp_mixer_stage_id stage)
0097 {
0098     switch (pipe) {
0099     case VG1:
0100         mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE0__MASK |
0101                 MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
0102         mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE0(stage) |
0103             COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE0_MIXER1);
0104         break;
0105     case VG2:
0106         mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE1__MASK |
0107                 MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
0108         mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE1(stage) |
0109             COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE1_MIXER1);
0110         break;
0111     case RGB1:
0112         mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE2__MASK |
0113                 MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
0114         mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE2(stage) |
0115             COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE2_MIXER1);
0116         break;
0117     case RGB2:
0118         mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE3__MASK |
0119                 MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
0120         mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE3(stage) |
0121             COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE3_MIXER1);
0122         break;
0123     case RGB3:
0124         mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE4__MASK |
0125                 MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
0126         mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE4(stage) |
0127             COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE4_MIXER1);
0128         break;
0129     case VG3:
0130         mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE5__MASK |
0131                 MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
0132         mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE5(stage) |
0133             COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE5_MIXER1);
0134         break;
0135     case VG4:
0136         mixer_cfg &= ~(MDP4_LAYERMIXER_IN_CFG_PIPE6__MASK |
0137                 MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
0138         mixer_cfg |= MDP4_LAYERMIXER_IN_CFG_PIPE6(stage) |
0139             COND(mixer == 1, MDP4_LAYERMIXER_IN_CFG_PIPE6_MIXER1);
0140         break;
0141     default:
0142         WARN(1, "invalid pipe");
0143         break;
0144     }
0145 
0146     return mixer_cfg;
0147 }
0148 
0149 int mdp4_disable(struct mdp4_kms *mdp4_kms);
0150 int mdp4_enable(struct mdp4_kms *mdp4_kms);
0151 
0152 void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
0153         uint32_t old_irqmask);
0154 void mdp4_irq_preinstall(struct msm_kms *kms);
0155 int mdp4_irq_postinstall(struct msm_kms *kms);
0156 void mdp4_irq_uninstall(struct msm_kms *kms);
0157 irqreturn_t mdp4_irq(struct msm_kms *kms);
0158 int mdp4_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
0159 void mdp4_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc);
0160 
0161 static inline uint32_t mdp4_pipe_caps(enum mdp4_pipe pipe)
0162 {
0163     switch (pipe) {
0164     case VG1:
0165     case VG2:
0166     case VG3:
0167     case VG4:
0168         return MDP_PIPE_CAP_HFLIP | MDP_PIPE_CAP_VFLIP |
0169                 MDP_PIPE_CAP_SCALE | MDP_PIPE_CAP_CSC;
0170     case RGB1:
0171     case RGB2:
0172     case RGB3:
0173         return MDP_PIPE_CAP_SCALE;
0174     default:
0175         return 0;
0176     }
0177 }
0178 
0179 enum mdp4_pipe mdp4_plane_pipe(struct drm_plane *plane);
0180 struct drm_plane *mdp4_plane_init(struct drm_device *dev,
0181         enum mdp4_pipe pipe_id, bool private_plane);
0182 
0183 uint32_t mdp4_crtc_vblank(struct drm_crtc *crtc);
0184 void mdp4_crtc_set_config(struct drm_crtc *crtc, uint32_t config);
0185 void mdp4_crtc_set_intf(struct drm_crtc *crtc, enum mdp4_intf intf, int mixer);
0186 void mdp4_crtc_wait_for_commit_done(struct drm_crtc *crtc);
0187 struct drm_crtc *mdp4_crtc_init(struct drm_device *dev,
0188         struct drm_plane *plane, int id, int ovlp_id,
0189         enum mdp4_dma dma_id);
0190 
0191 long mdp4_dtv_round_pixclk(struct drm_encoder *encoder, unsigned long rate);
0192 struct drm_encoder *mdp4_dtv_encoder_init(struct drm_device *dev);
0193 
0194 long mdp4_lcdc_round_pixclk(struct drm_encoder *encoder, unsigned long rate);
0195 struct drm_encoder *mdp4_lcdc_encoder_init(struct drm_device *dev,
0196         struct device_node *panel_node);
0197 
0198 struct drm_connector *mdp4_lvds_connector_init(struct drm_device *dev,
0199         struct device_node *panel_node, struct drm_encoder *encoder);
0200 
0201 #ifdef CONFIG_DRM_MSM_DSI
0202 struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev);
0203 #else
0204 static inline struct drm_encoder *mdp4_dsi_encoder_init(struct drm_device *dev)
0205 {
0206     return ERR_PTR(-ENODEV);
0207 }
0208 #endif
0209 
0210 #ifdef CONFIG_COMMON_CLK
0211 struct clk *mpd4_lvds_pll_init(struct drm_device *dev);
0212 #else
0213 static inline struct clk *mpd4_lvds_pll_init(struct drm_device *dev)
0214 {
0215     return ERR_PTR(-ENODEV);
0216 }
0217 #endif
0218 
0219 #endif /* __MDP4_KMS_H__ */