Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 172e9534 authored by Jerome Brunet's avatar Jerome Brunet Committed by Neil Armstrong
Browse files

clk: meson: axg-ao: add 32k generation subtree



Add the clock subtree generating the 32k clock in amlogic axg ao block.

Signed-off-by: default avatarJerome Brunet <jbrunet@baylibre.com>
Acked-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Signed-off-by: default avatarNeil Armstrong <narmstrong@baylibre.com>
Link: https://lkml.kernel.org/r/20181221160239.26265-6-jbrunet@baylibre.com
parent b249623f
Loading
Loading
Loading
Loading
+162 −13
Original line number Diff line number Diff line
@@ -12,10 +12,23 @@
#include <linux/platform_device.h>
#include <linux/reset-controller.h>
#include <linux/mfd/syscon.h>
#include "clk-regmap.h"
#include "clkc.h"
#include "meson-aoclk.h"
#include "axg-aoclk.h"

/*
 * AO Configuration Clock registers offsets
 * Register offsets from the data sheet must be multiplied by 4.
 */
#define AO_RTI_PWR_CNTL_REG1	0x0C
#define AO_RTI_PWR_CNTL_REG0	0x10
#define AO_RTI_GEN_CNTL_REG0	0x40
#define AO_OSCIN_CNTL		0x58
#define AO_CRT_CLK_CNTL1	0x68
#define AO_SAR_CLK		0x90
#define AO_RTC_ALT_CLK_CNTL0	0x94
#define AO_RTC_ALT_CLK_CNTL1	0x98

#define AXG_AO_GATE(_name, _bit)					\
static struct clk_regmap axg_aoclk_##_name = {				\
	.data = &(struct clk_regmap_gate_data) {			\
@@ -39,17 +52,141 @@ AXG_AO_GATE(uart2, 5);
AXG_AO_GATE(ir_blaster, 6);
AXG_AO_GATE(saradc, 7);

static struct clk_regmap axg_aoclk_cts_oscin = {
	.data = &(struct clk_regmap_gate_data){
		.offset = AO_RTI_PWR_CNTL_REG0,
		.bit_idx = 14,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cts_oscin",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_names = (const char *[]){ "xtal" },
		.num_parents = 1,
	},
};

static struct clk_regmap axg_aoclk_32k_pre = {
	.data = &(struct clk_regmap_gate_data){
		.offset = AO_RTC_ALT_CLK_CNTL0,
		.bit_idx = 31,
	},
	.hw.init = &(struct clk_init_data){
		.name = "axg_ao_32k_pre",
		.ops = &clk_regmap_gate_ops,
		.parent_names = (const char *[]){ "cts_oscin" },
		.num_parents = 1,
	},
};

static const struct meson_clk_dualdiv_param axg_32k_div_table[] = {
	{
		.dual	= 1,
		.n1	= 733,
		.m1	= 8,
		.n2	= 732,
		.m2	= 11,
	}, {}
};

static struct clk_regmap axg_aoclk_32k_div = {
	.data = &(struct meson_clk_dualdiv_data){
		.n1 = {
			.reg_off = AO_RTC_ALT_CLK_CNTL0,
			.shift   = 0,
			.width   = 12,
		},
		.n2 = {
			.reg_off = AO_RTC_ALT_CLK_CNTL0,
			.shift   = 12,
			.width   = 12,
		},
		.m1 = {
			.reg_off = AO_RTC_ALT_CLK_CNTL1,
			.shift   = 0,
			.width   = 12,
		},
		.m2 = {
			.reg_off = AO_RTC_ALT_CLK_CNTL1,
			.shift   = 12,
			.width   = 12,
		},
		.dual = {
			.reg_off = AO_RTC_ALT_CLK_CNTL0,
			.shift   = 28,
			.width   = 1,
		},
		.table = axg_32k_div_table,
	},
	.hw.init = &(struct clk_init_data){
		.name = "axg_ao_32k_div",
		.ops = &meson_clk_dualdiv_ops,
		.parent_names = (const char *[]){ "axg_ao_32k_pre" },
		.num_parents = 1,
	},
};

static struct clk_regmap axg_aoclk_32k_sel = {
	.data = &(struct clk_regmap_mux_data) {
		.offset = AO_RTC_ALT_CLK_CNTL1,
		.mask = 0x1,
		.shift = 24,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "axg_ao_32k_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_names = (const char *[]){ "axg_ao_32k_div",
						  "axg_ao_32k_pre" },
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap axg_aoclk_32k = {
	.data = &(struct clk_regmap_gate_data){
		.offset = AO_RTC_ALT_CLK_CNTL0,
		.bit_idx = 30,
	},
	.hw.init = &(struct clk_init_data){
		.name = "axg_ao_32k",
		.ops = &clk_regmap_gate_ops,
		.parent_names = (const char *[]){ "axg_ao_32k_sel" },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap axg_aoclk_cts_rtc_oscin = {
	.data = &(struct clk_regmap_mux_data) {
		.offset = AO_RTI_PWR_CNTL_REG0,
		.mask = 0x1,
		.shift = 10,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "axg_ao_cts_rtc_oscin",
		.ops = &clk_regmap_mux_ops,
		.parent_names = (const char *[]){ "axg_ao_32k",
						  "axg_ext_32k" },
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap axg_aoclk_clk81 = {
	.data = &(struct clk_regmap_mux_data) {
		.offset = AO_RTI_PWR_CNTL_REG0,
		.mask = 0x1,
		.shift = 8,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "axg_ao_clk81",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_names = (const char *[]){ "clk81", "ao_alt_xtal"},
		.parent_names = (const char *[]){ "clk81",
						  "axg_ao_cts_rtc_oscin"},
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

@@ -106,17 +243,23 @@ static const unsigned int axg_aoclk_reset[] = {
};

static struct clk_regmap *axg_aoclk_regmap[] = {
	[CLKID_AO_REMOTE]	= &axg_aoclk_remote,
	[CLKID_AO_I2C_MASTER]	= &axg_aoclk_i2c_master,
	[CLKID_AO_I2C_SLAVE]	= &axg_aoclk_i2c_slave,
	[CLKID_AO_UART1]	= &axg_aoclk_uart1,
	[CLKID_AO_UART2]	= &axg_aoclk_uart2,
	[CLKID_AO_IR_BLASTER]	= &axg_aoclk_ir_blaster,
	[CLKID_AO_SAR_ADC]	= &axg_aoclk_saradc,
	[CLKID_AO_CLK81]	= &axg_aoclk_clk81,
	[CLKID_AO_SAR_ADC_SEL]	= &axg_aoclk_saradc_mux,
	[CLKID_AO_SAR_ADC_DIV]	= &axg_aoclk_saradc_div,
	[CLKID_AO_SAR_ADC_CLK]	= &axg_aoclk_saradc_gate,
	&axg_aoclk_remote,
	&axg_aoclk_i2c_master,
	&axg_aoclk_i2c_slave,
	&axg_aoclk_uart1,
	&axg_aoclk_uart2,
	&axg_aoclk_ir_blaster,
	&axg_aoclk_saradc,
	&axg_aoclk_cts_oscin,
	&axg_aoclk_32k_pre,
	&axg_aoclk_32k_div,
	&axg_aoclk_32k_sel,
	&axg_aoclk_32k,
	&axg_aoclk_cts_rtc_oscin,
	&axg_aoclk_clk81,
	&axg_aoclk_saradc_mux,
	&axg_aoclk_saradc_div,
	&axg_aoclk_saradc_gate,
};

static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
@@ -132,6 +275,12 @@ static const struct clk_hw_onecell_data axg_aoclk_onecell_data = {
		[CLKID_AO_SAR_ADC_SEL]	= &axg_aoclk_saradc_mux.hw,
		[CLKID_AO_SAR_ADC_DIV]	= &axg_aoclk_saradc_div.hw,
		[CLKID_AO_SAR_ADC_CLK]	= &axg_aoclk_saradc_gate.hw,
		[CLKID_AO_CTS_OSCIN]	= &axg_aoclk_cts_oscin.hw,
		[CLKID_AO_32K_PRE]	= &axg_aoclk_32k_pre.hw,
		[CLKID_AO_32K_DIV]	= &axg_aoclk_32k_div.hw,
		[CLKID_AO_32K_SEL]	= &axg_aoclk_32k_sel.hw,
		[CLKID_AO_32K]		= &axg_aoclk_32k.hw,
		[CLKID_AO_CTS_RTC_OSCIN] = &axg_aoclk_cts_rtc_oscin.hw,
	},
	.num = NR_CLKS,
};
+1 −12
Original line number Diff line number Diff line
@@ -10,18 +10,7 @@
#ifndef __AXG_AOCLKC_H
#define __AXG_AOCLKC_H

#define NR_CLKS	11
/* AO Configuration Clock registers offsets
 * Register offsets from the data sheet must be multiplied by 4.
 */
#define AO_RTI_PWR_CNTL_REG1	0x0C
#define AO_RTI_PWR_CNTL_REG0	0x10
#define AO_RTI_GEN_CNTL_REG0	0x40
#define AO_OSCIN_CNTL		0x58
#define AO_CRT_CLK_CNTL1	0x68
#define AO_SAR_CLK		0x90
#define AO_RTC_ALT_CLK_CNTL0	0x94
#define AO_RTC_ALT_CLK_CNTL1	0x98
#define NR_CLKS	17

#include <dt-bindings/clock/axg-aoclkc.h>
#include <dt-bindings/reset/axg-aoclkc.h>