• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 HPMicro
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  *
6  */
7 
8 #include "hpm_common.h"
9 #include "hpm_lvb_drv.h"
10 
lvb_get_default_config(lvb_config_t * cfg)11 void lvb_get_default_config(lvb_config_t *cfg)
12 {
13     cfg->split_ch_is_reverse = false;
14     cfg->split_ch_data_is_unaligned = false;
15     cfg->split_hswhbp_width_is_even = true;
16     cfg->split_mode_en = false;
17     cfg->di0_vsync_polarity = lvb_di_vsync_polarity_active_high;
18     cfg->di1_vsync_polarity = lvb_di_vsync_polarity_active_high;
19     cfg->txclk_shift = lvb_txclk_shift_1100011;
20 }
21 
lvb_init(LVB_Type * ptr,lvb_config_t * cfg)22 void lvb_init(LVB_Type *ptr, lvb_config_t *cfg)
23 {
24     ptr->CTRL = (ptr->CTRL & ~(LVB_CTRL_SPLIT_CH_REVERSE_MASK |
25                         LVB_CTRL_SPLIT_CH_MODE_MASK |
26                         LVB_CTRL_SPLIT_HSWHBP_WIDTH_MASK |
27                         LVB_CTRL_SPLIT_MODE_EN_MASK |
28                         LVB_CTRL_DI1_VSYNC_POLARITY_MASK |
29                         LVB_CTRL_DI0_VSYNC_POLARITY_MASK |
30                         LVB_CTRL_LVDS_TXCLK_SHIFT_MASK)) |
31                         LVB_CTRL_SPLIT_CH_REVERSE_SET(cfg->split_ch_is_reverse) |
32                         LVB_CTRL_SPLIT_CH_MODE_SET(cfg->split_ch_data_is_unaligned) |
33                         LVB_CTRL_SPLIT_HSWHBP_WIDTH_SET(cfg->split_hswhbp_width_is_even) |
34                         LVB_CTRL_SPLIT_MODE_EN_SET(cfg->split_mode_en) |
35                         LVB_CTRL_DI1_VSYNC_POLARITY_SET(cfg->di1_vsync_polarity) |
36                         LVB_CTRL_DI0_VSYNC_POLARITY_SET(cfg->di0_vsync_polarity) |
37                         LVB_CTRL_LVDS_TXCLK_SHIFT_SET(cfg->txclk_shift);
38 }
39 
lvb_get_ch_default_config(lvb_ch_config_t * ch_cfg)40 void lvb_get_ch_default_config(lvb_ch_config_t *ch_cfg)
41 {
42     ch_cfg->data_src = lvb_ch_data_source_di0;
43     ch_cfg->map = lvb_ch_mapping_vesa;
44 }
45 
lvb_ch_config(LVB_Type * ptr,lvb_ch_num_t ch_num,lvb_ch_config_t * ch_cfg)46 void lvb_ch_config(LVB_Type *ptr, lvb_ch_num_t ch_num, lvb_ch_config_t *ch_cfg)
47 {
48     uint32_t reg_val;
49 
50     if (ch_num == lvb_ch_num_0) {
51         reg_val = (ptr->CTRL & ~(LVB_CTRL_CH0_BIT_MAPPING_MASK | LVB_CTRL_CH0_SEL_MASK)) |
52                 LVB_CTRL_CH0_BIT_MAPPING_SET(ch_cfg->map) |
53                 LVB_CTRL_CH0_SEL_SET(ch_cfg->data_src);
54     } else {
55         reg_val = (ptr->CTRL & ~(LVB_CTRL_CH1_BIT_MAPPING_MASK | LVB_CTRL_CH1_SEL_MASK)) |
56                 LVB_CTRL_CH1_BIT_MAPPING_SET(ch_cfg->map) |
57                 LVB_CTRL_CH1_SEL_SET(ch_cfg->data_src);
58     }
59 
60     ptr->CTRL = reg_val;
61 }
62 
lvb_ch_enable(LVB_Type * ptr,lvb_ch_num_t ch_num)63 void lvb_ch_enable(LVB_Type *ptr, lvb_ch_num_t ch_num)
64 {
65     if (ch_num == lvb_ch_num_0) {
66         ptr->CTRL |= LVB_CTRL_CH0_EN_MASK;
67     } else {
68         ptr->CTRL |= LVB_CTRL_CH1_EN_MASK;
69     }
70 }
71 
lvb_ch_disable(LVB_Type * ptr,lvb_ch_num_t ch_num)72 void lvb_ch_disable(LVB_Type *ptr, lvb_ch_num_t ch_num)
73 {
74     if (ch_num == lvb_ch_num_0) {
75         ptr->CTRL &= ~LVB_CTRL_CH0_EN_MASK;
76     } else {
77         ptr->CTRL &= ~LVB_CTRL_CH1_EN_MASK;
78     }
79 }
80 
lvb_lvds_phy_lane_get_default_config(lvb_lvds_phy_lane_config_t * cfg)81 void lvb_lvds_phy_lane_get_default_config(lvb_lvds_phy_lane_config_t *cfg)
82 {
83     cfg->tx_idle = false;
84     cfg->rterm_enable = true;
85     cfg->phase_sel = lvb_lvds_lane_phase_sel_4_16_ui;
86     cfg->amp = lvb_lvds_lane_amp_300_mv;
87     cfg->vcom = lvb_lvds_lane_vcom_1_2_v;
88     cfg->fvco_div4 = true;
89 }
90 
lvb_lvds_phy_lane_init(LVB_Type * ptr,lvb_lvds_lane_idx_t tx_index,lvb_lvds_phy_lane_config_t * cfg)91 void lvb_lvds_phy_lane_init(LVB_Type *ptr, lvb_lvds_lane_idx_t tx_index, lvb_lvds_phy_lane_config_t *cfg)
92 {
93     ptr->TX_PHY[tx_index].CTL0 = (ptr->TX_PHY[tx_index].CTL0 & ~(LVB_TX_PHY_CTL0_TX_IDLE_MASK |
94                                     LVB_TX_PHY_CTL0_TX_RTERM_EN_MASK |
95                                     LVB_TX_PHY_CTL0_TX_BUS_WIDTH_MASK |
96                                     LVB_TX_PHY_CTL0_TX_PHASE_SEL_MASK |
97                                     LVB_TX_PHY_CTL0_TX_VCOM_MASK |
98                                     LVB_TX_PHY_CTL0_TX_AMP_MASK)) |
99                                     (cfg->tx_idle ? LVB_TX_PHY_CTL0_TX_IDLE_MASK : 0) |
100                                     (cfg->rterm_enable ? LVB_TX_PHY_CTL0_TX_RTERM_EN_MASK : 0) |
101                                     LVB_TX_PHY_CTL0_TX_BUS_WIDTH_SET(2) | /* only 7bit */
102                                     LVB_TX_PHY_CTL0_TX_PHASE_SEL_SET(cfg->phase_sel) |
103                                     LVB_TX_PHY_CTL0_TX_VCOM_SET(cfg->vcom) |
104                                     LVB_TX_PHY_CTL0_TX_AMP_SET(cfg->amp);
105 
106     if (cfg->fvco_div4) {
107         ptr->TX_PHY[tx_index].CTL0 |= (1ul<<7);
108     } else {
109         ptr->TX_PHY[tx_index].CTL0 &= ~(1ul<<7);
110     }
111 }
112 
lvb_lvds_phy0_poweron(LVB_Type * ptr)113 void lvb_lvds_phy0_poweron(LVB_Type *ptr)
114 {
115     ptr->PHY_POW_CTRL[0] = (ptr->PHY_POW_CTRL[0] & ~(LVB_PHY_POW_CTRL_TXCK_PD_MASK |
116                             LVB_PHY_POW_CTRL_TX3_PD_MASK | LVB_PHY_POW_CTRL_TX2_PD_MASK |
117                             LVB_PHY_POW_CTRL_TX1_PD_MASK | LVB_PHY_POW_CTRL_TX0_PD_MASK)) |
118                             LVB_PHY_POW_CTRL_PWON_PLL_MASK;
119 }
120 
lvb_lvds_phy1_poweron(LVB_Type * ptr)121 void lvb_lvds_phy1_poweron(LVB_Type *ptr)
122 {
123     ptr->PHY_POW_CTRL[1] = (ptr->PHY_POW_CTRL[1] & ~(LVB_PHY_POW_CTRL_TXCK_PD_MASK |
124                             LVB_PHY_POW_CTRL_TX3_PD_MASK | LVB_PHY_POW_CTRL_TX2_PD_MASK |
125                             LVB_PHY_POW_CTRL_TX1_PD_MASK | LVB_PHY_POW_CTRL_TX0_PD_MASK)) |
126                             LVB_PHY_POW_CTRL_PWON_PLL_MASK;
127 }
128 
lvb_lvds_phy0_powerdown(LVB_Type * ptr)129 void lvb_lvds_phy0_powerdown(LVB_Type *ptr)
130 {
131     ptr->PHY_POW_CTRL[0] = (ptr->PHY_POW_CTRL[0] & ~LVB_PHY_POW_CTRL_PWON_PLL_MASK) |
132                             LVB_PHY_POW_CTRL_TXCK_PD_MASK | LVB_PHY_POW_CTRL_TX3_PD_MASK |
133                             LVB_PHY_POW_CTRL_TX2_PD_MASK | LVB_PHY_POW_CTRL_TX1_PD_MASK |
134                             LVB_PHY_POW_CTRL_TX0_PD_MASK;
135 }
136 
lvb_lvds_phy1_powerdown(LVB_Type * ptr)137 void lvb_lvds_phy1_powerdown(LVB_Type *ptr)
138 {
139     ptr->PHY_POW_CTRL[1] = (ptr->PHY_POW_CTRL[1] & ~LVB_PHY_POW_CTRL_PWON_PLL_MASK) |
140                             LVB_PHY_POW_CTRL_TXCK_PD_MASK | LVB_PHY_POW_CTRL_TX3_PD_MASK |
141                             LVB_PHY_POW_CTRL_TX2_PD_MASK | LVB_PHY_POW_CTRL_TX1_PD_MASK |
142                             LVB_PHY_POW_CTRL_TX0_PD_MASK;
143 }