From 7f26516985061781d3176d3ad49a90d41c7843da Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Fri, 1 Nov 2024 14:47:03 +1100 Subject: [PATCH 01/11] Clock driver for odroidc4 This implementation includes all clock definitions, basic operations of clock compoents, as well as interfaces to interact with clicnets via PPC. Client should be able to enable/disable a specific gate clock or query the current clock rate by passing the corresponding clock identifier, which is listed in g12a-bindings.h. set_rate() assumes that the rate requst is valid and compatible with the current configurations. Complete implementation that considers more incompatible requests will come in the future when dynamic clock configuration is necessary in lionsos Signed-off-by: Terry Bai --- build.zig | 67 + drivers/clk/clk-operations.c | 336 +++ drivers/clk/clk-operations.h | 144 + drivers/clk/clk.h | 397 +++ drivers/clk/meson/clk-measure.c | 230 ++ drivers/clk/meson/clk-meson.c | 481 +++ drivers/clk/meson/clk.c | 257 ++ drivers/clk/meson/create_clk_config.py | 130 + drivers/clk/meson/include/clk-measure.h | 9 + drivers/clk/meson/include/clk-meson.h | 175 ++ drivers/clk/meson/include/g12a-bindings.h | 293 ++ drivers/clk/meson/include/g12a-regs.h | 131 + drivers/clk/meson/sm1-clk.c | 1533 ++++++++++ drivers/clk/utils.h | 33 + examples/clk/board/odroidc4/clk.system | 38 + examples/clk/build.zig | 136 + examples/clk/build.zig.zon | 15 + examples/clk/client.c | 42 + examples/clk/dts/odroidc4.dts | 3216 +++++++++++++++++++++ include/sddf/clk/client.h | 77 + include/sddf/clk/protocol.h | 27 + 21 files changed, 7767 insertions(+) create mode 100644 drivers/clk/clk-operations.c create mode 100644 drivers/clk/clk-operations.h create mode 100644 drivers/clk/clk.h create mode 100644 drivers/clk/meson/clk-measure.c create mode 100644 drivers/clk/meson/clk-meson.c create mode 100644 drivers/clk/meson/clk.c create mode 100644 drivers/clk/meson/create_clk_config.py create mode 100644 drivers/clk/meson/include/clk-measure.h create mode 100644 drivers/clk/meson/include/clk-meson.h create mode 100644 drivers/clk/meson/include/g12a-bindings.h create mode 100644 drivers/clk/meson/include/g12a-regs.h create mode 100644 drivers/clk/meson/sm1-clk.c create mode 100644 drivers/clk/utils.h create mode 100644 examples/clk/board/odroidc4/clk.system create mode 100644 examples/clk/build.zig create mode 100644 examples/clk/build.zig.zon create mode 100644 examples/clk/client.c create mode 100644 examples/clk/dts/odroidc4.dts create mode 100644 include/sddf/clk/client.h create mode 100644 include/sddf/clk/protocol.h diff --git a/build.zig b/build.zig index 3ff102735..8c8110952 100644 --- a/build.zig +++ b/build.zig @@ -26,6 +26,10 @@ const DriverClass = struct { virtio }; + const Clock = enum { + meson, + }; + const I2cHost = enum { meson, }; @@ -202,6 +206,50 @@ fn addBlockDriver( return driver; } +fn addClockDriver( + b: *std.Build, + clk_config_include: LazyPath, + util: *std.Build.Step.Compile, + class: DriverClass.Clock, + target: std.Build.ResolvedTarget, + optimize: std.builtin.OptimizeMode, +) *std.Build.Step.Compile { + const driver = addPd(b, .{ + .name = b.fmt("driver_clk_{s}.elf", .{@tagName(class)}), + .target = target, + .optimize = optimize, + .strip = false, + }); + + switch (class) { + .meson => { + const files: []const []const u8 = &.{ + "drivers/clk/meson/clk.c", + "drivers/clk/meson/clk-meson.c", + "drivers/clk/meson/clk-measure.c", + "drivers/clk/meson/sm1-clk.c", + }; + driver.addCSourceFiles(.{ .files = files }); + }, + } + + const common_src_files = .{ "clk-operations.c" }; + + inline for (common_src_files) |f| { + driver.addCSourceFile(.{ + .file = b.path(b.fmt("drivers/clk/{s}", .{ f })) + }); + } + + driver.addIncludePath(clk_config_include); + driver.addIncludePath(b.path("include")); + driver.addIncludePath(b.path("drivers/clk")); + driver.addIncludePath(b.path(b.fmt("drivers/clk/{s}/include", .{@tagName(class)}))); + driver.linkLibrary(util); + + return driver; +} + fn addMmcDriver( b: *std.Build, blk_config_include: LazyPath, @@ -301,6 +349,8 @@ pub fn build(b: *std.Build) void { const net_config_include_option = b.option([]const u8, "net_config_include", "Include path to network config header") orelse ""; const i2c_client_include_option = b.option([]const u8, "i2c_client_include", "Include path to client config header") orelse ""; const gpu_config_include_option = b.option([]const u8, "gpu_config_include", "Include path to gpu config header") orelse ""; + const clk_conf_include_option = b.option([]const u8, "clk_conf_include", "Include path to client config header") orelse ""; + const dtb_path = b.option([]const u8, "dtb_path", "Path to the DTB file") orelse ""; // TODO: Right now this is not super ideal. What's happening is that we do not // always need a serial config include, but we must always specify it @@ -312,6 +362,7 @@ pub fn build(b: *std.Build) void { const net_config_include = LazyPath{ .cwd_relative = net_config_include_option }; const i2c_client_include = LazyPath{ .cwd_relative = i2c_client_include_option }; const gpu_config_include = LazyPath{ .cwd_relative = gpu_config_include_option }; + const clk_client_include = LazyPath{ .cwd_relative = clk_conf_include_option }; // libmicrokit // We're declaring explicitly here instead of with anonymous structs due to a bug. See https://github.com/ziglang/zig/issues/19832 libmicrokit = LazyPath{ .cwd_relative = libmicrokit_opt.? }; @@ -454,6 +505,22 @@ pub fn build(b: *std.Build) void { b.installArtifact(driver); } + // Clock drivers + inline for (std.meta.fields(DriverClass.Clock)) |class| { + const driver = addClockDriver(b, clk_client_include, util, @enumFromInt(class.value), target, optimize); + driver.linkLibrary(util_putchar_debug); + + const clk_config = b.addSystemCommand(&.{ + "python", + b.fmt("drivers/clk/{s}/create_clk_config.py", .{ class.name }), + dtb_path, + clk_conf_include_option, + }); // Creates a system command which runs the python interpreter + driver.step.dependOn(&clk_config.step); + + b.installArtifact(driver); + } + // I2C components const i2c_virt = addPd(b, .{ .name = "i2c_virt.elf", diff --git a/drivers/clk/clk-operations.c b/drivers/clk/clk-operations.c new file mode 100644 index 000000000..4a355ee4f --- /dev/null +++ b/drivers/clk/clk-operations.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +/* + * Operations for MPLL clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-mpll.c + * + * Copyright (c) 2016 AmLogic, Inc. + * Author: Michael Turquette + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for PLL clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-pll.c + * + * Copyright (c) 2015 Endless Mobile, Inc. + * Author: Carlo Caione + * + * Copyright (c) 2018 Baylibre, SAS. + * Author: Jerome Brunet + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for gate clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-regmap.c + * + * Copyright (c) 2018 BayLibre, SAS. + * Author: Jerome Brunet + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for fixed factor clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-fixed-factor.c + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for divider clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-divider.c + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * Copyright (C) 2011 Richard Zhao, Linaro + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + * + * Adjustable divider clock implementation + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for multiplexer clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-mux.c + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * Copyright (C) 2011 Richard Zhao, Linaro + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + * + * Simple multiplexer clock implementation + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for meson_vid_pll_div are derived from: + * https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vid-pll-div.c + * https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vclk.c + * + * Copyright (c) 2018 BayLibre, SAS. + * Author: Neil Armstrong + */ + +#include +#include +#include +#include +#include + +int reg_write(uint64_t base, uint32_t offset, uint32_t val) +{ + volatile uint32_t *clk_reg = ((void *)base + offset); + *clk_reg = val; + + return 0; +} + +int regmap_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width, uint32_t val) +{ + volatile uint32_t *clk_reg = ((void *)base + offset); + uint32_t reg_val = *clk_reg; + + reg_val &= ~(MASK(width) << shift); + reg_val |= ((MASK(width) & val) << shift); + + *clk_reg = reg_val; + + /* TODO: Check if the register has been updated correctly */ + + return 0; +} + +int regmap_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width) +{ + volatile uint32_t *clk_reg = ((void *)base + offset); + uint32_t reg_val = *clk_reg; + + reg_val >>= shift; + reg_val &= MASK(width); + + return reg_val; +} + +int regmap_mux_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask, uint32_t val) +{ + volatile uint32_t *clk_reg = ((void *)base + offset); + uint32_t reg_val = *clk_reg; + + reg_val &= ~(mask << shift); + reg_val |= ((mask & val) << shift); + + *clk_reg = reg_val; + + /* TODO: Check if the register has been updated correctly */ + + return 0; +} + +int regmap_mux_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask) +{ + volatile uint32_t *clk_reg = ((void *)base + offset); + uint32_t reg_val = *clk_reg; + + reg_val >>= shift; + reg_val &= mask; + + return reg_val; +} + +static int clk_gate_enable(struct clk *clk) +{ + struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); + + return regmap_update_bits(clk->base, data->offset, data->bit_idx, 1, 1); +} + +static int clk_gate_disable(struct clk *clk) +{ + struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); + + regmap_update_bits(clk->base, data->offset, data->bit_idx, 1, 0); + return 0; +} + +static int clk_gate_is_enabled(struct clk *clk) +{ + struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); + + /* TODO: to be checked */ + /* if (gate->flags & CLK_GATE_SET_TO_DISABLE) */ + /* val ^= BIT(gate->bit_idx); */ + + /* val &= BIT(gate->bit_idx); */ + /* return val ? 1 : 0; */ + + return regmap_read_bits(clk->base, data->offset, data->bit_idx, 1); +} + +const struct clk_ops clk_gate_ops = { + .enable = clk_gate_enable, + .disable = clk_gate_disable, + .is_enabled = clk_gate_is_enabled, +}; + +const struct clk_ops clk_gate_ro_ops = { + .is_enabled = clk_gate_is_enabled, +}; + +static unsigned long clk_div_recalc_rate(const struct clk *clk, unsigned long prate) +{ + + struct clk_div_data *data = (struct clk_div_data *)(clk->data); + uint32_t div = regmap_read_bits(clk->base, data->offset, data->shift, data->width); + + /* TODO: Need to verify the following cases */ + if (data->flags & CLK_DIVIDER_ONE_BASED) { + ; + } else if (data->flags & CLK_DIVIDER_POWER_OF_TWO) { + div = 1 << div; + } else if (data->flags & CLK_DIVIDER_MAX_AT_ZERO) { + div = div ? div : MASK(data->width) + 1; + } else { + div += 1; + } + + return DIV_ROUND_UP_ULL((uint64_t)prate, div); +} + +static int clk_div_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_rate) +{ + struct clk_div_data *data = (struct clk_div_data *)(clk->data); + uint32_t div = DIV_ROUND_UP(parent_rate, rate); + + if (data->flags & CLK_DIVIDER_ONE_BASED) { + /* TODO: to be implemented */ + ; + } else if (data->flags & CLK_DIVIDER_POWER_OF_TWO) { + /* div = __ffs(div); */ + } else if (data->flags & CLK_DIVIDER_MAX_AT_ZERO) { + div = (div == MASK(data->width) + 1) ? 0 : div; + } else { + div -= 1; + } + return regmap_update_bits(clk->base, data->offset, data->shift, data->width, div); +} + +/* static int clk_div_determine_rate(struct clk_hw *hw, */ +/* struct clk_rate_request *req) */ +/* { */ +/* struct clk_div_data *data = (struct clk_div_data *)(hw->clk->data); */ +/* /\* struct clk_regmap *clk = to_clk_regmap(hw); *\/ */ +/* /\* struct clk_div_data *div = clk_get_regmap_div_data(clk); *\/ */ +/* uint32_t val; */ + +/* /\* if read only, just return current value *\/ */ +/* if (data->flags & CLK_DIVIDER_READ_ONLY) { */ +/* val = regmap_read_bits(data->offset, data->shift, data->width); */ + +/* /\* return divider_ro_determine_rate(hw, req, div->table, *\/ */ +/* /\* div->width, div->flags, val); *\/ */ +/* } */ + +/* /\* return divider_determine_rate(hw, req, div->table, div->width, *\/ */ +/* /\* div->flags); *\/ */ +/* return 0; */ +/* } */ + +const struct clk_ops clk_divider_ops = { + .enable = NULL, + .recalc_rate = clk_div_recalc_rate, + /* .determine_rate = clk_div_determine_rate, */ + .set_rate = clk_div_set_rate, +}; + +const struct clk_ops clk_divider_ro_ops = { + .recalc_rate = clk_div_recalc_rate, + /* .determine_rate = clk_div_determine_rate, */ +}; + +static uint8_t clk_mux_get_parent(const struct clk *clk) +{ + struct clk_mux_data *data = (struct clk_mux_data *)(clk->data); + uint32_t num_parents = clk->hw.init->num_parents; + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->shift, data->mask); + + if (data->table) { + int i; + for (i = 0; i < num_parents; i++) { + if (data->table[i] == val) + return i; + } + return -1; + /* return -EINVAL; */ + } + + /* if (val && (flags & CLK_MUX_INDEX_BIT)) */ + /* val = ffs(val) - 1; */ + + /* if (val && (flags & CLK_MUX_INDEX_ONE)) */ + /* val--; */ + + if (val >= num_parents) + /* return -EINVAL; */ + return -1; + + /* return val; */ + return 0; +} + +static int clk_mux_set_parent(struct clk *clk, uint8_t index) +{ + struct clk_mux_data *data = (struct clk_mux_data *)(clk->data); + + if (data->table) { + unsigned int val = data->table[index]; + regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, val); + } + /* TODO: handle cases without table given */ + + return 0; +} + +const struct clk_ops clk_mux_ops = { + .get_parent = clk_mux_get_parent, .set_parent = clk_mux_set_parent, + /* .determine_rate = clk_mux_determine_rate, */ +}; + +const struct clk_ops clk_mux_ro_ops = { + .get_parent = clk_mux_get_parent, +}; + +static unsigned long clk_factor_recalc_rate(const struct clk *clk, unsigned long parent_rate) +{ + struct clk_fixed_factor_data *data = (struct clk_fixed_factor_data *)(clk->data); + unsigned long long int rate; + + rate = (unsigned long long int)parent_rate * data->mult; + do_div(rate, data->div); + return (unsigned long)rate; +} + +const struct clk_ops clk_fixed_factor_ops = { + /* .round_rate = clk_factor_round_rate, */ + /* .set_rate = clk_factor_set_rate, */ + .recalc_rate = clk_factor_recalc_rate, + /* .recalc_accuracy = clk_factor_recalc_accuracy, */ +}; + +static int clk_source_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_rate) +{ + struct clk_source_data *data = (struct clk_source_data *)(clk->data); + data->rate = rate; + + return 0; +} + +static unsigned long clk_source_get_rate(const struct clk *clk, unsigned long prate) +{ + struct clk_source_data *data = (struct clk_source_data *)(clk->data); + + return data->rate; +} + +const struct clk_ops clk_source_ops = { + .recalc_rate = clk_source_get_rate, + .set_rate = clk_source_set_rate, +}; diff --git a/drivers/clk/clk-operations.h b/drivers/clk/clk-operations.h new file mode 100644 index 000000000..22d4607aa --- /dev/null +++ b/drivers/clk/clk-operations.h @@ -0,0 +1,144 @@ +/* + * Copyright 2024, UNSW + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +#define CLK_INCORRECT_ARGS 1 +#define CLK_INVALID_OP 2 + +int reg_write(uint64_t base, uint32_t offset, uint32_t val); +int regmap_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width, uint32_t val); +int regmap_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width); +int regmap_mux_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask, uint32_t val); +int regmap_mux_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask); + +extern const struct clk_ops clk_source_ops; +extern const struct clk_ops clk_fixed_factor_ops; +extern const struct clk_ops clk_divider_ops; +extern const struct clk_ops clk_divider_ro_ops; +extern const struct clk_ops clk_mux_ops; +extern const struct clk_ops clk_mux_ro_ops; +extern const struct clk_ops clk_gate_ops; +extern const struct clk_ops clk_gate_ro_ops; + +#define CLK_FIXED_FACTOR(_name, _mult, _div, _data_flags, _parent_clks, _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_fixed_factor_data) { \ + .mult = (_mult), \ + .div = (_div), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_fixed_factor_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ +} + +#define CLK_GATE(_name, _offset, _bit, _data_flags, _parent_clks, _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_gate_data) { \ + .offset = (_offset), \ + .bit_idx = (_bit), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_gate_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = _num_parents, \ + .flags = (_init_flags), \ + }, \ +} + +#define CLK_GATE_RO(_name, _offset, _bit, _data_flags, _parent_clks, _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_gate_data) { \ + .offset = (_offset), \ + .bit_idx = (_bit), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_gate_ro_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = _num_parents, \ + .flags = (_init_flags), \ + }, \ +} + +#define CLK_MUX(_name, _offset, _mask, _shift, _table, _data_flags, _parent_data, _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_mux_data) { \ + .offset = (_offset), \ + .mask = (_mask), \ + .shift = (_shift), \ + .table = (_table), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_mux_ops, \ + .parent_data = (_parent_data), \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ +} + +#define CLK_MUX_RO(_name, _offset, _mask, _shift, _table, _data_flags, _parent_data, _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_mux_data) { \ + .offset = (_offset), \ + .mask = (_mask), \ + .shift = (_shift), \ + .table = (_table), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_mux_ro_ops, \ + .parent_data = (_parent_data), \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ +} + +#define CLK_DIV(_name, _offset, _shift, _width, _data_flags, _parent_clks, _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_div_data) { \ + .offset = (_offset), \ + .shift = (_shift), \ + .width = (_width), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_divider_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ +} + +#define CLK_DIV_RO(_name, _offset, _shift, _width, _data_flags, _parent_clks, _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_div_data) { \ + .offset = (_offset), \ + .shift = (_shift), \ + .width = (_width), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_divider_ro_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ +} diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h new file mode 100644 index 000000000..8dc9ab22f --- /dev/null +++ b/drivers/clk/clk.h @@ -0,0 +1,397 @@ + +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2010-2011 Jeremy Kerr + * Copyright (C) 2011-2012 Linaro Ltd + * + * This file is derived from: + * https://github.com/torvalds/linux/blob/6485cf5ea253d40d507cd71253c9568c5470cd27/include/linux/clk-provider.h + */ + +#pragma once + +#include + +/* + * flags used across common struct clk. these flags should only affect the + * top-level framework. custom flags for dealing with hardware specifics + * belong in struct clk_foo + */ +#define CLK_SET_RATE_GATE BIT(0) /* must be gated across rate change */ +#define CLK_SET_PARENT_GATE BIT(1) /* must be gated across re-parent */ +#define CLK_SET_RATE_PARENT BIT(2) /* propagate rate change up one level */ +#define CLK_IGNORE_UNUSED BIT(3) /* do not gate even if unused */ + /* unused */ + /* unused */ +#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */ +#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */ +#define CLK_GET_ACCURACY_NOCACHE BIT(8) /* do not use the cached clk accuracy */ +#define CLK_RECALC_NEW_RATES BIT(9) /* recalc rates after notifications */ +#define CLK_SET_RATE_UNGATE BIT(10) /* clock needs to run to set rate */ +#define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */ +/* parents need enable during gate/ungate, set rate and re-parent */ +#define CLK_OPS_PARENT_ENABLE BIT(12) +/* duty cycle call may be forwarded to the parent clock */ +#define CLK_DUTY_CYCLE_PARENT BIT(13) + +#define CLK_GATE_SET_TO_DISABLE BIT(0) +#define CLK_GATE_HIWORD_MASK BIT(1) +#define CLK_GATE_BIG_ENDIAN BIT(2) + +#define CLK_DIVIDER_ONE_BASED BIT(0) +#define CLK_DIVIDER_POWER_OF_TWO BIT(1) +#define CLK_DIVIDER_ALLOW_ZERO BIT(2) +#define CLK_DIVIDER_HIWORD_MASK BIT(3) +#define CLK_DIVIDER_ROUND_CLOSEST BIT(4) +#define CLK_DIVIDER_READ_ONLY BIT(5) +#define CLK_DIVIDER_MAX_AT_ZERO BIT(6) +#define CLK_DIVIDER_BIG_ENDIAN BIT(7) + +#define CLK_MUX_INDEX_ONE BIT(0) +#define CLK_MUX_INDEX_BIT BIT(1) +#define CLK_MUX_HIWORD_MASK BIT(2) +#define CLK_MUX_READ_ONLY BIT(3) /* mux can't be changed */ +#define CLK_MUX_ROUND_CLOSEST BIT(4) +#define CLK_MUX_BIG_ENDIAN BIT(5) + +#define CLK_FRAC_DIVIDER_ZERO_BASED BIT(0) +#define CLK_FRAC_DIVIDER_BIG_ENDIAN BIT(1) +#define CLK_FRAC_DIVIDER_POWER_OF_TWO_PS BIT(2) + +struct clk; +struct clk_hw; +struct clk_init_data; + +/** + * struct clk_hw - handle for traversing from a struct clk to its corresponding + * hardware-specific structure. struct clk_hw should be declared within struct + * clk_foo and then referenced by the struct clk instance that uses struct + * clk_foo's clk_ops + * + * @init: pointer to struct clk_init_data that contains the init data shared + * with the common clock framework. This pointer will be set to NULL once + * a clk_register() variant is called on this clk_hw pointer. + */ +struct clk_hw { + struct clk *clk; + struct clk_init_data *init; +}; + +/** + * struct clk_ops - Callback operations for hardware clocks; these are to + * be provided by the clock implementation, and will be called by drivers + * through the clk_* api. + * + * @prepare: Prepare the clock for enabling. This must not return until + * the clock is fully prepared, and it's safe to call clk_enable. + * This callback is intended to allow clock implementations to + * do any initialisation that may sleep. Called with + * prepare_lock held. + * + * @unprepare: Release the clock from its prepared state. This will typically + * undo any work done in the @prepare callback. Called with + * prepare_lock held. + * + * @is_prepared: Queries the hardware to determine if the clock is prepared. + * This function is allowed to sleep. Optional, if this op is not + * set then the prepare count will be used. + * + * @enable: Enable the clock atomically. This must not return until the + * clock is generating a valid clock signal, usable by consumer + * devices. Called with enable_lock held. This function must not + * sleep. + * + * @disable: Disable the clock atomically. Called with enable_lock held. + * This function must not sleep. + * + * @is_enabled: Queries the hardware to determine if the clock is enabled. + * This function must not sleep. Optional, if this op is not + * set then the enable count will be used. + * + * @disable_unused: Disable the clock atomically. Only called from + * clk_disable_unused for gate clocks with special needs. + * Called with enable_lock held. This function must not + * sleep. + * + * @recalc_rate: Recalculate the rate of this clock, by querying hardware. The + * parent rate is an input parameter. It is up to the caller to + * ensure that the prepare_mutex is held across this call. If the + * driver cannot figure out a rate for this clock, it must return + * 0. Returns the calculated rate. Optional, but recommended - if + * this op is not set then clock rate will be initialized to 0. + * + * @round_rate: Given a target rate as input, returns the closest rate actually + * supported by the clock. The parent rate is an input/output + * parameter. + * + * @determine_rate: Given a target rate as input, returns the closest rate + * actually supported by the clock, and optionally the parent clock + * that should be used to provide the clock rate. + * + * @set_parent: Change the input source of this clock; for clocks with multiple + * possible parents specify a new parent by passing in the index + * as a u8 corresponding to the parent in either the .parent_names + * or .parents arrays. This function in affect translates an + * array index into the value programmed into the hardware. + * Returns 0 on success, -EERROR otherwise. + * + * @get_parent: Queries the hardware to determine the parent of a clock. The + * return value is a u8 which specifies the index corresponding to + * the parent clock. This index can be applied to either the + * .parent_names or .parents arrays. In short, this function + * translates the parent value read from hardware into an array + * index. Currently only called when the clock is initialized by + * __clk_init. This callback is mandatory for clocks with + * multiple parents. It is optional (and unnecessary) for clocks + * with 0 or 1 parents. + * + * @set_rate: Change the rate of this clock. The requested rate is specified + * by the second argument, which should typically be the return + * of .round_rate call. The third argument gives the parent rate + * which is likely helpful for most .set_rate implementation. + * Returns 0 on success, -EERROR otherwise. + * + * @init: Perform platform-specific initialization magic. + * This is not used by any of the basic clock types. + * This callback exist for HW which needs to perform some + * initialisation magic for CCF to get an accurate view of the + * clock. It may also be used dynamic resource allocation is + * required. It shall not used to deal with clock parameters, + * such as rate or parents. + * Returns 0 on success, -EERROR otherwise. + * + */ +struct clk_ops { + uint8_t (*get_parent)(const struct clk *clk); + int (*set_parent)(struct clk *clk, uint8_t index); + unsigned long (*recalc_rate)(const struct clk *clk, unsigned long parent_rate); + int (*set_rate)(const struct clk *clk, uint32_t rate, uint32_t parent_rate); + void (*init)(struct clk *clk); + int (*enable)(struct clk *clk); + int (*disable)(struct clk *clk); + int (*is_enabled)(struct clk *clk); +}; + +struct clk { + struct clk_hw hw; + void *data; + uint64_t base; +}; + +/** + * struct clk_parent_data - clk parent information + * @hw: parent clk_hw pointer (used for clk providers with internal clks) + * @name: globally unique parent name (used as a fallback) + */ +struct clk_parent_data { + const struct clk *clk; + const char *name; +}; + +/** + * struct clk_init_data - holds init data that's common to all clocks and is + * shared between the clock provider and the common clock framework. + * + * @name: clock name + * @ops: operations this clock supports + * @parent_names: array of string names for all possible parents + * @parent_data: array of parent data for all possible parents (when some + * parents are external to the clk controller) + * @parent_clks: array of pointers to all possible parents (when all parents + * are internal to the clk controller) + * @num_parents: number of possible parents + * @flags: framework-level hints and quirks + */ +struct clk_init_data { + uint32_t num_parents; + uint32_t flags; + const char *name; + const struct clk_ops *ops; + const struct clk **parent_clks; + const struct clk_parent_data *parent_data; +}; + +/** + * struct clk_source_data - clock source data + * + * @rate: ouput rate of clock hardware + * + */ +struct clk_source_data { + uint64_t rate; +}; + +/** + * struct clk_gate_data - gate specific data + * + * @offset: offset of the register controlling gate + * @bit_idx: single bit controlling gate + * @flags: hardware-specific flags + * + * Flags: + * CLK_GATE_SET_TO_DISABLE - by default this clock sets the bit at bit_idx to + * enable the clock. Setting this flag does the opposite: setting the bit + * disable the clock and clearing it enables the clock + * CLK_GATE_HIWORD_MASK - The gate settings are only in lower 16-bit + * of this register, and mask of gate bits are in higher 16-bit of this + * register. While setting the gate bits, higher 16-bit should also be + * updated to indicate changing gate bits. + * CLK_GATE_BIG_ENDIAN - by default little endian register accesses are used for + * the gate register. Setting this flag makes the register accesses big + * endian. + */ +struct clk_gate_data { + uint32_t offset; + uint8_t bit_idx; + uint8_t flags; +}; + +/** + * struct clk_div_data - adjustable divider clock + * + * @reg: register containing the divider + * @shift: shift to the divider bit field + * @width: width of the divider bit field + * @table: array of value/divider pairs, last entry should have div = 0 + * @lock: register lock + * + * Clock with an adjustable divider affecting its output frequency. Implements + * .recalc_rate, .set_rate and .round_rate + * + * @flags: + * CLK_DIVIDER_ONE_BASED - by default the divisor is the value read from the + * register plus one. If CLK_DIVIDER_ONE_BASED is set then the divider is + * the raw value read from the register, with the value of zero considered + * invalid, unless CLK_DIVIDER_ALLOW_ZERO is set. + * CLK_DIVIDER_POWER_OF_TWO - clock divisor is 2 raised to the value read from + * the hardware register + * CLK_DIVIDER_ALLOW_ZERO - Allow zero divisors. For dividers which have + * CLK_DIVIDER_ONE_BASED set, it is possible to end up with a zero divisor. + * Some hardware implementations gracefully handle this case and allow a + * zero divisor by not modifying their input clock + * (divide by one / bypass). + * CLK_DIVIDER_HIWORD_MASK - The divider settings are only in lower 16-bit + * of this register, and mask of divider bits are in higher 16-bit of this + * register. While setting the divider bits, higher 16-bit should also be + * updated to indicate changing divider bits. + * CLK_DIVIDER_ROUND_CLOSEST - Makes the best calculated divider to be rounded + * to the closest integer instead of the up one. + * CLK_DIVIDER_READ_ONLY - The divider settings are preconfigured and should + * not be changed by the clock framework. + * CLK_DIVIDER_MAX_AT_ZERO - For dividers which are like CLK_DIVIDER_ONE_BASED + * except when the value read from the register is zero, the divisor is + * 2^width of the field. + * CLK_DIVIDER_BIG_ENDIAN - By default little endian register accesses are used + * for the divider register. Setting this flag makes the register accesses + * big endian. + */ +struct clk_div_data { + uint32_t offset; + uint8_t shift; + uint8_t width; + uint8_t flags; + /* const struct clk_div_table *table; */ +}; + +/** + * struct clk_fixed_factor_data - fixed multiplier and divider clock + * + * @mult: multiplier + * @div: divider + * @flags: behavior modifying flags + * + * Clock with a fixed multiplier and divider. The output frequency is the + * parent clock rate divided by div and multiplied by mult. + * Implements .recalc_rate, .set_rate, .round_rate and .recalc_accuracy + * + * Flags: + * * CLK_FIXED_FACTOR_FIXED_ACCURACY - Use the value in @acc instead of the + * parent clk accuracy. + */ +struct clk_fixed_factor_data { + uint32_t mult; + uint32_t div; + uint8_t flags; +}; + +/** + * struct clk_mux_data - multiplexer clock + * + * @reg: register controlling multiplexer + * @table: array of register values corresponding to the parent index + * @shift: shift to multiplexer bit field + * @mask: mask of mutliplexer bit field + * @flags: hardware-specific flags + * @lock: register lock + * + * Clock with multiple selectable parents. Implements .get_parent, .set_parent + * and .recalc_rate + * + * Flags: + * CLK_MUX_INDEX_ONE - register index starts at 1, not 0 + * CLK_MUX_INDEX_BIT - register index is a single bit (power of two) + * CLK_MUX_HIWORD_MASK - The mux settings are only in lower 16-bit of this + * register, and mask of mux bits are in higher 16-bit of this register. + * While setting the mux bits, higher 16-bit should also be updated to + * indicate changing mux bits. + * CLK_MUX_READ_ONLY - The mux registers can't be written, only read in the + * .get_parent clk_op. + * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired + * frequency. + * CLK_MUX_BIG_ENDIAN - By default little endian register accesses are used for + * the mux register. Setting this flag makes the register accesses big + * endian. + */ +struct clk_mux_data { + uint32_t offset; + uint32_t *table; + uint32_t mask; + uint8_t shift; + uint8_t flags; +}; + +/** + * function clk_probe() - initialise all clocks + * + * @clk_list: array of pointers to the clocks on SoC + * + * All parent clocks will be parsed by name and bound to the struct clk + */ +void clk_probe(struct clk *clk_list[]); + +/** + * function get_parent() - get the current parent clk + * + * @clk: pointer to the current clk + */ +const struct clk *get_parent(const struct clk *clk); + +/** + * function clk_get_rate() - get the rate of target clock + * + * @clk: pointer to the current clk + * + */ +unsigned long clk_get_rate(const struct clk *clk); + +/** + * function clk_enable() - enable the target clock signal + * + * @clk: pointer to the current clk + */ +uint32_t clk_enable(struct clk *clk); + +/** + * function clk_disable() - disable the target clock signal + * + * @clk: pointer to the current clk + */ +uint32_t clk_disable(struct clk *clk); + +/** + * function clk_set_rate() - set the nearest rate to the requested rate for + * the target clock + * + * @clk: pointer to the current clk + */ +uint32_t clk_set_rate(struct clk *clk, uint32_t rate); diff --git a/drivers/clk/meson/clk-measure.c b/drivers/clk/meson/clk-measure.c new file mode 100644 index 000000000..ad1e49dfc --- /dev/null +++ b/drivers/clk/meson/clk-measure.c @@ -0,0 +1,230 @@ +/* + * + * This program is derived from: + * https://github.com/hardkernel/u-boot/blob/odroidg12-v2015.01/arch/arm/cpu/armv8/g12a/clock.c + * + * Copyright (C) 2015 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include + +#define TIMER_CH 1 + +#define MSR_CLK_BASE 0x03300000 +#define MSR_CLK_DUTY 0x00 +#define MSR_CLK_REG0 0x01 +#define MSR_CLK_REG1 0x02 +#define MSR_CLK_REG2 0x03 + +#define DIV_ROUND_CLOSEST_ULL(x, divisor)( \ +{ \ + typeof(divisor) __d = divisor; \ + unsigned long long _tmp = (x) + (__d) / 2; \ + do_div(_tmp, __d); \ + _tmp; \ +} \ +) + +static const char *const sm1_table[] = { + [0] = "am_ring_osc_clk_out_ee[0]", + [1] = "am_ring_osc_clk_out_ee[1]", + [2] = "am_ring_osc_clk_out_ee[2]", + [3] = "am_ring_osc_clk_out_ee[3]", + [4] = "gp0_pll_clk", + [5] = "gp1_pll_clk", + [6] = "cts_enci_clk", + [7] = "clk81", + [8] = "cts_encp_clk", + [9] = "cts_encl_clk", + [10] = "cts_vdac_clk", + [11] = "mac_eth_tx_clk", + [12] = "hifi_pll_clk", + [13] = "mod_tcon_clko", + [14] = "cts_FEC_CLK_0", + [15] = "cts_FEC_CLK_1", + [16] = "cts_FEC_CLK_2", + [17] = "sys_pll_div16", + [18] = "sys_cpu_clk_div16", + [19] = "lcd_an_clk_ph2", + [20] = "rtc_osc_clk_out", + [21] = "lcd_an_clk_ph3", + [22] = "mac_eth_phy_ref_clk", + [23] = "mpll_clk_50m", + [24] = "cts_eth_clk125Mhz", + [25] = "cts_eth_clk_rmii", + [26] = "sc_clk_int", + [27] = "co_clkin_to_mac", + [28] = "cts_sar_adc_clk", + [29] = "pcie_clk_inp", + [30] = "pcie_clk_inn", + [31] = "mpll_clk_test_out", + [32] = "cts_vdec_clk", + [33] = "1'b0", + [34] = "eth_mppll_50m_ckout", + [35] = "cts_mali_clk", + [36] = "cts_hdmi_tx_pixel_clk", + [37] = "cts_cdac_clk_c", + [38] = "cts_vdin_meas_clk", + [39] = "cts_bt656_clk0", + [40] = "arm_ring_osc_clk_out[4]", + [41] = "mac_eth_rx_clk_rmii", + [42] = "mp0_clk_out", + [43] = "fclk_div5", + [44] = "cts_pwm_B_clk", + [45] = "cts_pwm_A_clk", + [46] = "cts_vpu_clk", + [47] = "ddr_dpll_pt_clk", + [48] = "mp1_clk_out", + [49] = "mp2_clk_out", + [50] = "mp3_clk_out", + [51] = "cts_sd_emmc_clk_C", + [52] = "cts_sd_emmc_clk_B", + [53] = "cts_sd_emmc_clk_A", + [54] = "cts_vpu_clkc", + [55] = "vid_pll_div_clk_out", + [56] = "cts_wave420l_aclk", + [57] = "cts_wave420l_cclk", + [58] = "cts_wave420l_bclk", + [59] = "cts_hcodec_clk", + [60] = "arm_ring_osc_clk_out[5]", + [61] = "gpio_clk_msr", + [62] = "cts_hevcb_clk", + [63] = "cts_dsi_meas_clk", + [64] = "cts_spicc_1_clk", + [65] = "cts_spicc_0_clk", + [66] = "cts_vid_lock_clk", + [67] = "cts_dsi_phy_clk", + [68] = "cts_hdcp22_esmclk", + [69] = "cts_hdcp22_skpclk", + [70] = "cts_pwm_F_clk", + [71] = "cts_pwm_E_clk", + [72] = "cts_pwm_D_clk", + [73] = "cts_pwm_C_clk", + [74] = "arm_ring_osc_clk_out[6]", + [75] = "cts_hevcf_clk", + [76] = "arm_ring_osc_clk_out[7]", + [77] = "rng_ring_osc_clk[0]", + [78] = "rng_ring_osc_clk[1]", + [79] = "rng_ring_osc_clk[2]", + [80] = "rng_ring_osc_clk[3]", + [81] = "cts_vapbclk", + [82] = "cts_ge2d_clk", + [83] = "co_rx_clk", + [84] = "co_tx_clk", + [85] = "arm_ring_osc_clk_out[8]", + [86] = "arm_ring_osc_clk_out[9]", + [87] = "mipi_csi_phy_clk", + [88] = "csi2_adapt_clk", + [89] = "HDMI_CLK_TODIG", + [90] = "cts_hdmitx_sys_clk", + [91] = "nna_core_clk", + [92] = "nna_axi_clk", + [93] = "vad_clk", + [94] = "eth_phy_rxclk", + [95] = "eth_phy_plltxclk", + [96] = "cts_vpu_clkb", + [97] = "cts_vpu_clkb_tmp", + [98] = "cts_ts_clk", + [99] = "arm_ring_osc_clk_out[10]", + [100] = "arm_ring_osc_clk_out[11]", + [101] = "arm_ring_osc_clk_out[12]", + [102] = "arm_ring_osc_clk_out[13]", + [103] = "arm_ring_osc_clk_out[14]", + [104] = "arm_ring_osc_clk_out[15]", + [105] = "arm_ring_osc_clk_out[16]", + [106] = "ephy_test_clk", + [107] = "au_dac_clk_g128x", + [108] = "c_alocker_in_clk", + [109] = "c_alocker_out_clk", + [110] = "audio_tdmout_c_sclk", + [111] = "audio_tdmout_b_sclk", + [112] = "audio_tdmout_a_sclk", + [113] = "audio_tdmin_lb_sclk", + [114] = "audio_tdmin_c_sclk", + [115] = "audio_tdmin_b_sclk", + [116] = "audio_tdmin_a_sclk", + [117] = "audio_resampleA_clk", + [118] = "audio_pdm_sysclk", + [119] = "audio_spdifout_b_mst_clk", + [120] = "audio_spdifout_mst_clk", + [121] = "audio_spdifin_mst_clk", + [122] = "mod_audio_pdm_dclk_o", + [123] = "audio_resampled_clk", + [124] = "earcx_pll_(dmac)_clk", + [125] = "earcrx_pll_test_clk", + [126] = "csi_phy0_clk_out", + [127] = "clk_csi2_data", +}; + +unsigned long clk_msr(unsigned long clk_mux) +{ + volatile uint32_t *mclk_reg0 = ((void *)MSR_CLK_BASE + (MSR_CLK_REG0 << 2)); + volatile uint32_t *mclk_reg2 = ((void *)MSR_CLK_BASE + (MSR_CLK_REG2 << 2)); + uint32_t duration = 640; + uint32_t regval = 0; + + /* Disable continuous measurement */ + /* Disable interrupts */ + *mclk_reg0 = regval; + + regval |= duration; /* 64uS is enough for measure the frequence? */ + *mclk_reg0 = regval; + + regval |= (clk_mux << 20); /* Select MUX */ + *mclk_reg0 = regval; + + regval |= (1 << 19); /* enable the clock */ + regval |= (1 << 16); /* enable measuring */ + *mclk_reg0 = regval; + + regval = *mclk_reg0; + + uint64_t start_time = sddf_timer_time_now(TIMER_CH); + uint64_t now_time = start_time; + + /* TODO: Check the busy bit */ + /* if (regval & (1 << 31)) */ + /* sddf_dprintf("CLK | ERR: The clock measure logic is busy\n"); */ + + /* Wait for the measurement to be done */ + while (true) { + now_time = sddf_timer_time_now(TIMER_CH); + + if ((now_time - start_time) > 1000000) { + break; + } + /* TODO: Could be optimised via timeouts */ + /* if (sleep_us) */ + /* udelay(sleep_us); */ + } + + regval &= ~(1 << 16); /* disable measuring */ + *mclk_reg0 = regval; + + uint32_t msr_val = *mclk_reg2; + + return DIV_ROUND_CLOSEST_ULL((msr_val & ((1 << 19) - 1)) * 1000000ULL, duration); +} + +const char *const *get_msr_clk_list(void) +{ + return sm1_table; +} diff --git a/drivers/clk/meson/clk-meson.c b/drivers/clk/meson/clk-meson.c new file mode 100644 index 000000000..67b864e32 --- /dev/null +++ b/drivers/clk/meson/clk-meson.c @@ -0,0 +1,481 @@ +// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +/* + * Operations for MPLL clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-mpll.c + * + * Copyright (c) 2016 AmLogic, Inc. + * Author: Michael Turquette + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for PLL clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-pll.c + * + * Copyright (c) 2015 Endless Mobile, Inc. + * Author: Carlo Caione + * + * Copyright (c) 2018 Baylibre, SAS. + * Author: Jerome Brunet + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for gate clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-regmap.c + * + * Copyright (c) 2018 BayLibre, SAS. + * Author: Jerome Brunet + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for fixed factor clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-fixed-factor.c + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for divider clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-divider.c + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * Copyright (C) 2011 Richard Zhao, Linaro + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + * + * Adjustable divider clock implementation + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for multiplexer clocks are derived from: + * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-mux.c + * + * Copyright (C) 2011 Sascha Hauer, Pengutronix + * Copyright (C) 2011 Richard Zhao, Linaro + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + * + * Simple multiplexer clock implementation + */ + +// SPDX-License-Identifier: GPL-2.0 +/* + * Operations for meson_vid_pll_div are derived from: + * https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vid-pll-div.c + * https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vclk.c + * + * Copyright (c) 2018 BayLibre, SAS. + * Author: Neil Armstrong + */ + +#include +#include +#include +#include +#include + +#define TIMER_CH 1 + +static inline uint32_t meson_parm_read(uint64_t base, struct parm parm) +{ + return regmap_read_bits(base, parm.reg_off, parm.shift, parm.width); +} + +/* TODO: Replace this doggy dealy() with a standard interface */ +void delay_us(uint32_t us) +{ + uint64_t start_time = sddf_timer_time_now(TIMER_CH); + uint64_t now_time = start_time; + while (now_time - start_time < us) { + now_time = sddf_timer_time_now(TIMER_CH); + } +} + +int regmap_multi_reg_write(uint64_t base, const struct reg_sequence *regs, int num_regs) +{ + int i; + for (i = 0; i < num_regs; i++) { + reg_write(base, regs[i].reg, regs[i].def); + /* TODO: delay is needed */ + if (regs[i].delay_us) { + delay_us(regs[i].delay_us); + } + } + return 0; +} + +static void meson_clk_pll_init(struct clk *clk) +{ + struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); + if ((data->flags & CLK_MESON_PLL_NOINIT_ENABLED) && clk->hw.init->ops->is_enabled(clk)) + return; + + if (data->init_count) { + /* Set the reset bit */ + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); + + regmap_multi_reg_write(clk->base, data->init_regs, data->init_count); + + /* Clear the reset bit */ + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 0); + } +} + +static unsigned long meson_clk_pll_recalc_rate(const struct clk *clk, unsigned long parent_rate) +{ + struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); + uint32_t n, m, frac; + + n = regmap_read_bits(clk->base, data->n.reg_off, data->n.shift, data->n.width); + if (n == 0) + return 0; + + m = regmap_read_bits(clk->base, data->m.reg_off, data->m.shift, data->m.width); + + frac = data->frac.width ? regmap_read_bits(clk->base, data->frac.reg_off, data->frac.shift, data->frac.width) : 0; + + uint64_t rate = (uint64_t)parent_rate * m; + + if (frac) { + uint64_t frac_rate = (uint64_t)parent_rate * frac; + rate += DIV_ROUND_UP_ULL(frac_rate, (1 << data->frac.width)); + } + + return DIV_ROUND_UP_ULL(rate, n); +} + +static int meson_clk_pll_is_enabled(struct clk *clk) +{ + struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); + + if (data->rst.width && meson_parm_read(clk->base, data->rst)) { + return 0; + } + + if (!meson_parm_read(clk->base, data->en) || !meson_parm_read(clk->base, data->l)) { + return 0; + } + + return 1; +} + +static int meson_clk_pll_enable(struct clk *clk) +{ + struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); + + if (meson_clk_pll_is_enabled(clk)) + return 0; + + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); + regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, data->en.width, 1); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); + + regmap_update_bits(clk->base, data->current_en.reg_off, data->current_en.shift, data->current_en.width, 1); + return 0; +} + +static int meson_clk_pll_disable(struct clk *clk) +{ + struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); + + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); + regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, data->en.width, 0); + return 0; +} + +const struct clk_ops meson_clk_pll_ops = { .init = meson_clk_pll_init, + .recalc_rate = meson_clk_pll_recalc_rate, + /* .determine_rate = meson_clk_pll_determine_rate, */ + /* .set_rate = meson_clk_pll_set_rate, */ + .is_enabled = meson_clk_pll_is_enabled, + .enable = meson_clk_pll_enable, + .disable = meson_clk_pll_disable }; + +const struct clk_ops meson_clk_pll_ro_ops = { + .recalc_rate = meson_clk_pll_recalc_rate, + .is_enabled = meson_clk_pll_is_enabled, +}; + +#define SDM_DEN 16384 +#define N2_MIN 4 +#define N2_MAX 511 + +static unsigned long mpll_recalc_rate(const struct clk *clk, unsigned long prate) +{ + struct meson_clk_mpll_data *data = (struct meson_clk_mpll_data *)(clk->data); + uint32_t sdm, n2; + + sdm = regmap_read_bits(clk->base, data->sdm.reg_off, data->sdm.shift, data->sdm.width); + n2 = regmap_read_bits(clk->base, data->n2.reg_off, data->n2.shift, data->n2.width); + + uint32_t divisor = (SDM_DEN * n2) + sdm; + if (n2 < N2_MIN) + return -1; + + return DIV_ROUND_UP_ULL((uint64_t)prate * SDM_DEN, divisor); +} + +static int mpll_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_rate) +{ + struct meson_clk_mpll_data *data = (struct meson_clk_mpll_data *)(clk->data); + uint64_t div = parent_rate; + uint64_t frac = do_div(div, rate); + uint32_t sdm, n2; + + frac *= SDM_DEN; + + if (data->flags & CLK_MESON_MPLL_ROUND_CLOSEST) + sdm = DIV_ROUND_CLOSEST_ULL(frac, rate); + else + sdm = DIV_ROUND_UP_ULL(frac, rate); + + if (sdm == SDM_DEN) { + sdm = 0; + div += 1; + } + + if (div < N2_MIN) { + n2 = N2_MIN; + sdm = 0; + } else if (div > N2_MAX) { + n2 = N2_MAX; + sdm = SDM_DEN - 1; + } else { + n2 = div; + } + + regmap_update_bits(clk->base, data->sdm.reg_off, data->sdm.shift, data->sdm.width, sdm); + regmap_update_bits(clk->base, data->n2.reg_off, data->n2.shift, data->n2.width, n2); + + /* volatile uint32_t *clk_reg = ((void *)clk_base + data->sdm.reg_off); */ + + return 0; +} + +static void mpll_init(struct clk *clk) +{ + struct meson_clk_mpll_data *data = (struct meson_clk_mpll_data *)(clk->data); + if (data->init_count) { + regmap_multi_reg_write(clk->base, data->init_regs, data->init_count); + } + + /* Enable the fractional part */ + regmap_update_bits(clk->base, data->sdm_en.reg_off, data->sdm_en.shift, data->sdm_en.width, 1); + + /* Set spread spectrum if possible */ + unsigned int ss = data->flags & CLK_MESON_MPLL_SPREAD_SPECTRUM ? 1 : 0; + regmap_update_bits(clk->base, data->ssen.reg_off, data->ssen.shift, data->ssen.width, ss); +} + +const struct clk_ops meson_clk_mpll_ops = { + .recalc_rate = mpll_recalc_rate, + /* .determine_rate = mpll_determine_rate, */ + .set_rate = mpll_set_rate, + .init = mpll_init, +}; + +static int meson_clk_pcie_pll_enable(struct clk *clk) +{ + struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); + int retries = 10; + int delay = 5000; + + do { + meson_clk_pll_init(clk); + do { + if (meson_parm_read(clk->base, data->l)) { + return 0; + } + delay_us(20); + } while (--delay); + } while (--retries); + + return -1; +} + +const struct clk_ops meson_clk_pcie_pll_ops = { .init = meson_clk_pll_init, + .recalc_rate = meson_clk_pll_recalc_rate, + /* .determine_rate = meson_clk_pll_determine_rate, */ + .is_enabled = meson_clk_pll_is_enabled, + .enable = meson_clk_pcie_pll_enable, + .disable = meson_clk_pll_disable }; + +struct vid_pll_div { + unsigned int shift_val; + unsigned int shift_sel; + unsigned int divider; + unsigned int multiplier; +}; + +#define VID_PLL_DIV(_val, _sel, _ft, _fb) \ + { \ + .shift_val = (_val), \ + .shift_sel = (_sel), \ + .divider = (_ft), \ + .multiplier = (_fb), \ + } + +static const struct vid_pll_div vid_pll_div_table[] = { + VID_PLL_DIV(0x0aaa, 0, 2, 1), /* 2/1 => /2 */ + VID_PLL_DIV(0x5294, 2, 5, 2), /* 5/2 => /2.5 */ + VID_PLL_DIV(0x0db6, 0, 3, 1), /* 3/1 => /3 */ + VID_PLL_DIV(0x36cc, 1, 7, 2), /* 7/2 => /3.5 */ + VID_PLL_DIV(0x6666, 2, 15, 4), /* 15/4 => /3.75 */ + VID_PLL_DIV(0x0ccc, 0, 4, 1), /* 4/1 => /4 */ + VID_PLL_DIV(0x739c, 2, 5, 1), /* 5/1 => /5 */ + VID_PLL_DIV(0x0e38, 0, 6, 1), /* 6/1 => /6 */ + VID_PLL_DIV(0x0000, 3, 25, 4), /* 25/4 => /6.25 */ + VID_PLL_DIV(0x3c78, 1, 7, 1), /* 7/1 => /7 */ + VID_PLL_DIV(0x78f0, 2, 15, 2), /* 15/2 => /7.5 */ + VID_PLL_DIV(0x0fc0, 0, 12, 1), /* 12/1 => /12 */ + VID_PLL_DIV(0x3f80, 1, 14, 1), /* 14/1 => /14 */ + VID_PLL_DIV(0x7f80, 2, 15, 1), /* 15/1 => /15 */ +}; + +static unsigned long meson_vid_pll_div_recalc_rate(const struct clk *clk, unsigned long prate) +{ + struct meson_vid_pll_div_data *data = (struct meson_vid_pll_div_data *)(clk->data); + const struct vid_pll_div *div; + uint32_t shift_val, shift_sel; + + shift_val = regmap_read_bits(clk->base, data->val.reg_off, data->val.shift, data->val.width); + shift_sel = regmap_read_bits(clk->base, data->sel.reg_off, data->sel.shift, data->sel.width); + + int i; + + for (i = 0; i < ARRAY_SIZE(vid_pll_div_table); ++i) { + if (vid_pll_div_table[i].shift_val == shift_val && vid_pll_div_table[i].shift_sel == shift_sel) { + div = &vid_pll_div_table[i]; + break; + } + } + + return DIV_ROUND_UP_ULL(prate * div->multiplier, div->divider); +} + +const struct clk_ops meson_vid_pll_div_ro_ops = { + .recalc_rate = meson_vid_pll_div_recalc_rate, +}; + +static int meson_vclk_gate_enable(struct clk *clk) +{ + struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); + + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 1); + + /* Do a reset pulse */ + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 1); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 0); + + return 0; +} + +static int meson_vclk_gate_disable(struct clk *clk) +{ + struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); + + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 0); + return 0; +} + +static int meson_vclk_gate_is_enabled(struct clk *clk) +{ + struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); + return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width); +} + +const struct clk_ops meson_vclk_gate_ops = { + .enable = meson_vclk_gate_enable, + .disable = meson_vclk_gate_disable, + .is_enabled = meson_vclk_gate_is_enabled, +}; + +static unsigned long meson_vclk_div_recalc_rate(const struct clk *clk, unsigned long prate) +{ + struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); + uint32_t div = regmap_read_bits(clk->base, data->div.reg_off, data->div.shift, data->div.width); + + /* TODO: Need to verify the following cases */ + if (data->flags & CLK_DIVIDER_ONE_BASED) { + ; + } else if (data->flags & CLK_DIVIDER_POWER_OF_TWO) { + div = 1 << div; + } else if (data->flags & CLK_DIVIDER_MAX_AT_ZERO) { + div = div ? div : MASK(data->div.width) + 1; + } else { + div += 1; + } + + return DIV_ROUND_UP_ULL((uint64_t)prate, div); +} + +static int meson_vclk_div_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_rate) +{ + struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); + + uint32_t div = DIV_ROUND_UP(parent_rate, rate); + + if (data->flags & CLK_DIVIDER_ONE_BASED) { + /* TODO: to be implemented */ + ; + } else if (data->flags & CLK_DIVIDER_POWER_OF_TWO) { + /* div = __ffs(div); */ + } else if (data->flags & CLK_DIVIDER_MAX_AT_ZERO) { + div = (div == MASK(data->div.width) + 1) ? 0 : div; + } else { + div -= 1; + } + return regmap_update_bits(clk->base, data->div.reg_off, data->div.shift, data->div.width, div); +} + +static int meson_vclk_div_enable(struct clk *clk) +{ + struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); + + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 0); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 1); + + return 0; +} + +static int meson_vclk_div_disable(struct clk *clk) +{ + struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); + + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 0); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 1); + return 0; +} + +static int meson_vclk_div_is_enabled(struct clk *clk) +{ + struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); + return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width); +} + +const struct clk_ops meson_vclk_div_ops = { + .recalc_rate = meson_vclk_div_recalc_rate, + /* .determine_rate = meson_vclk_div_determine_rate, */ + .set_rate = meson_vclk_div_set_rate, + .enable = meson_vclk_div_enable, + .disable = meson_vclk_div_disable, + .is_enabled = meson_vclk_div_is_enabled, +}; + +static unsigned long meson_clk_cpu_dyndiv_recalc_rate(const struct clk *clk, unsigned long prate) +{ + struct meson_clk_cpu_dyndiv_data *data = (struct meson_clk_cpu_dyndiv_data *)(clk->data); + uint32_t div = meson_parm_read(clk->base, data->div); + + div += 1; + + return DIV_ROUND_UP_ULL((uint64_t)prate, div); +} + +const struct clk_ops meson_clk_cpu_dyndiv_ops = { + .recalc_rate = meson_clk_cpu_dyndiv_recalc_rate, + /* .determine_rate = meson_clk_cpu_dyndiv_determine_rate, */ + /* .set_rate = meson_clk_cpu_dyndiv_set_rate, */ +}; diff --git a/drivers/clk/meson/clk.c b/drivers/clk/meson/clk.c new file mode 100644 index 000000000..414d8033d --- /dev/null +++ b/drivers/clk/meson/clk.c @@ -0,0 +1,257 @@ +/* + * Copyright 2024, UNSW + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Terry Bai: tianyi.bai@unsw.edu.au + */ + +#include +#include +#include +#include +#include +#include + +#include /* common definitions and interfaces */ +#include /* ops of common clocks e.g., div, mux, fixed factor, and gate*/ +#include /* implementation of clock measurements */ +#include /* operations for meson-specific clocks */ +#include /* offsets of control registers */ +#include /* clock id bindings*/ + +// Logging +#define DEBUG_DRIVER + +#ifdef DEBUG_DRIVER +#define LOG_DRIVER(...) do{ sddf_dprintf("CLK DRIVER|INFO: "); sddf_dprintf(__VA_ARGS__); }while(0) +#else +#define LOG_DRIVER(...) do{}while(0) +#endif + +#define LOG_DRIVER_ERR(...) do{ sddf_printf("CLK DRIVER|ERROR: "); sddf_printf(__VA_ARGS__); }while(0) + +#define I2C_CLK_OFFSET 320 +#define I2C_CLK_BIT (1 << 9) // bit 9 + +uintptr_t clk_regs; +uintptr_t msr_clk_base; + +struct clk **clk_list; + +/* TODO: Should be configured with init_regs */ +/* static struct clk_cfg fixed_clk_configs[] = { */ +/* { .clk_id = CLKID_FCLK_DIV2_DIV, .frequency = 1000000000 }, */ +/* { .clk_id = CLKID_FCLK_DIV3_DIV, .frequency = 666666667 }, */ +/* { .clk_id = CLKID_FCLK_DIV4_DIV, .frequency = 500000000 }, */ +/* { .clk_id = CLKID_FCLK_DIV5_DIV, .frequency = 400000000 }, */ +/* { .clk_id = CLKID_FCLK_DIV7_DIV, .frequency = 285700000 }, */ +/* } */ + +void clk_probe(struct clk *clk_list[]) +{ + int i; + for (i = 0; i < CLKID_PCIE_PLL; i++) { + clk_list[i]->base = (uint64_t)clk_regs; + if (clk_list[i] && clk_list[i]->hw.init->ops->init) { + clk_list[i]->hw.init->ops->init(clk_list[i]); + LOG_DRIVER("Initialise %s\n", clk_list[i]->hw.init->name); + } + } +} + +const struct clk *get_parent(const struct clk *clk) +{ + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; + uint32_t num_parents = init->num_parents; + + if (init->parent_data) { + uint8_t parent_idx = num_parents > 1 ? init->ops->get_parent(clk) : 0; + struct clk_parent_data parent_data = init->parent_data[parent_idx]; + + if (parent_data.clk) { + return parent_data.clk; + } else if (sddf_strcmp(parent_data.name, "xtal") == 0) { + return &g12a_xtal; + } + } + + if (num_parents > 0) { + return init->parent_clks[0]; + } + + return NULL; +} + +/* TODO: Should be just read from the structure, but need to update everytime when */ +/* related clocks are modified */ +unsigned long clk_get_rate(const struct clk *clk) +{ + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; + unsigned long parent_rate = 0; + + const struct clk *parent_clk = get_parent(clk); + if (parent_clk) { + parent_rate = clk_get_rate(parent_clk); + } + + unsigned long rate = parent_rate; + if (init->ops->recalc_rate) { + rate = init->ops->recalc_rate(clk, parent_rate); + } + + return rate; +} + +uint32_t clk_enable(struct clk *clk) +{ + if (clk->hw.init->ops->enable != NULL) { + return clk->hw.init->ops->enable(clk); + } + + return CLK_INVALID_OP; +} + +uint32_t clk_disable(struct clk *clk) +{ + if (clk->hw.init->ops->disable != NULL) { + return clk->hw.init->ops->disable(clk); + } + + return CLK_INVALID_OP; +} + +uint32_t clk_set_rate(struct clk *clk, uint32_t rate) +{ + if (clk->hw.init->ops->init) { + clk->hw.init->ops->init(clk); + } + + const struct clk *pclk = get_parent(clk); + uint64_t prate = clk_get_rate(pclk); + if (clk->hw.init->ops->set_rate) { + /* TODO: determine_rate() needs to be implemented */ + LOG_DRIVER("set %s to %dHz\n", clk->hw.init->name, rate); + clk->hw.init->ops->set_rate(clk, rate, prate); + } else { + /* TODO: We only propagate one level right now */ + if (pclk->hw.init->ops->set_rate) { + const struct clk *ppclk = get_parent(pclk); + uint64_t pprate = clk_get_rate(ppclk); + /* TODO: determine_rate() needs to be implemented */ + LOG_DRIVER("set %s to %dHz\n", pclk->hw.init->name, rate); + pclk->hw.init->ops->set_rate(pclk, prate, pprate); + } + } + + return 0; +} + +int clk_msr_stat() +{ + unsigned long clk_freq; + int i = 0; + + const char *const *clk_msr_list = get_msr_clk_list(); + for (i = 0; i < 128; i++) { + clk_freq = clk_msr(i); + LOG_DRIVER("[%4d][%4ldHz] %s\n", i, clk_freq, clk_msr_list[i]); + } + + return 0; +} + +void notified(microkit_channel ch) +{ +} + +void init(void) +{ + LOG_DRIVER("Clock driver initialising...\n"); + + clk_list = get_clk_list(); + + clk_probe(clk_list); + + volatile uint32_t *clk_i2c_ptr = ((void *)clk_regs + I2C_CLK_OFFSET); + + for (int i = 0; i < NUM_DEVICE_CLKS; i++) { + struct clk *clk = clk_list[clk_configs[i].clk_id]; + + /* Enable the clock */ + clk_enable(clk); + + /* TODO: Set parent */ + + /* Set rate for the target clock */ + if (clk_configs[i].frequency > 0) { + clk_set_rate(clk, clk_configs[i].frequency); + } + } + + // Check that registers actually changed + if (!(*clk_i2c_ptr & I2C_CLK_BIT)) { + LOG_DRIVER_ERR("failed to toggle clock!\n"); + } + + /* clk_msr_stat(); */ +} + +microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) +{ + uint32_t ret = 0; + uint32_t argc = microkit_msginfo_get_count(msginfo); + + /* TODO: Check if the channel is valid */ + switch (microkit_msginfo_get_label(msginfo)) { + + case SDDF_CLK_ENABLE: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + LOG_DRIVER("get request clk_enable(%d)\n", clk_id); + ret = clk_enable(clk_list[clk_id]); + break; + } + case SDDF_CLK_DISABLE: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + LOG_DRIVER("get request clk_disable(%d)\n", clk_id); + ret = clk_disable(clk_list[clk_id]); + break; + } + case SDDF_CLK_GET_RATE: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + ret = clk_get_rate(clk_list[clk_id]); + break; + } + case SDDF_CLK_SET_RATE: { + if (argc != 2) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + uint32_t rate = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_RATE); + ret = clk_set_rate(clk_list[clk_id], rate); + break; + } + default: + LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), + ch); + ret = 5; + } + return microkit_msginfo_new(ret, 0); +} diff --git a/drivers/clk/meson/create_clk_config.py b/drivers/clk/meson/create_clk_config.py new file mode 100644 index 000000000..34b0ad016 --- /dev/null +++ b/drivers/clk/meson/create_clk_config.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 + +# Copyright 2024, UNSW +# SPDX-License-Identifier: BSD-2-Clause +# +# The template is stolen from Bill's pinmux driver + +import os +import sys +from typing import List +from devicetree import edtlib, dtlib + +supported_compat_str_board = { "hardkernel,odroid-c4" } + +debug_parser = True +clock_list = {} + +def log_normal_parser(print_str: str) -> None: + if (debug_parser): + print("PARSER|INFO: " + print_str) + +def log_warning_parser(print_str: str) -> None: + sys.stderr.write("PARSER|WARNING: " + print_str) + +def log_error_parser(print_str: str) -> None: + sys.stderr.write("PARSER|ERROR: " + print_str) + +def parse_clock_list(dt: dtlib.DT, clocks: List) -> (List, List): + pnodes = [] + clk_ids = [] + i = 0 + + while (i < len(clocks)): + if clocks[i] == 0: + clk_ids.append(clocks[i]) + i += 1 + continue + pnode = devicetree.phandle2node[clocks[i]] + if "#clock-cells" in pnode.props and pnode.props["#clock-cells"].to_num() == 0: + # TODO: consider the case of `xtal` and represent this clock another way + clk_ids.append(clocks[i]) + pnodes.append(pnode) + elif clocks[i] > 0: + clk_ids.append(clocks[i+1]) + pnodes.append(pnode) + i += 1 + else: + clk_ids.append(-1) + i += 1 + + return clk_ids, pnodes + +def add_clock(clk_id: int, frequency: int, pclk_id: int): + if clk_id in clock_list.keys(): + if clock_list[clk_id][0] == 0 and frequency: + clock_list[clk_id] = (frequency, clock_list[clk_id][1]) + if clock_list[clk_id][1] == 0 and pclk_id: + clock_list[clk_id] = (clock_list[clk_id][0], pclk_id) + else: + clock_list[clk_id] = (frequency, pclk_id) + +def extract_clocks(dt: dtlib.DT, node: dtlib.Node) -> List: + props = list(node.props.keys()) + if "clocks" in props: + clocks = node.props["clocks"].to_nums() + clock_ids, pnodes = parse_clock_list(devicetree, clocks) + for clk_id in clock_ids: + add_clock(clk_id, 0, 0) + for pnode in pnodes: + extract_clocks(dt, pnode) + + if "max-frequency" in props: + max_frequency = node.props["max-frequency"].to_nums() + + if "assigned-clocks" in props and "assigned-clock-rates" in props: + assigned_clocks, pnodes = parse_clock_list(devicetree, node.props["assigned-clocks"].to_nums()) + assigned_clock_rates = node.props["assigned-clock-rates"].to_nums() + for clk_id, clk_rate in zip(assigned_clocks, assigned_clock_rates): + if (clk_rate): + add_clock(clk_id, clk_rate, 0) + for pnode in pnodes: + extract_clocks(dt, pnode) + + if "assigned-clocks" in props and "assigned-clock-parents" in props: + assigned_clocks, pnodes = parse_clock_list(devicetree, node.props["assigned-clocks"].to_nums()) + assigned_clock_parents, ppnodes = parse_clock_list(devicetree, node.props["assigned-clock-parents"].to_nums()) + for clk_id, pclk_id in zip(assigned_clocks, assigned_clock_parents): + if (pclk_id): + add_clock(clk_id, 0, pclk_id) + for pnode in pnodes: + extract_clocks(dt, pnode) + for pnode in ppnodes: + extract_clocks(dt, pnode) + + return enabled_clks + +def write_configs_to_headerfile(path: str) -> None: + with open(path + '/clk_config.h', "w") as f: + f.write("#include \n") + f.write("#define NUM_DEVICE_CLKS {}\n\n".format(len(clock_list))) + + clk_cfg_strs = [] + for key, value in clock_list.items(): + clk_cfg_strs.append(" {{ .clk_id = {}, .frequency = {}, .pclk_id = {} }}".format(key, value[0], value[1])) + + f.write("static struct clk_cfg clk_configs[] = {{\n{}\n}};".format(",\n".join(clk_cfg_strs))) + +if __name__ == "__main__": + devicetree = dtlib.DT(sys.argv[1], force=True) + for compat_str in devicetree.root.props["compatible"].to_strings(): + if compat_str in supported_compat_str_board: + supported = True + break + + if not supported: + log_error_parser("this board is not supported.") + exit(1) + + enabled_clks = [] + + for node in devicetree.node_iter(): + props = list(node.props.keys()) + if "status" in props: + status = node.props["status"].to_string() + if status == "okay": + extract_clocks(devicetree, node) + + write_configs_to_headerfile(sys.argv[2]) + + print('Initial clock configuration has been saved in ' + sys.argv[2] + '/clk_config.h') diff --git a/drivers/clk/meson/include/clk-measure.h b/drivers/clk/meson/include/clk-measure.h new file mode 100644 index 000000000..7de22a6b1 --- /dev/null +++ b/drivers/clk/meson/include/clk-measure.h @@ -0,0 +1,9 @@ +/* + * Copyright 2024, UNSW + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +const char *const *get_msr_clk_list(void); +unsigned long clk_msr(unsigned long clk_mux); diff --git a/drivers/clk/meson/include/clk-meson.h b/drivers/clk/meson/include/clk-meson.h new file mode 100644 index 000000000..aa06e1397 --- /dev/null +++ b/drivers/clk/meson/include/clk-meson.h @@ -0,0 +1,175 @@ +#pragma once + +#include + +#define CLK_MESON_MPLL_ROUND_CLOSEST BIT(0) +#define CLK_MESON_MPLL_SPREAD_SPECTRUM BIT(1) + +#define CLK_MESON_PLL_ROUND_CLOSEST BIT(0) +#define CLK_MESON_PLL_NOINIT_ENABLED BIT(1) + +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2015 Endless Mobile, Inc. + * Author: Carlo Caione + * + * Derived from: https://github.com/torvalds/linux/blob/6485cf5ea253d40d507cd71253c9568c5470cd27/drivers/clk/meson/parm.h + */ +/** + * struct parm - struct defines bits of a clock control field in registers + * + * @reg_off: offset of the register + * @shift: shift of the control field + * @width: width of the control field + * + * Register/value pairs for sequences of writes with an optional delay in + * microseconds to be applied after each write. + */ +struct parm { + uint16_t reg_off; + uint8_t shift; + uint8_t width; +}; + +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright 2011 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * Derived from: https://github.com/torvalds/linux/blob/6485cf5ea253d40d507cd71253c9568c5470cd27/include/linux/regmap.h + */ +/** + * struct reg_sequence - An individual write from a sequence of writes. + * + * @reg: Register address. + * @def: Register value. + * @delay_us: Delay to be applied after the register write in microseconds + */ +struct reg_sequence { + unsigned int reg; + unsigned int def; + unsigned int delay_us; +}; + +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2019 BayLibre, SAS. + * Author: Jerome Brunet + */ +/** + * struct reg_sequence - An individual write from a sequence of writes. + * + * @m: Register address. + * @n: Register value. + * @delay_us: Delay to be applied after the register write in microseconds + * + * Register/value pairs for sequences of writes with an optional delay in + * microseconds to be applied after each write. + */ +struct pll_params_table { + unsigned int m; + unsigned int n; +}; + +struct meson_clk_cpu_dyndiv_data { + struct parm div; + struct parm dyn; +}; + +struct meson_clk_pll_data { + struct parm en; + struct parm m; + struct parm n; + struct parm frac; + struct parm l; + struct parm rst; + struct parm current_en; + struct parm l_detect; + const struct reg_sequence *init_regs; + unsigned int init_count; + const struct pll_params_table *table; + /* const struct pll_mult_range *range; */ + uint8_t range_min; + uint8_t range_max; + uint8_t flags; +}; + +struct meson_clk_mpll_data { + struct parm sdm; + struct parm sdm_en; + struct parm n2; + struct parm ssen; + struct parm misc; + const struct reg_sequence *init_regs; + unsigned int init_count; + /* spinlock_t *lock; */ + uint8_t flags; +}; + +struct meson_vid_pll_div_data { + struct parm val; + struct parm sel; +}; + +struct meson_vclk_gate_data { + struct parm enable; + struct parm reset; + uint8_t flags; +}; + +struct meson_vclk_div_data { + struct parm div; + struct parm enable; + struct parm reset; + const struct clk_div_table *table; + uint8_t flags; +}; + +extern const struct clk_ops meson_clk_pll_ops; +extern const struct clk_ops meson_clk_pll_ro_ops; +extern const struct clk_ops meson_clk_mpll_ops; +extern const struct clk_ops meson_clk_pcie_pll_ops; +extern const struct clk_ops meson_vid_pll_div_ro_ops; +extern const struct clk_ops meson_vclk_gate_ops; +extern const struct clk_ops meson_vclk_div_ops; +extern const struct clk_ops meson_clk_cpu_dyndiv_ops; + +#define MESON_CLK81_GATE(_name, _reg, _bit) \ +struct clk _name = { \ + .data = &(struct clk_gate_data) { \ + .offset = (_reg), \ + .bit_idx = (_bit), \ + .flags = 0, \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_gate_ops, \ + .parent_clks = (const struct clk *[]) { \ + &g12a_clk81, \ + }, \ + .num_parents = 1, \ + .flags = 0, \ + }, \ +} + +#define MESON_CLK81_GATE_RO(_name, _reg, _bit) \ +struct clk _name = { \ + .data = &(struct clk_gate_data) { \ + .offset = (_reg), \ + .bit_idx = (_bit), \ + .flags = 0, \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_gate_ro_ops, \ + .parent_clks = (const struct clk *[]) { \ + &g12a_clk81, \ + }, \ + .num_parents = 1, \ + .flags = 0, \ + }, \ +} + +extern const struct clk g12a_xtal; +struct clk **get_clk_list(void); diff --git a/drivers/clk/meson/include/g12a-bindings.h b/drivers/clk/meson/include/g12a-bindings.h new file mode 100644 index 000000000..c817acdf1 --- /dev/null +++ b/drivers/clk/meson/include/g12a-bindings.h @@ -0,0 +1,293 @@ +/* SPDX-License-Identifier: GPL-2.0+ OR MIT */ +/* + * Meson-G12A clock tree IDs + * + * Copyright (c) 2018 Amlogic, Inc. All rights reserved. + * + * Source: https://github.com/torvalds/linux/blob/20371ba120635d9ab7fc7670497105af8f33eb08/include/dt-bindings/clock/g12a-clkc.h + */ + +#ifndef __G12A_CLKC_H +#define __G12A_CLKC_H + +#define CLKID_SYS_PLL 0 +#define CLKID_FIXED_PLL 1 +#define CLKID_FCLK_DIV2 2 +#define CLKID_FCLK_DIV3 3 +#define CLKID_FCLK_DIV4 4 +#define CLKID_FCLK_DIV5 5 +#define CLKID_FCLK_DIV7 6 +#define CLKID_GP0_PLL 7 +#define CLKID_MPEG_SEL 8 +#define CLKID_MPEG_DIV 9 +#define CLKID_CLK81 10 +#define CLKID_MPLL0 11 +#define CLKID_MPLL1 12 +#define CLKID_MPLL2 13 +#define CLKID_MPLL3 14 +#define CLKID_DDR 15 +#define CLKID_DOS 16 +#define CLKID_AUDIO_LOCKER 17 +#define CLKID_MIPI_DSI_HOST 18 +#define CLKID_ETH_PHY 19 +#define CLKID_ISA 20 +#define CLKID_PL301 21 +#define CLKID_PERIPHS 22 +#define CLKID_SPICC0 23 +#define CLKID_I2C 24 +#define CLKID_SANA 25 +#define CLKID_SD 26 +#define CLKID_RNG0 27 +#define CLKID_UART0 28 +#define CLKID_SPICC1 29 +#define CLKID_HIU_IFACE 30 +#define CLKID_MIPI_DSI_PHY 31 +#define CLKID_ASSIST_MISC 32 +#define CLKID_SD_EMMC_A 33 +#define CLKID_SD_EMMC_B 34 +#define CLKID_SD_EMMC_C 35 +#define CLKID_AUDIO_CODEC 36 +#define CLKID_AUDIO 37 +#define CLKID_ETH 38 +#define CLKID_DEMUX 39 +#define CLKID_AUDIO_IFIFO 40 +#define CLKID_ADC 41 +#define CLKID_UART1 42 +#define CLKID_G2D 43 +#define CLKID_RESET 44 +#define CLKID_PCIE_COMB 45 +#define CLKID_PARSER 46 +#define CLKID_USB 47 +#define CLKID_PCIE_PHY 48 +#define CLKID_AHB_ARB0 49 +#define CLKID_AHB_DATA_BUS 50 +#define CLKID_AHB_CTRL_BUS 51 +#define CLKID_HTX_HDCP22 52 +#define CLKID_HTX_PCLK 53 +#define CLKID_BT656 54 +#define CLKID_USB1_DDR_BRIDGE 55 +#define CLKID_MMC_PCLK 56 +#define CLKID_UART2 57 +#define CLKID_VPU_INTR 58 +#define CLKID_GIC 59 +#define CLKID_SD_EMMC_A_CLK0 60 +#define CLKID_SD_EMMC_B_CLK0 61 +#define CLKID_SD_EMMC_C_CLK0 62 +#define CLKID_SD_EMMC_A_CLK0_SEL 63 +#define CLKID_SD_EMMC_A_CLK0_DIV 64 +#define CLKID_SD_EMMC_B_CLK0_SEL 65 +#define CLKID_SD_EMMC_B_CLK0_DIV 66 +#define CLKID_SD_EMMC_C_CLK0_SEL 67 +#define CLKID_SD_EMMC_C_CLK0_DIV 68 +#define CLKID_MPLL0_DIV 69 +#define CLKID_MPLL1_DIV 70 +#define CLKID_MPLL2_DIV 71 +#define CLKID_MPLL3_DIV 72 +#define CLKID_MPLL_PREDIV 73 +#define CLKID_HIFI_PLL 74 +#define CLKID_FCLK_DIV2_DIV 75 +#define CLKID_FCLK_DIV3_DIV 76 +#define CLKID_FCLK_DIV4_DIV 77 +#define CLKID_FCLK_DIV5_DIV 78 +#define CLKID_FCLK_DIV7_DIV 79 +#define CLKID_VCLK2_VENCI0 80 +#define CLKID_VCLK2_VENCI1 81 +#define CLKID_VCLK2_VENCP0 82 +#define CLKID_VCLK2_VENCP1 83 +#define CLKID_VCLK2_VENCT0 84 +#define CLKID_VCLK2_VENCT1 85 +#define CLKID_VCLK2_OTHER 86 +#define CLKID_VCLK2_ENCI 87 +#define CLKID_VCLK2_ENCP 88 +#define CLKID_DAC_CLK 89 +#define CLKID_AOCLK 90 +#define CLKID_IEC958 91 +#define CLKID_ENC480P 92 +#define CLKID_RNG1 93 +#define CLKID_VCLK2_ENCT 94 +#define CLKID_VCLK2_ENCL 95 +#define CLKID_VCLK2_VENCLMMC 96 +#define CLKID_VCLK2_VENCL 97 +#define CLKID_VCLK2_OTHER1 98 +#define CLKID_FCLK_DIV2P5 99 +#define CLKID_FCLK_DIV2P5_DIV 100 +#define CLKID_FIXED_PLL_DCO 101 +#define CLKID_SYS_PLL_DCO 102 +#define CLKID_GP0_PLL_DCO 103 +#define CLKID_HIFI_PLL_DCO 104 +#define CLKID_DMA 105 +#define CLKID_EFUSE 106 +#define CLKID_ROM_BOOT 107 +#define CLKID_RESET_SEC 108 +#define CLKID_SEC_AHB_APB3 109 +#define CLKID_VPU_0_SEL 110 +#define CLKID_VPU_0_DIV 111 +#define CLKID_VPU_0 112 +#define CLKID_VPU_1_SEL 113 +#define CLKID_VPU_1_DIV 114 +#define CLKID_VPU_1 115 +#define CLKID_VPU 116 +#define CLKID_VAPB_0_SEL 117 +#define CLKID_VAPB_0_DIV 118 +#define CLKID_VAPB_0 119 +#define CLKID_VAPB_1_SEL 120 +#define CLKID_VAPB_1_DIV 121 +#define CLKID_VAPB_1 122 +#define CLKID_VAPB_SEL 123 +#define CLKID_VAPB 124 +#define CLKID_HDMI_PLL_DCO 125 +#define CLKID_HDMI_PLL_OD 126 +#define CLKID_HDMI_PLL_OD2 127 +#define CLKID_HDMI_PLL 128 +#define CLKID_VID_PLL 129 +#define CLKID_VID_PLL_SEL 130 +#define CLKID_VID_PLL_DIV 131 +#define CLKID_VCLK_SEL 132 +#define CLKID_VCLK2_SEL 133 +#define CLKID_VCLK_INPUT 134 +#define CLKID_VCLK2_INPUT 135 +#define CLKID_VCLK_DIV 136 +#define CLKID_VCLK2_DIV 137 +#define CLKID_VCLK 138 +#define CLKID_VCLK2 139 +#define CLKID_VCLK_DIV2_EN 140 +#define CLKID_VCLK_DIV4_EN 141 +#define CLKID_VCLK_DIV6_EN 142 +#define CLKID_VCLK_DIV12_EN 143 +#define CLKID_VCLK2_DIV2_EN 144 +#define CLKID_VCLK2_DIV4_EN 145 +#define CLKID_VCLK2_DIV6_EN 146 +#define CLKID_VCLK2_DIV12_EN 147 +#define CLKID_VCLK_DIV1 148 +#define CLKID_VCLK_DIV2 149 +#define CLKID_VCLK_DIV4 150 +#define CLKID_VCLK_DIV6 151 +#define CLKID_VCLK_DIV12 152 +#define CLKID_VCLK2_DIV1 153 +#define CLKID_VCLK2_DIV2 154 +#define CLKID_VCLK2_DIV4 155 +#define CLKID_VCLK2_DIV6 156 +#define CLKID_VCLK2_DIV12 157 +#define CLKID_CTS_ENCI_SEL 158 +#define CLKID_CTS_ENCP_SEL 159 +#define CLKID_CTS_VDAC_SEL 160 +#define CLKID_HDMI_TX_SEL 161 +#define CLKID_CTS_ENCI 162 +#define CLKID_CTS_ENCP 163 +#define CLKID_CTS_VDAC 164 +#define CLKID_HDMI_TX 165 +#define CLKID_HDMI_SEL 166 +#define CLKID_HDMI_DIV 167 +#define CLKID_HDMI 168 +#define CLKID_MALI_0_SEL 169 +#define CLKID_MALI_0_DIV 170 +#define CLKID_MALI_0 171 +#define CLKID_MALI_1_SEL 172 +#define CLKID_MALI_1_DIV 173 +#define CLKID_MALI_1 174 +#define CLKID_MALI 175 +#define CLKID_MPLL_50M_DIV 176 +#define CLKID_MPLL_50M 177 +#define CLKID_SYS_PLL_DIV16_EN 178 +#define CLKID_SYS_PLL_DIV16 179 +#define CLKID_CPU_CLK_DYN0_SEL 180 +#define CLKID_CPU_CLK_DYN0_DIV 181 +#define CLKID_CPU_CLK_DYN0 182 +#define CLKID_CPU_CLK_DYN1_SEL 183 +#define CLKID_CPU_CLK_DYN1_DIV 184 +#define CLKID_CPU_CLK_DYN1 185 +#define CLKID_CPU_CLK_DYN 186 +#define CLKID_CPU_CLK 187 +#define CLKID_CPU_CLK_DIV16_EN 188 +#define CLKID_CPU_CLK_DIV16 189 +#define CLKID_CPU_CLK_APB_DIV 190 +#define CLKID_CPU_CLK_APB 191 +#define CLKID_CPU_CLK_ATB_DIV 192 +#define CLKID_CPU_CLK_ATB 193 +#define CLKID_CPU_CLK_AXI_DIV 194 +#define CLKID_CPU_CLK_AXI 195 +#define CLKID_CPU_CLK_TRACE_DIV 196 +#define CLKID_CPU_CLK_TRACE 197 +#define CLKID_PCIE_PLL_DCO 198 +#define CLKID_PCIE_PLL_DCO_DIV2 199 +#define CLKID_PCIE_PLL_OD 200 +#define CLKID_PCIE_PLL 201 +#define CLKID_VDEC_1_SEL 202 +#define CLKID_VDEC_1_DIV 203 +#define CLKID_VDEC_1 204 +#define CLKID_VDEC_HEVC_SEL 205 +#define CLKID_VDEC_HEVC_DIV 206 +#define CLKID_VDEC_HEVC 207 +#define CLKID_VDEC_HEVCF_SEL 208 +#define CLKID_VDEC_HEVCF_DIV 209 +#define CLKID_VDEC_HEVCF 210 +#define CLKID_TS_DIV 211 +#define CLKID_TS 212 +#define CLKID_SYS1_PLL_DCO 213 +#define CLKID_SYS1_PLL 214 +#define CLKID_SYS1_PLL_DIV16_EN 215 +#define CLKID_SYS1_PLL_DIV16 216 +#define CLKID_CPUB_CLK_DYN0_SEL 217 +#define CLKID_CPUB_CLK_DYN0_DIV 218 +#define CLKID_CPUB_CLK_DYN0 219 +#define CLKID_CPUB_CLK_DYN1_SEL 220 +#define CLKID_CPUB_CLK_DYN1_DIV 221 +#define CLKID_CPUB_CLK_DYN1 222 +#define CLKID_CPUB_CLK_DYN 223 +#define CLKID_CPUB_CLK 224 +#define CLKID_CPUB_CLK_DIV16_EN 225 +#define CLKID_CPUB_CLK_DIV16 226 +#define CLKID_CPUB_CLK_DIV2 227 +#define CLKID_CPUB_CLK_DIV3 228 +#define CLKID_CPUB_CLK_DIV4 229 +#define CLKID_CPUB_CLK_DIV5 230 +#define CLKID_CPUB_CLK_DIV6 231 +#define CLKID_CPUB_CLK_DIV7 232 +#define CLKID_CPUB_CLK_DIV8 233 +#define CLKID_CPUB_CLK_APB_SEL 234 +#define CLKID_CPUB_CLK_APB 235 +#define CLKID_CPUB_CLK_ATB_SEL 236 +#define CLKID_CPUB_CLK_ATB 237 +#define CLKID_CPUB_CLK_AXI_SEL 238 +#define CLKID_CPUB_CLK_AXI 239 +#define CLKID_CPUB_CLK_TRACE_SEL 240 +#define CLKID_CPUB_CLK_TRACE 241 +#define CLKID_GP1_PLL_DCO 242 +#define CLKID_GP1_PLL 243 +#define CLKID_DSU_CLK_DYN0_SEL 244 +#define CLKID_DSU_CLK_DYN0_DIV 245 +#define CLKID_DSU_CLK_DYN0 246 +#define CLKID_DSU_CLK_DYN1_SEL 247 +#define CLKID_DSU_CLK_DYN1_DIV 248 +#define CLKID_DSU_CLK_DYN1 249 +#define CLKID_DSU_CLK_DYN 250 +#define CLKID_DSU_CLK_FINAL 251 +#define CLKID_DSU_CLK 252 +#define CLKID_CPU1_CLK 253 +#define CLKID_CPU2_CLK 254 +#define CLKID_CPU3_CLK 255 +#define CLKID_SPICC0_SCLK_SEL 256 +#define CLKID_SPICC0_SCLK_DIV 257 +#define CLKID_SPICC0_SCLK 258 +#define CLKID_SPICC1_SCLK_SEL 259 +#define CLKID_SPICC1_SCLK_DIV 260 +#define CLKID_SPICC1_SCLK 261 +#define CLKID_NNA_AXI_CLK_SEL 262 +#define CLKID_NNA_AXI_CLK_DIV 263 +#define CLKID_NNA_AXI_CLK 264 +#define CLKID_NNA_CORE_CLK_SEL 265 +#define CLKID_NNA_CORE_CLK_DIV 266 +#define CLKID_NNA_CORE_CLK 267 +#define CLKID_MIPI_DSI_PXCLK_DIV 268 +#define CLKID_MIPI_DSI_PXCLK_SEL 269 +#define CLKID_MIPI_DSI_PXCLK 270 +#define CLKID_CTS_ENCL 271 +#define CLKID_CTS_ENCL_SEL 272 +#define CLKID_MIPI_ISP_DIV 273 +#define CLKID_MIPI_ISP_SEL 274 +#define CLKID_MIPI_ISP 275 +#define CLKID_MIPI_ISP_GATE 276 +#define CLKID_MIPI_ISP_CSI_PHY0 277 +#define CLKID_MIPI_ISP_CSI_PHY1 278 + +#endif /* __G12A_CLKC_H */ diff --git a/drivers/clk/meson/include/g12a-regs.h b/drivers/clk/meson/include/g12a-regs.h new file mode 100644 index 000000000..1c587583d --- /dev/null +++ b/drivers/clk/meson/include/g12a-regs.h @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2016 Amlogic, Inc. + * Author: Michael Turquette + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + * Author: Jian Hu + * + * Source: https://github.com/torvalds/linux/blob/20371ba120635d9ab7fc7670497105af8f33eb08/drivers/clk/meson/g12a.h + */ +#ifndef __G12A_H +#define __G12A_H + +/* + * Clock controller register offsets + * + * Register offsets from the data sheet must be multiplied by 4 before + * adding them to the base address to get the right value. + */ +#define HHI_MIPI_CNTL0 0x000 +#define HHI_MIPI_CNTL1 0x004 +#define HHI_MIPI_CNTL2 0x008 +#define HHI_MIPI_STS 0x00C +#define HHI_GP0_PLL_CNTL0 0x040 +#define HHI_GP0_PLL_CNTL1 0x044 +#define HHI_GP0_PLL_CNTL2 0x048 +#define HHI_GP0_PLL_CNTL3 0x04C +#define HHI_GP0_PLL_CNTL4 0x050 +#define HHI_GP0_PLL_CNTL5 0x054 +#define HHI_GP0_PLL_CNTL6 0x058 +#define HHI_GP0_PLL_STS 0x05C +#define HHI_GP1_PLL_CNTL0 0x060 +#define HHI_GP1_PLL_CNTL1 0x064 +#define HHI_GP1_PLL_CNTL2 0x068 +#define HHI_GP1_PLL_CNTL3 0x06C +#define HHI_GP1_PLL_CNTL4 0x070 +#define HHI_GP1_PLL_CNTL5 0x074 +#define HHI_GP1_PLL_CNTL6 0x078 +#define HHI_GP1_PLL_STS 0x07C +#define HHI_PCIE_PLL_CNTL0 0x098 +#define HHI_PCIE_PLL_CNTL1 0x09C +#define HHI_PCIE_PLL_CNTL2 0x0A0 +#define HHI_PCIE_PLL_CNTL3 0x0A4 +#define HHI_PCIE_PLL_CNTL4 0x0A8 +#define HHI_PCIE_PLL_CNTL5 0x0AC +#define HHI_PCIE_PLL_STS 0x0B8 +#define HHI_HIFI_PLL_CNTL0 0x0D8 +#define HHI_HIFI_PLL_CNTL1 0x0DC +#define HHI_HIFI_PLL_CNTL2 0x0E0 +#define HHI_HIFI_PLL_CNTL3 0x0E4 +#define HHI_HIFI_PLL_CNTL4 0x0E8 +#define HHI_HIFI_PLL_CNTL5 0x0EC +#define HHI_HIFI_PLL_CNTL6 0x0F0 +#define HHI_VIID_CLK_DIV 0x128 +#define HHI_VIID_CLK_CNTL 0x12C +#define HHI_GCLK_MPEG0 0x140 +#define HHI_GCLK_MPEG1 0x144 +#define HHI_GCLK_MPEG2 0x148 +#define HHI_GCLK_OTHER 0x150 +#define HHI_GCLK_OTHER2 0x154 +#define HHI_SYS_CPU_CLK_CNTL1 0x15c +#define HHI_VID_CLK_DIV 0x164 +#define HHI_MPEG_CLK_CNTL 0x174 +#define HHI_AUD_CLK_CNTL 0x178 +#define HHI_VID_CLK_CNTL 0x17c +#define HHI_TS_CLK_CNTL 0x190 +#define HHI_VID_CLK_CNTL2 0x194 +#define HHI_SYS_CPU_CLK_CNTL0 0x19c +#define HHI_VID_PLL_CLK_DIV 0x1A0 +#define HHI_MALI_CLK_CNTL 0x1b0 +#define HHI_VPU_CLKC_CNTL 0x1b4 +#define HHI_VPU_CLK_CNTL 0x1bC +#define HHI_ISP_CLK_CNTL 0x1C0 +#define HHI_NNA_CLK_CNTL 0x1C8 +#define HHI_HDMI_CLK_CNTL 0x1CC +#define HHI_VDEC_CLK_CNTL 0x1E0 +#define HHI_VDEC2_CLK_CNTL 0x1E4 +#define HHI_VDEC3_CLK_CNTL 0x1E8 +#define HHI_VDEC4_CLK_CNTL 0x1EC +#define HHI_HDCP22_CLK_CNTL 0x1F0 +#define HHI_VAPBCLK_CNTL 0x1F4 +#define HHI_SYS_CPUB_CLK_CNTL1 0x200 +#define HHI_SYS_CPUB_CLK_CNTL 0x208 +#define HHI_VPU_CLKB_CNTL 0x20C +#define HHI_SYS_CPU_CLK_CNTL2 0x210 +#define HHI_SYS_CPU_CLK_CNTL3 0x214 +#define HHI_SYS_CPU_CLK_CNTL4 0x218 +#define HHI_SYS_CPU_CLK_CNTL5 0x21c +#define HHI_SYS_CPU_CLK_CNTL6 0x220 +#define HHI_GEN_CLK_CNTL 0x228 +#define HHI_VDIN_MEAS_CLK_CNTL 0x250 +#define HHI_MIPIDSI_PHY_CLK_CNTL 0x254 +#define HHI_NAND_CLK_CNTL 0x25C +#define HHI_SD_EMMC_CLK_CNTL 0x264 +#define HHI_MPLL_CNTL0 0x278 +#define HHI_MPLL_CNTL1 0x27C +#define HHI_MPLL_CNTL2 0x280 +#define HHI_MPLL_CNTL3 0x284 +#define HHI_MPLL_CNTL4 0x288 +#define HHI_MPLL_CNTL5 0x28c +#define HHI_MPLL_CNTL6 0x290 +#define HHI_MPLL_CNTL7 0x294 +#define HHI_MPLL_CNTL8 0x298 +#define HHI_FIX_PLL_CNTL0 0x2A0 +#define HHI_FIX_PLL_CNTL1 0x2A4 +#define HHI_FIX_PLL_CNTL3 0x2AC +#define HHI_SYS_PLL_CNTL0 0x2f4 +#define HHI_SYS_PLL_CNTL1 0x2f8 +#define HHI_SYS_PLL_CNTL2 0x2fc +#define HHI_SYS_PLL_CNTL3 0x300 +#define HHI_SYS_PLL_CNTL4 0x304 +#define HHI_SYS_PLL_CNTL5 0x308 +#define HHI_SYS_PLL_CNTL6 0x30c +#define HHI_HDMI_PLL_CNTL0 0x320 +#define HHI_HDMI_PLL_CNTL1 0x324 +#define HHI_HDMI_PLL_CNTL2 0x328 +#define HHI_HDMI_PLL_CNTL3 0x32c +#define HHI_HDMI_PLL_CNTL4 0x330 +#define HHI_HDMI_PLL_CNTL5 0x334 +#define HHI_HDMI_PLL_CNTL6 0x338 +#define HHI_SPICC_CLK_CNTL 0x3dc +#define HHI_SYS1_PLL_CNTL0 0x380 +#define HHI_SYS1_PLL_CNTL1 0x384 +#define HHI_SYS1_PLL_CNTL2 0x388 +#define HHI_SYS1_PLL_CNTL3 0x38c +#define HHI_SYS1_PLL_CNTL4 0x390 +#define HHI_SYS1_PLL_CNTL5 0x394 +#define HHI_SYS1_PLL_CNTL6 0x398 + +#endif /* __G12A_H */ diff --git a/drivers/clk/meson/sm1-clk.c b/drivers/clk/meson/sm1-clk.c new file mode 100644 index 000000000..ae980b50f --- /dev/null +++ b/drivers/clk/meson/sm1-clk.c @@ -0,0 +1,1533 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Amlogic Meson-G12A Clock Controller Driver + * + * Copyright (c) 2016 Baylibre SAS. + * Author: Michael Turquette + * + * Copyright (c) 2018 Amlogic, inc. + * Author: Qiufang Dai + * Author: Jian Hu + * + * Derived from: https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/g12a.c + */ + +#include +#include +#include +#include +#include +#include +#include + +const struct clk g12a_xtal = { .data = + &(struct clk_source_data) { + .rate = 24000000, + }, + .hw.init = &(struct clk_init_data) { + .name = "xtal", + .ops = &clk_source_ops, + } }; + +static struct clk g12a_fixed_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_FIX_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_FIX_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_FIX_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_FIX_PLL_CNTL1, + .shift = 0, + .width = 17, + }, + .l = { + .reg_off = HHI_FIX_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_FIX_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll_dco", + .ops = &meson_clk_pll_ro_ops, + .parent_data = &(const struct clk_parent_data) { + .name = "xtal", + }, + .num_parents = 1, + }, +}; +static CLK_DIV_RO(g12a_fixed_pll, HHI_FIX_PLL_CNTL0, 16, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_fixed_pll_dco }, 1, 0); +static struct clk g12a_sys_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_SYS_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_SYS_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_SYS_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .l = { + .reg_off = HHI_SYS_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_SYS_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + .range_min = 128, + .range_max = 250, + }, + .hw.init = &(struct clk_init_data){ + .name = "sys_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .name = "xtal", + }, + .num_parents = 1, + /* This clock feeds the CPU, avoid disabling it */ + .flags = CLK_IS_CRITICAL, + }, +}; +static CLK_DIV(g12a_sys_pll, HHI_SYS_PLL_CNTL0, 16, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_sys_pll_dco }, 1, 0); +static CLK_GATE_RO(g12a_sys_pll_div16_en, HHI_SYS_CPU_CLK_CNTL1, 24, 0, { &g12a_sys_pll }, 1, 0); +static CLK_FIXED_FACTOR(g12a_sys_pll_div16, 1, 16, 0, { &g12a_sys_pll_div16_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_fclk_div2_div, 1, 2, 0, { &g12a_fixed_pll }, 1, 0); +static CLK_GATE(g12a_fclk_div2, HHI_FIX_PLL_CNTL1, 24, 0, { &g12a_fclk_div2_div }, 1, 0); +static CLK_FIXED_FACTOR(g12a_fclk_div3_div, 1, 3, 0, { &g12a_fixed_pll }, 1, 0); +static CLK_GATE(g12a_fclk_div3, HHI_FIX_PLL_CNTL1, 20, 0, { &g12a_fclk_div3_div }, 1, 0); +const struct clk_parent_data g12a_cpu_clk_premux0_parent_table[] = { + { + .name = "xtal", + }, + { .clk = &g12a_fclk_div2 }, + { .clk = &g12a_fclk_div3 }, +}; +static CLK_MUX(g12a_cpu_clk_premux0, HHI_SYS_CPU_CLK_CNTL0, 0x3, 0, 0, CLK_MUX_ROUND_CLOSEST, + g12a_cpu_clk_premux0_parent_table, 3, 0); +const struct clk_parent_data g12a_cpu_clk_premux1_parent_table[] = { + { + .name = "xtal", + }, + { .clk = &g12a_fclk_div2 }, + { .clk = &g12a_fclk_div3 }, +}; +static CLK_MUX(g12a_cpu_clk_premux1, HHI_SYS_CPU_CLK_CNTL0, 0x3, 16, 0, 0, g12a_cpu_clk_premux1_parent_table, 3, 0); +static struct clk g12a_cpu_clk_mux0_div = { + .data = &(struct meson_clk_cpu_dyndiv_data){ + .div = { + .reg_off = HHI_SYS_CPU_CLK_CNTL0, + .shift = 4, + .width = 6, + }, + .dyn = { + .reg_off = HHI_SYS_CPU_CLK_CNTL0, + .shift = 26, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "cpu_clk_dyn0_div", + .ops = &meson_clk_cpu_dyndiv_ops, + .parent_clks = (const struct clk *[]) { + &g12a_cpu_clk_premux0 + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; +const struct clk_parent_data g12a_cpu_clk_postmux0_parent_table[] = { + { .clk = &g12a_cpu_clk_premux0 }, + { .clk = &g12a_cpu_clk_mux0_div }, +}; +static CLK_MUX(g12a_cpu_clk_postmux0, HHI_SYS_CPU_CLK_CNTL0, 0x1, 2, 0, CLK_MUX_ROUND_CLOSEST, + g12a_cpu_clk_postmux0_parent_table, 2, 0); +static CLK_DIV_RO(g12a_cpu_clk_mux1_div, HHI_SYS_CPU_CLK_CNTL0, 20, 6, 0, { &g12a_cpu_clk_premux1 }, 1, 0); +const struct clk_parent_data g12a_cpu_clk_postmux1_parent_table[] = { + { .clk = &g12a_cpu_clk_premux1 }, + { .clk = &g12a_cpu_clk_mux1_div }, +}; +static CLK_MUX(g12a_cpu_clk_postmux1, HHI_SYS_CPU_CLK_CNTL0, 0x1, 18, 0, 0, g12a_cpu_clk_postmux1_parent_table, 2, 0); +const struct clk_parent_data g12a_cpu_clk_dyn_parent_table[] = { + { .clk = &g12a_cpu_clk_postmux0 }, + { .clk = &g12a_cpu_clk_postmux1 }, +}; +static CLK_MUX(g12a_cpu_clk_dyn, HHI_SYS_CPU_CLK_CNTL0, 0x1, 10, 0, CLK_MUX_ROUND_CLOSEST, + g12a_cpu_clk_dyn_parent_table, 2, 0); +const struct clk_parent_data g12a_cpu_clk_parent_table[] = { + { .clk = &g12a_cpu_clk_dyn }, + { .clk = &g12a_sys_pll }, +}; +static CLK_MUX(g12a_cpu_clk, HHI_SYS_CPU_CLK_CNTL0, 0x1, 11, 0, CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_parent_table, 2, 0); + +static const struct reg_sequence g12a_gp0_init_regs[] = { + { .reg = HHI_GP0_PLL_CNTL1, .def = 0x00000000 }, { .reg = HHI_GP0_PLL_CNTL2, .def = 0x00000000 }, + { .reg = HHI_GP0_PLL_CNTL3, .def = 0x48681c00 }, { .reg = HHI_GP0_PLL_CNTL4, .def = 0x33771290 }, + { .reg = HHI_GP0_PLL_CNTL5, .def = 0x39272000 }, { .reg = HHI_GP0_PLL_CNTL6, .def = 0x56540000 }, +}; +static struct clk g12a_gp0_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_GP0_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_GP0_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_GP0_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_GP0_PLL_CNTL1, + .shift = 0, + .width = 17, + }, + .l = { + .reg_off = HHI_GP0_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_GP0_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + .range_min = 125, + .range_max = 255, + .init_regs = g12a_gp0_init_regs, + .init_count = ARRAY_SIZE(g12a_gp0_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .name = "xtal", + }, + .num_parents = 1, + }, +}; +static CLK_DIV(g12a_gp0_pll, HHI_GP0_PLL_CNTL0, 16, 3, (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), + { &g12a_gp0_pll_dco }, 1, 0); +static struct clk sm1_gp1_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_GP1_PLL_CNTL1, + .shift = 0, + .width = 17, + }, + .l = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_GP1_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "gp1_pll_dco", + .ops = &meson_clk_pll_ro_ops, + .parent_data = &(const struct clk_parent_data) { + .name = "xtal", + }, + .num_parents = 1, + /* This clock feeds the DSU, avoid disabling it */ + .flags = CLK_IS_CRITICAL, + }, +}; +static CLK_DIV_RO(sm1_gp1_pll, HHI_GP1_PLL_CNTL0, 16, 3, (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), + { &sm1_gp1_pll_dco }, 1, 0); + +const struct clk_parent_data sm1_dsu_clk_premux0_parent_table[] = { + { + .name = "xtal", + }, + { .clk = &g12a_fclk_div2 }, + { .clk = &g12a_fclk_div3 }, + { .clk = &sm1_gp1_pll }, +}; +static CLK_MUX_RO(sm1_dsu_clk_premux0, HHI_SYS_CPU_CLK_CNTL5, 0x3, 0, 0, 0, sm1_dsu_clk_premux0_parent_table, 4, 0); +const struct clk_parent_data sm1_dsu_clk_premux1_parent_table[] = { + { + .name = "xtal", + }, + { .clk = &g12a_fclk_div2 }, + { .clk = &g12a_fclk_div3 }, + { .clk = &sm1_gp1_pll }, +}; +static CLK_MUX_RO(sm1_dsu_clk_premux1, HHI_SYS_CPU_CLK_CNTL5, 0x3, 16, 0, 0, sm1_dsu_clk_premux1_parent_table, 4, 0); +static CLK_DIV_RO(sm1_dsu_clk_mux0_div, HHI_SYS_CPU_CLK_CNTL5, 4, 6, 0, { &sm1_dsu_clk_premux0 }, 1, 0); +const struct clk_parent_data sm1_dsu_clk_postmux0_parent_table[] = { + { + .clk = &sm1_dsu_clk_premux0, + }, + { .clk = &sm1_dsu_clk_mux0_div }, +}; +static CLK_MUX_RO(sm1_dsu_clk_postmux0, HHI_SYS_CPU_CLK_CNTL5, 0x1, 2, 0, 0, sm1_dsu_clk_postmux0_parent_table, 2, 0); +static CLK_DIV_RO(sm1_dsu_clk_mux1_div, HHI_SYS_CPU_CLK_CNTL5, 20, 6, 0, { &sm1_dsu_clk_premux1 }, 1, 0); + +const struct clk_parent_data sm1_dsu_clk_postmux1_parent_table[] = { + { + .clk = &sm1_dsu_clk_premux1, + }, + { .clk = &sm1_dsu_clk_mux1_div }, +}; +static CLK_MUX_RO(sm1_dsu_clk_postmux1, HHI_SYS_CPU_CLK_CNTL5, 0x1, 18, 0, 0, sm1_dsu_clk_postmux1_parent_table, 2, 0); +const struct clk_parent_data sm1_dsu_clk_dyn_parent_table[] = { + { + .clk = &sm1_dsu_clk_premux0, + }, + { + .clk = &sm1_dsu_clk_postmux1, + }, +}; +static CLK_MUX_RO(sm1_dsu_clk_dyn, HHI_SYS_CPU_CLK_CNTL5, 0x1, 10, 0, 0, sm1_dsu_clk_dyn_parent_table, 2, 0); +const struct clk_parent_data sm1_dsu_final_clk_parent_table[] = { + { + .clk = &sm1_dsu_clk_dyn, + }, + { + .clk = &g12a_sys_pll, + }, +}; +static CLK_MUX_RO(sm1_dsu_final_clk, HHI_SYS_CPU_CLK_CNTL5, 0x1, 11, 0, 0, sm1_dsu_final_clk_parent_table, 2, 0); +const struct clk_parent_data sm1_cpu_clk_parent_table[] = { + { + .clk = &g12a_cpu_clk, + }, +}; +static CLK_MUX_RO(sm1_cpu1_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 24, 0, 0, sm1_cpu_clk_parent_table, 1, 0); +static CLK_MUX_RO(sm1_cpu2_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 25, 0, 0, sm1_cpu_clk_parent_table, 1, 0); +static CLK_MUX_RO(sm1_cpu3_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 26, 0, 0, sm1_cpu_clk_parent_table, 1, 0); +const struct clk_parent_data sm1_dsu_clk_parent_table[] = { + { + .clk = &g12a_cpu_clk, + }, + { + .clk = &sm1_dsu_final_clk, + }, +}; +static CLK_MUX_RO(sm1_dsu_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 27, 0, 0, sm1_dsu_clk_parent_table, 2, 0); +static CLK_GATE_RO(g12a_cpu_clk_div16_en, HHI_SYS_CPU_CLK_CNTL1, 1, 0, { &g12a_cpu_clk }, 1, 0); +static CLK_FIXED_FACTOR(g12a_cpu_clk_div16, 1, 16, 0, { &g12a_cpu_clk_div16_en }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_apb_div, HHI_SYS_CPU_CLK_CNTL1, 3, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); +static CLK_GATE_RO(g12a_cpu_clk_apb, HHI_SYS_CPU_CLK_CNTL1, 1, 0, { &g12a_cpu_clk_apb_div }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_atb_div, HHI_SYS_CPU_CLK_CNTL1, 6, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); +static CLK_GATE_RO(g12a_cpu_clk_atb, HHI_SYS_CPU_CLK_CNTL1, 17, 0, { &g12a_cpu_clk_atb_div }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_axi_div, HHI_SYS_CPU_CLK_CNTL1, 9, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); +static CLK_GATE_RO(g12a_cpu_clk_axi, HHI_SYS_CPU_CLK_CNTL1, 18, 0, { &g12a_cpu_clk_axi_div }, 1, 0); +/* TODO: special case, ignore its parent clk at the moment */ +static CLK_DIV_RO(g12a_cpu_clk_trace_div, HHI_SYS_CPU_CLK_CNTL1, 20, 3, CLK_DIVIDER_POWER_OF_TWO, {}, 0, 0); +static CLK_GATE_RO(g12a_cpu_clk_trace, HHI_SYS_CPU_CLK_CNTL1, 23, 0, { &g12a_cpu_clk_trace_div }, 1, 0); + +static const struct reg_sequence g12a_hifi_init_regs[] = { + { .reg = HHI_HIFI_PLL_CNTL1, .def = 0x00000000 }, { .reg = HHI_HIFI_PLL_CNTL2, .def = 0x00000000 }, + { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x6a285c00 }, { .reg = HHI_HIFI_PLL_CNTL4, .def = 0x65771290 }, + { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x39272000 }, { .reg = HHI_HIFI_PLL_CNTL6, .def = 0x56540000 }, +}; + +static struct clk g12a_hifi_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_HIFI_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_HIFI_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_HIFI_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_HIFI_PLL_CNTL1, + .shift = 0, + .width = 17, + }, + .l = { + .reg_off = HHI_HIFI_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_HIFI_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + .range_min = 125, + .range_max = 255, + .init_regs = g12a_hifi_init_regs, + .init_count = ARRAY_SIZE(g12a_hifi_init_regs), + .flags = CLK_MESON_PLL_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll_dco", + .ops = &meson_clk_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .name = "xtal", + }, + .num_parents = 1, + }, +}; +static CLK_DIV(g12a_hifi_pll, HHI_HIFI_PLL_CNTL0, 16, 2, (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), + { &g12a_hifi_pll_dco }, 1, 0); + +/* + * The Meson G12A PCIE PLL is fined tuned to deliver a very precise + * 100MHz reference clock for the PCIe Analog PHY, and thus requires + * a strict register sequence to enable the PLL. + */ +static const struct reg_sequence g12a_pcie_pll_init_regs[] = { + { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x20090496 }, + { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x30090496 }, + { .reg = HHI_PCIE_PLL_CNTL1, .def = 0x00000000 }, + { .reg = HHI_PCIE_PLL_CNTL2, .def = 0x00001100 }, + { .reg = HHI_PCIE_PLL_CNTL3, .def = 0x10058e00 }, + { .reg = HHI_PCIE_PLL_CNTL4, .def = 0x000100c0 }, + { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x68000048 }, + { .reg = HHI_PCIE_PLL_CNTL5, .def = 0x68000068, .delay_us = 20 }, + { .reg = HHI_PCIE_PLL_CNTL4, .def = 0x008100c0, .delay_us = 10 }, + { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x34090496 }, + { .reg = HHI_PCIE_PLL_CNTL0, .def = 0x14090496, .delay_us = 10 }, + { .reg = HHI_PCIE_PLL_CNTL2, .def = 0x00001000 }, +}; +/* Keep a single entry table for recalc/round_rate() ops */ +static const struct pll_params_table g12a_pcie_pll_table[] = { + { .m = 150, .n = 1 }, + { .m = 0, .n = 0 }, +}; +static struct clk g12a_pcie_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_PCIE_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_PCIE_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_PCIE_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_PCIE_PLL_CNTL1, + .shift = 0, + .width = 12, + }, + .l = { + .reg_off = HHI_PCIE_PLL_CNTL0, + .shift = 31, + .width = 1, + }, + .rst = { + .reg_off = HHI_PCIE_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + .table = g12a_pcie_pll_table, + .init_regs = g12a_pcie_pll_init_regs, + .init_count = ARRAY_SIZE(g12a_pcie_pll_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "pcie_pll_dco", + .ops = &meson_clk_pcie_pll_ops, + .parent_data = &(const struct clk_parent_data) { + .name = "xtal", + }, + .num_parents = 1, + }, +}; +static CLK_FIXED_FACTOR(g12a_pcie_pll_dco_div2, 1, 2, 0, { &g12a_pcie_pll_dco }, 1, 0); +static CLK_DIV(g12a_pcie_pll_od, HHI_PCIE_PLL_CNTL0, 16, 5, + CLK_DIVIDER_ROUND_CLOSEST | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, { &g12a_pcie_pll_dco_div2 }, + 1, 0); +static CLK_FIXED_FACTOR(g12a_pcie_pll, 1, 2, 0, { &g12a_pcie_pll_od }, 1, 0); +static struct clk g12a_hdmi_pll_dco = { + .data = &(struct meson_clk_pll_data){ + .en = { + .reg_off = HHI_HDMI_PLL_CNTL0, + .shift = 28, + .width = 1, + }, + .m = { + .reg_off = HHI_HDMI_PLL_CNTL0, + .shift = 0, + .width = 8, + }, + .n = { + .reg_off = HHI_HDMI_PLL_CNTL0, + .shift = 10, + .width = 5, + }, + .frac = { + .reg_off = HHI_HDMI_PLL_CNTL1, + .shift = 0, + .width = 16, + }, + .l = { + .reg_off = HHI_HDMI_PLL_CNTL0, + .shift = 30, + .width = 1, + }, + .rst = { + .reg_off = HHI_HDMI_PLL_CNTL0, + .shift = 29, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data){ + .name = "hdmi_pll_dco", + .ops = &meson_clk_pll_ro_ops, + .parent_data = &(const struct clk_parent_data) { + .name = "xtal", + }, + .num_parents = 1, + /* + * Display directly handle hdmi pll registers ATM, we need + * NOCACHE to keep our view of the clock as accurate as possible + */ + .flags = CLK_GET_RATE_NOCACHE, + }, +}; +static CLK_DIV_RO(g12a_hdmi_pll_od, HHI_HDMI_PLL_CNTL0, 16, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_dco }, 1, 0); +static CLK_DIV_RO(g12a_hdmi_pll_od2, HHI_HDMI_PLL_CNTL0, 18, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_od }, 1, 0); +static CLK_DIV_RO(g12a_hdmi_pll, HHI_HDMI_PLL_CNTL0, 20, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_od2 }, 1, 0); +static CLK_FIXED_FACTOR(g12a_fclk_div4_div, 1, 4, 0, { &g12a_fixed_pll }, 1, 0); +static CLK_GATE(g12a_fclk_div4, HHI_FIX_PLL_CNTL1, 21, 0, { &g12a_fclk_div4_div }, 1, 0); +static CLK_FIXED_FACTOR(g12a_fclk_div5_div, 1, 5, 0, { &g12a_fixed_pll }, 1, 0); +static CLK_GATE(g12a_fclk_div5, HHI_FIX_PLL_CNTL1, 22, 0, { &g12a_fclk_div5_div }, 1, 0); +static CLK_FIXED_FACTOR(g12a_fclk_div7_div, 1, 7, 0, { &g12a_fixed_pll }, 1, 0); +static CLK_GATE(g12a_fclk_div7, HHI_FIX_PLL_CNTL1, 23, 0, { &g12a_fclk_div7_div }, 1, 0); +static CLK_FIXED_FACTOR(g12a_fclk_div2p5_div, 1, 5, 0, { &g12a_fixed_pll_dco }, 1, 0); +static CLK_GATE(g12a_fclk_div2p5, HHI_FIX_PLL_CNTL1, 25, 0, { &g12a_fclk_div2p5_div }, 1, 0); +static CLK_FIXED_FACTOR(g12a_mpll_50m_div, 1, 80, 0, { &g12a_fixed_pll_dco }, 1, 0); +const static struct clk_parent_data g12a_mpll_50m_parent_table[] = { + { + .name = "xtal", + }, + { .clk = &g12a_mpll_50m_div }, +}; +static CLK_MUX_RO(g12a_mpll_50m, HHI_FIX_PLL_CNTL3, 0x1, 5, 0, 0, g12a_mpll_50m_parent_table, 2, 0); +static CLK_FIXED_FACTOR(g12a_mpll_prediv, 1, 2, 0, { &g12a_fixed_pll_dco }, 1, 0); + +static const struct reg_sequence g12a_mpll0_init_regs[] = { + { .reg = HHI_MPLL_CNTL2, .def = 0x40000033 }, +}; +static struct clk g12a_mpll0_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = HHI_MPLL_CNTL1, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = HHI_MPLL_CNTL1, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = HHI_MPLL_CNTL1, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = HHI_MPLL_CNTL1, + .shift = 29, + .width = 1, + }, + /* .lock = &meson_clk_lock, */ + .init_regs = g12a_mpll0_init_regs, + .init_count = ARRAY_SIZE(g12a_mpll0_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll0_div", + .ops = &meson_clk_mpll_ops, + .parent_clks = (const struct clk *[]) { + &g12a_mpll_prediv + }, + .num_parents = 1, + }, +}; +static CLK_GATE(g12a_mpll0, HHI_MPLL_CNTL1, 31, 0, { &g12a_mpll0_div }, 1, 0); +static const struct reg_sequence g12a_mpll1_init_regs[] = { + { .reg = HHI_MPLL_CNTL4, .def = 0x40000033 }, +}; +static struct clk g12a_mpll1_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = HHI_MPLL_CNTL3, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = HHI_MPLL_CNTL3, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = HHI_MPLL_CNTL3, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = HHI_MPLL_CNTL3, + .shift = 29, + .width = 1, + }, + /* .lock = &meson_clk_lock, */ + .init_regs = g12a_mpll1_init_regs, + .init_count = ARRAY_SIZE(g12a_mpll1_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll1_div", + .ops = &meson_clk_mpll_ops, + .parent_clks = (const struct clk *[]) { + &g12a_mpll_prediv + }, + .num_parents = 1, + }, +}; +static CLK_GATE(g12a_mpll1, HHI_MPLL_CNTL3, 31, 0, { &g12a_mpll1_div }, 1, 0); +static const struct reg_sequence g12a_mpll2_init_regs[] = { + { .reg = HHI_MPLL_CNTL6, .def = 0x40000033 }, +}; +static struct clk g12a_mpll2_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = HHI_MPLL_CNTL5, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = HHI_MPLL_CNTL5, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = HHI_MPLL_CNTL5, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = HHI_MPLL_CNTL5, + .shift = 29, + .width = 1, + }, + /* .lock = &meson_clk_lock, */ + .init_regs = g12a_mpll2_init_regs, + .init_count = ARRAY_SIZE(g12a_mpll2_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll2_div", + .ops = &meson_clk_mpll_ops, + .parent_clks = (const struct clk *[]) { + &g12a_mpll_prediv + }, + .num_parents = 1, + }, +}; +static CLK_GATE(g12a_mpll2, HHI_MPLL_CNTL5, 31, 0, { &g12a_mpll2_div }, 1, 0); +static const struct reg_sequence g12a_mpll3_init_regs[] = { + { .reg = HHI_MPLL_CNTL8, .def = 0x40000033 }, +}; +static struct clk g12a_mpll3_div = { + .data = &(struct meson_clk_mpll_data){ + .sdm = { + .reg_off = HHI_MPLL_CNTL7, + .shift = 0, + .width = 14, + }, + .sdm_en = { + .reg_off = HHI_MPLL_CNTL7, + .shift = 30, + .width = 1, + }, + .n2 = { + .reg_off = HHI_MPLL_CNTL7, + .shift = 20, + .width = 9, + }, + .ssen = { + .reg_off = HHI_MPLL_CNTL7, + .shift = 29, + .width = 1, + }, + /* .lock = &meson_clk_lock, */ + .init_regs = g12a_mpll3_init_regs, + .init_count = ARRAY_SIZE(g12a_mpll3_init_regs), + }, + .hw.init = &(struct clk_init_data){ + .name = "mpll3_div", + .ops = &meson_clk_mpll_ops, + .parent_clks = (const struct clk *[]) { + &g12a_mpll_prediv + }, + .num_parents = 1, + }, +}; +static CLK_GATE(g12a_mpll3, HHI_MPLL_CNTL7, 31, 0, { &g12a_mpll3_div }, 1, 0); + +static uint32_t mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 }; +static const struct clk_parent_data clk81_parent_data[] = { + { + .name = "xtal", + }, + { .clk = &g12a_fclk_div7 }, + { .clk = &g12a_mpll1 }, + { .clk = &g12a_mpll2 }, + { .clk = &g12a_fclk_div4 }, + { .clk = &g12a_fclk_div3 }, + { .clk = &g12a_fclk_div5 }, +}; +static CLK_MUX_RO(g12a_mpeg_clk_sel, HHI_MPEG_CLK_CNTL, 0x7, 12, mux_table_clk81, 0, clk81_parent_data, + ARRAY_SIZE(clk81_parent_data), 0); +static CLK_DIV(g12a_mpeg_clk_div, HHI_MPEG_CLK_CNTL, 0, 7, 0, { &g12a_mpeg_clk_sel }, 1, 0); +static CLK_GATE(g12a_clk81, HHI_MPEG_CLK_CNTL, 7, 0, { &g12a_mpeg_clk_div }, 1, 0); +static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = { + { + .name = "xtal", + }, + { .clk = &g12a_fclk_div2 }, + { .clk = &g12a_fclk_div3 }, + { .clk = &g12a_fclk_div5 }, + { .clk = &g12a_fclk_div7 }, +}; +static CLK_MUX(g12a_sd_emmc_a_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 9, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, + CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_sd_emmc_a_clk0_div, HHI_SD_EMMC_CLK_CNTL, 0, 7, 0, { &g12a_sd_emmc_a_clk0_sel }, 1, 0); +static CLK_GATE(g12a_sd_emmc_a_clk0, HHI_SD_EMMC_CLK_CNTL, 7, 0, { &g12a_sd_emmc_a_clk0_div }, 1, 0); +static CLK_MUX(g12a_sd_emmc_b_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 25, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, + CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_sd_emmc_b_clk0_div, HHI_SD_EMMC_CLK_CNTL, 16, 7, 0, { &g12a_sd_emmc_b_clk0_sel }, 1, 0); +static CLK_GATE(g12a_sd_emmc_b_clk0, HHI_SD_EMMC_CLK_CNTL, 23, 0, { &g12a_sd_emmc_b_clk0_div }, 1, 0); +static CLK_MUX(g12a_sd_emmc_c_clk0_sel, HHI_NAND_CLK_CNTL, 0x7, 9, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, + CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_sd_emmc_c_clk0_div, HHI_NAND_CLK_CNTL, 0, 7, 0, { &g12a_sd_emmc_c_clk0_sel }, 1, 0); +static CLK_GATE(g12a_sd_emmc_c_clk0, HHI_NAND_CLK_CNTL, 7, 0, { &g12a_sd_emmc_c_clk0_div }, 1, 0); +static struct clk g12a_vid_pll_div = { + .data = &(struct meson_vid_pll_div_data){ + .val = { + .reg_off = HHI_VID_PLL_CLK_DIV, + .shift = 0, + .width = 15, + }, + .sel = { + .reg_off = HHI_VID_PLL_CLK_DIV, + .shift = 16, + .width = 2, + }, + }, + .hw.init = &(struct clk_init_data) { + .name = "vid_pll_div", + .ops = &meson_vid_pll_div_ro_ops, + .parent_clks = (const struct clk *[]) { &g12a_hdmi_pll }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, + }, +}; +static const struct clk_parent_data g12a_vid_pll_parent_table[] = { + { + .clk = &g12a_vid_pll_div, + }, + { + .clk = &g12a_hdmi_pll, + }, +}; + +static CLK_MUX(g12a_vid_pll_sel, HHI_VID_PLL_CLK_DIV, 0x1, 18, 0, 0, g12a_vid_pll_parent_table, 0, + CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_GATE(g12a_vid_pll, HHI_VID_PLL_CLK_DIV, 19, 0, { &g12a_vid_pll_sel }, 1, 0); +const static struct clk_parent_data g12a_vpu_sel_parent_table[] = { + { + .clk = &g12a_fclk_div3, + }, + { + .clk = &g12a_fclk_div4, + }, + { + .clk = &g12a_fclk_div5, + }, + { + .clk = &g12a_fclk_div7, + }, + { + .clk = &g12a_mpll1, + }, + { + .clk = &g12a_vid_pll, + }, + { + .clk = &g12a_hifi_pll, + }, + { + .clk = &g12a_gp0_pll, + }, +}; +static CLK_MUX(g12a_vpu_0_sel, HHI_VPU_CLK_CNTL, 0x7, 9, 0, 0, g12a_vpu_sel_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vpu_0_div, HHI_VPU_CLK_CNTL, 0, 7, 0, { &g12a_vpu_0_sel }, 1, 0); +static CLK_GATE(g12a_vpu_0, HHI_VPU_CLK_CNTL, 8, 0, { &g12a_vpu_0_div }, 1, 0); +static CLK_MUX(g12a_vpu_1_sel, HHI_VPU_CLK_CNTL, 0x7, 25, 0, 0, g12a_vpu_sel_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vpu_1_div, HHI_VPU_CLK_CNTL, 16, 7, 0, { &g12a_vpu_1_sel }, 1, 0); +static CLK_GATE(g12a_vpu_1, HHI_VPU_CLK_CNTL, 24, 0, { &g12a_vpu_1_div }, 1, 0); +const struct clk_parent_data g12a_vpu_parent_table[] = { + { .clk = &g12a_vpu_0 }, + { .clk = &g12a_vpu_1 }, +}; +static CLK_MUX(g12a_vpu, HHI_VPU_CLK_CNTL, 1, 31, 0, 0, g12a_vpu_parent_table, 2, 0); +static const struct clk_parent_data g12a_vdec_parent_table[] = { + { + .clk = &g12a_fclk_div2p5, + }, + { + .clk = &g12a_fclk_div3, + }, + { + .clk = &g12a_fclk_div4, + }, + { + .clk = &g12a_fclk_div5, + }, + { + .clk = &g12a_fclk_div7, + }, + { + .clk = &g12a_hifi_pll, + }, + { + .clk = &g12a_gp0_pll, + }, +}; + +static CLK_MUX(g12a_vdec_1_sel, HHI_VDEC_CLK_CNTL, 0x7, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, + CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_vdec_1_div, HHI_VDEC_CLK_CNTL, 0, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_1_sel }, 1, 0); +static CLK_GATE(g12a_vdec_1, HHI_VDEC_CLK_CNTL, 8, 0, { &g12a_vdec_1_div }, 1, 0); +static CLK_MUX(g12a_vdec_hevcf_sel, HHI_VDEC2_CLK_CNTL, 0x7, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, + CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_vdec_hevcf_div, HHI_VDEC2_CLK_CNTL, 0, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevcf_sel }, 1, + 0); +static CLK_GATE(g12a_vdec_hevcf, HHI_VDEC2_CLK_CNTL, 8, 0, { &g12a_vdec_hevcf_div }, 1, 0); +static CLK_MUX(g12a_vdec_hevc_sel, HHI_VDEC2_CLK_CNTL, 0x7, 25, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, + CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_vdec_hevc_div, HHI_VDEC2_CLK_CNTL, 16, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevc_sel }, 1, 0); +static CLK_GATE(g12a_vdec_hevc, HHI_VDEC2_CLK_CNTL, 24, 0, { &g12a_vdec_hevc_div }, 1, 0); +static const struct clk_parent_data g12a_vapb_parent_table[] = { + { + .clk = &g12a_fclk_div4, + }, + { + .clk = &g12a_fclk_div3, + }, + { + .clk = &g12a_fclk_div5, + }, + { + .clk = &g12a_fclk_div7, + }, + { + .clk = &g12a_mpll1, + }, + { + .clk = &g12a_vid_pll, + }, + { + .clk = &g12a_mpll2, + }, + { + .clk = &g12a_fclk_div2p5, + }, +}; +static CLK_MUX(g12a_vapb_0_sel, HHI_VAPBCLK_CNTL, 0x3, 9, 0, 0, g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vapb_0_div, HHI_VAPBCLK_CNTL, 0, 7, 0, { &g12a_vapb_0_sel }, 1, 0); +static CLK_GATE(g12a_vapb_0, HHI_VAPBCLK_CNTL, 8, 0, { &g12a_vapb_0_div }, 1, 0); +static CLK_MUX(g12a_vapb_1_sel, HHI_VAPBCLK_CNTL, 0x3, 25, 0, 0, g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vapb_1_div, HHI_VAPBCLK_CNTL, 16, 7, 0, { &g12a_vapb_1_sel }, 1, 0); +static CLK_GATE(g12a_vapb_1, HHI_VAPBCLK_CNTL, 24, 0, { &g12a_vapb_1_div }, 1, 0); +const struct clk_parent_data g12a_vapb_sel_parent_table[] = { + { .clk = &g12a_vapb_0 }, + { .clk = &g12a_vapb_1 }, +}; +static CLK_MUX(g12a_vapb_sel, HHI_VAPBCLK_CNTL, 1, 31, 0, 0, g12a_vapb_sel_parent_table, 2, 0); +static CLK_GATE(g12a_vapb, HHI_VAPBCLK_CNTL, 30, 0, { &g12a_vapb_sel }, 1, 0); +static const struct clk_parent_data g12a_vclk_parent_table[] = { + { + .clk = &g12a_vid_pll, + }, + { + .clk = &g12a_gp0_pll, + }, + { + .clk = &g12a_hifi_pll, + }, + { + .clk = &g12a_mpll1, + }, + { + .clk = &g12a_fclk_div3, + }, + { + .clk = &g12a_fclk_div4, + }, + { + .clk = &g12a_fclk_div5, + }, + { + .clk = &g12a_fclk_div7, + }, +}; +static CLK_MUX(g12a_vclk_sel, HHI_VID_CLK_CNTL, 0x7, 16, 0, 0, g12a_vclk_parent_table, 0, + CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_MUX(g12a_vclk2_sel, HHI_VIID_CLK_CNTL, 0x7, 16, 0, 0, g12a_vclk_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_GATE(g12a_vclk_input, HHI_VID_CLK_DIV, 16, 0, { &g12a_vclk_sel }, 1, 0); +static CLK_GATE(g12a_vclk2_input, HHI_VIID_CLK_DIV, 16, 0, { &g12a_vclk2_sel }, 1, 0); +static CLK_DIV(g12a_vclk_div, HHI_VID_CLK_DIV, 0, 8, 0, { &g12a_vclk_input }, 1, 0); +static struct clk g12a_vclk2_div = { + .data = &(struct meson_vclk_div_data){ + .div = { + .reg_off = HHI_VIID_CLK_DIV, + .shift = 0, + .width = 8, + }, + .enable = { + .reg_off = HHI_VIID_CLK_DIV, + .shift = 16, + .width = 1, + }, + .reset = { + .reg_off = HHI_VIID_CLK_DIV, + .shift = 17, + .width = 1, + }, + .flags = CLK_DIVIDER_ROUND_CLOSEST, + }, + .hw.init = &(struct clk_init_data){ + .name = "vclk2_div", + .ops = &meson_vclk_div_ops, + .parent_clks = (const struct clk *[]) { + &g12a_vclk2_input + }, + .num_parents = 1, + .flags = CLK_SET_RATE_GATE, + }, +}; +static CLK_GATE(g12a_vclk, HHI_VID_CLK_CNTL, 19, 0, { &g12a_vclk_div }, 1, 0); +static struct clk g12a_vclk2 = { + .data = &(struct meson_vclk_gate_data){ + .enable = { + .reg_off = HHI_VIID_CLK_CNTL, + .shift = 19, + .width = 1, + }, + .reset = { + .reg_off = HHI_VIID_CLK_CNTL, + .shift = 15, + .width = 1, + }, + }, + .hw.init = &(struct clk_init_data) { + .name = "vclk2", + .ops = &meson_vclk_gate_ops, + .parent_clks = (const struct clk *[]) { &g12a_vclk2_div }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; +static CLK_GATE(g12a_vclk_div1, HHI_VID_CLK_CNTL, 0, 0, { &g12a_vclk }, 1, 0); +static CLK_GATE(g12a_vclk_div2_en, HHI_VID_CLK_CNTL, 1, 0, { &g12a_vclk }, 1, 0); +static CLK_GATE(g12a_vclk_div4_en, HHI_VID_CLK_CNTL, 2, 0, { &g12a_vclk }, 1, 0); +static CLK_GATE(g12a_vclk_div6_en, HHI_VID_CLK_CNTL, 3, 0, { &g12a_vclk }, 1, 0); +static CLK_GATE(g12a_vclk_div12_en, HHI_VID_CLK_CNTL, 4, 0, { &g12a_vclk }, 1, 0); +static CLK_GATE(g12a_vclk2_div1, HHI_VIID_CLK_CNTL, 0, 0, { &g12a_vclk2 }, 1, 0); +static CLK_GATE(g12a_vclk2_div2_en, HHI_VIID_CLK_CNTL, 1, 0, { &g12a_vclk2 }, 1, 0); +static CLK_GATE(g12a_vclk2_div4_en, HHI_VIID_CLK_CNTL, 2, 0, { &g12a_vclk2 }, 1, 0); +static CLK_GATE(g12a_vclk2_div6_en, HHI_VIID_CLK_CNTL, 3, 0, { &g12a_vclk2 }, 1, 0); +static CLK_GATE(g12a_vclk2_div12_en, HHI_VIID_CLK_CNTL, 4, 0, { &g12a_vclk2 }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk_div2, 1, 2, 0, { &g12a_vclk_div2_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk_div4, 1, 4, 0, { &g12a_vclk_div4_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk_div6, 1, 6, 0, { &g12a_vclk_div6_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk_div12, 1, 12, 0, { &g12a_vclk_div12_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div2, 1, 2, 0, { &g12a_vclk2_div2_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div4, 1, 4, 0, { &g12a_vclk2_div4_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div6, 1, 6, 0, { &g12a_vclk2_div6_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div12, 1, 12, 0, { &g12a_vclk2_div12_en }, 1, 0); +static uint32_t mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_parent_data g12a_cts_parent_table[] = { + { + .clk = &g12a_vclk_div1, + }, + { + .clk = &g12a_vclk_div2, + }, + { + .clk = &g12a_vclk_div4, + }, + { + .clk = &g12a_vclk_div6, + }, + { + .clk = &g12a_vclk_div12, + }, + { + .clk = &g12a_vclk2_div1, + }, + { + .clk = &g12a_vclk2_div2, + }, + { + .clk = &g12a_vclk2_div4, + }, + { + .clk = &g12a_vclk2_div6, + }, + { + .clk = &g12a_vclk2_div12, + }, +}; +static CLK_MUX(g12a_cts_enci_sel, HHI_VID_CLK_DIV, 0xf, 28, mux_table_cts_sel, 0, g12a_cts_parent_table, + ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_MUX(g12a_cts_encp_sel, HHI_VID_CLK_DIV, 0xf, 20, mux_table_cts_sel, 0, g12a_cts_parent_table, + ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_MUX(g12a_cts_encl_sel, HHI_VIID_CLK_DIV, 0xf, 12, mux_table_cts_sel, 0, g12a_cts_parent_table, + ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT); +static CLK_MUX(g12a_cts_vdac_sel, HHI_VIID_CLK_DIV, 0xf, 28, mux_table_cts_sel, 0, g12a_cts_parent_table, + ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static uint32_t mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; +static const struct clk_parent_data g12a_cts_hdmi_tx_parent_table[] = { + { + .clk = &g12a_vclk_div1, + }, + { + .clk = &g12a_vclk_div2, + }, + { + .clk = &g12a_vclk_div4, + }, + { + .clk = &g12a_vclk_div6, + }, + { + .clk = &g12a_vclk_div12, + }, + { + .clk = &g12a_vclk2_div1, + }, + { + .clk = &g12a_vclk2_div2, + }, + { + .clk = &g12a_vclk2_div4, + }, + { + .clk = &g12a_vclk2_div6, + }, + { + .clk = &g12a_vclk2_div12, + }, +}; +static CLK_MUX(g12a_hdmi_tx_sel, HHI_HDMI_CLK_CNTL, 0xf, 16, mux_table_hdmi_tx_sel, 0, g12a_cts_hdmi_tx_parent_table, + ARRAY_SIZE(g12a_cts_hdmi_tx_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_GATE(g12a_cts_enci, HHI_VID_CLK_CNTL2, 0, 0, { &g12a_cts_enci_sel }, 1, 0); +static CLK_GATE(g12a_cts_encp, HHI_VID_CLK_CNTL2, 2, 0, { &g12a_cts_encp_sel }, 1, 0); +static CLK_GATE(g12a_cts_encl, HHI_VID_CLK_CNTL2, 3, 0, { &g12a_cts_encl_sel }, 1, 0); +static CLK_GATE(g12a_cts_vdac, HHI_VID_CLK_CNTL2, 4, 0, { &g12a_cts_vdac_sel }, 1, 0); +static CLK_GATE(g12a_hdmi_tx, HHI_VID_CLK_CNTL2, 5, 0, { &g12a_hdmi_tx_sel }, 1, 0); +static const struct clk_parent_data g12a_mipi_dsi_pxclk_parent_table[] = { + { + .clk = &g12a_vid_pll, + }, + { + .clk = &g12a_gp0_pll, + }, + { + .clk = &g12a_hifi_pll, + }, + { + .clk = &g12a_mpll1, + }, + { + .clk = &g12a_fclk_div2, + }, + { + .clk = &g12a_fclk_div2p5, + }, + { + .clk = &g12a_fclk_div3, + }, + { + .clk = &g12a_fclk_div7, + }, +}; +static CLK_MUX(g12a_mipi_dsi_pxclk_sel, HHI_MIPIDSI_PHY_CLK_CNTL, 0x7, 12, 0, CLK_MUX_ROUND_CLOSEST, + g12a_mipi_dsi_pxclk_parent_table, ARRAY_SIZE(g12a_mipi_dsi_pxclk_parent_table), + CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_mipi_dsi_pxclk_div, HHI_MIPIDSI_PHY_CLK_CNTL, 0, 7, 0, { &g12a_mipi_dsi_pxclk_sel }, 1, 0); +static CLK_GATE(g12a_mipi_dsi_pxclk, HHI_MIPIDSI_PHY_CLK_CNTL, 8, 0, { &g12a_mipi_dsi_pxclk_div }, 1, 0); +static const struct clk_parent_data g12a_hdmi_parent_table[] = { + { + .name = "xtal", + }, + { .clk = &g12a_fclk_div4 }, + { .clk = &g12a_fclk_div3 }, + { .clk = &g12a_fclk_div5 }, +}; +static CLK_MUX(g12a_hdmi_sel, HHI_HDMI_CLK_CNTL, 0x3, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_hdmi_parent_table, + ARRAY_SIZE(g12a_hdmi_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_DIV(g12a_hdmi_div, HHI_HDMI_CLK_CNTL, 0, 7, 0, { &g12a_hdmi_sel }, 1, 0); +static CLK_GATE(g12a_hdmi, HHI_HDMI_CLK_CNTL, 8, 0, { &g12a_hdmi_div }, 1, 0); +static const struct clk_parent_data g12a_mali_0_1_parent_data[] = { + { + .name = "xtal", + }, + { .clk = &g12a_gp0_pll }, + { .clk = &g12a_hifi_pll }, + { .clk = &g12a_fclk_div2p5 }, + { .clk = &g12a_fclk_div3 }, + { .clk = &g12a_fclk_div4 }, + { .clk = &g12a_fclk_div5 }, + { .clk = &g12a_fclk_div7 }, +}; +static CLK_MUX(g12a_mali_0_sel, HHI_MALI_CLK_CNTL, 0x7, 9, 0, 0, g12a_mali_0_1_parent_data, 8, 0); +static CLK_DIV(g12a_mali_0_div, HHI_MALI_CLK_CNTL, 0, 7, 0, { &g12a_mali_0_sel }, 1, 0); +static CLK_GATE(g12a_mali_0, HHI_MALI_CLK_CNTL, 8, 0, { &g12a_mali_0_div }, 1, 0); +static CLK_MUX(g12a_mali_1_sel, HHI_MALI_CLK_CNTL, 0x7, 25, 0, 0, g12a_mali_0_1_parent_data, 8, 0); +static CLK_DIV(g12a_mali_1_div, HHI_MALI_CLK_CNTL, 16, 7, 0, { &g12a_mali_1_sel }, 1, 0); +static CLK_GATE(g12a_mali_1, HHI_MALI_CLK_CNTL, 24, 0, { &g12a_mali_1_div }, 1, 0); +static const struct clk_parent_data g12a_mali_parent_table[] = { + { + .clk = &g12a_mali_0, + }, + { + .clk = &g12a_mali_1, + }, +}; +static CLK_MUX(g12a_mali, HHI_MALI_CLK_CNTL, 1, 31, 0, 0, g12a_mali_parent_table, 2, CLK_SET_RATE_PARENT); +static CLK_DIV_RO(g12a_ts_div, HHI_TS_CLK_CNTL, 0, 8, 0, { &g12a_ts_div }, 1, 0); +static CLK_GATE(g12a_ts, HHI_TS_CLK_CNTL, 8, 0, { &g12a_ts_div }, 1, 0); +static const struct clk_parent_data spicc_sclk_parent_data[] = { + { + .name = "xtal", + }, + { .clk = &g12a_clk81 }, + { .clk = &g12a_fclk_div4 }, + { .clk = &g12a_fclk_div3 }, + { .clk = &g12a_fclk_div5 }, + { .clk = &g12a_fclk_div7 }, +}; + +static CLK_MUX(g12a_spicc0_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 7, 0, 0, spicc_sclk_parent_data, 0, 0); +static CLK_DIV(g12a_spicc0_sclk_div, HHI_SPICC_CLK_CNTL, 0, 6, 0, { &g12a_spicc0_sclk_sel }, 1, 0); +static CLK_GATE(g12a_spicc0_sclk, HHI_SPICC_CLK_CNTL, 6, 0, { &g12a_spicc0_sclk_div }, 1, 0); +static CLK_MUX(g12a_spicc1_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 23, 0, 0, spicc_sclk_parent_data, 0, 0); +static CLK_DIV(g12a_spicc1_sclk_div, HHI_SPICC_CLK_CNTL, 16, 6, 0, { &g12a_spicc1_sclk_sel }, 1, 0); +static CLK_GATE(g12a_spicc1_sclk, HHI_SPICC_CLK_CNTL, 22, 0, { &g12a_spicc1_sclk_div }, 1, 0); +static const struct clk_parent_data nna_clk_parent_data[] = { + { + .name = "xtal", + }, + { + .clk = &g12a_gp0_pll, + }, + { + .clk = &g12a_hifi_pll, + }, + { + .clk = &g12a_fclk_div2p5, + }, + { + .clk = &g12a_fclk_div3, + }, + { + .clk = &g12a_fclk_div4, + }, + { + .clk = &g12a_fclk_div5, + }, + { .clk = &g12a_fclk_div7 }, +}; +static CLK_MUX(sm1_nna_axi_clk_sel, HHI_NNA_CLK_CNTL, 7, 9, 0, 0, nna_clk_parent_data, 0, 0); +static CLK_DIV(sm1_nna_axi_clk_div, HHI_NNA_CLK_CNTL, 0, 7, 0, { &sm1_nna_axi_clk_sel }, 1, 0); +static CLK_GATE(sm1_nna_axi_clk, HHI_NNA_CLK_CNTL, 8, 0, { &sm1_nna_axi_clk_div }, 1, 0); +static CLK_MUX(sm1_nna_core_clk_sel, HHI_NNA_CLK_CNTL, 7, 25, 0, 0, nna_clk_parent_data, 0, 0); +static CLK_DIV(sm1_nna_core_clk_div, HHI_NNA_CLK_CNTL, 16, 7, 0, { &sm1_nna_core_clk_sel }, 1, 0); +static CLK_GATE(sm1_nna_core_clk, HHI_NNA_CLK_CNTL, 24, 0, { &sm1_nna_core_clk_div }, 1, 0); + +/* Everything Else (EE) domain gates */ +static MESON_CLK81_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0); +static MESON_CLK81_GATE(g12a_dos, HHI_GCLK_MPEG0, 1); +static MESON_CLK81_GATE(g12a_audio_locker, HHI_GCLK_MPEG0, 2); +static MESON_CLK81_GATE(g12a_mipi_dsi_host, HHI_GCLK_MPEG0, 3); +static MESON_CLK81_GATE(g12a_eth_phy, HHI_GCLK_MPEG0, 4); +static MESON_CLK81_GATE(g12a_isa, HHI_GCLK_MPEG0, 5); +static MESON_CLK81_GATE(g12a_pl301, HHI_GCLK_MPEG0, 6); +static MESON_CLK81_GATE(g12a_periphs, HHI_GCLK_MPEG0, 7); +static MESON_CLK81_GATE(g12a_spicc_0, HHI_GCLK_MPEG0, 8); +static MESON_CLK81_GATE(g12a_i2c, HHI_GCLK_MPEG0, 9); +static MESON_CLK81_GATE(g12a_sana, HHI_GCLK_MPEG0, 10); +static MESON_CLK81_GATE(g12a_sd, HHI_GCLK_MPEG0, 11); +static MESON_CLK81_GATE(g12a_rng0, HHI_GCLK_MPEG0, 12); +static MESON_CLK81_GATE(g12a_uart0, HHI_GCLK_MPEG0, 13); +static MESON_CLK81_GATE(g12a_spicc_1, HHI_GCLK_MPEG0, 14); +static MESON_CLK81_GATE(g12a_hiu_reg, HHI_GCLK_MPEG0, 19); +static MESON_CLK81_GATE(g12a_mipi_dsi_phy, HHI_GCLK_MPEG0, 20); +static MESON_CLK81_GATE(g12a_assist_misc, HHI_GCLK_MPEG0, 23); +static MESON_CLK81_GATE(g12a_emmc_a, HHI_GCLK_MPEG0, 4); +static MESON_CLK81_GATE(g12a_emmc_b, HHI_GCLK_MPEG0, 25); +static MESON_CLK81_GATE(g12a_emmc_c, HHI_GCLK_MPEG0, 26); +static MESON_CLK81_GATE(g12a_audio_codec, HHI_GCLK_MPEG0, 28); + +static MESON_CLK81_GATE(g12a_audio, HHI_GCLK_MPEG1, 0); +static MESON_CLK81_GATE(g12a_eth_core, HHI_GCLK_MPEG1, 3); +static MESON_CLK81_GATE(g12a_demux, HHI_GCLK_MPEG1, 4); +static MESON_CLK81_GATE(g12a_audio_ififo, HHI_GCLK_MPEG1, 11); +static MESON_CLK81_GATE(g12a_adc, HHI_GCLK_MPEG1, 13); +static MESON_CLK81_GATE(g12a_uart1, HHI_GCLK_MPEG1, 16); +static MESON_CLK81_GATE(g12a_g2d, HHI_GCLK_MPEG1, 20); +static MESON_CLK81_GATE(g12a_reset, HHI_GCLK_MPEG1, 23); +static MESON_CLK81_GATE(g12a_pcie_comb, HHI_GCLK_MPEG1, 24); +static MESON_CLK81_GATE(g12a_parser, HHI_GCLK_MPEG1, 25); +static MESON_CLK81_GATE(g12a_usb_general, HHI_GCLK_MPEG1, 26); +static MESON_CLK81_GATE(g12a_pcie_phy, HHI_GCLK_MPEG1, 27); +static MESON_CLK81_GATE(g12a_ahb_arb0, HHI_GCLK_MPEG1, 29); + +static MESON_CLK81_GATE(g12a_ahb_data_bus, HHI_GCLK_MPEG2, 1); +static MESON_CLK81_GATE(g12a_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); +static MESON_CLK81_GATE(g12a_htx_hdcp22, HHI_GCLK_MPEG2, 3); +static MESON_CLK81_GATE(g12a_htx_pclk, HHI_GCLK_MPEG2, 4); +static MESON_CLK81_GATE(g12a_bt656, HHI_GCLK_MPEG2, 6); +static MESON_CLK81_GATE(g12a_usb1_to_ddr, HHI_GCLK_MPEG2, 8); +static MESON_CLK81_GATE(g12a_mmc_pclk, HHI_GCLK_MPEG2, 11); +static MESON_CLK81_GATE(g12a_uart2, HHI_GCLK_MPEG2, 15); +static MESON_CLK81_GATE(g12a_vpu_intr, HHI_GCLK_MPEG2, 25); +static MESON_CLK81_GATE(g12a_gic, HHI_GCLK_MPEG2, 30); + +static MESON_CLK81_GATE(g12a_vclk2_venci0, HHI_GCLK_OTHER, 1); +static MESON_CLK81_GATE(g12a_vclk2_venci1, HHI_GCLK_OTHER, 2); +static MESON_CLK81_GATE(g12a_vclk2_vencp0, HHI_GCLK_OTHER, 3); +static MESON_CLK81_GATE(g12a_vclk2_vencp1, HHI_GCLK_OTHER, 4); +static MESON_CLK81_GATE(g12a_vclk2_venct0, HHI_GCLK_OTHER, 5); +static MESON_CLK81_GATE(g12a_vclk2_venct1, HHI_GCLK_OTHER, 6); +static MESON_CLK81_GATE(g12a_vclk2_other, HHI_GCLK_OTHER, 7); +static MESON_CLK81_GATE(g12a_vclk2_enci, HHI_GCLK_OTHER, 8); +static MESON_CLK81_GATE(g12a_vclk2_encp, HHI_GCLK_OTHER, 9); +static MESON_CLK81_GATE(g12a_dac_clk, HHI_GCLK_OTHER, 10); +static MESON_CLK81_GATE(g12a_aoclk_gate, HHI_GCLK_OTHER, 14); +static MESON_CLK81_GATE(g12a_iec958_gate, HHI_GCLK_OTHER, 16); +static MESON_CLK81_GATE(g12a_enc480p, HHI_GCLK_OTHER, 20); +static MESON_CLK81_GATE(g12a_rng1, HHI_GCLK_OTHER, 21); +static MESON_CLK81_GATE(g12a_vclk2_enct, HHI_GCLK_OTHER, 22); +static MESON_CLK81_GATE(g12a_vclk2_encl, HHI_GCLK_OTHER, 23); +static MESON_CLK81_GATE(g12a_vclk2_venclmmc, HHI_GCLK_OTHER, 24); +static MESON_CLK81_GATE(g12a_vclk2_vencl, HHI_GCLK_OTHER, 25); +static MESON_CLK81_GATE(g12a_vclk2_other1, HHI_GCLK_OTHER, 26); + +static MESON_CLK81_GATE_RO(g12a_dma, HHI_GCLK_OTHER2, 0); +static MESON_CLK81_GATE_RO(g12a_efuse, HHI_GCLK_OTHER2, 1); +static MESON_CLK81_GATE_RO(g12a_rom_boot, HHI_GCLK_OTHER2, 2); +static MESON_CLK81_GATE_RO(g12a_reset_sec, HHI_GCLK_OTHER2, 3); +static MESON_CLK81_GATE_RO(g12a_sec_ahb_apb3, HHI_GCLK_OTHER2, 4); + +static struct clk *sm1_clks[] = { + [CLKID_SYS_PLL] = &g12a_sys_pll, + [CLKID_FIXED_PLL] = &g12a_fixed_pll, + [CLKID_FCLK_DIV2] = &g12a_fclk_div2, + [CLKID_FCLK_DIV3] = &g12a_fclk_div3, + [CLKID_FCLK_DIV4] = &g12a_fclk_div4, + [CLKID_FCLK_DIV5] = &g12a_fclk_div5, + [CLKID_FCLK_DIV7] = &g12a_fclk_div7, + [CLKID_FCLK_DIV2P5] = &g12a_fclk_div2p5, + [CLKID_GP0_PLL] = &g12a_gp0_pll, + [CLKID_MPEG_SEL] = &g12a_mpeg_clk_sel, + [CLKID_MPEG_DIV] = &g12a_mpeg_clk_div, + [CLKID_CLK81] = &g12a_clk81, + [CLKID_MPLL0] = &g12a_mpll0, + [CLKID_MPLL1] = &g12a_mpll1, + [CLKID_MPLL2] = &g12a_mpll2, + [CLKID_MPLL3] = &g12a_mpll3, + [CLKID_DDR] = &g12a_ddr, + [CLKID_DOS] = &g12a_dos, + [CLKID_AUDIO_LOCKER] = &g12a_audio_locker, + [CLKID_MIPI_DSI_HOST] = &g12a_mipi_dsi_host, + [CLKID_ETH_PHY] = &g12a_eth_phy, + [CLKID_ISA] = &g12a_isa, + [CLKID_PL301] = &g12a_pl301, + [CLKID_PERIPHS] = &g12a_periphs, + [CLKID_SPICC0] = &g12a_spicc_0, + [CLKID_I2C] = &g12a_i2c, + [CLKID_SANA] = &g12a_sana, + [CLKID_SD] = &g12a_sd, + [CLKID_RNG0] = &g12a_rng0, + [CLKID_UART0] = &g12a_uart0, + [CLKID_SPICC1] = &g12a_spicc_1, + [CLKID_HIU_IFACE] = &g12a_hiu_reg, + [CLKID_MIPI_DSI_PHY] = &g12a_mipi_dsi_phy, + [CLKID_ASSIST_MISC] = &g12a_assist_misc, + [CLKID_SD_EMMC_A] = &g12a_emmc_a, + [CLKID_SD_EMMC_B] = &g12a_emmc_b, + [CLKID_SD_EMMC_C] = &g12a_emmc_c, + [CLKID_AUDIO_CODEC] = &g12a_audio_codec, + [CLKID_AUDIO] = &g12a_audio, + [CLKID_ETH] = &g12a_eth_core, + [CLKID_DEMUX] = &g12a_demux, + [CLKID_AUDIO_IFIFO] = &g12a_audio_ififo, + [CLKID_ADC] = &g12a_adc, + [CLKID_UART1] = &g12a_uart1, + [CLKID_G2D] = &g12a_g2d, + [CLKID_RESET] = &g12a_reset, + [CLKID_PCIE_COMB] = &g12a_pcie_comb, + [CLKID_PARSER] = &g12a_parser, + [CLKID_USB] = &g12a_usb_general, + [CLKID_PCIE_PHY] = &g12a_pcie_phy, + [CLKID_AHB_ARB0] = &g12a_ahb_arb0, + [CLKID_AHB_DATA_BUS] = &g12a_ahb_data_bus, + [CLKID_AHB_CTRL_BUS] = &g12a_ahb_ctrl_bus, + [CLKID_HTX_HDCP22] = &g12a_htx_hdcp22, + [CLKID_HTX_PCLK] = &g12a_htx_pclk, + [CLKID_BT656] = &g12a_bt656, + [CLKID_USB1_DDR_BRIDGE] = &g12a_usb1_to_ddr, + [CLKID_MMC_PCLK] = &g12a_mmc_pclk, + [CLKID_UART2] = &g12a_uart2, + [CLKID_VPU_INTR] = &g12a_vpu_intr, + [CLKID_GIC] = &g12a_gic, + [CLKID_SD_EMMC_A_CLK0_SEL] = &g12a_sd_emmc_a_clk0_sel, + [CLKID_SD_EMMC_A_CLK0_DIV] = &g12a_sd_emmc_a_clk0_div, + [CLKID_SD_EMMC_A_CLK0] = &g12a_sd_emmc_a_clk0, + [CLKID_SD_EMMC_B_CLK0_SEL] = &g12a_sd_emmc_b_clk0_sel, + [CLKID_SD_EMMC_B_CLK0_DIV] = &g12a_sd_emmc_b_clk0_div, + [CLKID_SD_EMMC_B_CLK0] = &g12a_sd_emmc_b_clk0, + [CLKID_SD_EMMC_C_CLK0_SEL] = &g12a_sd_emmc_c_clk0_sel, + [CLKID_SD_EMMC_C_CLK0_DIV] = &g12a_sd_emmc_c_clk0_div, + [CLKID_SD_EMMC_C_CLK0] = &g12a_sd_emmc_c_clk0, + [CLKID_MPLL0_DIV] = &g12a_mpll0_div, + [CLKID_MPLL1_DIV] = &g12a_mpll1_div, + [CLKID_MPLL2_DIV] = &g12a_mpll2_div, + [CLKID_MPLL3_DIV] = &g12a_mpll3_div, + [CLKID_FCLK_DIV2_DIV] = &g12a_fclk_div2_div, + [CLKID_FCLK_DIV3_DIV] = &g12a_fclk_div3_div, + [CLKID_FCLK_DIV4_DIV] = &g12a_fclk_div4_div, + [CLKID_FCLK_DIV5_DIV] = &g12a_fclk_div5_div, + [CLKID_FCLK_DIV7_DIV] = &g12a_fclk_div7_div, + [CLKID_FCLK_DIV2P5_DIV] = &g12a_fclk_div2p5_div, + [CLKID_HIFI_PLL] = &g12a_hifi_pll, + [CLKID_VCLK2_VENCI0] = &g12a_vclk2_venci0, + [CLKID_VCLK2_VENCI1] = &g12a_vclk2_venci1, + [CLKID_VCLK2_VENCP0] = &g12a_vclk2_vencp0, + [CLKID_VCLK2_VENCP1] = &g12a_vclk2_vencp1, + [CLKID_VCLK2_VENCT0] = &g12a_vclk2_venct0, + [CLKID_VCLK2_VENCT1] = &g12a_vclk2_venct1, + [CLKID_VCLK2_OTHER] = &g12a_vclk2_other, + [CLKID_VCLK2_ENCI] = &g12a_vclk2_enci, + [CLKID_VCLK2_ENCP] = &g12a_vclk2_encp, + [CLKID_DAC_CLK] = &g12a_dac_clk, + [CLKID_AOCLK] = &g12a_aoclk_gate, + [CLKID_IEC958] = &g12a_iec958_gate, + [CLKID_ENC480P] = &g12a_enc480p, + [CLKID_RNG1] = &g12a_rng1, + [CLKID_VCLK2_ENCT] = &g12a_vclk2_enct, + [CLKID_VCLK2_ENCL] = &g12a_vclk2_encl, + [CLKID_VCLK2_VENCLMMC] = &g12a_vclk2_venclmmc, + [CLKID_VCLK2_VENCL] = &g12a_vclk2_vencl, + [CLKID_VCLK2_OTHER1] = &g12a_vclk2_other1, + [CLKID_FIXED_PLL_DCO] = &g12a_fixed_pll_dco, + [CLKID_SYS_PLL_DCO] = &g12a_sys_pll_dco, + [CLKID_GP0_PLL_DCO] = &g12a_gp0_pll_dco, + [CLKID_HIFI_PLL_DCO] = &g12a_hifi_pll_dco, + [CLKID_DMA] = &g12a_dma, + [CLKID_EFUSE] = &g12a_efuse, + [CLKID_ROM_BOOT] = &g12a_rom_boot, + [CLKID_RESET_SEC] = &g12a_reset_sec, + [CLKID_SEC_AHB_APB3] = &g12a_sec_ahb_apb3, + [CLKID_MPLL_PREDIV] = &g12a_mpll_prediv, + [CLKID_VPU_0_SEL] = &g12a_vpu_0_sel, + [CLKID_VPU_0_DIV] = &g12a_vpu_0_div, + [CLKID_VPU_0] = &g12a_vpu_0, + [CLKID_VPU_1_SEL] = &g12a_vpu_1_sel, + [CLKID_VPU_1_DIV] = &g12a_vpu_1_div, + [CLKID_VPU_1] = &g12a_vpu_1, + [CLKID_VPU] = &g12a_vpu, + [CLKID_VAPB_0_SEL] = &g12a_vapb_0_sel, + [CLKID_VAPB_0_DIV] = &g12a_vapb_0_div, + [CLKID_VAPB_0] = &g12a_vapb_0, + [CLKID_VAPB_1_SEL] = &g12a_vapb_1_sel, + [CLKID_VAPB_1_DIV] = &g12a_vapb_1_div, + [CLKID_VAPB_1] = &g12a_vapb_1, + [CLKID_VAPB_SEL] = &g12a_vapb_sel, + [CLKID_VAPB] = &g12a_vapb, + [CLKID_HDMI_PLL_DCO] = &g12a_hdmi_pll_dco, + [CLKID_HDMI_PLL_OD] = &g12a_hdmi_pll_od, + [CLKID_HDMI_PLL_OD2] = &g12a_hdmi_pll_od2, + [CLKID_HDMI_PLL] = &g12a_hdmi_pll, + [CLKID_VID_PLL] = &g12a_vid_pll_div, + [CLKID_VID_PLL_SEL] = &g12a_vid_pll_sel, + [CLKID_VID_PLL_DIV] = &g12a_vid_pll, + [CLKID_VCLK_SEL] = &g12a_vclk_sel, + [CLKID_VCLK2_SEL] = &g12a_vclk2_sel, + [CLKID_VCLK_INPUT] = &g12a_vclk_input, + [CLKID_VCLK2_INPUT] = &g12a_vclk2_input, + [CLKID_VCLK_DIV] = &g12a_vclk_div, + [CLKID_VCLK2_DIV] = &g12a_vclk2_div, + [CLKID_VCLK] = &g12a_vclk, + [CLKID_VCLK2] = &g12a_vclk2, + [CLKID_VCLK_DIV1] = &g12a_vclk_div1, + [CLKID_VCLK_DIV2_EN] = &g12a_vclk_div2_en, + [CLKID_VCLK_DIV4_EN] = &g12a_vclk_div4_en, + [CLKID_VCLK_DIV6_EN] = &g12a_vclk_div6_en, + [CLKID_VCLK_DIV12_EN] = &g12a_vclk_div12_en, + [CLKID_VCLK2_DIV1] = &g12a_vclk2_div1, + [CLKID_VCLK2_DIV2_EN] = &g12a_vclk2_div2_en, + [CLKID_VCLK2_DIV4_EN] = &g12a_vclk2_div4_en, + [CLKID_VCLK2_DIV6_EN] = &g12a_vclk2_div6_en, + [CLKID_VCLK2_DIV12_EN] = &g12a_vclk2_div12_en, + [CLKID_VCLK_DIV2] = &g12a_vclk_div2, + [CLKID_VCLK_DIV4] = &g12a_vclk_div4, + [CLKID_VCLK_DIV6] = &g12a_vclk_div6, + [CLKID_VCLK_DIV12] = &g12a_vclk_div12, + [CLKID_VCLK2_DIV2] = &g12a_vclk2_div2, + [CLKID_VCLK2_DIV4] = &g12a_vclk2_div4, + [CLKID_VCLK2_DIV6] = &g12a_vclk2_div6, + [CLKID_VCLK2_DIV12] = &g12a_vclk2_div12, + [CLKID_CTS_ENCI_SEL] = &g12a_cts_enci_sel, + [CLKID_CTS_ENCP_SEL] = &g12a_cts_encp_sel, + [CLKID_CTS_ENCL_SEL] = &g12a_cts_encl_sel, + [CLKID_CTS_VDAC_SEL] = &g12a_cts_vdac_sel, + [CLKID_HDMI_TX_SEL] = &g12a_hdmi_tx_sel, + [CLKID_CTS_ENCI] = &g12a_cts_enci, + [CLKID_CTS_ENCP] = &g12a_cts_encp, + [CLKID_CTS_ENCL] = &g12a_cts_encl, + [CLKID_CTS_VDAC] = &g12a_cts_vdac, + [CLKID_HDMI_TX] = &g12a_hdmi_tx, + [CLKID_HDMI_SEL] = &g12a_hdmi_sel, + [CLKID_HDMI_DIV] = &g12a_hdmi_div, + [CLKID_HDMI] = &g12a_hdmi, + [CLKID_MALI_0_SEL] = &g12a_mali_0_sel, + [CLKID_MALI_0_DIV] = &g12a_mali_0_div, + [CLKID_MALI_0] = &g12a_mali_0, + [CLKID_MALI_1_SEL] = &g12a_mali_1_sel, + [CLKID_MALI_1_DIV] = &g12a_mali_1_div, + [CLKID_MALI_1] = &g12a_mali_1, + [CLKID_MALI] = &g12a_mali, + [CLKID_MPLL_50M_DIV] = &g12a_mpll_50m_div, + [CLKID_MPLL_50M] = &g12a_mpll_50m, + [CLKID_SYS_PLL_DIV16_EN] = &g12a_sys_pll_div16_en, + [CLKID_SYS_PLL_DIV16] = &g12a_sys_pll_div16, + [CLKID_CPU_CLK_DYN0_SEL] = &g12a_cpu_clk_premux0, + [CLKID_CPU_CLK_DYN0_DIV] = &g12a_cpu_clk_mux0_div, + [CLKID_CPU_CLK_DYN0] = &g12a_cpu_clk_postmux0, + [CLKID_CPU_CLK_DYN1_SEL] = &g12a_cpu_clk_premux1, + [CLKID_CPU_CLK_DYN1_DIV] = &g12a_cpu_clk_mux1_div, + [CLKID_CPU_CLK_DYN1] = &g12a_cpu_clk_postmux1, + [CLKID_CPU_CLK_DYN] = &g12a_cpu_clk_dyn, + [CLKID_CPU_CLK] = &g12a_cpu_clk, + [CLKID_CPU_CLK_DIV16_EN] = &g12a_cpu_clk_div16_en, + [CLKID_CPU_CLK_DIV16] = &g12a_cpu_clk_div16, + [CLKID_CPU_CLK_APB_DIV] = &g12a_cpu_clk_apb_div, + [CLKID_CPU_CLK_APB] = &g12a_cpu_clk_apb, + [CLKID_CPU_CLK_ATB_DIV] = &g12a_cpu_clk_atb_div, + [CLKID_CPU_CLK_ATB] = &g12a_cpu_clk_atb, + [CLKID_CPU_CLK_AXI_DIV] = &g12a_cpu_clk_axi_div, + [CLKID_CPU_CLK_AXI] = &g12a_cpu_clk_axi, + [CLKID_CPU_CLK_TRACE_DIV] = &g12a_cpu_clk_trace_div, + [CLKID_CPU_CLK_TRACE] = &g12a_cpu_clk_trace, + [CLKID_PCIE_PLL_DCO] = &g12a_pcie_pll_dco, + [CLKID_PCIE_PLL_DCO_DIV2] = &g12a_pcie_pll_dco_div2, + [CLKID_PCIE_PLL_OD] = &g12a_pcie_pll_od, + [CLKID_PCIE_PLL] = &g12a_pcie_pll, + [CLKID_VDEC_1_SEL] = &g12a_vdec_1_sel, + [CLKID_VDEC_1_DIV] = &g12a_vdec_1_div, + [CLKID_VDEC_1] = &g12a_vdec_1, + [CLKID_VDEC_HEVC_SEL] = &g12a_vdec_hevc_sel, + [CLKID_VDEC_HEVC_DIV] = &g12a_vdec_hevc_div, + [CLKID_VDEC_HEVC] = &g12a_vdec_hevc, + [CLKID_VDEC_HEVCF_SEL] = &g12a_vdec_hevcf_sel, + [CLKID_VDEC_HEVCF_DIV] = &g12a_vdec_hevcf_div, + [CLKID_VDEC_HEVCF] = &g12a_vdec_hevcf, + [CLKID_TS_DIV] = &g12a_ts_div, + [CLKID_TS] = &g12a_ts, + [CLKID_GP1_PLL_DCO] = &sm1_gp1_pll_dco, + [CLKID_GP1_PLL] = &sm1_gp1_pll, + [CLKID_DSU_CLK_DYN0_SEL] = &sm1_dsu_clk_premux0, + [CLKID_DSU_CLK_DYN0_DIV] = &sm1_dsu_clk_premux1, + [CLKID_DSU_CLK_DYN0] = &sm1_dsu_clk_mux0_div, + [CLKID_DSU_CLK_DYN1_SEL] = &sm1_dsu_clk_postmux0, + [CLKID_DSU_CLK_DYN1_DIV] = &sm1_dsu_clk_mux1_div, + [CLKID_DSU_CLK_DYN1] = &sm1_dsu_clk_postmux1, + [CLKID_DSU_CLK_DYN] = &sm1_dsu_clk_dyn, + [CLKID_DSU_CLK_FINAL] = &sm1_dsu_final_clk, + [CLKID_DSU_CLK] = &sm1_dsu_clk, + [CLKID_CPU1_CLK] = &sm1_cpu1_clk, + [CLKID_CPU2_CLK] = &sm1_cpu2_clk, + [CLKID_CPU3_CLK] = &sm1_cpu3_clk, + [CLKID_SPICC0_SCLK_SEL] = &g12a_spicc0_sclk_sel, + [CLKID_SPICC0_SCLK_DIV] = &g12a_spicc0_sclk_div, + [CLKID_SPICC0_SCLK] = &g12a_spicc0_sclk, + [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel, + [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div, + [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk, + [CLKID_NNA_AXI_CLK_SEL] = &sm1_nna_axi_clk_sel, + [CLKID_NNA_AXI_CLK_DIV] = &sm1_nna_axi_clk_div, + [CLKID_NNA_AXI_CLK] = &sm1_nna_axi_clk, + [CLKID_NNA_CORE_CLK_SEL] = &sm1_nna_core_clk_sel, + [CLKID_NNA_CORE_CLK_DIV] = &sm1_nna_core_clk_div, + [CLKID_NNA_CORE_CLK] = &sm1_nna_core_clk, + [CLKID_MIPI_DSI_PXCLK_SEL] = &g12a_mipi_dsi_pxclk_sel, + [CLKID_MIPI_DSI_PXCLK_DIV] = &g12a_mipi_dsi_pxclk_div, + [CLKID_MIPI_DSI_PXCLK] = &g12a_mipi_dsi_pxclk, +}; + +struct clk **get_clk_list(void) +{ + return sm1_clks; +} diff --git a/drivers/clk/utils.h b/drivers/clk/utils.h new file mode 100644 index 000000000..4476e7372 --- /dev/null +++ b/drivers/clk/utils.h @@ -0,0 +1,33 @@ +/* + * Copyright 2024, UNSW + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#define MASK(width) ((1UL << width) - 1) + +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) + +#define do_div(n, base) ({ \ + uint32_t __base = (base); \ + uint32_t __rem; \ + __rem = ((uint64_t)(n)) % __base; \ + (n) = ((uint64_t)(n)) / __base; \ + __rem; \ + }) + +#define DIV_ROUND_DOWN_ULL(ll, d) \ + ({ uint64_t _tmp = (ll); do_div(_tmp, d); _tmp; }) + +#define DIV_ROUND_UP_ULL(ll, d) \ + DIV_ROUND_DOWN_ULL((uint64_t)(ll) + (d) - 1, (d)) + +#define DIV_ROUND_CLOSEST_ULL(x, divisor)( \ +{ \ + typeof(divisor) __d = divisor; \ + unsigned long long _tmp = (x) + (__d) / 2; \ + do_div(_tmp, __d); \ + _tmp; \ +} \ +) diff --git a/examples/clk/board/odroidc4/clk.system b/examples/clk/board/odroidc4/clk.system new file mode 100644 index 000000000..c9d24da0c --- /dev/null +++ b/examples/clk/board/odroidc4/clk.system @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/clk/build.zig b/examples/clk/build.zig new file mode 100644 index 000000000..a543474fa --- /dev/null +++ b/examples/clk/build.zig @@ -0,0 +1,136 @@ +// +// Copyright 2024, UNSW +// SPDX-License-Identifier: BSD-2-Clause +// +const std = @import("std"); + +const MicrokitBoard = enum { odroidc4 }; + +const Target = struct { + board: MicrokitBoard, + zig_target: std.Target.Query, +}; + +const targets = [_]Target{ + .{ + .board = MicrokitBoard.odroidc4, + .zig_target = std.Target.Query{ + .cpu_arch = .aarch64, + .cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_a55 }, + .os_tag = .freestanding, + .abi = .none, + }, + }, +}; + +fn findTarget(board: MicrokitBoard) std.Target.Query { + for (targets) |target| { + if (board == target.board) { + return target.zig_target; + } + } + + std.log.err("Board '{}' is not supported\n", .{board}); + std.posix.exit(1); +} + +const ConfigOptions = enum { debug, release, benchmark }; + +pub fn build(b: *std.Build) void { + const optimize = b.standardOptimizeOption(.{}); + + // Getting the path to the Microkit SDK before doing anything else + const microkit_sdk_arg = b.option([]const u8, "sdk", "Path to Microkit SDK"); + if (microkit_sdk_arg == null) { + std.log.err("Missing -Dsdk=/path/to/sdk argument being passed\n", .{}); + std.posix.exit(1); + } + const microkit_sdk = microkit_sdk_arg.?; + + const microkit_config_option = b.option(ConfigOptions, "config", "Microkit config to build for") orelse ConfigOptions.debug; + const microkit_config = @tagName(microkit_config_option); + + // Get the Microkit SDK board we want to target + const microkit_board_option = b.option(MicrokitBoard, "board", "Microkit board to target"); + + if (microkit_board_option == null) { + std.log.err("Missing -Dboard= argument being passed\n", .{}); + std.posix.exit(1); + } + const target = b.resolveTargetQuery(findTarget(microkit_board_option.?)); + const microkit_board = @tagName(microkit_board_option.?); + + const microkit_board_dir = b.fmt("{s}/board/{s}/{s}", .{ microkit_sdk, microkit_board, microkit_config }); + const microkit_tool = b.fmt("{s}/bin/microkit", .{microkit_sdk}); + const libmicrokit = b.fmt("{s}/lib/libmicrokit.a", .{microkit_board_dir}); + const libmicrokit_include = b.fmt("{s}/include", .{microkit_board_dir}); + const libmicrokit_linker_script = b.fmt("{s}/lib/microkit.ld", .{microkit_board_dir}); + + const dtb_arg = b.option([]const u8, "dtb", "Path to DTB file"); + if (dtb_arg == null) { + std.log.err("Missing -Dsdk=/path/to/dtb argument being passed\n", .{}); + std.posix.exit(1); + } + const dtb_path = std.Build.LazyPath{ .cwd_relative = dtb_arg.? }; + // TODO: Need to define this with built-in output path + const clk_conf_include = std.Build.LazyPath{ .cwd_relative = "zig-out/bin/" }; + const sddf_dep = b.dependency("sddf", .{ + .target = target, + .optimize = optimize, + .libmicrokit = @as([]const u8, libmicrokit), + .libmicrokit_include = @as([]const u8, libmicrokit_include), + .libmicrokit_linker_script = @as([]const u8, libmicrokit_linker_script), + .i2c_client_include = @as([]const u8, ""), + .clk_conf_include = @as([]const u8, clk_conf_include.getPath(b)), + .dtb_path = @as([]const u8, dtb_path.getPath(b) ), + }); + + const timer_driver_class = switch (microkit_board_option.?) { + .odroidc4 => "meson", + }; + + const clk_driver_class = switch (microkit_board_option.?) { + .odroidc4 => "meson", + }; + const clk_driver = sddf_dep.artifact(b.fmt("driver_clk_{s}.elf", .{clk_driver_class})); + const clk_driver_install = b.addInstallArtifact(clk_driver, .{ .dest_sub_path = "clk_driver.elf" }); + + const timer_driver = sddf_dep.artifact(b.fmt("driver_timer_{s}.elf", .{timer_driver_class})); + // This is required because the SDF file is expecting a different name to the artifact we + // are dealing with. + const timer_driver_install = b.addInstallArtifact(timer_driver, .{ .dest_sub_path = "timer_driver.elf" }); + + const client = b.addExecutable(.{ + .name = "client.elf", + .target = target, + .optimize = optimize, + .strip = false, + }); + client.addCSourceFile(.{ .file = b.path("client.c") }); + client.defineCMacro(b.fmt("TEST_BOARD_{s}", .{ microkit_board }), "1"); + client.addIncludePath(sddf_dep.path("include")); + client.linkLibrary(sddf_dep.artifact("util")); + client.linkLibrary(sddf_dep.artifact("util_putchar_debug")); + client.addIncludePath(.{ .cwd_relative = libmicrokit_include }); + client.addObjectFile(.{ .cwd_relative = libmicrokit }); + client.setLinkerScriptPath(.{ .cwd_relative = libmicrokit_linker_script }); + + b.installArtifact(client); + + const system_description_path = b.fmt("board/{s}/clk.system", .{microkit_board}); + const final_image_dest = b.getInstallPath(.bin, "./loader.img"); + const microkit_tool_cmd = b.addSystemCommand(&[_][]const u8{ + microkit_tool, + system_description_path, + "--search-path", b.getInstallPath(.bin, ""), + "--board", microkit_board, + "--config", microkit_config, + "-o", final_image_dest, + "-r", b.getInstallPath(.prefix, "./report.txt") }); + microkit_tool_cmd.step.dependOn(b.getInstallStep()); + microkit_tool_cmd.step.dependOn(&timer_driver_install.step); + microkit_tool_cmd.step.dependOn(&clk_driver_install.step); + const microkit_step = b.step("microkit", "Compile and build the final bootable image"); + microkit_step.dependOn(µkit_tool_cmd.step); + b.default_step = microkit_step; +} diff --git a/examples/clk/build.zig.zon b/examples/clk/build.zig.zon new file mode 100644 index 000000000..7d4f5b7eb --- /dev/null +++ b/examples/clk/build.zig.zon @@ -0,0 +1,15 @@ + +.{ + .name = "sddf_clk_example", + .version = "1.0.0", + + .dependencies = .{ + .sddf = .{ + .path = "../../" + }, + }, + .paths = .{ + "build.zig", + "build.zig.zon", + } +} diff --git a/examples/clk/client.c b/examples/clk/client.c new file mode 100644 index 000000000..7f69fd2f5 --- /dev/null +++ b/examples/clk/client.c @@ -0,0 +1,42 @@ +/* + * Copyright 2024, UNSW + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include + +#define CLK_DRIVER_CH 0 + +void init(void) +{ + sddf_dprintf("--------------------\n"); + sddf_dprintf("Clock driver test\n"); + +#ifdef TEST_BOARD_odroidc4 + sddf_dprintf("Test board: odroidc4\n"); + + uint32_t ret = sddf_clk_enable(CLK_DRIVER_CH, 10); + sddf_dprintf("ret_val: %x\n", ret); + + ret = sddf_clk_disable(CLK_DRIVER_CH, 24); + sddf_dprintf("ret_val: %x\n", ret); + + ret = sddf_clk_get_rate(CLK_DRIVER_CH, 10); + sddf_dprintf("ret_val: %x\n", ret); + + ret = sddf_clk_set_rate(CLK_DRIVER_CH, 10, 150000000); + sddf_dprintf("ret_val: %x\n", ret); +#elif + sddf_dprintf("No tests for the target board\n", ret); +#endif + + sddf_dprintf("--------------------\n"); +} + +void notified(microkit_channel ch) +{ +} diff --git a/examples/clk/dts/odroidc4.dts b/examples/clk/dts/odroidc4.dts new file mode 100644 index 000000000..8207eba92 --- /dev/null +++ b/examples/clk/dts/odroidc4.dts @@ -0,0 +1,3216 @@ +/dts-v1/; + +/ { + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + compatible = "hardkernel,odroid-c4\0amlogic,sm1"; + model = "Hardkernel ODROID-C4"; + + aliases { + mmc0 = "/soc/sd@ffe05000"; + mmc1 = "/soc/mmc@ffe07000"; + mmc2 = "/soc/sd@ffe03000"; + serial0 = "/soc/bus@ff800000/serial@3000"; + ethernet0 = "/soc/ethernet@ff3f0000"; + }; + + chosen { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + linux,stdout-path = "/soc/bus@ff800000/serial@3000"; + stdout-path = "/soc/bus@ff800000/serial@3000"; + linux,initrd-end = <0x00000000 0x2e000000>; + linux,initrd-start = <0x00000000 0x2d700000>; + bootargs = "console=ttyAML0,115200n8 root=/dev/ram0 nosmp rw debug loglevel=8 pci=nomsi earlyprintk=serial maxcpus=1"; + + framebuffer-cvbs { + compatible = "amlogic,simple-framebuffer\0simple-framebuffer"; + amlogic,pipeline = "vpu-cvbs"; + clocks = <0x02 0xa8 0x02 0x35 0x02 0x3a>; + status = "disabled"; + power-domains = <0x03 0x00>; + }; + + framebuffer-hdmi { + compatible = "amlogic,simple-framebuffer\0simple-framebuffer"; + amlogic,pipeline = "vpu-hdmi"; + clocks = <0x02 0xa8 0x02 0x35 0x02 0x3a>; + status = "disabled"; + power-domains = <0x03 0x00>; + }; + }; + + efuse { + compatible = "amlogic,meson-gxbb-efuse"; + clocks = <0x02 0x6a>; + #address-cells = <0x01>; + #size-cells = <0x01>; + read-only; + secure-monitor = <0x04>; + }; + + opp-table-gpu { + compatible = "operating-points-v2"; + phandle = <0x30>; + + opp-124999998 { + opp-hz = <0x00 0x773593e>; + opp-microvolt = <0xc3500>; + }; + + opp-249999996 { + opp-hz = <0x00 0xee6b27c>; + opp-microvolt = <0xc3500>; + }; + + opp-285714281 { + opp-hz = <0x00 0x1107a769>; + opp-microvolt = <0xc3500>; + }; + + opp-399999994 { + opp-hz = <0x00 0x17d783fa>; + opp-microvolt = <0xc3500>; + }; + + opp-499999992 { + opp-hz = <0x00 0x1dcd64f8>; + opp-microvolt = <0xc3500>; + }; + + opp-666666656 { + opp-hz = <0x00 0x27bc86a0>; + opp-microvolt = <0xc3500>; + }; + + opp-799999987 { + opp-hz = <0x00 0x2faf07f3>; + opp-microvolt = <0xc3500>; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + secmon@5000000 { + reg = <0x00 0x5000000 0x00 0x300000>; + no-map; + }; + + secmon@5300000 { + reg = <0x00 0x5300000 0x00 0x2000000>; + no-map; + }; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x00 0x1000000>; + alignment = <0x00 0x400000>; + alloc-ranges = <0x00 0x8000000 0x10000000>; + linux,cma-default; + }; + }; + + secure-monitor { + compatible = "amlogic,meson-gxbb-sm"; + phandle = <0x04>; + status = "disabled"; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + pcie@fc000000 { + compatible = "amlogic,g12a-pcie\0snps,dw-pcie"; + reg = <0x00 0xfc000000 0x00 0x400000 0x00 0xff648000 0x00 0x2000 0x00 0xfc400000 0x00 0x200000>; + reg-names = "elbi\0cfg\0config"; + interrupts = <0x00 0xdd 0x04>; + #interrupt-cells = <0x01>; + interrupt-map-mask = <0x00 0x00 0x00 0x00>; + interrupt-map = <0x00 0x00 0x00 0x00 0x01 0x00 0xdf 0x04>; + bus-range = <0x00 0xff>; + #address-cells = <0x03>; + #size-cells = <0x02>; + device_type = "pci"; + ranges = <0x81000000 0x00 0x00 0x00 0xfc600000 0x00 0x100000 0x82000000 0x00 0xfc700000 0x00 0xfc700000 0x00 0x1900000>; + clocks = <0x02 0x30 0x02 0x2d 0x02 0xc9>; + clock-names = "general\0pclk\0port"; + resets = <0x05 0x0c 0x05 0x0f>; + reset-names = "port\0apb"; + num-lanes = <0x01>; + phys = <0x06 0x02>; + phy-names = "pcie"; + status = "disabled"; + power-domains = <0x03 0x03>; + }; + + ethernet@ff3f0000 { + compatible = "amlogic,meson-g12a-dwmac\0snps,dwmac-3.70a\0snps,dwmac"; + reg = <0x00 0xff3f0000 0x00 0x10000 0x00 0xff634540 0x00 0x08>; + interrupts = <0x00 0x08 0x04>; + interrupt-names = "macirq"; + clocks = <0x02 0x26 0x02 0x02 0x02 0x0d 0x02 0x02>; + clock-names = "stmmaceth\0clkin0\0clkin1\0timing-adjustment"; + rx-fifo-depth = <0x1000>; + tx-fifo-depth = <0x800>; + status = "disabled"; + power-domains = <0x03 0x06>; + pinctrl-0 = <0x07 0x08>; + pinctrl-names = "default"; + phy-mode = "rgmii"; + phy-handle = <0x09>; + amlogic,tx-delay-ns = <0x02>; + + mdio { + #address-cells = <0x01>; + #size-cells = <0x00>; + compatible = "snps,dwmac-mdio"; + phandle = <0x13>; + }; + }; + + bus@ff600000 { + compatible = "simple-bus"; + reg = <0x00 0xff600000 0x00 0x200000>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x00 0x00 0xff600000 0x00 0x200000>; + + hdmi-tx@0 { + compatible = "amlogic,meson-g12a-dw-hdmi"; + reg = <0x00 0x00 0x00 0x10000>; + interrupts = <0x00 0x39 0x01>; + resets = <0x05 0x13 0x05 0x42 0x05 0x4f>; + reset-names = "hdmitx_apb\0hdmitx\0hdmitx_phy"; + clocks = <0x02 0xa8 0x02 0x35 0x02 0x3a>; + clock-names = "isfr\0iahb\0venci"; + #address-cells = <0x01>; + #size-cells = <0x00>; + #sound-dai-cells = <0x00>; + status = "okay"; + pinctrl-0 = <0x0a 0x0b>; + pinctrl-names = "default"; + hdmi-supply = <0x0c>; + phandle = <0x1b>; + + port@0 { + reg = <0x00>; + + endpoint { + remote-endpoint = <0x0d>; + phandle = <0x21>; + }; + }; + + port@1 { + reg = <0x01>; + + endpoint { + remote-endpoint = <0x0e>; + phandle = <0x42>; + }; + }; + }; + + bus@30000 { + compatible = "simple-bus"; + reg = <0x00 0x30000 0x00 0x2000>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x00 0x00 0x30000 0x00 0x2000>; + + rng@218 { + compatible = "amlogic,meson-rng"; + reg = <0x00 0x218 0x00 0x04>; + clocks = <0x02 0x1b>; + clock-names = "core"; + }; + }; + + audio-controller@32000 { + compatible = "amlogic,t9015"; + reg = <0x00 0x32000 0x00 0x14>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "ACODEC"; + clocks = <0x02 0x24>; + clock-names = "pclk"; + resets = <0x05 0x3d>; + status = "disabled"; + }; + + bus@34400 { + compatible = "simple-bus"; + reg = <0x00 0x34400 0x00 0x400>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x00 0x00 0x34400 0x00 0x400>; + + pinctrl@40 { + compatible = "amlogic,meson-g12a-periphs-pinctrl"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x0f>; + + bank@40 { + reg = <0x00 0x40 0x00 0x4c 0x00 0xe8 0x00 0x18 0x00 0x120 0x00 0x18 0x00 0x2c0 0x00 0x40 0x00 0x340 0x00 0x1c>; + reg-names = "gpio\0pull\0pull-enable\0mux\0ds"; + gpio-controller; + #gpio-cells = <0x02>; + gpio-ranges = <0x0f 0x00 0x00 0x56>; + gpio-line-names = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0PIN_36\0PIN_26\0PIN_32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0PIN_27\0PIN_28\0PIN_16\0PIN_18\0PIN_22\0PIN_11\0PIN_13\0PIN_7\0PIN_33\0PIN_15\0PIN_19\0PIN_21\0PIN_24\0PIN_23\0PIN_8\0PIN_10\0PIN_29\0PIN_31\0PIN_12\0PIN_3\0PIN_5\0PIN_35"; + phandle = <0x14>; + + hog-0 { + gpio-hog; + gpios = <0x14 0x00>; + output-high; + line-name = "usb-hub-reset"; + }; + }; + + cec_ao_a_h { + phandle = <0x1a>; + + mux { + groups = "cec_ao_a_h"; + function = "cec_ao_a_h"; + bias-disable; + }; + }; + + cec_ao_b_h { + phandle = <0x1c>; + + mux { + groups = "cec_ao_b_h"; + function = "cec_ao_b_h"; + bias-disable; + }; + }; + + emmc-ctrl { + phandle = <0x26>; + + mux-0 { + groups = "emmc_cmd"; + function = "emmc"; + bias-pull-up; + drive-strength-microamp = <0xfa0>; + }; + + mux-1 { + groups = "emmc_clk"; + function = "emmc"; + bias-disable; + drive-strength-microamp = <0xfa0>; + }; + }; + + emmc-data-4b { + + mux-0 { + groups = "emmc_nand_d0\0emmc_nand_d1\0emmc_nand_d2\0emmc_nand_d3"; + function = "emmc"; + bias-pull-up; + drive-strength-microamp = <0xfa0>; + }; + }; + + emmc-data-8b { + phandle = <0x27>; + + mux-0 { + groups = "emmc_nand_d0\0emmc_nand_d1\0emmc_nand_d2\0emmc_nand_d3\0emmc_nand_d4\0emmc_nand_d5\0emmc_nand_d6\0emmc_nand_d7"; + function = "emmc"; + bias-pull-up; + drive-strength-microamp = <0xfa0>; + }; + }; + + emmc-ds { + phandle = <0x28>; + + mux { + groups = "emmc_nand_ds"; + function = "emmc"; + bias-pull-down; + drive-strength-microamp = <0xfa0>; + }; + }; + + emmc_clk_gate { + phandle = <0x29>; + + mux { + groups = "BOOT_8"; + function = "gpio_periphs"; + bias-pull-down; + drive-strength-microamp = <0xfa0>; + }; + }; + + hdmitx_ddc { + phandle = <0x0b>; + + mux { + groups = "hdmitx_sda\0hdmitx_sck"; + function = "hdmitx"; + bias-disable; + drive-strength-microamp = <0xfa0>; + }; + }; + + hdmitx_hpd { + phandle = <0x0a>; + + mux { + groups = "hdmitx_hpd_in"; + function = "hdmitx"; + bias-disable; + }; + }; + + i2c0-sda-c { + + mux { + groups = "i2c0_sda_c"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c0-sck-c { + + mux { + groups = "i2c0_sck_c"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c0-sda-z0 { + + mux { + groups = "i2c0_sda_z0"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c0-sck-z1 { + + mux { + groups = "i2c0_sck_z1"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c0-sda-z7 { + + mux { + groups = "i2c0_sda_z7"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c0-sda-z8 { + + mux { + groups = "i2c0_sda_z8"; + function = "i2c0"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c1-sda-x { + + mux { + groups = "i2c1_sda_x"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c1-sck-x { + + mux { + groups = "i2c1_sck_x"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c1-sda-h2 { + + mux { + groups = "i2c1_sda_h2"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c1-sck-h3 { + + mux { + groups = "i2c1_sck_h3"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c1-sda-h6 { + + mux { + groups = "i2c1_sda_h6"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c1-sck-h7 { + + mux { + groups = "i2c1_sck_h7"; + function = "i2c1"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c2-sda-x { + + mux { + groups = "i2c2_sda_x"; + function = "i2c2"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c2-sck-x { + + mux { + groups = "i2c2_sck_x"; + function = "i2c2"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c2-sda-z { + + mux { + groups = "i2c2_sda_z"; + function = "i2c2"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c2-sck-z { + + mux { + groups = "i2c2_sck_z"; + function = "i2c2"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c3-sda-h { + + mux { + groups = "i2c3_sda_h"; + function = "i2c3"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c3-sck-h { + + mux { + groups = "i2c3_sck_h"; + function = "i2c3"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c3-sda-a { + + mux { + groups = "i2c3_sda_a"; + function = "i2c3"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c3-sck-a { + + mux { + groups = "i2c3_sck_a"; + function = "i2c3"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + mclk0-a { + + mux { + groups = "mclk0_a"; + function = "mclk0"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + mclk1-a { + + mux { + groups = "mclk1_a"; + function = "mclk1"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + mclk1-x { + + mux { + groups = "mclk1_x"; + function = "mclk1"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + mclk1-z { + + mux { + groups = "mclk1_z"; + function = "mclk1"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + nor { + + mux { + groups = "nor_d\0nor_q\0nor_c\0nor_cs"; + function = "nor"; + bias-disable; + }; + }; + + pdm-din0-a { + + mux { + groups = "pdm_din0_a"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din0-c { + + mux { + groups = "pdm_din0_c"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din0-x { + + mux { + groups = "pdm_din0_x"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din0-z { + + mux { + groups = "pdm_din0_z"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din1-a { + + mux { + groups = "pdm_din1_a"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din1-c { + + mux { + groups = "pdm_din1_c"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din1-x { + + mux { + groups = "pdm_din1_x"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din1-z { + + mux { + groups = "pdm_din1_z"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din2-a { + + mux { + groups = "pdm_din2_a"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din2-c { + + mux { + groups = "pdm_din2_c"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din2-x { + + mux { + groups = "pdm_din2_x"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din2-z { + + mux { + groups = "pdm_din2_z"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din3-a { + + mux { + groups = "pdm_din3_a"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din3-c { + + mux { + groups = "pdm_din3_c"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din3-x { + + mux { + groups = "pdm_din3_x"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-din3-z { + + mux { + groups = "pdm_din3_z"; + function = "pdm"; + bias-disable; + }; + }; + + pdm-dclk-a { + + mux { + groups = "pdm_dclk_a"; + function = "pdm"; + bias-disable; + drive-strength-microamp = <0x1f4>; + }; + }; + + pdm-dclk-c { + + mux { + groups = "pdm_dclk_c"; + function = "pdm"; + bias-disable; + drive-strength-microamp = <0x1f4>; + }; + }; + + pdm-dclk-x { + + mux { + groups = "pdm_dclk_x"; + function = "pdm"; + bias-disable; + drive-strength-microamp = <0x1f4>; + }; + }; + + pdm-dclk-z { + + mux { + groups = "pdm_dclk_z"; + function = "pdm"; + bias-disable; + drive-strength-microamp = <0x1f4>; + }; + }; + + pwm-a { + + mux { + groups = "pwm_a"; + function = "pwm_a"; + bias-disable; + }; + }; + + pwm-b-x7 { + + mux { + groups = "pwm_b_x7"; + function = "pwm_b"; + bias-disable; + }; + }; + + pwm-b-x19 { + + mux { + groups = "pwm_b_x19"; + function = "pwm_b"; + bias-disable; + }; + }; + + pwm-c-c { + + mux { + groups = "pwm_c_c"; + function = "pwm_c"; + bias-disable; + }; + }; + + pwm-c-x5 { + + mux { + groups = "pwm_c_x5"; + function = "pwm_c"; + bias-disable; + }; + }; + + pwm-c-x8 { + + mux { + groups = "pwm_c_x8"; + function = "pwm_c"; + bias-disable; + }; + }; + + pwm-d-x3 { + + mux { + groups = "pwm_d_x3"; + function = "pwm_d"; + bias-disable; + }; + }; + + pwm-d-x6 { + + mux { + groups = "pwm_d_x6"; + function = "pwm_d"; + bias-disable; + }; + }; + + pwm-e { + + mux { + groups = "pwm_e"; + function = "pwm_e"; + bias-disable; + }; + }; + + pwm-f-z { + + mux { + groups = "pwm_f_z"; + function = "pwm_f"; + bias-disable; + }; + }; + + pwm-f-a { + + mux { + groups = "pwm_f_a"; + function = "pwm_f"; + bias-disable; + }; + }; + + pwm-f-x { + + mux { + groups = "pwm_f_x"; + function = "pwm_f"; + bias-disable; + }; + }; + + pwm-f-h { + + mux { + groups = "pwm_f_h"; + function = "pwm_f"; + bias-disable; + }; + }; + + sdcard_c { + phandle = <0x22>; + + mux-0 { + groups = "sdcard_d0_c\0sdcard_d1_c\0sdcard_d2_c\0sdcard_d3_c\0sdcard_cmd_c"; + function = "sdcard"; + bias-pull-up; + drive-strength-microamp = <0xfa0>; + }; + + mux-1 { + groups = "sdcard_clk_c"; + function = "sdcard"; + bias-disable; + drive-strength-microamp = <0xfa0>; + }; + }; + + sdcard_clk_gate_c { + phandle = <0x23>; + + mux { + groups = "GPIOC_4"; + function = "gpio_periphs"; + bias-pull-down; + drive-strength-microamp = <0xfa0>; + }; + }; + + sdcard_z { + + mux-0 { + groups = "sdcard_d0_z\0sdcard_d1_z\0sdcard_d2_z\0sdcard_d3_z\0sdcard_cmd_z"; + function = "sdcard"; + bias-pull-up; + drive-strength-microamp = <0xfa0>; + }; + + mux-1 { + groups = "sdcard_clk_z"; + function = "sdcard"; + bias-disable; + drive-strength-microamp = <0xfa0>; + }; + }; + + sdcard_clk_gate_z { + + mux { + groups = "GPIOZ_6"; + function = "gpio_periphs"; + bias-pull-down; + drive-strength-microamp = <0xfa0>; + }; + }; + + sdio { + + mux { + groups = "sdio_d0\0sdio_d1\0sdio_d2\0sdio_d3\0sdio_clk\0sdio_cmd"; + function = "sdio"; + bias-disable; + drive-strength-microamp = <0xfa0>; + }; + }; + + sdio_clk_gate { + + mux { + groups = "GPIOX_4"; + function = "gpio_periphs"; + bias-pull-down; + drive-strength-microamp = <0xfa0>; + }; + }; + + spdif-in-a10 { + + mux { + groups = "spdif_in_a10"; + function = "spdif_in"; + bias-disable; + }; + }; + + spdif-in-a12 { + + mux { + groups = "spdif_in_a12"; + function = "spdif_in"; + bias-disable; + }; + }; + + spdif-in-h { + + mux { + groups = "spdif_in_h"; + function = "spdif_in"; + bias-disable; + }; + }; + + spdif-out-h { + + mux { + groups = "spdif_out_h"; + function = "spdif_out"; + drive-strength-microamp = <0x1f4>; + bias-disable; + }; + }; + + spdif-out-a11 { + + mux { + groups = "spdif_out_a11"; + function = "spdif_out"; + drive-strength-microamp = <0x1f4>; + bias-disable; + }; + }; + + spdif-out-a13 { + + mux { + groups = "spdif_out_a13"; + function = "spdif_out"; + drive-strength-microamp = <0x1f4>; + bias-disable; + }; + }; + + spicc0-x { + + mux { + groups = "spi0_mosi_x\0spi0_miso_x\0spi0_clk_x"; + function = "spi0"; + drive-strength-microamp = <0xfa0>; + bias-disable; + }; + }; + + spicc0-ss0-x { + + mux { + groups = "spi0_ss0_x"; + function = "spi0"; + drive-strength-microamp = <0xfa0>; + bias-disable; + }; + }; + + spicc0-c { + + mux { + groups = "spi0_mosi_c\0spi0_miso_c\0spi0_ss0_c\0spi0_clk_c"; + function = "spi0"; + drive-strength-microamp = <0xfa0>; + bias-disable; + }; + }; + + spicc1 { + + mux { + groups = "spi1_mosi\0spi1_miso\0spi1_clk"; + function = "spi1"; + drive-strength-microamp = <0xfa0>; + }; + }; + + spicc1-ss0 { + + mux { + groups = "spi1_ss0"; + function = "spi1"; + drive-strength-microamp = <0xfa0>; + bias-disable; + }; + }; + + tdm-a-din0 { + + mux { + groups = "tdm_a_din0"; + function = "tdm_a"; + bias-disable; + }; + }; + + tdm-a-din1 { + + mux { + groups = "tdm_a_din1"; + function = "tdm_a"; + bias-disable; + }; + }; + + tdm-a-dout0 { + + mux { + groups = "tdm_a_dout0"; + function = "tdm_a"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-a-dout1 { + + mux { + groups = "tdm_a_dout1"; + function = "tdm_a"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-a-fs { + + mux { + groups = "tdm_a_fs"; + function = "tdm_a"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-a-sclk { + + mux { + groups = "tdm_a_sclk"; + function = "tdm_a"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-a-slv-fs { + + mux { + groups = "tdm_a_slv_fs"; + function = "tdm_a"; + bias-disable; + }; + }; + + tdm-a-slv-sclk { + + mux { + groups = "tdm_a_slv_sclk"; + function = "tdm_a"; + bias-disable; + }; + }; + + tdm-b-din0 { + + mux { + groups = "tdm_b_din0"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm-b-din1 { + + mux { + groups = "tdm_b_din1"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm-b-din2 { + + mux { + groups = "tdm_b_din2"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm-b-din3-a { + + mux { + groups = "tdm_b_din3_a"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm-b-din3-h { + + mux { + groups = "tdm_b_din3_h"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm-b-dout0 { + + mux { + groups = "tdm_b_dout0"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-b-dout1 { + + mux { + groups = "tdm_b_dout1"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-b-dout2 { + + mux { + groups = "tdm_b_dout2"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-b-dout3-a { + + mux { + groups = "tdm_b_dout3_a"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-b-dout3-h { + + mux { + groups = "tdm_b_dout3_h"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-b-fs { + + mux { + groups = "tdm_b_fs"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-b-sclk { + + mux { + groups = "tdm_b_sclk"; + function = "tdm_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-b-slv-fs { + + mux { + groups = "tdm_b_slv_fs"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm-b-slv-sclk { + + mux { + groups = "tdm_b_slv_sclk"; + function = "tdm_b"; + bias-disable; + }; + }; + + tdm-c-din0-a { + + mux { + groups = "tdm_c_din0_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm-c-din0-z { + + mux { + groups = "tdm_c_din0_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm-c-din1-a { + + mux { + groups = "tdm_c_din1_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm-c-din1-z { + + mux { + groups = "tdm_c_din1_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm-c-din2-a { + + mux { + groups = "tdm_c_din2_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + eth-leds { + + mux { + groups = "eth_link_led\0eth_act_led"; + function = "eth"; + bias-disable; + }; + }; + + eth { + phandle = <0x07>; + + mux { + groups = "eth_mdio\0eth_mdc\0eth_rgmii_rx_clk\0eth_rx_dv\0eth_rxd0\0eth_rxd1\0eth_txen\0eth_txd0\0eth_txd1"; + function = "eth"; + drive-strength-microamp = <0xfa0>; + bias-disable; + }; + }; + + eth-rgmii { + phandle = <0x08>; + + mux { + groups = "eth_rxd2_rgmii\0eth_rxd3_rgmii\0eth_rgmii_tx_clk\0eth_txd2_rgmii\0eth_txd3_rgmii"; + function = "eth"; + drive-strength-microamp = <0xfa0>; + bias-disable; + }; + }; + + tdm-c-din2-z { + + mux { + groups = "tdm_c_din2_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm-c-din3-a { + + mux { + groups = "tdm_c_din3_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm-c-din3-z { + + mux { + groups = "tdm_c_din3_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm-c-dout0-a { + + mux { + groups = "tdm_c_dout0_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-dout0-z { + + mux { + groups = "tdm_c_dout0_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-dout1-a { + + mux { + groups = "tdm_c_dout1_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-dout1-z { + + mux { + groups = "tdm_c_dout1_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-dout2-a { + + mux { + groups = "tdm_c_dout2_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-dout2-z { + + mux { + groups = "tdm_c_dout2_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-dout3-a { + + mux { + groups = "tdm_c_dout3_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-dout3-z { + + mux { + groups = "tdm_c_dout3_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-fs-a { + + mux { + groups = "tdm_c_fs_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-fs-z { + + mux { + groups = "tdm_c_fs_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-sclk-a { + + mux { + groups = "tdm_c_sclk_a"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-sclk-z { + + mux { + groups = "tdm_c_sclk_z"; + function = "tdm_c"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-c-slv-fs-a { + + mux { + groups = "tdm_c_slv_fs_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm-c-slv-fs-z { + + mux { + groups = "tdm_c_slv_fs_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm-c-slv-sclk-a { + + mux { + groups = "tdm_c_slv_sclk_a"; + function = "tdm_c"; + bias-disable; + }; + }; + + tdm-c-slv-sclk-z { + + mux { + groups = "tdm_c_slv_sclk_z"; + function = "tdm_c"; + bias-disable; + }; + }; + + uart-a { + + mux { + groups = "uart_a_tx\0uart_a_rx"; + function = "uart_a"; + bias-disable; + }; + }; + + uart-a-cts-rts { + + mux { + groups = "uart_a_cts\0uart_a_rts"; + function = "uart_a"; + bias-disable; + }; + }; + + uart-b { + + mux { + groups = "uart_b_tx\0uart_b_rx"; + function = "uart_b"; + bias-disable; + }; + }; + + uart-c { + + mux { + groups = "uart_c_tx\0uart_c_rx"; + function = "uart_c"; + bias-disable; + }; + }; + + uart-c-cts-rts { + + mux { + groups = "uart_c_cts\0uart_c_rts"; + function = "uart_c"; + bias-disable; + }; + }; + }; + }; + + temperature-sensor@34800 { + compatible = "amlogic,g12a-cpu-thermal\0amlogic,g12a-thermal"; + reg = <0x00 0x34800 0x00 0x50>; + interrupts = <0x00 0x23 0x01>; + clocks = <0x02 0xd4>; + #thermal-sensor-cells = <0x00>; + amlogic,ao-secure = <0x10>; + phandle = <0x31>; + }; + + temperature-sensor@34c00 { + compatible = "amlogic,g12a-ddr-thermal\0amlogic,g12a-thermal"; + reg = <0x00 0x34c00 0x00 0x50>; + interrupts = <0x00 0x24 0x01>; + clocks = <0x02 0xd4>; + #thermal-sensor-cells = <0x00>; + amlogic,ao-secure = <0x10>; + phandle = <0x38>; + }; + + phy@36000 { + compatible = "amlogic,g12a-usb2-phy"; + reg = <0x00 0x36000 0x00 0x2000>; + clocks = <0x11>; + clock-names = "xtal"; + resets = <0x05 0x30>; + reset-names = "phy"; + #phy-cells = <0x00>; + phy-supply = <0x0c>; + phandle = <0x2d>; + }; + + bus@38000 { + compatible = "simple-bus"; + reg = <0x00 0x38000 0x00 0x400>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x00 0x00 0x38000 0x00 0x400>; + + video-lut@48 { + compatible = "amlogic,canvas"; + reg = <0x00 0x48 0x00 0x14>; + phandle = <0x20>; + }; + }; + + phy@3a000 { + compatible = "amlogic,g12a-usb2-phy"; + reg = <0x00 0x3a000 0x00 0x2000>; + clocks = <0x11>; + clock-names = "xtal"; + resets = <0x05 0x31>; + reset-names = "phy"; + #phy-cells = <0x00>; + phandle = <0x2e>; + }; + + bus@3c000 { + compatible = "simple-bus"; + reg = <0x00 0x3c000 0x00 0x1400>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x00 0x00 0x3c000 0x00 0x1400>; + + system-controller@0 { + compatible = "amlogic,meson-gx-hhi-sysctrl\0simple-mfd\0syscon"; + reg = <0x00 0x00 0x00 0x400>; + + clock-controller { + compatible = "amlogic,sm1-clkc"; + #clock-cells = <0x01>; + clocks = <0x11>; + clock-names = "xtal"; + phandle = <0x02>; + }; + + power-controller { + compatible = "amlogic,meson-sm1-pwrc"; + #power-domain-cells = <0x01>; + amlogic,ao-sysctrl = <0x12>; + resets = <0x05 0x05 0x05 0x0a 0x05 0x0d 0x05 0x25 0x05 0x85 0x05 0x86 0x05 0x87 0x05 0x89 0x05 0x8c 0x05 0x8d 0x05 0xe7>; + reset-names = "viu\0venc\0vcbus\0bt656\0rdma\0venci\0vencp\0vdac\0vdi6\0vencl\0vid_lock"; + clocks = <0x02 0x74 0x02 0x7c>; + clock-names = "vpu\0vapb"; + assigned-clocks = <0x02 0x6e 0x02 0x70 0x02 0x74 0x02 0x75 0x02 0x77 0x02 0x7b>; + assigned-clock-parents = <0x02 0x03 0x00 0x02 0x70 0x02 0x04 0x00 0x02 0x77>; + assigned-clock-rates = <0x00 0x27bc86aa 0x00 0x00 0xee6b280 0x00>; + phandle = <0x03>; + }; + }; + }; + + phy@46000 { + compatible = "amlogic,g12a-usb3-pcie-phy"; + reg = <0x00 0x46000 0x00 0x2000>; + clocks = <0x02 0xc9>; + clock-names = "ref_clk"; + resets = <0x05 0x0e>; + reset-names = "phy"; + assigned-clocks = <0x02 0xc9>; + assigned-clock-rates = <0x5f5e100>; + #phy-cells = <0x01>; + phandle = <0x06>; + }; + + mdio-multiplexer@4c000 { + compatible = "amlogic,g12a-mdio-mux"; + reg = <0x00 0x4c000 0x00 0xa4>; + clocks = <0x02 0x13 0x11 0x02 0xb1>; + clock-names = "pclk\0clkin0\0clkin1"; + mdio-parent-bus = <0x13>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + mdio@0 { + reg = <0x00>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + ethernet-phy@0 { + reg = <0x00>; + max-speed = <0x3e8>; + reset-assert-us = <0x2710>; + reset-deassert-us = <0x13880>; + reset-gpios = <0x14 0x0f 0x07>; + interrupt-parent = <0x15>; + interrupts = <0x1a 0x08>; + phandle = <0x09>; + }; + }; + + mdio@1 { + reg = <0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + + ethernet_phy@8 { + compatible = "ethernet-phy-id0180.3301\0ethernet-phy-ieee802.3-c22"; + interrupts = <0x00 0x09 0x04>; + reg = <0x08>; + max-speed = <0x64>; + }; + }; + }; + + bus@60000 { + compatible = "simple-bus"; + reg = <0x00 0x60000 0x00 0x1000>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x00 0x00 0x60000 0x00 0x1000>; + + clock-controller@0 { + status = "okay"; + compatible = "amlogic,sm1-audio-clkc"; + reg = <0x00 0x00 0x00 0xb4>; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + clocks = <0x02 0x25 0x02 0x0b 0x02 0x0c 0x02 0x0d 0x02 0x0e 0x02 0x4a 0x02 0x03 0x02 0x04 0x02 0x05>; + clock-names = "pclk\0mst_in0\0mst_in1\0mst_in2\0mst_in3\0mst_in4\0mst_in5\0mst_in6\0mst_in7"; + resets = <0x05 0x41>; + phandle = <0x16>; + }; + + audio-controller@100 { + compatible = "amlogic,sm1-toddr\0amlogic,axg-toddr"; + reg = <0x00 0x100 0x00 0x2c>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "TODDR_A"; + interrupts = <0x00 0x94 0x01>; + clocks = <0x16 0x29>; + resets = <0x17 0x00 0x16 0x06>; + reset-names = "arb\0rst"; + amlogic,fifo-depth = <0x2000>; + status = "disabled"; + }; + + audio-controller@140 { + compatible = "amlogic,sm1-toddr\0amlogic,axg-toddr"; + reg = <0x00 0x140 0x00 0x2c>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "TODDR_B"; + interrupts = <0x00 0x95 0x01>; + clocks = <0x16 0x2a>; + resets = <0x17 0x01 0x16 0x07>; + reset-names = "arb\0rst"; + amlogic,fifo-depth = <0x100>; + status = "disabled"; + }; + + audio-controller@180 { + compatible = "amlogic,sm1-toddr\0amlogic,axg-toddr"; + reg = <0x00 0x180 0x00 0x2c>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "TODDR_C"; + interrupts = <0x00 0x96 0x01>; + clocks = <0x16 0x2b>; + resets = <0x17 0x02 0x16 0x08>; + reset-names = "arb\0rst"; + amlogic,fifo-depth = <0x100>; + status = "disabled"; + }; + + audio-controller@1c0 { + compatible = "amlogic,sm1-frddr\0amlogic,axg-frddr"; + reg = <0x00 0x1c0 0x00 0x2c>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "FRDDR_A"; + interrupts = <0x00 0x98 0x01>; + clocks = <0x16 0x26>; + resets = <0x17 0x03 0x16 0x09>; + reset-names = "arb\0rst"; + amlogic,fifo-depth = <0x200>; + status = "okay"; + phandle = <0x44>; + }; + + audio-controller@200 { + compatible = "amlogic,sm1-frddr\0amlogic,axg-frddr"; + reg = <0x00 0x200 0x00 0x2c>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "FRDDR_B"; + interrupts = <0x00 0x99 0x01>; + clocks = <0x16 0x27>; + resets = <0x17 0x04 0x16 0x0a>; + reset-names = "arb\0rst"; + amlogic,fifo-depth = <0x100>; + status = "okay"; + phandle = <0x45>; + }; + + audio-controller@240 { + compatible = "amlogic,sm1-frddr\0amlogic,axg-frddr"; + reg = <0x00 0x240 0x00 0x2c>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "FRDDR_C"; + interrupts = <0x00 0x9a 0x01>; + clocks = <0x16 0x28>; + resets = <0x17 0x05 0x16 0x0b>; + reset-names = "arb\0rst"; + amlogic,fifo-depth = <0x100>; + status = "okay"; + phandle = <0x46>; + }; + + reset-controller@280 { + status = "okay"; + compatible = "amlogic,meson-sm1-audio-arb"; + reg = <0x00 0x280 0x00 0x04>; + #reset-cells = <0x01>; + clocks = <0x16 0x1d>; + phandle = <0x17>; + }; + + audio-controller@300 { + compatible = "amlogic,sm1-tdmin\0amlogic,axg-tdmin"; + reg = <0x00 0x300 0x00 0x40>; + sound-name-prefix = "TDMIN_A"; + resets = <0x16 0x01>; + clocks = <0x16 0x1f 0x16 0x7b 0x16 0x74 0x16 0x82 0x16 0x82>; + clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; + status = "disabled"; + }; + + audio-controller@340 { + compatible = "amlogic,sm1-tdmin\0amlogic,axg-tdmin"; + reg = <0x00 0x340 0x00 0x40>; + sound-name-prefix = "TDMIN_B"; + resets = <0x16 0x02>; + clocks = <0x16 0x20 0x16 0x7c 0x16 0x75 0x16 0x83 0x16 0x83>; + clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; + status = "disabled"; + }; + + audio-controller@380 { + compatible = "amlogic,sm1-tdmin\0amlogic,axg-tdmin"; + reg = <0x00 0x380 0x00 0x40>; + sound-name-prefix = "TDMIN_C"; + resets = <0x16 0x03>; + clocks = <0x16 0x21 0x16 0x7d 0x16 0x76 0x16 0x84 0x16 0x84>; + clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; + status = "disabled"; + }; + + audio-controller@3c0 { + compatible = "amlogic,sm1-tdmin\0amlogic,axg-tdmin"; + reg = <0x00 0x3c0 0x00 0x40>; + sound-name-prefix = "TDMIN_LB"; + resets = <0x16 0x04>; + clocks = <0x16 0x22 0x16 0x7e 0x16 0x77 0x16 0x85 0x16 0x85>; + clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; + status = "disabled"; + }; + + audio-controller@400 { + compatible = "amlogic,g12a-spdifin\0amlogic,axg-spdifin"; + reg = <0x00 0x400 0x00 0x30>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "SPDIFIN"; + interrupts = <0x00 0x97 0x01>; + clocks = <0x16 0x2d 0x16 0x38>; + clock-names = "pclk\0refclk"; + resets = <0x16 0x11>; + status = "disabled"; + }; + + audio-controller@480 { + compatible = "amlogic,g12a-spdifout\0amlogic,axg-spdifout"; + reg = <0x00 0x480 0x00 0x50>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "SPDIFOUT_A"; + clocks = <0x16 0x2e 0x16 0x37>; + clock-names = "pclk\0mclk"; + resets = <0x16 0x0f>; + status = "disabled"; + }; + + audio-controller@500 { + compatible = "amlogic,sm1-tdmout"; + reg = <0x00 0x500 0x00 0x40>; + sound-name-prefix = "TDMOUT_A"; + resets = <0x16 0x0c>; + clocks = <0x16 0x23 0x16 0x7f 0x16 0x78 0x16 0x86 0x16 0x86>; + clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; + status = "disabled"; + }; + + audio-controller@540 { + compatible = "amlogic,sm1-tdmout"; + reg = <0x00 0x540 0x00 0x40>; + sound-name-prefix = "TDMOUT_B"; + resets = <0x16 0x0d>; + clocks = <0x16 0x24 0x16 0x80 0x16 0x79 0x16 0x87 0x16 0x87>; + clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; + status = "okay"; + phandle = <0x43>; + }; + + audio-controller@580 { + compatible = "amlogic,sm1-tdmout"; + reg = <0x00 0x580 0x00 0x40>; + sound-name-prefix = "TDMOUT_C"; + resets = <0x16 0x0e>; + clocks = <0x16 0x25 0x16 0x81 0x16 0x7a 0x16 0x88 0x16 0x88>; + clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; + status = "disabled"; + }; + + audio-controller@740 { + compatible = "amlogic,sm1-toacodec\0amlogic,g12a-toacodec"; + reg = <0x00 0x740 0x00 0x04>; + #sound-dai-cells = <0x01>; + sound-name-prefix = "TOACODEC"; + resets = <0x16 0x17>; + status = "disabled"; + }; + + audio-controller@744 { + compatible = "amlogic,sm1-tohdmitx\0amlogic,g12a-tohdmitx"; + reg = <0x00 0x744 0x00 0x04>; + #sound-dai-cells = <0x01>; + sound-name-prefix = "TOHDMITX"; + resets = <0x16 0x18>; + status = "okay"; + phandle = <0x48>; + }; + + audio-controller@840 { + compatible = "amlogic,sm1-toddr\0amlogic,axg-toddr"; + reg = <0x00 0x840 0x00 0x2c>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "TODDR_D"; + interrupts = <0x00 0x31 0x01>; + clocks = <0x16 0xab>; + resets = <0x17 0x06 0x16 0x21>; + reset-names = "arb\0rst"; + amlogic,fifo-depth = <0x100>; + status = "disabled"; + }; + + audio-controller@880 { + compatible = "amlogic,sm1-frddr\0amlogic,axg-frddr"; + reg = <0x00 0x880 0x00 0x2c>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "FRDDR_D"; + interrupts = <0x00 0x32 0x01>; + clocks = <0x16 0xaa>; + resets = <0x17 0x07 0x16 0x20>; + reset-names = "arb\0rst"; + amlogic,fifo-depth = <0x100>; + status = "disabled"; + }; + }; + + audio-controller@61000 { + compatible = "amlogic,sm1-pdm\0amlogic,axg-pdm"; + reg = <0x00 0x61000 0x00 0x34>; + #sound-dai-cells = <0x00>; + sound-name-prefix = "PDM"; + clocks = <0x16 0x1e 0x16 0x39 0x16 0x3a>; + clock-names = "pclk\0dclk\0sysclk"; + resets = <0x16 0x00>; + status = "disabled"; + }; + }; + + bus@ff800000 { + compatible = "simple-bus"; + reg = <0x00 0xff800000 0x00 0x100000>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x00 0x00 0xff800000 0x00 0x100000>; + + sys-ctrl@0 { + compatible = "amlogic,meson-gx-ao-sysctrl\0simple-mfd\0syscon"; + reg = <0x00 0x00 0x00 0x100>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x00 0x00 0x00 0x00 0x100>; + phandle = <0x12>; + + clock-controller { + compatible = "amlogic,meson-g12a-aoclkc"; + #clock-cells = <0x01>; + #reset-cells = <0x01>; + clocks = <0x11 0x02 0x0a>; + clock-names = "xtal\0mpeg-clk"; + phandle = <0x19>; + }; + + pinctrl@14 { + compatible = "amlogic,meson-g12a-aobus-pinctrl"; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + phandle = <0x18>; + + bank@14 { + reg = <0x00 0x14 0x00 0x08 0x00 0x1c 0x00 0x08 0x00 0x24 0x00 0x14>; + reg-names = "mux\0ds\0gpio"; + gpio-controller; + #gpio-cells = <0x02>; + gpio-ranges = <0x18 0x00 0x00 0x0f>; + gpio-line-names = "\0\0\0\0PIN_47\0\0\0PIN_45\0PIN_46\0PIN_44\0PIN_42\0\0\0\0"; + phandle = <0x3e>; + }; + + i2c_ao_sck_pins { + + mux { + groups = "i2c_ao_sck"; + function = "i2c_ao"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c_ao_sda { + + mux { + groups = "i2c_ao_sda"; + function = "i2c_ao"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c_ao_sck_e { + + mux { + groups = "i2c_ao_sck_e"; + function = "i2c_ao"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + i2c_ao_sda_e { + + mux { + groups = "i2c_ao_sda_e"; + function = "i2c_ao"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + mclk0-ao { + + mux { + groups = "mclk0_ao"; + function = "mclk0_ao"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-ao-b-din0 { + + mux { + groups = "tdm_ao_b_din0"; + function = "tdm_ao_b"; + bias-disable; + }; + }; + + spdif-ao-out { + + mux { + groups = "spdif_ao_out"; + function = "spdif_ao_out"; + drive-strength-microamp = <0x1f4>; + bias-disable; + }; + }; + + tdm-ao-b-din1 { + + mux { + groups = "tdm_ao_b_din1"; + function = "tdm_ao_b"; + bias-disable; + }; + }; + + tdm-ao-b-din2 { + + mux { + groups = "tdm_ao_b_din2"; + function = "tdm_ao_b"; + bias-disable; + }; + }; + + tdm-ao-b-dout0 { + + mux { + groups = "tdm_ao_b_dout0"; + function = "tdm_ao_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-ao-b-dout1 { + + mux { + groups = "tdm_ao_b_dout1"; + function = "tdm_ao_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-ao-b-dout2 { + + mux { + groups = "tdm_ao_b_dout2"; + function = "tdm_ao_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-ao-b-fs { + + mux { + groups = "tdm_ao_b_fs"; + function = "tdm_ao_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-ao-b-sclk { + + mux { + groups = "tdm_ao_b_sclk"; + function = "tdm_ao_b"; + bias-disable; + drive-strength-microamp = <0xbb8>; + }; + }; + + tdm-ao-b-slv-fs { + + mux { + groups = "tdm_ao_b_slv_fs"; + function = "tdm_ao_b"; + bias-disable; + }; + }; + + tdm-ao-b-slv-sclk { + + mux { + groups = "tdm_ao_b_slv_sclk"; + function = "tdm_ao_b"; + bias-disable; + }; + }; + + uart-a-ao { + phandle = <0x1e>; + + mux { + groups = "uart_ao_a_tx\0uart_ao_a_rx"; + function = "uart_ao_a"; + bias-disable; + }; + }; + + uart-ao-a-cts-rts { + + mux { + groups = "uart_ao_a_cts\0uart_ao_a_rts"; + function = "uart_ao_a"; + bias-disable; + }; + }; + + uart-ao-b-2-3 { + + mux { + groups = "uart_ao_b_tx_2\0uart_ao_b_rx_3"; + function = "uart_ao_b"; + bias-disable; + }; + }; + + uart-ao-b-8-9 { + + mux { + groups = "uart_ao_b_tx_8\0uart_ao_b_rx_9"; + function = "uart_ao_b"; + bias-disable; + }; + }; + + uart-ao-b-cts-rts { + + mux { + groups = "uart_ao_b_cts\0uart_ao_b_rts"; + function = "uart_ao_b"; + bias-disable; + }; + }; + + pwm-a-e { + + mux { + groups = "pwm_a_e"; + function = "pwm_a_e"; + bias-disable; + }; + }; + + pwm-ao-a { + + mux { + groups = "pwm_ao_a"; + function = "pwm_ao_a"; + bias-disable; + }; + }; + + pwm-ao-b { + + mux { + groups = "pwm_ao_b"; + function = "pwm_ao_b"; + bias-disable; + }; + }; + + pwm-ao-c-4 { + + mux { + groups = "pwm_ao_c_4"; + function = "pwm_ao_c"; + bias-disable; + }; + }; + + pwm-ao-c-6 { + + mux { + groups = "pwm_ao_c_6"; + function = "pwm_ao_c"; + bias-disable; + }; + }; + + pwm-ao-d-5 { + + mux { + groups = "pwm_ao_d_5"; + function = "pwm_ao_d"; + bias-disable; + }; + }; + + pwm-ao-d-10 { + + mux { + groups = "pwm_ao_d_10"; + function = "pwm_ao_d"; + bias-disable; + }; + }; + + pwm-ao-d-e { + phandle = <0x1d>; + + mux { + groups = "pwm_ao_d_e"; + function = "pwm_ao_d"; + }; + }; + + remote-input-ao { + phandle = <0x1f>; + + mux { + groups = "remote_ao_input"; + function = "remote_ao_input"; + bias-disable; + }; + }; + }; + }; + + rtc@a8 { + compatible = "amlogic,meson-vrtc"; + reg = <0x00 0xa8 0x00 0x04>; + }; + + cec@100 { + compatible = "amlogic,meson-gx-ao-cec"; + reg = <0x00 0x100 0x00 0x14>; + interrupts = <0x00 0xc7 0x01>; + clocks = <0x19 0x1b>; + clock-names = "core"; + status = "disabled"; + pinctrl-0 = <0x1a>; + pinctrl-names = "default"; + hdmi-phandle = <0x1b>; + }; + + ao-secure@140 { + compatible = "amlogic,meson-gx-ao-secure\0syscon"; + reg = <0x00 0x140 0x00 0x140>; + amlogic,has-chip-id; + phandle = <0x10>; + status = "disabled"; + }; + + cec@280 { + compatible = "amlogic,meson-sm1-ao-cec"; + reg = <0x00 0x280 0x00 0x1c>; + interrupts = <0x00 0xcb 0x01>; + clocks = <0x19 0x13>; + clock-names = "oscin"; + status = "okay"; + pinctrl-0 = <0x1c>; + pinctrl-names = "default"; + hdmi-phandle = <0x1b>; + }; + + pwm@2000 { + compatible = "amlogic,meson-g12a-ao-pwm-cd"; + reg = <0x00 0x2000 0x00 0x20>; + #pwm-cells = <0x03>; + status = "okay"; + pinctrl-0 = <0x1d>; + pinctrl-names = "default"; + clocks = <0x11>; + clock-names = "clkin1"; + phandle = <0x41>; + }; + + serial@3000 { + compatible = "amlogic,meson-gx-uart\0amlogic,meson-ao-uart"; + reg = <0x00 0x3000 0x00 0x18>; + interrupts = <0x00 0xc1 0x01>; + clocks = <0x11 0x19 0x04 0x11>; + clock-names = "xtal\0pclk\0baud"; + status = "okay"; + pinctrl-0 = <0x1e>; + pinctrl-names = "default"; + }; + + serial@4000 { + compatible = "amlogic,meson-gx-uart\0amlogic,meson-ao-uart"; + reg = <0x00 0x4000 0x00 0x18>; + interrupts = <0x00 0xc5 0x01>; + clocks = <0x11 0x19 0x06 0x11>; + clock-names = "xtal\0pclk\0baud"; + status = "disabled"; + }; + + i2c@5000 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x00 0x5000 0x00 0x20>; + interrupts = <0x00 0xc3 0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x18>; + }; + + pwm@7000 { + compatible = "amlogic,meson-g12a-ao-pwm-ab"; + reg = <0x00 0x7000 0x00 0x20>; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + ir@8000 { + compatible = "amlogic,meson-gxbb-ir"; + reg = <0x00 0x8000 0x00 0x20>; + interrupts = <0x00 0xc4 0x01>; + status = "okay"; + pinctrl-0 = <0x1f>; + pinctrl-names = "default"; + linux,rc-map-name = "rc-odroid"; + }; + + adc@9000 { + compatible = "amlogic,meson-g12a-saradc\0amlogic,meson-saradc"; + reg = <0x00 0x9000 0x00 0x48>; + #io-channel-cells = <0x01>; + interrupts = <0x00 0xc8 0x01>; + clocks = <0x11 0x19 0x08 0x19 0x12 0x19 0x10>; + clock-names = "clkin\0core\0adc_clk\0adc_sel"; + status = "disabled"; + }; + }; + + video-decoder@ff620000 { + compatible = "amlogic,sm1-vdec"; + reg = <0x00 0xff620000 0x00 0x10000 0x00 0xffd0e180 0x00 0xe4>; + reg-names = "dos\0esparser"; + interrupts = <0x00 0x2c 0x01 0x00 0x20 0x01>; + interrupt-names = "vdec\0esparser"; + amlogic,ao-sysctrl = <0x12>; + amlogic,canvas = <0x20>; + clocks = <0x02 0x2e 0x02 0x10 0x02 0xcc 0x02 0xcf 0x02 0xd2>; + clock-names = "dos_parser\0dos\0vdec_1\0vdec_hevc\0vdec_hevcf"; + resets = <0x05 0x28>; + reset-names = "esparser"; + }; + + vpu@ff900000 { + compatible = "amlogic,meson-g12a-vpu"; + reg = <0x00 0xff900000 0x00 0x100000 0x00 0xff63c000 0x00 0x1000>; + reg-names = "vpu\0hhi"; + interrupts = <0x00 0x03 0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + amlogic,canvas = <0x20>; + power-domains = <0x03 0x00>; + status = "disabled"; + + port@0 { + reg = <0x00>; + }; + + port@1 { + reg = <0x01>; + + endpoint { + remote-endpoint = <0x21>; + phandle = <0x0d>; + }; + }; + }; + + interrupt-controller@ffc01000 { + compatible = "arm,gic-400"; + reg = <0x00 0xffc01000 0x00 0x1000 0x00 0xffc02000 0x00 0x2000 0x00 0xffc04000 0x00 0x2000 0x00 0xffc06000 0x00 0x2000>; + interrupt-controller; + interrupts = <0x01 0x09 0xff04>; + #interrupt-cells = <0x03>; + #address-cells = <0x00>; + phandle = <0x01>; + }; + + bus@ffd00000 { + compatible = "simple-bus"; + reg = <0x00 0xffd00000 0x00 0x100000>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges = <0x00 0x00 0x00 0xffd00000 0x00 0x100000>; + + reset-controller@1004 { + compatible = "amlogic,meson-axg-reset"; + reg = <0x00 0x1004 0x00 0x9c>; + #reset-cells = <0x01>; + phandle = <0x05>; + }; + + interrupt-controller@f080 { + compatible = "amlogic,meson-sm1-gpio-intc\0amlogic,meson-gpio-intc"; + reg = <0x00 0xf080 0x00 0x10>; + interrupt-controller; + #interrupt-cells = <0x02>; + amlogic,channel-interrupts = <0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47>; + phandle = <0x15>; + }; + + watchdog@f0d0 { + compatible = "amlogic,meson-gxbb-wdt"; + reg = <0x00 0xf0d0 0x00 0x10>; + clocks = <0x11>; + }; + + spi@13000 { + compatible = "amlogic,meson-g12a-spicc"; + reg = <0x00 0x13000 0x00 0x44>; + interrupts = <0x00 0x51 0x04>; + clocks = <0x02 0x17 0x02 0x102>; + clock-names = "core\0pclk"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + spi@15000 { + compatible = "amlogic,meson-g12a-spicc"; + reg = <0x00 0x15000 0x00 0x44>; + interrupts = <0x00 0x5a 0x04>; + clocks = <0x02 0x1d 0x02 0x105>; + clock-names = "core\0pclk"; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + }; + + spi@14000 { + compatible = "amlogic,meson-gxbb-spifc"; + status = "disabled"; + reg = <0x00 0x14000 0x00 0x80>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x0a>; + }; + + pwm@19000 { + compatible = "amlogic,meson-g12a-ee-pwm"; + reg = <0x00 0x19000 0x00 0x20>; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm@1a000 { + compatible = "amlogic,meson-g12a-ee-pwm"; + reg = <0x00 0x1a000 0x00 0x20>; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + pwm@1b000 { + compatible = "amlogic,meson-g12a-ee-pwm"; + reg = <0x00 0x1b000 0x00 0x20>; + #pwm-cells = <0x03>; + status = "disabled"; + }; + + i2c@1c000 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x00 0x1c000 0x00 0x20>; + interrupts = <0x00 0x27 0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x18>; + }; + + i2c@1d000 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x00 0x1d000 0x00 0x20>; + interrupts = <0x00 0xd7 0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x18>; + }; + + i2c@1e000 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x00 0x1e000 0x00 0x20>; + interrupts = <0x00 0xd6 0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x18>; + }; + + i2c@1f000 { + compatible = "amlogic,meson-axg-i2c"; + status = "disabled"; + reg = <0x00 0x1f000 0x00 0x20>; + interrupts = <0x00 0x15 0x01>; + #address-cells = <0x01>; + #size-cells = <0x00>; + clocks = <0x02 0x18>; + }; + + clock-measure@18000 { + compatible = "amlogic,meson-sm1-clk-measure"; + reg = <0x00 0x18000 0x00 0x10>; + }; + + serial@22000 { + compatible = "amlogic,meson-gx-uart"; + reg = <0x00 0x22000 0x00 0x18>; + interrupts = <0x00 0x5d 0x01>; + clocks = <0x11 0x02 0x39 0x11>; + clock-names = "xtal\0pclk\0baud"; + status = "disabled"; + }; + + serial@23000 { + compatible = "amlogic,meson-gx-uart"; + reg = <0x00 0x23000 0x00 0x18>; + interrupts = <0x00 0x4b 0x01>; + clocks = <0x11 0x02 0x2a 0x11>; + clock-names = "xtal\0pclk\0baud"; + status = "disabled"; + }; + + serial@24000 { + compatible = "amlogic,meson-gx-uart"; + reg = <0x00 0x24000 0x00 0x18>; + interrupts = <0x00 0x1a 0x01>; + clocks = <0x11 0x02 0x1c 0x11>; + clock-names = "xtal\0pclk\0baud"; + status = "disabled"; + fifo-size = <0x80>; + }; + }; + + sd@ffe03000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x00 0xffe03000 0x00 0x800>; + interrupts = <0x00 0xbd 0x01>; + status = "disabled"; + clocks = <0x02 0x21 0x02 0x3c 0x02 0x02>; + clock-names = "core\0clkin0\0clkin1"; + resets = <0x05 0x2c>; + }; + + sd@ffe05000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x00 0xffe05000 0x00 0x800>; + interrupts = <0x00 0xbe 0x01>; + status = "okay"; + clocks = <0x02 0x22 0x02 0x3d 0x02 0x02>; + clock-names = "core\0clkin0\0clkin1"; + resets = <0x05 0x2d>; + pinctrl-0 = <0x22>; + pinctrl-1 = <0x23>; + pinctrl-names = "default\0clk-gate"; + bus-width = <0x04>; + cap-sd-highspeed; + max-frequency = <0xbebc200>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + disable-wp; + cd-gpios = <0x14 0x2f 0x01>; + vmmc-supply = <0x24>; + vqmmc-supply = <0x25>; + }; + + mmc@ffe07000 { + compatible = "amlogic,meson-axg-mmc"; + reg = <0x00 0xffe07000 0x00 0x800>; + interrupts = <0x00 0xbf 0x01>; + status = "okay"; + clocks = <0x02 0x23 0x02 0x3e 0x02 0x02>; + clock-names = "core\0clkin0\0clkin1"; + resets = <0x05 0x2e>; + pinctrl-0 = <0x26 0x27 0x28>; + pinctrl-1 = <0x29>; + pinctrl-names = "default\0clk-gate"; + bus-width = <0x08>; + cap-mmc-highspeed; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + max-frequency = <0xbebc200>; + disable-wp; + mmc-pwrseq = <0x2a>; + vmmc-supply = <0x2b>; + vqmmc-supply = <0x2c>; + }; + + usb@ffe09000 { + status = "okay"; + compatible = "amlogic,meson-g12a-usb-ctrl"; + reg = <0x00 0xffe09000 0x00 0xa0>; + interrupts = <0x00 0x10 0x04>; + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + clocks = <0x02 0x2f>; + resets = <0x05 0x22>; + dr_mode = "otg"; + phys = <0x2d 0x2e 0x06 0x04>; + phy-names = "usb2-phy0\0usb2-phy1\0usb3-phy0"; + power-domains = <0x03 0x02>; + vbus-supply = <0x2f>; + + usb@ff400000 { + compatible = "amlogic,meson-g12a-usb\0snps,dwc2"; + reg = <0x00 0xff400000 0x00 0x40000>; + interrupts = <0x00 0x1f 0x04>; + clocks = <0x02 0x37>; + clock-names = "otg"; + phys = <0x2e>; + phy-names = "usb2-phy"; + dr_mode = "peripheral"; + g-rx-fifo-size = <0xc0>; + g-np-tx-fifo-size = <0x80>; + g-tx-fifo-size = <0x80 0x80 0x10 0x10 0x10>; + }; + + usb@ff500000 { + compatible = "snps,dwc3"; + reg = <0x00 0xff500000 0x00 0x100000>; + interrupts = <0x00 0x1e 0x04>; + dr_mode = "host"; + snps,dis_u2_susphy_quirk; + snps,quirk-frame-length-adjustment = <0x20>; + snps,parkmode-disable-ss-quirk; + }; + }; + + gpu@ffe40000 { + compatible = "amlogic,meson-g12a-mali\0arm,mali-bifrost"; + reg = <0x00 0xffe40000 0x00 0x40000>; + interrupt-parent = <0x01>; + interrupts = <0x00 0xa2 0x04 0x00 0xa1 0x04 0x00 0xa0 0x04>; + interrupt-names = "job\0mmu\0gpu"; + clocks = <0x02 0xaf>; + resets = <0x05 0x14 0x05 0x4e>; + operating-points-v2 = <0x30>; + #cooling-cells = <0x02>; + phandle = <0x3a>; + }; + }; + + thermal-zones { + + cpu-thermal { + polling-delay = <0x3e8>; + polling-delay-passive = <0x64>; + thermal-sensors = <0x31>; + + trips { + + cpu-passive { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x32>; + }; + + cpu-hot { + temperature = <0x17318>; + hysteresis = <0x7d0>; + type = "hot"; + phandle = <0x37>; + }; + + cpu-critical { + temperature = <0x1adb0>; + hysteresis = <0x7d0>; + type = "critical"; + }; + }; + + cooling-maps { + + map0 { + trip = <0x32>; + cooling-device = <0x33 0xffffffff 0xffffffff 0x34 0xffffffff 0xffffffff 0x35 0xffffffff 0xffffffff 0x36 0xffffffff 0xffffffff>; + }; + + map1 { + trip = <0x37>; + cooling-device = <0x33 0xffffffff 0xffffffff 0x34 0xffffffff 0xffffffff 0x35 0xffffffff 0xffffffff 0x36 0xffffffff 0xffffffff>; + }; + }; + }; + + ddr-thermal { + polling-delay = <0x3e8>; + polling-delay-passive = <0x64>; + thermal-sensors = <0x38>; + + trips { + + ddr-passive { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x39>; + }; + + ddr-critical { + temperature = <0x1adb0>; + hysteresis = <0x7d0>; + type = "critical"; + }; + }; + + cooling-maps { + + map { + trip = <0x39>; + cooling-device = <0x3a 0xffffffff 0xffffffff>; + }; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0xff08 0x01 0x0e 0xff08 0x01 0x0b 0xff08 0x01 0x0a 0xff08>; + arm,no-tick-in-suspend; + }; + + xtal-clk { + compatible = "fixed-clock"; + clock-frequency = <0x16e3600>; + clock-output-names = "xtal"; + #clock-cells = <0x00>; + phandle = <0x11>; + }; + + audio-controller-0 { + compatible = "amlogic,axg-tdm-iface"; + #sound-dai-cells = <0x00>; + sound-name-prefix = "TDM_A"; + clocks = <0x16 0x31 0x16 0x4f 0x16 0x56>; + clock-names = "mclk\0sclk\0lrclk"; + status = "disabled"; + }; + + audio-controller-1 { + compatible = "amlogic,axg-tdm-iface"; + #sound-dai-cells = <0x00>; + sound-name-prefix = "TDM_B"; + clocks = <0x16 0x32 0x16 0x50 0x16 0x57>; + clock-names = "mclk\0sclk\0lrclk"; + status = "okay"; + phandle = <0x47>; + }; + + audio-controller-2 { + compatible = "amlogic,axg-tdm-iface"; + #sound-dai-cells = <0x00>; + sound-name-prefix = "TDM_C"; + clocks = <0x16 0x33 0x16 0x51 0x16 0x58>; + clock-names = "mclk\0sclk\0lrclk"; + status = "disabled"; + }; + + cpus { + #address-cells = <0x02>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x00 0x00>; + enable-method = "psci"; + next-level-cache = <0x3b>; + #cooling-cells = <0x02>; + cpu-supply = <0x3c>; + operating-points-v2 = <0x3d>; + clocks = <0x02 0xbb>; + clock-latency = <0xc350>; + phandle = <0x33>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x00 0x01>; + enable-method = "psci"; + next-level-cache = <0x3b>; + #cooling-cells = <0x02>; + cpu-supply = <0x3c>; + operating-points-v2 = <0x3d>; + clocks = <0x02 0xfd>; + clock-latency = <0xc350>; + phandle = <0x34>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x00 0x02>; + enable-method = "psci"; + next-level-cache = <0x3b>; + #cooling-cells = <0x02>; + cpu-supply = <0x3c>; + operating-points-v2 = <0x3d>; + clocks = <0x02 0xfe>; + clock-latency = <0xc350>; + phandle = <0x35>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + reg = <0x00 0x03>; + enable-method = "psci"; + next-level-cache = <0x3b>; + #cooling-cells = <0x02>; + cpu-supply = <0x3c>; + operating-points-v2 = <0x3d>; + clocks = <0x02 0xff>; + clock-latency = <0xc350>; + phandle = <0x36>; + }; + + l2-cache0 { + compatible = "cache"; + phandle = <0x3b>; + }; + }; + + opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x3d>; + + opp-1000000000 { + opp-hz = <0x00 0x3b9aca00>; + opp-microvolt = <0xbbfd0>; + }; + + opp-1200000000 { + opp-hz = <0x00 0x47868c00>; + opp-microvolt = <0xbe6e0>; + }; + + opp-1404000000 { + opp-hz = <0x00 0x53af5700>; + opp-microvolt = <0xc0df0>; + }; + + opp-1500000000 { + opp-hz = <0x00 0x59682f00>; + opp-microvolt = <0xc3500>; + }; + + opp-1608000000 { + opp-hz = <0x00 0x5fd82200>; + opp-microvolt = <0xc5c10>; + }; + + opp-1704000000 { + opp-hz = <0x00 0x6590fa00>; + opp-microvolt = <0xcf850>; + }; + + opp-1800000000 { + opp-hz = <0x00 0x6b49d200>; + opp-microvolt = <0xdbba0>; + }; + + opp-1908000000 { + opp-hz = <0x00 0x71b9c500>; + opp-microvolt = <0xe7ef0>; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x00 0x20000000 0x00 0x10000000>; + }; + + emmc-pwrseq { + compatible = "mmc-pwrseq-emmc"; + reset-gpios = <0x14 0x25 0x01>; + phandle = <0x2a>; + }; + + regulator-tflash_vdd { + compatible = "regulator-fixed"; + regulator-name = "TFLASH_VDD"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + gpio = <0x3e 0x03 0x06>; + enable-active-high; + regulator-always-on; + phandle = <0x24>; + }; + + gpio-regulator-tf_io { + compatible = "regulator-gpio"; + regulator-name = "TF_IO"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x325aa0>; + vin-supply = <0x0c>; + enable-gpio = <0x3e 0x0e 0x06>; + enable-active-high; + regulator-always-on; + gpios = <0x3e 0x06 0x02>; + gpios-states = <0x00>; + states = <0x325aa0 0x00 0x1b7740 0x01>; + phandle = <0x25>; + }; + + regulator-flash_1v8 { + compatible = "regulator-fixed"; + regulator-name = "FLASH_1V8"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + vin-supply = <0x2b>; + regulator-always-on; + phandle = <0x2c>; + }; + + regulator-main_12v { + compatible = "regulator-fixed"; + regulator-name = "12V"; + regulator-min-microvolt = <0xb71b00>; + regulator-max-microvolt = <0xb71b00>; + regulator-always-on; + phandle = <0x3f>; + }; + + regulator-vcc_5v { + compatible = "regulator-fixed"; + regulator-name = "5V"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + regulator-always-on; + vin-supply = <0x3f>; + gpio = <0x14 0x18 0x06>; + enable-active-high; + phandle = <0x0c>; + }; + + regulator-vcc_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + vin-supply = <0x2b>; + regulator-always-on; + }; + + regulator-vcc_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + vin-supply = <0x40>; + regulator-always-on; + phandle = <0x2b>; + }; + + regulator-vddcpu { + compatible = "pwm-regulator"; + regulator-name = "VDDCPU"; + regulator-min-microvolt = <0xb0068>; + regulator-max-microvolt = <0xf9830>; + pwm-supply = <0x3f>; + pwms = <0x41 0x01 0x4e2 0x00>; + pwm-dutycycle-range = <0x64 0x00>; + regulator-boot-on; + regulator-always-on; + phandle = <0x3c>; + }; + + regulator-usb_pwr_en { + compatible = "regulator-fixed"; + regulator-name = "USB_PWR_EN"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + vin-supply = <0x0c>; + gpio = <0x3e 0x02 0x00>; + enable-active-high; + phandle = <0x2f>; + }; + + regulator-vddao_1v8 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_1V8"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1b7740>; + vin-supply = <0x40>; + regulator-always-on; + }; + + regulator-vddao_3v3 { + compatible = "regulator-fixed"; + regulator-name = "VDDAO_3V3"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + vin-supply = <0x3f>; + regulator-always-on; + phandle = <0x40>; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = [61 00]; + + port { + + endpoint { + remote-endpoint = <0x42>; + phandle = <0x0e>; + }; + }; + }; + + sound { + compatible = "amlogic,axg-sound-card"; + audio-aux-devs = <0x43>; + audio-routing = "TDMOUT_B IN 0\0FRDDR_A OUT 1\0TDMOUT_B IN 1\0FRDDR_B OUT 1\0TDMOUT_B IN 2\0FRDDR_C OUT 1\0TDM_B Playback\0TDMOUT_B OUT"; + assigned-clocks = <0x02 0x0d 0x02 0x0b 0x02 0x0c>; + assigned-clock-parents = <0x00 0x00 0x00>; + assigned-clock-rates = <0x11940000 0x10266000 0x17700000>; + status = "okay"; + model = "ODROID-C4"; + + dai-link-0 { + sound-dai = <0x44>; + }; + + dai-link-1 { + sound-dai = <0x45>; + }; + + dai-link-2 { + sound-dai = <0x46>; + }; + + dai-link-3 { + sound-dai = <0x47>; + dai-format = "i2s"; + dai-tdm-slot-tx-mask-0 = <0x01 0x01>; + dai-tdm-slot-tx-mask-1 = <0x01 0x01>; + dai-tdm-slot-tx-mask-2 = <0x01 0x01>; + dai-tdm-slot-tx-mask-3 = <0x01 0x01>; + mclk-fs = <0x100>; + + codec { + sound-dai = <0x48 0x01>; + }; + }; + + dai-link-4 { + sound-dai = <0x48 0x03>; + + codec { + sound-dai = <0x1b>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-blue { + color = <0x03>; + function = "status"; + gpios = <0x3e 0x0b 0x00>; + linux,default-trigger = "heartbeat"; + panic-indicator; + }; + }; +}; diff --git a/include/sddf/clk/client.h b/include/sddf/clk/client.h new file mode 100644 index 000000000..38fa5d9fe --- /dev/null +++ b/include/sddf/clk/client.h @@ -0,0 +1,77 @@ +/* + * Copyright 2024, UNSW + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include + +/** + * Send a clock enabling request via PPC into the passive clock driver. + * Use the label to indicate this request. + * @param channel of clock driver. + * @param identifier of target clock. + */ +static inline uint32_t sddf_clk_enable(microkit_channel channel, uint32_t clk_id) +{ + microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_ENABLE, 1); + microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); + + msginfo = microkit_ppcall(channel, msginfo); + + return (uint32_t)microkit_msginfo_get_label(msginfo); +} + +/** + * Send a clock disabling request via PPC into the passive clock driver. + * Use the label to indicate this request. + * @param channel of clock driver. + * @param identifier of target clock. + */ +static inline uint32_t sddf_clk_disable(microkit_channel channel, uint32_t clk_id) +{ + microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_DISABLE, 1); + microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); + + msginfo = microkit_ppcall(channel, msginfo); + + return (uint32_t)microkit_msginfo_get_label(msginfo); +} + +/** + * Send a clock get_rate request via PPC into the passive clock driver. + * Use the label to indicate this request. + * @param channel of clock driver. + * @param identifier of target clock. + */ +static inline uint32_t sddf_clk_get_rate(microkit_channel channel, uint32_t clk_id) +{ + microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_GET_RATE, 1); + microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); + + msginfo = microkit_ppcall(channel, msginfo); + + return (uint32_t)microkit_msginfo_get_label(msginfo); +} + +/** + * Send a clock set_rate request via PPC into the passive clock driver. + * Use the label to indicate this request. + * @param channel of clock driver. + * @param identifier of target clock. + * @param target clock frequency. + */ +static inline uint32_t sddf_clk_set_rate(microkit_channel channel, uint32_t clk_id, uint32_t rate) +{ + microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_SET_RATE, 2); + microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); + microkit_mr_set(SDDF_CLK_PARAM_RATE, rate); + + msginfo = microkit_ppcall(channel, msginfo); + + return (uint32_t)microkit_msginfo_get_label(msginfo); +} diff --git a/include/sddf/clk/protocol.h b/include/sddf/clk/protocol.h new file mode 100644 index 000000000..7f1b6bff6 --- /dev/null +++ b/include/sddf/clk/protocol.h @@ -0,0 +1,27 @@ +/* + * Copyright 2024, UNSW + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once +#include + +/* Shared functionality/definitions between pinctrl drivers and clients */ + +#ifdef ODROID_C4 +#include +#endif + +#define SDDF_CLK_ENABLE 0 +#define SDDF_CLK_DISABLE 1 +#define SDDF_CLK_GET_RATE 2 +#define SDDF_CLK_SET_RATE 3 + +#define SDDF_CLK_PARAM_ID 0 +#define SDDF_CLK_PARAM_RATE 1 + +struct clk_cfg { + uint32_t clk_id; + uint32_t frequency; + uint32_t pclk_id; +}; From 1e289038a52a4a4e281b60d54cc7667ba8640185 Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Fri, 1 Nov 2024 14:55:51 +1100 Subject: [PATCH 02/11] add Makefile Signed-off-by: Terry Bai --- drivers/clk/meson/clk_driver.mk | 32 +++++++++++++ examples/clk/Makefile | 44 ++++++++++++++++++ examples/clk/clk.mk | 80 +++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 drivers/clk/meson/clk_driver.mk create mode 100644 examples/clk/Makefile create mode 100644 examples/clk/clk.mk diff --git a/drivers/clk/meson/clk_driver.mk b/drivers/clk/meson/clk_driver.mk new file mode 100644 index 000000000..bf730c526 --- /dev/null +++ b/drivers/clk/meson/clk_driver.mk @@ -0,0 +1,32 @@ +# +# Copyright 2024, UNSW +# +# SPDX-License-Identifier: BSD-2-Clause + +CLK_DRIVER_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +CLK_DRIVER_OBJS := clk.o clk-operations.o clk-measure.o clk-meson.o sm1-clk.o + +clk_driver.elf: $(CLK_DRIVER_OBJS) libsddf_util_debug.a + $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ + +CLK_CONFIG_HEADER := $(BUILD_DIR)/clk_config.h +CLK_DRIVER_CONF_INC := $(SDDF)/include/sddf/clk +CLK_DRIVER_INC := $(CLK_DRIVER_DIR)/include +CLK_DRIVER_COMMON_DIR := $(SDDF)/drivers/clk + +$(CLK_DRIVER_OBJS): ${CLK_DRIVER_COMMON_DIR}/*.c ${CLK_DRIVER_DIR}/*.c $(CLK_CONFIG_HEADER) + $(CC) -c $(CFLAGS) \ + -I${CLK_DRIVER_INC} \ + -I${CLK_DRIVER_CONF_INC} \ + -I${BUILD_DIR} \ + -I${UART_DRIVER_DIR}/include \ + -I${CLK_DRIVER_COMMON_DIR} $^ + +$(CLK_CONFIG_HEADER): + $(PYTHON) $(CLK_DRIVER_DIR)/create_clk_config.py $(DTS_FILE) $(BUILD_DIR) + +clean:: + rm -f clk_driver.o + +clobber:: + rm -rf clk_driver.elf diff --git a/examples/clk/Makefile b/examples/clk/Makefile new file mode 100644 index 000000000..df144ac1f --- /dev/null +++ b/examples/clk/Makefile @@ -0,0 +1,44 @@ +# +# Copyright 2024, UNSW +# +# SPDX-License-Identifier: BSD-2-Clause +# + +ifeq ($(strip $(MICROKIT_SDK)),) +$(error MICROKIT_SDK must be specified) +endif +override MICROKIT_SDK := $(abspath ${MICROKIT_SDK}) + +ifeq ($(strip $(MICROKIT_BOARD)),) +$(error MICROKIT_BOARD must be specified) +endif +export MICROKIT_BOARD + +BUILD_DIR ?= build +# By default we make a debug build so that the client debug prints can be seen. +MICROKIT_CONFIG ?= debug + +export TOP:= $(abspath $(dir ${MAKEFILE_LIST})) + +CC := clang +LD := ld.lld +export MICROKIT_TOOL ?= $(abspath $(MICROKIT_SDK)/bin/microkit) + +export BOARD_DIR := $(abspath $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG)) +export SDDF := $(abspath ../..) +IMAGE_FILE := $(BUILD_DIR)/loader.img +REPORT_FILE := $(BUILD_DIR)/report.txt + +all: clean ${IMAGE_FILE} + +${IMAGE_FILE}: ${BUILD_DIR}/Makefile + ${MAKE} -C ${BUILD_DIR} MICROKIT_SDK=${MICROKIT_SDK} $(notdir $@) + +${BUILD_DIR}/Makefile: clk.mk + mkdir -p ${BUILD_DIR} + cp clk.mk ${BUILD_DIR}/Makefile + +clean: + rm -rfd $(BUILD_DIR) + +FORCE: diff --git a/examples/clk/clk.mk b/examples/clk/clk.mk new file mode 100644 index 000000000..9e6aa92c2 --- /dev/null +++ b/examples/clk/clk.mk @@ -0,0 +1,80 @@ +# +# Copyright 2024, UNSW +# +# SPDX-License-Identifier: BSD-2-Clause +# + +ifeq ($(strip $(MICROKIT_SDK)),) +$(error MICROKIT_SDK must be specified) +endif + + +ifeq ($(strip $(MICROKIT_BOARD)), odroidc4) + CPU := cortex-a55 + DTS_FILE := $(TOP)/dts/odroidc4.dts + SYSTEM_FILE := ${TOP}/board/odroidc4/clk.system + ARCH := aarch64 + DRIVER_DIR := meson + CPU := cortex-a55 +else +$(error Unsupported MICROKIT_BOARD given) +endif + +BUILD_DIR ?= $(TOP)/build +# By default we make a debug build so that the client debug prints can be seen. +MICROKIT_CONFIG ?= debug + +CC := aarch64-none-elf-gcc +LD := aarch64-none-elf-ld +AR := aarch64-none-elf-ar +AS := aarch64-none-elf-as +RANLIB := aarch64-none-elf-ranlib +PYTHON := python3 + +MICROKIT_TOOL ?= $(MICROKIT_SDK)/bin/microkit + +BOARD_DIR := $(MICROKIT_SDK)/board/$(MICROKIT_BOARD)/$(MICROKIT_CONFIG) +UTIL := $(SDDF)/util + +IMAGES := timer_driver.elf clk_driver.elf client.elf +CFLAGS := -mcpu=$(CPU) \ + -mstrict-align \ + -nostdlib \ + -ffreestanding \ + -g3 \ + -Wall -Wno-unused-function -Werror -Wno-unused-command-line-argument \ + -I$(BOARD_DIR)/include \ + -I$(SDDF)/include \ + -I$(LIBMICROKITCO_PATH) \ + -I$(TOP) + +LDFLAGS := -L$(BOARD_DIR)/lib -L. +LIBS := --start-group -lmicrokit -Tmicrokit.ld libsddf_util_debug.a --end-group + +IMAGE_FILE := loader.img +REPORT_FILE := report.txt +CLIENT_OBJS := client.o +CLK_DRIVER := $(SDDF)/drivers/clk/$(DRIVER_DIR) +TIMER_DRIVER := $(SDDF)/drivers/timer/$(DRIVER_DIR) + +all: $(IMAGE_FILE) + +${IMAGES}: libsddf_util_debug.a + +include ${SDDF}/util/util.mk +include ${TIMER_DRIVER}/timer_driver.mk +include ${CLK_DRIVER}/clk_driver.mk + +client.o: ${TOP}/client.c + $(CC) -c $(CFLAGS) $(CHIP_HEADER_INC) -DTEST_BOARD_${MICROKIT_BOARD} $< -o client.o + +client.elf: client.o + $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ + +$(IMAGE_FILE) $(REPORT_FILE): $(IMAGES) $(SYSTEM_FILE) + $(MICROKIT_TOOL) $(SYSTEM_FILE) --search-path $(TOP)/build --board $(MICROKIT_BOARD) --config $(MICROKIT_CONFIG) -o $(IMAGE_FILE) -r $(REPORT_FILE) + +clean:: + rm -f client.o +clobber:: clean + rm -f client.elf ${IMAGE_FILE} ${REPORT_FILE} From 1f03995629ad46aa001f8d5dc0754c03832b3a22 Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Mon, 4 Nov 2024 10:45:21 +1100 Subject: [PATCH 03/11] Clock driver for maaxboard Add clock driver for maaxboard. This commit includes all clock component definitions, basic operations, and a simple test on maaxboard. Scripts are added in build systems. A few files are reorganised for reuse Signed-off-by: Terry Bai --- build.zig | 11 +- drivers/clk/{meson => }/create_clk_config.py | 20 +- drivers/clk/imx/clk-imx.c | 283 +++ drivers/clk/imx/clk-imx8mq.c | 1518 ++++++++++++++ drivers/clk/imx/clk.c | 222 ++ drivers/clk/imx/clk_driver.mk | 34 + drivers/clk/imx/include/clk-imx.h | 342 +++ drivers/clk/imx/include/imx8mq-bindings.h | 430 ++++ drivers/clk/meson/clk.c | 4 +- drivers/clk/meson/clk_driver.mk | 14 +- examples/clk/board/maaxboard/clk.system | 39 + examples/clk/build.zig | 13 +- examples/clk/client.c | 11 +- examples/clk/clk.mk | 6 + examples/clk/dts/maaxboard.dts | 1950 ++++++++++++++++++ 15 files changed, 4875 insertions(+), 22 deletions(-) rename drivers/clk/{meson => }/create_clk_config.py (91%) create mode 100644 drivers/clk/imx/clk-imx.c create mode 100644 drivers/clk/imx/clk-imx8mq.c create mode 100644 drivers/clk/imx/clk.c create mode 100644 drivers/clk/imx/clk_driver.mk create mode 100644 drivers/clk/imx/include/clk-imx.h create mode 100644 drivers/clk/imx/include/imx8mq-bindings.h create mode 100644 examples/clk/board/maaxboard/clk.system create mode 100644 examples/clk/dts/maaxboard.dts diff --git a/build.zig b/build.zig index 8c8110952..5efbaeeb1 100644 --- a/build.zig +++ b/build.zig @@ -28,6 +28,7 @@ const DriverClass = struct { const Clock = enum { meson, + imx, }; const I2cHost = enum { @@ -231,6 +232,14 @@ fn addClockDriver( }; driver.addCSourceFiles(.{ .files = files }); }, + .imx => { + const files: []const []const u8 = &.{ + "drivers/clk/imx/clk.c", + "drivers/clk/imx/clk-imx.c", + "drivers/clk/imx/clk-imx8mq.c", + }; + driver.addCSourceFiles(.{ .files = files }); + }, } const common_src_files = .{ "clk-operations.c" }; @@ -512,7 +521,7 @@ pub fn build(b: *std.Build) void { const clk_config = b.addSystemCommand(&.{ "python", - b.fmt("drivers/clk/{s}/create_clk_config.py", .{ class.name }), + "drivers/clk/create_clk_config.py", dtb_path, clk_conf_include_option, }); // Creates a system command which runs the python interpreter diff --git a/drivers/clk/meson/create_clk_config.py b/drivers/clk/create_clk_config.py similarity index 91% rename from drivers/clk/meson/create_clk_config.py rename to drivers/clk/create_clk_config.py index 34b0ad016..f1255ccec 100644 --- a/drivers/clk/meson/create_clk_config.py +++ b/drivers/clk/create_clk_config.py @@ -2,15 +2,13 @@ # Copyright 2024, UNSW # SPDX-License-Identifier: BSD-2-Clause -# -# The template is stolen from Bill's pinmux driver import os import sys from typing import List from devicetree import edtlib, dtlib -supported_compat_str_board = { "hardkernel,odroid-c4" } +supported_compat_str_board = { "hardkernel,odroid-c4", "fsl,imx8mm-evk", "fsl,imx8mq" } debug_parser = True clock_list = {} @@ -67,7 +65,8 @@ def extract_clocks(dt: dtlib.DT, node: dtlib.Node) -> List: for clk_id in clock_ids: add_clock(clk_id, 0, 0) for pnode in pnodes: - extract_clocks(dt, pnode) + if pnode != node: + extract_clocks(dt, pnode) if "max-frequency" in props: max_frequency = node.props["max-frequency"].to_nums() @@ -79,7 +78,8 @@ def extract_clocks(dt: dtlib.DT, node: dtlib.Node) -> List: if (clk_rate): add_clock(clk_id, clk_rate, 0) for pnode in pnodes: - extract_clocks(dt, pnode) + if pnode != node: + extract_clocks(dt, pnode) if "assigned-clocks" in props and "assigned-clock-parents" in props: assigned_clocks, pnodes = parse_clock_list(devicetree, node.props["assigned-clocks"].to_nums()) @@ -88,11 +88,11 @@ def extract_clocks(dt: dtlib.DT, node: dtlib.Node) -> List: if (pclk_id): add_clock(clk_id, 0, pclk_id) for pnode in pnodes: - extract_clocks(dt, pnode) + if pnode != node: + extract_clocks(dt, pnode) for pnode in ppnodes: - extract_clocks(dt, pnode) - - return enabled_clks + if pnode != node: + extract_clocks(dt, pnode) def write_configs_to_headerfile(path: str) -> None: with open(path + '/clk_config.h', "w") as f: @@ -106,6 +106,7 @@ def write_configs_to_headerfile(path: str) -> None: f.write("static struct clk_cfg clk_configs[] = {{\n{}\n}};".format(",\n".join(clk_cfg_strs))) if __name__ == "__main__": + supported = False devicetree = dtlib.DT(sys.argv[1], force=True) for compat_str in devicetree.root.props["compatible"].to_strings(): if compat_str in supported_compat_str_board: @@ -116,7 +117,6 @@ def write_configs_to_headerfile(path: str) -> None: log_error_parser("this board is not supported.") exit(1) - enabled_clks = [] for node in devicetree.node_iter(): props = list(node.props.keys()) diff --git a/drivers/clk/imx/clk-imx.c b/drivers/clk/imx/clk-imx.c new file mode 100644 index 000000000..09d69acfd --- /dev/null +++ b/drivers/clk/imx/clk-imx.c @@ -0,0 +1,283 @@ +#include +#include +#include + +#define PLL_FRAC_DENOM 0x1000000 + +static int clk_gate2_enable(struct clk *clk) +{ + struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); + + return regmap_update_bits(clk->base, data->offset, data->bit_idx, 2, 0x3); +} + +static int clk_gate2_disable(struct clk *clk) +{ + struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); + + return regmap_update_bits(clk->base, data->offset, data->bit_idx, 2, 0); +} + +static int clk_gate2_is_enabled(struct clk *clk) +{ + struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); + + if (regmap_read_bits(clk->base, data->offset, data->bit_idx, 2) == 0x3) + return 1; + + return 0; +} + +const struct clk_ops clk_gate2_ops = { + .enable = clk_gate2_enable, + .disable = clk_gate2_disable, + /* .disable_unused = clk_gate2_disable_unused, */ + .is_enabled = clk_gate2_is_enabled, +}; + +static unsigned long clk_pll_recalc_rate(const struct clk *clk, + unsigned long prate) +{ + /* TODO: This function is derived from Linux codebase, but seems wrong + * according to the datasheet as PLL_REFCLK_DIV_VAL[5:10] is never used. */ + struct clk_frac_pll_data *data = (struct clk_frac_pll_data *)(clk->data); + uint64_t temp_rate = prate; + uint64_t rate; + + /* Output Divider value is (n + 1) * 2 */ + uint32_t output_div_val = regmap_read_bits(clk->base, data->offset, 0, 5); + output_div_val = (output_div_val + 1 ) * 2; + + /* Valid Frac Divider value is 1 to 2^24 */ + uint32_t frac_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 7, 24); + + /* Valid Int Divider value is 1 to 32 */ + uint32_t int_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 0, 7); + + temp_rate *= prate; + temp_rate *= frac_div_val; + do_div(temp_rate, PLL_FRAC_DENOM); + do_div(temp_rate, output_div_val); + + /* Frac Divider value is (n) */ + rate = prate * 8 * (int_div_val + 1); + do_div(rate, output_div_val); + rate += temp_rate; + + return rate; +} + +const struct clk_ops clk_frac_pll_ops = { + /* .prepare = clk_pll_prepare, */ + /* .unprepare = clk_pll_unprepare, */ + /* .is_prepared = clk_pll_is_prepared, */ + .recalc_rate = clk_pll_recalc_rate, + /* .round_rate = clk_pll_round_rate, */ + /* .set_rate = clk_pll_set_rate, */ +}; + +static unsigned long clk_sscg_pll_recalc_rate(const struct clk *clk, + unsigned long prate) +{ + struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); + uint64_t temp_rate = prate; + + uint32_t divr1 = regmap_read_bits(clk->base, data->offset + 0x8, 25, 3); + uint32_t divr2 = regmap_read_bits(clk->base, data->offset + 0x8, 19, 6); + uint32_t divf1 = regmap_read_bits(clk->base, data->offset + 0x8, 13, 6); + uint32_t divf2 = regmap_read_bits(clk->base, data->offset + 0x8, 7, 6); + uint32_t divq = regmap_read_bits(clk->base, data->offset + 0x8, 1, 6); + + if (regmap_read_bits(clk->base, data->offset, 4, 1)) { + temp_rate = prate; + } else if (regmap_read_bits(clk->base, data->offset, 5, 1)) { + temp_rate *= divf2; + do_div(temp_rate, (divr2 + 1) * (divq + 1)); + } else { + temp_rate *= 2; + temp_rate *= (divf1 + 1) * (divf2 + 1); + do_div(temp_rate, (divr1 + 1) * (divr2 + 1) * (divq + 1)); + } + + return 0; +} + +static uint8_t clk_sscg_pll_get_parent(const struct clk *clk) +{ + struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); + uint8_t ret = 0; + + if (regmap_read_bits(clk->base, data->offset, 4, 1)) { + ret = data->bypass2; + } else if (regmap_read_bits(clk->base, data->offset, 5, 1)) { + ret = data->bypass1; + } + + return ret; +} + +static int clk_sscg_pll_set_parent(struct clk *clk, uint8_t index) +{ + /* struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); */ + + /* TODO: This operation is based on `setup.bypass` instead of index passed from callee */ + + return 0; +} + +const struct clk_ops clk_sscg_pll_ops = { + /* .prepare = clk_sscg_pll_prepare, */ + /* .unprepare = clk_sscg_pll_unprepare, */ + /* .is_prepared = clk_sscg_pll_is_prepared, */ + .recalc_rate = clk_sscg_pll_recalc_rate, + /* .set_rate = clk_sscg_pll_set_rate, */ + .set_parent = clk_sscg_pll_set_parent, + .get_parent = clk_sscg_pll_get_parent, + /* .determine_rate = clk_sscg_pll_determine_rate, */ +}; + +static unsigned long imx8m_clk_core_slice_recalc_rate(const struct clk *clk, + unsigned long prate) +{ + struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); + + uint32_t div_val = regmap_read_bits(clk->base, data->offset, data->div_shift, data->div_width); + /* Divider value is n+1 */ + return DIV_ROUND_UP_ULL((uint64_t)prate, div_val + 1); +} + +static uint8_t imx8m_clk_core_slice_get_parent(const struct clk *clk) +{ + struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); + + uint32_t num_parents = clk->hw.init->num_parents; + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); + + if (val >= num_parents) + return -1; + + return val; +} + +static int imx8m_clk_core_slice_set_parent(struct clk *clk, uint8_t index) +{ + struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); + + /* + * write twice to make sure non-target interface + * SEL_A/B point the same clk input. + */ + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + + return 0; +} + +const struct clk_ops clk_core_slice_ops = { + .recalc_rate = imx8m_clk_core_slice_recalc_rate, + /* .round_rate = imx8m_clk_core_slice_round_rate, */ + /* .set_rate = imx8m_clk_core_slice_set_rate, */ + /* .determine_rate = imx8m_clk_core_slice_determine_rate, */ + .get_parent = imx8m_clk_core_slice_get_parent, + .set_parent = imx8m_clk_core_slice_set_parent, +}; + +static unsigned long imx8m_clk_common_slice_recalc_rate(const struct clk *clk, + unsigned long prate) +{ + struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); + + uint32_t prediv_val = regmap_read_bits(clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); + /* Divider value is n+1 */ + unsigned long prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, prediv_val + 1); + + uint32_t postdiv_val = regmap_read_bits(clk->base, data->offset, data->postdiv_shift, data->postdiv_width); + /* Divider value is n+1 */ + return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); +} + +static uint8_t imx8m_clk_common_slice_get_parent(const struct clk *clk) +{ + struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); + + uint32_t num_parents = clk->hw.init->num_parents; + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); + + if (val >= num_parents) + return -1; + + return val; +} + +static int imx8m_clk_common_slice_set_parent(struct clk *clk, uint8_t index) +{ + struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); + + /* + * write twice to make sure non-target interface + * SEL_A/B point the same clk input. + */ + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + + return 0; +} + +const struct clk_ops clk_common_slice_ops = { + .recalc_rate = imx8m_clk_common_slice_recalc_rate, + /* .round_rate = imx8m_clk_common_slice_round_rate, */ + /* .set_rate = imx8m_clk_common_slice_set_rate, */ + /* .determine_rate = imx8m_clk_common_slice_determine_rate, */ + .get_parent = imx8m_clk_common_slice_get_parent, + .set_parent = imx8m_clk_common_slice_set_parent, +}; + +static unsigned long imx8m_clk_bus_slice_recalc_rate(const struct clk *clk, + unsigned long prate) +{ + struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); + + uint32_t prediv_val = regmap_read_bits(clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); + /* Divider value is n+1 */ + unsigned long prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, prediv_val + 1); + + uint32_t postdiv_val = regmap_read_bits(clk->base, data->offset, data->postdiv_shift, data->postdiv_width); + /* Divider value is n+1 */ + return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); +} + +static uint8_t imx8m_clk_bus_slice_get_parent(const struct clk *clk) +{ + struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); + + uint32_t num_parents = clk->hw.init->num_parents; + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); + + if (val >= num_parents) + return -1; + + return val; +} + +static int imx8m_clk_bus_slice_set_parent(struct clk *clk, uint8_t index) +{ + struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); + + /* + * write twice to make sure non-target interface + * SEL_A/B point the same clk input. + */ + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + + return 0; +} + +const struct clk_ops clk_bus_slice_ops = { + .recalc_rate = imx8m_clk_bus_slice_recalc_rate, + /* .round_rate = imx8m_clk_composite_divider_round_rate, */ + /* .set_rate = imx8m_clk_composite_divider_set_rate, */ + /* .determine_rate = imx8m_divider_determine_rate, */ + .get_parent = imx8m_clk_bus_slice_get_parent, + .set_parent = imx8m_clk_bus_slice_set_parent, +}; diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c new file mode 100644 index 000000000..059c51b43 --- /dev/null +++ b/drivers/clk/imx/clk-imx8mq.c @@ -0,0 +1,1518 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2017-2018 NXP. + * + * Derived from: https://github.com/torvalds/linux/blob/75b607fab38d149f232f01eae5e6392b394dd659/drivers/clk/imx/clk-imx8mm.c + */ + +#include +#include +#include +#include +#include +#include +#include + + +static struct clk_parent_data pll_ref_sels[] = { + { .name = "osc_25m", }, + { .name = "osc_27m", }, + { .name = "hdmi_phy_27m", }, + { .name = "dummy", }, +}; + +static struct clk_parent_data arm_pll_bypass_sels[] = { + { .name = "arm_pll", }, + { .name = "arm_pll_ref_sel", }, +}; + +static struct clk_parent_data gpu_pll_bypass_sels[] = { + { .name = "gpu_pll", }, + { .name = "gpu_pll_ref_sel", }, +}; + +static struct clk_parent_data vpu_pll_bypass_sels[] = { + { .name = "vpu_pll", }, + { .name = "vpu_pll_ref_sel", }, +}; + +static struct clk_parent_data audio_pll1_bypass_sels[] = { + { .name = "audio_pll1", }, + { .name = "audio_pll1_ref_sel", }, +}; + +static struct clk_parent_data audio_pll2_bypass_sels[] = { + { .name = "audio_pll2", }, + { .name = "audio_pll2_ref_sel", }, +}; + +static struct clk_parent_data video_pll1_bypass_sels[] = { + { .name = "video_pll1", }, + { .name = "video_pll1_ref_sel", }, +}; + +static struct clk_parent_data sys3_pll_out_sels[] = { + { .name = "sys3_pll1_ref_sel", }, +}; + +static struct clk_parent_data dram_pll_out_sels[] = { + { .name = "dram_pll1_ref_sel", }, +}; + +static struct clk_parent_data video2_pll_out_sels[] = { + { .name = "video2_pll1_ref_sel", }, +}; + +static struct clk_parent_data imx8mq_a53_sels[] = { + { .name = "osc_25m", }, + { .name = "arm_pll_out", }, + { .name = "sys2_pll_500m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys1_pll_400m", }, + { .name = "audio_pll1_out", }, + { .name = "sys3_pll_out", }, +}; + +static struct clk_parent_data imx8mq_a53_core_sels[] = { + { .name = "arm_a53_div", }, + { .name = "arm_pll_out", }, +}; + +static struct clk_parent_data imx8mq_arm_m4_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys2_pll_250m", }, + { .name = "sys1_pll_266m", }, + { .name = "sys1_pll_800m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "sys3_pll_out", }, +}; + +static struct clk_parent_data imx8mq_vpu_sels[] = { + { .name = "osc_25m", }, + { .name = "arm_pll_out", }, + { .name = "sys2_pll_500m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys1_pll_400m", }, + { .name = "audio_pll1_out", }, + { .name = "vpu_pll_out", }, +}; + +static struct clk_parent_data imx8mq_gpu_core_sels[] = { + { .name = "osc_25m", }, + { .name = "gpu_pll_out", }, + { .name = "sys1_pll_800m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_1000m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_gpu_shader_sels[] = { + { .name = "osc_25m", }, + { .name = "gpu_pll_out", }, + { .name = "sys1_pll_800m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_1000m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_main_axi_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_333m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_250m", }, + { .name = "sys2_pll_1000m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "sys1_pll_100m", }, +}; + +static struct clk_parent_data imx8mq_enet_axi_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_266m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_250m", }, + { .name = "sys2_pll_200m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "sys3_pll_out", }, +}; + +static struct clk_parent_data imx8mq_nand_usdhc_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_266m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_133m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_250m", }, + { .name = "audio_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_vpu_bus_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_800m", }, + { .name = "vpu_pll_out", }, + { .name = "audio_pll2_out", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_100m", }, +}; + +static struct clk_parent_data imx8mq_disp_axi_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_125m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys3_pll_out", }, + { .name = "sys1_pll_400m", }, + { .name = "audio_pll2_out", }, + { .name = "clk_ext1", }, + { .name = "clk_ext4", }, +}; + +static struct clk_parent_data imx8mq_disp_apb_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_125m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys3_pll_out", }, + { .name = "sys1_pll_40m", }, + { .name = "audio_pll2_out", }, + { .name = "clk_ext1", }, + { .name = "clk_ext3", }, +}; + +static struct clk_parent_data imx8mq_disp_rtrm_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_400m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, +}; + +static struct clk_parent_data imx8mq_usb_bus_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_500m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys2_pll_200m", }, + { .name = "clk_ext2", }, + { .name = "clk_ext4", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_gpu_axi_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_800m", }, + { .name = "gpu_pll_out", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_1000m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_gpu_ahb_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_800m", }, + { .name = "gpu_pll_out", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_1000m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_noc_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys2_pll_500m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_noc_apb_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_400m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_333m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_800m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_ahb_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_133m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys1_pll_400m", }, + { .name = "sys2_pll_125m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_audio_ahb_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_500m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys2_pll_166m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_dsi_ahb_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_80m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext3", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_dram_alt_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys1_pll_100m", }, + { .name = "sys2_pll_500m", }, + { .name = "sys2_pll_250m", }, + { .name = "sys1_pll_400m", }, + { .name = "audio_pll1_out", }, + { .name = "sys1_pll_266m", }, +}; + +static struct clk_parent_data imx8mq_dram_apb_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_250m", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_vpu_g1_sels[] = { + { .name = "osc_25m", }, + { .name = "vpu_pll_out", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys1_pll_100m", }, + { .name = "sys2_pll_125m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_vpu_g2_sels[] = { + { .name = "osc_25m", }, + { .name = "vpu_pll_out", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys1_pll_100m", }, + { .name = "sys2_pll_125m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_disp_dtrc_sels[] = { + { .name = "osc_25m", }, + { .name = "vpu_pll_out", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_disp_dc8000_sels[] = { + { .name = "osc_25m", }, + { .name = "vpu_pll_out", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_pcie1_ctrl_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_250m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_266m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_500m", }, + { .name = "sys2_pll_333m", }, + { .name = "sys3_pll_out", }, +}; + +static struct clk_parent_data imx8mq_pcie1_phy_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys2_pll_500m", }, + { .name = "clk_ext1", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, + { .name = "clk_ext4", }, +}; + +static struct clk_parent_data imx8mq_pcie1_aux_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys2_pll_50m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_80m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys1_pll_200m", }, +}; + +static struct clk_parent_data imx8mq_dc_pixel_sels[] = { + { .name = "osc_25m", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "audio_pll1_out", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext4", }, +}; + +static struct clk_parent_data imx8mq_lcdif_pixel_sels[] = { + { .name = "osc_25m", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "audio_pll1_out", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext4", }, +}; + +static struct clk_parent_data imx8mq_sai1_sels[] = { + { .name = "osc_25m", }, + { .name = "audio_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, + { .name = "sys1_pll_133m", }, + { .name = "osc_27m", }, + { .name = "clk_ext1", }, + { .name = "clk_ext2", }, +}; + +static struct clk_parent_data imx8mq_sai2_sels[] = { + { .name = "osc_25m", }, + { .name = "audio_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, + { .name = "sys1_pll_133m", }, + { .name = "osc_27m", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, +}; + +static struct clk_parent_data imx8mq_sai3_sels[] = { + { .name = "osc_25m", }, + { .name = "audio_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, + { .name = "sys1_pll_133m", }, + { .name = "osc_27m", }, + { .name = "clk_ext3", }, + { .name = "clk_ext4", }, +}; + +static struct clk_parent_data imx8mq_sai4_sels[] = { + { .name = "osc_25m", }, + { .name = "audio_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, + { .name = "sys1_pll_133m", }, + { .name = "osc_27m", }, + { .name = "clk_ext1", }, + { .name = "clk_ext2", }, +}; + +static struct clk_parent_data imx8mq_sai5_sels[] = { + { .name = "osc_25m", }, + { .name = "audio_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, + { .name = "sys1_pll_133m", }, + { .name = "osc_27m", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, +}; + +static struct clk_parent_data imx8mq_sai6_sels[] = { + { .name = "osc_25m", }, + { .name = "audio_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, + { .name = "sys1_pll_133m", }, + { .name = "osc_27m", }, + { .name = "clk_ext3", }, + { .name = "clk_ext4", }, +}; + +static struct clk_parent_data imx8mq_spdif1_sels[] = { + { .name = "osc_25m", }, + { .name = "audio_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, + { .name = "sys1_pll_133m", }, + { .name = "osc_27m", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, +}; + +static struct clk_parent_data imx8mq_spdif2_sels[] = { + { .name = "osc_25m", }, + { .name = "audio_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, + { .name = "sys1_pll_133m", }, + { .name = "osc_27m", }, + { .name = "clk_ext3", }, + { .name = "clk_ext4", }, +}; + +static struct clk_parent_data imx8mq_enet_ref_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_125m", }, + { .name = "sys2_pll_500m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_160m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "clk_ext4", }, +}; + +static struct clk_parent_data imx8mq_enet_timer_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "audio_pll1_out", }, + { .name = "clk_ext1", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, + { .name = "clk_ext4", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_enet_phy_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_50m", }, + { .name = "sys2_pll_125m", }, + { .name = "sys2_pll_500m", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_nand_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_500m", }, + { .name = "audio_pll1_out", }, + { .name = "sys1_pll_400m", }, + { .name = "audio_pll2_out", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_250m", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_qspi_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_400m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_500m", }, + { .name = "audio_pll2_out", }, + { .name = "sys1_pll_266m", }, + { .name = "sys3_pll_out", }, + { .name = "sys1_pll_100m", }, +}; + +static struct clk_parent_data imx8mq_usdhc1_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_400m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_500m", }, + { .name = "sys3_pll_out", }, + { .name = "sys1_pll_266m", }, + { .name = "audio_pll2_out", }, + { .name = "sys1_pll_100m", }, +}; + +static struct clk_parent_data imx8mq_usdhc2_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_400m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_500m", }, + { .name = "sys3_pll_out", }, + { .name = "sys1_pll_266m", }, + { .name = "audio_pll2_out", }, + { .name = "sys1_pll_100m", }, +}; + +static struct clk_parent_data imx8mq_i2c1_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys2_pll_50m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "sys1_pll_133m", }, +}; + +static struct clk_parent_data imx8mq_i2c2_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys2_pll_50m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "sys1_pll_133m", }, +}; + +static struct clk_parent_data imx8mq_i2c3_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys2_pll_50m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "sys1_pll_133m", }, +}; + +static struct clk_parent_data imx8mq_i2c4_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys2_pll_50m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "audio_pll2_out", }, + { .name = "sys1_pll_133m", }, +}; + +static struct clk_parent_data imx8mq_uart1_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_80m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext2", }, + { .name = "clk_ext4", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_uart2_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_80m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_uart3_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_80m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext2", }, + { .name = "clk_ext4", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_uart4_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_80m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_usb_core_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_100m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys2_pll_200m", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_usb_phy_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_100m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys2_pll_200m", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_gic_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys2_pll_200m", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_ecspi1_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_250m", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_ecspi2_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_250m", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_pwm1_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext1", }, + { .name = "sys1_pll_80m", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_pwm2_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext1", }, + { .name = "sys1_pll_80m", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_pwm3_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext2", }, + { .name = "sys1_pll_80m", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_pwm4_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext2", }, + { .name = "sys1_pll_80m", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_gpt1_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_400m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys1_pll_80m", }, + { .name = "audio_pll1_out", }, + { .name = "clk_ext1", }, +}; + +static struct clk_parent_data imx8mq_wdog_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_133m", }, + { .name = "sys1_pll_160m", }, + { .name = "vpu_pll_out", }, + { .name = "sys2_pll_125m", }, + { .name = "sys3_pll_out", }, + { .name = "sys1_pll_80m", }, + { .name = "sys2_pll_166m", }, +}; + +static struct clk_parent_data imx8mq_wrclk_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_40m", }, + { .name = "vpu_pll_out", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_266m", }, + { .name = "sys2_pll_500m", }, + { .name = "sys1_pll_100m", }, +}; + +static struct clk_parent_data imx8mq_dsi_core_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_266m", }, + { .name = "sys2_pll_250m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_dsi_phy_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_125m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "clk_ext2", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_dsi_dbi_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_266m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_dsi_esc_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_80m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext3", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_csi1_core_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_266m", }, + { .name = "sys2_pll_250m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_csi1_phy_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_125m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "clk_ext2", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_csi1_esc_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_80m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext3", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_csi2_core_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_266m", }, + { .name = "sys2_pll_250m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_csi2_phy_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_125m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "clk_ext2", }, + { .name = "audio_pll2_out", }, + { .name = "video_pll1_out", }, +}; + +static struct clk_parent_data imx8mq_csi2_esc_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_80m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_1000m", }, + { .name = "sys3_pll_out", }, + { .name = "clk_ext3", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_pcie2_ctrl_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_250m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_266m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys2_pll_500m", }, + { .name = "sys2_pll_333m", }, + { .name = "sys3_pll_out", }, +}; + +static struct clk_parent_data imx8mq_pcie2_phy_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_100m", }, + { .name = "sys2_pll_500m", }, + { .name = "clk_ext1", }, + { .name = "clk_ext2", }, + { .name = "clk_ext3", }, + { .name = "clk_ext4", }, + { .name = "sys1_pll_400m", }, +}; + +static struct clk_parent_data imx8mq_pcie2_aux_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys2_pll_50m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_100m", }, + { .name = "sys1_pll_80m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys1_pll_200m", }, +}; + +static struct clk_parent_data imx8mq_ecspi3_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_40m", }, + { .name = "sys1_pll_160m", }, + { .name = "sys1_pll_800m", }, + { .name = "sys3_pll_out", }, + { .name = "sys2_pll_250m", }, + { .name = "audio_pll2_out", }, +}; + +static struct clk_parent_data imx8mq_dram_core_sels[] = { + { .name = "dram_pll_out", }, + { .name = "dram_alt_root", }, +}; + +static struct clk_parent_data imx8mq_clko1_sels[] = { + { .name = "osc_25m", }, + { .name = "sys1_pll_800m", }, + { .name = "osc_27m", }, + { .name = "sys1_pll_200m", }, + { .name = "audio_pll2_out", }, + { .name = "sys2_pll_500m", }, + { .name = "vpu_pll_out", }, + { .name = "sys1_pll_80m", }, +}; + +static struct clk_parent_data imx8mq_clko2_sels[] = { + { .name = "osc_25m", }, + { .name = "sys2_pll_200m", }, + { .name = "sys1_pll_400m", }, + { .name = "sys2_pll_166m", }, + { .name = "sys3_pll_out", }, + { .name = "audio_pll1_out", }, + { .name = "video_pll1_out", }, + { .name = "ckil", }, +}; + +static struct clk_parent_data pllout_monitor_sels[] = { + { .name = "osc_25m", }, + { .name = "osc_27m", }, + { .name = "dummy", }, + { .name = "dummy", }, + { .name = "ckil", }, + { .name = "audio_pll1_out_monitor", }, + { .name = "audio_pll2_out_monitor", }, + { .name = "video_pll1_out_monitor", }, + { .name = "gpu_pll_out_monitor", }, + { .name = "vpu_pll_out_monitor", }, + { .name = "arm_pll_out_monitor", }, + { .name = "sys_pll1_out_monitor", }, + { .name = "sys_pll2_out_monitor", }, + { .name = "sys_pll3_out_monitor", }, + { .name = "dram_pll_out_monitor", }, + { .name = "video_pll2_out_monitor", }, +}; + + +static IMX_CLK_SOURCE(dummy, 0); +static IMX_CLK_SOURCE(ckil, 0x8000); +static IMX_CLK_SOURCE(osc_25m, 0x17d7840); +static IMX_CLK_SOURCE(osc_27m, 0x19bfcc0); +static IMX_CLK_SOURCE(clk_ext1, 0x7ed6b40); +static IMX_CLK_SOURCE(clk_ext2, 0x7ed6b40); +static IMX_CLK_SOURCE(clk_ext3, 0x7ed6b40); +static IMX_CLK_SOURCE(clk_ext4, 0x7ed6b40); + +static IMX_CLK_MUX(arm_pll_ref_sel, CCM_ANALOG_BASE, 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(gpu_pll_ref_sel, CCM_ANALOG_BASE, 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(vpu_pll_ref_sel, CCM_ANALOG_BASE, 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(audio_pll1_ref_sel, CCM_ANALOG_BASE, 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(audio_pll2_ref_sel, CCM_ANALOG_BASE, 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(video_pll1_ref_sel, CCM_ANALOG_BASE, 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(sys3_pll1_ref_sel, CCM_ANALOG_BASE, 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(dram_pll1_ref_sel, CCM_ANALOG_BASE, 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(video2_pll1_ref_sel, CCM_ANALOG_BASE, 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + +static IMX_CLK_DIV(arm_pll_ref_div, { &arm_pll_ref_sel }, CCM_ANALOG_BASE, 0x28, 5, 6); +static IMX_CLK_DIV(gpu_pll_ref_div, { &gpu_pll_ref_sel }, CCM_ANALOG_BASE, 0x18, 5, 6); +static IMX_CLK_DIV(vpu_pll_ref_div, { &vpu_pll_ref_sel }, CCM_ANALOG_BASE, 0x20, 5, 6); +static IMX_CLK_DIV(audio_pll1_ref_div, { &audio_pll1_ref_sel }, CCM_ANALOG_BASE, 0x0, 5, 6); +static IMX_CLK_DIV(audio_pll2_ref_div, { &audio_pll2_ref_sel }, CCM_ANALOG_BASE, 0x8, 5, 6); +static IMX_CLK_DIV(video_pll1_ref_div, { &video_pll1_ref_sel }, CCM_ANALOG_BASE, 0x10, 5, 6); + +static IMX_CLK_FRAC_PLL(arm_pll, { &arm_pll_ref_div }, CCM_ANALOG_BASE, 0x28); +static IMX_CLK_FRAC_PLL(gpu_pll, { &gpu_pll_ref_div }, CCM_ANALOG_BASE, 0x18); +static IMX_CLK_FRAC_PLL(vpu_pll, { &vpu_pll_ref_div }, CCM_ANALOG_BASE, 0x20); +static IMX_CLK_FRAC_PLL(audio_pll1, { &audio_pll1_ref_div }, CCM_ANALOG_BASE, 0x0); +static IMX_CLK_FRAC_PLL(audio_pll2, { &audio_pll2_ref_div }, CCM_ANALOG_BASE, 0x8); +static IMX_CLK_FRAC_PLL(video_pll1, { &video_pll1_ref_div }, CCM_ANALOG_BASE, 0x10); + +/* PLL bypass out */ +static IMX_CLK_MUX_FLAGS(arm_pll_bypass, CCM_ANALOG_BASE, 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); +static IMX_CLK_MUX(gpu_pll_bypass, CCM_ANALOG_BASE, 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels)); +static IMX_CLK_MUX(vpu_pll_bypass, CCM_ANALOG_BASE, 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels)); +static IMX_CLK_MUX(audio_pll1_bypass, CCM_ANALOG_BASE, 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels)); +static IMX_CLK_MUX(audio_pll2_bypass, CCM_ANALOG_BASE, 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels)); +static IMX_CLK_MUX(video_pll1_bypass, CCM_ANALOG_BASE, 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels)); + +/* PLL OUT GATE */ +static IMX_CLK_GATE(arm_pll_out, { &arm_pll_bypass }, CCM_ANALOG_BASE, 0x28, 21); +static IMX_CLK_GATE(gpu_pll_out, { &gpu_pll_bypass }, CCM_ANALOG_BASE, 0x18, 21); +static IMX_CLK_GATE(vpu_pll_out, { &vpu_pll_bypass }, CCM_ANALOG_BASE, 0x20, 21); +static IMX_CLK_GATE(audio_pll1_out, { &audio_pll1_bypass }, CCM_ANALOG_BASE, 0x0, 21); +static IMX_CLK_GATE(audio_pll2_out, { &audio_pll2_bypass }, CCM_ANALOG_BASE, 0x8, 21); +static IMX_CLK_GATE(video_pll1_out, { &video_pll1_bypass }, CCM_ANALOG_BASE, 0x10, 21); + +static IMX_CLK_FIXED(sys1_pll_out, 800000000); +static IMX_CLK_FIXED(sys2_pll_out, 1000000000); +static IMX_CLK_SSCG_PLL(sys3_pll_out, sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x48, CLK_IS_CRITICAL); +static IMX_CLK_SSCG_PLL(dram_pll_out, dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x60, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); +static IMX_CLK_SSCG_PLL(video2_pll_out, video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x54, 0); + +/* SYS PLL1 fixed output */ +static IMX_CLK_FIXED_FACTOR(sys1_pll_40m, { &sys1_pll_out }, 1, 20); +static IMX_CLK_FIXED_FACTOR(sys1_pll_80m, { &sys1_pll_out }, 1, 10); +static IMX_CLK_FIXED_FACTOR(sys1_pll_100m, { &sys1_pll_out }, 1, 8); +static IMX_CLK_FIXED_FACTOR(sys1_pll_133m, { &sys1_pll_out }, 1, 6); +static IMX_CLK_FIXED_FACTOR(sys1_pll_160m, { &sys1_pll_out }, 1, 5); +static IMX_CLK_FIXED_FACTOR(sys1_pll_200m, { &sys1_pll_out }, 1, 4); +static IMX_CLK_FIXED_FACTOR(sys1_pll_266m, { &sys1_pll_out }, 1, 3); +static IMX_CLK_FIXED_FACTOR(sys1_pll_400m, { &sys1_pll_out }, 1, 2); +static IMX_CLK_FIXED_FACTOR(sys1_pll_800m, { &sys1_pll_out }, 1, 1); + +/* SYS PLL2 fixed output */ +static IMX_CLK_FIXED_FACTOR(sys2_pll_50m, { &sys2_pll_out }, 1, 20); +static IMX_CLK_FIXED_FACTOR(sys2_pll_100m, { &sys2_pll_out }, 1, 10); +static IMX_CLK_FIXED_FACTOR(sys2_pll_125m, { &sys2_pll_out }, 1, 8); +static IMX_CLK_FIXED_FACTOR(sys2_pll_166m, { &sys2_pll_out }, 1, 6); +static IMX_CLK_FIXED_FACTOR(sys2_pll_200m, { &sys2_pll_out }, 1, 5); +static IMX_CLK_FIXED_FACTOR(sys2_pll_250m, { &sys2_pll_out }, 1, 4); +static IMX_CLK_FIXED_FACTOR(sys2_pll_333m, { &sys2_pll_out }, 1, 3); +static IMX_CLK_FIXED_FACTOR(sys2_pll_500m, { &sys2_pll_out }, 1, 2); +static IMX_CLK_FIXED_FACTOR(sys2_pll_1000m, { &sys2_pll_out }, 1, 1); + +static IMX_CLK_DIV(audio_pll1_out_monitor, { &audio_pll1_bypass }, CCM_ANALOG_BASE, 0x78, 0, 3); +static IMX_CLK_DIV(audio_pll2_out_monitor, { &audio_pll2_bypass }, CCM_ANALOG_BASE, 0x78, 4, 3); +static IMX_CLK_DIV(video_pll1_out_monitor, { &video_pll1_bypass }, CCM_ANALOG_BASE, 0x78, 8, 3); +static IMX_CLK_DIV(gpu_pll_out_monitor, { &gpu_pll_bypass }, CCM_ANALOG_BASE, 0x78, 12, 3); +static IMX_CLK_DIV(vpu_pll_out_monitor, { &vpu_pll_bypass }, CCM_ANALOG_BASE, 0x78, 16, 3); +static IMX_CLK_DIV(arm_pll_out_monitor, { &arm_pll_bypass }, CCM_ANALOG_BASE, 0x78, 20, 3); +static IMX_CLK_DIV(sys_pll1_out_monitor, { &sys1_pll_out }, CCM_ANALOG_BASE, 0x7c, 0, 3); +static IMX_CLK_DIV(sys_pll2_out_monitor, { &sys2_pll_out }, CCM_ANALOG_BASE, 0x7c, 4, 3); +static IMX_CLK_DIV(sys_pll3_out_monitor, { &sys3_pll_out }, CCM_ANALOG_BASE, 0x7c, 8, 3); +static IMX_CLK_DIV(dram_pll_out_monitor, { &dram_pll_out }, CCM_ANALOG_BASE, 0x7c, 12, 3); +static IMX_CLK_DIV(video_pll2_out_monitor, { &video2_pll_out }, CCM_ANALOG_BASE, 0x7c, 16, 3); +static IMX_CLK_MUX(pllout_monitor_sel, CCM_ANALOG_BASE, 0x74, 0, 4, pllout_monitor_sels, ARRAY_SIZE(pllout_monitor_sels)); +static IMX_CLK_GATE(pllout_monitor_clk2, { &pllout_monitor_sel }, CCM_ANALOG_BASE, 0x74, 4); + +/* CORE */ +static IMX_CLK_COMPOSITE_CORE(arm_a53_div, imx8mq_a53_sels, CCM_BASE, 0x8000); + +static IMX_CLK_COMPOSITE_CORE(arm_m4_core, imx8mq_arm_m4_sels, CCM_BASE, 0x8080); +static IMX_CLK_COMPOSITE_CORE(vpu_core, imx8mq_vpu_sels, CCM_BASE, 0x8100); +static IMX_CLK_COMPOSITE_CORE(gpu_core, imx8mq_gpu_core_sels, CCM_BASE, 0x8180); +static IMX_CLK_COMPOSITE(gpu_shader, imx8mq_gpu_shader_sels, CCM_BASE, 0x8200); + +/* CORE SEL */ +static IMX_CLK_MUX2(arm_a53_core, CCM_BASE, 0x9880, 24, 1, imx8mq_a53_core_sels, ARRAY_SIZE(imx8mq_a53_core_sels)); + +/* BUS */ +static IMX_CLK_COMPOSITE_BUS(main_axi, imx8mq_main_axi_sels, CCM_BASE, 0x8800); +static IMX_CLK_COMPOSITE_BUS(enet_axi, imx8mq_enet_axi_sels, CCM_BASE, 0x8880); +static IMX_CLK_COMPOSITE_BUS(nand_usdhc_bus, imx8mq_nand_usdhc_sels, CCM_BASE, 0x8900); +static IMX_CLK_COMPOSITE_BUS(vpu_bus, imx8mq_vpu_bus_sels, CCM_BASE, 0x8980); +static IMX_CLK_COMPOSITE_BUS(disp_axi, imx8mq_disp_axi_sels, CCM_BASE, 0x8a00); +static IMX_CLK_COMPOSITE_BUS(disp_apb, imx8mq_disp_apb_sels, CCM_BASE, 0x8a80); +static IMX_CLK_COMPOSITE_BUS(disp_rtrm, imx8mq_disp_rtrm_sels, CCM_BASE, 0x8b00); +static IMX_CLK_COMPOSITE_BUS(usb_bus, imx8mq_usb_bus_sels, CCM_BASE, 0x8b80); +static IMX_CLK_COMPOSITE_BUS(gpu_axi, imx8mq_gpu_axi_sels, CCM_BASE, 0x8c00); +static IMX_CLK_COMPOSITE_BUS(gpu_ahb, imx8mq_gpu_ahb_sels, CCM_BASE, 0x8c80); +static IMX_CLK_COMPOSITE_BUS(noc, imx8mq_noc_sels, CCM_BASE, 0x8d00); +static IMX_CLK_COMPOSITE_BUS(noc_apb, imx8mq_noc_apb_sels, CCM_BASE, 0x8d80); + +/* AHB */ +/* AHB clock is used by the AHB bus therefore marked as critical */ +static IMX_CLK_COMPOSITE_BUS(ahb, imx8mq_ahb_sels, CCM_BASE, 0x9000); +static IMX_CLK_COMPOSITE_BUS(audio_ahb, imx8mq_audio_ahb_sels, CCM_BASE, 0x9100); + +/* IPG */ +static IMX_CLK_DIV2(ipg_root, { &ahb }, CCM_BASE, 0x9080, 0, 1); +static IMX_CLK_DIV2(ipg_audio_root, { &audio_ahb }, CCM_BASE, 0x9180, 0, 1); + +/* + * DRAM clocks are manipulated from TF-A outside clock framework. + * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE + * as div value should always be read from hardware + */ +static IMX_CLK_MUX2_FLAGS(dram_core_clk, CCM_BASE, 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL); +static IMX_CLK_COMPOSITE_FW_MANAGED(dram_alt, imx8mq_dram_alt_sels, CCM_BASE, 0xa000); +static IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(dram_apb, imx8mq_dram_apb_sels, CCM_BASE, 0xa080); + +/* IP */ +static IMX_CLK_COMPOSITE(vpu_g1, imx8mq_vpu_g1_sels, CCM_BASE, 0xa100); +static IMX_CLK_COMPOSITE(vpu_g2, imx8mq_vpu_g2_sels, CCM_BASE, 0xa180); +static IMX_CLK_COMPOSITE(disp_dtrc, imx8mq_disp_dtrc_sels, CCM_BASE, 0xa200); +static IMX_CLK_COMPOSITE(disp_dc8000, imx8mq_disp_dc8000_sels, CCM_BASE, 0xa280); +static IMX_CLK_COMPOSITE(pcie1_ctrl, imx8mq_pcie1_ctrl_sels, CCM_BASE, 0xa300); +static IMX_CLK_COMPOSITE(pcie1_phy, imx8mq_pcie1_phy_sels, CCM_BASE, 0xa380); +static IMX_CLK_COMPOSITE(pcie1_aux, imx8mq_pcie1_aux_sels, CCM_BASE, 0xa400); +static IMX_CLK_COMPOSITE(dc_pixel, imx8mq_dc_pixel_sels, CCM_BASE, 0xa480); +static IMX_CLK_COMPOSITE(lcdif_pixel, imx8mq_lcdif_pixel_sels, CCM_BASE, 0xa500); +static IMX_CLK_COMPOSITE(sai1, imx8mq_sai1_sels, CCM_BASE, 0xa580); +static IMX_CLK_COMPOSITE(sai2, imx8mq_sai2_sels, CCM_BASE, 0xa600); +static IMX_CLK_COMPOSITE(sai3, imx8mq_sai3_sels, CCM_BASE, 0xa680); +static IMX_CLK_COMPOSITE(sai4, imx8mq_sai4_sels, CCM_BASE, 0xa700); +static IMX_CLK_COMPOSITE(sai5, imx8mq_sai5_sels, CCM_BASE, 0xa780); +static IMX_CLK_COMPOSITE(sai6, imx8mq_sai6_sels, CCM_BASE, 0xa800); +static IMX_CLK_COMPOSITE(spdif1, imx8mq_spdif1_sels, CCM_BASE, 0xa880); +static IMX_CLK_COMPOSITE(spdif2, imx8mq_spdif2_sels, CCM_BASE, 0xa900); +static IMX_CLK_COMPOSITE(enet_ref, imx8mq_enet_ref_sels, CCM_BASE, 0xa980); +static IMX_CLK_COMPOSITE(enet_timer, imx8mq_enet_timer_sels, CCM_BASE, 0xaa00); +static IMX_CLK_COMPOSITE(enet_phy, imx8mq_enet_phy_sels, CCM_BASE, 0xaa80); +static IMX_CLK_COMPOSITE(nand, imx8mq_nand_sels, CCM_BASE, 0xab00); +static IMX_CLK_COMPOSITE(qspi, imx8mq_qspi_sels, CCM_BASE, 0xab80); +static IMX_CLK_COMPOSITE(usdhc1, imx8mq_usdhc1_sels, CCM_BASE, 0xac00); +static IMX_CLK_COMPOSITE(usdhc2, imx8mq_usdhc2_sels, CCM_BASE, 0xac80); +static IMX_CLK_COMPOSITE(i2c1, imx8mq_i2c1_sels, CCM_BASE, 0xad00); +static IMX_CLK_COMPOSITE(i2c2, imx8mq_i2c2_sels, CCM_BASE, 0xad80); +static IMX_CLK_COMPOSITE(i2c3, imx8mq_i2c3_sels, CCM_BASE, 0xae00); +static IMX_CLK_COMPOSITE(i2c4, imx8mq_i2c4_sels, CCM_BASE, 0xae80); +static IMX_CLK_COMPOSITE(uart1, imx8mq_uart1_sels, CCM_BASE, 0xaf00); +static IMX_CLK_COMPOSITE(uart2, imx8mq_uart2_sels, CCM_BASE, 0xaf80); +static IMX_CLK_COMPOSITE(uart3, imx8mq_uart3_sels, CCM_BASE, 0xb000); +static IMX_CLK_COMPOSITE(uart4, imx8mq_uart4_sels, CCM_BASE, 0xb080); +static IMX_CLK_COMPOSITE(usb_core_ref, imx8mq_usb_core_sels, CCM_BASE, 0xb100); +static IMX_CLK_COMPOSITE(usb_phy_ref, imx8mq_usb_phy_sels, CCM_BASE, 0xb180); +static IMX_CLK_COMPOSITE(gic, imx8mq_gic_sels, CCM_BASE, 0xb200); +static IMX_CLK_COMPOSITE(ecspi1, imx8mq_ecspi1_sels, CCM_BASE, 0xb280); +static IMX_CLK_COMPOSITE(ecspi2, imx8mq_ecspi2_sels, CCM_BASE, 0xb300); +static IMX_CLK_COMPOSITE(pwm1, imx8mq_pwm1_sels, CCM_BASE, 0xb380); +static IMX_CLK_COMPOSITE(pwm2, imx8mq_pwm2_sels, CCM_BASE, 0xb400); +static IMX_CLK_COMPOSITE(pwm3, imx8mq_pwm3_sels, CCM_BASE, 0xb480); +static IMX_CLK_COMPOSITE(pwm4, imx8mq_pwm4_sels, CCM_BASE, 0xb500); +static IMX_CLK_COMPOSITE(gpt1, imx8mq_gpt1_sels, CCM_BASE, 0xb580); +static IMX_CLK_COMPOSITE(wdog, imx8mq_wdog_sels, CCM_BASE, 0xb900); +static IMX_CLK_COMPOSITE(wrclk, imx8mq_wrclk_sels, CCM_BASE, 0xb980); +static IMX_CLK_COMPOSITE(clko1, imx8mq_clko1_sels, CCM_BASE, 0xba00); +static IMX_CLK_COMPOSITE(clko2, imx8mq_clko2_sels, CCM_BASE, 0xba80); +static IMX_CLK_COMPOSITE(dsi_core, imx8mq_dsi_core_sels, CCM_BASE, 0xbb00); +static IMX_CLK_COMPOSITE(dsi_phy_ref, imx8mq_dsi_phy_sels, CCM_BASE, 0xbb80); +static IMX_CLK_COMPOSITE(dsi_dbi, imx8mq_dsi_dbi_sels, CCM_BASE, 0xbc00); +static IMX_CLK_COMPOSITE(dsi_esc, imx8mq_dsi_esc_sels, CCM_BASE, 0xbc80); +static IMX_CLK_COMPOSITE(dsi_ahb, imx8mq_dsi_ahb_sels, CCM_BASE, 0x9200); +static IMX_CLK_DIV2(dsi_ipg_div, { &dsi_ahb }, CCM_BASE, 0x9280, 0, 6); +static IMX_CLK_COMPOSITE(csi1_core, imx8mq_csi1_core_sels, CCM_BASE, 0xbd00); +static IMX_CLK_COMPOSITE(csi1_phy_ref, imx8mq_csi1_phy_sels, CCM_BASE, 0xbd80); +static IMX_CLK_COMPOSITE(csi1_esc, imx8mq_csi1_esc_sels, CCM_BASE, 0xbe00); +static IMX_CLK_COMPOSITE(csi2_core, imx8mq_csi2_core_sels, CCM_BASE, 0xbe80); +static IMX_CLK_COMPOSITE(csi2_phy_ref, imx8mq_csi2_phy_sels, CCM_BASE, 0xbf00); +static IMX_CLK_COMPOSITE(csi2_esc, imx8mq_csi2_esc_sels, CCM_BASE, 0xbf80); +static IMX_CLK_COMPOSITE(pcie2_ctrl, imx8mq_pcie2_ctrl_sels, CCM_BASE, 0xc000); +static IMX_CLK_COMPOSITE(pcie2_phy, imx8mq_pcie2_phy_sels, CCM_BASE, 0xc080); +static IMX_CLK_COMPOSITE(pcie2_aux, imx8mq_pcie2_aux_sels, CCM_BASE, 0xc100); +static IMX_CLK_COMPOSITE(ecspi3, imx8mq_ecspi3_sels, CCM_BASE, 0xc180); + +static IMX_CLK_GATE4(ecspi1_root_clk, { &ecspi1 }, CCM_BASE, 0x4070, 0); +static IMX_CLK_GATE4(ecspi2_root_clk, { &ecspi2 }, CCM_BASE, 0x4080, 0); +static IMX_CLK_GATE4(ecspi3_root_clk, { &ecspi3 }, CCM_BASE, 0x4090, 0); +static IMX_CLK_GATE4(enet1_root_clk, { &enet_axi }, CCM_BASE, 0x40a0, 0); +static IMX_CLK_GATE4(gpio1_root_clk, { &ipg_root }, CCM_BASE, 0x40b0, 0); +static IMX_CLK_GATE4(gpio2_root_clk, { &ipg_root }, CCM_BASE, 0x40c0, 0); +static IMX_CLK_GATE4(gpio3_root_clk, { &ipg_root }, CCM_BASE, 0x40d0, 0); +static IMX_CLK_GATE4(gpio4_root_clk, { &ipg_root }, CCM_BASE, 0x40e0, 0); +static IMX_CLK_GATE4(gpio5_root_clk, { &ipg_root }, CCM_BASE, 0x40f0, 0); +static IMX_CLK_GATE4(gpt1_root_clk, { &gpt1 }, CCM_BASE, 0x4100, 0); +static IMX_CLK_GATE4(i2c1_root_clk, { &i2c1 }, CCM_BASE, 0x4170, 0); +static IMX_CLK_GATE4(i2c2_root_clk, { &i2c2 }, CCM_BASE, 0x4180, 0); +static IMX_CLK_GATE4(i2c3_root_clk, { &i2c3 }, CCM_BASE, 0x4190, 0); +static IMX_CLK_GATE4(i2c4_root_clk, { &i2c4 }, CCM_BASE, 0x41a0, 0); +static IMX_CLK_GATE4(mu_root_clk, { &ipg_root }, CCM_BASE, 0x4210, 0); +static IMX_CLK_GATE4(ocotp_root_clk, { &ipg_root }, CCM_BASE, 0x4220, 0); +static IMX_CLK_GATE4(pcie1_root_clk, { &pcie1_ctrl }, CCM_BASE, 0x4250, 0); +static IMX_CLK_GATE4(pcie2_root_clk, { &pcie2_ctrl }, CCM_BASE, 0x4640, 0); +static IMX_CLK_GATE4(pwm1_root_clk, { &pwm1 }, CCM_BASE, 0x4280, 0); +static IMX_CLK_GATE4(pwm2_root_clk, { &pwm2 }, CCM_BASE, 0x4290, 0); +static IMX_CLK_GATE4(pwm3_root_clk, { &pwm3 }, CCM_BASE, 0x42a0, 0); +static IMX_CLK_GATE4(pwm4_root_clk, { &pwm4 }, CCM_BASE, 0x42b0, 0); +static IMX_CLK_GATE4(qspi_root_clk, { &qspi }, CCM_BASE, 0x42f0, 0); + +static IMX_CLK_GATE2_SHARED2(nand_root_clk, { &nand }, CCM_BASE, 0x4300, 0, &share_count_nand); +static IMX_CLK_GATE2_SHARED2(nand_usdhc_rawnand_clk, { &nand_usdhc_bus }, CCM_BASE, 0x4300, 0, &share_count_nand); +static IMX_CLK_GATE2_SHARED2(sai1_root_clk, { &sai1 }, CCM_BASE, 0x4330, 0, &share_count_sai1); +static IMX_CLK_GATE2_SHARED2(sai1_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4330, 0, &share_count_sai1); +static IMX_CLK_GATE2_SHARED2(sai2_root_clk, { &sai2 }, CCM_BASE, 0x4340, 0, &share_count_sai2); +static IMX_CLK_GATE2_SHARED2(sai2_ipg_clk, { &ipg_root }, CCM_BASE, 0x4340, 0, &share_count_sai2); +static IMX_CLK_GATE2_SHARED2(sai3_root_clk, { &sai3 }, CCM_BASE, 0x4350, 0, &share_count_sai3); +static IMX_CLK_GATE2_SHARED2(sai3_ipg_clk, { &ipg_root }, CCM_BASE, 0x4350, 0, &share_count_sai3); +static IMX_CLK_GATE2_SHARED2(sai4_root_clk, { &sai4 }, CCM_BASE, 0x4360, 0, &share_count_sai4); +static IMX_CLK_GATE2_SHARED2(sai4_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4360, 0, &share_count_sai4); +static IMX_CLK_GATE2_SHARED2(sai5_root_clk, { &sai5 }, CCM_BASE, 0x4370, 0, &share_count_sai5); +static IMX_CLK_GATE2_SHARED2(sai5_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4370, 0, &share_count_sai5); +static IMX_CLK_GATE2_SHARED2(sai6_root_clk, { &sai6 }, CCM_BASE, 0x4380, 0, &share_count_sai6); +static IMX_CLK_GATE2_SHARED2(sai6_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4380, 0, &share_count_sai6); +static IMX_CLK_GATE4(uart1_root_clk, { &uart1 }, CCM_BASE, 0x4490, 0); +static IMX_CLK_GATE4(uart2_root_clk, { &uart2 }, CCM_BASE, 0x44a0, 0); +static IMX_CLK_GATE4(uart3_root_clk, { &uart3 }, CCM_BASE, 0x44b0, 0); +static IMX_CLK_GATE4(uart4_root_clk, { &uart4 }, CCM_BASE, 0x44c0, 0); +static IMX_CLK_GATE4(usb1_ctrl_root_clk, { &usb_bus }, CCM_BASE, 0x44d0, 0); +static IMX_CLK_GATE4(usb2_ctrl_root_clk, { &usb_bus }, CCM_BASE, 0x44e0, 0); +static IMX_CLK_GATE4(usb1_phy_root_clk, { &usb_phy_ref }, CCM_BASE, 0x44f0, 0); +static IMX_CLK_GATE4(usb2_phy_root_clk, { &usb_phy_ref }, CCM_BASE, 0x4500, 0); +static IMX_CLK_GATE4(usdhc1_root_clk, { &usdhc1 }, CCM_BASE, 0x4510, 0); +static IMX_CLK_GATE4(usdhc2_root_clk, { &usdhc2 }, CCM_BASE, 0x4520, 0); +static IMX_CLK_GATE4(wdog1_root_clk, { &wdog }, CCM_BASE, 0x4530, 0); +static IMX_CLK_GATE4(wdog2_root_clk, { &wdog }, CCM_BASE, 0x4540, 0); +static IMX_CLK_GATE4(wdog3_root_clk, { &wdog }, CCM_BASE, 0x4550, 0); +static IMX_CLK_GATE2_FLAGS(vpu_g1_root_clk, { &vpu_g1 }, CCM_BASE, 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); +static IMX_CLK_GATE4(gpu_root_clk, { &gpu_core }, CCM_BASE, 0x4570, 0); +static IMX_CLK_GATE2_FLAGS(vpu_g2_root_clk, { &vpu_g2 }, CCM_BASE, 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); +static IMX_CLK_GATE2_SHARED2(disp_root_clk, { &disp_dc8000 }, CCM_BASE, 0x45d0, 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_axi_root_clk, { &disp_axi }, CCM_BASE, 0x45d0, 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_apb_root_clk, { &disp_apb }, CCM_BASE, 0x45d0, 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_rtrm_root_clk, { &disp_rtrm }, CCM_BASE, 0x45d0, 0, &share_count_dcss); +static IMX_CLK_GATE4(tmu_root_clk, { &ipg_root }, CCM_BASE, 0x4620, 0); +static IMX_CLK_GATE2_FLAGS(vpu_dec_root_clk, { &vpu_bus }, CCM_BASE, 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); +static IMX_CLK_GATE4(csi1_root_clk, { &csi1_core }, CCM_BASE, 0x4650, 0); +static IMX_CLK_GATE4(csi2_root_clk, { &csi2_core }, CCM_BASE, 0x4660, 0); +static IMX_CLK_GATE4(sdma1_clk, { &ipg_root }, CCM_BASE, 0x43a0, 0); +static IMX_CLK_GATE4(sdma2_clk, { &ipg_audio_root }, CCM_BASE, 0x43b0, 0); + +static IMX_CLK_FIXED_FACTOR(gpt_3m, { &osc_25m }, 1, 8); +static IMX_CLK_FIXED_FACTOR(dram_alt_root, { &dram_alt }, 1, 4); + +/* hws[IMX8MQ_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core", */ +/* hws[IMX8MQ_CLK_A53_CORE]->clk, */ +/* hws[IMX8MQ_CLK_A53_CORE]->clk, */ +/* hws[IMX8MQ_ARM_PLL_OUT]->clk, */ +/* hws[IMX8MQ_CLK_A53_DIV]->clk); */ + +static struct clk *imx8mq_clks[IMX8MQ_CLK_END] = { + [IMX8MQ_CLK_DUMMY] = &dummy, + [IMX8MQ_CLK_32K] = &ckil, + [IMX8MQ_CLK_25M] = &osc_25m, + [IMX8MQ_CLK_27M] = &osc_27m, + [IMX8MQ_CLK_EXT1] = &clk_ext1, + [IMX8MQ_CLK_EXT2] = &clk_ext2, + [IMX8MQ_CLK_EXT3] = &clk_ext3, + [IMX8MQ_CLK_EXT4] = &clk_ext4, + [IMX8MQ_ARM_PLL_REF_SEL] = &arm_pll_ref_sel, + [IMX8MQ_GPU_PLL_REF_SEL] = &gpu_pll_ref_sel, + [IMX8MQ_VPU_PLL_REF_SEL] = &vpu_pll_ref_sel, + [IMX8MQ_AUDIO_PLL1_REF_SEL] = &audio_pll1_ref_sel, + [IMX8MQ_AUDIO_PLL2_REF_SEL] = &audio_pll2_ref_sel, + [IMX8MQ_VIDEO_PLL1_REF_SEL] = &video_pll1_ref_sel, + [IMX8MQ_SYS3_PLL1_REF_SEL] = &sys3_pll1_ref_sel, + [IMX8MQ_DRAM_PLL1_REF_SEL] = &dram_pll1_ref_sel, + [IMX8MQ_VIDEO2_PLL1_REF_SEL] = &video2_pll1_ref_sel, + [IMX8MQ_ARM_PLL_REF_DIV] = &arm_pll_ref_div, + [IMX8MQ_GPU_PLL_REF_DIV] = &gpu_pll_ref_div, + [IMX8MQ_VPU_PLL_REF_DIV] = &vpu_pll_ref_div, + [IMX8MQ_AUDIO_PLL1_REF_DIV] = &audio_pll1_ref_div, + [IMX8MQ_AUDIO_PLL2_REF_DIV] = &audio_pll2_ref_div, + [IMX8MQ_VIDEO_PLL1_REF_DIV] = &video_pll1_ref_div, + [IMX8MQ_ARM_PLL] = &arm_pll, + [IMX8MQ_GPU_PLL] = &gpu_pll, + [IMX8MQ_VPU_PLL] = &vpu_pll, + [IMX8MQ_AUDIO_PLL1] = &audio_pll1, + [IMX8MQ_AUDIO_PLL2] = &audio_pll2, + [IMX8MQ_VIDEO_PLL1] = &video_pll1, + [IMX8MQ_ARM_PLL_BYPASS] = &arm_pll_bypass, + [IMX8MQ_GPU_PLL_BYPASS] = &gpu_pll_bypass, + [IMX8MQ_VPU_PLL_BYPASS] = &vpu_pll_bypass, + [IMX8MQ_AUDIO_PLL1_BYPASS] = &audio_pll1_bypass, + [IMX8MQ_AUDIO_PLL2_BYPASS] = &audio_pll2_bypass, + [IMX8MQ_VIDEO_PLL1_BYPASS] = &video_pll1_bypass, + [IMX8MQ_ARM_PLL_OUT] = &arm_pll_out, + [IMX8MQ_GPU_PLL_OUT] = &gpu_pll_out, + [IMX8MQ_VPU_PLL_OUT] = &vpu_pll_out, + [IMX8MQ_AUDIO_PLL1_OUT] = &audio_pll1_out, + [IMX8MQ_AUDIO_PLL2_OUT] = &audio_pll2_out, + [IMX8MQ_VIDEO_PLL1_OUT] = &video_pll1_out, + [IMX8MQ_SYS1_PLL_OUT] = &sys1_pll_out, + [IMX8MQ_SYS2_PLL_OUT] = &sys2_pll_out, + [IMX8MQ_SYS3_PLL_OUT] = &sys3_pll_out, + [IMX8MQ_DRAM_PLL_OUT] = &dram_pll_out, + [IMX8MQ_VIDEO2_PLL_OUT] = &video2_pll_out, + [IMX8MQ_SYS1_PLL_40M] = &sys1_pll_40m, + [IMX8MQ_SYS1_PLL_80M] = &sys1_pll_80m, + [IMX8MQ_SYS1_PLL_100M] = &sys1_pll_100m, + [IMX8MQ_SYS1_PLL_133M] = &sys1_pll_133m, + [IMX8MQ_SYS1_PLL_160M] = &sys1_pll_160m, + [IMX8MQ_SYS1_PLL_200M] = &sys1_pll_200m, + [IMX8MQ_SYS1_PLL_266M] = &sys1_pll_266m, + [IMX8MQ_SYS1_PLL_400M] = &sys1_pll_400m, + [IMX8MQ_SYS1_PLL_800M] = &sys1_pll_800m, + [IMX8MQ_SYS2_PLL_50M] = &sys2_pll_50m, + [IMX8MQ_SYS2_PLL_100M] = &sys2_pll_100m, + [IMX8MQ_SYS2_PLL_125M] = &sys2_pll_125m, + [IMX8MQ_SYS2_PLL_166M] = &sys2_pll_166m, + [IMX8MQ_SYS2_PLL_200M] = &sys2_pll_200m, + [IMX8MQ_SYS2_PLL_250M] = &sys2_pll_250m, + [IMX8MQ_SYS2_PLL_333M] = &sys2_pll_333m, + [IMX8MQ_SYS2_PLL_500M] = &sys2_pll_500m, + [IMX8MQ_SYS2_PLL_1000M] = &sys2_pll_1000m, + [IMX8MQ_CLK_MON_AUDIO_PLL1_DIV] = &audio_pll1_out_monitor, + [IMX8MQ_CLK_MON_AUDIO_PLL2_DIV] = &audio_pll2_out_monitor, + [IMX8MQ_CLK_MON_VIDEO_PLL1_DIV] = &video_pll1_out_monitor, + [IMX8MQ_CLK_MON_GPU_PLL_DIV] = &gpu_pll_out_monitor, + [IMX8MQ_CLK_MON_VPU_PLL_DIV] = &vpu_pll_out_monitor, + [IMX8MQ_CLK_MON_ARM_PLL_DIV] = &arm_pll_out_monitor, + [IMX8MQ_CLK_MON_SYS_PLL1_DIV] = &sys_pll1_out_monitor, + [IMX8MQ_CLK_MON_SYS_PLL2_DIV] = &sys_pll2_out_monitor, + [IMX8MQ_CLK_MON_SYS_PLL3_DIV] = &sys_pll3_out_monitor, + [IMX8MQ_CLK_MON_DRAM_PLL_DIV] = &dram_pll_out_monitor, + [IMX8MQ_CLK_MON_VIDEO_PLL2_DIV] = &video_pll2_out_monitor, + [IMX8MQ_CLK_MON_SEL] = &pllout_monitor_sel, + [IMX8MQ_CLK_MON_CLK2_OUT] = &pllout_monitor_clk2, + [IMX8MQ_CLK_A53_DIV] = &arm_a53_div, + [IMX8MQ_CLK_A53_CG] = &arm_a53_div, + [IMX8MQ_CLK_A53_SRC] = &arm_a53_div, + [IMX8MQ_CLK_M4_CORE] = &arm_m4_core, + [IMX8MQ_CLK_VPU_CORE] = &vpu_core, + [IMX8MQ_CLK_GPU_CORE] = &gpu_core, + [IMX8MQ_CLK_GPU_SHADER] = &gpu_shader, + [IMX8MQ_CLK_M4_SRC] = &arm_m4_core, + [IMX8MQ_CLK_M4_CG] = &arm_m4_core, + [IMX8MQ_CLK_M4_DIV] = &arm_m4_core, + [IMX8MQ_CLK_VPU_SRC] = &vpu_core, + [IMX8MQ_CLK_VPU_CG] = &vpu_core, + [IMX8MQ_CLK_VPU_DIV] = &vpu_core, + [IMX8MQ_CLK_GPU_CORE_SRC] = &gpu_core, + [IMX8MQ_CLK_GPU_CORE_CG] = &gpu_core, + [IMX8MQ_CLK_GPU_CORE_DIV] = &gpu_core, + [IMX8MQ_CLK_GPU_SHADER_SRC] = &gpu_shader, + [IMX8MQ_CLK_GPU_SHADER_CG] = &gpu_shader, + [IMX8MQ_CLK_GPU_SHADER_DIV] = &gpu_shader, + [IMX8MQ_CLK_A53_CORE] = &arm_a53_core, + [IMX8MQ_CLK_MAIN_AXI] = &main_axi, + [IMX8MQ_CLK_ENET_AXI] = &enet_axi, + [IMX8MQ_CLK_NAND_USDHC_BUS] = &nand_usdhc_bus, + [IMX8MQ_CLK_VPU_BUS] = &vpu_bus, + [IMX8MQ_CLK_DISP_AXI] = &disp_axi, + [IMX8MQ_CLK_DISP_APB] = &disp_apb, + [IMX8MQ_CLK_DISP_RTRM] = &disp_rtrm, + [IMX8MQ_CLK_USB_BUS] = &usb_bus, + [IMX8MQ_CLK_GPU_AXI] = &gpu_axi, + [IMX8MQ_CLK_GPU_AHB] = &gpu_ahb, + [IMX8MQ_CLK_NOC] = &noc, + [IMX8MQ_CLK_NOC_APB] = &noc_apb, + [IMX8MQ_CLK_AHB] = &ahb, + [IMX8MQ_CLK_AUDIO_AHB] = &audio_ahb, + [IMX8MQ_CLK_IPG_ROOT] = &ipg_root, + [IMX8MQ_CLK_IPG_AUDIO_ROOT] = &ipg_audio_root, + [IMX8MQ_CLK_DRAM_CORE] = &dram_core_clk, + [IMX8MQ_CLK_DRAM_ALT] = &dram_alt, + [IMX8MQ_CLK_DRAM_APB] = &dram_apb, + [IMX8MQ_CLK_VPU_G1] = &vpu_g1, + [IMX8MQ_CLK_VPU_G2] = &vpu_g2, + [IMX8MQ_CLK_DISP_DTRC] = &disp_dtrc, + [IMX8MQ_CLK_DISP_DC8000] = &disp_dc8000, + [IMX8MQ_CLK_PCIE1_CTRL] = &pcie1_ctrl, + [IMX8MQ_CLK_PCIE1_PHY] = &pcie1_phy, + [IMX8MQ_CLK_PCIE1_AUX] = &pcie1_aux, + [IMX8MQ_CLK_DC_PIXEL] = &dc_pixel, + [IMX8MQ_CLK_LCDIF_PIXEL] = &lcdif_pixel, + [IMX8MQ_CLK_SAI1] = &sai1, + [IMX8MQ_CLK_SAI2] = &sai2, + [IMX8MQ_CLK_SAI3] = &sai3, + [IMX8MQ_CLK_SAI4] = &sai4, + [IMX8MQ_CLK_SAI5] = &sai5, + [IMX8MQ_CLK_SAI6] = &sai6, + [IMX8MQ_CLK_SPDIF1] = &spdif1, + [IMX8MQ_CLK_SPDIF2] = &spdif2, + [IMX8MQ_CLK_ENET_REF] = &enet_ref, + [IMX8MQ_CLK_ENET_TIMER] = &enet_timer, + [IMX8MQ_CLK_ENET_PHY_REF] = &enet_phy, + [IMX8MQ_CLK_NAND] = &nand, + [IMX8MQ_CLK_QSPI] = &qspi, + [IMX8MQ_CLK_USDHC1] = &usdhc1, + [IMX8MQ_CLK_USDHC2] = &usdhc2, + [IMX8MQ_CLK_I2C1] = &i2c1, + [IMX8MQ_CLK_I2C2] = &i2c2, + [IMX8MQ_CLK_I2C3] = &i2c3, + [IMX8MQ_CLK_I2C4] = &i2c4, + [IMX8MQ_CLK_UART1] = &uart1, + [IMX8MQ_CLK_UART2] = &uart2, + [IMX8MQ_CLK_UART3] = &uart3, + [IMX8MQ_CLK_UART4] = &uart4, + [IMX8MQ_CLK_USB_CORE_REF] = &usb_core_ref, + [IMX8MQ_CLK_USB_PHY_REF] = &usb_phy_ref, + [IMX8MQ_CLK_GIC] = &gic, + [IMX8MQ_CLK_ECSPI1] = &ecspi1, + [IMX8MQ_CLK_ECSPI2] = &ecspi2, + [IMX8MQ_CLK_PWM1] = &pwm1, + [IMX8MQ_CLK_PWM2] = &pwm2, + [IMX8MQ_CLK_PWM3] = &pwm3, + [IMX8MQ_CLK_PWM4] = &pwm4, + [IMX8MQ_CLK_GPT1] = &gpt1, + [IMX8MQ_CLK_WDOG] = &wdog, + [IMX8MQ_CLK_WRCLK] = &wrclk, + [IMX8MQ_CLK_CLKO1] = &clko1, + [IMX8MQ_CLK_CLKO2] = &clko2, + [IMX8MQ_CLK_DSI_CORE] = &dsi_core, + [IMX8MQ_CLK_DSI_PHY_REF] = &dsi_phy_ref, + [IMX8MQ_CLK_DSI_DBI] = &dsi_dbi, + [IMX8MQ_CLK_DSI_ESC] = &dsi_esc, + [IMX8MQ_CLK_DSI_AHB] = &dsi_ahb, + [IMX8MQ_CLK_DSI_IPG_DIV] = &dsi_ipg_div, + [IMX8MQ_CLK_CSI1_CORE] = &csi1_core, + [IMX8MQ_CLK_CSI1_PHY_REF] = &csi1_phy_ref, + [IMX8MQ_CLK_CSI1_ESC] = &csi1_esc, + [IMX8MQ_CLK_CSI2_CORE] = &csi2_core, + [IMX8MQ_CLK_CSI2_PHY_REF] = &csi2_phy_ref, + [IMX8MQ_CLK_CSI2_ESC] = &csi2_esc, + [IMX8MQ_CLK_PCIE2_CTRL] = &pcie2_ctrl, + [IMX8MQ_CLK_PCIE2_PHY] = &pcie2_phy, + [IMX8MQ_CLK_PCIE2_AUX] = &pcie2_aux, + [IMX8MQ_CLK_ECSPI3] = &ecspi3, + [IMX8MQ_CLK_ECSPI1_ROOT] = &ecspi1_root_clk, + [IMX8MQ_CLK_ECSPI2_ROOT] = &ecspi2_root_clk, + [IMX8MQ_CLK_ECSPI3_ROOT] = &ecspi3_root_clk, + [IMX8MQ_CLK_ENET1_ROOT] = &enet1_root_clk, + [IMX8MQ_CLK_GPIO1_ROOT] = &gpio1_root_clk, + [IMX8MQ_CLK_GPIO2_ROOT] = &gpio2_root_clk, + [IMX8MQ_CLK_GPIO3_ROOT] = &gpio3_root_clk, + [IMX8MQ_CLK_GPIO4_ROOT] = &gpio4_root_clk, + [IMX8MQ_CLK_GPIO5_ROOT] = &gpio5_root_clk, + [IMX8MQ_CLK_GPT1_ROOT] = &gpt1_root_clk, + [IMX8MQ_CLK_I2C1_ROOT] = &i2c1_root_clk, + [IMX8MQ_CLK_I2C2_ROOT] = &i2c2_root_clk, + [IMX8MQ_CLK_I2C3_ROOT] = &i2c3_root_clk, + [IMX8MQ_CLK_I2C4_ROOT] = &i2c4_root_clk, + [IMX8MQ_CLK_MU_ROOT] = &mu_root_clk, + [IMX8MQ_CLK_OCOTP_ROOT] = &ocotp_root_clk, + [IMX8MQ_CLK_PCIE1_ROOT] = &pcie1_root_clk, + [IMX8MQ_CLK_PCIE2_ROOT] = &pcie2_root_clk, + [IMX8MQ_CLK_PWM1_ROOT] = &pwm1_root_clk, + [IMX8MQ_CLK_PWM2_ROOT] = &pwm2_root_clk, + [IMX8MQ_CLK_PWM3_ROOT] = &pwm3_root_clk, + [IMX8MQ_CLK_PWM4_ROOT] = &pwm4_root_clk, + [IMX8MQ_CLK_QSPI_ROOT] = &qspi_root_clk, + [IMX8MQ_CLK_RAWNAND_ROOT] = &nand_root_clk, + [IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = &nand_usdhc_rawnand_clk, + [IMX8MQ_CLK_SAI1_ROOT] = &sai1_root_clk, + [IMX8MQ_CLK_SAI1_IPG] = &sai1_ipg_clk, + [IMX8MQ_CLK_SAI2_ROOT] = &sai2_root_clk, + [IMX8MQ_CLK_SAI2_IPG] = &sai2_ipg_clk, + [IMX8MQ_CLK_SAI3_ROOT] = &sai3_root_clk, + [IMX8MQ_CLK_SAI3_IPG] = &sai3_ipg_clk, + [IMX8MQ_CLK_SAI4_ROOT] = &sai4_root_clk, + [IMX8MQ_CLK_SAI4_IPG] = &sai4_ipg_clk, + [IMX8MQ_CLK_SAI5_ROOT] = &sai5_root_clk, + [IMX8MQ_CLK_SAI5_IPG] = &sai5_ipg_clk, + [IMX8MQ_CLK_SAI6_ROOT] = &sai6_root_clk, + [IMX8MQ_CLK_SAI6_IPG] = &sai6_ipg_clk, + [IMX8MQ_CLK_UART1_ROOT] = &uart1_root_clk, + [IMX8MQ_CLK_UART2_ROOT] = &uart2_root_clk, + [IMX8MQ_CLK_UART3_ROOT] = &uart3_root_clk, + [IMX8MQ_CLK_UART4_ROOT] = &uart4_root_clk, + [IMX8MQ_CLK_USB1_CTRL_ROOT] = &usb1_ctrl_root_clk, + [IMX8MQ_CLK_USB2_CTRL_ROOT] = &usb2_ctrl_root_clk, + [IMX8MQ_CLK_USB1_PHY_ROOT] = &usb1_phy_root_clk, + [IMX8MQ_CLK_USB2_PHY_ROOT] = &usb2_phy_root_clk, + [IMX8MQ_CLK_USDHC1_ROOT] = &usdhc1_root_clk, + [IMX8MQ_CLK_USDHC2_ROOT] = &usdhc2_root_clk, + [IMX8MQ_CLK_WDOG1_ROOT] = &wdog1_root_clk, + [IMX8MQ_CLK_WDOG2_ROOT] = &wdog2_root_clk, + [IMX8MQ_CLK_WDOG3_ROOT] = &wdog3_root_clk, + [IMX8MQ_CLK_VPU_G1_ROOT] = &vpu_g1_root_clk, + [IMX8MQ_CLK_GPU_ROOT] = &gpu_root_clk, + [IMX8MQ_CLK_VPU_G2_ROOT] = &vpu_g2_root_clk, + [IMX8MQ_CLK_DISP_ROOT] = &disp_root_clk, + [IMX8MQ_CLK_DISP_AXI_ROOT] = &disp_axi_root_clk, + [IMX8MQ_CLK_DISP_APB_ROOT] = &disp_apb_root_clk, + [IMX8MQ_CLK_DISP_RTRM_ROOT] = &disp_rtrm_root_clk, + [IMX8MQ_CLK_TMU_ROOT] = &tmu_root_clk, + [IMX8MQ_CLK_VPU_DEC_ROOT] = &vpu_dec_root_clk, + [IMX8MQ_CLK_CSI1_ROOT] = &csi1_root_clk, + [IMX8MQ_CLK_CSI2_ROOT] = &csi2_root_clk, + [IMX8MQ_CLK_SDMA1_ROOT] = &sdma1_clk, + [IMX8MQ_CLK_SDMA2_ROOT] = &sdma2_clk, + [IMX8MQ_GPT_3M_CLK] = &gpt_3m, + [IMX8MQ_CLK_DRAM_ALT_ROOT] = &dram_alt_root, +}; + +struct clk **get_clk_list(void) +{ + sddf_dprintf("get clk list\n"); + + return imx8mq_clks; +} diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c new file mode 100644 index 000000000..c16f3e876 --- /dev/null +++ b/drivers/clk/imx/clk.c @@ -0,0 +1,222 @@ +/* + * Copyright 2024, UNSW + * + * SPDX-License-Identifier: BSD-2-Clause + * + * Terry Bai: tianyi.bai@unsw.edu.au + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +// Logging +/* #define DEBUG_DRIVER */ + +#ifdef DEBUG_DRIVER +#define LOG_DRIVER(...) do{ sddf_dprintf("CLK DRIVER|INFO: "); sddf_dprintf(__VA_ARGS__); }while(0) +#else +#define LOG_DRIVER(...) do{}while(0) +#endif + +#define LOG_DRIVER_ERR(...) do{ sddf_printf("CLK DRIVER|ERROR: "); sddf_printf(__VA_ARGS__); }while(0) + +#define CLIENT_CH 0 + +#define NUM_CLK_LIST IMX8MQ_CLK_END + +struct clk **clk_list; + +uintptr_t ccm_base; +uintptr_t ccm_analog_base; + +void clk_probe(struct clk *clk_list[]) +{ + int i; + for (i = 0; i < NUM_CLK_LIST; i++) { + if (!clk_list[i]) { + continue; + } + if (clk_list[i]->base == CCM_BASE) { + clk_list[i]->base = ccm_base; + } else if (clk_list[i]->base == CCM_ANALOG_BASE) { + clk_list[i]->base = ccm_analog_base; + } + if (clk_list[i] && clk_list[i]->hw.init->ops->init) { + clk_list[i]->hw.init->ops->init(clk_list[i]); + LOG_DRIVER("Initialise %s\n", clk_list[i]->hw.init->name); + } + } +} + +const struct clk *get_parent(const struct clk *clk) +{ + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; + uint32_t num_parents = init->num_parents; + + if (init->parent_data) { + uint8_t parent_idx = num_parents > 1 ? init->ops->get_parent(clk) : 0; + struct clk_parent_data parent_data = init->parent_data[parent_idx]; + + if (parent_data.clk) { + return parent_data.clk; + } else if (sddf_strcmp(parent_data.name, "xtal") == 0) { + return NULL; + } + } + + if (num_parents > 0) { + return init->parent_clks[0]; + } + + return NULL; +} + +/* TODO: Should be just read from the structure, but need to update everytime when */ +/* related clocks are modified */ +unsigned long clk_get_rate(const struct clk *clk) +{ + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; + unsigned long parent_rate = 0; + + const struct clk *parent_clk = get_parent(clk); + if (parent_clk) { + parent_rate = clk_get_rate(parent_clk); + } + + unsigned long rate = parent_rate; + if (init->ops->recalc_rate) { + rate = init->ops->recalc_rate(clk, parent_rate); + } + + return rate; +} + +uint32_t clk_enable(struct clk *clk) +{ + if (clk->hw.init->ops->enable != NULL) { + return clk->hw.init->ops->enable(clk); + } + + return CLK_INVALID_OP; +} + +uint32_t clk_disable(struct clk *clk) +{ + if (clk->hw.init->ops->disable != NULL) { + return clk->hw.init->ops->disable(clk); + } + + return CLK_INVALID_OP; +} + +uint32_t clk_set_rate(struct clk *clk, uint32_t rate) +{ + if (clk->hw.init->ops->init) { + clk->hw.init->ops->init(clk); + } + + const struct clk *pclk = get_parent(clk); + uint64_t prate = clk_get_rate(pclk); + if (clk->hw.init->ops->set_rate) { + /* TODO: determine_rate() needs to be implemented */ + LOG_DRIVER("set %s to %dHz\n", clk->hw.init->name, rate); + clk->hw.init->ops->set_rate(clk, rate, prate); + } else { + /* TODO: We only propagate one level right now */ + if (pclk->hw.init->ops->set_rate) { + const struct clk *ppclk = get_parent(pclk); + uint64_t pprate = clk_get_rate(ppclk); + /* TODO: determine_rate() needs to be implemented */ + LOG_DRIVER("set %s to %dHz\n", pclk->hw.init->name, rate); + pclk->hw.init->ops->set_rate(pclk, prate, pprate); + } + } + + return 0; +} + +void notified(microkit_channel ch) +{ + +} + +void init(void) +{ + + clk_list = get_clk_list(); + + clk_probe(clk_list); + + for (int i = 0; i < NUM_DEVICE_CLKS; i++) { + uint32_t idx = clk_configs[i].clk_id; + uint32_t rate = clk_configs[i].frequency; + + sddf_dprintf("idx: %u, frequency: 0x%x\n", idx, rate); + } +} + +microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) +{ + uint32_t ret = 0; + uint32_t argc = microkit_msginfo_get_count(msginfo); + + /* TODO: Check if the channel is valid */ + switch (microkit_msginfo_get_label(msginfo)) { + + case SDDF_CLK_ENABLE: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + LOG_DRIVER("get request clk_enable(%d)\n", clk_id); + ret = clk_enable(clk_list[clk_id]); + break; + } + case SDDF_CLK_DISABLE: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + LOG_DRIVER("get request clk_disable(%d)\n", clk_id); + ret = clk_disable(clk_list[clk_id]); + break; + } + case SDDF_CLK_GET_RATE: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + ret = clk_get_rate(clk_list[clk_id]); + break; + } + case SDDF_CLK_SET_RATE: { + if (argc != 2) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + uint32_t rate = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_RATE); + ret = clk_set_rate(clk_list[clk_id], rate); + break; + } + default: + LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), ch); + ret = 5; + } + return microkit_msginfo_new(ret, 0); +} diff --git a/drivers/clk/imx/clk_driver.mk b/drivers/clk/imx/clk_driver.mk new file mode 100644 index 000000000..bfb9012fd --- /dev/null +++ b/drivers/clk/imx/clk_driver.mk @@ -0,0 +1,34 @@ +# +# Copyright 2024, UNSW +# +# SPDX-License-Identifier: BSD-2-Clause + +CLK_DRIVER_DIR := $(dir $(lastword $(MAKEFILE_LIST))) +CLK_DRIVER_COMMON_DIR := $(SDDF)/drivers/clk +CLK_CONFIG_HEADER := $(BUILD_DIR)/clk_config.h +CLK_DRIVER_CONF_INC := $(SDDF)/include/sddf/clk +CLK_DRIVER_INC := $(CLK_DRIVER_DIR)/include + +CLK_DRIVER_OBJS := clk.o clk-operations.o clk-imx8mq.o clk-imx.o + +clk_driver.elf: $(CLK_DRIVER_OBJS) libsddf_util_debug.a + $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ + + +$(CLK_DRIVER_OBJS): ${CLK_DRIVER_COMMON_DIR}/*.c ${CLK_DRIVER_DIR}/*.c $(CLK_CONFIG_HEADER) + $(CC) -c $(CFLAGS) \ + -I${CLK_DRIVER_INC} \ + -I${CLK_DRIVER_CONF_INC} \ + -I${CLK_DRIVER_COMMON_DIR} \ + -I${BUILD_DIR} \ + -I${UART_DRIVER_DIR}/include \ + -I${CLK_DRIVER_COMMON_DIR} $^ + +$(CLK_CONFIG_HEADER): $(DTS_FILE) + $(PYTHON) $(CLK_DRIVER_COMMON_DIR)/create_clk_config.py $(DTS_FILE) $(BUILD_DIR) + +clean:: + rm -f clk_driver.o + +clobber:: + rm -rf clk_driver.elf diff --git a/drivers/clk/imx/include/clk-imx.h b/drivers/clk/imx/include/clk-imx.h new file mode 100644 index 000000000..a99a81d62 --- /dev/null +++ b/drivers/clk/imx/include/clk-imx.h @@ -0,0 +1,342 @@ +#pragma once + +#include + +/* These two magic numbers are used to define static clock + * structures at compile time, and will be replaced with + * real base addresses in clk_probe(). + */ +#define CCM_BASE 0x1234 +#define CCM_ANALOG_BASE 0x5678 + +#define PCG_PREDIV_SHIFT 16 +#define PCG_PREDIV_WIDTH 3 +#define PCG_PREDIV_MAX 8 + +#define PCG_DIV_SHIFT 0 +#define PCG_CORE_DIV_WIDTH 3 +#define PCG_DIV_WIDTH 6 +#define PCG_DIV_MAX 64 + +#define PCG_PCS_SHIFT 24 +#define PCG_PCS_MASK 0x7 + +#define PCG_CGC_SHIFT 28 + +struct clk_gate2 { + uint8_t bit_idx; + uint8_t cgr_val; + uint8_t cgr_mask; + uint8_t flags; + uint32_t *share_count; +}; + +struct clk_frac_pll_data { + uint32_t offset; +}; + +struct clk_sscg_pll_data { + /* struct clk_sscg_pll_setup setup; */ + uint32_t offset; + uint8_t parent; + uint8_t bypass1; + uint8_t bypass2; +}; + +/** + * Refer to section 5.1.5.4.1 Core clock slice in datasheet. + */ +struct clk_core_slice_data { + /* Common */ + uint32_t offset; + /* Mux */ + uint8_t mux_shift; + uint8_t mux_mask; + /* Gate */ + uint8_t gate_shift; + /* Divider */ + uint8_t div_shift; + uint8_t div_width; +}; + +/** + * Refer to section 5.1.5.4.2 Bus clock slice in datasheet. + */ +struct clk_bus_slice_data { + /* Common */ + uint32_t offset; + /* Mux */ + uint8_t mux_shift; + uint8_t mux_mask; + /* Gate */ + uint8_t gate_shift; + /* Prev Divider */ + uint8_t prevdiv_shift; + uint8_t prevdiv_width; + /* Post Divider */ + uint8_t postdiv_shift; + uint8_t postdiv_width; +}; + +/** + * Refer to section 5.1.5.4.3 Peripheral clock slice in datasheet. + */ +struct clk_common_slice_data { + /* Common */ + uint32_t offset; + /* Mux */ + uint8_t mux_shift; + uint8_t mux_mask; + /* Gate */ + uint8_t gate_shift; + /* Prev Divider */ + uint8_t prevdiv_shift; + uint8_t prevdiv_width; + /* Post Divider */ + uint8_t postdiv_shift; + uint8_t postdiv_width; +}; + +extern const struct clk_ops clk_gate2_ops; +extern const struct clk_ops clk_frac_pll_ops; +extern const struct clk_ops clk_sscg_pll_ops; +extern const struct clk_ops clk_core_slice_ops; +extern const struct clk_ops clk_bus_slice_ops; +extern const struct clk_ops clk_common_slice_ops; + +struct clk **get_clk_list(void); + +#define IMX_CLK_SOURCE(_name, _rate) \ +struct clk _name = { \ + .data = &(struct clk_source_data){ \ + .rate = (_rate), \ + }, \ + .hw.init = &(struct clk_init_data){ \ + .name = #_name, \ + .ops = &clk_source_ops, \ + } \ +} + +/* need to see difference between fixed clk and source clk */ +#define IMX_CLK_FIXED(_name, _rate) \ +IMX_CLK_SOURCE(_name, _rate) + +#define IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ + _parent_data, _num_parents, _init_flags) \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_mux_data) { \ + .offset = (_offset), \ + .mask = MASK(_width), \ + .shift = (_shift), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_mux_ops, \ + .parent_data = (_parent_data), \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ +} + +#define IMX_CLK_MUX(_name, _base, _offset, _shift, _width, \ + _parent_data, _num_parents) \ +IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ + _parent_data, _num_parents, 0) + +#define IMX_CLK_MUX2(_name, _base, _offset, _shift, _width, \ + _parent_data, _num_parents) \ +IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ + _parent_data, _num_parents, CLK_OPS_PARENT_ENABLE) + +#define IMX_CLK_MUX2_FLAGS(_name, _base, _offset, _shift, _width, \ + _parent_data, _num_parents, _flags) \ +IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ + _parent_data, _num_parents, _flags | CLK_OPS_PARENT_ENABLE) + +#define IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, \ + _shift, _width, _flags) \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_div_data) { \ + .offset = (_offset), \ + .shift = (_shift), \ + .width = (_width), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_divider_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = 1, \ + .flags = 0, \ + }, \ +} + +#define IMX_CLK_DIV(_name, _parent_clks, _base, _offset, \ + _shift, _width) \ +IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, _width, 0) + +#define IMX_CLK_DIV2(_name, _parent_clks, _base, _offset, \ + _shift, _width) \ +IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, \ + _width, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE) + + +#define IMX_CLK_FRAC_PLL(_name, _parent_clks, _base, _offset) \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_frac_pll_data) { \ + .offset = (_offset), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_frac_pll_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = 1, \ + }, \ +} + +#define IMX_CLK_GATE1(_name, _parent_clks, _base, _offset, _shift) \ +CLK_GATE(_name, _offset, _shift, 0, _parent_clks, 1, 0) + +#define IMX_CLK_GATE(_name, _parent_clks, _base, _offset, _shift) \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_gate_data) { \ + .offset = (_offset), \ + .bit_idx = (_shift), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_gate_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = 1, \ + }, \ +} + +#define IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, _flags) \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_gate_data) { \ + .offset = (_offset), \ + .bit_idx = (_shift), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_gate2_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = 1, \ + }, \ +} + +#define IMX_CLK_GATE2_SHARED2(_name, _parent_clks, _base, _offset, _shift, _shared_count) \ +IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, 0) + +#define IMX_CLK_GATE4(_name, _parent_clks, _base, _offset, _shift) \ +IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, 0) + +#define IMX_CLK_FIXED_FACTOR(_name, _parent_clks, _mult, _div) \ +CLK_FIXED_FACTOR(_name, _mult, _div, 0, _parent_clks, 1, CLK_SET_RATE_PARENT) + +#define IMX_CLK_SSCG_PLL(_name, _parent_data, _num_parents, _parent, \ + _bypass1, _bypass2, _base, _offset, _flags) \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_sscg_pll_data) { \ + .offset = (_offset), \ + .parent = (_parent), \ + .bypass1 = (_bypass1), \ + .bypass2 = (_bypass2), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_sscg_pll_ops, \ + .parent_data = (_parent_data), \ + .num_parents = 1, \ + .flags = _flags, \ + }, \ +} + +#define IMX_CLK_COMPOSITE_CORE(_name, _parent_data, _base, _offset) \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_core_slice_data) { \ + .offset = (_offset), \ + .mux_shift = PCG_PCS_SHIFT, \ + .mux_mask = PCG_PCS_MASK, \ + .div_shift = PCG_DIV_SHIFT, \ + .div_width = PCG_CORE_DIV_WIDTH, \ + .gate_shift = PCG_CGC_SHIFT, \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_core_slice_ops, \ + .parent_data = (_parent_data), \ + .num_parents = ARRAY_SIZE(_parent_data), \ + .flags = (CLK_DIVIDER_ROUND_CLOSEST | \ + CLK_SET_RATE_NO_REPARENT | \ + CLK_OPS_PARENT_ENABLE) \ + }, \ +} + +#define IMX_CLK_COMPOSITE_BUS(_name, _parent_data, _base, _offset) \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_bus_slice_data) { \ + .offset = (_offset), \ + .mux_shift = PCG_PCS_SHIFT, \ + .mux_mask = PCG_PCS_MASK, \ + .prevdiv_shift = PCG_PREDIV_SHIFT, \ + .prevdiv_width = PCG_PREDIV_WIDTH, \ + .postdiv_shift = PCG_DIV_SHIFT, \ + .postdiv_width = PCG_DIV_WIDTH, \ + .gate_shift = PCG_CGC_SHIFT, \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_bus_slice_ops, \ + .parent_data = (_parent_data), \ + .num_parents = ARRAY_SIZE(_parent_data), \ + .flags = (CLK_DIVIDER_ROUND_CLOSEST | \ + CLK_SET_RATE_NO_REPARENT | \ + CLK_OPS_PARENT_ENABLE) \ + }, \ +} + +#define IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset,\ + _flags) \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_common_slice_data) { \ + .offset = (_offset), \ + .mux_shift = PCG_PCS_SHIFT, \ + .mux_mask = PCG_PCS_MASK, \ + .prevdiv_shift = PCG_PREDIV_SHIFT, \ + .prevdiv_width = PCG_PREDIV_WIDTH, \ + .postdiv_shift = PCG_DIV_SHIFT, \ + .postdiv_width = PCG_DIV_WIDTH, \ + .gate_shift = PCG_CGC_SHIFT, \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_common_slice_ops, \ + .parent_data = (_parent_data), \ + .num_parents = ARRAY_SIZE(_parent_data), \ + .flags = CLK_DIVIDER_ROUND_CLOSEST | \ + CLK_SET_RATE_NO_REPARENT | \ + CLK_OPS_PARENT_ENABLE | \ + (_flags), \ + }, \ +} + +#define IMX_CLK_COMPOSITE(_name, _parent_data, _base, _offset) \ +IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, \ + CLK_OPS_PARENT_ENABLE) + +#define IMX_CLK_COMPOSITE_FW_MANAGED(_name, _parent_data, _base, _offset) \ +IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, \ + (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE)) + +#define IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(_name, _parent_data, _base, _offset) \ +IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, \ + (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL)) diff --git a/drivers/clk/imx/include/imx8mq-bindings.h b/drivers/clk/imx/include/imx8mq-bindings.h new file mode 100644 index 000000000..2f74b3c6a --- /dev/null +++ b/drivers/clk/imx/include/imx8mq-bindings.h @@ -0,0 +1,430 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * + * Source: https://github.com/torvalds/linux/blob/master/include/dt-bindings/clock/imx8mq-clock.h + */ + +#pragma once + +#define IMX8MQ_CLK_DUMMY 0 +#define IMX8MQ_CLK_32K 1 +#define IMX8MQ_CLK_25M 2 +#define IMX8MQ_CLK_27M 3 +#define IMX8MQ_CLK_EXT1 4 +#define IMX8MQ_CLK_EXT2 5 +#define IMX8MQ_CLK_EXT3 6 +#define IMX8MQ_CLK_EXT4 7 + +/* ANAMIX PLL clocks */ +/* FRAC PLLs */ +/* ARM PLL */ +#define IMX8MQ_ARM_PLL_REF_SEL 8 +#define IMX8MQ_ARM_PLL_REF_DIV 9 +#define IMX8MQ_ARM_PLL 10 +#define IMX8MQ_ARM_PLL_BYPASS 11 +#define IMX8MQ_ARM_PLL_OUT 12 + +/* GPU PLL */ +#define IMX8MQ_GPU_PLL_REF_SEL 13 +#define IMX8MQ_GPU_PLL_REF_DIV 14 +#define IMX8MQ_GPU_PLL 15 +#define IMX8MQ_GPU_PLL_BYPASS 16 +#define IMX8MQ_GPU_PLL_OUT 17 + +/* VPU PLL */ +#define IMX8MQ_VPU_PLL_REF_SEL 18 +#define IMX8MQ_VPU_PLL_REF_DIV 19 +#define IMX8MQ_VPU_PLL 20 +#define IMX8MQ_VPU_PLL_BYPASS 21 +#define IMX8MQ_VPU_PLL_OUT 22 + +/* AUDIO PLL1 */ +#define IMX8MQ_AUDIO_PLL1_REF_SEL 23 +#define IMX8MQ_AUDIO_PLL1_REF_DIV 24 +#define IMX8MQ_AUDIO_PLL1 25 +#define IMX8MQ_AUDIO_PLL1_BYPASS 26 +#define IMX8MQ_AUDIO_PLL1_OUT 27 + +/* AUDIO PLL2 */ +#define IMX8MQ_AUDIO_PLL2_REF_SEL 28 +#define IMX8MQ_AUDIO_PLL2_REF_DIV 29 +#define IMX8MQ_AUDIO_PLL2 30 +#define IMX8MQ_AUDIO_PLL2_BYPASS 31 +#define IMX8MQ_AUDIO_PLL2_OUT 32 + +/* VIDEO PLL1 */ +#define IMX8MQ_VIDEO_PLL1_REF_SEL 33 +#define IMX8MQ_VIDEO_PLL1_REF_DIV 34 +#define IMX8MQ_VIDEO_PLL1 35 +#define IMX8MQ_VIDEO_PLL1_BYPASS 36 +#define IMX8MQ_VIDEO_PLL1_OUT 37 + +/* SYS1 PLL */ +#define IMX8MQ_SYS1_PLL1_REF_SEL 38 +#define IMX8MQ_SYS1_PLL1_REF_DIV 39 +#define IMX8MQ_SYS1_PLL1 40 +#define IMX8MQ_SYS1_PLL1_OUT 41 +#define IMX8MQ_SYS1_PLL1_OUT_DIV 42 +#define IMX8MQ_SYS1_PLL2 43 +#define IMX8MQ_SYS1_PLL2_DIV 44 +#define IMX8MQ_SYS1_PLL2_OUT 45 + +/* SYS2 PLL */ +#define IMX8MQ_SYS2_PLL1_REF_SEL 46 +#define IMX8MQ_SYS2_PLL1_REF_DIV 47 +#define IMX8MQ_SYS2_PLL1 48 +#define IMX8MQ_SYS2_PLL1_OUT 49 +#define IMX8MQ_SYS2_PLL1_OUT_DIV 50 +#define IMX8MQ_SYS2_PLL2 51 +#define IMX8MQ_SYS2_PLL2_DIV 52 +#define IMX8MQ_SYS2_PLL2_OUT 53 + +/* SYS3 PLL */ +#define IMX8MQ_SYS3_PLL1_REF_SEL 54 +#define IMX8MQ_SYS3_PLL1_REF_DIV 55 +#define IMX8MQ_SYS3_PLL1 56 +#define IMX8MQ_SYS3_PLL1_OUT 57 +#define IMX8MQ_SYS3_PLL1_OUT_DIV 58 +#define IMX8MQ_SYS3_PLL2 59 +#define IMX8MQ_SYS3_PLL2_DIV 60 +#define IMX8MQ_SYS3_PLL2_OUT 61 + +/* DRAM PLL */ +#define IMX8MQ_DRAM_PLL1_REF_SEL 62 +#define IMX8MQ_DRAM_PLL1_REF_DIV 63 +#define IMX8MQ_DRAM_PLL1 64 +#define IMX8MQ_DRAM_PLL1_OUT 65 +#define IMX8MQ_DRAM_PLL1_OUT_DIV 66 +#define IMX8MQ_DRAM_PLL2 67 +#define IMX8MQ_DRAM_PLL2_DIV 68 +#define IMX8MQ_DRAM_PLL2_OUT 69 + +/* SYS PLL DIV */ +#define IMX8MQ_SYS1_PLL_40M 70 +#define IMX8MQ_SYS1_PLL_80M 71 +#define IMX8MQ_SYS1_PLL_100M 72 +#define IMX8MQ_SYS1_PLL_133M 73 +#define IMX8MQ_SYS1_PLL_160M 74 +#define IMX8MQ_SYS1_PLL_200M 75 +#define IMX8MQ_SYS1_PLL_266M 76 +#define IMX8MQ_SYS1_PLL_400M 77 +#define IMX8MQ_SYS1_PLL_800M 78 + +#define IMX8MQ_SYS2_PLL_50M 79 +#define IMX8MQ_SYS2_PLL_100M 80 +#define IMX8MQ_SYS2_PLL_125M 81 +#define IMX8MQ_SYS2_PLL_166M 82 +#define IMX8MQ_SYS2_PLL_200M 83 +#define IMX8MQ_SYS2_PLL_250M 84 +#define IMX8MQ_SYS2_PLL_333M 85 +#define IMX8MQ_SYS2_PLL_500M 86 +#define IMX8MQ_SYS2_PLL_1000M 87 + +/* CCM ROOT clocks */ +/* A53 */ +#define IMX8MQ_CLK_A53_SRC 88 +#define IMX8MQ_CLK_A53_CG 89 +#define IMX8MQ_CLK_A53_DIV 90 +/* M4 */ +#define IMX8MQ_CLK_M4_SRC 91 +#define IMX8MQ_CLK_M4_CG 92 +#define IMX8MQ_CLK_M4_DIV 93 +/* VPU */ +#define IMX8MQ_CLK_VPU_SRC 94 +#define IMX8MQ_CLK_VPU_CG 95 +#define IMX8MQ_CLK_VPU_DIV 96 +/* GPU CORE */ +#define IMX8MQ_CLK_GPU_CORE_SRC 97 +#define IMX8MQ_CLK_GPU_CORE_CG 98 +#define IMX8MQ_CLK_GPU_CORE_DIV 99 +/* GPU SHADER */ +#define IMX8MQ_CLK_GPU_SHADER_SRC 100 +#define IMX8MQ_CLK_GPU_SHADER_CG 101 +#define IMX8MQ_CLK_GPU_SHADER_DIV 102 + +/* BUS TYPE */ +/* MAIN AXI */ +#define IMX8MQ_CLK_MAIN_AXI 103 +/* ENET AXI */ +#define IMX8MQ_CLK_ENET_AXI 104 +/* NAND_USDHC_BUS */ +#define IMX8MQ_CLK_NAND_USDHC_BUS 105 +/* VPU BUS */ +#define IMX8MQ_CLK_VPU_BUS 106 +/* DISP_AXI */ +#define IMX8MQ_CLK_DISP_AXI 107 +/* DISP APB */ +#define IMX8MQ_CLK_DISP_APB 108 +/* DISP RTRM */ +#define IMX8MQ_CLK_DISP_RTRM 109 +/* USB_BUS */ +#define IMX8MQ_CLK_USB_BUS 110 +/* GPU_AXI */ +#define IMX8MQ_CLK_GPU_AXI 111 +/* GPU_AHB */ +#define IMX8MQ_CLK_GPU_AHB 112 +/* NOC */ +#define IMX8MQ_CLK_NOC 113 +/* NOC_APB */ +#define IMX8MQ_CLK_NOC_APB 115 + +/* AHB */ +#define IMX8MQ_CLK_AHB 116 +/* AUDIO AHB */ +#define IMX8MQ_CLK_AUDIO_AHB 117 + +/* DRAM_ALT */ +#define IMX8MQ_CLK_DRAM_ALT 118 +/* DRAM APB */ +#define IMX8MQ_CLK_DRAM_APB 119 +/* VPU_G1 */ +#define IMX8MQ_CLK_VPU_G1 120 +/* VPU_G2 */ +#define IMX8MQ_CLK_VPU_G2 121 +/* DISP_DTRC */ +#define IMX8MQ_CLK_DISP_DTRC 122 +/* DISP_DC8000 */ +#define IMX8MQ_CLK_DISP_DC8000 123 +/* PCIE_CTRL */ +#define IMX8MQ_CLK_PCIE1_CTRL 124 +/* PCIE_PHY */ +#define IMX8MQ_CLK_PCIE1_PHY 125 +/* PCIE_AUX */ +#define IMX8MQ_CLK_PCIE1_AUX 126 +/* DC_PIXEL */ +#define IMX8MQ_CLK_DC_PIXEL 127 +/* LCDIF_PIXEL */ +#define IMX8MQ_CLK_LCDIF_PIXEL 128 +/* SAI1~6 */ +#define IMX8MQ_CLK_SAI1 129 + +#define IMX8MQ_CLK_SAI2 130 + +#define IMX8MQ_CLK_SAI3 131 + +#define IMX8MQ_CLK_SAI4 132 + +#define IMX8MQ_CLK_SAI5 133 + +#define IMX8MQ_CLK_SAI6 134 +/* SPDIF1 */ +#define IMX8MQ_CLK_SPDIF1 135 +/* SPDIF2 */ +#define IMX8MQ_CLK_SPDIF2 136 +/* ENET_REF */ +#define IMX8MQ_CLK_ENET_REF 137 +/* ENET_TIMER */ +#define IMX8MQ_CLK_ENET_TIMER 138 +/* ENET_PHY */ +#define IMX8MQ_CLK_ENET_PHY_REF 139 +/* NAND */ +#define IMX8MQ_CLK_NAND 140 +/* QSPI */ +#define IMX8MQ_CLK_QSPI 141 +/* USDHC1 */ +#define IMX8MQ_CLK_USDHC1 142 +/* USDHC2 */ +#define IMX8MQ_CLK_USDHC2 143 +/* I2C1 */ +#define IMX8MQ_CLK_I2C1 144 +/* I2C2 */ +#define IMX8MQ_CLK_I2C2 145 +/* I2C3 */ +#define IMX8MQ_CLK_I2C3 146 +/* I2C4 */ +#define IMX8MQ_CLK_I2C4 147 +/* UART1 */ +#define IMX8MQ_CLK_UART1 148 +/* UART2 */ +#define IMX8MQ_CLK_UART2 149 +/* UART3 */ +#define IMX8MQ_CLK_UART3 150 +/* UART4 */ +#define IMX8MQ_CLK_UART4 151 +/* USB_CORE_REF */ +#define IMX8MQ_CLK_USB_CORE_REF 152 +/* USB_PHY_REF */ +#define IMX8MQ_CLK_USB_PHY_REF 153 +/* ECSPI1 */ +#define IMX8MQ_CLK_ECSPI1 154 +/* ECSPI2 */ +#define IMX8MQ_CLK_ECSPI2 155 +/* PWM1 */ +#define IMX8MQ_CLK_PWM1 156 +/* PWM2 */ +#define IMX8MQ_CLK_PWM2 157 +/* PWM3 */ +#define IMX8MQ_CLK_PWM3 158 +/* PWM4 */ +#define IMX8MQ_CLK_PWM4 159 +/* GPT1 */ +#define IMX8MQ_CLK_GPT1 160 +/* WDOG */ +#define IMX8MQ_CLK_WDOG 161 +/* WRCLK */ +#define IMX8MQ_CLK_WRCLK 162 +/* DSI_CORE */ +#define IMX8MQ_CLK_DSI_CORE 163 +/* DSI_PHY */ +#define IMX8MQ_CLK_DSI_PHY_REF 164 +/* DSI_DBI */ +#define IMX8MQ_CLK_DSI_DBI 165 +/*DSI_ESC */ +#define IMX8MQ_CLK_DSI_ESC 166 +/* CSI1_CORE */ +#define IMX8MQ_CLK_CSI1_CORE 167 +/* CSI1_PHY */ +#define IMX8MQ_CLK_CSI1_PHY_REF 168 +/* CSI_ESC */ +#define IMX8MQ_CLK_CSI1_ESC 169 +/* CSI2_CORE */ +#define IMX8MQ_CLK_CSI2_CORE 170 +/* CSI2_PHY */ +#define IMX8MQ_CLK_CSI2_PHY_REF 171 +/* CSI2_ESC */ +#define IMX8MQ_CLK_CSI2_ESC 172 +/* PCIE2_CTRL */ +#define IMX8MQ_CLK_PCIE2_CTRL 173 +/* PCIE2_PHY */ +#define IMX8MQ_CLK_PCIE2_PHY 174 +/* PCIE2_AUX */ +#define IMX8MQ_CLK_PCIE2_AUX 175 +/* ECSPI3 */ +#define IMX8MQ_CLK_ECSPI3 176 + +/* CCGR clocks */ +#define IMX8MQ_CLK_A53_ROOT 177 +#define IMX8MQ_CLK_DRAM_ROOT 178 +#define IMX8MQ_CLK_ECSPI1_ROOT 179 +#define IMX8MQ_CLK_ECSPI2_ROOT 180 +#define IMX8MQ_CLK_ECSPI3_ROOT 181 +#define IMX8MQ_CLK_ENET1_ROOT 182 +#define IMX8MQ_CLK_GPT1_ROOT 183 +#define IMX8MQ_CLK_I2C1_ROOT 184 +#define IMX8MQ_CLK_I2C2_ROOT 185 +#define IMX8MQ_CLK_I2C3_ROOT 186 +#define IMX8MQ_CLK_I2C4_ROOT 187 +#define IMX8MQ_CLK_M4_ROOT 188 +#define IMX8MQ_CLK_PCIE1_ROOT 189 +#define IMX8MQ_CLK_PCIE2_ROOT 190 +#define IMX8MQ_CLK_PWM1_ROOT 191 +#define IMX8MQ_CLK_PWM2_ROOT 192 +#define IMX8MQ_CLK_PWM3_ROOT 193 +#define IMX8MQ_CLK_PWM4_ROOT 194 +#define IMX8MQ_CLK_QSPI_ROOT 195 +#define IMX8MQ_CLK_SAI1_ROOT 196 +#define IMX8MQ_CLK_SAI2_ROOT 197 +#define IMX8MQ_CLK_SAI3_ROOT 198 +#define IMX8MQ_CLK_SAI4_ROOT 199 +#define IMX8MQ_CLK_SAI5_ROOT 200 +#define IMX8MQ_CLK_SAI6_ROOT 201 +#define IMX8MQ_CLK_UART1_ROOT 202 +#define IMX8MQ_CLK_UART2_ROOT 203 +#define IMX8MQ_CLK_UART3_ROOT 204 +#define IMX8MQ_CLK_UART4_ROOT 205 +#define IMX8MQ_CLK_USB1_CTRL_ROOT 206 +#define IMX8MQ_CLK_USB2_CTRL_ROOT 207 +#define IMX8MQ_CLK_USB1_PHY_ROOT 208 +#define IMX8MQ_CLK_USB2_PHY_ROOT 209 +#define IMX8MQ_CLK_USDHC1_ROOT 210 +#define IMX8MQ_CLK_USDHC2_ROOT 211 +#define IMX8MQ_CLK_WDOG1_ROOT 212 +#define IMX8MQ_CLK_WDOG2_ROOT 213 +#define IMX8MQ_CLK_WDOG3_ROOT 214 +#define IMX8MQ_CLK_GPU_ROOT 215 +#define IMX8MQ_CLK_HEVC_ROOT 216 +#define IMX8MQ_CLK_AVC_ROOT 217 +#define IMX8MQ_CLK_VP9_ROOT 218 +#define IMX8MQ_CLK_HEVC_INTER_ROOT 219 +#define IMX8MQ_CLK_DISP_ROOT 220 +#define IMX8MQ_CLK_HDMI_ROOT 221 +#define IMX8MQ_CLK_HDMI_PHY_ROOT 222 +#define IMX8MQ_CLK_VPU_DEC_ROOT 223 +#define IMX8MQ_CLK_CSI1_ROOT 224 +#define IMX8MQ_CLK_CSI2_ROOT 225 +#define IMX8MQ_CLK_RAWNAND_ROOT 226 +#define IMX8MQ_CLK_SDMA1_ROOT 227 +#define IMX8MQ_CLK_SDMA2_ROOT 228 +#define IMX8MQ_CLK_VPU_G1_ROOT 229 +#define IMX8MQ_CLK_VPU_G2_ROOT 230 + +/* SCCG PLL GATE */ +#define IMX8MQ_SYS1_PLL_OUT 231 +#define IMX8MQ_SYS2_PLL_OUT 232 +#define IMX8MQ_SYS3_PLL_OUT 233 +#define IMX8MQ_DRAM_PLL_OUT 234 + +#define IMX8MQ_GPT_3M_CLK 235 + +#define IMX8MQ_CLK_IPG_ROOT 236 +#define IMX8MQ_CLK_IPG_AUDIO_ROOT 237 +#define IMX8MQ_CLK_SAI1_IPG 238 +#define IMX8MQ_CLK_SAI2_IPG 239 +#define IMX8MQ_CLK_SAI3_IPG 240 +#define IMX8MQ_CLK_SAI4_IPG 241 +#define IMX8MQ_CLK_SAI5_IPG 242 +#define IMX8MQ_CLK_SAI6_IPG 243 + +/* DSI AHB/IPG clocks */ +/* rxesc clock */ +#define IMX8MQ_CLK_DSI_AHB 244 +/* txesc clock */ +#define IMX8MQ_CLK_DSI_IPG_DIV 245 + +#define IMX8MQ_CLK_TMU_ROOT 246 + +/* Display root clocks */ +#define IMX8MQ_CLK_DISP_AXI_ROOT 247 +#define IMX8MQ_CLK_DISP_APB_ROOT 248 +#define IMX8MQ_CLK_DISP_RTRM_ROOT 249 + +#define IMX8MQ_CLK_OCOTP_ROOT 250 + +#define IMX8MQ_CLK_DRAM_ALT_ROOT 251 +#define IMX8MQ_CLK_DRAM_CORE 252 + +#define IMX8MQ_CLK_MU_ROOT 253 +#define IMX8MQ_VIDEO2_PLL_OUT 254 + +#define IMX8MQ_CLK_CLKO2 255 + +#define IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK 256 + +#define IMX8MQ_CLK_CLKO1 257 +#define IMX8MQ_CLK_ARM 258 + +#define IMX8MQ_CLK_GPIO1_ROOT 259 +#define IMX8MQ_CLK_GPIO2_ROOT 260 +#define IMX8MQ_CLK_GPIO3_ROOT 261 +#define IMX8MQ_CLK_GPIO4_ROOT 262 +#define IMX8MQ_CLK_GPIO5_ROOT 263 + +#define IMX8MQ_CLK_SNVS_ROOT 264 +#define IMX8MQ_CLK_GIC 265 + +#define IMX8MQ_VIDEO2_PLL1_REF_SEL 266 + +#define IMX8MQ_CLK_GPU_CORE 285 +#define IMX8MQ_CLK_GPU_SHADER 286 +#define IMX8MQ_CLK_M4_CORE 287 +#define IMX8MQ_CLK_VPU_CORE 288 + +#define IMX8MQ_CLK_A53_CORE 289 + +#define IMX8MQ_CLK_MON_AUDIO_PLL1_DIV 290 +#define IMX8MQ_CLK_MON_AUDIO_PLL2_DIV 291 +#define IMX8MQ_CLK_MON_VIDEO_PLL1_DIV 292 +#define IMX8MQ_CLK_MON_GPU_PLL_DIV 293 +#define IMX8MQ_CLK_MON_VPU_PLL_DIV 294 +#define IMX8MQ_CLK_MON_ARM_PLL_DIV 295 +#define IMX8MQ_CLK_MON_SYS_PLL1_DIV 296 +#define IMX8MQ_CLK_MON_SYS_PLL2_DIV 297 +#define IMX8MQ_CLK_MON_SYS_PLL3_DIV 298 +#define IMX8MQ_CLK_MON_DRAM_PLL_DIV 299 +#define IMX8MQ_CLK_MON_VIDEO_PLL2_DIV 300 +#define IMX8MQ_CLK_MON_SEL 301 +#define IMX8MQ_CLK_MON_CLK2_OUT 302 + +#define IMX8MQ_CLK_END 303 diff --git a/drivers/clk/meson/clk.c b/drivers/clk/meson/clk.c index 414d8033d..925db7521 100644 --- a/drivers/clk/meson/clk.c +++ b/drivers/clk/meson/clk.c @@ -21,7 +21,7 @@ #include /* clock id bindings*/ // Logging -#define DEBUG_DRIVER +/* #define DEBUG_DRIVER */ #ifdef DEBUG_DRIVER #define LOG_DRIVER(...) do{ sddf_dprintf("CLK DRIVER|INFO: "); sddf_dprintf(__VA_ARGS__); }while(0) @@ -149,6 +149,7 @@ uint32_t clk_set_rate(struct clk *clk, uint32_t rate) int clk_msr_stat() { +#ifdef DEBUG_DRIVER unsigned long clk_freq; int i = 0; @@ -157,6 +158,7 @@ int clk_msr_stat() clk_freq = clk_msr(i); LOG_DRIVER("[%4d][%4ldHz] %s\n", i, clk_freq, clk_msr_list[i]); } +#endif return 0; } diff --git a/drivers/clk/meson/clk_driver.mk b/drivers/clk/meson/clk_driver.mk index bf730c526..6aff1dbb2 100644 --- a/drivers/clk/meson/clk_driver.mk +++ b/drivers/clk/meson/clk_driver.mk @@ -4,16 +4,16 @@ # SPDX-License-Identifier: BSD-2-Clause CLK_DRIVER_DIR := $(dir $(lastword $(MAKEFILE_LIST))) -CLK_DRIVER_OBJS := clk.o clk-operations.o clk-measure.o clk-meson.o sm1-clk.o - -clk_driver.elf: $(CLK_DRIVER_OBJS) libsddf_util_debug.a - $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ - CLK_CONFIG_HEADER := $(BUILD_DIR)/clk_config.h CLK_DRIVER_CONF_INC := $(SDDF)/include/sddf/clk CLK_DRIVER_INC := $(CLK_DRIVER_DIR)/include CLK_DRIVER_COMMON_DIR := $(SDDF)/drivers/clk +CLK_DRIVER_OBJS := clk.o clk-operations.o clk-measure.o clk-meson.o sm1-clk.o + +clk_driver.elf: $(CLK_DRIVER_OBJS) libsddf_util_debug.a + $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ + $(CLK_DRIVER_OBJS): ${CLK_DRIVER_COMMON_DIR}/*.c ${CLK_DRIVER_DIR}/*.c $(CLK_CONFIG_HEADER) $(CC) -c $(CFLAGS) \ -I${CLK_DRIVER_INC} \ @@ -22,8 +22,8 @@ $(CLK_DRIVER_OBJS): ${CLK_DRIVER_COMMON_DIR}/*.c ${CLK_DRIVER_DIR}/*.c $(CLK_CON -I${UART_DRIVER_DIR}/include \ -I${CLK_DRIVER_COMMON_DIR} $^ -$(CLK_CONFIG_HEADER): - $(PYTHON) $(CLK_DRIVER_DIR)/create_clk_config.py $(DTS_FILE) $(BUILD_DIR) +$(CLK_CONFIG_HEADER): $(DTS_FILE) + $(PYTHON) $(CLK_DRIVER_COMMON_DIR)/create_clk_config.py $(DTS_FILE) $(BUILD_DIR) clean:: rm -f clk_driver.o diff --git a/examples/clk/board/maaxboard/clk.system b/examples/clk/board/maaxboard/clk.system new file mode 100644 index 000000000..5d6f69373 --- /dev/null +++ b/examples/clk/board/maaxboard/clk.system @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/clk/build.zig b/examples/clk/build.zig index a543474fa..583dd6a01 100644 --- a/examples/clk/build.zig +++ b/examples/clk/build.zig @@ -4,7 +4,7 @@ // const std = @import("std"); -const MicrokitBoard = enum { odroidc4 }; +const MicrokitBoard = enum { odroidc4, maaxboard }; const Target = struct { board: MicrokitBoard, @@ -21,6 +21,15 @@ const targets = [_]Target{ .abi = .none, }, }, + .{ + .board = MicrokitBoard.maaxboard, + .zig_target = std.Target.Query{ + .cpu_arch = .aarch64, + .cpu_model = .{ .explicit = &std.Target.arm.cpu.cortex_a53 }, + .os_tag = .freestanding, + .abi = .none, + }, + }, }; fn findTarget(board: MicrokitBoard) std.Target.Query { @@ -87,10 +96,12 @@ pub fn build(b: *std.Build) void { const timer_driver_class = switch (microkit_board_option.?) { .odroidc4 => "meson", + .maaxboard => "imx", }; const clk_driver_class = switch (microkit_board_option.?) { .odroidc4 => "meson", + .maaxboard => "imx", }; const clk_driver = sddf_dep.artifact(b.fmt("driver_clk_{s}.elf", .{clk_driver_class})); const clk_driver_install = b.addInstallArtifact(clk_driver, .{ .dest_sub_path = "clk_driver.elf" }); diff --git a/examples/clk/client.c b/examples/clk/client.c index 7f69fd2f5..65894be3d 100644 --- a/examples/clk/client.c +++ b/examples/clk/client.c @@ -14,7 +14,7 @@ void init(void) { sddf_dprintf("--------------------\n"); - sddf_dprintf("Clock driver test\n"); + sddf_dprintf("Clock Driver Test\n"); #ifdef TEST_BOARD_odroidc4 sddf_dprintf("Test board: odroidc4\n"); @@ -30,7 +30,14 @@ void init(void) ret = sddf_clk_set_rate(CLK_DRIVER_CH, 10, 150000000); sddf_dprintf("ret_val: %x\n", ret); -#elif + +#elif TEST_BOARD_maaxboard + sddf_dprintf("Test board: maaxboard\n"); + + uint32_t ret = sddf_clk_enable(CLK_DRIVER_CH, 196); + sddf_dprintf("ret_val: %x\n", ret); + +#else sddf_dprintf("No tests for the target board\n", ret); #endif diff --git a/examples/clk/clk.mk b/examples/clk/clk.mk index 9e6aa92c2..df895982a 100644 --- a/examples/clk/clk.mk +++ b/examples/clk/clk.mk @@ -16,6 +16,12 @@ ifeq ($(strip $(MICROKIT_BOARD)), odroidc4) ARCH := aarch64 DRIVER_DIR := meson CPU := cortex-a55 +else ifeq ($(strip $(MICROKIT_BOARD)), maaxboard) + ARCH := aarch64 + DTS_FILE := $(TOP)/dts/maaxboard.dts + SYSTEM_FILE := ${TOP}/board/maaxboard/clk.system + DRIVER_DIR := imx + CPU := cortex-a53 else $(error Unsupported MICROKIT_BOARD given) endif diff --git a/examples/clk/dts/maaxboard.dts b/examples/clk/dts/maaxboard.dts new file mode 100644 index 000000000..434b0e863 --- /dev/null +++ b/examples/clk/dts/maaxboard.dts @@ -0,0 +1,1950 @@ +/* + * Copyright 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * Copyright (C) 2017-2018 Pengutronix, Lucas Stach + * Copyright 2019 EMBEST + * Copyright 2022 Capgemini Engineering + * + * SPDX-License-Identifier: GPL-2.0-only + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * This file is derived from a DTS file supplied by Avnet. + * + * The licenses of all input files to this process are compatible + * with GPL-2.0. + * + * The following commands were used to derive this file: + * > git clone https://github.com/Avnet/linux-imx.git + * > cd linux-imx + * > cpp -nostdinc -I include -I arch -undef -x assembler-with-cpp \ + * > arch/arm64/boot/dts/freescale/maaxboard-dcss-hdmi.dts temp.dts + * > dtc -o temp.dtb temp.dts + * > dtc -o maaxboard.dts temp.dtb + * > rm temp.dts temp.dtb + */ + +/dts-v1/; + +/ { + interrupt-parent = <0x01>; + #address-cells = <0x02>; + #size-cells = <0x02>; + model = "Avnet Maaxboard"; + compatible = "avnet/embest,maaxboard\0fsl,imx8mq"; + + aliases { + csi0 = "/soc@0/bus@30800000/mipi_csi1@30a70000"; + csi1 = "/soc@0/bus@30800000/mipi_csi2@30b60000"; + ethernet0 = "/soc@0/bus@30800000/ethernet@30be0000"; + gpio0 = "/soc@0/bus@30000000/gpio@30200000"; + gpio1 = "/soc@0/bus@30000000/gpio@30210000"; + gpio2 = "/soc@0/bus@30000000/gpio@30220000"; + gpio3 = "/soc@0/bus@30000000/gpio@30230000"; + gpio4 = "/soc@0/bus@30000000/gpio@30240000"; + i2c0 = "/soc@0/bus@30800000/i2c@30a20000"; + i2c1 = "/soc@0/bus@30800000/i2c@30a30000"; + i2c2 = "/soc@0/bus@30800000/i2c@30a40000"; + i2c3 = "/soc@0/bus@30800000/i2c@30a50000"; + mmc0 = "/soc@0/bus@30800000/mmc@30b40000"; + mmc1 = "/soc@0/bus@30800000/mmc@30b50000"; + serial0 = "/soc@0/bus@30800000/serial@30860000"; + serial1 = "/soc@0/bus@30800000/serial@30890000"; + serial2 = "/soc@0/bus@30800000/serial@30880000"; + serial3 = "/soc@0/bus@30800000/serial@30a60000"; + spi0 = "/soc@0/bus@30800000/spi@30820000"; + spi1 = "/soc@0/bus@30800000/spi@30830000"; + spi2 = "/soc@0/bus@30800000/spi@30840000"; + }; + + clock-ckil { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "ckil"; + phandle = <0x15>; + }; + + clock-osc-25m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x17d7840>; + clock-output-names = "osc_25m"; + phandle = <0x16>; + }; + + clock-osc-27m { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x19bfcc0>; + clock-output-names = "osc_27m"; + phandle = <0x17>; + }; + + clock-ext1 { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x7ed6b40>; + clock-output-names = "clk_ext1"; + phandle = <0x18>; + }; + + clock-ext2 { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x7ed6b40>; + clock-output-names = "clk_ext2"; + phandle = <0x19>; + }; + + clock-ext3 { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x7ed6b40>; + clock-output-names = "clk_ext3"; + phandle = <0x1a>; + }; + + clock-ext4 { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x7ed6b40>; + clock-output-names = "clk_ext4"; + phandle = <0x1b>; + }; + + cpus { + #address-cells = <0x01>; + #size-cells = <0x00>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x00>; + clock-latency = <0xee6c>; + clocks = <0x02 0x102>; + enable-method = "psci"; + next-level-cache = <0x03>; + operating-points-v2 = <0x04>; + #cooling-cells = <0x02>; + nvmem-cells = <0x05>; + nvmem-cell-names = "speed_grade"; + cpu-idle-states = <0x06>; + phandle = <0x08>; + }; + + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x01>; + clock-latency = <0xee6c>; + clocks = <0x02 0x102>; + enable-method = "psci"; + next-level-cache = <0x03>; + operating-points-v2 = <0x04>; + #cooling-cells = <0x02>; + cpu-idle-states = <0x06>; + phandle = <0x09>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x02>; + clock-latency = <0xee6c>; + clocks = <0x02 0x102>; + enable-method = "psci"; + next-level-cache = <0x03>; + operating-points-v2 = <0x04>; + #cooling-cells = <0x02>; + cpu-idle-states = <0x06>; + phandle = <0x0a>; + }; + + cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x03>; + clock-latency = <0xee6c>; + clocks = <0x02 0x102>; + enable-method = "psci"; + next-level-cache = <0x03>; + operating-points-v2 = <0x04>; + #cooling-cells = <0x02>; + cpu-idle-states = <0x06>; + phandle = <0x0b>; + }; + + l2-cache0 { + compatible = "cache"; + phandle = <0x03>; + }; + + idle-states { + entry-method = "psci"; + + cpu-sleep { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x10033>; + local-timer-stop; + entry-latency-us = <0x3e8>; + exit-latency-us = <0x2bc>; + min-residency-us = <0xa8c>; + wakeup-latency-us = <0x5dc>; + phandle = <0x06>; + }; + }; + }; + + opp-table { + compatible = "operating-points-v2"; + opp-shared; + phandle = <0x04>; + + opp-800000000 { + opp-hz = <0x00 0x2faf0800>; + opp-microvolt = <0xdbba0>; + opp-supported-hw = <0x0f 0x04>; + clock-latency-ns = <0x249f0>; + opp-suspend; + }; + + opp-1000000000 { + opp-hz = <0x00 0x3b9aca00>; + opp-microvolt = <0xdbba0>; + opp-supported-hw = <0x0e 0x03>; + clock-latency-ns = <0x249f0>; + opp-suspend; + }; + + opp-1300000000 { + opp-hz = <0x00 0x4d7c6d00>; + opp-microvolt = <0xf4240>; + opp-supported-hw = <0x0c 0x04>; + clock-latency-ns = <0x249f0>; + opp-suspend; + }; + + opp-1500000000 { + opp-hz = <0x00 0x59682f00>; + opp-microvolt = <0xf4240>; + opp-supported-hw = <0x08 0x03>; + clock-latency-ns = <0x249f0>; + opp-suspend; + }; + }; + + pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = <0x01 0x07 0x04>; + interrupt-parent = <0x07>; + interrupt-affinity = <0x08 0x09 0x0a 0x0b>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + thermal-zones { + + cpu-thermal { + polling-delay-passive = <0xfa>; + polling-delay = <0x7d0>; + thermal-sensors = <0x0c 0x00>; + + trips { + + cpu-alert { + temperature = <0x13880>; + hysteresis = <0x7d0>; + type = "passive"; + }; + + cpu-crit { + temperature = <0x17318>; + hysteresis = <0x7d0>; + type = "critical"; + }; + + trip0 { + temperature = <0x13880>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x0d>; + }; + + trip1 { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x0f>; + }; + }; + + cooling-maps { + + map0 { + trip = <0x0d>; + cooling-device = <0x0e 0x00 0x01 0x08 0xffffffff 0xffffffff 0x09 0xffffffff 0xffffffff 0x0a 0xffffffff 0xffffffff 0x0b 0xffffffff 0xffffffff>; + }; + + map1 { + trip = <0x0f>; + cooling-device = <0x0e 0x00 0x02>; + }; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <0x01 0x0d 0x08 0x01 0x0e 0x08 0x01 0x0b 0x08 0x01 0x0a 0x08>; + interrupt-parent = <0x07>; + arm,no-tick-in-suspend; + }; + + busfreq { + compatible = "fsl,imx_busfreq"; + clocks = <0x02 0xea 0x02 0x76 0x02 0x77 0x02 0x77 0x02 0xfc 0x02 0xfb 0x02 0x46 0x02 0x4d 0x02 0x48 0x02 0x4e 0x02 0x71 0x02 0x67 0x02 0x74 0x02 0x02 0x02 0x55 0x02 0x49>; + clock-names = "dram_pll\0dram_alt_src\0dram_apb_src\0dram_apb_pre_div\0dram_core\0dram_alt_root\0sys1_pll_40m\0sys1_pll_400m\0sys1_pll_100m\0sys1_pll_800m\0noc_div\0main_axi_src\0ahb_div\0osc_25m\0sys2_pll_333m\0sys1_pll_133m"; + interrupts = <0x00 0x66 0x04 0x00 0x6d 0x04 0x00 0x6e 0x04 0x00 0x6f 0x04>; + interrupt-name = "irq_busfreq_0\0irq_busfreq_1\0irq_busfreq_2\0irq_busfreq_3"; + }; + + soc@0 { + compatible = "simple-bus"; + #address-cells = <0x01>; + #size-cells = <0x01>; + ranges = <0x00 0x00 0x00 0x3e000000>; + dma-ranges = <0x40000000 0x00 0x40000000 0xc0000000>; + + caam-sm@100000 { + compatible = "fsl,imx6q-caam-sm"; + reg = <0x100000 0x8000>; + }; + + bus@30000000 { + compatible = "fsl,imx8mq-aips-bus\0simple-bus"; + #address-cells = <0x01>; + #size-cells = <0x01>; + ranges = <0x30000000 0x30000000 0x400000>; + + sai@30010000 { + compatible = "fsl,imx8mq-sai\0fsl,imx6sx-sai"; + reg = <0x30010000 0x10000>; + interrupts = <0x00 0x5f 0x04>; + clocks = <0x02 0xee 0x02 0x00 0x02 0xc4 0x02 0x00 0x02 0x00>; + clock-names = "bus\0mclk0\0mclk1\0mclk2\0mclk3"; + dmas = <0x10 0x08 0x01 0x00 0x10 0x09 0x01 0x00>; + dma-names = "rx\0tx"; + fsl,dataline = <0x00 0xff 0xff>; + status = "disabled"; + }; + + sai@30030000 { + compatible = "fsl,imx8mq-sai\0fsl,imx6sx-sai"; + reg = <0x30030000 0x10000>; + interrupts = <0x00 0x5a 0x04>; + clocks = <0x02 0xf3 0x02 0x00 0x02 0xc9 0x02 0x00 0x02 0x00>; + clock-names = "bus\0mclk0\0mclk1\0mclk2\0mclk3"; + dmas = <0x10 0x04 0x18 0x00 0x10 0x05 0x18 0x00>; + dma-names = "rx\0tx"; + fsl,shared-interrupt; + status = "disabled"; + }; + + sai@30040000 { + compatible = "fsl,imx8mq-sai\0fsl,imx6sx-sai"; + reg = <0x30040000 0x10000>; + interrupts = <0x00 0x5a 0x04>; + clocks = <0x02 0xf2 0x02 0x00 0x02 0xc8 0x02 0x00 0x02 0x00>; + clock-names = "bus\0mclk0\0mclk1\0mclk2\0mclk3"; + dmas = <0x10 0x02 0x18 0x00 0x10 0x03 0x18 0x00>; + dma-names = "rx\0tx"; + fsl,shared-interrupt; + fsl,dataline = <0x00 0x0f 0x0f>; + status = "disabled"; + }; + + sai@30050000 { + compatible = "fsl,imx8mq-sai\0fsl,imx6sx-sai"; + reg = <0x30050000 0x10000>; + interrupts = <0x00 0x64 0x04>; + clocks = <0x02 0xf1 0x02 0x00 0x02 0xc7 0x02 0x00 0x02 0x00 0x02 0x1b 0x02 0x20>; + clock-names = "bus\0mclk0\0mclk1\0mclk2\0mclk3\0pll8k\0pll11k"; + dmas = <0x10 0x00 0x18 0x00 0x10 0x01 0x18 0x00>; + dma-names = "rx\0tx"; + fsl,dataline = <0x00 0x00 0x0f>; + status = "okay"; + assigned-clocks = <0x02 0x84>; + assigned-clock-parents = <0x02 0x1b>; + assigned-clock-rates = <0x1770000>; + phandle = <0x55>; + }; + + gpio@30200000 { + compatible = "fsl,imx8mq-gpio\0fsl,imx35-gpio"; + reg = <0x30200000 0x10000>; + interrupts = <0x00 0x40 0x04 0x00 0x41 0x04>; + clocks = <0x02 0x103>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + gpio-ranges = <0x11 0x00 0x0a 0x1e>; + phandle = <0x2e>; + }; + + gpio@30210000 { + compatible = "fsl,imx8mq-gpio\0fsl,imx35-gpio"; + reg = <0x30210000 0x10000>; + interrupts = <0x00 0x42 0x04 0x00 0x43 0x04>; + clocks = <0x02 0x104>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + gpio-ranges = <0x11 0x00 0x28 0x15>; + phandle = <0x43>; + }; + + gpio@30220000 { + compatible = "fsl,imx8mq-gpio\0fsl,imx35-gpio"; + reg = <0x30220000 0x10000>; + interrupts = <0x00 0x44 0x04 0x00 0x45 0x04>; + clocks = <0x02 0x105>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + gpio-ranges = <0x11 0x00 0x3d 0x1a>; + phandle = <0x30>; + }; + + gpio@30230000 { + compatible = "fsl,imx8mq-gpio\0fsl,imx35-gpio"; + reg = <0x30230000 0x10000>; + interrupts = <0x00 0x46 0x04 0x00 0x47 0x04>; + clocks = <0x02 0x106>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + gpio-ranges = <0x11 0x00 0x57 0x20>; + }; + + gpio@30240000 { + compatible = "fsl,imx8mq-gpio\0fsl,imx35-gpio"; + reg = <0x30240000 0x10000>; + interrupts = <0x00 0x48 0x04 0x00 0x49 0x04>; + clocks = <0x02 0x107>; + gpio-controller; + #gpio-cells = <0x02>; + interrupt-controller; + #interrupt-cells = <0x02>; + gpio-ranges = <0x11 0x00 0x77 0x1e>; + phandle = <0x23>; + }; + + tmu@30260000 { + compatible = "fsl,imx8mq-tmu"; + reg = <0x30260000 0x10000>; + interrupt = <0x00 0x31 0x04>; + clocks = <0x02 0xf6>; + little-endian; + fsl,tmu-range = <0xb0000 0xa0026 0x80048 0x70061>; + fsl,tmu-calibration = <0x00 0x23 0x01 0x29 0x02 0x2f 0x03 0x35 0x04 0x3d 0x05 0x43 0x06 0x4b 0x07 0x51 0x08 0x57 0x09 0x5f 0x0a 0x67 0x0b 0x6f 0x10000 0x1b 0x10001 0x23 0x10002 0x2b 0x10003 0x33 0x10004 0x3b 0x10005 0x43 0x10006 0x4b 0x10007 0x55 0x10008 0x5d 0x10009 0x67 0x1000a 0x70 0x20000 0x17 0x20001 0x23 0x20002 0x2d 0x20003 0x37 0x20004 0x41 0x20005 0x4b 0x20006 0x57 0x20007 0x63 0x20008 0x6f 0x30000 0x15 0x30001 0x21 0x30002 0x2d 0x30003 0x39 0x30004 0x45 0x30005 0x53 0x30006 0x5f 0x30007 0x71>; + #thermal-sensor-cells = <0x00>; + phandle = <0x0c>; + + throttle-cfgs { + + devfreq { + throttle,max_state = <0x02>; + #cooling-cells = <0x02>; + phandle = <0x0e>; + }; + }; + }; + + watchdog@30280000 { + compatible = "fsl,imx8mq-wdt\0fsl,imx21-wdt"; + reg = <0x30280000 0x10000>; + interrupts = <0x00 0x4e 0x04>; + clocks = <0x02 0xd4>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x12>; + fsl,ext-reset-output; + }; + + watchdog@30290000 { + compatible = "fsl,imx8mq-wdt\0fsl,imx21-wdt"; + reg = <0x30290000 0x10000>; + interrupts = <0x00 0x4f 0x04>; + clocks = <0x02 0xd5>; + status = "disabled"; + }; + + watchdog@302a0000 { + compatible = "fsl,imx8mq-wdt\0fsl,imx21-wdt"; + reg = <0x302a0000 0x10000>; + interrupts = <0x00 0x0a 0x04>; + clocks = <0x02 0xd6>; + status = "disabled"; + }; + + sdma@302c0000 { + compatible = "fsl,imx8mq-sdma\0fsl,imx7d-sdma"; + reg = <0x302c0000 0x10000>; + interrupts = <0x00 0x67 0x04>; + clocks = <0x02 0xe4 0x02 0xe4>; + clock-names = "ipg\0ahb"; + #dma-cells = <0x03>; + fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin"; + phandle = <0x10>; + }; + + lcdif@30320000 { + compatible = "fsl,imx8mq-lcdif\0fsl,imx28-lcdif"; + reg = <0x30320000 0x10000>; + clocks = <0x02 0x80>; + clock-names = "pix"; + assigned-clocks = <0x02 0x80 0x02 0x24 0x02 0x21>; + assigned-clock-parents = <0x02 0x25 0x02 0x23 0x02 0x03>; + interrupts = <0x00 0x05 0x04>; + status = "disabled"; + }; + + iomuxc@30330000 { + compatible = "fsl,imx8mq-iomuxc"; + reg = <0x30330000 0x10000>; + pinctrl-names = "default"; + pinctrl-0 = <0x13>; + phandle = <0x11>; + + imx8mq-evk { + + gpio_ledsgrp { + fsl,pins = <0x3c 0x2a4 0x00 0x00 0x00 0x19 0x48 0x2b0 0x00 0x00 0x00 0x19>; + phandle = <0x53>; + }; + + gpio_keysgrp { + fsl,pins = <0x110 0x378 0x00 0x05 0x00 0x56 0x10c 0x374 0x00 0x05 0x00 0x56>; + phandle = <0x54>; + }; + + uart1grp { + fsl,pins = <0x234 0x49c 0x4f4 0x00 0x00 0x49 0x238 0x4a0 0x00 0x00 0x00 0x49>; + phandle = <0x24>; + }; + + uart4grp { + fsl,pins = <0x24c 0x4b4 0x50c 0x00 0x02 0x49 0x250 0x4b8 0x00 0x00 0x00 0x49 0x210 0x478 0x508 0x01 0x01 0x49 0x20c 0x474 0x00 0x01 0x00 0x49 0x208 0x470 0x00 0x05 0x00 0x19>; + phandle = <0x36>; + }; + + wlangrp { + fsl,pins = <0xec 0x354 0x00 0x05 0x00 0x19 0xd0 0x338 0x00 0x05 0x00 0x19 0x28 0x290 0x00 0x05 0x00 0x05>; + phandle = <0x57>; + }; + + reg3V3wfgrp { + fsl,pins = <0xf0 0x358 0x00 0x05 0x00 0x19>; + phandle = <0x56>; + }; + + usdhc1grp { + fsl,pins = <0xa0 0x308 0x00 0x00 0x00 0x83 0xa4 0x30c 0x00 0x00 0x00 0xc3 0xa8 0x310 0x00 0x00 0x00 0xc3 0xac 0x314 0x00 0x00 0x00 0xc3 0xb0 0x318 0x00 0x00 0x00 0xc3 0xb4 0x31c 0x00 0x00 0x00 0xc3 0x40 0x2a8 0x00 0x00 0x00 0x19>; + phandle = <0x3d>; + }; + + usdhc1grp100mhz { + fsl,pins = <0xa0 0x308 0x00 0x00 0x00 0x85 0xa4 0x30c 0x00 0x00 0x00 0xc5 0xa8 0x310 0x00 0x00 0x00 0xc5 0xac 0x314 0x00 0x00 0x00 0xc5 0xb0 0x318 0x00 0x00 0x00 0xc5 0xb4 0x31c 0x00 0x00 0x00 0xc5 0x40 0x2a8 0x00 0x00 0x00 0x19>; + phandle = <0x3e>; + }; + + usdhc1grp200mhz { + fsl,pins = <0xa0 0x308 0x00 0x00 0x00 0x87 0xa4 0x30c 0x00 0x00 0x00 0xc7 0xa8 0x310 0x00 0x00 0x00 0xc7 0xac 0x314 0x00 0x00 0x00 0xc7 0xb0 0x318 0x00 0x00 0x00 0xc7 0xb4 0x31c 0x00 0x00 0x00 0xc7 0x40 0x2a8 0x00 0x00 0x00 0x19>; + phandle = <0x3f>; + }; + + usdhc2grp { + fsl,pins = <0xd4 0x33c 0x00 0x00 0x00 0x83 0xd8 0x340 0x00 0x00 0x00 0xc3 0xdc 0x344 0x00 0x00 0x00 0xc3 0xe0 0x348 0x00 0x00 0x00 0xc3 0xe4 0x34c 0x00 0x00 0x00 0xc3 0xe8 0x350 0x00 0x00 0x00 0xc3>; + phandle = <0x40>; + }; + + i2c1grp { + fsl,pins = <0x214 0x47c 0x00 0x00 0x00 0x4000007f 0x218 0x480 0x00 0x00 0x00 0x4000007f>; + phandle = <0x2b>; + }; + + i2c4grp { + fsl,pins = <0x22c 0x494 0x00 0x00 0x00 0x4000007f 0x230 0x498 0x00 0x00 0x00 0x4000007f>; + phandle = <0x35>; + }; + + csi1grp { + fsl,pins = <0x13c 0x3a4 0x00 0x05 0x00 0x19 0x12c 0x394 0x00 0x05 0x00 0x19>; + phandle = <0x2f>; + }; + + pmicirq { + fsl,pins = <0x44 0x2ac 0x00 0x00 0x00 0x19>; + phandle = <0x2c>; + }; + + wdoggrp { + fsl,pins = <0x30 0x298 0x00 0x01 0x00 0xc6>; + phandle = <0x12>; + }; + + fec1grp { + fsl,pins = <0x68 0x2d0 0x00 0x00 0x00 0x03 0x6c 0x2d4 0x4c0 0x00 0x01 0x23 0x70 0x2d8 0x00 0x00 0x00 0x1f 0x74 0x2dc 0x00 0x00 0x00 0x1f 0x78 0x2e0 0x00 0x00 0x00 0x1f 0x7c 0x2e4 0x00 0x00 0x00 0x1f 0x9c 0x304 0x00 0x00 0x00 0x91 0x98 0x300 0x00 0x00 0x00 0x91 0x94 0x2fc 0x00 0x00 0x00 0x91 0x90 0x2f8 0x00 0x00 0x00 0x91 0x84 0x2ec 0x00 0x00 0x00 0x1f 0x8c 0x2f4 0x00 0x00 0x00 0x91 0x88 0x2f0 0x00 0x00 0x00 0x91 0x80 0x2e8 0x00 0x00 0x00 0x1f 0x4c 0x2b4 0x00 0x00 0x00 0x19>; + phandle = <0x46>; + }; + + hoggrp { + fsl,pins = <0x134 0x39c 0x00 0x05 0x00 0x19 0x138 0x3a0 0x00 0x05 0x00 0x19 0x114 0x37c 0x00 0x05 0x00 0x19 0x118 0x380 0x00 0x05 0x00 0x19 0x130 0x398 0x00 0x05 0x00 0x19 0x34 0x29c 0x00 0x00 0x00 0x19 0x120 0x388 0x00 0x05 0x00 0x19 0xfc 0x364 0x00 0x05 0x00 0x19 0x108 0x370 0x00 0x05 0x00 0x19 0x11c 0x384 0x00 0x05 0x00 0x19>; + phandle = <0x13>; + }; + + ecspi1grp { + fsl,pins = <0x200 0x468 0x00 0x05 0x00 0x19 0x1f8 0x460 0x00 0x00 0x00 0x19 0x1fc 0x464 0x00 0x00 0x00 0x19 0x1f4 0x45c 0x00 0x00 0x00 0x19>; + phandle = <0x22>; + }; + + i2c2grp { + fsl,pins = <0x21c 0x484 0x00 0x00 0x00 0x4000007f 0x220 0x488 0x00 0x00 0x00 0x4000007f>; + phandle = <0x32>; + }; + + i2c3grp { + fsl,pins = <0x224 0x48c 0x00 0x00 0x00 0x4000007f 0x228 0x490 0x00 0x00 0x00 0x4000007f>; + phandle = <0x34>; + }; + + uart2grp { + fsl,pins = <0x23c 0x4a4 0x4fc 0x00 0x00 0x49 0x240 0x4a8 0x00 0x00 0x00 0x49>; + phandle = <0x25>; + }; + + pwm2_grp { + fsl,pins = <0x5c 0x2c4 0x00 0x05 0x00 0x06>; + phandle = <0x1f>; + }; + + pwm4_grp { + fsl,pins = <0x64 0x2cc 0x00 0x05 0x00 0x06>; + phandle = <0x20>; + }; + + sai2grp { + fsl,pins = <0x1bc 0x424 0x00 0x00 0x00 0xd6 0x1c0 0x428 0x00 0x00 0x00 0xd6 0x1b8 0x420 0x00 0x00 0x00 0xd6 0x1c4 0x42c 0x00 0x00 0x00 0xd6>; + phandle = <0x26>; + }; + }; + }; + + syscon@30340000 { + compatible = "fsl,imx8mq-iomuxc-gpr\0fsl,imx6q-iomuxc-gpr\0syscon\0simple-mfd"; + reg = <0x30340000 0x10000>; + phandle = <0x39>; + + mux-controller { + compatible = "mmio-mux"; + #mux-control-cells = <0x01>; + mux-reg-masks = <0x34 0x04>; + phandle = <0x29>; + }; + }; + + ocotp-ctrl@30350000 { + compatible = "fsl,imx8mq-ocotp\0syscon"; + reg = <0x30350000 0x10000>; + clocks = <0x02 0xfa>; + #address-cells = <0x01>; + #size-cells = <0x01>; + + speed-grade@10 { + reg = <0x10 0x04>; + phandle = <0x05>; + }; + + mac-address@640 { + reg = <0x90 0x06>; + phandle = <0x45>; + }; + }; + + syscon@30360000 { + compatible = "fsl,imx8mq-anatop\0syscon"; + reg = <0x30360000 0x10000>; + interrupts = <0x00 0x31 0x04>; + }; + + caam_secvio { + compatible = "fsl,imx6q-caam-secvio"; + interrupts = <0x00 0x14 0x04>; + jtag-tamper = "disabled"; + watchdog-tamper = "enabled"; + internal-boot-tamper = "enabled"; + external-pin-tamper = "disabled"; + }; + + caam-snvs@30370000 { + compatible = "fsl,imx6q-caam-snvs"; + reg = <0x30370000 0x10000>; + }; + + snvs@30370000 { + compatible = "fsl,sec-v4.0-mon\0syscon\0simple-mfd"; + reg = <0x30370000 0x10000>; + phandle = <0x14>; + + snvs-rtc-lp { + compatible = "fsl,sec-v4.0-mon-rtc-lp"; + regmap = <0x14>; + offset = <0x34>; + interrupts = <0x00 0x13 0x04 0x00 0x14 0x04>; + clocks = <0x02 0x108>; + clock-names = "snvs-rtc"; + }; + + snvs-powerkey { + compatible = "fsl,sec-v4.0-pwrkey"; + regmap = <0x14>; + interrupts = <0x00 0x04 0x04>; + clocks = <0x02 0x108>; + clock-names = "snvs"; + linux,keycode = <0x74>; + wakeup-source; + status = "okay"; + }; + }; + + clock-controller@30380000 { + compatible = "fsl,imx8mq-ccm"; + reg = <0x30380000 0x10000>; + interrupts = <0x00 0x55 0x04 0x00 0x56 0x04>; + #clock-cells = <0x01>; + clocks = <0x15 0x16 0x17 0x18 0x19 0x1a 0x1b>; + clock-names = "ckil\0osc_25m\0osc_27m\0clk_ext1\0clk_ext2\0clk_ext3\0clk_ext4"; + assigned-clocks = <0x02 0x69 0x02 0x75 0x02 0x19 0x02 0x1e>; + assigned-clock-parents = <0x02 0x4c 0x02 0x56>; + assigned-clock-rates = <0x00 0x00 0x2ee00000 0x2b110000>; + phandle = <0x02>; + }; + + reset-controller@30390000 { + compatible = "fsl,imx8mq-src\0syscon"; + reg = <0x30390000 0x10000>; + #reset-cells = <0x01>; + phandle = <0x28>; + }; + + gpc@303a0000 { + compatible = "fsl,imx8mq-gpc"; + reg = <0x303a0000 0x10000>; + interrupt-parent = <0x07>; + interrupt-controller; + broken-wake-request-signals; + #interrupt-cells = <0x03>; + phandle = <0x01>; + + pgc { + #address-cells = <0x01>; + #size-cells = <0x00>; + + power-domain@0 { + #power-domain-cells = <0x00>; + reg = <0x00>; + phandle = <0x27>; + }; + + power-domain@1 { + #power-domain-cells = <0x00>; + reg = <0x01>; + power-domains = <0x1c>; + phandle = <0x50>; + }; + + power-domain@2 { + #power-domain-cells = <0x00>; + reg = <0x02>; + }; + + power-domain@3 { + #power-domain-cells = <0x00>; + reg = <0x03>; + phandle = <0x4e>; + }; + + power-domain@4 { + #power-domain-cells = <0x00>; + reg = <0x04>; + }; + + power-domain@5 { + #power-domain-cells = <0x00>; + reg = <0x05>; + clocks = <0x02 0xd7 0x02 0x66 0x02 0x6f 0x02 0x70>; + power-supply = <0x1d>; + phandle = <0x4b>; + }; + + power-domain@6 { + #power-domain-cells = <0x00>; + reg = <0x06>; + power-supply = <0x1e>; + phandle = <0x51>; + }; + + power-domain@7 { + #power-domain-cells = <0x00>; + reg = <0x07>; + }; + + power-domain@8 { + #power-domain-cells = <0x00>; + reg = <0x08>; + phandle = <0x38>; + }; + + power-domain@9 { + #power-domain-cells = <0x00>; + reg = <0x09>; + phandle = <0x44>; + }; + + power-domain@a { + #power-domain-cells = <0x00>; + reg = <0x0a>; + phandle = <0x1c>; + }; + }; + }; + }; + + bus@30400000 { + compatible = "fsl,imx8mq-aips-bus\0simple-bus"; + #address-cells = <0x01>; + #size-cells = <0x01>; + ranges = <0x30400000 0x30400000 0x400000>; + + pwm@30660000 { + compatible = "fsl,imx8mq-pwm\0fsl,imx27-pwm"; + reg = <0x30660000 0x10000>; + interrupts = <0x00 0x51 0x04>; + clocks = <0x02 0xbf 0x02 0xbf>; + clock-names = "ipg\0per"; + #pwm-cells = <0x02>; + status = "disabled"; + }; + + pwm@30670000 { + compatible = "fsl,imx8mq-pwm\0fsl,imx27-pwm"; + reg = <0x30670000 0x10000>; + interrupts = <0x00 0x52 0x04>; + clocks = <0x02 0xc0 0x02 0xc0>; + clock-names = "ipg\0per"; + #pwm-cells = <0x02>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x1f>; + }; + + pwm@30680000 { + compatible = "fsl,imx8mq-pwm\0fsl,imx27-pwm"; + reg = <0x30680000 0x10000>; + interrupts = <0x00 0x53 0x04>; + clocks = <0x02 0xc1 0x02 0xc1>; + clock-names = "ipg\0per"; + #pwm-cells = <0x02>; + status = "disabled"; + }; + + pwm@30690000 { + compatible = "fsl,imx8mq-pwm\0fsl,imx27-pwm"; + reg = <0x30690000 0x10000>; + interrupts = <0x00 0x54 0x04>; + clocks = <0x02 0xc2 0x02 0xc2>; + clock-names = "ipg\0per"; + #pwm-cells = <0x02>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x20>; + }; + + timer@306a0000 { + compatible = "nxp,sysctr-timer"; + reg = <0x306a0000 0x20000>; + interrupts = <0x00 0x2f 0x04>; + clocks = <0x16>; + clock-names = "per"; + }; + }; + + bus@30800000 { + compatible = "fsl,imx8mq-aips-bus\0simple-bus"; + #address-cells = <0x01>; + #size-cells = <0x01>; + ranges = <0x30800000 0x30800000 0x400000 0x8000000 0x8000000 0x10000000>; + + spdif@30810000 { + compatible = "fsl,imx8mm-spdif\0fsl,imx35-spdif"; + reg = <0x30810000 0x10000>; + interrupts = <0x00 0x06 0x04>; + clocks = <0x02 0xec 0x02 0x02 0x02 0x87 0x02 0x00 0x02 0x00 0x02 0x00 0x02 0xec 0x02 0x00 0x02 0x00 0x02 0x00>; + clock-names = "core\0rxtx0\0rxtx1\0rxtx2\0rxtx3\0rxtx4\0rxtx5\0rxtx6\0rxtx7\0spba"; + dmas = <0x21 0x08 0x12 0x00 0x21 0x09 0x12 0x00>; + dma-names = "rx\0tx"; + status = "disabled"; + }; + + spi@30820000 { + #address-cells = <0x01>; + #size-cells = <0x00>; + compatible = "fsl,imx8mq-ecspi\0fsl,imx51-ecspi"; + reg = <0x30820000 0x10000>; + interrupts = <0x00 0x1f 0x04>; + clocks = <0x02 0xb3 0x02 0xb3>; + clock-names = "ipg\0per"; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x22>; + fsl,spi-num-chipselects = <0x01>; + cs-gpios = <0x23 0x09 0x00>; + + spidev@0 { + compatible = "fsl,spidev\0semtech,sx1301"; + reg = <0x00>; + spi-max-frequency = <0x1e8480>; + }; + }; + + spi@30830000 { + #address-cells = <0x01>; + #size-cells = <0x00>; + compatible = "fsl,imx8mq-ecspi\0fsl,imx51-ecspi"; + reg = <0x30830000 0x10000>; + interrupts = <0x00 0x20 0x04>; + clocks = <0x02 0xb4 0x02 0xb4>; + clock-names = "ipg\0per"; + status = "disabled"; + }; + + spi@30840000 { + #address-cells = <0x01>; + #size-cells = <0x00>; + compatible = "fsl,imx8mq-ecspi\0fsl,imx51-ecspi"; + reg = <0x30840000 0x10000>; + interrupts = <0x00 0x21 0x04>; + clocks = <0x02 0xb5 0x02 0xb5>; + clock-names = "ipg\0per"; + status = "disabled"; + }; + + serial@30860000 { + compatible = "fsl,imx8mq-uart\0fsl,imx6q-uart"; + reg = <0x30860000 0x10000>; + interrupts = <0x00 0x1a 0x04>; + clocks = <0x02 0xca 0x02 0xca>; + clock-names = "ipg\0per"; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x24>; + assigned-clocks = <0x02 0x94>; + assigned-clock-parents = <0x02 0x02>; + }; + + serial@30880000 { + compatible = "fsl,imx8mq-uart\0fsl,imx6q-uart"; + reg = <0x30880000 0x10000>; + interrupts = <0x00 0x1c 0x04>; + clocks = <0x02 0xcc 0x02 0xcc>; + clock-names = "ipg\0per"; + status = "disabled"; + }; + + serial@30890000 { + compatible = "fsl,imx8mq-uart\0fsl,imx6q-uart"; + reg = <0x30890000 0x10000>; + interrupts = <0x00 0x1b 0x04>; + clocks = <0x02 0xcb 0x02 0xcb>; + clock-names = "ipg\0per"; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x25>; + assigned-clocks = <0x02 0x95>; + assigned-clock-parents = <0x02 0x02>; + }; + + spdif@308a0000 { + compatible = "fsl,imx8mm-spdif\0fsl,imx35-spdif"; + reg = <0x308a0000 0x10000>; + interrupts = <0x00 0x0d 0x04>; + clocks = <0x02 0xec 0x02 0x02 0x02 0x88 0x02 0x00 0x02 0x00 0x02 0x00 0x02 0xec 0x02 0x00 0x02 0x00 0x02 0x00>; + clock-names = "core\0rxtx0\0rxtx1\0rxtx2\0rxtx3\0rxtx4\0rxtx5\0rxtx6\0rxtx7\0spba"; + dmas = <0x21 0x10 0x12 0x00 0x21 0x11 0x12 0x00>; + dma-names = "rx\0tx"; + status = "disabled"; + }; + + sai@308b0000 { + #sound-dai-cells = <0x00>; + compatible = "fsl,imx8mq-sai"; + reg = <0x308b0000 0x10000>; + interrupts = <0x00 0x60 0x04>; + clocks = <0x02 0xef 0x02 0x00 0x02 0xc5 0x02 0x00 0x02 0x00>; + clock-names = "bus\0mclk0\0mclk1\0mclk2\0mclk3"; + dmas = <0x21 0x0a 0x18 0x00 0x21 0x0b 0x18 0x00>; + dma-names = "rx\0tx"; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x26>; + assigned-clocks = <0x02 0x82>; + assigned-clock-parents = <0x02 0x1b>; + assigned-clock-rates = <0x1770000>; + phandle = <0x59>; + }; + + sai@308c0000 { + compatible = "fsl,imx8mq-sai\0fsl,imx6sx-sai"; + reg = <0x308c0000 0x10000>; + interrupts = <0x00 0x32 0x04>; + clocks = <0x02 0xf0 0x02 0x00 0x02 0xc6 0x02 0x00 0x02 0x00>; + clock-names = "bus\0mclk0\0mclk1\0mclk2\0mclk3"; + dmas = <0x21 0x0c 0x18 0x00 0x21 0x0d 0x18 0x00>; + dma-names = "rx\0tx"; + status = "disabled"; + }; + + crypto@30900000 { + compatible = "fsl,sec-v4.0"; + #address-cells = <0x01>; + #size-cells = <0x01>; + reg = <0x30900000 0x40000>; + ranges = <0x00 0x30900000 0x40000>; + interrupts = <0x00 0x5b 0x04>; + clocks = <0x02 0x74 0x02 0xec>; + clock-names = "aclk\0ipg"; + + jr@1000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x1000 0x1000>; + interrupts = <0x00 0x69 0x04>; + }; + + jr@2000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x2000 0x1000>; + interrupts = <0x00 0x6a 0x04>; + }; + + jr@3000 { + compatible = "fsl,sec-v4.0-job-ring"; + reg = <0x3000 0x1000>; + interrupts = <0x00 0x72 0x04>; + }; + }; + + dphy@30a00300 { + compatible = "fsl,imx8mq-mipi-dphy"; + reg = <0x30a00300 0x100>; + clocks = <0x02 0xa4>; + clock-names = "phy_ref"; + assigned-clocks = <0x02 0xa4>; + assigned-clock-parents = <0x02 0x25>; + assigned-clock-rates = <0x16e3600>; + #phy-cells = <0x00>; + power-domains = <0x27>; + status = "disabled"; + phandle = <0x2a>; + }; + + mipi_dsi@30a00000 { + #address-cells = <0x01>; + #size-cells = <0x00>; + compatible = "fsl,imx8mq-nwl-dsi"; + reg = <0x30a00000 0x300>; + clocks = <0x02 0xa3 0x02 0xf4 0x02 0xf5 0x02 0xa4 0x02 0x23 0x02 0x80>; + clock-names = "core\0rx_esc\0tx_esc\0phy_ref\0video_pll\0lcdif"; + assigned-clocks = <0x02 0xa4 0x02 0xa3 0x02 0xf4 0x02 0xf5>; + assigned-clock-parents = <0x02 0x25 0x02 0x4c 0x02 0x47>; + assigned-clock-rates = <0x19bfcc0 0xfdad680 0x4c4b400 0x1312d00>; + interrupts = <0x00 0x22 0x04>; + power-domains = <0x27>; + resets = <0x28 0x15 0x28 0x17 0x28 0x18 0x28 0x19>; + reset-names = "byte\0dpi\0esc\0pclk"; + mux-controls = <0x29 0x00>; + phys = <0x2a>; + phy-names = "dphy"; + status = "disabled"; + }; + + i2c@30a20000 { + compatible = "fsl,imx8mq-i2c\0fsl,imx21-i2c"; + reg = <0x30a20000 0x10000>; + interrupts = <0x00 0x23 0x04>; + clocks = <0x02 0xb8>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x186a0>; + pinctrl-names = "default"; + pinctrl-0 = <0x2b>; + + pmic@4b { + compatible = "rohm,bd71837"; + reg = <0x4b>; + pinctrl-names = "default"; + pinctrl-0 = <0x2c>; + clocks = <0x2d>; + clock-names = "osc"; + clock-output-names = "pmic_clk"; + interrupt-parent = <0x2e>; + interrupts = <0x07 0x01>; + interrupt-names = "irq"; + rohm,reset-snvs-powered; + + regulators { + + BUCK1 { + regulator-name = "buck1"; + regulator-min-microvolt = <0xaae60>; + regulator-max-microvolt = <0x13d620>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <0x4e2>; + rohm,dvs-run-voltage = <0xdbba0>; + rohm,dvs-idle-voltage = <0xcf850>; + rohm,dvs-suspend-voltage = <0xc3500>; + }; + + BUCK2 { + regulator-name = "buck2"; + regulator-min-microvolt = <0xaae60>; + regulator-max-microvolt = <0x13d620>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <0x4e2>; + rohm,dvs-run-voltage = <0xf4240>; + rohm,dvs-idle-voltage = <0xdbba0>; + }; + + BUCK3 { + regulator-name = "buck3"; + regulator-min-microvolt = <0xaae60>; + regulator-max-microvolt = <0x13d620>; + regulator-boot-on; + rohm,dvs-run-voltage = <0xf4240>; + regulator-enable-ramp-delay = <0xb4>; + phandle = <0x1d>; + }; + + BUCK4 { + regulator-name = "buck4"; + regulator-min-microvolt = <0xaae60>; + regulator-max-microvolt = <0x13d620>; + rohm,dvs-run-voltage = <0xf4240>; + regulator-boot-on; + regulator-enable-ramp-delay = <0xb4>; + phandle = <0x1e>; + }; + + BUCK5 { + regulator-name = "buck5"; + regulator-min-microvolt = <0xdbba0>; + regulator-max-microvolt = <0xf4240>; + regulator-boot-on; + regulator-always-on; + }; + + BUCK6 { + regulator-name = "buck6"; + regulator-min-microvolt = <0x2dc6c0>; + regulator-max-microvolt = <0x325aa0>; + regulator-boot-on; + regulator-always-on; + }; + + BUCK7 { + regulator-name = "buck7"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1cfde0>; + regulator-boot-on; + regulator-always-on; + }; + + BUCK8 { + regulator-name = "buck8"; + regulator-min-microvolt = <0x124f80>; + regulator-max-microvolt = <0x13d620>; + regulator-boot-on; + regulator-always-on; + }; + + LDO1 { + regulator-name = "ldo1"; + regulator-min-microvolt = <0x2dc6c0>; + regulator-max-microvolt = <0x325aa0>; + regulator-boot-on; + regulator-always-on; + }; + + LDO2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <0xdbba0>; + regulator-max-microvolt = <0xdbba0>; + regulator-boot-on; + regulator-always-on; + }; + + LDO3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <0x1b7740>; + regulator-max-microvolt = <0x1cfde0>; + regulator-boot-on; + regulator-always-on; + }; + + LDO4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <0xdbba0>; + regulator-max-microvolt = <0xf4240>; + regulator-boot-on; + regulator-always-on; + }; + + LDO5 { + regulator-name = "ldo5"; + regulator-min-microvolt = <0x2625a0>; + regulator-max-microvolt = <0x27ac40>; + regulator-boot-on; + regulator-always-on; + }; + + LDO6 { + regulator-name = "ldo6"; + regulator-min-microvolt = <0xdbba0>; + regulator-max-microvolt = <0xf4240>; + regulator-boot-on; + regulator-always-on; + }; + + LDO7 { + regulator-name = "ldo7"; + regulator-min-microvolt = <0x2dc6c0>; + regulator-max-microvolt = <0x325aa0>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + ov5640_mipi@3c { + compatible = "ovti,ov5640_mipi"; + reg = <0x3c>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x2f>; + clocks = <0x02 0xff>; + clock-names = "csi_mclk"; + csi_id = <0x00>; + pwn-gpios = <0x30 0x0e 0x00>; + rst-gpios = <0x30 0x12 0x00>; + mclk = <0x16e3600>; + mclk_source = <0x00>; + + port { + + endpoint { + remote-endpoint = <0x31>; + phandle = <0x3a>; + }; + }; + }; + }; + + i2c@30a30000 { + compatible = "fsl,imx8mq-i2c\0fsl,imx21-i2c"; + reg = <0x30a30000 0x10000>; + interrupts = <0x00 0x24 0x04>; + clocks = <0x02 0xb9>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x61a80>; + pinctrl-names = "default"; + pinctrl-0 = <0x32>; + + wm8960@1a { + #sound-dai-cells = <0x00>; + compatible = "wlf,wm8960"; + reg = <0x1a>; + clocks = <0x33>; + clock-names = "mclk"; + wlf,shared-lrclk; + phandle = <0x5a>; + }; + }; + + i2c@30a40000 { + compatible = "fsl,imx8mq-i2c\0fsl,imx21-i2c"; + reg = <0x30a40000 0x10000>; + interrupts = <0x00 0x25 0x04>; + clocks = <0x02 0xba>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "okay"; + clock-frequency = <0x186a0>; + pinctrl-names = "default"; + pinctrl-0 = <0x34>; + }; + + i2c@30a50000 { + compatible = "fsl,imx8mq-i2c\0fsl,imx21-i2c"; + reg = <0x30a50000 0x10000>; + interrupts = <0x00 0x26 0x04>; + clocks = <0x02 0xbb>; + #address-cells = <0x01>; + #size-cells = <0x00>; + status = "disabled"; + clock-frequency = <0x61a80>; + pinctrl-names = "default"; + pinctrl-0 = <0x35>; + }; + + serial@30a60000 { + compatible = "fsl,imx8mq-uart\0fsl,imx6q-uart"; + reg = <0x30a60000 0x10000>; + interrupts = <0x00 0x1d 0x04>; + clocks = <0x02 0xcd 0x02 0xcd>; + clock-names = "ipg\0per"; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x36>; + assigned-clocks = <0x02 0x97>; + assigned-clock-parents = <0x02 0x47>; + fsl,uart-has-rtscts; + resets = <0x37>; + }; + + mipi_csi1@30a70000 { + compatible = "fsl,mxc-mipi-csi2_yav"; + reg = <0x30a70000 0x1000>; + interrupts = <0x00 0x2c 0x04>; + clocks = <0x02 0xa7 0x02 0xa9 0x02 0xa8>; + clock-names = "clk_core\0clk_esc\0clk_pxl"; + assigned-clocks = <0x02 0xa7 0x02 0xa8 0x02 0xa9>; + assigned-clock-rates = <0x7ed6b40 0x5f5e100 0x3ef1480>; + power-domains = <0x38>; + csis-phy-reset = <0x28 0x4c 0x07>; + phy-gpr = <0x39 0x88>; + status = "okay"; + #address-cells = <0x01>; + #size-cells = <0x00>; + + port { + + endpoint@0 { + remote-endpoint = <0x3a>; + data-lanes = <0x01 0x02>; + bus-type = <0x04>; + phandle = <0x31>; + }; + + endpoint@1 { + remote-endpoint = <0x3b>; + phandle = <0x3c>; + }; + }; + }; + + csi1_bridge@30a90000 { + compatible = "fsl,imx8mq-csi\0fsl,imx6s-csi"; + reg = <0x30a90000 0x10000>; + interrupts = <0x00 0x2a 0x04>; + clocks = <0x02 0x00 0x02 0xe0 0x02 0x00>; + clock-names = "disp-axi\0csi_mclk\0disp_dcic"; + status = "okay"; + fsl,mipi-mode; + fsl,two-8bit-sensor-mode; + + port { + + endpoint { + remote-endpoint = <0x3c>; + phandle = <0x3b>; + }; + }; + }; + + mu@30aa0000 { + compatible = "fsl,imx8mq-mu\0fsl,imx6sx-mu"; + reg = <0x30aa0000 0x10000>; + interrupts = <0x00 0x58 0x04>; + clocks = <0x02 0xfd>; + clock-names = "mu"; + #mbox-cells = <0x02>; + phandle = <0x52>; + }; + + mmc@30b40000 { + compatible = "fsl,imx8mq-usdhc\0fsl,imx7d-usdhc"; + reg = <0x30b40000 0x10000>; + interrupts = <0x00 0x16 0x04>; + clocks = <0x02 0xec 0x02 0x69 0x02 0xd2>; + clock-names = "ipg\0ahb\0per"; + assigned-clocks = <0x02 0x8e>; + assigned-clock-rates = <0x17d78400>; + fsl,tuning-start-tap = <0x14>; + fsl,tuning-step = <0x02>; + bus-width = <0x04>; + status = "okay"; + pinctrl-names = "default\0state_100mhz\0state_200mhz"; + pinctrl-0 = <0x3d>; + pinctrl-1 = <0x3e>; + pinctrl-2 = <0x3f>; + non-removable; + no-sdio; + no-1-8-v; + }; + + mmc@30b50000 { + compatible = "fsl,imx8mq-usdhc\0fsl,imx7d-usdhc"; + reg = <0x30b50000 0x10000>; + interrupts = <0x00 0x17 0x04>; + clocks = <0x02 0xec 0x02 0x69 0x02 0xd3>; + clock-names = "ipg\0ahb\0per"; + fsl,tuning-start-tap = <0x14>; + fsl,tuning-step = <0x02>; + bus-width = <0x04>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x40>; + vmmc-supply = <0x41>; + mmc-pwrseq = <0x42>; + no-1-8-v; + non-removable; + pm-ignore-notify; + keep-power-in-suspend; + #address-cells = <0x01>; + #size-cells = <0x00>; + + bcrmf@1 { + reg = <0x01>; + compatible = "brcm,bcm4329-fmac"; + interrupt-parent = <0x43>; + interrupts = <0x0c 0x08>; + interrupt-names = "host-wake"; + }; + }; + + mipi_csi2@30b60000 { + compatible = "fsl,mxc-mipi-csi2_yav"; + reg = <0x30b60000 0x1000>; + interrupts = <0x00 0x2d 0x04>; + clocks = <0x02 0xaa 0x02 0xac 0x02 0xab>; + clock-names = "clk_core\0clk_esc\0clk_pxl"; + assigned-clocks = <0x02 0xaa 0x02 0xab 0x02 0xac>; + assigned-clock-rates = <0x7ed6b40 0x5f5e100 0x3ef1480>; + power-domains = <0x44>; + csis-phy-reset = <0x28 0x50 0x07>; + phy-gpr = <0x39 0xa4>; + status = "disabled"; + }; + + csi2_bridge@30b80000 { + compatible = "fsl,imx8mq-csi\0fsl,imx6s-csi"; + reg = <0x30b80000 0x10000>; + interrupts = <0x00 0x2b 0x04>; + clocks = <0x02 0x00 0x02 0xe1 0x02 0x00>; + clock-names = "disp-axi\0csi_mclk\0disp_dcic"; + status = "disabled"; + }; + + spi@30bb0000 { + #address-cells = <0x01>; + #size-cells = <0x00>; + compatible = "fsl,imx8mq-qspi\0fsl,imx7d-qspi"; + reg = <0x30bb0000 0x10000 0x8000000 0x10000000>; + reg-names = "QuadSPI\0QuadSPI-memory"; + interrupts = <0x00 0x6b 0x04>; + clocks = <0x02 0xc3 0x02 0xc3>; + clock-names = "qspi_en\0qspi"; + status = "disabled"; + }; + + sdma@30bd0000 { + compatible = "fsl,imx8mq-sdma\0fsl,imx7d-sdma"; + reg = <0x30bd0000 0x10000>; + interrupts = <0x00 0x02 0x04>; + clocks = <0x02 0xe3 0x02 0x74>; + clock-names = "ipg\0ahb"; + #dma-cells = <0x03>; + fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin"; + phandle = <0x21>; + }; + + ethernet@30be0000 { + compatible = "fsl,imx8mq-fec\0fsl,imx6sx-fec"; + reg = <0x30be0000 0x10000>; + interrupts = <0x00 0x76 0x04 0x00 0x77 0x04 0x00 0x78 0x04>; + clocks = <0x02 0xb6 0x02 0xb6 0x02 0x8a 0x02 0x89 0x02 0x8b>; + clock-names = "ipg\0ahb\0ptp\0enet_clk_ref\0enet_out"; + fsl,num-tx-queues = <0x03>; + fsl,num-rx-queues = <0x03>; + nvmem-cells = <0x45>; + nvmem-cell-names = "mac-address"; + nvmem_macaddr_swap; + stop-mode = <0x39 0x10 0x03>; + fsl,wakeup_irq = <0x02>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <0x46>; + phy-mode = "rgmii-id"; + phy-handle = <0x47>; + fsl,magic-packet; + phy-reset-gpios = <0x2e 0x09 0x01>; + + mdio { + #address-cells = <0x01>; + #size-cells = <0x00>; + + ethernet-phy@4 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x04>; + at803x,eee-disabled; + phandle = <0x47>; + }; + }; + }; + }; + + bus@32c00000 { + compatible = "fsl,imx8mq-aips-bus\0simple-bus"; + #address-cells = <0x01>; + #size-cells = <0x01>; + ranges = <0x32c00000 0x32c00000 0x400000>; + + hdmi@32c00000 { + reg = <0x32c00000 0x100000 0x32e40000 0x40000>; + interrupts = <0x00 0x10 0x04 0x00 0x19 0x04>; + interrupt-names = "plug_in\0plug_out"; + compatible = "cdn,imx8mq-hdmi"; + lane-mapping = <0xe4>; + status = "okay"; + + port@1 { + + endpoint { + remote-endpoint = <0x48>; + phandle = <0x4a>; + }; + }; + }; + + interrupt-controller@32e2d000 { + compatible = "fsl,imx8m-irqsteer\0fsl,imx-irqsteer"; + reg = <0x32e2d000 0x1000>; + interrupts = <0x00 0x12 0x04>; + clocks = <0x02 0xf8>; + clock-names = "ipg"; + fsl,channel = <0x00>; + fsl,num-irqs = <0x40>; + interrupt-controller; + #interrupt-cells = <0x01>; + status = "okay"; + phandle = <0x49>; + }; + + display-controller@32e00000 { + #address-cells = <0x01>; + #size-cells = <0x00>; + compatible = "nxp,imx8mq-dcss"; + reg = <0x32e00000 0x2d000 0x32e2f000 0x1000>; + interrupts = <0x06 0x08 0x09 0x10 0x11>; + interrupt-names = "ctx_ld\0ctxld_kick\0vblank\0dtrc_ch1\0dtrc_ch2"; + interrupt-parent = <0x49>; + clocks = <0x02 0xf8 0x02 0xf7 0x02 0xf9 0x02 0xfe 0x02 0x7a 0x02 0x10a 0x02 0x10b>; + clock-names = "apb\0axi\0rtrm\0pix\0dtrc\0pll_src\0pll_phy_ref"; + assigned-clocks = <0x02 0x6b 0x02 0x6d 0x02 0x10a>; + assigned-clock-parents = <0x02 0x4e 0x02 0x4e 0x02 0x03>; + assigned-clock-rates = <0x2faf0800 0x17d78400>; + status = "okay"; + + port@0 { + + endpoint { + remote-endpoint = <0x4a>; + phandle = <0x48>; + }; + }; + }; + }; + + gpu@38000000 { + compatible = "vivante,gc"; + reg = <0x38000000 0x40000>; + interrupts = <0x00 0x03 0x04>; + clocks = <0x02 0xd7 0x02 0x66 0x02 0x6f 0x02 0x70>; + clock-names = "core\0shader\0bus\0reg"; + assigned-clocks = <0x02 0x61 0x02 0x64 0x02 0x6f 0x02 0x70 0x02 0x10>; + assigned-clock-parents = <0x02 0x11 0x02 0x11 0x02 0x11 0x02 0x11 0x02 0x0f>; + assigned-clock-rates = <0x2faf0800 0x2faf0800 0x2faf0800 0x2faf0800 0x00>; + power-domains = <0x4b>; + status = "disabled"; + }; + + usb@38100000 { + compatible = "fsl,imx8mq-dwc3\0snps,dwc3"; + reg = <0x38100000 0x10000>; + clocks = <0x02 0xce 0x02 0x98 0x02 0x01>; + clock-names = "bus_early\0ref\0suspend"; + assigned-clocks = <0x02 0x6e 0x02 0x98>; + assigned-clock-parents = <0x02 0x56 0x02 0x48>; + assigned-clock-rates = <0x1dcd6500 0x5f5e100>; + interrupts = <0x00 0x28 0x04>; + phys = <0x4c 0x4c>; + phy-names = "usb2-phy\0usb3-phy"; + usb3-resume-missing-cas; + snps,power-down-scale = <0x02>; + status = "okay"; + dr_mode = "host"; + }; + + usb-phy@381f0040 { + compatible = "fsl,imx8mq-usb-phy"; + reg = <0x381f0040 0x40>; + clocks = <0x02 0xd0>; + clock-names = "phy"; + assigned-clocks = <0x02 0x99>; + assigned-clock-parents = <0x02 0x48>; + assigned-clock-rates = <0x5f5e100>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4c>; + }; + + usb@38200000 { + compatible = "fsl,imx8mq-dwc3\0snps,dwc3"; + reg = <0x38200000 0x10000>; + clocks = <0x02 0xcf 0x02 0x98 0x02 0x01>; + clock-names = "bus_early\0ref\0suspend"; + assigned-clocks = <0x02 0x6e 0x02 0x98>; + assigned-clock-parents = <0x02 0x56 0x02 0x48>; + assigned-clock-rates = <0x1dcd6500 0x5f5e100>; + interrupts = <0x00 0x29 0x04>; + phys = <0x4d 0x4d>; + phy-names = "usb2-phy\0usb3-phy"; + power-domains = <0x4e>; + usb3-resume-missing-cas; + snps,power-down-scale = <0x02>; + status = "okay"; + dr_mode = "host"; + }; + + usb-phy@382f0040 { + compatible = "fsl,imx8mq-usb-phy"; + reg = <0x382f0040 0x40>; + clocks = <0x02 0xd1>; + clock-names = "phy"; + assigned-clocks = <0x02 0x99>; + assigned-clock-parents = <0x02 0x48>; + assigned-clock-rates = <0x5f5e100>; + #phy-cells = <0x00>; + status = "okay"; + phandle = <0x4d>; + }; + + dma-apbh@33000000 { + compatible = "fsl,imx7d-dma-apbh\0fsl,imx28-dma-apbh"; + reg = <0x33000000 0x2000>; + interrupts = <0x00 0x0c 0x04 0x00 0x0c 0x04 0x00 0x0c 0x04 0x00 0x0c 0x04>; + interrupt-names = "gpmi0\0gpmi1\0gpmi2\0gpmi3"; + #dma-cells = <0x01>; + dma-channels = <0x04>; + clocks = <0x02 0x100>; + phandle = <0x4f>; + }; + + gpmi-nand@33002000 { + compatible = "fsl,imx7d-gpmi-nand"; + #address-cells = <0x01>; + #size-cells = <0x01>; + reg = <0x33002000 0x2000 0x33004000 0x4000>; + reg-names = "gpmi-nand\0bch"; + interrupts = <0x00 0x0e 0x04>; + interrupt-names = "bch"; + clocks = <0x02 0xe2 0x02 0x100>; + clock-names = "gpmi_io\0gpmi_bch_apb"; + dmas = <0x4f 0x00>; + dma-names = "rx-tx"; + status = "disabled"; + }; + + pcie@33800000 { + compatible = "fsl,imx8mq-pcie"; + reg = <0x33800000 0x400000 0x1ff00000 0x80000>; + reg-names = "dbi\0config"; + #address-cells = <0x03>; + #size-cells = <0x02>; + device_type = "pci"; + bus-range = <0x00 0xff>; + ranges = <0x81000000 0x00 0x00 0x1ff80000 0x00 0x10000 0x82000000 0x00 0x18000000 0x18000000 0x00 0x7f00000>; + num-lanes = <0x01>; + num-viewport = <0x04>; + interrupts = <0x00 0x7a 0x04 0x00 0x7f 0x04>; + interrupt-names = "msi\0dma"; + #interrupt-cells = <0x01>; + interrupt-map-mask = <0x00 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x07 0x00 0x7d 0x04 0x00 0x00 0x00 0x02 0x07 0x00 0x7c 0x04 0x00 0x00 0x00 0x03 0x07 0x00 0x7b 0x04 0x00 0x00 0x00 0x04 0x07 0x00 0x7a 0x04>; + fsl,max-link-speed = <0x02>; + power-domains = <0x50>; + resets = <0x28 0x1a 0x28 0x1c 0x28 0x1d>; + reset-names = "pciephy\0apps\0turnoff"; + status = "disabled"; + }; + + pcie@33c00000 { + compatible = "fsl,imx8mq-pcie"; + reg = <0x33c00000 0x400000 0x27f00000 0x80000>; + reg-names = "dbi\0config"; + #address-cells = <0x03>; + #size-cells = <0x02>; + device_type = "pci"; + ranges = <0x81000000 0x00 0x00 0x27f80000 0x00 0x10000 0x82000000 0x00 0x20000000 0x20000000 0x00 0x7f00000>; + num-lanes = <0x01>; + num-viewport = <0x04>; + interrupts = <0x00 0x4a 0x04 0x00 0x50 0x04>; + interrupt-names = "msi\0dma"; + #interrupt-cells = <0x01>; + interrupt-map-mask = <0x00 0x00 0x00 0x07>; + interrupt-map = <0x00 0x00 0x00 0x01 0x07 0x00 0x4d 0x04 0x00 0x00 0x00 0x02 0x07 0x00 0x4c 0x04 0x00 0x00 0x00 0x03 0x07 0x00 0x4b 0x04 0x00 0x00 0x00 0x04 0x07 0x00 0x4a 0x04>; + fsl,max-link-speed = <0x02>; + power-domains = <0x50>; + resets = <0x28 0x22 0x28 0x24 0x28 0x25>; + reset-names = "pciephy\0apps\0turnoff"; + status = "disabled"; + }; + + interrupt-controller@38800000 { + compatible = "arm,gic-v3"; + reg = <0x38800000 0x10000 0x38880000 0xc0000 0x31000000 0x2000 0x31010000 0x2000 0x31020000 0x2000>; + #interrupt-cells = <0x03>; + interrupt-controller; + interrupts = <0x01 0x09 0x04>; + interrupt-parent = <0x07>; + phandle = <0x07>; + }; + + ddr-pmu@3d800000 { + compatible = "fsl,imx8mq-ddr-pmu\0fsl,imx8m-ddr-pmu"; + reg = <0x3d800000 0x400000>; + interrupt-parent = <0x07>; + interrupts = <0x00 0x62 0x04>; + }; + + vpu@38300000 { + compatible = "nxp,imx8mq-hantro"; + reg = <0x38300000 0x200000>; + reg-names = "regs_hantro"; + interrupts = <0x00 0x07 0x04 0x00 0x08 0x04>; + interrupt-names = "irq_hantro_g1\0irq_hantro_g2"; + clocks = <0x02 0xe5 0x02 0xe6 0x02 0xdf>; + clock-names = "clk_hantro_g1\0clk_hantro_g2\0clk_hantro_bus"; + assigned-clocks = <0x02 0x78 0x02 0x79 0x02 0x6a>; + assigned-clock-parents = <0x02 0x16 0x02 0x16 0x02 0x4e>; + assigned-clock-rates = <0x23c34600 0x23c34600 0x2faf0800>; + power-domains = <0x51>; + status = "okay"; + }; + }; + + gpu3d@38000000 { + compatible = "fsl,imx8mq-gpu\0fsl,imx6q-gpu"; + reg = <0x00 0x38000000 0x00 0x40000 0x00 0x40000000 0x00 0xc0000000 0x00 0x00 0x00 0x10000000>; + reg-names = "iobase_3d\0phys_baseaddr\0contiguous_mem"; + interrupts = <0x00 0x03 0x04>; + interrupt-names = "irq_3d"; + clocks = <0x02 0xd7 0x02 0x66 0x02 0x6f 0x02 0x70>; + clock-names = "gpu3d_clk\0gpu3d_shader_clk\0gpu3d_axi_clk\0gpu3d_ahb_clk"; + assigned-clocks = <0x02 0x61 0x02 0x64 0x02 0x6f 0x02 0x70>; + assigned-clock-parents = <0x02 0x11 0x02 0x11 0x02 0x11 0x02 0x11>; + assigned-clock-rates = <0x2faf0800 0x2faf0800 0x2faf0800 0x2faf0800>; + power-domains = <0x4b>; + status = "okay"; + }; + + rpmsg { + compatible = "fsl,imx8mq-rpmsg"; + mbox-names = "tx\0rx\0rxdb"; + mboxes = <0x52 0x00 0x01 0x52 0x01 0x01 0x52 0x03 0x01>; + status = "disabled"; + }; + + chosen { + stdout-path = "/soc@0/bus@30800000/serial@30860000"; + }; + + memory@40000000 { + device_type = "memory"; + reg = <0x00 0x40000000 0x00 0x80000000>; + }; + + reserved-memory { + #address-cells = <0x02>; + #size-cells = <0x02>; + ranges; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x00 0x3c000000>; + alloc-ranges = <0x00 0x40000000 0x00 0x40000000>; + linux,cma-default; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <0x53>; + status = "okay"; + + sys_led { + label = "sys_led"; + gpios = <0x2e 0x05 0x00>; + default-state = "on"; + linux,default-trigger = "heartbeat"; + }; + + usr_led { + label = "usr_led"; + gpios = <0x2e 0x08 0x00>; + default-state = "on"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <0x54>; + + home { + label = "home Button"; + gpios = <0x30 0x07 0x01>; + linux,code = <0x66>; + gpio-key,wakeup; + }; + + back { + label = "back Button"; + gpios = <0x30 0x06 0x01>; + linux,code = <0x19c>; + }; + }; + + gpiomem { + compatible = "maaxboard,maaxboard-gpiomem"; + status = "okay"; + }; + + sound-hdmi { + compatible = "fsl,imx8mq-evk-cdnhdmi\0fsl,imx-audio-cdnhdmi"; + model = "imx-audio-hdmi"; + audio-cpu = <0x55>; + protocol = <0x01>; + hdmi-out; + constraint-rate = <0xac44 0x15888 0x2b110 0x7d00 0xbb80 0x17700 0x2ee00>; + status = "okay"; + }; + + regulators { + compatible = "simple-bus"; + #address-cells = <0x01>; + #size-cells = <0x00>; + + regulator@1 { + compatible = "regulator-fixed"; + reg = <0x01>; + pinctrl-names = "default"; + pinctrl-0 = <0x56>; + regulator-name = "WF_3V3"; + regulator-min-microvolt = <0x325aa0>; + regulator-max-microvolt = <0x325aa0>; + gpio = <0x43 0x14 0x00>; + regulator-always-on; + enable-active-high; + phandle = <0x41>; + }; + }; + + sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <0x57>; + reset-gpios = <0x43 0x13 0x01>; + phandle = <0x42>; + }; + + bt_reset { + compatible = "gpio-reset"; + reset-gpios = <0x23 0x0b 0x01>; + reset-delay-us = <0x3e8>; + reset-post-delay-ms = <0x28>; + #reset-cells = <0x00>; + phandle = <0x37>; + }; + + clock-pmic { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x8000>; + clock-output-names = "pmic_osc"; + phandle = <0x2d>; + }; + + sound-wm8960 { + compatible = "simple-audio-card"; + simple-audio-card,name = "wm8960-sound-audio"; + simple-audio-card,bitclock-master = <0x58>; + simple-audio-card,frame-master = <0x58>; + simple-audio-card,format = "i2s"; + status = "okay"; + simple-audio-card,widgets = "Microphone\0Mic Jack\0Line\0Line In\0Line\0Line Out\0Speaker\0Speaker\0Headphone\0Headphone Jack"; + simple-audio-card,routing = "Headphone Jack\0HP_L\0Headphone Jack\0HP_R\0Speaker\0SPK_LP\0Speaker\0SPK_LN\0Speaker\0SPK_RP\0Speaker\0SPK_RN\0LINPUT1\0Mic Jack\0LINPUT3\0Mic Jack\0RINPUT1\0Mic Jack\0RINPUT2\0Mic Jack\0Mic Jack\0MICB"; + + simple-audio-card,cpu { + sound-dai = <0x59>; + }; + + simple-audio-card,codec { + sound-dai = <0x5a>; + clocks = <0x33>; + phandle = <0x58>; + }; + }; + + wm8960_mclk { + compatible = "fixed-clock"; + #clock-cells = <0x00>; + clock-frequency = <0x16e3600>; + clock-output-names = "wm8960-mclk"; + phandle = <0x33>; + }; +}; From 06bd8b66a12b3c8399425b5a12cdaecf6c48a81b Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Mon, 4 Nov 2024 16:33:08 +1100 Subject: [PATCH 04/11] Clk: fix style Signed-off-by: Terry Bai --- drivers/clk/imx/clk-imx.c | 17 +- drivers/clk/imx/clk-imx8mq.c | 3406 ++++++++++++++++++++--------- drivers/clk/imx/clk.c | 78 +- drivers/clk/imx/include/clk-imx.h | 28 +- 4 files changed, 2454 insertions(+), 1075 deletions(-) diff --git a/drivers/clk/imx/clk-imx.c b/drivers/clk/imx/clk-imx.c index 09d69acfd..244a6ab33 100644 --- a/drivers/clk/imx/clk-imx.c +++ b/drivers/clk/imx/clk-imx.c @@ -35,8 +35,7 @@ const struct clk_ops clk_gate2_ops = { .is_enabled = clk_gate2_is_enabled, }; -static unsigned long clk_pll_recalc_rate(const struct clk *clk, - unsigned long prate) +static unsigned long clk_pll_recalc_rate(const struct clk *clk, unsigned long prate) { /* TODO: This function is derived from Linux codebase, but seems wrong * according to the datasheet as PLL_REFCLK_DIV_VAL[5:10] is never used. */ @@ -46,7 +45,7 @@ static unsigned long clk_pll_recalc_rate(const struct clk *clk, /* Output Divider value is (n + 1) * 2 */ uint32_t output_div_val = regmap_read_bits(clk->base, data->offset, 0, 5); - output_div_val = (output_div_val + 1 ) * 2; + output_div_val = (output_div_val + 1) * 2; /* Valid Frac Divider value is 1 to 2^24 */ uint32_t frac_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 7, 24); @@ -76,8 +75,7 @@ const struct clk_ops clk_frac_pll_ops = { /* .set_rate = clk_pll_set_rate, */ }; -static unsigned long clk_sscg_pll_recalc_rate(const struct clk *clk, - unsigned long prate) +static unsigned long clk_sscg_pll_recalc_rate(const struct clk *clk, unsigned long prate) { struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); uint64_t temp_rate = prate; @@ -136,8 +134,7 @@ const struct clk_ops clk_sscg_pll_ops = { /* .determine_rate = clk_sscg_pll_determine_rate, */ }; -static unsigned long imx8m_clk_core_slice_recalc_rate(const struct clk *clk, - unsigned long prate) +static unsigned long imx8m_clk_core_slice_recalc_rate(const struct clk *clk, unsigned long prate) { struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); @@ -182,8 +179,7 @@ const struct clk_ops clk_core_slice_ops = { .set_parent = imx8m_clk_core_slice_set_parent, }; -static unsigned long imx8m_clk_common_slice_recalc_rate(const struct clk *clk, - unsigned long prate) +static unsigned long imx8m_clk_common_slice_recalc_rate(const struct clk *clk, unsigned long prate) { struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); @@ -232,8 +228,7 @@ const struct clk_ops clk_common_slice_ops = { .set_parent = imx8m_clk_common_slice_set_parent, }; -static unsigned long imx8m_clk_bus_slice_recalc_rate(const struct clk *clk, - unsigned long prate) +static unsigned long imx8m_clk_bus_slice_recalc_rate(const struct clk *clk, unsigned long prate) { struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 059c51b43..bd78cf595 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -13,985 +13,2367 @@ #include #include - static struct clk_parent_data pll_ref_sels[] = { - { .name = "osc_25m", }, - { .name = "osc_27m", }, - { .name = "hdmi_phy_27m", }, - { .name = "dummy", }, + { + .name = "osc_25m", + }, + { + .name = "osc_27m", + }, + { + .name = "hdmi_phy_27m", + }, + { + .name = "dummy", + }, }; static struct clk_parent_data arm_pll_bypass_sels[] = { - { .name = "arm_pll", }, - { .name = "arm_pll_ref_sel", }, + { + .name = "arm_pll", + }, + { + .name = "arm_pll_ref_sel", + }, }; static struct clk_parent_data gpu_pll_bypass_sels[] = { - { .name = "gpu_pll", }, - { .name = "gpu_pll_ref_sel", }, + { + .name = "gpu_pll", + }, + { + .name = "gpu_pll_ref_sel", + }, }; static struct clk_parent_data vpu_pll_bypass_sels[] = { - { .name = "vpu_pll", }, - { .name = "vpu_pll_ref_sel", }, + { + .name = "vpu_pll", + }, + { + .name = "vpu_pll_ref_sel", + }, }; static struct clk_parent_data audio_pll1_bypass_sels[] = { - { .name = "audio_pll1", }, - { .name = "audio_pll1_ref_sel", }, + { + .name = "audio_pll1", + }, + { + .name = "audio_pll1_ref_sel", + }, }; static struct clk_parent_data audio_pll2_bypass_sels[] = { - { .name = "audio_pll2", }, - { .name = "audio_pll2_ref_sel", }, + { + .name = "audio_pll2", + }, + { + .name = "audio_pll2_ref_sel", + }, }; static struct clk_parent_data video_pll1_bypass_sels[] = { - { .name = "video_pll1", }, - { .name = "video_pll1_ref_sel", }, + { + .name = "video_pll1", + }, + { + .name = "video_pll1_ref_sel", + }, }; static struct clk_parent_data sys3_pll_out_sels[] = { - { .name = "sys3_pll1_ref_sel", }, + { + .name = "sys3_pll1_ref_sel", + }, }; static struct clk_parent_data dram_pll_out_sels[] = { - { .name = "dram_pll1_ref_sel", }, + { + .name = "dram_pll1_ref_sel", + }, }; static struct clk_parent_data video2_pll_out_sels[] = { - { .name = "video2_pll1_ref_sel", }, + { + .name = "video2_pll1_ref_sel", + }, }; static struct clk_parent_data imx8mq_a53_sels[] = { - { .name = "osc_25m", }, - { .name = "arm_pll_out", }, - { .name = "sys2_pll_500m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys1_pll_400m", }, - { .name = "audio_pll1_out", }, - { .name = "sys3_pll_out", }, + { + .name = "osc_25m", + }, + { + .name = "arm_pll_out", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "sys3_pll_out", + }, }; static struct clk_parent_data imx8mq_a53_core_sels[] = { - { .name = "arm_a53_div", }, - { .name = "arm_pll_out", }, + { + .name = "arm_a53_div", + }, + { + .name = "arm_pll_out", + }, }; static struct clk_parent_data imx8mq_arm_m4_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys2_pll_250m", }, - { .name = "sys1_pll_266m", }, - { .name = "sys1_pll_800m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "sys3_pll_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys3_pll_out", + }, }; static struct clk_parent_data imx8mq_vpu_sels[] = { - { .name = "osc_25m", }, - { .name = "arm_pll_out", }, - { .name = "sys2_pll_500m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys1_pll_400m", }, - { .name = "audio_pll1_out", }, - { .name = "vpu_pll_out", }, + { + .name = "osc_25m", + }, + { + .name = "arm_pll_out", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "vpu_pll_out", + }, }; static struct clk_parent_data imx8mq_gpu_core_sels[] = { - { .name = "osc_25m", }, - { .name = "gpu_pll_out", }, - { .name = "sys1_pll_800m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_1000m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "gpu_pll_out", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_gpu_shader_sels[] = { - { .name = "osc_25m", }, - { .name = "gpu_pll_out", }, - { .name = "sys1_pll_800m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_1000m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "gpu_pll_out", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_main_axi_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_333m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_250m", }, - { .name = "sys2_pll_1000m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "sys1_pll_100m", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_333m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys1_pll_100m", + }, }; static struct clk_parent_data imx8mq_enet_axi_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_266m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_250m", }, - { .name = "sys2_pll_200m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "sys3_pll_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys3_pll_out", + }, }; static struct clk_parent_data imx8mq_nand_usdhc_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_266m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_133m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_250m", }, - { .name = "audio_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "audio_pll1_out", + }, }; static struct clk_parent_data imx8mq_vpu_bus_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_800m", }, - { .name = "vpu_pll_out", }, - { .name = "audio_pll2_out", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_100m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "vpu_pll_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_100m", + }, }; static struct clk_parent_data imx8mq_disp_axi_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_125m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys3_pll_out", }, - { .name = "sys1_pll_400m", }, - { .name = "audio_pll2_out", }, - { .name = "clk_ext1", }, - { .name = "clk_ext4", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "clk_ext1", + }, + { + .name = "clk_ext4", + }, }; static struct clk_parent_data imx8mq_disp_apb_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_125m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys3_pll_out", }, - { .name = "sys1_pll_40m", }, - { .name = "audio_pll2_out", }, - { .name = "clk_ext1", }, - { .name = "clk_ext3", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "clk_ext1", + }, + { + .name = "clk_ext3", + }, }; static struct clk_parent_data imx8mq_disp_rtrm_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_400m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, }; static struct clk_parent_data imx8mq_usb_bus_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_500m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys2_pll_200m", }, - { .name = "clk_ext2", }, - { .name = "clk_ext4", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext4", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_gpu_axi_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_800m", }, - { .name = "gpu_pll_out", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_1000m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "gpu_pll_out", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_gpu_ahb_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_800m", }, - { .name = "gpu_pll_out", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_1000m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "gpu_pll_out", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_noc_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys2_pll_500m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_noc_apb_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_400m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_333m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_800m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_333m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_ahb_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_133m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys1_pll_400m", }, - { .name = "sys2_pll_125m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_audio_ahb_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_500m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys2_pll_166m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys2_pll_166m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_dsi_ahb_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_80m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext3", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext3", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_dram_alt_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys1_pll_100m", }, - { .name = "sys2_pll_500m", }, - { .name = "sys2_pll_250m", }, - { .name = "sys1_pll_400m", }, - { .name = "audio_pll1_out", }, - { .name = "sys1_pll_266m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys1_pll_100m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "sys1_pll_266m", + }, }; static struct clk_parent_data imx8mq_dram_apb_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_250m", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_vpu_g1_sels[] = { - { .name = "osc_25m", }, - { .name = "vpu_pll_out", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys1_pll_100m", }, - { .name = "sys2_pll_125m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "vpu_pll_out", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys1_pll_100m", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll1_out", + }, }; static struct clk_parent_data imx8mq_vpu_g2_sels[] = { - { .name = "osc_25m", }, - { .name = "vpu_pll_out", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys1_pll_100m", }, - { .name = "sys2_pll_125m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "vpu_pll_out", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys1_pll_100m", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll1_out", + }, }; static struct clk_parent_data imx8mq_disp_dtrc_sels[] = { - { .name = "osc_25m", }, - { .name = "vpu_pll_out", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "vpu_pll_out", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_disp_dc8000_sels[] = { - { .name = "osc_25m", }, - { .name = "vpu_pll_out", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "vpu_pll_out", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_pcie1_ctrl_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_250m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_266m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_500m", }, - { .name = "sys2_pll_333m", }, - { .name = "sys3_pll_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys2_pll_333m", + }, + { + .name = "sys3_pll_out", + }, }; static struct clk_parent_data imx8mq_pcie1_phy_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys2_pll_500m", }, - { .name = "clk_ext1", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, - { .name = "clk_ext4", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "clk_ext1", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, + { + .name = "clk_ext4", + }, }; static struct clk_parent_data imx8mq_pcie1_aux_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys2_pll_50m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_80m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys1_pll_200m", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys2_pll_50m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys1_pll_200m", + }, }; static struct clk_parent_data imx8mq_dc_pixel_sels[] = { - { .name = "osc_25m", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "audio_pll1_out", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext4", }, + { + .name = "osc_25m", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext4", + }, }; static struct clk_parent_data imx8mq_lcdif_pixel_sels[] = { - { .name = "osc_25m", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "audio_pll1_out", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext4", }, + { + .name = "osc_25m", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext4", + }, }; static struct clk_parent_data imx8mq_sai1_sels[] = { - { .name = "osc_25m", }, - { .name = "audio_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, - { .name = "sys1_pll_133m", }, - { .name = "osc_27m", }, - { .name = "clk_ext1", }, - { .name = "clk_ext2", }, + { + .name = "osc_25m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "osc_27m", + }, + { + .name = "clk_ext1", + }, + { + .name = "clk_ext2", + }, }; static struct clk_parent_data imx8mq_sai2_sels[] = { - { .name = "osc_25m", }, - { .name = "audio_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, - { .name = "sys1_pll_133m", }, - { .name = "osc_27m", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, + { + .name = "osc_25m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "osc_27m", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, }; static struct clk_parent_data imx8mq_sai3_sels[] = { - { .name = "osc_25m", }, - { .name = "audio_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, - { .name = "sys1_pll_133m", }, - { .name = "osc_27m", }, - { .name = "clk_ext3", }, - { .name = "clk_ext4", }, + { + .name = "osc_25m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "osc_27m", + }, + { + .name = "clk_ext3", + }, + { + .name = "clk_ext4", + }, }; static struct clk_parent_data imx8mq_sai4_sels[] = { - { .name = "osc_25m", }, - { .name = "audio_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, - { .name = "sys1_pll_133m", }, - { .name = "osc_27m", }, - { .name = "clk_ext1", }, - { .name = "clk_ext2", }, + { + .name = "osc_25m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "osc_27m", + }, + { + .name = "clk_ext1", + }, + { + .name = "clk_ext2", + }, }; static struct clk_parent_data imx8mq_sai5_sels[] = { - { .name = "osc_25m", }, - { .name = "audio_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, - { .name = "sys1_pll_133m", }, - { .name = "osc_27m", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, + { + .name = "osc_25m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "osc_27m", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, }; static struct clk_parent_data imx8mq_sai6_sels[] = { - { .name = "osc_25m", }, - { .name = "audio_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, - { .name = "sys1_pll_133m", }, - { .name = "osc_27m", }, - { .name = "clk_ext3", }, - { .name = "clk_ext4", }, + { + .name = "osc_25m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "osc_27m", + }, + { + .name = "clk_ext3", + }, + { + .name = "clk_ext4", + }, }; static struct clk_parent_data imx8mq_spdif1_sels[] = { - { .name = "osc_25m", }, - { .name = "audio_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, - { .name = "sys1_pll_133m", }, - { .name = "osc_27m", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, + { + .name = "osc_25m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "osc_27m", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, }; static struct clk_parent_data imx8mq_spdif2_sels[] = { - { .name = "osc_25m", }, - { .name = "audio_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, - { .name = "sys1_pll_133m", }, - { .name = "osc_27m", }, - { .name = "clk_ext3", }, - { .name = "clk_ext4", }, + { + .name = "osc_25m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "osc_27m", + }, + { + .name = "clk_ext3", + }, + { + .name = "clk_ext4", + }, }; static struct clk_parent_data imx8mq_enet_ref_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_125m", }, - { .name = "sys2_pll_500m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_160m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "clk_ext4", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "clk_ext4", + }, }; static struct clk_parent_data imx8mq_enet_timer_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "audio_pll1_out", }, - { .name = "clk_ext1", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, - { .name = "clk_ext4", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "clk_ext1", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, + { + .name = "clk_ext4", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_enet_phy_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_50m", }, - { .name = "sys2_pll_125m", }, - { .name = "sys2_pll_500m", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_50m", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_nand_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_500m", }, - { .name = "audio_pll1_out", }, - { .name = "sys1_pll_400m", }, - { .name = "audio_pll2_out", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_250m", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_qspi_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_400m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_500m", }, - { .name = "audio_pll2_out", }, - { .name = "sys1_pll_266m", }, - { .name = "sys3_pll_out", }, - { .name = "sys1_pll_100m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys1_pll_100m", + }, }; static struct clk_parent_data imx8mq_usdhc1_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_400m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_500m", }, - { .name = "sys3_pll_out", }, - { .name = "sys1_pll_266m", }, - { .name = "audio_pll2_out", }, - { .name = "sys1_pll_100m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "sys1_pll_100m", + }, }; static struct clk_parent_data imx8mq_usdhc2_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_400m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_500m", }, - { .name = "sys3_pll_out", }, - { .name = "sys1_pll_266m", }, - { .name = "audio_pll2_out", }, - { .name = "sys1_pll_100m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "sys1_pll_100m", + }, }; static struct clk_parent_data imx8mq_i2c1_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys2_pll_50m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "sys1_pll_133m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys2_pll_50m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "sys1_pll_133m", + }, }; static struct clk_parent_data imx8mq_i2c2_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys2_pll_50m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "sys1_pll_133m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys2_pll_50m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "sys1_pll_133m", + }, }; static struct clk_parent_data imx8mq_i2c3_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys2_pll_50m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "sys1_pll_133m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys2_pll_50m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "sys1_pll_133m", + }, }; static struct clk_parent_data imx8mq_i2c4_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys2_pll_50m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "audio_pll2_out", }, - { .name = "sys1_pll_133m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys2_pll_50m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "sys1_pll_133m", + }, }; static struct clk_parent_data imx8mq_uart1_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_80m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext2", }, - { .name = "clk_ext4", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext4", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_uart2_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_80m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_uart3_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_80m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext2", }, - { .name = "clk_ext4", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext4", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_uart4_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_80m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_usb_core_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_100m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys2_pll_200m", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_100m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_usb_phy_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_100m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys2_pll_200m", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_100m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_gic_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys2_pll_200m", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_ecspi1_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_250m", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_ecspi2_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_250m", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_pwm1_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext1", }, - { .name = "sys1_pll_80m", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext1", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_pwm2_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext1", }, - { .name = "sys1_pll_80m", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext1", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_pwm3_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext2", }, - { .name = "sys1_pll_80m", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext2", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_pwm4_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext2", }, - { .name = "sys1_pll_80m", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext2", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_gpt1_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_400m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys1_pll_80m", }, - { .name = "audio_pll1_out", }, - { .name = "clk_ext1", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "clk_ext1", + }, }; static struct clk_parent_data imx8mq_wdog_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_133m", }, - { .name = "sys1_pll_160m", }, - { .name = "vpu_pll_out", }, - { .name = "sys2_pll_125m", }, - { .name = "sys3_pll_out", }, - { .name = "sys1_pll_80m", }, - { .name = "sys2_pll_166m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_133m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "vpu_pll_out", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys2_pll_166m", + }, }; static struct clk_parent_data imx8mq_wrclk_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_40m", }, - { .name = "vpu_pll_out", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_266m", }, - { .name = "sys2_pll_500m", }, - { .name = "sys1_pll_100m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "vpu_pll_out", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys1_pll_100m", + }, }; static struct clk_parent_data imx8mq_dsi_core_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_266m", }, - { .name = "sys2_pll_250m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_dsi_phy_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_125m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "clk_ext2", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "clk_ext2", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_dsi_dbi_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_266m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_dsi_esc_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_80m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext3", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext3", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_csi1_core_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_266m", }, - { .name = "sys2_pll_250m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_csi1_phy_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_125m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "clk_ext2", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "clk_ext2", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_csi1_esc_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_80m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext3", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext3", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_csi2_core_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_266m", }, - { .name = "sys2_pll_250m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_csi2_phy_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_125m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "clk_ext2", }, - { .name = "audio_pll2_out", }, - { .name = "video_pll1_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_125m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "clk_ext2", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "video_pll1_out", + }, }; static struct clk_parent_data imx8mq_csi2_esc_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_80m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_1000m", }, - { .name = "sys3_pll_out", }, - { .name = "clk_ext3", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_1000m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "clk_ext3", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_pcie2_ctrl_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_250m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_266m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys2_pll_500m", }, - { .name = "sys2_pll_333m", }, - { .name = "sys3_pll_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_266m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "sys2_pll_333m", + }, + { + .name = "sys3_pll_out", + }, }; static struct clk_parent_data imx8mq_pcie2_phy_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_100m", }, - { .name = "sys2_pll_500m", }, - { .name = "clk_ext1", }, - { .name = "clk_ext2", }, - { .name = "clk_ext3", }, - { .name = "clk_ext4", }, - { .name = "sys1_pll_400m", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "clk_ext1", + }, + { + .name = "clk_ext2", + }, + { + .name = "clk_ext3", + }, + { + .name = "clk_ext4", + }, + { + .name = "sys1_pll_400m", + }, }; static struct clk_parent_data imx8mq_pcie2_aux_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys2_pll_50m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_100m", }, - { .name = "sys1_pll_80m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys1_pll_200m", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys2_pll_50m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_100m", + }, + { + .name = "sys1_pll_80m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys1_pll_200m", + }, }; static struct clk_parent_data imx8mq_ecspi3_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_40m", }, - { .name = "sys1_pll_160m", }, - { .name = "sys1_pll_800m", }, - { .name = "sys3_pll_out", }, - { .name = "sys2_pll_250m", }, - { .name = "audio_pll2_out", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_40m", + }, + { + .name = "sys1_pll_160m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "sys2_pll_250m", + }, + { + .name = "audio_pll2_out", + }, }; static struct clk_parent_data imx8mq_dram_core_sels[] = { - { .name = "dram_pll_out", }, - { .name = "dram_alt_root", }, + { + .name = "dram_pll_out", + }, + { + .name = "dram_alt_root", + }, }; static struct clk_parent_data imx8mq_clko1_sels[] = { - { .name = "osc_25m", }, - { .name = "sys1_pll_800m", }, - { .name = "osc_27m", }, - { .name = "sys1_pll_200m", }, - { .name = "audio_pll2_out", }, - { .name = "sys2_pll_500m", }, - { .name = "vpu_pll_out", }, - { .name = "sys1_pll_80m", }, + { + .name = "osc_25m", + }, + { + .name = "sys1_pll_800m", + }, + { + .name = "osc_27m", + }, + { + .name = "sys1_pll_200m", + }, + { + .name = "audio_pll2_out", + }, + { + .name = "sys2_pll_500m", + }, + { + .name = "vpu_pll_out", + }, + { + .name = "sys1_pll_80m", + }, }; static struct clk_parent_data imx8mq_clko2_sels[] = { - { .name = "osc_25m", }, - { .name = "sys2_pll_200m", }, - { .name = "sys1_pll_400m", }, - { .name = "sys2_pll_166m", }, - { .name = "sys3_pll_out", }, - { .name = "audio_pll1_out", }, - { .name = "video_pll1_out", }, - { .name = "ckil", }, + { + .name = "osc_25m", + }, + { + .name = "sys2_pll_200m", + }, + { + .name = "sys1_pll_400m", + }, + { + .name = "sys2_pll_166m", + }, + { + .name = "sys3_pll_out", + }, + { + .name = "audio_pll1_out", + }, + { + .name = "video_pll1_out", + }, + { + .name = "ckil", + }, }; static struct clk_parent_data pllout_monitor_sels[] = { - { .name = "osc_25m", }, - { .name = "osc_27m", }, - { .name = "dummy", }, - { .name = "dummy", }, - { .name = "ckil", }, - { .name = "audio_pll1_out_monitor", }, - { .name = "audio_pll2_out_monitor", }, - { .name = "video_pll1_out_monitor", }, - { .name = "gpu_pll_out_monitor", }, - { .name = "vpu_pll_out_monitor", }, - { .name = "arm_pll_out_monitor", }, - { .name = "sys_pll1_out_monitor", }, - { .name = "sys_pll2_out_monitor", }, - { .name = "sys_pll3_out_monitor", }, - { .name = "dram_pll_out_monitor", }, - { .name = "video_pll2_out_monitor", }, + { + .name = "osc_25m", + }, + { + .name = "osc_27m", + }, + { + .name = "dummy", + }, + { + .name = "dummy", + }, + { + .name = "ckil", + }, + { + .name = "audio_pll1_out_monitor", + }, + { + .name = "audio_pll2_out_monitor", + }, + { + .name = "video_pll1_out_monitor", + }, + { + .name = "gpu_pll_out_monitor", + }, + { + .name = "vpu_pll_out_monitor", + }, + { + .name = "arm_pll_out_monitor", + }, + { + .name = "sys_pll1_out_monitor", + }, + { + .name = "sys_pll2_out_monitor", + }, + { + .name = "sys_pll3_out_monitor", + }, + { + .name = "dram_pll_out_monitor", + }, + { + .name = "video_pll2_out_monitor", + }, }; - static IMX_CLK_SOURCE(dummy, 0); static IMX_CLK_SOURCE(ckil, 0x8000); static IMX_CLK_SOURCE(osc_25m, 0x17d7840); @@ -1026,12 +2408,16 @@ static IMX_CLK_FRAC_PLL(audio_pll2, { &audio_pll2_ref_div }, CCM_ANALOG_BASE, 0x static IMX_CLK_FRAC_PLL(video_pll1, { &video_pll1_ref_div }, CCM_ANALOG_BASE, 0x10); /* PLL bypass out */ -static IMX_CLK_MUX_FLAGS(arm_pll_bypass, CCM_ANALOG_BASE, 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); +static IMX_CLK_MUX_FLAGS(arm_pll_bypass, CCM_ANALOG_BASE, 0x28, 14, 1, arm_pll_bypass_sels, + ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); static IMX_CLK_MUX(gpu_pll_bypass, CCM_ANALOG_BASE, 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels)); static IMX_CLK_MUX(vpu_pll_bypass, CCM_ANALOG_BASE, 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels)); -static IMX_CLK_MUX(audio_pll1_bypass, CCM_ANALOG_BASE, 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels)); -static IMX_CLK_MUX(audio_pll2_bypass, CCM_ANALOG_BASE, 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels)); -static IMX_CLK_MUX(video_pll1_bypass, CCM_ANALOG_BASE, 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels)); +static IMX_CLK_MUX(audio_pll1_bypass, CCM_ANALOG_BASE, 0x0, 14, 1, audio_pll1_bypass_sels, + ARRAY_SIZE(audio_pll1_bypass_sels)); +static IMX_CLK_MUX(audio_pll2_bypass, CCM_ANALOG_BASE, 0x8, 14, 1, audio_pll2_bypass_sels, + ARRAY_SIZE(audio_pll2_bypass_sels)); +static IMX_CLK_MUX(video_pll1_bypass, CCM_ANALOG_BASE, 0x10, 14, 1, video_pll1_bypass_sels, + ARRAY_SIZE(video_pll1_bypass_sels)); /* PLL OUT GATE */ static IMX_CLK_GATE(arm_pll_out, { &arm_pll_bypass }, CCM_ANALOG_BASE, 0x28, 21); @@ -1043,9 +2429,12 @@ static IMX_CLK_GATE(video_pll1_out, { &video_pll1_bypass }, CCM_ANALOG_BASE, 0x1 static IMX_CLK_FIXED(sys1_pll_out, 800000000); static IMX_CLK_FIXED(sys2_pll_out, 1000000000); -static IMX_CLK_SSCG_PLL(sys3_pll_out, sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x48, CLK_IS_CRITICAL); -static IMX_CLK_SSCG_PLL(dram_pll_out, dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x60, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); -static IMX_CLK_SSCG_PLL(video2_pll_out, video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x54, 0); +static IMX_CLK_SSCG_PLL(sys3_pll_out, sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x48, + CLK_IS_CRITICAL); +static IMX_CLK_SSCG_PLL(dram_pll_out, dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x60, + CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); +static IMX_CLK_SSCG_PLL(video2_pll_out, video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, + 0x54, 0); /* SYS PLL1 fixed output */ static IMX_CLK_FIXED_FACTOR(sys1_pll_40m, { &sys1_pll_out }, 1, 20); @@ -1080,7 +2469,8 @@ static IMX_CLK_DIV(sys_pll2_out_monitor, { &sys2_pll_out }, CCM_ANALOG_BASE, 0x7 static IMX_CLK_DIV(sys_pll3_out_monitor, { &sys3_pll_out }, CCM_ANALOG_BASE, 0x7c, 8, 3); static IMX_CLK_DIV(dram_pll_out_monitor, { &dram_pll_out }, CCM_ANALOG_BASE, 0x7c, 12, 3); static IMX_CLK_DIV(video_pll2_out_monitor, { &video2_pll_out }, CCM_ANALOG_BASE, 0x7c, 16, 3); -static IMX_CLK_MUX(pllout_monitor_sel, CCM_ANALOG_BASE, 0x74, 0, 4, pllout_monitor_sels, ARRAY_SIZE(pllout_monitor_sels)); +static IMX_CLK_MUX(pllout_monitor_sel, CCM_ANALOG_BASE, 0x74, 0, 4, pllout_monitor_sels, + ARRAY_SIZE(pllout_monitor_sels)); static IMX_CLK_GATE(pllout_monitor_clk2, { &pllout_monitor_sel }, CCM_ANALOG_BASE, 0x74, 4); /* CORE */ @@ -1122,73 +2512,74 @@ static IMX_CLK_DIV2(ipg_audio_root, { &audio_ahb }, CCM_BASE, 0x9180, 0, 1); * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE * as div value should always be read from hardware */ -static IMX_CLK_MUX2_FLAGS(dram_core_clk, CCM_BASE, 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL); +static IMX_CLK_MUX2_FLAGS(dram_core_clk, CCM_BASE, 0x9800, 24, 1, imx8mq_dram_core_sels, + ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL); static IMX_CLK_COMPOSITE_FW_MANAGED(dram_alt, imx8mq_dram_alt_sels, CCM_BASE, 0xa000); static IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(dram_apb, imx8mq_dram_apb_sels, CCM_BASE, 0xa080); /* IP */ -static IMX_CLK_COMPOSITE(vpu_g1, imx8mq_vpu_g1_sels, CCM_BASE, 0xa100); -static IMX_CLK_COMPOSITE(vpu_g2, imx8mq_vpu_g2_sels, CCM_BASE, 0xa180); -static IMX_CLK_COMPOSITE(disp_dtrc, imx8mq_disp_dtrc_sels, CCM_BASE, 0xa200); -static IMX_CLK_COMPOSITE(disp_dc8000, imx8mq_disp_dc8000_sels, CCM_BASE, 0xa280); -static IMX_CLK_COMPOSITE(pcie1_ctrl, imx8mq_pcie1_ctrl_sels, CCM_BASE, 0xa300); -static IMX_CLK_COMPOSITE(pcie1_phy, imx8mq_pcie1_phy_sels, CCM_BASE, 0xa380); -static IMX_CLK_COMPOSITE(pcie1_aux, imx8mq_pcie1_aux_sels, CCM_BASE, 0xa400); -static IMX_CLK_COMPOSITE(dc_pixel, imx8mq_dc_pixel_sels, CCM_BASE, 0xa480); -static IMX_CLK_COMPOSITE(lcdif_pixel, imx8mq_lcdif_pixel_sels, CCM_BASE, 0xa500); -static IMX_CLK_COMPOSITE(sai1, imx8mq_sai1_sels, CCM_BASE, 0xa580); -static IMX_CLK_COMPOSITE(sai2, imx8mq_sai2_sels, CCM_BASE, 0xa600); -static IMX_CLK_COMPOSITE(sai3, imx8mq_sai3_sels, CCM_BASE, 0xa680); -static IMX_CLK_COMPOSITE(sai4, imx8mq_sai4_sels, CCM_BASE, 0xa700); -static IMX_CLK_COMPOSITE(sai5, imx8mq_sai5_sels, CCM_BASE, 0xa780); -static IMX_CLK_COMPOSITE(sai6, imx8mq_sai6_sels, CCM_BASE, 0xa800); -static IMX_CLK_COMPOSITE(spdif1, imx8mq_spdif1_sels, CCM_BASE, 0xa880); -static IMX_CLK_COMPOSITE(spdif2, imx8mq_spdif2_sels, CCM_BASE, 0xa900); -static IMX_CLK_COMPOSITE(enet_ref, imx8mq_enet_ref_sels, CCM_BASE, 0xa980); -static IMX_CLK_COMPOSITE(enet_timer, imx8mq_enet_timer_sels, CCM_BASE, 0xaa00); -static IMX_CLK_COMPOSITE(enet_phy, imx8mq_enet_phy_sels, CCM_BASE, 0xaa80); -static IMX_CLK_COMPOSITE(nand, imx8mq_nand_sels, CCM_BASE, 0xab00); -static IMX_CLK_COMPOSITE(qspi, imx8mq_qspi_sels, CCM_BASE, 0xab80); -static IMX_CLK_COMPOSITE(usdhc1, imx8mq_usdhc1_sels, CCM_BASE, 0xac00); -static IMX_CLK_COMPOSITE(usdhc2, imx8mq_usdhc2_sels, CCM_BASE, 0xac80); -static IMX_CLK_COMPOSITE(i2c1, imx8mq_i2c1_sels, CCM_BASE, 0xad00); -static IMX_CLK_COMPOSITE(i2c2, imx8mq_i2c2_sels, CCM_BASE, 0xad80); -static IMX_CLK_COMPOSITE(i2c3, imx8mq_i2c3_sels, CCM_BASE, 0xae00); -static IMX_CLK_COMPOSITE(i2c4, imx8mq_i2c4_sels, CCM_BASE, 0xae80); -static IMX_CLK_COMPOSITE(uart1, imx8mq_uart1_sels, CCM_BASE, 0xaf00); -static IMX_CLK_COMPOSITE(uart2, imx8mq_uart2_sels, CCM_BASE, 0xaf80); -static IMX_CLK_COMPOSITE(uart3, imx8mq_uart3_sels, CCM_BASE, 0xb000); -static IMX_CLK_COMPOSITE(uart4, imx8mq_uart4_sels, CCM_BASE, 0xb080); -static IMX_CLK_COMPOSITE(usb_core_ref, imx8mq_usb_core_sels, CCM_BASE, 0xb100); -static IMX_CLK_COMPOSITE(usb_phy_ref, imx8mq_usb_phy_sels, CCM_BASE, 0xb180); -static IMX_CLK_COMPOSITE(gic, imx8mq_gic_sels, CCM_BASE, 0xb200); -static IMX_CLK_COMPOSITE(ecspi1, imx8mq_ecspi1_sels, CCM_BASE, 0xb280); -static IMX_CLK_COMPOSITE(ecspi2, imx8mq_ecspi2_sels, CCM_BASE, 0xb300); -static IMX_CLK_COMPOSITE(pwm1, imx8mq_pwm1_sels, CCM_BASE, 0xb380); -static IMX_CLK_COMPOSITE(pwm2, imx8mq_pwm2_sels, CCM_BASE, 0xb400); -static IMX_CLK_COMPOSITE(pwm3, imx8mq_pwm3_sels, CCM_BASE, 0xb480); -static IMX_CLK_COMPOSITE(pwm4, imx8mq_pwm4_sels, CCM_BASE, 0xb500); -static IMX_CLK_COMPOSITE(gpt1, imx8mq_gpt1_sels, CCM_BASE, 0xb580); -static IMX_CLK_COMPOSITE(wdog, imx8mq_wdog_sels, CCM_BASE, 0xb900); -static IMX_CLK_COMPOSITE(wrclk, imx8mq_wrclk_sels, CCM_BASE, 0xb980); -static IMX_CLK_COMPOSITE(clko1, imx8mq_clko1_sels, CCM_BASE, 0xba00); -static IMX_CLK_COMPOSITE(clko2, imx8mq_clko2_sels, CCM_BASE, 0xba80); -static IMX_CLK_COMPOSITE(dsi_core, imx8mq_dsi_core_sels, CCM_BASE, 0xbb00); -static IMX_CLK_COMPOSITE(dsi_phy_ref, imx8mq_dsi_phy_sels, CCM_BASE, 0xbb80); -static IMX_CLK_COMPOSITE(dsi_dbi, imx8mq_dsi_dbi_sels, CCM_BASE, 0xbc00); -static IMX_CLK_COMPOSITE(dsi_esc, imx8mq_dsi_esc_sels, CCM_BASE, 0xbc80); -static IMX_CLK_COMPOSITE(dsi_ahb, imx8mq_dsi_ahb_sels, CCM_BASE, 0x9200); -static IMX_CLK_DIV2(dsi_ipg_div, { &dsi_ahb }, CCM_BASE, 0x9280, 0, 6); -static IMX_CLK_COMPOSITE(csi1_core, imx8mq_csi1_core_sels, CCM_BASE, 0xbd00); -static IMX_CLK_COMPOSITE(csi1_phy_ref, imx8mq_csi1_phy_sels, CCM_BASE, 0xbd80); -static IMX_CLK_COMPOSITE(csi1_esc, imx8mq_csi1_esc_sels, CCM_BASE, 0xbe00); -static IMX_CLK_COMPOSITE(csi2_core, imx8mq_csi2_core_sels, CCM_BASE, 0xbe80); -static IMX_CLK_COMPOSITE(csi2_phy_ref, imx8mq_csi2_phy_sels, CCM_BASE, 0xbf00); -static IMX_CLK_COMPOSITE(csi2_esc, imx8mq_csi2_esc_sels, CCM_BASE, 0xbf80); -static IMX_CLK_COMPOSITE(pcie2_ctrl, imx8mq_pcie2_ctrl_sels, CCM_BASE, 0xc000); -static IMX_CLK_COMPOSITE(pcie2_phy, imx8mq_pcie2_phy_sels, CCM_BASE, 0xc080); -static IMX_CLK_COMPOSITE(pcie2_aux, imx8mq_pcie2_aux_sels, CCM_BASE, 0xc100); -static IMX_CLK_COMPOSITE(ecspi3, imx8mq_ecspi3_sels, CCM_BASE, 0xc180); +static IMX_CLK_COMPOSITE(vpu_g1, imx8mq_vpu_g1_sels, CCM_BASE, 0xa100); +static IMX_CLK_COMPOSITE(vpu_g2, imx8mq_vpu_g2_sels, CCM_BASE, 0xa180); +static IMX_CLK_COMPOSITE(disp_dtrc, imx8mq_disp_dtrc_sels, CCM_BASE, 0xa200); +static IMX_CLK_COMPOSITE(disp_dc8000, imx8mq_disp_dc8000_sels, CCM_BASE, 0xa280); +static IMX_CLK_COMPOSITE(pcie1_ctrl, imx8mq_pcie1_ctrl_sels, CCM_BASE, 0xa300); +static IMX_CLK_COMPOSITE(pcie1_phy, imx8mq_pcie1_phy_sels, CCM_BASE, 0xa380); +static IMX_CLK_COMPOSITE(pcie1_aux, imx8mq_pcie1_aux_sels, CCM_BASE, 0xa400); +static IMX_CLK_COMPOSITE(dc_pixel, imx8mq_dc_pixel_sels, CCM_BASE, 0xa480); +static IMX_CLK_COMPOSITE(lcdif_pixel, imx8mq_lcdif_pixel_sels, CCM_BASE, 0xa500); +static IMX_CLK_COMPOSITE(sai1, imx8mq_sai1_sels, CCM_BASE, 0xa580); +static IMX_CLK_COMPOSITE(sai2, imx8mq_sai2_sels, CCM_BASE, 0xa600); +static IMX_CLK_COMPOSITE(sai3, imx8mq_sai3_sels, CCM_BASE, 0xa680); +static IMX_CLK_COMPOSITE(sai4, imx8mq_sai4_sels, CCM_BASE, 0xa700); +static IMX_CLK_COMPOSITE(sai5, imx8mq_sai5_sels, CCM_BASE, 0xa780); +static IMX_CLK_COMPOSITE(sai6, imx8mq_sai6_sels, CCM_BASE, 0xa800); +static IMX_CLK_COMPOSITE(spdif1, imx8mq_spdif1_sels, CCM_BASE, 0xa880); +static IMX_CLK_COMPOSITE(spdif2, imx8mq_spdif2_sels, CCM_BASE, 0xa900); +static IMX_CLK_COMPOSITE(enet_ref, imx8mq_enet_ref_sels, CCM_BASE, 0xa980); +static IMX_CLK_COMPOSITE(enet_timer, imx8mq_enet_timer_sels, CCM_BASE, 0xaa00); +static IMX_CLK_COMPOSITE(enet_phy, imx8mq_enet_phy_sels, CCM_BASE, 0xaa80); +static IMX_CLK_COMPOSITE(nand, imx8mq_nand_sels, CCM_BASE, 0xab00); +static IMX_CLK_COMPOSITE(qspi, imx8mq_qspi_sels, CCM_BASE, 0xab80); +static IMX_CLK_COMPOSITE(usdhc1, imx8mq_usdhc1_sels, CCM_BASE, 0xac00); +static IMX_CLK_COMPOSITE(usdhc2, imx8mq_usdhc2_sels, CCM_BASE, 0xac80); +static IMX_CLK_COMPOSITE(i2c1, imx8mq_i2c1_sels, CCM_BASE, 0xad00); +static IMX_CLK_COMPOSITE(i2c2, imx8mq_i2c2_sels, CCM_BASE, 0xad80); +static IMX_CLK_COMPOSITE(i2c3, imx8mq_i2c3_sels, CCM_BASE, 0xae00); +static IMX_CLK_COMPOSITE(i2c4, imx8mq_i2c4_sels, CCM_BASE, 0xae80); +static IMX_CLK_COMPOSITE(uart1, imx8mq_uart1_sels, CCM_BASE, 0xaf00); +static IMX_CLK_COMPOSITE(uart2, imx8mq_uart2_sels, CCM_BASE, 0xaf80); +static IMX_CLK_COMPOSITE(uart3, imx8mq_uart3_sels, CCM_BASE, 0xb000); +static IMX_CLK_COMPOSITE(uart4, imx8mq_uart4_sels, CCM_BASE, 0xb080); +static IMX_CLK_COMPOSITE(usb_core_ref, imx8mq_usb_core_sels, CCM_BASE, 0xb100); +static IMX_CLK_COMPOSITE(usb_phy_ref, imx8mq_usb_phy_sels, CCM_BASE, 0xb180); +static IMX_CLK_COMPOSITE(gic, imx8mq_gic_sels, CCM_BASE, 0xb200); +static IMX_CLK_COMPOSITE(ecspi1, imx8mq_ecspi1_sels, CCM_BASE, 0xb280); +static IMX_CLK_COMPOSITE(ecspi2, imx8mq_ecspi2_sels, CCM_BASE, 0xb300); +static IMX_CLK_COMPOSITE(pwm1, imx8mq_pwm1_sels, CCM_BASE, 0xb380); +static IMX_CLK_COMPOSITE(pwm2, imx8mq_pwm2_sels, CCM_BASE, 0xb400); +static IMX_CLK_COMPOSITE(pwm3, imx8mq_pwm3_sels, CCM_BASE, 0xb480); +static IMX_CLK_COMPOSITE(pwm4, imx8mq_pwm4_sels, CCM_BASE, 0xb500); +static IMX_CLK_COMPOSITE(gpt1, imx8mq_gpt1_sels, CCM_BASE, 0xb580); +static IMX_CLK_COMPOSITE(wdog, imx8mq_wdog_sels, CCM_BASE, 0xb900); +static IMX_CLK_COMPOSITE(wrclk, imx8mq_wrclk_sels, CCM_BASE, 0xb980); +static IMX_CLK_COMPOSITE(clko1, imx8mq_clko1_sels, CCM_BASE, 0xba00); +static IMX_CLK_COMPOSITE(clko2, imx8mq_clko2_sels, CCM_BASE, 0xba80); +static IMX_CLK_COMPOSITE(dsi_core, imx8mq_dsi_core_sels, CCM_BASE, 0xbb00); +static IMX_CLK_COMPOSITE(dsi_phy_ref, imx8mq_dsi_phy_sels, CCM_BASE, 0xbb80); +static IMX_CLK_COMPOSITE(dsi_dbi, imx8mq_dsi_dbi_sels, CCM_BASE, 0xbc00); +static IMX_CLK_COMPOSITE(dsi_esc, imx8mq_dsi_esc_sels, CCM_BASE, 0xbc80); +static IMX_CLK_COMPOSITE(dsi_ahb, imx8mq_dsi_ahb_sels, CCM_BASE, 0x9200); +static IMX_CLK_DIV2(dsi_ipg_div, { &dsi_ahb }, CCM_BASE, 0x9280, 0, 6); +static IMX_CLK_COMPOSITE(csi1_core, imx8mq_csi1_core_sels, CCM_BASE, 0xbd00); +static IMX_CLK_COMPOSITE(csi1_phy_ref, imx8mq_csi1_phy_sels, CCM_BASE, 0xbd80); +static IMX_CLK_COMPOSITE(csi1_esc, imx8mq_csi1_esc_sels, CCM_BASE, 0xbe00); +static IMX_CLK_COMPOSITE(csi2_core, imx8mq_csi2_core_sels, CCM_BASE, 0xbe80); +static IMX_CLK_COMPOSITE(csi2_phy_ref, imx8mq_csi2_phy_sels, CCM_BASE, 0xbf00); +static IMX_CLK_COMPOSITE(csi2_esc, imx8mq_csi2_esc_sels, CCM_BASE, 0xbf80); +static IMX_CLK_COMPOSITE(pcie2_ctrl, imx8mq_pcie2_ctrl_sels, CCM_BASE, 0xc000); +static IMX_CLK_COMPOSITE(pcie2_phy, imx8mq_pcie2_phy_sels, CCM_BASE, 0xc080); +static IMX_CLK_COMPOSITE(pcie2_aux, imx8mq_pcie2_aux_sels, CCM_BASE, 0xc100); +static IMX_CLK_COMPOSITE(ecspi3, imx8mq_ecspi3_sels, CCM_BASE, 0xc180); static IMX_CLK_GATE4(ecspi1_root_clk, { &ecspi1 }, CCM_BASE, 0x4070, 0); static IMX_CLK_GATE4(ecspi2_root_clk, { &ecspi2 }, CCM_BASE, 0x4080, 0); @@ -1241,15 +2632,18 @@ static IMX_CLK_GATE4(usdhc2_root_clk, { &usdhc2 }, CCM_BASE, 0x4520, 0); static IMX_CLK_GATE4(wdog1_root_clk, { &wdog }, CCM_BASE, 0x4530, 0); static IMX_CLK_GATE4(wdog2_root_clk, { &wdog }, CCM_BASE, 0x4540, 0); static IMX_CLK_GATE4(wdog3_root_clk, { &wdog }, CCM_BASE, 0x4550, 0); -static IMX_CLK_GATE2_FLAGS(vpu_g1_root_clk, { &vpu_g1 }, CCM_BASE, 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); +static IMX_CLK_GATE2_FLAGS(vpu_g1_root_clk, { &vpu_g1 }, CCM_BASE, 0x4560, 0, + CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); static IMX_CLK_GATE4(gpu_root_clk, { &gpu_core }, CCM_BASE, 0x4570, 0); -static IMX_CLK_GATE2_FLAGS(vpu_g2_root_clk, { &vpu_g2 }, CCM_BASE, 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); +static IMX_CLK_GATE2_FLAGS(vpu_g2_root_clk, { &vpu_g2 }, CCM_BASE, 0x45a0, 0, + CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); static IMX_CLK_GATE2_SHARED2(disp_root_clk, { &disp_dc8000 }, CCM_BASE, 0x45d0, 0, &share_count_dcss); static IMX_CLK_GATE2_SHARED2(disp_axi_root_clk, { &disp_axi }, CCM_BASE, 0x45d0, 0, &share_count_dcss); static IMX_CLK_GATE2_SHARED2(disp_apb_root_clk, { &disp_apb }, CCM_BASE, 0x45d0, 0, &share_count_dcss); static IMX_CLK_GATE2_SHARED2(disp_rtrm_root_clk, { &disp_rtrm }, CCM_BASE, 0x45d0, 0, &share_count_dcss); static IMX_CLK_GATE4(tmu_root_clk, { &ipg_root }, CCM_BASE, 0x4620, 0); -static IMX_CLK_GATE2_FLAGS(vpu_dec_root_clk, { &vpu_bus }, CCM_BASE, 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); +static IMX_CLK_GATE2_FLAGS(vpu_dec_root_clk, { &vpu_bus }, CCM_BASE, 0x4630, 0, + CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); static IMX_CLK_GATE4(csi1_root_clk, { &csi1_core }, CCM_BASE, 0x4650, 0); static IMX_CLK_GATE4(csi2_root_clk, { &csi2_core }, CCM_BASE, 0x4660, 0); static IMX_CLK_GATE4(sdma1_clk, { &ipg_root }, CCM_BASE, 0x43a0, 0); @@ -1265,249 +2659,249 @@ static IMX_CLK_FIXED_FACTOR(dram_alt_root, { &dram_alt }, 1, 4); /* hws[IMX8MQ_CLK_A53_DIV]->clk); */ static struct clk *imx8mq_clks[IMX8MQ_CLK_END] = { - [IMX8MQ_CLK_DUMMY] = &dummy, - [IMX8MQ_CLK_32K] = &ckil, - [IMX8MQ_CLK_25M] = &osc_25m, - [IMX8MQ_CLK_27M] = &osc_27m, - [IMX8MQ_CLK_EXT1] = &clk_ext1, - [IMX8MQ_CLK_EXT2] = &clk_ext2, - [IMX8MQ_CLK_EXT3] = &clk_ext3, - [IMX8MQ_CLK_EXT4] = &clk_ext4, - [IMX8MQ_ARM_PLL_REF_SEL] = &arm_pll_ref_sel, - [IMX8MQ_GPU_PLL_REF_SEL] = &gpu_pll_ref_sel, - [IMX8MQ_VPU_PLL_REF_SEL] = &vpu_pll_ref_sel, - [IMX8MQ_AUDIO_PLL1_REF_SEL] = &audio_pll1_ref_sel, - [IMX8MQ_AUDIO_PLL2_REF_SEL] = &audio_pll2_ref_sel, - [IMX8MQ_VIDEO_PLL1_REF_SEL] = &video_pll1_ref_sel, - [IMX8MQ_SYS3_PLL1_REF_SEL] = &sys3_pll1_ref_sel, - [IMX8MQ_DRAM_PLL1_REF_SEL] = &dram_pll1_ref_sel, - [IMX8MQ_VIDEO2_PLL1_REF_SEL] = &video2_pll1_ref_sel, - [IMX8MQ_ARM_PLL_REF_DIV] = &arm_pll_ref_div, - [IMX8MQ_GPU_PLL_REF_DIV] = &gpu_pll_ref_div, - [IMX8MQ_VPU_PLL_REF_DIV] = &vpu_pll_ref_div, - [IMX8MQ_AUDIO_PLL1_REF_DIV] = &audio_pll1_ref_div, - [IMX8MQ_AUDIO_PLL2_REF_DIV] = &audio_pll2_ref_div, - [IMX8MQ_VIDEO_PLL1_REF_DIV] = &video_pll1_ref_div, - [IMX8MQ_ARM_PLL] = &arm_pll, - [IMX8MQ_GPU_PLL] = &gpu_pll, - [IMX8MQ_VPU_PLL] = &vpu_pll, - [IMX8MQ_AUDIO_PLL1] = &audio_pll1, - [IMX8MQ_AUDIO_PLL2] = &audio_pll2, - [IMX8MQ_VIDEO_PLL1] = &video_pll1, - [IMX8MQ_ARM_PLL_BYPASS] = &arm_pll_bypass, - [IMX8MQ_GPU_PLL_BYPASS] = &gpu_pll_bypass, - [IMX8MQ_VPU_PLL_BYPASS] = &vpu_pll_bypass, - [IMX8MQ_AUDIO_PLL1_BYPASS] = &audio_pll1_bypass, - [IMX8MQ_AUDIO_PLL2_BYPASS] = &audio_pll2_bypass, - [IMX8MQ_VIDEO_PLL1_BYPASS] = &video_pll1_bypass, - [IMX8MQ_ARM_PLL_OUT] = &arm_pll_out, - [IMX8MQ_GPU_PLL_OUT] = &gpu_pll_out, - [IMX8MQ_VPU_PLL_OUT] = &vpu_pll_out, - [IMX8MQ_AUDIO_PLL1_OUT] = &audio_pll1_out, - [IMX8MQ_AUDIO_PLL2_OUT] = &audio_pll2_out, - [IMX8MQ_VIDEO_PLL1_OUT] = &video_pll1_out, - [IMX8MQ_SYS1_PLL_OUT] = &sys1_pll_out, - [IMX8MQ_SYS2_PLL_OUT] = &sys2_pll_out, - [IMX8MQ_SYS3_PLL_OUT] = &sys3_pll_out, - [IMX8MQ_DRAM_PLL_OUT] = &dram_pll_out, - [IMX8MQ_VIDEO2_PLL_OUT] = &video2_pll_out, - [IMX8MQ_SYS1_PLL_40M] = &sys1_pll_40m, - [IMX8MQ_SYS1_PLL_80M] = &sys1_pll_80m, - [IMX8MQ_SYS1_PLL_100M] = &sys1_pll_100m, - [IMX8MQ_SYS1_PLL_133M] = &sys1_pll_133m, - [IMX8MQ_SYS1_PLL_160M] = &sys1_pll_160m, - [IMX8MQ_SYS1_PLL_200M] = &sys1_pll_200m, - [IMX8MQ_SYS1_PLL_266M] = &sys1_pll_266m, - [IMX8MQ_SYS1_PLL_400M] = &sys1_pll_400m, - [IMX8MQ_SYS1_PLL_800M] = &sys1_pll_800m, - [IMX8MQ_SYS2_PLL_50M] = &sys2_pll_50m, - [IMX8MQ_SYS2_PLL_100M] = &sys2_pll_100m, - [IMX8MQ_SYS2_PLL_125M] = &sys2_pll_125m, - [IMX8MQ_SYS2_PLL_166M] = &sys2_pll_166m, - [IMX8MQ_SYS2_PLL_200M] = &sys2_pll_200m, - [IMX8MQ_SYS2_PLL_250M] = &sys2_pll_250m, - [IMX8MQ_SYS2_PLL_333M] = &sys2_pll_333m, - [IMX8MQ_SYS2_PLL_500M] = &sys2_pll_500m, - [IMX8MQ_SYS2_PLL_1000M] = &sys2_pll_1000m, + [IMX8MQ_CLK_DUMMY] = &dummy, + [IMX8MQ_CLK_32K] = &ckil, + [IMX8MQ_CLK_25M] = &osc_25m, + [IMX8MQ_CLK_27M] = &osc_27m, + [IMX8MQ_CLK_EXT1] = &clk_ext1, + [IMX8MQ_CLK_EXT2] = &clk_ext2, + [IMX8MQ_CLK_EXT3] = &clk_ext3, + [IMX8MQ_CLK_EXT4] = &clk_ext4, + [IMX8MQ_ARM_PLL_REF_SEL] = &arm_pll_ref_sel, + [IMX8MQ_GPU_PLL_REF_SEL] = &gpu_pll_ref_sel, + [IMX8MQ_VPU_PLL_REF_SEL] = &vpu_pll_ref_sel, + [IMX8MQ_AUDIO_PLL1_REF_SEL] = &audio_pll1_ref_sel, + [IMX8MQ_AUDIO_PLL2_REF_SEL] = &audio_pll2_ref_sel, + [IMX8MQ_VIDEO_PLL1_REF_SEL] = &video_pll1_ref_sel, + [IMX8MQ_SYS3_PLL1_REF_SEL] = &sys3_pll1_ref_sel, + [IMX8MQ_DRAM_PLL1_REF_SEL] = &dram_pll1_ref_sel, + [IMX8MQ_VIDEO2_PLL1_REF_SEL] = &video2_pll1_ref_sel, + [IMX8MQ_ARM_PLL_REF_DIV] = &arm_pll_ref_div, + [IMX8MQ_GPU_PLL_REF_DIV] = &gpu_pll_ref_div, + [IMX8MQ_VPU_PLL_REF_DIV] = &vpu_pll_ref_div, + [IMX8MQ_AUDIO_PLL1_REF_DIV] = &audio_pll1_ref_div, + [IMX8MQ_AUDIO_PLL2_REF_DIV] = &audio_pll2_ref_div, + [IMX8MQ_VIDEO_PLL1_REF_DIV] = &video_pll1_ref_div, + [IMX8MQ_ARM_PLL] = &arm_pll, + [IMX8MQ_GPU_PLL] = &gpu_pll, + [IMX8MQ_VPU_PLL] = &vpu_pll, + [IMX8MQ_AUDIO_PLL1] = &audio_pll1, + [IMX8MQ_AUDIO_PLL2] = &audio_pll2, + [IMX8MQ_VIDEO_PLL1] = &video_pll1, + [IMX8MQ_ARM_PLL_BYPASS] = &arm_pll_bypass, + [IMX8MQ_GPU_PLL_BYPASS] = &gpu_pll_bypass, + [IMX8MQ_VPU_PLL_BYPASS] = &vpu_pll_bypass, + [IMX8MQ_AUDIO_PLL1_BYPASS] = &audio_pll1_bypass, + [IMX8MQ_AUDIO_PLL2_BYPASS] = &audio_pll2_bypass, + [IMX8MQ_VIDEO_PLL1_BYPASS] = &video_pll1_bypass, + [IMX8MQ_ARM_PLL_OUT] = &arm_pll_out, + [IMX8MQ_GPU_PLL_OUT] = &gpu_pll_out, + [IMX8MQ_VPU_PLL_OUT] = &vpu_pll_out, + [IMX8MQ_AUDIO_PLL1_OUT] = &audio_pll1_out, + [IMX8MQ_AUDIO_PLL2_OUT] = &audio_pll2_out, + [IMX8MQ_VIDEO_PLL1_OUT] = &video_pll1_out, + [IMX8MQ_SYS1_PLL_OUT] = &sys1_pll_out, + [IMX8MQ_SYS2_PLL_OUT] = &sys2_pll_out, + [IMX8MQ_SYS3_PLL_OUT] = &sys3_pll_out, + [IMX8MQ_DRAM_PLL_OUT] = &dram_pll_out, + [IMX8MQ_VIDEO2_PLL_OUT] = &video2_pll_out, + [IMX8MQ_SYS1_PLL_40M] = &sys1_pll_40m, + [IMX8MQ_SYS1_PLL_80M] = &sys1_pll_80m, + [IMX8MQ_SYS1_PLL_100M] = &sys1_pll_100m, + [IMX8MQ_SYS1_PLL_133M] = &sys1_pll_133m, + [IMX8MQ_SYS1_PLL_160M] = &sys1_pll_160m, + [IMX8MQ_SYS1_PLL_200M] = &sys1_pll_200m, + [IMX8MQ_SYS1_PLL_266M] = &sys1_pll_266m, + [IMX8MQ_SYS1_PLL_400M] = &sys1_pll_400m, + [IMX8MQ_SYS1_PLL_800M] = &sys1_pll_800m, + [IMX8MQ_SYS2_PLL_50M] = &sys2_pll_50m, + [IMX8MQ_SYS2_PLL_100M] = &sys2_pll_100m, + [IMX8MQ_SYS2_PLL_125M] = &sys2_pll_125m, + [IMX8MQ_SYS2_PLL_166M] = &sys2_pll_166m, + [IMX8MQ_SYS2_PLL_200M] = &sys2_pll_200m, + [IMX8MQ_SYS2_PLL_250M] = &sys2_pll_250m, + [IMX8MQ_SYS2_PLL_333M] = &sys2_pll_333m, + [IMX8MQ_SYS2_PLL_500M] = &sys2_pll_500m, + [IMX8MQ_SYS2_PLL_1000M] = &sys2_pll_1000m, [IMX8MQ_CLK_MON_AUDIO_PLL1_DIV] = &audio_pll1_out_monitor, [IMX8MQ_CLK_MON_AUDIO_PLL2_DIV] = &audio_pll2_out_monitor, [IMX8MQ_CLK_MON_VIDEO_PLL1_DIV] = &video_pll1_out_monitor, - [IMX8MQ_CLK_MON_GPU_PLL_DIV] = &gpu_pll_out_monitor, - [IMX8MQ_CLK_MON_VPU_PLL_DIV] = &vpu_pll_out_monitor, - [IMX8MQ_CLK_MON_ARM_PLL_DIV] = &arm_pll_out_monitor, - [IMX8MQ_CLK_MON_SYS_PLL1_DIV] = &sys_pll1_out_monitor, - [IMX8MQ_CLK_MON_SYS_PLL2_DIV] = &sys_pll2_out_monitor, - [IMX8MQ_CLK_MON_SYS_PLL3_DIV] = &sys_pll3_out_monitor, - [IMX8MQ_CLK_MON_DRAM_PLL_DIV] = &dram_pll_out_monitor, + [IMX8MQ_CLK_MON_GPU_PLL_DIV] = &gpu_pll_out_monitor, + [IMX8MQ_CLK_MON_VPU_PLL_DIV] = &vpu_pll_out_monitor, + [IMX8MQ_CLK_MON_ARM_PLL_DIV] = &arm_pll_out_monitor, + [IMX8MQ_CLK_MON_SYS_PLL1_DIV] = &sys_pll1_out_monitor, + [IMX8MQ_CLK_MON_SYS_PLL2_DIV] = &sys_pll2_out_monitor, + [IMX8MQ_CLK_MON_SYS_PLL3_DIV] = &sys_pll3_out_monitor, + [IMX8MQ_CLK_MON_DRAM_PLL_DIV] = &dram_pll_out_monitor, [IMX8MQ_CLK_MON_VIDEO_PLL2_DIV] = &video_pll2_out_monitor, - [IMX8MQ_CLK_MON_SEL] = &pllout_monitor_sel, - [IMX8MQ_CLK_MON_CLK2_OUT] = &pllout_monitor_clk2, - [IMX8MQ_CLK_A53_DIV] = &arm_a53_div, - [IMX8MQ_CLK_A53_CG] = &arm_a53_div, - [IMX8MQ_CLK_A53_SRC] = &arm_a53_div, - [IMX8MQ_CLK_M4_CORE] = &arm_m4_core, - [IMX8MQ_CLK_VPU_CORE] = &vpu_core, - [IMX8MQ_CLK_GPU_CORE] = &gpu_core, - [IMX8MQ_CLK_GPU_SHADER] = &gpu_shader, - [IMX8MQ_CLK_M4_SRC] = &arm_m4_core, - [IMX8MQ_CLK_M4_CG] = &arm_m4_core, - [IMX8MQ_CLK_M4_DIV] = &arm_m4_core, - [IMX8MQ_CLK_VPU_SRC] = &vpu_core, - [IMX8MQ_CLK_VPU_CG] = &vpu_core, - [IMX8MQ_CLK_VPU_DIV] = &vpu_core, - [IMX8MQ_CLK_GPU_CORE_SRC] = &gpu_core, - [IMX8MQ_CLK_GPU_CORE_CG] = &gpu_core, - [IMX8MQ_CLK_GPU_CORE_DIV] = &gpu_core, - [IMX8MQ_CLK_GPU_SHADER_SRC] = &gpu_shader, - [IMX8MQ_CLK_GPU_SHADER_CG] = &gpu_shader, - [IMX8MQ_CLK_GPU_SHADER_DIV] = &gpu_shader, - [IMX8MQ_CLK_A53_CORE] = &arm_a53_core, - [IMX8MQ_CLK_MAIN_AXI] = &main_axi, - [IMX8MQ_CLK_ENET_AXI] = &enet_axi, - [IMX8MQ_CLK_NAND_USDHC_BUS] = &nand_usdhc_bus, - [IMX8MQ_CLK_VPU_BUS] = &vpu_bus, - [IMX8MQ_CLK_DISP_AXI] = &disp_axi, - [IMX8MQ_CLK_DISP_APB] = &disp_apb, - [IMX8MQ_CLK_DISP_RTRM] = &disp_rtrm, - [IMX8MQ_CLK_USB_BUS] = &usb_bus, - [IMX8MQ_CLK_GPU_AXI] = &gpu_axi, - [IMX8MQ_CLK_GPU_AHB] = &gpu_ahb, - [IMX8MQ_CLK_NOC] = &noc, - [IMX8MQ_CLK_NOC_APB] = &noc_apb, - [IMX8MQ_CLK_AHB] = &ahb, - [IMX8MQ_CLK_AUDIO_AHB] = &audio_ahb, - [IMX8MQ_CLK_IPG_ROOT] = &ipg_root, - [IMX8MQ_CLK_IPG_AUDIO_ROOT] = &ipg_audio_root, - [IMX8MQ_CLK_DRAM_CORE] = &dram_core_clk, - [IMX8MQ_CLK_DRAM_ALT] = &dram_alt, - [IMX8MQ_CLK_DRAM_APB] = &dram_apb, - [IMX8MQ_CLK_VPU_G1] = &vpu_g1, - [IMX8MQ_CLK_VPU_G2] = &vpu_g2, - [IMX8MQ_CLK_DISP_DTRC] = &disp_dtrc, - [IMX8MQ_CLK_DISP_DC8000] = &disp_dc8000, - [IMX8MQ_CLK_PCIE1_CTRL] = &pcie1_ctrl, - [IMX8MQ_CLK_PCIE1_PHY] = &pcie1_phy, - [IMX8MQ_CLK_PCIE1_AUX] = &pcie1_aux, - [IMX8MQ_CLK_DC_PIXEL] = &dc_pixel, - [IMX8MQ_CLK_LCDIF_PIXEL] = &lcdif_pixel, - [IMX8MQ_CLK_SAI1] = &sai1, - [IMX8MQ_CLK_SAI2] = &sai2, - [IMX8MQ_CLK_SAI3] = &sai3, - [IMX8MQ_CLK_SAI4] = &sai4, - [IMX8MQ_CLK_SAI5] = &sai5, - [IMX8MQ_CLK_SAI6] = &sai6, - [IMX8MQ_CLK_SPDIF1] = &spdif1, - [IMX8MQ_CLK_SPDIF2] = &spdif2, - [IMX8MQ_CLK_ENET_REF] = &enet_ref, - [IMX8MQ_CLK_ENET_TIMER] = &enet_timer, - [IMX8MQ_CLK_ENET_PHY_REF] = &enet_phy, - [IMX8MQ_CLK_NAND] = &nand, - [IMX8MQ_CLK_QSPI] = &qspi, - [IMX8MQ_CLK_USDHC1] = &usdhc1, - [IMX8MQ_CLK_USDHC2] = &usdhc2, - [IMX8MQ_CLK_I2C1] = &i2c1, - [IMX8MQ_CLK_I2C2] = &i2c2, - [IMX8MQ_CLK_I2C3] = &i2c3, - [IMX8MQ_CLK_I2C4] = &i2c4, - [IMX8MQ_CLK_UART1] = &uart1, - [IMX8MQ_CLK_UART2] = &uart2, - [IMX8MQ_CLK_UART3] = &uart3, - [IMX8MQ_CLK_UART4] = &uart4, - [IMX8MQ_CLK_USB_CORE_REF] = &usb_core_ref, - [IMX8MQ_CLK_USB_PHY_REF] = &usb_phy_ref, - [IMX8MQ_CLK_GIC] = &gic, - [IMX8MQ_CLK_ECSPI1] = &ecspi1, - [IMX8MQ_CLK_ECSPI2] = &ecspi2, - [IMX8MQ_CLK_PWM1] = &pwm1, - [IMX8MQ_CLK_PWM2] = &pwm2, - [IMX8MQ_CLK_PWM3] = &pwm3, - [IMX8MQ_CLK_PWM4] = &pwm4, - [IMX8MQ_CLK_GPT1] = &gpt1, - [IMX8MQ_CLK_WDOG] = &wdog, - [IMX8MQ_CLK_WRCLK] = &wrclk, - [IMX8MQ_CLK_CLKO1] = &clko1, - [IMX8MQ_CLK_CLKO2] = &clko2, - [IMX8MQ_CLK_DSI_CORE] = &dsi_core, - [IMX8MQ_CLK_DSI_PHY_REF] = &dsi_phy_ref, - [IMX8MQ_CLK_DSI_DBI] = &dsi_dbi, - [IMX8MQ_CLK_DSI_ESC] = &dsi_esc, - [IMX8MQ_CLK_DSI_AHB] = &dsi_ahb, - [IMX8MQ_CLK_DSI_IPG_DIV] = &dsi_ipg_div, - [IMX8MQ_CLK_CSI1_CORE] = &csi1_core, - [IMX8MQ_CLK_CSI1_PHY_REF] = &csi1_phy_ref, - [IMX8MQ_CLK_CSI1_ESC] = &csi1_esc, - [IMX8MQ_CLK_CSI2_CORE] = &csi2_core, - [IMX8MQ_CLK_CSI2_PHY_REF] = &csi2_phy_ref, - [IMX8MQ_CLK_CSI2_ESC] = &csi2_esc, - [IMX8MQ_CLK_PCIE2_CTRL] = &pcie2_ctrl, - [IMX8MQ_CLK_PCIE2_PHY] = &pcie2_phy, - [IMX8MQ_CLK_PCIE2_AUX] = &pcie2_aux, - [IMX8MQ_CLK_ECSPI3] = &ecspi3, - [IMX8MQ_CLK_ECSPI1_ROOT] = &ecspi1_root_clk, - [IMX8MQ_CLK_ECSPI2_ROOT] = &ecspi2_root_clk, - [IMX8MQ_CLK_ECSPI3_ROOT] = &ecspi3_root_clk, - [IMX8MQ_CLK_ENET1_ROOT] = &enet1_root_clk, - [IMX8MQ_CLK_GPIO1_ROOT] = &gpio1_root_clk, - [IMX8MQ_CLK_GPIO2_ROOT] = &gpio2_root_clk, - [IMX8MQ_CLK_GPIO3_ROOT] = &gpio3_root_clk, - [IMX8MQ_CLK_GPIO4_ROOT] = &gpio4_root_clk, - [IMX8MQ_CLK_GPIO5_ROOT] = &gpio5_root_clk, - [IMX8MQ_CLK_GPT1_ROOT] = &gpt1_root_clk, - [IMX8MQ_CLK_I2C1_ROOT] = &i2c1_root_clk, - [IMX8MQ_CLK_I2C2_ROOT] = &i2c2_root_clk, - [IMX8MQ_CLK_I2C3_ROOT] = &i2c3_root_clk, - [IMX8MQ_CLK_I2C4_ROOT] = &i2c4_root_clk, - [IMX8MQ_CLK_MU_ROOT] = &mu_root_clk, - [IMX8MQ_CLK_OCOTP_ROOT] = &ocotp_root_clk, - [IMX8MQ_CLK_PCIE1_ROOT] = &pcie1_root_clk, - [IMX8MQ_CLK_PCIE2_ROOT] = &pcie2_root_clk, - [IMX8MQ_CLK_PWM1_ROOT] = &pwm1_root_clk, - [IMX8MQ_CLK_PWM2_ROOT] = &pwm2_root_clk, - [IMX8MQ_CLK_PWM3_ROOT] = &pwm3_root_clk, - [IMX8MQ_CLK_PWM4_ROOT] = &pwm4_root_clk, - [IMX8MQ_CLK_QSPI_ROOT] = &qspi_root_clk, - [IMX8MQ_CLK_RAWNAND_ROOT] = &nand_root_clk, + [IMX8MQ_CLK_MON_SEL] = &pllout_monitor_sel, + [IMX8MQ_CLK_MON_CLK2_OUT] = &pllout_monitor_clk2, + [IMX8MQ_CLK_A53_DIV] = &arm_a53_div, + [IMX8MQ_CLK_A53_CG] = &arm_a53_div, + [IMX8MQ_CLK_A53_SRC] = &arm_a53_div, + [IMX8MQ_CLK_M4_CORE] = &arm_m4_core, + [IMX8MQ_CLK_VPU_CORE] = &vpu_core, + [IMX8MQ_CLK_GPU_CORE] = &gpu_core, + [IMX8MQ_CLK_GPU_SHADER] = &gpu_shader, + [IMX8MQ_CLK_M4_SRC] = &arm_m4_core, + [IMX8MQ_CLK_M4_CG] = &arm_m4_core, + [IMX8MQ_CLK_M4_DIV] = &arm_m4_core, + [IMX8MQ_CLK_VPU_SRC] = &vpu_core, + [IMX8MQ_CLK_VPU_CG] = &vpu_core, + [IMX8MQ_CLK_VPU_DIV] = &vpu_core, + [IMX8MQ_CLK_GPU_CORE_SRC] = &gpu_core, + [IMX8MQ_CLK_GPU_CORE_CG] = &gpu_core, + [IMX8MQ_CLK_GPU_CORE_DIV] = &gpu_core, + [IMX8MQ_CLK_GPU_SHADER_SRC] = &gpu_shader, + [IMX8MQ_CLK_GPU_SHADER_CG] = &gpu_shader, + [IMX8MQ_CLK_GPU_SHADER_DIV] = &gpu_shader, + [IMX8MQ_CLK_A53_CORE] = &arm_a53_core, + [IMX8MQ_CLK_MAIN_AXI] = &main_axi, + [IMX8MQ_CLK_ENET_AXI] = &enet_axi, + [IMX8MQ_CLK_NAND_USDHC_BUS] = &nand_usdhc_bus, + [IMX8MQ_CLK_VPU_BUS] = &vpu_bus, + [IMX8MQ_CLK_DISP_AXI] = &disp_axi, + [IMX8MQ_CLK_DISP_APB] = &disp_apb, + [IMX8MQ_CLK_DISP_RTRM] = &disp_rtrm, + [IMX8MQ_CLK_USB_BUS] = &usb_bus, + [IMX8MQ_CLK_GPU_AXI] = &gpu_axi, + [IMX8MQ_CLK_GPU_AHB] = &gpu_ahb, + [IMX8MQ_CLK_NOC] = &noc, + [IMX8MQ_CLK_NOC_APB] = &noc_apb, + [IMX8MQ_CLK_AHB] = &ahb, + [IMX8MQ_CLK_AUDIO_AHB] = &audio_ahb, + [IMX8MQ_CLK_IPG_ROOT] = &ipg_root, + [IMX8MQ_CLK_IPG_AUDIO_ROOT] = &ipg_audio_root, + [IMX8MQ_CLK_DRAM_CORE] = &dram_core_clk, + [IMX8MQ_CLK_DRAM_ALT] = &dram_alt, + [IMX8MQ_CLK_DRAM_APB] = &dram_apb, + [IMX8MQ_CLK_VPU_G1] = &vpu_g1, + [IMX8MQ_CLK_VPU_G2] = &vpu_g2, + [IMX8MQ_CLK_DISP_DTRC] = &disp_dtrc, + [IMX8MQ_CLK_DISP_DC8000] = &disp_dc8000, + [IMX8MQ_CLK_PCIE1_CTRL] = &pcie1_ctrl, + [IMX8MQ_CLK_PCIE1_PHY] = &pcie1_phy, + [IMX8MQ_CLK_PCIE1_AUX] = &pcie1_aux, + [IMX8MQ_CLK_DC_PIXEL] = &dc_pixel, + [IMX8MQ_CLK_LCDIF_PIXEL] = &lcdif_pixel, + [IMX8MQ_CLK_SAI1] = &sai1, + [IMX8MQ_CLK_SAI2] = &sai2, + [IMX8MQ_CLK_SAI3] = &sai3, + [IMX8MQ_CLK_SAI4] = &sai4, + [IMX8MQ_CLK_SAI5] = &sai5, + [IMX8MQ_CLK_SAI6] = &sai6, + [IMX8MQ_CLK_SPDIF1] = &spdif1, + [IMX8MQ_CLK_SPDIF2] = &spdif2, + [IMX8MQ_CLK_ENET_REF] = &enet_ref, + [IMX8MQ_CLK_ENET_TIMER] = &enet_timer, + [IMX8MQ_CLK_ENET_PHY_REF] = &enet_phy, + [IMX8MQ_CLK_NAND] = &nand, + [IMX8MQ_CLK_QSPI] = &qspi, + [IMX8MQ_CLK_USDHC1] = &usdhc1, + [IMX8MQ_CLK_USDHC2] = &usdhc2, + [IMX8MQ_CLK_I2C1] = &i2c1, + [IMX8MQ_CLK_I2C2] = &i2c2, + [IMX8MQ_CLK_I2C3] = &i2c3, + [IMX8MQ_CLK_I2C4] = &i2c4, + [IMX8MQ_CLK_UART1] = &uart1, + [IMX8MQ_CLK_UART2] = &uart2, + [IMX8MQ_CLK_UART3] = &uart3, + [IMX8MQ_CLK_UART4] = &uart4, + [IMX8MQ_CLK_USB_CORE_REF] = &usb_core_ref, + [IMX8MQ_CLK_USB_PHY_REF] = &usb_phy_ref, + [IMX8MQ_CLK_GIC] = &gic, + [IMX8MQ_CLK_ECSPI1] = &ecspi1, + [IMX8MQ_CLK_ECSPI2] = &ecspi2, + [IMX8MQ_CLK_PWM1] = &pwm1, + [IMX8MQ_CLK_PWM2] = &pwm2, + [IMX8MQ_CLK_PWM3] = &pwm3, + [IMX8MQ_CLK_PWM4] = &pwm4, + [IMX8MQ_CLK_GPT1] = &gpt1, + [IMX8MQ_CLK_WDOG] = &wdog, + [IMX8MQ_CLK_WRCLK] = &wrclk, + [IMX8MQ_CLK_CLKO1] = &clko1, + [IMX8MQ_CLK_CLKO2] = &clko2, + [IMX8MQ_CLK_DSI_CORE] = &dsi_core, + [IMX8MQ_CLK_DSI_PHY_REF] = &dsi_phy_ref, + [IMX8MQ_CLK_DSI_DBI] = &dsi_dbi, + [IMX8MQ_CLK_DSI_ESC] = &dsi_esc, + [IMX8MQ_CLK_DSI_AHB] = &dsi_ahb, + [IMX8MQ_CLK_DSI_IPG_DIV] = &dsi_ipg_div, + [IMX8MQ_CLK_CSI1_CORE] = &csi1_core, + [IMX8MQ_CLK_CSI1_PHY_REF] = &csi1_phy_ref, + [IMX8MQ_CLK_CSI1_ESC] = &csi1_esc, + [IMX8MQ_CLK_CSI2_CORE] = &csi2_core, + [IMX8MQ_CLK_CSI2_PHY_REF] = &csi2_phy_ref, + [IMX8MQ_CLK_CSI2_ESC] = &csi2_esc, + [IMX8MQ_CLK_PCIE2_CTRL] = &pcie2_ctrl, + [IMX8MQ_CLK_PCIE2_PHY] = &pcie2_phy, + [IMX8MQ_CLK_PCIE2_AUX] = &pcie2_aux, + [IMX8MQ_CLK_ECSPI3] = &ecspi3, + [IMX8MQ_CLK_ECSPI1_ROOT] = &ecspi1_root_clk, + [IMX8MQ_CLK_ECSPI2_ROOT] = &ecspi2_root_clk, + [IMX8MQ_CLK_ECSPI3_ROOT] = &ecspi3_root_clk, + [IMX8MQ_CLK_ENET1_ROOT] = &enet1_root_clk, + [IMX8MQ_CLK_GPIO1_ROOT] = &gpio1_root_clk, + [IMX8MQ_CLK_GPIO2_ROOT] = &gpio2_root_clk, + [IMX8MQ_CLK_GPIO3_ROOT] = &gpio3_root_clk, + [IMX8MQ_CLK_GPIO4_ROOT] = &gpio4_root_clk, + [IMX8MQ_CLK_GPIO5_ROOT] = &gpio5_root_clk, + [IMX8MQ_CLK_GPT1_ROOT] = &gpt1_root_clk, + [IMX8MQ_CLK_I2C1_ROOT] = &i2c1_root_clk, + [IMX8MQ_CLK_I2C2_ROOT] = &i2c2_root_clk, + [IMX8MQ_CLK_I2C3_ROOT] = &i2c3_root_clk, + [IMX8MQ_CLK_I2C4_ROOT] = &i2c4_root_clk, + [IMX8MQ_CLK_MU_ROOT] = &mu_root_clk, + [IMX8MQ_CLK_OCOTP_ROOT] = &ocotp_root_clk, + [IMX8MQ_CLK_PCIE1_ROOT] = &pcie1_root_clk, + [IMX8MQ_CLK_PCIE2_ROOT] = &pcie2_root_clk, + [IMX8MQ_CLK_PWM1_ROOT] = &pwm1_root_clk, + [IMX8MQ_CLK_PWM2_ROOT] = &pwm2_root_clk, + [IMX8MQ_CLK_PWM3_ROOT] = &pwm3_root_clk, + [IMX8MQ_CLK_PWM4_ROOT] = &pwm4_root_clk, + [IMX8MQ_CLK_QSPI_ROOT] = &qspi_root_clk, + [IMX8MQ_CLK_RAWNAND_ROOT] = &nand_root_clk, [IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = &nand_usdhc_rawnand_clk, - [IMX8MQ_CLK_SAI1_ROOT] = &sai1_root_clk, - [IMX8MQ_CLK_SAI1_IPG] = &sai1_ipg_clk, - [IMX8MQ_CLK_SAI2_ROOT] = &sai2_root_clk, - [IMX8MQ_CLK_SAI2_IPG] = &sai2_ipg_clk, - [IMX8MQ_CLK_SAI3_ROOT] = &sai3_root_clk, - [IMX8MQ_CLK_SAI3_IPG] = &sai3_ipg_clk, - [IMX8MQ_CLK_SAI4_ROOT] = &sai4_root_clk, - [IMX8MQ_CLK_SAI4_IPG] = &sai4_ipg_clk, - [IMX8MQ_CLK_SAI5_ROOT] = &sai5_root_clk, - [IMX8MQ_CLK_SAI5_IPG] = &sai5_ipg_clk, - [IMX8MQ_CLK_SAI6_ROOT] = &sai6_root_clk, - [IMX8MQ_CLK_SAI6_IPG] = &sai6_ipg_clk, - [IMX8MQ_CLK_UART1_ROOT] = &uart1_root_clk, - [IMX8MQ_CLK_UART2_ROOT] = &uart2_root_clk, - [IMX8MQ_CLK_UART3_ROOT] = &uart3_root_clk, - [IMX8MQ_CLK_UART4_ROOT] = &uart4_root_clk, - [IMX8MQ_CLK_USB1_CTRL_ROOT] = &usb1_ctrl_root_clk, - [IMX8MQ_CLK_USB2_CTRL_ROOT] = &usb2_ctrl_root_clk, - [IMX8MQ_CLK_USB1_PHY_ROOT] = &usb1_phy_root_clk, - [IMX8MQ_CLK_USB2_PHY_ROOT] = &usb2_phy_root_clk, - [IMX8MQ_CLK_USDHC1_ROOT] = &usdhc1_root_clk, - [IMX8MQ_CLK_USDHC2_ROOT] = &usdhc2_root_clk, - [IMX8MQ_CLK_WDOG1_ROOT] = &wdog1_root_clk, - [IMX8MQ_CLK_WDOG2_ROOT] = &wdog2_root_clk, - [IMX8MQ_CLK_WDOG3_ROOT] = &wdog3_root_clk, - [IMX8MQ_CLK_VPU_G1_ROOT] = &vpu_g1_root_clk, - [IMX8MQ_CLK_GPU_ROOT] = &gpu_root_clk, - [IMX8MQ_CLK_VPU_G2_ROOT] = &vpu_g2_root_clk, - [IMX8MQ_CLK_DISP_ROOT] = &disp_root_clk, - [IMX8MQ_CLK_DISP_AXI_ROOT] = &disp_axi_root_clk, - [IMX8MQ_CLK_DISP_APB_ROOT] = &disp_apb_root_clk, - [IMX8MQ_CLK_DISP_RTRM_ROOT] = &disp_rtrm_root_clk, - [IMX8MQ_CLK_TMU_ROOT] = &tmu_root_clk, - [IMX8MQ_CLK_VPU_DEC_ROOT] = &vpu_dec_root_clk, - [IMX8MQ_CLK_CSI1_ROOT] = &csi1_root_clk, - [IMX8MQ_CLK_CSI2_ROOT] = &csi2_root_clk, - [IMX8MQ_CLK_SDMA1_ROOT] = &sdma1_clk, - [IMX8MQ_CLK_SDMA2_ROOT] = &sdma2_clk, - [IMX8MQ_GPT_3M_CLK] = &gpt_3m, - [IMX8MQ_CLK_DRAM_ALT_ROOT] = &dram_alt_root, + [IMX8MQ_CLK_SAI1_ROOT] = &sai1_root_clk, + [IMX8MQ_CLK_SAI1_IPG] = &sai1_ipg_clk, + [IMX8MQ_CLK_SAI2_ROOT] = &sai2_root_clk, + [IMX8MQ_CLK_SAI2_IPG] = &sai2_ipg_clk, + [IMX8MQ_CLK_SAI3_ROOT] = &sai3_root_clk, + [IMX8MQ_CLK_SAI3_IPG] = &sai3_ipg_clk, + [IMX8MQ_CLK_SAI4_ROOT] = &sai4_root_clk, + [IMX8MQ_CLK_SAI4_IPG] = &sai4_ipg_clk, + [IMX8MQ_CLK_SAI5_ROOT] = &sai5_root_clk, + [IMX8MQ_CLK_SAI5_IPG] = &sai5_ipg_clk, + [IMX8MQ_CLK_SAI6_ROOT] = &sai6_root_clk, + [IMX8MQ_CLK_SAI6_IPG] = &sai6_ipg_clk, + [IMX8MQ_CLK_UART1_ROOT] = &uart1_root_clk, + [IMX8MQ_CLK_UART2_ROOT] = &uart2_root_clk, + [IMX8MQ_CLK_UART3_ROOT] = &uart3_root_clk, + [IMX8MQ_CLK_UART4_ROOT] = &uart4_root_clk, + [IMX8MQ_CLK_USB1_CTRL_ROOT] = &usb1_ctrl_root_clk, + [IMX8MQ_CLK_USB2_CTRL_ROOT] = &usb2_ctrl_root_clk, + [IMX8MQ_CLK_USB1_PHY_ROOT] = &usb1_phy_root_clk, + [IMX8MQ_CLK_USB2_PHY_ROOT] = &usb2_phy_root_clk, + [IMX8MQ_CLK_USDHC1_ROOT] = &usdhc1_root_clk, + [IMX8MQ_CLK_USDHC2_ROOT] = &usdhc2_root_clk, + [IMX8MQ_CLK_WDOG1_ROOT] = &wdog1_root_clk, + [IMX8MQ_CLK_WDOG2_ROOT] = &wdog2_root_clk, + [IMX8MQ_CLK_WDOG3_ROOT] = &wdog3_root_clk, + [IMX8MQ_CLK_VPU_G1_ROOT] = &vpu_g1_root_clk, + [IMX8MQ_CLK_GPU_ROOT] = &gpu_root_clk, + [IMX8MQ_CLK_VPU_G2_ROOT] = &vpu_g2_root_clk, + [IMX8MQ_CLK_DISP_ROOT] = &disp_root_clk, + [IMX8MQ_CLK_DISP_AXI_ROOT] = &disp_axi_root_clk, + [IMX8MQ_CLK_DISP_APB_ROOT] = &disp_apb_root_clk, + [IMX8MQ_CLK_DISP_RTRM_ROOT] = &disp_rtrm_root_clk, + [IMX8MQ_CLK_TMU_ROOT] = &tmu_root_clk, + [IMX8MQ_CLK_VPU_DEC_ROOT] = &vpu_dec_root_clk, + [IMX8MQ_CLK_CSI1_ROOT] = &csi1_root_clk, + [IMX8MQ_CLK_CSI2_ROOT] = &csi2_root_clk, + [IMX8MQ_CLK_SDMA1_ROOT] = &sdma1_clk, + [IMX8MQ_CLK_SDMA2_ROOT] = &sdma2_clk, + [IMX8MQ_GPT_3M_CLK] = &gpt_3m, + [IMX8MQ_CLK_DRAM_ALT_ROOT] = &dram_alt_root, }; struct clk **get_clk_list(void) diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index c16f3e876..9b15fbab6 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -145,7 +145,6 @@ uint32_t clk_set_rate(struct clk *clk, uint32_t rate) void notified(microkit_channel ch) { - } void init(void) @@ -171,52 +170,53 @@ microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) /* TODO: Check if the channel is valid */ switch (microkit_msginfo_get_label(msginfo)) { - case SDDF_CLK_ENABLE: { - if (argc != 1) { - LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; - break; - } - uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - LOG_DRIVER("get request clk_enable(%d)\n", clk_id); - ret = clk_enable(clk_list[clk_id]); + case SDDF_CLK_ENABLE: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; break; } - case SDDF_CLK_DISABLE: { - if (argc != 1) { - LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; - break; - } - uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - LOG_DRIVER("get request clk_disable(%d)\n", clk_id); - ret = clk_disable(clk_list[clk_id]); + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + LOG_DRIVER("get request clk_enable(%d)\n", clk_id); + ret = clk_enable(clk_list[clk_id]); + break; + } + case SDDF_CLK_DISABLE: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; break; } - case SDDF_CLK_GET_RATE: { - if (argc != 1) { - LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; - break; - } - uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - ret = clk_get_rate(clk_list[clk_id]); + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + LOG_DRIVER("get request clk_disable(%d)\n", clk_id); + ret = clk_disable(clk_list[clk_id]); + break; + } + case SDDF_CLK_GET_RATE: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; break; } - case SDDF_CLK_SET_RATE: { - if (argc != 2) { - LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; - break; - } - uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - uint32_t rate = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_RATE); - ret = clk_set_rate(clk_list[clk_id], rate); + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + ret = clk_get_rate(clk_list[clk_id]); + break; + } + case SDDF_CLK_SET_RATE: { + if (argc != 2) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + ret = CLK_INCORRECT_ARGS; break; } - default: - LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), ch); - ret = 5; + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + uint32_t rate = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_RATE); + ret = clk_set_rate(clk_list[clk_id], rate); + break; + } + default: + LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), + ch); + ret = 5; } return microkit_msginfo_new(ret, 0); } diff --git a/drivers/clk/imx/include/clk-imx.h b/drivers/clk/imx/include/clk-imx.h index a99a81d62..60723260c 100644 --- a/drivers/clk/imx/include/clk-imx.h +++ b/drivers/clk/imx/include/clk-imx.h @@ -121,8 +121,7 @@ struct clk _name = { \ #define IMX_CLK_FIXED(_name, _rate) \ IMX_CLK_SOURCE(_name, _rate) -#define IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ - _parent_data, _num_parents, _init_flags) \ +#define IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, _parent_data, _num_parents, _init_flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_mux_data) { \ @@ -139,23 +138,19 @@ struct clk _name = { \ }, \ } -#define IMX_CLK_MUX(_name, _base, _offset, _shift, _width, \ - _parent_data, _num_parents) \ +#define IMX_CLK_MUX(_name, _base, _offset, _shift, _width, _parent_data, _num_parents) \ IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ _parent_data, _num_parents, 0) -#define IMX_CLK_MUX2(_name, _base, _offset, _shift, _width, \ - _parent_data, _num_parents) \ +#define IMX_CLK_MUX2(_name, _base, _offset, _shift, _width, _parent_data, _num_parents) \ IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ _parent_data, _num_parents, CLK_OPS_PARENT_ENABLE) -#define IMX_CLK_MUX2_FLAGS(_name, _base, _offset, _shift, _width, \ - _parent_data, _num_parents, _flags) \ +#define IMX_CLK_MUX2_FLAGS(_name, _base, _offset, _shift, _width, _parent_data, _num_parents, _flags) \ IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ _parent_data, _num_parents, _flags | CLK_OPS_PARENT_ENABLE) -#define IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, \ - _shift, _width, _flags) \ +#define IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, _width, _flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_div_data) { \ @@ -172,16 +167,13 @@ struct clk _name = { \ }, \ } -#define IMX_CLK_DIV(_name, _parent_clks, _base, _offset, \ - _shift, _width) \ +#define IMX_CLK_DIV(_name, _parent_clks, _base, _offset, _shift, _width) \ IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, _width, 0) -#define IMX_CLK_DIV2(_name, _parent_clks, _base, _offset, \ - _shift, _width) \ +#define IMX_CLK_DIV2(_name, _parent_clks, _base, _offset, _shift, _width) \ IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, \ _width, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE) - #define IMX_CLK_FRAC_PLL(_name, _parent_clks, _base, _offset) \ struct clk _name = { \ .base = (_base), \ @@ -238,8 +230,7 @@ IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, 0) #define IMX_CLK_FIXED_FACTOR(_name, _parent_clks, _mult, _div) \ CLK_FIXED_FACTOR(_name, _mult, _div, 0, _parent_clks, 1, CLK_SET_RATE_PARENT) -#define IMX_CLK_SSCG_PLL(_name, _parent_data, _num_parents, _parent, \ - _bypass1, _bypass2, _base, _offset, _flags) \ +#define IMX_CLK_SSCG_PLL(_name, _parent_data, _num_parents, _parent, _bypass1, _bypass2, _base, _offset, _flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_sscg_pll_data) { \ @@ -303,8 +294,7 @@ struct clk _name = { \ }, \ } -#define IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset,\ - _flags) \ +#define IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, _flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_common_slice_data) { \ From 9d0fa57b5e713614f80fb7657bb8288b3343a5ca Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Tue, 5 Nov 2024 16:24:26 +1100 Subject: [PATCH 05/11] clk: modify interfaces and fix issues during initialisation This commit includes modifiation to the interfaces, primarily for set/get rate, which return error state as well as final rate. More tests are conducted to verify the basic operations of types of clock components. A few bugs are fixed as well. Signed-off-by: Terry Bai --- drivers/clk/clk-operations.h | 3 + drivers/clk/clk.h | 6 +- drivers/clk/imx/clk-imx8mq.c | 2 - drivers/clk/imx/clk.c | 166 +++++++++++++++++++++++++--------- drivers/clk/meson/clk-meson.c | 5 +- drivers/clk/meson/clk.c | 127 ++++++++++++++++++-------- examples/clk/client.c | 12 ++- include/sddf/clk/client.h | 10 +- 8 files changed, 237 insertions(+), 94 deletions(-) diff --git a/drivers/clk/clk-operations.h b/drivers/clk/clk-operations.h index 22d4607aa..6848ae32e 100644 --- a/drivers/clk/clk-operations.h +++ b/drivers/clk/clk-operations.h @@ -9,6 +9,9 @@ #define CLK_INCORRECT_ARGS 1 #define CLK_INVALID_OP 2 +#define CLK_INVALID_ID 3 +#define CLK_UNKNOWN_REQ 4 +#define CLK_UNKNOWN_TARGET 5 int reg_write(uint64_t base, uint32_t offset, uint32_t val); int regmap_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width, uint32_t val); diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 8dc9ab22f..61d5a22fa 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -372,7 +372,7 @@ const struct clk *get_parent(const struct clk *clk); * @clk: pointer to the current clk * */ -unsigned long clk_get_rate(const struct clk *clk); +uint32_t clk_get_rate(const struct clk *clk, uint64_t *rate); /** * function clk_enable() - enable the target clock signal @@ -393,5 +393,7 @@ uint32_t clk_disable(struct clk *clk); * the target clock * * @clk: pointer to the current clk + * @req_rate: request rate + * @rate: pointer to result variable */ -uint32_t clk_set_rate(struct clk *clk, uint32_t rate); +uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate); diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index bd78cf595..98fdd2346 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -2906,7 +2906,5 @@ static struct clk *imx8mq_clks[IMX8MQ_CLK_END] = { struct clk **get_clk_list(void) { - sddf_dprintf("get clk list\n"); - return imx8mq_clks; } diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index 9b15fbab6..d908a3abb 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -37,27 +38,42 @@ struct clk **clk_list; uintptr_t ccm_base; uintptr_t ccm_analog_base; +struct clk *get_clk_by_name(const char *name) +{ + for (int i = 0; i < NUM_CLK_LIST; i++) { + if (clk_list[i] && sddf_strcmp(clk_list[i]->hw.init->name, name) == 0) { + return clk_list[i]; + } + } + return NULL; +} + void clk_probe(struct clk *clk_list[]) { - int i; - for (i = 0; i < NUM_CLK_LIST; i++) { + for (int i = 0; i < NUM_CLK_LIST; i++) { if (!clk_list[i]) { continue; } + + struct clk_init_data *init_data = clk_list[i]->hw.init; + if (clk_list[i]->base == CCM_BASE) { clk_list[i]->base = ccm_base; } else if (clk_list[i]->base == CCM_ANALOG_BASE) { clk_list[i]->base = ccm_analog_base; } - if (clk_list[i] && clk_list[i]->hw.init->ops->init) { - clk_list[i]->hw.init->ops->init(clk_list[i]); - LOG_DRIVER("Initialise %s\n", clk_list[i]->hw.init->name); + if (clk_list[i] && init_data->ops->init) { + init_data->ops->init(clk_list[i]); + LOG_DRIVER("Initialise %s\n", init_data->name); } } } const struct clk *get_parent(const struct clk *clk) { + if (!clk) + return NULL; + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; uint32_t num_parents = init->num_parents; @@ -67,8 +83,8 @@ const struct clk *get_parent(const struct clk *clk) if (parent_data.clk) { return parent_data.clk; - } else if (sddf_strcmp(parent_data.name, "xtal") == 0) { - return NULL; + } else if (parent_data.name) { + return get_clk_by_name(parent_data.name); } } @@ -81,26 +97,37 @@ const struct clk *get_parent(const struct clk *clk) /* TODO: Should be just read from the structure, but need to update everytime when */ /* related clocks are modified */ -unsigned long clk_get_rate(const struct clk *clk) +uint32_t clk_get_rate(const struct clk *clk, uint64_t *rate) { + if (!clk) + return CLK_UNKNOWN_TARGET; + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; - unsigned long parent_rate = 0; + uint64_t parent_rate = 0; + uint32_t err = 0; const struct clk *parent_clk = get_parent(clk); + if (parent_clk) { - parent_rate = clk_get_rate(parent_clk); + err = clk_get_rate(parent_clk, &parent_rate); } - unsigned long rate = parent_rate; + if (err) + return err; + + *rate = parent_rate; if (init->ops->recalc_rate) { - rate = init->ops->recalc_rate(clk, parent_rate); + *rate = init->ops->recalc_rate(clk, parent_rate); } - return rate; + return 0; } uint32_t clk_enable(struct clk *clk) { + if (!clk) + return CLK_UNKNOWN_TARGET; + if (clk->hw.init->ops->enable != NULL) { return clk->hw.init->ops->enable(clk); } @@ -110,6 +137,9 @@ uint32_t clk_enable(struct clk *clk) uint32_t clk_disable(struct clk *clk) { + if (!clk) + return CLK_UNKNOWN_TARGET; + if (clk->hw.init->ops->disable != NULL) { return clk->hw.init->ops->disable(clk); } @@ -117,29 +147,62 @@ uint32_t clk_disable(struct clk *clk) return CLK_INVALID_OP; } -uint32_t clk_set_rate(struct clk *clk, uint32_t rate) +uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) { + if (!clk) + return CLK_UNKNOWN_TARGET; + + /* TODO: we only propagate request to one level up. More operations need to be + * invoked by clients until a dynamic configration algorithm implemented */ if (clk->hw.init->ops->init) { clk->hw.init->ops->init(clk); } const struct clk *pclk = get_parent(clk); - uint64_t prate = clk_get_rate(pclk); + uint64_t prate = 0; + uint32_t err = clk_get_rate(pclk, &prate); + if (err) { + LOG_DRIVER_ERR("Failed to get parent clock's rate\n"); + return err; + } + if (clk->hw.init->ops->set_rate) { - /* TODO: determine_rate() needs to be implemented */ - LOG_DRIVER("set %s to %dHz\n", clk->hw.init->name, rate); - clk->hw.init->ops->set_rate(clk, rate, prate); - } else { - /* TODO: We only propagate one level right now */ - if (pclk->hw.init->ops->set_rate) { - const struct clk *ppclk = get_parent(pclk); - uint64_t pprate = clk_get_rate(ppclk); - /* TODO: determine_rate() needs to be implemented */ - LOG_DRIVER("set %s to %dHz\n", pclk->hw.init->name, rate); + *rate = clk->hw.init->ops->set_rate(clk, req_rate, prate); + return 0; + } else if (pclk && pclk->hw.init->ops->set_rate) { + const struct clk *ppclk = get_parent(pclk); + uint64_t pprate = 0; + uint32_t err = clk_get_rate(ppclk, &pprate); + if (!err) { pclk->hw.init->ops->set_rate(pclk, prate, pprate); + return 0; } + return err; } + return CLK_INVALID_OP; +} + +int clk_msr_stat() +{ +#ifdef DEBUG_DRIVER + int i; + uint64_t rate = 0; + uint32_t err; + + LOG_DRIVER("-------Expected clock rates------\n"); + for (i = 0; i < NUM_CLK_LIST; i++) { + if (clk_list[i]) { + err = clk_get_rate(clk_list[i], &rate); + if (err) { + LOG_DRIVER_ERR("Failed to get rate of %s: -%u\n", clk_list[i]->hw.init->name, err); + } + LOG_DRIVER("[%4d][%10luHz] %s\n", i, rate, clk_list[i]->hw.init->name); + } + } + LOG_DRIVER("-----------------------------\n"); +#endif + return 0; } @@ -149,22 +212,35 @@ void notified(microkit_channel ch) void init(void) { - clk_list = get_clk_list(); clk_probe(clk_list); + clk_msr_stat(); for (int i = 0; i < NUM_DEVICE_CLKS; i++) { - uint32_t idx = clk_configs[i].clk_id; - uint32_t rate = clk_configs[i].frequency; - - sddf_dprintf("idx: %u, frequency: 0x%x\n", idx, rate); + struct clk *clk = clk_list[clk_configs[i].clk_id]; + LOG_DRIVER("clk_id: %d\n", clk_configs[i].clk_id); + /* Enable the clock */ + clk_enable(clk); + + /* TODO: Set parent */ + + /* TODO: Set rate for the target clock */ + /* if (clk_configs[i].frequency > 0) { */ + /* LOG_DRIVER("set rate for %s\n", clk->hw.init->name); */ + /* uint64_t rate = 0; */ + /* uint32_t err = clk_set_rate(clk, clk_configs[i].frequency, &rate); */ + /* if (err) { */ + /* LOG_DRIVER_ERR("Failed to set rate [%d] for clk_id: %d\n", clk_configs[i].frequency, clk_configs[i].clk_id); */ + /* } */ + /* LOG_DRIVER("------------------\n"); */ + /* } */ } } microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) { - uint32_t ret = 0; + uint32_t err = 0; uint32_t argc = microkit_msginfo_get_count(msginfo); /* TODO: Check if the channel is valid */ @@ -173,50 +249,52 @@ microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) case SDDF_CLK_ENABLE: { if (argc != 1) { LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; + err = CLK_INCORRECT_ARGS; break; } uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); LOG_DRIVER("get request clk_enable(%d)\n", clk_id); - ret = clk_enable(clk_list[clk_id]); + err = clk_enable(clk_list[clk_id]); break; } case SDDF_CLK_DISABLE: { if (argc != 1) { LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; + err = CLK_INCORRECT_ARGS; break; } uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); LOG_DRIVER("get request clk_disable(%d)\n", clk_id); - ret = clk_disable(clk_list[clk_id]); + err = clk_disable(clk_list[clk_id]); break; } case SDDF_CLK_GET_RATE: { if (argc != 1) { LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; + err = CLK_INCORRECT_ARGS; break; } uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - ret = clk_get_rate(clk_list[clk_id]); + uint64_t rate = 0; + err = clk_get_rate(clk_list[clk_id], &rate); break; } case SDDF_CLK_SET_RATE: { if (argc != 2) { LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; + err = CLK_INCORRECT_ARGS; break; } uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - uint32_t rate = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_RATE); - ret = clk_set_rate(clk_list[clk_id], rate); + uint64_t req_rate = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_RATE); + uint64_t rate = 0; + err = clk_set_rate(clk_list[clk_id], req_rate, &rate); break; } default: - LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), - ch); - ret = 5; + LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", + microkit_msginfo_get_label(msginfo), ch); + err = CLK_UNKNOWN_REQ; } - return microkit_msginfo_new(ret, 0); + return microkit_msginfo_new(err, 0); } diff --git a/drivers/clk/meson/clk-meson.c b/drivers/clk/meson/clk-meson.c index 67b864e32..6c26f1fff 100644 --- a/drivers/clk/meson/clk-meson.c +++ b/drivers/clk/meson/clk-meson.c @@ -348,11 +348,12 @@ static unsigned long meson_vid_pll_div_recalc_rate(const struct clk *clk, unsign for (i = 0; i < ARRAY_SIZE(vid_pll_div_table); ++i) { if (vid_pll_div_table[i].shift_val == shift_val && vid_pll_div_table[i].shift_sel == shift_sel) { div = &vid_pll_div_table[i]; - break; + return DIV_ROUND_UP_ULL(prate * div->multiplier, div->divider); } } - return DIV_ROUND_UP_ULL(prate * div->multiplier, div->divider); + /* Return 0 if the vid pll is not configured */ + return 0; } const struct clk_ops meson_vid_pll_div_ro_ops = { diff --git a/drivers/clk/meson/clk.c b/drivers/clk/meson/clk.c index 925db7521..368ee6c99 100644 --- a/drivers/clk/meson/clk.c +++ b/drivers/clk/meson/clk.c @@ -31,6 +31,8 @@ #define LOG_DRIVER_ERR(...) do{ sddf_printf("CLK DRIVER|ERROR: "); sddf_printf(__VA_ARGS__); }while(0) +#define NUM_CLK_LIST CLKID_PCIE_PLL + #define I2C_CLK_OFFSET 320 #define I2C_CLK_BIT (1 << 9) // bit 9 @@ -51,7 +53,7 @@ struct clk **clk_list; void clk_probe(struct clk *clk_list[]) { int i; - for (i = 0; i < CLKID_PCIE_PLL; i++) { + for (i = 0; i < NUM_CLK_LIST; i++) { clk_list[i]->base = (uint64_t)clk_regs; if (clk_list[i] && clk_list[i]->hw.init->ops->init) { clk_list[i]->hw.init->ops->init(clk_list[i]); @@ -62,6 +64,9 @@ void clk_probe(struct clk *clk_list[]) const struct clk *get_parent(const struct clk *clk) { + if (!clk) + return NULL; + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; uint32_t num_parents = init->num_parents; @@ -85,26 +90,36 @@ const struct clk *get_parent(const struct clk *clk) /* TODO: Should be just read from the structure, but need to update everytime when */ /* related clocks are modified */ -unsigned long clk_get_rate(const struct clk *clk) +uint32_t clk_get_rate(const struct clk *clk, unsigned long *rate) { + if (!clk) + return CLK_UNKNOWN_TARGET; + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; unsigned long parent_rate = 0; + uint32_t err = 0; const struct clk *parent_clk = get_parent(clk); if (parent_clk) { - parent_rate = clk_get_rate(parent_clk); + err = clk_get_rate(parent_clk, &parent_rate); } - unsigned long rate = parent_rate; + if (err) + return err; + + *rate = parent_rate; if (init->ops->recalc_rate) { - rate = init->ops->recalc_rate(clk, parent_rate); + *rate = init->ops->recalc_rate(clk, parent_rate); } - return rate; + return 0; } uint32_t clk_enable(struct clk *clk) { + if (!clk) + return CLK_UNKNOWN_TARGET; + if (clk->hw.init->ops->enable != NULL) { return clk->hw.init->ops->enable(clk); } @@ -114,6 +129,9 @@ uint32_t clk_enable(struct clk *clk) uint32_t clk_disable(struct clk *clk) { + if (!clk) + return CLK_UNKNOWN_TARGET; + if (clk->hw.init->ops->disable != NULL) { return clk->hw.init->ops->disable(clk); } @@ -121,30 +139,44 @@ uint32_t clk_disable(struct clk *clk) return CLK_INVALID_OP; } -uint32_t clk_set_rate(struct clk *clk, uint32_t rate) +uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) { + if (!clk) + return CLK_UNKNOWN_TARGET; + + /* TODO: we only propagate request to one level up. More operations need to be + * invoked by clients until a dynamic configration algorithm implemented */ if (clk->hw.init->ops->init) { clk->hw.init->ops->init(clk); } const struct clk *pclk = get_parent(clk); - uint64_t prate = clk_get_rate(pclk); + uint64_t prate = 0; + uint32_t err = clk_get_rate(pclk, &prate); + if (err) { + LOG_DRIVER_ERR("Failed to get parent clock's rate\n"); + return err; + } + if (clk->hw.init->ops->set_rate) { - /* TODO: determine_rate() needs to be implemented */ - LOG_DRIVER("set %s to %dHz\n", clk->hw.init->name, rate); - clk->hw.init->ops->set_rate(clk, rate, prate); + clk->hw.init->ops->set_rate(clk, req_rate, prate); + *rate = req_rate; + return 0; } else { - /* TODO: We only propagate one level right now */ if (pclk->hw.init->ops->set_rate) { const struct clk *ppclk = get_parent(pclk); - uint64_t pprate = clk_get_rate(ppclk); - /* TODO: determine_rate() needs to be implemented */ - LOG_DRIVER("set %s to %dHz\n", pclk->hw.init->name, rate); - pclk->hw.init->ops->set_rate(pclk, prate, pprate); + uint64_t pprate = 0; + uint32_t err = clk_get_rate(ppclk, &pprate); + if (!err) { + pclk->hw.init->ops->set_rate(pclk, prate, pprate); + *rate = req_rate; + return 0; + } + return err; } } - return 0; + return CLK_INVALID_OP; } int clk_msr_stat() @@ -152,12 +184,28 @@ int clk_msr_stat() #ifdef DEBUG_DRIVER unsigned long clk_freq; int i = 0; + uint64_t rate = 0; + uint32_t err; const char *const *clk_msr_list = get_msr_clk_list(); + + LOG_DRIVER("-------Expected clock rates------\n"); + for (i = 0; i < NUM_CLK_LIST; i++) { + err = clk_get_rate(clk_list[i], &rate); + if (err) { + LOG_DRIVER("Failed to get rate of %s: -%u\n", clk_list[i]->hw.init->name, err); + + } + LOG_DRIVER("[%4d][%4luHz] %s\n", i, rate, clk_list[i]->hw.init->name); + } + LOG_DRIVER("---------------------------------\n"); + LOG_DRIVER("---------Clock measurement-------\n"); for (i = 0; i < 128; i++) { clk_freq = clk_msr(i); LOG_DRIVER("[%4d][%4ldHz] %s\n", i, clk_freq, clk_msr_list[i]); } + LOG_DRIVER("-----------------------------\n"); + #endif return 0; @@ -174,8 +222,8 @@ void init(void) clk_list = get_clk_list(); clk_probe(clk_list); + clk_msr_stat(); - volatile uint32_t *clk_i2c_ptr = ((void *)clk_regs + I2C_CLK_OFFSET); for (int i = 0; i < NUM_DEVICE_CLKS; i++) { struct clk *clk = clk_list[clk_configs[i].clk_id]; @@ -187,21 +235,20 @@ void init(void) /* Set rate for the target clock */ if (clk_configs[i].frequency > 0) { - clk_set_rate(clk, clk_configs[i].frequency); + uint64_t rate = 0; + uint32_t err = clk_set_rate(clk, clk_configs[i].frequency, &rate); + if (err) { + LOG_DRIVER_ERR("Failed to set rate [%d] for clk_id: %d\n", clk_configs[i].frequency, clk_configs[i].clk_id); + } } } - // Check that registers actually changed - if (!(*clk_i2c_ptr & I2C_CLK_BIT)) { - LOG_DRIVER_ERR("failed to toggle clock!\n"); - } - - /* clk_msr_stat(); */ } microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) { - uint32_t ret = 0; + uint32_t err = 0; + uint32_t ret_num = 0; uint32_t argc = microkit_msginfo_get_count(msginfo); /* TODO: Check if the channel is valid */ @@ -210,50 +257,56 @@ microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) case SDDF_CLK_ENABLE: { if (argc != 1) { LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; + err = CLK_INCORRECT_ARGS; break; } uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); LOG_DRIVER("get request clk_enable(%d)\n", clk_id); - ret = clk_enable(clk_list[clk_id]); + err = clk_enable(clk_list[clk_id]); break; } case SDDF_CLK_DISABLE: { if (argc != 1) { LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; + err = CLK_INCORRECT_ARGS; break; } uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); LOG_DRIVER("get request clk_disable(%d)\n", clk_id); - ret = clk_disable(clk_list[clk_id]); + err = clk_disable(clk_list[clk_id]); break; } case SDDF_CLK_GET_RATE: { if (argc != 1) { LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; + err = CLK_INCORRECT_ARGS; break; } uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - ret = clk_get_rate(clk_list[clk_id]); + uint64_t rate = 0; + err = clk_get_rate(clk_list[clk_id], &rate); + microkit_mr_set(0, rate); + ret_num = 1; break; } case SDDF_CLK_SET_RATE: { if (argc != 2) { LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - ret = CLK_INCORRECT_ARGS; + err = CLK_INCORRECT_ARGS; break; } uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - uint32_t rate = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_RATE); - ret = clk_set_rate(clk_list[clk_id], rate); + uint32_t req_rate = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_RATE); + uint64_t rate = 0; + err = clk_set_rate(clk_list[clk_id], req_rate, &rate); + microkit_mr_set(0, rate); + ret_num = 1; break; } default: LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), ch); - ret = 5; + err = CLK_UNKNOWN_REQ; } - return microkit_msginfo_new(ret, 0); + return microkit_msginfo_new(err, ret_num); } diff --git a/examples/clk/client.c b/examples/clk/client.c index 65894be3d..e9d66036f 100644 --- a/examples/clk/client.c +++ b/examples/clk/client.c @@ -25,11 +25,15 @@ void init(void) ret = sddf_clk_disable(CLK_DRIVER_CH, 24); sddf_dprintf("ret_val: %x\n", ret); - ret = sddf_clk_get_rate(CLK_DRIVER_CH, 10); - sddf_dprintf("ret_val: %x\n", ret); + uint64_t rate = 0; + ret = sddf_clk_get_rate(CLK_DRIVER_CH, 10, &rate); + sddf_dprintf("err: %d rate: %lu\n", ret, rate); - ret = sddf_clk_set_rate(CLK_DRIVER_CH, 10, 150000000); - sddf_dprintf("ret_val: %x\n", ret); + ret = sddf_clk_set_rate(CLK_DRIVER_CH, 10, 150000000, &rate); + sddf_dprintf("err: %d, rate: %lu\n", ret, rate); + + ret = sddf_clk_get_rate(CLK_DRIVER_CH, 187, &rate); + sddf_dprintf("err: %d, rate: %lu\n", ret, rate); #elif TEST_BOARD_maaxboard sddf_dprintf("Test board: maaxboard\n"); diff --git a/include/sddf/clk/client.h b/include/sddf/clk/client.h index 38fa5d9fe..8d0d51e6c 100644 --- a/include/sddf/clk/client.h +++ b/include/sddf/clk/client.h @@ -47,14 +47,16 @@ static inline uint32_t sddf_clk_disable(microkit_channel channel, uint32_t clk_i * Use the label to indicate this request. * @param channel of clock driver. * @param identifier of target clock. + * @param pointer to result variable. */ -static inline uint32_t sddf_clk_get_rate(microkit_channel channel, uint32_t clk_id) +static inline uint32_t sddf_clk_get_rate(microkit_channel channel, uint32_t clk_id, uint64_t *rate) { microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_GET_RATE, 1); microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); msginfo = microkit_ppcall(channel, msginfo); + *rate = microkit_mr_get(0); return (uint32_t)microkit_msginfo_get_label(msginfo); } @@ -64,14 +66,16 @@ static inline uint32_t sddf_clk_get_rate(microkit_channel channel, uint32_t clk_ * @param channel of clock driver. * @param identifier of target clock. * @param target clock frequency. + * @param pointer to result variable. */ -static inline uint32_t sddf_clk_set_rate(microkit_channel channel, uint32_t clk_id, uint32_t rate) +static inline uint32_t sddf_clk_set_rate(microkit_channel channel, uint32_t clk_id, uint64_t req_rate, uint64_t *rate) { microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_SET_RATE, 2); microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); - microkit_mr_set(SDDF_CLK_PARAM_RATE, rate); + microkit_mr_set(SDDF_CLK_PARAM_RATE, req_rate); msginfo = microkit_ppcall(channel, msginfo); + *rate = microkit_mr_get(0); return (uint32_t)microkit_msginfo_get_label(msginfo); } From 1acc8de2511e55d8121a256618aa4f58b6a6f36d Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Fri, 8 Nov 2024 13:43:04 +1100 Subject: [PATCH 06/11] clk: fix style and add licenses This commit fixed style and license issues Signed-off-by: Terry Bai --- LICENSES/GPL-2.0-only.txt | 117 ++++ LICENSES/GPL-2.0-or-later.txt | 117 ++++ drivers/clk/clk-operations.c | 163 ++---- drivers/clk/clk-operations.h | 281 +++++---- drivers/clk/clk.h | 14 +- drivers/clk/imx/clk-imx.c | 126 +++- drivers/clk/imx/clk-imx8mq.c | 243 +++++--- drivers/clk/imx/clk.c | 12 +- drivers/clk/imx/clk_driver.mk | 2 +- drivers/clk/imx/include/clk-imx.h | 141 +++-- drivers/clk/imx/include/imx8mq-bindings.h | 2 +- drivers/clk/meson/clk-measure.c | 19 +- drivers/clk/meson/clk-meson.c | 238 +++++--- drivers/clk/meson/clk.c | 42 +- drivers/clk/meson/clk_driver.mk | 2 +- drivers/clk/meson/include/clk-meson.h | 4 +- drivers/clk/meson/include/g12a-bindings.h | 2 +- drivers/clk/meson/include/g12a-regs.h | 2 +- drivers/clk/meson/sm1-clk.c | 465 +++++++++------ drivers/clk/utils.h | 2 +- examples/clk/build.zig.zon | 5 +- examples/clk/dts/odroidc4.dts | 680 ++++++++++------------ include/sddf/clk/client.h | 13 +- 23 files changed, 1622 insertions(+), 1070 deletions(-) create mode 100644 LICENSES/GPL-2.0-only.txt create mode 100644 LICENSES/GPL-2.0-or-later.txt diff --git a/LICENSES/GPL-2.0-only.txt b/LICENSES/GPL-2.0-only.txt new file mode 100644 index 000000000..17cb28643 --- /dev/null +++ b/LICENSES/GPL-2.0-only.txt @@ -0,0 +1,117 @@ +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + + c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. + + one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. + +signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice diff --git a/LICENSES/GPL-2.0-or-later.txt b/LICENSES/GPL-2.0-or-later.txt new file mode 100644 index 000000000..17cb28643 --- /dev/null +++ b/LICENSES/GPL-2.0-or-later.txt @@ -0,0 +1,117 @@ +GNU GENERAL PUBLIC LICENSE +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. + + c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. + + one line to give the program's name and an idea of what it does. Copyright (C) yyyy name of author + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. + +signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice diff --git a/drivers/clk/clk-operations.c b/drivers/clk/clk-operations.c index 4a355ee4f..6fe7167ab 100644 --- a/drivers/clk/clk-operations.c +++ b/drivers/clk/clk-operations.c @@ -1,16 +1,18 @@ -// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) /* * Operations for MPLL clocks are derived from: - * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-mpll.c + * https://github.com/torvalds/linux/blob/ + * befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-mpll.c * * Copyright (c) 2016 AmLogic, Inc. * Author: Michael Turquette */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for PLL clocks are derived from: - * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-pll.c + * https://github.com/torvalds/linux/blob/ + * befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-pll.c * * Copyright (c) 2015 Endless Mobile, Inc. * Author: Carlo Caione @@ -19,27 +21,30 @@ * Author: Jerome Brunet */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for gate clocks are derived from: - * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-regmap.c + * https://github.com/torvalds/linux/blob/ + * befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-regmap.c * * Copyright (c) 2018 BayLibre, SAS. * Author: Jerome Brunet */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for fixed factor clocks are derived from: - * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-fixed-factor.c + * https://github.com/torvalds/linux/blob/ + * befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-fixed-factor.c * * Copyright (C) 2011 Sascha Hauer, Pengutronix */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for divider clocks are derived from: - * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-divider.c + * https://github.com/torvalds/linux/blob/ + * befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-divider.c * * Copyright (C) 2011 Sascha Hauer, Pengutronix * Copyright (C) 2011 Richard Zhao, Linaro @@ -48,10 +53,11 @@ * Adjustable divider clock implementation */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for multiplexer clocks are derived from: - * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-mux.c + * https://github.com/torvalds/linux/blob/ + * befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-mux.c * * Copyright (C) 2011 Sascha Hauer, Pengutronix * Copyright (C) 2011 Richard Zhao, Linaro @@ -60,90 +66,31 @@ * Simple multiplexer clock implementation */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for meson_vid_pll_div are derived from: - * https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vid-pll-div.c - * https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vclk.c + * https://github.com/torvalds/linux/blob/ + * 7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vid-pll-div.c + * https://github.com/torvalds/linux/blob/ + * 7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vclk.c * * Copyright (c) 2018 BayLibre, SAS. * Author: Neil Armstrong */ #include -#include #include #include #include -int reg_write(uint64_t base, uint32_t offset, uint32_t val) -{ - volatile uint32_t *clk_reg = ((void *)base + offset); - *clk_reg = val; - - return 0; -} - -int regmap_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width, uint32_t val) -{ - volatile uint32_t *clk_reg = ((void *)base + offset); - uint32_t reg_val = *clk_reg; - - reg_val &= ~(MASK(width) << shift); - reg_val |= ((MASK(width) & val) << shift); - - *clk_reg = reg_val; - - /* TODO: Check if the register has been updated correctly */ - - return 0; -} - -int regmap_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width) -{ - volatile uint32_t *clk_reg = ((void *)base + offset); - uint32_t reg_val = *clk_reg; - - reg_val >>= shift; - reg_val &= MASK(width); - - return reg_val; -} - -int regmap_mux_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask, uint32_t val) -{ - volatile uint32_t *clk_reg = ((void *)base + offset); - uint32_t reg_val = *clk_reg; - - reg_val &= ~(mask << shift); - reg_val |= ((mask & val) << shift); - - *clk_reg = reg_val; - - /* TODO: Check if the register has been updated correctly */ - - return 0; -} - -int regmap_mux_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask) -{ - volatile uint32_t *clk_reg = ((void *)base + offset); - uint32_t reg_val = *clk_reg; - - reg_val >>= shift; - reg_val &= mask; - - return reg_val; -} - -static int clk_gate_enable(struct clk *clk) +static inline int clk_gate_enable(struct clk *clk) { struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); return regmap_update_bits(clk->base, data->offset, data->bit_idx, 1, 1); } -static int clk_gate_disable(struct clk *clk) +static inline int clk_gate_disable(struct clk *clk) { struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); @@ -151,7 +98,7 @@ static int clk_gate_disable(struct clk *clk) return 0; } -static int clk_gate_is_enabled(struct clk *clk) +static inline int clk_gate_is_enabled(struct clk *clk) { struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); @@ -175,11 +122,13 @@ const struct clk_ops clk_gate_ro_ops = { .is_enabled = clk_gate_is_enabled, }; -static unsigned long clk_div_recalc_rate(const struct clk *clk, unsigned long prate) +static inline unsigned long clk_div_recalc_rate(const struct clk *clk, + unsigned long prate) { struct clk_div_data *data = (struct clk_div_data *)(clk->data); - uint32_t div = regmap_read_bits(clk->base, data->offset, data->shift, data->width); + uint32_t div = regmap_read_bits(clk->base, data->offset, data->shift, + data->width); /* TODO: Need to verify the following cases */ if (data->flags & CLK_DIVIDER_ONE_BASED) { @@ -195,7 +144,8 @@ static unsigned long clk_div_recalc_rate(const struct clk *clk, unsigned long pr return DIV_ROUND_UP_ULL((uint64_t)prate, div); } -static int clk_div_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_rate) +static inline int clk_div_set_rate(const struct clk *clk, uint32_t rate, + uint32_t parent_rate) { struct clk_div_data *data = (struct clk_div_data *)(clk->data); uint32_t div = DIV_ROUND_UP(parent_rate, rate); @@ -210,30 +160,10 @@ static int clk_div_set_rate(const struct clk *clk, uint32_t rate, uint32_t paren } else { div -= 1; } - return regmap_update_bits(clk->base, data->offset, data->shift, data->width, div); + return regmap_update_bits(clk->base, data->offset, data->shift, data->width, + div); } -/* static int clk_div_determine_rate(struct clk_hw *hw, */ -/* struct clk_rate_request *req) */ -/* { */ -/* struct clk_div_data *data = (struct clk_div_data *)(hw->clk->data); */ -/* /\* struct clk_regmap *clk = to_clk_regmap(hw); *\/ */ -/* /\* struct clk_div_data *div = clk_get_regmap_div_data(clk); *\/ */ -/* uint32_t val; */ - -/* /\* if read only, just return current value *\/ */ -/* if (data->flags & CLK_DIVIDER_READ_ONLY) { */ -/* val = regmap_read_bits(data->offset, data->shift, data->width); */ - -/* /\* return divider_ro_determine_rate(hw, req, div->table, *\/ */ -/* /\* div->width, div->flags, val); *\/ */ -/* } */ - -/* /\* return divider_determine_rate(hw, req, div->table, div->width, *\/ */ -/* /\* div->flags); *\/ */ -/* return 0; */ -/* } */ - const struct clk_ops clk_divider_ops = { .enable = NULL, .recalc_rate = clk_div_recalc_rate, @@ -246,11 +176,12 @@ const struct clk_ops clk_divider_ro_ops = { /* .determine_rate = clk_div_determine_rate, */ }; -static uint8_t clk_mux_get_parent(const struct clk *clk) +static inline uint8_t clk_mux_get_parent(const struct clk *clk) { struct clk_mux_data *data = (struct clk_mux_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->shift, data->mask); + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->shift, + data->mask); if (data->table) { int i; @@ -276,15 +207,17 @@ static uint8_t clk_mux_get_parent(const struct clk *clk) return 0; } -static int clk_mux_set_parent(struct clk *clk, uint8_t index) +static inline int clk_mux_set_parent(struct clk *clk, uint8_t index) { struct clk_mux_data *data = (struct clk_mux_data *)(clk->data); if (data->table) { unsigned int val = data->table[index]; - regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, val); + regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, + val); } - /* TODO: handle cases without table given */ + regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, + index); return 0; } @@ -298,9 +231,11 @@ const struct clk_ops clk_mux_ro_ops = { .get_parent = clk_mux_get_parent, }; -static unsigned long clk_factor_recalc_rate(const struct clk *clk, unsigned long parent_rate) +static inline unsigned long clk_factor_recalc_rate(const struct clk *clk, + unsigned long parent_rate) { - struct clk_fixed_factor_data *data = (struct clk_fixed_factor_data *)(clk->data); + struct clk_fixed_factor_data *data = + (struct clk_fixed_factor_data *)(clk->data); unsigned long long int rate; rate = (unsigned long long int)parent_rate * data->mult; @@ -315,7 +250,8 @@ const struct clk_ops clk_fixed_factor_ops = { /* .recalc_accuracy = clk_factor_recalc_accuracy, */ }; -static int clk_source_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_rate) +static inline int clk_source_set_rate(const struct clk *clk, uint32_t rate, + uint32_t parent_rate) { struct clk_source_data *data = (struct clk_source_data *)(clk->data); data->rate = rate; @@ -323,7 +259,8 @@ static int clk_source_set_rate(const struct clk *clk, uint32_t rate, uint32_t pa return 0; } -static unsigned long clk_source_get_rate(const struct clk *clk, unsigned long prate) +static inline unsigned long clk_source_get_rate(const struct clk *clk, + unsigned long prate) { struct clk_source_data *data = (struct clk_source_data *)(clk->data); diff --git a/drivers/clk/clk-operations.h b/drivers/clk/clk-operations.h index 6848ae32e..beccd73c8 100644 --- a/drivers/clk/clk-operations.h +++ b/drivers/clk/clk-operations.h @@ -6,6 +6,7 @@ #pragma once #include +#include #define CLK_INCORRECT_ARGS 1 #define CLK_INVALID_OP 2 @@ -13,11 +14,66 @@ #define CLK_UNKNOWN_REQ 4 #define CLK_UNKNOWN_TARGET 5 -int reg_write(uint64_t base, uint32_t offset, uint32_t val); -int regmap_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width, uint32_t val); -int regmap_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width); -int regmap_mux_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask, uint32_t val); -int regmap_mux_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask); +static inline int reg_write(uint64_t base, uint32_t offset, uint32_t val) +{ + volatile uint32_t *clk_reg = ((void *)base + offset); + *clk_reg = val; + + return 0; +} + +static inline int regmap_update_bits(uint64_t base, uint32_t offset, + uint8_t shift, uint8_t width, uint32_t val) +{ + volatile uint32_t *clk_reg = ((void *)base + offset); + uint32_t reg_val = *clk_reg; + + reg_val &= ~(MASK(width) << shift); + reg_val |= ((MASK(width) & val) << shift); + + *clk_reg = reg_val; + + return 0; +} + +static inline uint32_t regmap_read_bits(uint64_t base, uint32_t offset, + uint8_t shift, uint8_t width) +{ + volatile uint32_t *clk_reg = ((void *)base + offset); + uint32_t reg_val = *clk_reg; + + reg_val >>= shift; + reg_val &= MASK(width); + + return reg_val; +} + +static inline int regmap_mux_update_bits(uint64_t base, uint32_t offset, + uint8_t shift, uint32_t mask, + uint32_t val) +{ + volatile uint32_t *clk_reg = ((void *)base + offset); + uint32_t reg_val = *clk_reg; + + reg_val &= ~(mask << shift); + reg_val |= ((mask & val) << shift); + + *clk_reg = reg_val; + + return 0; +} + +static inline uint32_t regmap_mux_read_bits(uint64_t base, uint32_t offset, + uint8_t shift, uint32_t mask) +{ + volatile uint32_t *clk_reg = ((void *)base + offset); + uint32_t reg_val = *clk_reg; + + reg_val >>= shift; + reg_val &= mask; + + return reg_val; +} extern const struct clk_ops clk_source_ops; extern const struct clk_ops clk_fixed_factor_ops; @@ -28,120 +84,127 @@ extern const struct clk_ops clk_mux_ro_ops; extern const struct clk_ops clk_gate_ops; extern const struct clk_ops clk_gate_ro_ops; -#define CLK_FIXED_FACTOR(_name, _mult, _div, _data_flags, _parent_clks, _num_parents, _init_flags) \ -struct clk _name = { \ - .data = &(struct clk_fixed_factor_data) { \ - .mult = (_mult), \ - .div = (_div), \ - .flags = (_data_flags), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = &clk_fixed_factor_ops, \ - .parent_clks = (const struct clk *[]) _parent_clks, \ - .num_parents = (_num_parents), \ - .flags = (_init_flags), \ - }, \ +#define CLK_FIXED_FACTOR(_name, _mult, _div, _data_flags, _parent_clks, \ + _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_fixed_factor_data) { \ + .mult = (_mult), \ + .div = (_div), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_fixed_factor_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ } -#define CLK_GATE(_name, _offset, _bit, _data_flags, _parent_clks, _num_parents, _init_flags) \ -struct clk _name = { \ - .data = &(struct clk_gate_data) { \ - .offset = (_offset), \ - .bit_idx = (_bit), \ - .flags = (_data_flags), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = &clk_gate_ops, \ - .parent_clks = (const struct clk *[]) _parent_clks, \ - .num_parents = _num_parents, \ - .flags = (_init_flags), \ - }, \ +#define CLK_GATE(_name, _offset, _bit, _data_flags, _parent_clks, \ + _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_gate_data) { \ + .offset = (_offset), \ + .bit_idx = (_bit), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_gate_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = _num_parents, \ + .flags = (_init_flags), \ + }, \ } -#define CLK_GATE_RO(_name, _offset, _bit, _data_flags, _parent_clks, _num_parents, _init_flags) \ -struct clk _name = { \ - .data = &(struct clk_gate_data) { \ - .offset = (_offset), \ - .bit_idx = (_bit), \ - .flags = (_data_flags), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = &clk_gate_ro_ops, \ - .parent_clks = (const struct clk *[]) _parent_clks, \ - .num_parents = _num_parents, \ - .flags = (_init_flags), \ - }, \ +#define CLK_GATE_RO(_name, _offset, _bit, _data_flags, _parent_clks, \ + _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_gate_data) { \ + .offset = (_offset), \ + .bit_idx = (_bit), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_gate_ro_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = _num_parents, \ + .flags = (_init_flags), \ + }, \ } -#define CLK_MUX(_name, _offset, _mask, _shift, _table, _data_flags, _parent_data, _num_parents, _init_flags) \ -struct clk _name = { \ - .data = &(struct clk_mux_data) { \ - .offset = (_offset), \ - .mask = (_mask), \ - .shift = (_shift), \ - .table = (_table), \ - .flags = (_data_flags), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = &clk_mux_ops, \ - .parent_data = (_parent_data), \ - .num_parents = (_num_parents), \ - .flags = (_init_flags), \ - }, \ +#define CLK_MUX(_name, _offset, _mask, _shift, _table, _data_flags, \ + _parent_data, _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_mux_data) { \ + .offset = (_offset), \ + .mask = (_mask), \ + .shift = (_shift), \ + .table = (_table), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_mux_ops, \ + .parent_data = (_parent_data), \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ } -#define CLK_MUX_RO(_name, _offset, _mask, _shift, _table, _data_flags, _parent_data, _num_parents, _init_flags) \ -struct clk _name = { \ - .data = &(struct clk_mux_data) { \ - .offset = (_offset), \ - .mask = (_mask), \ - .shift = (_shift), \ - .table = (_table), \ - .flags = (_data_flags), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = &clk_mux_ro_ops, \ - .parent_data = (_parent_data), \ - .num_parents = (_num_parents), \ - .flags = (_init_flags), \ - }, \ +#define CLK_MUX_RO(_name, _offset, _mask, _shift, _table, _data_flags, \ + _parent_data, _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_mux_data) { \ + .offset = (_offset), \ + .mask = (_mask), \ + .shift = (_shift), \ + .table = (_table), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_mux_ro_ops, \ + .parent_data = (_parent_data), \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ } -#define CLK_DIV(_name, _offset, _shift, _width, _data_flags, _parent_clks, _num_parents, _init_flags) \ -struct clk _name = { \ - .data = &(struct clk_div_data) { \ - .offset = (_offset), \ - .shift = (_shift), \ - .width = (_width), \ - .flags = (_data_flags), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = &clk_divider_ops, \ - .parent_clks = (const struct clk *[]) _parent_clks, \ - .num_parents = (_num_parents), \ - .flags = (_init_flags), \ - }, \ +#define CLK_DIV(_name, _offset, _shift, _width, _data_flags, _parent_clks, \ + _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_div_data) { \ + .offset = (_offset), \ + .shift = (_shift), \ + .width = (_width), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_divider_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ } -#define CLK_DIV_RO(_name, _offset, _shift, _width, _data_flags, _parent_clks, _num_parents, _init_flags) \ -struct clk _name = { \ - .data = &(struct clk_div_data) { \ - .offset = (_offset), \ - .shift = (_shift), \ - .width = (_width), \ - .flags = (_data_flags), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = &clk_divider_ro_ops, \ - .parent_clks = (const struct clk *[]) _parent_clks, \ - .num_parents = (_num_parents), \ - .flags = (_init_flags), \ - }, \ +#define CLK_DIV_RO(_name, _offset, _shift, _width, _data_flags, _parent_clks, \ + _num_parents, _init_flags) \ +struct clk _name = { \ + .data = &(struct clk_div_data) { \ + .offset = (_offset), \ + .shift = (_shift), \ + .width = (_width), \ + .flags = (_data_flags), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_divider_ro_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ } diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 61d5a22fa..60bfd0485 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -1,11 +1,12 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2010-2011 Jeremy Kerr * Copyright (C) 2011-2012 Linaro Ltd * * This file is derived from: - * https://github.com/torvalds/linux/blob/6485cf5ea253d40d507cd71253c9568c5470cd27/include/linux/clk-provider.h + * https://github.com/torvalds/linux/blob/ + * 6485cf5ea253d40d507cd71253c9568c5470cd27/include/linux/clk-provider.h */ #pragma once @@ -164,7 +165,8 @@ struct clk_hw { struct clk_ops { uint8_t (*get_parent)(const struct clk *clk); int (*set_parent)(struct clk *clk, uint8_t index); - unsigned long (*recalc_rate)(const struct clk *clk, unsigned long parent_rate); + unsigned long (*recalc_rate)(const struct clk *clk, + unsigned long parent_rate); int (*set_rate)(const struct clk *clk, uint32_t rate, uint32_t parent_rate); void (*init)(struct clk *clk); int (*enable)(struct clk *clk); @@ -236,9 +238,6 @@ struct clk_source_data { * of this register, and mask of gate bits are in higher 16-bit of this * register. While setting the gate bits, higher 16-bit should also be * updated to indicate changing gate bits. - * CLK_GATE_BIG_ENDIAN - by default little endian register accesses are used for - * the gate register. Setting this flag makes the register accesses big - * endian. */ struct clk_gate_data { uint32_t offset; @@ -281,9 +280,6 @@ struct clk_gate_data { * CLK_DIVIDER_MAX_AT_ZERO - For dividers which are like CLK_DIVIDER_ONE_BASED * except when the value read from the register is zero, the divisor is * 2^width of the field. - * CLK_DIVIDER_BIG_ENDIAN - By default little endian register accesses are used - * for the divider register. Setting this flag makes the register accesses - * big endian. */ struct clk_div_data { uint32_t offset; diff --git a/drivers/clk/imx/clk-imx.c b/drivers/clk/imx/clk-imx.c index 244a6ab33..ab3ccb801 100644 --- a/drivers/clk/imx/clk-imx.c +++ b/drivers/clk/imx/clk-imx.c @@ -1,3 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2010-2011 Canonical Ltd + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + * + * Gated clock implementation + * Source: https://github.com/torvalds/linux/blob/ + * cfaaa7d010d1fc58f9717fcc8591201e741d2d49/drivers/clk/imx/clk-gate2.c + */ + +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2018 NXP. + * + * Source: https://github.com/torvalds/linux/blob/ + * cfaaa7d010d1fc58f9717fcc8591201e741d2d49/drivers/clk/imx/clk-frac-pll.c + */ + +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright 2018 NXP. + * + * Source: https://github.com/torvalds/linux/blob/ + * cfaaa7d010d1fc58f9717fcc8591201e741d2d49/drivers/clk/imx/clk-sscg-pll.c + */ + +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2018 NXP + * + * Source: https://github.com/torvalds/linux/blob/ + * cfaaa7d010d1fc58f9717fcc8591201e741d2d49/drivers/clk/imx/clk-composite-8m.c + */ + #include #include #include @@ -35,7 +69,8 @@ const struct clk_ops clk_gate2_ops = { .is_enabled = clk_gate2_is_enabled, }; -static unsigned long clk_pll_recalc_rate(const struct clk *clk, unsigned long prate) +static unsigned long clk_pll_recalc_rate(const struct clk *clk, + unsigned long prate) { /* TODO: This function is derived from Linux codebase, but seems wrong * according to the datasheet as PLL_REFCLK_DIV_VAL[5:10] is never used. */ @@ -48,10 +83,12 @@ static unsigned long clk_pll_recalc_rate(const struct clk *clk, unsigned long pr output_div_val = (output_div_val + 1) * 2; /* Valid Frac Divider value is 1 to 2^24 */ - uint32_t frac_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 7, 24); + uint32_t frac_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 7, + 24); /* Valid Int Divider value is 1 to 32 */ - uint32_t int_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 0, 7); + uint32_t int_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 0, + 7); temp_rate *= prate; temp_rate *= frac_div_val; @@ -75,7 +112,8 @@ const struct clk_ops clk_frac_pll_ops = { /* .set_rate = clk_pll_set_rate, */ }; -static unsigned long clk_sscg_pll_recalc_rate(const struct clk *clk, unsigned long prate) +static unsigned long clk_sscg_pll_recalc_rate(const struct clk *clk, + unsigned long prate) { struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); uint64_t temp_rate = prate; @@ -116,9 +154,10 @@ static uint8_t clk_sscg_pll_get_parent(const struct clk *clk) static int clk_sscg_pll_set_parent(struct clk *clk, uint8_t index) { - /* struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); */ + // struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); - /* TODO: This operation is based on `setup.bypass` instead of index passed from callee */ + /* TODO: This operation is based on `setup.bypass` instead of index + * passed from callee, need to be decided by clock manager */ return 0; } @@ -134,21 +173,26 @@ const struct clk_ops clk_sscg_pll_ops = { /* .determine_rate = clk_sscg_pll_determine_rate, */ }; -static unsigned long imx8m_clk_core_slice_recalc_rate(const struct clk *clk, unsigned long prate) +static unsigned long imx8m_clk_core_slice_recalc_rate(const struct clk *clk, + unsigned long prate) { - struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); + struct clk_core_slice_data *data = + (struct clk_core_slice_data *)(clk->data); - uint32_t div_val = regmap_read_bits(clk->base, data->offset, data->div_shift, data->div_width); + uint32_t div_val = regmap_read_bits(clk->base, data->offset, + data->div_shift, data->div_width); /* Divider value is n+1 */ return DIV_ROUND_UP_ULL((uint64_t)prate, div_val + 1); } static uint8_t imx8m_clk_core_slice_get_parent(const struct clk *clk) { - struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); + struct clk_core_slice_data *data = + (struct clk_core_slice_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, + data->mux_shift, data->mux_mask); if (val >= num_parents) return -1; @@ -158,14 +202,17 @@ static uint8_t imx8m_clk_core_slice_get_parent(const struct clk *clk) static int imx8m_clk_core_slice_set_parent(struct clk *clk, uint8_t index) { - struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); + struct clk_core_slice_data *data = + (struct clk_core_slice_data *)(clk->data); /* * write twice to make sure non-target interface * SEL_A/B point the same clk input. */ - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, + data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, + data->mux_mask, index); return 0; } @@ -179,25 +226,32 @@ const struct clk_ops clk_core_slice_ops = { .set_parent = imx8m_clk_core_slice_set_parent, }; -static unsigned long imx8m_clk_common_slice_recalc_rate(const struct clk *clk, unsigned long prate) +static unsigned long imx8m_clk_common_slice_recalc_rate(const struct clk *clk, + unsigned long prate) { - struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); + struct clk_common_slice_data *data = + (struct clk_common_slice_data *)(clk->data); - uint32_t prediv_val = regmap_read_bits(clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); + uint32_t prediv_val = regmap_read_bits( + clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); /* Divider value is n+1 */ - unsigned long prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, prediv_val + 1); + unsigned long prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, + prediv_val + 1); - uint32_t postdiv_val = regmap_read_bits(clk->base, data->offset, data->postdiv_shift, data->postdiv_width); + uint32_t postdiv_val = regmap_read_bits( + clk->base, data->offset, data->postdiv_shift, data->postdiv_width); /* Divider value is n+1 */ return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); } static uint8_t imx8m_clk_common_slice_get_parent(const struct clk *clk) { - struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); + struct clk_common_slice_data *data = + (struct clk_common_slice_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, + data->mux_shift, data->mux_mask); if (val >= num_parents) return -1; @@ -207,14 +261,17 @@ static uint8_t imx8m_clk_common_slice_get_parent(const struct clk *clk) static int imx8m_clk_common_slice_set_parent(struct clk *clk, uint8_t index) { - struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); + struct clk_common_slice_data *data = + (struct clk_common_slice_data *)(clk->data); /* * write twice to make sure non-target interface * SEL_A/B point the same clk input. */ - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, + data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, + data->mux_mask, index); return 0; } @@ -228,15 +285,19 @@ const struct clk_ops clk_common_slice_ops = { .set_parent = imx8m_clk_common_slice_set_parent, }; -static unsigned long imx8m_clk_bus_slice_recalc_rate(const struct clk *clk, unsigned long prate) +static unsigned long imx8m_clk_bus_slice_recalc_rate(const struct clk *clk, + unsigned long prate) { struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); - uint32_t prediv_val = regmap_read_bits(clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); + uint32_t prediv_val = regmap_read_bits( + clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); /* Divider value is n+1 */ - unsigned long prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, prediv_val + 1); + unsigned long prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, + prediv_val + 1); - uint32_t postdiv_val = regmap_read_bits(clk->base, data->offset, data->postdiv_shift, data->postdiv_width); + uint32_t postdiv_val = regmap_read_bits( + clk->base, data->offset, data->postdiv_shift, data->postdiv_width); /* Divider value is n+1 */ return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); } @@ -246,7 +307,8 @@ static uint8_t imx8m_clk_bus_slice_get_parent(const struct clk *clk) struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, + data->mux_shift, data->mux_mask); if (val >= num_parents) return -1; @@ -262,8 +324,10 @@ static int imx8m_clk_bus_slice_set_parent(struct clk *clk, uint8_t index) * write twice to make sure non-target interface * SEL_A/B point the same clk input. */ - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, + data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, + data->mux_mask, index); return 0; } diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 98fdd2346..78a3807b6 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -1,8 +1,7 @@ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* - * Copyright 2017-2018 NXP. - * - * Derived from: https://github.com/torvalds/linux/blob/75b607fab38d149f232f01eae5e6392b394dd659/drivers/clk/imx/clk-imx8mm.c + * Copyright 2018 NXP. + * Copyright (C) 2017 Pengutronix, Lucas Stach */ #include @@ -2383,58 +2382,88 @@ static IMX_CLK_SOURCE(clk_ext2, 0x7ed6b40); static IMX_CLK_SOURCE(clk_ext3, 0x7ed6b40); static IMX_CLK_SOURCE(clk_ext4, 0x7ed6b40); -static IMX_CLK_MUX(arm_pll_ref_sel, CCM_ANALOG_BASE, 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(gpu_pll_ref_sel, CCM_ANALOG_BASE, 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(vpu_pll_ref_sel, CCM_ANALOG_BASE, 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(audio_pll1_ref_sel, CCM_ANALOG_BASE, 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(audio_pll2_ref_sel, CCM_ANALOG_BASE, 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(video_pll1_ref_sel, CCM_ANALOG_BASE, 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(sys3_pll1_ref_sel, CCM_ANALOG_BASE, 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(dram_pll1_ref_sel, CCM_ANALOG_BASE, 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(video2_pll1_ref_sel, CCM_ANALOG_BASE, 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - -static IMX_CLK_DIV(arm_pll_ref_div, { &arm_pll_ref_sel }, CCM_ANALOG_BASE, 0x28, 5, 6); -static IMX_CLK_DIV(gpu_pll_ref_div, { &gpu_pll_ref_sel }, CCM_ANALOG_BASE, 0x18, 5, 6); -static IMX_CLK_DIV(vpu_pll_ref_div, { &vpu_pll_ref_sel }, CCM_ANALOG_BASE, 0x20, 5, 6); -static IMX_CLK_DIV(audio_pll1_ref_div, { &audio_pll1_ref_sel }, CCM_ANALOG_BASE, 0x0, 5, 6); -static IMX_CLK_DIV(audio_pll2_ref_div, { &audio_pll2_ref_sel }, CCM_ANALOG_BASE, 0x8, 5, 6); -static IMX_CLK_DIV(video_pll1_ref_div, { &video_pll1_ref_sel }, CCM_ANALOG_BASE, 0x10, 5, 6); +static IMX_CLK_MUX(arm_pll_ref_sel, CCM_ANALOG_BASE, 0x28, 16, 2, pll_ref_sels, + ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(gpu_pll_ref_sel, CCM_ANALOG_BASE, 0x18, 16, 2, pll_ref_sels, + ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(vpu_pll_ref_sel, CCM_ANALOG_BASE, 0x20, 16, 2, pll_ref_sels, + ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(audio_pll1_ref_sel, CCM_ANALOG_BASE, 0x0, 16, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(audio_pll2_ref_sel, CCM_ANALOG_BASE, 0x8, 16, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(video_pll1_ref_sel, CCM_ANALOG_BASE, 0x10, 16, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(sys3_pll1_ref_sel, CCM_ANALOG_BASE, 0x48, 0, 2, pll_ref_sels, + ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(dram_pll1_ref_sel, CCM_ANALOG_BASE, 0x60, 0, 2, pll_ref_sels, + ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(video2_pll1_ref_sel, CCM_ANALOG_BASE, 0x54, 0, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + +static IMX_CLK_DIV(arm_pll_ref_div, { &arm_pll_ref_sel }, CCM_ANALOG_BASE, 0x28, + 5, 6); +static IMX_CLK_DIV(gpu_pll_ref_div, { &gpu_pll_ref_sel }, CCM_ANALOG_BASE, 0x18, + 5, 6); +static IMX_CLK_DIV(vpu_pll_ref_div, { &vpu_pll_ref_sel }, CCM_ANALOG_BASE, 0x20, + 5, 6); +static IMX_CLK_DIV(audio_pll1_ref_div, { &audio_pll1_ref_sel }, CCM_ANALOG_BASE, + 0x0, 5, 6); +static IMX_CLK_DIV(audio_pll2_ref_div, { &audio_pll2_ref_sel }, CCM_ANALOG_BASE, + 0x8, 5, 6); +static IMX_CLK_DIV(video_pll1_ref_div, { &video_pll1_ref_sel }, CCM_ANALOG_BASE, + 0x10, 5, 6); static IMX_CLK_FRAC_PLL(arm_pll, { &arm_pll_ref_div }, CCM_ANALOG_BASE, 0x28); static IMX_CLK_FRAC_PLL(gpu_pll, { &gpu_pll_ref_div }, CCM_ANALOG_BASE, 0x18); static IMX_CLK_FRAC_PLL(vpu_pll, { &vpu_pll_ref_div }, CCM_ANALOG_BASE, 0x20); -static IMX_CLK_FRAC_PLL(audio_pll1, { &audio_pll1_ref_div }, CCM_ANALOG_BASE, 0x0); -static IMX_CLK_FRAC_PLL(audio_pll2, { &audio_pll2_ref_div }, CCM_ANALOG_BASE, 0x8); -static IMX_CLK_FRAC_PLL(video_pll1, { &video_pll1_ref_div }, CCM_ANALOG_BASE, 0x10); +static IMX_CLK_FRAC_PLL(audio_pll1, { &audio_pll1_ref_div }, CCM_ANALOG_BASE, + 0x0); +static IMX_CLK_FRAC_PLL(audio_pll2, { &audio_pll2_ref_div }, CCM_ANALOG_BASE, + 0x8); +static IMX_CLK_FRAC_PLL(video_pll1, { &video_pll1_ref_div }, CCM_ANALOG_BASE, + 0x10); /* PLL bypass out */ -static IMX_CLK_MUX_FLAGS(arm_pll_bypass, CCM_ANALOG_BASE, 0x28, 14, 1, arm_pll_bypass_sels, - ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); -static IMX_CLK_MUX(gpu_pll_bypass, CCM_ANALOG_BASE, 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels)); -static IMX_CLK_MUX(vpu_pll_bypass, CCM_ANALOG_BASE, 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels)); -static IMX_CLK_MUX(audio_pll1_bypass, CCM_ANALOG_BASE, 0x0, 14, 1, audio_pll1_bypass_sels, - ARRAY_SIZE(audio_pll1_bypass_sels)); -static IMX_CLK_MUX(audio_pll2_bypass, CCM_ANALOG_BASE, 0x8, 14, 1, audio_pll2_bypass_sels, - ARRAY_SIZE(audio_pll2_bypass_sels)); -static IMX_CLK_MUX(video_pll1_bypass, CCM_ANALOG_BASE, 0x10, 14, 1, video_pll1_bypass_sels, - ARRAY_SIZE(video_pll1_bypass_sels)); +static IMX_CLK_MUX_FLAGS(arm_pll_bypass, CCM_ANALOG_BASE, 0x28, 14, 1, + arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), + CLK_SET_RATE_PARENT); +static IMX_CLK_MUX(gpu_pll_bypass, CCM_ANALOG_BASE, 0x18, 14, 1, + gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels)); +static IMX_CLK_MUX(vpu_pll_bypass, CCM_ANALOG_BASE, 0x20, 14, 1, + vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels)); +static IMX_CLK_MUX(audio_pll1_bypass, CCM_ANALOG_BASE, 0x0, 14, 1, + audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels)); +static IMX_CLK_MUX(audio_pll2_bypass, CCM_ANALOG_BASE, 0x8, 14, 1, + audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels)); +static IMX_CLK_MUX(video_pll1_bypass, CCM_ANALOG_BASE, 0x10, 14, 1, + video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels)); /* PLL OUT GATE */ -static IMX_CLK_GATE(arm_pll_out, { &arm_pll_bypass }, CCM_ANALOG_BASE, 0x28, 21); -static IMX_CLK_GATE(gpu_pll_out, { &gpu_pll_bypass }, CCM_ANALOG_BASE, 0x18, 21); -static IMX_CLK_GATE(vpu_pll_out, { &vpu_pll_bypass }, CCM_ANALOG_BASE, 0x20, 21); -static IMX_CLK_GATE(audio_pll1_out, { &audio_pll1_bypass }, CCM_ANALOG_BASE, 0x0, 21); -static IMX_CLK_GATE(audio_pll2_out, { &audio_pll2_bypass }, CCM_ANALOG_BASE, 0x8, 21); -static IMX_CLK_GATE(video_pll1_out, { &video_pll1_bypass }, CCM_ANALOG_BASE, 0x10, 21); +static IMX_CLK_GATE(arm_pll_out, { &arm_pll_bypass }, CCM_ANALOG_BASE, 0x28, + 21); +static IMX_CLK_GATE(gpu_pll_out, { &gpu_pll_bypass }, CCM_ANALOG_BASE, 0x18, + 21); +static IMX_CLK_GATE(vpu_pll_out, { &vpu_pll_bypass }, CCM_ANALOG_BASE, 0x20, + 21); +static IMX_CLK_GATE(audio_pll1_out, { &audio_pll1_bypass }, CCM_ANALOG_BASE, + 0x0, 21); +static IMX_CLK_GATE(audio_pll2_out, { &audio_pll2_bypass }, CCM_ANALOG_BASE, + 0x8, 21); +static IMX_CLK_GATE(video_pll1_out, { &video_pll1_bypass }, CCM_ANALOG_BASE, + 0x10, 21); static IMX_CLK_FIXED(sys1_pll_out, 800000000); static IMX_CLK_FIXED(sys2_pll_out, 1000000000); -static IMX_CLK_SSCG_PLL(sys3_pll_out, sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x48, - CLK_IS_CRITICAL); -static IMX_CLK_SSCG_PLL(dram_pll_out, dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x60, - CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); -static IMX_CLK_SSCG_PLL(video2_pll_out, video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, - 0x54, 0); +static IMX_CLK_SSCG_PLL(sys3_pll_out, sys3_pll_out_sels, + ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, + 0x48, CLK_IS_CRITICAL); +static IMX_CLK_SSCG_PLL(dram_pll_out, dram_pll_out_sels, + ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, + 0x60, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); +static IMX_CLK_SSCG_PLL(video2_pll_out, video2_pll_out_sels, + ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, + CCM_ANALOG_BASE, 0x54, 0); /* SYS PLL1 fixed output */ static IMX_CLK_FIXED_FACTOR(sys1_pll_40m, { &sys1_pll_out }, 1, 20); @@ -2458,40 +2487,56 @@ static IMX_CLK_FIXED_FACTOR(sys2_pll_333m, { &sys2_pll_out }, 1, 3); static IMX_CLK_FIXED_FACTOR(sys2_pll_500m, { &sys2_pll_out }, 1, 2); static IMX_CLK_FIXED_FACTOR(sys2_pll_1000m, { &sys2_pll_out }, 1, 1); -static IMX_CLK_DIV(audio_pll1_out_monitor, { &audio_pll1_bypass }, CCM_ANALOG_BASE, 0x78, 0, 3); -static IMX_CLK_DIV(audio_pll2_out_monitor, { &audio_pll2_bypass }, CCM_ANALOG_BASE, 0x78, 4, 3); -static IMX_CLK_DIV(video_pll1_out_monitor, { &video_pll1_bypass }, CCM_ANALOG_BASE, 0x78, 8, 3); -static IMX_CLK_DIV(gpu_pll_out_monitor, { &gpu_pll_bypass }, CCM_ANALOG_BASE, 0x78, 12, 3); -static IMX_CLK_DIV(vpu_pll_out_monitor, { &vpu_pll_bypass }, CCM_ANALOG_BASE, 0x78, 16, 3); -static IMX_CLK_DIV(arm_pll_out_monitor, { &arm_pll_bypass }, CCM_ANALOG_BASE, 0x78, 20, 3); -static IMX_CLK_DIV(sys_pll1_out_monitor, { &sys1_pll_out }, CCM_ANALOG_BASE, 0x7c, 0, 3); -static IMX_CLK_DIV(sys_pll2_out_monitor, { &sys2_pll_out }, CCM_ANALOG_BASE, 0x7c, 4, 3); -static IMX_CLK_DIV(sys_pll3_out_monitor, { &sys3_pll_out }, CCM_ANALOG_BASE, 0x7c, 8, 3); -static IMX_CLK_DIV(dram_pll_out_monitor, { &dram_pll_out }, CCM_ANALOG_BASE, 0x7c, 12, 3); -static IMX_CLK_DIV(video_pll2_out_monitor, { &video2_pll_out }, CCM_ANALOG_BASE, 0x7c, 16, 3); -static IMX_CLK_MUX(pllout_monitor_sel, CCM_ANALOG_BASE, 0x74, 0, 4, pllout_monitor_sels, - ARRAY_SIZE(pllout_monitor_sels)); -static IMX_CLK_GATE(pllout_monitor_clk2, { &pllout_monitor_sel }, CCM_ANALOG_BASE, 0x74, 4); +static IMX_CLK_DIV(audio_pll1_out_monitor, { &audio_pll1_bypass }, + CCM_ANALOG_BASE, 0x78, 0, 3); +static IMX_CLK_DIV(audio_pll2_out_monitor, { &audio_pll2_bypass }, + CCM_ANALOG_BASE, 0x78, 4, 3); +static IMX_CLK_DIV(video_pll1_out_monitor, { &video_pll1_bypass }, + CCM_ANALOG_BASE, 0x78, 8, 3); +static IMX_CLK_DIV(gpu_pll_out_monitor, { &gpu_pll_bypass }, CCM_ANALOG_BASE, + 0x78, 12, 3); +static IMX_CLK_DIV(vpu_pll_out_monitor, { &vpu_pll_bypass }, CCM_ANALOG_BASE, + 0x78, 16, 3); +static IMX_CLK_DIV(arm_pll_out_monitor, { &arm_pll_bypass }, CCM_ANALOG_BASE, + 0x78, 20, 3); +static IMX_CLK_DIV(sys_pll1_out_monitor, { &sys1_pll_out }, CCM_ANALOG_BASE, + 0x7c, 0, 3); +static IMX_CLK_DIV(sys_pll2_out_monitor, { &sys2_pll_out }, CCM_ANALOG_BASE, + 0x7c, 4, 3); +static IMX_CLK_DIV(sys_pll3_out_monitor, { &sys3_pll_out }, CCM_ANALOG_BASE, + 0x7c, 8, 3); +static IMX_CLK_DIV(dram_pll_out_monitor, { &dram_pll_out }, CCM_ANALOG_BASE, + 0x7c, 12, 3); +static IMX_CLK_DIV(video_pll2_out_monitor, { &video2_pll_out }, CCM_ANALOG_BASE, + 0x7c, 16, 3); +static IMX_CLK_MUX(pllout_monitor_sel, CCM_ANALOG_BASE, 0x74, 0, 4, + pllout_monitor_sels, ARRAY_SIZE(pllout_monitor_sels)); +static IMX_CLK_GATE(pllout_monitor_clk2, { &pllout_monitor_sel }, + CCM_ANALOG_BASE, 0x74, 4); /* CORE */ static IMX_CLK_COMPOSITE_CORE(arm_a53_div, imx8mq_a53_sels, CCM_BASE, 0x8000); -static IMX_CLK_COMPOSITE_CORE(arm_m4_core, imx8mq_arm_m4_sels, CCM_BASE, 0x8080); +static IMX_CLK_COMPOSITE_CORE(arm_m4_core, imx8mq_arm_m4_sels, CCM_BASE, + 0x8080); static IMX_CLK_COMPOSITE_CORE(vpu_core, imx8mq_vpu_sels, CCM_BASE, 0x8100); static IMX_CLK_COMPOSITE_CORE(gpu_core, imx8mq_gpu_core_sels, CCM_BASE, 0x8180); static IMX_CLK_COMPOSITE(gpu_shader, imx8mq_gpu_shader_sels, CCM_BASE, 0x8200); /* CORE SEL */ -static IMX_CLK_MUX2(arm_a53_core, CCM_BASE, 0x9880, 24, 1, imx8mq_a53_core_sels, ARRAY_SIZE(imx8mq_a53_core_sels)); +static IMX_CLK_MUX2(arm_a53_core, CCM_BASE, 0x9880, 24, 1, imx8mq_a53_core_sels, + ARRAY_SIZE(imx8mq_a53_core_sels)); /* BUS */ static IMX_CLK_COMPOSITE_BUS(main_axi, imx8mq_main_axi_sels, CCM_BASE, 0x8800); static IMX_CLK_COMPOSITE_BUS(enet_axi, imx8mq_enet_axi_sels, CCM_BASE, 0x8880); -static IMX_CLK_COMPOSITE_BUS(nand_usdhc_bus, imx8mq_nand_usdhc_sels, CCM_BASE, 0x8900); +static IMX_CLK_COMPOSITE_BUS(nand_usdhc_bus, imx8mq_nand_usdhc_sels, CCM_BASE, + 0x8900); static IMX_CLK_COMPOSITE_BUS(vpu_bus, imx8mq_vpu_bus_sels, CCM_BASE, 0x8980); static IMX_CLK_COMPOSITE_BUS(disp_axi, imx8mq_disp_axi_sels, CCM_BASE, 0x8a00); static IMX_CLK_COMPOSITE_BUS(disp_apb, imx8mq_disp_apb_sels, CCM_BASE, 0x8a80); -static IMX_CLK_COMPOSITE_BUS(disp_rtrm, imx8mq_disp_rtrm_sels, CCM_BASE, 0x8b00); +static IMX_CLK_COMPOSITE_BUS(disp_rtrm, imx8mq_disp_rtrm_sels, CCM_BASE, + 0x8b00); static IMX_CLK_COMPOSITE_BUS(usb_bus, imx8mq_usb_bus_sels, CCM_BASE, 0x8b80); static IMX_CLK_COMPOSITE_BUS(gpu_axi, imx8mq_gpu_axi_sels, CCM_BASE, 0x8c00); static IMX_CLK_COMPOSITE_BUS(gpu_ahb, imx8mq_gpu_ahb_sels, CCM_BASE, 0x8c80); @@ -2501,7 +2546,8 @@ static IMX_CLK_COMPOSITE_BUS(noc_apb, imx8mq_noc_apb_sels, CCM_BASE, 0x8d80); /* AHB */ /* AHB clock is used by the AHB bus therefore marked as critical */ static IMX_CLK_COMPOSITE_BUS(ahb, imx8mq_ahb_sels, CCM_BASE, 0x9000); -static IMX_CLK_COMPOSITE_BUS(audio_ahb, imx8mq_audio_ahb_sels, CCM_BASE, 0x9100); +static IMX_CLK_COMPOSITE_BUS(audio_ahb, imx8mq_audio_ahb_sels, CCM_BASE, + 0x9100); /* IPG */ static IMX_CLK_DIV2(ipg_root, { &ahb }, CCM_BASE, 0x9080, 0, 1); @@ -2512,21 +2558,26 @@ static IMX_CLK_DIV2(ipg_audio_root, { &audio_ahb }, CCM_BASE, 0x9180, 0, 1); * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE * as div value should always be read from hardware */ -static IMX_CLK_MUX2_FLAGS(dram_core_clk, CCM_BASE, 0x9800, 24, 1, imx8mq_dram_core_sels, +static IMX_CLK_MUX2_FLAGS(dram_core_clk, CCM_BASE, 0x9800, 24, 1, + imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL); -static IMX_CLK_COMPOSITE_FW_MANAGED(dram_alt, imx8mq_dram_alt_sels, CCM_BASE, 0xa000); -static IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(dram_apb, imx8mq_dram_apb_sels, CCM_BASE, 0xa080); +static IMX_CLK_COMPOSITE_FW_MANAGED(dram_alt, imx8mq_dram_alt_sels, CCM_BASE, + 0xa000); +static IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(dram_apb, imx8mq_dram_apb_sels, + CCM_BASE, 0xa080); /* IP */ static IMX_CLK_COMPOSITE(vpu_g1, imx8mq_vpu_g1_sels, CCM_BASE, 0xa100); static IMX_CLK_COMPOSITE(vpu_g2, imx8mq_vpu_g2_sels, CCM_BASE, 0xa180); static IMX_CLK_COMPOSITE(disp_dtrc, imx8mq_disp_dtrc_sels, CCM_BASE, 0xa200); -static IMX_CLK_COMPOSITE(disp_dc8000, imx8mq_disp_dc8000_sels, CCM_BASE, 0xa280); +static IMX_CLK_COMPOSITE(disp_dc8000, imx8mq_disp_dc8000_sels, CCM_BASE, + 0xa280); static IMX_CLK_COMPOSITE(pcie1_ctrl, imx8mq_pcie1_ctrl_sels, CCM_BASE, 0xa300); static IMX_CLK_COMPOSITE(pcie1_phy, imx8mq_pcie1_phy_sels, CCM_BASE, 0xa380); static IMX_CLK_COMPOSITE(pcie1_aux, imx8mq_pcie1_aux_sels, CCM_BASE, 0xa400); static IMX_CLK_COMPOSITE(dc_pixel, imx8mq_dc_pixel_sels, CCM_BASE, 0xa480); -static IMX_CLK_COMPOSITE(lcdif_pixel, imx8mq_lcdif_pixel_sels, CCM_BASE, 0xa500); +static IMX_CLK_COMPOSITE(lcdif_pixel, imx8mq_lcdif_pixel_sels, CCM_BASE, + 0xa500); static IMX_CLK_COMPOSITE(sai1, imx8mq_sai1_sels, CCM_BASE, 0xa580); static IMX_CLK_COMPOSITE(sai2, imx8mq_sai2_sels, CCM_BASE, 0xa600); static IMX_CLK_COMPOSITE(sai3, imx8mq_sai3_sels, CCM_BASE, 0xa680); @@ -2605,20 +2656,34 @@ static IMX_CLK_GATE4(pwm3_root_clk, { &pwm3 }, CCM_BASE, 0x42a0, 0); static IMX_CLK_GATE4(pwm4_root_clk, { &pwm4 }, CCM_BASE, 0x42b0, 0); static IMX_CLK_GATE4(qspi_root_clk, { &qspi }, CCM_BASE, 0x42f0, 0); -static IMX_CLK_GATE2_SHARED2(nand_root_clk, { &nand }, CCM_BASE, 0x4300, 0, &share_count_nand); -static IMX_CLK_GATE2_SHARED2(nand_usdhc_rawnand_clk, { &nand_usdhc_bus }, CCM_BASE, 0x4300, 0, &share_count_nand); -static IMX_CLK_GATE2_SHARED2(sai1_root_clk, { &sai1 }, CCM_BASE, 0x4330, 0, &share_count_sai1); -static IMX_CLK_GATE2_SHARED2(sai1_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4330, 0, &share_count_sai1); -static IMX_CLK_GATE2_SHARED2(sai2_root_clk, { &sai2 }, CCM_BASE, 0x4340, 0, &share_count_sai2); -static IMX_CLK_GATE2_SHARED2(sai2_ipg_clk, { &ipg_root }, CCM_BASE, 0x4340, 0, &share_count_sai2); -static IMX_CLK_GATE2_SHARED2(sai3_root_clk, { &sai3 }, CCM_BASE, 0x4350, 0, &share_count_sai3); -static IMX_CLK_GATE2_SHARED2(sai3_ipg_clk, { &ipg_root }, CCM_BASE, 0x4350, 0, &share_count_sai3); -static IMX_CLK_GATE2_SHARED2(sai4_root_clk, { &sai4 }, CCM_BASE, 0x4360, 0, &share_count_sai4); -static IMX_CLK_GATE2_SHARED2(sai4_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4360, 0, &share_count_sai4); -static IMX_CLK_GATE2_SHARED2(sai5_root_clk, { &sai5 }, CCM_BASE, 0x4370, 0, &share_count_sai5); -static IMX_CLK_GATE2_SHARED2(sai5_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4370, 0, &share_count_sai5); -static IMX_CLK_GATE2_SHARED2(sai6_root_clk, { &sai6 }, CCM_BASE, 0x4380, 0, &share_count_sai6); -static IMX_CLK_GATE2_SHARED2(sai6_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4380, 0, &share_count_sai6); +static IMX_CLK_GATE2_SHARED2(nand_root_clk, { &nand }, CCM_BASE, 0x4300, 0, + &share_count_nand); +static IMX_CLK_GATE2_SHARED2(nand_usdhc_rawnand_clk, { &nand_usdhc_bus }, + CCM_BASE, 0x4300, 0, &share_count_nand); +static IMX_CLK_GATE2_SHARED2(sai1_root_clk, { &sai1 }, CCM_BASE, 0x4330, 0, + &share_count_sai1); +static IMX_CLK_GATE2_SHARED2(sai1_ipg_clk, { &ipg_audio_root }, CCM_BASE, + 0x4330, 0, &share_count_sai1); +static IMX_CLK_GATE2_SHARED2(sai2_root_clk, { &sai2 }, CCM_BASE, 0x4340, 0, + &share_count_sai2); +static IMX_CLK_GATE2_SHARED2(sai2_ipg_clk, { &ipg_root }, CCM_BASE, 0x4340, 0, + &share_count_sai2); +static IMX_CLK_GATE2_SHARED2(sai3_root_clk, { &sai3 }, CCM_BASE, 0x4350, 0, + &share_count_sai3); +static IMX_CLK_GATE2_SHARED2(sai3_ipg_clk, { &ipg_root }, CCM_BASE, 0x4350, 0, + &share_count_sai3); +static IMX_CLK_GATE2_SHARED2(sai4_root_clk, { &sai4 }, CCM_BASE, 0x4360, 0, + &share_count_sai4); +static IMX_CLK_GATE2_SHARED2(sai4_ipg_clk, { &ipg_audio_root }, CCM_BASE, + 0x4360, 0, &share_count_sai4); +static IMX_CLK_GATE2_SHARED2(sai5_root_clk, { &sai5 }, CCM_BASE, 0x4370, 0, + &share_count_sai5); +static IMX_CLK_GATE2_SHARED2(sai5_ipg_clk, { &ipg_audio_root }, CCM_BASE, + 0x4370, 0, &share_count_sai5); +static IMX_CLK_GATE2_SHARED2(sai6_root_clk, { &sai6 }, CCM_BASE, 0x4380, 0, + &share_count_sai6); +static IMX_CLK_GATE2_SHARED2(sai6_ipg_clk, { &ipg_audio_root }, CCM_BASE, + 0x4380, 0, &share_count_sai6); static IMX_CLK_GATE4(uart1_root_clk, { &uart1 }, CCM_BASE, 0x4490, 0); static IMX_CLK_GATE4(uart2_root_clk, { &uart2 }, CCM_BASE, 0x44a0, 0); static IMX_CLK_GATE4(uart3_root_clk, { &uart3 }, CCM_BASE, 0x44b0, 0); @@ -2637,10 +2702,14 @@ static IMX_CLK_GATE2_FLAGS(vpu_g1_root_clk, { &vpu_g1 }, CCM_BASE, 0x4560, 0, static IMX_CLK_GATE4(gpu_root_clk, { &gpu_core }, CCM_BASE, 0x4570, 0); static IMX_CLK_GATE2_FLAGS(vpu_g2_root_clk, { &vpu_g2 }, CCM_BASE, 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); -static IMX_CLK_GATE2_SHARED2(disp_root_clk, { &disp_dc8000 }, CCM_BASE, 0x45d0, 0, &share_count_dcss); -static IMX_CLK_GATE2_SHARED2(disp_axi_root_clk, { &disp_axi }, CCM_BASE, 0x45d0, 0, &share_count_dcss); -static IMX_CLK_GATE2_SHARED2(disp_apb_root_clk, { &disp_apb }, CCM_BASE, 0x45d0, 0, &share_count_dcss); -static IMX_CLK_GATE2_SHARED2(disp_rtrm_root_clk, { &disp_rtrm }, CCM_BASE, 0x45d0, 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_root_clk, { &disp_dc8000 }, CCM_BASE, 0x45d0, + 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_axi_root_clk, { &disp_axi }, CCM_BASE, 0x45d0, + 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_apb_root_clk, { &disp_apb }, CCM_BASE, 0x45d0, + 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_rtrm_root_clk, { &disp_rtrm }, CCM_BASE, + 0x45d0, 0, &share_count_dcss); static IMX_CLK_GATE4(tmu_root_clk, { &ipg_root }, CCM_BASE, 0x4620, 0); static IMX_CLK_GATE2_FLAGS(vpu_dec_root_clk, { &vpu_bus }, CCM_BASE, 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index d908a3abb..d17b3cae9 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -83,7 +83,8 @@ const struct clk *get_parent(const struct clk *clk) if (parent_data.clk) { return parent_data.clk; - } else if (parent_data.name) { + } + if (parent_data.name) { return get_clk_by_name(parent_data.name); } } @@ -169,7 +170,8 @@ uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) if (clk->hw.init->ops->set_rate) { *rate = clk->hw.init->ops->set_rate(clk, req_rate, prate); return 0; - } else if (pclk && pclk->hw.init->ops->set_rate) { + } + if (pclk && pclk->hw.init->ops->set_rate) { const struct clk *ppclk = get_parent(pclk); uint64_t pprate = 0; uint32_t err = clk_get_rate(ppclk, &pprate); @@ -195,9 +197,11 @@ int clk_msr_stat() if (clk_list[i]) { err = clk_get_rate(clk_list[i], &rate); if (err) { - LOG_DRIVER_ERR("Failed to get rate of %s: -%u\n", clk_list[i]->hw.init->name, err); + LOG_DRIVER_ERR("Failed to get rate of %s: -%u\n", + clk_list[i]->hw.init->name, err); } - LOG_DRIVER("[%4d][%10luHz] %s\n", i, rate, clk_list[i]->hw.init->name); + LOG_DRIVER("[%4d][%10luHz] %s\n", i, rate, + clk_list[i]->hw.init->name); } } LOG_DRIVER("-----------------------------\n"); diff --git a/drivers/clk/imx/clk_driver.mk b/drivers/clk/imx/clk_driver.mk index bfb9012fd..b4d906d8e 100644 --- a/drivers/clk/imx/clk_driver.mk +++ b/drivers/clk/imx/clk_driver.mk @@ -24,7 +24,7 @@ $(CLK_DRIVER_OBJS): ${CLK_DRIVER_COMMON_DIR}/*.c ${CLK_DRIVER_DIR}/*.c $(CLK_CON -I${UART_DRIVER_DIR}/include \ -I${CLK_DRIVER_COMMON_DIR} $^ -$(CLK_CONFIG_HEADER): $(DTS_FILE) +$(CLK_CONFIG_HEADER): $(DTS_FILE) $(CLK_DRIVER_COMMON_DIR)/create_clk_config.py $(PYTHON) $(CLK_DRIVER_COMMON_DIR)/create_clk_config.py $(DTS_FILE) $(BUILD_DIR) clean:: diff --git a/drivers/clk/imx/include/clk-imx.h b/drivers/clk/imx/include/clk-imx.h index 60723260c..db012ba42 100644 --- a/drivers/clk/imx/include/clk-imx.h +++ b/drivers/clk/imx/include/clk-imx.h @@ -1,3 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2010-2011 Canonical Ltd + * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd + * + * Gated clock implementation + * Source: https://github.com/torvalds/linux/blob/ + * cfaaa7d010d1fc58f9717fcc8591201e741d2d49/drivers/clk/imx/clk-gate2.c + */ + +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2018 NXP. + * + * Source: https://github.com/torvalds/linux/blob/ + * cfaaa7d010d1fc58f9717fcc8591201e741d2d49/drivers/clk/imx/clk-frac-pll.c + */ + +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright 2018 NXP. + * + * Source: https://github.com/torvalds/linux/blob/ + * cfaaa7d010d1fc58f9717fcc8591201e741d2d49/drivers/clk/imx/clk-sscg-pll.c + */ + +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2018 NXP + * + * Source: https://github.com/torvalds/linux/blob/ + * cfaaa7d010d1fc58f9717fcc8591201e741d2d49/drivers/clk/imx/clk-composite-8m.c + */ #pragma once #include @@ -121,36 +154,41 @@ struct clk _name = { \ #define IMX_CLK_FIXED(_name, _rate) \ IMX_CLK_SOURCE(_name, _rate) -#define IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, _parent_data, _num_parents, _init_flags) \ -struct clk _name = { \ - .base = (_base), \ - .data = &(struct clk_mux_data) { \ - .offset = (_offset), \ - .mask = MASK(_width), \ - .shift = (_shift), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = &clk_mux_ops, \ - .parent_data = (_parent_data), \ - .num_parents = (_num_parents), \ - .flags = (_init_flags), \ - }, \ +#define IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, _parent_data, \ + _num_parents, _init_flags) \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_mux_data) { \ + .offset = (_offset), \ + .mask = MASK(_width), \ + .shift = (_shift), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_mux_ops, \ + .parent_data = (_parent_data), \ + .num_parents = (_num_parents), \ + .flags = (_init_flags), \ + }, \ } -#define IMX_CLK_MUX(_name, _base, _offset, _shift, _width, _parent_data, _num_parents) \ -IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ +#define IMX_CLK_MUX(_name, _base, _offset, _shift, _width, _parent_data, \ + _num_parents) \ +IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ _parent_data, _num_parents, 0) -#define IMX_CLK_MUX2(_name, _base, _offset, _shift, _width, _parent_data, _num_parents) \ +#define IMX_CLK_MUX2(_name, _base, _offset, _shift, _width, _parent_data, \ + _num_parents) \ IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ _parent_data, _num_parents, CLK_OPS_PARENT_ENABLE) -#define IMX_CLK_MUX2_FLAGS(_name, _base, _offset, _shift, _width, _parent_data, _num_parents, _flags) \ -IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ +#define IMX_CLK_MUX2_FLAGS(_name, _base, _offset, _shift, _width, \ + _parent_data, _num_parents, _flags) \ +IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ _parent_data, _num_parents, _flags | CLK_OPS_PARENT_ENABLE) -#define IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, _width, _flags) \ +#define IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, _width, \ + _flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_div_data) { \ @@ -167,25 +205,25 @@ struct clk _name = { \ }, \ } -#define IMX_CLK_DIV(_name, _parent_clks, _base, _offset, _shift, _width) \ +#define IMX_CLK_DIV(_name, _parent_clks, _base, _offset, _shift, _width) \ IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, _width, 0) -#define IMX_CLK_DIV2(_name, _parent_clks, _base, _offset, _shift, _width) \ -IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, \ +#define IMX_CLK_DIV2(_name, _parent_clks, _base, _offset, _shift, _width) \ +IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, \ _width, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE) #define IMX_CLK_FRAC_PLL(_name, _parent_clks, _base, _offset) \ -struct clk _name = { \ - .base = (_base), \ - .data = &(struct clk_frac_pll_data) { \ - .offset = (_offset), \ - }, \ - .hw.init = &(struct clk_init_data) { \ - .name = #_name, \ - .ops = &clk_frac_pll_ops, \ - .parent_clks = (const struct clk *[]) _parent_clks, \ - .num_parents = 1, \ - }, \ +struct clk _name = { \ + .base = (_base), \ + .data = &(struct clk_frac_pll_data) { \ + .offset = (_offset), \ + }, \ + .hw.init = &(struct clk_init_data) { \ + .name = #_name, \ + .ops = &clk_frac_pll_ops, \ + .parent_clks = (const struct clk *[]) _parent_clks, \ + .num_parents = 1, \ + }, \ } #define IMX_CLK_GATE1(_name, _parent_clks, _base, _offset, _shift) \ @@ -206,7 +244,8 @@ struct clk _name = { \ }, \ } -#define IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, _flags) \ +#define IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, \ + _flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_gate_data) { \ @@ -221,16 +260,18 @@ struct clk _name = { \ }, \ } -#define IMX_CLK_GATE2_SHARED2(_name, _parent_clks, _base, _offset, _shift, _shared_count) \ +#define IMX_CLK_GATE2_SHARED2(_name, _parent_clks, _base, _offset, _shift, \ + _shared_count) \ IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, 0) -#define IMX_CLK_GATE4(_name, _parent_clks, _base, _offset, _shift) \ +#define IMX_CLK_GATE4(_name, _parent_clks, _base, _offset, _shift) \ IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, 0) #define IMX_CLK_FIXED_FACTOR(_name, _parent_clks, _mult, _div) \ CLK_FIXED_FACTOR(_name, _mult, _div, 0, _parent_clks, 1, CLK_SET_RATE_PARENT) -#define IMX_CLK_SSCG_PLL(_name, _parent_data, _num_parents, _parent, _bypass1, _bypass2, _base, _offset, _flags) \ +#define IMX_CLK_SSCG_PLL(_name, _parent_data, _num_parents, _parent, _bypass1, \ + _bypass2, _base, _offset, _flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_sscg_pll_data) { \ @@ -277,8 +318,8 @@ struct clk _name = { \ .offset = (_offset), \ .mux_shift = PCG_PCS_SHIFT, \ .mux_mask = PCG_PCS_MASK, \ - .prevdiv_shift = PCG_PREDIV_SHIFT, \ - .prevdiv_width = PCG_PREDIV_WIDTH, \ + .prevdiv_shift = PCG_PREDIV_SHIFT, \ + .prevdiv_width = PCG_PREDIV_WIDTH, \ .postdiv_shift = PCG_DIV_SHIFT, \ .postdiv_width = PCG_DIV_WIDTH, \ .gate_shift = PCG_CGC_SHIFT, \ @@ -294,7 +335,7 @@ struct clk _name = { \ }, \ } -#define IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, _flags) \ +#define IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, _flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_common_slice_data) { \ @@ -324,9 +365,13 @@ IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, \ CLK_OPS_PARENT_ENABLE) #define IMX_CLK_COMPOSITE_FW_MANAGED(_name, _parent_data, _base, _offset) \ -IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, \ - (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE)) - -#define IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(_name, _parent_data, _base, _offset) \ -IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, \ - (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE | CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL)) +IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, \ + (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE \ + | CLK_GET_RATE_NOCACHE)) + +#define IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(_name, _parent_data, _base, \ + _offset) \ +IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, \ + (CLK_SET_RATE_NO_REPARENT | \ + CLK_OPS_PARENT_ENABLE | \ + CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL)) diff --git a/drivers/clk/imx/include/imx8mq-bindings.h b/drivers/clk/imx/include/imx8mq-bindings.h index 2f74b3c6a..5af8332ce 100644 --- a/drivers/clk/imx/include/imx8mq-bindings.h +++ b/drivers/clk/imx/include/imx8mq-bindings.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright 2016 Freescale Semiconductor, Inc. * Copyright 2017 NXP diff --git a/drivers/clk/meson/clk-measure.c b/drivers/clk/meson/clk-measure.c index ad1e49dfc..5513fa288 100644 --- a/drivers/clk/meson/clk-measure.c +++ b/drivers/clk/meson/clk-measure.c @@ -1,4 +1,4 @@ -/* +/* SPDX-License-Identifier: GPL-2.0-or-later * * This program is derived from: * https://github.com/hardkernel/u-boot/blob/odroidg12-v2015.01/arch/arm/cpu/armv8/g12a/clock.c @@ -185,14 +185,14 @@ unsigned long clk_msr(unsigned long clk_mux) /* Disable interrupts */ *mclk_reg0 = regval; - regval |= duration; /* 64uS is enough for measure the frequence? */ + regval |= duration; /* 64uS is enough for measure the frequence? */ *mclk_reg0 = regval; - regval |= (clk_mux << 20); /* Select MUX */ + regval |= (clk_mux << 20); /* Select MUX */ *mclk_reg0 = regval; - regval |= (1 << 19); /* enable the clock */ - regval |= (1 << 16); /* enable measuring */ + regval |= (1 << 19); /* enable the clock */ + regval |= (1 << 16); /* enable measuring */ *mclk_reg0 = regval; regval = *mclk_reg0; @@ -202,7 +202,7 @@ unsigned long clk_msr(unsigned long clk_mux) /* TODO: Check the busy bit */ /* if (regval & (1 << 31)) */ - /* sddf_dprintf("CLK | ERR: The clock measure logic is busy\n"); */ + /* sddf_dprintf("CLK | ERR: The clock measure logic is busy\n"); */ /* Wait for the measurement to be done */ while (true) { @@ -213,15 +213,16 @@ unsigned long clk_msr(unsigned long clk_mux) } /* TODO: Could be optimised via timeouts */ /* if (sleep_us) */ - /* udelay(sleep_us); */ + /* udelay(sleep_us); */ } - regval &= ~(1 << 16); /* disable measuring */ + regval &= ~(1 << 16); /* disable measuring */ *mclk_reg0 = regval; uint32_t msr_val = *mclk_reg2; - return DIV_ROUND_CLOSEST_ULL((msr_val & ((1 << 19) - 1)) * 1000000ULL, duration); + return DIV_ROUND_CLOSEST_ULL((msr_val & ((1 << 19) - 1)) * 1000000ULL, + duration); } const char *const *get_msr_clk_list(void) diff --git a/drivers/clk/meson/clk-meson.c b/drivers/clk/meson/clk-meson.c index 6c26f1fff..990cc2242 100644 --- a/drivers/clk/meson/clk-meson.c +++ b/drivers/clk/meson/clk-meson.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) /* * Operations for MPLL clocks are derived from: * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-mpll.c @@ -7,7 +7,7 @@ * Author: Michael Turquette */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for PLL clocks are derived from: * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-pll.c @@ -19,7 +19,7 @@ * Author: Jerome Brunet */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for gate clocks are derived from: * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/meson/clk-regmap.c @@ -28,7 +28,7 @@ * Author: Jerome Brunet */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for fixed factor clocks are derived from: * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-fixed-factor.c @@ -36,7 +36,7 @@ * Copyright (C) 2011 Sascha Hauer, Pengutronix */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for divider clocks are derived from: * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-divider.c @@ -48,7 +48,7 @@ * Adjustable divider clock implementation */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for multiplexer clocks are derived from: * https://github.com/torvalds/linux/blob/befe87380e21f0d37633273e1068c9318f8135ff/drivers/clk/clk-mux.c @@ -60,7 +60,7 @@ * Simple multiplexer clock implementation */ -// SPDX-License-Identifier: GPL-2.0 +// SPDX-License-Identifier: GPL-2.0-only /* * Operations for meson_vid_pll_div are derived from: * https://github.com/torvalds/linux/blob/7ec462100ef9142344ddbf86f2c3008b97acddbe/drivers/clk/meson/vid-pll-div.c @@ -83,7 +83,7 @@ static inline uint32_t meson_parm_read(uint64_t base, struct parm parm) return regmap_read_bits(base, parm.reg_off, parm.shift, parm.width); } -/* TODO: Replace this doggy dealy() with a standard interface */ +/* TODO: Replace this doggy delay() with a standard interface */ void delay_us(uint32_t us) { uint64_t start_time = sddf_timer_time_now(TIMER_CH); @@ -93,12 +93,12 @@ void delay_us(uint32_t us) } } -int regmap_multi_reg_write(uint64_t base, const struct reg_sequence *regs, int num_regs) +int regmap_multi_reg_write(uint64_t base, const struct reg_sequence *regs, + int num_regs) { int i; for (i = 0; i < num_regs; i++) { reg_write(base, regs[i].reg, regs[i].def); - /* TODO: delay is needed */ if (regs[i].delay_us) { delay_us(regs[i].delay_us); } @@ -109,32 +109,41 @@ int regmap_multi_reg_write(uint64_t base, const struct reg_sequence *regs, int n static void meson_clk_pll_init(struct clk *clk) { struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); - if ((data->flags & CLK_MESON_PLL_NOINIT_ENABLED) && clk->hw.init->ops->is_enabled(clk)) + if ((data->flags & CLK_MESON_PLL_NOINIT_ENABLED) + && clk->hw.init->ops->is_enabled(clk)) return; if (data->init_count) { /* Set the reset bit */ - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, + data->rst.width, 1); regmap_multi_reg_write(clk->base, data->init_regs, data->init_count); /* Clear the reset bit */ - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 0); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, + data->rst.width, 0); } } -static unsigned long meson_clk_pll_recalc_rate(const struct clk *clk, unsigned long parent_rate) +static unsigned long meson_clk_pll_recalc_rate(const struct clk *clk, + unsigned long parent_rate) { struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); uint32_t n, m, frac; - n = regmap_read_bits(clk->base, data->n.reg_off, data->n.shift, data->n.width); + n = regmap_read_bits(clk->base, data->n.reg_off, data->n.shift, + data->n.width); if (n == 0) return 0; - m = regmap_read_bits(clk->base, data->m.reg_off, data->m.shift, data->m.width); + m = regmap_read_bits(clk->base, data->m.reg_off, data->m.shift, + data->m.width); - frac = data->frac.width ? regmap_read_bits(clk->base, data->frac.reg_off, data->frac.shift, data->frac.width) : 0; + frac = data->frac.width + ? regmap_read_bits(clk->base, data->frac.reg_off, data->frac.shift, + data->frac.width) + : 0; uint64_t rate = (uint64_t)parent_rate * m; @@ -154,7 +163,8 @@ static int meson_clk_pll_is_enabled(struct clk *clk) return 0; } - if (!meson_parm_read(clk->base, data->en) || !meson_parm_read(clk->base, data->l)) { + if (!meson_parm_read(clk->base, data->en) + || !meson_parm_read(clk->base, data->l)) { return 0; } @@ -168,11 +178,15 @@ static int meson_clk_pll_enable(struct clk *clk) if (meson_clk_pll_is_enabled(clk)) return 0; - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); - regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, data->en.width, 1); - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, + data->rst.width, 1); + regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, + data->en.width, 1); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, + data->rst.width, 1); - regmap_update_bits(clk->base, data->current_en.reg_off, data->current_en.shift, data->current_en.width, 1); + regmap_update_bits(clk->base, data->current_en.reg_off, + data->current_en.shift, data->current_en.width, 1); return 0; } @@ -180,18 +194,22 @@ static int meson_clk_pll_disable(struct clk *clk) { struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); - regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, data->en.width, 0); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, + data->rst.width, 1); + regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, + data->en.width, 0); return 0; } -const struct clk_ops meson_clk_pll_ops = { .init = meson_clk_pll_init, - .recalc_rate = meson_clk_pll_recalc_rate, +const struct clk_ops meson_clk_pll_ops = { + .init = meson_clk_pll_init, + .recalc_rate = meson_clk_pll_recalc_rate, /* .determine_rate = meson_clk_pll_determine_rate, */ /* .set_rate = meson_clk_pll_set_rate, */ - .is_enabled = meson_clk_pll_is_enabled, - .enable = meson_clk_pll_enable, - .disable = meson_clk_pll_disable }; + .is_enabled = meson_clk_pll_is_enabled, + .enable = meson_clk_pll_enable, + .disable = meson_clk_pll_disable +}; const struct clk_ops meson_clk_pll_ro_ops = { .recalc_rate = meson_clk_pll_recalc_rate, @@ -202,13 +220,17 @@ const struct clk_ops meson_clk_pll_ro_ops = { #define N2_MIN 4 #define N2_MAX 511 -static unsigned long mpll_recalc_rate(const struct clk *clk, unsigned long prate) +static unsigned long mpll_recalc_rate(const struct clk *clk, + unsigned long prate) { - struct meson_clk_mpll_data *data = (struct meson_clk_mpll_data *)(clk->data); + struct meson_clk_mpll_data *data = + (struct meson_clk_mpll_data *)(clk->data); uint32_t sdm, n2; - sdm = regmap_read_bits(clk->base, data->sdm.reg_off, data->sdm.shift, data->sdm.width); - n2 = regmap_read_bits(clk->base, data->n2.reg_off, data->n2.shift, data->n2.width); + sdm = regmap_read_bits(clk->base, data->sdm.reg_off, data->sdm.shift, + data->sdm.width); + n2 = regmap_read_bits(clk->base, data->n2.reg_off, data->n2.shift, + data->n2.width); uint32_t divisor = (SDM_DEN * n2) + sdm; if (n2 < N2_MIN) @@ -217,9 +239,11 @@ static unsigned long mpll_recalc_rate(const struct clk *clk, unsigned long prate return DIV_ROUND_UP_ULL((uint64_t)prate * SDM_DEN, divisor); } -static int mpll_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_rate) +static int mpll_set_rate(const struct clk *clk, uint32_t rate, + uint32_t parent_rate) { - struct meson_clk_mpll_data *data = (struct meson_clk_mpll_data *)(clk->data); + struct meson_clk_mpll_data *data = + (struct meson_clk_mpll_data *)(clk->data); uint64_t div = parent_rate; uint64_t frac = do_div(div, rate); uint32_t sdm, n2; @@ -246,27 +270,30 @@ static int mpll_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_r n2 = div; } - regmap_update_bits(clk->base, data->sdm.reg_off, data->sdm.shift, data->sdm.width, sdm); - regmap_update_bits(clk->base, data->n2.reg_off, data->n2.shift, data->n2.width, n2); - - /* volatile uint32_t *clk_reg = ((void *)clk_base + data->sdm.reg_off); */ + regmap_update_bits(clk->base, data->sdm.reg_off, data->sdm.shift, + data->sdm.width, sdm); + regmap_update_bits(clk->base, data->n2.reg_off, data->n2.shift, + data->n2.width, n2); return 0; } static void mpll_init(struct clk *clk) { - struct meson_clk_mpll_data *data = (struct meson_clk_mpll_data *)(clk->data); + struct meson_clk_mpll_data *data = + (struct meson_clk_mpll_data *)(clk->data); if (data->init_count) { regmap_multi_reg_write(clk->base, data->init_regs, data->init_count); } /* Enable the fractional part */ - regmap_update_bits(clk->base, data->sdm_en.reg_off, data->sdm_en.shift, data->sdm_en.width, 1); + regmap_update_bits(clk->base, data->sdm_en.reg_off, data->sdm_en.shift, + data->sdm_en.width, 1); /* Set spread spectrum if possible */ unsigned int ss = data->flags & CLK_MESON_MPLL_SPREAD_SPECTRUM ? 1 : 0; - regmap_update_bits(clk->base, data->ssen.reg_off, data->ssen.shift, data->ssen.width, ss); + regmap_update_bits(clk->base, data->ssen.reg_off, data->ssen.shift, + data->ssen.width, ss); } const struct clk_ops meson_clk_mpll_ops = { @@ -295,12 +322,14 @@ static int meson_clk_pcie_pll_enable(struct clk *clk) return -1; } -const struct clk_ops meson_clk_pcie_pll_ops = { .init = meson_clk_pll_init, - .recalc_rate = meson_clk_pll_recalc_rate, +const struct clk_ops meson_clk_pcie_pll_ops = { + .init = meson_clk_pll_init, + .recalc_rate = meson_clk_pll_recalc_rate, /* .determine_rate = meson_clk_pll_determine_rate, */ - .is_enabled = meson_clk_pll_is_enabled, - .enable = meson_clk_pcie_pll_enable, - .disable = meson_clk_pll_disable }; + .is_enabled = meson_clk_pll_is_enabled, + .enable = meson_clk_pcie_pll_enable, + .disable = meson_clk_pll_disable +}; struct vid_pll_div { unsigned int shift_val; @@ -318,35 +347,40 @@ struct vid_pll_div { } static const struct vid_pll_div vid_pll_div_table[] = { - VID_PLL_DIV(0x0aaa, 0, 2, 1), /* 2/1 => /2 */ - VID_PLL_DIV(0x5294, 2, 5, 2), /* 5/2 => /2.5 */ - VID_PLL_DIV(0x0db6, 0, 3, 1), /* 3/1 => /3 */ - VID_PLL_DIV(0x36cc, 1, 7, 2), /* 7/2 => /3.5 */ - VID_PLL_DIV(0x6666, 2, 15, 4), /* 15/4 => /3.75 */ - VID_PLL_DIV(0x0ccc, 0, 4, 1), /* 4/1 => /4 */ - VID_PLL_DIV(0x739c, 2, 5, 1), /* 5/1 => /5 */ - VID_PLL_DIV(0x0e38, 0, 6, 1), /* 6/1 => /6 */ - VID_PLL_DIV(0x0000, 3, 25, 4), /* 25/4 => /6.25 */ - VID_PLL_DIV(0x3c78, 1, 7, 1), /* 7/1 => /7 */ - VID_PLL_DIV(0x78f0, 2, 15, 2), /* 15/2 => /7.5 */ - VID_PLL_DIV(0x0fc0, 0, 12, 1), /* 12/1 => /12 */ - VID_PLL_DIV(0x3f80, 1, 14, 1), /* 14/1 => /14 */ - VID_PLL_DIV(0x7f80, 2, 15, 1), /* 15/1 => /15 */ + VID_PLL_DIV(0x0aaa, 0, 2, 1), /* 2/1 => /2 */ + VID_PLL_DIV(0x5294, 2, 5, 2), /* 5/2 => /2.5 */ + VID_PLL_DIV(0x0db6, 0, 3, 1), /* 3/1 => /3 */ + VID_PLL_DIV(0x36cc, 1, 7, 2), /* 7/2 => /3.5 */ + VID_PLL_DIV(0x6666, 2, 15, 4), /* 15/4 => /3.75 */ + VID_PLL_DIV(0x0ccc, 0, 4, 1), /* 4/1 => /4 */ + VID_PLL_DIV(0x739c, 2, 5, 1), /* 5/1 => /5 */ + VID_PLL_DIV(0x0e38, 0, 6, 1), /* 6/1 => /6 */ + VID_PLL_DIV(0x0000, 3, 25, 4), /* 25/4 => /6.25 */ + VID_PLL_DIV(0x3c78, 1, 7, 1), /* 7/1 => /7 */ + VID_PLL_DIV(0x78f0, 2, 15, 2), /* 15/2 => /7.5 */ + VID_PLL_DIV(0x0fc0, 0, 12, 1), /* 12/1 => /12 */ + VID_PLL_DIV(0x3f80, 1, 14, 1), /* 14/1 => /14 */ + VID_PLL_DIV(0x7f80, 2, 15, 1), /* 15/1 => /15 */ }; -static unsigned long meson_vid_pll_div_recalc_rate(const struct clk *clk, unsigned long prate) +static unsigned long meson_vid_pll_div_recalc_rate(const struct clk *clk, + unsigned long prate) { - struct meson_vid_pll_div_data *data = (struct meson_vid_pll_div_data *)(clk->data); + struct meson_vid_pll_div_data *data = + (struct meson_vid_pll_div_data *)(clk->data); const struct vid_pll_div *div; uint32_t shift_val, shift_sel; - shift_val = regmap_read_bits(clk->base, data->val.reg_off, data->val.shift, data->val.width); - shift_sel = regmap_read_bits(clk->base, data->sel.reg_off, data->sel.shift, data->sel.width); + shift_val = regmap_read_bits(clk->base, data->val.reg_off, data->val.shift, + data->val.width); + shift_sel = regmap_read_bits(clk->base, data->sel.reg_off, data->sel.shift, + data->sel.width); int i; for (i = 0; i < ARRAY_SIZE(vid_pll_div_table); ++i) { - if (vid_pll_div_table[i].shift_val == shift_val && vid_pll_div_table[i].shift_sel == shift_sel) { + if (vid_pll_div_table[i].shift_val == shift_val + && vid_pll_div_table[i].shift_sel == shift_sel) { div = &vid_pll_div_table[i]; return DIV_ROUND_UP_ULL(prate * div->multiplier, div->divider); } @@ -362,29 +396,37 @@ const struct clk_ops meson_vid_pll_div_ro_ops = { static int meson_vclk_gate_enable(struct clk *clk) { - struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); + struct meson_vclk_gate_data *data = + (struct meson_vclk_gate_data *)(clk->data); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 1); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, + data->enable.width, 1); /* Do a reset pulse */ - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 1); - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 0); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, + data->reset.width, 1); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, + data->reset.width, 0); return 0; } static int meson_vclk_gate_disable(struct clk *clk) { - struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); + struct meson_vclk_gate_data *data = + (struct meson_vclk_gate_data *)(clk->data); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 0); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, + data->enable.width, 0); return 0; } static int meson_vclk_gate_is_enabled(struct clk *clk) { - struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); - return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width); + struct meson_vclk_gate_data *data = + (struct meson_vclk_gate_data *)(clk->data); + return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, + data->enable.width); } const struct clk_ops meson_vclk_gate_ops = { @@ -393,10 +435,13 @@ const struct clk_ops meson_vclk_gate_ops = { .is_enabled = meson_vclk_gate_is_enabled, }; -static unsigned long meson_vclk_div_recalc_rate(const struct clk *clk, unsigned long prate) +static unsigned long meson_vclk_div_recalc_rate(const struct clk *clk, + unsigned long prate) { - struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); - uint32_t div = regmap_read_bits(clk->base, data->div.reg_off, data->div.shift, data->div.width); + struct meson_vclk_div_data *data = + (struct meson_vclk_div_data *)(clk->data); + uint32_t div = regmap_read_bits(clk->base, data->div.reg_off, + data->div.shift, data->div.width); /* TODO: Need to verify the following cases */ if (data->flags & CLK_DIVIDER_ONE_BASED) { @@ -412,9 +457,11 @@ static unsigned long meson_vclk_div_recalc_rate(const struct clk *clk, unsigned return DIV_ROUND_UP_ULL((uint64_t)prate, div); } -static int meson_vclk_div_set_rate(const struct clk *clk, uint32_t rate, uint32_t parent_rate) +static int meson_vclk_div_set_rate(const struct clk *clk, uint32_t rate, + uint32_t parent_rate) { - struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); + struct meson_vclk_div_data *data = + (struct meson_vclk_div_data *)(clk->data); uint32_t div = DIV_ROUND_UP(parent_rate, rate); @@ -428,32 +475,41 @@ static int meson_vclk_div_set_rate(const struct clk *clk, uint32_t rate, uint32_ } else { div -= 1; } - return regmap_update_bits(clk->base, data->div.reg_off, data->div.shift, data->div.width, div); + return regmap_update_bits(clk->base, data->div.reg_off, data->div.shift, + data->div.width, div); } static int meson_vclk_div_enable(struct clk *clk) { - struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); + struct meson_vclk_div_data *data = + (struct meson_vclk_div_data *)(clk->data); - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 0); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 1); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, + data->reset.width, 0); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, + data->enable.width, 1); return 0; } static int meson_vclk_div_disable(struct clk *clk) { - struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); + struct meson_vclk_div_data *data = + (struct meson_vclk_div_data *)(clk->data); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 0); - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 1); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, + data->enable.width, 0); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, + data->reset.width, 1); return 0; } static int meson_vclk_div_is_enabled(struct clk *clk) { - struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); - return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width); + struct meson_vclk_div_data *data = + (struct meson_vclk_div_data *)(clk->data); + return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, + data->enable.width); } const struct clk_ops meson_vclk_div_ops = { @@ -465,9 +521,11 @@ const struct clk_ops meson_vclk_div_ops = { .is_enabled = meson_vclk_div_is_enabled, }; -static unsigned long meson_clk_cpu_dyndiv_recalc_rate(const struct clk *clk, unsigned long prate) +static unsigned long meson_clk_cpu_dyndiv_recalc_rate(const struct clk *clk, + unsigned long prate) { - struct meson_clk_cpu_dyndiv_data *data = (struct meson_clk_cpu_dyndiv_data *)(clk->data); + struct meson_clk_cpu_dyndiv_data *data = + (struct meson_clk_cpu_dyndiv_data *)(clk->data); uint32_t div = meson_parm_read(clk->base, data->div); div += 1; diff --git a/drivers/clk/meson/clk.c b/drivers/clk/meson/clk.c index 368ee6c99..3f303882c 100644 --- a/drivers/clk/meson/clk.c +++ b/drivers/clk/meson/clk.c @@ -15,10 +15,10 @@ #include /* common definitions and interfaces */ #include /* ops of common clocks e.g., div, mux, fixed factor, and gate*/ -#include /* implementation of clock measurements */ -#include /* operations for meson-specific clocks */ -#include /* offsets of control registers */ -#include /* clock id bindings*/ +#include /* implementation of clock measurements */ +#include /* operations for meson-specific clocks */ +#include /* offsets of control registers */ +#include /* clock id bindings*/ // Logging /* #define DEBUG_DRIVER */ @@ -162,18 +162,17 @@ uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) clk->hw.init->ops->set_rate(clk, req_rate, prate); *rate = req_rate; return 0; - } else { - if (pclk->hw.init->ops->set_rate) { - const struct clk *ppclk = get_parent(pclk); - uint64_t pprate = 0; - uint32_t err = clk_get_rate(ppclk, &pprate); - if (!err) { - pclk->hw.init->ops->set_rate(pclk, prate, pprate); - *rate = req_rate; - return 0; - } - return err; + } + if (pclk->hw.init->ops->set_rate) { + const struct clk *ppclk = get_parent(pclk); + uint64_t pprate = 0; + uint32_t err = clk_get_rate(ppclk, &pprate); + if (!err) { + pclk->hw.init->ops->set_rate(pclk, prate, pprate); + *rate = req_rate; + return 0; } + return err; } return CLK_INVALID_OP; @@ -193,8 +192,8 @@ int clk_msr_stat() for (i = 0; i < NUM_CLK_LIST; i++) { err = clk_get_rate(clk_list[i], &rate); if (err) { - LOG_DRIVER("Failed to get rate of %s: -%u\n", clk_list[i]->hw.init->name, err); - + LOG_DRIVER("Failed to get rate of %s: -%u\n", + clk_list[i]->hw.init->name, err); } LOG_DRIVER("[%4d][%4luHz] %s\n", i, rate, clk_list[i]->hw.init->name); } @@ -224,7 +223,6 @@ void init(void) clk_probe(clk_list); clk_msr_stat(); - for (int i = 0; i < NUM_DEVICE_CLKS; i++) { struct clk *clk = clk_list[clk_configs[i].clk_id]; @@ -238,11 +236,11 @@ void init(void) uint64_t rate = 0; uint32_t err = clk_set_rate(clk, clk_configs[i].frequency, &rate); if (err) { - LOG_DRIVER_ERR("Failed to set rate [%d] for clk_id: %d\n", clk_configs[i].frequency, clk_configs[i].clk_id); + LOG_DRIVER_ERR("Failed to set rate [%d] for clk_id: %d\n", + clk_configs[i].frequency, clk_configs[i].clk_id); } } } - } microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) @@ -304,8 +302,8 @@ microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) break; } default: - LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), - ch); + LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", + microkit_msginfo_get_label(msginfo), ch); err = CLK_UNKNOWN_REQ; } return microkit_msginfo_new(err, ret_num); diff --git a/drivers/clk/meson/clk_driver.mk b/drivers/clk/meson/clk_driver.mk index 6aff1dbb2..379d43454 100644 --- a/drivers/clk/meson/clk_driver.mk +++ b/drivers/clk/meson/clk_driver.mk @@ -22,7 +22,7 @@ $(CLK_DRIVER_OBJS): ${CLK_DRIVER_COMMON_DIR}/*.c ${CLK_DRIVER_DIR}/*.c $(CLK_CON -I${UART_DRIVER_DIR}/include \ -I${CLK_DRIVER_COMMON_DIR} $^ -$(CLK_CONFIG_HEADER): $(DTS_FILE) +$(CLK_CONFIG_HEADER): $(DTS_FILE) $(CLK_DRIVER_COMMON_DIR)/create_clk_config.py $(PYTHON) $(CLK_DRIVER_COMMON_DIR)/create_clk_config.py $(DTS_FILE) $(BUILD_DIR) clean:: diff --git a/drivers/clk/meson/include/clk-meson.h b/drivers/clk/meson/include/clk-meson.h index aa06e1397..8563b166a 100644 --- a/drivers/clk/meson/include/clk-meson.h +++ b/drivers/clk/meson/include/clk-meson.h @@ -8,7 +8,7 @@ #define CLK_MESON_PLL_ROUND_CLOSEST BIT(0) #define CLK_MESON_PLL_NOINIT_ENABLED BIT(1) -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015 Endless Mobile, Inc. * Author: Carlo Caione @@ -52,7 +52,7 @@ struct reg_sequence { unsigned int delay_us; }; -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2019 BayLibre, SAS. * Author: Jerome Brunet diff --git a/drivers/clk/meson/include/g12a-bindings.h b/drivers/clk/meson/include/g12a-bindings.h index c817acdf1..582b0d084 100644 --- a/drivers/clk/meson/include/g12a-bindings.h +++ b/drivers/clk/meson/include/g12a-bindings.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0+ OR MIT */ +/* SPDX-License-Identifier: GPL-2.0-or-later OR MIT */ /* * Meson-G12A clock tree IDs * diff --git a/drivers/clk/meson/include/g12a-regs.h b/drivers/clk/meson/include/g12a-regs.h index 1c587583d..9c1a91305 100644 --- a/drivers/clk/meson/include/g12a-regs.h +++ b/drivers/clk/meson/include/g12a-regs.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* SPDX-License-Identifier: (GPL-2.0-or-later OR MIT) */ /* * Copyright (c) 2016 Amlogic, Inc. * Author: Michael Turquette diff --git a/drivers/clk/meson/sm1-clk.c b/drivers/clk/meson/sm1-clk.c index ae980b50f..07924ecea 100644 --- a/drivers/clk/meson/sm1-clk.c +++ b/drivers/clk/meson/sm1-clk.c @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Amlogic Meson-G12A Clock Controller Driver * @@ -71,7 +71,8 @@ static struct clk g12a_fixed_pll_dco = { .num_parents = 1, }, }; -static CLK_DIV_RO(g12a_fixed_pll, HHI_FIX_PLL_CNTL0, 16, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_fixed_pll_dco }, 1, 0); +static CLK_DIV_RO(g12a_fixed_pll, HHI_FIX_PLL_CNTL0, 16, 2, + CLK_DIVIDER_POWER_OF_TWO, { &g12a_fixed_pll_dco }, 1, 0); static struct clk g12a_sys_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { @@ -113,13 +114,18 @@ static struct clk g12a_sys_pll_dco = { .flags = CLK_IS_CRITICAL, }, }; -static CLK_DIV(g12a_sys_pll, HHI_SYS_PLL_CNTL0, 16, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_sys_pll_dco }, 1, 0); -static CLK_GATE_RO(g12a_sys_pll_div16_en, HHI_SYS_CPU_CLK_CNTL1, 24, 0, { &g12a_sys_pll }, 1, 0); -static CLK_FIXED_FACTOR(g12a_sys_pll_div16, 1, 16, 0, { &g12a_sys_pll_div16_en }, 1, 0); +static CLK_DIV(g12a_sys_pll, HHI_SYS_PLL_CNTL0, 16, 3, CLK_DIVIDER_POWER_OF_TWO, + { &g12a_sys_pll_dco }, 1, 0); +static CLK_GATE_RO(g12a_sys_pll_div16_en, HHI_SYS_CPU_CLK_CNTL1, 24, 0, + { &g12a_sys_pll }, 1, 0); +static CLK_FIXED_FACTOR(g12a_sys_pll_div16, 1, 16, 0, + { &g12a_sys_pll_div16_en }, 1, 0); static CLK_FIXED_FACTOR(g12a_fclk_div2_div, 1, 2, 0, { &g12a_fixed_pll }, 1, 0); -static CLK_GATE(g12a_fclk_div2, HHI_FIX_PLL_CNTL1, 24, 0, { &g12a_fclk_div2_div }, 1, 0); +static CLK_GATE(g12a_fclk_div2, HHI_FIX_PLL_CNTL1, 24, 0, + { &g12a_fclk_div2_div }, 1, 0); static CLK_FIXED_FACTOR(g12a_fclk_div3_div, 1, 3, 0, { &g12a_fixed_pll }, 1, 0); -static CLK_GATE(g12a_fclk_div3, HHI_FIX_PLL_CNTL1, 20, 0, { &g12a_fclk_div3_div }, 1, 0); +static CLK_GATE(g12a_fclk_div3, HHI_FIX_PLL_CNTL1, 20, 0, + { &g12a_fclk_div3_div }, 1, 0); const struct clk_parent_data g12a_cpu_clk_premux0_parent_table[] = { { .name = "xtal", @@ -127,8 +133,8 @@ const struct clk_parent_data g12a_cpu_clk_premux0_parent_table[] = { { .clk = &g12a_fclk_div2 }, { .clk = &g12a_fclk_div3 }, }; -static CLK_MUX(g12a_cpu_clk_premux0, HHI_SYS_CPU_CLK_CNTL0, 0x3, 0, 0, CLK_MUX_ROUND_CLOSEST, - g12a_cpu_clk_premux0_parent_table, 3, 0); +static CLK_MUX(g12a_cpu_clk_premux0, HHI_SYS_CPU_CLK_CNTL0, 0x3, 0, 0, + CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_premux0_parent_table, 3, 0); const struct clk_parent_data g12a_cpu_clk_premux1_parent_table[] = { { .name = "xtal", @@ -136,7 +142,8 @@ const struct clk_parent_data g12a_cpu_clk_premux1_parent_table[] = { { .clk = &g12a_fclk_div2 }, { .clk = &g12a_fclk_div3 }, }; -static CLK_MUX(g12a_cpu_clk_premux1, HHI_SYS_CPU_CLK_CNTL0, 0x3, 16, 0, 0, g12a_cpu_clk_premux1_parent_table, 3, 0); +static CLK_MUX(g12a_cpu_clk_premux1, HHI_SYS_CPU_CLK_CNTL0, 0x3, 16, 0, 0, + g12a_cpu_clk_premux1_parent_table, 3, 0); static struct clk g12a_cpu_clk_mux0_div = { .data = &(struct meson_clk_cpu_dyndiv_data){ .div = { @@ -164,30 +171,36 @@ const struct clk_parent_data g12a_cpu_clk_postmux0_parent_table[] = { { .clk = &g12a_cpu_clk_premux0 }, { .clk = &g12a_cpu_clk_mux0_div }, }; -static CLK_MUX(g12a_cpu_clk_postmux0, HHI_SYS_CPU_CLK_CNTL0, 0x1, 2, 0, CLK_MUX_ROUND_CLOSEST, - g12a_cpu_clk_postmux0_parent_table, 2, 0); -static CLK_DIV_RO(g12a_cpu_clk_mux1_div, HHI_SYS_CPU_CLK_CNTL0, 20, 6, 0, { &g12a_cpu_clk_premux1 }, 1, 0); +static CLK_MUX(g12a_cpu_clk_postmux0, HHI_SYS_CPU_CLK_CNTL0, 0x1, 2, 0, + CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_postmux0_parent_table, 2, 0); +static CLK_DIV_RO(g12a_cpu_clk_mux1_div, HHI_SYS_CPU_CLK_CNTL0, 20, 6, 0, + { &g12a_cpu_clk_premux1 }, 1, 0); const struct clk_parent_data g12a_cpu_clk_postmux1_parent_table[] = { { .clk = &g12a_cpu_clk_premux1 }, { .clk = &g12a_cpu_clk_mux1_div }, }; -static CLK_MUX(g12a_cpu_clk_postmux1, HHI_SYS_CPU_CLK_CNTL0, 0x1, 18, 0, 0, g12a_cpu_clk_postmux1_parent_table, 2, 0); +static CLK_MUX(g12a_cpu_clk_postmux1, HHI_SYS_CPU_CLK_CNTL0, 0x1, 18, 0, 0, + g12a_cpu_clk_postmux1_parent_table, 2, 0); const struct clk_parent_data g12a_cpu_clk_dyn_parent_table[] = { { .clk = &g12a_cpu_clk_postmux0 }, { .clk = &g12a_cpu_clk_postmux1 }, }; -static CLK_MUX(g12a_cpu_clk_dyn, HHI_SYS_CPU_CLK_CNTL0, 0x1, 10, 0, CLK_MUX_ROUND_CLOSEST, - g12a_cpu_clk_dyn_parent_table, 2, 0); +static CLK_MUX(g12a_cpu_clk_dyn, HHI_SYS_CPU_CLK_CNTL0, 0x1, 10, 0, + CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_dyn_parent_table, 2, 0); const struct clk_parent_data g12a_cpu_clk_parent_table[] = { { .clk = &g12a_cpu_clk_dyn }, { .clk = &g12a_sys_pll }, }; -static CLK_MUX(g12a_cpu_clk, HHI_SYS_CPU_CLK_CNTL0, 0x1, 11, 0, CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_parent_table, 2, 0); +static CLK_MUX(g12a_cpu_clk, HHI_SYS_CPU_CLK_CNTL0, 0x1, 11, 0, + CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_parent_table, 2, 0); static const struct reg_sequence g12a_gp0_init_regs[] = { - { .reg = HHI_GP0_PLL_CNTL1, .def = 0x00000000 }, { .reg = HHI_GP0_PLL_CNTL2, .def = 0x00000000 }, - { .reg = HHI_GP0_PLL_CNTL3, .def = 0x48681c00 }, { .reg = HHI_GP0_PLL_CNTL4, .def = 0x33771290 }, - { .reg = HHI_GP0_PLL_CNTL5, .def = 0x39272000 }, { .reg = HHI_GP0_PLL_CNTL6, .def = 0x56540000 }, + { .reg = HHI_GP0_PLL_CNTL1, .def = 0x00000000 }, + { .reg = HHI_GP0_PLL_CNTL2, .def = 0x00000000 }, + { .reg = HHI_GP0_PLL_CNTL3, .def = 0x48681c00 }, + { .reg = HHI_GP0_PLL_CNTL4, .def = 0x33771290 }, + { .reg = HHI_GP0_PLL_CNTL5, .def = 0x39272000 }, + { .reg = HHI_GP0_PLL_CNTL6, .def = 0x56540000 }, }; static struct clk g12a_gp0_pll_dco = { .data = &(struct meson_clk_pll_data){ @@ -235,7 +248,8 @@ static struct clk g12a_gp0_pll_dco = { .num_parents = 1, }, }; -static CLK_DIV(g12a_gp0_pll, HHI_GP0_PLL_CNTL0, 16, 3, (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), +static CLK_DIV(g12a_gp0_pll, HHI_GP0_PLL_CNTL0, 16, 3, + (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), { &g12a_gp0_pll_dco }, 1, 0); static struct clk sm1_gp1_pll_dco = { .data = &(struct meson_clk_pll_data){ @@ -281,7 +295,8 @@ static struct clk sm1_gp1_pll_dco = { .flags = CLK_IS_CRITICAL, }, }; -static CLK_DIV_RO(sm1_gp1_pll, HHI_GP1_PLL_CNTL0, 16, 3, (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), +static CLK_DIV_RO(sm1_gp1_pll, HHI_GP1_PLL_CNTL0, 16, 3, + (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), { &sm1_gp1_pll_dco }, 1, 0); const struct clk_parent_data sm1_dsu_clk_premux0_parent_table[] = { @@ -292,7 +307,8 @@ const struct clk_parent_data sm1_dsu_clk_premux0_parent_table[] = { { .clk = &g12a_fclk_div3 }, { .clk = &sm1_gp1_pll }, }; -static CLK_MUX_RO(sm1_dsu_clk_premux0, HHI_SYS_CPU_CLK_CNTL5, 0x3, 0, 0, 0, sm1_dsu_clk_premux0_parent_table, 4, 0); +static CLK_MUX_RO(sm1_dsu_clk_premux0, HHI_SYS_CPU_CLK_CNTL5, 0x3, 0, 0, 0, + sm1_dsu_clk_premux0_parent_table, 4, 0); const struct clk_parent_data sm1_dsu_clk_premux1_parent_table[] = { { .name = "xtal", @@ -301,16 +317,20 @@ const struct clk_parent_data sm1_dsu_clk_premux1_parent_table[] = { { .clk = &g12a_fclk_div3 }, { .clk = &sm1_gp1_pll }, }; -static CLK_MUX_RO(sm1_dsu_clk_premux1, HHI_SYS_CPU_CLK_CNTL5, 0x3, 16, 0, 0, sm1_dsu_clk_premux1_parent_table, 4, 0); -static CLK_DIV_RO(sm1_dsu_clk_mux0_div, HHI_SYS_CPU_CLK_CNTL5, 4, 6, 0, { &sm1_dsu_clk_premux0 }, 1, 0); +static CLK_MUX_RO(sm1_dsu_clk_premux1, HHI_SYS_CPU_CLK_CNTL5, 0x3, 16, 0, 0, + sm1_dsu_clk_premux1_parent_table, 4, 0); +static CLK_DIV_RO(sm1_dsu_clk_mux0_div, HHI_SYS_CPU_CLK_CNTL5, 4, 6, 0, + { &sm1_dsu_clk_premux0 }, 1, 0); const struct clk_parent_data sm1_dsu_clk_postmux0_parent_table[] = { { .clk = &sm1_dsu_clk_premux0, }, { .clk = &sm1_dsu_clk_mux0_div }, }; -static CLK_MUX_RO(sm1_dsu_clk_postmux0, HHI_SYS_CPU_CLK_CNTL5, 0x1, 2, 0, 0, sm1_dsu_clk_postmux0_parent_table, 2, 0); -static CLK_DIV_RO(sm1_dsu_clk_mux1_div, HHI_SYS_CPU_CLK_CNTL5, 20, 6, 0, { &sm1_dsu_clk_premux1 }, 1, 0); +static CLK_MUX_RO(sm1_dsu_clk_postmux0, HHI_SYS_CPU_CLK_CNTL5, 0x1, 2, 0, 0, + sm1_dsu_clk_postmux0_parent_table, 2, 0); +static CLK_DIV_RO(sm1_dsu_clk_mux1_div, HHI_SYS_CPU_CLK_CNTL5, 20, 6, 0, + { &sm1_dsu_clk_premux1 }, 1, 0); const struct clk_parent_data sm1_dsu_clk_postmux1_parent_table[] = { { @@ -318,7 +338,8 @@ const struct clk_parent_data sm1_dsu_clk_postmux1_parent_table[] = { }, { .clk = &sm1_dsu_clk_mux1_div }, }; -static CLK_MUX_RO(sm1_dsu_clk_postmux1, HHI_SYS_CPU_CLK_CNTL5, 0x1, 18, 0, 0, sm1_dsu_clk_postmux1_parent_table, 2, 0); +static CLK_MUX_RO(sm1_dsu_clk_postmux1, HHI_SYS_CPU_CLK_CNTL5, 0x1, 18, 0, 0, + sm1_dsu_clk_postmux1_parent_table, 2, 0); const struct clk_parent_data sm1_dsu_clk_dyn_parent_table[] = { { .clk = &sm1_dsu_clk_premux0, @@ -327,7 +348,8 @@ const struct clk_parent_data sm1_dsu_clk_dyn_parent_table[] = { .clk = &sm1_dsu_clk_postmux1, }, }; -static CLK_MUX_RO(sm1_dsu_clk_dyn, HHI_SYS_CPU_CLK_CNTL5, 0x1, 10, 0, 0, sm1_dsu_clk_dyn_parent_table, 2, 0); +static CLK_MUX_RO(sm1_dsu_clk_dyn, HHI_SYS_CPU_CLK_CNTL5, 0x1, 10, 0, 0, + sm1_dsu_clk_dyn_parent_table, 2, 0); const struct clk_parent_data sm1_dsu_final_clk_parent_table[] = { { .clk = &sm1_dsu_clk_dyn, @@ -336,15 +358,19 @@ const struct clk_parent_data sm1_dsu_final_clk_parent_table[] = { .clk = &g12a_sys_pll, }, }; -static CLK_MUX_RO(sm1_dsu_final_clk, HHI_SYS_CPU_CLK_CNTL5, 0x1, 11, 0, 0, sm1_dsu_final_clk_parent_table, 2, 0); +static CLK_MUX_RO(sm1_dsu_final_clk, HHI_SYS_CPU_CLK_CNTL5, 0x1, 11, 0, 0, + sm1_dsu_final_clk_parent_table, 2, 0); const struct clk_parent_data sm1_cpu_clk_parent_table[] = { { .clk = &g12a_cpu_clk, }, }; -static CLK_MUX_RO(sm1_cpu1_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 24, 0, 0, sm1_cpu_clk_parent_table, 1, 0); -static CLK_MUX_RO(sm1_cpu2_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 25, 0, 0, sm1_cpu_clk_parent_table, 1, 0); -static CLK_MUX_RO(sm1_cpu3_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 26, 0, 0, sm1_cpu_clk_parent_table, 1, 0); +static CLK_MUX_RO(sm1_cpu1_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 24, 0, 0, + sm1_cpu_clk_parent_table, 1, 0); +static CLK_MUX_RO(sm1_cpu2_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 25, 0, 0, + sm1_cpu_clk_parent_table, 1, 0); +static CLK_MUX_RO(sm1_cpu3_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 26, 0, 0, + sm1_cpu_clk_parent_table, 1, 0); const struct clk_parent_data sm1_dsu_clk_parent_table[] = { { .clk = &g12a_cpu_clk, @@ -353,23 +379,37 @@ const struct clk_parent_data sm1_dsu_clk_parent_table[] = { .clk = &sm1_dsu_final_clk, }, }; -static CLK_MUX_RO(sm1_dsu_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 27, 0, 0, sm1_dsu_clk_parent_table, 2, 0); -static CLK_GATE_RO(g12a_cpu_clk_div16_en, HHI_SYS_CPU_CLK_CNTL1, 1, 0, { &g12a_cpu_clk }, 1, 0); -static CLK_FIXED_FACTOR(g12a_cpu_clk_div16, 1, 16, 0, { &g12a_cpu_clk_div16_en }, 1, 0); -static CLK_DIV_RO(g12a_cpu_clk_apb_div, HHI_SYS_CPU_CLK_CNTL1, 3, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); -static CLK_GATE_RO(g12a_cpu_clk_apb, HHI_SYS_CPU_CLK_CNTL1, 1, 0, { &g12a_cpu_clk_apb_div }, 1, 0); -static CLK_DIV_RO(g12a_cpu_clk_atb_div, HHI_SYS_CPU_CLK_CNTL1, 6, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); -static CLK_GATE_RO(g12a_cpu_clk_atb, HHI_SYS_CPU_CLK_CNTL1, 17, 0, { &g12a_cpu_clk_atb_div }, 1, 0); -static CLK_DIV_RO(g12a_cpu_clk_axi_div, HHI_SYS_CPU_CLK_CNTL1, 9, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); -static CLK_GATE_RO(g12a_cpu_clk_axi, HHI_SYS_CPU_CLK_CNTL1, 18, 0, { &g12a_cpu_clk_axi_div }, 1, 0); +static CLK_MUX_RO(sm1_dsu_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 27, 0, 0, + sm1_dsu_clk_parent_table, 2, 0); +static CLK_GATE_RO(g12a_cpu_clk_div16_en, HHI_SYS_CPU_CLK_CNTL1, 1, 0, + { &g12a_cpu_clk }, 1, 0); +static CLK_FIXED_FACTOR(g12a_cpu_clk_div16, 1, 16, 0, + { &g12a_cpu_clk_div16_en }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_apb_div, HHI_SYS_CPU_CLK_CNTL1, 3, 3, + CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); +static CLK_GATE_RO(g12a_cpu_clk_apb, HHI_SYS_CPU_CLK_CNTL1, 1, 0, + { &g12a_cpu_clk_apb_div }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_atb_div, HHI_SYS_CPU_CLK_CNTL1, 6, 3, + CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); +static CLK_GATE_RO(g12a_cpu_clk_atb, HHI_SYS_CPU_CLK_CNTL1, 17, 0, + { &g12a_cpu_clk_atb_div }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_axi_div, HHI_SYS_CPU_CLK_CNTL1, 9, 3, + CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); +static CLK_GATE_RO(g12a_cpu_clk_axi, HHI_SYS_CPU_CLK_CNTL1, 18, 0, + { &g12a_cpu_clk_axi_div }, 1, 0); /* TODO: special case, ignore its parent clk at the moment */ -static CLK_DIV_RO(g12a_cpu_clk_trace_div, HHI_SYS_CPU_CLK_CNTL1, 20, 3, CLK_DIVIDER_POWER_OF_TWO, {}, 0, 0); -static CLK_GATE_RO(g12a_cpu_clk_trace, HHI_SYS_CPU_CLK_CNTL1, 23, 0, { &g12a_cpu_clk_trace_div }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_trace_div, HHI_SYS_CPU_CLK_CNTL1, 20, 3, + CLK_DIVIDER_POWER_OF_TWO, {}, 0, 0); +static CLK_GATE_RO(g12a_cpu_clk_trace, HHI_SYS_CPU_CLK_CNTL1, 23, 0, + { &g12a_cpu_clk_trace_div }, 1, 0); static const struct reg_sequence g12a_hifi_init_regs[] = { - { .reg = HHI_HIFI_PLL_CNTL1, .def = 0x00000000 }, { .reg = HHI_HIFI_PLL_CNTL2, .def = 0x00000000 }, - { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x6a285c00 }, { .reg = HHI_HIFI_PLL_CNTL4, .def = 0x65771290 }, - { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x39272000 }, { .reg = HHI_HIFI_PLL_CNTL6, .def = 0x56540000 }, + { .reg = HHI_HIFI_PLL_CNTL1, .def = 0x00000000 }, + { .reg = HHI_HIFI_PLL_CNTL2, .def = 0x00000000 }, + { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x6a285c00 }, + { .reg = HHI_HIFI_PLL_CNTL4, .def = 0x65771290 }, + { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x39272000 }, + { .reg = HHI_HIFI_PLL_CNTL6, .def = 0x56540000 }, }; static struct clk g12a_hifi_pll_dco = { @@ -419,7 +459,8 @@ static struct clk g12a_hifi_pll_dco = { .num_parents = 1, }, }; -static CLK_DIV(g12a_hifi_pll, HHI_HIFI_PLL_CNTL0, 16, 2, (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), +static CLK_DIV(g12a_hifi_pll, HHI_HIFI_PLL_CNTL0, 16, 2, + (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), { &g12a_hifi_pll_dco }, 1, 0); /* @@ -491,10 +532,12 @@ static struct clk g12a_pcie_pll_dco = { .num_parents = 1, }, }; -static CLK_FIXED_FACTOR(g12a_pcie_pll_dco_div2, 1, 2, 0, { &g12a_pcie_pll_dco }, 1, 0); +static CLK_FIXED_FACTOR(g12a_pcie_pll_dco_div2, 1, 2, 0, { &g12a_pcie_pll_dco }, + 1, 0); static CLK_DIV(g12a_pcie_pll_od, HHI_PCIE_PLL_CNTL0, 16, 5, - CLK_DIVIDER_ROUND_CLOSEST | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, { &g12a_pcie_pll_dco_div2 }, - 1, 0); + CLK_DIVIDER_ROUND_CLOSEST | CLK_DIVIDER_ONE_BASED + | CLK_DIVIDER_ALLOW_ZERO, + { &g12a_pcie_pll_dco_div2 }, 1, 0); static CLK_FIXED_FACTOR(g12a_pcie_pll, 1, 2, 0, { &g12a_pcie_pll_od }, 1, 0); static struct clk g12a_hdmi_pll_dco = { .data = &(struct meson_clk_pll_data){ @@ -543,26 +586,37 @@ static struct clk g12a_hdmi_pll_dco = { .flags = CLK_GET_RATE_NOCACHE, }, }; -static CLK_DIV_RO(g12a_hdmi_pll_od, HHI_HDMI_PLL_CNTL0, 16, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_dco }, 1, 0); -static CLK_DIV_RO(g12a_hdmi_pll_od2, HHI_HDMI_PLL_CNTL0, 18, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_od }, 1, 0); -static CLK_DIV_RO(g12a_hdmi_pll, HHI_HDMI_PLL_CNTL0, 20, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_od2 }, 1, 0); +static CLK_DIV_RO(g12a_hdmi_pll_od, HHI_HDMI_PLL_CNTL0, 16, 2, + CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_dco }, 1, 0); +static CLK_DIV_RO(g12a_hdmi_pll_od2, HHI_HDMI_PLL_CNTL0, 18, 2, + CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_od }, 1, 0); +static CLK_DIV_RO(g12a_hdmi_pll, HHI_HDMI_PLL_CNTL0, 20, 2, + CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_od2 }, 1, 0); static CLK_FIXED_FACTOR(g12a_fclk_div4_div, 1, 4, 0, { &g12a_fixed_pll }, 1, 0); -static CLK_GATE(g12a_fclk_div4, HHI_FIX_PLL_CNTL1, 21, 0, { &g12a_fclk_div4_div }, 1, 0); +static CLK_GATE(g12a_fclk_div4, HHI_FIX_PLL_CNTL1, 21, 0, + { &g12a_fclk_div4_div }, 1, 0); static CLK_FIXED_FACTOR(g12a_fclk_div5_div, 1, 5, 0, { &g12a_fixed_pll }, 1, 0); -static CLK_GATE(g12a_fclk_div5, HHI_FIX_PLL_CNTL1, 22, 0, { &g12a_fclk_div5_div }, 1, 0); +static CLK_GATE(g12a_fclk_div5, HHI_FIX_PLL_CNTL1, 22, 0, + { &g12a_fclk_div5_div }, 1, 0); static CLK_FIXED_FACTOR(g12a_fclk_div7_div, 1, 7, 0, { &g12a_fixed_pll }, 1, 0); -static CLK_GATE(g12a_fclk_div7, HHI_FIX_PLL_CNTL1, 23, 0, { &g12a_fclk_div7_div }, 1, 0); -static CLK_FIXED_FACTOR(g12a_fclk_div2p5_div, 1, 5, 0, { &g12a_fixed_pll_dco }, 1, 0); -static CLK_GATE(g12a_fclk_div2p5, HHI_FIX_PLL_CNTL1, 25, 0, { &g12a_fclk_div2p5_div }, 1, 0); -static CLK_FIXED_FACTOR(g12a_mpll_50m_div, 1, 80, 0, { &g12a_fixed_pll_dco }, 1, 0); +static CLK_GATE(g12a_fclk_div7, HHI_FIX_PLL_CNTL1, 23, 0, + { &g12a_fclk_div7_div }, 1, 0); +static CLK_FIXED_FACTOR(g12a_fclk_div2p5_div, 1, 5, 0, { &g12a_fixed_pll_dco }, + 1, 0); +static CLK_GATE(g12a_fclk_div2p5, HHI_FIX_PLL_CNTL1, 25, 0, + { &g12a_fclk_div2p5_div }, 1, 0); +static CLK_FIXED_FACTOR(g12a_mpll_50m_div, 1, 80, 0, { &g12a_fixed_pll_dco }, 1, + 0); const static struct clk_parent_data g12a_mpll_50m_parent_table[] = { { .name = "xtal", }, { .clk = &g12a_mpll_50m_div }, }; -static CLK_MUX_RO(g12a_mpll_50m, HHI_FIX_PLL_CNTL3, 0x1, 5, 0, 0, g12a_mpll_50m_parent_table, 2, 0); -static CLK_FIXED_FACTOR(g12a_mpll_prediv, 1, 2, 0, { &g12a_fixed_pll_dco }, 1, 0); +static CLK_MUX_RO(g12a_mpll_50m, HHI_FIX_PLL_CNTL3, 0x1, 5, 0, 0, + g12a_mpll_50m_parent_table, 2, 0); +static CLK_FIXED_FACTOR(g12a_mpll_prediv, 1, 2, 0, { &g12a_fixed_pll_dco }, 1, + 0); static const struct reg_sequence g12a_mpll0_init_regs[] = { { .reg = HHI_MPLL_CNTL2, .def = 0x40000033 }, @@ -733,10 +787,13 @@ static const struct clk_parent_data clk81_parent_data[] = { { .clk = &g12a_fclk_div3 }, { .clk = &g12a_fclk_div5 }, }; -static CLK_MUX_RO(g12a_mpeg_clk_sel, HHI_MPEG_CLK_CNTL, 0x7, 12, mux_table_clk81, 0, clk81_parent_data, +static CLK_MUX_RO(g12a_mpeg_clk_sel, HHI_MPEG_CLK_CNTL, 0x7, 12, + mux_table_clk81, 0, clk81_parent_data, ARRAY_SIZE(clk81_parent_data), 0); -static CLK_DIV(g12a_mpeg_clk_div, HHI_MPEG_CLK_CNTL, 0, 7, 0, { &g12a_mpeg_clk_sel }, 1, 0); -static CLK_GATE(g12a_clk81, HHI_MPEG_CLK_CNTL, 7, 0, { &g12a_mpeg_clk_div }, 1, 0); +static CLK_DIV(g12a_mpeg_clk_div, HHI_MPEG_CLK_CNTL, 0, 7, 0, + { &g12a_mpeg_clk_sel }, 1, 0); +static CLK_GATE(g12a_clk81, HHI_MPEG_CLK_CNTL, 7, 0, { &g12a_mpeg_clk_div }, 1, + 0); static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = { { .name = "xtal", @@ -746,18 +803,24 @@ static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = { { .clk = &g12a_fclk_div5 }, { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(g12a_sd_emmc_a_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 9, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, - CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_sd_emmc_a_clk0_div, HHI_SD_EMMC_CLK_CNTL, 0, 7, 0, { &g12a_sd_emmc_a_clk0_sel }, 1, 0); -static CLK_GATE(g12a_sd_emmc_a_clk0, HHI_SD_EMMC_CLK_CNTL, 7, 0, { &g12a_sd_emmc_a_clk0_div }, 1, 0); -static CLK_MUX(g12a_sd_emmc_b_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 25, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, - CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_sd_emmc_b_clk0_div, HHI_SD_EMMC_CLK_CNTL, 16, 7, 0, { &g12a_sd_emmc_b_clk0_sel }, 1, 0); -static CLK_GATE(g12a_sd_emmc_b_clk0, HHI_SD_EMMC_CLK_CNTL, 23, 0, { &g12a_sd_emmc_b_clk0_div }, 1, 0); -static CLK_MUX(g12a_sd_emmc_c_clk0_sel, HHI_NAND_CLK_CNTL, 0x7, 9, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, - CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_sd_emmc_c_clk0_div, HHI_NAND_CLK_CNTL, 0, 7, 0, { &g12a_sd_emmc_c_clk0_sel }, 1, 0); -static CLK_GATE(g12a_sd_emmc_c_clk0, HHI_NAND_CLK_CNTL, 7, 0, { &g12a_sd_emmc_c_clk0_div }, 1, 0); +static CLK_MUX(g12a_sd_emmc_a_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 9, 0, 0, + g12a_sd_emmc_clk0_parent_data, 0, CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_sd_emmc_a_clk0_div, HHI_SD_EMMC_CLK_CNTL, 0, 7, 0, + { &g12a_sd_emmc_a_clk0_sel }, 1, 0); +static CLK_GATE(g12a_sd_emmc_a_clk0, HHI_SD_EMMC_CLK_CNTL, 7, 0, + { &g12a_sd_emmc_a_clk0_div }, 1, 0); +static CLK_MUX(g12a_sd_emmc_b_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 25, 0, 0, + g12a_sd_emmc_clk0_parent_data, 0, CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_sd_emmc_b_clk0_div, HHI_SD_EMMC_CLK_CNTL, 16, 7, 0, + { &g12a_sd_emmc_b_clk0_sel }, 1, 0); +static CLK_GATE(g12a_sd_emmc_b_clk0, HHI_SD_EMMC_CLK_CNTL, 23, 0, + { &g12a_sd_emmc_b_clk0_div }, 1, 0); +static CLK_MUX(g12a_sd_emmc_c_clk0_sel, HHI_NAND_CLK_CNTL, 0x7, 9, 0, 0, + g12a_sd_emmc_clk0_parent_data, 0, CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_sd_emmc_c_clk0_div, HHI_NAND_CLK_CNTL, 0, 7, 0, + { &g12a_sd_emmc_c_clk0_sel }, 1, 0); +static CLK_GATE(g12a_sd_emmc_c_clk0, HHI_NAND_CLK_CNTL, 7, 0, + { &g12a_sd_emmc_c_clk0_div }, 1, 0); static struct clk g12a_vid_pll_div = { .data = &(struct meson_vid_pll_div_data){ .val = { @@ -788,9 +851,11 @@ static const struct clk_parent_data g12a_vid_pll_parent_table[] = { }, }; -static CLK_MUX(g12a_vid_pll_sel, HHI_VID_PLL_CLK_DIV, 0x1, 18, 0, 0, g12a_vid_pll_parent_table, 0, +static CLK_MUX(g12a_vid_pll_sel, HHI_VID_PLL_CLK_DIV, 0x1, 18, 0, 0, + g12a_vid_pll_parent_table, 0, CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_GATE(g12a_vid_pll, HHI_VID_PLL_CLK_DIV, 19, 0, { &g12a_vid_pll_sel }, 1, 0); +static CLK_GATE(g12a_vid_pll, HHI_VID_PLL_CLK_DIV, 19, 0, { &g12a_vid_pll_sel }, + 1, 0); const static struct clk_parent_data g12a_vpu_sel_parent_table[] = { { .clk = &g12a_fclk_div3, @@ -817,17 +882,22 @@ const static struct clk_parent_data g12a_vpu_sel_parent_table[] = { .clk = &g12a_gp0_pll, }, }; -static CLK_MUX(g12a_vpu_0_sel, HHI_VPU_CLK_CNTL, 0x7, 9, 0, 0, g12a_vpu_sel_parent_table, 0, CLK_SET_RATE_NO_REPARENT); -static CLK_DIV(g12a_vpu_0_div, HHI_VPU_CLK_CNTL, 0, 7, 0, { &g12a_vpu_0_sel }, 1, 0); +static CLK_MUX(g12a_vpu_0_sel, HHI_VPU_CLK_CNTL, 0x7, 9, 0, 0, + g12a_vpu_sel_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vpu_0_div, HHI_VPU_CLK_CNTL, 0, 7, 0, { &g12a_vpu_0_sel }, + 1, 0); static CLK_GATE(g12a_vpu_0, HHI_VPU_CLK_CNTL, 8, 0, { &g12a_vpu_0_div }, 1, 0); -static CLK_MUX(g12a_vpu_1_sel, HHI_VPU_CLK_CNTL, 0x7, 25, 0, 0, g12a_vpu_sel_parent_table, 0, CLK_SET_RATE_NO_REPARENT); -static CLK_DIV(g12a_vpu_1_div, HHI_VPU_CLK_CNTL, 16, 7, 0, { &g12a_vpu_1_sel }, 1, 0); +static CLK_MUX(g12a_vpu_1_sel, HHI_VPU_CLK_CNTL, 0x7, 25, 0, 0, + g12a_vpu_sel_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vpu_1_div, HHI_VPU_CLK_CNTL, 16, 7, 0, { &g12a_vpu_1_sel }, + 1, 0); static CLK_GATE(g12a_vpu_1, HHI_VPU_CLK_CNTL, 24, 0, { &g12a_vpu_1_div }, 1, 0); const struct clk_parent_data g12a_vpu_parent_table[] = { { .clk = &g12a_vpu_0 }, { .clk = &g12a_vpu_1 }, }; -static CLK_MUX(g12a_vpu, HHI_VPU_CLK_CNTL, 1, 31, 0, 0, g12a_vpu_parent_table, 2, 0); +static CLK_MUX(g12a_vpu, HHI_VPU_CLK_CNTL, 1, 31, 0, 0, g12a_vpu_parent_table, + 2, 0); static const struct clk_parent_data g12a_vdec_parent_table[] = { { .clk = &g12a_fclk_div2p5, @@ -852,19 +922,27 @@ static const struct clk_parent_data g12a_vdec_parent_table[] = { }, }; -static CLK_MUX(g12a_vdec_1_sel, HHI_VDEC_CLK_CNTL, 0x7, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, +static CLK_MUX(g12a_vdec_1_sel, HHI_VDEC_CLK_CNTL, 0x7, 9, 0, + CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_vdec_1_div, HHI_VDEC_CLK_CNTL, 0, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_1_sel }, 1, 0); -static CLK_GATE(g12a_vdec_1, HHI_VDEC_CLK_CNTL, 8, 0, { &g12a_vdec_1_div }, 1, 0); -static CLK_MUX(g12a_vdec_hevcf_sel, HHI_VDEC2_CLK_CNTL, 0x7, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, +static CLK_DIV(g12a_vdec_1_div, HHI_VDEC_CLK_CNTL, 0, 7, + CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_1_sel }, 1, 0); +static CLK_GATE(g12a_vdec_1, HHI_VDEC_CLK_CNTL, 8, 0, { &g12a_vdec_1_div }, 1, + 0); +static CLK_MUX(g12a_vdec_hevcf_sel, HHI_VDEC2_CLK_CNTL, 0x7, 9, 0, + CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_vdec_hevcf_div, HHI_VDEC2_CLK_CNTL, 0, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevcf_sel }, 1, - 0); -static CLK_GATE(g12a_vdec_hevcf, HHI_VDEC2_CLK_CNTL, 8, 0, { &g12a_vdec_hevcf_div }, 1, 0); -static CLK_MUX(g12a_vdec_hevc_sel, HHI_VDEC2_CLK_CNTL, 0x7, 25, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, +static CLK_DIV(g12a_vdec_hevcf_div, HHI_VDEC2_CLK_CNTL, 0, 7, + CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevcf_sel }, 1, 0); +static CLK_GATE(g12a_vdec_hevcf, HHI_VDEC2_CLK_CNTL, 8, 0, + { &g12a_vdec_hevcf_div }, 1, 0); +static CLK_MUX(g12a_vdec_hevc_sel, HHI_VDEC2_CLK_CNTL, 0x7, 25, 0, + CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_vdec_hevc_div, HHI_VDEC2_CLK_CNTL, 16, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevc_sel }, 1, 0); -static CLK_GATE(g12a_vdec_hevc, HHI_VDEC2_CLK_CNTL, 24, 0, { &g12a_vdec_hevc_div }, 1, 0); +static CLK_DIV(g12a_vdec_hevc_div, HHI_VDEC2_CLK_CNTL, 16, 7, + CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevc_sel }, 1, 0); +static CLK_GATE(g12a_vdec_hevc, HHI_VDEC2_CLK_CNTL, 24, 0, + { &g12a_vdec_hevc_div }, 1, 0); static const struct clk_parent_data g12a_vapb_parent_table[] = { { .clk = &g12a_fclk_div4, @@ -891,17 +969,24 @@ static const struct clk_parent_data g12a_vapb_parent_table[] = { .clk = &g12a_fclk_div2p5, }, }; -static CLK_MUX(g12a_vapb_0_sel, HHI_VAPBCLK_CNTL, 0x3, 9, 0, 0, g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); -static CLK_DIV(g12a_vapb_0_div, HHI_VAPBCLK_CNTL, 0, 7, 0, { &g12a_vapb_0_sel }, 1, 0); -static CLK_GATE(g12a_vapb_0, HHI_VAPBCLK_CNTL, 8, 0, { &g12a_vapb_0_div }, 1, 0); -static CLK_MUX(g12a_vapb_1_sel, HHI_VAPBCLK_CNTL, 0x3, 25, 0, 0, g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); -static CLK_DIV(g12a_vapb_1_div, HHI_VAPBCLK_CNTL, 16, 7, 0, { &g12a_vapb_1_sel }, 1, 0); -static CLK_GATE(g12a_vapb_1, HHI_VAPBCLK_CNTL, 24, 0, { &g12a_vapb_1_div }, 1, 0); +static CLK_MUX(g12a_vapb_0_sel, HHI_VAPBCLK_CNTL, 0x3, 9, 0, 0, + g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vapb_0_div, HHI_VAPBCLK_CNTL, 0, 7, 0, { &g12a_vapb_0_sel }, + 1, 0); +static CLK_GATE(g12a_vapb_0, HHI_VAPBCLK_CNTL, 8, 0, { &g12a_vapb_0_div }, 1, + 0); +static CLK_MUX(g12a_vapb_1_sel, HHI_VAPBCLK_CNTL, 0x3, 25, 0, 0, + g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vapb_1_div, HHI_VAPBCLK_CNTL, 16, 7, 0, + { &g12a_vapb_1_sel }, 1, 0); +static CLK_GATE(g12a_vapb_1, HHI_VAPBCLK_CNTL, 24, 0, { &g12a_vapb_1_div }, 1, + 0); const struct clk_parent_data g12a_vapb_sel_parent_table[] = { { .clk = &g12a_vapb_0 }, { .clk = &g12a_vapb_1 }, }; -static CLK_MUX(g12a_vapb_sel, HHI_VAPBCLK_CNTL, 1, 31, 0, 0, g12a_vapb_sel_parent_table, 2, 0); +static CLK_MUX(g12a_vapb_sel, HHI_VAPBCLK_CNTL, 1, 31, 0, 0, + g12a_vapb_sel_parent_table, 2, 0); static CLK_GATE(g12a_vapb, HHI_VAPBCLK_CNTL, 30, 0, { &g12a_vapb_sel }, 1, 0); static const struct clk_parent_data g12a_vclk_parent_table[] = { { @@ -929,12 +1014,17 @@ static const struct clk_parent_data g12a_vclk_parent_table[] = { .clk = &g12a_fclk_div7, }, }; -static CLK_MUX(g12a_vclk_sel, HHI_VID_CLK_CNTL, 0x7, 16, 0, 0, g12a_vclk_parent_table, 0, +static CLK_MUX(g12a_vclk_sel, HHI_VID_CLK_CNTL, 0x7, 16, 0, 0, + g12a_vclk_parent_table, 0, CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_MUX(g12a_vclk2_sel, HHI_VIID_CLK_CNTL, 0x7, 16, 0, 0, g12a_vclk_parent_table, 0, CLK_SET_RATE_NO_REPARENT); -static CLK_GATE(g12a_vclk_input, HHI_VID_CLK_DIV, 16, 0, { &g12a_vclk_sel }, 1, 0); -static CLK_GATE(g12a_vclk2_input, HHI_VIID_CLK_DIV, 16, 0, { &g12a_vclk2_sel }, 1, 0); -static CLK_DIV(g12a_vclk_div, HHI_VID_CLK_DIV, 0, 8, 0, { &g12a_vclk_input }, 1, 0); +static CLK_MUX(g12a_vclk2_sel, HHI_VIID_CLK_CNTL, 0x7, 16, 0, 0, + g12a_vclk_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_GATE(g12a_vclk_input, HHI_VID_CLK_DIV, 16, 0, { &g12a_vclk_sel }, 1, + 0); +static CLK_GATE(g12a_vclk2_input, HHI_VIID_CLK_DIV, 16, 0, { &g12a_vclk2_sel }, + 1, 0); +static CLK_DIV(g12a_vclk_div, HHI_VID_CLK_DIV, 0, 8, 0, { &g12a_vclk_input }, 1, + 0); static struct clk g12a_vclk2_div = { .data = &(struct meson_vclk_div_data){ .div = { @@ -987,23 +1077,37 @@ static struct clk g12a_vclk2 = { }, }; static CLK_GATE(g12a_vclk_div1, HHI_VID_CLK_CNTL, 0, 0, { &g12a_vclk }, 1, 0); -static CLK_GATE(g12a_vclk_div2_en, HHI_VID_CLK_CNTL, 1, 0, { &g12a_vclk }, 1, 0); -static CLK_GATE(g12a_vclk_div4_en, HHI_VID_CLK_CNTL, 2, 0, { &g12a_vclk }, 1, 0); -static CLK_GATE(g12a_vclk_div6_en, HHI_VID_CLK_CNTL, 3, 0, { &g12a_vclk }, 1, 0); -static CLK_GATE(g12a_vclk_div12_en, HHI_VID_CLK_CNTL, 4, 0, { &g12a_vclk }, 1, 0); -static CLK_GATE(g12a_vclk2_div1, HHI_VIID_CLK_CNTL, 0, 0, { &g12a_vclk2 }, 1, 0); -static CLK_GATE(g12a_vclk2_div2_en, HHI_VIID_CLK_CNTL, 1, 0, { &g12a_vclk2 }, 1, 0); -static CLK_GATE(g12a_vclk2_div4_en, HHI_VIID_CLK_CNTL, 2, 0, { &g12a_vclk2 }, 1, 0); -static CLK_GATE(g12a_vclk2_div6_en, HHI_VIID_CLK_CNTL, 3, 0, { &g12a_vclk2 }, 1, 0); -static CLK_GATE(g12a_vclk2_div12_en, HHI_VIID_CLK_CNTL, 4, 0, { &g12a_vclk2 }, 1, 0); +static CLK_GATE(g12a_vclk_div2_en, HHI_VID_CLK_CNTL, 1, 0, { &g12a_vclk }, 1, + 0); +static CLK_GATE(g12a_vclk_div4_en, HHI_VID_CLK_CNTL, 2, 0, { &g12a_vclk }, 1, + 0); +static CLK_GATE(g12a_vclk_div6_en, HHI_VID_CLK_CNTL, 3, 0, { &g12a_vclk }, 1, + 0); +static CLK_GATE(g12a_vclk_div12_en, HHI_VID_CLK_CNTL, 4, 0, { &g12a_vclk }, 1, + 0); +static CLK_GATE(g12a_vclk2_div1, HHI_VIID_CLK_CNTL, 0, 0, { &g12a_vclk2 }, 1, + 0); +static CLK_GATE(g12a_vclk2_div2_en, HHI_VIID_CLK_CNTL, 1, 0, { &g12a_vclk2 }, 1, + 0); +static CLK_GATE(g12a_vclk2_div4_en, HHI_VIID_CLK_CNTL, 2, 0, { &g12a_vclk2 }, 1, + 0); +static CLK_GATE(g12a_vclk2_div6_en, HHI_VIID_CLK_CNTL, 3, 0, { &g12a_vclk2 }, 1, + 0); +static CLK_GATE(g12a_vclk2_div12_en, HHI_VIID_CLK_CNTL, 4, 0, { &g12a_vclk2 }, + 1, 0); static CLK_FIXED_FACTOR(g12a_vclk_div2, 1, 2, 0, { &g12a_vclk_div2_en }, 1, 0); static CLK_FIXED_FACTOR(g12a_vclk_div4, 1, 4, 0, { &g12a_vclk_div4_en }, 1, 0); static CLK_FIXED_FACTOR(g12a_vclk_div6, 1, 6, 0, { &g12a_vclk_div6_en }, 1, 0); -static CLK_FIXED_FACTOR(g12a_vclk_div12, 1, 12, 0, { &g12a_vclk_div12_en }, 1, 0); -static CLK_FIXED_FACTOR(g12a_vclk2_div2, 1, 2, 0, { &g12a_vclk2_div2_en }, 1, 0); -static CLK_FIXED_FACTOR(g12a_vclk2_div4, 1, 4, 0, { &g12a_vclk2_div4_en }, 1, 0); -static CLK_FIXED_FACTOR(g12a_vclk2_div6, 1, 6, 0, { &g12a_vclk2_div6_en }, 1, 0); -static CLK_FIXED_FACTOR(g12a_vclk2_div12, 1, 12, 0, { &g12a_vclk2_div12_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk_div12, 1, 12, 0, { &g12a_vclk_div12_en }, 1, + 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div2, 1, 2, 0, { &g12a_vclk2_div2_en }, 1, + 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div4, 1, 4, 0, { &g12a_vclk2_div4_en }, 1, + 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div6, 1, 6, 0, { &g12a_vclk2_div6_en }, 1, + 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div12, 1, 12, 0, { &g12a_vclk2_div12_en }, 1, + 0); static uint32_t mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; static const struct clk_parent_data g12a_cts_parent_table[] = { { @@ -1037,14 +1141,18 @@ static const struct clk_parent_data g12a_cts_parent_table[] = { .clk = &g12a_vclk2_div12, }, }; -static CLK_MUX(g12a_cts_enci_sel, HHI_VID_CLK_DIV, 0xf, 28, mux_table_cts_sel, 0, g12a_cts_parent_table, - ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_MUX(g12a_cts_encp_sel, HHI_VID_CLK_DIV, 0xf, 20, mux_table_cts_sel, 0, g12a_cts_parent_table, - ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_MUX(g12a_cts_encl_sel, HHI_VIID_CLK_DIV, 0xf, 12, mux_table_cts_sel, 0, g12a_cts_parent_table, - ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT); -static CLK_MUX(g12a_cts_vdac_sel, HHI_VIID_CLK_DIV, 0xf, 28, mux_table_cts_sel, 0, g12a_cts_parent_table, - ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_MUX(g12a_cts_enci_sel, HHI_VID_CLK_DIV, 0xf, 28, mux_table_cts_sel, + 0, g12a_cts_parent_table, ARRAY_SIZE(g12a_cts_parent_table), + CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_MUX(g12a_cts_encp_sel, HHI_VID_CLK_DIV, 0xf, 20, mux_table_cts_sel, + 0, g12a_cts_parent_table, ARRAY_SIZE(g12a_cts_parent_table), + CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_MUX(g12a_cts_encl_sel, HHI_VIID_CLK_DIV, 0xf, 12, mux_table_cts_sel, + 0, g12a_cts_parent_table, ARRAY_SIZE(g12a_cts_parent_table), + CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT); +static CLK_MUX(g12a_cts_vdac_sel, HHI_VIID_CLK_DIV, 0xf, 28, mux_table_cts_sel, + 0, g12a_cts_parent_table, ARRAY_SIZE(g12a_cts_parent_table), + CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); static uint32_t mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; static const struct clk_parent_data g12a_cts_hdmi_tx_parent_table[] = { { @@ -1078,13 +1186,20 @@ static const struct clk_parent_data g12a_cts_hdmi_tx_parent_table[] = { .clk = &g12a_vclk2_div12, }, }; -static CLK_MUX(g12a_hdmi_tx_sel, HHI_HDMI_CLK_CNTL, 0xf, 16, mux_table_hdmi_tx_sel, 0, g12a_cts_hdmi_tx_parent_table, - ARRAY_SIZE(g12a_cts_hdmi_tx_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_GATE(g12a_cts_enci, HHI_VID_CLK_CNTL2, 0, 0, { &g12a_cts_enci_sel }, 1, 0); -static CLK_GATE(g12a_cts_encp, HHI_VID_CLK_CNTL2, 2, 0, { &g12a_cts_encp_sel }, 1, 0); -static CLK_GATE(g12a_cts_encl, HHI_VID_CLK_CNTL2, 3, 0, { &g12a_cts_encl_sel }, 1, 0); -static CLK_GATE(g12a_cts_vdac, HHI_VID_CLK_CNTL2, 4, 0, { &g12a_cts_vdac_sel }, 1, 0); -static CLK_GATE(g12a_hdmi_tx, HHI_VID_CLK_CNTL2, 5, 0, { &g12a_hdmi_tx_sel }, 1, 0); +static CLK_MUX(g12a_hdmi_tx_sel, HHI_HDMI_CLK_CNTL, 0xf, 16, + mux_table_hdmi_tx_sel, 0, g12a_cts_hdmi_tx_parent_table, + ARRAY_SIZE(g12a_cts_hdmi_tx_parent_table), + CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_GATE(g12a_cts_enci, HHI_VID_CLK_CNTL2, 0, 0, { &g12a_cts_enci_sel }, + 1, 0); +static CLK_GATE(g12a_cts_encp, HHI_VID_CLK_CNTL2, 2, 0, { &g12a_cts_encp_sel }, + 1, 0); +static CLK_GATE(g12a_cts_encl, HHI_VID_CLK_CNTL2, 3, 0, { &g12a_cts_encl_sel }, + 1, 0); +static CLK_GATE(g12a_cts_vdac, HHI_VID_CLK_CNTL2, 4, 0, { &g12a_cts_vdac_sel }, + 1, 0); +static CLK_GATE(g12a_hdmi_tx, HHI_VID_CLK_CNTL2, 5, 0, { &g12a_hdmi_tx_sel }, 1, + 0); static const struct clk_parent_data g12a_mipi_dsi_pxclk_parent_table[] = { { .clk = &g12a_vid_pll, @@ -1111,11 +1226,14 @@ static const struct clk_parent_data g12a_mipi_dsi_pxclk_parent_table[] = { .clk = &g12a_fclk_div7, }, }; -static CLK_MUX(g12a_mipi_dsi_pxclk_sel, HHI_MIPIDSI_PHY_CLK_CNTL, 0x7, 12, 0, CLK_MUX_ROUND_CLOSEST, - g12a_mipi_dsi_pxclk_parent_table, ARRAY_SIZE(g12a_mipi_dsi_pxclk_parent_table), +static CLK_MUX(g12a_mipi_dsi_pxclk_sel, HHI_MIPIDSI_PHY_CLK_CNTL, 0x7, 12, 0, + CLK_MUX_ROUND_CLOSEST, g12a_mipi_dsi_pxclk_parent_table, + ARRAY_SIZE(g12a_mipi_dsi_pxclk_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_mipi_dsi_pxclk_div, HHI_MIPIDSI_PHY_CLK_CNTL, 0, 7, 0, { &g12a_mipi_dsi_pxclk_sel }, 1, 0); -static CLK_GATE(g12a_mipi_dsi_pxclk, HHI_MIPIDSI_PHY_CLK_CNTL, 8, 0, { &g12a_mipi_dsi_pxclk_div }, 1, 0); +static CLK_DIV(g12a_mipi_dsi_pxclk_div, HHI_MIPIDSI_PHY_CLK_CNTL, 0, 7, 0, + { &g12a_mipi_dsi_pxclk_sel }, 1, 0); +static CLK_GATE(g12a_mipi_dsi_pxclk, HHI_MIPIDSI_PHY_CLK_CNTL, 8, 0, + { &g12a_mipi_dsi_pxclk_div }, 1, 0); static const struct clk_parent_data g12a_hdmi_parent_table[] = { { .name = "xtal", @@ -1124,9 +1242,12 @@ static const struct clk_parent_data g12a_hdmi_parent_table[] = { { .clk = &g12a_fclk_div3 }, { .clk = &g12a_fclk_div5 }, }; -static CLK_MUX(g12a_hdmi_sel, HHI_HDMI_CLK_CNTL, 0x3, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_hdmi_parent_table, - ARRAY_SIZE(g12a_hdmi_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_DIV(g12a_hdmi_div, HHI_HDMI_CLK_CNTL, 0, 7, 0, { &g12a_hdmi_sel }, 1, 0); +static CLK_MUX(g12a_hdmi_sel, HHI_HDMI_CLK_CNTL, 0x3, 9, 0, + CLK_MUX_ROUND_CLOSEST, g12a_hdmi_parent_table, + ARRAY_SIZE(g12a_hdmi_parent_table), + CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_DIV(g12a_hdmi_div, HHI_HDMI_CLK_CNTL, 0, 7, 0, { &g12a_hdmi_sel }, 1, + 0); static CLK_GATE(g12a_hdmi, HHI_HDMI_CLK_CNTL, 8, 0, { &g12a_hdmi_div }, 1, 0); static const struct clk_parent_data g12a_mali_0_1_parent_data[] = { { @@ -1140,12 +1261,18 @@ static const struct clk_parent_data g12a_mali_0_1_parent_data[] = { { .clk = &g12a_fclk_div5 }, { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(g12a_mali_0_sel, HHI_MALI_CLK_CNTL, 0x7, 9, 0, 0, g12a_mali_0_1_parent_data, 8, 0); -static CLK_DIV(g12a_mali_0_div, HHI_MALI_CLK_CNTL, 0, 7, 0, { &g12a_mali_0_sel }, 1, 0); -static CLK_GATE(g12a_mali_0, HHI_MALI_CLK_CNTL, 8, 0, { &g12a_mali_0_div }, 1, 0); -static CLK_MUX(g12a_mali_1_sel, HHI_MALI_CLK_CNTL, 0x7, 25, 0, 0, g12a_mali_0_1_parent_data, 8, 0); -static CLK_DIV(g12a_mali_1_div, HHI_MALI_CLK_CNTL, 16, 7, 0, { &g12a_mali_1_sel }, 1, 0); -static CLK_GATE(g12a_mali_1, HHI_MALI_CLK_CNTL, 24, 0, { &g12a_mali_1_div }, 1, 0); +static CLK_MUX(g12a_mali_0_sel, HHI_MALI_CLK_CNTL, 0x7, 9, 0, 0, + g12a_mali_0_1_parent_data, 8, 0); +static CLK_DIV(g12a_mali_0_div, HHI_MALI_CLK_CNTL, 0, 7, 0, + { &g12a_mali_0_sel }, 1, 0); +static CLK_GATE(g12a_mali_0, HHI_MALI_CLK_CNTL, 8, 0, { &g12a_mali_0_div }, 1, + 0); +static CLK_MUX(g12a_mali_1_sel, HHI_MALI_CLK_CNTL, 0x7, 25, 0, 0, + g12a_mali_0_1_parent_data, 8, 0); +static CLK_DIV(g12a_mali_1_div, HHI_MALI_CLK_CNTL, 16, 7, 0, + { &g12a_mali_1_sel }, 1, 0); +static CLK_GATE(g12a_mali_1, HHI_MALI_CLK_CNTL, 24, 0, { &g12a_mali_1_div }, 1, + 0); static const struct clk_parent_data g12a_mali_parent_table[] = { { .clk = &g12a_mali_0, @@ -1154,8 +1281,10 @@ static const struct clk_parent_data g12a_mali_parent_table[] = { .clk = &g12a_mali_1, }, }; -static CLK_MUX(g12a_mali, HHI_MALI_CLK_CNTL, 1, 31, 0, 0, g12a_mali_parent_table, 2, CLK_SET_RATE_PARENT); -static CLK_DIV_RO(g12a_ts_div, HHI_TS_CLK_CNTL, 0, 8, 0, { &g12a_ts_div }, 1, 0); +static CLK_MUX(g12a_mali, HHI_MALI_CLK_CNTL, 1, 31, 0, 0, + g12a_mali_parent_table, 2, CLK_SET_RATE_PARENT); +static CLK_DIV_RO(g12a_ts_div, HHI_TS_CLK_CNTL, 0, 8, 0, { &g12a_ts_div }, 1, + 0); static CLK_GATE(g12a_ts, HHI_TS_CLK_CNTL, 8, 0, { &g12a_ts_div }, 1, 0); static const struct clk_parent_data spicc_sclk_parent_data[] = { { @@ -1168,12 +1297,18 @@ static const struct clk_parent_data spicc_sclk_parent_data[] = { { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(g12a_spicc0_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 7, 0, 0, spicc_sclk_parent_data, 0, 0); -static CLK_DIV(g12a_spicc0_sclk_div, HHI_SPICC_CLK_CNTL, 0, 6, 0, { &g12a_spicc0_sclk_sel }, 1, 0); -static CLK_GATE(g12a_spicc0_sclk, HHI_SPICC_CLK_CNTL, 6, 0, { &g12a_spicc0_sclk_div }, 1, 0); -static CLK_MUX(g12a_spicc1_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 23, 0, 0, spicc_sclk_parent_data, 0, 0); -static CLK_DIV(g12a_spicc1_sclk_div, HHI_SPICC_CLK_CNTL, 16, 6, 0, { &g12a_spicc1_sclk_sel }, 1, 0); -static CLK_GATE(g12a_spicc1_sclk, HHI_SPICC_CLK_CNTL, 22, 0, { &g12a_spicc1_sclk_div }, 1, 0); +static CLK_MUX(g12a_spicc0_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 7, 0, 0, + spicc_sclk_parent_data, 0, 0); +static CLK_DIV(g12a_spicc0_sclk_div, HHI_SPICC_CLK_CNTL, 0, 6, 0, + { &g12a_spicc0_sclk_sel }, 1, 0); +static CLK_GATE(g12a_spicc0_sclk, HHI_SPICC_CLK_CNTL, 6, 0, + { &g12a_spicc0_sclk_div }, 1, 0); +static CLK_MUX(g12a_spicc1_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 23, 0, 0, + spicc_sclk_parent_data, 0, 0); +static CLK_DIV(g12a_spicc1_sclk_div, HHI_SPICC_CLK_CNTL, 16, 6, 0, + { &g12a_spicc1_sclk_sel }, 1, 0); +static CLK_GATE(g12a_spicc1_sclk, HHI_SPICC_CLK_CNTL, 22, 0, + { &g12a_spicc1_sclk_div }, 1, 0); static const struct clk_parent_data nna_clk_parent_data[] = { { .name = "xtal", @@ -1198,12 +1333,18 @@ static const struct clk_parent_data nna_clk_parent_data[] = { }, { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(sm1_nna_axi_clk_sel, HHI_NNA_CLK_CNTL, 7, 9, 0, 0, nna_clk_parent_data, 0, 0); -static CLK_DIV(sm1_nna_axi_clk_div, HHI_NNA_CLK_CNTL, 0, 7, 0, { &sm1_nna_axi_clk_sel }, 1, 0); -static CLK_GATE(sm1_nna_axi_clk, HHI_NNA_CLK_CNTL, 8, 0, { &sm1_nna_axi_clk_div }, 1, 0); -static CLK_MUX(sm1_nna_core_clk_sel, HHI_NNA_CLK_CNTL, 7, 25, 0, 0, nna_clk_parent_data, 0, 0); -static CLK_DIV(sm1_nna_core_clk_div, HHI_NNA_CLK_CNTL, 16, 7, 0, { &sm1_nna_core_clk_sel }, 1, 0); -static CLK_GATE(sm1_nna_core_clk, HHI_NNA_CLK_CNTL, 24, 0, { &sm1_nna_core_clk_div }, 1, 0); +static CLK_MUX(sm1_nna_axi_clk_sel, HHI_NNA_CLK_CNTL, 7, 9, 0, 0, + nna_clk_parent_data, 0, 0); +static CLK_DIV(sm1_nna_axi_clk_div, HHI_NNA_CLK_CNTL, 0, 7, 0, + { &sm1_nna_axi_clk_sel }, 1, 0); +static CLK_GATE(sm1_nna_axi_clk, HHI_NNA_CLK_CNTL, 8, 0, + { &sm1_nna_axi_clk_div }, 1, 0); +static CLK_MUX(sm1_nna_core_clk_sel, HHI_NNA_CLK_CNTL, 7, 25, 0, 0, + nna_clk_parent_data, 0, 0); +static CLK_DIV(sm1_nna_core_clk_div, HHI_NNA_CLK_CNTL, 16, 7, 0, + { &sm1_nna_core_clk_sel }, 1, 0); +static CLK_GATE(sm1_nna_core_clk, HHI_NNA_CLK_CNTL, 24, 0, + { &sm1_nna_core_clk_div }, 1, 0); /* Everything Else (EE) domain gates */ static MESON_CLK81_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0); diff --git a/drivers/clk/utils.h b/drivers/clk/utils.h index 4476e7372..5a521673d 100644 --- a/drivers/clk/utils.h +++ b/drivers/clk/utils.h @@ -9,7 +9,7 @@ #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) -#define do_div(n, base) ({ \ +#define do_div(n, base) ({ \ uint32_t __base = (base); \ uint32_t __rem; \ __rem = ((uint64_t)(n)) % __base; \ diff --git a/examples/clk/build.zig.zon b/examples/clk/build.zig.zon index 7d4f5b7eb..6deea19f4 100644 --- a/examples/clk/build.zig.zon +++ b/examples/clk/build.zig.zon @@ -1,4 +1,7 @@ - +// +// Copyright 2024, UNSW +// SPDX-License-Identifier: BSD-2-Clause +// .{ .name = "sddf_clk_example", .version = "1.0.0", diff --git a/examples/clk/dts/odroidc4.dts b/examples/clk/dts/odroidc4.dts index 8207eba92..2cc3083c0 100644 --- a/examples/clk/dts/odroidc4.dts +++ b/examples/clk/dts/odroidc4.dts @@ -1,3 +1,13 @@ +/* + * Copyright Linux Kernel Team + * + * SPDX-License-Identifier: GPL-2.0-only + * + * This file is derived from an intermediate build stage of the + * Linux kernel. The licenses of all input files to this process + * are compatible with GPL-2.0-only. + */ + /dts-v1/; / { @@ -19,11 +29,7 @@ #address-cells = <0x02>; #size-cells = <0x02>; ranges; - linux,stdout-path = "/soc/bus@ff800000/serial@3000"; - stdout-path = "/soc/bus@ff800000/serial@3000"; - linux,initrd-end = <0x00000000 0x2e000000>; - linux,initrd-start = <0x00000000 0x2d700000>; - bootargs = "console=ttyAML0,115200n8 root=/dev/ram0 nosmp rw debug loglevel=8 pci=nomsi earlyprintk=serial maxcpus=1"; + stdout-path = "serial0:115200n8"; framebuffer-cvbs { compatible = "amlogic,simple-framebuffer\0simple-framebuffer"; @@ -51,9 +57,9 @@ secure-monitor = <0x04>; }; - opp-table-gpu { + gpu-opp-table { compatible = "operating-points-v2"; - phandle = <0x30>; + phandle = <0x38>; opp-124999998 { opp-hz = <0x00 0x773593e>; @@ -106,17 +112,11 @@ no-map; }; - secmon@5300000 { - reg = <0x00 0x5300000 0x00 0x2000000>; - no-map; - }; - linux,cma { compatible = "shared-dma-pool"; reusable; - size = <0x00 0x1000000>; + size = <0x00 0x10000000>; alignment = <0x00 0x400000>; - alloc-ranges = <0x00 0x8000000 0x10000000>; linux,cma-default; }; }; @@ -124,7 +124,6 @@ secure-monitor { compatible = "amlogic,meson-gxbb-sm"; phandle = <0x04>; - status = "disabled"; }; soc { @@ -157,6 +156,81 @@ power-domains = <0x03 0x03>; }; + thermal-zones { + + cpu-thermal { + polling-delay = <0x3e8>; + polling-delay-passive = <0x64>; + thermal-sensors = <0x07>; + + trips { + + cpu-passive { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x08>; + }; + + cpu-hot { + temperature = <0x17318>; + hysteresis = <0x7d0>; + type = "hot"; + phandle = <0x0d>; + }; + + cpu-critical { + temperature = <0x1adb0>; + hysteresis = <0x7d0>; + type = "critical"; + }; + }; + + cooling-maps { + + map0 { + trip = <0x08>; + cooling-device = <0x09 0xffffffff 0xffffffff 0x0a 0xffffffff 0xffffffff 0x0b 0xffffffff 0xffffffff 0x0c 0xffffffff 0xffffffff>; + }; + + map1 { + trip = <0x0d>; + cooling-device = <0x09 0xffffffff 0xffffffff 0x0a 0xffffffff 0xffffffff 0x0b 0xffffffff 0xffffffff 0x0c 0xffffffff 0xffffffff>; + }; + }; + }; + + ddr-thermal { + polling-delay = <0x3e8>; + polling-delay-passive = <0x64>; + thermal-sensors = <0x0e>; + + trips { + + ddr-passive { + temperature = <0x14c08>; + hysteresis = <0x7d0>; + type = "passive"; + phandle = <0x0f>; + }; + + ddr-critical { + temperature = <0x1adb0>; + hysteresis = <0x7d0>; + type = "critical"; + }; + }; + + cooling-maps { + + map { + trip = <0x0f>; + cooling-device = <0x10 0xffffffff 0xffffffff>; + }; + }; + }; + }; + ethernet@ff3f0000 { compatible = "amlogic,meson-g12a-dwmac\0snps,dwmac-3.70a\0snps,dwmac"; reg = <0x00 0xff3f0000 0x00 0x10000 0x00 0xff634540 0x00 0x08>; @@ -166,19 +240,19 @@ clock-names = "stmmaceth\0clkin0\0clkin1\0timing-adjustment"; rx-fifo-depth = <0x1000>; tx-fifo-depth = <0x800>; - status = "disabled"; + status = "okay"; power-domains = <0x03 0x06>; - pinctrl-0 = <0x07 0x08>; + pinctrl-0 = <0x11 0x12>; pinctrl-names = "default"; phy-mode = "rgmii"; - phy-handle = <0x09>; + phy-handle = <0x13>; amlogic,tx-delay-ns = <0x02>; mdio { #address-cells = <0x01>; #size-cells = <0x00>; compatible = "snps,dwmac-mdio"; - phandle = <0x13>; + phandle = <0x1e>; }; }; @@ -201,17 +275,17 @@ #size-cells = <0x00>; #sound-dai-cells = <0x00>; status = "okay"; - pinctrl-0 = <0x0a 0x0b>; + pinctrl-0 = <0x14 0x15>; pinctrl-names = "default"; - hdmi-supply = <0x0c>; - phandle = <0x1b>; + hdmi-supply = <0x16>; + phandle = <0x47>; port@0 { reg = <0x00>; endpoint { - remote-endpoint = <0x0d>; - phandle = <0x21>; + remote-endpoint = <0x17>; + phandle = <0x28>; }; }; @@ -219,8 +293,8 @@ reg = <0x01>; endpoint { - remote-endpoint = <0x0e>; - phandle = <0x42>; + remote-endpoint = <0x18>; + phandle = <0x40>; }; }; }; @@ -263,16 +337,16 @@ #address-cells = <0x02>; #size-cells = <0x02>; ranges; - phandle = <0x0f>; + phandle = <0x19>; bank@40 { reg = <0x00 0x40 0x00 0x4c 0x00 0xe8 0x00 0x18 0x00 0x120 0x00 0x18 0x00 0x2c0 0x00 0x40 0x00 0x340 0x00 0x1c>; reg-names = "gpio\0pull\0pull-enable\0mux\0ds"; gpio-controller; #gpio-cells = <0x02>; - gpio-ranges = <0x0f 0x00 0x00 0x56>; + gpio-ranges = <0x19 0x00 0x00 0x56>; gpio-line-names = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0PIN_36\0PIN_26\0PIN_32\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0PIN_27\0PIN_28\0PIN_16\0PIN_18\0PIN_22\0PIN_11\0PIN_13\0PIN_7\0PIN_33\0PIN_15\0PIN_19\0PIN_21\0PIN_24\0PIN_23\0PIN_8\0PIN_10\0PIN_29\0PIN_31\0PIN_12\0PIN_3\0PIN_5\0PIN_35"; - phandle = <0x14>; + phandle = <0x2b>; hog-0 { gpio-hog; @@ -283,7 +357,6 @@ }; cec_ao_a_h { - phandle = <0x1a>; mux { groups = "cec_ao_a_h"; @@ -293,7 +366,6 @@ }; cec_ao_b_h { - phandle = <0x1c>; mux { groups = "cec_ao_b_h"; @@ -303,7 +375,7 @@ }; emmc-ctrl { - phandle = <0x26>; + phandle = <0x2e>; mux-0 { groups = "emmc_cmd"; @@ -331,7 +403,7 @@ }; emmc-data-8b { - phandle = <0x27>; + phandle = <0x2f>; mux-0 { groups = "emmc_nand_d0\0emmc_nand_d1\0emmc_nand_d2\0emmc_nand_d3\0emmc_nand_d4\0emmc_nand_d5\0emmc_nand_d6\0emmc_nand_d7"; @@ -342,7 +414,7 @@ }; emmc-ds { - phandle = <0x28>; + phandle = <0x30>; mux { groups = "emmc_nand_ds"; @@ -353,7 +425,7 @@ }; emmc_clk_gate { - phandle = <0x29>; + phandle = <0x31>; mux { groups = "BOOT_8"; @@ -364,7 +436,7 @@ }; hdmitx_ddc { - phandle = <0x0b>; + phandle = <0x15>; mux { groups = "hdmitx_sda\0hdmitx_sck"; @@ -375,7 +447,7 @@ }; hdmitx_hpd { - phandle = <0x0a>; + phandle = <0x14>; mux { groups = "hdmitx_hpd_in"; @@ -898,24 +970,6 @@ }; }; - pwm-f-z { - - mux { - groups = "pwm_f_z"; - function = "pwm_f"; - bias-disable; - }; - }; - - pwm-f-a { - - mux { - groups = "pwm_f_a"; - function = "pwm_f"; - bias-disable; - }; - }; - pwm-f-x { mux { @@ -935,7 +989,7 @@ }; sdcard_c { - phandle = <0x22>; + phandle = <0x29>; mux-0 { groups = "sdcard_d0_c\0sdcard_d1_c\0sdcard_d2_c\0sdcard_d3_c\0sdcard_cmd_c"; @@ -953,7 +1007,7 @@ }; sdcard_clk_gate_c { - phandle = <0x23>; + phandle = <0x2a>; mux { groups = "GPIOC_4"; @@ -1380,7 +1434,7 @@ }; eth { - phandle = <0x07>; + phandle = <0x11>; mux { groups = "eth_mdio\0eth_mdc\0eth_rgmii_rx_clk\0eth_rx_dv\0eth_rxd0\0eth_rxd1\0eth_txen\0eth_txd0\0eth_txd1"; @@ -1391,7 +1445,7 @@ }; eth-rgmii { - phandle = <0x08>; + phandle = <0x12>; mux { groups = "eth_rxd2_rgmii\0eth_rxd3_rgmii\0eth_rgmii_tx_clk\0eth_txd2_rgmii\0eth_txd3_rgmii"; @@ -1637,8 +1691,8 @@ interrupts = <0x00 0x23 0x01>; clocks = <0x02 0xd4>; #thermal-sensor-cells = <0x00>; - amlogic,ao-secure = <0x10>; - phandle = <0x31>; + amlogic,ao-secure = <0x1a>; + phandle = <0x07>; }; temperature-sensor@34c00 { @@ -1647,20 +1701,20 @@ interrupts = <0x00 0x24 0x01>; clocks = <0x02 0xd4>; #thermal-sensor-cells = <0x00>; - amlogic,ao-secure = <0x10>; - phandle = <0x38>; + amlogic,ao-secure = <0x1a>; + phandle = <0x0e>; }; phy@36000 { compatible = "amlogic,g12a-usb2-phy"; reg = <0x00 0x36000 0x00 0x2000>; - clocks = <0x11>; + clocks = <0x1b>; clock-names = "xtal"; resets = <0x05 0x30>; reset-names = "phy"; #phy-cells = <0x00>; - phy-supply = <0x0c>; - phandle = <0x2d>; + phy-supply = <0x16>; + phandle = <0x35>; }; bus@38000 { @@ -1673,19 +1727,20 @@ video-lut@48 { compatible = "amlogic,canvas"; reg = <0x00 0x48 0x00 0x14>; - phandle = <0x20>; + phandle = <0x27>; }; }; phy@3a000 { compatible = "amlogic,g12a-usb2-phy"; reg = <0x00 0x3a000 0x00 0x2000>; - clocks = <0x11>; + clocks = <0x1b>; clock-names = "xtal"; resets = <0x05 0x31>; reset-names = "phy"; #phy-cells = <0x00>; - phandle = <0x2e>; + phy-supply = <0x1c>; + phandle = <0x36>; }; bus@3c000 { @@ -1702,7 +1757,7 @@ clock-controller { compatible = "amlogic,sm1-clkc"; #clock-cells = <0x01>; - clocks = <0x11>; + clocks = <0x1b>; clock-names = "xtal"; phandle = <0x02>; }; @@ -1710,7 +1765,7 @@ power-controller { compatible = "amlogic,meson-sm1-pwrc"; #power-domain-cells = <0x01>; - amlogic,ao-sysctrl = <0x12>; + amlogic,ao-sysctrl = <0x1d>; resets = <0x05 0x05 0x05 0x0a 0x05 0x0d 0x05 0x25 0x05 0x85 0x05 0x86 0x05 0x87 0x05 0x89 0x05 0x8c 0x05 0x8d 0x05 0xe7>; reset-names = "viu\0venc\0vcbus\0bt656\0rdma\0venci\0vencp\0vdac\0vdi6\0vencl\0vid_lock"; clocks = <0x02 0x74 0x02 0x7c>; @@ -1739,9 +1794,9 @@ mdio-multiplexer@4c000 { compatible = "amlogic,g12a-mdio-mux"; reg = <0x00 0x4c000 0x00 0xa4>; - clocks = <0x02 0x13 0x11 0x02 0xb1>; + clocks = <0x02 0x13 0x1b 0x02 0xb1>; clock-names = "pclk\0clkin0\0clkin1"; - mdio-parent-bus = <0x13>; + mdio-parent-bus = <0x1e>; #address-cells = <0x01>; #size-cells = <0x00>; @@ -1753,12 +1808,9 @@ ethernet-phy@0 { reg = <0x00>; max-speed = <0x3e8>; - reset-assert-us = <0x2710>; - reset-deassert-us = <0x13880>; - reset-gpios = <0x14 0x0f 0x07>; - interrupt-parent = <0x15>; + interrupt-parent = <0x1f>; interrupts = <0x1a 0x08>; - phandle = <0x09>; + phandle = <0x13>; }; }; @@ -1792,7 +1844,7 @@ clocks = <0x02 0x25 0x02 0x0b 0x02 0x0c 0x02 0x0d 0x02 0x0e 0x02 0x4a 0x02 0x03 0x02 0x04 0x02 0x05>; clock-names = "pclk\0mst_in0\0mst_in1\0mst_in2\0mst_in3\0mst_in4\0mst_in5\0mst_in6\0mst_in7"; resets = <0x05 0x41>; - phandle = <0x16>; + phandle = <0x20>; }; audio-controller@100 { @@ -1801,8 +1853,8 @@ #sound-dai-cells = <0x00>; sound-name-prefix = "TODDR_A"; interrupts = <0x00 0x94 0x01>; - clocks = <0x16 0x29>; - resets = <0x17 0x00 0x16 0x06>; + clocks = <0x20 0x29>; + resets = <0x21 0x00 0x20 0x06>; reset-names = "arb\0rst"; amlogic,fifo-depth = <0x2000>; status = "disabled"; @@ -1814,8 +1866,8 @@ #sound-dai-cells = <0x00>; sound-name-prefix = "TODDR_B"; interrupts = <0x00 0x95 0x01>; - clocks = <0x16 0x2a>; - resets = <0x17 0x01 0x16 0x07>; + clocks = <0x20 0x2a>; + resets = <0x21 0x01 0x20 0x07>; reset-names = "arb\0rst"; amlogic,fifo-depth = <0x100>; status = "disabled"; @@ -1827,8 +1879,8 @@ #sound-dai-cells = <0x00>; sound-name-prefix = "TODDR_C"; interrupts = <0x00 0x96 0x01>; - clocks = <0x16 0x2b>; - resets = <0x17 0x02 0x16 0x08>; + clocks = <0x20 0x2b>; + resets = <0x21 0x02 0x20 0x08>; reset-names = "arb\0rst"; amlogic,fifo-depth = <0x100>; status = "disabled"; @@ -1840,12 +1892,12 @@ #sound-dai-cells = <0x00>; sound-name-prefix = "FRDDR_A"; interrupts = <0x00 0x98 0x01>; - clocks = <0x16 0x26>; - resets = <0x17 0x03 0x16 0x09>; + clocks = <0x20 0x26>; + resets = <0x21 0x03 0x20 0x09>; reset-names = "arb\0rst"; amlogic,fifo-depth = <0x200>; status = "okay"; - phandle = <0x44>; + phandle = <0x42>; }; audio-controller@200 { @@ -1854,12 +1906,12 @@ #sound-dai-cells = <0x00>; sound-name-prefix = "FRDDR_B"; interrupts = <0x00 0x99 0x01>; - clocks = <0x16 0x27>; - resets = <0x17 0x04 0x16 0x0a>; + clocks = <0x20 0x27>; + resets = <0x21 0x04 0x20 0x0a>; reset-names = "arb\0rst"; amlogic,fifo-depth = <0x100>; status = "okay"; - phandle = <0x45>; + phandle = <0x43>; }; audio-controller@240 { @@ -1868,12 +1920,12 @@ #sound-dai-cells = <0x00>; sound-name-prefix = "FRDDR_C"; interrupts = <0x00 0x9a 0x01>; - clocks = <0x16 0x28>; - resets = <0x17 0x05 0x16 0x0b>; + clocks = <0x20 0x28>; + resets = <0x21 0x05 0x20 0x0b>; reset-names = "arb\0rst"; amlogic,fifo-depth = <0x100>; status = "okay"; - phandle = <0x46>; + phandle = <0x44>; }; reset-controller@280 { @@ -1881,16 +1933,16 @@ compatible = "amlogic,meson-sm1-audio-arb"; reg = <0x00 0x280 0x00 0x04>; #reset-cells = <0x01>; - clocks = <0x16 0x1d>; - phandle = <0x17>; + clocks = <0x20 0x1d>; + phandle = <0x21>; }; audio-controller@300 { compatible = "amlogic,sm1-tdmin\0amlogic,axg-tdmin"; reg = <0x00 0x300 0x00 0x40>; sound-name-prefix = "TDMIN_A"; - resets = <0x16 0x01>; - clocks = <0x16 0x1f 0x16 0x7b 0x16 0x74 0x16 0x82 0x16 0x82>; + resets = <0x20 0x01>; + clocks = <0x20 0x1f 0x20 0x7b 0x20 0x74 0x20 0x82 0x20 0x82>; clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; status = "disabled"; }; @@ -1899,8 +1951,8 @@ compatible = "amlogic,sm1-tdmin\0amlogic,axg-tdmin"; reg = <0x00 0x340 0x00 0x40>; sound-name-prefix = "TDMIN_B"; - resets = <0x16 0x02>; - clocks = <0x16 0x20 0x16 0x7c 0x16 0x75 0x16 0x83 0x16 0x83>; + resets = <0x20 0x02>; + clocks = <0x20 0x20 0x20 0x7c 0x20 0x75 0x20 0x83 0x20 0x83>; clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; status = "disabled"; }; @@ -1909,8 +1961,8 @@ compatible = "amlogic,sm1-tdmin\0amlogic,axg-tdmin"; reg = <0x00 0x380 0x00 0x40>; sound-name-prefix = "TDMIN_C"; - resets = <0x16 0x03>; - clocks = <0x16 0x21 0x16 0x7d 0x16 0x76 0x16 0x84 0x16 0x84>; + resets = <0x20 0x03>; + clocks = <0x20 0x21 0x20 0x7d 0x20 0x76 0x20 0x84 0x20 0x84>; clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; status = "disabled"; }; @@ -1919,41 +1971,18 @@ compatible = "amlogic,sm1-tdmin\0amlogic,axg-tdmin"; reg = <0x00 0x3c0 0x00 0x40>; sound-name-prefix = "TDMIN_LB"; - resets = <0x16 0x04>; - clocks = <0x16 0x22 0x16 0x7e 0x16 0x77 0x16 0x85 0x16 0x85>; + resets = <0x20 0x04>; + clocks = <0x20 0x22 0x20 0x7e 0x20 0x77 0x20 0x85 0x20 0x85>; clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; status = "disabled"; }; - audio-controller@400 { - compatible = "amlogic,g12a-spdifin\0amlogic,axg-spdifin"; - reg = <0x00 0x400 0x00 0x30>; - #sound-dai-cells = <0x00>; - sound-name-prefix = "SPDIFIN"; - interrupts = <0x00 0x97 0x01>; - clocks = <0x16 0x2d 0x16 0x38>; - clock-names = "pclk\0refclk"; - resets = <0x16 0x11>; - status = "disabled"; - }; - - audio-controller@480 { - compatible = "amlogic,g12a-spdifout\0amlogic,axg-spdifout"; - reg = <0x00 0x480 0x00 0x50>; - #sound-dai-cells = <0x00>; - sound-name-prefix = "SPDIFOUT_A"; - clocks = <0x16 0x2e 0x16 0x37>; - clock-names = "pclk\0mclk"; - resets = <0x16 0x0f>; - status = "disabled"; - }; - audio-controller@500 { compatible = "amlogic,sm1-tdmout"; reg = <0x00 0x500 0x00 0x40>; sound-name-prefix = "TDMOUT_A"; - resets = <0x16 0x0c>; - clocks = <0x16 0x23 0x16 0x7f 0x16 0x78 0x16 0x86 0x16 0x86>; + resets = <0x20 0x0c>; + clocks = <0x20 0x23 0x20 0x7f 0x20 0x78 0x20 0x86 0x20 0x86>; clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; status = "disabled"; }; @@ -1962,40 +1991,31 @@ compatible = "amlogic,sm1-tdmout"; reg = <0x00 0x540 0x00 0x40>; sound-name-prefix = "TDMOUT_B"; - resets = <0x16 0x0d>; - clocks = <0x16 0x24 0x16 0x80 0x16 0x79 0x16 0x87 0x16 0x87>; + resets = <0x20 0x0d>; + clocks = <0x20 0x24 0x20 0x80 0x20 0x79 0x20 0x87 0x20 0x87>; clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; status = "okay"; - phandle = <0x43>; + phandle = <0x41>; }; audio-controller@580 { compatible = "amlogic,sm1-tdmout"; reg = <0x00 0x580 0x00 0x40>; sound-name-prefix = "TDMOUT_C"; - resets = <0x16 0x0e>; - clocks = <0x16 0x25 0x16 0x81 0x16 0x7a 0x16 0x88 0x16 0x88>; + resets = <0x20 0x0e>; + clocks = <0x20 0x25 0x20 0x81 0x20 0x7a 0x20 0x88 0x20 0x88>; clock-names = "pclk\0sclk\0sclk_sel\0lrclk\0lrclk_sel"; status = "disabled"; }; - audio-controller@740 { - compatible = "amlogic,sm1-toacodec\0amlogic,g12a-toacodec"; - reg = <0x00 0x740 0x00 0x04>; - #sound-dai-cells = <0x01>; - sound-name-prefix = "TOACODEC"; - resets = <0x16 0x17>; - status = "disabled"; - }; - audio-controller@744 { compatible = "amlogic,sm1-tohdmitx\0amlogic,g12a-tohdmitx"; reg = <0x00 0x744 0x00 0x04>; #sound-dai-cells = <0x01>; sound-name-prefix = "TOHDMITX"; - resets = <0x16 0x18>; + resets = <0x20 0x18>; status = "okay"; - phandle = <0x48>; + phandle = <0x46>; }; audio-controller@840 { @@ -2004,8 +2024,8 @@ #sound-dai-cells = <0x00>; sound-name-prefix = "TODDR_D"; interrupts = <0x00 0x31 0x01>; - clocks = <0x16 0xab>; - resets = <0x17 0x06 0x16 0x21>; + clocks = <0x20 0xab>; + resets = <0x21 0x06 0x20 0x21>; reset-names = "arb\0rst"; amlogic,fifo-depth = <0x100>; status = "disabled"; @@ -2017,8 +2037,8 @@ #sound-dai-cells = <0x00>; sound-name-prefix = "FRDDR_D"; interrupts = <0x00 0x32 0x01>; - clocks = <0x16 0xaa>; - resets = <0x17 0x07 0x16 0x20>; + clocks = <0x20 0xaa>; + resets = <0x21 0x07 0x20 0x20>; reset-names = "arb\0rst"; amlogic,fifo-depth = <0x100>; status = "disabled"; @@ -2030,9 +2050,9 @@ reg = <0x00 0x61000 0x00 0x34>; #sound-dai-cells = <0x00>; sound-name-prefix = "PDM"; - clocks = <0x16 0x1e 0x16 0x39 0x16 0x3a>; + clocks = <0x20 0x1e 0x20 0x39 0x20 0x3a>; clock-names = "pclk\0dclk\0sysclk"; - resets = <0x16 0x00>; + resets = <0x20 0x00>; status = "disabled"; }; }; @@ -2050,15 +2070,15 @@ #address-cells = <0x02>; #size-cells = <0x02>; ranges = <0x00 0x00 0x00 0x00 0x00 0x100>; - phandle = <0x12>; + phandle = <0x1d>; clock-controller { compatible = "amlogic,meson-g12a-aoclkc"; #clock-cells = <0x01>; #reset-cells = <0x01>; - clocks = <0x11 0x02 0x0a>; + clocks = <0x1b 0x02 0x0a>; clock-names = "xtal\0mpeg-clk"; - phandle = <0x19>; + phandle = <0x23>; }; pinctrl@14 { @@ -2066,16 +2086,16 @@ #address-cells = <0x02>; #size-cells = <0x02>; ranges; - phandle = <0x18>; + phandle = <0x22>; bank@14 { reg = <0x00 0x14 0x00 0x08 0x00 0x1c 0x00 0x08 0x00 0x24 0x00 0x14>; reg-names = "mux\0ds\0gpio"; gpio-controller; #gpio-cells = <0x02>; - gpio-ranges = <0x18 0x00 0x00 0x0f>; + gpio-ranges = <0x22 0x00 0x00 0x0f>; gpio-line-names = "\0\0\0\0PIN_47\0\0\0PIN_45\0PIN_46\0PIN_44\0PIN_42\0\0\0\0"; - phandle = <0x3e>; + phandle = <0x3c>; }; i2c_ao_sck_pins { @@ -2234,7 +2254,7 @@ }; uart-a-ao { - phandle = <0x1e>; + phandle = <0x25>; mux { groups = "uart_ao_a_tx\0uart_ao_a_rx"; @@ -2252,33 +2272,6 @@ }; }; - uart-ao-b-2-3 { - - mux { - groups = "uart_ao_b_tx_2\0uart_ao_b_rx_3"; - function = "uart_ao_b"; - bias-disable; - }; - }; - - uart-ao-b-8-9 { - - mux { - groups = "uart_ao_b_tx_8\0uart_ao_b_rx_9"; - function = "uart_ao_b"; - bias-disable; - }; - }; - - uart-ao-b-cts-rts { - - mux { - groups = "uart_ao_b_cts\0uart_ao_b_rts"; - function = "uart_ao_b"; - bias-disable; - }; - }; - pwm-a-e { mux { @@ -2343,7 +2336,7 @@ }; pwm-ao-d-e { - phandle = <0x1d>; + phandle = <0x24>; mux { groups = "pwm_ao_d_e"; @@ -2352,7 +2345,7 @@ }; remote-input-ao { - phandle = <0x1f>; + phandle = <0x26>; mux { groups = "remote_ao_input"; @@ -2372,32 +2365,25 @@ compatible = "amlogic,meson-gx-ao-cec"; reg = <0x00 0x100 0x00 0x14>; interrupts = <0x00 0xc7 0x01>; - clocks = <0x19 0x1b>; + clocks = <0x23 0x1b>; clock-names = "core"; status = "disabled"; - pinctrl-0 = <0x1a>; - pinctrl-names = "default"; - hdmi-phandle = <0x1b>; }; ao-secure@140 { compatible = "amlogic,meson-gx-ao-secure\0syscon"; reg = <0x00 0x140 0x00 0x140>; amlogic,has-chip-id; - phandle = <0x10>; - status = "disabled"; + phandle = <0x1a>; }; cec@280 { compatible = "amlogic,meson-sm1-ao-cec"; reg = <0x00 0x280 0x00 0x1c>; interrupts = <0x00 0xcb 0x01>; - clocks = <0x19 0x13>; + clocks = <0x23 0x13>; clock-names = "oscin"; - status = "okay"; - pinctrl-0 = <0x1c>; - pinctrl-names = "default"; - hdmi-phandle = <0x1b>; + status = "disabled"; }; pwm@2000 { @@ -2405,21 +2391,21 @@ reg = <0x00 0x2000 0x00 0x20>; #pwm-cells = <0x03>; status = "okay"; - pinctrl-0 = <0x1d>; + pinctrl-0 = <0x24>; pinctrl-names = "default"; - clocks = <0x11>; + clocks = <0x1b>; clock-names = "clkin1"; - phandle = <0x41>; + phandle = <0x3f>; }; serial@3000 { compatible = "amlogic,meson-gx-uart\0amlogic,meson-ao-uart"; reg = <0x00 0x3000 0x00 0x18>; interrupts = <0x00 0xc1 0x01>; - clocks = <0x11 0x19 0x04 0x11>; + clocks = <0x1b 0x23 0x04 0x1b>; clock-names = "xtal\0pclk\0baud"; status = "okay"; - pinctrl-0 = <0x1e>; + pinctrl-0 = <0x25>; pinctrl-names = "default"; }; @@ -2427,7 +2413,7 @@ compatible = "amlogic,meson-gx-uart\0amlogic,meson-ao-uart"; reg = <0x00 0x4000 0x00 0x18>; interrupts = <0x00 0xc5 0x01>; - clocks = <0x11 0x19 0x06 0x11>; + clocks = <0x1b 0x23 0x06 0x1b>; clock-names = "xtal\0pclk\0baud"; status = "disabled"; }; @@ -2454,7 +2440,7 @@ reg = <0x00 0x8000 0x00 0x20>; interrupts = <0x00 0xc4 0x01>; status = "okay"; - pinctrl-0 = <0x1f>; + pinctrl-0 = <0x26>; pinctrl-names = "default"; linux,rc-map-name = "rc-odroid"; }; @@ -2464,9 +2450,9 @@ reg = <0x00 0x9000 0x00 0x48>; #io-channel-cells = <0x01>; interrupts = <0x00 0xc8 0x01>; - clocks = <0x11 0x19 0x08 0x19 0x12 0x19 0x10>; + clocks = <0x1b 0x23 0x08 0x23 0x12 0x23 0x10>; clock-names = "clkin\0core\0adc_clk\0adc_sel"; - status = "disabled"; + status = "okay"; }; }; @@ -2476,8 +2462,8 @@ reg-names = "dos\0esparser"; interrupts = <0x00 0x2c 0x01 0x00 0x20 0x01>; interrupt-names = "vdec\0esparser"; - amlogic,ao-sysctrl = <0x12>; - amlogic,canvas = <0x20>; + amlogic,ao-sysctrl = <0x1d>; + amlogic,canvas = <0x27>; clocks = <0x02 0x2e 0x02 0x10 0x02 0xcc 0x02 0xcf 0x02 0xd2>; clock-names = "dos_parser\0dos\0vdec_1\0vdec_hevc\0vdec_hevcf"; resets = <0x05 0x28>; @@ -2491,9 +2477,8 @@ interrupts = <0x00 0x03 0x01>; #address-cells = <0x01>; #size-cells = <0x00>; - amlogic,canvas = <0x20>; + amlogic,canvas = <0x27>; power-domains = <0x03 0x00>; - status = "disabled"; port@0 { reg = <0x00>; @@ -2503,8 +2488,8 @@ reg = <0x01>; endpoint { - remote-endpoint = <0x21>; - phandle = <0x0d>; + remote-endpoint = <0x28>; + phandle = <0x17>; }; }; }; @@ -2539,13 +2524,13 @@ interrupt-controller; #interrupt-cells = <0x02>; amlogic,channel-interrupts = <0x40 0x41 0x42 0x43 0x44 0x45 0x46 0x47>; - phandle = <0x15>; + phandle = <0x1f>; }; watchdog@f0d0 { compatible = "amlogic,meson-gxbb-wdt"; reg = <0x00 0xf0d0 0x00 0x10>; - clocks = <0x11>; + clocks = <0x1b>; }; spi@13000 { @@ -2649,7 +2634,7 @@ compatible = "amlogic,meson-gx-uart"; reg = <0x00 0x22000 0x00 0x18>; interrupts = <0x00 0x5d 0x01>; - clocks = <0x11 0x02 0x39 0x11>; + clocks = <0x1b 0x02 0x39 0x1b>; clock-names = "xtal\0pclk\0baud"; status = "disabled"; }; @@ -2658,7 +2643,7 @@ compatible = "amlogic,meson-gx-uart"; reg = <0x00 0x23000 0x00 0x18>; interrupts = <0x00 0x4b 0x01>; - clocks = <0x11 0x02 0x2a 0x11>; + clocks = <0x1b 0x02 0x2a 0x1b>; clock-names = "xtal\0pclk\0baud"; status = "disabled"; }; @@ -2667,10 +2652,9 @@ compatible = "amlogic,meson-gx-uart"; reg = <0x00 0x24000 0x00 0x18>; interrupts = <0x00 0x1a 0x01>; - clocks = <0x11 0x02 0x1c 0x11>; + clocks = <0x1b 0x02 0x1c 0x1b>; clock-names = "xtal\0pclk\0baud"; status = "disabled"; - fifo-size = <0x80>; }; }; @@ -2692,8 +2676,8 @@ clocks = <0x02 0x22 0x02 0x3d 0x02 0x02>; clock-names = "core\0clkin0\0clkin1"; resets = <0x05 0x2d>; - pinctrl-0 = <0x22>; - pinctrl-1 = <0x23>; + pinctrl-0 = <0x29>; + pinctrl-1 = <0x2a>; pinctrl-names = "default\0clk-gate"; bus-width = <0x04>; cap-sd-highspeed; @@ -2703,9 +2687,9 @@ sd-uhs-sdr50; sd-uhs-sdr104; disable-wp; - cd-gpios = <0x14 0x2f 0x01>; - vmmc-supply = <0x24>; - vqmmc-supply = <0x25>; + cd-gpios = <0x2b 0x2f 0x01>; + vmmc-supply = <0x2c>; + vqmmc-supply = <0x2d>; }; mmc@ffe07000 { @@ -2716,8 +2700,8 @@ clocks = <0x02 0x23 0x02 0x3e 0x02 0x02>; clock-names = "core\0clkin0\0clkin1"; resets = <0x05 0x2e>; - pinctrl-0 = <0x26 0x27 0x28>; - pinctrl-1 = <0x29>; + pinctrl-0 = <0x2e 0x2f 0x30>; + pinctrl-1 = <0x31>; pinctrl-names = "default\0clk-gate"; bus-width = <0x08>; cap-mmc-highspeed; @@ -2725,9 +2709,9 @@ mmc-hs200-1_8v; max-frequency = <0xbebc200>; disable-wp; - mmc-pwrseq = <0x2a>; - vmmc-supply = <0x2b>; - vqmmc-supply = <0x2c>; + mmc-pwrseq = <0x32>; + vmmc-supply = <0x33>; + vqmmc-supply = <0x34>; }; usb@ffe09000 { @@ -2741,10 +2725,10 @@ clocks = <0x02 0x2f>; resets = <0x05 0x22>; dr_mode = "otg"; - phys = <0x2d 0x2e 0x06 0x04>; + phys = <0x35 0x36 0x06 0x04>; phy-names = "usb2-phy0\0usb2-phy1\0usb3-phy0"; power-domains = <0x03 0x02>; - vbus-supply = <0x2f>; + vbus-supply = <0x37>; usb@ff400000 { compatible = "amlogic,meson-g12a-usb\0snps,dwc2"; @@ -2752,7 +2736,7 @@ interrupts = <0x00 0x1f 0x04>; clocks = <0x02 0x37>; clock-names = "otg"; - phys = <0x2e>; + phys = <0x36>; phy-names = "usb2-phy"; dr_mode = "peripheral"; g-rx-fifo-size = <0xc0>; @@ -2779,84 +2763,9 @@ interrupt-names = "job\0mmu\0gpu"; clocks = <0x02 0xaf>; resets = <0x05 0x14 0x05 0x4e>; - operating-points-v2 = <0x30>; + operating-points-v2 = <0x38>; #cooling-cells = <0x02>; - phandle = <0x3a>; - }; - }; - - thermal-zones { - - cpu-thermal { - polling-delay = <0x3e8>; - polling-delay-passive = <0x64>; - thermal-sensors = <0x31>; - - trips { - - cpu-passive { - temperature = <0x14c08>; - hysteresis = <0x7d0>; - type = "passive"; - phandle = <0x32>; - }; - - cpu-hot { - temperature = <0x17318>; - hysteresis = <0x7d0>; - type = "hot"; - phandle = <0x37>; - }; - - cpu-critical { - temperature = <0x1adb0>; - hysteresis = <0x7d0>; - type = "critical"; - }; - }; - - cooling-maps { - - map0 { - trip = <0x32>; - cooling-device = <0x33 0xffffffff 0xffffffff 0x34 0xffffffff 0xffffffff 0x35 0xffffffff 0xffffffff 0x36 0xffffffff 0xffffffff>; - }; - - map1 { - trip = <0x37>; - cooling-device = <0x33 0xffffffff 0xffffffff 0x34 0xffffffff 0xffffffff 0x35 0xffffffff 0xffffffff 0x36 0xffffffff 0xffffffff>; - }; - }; - }; - - ddr-thermal { - polling-delay = <0x3e8>; - polling-delay-passive = <0x64>; - thermal-sensors = <0x38>; - - trips { - - ddr-passive { - temperature = <0x14c08>; - hysteresis = <0x7d0>; - type = "passive"; - phandle = <0x39>; - }; - - ddr-critical { - temperature = <0x1adb0>; - hysteresis = <0x7d0>; - type = "critical"; - }; - }; - - cooling-maps { - - map { - trip = <0x39>; - cooling-device = <0x3a 0xffffffff 0xffffffff>; - }; - }; + phandle = <0x10>; }; }; @@ -2871,14 +2780,14 @@ clock-frequency = <0x16e3600>; clock-output-names = "xtal"; #clock-cells = <0x00>; - phandle = <0x11>; + phandle = <0x1b>; }; audio-controller-0 { compatible = "amlogic,axg-tdm-iface"; #sound-dai-cells = <0x00>; sound-name-prefix = "TDM_A"; - clocks = <0x16 0x31 0x16 0x4f 0x16 0x56>; + clocks = <0x20 0x31 0x20 0x4f 0x20 0x56>; clock-names = "mclk\0sclk\0lrclk"; status = "disabled"; }; @@ -2887,17 +2796,17 @@ compatible = "amlogic,axg-tdm-iface"; #sound-dai-cells = <0x00>; sound-name-prefix = "TDM_B"; - clocks = <0x16 0x32 0x16 0x50 0x16 0x57>; + clocks = <0x20 0x32 0x20 0x50 0x20 0x57>; clock-names = "mclk\0sclk\0lrclk"; status = "okay"; - phandle = <0x47>; + phandle = <0x45>; }; audio-controller-2 { compatible = "amlogic,axg-tdm-iface"; #sound-dai-cells = <0x00>; sound-name-prefix = "TDM_C"; - clocks = <0x16 0x33 0x16 0x51 0x16 0x58>; + clocks = <0x20 0x33 0x20 0x51 0x20 0x58>; clock-names = "mclk\0sclk\0lrclk"; status = "disabled"; }; @@ -2911,13 +2820,13 @@ compatible = "arm,cortex-a55"; reg = <0x00 0x00>; enable-method = "psci"; - next-level-cache = <0x3b>; + next-level-cache = <0x39>; #cooling-cells = <0x02>; - cpu-supply = <0x3c>; - operating-points-v2 = <0x3d>; + cpu-supply = <0x3a>; + operating-points-v2 = <0x3b>; clocks = <0x02 0xbb>; clock-latency = <0xc350>; - phandle = <0x33>; + phandle = <0x09>; }; cpu@1 { @@ -2925,13 +2834,13 @@ compatible = "arm,cortex-a55"; reg = <0x00 0x01>; enable-method = "psci"; - next-level-cache = <0x3b>; + next-level-cache = <0x39>; #cooling-cells = <0x02>; - cpu-supply = <0x3c>; - operating-points-v2 = <0x3d>; + cpu-supply = <0x3a>; + operating-points-v2 = <0x3b>; clocks = <0x02 0xfd>; clock-latency = <0xc350>; - phandle = <0x34>; + phandle = <0x0a>; }; cpu@2 { @@ -2939,13 +2848,13 @@ compatible = "arm,cortex-a55"; reg = <0x00 0x02>; enable-method = "psci"; - next-level-cache = <0x3b>; + next-level-cache = <0x39>; #cooling-cells = <0x02>; - cpu-supply = <0x3c>; - operating-points-v2 = <0x3d>; + cpu-supply = <0x3a>; + operating-points-v2 = <0x3b>; clocks = <0x02 0xfe>; clock-latency = <0xc350>; - phandle = <0x35>; + phandle = <0x0b>; }; cpu@3 { @@ -2953,25 +2862,45 @@ compatible = "arm,cortex-a55"; reg = <0x00 0x03>; enable-method = "psci"; - next-level-cache = <0x3b>; + next-level-cache = <0x39>; #cooling-cells = <0x02>; - cpu-supply = <0x3c>; - operating-points-v2 = <0x3d>; + cpu-supply = <0x3a>; + operating-points-v2 = <0x3b>; clocks = <0x02 0xff>; clock-latency = <0xc350>; - phandle = <0x36>; + phandle = <0x0c>; }; l2-cache0 { compatible = "cache"; - phandle = <0x3b>; + phandle = <0x39>; }; }; opp-table { compatible = "operating-points-v2"; opp-shared; - phandle = <0x3d>; + phandle = <0x3b>; + + opp-100000000 { + opp-hz = <0x00 0x5f5e100>; + opp-microvolt = <0xb2390>; + }; + + opp-250000000 { + opp-hz = <0x00 0xee6b280>; + opp-microvolt = <0xb2390>; + }; + + opp-500000000 { + opp-hz = <0x00 0x1dcd6500>; + opp-microvolt = <0xb2390>; + }; + + opp-667000000 { + opp-hz = <0x00 0x27bc86aa>; + opp-microvolt = <0xb71b0>; + }; opp-1000000000 { opp-hz = <0x00 0x3b9aca00>; @@ -3016,13 +2945,13 @@ memory@0 { device_type = "memory"; - reg = <0x00 0x20000000 0x00 0x10000000>; + reg = <0x00 0x00 0x00 0xf5800000>; }; emmc-pwrseq { compatible = "mmc-pwrseq-emmc"; - reset-gpios = <0x14 0x25 0x01>; - phandle = <0x2a>; + reset-gpios = <0x2b 0x25 0x01>; + phandle = <0x32>; }; regulator-tflash_vdd { @@ -3030,10 +2959,10 @@ regulator-name = "TFLASH_VDD"; regulator-min-microvolt = <0x325aa0>; regulator-max-microvolt = <0x325aa0>; - gpio = <0x3e 0x03 0x06>; + gpio = <0x3c 0x03 0x06>; enable-active-high; regulator-always-on; - phandle = <0x24>; + phandle = <0x2c>; }; gpio-regulator-tf_io { @@ -3041,14 +2970,10 @@ regulator-name = "TF_IO"; regulator-min-microvolt = <0x1b7740>; regulator-max-microvolt = <0x325aa0>; - vin-supply = <0x0c>; - enable-gpio = <0x3e 0x0e 0x06>; - enable-active-high; - regulator-always-on; - gpios = <0x3e 0x06 0x02>; + gpios = <0x3c 0x06 0x00>; gpios-states = <0x00>; states = <0x325aa0 0x00 0x1b7740 0x01>; - phandle = <0x25>; + phandle = <0x2d>; }; regulator-flash_1v8 { @@ -3056,9 +2981,9 @@ regulator-name = "FLASH_1V8"; regulator-min-microvolt = <0x1b7740>; regulator-max-microvolt = <0x1b7740>; - vin-supply = <0x2b>; + vin-supply = <0x33>; regulator-always-on; - phandle = <0x2c>; + phandle = <0x34>; }; regulator-main_12v { @@ -3067,7 +2992,7 @@ regulator-min-microvolt = <0xb71b00>; regulator-max-microvolt = <0xb71b00>; regulator-always-on; - phandle = <0x3f>; + phandle = <0x3d>; }; regulator-vcc_5v { @@ -3076,10 +3001,8 @@ regulator-min-microvolt = <0x4c4b40>; regulator-max-microvolt = <0x4c4b40>; regulator-always-on; - vin-supply = <0x3f>; - gpio = <0x14 0x18 0x06>; - enable-active-high; - phandle = <0x0c>; + vin-supply = <0x3d>; + phandle = <0x16>; }; regulator-vcc_1v8 { @@ -3087,7 +3010,7 @@ regulator-name = "VCC_1V8"; regulator-min-microvolt = <0x1b7740>; regulator-max-microvolt = <0x1b7740>; - vin-supply = <0x2b>; + vin-supply = <0x33>; regulator-always-on; }; @@ -3096,9 +3019,9 @@ regulator-name = "VCC_3V3"; regulator-min-microvolt = <0x325aa0>; regulator-max-microvolt = <0x325aa0>; - vin-supply = <0x40>; + vin-supply = <0x3e>; regulator-always-on; - phandle = <0x2b>; + phandle = <0x33>; }; regulator-vddcpu { @@ -3106,12 +3029,12 @@ regulator-name = "VDDCPU"; regulator-min-microvolt = <0xb0068>; regulator-max-microvolt = <0xf9830>; - pwm-supply = <0x3f>; - pwms = <0x41 0x01 0x4e2 0x00>; + vin-supply = <0x3d>; + pwms = <0x3f 0x01 0x4e2 0x00>; pwm-dutycycle-range = <0x64 0x00>; regulator-boot-on; regulator-always-on; - phandle = <0x3c>; + phandle = <0x3a>; }; regulator-usb_pwr_en { @@ -3119,10 +3042,10 @@ regulator-name = "USB_PWR_EN"; regulator-min-microvolt = <0x4c4b40>; regulator-max-microvolt = <0x4c4b40>; - vin-supply = <0x0c>; - gpio = <0x3e 0x02 0x00>; + vin-supply = <0x16>; + gpio = <0x3c 0x02 0x00>; enable-active-high; - phandle = <0x2f>; + phandle = <0x37>; }; regulator-vddao_1v8 { @@ -3130,7 +3053,7 @@ regulator-name = "VDDAO_1V8"; regulator-min-microvolt = <0x1b7740>; regulator-max-microvolt = <0x1b7740>; - vin-supply = <0x40>; + vin-supply = <0x3e>; regulator-always-on; }; @@ -3139,9 +3062,9 @@ regulator-name = "VDDAO_3V3"; regulator-min-microvolt = <0x325aa0>; regulator-max-microvolt = <0x325aa0>; - vin-supply = <0x3f>; + vin-supply = <0x3d>; regulator-always-on; - phandle = <0x40>; + phandle = <0x3e>; }; hdmi-connector { @@ -3151,15 +3074,15 @@ port { endpoint { - remote-endpoint = <0x42>; - phandle = <0x0e>; + remote-endpoint = <0x40>; + phandle = <0x18>; }; }; }; sound { compatible = "amlogic,axg-sound-card"; - audio-aux-devs = <0x43>; + audio-aux-devs = <0x41>; audio-routing = "TDMOUT_B IN 0\0FRDDR_A OUT 1\0TDMOUT_B IN 1\0FRDDR_B OUT 1\0TDMOUT_B IN 2\0FRDDR_C OUT 1\0TDM_B Playback\0TDMOUT_B OUT"; assigned-clocks = <0x02 0x0d 0x02 0x0b 0x02 0x0c>; assigned-clock-parents = <0x00 0x00 0x00>; @@ -3168,19 +3091,19 @@ model = "ODROID-C4"; dai-link-0 { - sound-dai = <0x44>; + sound-dai = <0x42>; }; dai-link-1 { - sound-dai = <0x45>; + sound-dai = <0x43>; }; dai-link-2 { - sound-dai = <0x46>; + sound-dai = <0x44>; }; dai-link-3 { - sound-dai = <0x47>; + sound-dai = <0x45>; dai-format = "i2s"; dai-tdm-slot-tx-mask-0 = <0x01 0x01>; dai-tdm-slot-tx-mask-1 = <0x01 0x01>; @@ -3189,15 +3112,15 @@ mclk-fs = <0x100>; codec { - sound-dai = <0x48 0x01>; + sound-dai = <0x46 0x01>; }; }; dai-link-4 { - sound-dai = <0x48 0x03>; + sound-dai = <0x46 0x03>; codec { - sound-dai = <0x1b>; + sound-dai = <0x47>; }; }; }; @@ -3208,9 +3131,20 @@ led-blue { color = <0x03>; function = "status"; - gpios = <0x3e 0x0b 0x00>; + gpios = <0x3c 0x0b 0x00>; linux,default-trigger = "heartbeat"; panic-indicator; }; }; + + regulator-hub_5v { + compatible = "regulator-fixed"; + regulator-name = "HUB_5V"; + regulator-min-microvolt = <0x4c4b40>; + regulator-max-microvolt = <0x4c4b40>; + vin-supply = <0x16>; + gpio = <0x2b 0x14 0x00>; + enable-active-high; + phandle = <0x1c>; + }; }; diff --git a/include/sddf/clk/client.h b/include/sddf/clk/client.h index 8d0d51e6c..d5dc3e937 100644 --- a/include/sddf/clk/client.h +++ b/include/sddf/clk/client.h @@ -16,7 +16,8 @@ * @param channel of clock driver. * @param identifier of target clock. */ -static inline uint32_t sddf_clk_enable(microkit_channel channel, uint32_t clk_id) +static inline uint32_t sddf_clk_enable(microkit_channel channel, + uint32_t clk_id) { microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_ENABLE, 1); microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); @@ -32,7 +33,8 @@ static inline uint32_t sddf_clk_enable(microkit_channel channel, uint32_t clk_id * @param channel of clock driver. * @param identifier of target clock. */ -static inline uint32_t sddf_clk_disable(microkit_channel channel, uint32_t clk_id) +static inline uint32_t sddf_clk_disable(microkit_channel channel, + uint32_t clk_id) { microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_DISABLE, 1); microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); @@ -49,7 +51,8 @@ static inline uint32_t sddf_clk_disable(microkit_channel channel, uint32_t clk_i * @param identifier of target clock. * @param pointer to result variable. */ -static inline uint32_t sddf_clk_get_rate(microkit_channel channel, uint32_t clk_id, uint64_t *rate) +static inline uint32_t sddf_clk_get_rate(microkit_channel channel, + uint32_t clk_id, uint64_t *rate) { microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_GET_RATE, 1); microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); @@ -68,7 +71,9 @@ static inline uint32_t sddf_clk_get_rate(microkit_channel channel, uint32_t clk_ * @param target clock frequency. * @param pointer to result variable. */ -static inline uint32_t sddf_clk_set_rate(microkit_channel channel, uint32_t clk_id, uint64_t req_rate, uint64_t *rate) +static inline uint32_t sddf_clk_set_rate(microkit_channel channel, + uint32_t clk_id, uint64_t req_rate, + uint64_t *rate) { microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_SET_RATE, 2); microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); From 0a6c6641e8e0e9d40b0bca194211bc95080d4c9f Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Mon, 18 Nov 2024 16:35:08 +1100 Subject: [PATCH 07/11] clk: fix style and data types This commit replaces all platform-dependent data types with fix-sized types, and unifies the return values of interfaces as signed integers. The return value 0 indicates the success on the request to clock driver, and negative values indicate the failure reasons. Signed-off-by: Terry Bai --- drivers/clk/clk-operations.c | 41 +-- drivers/clk/clk-operations.h | 44 ++- drivers/clk/clk.h | 38 +-- drivers/clk/imx/clk-imx.c | 87 ++---- drivers/clk/imx/clk-imx8mq.c | 236 ++++++--------- drivers/clk/imx/clk.c | 29 +- drivers/clk/imx/include/clk-imx.h | 27 +- drivers/clk/meson/clk-measure.c | 3 +- drivers/clk/meson/clk-meson.c | 193 +++++-------- drivers/clk/meson/clk.c | 33 ++- drivers/clk/meson/sm1-clk.c | 463 +++++++++++------------------- examples/clk/client.c | 66 ++++- include/sddf/clk/client.h | 21 +- 13 files changed, 479 insertions(+), 802 deletions(-) diff --git a/drivers/clk/clk-operations.c b/drivers/clk/clk-operations.c index 6fe7167ab..885138b5e 100644 --- a/drivers/clk/clk-operations.c +++ b/drivers/clk/clk-operations.c @@ -122,13 +122,11 @@ const struct clk_ops clk_gate_ro_ops = { .is_enabled = clk_gate_is_enabled, }; -static inline unsigned long clk_div_recalc_rate(const struct clk *clk, - unsigned long prate) +static inline uint64_t clk_div_recalc_rate(const struct clk *clk, uint64_t prate) { struct clk_div_data *data = (struct clk_div_data *)(clk->data); - uint32_t div = regmap_read_bits(clk->base, data->offset, data->shift, - data->width); + uint32_t div = regmap_read_bits(clk->base, data->offset, data->shift, data->width); /* TODO: Need to verify the following cases */ if (data->flags & CLK_DIVIDER_ONE_BASED) { @@ -144,8 +142,7 @@ static inline unsigned long clk_div_recalc_rate(const struct clk *clk, return DIV_ROUND_UP_ULL((uint64_t)prate, div); } -static inline int clk_div_set_rate(const struct clk *clk, uint32_t rate, - uint32_t parent_rate) +static inline int clk_div_set_rate(const struct clk *clk, uint64_t rate, uint64_t parent_rate) { struct clk_div_data *data = (struct clk_div_data *)(clk->data); uint32_t div = DIV_ROUND_UP(parent_rate, rate); @@ -160,8 +157,7 @@ static inline int clk_div_set_rate(const struct clk *clk, uint32_t rate, } else { div -= 1; } - return regmap_update_bits(clk->base, data->offset, data->shift, data->width, - div); + return regmap_update_bits(clk->base, data->offset, data->shift, data->width, div); } const struct clk_ops clk_divider_ops = { @@ -180,8 +176,7 @@ static inline uint8_t clk_mux_get_parent(const struct clk *clk) { struct clk_mux_data *data = (struct clk_mux_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->shift, - data->mask); + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->shift, data->mask); if (data->table) { int i; @@ -212,12 +207,10 @@ static inline int clk_mux_set_parent(struct clk *clk, uint8_t index) struct clk_mux_data *data = (struct clk_mux_data *)(clk->data); if (data->table) { - unsigned int val = data->table[index]; - regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, - val); + uint32_t val = data->table[index]; + regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, val); } - regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, - index); + regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, index); return 0; } @@ -231,16 +224,14 @@ const struct clk_ops clk_mux_ro_ops = { .get_parent = clk_mux_get_parent, }; -static inline unsigned long clk_factor_recalc_rate(const struct clk *clk, - unsigned long parent_rate) +static inline uint64_t clk_factor_recalc_rate(const struct clk *clk, uint64_t parent_rate) { - struct clk_fixed_factor_data *data = - (struct clk_fixed_factor_data *)(clk->data); - unsigned long long int rate; + struct clk_fixed_factor_data *data = (struct clk_fixed_factor_data *)(clk->data); + uint64_t rate; - rate = (unsigned long long int)parent_rate * data->mult; + rate = (uint64_t)parent_rate * data->mult; do_div(rate, data->div); - return (unsigned long)rate; + return (uint64_t)rate; } const struct clk_ops clk_fixed_factor_ops = { @@ -250,8 +241,7 @@ const struct clk_ops clk_fixed_factor_ops = { /* .recalc_accuracy = clk_factor_recalc_accuracy, */ }; -static inline int clk_source_set_rate(const struct clk *clk, uint32_t rate, - uint32_t parent_rate) +static inline int clk_source_set_rate(const struct clk *clk, uint64_t rate, uint64_t parent_rate) { struct clk_source_data *data = (struct clk_source_data *)(clk->data); data->rate = rate; @@ -259,8 +249,7 @@ static inline int clk_source_set_rate(const struct clk *clk, uint32_t rate, return 0; } -static inline unsigned long clk_source_get_rate(const struct clk *clk, - unsigned long prate) +static inline uint64_t clk_source_get_rate(const struct clk *clk, uint64_t prate) { struct clk_source_data *data = (struct clk_source_data *)(clk->data); diff --git a/drivers/clk/clk-operations.h b/drivers/clk/clk-operations.h index beccd73c8..2dc02a301 100644 --- a/drivers/clk/clk-operations.h +++ b/drivers/clk/clk-operations.h @@ -8,11 +8,11 @@ #include #include -#define CLK_INCORRECT_ARGS 1 -#define CLK_INVALID_OP 2 -#define CLK_INVALID_ID 3 -#define CLK_UNKNOWN_REQ 4 -#define CLK_UNKNOWN_TARGET 5 +#define CLK_INCORRECT_ARGS -1 +#define CLK_INVALID_OP -2 +#define CLK_INVALID_ID -3 +#define CLK_UNKNOWN_REQ -4 +#define CLK_UNKNOWN_TARGET -5 static inline int reg_write(uint64_t base, uint32_t offset, uint32_t val) { @@ -22,8 +22,7 @@ static inline int reg_write(uint64_t base, uint32_t offset, uint32_t val) return 0; } -static inline int regmap_update_bits(uint64_t base, uint32_t offset, - uint8_t shift, uint8_t width, uint32_t val) +static inline int regmap_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width, uint32_t val) { volatile uint32_t *clk_reg = ((void *)base + offset); uint32_t reg_val = *clk_reg; @@ -36,8 +35,7 @@ static inline int regmap_update_bits(uint64_t base, uint32_t offset, return 0; } -static inline uint32_t regmap_read_bits(uint64_t base, uint32_t offset, - uint8_t shift, uint8_t width) +static inline uint32_t regmap_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width) { volatile uint32_t *clk_reg = ((void *)base + offset); uint32_t reg_val = *clk_reg; @@ -48,9 +46,7 @@ static inline uint32_t regmap_read_bits(uint64_t base, uint32_t offset, return reg_val; } -static inline int regmap_mux_update_bits(uint64_t base, uint32_t offset, - uint8_t shift, uint32_t mask, - uint32_t val) +static inline int regmap_mux_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask, uint32_t val) { volatile uint32_t *clk_reg = ((void *)base + offset); uint32_t reg_val = *clk_reg; @@ -63,8 +59,7 @@ static inline int regmap_mux_update_bits(uint64_t base, uint32_t offset, return 0; } -static inline uint32_t regmap_mux_read_bits(uint64_t base, uint32_t offset, - uint8_t shift, uint32_t mask) +static inline uint32_t regmap_mux_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask) { volatile uint32_t *clk_reg = ((void *)base + offset); uint32_t reg_val = *clk_reg; @@ -84,8 +79,7 @@ extern const struct clk_ops clk_mux_ro_ops; extern const struct clk_ops clk_gate_ops; extern const struct clk_ops clk_gate_ro_ops; -#define CLK_FIXED_FACTOR(_name, _mult, _div, _data_flags, _parent_clks, \ - _num_parents, _init_flags) \ +#define CLK_FIXED_FACTOR(_name, _mult, _div, _data_flags, _parent_clks, _num_parents, _init_flags) \ struct clk _name = { \ .data = &(struct clk_fixed_factor_data) { \ .mult = (_mult), \ @@ -101,8 +95,7 @@ struct clk _name = { \ }, \ } -#define CLK_GATE(_name, _offset, _bit, _data_flags, _parent_clks, \ - _num_parents, _init_flags) \ +#define CLK_GATE(_name, _offset, _bit, _data_flags, _parent_clks, _num_parents, _init_flags) \ struct clk _name = { \ .data = &(struct clk_gate_data) { \ .offset = (_offset), \ @@ -118,8 +111,7 @@ struct clk _name = { \ }, \ } -#define CLK_GATE_RO(_name, _offset, _bit, _data_flags, _parent_clks, \ - _num_parents, _init_flags) \ +#define CLK_GATE_RO(_name, _offset, _bit, _data_flags, _parent_clks, _num_parents, _init_flags) \ struct clk _name = { \ .data = &(struct clk_gate_data) { \ .offset = (_offset), \ @@ -135,8 +127,7 @@ struct clk _name = { \ }, \ } -#define CLK_MUX(_name, _offset, _mask, _shift, _table, _data_flags, \ - _parent_data, _num_parents, _init_flags) \ +#define CLK_MUX(_name, _offset, _mask, _shift, _table, _data_flags, _parent_data, _num_parents, _init_flags) \ struct clk _name = { \ .data = &(struct clk_mux_data) { \ .offset = (_offset), \ @@ -154,8 +145,7 @@ struct clk _name = { \ }, \ } -#define CLK_MUX_RO(_name, _offset, _mask, _shift, _table, _data_flags, \ - _parent_data, _num_parents, _init_flags) \ +#define CLK_MUX_RO(_name, _offset, _mask, _shift, _table, _data_flags, _parent_data, _num_parents, _init_flags) \ struct clk _name = { \ .data = &(struct clk_mux_data) { \ .offset = (_offset), \ @@ -173,8 +163,7 @@ struct clk _name = { \ }, \ } -#define CLK_DIV(_name, _offset, _shift, _width, _data_flags, _parent_clks, \ - _num_parents, _init_flags) \ +#define CLK_DIV(_name, _offset, _shift, _width, _data_flags, _parent_clks, _num_parents, _init_flags) \ struct clk _name = { \ .data = &(struct clk_div_data) { \ .offset = (_offset), \ @@ -191,8 +180,7 @@ struct clk _name = { \ }, \ } -#define CLK_DIV_RO(_name, _offset, _shift, _width, _data_flags, _parent_clks, \ - _num_parents, _init_flags) \ +#define CLK_DIV_RO(_name, _offset, _shift, _width, _data_flags, _parent_clks, _num_parents, _init_flags) \ struct clk _name = { \ .data = &(struct clk_div_data) { \ .offset = (_offset), \ diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 60bfd0485..f73d2b98e 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -70,8 +70,7 @@ struct clk_init_data; * clk_foo's clk_ops * * @init: pointer to struct clk_init_data that contains the init data shared - * with the common clock framework. This pointer will be set to NULL once - * a clk_register() variant is called on this clk_hw pointer. + * with the common clock framework. */ struct clk_hw { struct clk *clk; @@ -83,20 +82,6 @@ struct clk_hw { * be provided by the clock implementation, and will be called by drivers * through the clk_* api. * - * @prepare: Prepare the clock for enabling. This must not return until - * the clock is fully prepared, and it's safe to call clk_enable. - * This callback is intended to allow clock implementations to - * do any initialisation that may sleep. Called with - * prepare_lock held. - * - * @unprepare: Release the clock from its prepared state. This will typically - * undo any work done in the @prepare callback. Called with - * prepare_lock held. - * - * @is_prepared: Queries the hardware to determine if the clock is prepared. - * This function is allowed to sleep. Optional, if this op is not - * set then the prepare count will be used. - * * @enable: Enable the clock atomically. This must not return until the * clock is generating a valid clock signal, usable by consumer * devices. Called with enable_lock held. This function must not @@ -109,11 +94,6 @@ struct clk_hw { * This function must not sleep. Optional, if this op is not * set then the enable count will be used. * - * @disable_unused: Disable the clock atomically. Only called from - * clk_disable_unused for gate clocks with special needs. - * Called with enable_lock held. This function must not - * sleep. - * * @recalc_rate: Recalculate the rate of this clock, by querying hardware. The * parent rate is an input parameter. It is up to the caller to * ensure that the prepare_mutex is held across this call. If the @@ -165,9 +145,8 @@ struct clk_hw { struct clk_ops { uint8_t (*get_parent)(const struct clk *clk); int (*set_parent)(struct clk *clk, uint8_t index); - unsigned long (*recalc_rate)(const struct clk *clk, - unsigned long parent_rate); - int (*set_rate)(const struct clk *clk, uint32_t rate, uint32_t parent_rate); + uint64_t (*recalc_rate)(const struct clk *clk, uint64_t parent_rate); + int (*set_rate)(const struct clk *clk, uint64_t rate, uint64_t parent_rate); void (*init)(struct clk *clk); int (*enable)(struct clk *clk); int (*disable)(struct clk *clk); @@ -334,9 +313,6 @@ struct clk_fixed_factor_data { * .get_parent clk_op. * CLK_MUX_ROUND_CLOSEST - Use the parent rate that is closest to the desired * frequency. - * CLK_MUX_BIG_ENDIAN - By default little endian register accesses are used for - * the mux register. Setting this flag makes the register accesses big - * endian. */ struct clk_mux_data { uint32_t offset; @@ -368,21 +344,21 @@ const struct clk *get_parent(const struct clk *clk); * @clk: pointer to the current clk * */ -uint32_t clk_get_rate(const struct clk *clk, uint64_t *rate); +int clk_get_rate(const struct clk *clk, uint64_t *rate); /** * function clk_enable() - enable the target clock signal * * @clk: pointer to the current clk */ -uint32_t clk_enable(struct clk *clk); +int clk_enable(struct clk *clk); /** * function clk_disable() - disable the target clock signal * * @clk: pointer to the current clk */ -uint32_t clk_disable(struct clk *clk); +int clk_disable(struct clk *clk); /** * function clk_set_rate() - set the nearest rate to the requested rate for @@ -392,4 +368,4 @@ uint32_t clk_disable(struct clk *clk); * @req_rate: request rate * @rate: pointer to result variable */ -uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate); +int clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate); diff --git a/drivers/clk/imx/clk-imx.c b/drivers/clk/imx/clk-imx.c index ab3ccb801..e188cf72d 100644 --- a/drivers/clk/imx/clk-imx.c +++ b/drivers/clk/imx/clk-imx.c @@ -69,8 +69,7 @@ const struct clk_ops clk_gate2_ops = { .is_enabled = clk_gate2_is_enabled, }; -static unsigned long clk_pll_recalc_rate(const struct clk *clk, - unsigned long prate) +static uint64_t clk_pll_recalc_rate(const struct clk *clk, uint64_t prate) { /* TODO: This function is derived from Linux codebase, but seems wrong * according to the datasheet as PLL_REFCLK_DIV_VAL[5:10] is never used. */ @@ -83,12 +82,10 @@ static unsigned long clk_pll_recalc_rate(const struct clk *clk, output_div_val = (output_div_val + 1) * 2; /* Valid Frac Divider value is 1 to 2^24 */ - uint32_t frac_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 7, - 24); + uint32_t frac_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 7, 24); /* Valid Int Divider value is 1 to 32 */ - uint32_t int_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 0, - 7); + uint32_t int_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 0, 7); temp_rate *= prate; temp_rate *= frac_div_val; @@ -112,8 +109,7 @@ const struct clk_ops clk_frac_pll_ops = { /* .set_rate = clk_pll_set_rate, */ }; -static unsigned long clk_sscg_pll_recalc_rate(const struct clk *clk, - unsigned long prate) +static uint64_t clk_sscg_pll_recalc_rate(const struct clk *clk, uint64_t prate) { struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); uint64_t temp_rate = prate; @@ -173,26 +169,21 @@ const struct clk_ops clk_sscg_pll_ops = { /* .determine_rate = clk_sscg_pll_determine_rate, */ }; -static unsigned long imx8m_clk_core_slice_recalc_rate(const struct clk *clk, - unsigned long prate) +static uint64_t imx8m_clk_core_slice_recalc_rate(const struct clk *clk, uint64_t prate) { - struct clk_core_slice_data *data = - (struct clk_core_slice_data *)(clk->data); + struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); - uint32_t div_val = regmap_read_bits(clk->base, data->offset, - data->div_shift, data->div_width); + uint32_t div_val = regmap_read_bits(clk->base, data->offset, data->div_shift, data->div_width); /* Divider value is n+1 */ return DIV_ROUND_UP_ULL((uint64_t)prate, div_val + 1); } static uint8_t imx8m_clk_core_slice_get_parent(const struct clk *clk) { - struct clk_core_slice_data *data = - (struct clk_core_slice_data *)(clk->data); + struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, - data->mux_shift, data->mux_mask); + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); if (val >= num_parents) return -1; @@ -202,17 +193,14 @@ static uint8_t imx8m_clk_core_slice_get_parent(const struct clk *clk) static int imx8m_clk_core_slice_set_parent(struct clk *clk, uint8_t index) { - struct clk_core_slice_data *data = - (struct clk_core_slice_data *)(clk->data); + struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); /* * write twice to make sure non-target interface * SEL_A/B point the same clk input. */ - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, - data->mux_mask, index); - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, - data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); return 0; } @@ -226,32 +214,25 @@ const struct clk_ops clk_core_slice_ops = { .set_parent = imx8m_clk_core_slice_set_parent, }; -static unsigned long imx8m_clk_common_slice_recalc_rate(const struct clk *clk, - unsigned long prate) +static uint64_t imx8m_clk_common_slice_recalc_rate(const struct clk *clk, uint64_t prate) { - struct clk_common_slice_data *data = - (struct clk_common_slice_data *)(clk->data); + struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); - uint32_t prediv_val = regmap_read_bits( - clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); + uint32_t prediv_val = regmap_read_bits(clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); /* Divider value is n+1 */ - unsigned long prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, - prediv_val + 1); + uint64_t prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, prediv_val + 1); - uint32_t postdiv_val = regmap_read_bits( - clk->base, data->offset, data->postdiv_shift, data->postdiv_width); + uint32_t postdiv_val = regmap_read_bits(clk->base, data->offset, data->postdiv_shift, data->postdiv_width); /* Divider value is n+1 */ return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); } static uint8_t imx8m_clk_common_slice_get_parent(const struct clk *clk) { - struct clk_common_slice_data *data = - (struct clk_common_slice_data *)(clk->data); + struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, - data->mux_shift, data->mux_mask); + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); if (val >= num_parents) return -1; @@ -261,17 +242,14 @@ static uint8_t imx8m_clk_common_slice_get_parent(const struct clk *clk) static int imx8m_clk_common_slice_set_parent(struct clk *clk, uint8_t index) { - struct clk_common_slice_data *data = - (struct clk_common_slice_data *)(clk->data); + struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); /* * write twice to make sure non-target interface * SEL_A/B point the same clk input. */ - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, - data->mux_mask, index); - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, - data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); return 0; } @@ -285,19 +263,15 @@ const struct clk_ops clk_common_slice_ops = { .set_parent = imx8m_clk_common_slice_set_parent, }; -static unsigned long imx8m_clk_bus_slice_recalc_rate(const struct clk *clk, - unsigned long prate) +static uint64_t imx8m_clk_bus_slice_recalc_rate(const struct clk *clk, uint64_t prate) { struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); - uint32_t prediv_val = regmap_read_bits( - clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); + uint32_t prediv_val = regmap_read_bits(clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); /* Divider value is n+1 */ - unsigned long prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, - prediv_val + 1); + uint64_t prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, prediv_val + 1); - uint32_t postdiv_val = regmap_read_bits( - clk->base, data->offset, data->postdiv_shift, data->postdiv_width); + uint32_t postdiv_val = regmap_read_bits(clk->base, data->offset, data->postdiv_shift, data->postdiv_width); /* Divider value is n+1 */ return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); } @@ -307,8 +281,7 @@ static uint8_t imx8m_clk_bus_slice_get_parent(const struct clk *clk) struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, - data->mux_shift, data->mux_mask); + uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); if (val >= num_parents) return -1; @@ -324,10 +297,8 @@ static int imx8m_clk_bus_slice_set_parent(struct clk *clk, uint8_t index) * write twice to make sure non-target interface * SEL_A/B point the same clk input. */ - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, - data->mux_mask, index); - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, - data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); return 0; } diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 78a3807b6..0bf1d4cd6 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -2382,88 +2382,58 @@ static IMX_CLK_SOURCE(clk_ext2, 0x7ed6b40); static IMX_CLK_SOURCE(clk_ext3, 0x7ed6b40); static IMX_CLK_SOURCE(clk_ext4, 0x7ed6b40); -static IMX_CLK_MUX(arm_pll_ref_sel, CCM_ANALOG_BASE, 0x28, 16, 2, pll_ref_sels, - ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(gpu_pll_ref_sel, CCM_ANALOG_BASE, 0x18, 16, 2, pll_ref_sels, - ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(vpu_pll_ref_sel, CCM_ANALOG_BASE, 0x20, 16, 2, pll_ref_sels, - ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(audio_pll1_ref_sel, CCM_ANALOG_BASE, 0x0, 16, 2, - pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(audio_pll2_ref_sel, CCM_ANALOG_BASE, 0x8, 16, 2, - pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(video_pll1_ref_sel, CCM_ANALOG_BASE, 0x10, 16, 2, - pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(sys3_pll1_ref_sel, CCM_ANALOG_BASE, 0x48, 0, 2, pll_ref_sels, - ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(dram_pll1_ref_sel, CCM_ANALOG_BASE, 0x60, 0, 2, pll_ref_sels, - ARRAY_SIZE(pll_ref_sels)); -static IMX_CLK_MUX(video2_pll1_ref_sel, CCM_ANALOG_BASE, 0x54, 0, 2, - pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - -static IMX_CLK_DIV(arm_pll_ref_div, { &arm_pll_ref_sel }, CCM_ANALOG_BASE, 0x28, - 5, 6); -static IMX_CLK_DIV(gpu_pll_ref_div, { &gpu_pll_ref_sel }, CCM_ANALOG_BASE, 0x18, - 5, 6); -static IMX_CLK_DIV(vpu_pll_ref_div, { &vpu_pll_ref_sel }, CCM_ANALOG_BASE, 0x20, - 5, 6); -static IMX_CLK_DIV(audio_pll1_ref_div, { &audio_pll1_ref_sel }, CCM_ANALOG_BASE, - 0x0, 5, 6); -static IMX_CLK_DIV(audio_pll2_ref_div, { &audio_pll2_ref_sel }, CCM_ANALOG_BASE, - 0x8, 5, 6); -static IMX_CLK_DIV(video_pll1_ref_div, { &video_pll1_ref_sel }, CCM_ANALOG_BASE, - 0x10, 5, 6); +static IMX_CLK_MUX(arm_pll_ref_sel, CCM_ANALOG_BASE, 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(gpu_pll_ref_sel, CCM_ANALOG_BASE, 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(vpu_pll_ref_sel, CCM_ANALOG_BASE, 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(audio_pll1_ref_sel, CCM_ANALOG_BASE, 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(audio_pll2_ref_sel, CCM_ANALOG_BASE, 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(video_pll1_ref_sel, CCM_ANALOG_BASE, 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(sys3_pll1_ref_sel, CCM_ANALOG_BASE, 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(dram_pll1_ref_sel, CCM_ANALOG_BASE, 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); +static IMX_CLK_MUX(video2_pll1_ref_sel, CCM_ANALOG_BASE, 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + +static IMX_CLK_DIV(arm_pll_ref_div, { &arm_pll_ref_sel }, CCM_ANALOG_BASE, 0x28, 5, 6); +static IMX_CLK_DIV(gpu_pll_ref_div, { &gpu_pll_ref_sel }, CCM_ANALOG_BASE, 0x18, 5, 6); +static IMX_CLK_DIV(vpu_pll_ref_div, { &vpu_pll_ref_sel }, CCM_ANALOG_BASE, 0x20, 5, 6); +static IMX_CLK_DIV(audio_pll1_ref_div, { &audio_pll1_ref_sel }, CCM_ANALOG_BASE, 0x0, 5, 6); +static IMX_CLK_DIV(audio_pll2_ref_div, { &audio_pll2_ref_sel }, CCM_ANALOG_BASE, 0x8, 5, 6); +static IMX_CLK_DIV(video_pll1_ref_div, { &video_pll1_ref_sel }, CCM_ANALOG_BASE, 0x10, 5, 6); static IMX_CLK_FRAC_PLL(arm_pll, { &arm_pll_ref_div }, CCM_ANALOG_BASE, 0x28); static IMX_CLK_FRAC_PLL(gpu_pll, { &gpu_pll_ref_div }, CCM_ANALOG_BASE, 0x18); static IMX_CLK_FRAC_PLL(vpu_pll, { &vpu_pll_ref_div }, CCM_ANALOG_BASE, 0x20); -static IMX_CLK_FRAC_PLL(audio_pll1, { &audio_pll1_ref_div }, CCM_ANALOG_BASE, - 0x0); -static IMX_CLK_FRAC_PLL(audio_pll2, { &audio_pll2_ref_div }, CCM_ANALOG_BASE, - 0x8); -static IMX_CLK_FRAC_PLL(video_pll1, { &video_pll1_ref_div }, CCM_ANALOG_BASE, - 0x10); +static IMX_CLK_FRAC_PLL(audio_pll1, { &audio_pll1_ref_div }, CCM_ANALOG_BASE, 0x0); +static IMX_CLK_FRAC_PLL(audio_pll2, { &audio_pll2_ref_div }, CCM_ANALOG_BASE, 0x8); +static IMX_CLK_FRAC_PLL(video_pll1, { &video_pll1_ref_div }, CCM_ANALOG_BASE, 0x10); /* PLL bypass out */ -static IMX_CLK_MUX_FLAGS(arm_pll_bypass, CCM_ANALOG_BASE, 0x28, 14, 1, - arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), - CLK_SET_RATE_PARENT); -static IMX_CLK_MUX(gpu_pll_bypass, CCM_ANALOG_BASE, 0x18, 14, 1, - gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels)); -static IMX_CLK_MUX(vpu_pll_bypass, CCM_ANALOG_BASE, 0x20, 14, 1, - vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels)); -static IMX_CLK_MUX(audio_pll1_bypass, CCM_ANALOG_BASE, 0x0, 14, 1, - audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels)); -static IMX_CLK_MUX(audio_pll2_bypass, CCM_ANALOG_BASE, 0x8, 14, 1, - audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels)); -static IMX_CLK_MUX(video_pll1_bypass, CCM_ANALOG_BASE, 0x10, 14, 1, - video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels)); +static IMX_CLK_MUX_FLAGS(arm_pll_bypass, CCM_ANALOG_BASE, 0x28, 14, 1, arm_pll_bypass_sels, + ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); +static IMX_CLK_MUX(gpu_pll_bypass, CCM_ANALOG_BASE, 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels)); +static IMX_CLK_MUX(vpu_pll_bypass, CCM_ANALOG_BASE, 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels)); +static IMX_CLK_MUX(audio_pll1_bypass, CCM_ANALOG_BASE, 0x0, 14, 1, audio_pll1_bypass_sels, + ARRAY_SIZE(audio_pll1_bypass_sels)); +static IMX_CLK_MUX(audio_pll2_bypass, CCM_ANALOG_BASE, 0x8, 14, 1, audio_pll2_bypass_sels, + ARRAY_SIZE(audio_pll2_bypass_sels)); +static IMX_CLK_MUX(video_pll1_bypass, CCM_ANALOG_BASE, 0x10, 14, 1, video_pll1_bypass_sels, + ARRAY_SIZE(video_pll1_bypass_sels)); /* PLL OUT GATE */ -static IMX_CLK_GATE(arm_pll_out, { &arm_pll_bypass }, CCM_ANALOG_BASE, 0x28, - 21); -static IMX_CLK_GATE(gpu_pll_out, { &gpu_pll_bypass }, CCM_ANALOG_BASE, 0x18, - 21); -static IMX_CLK_GATE(vpu_pll_out, { &vpu_pll_bypass }, CCM_ANALOG_BASE, 0x20, - 21); -static IMX_CLK_GATE(audio_pll1_out, { &audio_pll1_bypass }, CCM_ANALOG_BASE, - 0x0, 21); -static IMX_CLK_GATE(audio_pll2_out, { &audio_pll2_bypass }, CCM_ANALOG_BASE, - 0x8, 21); -static IMX_CLK_GATE(video_pll1_out, { &video_pll1_bypass }, CCM_ANALOG_BASE, - 0x10, 21); +static IMX_CLK_GATE(arm_pll_out, { &arm_pll_bypass }, CCM_ANALOG_BASE, 0x28, 21); +static IMX_CLK_GATE(gpu_pll_out, { &gpu_pll_bypass }, CCM_ANALOG_BASE, 0x18, 21); +static IMX_CLK_GATE(vpu_pll_out, { &vpu_pll_bypass }, CCM_ANALOG_BASE, 0x20, 21); +static IMX_CLK_GATE(audio_pll1_out, { &audio_pll1_bypass }, CCM_ANALOG_BASE, 0x0, 21); +static IMX_CLK_GATE(audio_pll2_out, { &audio_pll2_bypass }, CCM_ANALOG_BASE, 0x8, 21); +static IMX_CLK_GATE(video_pll1_out, { &video_pll1_bypass }, CCM_ANALOG_BASE, 0x10, 21); static IMX_CLK_FIXED(sys1_pll_out, 800000000); static IMX_CLK_FIXED(sys2_pll_out, 1000000000); -static IMX_CLK_SSCG_PLL(sys3_pll_out, sys3_pll_out_sels, - ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, - 0x48, CLK_IS_CRITICAL); -static IMX_CLK_SSCG_PLL(dram_pll_out, dram_pll_out_sels, - ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, - 0x60, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); -static IMX_CLK_SSCG_PLL(video2_pll_out, video2_pll_out_sels, - ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, - CCM_ANALOG_BASE, 0x54, 0); +static IMX_CLK_SSCG_PLL(sys3_pll_out, sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x48, + CLK_IS_CRITICAL); +static IMX_CLK_SSCG_PLL(dram_pll_out, dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, 0x60, + CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE); +static IMX_CLK_SSCG_PLL(video2_pll_out, video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, CCM_ANALOG_BASE, + 0x54, 0); /* SYS PLL1 fixed output */ static IMX_CLK_FIXED_FACTOR(sys1_pll_40m, { &sys1_pll_out }, 1, 20); @@ -2487,56 +2457,40 @@ static IMX_CLK_FIXED_FACTOR(sys2_pll_333m, { &sys2_pll_out }, 1, 3); static IMX_CLK_FIXED_FACTOR(sys2_pll_500m, { &sys2_pll_out }, 1, 2); static IMX_CLK_FIXED_FACTOR(sys2_pll_1000m, { &sys2_pll_out }, 1, 1); -static IMX_CLK_DIV(audio_pll1_out_monitor, { &audio_pll1_bypass }, - CCM_ANALOG_BASE, 0x78, 0, 3); -static IMX_CLK_DIV(audio_pll2_out_monitor, { &audio_pll2_bypass }, - CCM_ANALOG_BASE, 0x78, 4, 3); -static IMX_CLK_DIV(video_pll1_out_monitor, { &video_pll1_bypass }, - CCM_ANALOG_BASE, 0x78, 8, 3); -static IMX_CLK_DIV(gpu_pll_out_monitor, { &gpu_pll_bypass }, CCM_ANALOG_BASE, - 0x78, 12, 3); -static IMX_CLK_DIV(vpu_pll_out_monitor, { &vpu_pll_bypass }, CCM_ANALOG_BASE, - 0x78, 16, 3); -static IMX_CLK_DIV(arm_pll_out_monitor, { &arm_pll_bypass }, CCM_ANALOG_BASE, - 0x78, 20, 3); -static IMX_CLK_DIV(sys_pll1_out_monitor, { &sys1_pll_out }, CCM_ANALOG_BASE, - 0x7c, 0, 3); -static IMX_CLK_DIV(sys_pll2_out_monitor, { &sys2_pll_out }, CCM_ANALOG_BASE, - 0x7c, 4, 3); -static IMX_CLK_DIV(sys_pll3_out_monitor, { &sys3_pll_out }, CCM_ANALOG_BASE, - 0x7c, 8, 3); -static IMX_CLK_DIV(dram_pll_out_monitor, { &dram_pll_out }, CCM_ANALOG_BASE, - 0x7c, 12, 3); -static IMX_CLK_DIV(video_pll2_out_monitor, { &video2_pll_out }, CCM_ANALOG_BASE, - 0x7c, 16, 3); -static IMX_CLK_MUX(pllout_monitor_sel, CCM_ANALOG_BASE, 0x74, 0, 4, - pllout_monitor_sels, ARRAY_SIZE(pllout_monitor_sels)); -static IMX_CLK_GATE(pllout_monitor_clk2, { &pllout_monitor_sel }, - CCM_ANALOG_BASE, 0x74, 4); +static IMX_CLK_DIV(audio_pll1_out_monitor, { &audio_pll1_bypass }, CCM_ANALOG_BASE, 0x78, 0, 3); +static IMX_CLK_DIV(audio_pll2_out_monitor, { &audio_pll2_bypass }, CCM_ANALOG_BASE, 0x78, 4, 3); +static IMX_CLK_DIV(video_pll1_out_monitor, { &video_pll1_bypass }, CCM_ANALOG_BASE, 0x78, 8, 3); +static IMX_CLK_DIV(gpu_pll_out_monitor, { &gpu_pll_bypass }, CCM_ANALOG_BASE, 0x78, 12, 3); +static IMX_CLK_DIV(vpu_pll_out_monitor, { &vpu_pll_bypass }, CCM_ANALOG_BASE, 0x78, 16, 3); +static IMX_CLK_DIV(arm_pll_out_monitor, { &arm_pll_bypass }, CCM_ANALOG_BASE, 0x78, 20, 3); +static IMX_CLK_DIV(sys_pll1_out_monitor, { &sys1_pll_out }, CCM_ANALOG_BASE, 0x7c, 0, 3); +static IMX_CLK_DIV(sys_pll2_out_monitor, { &sys2_pll_out }, CCM_ANALOG_BASE, 0x7c, 4, 3); +static IMX_CLK_DIV(sys_pll3_out_monitor, { &sys3_pll_out }, CCM_ANALOG_BASE, 0x7c, 8, 3); +static IMX_CLK_DIV(dram_pll_out_monitor, { &dram_pll_out }, CCM_ANALOG_BASE, 0x7c, 12, 3); +static IMX_CLK_DIV(video_pll2_out_monitor, { &video2_pll_out }, CCM_ANALOG_BASE, 0x7c, 16, 3); +static IMX_CLK_MUX(pllout_monitor_sel, CCM_ANALOG_BASE, 0x74, 0, 4, pllout_monitor_sels, + ARRAY_SIZE(pllout_monitor_sels)); +static IMX_CLK_GATE(pllout_monitor_clk2, { &pllout_monitor_sel }, CCM_ANALOG_BASE, 0x74, 4); /* CORE */ static IMX_CLK_COMPOSITE_CORE(arm_a53_div, imx8mq_a53_sels, CCM_BASE, 0x8000); -static IMX_CLK_COMPOSITE_CORE(arm_m4_core, imx8mq_arm_m4_sels, CCM_BASE, - 0x8080); +static IMX_CLK_COMPOSITE_CORE(arm_m4_core, imx8mq_arm_m4_sels, CCM_BASE, 0x8080); static IMX_CLK_COMPOSITE_CORE(vpu_core, imx8mq_vpu_sels, CCM_BASE, 0x8100); static IMX_CLK_COMPOSITE_CORE(gpu_core, imx8mq_gpu_core_sels, CCM_BASE, 0x8180); static IMX_CLK_COMPOSITE(gpu_shader, imx8mq_gpu_shader_sels, CCM_BASE, 0x8200); /* CORE SEL */ -static IMX_CLK_MUX2(arm_a53_core, CCM_BASE, 0x9880, 24, 1, imx8mq_a53_core_sels, - ARRAY_SIZE(imx8mq_a53_core_sels)); +static IMX_CLK_MUX2(arm_a53_core, CCM_BASE, 0x9880, 24, 1, imx8mq_a53_core_sels, ARRAY_SIZE(imx8mq_a53_core_sels)); /* BUS */ static IMX_CLK_COMPOSITE_BUS(main_axi, imx8mq_main_axi_sels, CCM_BASE, 0x8800); static IMX_CLK_COMPOSITE_BUS(enet_axi, imx8mq_enet_axi_sels, CCM_BASE, 0x8880); -static IMX_CLK_COMPOSITE_BUS(nand_usdhc_bus, imx8mq_nand_usdhc_sels, CCM_BASE, - 0x8900); +static IMX_CLK_COMPOSITE_BUS(nand_usdhc_bus, imx8mq_nand_usdhc_sels, CCM_BASE, 0x8900); static IMX_CLK_COMPOSITE_BUS(vpu_bus, imx8mq_vpu_bus_sels, CCM_BASE, 0x8980); static IMX_CLK_COMPOSITE_BUS(disp_axi, imx8mq_disp_axi_sels, CCM_BASE, 0x8a00); static IMX_CLK_COMPOSITE_BUS(disp_apb, imx8mq_disp_apb_sels, CCM_BASE, 0x8a80); -static IMX_CLK_COMPOSITE_BUS(disp_rtrm, imx8mq_disp_rtrm_sels, CCM_BASE, - 0x8b00); +static IMX_CLK_COMPOSITE_BUS(disp_rtrm, imx8mq_disp_rtrm_sels, CCM_BASE, 0x8b00); static IMX_CLK_COMPOSITE_BUS(usb_bus, imx8mq_usb_bus_sels, CCM_BASE, 0x8b80); static IMX_CLK_COMPOSITE_BUS(gpu_axi, imx8mq_gpu_axi_sels, CCM_BASE, 0x8c00); static IMX_CLK_COMPOSITE_BUS(gpu_ahb, imx8mq_gpu_ahb_sels, CCM_BASE, 0x8c80); @@ -2546,8 +2500,7 @@ static IMX_CLK_COMPOSITE_BUS(noc_apb, imx8mq_noc_apb_sels, CCM_BASE, 0x8d80); /* AHB */ /* AHB clock is used by the AHB bus therefore marked as critical */ static IMX_CLK_COMPOSITE_BUS(ahb, imx8mq_ahb_sels, CCM_BASE, 0x9000); -static IMX_CLK_COMPOSITE_BUS(audio_ahb, imx8mq_audio_ahb_sels, CCM_BASE, - 0x9100); +static IMX_CLK_COMPOSITE_BUS(audio_ahb, imx8mq_audio_ahb_sels, CCM_BASE, 0x9100); /* IPG */ static IMX_CLK_DIV2(ipg_root, { &ahb }, CCM_BASE, 0x9080, 0, 1); @@ -2558,26 +2511,21 @@ static IMX_CLK_DIV2(ipg_audio_root, { &audio_ahb }, CCM_BASE, 0x9180, 0, 1); * The fw_managed helper sets GET_RATE_NOCACHE and clears SET_PARENT_GATE * as div value should always be read from hardware */ -static IMX_CLK_MUX2_FLAGS(dram_core_clk, CCM_BASE, 0x9800, 24, 1, - imx8mq_dram_core_sels, +static IMX_CLK_MUX2_FLAGS(dram_core_clk, CCM_BASE, 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL); -static IMX_CLK_COMPOSITE_FW_MANAGED(dram_alt, imx8mq_dram_alt_sels, CCM_BASE, - 0xa000); -static IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(dram_apb, imx8mq_dram_apb_sels, - CCM_BASE, 0xa080); +static IMX_CLK_COMPOSITE_FW_MANAGED(dram_alt, imx8mq_dram_alt_sels, CCM_BASE, 0xa000); +static IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(dram_apb, imx8mq_dram_apb_sels, CCM_BASE, 0xa080); /* IP */ static IMX_CLK_COMPOSITE(vpu_g1, imx8mq_vpu_g1_sels, CCM_BASE, 0xa100); static IMX_CLK_COMPOSITE(vpu_g2, imx8mq_vpu_g2_sels, CCM_BASE, 0xa180); static IMX_CLK_COMPOSITE(disp_dtrc, imx8mq_disp_dtrc_sels, CCM_BASE, 0xa200); -static IMX_CLK_COMPOSITE(disp_dc8000, imx8mq_disp_dc8000_sels, CCM_BASE, - 0xa280); +static IMX_CLK_COMPOSITE(disp_dc8000, imx8mq_disp_dc8000_sels, CCM_BASE, 0xa280); static IMX_CLK_COMPOSITE(pcie1_ctrl, imx8mq_pcie1_ctrl_sels, CCM_BASE, 0xa300); static IMX_CLK_COMPOSITE(pcie1_phy, imx8mq_pcie1_phy_sels, CCM_BASE, 0xa380); static IMX_CLK_COMPOSITE(pcie1_aux, imx8mq_pcie1_aux_sels, CCM_BASE, 0xa400); static IMX_CLK_COMPOSITE(dc_pixel, imx8mq_dc_pixel_sels, CCM_BASE, 0xa480); -static IMX_CLK_COMPOSITE(lcdif_pixel, imx8mq_lcdif_pixel_sels, CCM_BASE, - 0xa500); +static IMX_CLK_COMPOSITE(lcdif_pixel, imx8mq_lcdif_pixel_sels, CCM_BASE, 0xa500); static IMX_CLK_COMPOSITE(sai1, imx8mq_sai1_sels, CCM_BASE, 0xa580); static IMX_CLK_COMPOSITE(sai2, imx8mq_sai2_sels, CCM_BASE, 0xa600); static IMX_CLK_COMPOSITE(sai3, imx8mq_sai3_sels, CCM_BASE, 0xa680); @@ -2656,34 +2604,20 @@ static IMX_CLK_GATE4(pwm3_root_clk, { &pwm3 }, CCM_BASE, 0x42a0, 0); static IMX_CLK_GATE4(pwm4_root_clk, { &pwm4 }, CCM_BASE, 0x42b0, 0); static IMX_CLK_GATE4(qspi_root_clk, { &qspi }, CCM_BASE, 0x42f0, 0); -static IMX_CLK_GATE2_SHARED2(nand_root_clk, { &nand }, CCM_BASE, 0x4300, 0, - &share_count_nand); -static IMX_CLK_GATE2_SHARED2(nand_usdhc_rawnand_clk, { &nand_usdhc_bus }, - CCM_BASE, 0x4300, 0, &share_count_nand); -static IMX_CLK_GATE2_SHARED2(sai1_root_clk, { &sai1 }, CCM_BASE, 0x4330, 0, - &share_count_sai1); -static IMX_CLK_GATE2_SHARED2(sai1_ipg_clk, { &ipg_audio_root }, CCM_BASE, - 0x4330, 0, &share_count_sai1); -static IMX_CLK_GATE2_SHARED2(sai2_root_clk, { &sai2 }, CCM_BASE, 0x4340, 0, - &share_count_sai2); -static IMX_CLK_GATE2_SHARED2(sai2_ipg_clk, { &ipg_root }, CCM_BASE, 0x4340, 0, - &share_count_sai2); -static IMX_CLK_GATE2_SHARED2(sai3_root_clk, { &sai3 }, CCM_BASE, 0x4350, 0, - &share_count_sai3); -static IMX_CLK_GATE2_SHARED2(sai3_ipg_clk, { &ipg_root }, CCM_BASE, 0x4350, 0, - &share_count_sai3); -static IMX_CLK_GATE2_SHARED2(sai4_root_clk, { &sai4 }, CCM_BASE, 0x4360, 0, - &share_count_sai4); -static IMX_CLK_GATE2_SHARED2(sai4_ipg_clk, { &ipg_audio_root }, CCM_BASE, - 0x4360, 0, &share_count_sai4); -static IMX_CLK_GATE2_SHARED2(sai5_root_clk, { &sai5 }, CCM_BASE, 0x4370, 0, - &share_count_sai5); -static IMX_CLK_GATE2_SHARED2(sai5_ipg_clk, { &ipg_audio_root }, CCM_BASE, - 0x4370, 0, &share_count_sai5); -static IMX_CLK_GATE2_SHARED2(sai6_root_clk, { &sai6 }, CCM_BASE, 0x4380, 0, - &share_count_sai6); -static IMX_CLK_GATE2_SHARED2(sai6_ipg_clk, { &ipg_audio_root }, CCM_BASE, - 0x4380, 0, &share_count_sai6); +static IMX_CLK_GATE2_SHARED2(nand_root_clk, { &nand }, CCM_BASE, 0x4300, 0, &share_count_nand); +static IMX_CLK_GATE2_SHARED2(nand_usdhc_rawnand_clk, { &nand_usdhc_bus }, CCM_BASE, 0x4300, 0, &share_count_nand); +static IMX_CLK_GATE2_SHARED2(sai1_root_clk, { &sai1 }, CCM_BASE, 0x4330, 0, &share_count_sai1); +static IMX_CLK_GATE2_SHARED2(sai1_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4330, 0, &share_count_sai1); +static IMX_CLK_GATE2_SHARED2(sai2_root_clk, { &sai2 }, CCM_BASE, 0x4340, 0, &share_count_sai2); +static IMX_CLK_GATE2_SHARED2(sai2_ipg_clk, { &ipg_root }, CCM_BASE, 0x4340, 0, &share_count_sai2); +static IMX_CLK_GATE2_SHARED2(sai3_root_clk, { &sai3 }, CCM_BASE, 0x4350, 0, &share_count_sai3); +static IMX_CLK_GATE2_SHARED2(sai3_ipg_clk, { &ipg_root }, CCM_BASE, 0x4350, 0, &share_count_sai3); +static IMX_CLK_GATE2_SHARED2(sai4_root_clk, { &sai4 }, CCM_BASE, 0x4360, 0, &share_count_sai4); +static IMX_CLK_GATE2_SHARED2(sai4_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4360, 0, &share_count_sai4); +static IMX_CLK_GATE2_SHARED2(sai5_root_clk, { &sai5 }, CCM_BASE, 0x4370, 0, &share_count_sai5); +static IMX_CLK_GATE2_SHARED2(sai5_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4370, 0, &share_count_sai5); +static IMX_CLK_GATE2_SHARED2(sai6_root_clk, { &sai6 }, CCM_BASE, 0x4380, 0, &share_count_sai6); +static IMX_CLK_GATE2_SHARED2(sai6_ipg_clk, { &ipg_audio_root }, CCM_BASE, 0x4380, 0, &share_count_sai6); static IMX_CLK_GATE4(uart1_root_clk, { &uart1 }, CCM_BASE, 0x4490, 0); static IMX_CLK_GATE4(uart2_root_clk, { &uart2 }, CCM_BASE, 0x44a0, 0); static IMX_CLK_GATE4(uart3_root_clk, { &uart3 }, CCM_BASE, 0x44b0, 0); @@ -2702,14 +2636,10 @@ static IMX_CLK_GATE2_FLAGS(vpu_g1_root_clk, { &vpu_g1 }, CCM_BASE, 0x4560, 0, static IMX_CLK_GATE4(gpu_root_clk, { &gpu_core }, CCM_BASE, 0x4570, 0); static IMX_CLK_GATE2_FLAGS(vpu_g2_root_clk, { &vpu_g2 }, CCM_BASE, 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); -static IMX_CLK_GATE2_SHARED2(disp_root_clk, { &disp_dc8000 }, CCM_BASE, 0x45d0, - 0, &share_count_dcss); -static IMX_CLK_GATE2_SHARED2(disp_axi_root_clk, { &disp_axi }, CCM_BASE, 0x45d0, - 0, &share_count_dcss); -static IMX_CLK_GATE2_SHARED2(disp_apb_root_clk, { &disp_apb }, CCM_BASE, 0x45d0, - 0, &share_count_dcss); -static IMX_CLK_GATE2_SHARED2(disp_rtrm_root_clk, { &disp_rtrm }, CCM_BASE, - 0x45d0, 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_root_clk, { &disp_dc8000 }, CCM_BASE, 0x45d0, 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_axi_root_clk, { &disp_axi }, CCM_BASE, 0x45d0, 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_apb_root_clk, { &disp_apb }, CCM_BASE, 0x45d0, 0, &share_count_dcss); +static IMX_CLK_GATE2_SHARED2(disp_rtrm_root_clk, { &disp_rtrm }, CCM_BASE, 0x45d0, 0, &share_count_dcss); static IMX_CLK_GATE4(tmu_root_clk, { &ipg_root }, CCM_BASE, 0x4620, 0); static IMX_CLK_GATE2_FLAGS(vpu_dec_root_clk, { &vpu_bus }, CCM_BASE, 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE); diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index d17b3cae9..f05e2babf 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -98,14 +98,14 @@ const struct clk *get_parent(const struct clk *clk) /* TODO: Should be just read from the structure, but need to update everytime when */ /* related clocks are modified */ -uint32_t clk_get_rate(const struct clk *clk, uint64_t *rate) +int clk_get_rate(const struct clk *clk, uint64_t *rate) { if (!clk) return CLK_UNKNOWN_TARGET; const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; uint64_t parent_rate = 0; - uint32_t err = 0; + int err = 0; const struct clk *parent_clk = get_parent(clk); @@ -124,7 +124,7 @@ uint32_t clk_get_rate(const struct clk *clk, uint64_t *rate) return 0; } -uint32_t clk_enable(struct clk *clk) +int clk_enable(struct clk *clk) { if (!clk) return CLK_UNKNOWN_TARGET; @@ -136,7 +136,7 @@ uint32_t clk_enable(struct clk *clk) return CLK_INVALID_OP; } -uint32_t clk_disable(struct clk *clk) +int clk_disable(struct clk *clk) { if (!clk) return CLK_UNKNOWN_TARGET; @@ -148,7 +148,7 @@ uint32_t clk_disable(struct clk *clk) return CLK_INVALID_OP; } -uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) +int clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) { if (!clk) return CLK_UNKNOWN_TARGET; @@ -161,7 +161,7 @@ uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) const struct clk *pclk = get_parent(clk); uint64_t prate = 0; - uint32_t err = clk_get_rate(pclk, &prate); + int err = clk_get_rate(pclk, &prate); if (err) { LOG_DRIVER_ERR("Failed to get parent clock's rate\n"); return err; @@ -174,7 +174,7 @@ uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) if (pclk && pclk->hw.init->ops->set_rate) { const struct clk *ppclk = get_parent(pclk); uint64_t pprate = 0; - uint32_t err = clk_get_rate(ppclk, &pprate); + int err = clk_get_rate(ppclk, &pprate); if (!err) { pclk->hw.init->ops->set_rate(pclk, prate, pprate); return 0; @@ -190,18 +190,17 @@ int clk_msr_stat() #ifdef DEBUG_DRIVER int i; uint64_t rate = 0; - uint32_t err; + int err; LOG_DRIVER("-------Expected clock rates------\n"); for (i = 0; i < NUM_CLK_LIST; i++) { if (clk_list[i]) { err = clk_get_rate(clk_list[i], &rate); if (err) { - LOG_DRIVER_ERR("Failed to get rate of %s: -%u\n", - clk_list[i]->hw.init->name, err); + LOG_DRIVER_ERR("Failed to get rate of %s: -%u\n", clk_list[i]->hw.init->name, err); + return err; } - LOG_DRIVER("[%4d][%10luHz] %s\n", i, rate, - clk_list[i]->hw.init->name); + LOG_DRIVER("[%4d][%10luHz] %s\n", i, rate, clk_list[i]->hw.init->name); } } LOG_DRIVER("-----------------------------\n"); @@ -244,7 +243,7 @@ void init(void) microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) { - uint32_t err = 0; + int err = 0; uint32_t argc = microkit_msginfo_get_count(msginfo); /* TODO: Check if the channel is valid */ @@ -296,8 +295,8 @@ microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) break; } default: - LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", - microkit_msginfo_get_label(msginfo), ch); + LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), + ch); err = CLK_UNKNOWN_REQ; } return microkit_msginfo_new(err, 0); diff --git a/drivers/clk/imx/include/clk-imx.h b/drivers/clk/imx/include/clk-imx.h index db012ba42..3fd64c125 100644 --- a/drivers/clk/imx/include/clk-imx.h +++ b/drivers/clk/imx/include/clk-imx.h @@ -154,8 +154,7 @@ struct clk _name = { \ #define IMX_CLK_FIXED(_name, _rate) \ IMX_CLK_SOURCE(_name, _rate) -#define IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, _parent_data, \ - _num_parents, _init_flags) \ +#define IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, _parent_data, _num_parents, _init_flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_mux_data) { \ @@ -172,23 +171,19 @@ struct clk _name = { \ }, \ } -#define IMX_CLK_MUX(_name, _base, _offset, _shift, _width, _parent_data, \ - _num_parents) \ +#define IMX_CLK_MUX(_name, _base, _offset, _shift, _width, _parent_data, _num_parents) \ IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ _parent_data, _num_parents, 0) -#define IMX_CLK_MUX2(_name, _base, _offset, _shift, _width, _parent_data, \ - _num_parents) \ +#define IMX_CLK_MUX2(_name, _base, _offset, _shift, _width, _parent_data, _num_parents) \ IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ _parent_data, _num_parents, CLK_OPS_PARENT_ENABLE) -#define IMX_CLK_MUX2_FLAGS(_name, _base, _offset, _shift, _width, \ - _parent_data, _num_parents, _flags) \ +#define IMX_CLK_MUX2_FLAGS(_name, _base, _offset, _shift, _width, _parent_data, _num_parents, _flags) \ IMX_CLK_MUX_FLAGS(_name, _base, _offset, _shift, _width, \ _parent_data, _num_parents, _flags | CLK_OPS_PARENT_ENABLE) -#define IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, _width, \ - _flags) \ +#define IMX_CLK_DIV_FLAGS(_name, _parent_clks, _base, _offset, _shift, _width, _flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_div_data) { \ @@ -244,8 +239,7 @@ struct clk _name = { \ }, \ } -#define IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, \ - _flags) \ +#define IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, _flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_gate_data) { \ @@ -260,8 +254,7 @@ struct clk _name = { \ }, \ } -#define IMX_CLK_GATE2_SHARED2(_name, _parent_clks, _base, _offset, _shift, \ - _shared_count) \ +#define IMX_CLK_GATE2_SHARED2(_name, _parent_clks, _base, _offset, _shift, _shared_count) \ IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, 0) #define IMX_CLK_GATE4(_name, _parent_clks, _base, _offset, _shift) \ @@ -270,8 +263,7 @@ IMX_CLK_GATE2_FLAGS(_name, _parent_clks, _base, _offset, _shift, 0) #define IMX_CLK_FIXED_FACTOR(_name, _parent_clks, _mult, _div) \ CLK_FIXED_FACTOR(_name, _mult, _div, 0, _parent_clks, 1, CLK_SET_RATE_PARENT) -#define IMX_CLK_SSCG_PLL(_name, _parent_data, _num_parents, _parent, _bypass1, \ - _bypass2, _base, _offset, _flags) \ +#define IMX_CLK_SSCG_PLL(_name, _parent_data, _num_parents, _parent, _bypass1, _bypass2, _base, _offset, _flags) \ struct clk _name = { \ .base = (_base), \ .data = &(struct clk_sscg_pll_data) { \ @@ -369,8 +361,7 @@ IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, \ (CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE \ | CLK_GET_RATE_NOCACHE)) -#define IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(_name, _parent_data, _base, \ - _offset) \ +#define IMX_CLK_COMPOSITE_FW_MANAGED_CRITICAL(_name, _parent_data, _base, _offset) \ IMX_CLK_COMPOSITE_FLAGS(_name, _parent_data, _base, _offset, \ (CLK_SET_RATE_NO_REPARENT | \ CLK_OPS_PARENT_ENABLE | \ diff --git a/drivers/clk/meson/clk-measure.c b/drivers/clk/meson/clk-measure.c index 5513fa288..a58d4fbb1 100644 --- a/drivers/clk/meson/clk-measure.c +++ b/drivers/clk/meson/clk-measure.c @@ -221,8 +221,7 @@ unsigned long clk_msr(unsigned long clk_mux) uint32_t msr_val = *mclk_reg2; - return DIV_ROUND_CLOSEST_ULL((msr_val & ((1 << 19) - 1)) * 1000000ULL, - duration); + return DIV_ROUND_CLOSEST_ULL((msr_val & ((1 << 19) - 1)) * 1000000ULL, duration); } const char *const *get_msr_clk_list(void) diff --git a/drivers/clk/meson/clk-meson.c b/drivers/clk/meson/clk-meson.c index 990cc2242..3cfa687fd 100644 --- a/drivers/clk/meson/clk-meson.c +++ b/drivers/clk/meson/clk-meson.c @@ -93,8 +93,7 @@ void delay_us(uint32_t us) } } -int regmap_multi_reg_write(uint64_t base, const struct reg_sequence *regs, - int num_regs) +int regmap_multi_reg_write(uint64_t base, const struct reg_sequence *regs, int num_regs) { int i; for (i = 0; i < num_regs; i++) { @@ -109,41 +108,32 @@ int regmap_multi_reg_write(uint64_t base, const struct reg_sequence *regs, static void meson_clk_pll_init(struct clk *clk) { struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); - if ((data->flags & CLK_MESON_PLL_NOINIT_ENABLED) - && clk->hw.init->ops->is_enabled(clk)) + if ((data->flags & CLK_MESON_PLL_NOINIT_ENABLED) && clk->hw.init->ops->is_enabled(clk)) return; if (data->init_count) { /* Set the reset bit */ - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, - data->rst.width, 1); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); regmap_multi_reg_write(clk->base, data->init_regs, data->init_count); /* Clear the reset bit */ - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, - data->rst.width, 0); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 0); } } -static unsigned long meson_clk_pll_recalc_rate(const struct clk *clk, - unsigned long parent_rate) +static unsigned long meson_clk_pll_recalc_rate(const struct clk *clk, unsigned long parent_rate) { struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); uint32_t n, m, frac; - n = regmap_read_bits(clk->base, data->n.reg_off, data->n.shift, - data->n.width); + n = regmap_read_bits(clk->base, data->n.reg_off, data->n.shift, data->n.width); if (n == 0) return 0; - m = regmap_read_bits(clk->base, data->m.reg_off, data->m.shift, - data->m.width); + m = regmap_read_bits(clk->base, data->m.reg_off, data->m.shift, data->m.width); - frac = data->frac.width - ? regmap_read_bits(clk->base, data->frac.reg_off, data->frac.shift, - data->frac.width) - : 0; + frac = data->frac.width ? regmap_read_bits(clk->base, data->frac.reg_off, data->frac.shift, data->frac.width) : 0; uint64_t rate = (uint64_t)parent_rate * m; @@ -163,8 +153,7 @@ static int meson_clk_pll_is_enabled(struct clk *clk) return 0; } - if (!meson_parm_read(clk->base, data->en) - || !meson_parm_read(clk->base, data->l)) { + if (!meson_parm_read(clk->base, data->en) || !meson_parm_read(clk->base, data->l)) { return 0; } @@ -178,15 +167,11 @@ static int meson_clk_pll_enable(struct clk *clk) if (meson_clk_pll_is_enabled(clk)) return 0; - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, - data->rst.width, 1); - regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, - data->en.width, 1); - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, - data->rst.width, 1); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); + regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, data->en.width, 1); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); - regmap_update_bits(clk->base, data->current_en.reg_off, - data->current_en.shift, data->current_en.width, 1); + regmap_update_bits(clk->base, data->current_en.reg_off, data->current_en.shift, data->current_en.width, 1); return 0; } @@ -194,22 +179,18 @@ static int meson_clk_pll_disable(struct clk *clk) { struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, - data->rst.width, 1); - regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, - data->en.width, 0); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); + regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, data->en.width, 0); return 0; } -const struct clk_ops meson_clk_pll_ops = { - .init = meson_clk_pll_init, - .recalc_rate = meson_clk_pll_recalc_rate, +const struct clk_ops meson_clk_pll_ops = { .init = meson_clk_pll_init, + .recalc_rate = meson_clk_pll_recalc_rate, /* .determine_rate = meson_clk_pll_determine_rate, */ /* .set_rate = meson_clk_pll_set_rate, */ - .is_enabled = meson_clk_pll_is_enabled, - .enable = meson_clk_pll_enable, - .disable = meson_clk_pll_disable -}; + .is_enabled = meson_clk_pll_is_enabled, + .enable = meson_clk_pll_enable, + .disable = meson_clk_pll_disable }; const struct clk_ops meson_clk_pll_ro_ops = { .recalc_rate = meson_clk_pll_recalc_rate, @@ -220,17 +201,13 @@ const struct clk_ops meson_clk_pll_ro_ops = { #define N2_MIN 4 #define N2_MAX 511 -static unsigned long mpll_recalc_rate(const struct clk *clk, - unsigned long prate) +static uint64_t mpll_recalc_rate(const struct clk *clk, uint64_t prate) { - struct meson_clk_mpll_data *data = - (struct meson_clk_mpll_data *)(clk->data); + struct meson_clk_mpll_data *data = (struct meson_clk_mpll_data *)(clk->data); uint32_t sdm, n2; - sdm = regmap_read_bits(clk->base, data->sdm.reg_off, data->sdm.shift, - data->sdm.width); - n2 = regmap_read_bits(clk->base, data->n2.reg_off, data->n2.shift, - data->n2.width); + sdm = regmap_read_bits(clk->base, data->sdm.reg_off, data->sdm.shift, data->sdm.width); + n2 = regmap_read_bits(clk->base, data->n2.reg_off, data->n2.shift, data->n2.width); uint32_t divisor = (SDM_DEN * n2) + sdm; if (n2 < N2_MIN) @@ -239,11 +216,9 @@ static unsigned long mpll_recalc_rate(const struct clk *clk, return DIV_ROUND_UP_ULL((uint64_t)prate * SDM_DEN, divisor); } -static int mpll_set_rate(const struct clk *clk, uint32_t rate, - uint32_t parent_rate) +static int mpll_set_rate(const struct clk *clk, uint64_t rate, uint64_t parent_rate) { - struct meson_clk_mpll_data *data = - (struct meson_clk_mpll_data *)(clk->data); + struct meson_clk_mpll_data *data = (struct meson_clk_mpll_data *)(clk->data); uint64_t div = parent_rate; uint64_t frac = do_div(div, rate); uint32_t sdm, n2; @@ -270,30 +245,25 @@ static int mpll_set_rate(const struct clk *clk, uint32_t rate, n2 = div; } - regmap_update_bits(clk->base, data->sdm.reg_off, data->sdm.shift, - data->sdm.width, sdm); - regmap_update_bits(clk->base, data->n2.reg_off, data->n2.shift, - data->n2.width, n2); + regmap_update_bits(clk->base, data->sdm.reg_off, data->sdm.shift, data->sdm.width, sdm); + regmap_update_bits(clk->base, data->n2.reg_off, data->n2.shift, data->n2.width, n2); return 0; } static void mpll_init(struct clk *clk) { - struct meson_clk_mpll_data *data = - (struct meson_clk_mpll_data *)(clk->data); + struct meson_clk_mpll_data *data = (struct meson_clk_mpll_data *)(clk->data); if (data->init_count) { regmap_multi_reg_write(clk->base, data->init_regs, data->init_count); } /* Enable the fractional part */ - regmap_update_bits(clk->base, data->sdm_en.reg_off, data->sdm_en.shift, - data->sdm_en.width, 1); + regmap_update_bits(clk->base, data->sdm_en.reg_off, data->sdm_en.shift, data->sdm_en.width, 1); /* Set spread spectrum if possible */ - unsigned int ss = data->flags & CLK_MESON_MPLL_SPREAD_SPECTRUM ? 1 : 0; - regmap_update_bits(clk->base, data->ssen.reg_off, data->ssen.shift, - data->ssen.width, ss); + uint32_t ss = data->flags & CLK_MESON_MPLL_SPREAD_SPECTRUM ? 1 : 0; + regmap_update_bits(clk->base, data->ssen.reg_off, data->ssen.shift, data->ssen.width, ss); } const struct clk_ops meson_clk_mpll_ops = { @@ -322,14 +292,12 @@ static int meson_clk_pcie_pll_enable(struct clk *clk) return -1; } -const struct clk_ops meson_clk_pcie_pll_ops = { - .init = meson_clk_pll_init, - .recalc_rate = meson_clk_pll_recalc_rate, +const struct clk_ops meson_clk_pcie_pll_ops = { .init = meson_clk_pll_init, + .recalc_rate = meson_clk_pll_recalc_rate, /* .determine_rate = meson_clk_pll_determine_rate, */ - .is_enabled = meson_clk_pll_is_enabled, - .enable = meson_clk_pcie_pll_enable, - .disable = meson_clk_pll_disable -}; + .is_enabled = meson_clk_pll_is_enabled, + .enable = meson_clk_pcie_pll_enable, + .disable = meson_clk_pll_disable }; struct vid_pll_div { unsigned int shift_val; @@ -363,24 +331,19 @@ static const struct vid_pll_div vid_pll_div_table[] = { VID_PLL_DIV(0x7f80, 2, 15, 1), /* 15/1 => /15 */ }; -static unsigned long meson_vid_pll_div_recalc_rate(const struct clk *clk, - unsigned long prate) +static unsigned long meson_vid_pll_div_recalc_rate(const struct clk *clk, unsigned long prate) { - struct meson_vid_pll_div_data *data = - (struct meson_vid_pll_div_data *)(clk->data); + struct meson_vid_pll_div_data *data = (struct meson_vid_pll_div_data *)(clk->data); const struct vid_pll_div *div; uint32_t shift_val, shift_sel; - shift_val = regmap_read_bits(clk->base, data->val.reg_off, data->val.shift, - data->val.width); - shift_sel = regmap_read_bits(clk->base, data->sel.reg_off, data->sel.shift, - data->sel.width); + shift_val = regmap_read_bits(clk->base, data->val.reg_off, data->val.shift, data->val.width); + shift_sel = regmap_read_bits(clk->base, data->sel.reg_off, data->sel.shift, data->sel.width); int i; for (i = 0; i < ARRAY_SIZE(vid_pll_div_table); ++i) { - if (vid_pll_div_table[i].shift_val == shift_val - && vid_pll_div_table[i].shift_sel == shift_sel) { + if (vid_pll_div_table[i].shift_val == shift_val && vid_pll_div_table[i].shift_sel == shift_sel) { div = &vid_pll_div_table[i]; return DIV_ROUND_UP_ULL(prate * div->multiplier, div->divider); } @@ -396,37 +359,29 @@ const struct clk_ops meson_vid_pll_div_ro_ops = { static int meson_vclk_gate_enable(struct clk *clk) { - struct meson_vclk_gate_data *data = - (struct meson_vclk_gate_data *)(clk->data); + struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, - data->enable.width, 1); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 1); /* Do a reset pulse */ - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, - data->reset.width, 1); - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, - data->reset.width, 0); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 1); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 0); return 0; } static int meson_vclk_gate_disable(struct clk *clk) { - struct meson_vclk_gate_data *data = - (struct meson_vclk_gate_data *)(clk->data); + struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, - data->enable.width, 0); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 0); return 0; } static int meson_vclk_gate_is_enabled(struct clk *clk) { - struct meson_vclk_gate_data *data = - (struct meson_vclk_gate_data *)(clk->data); - return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, - data->enable.width); + struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); + return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width); } const struct clk_ops meson_vclk_gate_ops = { @@ -435,13 +390,10 @@ const struct clk_ops meson_vclk_gate_ops = { .is_enabled = meson_vclk_gate_is_enabled, }; -static unsigned long meson_vclk_div_recalc_rate(const struct clk *clk, - unsigned long prate) +static unsigned long meson_vclk_div_recalc_rate(const struct clk *clk, unsigned long prate) { - struct meson_vclk_div_data *data = - (struct meson_vclk_div_data *)(clk->data); - uint32_t div = regmap_read_bits(clk->base, data->div.reg_off, - data->div.shift, data->div.width); + struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); + uint32_t div = regmap_read_bits(clk->base, data->div.reg_off, data->div.shift, data->div.width); /* TODO: Need to verify the following cases */ if (data->flags & CLK_DIVIDER_ONE_BASED) { @@ -457,11 +409,9 @@ static unsigned long meson_vclk_div_recalc_rate(const struct clk *clk, return DIV_ROUND_UP_ULL((uint64_t)prate, div); } -static int meson_vclk_div_set_rate(const struct clk *clk, uint32_t rate, - uint32_t parent_rate) +static int meson_vclk_div_set_rate(const struct clk *clk, uint64_t rate, uint64_t parent_rate) { - struct meson_vclk_div_data *data = - (struct meson_vclk_div_data *)(clk->data); + struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); uint32_t div = DIV_ROUND_UP(parent_rate, rate); @@ -475,41 +425,32 @@ static int meson_vclk_div_set_rate(const struct clk *clk, uint32_t rate, } else { div -= 1; } - return regmap_update_bits(clk->base, data->div.reg_off, data->div.shift, - data->div.width, div); + return regmap_update_bits(clk->base, data->div.reg_off, data->div.shift, data->div.width, div); } static int meson_vclk_div_enable(struct clk *clk) { - struct meson_vclk_div_data *data = - (struct meson_vclk_div_data *)(clk->data); + struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, - data->reset.width, 0); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, - data->enable.width, 1); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 0); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 1); return 0; } static int meson_vclk_div_disable(struct clk *clk) { - struct meson_vclk_div_data *data = - (struct meson_vclk_div_data *)(clk->data); + struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, - data->enable.width, 0); - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, - data->reset.width, 1); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 0); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 1); return 0; } static int meson_vclk_div_is_enabled(struct clk *clk) { - struct meson_vclk_div_data *data = - (struct meson_vclk_div_data *)(clk->data); - return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, - data->enable.width); + struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); + return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width); } const struct clk_ops meson_vclk_div_ops = { @@ -521,11 +462,9 @@ const struct clk_ops meson_vclk_div_ops = { .is_enabled = meson_vclk_div_is_enabled, }; -static unsigned long meson_clk_cpu_dyndiv_recalc_rate(const struct clk *clk, - unsigned long prate) +static unsigned long meson_clk_cpu_dyndiv_recalc_rate(const struct clk *clk, unsigned long prate) { - struct meson_clk_cpu_dyndiv_data *data = - (struct meson_clk_cpu_dyndiv_data *)(clk->data); + struct meson_clk_cpu_dyndiv_data *data = (struct meson_clk_cpu_dyndiv_data *)(clk->data); uint32_t div = meson_parm_read(clk->base, data->div); div += 1; diff --git a/drivers/clk/meson/clk.c b/drivers/clk/meson/clk.c index 3f303882c..23ed849de 100644 --- a/drivers/clk/meson/clk.c +++ b/drivers/clk/meson/clk.c @@ -90,14 +90,14 @@ const struct clk *get_parent(const struct clk *clk) /* TODO: Should be just read from the structure, but need to update everytime when */ /* related clocks are modified */ -uint32_t clk_get_rate(const struct clk *clk, unsigned long *rate) +int clk_get_rate(const struct clk *clk, uint64_t *rate) { if (!clk) return CLK_UNKNOWN_TARGET; const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; - unsigned long parent_rate = 0; - uint32_t err = 0; + uint64_t parent_rate = 0; + int err = 0; const struct clk *parent_clk = get_parent(clk); if (parent_clk) { @@ -115,7 +115,7 @@ uint32_t clk_get_rate(const struct clk *clk, unsigned long *rate) return 0; } -uint32_t clk_enable(struct clk *clk) +int clk_enable(struct clk *clk) { if (!clk) return CLK_UNKNOWN_TARGET; @@ -127,7 +127,7 @@ uint32_t clk_enable(struct clk *clk) return CLK_INVALID_OP; } -uint32_t clk_disable(struct clk *clk) +int clk_disable(struct clk *clk) { if (!clk) return CLK_UNKNOWN_TARGET; @@ -139,7 +139,7 @@ uint32_t clk_disable(struct clk *clk) return CLK_INVALID_OP; } -uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) +int clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) { if (!clk) return CLK_UNKNOWN_TARGET; @@ -152,7 +152,7 @@ uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) const struct clk *pclk = get_parent(clk); uint64_t prate = 0; - uint32_t err = clk_get_rate(pclk, &prate); + int err = clk_get_rate(pclk, &prate); if (err) { LOG_DRIVER_ERR("Failed to get parent clock's rate\n"); return err; @@ -166,7 +166,7 @@ uint32_t clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) if (pclk->hw.init->ops->set_rate) { const struct clk *ppclk = get_parent(pclk); uint64_t pprate = 0; - uint32_t err = clk_get_rate(ppclk, &pprate); + int err = clk_get_rate(ppclk, &pprate); if (!err) { pclk->hw.init->ops->set_rate(pclk, prate, pprate); *rate = req_rate; @@ -184,7 +184,7 @@ int clk_msr_stat() unsigned long clk_freq; int i = 0; uint64_t rate = 0; - uint32_t err; + int err; const char *const *clk_msr_list = get_msr_clk_list(); @@ -192,8 +192,7 @@ int clk_msr_stat() for (i = 0; i < NUM_CLK_LIST; i++) { err = clk_get_rate(clk_list[i], &rate); if (err) { - LOG_DRIVER("Failed to get rate of %s: -%u\n", - clk_list[i]->hw.init->name, err); + LOG_DRIVER("Failed to get rate of %s: -%u\n", clk_list[i]->hw.init->name, err); } LOG_DRIVER("[%4d][%4luHz] %s\n", i, rate, clk_list[i]->hw.init->name); } @@ -234,10 +233,10 @@ void init(void) /* Set rate for the target clock */ if (clk_configs[i].frequency > 0) { uint64_t rate = 0; - uint32_t err = clk_set_rate(clk, clk_configs[i].frequency, &rate); + int err = clk_set_rate(clk, clk_configs[i].frequency, &rate); if (err) { - LOG_DRIVER_ERR("Failed to set rate [%d] for clk_id: %d\n", - clk_configs[i].frequency, clk_configs[i].clk_id); + LOG_DRIVER_ERR("Failed to set rate [%d] for clk_id: %d\n", clk_configs[i].frequency, + clk_configs[i].clk_id); } } } @@ -245,7 +244,7 @@ void init(void) microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) { - uint32_t err = 0; + int err = 0; uint32_t ret_num = 0; uint32_t argc = microkit_msginfo_get_count(msginfo); @@ -302,8 +301,8 @@ microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) break; } default: - LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", - microkit_msginfo_get_label(msginfo), ch); + LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), + ch); err = CLK_UNKNOWN_REQ; } return microkit_msginfo_new(err, ret_num); diff --git a/drivers/clk/meson/sm1-clk.c b/drivers/clk/meson/sm1-clk.c index 07924ecea..97069e87b 100644 --- a/drivers/clk/meson/sm1-clk.c +++ b/drivers/clk/meson/sm1-clk.c @@ -71,8 +71,7 @@ static struct clk g12a_fixed_pll_dco = { .num_parents = 1, }, }; -static CLK_DIV_RO(g12a_fixed_pll, HHI_FIX_PLL_CNTL0, 16, 2, - CLK_DIVIDER_POWER_OF_TWO, { &g12a_fixed_pll_dco }, 1, 0); +static CLK_DIV_RO(g12a_fixed_pll, HHI_FIX_PLL_CNTL0, 16, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_fixed_pll_dco }, 1, 0); static struct clk g12a_sys_pll_dco = { .data = &(struct meson_clk_pll_data){ .en = { @@ -114,18 +113,13 @@ static struct clk g12a_sys_pll_dco = { .flags = CLK_IS_CRITICAL, }, }; -static CLK_DIV(g12a_sys_pll, HHI_SYS_PLL_CNTL0, 16, 3, CLK_DIVIDER_POWER_OF_TWO, - { &g12a_sys_pll_dco }, 1, 0); -static CLK_GATE_RO(g12a_sys_pll_div16_en, HHI_SYS_CPU_CLK_CNTL1, 24, 0, - { &g12a_sys_pll }, 1, 0); -static CLK_FIXED_FACTOR(g12a_sys_pll_div16, 1, 16, 0, - { &g12a_sys_pll_div16_en }, 1, 0); +static CLK_DIV(g12a_sys_pll, HHI_SYS_PLL_CNTL0, 16, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_sys_pll_dco }, 1, 0); +static CLK_GATE_RO(g12a_sys_pll_div16_en, HHI_SYS_CPU_CLK_CNTL1, 24, 0, { &g12a_sys_pll }, 1, 0); +static CLK_FIXED_FACTOR(g12a_sys_pll_div16, 1, 16, 0, { &g12a_sys_pll_div16_en }, 1, 0); static CLK_FIXED_FACTOR(g12a_fclk_div2_div, 1, 2, 0, { &g12a_fixed_pll }, 1, 0); -static CLK_GATE(g12a_fclk_div2, HHI_FIX_PLL_CNTL1, 24, 0, - { &g12a_fclk_div2_div }, 1, 0); +static CLK_GATE(g12a_fclk_div2, HHI_FIX_PLL_CNTL1, 24, 0, { &g12a_fclk_div2_div }, 1, 0); static CLK_FIXED_FACTOR(g12a_fclk_div3_div, 1, 3, 0, { &g12a_fixed_pll }, 1, 0); -static CLK_GATE(g12a_fclk_div3, HHI_FIX_PLL_CNTL1, 20, 0, - { &g12a_fclk_div3_div }, 1, 0); +static CLK_GATE(g12a_fclk_div3, HHI_FIX_PLL_CNTL1, 20, 0, { &g12a_fclk_div3_div }, 1, 0); const struct clk_parent_data g12a_cpu_clk_premux0_parent_table[] = { { .name = "xtal", @@ -133,8 +127,8 @@ const struct clk_parent_data g12a_cpu_clk_premux0_parent_table[] = { { .clk = &g12a_fclk_div2 }, { .clk = &g12a_fclk_div3 }, }; -static CLK_MUX(g12a_cpu_clk_premux0, HHI_SYS_CPU_CLK_CNTL0, 0x3, 0, 0, - CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_premux0_parent_table, 3, 0); +static CLK_MUX(g12a_cpu_clk_premux0, HHI_SYS_CPU_CLK_CNTL0, 0x3, 0, 0, CLK_MUX_ROUND_CLOSEST, + g12a_cpu_clk_premux0_parent_table, 3, 0); const struct clk_parent_data g12a_cpu_clk_premux1_parent_table[] = { { .name = "xtal", @@ -142,8 +136,7 @@ const struct clk_parent_data g12a_cpu_clk_premux1_parent_table[] = { { .clk = &g12a_fclk_div2 }, { .clk = &g12a_fclk_div3 }, }; -static CLK_MUX(g12a_cpu_clk_premux1, HHI_SYS_CPU_CLK_CNTL0, 0x3, 16, 0, 0, - g12a_cpu_clk_premux1_parent_table, 3, 0); +static CLK_MUX(g12a_cpu_clk_premux1, HHI_SYS_CPU_CLK_CNTL0, 0x3, 16, 0, 0, g12a_cpu_clk_premux1_parent_table, 3, 0); static struct clk g12a_cpu_clk_mux0_div = { .data = &(struct meson_clk_cpu_dyndiv_data){ .div = { @@ -171,36 +164,30 @@ const struct clk_parent_data g12a_cpu_clk_postmux0_parent_table[] = { { .clk = &g12a_cpu_clk_premux0 }, { .clk = &g12a_cpu_clk_mux0_div }, }; -static CLK_MUX(g12a_cpu_clk_postmux0, HHI_SYS_CPU_CLK_CNTL0, 0x1, 2, 0, - CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_postmux0_parent_table, 2, 0); -static CLK_DIV_RO(g12a_cpu_clk_mux1_div, HHI_SYS_CPU_CLK_CNTL0, 20, 6, 0, - { &g12a_cpu_clk_premux1 }, 1, 0); +static CLK_MUX(g12a_cpu_clk_postmux0, HHI_SYS_CPU_CLK_CNTL0, 0x1, 2, 0, CLK_MUX_ROUND_CLOSEST, + g12a_cpu_clk_postmux0_parent_table, 2, 0); +static CLK_DIV_RO(g12a_cpu_clk_mux1_div, HHI_SYS_CPU_CLK_CNTL0, 20, 6, 0, { &g12a_cpu_clk_premux1 }, 1, 0); const struct clk_parent_data g12a_cpu_clk_postmux1_parent_table[] = { { .clk = &g12a_cpu_clk_premux1 }, { .clk = &g12a_cpu_clk_mux1_div }, }; -static CLK_MUX(g12a_cpu_clk_postmux1, HHI_SYS_CPU_CLK_CNTL0, 0x1, 18, 0, 0, - g12a_cpu_clk_postmux1_parent_table, 2, 0); +static CLK_MUX(g12a_cpu_clk_postmux1, HHI_SYS_CPU_CLK_CNTL0, 0x1, 18, 0, 0, g12a_cpu_clk_postmux1_parent_table, 2, 0); const struct clk_parent_data g12a_cpu_clk_dyn_parent_table[] = { { .clk = &g12a_cpu_clk_postmux0 }, { .clk = &g12a_cpu_clk_postmux1 }, }; -static CLK_MUX(g12a_cpu_clk_dyn, HHI_SYS_CPU_CLK_CNTL0, 0x1, 10, 0, - CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_dyn_parent_table, 2, 0); +static CLK_MUX(g12a_cpu_clk_dyn, HHI_SYS_CPU_CLK_CNTL0, 0x1, 10, 0, CLK_MUX_ROUND_CLOSEST, + g12a_cpu_clk_dyn_parent_table, 2, 0); const struct clk_parent_data g12a_cpu_clk_parent_table[] = { { .clk = &g12a_cpu_clk_dyn }, { .clk = &g12a_sys_pll }, }; -static CLK_MUX(g12a_cpu_clk, HHI_SYS_CPU_CLK_CNTL0, 0x1, 11, 0, - CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_parent_table, 2, 0); +static CLK_MUX(g12a_cpu_clk, HHI_SYS_CPU_CLK_CNTL0, 0x1, 11, 0, CLK_MUX_ROUND_CLOSEST, g12a_cpu_clk_parent_table, 2, 0); static const struct reg_sequence g12a_gp0_init_regs[] = { - { .reg = HHI_GP0_PLL_CNTL1, .def = 0x00000000 }, - { .reg = HHI_GP0_PLL_CNTL2, .def = 0x00000000 }, - { .reg = HHI_GP0_PLL_CNTL3, .def = 0x48681c00 }, - { .reg = HHI_GP0_PLL_CNTL4, .def = 0x33771290 }, - { .reg = HHI_GP0_PLL_CNTL5, .def = 0x39272000 }, - { .reg = HHI_GP0_PLL_CNTL6, .def = 0x56540000 }, + { .reg = HHI_GP0_PLL_CNTL1, .def = 0x00000000 }, { .reg = HHI_GP0_PLL_CNTL2, .def = 0x00000000 }, + { .reg = HHI_GP0_PLL_CNTL3, .def = 0x48681c00 }, { .reg = HHI_GP0_PLL_CNTL4, .def = 0x33771290 }, + { .reg = HHI_GP0_PLL_CNTL5, .def = 0x39272000 }, { .reg = HHI_GP0_PLL_CNTL6, .def = 0x56540000 }, }; static struct clk g12a_gp0_pll_dco = { .data = &(struct meson_clk_pll_data){ @@ -248,8 +235,7 @@ static struct clk g12a_gp0_pll_dco = { .num_parents = 1, }, }; -static CLK_DIV(g12a_gp0_pll, HHI_GP0_PLL_CNTL0, 16, 3, - (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), +static CLK_DIV(g12a_gp0_pll, HHI_GP0_PLL_CNTL0, 16, 3, (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), { &g12a_gp0_pll_dco }, 1, 0); static struct clk sm1_gp1_pll_dco = { .data = &(struct meson_clk_pll_data){ @@ -295,8 +281,7 @@ static struct clk sm1_gp1_pll_dco = { .flags = CLK_IS_CRITICAL, }, }; -static CLK_DIV_RO(sm1_gp1_pll, HHI_GP1_PLL_CNTL0, 16, 3, - (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), +static CLK_DIV_RO(sm1_gp1_pll, HHI_GP1_PLL_CNTL0, 16, 3, (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), { &sm1_gp1_pll_dco }, 1, 0); const struct clk_parent_data sm1_dsu_clk_premux0_parent_table[] = { @@ -307,8 +292,7 @@ const struct clk_parent_data sm1_dsu_clk_premux0_parent_table[] = { { .clk = &g12a_fclk_div3 }, { .clk = &sm1_gp1_pll }, }; -static CLK_MUX_RO(sm1_dsu_clk_premux0, HHI_SYS_CPU_CLK_CNTL5, 0x3, 0, 0, 0, - sm1_dsu_clk_premux0_parent_table, 4, 0); +static CLK_MUX_RO(sm1_dsu_clk_premux0, HHI_SYS_CPU_CLK_CNTL5, 0x3, 0, 0, 0, sm1_dsu_clk_premux0_parent_table, 4, 0); const struct clk_parent_data sm1_dsu_clk_premux1_parent_table[] = { { .name = "xtal", @@ -317,20 +301,16 @@ const struct clk_parent_data sm1_dsu_clk_premux1_parent_table[] = { { .clk = &g12a_fclk_div3 }, { .clk = &sm1_gp1_pll }, }; -static CLK_MUX_RO(sm1_dsu_clk_premux1, HHI_SYS_CPU_CLK_CNTL5, 0x3, 16, 0, 0, - sm1_dsu_clk_premux1_parent_table, 4, 0); -static CLK_DIV_RO(sm1_dsu_clk_mux0_div, HHI_SYS_CPU_CLK_CNTL5, 4, 6, 0, - { &sm1_dsu_clk_premux0 }, 1, 0); +static CLK_MUX_RO(sm1_dsu_clk_premux1, HHI_SYS_CPU_CLK_CNTL5, 0x3, 16, 0, 0, sm1_dsu_clk_premux1_parent_table, 4, 0); +static CLK_DIV_RO(sm1_dsu_clk_mux0_div, HHI_SYS_CPU_CLK_CNTL5, 4, 6, 0, { &sm1_dsu_clk_premux0 }, 1, 0); const struct clk_parent_data sm1_dsu_clk_postmux0_parent_table[] = { { .clk = &sm1_dsu_clk_premux0, }, { .clk = &sm1_dsu_clk_mux0_div }, }; -static CLK_MUX_RO(sm1_dsu_clk_postmux0, HHI_SYS_CPU_CLK_CNTL5, 0x1, 2, 0, 0, - sm1_dsu_clk_postmux0_parent_table, 2, 0); -static CLK_DIV_RO(sm1_dsu_clk_mux1_div, HHI_SYS_CPU_CLK_CNTL5, 20, 6, 0, - { &sm1_dsu_clk_premux1 }, 1, 0); +static CLK_MUX_RO(sm1_dsu_clk_postmux0, HHI_SYS_CPU_CLK_CNTL5, 0x1, 2, 0, 0, sm1_dsu_clk_postmux0_parent_table, 2, 0); +static CLK_DIV_RO(sm1_dsu_clk_mux1_div, HHI_SYS_CPU_CLK_CNTL5, 20, 6, 0, { &sm1_dsu_clk_premux1 }, 1, 0); const struct clk_parent_data sm1_dsu_clk_postmux1_parent_table[] = { { @@ -338,8 +318,7 @@ const struct clk_parent_data sm1_dsu_clk_postmux1_parent_table[] = { }, { .clk = &sm1_dsu_clk_mux1_div }, }; -static CLK_MUX_RO(sm1_dsu_clk_postmux1, HHI_SYS_CPU_CLK_CNTL5, 0x1, 18, 0, 0, - sm1_dsu_clk_postmux1_parent_table, 2, 0); +static CLK_MUX_RO(sm1_dsu_clk_postmux1, HHI_SYS_CPU_CLK_CNTL5, 0x1, 18, 0, 0, sm1_dsu_clk_postmux1_parent_table, 2, 0); const struct clk_parent_data sm1_dsu_clk_dyn_parent_table[] = { { .clk = &sm1_dsu_clk_premux0, @@ -348,8 +327,7 @@ const struct clk_parent_data sm1_dsu_clk_dyn_parent_table[] = { .clk = &sm1_dsu_clk_postmux1, }, }; -static CLK_MUX_RO(sm1_dsu_clk_dyn, HHI_SYS_CPU_CLK_CNTL5, 0x1, 10, 0, 0, - sm1_dsu_clk_dyn_parent_table, 2, 0); +static CLK_MUX_RO(sm1_dsu_clk_dyn, HHI_SYS_CPU_CLK_CNTL5, 0x1, 10, 0, 0, sm1_dsu_clk_dyn_parent_table, 2, 0); const struct clk_parent_data sm1_dsu_final_clk_parent_table[] = { { .clk = &sm1_dsu_clk_dyn, @@ -358,19 +336,15 @@ const struct clk_parent_data sm1_dsu_final_clk_parent_table[] = { .clk = &g12a_sys_pll, }, }; -static CLK_MUX_RO(sm1_dsu_final_clk, HHI_SYS_CPU_CLK_CNTL5, 0x1, 11, 0, 0, - sm1_dsu_final_clk_parent_table, 2, 0); +static CLK_MUX_RO(sm1_dsu_final_clk, HHI_SYS_CPU_CLK_CNTL5, 0x1, 11, 0, 0, sm1_dsu_final_clk_parent_table, 2, 0); const struct clk_parent_data sm1_cpu_clk_parent_table[] = { { .clk = &g12a_cpu_clk, }, }; -static CLK_MUX_RO(sm1_cpu1_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 24, 0, 0, - sm1_cpu_clk_parent_table, 1, 0); -static CLK_MUX_RO(sm1_cpu2_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 25, 0, 0, - sm1_cpu_clk_parent_table, 1, 0); -static CLK_MUX_RO(sm1_cpu3_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 26, 0, 0, - sm1_cpu_clk_parent_table, 1, 0); +static CLK_MUX_RO(sm1_cpu1_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 24, 0, 0, sm1_cpu_clk_parent_table, 1, 0); +static CLK_MUX_RO(sm1_cpu2_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 25, 0, 0, sm1_cpu_clk_parent_table, 1, 0); +static CLK_MUX_RO(sm1_cpu3_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 26, 0, 0, sm1_cpu_clk_parent_table, 1, 0); const struct clk_parent_data sm1_dsu_clk_parent_table[] = { { .clk = &g12a_cpu_clk, @@ -379,37 +353,23 @@ const struct clk_parent_data sm1_dsu_clk_parent_table[] = { .clk = &sm1_dsu_final_clk, }, }; -static CLK_MUX_RO(sm1_dsu_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 27, 0, 0, - sm1_dsu_clk_parent_table, 2, 0); -static CLK_GATE_RO(g12a_cpu_clk_div16_en, HHI_SYS_CPU_CLK_CNTL1, 1, 0, - { &g12a_cpu_clk }, 1, 0); -static CLK_FIXED_FACTOR(g12a_cpu_clk_div16, 1, 16, 0, - { &g12a_cpu_clk_div16_en }, 1, 0); -static CLK_DIV_RO(g12a_cpu_clk_apb_div, HHI_SYS_CPU_CLK_CNTL1, 3, 3, - CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); -static CLK_GATE_RO(g12a_cpu_clk_apb, HHI_SYS_CPU_CLK_CNTL1, 1, 0, - { &g12a_cpu_clk_apb_div }, 1, 0); -static CLK_DIV_RO(g12a_cpu_clk_atb_div, HHI_SYS_CPU_CLK_CNTL1, 6, 3, - CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); -static CLK_GATE_RO(g12a_cpu_clk_atb, HHI_SYS_CPU_CLK_CNTL1, 17, 0, - { &g12a_cpu_clk_atb_div }, 1, 0); -static CLK_DIV_RO(g12a_cpu_clk_axi_div, HHI_SYS_CPU_CLK_CNTL1, 9, 3, - CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); -static CLK_GATE_RO(g12a_cpu_clk_axi, HHI_SYS_CPU_CLK_CNTL1, 18, 0, - { &g12a_cpu_clk_axi_div }, 1, 0); +static CLK_MUX_RO(sm1_dsu_clk, HHI_SYS_CPU_CLK_CNTL6, 0x1, 27, 0, 0, sm1_dsu_clk_parent_table, 2, 0); +static CLK_GATE_RO(g12a_cpu_clk_div16_en, HHI_SYS_CPU_CLK_CNTL1, 1, 0, { &g12a_cpu_clk }, 1, 0); +static CLK_FIXED_FACTOR(g12a_cpu_clk_div16, 1, 16, 0, { &g12a_cpu_clk_div16_en }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_apb_div, HHI_SYS_CPU_CLK_CNTL1, 3, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); +static CLK_GATE_RO(g12a_cpu_clk_apb, HHI_SYS_CPU_CLK_CNTL1, 1, 0, { &g12a_cpu_clk_apb_div }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_atb_div, HHI_SYS_CPU_CLK_CNTL1, 6, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); +static CLK_GATE_RO(g12a_cpu_clk_atb, HHI_SYS_CPU_CLK_CNTL1, 17, 0, { &g12a_cpu_clk_atb_div }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_axi_div, HHI_SYS_CPU_CLK_CNTL1, 9, 3, CLK_DIVIDER_POWER_OF_TWO, { &g12a_cpu_clk }, 1, 0); +static CLK_GATE_RO(g12a_cpu_clk_axi, HHI_SYS_CPU_CLK_CNTL1, 18, 0, { &g12a_cpu_clk_axi_div }, 1, 0); /* TODO: special case, ignore its parent clk at the moment */ -static CLK_DIV_RO(g12a_cpu_clk_trace_div, HHI_SYS_CPU_CLK_CNTL1, 20, 3, - CLK_DIVIDER_POWER_OF_TWO, {}, 0, 0); -static CLK_GATE_RO(g12a_cpu_clk_trace, HHI_SYS_CPU_CLK_CNTL1, 23, 0, - { &g12a_cpu_clk_trace_div }, 1, 0); +static CLK_DIV_RO(g12a_cpu_clk_trace_div, HHI_SYS_CPU_CLK_CNTL1, 20, 3, CLK_DIVIDER_POWER_OF_TWO, {}, 0, 0); +static CLK_GATE_RO(g12a_cpu_clk_trace, HHI_SYS_CPU_CLK_CNTL1, 23, 0, { &g12a_cpu_clk_trace_div }, 1, 0); static const struct reg_sequence g12a_hifi_init_regs[] = { - { .reg = HHI_HIFI_PLL_CNTL1, .def = 0x00000000 }, - { .reg = HHI_HIFI_PLL_CNTL2, .def = 0x00000000 }, - { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x6a285c00 }, - { .reg = HHI_HIFI_PLL_CNTL4, .def = 0x65771290 }, - { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x39272000 }, - { .reg = HHI_HIFI_PLL_CNTL6, .def = 0x56540000 }, + { .reg = HHI_HIFI_PLL_CNTL1, .def = 0x00000000 }, { .reg = HHI_HIFI_PLL_CNTL2, .def = 0x00000000 }, + { .reg = HHI_HIFI_PLL_CNTL3, .def = 0x6a285c00 }, { .reg = HHI_HIFI_PLL_CNTL4, .def = 0x65771290 }, + { .reg = HHI_HIFI_PLL_CNTL5, .def = 0x39272000 }, { .reg = HHI_HIFI_PLL_CNTL6, .def = 0x56540000 }, }; static struct clk g12a_hifi_pll_dco = { @@ -459,8 +419,7 @@ static struct clk g12a_hifi_pll_dco = { .num_parents = 1, }, }; -static CLK_DIV(g12a_hifi_pll, HHI_HIFI_PLL_CNTL0, 16, 2, - (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), +static CLK_DIV(g12a_hifi_pll, HHI_HIFI_PLL_CNTL0, 16, 2, (CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_ROUND_CLOSEST), { &g12a_hifi_pll_dco }, 1, 0); /* @@ -532,12 +491,10 @@ static struct clk g12a_pcie_pll_dco = { .num_parents = 1, }, }; -static CLK_FIXED_FACTOR(g12a_pcie_pll_dco_div2, 1, 2, 0, { &g12a_pcie_pll_dco }, - 1, 0); +static CLK_FIXED_FACTOR(g12a_pcie_pll_dco_div2, 1, 2, 0, { &g12a_pcie_pll_dco }, 1, 0); static CLK_DIV(g12a_pcie_pll_od, HHI_PCIE_PLL_CNTL0, 16, 5, - CLK_DIVIDER_ROUND_CLOSEST | CLK_DIVIDER_ONE_BASED - | CLK_DIVIDER_ALLOW_ZERO, - { &g12a_pcie_pll_dco_div2 }, 1, 0); + CLK_DIVIDER_ROUND_CLOSEST | CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, { &g12a_pcie_pll_dco_div2 }, + 1, 0); static CLK_FIXED_FACTOR(g12a_pcie_pll, 1, 2, 0, { &g12a_pcie_pll_od }, 1, 0); static struct clk g12a_hdmi_pll_dco = { .data = &(struct meson_clk_pll_data){ @@ -586,37 +543,26 @@ static struct clk g12a_hdmi_pll_dco = { .flags = CLK_GET_RATE_NOCACHE, }, }; -static CLK_DIV_RO(g12a_hdmi_pll_od, HHI_HDMI_PLL_CNTL0, 16, 2, - CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_dco }, 1, 0); -static CLK_DIV_RO(g12a_hdmi_pll_od2, HHI_HDMI_PLL_CNTL0, 18, 2, - CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_od }, 1, 0); -static CLK_DIV_RO(g12a_hdmi_pll, HHI_HDMI_PLL_CNTL0, 20, 2, - CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_od2 }, 1, 0); +static CLK_DIV_RO(g12a_hdmi_pll_od, HHI_HDMI_PLL_CNTL0, 16, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_dco }, 1, 0); +static CLK_DIV_RO(g12a_hdmi_pll_od2, HHI_HDMI_PLL_CNTL0, 18, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_od }, 1, 0); +static CLK_DIV_RO(g12a_hdmi_pll, HHI_HDMI_PLL_CNTL0, 20, 2, CLK_DIVIDER_POWER_OF_TWO, { &g12a_hdmi_pll_od2 }, 1, 0); static CLK_FIXED_FACTOR(g12a_fclk_div4_div, 1, 4, 0, { &g12a_fixed_pll }, 1, 0); -static CLK_GATE(g12a_fclk_div4, HHI_FIX_PLL_CNTL1, 21, 0, - { &g12a_fclk_div4_div }, 1, 0); +static CLK_GATE(g12a_fclk_div4, HHI_FIX_PLL_CNTL1, 21, 0, { &g12a_fclk_div4_div }, 1, 0); static CLK_FIXED_FACTOR(g12a_fclk_div5_div, 1, 5, 0, { &g12a_fixed_pll }, 1, 0); -static CLK_GATE(g12a_fclk_div5, HHI_FIX_PLL_CNTL1, 22, 0, - { &g12a_fclk_div5_div }, 1, 0); +static CLK_GATE(g12a_fclk_div5, HHI_FIX_PLL_CNTL1, 22, 0, { &g12a_fclk_div5_div }, 1, 0); static CLK_FIXED_FACTOR(g12a_fclk_div7_div, 1, 7, 0, { &g12a_fixed_pll }, 1, 0); -static CLK_GATE(g12a_fclk_div7, HHI_FIX_PLL_CNTL1, 23, 0, - { &g12a_fclk_div7_div }, 1, 0); -static CLK_FIXED_FACTOR(g12a_fclk_div2p5_div, 1, 5, 0, { &g12a_fixed_pll_dco }, - 1, 0); -static CLK_GATE(g12a_fclk_div2p5, HHI_FIX_PLL_CNTL1, 25, 0, - { &g12a_fclk_div2p5_div }, 1, 0); -static CLK_FIXED_FACTOR(g12a_mpll_50m_div, 1, 80, 0, { &g12a_fixed_pll_dco }, 1, - 0); +static CLK_GATE(g12a_fclk_div7, HHI_FIX_PLL_CNTL1, 23, 0, { &g12a_fclk_div7_div }, 1, 0); +static CLK_FIXED_FACTOR(g12a_fclk_div2p5_div, 1, 5, 0, { &g12a_fixed_pll_dco }, 1, 0); +static CLK_GATE(g12a_fclk_div2p5, HHI_FIX_PLL_CNTL1, 25, 0, { &g12a_fclk_div2p5_div }, 1, 0); +static CLK_FIXED_FACTOR(g12a_mpll_50m_div, 1, 80, 0, { &g12a_fixed_pll_dco }, 1, 0); const static struct clk_parent_data g12a_mpll_50m_parent_table[] = { { .name = "xtal", }, { .clk = &g12a_mpll_50m_div }, }; -static CLK_MUX_RO(g12a_mpll_50m, HHI_FIX_PLL_CNTL3, 0x1, 5, 0, 0, - g12a_mpll_50m_parent_table, 2, 0); -static CLK_FIXED_FACTOR(g12a_mpll_prediv, 1, 2, 0, { &g12a_fixed_pll_dco }, 1, - 0); +static CLK_MUX_RO(g12a_mpll_50m, HHI_FIX_PLL_CNTL3, 0x1, 5, 0, 0, g12a_mpll_50m_parent_table, 2, 0); +static CLK_FIXED_FACTOR(g12a_mpll_prediv, 1, 2, 0, { &g12a_fixed_pll_dco }, 1, 0); static const struct reg_sequence g12a_mpll0_init_regs[] = { { .reg = HHI_MPLL_CNTL2, .def = 0x40000033 }, @@ -787,13 +733,10 @@ static const struct clk_parent_data clk81_parent_data[] = { { .clk = &g12a_fclk_div3 }, { .clk = &g12a_fclk_div5 }, }; -static CLK_MUX_RO(g12a_mpeg_clk_sel, HHI_MPEG_CLK_CNTL, 0x7, 12, - mux_table_clk81, 0, clk81_parent_data, +static CLK_MUX_RO(g12a_mpeg_clk_sel, HHI_MPEG_CLK_CNTL, 0x7, 12, mux_table_clk81, 0, clk81_parent_data, ARRAY_SIZE(clk81_parent_data), 0); -static CLK_DIV(g12a_mpeg_clk_div, HHI_MPEG_CLK_CNTL, 0, 7, 0, - { &g12a_mpeg_clk_sel }, 1, 0); -static CLK_GATE(g12a_clk81, HHI_MPEG_CLK_CNTL, 7, 0, { &g12a_mpeg_clk_div }, 1, - 0); +static CLK_DIV(g12a_mpeg_clk_div, HHI_MPEG_CLK_CNTL, 0, 7, 0, { &g12a_mpeg_clk_sel }, 1, 0); +static CLK_GATE(g12a_clk81, HHI_MPEG_CLK_CNTL, 7, 0, { &g12a_mpeg_clk_div }, 1, 0); static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = { { .name = "xtal", @@ -803,24 +746,18 @@ static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = { { .clk = &g12a_fclk_div5 }, { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(g12a_sd_emmc_a_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 9, 0, 0, - g12a_sd_emmc_clk0_parent_data, 0, CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_sd_emmc_a_clk0_div, HHI_SD_EMMC_CLK_CNTL, 0, 7, 0, - { &g12a_sd_emmc_a_clk0_sel }, 1, 0); -static CLK_GATE(g12a_sd_emmc_a_clk0, HHI_SD_EMMC_CLK_CNTL, 7, 0, - { &g12a_sd_emmc_a_clk0_div }, 1, 0); -static CLK_MUX(g12a_sd_emmc_b_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 25, 0, 0, - g12a_sd_emmc_clk0_parent_data, 0, CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_sd_emmc_b_clk0_div, HHI_SD_EMMC_CLK_CNTL, 16, 7, 0, - { &g12a_sd_emmc_b_clk0_sel }, 1, 0); -static CLK_GATE(g12a_sd_emmc_b_clk0, HHI_SD_EMMC_CLK_CNTL, 23, 0, - { &g12a_sd_emmc_b_clk0_div }, 1, 0); -static CLK_MUX(g12a_sd_emmc_c_clk0_sel, HHI_NAND_CLK_CNTL, 0x7, 9, 0, 0, - g12a_sd_emmc_clk0_parent_data, 0, CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_sd_emmc_c_clk0_div, HHI_NAND_CLK_CNTL, 0, 7, 0, - { &g12a_sd_emmc_c_clk0_sel }, 1, 0); -static CLK_GATE(g12a_sd_emmc_c_clk0, HHI_NAND_CLK_CNTL, 7, 0, - { &g12a_sd_emmc_c_clk0_div }, 1, 0); +static CLK_MUX(g12a_sd_emmc_a_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 9, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, + CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_sd_emmc_a_clk0_div, HHI_SD_EMMC_CLK_CNTL, 0, 7, 0, { &g12a_sd_emmc_a_clk0_sel }, 1, 0); +static CLK_GATE(g12a_sd_emmc_a_clk0, HHI_SD_EMMC_CLK_CNTL, 7, 0, { &g12a_sd_emmc_a_clk0_div }, 1, 0); +static CLK_MUX(g12a_sd_emmc_b_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 25, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, + CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_sd_emmc_b_clk0_div, HHI_SD_EMMC_CLK_CNTL, 16, 7, 0, { &g12a_sd_emmc_b_clk0_sel }, 1, 0); +static CLK_GATE(g12a_sd_emmc_b_clk0, HHI_SD_EMMC_CLK_CNTL, 23, 0, { &g12a_sd_emmc_b_clk0_div }, 1, 0); +static CLK_MUX(g12a_sd_emmc_c_clk0_sel, HHI_NAND_CLK_CNTL, 0x7, 9, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, + CLK_SET_RATE_PARENT); +static CLK_DIV(g12a_sd_emmc_c_clk0_div, HHI_NAND_CLK_CNTL, 0, 7, 0, { &g12a_sd_emmc_c_clk0_sel }, 1, 0); +static CLK_GATE(g12a_sd_emmc_c_clk0, HHI_NAND_CLK_CNTL, 7, 0, { &g12a_sd_emmc_c_clk0_div }, 1, 0); static struct clk g12a_vid_pll_div = { .data = &(struct meson_vid_pll_div_data){ .val = { @@ -851,11 +788,9 @@ static const struct clk_parent_data g12a_vid_pll_parent_table[] = { }, }; -static CLK_MUX(g12a_vid_pll_sel, HHI_VID_PLL_CLK_DIV, 0x1, 18, 0, 0, - g12a_vid_pll_parent_table, 0, +static CLK_MUX(g12a_vid_pll_sel, HHI_VID_PLL_CLK_DIV, 0x1, 18, 0, 0, g12a_vid_pll_parent_table, 0, CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_GATE(g12a_vid_pll, HHI_VID_PLL_CLK_DIV, 19, 0, { &g12a_vid_pll_sel }, - 1, 0); +static CLK_GATE(g12a_vid_pll, HHI_VID_PLL_CLK_DIV, 19, 0, { &g12a_vid_pll_sel }, 1, 0); const static struct clk_parent_data g12a_vpu_sel_parent_table[] = { { .clk = &g12a_fclk_div3, @@ -882,22 +817,17 @@ const static struct clk_parent_data g12a_vpu_sel_parent_table[] = { .clk = &g12a_gp0_pll, }, }; -static CLK_MUX(g12a_vpu_0_sel, HHI_VPU_CLK_CNTL, 0x7, 9, 0, 0, - g12a_vpu_sel_parent_table, 0, CLK_SET_RATE_NO_REPARENT); -static CLK_DIV(g12a_vpu_0_div, HHI_VPU_CLK_CNTL, 0, 7, 0, { &g12a_vpu_0_sel }, - 1, 0); +static CLK_MUX(g12a_vpu_0_sel, HHI_VPU_CLK_CNTL, 0x7, 9, 0, 0, g12a_vpu_sel_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vpu_0_div, HHI_VPU_CLK_CNTL, 0, 7, 0, { &g12a_vpu_0_sel }, 1, 0); static CLK_GATE(g12a_vpu_0, HHI_VPU_CLK_CNTL, 8, 0, { &g12a_vpu_0_div }, 1, 0); -static CLK_MUX(g12a_vpu_1_sel, HHI_VPU_CLK_CNTL, 0x7, 25, 0, 0, - g12a_vpu_sel_parent_table, 0, CLK_SET_RATE_NO_REPARENT); -static CLK_DIV(g12a_vpu_1_div, HHI_VPU_CLK_CNTL, 16, 7, 0, { &g12a_vpu_1_sel }, - 1, 0); +static CLK_MUX(g12a_vpu_1_sel, HHI_VPU_CLK_CNTL, 0x7, 25, 0, 0, g12a_vpu_sel_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vpu_1_div, HHI_VPU_CLK_CNTL, 16, 7, 0, { &g12a_vpu_1_sel }, 1, 0); static CLK_GATE(g12a_vpu_1, HHI_VPU_CLK_CNTL, 24, 0, { &g12a_vpu_1_div }, 1, 0); const struct clk_parent_data g12a_vpu_parent_table[] = { { .clk = &g12a_vpu_0 }, { .clk = &g12a_vpu_1 }, }; -static CLK_MUX(g12a_vpu, HHI_VPU_CLK_CNTL, 1, 31, 0, 0, g12a_vpu_parent_table, - 2, 0); +static CLK_MUX(g12a_vpu, HHI_VPU_CLK_CNTL, 1, 31, 0, 0, g12a_vpu_parent_table, 2, 0); static const struct clk_parent_data g12a_vdec_parent_table[] = { { .clk = &g12a_fclk_div2p5, @@ -922,27 +852,19 @@ static const struct clk_parent_data g12a_vdec_parent_table[] = { }, }; -static CLK_MUX(g12a_vdec_1_sel, HHI_VDEC_CLK_CNTL, 0x7, 9, 0, - CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, +static CLK_MUX(g12a_vdec_1_sel, HHI_VDEC_CLK_CNTL, 0x7, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_vdec_1_div, HHI_VDEC_CLK_CNTL, 0, 7, - CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_1_sel }, 1, 0); -static CLK_GATE(g12a_vdec_1, HHI_VDEC_CLK_CNTL, 8, 0, { &g12a_vdec_1_div }, 1, - 0); -static CLK_MUX(g12a_vdec_hevcf_sel, HHI_VDEC2_CLK_CNTL, 0x7, 9, 0, - CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, +static CLK_DIV(g12a_vdec_1_div, HHI_VDEC_CLK_CNTL, 0, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_1_sel }, 1, 0); +static CLK_GATE(g12a_vdec_1, HHI_VDEC_CLK_CNTL, 8, 0, { &g12a_vdec_1_div }, 1, 0); +static CLK_MUX(g12a_vdec_hevcf_sel, HHI_VDEC2_CLK_CNTL, 0x7, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_vdec_hevcf_div, HHI_VDEC2_CLK_CNTL, 0, 7, - CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevcf_sel }, 1, 0); -static CLK_GATE(g12a_vdec_hevcf, HHI_VDEC2_CLK_CNTL, 8, 0, - { &g12a_vdec_hevcf_div }, 1, 0); -static CLK_MUX(g12a_vdec_hevc_sel, HHI_VDEC2_CLK_CNTL, 0x7, 25, 0, - CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, +static CLK_DIV(g12a_vdec_hevcf_div, HHI_VDEC2_CLK_CNTL, 0, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevcf_sel }, 1, + 0); +static CLK_GATE(g12a_vdec_hevcf, HHI_VDEC2_CLK_CNTL, 8, 0, { &g12a_vdec_hevcf_div }, 1, 0); +static CLK_MUX(g12a_vdec_hevc_sel, HHI_VDEC2_CLK_CNTL, 0x7, 25, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_vdec_hevc_div, HHI_VDEC2_CLK_CNTL, 16, 7, - CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevc_sel }, 1, 0); -static CLK_GATE(g12a_vdec_hevc, HHI_VDEC2_CLK_CNTL, 24, 0, - { &g12a_vdec_hevc_div }, 1, 0); +static CLK_DIV(g12a_vdec_hevc_div, HHI_VDEC2_CLK_CNTL, 16, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevc_sel }, 1, 0); +static CLK_GATE(g12a_vdec_hevc, HHI_VDEC2_CLK_CNTL, 24, 0, { &g12a_vdec_hevc_div }, 1, 0); static const struct clk_parent_data g12a_vapb_parent_table[] = { { .clk = &g12a_fclk_div4, @@ -969,24 +891,17 @@ static const struct clk_parent_data g12a_vapb_parent_table[] = { .clk = &g12a_fclk_div2p5, }, }; -static CLK_MUX(g12a_vapb_0_sel, HHI_VAPBCLK_CNTL, 0x3, 9, 0, 0, - g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); -static CLK_DIV(g12a_vapb_0_div, HHI_VAPBCLK_CNTL, 0, 7, 0, { &g12a_vapb_0_sel }, - 1, 0); -static CLK_GATE(g12a_vapb_0, HHI_VAPBCLK_CNTL, 8, 0, { &g12a_vapb_0_div }, 1, - 0); -static CLK_MUX(g12a_vapb_1_sel, HHI_VAPBCLK_CNTL, 0x3, 25, 0, 0, - g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); -static CLK_DIV(g12a_vapb_1_div, HHI_VAPBCLK_CNTL, 16, 7, 0, - { &g12a_vapb_1_sel }, 1, 0); -static CLK_GATE(g12a_vapb_1, HHI_VAPBCLK_CNTL, 24, 0, { &g12a_vapb_1_div }, 1, - 0); +static CLK_MUX(g12a_vapb_0_sel, HHI_VAPBCLK_CNTL, 0x3, 9, 0, 0, g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vapb_0_div, HHI_VAPBCLK_CNTL, 0, 7, 0, { &g12a_vapb_0_sel }, 1, 0); +static CLK_GATE(g12a_vapb_0, HHI_VAPBCLK_CNTL, 8, 0, { &g12a_vapb_0_div }, 1, 0); +static CLK_MUX(g12a_vapb_1_sel, HHI_VAPBCLK_CNTL, 0x3, 25, 0, 0, g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_DIV(g12a_vapb_1_div, HHI_VAPBCLK_CNTL, 16, 7, 0, { &g12a_vapb_1_sel }, 1, 0); +static CLK_GATE(g12a_vapb_1, HHI_VAPBCLK_CNTL, 24, 0, { &g12a_vapb_1_div }, 1, 0); const struct clk_parent_data g12a_vapb_sel_parent_table[] = { { .clk = &g12a_vapb_0 }, { .clk = &g12a_vapb_1 }, }; -static CLK_MUX(g12a_vapb_sel, HHI_VAPBCLK_CNTL, 1, 31, 0, 0, - g12a_vapb_sel_parent_table, 2, 0); +static CLK_MUX(g12a_vapb_sel, HHI_VAPBCLK_CNTL, 1, 31, 0, 0, g12a_vapb_sel_parent_table, 2, 0); static CLK_GATE(g12a_vapb, HHI_VAPBCLK_CNTL, 30, 0, { &g12a_vapb_sel }, 1, 0); static const struct clk_parent_data g12a_vclk_parent_table[] = { { @@ -1014,17 +929,12 @@ static const struct clk_parent_data g12a_vclk_parent_table[] = { .clk = &g12a_fclk_div7, }, }; -static CLK_MUX(g12a_vclk_sel, HHI_VID_CLK_CNTL, 0x7, 16, 0, 0, - g12a_vclk_parent_table, 0, +static CLK_MUX(g12a_vclk_sel, HHI_VID_CLK_CNTL, 0x7, 16, 0, 0, g12a_vclk_parent_table, 0, CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_MUX(g12a_vclk2_sel, HHI_VIID_CLK_CNTL, 0x7, 16, 0, 0, - g12a_vclk_parent_table, 0, CLK_SET_RATE_NO_REPARENT); -static CLK_GATE(g12a_vclk_input, HHI_VID_CLK_DIV, 16, 0, { &g12a_vclk_sel }, 1, - 0); -static CLK_GATE(g12a_vclk2_input, HHI_VIID_CLK_DIV, 16, 0, { &g12a_vclk2_sel }, - 1, 0); -static CLK_DIV(g12a_vclk_div, HHI_VID_CLK_DIV, 0, 8, 0, { &g12a_vclk_input }, 1, - 0); +static CLK_MUX(g12a_vclk2_sel, HHI_VIID_CLK_CNTL, 0x7, 16, 0, 0, g12a_vclk_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_GATE(g12a_vclk_input, HHI_VID_CLK_DIV, 16, 0, { &g12a_vclk_sel }, 1, 0); +static CLK_GATE(g12a_vclk2_input, HHI_VIID_CLK_DIV, 16, 0, { &g12a_vclk2_sel }, 1, 0); +static CLK_DIV(g12a_vclk_div, HHI_VID_CLK_DIV, 0, 8, 0, { &g12a_vclk_input }, 1, 0); static struct clk g12a_vclk2_div = { .data = &(struct meson_vclk_div_data){ .div = { @@ -1077,37 +987,23 @@ static struct clk g12a_vclk2 = { }, }; static CLK_GATE(g12a_vclk_div1, HHI_VID_CLK_CNTL, 0, 0, { &g12a_vclk }, 1, 0); -static CLK_GATE(g12a_vclk_div2_en, HHI_VID_CLK_CNTL, 1, 0, { &g12a_vclk }, 1, - 0); -static CLK_GATE(g12a_vclk_div4_en, HHI_VID_CLK_CNTL, 2, 0, { &g12a_vclk }, 1, - 0); -static CLK_GATE(g12a_vclk_div6_en, HHI_VID_CLK_CNTL, 3, 0, { &g12a_vclk }, 1, - 0); -static CLK_GATE(g12a_vclk_div12_en, HHI_VID_CLK_CNTL, 4, 0, { &g12a_vclk }, 1, - 0); -static CLK_GATE(g12a_vclk2_div1, HHI_VIID_CLK_CNTL, 0, 0, { &g12a_vclk2 }, 1, - 0); -static CLK_GATE(g12a_vclk2_div2_en, HHI_VIID_CLK_CNTL, 1, 0, { &g12a_vclk2 }, 1, - 0); -static CLK_GATE(g12a_vclk2_div4_en, HHI_VIID_CLK_CNTL, 2, 0, { &g12a_vclk2 }, 1, - 0); -static CLK_GATE(g12a_vclk2_div6_en, HHI_VIID_CLK_CNTL, 3, 0, { &g12a_vclk2 }, 1, - 0); -static CLK_GATE(g12a_vclk2_div12_en, HHI_VIID_CLK_CNTL, 4, 0, { &g12a_vclk2 }, - 1, 0); +static CLK_GATE(g12a_vclk_div2_en, HHI_VID_CLK_CNTL, 1, 0, { &g12a_vclk }, 1, 0); +static CLK_GATE(g12a_vclk_div4_en, HHI_VID_CLK_CNTL, 2, 0, { &g12a_vclk }, 1, 0); +static CLK_GATE(g12a_vclk_div6_en, HHI_VID_CLK_CNTL, 3, 0, { &g12a_vclk }, 1, 0); +static CLK_GATE(g12a_vclk_div12_en, HHI_VID_CLK_CNTL, 4, 0, { &g12a_vclk }, 1, 0); +static CLK_GATE(g12a_vclk2_div1, HHI_VIID_CLK_CNTL, 0, 0, { &g12a_vclk2 }, 1, 0); +static CLK_GATE(g12a_vclk2_div2_en, HHI_VIID_CLK_CNTL, 1, 0, { &g12a_vclk2 }, 1, 0); +static CLK_GATE(g12a_vclk2_div4_en, HHI_VIID_CLK_CNTL, 2, 0, { &g12a_vclk2 }, 1, 0); +static CLK_GATE(g12a_vclk2_div6_en, HHI_VIID_CLK_CNTL, 3, 0, { &g12a_vclk2 }, 1, 0); +static CLK_GATE(g12a_vclk2_div12_en, HHI_VIID_CLK_CNTL, 4, 0, { &g12a_vclk2 }, 1, 0); static CLK_FIXED_FACTOR(g12a_vclk_div2, 1, 2, 0, { &g12a_vclk_div2_en }, 1, 0); static CLK_FIXED_FACTOR(g12a_vclk_div4, 1, 4, 0, { &g12a_vclk_div4_en }, 1, 0); static CLK_FIXED_FACTOR(g12a_vclk_div6, 1, 6, 0, { &g12a_vclk_div6_en }, 1, 0); -static CLK_FIXED_FACTOR(g12a_vclk_div12, 1, 12, 0, { &g12a_vclk_div12_en }, 1, - 0); -static CLK_FIXED_FACTOR(g12a_vclk2_div2, 1, 2, 0, { &g12a_vclk2_div2_en }, 1, - 0); -static CLK_FIXED_FACTOR(g12a_vclk2_div4, 1, 4, 0, { &g12a_vclk2_div4_en }, 1, - 0); -static CLK_FIXED_FACTOR(g12a_vclk2_div6, 1, 6, 0, { &g12a_vclk2_div6_en }, 1, - 0); -static CLK_FIXED_FACTOR(g12a_vclk2_div12, 1, 12, 0, { &g12a_vclk2_div12_en }, 1, - 0); +static CLK_FIXED_FACTOR(g12a_vclk_div12, 1, 12, 0, { &g12a_vclk_div12_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div2, 1, 2, 0, { &g12a_vclk2_div2_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div4, 1, 4, 0, { &g12a_vclk2_div4_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div6, 1, 6, 0, { &g12a_vclk2_div6_en }, 1, 0); +static CLK_FIXED_FACTOR(g12a_vclk2_div12, 1, 12, 0, { &g12a_vclk2_div12_en }, 1, 0); static uint32_t mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; static const struct clk_parent_data g12a_cts_parent_table[] = { { @@ -1141,18 +1037,14 @@ static const struct clk_parent_data g12a_cts_parent_table[] = { .clk = &g12a_vclk2_div12, }, }; -static CLK_MUX(g12a_cts_enci_sel, HHI_VID_CLK_DIV, 0xf, 28, mux_table_cts_sel, - 0, g12a_cts_parent_table, ARRAY_SIZE(g12a_cts_parent_table), - CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_MUX(g12a_cts_encp_sel, HHI_VID_CLK_DIV, 0xf, 20, mux_table_cts_sel, - 0, g12a_cts_parent_table, ARRAY_SIZE(g12a_cts_parent_table), - CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_MUX(g12a_cts_encl_sel, HHI_VIID_CLK_DIV, 0xf, 12, mux_table_cts_sel, - 0, g12a_cts_parent_table, ARRAY_SIZE(g12a_cts_parent_table), - CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT); -static CLK_MUX(g12a_cts_vdac_sel, HHI_VIID_CLK_DIV, 0xf, 28, mux_table_cts_sel, - 0, g12a_cts_parent_table, ARRAY_SIZE(g12a_cts_parent_table), - CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_MUX(g12a_cts_enci_sel, HHI_VID_CLK_DIV, 0xf, 28, mux_table_cts_sel, 0, g12a_cts_parent_table, + ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_MUX(g12a_cts_encp_sel, HHI_VID_CLK_DIV, 0xf, 20, mux_table_cts_sel, 0, g12a_cts_parent_table, + ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_MUX(g12a_cts_encl_sel, HHI_VIID_CLK_DIV, 0xf, 12, mux_table_cts_sel, 0, g12a_cts_parent_table, + ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT); +static CLK_MUX(g12a_cts_vdac_sel, HHI_VIID_CLK_DIV, 0xf, 28, mux_table_cts_sel, 0, g12a_cts_parent_table, + ARRAY_SIZE(g12a_cts_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); static uint32_t mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 }; static const struct clk_parent_data g12a_cts_hdmi_tx_parent_table[] = { { @@ -1186,20 +1078,13 @@ static const struct clk_parent_data g12a_cts_hdmi_tx_parent_table[] = { .clk = &g12a_vclk2_div12, }, }; -static CLK_MUX(g12a_hdmi_tx_sel, HHI_HDMI_CLK_CNTL, 0xf, 16, - mux_table_hdmi_tx_sel, 0, g12a_cts_hdmi_tx_parent_table, - ARRAY_SIZE(g12a_cts_hdmi_tx_parent_table), - CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_GATE(g12a_cts_enci, HHI_VID_CLK_CNTL2, 0, 0, { &g12a_cts_enci_sel }, - 1, 0); -static CLK_GATE(g12a_cts_encp, HHI_VID_CLK_CNTL2, 2, 0, { &g12a_cts_encp_sel }, - 1, 0); -static CLK_GATE(g12a_cts_encl, HHI_VID_CLK_CNTL2, 3, 0, { &g12a_cts_encl_sel }, - 1, 0); -static CLK_GATE(g12a_cts_vdac, HHI_VID_CLK_CNTL2, 4, 0, { &g12a_cts_vdac_sel }, - 1, 0); -static CLK_GATE(g12a_hdmi_tx, HHI_VID_CLK_CNTL2, 5, 0, { &g12a_hdmi_tx_sel }, 1, - 0); +static CLK_MUX(g12a_hdmi_tx_sel, HHI_HDMI_CLK_CNTL, 0xf, 16, mux_table_hdmi_tx_sel, 0, g12a_cts_hdmi_tx_parent_table, + ARRAY_SIZE(g12a_cts_hdmi_tx_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_GATE(g12a_cts_enci, HHI_VID_CLK_CNTL2, 0, 0, { &g12a_cts_enci_sel }, 1, 0); +static CLK_GATE(g12a_cts_encp, HHI_VID_CLK_CNTL2, 2, 0, { &g12a_cts_encp_sel }, 1, 0); +static CLK_GATE(g12a_cts_encl, HHI_VID_CLK_CNTL2, 3, 0, { &g12a_cts_encl_sel }, 1, 0); +static CLK_GATE(g12a_cts_vdac, HHI_VID_CLK_CNTL2, 4, 0, { &g12a_cts_vdac_sel }, 1, 0); +static CLK_GATE(g12a_hdmi_tx, HHI_VID_CLK_CNTL2, 5, 0, { &g12a_hdmi_tx_sel }, 1, 0); static const struct clk_parent_data g12a_mipi_dsi_pxclk_parent_table[] = { { .clk = &g12a_vid_pll, @@ -1226,14 +1111,11 @@ static const struct clk_parent_data g12a_mipi_dsi_pxclk_parent_table[] = { .clk = &g12a_fclk_div7, }, }; -static CLK_MUX(g12a_mipi_dsi_pxclk_sel, HHI_MIPIDSI_PHY_CLK_CNTL, 0x7, 12, 0, - CLK_MUX_ROUND_CLOSEST, g12a_mipi_dsi_pxclk_parent_table, - ARRAY_SIZE(g12a_mipi_dsi_pxclk_parent_table), +static CLK_MUX(g12a_mipi_dsi_pxclk_sel, HHI_MIPIDSI_PHY_CLK_CNTL, 0x7, 12, 0, CLK_MUX_ROUND_CLOSEST, + g12a_mipi_dsi_pxclk_parent_table, ARRAY_SIZE(g12a_mipi_dsi_pxclk_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT); -static CLK_DIV(g12a_mipi_dsi_pxclk_div, HHI_MIPIDSI_PHY_CLK_CNTL, 0, 7, 0, - { &g12a_mipi_dsi_pxclk_sel }, 1, 0); -static CLK_GATE(g12a_mipi_dsi_pxclk, HHI_MIPIDSI_PHY_CLK_CNTL, 8, 0, - { &g12a_mipi_dsi_pxclk_div }, 1, 0); +static CLK_DIV(g12a_mipi_dsi_pxclk_div, HHI_MIPIDSI_PHY_CLK_CNTL, 0, 7, 0, { &g12a_mipi_dsi_pxclk_sel }, 1, 0); +static CLK_GATE(g12a_mipi_dsi_pxclk, HHI_MIPIDSI_PHY_CLK_CNTL, 8, 0, { &g12a_mipi_dsi_pxclk_div }, 1, 0); static const struct clk_parent_data g12a_hdmi_parent_table[] = { { .name = "xtal", @@ -1242,12 +1124,9 @@ static const struct clk_parent_data g12a_hdmi_parent_table[] = { { .clk = &g12a_fclk_div3 }, { .clk = &g12a_fclk_div5 }, }; -static CLK_MUX(g12a_hdmi_sel, HHI_HDMI_CLK_CNTL, 0x3, 9, 0, - CLK_MUX_ROUND_CLOSEST, g12a_hdmi_parent_table, - ARRAY_SIZE(g12a_hdmi_parent_table), - CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_DIV(g12a_hdmi_div, HHI_HDMI_CLK_CNTL, 0, 7, 0, { &g12a_hdmi_sel }, 1, - 0); +static CLK_MUX(g12a_hdmi_sel, HHI_HDMI_CLK_CNTL, 0x3, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_hdmi_parent_table, + ARRAY_SIZE(g12a_hdmi_parent_table), CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); +static CLK_DIV(g12a_hdmi_div, HHI_HDMI_CLK_CNTL, 0, 7, 0, { &g12a_hdmi_sel }, 1, 0); static CLK_GATE(g12a_hdmi, HHI_HDMI_CLK_CNTL, 8, 0, { &g12a_hdmi_div }, 1, 0); static const struct clk_parent_data g12a_mali_0_1_parent_data[] = { { @@ -1261,18 +1140,12 @@ static const struct clk_parent_data g12a_mali_0_1_parent_data[] = { { .clk = &g12a_fclk_div5 }, { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(g12a_mali_0_sel, HHI_MALI_CLK_CNTL, 0x7, 9, 0, 0, - g12a_mali_0_1_parent_data, 8, 0); -static CLK_DIV(g12a_mali_0_div, HHI_MALI_CLK_CNTL, 0, 7, 0, - { &g12a_mali_0_sel }, 1, 0); -static CLK_GATE(g12a_mali_0, HHI_MALI_CLK_CNTL, 8, 0, { &g12a_mali_0_div }, 1, - 0); -static CLK_MUX(g12a_mali_1_sel, HHI_MALI_CLK_CNTL, 0x7, 25, 0, 0, - g12a_mali_0_1_parent_data, 8, 0); -static CLK_DIV(g12a_mali_1_div, HHI_MALI_CLK_CNTL, 16, 7, 0, - { &g12a_mali_1_sel }, 1, 0); -static CLK_GATE(g12a_mali_1, HHI_MALI_CLK_CNTL, 24, 0, { &g12a_mali_1_div }, 1, - 0); +static CLK_MUX(g12a_mali_0_sel, HHI_MALI_CLK_CNTL, 0x7, 9, 0, 0, g12a_mali_0_1_parent_data, 8, 0); +static CLK_DIV(g12a_mali_0_div, HHI_MALI_CLK_CNTL, 0, 7, 0, { &g12a_mali_0_sel }, 1, 0); +static CLK_GATE(g12a_mali_0, HHI_MALI_CLK_CNTL, 8, 0, { &g12a_mali_0_div }, 1, 0); +static CLK_MUX(g12a_mali_1_sel, HHI_MALI_CLK_CNTL, 0x7, 25, 0, 0, g12a_mali_0_1_parent_data, 8, 0); +static CLK_DIV(g12a_mali_1_div, HHI_MALI_CLK_CNTL, 16, 7, 0, { &g12a_mali_1_sel }, 1, 0); +static CLK_GATE(g12a_mali_1, HHI_MALI_CLK_CNTL, 24, 0, { &g12a_mali_1_div }, 1, 0); static const struct clk_parent_data g12a_mali_parent_table[] = { { .clk = &g12a_mali_0, @@ -1281,10 +1154,8 @@ static const struct clk_parent_data g12a_mali_parent_table[] = { .clk = &g12a_mali_1, }, }; -static CLK_MUX(g12a_mali, HHI_MALI_CLK_CNTL, 1, 31, 0, 0, - g12a_mali_parent_table, 2, CLK_SET_RATE_PARENT); -static CLK_DIV_RO(g12a_ts_div, HHI_TS_CLK_CNTL, 0, 8, 0, { &g12a_ts_div }, 1, - 0); +static CLK_MUX(g12a_mali, HHI_MALI_CLK_CNTL, 1, 31, 0, 0, g12a_mali_parent_table, 2, CLK_SET_RATE_PARENT); +static CLK_DIV_RO(g12a_ts_div, HHI_TS_CLK_CNTL, 0, 8, 0, { &g12a_ts_div }, 1, 0); static CLK_GATE(g12a_ts, HHI_TS_CLK_CNTL, 8, 0, { &g12a_ts_div }, 1, 0); static const struct clk_parent_data spicc_sclk_parent_data[] = { { @@ -1297,18 +1168,12 @@ static const struct clk_parent_data spicc_sclk_parent_data[] = { { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(g12a_spicc0_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 7, 0, 0, - spicc_sclk_parent_data, 0, 0); -static CLK_DIV(g12a_spicc0_sclk_div, HHI_SPICC_CLK_CNTL, 0, 6, 0, - { &g12a_spicc0_sclk_sel }, 1, 0); -static CLK_GATE(g12a_spicc0_sclk, HHI_SPICC_CLK_CNTL, 6, 0, - { &g12a_spicc0_sclk_div }, 1, 0); -static CLK_MUX(g12a_spicc1_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 23, 0, 0, - spicc_sclk_parent_data, 0, 0); -static CLK_DIV(g12a_spicc1_sclk_div, HHI_SPICC_CLK_CNTL, 16, 6, 0, - { &g12a_spicc1_sclk_sel }, 1, 0); -static CLK_GATE(g12a_spicc1_sclk, HHI_SPICC_CLK_CNTL, 22, 0, - { &g12a_spicc1_sclk_div }, 1, 0); +static CLK_MUX(g12a_spicc0_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 7, 0, 0, spicc_sclk_parent_data, 0, 0); +static CLK_DIV(g12a_spicc0_sclk_div, HHI_SPICC_CLK_CNTL, 0, 6, 0, { &g12a_spicc0_sclk_sel }, 1, 0); +static CLK_GATE(g12a_spicc0_sclk, HHI_SPICC_CLK_CNTL, 6, 0, { &g12a_spicc0_sclk_div }, 1, 0); +static CLK_MUX(g12a_spicc1_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 23, 0, 0, spicc_sclk_parent_data, 0, 0); +static CLK_DIV(g12a_spicc1_sclk_div, HHI_SPICC_CLK_CNTL, 16, 6, 0, { &g12a_spicc1_sclk_sel }, 1, 0); +static CLK_GATE(g12a_spicc1_sclk, HHI_SPICC_CLK_CNTL, 22, 0, { &g12a_spicc1_sclk_div }, 1, 0); static const struct clk_parent_data nna_clk_parent_data[] = { { .name = "xtal", @@ -1333,18 +1198,12 @@ static const struct clk_parent_data nna_clk_parent_data[] = { }, { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(sm1_nna_axi_clk_sel, HHI_NNA_CLK_CNTL, 7, 9, 0, 0, - nna_clk_parent_data, 0, 0); -static CLK_DIV(sm1_nna_axi_clk_div, HHI_NNA_CLK_CNTL, 0, 7, 0, - { &sm1_nna_axi_clk_sel }, 1, 0); -static CLK_GATE(sm1_nna_axi_clk, HHI_NNA_CLK_CNTL, 8, 0, - { &sm1_nna_axi_clk_div }, 1, 0); -static CLK_MUX(sm1_nna_core_clk_sel, HHI_NNA_CLK_CNTL, 7, 25, 0, 0, - nna_clk_parent_data, 0, 0); -static CLK_DIV(sm1_nna_core_clk_div, HHI_NNA_CLK_CNTL, 16, 7, 0, - { &sm1_nna_core_clk_sel }, 1, 0); -static CLK_GATE(sm1_nna_core_clk, HHI_NNA_CLK_CNTL, 24, 0, - { &sm1_nna_core_clk_div }, 1, 0); +static CLK_MUX(sm1_nna_axi_clk_sel, HHI_NNA_CLK_CNTL, 7, 9, 0, 0, nna_clk_parent_data, 0, 0); +static CLK_DIV(sm1_nna_axi_clk_div, HHI_NNA_CLK_CNTL, 0, 7, 0, { &sm1_nna_axi_clk_sel }, 1, 0); +static CLK_GATE(sm1_nna_axi_clk, HHI_NNA_CLK_CNTL, 8, 0, { &sm1_nna_axi_clk_div }, 1, 0); +static CLK_MUX(sm1_nna_core_clk_sel, HHI_NNA_CLK_CNTL, 7, 25, 0, 0, nna_clk_parent_data, 0, 0); +static CLK_DIV(sm1_nna_core_clk_div, HHI_NNA_CLK_CNTL, 16, 7, 0, { &sm1_nna_core_clk_sel }, 1, 0); +static CLK_GATE(sm1_nna_core_clk, HHI_NNA_CLK_CNTL, 24, 0, { &sm1_nna_core_clk_div }, 1, 0); /* Everything Else (EE) domain gates */ static MESON_CLK81_GATE(g12a_ddr, HHI_GCLK_MPEG0, 0); diff --git a/examples/clk/client.c b/examples/clk/client.c index e9d66036f..0fef03106 100644 --- a/examples/clk/client.c +++ b/examples/clk/client.c @@ -19,27 +19,69 @@ void init(void) #ifdef TEST_BOARD_odroidc4 sddf_dprintf("Test board: odroidc4\n"); - uint32_t ret = sddf_clk_enable(CLK_DRIVER_CH, 10); - sddf_dprintf("ret_val: %x\n", ret); + /** + * CLKID_CLK81 = 10 + * CLKID_I2C = 24 + * CLKID_CPU_CLK = 187 + * + * see `sddf/drivers/clk/meson/include/g12a-bindings.h` for more clock indices. + * + **/ + uint32_t clk_id_to_enable = 10; + int ret = sddf_clk_enable(CLK_DRIVER_CH, clk_id_to_enable); + if (ret) { + sddf_dprintf("Failed to enable clock %u: err - %d\n", clk_id_to_enable, ret); + } else { + sddf_dprintf("Successfully enabled clock %u\n", clk_id_to_enable); + } - ret = sddf_clk_disable(CLK_DRIVER_CH, 24); - sddf_dprintf("ret_val: %x\n", ret); + uint32_t clk_id_to_disable = 24; + ret = sddf_clk_disable(CLK_DRIVER_CH, clk_id_to_disable); + if (ret) { + sddf_dprintf("Failed to disable clock %u: err - %d\n", clk_id_to_enable, ret); + } else { + sddf_dprintf("Successfully disabled clock %u\n", clk_id_to_enable); + } uint64_t rate = 0; - ret = sddf_clk_get_rate(CLK_DRIVER_CH, 10, &rate); - sddf_dprintf("err: %d rate: %lu\n", ret, rate); + uint32_t clk_id_to_set_rate = 10; + ret = sddf_clk_get_rate(CLK_DRIVER_CH, clk_id_to_set_rate, &rate); + if (ret) { + sddf_dprintf("Failed to get the rate of clock %u: err - %d\n", clk_id_to_set_rate, ret); + } else { + sddf_dprintf("The rate of clock %u: %lu\n", clk_id_to_set_rate, rate); + } - ret = sddf_clk_set_rate(CLK_DRIVER_CH, 10, 150000000, &rate); - sddf_dprintf("err: %d, rate: %lu\n", ret, rate); + ret = sddf_clk_set_rate(CLK_DRIVER_CH, clk_id_to_set_rate, 150000000, &rate); + if (ret) { + sddf_dprintf("Failed to set the rate of clock %u: err - %d\n", clk_id_to_set_rate, ret); + } else { + sddf_dprintf("Set the rate of clock %u to %lu\n", ret, rate); + } - ret = sddf_clk_get_rate(CLK_DRIVER_CH, 187, &rate); - sddf_dprintf("err: %d, rate: %lu\n", ret, rate); + uint32_t clk_id_to_get_rate = 187; + ret = sddf_clk_get_rate(CLK_DRIVER_CH, clk_id_to_get_rate, &rate); + if (ret) { + sddf_dprintf("Failed to get the rate of clock %u: err - %d\n", clk_id_to_get_rate, ret); + } else { + sddf_dprintf("The rate of clock %u: %lu\n", clk_id_to_get_rate, rate); + } #elif TEST_BOARD_maaxboard sddf_dprintf("Test board: maaxboard\n"); - uint32_t ret = sddf_clk_enable(CLK_DRIVER_CH, 196); - sddf_dprintf("ret_val: %x\n", ret); + /** + * IMX8MQ_CLK_SAI1_ROOT = 196 + * + * see `sddf/drivers/clk/imx/include/imx8mq-bindings.h` for more clock indices. + * */ + uint32_t clk_id_to_enable = 196; + int ret = sddf_clk_enable(CLK_DRIVER_CH, clk_id_to_enable); + if (ret) { + sddf_dprintf("Failed to enable clock %u: err - %d\n", clk_id_to_enable, ret); + } else { + sddf_dprintf("Successfully enabled clock %u\n", clk_id_to_enable); + } #else sddf_dprintf("No tests for the target board\n", ret); diff --git a/include/sddf/clk/client.h b/include/sddf/clk/client.h index d5dc3e937..21c1f3336 100644 --- a/include/sddf/clk/client.h +++ b/include/sddf/clk/client.h @@ -16,15 +16,14 @@ * @param channel of clock driver. * @param identifier of target clock. */ -static inline uint32_t sddf_clk_enable(microkit_channel channel, - uint32_t clk_id) +static inline int sddf_clk_enable(microkit_channel channel, uint32_t clk_id) { microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_ENABLE, 1); microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); msginfo = microkit_ppcall(channel, msginfo); - return (uint32_t)microkit_msginfo_get_label(msginfo); + return (int)microkit_msginfo_get_label(msginfo); } /** @@ -33,15 +32,14 @@ static inline uint32_t sddf_clk_enable(microkit_channel channel, * @param channel of clock driver. * @param identifier of target clock. */ -static inline uint32_t sddf_clk_disable(microkit_channel channel, - uint32_t clk_id) +static inline int sddf_clk_disable(microkit_channel channel, uint32_t clk_id) { microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_DISABLE, 1); microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); msginfo = microkit_ppcall(channel, msginfo); - return (uint32_t)microkit_msginfo_get_label(msginfo); + return (int)microkit_msginfo_get_label(msginfo); } /** @@ -51,8 +49,7 @@ static inline uint32_t sddf_clk_disable(microkit_channel channel, * @param identifier of target clock. * @param pointer to result variable. */ -static inline uint32_t sddf_clk_get_rate(microkit_channel channel, - uint32_t clk_id, uint64_t *rate) +static inline int sddf_clk_get_rate(microkit_channel channel, uint32_t clk_id, uint64_t *rate) { microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_GET_RATE, 1); microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); @@ -60,7 +57,7 @@ static inline uint32_t sddf_clk_get_rate(microkit_channel channel, msginfo = microkit_ppcall(channel, msginfo); *rate = microkit_mr_get(0); - return (uint32_t)microkit_msginfo_get_label(msginfo); + return (int)microkit_msginfo_get_label(msginfo); } /** @@ -71,9 +68,7 @@ static inline uint32_t sddf_clk_get_rate(microkit_channel channel, * @param target clock frequency. * @param pointer to result variable. */ -static inline uint32_t sddf_clk_set_rate(microkit_channel channel, - uint32_t clk_id, uint64_t req_rate, - uint64_t *rate) +static inline int sddf_clk_set_rate(microkit_channel channel, uint32_t clk_id, uint64_t req_rate, uint64_t *rate) { microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_SET_RATE, 2); microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); @@ -82,5 +77,5 @@ static inline uint32_t sddf_clk_set_rate(microkit_channel channel, msginfo = microkit_ppcall(channel, msginfo); *rate = microkit_mr_get(0); - return (uint32_t)microkit_msginfo_get_label(msginfo); + return (int)microkit_msginfo_get_label(msginfo); } From d8a400c9ed3b2b7f88a067c00068ad6e56615579 Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Mon, 18 Nov 2024 17:05:19 +1100 Subject: [PATCH 08/11] clk: combine regmap_* and regmap_mux_* operations Abstract a set of regmap_* operations by combining mux-specific ones and ordinary ones Signed-off-by: Terry Bai --- drivers/clk/clk-operations.c | 17 +++---- drivers/clk/clk-operations.h | 30 ++----------- drivers/clk/{utils.h => clk_utils.h} | 0 drivers/clk/imx/clk-imx.c | 60 ++++++++++++------------- drivers/clk/imx/clk-imx8mq.c | 2 +- drivers/clk/meson/clk-measure.c | 2 +- drivers/clk/meson/clk-meson.c | 67 ++++++++++++++-------------- drivers/clk/meson/sm1-clk.c | 2 +- 8 files changed, 79 insertions(+), 101 deletions(-) rename drivers/clk/{utils.h => clk_utils.h} (100%) diff --git a/drivers/clk/clk-operations.c b/drivers/clk/clk-operations.c index 885138b5e..423a3376c 100644 --- a/drivers/clk/clk-operations.c +++ b/drivers/clk/clk-operations.c @@ -82,19 +82,20 @@ #include #include #include +#include static inline int clk_gate_enable(struct clk *clk) { struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); - return regmap_update_bits(clk->base, data->offset, data->bit_idx, 1, 1); + return regmap_update_bits(clk->base, data->offset, data->bit_idx, MASK(1), 1); } static inline int clk_gate_disable(struct clk *clk) { struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); - regmap_update_bits(clk->base, data->offset, data->bit_idx, 1, 0); + regmap_update_bits(clk->base, data->offset, data->bit_idx, MASK(1), 0); return 0; } @@ -109,7 +110,7 @@ static inline int clk_gate_is_enabled(struct clk *clk) /* val &= BIT(gate->bit_idx); */ /* return val ? 1 : 0; */ - return regmap_read_bits(clk->base, data->offset, data->bit_idx, 1); + return regmap_read_bits(clk->base, data->offset, data->bit_idx, MASK(1)); } const struct clk_ops clk_gate_ops = { @@ -126,7 +127,7 @@ static inline uint64_t clk_div_recalc_rate(const struct clk *clk, uint64_t prate { struct clk_div_data *data = (struct clk_div_data *)(clk->data); - uint32_t div = regmap_read_bits(clk->base, data->offset, data->shift, data->width); + uint32_t div = regmap_read_bits(clk->base, data->offset, data->shift, MASK(data->width)); /* TODO: Need to verify the following cases */ if (data->flags & CLK_DIVIDER_ONE_BASED) { @@ -157,7 +158,7 @@ static inline int clk_div_set_rate(const struct clk *clk, uint64_t rate, uint64_ } else { div -= 1; } - return regmap_update_bits(clk->base, data->offset, data->shift, data->width, div); + return regmap_update_bits(clk->base, data->offset, data->shift, MASK(data->width), div); } const struct clk_ops clk_divider_ops = { @@ -176,7 +177,7 @@ static inline uint8_t clk_mux_get_parent(const struct clk *clk) { struct clk_mux_data *data = (struct clk_mux_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->shift, data->mask); + uint32_t val = regmap_read_bits(clk->base, data->offset, data->shift, data->mask); if (data->table) { int i; @@ -208,9 +209,9 @@ static inline int clk_mux_set_parent(struct clk *clk, uint8_t index) if (data->table) { uint32_t val = data->table[index]; - regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, val); + regmap_update_bits(clk->base, data->offset, data->shift, data->mask, val); } - regmap_mux_update_bits(clk->base, data->offset, data->shift, data->mask, index); + regmap_update_bits(clk->base, data->offset, data->shift, data->mask, index); return 0; } diff --git a/drivers/clk/clk-operations.h b/drivers/clk/clk-operations.h index 2dc02a301..cec380404 100644 --- a/drivers/clk/clk-operations.h +++ b/drivers/clk/clk-operations.h @@ -6,7 +6,7 @@ #pragma once #include -#include +#include #define CLK_INCORRECT_ARGS -1 #define CLK_INVALID_OP -2 @@ -22,31 +22,7 @@ static inline int reg_write(uint64_t base, uint32_t offset, uint32_t val) return 0; } -static inline int regmap_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width, uint32_t val) -{ - volatile uint32_t *clk_reg = ((void *)base + offset); - uint32_t reg_val = *clk_reg; - - reg_val &= ~(MASK(width) << shift); - reg_val |= ((MASK(width) & val) << shift); - - *clk_reg = reg_val; - - return 0; -} - -static inline uint32_t regmap_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint8_t width) -{ - volatile uint32_t *clk_reg = ((void *)base + offset); - uint32_t reg_val = *clk_reg; - - reg_val >>= shift; - reg_val &= MASK(width); - - return reg_val; -} - -static inline int regmap_mux_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask, uint32_t val) +static inline int regmap_update_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask, uint32_t val) { volatile uint32_t *clk_reg = ((void *)base + offset); uint32_t reg_val = *clk_reg; @@ -59,7 +35,7 @@ static inline int regmap_mux_update_bits(uint64_t base, uint32_t offset, uint8_t return 0; } -static inline uint32_t regmap_mux_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask) +static inline uint32_t regmap_read_bits(uint64_t base, uint32_t offset, uint8_t shift, uint32_t mask) { volatile uint32_t *clk_reg = ((void *)base + offset); uint32_t reg_val = *clk_reg; diff --git a/drivers/clk/utils.h b/drivers/clk/clk_utils.h similarity index 100% rename from drivers/clk/utils.h rename to drivers/clk/clk_utils.h diff --git a/drivers/clk/imx/clk-imx.c b/drivers/clk/imx/clk-imx.c index e188cf72d..ae0a1891e 100644 --- a/drivers/clk/imx/clk-imx.c +++ b/drivers/clk/imx/clk-imx.c @@ -32,7 +32,7 @@ * cfaaa7d010d1fc58f9717fcc8591201e741d2d49/drivers/clk/imx/clk-composite-8m.c */ -#include +#include #include #include @@ -42,21 +42,21 @@ static int clk_gate2_enable(struct clk *clk) { struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); - return regmap_update_bits(clk->base, data->offset, data->bit_idx, 2, 0x3); + return regmap_update_bits(clk->base, data->offset, data->bit_idx, MASK(2), 0x3); } static int clk_gate2_disable(struct clk *clk) { struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); - return regmap_update_bits(clk->base, data->offset, data->bit_idx, 2, 0); + return regmap_update_bits(clk->base, data->offset, data->bit_idx, MASK(2), 0); } static int clk_gate2_is_enabled(struct clk *clk) { struct clk_gate_data *data = (struct clk_gate_data *)(clk->data); - if (regmap_read_bits(clk->base, data->offset, data->bit_idx, 2) == 0x3) + if (regmap_read_bits(clk->base, data->offset, data->bit_idx, MASK(2)) == 0x3) return 1; return 0; @@ -78,14 +78,14 @@ static uint64_t clk_pll_recalc_rate(const struct clk *clk, uint64_t prate) uint64_t rate; /* Output Divider value is (n + 1) * 2 */ - uint32_t output_div_val = regmap_read_bits(clk->base, data->offset, 0, 5); + uint32_t output_div_val = regmap_read_bits(clk->base, data->offset, 0, MASK(5)); output_div_val = (output_div_val + 1) * 2; /* Valid Frac Divider value is 1 to 2^24 */ - uint32_t frac_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 7, 24); + uint32_t frac_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 7, MASK(24)); /* Valid Int Divider value is 1 to 32 */ - uint32_t int_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 0, 7); + uint32_t int_div_val = regmap_read_bits(clk->base, data->offset + 0x4, 0, MASK(7)); temp_rate *= prate; temp_rate *= frac_div_val; @@ -114,15 +114,15 @@ static uint64_t clk_sscg_pll_recalc_rate(const struct clk *clk, uint64_t prate) struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); uint64_t temp_rate = prate; - uint32_t divr1 = regmap_read_bits(clk->base, data->offset + 0x8, 25, 3); - uint32_t divr2 = regmap_read_bits(clk->base, data->offset + 0x8, 19, 6); - uint32_t divf1 = regmap_read_bits(clk->base, data->offset + 0x8, 13, 6); - uint32_t divf2 = regmap_read_bits(clk->base, data->offset + 0x8, 7, 6); - uint32_t divq = regmap_read_bits(clk->base, data->offset + 0x8, 1, 6); + uint32_t divr1 = regmap_read_bits(clk->base, data->offset + 0x8, 25, MASK(3)); + uint32_t divr2 = regmap_read_bits(clk->base, data->offset + 0x8, 19, MASK(6)); + uint32_t divf1 = regmap_read_bits(clk->base, data->offset + 0x8, 13, MASK(6)); + uint32_t divf2 = regmap_read_bits(clk->base, data->offset + 0x8, 7, MASK(6)); + uint32_t divq = regmap_read_bits(clk->base, data->offset + 0x8, 1, MASK(6)); - if (regmap_read_bits(clk->base, data->offset, 4, 1)) { + if (regmap_read_bits(clk->base, data->offset, 4, MASK(1))) { temp_rate = prate; - } else if (regmap_read_bits(clk->base, data->offset, 5, 1)) { + } else if (regmap_read_bits(clk->base, data->offset, 5, MASK(1))) { temp_rate *= divf2; do_div(temp_rate, (divr2 + 1) * (divq + 1)); } else { @@ -139,9 +139,9 @@ static uint8_t clk_sscg_pll_get_parent(const struct clk *clk) struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); uint8_t ret = 0; - if (regmap_read_bits(clk->base, data->offset, 4, 1)) { + if (regmap_read_bits(clk->base, data->offset, 4, MASK(1))) { ret = data->bypass2; - } else if (regmap_read_bits(clk->base, data->offset, 5, 1)) { + } else if (regmap_read_bits(clk->base, data->offset, 5, MASK(1))) { ret = data->bypass1; } @@ -173,7 +173,7 @@ static uint64_t imx8m_clk_core_slice_recalc_rate(const struct clk *clk, uint64_t { struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); - uint32_t div_val = regmap_read_bits(clk->base, data->offset, data->div_shift, data->div_width); + uint32_t div_val = regmap_read_bits(clk->base, data->offset, data->div_shift, MASK(data->div_width)); /* Divider value is n+1 */ return DIV_ROUND_UP_ULL((uint64_t)prate, div_val + 1); } @@ -183,7 +183,7 @@ static uint8_t imx8m_clk_core_slice_get_parent(const struct clk *clk) struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); + uint32_t val = regmap_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); if (val >= num_parents) return -1; @@ -199,8 +199,8 @@ static int imx8m_clk_core_slice_set_parent(struct clk *clk, uint8_t index) * write twice to make sure non-target interface * SEL_A/B point the same clk input. */ - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); return 0; } @@ -218,11 +218,11 @@ static uint64_t imx8m_clk_common_slice_recalc_rate(const struct clk *clk, uint64 { struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); - uint32_t prediv_val = regmap_read_bits(clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); + uint32_t prediv_val = regmap_read_bits(clk->base, data->offset, data->prevdiv_shift, MASK(data->prevdiv_width)); /* Divider value is n+1 */ uint64_t prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, prediv_val + 1); - uint32_t postdiv_val = regmap_read_bits(clk->base, data->offset, data->postdiv_shift, data->postdiv_width); + uint32_t postdiv_val = regmap_read_bits(clk->base, data->offset, data->postdiv_shift, MASK(data->postdiv_width)); /* Divider value is n+1 */ return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); } @@ -232,7 +232,7 @@ static uint8_t imx8m_clk_common_slice_get_parent(const struct clk *clk) struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); + uint32_t val = regmap_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); if (val >= num_parents) return -1; @@ -248,8 +248,8 @@ static int imx8m_clk_common_slice_set_parent(struct clk *clk, uint8_t index) * write twice to make sure non-target interface * SEL_A/B point the same clk input. */ - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); return 0; } @@ -267,11 +267,11 @@ static uint64_t imx8m_clk_bus_slice_recalc_rate(const struct clk *clk, uint64_t { struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); - uint32_t prediv_val = regmap_read_bits(clk->base, data->offset, data->prevdiv_shift, data->prevdiv_width); + uint32_t prediv_val = regmap_read_bits(clk->base, data->offset, data->prevdiv_shift, MASK(data->prevdiv_width)); /* Divider value is n+1 */ uint64_t prediv_rate = DIV_ROUND_UP_ULL((uint64_t)prate, prediv_val + 1); - uint32_t postdiv_val = regmap_read_bits(clk->base, data->offset, data->postdiv_shift, data->postdiv_width); + uint32_t postdiv_val = regmap_read_bits(clk->base, data->offset, data->postdiv_shift, MASK(data->postdiv_width)); /* Divider value is n+1 */ return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); } @@ -281,7 +281,7 @@ static uint8_t imx8m_clk_bus_slice_get_parent(const struct clk *clk) struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; - uint32_t val = regmap_mux_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); + uint32_t val = regmap_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); if (val >= num_parents) return -1; @@ -297,8 +297,8 @@ static int imx8m_clk_bus_slice_set_parent(struct clk *clk, uint8_t index) * write twice to make sure non-target interface * SEL_A/B point the same clk input. */ - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); - regmap_mux_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); + regmap_update_bits(clk->base, data->offset, data->mux_shift, data->mux_mask, index); return 0; } diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index 0bf1d4cd6..fc484147e 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -5,7 +5,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/clk/meson/clk-measure.c b/drivers/clk/meson/clk-measure.c index a58d4fbb1..3869944ed 100644 --- a/drivers/clk/meson/clk-measure.c +++ b/drivers/clk/meson/clk-measure.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include diff --git a/drivers/clk/meson/clk-meson.c b/drivers/clk/meson/clk-meson.c index 3cfa687fd..374b6e73d 100644 --- a/drivers/clk/meson/clk-meson.c +++ b/drivers/clk/meson/clk-meson.c @@ -70,7 +70,7 @@ * Author: Neil Armstrong */ -#include +#include #include #include #include @@ -80,7 +80,7 @@ static inline uint32_t meson_parm_read(uint64_t base, struct parm parm) { - return regmap_read_bits(base, parm.reg_off, parm.shift, parm.width); + return regmap_read_bits(base, parm.reg_off, parm.shift, MASK(parm.width)); } /* TODO: Replace this doggy delay() with a standard interface */ @@ -113,12 +113,12 @@ static void meson_clk_pll_init(struct clk *clk) if (data->init_count) { /* Set the reset bit */ - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, MASK(data->rst.width), 1); regmap_multi_reg_write(clk->base, data->init_regs, data->init_count); /* Clear the reset bit */ - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 0); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, MASK(data->rst.width), 0); } } @@ -127,13 +127,14 @@ static unsigned long meson_clk_pll_recalc_rate(const struct clk *clk, unsigned l struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); uint32_t n, m, frac; - n = regmap_read_bits(clk->base, data->n.reg_off, data->n.shift, data->n.width); + n = regmap_read_bits(clk->base, data->n.reg_off, data->n.shift, MASK(data->n.width)); if (n == 0) return 0; - m = regmap_read_bits(clk->base, data->m.reg_off, data->m.shift, data->m.width); + m = regmap_read_bits(clk->base, data->m.reg_off, data->m.shift, MASK(data->m.width)); - frac = data->frac.width ? regmap_read_bits(clk->base, data->frac.reg_off, data->frac.shift, data->frac.width) : 0; + frac = data->frac.width ? regmap_read_bits(clk->base, data->frac.reg_off, data->frac.shift, MASK(data->frac.width)) + : 0; uint64_t rate = (uint64_t)parent_rate * m; @@ -167,11 +168,11 @@ static int meson_clk_pll_enable(struct clk *clk) if (meson_clk_pll_is_enabled(clk)) return 0; - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); - regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, data->en.width, 1); - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, MASK(data->rst.width), 1); + regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, MASK(data->en.width), 1); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, MASK(data->rst.width), 1); - regmap_update_bits(clk->base, data->current_en.reg_off, data->current_en.shift, data->current_en.width, 1); + regmap_update_bits(clk->base, data->current_en.reg_off, data->current_en.shift, MASK(data->current_en.width), 1); return 0; } @@ -179,8 +180,8 @@ static int meson_clk_pll_disable(struct clk *clk) { struct meson_clk_pll_data *data = (struct meson_clk_pll_data *)(clk->data); - regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, data->rst.width, 1); - regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, data->en.width, 0); + regmap_update_bits(clk->base, data->rst.reg_off, data->rst.shift, MASK(data->rst.width), 1); + regmap_update_bits(clk->base, data->en.reg_off, data->en.shift, MASK(data->en.width), 0); return 0; } @@ -206,8 +207,8 @@ static uint64_t mpll_recalc_rate(const struct clk *clk, uint64_t prate) struct meson_clk_mpll_data *data = (struct meson_clk_mpll_data *)(clk->data); uint32_t sdm, n2; - sdm = regmap_read_bits(clk->base, data->sdm.reg_off, data->sdm.shift, data->sdm.width); - n2 = regmap_read_bits(clk->base, data->n2.reg_off, data->n2.shift, data->n2.width); + sdm = regmap_read_bits(clk->base, data->sdm.reg_off, data->sdm.shift, MASK(data->sdm.width)); + n2 = regmap_read_bits(clk->base, data->n2.reg_off, data->n2.shift, MASK(data->n2.width)); uint32_t divisor = (SDM_DEN * n2) + sdm; if (n2 < N2_MIN) @@ -245,8 +246,8 @@ static int mpll_set_rate(const struct clk *clk, uint64_t rate, uint64_t parent_r n2 = div; } - regmap_update_bits(clk->base, data->sdm.reg_off, data->sdm.shift, data->sdm.width, sdm); - regmap_update_bits(clk->base, data->n2.reg_off, data->n2.shift, data->n2.width, n2); + regmap_update_bits(clk->base, data->sdm.reg_off, data->sdm.shift, MASK(data->sdm.width), sdm); + regmap_update_bits(clk->base, data->n2.reg_off, data->n2.shift, MASK(data->n2.width), n2); return 0; } @@ -259,11 +260,11 @@ static void mpll_init(struct clk *clk) } /* Enable the fractional part */ - regmap_update_bits(clk->base, data->sdm_en.reg_off, data->sdm_en.shift, data->sdm_en.width, 1); + regmap_update_bits(clk->base, data->sdm_en.reg_off, data->sdm_en.shift, MASK(data->sdm_en.width), 1); /* Set spread spectrum if possible */ uint32_t ss = data->flags & CLK_MESON_MPLL_SPREAD_SPECTRUM ? 1 : 0; - regmap_update_bits(clk->base, data->ssen.reg_off, data->ssen.shift, data->ssen.width, ss); + regmap_update_bits(clk->base, data->ssen.reg_off, data->ssen.shift, MASK(data->ssen.width), ss); } const struct clk_ops meson_clk_mpll_ops = { @@ -337,8 +338,8 @@ static unsigned long meson_vid_pll_div_recalc_rate(const struct clk *clk, unsign const struct vid_pll_div *div; uint32_t shift_val, shift_sel; - shift_val = regmap_read_bits(clk->base, data->val.reg_off, data->val.shift, data->val.width); - shift_sel = regmap_read_bits(clk->base, data->sel.reg_off, data->sel.shift, data->sel.width); + shift_val = regmap_read_bits(clk->base, data->val.reg_off, data->val.shift, MASK(data->val.width)); + shift_sel = regmap_read_bits(clk->base, data->sel.reg_off, data->sel.shift, MASK(data->sel.width)); int i; @@ -361,11 +362,11 @@ static int meson_vclk_gate_enable(struct clk *clk) { struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 1); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, MASK(data->enable.width), 1); /* Do a reset pulse */ - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 1); - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 0); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, MASK(data->reset.width), 1); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, MASK(data->reset.width), 0); return 0; } @@ -374,14 +375,14 @@ static int meson_vclk_gate_disable(struct clk *clk) { struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 0); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, MASK(data->enable.width), 0); return 0; } static int meson_vclk_gate_is_enabled(struct clk *clk) { struct meson_vclk_gate_data *data = (struct meson_vclk_gate_data *)(clk->data); - return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width); + return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, MASK(data->enable.width)); } const struct clk_ops meson_vclk_gate_ops = { @@ -393,7 +394,7 @@ const struct clk_ops meson_vclk_gate_ops = { static unsigned long meson_vclk_div_recalc_rate(const struct clk *clk, unsigned long prate) { struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); - uint32_t div = regmap_read_bits(clk->base, data->div.reg_off, data->div.shift, data->div.width); + uint32_t div = regmap_read_bits(clk->base, data->div.reg_off, data->div.shift, MASK(data->div.width)); /* TODO: Need to verify the following cases */ if (data->flags & CLK_DIVIDER_ONE_BASED) { @@ -425,15 +426,15 @@ static int meson_vclk_div_set_rate(const struct clk *clk, uint64_t rate, uint64_ } else { div -= 1; } - return regmap_update_bits(clk->base, data->div.reg_off, data->div.shift, data->div.width, div); + return regmap_update_bits(clk->base, data->div.reg_off, data->div.shift, MASK(data->div.width), div); } static int meson_vclk_div_enable(struct clk *clk) { struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 0); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 1); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, MASK(data->reset.width), 0); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, MASK(data->enable.width), 1); return 0; } @@ -442,15 +443,15 @@ static int meson_vclk_div_disable(struct clk *clk) { struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); - regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width, 0); - regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, data->reset.width, 1); + regmap_update_bits(clk->base, data->enable.reg_off, data->enable.shift, MASK(data->enable.width), 0); + regmap_update_bits(clk->base, data->reset.reg_off, data->reset.shift, MASK(data->reset.width), 1); return 0; } static int meson_vclk_div_is_enabled(struct clk *clk) { struct meson_vclk_div_data *data = (struct meson_vclk_div_data *)(clk->data); - return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, data->enable.width); + return regmap_read_bits(clk->base, data->enable.reg_off, data->enable.shift, MASK(data->enable.width)); } const struct clk_ops meson_vclk_div_ops = { diff --git a/drivers/clk/meson/sm1-clk.c b/drivers/clk/meson/sm1-clk.c index 97069e87b..dabcaa425 100644 --- a/drivers/clk/meson/sm1-clk.c +++ b/drivers/clk/meson/sm1-clk.c @@ -13,7 +13,7 @@ */ #include -#include +#include #include #include #include From e38a2d3fcdea6188bd8a23ed665de02eea3cd2f7 Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Tue, 19 Nov 2024 13:27:08 +1100 Subject: [PATCH 09/11] clk: add get/set parent interfaces Add clk_get_parent() and clk_set_parent() interfaces for the clients. Fixed several logic issues in related implementations. More clock component definition checkings and fixup. Signed-off-by: Terry Bai --- drivers/clk/clk-operations.c | 21 ++--- drivers/clk/clk.h | 2 +- drivers/clk/imx/clk-imx.c | 30 +++--- drivers/clk/imx/clk.c | 104 ++++++++++++++++++++- drivers/clk/meson/clk.c | 109 +++++++++++++++++++++- drivers/clk/meson/include/clk-meson.h | 1 - drivers/clk/meson/include/g12a-bindings.h | 2 + drivers/clk/meson/sm1-clk.c | 45 ++++----- examples/clk/client.c | 41 +++++++- include/sddf/clk/client.h | 35 +++++++ include/sddf/clk/protocol.h | 4 + 11 files changed, 335 insertions(+), 59 deletions(-) diff --git a/drivers/clk/clk-operations.c b/drivers/clk/clk-operations.c index 423a3376c..3a39a686d 100644 --- a/drivers/clk/clk-operations.c +++ b/drivers/clk/clk-operations.c @@ -173,7 +173,7 @@ const struct clk_ops clk_divider_ro_ops = { /* .determine_rate = clk_div_determine_rate, */ }; -static inline uint8_t clk_mux_get_parent(const struct clk *clk) +static inline int clk_mux_get_parent(const struct clk *clk, uint8_t *index) { struct clk_mux_data *data = (struct clk_mux_data *)(clk->data); uint32_t num_parents = clk->hw.init->num_parents; @@ -182,11 +182,12 @@ static inline uint8_t clk_mux_get_parent(const struct clk *clk) if (data->table) { int i; for (i = 0; i < num_parents; i++) { - if (data->table[i] == val) - return i; + if (data->table[i] == val) { + *index = i; + return 0; + } } - return -1; - /* return -EINVAL; */ + return CLK_UNKNOWN_TARGET; } /* if (val && (flags & CLK_MUX_INDEX_BIT)) */ @@ -196,10 +197,9 @@ static inline uint8_t clk_mux_get_parent(const struct clk *clk) /* val--; */ if (val >= num_parents) - /* return -EINVAL; */ - return -1; + return CLK_UNKNOWN_TARGET; - /* return val; */ + *index = val; return 0; } @@ -209,11 +209,10 @@ static inline int clk_mux_set_parent(struct clk *clk, uint8_t index) if (data->table) { uint32_t val = data->table[index]; - regmap_update_bits(clk->base, data->offset, data->shift, data->mask, val); + return regmap_update_bits(clk->base, data->offset, data->shift, data->mask, val); } - regmap_update_bits(clk->base, data->offset, data->shift, data->mask, index); - return 0; + return regmap_update_bits(clk->base, data->offset, data->shift, data->mask, index); } const struct clk_ops clk_mux_ops = { diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index f73d2b98e..4402d34a9 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -143,7 +143,7 @@ struct clk_hw { * */ struct clk_ops { - uint8_t (*get_parent)(const struct clk *clk); + int (*get_parent)(const struct clk *clk, uint8_t *index); int (*set_parent)(struct clk *clk, uint8_t index); uint64_t (*recalc_rate)(const struct clk *clk, uint64_t parent_rate); int (*set_rate)(const struct clk *clk, uint64_t rate, uint64_t parent_rate); diff --git a/drivers/clk/imx/clk-imx.c b/drivers/clk/imx/clk-imx.c index ae0a1891e..64282fcc8 100644 --- a/drivers/clk/imx/clk-imx.c +++ b/drivers/clk/imx/clk-imx.c @@ -134,18 +134,17 @@ static uint64_t clk_sscg_pll_recalc_rate(const struct clk *clk, uint64_t prate) return 0; } -static uint8_t clk_sscg_pll_get_parent(const struct clk *clk) +static int clk_sscg_pll_get_parent(const struct clk *clk, uint8_t *index) { struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); - uint8_t ret = 0; if (regmap_read_bits(clk->base, data->offset, 4, MASK(1))) { - ret = data->bypass2; + *index = data->bypass2; } else if (regmap_read_bits(clk->base, data->offset, 5, MASK(1))) { - ret = data->bypass1; + *index = data->bypass1; } - return ret; + return 0; } static int clk_sscg_pll_set_parent(struct clk *clk, uint8_t index) @@ -178,7 +177,7 @@ static uint64_t imx8m_clk_core_slice_recalc_rate(const struct clk *clk, uint64_t return DIV_ROUND_UP_ULL((uint64_t)prate, div_val + 1); } -static uint8_t imx8m_clk_core_slice_get_parent(const struct clk *clk) +static int imx8m_clk_core_slice_get_parent(const struct clk *clk, uint8_t *index) { struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); @@ -186,9 +185,10 @@ static uint8_t imx8m_clk_core_slice_get_parent(const struct clk *clk) uint32_t val = regmap_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); if (val >= num_parents) - return -1; + return CLK_UNKNOWN_TARGET; - return val; + *index = val; + return 0; } static int imx8m_clk_core_slice_set_parent(struct clk *clk, uint8_t index) @@ -227,7 +227,7 @@ static uint64_t imx8m_clk_common_slice_recalc_rate(const struct clk *clk, uint64 return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); } -static uint8_t imx8m_clk_common_slice_get_parent(const struct clk *clk) +static int imx8m_clk_common_slice_get_parent(const struct clk *clk, uint8_t *index) { struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); @@ -235,9 +235,10 @@ static uint8_t imx8m_clk_common_slice_get_parent(const struct clk *clk) uint32_t val = regmap_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); if (val >= num_parents) - return -1; + return CLK_UNKNOWN_TARGET; - return val; + *index = val; + return 0; } static int imx8m_clk_common_slice_set_parent(struct clk *clk, uint8_t index) @@ -276,7 +277,7 @@ static uint64_t imx8m_clk_bus_slice_recalc_rate(const struct clk *clk, uint64_t return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); } -static uint8_t imx8m_clk_bus_slice_get_parent(const struct clk *clk) +static int imx8m_clk_bus_slice_get_parent(const struct clk *clk, uint8_t *index) { struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); @@ -284,9 +285,10 @@ static uint8_t imx8m_clk_bus_slice_get_parent(const struct clk *clk) uint32_t val = regmap_read_bits(clk->base, data->offset, data->mux_shift, data->mux_mask); if (val >= num_parents) - return -1; + return CLK_UNKNOWN_TARGET; - return val; + *index = val; + return 0; } static int imx8m_clk_bus_slice_set_parent(struct clk *clk, uint8_t index) diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index f05e2babf..0d6fc04b0 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -62,6 +62,7 @@ void clk_probe(struct clk *clk_list[]) } else if (clk_list[i]->base == CCM_ANALOG_BASE) { clk_list[i]->base = ccm_analog_base; } + if (clk_list[i] && init_data->ops->init) { init_data->ops->init(clk_list[i]); LOG_DRIVER("Initialise %s\n", init_data->name); @@ -78,7 +79,11 @@ const struct clk *get_parent(const struct clk *clk) uint32_t num_parents = init->num_parents; if (init->parent_data) { - uint8_t parent_idx = num_parents > 1 ? init->ops->get_parent(clk) : 0; + uint8_t parent_idx = 0; + int err = num_parents > 1 ? init->ops->get_parent(clk, &parent_idx) : 0; + if (err) + return NULL; + struct clk_parent_data parent_data = init->parent_data[parent_idx]; if (parent_data.clk) { @@ -96,6 +101,58 @@ const struct clk *get_parent(const struct clk *clk) return NULL; } +int clk_get_parent_id(const struct clk *clk, uint32_t *parent_clk_id) +{ + if (!clk) + return CLK_UNKNOWN_TARGET; + + const struct clk *pclk = get_parent(clk); + + if (pclk == NULL) + return CLK_INVALID_OP; + + for (int i = 0; i < NUM_CLK_LIST; i++) { + if (pclk == clk_list[i]) { + *parent_clk_id = i; + return 0; + } + } + + return CLK_UNKNOWN_TARGET; +} + +/* The user needs to know which parent clock the value represents, and check + * if the target parent clock is configured correctly with clk_get_parent() */ +int clk_set_parent_by_val(struct clk *clk, uint32_t parent_idx) +{ + if (!clk) + return CLK_UNKNOWN_TARGET; + + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; + if (init->ops->set_parent) { + init->ops->set_parent(clk, parent_idx); + return 0; + } + LOG_DRIVER_ERR("clock \"%s\" has no set_parent() interface\n", init->name); + return CLK_INVALID_OP; +} + +int clk_set_parent_by_id(struct clk *clk, uint32_t pclk_id) +{ + const struct clk *pclk = clk_list[pclk_id]; + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; + uint32_t num_parents = init->num_parents; + for (int i = 0; i < num_parents; i++) { + if (init->parent_clks && init->parent_clks[i] == pclk) { + return clk_set_parent_by_val(clk, i); + } else if (get_clk_by_name(init->parent_data[i].name) == pclk) { + return clk_set_parent_by_val(clk, i); + } + } + + return CLK_UNKNOWN_TARGET; +} + /* TODO: Should be just read from the structure, but need to update everytime when */ /* related clocks are modified */ int clk_get_rate(const struct clk *clk, uint64_t *rate) @@ -215,6 +272,7 @@ void notified(microkit_channel ch) void init(void) { + int err = 0; clk_list = get_clk_list(); clk_probe(clk_list); @@ -222,11 +280,18 @@ void init(void) for (int i = 0; i < NUM_DEVICE_CLKS; i++) { struct clk *clk = clk_list[clk_configs[i].clk_id]; - LOG_DRIVER("clk_id: %d\n", clk_configs[i].clk_id); + /* Enable the clock */ clk_enable(clk); - /* TODO: Set parent */ + /* Set parent for clocks as configured in device tree */ + if (clk_configs[i].pclk_id) { + err = clk_set_parent_by_id(clk, clk_configs[i].pclk_id); + if (err) { + LOG_DRIVER_ERR("Failed to set parent %u for clock %u: err - %d\n", clk_configs[i].pclk_id, + clk_configs[i].clk_id, err); + } + } /* TODO: Set rate for the target clock */ /* if (clk_configs[i].frequency > 0) { */ @@ -244,6 +309,7 @@ void init(void) microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) { int err = 0; + uint32_t ret_num = 0; uint32_t argc = microkit_msginfo_get_count(msginfo); /* TODO: Check if the channel is valid */ @@ -280,6 +346,8 @@ microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); uint64_t rate = 0; err = clk_get_rate(clk_list[clk_id], &rate); + microkit_mr_set(0, rate); + ret_num = 1; break; } case SDDF_CLK_SET_RATE: { @@ -292,6 +360,34 @@ microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) uint64_t req_rate = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_RATE); uint64_t rate = 0; err = clk_set_rate(clk_list[clk_id], req_rate, &rate); + microkit_mr_set(0, rate); + ret_num = 1; + break; + } + case SDDF_CLK_GET_PARENT: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + err = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + uint32_t pclk_id = 0; + err = clk_get_parent_id(clk_list[clk_id], &pclk_id); + microkit_mr_set(0, pclk_id); + ret_num = 1; + break; + } + case SDDF_CLK_SET_PARENT: { + if (argc != 2) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + err = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + uint32_t pclk_idx = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_PCLK_IDX); + err = clk_set_parent_by_val(clk_list[clk_id], pclk_idx); + microkit_mr_set(0, pclk_idx); + ret_num = 1; break; } default: @@ -299,5 +395,5 @@ microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) ch); err = CLK_UNKNOWN_REQ; } - return microkit_msginfo_new(err, 0); + return microkit_msginfo_new(err, ret_num); } diff --git a/drivers/clk/meson/clk.c b/drivers/clk/meson/clk.c index 23ed849de..05a72ccb5 100644 --- a/drivers/clk/meson/clk.c +++ b/drivers/clk/meson/clk.c @@ -31,7 +31,7 @@ #define LOG_DRIVER_ERR(...) do{ sddf_printf("CLK DRIVER|ERROR: "); sddf_printf(__VA_ARGS__); }while(0) -#define NUM_CLK_LIST CLKID_PCIE_PLL +#define NUM_CLK_LIST 280 #define I2C_CLK_OFFSET 320 #define I2C_CLK_BIT (1 << 9) // bit 9 @@ -41,6 +41,16 @@ uintptr_t msr_clk_base; struct clk **clk_list; +struct clk *get_clk_by_name(const char *name) +{ + for (int i = 0; i < NUM_CLK_LIST; i++) { + if (clk_list[i] && sddf_strcmp(clk_list[i]->hw.init->name, name) == 0) { + return clk_list[i]; + } + } + return NULL; +} + /* TODO: Should be configured with init_regs */ /* static struct clk_cfg fixed_clk_configs[] = { */ /* { .clk_id = CLKID_FCLK_DIV2_DIV, .frequency = 1000000000 }, */ @@ -54,8 +64,10 @@ void clk_probe(struct clk *clk_list[]) { int i; for (i = 0; i < NUM_CLK_LIST; i++) { + if (!clk_list[i]) + continue; clk_list[i]->base = (uint64_t)clk_regs; - if (clk_list[i] && clk_list[i]->hw.init->ops->init) { + if (clk_list[i]->hw.init->ops->init) { clk_list[i]->hw.init->ops->init(clk_list[i]); LOG_DRIVER("Initialise %s\n", clk_list[i]->hw.init->name); } @@ -71,13 +83,17 @@ const struct clk *get_parent(const struct clk *clk) uint32_t num_parents = init->num_parents; if (init->parent_data) { - uint8_t parent_idx = num_parents > 1 ? init->ops->get_parent(clk) : 0; + uint8_t parent_idx = 0; + int err = num_parents > 1 ? init->ops->get_parent(clk, &parent_idx) : 0; + if (err) + return NULL; + struct clk_parent_data parent_data = init->parent_data[parent_idx]; if (parent_data.clk) { return parent_data.clk; } else if (sddf_strcmp(parent_data.name, "xtal") == 0) { - return &g12a_xtal; + return clk_list[CLKID_G12A_XTAL]; } } @@ -88,6 +104,57 @@ const struct clk *get_parent(const struct clk *clk) return NULL; } +int clk_get_parent_id(const struct clk *clk, uint32_t *parent_clk_id) +{ + if (!clk) + return CLK_UNKNOWN_TARGET; + + const struct clk *pclk = get_parent(clk); + + if (pclk == NULL) + return CLK_INVALID_OP; + + for (int i = 0; i < NUM_CLK_LIST; i++) { + if (pclk == clk_list[i]) { + *parent_clk_id = i; + return 0; + } + } + + return CLK_UNKNOWN_TARGET; +} + +/* The user needs to know which parent clock the value represents, and check + * if the target parent clock is configured correctly with clk_get_parent() */ +int clk_set_parent_by_val(struct clk *clk, uint32_t parent_idx) +{ + if (!clk) + return CLK_UNKNOWN_TARGET; + + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; + if (init->ops->set_parent) { + init->ops->set_parent(clk, parent_idx); + return 0; + } + return CLK_INVALID_OP; +} + +int clk_set_parent_by_id(struct clk *clk, uint32_t pclk_id) +{ + const struct clk *pclk = clk_list[pclk_id]; + const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; + uint32_t num_parents = init->num_parents; + for (int i = 0; i < num_parents; i++) { + if (init->parent_clks && init->parent_clks[i] == pclk) { + return clk_set_parent_by_val(clk, i); + } else if (get_clk_by_name(init->parent_data[i].name) == pclk) { + return clk_set_parent_by_val(clk, i); + } + } + + return CLK_UNKNOWN_TARGET; +} + /* TODO: Should be just read from the structure, but need to update everytime when */ /* related clocks are modified */ int clk_get_rate(const struct clk *clk, uint64_t *rate) @@ -217,6 +284,7 @@ void init(void) { LOG_DRIVER("Clock driver initialising...\n"); + int err = 0; clk_list = get_clk_list(); clk_probe(clk_list); @@ -228,7 +296,14 @@ void init(void) /* Enable the clock */ clk_enable(clk); - /* TODO: Set parent */ + /* Set parent for clocks as configured in device tree */ + if (clk_configs[i].pclk_id) { + err = clk_set_parent_by_id(clk, clk_configs[i].pclk_id); + if (err) { + LOG_DRIVER_ERR("Failed to set parent %u for clock %u: err - %d\n", clk_configs[i].pclk_id, + clk_configs[i].clk_id, err); + } + } /* Set rate for the target clock */ if (clk_configs[i].frequency > 0) { @@ -300,6 +375,30 @@ microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) ret_num = 1; break; } + case SDDF_CLK_GET_PARENT: { + if (argc != 1) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + err = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + uint32_t pclk_id = 0; + err = clk_get_parent_id(clk_list[clk_id], &pclk_id); + microkit_mr_set(0, pclk_id); + ret_num = 1; + break; + } + case SDDF_CLK_SET_PARENT: { + if (argc != 2) { + LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); + err = CLK_INCORRECT_ARGS; + break; + } + uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); + uint32_t pclk_idx = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_PCLK_IDX); + err = clk_set_parent_by_val(clk_list[clk_id], pclk_idx); + break; + } default: LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), ch); diff --git a/drivers/clk/meson/include/clk-meson.h b/drivers/clk/meson/include/clk-meson.h index 8563b166a..77e52d97c 100644 --- a/drivers/clk/meson/include/clk-meson.h +++ b/drivers/clk/meson/include/clk-meson.h @@ -171,5 +171,4 @@ struct clk _name = { \ }, \ } -extern const struct clk g12a_xtal; struct clk **get_clk_list(void); diff --git a/drivers/clk/meson/include/g12a-bindings.h b/drivers/clk/meson/include/g12a-bindings.h index 582b0d084..df04e4de0 100644 --- a/drivers/clk/meson/include/g12a-bindings.h +++ b/drivers/clk/meson/include/g12a-bindings.h @@ -290,4 +290,6 @@ #define CLKID_MIPI_ISP_CSI_PHY0 277 #define CLKID_MIPI_ISP_CSI_PHY1 278 +#define CLKID_G12A_XTAL 279 + #endif /* __G12A_CLKC_H */ diff --git a/drivers/clk/meson/sm1-clk.c b/drivers/clk/meson/sm1-clk.c index dabcaa425..55d2ac5f8 100644 --- a/drivers/clk/meson/sm1-clk.c +++ b/drivers/clk/meson/sm1-clk.c @@ -20,14 +20,14 @@ #include #include -const struct clk g12a_xtal = { .data = - &(struct clk_source_data) { - .rate = 24000000, - }, - .hw.init = &(struct clk_init_data) { - .name = "xtal", - .ops = &clk_source_ops, - } }; +static struct clk g12a_xtal = { .data = + &(struct clk_source_data) { + .rate = 24000000, + }, + .hw.init = &(struct clk_init_data) { + .name = "xtal", + .ops = &clk_source_ops, + } }; static struct clk g12a_fixed_pll_dco = { .data = &(struct meson_clk_pll_data){ @@ -746,15 +746,15 @@ static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = { { .clk = &g12a_fclk_div5 }, { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(g12a_sd_emmc_a_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 9, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, +static CLK_MUX(g12a_sd_emmc_a_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 9, 0, 0, g12a_sd_emmc_clk0_parent_data, 5, CLK_SET_RATE_PARENT); static CLK_DIV(g12a_sd_emmc_a_clk0_div, HHI_SD_EMMC_CLK_CNTL, 0, 7, 0, { &g12a_sd_emmc_a_clk0_sel }, 1, 0); static CLK_GATE(g12a_sd_emmc_a_clk0, HHI_SD_EMMC_CLK_CNTL, 7, 0, { &g12a_sd_emmc_a_clk0_div }, 1, 0); -static CLK_MUX(g12a_sd_emmc_b_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 25, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, +static CLK_MUX(g12a_sd_emmc_b_clk0_sel, HHI_SD_EMMC_CLK_CNTL, 0x7, 25, 0, 0, g12a_sd_emmc_clk0_parent_data, 5, CLK_SET_RATE_PARENT); static CLK_DIV(g12a_sd_emmc_b_clk0_div, HHI_SD_EMMC_CLK_CNTL, 16, 7, 0, { &g12a_sd_emmc_b_clk0_sel }, 1, 0); static CLK_GATE(g12a_sd_emmc_b_clk0, HHI_SD_EMMC_CLK_CNTL, 23, 0, { &g12a_sd_emmc_b_clk0_div }, 1, 0); -static CLK_MUX(g12a_sd_emmc_c_clk0_sel, HHI_NAND_CLK_CNTL, 0x7, 9, 0, 0, g12a_sd_emmc_clk0_parent_data, 0, +static CLK_MUX(g12a_sd_emmc_c_clk0_sel, HHI_NAND_CLK_CNTL, 0x7, 9, 0, 0, g12a_sd_emmc_clk0_parent_data, 5, CLK_SET_RATE_PARENT); static CLK_DIV(g12a_sd_emmc_c_clk0_div, HHI_NAND_CLK_CNTL, 0, 7, 0, { &g12a_sd_emmc_c_clk0_sel }, 1, 0); static CLK_GATE(g12a_sd_emmc_c_clk0, HHI_NAND_CLK_CNTL, 7, 0, { &g12a_sd_emmc_c_clk0_div }, 1, 0); @@ -852,16 +852,16 @@ static const struct clk_parent_data g12a_vdec_parent_table[] = { }, }; -static CLK_MUX(g12a_vdec_1_sel, HHI_VDEC_CLK_CNTL, 0x7, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, +static CLK_MUX(g12a_vdec_1_sel, HHI_VDEC_CLK_CNTL, 0x7, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 7, CLK_SET_RATE_PARENT); static CLK_DIV(g12a_vdec_1_div, HHI_VDEC_CLK_CNTL, 0, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_1_sel }, 1, 0); static CLK_GATE(g12a_vdec_1, HHI_VDEC_CLK_CNTL, 8, 0, { &g12a_vdec_1_div }, 1, 0); -static CLK_MUX(g12a_vdec_hevcf_sel, HHI_VDEC2_CLK_CNTL, 0x7, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, +static CLK_MUX(g12a_vdec_hevcf_sel, HHI_VDEC2_CLK_CNTL, 0x7, 9, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 7, CLK_SET_RATE_PARENT); static CLK_DIV(g12a_vdec_hevcf_div, HHI_VDEC2_CLK_CNTL, 0, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevcf_sel }, 1, 0); static CLK_GATE(g12a_vdec_hevcf, HHI_VDEC2_CLK_CNTL, 8, 0, { &g12a_vdec_hevcf_div }, 1, 0); -static CLK_MUX(g12a_vdec_hevc_sel, HHI_VDEC2_CLK_CNTL, 0x7, 25, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 0, +static CLK_MUX(g12a_vdec_hevc_sel, HHI_VDEC2_CLK_CNTL, 0x7, 25, 0, CLK_MUX_ROUND_CLOSEST, g12a_vdec_parent_table, 7, CLK_SET_RATE_PARENT); static CLK_DIV(g12a_vdec_hevc_div, HHI_VDEC2_CLK_CNTL, 16, 7, CLK_DIVIDER_ROUND_CLOSEST, { &g12a_vdec_hevc_sel }, 1, 0); static CLK_GATE(g12a_vdec_hevc, HHI_VDEC2_CLK_CNTL, 24, 0, { &g12a_vdec_hevc_div }, 1, 0); @@ -891,10 +891,10 @@ static const struct clk_parent_data g12a_vapb_parent_table[] = { .clk = &g12a_fclk_div2p5, }, }; -static CLK_MUX(g12a_vapb_0_sel, HHI_VAPBCLK_CNTL, 0x3, 9, 0, 0, g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_MUX(g12a_vapb_0_sel, HHI_VAPBCLK_CNTL, 0x3, 9, 0, 0, g12a_vapb_parent_table, 8, CLK_SET_RATE_NO_REPARENT); static CLK_DIV(g12a_vapb_0_div, HHI_VAPBCLK_CNTL, 0, 7, 0, { &g12a_vapb_0_sel }, 1, 0); static CLK_GATE(g12a_vapb_0, HHI_VAPBCLK_CNTL, 8, 0, { &g12a_vapb_0_div }, 1, 0); -static CLK_MUX(g12a_vapb_1_sel, HHI_VAPBCLK_CNTL, 0x3, 25, 0, 0, g12a_vapb_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_MUX(g12a_vapb_1_sel, HHI_VAPBCLK_CNTL, 0x3, 25, 0, 0, g12a_vapb_parent_table, 8, CLK_SET_RATE_NO_REPARENT); static CLK_DIV(g12a_vapb_1_div, HHI_VAPBCLK_CNTL, 16, 7, 0, { &g12a_vapb_1_sel }, 1, 0); static CLK_GATE(g12a_vapb_1, HHI_VAPBCLK_CNTL, 24, 0, { &g12a_vapb_1_div }, 1, 0); const struct clk_parent_data g12a_vapb_sel_parent_table[] = { @@ -929,9 +929,9 @@ static const struct clk_parent_data g12a_vclk_parent_table[] = { .clk = &g12a_fclk_div7, }, }; -static CLK_MUX(g12a_vclk_sel, HHI_VID_CLK_CNTL, 0x7, 16, 0, 0, g12a_vclk_parent_table, 0, +static CLK_MUX(g12a_vclk_sel, HHI_VID_CLK_CNTL, 0x7, 16, 0, 0, g12a_vclk_parent_table, 8, CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE); -static CLK_MUX(g12a_vclk2_sel, HHI_VIID_CLK_CNTL, 0x7, 16, 0, 0, g12a_vclk_parent_table, 0, CLK_SET_RATE_NO_REPARENT); +static CLK_MUX(g12a_vclk2_sel, HHI_VIID_CLK_CNTL, 0x7, 16, 0, 0, g12a_vclk_parent_table, 8, CLK_SET_RATE_NO_REPARENT); static CLK_GATE(g12a_vclk_input, HHI_VID_CLK_DIV, 16, 0, { &g12a_vclk_sel }, 1, 0); static CLK_GATE(g12a_vclk2_input, HHI_VIID_CLK_DIV, 16, 0, { &g12a_vclk2_sel }, 1, 0); static CLK_DIV(g12a_vclk_div, HHI_VID_CLK_DIV, 0, 8, 0, { &g12a_vclk_input }, 1, 0); @@ -1168,10 +1168,10 @@ static const struct clk_parent_data spicc_sclk_parent_data[] = { { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(g12a_spicc0_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 7, 0, 0, spicc_sclk_parent_data, 0, 0); +static CLK_MUX(g12a_spicc0_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 7, 0, 0, spicc_sclk_parent_data, 6, 0); static CLK_DIV(g12a_spicc0_sclk_div, HHI_SPICC_CLK_CNTL, 0, 6, 0, { &g12a_spicc0_sclk_sel }, 1, 0); static CLK_GATE(g12a_spicc0_sclk, HHI_SPICC_CLK_CNTL, 6, 0, { &g12a_spicc0_sclk_div }, 1, 0); -static CLK_MUX(g12a_spicc1_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 23, 0, 0, spicc_sclk_parent_data, 0, 0); +static CLK_MUX(g12a_spicc1_sclk_sel, HHI_SPICC_CLK_CNTL, 7, 23, 0, 0, spicc_sclk_parent_data, 6, 0); static CLK_DIV(g12a_spicc1_sclk_div, HHI_SPICC_CLK_CNTL, 16, 6, 0, { &g12a_spicc1_sclk_sel }, 1, 0); static CLK_GATE(g12a_spicc1_sclk, HHI_SPICC_CLK_CNTL, 22, 0, { &g12a_spicc1_sclk_div }, 1, 0); static const struct clk_parent_data nna_clk_parent_data[] = { @@ -1198,10 +1198,10 @@ static const struct clk_parent_data nna_clk_parent_data[] = { }, { .clk = &g12a_fclk_div7 }, }; -static CLK_MUX(sm1_nna_axi_clk_sel, HHI_NNA_CLK_CNTL, 7, 9, 0, 0, nna_clk_parent_data, 0, 0); +static CLK_MUX(sm1_nna_axi_clk_sel, HHI_NNA_CLK_CNTL, 7, 9, 0, 0, nna_clk_parent_data, 8, 0); static CLK_DIV(sm1_nna_axi_clk_div, HHI_NNA_CLK_CNTL, 0, 7, 0, { &sm1_nna_axi_clk_sel }, 1, 0); static CLK_GATE(sm1_nna_axi_clk, HHI_NNA_CLK_CNTL, 8, 0, { &sm1_nna_axi_clk_div }, 1, 0); -static CLK_MUX(sm1_nna_core_clk_sel, HHI_NNA_CLK_CNTL, 7, 25, 0, 0, nna_clk_parent_data, 0, 0); +static CLK_MUX(sm1_nna_core_clk_sel, HHI_NNA_CLK_CNTL, 7, 25, 0, 0, nna_clk_parent_data, 8, 0); static CLK_DIV(sm1_nna_core_clk_div, HHI_NNA_CLK_CNTL, 16, 7, 0, { &sm1_nna_core_clk_sel }, 1, 0); static CLK_GATE(sm1_nna_core_clk, HHI_NNA_CLK_CNTL, 24, 0, { &sm1_nna_core_clk_div }, 1, 0); @@ -1525,6 +1525,7 @@ static struct clk *sm1_clks[] = { [CLKID_MIPI_DSI_PXCLK_SEL] = &g12a_mipi_dsi_pxclk_sel, [CLKID_MIPI_DSI_PXCLK_DIV] = &g12a_mipi_dsi_pxclk_div, [CLKID_MIPI_DSI_PXCLK] = &g12a_mipi_dsi_pxclk, + [CLKID_G12A_XTAL] = &g12a_xtal, }; struct clk **get_clk_list(void) diff --git a/examples/clk/client.c b/examples/clk/client.c index 0fef03106..e68219b54 100644 --- a/examples/clk/client.c +++ b/examples/clk/client.c @@ -67,22 +67,61 @@ void init(void) sddf_dprintf("The rate of clock %u: %lu\n", clk_id_to_get_rate, rate); } + uint32_t clk_id_to_test_parent = 63; + uint32_t parent_id = 0; + ret = sddf_clk_get_parent(CLK_DRIVER_CH, clk_id_to_test_parent, &parent_id); + if (ret) { + sddf_dprintf("Failed to get the parent of clock %u: err - %d\n", clk_id_to_test_parent, ret); + } else { + sddf_dprintf("The parent of clock %u: %u\n", clk_id_to_test_parent, parent_id); + } + + uint32_t pclk_idx = 3; + ret = sddf_clk_set_parent(CLK_DRIVER_CH, clk_id_to_test_parent, pclk_idx); + if (ret) { + sddf_dprintf("Failed to set the parent of clock %u: err - %d\n", clk_id_to_test_parent, ret); + } else { + ret = sddf_clk_get_parent(CLK_DRIVER_CH, clk_id_to_test_parent, &parent_id); + sddf_dprintf("The parent of clock %u has been set to: %u\n", clk_id_to_test_parent, parent_id); + } + #elif TEST_BOARD_maaxboard sddf_dprintf("Test board: maaxboard\n"); + int ret = 0; /** * IMX8MQ_CLK_SAI1_ROOT = 196 + * IMX8MQ_CLK_I2C1 = 144 * * see `sddf/drivers/clk/imx/include/imx8mq-bindings.h` for more clock indices. * */ + uint32_t clk_id_to_enable = 196; - int ret = sddf_clk_enable(CLK_DRIVER_CH, clk_id_to_enable); + ret = sddf_clk_enable(CLK_DRIVER_CH, clk_id_to_enable); if (ret) { sddf_dprintf("Failed to enable clock %u: err - %d\n", clk_id_to_enable, ret); } else { sddf_dprintf("Successfully enabled clock %u\n", clk_id_to_enable); } + uint32_t clk_id_to_test_parent = 144; + uint32_t parent_id = 0; + ret = sddf_clk_get_parent(CLK_DRIVER_CH, clk_id_to_test_parent, &parent_id); + if (ret) { + sddf_dprintf("Failed to get the parent of clock %u: err - %d\n", clk_id_to_test_parent, ret); + } else { + sddf_dprintf("The parent of clock %u: %u\n", clk_id_to_test_parent, parent_id); + } + + uint32_t pclk_idx = 3; + ret = sddf_clk_set_parent(CLK_DRIVER_CH, clk_id_to_test_parent, pclk_idx); + if (ret) { + sddf_dprintf("Failed to set the parent of clock %u: err - %d\n", clk_id_to_test_parent, ret); + } else { + ret = sddf_clk_get_parent(CLK_DRIVER_CH, clk_id_to_test_parent, &parent_id); + sddf_dprintf("The parent of clock %u has been set to: %u\n", clk_id_to_test_parent, parent_id); + } + #else sddf_dprintf("No tests for the target board\n", ret); #endif diff --git a/include/sddf/clk/client.h b/include/sddf/clk/client.h index 21c1f3336..ec1e22847 100644 --- a/include/sddf/clk/client.h +++ b/include/sddf/clk/client.h @@ -79,3 +79,38 @@ static inline int sddf_clk_set_rate(microkit_channel channel, uint32_t clk_id, u *rate = microkit_mr_get(0); return (int)microkit_msginfo_get_label(msginfo); } + +/** + * Send a clock get_parent request via PPC into the passive clock driver. + * Use the label to indicate this request. + * @param channel of clock driver. + * @param pointer to result (i.e. pclk_id) + */ +static inline int sddf_clk_get_parent(microkit_channel channel, uint32_t clk_id, uint32_t *pclk_id) +{ + microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_GET_PARENT, 1); + microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); + + msginfo = microkit_ppcall(channel, msginfo); + + *pclk_id = microkit_mr_get(0); + return (int)microkit_msginfo_get_label(msginfo); +} + +/** + * Send a clock set_parent request via PPC into the passive clock driver. + * Use the label to indicate this request. + * @param channel of clock driver. + * @param identifier of target clock. + * @param indice of target clock. + */ +static inline int sddf_clk_set_parent(microkit_channel channel, uint32_t clk_id, uint32_t parent_idx) +{ + microkit_msginfo msginfo = microkit_msginfo_new(SDDF_CLK_SET_PARENT, 2); + microkit_mr_set(SDDF_CLK_PARAM_ID, clk_id); + microkit_mr_set(SDDF_CLK_PARAM_PCLK_IDX, parent_idx); + + msginfo = microkit_ppcall(channel, msginfo); + + return (int)microkit_msginfo_get_label(msginfo); +} diff --git a/include/sddf/clk/protocol.h b/include/sddf/clk/protocol.h index 7f1b6bff6..781483ced 100644 --- a/include/sddf/clk/protocol.h +++ b/include/sddf/clk/protocol.h @@ -16,10 +16,14 @@ #define SDDF_CLK_DISABLE 1 #define SDDF_CLK_GET_RATE 2 #define SDDF_CLK_SET_RATE 3 +#define SDDF_CLK_GET_PARENT 4 +#define SDDF_CLK_SET_PARENT 5 #define SDDF_CLK_PARAM_ID 0 #define SDDF_CLK_PARAM_RATE 1 +#define SDDF_CLK_PARAM_PCLK_IDX 1 + struct clk_cfg { uint32_t clk_id; uint32_t frequency; From 38d9f73d70a9cc3b714ed12698d4770b59ba446e Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Wed, 20 Nov 2024 13:30:46 +1100 Subject: [PATCH 10/11] clk: set_rate for maaxboard clocks This commit adds set_rate() implementations for maaxboard. Now clocks can be set to target rate at initialisation time and configured dynamically. Signed-off-by: Terry Bai --- drivers/clk/clk-operations.h | 12 +++ drivers/clk/clk.h | 2 + drivers/clk/clk_utils.h | 2 + drivers/clk/imx/clk-imx.c | 141 ++++++++++++++++++++++++++++++++-- drivers/clk/imx/clk.c | 19 +++-- drivers/clk/meson/clk-meson.c | 37 ++++----- 6 files changed, 175 insertions(+), 38 deletions(-) diff --git a/drivers/clk/clk-operations.h b/drivers/clk/clk-operations.h index cec380404..361075af8 100644 --- a/drivers/clk/clk-operations.h +++ b/drivers/clk/clk-operations.h @@ -7,12 +7,24 @@ #include #include +#include #define CLK_INCORRECT_ARGS -1 #define CLK_INVALID_OP -2 #define CLK_INVALID_ID -3 #define CLK_UNKNOWN_REQ -4 #define CLK_UNKNOWN_TARGET -5 +#define CLK_FAILED_OP -6 + +/* TODO: Replace this doggy delay() with a standard interface */ +static inline void delay_us(uint32_t us) +{ + uint64_t start_time = sddf_timer_time_now(TIMER_CH); + uint64_t now_time = start_time; + while (now_time - start_time < us) { + now_time = sddf_timer_time_now(TIMER_CH); + } +} static inline int reg_write(uint64_t base, uint32_t offset, uint32_t val) { diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index 4402d34a9..ffcedad6f 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -13,6 +13,8 @@ #include +#define TIMER_CH 1 + /* * flags used across common struct clk. these flags should only affect the * top-level framework. custom flags for dealing with hardware specifics diff --git a/drivers/clk/clk_utils.h b/drivers/clk/clk_utils.h index 5a521673d..d22d451e7 100644 --- a/drivers/clk/clk_utils.h +++ b/drivers/clk/clk_utils.h @@ -7,6 +7,8 @@ #define MASK(width) ((1UL << width) - 1) +#define abs(x) ( ( (x) < 0) ? -(x) : (x) ) + #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) #define do_div(n, base) ({ \ diff --git a/drivers/clk/imx/clk-imx.c b/drivers/clk/imx/clk-imx.c index 64282fcc8..6691ab0c2 100644 --- a/drivers/clk/imx/clk-imx.c +++ b/drivers/clk/imx/clk-imx.c @@ -32,6 +32,7 @@ * cfaaa7d010d1fc58f9717fcc8591201e741d2d49/drivers/clk/imx/clk-composite-8m.c */ +#include #include #include #include @@ -100,13 +101,70 @@ static uint64_t clk_pll_recalc_rate(const struct clk *clk, uint64_t prate) return rate; } +static int clk_pll_set_rate(const struct clk *clk, uint64_t rate, uint64_t parent_rate) +{ + struct clk_frac_pll_data *data = (struct clk_frac_pll_data *)(clk->data); + uint32_t divfi, divff; + uint64_t temp64; + int ret; + + parent_rate *= 8; + rate *= 2; + divfi = rate / parent_rate; + temp64 = parent_rate * divfi; + temp64 = rate - temp64; + temp64 *= PLL_FRAC_DENOM; + do_div(temp64, parent_rate); + divff = temp64; + + /** + * Keep PLL_OUTPUT_VAL at zero. + * + * pllout = parent_rate * 8 / 2 * DIVF_VAL; + * where DIVF_VAL = 1 + DIVFI + DIVFF / 2^24. + */ + + /* Write PLL_FRAC_DIV_CTL */ + ret = regmap_update_bits(clk->base, data->offset + 0x4, 7, 24, divff); + if (ret) + return ret; + + /* Write PLL_INT_DIV_CTL */ + ret = regmap_update_bits(clk->base, data->offset + 0x4, 0, 7, divfi - 1); + if (ret) + return ret; + + /* Clear PLL_OUTPUT_DIV_VAL */ + ret = regmap_update_bits(clk->base, data->offset, 0, 5, 0); + if (ret) + return ret; + + /* Set the NEV_DIV_VAL to reload the DIVFI and DIVFF */ + ret = regmap_update_bits(clk->base, data->offset, 12, 1, 1); + if (ret) + return ret; + + // Wait ack + uint32_t timeout = 1000; + while (timeout--) { + if (regmap_read_bits(clk->base, data->offset, 12, 1)) { + break; + } + } + if (!timeout) + return CLK_FAILED_OP; + + /* clear the NEV_DIV_VAL */ + return regmap_update_bits(clk->base, data->offset, 12, 1, 1); +} + const struct clk_ops clk_frac_pll_ops = { /* .prepare = clk_pll_prepare, */ /* .unprepare = clk_pll_unprepare, */ /* .is_prepared = clk_pll_is_prepared, */ .recalc_rate = clk_pll_recalc_rate, /* .round_rate = clk_pll_round_rate, */ - /* .set_rate = clk_pll_set_rate, */ + .set_rate = clk_pll_set_rate, }; static uint64_t clk_sscg_pll_recalc_rate(const struct clk *clk, uint64_t prate) @@ -134,6 +192,15 @@ static uint64_t clk_sscg_pll_recalc_rate(const struct clk *clk, uint64_t prate) return 0; } +static int clk_sscg_pll_set_rate(const struct clk *clk, uint64_t rate, uint64_t parent_rate) +{ + /* struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); */ + + /* TODO: to be implemented. */ + + return 0; +} + static int clk_sscg_pll_get_parent(const struct clk *clk, uint8_t *index) { struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); @@ -149,7 +216,7 @@ static int clk_sscg_pll_get_parent(const struct clk *clk, uint8_t *index) static int clk_sscg_pll_set_parent(struct clk *clk, uint8_t index) { - // struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); + /* struct clk_sscg_pll_data *data = (struct clk_sscg_pll_data *)(clk->data); */ /* TODO: This operation is based on `setup.bypass` instead of index * passed from callee, need to be decided by clock manager */ @@ -168,6 +235,27 @@ const struct clk_ops clk_sscg_pll_ops = { /* .determine_rate = clk_sscg_pll_determine_rate, */ }; +static int imx8mx_clk_composite_determine_rate(uint64_t rate, uint64_t parent_rate, uint32_t *prev_div, + uint32_t *post_div) +{ + uint32_t min_error = UINT_MAX; + int ret = CLK_FAILED_OP; + + for (int i = 1; i <= PCG_PREDIV_MAX; i++) { + for (int j = 1; j <= PCG_DIV_MAX; j++) { + uint32_t error = abs(((parent_rate / i) / j) - rate); + if (error < min_error) { + *prev_div = i; + *post_div = j; + min_error = error; + ret = 0; + } + } + } + + return ret; +} + static uint64_t imx8m_clk_core_slice_recalc_rate(const struct clk *clk, uint64_t prate) { struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); @@ -177,6 +265,15 @@ static uint64_t imx8m_clk_core_slice_recalc_rate(const struct clk *clk, uint64_t return DIV_ROUND_UP_ULL((uint64_t)prate, div_val + 1); } +static int imx8m_clk_core_slice_set_rate(const struct clk *clk, uint64_t rate, uint64_t parent_rate) +{ + struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); + + uint32_t div = DIV_ROUND_UP(parent_rate, rate) - 1; + + return regmap_update_bits(clk->base, data->offset, data->div_shift, MASK(data->div_width), div); +} + static int imx8m_clk_core_slice_get_parent(const struct clk *clk, uint8_t *index) { struct clk_core_slice_data *data = (struct clk_core_slice_data *)(clk->data); @@ -208,7 +305,7 @@ static int imx8m_clk_core_slice_set_parent(struct clk *clk, uint8_t index) const struct clk_ops clk_core_slice_ops = { .recalc_rate = imx8m_clk_core_slice_recalc_rate, /* .round_rate = imx8m_clk_core_slice_round_rate, */ - /* .set_rate = imx8m_clk_core_slice_set_rate, */ + .set_rate = imx8m_clk_core_slice_set_rate, /* .determine_rate = imx8m_clk_core_slice_determine_rate, */ .get_parent = imx8m_clk_core_slice_get_parent, .set_parent = imx8m_clk_core_slice_set_parent, @@ -227,6 +324,23 @@ static uint64_t imx8m_clk_common_slice_recalc_rate(const struct clk *clk, uint64 return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); } +static int imx8m_clk_common_slice_set_rate(const struct clk *clk, uint64_t rate, uint64_t parent_rate) +{ + struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); + uint32_t prev_div = 1; + uint32_t post_div = 1; + + int ret = imx8mx_clk_composite_determine_rate(rate, parent_rate, &prev_div, &post_div); + if (ret) + return ret; + + ret = regmap_update_bits(clk->base, data->offset, data->prevdiv_shift, MASK(data->prevdiv_width), prev_div); + if (ret) + return ret; + + return regmap_update_bits(clk->base, data->offset, data->postdiv_shift, MASK(data->postdiv_width), post_div); +} + static int imx8m_clk_common_slice_get_parent(const struct clk *clk, uint8_t *index) { struct clk_common_slice_data *data = (struct clk_common_slice_data *)(clk->data); @@ -258,7 +372,7 @@ static int imx8m_clk_common_slice_set_parent(struct clk *clk, uint8_t index) const struct clk_ops clk_common_slice_ops = { .recalc_rate = imx8m_clk_common_slice_recalc_rate, /* .round_rate = imx8m_clk_common_slice_round_rate, */ - /* .set_rate = imx8m_clk_common_slice_set_rate, */ + .set_rate = imx8m_clk_common_slice_set_rate, /* .determine_rate = imx8m_clk_common_slice_determine_rate, */ .get_parent = imx8m_clk_common_slice_get_parent, .set_parent = imx8m_clk_common_slice_set_parent, @@ -277,6 +391,23 @@ static uint64_t imx8m_clk_bus_slice_recalc_rate(const struct clk *clk, uint64_t return DIV_ROUND_UP_ULL((uint64_t)prediv_rate, postdiv_val + 1); } +static int imx8m_clk_bus_slice_set_rate(const struct clk *clk, uint64_t rate, uint64_t parent_rate) +{ + struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); + uint32_t prev_div = 1; + uint32_t post_div = 1; + + int ret = imx8mx_clk_composite_determine_rate(rate, parent_rate, &prev_div, &post_div); + if (ret) + return ret; + + ret = regmap_update_bits(clk->base, data->offset, data->prevdiv_shift, MASK(data->prevdiv_width), prev_div); + if (ret) + return ret; + + return regmap_update_bits(clk->base, data->offset, data->postdiv_shift, MASK(data->postdiv_width), post_div); +} + static int imx8m_clk_bus_slice_get_parent(const struct clk *clk, uint8_t *index) { struct clk_bus_slice_data *data = (struct clk_bus_slice_data *)(clk->data); @@ -308,7 +439,7 @@ static int imx8m_clk_bus_slice_set_parent(struct clk *clk, uint8_t index) const struct clk_ops clk_bus_slice_ops = { .recalc_rate = imx8m_clk_bus_slice_recalc_rate, /* .round_rate = imx8m_clk_composite_divider_round_rate, */ - /* .set_rate = imx8m_clk_composite_divider_set_rate, */ + .set_rate = imx8m_clk_bus_slice_set_rate, /* .determine_rate = imx8m_divider_determine_rate, */ .get_parent = imx8m_clk_bus_slice_get_parent, .set_parent = imx8m_clk_bus_slice_set_parent, diff --git a/drivers/clk/imx/clk.c b/drivers/clk/imx/clk.c index 0d6fc04b0..1a4836795 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/imx/clk.c @@ -293,16 +293,15 @@ void init(void) } } - /* TODO: Set rate for the target clock */ - /* if (clk_configs[i].frequency > 0) { */ - /* LOG_DRIVER("set rate for %s\n", clk->hw.init->name); */ - /* uint64_t rate = 0; */ - /* uint32_t err = clk_set_rate(clk, clk_configs[i].frequency, &rate); */ - /* if (err) { */ - /* LOG_DRIVER_ERR("Failed to set rate [%d] for clk_id: %d\n", clk_configs[i].frequency, clk_configs[i].clk_id); */ - /* } */ - /* LOG_DRIVER("------------------\n"); */ - /* } */ + if (clk_configs[i].frequency > 0) { + LOG_DRIVER("set rate for %s\n", clk->hw.init->name); + uint64_t rate = 0; + uint32_t err = clk_set_rate(clk, clk_configs[i].frequency, &rate); + if (err) { + LOG_DRIVER_ERR("Failed to set rate [%d] for clk_id: %d\n", clk_configs[i].frequency, + clk_configs[i].clk_id); + } + } } } diff --git a/drivers/clk/meson/clk-meson.c b/drivers/clk/meson/clk-meson.c index 374b6e73d..45399a334 100644 --- a/drivers/clk/meson/clk-meson.c +++ b/drivers/clk/meson/clk-meson.c @@ -73,26 +73,13 @@ #include #include #include -#include #include -#define TIMER_CH 1 - static inline uint32_t meson_parm_read(uint64_t base, struct parm parm) { return regmap_read_bits(base, parm.reg_off, parm.shift, MASK(parm.width)); } -/* TODO: Replace this doggy delay() with a standard interface */ -void delay_us(uint32_t us) -{ - uint64_t start_time = sddf_timer_time_now(TIMER_CH); - uint64_t now_time = start_time; - while (now_time - start_time < us) { - now_time = sddf_timer_time_now(TIMER_CH); - } -} - int regmap_multi_reg_write(uint64_t base, const struct reg_sequence *regs, int num_regs) { int i; @@ -185,13 +172,15 @@ static int meson_clk_pll_disable(struct clk *clk) return 0; } -const struct clk_ops meson_clk_pll_ops = { .init = meson_clk_pll_init, - .recalc_rate = meson_clk_pll_recalc_rate, +const struct clk_ops meson_clk_pll_ops = { + .init = meson_clk_pll_init, + .recalc_rate = meson_clk_pll_recalc_rate, /* .determine_rate = meson_clk_pll_determine_rate, */ /* .set_rate = meson_clk_pll_set_rate, */ - .is_enabled = meson_clk_pll_is_enabled, - .enable = meson_clk_pll_enable, - .disable = meson_clk_pll_disable }; + .is_enabled = meson_clk_pll_is_enabled, + .enable = meson_clk_pll_enable, + .disable = meson_clk_pll_disable, +}; const struct clk_ops meson_clk_pll_ro_ops = { .recalc_rate = meson_clk_pll_recalc_rate, @@ -293,12 +282,14 @@ static int meson_clk_pcie_pll_enable(struct clk *clk) return -1; } -const struct clk_ops meson_clk_pcie_pll_ops = { .init = meson_clk_pll_init, - .recalc_rate = meson_clk_pll_recalc_rate, +const struct clk_ops meson_clk_pcie_pll_ops = { + .init = meson_clk_pll_init, + .recalc_rate = meson_clk_pll_recalc_rate, /* .determine_rate = meson_clk_pll_determine_rate, */ - .is_enabled = meson_clk_pll_is_enabled, - .enable = meson_clk_pcie_pll_enable, - .disable = meson_clk_pll_disable }; + .is_enabled = meson_clk_pll_is_enabled, + .enable = meson_clk_pcie_pll_enable, + .disable = meson_clk_pll_disable, +}; struct vid_pll_div { unsigned int shift_val; From 8812739110f55bdad2eaf3d50d25d6cbd7b8ac88 Mon Sep 17 00:00:00 2001 From: Terry Bai Date: Thu, 21 Nov 2024 11:25:40 +1100 Subject: [PATCH 11/11] clk: reorganise files This commit reorgnises source files to allow more code to be shared for multiple boards. Refactor makefiles: - move objectives to clk_driver directory - use built-in CFLAGS in rules Temporary fixup for a zig build issue: create_clk_config.py cannot find the lazypath `zig-out/bin` when executing. The current solution is to create an install directory in advance, but it would be a bit of trouble to find the generated header file if someone want to read or modify it. Moved clock specifier binding files to `include/sddf/clk`, so the clients will be able to configure clocks with macro constants Signed-off-by: Terry Bai --- build.zig | 12 +- drivers/clk/{imx => }/clk.c | 78 +--- drivers/clk/clk.h | 27 ++ drivers/clk/imx/clk-imx8mq.c | 50 ++- drivers/clk/imx/clk_driver.mk | 25 +- drivers/clk/imx/include/clk-imx8mq.h | 11 + drivers/clk/meson/clk.c | 408 ------------------ drivers/clk/meson/clk_driver.mk | 25 +- drivers/clk/meson/include/clk-sm1.h | 11 + drivers/clk/meson/sm1-clk.c | 60 ++- examples/clk/client.c | 22 +- examples/clk/clk.mk | 5 +- .../sddf/clk}/g12a-bindings.h | 5 +- .../sddf/clk}/imx8mq-bindings.h | 0 14 files changed, 233 insertions(+), 506 deletions(-) rename drivers/clk/{imx => }/clk.c (87%) create mode 100644 drivers/clk/imx/include/clk-imx8mq.h delete mode 100644 drivers/clk/meson/clk.c create mode 100644 drivers/clk/meson/include/clk-sm1.h rename {drivers/clk/meson/include => include/sddf/clk}/g12a-bindings.h (99%) rename {drivers/clk/imx/include => include/sddf/clk}/imx8mq-bindings.h (100%) diff --git a/build.zig b/build.zig index 5efbaeeb1..04056f24d 100644 --- a/build.zig +++ b/build.zig @@ -225,7 +225,6 @@ fn addClockDriver( switch (class) { .meson => { const files: []const []const u8 = &.{ - "drivers/clk/meson/clk.c", "drivers/clk/meson/clk-meson.c", "drivers/clk/meson/clk-measure.c", "drivers/clk/meson/sm1-clk.c", @@ -234,7 +233,6 @@ fn addClockDriver( }, .imx => { const files: []const []const u8 = &.{ - "drivers/clk/imx/clk.c", "drivers/clk/imx/clk-imx.c", "drivers/clk/imx/clk-imx8mq.c", }; @@ -242,7 +240,10 @@ fn addClockDriver( }, } - const common_src_files = .{ "clk-operations.c" }; + const common_src_files = .{ + "clk-operations.c", + "clk.c", + }; inline for (common_src_files) |f| { driver.addCSourceFile(.{ @@ -250,6 +251,7 @@ fn addClockDriver( }); } + driver.defineCMacro(b.fmt("BOARD_CLASS_{s}", .{ @tagName(class) }), "1"); driver.addIncludePath(clk_config_include); driver.addIncludePath(b.path("include")); driver.addIncludePath(b.path("drivers/clk")); @@ -523,9 +525,9 @@ pub fn build(b: *std.Build) void { "python", "drivers/clk/create_clk_config.py", dtb_path, - clk_conf_include_option, }); // Creates a system command which runs the python interpreter - driver.step.dependOn(&clk_config.step); + const clk_config_include = clk_config.addOutputDirectoryArg("test"); + driver.addIncludePath(clk_config_include); b.installArtifact(driver); } diff --git a/drivers/clk/imx/clk.c b/drivers/clk/clk.c similarity index 87% rename from drivers/clk/imx/clk.c rename to drivers/clk/clk.c index 1a4836795..3b34f1b08 100644 --- a/drivers/clk/imx/clk.c +++ b/drivers/clk/clk.c @@ -11,12 +11,21 @@ #include #include #include - -#include -#include -#include -#include -#include +#include /* common definitions and interfaces */ +#include /* ops of common clocks e.g., div, mux, fixed factor, and gate*/ +#include /* configuration parsed from device tree */ + +#ifdef BOARD_CLASS_meson +#include /* operations for meson-specific clocks */ +#include /* implementation of clock measurements */ +#include /* g12a-specific definitions */ +#include /* offsets of control registers */ +#elif BOARD_CLASS_imx +#include /* operations for imx-specific clocks */ +#include /* imx8mq-specific definitions */ +#else +#error "The platform is not supported!\n" +#endif // Logging /* #define DEBUG_DRIVER */ @@ -29,15 +38,14 @@ #define LOG_DRIVER_ERR(...) do{ sddf_printf("CLK DRIVER|ERROR: "); sddf_printf(__VA_ARGS__); }while(0) -#define CLIENT_CH 0 +#ifndef NUM_CLK_LIST +#error "Constant \"NUM_CLK_LIST\" should be defined\n") +#endif -#define NUM_CLK_LIST IMX8MQ_CLK_END +#define CLIENT_CH 0 struct clk **clk_list; -uintptr_t ccm_base; -uintptr_t ccm_analog_base; - struct clk *get_clk_by_name(const char *name) { for (int i = 0; i < NUM_CLK_LIST; i++) { @@ -48,28 +56,6 @@ struct clk *get_clk_by_name(const char *name) return NULL; } -void clk_probe(struct clk *clk_list[]) -{ - for (int i = 0; i < NUM_CLK_LIST; i++) { - if (!clk_list[i]) { - continue; - } - - struct clk_init_data *init_data = clk_list[i]->hw.init; - - if (clk_list[i]->base == CCM_BASE) { - clk_list[i]->base = ccm_base; - } else if (clk_list[i]->base == CCM_ANALOG_BASE) { - clk_list[i]->base = ccm_analog_base; - } - - if (clk_list[i] && init_data->ops->init) { - init_data->ops->init(clk_list[i]); - LOG_DRIVER("Initialise %s\n", init_data->name); - } - } -} - const struct clk *get_parent(const struct clk *clk) { if (!clk) @@ -242,30 +228,6 @@ int clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) return CLK_INVALID_OP; } -int clk_msr_stat() -{ -#ifdef DEBUG_DRIVER - int i; - uint64_t rate = 0; - int err; - - LOG_DRIVER("-------Expected clock rates------\n"); - for (i = 0; i < NUM_CLK_LIST; i++) { - if (clk_list[i]) { - err = clk_get_rate(clk_list[i], &rate); - if (err) { - LOG_DRIVER_ERR("Failed to get rate of %s: -%u\n", clk_list[i]->hw.init->name, err); - return err; - } - LOG_DRIVER("[%4d][%10luHz] %s\n", i, rate, clk_list[i]->hw.init->name); - } - } - LOG_DRIVER("-----------------------------\n"); -#endif - - return 0; -} - void notified(microkit_channel ch) { } @@ -276,7 +238,7 @@ void init(void) clk_list = get_clk_list(); clk_probe(clk_list); - clk_msr_stat(); + clk_msr_stat(clk_list); for (int i = 0; i < NUM_DEVICE_CLKS; i++) { struct clk *clk = clk_list[clk_configs[i].clk_id]; diff --git a/drivers/clk/clk.h b/drivers/clk/clk.h index ffcedad6f..fc2c6d2ee 100644 --- a/drivers/clk/clk.h +++ b/drivers/clk/clk.h @@ -15,6 +15,17 @@ #define TIMER_CH 1 +// Logging +/* #define DEBUG_DRIVER */ + +#ifdef DEBUG_DRIVER +#define LOG_DRIVER(...) do{ sddf_dprintf("CLK DRIVER|INFO: "); sddf_dprintf(__VA_ARGS__); }while(0) +#else +#define LOG_DRIVER(...) do{}while(0) +#endif + +#define LOG_DRIVER_ERR(...) do{ sddf_printf("CLK DRIVER|ERROR: "); sddf_printf(__VA_ARGS__); }while(0) + /* * flags used across common struct clk. these flags should only affect the * top-level framework. custom flags for dealing with hardware specifics @@ -324,6 +335,15 @@ struct clk_mux_data { uint8_t flags; }; +/** + * function clk_msr_stat() - measure clock rates + * + * @clk_list: array of pointers to the clocks on SoC + * + * All parent clocks will be parsed by name and bound to the struct clk + */ +int clk_msr_stat(struct clk *clk_list[]); + /** * function clk_probe() - initialise all clocks * @@ -333,6 +353,13 @@ struct clk_mux_data { */ void clk_probe(struct clk *clk_list[]); +/** + * function get_clk_list() - initialise all clocks + * + * get a list of clock components for specific board + */ +struct clk **get_clk_list(); + /** * function get_parent() - get the current parent clk * diff --git a/drivers/clk/imx/clk-imx8mq.c b/drivers/clk/imx/clk-imx8mq.c index fc484147e..1a5406457 100644 --- a/drivers/clk/imx/clk-imx8mq.c +++ b/drivers/clk/imx/clk-imx8mq.c @@ -6,11 +6,14 @@ #include #include -#include #include #include #include #include +#include + +uintptr_t ccm_base; +uintptr_t ccm_analog_base; static struct clk_parent_data pll_ref_sels[] = { { @@ -2903,7 +2906,52 @@ static struct clk *imx8mq_clks[IMX8MQ_CLK_END] = { [IMX8MQ_CLK_DRAM_ALT_ROOT] = &dram_alt_root, }; +int clk_msr_stat(struct clk *clk_list[]) +{ +#ifdef DEBUG_DRIVER + int i; + uint64_t rate = 0; + int err; + + LOG_DRIVER("-------Expected clock rates------\n"); + for (i = 0; i < NUM_CLK_LIST; i++) { + if (clk_list[i]) { + err = clk_get_rate(clk_list[i], &rate); + if (err) { + LOG_DRIVER_ERR("Failed to get rate of %s: -%u\n", clk_list[i]->hw.init->name, err); + return err; + } + LOG_DRIVER("[%4d][%10luHz] %s\n", i, rate, clk_list[i]->hw.init->name); + } + } + LOG_DRIVER("-----------------------------\n"); +#endif + + return 0; +} + struct clk **get_clk_list(void) { return imx8mq_clks; } + +void clk_probe(struct clk *clk_list[]) +{ + for (int i = 0; i < NUM_CLK_LIST; i++) { + if (!clk_list[i]) { + continue; + } + + struct clk_init_data *init_data = clk_list[i]->hw.init; + + if (clk_list[i]->base == CCM_BASE) { + clk_list[i]->base = ccm_base; + } else if (clk_list[i]->base == CCM_ANALOG_BASE) { + clk_list[i]->base = ccm_analog_base; + } + + if (clk_list[i] && init_data->ops->init) { + init_data->ops->init(clk_list[i]); + } + } +} diff --git a/drivers/clk/imx/clk_driver.mk b/drivers/clk/imx/clk_driver.mk index b4d906d8e..624ab5ac1 100644 --- a/drivers/clk/imx/clk_driver.mk +++ b/drivers/clk/imx/clk_driver.mk @@ -4,25 +4,28 @@ # SPDX-License-Identifier: BSD-2-Clause CLK_DRIVER_DIR := $(dir $(lastword $(MAKEFILE_LIST))) -CLK_DRIVER_COMMON_DIR := $(SDDF)/drivers/clk CLK_CONFIG_HEADER := $(BUILD_DIR)/clk_config.h CLK_DRIVER_CONF_INC := $(SDDF)/include/sddf/clk CLK_DRIVER_INC := $(CLK_DRIVER_DIR)/include +CLK_DRIVER_COMMON_DIR := $(SDDF)/drivers/clk/ -CLK_DRIVER_OBJS := clk.o clk-operations.o clk-imx8mq.o clk-imx.o +CLK_DRIVER_BOARD_SOURCES := clk-imx.c clk-imx8mq.c +CLK_DRIVER_COMMON_SOURCES := clk.c clk-operations.c +CLK_DRIVER_SOURCES := $(addprefix $(CLK_DRIVER_DIR), $(CLK_DRIVER_BOARD_SOURCES)) \ + $(addprefix $(CLK_DRIVER_COMMON_DIR), $(CLK_DRIVER_COMMON_SOURCES)) +CLK_DRIVER_OBJS = $(patsubst $(CLK_DRIVER_COMMON_DIR)%.c, clk_driver/%.o, $(CLK_DRIVER_SOURCES)) -clk_driver.elf: $(CLK_DRIVER_OBJS) libsddf_util_debug.a - $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ - - -$(CLK_DRIVER_OBJS): ${CLK_DRIVER_COMMON_DIR}/*.c ${CLK_DRIVER_DIR}/*.c $(CLK_CONFIG_HEADER) - $(CC) -c $(CFLAGS) \ - -I${CLK_DRIVER_INC} \ +$(CLK_DRIVER_OBJS): CFLAGS += -I${CLK_DRIVER_INC} \ -I${CLK_DRIVER_CONF_INC} \ - -I${CLK_DRIVER_COMMON_DIR} \ -I${BUILD_DIR} \ -I${UART_DRIVER_DIR}/include \ - -I${CLK_DRIVER_COMMON_DIR} $^ + -I${CLK_DRIVER_COMMON_DIR} +clk_driver/%.o: $(CLK_DRIVER_COMMON_DIR)/%.c $(CLK_CONFIG_HEADER) + mkdir -p $(dir $@) + $(CC) -c $(CFLAGS) -o $@ $< + +clk_driver.elf: $(CLK_DRIVER_OBJS) libsddf_util_debug.a + $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ $(CLK_CONFIG_HEADER): $(DTS_FILE) $(CLK_DRIVER_COMMON_DIR)/create_clk_config.py $(PYTHON) $(CLK_DRIVER_COMMON_DIR)/create_clk_config.py $(DTS_FILE) $(BUILD_DIR) diff --git a/drivers/clk/imx/include/clk-imx8mq.h b/drivers/clk/imx/include/clk-imx8mq.h new file mode 100644 index 000000000..4140ce3cb --- /dev/null +++ b/drivers/clk/imx/include/clk-imx8mq.h @@ -0,0 +1,11 @@ +/* + * Copyright 2024, UNSW + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +#define NUM_CLK_LIST IMX8MQ_CLK_END diff --git a/drivers/clk/meson/clk.c b/drivers/clk/meson/clk.c deleted file mode 100644 index 05a72ccb5..000000000 --- a/drivers/clk/meson/clk.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright 2024, UNSW - * - * SPDX-License-Identifier: BSD-2-Clause - * - * Terry Bai: tianyi.bai@unsw.edu.au - */ - -#include -#include -#include -#include -#include -#include - -#include /* common definitions and interfaces */ -#include /* ops of common clocks e.g., div, mux, fixed factor, and gate*/ -#include /* implementation of clock measurements */ -#include /* operations for meson-specific clocks */ -#include /* offsets of control registers */ -#include /* clock id bindings*/ - -// Logging -/* #define DEBUG_DRIVER */ - -#ifdef DEBUG_DRIVER -#define LOG_DRIVER(...) do{ sddf_dprintf("CLK DRIVER|INFO: "); sddf_dprintf(__VA_ARGS__); }while(0) -#else -#define LOG_DRIVER(...) do{}while(0) -#endif - -#define LOG_DRIVER_ERR(...) do{ sddf_printf("CLK DRIVER|ERROR: "); sddf_printf(__VA_ARGS__); }while(0) - -#define NUM_CLK_LIST 280 - -#define I2C_CLK_OFFSET 320 -#define I2C_CLK_BIT (1 << 9) // bit 9 - -uintptr_t clk_regs; -uintptr_t msr_clk_base; - -struct clk **clk_list; - -struct clk *get_clk_by_name(const char *name) -{ - for (int i = 0; i < NUM_CLK_LIST; i++) { - if (clk_list[i] && sddf_strcmp(clk_list[i]->hw.init->name, name) == 0) { - return clk_list[i]; - } - } - return NULL; -} - -/* TODO: Should be configured with init_regs */ -/* static struct clk_cfg fixed_clk_configs[] = { */ -/* { .clk_id = CLKID_FCLK_DIV2_DIV, .frequency = 1000000000 }, */ -/* { .clk_id = CLKID_FCLK_DIV3_DIV, .frequency = 666666667 }, */ -/* { .clk_id = CLKID_FCLK_DIV4_DIV, .frequency = 500000000 }, */ -/* { .clk_id = CLKID_FCLK_DIV5_DIV, .frequency = 400000000 }, */ -/* { .clk_id = CLKID_FCLK_DIV7_DIV, .frequency = 285700000 }, */ -/* } */ - -void clk_probe(struct clk *clk_list[]) -{ - int i; - for (i = 0; i < NUM_CLK_LIST; i++) { - if (!clk_list[i]) - continue; - clk_list[i]->base = (uint64_t)clk_regs; - if (clk_list[i]->hw.init->ops->init) { - clk_list[i]->hw.init->ops->init(clk_list[i]); - LOG_DRIVER("Initialise %s\n", clk_list[i]->hw.init->name); - } - } -} - -const struct clk *get_parent(const struct clk *clk) -{ - if (!clk) - return NULL; - - const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; - uint32_t num_parents = init->num_parents; - - if (init->parent_data) { - uint8_t parent_idx = 0; - int err = num_parents > 1 ? init->ops->get_parent(clk, &parent_idx) : 0; - if (err) - return NULL; - - struct clk_parent_data parent_data = init->parent_data[parent_idx]; - - if (parent_data.clk) { - return parent_data.clk; - } else if (sddf_strcmp(parent_data.name, "xtal") == 0) { - return clk_list[CLKID_G12A_XTAL]; - } - } - - if (num_parents > 0) { - return init->parent_clks[0]; - } - - return NULL; -} - -int clk_get_parent_id(const struct clk *clk, uint32_t *parent_clk_id) -{ - if (!clk) - return CLK_UNKNOWN_TARGET; - - const struct clk *pclk = get_parent(clk); - - if (pclk == NULL) - return CLK_INVALID_OP; - - for (int i = 0; i < NUM_CLK_LIST; i++) { - if (pclk == clk_list[i]) { - *parent_clk_id = i; - return 0; - } - } - - return CLK_UNKNOWN_TARGET; -} - -/* The user needs to know which parent clock the value represents, and check - * if the target parent clock is configured correctly with clk_get_parent() */ -int clk_set_parent_by_val(struct clk *clk, uint32_t parent_idx) -{ - if (!clk) - return CLK_UNKNOWN_TARGET; - - const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; - if (init->ops->set_parent) { - init->ops->set_parent(clk, parent_idx); - return 0; - } - return CLK_INVALID_OP; -} - -int clk_set_parent_by_id(struct clk *clk, uint32_t pclk_id) -{ - const struct clk *pclk = clk_list[pclk_id]; - const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; - uint32_t num_parents = init->num_parents; - for (int i = 0; i < num_parents; i++) { - if (init->parent_clks && init->parent_clks[i] == pclk) { - return clk_set_parent_by_val(clk, i); - } else if (get_clk_by_name(init->parent_data[i].name) == pclk) { - return clk_set_parent_by_val(clk, i); - } - } - - return CLK_UNKNOWN_TARGET; -} - -/* TODO: Should be just read from the structure, but need to update everytime when */ -/* related clocks are modified */ -int clk_get_rate(const struct clk *clk, uint64_t *rate) -{ - if (!clk) - return CLK_UNKNOWN_TARGET; - - const struct clk_init_data *init = (struct clk_init_data *)clk->hw.init; - uint64_t parent_rate = 0; - int err = 0; - - const struct clk *parent_clk = get_parent(clk); - if (parent_clk) { - err = clk_get_rate(parent_clk, &parent_rate); - } - - if (err) - return err; - - *rate = parent_rate; - if (init->ops->recalc_rate) { - *rate = init->ops->recalc_rate(clk, parent_rate); - } - - return 0; -} - -int clk_enable(struct clk *clk) -{ - if (!clk) - return CLK_UNKNOWN_TARGET; - - if (clk->hw.init->ops->enable != NULL) { - return clk->hw.init->ops->enable(clk); - } - - return CLK_INVALID_OP; -} - -int clk_disable(struct clk *clk) -{ - if (!clk) - return CLK_UNKNOWN_TARGET; - - if (clk->hw.init->ops->disable != NULL) { - return clk->hw.init->ops->disable(clk); - } - - return CLK_INVALID_OP; -} - -int clk_set_rate(struct clk *clk, uint64_t req_rate, uint64_t *rate) -{ - if (!clk) - return CLK_UNKNOWN_TARGET; - - /* TODO: we only propagate request to one level up. More operations need to be - * invoked by clients until a dynamic configration algorithm implemented */ - if (clk->hw.init->ops->init) { - clk->hw.init->ops->init(clk); - } - - const struct clk *pclk = get_parent(clk); - uint64_t prate = 0; - int err = clk_get_rate(pclk, &prate); - if (err) { - LOG_DRIVER_ERR("Failed to get parent clock's rate\n"); - return err; - } - - if (clk->hw.init->ops->set_rate) { - clk->hw.init->ops->set_rate(clk, req_rate, prate); - *rate = req_rate; - return 0; - } - if (pclk->hw.init->ops->set_rate) { - const struct clk *ppclk = get_parent(pclk); - uint64_t pprate = 0; - int err = clk_get_rate(ppclk, &pprate); - if (!err) { - pclk->hw.init->ops->set_rate(pclk, prate, pprate); - *rate = req_rate; - return 0; - } - return err; - } - - return CLK_INVALID_OP; -} - -int clk_msr_stat() -{ -#ifdef DEBUG_DRIVER - unsigned long clk_freq; - int i = 0; - uint64_t rate = 0; - int err; - - const char *const *clk_msr_list = get_msr_clk_list(); - - LOG_DRIVER("-------Expected clock rates------\n"); - for (i = 0; i < NUM_CLK_LIST; i++) { - err = clk_get_rate(clk_list[i], &rate); - if (err) { - LOG_DRIVER("Failed to get rate of %s: -%u\n", clk_list[i]->hw.init->name, err); - } - LOG_DRIVER("[%4d][%4luHz] %s\n", i, rate, clk_list[i]->hw.init->name); - } - LOG_DRIVER("---------------------------------\n"); - LOG_DRIVER("---------Clock measurement-------\n"); - for (i = 0; i < 128; i++) { - clk_freq = clk_msr(i); - LOG_DRIVER("[%4d][%4ldHz] %s\n", i, clk_freq, clk_msr_list[i]); - } - LOG_DRIVER("-----------------------------\n"); - -#endif - - return 0; -} - -void notified(microkit_channel ch) -{ -} - -void init(void) -{ - LOG_DRIVER("Clock driver initialising...\n"); - - int err = 0; - clk_list = get_clk_list(); - - clk_probe(clk_list); - clk_msr_stat(); - - for (int i = 0; i < NUM_DEVICE_CLKS; i++) { - struct clk *clk = clk_list[clk_configs[i].clk_id]; - - /* Enable the clock */ - clk_enable(clk); - - /* Set parent for clocks as configured in device tree */ - if (clk_configs[i].pclk_id) { - err = clk_set_parent_by_id(clk, clk_configs[i].pclk_id); - if (err) { - LOG_DRIVER_ERR("Failed to set parent %u for clock %u: err - %d\n", clk_configs[i].pclk_id, - clk_configs[i].clk_id, err); - } - } - - /* Set rate for the target clock */ - if (clk_configs[i].frequency > 0) { - uint64_t rate = 0; - int err = clk_set_rate(clk, clk_configs[i].frequency, &rate); - if (err) { - LOG_DRIVER_ERR("Failed to set rate [%d] for clk_id: %d\n", clk_configs[i].frequency, - clk_configs[i].clk_id); - } - } - } -} - -microkit_msginfo protected(microkit_channel ch, microkit_msginfo msginfo) -{ - int err = 0; - uint32_t ret_num = 0; - uint32_t argc = microkit_msginfo_get_count(msginfo); - - /* TODO: Check if the channel is valid */ - switch (microkit_msginfo_get_label(msginfo)) { - - case SDDF_CLK_ENABLE: { - if (argc != 1) { - LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - err = CLK_INCORRECT_ARGS; - break; - } - uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - LOG_DRIVER("get request clk_enable(%d)\n", clk_id); - err = clk_enable(clk_list[clk_id]); - break; - } - case SDDF_CLK_DISABLE: { - if (argc != 1) { - LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - err = CLK_INCORRECT_ARGS; - break; - } - uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - LOG_DRIVER("get request clk_disable(%d)\n", clk_id); - err = clk_disable(clk_list[clk_id]); - break; - } - case SDDF_CLK_GET_RATE: { - if (argc != 1) { - LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - err = CLK_INCORRECT_ARGS; - break; - } - uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - uint64_t rate = 0; - err = clk_get_rate(clk_list[clk_id], &rate); - microkit_mr_set(0, rate); - ret_num = 1; - break; - } - case SDDF_CLK_SET_RATE: { - if (argc != 2) { - LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - err = CLK_INCORRECT_ARGS; - break; - } - uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - uint32_t req_rate = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_RATE); - uint64_t rate = 0; - err = clk_set_rate(clk_list[clk_id], req_rate, &rate); - microkit_mr_set(0, rate); - ret_num = 1; - break; - } - case SDDF_CLK_GET_PARENT: { - if (argc != 1) { - LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - err = CLK_INCORRECT_ARGS; - break; - } - uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - uint32_t pclk_id = 0; - err = clk_get_parent_id(clk_list[clk_id], &pclk_id); - microkit_mr_set(0, pclk_id); - ret_num = 1; - break; - } - case SDDF_CLK_SET_PARENT: { - if (argc != 2) { - LOG_DRIVER_ERR("Incorrect number of arguments %u != 1\n", argc); - err = CLK_INCORRECT_ARGS; - break; - } - uint32_t clk_id = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_ID); - uint32_t pclk_idx = (uint32_t)microkit_mr_get(SDDF_CLK_PARAM_PCLK_IDX); - err = clk_set_parent_by_val(clk_list[clk_id], pclk_idx); - break; - } - default: - LOG_DRIVER_ERR("Unknown request %lu to clockk driver from channel %u\n", microkit_msginfo_get_label(msginfo), - ch); - err = CLK_UNKNOWN_REQ; - } - return microkit_msginfo_new(err, ret_num); -} diff --git a/drivers/clk/meson/clk_driver.mk b/drivers/clk/meson/clk_driver.mk index 379d43454..9e147ba08 100644 --- a/drivers/clk/meson/clk_driver.mk +++ b/drivers/clk/meson/clk_driver.mk @@ -7,21 +7,26 @@ CLK_DRIVER_DIR := $(dir $(lastword $(MAKEFILE_LIST))) CLK_CONFIG_HEADER := $(BUILD_DIR)/clk_config.h CLK_DRIVER_CONF_INC := $(SDDF)/include/sddf/clk CLK_DRIVER_INC := $(CLK_DRIVER_DIR)/include -CLK_DRIVER_COMMON_DIR := $(SDDF)/drivers/clk +CLK_DRIVER_COMMON_DIR := $(SDDF)/drivers/clk/ -CLK_DRIVER_OBJS := clk.o clk-operations.o clk-measure.o clk-meson.o sm1-clk.o +CLK_DRIVER_BOARD_SOURCES := clk-measure.c clk-meson.c sm1-clk.c +CLK_DRIVER_COMMON_SOURCES := clk.c clk-operations.c +CLK_DRIVER_SOURCES := $(addprefix $(CLK_DRIVER_DIR), $(CLK_DRIVER_BOARD_SOURCES)) \ + $(addprefix $(CLK_DRIVER_COMMON_DIR), $(CLK_DRIVER_COMMON_SOURCES)) +CLK_DRIVER_OBJS = $(patsubst $(CLK_DRIVER_COMMON_DIR)%.c, clk_driver/%.o, $(CLK_DRIVER_SOURCES)) + +$(CLK_DRIVER_OBJS): CFLAGS += -I${CLK_DRIVER_INC} \ + -I${CLK_DRIVER_CONF_INC} \ + -I${BUILD_DIR} \ + -I${UART_DRIVER_DIR}/include \ + -I${CLK_DRIVER_COMMON_DIR} +clk_driver/%.o: $(CLK_DRIVER_COMMON_DIR)/%.c $(CLK_CONFIG_HEADER) + mkdir -p $(dir $@) + $(CC) -c $(CFLAGS) -o $@ $< clk_driver.elf: $(CLK_DRIVER_OBJS) libsddf_util_debug.a $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ -$(CLK_DRIVER_OBJS): ${CLK_DRIVER_COMMON_DIR}/*.c ${CLK_DRIVER_DIR}/*.c $(CLK_CONFIG_HEADER) - $(CC) -c $(CFLAGS) \ - -I${CLK_DRIVER_INC} \ - -I${CLK_DRIVER_CONF_INC} \ - -I${BUILD_DIR} \ - -I${UART_DRIVER_DIR}/include \ - -I${CLK_DRIVER_COMMON_DIR} $^ - $(CLK_CONFIG_HEADER): $(DTS_FILE) $(CLK_DRIVER_COMMON_DIR)/create_clk_config.py $(PYTHON) $(CLK_DRIVER_COMMON_DIR)/create_clk_config.py $(DTS_FILE) $(BUILD_DIR) diff --git a/drivers/clk/meson/include/clk-sm1.h b/drivers/clk/meson/include/clk-sm1.h new file mode 100644 index 000000000..1ac3e05eb --- /dev/null +++ b/drivers/clk/meson/include/clk-sm1.h @@ -0,0 +1,11 @@ +/* + * Copyright 2024, UNSW + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +#define NUM_CLK_LIST 280 diff --git a/drivers/clk/meson/sm1-clk.c b/drivers/clk/meson/sm1-clk.c index 55d2ac5f8..a47bb4ae4 100644 --- a/drivers/clk/meson/sm1-clk.c +++ b/drivers/clk/meson/sm1-clk.c @@ -14,11 +14,15 @@ #include #include -#include #include #include +#include #include #include +#include + +uintptr_t clk_regs; +uintptr_t msr_clk_base; static struct clk g12a_xtal = { .data = &(struct clk_source_data) { @@ -1528,6 +1532,60 @@ static struct clk *sm1_clks[] = { [CLKID_G12A_XTAL] = &g12a_xtal, }; +int clk_msr_stat(struct clk *clk_list[]) +{ +#ifdef DEBUG_DRIVER + unsigned long clk_freq; + int i = 0; + uint64_t rate = 0; + int err; + + const char *const *clk_msr_list = get_msr_clk_list(); + + LOG_DRIVER("-------Expected clock rates------\n"); + for (i = 0; i < NUM_CLK_LIST; i++) { + err = clk_get_rate(clk_list[i], &rate); + if (err) { + LOG_DRIVER("Failed to get rate of %s: -%u\n", clk_list[i]->hw.init->name, err); + } + LOG_DRIVER("[%4d][%4luHz] %s\n", i, rate, clk_list[i]->hw.init->name); + } + LOG_DRIVER("---------------------------------\n"); + LOG_DRIVER("---------Clock measurement-------\n"); + for (i = 0; i < 128; i++) { + clk_freq = clk_msr(i); + LOG_DRIVER("[%4d][%4ldHz] %s\n", i, clk_freq, clk_msr_list[i]); + } + LOG_DRIVER("-----------------------------\n"); + +#endif + + return 0; +} + +/* TODO: Should be configured with init_regs */ +/* static struct clk_cfg fixed_clk_configs[] = { */ +/* { .clk_id = CLKID_FCLK_DIV2_DIV, .frequency = 1000000000 }, */ +/* { .clk_id = CLKID_FCLK_DIV3_DIV, .frequency = 666666667 }, */ +/* { .clk_id = CLKID_FCLK_DIV4_DIV, .frequency = 500000000 }, */ +/* { .clk_id = CLKID_FCLK_DIV5_DIV, .frequency = 400000000 }, */ +/* { .clk_id = CLKID_FCLK_DIV7_DIV, .frequency = 285700000 }, */ +/* } */ + +void clk_probe(struct clk *clk_list[]) +{ + int i; + for (i = 0; i < NUM_CLK_LIST; i++) { + if (!clk_list[i]) + continue; + clk_list[i]->base = (uint64_t)clk_regs; + if (clk_list[i]->hw.init->ops->init) { + clk_list[i]->hw.init->ops->init(clk_list[i]); + LOG_DRIVER("Initialise %s\n", clk_list[i]->hw.init->name); + } + } +} + struct clk **get_clk_list(void) { return sm1_clks; diff --git a/examples/clk/client.c b/examples/clk/client.c index e68219b54..4b6e21bc7 100644 --- a/examples/clk/client.c +++ b/examples/clk/client.c @@ -11,6 +11,14 @@ #define CLK_DRIVER_CH 0 +#ifdef TEST_BOARD_odroidc4 +#include +#elif TEST_BOARD_maaxboard +#include +#else +#error "The target board is not supported\n" +#endif + void init(void) { sddf_dprintf("--------------------\n"); @@ -27,7 +35,7 @@ void init(void) * see `sddf/drivers/clk/meson/include/g12a-bindings.h` for more clock indices. * **/ - uint32_t clk_id_to_enable = 10; + uint32_t clk_id_to_enable = CLKID_CLK81; int ret = sddf_clk_enable(CLK_DRIVER_CH, clk_id_to_enable); if (ret) { sddf_dprintf("Failed to enable clock %u: err - %d\n", clk_id_to_enable, ret); @@ -35,7 +43,7 @@ void init(void) sddf_dprintf("Successfully enabled clock %u\n", clk_id_to_enable); } - uint32_t clk_id_to_disable = 24; + uint32_t clk_id_to_disable = CLKID_I2C; ret = sddf_clk_disable(CLK_DRIVER_CH, clk_id_to_disable); if (ret) { sddf_dprintf("Failed to disable clock %u: err - %d\n", clk_id_to_enable, ret); @@ -44,7 +52,7 @@ void init(void) } uint64_t rate = 0; - uint32_t clk_id_to_set_rate = 10; + uint32_t clk_id_to_set_rate = CLKID_CLK81; ret = sddf_clk_get_rate(CLK_DRIVER_CH, clk_id_to_set_rate, &rate); if (ret) { sddf_dprintf("Failed to get the rate of clock %u: err - %d\n", clk_id_to_set_rate, ret); @@ -59,7 +67,7 @@ void init(void) sddf_dprintf("Set the rate of clock %u to %lu\n", ret, rate); } - uint32_t clk_id_to_get_rate = 187; + uint32_t clk_id_to_get_rate = CLKID_CPU_CLK; ret = sddf_clk_get_rate(CLK_DRIVER_CH, clk_id_to_get_rate, &rate); if (ret) { sddf_dprintf("Failed to get the rate of clock %u: err - %d\n", clk_id_to_get_rate, ret); @@ -67,7 +75,7 @@ void init(void) sddf_dprintf("The rate of clock %u: %lu\n", clk_id_to_get_rate, rate); } - uint32_t clk_id_to_test_parent = 63; + uint32_t clk_id_to_test_parent = CLKID_SD_EMMC_A_CLK0_SEL; uint32_t parent_id = 0; ret = sddf_clk_get_parent(CLK_DRIVER_CH, clk_id_to_test_parent, &parent_id); if (ret) { @@ -96,7 +104,7 @@ void init(void) * see `sddf/drivers/clk/imx/include/imx8mq-bindings.h` for more clock indices. * */ - uint32_t clk_id_to_enable = 196; + uint32_t clk_id_to_enable = IMX8MQ_CLK_SAI1_ROOT; ret = sddf_clk_enable(CLK_DRIVER_CH, clk_id_to_enable); if (ret) { sddf_dprintf("Failed to enable clock %u: err - %d\n", clk_id_to_enable, ret); @@ -104,7 +112,7 @@ void init(void) sddf_dprintf("Successfully enabled clock %u\n", clk_id_to_enable); } - uint32_t clk_id_to_test_parent = 144; + uint32_t clk_id_to_test_parent = IMX8MQ_CLK_I2C1; uint32_t parent_id = 0; ret = sddf_clk_get_parent(CLK_DRIVER_CH, clk_id_to_test_parent, &parent_id); if (ret) { diff --git a/examples/clk/clk.mk b/examples/clk/clk.mk index df895982a..258e6f25c 100644 --- a/examples/clk/clk.mk +++ b/examples/clk/clk.mk @@ -15,12 +15,14 @@ ifeq ($(strip $(MICROKIT_BOARD)), odroidc4) SYSTEM_FILE := ${TOP}/board/odroidc4/clk.system ARCH := aarch64 DRIVER_DIR := meson + DRIVER_CLASS := meson CPU := cortex-a55 else ifeq ($(strip $(MICROKIT_BOARD)), maaxboard) ARCH := aarch64 DTS_FILE := $(TOP)/dts/maaxboard.dts SYSTEM_FILE := ${TOP}/board/maaxboard/clk.system DRIVER_DIR := imx + DRIVER_CLASS := imx CPU := cortex-a53 else $(error Unsupported MICROKIT_BOARD given) @@ -52,7 +54,8 @@ CFLAGS := -mcpu=$(CPU) \ -I$(BOARD_DIR)/include \ -I$(SDDF)/include \ -I$(LIBMICROKITCO_PATH) \ - -I$(TOP) + -I$(TOP) \ + -DBOARD_CLASS_$(DRIVER_CLASS) LDFLAGS := -L$(BOARD_DIR)/lib -L. LIBS := --start-group -lmicrokit -Tmicrokit.ld libsddf_util_debug.a --end-group diff --git a/drivers/clk/meson/include/g12a-bindings.h b/include/sddf/clk/g12a-bindings.h similarity index 99% rename from drivers/clk/meson/include/g12a-bindings.h rename to include/sddf/clk/g12a-bindings.h index df04e4de0..f987c8e5a 100644 --- a/drivers/clk/meson/include/g12a-bindings.h +++ b/include/sddf/clk/g12a-bindings.h @@ -7,8 +7,7 @@ * Source: https://github.com/torvalds/linux/blob/20371ba120635d9ab7fc7670497105af8f33eb08/include/dt-bindings/clock/g12a-clkc.h */ -#ifndef __G12A_CLKC_H -#define __G12A_CLKC_H +#pragma once #define CLKID_SYS_PLL 0 #define CLKID_FIXED_PLL 1 @@ -291,5 +290,3 @@ #define CLKID_MIPI_ISP_CSI_PHY1 278 #define CLKID_G12A_XTAL 279 - -#endif /* __G12A_CLKC_H */ diff --git a/drivers/clk/imx/include/imx8mq-bindings.h b/include/sddf/clk/imx8mq-bindings.h similarity index 100% rename from drivers/clk/imx/include/imx8mq-bindings.h rename to include/sddf/clk/imx8mq-bindings.h