1 /* 2 * 3 * (C) COPYRIGHT 2013-2016 ARM Limited. All rights reserved. 4 * 5 * This program is free software and is provided to you under the terms of the 6 * GNU General Public License version 2 as published by the Free Software 7 * Foundation, and any use by you of this program is subject to the terms 8 * of such GNU licence. 9 * 10 * ARM Mali DP hardware manipulation routines. 11 */ 12 13 #ifndef __MALIDP_HW_H__ 14 #define __MALIDP_HW_H__ 15 16 #include <linux/bitops.h> 17 #include "malidp_regs.h" 18 19 struct videomode; 20 struct clk; 21 22 /* Mali DP IP blocks */ 23 enum { 24 MALIDP_DE_BLOCK = 0, 25 MALIDP_SE_BLOCK, 26 MALIDP_DC_BLOCK 27 }; 28 29 /* Mali DP layer IDs */ 30 enum { 31 DE_VIDEO1 = BIT(0), 32 DE_GRAPHICS1 = BIT(1), 33 DE_GRAPHICS2 = BIT(2), /* used only in DP500 */ 34 DE_VIDEO2 = BIT(3), 35 DE_SMART = BIT(4), 36 }; 37 38 struct malidp_input_format { 39 u32 format; /* DRM fourcc */ 40 u8 layer; /* bitmask of layers supporting it */ 41 u8 id; /* used internally */ 42 }; 43 44 #define MALIDP_INVALID_FORMAT_ID 0xff 45 46 /* 47 * hide the differences between register maps 48 * by using a common structure to hold the 49 * base register offsets 50 */ 51 52 struct malidp_irq_map { 53 u32 irq_mask; /* mask of IRQs that can be enabled in the block */ 54 u32 vsync_irq; /* IRQ bit used for signaling during VSYNC */ 55 }; 56 57 struct malidp_layer { 58 u16 id; /* layer ID */ 59 u16 base; /* address offset for the register bank */ 60 u16 ptr; /* address offset for the pointer register */ 61 }; 62 63 /* regmap features */ 64 #define MALIDP_REGMAP_HAS_CLEARIRQ (1 << 0) 65 66 struct malidp_hw_regmap { 67 /* address offset of the DE register bank */ 68 /* is always 0x0000 */ 69 /* address offset of the SE registers bank */ 70 const u16 se_base; 71 /* address offset of the DC registers bank */ 72 const u16 dc_base; 73 74 /* address offset for the output depth register */ 75 const u16 out_depth_base; 76 77 /* bitmap with register map features */ 78 const u8 features; 79 80 /* list of supported layers */ 81 const u8 n_layers; 82 const struct malidp_layer *layers; 83 84 const struct malidp_irq_map de_irq_map; 85 const struct malidp_irq_map se_irq_map; 86 const struct malidp_irq_map dc_irq_map; 87 88 /* list of supported input formats for each layer */ 89 const struct malidp_input_format *input_formats; 90 const u8 n_input_formats; 91 92 /* pitch alignment requirement in bytes */ 93 const u8 bus_align_bytes; 94 }; 95 96 struct malidp_hw_device { 97 const struct malidp_hw_regmap map; 98 void __iomem *regs; 99 100 /* APB clock */ 101 struct clk *pclk; 102 /* AXI clock */ 103 struct clk *aclk; 104 /* main clock for display core */ 105 struct clk *mclk; 106 /* pixel clock for display core */ 107 struct clk *pxlclk; 108 109 /* 110 * Validate the driver instance against the hardware bits 111 */ 112 int (*query_hw)(struct malidp_hw_device *hwdev); 113 114 /* 115 * Set the hardware into config mode, ready to accept mode changes 116 */ 117 void (*enter_config_mode)(struct malidp_hw_device *hwdev); 118 119 /* 120 * Tell hardware to exit configuration mode 121 */ 122 void (*leave_config_mode)(struct malidp_hw_device *hwdev); 123 124 /* 125 * Query if hardware is in configuration mode 126 */ 127 bool (*in_config_mode)(struct malidp_hw_device *hwdev); 128 129 /* 130 * Set configuration valid flag for hardware parameters that can 131 * be changed outside the configuration mode. Hardware will use 132 * the new settings when config valid is set after the end of the 133 * current buffer scanout 134 */ 135 void (*set_config_valid)(struct malidp_hw_device *hwdev); 136 137 /* 138 * Set a new mode in hardware. Requires the hardware to be in 139 * configuration mode before this function is called. 140 */ 141 void (*modeset)(struct malidp_hw_device *hwdev, struct videomode *m); 142 143 /* 144 * Calculate the required rotation memory given the active area 145 * and the buffer format. 146 */ 147 int (*rotmem_required)(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt); 148 149 u8 features; 150 151 u8 min_line_size; 152 u16 max_line_size; 153 154 /* size of memory used for rotating layers, up to two banks available */ 155 u32 rotation_memory[2]; 156 }; 157 158 /* Supported variants of the hardware */ 159 enum { 160 MALIDP_500 = 0, 161 MALIDP_550, 162 MALIDP_650, 163 /* keep the next entry last */ 164 MALIDP_MAX_DEVICES 165 }; 166 167 extern const struct malidp_hw_device malidp_device[MALIDP_MAX_DEVICES]; 168 169 static inline u32 malidp_hw_read(struct malidp_hw_device *hwdev, u32 reg) 170 { 171 return readl(hwdev->regs + reg); 172 } 173 174 static inline void malidp_hw_write(struct malidp_hw_device *hwdev, 175 u32 value, u32 reg) 176 { 177 writel(value, hwdev->regs + reg); 178 } 179 180 static inline void malidp_hw_setbits(struct malidp_hw_device *hwdev, 181 u32 mask, u32 reg) 182 { 183 u32 data = malidp_hw_read(hwdev, reg); 184 185 data |= mask; 186 malidp_hw_write(hwdev, data, reg); 187 } 188 189 static inline void malidp_hw_clearbits(struct malidp_hw_device *hwdev, 190 u32 mask, u32 reg) 191 { 192 u32 data = malidp_hw_read(hwdev, reg); 193 194 data &= ~mask; 195 malidp_hw_write(hwdev, data, reg); 196 } 197 198 static inline u32 malidp_get_block_base(struct malidp_hw_device *hwdev, 199 u8 block) 200 { 201 switch (block) { 202 case MALIDP_SE_BLOCK: 203 return hwdev->map.se_base; 204 case MALIDP_DC_BLOCK: 205 return hwdev->map.dc_base; 206 } 207 208 return 0; 209 } 210 211 static inline void malidp_hw_disable_irq(struct malidp_hw_device *hwdev, 212 u8 block, u32 irq) 213 { 214 u32 base = malidp_get_block_base(hwdev, block); 215 216 malidp_hw_clearbits(hwdev, irq, base + MALIDP_REG_MASKIRQ); 217 } 218 219 static inline void malidp_hw_enable_irq(struct malidp_hw_device *hwdev, 220 u8 block, u32 irq) 221 { 222 u32 base = malidp_get_block_base(hwdev, block); 223 224 malidp_hw_setbits(hwdev, irq, base + MALIDP_REG_MASKIRQ); 225 } 226 227 int malidp_de_irq_init(struct drm_device *drm, int irq); 228 void malidp_de_irq_fini(struct drm_device *drm); 229 int malidp_se_irq_init(struct drm_device *drm, int irq); 230 void malidp_se_irq_fini(struct drm_device *drm); 231 232 u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map, 233 u8 layer_id, u32 format); 234 235 static inline bool malidp_hw_pitch_valid(struct malidp_hw_device *hwdev, 236 unsigned int pitch) 237 { 238 return !(pitch & (hwdev->map.bus_align_bytes - 1)); 239 } 240 241 /* 242 * background color components are defined as 12bits values, 243 * they will be shifted right when stored on hardware that 244 * supports only 8bits per channel 245 */ 246 #define MALIDP_BGND_COLOR_R 0x000 247 #define MALIDP_BGND_COLOR_G 0x000 248 #define MALIDP_BGND_COLOR_B 0x000 249 250 #endif /* __MALIDP_HW_H__ */ 251