0001
0002
0003
0004
0005
0006 #include <linux/of_gpio.h>
0007 #include <linux/phy/phy.h>
0008
0009 #include <drm/drm_of.h>
0010 #include <drm/drm_print.h>
0011 #include <drm/drm_bridge.h>
0012
0013 #include "dp_parser.h"
0014 #include "dp_reg.h"
0015
0016 #define DP_DEFAULT_AHB_OFFSET 0x0000
0017 #define DP_DEFAULT_AHB_SIZE 0x0200
0018 #define DP_DEFAULT_AUX_OFFSET 0x0200
0019 #define DP_DEFAULT_AUX_SIZE 0x0200
0020 #define DP_DEFAULT_LINK_OFFSET 0x0400
0021 #define DP_DEFAULT_LINK_SIZE 0x0C00
0022 #define DP_DEFAULT_P0_OFFSET 0x1000
0023 #define DP_DEFAULT_P0_SIZE 0x0400
0024
0025 static void __iomem *dp_ioremap(struct platform_device *pdev, int idx, size_t *len)
0026 {
0027 struct resource *res;
0028 void __iomem *base;
0029
0030 base = devm_platform_get_and_ioremap_resource(pdev, idx, &res);
0031 if (!IS_ERR(base))
0032 *len = resource_size(res);
0033
0034 return base;
0035 }
0036
0037 static int dp_parser_ctrl_res(struct dp_parser *parser)
0038 {
0039 struct platform_device *pdev = parser->pdev;
0040 struct dp_io *io = &parser->io;
0041 struct dss_io_data *dss = &io->dp_controller;
0042
0043 dss->ahb.base = dp_ioremap(pdev, 0, &dss->ahb.len);
0044 if (IS_ERR(dss->ahb.base))
0045 return PTR_ERR(dss->ahb.base);
0046
0047 dss->aux.base = dp_ioremap(pdev, 1, &dss->aux.len);
0048 if (IS_ERR(dss->aux.base)) {
0049
0050
0051
0052
0053
0054
0055
0056 if (PTR_ERR(dss->aux.base) == -EINVAL) {
0057 if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
0058 DRM_ERROR("legacy memory region not large enough\n");
0059 return -EINVAL;
0060 }
0061
0062 dss->ahb.len = DP_DEFAULT_AHB_SIZE;
0063 dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET;
0064 dss->aux.len = DP_DEFAULT_AUX_SIZE;
0065 dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET;
0066 dss->link.len = DP_DEFAULT_LINK_SIZE;
0067 dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET;
0068 dss->p0.len = DP_DEFAULT_P0_SIZE;
0069 } else {
0070 DRM_ERROR("unable to remap aux region: %pe\n", dss->aux.base);
0071 return PTR_ERR(dss->aux.base);
0072 }
0073 } else {
0074 dss->link.base = dp_ioremap(pdev, 2, &dss->link.len);
0075 if (IS_ERR(dss->link.base)) {
0076 DRM_ERROR("unable to remap link region: %pe\n", dss->link.base);
0077 return PTR_ERR(dss->link.base);
0078 }
0079
0080 dss->p0.base = dp_ioremap(pdev, 3, &dss->p0.len);
0081 if (IS_ERR(dss->p0.base)) {
0082 DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0.base);
0083 return PTR_ERR(dss->p0.base);
0084 }
0085 }
0086
0087 io->phy = devm_phy_get(&pdev->dev, "dp");
0088 if (IS_ERR(io->phy))
0089 return PTR_ERR(io->phy);
0090
0091 return 0;
0092 }
0093
0094 static int dp_parser_misc(struct dp_parser *parser)
0095 {
0096 struct device_node *of_node = parser->pdev->dev.of_node;
0097 int len;
0098
0099 len = drm_of_get_data_lanes_count(of_node, 1, DP_MAX_NUM_DP_LANES);
0100 if (len < 0) {
0101 DRM_WARN("Invalid property \"data-lanes\", default max DP lanes = %d\n",
0102 DP_MAX_NUM_DP_LANES);
0103 len = DP_MAX_NUM_DP_LANES;
0104 }
0105
0106 parser->max_dp_lanes = len;
0107 return 0;
0108 }
0109
0110 static inline bool dp_parser_check_prefix(const char *clk_prefix,
0111 const char *clk_name)
0112 {
0113 return !strncmp(clk_prefix, clk_name, strlen(clk_prefix));
0114 }
0115
0116 static int dp_parser_init_clk_data(struct dp_parser *parser)
0117 {
0118 int num_clk, i, rc;
0119 int core_clk_count = 0, ctrl_clk_count = 0, stream_clk_count = 0;
0120 const char *clk_name;
0121 struct device *dev = &parser->pdev->dev;
0122 struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
0123 struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM];
0124 struct dss_module_power *stream_power = &parser->mp[DP_STREAM_PM];
0125
0126 num_clk = of_property_count_strings(dev->of_node, "clock-names");
0127 if (num_clk <= 0) {
0128 DRM_ERROR("no clocks are defined\n");
0129 return -EINVAL;
0130 }
0131
0132 for (i = 0; i < num_clk; i++) {
0133 rc = of_property_read_string_index(dev->of_node,
0134 "clock-names", i, &clk_name);
0135 if (rc < 0)
0136 return rc;
0137
0138 if (dp_parser_check_prefix("core", clk_name))
0139 core_clk_count++;
0140
0141 if (dp_parser_check_prefix("ctrl", clk_name))
0142 ctrl_clk_count++;
0143
0144 if (dp_parser_check_prefix("stream", clk_name))
0145 stream_clk_count++;
0146 }
0147
0148
0149 if (core_clk_count == 0) {
0150 DRM_ERROR("no core clocks are defined\n");
0151 return -EINVAL;
0152 }
0153
0154 core_power->num_clk = core_clk_count;
0155 core_power->clocks = devm_kcalloc(dev,
0156 core_power->num_clk, sizeof(struct clk_bulk_data),
0157 GFP_KERNEL);
0158 if (!core_power->clocks)
0159 return -ENOMEM;
0160
0161
0162 if (ctrl_clk_count == 0) {
0163 DRM_ERROR("no ctrl clocks are defined\n");
0164 return -EINVAL;
0165 }
0166
0167 ctrl_power->num_clk = ctrl_clk_count;
0168 ctrl_power->clocks = devm_kcalloc(dev,
0169 ctrl_power->num_clk, sizeof(struct clk_bulk_data),
0170 GFP_KERNEL);
0171 if (!ctrl_power->clocks) {
0172 ctrl_power->num_clk = 0;
0173 return -ENOMEM;
0174 }
0175
0176
0177 if (stream_clk_count == 0) {
0178 DRM_ERROR("no stream (pixel) clocks are defined\n");
0179 return -EINVAL;
0180 }
0181
0182 stream_power->num_clk = stream_clk_count;
0183 stream_power->clocks = devm_kcalloc(dev,
0184 stream_power->num_clk, sizeof(struct clk_bulk_data),
0185 GFP_KERNEL);
0186 if (!stream_power->clocks) {
0187 stream_power->num_clk = 0;
0188 return -ENOMEM;
0189 }
0190
0191 return 0;
0192 }
0193
0194 static int dp_parser_clock(struct dp_parser *parser)
0195 {
0196 int rc = 0, i = 0;
0197 int num_clk = 0;
0198 int core_clk_index = 0, ctrl_clk_index = 0, stream_clk_index = 0;
0199 int core_clk_count = 0, ctrl_clk_count = 0, stream_clk_count = 0;
0200 const char *clk_name;
0201 struct device *dev = &parser->pdev->dev;
0202 struct dss_module_power *core_power = &parser->mp[DP_CORE_PM];
0203 struct dss_module_power *ctrl_power = &parser->mp[DP_CTRL_PM];
0204 struct dss_module_power *stream_power = &parser->mp[DP_STREAM_PM];
0205
0206 rc = dp_parser_init_clk_data(parser);
0207 if (rc) {
0208 DRM_ERROR("failed to initialize power data %d\n", rc);
0209 return -EINVAL;
0210 }
0211
0212 core_clk_count = core_power->num_clk;
0213 ctrl_clk_count = ctrl_power->num_clk;
0214 stream_clk_count = stream_power->num_clk;
0215
0216 num_clk = core_clk_count + ctrl_clk_count + stream_clk_count;
0217
0218 for (i = 0; i < num_clk; i++) {
0219 rc = of_property_read_string_index(dev->of_node, "clock-names",
0220 i, &clk_name);
0221 if (rc) {
0222 DRM_ERROR("error reading clock-names %d\n", rc);
0223 return rc;
0224 }
0225 if (dp_parser_check_prefix("core", clk_name) &&
0226 core_clk_index < core_clk_count) {
0227 core_power->clocks[core_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
0228 core_clk_index++;
0229 } else if (dp_parser_check_prefix("stream", clk_name) &&
0230 stream_clk_index < stream_clk_count) {
0231 stream_power->clocks[stream_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
0232 stream_clk_index++;
0233 } else if (dp_parser_check_prefix("ctrl", clk_name) &&
0234 ctrl_clk_index < ctrl_clk_count) {
0235 ctrl_power->clocks[ctrl_clk_index].id = devm_kstrdup(dev, clk_name, GFP_KERNEL);
0236 ctrl_clk_index++;
0237 }
0238 }
0239
0240 return 0;
0241 }
0242
0243 int dp_parser_find_next_bridge(struct dp_parser *parser)
0244 {
0245 struct device *dev = &parser->pdev->dev;
0246 struct drm_bridge *bridge;
0247
0248 bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0);
0249 if (IS_ERR(bridge))
0250 return PTR_ERR(bridge);
0251
0252 parser->next_bridge = bridge;
0253
0254 return 0;
0255 }
0256
0257 static int dp_parser_parse(struct dp_parser *parser)
0258 {
0259 int rc = 0;
0260
0261 if (!parser) {
0262 DRM_ERROR("invalid input\n");
0263 return -EINVAL;
0264 }
0265
0266 rc = dp_parser_ctrl_res(parser);
0267 if (rc)
0268 return rc;
0269
0270 rc = dp_parser_misc(parser);
0271 if (rc)
0272 return rc;
0273
0274 rc = dp_parser_clock(parser);
0275 if (rc)
0276 return rc;
0277
0278 return 0;
0279 }
0280
0281 struct dp_parser *dp_parser_get(struct platform_device *pdev)
0282 {
0283 struct dp_parser *parser;
0284
0285 parser = devm_kzalloc(&pdev->dev, sizeof(*parser), GFP_KERNEL);
0286 if (!parser)
0287 return ERR_PTR(-ENOMEM);
0288
0289 parser->parse = dp_parser_parse;
0290 parser->pdev = pdev;
0291
0292 return parser;
0293 }