Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: ti: j721e-wiz: Implement DisplayPort mode to the wiz driver

For DisplayPort use we need to set WIZ_CONFIG_LANECTL register's
P_STANDARD_MODE bits to "mode 3". In the DisplayPort use also the
P_ENABLE bits of the same register are set to P_ENABLE instead of
P_ENABLE_FORCE, so that the DisplayPort driver can enable and disable
the lane as needed. The DisplayPort mode is selected according to
"cdns,phy-type"-properties found in link subnodes under the managed
serdes (see "ti,sierra-phy-t0" and "ti,j721e-serdes-10g" devicetree
bindings for details). All other values of "cdns,phy-type"-property
but PHY_TYPE_DP will set P_STANDARD_MODE bits to 0 and P_ENABLE bits
to force enable.

Signed-off-by: Jyri Sarha <jsarha@ti.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

authored by

Jyri Sarha and committed by
Kishon Vijay Abraham I
7ae14cf5 8f3d9f35

+55 -4
+55 -4
drivers/phy/ti/phy-j721e-wiz.c
··· 20 20 #include <linux/pm_runtime.h> 21 21 #include <linux/regmap.h> 22 22 #include <linux/reset-controller.h> 23 + #include <dt-bindings/phy/phy.h> 23 24 24 25 #define WIZ_SERDES_CTRL 0x404 25 26 #define WIZ_SERDES_TOP_CTRL 0x408 ··· 78 77 REG_FIELD(WIZ_LANECTL(2), 30, 31), 79 78 REG_FIELD(WIZ_LANECTL(3), 30, 31), 80 79 }; 80 + 81 + enum p_enable { P_ENABLE = 2, P_ENABLE_FORCE = 1, P_ENABLE_DISABLE = 0 }; 81 82 82 83 static const struct reg_field p_align[WIZ_MAX_LANES] = { 83 84 REG_FIELD(WIZ_LANECTL(0), 29, 29), ··· 223 220 struct reset_controller_dev wiz_phy_reset_dev; 224 221 struct gpio_desc *gpio_typec_dir; 225 222 int typec_dir_delay; 223 + u32 lane_phy_type[WIZ_MAX_LANES]; 226 224 }; 227 225 228 226 static int wiz_reset(struct wiz *wiz) ··· 246 242 static int wiz_mode_select(struct wiz *wiz) 247 243 { 248 244 u32 num_lanes = wiz->num_lanes; 245 + enum wiz_lane_standard_mode mode; 249 246 int ret; 250 247 int i; 251 248 252 249 for (i = 0; i < num_lanes; i++) { 253 - ret = regmap_field_write(wiz->p_standard_mode[i], 254 - LANE_MODE_GEN4); 250 + if (wiz->lane_phy_type[i] == PHY_TYPE_DP) 251 + mode = LANE_MODE_GEN1; 252 + else 253 + mode = LANE_MODE_GEN4; 254 + 255 + ret = regmap_field_write(wiz->p_standard_mode[i], mode); 255 256 if (ret) 256 257 return ret; 257 258 } ··· 716 707 return ret; 717 708 } 718 709 719 - ret = regmap_field_write(wiz->p_enable[id - 1], false); 710 + ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_DISABLE); 720 711 return ret; 721 712 } 722 713 ··· 743 734 return ret; 744 735 } 745 736 746 - ret = regmap_field_write(wiz->p_enable[id - 1], true); 737 + if (wiz->lane_phy_type[id - 1] == PHY_TYPE_DP) 738 + ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE); 739 + else 740 + ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_FORCE); 741 + 747 742 return ret; 748 743 } 749 744 ··· 773 760 {} 774 761 }; 775 762 MODULE_DEVICE_TABLE(of, wiz_id_table); 763 + 764 + static int wiz_get_lane_phy_types(struct device *dev, struct wiz *wiz) 765 + { 766 + struct device_node *serdes, *subnode; 767 + 768 + serdes = of_get_child_by_name(dev->of_node, "serdes"); 769 + if (!serdes) { 770 + dev_err(dev, "%s: Getting \"serdes\"-node failed\n", __func__); 771 + return -EINVAL; 772 + } 773 + 774 + for_each_child_of_node(serdes, subnode) { 775 + u32 reg, num_lanes = 1, phy_type = PHY_NONE; 776 + int ret, i; 777 + 778 + ret = of_property_read_u32(subnode, "reg", &reg); 779 + if (ret) { 780 + dev_err(dev, 781 + "%s: Reading \"reg\" from \"%s\" failed: %d\n", 782 + __func__, subnode->name, ret); 783 + return ret; 784 + } 785 + of_property_read_u32(subnode, "cdns,num-lanes", &num_lanes); 786 + of_property_read_u32(subnode, "cdns,phy-type", &phy_type); 787 + 788 + dev_dbg(dev, "%s: Lanes %u-%u have phy-type %u\n", __func__, 789 + reg, reg + num_lanes - 1, phy_type); 790 + 791 + for (i = reg; i < reg + num_lanes; i++) 792 + wiz->lane_phy_type[i] = phy_type; 793 + } 794 + 795 + return 0; 796 + } 776 797 777 798 static int wiz_probe(struct platform_device *pdev) 778 799 { ··· 890 843 goto err_addr_to_resource; 891 844 } 892 845 } 846 + 847 + ret = wiz_get_lane_phy_types(dev, wiz); 848 + if (ret) 849 + return ret; 893 850 894 851 wiz->dev = dev; 895 852 wiz->regmap = regmap;