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 SE_MEMWRITE = BIT(5), 37 }; 38 39 struct malidp_format_id { 40 u32 format; /* DRM fourcc */ 41 u8 layer; /* bitmask of layers supporting it */ 42 u8 id; /* used internally */ 43 }; 44 45 #define MALIDP_INVALID_FORMAT_ID 0xff 46 47 /* 48 * hide the differences between register maps 49 * by using a common structure to hold the 50 * base register offsets 51 */ 52 53 struct malidp_irq_map { 54 u32 irq_mask; /* mask of IRQs that can be enabled in the block */ 55 u32 vsync_irq; /* IRQ bit used for signaling during VSYNC */ 56 u32 err_mask; /* mask of bits that represent errors */ 57 }; 58 59 struct malidp_layer { 60 u16 id; /* layer ID */ 61 u16 base; /* address offset for the register bank */ 62 u16 ptr; /* address offset for the pointer register */ 63 u16 stride_offset; /* offset to the first stride register. */ 64 s16 yuv2rgb_offset; /* offset to the YUV->RGB matrix entries */ 65 }; 66 67 enum malidp_scaling_coeff_set { 68 MALIDP_UPSCALING_COEFFS = 1, 69 MALIDP_DOWNSCALING_1_5_COEFFS = 2, 70 MALIDP_DOWNSCALING_2_COEFFS = 3, 71 MALIDP_DOWNSCALING_2_75_COEFFS = 4, 72 MALIDP_DOWNSCALING_4_COEFFS = 5, 73 }; 74 75 struct malidp_se_config { 76 u8 scale_enable : 1; 77 u8 enhancer_enable : 1; 78 u8 hcoeff : 3; 79 u8 vcoeff : 3; 80 u8 plane_src_id; 81 u16 input_w, input_h; 82 u16 output_w, output_h; 83 u32 h_init_phase, h_delta_phase; 84 u32 v_init_phase, v_delta_phase; 85 }; 86 87 /* regmap features */ 88 #define MALIDP_REGMAP_HAS_CLEARIRQ (1 << 0) 89 90 struct malidp_hw_regmap { 91 /* address offset of the DE register bank */ 92 /* is always 0x0000 */ 93 /* address offset of the DE coefficients registers */ 94 const u16 coeffs_base; 95 /* address offset of the SE registers bank */ 96 const u16 se_base; 97 /* address offset of the DC registers bank */ 98 const u16 dc_base; 99 100 /* address offset for the output depth register */ 101 const u16 out_depth_base; 102 103 /* bitmap with register map features */ 104 const u8 features; 105 106 /* list of supported layers */ 107 const u8 n_layers; 108 const struct malidp_layer *layers; 109 110 const struct malidp_irq_map de_irq_map; 111 const struct malidp_irq_map se_irq_map; 112 const struct malidp_irq_map dc_irq_map; 113 114 /* list of supported pixel formats for each layer */ 115 const struct malidp_format_id *pixel_formats; 116 const u8 n_pixel_formats; 117 118 /* pitch alignment requirement in bytes */ 119 const u8 bus_align_bytes; 120 }; 121 122 /* device features */ 123 /* Unlike DP550/650, DP500 has 3 stride registers in its video layer. */ 124 #define MALIDP_DEVICE_LV_HAS_3_STRIDES BIT(0) 125 126 struct malidp_hw_device; 127 128 /* 129 * Static structure containing hardware specific data and pointers to 130 * functions that behave differently between various versions of the IP. 131 */ 132 struct malidp_hw { 133 const struct malidp_hw_regmap map; 134 135 /* 136 * Validate the driver instance against the hardware bits 137 */ 138 int (*query_hw)(struct malidp_hw_device *hwdev); 139 140 /* 141 * Set the hardware into config mode, ready to accept mode changes 142 */ 143 void (*enter_config_mode)(struct malidp_hw_device *hwdev); 144 145 /* 146 * Tell hardware to exit configuration mode 147 */ 148 void (*leave_config_mode)(struct malidp_hw_device *hwdev); 149 150 /* 151 * Query if hardware is in configuration mode 152 */ 153 bool (*in_config_mode)(struct malidp_hw_device *hwdev); 154 155 /* 156 * Set/clear configuration valid flag for hardware parameters that can 157 * be changed outside the configuration mode to the given value. 158 * Hardware will use the new settings when config valid is set, 159 * after the end of the current buffer scanout, and will ignore 160 * any new values for those parameters if config valid flag is cleared 161 */ 162 void (*set_config_valid)(struct malidp_hw_device *hwdev, u8 value); 163 164 /* 165 * Set a new mode in hardware. Requires the hardware to be in 166 * configuration mode before this function is called. 167 */ 168 void (*modeset)(struct malidp_hw_device *hwdev, struct videomode *m); 169 170 /* 171 * Calculate the required rotation memory given the active area 172 * and the buffer format. 173 */ 174 int (*rotmem_required)(struct malidp_hw_device *hwdev, u16 w, u16 h, u32 fmt); 175 176 int (*se_set_scaling_coeffs)(struct malidp_hw_device *hwdev, 177 struct malidp_se_config *se_config, 178 struct malidp_se_config *old_config); 179 180 long (*se_calc_mclk)(struct malidp_hw_device *hwdev, 181 struct malidp_se_config *se_config, 182 struct videomode *vm); 183 /* 184 * Enable writing to memory the content of the next frame 185 * @param hwdev - malidp_hw_device structure containing the HW description 186 * @param addrs - array of addresses for each plane 187 * @param pitches - array of pitches for each plane 188 * @param num_planes - number of planes to be written 189 * @param w - width of the output frame 190 * @param h - height of the output frame 191 * @param fmt_id - internal format ID of output buffer 192 */ 193 int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs, 194 s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id, 195 const s16 *rgb2yuv_coeffs); 196 197 /* 198 * Disable the writing to memory of the next frame's content. 199 */ 200 void (*disable_memwrite)(struct malidp_hw_device *hwdev); 201 202 u8 features; 203 }; 204 205 /* Supported variants of the hardware */ 206 enum { 207 MALIDP_500 = 0, 208 MALIDP_550, 209 MALIDP_650, 210 /* keep the next entry last */ 211 MALIDP_MAX_DEVICES 212 }; 213 214 extern const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES]; 215 216 /* 217 * Structure used by the driver during runtime operation. 218 */ 219 struct malidp_hw_device { 220 struct malidp_hw *hw; 221 void __iomem *regs; 222 223 /* APB clock */ 224 struct clk *pclk; 225 /* AXI clock */ 226 struct clk *aclk; 227 /* main clock for display core */ 228 struct clk *mclk; 229 /* pixel clock for display core */ 230 struct clk *pxlclk; 231 232 u8 min_line_size; 233 u16 max_line_size; 234 u32 output_color_depth; 235 236 /* track the device PM state */ 237 bool pm_suspended; 238 239 /* track the SE memory writeback state */ 240 u8 mw_state; 241 242 /* size of memory used for rotating layers, up to two banks available */ 243 u32 rotation_memory[2]; 244 }; 245 246 static inline u32 malidp_hw_read(struct malidp_hw_device *hwdev, u32 reg) 247 { 248 WARN_ON(hwdev->pm_suspended); 249 return readl(hwdev->regs + reg); 250 } 251 252 static inline void malidp_hw_write(struct malidp_hw_device *hwdev, 253 u32 value, u32 reg) 254 { 255 WARN_ON(hwdev->pm_suspended); 256 writel(value, hwdev->regs + reg); 257 } 258 259 static inline void malidp_hw_setbits(struct malidp_hw_device *hwdev, 260 u32 mask, u32 reg) 261 { 262 u32 data = malidp_hw_read(hwdev, reg); 263 264 data |= mask; 265 malidp_hw_write(hwdev, data, reg); 266 } 267 268 static inline void malidp_hw_clearbits(struct malidp_hw_device *hwdev, 269 u32 mask, u32 reg) 270 { 271 u32 data = malidp_hw_read(hwdev, reg); 272 273 data &= ~mask; 274 malidp_hw_write(hwdev, data, reg); 275 } 276 277 static inline u32 malidp_get_block_base(struct malidp_hw_device *hwdev, 278 u8 block) 279 { 280 switch (block) { 281 case MALIDP_SE_BLOCK: 282 return hwdev->hw->map.se_base; 283 case MALIDP_DC_BLOCK: 284 return hwdev->hw->map.dc_base; 285 } 286 287 return 0; 288 } 289 290 static inline void malidp_hw_disable_irq(struct malidp_hw_device *hwdev, 291 u8 block, u32 irq) 292 { 293 u32 base = malidp_get_block_base(hwdev, block); 294 295 malidp_hw_clearbits(hwdev, irq, base + MALIDP_REG_MASKIRQ); 296 } 297 298 static inline void malidp_hw_enable_irq(struct malidp_hw_device *hwdev, 299 u8 block, u32 irq) 300 { 301 u32 base = malidp_get_block_base(hwdev, block); 302 303 malidp_hw_setbits(hwdev, irq, base + MALIDP_REG_MASKIRQ); 304 } 305 306 int malidp_de_irq_init(struct drm_device *drm, int irq); 307 void malidp_se_irq_hw_init(struct malidp_hw_device *hwdev); 308 void malidp_de_irq_hw_init(struct malidp_hw_device *hwdev); 309 void malidp_de_irq_fini(struct malidp_hw_device *hwdev); 310 int malidp_se_irq_init(struct drm_device *drm, int irq); 311 void malidp_se_irq_fini(struct malidp_hw_device *hwdev); 312 313 u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map, 314 u8 layer_id, u32 format); 315 316 static inline u8 malidp_hw_get_pitch_align(struct malidp_hw_device *hwdev, bool rotated) 317 { 318 /* 319 * only hardware that cannot do 8 bytes bus alignments have further 320 * constraints on rotated planes 321 */ 322 if (hwdev->hw->map.bus_align_bytes == 8) 323 return 8; 324 else 325 return hwdev->hw->map.bus_align_bytes << (rotated ? 2 : 0); 326 } 327 328 /* U16.16 */ 329 #define FP_1_00000 0x00010000 /* 1.0 */ 330 #define FP_0_66667 0x0000AAAA /* 0.6667 = 1/1.5 */ 331 #define FP_0_50000 0x00008000 /* 0.5 = 1/2 */ 332 #define FP_0_36363 0x00005D17 /* 0.36363 = 1/2.75 */ 333 #define FP_0_25000 0x00004000 /* 0.25 = 1/4 */ 334 335 static inline enum malidp_scaling_coeff_set 336 malidp_se_select_coeffs(u32 upscale_factor) 337 { 338 return (upscale_factor >= FP_1_00000) ? MALIDP_UPSCALING_COEFFS : 339 (upscale_factor >= FP_0_66667) ? MALIDP_DOWNSCALING_1_5_COEFFS : 340 (upscale_factor >= FP_0_50000) ? MALIDP_DOWNSCALING_2_COEFFS : 341 (upscale_factor >= FP_0_36363) ? MALIDP_DOWNSCALING_2_75_COEFFS : 342 MALIDP_DOWNSCALING_4_COEFFS; 343 } 344 345 #undef FP_0_25000 346 #undef FP_0_36363 347 #undef FP_0_50000 348 #undef FP_0_66667 349 #undef FP_1_00000 350 351 static inline void malidp_se_set_enh_coeffs(struct malidp_hw_device *hwdev) 352 { 353 static const s32 enhancer_coeffs[] = { 354 -8, -8, -8, -8, 128, -8, -8, -8, -8 355 }; 356 u32 val = MALIDP_SE_SET_ENH_LIMIT_LOW(MALIDP_SE_ENH_LOW_LEVEL) | 357 MALIDP_SE_SET_ENH_LIMIT_HIGH(MALIDP_SE_ENH_HIGH_LEVEL); 358 u32 image_enh = hwdev->hw->map.se_base + 359 ((hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ? 360 0x10 : 0xC) + MALIDP_SE_IMAGE_ENH; 361 u32 enh_coeffs = image_enh + MALIDP_SE_ENH_COEFF0; 362 int i; 363 364 malidp_hw_write(hwdev, val, image_enh); 365 for (i = 0; i < ARRAY_SIZE(enhancer_coeffs); ++i) 366 malidp_hw_write(hwdev, enhancer_coeffs[i], enh_coeffs + i * 4); 367 } 368 369 /* 370 * background color components are defined as 12bits values, 371 * they will be shifted right when stored on hardware that 372 * supports only 8bits per channel 373 */ 374 #define MALIDP_BGND_COLOR_R 0x000 375 #define MALIDP_BGND_COLOR_G 0x000 376 #define MALIDP_BGND_COLOR_B 0x000 377 378 #define MALIDP_COLORADJ_NUM_COEFFS 12 379 #define MALIDP_COEFFTAB_NUM_COEFFS 64 380 381 #define MALIDP_GAMMA_LUT_SIZE 4096 382 383 #endif /* __MALIDP_HW_H__ */ 384