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, &param);
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(&param.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(&param.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