aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mxs/mach-mxs.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-mxs/mach-mxs.c')
-rw-r--r--arch/arm/mach-mxs/mach-mxs.c130
1 files changed, 119 insertions, 11 deletions
diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index 5b62b6489d4b..7fa611c1b287 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -19,13 +19,13 @@
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/gpio.h> 20#include <linux/gpio.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/irqchip.h>
23#include <linux/irqchip/mxs.h> 22#include <linux/irqchip/mxs.h>
24#include <linux/micrel_phy.h> 23#include <linux/micrel_phy.h>
25#include <linux/of_address.h> 24#include <linux/of_address.h>
26#include <linux/of_platform.h> 25#include <linux/of_platform.h>
27#include <linux/phy.h> 26#include <linux/phy.h>
28#include <linux/pinctrl/consumer.h> 27#include <linux/pinctrl/consumer.h>
28#include <linux/sys_soc.h>
29#include <asm/mach/arch.h> 29#include <asm/mach/arch.h>
30#include <asm/mach/map.h> 30#include <asm/mach/map.h>
31#include <asm/mach/time.h> 31#include <asm/mach/time.h>
@@ -39,12 +39,28 @@
39#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2 39#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0 0x2
40#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3 40#define MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR1 0x3
41 41
42#define HW_DIGCTL_CHIPID 0x310
43#define HW_DIGCTL_CHIPID_MASK (0xffff << 16)
44#define HW_DIGCTL_REV_MASK 0xff
45#define HW_DIGCTL_CHIPID_MX23 (0x3780 << 16)
46#define HW_DIGCTL_CHIPID_MX28 (0x2800 << 16)
47
48#define MXS_CHIP_REVISION_1_0 0x10
49#define MXS_CHIP_REVISION_1_1 0x11
50#define MXS_CHIP_REVISION_1_2 0x12
51#define MXS_CHIP_REVISION_1_3 0x13
52#define MXS_CHIP_REVISION_1_4 0x14
53#define MXS_CHIP_REV_UNKNOWN 0xff
54
42#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr)) 55#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
43 56
44#define MXS_SET_ADDR 0x4 57#define MXS_SET_ADDR 0x4
45#define MXS_CLR_ADDR 0x8 58#define MXS_CLR_ADDR 0x8
46#define MXS_TOG_ADDR 0xc 59#define MXS_TOG_ADDR 0xc
47 60
61static u32 chipid;
62static u32 socid;
63
48static inline void __mxs_setl(u32 mask, void __iomem *reg) 64static inline void __mxs_setl(u32 mask, void __iomem *reg)
49{ 65{
50 __raw_writel(mask, reg + MXS_SET_ADDR); 66 __raw_writel(mask, reg + MXS_SET_ADDR);
@@ -352,29 +368,123 @@ static void __init tx28_post_init(void)
352 pinctrl_put(pctl); 368 pinctrl_put(pctl);
353} 369}
354 370
355static void __init cfa10049_init(void) 371static void __init crystalfontz_init(void)
356{ 372{
357 update_fec_mac_prop(OUI_CRYSTALFONTZ); 373 update_fec_mac_prop(OUI_CRYSTALFONTZ);
358} 374}
359 375
360static void __init cfa10037_init(void) 376static const char __init *mxs_get_soc_id(void)
361{ 377{
362 update_fec_mac_prop(OUI_CRYSTALFONTZ); 378 struct device_node *np;
379 void __iomem *digctl_base;
380
381 np = of_find_compatible_node(NULL, NULL, "fsl,imx23-digctl");
382 digctl_base = of_iomap(np, 0);
383 WARN_ON(!digctl_base);
384
385 chipid = readl(digctl_base + HW_DIGCTL_CHIPID);
386 socid = chipid & HW_DIGCTL_CHIPID_MASK;
387
388 iounmap(digctl_base);
389 of_node_put(np);
390
391 switch (socid) {
392 case HW_DIGCTL_CHIPID_MX23:
393 return "i.MX23";
394 case HW_DIGCTL_CHIPID_MX28:
395 return "i.MX28";
396 default:
397 return "Unknown";
398 }
399}
400
401static u32 __init mxs_get_cpu_rev(void)
402{
403 u32 rev = chipid & HW_DIGCTL_REV_MASK;
404
405 switch (socid) {
406 case HW_DIGCTL_CHIPID_MX23:
407 switch (rev) {
408 case 0x0:
409 return MXS_CHIP_REVISION_1_0;
410 case 0x1:
411 return MXS_CHIP_REVISION_1_1;
412 case 0x2:
413 return MXS_CHIP_REVISION_1_2;
414 case 0x3:
415 return MXS_CHIP_REVISION_1_3;
416 case 0x4:
417 return MXS_CHIP_REVISION_1_4;
418 default:
419 return MXS_CHIP_REV_UNKNOWN;
420 }
421 case HW_DIGCTL_CHIPID_MX28:
422 switch (rev) {
423 case 0x0:
424 return MXS_CHIP_REVISION_1_1;
425 case 0x1:
426 return MXS_CHIP_REVISION_1_2;
427 default:
428 return MXS_CHIP_REV_UNKNOWN;
429 }
430 default:
431 return MXS_CHIP_REV_UNKNOWN;
432 }
433}
434
435static const char __init *mxs_get_revision(void)
436{
437 u32 rev = mxs_get_cpu_rev();
438
439 if (rev != MXS_CHIP_REV_UNKNOWN)
440 return kasprintf(GFP_KERNEL, "TO%d.%d", (rev >> 4) & 0xf,
441 rev & 0xf);
442 else
443 return kasprintf(GFP_KERNEL, "%s", "Unknown");
363} 444}
364 445
365static void __init mxs_machine_init(void) 446static void __init mxs_machine_init(void)
366{ 447{
448 struct device_node *root;
449 struct device *parent;
450 struct soc_device *soc_dev;
451 struct soc_device_attribute *soc_dev_attr;
452 int ret;
453
454 soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
455 if (!soc_dev_attr)
456 return;
457
458 root = of_find_node_by_path("/");
459 ret = of_property_read_string(root, "model", &soc_dev_attr->machine);
460 if (ret)
461 return;
462
463 soc_dev_attr->family = "Freescale MXS Family";
464 soc_dev_attr->soc_id = mxs_get_soc_id();
465 soc_dev_attr->revision = mxs_get_revision();
466
467 soc_dev = soc_device_register(soc_dev_attr);
468 if (IS_ERR(soc_dev)) {
469 kfree(soc_dev_attr->revision);
470 kfree(soc_dev_attr);
471 return;
472 }
473
474 parent = soc_device_to_device(soc_dev);
475
367 if (of_machine_is_compatible("fsl,imx28-evk")) 476 if (of_machine_is_compatible("fsl,imx28-evk"))
368 imx28_evk_init(); 477 imx28_evk_init();
369 else if (of_machine_is_compatible("bluegiga,apx4devkit")) 478 else if (of_machine_is_compatible("bluegiga,apx4devkit"))
370 apx4devkit_init(); 479 apx4devkit_init();
371 else if (of_machine_is_compatible("crystalfontz,cfa10037")) 480 else if (of_machine_is_compatible("crystalfontz,cfa10037") ||
372 cfa10037_init(); 481 of_machine_is_compatible("crystalfontz,cfa10049") ||
373 else if (of_machine_is_compatible("crystalfontz,cfa10049")) 482 of_machine_is_compatible("crystalfontz,cfa10055") ||
374 cfa10049_init(); 483 of_machine_is_compatible("crystalfontz,cfa10057"))
484 crystalfontz_init();
375 485
376 of_platform_populate(NULL, of_default_bus_match_table, 486 of_platform_populate(NULL, of_default_bus_match_table,
377 mxs_auxdata_lookup, NULL); 487 mxs_auxdata_lookup, parent);
378 488
379 if (of_machine_is_compatible("karo,tx28")) 489 if (of_machine_is_compatible("karo,tx28"))
380 tx28_post_init(); 490 tx28_post_init();
@@ -434,8 +544,6 @@ static const char *mxs_dt_compat[] __initdata = {
434}; 544};
435 545
436DT_MACHINE_START(MXS, "Freescale MXS (Device Tree)") 546DT_MACHINE_START(MXS, "Freescale MXS (Device Tree)")
437 .map_io = debug_ll_io_init,
438 .init_irq = irqchip_init,
439 .handle_irq = icoll_handle_irq, 547 .handle_irq = icoll_handle_irq,
440 .init_time = mxs_timer_init, 548 .init_time = mxs_timer_init,
441 .init_machine = mxs_machine_init, 549 .init_machine = mxs_machine_init,