1 /* 2 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. 3 * Copyright (C) 2013 Red Hat 4 * Author: Rob Clark <robdclark@gmail.com> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published by 8 * the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 * You should have received a copy of the GNU General Public License along with 16 * this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef __DPU_KMS_H__ 20 #define __DPU_KMS_H__ 21 22 #include "msm_drv.h" 23 #include "msm_kms.h" 24 #include "msm_mmu.h" 25 #include "msm_gem.h" 26 #include "dpu_dbg.h" 27 #include "dpu_hw_catalog.h" 28 #include "dpu_hw_ctl.h" 29 #include "dpu_hw_lm.h" 30 #include "dpu_hw_interrupts.h" 31 #include "dpu_hw_top.h" 32 #include "dpu_rm.h" 33 #include "dpu_power_handle.h" 34 #include "dpu_irq.h" 35 #include "dpu_core_perf.h" 36 37 #define DRMID(x) ((x) ? (x)->base.id : -1) 38 39 /** 40 * DPU_DEBUG - macro for kms/plane/crtc/encoder/connector logs 41 * @fmt: Pointer to format string 42 */ 43 #define DPU_DEBUG(fmt, ...) \ 44 do { \ 45 if (unlikely(drm_debug & DRM_UT_KMS)) \ 46 DRM_DEBUG(fmt, ##__VA_ARGS__); \ 47 else \ 48 pr_debug(fmt, ##__VA_ARGS__); \ 49 } while (0) 50 51 /** 52 * DPU_DEBUG_DRIVER - macro for hardware driver logging 53 * @fmt: Pointer to format string 54 */ 55 #define DPU_DEBUG_DRIVER(fmt, ...) \ 56 do { \ 57 if (unlikely(drm_debug & DRM_UT_DRIVER)) \ 58 DRM_ERROR(fmt, ##__VA_ARGS__); \ 59 else \ 60 pr_debug(fmt, ##__VA_ARGS__); \ 61 } while (0) 62 63 #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__) 64 65 /** 66 * ktime_compare_safe - compare two ktime structures 67 * This macro is similar to the standard ktime_compare() function, but 68 * attempts to also handle ktime overflows. 69 * @A: First ktime value 70 * @B: Second ktime value 71 * Returns: -1 if A < B, 0 if A == B, 1 if A > B 72 */ 73 #define ktime_compare_safe(A, B) \ 74 ktime_compare(ktime_sub((A), (B)), ktime_set(0, 0)) 75 76 #define DPU_NAME_SIZE 12 77 78 /* timeout in frames waiting for frame done */ 79 #define DPU_FRAME_DONE_TIMEOUT 60 80 81 /* 82 * struct dpu_irq_callback - IRQ callback handlers 83 * @list: list to callback 84 * @func: intr handler 85 * @arg: argument for the handler 86 */ 87 struct dpu_irq_callback { 88 struct list_head list; 89 void (*func)(void *arg, int irq_idx); 90 void *arg; 91 }; 92 93 /** 94 * struct dpu_irq: IRQ structure contains callback registration info 95 * @total_irq: total number of irq_idx obtained from HW interrupts mapping 96 * @irq_cb_tbl: array of IRQ callbacks setting 97 * @enable_counts array of IRQ enable counts 98 * @cb_lock: callback lock 99 * @debugfs_file: debugfs file for irq statistics 100 */ 101 struct dpu_irq { 102 u32 total_irqs; 103 struct list_head *irq_cb_tbl; 104 atomic_t *enable_counts; 105 atomic_t *irq_counts; 106 spinlock_t cb_lock; 107 struct dentry *debugfs_file; 108 }; 109 110 struct dpu_kms { 111 struct msm_kms base; 112 struct drm_device *dev; 113 int core_rev; 114 struct dpu_mdss_cfg *catalog; 115 116 struct dpu_power_handle phandle; 117 struct dpu_power_client *core_client; 118 struct dpu_power_event *power_event; 119 120 /* directory entry for debugfs */ 121 struct dentry *debugfs_root; 122 struct dentry *debugfs_danger; 123 struct dentry *debugfs_vbif; 124 125 /* io/register spaces: */ 126 void __iomem *mmio, *vbif[VBIF_MAX], *reg_dma; 127 unsigned long mmio_len, vbif_len[VBIF_MAX], reg_dma_len; 128 129 struct regulator *vdd; 130 struct regulator *mmagic; 131 struct regulator *venus; 132 133 struct dpu_hw_intr *hw_intr; 134 struct dpu_irq irq_obj; 135 136 struct dpu_core_perf perf; 137 138 /* saved atomic state during system suspend */ 139 struct drm_atomic_state *suspend_state; 140 bool suspend_block; 141 142 struct dpu_rm rm; 143 bool rm_init; 144 145 struct dpu_hw_vbif *hw_vbif[VBIF_MAX]; 146 struct dpu_hw_mdp *hw_mdp; 147 148 bool has_danger_ctrl; 149 150 struct platform_device *pdev; 151 bool rpm_enabled; 152 struct dss_module_power mp; 153 }; 154 155 struct vsync_info { 156 u32 frame_count; 157 u32 line_count; 158 }; 159 160 #define to_dpu_kms(x) container_of(x, struct dpu_kms, base) 161 162 /* get struct msm_kms * from drm_device * */ 163 #define ddev_to_msm_kms(D) ((D) && (D)->dev_private ? \ 164 ((struct msm_drm_private *)((D)->dev_private))->kms : NULL) 165 166 /** 167 * dpu_kms_is_suspend_state - whether or not the system is pm suspended 168 * @dev: Pointer to drm device 169 * Return: Suspend status 170 */ 171 static inline bool dpu_kms_is_suspend_state(struct drm_device *dev) 172 { 173 if (!ddev_to_msm_kms(dev)) 174 return false; 175 176 return to_dpu_kms(ddev_to_msm_kms(dev))->suspend_state != NULL; 177 } 178 179 /** 180 * dpu_kms_is_suspend_blocked - whether or not commits are blocked due to pm 181 * suspend status 182 * @dev: Pointer to drm device 183 * Return: True if commits should be rejected due to pm suspend 184 */ 185 static inline bool dpu_kms_is_suspend_blocked(struct drm_device *dev) 186 { 187 if (!dpu_kms_is_suspend_state(dev)) 188 return false; 189 190 return to_dpu_kms(ddev_to_msm_kms(dev))->suspend_block; 191 } 192 193 /** 194 * Debugfs functions - extra helper functions for debugfs support 195 * 196 * Main debugfs documentation is located at, 197 * 198 * Documentation/filesystems/debugfs.txt 199 * 200 * @dpu_debugfs_setup_regset32: Initialize data for dpu_debugfs_create_regset32 201 * @dpu_debugfs_create_regset32: Create 32-bit register dump file 202 * @dpu_debugfs_get_root: Get root dentry for DPU_KMS's debugfs node 203 */ 204 205 /** 206 * Companion structure for dpu_debugfs_create_regset32. Do not initialize the 207 * members of this structure explicitly; use dpu_debugfs_setup_regset32 instead. 208 */ 209 struct dpu_debugfs_regset32 { 210 uint32_t offset; 211 uint32_t blk_len; 212 struct dpu_kms *dpu_kms; 213 }; 214 215 /** 216 * dpu_debugfs_setup_regset32 - Initialize register block definition for debugfs 217 * This function is meant to initialize dpu_debugfs_regset32 structures for use 218 * with dpu_debugfs_create_regset32. 219 * @regset: opaque register definition structure 220 * @offset: sub-block offset 221 * @length: sub-block length, in bytes 222 * @dpu_kms: pointer to dpu kms structure 223 */ 224 void dpu_debugfs_setup_regset32(struct dpu_debugfs_regset32 *regset, 225 uint32_t offset, uint32_t length, struct dpu_kms *dpu_kms); 226 227 /** 228 * dpu_debugfs_create_regset32 - Create register read back file for debugfs 229 * 230 * This function is almost identical to the standard debugfs_create_regset32() 231 * function, with the main difference being that a list of register 232 * names/offsets do not need to be provided. The 'read' function simply outputs 233 * sequential register values over a specified range. 234 * 235 * Similar to the related debugfs_create_regset32 API, the structure pointed to 236 * by regset needs to persist for the lifetime of the created file. The calling 237 * code is responsible for initialization/management of this structure. 238 * 239 * The structure pointed to by regset is meant to be opaque. Please use 240 * dpu_debugfs_setup_regset32 to initialize it. 241 * 242 * @name: File name within debugfs 243 * @mode: File mode within debugfs 244 * @parent: Parent directory entry within debugfs, can be NULL 245 * @regset: Pointer to persistent register block definition 246 * 247 * Return: dentry pointer for newly created file, use either debugfs_remove() 248 * or debugfs_remove_recursive() (on a parent directory) to remove the 249 * file 250 */ 251 void *dpu_debugfs_create_regset32(const char *name, umode_t mode, 252 void *parent, struct dpu_debugfs_regset32 *regset); 253 254 /** 255 * dpu_debugfs_get_root - Return root directory entry for KMS's debugfs 256 * 257 * The return value should be passed as the 'parent' argument to subsequent 258 * debugfs create calls. 259 * 260 * @dpu_kms: Pointer to DPU's KMS structure 261 * 262 * Return: dentry pointer for DPU's debugfs location 263 */ 264 void *dpu_debugfs_get_root(struct dpu_kms *dpu_kms); 265 266 /** 267 * DPU info management functions 268 * These functions/definitions allow for building up a 'dpu_info' structure 269 * containing one or more "key=value\n" entries. 270 */ 271 #define DPU_KMS_INFO_MAX_SIZE 4096 272 273 /** 274 * Vblank enable/disable functions 275 */ 276 int dpu_enable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); 277 void dpu_disable_vblank(struct msm_kms *kms, struct drm_crtc *crtc); 278 279 void dpu_kms_encoder_enable(struct drm_encoder *encoder); 280 281 /** 282 * dpu_kms_get_clk_rate() - get the clock rate 283 * @dpu_kms: poiner to dpu_kms structure 284 * @clock_name: clock name to get the rate 285 * 286 * Return: current clock rate 287 */ 288 u64 dpu_kms_get_clk_rate(struct dpu_kms *dpu_kms, char *clock_name); 289 290 #endif /* __dpu_kms_H__ */ 291