summaryrefslogtreecommitdiff
path: root/drivers/media/platform/exynos5-is/fimc-is-backend.h
blob: 40a4d329996ca49276bd1ab9fe0f65c7f692c1a6 (plain)
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/*
 * Samsung EXYNOS5/EXYNOS3250 FIMC-IS (Imaging Subsystem) driver
 *
 * Copyright (C) 2013-2014 Samsung Electronics Co., Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 */
#ifndef FIMC_IS_BACKEND_H_
#define FIMC_IS_BACKEND_H_

#include "fimc-is-fw.h"
#include <linux/types.h>


/*
 * MCUCTL Shared register types
 */
#define MCUCTL_SHARED_REG_INVAL 0
#define MCUCTL_SHARED_REG_R	(1 << 0)
#define MCUCTL_SHARED_REG_W	(1 << 1)
#define MCUCTL_SHARED_REG_RW	(MCUCTL_SHARED_REG_R | MCUCTL_SHARED_REG_W)

/*
 * Set of supported MCUCTL shared registers.
 * Might be extended if needed.
 */
enum{
        /* | COMMAND ID | SENSOR/GROUP ID | PARAMS |		  */
        MCUCTL_HIC_REG,
        /* | NUMBER 	|			    		  */
        MCUCTL_PW_DONW_REG,
        /* | IFLAGS	| COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_IHC_REG,
        /* | IFLAGS     | COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_3AA0C_REG,
        /* | IFLAGS     | COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_3AA1C_REG,
        /* | IFLAGS     | COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_ISP_REG,
        /* | IFLAGS     | COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_SCC_REG,
        /* | IFLAGS     | COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_DNR_REG,
        /* | IFLAGS     | COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_DIS_REG,
        /* | IFLAGS     | COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_SCP_REG,
        /* | IFLAGS     | COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_YUV_REG,
        /* | IFLAGS     | COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_SHOT_REG,
        /* | IFLAGS     | COMMAND ID | SENSOR/GROUP ID | PARAMS  | */
        MCUCTL_META_REG,
        /* | SENSOR3    | SENSOR2    | SENSOR1         | SENSOR0 | */
        MCUCTL_FRAME_COUNT_REG,
        MCUCTL_END_REG
};

#define MCUCTL_SREG_SIZE	4

/**
 * struct mcuctl_sreg_desc - MCUCTL Shared register descriptor
 * @base_offset: Base offset of logical MCUCTL shared registers range
 * 		 relative to the begining of MCUCTL shared area
 * @range: Number of 32-bits registers within the range
 * @data_range: Number of 32-bits registers dedicated for communication
 * 		parameters
 * @type: type of the registers set: MCUCTL_SHARED_REG_INVAL denotes given set
 * 	  is not supported. MCUCTL_SHARED_REG_R, MCUCTL_SHARED_REG_W indicate
 * 	  readable / writable registers.
 */
struct mcuctl_sreg_desc {
        unsigned long base_offset;
        unsigned int range;
        unsigned int data_range;
        unsigned int type;
};

/*
 * MCUCTL Shared regs layout
 * Single set of logically related registers:
 * OFFSET: | 0x00 | : INTERRUPT FLAGS *OPTIONAL*
 * OFFSET: | 0x04 | : COMMAND ID
 * OFFSET: | 0x08 | : SENSOR  ID / GROUP ID
 * OFFSET: | 0x0c | : COMMAND PARAMETERS (max.4)
 */

#define MCUCTL_SHARED_REG(offset, size, data_size, reg_type)\
{							    \
        .base_offset = offset,				    \
        .range 	     = size,				    \
        .data_range  = data_size,			    \
        .type        = reg_type,			    \
}

/**
 *  @brief Generic set of FIMC IS interrupts
 */
enum fimc_is_interrupt {
        INTR_GENERAL,
        INTR_ISP_DONE,
        INTR_3A0C_DONE,
        INTR_3A1C_DONE,
        INTR_SCC_DONE,
        INTR_DNR_DONE,
        INTR_DIS_DONE,
        INTR_SCP_DONE,
        INTR_ISP_YUV_DONE,
        INTR_META_DONE,
        INTR_SHOT_DONE,
        INTR_MAX_MAP

};

/**
 * @brief Unspecified firmware version
 */
#define FIMC_IS_FW_VER_UNKNOWN	0
/**
 * @brief Generic error code
 */
#define FIMC_IS_FW_INVALID (-EINVAL)

/**
 * @brief Map firmware specific interrupt source id
 * 	  to generic one
 */
#define FIMC_IS_FW_GET_INTR_SRC(fw_data, __intr_src)	\
        ((__intr_src) < (fw_data)->interrupt_map_size	\
                ? (fw_data)->interrupt_map[(__intr_src)]\
                : FIMC_IS_FW_INVALID)

/**
 * @brief Verify if given command is supported by current firmware
 */
#define FIMC_IS_FW_CMD_SUPPORT(fw_data, __cmd) 				\
({									\
        u64 __cmd_bitmap = 0; 						\
        unsigned int __bit = 0; 					\
        if ((__cmd) <= HIC_COMMAND_END) {				\
                __cmd_bitmap = (fw_data)->instruction_set.hic_bitmap;	\
                __bit = (__cmd) -1;					\
        }								\
        else if ((__cmd) <= IHC_COMMAND_END) { 				\
                __cmd_bitmap = (fw_data)->instruction_set.ihc_bitmap; 	\
                __bit = (__cmd) - IHC_COMMAND_BEGIN; 			\
        }								\
        __cmd_bitmap & (1ULL << __bit) ? 1 : 0;				\
})

/**
 * struct fimc_is_fw_commands - internal info on firmware support
 * 				for FIMC IS <-> Host communication commands
 * @hic_bitmap: bitmap of supported HIC commands
 * 		(each command (ID) is mapped to a corresponding bit)
 * @ihc_bitmap: bitmap of supported IHC commands
 * 		(each command (ID) is mapped to a corresponding bit,
 * 		starting with IHC_COMMAND_BEGIN mapped to first bit)
 *
 */
struct fimc_is_fw_commands{
        u64	hic_bitmap;
        u64	ihc_bitmap;
};


/**
 * struct fimc_is_fw_dta -  set of internal data used to control
 * 			    proper information flow between the
 * 			    driver itself and currently used FIMC IS
 * 			    firmware
 * @fw_version: reference firmware version
 * @mcuctl_sreg_map: map of MCUCTL shared registers
 * @instruction_set: bitmap of supported instructions
 * @interrupt_map: FIMC IS fw specific interrupts src map
 */
struct fimc_is_fw_data {
        unsigned int		 		 version;
        const struct fimc_is_fw_commands 	 instruction_set;
        const struct mcuctl_sreg_desc const	*mcuctl_sreg_map;
        const unsigned int const		*interrupt_map;
        unsigned int				 interrupt_map_size;
};

void fimc_is_fw_set_default(struct fimc_is_fw_data **fw_data);
int fimc_is_fw_config(struct fimc_is_fw_data **fw_data, unsigned int fw_version);


int mcuctl_sreg_get_desc(struct fimc_is_fw_data *fw_data,
                         unsigned int mcuctl_sreg_id,
                         struct mcuctl_sreg_desc *mcuctl_sreg_desc);

int mcuctl_sreg_get_offset(struct fimc_is_fw_data *fw_data,
                           unsigned int mcuctl_sreg_id,
                           unsigned long * offset);

int mcuctl_sreg_get_range(struct fimc_is_fw_data *fw_data,
                          unsigned int mcuctl_sreg_id,
                          unsigned long *range);

int mcuctl_sreg_get_data_range(struct fimc_is_fw_data *fw_data,
                               unsigned int mcuctl_sreg_id,
                               unsigned int *data_range);

int mcuctl_sreg_is_valid(struct fimc_is_fw_data *fw_data,
                         unsigned int mcuctl_sreg_id);


#endif /*FIMC_IS_BACKEND_H_*/