1 /*
2 * Copyright (c) 2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7 #include "hpm_panel.h"
8 #include "hpm_pixelmux_drv.h"
9 #include "hpm_lvb_drv.h"
10
lvds_panel_lvb_init(hpm_panel_t * panel)11 static void lvds_panel_lvb_init(hpm_panel_t *panel)
12 {
13 LVB_Type *lvb_base = panel->hw_if.video.lvds.lvb_base;
14 lvb_config_t lvb_config;
15 lvb_get_default_config(&lvb_config);
16
17 lvb_config.split_mode_en = false;
18 lvb_config.txclk_shift = lvb_txclk_shift_1100011;
19 lvb_init(lvb_base, &lvb_config);
20
21 lvb_ch_config_t lvb_ch_cfg;
22 lvb_ch_cfg.map = lvb_ch_mapping_vesa;
23
24 if (panel->hw_if.video.lvds.channel_di_index == 0)
25 lvb_ch_cfg.data_src = lvb_ch_data_source_di0;
26 else
27 lvb_ch_cfg.data_src = lvb_ch_data_source_di1;
28
29 if (panel->hw_if.video.lvds.channel_index == 0) {
30 lvb_ch_config(lvb_base, lvb_ch_num_0, &lvb_ch_cfg);
31 lvb_ch_enable(lvb_base, lvb_ch_num_0);
32 } else {
33 lvb_ch_config(lvb_base, lvb_ch_num_1, &lvb_ch_cfg);
34 lvb_ch_enable(lvb_base, lvb_ch_num_1);
35 }
36 }
37
lvds_panel_phy_init(hpm_panel_t * panel)38 static void lvds_panel_phy_init(hpm_panel_t *panel)
39 {
40 LVB_Type *lvb_base = panel->hw_if.video.lvds.lvb_base;
41 lvds_phy_clk_param_t param;
42 uint32_t pixel_clk = panel->hw_if.lcdc_pixel_clk_khz * 1000;
43 pixelmux_lvds_phy_calc_pll_cfg(pixel_clk, false, ¶m);
44
45 lvb_lvds_phy_lane_config_t lvds_lane_cfg;
46 lvb_lvds_phy_lane_get_default_config(&lvds_lane_cfg);
47 lvds_lane_cfg.fvco_div4 = param.reg.data_rate_div4;
48
49 if (panel->hw_if.video.lvds.channel_index == 0) {
50 pixelmux_config_lvds_tx_phy0_clk(¶m.reg);
51 lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx0, &lvds_lane_cfg);
52 lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx1, &lvds_lane_cfg);
53 lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx2, &lvds_lane_cfg);
54 lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx3, &lvds_lane_cfg);
55 lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_txck, &lvds_lane_cfg);
56 lvb_lvds_phy0_poweron(lvb_base);
57
58 while (lvb_lvds_phy0_pll_is_lock(lvb_base) == false) {
59 }
60 } else {
61 pixelmux_config_lvds_tx_phy1_clk(¶m.reg);
62 lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx0, &lvds_lane_cfg);
63 lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx1, &lvds_lane_cfg);
64 lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx2, &lvds_lane_cfg);
65 lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx3, &lvds_lane_cfg);
66 lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_txck, &lvds_lane_cfg);
67 lvb_lvds_phy1_poweron(lvb_base);
68
69 while (lvb_lvds_phy1_pll_is_lock(lvb_base) == false) {
70 }
71 }
72 }
73
reset(hpm_panel_t * panel)74 static void reset(hpm_panel_t *panel)
75 {
76 if (!panel->hw_if.set_reset_pin_level)
77 return;
78
79 panel->hw_if.set_reset_pin_level(0);
80 hpm_panel_delay_us(2000);
81
82 panel->hw_if.set_reset_pin_level(1);
83 hpm_panel_delay_us(2000);
84 }
85
init(hpm_panel_t * panel)86 static void init(hpm_panel_t *panel)
87 {
88 if (panel->hw_if.set_video_router)
89 panel->hw_if.set_video_router();
90
91 lvds_panel_lvb_init(panel);
92 lvds_panel_phy_init(panel);
93 }
94
power_on(hpm_panel_t * panel)95 static void power_on(hpm_panel_t *panel)
96 {
97 if (panel->state.power_state != HPM_PANEL_STATE_POWER_ON &&
98 panel->hw_if.set_backlight) {
99 if (panel->state.backlight_percent == 0)
100 panel->state.backlight_percent = 100;
101
102 panel->hw_if.set_backlight(panel->state.backlight_percent);
103 panel->state.power_state = HPM_PANEL_STATE_POWER_ON;
104 }
105 }
106
power_off(hpm_panel_t * panel)107 static void power_off(hpm_panel_t *panel)
108 {
109 if (panel->state.power_state != HPM_PANEL_STATE_POWER_OFF &&
110 panel->hw_if.set_backlight) {
111
112 panel->hw_if.set_backlight(0);
113 panel->state.power_state = HPM_PANEL_STATE_POWER_OFF;
114 }
115 }
116
117 hpm_panel_t panel_cc10128007 = {
118 .name = "cc10128007",
119 .if_type = HPM_PANEL_IF_TYPE_LVDS_SINGLE,
120 .timing = {
121 .pixel_clock_khz = 74250,
122 .hactive = 800,
123 .hfront_porch = 60,
124 .hback_porch = 60,
125 .hsync_len = 40,
126
127 .vactive = 1280,
128 .vfront_porch = 18,
129 .vback_porch = 18,
130 .vsync_len = 6,
131 },
132 .funcs = {
133 .reset = reset,
134 .init = init,
135 .power_on = power_on,
136 .power_off = power_off,
137 },
138 };
139
140