#define  PMC_CNTRL_SYSCLK_OE           BIT(11) /* system clock enable */
 #define  PMC_CNTRL_SYSCLK_POLARITY     BIT(10) /* sys clk polarity */
 #define  PMC_CNTRL_PWRREQ_POLARITY     BIT(8)
+#define  PMC_CNTRL_BLINK_EN            7
 #define  PMC_CNTRL_MAIN_RST            BIT(4)
 
 #define PMC_WAKE_MASK                  0x0c
 #define PMC_WAKE_LEVEL                 0x10
 #define PMC_WAKE_STATUS                        0x14
 #define PMC_SW_WAKE_STATUS             0x18
+#define PMC_DPD_PADS_ORIDE             0x1c
+#define  PMC_DPD_PADS_ORIDE_BLINK      20
 
 #define DPD_SAMPLE                     0x020
 #define  DPD_SAMPLE_ENABLE             BIT(0)
 
 #define PWRGATE_STATUS                 0x38
 
+#define PMC_BLINK_TIMER                        0x40
 #define PMC_IMPL_E_33V_PWR             0x40
 
 #define PMC_PWR_DET                    0x48
 
 #define to_pmc_clk(_hw) container_of(_hw, struct pmc_clk, hw)
 
+struct pmc_clk_gate {
+       struct clk_hw   hw;
+       unsigned long   offs;
+       u32             shift;
+};
+
+#define to_pmc_clk_gate(_hw) container_of(_hw, struct pmc_clk_gate, hw)
+
 struct pmc_clk_init_data {
        char *name;
        const char *const *parents;
 
        const struct pmc_clk_init_data *pmc_clks_data;
        unsigned int num_pmc_clks;
+       bool has_blink_output;
 };
 
 static const char * const tegra186_reset_sources[] = {
        return clk_register(NULL, &pmc_clk->hw);
 }
 
+static int pmc_clk_gate_is_enabled(struct clk_hw *hw)
+{
+       struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
+
+       return tegra_pmc_readl(pmc, gate->offs) & BIT(gate->shift) ? 1 : 0;
+}
+
+static int pmc_clk_gate_enable(struct clk_hw *hw)
+{
+       struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
+
+       pmc_clk_set_state(gate->offs, gate->shift, 1);
+
+       return 0;
+}
+
+static void pmc_clk_gate_disable(struct clk_hw *hw)
+{
+       struct pmc_clk_gate *gate = to_pmc_clk_gate(hw);
+
+       pmc_clk_set_state(gate->offs, gate->shift, 0);
+}
+
+static const struct clk_ops pmc_clk_gate_ops = {
+       .is_enabled = pmc_clk_gate_is_enabled,
+       .enable = pmc_clk_gate_enable,
+       .disable = pmc_clk_gate_disable,
+};
+
+static struct clk *
+tegra_pmc_clk_gate_register(struct tegra_pmc *pmc, const char *name,
+                           const char *parent_name, unsigned long offset,
+                           u32 shift)
+{
+       struct clk_init_data init;
+       struct pmc_clk_gate *gate;
+
+       gate = devm_kzalloc(pmc->dev, sizeof(*gate), GFP_KERNEL);
+       if (!gate)
+               return ERR_PTR(-ENOMEM);
+
+       init.name = name;
+       init.ops = &pmc_clk_gate_ops;
+       init.parent_names = &parent_name;
+       init.num_parents = 1;
+       init.flags = 0;
+
+       gate->hw.init = &init;
+       gate->offs = offset;
+       gate->shift = shift;
+
+       return clk_register(NULL, &gate->hw);
+}
+
 static void tegra_pmc_clock_register(struct tegra_pmc *pmc,
                                     struct device_node *np)
 {
        int i, err;
 
        num_clks = pmc->soc->num_pmc_clks;
+       if (pmc->soc->has_blink_output)
+               num_clks += 1;
 
        if (!num_clks)
                return;
                clk_data->clks[data->clk_id] = clk;
        }
 
+       if (pmc->soc->has_blink_output) {
+               tegra_pmc_writel(pmc, 0x0, PMC_BLINK_TIMER);
+               clk = tegra_pmc_clk_gate_register(pmc,
+                                                 "pmc_blink_override",
+                                                 "clk_32k",
+                                                 PMC_DPD_PADS_ORIDE,
+                                                 PMC_DPD_PADS_ORIDE_BLINK);
+               if (IS_ERR(clk)) {
+                       dev_warn(pmc->dev,
+                                "unable to register pmc_blink_override: %d\n",
+                                PTR_ERR_OR_ZERO(clk));
+                       return;
+               }
+
+               clk = tegra_pmc_clk_gate_register(pmc, "pmc_blink",
+                                                 "pmc_blink_override",
+                                                 PMC_CNTRL,
+                                                 PMC_CNTRL_BLINK_EN);
+               if (IS_ERR(clk)) {
+                       dev_warn(pmc->dev,
+                                "unable to register pmc_blink: %d\n",
+                                PTR_ERR_OR_ZERO(clk));
+                       return;
+               }
+
+               err = clk_register_clkdev(clk, "pmc_blink", NULL);
+               if (err) {
+                       dev_warn(pmc->dev,
+                                "unable to register pmc_blink lookup: %d\n",
+                                err);
+                       return;
+               }
+
+               clk_data->clks[TEGRA_PMC_CLK_BLINK] = clk;
+       }
+
        err = of_clk_add_provider(np, of_clk_src_onecell_get, clk_data);
        if (err)
                dev_warn(pmc->dev, "failed to add pmc clock provider: %d\n",
        .num_reset_levels = 0,
        .pmc_clks_data = NULL,
        .num_pmc_clks = 0,
+       .has_blink_output = true,
 };
 
 static const char * const tegra30_powergates[] = {
        .num_reset_levels = 0,
        .pmc_clks_data = tegra_pmc_clks_data,
        .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+       .has_blink_output = true,
 };
 
 static const char * const tegra114_powergates[] = {
        .num_reset_levels = 0,
        .pmc_clks_data = tegra_pmc_clks_data,
        .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+       .has_blink_output = true,
 };
 
 static const char * const tegra124_powergates[] = {
        .num_reset_levels = 0,
        .pmc_clks_data = tegra_pmc_clks_data,
        .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+       .has_blink_output = true,
 };
 
 static const char * const tegra210_powergates[] = {
        .wake_events = tegra210_wake_events,
        .pmc_clks_data = tegra_pmc_clks_data,
        .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data),
+       .has_blink_output = true,
 };
 
 #define TEGRA186_IO_PAD_TABLE(_pad)                                         \
        .wake_events = tegra186_wake_events,
        .pmc_clks_data = NULL,
        .num_pmc_clks = 0,
+       .has_blink_output = false,
 };
 
 static const struct tegra_io_pad_soc tegra194_io_pads[] = {
        .wake_events = tegra194_wake_events,
        .pmc_clks_data = NULL,
        .num_pmc_clks = 0,
+       .has_blink_output = false,
 };
 
 static const struct of_device_id tegra_pmc_match[] = {