Hi Michael, On Wed, Jul 3, 2024 at 6:15 AM Michael Trimarchi <mich...@amarulasolutions.com> wrote: > > Upstream Linux commit f90b68d6c8b0. ....
> The CORE/BUS root slice has following design, simplied graph: > The difference is core not have pre_div block. > A composite core/bus clk has 8 inputs for mux to select, saying clk[0-7]. > > It support target(smart) interface and normal interface. Target interface > is exported for programmer easy to configure ccm root. Normal interface > is also exported, but we not use it in our driver, because it will > introduce more complexity compared with target interface. > > The normal interface simplified as below: > SEL_A GA > +--+ +-+ > | +->+ +------+ > CLK[0-7]--->+ | +-+ | > | | | +----v---+ +----+ > | +--+ |pre_diva+----> | +---------+ > | +--------+ |mux +--+post_div | > | +--+ |pre_divb+--->+ | +---------+ > | | | +----^---+ +----+ > +--->+ | +-+ | > | +->+ +------+ > +--+ +-+ > SEL_B GB > > The mux in the upper pic is not the target interface MUX, target > interface MUX is hiding SEL_A and SEL_B. When you choose clk[0-7], > you are actually writing SEL_A or SEL_B depends on the internal > counter which will also control the internal "mux". > > The target interface simplified as below which is used by Linux Kernel: > CLK[0-7]--->MUX-->Gate-->pre_div-->post_div > > A requirement of the Target Interface's software is that the > target clock source is active, it means when setting SEL_A, the > current input clk to SEL_A must be active, same to SEL_B. > > We touch target interface, but hardware logic actually also need > configure normal interface. > > There will be system hang, when doing the following steps: > The initial state: > SEL_A/SEL_B are both sourcing from clk0, the internal counter > choose SEL_A. > 1. switch mux from clk0 to clk1 > The hardware logic will choose SEL_B and configure SEL_B to clk1. > SEL_A no changed. > 2. gate off clk0 > Disable clk0, then the input to SEL_A is off. > 3. switch from clk1 to clk2 > The hardware logic will choose SEL_A and configure SEL_A to clk2, > however the current SEL_A input clk0 is off, the system hang. > > The solution to fix the issue is in step 1, write twice to > target interface MUX, it will make SEL_A/SEL_B both sources > from clk1, then no need to care about the state of clk0. And > finally system performs well. Shouldn't this also contain the original kernel commit author's Signed-off-by? > Signed-off-by: Michael Trimarchi <mich...@amarulasolutions.com>