mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-03 09:04:21 +08:00
Merge branches 'clk-x86', 'clk-stm', 'clk-amlogic' and 'clk-allwinner' into clk-next
* clk-x86: clk: x86: Fix clk_gate_flags for RV_CLK_GATE clk: x86: Use dynamic con_id string during clk registration ACPI: APD: Add a fmw property clk-name drivers: acpi: acpi_apd: Remove unused device property "is-rv" x86: clk: clk-fch: Add support for newer family of AMD's SOC clk: Introduce clk-tps68470 driver platform/x86: int3472: Deal with probe ordering issues platform/x86: int3472: Pass tps68470_regulator_platform_data to the tps68470-regulator MFD-cell platform/x86: int3472: Pass tps68470_clk_platform_data to the tps68470-regulator MFD-cell platform/x86: int3472: Add get_sensor_adev_and_name() helper platform/x86: int3472: Split into 2 drivers platform_data: Add linux/platform_data/tps68470.h file i2c: acpi: Add i2c_acpi_new_device_by_fwnode() function i2c: acpi: Use acpi_dev_ready_for_enumeration() helper ACPI: delay enumeration of devices with a _DEP pointing to an INT3472 device * clk-stm: clk: stm32: Fix ltdc's clock turn off by clk_disable_unused() after system enter shell * clk-amlogic: clk: meson: gxbb: Fix the SDM_EN bit for MPLL0 on GXBB * clk-allwinner: clk: sunxi-ng: Add support for the D1 SoC clocks clk: sunxi-ng: gate: Add macros for gates with fixed dividers clk: sunxi-ng: mux: Add macros using clk_parent_data and clk_hw clk: sunxi-ng: mp: Add macros using clk_parent_data and clk_hw clk: sunxi-ng: div: Add macros using clk_parent_data and clk_hw dt-bindings: clk: Add compatibles for D1 CCUs clk: sunxi-ng: Allow the CCU core to be built as a module clk: sunxi-ng: Convert early providers to platform drivers clk: sunxi-ng: Allow drivers to be built as modules clk: sunxi-ng: Export symbols used by CCU drivers
This commit is contained in:
commit
151768f348
@ -34,6 +34,8 @@ properties:
|
||||
- allwinner,sun8i-v3-ccu
|
||||
- allwinner,sun8i-v3s-ccu
|
||||
- allwinner,sun9i-a80-ccu
|
||||
- allwinner,sun20i-d1-ccu
|
||||
- allwinner,sun20i-d1-r-ccu
|
||||
- allwinner,sun50i-a64-ccu
|
||||
- allwinner,sun50i-a64-r-ccu
|
||||
- allwinner,sun50i-a100-ccu
|
||||
@ -79,6 +81,7 @@ if:
|
||||
enum:
|
||||
- allwinner,sun8i-a83t-r-ccu
|
||||
- allwinner,sun8i-h3-r-ccu
|
||||
- allwinner,sun20i-d1-r-ccu
|
||||
- allwinner,sun50i-a64-r-ccu
|
||||
- allwinner,sun50i-a100-r-ccu
|
||||
- allwinner,sun50i-h6-r-ccu
|
||||
@ -99,6 +102,7 @@ else:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- allwinner,sun20i-d1-ccu
|
||||
- allwinner,sun50i-a100-ccu
|
||||
- allwinner,sun50i-h6-ccu
|
||||
- allwinner,sun50i-h616-ccu
|
||||
|
@ -87,8 +87,15 @@ static int fch_misc_setup(struct apd_private_data *pdata)
|
||||
if (ret < 0)
|
||||
return -ENOENT;
|
||||
|
||||
if (!acpi_dev_get_property(adev, "is-rv", ACPI_TYPE_INTEGER, &obj))
|
||||
clk_data->is_rv = obj->integer.value;
|
||||
if (!acpi_dev_get_property(adev, "clk-name", ACPI_TYPE_STRING, &obj)) {
|
||||
clk_data->name = devm_kzalloc(&adev->dev, obj->string.length,
|
||||
GFP_KERNEL);
|
||||
|
||||
strcpy(clk_data->name, obj->string.pointer);
|
||||
} else {
|
||||
/* Set default name to mclk if entry missing in firmware */
|
||||
clk_data->name = "mclk";
|
||||
}
|
||||
|
||||
list_for_each_entry(rentry, &resource_list, node) {
|
||||
clk_data->base = devm_ioremap(&adev->dev, rentry->res->start,
|
||||
|
@ -797,6 +797,12 @@ static const char * const acpi_ignore_dep_ids[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
/* List of HIDs for which we honor deps of matching ACPI devs, when checking _DEP lists. */
|
||||
static const char * const acpi_honor_dep_ids[] = {
|
||||
"INT3472", /* Camera sensor PMIC / clk and regulator info */
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct acpi_device *acpi_bus_get_parent(acpi_handle handle)
|
||||
{
|
||||
struct acpi_device *device = NULL;
|
||||
@ -1762,8 +1768,12 @@ static void acpi_scan_dep_init(struct acpi_device *adev)
|
||||
struct acpi_dep_data *dep;
|
||||
|
||||
list_for_each_entry(dep, &acpi_dep_list, node) {
|
||||
if (dep->consumer == adev->handle)
|
||||
if (dep->consumer == adev->handle) {
|
||||
if (dep->honor_dep)
|
||||
adev->flags.honor_deps = 1;
|
||||
|
||||
adev->dep_unmet++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1967,7 +1977,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
|
||||
for (count = 0, i = 0; i < dep_devices.count; i++) {
|
||||
struct acpi_device_info *info;
|
||||
struct acpi_dep_data *dep;
|
||||
bool skip;
|
||||
bool skip, honor_dep;
|
||||
|
||||
status = acpi_get_object_info(dep_devices.handles[i], &info);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
@ -1976,6 +1986,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
|
||||
}
|
||||
|
||||
skip = acpi_info_matches_ids(info, acpi_ignore_dep_ids);
|
||||
honor_dep = acpi_info_matches_ids(info, acpi_honor_dep_ids);
|
||||
kfree(info);
|
||||
|
||||
if (skip)
|
||||
@ -1989,6 +2000,7 @@ static u32 acpi_scan_check_dep(acpi_handle handle, bool check_dep)
|
||||
|
||||
dep->supplier = dep_devices.handles[i];
|
||||
dep->consumer = handle;
|
||||
dep->honor_dep = honor_dep;
|
||||
|
||||
mutex_lock(&acpi_dep_list_lock);
|
||||
list_add_tail(&dep->node , &acpi_dep_list);
|
||||
@ -2155,8 +2167,8 @@ static void acpi_bus_attach(struct acpi_device *device, bool first_pass)
|
||||
register_dock_dependent_device(device, ejd);
|
||||
|
||||
acpi_bus_get_status(device);
|
||||
/* Skip devices that are not present. */
|
||||
if (!acpi_device_is_present(device)) {
|
||||
/* Skip devices that are not ready for enumeration (e.g. not present) */
|
||||
if (!acpi_dev_ready_for_enumeration(device)) {
|
||||
device->flags.initialized = false;
|
||||
acpi_device_clear_enumerated(device);
|
||||
device->flags.power_manageable = 0;
|
||||
@ -2318,6 +2330,23 @@ void acpi_dev_clear_dependencies(struct acpi_device *supplier)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_clear_dependencies);
|
||||
|
||||
/**
|
||||
* acpi_dev_ready_for_enumeration - Check if the ACPI device is ready for enumeration
|
||||
* @device: Pointer to the &struct acpi_device to check
|
||||
*
|
||||
* Check if the device is present and has no unmet dependencies.
|
||||
*
|
||||
* Return true if the device is ready for enumeratino. Otherwise, return false.
|
||||
*/
|
||||
bool acpi_dev_ready_for_enumeration(const struct acpi_device *device)
|
||||
{
|
||||
if (device->flags.honor_deps && device->dep_unmet)
|
||||
return false;
|
||||
|
||||
return acpi_device_is_present(device);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_dev_ready_for_enumeration);
|
||||
|
||||
/**
|
||||
* acpi_dev_get_first_consumer_dev - Return ACPI device dependent on @supplier
|
||||
* @supplier: Pointer to the dependee device
|
||||
|
@ -169,6 +169,14 @@ config COMMON_CLK_CDCE706
|
||||
help
|
||||
This driver supports TI CDCE706 programmable 3-PLL clock synthesizer.
|
||||
|
||||
config COMMON_CLK_TPS68470
|
||||
tristate "Clock Driver for TI TPS68470 PMIC"
|
||||
depends on I2C
|
||||
depends on INTEL_SKL_INT3472 || COMPILE_TEST
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This driver supports the clocks provided by the TPS68470 PMIC.
|
||||
|
||||
config COMMON_CLK_CDCE925
|
||||
tristate "Clock driver for TI CDCE913/925/937/949 devices"
|
||||
depends on I2C
|
||||
|
@ -64,6 +64,7 @@ obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
|
||||
obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o
|
||||
obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
|
||||
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
|
||||
obj-$(CONFIG_COMMON_CLK_TPS68470) += clk-tps68470.o
|
||||
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
|
||||
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
|
||||
obj-$(CONFIG_COMMON_CLK_VC5) += clk-versaclock5.o
|
||||
@ -111,7 +112,7 @@ obj-$(CONFIG_PLAT_SPEAR) += spear/
|
||||
obj-y += sprd/
|
||||
obj-$(CONFIG_ARCH_STI) += st/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-$(CONFIG_SUNXI_CCU) += sunxi-ng/
|
||||
obj-y += sunxi-ng/
|
||||
obj-$(CONFIG_ARCH_TEGRA) += tegra/
|
||||
obj-y += ti/
|
||||
obj-$(CONFIG_CLK_UNIPHIER) += uniphier/
|
||||
|
@ -129,7 +129,6 @@ static const struct stm32f4_gate_data stm32f429_gates[] __initconst = {
|
||||
{ STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" },
|
||||
};
|
||||
|
||||
static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
|
||||
@ -211,7 +210,6 @@ static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
|
||||
{ STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" },
|
||||
};
|
||||
|
||||
static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
|
||||
@ -286,7 +284,6 @@ static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
|
||||
{ STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" },
|
||||
};
|
||||
|
||||
static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
|
||||
@ -364,7 +361,6 @@ static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
|
||||
{ STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" },
|
||||
{ STM32F4_RCC_APB2ENR, 30, "mdio", "apb2_div" },
|
||||
};
|
||||
|
||||
|
261
drivers/clk/clk-tps68470.c
Normal file
261
drivers/clk/clk-tps68470.c
Normal file
@ -0,0 +1,261 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Clock driver for TPS68470 PMIC
|
||||
*
|
||||
* Copyright (c) 2021 Red Hat Inc.
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
*
|
||||
* Authors:
|
||||
* Hans de Goede <hdegoede@redhat.com>
|
||||
* Zaikuo Wang <zaikuo.wang@intel.com>
|
||||
* Tianshu Qiu <tian.shu.qiu@intel.com>
|
||||
* Jian Xu Zheng <jian.xu.zheng@intel.com>
|
||||
* Yuning Pu <yuning.pu@intel.com>
|
||||
* Antti Laakso <antti.laakso@intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/tps68470.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/tps68470.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#define TPS68470_CLK_NAME "tps68470-clk"
|
||||
|
||||
#define to_tps68470_clkdata(clkd) \
|
||||
container_of(clkd, struct tps68470_clkdata, clkout_hw)
|
||||
|
||||
static struct tps68470_clkout_freqs {
|
||||
unsigned long freq;
|
||||
unsigned int xtaldiv;
|
||||
unsigned int plldiv;
|
||||
unsigned int postdiv;
|
||||
unsigned int buckdiv;
|
||||
unsigned int boostdiv;
|
||||
} clk_freqs[] = {
|
||||
/*
|
||||
* The PLL is used to multiply the crystal oscillator
|
||||
* frequency range of 3 MHz to 27 MHz by a programmable
|
||||
* factor of F = (M/N)*(1/P) such that the output
|
||||
* available at the HCLK_A or HCLK_B pins are in the range
|
||||
* of 4 MHz to 64 MHz in increments of 0.1 MHz.
|
||||
*
|
||||
* hclk_# = osc_in * (((plldiv*2)+320) / (xtaldiv+30)) * (1 / 2^postdiv)
|
||||
*
|
||||
* PLL_REF_CLK should be as close as possible to 100kHz
|
||||
* PLL_REF_CLK = input clk / XTALDIV[7:0] + 30)
|
||||
*
|
||||
* PLL_VCO_CLK = (PLL_REF_CLK * (plldiv*2 + 320))
|
||||
*
|
||||
* BOOST should be as close as possible to 2Mhz
|
||||
* BOOST = PLL_VCO_CLK / (BOOSTDIV[4:0] + 16) *
|
||||
*
|
||||
* BUCK should be as close as possible to 5.2Mhz
|
||||
* BUCK = PLL_VCO_CLK / (BUCKDIV[3:0] + 5)
|
||||
*
|
||||
* osc_in xtaldiv plldiv postdiv hclk_#
|
||||
* 20Mhz 170 32 1 19.2Mhz
|
||||
* 20Mhz 170 40 1 20Mhz
|
||||
* 20Mhz 170 80 1 24Mhz
|
||||
*/
|
||||
{ 19200000, 170, 32, 1, 2, 3 },
|
||||
{ 20000000, 170, 40, 1, 3, 4 },
|
||||
{ 24000000, 170, 80, 1, 4, 8 },
|
||||
};
|
||||
|
||||
struct tps68470_clkdata {
|
||||
struct clk_hw clkout_hw;
|
||||
struct regmap *regmap;
|
||||
unsigned long rate;
|
||||
};
|
||||
|
||||
static int tps68470_clk_is_prepared(struct clk_hw *hw)
|
||||
{
|
||||
struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
|
||||
int val;
|
||||
|
||||
if (regmap_read(clkdata->regmap, TPS68470_REG_PLLCTL, &val))
|
||||
return 0;
|
||||
|
||||
return val & TPS68470_PLL_EN_MASK;
|
||||
}
|
||||
|
||||
static int tps68470_clk_prepare(struct clk_hw *hw)
|
||||
{
|
||||
struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
|
||||
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1,
|
||||
(TPS68470_PLL_OUTPUT_ENABLE << TPS68470_OUTPUT_A_SHIFT) |
|
||||
(TPS68470_PLL_OUTPUT_ENABLE << TPS68470_OUTPUT_B_SHIFT));
|
||||
|
||||
regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL,
|
||||
TPS68470_PLL_EN_MASK, TPS68470_PLL_EN_MASK);
|
||||
|
||||
/*
|
||||
* The PLLCTL reg lock bit is set by the PMIC after approx. 4ms and
|
||||
* does not indicate a true lock, so just wait 4 ms.
|
||||
*/
|
||||
usleep_range(4000, 5000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void tps68470_clk_unprepare(struct clk_hw *hw)
|
||||
{
|
||||
struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
|
||||
|
||||
/* Disable clock first ... */
|
||||
regmap_update_bits(clkdata->regmap, TPS68470_REG_PLLCTL, TPS68470_PLL_EN_MASK, 0);
|
||||
|
||||
/* ... and then tri-state the clock outputs. */
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG1, 0);
|
||||
}
|
||||
|
||||
static unsigned long tps68470_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
|
||||
|
||||
return clkdata->rate;
|
||||
}
|
||||
|
||||
/*
|
||||
* This returns the index of the clk_freqs[] cfg with the closest rate for
|
||||
* use in tps68470_clk_round_rate(). tps68470_clk_set_rate() checks that
|
||||
* the rate of the returned cfg is an exact match.
|
||||
*/
|
||||
static unsigned int tps68470_clk_cfg_lookup(unsigned long rate)
|
||||
{
|
||||
long diff, best_diff = LONG_MAX;
|
||||
unsigned int i, best_idx = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(clk_freqs); i++) {
|
||||
diff = clk_freqs[i].freq - rate;
|
||||
if (diff == 0)
|
||||
return i;
|
||||
|
||||
diff = abs(diff);
|
||||
if (diff < best_diff) {
|
||||
best_diff = diff;
|
||||
best_idx = i;
|
||||
}
|
||||
}
|
||||
|
||||
return best_idx;
|
||||
}
|
||||
|
||||
static long tps68470_clk_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
unsigned int idx = tps68470_clk_cfg_lookup(rate);
|
||||
|
||||
return clk_freqs[idx].freq;
|
||||
}
|
||||
|
||||
static int tps68470_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct tps68470_clkdata *clkdata = to_tps68470_clkdata(hw);
|
||||
unsigned int idx = tps68470_clk_cfg_lookup(rate);
|
||||
|
||||
if (rate != clk_freqs[idx].freq)
|
||||
return -EINVAL;
|
||||
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_BOOSTDIV, clk_freqs[idx].boostdiv);
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_BUCKDIV, clk_freqs[idx].buckdiv);
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_PLLSWR, TPS68470_PLLSWR_DEFAULT);
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_XTALDIV, clk_freqs[idx].xtaldiv);
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_PLLDIV, clk_freqs[idx].plldiv);
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV, clk_freqs[idx].postdiv);
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_POSTDIV2, clk_freqs[idx].postdiv);
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_CLKCFG2, TPS68470_CLKCFG2_DRV_STR_2MA);
|
||||
|
||||
regmap_write(clkdata->regmap, TPS68470_REG_PLLCTL,
|
||||
TPS68470_OSC_EXT_CAP_DEFAULT << TPS68470_OSC_EXT_CAP_SHIFT |
|
||||
TPS68470_CLK_SRC_XTAL << TPS68470_CLK_SRC_SHIFT);
|
||||
|
||||
clkdata->rate = rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops tps68470_clk_ops = {
|
||||
.is_prepared = tps68470_clk_is_prepared,
|
||||
.prepare = tps68470_clk_prepare,
|
||||
.unprepare = tps68470_clk_unprepare,
|
||||
.recalc_rate = tps68470_clk_recalc_rate,
|
||||
.round_rate = tps68470_clk_round_rate,
|
||||
.set_rate = tps68470_clk_set_rate,
|
||||
};
|
||||
|
||||
static int tps68470_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tps68470_clk_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct clk_init_data tps68470_clk_initdata = {
|
||||
.name = TPS68470_CLK_NAME,
|
||||
.ops = &tps68470_clk_ops,
|
||||
/* Changing the dividers when the PLL is on is not allowed */
|
||||
.flags = CLK_SET_RATE_GATE,
|
||||
};
|
||||
struct tps68470_clkdata *tps68470_clkdata;
|
||||
int ret;
|
||||
|
||||
tps68470_clkdata = devm_kzalloc(&pdev->dev, sizeof(*tps68470_clkdata),
|
||||
GFP_KERNEL);
|
||||
if (!tps68470_clkdata)
|
||||
return -ENOMEM;
|
||||
|
||||
tps68470_clkdata->regmap = dev_get_drvdata(pdev->dev.parent);
|
||||
tps68470_clkdata->clkout_hw.init = &tps68470_clk_initdata;
|
||||
|
||||
/* Set initial rate */
|
||||
tps68470_clk_set_rate(&tps68470_clkdata->clkout_hw, clk_freqs[0].freq, 0);
|
||||
|
||||
ret = devm_clk_hw_register(&pdev->dev, &tps68470_clkdata->clkout_hw);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_clk_hw_register_clkdev(&pdev->dev, &tps68470_clkdata->clkout_hw,
|
||||
TPS68470_CLK_NAME, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (pdata) {
|
||||
ret = devm_clk_hw_register_clkdev(&pdev->dev,
|
||||
&tps68470_clkdata->clkout_hw,
|
||||
pdata->consumer_con_id,
|
||||
pdata->consumer_dev_name);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct platform_driver tps68470_clk_driver = {
|
||||
.driver = {
|
||||
.name = TPS68470_CLK_NAME,
|
||||
},
|
||||
.probe = tps68470_clk_probe,
|
||||
};
|
||||
|
||||
/*
|
||||
* The ACPI tps68470 probe-ordering depends on the clk/gpio/regulator drivers
|
||||
* registering before the drivers for the camera-sensors which use them bind.
|
||||
* subsys_initcall() ensures this when the drivers are builtin.
|
||||
*/
|
||||
static int __init tps68470_clk_init(void)
|
||||
{
|
||||
return platform_driver_register(&tps68470_clk_driver);
|
||||
}
|
||||
subsys_initcall(tps68470_clk_init);
|
||||
|
||||
static void __exit tps68470_clk_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&tps68470_clk_driver);
|
||||
}
|
||||
module_exit(tps68470_clk_exit);
|
||||
|
||||
MODULE_ALIAS("platform:tps68470-clk");
|
||||
MODULE_DESCRIPTION("clock driver for TPS68470 pmic");
|
||||
MODULE_LICENSE("GPL");
|
@ -713,6 +713,35 @@ static struct clk_regmap gxbb_mpll_prediv = {
|
||||
};
|
||||
|
||||
static struct clk_regmap gxbb_mpll0_div = {
|
||||
.data = &(struct meson_clk_mpll_data){
|
||||
.sdm = {
|
||||
.reg_off = HHI_MPLL_CNTL7,
|
||||
.shift = 0,
|
||||
.width = 14,
|
||||
},
|
||||
.sdm_en = {
|
||||
.reg_off = HHI_MPLL_CNTL,
|
||||
.shift = 25,
|
||||
.width = 1,
|
||||
},
|
||||
.n2 = {
|
||||
.reg_off = HHI_MPLL_CNTL7,
|
||||
.shift = 16,
|
||||
.width = 9,
|
||||
},
|
||||
.lock = &meson_clk_lock,
|
||||
},
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mpll0_div",
|
||||
.ops = &meson_clk_mpll_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&gxbb_mpll_prediv.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap gxl_mpll0_div = {
|
||||
.data = &(struct meson_clk_mpll_data){
|
||||
.sdm = {
|
||||
.reg_off = HHI_MPLL_CNTL7,
|
||||
@ -749,7 +778,16 @@ static struct clk_regmap gxbb_mpll0 = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "mpll0",
|
||||
.ops = &clk_regmap_gate_ops,
|
||||
.parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw },
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
/*
|
||||
* Note:
|
||||
* GXL and GXBB have different SDM_EN registers. We
|
||||
* fallback to the global naming string mechanism so
|
||||
* mpll0_div picks up the appropriate one.
|
||||
*/
|
||||
.name = "mpll0_div",
|
||||
.index = -1,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
},
|
||||
@ -3044,7 +3082,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = {
|
||||
[CLKID_VAPB_1] = &gxbb_vapb_1.hw,
|
||||
[CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw,
|
||||
[CLKID_VAPB] = &gxbb_vapb.hw,
|
||||
[CLKID_MPLL0_DIV] = &gxbb_mpll0_div.hw,
|
||||
[CLKID_MPLL0_DIV] = &gxl_mpll0_div.hw,
|
||||
[CLKID_MPLL1_DIV] = &gxbb_mpll1_div.hw,
|
||||
[CLKID_MPLL2_DIV] = &gxbb_mpll2_div.hw,
|
||||
[CLKID_MPLL_PREDIV] = &gxbb_mpll_prediv.hw,
|
||||
@ -3439,7 +3477,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = {
|
||||
&gxbb_mpll0,
|
||||
&gxbb_mpll1,
|
||||
&gxbb_mpll2,
|
||||
&gxbb_mpll0_div,
|
||||
&gxl_mpll0_div,
|
||||
&gxbb_mpll1_div,
|
||||
&gxbb_mpll2_div,
|
||||
&gxbb_cts_amclk_div,
|
||||
|
@ -1,6 +1,6 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
config SUNXI_CCU
|
||||
bool "Clock support for Allwinner SoCs"
|
||||
tristate "Clock support for Allwinner SoCs"
|
||||
depends on ARCH_SUNXI || COMPILE_TEST
|
||||
select RESET_CONTROLLER
|
||||
default ARCH_SUNXI
|
||||
@ -8,42 +8,52 @@ config SUNXI_CCU
|
||||
if SUNXI_CCU
|
||||
|
||||
config SUNIV_F1C100S_CCU
|
||||
bool "Support for the Allwinner newer F1C100s CCU"
|
||||
tristate "Support for the Allwinner newer F1C100s CCU"
|
||||
default MACH_SUNIV
|
||||
depends on MACH_SUNIV || COMPILE_TEST
|
||||
|
||||
config SUN20I_D1_CCU
|
||||
tristate "Support for the Allwinner D1 CCU"
|
||||
default RISCV && ARCH_SUNXI
|
||||
depends on (RISCV && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN20I_D1_R_CCU
|
||||
tristate "Support for the Allwinner D1 PRCM CCU"
|
||||
default RISCV && ARCH_SUNXI
|
||||
depends on (RISCV && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN50I_A64_CCU
|
||||
bool "Support for the Allwinner A64 CCU"
|
||||
tristate "Support for the Allwinner A64 CCU"
|
||||
default ARM64 && ARCH_SUNXI
|
||||
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN50I_A100_CCU
|
||||
bool "Support for the Allwinner A100 CCU"
|
||||
tristate "Support for the Allwinner A100 CCU"
|
||||
default ARM64 && ARCH_SUNXI
|
||||
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN50I_A100_R_CCU
|
||||
bool "Support for the Allwinner A100 PRCM CCU"
|
||||
tristate "Support for the Allwinner A100 PRCM CCU"
|
||||
default ARM64 && ARCH_SUNXI
|
||||
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN50I_H6_CCU
|
||||
bool "Support for the Allwinner H6 CCU"
|
||||
tristate "Support for the Allwinner H6 CCU"
|
||||
default ARM64 && ARCH_SUNXI
|
||||
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN50I_H616_CCU
|
||||
bool "Support for the Allwinner H616 CCU"
|
||||
tristate "Support for the Allwinner H616 CCU"
|
||||
default ARM64 && ARCH_SUNXI
|
||||
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN50I_H6_R_CCU
|
||||
bool "Support for the Allwinner H6 and H616 PRCM CCU"
|
||||
tristate "Support for the Allwinner H6 and H616 PRCM CCU"
|
||||
default ARM64 && ARCH_SUNXI
|
||||
depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN4I_A10_CCU
|
||||
bool "Support for the Allwinner A10/A20 CCU"
|
||||
tristate "Support for the Allwinner A10/A20 CCU"
|
||||
default MACH_SUN4I
|
||||
default MACH_SUN7I
|
||||
depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST
|
||||
@ -52,53 +62,54 @@ config SUN5I_CCU
|
||||
bool "Support for the Allwinner sun5i family CCM"
|
||||
default MACH_SUN5I
|
||||
depends on MACH_SUN5I || COMPILE_TEST
|
||||
depends on SUNXI_CCU=y
|
||||
|
||||
config SUN6I_A31_CCU
|
||||
bool "Support for the Allwinner A31/A31s CCU"
|
||||
tristate "Support for the Allwinner A31/A31s CCU"
|
||||
default MACH_SUN6I
|
||||
depends on MACH_SUN6I || COMPILE_TEST
|
||||
|
||||
config SUN8I_A23_CCU
|
||||
bool "Support for the Allwinner A23 CCU"
|
||||
tristate "Support for the Allwinner A23 CCU"
|
||||
default MACH_SUN8I
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_A33_CCU
|
||||
bool "Support for the Allwinner A33 CCU"
|
||||
tristate "Support for the Allwinner A33 CCU"
|
||||
default MACH_SUN8I
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_A83T_CCU
|
||||
bool "Support for the Allwinner A83T CCU"
|
||||
tristate "Support for the Allwinner A83T CCU"
|
||||
default MACH_SUN8I
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_H3_CCU
|
||||
bool "Support for the Allwinner H3 CCU"
|
||||
tristate "Support for the Allwinner H3 CCU"
|
||||
default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
|
||||
depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST
|
||||
|
||||
config SUN8I_V3S_CCU
|
||||
bool "Support for the Allwinner V3s CCU"
|
||||
tristate "Support for the Allwinner V3s CCU"
|
||||
default MACH_SUN8I
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_DE2_CCU
|
||||
bool "Support for the Allwinner SoCs DE2 CCU"
|
||||
tristate "Support for the Allwinner SoCs DE2 CCU"
|
||||
default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
|
||||
|
||||
config SUN8I_R40_CCU
|
||||
bool "Support for the Allwinner R40 CCU"
|
||||
tristate "Support for the Allwinner R40 CCU"
|
||||
default MACH_SUN8I
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN9I_A80_CCU
|
||||
bool "Support for the Allwinner A80 CCU"
|
||||
tristate "Support for the Allwinner A80 CCU"
|
||||
default MACH_SUN9I
|
||||
depends on MACH_SUN9I || COMPILE_TEST
|
||||
|
||||
config SUN8I_R_CCU
|
||||
bool "Support for Allwinner SoCs' PRCM CCUs"
|
||||
tristate "Support for Allwinner SoCs' PRCM CCUs"
|
||||
default MACH_SUN8I || (ARCH_SUNXI && ARM64)
|
||||
|
||||
endif
|
||||
|
@ -1,44 +1,73 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_SUNXI_CCU) += sunxi-ccu.o
|
||||
|
||||
# Common objects
|
||||
obj-y += ccu_common.o
|
||||
obj-y += ccu_mmc_timing.o
|
||||
obj-y += ccu_reset.o
|
||||
sunxi-ccu-y += ccu_common.o
|
||||
sunxi-ccu-y += ccu_mmc_timing.o
|
||||
sunxi-ccu-y += ccu_reset.o
|
||||
|
||||
# Base clock types
|
||||
obj-y += ccu_div.o
|
||||
obj-y += ccu_frac.o
|
||||
obj-y += ccu_gate.o
|
||||
obj-y += ccu_mux.o
|
||||
obj-y += ccu_mult.o
|
||||
obj-y += ccu_phase.o
|
||||
obj-y += ccu_sdm.o
|
||||
sunxi-ccu-y += ccu_div.o
|
||||
sunxi-ccu-y += ccu_frac.o
|
||||
sunxi-ccu-y += ccu_gate.o
|
||||
sunxi-ccu-y += ccu_mux.o
|
||||
sunxi-ccu-y += ccu_mult.o
|
||||
sunxi-ccu-y += ccu_phase.o
|
||||
sunxi-ccu-y += ccu_sdm.o
|
||||
|
||||
# Multi-factor clocks
|
||||
obj-y += ccu_nk.o
|
||||
obj-y += ccu_nkm.o
|
||||
obj-y += ccu_nkmp.o
|
||||
obj-y += ccu_nm.o
|
||||
obj-y += ccu_mp.o
|
||||
sunxi-ccu-y += ccu_nk.o
|
||||
sunxi-ccu-y += ccu_nkm.o
|
||||
sunxi-ccu-y += ccu_nkmp.o
|
||||
sunxi-ccu-y += ccu_nm.o
|
||||
sunxi-ccu-y += ccu_mp.o
|
||||
|
||||
# SoC support
|
||||
obj-$(CONFIG_SUNIV_F1C100S_CCU) += ccu-suniv-f1c100s.o
|
||||
obj-$(CONFIG_SUN50I_A64_CCU) += ccu-sun50i-a64.o
|
||||
obj-$(CONFIG_SUN50I_A100_CCU) += ccu-sun50i-a100.o
|
||||
obj-$(CONFIG_SUN50I_A100_R_CCU) += ccu-sun50i-a100-r.o
|
||||
obj-$(CONFIG_SUN50I_H6_CCU) += ccu-sun50i-h6.o
|
||||
obj-$(CONFIG_SUN50I_H616_CCU) += ccu-sun50i-h616.o
|
||||
obj-$(CONFIG_SUN50I_H6_R_CCU) += ccu-sun50i-h6-r.o
|
||||
obj-$(CONFIG_SUN4I_A10_CCU) += ccu-sun4i-a10.o
|
||||
obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o
|
||||
obj-$(CONFIG_SUN6I_A31_CCU) += ccu-sun6i-a31.o
|
||||
obj-$(CONFIG_SUN8I_A23_CCU) += ccu-sun8i-a23.o
|
||||
obj-$(CONFIG_SUN8I_A33_CCU) += ccu-sun8i-a33.o
|
||||
obj-$(CONFIG_SUN8I_A83T_CCU) += ccu-sun8i-a83t.o
|
||||
obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o
|
||||
obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o
|
||||
obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o
|
||||
obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o
|
||||
obj-$(CONFIG_SUN8I_R40_CCU) += ccu-sun8i-r40.o
|
||||
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o
|
||||
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o
|
||||
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
|
||||
obj-$(CONFIG_SUNIV_F1C100S_CCU) += suniv-f1c100s-ccu.o
|
||||
obj-$(CONFIG_SUN20I_D1_CCU) += sun20i-d1-ccu.o
|
||||
obj-$(CONFIG_SUN20I_D1_R_CCU) += sun20i-d1-r-ccu.o
|
||||
obj-$(CONFIG_SUN50I_A64_CCU) += sun50i-a64-ccu.o
|
||||
obj-$(CONFIG_SUN50I_A100_CCU) += sun50i-a100-ccu.o
|
||||
obj-$(CONFIG_SUN50I_A100_R_CCU) += sun50i-a100-r-ccu.o
|
||||
obj-$(CONFIG_SUN50I_H6_CCU) += sun50i-h6-ccu.o
|
||||
obj-$(CONFIG_SUN50I_H6_R_CCU) += sun50i-h6-r-ccu.o
|
||||
obj-$(CONFIG_SUN50I_H616_CCU) += sun50i-h616-ccu.o
|
||||
obj-$(CONFIG_SUN4I_A10_CCU) += sun4i-a10-ccu.o
|
||||
obj-$(CONFIG_SUN5I_CCU) += sun5i-ccu.o
|
||||
obj-$(CONFIG_SUN6I_A31_CCU) += sun6i-a31-ccu.o
|
||||
obj-$(CONFIG_SUN8I_A23_CCU) += sun8i-a23-ccu.o
|
||||
obj-$(CONFIG_SUN8I_A33_CCU) += sun8i-a33-ccu.o
|
||||
obj-$(CONFIG_SUN8I_A83T_CCU) += sun8i-a83t-ccu.o
|
||||
obj-$(CONFIG_SUN8I_H3_CCU) += sun8i-h3-ccu.o
|
||||
obj-$(CONFIG_SUN8I_R40_CCU) += sun8i-r40-ccu.o
|
||||
obj-$(CONFIG_SUN8I_V3S_CCU) += sun8i-v3s-ccu.o
|
||||
obj-$(CONFIG_SUN8I_DE2_CCU) += sun8i-de2-ccu.o
|
||||
obj-$(CONFIG_SUN8I_R_CCU) += sun8i-r-ccu.o
|
||||
obj-$(CONFIG_SUN9I_A80_CCU) += sun9i-a80-ccu.o
|
||||
obj-$(CONFIG_SUN9I_A80_CCU) += sun9i-a80-de-ccu.o
|
||||
obj-$(CONFIG_SUN9I_A80_CCU) += sun9i-a80-usb-ccu.o
|
||||
|
||||
suniv-f1c100s-ccu-y += ccu-suniv-f1c100s.o
|
||||
sun20i-d1-ccu-y += ccu-sun20i-d1.o
|
||||
sun20i-d1-r-ccu-y += ccu-sun20i-d1-r.o
|
||||
sun50i-a64-ccu-y += ccu-sun50i-a64.o
|
||||
sun50i-a100-ccu-y += ccu-sun50i-a100.o
|
||||
sun50i-a100-r-ccu-y += ccu-sun50i-a100-r.o
|
||||
sun50i-h6-ccu-y += ccu-sun50i-h6.o
|
||||
sun50i-h6-r-ccu-y += ccu-sun50i-h6-r.o
|
||||
sun50i-h616-ccu-y += ccu-sun50i-h616.o
|
||||
sun4i-a10-ccu-y += ccu-sun4i-a10.o
|
||||
sun5i-ccu-y += ccu-sun5i.o
|
||||
sun6i-a31-ccu-y += ccu-sun6i-a31.o
|
||||
sun8i-a23-ccu-y += ccu-sun8i-a23.o
|
||||
sun8i-a33-ccu-y += ccu-sun8i-a33.o
|
||||
sun8i-a83t-ccu-y += ccu-sun8i-a83t.o
|
||||
sun8i-h3-ccu-y += ccu-sun8i-h3.o
|
||||
sun8i-r40-ccu-y += ccu-sun8i-r40.o
|
||||
sun8i-v3s-ccu-y += ccu-sun8i-v3s.o
|
||||
sun8i-de2-ccu-y += ccu-sun8i-de2.o
|
||||
sun8i-r-ccu-y += ccu-sun8i-r.o
|
||||
sun9i-a80-ccu-y += ccu-sun9i-a80.o
|
||||
sun9i-a80-de-ccu-y += ccu-sun9i-a80-de.o
|
||||
sun9i-a80-usb-ccu-y += ccu-sun9i-a80-usb.o
|
||||
|
140
drivers/clk/sunxi-ng/ccu-sun20i-d1-r.c
Normal file
140
drivers/clk/sunxi-ng/ccu-sun20i-d1-r.c
Normal file
@ -0,0 +1,140 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2020 huangzhenwei@allwinnertech.com
|
||||
* Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_reset.h"
|
||||
|
||||
#include "ccu_gate.h"
|
||||
#include "ccu_mp.h"
|
||||
|
||||
#include "ccu-sun20i-d1-r.h"
|
||||
|
||||
static const struct clk_parent_data r_ahb_apb0_parents[] = {
|
||||
{ .fw_name = "hosc" },
|
||||
{ .fw_name = "losc" },
|
||||
{ .fw_name = "iosc" },
|
||||
{ .fw_name = "pll-periph" },
|
||||
};
|
||||
static SUNXI_CCU_MP_DATA_WITH_MUX(r_ahb_clk, "r-ahb",
|
||||
r_ahb_apb0_parents, 0x000,
|
||||
0, 5, /* M */
|
||||
8, 2, /* P */
|
||||
24, 3, /* mux */
|
||||
0);
|
||||
static const struct clk_hw *r_ahb_hw = &r_ahb_clk.common.hw;
|
||||
|
||||
static SUNXI_CCU_MP_DATA_WITH_MUX(r_apb0_clk, "r-apb0",
|
||||
r_ahb_apb0_parents, 0x00c,
|
||||
0, 5, /* M */
|
||||
8, 2, /* P */
|
||||
24, 3, /* mux */
|
||||
0);
|
||||
static const struct clk_hw *r_apb0_hw = &r_apb0_clk.common.hw;
|
||||
|
||||
static SUNXI_CCU_GATE_HWS(bus_r_timer_clk, "bus-r-timer", &r_apb0_hw,
|
||||
0x11c, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE_HWS(bus_r_twd_clk, "bus-r-twd", &r_apb0_hw,
|
||||
0x12c, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE_HWS(bus_r_ppu_clk, "bus-r-ppu", &r_apb0_hw,
|
||||
0x1ac, BIT(0), 0);
|
||||
|
||||
static const struct clk_parent_data r_ir_rx_parents[] = {
|
||||
{ .fw_name = "losc" },
|
||||
{ .fw_name = "hosc" },
|
||||
};
|
||||
static SUNXI_CCU_MP_DATA_WITH_MUX_GATE(r_ir_rx_clk, "r-ir-rx",
|
||||
r_ir_rx_parents, 0x1c0,
|
||||
0, 5, /* M */
|
||||
8, 2, /* P */
|
||||
24, 2, /* mux */
|
||||
BIT(31), /* gate */
|
||||
0);
|
||||
|
||||
static SUNXI_CCU_GATE_HWS(bus_r_ir_rx_clk, "bus-r-ir-rx", &r_apb0_hw,
|
||||
0x1cc, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE_HWS(bus_r_rtc_clk, "bus-r-rtc", &r_ahb_hw,
|
||||
0x20c, BIT(0), 0);
|
||||
static SUNXI_CCU_GATE_HWS(bus_r_cpucfg_clk, "bus-r-cpucfg", &r_apb0_hw,
|
||||
0x22c, BIT(0), 0);
|
||||
|
||||
static struct ccu_common *sun20i_d1_r_ccu_clks[] = {
|
||||
&r_ahb_clk.common,
|
||||
&r_apb0_clk.common,
|
||||
&bus_r_timer_clk.common,
|
||||
&bus_r_twd_clk.common,
|
||||
&bus_r_ppu_clk.common,
|
||||
&r_ir_rx_clk.common,
|
||||
&bus_r_ir_rx_clk.common,
|
||||
&bus_r_rtc_clk.common,
|
||||
&bus_r_cpucfg_clk.common,
|
||||
};
|
||||
|
||||
static struct clk_hw_onecell_data sun20i_d1_r_hw_clks = {
|
||||
.num = CLK_NUMBER,
|
||||
.hws = {
|
||||
[CLK_R_AHB] = &r_ahb_clk.common.hw,
|
||||
[CLK_R_APB0] = &r_apb0_clk.common.hw,
|
||||
[CLK_BUS_R_TIMER] = &bus_r_timer_clk.common.hw,
|
||||
[CLK_BUS_R_TWD] = &bus_r_twd_clk.common.hw,
|
||||
[CLK_BUS_R_PPU] = &bus_r_ppu_clk.common.hw,
|
||||
[CLK_R_IR_RX] = &r_ir_rx_clk.common.hw,
|
||||
[CLK_BUS_R_IR_RX] = &bus_r_ir_rx_clk.common.hw,
|
||||
[CLK_BUS_R_RTC] = &bus_r_rtc_clk.common.hw,
|
||||
[CLK_BUS_R_CPUCFG] = &bus_r_cpucfg_clk.common.hw,
|
||||
},
|
||||
};
|
||||
|
||||
static struct ccu_reset_map sun20i_d1_r_ccu_resets[] = {
|
||||
[RST_BUS_R_TIMER] = { 0x11c, BIT(16) },
|
||||
[RST_BUS_R_TWD] = { 0x12c, BIT(16) },
|
||||
[RST_BUS_R_PPU] = { 0x1ac, BIT(16) },
|
||||
[RST_BUS_R_IR_RX] = { 0x1cc, BIT(16) },
|
||||
[RST_BUS_R_RTC] = { 0x20c, BIT(16) },
|
||||
[RST_BUS_R_CPUCFG] = { 0x22c, BIT(16) },
|
||||
};
|
||||
|
||||
static const struct sunxi_ccu_desc sun20i_d1_r_ccu_desc = {
|
||||
.ccu_clks = sun20i_d1_r_ccu_clks,
|
||||
.num_ccu_clks = ARRAY_SIZE(sun20i_d1_r_ccu_clks),
|
||||
|
||||
.hw_clks = &sun20i_d1_r_hw_clks,
|
||||
|
||||
.resets = sun20i_d1_r_ccu_resets,
|
||||
.num_resets = ARRAY_SIZE(sun20i_d1_r_ccu_resets),
|
||||
};
|
||||
|
||||
static int sun20i_d1_r_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *reg;
|
||||
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun20i_d1_r_ccu_desc);
|
||||
}
|
||||
|
||||
static const struct of_device_id sun20i_d1_r_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun20i-d1-r-ccu" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver sun20i_d1_r_ccu_driver = {
|
||||
.probe = sun20i_d1_r_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun20i-d1-r-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun20i_d1_r_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun20i_d1_r_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
17
drivers/clk/sunxi-ng/ccu-sun20i-d1-r.h
Normal file
17
drivers/clk/sunxi-ng/ccu-sun20i-d1-r.h
Normal file
@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2020 frank@allwinnertech.com
|
||||
* Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#ifndef _CCU_SUN20I_D1_R_H
|
||||
#define _CCU_SUN20I_D1_R_H
|
||||
|
||||
#include <dt-bindings/clock/sun20i-d1-r-ccu.h>
|
||||
#include <dt-bindings/reset/sun20i-d1-r-ccu.h>
|
||||
|
||||
#define CLK_R_APB0 1
|
||||
|
||||
#define CLK_NUMBER (CLK_BUS_R_CPUCFG + 1)
|
||||
|
||||
#endif /* _CCU_SUN20I_D1_R_H */
|
1390
drivers/clk/sunxi-ng/ccu-sun20i-d1.c
Normal file
1390
drivers/clk/sunxi-ng/ccu-sun20i-d1.c
Normal file
File diff suppressed because it is too large
Load Diff
15
drivers/clk/sunxi-ng/ccu-sun20i-d1.h
Normal file
15
drivers/clk/sunxi-ng/ccu-sun20i-d1.h
Normal file
@ -0,0 +1,15 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2020 frank@allwinnertech.com
|
||||
* Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#ifndef _CCU_SUN20I_D1_H_
|
||||
#define _CCU_SUN20I_D1_H_
|
||||
|
||||
#include <dt-bindings/clock/sun20i-d1-ccu.h>
|
||||
#include <dt-bindings/reset/sun20i-d1-ccu.h>
|
||||
|
||||
#define CLK_NUMBER (CLK_FANOUT2 + 1)
|
||||
|
||||
#endif /* _CCU_SUN20I_D1_H_ */
|
@ -7,7 +7,9 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_reset.h"
|
||||
@ -1425,18 +1427,19 @@ static const struct sunxi_ccu_desc sun7i_a20_ccu_desc = {
|
||||
.num_resets = ARRAY_SIZE(sunxi_a10_a20_ccu_resets),
|
||||
};
|
||||
|
||||
static void __init sun4i_ccu_init(struct device_node *node,
|
||||
const struct sunxi_ccu_desc *desc)
|
||||
static int sun4i_a10_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct sunxi_ccu_desc *desc;
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%s: Could not map the clock registers\n",
|
||||
of_node_full_name(node));
|
||||
return;
|
||||
}
|
||||
desc = of_device_get_match_data(&pdev->dev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
val = readl(reg + SUN4I_PLL_AUDIO_REG);
|
||||
|
||||
@ -1464,19 +1467,30 @@ static void __init sun4i_ccu_init(struct device_node *node,
|
||||
val &= ~GENMASK(7, 6);
|
||||
writel(val | (2 << 6), reg + SUN4I_AHB_REG);
|
||||
|
||||
of_sunxi_ccu_probe(node, reg, desc);
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
|
||||
}
|
||||
|
||||
static void __init sun4i_a10_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sun4i_ccu_init(node, &sun4i_a10_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun4i_a10_ccu, "allwinner,sun4i-a10-ccu",
|
||||
sun4i_a10_ccu_setup);
|
||||
static const struct of_device_id sun4i_a10_ccu_ids[] = {
|
||||
{
|
||||
.compatible = "allwinner,sun4i-a10-ccu",
|
||||
.data = &sun4i_a10_ccu_desc,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun7i-a20-ccu",
|
||||
.data = &sun7i_a20_ccu_desc,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static void __init sun7i_a20_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sun4i_ccu_init(node, &sun7i_a20_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun7i_a20_ccu, "allwinner,sun7i-a20-ccu",
|
||||
sun7i_a20_ccu_setup);
|
||||
static struct platform_driver sun4i_a10_ccu_driver = {
|
||||
.probe = sun4i_a10_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun4i-a10-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun4i_a10_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun4i_a10_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -213,3 +212,6 @@ static struct platform_driver sun50i_a100_r_ccu_driver = {
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun50i_a100_r_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -1275,3 +1274,6 @@ static struct platform_driver sun50i_a100_ccu_driver = {
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun50i_a100_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -980,4 +980,7 @@ static struct platform_driver sun50i_a64_ccu_driver = {
|
||||
.of_match_table = sun50i_a64_ccu_ids,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(sun50i_a64_ccu_driver);
|
||||
module_platform_driver(sun50i_a64_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -4,7 +4,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -221,30 +222,43 @@ static const struct sunxi_ccu_desc sun50i_h616_r_ccu_desc = {
|
||||
.num_resets = ARRAY_SIZE(sun50i_h616_r_ccu_resets),
|
||||
};
|
||||
|
||||
static void __init sunxi_r_ccu_init(struct device_node *node,
|
||||
const struct sunxi_ccu_desc *desc)
|
||||
static int sun50i_h6_r_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct sunxi_ccu_desc *desc;
|
||||
void __iomem *reg;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%pOF: Could not map the clock registers\n", node);
|
||||
return;
|
||||
}
|
||||
desc = of_device_get_match_data(&pdev->dev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
of_sunxi_ccu_probe(node, reg, desc);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
|
||||
}
|
||||
|
||||
static void __init sun50i_h6_r_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_r_ccu_init(node, &sun50i_h6_r_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun50i_h6_r_ccu, "allwinner,sun50i-h6-r-ccu",
|
||||
sun50i_h6_r_ccu_setup);
|
||||
static const struct of_device_id sun50i_h6_r_ccu_ids[] = {
|
||||
{
|
||||
.compatible = "allwinner,sun50i-h6-r-ccu",
|
||||
.data = &sun50i_h6_r_ccu_desc,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun50i-h616-r-ccu",
|
||||
.data = &sun50i_h616_r_ccu_desc,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static void __init sun50i_h616_r_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_r_ccu_init(node, &sun50i_h616_r_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun50i_h616_r_ccu, "allwinner,sun50i-h616-r-ccu",
|
||||
sun50i_h616_r_ccu_setup);
|
||||
static struct platform_driver sun50i_h6_r_ccu_driver = {
|
||||
.probe = sun50i_h6_r_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun50i-h6-r-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun50i_h6_r_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun50i_h6_r_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -1254,4 +1254,7 @@ static struct platform_driver sun50i_h6_ccu_driver = {
|
||||
.of_match_table = sun50i_h6_ccu_ids,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(sun50i_h6_ccu_driver);
|
||||
module_platform_driver(sun50i_h6_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -1082,17 +1082,15 @@ static const u32 usb2_clk_regs[] = {
|
||||
SUN50I_H616_USB3_CLK_REG,
|
||||
};
|
||||
|
||||
static void __init sun50i_h616_ccu_setup(struct device_node *node)
|
||||
static int sun50i_h616_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
int i;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%pOF: Could not map clock registers\n", node);
|
||||
return;
|
||||
}
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
/* Enable the lock bits and the output enable bits on all PLLs */
|
||||
for (i = 0; i < ARRAY_SIZE(pll_regs); i++) {
|
||||
@ -1141,8 +1139,23 @@ static void __init sun50i_h616_ccu_setup(struct device_node *node)
|
||||
val |= BIT(24);
|
||||
writel(val, reg + SUN50I_H616_HDMI_CEC_CLK_REG);
|
||||
|
||||
of_sunxi_ccu_probe(node, reg, &sun50i_h616_ccu_desc);
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun50i_h616_ccu_desc);
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE(sun50i_h616_ccu, "allwinner,sun50i-h616-ccu",
|
||||
sun50i_h616_ccu_setup);
|
||||
static const struct of_device_id sun50i_h616_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun50i-h616-ccu" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver sun50i_h616_ccu_driver = {
|
||||
.probe = sun50i_h616_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun50i-h616-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun50i_h616_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun50i_h616_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -9,7 +9,8 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_reset.h"
|
||||
@ -1226,16 +1227,15 @@ static struct ccu_mux_nb sun6i_a31_cpu_nb = {
|
||||
.bypass_index = 1, /* index of 24 MHz oscillator */
|
||||
};
|
||||
|
||||
static void __init sun6i_a31_ccu_setup(struct device_node *node)
|
||||
static int sun6i_a31_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *reg;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%pOF: Could not map the clock registers\n", node);
|
||||
return;
|
||||
}
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 1 */
|
||||
val = readl(reg + SUN6I_A31_PLL_AUDIO_REG);
|
||||
@ -1257,10 +1257,30 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node)
|
||||
val |= 0x3 << 12;
|
||||
writel(val, reg + SUN6I_A31_AHB1_REG);
|
||||
|
||||
of_sunxi_ccu_probe(node, reg, &sun6i_a31_ccu_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun6i_a31_ccu_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
|
||||
&sun6i_a31_cpu_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
CLK_OF_DECLARE(sun6i_a31_ccu, "allwinner,sun6i-a31-ccu",
|
||||
sun6i_a31_ccu_setup);
|
||||
|
||||
static const struct of_device_id sun6i_a31_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun6i-a31-ccu" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver sun6i_a31_ccu_driver = {
|
||||
.probe = sun6i_a31_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun6i-a31-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun6i_a31_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun6i_a31_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,7 +5,8 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_reset.h"
|
||||
@ -724,16 +725,14 @@ static const struct sunxi_ccu_desc sun8i_a23_ccu_desc = {
|
||||
.num_resets = ARRAY_SIZE(sun8i_a23_ccu_resets),
|
||||
};
|
||||
|
||||
static void __init sun8i_a23_ccu_setup(struct device_node *node)
|
||||
static int sun8i_a23_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%pOF: Could not map the clock registers\n", node);
|
||||
return;
|
||||
}
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 1 */
|
||||
val = readl(reg + SUN8I_A23_PLL_AUDIO_REG);
|
||||
@ -745,7 +744,23 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node)
|
||||
val &= ~BIT(16);
|
||||
writel(val, reg + SUN8I_A23_PLL_MIPI_REG);
|
||||
|
||||
of_sunxi_ccu_probe(node, reg, &sun8i_a23_ccu_desc);
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a23_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun8i_a23_ccu, "allwinner,sun8i-a23-ccu",
|
||||
sun8i_a23_ccu_setup);
|
||||
|
||||
static const struct of_device_id sun8i_a23_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun8i-a23-ccu" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver sun8i_a23_ccu_driver = {
|
||||
.probe = sun8i_a23_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun8i-a23-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun8i_a23_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun8i_a23_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,7 +5,8 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_reset.h"
|
||||
@ -784,16 +785,15 @@ static struct ccu_mux_nb sun8i_a33_cpu_nb = {
|
||||
.bypass_index = 1, /* index of 24 MHz oscillator */
|
||||
};
|
||||
|
||||
static void __init sun8i_a33_ccu_setup(struct device_node *node)
|
||||
static int sun8i_a33_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *reg;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%pOF: Could not map the clock registers\n", node);
|
||||
return;
|
||||
}
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 1 */
|
||||
val = readl(reg + SUN8I_A33_PLL_AUDIO_REG);
|
||||
@ -805,7 +805,9 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
|
||||
val &= ~BIT(16);
|
||||
writel(val, reg + SUN8I_A33_PLL_MIPI_REG);
|
||||
|
||||
of_sunxi_ccu_probe(node, reg, &sun8i_a33_ccu_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &sun8i_a33_ccu_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Gate then ungate PLL CPU after any rate changes */
|
||||
ccu_pll_notifier_register(&sun8i_a33_pll_cpu_nb);
|
||||
@ -813,6 +815,24 @@ static void __init sun8i_a33_ccu_setup(struct device_node *node)
|
||||
/* Reparent CPU during PLL CPU rate changes */
|
||||
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
|
||||
&sun8i_a33_cpu_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
CLK_OF_DECLARE(sun8i_a33_ccu, "allwinner,sun8i-a33-ccu",
|
||||
sun8i_a33_ccu_setup);
|
||||
|
||||
static const struct of_device_id sun8i_a33_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,sun8i-a33-ccu" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver sun8i_a33_ccu_driver = {
|
||||
.probe = sun8i_a33_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun8i-a33-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun8i_a33_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun8i_a33_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -920,4 +920,7 @@ static struct platform_driver sun8i_a83t_ccu_driver = {
|
||||
.of_match_table = sun8i_a83t_ccu_ids,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(sun8i_a83t_ccu_driver);
|
||||
module_platform_driver(sun8i_a83t_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
@ -394,4 +394,7 @@ static struct platform_driver sunxi_de2_clk_driver = {
|
||||
.of_match_table = sunxi_de2_clk_ids,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(sunxi_de2_clk_driver);
|
||||
module_platform_driver(sunxi_de2_clk_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,7 +5,9 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_reset.h"
|
||||
@ -1137,24 +1139,29 @@ static struct ccu_mux_nb sun8i_h3_cpu_nb = {
|
||||
.bypass_index = 1, /* index of 24 MHz oscillator */
|
||||
};
|
||||
|
||||
static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
|
||||
const struct sunxi_ccu_desc *desc)
|
||||
static int sun8i_h3_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct sunxi_ccu_desc *desc;
|
||||
void __iomem *reg;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%pOF: Could not map the clock registers\n", node);
|
||||
return;
|
||||
}
|
||||
desc = of_device_get_match_data(&pdev->dev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 1 */
|
||||
val = readl(reg + SUN8I_H3_PLL_AUDIO_REG);
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
|
||||
|
||||
of_sunxi_ccu_probe(node, reg, desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Gate then ungate PLL CPU after any rate changes */
|
||||
ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb);
|
||||
@ -1162,18 +1169,31 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
|
||||
/* Reparent CPU during PLL CPU rate changes */
|
||||
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
|
||||
&sun8i_h3_cpu_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init sun8i_h3_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_h3_h5_ccu_init(node, &sun8i_h3_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun8i_h3_ccu, "allwinner,sun8i-h3-ccu",
|
||||
sun8i_h3_ccu_setup);
|
||||
static const struct of_device_id sun8i_h3_ccu_ids[] = {
|
||||
{
|
||||
.compatible = "allwinner,sun8i-h3-ccu",
|
||||
.data = &sun8i_h3_ccu_desc,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun50i-h5-ccu",
|
||||
.data = &sun50i_h5_ccu_desc,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static void __init sun50i_h5_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_h3_h5_ccu_init(node, &sun50i_h5_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun50i_h5_ccu, "allwinner,sun50i-h5-ccu",
|
||||
sun50i_h5_ccu_setup);
|
||||
static struct platform_driver sun8i_h3_ccu_driver = {
|
||||
.probe = sun8i_h3_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun8i-h3-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun8i_h3_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun8i_h3_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -4,7 +4,8 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -254,37 +255,47 @@ static const struct sunxi_ccu_desc sun50i_a64_r_ccu_desc = {
|
||||
.num_resets = ARRAY_SIZE(sun50i_a64_r_ccu_resets),
|
||||
};
|
||||
|
||||
static void __init sunxi_r_ccu_init(struct device_node *node,
|
||||
const struct sunxi_ccu_desc *desc)
|
||||
static int sun8i_r_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct sunxi_ccu_desc *desc;
|
||||
void __iomem *reg;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%pOF: Could not map the clock registers\n", node);
|
||||
return;
|
||||
}
|
||||
desc = of_device_get_match_data(&pdev->dev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
of_sunxi_ccu_probe(node, reg, desc);
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
|
||||
}
|
||||
|
||||
static void __init sun8i_a83t_r_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_r_ccu_init(node, &sun8i_a83t_r_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun8i_a83t_r_ccu, "allwinner,sun8i-a83t-r-ccu",
|
||||
sun8i_a83t_r_ccu_setup);
|
||||
static const struct of_device_id sun8i_r_ccu_ids[] = {
|
||||
{
|
||||
.compatible = "allwinner,sun8i-a83t-r-ccu",
|
||||
.data = &sun8i_a83t_r_ccu_desc,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun8i-h3-r-ccu",
|
||||
.data = &sun8i_h3_r_ccu_desc,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun50i-a64-r-ccu",
|
||||
.data = &sun50i_a64_r_ccu_desc,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static void __init sun8i_h3_r_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_r_ccu_init(node, &sun8i_h3_r_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun8i_h3_r_ccu, "allwinner,sun8i-h3-r-ccu",
|
||||
sun8i_h3_r_ccu_setup);
|
||||
static struct platform_driver sun8i_r_ccu_driver = {
|
||||
.probe = sun8i_r_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun8i-r-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun8i_r_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun8i_r_ccu_driver);
|
||||
|
||||
static void __init sun50i_a64_r_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_r_ccu_init(node, &sun50i_a64_r_ccu_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(sun50i_a64_r_ccu, "allwinner,sun50i-a64-r-ccu",
|
||||
sun50i_a64_r_ccu_setup);
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
@ -1371,4 +1372,7 @@ static struct platform_driver sun8i_r40_ccu_driver = {
|
||||
.of_match_table = sun8i_r40_ccu_ids,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(sun8i_r40_ccu_driver);
|
||||
module_platform_driver(sun8i_r40_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -8,7 +8,9 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_reset.h"
|
||||
@ -805,38 +807,49 @@ static const struct sunxi_ccu_desc sun8i_v3_ccu_desc = {
|
||||
.num_resets = ARRAY_SIZE(sun8i_v3_ccu_resets),
|
||||
};
|
||||
|
||||
static void __init sun8i_v3_v3s_ccu_init(struct device_node *node,
|
||||
const struct sunxi_ccu_desc *ccu_desc)
|
||||
static int sun8i_v3s_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct sunxi_ccu_desc *desc;
|
||||
void __iomem *reg;
|
||||
u32 val;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%pOF: Could not map the clock registers\n", node);
|
||||
return;
|
||||
}
|
||||
desc = of_device_get_match_data(&pdev->dev);
|
||||
if (!desc)
|
||||
return -EINVAL;
|
||||
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 1 */
|
||||
val = readl(reg + SUN8I_V3S_PLL_AUDIO_REG);
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val, reg + SUN8I_V3S_PLL_AUDIO_REG);
|
||||
|
||||
of_sunxi_ccu_probe(node, reg, ccu_desc);
|
||||
return devm_sunxi_ccu_probe(&pdev->dev, reg, desc);
|
||||
}
|
||||
|
||||
static void __init sun8i_v3s_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sun8i_v3_v3s_ccu_init(node, &sun8i_v3s_ccu_desc);
|
||||
}
|
||||
static const struct of_device_id sun8i_v3s_ccu_ids[] = {
|
||||
{
|
||||
.compatible = "allwinner,sun8i-v3-ccu",
|
||||
.data = &sun8i_v3_ccu_desc,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun8i-v3s-ccu",
|
||||
.data = &sun8i_v3s_ccu_desc,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static void __init sun8i_v3_ccu_setup(struct device_node *node)
|
||||
{
|
||||
sun8i_v3_v3s_ccu_init(node, &sun8i_v3_ccu_desc);
|
||||
}
|
||||
static struct platform_driver sun8i_v3s_ccu_driver = {
|
||||
.probe = sun8i_v3s_ccu_probe,
|
||||
.driver = {
|
||||
.name = "sun8i-v3s-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = sun8i_v3s_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(sun8i_v3s_ccu_driver);
|
||||
|
||||
CLK_OF_DECLARE(sun8i_v3s_ccu, "allwinner,sun8i-v3s-ccu",
|
||||
sun8i_v3s_ccu_setup);
|
||||
|
||||
CLK_OF_DECLARE(sun8i_v3_ccu, "allwinner,sun8i-v3-ccu",
|
||||
sun8i_v3_ccu_setup);
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/reset.h>
|
||||
|
||||
@ -270,4 +270,7 @@ static struct platform_driver sun9i_a80_de_clk_driver = {
|
||||
.of_match_table = sun9i_a80_de_clk_ids,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(sun9i_a80_de_clk_driver);
|
||||
module_platform_driver(sun9i_a80_de_clk_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -138,4 +138,7 @@ static struct platform_driver sun9i_a80_usb_clk_driver = {
|
||||
.of_match_table = sun9i_a80_usb_clk_ids,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(sun9i_a80_usb_clk_driver);
|
||||
module_platform_driver(sun9i_a80_usb_clk_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -1245,4 +1245,7 @@ static struct platform_driver sun9i_a80_ccu_driver = {
|
||||
.of_match_table = sun9i_a80_ccu_ids,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(sun9i_a80_ccu_driver);
|
||||
module_platform_driver(sun9i_a80_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -6,7 +6,8 @@
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
#include "ccu_reset.h"
|
||||
@ -522,23 +523,24 @@ static struct ccu_mux_nb suniv_cpu_nb = {
|
||||
.bypass_index = 1, /* index of 24 MHz oscillator */
|
||||
};
|
||||
|
||||
static void __init suniv_f1c100s_ccu_setup(struct device_node *node)
|
||||
static int suniv_f1c100s_ccu_probe(struct platform_device *pdev)
|
||||
{
|
||||
void __iomem *reg;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg)) {
|
||||
pr_err("%pOF: Could not map the clock registers\n", node);
|
||||
return;
|
||||
}
|
||||
reg = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg))
|
||||
return PTR_ERR(reg);
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 4 */
|
||||
val = readl(reg + SUNIV_PLL_AUDIO_REG);
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val | (3 << 16), reg + SUNIV_PLL_AUDIO_REG);
|
||||
|
||||
of_sunxi_ccu_probe(node, reg, &suniv_ccu_desc);
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, &suniv_ccu_desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Gate then ungate PLL CPU after any rate changes */
|
||||
ccu_pll_notifier_register(&suniv_pll_cpu_nb);
|
||||
@ -546,6 +548,24 @@ static void __init suniv_f1c100s_ccu_setup(struct device_node *node)
|
||||
/* Reparent CPU during PLL CPU rate changes */
|
||||
ccu_mux_notifier_register(pll_cpu_clk.common.hw.clk,
|
||||
&suniv_cpu_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
CLK_OF_DECLARE(suniv_f1c100s_ccu, "allwinner,suniv-f1c100s-ccu",
|
||||
suniv_f1c100s_ccu_setup);
|
||||
|
||||
static const struct of_device_id suniv_f1c100s_ccu_ids[] = {
|
||||
{ .compatible = "allwinner,suniv-f1c100s-ccu" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct platform_driver suniv_f1c100s_ccu_driver = {
|
||||
.probe = suniv_f1c100s_ccu_probe,
|
||||
.driver = {
|
||||
.name = "suniv-f1c100s-ccu",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = suniv_f1c100s_ccu_ids,
|
||||
},
|
||||
};
|
||||
module_platform_driver(suniv_f1c100s_ccu_driver);
|
||||
|
||||
MODULE_IMPORT_NS(SUNXI_CCU);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
@ -36,6 +37,7 @@ void ccu_helper_wait_for_lock(struct ccu_common *common, u32 lock)
|
||||
|
||||
WARN_ON(readl_relaxed_poll_timeout(addr, reg, reg & lock, 100, 70000));
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_helper_wait_for_lock, SUNXI_CCU);
|
||||
|
||||
/*
|
||||
* This clock notifier is called when the frequency of a PLL clock is
|
||||
@ -83,6 +85,7 @@ int ccu_pll_notifier_register(struct ccu_pll_nb *pll_nb)
|
||||
return clk_notifier_register(pll_nb->common->hw.clk,
|
||||
&pll_nb->clk_nb);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_pll_notifier_register, SUNXI_CCU);
|
||||
|
||||
static int sunxi_ccu_probe(struct sunxi_ccu *ccu, struct device *dev,
|
||||
struct device_node *node, void __iomem *reg,
|
||||
@ -194,6 +197,7 @@ int devm_sunxi_ccu_probe(struct device *dev, void __iomem *reg,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(devm_sunxi_ccu_probe, SUNXI_CCU);
|
||||
|
||||
void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
const struct sunxi_ccu_desc *desc)
|
||||
@ -211,3 +215,5 @@ void of_sunxi_ccu_probe(struct device_node *node, void __iomem *reg,
|
||||
kfree(ccu);
|
||||
}
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
@ -141,3 +141,4 @@ const struct clk_ops ccu_div_ops = {
|
||||
.recalc_rate = ccu_div_recalc_rate,
|
||||
.set_rate = ccu_div_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_div_ops, SUNXI_CCU);
|
||||
|
@ -108,6 +108,22 @@ struct ccu_div {
|
||||
_shift, _width, _table, 0, \
|
||||
_flags)
|
||||
|
||||
#define SUNXI_CCU_DIV_TABLE_HW(_struct, _name, _parent, _reg, \
|
||||
_shift, _width, \
|
||||
_table, _flags) \
|
||||
struct ccu_div _struct = { \
|
||||
.div = _SUNXI_CCU_DIV_TABLE(_shift, _width, \
|
||||
_table), \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_HW(_name, \
|
||||
_parent, \
|
||||
&ccu_div_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
|
||||
_parents, _table, \
|
||||
_reg, \
|
||||
@ -166,6 +182,68 @@ struct ccu_div {
|
||||
SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
|
||||
_mshift, _mwidth, 0, _flags)
|
||||
|
||||
#define SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, \
|
||||
_muxshift, _muxwidth, \
|
||||
_gate, _flags) \
|
||||
struct ccu_div _struct = { \
|
||||
.enable = _gate, \
|
||||
.div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
|
||||
.mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \
|
||||
_parents, \
|
||||
&ccu_div_ops, \
|
||||
_flags), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_M_DATA_WITH_MUX(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, \
|
||||
_muxshift, _muxwidth, \
|
||||
_flags) \
|
||||
SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, \
|
||||
_muxshift, _muxwidth, \
|
||||
0, _flags)
|
||||
|
||||
#define SUNXI_CCU_M_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, _muxshift, _muxwidth, \
|
||||
_gate, _flags) \
|
||||
struct ccu_div _struct = { \
|
||||
.enable = _gate, \
|
||||
.div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
|
||||
.mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS_HW(_name, \
|
||||
_parents, \
|
||||
&ccu_div_ops, \
|
||||
_flags), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg, \
|
||||
_mshift, _mwidth, _gate, \
|
||||
_flags) \
|
||||
struct ccu_div _struct = { \
|
||||
.enable = _gate, \
|
||||
.div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_HWS(_name, \
|
||||
_parent, \
|
||||
&ccu_div_ops, \
|
||||
_flags), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_M_HWS(_struct, _name, _parent, _reg, _mshift, \
|
||||
_mwidth, _flags) \
|
||||
SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg, \
|
||||
_mshift, _mwidth, 0, _flags)
|
||||
|
||||
static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
|
||||
{
|
||||
struct ccu_common *common = hw_to_ccu_common(hw);
|
||||
|
@ -18,6 +18,7 @@ bool ccu_frac_helper_is_enabled(struct ccu_common *common,
|
||||
|
||||
return !(readl(common->base + common->reg) & cf->enable);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_is_enabled, SUNXI_CCU);
|
||||
|
||||
void ccu_frac_helper_enable(struct ccu_common *common,
|
||||
struct ccu_frac_internal *cf)
|
||||
@ -33,6 +34,7 @@ void ccu_frac_helper_enable(struct ccu_common *common,
|
||||
writel(reg & ~cf->enable, common->base + common->reg);
|
||||
spin_unlock_irqrestore(common->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_enable, SUNXI_CCU);
|
||||
|
||||
void ccu_frac_helper_disable(struct ccu_common *common,
|
||||
struct ccu_frac_internal *cf)
|
||||
@ -48,6 +50,7 @@ void ccu_frac_helper_disable(struct ccu_common *common,
|
||||
writel(reg | cf->enable, common->base + common->reg);
|
||||
spin_unlock_irqrestore(common->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_disable, SUNXI_CCU);
|
||||
|
||||
bool ccu_frac_helper_has_rate(struct ccu_common *common,
|
||||
struct ccu_frac_internal *cf,
|
||||
@ -58,6 +61,7 @@ bool ccu_frac_helper_has_rate(struct ccu_common *common,
|
||||
|
||||
return (cf->rates[0] == rate) || (cf->rates[1] == rate);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_has_rate, SUNXI_CCU);
|
||||
|
||||
unsigned long ccu_frac_helper_read_rate(struct ccu_common *common,
|
||||
struct ccu_frac_internal *cf)
|
||||
@ -79,6 +83,7 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common,
|
||||
|
||||
return (reg & cf->select) ? cf->rates[1] : cf->rates[0];
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_read_rate, SUNXI_CCU);
|
||||
|
||||
int ccu_frac_helper_set_rate(struct ccu_common *common,
|
||||
struct ccu_frac_internal *cf,
|
||||
@ -107,3 +112,4 @@ int ccu_frac_helper_set_rate(struct ccu_common *common,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_frac_helper_set_rate, SUNXI_CCU);
|
||||
|
@ -24,6 +24,7 @@ void ccu_gate_helper_disable(struct ccu_common *common, u32 gate)
|
||||
|
||||
spin_unlock_irqrestore(common->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_disable, SUNXI_CCU);
|
||||
|
||||
static void ccu_gate_disable(struct clk_hw *hw)
|
||||
{
|
||||
@ -49,6 +50,7 @@ int ccu_gate_helper_enable(struct ccu_common *common, u32 gate)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_enable, SUNXI_CCU);
|
||||
|
||||
static int ccu_gate_enable(struct clk_hw *hw)
|
||||
{
|
||||
@ -64,6 +66,7 @@ int ccu_gate_helper_is_enabled(struct ccu_common *common, u32 gate)
|
||||
|
||||
return readl(common->base + common->reg) & gate;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_gate_helper_is_enabled, SUNXI_CCU);
|
||||
|
||||
static int ccu_gate_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
@ -124,3 +127,4 @@ const struct clk_ops ccu_gate_ops = {
|
||||
.set_rate = ccu_gate_set_rate,
|
||||
.recalc_rate = ccu_gate_recalc_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_gate_ops, SUNXI_CCU);
|
||||
|
@ -53,7 +53,7 @@ struct ccu_gate {
|
||||
}
|
||||
|
||||
/*
|
||||
* The following two macros allow the re-use of the data structure
|
||||
* The following macros allow the re-use of the data structure
|
||||
* holding the parent info.
|
||||
*/
|
||||
#define SUNXI_CCU_GATE_HWS(_struct, _name, _parent, _reg, _gate, _flags) \
|
||||
@ -68,6 +68,21 @@ struct ccu_gate {
|
||||
} \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_GATE_HWS_WITH_PREDIV(_struct, _name, _parent, _reg, \
|
||||
_gate, _prediv, _flags) \
|
||||
struct ccu_gate _struct = { \
|
||||
.enable = _gate, \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.prediv = _prediv, \
|
||||
.features = CCU_FEATURE_ALL_PREDIV, \
|
||||
.hw.init = CLK_HW_INIT_HWS(_name, \
|
||||
_parent, \
|
||||
&ccu_gate_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_GATE_DATA(_struct, _name, _data, _reg, _gate, _flags) \
|
||||
struct ccu_gate _struct = { \
|
||||
.enable = _gate, \
|
||||
@ -81,6 +96,21 @@ struct ccu_gate {
|
||||
} \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_GATE_DATA_WITH_PREDIV(_struct, _name, _parent, _reg, \
|
||||
_gate, _prediv, _flags) \
|
||||
struct ccu_gate _struct = { \
|
||||
.enable = _gate, \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.prediv = _prediv, \
|
||||
.features = CCU_FEATURE_ALL_PREDIV, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \
|
||||
_parent, \
|
||||
&ccu_gate_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
static inline struct ccu_gate *hw_to_ccu_gate(struct clk_hw *hw)
|
||||
{
|
||||
struct ccu_common *common = hw_to_ccu_common(hw);
|
||||
|
@ -245,6 +245,7 @@ const struct clk_ops ccu_mp_ops = {
|
||||
.recalc_rate = ccu_mp_recalc_rate,
|
||||
.set_rate = ccu_mp_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_mp_ops, SUNXI_CCU);
|
||||
|
||||
/*
|
||||
* Support for MMC timing mode switching
|
||||
@ -325,3 +326,4 @@ const struct clk_ops ccu_mp_mmc_ops = {
|
||||
.recalc_rate = ccu_mp_mmc_recalc_rate,
|
||||
.set_rate = ccu_mp_mmc_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_mp_mmc_ops, SUNXI_CCU);
|
||||
|
@ -82,6 +82,55 @@ struct ccu_mp {
|
||||
_muxshift, _muxwidth, \
|
||||
0, _flags)
|
||||
|
||||
#define SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, \
|
||||
_pshift, _pwidth, \
|
||||
_muxshift, _muxwidth, \
|
||||
_gate, _flags) \
|
||||
struct ccu_mp _struct = { \
|
||||
.enable = _gate, \
|
||||
.m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
|
||||
.p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
|
||||
.mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \
|
||||
_parents, \
|
||||
&ccu_mp_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_MP_DATA_WITH_MUX(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, \
|
||||
_pshift, _pwidth, \
|
||||
_muxshift, _muxwidth, \
|
||||
_flags) \
|
||||
SUNXI_CCU_MP_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, \
|
||||
_pshift, _pwidth, \
|
||||
_muxshift, _muxwidth, \
|
||||
0, _flags)
|
||||
|
||||
#define SUNXI_CCU_MP_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
|
||||
_mshift, _mwidth, \
|
||||
_pshift, _pwidth, \
|
||||
_muxshift, _muxwidth, \
|
||||
_gate, _flags) \
|
||||
struct ccu_mp _struct = { \
|
||||
.enable = _gate, \
|
||||
.m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
|
||||
.p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
|
||||
.mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS_HW(_name, \
|
||||
_parents, \
|
||||
&ccu_mp_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
static inline struct ccu_mp *hw_to_ccu_mp(struct clk_hw *hw)
|
||||
{
|
||||
struct ccu_common *common = hw_to_ccu_common(hw);
|
||||
|
@ -170,3 +170,4 @@ const struct clk_ops ccu_mult_ops = {
|
||||
.recalc_rate = ccu_mult_recalc_rate,
|
||||
.set_rate = ccu_mult_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_mult_ops, SUNXI_CCU);
|
||||
|
@ -64,6 +64,7 @@ unsigned long ccu_mux_helper_apply_prediv(struct ccu_common *common,
|
||||
{
|
||||
return parent_rate / ccu_mux_get_prediv(common, cm, parent_index);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_apply_prediv, SUNXI_CCU);
|
||||
|
||||
static unsigned long ccu_mux_helper_unapply_prediv(struct ccu_common *common,
|
||||
struct ccu_mux_internal *cm,
|
||||
@ -152,6 +153,7 @@ out:
|
||||
req->rate = best_rate;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_determine_rate, SUNXI_CCU);
|
||||
|
||||
u8 ccu_mux_helper_get_parent(struct ccu_common *common,
|
||||
struct ccu_mux_internal *cm)
|
||||
@ -174,6 +176,7 @@ u8 ccu_mux_helper_get_parent(struct ccu_common *common,
|
||||
|
||||
return parent;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_get_parent, SUNXI_CCU);
|
||||
|
||||
int ccu_mux_helper_set_parent(struct ccu_common *common,
|
||||
struct ccu_mux_internal *cm,
|
||||
@ -195,6 +198,7 @@ int ccu_mux_helper_set_parent(struct ccu_common *common,
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_mux_helper_set_parent, SUNXI_CCU);
|
||||
|
||||
static void ccu_mux_disable(struct clk_hw *hw)
|
||||
{
|
||||
@ -251,6 +255,7 @@ const struct clk_ops ccu_mux_ops = {
|
||||
.determine_rate = __clk_mux_determine_rate,
|
||||
.recalc_rate = ccu_mux_recalc_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_mux_ops, SUNXI_CCU);
|
||||
|
||||
/*
|
||||
* This clock notifier is called when the frequency of the of the parent
|
||||
@ -285,3 +290,4 @@ int ccu_mux_notifier_register(struct clk *clk, struct ccu_mux_nb *mux_nb)
|
||||
|
||||
return clk_notifier_register(clk, &mux_nb->clk_nb);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_mux_notifier_register, SUNXI_CCU);
|
||||
|
@ -72,6 +72,39 @@ struct ccu_mux {
|
||||
SUNXI_CCU_MUX_TABLE_WITH_GATE(_struct, _name, _parents, NULL, \
|
||||
_reg, _shift, _width, 0, _flags)
|
||||
|
||||
#define SUNXI_CCU_MUX_DATA_WITH_GATE(_struct, _name, _parents, _reg, \
|
||||
_shift, _width, _gate, _flags) \
|
||||
struct ccu_mux _struct = { \
|
||||
.enable = _gate, \
|
||||
.mux = _SUNXI_CCU_MUX(_shift, _width), \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \
|
||||
_parents, \
|
||||
&ccu_mux_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_MUX_DATA(_struct, _name, _parents, _reg, \
|
||||
_shift, _width, _flags) \
|
||||
SUNXI_CCU_MUX_DATA_WITH_GATE(_struct, _name, _parents, _reg, \
|
||||
_shift, _width, 0, _flags)
|
||||
|
||||
#define SUNXI_CCU_MUX_HW_WITH_GATE(_struct, _name, _parents, _reg, \
|
||||
_shift, _width, _gate, _flags) \
|
||||
struct ccu_mux _struct = { \
|
||||
.enable = _gate, \
|
||||
.mux = _SUNXI_CCU_MUX(_shift, _width), \
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.hw.init = CLK_HW_INIT_PARENTS_HW(_name, \
|
||||
_parents, \
|
||||
&ccu_mux_ops, \
|
||||
_flags), \
|
||||
} \
|
||||
}
|
||||
|
||||
static inline struct ccu_mux *hw_to_ccu_mux(struct clk_hw *hw)
|
||||
{
|
||||
struct ccu_common *common = hw_to_ccu_common(hw);
|
||||
|
@ -157,3 +157,4 @@ const struct clk_ops ccu_nk_ops = {
|
||||
.round_rate = ccu_nk_round_rate,
|
||||
.set_rate = ccu_nk_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_nk_ops, SUNXI_CCU);
|
||||
|
@ -206,3 +206,4 @@ const struct clk_ops ccu_nkm_ops = {
|
||||
.recalc_rate = ccu_nkm_recalc_rate,
|
||||
.set_rate = ccu_nkm_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_nkm_ops, SUNXI_CCU);
|
||||
|
@ -230,3 +230,4 @@ const struct clk_ops ccu_nkmp_ops = {
|
||||
.round_rate = ccu_nkmp_round_rate,
|
||||
.set_rate = ccu_nkmp_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_nkmp_ops, SUNXI_CCU);
|
||||
|
@ -238,3 +238,4 @@ const struct clk_ops ccu_nm_ops = {
|
||||
.round_rate = ccu_nm_round_rate,
|
||||
.set_rate = ccu_nm_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_nm_ops, SUNXI_CCU);
|
||||
|
@ -121,3 +121,4 @@ const struct clk_ops ccu_phase_ops = {
|
||||
.get_phase = ccu_phase_get_phase,
|
||||
.set_phase = ccu_phase_set_phase,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_phase_ops, SUNXI_CCU);
|
||||
|
@ -75,3 +75,4 @@ const struct reset_control_ops ccu_reset_ops = {
|
||||
.reset = ccu_reset_reset,
|
||||
.status = ccu_reset_status,
|
||||
};
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_reset_ops, SUNXI_CCU);
|
||||
|
@ -20,6 +20,7 @@ bool ccu_sdm_helper_is_enabled(struct ccu_common *common,
|
||||
|
||||
return !!(readl(common->base + sdm->tuning_reg) & sdm->tuning_enable);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_is_enabled, SUNXI_CCU);
|
||||
|
||||
void ccu_sdm_helper_enable(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
@ -49,6 +50,7 @@ void ccu_sdm_helper_enable(struct ccu_common *common,
|
||||
writel(reg | sdm->enable, common->base + common->reg);
|
||||
spin_unlock_irqrestore(common->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_enable, SUNXI_CCU);
|
||||
|
||||
void ccu_sdm_helper_disable(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm)
|
||||
@ -69,6 +71,7 @@ void ccu_sdm_helper_disable(struct ccu_common *common,
|
||||
writel(reg & ~sdm->tuning_enable, common->base + sdm->tuning_reg);
|
||||
spin_unlock_irqrestore(common->lock, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_disable, SUNXI_CCU);
|
||||
|
||||
/*
|
||||
* Sigma delta modulation provides a way to do fractional-N frequency
|
||||
@ -102,6 +105,7 @@ bool ccu_sdm_helper_has_rate(struct ccu_common *common,
|
||||
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_has_rate, SUNXI_CCU);
|
||||
|
||||
unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
@ -132,6 +136,7 @@ unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
|
||||
/* We can't calculate the effective clock rate, so just fail. */
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_read_rate, SUNXI_CCU);
|
||||
|
||||
int ccu_sdm_helper_get_factors(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
@ -153,3 +158,4 @@ int ccu_sdm_helper_get_factors(struct ccu_common *common,
|
||||
/* nothing found */
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ccu_sdm_helper_get_factors, SUNXI_CCU);
|
||||
|
@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
/*
|
||||
* clock framework for AMD Stoney based clocks
|
||||
* clock framework for AMD FCH controller block
|
||||
*
|
||||
* Copyright 2018 Advanced Micro Devices, Inc.
|
||||
*/
|
||||
@ -8,6 +8,7 @@
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/platform_data/clk-fch.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
@ -26,22 +27,37 @@
|
||||
#define ST_CLK_GATE 3
|
||||
#define ST_MAX_CLKS 4
|
||||
|
||||
#define RV_CLK_48M 0
|
||||
#define RV_CLK_GATE 1
|
||||
#define RV_MAX_CLKS 2
|
||||
#define CLK_48M_FIXED 0
|
||||
#define CLK_GATE_FIXED 1
|
||||
#define CLK_MAX_FIXED 2
|
||||
|
||||
/* List of supported CPU ids for clk mux with 25Mhz clk support */
|
||||
#define AMD_CPU_ID_ST 0x1576
|
||||
|
||||
static const char * const clk_oscout1_parents[] = { "clk48MHz", "clk25MHz" };
|
||||
static struct clk_hw *hws[ST_MAX_CLKS];
|
||||
|
||||
static const struct pci_device_id fch_pci_ids[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, AMD_CPU_ID_ST) },
|
||||
{ }
|
||||
};
|
||||
|
||||
static int fch_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct fch_clk_data *fch_data;
|
||||
struct pci_dev *rdev;
|
||||
|
||||
fch_data = dev_get_platdata(&pdev->dev);
|
||||
if (!fch_data || !fch_data->base)
|
||||
return -EINVAL;
|
||||
|
||||
if (!fch_data->is_rv) {
|
||||
rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
|
||||
if (!rdev) {
|
||||
dev_err(&pdev->dev, "FCH device not found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (pci_match_id(fch_pci_ids, rdev)) {
|
||||
hws[ST_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz",
|
||||
NULL, 0, 48000000);
|
||||
hws[ST_CLK_25M] = clk_hw_register_fixed_rate(NULL, "clk25MHz",
|
||||
@ -59,34 +75,38 @@ static int fch_clk_probe(struct platform_device *pdev)
|
||||
OSCCLKENB, CLK_GATE_SET_TO_DISABLE, NULL);
|
||||
|
||||
devm_clk_hw_register_clkdev(&pdev->dev, hws[ST_CLK_GATE],
|
||||
"oscout1", NULL);
|
||||
fch_data->name, NULL);
|
||||
} else {
|
||||
hws[RV_CLK_48M] = clk_hw_register_fixed_rate(NULL, "clk48MHz",
|
||||
hws[CLK_48M_FIXED] = clk_hw_register_fixed_rate(NULL, "clk48MHz",
|
||||
NULL, 0, 48000000);
|
||||
|
||||
hws[RV_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1",
|
||||
hws[CLK_GATE_FIXED] = clk_hw_register_gate(NULL, "oscout1",
|
||||
"clk48MHz", 0, fch_data->base + MISCCLKCNTL1,
|
||||
OSCCLKENB, CLK_GATE_SET_TO_DISABLE, NULL);
|
||||
OSCCLKENB, 0, NULL);
|
||||
|
||||
devm_clk_hw_register_clkdev(&pdev->dev, hws[RV_CLK_GATE],
|
||||
"oscout1", NULL);
|
||||
devm_clk_hw_register_clkdev(&pdev->dev, hws[CLK_GATE_FIXED],
|
||||
fch_data->name, NULL);
|
||||
}
|
||||
|
||||
pci_dev_put(rdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fch_clk_remove(struct platform_device *pdev)
|
||||
{
|
||||
int i, clks;
|
||||
struct fch_clk_data *fch_data;
|
||||
struct pci_dev *rdev;
|
||||
|
||||
fch_data = dev_get_platdata(&pdev->dev);
|
||||
rdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0, 0));
|
||||
if (!rdev)
|
||||
return -ENODEV;
|
||||
|
||||
clks = fch_data->is_rv ? RV_MAX_CLKS : ST_MAX_CLKS;
|
||||
clks = pci_match_id(fch_pci_ids, rdev) ? CLK_MAX_FIXED : ST_MAX_CLKS;
|
||||
|
||||
for (i = 0; i < clks; i++)
|
||||
clk_hw_unregister(hws[i]);
|
||||
|
||||
pci_dev_put(rdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -144,9 +144,12 @@ static int i2c_acpi_do_lookup(struct acpi_device *adev,
|
||||
struct list_head resource_list;
|
||||
int ret;
|
||||
|
||||
if (acpi_bus_get_status(adev) || !adev->status.present)
|
||||
if (acpi_bus_get_status(adev))
|
||||
return -EINVAL;
|
||||
|
||||
if (!acpi_dev_ready_for_enumeration(adev))
|
||||
return -ENODEV;
|
||||
|
||||
if (acpi_match_device_ids(adev, i2c_acpi_ignored_device_ids) == 0)
|
||||
return -ENODEV;
|
||||
|
||||
@ -473,8 +476,8 @@ struct notifier_block i2c_acpi_notifier = {
|
||||
};
|
||||
|
||||
/**
|
||||
* i2c_acpi_new_device - Create i2c-client for the Nth I2cSerialBus resource
|
||||
* @dev: Device owning the ACPI resources to get the client from
|
||||
* i2c_acpi_new_device_by_fwnode - Create i2c-client for the Nth I2cSerialBus resource
|
||||
* @fwnode: fwnode with the ACPI resources to get the client from
|
||||
* @index: Index of ACPI resource to get
|
||||
* @info: describes the I2C device; note this is modified (addr gets set)
|
||||
* Context: can sleep
|
||||
@ -490,15 +493,20 @@ struct notifier_block i2c_acpi_notifier = {
|
||||
* Returns a pointer to the new i2c-client, or error pointer in case of failure.
|
||||
* Specifically, -EPROBE_DEFER is returned if the adapter is not found.
|
||||
*/
|
||||
struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
|
||||
struct i2c_board_info *info)
|
||||
struct i2c_client *i2c_acpi_new_device_by_fwnode(struct fwnode_handle *fwnode,
|
||||
int index,
|
||||
struct i2c_board_info *info)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
struct i2c_acpi_lookup lookup;
|
||||
struct i2c_adapter *adapter;
|
||||
struct acpi_device *adev;
|
||||
LIST_HEAD(resource_list);
|
||||
int ret;
|
||||
|
||||
adev = to_acpi_device_node(fwnode);
|
||||
if (!adev)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
memset(&lookup, 0, sizeof(lookup));
|
||||
lookup.info = info;
|
||||
lookup.device_handle = acpi_device_handle(adev);
|
||||
@ -520,7 +528,7 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
|
||||
|
||||
return i2c_new_client_device(adapter, info);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
|
||||
EXPORT_SYMBOL_GPL(i2c_acpi_new_device_by_fwnode);
|
||||
|
||||
bool i2c_acpi_waive_d0_probe(struct device *dev)
|
||||
{
|
||||
|
@ -966,6 +966,7 @@ config MMC_REALTEK_USB
|
||||
config MMC_SUNXI
|
||||
tristate "Allwinner sunxi SD/MMC Host Controller support"
|
||||
depends on ARCH_SUNXI || COMPILE_TEST
|
||||
depends on SUNXI_CCU
|
||||
help
|
||||
This selects support for the SD/MMC Host Controller on
|
||||
Allwinner sunxi SoCs.
|
||||
|
@ -1,5 +1,4 @@
|
||||
obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472.o
|
||||
intel_skl_int3472-y := intel_skl_int3472_common.o \
|
||||
intel_skl_int3472_discrete.o \
|
||||
intel_skl_int3472_tps68470.o \
|
||||
intel_skl_int3472_clk_and_regulator.o
|
||||
obj-$(CONFIG_INTEL_SKL_INT3472) += intel_skl_int3472_discrete.o \
|
||||
intel_skl_int3472_tps68470.o
|
||||
intel_skl_int3472_discrete-y := discrete.o clk_and_regulator.o common.o
|
||||
intel_skl_int3472_tps68470-y := tps68470.o tps68470_board_data.o common.o
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "intel_skl_int3472_common.h"
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* The regulators have to have .ops to be valid, but the only ops we actually
|
82
drivers/platform/x86/intel/int3472/common.c
Normal file
82
drivers/platform/x86/intel/int3472/common.c
Normal file
@ -0,0 +1,82 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Author: Dan Scally <djrscally@gmail.com> */
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
|
||||
{
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
acpi_handle handle = adev->handle;
|
||||
union acpi_object *obj;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_object(handle, id, NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
obj = buffer.pointer;
|
||||
if (!obj)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
if (obj->type != ACPI_TYPE_BUFFER) {
|
||||
acpi_handle_err(handle, "%s object is not an ACPI buffer\n", id);
|
||||
kfree(obj);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
|
||||
{
|
||||
union acpi_object *obj;
|
||||
int ret;
|
||||
|
||||
obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
|
||||
if (IS_ERR(obj))
|
||||
return PTR_ERR(obj);
|
||||
|
||||
if (obj->buffer.length > sizeof(*cldb)) {
|
||||
acpi_handle_err(adev->handle, "The CLDB buffer is too large\n");
|
||||
ret = -EINVAL;
|
||||
goto out_free_obj;
|
||||
}
|
||||
|
||||
memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
|
||||
ret = 0;
|
||||
|
||||
out_free_obj:
|
||||
kfree(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* sensor_adev_ret may be NULL, name_ret must not be NULL */
|
||||
int skl_int3472_get_sensor_adev_and_name(struct device *dev,
|
||||
struct acpi_device **sensor_adev_ret,
|
||||
const char **name_ret)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(dev);
|
||||
struct acpi_device *sensor;
|
||||
int ret = 0;
|
||||
|
||||
sensor = acpi_dev_get_first_consumer_dev(adev);
|
||||
if (!sensor) {
|
||||
dev_err(dev, "INT3472 seems to have no dependents.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
*name_ret = devm_kasprintf(dev, GFP_KERNEL, I2C_DEV_NAME_FORMAT,
|
||||
acpi_dev_name(sensor));
|
||||
if (!*name_ret)
|
||||
ret = -ENOMEM;
|
||||
|
||||
if (ret == 0 && sensor_adev_ret)
|
||||
*sensor_adev_ret = sensor;
|
||||
else
|
||||
acpi_dev_put(sensor);
|
||||
|
||||
return ret;
|
||||
}
|
@ -105,12 +105,12 @@ struct int3472_discrete_device {
|
||||
struct gpiod_lookup_table gpios;
|
||||
};
|
||||
|
||||
int skl_int3472_discrete_probe(struct platform_device *pdev);
|
||||
int skl_int3472_discrete_remove(struct platform_device *pdev);
|
||||
int skl_int3472_tps68470_probe(struct i2c_client *client);
|
||||
union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev,
|
||||
char *id);
|
||||
int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb);
|
||||
int skl_int3472_get_sensor_adev_and_name(struct device *dev,
|
||||
struct acpi_device **sensor_adev_ret,
|
||||
const char **name_ret);
|
||||
|
||||
int skl_int3472_register_clock(struct int3472_discrete_device *int3472);
|
||||
void skl_int3472_unregister_clock(struct int3472_discrete_device *int3472);
|
@ -14,7 +14,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/uuid.h>
|
||||
|
||||
#include "intel_skl_int3472_common.h"
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* 79234640-9e10-4fea-a5c1-b5aa8b19756f
|
||||
@ -332,7 +332,9 @@ static int skl_int3472_parse_crs(struct int3472_discrete_device *int3472)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int skl_int3472_discrete_probe(struct platform_device *pdev)
|
||||
static int skl_int3472_discrete_remove(struct platform_device *pdev);
|
||||
|
||||
static int skl_int3472_discrete_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(&pdev->dev);
|
||||
struct int3472_discrete_device *int3472;
|
||||
@ -361,19 +363,10 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
|
||||
int3472->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, int3472);
|
||||
|
||||
int3472->sensor = acpi_dev_get_first_consumer_dev(adev);
|
||||
if (!int3472->sensor) {
|
||||
dev_err(&pdev->dev, "INT3472 seems to have no dependents.\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
int3472->sensor_name = devm_kasprintf(int3472->dev, GFP_KERNEL,
|
||||
I2C_DEV_NAME_FORMAT,
|
||||
acpi_dev_name(int3472->sensor));
|
||||
if (!int3472->sensor_name) {
|
||||
ret = -ENOMEM;
|
||||
goto err_put_sensor;
|
||||
}
|
||||
ret = skl_int3472_get_sensor_adev_and_name(&pdev->dev, &int3472->sensor,
|
||||
&int3472->sensor_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* Initialising this list means we can call gpiod_remove_lookup_table()
|
||||
@ -387,15 +380,11 @@ int skl_int3472_discrete_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
acpi_dev_clear_dependencies(adev);
|
||||
return 0;
|
||||
|
||||
err_put_sensor:
|
||||
acpi_dev_put(int3472->sensor);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int skl_int3472_discrete_remove(struct platform_device *pdev)
|
||||
static int skl_int3472_discrete_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct int3472_discrete_device *int3472 = platform_get_drvdata(pdev);
|
||||
|
||||
@ -411,3 +400,23 @@ int skl_int3472_discrete_remove(struct platform_device *pdev)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id int3472_device_id[] = {
|
||||
{ "INT3472", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, int3472_device_id);
|
||||
|
||||
static struct platform_driver int3472_discrete = {
|
||||
.driver = {
|
||||
.name = "int3472-discrete",
|
||||
.acpi_match_table = int3472_device_id,
|
||||
},
|
||||
.probe = skl_int3472_discrete_probe,
|
||||
.remove = skl_int3472_discrete_remove,
|
||||
};
|
||||
module_platform_driver(int3472_discrete);
|
||||
|
||||
MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Discrete Device Driver");
|
||||
MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -1,106 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Author: Dan Scally <djrscally@gmail.com> */
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "intel_skl_int3472_common.h"
|
||||
|
||||
union acpi_object *skl_int3472_get_acpi_buffer(struct acpi_device *adev, char *id)
|
||||
{
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
|
||||
acpi_handle handle = adev->handle;
|
||||
union acpi_object *obj;
|
||||
acpi_status status;
|
||||
|
||||
status = acpi_evaluate_object(handle, id, NULL, &buffer);
|
||||
if (ACPI_FAILURE(status))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
obj = buffer.pointer;
|
||||
if (!obj)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
if (obj->type != ACPI_TYPE_BUFFER) {
|
||||
acpi_handle_err(handle, "%s object is not an ACPI buffer\n", id);
|
||||
kfree(obj);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
int skl_int3472_fill_cldb(struct acpi_device *adev, struct int3472_cldb *cldb)
|
||||
{
|
||||
union acpi_object *obj;
|
||||
int ret;
|
||||
|
||||
obj = skl_int3472_get_acpi_buffer(adev, "CLDB");
|
||||
if (IS_ERR(obj))
|
||||
return PTR_ERR(obj);
|
||||
|
||||
if (obj->buffer.length > sizeof(*cldb)) {
|
||||
acpi_handle_err(adev->handle, "The CLDB buffer is too large\n");
|
||||
ret = -EINVAL;
|
||||
goto out_free_obj;
|
||||
}
|
||||
|
||||
memcpy(cldb, obj->buffer.pointer, obj->buffer.length);
|
||||
ret = 0;
|
||||
|
||||
out_free_obj:
|
||||
kfree(obj);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id int3472_device_id[] = {
|
||||
{ "INT3472", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, int3472_device_id);
|
||||
|
||||
static struct platform_driver int3472_discrete = {
|
||||
.driver = {
|
||||
.name = "int3472-discrete",
|
||||
.acpi_match_table = int3472_device_id,
|
||||
},
|
||||
.probe = skl_int3472_discrete_probe,
|
||||
.remove = skl_int3472_discrete_remove,
|
||||
};
|
||||
|
||||
static struct i2c_driver int3472_tps68470 = {
|
||||
.driver = {
|
||||
.name = "int3472-tps68470",
|
||||
.acpi_match_table = int3472_device_id,
|
||||
},
|
||||
.probe_new = skl_int3472_tps68470_probe,
|
||||
};
|
||||
|
||||
static int skl_int3472_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&int3472_discrete);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = i2c_register_driver(THIS_MODULE, &int3472_tps68470);
|
||||
if (ret)
|
||||
platform_driver_unregister(&int3472_discrete);
|
||||
|
||||
return ret;
|
||||
}
|
||||
module_init(skl_int3472_init);
|
||||
|
||||
static void skl_int3472_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&int3472_discrete);
|
||||
i2c_del_driver(&int3472_tps68470);
|
||||
}
|
||||
module_exit(skl_int3472_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI Device Driver");
|
||||
MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -2,27 +2,27 @@
|
||||
/* Author: Dan Scally <djrscally@gmail.com> */
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/tps68470.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/tps68470.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "intel_skl_int3472_common.h"
|
||||
#include "common.h"
|
||||
#include "tps68470.h"
|
||||
|
||||
#define DESIGNED_FOR_CHROMEOS 1
|
||||
#define DESIGNED_FOR_WINDOWS 2
|
||||
|
||||
#define TPS68470_WIN_MFD_CELL_COUNT 3
|
||||
|
||||
static const struct mfd_cell tps68470_cros[] = {
|
||||
{ .name = "tps68470-gpio" },
|
||||
{ .name = "tps68470_pmic_opregion" },
|
||||
};
|
||||
|
||||
static const struct mfd_cell tps68470_win[] = {
|
||||
{ .name = "tps68470-gpio" },
|
||||
{ .name = "tps68470-clk" },
|
||||
{ .name = "tps68470-regulator" },
|
||||
};
|
||||
|
||||
static const struct regmap_config tps68470_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@ -95,13 +95,21 @@ static int skl_int3472_tps68470_calc_type(struct acpi_device *adev)
|
||||
return DESIGNED_FOR_WINDOWS;
|
||||
}
|
||||
|
||||
int skl_int3472_tps68470_probe(struct i2c_client *client)
|
||||
static int skl_int3472_tps68470_probe(struct i2c_client *client)
|
||||
{
|
||||
struct acpi_device *adev = ACPI_COMPANION(&client->dev);
|
||||
const struct int3472_tps68470_board_data *board_data;
|
||||
struct tps68470_clk_platform_data clk_pdata = {};
|
||||
struct mfd_cell *cells;
|
||||
struct regmap *regmap;
|
||||
int device_type;
|
||||
int ret;
|
||||
|
||||
ret = skl_int3472_get_sensor_adev_and_name(&client->dev, NULL,
|
||||
&clk_pdata.consumer_dev_name);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(&client->dev, "Failed to create regmap: %ld\n", PTR_ERR(regmap));
|
||||
@ -119,9 +127,38 @@ int skl_int3472_tps68470_probe(struct i2c_client *client)
|
||||
device_type = skl_int3472_tps68470_calc_type(adev);
|
||||
switch (device_type) {
|
||||
case DESIGNED_FOR_WINDOWS:
|
||||
board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
|
||||
if (!board_data)
|
||||
return dev_err_probe(&client->dev, -ENODEV, "No board-data found for this model\n");
|
||||
|
||||
cells = kcalloc(TPS68470_WIN_MFD_CELL_COUNT, sizeof(*cells), GFP_KERNEL);
|
||||
if (!cells)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* The order of the cells matters here! The clk must be first
|
||||
* because the regulator depends on it. The gpios must be last,
|
||||
* acpi_gpiochip_add() calls acpi_dev_clear_dependencies() and
|
||||
* the clk + regulators must be ready when this happens.
|
||||
*/
|
||||
cells[0].name = "tps68470-clk";
|
||||
cells[0].platform_data = &clk_pdata;
|
||||
cells[0].pdata_size = sizeof(clk_pdata);
|
||||
cells[1].name = "tps68470-regulator";
|
||||
cells[1].platform_data = (void *)board_data->tps68470_regulator_pdata;
|
||||
cells[1].pdata_size = sizeof(struct tps68470_regulator_platform_data);
|
||||
cells[2].name = "tps68470-gpio";
|
||||
|
||||
gpiod_add_lookup_table(board_data->tps68470_gpio_lookup_table);
|
||||
|
||||
ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
|
||||
tps68470_win, ARRAY_SIZE(tps68470_win),
|
||||
cells, TPS68470_WIN_MFD_CELL_COUNT,
|
||||
NULL, 0, NULL);
|
||||
kfree(cells);
|
||||
|
||||
if (ret)
|
||||
gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
|
||||
|
||||
break;
|
||||
case DESIGNED_FOR_CHROMEOS:
|
||||
ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
|
||||
@ -133,5 +170,42 @@ int skl_int3472_tps68470_probe(struct i2c_client *client)
|
||||
return device_type;
|
||||
}
|
||||
|
||||
/*
|
||||
* No acpi_dev_clear_dependencies() here, since the acpi_gpiochip_add()
|
||||
* for the GPIO cell already does this.
|
||||
*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int skl_int3472_tps68470_remove(struct i2c_client *client)
|
||||
{
|
||||
const struct int3472_tps68470_board_data *board_data;
|
||||
|
||||
board_data = int3472_tps68470_get_board_data(dev_name(&client->dev));
|
||||
if (board_data)
|
||||
gpiod_remove_lookup_table(board_data->tps68470_gpio_lookup_table);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id int3472_device_id[] = {
|
||||
{ "INT3472", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, int3472_device_id);
|
||||
|
||||
static struct i2c_driver int3472_tps68470 = {
|
||||
.driver = {
|
||||
.name = "int3472-tps68470",
|
||||
.acpi_match_table = int3472_device_id,
|
||||
},
|
||||
.probe_new = skl_int3472_tps68470_probe,
|
||||
.remove = skl_int3472_tps68470_remove,
|
||||
};
|
||||
module_i2c_driver(int3472_tps68470);
|
||||
|
||||
MODULE_DESCRIPTION("Intel SkyLake INT3472 ACPI TPS68470 Device Driver");
|
||||
MODULE_AUTHOR("Daniel Scally <djrscally@gmail.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_SOFTDEP("pre: clk-tps68470 tps68470-regulator");
|
25
drivers/platform/x86/intel/int3472/tps68470.h
Normal file
25
drivers/platform/x86/intel/int3472/tps68470.h
Normal file
@ -0,0 +1,25 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* TI TPS68470 PMIC platform data definition.
|
||||
*
|
||||
* Copyright (c) 2021 Red Hat Inc.
|
||||
*
|
||||
* Red Hat authors:
|
||||
* Hans de Goede <hdegoede@redhat.com>
|
||||
*/
|
||||
|
||||
#ifndef _INTEL_SKL_INT3472_TPS68470_H
|
||||
#define _INTEL_SKL_INT3472_TPS68470_H
|
||||
|
||||
struct gpiod_lookup_table;
|
||||
struct tps68470_regulator_platform_data;
|
||||
|
||||
struct int3472_tps68470_board_data {
|
||||
const char *dev_name;
|
||||
struct gpiod_lookup_table *tps68470_gpio_lookup_table;
|
||||
const struct tps68470_regulator_platform_data *tps68470_regulator_pdata;
|
||||
};
|
||||
|
||||
const struct int3472_tps68470_board_data *int3472_tps68470_get_board_data(const char *dev_name);
|
||||
|
||||
#endif
|
145
drivers/platform/x86/intel/int3472/tps68470_board_data.c
Normal file
145
drivers/platform/x86/intel/int3472/tps68470_board_data.c
Normal file
@ -0,0 +1,145 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* TI TPS68470 PMIC platform data definition.
|
||||
*
|
||||
* Copyright (c) 2021 Dan Scally <djrscally@gmail.com>
|
||||
* Copyright (c) 2021 Red Hat Inc.
|
||||
*
|
||||
* Red Hat authors:
|
||||
* Hans de Goede <hdegoede@redhat.com>
|
||||
*/
|
||||
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/platform_data/tps68470.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include "tps68470.h"
|
||||
|
||||
static struct regulator_consumer_supply int347a_core_consumer_supplies[] = {
|
||||
REGULATOR_SUPPLY("dvdd", "i2c-INT347A:00"),
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply int347a_ana_consumer_supplies[] = {
|
||||
REGULATOR_SUPPLY("avdd", "i2c-INT347A:00"),
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply int347a_vcm_consumer_supplies[] = {
|
||||
REGULATOR_SUPPLY("vdd", "i2c-INT347A:00-VCM"),
|
||||
};
|
||||
|
||||
static struct regulator_consumer_supply int347a_vsio_consumer_supplies[] = {
|
||||
REGULATOR_SUPPLY("dovdd", "i2c-INT347A:00"),
|
||||
REGULATOR_SUPPLY("vsio", "i2c-INT347A:00-VCM"),
|
||||
};
|
||||
|
||||
static const struct regulator_init_data surface_go_tps68470_core_reg_init_data = {
|
||||
.constraints = {
|
||||
.min_uV = 1200000,
|
||||
.max_uV = 1200000,
|
||||
.apply_uV = true,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(int347a_core_consumer_supplies),
|
||||
.consumer_supplies = int347a_core_consumer_supplies,
|
||||
};
|
||||
|
||||
static const struct regulator_init_data surface_go_tps68470_ana_reg_init_data = {
|
||||
.constraints = {
|
||||
.min_uV = 2815200,
|
||||
.max_uV = 2815200,
|
||||
.apply_uV = true,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(int347a_ana_consumer_supplies),
|
||||
.consumer_supplies = int347a_ana_consumer_supplies,
|
||||
};
|
||||
|
||||
static const struct regulator_init_data surface_go_tps68470_vcm_reg_init_data = {
|
||||
.constraints = {
|
||||
.min_uV = 2815200,
|
||||
.max_uV = 2815200,
|
||||
.apply_uV = true,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(int347a_vcm_consumer_supplies),
|
||||
.consumer_supplies = int347a_vcm_consumer_supplies,
|
||||
};
|
||||
|
||||
/* Ensure the always-on VIO regulator has the same voltage as VSIO */
|
||||
static const struct regulator_init_data surface_go_tps68470_vio_reg_init_data = {
|
||||
.constraints = {
|
||||
.min_uV = 1800600,
|
||||
.max_uV = 1800600,
|
||||
.apply_uV = true,
|
||||
.always_on = true,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regulator_init_data surface_go_tps68470_vsio_reg_init_data = {
|
||||
.constraints = {
|
||||
.min_uV = 1800600,
|
||||
.max_uV = 1800600,
|
||||
.apply_uV = true,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
|
||||
},
|
||||
.num_consumer_supplies = ARRAY_SIZE(int347a_vsio_consumer_supplies),
|
||||
.consumer_supplies = int347a_vsio_consumer_supplies,
|
||||
};
|
||||
|
||||
static const struct tps68470_regulator_platform_data surface_go_tps68470_pdata = {
|
||||
.reg_init_data = {
|
||||
[TPS68470_CORE] = &surface_go_tps68470_core_reg_init_data,
|
||||
[TPS68470_ANA] = &surface_go_tps68470_ana_reg_init_data,
|
||||
[TPS68470_VCM] = &surface_go_tps68470_vcm_reg_init_data,
|
||||
[TPS68470_VIO] = &surface_go_tps68470_vio_reg_init_data,
|
||||
[TPS68470_VSIO] = &surface_go_tps68470_vsio_reg_init_data,
|
||||
},
|
||||
};
|
||||
|
||||
static struct gpiod_lookup_table surface_go_tps68470_gpios = {
|
||||
.dev_id = "i2c-INT347A:00",
|
||||
.table = {
|
||||
GPIO_LOOKUP("tps68470-gpio", 9, "reset", GPIO_ACTIVE_LOW),
|
||||
GPIO_LOOKUP("tps68470-gpio", 7, "powerdown", GPIO_ACTIVE_LOW)
|
||||
}
|
||||
};
|
||||
|
||||
static const struct int3472_tps68470_board_data surface_go_tps68470_board_data = {
|
||||
.dev_name = "i2c-INT3472:05",
|
||||
.tps68470_gpio_lookup_table = &surface_go_tps68470_gpios,
|
||||
.tps68470_regulator_pdata = &surface_go_tps68470_pdata,
|
||||
};
|
||||
|
||||
static const struct dmi_system_id int3472_tps68470_board_data_table[] = {
|
||||
{
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Go"),
|
||||
},
|
||||
.driver_data = (void *)&surface_go_tps68470_board_data,
|
||||
},
|
||||
{
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Surface Go 2"),
|
||||
},
|
||||
.driver_data = (void *)&surface_go_tps68470_board_data,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
const struct int3472_tps68470_board_data *int3472_tps68470_get_board_data(const char *dev_name)
|
||||
{
|
||||
const struct int3472_tps68470_board_data *board_data;
|
||||
const struct dmi_system_id *match;
|
||||
|
||||
for (match = dmi_first_match(int3472_tps68470_board_data_table);
|
||||
match;
|
||||
match = dmi_first_match(match + 1)) {
|
||||
board_data = match->driver_data;
|
||||
if (strcmp(board_data->dev_name, dev_name) == 0)
|
||||
return board_data;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
@ -202,7 +202,8 @@ struct acpi_device_flags {
|
||||
u32 coherent_dma:1;
|
||||
u32 cca_seen:1;
|
||||
u32 enumeration_by_parent:1;
|
||||
u32 reserved:19;
|
||||
u32 honor_deps:1;
|
||||
u32 reserved:18;
|
||||
};
|
||||
|
||||
/* File System */
|
||||
@ -285,6 +286,7 @@ struct acpi_dep_data {
|
||||
struct list_head node;
|
||||
acpi_handle supplier;
|
||||
acpi_handle consumer;
|
||||
bool honor_dep;
|
||||
};
|
||||
|
||||
/* Performance Management */
|
||||
@ -693,6 +695,7 @@ static inline bool acpi_device_can_poweroff(struct acpi_device *adev)
|
||||
bool acpi_dev_hid_uid_match(struct acpi_device *adev, const char *hid2, const char *uid2);
|
||||
|
||||
void acpi_dev_clear_dependencies(struct acpi_device *supplier);
|
||||
bool acpi_dev_ready_for_enumeration(const struct acpi_device *device);
|
||||
struct acpi_device *acpi_dev_get_first_consumer_dev(struct acpi_device *supplier);
|
||||
struct acpi_device *
|
||||
acpi_dev_get_next_match_dev(struct acpi_device *adev, const char *hid, const char *uid, s64 hrv);
|
||||
|
156
include/dt-bindings/clock/sun20i-d1-ccu.h
Normal file
156
include/dt-bindings/clock/sun20i-d1-ccu.h
Normal file
@ -0,0 +1,156 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
|
||||
/*
|
||||
* Copyright (C) 2020 huangzhenwei@allwinnertech.com
|
||||
* Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_
|
||||
#define _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_
|
||||
|
||||
#define CLK_PLL_CPUX 0
|
||||
#define CLK_PLL_DDR0 1
|
||||
#define CLK_PLL_PERIPH0_4X 2
|
||||
#define CLK_PLL_PERIPH0_2X 3
|
||||
#define CLK_PLL_PERIPH0_800M 4
|
||||
#define CLK_PLL_PERIPH0 5
|
||||
#define CLK_PLL_PERIPH0_DIV3 6
|
||||
#define CLK_PLL_VIDEO0_4X 7
|
||||
#define CLK_PLL_VIDEO0_2X 8
|
||||
#define CLK_PLL_VIDEO0 9
|
||||
#define CLK_PLL_VIDEO1_4X 10
|
||||
#define CLK_PLL_VIDEO1_2X 11
|
||||
#define CLK_PLL_VIDEO1 12
|
||||
#define CLK_PLL_VE 13
|
||||
#define CLK_PLL_AUDIO0_4X 14
|
||||
#define CLK_PLL_AUDIO0_2X 15
|
||||
#define CLK_PLL_AUDIO0 16
|
||||
#define CLK_PLL_AUDIO1 17
|
||||
#define CLK_PLL_AUDIO1_DIV2 18
|
||||
#define CLK_PLL_AUDIO1_DIV5 19
|
||||
#define CLK_CPUX 20
|
||||
#define CLK_CPUX_AXI 21
|
||||
#define CLK_CPUX_APB 22
|
||||
#define CLK_PSI_AHB 23
|
||||
#define CLK_APB0 24
|
||||
#define CLK_APB1 25
|
||||
#define CLK_MBUS 26
|
||||
#define CLK_DE 27
|
||||
#define CLK_BUS_DE 28
|
||||
#define CLK_DI 29
|
||||
#define CLK_BUS_DI 30
|
||||
#define CLK_G2D 31
|
||||
#define CLK_BUS_G2D 32
|
||||
#define CLK_CE 33
|
||||
#define CLK_BUS_CE 34
|
||||
#define CLK_VE 35
|
||||
#define CLK_BUS_VE 36
|
||||
#define CLK_BUS_DMA 37
|
||||
#define CLK_BUS_MSGBOX0 38
|
||||
#define CLK_BUS_MSGBOX1 39
|
||||
#define CLK_BUS_MSGBOX2 40
|
||||
#define CLK_BUS_SPINLOCK 41
|
||||
#define CLK_BUS_HSTIMER 42
|
||||
#define CLK_AVS 43
|
||||
#define CLK_BUS_DBG 44
|
||||
#define CLK_BUS_PWM 45
|
||||
#define CLK_BUS_IOMMU 46
|
||||
#define CLK_DRAM 47
|
||||
#define CLK_MBUS_DMA 48
|
||||
#define CLK_MBUS_VE 49
|
||||
#define CLK_MBUS_CE 50
|
||||
#define CLK_MBUS_TVIN 51
|
||||
#define CLK_MBUS_CSI 52
|
||||
#define CLK_MBUS_G2D 53
|
||||
#define CLK_MBUS_RISCV 54
|
||||
#define CLK_BUS_DRAM 55
|
||||
#define CLK_MMC0 56
|
||||
#define CLK_MMC1 57
|
||||
#define CLK_MMC2 58
|
||||
#define CLK_BUS_MMC0 59
|
||||
#define CLK_BUS_MMC1 60
|
||||
#define CLK_BUS_MMC2 61
|
||||
#define CLK_BUS_UART0 62
|
||||
#define CLK_BUS_UART1 63
|
||||
#define CLK_BUS_UART2 64
|
||||
#define CLK_BUS_UART3 65
|
||||
#define CLK_BUS_UART4 66
|
||||
#define CLK_BUS_UART5 67
|
||||
#define CLK_BUS_I2C0 68
|
||||
#define CLK_BUS_I2C1 69
|
||||
#define CLK_BUS_I2C2 70
|
||||
#define CLK_BUS_I2C3 71
|
||||
#define CLK_SPI0 72
|
||||
#define CLK_SPI1 73
|
||||
#define CLK_BUS_SPI0 74
|
||||
#define CLK_BUS_SPI1 75
|
||||
#define CLK_EMAC_25M 76
|
||||
#define CLK_BUS_EMAC 77
|
||||
#define CLK_IR_TX 78
|
||||
#define CLK_BUS_IR_TX 79
|
||||
#define CLK_BUS_GPADC 80
|
||||
#define CLK_BUS_THS 81
|
||||
#define CLK_I2S0 82
|
||||
#define CLK_I2S1 83
|
||||
#define CLK_I2S2 84
|
||||
#define CLK_I2S2_ASRC 85
|
||||
#define CLK_BUS_I2S0 86
|
||||
#define CLK_BUS_I2S1 87
|
||||
#define CLK_BUS_I2S2 88
|
||||
#define CLK_SPDIF_TX 89
|
||||
#define CLK_SPDIF_RX 90
|
||||
#define CLK_BUS_SPDIF 91
|
||||
#define CLK_DMIC 92
|
||||
#define CLK_BUS_DMIC 93
|
||||
#define CLK_AUDIO_DAC 94
|
||||
#define CLK_AUDIO_ADC 95
|
||||
#define CLK_BUS_AUDIO 96
|
||||
#define CLK_USB_OHCI0 97
|
||||
#define CLK_USB_OHCI1 98
|
||||
#define CLK_BUS_OHCI0 99
|
||||
#define CLK_BUS_OHCI1 100
|
||||
#define CLK_BUS_EHCI0 101
|
||||
#define CLK_BUS_EHCI1 102
|
||||
#define CLK_BUS_OTG 103
|
||||
#define CLK_BUS_LRADC 104
|
||||
#define CLK_BUS_DPSS_TOP 105
|
||||
#define CLK_HDMI_24M 106
|
||||
#define CLK_HDMI_CEC_32K 107
|
||||
#define CLK_HDMI_CEC 108
|
||||
#define CLK_BUS_HDMI 109
|
||||
#define CLK_MIPI_DSI 110
|
||||
#define CLK_BUS_MIPI_DSI 111
|
||||
#define CLK_TCON_LCD0 112
|
||||
#define CLK_BUS_TCON_LCD0 113
|
||||
#define CLK_TCON_TV 114
|
||||
#define CLK_BUS_TCON_TV 115
|
||||
#define CLK_TVE 116
|
||||
#define CLK_BUS_TVE_TOP 117
|
||||
#define CLK_BUS_TVE 118
|
||||
#define CLK_TVD 119
|
||||
#define CLK_BUS_TVD_TOP 120
|
||||
#define CLK_BUS_TVD 121
|
||||
#define CLK_LEDC 122
|
||||
#define CLK_BUS_LEDC 123
|
||||
#define CLK_CSI_TOP 124
|
||||
#define CLK_CSI_MCLK 125
|
||||
#define CLK_BUS_CSI 126
|
||||
#define CLK_TPADC 127
|
||||
#define CLK_BUS_TPADC 128
|
||||
#define CLK_BUS_TZMA 129
|
||||
#define CLK_DSP 130
|
||||
#define CLK_BUS_DSP_CFG 131
|
||||
#define CLK_RISCV 132
|
||||
#define CLK_RISCV_AXI 133
|
||||
#define CLK_BUS_RISCV_CFG 134
|
||||
#define CLK_FANOUT_24M 135
|
||||
#define CLK_FANOUT_12M 136
|
||||
#define CLK_FANOUT_16M 137
|
||||
#define CLK_FANOUT_25M 138
|
||||
#define CLK_FANOUT_32K 139
|
||||
#define CLK_FANOUT_27M 140
|
||||
#define CLK_FANOUT_PCLK 141
|
||||
#define CLK_FANOUT0 142
|
||||
#define CLK_FANOUT1 143
|
||||
#define CLK_FANOUT2 144
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_SUN20I_D1_CCU_H_ */
|
19
include/dt-bindings/clock/sun20i-d1-r-ccu.h
Normal file
19
include/dt-bindings/clock/sun20i-d1-r-ccu.h
Normal file
@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
|
||||
/*
|
||||
* Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_
|
||||
#define _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_
|
||||
|
||||
#define CLK_R_AHB 0
|
||||
|
||||
#define CLK_BUS_R_TIMER 2
|
||||
#define CLK_BUS_R_TWD 3
|
||||
#define CLK_BUS_R_PPU 4
|
||||
#define CLK_R_IR_RX 5
|
||||
#define CLK_BUS_R_IR_RX 6
|
||||
#define CLK_BUS_R_RTC 7
|
||||
#define CLK_BUS_R_CPUCFG 8
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_SUN20I_D1_R_CCU_H_ */
|
77
include/dt-bindings/reset/sun20i-d1-ccu.h
Normal file
77
include/dt-bindings/reset/sun20i-d1-ccu.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
|
||||
/*
|
||||
* Copyright (c) 2020 huangzhenwei@allwinnertech.com
|
||||
* Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_RST_SUN20I_D1_CCU_H_
|
||||
#define _DT_BINDINGS_RST_SUN20I_D1_CCU_H_
|
||||
|
||||
#define RST_MBUS 0
|
||||
#define RST_BUS_DE 1
|
||||
#define RST_BUS_DI 2
|
||||
#define RST_BUS_G2D 3
|
||||
#define RST_BUS_CE 4
|
||||
#define RST_BUS_VE 5
|
||||
#define RST_BUS_DMA 6
|
||||
#define RST_BUS_MSGBOX0 7
|
||||
#define RST_BUS_MSGBOX1 8
|
||||
#define RST_BUS_MSGBOX2 9
|
||||
#define RST_BUS_SPINLOCK 10
|
||||
#define RST_BUS_HSTIMER 11
|
||||
#define RST_BUS_DBG 12
|
||||
#define RST_BUS_PWM 13
|
||||
#define RST_BUS_DRAM 14
|
||||
#define RST_BUS_MMC0 15
|
||||
#define RST_BUS_MMC1 16
|
||||
#define RST_BUS_MMC2 17
|
||||
#define RST_BUS_UART0 18
|
||||
#define RST_BUS_UART1 19
|
||||
#define RST_BUS_UART2 20
|
||||
#define RST_BUS_UART3 21
|
||||
#define RST_BUS_UART4 22
|
||||
#define RST_BUS_UART5 23
|
||||
#define RST_BUS_I2C0 24
|
||||
#define RST_BUS_I2C1 25
|
||||
#define RST_BUS_I2C2 26
|
||||
#define RST_BUS_I2C3 27
|
||||
#define RST_BUS_SPI0 28
|
||||
#define RST_BUS_SPI1 29
|
||||
#define RST_BUS_EMAC 30
|
||||
#define RST_BUS_IR_TX 31
|
||||
#define RST_BUS_GPADC 32
|
||||
#define RST_BUS_THS 33
|
||||
#define RST_BUS_I2S0 34
|
||||
#define RST_BUS_I2S1 35
|
||||
#define RST_BUS_I2S2 36
|
||||
#define RST_BUS_SPDIF 37
|
||||
#define RST_BUS_DMIC 38
|
||||
#define RST_BUS_AUDIO 39
|
||||
#define RST_USB_PHY0 40
|
||||
#define RST_USB_PHY1 41
|
||||
#define RST_BUS_OHCI0 42
|
||||
#define RST_BUS_OHCI1 43
|
||||
#define RST_BUS_EHCI0 44
|
||||
#define RST_BUS_EHCI1 45
|
||||
#define RST_BUS_OTG 46
|
||||
#define RST_BUS_LRADC 47
|
||||
#define RST_BUS_DPSS_TOP 48
|
||||
#define RST_BUS_HDMI_SUB 49
|
||||
#define RST_BUS_HDMI_MAIN 50
|
||||
#define RST_BUS_MIPI_DSI 51
|
||||
#define RST_BUS_TCON_LCD0 52
|
||||
#define RST_BUS_TCON_TV 53
|
||||
#define RST_BUS_LVDS0 54
|
||||
#define RST_BUS_TVE 55
|
||||
#define RST_BUS_TVE_TOP 56
|
||||
#define RST_BUS_TVD 57
|
||||
#define RST_BUS_TVD_TOP 58
|
||||
#define RST_BUS_LEDC 59
|
||||
#define RST_BUS_CSI 60
|
||||
#define RST_BUS_TPADC 61
|
||||
#define RST_DSP 62
|
||||
#define RST_BUS_DSP_CFG 63
|
||||
#define RST_BUS_DSP_DBG 64
|
||||
#define RST_BUS_RISCV_CFG 65
|
||||
|
||||
#endif /* _DT_BINDINGS_RST_SUN20I_D1_CCU_H_ */
|
16
include/dt-bindings/reset/sun20i-d1-r-ccu.h
Normal file
16
include/dt-bindings/reset/sun20i-d1-r-ccu.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0+ or MIT) */
|
||||
/*
|
||||
* Copyright (C) 2021 Samuel Holland <samuel@sholland.org>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_
|
||||
#define _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_
|
||||
|
||||
#define RST_BUS_R_TIMER 0
|
||||
#define RST_BUS_R_TWD 1
|
||||
#define RST_BUS_R_PPU 2
|
||||
#define RST_BUS_R_IR_RX 3
|
||||
#define RST_BUS_R_RTC 4
|
||||
#define RST_BUS_R_CPUCFG 5
|
||||
|
||||
#endif /* _DT_BINDINGS_RST_SUN20I_D1_R_CCU_H_ */
|
@ -6,22 +6,7 @@
|
||||
#ifndef _LINUX_CLK_SUNXI_NG_H_
|
||||
#define _LINUX_CLK_SUNXI_NG_H_
|
||||
|
||||
#include <linux/errno.h>
|
||||
|
||||
#ifdef CONFIG_SUNXI_CCU
|
||||
int sunxi_ccu_set_mmc_timing_mode(struct clk *clk, bool new_mode);
|
||||
int sunxi_ccu_get_mmc_timing_mode(struct clk *clk);
|
||||
#else
|
||||
static inline int sunxi_ccu_set_mmc_timing_mode(struct clk *clk,
|
||||
bool new_mode)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int sunxi_ccu_get_mmc_timing_mode(struct clk *clk)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1025,8 +1025,9 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
|
||||
struct acpi_resource_i2c_serialbus **i2c);
|
||||
int i2c_acpi_client_count(struct acpi_device *adev);
|
||||
u32 i2c_acpi_find_bus_speed(struct device *dev);
|
||||
struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
|
||||
struct i2c_board_info *info);
|
||||
struct i2c_client *i2c_acpi_new_device_by_fwnode(struct fwnode_handle *fwnode,
|
||||
int index,
|
||||
struct i2c_board_info *info);
|
||||
struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle);
|
||||
bool i2c_acpi_waive_d0_probe(struct device *dev);
|
||||
#else
|
||||
@ -1043,8 +1044,9 @@ static inline u32 i2c_acpi_find_bus_speed(struct device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline struct i2c_client *i2c_acpi_new_device(struct device *dev,
|
||||
int index, struct i2c_board_info *info)
|
||||
static inline struct i2c_client *i2c_acpi_new_device_by_fwnode(
|
||||
struct fwnode_handle *fwnode, int index,
|
||||
struct i2c_board_info *info)
|
||||
{
|
||||
return ERR_PTR(-ENODEV);
|
||||
}
|
||||
@ -1058,4 +1060,11 @@ static inline bool i2c_acpi_waive_d0_probe(struct device *dev)
|
||||
}
|
||||
#endif /* CONFIG_ACPI */
|
||||
|
||||
static inline struct i2c_client *i2c_acpi_new_device(struct device *dev,
|
||||
int index,
|
||||
struct i2c_board_info *info)
|
||||
{
|
||||
return i2c_acpi_new_device_by_fwnode(dev_fwnode(dev), index, info);
|
||||
}
|
||||
|
||||
#endif /* _LINUX_I2C_H */
|
||||
|
@ -75,6 +75,17 @@
|
||||
#define TPS68470_CLKCFG1_MODE_A_MASK GENMASK(1, 0)
|
||||
#define TPS68470_CLKCFG1_MODE_B_MASK GENMASK(3, 2)
|
||||
|
||||
#define TPS68470_CLKCFG2_DRV_STR_2MA 0x05
|
||||
#define TPS68470_PLL_OUTPUT_ENABLE 0x02
|
||||
#define TPS68470_CLK_SRC_XTAL BIT(0)
|
||||
#define TPS68470_PLLSWR_DEFAULT GENMASK(1, 0)
|
||||
#define TPS68470_OSC_EXT_CAP_DEFAULT 0x05
|
||||
|
||||
#define TPS68470_OUTPUT_A_SHIFT 0x00
|
||||
#define TPS68470_OUTPUT_B_SHIFT 0x02
|
||||
#define TPS68470_CLK_SRC_SHIFT GENMASK(2, 0)
|
||||
#define TPS68470_OSC_EXT_CAP_SHIFT BIT(2)
|
||||
|
||||
#define TPS68470_GPIO_CTL_REG_A(x) (TPS68470_REG_GPCTL0A + (x) * 2)
|
||||
#define TPS68470_GPIO_CTL_REG_B(x) (TPS68470_REG_GPCTL0B + (x) * 2)
|
||||
#define TPS68470_GPIO_MODE_MASK GENMASK(1, 0)
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
struct fch_clk_data {
|
||||
void __iomem *base;
|
||||
u32 is_rv;
|
||||
char *name;
|
||||
};
|
||||
|
||||
#endif /* __CLK_FCH_H */
|
||||
|
35
include/linux/platform_data/tps68470.h
Normal file
35
include/linux/platform_data/tps68470.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* TI TPS68470 PMIC platform data definition.
|
||||
*
|
||||
* Copyright (c) 2021 Red Hat Inc.
|
||||
*
|
||||
* Red Hat authors:
|
||||
* Hans de Goede <hdegoede@redhat.com>
|
||||
*/
|
||||
#ifndef __PDATA_TPS68470_H
|
||||
#define __PDATA_TPS68470_H
|
||||
|
||||
enum tps68470_regulators {
|
||||
TPS68470_CORE,
|
||||
TPS68470_ANA,
|
||||
TPS68470_VCM,
|
||||
TPS68470_VIO,
|
||||
TPS68470_VSIO,
|
||||
TPS68470_AUX1,
|
||||
TPS68470_AUX2,
|
||||
TPS68470_NUM_REGULATORS
|
||||
};
|
||||
|
||||
struct regulator_init_data;
|
||||
|
||||
struct tps68470_regulator_platform_data {
|
||||
const struct regulator_init_data *reg_init_data[TPS68470_NUM_REGULATORS];
|
||||
};
|
||||
|
||||
struct tps68470_clk_platform_data {
|
||||
const char *consumer_dev_name;
|
||||
const char *consumer_con_id;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user