1/* 2 * Coda multi-standard codec IP 3 * 4 * Copyright (C) 2014 Philipp Zabel, Pengutronix 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 */ 11 12#include <linux/bitops.h> 13#include "coda.h" 14 15#define XY2_INVERT BIT(7) 16#define XY2_ZERO BIT(6) 17#define XY2_TB_XOR BIT(5) 18#define XY2_XYSEL BIT(4) 19#define XY2_Y (1 << 4) 20#define XY2_X (0 << 4) 21 22#define XY2(luma_sel, luma_bit, chroma_sel, chroma_bit) \ 23 (((XY2_##luma_sel) | (luma_bit)) << 8 | \ 24 (XY2_##chroma_sel) | (chroma_bit)) 25 26static const u16 xy2ca_zero_map[16] = { 27 XY2(ZERO, 0, ZERO, 0), 28 XY2(ZERO, 0, ZERO, 0), 29 XY2(ZERO, 0, ZERO, 0), 30 XY2(ZERO, 0, ZERO, 0), 31 XY2(ZERO, 0, ZERO, 0), 32 XY2(ZERO, 0, ZERO, 0), 33 XY2(ZERO, 0, ZERO, 0), 34 XY2(ZERO, 0, ZERO, 0), 35 XY2(ZERO, 0, ZERO, 0), 36 XY2(ZERO, 0, ZERO, 0), 37 XY2(ZERO, 0, ZERO, 0), 38 XY2(ZERO, 0, ZERO, 0), 39 XY2(ZERO, 0, ZERO, 0), 40 XY2(ZERO, 0, ZERO, 0), 41 XY2(ZERO, 0, ZERO, 0), 42 XY2(ZERO, 0, ZERO, 0), 43}; 44 45static const u16 xy2ca_tiled_map[16] = { 46 XY2(Y, 0, Y, 0), 47 XY2(Y, 1, Y, 1), 48 XY2(Y, 2, Y, 2), 49 XY2(Y, 3, X, 3), 50 XY2(X, 3, ZERO, 0), 51 XY2(ZERO, 0, ZERO, 0), 52 XY2(ZERO, 0, ZERO, 0), 53 XY2(ZERO, 0, ZERO, 0), 54 XY2(ZERO, 0, ZERO, 0), 55 XY2(ZERO, 0, ZERO, 0), 56 XY2(ZERO, 0, ZERO, 0), 57 XY2(ZERO, 0, ZERO, 0), 58 XY2(ZERO, 0, ZERO, 0), 59 XY2(ZERO, 0, ZERO, 0), 60 XY2(ZERO, 0, ZERO, 0), 61 XY2(ZERO, 0, ZERO, 0), 62}; 63 64/* 65 * RA[15:0], CA[15:8] are hardwired to contain the 24-bit macroblock 66 * start offset (macroblock size is 16x16 for luma, 16x8 for chroma). 67 * Bits CA[4:0] are set using XY2CA above. BA[3:0] seems to be unused. 68 */ 69 70#define RBC_CA (0 << 4) 71#define RBC_BA (1 << 4) 72#define RBC_RA (2 << 4) 73#define RBC_ZERO (3 << 4) 74 75#define RBC(luma_sel, luma_bit, chroma_sel, chroma_bit) \ 76 (((RBC_##luma_sel) | (luma_bit)) << 6 | \ 77 (RBC_##chroma_sel) | (chroma_bit)) 78 79static const u16 rbc2axi_tiled_map[32] = { 80 RBC(ZERO, 0, ZERO, 0), 81 RBC(ZERO, 0, ZERO, 0), 82 RBC(ZERO, 0, ZERO, 0), 83 RBC(CA, 0, CA, 0), 84 RBC(CA, 1, CA, 1), 85 RBC(CA, 2, CA, 2), 86 RBC(CA, 3, CA, 3), 87 RBC(CA, 4, CA, 8), 88 RBC(CA, 8, CA, 9), 89 RBC(CA, 9, CA, 10), 90 RBC(CA, 10, CA, 11), 91 RBC(CA, 11, CA, 12), 92 RBC(CA, 12, CA, 13), 93 RBC(CA, 13, CA, 14), 94 RBC(CA, 14, CA, 15), 95 RBC(CA, 15, RA, 0), 96 RBC(RA, 0, RA, 1), 97 RBC(RA, 1, RA, 2), 98 RBC(RA, 2, RA, 3), 99 RBC(RA, 3, RA, 4), 100 RBC(RA, 4, RA, 5), 101 RBC(RA, 5, RA, 6), 102 RBC(RA, 6, RA, 7), 103 RBC(RA, 7, RA, 8), 104 RBC(RA, 8, RA, 9), 105 RBC(RA, 9, RA, 10), 106 RBC(RA, 10, RA, 11), 107 RBC(RA, 11, RA, 12), 108 RBC(RA, 12, RA, 13), 109 RBC(RA, 13, RA, 14), 110 RBC(RA, 14, RA, 15), 111 RBC(RA, 15, ZERO, 0), 112}; 113 114void coda_set_gdi_regs(struct coda_ctx *ctx) 115{ 116 struct coda_dev *dev = ctx->dev; 117 const u16 *xy2ca_map; 118 u32 xy2rbc_config; 119 int i; 120 121 switch (ctx->tiled_map_type) { 122 case GDI_LINEAR_FRAME_MAP: 123 default: 124 xy2ca_map = xy2ca_zero_map; 125 xy2rbc_config = 0; 126 break; 127 case GDI_TILED_FRAME_MB_RASTER_MAP: 128 xy2ca_map = xy2ca_tiled_map; 129 xy2rbc_config = CODA9_XY2RBC_TILED_MAP | 130 CODA9_XY2RBC_CA_INC_HOR | 131 (16 - 1) << 12 | (8 - 1) << 4; 132 break; 133 } 134 135 for (i = 0; i < 16; i++) 136 coda_write(dev, xy2ca_map[i], 137 CODA9_GDI_XY2_CAS_0 + 4 * i); 138 for (i = 0; i < 4; i++) 139 coda_write(dev, XY2(ZERO, 0, ZERO, 0), 140 CODA9_GDI_XY2_BA_0 + 4 * i); 141 for (i = 0; i < 16; i++) 142 coda_write(dev, XY2(ZERO, 0, ZERO, 0), 143 CODA9_GDI_XY2_RAS_0 + 4 * i); 144 coda_write(dev, xy2rbc_config, CODA9_GDI_XY2_RBC_CONFIG); 145 if (xy2rbc_config) { 146 for (i = 0; i < 32; i++) 147 coda_write(dev, rbc2axi_tiled_map[i], 148 CODA9_GDI_RBC2_AXI_0 + 4 * i); 149 } 150} 151