1186f8572SMark Yao /* 2186f8572SMark Yao * (C) Copyright 2008-2017 Fuzhou Rockchip Electronics Co., Ltd 3186f8572SMark Yao * 4186f8572SMark Yao * SPDX-License-Identifier: GPL-2.0+ 5186f8572SMark Yao */ 6186f8572SMark Yao 7186f8572SMark Yao #include <config.h> 8186f8572SMark Yao #include <common.h> 94b8c2ef1SMark Yao #include <dm/device.h> 10186f8572SMark Yao #include <errno.h> 11186f8572SMark Yao #include <asm/unaligned.h> 12186f8572SMark Yao #include <linux/list.h> 13186f8572SMark Yao 14186f8572SMark Yao #include "rockchip_display.h" 15186f8572SMark Yao #include "rockchip_crtc.h" 16186f8572SMark Yao #include "rockchip_connector.h" 17186f8572SMark Yao #include "rockchip_phy.h" 18186f8572SMark Yao 194b8c2ef1SMark Yao #ifdef CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI 20211d041fSWyon Bi static const struct rockchip_phy rockchip_inno_mipi_dphy_data = { 21740d3834SJerry Xu .funcs = &inno_mipi_dphy_funcs, 22740d3834SJerry Xu }; 234b8c2ef1SMark Yao #endif 244b8c2ef1SMark Yao 25*8e2bab3fSAlgea Cao #ifdef CONFIG_ROCKCHIP_INNO_HDMI_PHY 26*8e2bab3fSAlgea Cao static const struct rockchip_phy rockchip_inno_hdmi_phy_data = { 27*8e2bab3fSAlgea Cao .funcs = &inno_hdmi_phy_funcs, 28*8e2bab3fSAlgea Cao }; 29*8e2bab3fSAlgea Cao #endif 30*8e2bab3fSAlgea Cao 314b8c2ef1SMark Yao static const struct udevice_id rockchip_phy_ids[] = { 324b8c2ef1SMark Yao #ifdef CONFIG_DRM_ROCKCHIP_DW_MIPI_DSI 33186f8572SMark Yao { 34211d041fSWyon Bi .compatible = "rockchip,px30-mipi-dphy", 35211d041fSWyon Bi .data = (ulong)&rockchip_inno_mipi_dphy_data, 36186f8572SMark Yao }, 37740d3834SJerry Xu { 38b7e3dd57SKever Yang .compatible = "rockchip,rk3128-mipi-dphy", 39211d041fSWyon Bi .data = (ulong)&rockchip_inno_mipi_dphy_data, 40211d041fSWyon Bi }, 41211d041fSWyon Bi { 42211d041fSWyon Bi .compatible = "rockchip,rk3366-mipi-dphy", 43211d041fSWyon Bi .data = (ulong)&rockchip_inno_mipi_dphy_data, 44211d041fSWyon Bi }, 45211d041fSWyon Bi { 46211d041fSWyon Bi .compatible = "rockchip,rk3368-mipi-dphy", 47211d041fSWyon Bi .data = (ulong)&rockchip_inno_mipi_dphy_data, 48740d3834SJerry Xu }, 491abf41e2SNickey Yang { 501abf41e2SNickey Yang .compatible = "rockchip,rv1108-mipi-dphy", 511abf41e2SNickey Yang .data = (ulong)&rockchip_inno_mipi_dphy_data, 521abf41e2SNickey Yang }, 53186f8572SMark Yao #endif 54*8e2bab3fSAlgea Cao #ifdef CONFIG_ROCKCHIP_INNO_HDMI_PHY 55*8e2bab3fSAlgea Cao { 56*8e2bab3fSAlgea Cao .compatible = "rockchip,rk3328-hdmi-phy", 57*8e2bab3fSAlgea Cao .data = (ulong)&rockchip_inno_hdmi_phy_data, 58*8e2bab3fSAlgea Cao }, 59*8e2bab3fSAlgea Cao { 60*8e2bab3fSAlgea Cao .compatible = "rockchip,rk3228-hdmi-phy", 61*8e2bab3fSAlgea Cao .data = (ulong)&rockchip_inno_hdmi_phy_data, 62*8e2bab3fSAlgea Cao }, 63*8e2bab3fSAlgea Cao 64*8e2bab3fSAlgea Cao #endif 654b8c2ef1SMark Yao {} 66186f8572SMark Yao }; 67186f8572SMark Yao 684b8c2ef1SMark Yao static int rockchip_phy_probe(struct udevice *dev) 69186f8572SMark Yao { 704b8c2ef1SMark Yao return 0; 71186f8572SMark Yao } 72186f8572SMark Yao 734b8c2ef1SMark Yao static int rockchip_phy_bind(struct udevice *dev) 744b8c2ef1SMark Yao { 754b8c2ef1SMark Yao return 0; 76186f8572SMark Yao } 77186f8572SMark Yao 784b8c2ef1SMark Yao U_BOOT_DRIVER(rockchip_phy) = { 794b8c2ef1SMark Yao .name = "rockchip_phy", 804b8c2ef1SMark Yao .id = UCLASS_PHY, 814b8c2ef1SMark Yao .of_match = rockchip_phy_ids, 824b8c2ef1SMark Yao .bind = rockchip_phy_bind, 834b8c2ef1SMark Yao .probe = rockchip_phy_probe, 844b8c2ef1SMark Yao }; 854b8c2ef1SMark Yao 86186f8572SMark Yao int rockchip_phy_power_on(struct display_state *state) 87186f8572SMark Yao { 88186f8572SMark Yao struct connector_state *conn_state = &state->conn_state; 89186f8572SMark Yao const struct rockchip_phy *phy = conn_state->phy; 90186f8572SMark Yao 91186f8572SMark Yao if (!phy || !phy->funcs || !phy->funcs->power_on) { 92186f8572SMark Yao printf("%s: failed to find phy power on funcs\n", __func__); 93186f8572SMark Yao return -ENODEV; 94186f8572SMark Yao } 95186f8572SMark Yao 96186f8572SMark Yao return phy->funcs->power_on(state); 97186f8572SMark Yao } 98186f8572SMark Yao 99186f8572SMark Yao int rockchip_phy_power_off(struct display_state *state) 100186f8572SMark Yao { 101186f8572SMark Yao struct connector_state *conn_state = &state->conn_state; 102186f8572SMark Yao const struct rockchip_phy *phy = conn_state->phy; 103186f8572SMark Yao 104186f8572SMark Yao if (!phy || !phy->funcs || !phy->funcs->power_off) { 105186f8572SMark Yao printf("%s: failed to find phy power_off funcs\n", __func__); 106186f8572SMark Yao return -ENODEV; 107186f8572SMark Yao } 108186f8572SMark Yao 109186f8572SMark Yao return phy->funcs->power_off(state); 110186f8572SMark Yao } 111186f8572SMark Yao 112186f8572SMark Yao unsigned long rockchip_phy_set_pll(struct display_state *state, 113186f8572SMark Yao unsigned long rate) 114186f8572SMark Yao { 115186f8572SMark Yao struct connector_state *conn_state = &state->conn_state; 116186f8572SMark Yao const struct rockchip_phy *phy = conn_state->phy; 117186f8572SMark Yao 118186f8572SMark Yao if (!phy || !phy->funcs || !phy->funcs->set_pll) { 119186f8572SMark Yao printf("%s: failed to find phy set_pll funcs\n", __func__); 120186f8572SMark Yao return -ENODEV; 121186f8572SMark Yao } 122186f8572SMark Yao 123186f8572SMark Yao return phy->funcs->set_pll(state, rate); 124186f8572SMark Yao } 125*8e2bab3fSAlgea Cao 126*8e2bab3fSAlgea Cao void rockchip_phy_set_bus_width(struct display_state *state, u32 bus_width) 127*8e2bab3fSAlgea Cao { 128*8e2bab3fSAlgea Cao struct connector_state *conn_state = &state->conn_state; 129*8e2bab3fSAlgea Cao const struct rockchip_phy *phy = 130*8e2bab3fSAlgea Cao (struct rockchip_phy *)conn_state->phy; 131*8e2bab3fSAlgea Cao 132*8e2bab3fSAlgea Cao if (!phy || !phy->funcs || !phy->funcs->set_bus_width) { 133*8e2bab3fSAlgea Cao debug("%s: failed to find phy set_bus_width funcs\n", __func__); 134*8e2bab3fSAlgea Cao return; 135*8e2bab3fSAlgea Cao } 136*8e2bab3fSAlgea Cao 137*8e2bab3fSAlgea Cao return phy->funcs->set_bus_width(state, bus_width); 138*8e2bab3fSAlgea Cao } 139*8e2bab3fSAlgea Cao 140*8e2bab3fSAlgea Cao long rockchip_phy_round_rate(struct display_state *state, unsigned long rate) 141*8e2bab3fSAlgea Cao { 142*8e2bab3fSAlgea Cao struct connector_state *conn_state = &state->conn_state; 143*8e2bab3fSAlgea Cao const struct rockchip_phy *phy = 144*8e2bab3fSAlgea Cao (struct rockchip_phy *)conn_state->phy; 145*8e2bab3fSAlgea Cao 146*8e2bab3fSAlgea Cao if (!phy || !phy->funcs || !phy->funcs->round_rate) { 147*8e2bab3fSAlgea Cao debug("%s: failed to find phy round_rate funcs\n", __func__); 148*8e2bab3fSAlgea Cao return -ENODEV; 149*8e2bab3fSAlgea Cao } 150*8e2bab3fSAlgea Cao 151*8e2bab3fSAlgea Cao return phy->funcs->round_rate(state, rate); 152*8e2bab3fSAlgea Cao } 153