aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwtracing/intel_th/gth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwtracing/intel_th/gth.c')
-rw-r--r--drivers/hwtracing/intel_th/gth.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/drivers/hwtracing/intel_th/gth.c b/drivers/hwtracing/intel_th/gth.c
index dd32d0bad687..018678ec3c13 100644
--- a/drivers/hwtracing/intel_th/gth.c
+++ b/drivers/hwtracing/intel_th/gth.c
@@ -285,16 +285,16 @@ gth_output_parm_get(struct gth_device *gth, int port, unsigned int parm)
*/
static int intel_th_gth_reset(struct gth_device *gth)
{
- u32 scratchpad;
+ u32 reg;
int port, i;
- scratchpad = ioread32(gth->base + REG_GTH_SCRPD0);
- if (scratchpad & SCRPD_DEBUGGER_IN_USE)
+ reg = ioread32(gth->base + REG_GTH_SCRPD0);
+ if (reg & 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);
+ reg |= SCRPD_STH_IS_ENABLED | SCRPD_TRIGGER_IS_ENABLED;
+ iowrite32(reg, gth->base + REG_GTH_SCRPD0);
/* output ports */
for (port = 0; port < 8; port++) {
@@ -512,6 +512,15 @@ static void intel_th_gth_disable(struct intel_th_device *thdev,
iowrite32(reg, gth->base + REG_GTH_SCRPD0);
}
+static void gth_tscu_resync(struct gth_device *gth)
+{
+ u32 reg;
+
+ reg = ioread32(gth->base + REG_TSCU_TSUCTRL);
+ reg &= ~TSUCTRL_CTCRESYNC;
+ iowrite32(reg, gth->base + REG_TSCU_TSUCTRL);
+}
+
/**
* intel_th_gth_enable() - enable tracing to an output device
* @thdev: GTH device
@@ -524,6 +533,7 @@ static void intel_th_gth_enable(struct intel_th_device *thdev,
struct intel_th_output *output)
{
struct gth_device *gth = dev_get_drvdata(&thdev->dev);
+ struct intel_th *th = to_intel_th(thdev);
u32 scr = 0xfc0000, scrpd;
int master;
@@ -539,6 +549,9 @@ static void intel_th_gth_enable(struct intel_th_device *thdev,
output->active = true;
spin_unlock(&gth->gth_lock);
+ if (INTEL_TH_CAP(th, tscu_enable))
+ gth_tscu_resync(gth);
+
scrpd = ioread32(gth->base + REG_GTH_SCRPD0);
scrpd |= output->scratchpad;
iowrite32(scrpd, gth->base + REG_GTH_SCRPD0);
@@ -639,6 +652,7 @@ intel_th_gth_set_output(struct intel_th_device *thdev, unsigned int master)
static int intel_th_gth_probe(struct intel_th_device *thdev)
{
struct device *dev = &thdev->dev;
+ struct intel_th *th = dev_get_drvdata(dev->parent);
struct gth_device *gth;
struct resource *res;
void __iomem *base;
@@ -660,6 +674,8 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
gth->base = base;
spin_lock_init(&gth->gth_lock);
+ dev_set_drvdata(dev, gth);
+
/*
* Host mode can be signalled via SW means or via SCRPD_DEBUGGER_IN_USE
* bit. Either way, don't reset HW in this case, and don't export any
@@ -667,7 +683,7 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
* drivers to ports, see intel_th_gth_assign().
*/
if (thdev->host_mode)
- goto done;
+ return 0;
ret = intel_th_gth_reset(gth);
if (ret) {
@@ -676,7 +692,7 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
thdev->host_mode = true;
- goto done;
+ return 0;
}
for (i = 0; i < TH_CONFIGURABLE_MASTERS + 1; i++)
@@ -687,6 +703,13 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
gth->output[i].index = i;
gth->output[i].port_type =
gth_output_parm_get(gth, i, TH_OUTPUT_PARM(port));
+ if (gth->output[i].port_type == GTH_NONE)
+ continue;
+
+ ret = intel_th_output_enable(th, gth->output[i].port_type);
+ /* -ENODEV is ok, we just won't have that device enumerated */
+ if (ret && ret != -ENODEV)
+ return ret;
}
if (intel_th_output_attributes(gth) ||
@@ -698,9 +721,6 @@ static int intel_th_gth_probe(struct intel_th_device *thdev)
return -ENOMEM;
}
-done:
- dev_set_drvdata(dev, gth);
-
return 0;
}