aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/atomisp/pci/atomisp2/css2400/hive_isp_css_common/host/gdc.c
blob: 1966b147f8ab3887f8152d239a7673ab9782b352 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * Support for Intel Camera Imaging ISP subsystem.
 * Copyright (c) 2010-2015, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

/* The name "gdc.h is already taken" */
#include "gdc_device.h"

#include "device_access.h"

#include "assert_support.h"

/*
 * Local function declarations
 */
static inline void gdc_reg_store(
	const gdc_ID_t		ID,
	const unsigned int	reg,
	const hrt_data		value);

static inline hrt_data gdc_reg_load(
	const gdc_ID_t		ID,
	const unsigned int	reg);


#ifndef __INLINE_GDC__
#include "gdc_private.h"
#endif /* __INLINE_GDC__ */

/*
 * Exported function implementations
 */
void gdc_lut_store(
	const gdc_ID_t		ID,
	const int			data[4][HRT_GDC_N])
{
	unsigned int i, lut_offset = HRT_GDC_LUT_IDX;

	assert(ID < N_GDC_ID);
	assert(HRT_GDC_LUT_COEFF_OFFSET <= (4*sizeof(hrt_data)));

	for (i = 0; i < HRT_GDC_N; i++) {
		hrt_data	entry_0 = data[0][i] & HRT_GDC_BCI_COEF_MASK;
		hrt_data	entry_1 = data[1][i] & HRT_GDC_BCI_COEF_MASK;
		hrt_data	entry_2 = data[2][i] & HRT_GDC_BCI_COEF_MASK;
		hrt_data	entry_3 = data[3][i] & HRT_GDC_BCI_COEF_MASK;

		hrt_data	word_0 = entry_0 |
			(entry_1 << HRT_GDC_LUT_COEFF_OFFSET);
		hrt_data	word_1 = entry_2 |
			(entry_3 << HRT_GDC_LUT_COEFF_OFFSET);

		gdc_reg_store(ID, lut_offset++, word_0);
		gdc_reg_store(ID, lut_offset++, word_1);
	}
	return;
}

/*
 * Input LUT format:
 * c0[0-1023], c1[0-1023], c2[0-1023] c3[0-1023]
 *
 * Output LUT format (interleaved):
 * c0[0], c1[0], c2[0], c3[0], c0[1], c1[1], c2[1], c3[1], ....
 * c0[1023], c1[1023], c2[1023], c3[1023]
 *
 * The first format needs c0[0], c1[0] (which are 1024 words apart)
 * to program gdc LUT registers. This makes it difficult to do piecemeal
 * reads in SP side gdc_lut_store
 *
 * Interleaved format allows use of contiguous bytes to store into
 * gdc LUT registers.
 *
 * See gdc_lut_store() definition in host/gdc.c vs sp/gdc_private.h
 *
 */
void gdc_lut_convert_to_isp_format(const int in_lut[4][HRT_GDC_N],
	int out_lut[4][HRT_GDC_N])
{
	unsigned int i;
	int *out = (int *)out_lut;

	for (i = 0; i < HRT_GDC_N; i++) {
		out[0] = in_lut[0][i];
		out[1] = in_lut[1][i];
		out[2] = in_lut[2][i];
		out[3] = in_lut[3][i];
		out += 4;
	}
}

int gdc_get_unity(
	const gdc_ID_t		ID)
{
	assert(ID < N_GDC_ID);
	(void)ID;
	return (int)(1UL << HRT_GDC_FRAC_BITS);
}


/*
 * Local function implementations
 */
static inline void gdc_reg_store(
	const gdc_ID_t		ID,
	const unsigned int	reg,
	const hrt_data		value)
{
	ia_css_device_store_uint32(GDC_BASE[ID] + reg*sizeof(hrt_data), value);
	return;
}

static inline hrt_data gdc_reg_load(
	const gdc_ID_t		ID,
	const unsigned int	reg)
{
	return ia_css_device_load_uint32(GDC_BASE[ID] + reg*sizeof(hrt_data));
}