• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #ifndef HPM_LVB_DRV_H
9 #define HPM_LVB_DRV_H
10 
11 /**
12  * @brief LVB APIs
13  * @defgroup lvb_interface LVB driver APIs
14  * @ingroup lvb_interfaces
15  * @{
16  */
17 
18 #include "hpm_common.h"
19 #include "hpm_soc.h"
20 #include "hpm_lvb_regs.h"
21 
22 /**
23  * @brief LVB DI vsync polarity
24  */
25 typedef enum lvb_di_vsync_polarity {
26     lvb_di_vsync_polarity_active_high = 0,
27     lvb_di_vsync_polarity_active_low
28 } lvb_di_vsync_polarity_t;
29 
30 /**
31  * @brief Shift the LVDS TX PHY clock in relation to the data
32  */
33 typedef enum lvb_txclk_shift {
34     lvb_txclk_shift_1100011 = 0,
35     lvb_txclk_shift_1110001,
36     lvb_txclk_shift_1111000,
37     lvb_txclk_shift_1000111,
38     lvb_txclk_shift_0001111,
39     lvb_txclk_shift_0011110,
40     lvb_txclk_shift_0111100,
41 } lvb_txclk_shift_t;
42 
43 /**
44  * @brief LVB config
45  */
46 typedef struct lvb_config {
47     bool split_ch_is_reverse; /*!< Just for split mode, reverse two channel data */
48     bool split_ch_data_is_unaligned; /*!< Just for split mode, two channel pixel data are aligned */
49     bool split_hswhbp_width_is_even; /*!< Just for split mode, the sum of HSW and HBP width is even */
50     bool split_mode_en; /*!< Note: when using split mode, ch0/1 should be enabled, and should select same DI */
51     lvb_di_vsync_polarity_t di1_vsync_polarity; /*!< lvb di1 vsync polarity */
52     lvb_di_vsync_polarity_t di0_vsync_polarity; /*!< lvb di0 vsync polarity */
53     lvb_txclk_shift_t txclk_shift; /*!< Shift the LVDS TX PHY clock in relation to the data */
54 } lvb_config_t;
55 
56 /**
57  * @brief LVB channel pixel data mapping
58  */
59 typedef enum lvb_ch_mapping {
60     lvb_ch_mapping_vesa = 0,
61     lvb_ch_mapping_jeida,
62 } lvb_ch_mapping_t;
63 
64 /**
65  * @brief LVB channel pixel data source
66  */
67 typedef enum lvb_ch_data_source {
68     lvb_ch_data_source_di0 = 0,
69     lvb_ch_data_source_di1,
70 } lv_ch_data_source_t;
71 
72 /**
73  * @brief LVB channel number
74  */
75 typedef enum lvb_ch_num {
76     lvb_ch_num_0 = 0,
77     lvb_ch_num_1 = 1
78 } lvb_ch_num_t;
79 
80 /**
81  * @brief LVB channel config
82  */
83 typedef struct lvb_ch_config {
84     lvb_ch_mapping_t map;
85     lv_ch_data_source_t data_src;
86 } lvb_ch_config_t;
87 
88 typedef enum lvb_lvds_lane_phase_sel {
89     lvb_lvds_lane_phase_sel_0_ui = 0,
90     lvb_lvds_lane_phase_sel_1_16_ui,
91     lvb_lvds_lane_phase_sel_2_16_ui,
92     lvb_lvds_lane_phase_sel_3_16_ui,
93     lvb_lvds_lane_phase_sel_4_16_ui,
94     lvb_lvds_lane_phase_sel_5_16_ui,
95     lvb_lvds_lane_phase_sel_6_16_ui,
96     lvb_lvds_lane_phase_sel_7_16_ui,
97     lvb_lvds_lane_phase_sel_8_16_ui,
98     lvb_lvds_lane_phase_sel_9_16_ui,
99     lvb_lvds_lane_phase_sel_10_16_ui,
100     lvb_lvds_lane_phase_sel_11_16_ui,
101     lvb_lvds_lane_phase_sel_12_16_ui,
102     lvb_lvds_lane_phase_sel_13_16_ui,
103     lvb_lvds_lane_phase_sel_14_16_ui,
104     lvb_lvds_lane_phase_sel_15_16_ui,
105 } lvb_lvds_lane_phase_sel_t;
106 
107 typedef enum lvb_lvds_lane_amp {
108     lvb_lvds_lane_amp_50_mv = 0,
109     lvb_lvds_lane_amp_100_mv,
110     lvb_lvds_lane_amp_150_mv,
111     lvb_lvds_lane_amp_200_mv,
112     lvb_lvds_lane_amp_250_mv,
113     lvb_lvds_lane_amp_300_mv,
114     lvb_lvds_lane_amp_350_mv,
115     lvb_lvds_lane_amp_400_mv,
116     lvb_lvds_lane_amp_450_mv,
117     lvb_lvds_lane_amp_500_mv,
118     lvb_lvds_lane_amp_550_mv,
119     lvb_lvds_lane_amp_600_mv
120 } lvb_lvds_lane_amp_t;
121 
122 typedef enum lvb_lvds_lane_vcom {
123     lvb_lvds_lane_vcom_0_7_v = 0,
124     lvb_lvds_lane_vcom_0_8_v,
125     lvb_lvds_lane_vcom_0_9_v,
126     lvb_lvds_lane_vcom_1_0_v,
127     lvb_lvds_lane_vcom_1_1_v,
128     lvb_lvds_lane_vcom_1_2_v,
129     lvb_lvds_lane_vcom_1_3_v,
130     lvb_lvds_lane_vcom_1_4_v,
131     lvb_lvds_lane_vcom_1_5_v,
132 } lvb_lvds_lane_vcom_t;
133 
134 typedef struct lvb_lvds_phy_lane_config {
135     bool rterm_enable;
136     bool tx_idle;
137     lvb_lvds_lane_phase_sel_t phase_sel;
138     lvb_lvds_lane_amp_t amp;
139     lvb_lvds_lane_vcom_t vcom;
140     bool fvco_div4;
141 } lvb_lvds_phy_lane_config_t;
142 
143 typedef enum lvb_lvds_lane_idx {
144     lvb_lvds_lane_idx_lvds0_tx0 = LVB_TX_PHY_LVDS0_TX0,
145     lvb_lvds_lane_idx_lvds0_tx1 = LVB_TX_PHY_LVDS0_TX1,
146     lvb_lvds_lane_idx_lvds0_tx2 = LVB_TX_PHY_LVDS0_TX2,
147     lvb_lvds_lane_idx_lvds0_tx3 = LVB_TX_PHY_LVDS0_TX3,
148     lvb_lvds_lane_idx_lvds0_txck = LVB_TX_PHY_LVDS0_TXCK,
149     lvb_lvds_lane_idx_lvds1_tx0 = LVB_TX_PHY_LVDS1_TX0,
150     lvb_lvds_lane_idx_lvds1_tx1 = LVB_TX_PHY_LVDS1_TX1,
151     lvb_lvds_lane_idx_lvds1_tx2 = LVB_TX_PHY_LVDS1_TX2,
152     lvb_lvds_lane_idx_lvds1_tx3 = LVB_TX_PHY_LVDS1_TX3,
153     lvb_lvds_lane_idx_lvds1_txck = LVB_TX_PHY_LVDS1_TXCK,
154 } lvb_lvds_lane_idx_t;
155 
156 #ifdef __cplusplus
157 extern "C" {
158 #endif
159 
160 /**
161  * @brief get LVB of default config
162  *
163  * @param[out] cfg config of LVB
164  */
165 void lvb_get_default_config(lvb_config_t *cfg);
166 
167 /**
168  * @brief LVB init
169  *
170  * @param[in] ptr LVB base address
171  * @param[in] cfg config of LVB
172  */
173 void lvb_init(LVB_Type *ptr, lvb_config_t *cfg);
174 
175 /**
176  * @brief get LVB channel of default config
177  *
178  * @param[out] cfg config of LVB
179  */
180 void lvb_get_ch_default_config(lvb_ch_config_t *ch_cfg);
181 
182 /**
183  * @brief LVB channel config
184  *
185  * @param[in] ptr LVB base address
186  * @param[in] ch_num LVB channel number
187  * @param[in] cfg config of LVB channel
188  */
189 void lvb_ch_config(LVB_Type *ptr, lvb_ch_num_t ch_num, lvb_ch_config_t *ch_cfg);
190 
191 /**
192  * @brief LVB channel enable
193  *
194  * @param[in] ptr LVB base address
195  * @param[in] ch_num LVB channel number
196  */
197 void lvb_ch_enable(LVB_Type *ptr, lvb_ch_num_t ch_num);
198 
199 /**
200  * @brief LVB channel disable
201  *
202  * @param[in] ptr LVB base address
203  * @param[in] ch_num LVB channel number
204  */
205 void lvb_ch_disable(LVB_Type *ptr, lvb_ch_num_t ch_num);
206 
207 /**
208  * @brief check LVB phy0 is lock
209  *
210  * @param[in] ptr LVB base address
211  */
lvb_lvds_phy0_pll_is_lock(LVB_Type * ptr)212 static inline bool lvb_lvds_phy0_pll_is_lock(LVB_Type *ptr)
213 {
214     return !!LVB_PHY_STAT_LVDS0_TX_PHY_PLL_LOCK_GET(ptr->PHY_STAT);
215 }
216 
217 /**
218  * @brief check LVB phy1 is lock
219  *
220  * @param[in] ptr LVB base address
221  */
lvb_lvds_phy1_pll_is_lock(LVB_Type * ptr)222 static inline bool lvb_lvds_phy1_pll_is_lock(LVB_Type *ptr)
223 {
224     return !!LVB_PHY_STAT_LVDS1_TX_PHY_PLL_LOCK_GET(ptr->PHY_STAT);
225 }
226 
227 /**
228  * @brief check LVB phy0 and phy1 is lock
229  *
230  * @param[in] ptr LVB base address
231  */
lvb_lvds_phy_split_pll_is_lock(LVB_Type * ptr)232 static inline bool lvb_lvds_phy_split_pll_is_lock(LVB_Type *ptr)
233 {
234     return !!LVB_PHY_STAT_LVDS0_TX_PHY_PLL_LOCK_GET(ptr->PHY_STAT) &&
235             !!LVB_PHY_STAT_LVDS1_TX_PHY_PLL_LOCK_GET(ptr->PHY_STAT);
236 }
237 
238 /**
239  * @brief lvb lvds lane get default config
240  *
241  * @param[out] cfg lvds lane config @ref lvb_lvds_phy_lane_config_t
242  */
243 void lvb_lvds_phy_lane_get_default_config(lvb_lvds_phy_lane_config_t *cfg);
244 
245 /**
246  * @brief lvb lvds lane init and config
247  *
248  * @param[in] ptr LVB base address
249  * @param[in] tx_index lvds phy lane index @ref lvb_lvds_lane_idx_t
250  * @param[in] cfg lvds lane config @ref lvb_lvds_phy_lane_config_t
251  */
252 void lvb_lvds_phy_lane_init(LVB_Type *ptr, lvb_lvds_lane_idx_t tx_index, lvb_lvds_phy_lane_config_t *cfg);
253 
254 /**
255  * @brief power on LVB phy0
256  *
257  * @param[in] ptr LVB base address
258  */
259 void lvb_lvds_phy0_poweron(LVB_Type *ptr);
260 
261 /**
262  * @brief power on LVB phy1
263  *
264  * @param[in] ptr LVB base address
265  */
266 void lvb_lvds_phy1_poweron(LVB_Type *ptr);
267 
268 /**
269  * @brief power down LVB phy0
270  *
271  * @param[in] ptr LVB base address
272  */
273 void lvb_lvds_phy0_powerdown(LVB_Type *ptr);
274 
275 /**
276  * @brief power down LVB phy0
277  *
278  * @param[in] ptr LVB base address
279  */
280 void lvb_lvds_phy1_powerdown(LVB_Type *ptr);
281 
282 #ifdef __cplusplus
283 }
284 #endif
285 
286 /**
287  * @}
288  */
289 #endif /* HPM_LVB_DRV_H */
290