0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef __MALIDP_HW_H__
0010 #define __MALIDP_HW_H__
0011
0012 #include <linux/bitops.h>
0013 #include "malidp_regs.h"
0014
0015 struct videomode;
0016 struct clk;
0017
0018
0019 enum {
0020 MALIDP_DE_BLOCK = 0,
0021 MALIDP_SE_BLOCK,
0022 MALIDP_DC_BLOCK
0023 };
0024
0025
0026 enum {
0027 DE_VIDEO1 = BIT(0),
0028 DE_GRAPHICS1 = BIT(1),
0029 DE_GRAPHICS2 = BIT(2),
0030 DE_VIDEO2 = BIT(3),
0031 DE_SMART = BIT(4),
0032 SE_MEMWRITE = BIT(5),
0033 };
0034
0035 enum rotation_features {
0036 ROTATE_NONE,
0037 ROTATE_ANY,
0038 ROTATE_COMPRESSED,
0039 };
0040
0041 struct malidp_format_id {
0042 u32 format;
0043 u8 layer;
0044 u8 id;
0045 };
0046
0047 #define MALIDP_INVALID_FORMAT_ID 0xff
0048
0049
0050
0051
0052
0053
0054
0055 struct malidp_irq_map {
0056 u32 irq_mask;
0057 u32 vsync_irq;
0058 u32 err_mask;
0059 };
0060
0061 struct malidp_layer {
0062 u16 id;
0063 u16 base;
0064 u16 ptr;
0065 u16 stride_offset;
0066 s16 yuv2rgb_offset;
0067 u16 mmu_ctrl_offset;
0068 enum rotation_features rot;
0069
0070 u16 afbc_decoder_offset;
0071 };
0072
0073 enum malidp_scaling_coeff_set {
0074 MALIDP_UPSCALING_COEFFS = 1,
0075 MALIDP_DOWNSCALING_1_5_COEFFS = 2,
0076 MALIDP_DOWNSCALING_2_COEFFS = 3,
0077 MALIDP_DOWNSCALING_2_75_COEFFS = 4,
0078 MALIDP_DOWNSCALING_4_COEFFS = 5,
0079 };
0080
0081 struct malidp_se_config {
0082 u8 scale_enable : 1;
0083 u8 enhancer_enable : 1;
0084 u8 hcoeff : 3;
0085 u8 vcoeff : 3;
0086 u8 plane_src_id;
0087 u16 input_w, input_h;
0088 u16 output_w, output_h;
0089 u32 h_init_phase, h_delta_phase;
0090 u32 v_init_phase, v_delta_phase;
0091 };
0092
0093
0094 #define MALIDP_REGMAP_HAS_CLEARIRQ BIT(0)
0095 #define MALIDP_DEVICE_AFBC_SUPPORT_SPLIT BIT(1)
0096 #define MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT BIT(2)
0097 #define MALIDP_DEVICE_AFBC_YUYV_USE_422_P2 BIT(3)
0098
0099 struct malidp_hw_regmap {
0100
0101
0102
0103 const u16 coeffs_base;
0104
0105 const u16 se_base;
0106
0107 const u16 dc_base;
0108
0109
0110 const u16 out_depth_base;
0111
0112
0113 const u8 features;
0114
0115
0116 const u8 n_layers;
0117 const struct malidp_layer *layers;
0118
0119 const struct malidp_irq_map de_irq_map;
0120 const struct malidp_irq_map se_irq_map;
0121 const struct malidp_irq_map dc_irq_map;
0122
0123
0124 const struct malidp_format_id *pixel_formats;
0125 const u8 n_pixel_formats;
0126
0127
0128 const u8 bus_align_bytes;
0129 };
0130
0131
0132
0133 #define MALIDP_DEVICE_LV_HAS_3_STRIDES BIT(0)
0134
0135 struct malidp_hw_device;
0136
0137
0138
0139
0140
0141 struct malidp_hw {
0142 const struct malidp_hw_regmap map;
0143
0144
0145
0146
0147 int (*query_hw)(struct malidp_hw_device *hwdev);
0148
0149
0150
0151
0152 void (*enter_config_mode)(struct malidp_hw_device *hwdev);
0153
0154
0155
0156
0157 void (*leave_config_mode)(struct malidp_hw_device *hwdev);
0158
0159
0160
0161
0162 bool (*in_config_mode)(struct malidp_hw_device *hwdev);
0163
0164
0165
0166
0167
0168
0169
0170
0171 void (*set_config_valid)(struct malidp_hw_device *hwdev, u8 value);
0172
0173
0174
0175
0176
0177 void (*modeset)(struct malidp_hw_device *hwdev, struct videomode *m);
0178
0179
0180
0181
0182
0183 int (*rotmem_required)(struct malidp_hw_device *hwdev, u16 w, u16 h,
0184 u32 fmt, bool has_modifier);
0185
0186 int (*se_set_scaling_coeffs)(struct malidp_hw_device *hwdev,
0187 struct malidp_se_config *se_config,
0188 struct malidp_se_config *old_config);
0189
0190 long (*se_calc_mclk)(struct malidp_hw_device *hwdev,
0191 struct malidp_se_config *se_config,
0192 struct videomode *vm);
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203 int (*enable_memwrite)(struct malidp_hw_device *hwdev, dma_addr_t *addrs,
0204 s32 *pitches, int num_planes, u16 w, u16 h, u32 fmt_id,
0205 const s16 *rgb2yuv_coeffs);
0206
0207
0208
0209
0210 void (*disable_memwrite)(struct malidp_hw_device *hwdev);
0211
0212 u8 features;
0213 };
0214
0215
0216 enum {
0217 MALIDP_500 = 0,
0218 MALIDP_550,
0219 MALIDP_650,
0220
0221 MALIDP_MAX_DEVICES
0222 };
0223
0224 extern const struct malidp_hw malidp_device[MALIDP_MAX_DEVICES];
0225
0226
0227
0228
0229 struct malidp_hw_device {
0230 struct malidp_hw *hw;
0231 void __iomem *regs;
0232
0233
0234 struct clk *pclk;
0235
0236 struct clk *aclk;
0237
0238 struct clk *mclk;
0239
0240 struct clk *pxlclk;
0241
0242 u8 min_line_size;
0243 u16 max_line_size;
0244 u32 output_color_depth;
0245
0246
0247 bool pm_suspended;
0248
0249
0250 u8 mw_state;
0251
0252
0253 u32 rotation_memory[2];
0254
0255
0256 u32 arqos_value;
0257 };
0258
0259 static inline u32 malidp_hw_read(struct malidp_hw_device *hwdev, u32 reg)
0260 {
0261 WARN_ON(hwdev->pm_suspended);
0262 return readl(hwdev->regs + reg);
0263 }
0264
0265 static inline void malidp_hw_write(struct malidp_hw_device *hwdev,
0266 u32 value, u32 reg)
0267 {
0268 WARN_ON(hwdev->pm_suspended);
0269 writel(value, hwdev->regs + reg);
0270 }
0271
0272 static inline void malidp_hw_setbits(struct malidp_hw_device *hwdev,
0273 u32 mask, u32 reg)
0274 {
0275 u32 data = malidp_hw_read(hwdev, reg);
0276
0277 data |= mask;
0278 malidp_hw_write(hwdev, data, reg);
0279 }
0280
0281 static inline void malidp_hw_clearbits(struct malidp_hw_device *hwdev,
0282 u32 mask, u32 reg)
0283 {
0284 u32 data = malidp_hw_read(hwdev, reg);
0285
0286 data &= ~mask;
0287 malidp_hw_write(hwdev, data, reg);
0288 }
0289
0290 static inline u32 malidp_get_block_base(struct malidp_hw_device *hwdev,
0291 u8 block)
0292 {
0293 switch (block) {
0294 case MALIDP_SE_BLOCK:
0295 return hwdev->hw->map.se_base;
0296 case MALIDP_DC_BLOCK:
0297 return hwdev->hw->map.dc_base;
0298 }
0299
0300 return 0;
0301 }
0302
0303 static inline void malidp_hw_disable_irq(struct malidp_hw_device *hwdev,
0304 u8 block, u32 irq)
0305 {
0306 u32 base = malidp_get_block_base(hwdev, block);
0307
0308 malidp_hw_clearbits(hwdev, irq, base + MALIDP_REG_MASKIRQ);
0309 }
0310
0311 static inline void malidp_hw_enable_irq(struct malidp_hw_device *hwdev,
0312 u8 block, u32 irq)
0313 {
0314 u32 base = malidp_get_block_base(hwdev, block);
0315
0316 malidp_hw_setbits(hwdev, irq, base + MALIDP_REG_MASKIRQ);
0317 }
0318
0319 int malidp_de_irq_init(struct drm_device *drm, int irq);
0320 void malidp_se_irq_hw_init(struct malidp_hw_device *hwdev);
0321 void malidp_de_irq_hw_init(struct malidp_hw_device *hwdev);
0322 void malidp_de_irq_fini(struct malidp_hw_device *hwdev);
0323 int malidp_se_irq_init(struct drm_device *drm, int irq);
0324 void malidp_se_irq_fini(struct malidp_hw_device *hwdev);
0325
0326 u8 malidp_hw_get_format_id(const struct malidp_hw_regmap *map,
0327 u8 layer_id, u32 format, bool has_modifier);
0328
0329 int malidp_format_get_bpp(u32 fmt);
0330
0331 static inline u8 malidp_hw_get_pitch_align(struct malidp_hw_device *hwdev, bool rotated)
0332 {
0333
0334
0335
0336
0337 if (hwdev->hw->map.bus_align_bytes == 8)
0338 return 8;
0339 else
0340 return hwdev->hw->map.bus_align_bytes << (rotated ? 2 : 0);
0341 }
0342
0343
0344 #define FP_1_00000 0x00010000
0345 #define FP_0_66667 0x0000AAAA
0346 #define FP_0_50000 0x00008000
0347 #define FP_0_36363 0x00005D17
0348 #define FP_0_25000 0x00004000
0349
0350 static inline enum malidp_scaling_coeff_set
0351 malidp_se_select_coeffs(u32 upscale_factor)
0352 {
0353 return (upscale_factor >= FP_1_00000) ? MALIDP_UPSCALING_COEFFS :
0354 (upscale_factor >= FP_0_66667) ? MALIDP_DOWNSCALING_1_5_COEFFS :
0355 (upscale_factor >= FP_0_50000) ? MALIDP_DOWNSCALING_2_COEFFS :
0356 (upscale_factor >= FP_0_36363) ? MALIDP_DOWNSCALING_2_75_COEFFS :
0357 MALIDP_DOWNSCALING_4_COEFFS;
0358 }
0359
0360 #undef FP_0_25000
0361 #undef FP_0_36363
0362 #undef FP_0_50000
0363 #undef FP_0_66667
0364 #undef FP_1_00000
0365
0366 static inline void malidp_se_set_enh_coeffs(struct malidp_hw_device *hwdev)
0367 {
0368 static const s32 enhancer_coeffs[] = {
0369 -8, -8, -8, -8, 128, -8, -8, -8, -8
0370 };
0371 u32 val = MALIDP_SE_SET_ENH_LIMIT_LOW(MALIDP_SE_ENH_LOW_LEVEL) |
0372 MALIDP_SE_SET_ENH_LIMIT_HIGH(MALIDP_SE_ENH_HIGH_LEVEL);
0373 u32 image_enh = hwdev->hw->map.se_base +
0374 ((hwdev->hw->map.features & MALIDP_REGMAP_HAS_CLEARIRQ) ?
0375 0x10 : 0xC) + MALIDP_SE_IMAGE_ENH;
0376 u32 enh_coeffs = image_enh + MALIDP_SE_ENH_COEFF0;
0377 int i;
0378
0379 malidp_hw_write(hwdev, val, image_enh);
0380 for (i = 0; i < ARRAY_SIZE(enhancer_coeffs); ++i)
0381 malidp_hw_write(hwdev, enhancer_coeffs[i], enh_coeffs + i * 4);
0382 }
0383
0384
0385
0386
0387
0388
0389 #define MALIDP_BGND_COLOR_R 0x000
0390 #define MALIDP_BGND_COLOR_G 0x000
0391 #define MALIDP_BGND_COLOR_B 0x000
0392
0393 #define MALIDP_COLORADJ_NUM_COEFFS 12
0394 #define MALIDP_COEFFTAB_NUM_COEFFS 64
0395
0396 #define MALIDP_GAMMA_LUT_SIZE 4096
0397
0398 #define AFBC_SIZE_MASK AFBC_FORMAT_MOD_BLOCK_SIZE_MASK
0399 #define AFBC_SIZE_16X16 AFBC_FORMAT_MOD_BLOCK_SIZE_16x16
0400 #define AFBC_YTR AFBC_FORMAT_MOD_YTR
0401 #define AFBC_SPARSE AFBC_FORMAT_MOD_SPARSE
0402 #define AFBC_CBR AFBC_FORMAT_MOD_CBR
0403 #define AFBC_SPLIT AFBC_FORMAT_MOD_SPLIT
0404 #define AFBC_TILED AFBC_FORMAT_MOD_TILED
0405 #define AFBC_SC AFBC_FORMAT_MOD_SC
0406
0407 #define AFBC_MOD_VALID_BITS (AFBC_SIZE_MASK | AFBC_YTR | AFBC_SPLIT | \
0408 AFBC_SPARSE | AFBC_CBR | AFBC_TILED | AFBC_SC)
0409
0410 extern const u64 malidp_format_modifiers[];
0411
0412 #endif