diff options
-rw-r--r-- | drivers/gpu/drm/arm/malidp_drv.c | 52 | ||||
-rw-r--r-- | drivers/gpu/drm/arm/malidp_regs.h | 2 |
2 files changed, 54 insertions, 0 deletions
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c index 080f7631c672..6e59b3effb97 100644 --- a/drivers/gpu/drm/arm/malidp_drv.c +++ b/drivers/gpu/drm/arm/malidp_drv.c | |||
@@ -255,6 +255,46 @@ static const struct of_device_id malidp_drm_of_match[] = { | |||
255 | }; | 255 | }; |
256 | MODULE_DEVICE_TABLE(of, malidp_drm_of_match); | 256 | MODULE_DEVICE_TABLE(of, malidp_drm_of_match); |
257 | 257 | ||
258 | static bool malidp_is_compatible_hw_id(struct malidp_hw_device *hwdev, | ||
259 | const struct of_device_id *dev_id) | ||
260 | { | ||
261 | u32 core_id; | ||
262 | const char *compatstr_dp500 = "arm,mali-dp500"; | ||
263 | bool is_dp500; | ||
264 | bool dt_is_dp500; | ||
265 | |||
266 | /* | ||
267 | * The DP500 CORE_ID register is in a different location, so check it | ||
268 | * first. If the product id field matches, then this is DP500, otherwise | ||
269 | * check the DP550/650 CORE_ID register. | ||
270 | */ | ||
271 | core_id = malidp_hw_read(hwdev, MALIDP500_DC_BASE + MALIDP_DE_CORE_ID); | ||
272 | /* Offset 0x18 will never read 0x500 on products other than DP500. */ | ||
273 | is_dp500 = (MALIDP_PRODUCT_ID(core_id) == 0x500); | ||
274 | dt_is_dp500 = strnstr(dev_id->compatible, compatstr_dp500, | ||
275 | sizeof(dev_id->compatible)) != NULL; | ||
276 | if (is_dp500 != dt_is_dp500) { | ||
277 | DRM_ERROR("Device-tree expects %s, but hardware %s DP500.\n", | ||
278 | dev_id->compatible, is_dp500 ? "is" : "is not"); | ||
279 | return false; | ||
280 | } else if (!dt_is_dp500) { | ||
281 | u16 product_id; | ||
282 | char buf[32]; | ||
283 | |||
284 | core_id = malidp_hw_read(hwdev, | ||
285 | MALIDP550_DC_BASE + MALIDP_DE_CORE_ID); | ||
286 | product_id = MALIDP_PRODUCT_ID(core_id); | ||
287 | snprintf(buf, sizeof(buf), "arm,mali-dp%X", product_id); | ||
288 | if (!strnstr(dev_id->compatible, buf, | ||
289 | sizeof(dev_id->compatible))) { | ||
290 | DRM_ERROR("Device-tree expects %s, but hardware is DP%03X.\n", | ||
291 | dev_id->compatible, product_id); | ||
292 | return false; | ||
293 | } | ||
294 | } | ||
295 | return true; | ||
296 | } | ||
297 | |||
258 | #define MAX_OUTPUT_CHANNELS 3 | 298 | #define MAX_OUTPUT_CHANNELS 3 |
259 | 299 | ||
260 | static int malidp_bind(struct device *dev) | 300 | static int malidp_bind(struct device *dev) |
@@ -265,6 +305,7 @@ static int malidp_bind(struct device *dev) | |||
265 | struct malidp_drm *malidp; | 305 | struct malidp_drm *malidp; |
266 | struct malidp_hw_device *hwdev; | 306 | struct malidp_hw_device *hwdev; |
267 | struct platform_device *pdev = to_platform_device(dev); | 307 | struct platform_device *pdev = to_platform_device(dev); |
308 | struct of_device_id const *dev_id; | ||
268 | /* number of lines for the R, G and B output */ | 309 | /* number of lines for the R, G and B output */ |
269 | u8 output_width[MAX_OUTPUT_CHANNELS]; | 310 | u8 output_width[MAX_OUTPUT_CHANNELS]; |
270 | int ret = 0, i; | 311 | int ret = 0, i; |
@@ -327,6 +368,17 @@ static int malidp_bind(struct device *dev) | |||
327 | clk_prepare_enable(hwdev->aclk); | 368 | clk_prepare_enable(hwdev->aclk); |
328 | clk_prepare_enable(hwdev->mclk); | 369 | clk_prepare_enable(hwdev->mclk); |
329 | 370 | ||
371 | dev_id = of_match_device(malidp_drm_of_match, dev); | ||
372 | if (!dev_id) { | ||
373 | ret = -EINVAL; | ||
374 | goto query_hw_fail; | ||
375 | } | ||
376 | |||
377 | if (!malidp_is_compatible_hw_id(hwdev, dev_id)) { | ||
378 | ret = -EINVAL; | ||
379 | goto query_hw_fail; | ||
380 | } | ||
381 | |||
330 | ret = hwdev->query_hw(hwdev); | 382 | ret = hwdev->query_hw(hwdev); |
331 | if (ret) { | 383 | if (ret) { |
332 | DRM_ERROR("Invalid HW configuration\n"); | 384 | DRM_ERROR("Invalid HW configuration\n"); |
diff --git a/drivers/gpu/drm/arm/malidp_regs.h b/drivers/gpu/drm/arm/malidp_regs.h index 73fecb38f955..7a89997dd134 100644 --- a/drivers/gpu/drm/arm/malidp_regs.h +++ b/drivers/gpu/drm/arm/malidp_regs.h | |||
@@ -92,6 +92,8 @@ | |||
92 | #define MALIDP_DE_H_ACTIVE(x) (((x) & 0x1fff) << 0) | 92 | #define MALIDP_DE_H_ACTIVE(x) (((x) & 0x1fff) << 0) |
93 | #define MALIDP_DE_V_ACTIVE(x) (((x) & 0x1fff) << 16) | 93 | #define MALIDP_DE_V_ACTIVE(x) (((x) & 0x1fff) << 16) |
94 | 94 | ||
95 | #define MALIDP_PRODUCT_ID(__core_id) ((u32)(__core_id) >> 16) | ||
96 | |||
95 | /* register offsets and bits specific to DP500 */ | 97 | /* register offsets and bits specific to DP500 */ |
96 | #define MALIDP500_DC_BASE 0x00000 | 98 | #define MALIDP500_DC_BASE 0x00000 |
97 | #define MALIDP500_DC_CONTROL 0x0000c | 99 | #define MALIDP500_DC_CONTROL 0x0000c |