1 /*
2 * Copyright (c) 2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #ifndef HPM_LCB_DRV_H
9 #define HPM_LCB_DRV_H
10
11 /**
12 * @brief LCB APIs
13 * @defgroup lcb_interface LCB driver APIs
14 * @ingroup lcb_interfaces
15 * @{
16 */
17
18 #include "hpm_common.h"
19 #include "hpm_soc.h"
20 #include "hpm_lcb_regs.h"
21
22 typedef enum lcb_rxclk_sel {
23 lcb_rxclk_sel_phy0 = 0,
24 lcb_rxclk_sel_phy1 = 1,
25 } lcb_rxclk_sel_t;
26
27 typedef enum lcb_mode {
28 lcb_mode_display = 0,
29 lcb_mode_cam_link = 1,
30 } lcb_mode_t;
31
32 typedef enum lcb_display_mode_mapping {
33 lcb_display_mode_mapping_vesa = 0,
34 lcb_display_mode_mapping_jeida = 1,
35 } lcb_display_mode_mapping_t;
36
37 typedef enum lcb_display_mode_data_width {
38 lcb_display_mode_data_width_18bit = 0,
39 lcb_display_mode_data_width_24bit = 1,
40 } lcb_display_mode_data_width_t;
41
42 typedef struct lcb_display_mode_config {
43 lcb_display_mode_mapping_t map;
44 lcb_display_mode_data_width_t data_width;
45 } lcb_display_mode_config_t;
46
47 typedef enum lcb_cam_link_mode_data_width {
48 lcb_cam_link_mode_data_width_24bit = 0,
49 lcb_cam_link_mode_data_width_30bit = 1,
50 lcb_cam_link_mode_data_width_36bit = 1,
51 } lcb_cam_link_mode_data_width_t;
52
53 typedef struct lcb_cam_link_mode_config {
54 lcb_cam_link_mode_data_width_t data_width;
55 } lcb_cam_link_mode_config_t;
56
57 typedef struct lcb_config {
58 lcb_rxclk_sel_t rxclk_sel;
59 lcb_mode_t mode;
60 union {
61 lcb_display_mode_config_t display;
62 lcb_cam_link_mode_config_t cam_link;
63 };
64 } lcb_config_t;
65
66 /**
67 * @brief Terminal impedance regulation
68 */
69 typedef enum lcb_lvds_phy_rterm {
70 lcb_lvds_phy_rterm_hi_z = 0,
71 lcb_lvds_phy_rterm_150_ohm = 1,
72 lcb_lvds_phy_rterm_100_ohm = 8,
73 lcb_lvds_phy_rterm_75_ohm = 15,
74 } lcb_lvds_phy_rterm_t;
75
76 typedef struct lcb_lvds_phy_data_lane_config {
77 uint8_t dline_adj; /*!< Lane N skew adjustment value between data and clock. 0000000: max; 1111111: min */
78 lcb_lvds_phy_rterm_t rterm; /*!< Terminal impedance regulation */
79 } lcb_lvds_phy_data_lane_config_t;
80
81 /**
82 * @brief DLL loop delay adjustment minimum frequency
83 */
84 typedef enum lcb_lvds_phy_dll_delay_adj_min_freq {
85 lcb_lvds_phy_dll_delay_adj_min_freq_40_70mhz = 0,
86 lcb_lvds_phy_dll_delay_adj_min_freq_70_110mhz = 0,
87 } lcb_lvds_phy_dll_delay_adj_min_freq_t;
88
89 typedef struct lcb_lvds_phy_clk_lane_config {
90 lcb_lvds_phy_dll_delay_adj_min_freq_t min_adj;
91 uint16_t dll_tuning_int; /*!< DLL loop delay coarse adjustment initial value. 00000000: min ; 11111111: max */
92 lcb_lvds_phy_rterm_t rterm; /*!< Terminal impedance regulation */
93 } lcb_lvds_phy_clk_lane_config_t;
94
95 typedef enum lcb_lvds_phy_data_lane_id {
96 lcb_lvds_phy_data_lane_id_0 = 0,
97 lcb_lvds_phy_data_lane_id_1 = 1,
98 } lcb_lvds_phy_data_lane_id_t;
99
100 #ifdef __cplusplus
101 extern "C" {
102 #endif
103
104 /**
105 * @brief get LCB of default config
106 *
107 * @param[out] cfg config of LCB
108 */
109 void lcb_get_default_config(lcb_config_t *cfg);
110
111 /**
112 * @brief LCB init
113 *
114 * @param[in] ptr LCB base address
115 * @param[in] cfg config of LCB
116 */
117 void lcb_init(LCB_Type *ptr, lcb_config_t *cfg);
118
119 /**
120 * @brief get LCB clk_lane of default config
121 *
122 * @param[out] cfg config of clk_lane
123 */
124 void lcb_get_phy_clk_lane_default_config(lcb_lvds_phy_clk_lane_config_t *cfg);
125
126 /**
127 * @brief get LCB data_lane of default config
128 *
129 * @param[out] cfg config of data_lane
130 */
131 void lcb_get_phy_data_lane_default_config(lcb_lvds_phy_data_lane_config_t *cfg);
132
133 /**
134 * @brief LCB phy0 data lane config
135 *
136 * @param[in] ptr LCB base address
137 * @param[in] cfg config of phy0 data lane
138 * @param[in] lane_id data lane id
139 */
140 void lcb_lvds_phy0_data_lane_config(LCB_Type *ptr, lcb_lvds_phy_data_lane_config_t *cfg, lcb_lvds_phy_data_lane_id_t lane_id);
141
142 /**
143 * @brief LCB phy0 clk lane config
144 *
145 * @param[in] ptr LCB base address
146 * @param[in] cfg config of phy0 clk lane
147 */
148 void lcb_lvds_phy0_clk_lane_config(LCB_Type *ptr, lcb_lvds_phy_clk_lane_config_t *cfg);
149
150 /**
151 * @brief LCB phy1 data lane config
152 *
153 * @param[in] ptr LCB base address
154 * @param[in] cfg config of phy1 data lane
155 * @param[in] lane_id data lane id
156 */
157 void lcb_lvds_phy1_data_lane_config(LCB_Type *ptr, lcb_lvds_phy_data_lane_config_t *cfg, lcb_lvds_phy_data_lane_id_t lane_id);
158
159 /**
160 * @brief LCB phy1 clk lane config
161 *
162 * @param[in] ptr LCB base address
163 * @param[in] cfg config of phy1 clk lane
164 */
165 void lcb_lvds_phy1_clk_lane_config(LCB_Type *ptr, lcb_lvds_phy_clk_lane_config_t *cfg);
166
167 /**
168 * @brief power on LCB phy0
169 *
170 * @param[in] ptr LCB base address
171 */
172 void lcb_lvds_phy0_poweron(LCB_Type *ptr);
173
174 /**
175 * @brief power on LCB phy1
176 *
177 * @param[in] ptr LCB base address
178 */
179 void lcb_lvds_phy1_poweron(LCB_Type *ptr);
180
181 /**
182 * @brief power down LCB phy0
183 *
184 * @param[in] ptr LCB base address
185 */
186 void lcb_lvds_phy0_powerdown(LCB_Type *ptr);
187
188 /**
189 * @brief power on LCB phy1
190 *
191 * @param[in] ptr LCB base address
192 */
193 void lcb_lvds_phy1_powerdown(LCB_Type *ptr);
194
195 /**
196 * @brief check LCB phy0 is lock
197 *
198 * @param[in] ptr LCB base address
199 */
lcb_lvds_phy0_dll_is_lock(LCB_Type * ptr)200 static inline bool lcb_lvds_phy0_dll_is_lock(LCB_Type *ptr)
201 {
202 return !!LCB_PHY_STAT_LVDS0_RX_PHY_DLL_LOCK_GET(ptr->PHY_STAT);
203 }
204
205 /**
206 * @brief check LCB phy1 is lock
207 *
208 * @param[in] ptr LCB base address
209 */
lcb_lvds_phy1_dll_is_lock(LCB_Type * ptr)210 static inline bool lcb_lvds_phy1_dll_is_lock(LCB_Type *ptr)
211 {
212 return !!LCB_PHY_STAT_LVDS1_RX_PHY_DLL_LOCK_GET(ptr->PHY_STAT);
213 }
214
215 /**
216 * @brief check LCB display phy is lock
217 *
218 * @param[in] ptr LCB base address
219 */
lcb_lvds_display_phy_dll_is_lock(LCB_Type * ptr)220 static inline bool lcb_lvds_display_phy_dll_is_lock(LCB_Type *ptr)
221 {
222 return !!LCB_PHY_STAT_LVDS0_RX_PHY_DLL_LOCK_GET(ptr->PHY_STAT) &&
223 !!LCB_PHY_STAT_LVDS1_RX_PHY_DLL_LOCK_GET(ptr->PHY_STAT);
224 }
225
226
227 #ifdef __cplusplus
228 }
229 #endif
230
231 /**
232 * @}
233 */
234 #endif /* HPM_LCB_DRV_H */
235