Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

soc/tegra: pmc: Fix dual edge triggered wakes

When a wake event is defined to be triggered on both positive and
negative edge of the input wake signal, it is crucial to know the
current state of the signal when going into suspend. The intended way to
obtain the current state of the wake signals is to read the
WAKE_AOWAKE_SW_STATUS register, which should contains the raw state of
the wake signals.

However, this register is edge triggered, an edge will not be generated
for signals that are already asserted prior to the assertion of
WAKE_LATCH_SW.

To workaround this, change the polarity of the wake level from '0' to
'1' while latching the signals, as this will generate an edge for
signals that are set to '1'.

Signed-off-by: Stefan Kristiansson <stefank@nvidia.com>
Signed-off-by: Petlozu Pravareshwar <petlozup@nvidia.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>

authored by

Petlozu Pravareshwar and committed by
Thierry Reding
1ddb8f6d c9c4ddb2

+176 -5
+176 -5
drivers/soc/tegra/pmc.c
··· 46 46 #include <linux/seq_file.h> 47 47 #include <linux/slab.h> 48 48 #include <linux/spinlock.h> 49 + #include <linux/syscore_ops.h> 49 50 50 51 #include <soc/tegra/common.h> 51 52 #include <soc/tegra/fuse.h> ··· 183 182 #define WAKE_AOWAKE_TIER0_ROUTING(x) (0x4b4 + ((x) << 2)) 184 183 #define WAKE_AOWAKE_TIER1_ROUTING(x) (0x4c0 + ((x) << 2)) 185 184 #define WAKE_AOWAKE_TIER2_ROUTING(x) (0x4cc + ((x) << 2)) 185 + #define WAKE_AOWAKE_SW_STATUS_W_0 0x49c 186 + #define WAKE_AOWAKE_SW_STATUS(x) (0x4a0 + ((x) << 2)) 187 + #define WAKE_LATCH_SW 0x498 186 188 187 189 #define WAKE_AOWAKE_CTRL 0x4f4 188 190 #define WAKE_AOWAKE_CTRL_INTR_POLARITY BIT(0) ··· 371 367 */ 372 368 const struct tegra_wake_event *wake_events; 373 369 unsigned int num_wake_events; 370 + unsigned int max_wake_events; 371 + unsigned int max_wake_vectors; 374 372 375 373 const struct pmc_clk_init_data *pmc_clks_data; 376 374 unsigned int num_pmc_clks; ··· 413 407 * @clk_nb: pclk clock changes handler 414 408 * @core_domain_state_synced: flag marking the core domain's state as synced 415 409 * @core_domain_registered: flag marking the core domain as registered 410 + * @wake_type_level_map: Bitmap indicating level type for non-dual edge wakes 411 + * @wake_type_dual_edge_map: Bitmap indicating if a wake is dual-edge or not 412 + * @wake_sw_status_map: Bitmap to hold raw status of wakes without mask 413 + * @wake_cntrl_level_map: Bitmap to hold wake levels to be programmed in 414 + * cntrl register associated with each wake during system suspend. 416 415 */ 417 416 struct tegra_pmc { 418 417 struct device *dev; ··· 458 447 459 448 bool core_domain_state_synced; 460 449 bool core_domain_registered; 450 + 451 + unsigned long *wake_type_level_map; 452 + unsigned long *wake_type_dual_edge_map; 453 + unsigned long *wake_sw_status_map; 454 + unsigned long *wake_cntrl_level_map; 455 + struct syscore_ops syscore; 461 456 }; 462 457 463 458 static struct tegra_pmc *pmc = &(struct tegra_pmc) { ··· 1940 1923 return 0; 1941 1924 } 1942 1925 1943 - static void tegra_pmc_init(struct tegra_pmc *pmc) 1926 + static int tegra_pmc_init(struct tegra_pmc *pmc) 1944 1927 { 1928 + if (pmc->soc->max_wake_events > 0) { 1929 + pmc->wake_type_level_map = bitmap_zalloc(pmc->soc->max_wake_events, GFP_KERNEL); 1930 + if (!pmc->wake_type_level_map) 1931 + return -ENOMEM; 1932 + 1933 + pmc->wake_type_dual_edge_map = bitmap_zalloc(pmc->soc->max_wake_events, GFP_KERNEL); 1934 + if (!pmc->wake_type_dual_edge_map) 1935 + return -ENOMEM; 1936 + 1937 + pmc->wake_sw_status_map = bitmap_zalloc(pmc->soc->max_wake_events, GFP_KERNEL); 1938 + if (!pmc->wake_sw_status_map) 1939 + return -ENOMEM; 1940 + 1941 + pmc->wake_cntrl_level_map = bitmap_zalloc(pmc->soc->max_wake_events, GFP_KERNEL); 1942 + if (!pmc->wake_cntrl_level_map) 1943 + return -ENOMEM; 1944 + } 1945 + 1945 1946 if (pmc->soc->init) 1946 1947 pmc->soc->init(pmc); 1948 + 1949 + return 0; 1947 1950 } 1948 1951 1949 1952 static void tegra_pmc_init_tsense_reset(struct tegra_pmc *pmc) ··· 2454 2417 case IRQ_TYPE_EDGE_RISING: 2455 2418 case IRQ_TYPE_LEVEL_HIGH: 2456 2419 value |= WAKE_AOWAKE_CNTRL_LEVEL; 2420 + set_bit(data->hwirq, pmc->wake_type_level_map); 2421 + clear_bit(data->hwirq, pmc->wake_type_dual_edge_map); 2457 2422 break; 2458 2423 2459 2424 case IRQ_TYPE_EDGE_FALLING: 2460 2425 case IRQ_TYPE_LEVEL_LOW: 2461 2426 value &= ~WAKE_AOWAKE_CNTRL_LEVEL; 2427 + clear_bit(data->hwirq, pmc->wake_type_level_map); 2428 + clear_bit(data->hwirq, pmc->wake_type_dual_edge_map); 2462 2429 break; 2463 2430 2464 2431 case IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING: 2465 2432 value ^= WAKE_AOWAKE_CNTRL_LEVEL; 2433 + clear_bit(data->hwirq, pmc->wake_type_level_map); 2434 + set_bit(data->hwirq, pmc->wake_type_dual_edge_map); 2466 2435 break; 2467 2436 2468 2437 default: ··· 3000 2957 3001 2958 pmc->dev = &pdev->dev; 3002 2959 3003 - tegra_pmc_init(pmc); 2960 + err = tegra_pmc_init(pmc); 2961 + if (err < 0) { 2962 + dev_err(&pdev->dev, "failed to initialize PMC: %d\n", err); 2963 + return err; 2964 + } 3004 2965 3005 2966 tegra_pmc_init_tsense_reset(pmc); 3006 2967 ··· 3053 3006 clk_notifier_unregister(pmc->clk, &pmc->clk_nb); 3054 3007 3055 3008 return err; 3009 + } 3010 + 3011 + /* 3012 + * Ensures that sufficient time is passed for a register write to 3013 + * serialize into the 32KHz domain. 3014 + */ 3015 + static void wke_32kwritel(struct tegra_pmc *pmc, u32 value, unsigned int offset) 3016 + { 3017 + writel(value, pmc->wake + offset); 3018 + udelay(130); 3019 + } 3020 + 3021 + static void wke_write_wake_level(struct tegra_pmc *pmc, int wake, int level) 3022 + { 3023 + unsigned int offset = WAKE_AOWAKE_CNTRL(wake); 3024 + u32 value; 3025 + 3026 + value = readl(pmc->wake + offset); 3027 + if (level) 3028 + value |= WAKE_AOWAKE_CNTRL_LEVEL; 3029 + else 3030 + value &= ~WAKE_AOWAKE_CNTRL_LEVEL; 3031 + 3032 + writel(value, pmc->wake + offset); 3033 + } 3034 + 3035 + static void wke_write_wake_levels(struct tegra_pmc *pmc) 3036 + { 3037 + unsigned int i; 3038 + 3039 + for (i = 0; i < pmc->soc->max_wake_events; i++) 3040 + wke_write_wake_level(pmc, i, test_bit(i, pmc->wake_cntrl_level_map)); 3041 + } 3042 + 3043 + static void wke_clear_sw_wake_status(struct tegra_pmc *pmc) 3044 + { 3045 + wke_32kwritel(pmc, 1, WAKE_AOWAKE_SW_STATUS_W_0); 3046 + } 3047 + 3048 + static void wke_read_sw_wake_status(struct tegra_pmc *pmc) 3049 + { 3050 + unsigned long status; 3051 + unsigned int wake, i; 3052 + 3053 + for (i = 0; i < pmc->soc->max_wake_events; i++) 3054 + wke_write_wake_level(pmc, i, 0); 3055 + 3056 + wke_clear_sw_wake_status(pmc); 3057 + 3058 + wke_32kwritel(pmc, 1, WAKE_LATCH_SW); 3059 + 3060 + /* 3061 + * WAKE_AOWAKE_SW_STATUS is edge triggered, so in order to 3062 + * obtain the current status of the input wake signals, change 3063 + * the polarity of the wake level from 0->1 while latching to force 3064 + * a positive edge if the sampled signal is '1'. 3065 + */ 3066 + for (i = 0; i < pmc->soc->max_wake_events; i++) 3067 + wke_write_wake_level(pmc, i, 1); 3068 + 3069 + /* 3070 + * Wait for the update to be synced into the 32kHz domain, 3071 + * and let enough time lapse, so that the wake signals have time to 3072 + * be sampled. 3073 + */ 3074 + udelay(300); 3075 + 3076 + wke_32kwritel(pmc, 0, WAKE_LATCH_SW); 3077 + 3078 + bitmap_zero(pmc->wake_sw_status_map, pmc->soc->max_wake_events); 3079 + 3080 + for (i = 0; i < pmc->soc->max_wake_vectors; i++) { 3081 + status = readl(pmc->wake + WAKE_AOWAKE_SW_STATUS(i)); 3082 + 3083 + for_each_set_bit(wake, &status, 32) 3084 + set_bit(wake + (i * 32), pmc->wake_sw_status_map); 3085 + } 3086 + } 3087 + 3088 + static void wke_clear_wake_status(struct tegra_pmc *pmc) 3089 + { 3090 + unsigned long status; 3091 + unsigned int i, wake; 3092 + u32 mask; 3093 + 3094 + for (i = 0; i < pmc->soc->max_wake_vectors; i++) { 3095 + mask = readl(pmc->wake + WAKE_AOWAKE_TIER2_ROUTING(i)); 3096 + status = readl(pmc->wake + WAKE_AOWAKE_STATUS_R(i)) & mask; 3097 + 3098 + for_each_set_bit(wake, &status, 32) 3099 + wke_32kwritel(pmc, 0x1, WAKE_AOWAKE_STATUS_W((i * 32) + wake)); 3100 + } 3101 + } 3102 + 3103 + static int tegra186_pmc_wake_syscore_suspend(void) 3104 + { 3105 + wke_read_sw_wake_status(pmc); 3106 + 3107 + /* flip the wakeup trigger for dual-edge triggered pads 3108 + * which are currently asserting as wakeups 3109 + */ 3110 + bitmap_andnot(pmc->wake_cntrl_level_map, pmc->wake_type_dual_edge_map, 3111 + pmc->wake_sw_status_map, pmc->soc->max_wake_events); 3112 + bitmap_or(pmc->wake_cntrl_level_map, pmc->wake_cntrl_level_map, 3113 + pmc->wake_type_level_map, pmc->soc->max_wake_events); 3114 + 3115 + /* Clear PMC Wake Status registers while going to suspend */ 3116 + wke_clear_wake_status(pmc); 3117 + wke_write_wake_levels(pmc); 3118 + 3119 + return 0; 3056 3120 } 3057 3121 3058 3122 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) ··· 3809 3651 .rst_level_mask = 0x3, 3810 3652 }; 3811 3653 3654 + static void tegra186_pmc_init(struct tegra_pmc *pmc) 3655 + { 3656 + pmc->syscore.suspend = tegra186_pmc_wake_syscore_suspend; 3657 + 3658 + register_syscore_ops(&pmc->syscore); 3659 + } 3660 + 3812 3661 static void tegra186_pmc_setup_irq_polarity(struct tegra_pmc *pmc, 3813 3662 struct device_node *np, 3814 3663 bool invert) ··· 3895 3730 .num_pin_descs = ARRAY_SIZE(tegra186_pin_descs), 3896 3731 .pin_descs = tegra186_pin_descs, 3897 3732 .regs = &tegra186_pmc_regs, 3898 - .init = NULL, 3733 + .init = tegra186_pmc_init, 3899 3734 .setup_irq_polarity = tegra186_pmc_setup_irq_polarity, 3900 3735 .irq_set_wake = tegra186_pmc_irq_set_wake, 3901 3736 .irq_set_type = tegra186_pmc_irq_set_type, ··· 3905 3740 .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels), 3906 3741 .num_wake_events = ARRAY_SIZE(tegra186_wake_events), 3907 3742 .wake_events = tegra186_wake_events, 3743 + .max_wake_events = 96, 3744 + .max_wake_vectors = 3, 3908 3745 .pmc_clks_data = NULL, 3909 3746 .num_pmc_clks = 0, 3910 3747 .has_blink_output = false, ··· 4079 3912 .num_pin_descs = ARRAY_SIZE(tegra194_pin_descs), 4080 3913 .pin_descs = tegra194_pin_descs, 4081 3914 .regs = &tegra194_pmc_regs, 4082 - .init = NULL, 3915 + .init = tegra186_pmc_init, 4083 3916 .setup_irq_polarity = tegra186_pmc_setup_irq_polarity, 4084 3917 .irq_set_wake = tegra186_pmc_irq_set_wake, 4085 3918 .irq_set_type = tegra186_pmc_irq_set_type, ··· 4089 3922 .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels), 4090 3923 .num_wake_events = ARRAY_SIZE(tegra194_wake_events), 4091 3924 .wake_events = tegra194_wake_events, 3925 + .max_wake_events = 96, 3926 + .max_wake_vectors = 3, 4092 3927 .pmc_clks_data = NULL, 4093 3928 .num_pmc_clks = 0, 4094 3929 .has_blink_output = false, ··· 4204 4035 .num_pin_descs = ARRAY_SIZE(tegra234_pin_descs), 4205 4036 .pin_descs = tegra234_pin_descs, 4206 4037 .regs = &tegra234_pmc_regs, 4207 - .init = NULL, 4038 + .init = tegra186_pmc_init, 4208 4039 .setup_irq_polarity = tegra186_pmc_setup_irq_polarity, 4209 4040 .irq_set_wake = tegra186_pmc_irq_set_wake, 4210 4041 .irq_set_type = tegra186_pmc_irq_set_type, ··· 4214 4045 .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels), 4215 4046 .num_wake_events = ARRAY_SIZE(tegra234_wake_events), 4216 4047 .wake_events = tegra234_wake_events, 4048 + .max_wake_events = 96, 4049 + .max_wake_vectors = 3, 4217 4050 .pmc_clks_data = NULL, 4218 4051 .num_pmc_clks = 0, 4219 4052 .has_blink_output = false,