• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = true;
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     lvb_ch_config(lvb_base, lvb_ch_num_0, &lvb_ch_cfg);
30     lvb_ch_config(lvb_base, lvb_ch_num_1, &lvb_ch_cfg);
31 
32     lvb_ch_enable(lvb_base, lvb_ch_num_0);
33     lvb_ch_enable(lvb_base, lvb_ch_num_1);
34 }
35 
lvds_panel_phy_init(hpm_panel_t * panel)36 static void lvds_panel_phy_init(hpm_panel_t *panel)
37 {
38     LVB_Type *lvb_base = panel->hw_if.video.lvds.lvb_base;
39     lvds_phy_clk_param_t param;
40     uint32_t pixel_clk = panel->hw_if.lcdc_pixel_clk_khz * 1000;
41     pixelmux_lvds_phy_calc_pll_cfg(pixel_clk, true, &param);
42     pixelmux_config_lvds_tx_phy0_clk(&param.reg);
43     pixelmux_config_lvds_tx_phy1_clk(&param.reg);
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     lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx0, &lvds_lane_cfg);
49     lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx1, &lvds_lane_cfg);
50     lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx2, &lvds_lane_cfg);
51     lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_tx3, &lvds_lane_cfg);
52     lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds0_txck, &lvds_lane_cfg);
53     lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx0, &lvds_lane_cfg);
54     lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx1, &lvds_lane_cfg);
55     lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx2, &lvds_lane_cfg);
56     lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_tx3, &lvds_lane_cfg);
57     lvb_lvds_phy_lane_init(lvb_base, lvb_lvds_lane_idx_lvds1_txck, &lvds_lane_cfg);
58 
59     lvb_lvds_phy0_poweron(lvb_base);
60     lvb_lvds_phy1_poweron(lvb_base);
61 
62     while (lvb_lvds_phy_split_pll_is_lock(lvb_base) == false) {
63     }
64 }
65 
reset(hpm_panel_t * panel)66 static void reset(hpm_panel_t *panel)
67 {
68     if (!panel->hw_if.set_reset_pin_level)
69         return;
70 
71     panel->hw_if.set_reset_pin_level(0);
72     hpm_panel_delay_us(2000);
73 
74     panel->hw_if.set_reset_pin_level(1);
75     hpm_panel_delay_us(2000);
76 }
77 
init(hpm_panel_t * panel)78 static void init(hpm_panel_t *panel)
79 {
80     if (panel->hw_if.set_video_router)
81         panel->hw_if.set_video_router();
82 
83     lvds_panel_lvb_init(panel);
84     lvds_panel_phy_init(panel);
85 }
86 
87 hpm_panel_t panel_tm103xdgp01 = {
88     .name = "tm103xdgp01",
89     .if_type = HPM_PANEL_IF_TYPE_LVDS_SPLIT,
90     .timing = {
91         .pixel_clock_khz = 45000,
92         .hactive = 1920,
93         .hfront_porch = 32,
94         .hback_porch = 32,
95         .hsync_len = 64,
96 
97         .vactive = 720,
98         .vfront_porch = 2,
99         .vback_porch = 2,
100         .vsync_len = 4,
101     },
102     .funcs = {
103         .reset = reset,
104         .init = init,
105     },
106 };
107 
108