1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. 4 */ 5 6 #include <linux/of_gpio.h> 7 #include <linux/phy/phy.h> 8 9 #include <drm/drm_print.h> 10 11 #include "dp_parser.h" 12 #include "dp_reg.h" 13 14 static const struct dp_regulator_cfg sdm845_dp_reg_cfg = { 15 .num = 2, 16 .regs = { 17 {"vdda-1p2", 21800, 4 }, /* 1.2 V */ 18 {"vdda-0p9", 36000, 32 }, /* 0.9 V */ 19 }, 20 }; 21 22 static int msm_dss_ioremap(struct platform_device *pdev, 23 struct dss_io_data *io_data) 24 { 25 struct resource *res = NULL; 26 27 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 28 if (!res) { 29 DRM_ERROR("%pS->%s: msm_dss_get_res failed\n", 30 __builtin_return_address(0), __func__); 31 return -ENODEV; 32 } 33 34 io_data->len = (u32)resource_size(res); 35 io_data->base = ioremap(res->start, io_data->len); 36 if (!io_data->base) { 37 DRM_ERROR("%pS->%s: ioremap failed\n", 38 __builtin_return_address(0), __func__); 39 return -EIO; 40 } 41 42 return 0; 43 } 44 45 static void msm_dss_iounmap(struct dss_io_data *io_data) 46 { 47 if (io_data->base) { 48 iounmap(io_data->base); 49 io_data->base = NULL; 50 } 51 io_data->len = 0; 52 } 53 54 static void dp_parser_unmap_io_resources(struct dp_parser *parser) 55 { 56 struct dp_io *io = &parser->io; 57 58 msm_dss_iounmap(&io->dp_controller); 59 } 60 61 static int dp_parser_ctrl_res(struct dp_parser *parser) 62 { 63 int rc = 0; 64 struct platform_device *pdev = parser->pdev; 65 struct dp_io *io = &parser->io; 66 67 rc = msm_dss_ioremap(pdev, &io->dp_controller); 68 if (rc) { 69 DRM_ERROR("unable to remap dp io resources, rc=%d\n", rc); 70 goto err; 71 } 72 73 io->phy = devm_phy_get(&pdev->dev, "dp"); 74 if (IS_ERR(io->phy)) { 75 rc = PTR_ERR(io->phy); 76 goto err; 77 } 78 79 return 0; 80 err: 81 dp_parser_unmap_io_resources(parser); 82 return rc; 83 } 84 85 static int dp_parser_misc(struct dp_parser *parser) 86 { 87 struct device_node *of_node = parser->pdev->dev.of_node; 88 int len = 0; 89 const char *data_lane_property = "data-lanes"; 90 91 len = of_property_count_elems_of_size(of_node, 92 data_lane_property, sizeof(u32)); 93 if (len < 0) { 94 DRM_WARN("Invalid property %s, default max DP lanes = %d\n", 95 data_lane_property, DP_MAX_NUM_DP_LANES); 96 len = DP_MAX_NUM_DP_LANES; 97 } 98 99 parser->max_dp_lanes = len; 100 return 0; 101 } 102 103 static inline bool dp_parser_check_prefix(const char *clk_prefix, 104 const char *clk_name) 105 { 106 return !strncmp(clk_prefix, clk_name, strlen(clk_prefix)); 107 } 108 109 static int dp_parser_init_clk_data(struct dp_parser *parser) 110 { 111 int num_clk, i, rc; 112 int core_clk_count = 0, ctrl_clk_count = 0, stream_clk_count = 0; 113 const char *clk_name; 114 struct device *dev = &parser->pdev->dev; 115 struct dss_module_power *core_power = &parser->mp[DP_CORE_PM]; 116 struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM]; 117 struct dss_module_power *stream_power = &parser->mp[DP_STREAM_PM]; 118 119 num_clk = of_property_count_strings(dev->of_node, "clock-names"); 120 if (num_clk <= 0) { 121 DRM_ERROR("no clocks are defined\n"); 122 return -EINVAL; 123 } 124 125 for (i = 0; i < num_clk; i++) { 126 rc = of_property_read_string_index(dev->of_node, 127 "clock-names", i, &clk_name); 128 if (rc < 0) 129 return rc; 130 131 if (dp_parser_check_prefix("core", clk_name)) 132 core_clk_count++; 133 134 if (dp_parser_check_prefix("ctrl", clk_name)) 135 ctrl_clk_count++; 136 137 if (dp_parser_check_prefix("stream", clk_name)) 138 stream_clk_count++; 139 } 140 141 /* Initialize the CORE power module */ 142 if (core_clk_count == 0) { 143 DRM_ERROR("no core clocks are defined\n"); 144 return -EINVAL; 145 } 146 147 core_power->num_clk = core_clk_count; 148 core_power->clk_config = devm_kzalloc(dev, 149 sizeof(struct dss_clk) * core_power->num_clk, 150 GFP_KERNEL); 151 if (!core_power->clk_config) 152 return -EINVAL; 153 154 /* Initialize the CTRL power module */ 155 if (ctrl_clk_count == 0) { 156 DRM_ERROR("no ctrl clocks are defined\n"); 157 return -EINVAL; 158 } 159 160 ctrl_power->num_clk = ctrl_clk_count; 161 ctrl_power->clk_config = devm_kzalloc(dev, 162 sizeof(struct dss_clk) * ctrl_power->num_clk, 163 GFP_KERNEL); 164 if (!ctrl_power->clk_config) { 165 ctrl_power->num_clk = 0; 166 return -EINVAL; 167 } 168 169 /* Initialize the STREAM power module */ 170 if (stream_clk_count == 0) { 171 DRM_ERROR("no stream (pixel) clocks are defined\n"); 172 return -EINVAL; 173 } 174 175 stream_power->num_clk = stream_clk_count; 176 stream_power->clk_config = devm_kzalloc(dev, 177 sizeof(struct dss_clk) * stream_power->num_clk, 178 GFP_KERNEL); 179 if (!stream_power->clk_config) { 180 stream_power->num_clk = 0; 181 return -EINVAL; 182 } 183 184 return 0; 185 } 186 187 static int dp_parser_clock(struct dp_parser *parser) 188 { 189 int rc = 0, i = 0; 190 int num_clk = 0; 191 int core_clk_index = 0, ctrl_clk_index = 0, stream_clk_index = 0; 192 int core_clk_count = 0, ctrl_clk_count = 0, stream_clk_count = 0; 193 const char *clk_name; 194 struct device *dev = &parser->pdev->dev; 195 struct dss_module_power *core_power = &parser->mp[DP_CORE_PM]; 196 struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM]; 197 struct dss_module_power *stream_power = &parser->mp[DP_STREAM_PM]; 198 199 rc = dp_parser_init_clk_data(parser); 200 if (rc) { 201 DRM_ERROR("failed to initialize power data %d\n", rc); 202 return -EINVAL; 203 } 204 205 core_clk_count = core_power->num_clk; 206 ctrl_clk_count = ctrl_power->num_clk; 207 stream_clk_count = stream_power->num_clk; 208 209 num_clk = core_clk_count + ctrl_clk_count + stream_clk_count; 210 211 for (i = 0; i < num_clk; i++) { 212 rc = of_property_read_string_index(dev->of_node, "clock-names", 213 i, &clk_name); 214 if (rc) { 215 DRM_ERROR("error reading clock-names %d\n", rc); 216 return rc; 217 } 218 if (dp_parser_check_prefix("core", clk_name) && 219 core_clk_index < core_clk_count) { 220 struct dss_clk *clk = 221 &core_power->clk_config[core_clk_index]; 222 strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name)); 223 clk->type = DSS_CLK_AHB; 224 core_clk_index++; 225 } else if (dp_parser_check_prefix("stream", clk_name) && 226 stream_clk_index < stream_clk_count) { 227 struct dss_clk *clk = 228 &stream_power->clk_config[stream_clk_index]; 229 strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name)); 230 clk->type = DSS_CLK_PCLK; 231 stream_clk_index++; 232 } else if (dp_parser_check_prefix("ctrl", clk_name) && 233 ctrl_clk_index < ctrl_clk_count) { 234 struct dss_clk *clk = 235 &ctrl_power->clk_config[ctrl_clk_index]; 236 strlcpy(clk->clk_name, clk_name, sizeof(clk->clk_name)); 237 ctrl_clk_index++; 238 if (dp_parser_check_prefix("ctrl_link", clk_name) || 239 dp_parser_check_prefix("stream_pixel", clk_name)) 240 clk->type = DSS_CLK_PCLK; 241 else 242 clk->type = DSS_CLK_AHB; 243 } 244 } 245 246 DRM_DEBUG_DP("clock parsing successful\n"); 247 248 return 0; 249 } 250 251 static int dp_parser_parse(struct dp_parser *parser) 252 { 253 int rc = 0; 254 255 if (!parser) { 256 DRM_ERROR("invalid input\n"); 257 return -EINVAL; 258 } 259 260 rc = dp_parser_ctrl_res(parser); 261 if (rc) 262 return rc; 263 264 rc = dp_parser_misc(parser); 265 if (rc) 266 return rc; 267 268 rc = dp_parser_clock(parser); 269 if (rc) 270 return rc; 271 272 /* Map the corresponding regulator information according to 273 * version. Currently, since we only have one supported platform, 274 * mapping the regulator directly. 275 */ 276 parser->regulator_cfg = &sdm845_dp_reg_cfg; 277 278 return 0; 279 } 280 281 struct dp_parser *dp_parser_get(struct platform_device *pdev) 282 { 283 struct dp_parser *parser; 284 285 parser = devm_kzalloc(&pdev->dev, sizeof(*parser), GFP_KERNEL); 286 if (!parser) 287 return ERR_PTR(-ENOMEM); 288 289 parser->parse = dp_parser_parse; 290 parser->pdev = pdev; 291 292 return parser; 293 } 294