On Tue, Oct 11, 2016 at 08:18:12PM +0200, Daniel Lezcano wrote: > > Hi Rich, > > On Sun, Oct 09, 2016 at 05:34:22AM +0000, Rich Felker wrote: > > At the hardware level, the J-Core PIT is integrated with the interrupt > > controller, but it is represented as its own device and has an > > independent programming interface. It provides a 12-bit countdown > > timer, which is not presently used, and a periodic timer. The interval > > length for the latter is programmable via a 32-bit throttle register > > whose units are determined by a bus-period register. The periodic > > timer is used to implement both periodic and oneshot clock event > > modes; in oneshot mode the interrupt handler simply disables the timer > > as soon as it fires. > > > > Despite its device tree node representing an interrupt for the PIT, > > the actual irq generated is programmable, not hard-wired. The driver > > is responsible for programming the PIT to generate the hardware irq > > number that the DT assigns to it. > > > > On SMP configurations, J-Core provides cpu-local instances of the PIT; > > no broadcast timer is needed. This driver supports the creation of the > > necessary per-cpu clock_event_device instances. > > For my personnal information, why no broadcast timer is needed ?
Broadcast timer is only needed if you don't have percpu local timers. Early on in SMP development I actually tested with an ipi broadcast timer and performance was noticably worse. > Are the CPUs on always-on power down ? For now they are always on and don't even have the sleep instruction (i.e. stop cpu clock until interrupt) implemented. Adding sleep will be the first power-saving step, and perhaps the only one for now, since there doesn't seem to be any indication (according to the ppl working on the hardware) that a deeper sleep would provide significant additional savings. > > A nanosecond-resolution clocksource is provided using the J-Core "RTC" > > registers, which give a 64-bit seconds count and 32-bit nanoseconds > > that wrap every second. The driver converts these to a full-range > > 32-bit nanoseconds count. > > > > Signed-off-by: Rich Felker <dal...@libc.org> > > --- > > drivers/clocksource/Kconfig | 10 ++ > > drivers/clocksource/Makefile | 1 + > > drivers/clocksource/jcore-pit.c | 231 > > ++++++++++++++++++++++++++++++++++++++++ > > include/linux/cpuhotplug.h | 1 + > > 4 files changed, 243 insertions(+) > > create mode 100644 drivers/clocksource/jcore-pit.c > > > > diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig > > index 5677886..95dd78b 100644 > > --- a/drivers/clocksource/Kconfig > > +++ b/drivers/clocksource/Kconfig > > @@ -407,6 +407,16 @@ config SYS_SUPPORTS_SH_TMU > > config SYS_SUPPORTS_EM_STI > > bool > > > > +config CLKSRC_JCORE_PIT > > + bool "J-Core PIT timer driver" > > + depends on OF && (SUPERH || COMPILE_TEST) > > Actually the idea is to have the SUPERH to select this timer, not create > a dependency on SUPERH from here. > > We don't want to prompt in the configuration menu the drivers because it > would be impossible to anyone to know which timer comes with which > hardware, so we let the platform to select the timer it needs. I thought we discussed this before. For users building a kernel for legacy SH systems, especially in the current state where they're only supported with hard-coded board files rather than device tree, it makes no sense to build drivers for J-core hardware. It would make sense to be on by default for CONFIG_SH_DEVICE_TREE with a compatible CPU selection, but at least at this time, not for SUPERH in general. Anyway I'd really like to do this non-invasively as long as we have a mix of legacy and new stuff and the legacy stuff is not readily testable. Once all of arch/sh is moved over to device tree, could we revisit this and make all the drivers follow a common policy (on by default if they're associated with boards/SoCs using a matching or compatible CPU model, or something like that, but still able to be disabled manually, since the user might be trying to get a tiny-ish embedded kernel)? > The exception is to enable in order to compile on non-native platform to > compile-test a bunch of drivers (eg. compile most of the clocksource / > clockevents drivers on a x86 big server). > > That's why we should have: > > config CLKSRC_JCORE_PIT > bool "J-Core PIT timer driver" if COMPILE_TEST > > So the jcore pit driver option appears only if compile test is enabled > otherwise it is a silent option and the user doesn't have to deal with > it. Having consistent dependency like the other drivers will help future > changes to consolidate the Kconfig. I don't think this matches the user expectation for the arch yet. For now we have a j2_defconfig that enables the drivers and other kernel settings expected to be useful for J-core socs. I want to modernize this all but that's a separate project. > [ ... ] > > > +#define REG_PITEN 0x00 > > +#define REG_THROT 0x10 > > +#define REG_COUNT 0x14 > > +#define REG_BUSPD 0x18 > > +#define REG_SECHI 0x20 > > +#define REG_SECLO 0x24 > > +#define REG_NSEC 0x28 > > + > > +struct jcore_pit { > > + struct clock_event_device ced; > > + __iomem void *base; > > It is not '__iomem void *' but 'void __iomem *'. This appears multiple > times in this code. OK, I'll change that. > > + unsigned long periodic_delta; > > + unsigned cpu; > > This field is pointless, 'cpu' is only used for a trace in the init > function which has already the cpu has parameter. OK, will remove. It was needed for the old notify framework but not for cpu hotplug framework, I think. > > + u32 enable_val; > > +}; > > + > > +static __iomem void *jcore_pit_base; > > static void __iomem *jcore_pit_base; OK. > > +struct jcore_pit __percpu *jcore_pit_percpu; > > static. OK. > [ ... ] > > > +static int __init jcore_pit_init(struct device_node *node) > > +{ > > [ ... ] Was there something analogous you wanted me to change here, or just leftover quoting? > > + /* > > + * The J-Core PIT is not hard-wired to a particular IRQ, but > > + * integrated with the interrupt controller such that the IRQ it > > + * generates is programmable. The programming interface has a > > + * legacy field which was an interrupt priority for AIC1, but > > + * which is OR'd onto bits 2-5 of the generated IRQ number when > > + * used with J-Core AIC2, so set it to match these bits. > > + */ > > + hwirq = irq_get_irq_data(pit_irq)->hwirq; > > + irqprio = (hwirq >> 2) & PIT_PRIO_MASK; > > + enable_val = (1U << PIT_ENABLE_SHIFT) > > + | (hwirq << PIT_IRQ_SHIFT) > > + | (irqprio << PIT_PRIO_SHIFT); > > + > > Why mention AIC1 if there is not test to check if AIC1 || AIC2 ? > > Will be the same information available if the irqchip is AIC1 ? The bit layout of the PIT enable register is: .....e..ppppiiiiiiii............ where the .'s indicate unrelated/unused bits, e is enable, p is priority, and i is hard irq number. For the PIT included in AIC1 (obsolete but still in use), any hard irq (trap number) can be programmed via the 8 iiiiiiii bits, and a priority (0-15) is programmable separately in the pppp bits. For the PIT included in AIC2 (current), the programming interface is equivalent modulo interrupt mapping. This is why a different compatible tag was not used. However only traps 64-127 (the ones actually intended to be used for interrupts, rather than syscalls/exceptions/etc.) can be programmed (the high 2 bits of i are ignored) and the priority pppp is <<2'd and or'd onto the irq number. This was a poor decision made on the hardware engineering side based on a wrong assumption that preserving old priority mapping of outdated software was important, whereas priorities weren't/aren't even being used. When we do the next round of interrupt controller improvements (AIC3) the PIT programming interface should remain compatible with the driver; likely the priority bits will just be ignored. If we do want to change the programming interface beyond this at some point (that maay be a good idea, since we have identified several things that are less than ideal for Linux, like the sechi/seclo/ns clocksource), a new compatible tag will be added instead. > I have to admin I find strange this driver has to invoke irq_get_irq_data(), > it is the only one and it sounds even strange it has to be stored per cpu > below. The timer will not actually generate the irq it's assigned to (or any interrupt at all) unless/until it's programmed for the (hard) irq number. The need to use irq_get_irq_data comes from the fact that the hardware needs the hard irq number, not a virq number, which could in principle be different. There's probably some argument that could have been made that the irqchip and clocksource/timer driver should have been unified since they're unified in the hardware and have this awkward programming relationship, but that didn't fit the Linux model very well and I think having them factored like this encourages future versions of the hardware to adapt to the model the software wants. Rich