renesas-soc.c (2a4056a759e26745f3a19431f5428c581fd8f347) | renesas-soc.c (175f435f44b724e389f23c154d94fda45870c1f6) |
---|---|
1/* 2 * Renesas SoC Identification 3 * 4 * Copyright (C) 2014-2016 Glider bvba 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. --- 32 unchanged lines hidden (view full) --- 41 .reg = 0xfff00044, /* PRR (Product Register) */ 42}; 43 44static const struct renesas_family fam_rmobile __initconst __maybe_unused = { 45 .name = "R-Mobile", 46 .reg = 0xe600101c, /* CCCR (Common Chip Code Register) */ 47}; 48 | 1/* 2 * Renesas SoC Identification 3 * 4 * Copyright (C) 2014-2016 Glider bvba 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. --- 32 unchanged lines hidden (view full) --- 41 .reg = 0xfff00044, /* PRR (Product Register) */ 42}; 43 44static const struct renesas_family fam_rmobile __initconst __maybe_unused = { 45 .name = "R-Mobile", 46 .reg = 0xe600101c, /* CCCR (Common Chip Code Register) */ 47}; 48 |
49static const struct renesas_family fam_rza __initconst __maybe_unused = { 50 .name = "RZ/A", | 49static const struct renesas_family fam_rza1 __initconst __maybe_unused = { 50 .name = "RZ/A1", |
51}; 52 | 51}; 52 |
53static const struct renesas_family fam_rza2 __initconst __maybe_unused = { 54 .name = "RZ/A2", 55}; 56 |
|
53static const struct renesas_family fam_rzg1 __initconst __maybe_unused = { 54 .name = "RZ/G1", 55 .reg = 0xff000044, /* PRR (Product Register) */ 56}; 57 58static const struct renesas_family fam_rzg2 __initconst __maybe_unused = { 59 .name = "RZ/G2", 60 .reg = 0xfff00044, /* PRR (Product Register) */ --- 6 unchanged lines hidden (view full) --- 67 68 69struct renesas_soc { 70 const struct renesas_family *family; 71 u8 id; 72}; 73 74static const struct renesas_soc soc_rz_a1h __initconst __maybe_unused = { | 57static const struct renesas_family fam_rzg1 __initconst __maybe_unused = { 58 .name = "RZ/G1", 59 .reg = 0xff000044, /* PRR (Product Register) */ 60}; 61 62static const struct renesas_family fam_rzg2 __initconst __maybe_unused = { 63 .name = "RZ/G2", 64 .reg = 0xfff00044, /* PRR (Product Register) */ --- 6 unchanged lines hidden (view full) --- 71 72 73struct renesas_soc { 74 const struct renesas_family *family; 75 u8 id; 76}; 77 78static const struct renesas_soc soc_rz_a1h __initconst __maybe_unused = { |
75 .family = &fam_rza, | 79 .family = &fam_rza1, |
76}; 77 | 80}; 81 |
82static const struct renesas_soc soc_rz_a2m __initconst __maybe_unused = { 83 .family = &fam_rza2, 84 .id = 0x3b, 85}; 86 |
|
78static const struct renesas_soc soc_rmobile_ape6 __initconst __maybe_unused = { 79 .family = &fam_rmobile, 80 .id = 0x3f, 81}; 82 83static const struct renesas_soc soc_rmobile_a1 __initconst __maybe_unused = { 84 .family = &fam_rmobile, 85 .id = 0x40, --- 103 unchanged lines hidden (view full) --- 189 .id = 0x37, 190}; 191 192 193static const struct of_device_id renesas_socs[] __initconst = { 194#ifdef CONFIG_ARCH_R7S72100 195 { .compatible = "renesas,r7s72100", .data = &soc_rz_a1h }, 196#endif | 87static const struct renesas_soc soc_rmobile_ape6 __initconst __maybe_unused = { 88 .family = &fam_rmobile, 89 .id = 0x3f, 90}; 91 92static const struct renesas_soc soc_rmobile_a1 __initconst __maybe_unused = { 93 .family = &fam_rmobile, 94 .id = 0x40, --- 103 unchanged lines hidden (view full) --- 198 .id = 0x37, 199}; 200 201 202static const struct of_device_id renesas_socs[] __initconst = { 203#ifdef CONFIG_ARCH_R7S72100 204 { .compatible = "renesas,r7s72100", .data = &soc_rz_a1h }, 205#endif |
206#ifdef CONFIG_ARCH_R7S9210 207 { .compatible = "renesas,r7s9210", .data = &soc_rz_a2m }, 208#endif |
|
197#ifdef CONFIG_ARCH_R8A73A4 198 { .compatible = "renesas,r8a73a4", .data = &soc_rmobile_ape6 }, 199#endif 200#ifdef CONFIG_ARCH_R8A7740 201 { .compatible = "renesas,r8a7740", .data = &soc_rmobile_a1 }, 202#endif 203#ifdef CONFIG_ARCH_R8A7742 204 { .compatible = "renesas,r8a7742", .data = &soc_rz_g1h }, --- 65 unchanged lines hidden (view full) --- 270{ 271 struct soc_device_attribute *soc_dev_attr; 272 const struct renesas_family *family; 273 const struct of_device_id *match; 274 const struct renesas_soc *soc; 275 void __iomem *chipid = NULL; 276 struct soc_device *soc_dev; 277 struct device_node *np; | 209#ifdef CONFIG_ARCH_R8A73A4 210 { .compatible = "renesas,r8a73a4", .data = &soc_rmobile_ape6 }, 211#endif 212#ifdef CONFIG_ARCH_R8A7740 213 { .compatible = "renesas,r8a7740", .data = &soc_rmobile_a1 }, 214#endif 215#ifdef CONFIG_ARCH_R8A7742 216 { .compatible = "renesas,r8a7742", .data = &soc_rz_g1h }, --- 65 unchanged lines hidden (view full) --- 282{ 283 struct soc_device_attribute *soc_dev_attr; 284 const struct renesas_family *family; 285 const struct of_device_id *match; 286 const struct renesas_soc *soc; 287 void __iomem *chipid = NULL; 288 struct soc_device *soc_dev; 289 struct device_node *np; |
278 unsigned int product; | 290 unsigned int product, eshi = 0, eslo; |
279 280 match = of_match_node(renesas_socs, of_root); 281 if (!match) 282 return -ENODEV; 283 284 soc = match->data; 285 family = soc->family; 286 | 291 292 match = of_match_node(renesas_socs, of_root); 293 if (!match) 294 return -ENODEV; 295 296 soc = match->data; 297 family = soc->family; 298 |
299 np = of_find_compatible_node(NULL, NULL, "renesas,bsid"); 300 if (np) { 301 chipid = of_iomap(np, 0); 302 of_node_put(np); 303 304 if (chipid) { 305 product = readl(chipid); 306 iounmap(chipid); 307 308 if (soc->id && ((product >> 16) & 0xff) != soc->id) { 309 pr_warn("SoC mismatch (product = 0x%x)\n", 310 product); 311 return -ENODEV; 312 } 313 } 314 315 /* 316 * TODO: Upper 4 bits of BSID are for chip version, but the 317 * format is not known at this time so we don't know how to 318 * specify eshi and eslo 319 */ 320 321 goto done; 322 } 323 |
|
287 /* Try PRR first, then hardcoded fallback */ 288 np = of_find_compatible_node(NULL, NULL, "renesas,prr"); 289 if (np) { 290 chipid = of_iomap(np, 0); 291 of_node_put(np); 292 } else if (soc->id) { 293 chipid = ioremap(family->reg, 4); 294 } 295 if (chipid) { 296 product = readl(chipid); 297 iounmap(chipid); 298 /* R-Car M3-W ES1.1 incorrectly identifies as ES2.0 */ 299 if ((product & 0x7fff) == 0x5210) 300 product ^= 0x11; 301 if (soc->id && ((product >> 8) & 0xff) != soc->id) { 302 pr_warn("SoC mismatch (product = 0x%x)\n", product); 303 return -ENODEV; 304 } | 324 /* Try PRR first, then hardcoded fallback */ 325 np = of_find_compatible_node(NULL, NULL, "renesas,prr"); 326 if (np) { 327 chipid = of_iomap(np, 0); 328 of_node_put(np); 329 } else if (soc->id) { 330 chipid = ioremap(family->reg, 4); 331 } 332 if (chipid) { 333 product = readl(chipid); 334 iounmap(chipid); 335 /* R-Car M3-W ES1.1 incorrectly identifies as ES2.0 */ 336 if ((product & 0x7fff) == 0x5210) 337 product ^= 0x11; 338 if (soc->id && ((product >> 8) & 0xff) != soc->id) { 339 pr_warn("SoC mismatch (product = 0x%x)\n", product); 340 return -ENODEV; 341 } |
342 eshi = ((product >> 4) & 0x0f) + 1; 343 eslo = product & 0xf; |
|
305 } 306 | 344 } 345 |
346done: |
|
307 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); 308 if (!soc_dev_attr) 309 return -ENOMEM; 310 311 np = of_find_node_by_path("/"); 312 of_property_read_string(np, "model", &soc_dev_attr->machine); 313 of_node_put(np); 314 315 soc_dev_attr->family = kstrdup_const(family->name, GFP_KERNEL); 316 soc_dev_attr->soc_id = kstrdup_const(strchr(match->compatible, ',') + 1, 317 GFP_KERNEL); | 347 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL); 348 if (!soc_dev_attr) 349 return -ENOMEM; 350 351 np = of_find_node_by_path("/"); 352 of_property_read_string(np, "model", &soc_dev_attr->machine); 353 of_node_put(np); 354 355 soc_dev_attr->family = kstrdup_const(family->name, GFP_KERNEL); 356 soc_dev_attr->soc_id = kstrdup_const(strchr(match->compatible, ',') + 1, 357 GFP_KERNEL); |
318 if (chipid) 319 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u", 320 ((product >> 4) & 0x0f) + 1, 321 product & 0xf); | 358 if (eshi) 359 soc_dev_attr->revision = kasprintf(GFP_KERNEL, "ES%u.%u", eshi, 360 eslo); |
322 323 pr_info("Detected Renesas %s %s %s\n", soc_dev_attr->family, 324 soc_dev_attr->soc_id, soc_dev_attr->revision ?: ""); 325 326 soc_dev = soc_device_register(soc_dev_attr); 327 if (IS_ERR(soc_dev)) { 328 kfree(soc_dev_attr->revision); 329 kfree_const(soc_dev_attr->soc_id); 330 kfree_const(soc_dev_attr->family); 331 kfree(soc_dev_attr); 332 return PTR_ERR(soc_dev); 333 } 334 335 return 0; 336} 337early_initcall(renesas_soc_init); | 361 362 pr_info("Detected Renesas %s %s %s\n", soc_dev_attr->family, 363 soc_dev_attr->soc_id, soc_dev_attr->revision ?: ""); 364 365 soc_dev = soc_device_register(soc_dev_attr); 366 if (IS_ERR(soc_dev)) { 367 kfree(soc_dev_attr->revision); 368 kfree_const(soc_dev_attr->soc_id); 369 kfree_const(soc_dev_attr->family); 370 kfree(soc_dev_attr); 371 return PTR_ERR(soc_dev); 372 } 373 374 return 0; 375} 376early_initcall(renesas_soc_init); |