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_lcb_drv.h"
10
lcb_get_default_config(lcb_config_t * cfg)11 void lcb_get_default_config(lcb_config_t *cfg)
12 {
13 cfg->mode = lcb_mode_display;
14 cfg->rxclk_sel = lcb_rxclk_sel_phy0;
15 cfg->display.data_width = lcb_display_mode_data_width_24bit;
16 cfg->display.map = lcb_display_mode_mapping_vesa;
17 }
18
lcb_init(LCB_Type * ptr,lcb_config_t * cfg)19 void lcb_init(LCB_Type *ptr, lcb_config_t *cfg)
20 {
21 uint32_t reg_val;
22
23 if (cfg->mode == lcb_mode_display)
24 reg_val = (ptr->CTRL & ~(LCB_CTRL_LVDS_RXCK_SEL_MASK |
25 LCB_CTRL_MODE_MASK |
26 LCB_CTRL_DATA_WIDTH_MASK |
27 LCB_CTRL_BIT_MAPPING_MASK)) |
28 LCB_CTRL_MODE_SET(cfg->mode) |
29 LCB_CTRL_LVDS_RXCK_SEL_SET(cfg->rxclk_sel) |
30 LCB_CTRL_DATA_WIDTH_SET(cfg->display.data_width) |
31 LCB_CTRL_BIT_MAPPING_SET(cfg->display.map);
32 else
33 reg_val = (ptr->CTRL & ~(LCB_CTRL_LVDS_RXCK_SEL_MASK |
34 LCB_CTRL_MODE_MASK |
35 LCB_CTRL_CAM_LINK_WIDTH_MASK)) |
36 LCB_CTRL_MODE_SET(cfg->mode) |
37 LCB_CTRL_LVDS_RXCK_SEL_SET(cfg->rxclk_sel) |
38 LCB_CTRL_CAM_LINK_WIDTH_SET(cfg->cam_link.data_width);
39
40 ptr->CTRL = reg_val;
41 }
42
lcb_get_phy_clk_lane_default_config(lcb_lvds_phy_clk_lane_config_t * cfg)43 void lcb_get_phy_clk_lane_default_config(lcb_lvds_phy_clk_lane_config_t *cfg)
44 {
45 cfg->rterm = lcb_lvds_phy_rterm_100_ohm;
46 cfg->min_adj = lcb_lvds_phy_dll_delay_adj_min_freq_70_110mhz;
47 cfg->dll_tuning_int = 0x1FFU;
48 }
49
lcb_get_phy_data_lane_default_config(lcb_lvds_phy_data_lane_config_t * cfg)50 void lcb_get_phy_data_lane_default_config(lcb_lvds_phy_data_lane_config_t *cfg)
51 {
52 cfg->rterm = lcb_lvds_phy_rterm_100_ohm;
53 cfg->dline_adj = 0x41;
54 }
55
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)56 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)
57 {
58 ptr->PHY_D_CTRL[lane_id] = (ptr->PHY_D_CTRL[lane_id] & ~(LCB_PHY_D_CTRL_RX_RTERM_MASK)) |
59 LCB_PHY_D_CTRL_RX_RTERM_SET(cfg->rterm);
60
61 if (lane_id == lcb_lvds_phy_data_lane_id_0)
62 ptr->PHY_ADJ_CTRL[0] = (ptr->PHY_ADJ_CTRL[0] & ~(LCB_PHY_ADJ_CTRL_LVDS_RX0_DLINE_ADJ_MASK)) |
63 LCB_PHY_ADJ_CTRL_LVDS_RX0_DLINE_ADJ_SET(cfg->dline_adj);
64 else if (lane_id == lcb_lvds_phy_data_lane_id_1)
65 ptr->PHY_ADJ_CTRL[0] = (ptr->PHY_ADJ_CTRL[0] & ~(LCB_PHY_ADJ_CTRL_LVDS_RX1_DLINE_ADJ_MASK)) |
66 LCB_PHY_ADJ_CTRL_LVDS_RX1_DLINE_ADJ_SET(cfg->dline_adj);
67 }
68
lcb_lvds_phy0_clk_lane_config(LCB_Type * ptr,lcb_lvds_phy_clk_lane_config_t * cfg)69 void lcb_lvds_phy0_clk_lane_config(LCB_Type *ptr, lcb_lvds_phy_clk_lane_config_t *cfg)
70 {
71 ptr->PHY_CK_CTRL[0] = (ptr->PHY_CK_CTRL[0] & ~(LCB_PHY_CK_CTRL_RX_RTERM_MASK | 0x0001)) |
72 LCB_PHY_CK_CTRL_RX_RTERM_SET(cfg->rterm) |
73 (uint32_t)cfg->min_adj;
74
75 ptr->PHY_ADJ_CTRL[0] = (ptr->PHY_ADJ_CTRL[0] & ~(LCB_PHY_ADJ_CTRL_LVDS_DLL_TUNING_INT_MASK)) |
76 LCB_PHY_ADJ_CTRL_LVDS_DLL_TUNING_INT_SET(cfg->dll_tuning_int);
77 }
78
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)79 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)
80 {
81 ptr->PHY_D_CTRL[lane_id + 2] = (ptr->PHY_D_CTRL[lane_id + 2] & ~(LCB_PHY_D_CTRL_RX_RTERM_MASK)) |
82 LCB_PHY_D_CTRL_RX_RTERM_SET(cfg->rterm);
83
84 if (lane_id == lcb_lvds_phy_data_lane_id_0)
85 ptr->PHY_ADJ_CTRL[1] = (ptr->PHY_ADJ_CTRL[1] & ~(LCB_PHY_ADJ_CTRL_LVDS_RX0_DLINE_ADJ_MASK)) |
86 LCB_PHY_ADJ_CTRL_LVDS_RX0_DLINE_ADJ_SET(cfg->dline_adj);
87 else if (lane_id == lcb_lvds_phy_data_lane_id_1)
88 ptr->PHY_ADJ_CTRL[1] = (ptr->PHY_ADJ_CTRL[1] & ~(LCB_PHY_ADJ_CTRL_LVDS_RX1_DLINE_ADJ_MASK)) |
89 LCB_PHY_ADJ_CTRL_LVDS_RX1_DLINE_ADJ_SET(cfg->dline_adj);
90 }
91
lcb_lvds_phy1_clk_lane_config(LCB_Type * ptr,lcb_lvds_phy_clk_lane_config_t * cfg)92 void lcb_lvds_phy1_clk_lane_config(LCB_Type *ptr, lcb_lvds_phy_clk_lane_config_t *cfg)
93 {
94 ptr->PHY_CK_CTRL[1] = (ptr->PHY_CK_CTRL[1] & ~(LCB_PHY_CK_CTRL_RX_RTERM_MASK | 0x0001)) |
95 LCB_PHY_CK_CTRL_RX_RTERM_SET(cfg->rterm) |
96 (uint32_t)cfg->min_adj;
97
98 ptr->PHY_ADJ_CTRL[1] = (ptr->PHY_ADJ_CTRL[1] & ~(LCB_PHY_ADJ_CTRL_LVDS_DLL_TUNING_INT_MASK)) |
99 LCB_PHY_ADJ_CTRL_LVDS_DLL_TUNING_INT_SET(cfg->dll_tuning_int);
100 }
101
lcb_lvds_phy0_poweron(LCB_Type * ptr)102 void lcb_lvds_phy0_poweron(LCB_Type *ptr)
103 {
104 ptr->PHY_POW_CTRL[0] &= ~(LCB_PHY_POW_CTRL_IDDQ_EN_MASK |
105 LCB_PHY_POW_CTRL_RXCK_PD_MASK |
106 LCB_PHY_POW_CTRL_RX1_PD_MASK |
107 LCB_PHY_POW_CTRL_RX0_PD_MASK);
108 }
109
lcb_lvds_phy1_poweron(LCB_Type * ptr)110 void lcb_lvds_phy1_poweron(LCB_Type *ptr)
111 {
112 ptr->PHY_POW_CTRL[1] &= ~(LCB_PHY_POW_CTRL_IDDQ_EN_MASK |
113 LCB_PHY_POW_CTRL_RXCK_PD_MASK |
114 LCB_PHY_POW_CTRL_RX1_PD_MASK |
115 LCB_PHY_POW_CTRL_RX0_PD_MASK);
116 }
117
lcb_lvds_phy0_powerdown(LCB_Type * ptr)118 void lcb_lvds_phy0_powerdown(LCB_Type *ptr)
119 {
120 ptr->PHY_POW_CTRL[0] |= (LCB_PHY_POW_CTRL_IDDQ_EN_MASK |
121 LCB_PHY_POW_CTRL_RXCK_PD_MASK |
122 LCB_PHY_POW_CTRL_RX1_PD_MASK |
123 LCB_PHY_POW_CTRL_RX0_PD_MASK);
124 }
125
lcb_lvds_phy1_powerdown(LCB_Type * ptr)126 void lcb_lvds_phy1_powerdown(LCB_Type *ptr)
127 {
128 ptr->PHY_POW_CTRL[1] |= (LCB_PHY_POW_CTRL_IDDQ_EN_MASK |
129 LCB_PHY_POW_CTRL_RXCK_PD_MASK |
130 LCB_PHY_POW_CTRL_RX1_PD_MASK |
131 LCB_PHY_POW_CTRL_RX0_PD_MASK);
132 }