1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4*4882a593Smuzhiyun */
5*4882a593Smuzhiyun
6*4882a593Smuzhiyun #ifndef __DSI_CONNECTOR_H__
7*4882a593Smuzhiyun #define __DSI_CONNECTOR_H__
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <linux/of_platform.h>
10*4882a593Smuzhiyun #include <linux/platform_device.h>
11*4882a593Smuzhiyun
12*4882a593Smuzhiyun #include <drm/drm_bridge.h>
13*4882a593Smuzhiyun #include <drm/drm_crtc.h>
14*4882a593Smuzhiyun #include <drm/drm_mipi_dsi.h>
15*4882a593Smuzhiyun #include <drm/drm_panel.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #include "msm_drv.h"
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #define DSI_0 0
20*4882a593Smuzhiyun #define DSI_1 1
21*4882a593Smuzhiyun #define DSI_MAX 2
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun struct msm_dsi_phy_shared_timings;
24*4882a593Smuzhiyun struct msm_dsi_phy_clk_request;
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun enum msm_dsi_phy_type {
27*4882a593Smuzhiyun MSM_DSI_PHY_28NM_HPM,
28*4882a593Smuzhiyun MSM_DSI_PHY_28NM_LP,
29*4882a593Smuzhiyun MSM_DSI_PHY_20NM,
30*4882a593Smuzhiyun MSM_DSI_PHY_28NM_8960,
31*4882a593Smuzhiyun MSM_DSI_PHY_14NM,
32*4882a593Smuzhiyun MSM_DSI_PHY_10NM,
33*4882a593Smuzhiyun MSM_DSI_PHY_7NM,
34*4882a593Smuzhiyun MSM_DSI_PHY_7NM_V4_1,
35*4882a593Smuzhiyun MSM_DSI_PHY_MAX
36*4882a593Smuzhiyun };
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun enum msm_dsi_phy_usecase {
39*4882a593Smuzhiyun MSM_DSI_PHY_STANDALONE,
40*4882a593Smuzhiyun MSM_DSI_PHY_MASTER,
41*4882a593Smuzhiyun MSM_DSI_PHY_SLAVE,
42*4882a593Smuzhiyun };
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #define DSI_DEV_REGULATOR_MAX 8
45*4882a593Smuzhiyun #define DSI_BUS_CLK_MAX 4
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /* Regulators for DSI devices */
48*4882a593Smuzhiyun struct dsi_reg_entry {
49*4882a593Smuzhiyun char name[32];
50*4882a593Smuzhiyun int enable_load;
51*4882a593Smuzhiyun int disable_load;
52*4882a593Smuzhiyun };
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun struct dsi_reg_config {
55*4882a593Smuzhiyun int num;
56*4882a593Smuzhiyun struct dsi_reg_entry regs[DSI_DEV_REGULATOR_MAX];
57*4882a593Smuzhiyun };
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun struct msm_dsi {
60*4882a593Smuzhiyun struct drm_device *dev;
61*4882a593Smuzhiyun struct platform_device *pdev;
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun /* connector managed by us when we're connected to a drm_panel */
64*4882a593Smuzhiyun struct drm_connector *connector;
65*4882a593Smuzhiyun /* internal dsi bridge attached to MDP interface */
66*4882a593Smuzhiyun struct drm_bridge *bridge;
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun struct mipi_dsi_host *host;
69*4882a593Smuzhiyun struct msm_dsi_phy *phy;
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun /*
72*4882a593Smuzhiyun * panel/external_bridge connected to dsi bridge output, only one of the
73*4882a593Smuzhiyun * two can be valid at a time
74*4882a593Smuzhiyun */
75*4882a593Smuzhiyun struct drm_panel *panel;
76*4882a593Smuzhiyun struct drm_bridge *external_bridge;
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun struct device *phy_dev;
79*4882a593Smuzhiyun bool phy_enabled;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun /* the encoder we are hooked to (outside of dsi block) */
82*4882a593Smuzhiyun struct drm_encoder *encoder;
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun int id;
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun /* dsi manager */
88*4882a593Smuzhiyun struct drm_bridge *msm_dsi_manager_bridge_init(u8 id);
89*4882a593Smuzhiyun void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge);
90*4882a593Smuzhiyun struct drm_connector *msm_dsi_manager_connector_init(u8 id);
91*4882a593Smuzhiyun struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id);
92*4882a593Smuzhiyun int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg);
93*4882a593Smuzhiyun bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len);
94*4882a593Smuzhiyun void msm_dsi_manager_setup_encoder(int id);
95*4882a593Smuzhiyun int msm_dsi_manager_register(struct msm_dsi *msm_dsi);
96*4882a593Smuzhiyun void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi);
97*4882a593Smuzhiyun bool msm_dsi_manager_validate_current_config(u8 id);
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun /* msm dsi */
msm_dsi_device_connected(struct msm_dsi * msm_dsi)100*4882a593Smuzhiyun static inline bool msm_dsi_device_connected(struct msm_dsi *msm_dsi)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun return msm_dsi->panel || msm_dsi->external_bridge;
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun struct drm_encoder *msm_dsi_get_encoder(struct msm_dsi *msm_dsi);
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun /* dsi pll */
108*4882a593Smuzhiyun struct msm_dsi_pll;
109*4882a593Smuzhiyun #ifdef CONFIG_DRM_MSM_DSI_PLL
110*4882a593Smuzhiyun struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev,
111*4882a593Smuzhiyun enum msm_dsi_phy_type type, int dsi_id);
112*4882a593Smuzhiyun void msm_dsi_pll_destroy(struct msm_dsi_pll *pll);
113*4882a593Smuzhiyun int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll,
114*4882a593Smuzhiyun struct clk **byte_clk_provider, struct clk **pixel_clk_provider);
115*4882a593Smuzhiyun void msm_dsi_pll_save_state(struct msm_dsi_pll *pll);
116*4882a593Smuzhiyun int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll);
117*4882a593Smuzhiyun int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll,
118*4882a593Smuzhiyun enum msm_dsi_phy_usecase uc);
119*4882a593Smuzhiyun #else
msm_dsi_pll_init(struct platform_device * pdev,enum msm_dsi_phy_type type,int id)120*4882a593Smuzhiyun static inline struct msm_dsi_pll *msm_dsi_pll_init(struct platform_device *pdev,
121*4882a593Smuzhiyun enum msm_dsi_phy_type type, int id) {
122*4882a593Smuzhiyun return ERR_PTR(-ENODEV);
123*4882a593Smuzhiyun }
msm_dsi_pll_destroy(struct msm_dsi_pll * pll)124*4882a593Smuzhiyun static inline void msm_dsi_pll_destroy(struct msm_dsi_pll *pll)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun }
msm_dsi_pll_get_clk_provider(struct msm_dsi_pll * pll,struct clk ** byte_clk_provider,struct clk ** pixel_clk_provider)127*4882a593Smuzhiyun static inline int msm_dsi_pll_get_clk_provider(struct msm_dsi_pll *pll,
128*4882a593Smuzhiyun struct clk **byte_clk_provider, struct clk **pixel_clk_provider)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun return -ENODEV;
131*4882a593Smuzhiyun }
msm_dsi_pll_save_state(struct msm_dsi_pll * pll)132*4882a593Smuzhiyun static inline void msm_dsi_pll_save_state(struct msm_dsi_pll *pll)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun }
msm_dsi_pll_restore_state(struct msm_dsi_pll * pll)135*4882a593Smuzhiyun static inline int msm_dsi_pll_restore_state(struct msm_dsi_pll *pll)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun return 0;
138*4882a593Smuzhiyun }
msm_dsi_pll_set_usecase(struct msm_dsi_pll * pll,enum msm_dsi_phy_usecase uc)139*4882a593Smuzhiyun static inline int msm_dsi_pll_set_usecase(struct msm_dsi_pll *pll,
140*4882a593Smuzhiyun enum msm_dsi_phy_usecase uc)
141*4882a593Smuzhiyun {
142*4882a593Smuzhiyun return -ENODEV;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun #endif
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun /* dsi host */
147*4882a593Smuzhiyun struct msm_dsi_host;
148*4882a593Smuzhiyun int msm_dsi_host_xfer_prepare(struct mipi_dsi_host *host,
149*4882a593Smuzhiyun const struct mipi_dsi_msg *msg);
150*4882a593Smuzhiyun void msm_dsi_host_xfer_restore(struct mipi_dsi_host *host,
151*4882a593Smuzhiyun const struct mipi_dsi_msg *msg);
152*4882a593Smuzhiyun int msm_dsi_host_cmd_tx(struct mipi_dsi_host *host,
153*4882a593Smuzhiyun const struct mipi_dsi_msg *msg);
154*4882a593Smuzhiyun int msm_dsi_host_cmd_rx(struct mipi_dsi_host *host,
155*4882a593Smuzhiyun const struct mipi_dsi_msg *msg);
156*4882a593Smuzhiyun void msm_dsi_host_cmd_xfer_commit(struct mipi_dsi_host *host,
157*4882a593Smuzhiyun u32 dma_base, u32 len);
158*4882a593Smuzhiyun int msm_dsi_host_enable(struct mipi_dsi_host *host);
159*4882a593Smuzhiyun int msm_dsi_host_disable(struct mipi_dsi_host *host);
160*4882a593Smuzhiyun int msm_dsi_host_power_on(struct mipi_dsi_host *host,
161*4882a593Smuzhiyun struct msm_dsi_phy_shared_timings *phy_shared_timings,
162*4882a593Smuzhiyun bool is_dual_dsi);
163*4882a593Smuzhiyun int msm_dsi_host_power_off(struct mipi_dsi_host *host);
164*4882a593Smuzhiyun int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host,
165*4882a593Smuzhiyun const struct drm_display_mode *mode);
166*4882a593Smuzhiyun struct drm_panel *msm_dsi_host_get_panel(struct mipi_dsi_host *host);
167*4882a593Smuzhiyun unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host);
168*4882a593Smuzhiyun struct drm_bridge *msm_dsi_host_get_bridge(struct mipi_dsi_host *host);
169*4882a593Smuzhiyun int msm_dsi_host_register(struct mipi_dsi_host *host, bool check_defer);
170*4882a593Smuzhiyun void msm_dsi_host_unregister(struct mipi_dsi_host *host);
171*4882a593Smuzhiyun int msm_dsi_host_set_src_pll(struct mipi_dsi_host *host,
172*4882a593Smuzhiyun struct msm_dsi_pll *src_pll);
173*4882a593Smuzhiyun void msm_dsi_host_reset_phy(struct mipi_dsi_host *host);
174*4882a593Smuzhiyun void msm_dsi_host_get_phy_clk_req(struct mipi_dsi_host *host,
175*4882a593Smuzhiyun struct msm_dsi_phy_clk_request *clk_req,
176*4882a593Smuzhiyun bool is_dual_dsi);
177*4882a593Smuzhiyun void msm_dsi_host_destroy(struct mipi_dsi_host *host);
178*4882a593Smuzhiyun int msm_dsi_host_modeset_init(struct mipi_dsi_host *host,
179*4882a593Smuzhiyun struct drm_device *dev);
180*4882a593Smuzhiyun int msm_dsi_host_init(struct msm_dsi *msm_dsi);
181*4882a593Smuzhiyun int msm_dsi_runtime_suspend(struct device *dev);
182*4882a593Smuzhiyun int msm_dsi_runtime_resume(struct device *dev);
183*4882a593Smuzhiyun int dsi_link_clk_set_rate_6g(struct msm_dsi_host *msm_host);
184*4882a593Smuzhiyun int dsi_link_clk_set_rate_v2(struct msm_dsi_host *msm_host);
185*4882a593Smuzhiyun int dsi_link_clk_enable_6g(struct msm_dsi_host *msm_host);
186*4882a593Smuzhiyun int dsi_link_clk_enable_v2(struct msm_dsi_host *msm_host);
187*4882a593Smuzhiyun void dsi_link_clk_disable_6g(struct msm_dsi_host *msm_host);
188*4882a593Smuzhiyun void dsi_link_clk_disable_v2(struct msm_dsi_host *msm_host);
189*4882a593Smuzhiyun int dsi_tx_buf_alloc_6g(struct msm_dsi_host *msm_host, int size);
190*4882a593Smuzhiyun int dsi_tx_buf_alloc_v2(struct msm_dsi_host *msm_host, int size);
191*4882a593Smuzhiyun void *dsi_tx_buf_get_6g(struct msm_dsi_host *msm_host);
192*4882a593Smuzhiyun void *dsi_tx_buf_get_v2(struct msm_dsi_host *msm_host);
193*4882a593Smuzhiyun void dsi_tx_buf_put_6g(struct msm_dsi_host *msm_host);
194*4882a593Smuzhiyun int dsi_dma_base_get_6g(struct msm_dsi_host *msm_host, uint64_t *iova);
195*4882a593Smuzhiyun int dsi_dma_base_get_v2(struct msm_dsi_host *msm_host, uint64_t *iova);
196*4882a593Smuzhiyun int dsi_clk_init_v2(struct msm_dsi_host *msm_host);
197*4882a593Smuzhiyun int dsi_clk_init_6g_v2(struct msm_dsi_host *msm_host);
198*4882a593Smuzhiyun int dsi_calc_clk_rate_v2(struct msm_dsi_host *msm_host, bool is_dual_dsi);
199*4882a593Smuzhiyun int dsi_calc_clk_rate_6g(struct msm_dsi_host *msm_host, bool is_dual_dsi);
200*4882a593Smuzhiyun
201*4882a593Smuzhiyun /* dsi phy */
202*4882a593Smuzhiyun struct msm_dsi_phy;
203*4882a593Smuzhiyun struct msm_dsi_phy_shared_timings {
204*4882a593Smuzhiyun u32 clk_post;
205*4882a593Smuzhiyun u32 clk_pre;
206*4882a593Smuzhiyun bool clk_pre_inc_by_2;
207*4882a593Smuzhiyun };
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun struct msm_dsi_phy_clk_request {
210*4882a593Smuzhiyun unsigned long bitclk_rate;
211*4882a593Smuzhiyun unsigned long escclk_rate;
212*4882a593Smuzhiyun };
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun void msm_dsi_phy_driver_register(void);
215*4882a593Smuzhiyun void msm_dsi_phy_driver_unregister(void);
216*4882a593Smuzhiyun int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id,
217*4882a593Smuzhiyun struct msm_dsi_phy_clk_request *clk_req);
218*4882a593Smuzhiyun void msm_dsi_phy_disable(struct msm_dsi_phy *phy);
219*4882a593Smuzhiyun void msm_dsi_phy_get_shared_timings(struct msm_dsi_phy *phy,
220*4882a593Smuzhiyun struct msm_dsi_phy_shared_timings *shared_timing);
221*4882a593Smuzhiyun struct msm_dsi_pll *msm_dsi_phy_get_pll(struct msm_dsi_phy *phy);
222*4882a593Smuzhiyun void msm_dsi_phy_set_usecase(struct msm_dsi_phy *phy,
223*4882a593Smuzhiyun enum msm_dsi_phy_usecase uc);
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun #endif /* __DSI_CONNECTOR_H__ */
226*4882a593Smuzhiyun
227