1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Support for Intel Camera Imaging ISP subsystem. 4 * Copyright (c) 2010-2015, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 */ 15 16 /* The name "gdc.h is already taken" */ 17 #include "gdc_device.h" 18 19 #include "device_access.h" 20 21 #include "assert_support.h" 22 23 /* 24 * Local function declarations 25 */ 26 static inline void gdc_reg_store( 27 const gdc_ID_t ID, 28 const unsigned int reg, 29 const hrt_data value); 30 31 static inline hrt_data gdc_reg_load( 32 const gdc_ID_t ID, 33 const unsigned int reg); 34 35 #ifndef __INLINE_GDC__ 36 #include "gdc_private.h" 37 #endif /* __INLINE_GDC__ */ 38 39 /* 40 * Exported function implementations 41 */ 42 void gdc_lut_store( 43 const gdc_ID_t ID, 44 const int data[4][HRT_GDC_N]) 45 { 46 unsigned int i, lut_offset = HRT_GDC_LUT_IDX; 47 48 assert(ID < N_GDC_ID); 49 assert(HRT_GDC_LUT_COEFF_OFFSET <= (4 * sizeof(hrt_data))); 50 51 for (i = 0; i < HRT_GDC_N; i++) { 52 hrt_data entry_0 = data[0][i] & HRT_GDC_BCI_COEF_MASK; 53 hrt_data entry_1 = data[1][i] & HRT_GDC_BCI_COEF_MASK; 54 hrt_data entry_2 = data[2][i] & HRT_GDC_BCI_COEF_MASK; 55 hrt_data entry_3 = data[3][i] & HRT_GDC_BCI_COEF_MASK; 56 57 hrt_data word_0 = entry_0 | 58 (entry_1 << HRT_GDC_LUT_COEFF_OFFSET); 59 hrt_data word_1 = entry_2 | 60 (entry_3 << HRT_GDC_LUT_COEFF_OFFSET); 61 62 gdc_reg_store(ID, lut_offset++, word_0); 63 gdc_reg_store(ID, lut_offset++, word_1); 64 } 65 return; 66 } 67 68 /* 69 * Input LUT format: 70 * c0[0-1023], c1[0-1023], c2[0-1023] c3[0-1023] 71 * 72 * Output LUT format (interleaved): 73 * c0[0], c1[0], c2[0], c3[0], c0[1], c1[1], c2[1], c3[1], .... 74 * c0[1023], c1[1023], c2[1023], c3[1023] 75 * 76 * The first format needs c0[0], c1[0] (which are 1024 words apart) 77 * to program gdc LUT registers. This makes it difficult to do piecemeal 78 * reads in SP side gdc_lut_store 79 * 80 * Interleaved format allows use of contiguous bytes to store into 81 * gdc LUT registers. 82 * 83 * See gdc_lut_store() definition in host/gdc.c vs sp/gdc_private.h 84 * 85 */ 86 void gdc_lut_convert_to_isp_format(const int in_lut[4][HRT_GDC_N], 87 int out_lut[4][HRT_GDC_N]) 88 { 89 unsigned int i; 90 int *out = (int *)out_lut; 91 92 for (i = 0; i < HRT_GDC_N; i++) { 93 out[0] = in_lut[0][i]; 94 out[1] = in_lut[1][i]; 95 out[2] = in_lut[2][i]; 96 out[3] = in_lut[3][i]; 97 out += 4; 98 } 99 } 100 101 int gdc_get_unity( 102 const gdc_ID_t ID) 103 { 104 assert(ID < N_GDC_ID); 105 (void)ID; 106 return (int)(1UL << HRT_GDC_FRAC_BITS); 107 } 108 109 /* 110 * Local function implementations 111 */ 112 static inline void gdc_reg_store( 113 const gdc_ID_t ID, 114 const unsigned int reg, 115 const hrt_data value) 116 { 117 ia_css_device_store_uint32(GDC_BASE[ID] + reg * sizeof(hrt_data), value); 118 return; 119 } 120 121 static inline hrt_data gdc_reg_load( 122 const gdc_ID_t ID, 123 const unsigned int reg) 124 { 125 return ia_css_device_load_uint32(GDC_BASE[ID] + reg * sizeof(hrt_data)); 126 } 127