nxp-mcuxpresso/mcux-sdk

Possibility to get Root Clock of Module based on Base Address on i.MXRT11xx

Opened this issue · 7 comments

Is your enhancement proposal related to a problem? Please describe.

I want to get the clock frequencies for a given LPI2C (or other peripheral) programmatically based on a module base address. Reason for that is that I currently initialize the modules based on an FDT which provides the base address but not some of the magic numbers like the kCLOCK_Root_Lpi2c4 that could be passed to the CLOCK_GetRootClockMux. Adding these to the FDT would be more or less redundant because the module could already be identified with the base address.

Describe the solution you'd like

The fsl_clock.h already provides arrays like LPI2C_CLOCKS. Together with LPI2C_BASE_PTRS from MIMXRT1166_cm7.h it is possible to map base addresses to clock_lpcg_t. A similar mapping would be possible if similar arrays for the root clocks would be provided (for example #define LPI2C_ROOT_CLOCK {kCLOCK_IpInvalid, kCLOCK_ROOT_Lpi2c1, kCLOCK_ROOT_Lpi2c2, ...}

Hi @c-mauderer, thanks your proposal. We will evaluate this. For the FDT, do you mean FDT Group? Could you please provide more details about the background?

Hi @c-mauderer, thanks your proposal. We will evaluate this. For the FDT, do you mean FDT Group? Could you please provide more details about the background?

With FDT I meant a flattened device tree. In my case it's a hand written one and not one generated with the NXP tools. I more or less have base addresses, "compatible" strings and some further information necessary for my application. My driver search for modules that are compatible and initialize for these modules. For finding the right clock information, I use the header files provided by the mcux-sdk.

Hi @c-mauderer, do you mean to generate some macros based on peripheral base address stored in device tree. And clock driver provide mapping between those macros and related clock roots?
For example, if LPI2C1's base address is 0x40001000, this property is stored in device tree, and a macro is generated based on device tree, may be CLOCK_ROOT_40001000. You want clock driver to provide a mapping:

#define CLOCK_ROOT_40001000 kCLOCK_ROOT_Lpi2c1

Hi @Albort12138, sorry I should have added an example. The device tree isn't that relevant. It's just one method to get a base address. What I want is to get the correct clock based on a base address. Let's assume I want to write a I2C driver. Someone (in my case a FDT) told me that I should work with a module at address 0x40110000 (which would be LPI2C4 on the IMXRT1166). Now I want to find out what root clock frequency it has because I need that to calculate my baudrate.

At the moment I can get the clock_ip_name_t like follows:

static clock_ip_name_t lpi2c_clock_ip(volatile LPI2C_Type *regs)
{
  LPI2C_Type *const base_addresses[] = LPI2C_BASE_PTRS;
  static const clock_ip_name_t lpi2c_clocks[] = LPI2C_CLOCKS;
  size_t i;

  for (i = 0; i < RTEMS_ARRAY_SIZE(base_addresses); ++i) {
    if (base_addresses[i] == regs) {
      return lpi2c_clocks[i];
    }
  }

  return kCLOCK_IpInvalid;
}

Now I have the clock_ip_name_t which I can use to for example enable my clock using CLOCK_EnableClock(...). But I still don't know the frequency. For that I need the CLOCK_GetRootClockFreq(...). But that function takes a clock_root_t and not a clock_ip_name_t. So I somehow have to get the matching clock_root_t. A hacky method for that is the following:

clock_root_t clock_root = lpi2c_clock_ip(base_ptr) + kCLOCK_Root_Lpi2c1 - kCLOCK_Lpi2c1

But obviously, that is not a clean solution because I just made an assumption that the kCLOCK_Root_Lpi2c* values have an incrementing order. It would be a lot cleaner if I would have something like LPI2C_CLOCKS for the root clocks too so that I can use a similar function like the lpi2c_clock_ip to find out the root_clock.

Hi @c-mauderer, thanks your clarification. I think, the function to return clock frequency based on clock_ip_name_t may satisfy your requirement. We already have plan to do this.

Hi @c-mauderer, thanks your clarification. I think, the function to return clock frequency based on clock_ip_name_t may satisfy your requirement. We already have plan to do this.

Yes, a function that can get the frequency based on the clock_ip_name_t would work quite well. Do you have some feature request or similar for that so that I can watch the progress on that function?

We plan to enable this feature next release. So hard to provide progress at this time point.😊