On Mon, May 24, 2021 at 1:28 PM Sven Peter <sven@xxxxxxxxxxxxx> wrote: > > > Hi, > > This series adds support for the clock gates present in Apple's SoCs such as > the M1. > > These SoCs have various clock gates for their peripherals usually located in > one or two MMIO regions. Each clock gate is a single 32 bit register which > contains bits for the requested and the actual mode. The mode is represented by > four bits. We however only care about "everything enabled" (0b1111) and > "everything disabled" (0b000) for now. The other modes are probably different > low-power states which don't even seem to be used by MacOS. The actual power > management is located in a different region (and probably handled by a separate > processor on the M1). > > Additionally, these clocks have a topology that is usually specified in Apple's > Device Tree. As far as I can tell most Linux drivers seem to encode this topology > directly in the source code though. Despite this, we would still like to encode > the topology in the device tree itself: We only define leaf clocks primarily. There's some exceptions such as if PLLs are a separate h/w block. The reason for this is because typical SoCs have 100s of just leaf clocks. If we tried to model everything, it would never be complete nor correct. Actually, we did try that at first. > Apple seems to only change HW blocks when they have a very good reason and even > then they seem to keep the changes minimal. This specific clock gate MMIO block > has already been used in the Apple A7 released in 2013. The only differences > since then are the available clocks (which can be identified by a simple offset) > and their topology. Clock gates are easy. What about muxes, dividers, etc.? > It's likely that Apple will still use this block in future SoCs as well. By > encoding the clock gate topology inside the device tree as well we can use a > single driver and only need updates to the device tree once they are released. > This might allow end users to already run their favorite distribution by just > updating the bootloader with a new device tree instead of having to wait until > the new topology is integrated into their distro kernel. > > Additionally, the driver itself can be kept very simple and not much code needs > to be duplicated and then updated for each new SoC between various consumers of > these device tree nodes (Linux, u-boot, and OpenBSD for now). > > > This series therefore creates a single device tree node for each clock gate. > This unfortunately maps a whole page out of which only a single register will > be used for each node. > > The other alternative I considered was to create a syscon/simple-mfd node > and have the clock nodes as children. The gates would then use a regmap which > would only require a single entry in the pagetable for all clocks. I decided > against this option since the clock gate MMIO region actually isn't a > multi-function device. I would do a single node per mmio region with the register offset (or offset / 4) being the clock id. This can still support new SoCs easily if you have a fallback compatible. If you want/need to get all the clocks, just walk the DT 'clocks' properties and extract all the IDs. Rob