Lines Matching +full:port +full:- +full:base
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2014-2015 Intel Corporation.
25 * struct gth_output - GTH view on an output port
28 * @index: output port number
29 * @port_type: one of GTH_* port type values
41 * struct gth_device - GTH device
43 * @base: register window base address
47 * @master: master/output port assignments
52 void __iomem *base; member
61 static void gth_output_set(struct gth_device *gth, int port, in gth_output_set() argument
64 unsigned long reg = port & 4 ? REG_GTH_GTHOPT1 : REG_GTH_GTHOPT0; in gth_output_set()
66 int shift = (port & 3) * 8; in gth_output_set()
68 val = ioread32(gth->base + reg); in gth_output_set()
71 iowrite32(val, gth->base + reg); in gth_output_set()
74 static unsigned int gth_output_get(struct gth_device *gth, int port) in gth_output_get() argument
76 unsigned long reg = port & 4 ? REG_GTH_GTHOPT1 : REG_GTH_GTHOPT0; in gth_output_get()
78 int shift = (port & 3) * 8; in gth_output_get()
80 val = ioread32(gth->base + reg); in gth_output_get()
87 static void gth_smcfreq_set(struct gth_device *gth, int port, in gth_smcfreq_set() argument
90 unsigned long reg = REG_GTH_SMCR0 + ((port / 2) * 4); in gth_smcfreq_set()
91 int shift = (port & 1) * 16; in gth_smcfreq_set()
94 val = ioread32(gth->base + reg); in gth_smcfreq_set()
97 iowrite32(val, gth->base + reg); in gth_smcfreq_set()
100 static unsigned int gth_smcfreq_get(struct gth_device *gth, int port) in gth_smcfreq_get() argument
102 unsigned long reg = REG_GTH_SMCR0 + ((port / 2) * 4); in gth_smcfreq_get()
103 int shift = (port & 1) * 16; in gth_smcfreq_get()
106 val = ioread32(gth->base + reg); in gth_smcfreq_get()
124 gth_master_set(struct gth_device *gth, unsigned int master, int port) in gth_master_set() argument
135 val = ioread32(gth->base + reg); in gth_master_set()
137 if (port >= 0) in gth_master_set()
138 val |= (0x8 | port) << shift; in gth_master_set()
139 iowrite32(val, gth->base + reg); in gth_master_set()
148 struct gth_device *gth = ma->gth; in master_attr_show()
150 int port; in master_attr_show() local
152 spin_lock(>h->gth_lock); in master_attr_show()
153 port = gth->master[ma->master]; in master_attr_show()
154 spin_unlock(>h->gth_lock); in master_attr_show()
156 if (port >= 0) in master_attr_show()
157 count = snprintf(buf, PAGE_SIZE, "%x\n", port); in master_attr_show()
170 struct gth_device *gth = ma->gth; in master_attr_store()
171 int old_port, port; in master_attr_store() local
173 if (kstrtoint(buf, 10, &port) < 0) in master_attr_store()
174 return -EINVAL; in master_attr_store()
176 if (port >= TH_POSSIBLE_OUTPUTS || port < -1) in master_attr_store()
177 return -EINVAL; in master_attr_store()
179 spin_lock(>h->gth_lock); in master_attr_store()
181 /* disconnect from the previous output port, if any */ in master_attr_store()
182 old_port = gth->master[ma->master]; in master_attr_store()
184 gth->master[ma->master] = -1; in master_attr_store()
185 clear_bit(ma->master, gth->output[old_port].master); in master_attr_store()
188 * if the port is active, program this setting, in master_attr_store()
191 if (gth->output[old_port].output->active) in master_attr_store()
192 gth_master_set(gth, ma->master, -1); in master_attr_store()
195 /* connect to the new output port, if any */ in master_attr_store()
196 if (port >= 0) { in master_attr_store()
197 /* check if there's a driver for this port */ in master_attr_store()
198 if (!gth->output[port].output) { in master_attr_store()
199 count = -ENODEV; in master_attr_store()
203 set_bit(ma->master, gth->output[port].master); in master_attr_store()
205 /* if the port is active, program this setting, see above */ in master_attr_store()
206 if (gth->output[port].output->active) in master_attr_store()
207 gth_master_set(gth, ma->master, port); in master_attr_store()
210 gth->master[ma->master] = port; in master_attr_store()
213 spin_unlock(>h->gth_lock); in master_attr_store()
221 unsigned int port; member
235 unsigned int (*get)(struct gth_device *gth, int port);
236 void (*set)(struct gth_device *gth, int port,
242 OUTPUT_PARM(port, 0x7, 1, 0, output),
251 gth_output_parm_set(struct gth_device *gth, int port, unsigned int parm, in gth_output_parm_set() argument
254 unsigned int config = output_parms[parm].get(gth, port); in gth_output_parm_set()
260 output_parms[parm].set(gth, port, config); in gth_output_parm_set()
264 gth_output_parm_get(struct gth_device *gth, int port, unsigned int parm) in gth_output_parm_get() argument
266 unsigned int config = output_parms[parm].get(gth, port); in gth_output_parm_get()
281 int port, i; in intel_th_gth_reset() local
283 reg = ioread32(gth->base + REG_GTH_SCRPD0); in intel_th_gth_reset()
285 return -EBUSY; in intel_th_gth_reset()
289 iowrite32(reg, gth->base + REG_GTH_SCRPD0); in intel_th_gth_reset()
292 for (port = 0; port < 8; port++) { in intel_th_gth_reset()
293 if (gth_output_parm_get(gth, port, TH_OUTPUT_PARM(port)) == in intel_th_gth_reset()
297 gth_output_set(gth, port, 0); in intel_th_gth_reset()
298 gth_smcfreq_set(gth, port, 16); in intel_th_gth_reset()
301 iowrite32(0, gth->base + REG_GTH_DESTOVR); in intel_th_gth_reset()
305 iowrite32(0, gth->base + REG_GTH_SWDEST0 + i * 4); in intel_th_gth_reset()
308 iowrite32(0, gth->base + REG_GTH_SCR); in intel_th_gth_reset()
309 iowrite32(0xfc, gth->base + REG_GTH_SCR2); in intel_th_gth_reset()
312 iowrite32(CTS_EVENT_ENABLE_IF_ANYTHING, gth->base + REG_CTS_C0S0_EN); in intel_th_gth_reset()
314 CTS_ACTION_CONTROL_TRIGGER, gth->base + REG_CTS_C0S0_ACT); in intel_th_gth_reset()
329 struct gth_device *gth = oa->gth; in output_attr_show()
334 spin_lock(>h->gth_lock); in output_attr_show()
336 gth_output_parm_get(gth, oa->port, oa->parm)); in output_attr_show()
337 spin_unlock(>h->gth_lock); in output_attr_show()
350 struct gth_device *gth = oa->gth; in output_attr_store()
354 return -EINVAL; in output_attr_store()
358 spin_lock(>h->gth_lock); in output_attr_store()
359 gth_output_parm_set(gth, oa->port, oa->parm, config); in output_attr_store()
360 spin_unlock(>h->gth_lock); in output_attr_store()
373 attrs = devm_kcalloc(gth->dev, nattrs, sizeof(void *), GFP_KERNEL); in intel_th_master_attributes()
375 return -ENOMEM; in intel_th_master_attributes()
377 master_attrs = devm_kcalloc(gth->dev, nattrs, in intel_th_master_attributes()
381 return -ENOMEM; in intel_th_master_attributes()
386 name = devm_kasprintf(gth->dev, GFP_KERNEL, "%d%s", i, in intel_th_master_attributes()
389 return -ENOMEM; in intel_th_master_attributes()
403 gth->master_group.name = "masters"; in intel_th_master_attributes()
404 gth->master_group.attrs = attrs; in intel_th_master_attributes()
406 return sysfs_create_group(>h->dev->kobj, >h->master_group); in intel_th_master_attributes()
417 attrs = devm_kcalloc(gth->dev, nattrs, sizeof(void *), GFP_KERNEL); in intel_th_output_attributes()
419 return -ENOMEM; in intel_th_output_attributes()
421 out_attrs = devm_kcalloc(gth->dev, nattrs, in intel_th_output_attributes()
425 return -ENOMEM; in intel_th_output_attributes()
432 name = devm_kasprintf(gth->dev, GFP_KERNEL, "%d_%s", i, in intel_th_output_attributes()
435 return -ENOMEM; in intel_th_output_attributes()
453 out_attrs[idx].port = i; in intel_th_output_attributes()
458 gth->output_group.name = "outputs"; in intel_th_output_attributes()
459 gth->output_group.attrs = attrs; in intel_th_output_attributes()
461 return sysfs_create_group(>h->dev->kobj, >h->output_group); in intel_th_output_attributes()
465 * intel_th_gth_stop() - stop tracing to an output device
471 * pipelines to be empty for the corresponding output port.
480 to_intel_th_driver(outdev->dev.driver); in intel_th_gth_stop()
485 iowrite32(0, gth->base + REG_GTH_SCR); in intel_th_gth_stop()
486 iowrite32(scr2, gth->base + REG_GTH_SCR2); in intel_th_gth_stop()
488 /* wait on pipeline empty for the given port */ in intel_th_gth_stop()
490 count && !(reg & BIT(output->port)); count--) { in intel_th_gth_stop()
491 reg = ioread32(gth->base + REG_GTH_STAT); in intel_th_gth_stop()
496 dev_dbg(gth->dev, "timeout waiting for GTH[%d] PLE\n", in intel_th_gth_stop()
497 output->port); in intel_th_gth_stop()
500 if (outdrv->wait_empty) in intel_th_gth_stop()
501 outdrv->wait_empty(outdev); in intel_th_gth_stop()
504 iowrite32(0xfc, gth->base + REG_GTH_SCR2); in intel_th_gth_stop()
508 * intel_th_gth_start() - start tracing to an output device
519 if (output->multiblock) in intel_th_gth_start()
522 iowrite32(scr, gth->base + REG_GTH_SCR); in intel_th_gth_start()
523 iowrite32(0, gth->base + REG_GTH_SCR2); in intel_th_gth_start()
527 * intel_th_gth_disable() - disable tracing to an output device
533 * "pipeline empty" bit for corresponding output port.
538 struct gth_device *gth = dev_get_drvdata(&thdev->dev); in intel_th_gth_disable()
542 spin_lock(>h->gth_lock); in intel_th_gth_disable()
543 output->active = false; in intel_th_gth_disable()
545 for_each_set_bit(master, gth->output[output->port].master, in intel_th_gth_disable()
547 gth_master_set(gth, master, -1); in intel_th_gth_disable()
549 spin_unlock(>h->gth_lock); in intel_th_gth_disable()
553 reg = ioread32(gth->base + REG_GTH_SCRPD0); in intel_th_gth_disable()
554 reg &= ~output->scratchpad; in intel_th_gth_disable()
555 iowrite32(reg, gth->base + REG_GTH_SCRPD0); in intel_th_gth_disable()
562 reg = ioread32(gth->base + REG_TSCU_TSUCTRL); in gth_tscu_resync()
564 iowrite32(reg, gth->base + REG_TSCU_TSUCTRL); in gth_tscu_resync()
570 struct gth_device *gth = dev_get_drvdata(&thdev->dev); in intel_th_gth_prepare()
574 * Wait until the output port is in reset before we start in intel_th_gth_prepare()
578 count && !(gth_output_get(gth, output->port) & BIT(5)); count--) in intel_th_gth_prepare()
583 * intel_th_gth_enable() - enable tracing to an output device
593 struct gth_device *gth = dev_get_drvdata(&thdev->dev); in intel_th_gth_enable()
598 spin_lock(>h->gth_lock); in intel_th_gth_enable()
599 for_each_set_bit(master, gth->output[output->port].master, in intel_th_gth_enable()
601 gth_master_set(gth, master, output->port); in intel_th_gth_enable()
604 output->active = true; in intel_th_gth_enable()
605 spin_unlock(>h->gth_lock); in intel_th_gth_enable()
610 scrpd = ioread32(gth->base + REG_GTH_SCRPD0); in intel_th_gth_enable()
611 scrpd |= output->scratchpad; in intel_th_gth_enable()
612 iowrite32(scrpd, gth->base + REG_GTH_SCRPD0); in intel_th_gth_enable()
618 * intel_th_gth_switch() - execute a switch sequence
623 * when tracing to MSC in multi-block mode.
628 struct gth_device *gth = dev_get_drvdata(&thdev->dev); in intel_th_gth_switch()
633 iowrite32(0, gth->base + REG_CTS_CTL); in intel_th_gth_switch()
634 iowrite32(CTS_CTL_SEQUENCER_ENABLE, gth->base + REG_CTS_CTL); in intel_th_gth_switch()
637 count && !(reg & BIT(4)); count--) { in intel_th_gth_switch()
638 reg = ioread32(gth->base + REG_CTS_STAT); in intel_th_gth_switch()
642 dev_dbg(&thdev->dev, "timeout waiting for CTS Trigger\n"); in intel_th_gth_switch()
644 /* De-assert the trigger */ in intel_th_gth_switch()
645 iowrite32(0, gth->base + REG_CTS_CTL); in intel_th_gth_switch()
652 * intel_th_gth_assign() - assign output device to a GTH output port
660 * Return: 0 on success, -errno on error.
665 struct gth_device *gth = dev_get_drvdata(&thdev->dev); in intel_th_gth_assign()
668 if (thdev->host_mode) in intel_th_gth_assign()
669 return -EBUSY; in intel_th_gth_assign()
671 if (othdev->type != INTEL_TH_OUTPUT) in intel_th_gth_assign()
672 return -EINVAL; in intel_th_gth_assign()
675 if (gth->output[i].port_type != othdev->output.type) in intel_th_gth_assign()
678 if (othdev->id == -1 || othdev->id == id) in intel_th_gth_assign()
684 return -ENOENT; in intel_th_gth_assign()
687 spin_lock(>h->gth_lock); in intel_th_gth_assign()
688 othdev->output.port = i; in intel_th_gth_assign()
689 othdev->output.active = false; in intel_th_gth_assign()
690 gth->output[i].output = &othdev->output; in intel_th_gth_assign()
691 spin_unlock(>h->gth_lock); in intel_th_gth_assign()
697 * intel_th_gth_unassign() - deassociate an output device from its output port
704 struct gth_device *gth = dev_get_drvdata(&thdev->dev); in intel_th_gth_unassign()
705 int port = othdev->output.port; in intel_th_gth_unassign() local
708 if (thdev->host_mode) in intel_th_gth_unassign()
711 spin_lock(>h->gth_lock); in intel_th_gth_unassign()
712 othdev->output.port = -1; in intel_th_gth_unassign()
713 othdev->output.active = false; in intel_th_gth_unassign()
714 gth->output[port].output = NULL; in intel_th_gth_unassign()
716 if (gth->master[master] == port) in intel_th_gth_unassign()
717 gth->master[master] = -1; in intel_th_gth_unassign()
718 spin_unlock(>h->gth_lock); in intel_th_gth_unassign()
724 struct gth_device *gth = dev_get_drvdata(&thdev->dev); in intel_th_gth_set_output()
725 int port = 0; /* FIXME: make default output configurable */ in intel_th_gth_set_output() local
734 spin_lock(>h->gth_lock); in intel_th_gth_set_output()
735 if (gth->master[master] == -1) { in intel_th_gth_set_output()
736 set_bit(master, gth->output[port].master); in intel_th_gth_set_output()
737 gth->master[master] = port; in intel_th_gth_set_output()
739 spin_unlock(>h->gth_lock); in intel_th_gth_set_output()
746 struct device *dev = &thdev->dev; in intel_th_gth_probe()
747 struct intel_th *th = dev_get_drvdata(dev->parent); in intel_th_gth_probe()
750 void __iomem *base; in intel_th_gth_probe() local
755 return -ENODEV; in intel_th_gth_probe()
757 base = devm_ioremap(dev, res->start, resource_size(res)); in intel_th_gth_probe()
758 if (!base) in intel_th_gth_probe()
759 return -ENOMEM; in intel_th_gth_probe()
763 return -ENOMEM; in intel_th_gth_probe()
765 gth->dev = dev; in intel_th_gth_probe()
766 gth->base = base; in intel_th_gth_probe()
767 spin_lock_init(>h->gth_lock); in intel_th_gth_probe()
777 if (thdev->host_mode) in intel_th_gth_probe()
782 if (ret != -EBUSY) in intel_th_gth_probe()
785 thdev->host_mode = true; in intel_th_gth_probe()
791 gth->master[i] = -1; in intel_th_gth_probe()
794 gth->output[i].gth = gth; in intel_th_gth_probe()
795 gth->output[i].index = i; in intel_th_gth_probe()
796 gth->output[i].port_type = in intel_th_gth_probe()
797 gth_output_parm_get(gth, i, TH_OUTPUT_PARM(port)); in intel_th_gth_probe()
798 if (gth->output[i].port_type == GTH_NONE) in intel_th_gth_probe()
801 ret = intel_th_output_enable(th, gth->output[i].port_type); in intel_th_gth_probe()
802 /* -ENODEV is ok, we just won't have that device enumerated */ in intel_th_gth_probe()
803 if (ret && ret != -ENODEV) in intel_th_gth_probe()
811 if (gth->output_group.attrs) in intel_th_gth_probe()
812 sysfs_remove_group(>h->dev->kobj, >h->output_group); in intel_th_gth_probe()
813 return -ENOMEM; in intel_th_gth_probe()
821 struct gth_device *gth = dev_get_drvdata(&thdev->dev); in intel_th_gth_remove()
823 sysfs_remove_group(>h->dev->kobj, >h->output_group); in intel_th_gth_remove()
824 sysfs_remove_group(>h->dev->kobj, >h->master_group); in intel_th_gth_remove()