aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2017-12-15 12:41:23 -0500
committerTony Lindgren <tony@atomide.com>2017-12-21 10:28:54 -0500
commitc5a2de97fbd2979fab291fb048084d3fddd322dd (patch)
tree45dfca45e1e9c683c961cb20936d464a2380f673
parent566a9b05e1fa47dcfb93a4459145d0fdc06d3046 (diff)
bus: ti-sysc: Add parsing of module capabilities
We need to configure the interconnect target module based on the device three configuration. Let's also add a new quirk for SYSC_QUIRK_RESET_STATUS to indicate that the SYSCONFIG reset bit changes after the reset is done. Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r--drivers/bus/ti-sysc.c100
-rw-r--r--include/linux/platform_data/ti-sysc.h10
2 files changed, 110 insertions, 0 deletions
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
index 090612460cef..2c62985a345f 100644
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -39,6 +39,9 @@ enum sysc_clocks {
39 39
40static const char * const clock_names[] = { "fck", "ick", }; 40static const char * const clock_names[] = { "fck", "ick", };
41 41
42#define SYSC_IDLEMODE_MASK 3
43#define SYSC_CLOCKACTIVITY_MASK 3
44
42/** 45/**
43 * struct sysc - TI sysc interconnect target module registers and capabilities 46 * struct sysc - TI sysc interconnect target module registers and capabilities
44 * @dev: struct device pointer 47 * @dev: struct device pointer
@@ -517,6 +520,91 @@ static int sysc_init_module(struct sysc *ddata)
517 return 0; 520 return 0;
518} 521}
519 522
523static int sysc_init_sysc_mask(struct sysc *ddata)
524{
525 struct device_node *np = ddata->dev->of_node;
526 int error;
527 u32 val;
528
529 error = of_property_read_u32(np, "ti,sysc-mask", &val);
530 if (error)
531 return 0;
532
533 if (val)
534 ddata->cfg.sysc_val = val & ddata->cap->sysc_mask;
535 else
536 ddata->cfg.sysc_val = ddata->cap->sysc_mask;
537
538 return 0;
539}
540
541static int sysc_init_idlemode(struct sysc *ddata, u8 *idlemodes,
542 const char *name)
543{
544 struct device_node *np = ddata->dev->of_node;
545 struct property *prop;
546 const __be32 *p;
547 u32 val;
548
549 of_property_for_each_u32(np, name, prop, p, val) {
550 if (val >= SYSC_NR_IDLEMODES) {
551 dev_err(ddata->dev, "invalid idlemode: %i\n", val);
552 return -EINVAL;
553 }
554 *idlemodes |= (1 << val);
555 }
556
557 return 0;
558}
559
560static int sysc_init_idlemodes(struct sysc *ddata)
561{
562 int error;
563
564 error = sysc_init_idlemode(ddata, &ddata->cfg.midlemodes,
565 "ti,sysc-midle");
566 if (error)
567 return error;
568
569 error = sysc_init_idlemode(ddata, &ddata->cfg.sidlemodes,
570 "ti,sysc-sidle");
571 if (error)
572 return error;
573
574 return 0;
575}
576
577/*
578 * Only some devices on omap4 and later have SYSCONFIG reset done
579 * bit. We can detect this if there is no SYSSTATUS at all, or the
580 * SYSTATUS bit 0 is not used. Note that some SYSSTATUS registers
581 * have multiple bits for the child devices like OHCI and EHCI.
582 * Depends on SYSC being parsed first.
583 */
584static int sysc_init_syss_mask(struct sysc *ddata)
585{
586 struct device_node *np = ddata->dev->of_node;
587 int error;
588 u32 val;
589
590 error = of_property_read_u32(np, "ti,syss-mask", &val);
591 if (error) {
592 if ((ddata->cap->type == TI_SYSC_OMAP4 ||
593 ddata->cap->type == TI_SYSC_OMAP4_TIMER) &&
594 (ddata->cfg.sysc_val & SYSC_OMAP4_SOFTRESET))
595 ddata->cfg.quirks |= SYSC_QUIRK_RESET_STATUS;
596
597 return 0;
598 }
599
600 if (!(val & 1) && (ddata->cfg.sysc_val & SYSC_OMAP4_SOFTRESET))
601 ddata->cfg.quirks |= SYSC_QUIRK_RESET_STATUS;
602
603 ddata->cfg.syss_mask = val;
604
605 return 0;
606}
607
520/* Device tree configured quirks */ 608/* Device tree configured quirks */
521struct sysc_dts_quirk { 609struct sysc_dts_quirk {
522 const char *name; 610 const char *name;
@@ -820,6 +908,18 @@ static int sysc_probe(struct platform_device *pdev)
820 if (error) 908 if (error)
821 goto unprepare; 909 goto unprepare;
822 910
911 error = sysc_init_sysc_mask(ddata);
912 if (error)
913 goto unprepare;
914
915 error = sysc_init_idlemodes(ddata);
916 if (error)
917 goto unprepare;
918
919 error = sysc_init_syss_mask(ddata);
920 if (error)
921 goto unprepare;
922
823 pm_runtime_enable(ddata->dev); 923 pm_runtime_enable(ddata->dev);
824 924
825 error = sysc_init_module(ddata); 925 error = sysc_init_module(ddata);
diff --git a/include/linux/platform_data/ti-sysc.h b/include/linux/platform_data/ti-sysc.h
index 28e5a61d4abc..1be356330b96 100644
--- a/include/linux/platform_data/ti-sysc.h
+++ b/include/linux/platform_data/ti-sysc.h
@@ -41,6 +41,7 @@ struct sysc_regbits {
41 s8 emufree_shift; 41 s8 emufree_shift;
42}; 42};
43 43
44#define SYSC_QUIRK_RESET_STATUS BIT(7)
44#define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6) 45#define SYSC_QUIRK_NO_IDLE_ON_INIT BIT(6)
45#define SYSC_QUIRK_NO_RESET_ON_INIT BIT(5) 46#define SYSC_QUIRK_NO_RESET_ON_INIT BIT(5)
46#define SYSC_QUIRK_OPT_CLKS_NEEDED BIT(4) 47#define SYSC_QUIRK_OPT_CLKS_NEEDED BIT(4)
@@ -49,6 +50,8 @@ struct sysc_regbits {
49#define SYSC_QUIRK_UNCACHED BIT(1) 50#define SYSC_QUIRK_UNCACHED BIT(1)
50#define SYSC_QUIRK_USE_CLOCKACT BIT(0) 51#define SYSC_QUIRK_USE_CLOCKACT BIT(0)
51 52
53#define SYSC_NR_IDLEMODES 4
54
52/** 55/**
53 * struct sysc_capabilities - capabilities for an interconnect target module 56 * struct sysc_capabilities - capabilities for an interconnect target module
54 * 57 *
@@ -65,10 +68,17 @@ struct sysc_capabilities {
65 68
66/** 69/**
67 * struct sysc_config - configuration for an interconnect target module 70 * struct sysc_config - configuration for an interconnect target module
71 * @sysc_val: configured value for sysc register
72 * @midlemodes: bitmask of supported master idle modes
73 * @sidlemodes: bitmask of supported master idle modes
68 * @srst_udelay: optional delay needed after OCP soft reset 74 * @srst_udelay: optional delay needed after OCP soft reset
69 * @quirks: bitmask of enabled quirks 75 * @quirks: bitmask of enabled quirks
70 */ 76 */
71struct sysc_config { 77struct sysc_config {
78 u32 sysc_val;
79 u32 syss_mask;
80 u8 midlemodes;
81 u8 sidlemodes;
72 u8 srst_udelay; 82 u8 srst_udelay;
73 u32 quirks; 83 u32 quirks;
74}; 84};