• 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_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