1 /* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. 2 * 3 * This program is free software; you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License version 2 and 5 * only version 2 as published by the Free Software Foundation. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 */ 12 13 #ifndef _DPU_HW_INTERRUPTS_H 14 #define _DPU_HW_INTERRUPTS_H 15 16 #include <linux/types.h> 17 18 #include "dpu_hwio.h" 19 #include "dpu_hw_catalog.h" 20 #include "dpu_hw_util.h" 21 #include "dpu_hw_mdss.h" 22 23 #define IRQ_SOURCE_MDP BIT(0) 24 #define IRQ_SOURCE_DSI0 BIT(4) 25 #define IRQ_SOURCE_DSI1 BIT(5) 26 #define IRQ_SOURCE_HDMI BIT(8) 27 #define IRQ_SOURCE_EDP BIT(12) 28 #define IRQ_SOURCE_MHL BIT(16) 29 30 /** 31 * dpu_intr_type - HW Interrupt Type 32 * @DPU_IRQ_TYPE_WB_ROT_COMP: WB rotator done 33 * @DPU_IRQ_TYPE_WB_WFD_COMP: WB WFD done 34 * @DPU_IRQ_TYPE_PING_PONG_COMP: PingPong done 35 * @DPU_IRQ_TYPE_PING_PONG_RD_PTR: PingPong read pointer 36 * @DPU_IRQ_TYPE_PING_PONG_WR_PTR: PingPong write pointer 37 * @DPU_IRQ_TYPE_PING_PONG_AUTO_REF: PingPong auto refresh 38 * @DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK: PingPong Tear check 39 * @DPU_IRQ_TYPE_PING_PONG_TE_CHECK: PingPong TE detection 40 * @DPU_IRQ_TYPE_INTF_UNDER_RUN: INTF underrun 41 * @DPU_IRQ_TYPE_INTF_VSYNC: INTF VSYNC 42 * @DPU_IRQ_TYPE_CWB_OVERFLOW: Concurrent WB overflow 43 * @DPU_IRQ_TYPE_HIST_VIG_DONE: VIG Histogram done 44 * @DPU_IRQ_TYPE_HIST_VIG_RSTSEQ: VIG Histogram reset 45 * @DPU_IRQ_TYPE_HIST_DSPP_DONE: DSPP Histogram done 46 * @DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ: DSPP Histogram reset 47 * @DPU_IRQ_TYPE_WD_TIMER: Watchdog timer 48 * @DPU_IRQ_TYPE_SFI_VIDEO_IN: Video static frame INTR into static 49 * @DPU_IRQ_TYPE_SFI_VIDEO_OUT: Video static frame INTR out-of static 50 * @DPU_IRQ_TYPE_SFI_CMD_0_IN: DSI CMD0 static frame INTR into static 51 * @DPU_IRQ_TYPE_SFI_CMD_0_OUT: DSI CMD0 static frame INTR out-of static 52 * @DPU_IRQ_TYPE_SFI_CMD_1_IN: DSI CMD1 static frame INTR into static 53 * @DPU_IRQ_TYPE_SFI_CMD_1_OUT: DSI CMD1 static frame INTR out-of static 54 * @DPU_IRQ_TYPE_SFI_CMD_2_IN: DSI CMD2 static frame INTR into static 55 * @DPU_IRQ_TYPE_SFI_CMD_2_OUT: DSI CMD2 static frame INTR out-of static 56 * @DPU_IRQ_TYPE_PROG_LINE: Programmable Line interrupt 57 * @DPU_IRQ_TYPE_AD4_BL_DONE: AD4 backlight 58 * @DPU_IRQ_TYPE_CTL_START: Control start 59 * @DPU_IRQ_TYPE_RESERVED: Reserved for expansion 60 */ 61 enum dpu_intr_type { 62 DPU_IRQ_TYPE_WB_ROT_COMP, 63 DPU_IRQ_TYPE_WB_WFD_COMP, 64 DPU_IRQ_TYPE_PING_PONG_COMP, 65 DPU_IRQ_TYPE_PING_PONG_RD_PTR, 66 DPU_IRQ_TYPE_PING_PONG_WR_PTR, 67 DPU_IRQ_TYPE_PING_PONG_AUTO_REF, 68 DPU_IRQ_TYPE_PING_PONG_TEAR_CHECK, 69 DPU_IRQ_TYPE_PING_PONG_TE_CHECK, 70 DPU_IRQ_TYPE_INTF_UNDER_RUN, 71 DPU_IRQ_TYPE_INTF_VSYNC, 72 DPU_IRQ_TYPE_CWB_OVERFLOW, 73 DPU_IRQ_TYPE_HIST_VIG_DONE, 74 DPU_IRQ_TYPE_HIST_VIG_RSTSEQ, 75 DPU_IRQ_TYPE_HIST_DSPP_DONE, 76 DPU_IRQ_TYPE_HIST_DSPP_RSTSEQ, 77 DPU_IRQ_TYPE_WD_TIMER, 78 DPU_IRQ_TYPE_SFI_VIDEO_IN, 79 DPU_IRQ_TYPE_SFI_VIDEO_OUT, 80 DPU_IRQ_TYPE_SFI_CMD_0_IN, 81 DPU_IRQ_TYPE_SFI_CMD_0_OUT, 82 DPU_IRQ_TYPE_SFI_CMD_1_IN, 83 DPU_IRQ_TYPE_SFI_CMD_1_OUT, 84 DPU_IRQ_TYPE_SFI_CMD_2_IN, 85 DPU_IRQ_TYPE_SFI_CMD_2_OUT, 86 DPU_IRQ_TYPE_PROG_LINE, 87 DPU_IRQ_TYPE_AD4_BL_DONE, 88 DPU_IRQ_TYPE_CTL_START, 89 DPU_IRQ_TYPE_RESERVED, 90 }; 91 92 struct dpu_hw_intr; 93 94 /** 95 * Interrupt operations. 96 */ 97 struct dpu_hw_intr_ops { 98 /** 99 * set_mask - Programs the given interrupt register with the 100 * given interrupt mask. Register value will get overwritten. 101 * @intr: HW interrupt handle 102 * @reg_off: MDSS HW register offset 103 * @irqmask: IRQ mask value 104 */ 105 void (*set_mask)( 106 struct dpu_hw_intr *intr, 107 uint32_t reg, 108 uint32_t irqmask); 109 110 /** 111 * irq_idx_lookup - Lookup IRQ index on the HW interrupt type 112 * Used for all irq related ops 113 * @intr_type: Interrupt type defined in dpu_intr_type 114 * @instance_idx: HW interrupt block instance 115 * @return: irq_idx or -EINVAL for lookup fail 116 */ 117 int (*irq_idx_lookup)( 118 enum dpu_intr_type intr_type, 119 u32 instance_idx); 120 121 /** 122 * enable_irq - Enable IRQ based on lookup IRQ index 123 * @intr: HW interrupt handle 124 * @irq_idx: Lookup irq index return from irq_idx_lookup 125 * @return: 0 for success, otherwise failure 126 */ 127 int (*enable_irq)( 128 struct dpu_hw_intr *intr, 129 int irq_idx); 130 131 /** 132 * disable_irq - Disable IRQ based on lookup IRQ index 133 * @intr: HW interrupt handle 134 * @irq_idx: Lookup irq index return from irq_idx_lookup 135 * @return: 0 for success, otherwise failure 136 */ 137 int (*disable_irq)( 138 struct dpu_hw_intr *intr, 139 int irq_idx); 140 141 /** 142 * clear_all_irqs - Clears all the interrupts (i.e. acknowledges 143 * any asserted IRQs). Useful during reset. 144 * @intr: HW interrupt handle 145 * @return: 0 for success, otherwise failure 146 */ 147 int (*clear_all_irqs)( 148 struct dpu_hw_intr *intr); 149 150 /** 151 * disable_all_irqs - Disables all the interrupts. Useful during reset. 152 * @intr: HW interrupt handle 153 * @return: 0 for success, otherwise failure 154 */ 155 int (*disable_all_irqs)( 156 struct dpu_hw_intr *intr); 157 158 /** 159 * dispatch_irqs - IRQ dispatcher will call the given callback 160 * function when a matching interrupt status bit is 161 * found in the irq mapping table. 162 * @intr: HW interrupt handle 163 * @cbfunc: Callback function pointer 164 * @arg: Argument to pass back during callback 165 */ 166 void (*dispatch_irqs)( 167 struct dpu_hw_intr *intr, 168 void (*cbfunc)(void *arg, int irq_idx), 169 void *arg); 170 171 /** 172 * get_interrupt_statuses - Gets and store value from all interrupt 173 * status registers that are currently fired. 174 * @intr: HW interrupt handle 175 */ 176 void (*get_interrupt_statuses)( 177 struct dpu_hw_intr *intr); 178 179 /** 180 * clear_interrupt_status - Clears HW interrupt status based on given 181 * lookup IRQ index. 182 * @intr: HW interrupt handle 183 * @irq_idx: Lookup irq index return from irq_idx_lookup 184 */ 185 void (*clear_interrupt_status)( 186 struct dpu_hw_intr *intr, 187 int irq_idx); 188 189 /** 190 * clear_intr_status_nolock() - clears the HW interrupts without lock 191 * @intr: HW interrupt handle 192 * @irq_idx: Lookup irq index return from irq_idx_lookup 193 */ 194 void (*clear_intr_status_nolock)( 195 struct dpu_hw_intr *intr, 196 int irq_idx); 197 198 /** 199 * get_interrupt_status - Gets HW interrupt status, and clear if set, 200 * based on given lookup IRQ index. 201 * @intr: HW interrupt handle 202 * @irq_idx: Lookup irq index return from irq_idx_lookup 203 * @clear: True to clear irq after read 204 */ 205 u32 (*get_interrupt_status)( 206 struct dpu_hw_intr *intr, 207 int irq_idx, 208 bool clear); 209 210 /** 211 * get_valid_interrupts - Gets a mask of all valid interrupt sources 212 * within DPU. These are actually status bits 213 * within interrupt registers that specify the 214 * source of the interrupt in IRQs. For example, 215 * valid interrupt sources can be MDP, DSI, 216 * HDMI etc. 217 * @intr: HW interrupt handle 218 * @mask: Returning the interrupt source MASK 219 * @return: 0 for success, otherwise failure 220 */ 221 int (*get_valid_interrupts)( 222 struct dpu_hw_intr *intr, 223 uint32_t *mask); 224 }; 225 226 /** 227 * struct dpu_hw_intr: hw interrupts handling data structure 228 * @hw: virtual address mapping 229 * @ops: function pointer mapping for IRQ handling 230 * @cache_irq_mask: array of IRQ enable masks reg storage created during init 231 * @save_irq_status: array of IRQ status reg storage created during init 232 * @irq_idx_tbl_size: total number of irq_idx mapped in the hw_interrupts 233 * @irq_lock: spinlock for accessing IRQ resources 234 */ 235 struct dpu_hw_intr { 236 struct dpu_hw_blk_reg_map hw; 237 struct dpu_hw_intr_ops ops; 238 u32 *cache_irq_mask; 239 u32 *save_irq_status; 240 u32 irq_idx_tbl_size; 241 spinlock_t irq_lock; 242 }; 243 244 /** 245 * dpu_hw_intr_init(): Initializes the interrupts hw object 246 * @addr: mapped register io address of MDP 247 * @m : pointer to mdss catalog data 248 */ 249 struct dpu_hw_intr *dpu_hw_intr_init(void __iomem *addr, 250 struct dpu_mdss_cfg *m); 251 252 /** 253 * dpu_hw_intr_destroy(): Cleanup interrutps hw object 254 * @intr: pointer to interrupts hw object 255 */ 256 void dpu_hw_intr_destroy(struct dpu_hw_intr *intr); 257 #endif 258