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 #ifndef __INLINE_GDC__
32 #include "gdc_private.h"
33 #endif /* __INLINE_GDC__ */
34
35 /*
36 * Exported function implementations
37 */
gdc_lut_store(const gdc_ID_t ID,const int data[4][HRT_GDC_N])38 void gdc_lut_store(
39 const gdc_ID_t ID,
40 const int data[4][HRT_GDC_N])
41 {
42 unsigned int i, lut_offset = HRT_GDC_LUT_IDX;
43
44 assert(ID < N_GDC_ID);
45 assert(HRT_GDC_LUT_COEFF_OFFSET <= (4 * sizeof(hrt_data)));
46
47 for (i = 0; i < HRT_GDC_N; i++) {
48 hrt_data entry_0 = data[0][i] & HRT_GDC_BCI_COEF_MASK;
49 hrt_data entry_1 = data[1][i] & HRT_GDC_BCI_COEF_MASK;
50 hrt_data entry_2 = data[2][i] & HRT_GDC_BCI_COEF_MASK;
51 hrt_data entry_3 = data[3][i] & HRT_GDC_BCI_COEF_MASK;
52
53 hrt_data word_0 = entry_0 |
54 (entry_1 << HRT_GDC_LUT_COEFF_OFFSET);
55 hrt_data word_1 = entry_2 |
56 (entry_3 << HRT_GDC_LUT_COEFF_OFFSET);
57
58 gdc_reg_store(ID, lut_offset++, word_0);
59 gdc_reg_store(ID, lut_offset++, word_1);
60 }
61 return;
62 }
63
64 /*
65 * Input LUT format:
66 * c0[0-1023], c1[0-1023], c2[0-1023] c3[0-1023]
67 *
68 * Output LUT format (interleaved):
69 * c0[0], c1[0], c2[0], c3[0], c0[1], c1[1], c2[1], c3[1], ....
70 * c0[1023], c1[1023], c2[1023], c3[1023]
71 *
72 * The first format needs c0[0], c1[0] (which are 1024 words apart)
73 * to program gdc LUT registers. This makes it difficult to do piecemeal
74 * reads in SP side gdc_lut_store
75 *
76 * Interleaved format allows use of contiguous bytes to store into
77 * gdc LUT registers.
78 *
79 * See gdc_lut_store() definition in host/gdc.c vs sp/gdc_private.h
80 *
81 */
gdc_lut_convert_to_isp_format(const int in_lut[4][HRT_GDC_N],int out_lut[4][HRT_GDC_N])82 void gdc_lut_convert_to_isp_format(const int in_lut[4][HRT_GDC_N],
83 int out_lut[4][HRT_GDC_N])
84 {
85 unsigned int i;
86 int *out = (int *)out_lut;
87
88 for (i = 0; i < HRT_GDC_N; i++) {
89 out[0] = in_lut[0][i];
90 out[1] = in_lut[1][i];
91 out[2] = in_lut[2][i];
92 out[3] = in_lut[3][i];
93 out += 4;
94 }
95 }
96
gdc_get_unity(const gdc_ID_t ID)97 int gdc_get_unity(
98 const gdc_ID_t ID)
99 {
100 assert(ID < N_GDC_ID);
101 (void)ID;
102 return (int)(1UL << HRT_GDC_FRAC_BITS);
103 }
104
105 /*
106 * Local function implementations
107 */
gdc_reg_store(const gdc_ID_t ID,const unsigned int reg,const hrt_data value)108 static inline void gdc_reg_store(
109 const gdc_ID_t ID,
110 const unsigned int reg,
111 const hrt_data value)
112 {
113 ia_css_device_store_uint32(GDC_BASE[ID] + reg * sizeof(hrt_data), value);
114 return;
115 }
116