unsigned                nres;
        unsigned                type;
        unsigned                otype;
+       unsigned                scrpd;
        int                     id;
 } intel_th_subdevices[TH_SUBDEVICE_MAX] = {
        {
                .id     = 0,
                .type   = INTEL_TH_OUTPUT,
                .otype  = GTH_MSU,
+               .scrpd  = SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC0_IS_ENABLED,
        },
        {
                .nres   = 2,
                .id     = 1,
                .type   = INTEL_TH_OUTPUT,
                .otype  = GTH_MSU,
+               .scrpd  = SCRPD_MEM_IS_PRIM_DEST | SCRPD_MSC1_IS_ENABLED,
        },
        {
                .nres   = 2,
                .name   = "pti",
                .type   = INTEL_TH_OUTPUT,
                .otype  = GTH_PTI,
+               .scrpd  = SCRPD_PTI_IS_PRIM_DEST,
        },
        {
                .nres   = 1,
                        thdev->dev.devt = MKDEV(th->major, i);
                        thdev->output.type = subdev->otype;
                        thdev->output.port = -1;
+                       thdev->output.scratchpad = subdev->scrpd;
                }
 
                err = device_add(&thdev->dev);
 
        if (scratchpad & SCRPD_DEBUGGER_IN_USE)
                return -EBUSY;
 
+       /* Always save/restore STH and TU registers in S0ix entry/exit */
+       scratchpad |= SCRPD_STH_IS_ENABLED | SCRPD_TRIGGER_IS_ENABLED;
+       iowrite32(scratchpad, gth->base + REG_GTH_SCRPD0);
+
        /* output ports */
        for (port = 0; port < 8; port++) {
                if (gth_output_parm_get(gth, port, TH_OUTPUT_PARM(port)) ==
        if (!count)
                dev_dbg(&thdev->dev, "timeout waiting for GTH[%d] PLE\n",
                        output->port);
+
+       reg = ioread32(gth->base + REG_GTH_SCRPD0);
+       reg &= ~output->scratchpad;
+       iowrite32(reg, gth->base + REG_GTH_SCRPD0);
 }
 
 /**
                                struct intel_th_output *output)
 {
        struct gth_device *gth = dev_get_drvdata(&thdev->dev);
-       u32 scr = 0xfc0000;
+       u32 scr = 0xfc0000, scrpd;
        int master;
 
        spin_lock(>h->gth_lock);
        output->active = true;
        spin_unlock(>h->gth_lock);
 
+       scrpd = ioread32(gth->base + REG_GTH_SCRPD0);
+       scrpd |= output->scratchpad;
+       iowrite32(scrpd, gth->base + REG_GTH_SCRPD0);
+
        iowrite32(scr, gth->base + REG_GTH_SCR);
        iowrite32(0, gth->base + REG_GTH_SCR2);
 }
 
  * struct intel_th_output - descriptor INTEL_TH_OUTPUT type devices
  * @port:      output port number, assigned by the switch
  * @type:      GTH_{MSU,CTP,PTI}
+ * @scratchpad:        scratchpad bits to flag when this output is enabled
  * @multiblock:        true for multiblock output configuration
  * @active:    true when this output is enabled
  *
 struct intel_th_output {
        int             port;
        unsigned int    type;
+       unsigned int    scratchpad;
        bool            multiblock;
        bool            active;
 };
        GTH_PTI = 4,    /* MIPI-PTI */
 };
 
+/*
+ * Scratchpad bits: tell firmware and external debuggers
+ * what we are up to.
+ */
+enum {
+       /* Memory is the primary destination */
+       SCRPD_MEM_IS_PRIM_DEST          = BIT(0),
+       /* XHCI DbC is the primary destination */
+       SCRPD_DBC_IS_PRIM_DEST          = BIT(1),
+       /* PTI is the primary destination */
+       SCRPD_PTI_IS_PRIM_DEST          = BIT(2),
+       /* BSSB is the primary destination */
+       SCRPD_BSSB_IS_PRIM_DEST         = BIT(3),
+       /* PTI is the alternate destination */
+       SCRPD_PTI_IS_ALT_DEST           = BIT(4),
+       /* BSSB is the alternate destination */
+       SCRPD_BSSB_IS_ALT_DEST          = BIT(5),
+       /* DeepSx exit occurred */
+       SCRPD_DEEPSX_EXIT               = BIT(6),
+       /* S4 exit occurred */
+       SCRPD_S4_EXIT                   = BIT(7),
+       /* S5 exit occurred */
+       SCRPD_S5_EXIT                   = BIT(8),
+       /* MSU controller 0/1 is enabled */
+       SCRPD_MSC0_IS_ENABLED           = BIT(9),
+       SCRPD_MSC1_IS_ENABLED           = BIT(10),
+       /* Sx exit occurred */
+       SCRPD_SX_EXIT                   = BIT(11),
+       /* Trigger Unit is enabled */
+       SCRPD_TRIGGER_IS_ENABLED        = BIT(12),
+       SCRPD_ODLA_IS_ENABLED           = BIT(13),
+       SCRPD_SOCHAP_IS_ENABLED         = BIT(14),
+       SCRPD_STH_IS_ENABLED            = BIT(15),
+       SCRPD_DCIH_IS_ENABLED           = BIT(16),
+       SCRPD_VER_IS_ENABLED            = BIT(17),
+       /* External debugger is using Intel TH */
+       SCRPD_DEBUGGER_IN_USE           = BIT(24),
+};
+
 #endif