mirror of
https://github.com/torvalds/linux.git
synced 2024-12-24 11:51:27 +00:00
drm: mali-dp: Check hw version matches device-tree
Refuse to bind if the device-tree compatible string lists a different hardware version. Reviewed-by: Brian Starkey <brian.starkey@arm.com> Signed-off-by: Mihail Atanassov <mihail.atanassov@arm.com> Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
This commit is contained in:
parent
6211b4868e
commit
592d8c8cce
@ -255,6 +255,46 @@ static const struct of_device_id malidp_drm_of_match[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, malidp_drm_of_match);
|
||||
|
||||
static bool malidp_is_compatible_hw_id(struct malidp_hw_device *hwdev,
|
||||
const struct of_device_id *dev_id)
|
||||
{
|
||||
u32 core_id;
|
||||
const char *compatstr_dp500 = "arm,mali-dp500";
|
||||
bool is_dp500;
|
||||
bool dt_is_dp500;
|
||||
|
||||
/*
|
||||
* The DP500 CORE_ID register is in a different location, so check it
|
||||
* first. If the product id field matches, then this is DP500, otherwise
|
||||
* check the DP550/650 CORE_ID register.
|
||||
*/
|
||||
core_id = malidp_hw_read(hwdev, MALIDP500_DC_BASE + MALIDP_DE_CORE_ID);
|
||||
/* Offset 0x18 will never read 0x500 on products other than DP500. */
|
||||
is_dp500 = (MALIDP_PRODUCT_ID(core_id) == 0x500);
|
||||
dt_is_dp500 = strnstr(dev_id->compatible, compatstr_dp500,
|
||||
sizeof(dev_id->compatible)) != NULL;
|
||||
if (is_dp500 != dt_is_dp500) {
|
||||
DRM_ERROR("Device-tree expects %s, but hardware %s DP500.\n",
|
||||
dev_id->compatible, is_dp500 ? "is" : "is not");
|
||||
return false;
|
||||
} else if (!dt_is_dp500) {
|
||||
u16 product_id;
|
||||
char buf[32];
|
||||
|
||||
core_id = malidp_hw_read(hwdev,
|
||||
MALIDP550_DC_BASE + MALIDP_DE_CORE_ID);
|
||||
product_id = MALIDP_PRODUCT_ID(core_id);
|
||||
snprintf(buf, sizeof(buf), "arm,mali-dp%X", product_id);
|
||||
if (!strnstr(dev_id->compatible, buf,
|
||||
sizeof(dev_id->compatible))) {
|
||||
DRM_ERROR("Device-tree expects %s, but hardware is DP%03X.\n",
|
||||
dev_id->compatible, product_id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define MAX_OUTPUT_CHANNELS 3
|
||||
|
||||
static int malidp_bind(struct device *dev)
|
||||
@ -265,6 +305,7 @@ static int malidp_bind(struct device *dev)
|
||||
struct malidp_drm *malidp;
|
||||
struct malidp_hw_device *hwdev;
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct of_device_id const *dev_id;
|
||||
/* number of lines for the R, G and B output */
|
||||
u8 output_width[MAX_OUTPUT_CHANNELS];
|
||||
int ret = 0, i;
|
||||
@ -327,6 +368,17 @@ static int malidp_bind(struct device *dev)
|
||||
clk_prepare_enable(hwdev->aclk);
|
||||
clk_prepare_enable(hwdev->mclk);
|
||||
|
||||
dev_id = of_match_device(malidp_drm_of_match, dev);
|
||||
if (!dev_id) {
|
||||
ret = -EINVAL;
|
||||
goto query_hw_fail;
|
||||
}
|
||||
|
||||
if (!malidp_is_compatible_hw_id(hwdev, dev_id)) {
|
||||
ret = -EINVAL;
|
||||
goto query_hw_fail;
|
||||
}
|
||||
|
||||
ret = hwdev->query_hw(hwdev);
|
||||
if (ret) {
|
||||
DRM_ERROR("Invalid HW configuration\n");
|
||||
|
@ -92,6 +92,8 @@
|
||||
#define MALIDP_DE_H_ACTIVE(x) (((x) & 0x1fff) << 0)
|
||||
#define MALIDP_DE_V_ACTIVE(x) (((x) & 0x1fff) << 16)
|
||||
|
||||
#define MALIDP_PRODUCT_ID(__core_id) ((u32)(__core_id) >> 16)
|
||||
|
||||
/* register offsets and bits specific to DP500 */
|
||||
#define MALIDP500_DC_BASE 0x00000
|
||||
#define MALIDP500_DC_CONTROL 0x0000c
|
||||
|
Loading…
Reference in New Issue
Block a user