Samsung SoC clock drivers changes for 6.4

1. Exynos850: Add CMU_G3D clock controller for the Mali GPU.  This
    brings new PLLs and few cleanups/simplifications in core Exynos clock
    controller code, so they can be easier re-used in Exynos850 clock
    controller driver.
    New CMU_G3D clock controller needs Devicetree bindings header changes
    with clock indices which are pulled from Samsung SoC repository.
 
 2. Extract Exynos5433 (ARM64) clock controller power management code to
    common driver parts, so later it can be re-used by other Exynos clock
    controller drivers.  This only prepares for such re-usage, which is
    expected to come later for Exynos850.
 
 3. Exynos850: make PMU_ALIVE_PCLK clock critical, because it is needed
    for core block - Power Management Unit.
 
 4. Cleanup: remove() callback returns void.
 -----BEGIN PGP SIGNATURE-----
 
 iQJEBAABCgAuFiEE3dJiKD0RGyM7briowTdm5oaLg9cFAmQq/w4QHGtyemtAa2Vy
 bmVsLm9yZwAKCRDBN2bmhouD13e1EACPzodn79YLuJLWP9O1vQDWlJhyr0WBpy/p
 dusjrgBSlgOP11rc1mSVM4iCNsfB4KVICVArGTCRaXCIhi8+qrzQBWIBF2UmZEKP
 YMzNKiOVBZl+ZNZH+h7WndvY9aZwSSGim7kbJ5Gx3MvKyFFJvw/48xbGKTJTvNUf
 ZoT4X0JmYCTXhspat0syeGuFdt8NAMPeo4Zf1xbbtGWf0nmuTnG3aDanjdvjPtwE
 nFBC/O1i9xTS1wpchD7wUU5zZrL54jzNCJxbHB05itWO3jsPM8vKKdAZY9ZLYQFz
 d2Uzkcsvc4KkCfNKfyanGhVjwdj3lhsh4jqDburAJUmWxclT1O9bBHEPXof8/C1I
 0q47Pja6hwLYG0KB5/JWjTSLVnYktU1lTVLCpg3WKuti3PZ2VMxQh+tAZa8xoz9n
 Lh9B67fLMPGV8kr+ovQrGzKLIPboR98BawSU/TDko0u3SgpNTf8Xjrnmrd6G0t28
 CgteSjzua4/i3/aV82PJsxjAY87FLhf4iCjsJN4KAYZ+7sJj363Zc/P6g7Ur003P
 0wC/4tQKM/GMGLIJwChBTv9Skvom3TKuWdkazEcsFJdRGcrvZUPQ/m1G27qjD0Qs
 lSXydrIJvp0XgH6V/65hGYQ3Zd65W2xChFaab2yNqLyol59hKvWFSsEp337Zy3Ef
 QJ5z+UYZug==
 =IafV
 -----END PGP SIGNATURE-----

Merge tag 'samsung-clk-6.4' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into clk-samsung

Pull Samsung SoC clk drivers updates from Krzysztof Kozlowski:

 - Exynos850: Add CMU_G3D clock controller for the Mali GPU.  This
   brings new PLLs and few cleanups/simplifications in core Exynos clock
   controller code, so they can be easier re-used in Exynos850 clock
   controller driver.
   New CMU_G3D clock controller needs Devicetree bindings header changes
   with clock indices which are pulled from Samsung SoC repository.

 - Extract Exynos5433 (ARM64) clock controller power management code to
   common driver parts, so later it can be re-used by other Exynos clock
   controller drivers.  This only prepares for such re-usage, which is
   expected to come later for Exynos850.

 - Exynos850: make PMU_ALIVE_PCLK clock critical, because it is needed
   for core block - Power Management Unit.

 - Cleanup: remove() callback returns void.

* tag 'samsung-clk-6.4' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux:
  clk: samsung: exynos850: Make PMU_ALIVE_PCLK critical
  clk: samsung: Convert to platform remove callback returning void
  clk: samsung: exynos5433: Extract PM support to common ARM64 layer
  clk: samsung: Extract parent clock enabling to common function
  clk: samsung: Extract clocks registration to common function
  clk: samsung: exynos850: Add AUD and HSI main gate clocks
  clk: samsung: exynos850: Implement CMU_G3D domain
  clk: samsung: clk-pll: Implement pll0818x PLL type
  clk: samsung: Set dev in samsung_clk_init()
  clk: samsung: Don't pass reg_base to samsung_clk_register_pll()
  clk: samsung: Remove np argument from samsung_clk_init()
  dt-bindings: clock: exynos850: Add AUD and HSI main gate clocks
  dt-bindings: clock: exynos850: Add Exynos850 CMU_G3D
This commit is contained in:
Stephen Boyd 2023-04-03 12:05:23 -07:00
commit ef382228d2
18 changed files with 474 additions and 229 deletions

View File

@ -37,6 +37,7 @@ properties:
- samsung,exynos850-cmu-cmgp
- samsung,exynos850-cmu-core
- samsung,exynos850-cmu-dpu
- samsung,exynos850-cmu-g3d
- samsung,exynos850-cmu-hsi
- samsung,exynos850-cmu-is
- samsung,exynos850-cmu-mfcmscl
@ -169,6 +170,24 @@ allOf:
- const: oscclk
- const: dout_dpu
- if:
properties:
compatible:
contains:
const: samsung,exynos850-cmu-g3d
then:
properties:
clocks:
items:
- description: External reference clock (26 MHz)
- description: G3D clock (from CMU_TOP)
clock-names:
items:
- const: oscclk
- const: dout_g3d_switch
- if:
properties:
compatible:

View File

@ -10,6 +10,9 @@
*/
#include <linux/clk.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include "clk-exynos-arm64.h"
@ -21,6 +24,19 @@
#define GATE_OFF_START 0x2000
#define GATE_OFF_END 0x2fff
struct exynos_arm64_cmu_data {
struct samsung_clk_reg_dump *clk_save;
unsigned int nr_clk_save;
const struct samsung_clk_reg_dump *clk_suspend;
unsigned int nr_clk_suspend;
struct clk *clk;
struct clk **pclks;
int nr_pclks;
struct samsung_clk_provider *ctx;
};
/**
* exynos_arm64_init_clocks - Set clocks initial configuration
* @np: CMU device tree node with "reg" property (CMU addr)
@ -56,6 +72,83 @@ static void __init exynos_arm64_init_clocks(struct device_node *np,
iounmap(reg_base);
}
/**
* exynos_arm64_enable_bus_clk - Enable parent clock of specified CMU
*
* @dev: Device object; may be NULL if this function is not being
* called from platform driver probe function
* @np: CMU device tree node
* @cmu: CMU data
*
* Keep CMU parent clock running (needed for CMU registers access).
*
* Return: 0 on success or a negative error code on failure.
*/
static int __init exynos_arm64_enable_bus_clk(struct device *dev,
struct device_node *np, const struct samsung_cmu_info *cmu)
{
struct clk *parent_clk;
if (!cmu->clk_name)
return 0;
if (dev) {
struct exynos_arm64_cmu_data *data;
parent_clk = clk_get(dev, cmu->clk_name);
data = dev_get_drvdata(dev);
if (data)
data->clk = parent_clk;
} else {
parent_clk = of_clk_get_by_name(np, cmu->clk_name);
}
if (IS_ERR(parent_clk))
return PTR_ERR(parent_clk);
return clk_prepare_enable(parent_clk);
}
static int __init exynos_arm64_cmu_prepare_pm(struct device *dev,
const struct samsung_cmu_info *cmu)
{
struct exynos_arm64_cmu_data *data = dev_get_drvdata(dev);
int i;
data->clk_save = samsung_clk_alloc_reg_dump(cmu->clk_regs,
cmu->nr_clk_regs);
if (!data->clk_save)
return -ENOMEM;
data->nr_clk_save = cmu->nr_clk_regs;
data->clk_suspend = cmu->suspend_regs;
data->nr_clk_suspend = cmu->nr_suspend_regs;
data->nr_pclks = of_clk_get_parent_count(dev->of_node);
if (!data->nr_pclks)
return 0;
data->pclks = devm_kcalloc(dev, sizeof(struct clk *), data->nr_pclks,
GFP_KERNEL);
if (!data->pclks) {
kfree(data->clk_save);
return -ENOMEM;
}
for (i = 0; i < data->nr_pclks; i++) {
struct clk *clk = of_clk_get(dev->of_node, i);
if (IS_ERR(clk)) {
kfree(data->clk_save);
while (--i >= 0)
clk_put(data->pclks[i]);
return PTR_ERR(clk);
}
data->pclks[i] = clk;
}
return 0;
}
/**
* exynos_arm64_register_cmu - Register specified Exynos CMU domain
* @dev: Device object; may be NULL if this function is not being
@ -72,23 +165,127 @@ static void __init exynos_arm64_init_clocks(struct device_node *np,
void __init exynos_arm64_register_cmu(struct device *dev,
struct device_node *np, const struct samsung_cmu_info *cmu)
{
/* Keep CMU parent clock running (needed for CMU registers access) */
if (cmu->clk_name) {
struct clk *parent_clk;
int err;
if (dev)
parent_clk = clk_get(dev, cmu->clk_name);
else
parent_clk = of_clk_get_by_name(np, cmu->clk_name);
if (IS_ERR(parent_clk)) {
pr_err("%s: could not find bus clock %s; err = %ld\n",
__func__, cmu->clk_name, PTR_ERR(parent_clk));
} else {
clk_prepare_enable(parent_clk);
}
}
/*
* Try to boot even if the parent clock enablement fails, as it might be
* already enabled by bootloader.
*/
err = exynos_arm64_enable_bus_clk(dev, np, cmu);
if (err)
pr_err("%s: could not enable bus clock %s; err = %d\n",
__func__, cmu->clk_name, err);
exynos_arm64_init_clocks(np, cmu->clk_regs, cmu->nr_clk_regs);
samsung_cmu_register_one(np, cmu);
}
/**
* exynos_arm64_register_cmu_pm - Register Exynos CMU domain with PM support
*
* @pdev: Platform device object
* @set_manual: If true, set gate clocks to manual mode
*
* It's a version of exynos_arm64_register_cmu() with PM support. Should be
* called from probe function of platform driver.
*
* Return: 0 on success, or negative error code on error.
*/
int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev,
bool set_manual)
{
const struct samsung_cmu_info *cmu;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct exynos_arm64_cmu_data *data;
void __iomem *reg_base;
int ret;
cmu = of_device_get_match_data(dev);
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
platform_set_drvdata(pdev, data);
ret = exynos_arm64_cmu_prepare_pm(dev, cmu);
if (ret)
return ret;
/*
* Try to boot even if the parent clock enablement fails, as it might be
* already enabled by bootloader.
*/
ret = exynos_arm64_enable_bus_clk(dev, NULL, cmu);
if (ret)
dev_err(dev, "%s: could not enable bus clock %s; err = %d\n",
__func__, cmu->clk_name, ret);
if (set_manual)
exynos_arm64_init_clocks(np, cmu->clk_regs, cmu->nr_clk_regs);
reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(reg_base))
return PTR_ERR(reg_base);
data->ctx = samsung_clk_init(dev, reg_base, cmu->nr_clk_ids);
/*
* Enable runtime PM here to allow the clock core using runtime PM
* for the registered clocks. Additionally, we increase the runtime
* PM usage count before registering the clocks, to prevent the
* clock core from runtime suspending the device.
*/
pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
samsung_cmu_register_clocks(data->ctx, cmu);
samsung_clk_of_add_provider(dev->of_node, data->ctx);
pm_runtime_put_sync(dev);
return 0;
}
int exynos_arm64_cmu_suspend(struct device *dev)
{
struct exynos_arm64_cmu_data *data = dev_get_drvdata(dev);
int i;
samsung_clk_save(data->ctx->reg_base, data->clk_save,
data->nr_clk_save);
for (i = 0; i < data->nr_pclks; i++)
clk_prepare_enable(data->pclks[i]);
/* For suspend some registers have to be set to certain values */
samsung_clk_restore(data->ctx->reg_base, data->clk_suspend,
data->nr_clk_suspend);
for (i = 0; i < data->nr_pclks; i++)
clk_disable_unprepare(data->pclks[i]);
clk_disable_unprepare(data->clk);
return 0;
}
int exynos_arm64_cmu_resume(struct device *dev)
{
struct exynos_arm64_cmu_data *data = dev_get_drvdata(dev);
int i;
clk_prepare_enable(data->clk);
for (i = 0; i < data->nr_pclks; i++)
clk_prepare_enable(data->pclks[i]);
samsung_clk_restore(data->ctx->reg_base, data->clk_save,
data->nr_clk_save);
for (i = 0; i < data->nr_pclks; i++)
clk_disable_unprepare(data->pclks[i]);
return 0;
}

View File

@ -16,5 +16,8 @@
void exynos_arm64_register_cmu(struct device *dev,
struct device_node *np, const struct samsung_cmu_info *cmu);
int exynos_arm64_register_cmu_pm(struct platform_device *pdev, bool set_manual);
int exynos_arm64_cmu_suspend(struct device *dev);
int exynos_arm64_cmu_resume(struct device *dev);
#endif /* __CLK_EXYNOS_ARM64_H */

View File

@ -268,7 +268,7 @@ unregister:
return ret;
}
static int exynos_audss_clk_remove(struct platform_device *pdev)
static void exynos_audss_clk_remove(struct platform_device *pdev)
{
of_clk_del_provider(pdev->dev.of_node);
@ -277,8 +277,6 @@ static int exynos_audss_clk_remove(struct platform_device *pdev)
if (!IS_ERR(epll))
clk_disable_unprepare(epll);
return 0;
}
static const struct dev_pm_ops exynos_audss_clk_pm_ops = {
@ -295,7 +293,7 @@ static struct platform_driver exynos_audss_clk_driver = {
.pm = &exynos_audss_clk_pm_ops,
},
.probe = exynos_audss_clk_probe,
.remove = exynos_audss_clk_remove,
.remove_new = exynos_audss_clk_remove,
};
module_platform_driver(exynos_audss_clk_driver);

View File

@ -196,15 +196,13 @@ clks_put:
return ret;
}
static int exynos_clkout_remove(struct platform_device *pdev)
static void exynos_clkout_remove(struct platform_device *pdev)
{
struct exynos_clkout *clkout = platform_get_drvdata(pdev);
of_clk_del_provider(clkout->np);
clk_hw_unregister(clkout->data.hws[0]);
iounmap(clkout->reg);
return 0;
}
static int __maybe_unused exynos_clkout_suspend(struct device *dev)
@ -235,7 +233,7 @@ static struct platform_driver exynos_clkout_driver = {
.pm = &exynos_clkout_pm_ops,
},
.probe = exynos_clkout_probe,
.remove = exynos_clkout_remove,
.remove_new = exynos_clkout_remove,
};
module_platform_driver(exynos_clkout_driver);

View File

@ -1251,7 +1251,7 @@ static void __init exynos4_clk_init(struct device_node *np,
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
ctx = samsung_clk_init(NULL, reg_base, CLK_NR_CLKS);
hws = ctx->clk_data.hws;
samsung_clk_of_register_fixed_ext(ctx, exynos4_fixed_rate_ext_clks,
@ -1276,7 +1276,7 @@ static void __init exynos4_clk_init(struct device_node *np,
exynos4210_vpll_rates;
samsung_clk_register_pll(ctx, exynos4210_plls,
ARRAY_SIZE(exynos4210_plls), reg_base);
ARRAY_SIZE(exynos4210_plls));
} else {
if (clk_hw_get_rate(hws[CLK_FIN_PLL]) == 24000000) {
exynos4x12_plls[apll].rate_table =
@ -1288,7 +1288,7 @@ static void __init exynos4_clk_init(struct device_node *np,
}
samsung_clk_register_pll(ctx, exynos4x12_plls,
ARRAY_SIZE(exynos4x12_plls), reg_base);
ARRAY_SIZE(exynos4x12_plls));
}
samsung_clk_register_fixed_rate(ctx, exynos4_fixed_rate_clks,

View File

@ -121,8 +121,7 @@ static int __init exynos4x12_isp_clk_probe(struct platform_device *pdev)
if (!exynos4x12_save_isp)
return -ENOMEM;
ctx = samsung_clk_init(np, reg_base, CLK_NR_ISP_CLKS);
ctx->dev = dev;
ctx = samsung_clk_init(dev, reg_base, CLK_NR_ISP_CLKS);
platform_set_drvdata(pdev, ctx);

View File

@ -797,7 +797,7 @@ static void __init exynos5250_clk_init(struct device_node *np)
panic("%s: unable to determine soc\n", __func__);
}
ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
ctx = samsung_clk_init(NULL, reg_base, CLK_NR_CLKS);
hws = ctx->clk_data.hws;
samsung_clk_of_register_fixed_ext(ctx, exynos5250_fixed_rate_ext_clks,
@ -815,8 +815,7 @@ static void __init exynos5250_clk_init(struct device_node *np)
exynos5250_plls[vpll].rate_table = vpll_24mhz_tbl;
samsung_clk_register_pll(ctx, exynos5250_plls,
ARRAY_SIZE(exynos5250_plls),
reg_base);
ARRAY_SIZE(exynos5250_plls));
samsung_clk_register_fixed_rate(ctx, exynos5250_fixed_rate_clks,
ARRAY_SIZE(exynos5250_fixed_rate_clks));
samsung_clk_register_fixed_factor(ctx, exynos5250_fixed_factor_clks,

View File

@ -1587,7 +1587,7 @@ static void __init exynos5x_clk_init(struct device_node *np,
exynos5x_soc = soc;
ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS);
ctx = samsung_clk_init(NULL, reg_base, CLK_NR_CLKS);
hws = ctx->clk_data.hws;
samsung_clk_of_register_fixed_ext(ctx, exynos5x_fixed_rate_ext_clks,
@ -1606,8 +1606,7 @@ static void __init exynos5x_clk_init(struct device_node *np,
else
exynos5x_plls[bpll].rate_table = exynos5422_bpll_rate_table;
samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls),
reg_base);
samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls));
samsung_clk_register_fixed_rate(ctx, exynos5x_fixed_rate_clks,
ARRAY_SIZE(exynos5x_fixed_rate_clks));
samsung_clk_register_fixed_factor(ctx, exynos5x_fixed_factor_clks,

View File

@ -10,7 +10,6 @@
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
@ -19,6 +18,7 @@
#include "clk.h"
#include "clk-cpu.h"
#include "clk-exynos-arm64.h"
#include "clk-pll.h"
/*
@ -5478,160 +5478,9 @@ static const struct samsung_cmu_info imem_cmu_info __initconst = {
.clk_name = "aclk_imem_200",
};
struct exynos5433_cmu_data {
struct samsung_clk_reg_dump *clk_save;
unsigned int nr_clk_save;
const struct samsung_clk_reg_dump *clk_suspend;
unsigned int nr_clk_suspend;
struct clk *clk;
struct clk **pclks;
int nr_pclks;
/* must be the last entry */
struct samsung_clk_provider ctx;
};
static int __maybe_unused exynos5433_cmu_suspend(struct device *dev)
{
struct exynos5433_cmu_data *data = dev_get_drvdata(dev);
int i;
samsung_clk_save(data->ctx.reg_base, data->clk_save,
data->nr_clk_save);
for (i = 0; i < data->nr_pclks; i++)
clk_prepare_enable(data->pclks[i]);
/* for suspend some registers have to be set to certain values */
samsung_clk_restore(data->ctx.reg_base, data->clk_suspend,
data->nr_clk_suspend);
for (i = 0; i < data->nr_pclks; i++)
clk_disable_unprepare(data->pclks[i]);
clk_disable_unprepare(data->clk);
return 0;
}
static int __maybe_unused exynos5433_cmu_resume(struct device *dev)
{
struct exynos5433_cmu_data *data = dev_get_drvdata(dev);
int i;
clk_prepare_enable(data->clk);
for (i = 0; i < data->nr_pclks; i++)
clk_prepare_enable(data->pclks[i]);
samsung_clk_restore(data->ctx.reg_base, data->clk_save,
data->nr_clk_save);
for (i = 0; i < data->nr_pclks; i++)
clk_disable_unprepare(data->pclks[i]);
return 0;
}
static int __init exynos5433_cmu_probe(struct platform_device *pdev)
{
const struct samsung_cmu_info *info;
struct exynos5433_cmu_data *data;
struct samsung_clk_provider *ctx;
struct device *dev = &pdev->dev;
void __iomem *reg_base;
int i;
info = of_device_get_match_data(dev);
data = devm_kzalloc(dev,
struct_size(data, ctx.clk_data.hws, info->nr_clk_ids),
GFP_KERNEL);
if (!data)
return -ENOMEM;
ctx = &data->ctx;
reg_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(reg_base))
return PTR_ERR(reg_base);
for (i = 0; i < info->nr_clk_ids; ++i)
ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
ctx->clk_data.num = info->nr_clk_ids;
ctx->reg_base = reg_base;
ctx->dev = dev;
spin_lock_init(&ctx->lock);
data->clk_save = samsung_clk_alloc_reg_dump(info->clk_regs,
info->nr_clk_regs);
if (!data->clk_save)
return -ENOMEM;
data->nr_clk_save = info->nr_clk_regs;
data->clk_suspend = info->suspend_regs;
data->nr_clk_suspend = info->nr_suspend_regs;
data->nr_pclks = of_clk_get_parent_count(dev->of_node);
if (data->nr_pclks > 0) {
data->pclks = devm_kcalloc(dev, sizeof(struct clk *),
data->nr_pclks, GFP_KERNEL);
if (!data->pclks) {
kfree(data->clk_save);
return -ENOMEM;
}
for (i = 0; i < data->nr_pclks; i++) {
struct clk *clk = of_clk_get(dev->of_node, i);
if (IS_ERR(clk)) {
kfree(data->clk_save);
while (--i >= 0)
clk_put(data->pclks[i]);
return PTR_ERR(clk);
}
data->pclks[i] = clk;
}
}
if (info->clk_name)
data->clk = clk_get(dev, info->clk_name);
clk_prepare_enable(data->clk);
platform_set_drvdata(pdev, data);
/*
* Enable runtime PM here to allow the clock core using runtime PM
* for the registered clocks. Additionally, we increase the runtime
* PM usage count before registering the clocks, to prevent the
* clock core from runtime suspending the device.
*/
pm_runtime_get_noresume(dev);
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
if (info->pll_clks)
samsung_clk_register_pll(ctx, info->pll_clks, info->nr_pll_clks,
reg_base);
if (info->mux_clks)
samsung_clk_register_mux(ctx, info->mux_clks,
info->nr_mux_clks);
if (info->div_clks)
samsung_clk_register_div(ctx, info->div_clks,
info->nr_div_clks);
if (info->gate_clks)
samsung_clk_register_gate(ctx, info->gate_clks,
info->nr_gate_clks);
if (info->fixed_clks)
samsung_clk_register_fixed_rate(ctx, info->fixed_clks,
info->nr_fixed_clks);
if (info->fixed_factor_clks)
samsung_clk_register_fixed_factor(ctx, info->fixed_factor_clks,
info->nr_fixed_factor_clks);
samsung_clk_of_add_provider(dev->of_node, ctx);
pm_runtime_put_sync(dev);
return 0;
return exynos_arm64_register_cmu_pm(pdev, false);
}
static const struct of_device_id exynos5433_cmu_of_match[] = {
@ -5679,7 +5528,7 @@ static const struct of_device_id exynos5433_cmu_of_match[] = {
};
static const struct dev_pm_ops exynos5433_cmu_pm_ops = {
SET_RUNTIME_PM_OPS(exynos5433_cmu_suspend, exynos5433_cmu_resume,
SET_RUNTIME_PM_OPS(exynos_arm64_cmu_suspend, exynos_arm64_cmu_resume,
NULL)
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)

View File

@ -36,6 +36,7 @@
#define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD 0x101c
#define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS 0x1020
#define CLK_CON_MUX_MUX_CLKCMU_DPU 0x1034
#define CLK_CON_MUX_MUX_CLKCMU_G3D_SWITCH 0x1038
#define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS 0x103c
#define CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD 0x1040
#define CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD 0x1044
@ -57,6 +58,7 @@
#define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD 0x1828
#define CLK_CON_DIV_CLKCMU_CORE_SSS 0x182c
#define CLK_CON_DIV_CLKCMU_DPU 0x1840
#define CLK_CON_DIV_CLKCMU_G3D_SWITCH 0x1844
#define CLK_CON_DIV_CLKCMU_HSI_BUS 0x1848
#define CLK_CON_DIV_CLKCMU_HSI_MMC_CARD 0x184c
#define CLK_CON_DIV_CLKCMU_HSI_USB20DRD 0x1850
@ -84,6 +86,7 @@
#define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD 0x2024
#define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS 0x2028
#define CLK_CON_GAT_GATE_CLKCMU_DPU 0x203c
#define CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH 0x2040
#define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS 0x2044
#define CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD 0x2048
#define CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD 0x204c
@ -116,6 +119,7 @@ static const unsigned long top_clk_regs[] __initconst = {
CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD,
CLK_CON_MUX_MUX_CLKCMU_CORE_SSS,
CLK_CON_MUX_MUX_CLKCMU_DPU,
CLK_CON_MUX_MUX_CLKCMU_G3D_SWITCH,
CLK_CON_MUX_MUX_CLKCMU_HSI_BUS,
CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD,
CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD,
@ -137,6 +141,7 @@ static const unsigned long top_clk_regs[] __initconst = {
CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD,
CLK_CON_DIV_CLKCMU_CORE_SSS,
CLK_CON_DIV_CLKCMU_DPU,
CLK_CON_DIV_CLKCMU_G3D_SWITCH,
CLK_CON_DIV_CLKCMU_HSI_BUS,
CLK_CON_DIV_CLKCMU_HSI_MMC_CARD,
CLK_CON_DIV_CLKCMU_HSI_USB20DRD,
@ -164,6 +169,7 @@ static const unsigned long top_clk_regs[] __initconst = {
CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD,
CLK_CON_GAT_GATE_CLKCMU_CORE_SSS,
CLK_CON_GAT_GATE_CLKCMU_DPU,
CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH,
CLK_CON_GAT_GATE_CLKCMU_HSI_BUS,
CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD,
CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD,
@ -216,6 +222,9 @@ PNAME(mout_core_mmc_embd_p) = { "oscclk", "dout_shared0_div2",
"oscclk", "oscclk" };
PNAME(mout_core_sss_p) = { "dout_shared0_div3", "dout_shared1_div3",
"dout_shared0_div4", "dout_shared1_div4" };
/* List of parent clocks for Muxes in CMU_TOP: for CMU_G3D */
PNAME(mout_g3d_switch_p) = { "dout_shared0_div2", "dout_shared1_div2",
"dout_shared0_div3", "dout_shared1_div3" };
/* List of parent clocks for Muxes in CMU_TOP: for CMU_HSI */
PNAME(mout_hsi_bus_p) = { "dout_shared0_div2", "dout_shared1_div2" };
PNAME(mout_hsi_mmc_card_p) = { "oscclk", "dout_shared0_div2",
@ -283,6 +292,10 @@ static const struct samsung_mux_clock top_mux_clks[] __initconst = {
MUX(CLK_MOUT_DPU, "mout_dpu", mout_dpu_p,
CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 2),
/* G3D */
MUX(CLK_MOUT_G3D_SWITCH, "mout_g3d_switch", mout_g3d_switch_p,
CLK_CON_MUX_MUX_CLKCMU_G3D_SWITCH, 0, 2),
/* HSI */
MUX(CLK_MOUT_HSI_BUS, "mout_hsi_bus", mout_hsi_bus_p,
CLK_CON_MUX_MUX_CLKCMU_HSI_BUS, 0, 1),
@ -357,6 +370,10 @@ static const struct samsung_div_clock top_div_clks[] __initconst = {
DIV(CLK_DOUT_DPU, "dout_dpu", "gout_dpu",
CLK_CON_DIV_CLKCMU_DPU, 0, 4),
/* G3D */
DIV(CLK_DOUT_G3D_SWITCH, "dout_g3d_switch", "gout_g3d_switch",
CLK_CON_DIV_CLKCMU_G3D_SWITCH, 0, 3),
/* HSI */
DIV(CLK_DOUT_HSI_BUS, "dout_hsi_bus", "gout_hsi_bus",
CLK_CON_DIV_CLKCMU_HSI_BUS, 0, 4),
@ -417,6 +434,10 @@ static const struct samsung_gate_clock top_gate_clks[] __initconst = {
GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu",
CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0),
/* G3D */
GATE(CLK_GOUT_G3D_SWITCH, "gout_g3d_switch", "mout_g3d_switch",
CLK_CON_GAT_GATE_CLKCMU_G3D_SWITCH, 21, 0, 0),
/* HSI */
GATE(CLK_GOUT_HSI_BUS, "gout_hsi_bus", "mout_hsi_bus",
CLK_CON_GAT_GATE_CLKCMU_HSI_BUS, 21, 0, 0),
@ -591,7 +612,7 @@ static const struct samsung_gate_clock apm_gate_clks[] __initconst = {
CLK_CON_GAT_GOUT_APM_APBIF_GPIO_ALIVE_PCLK, 21, CLK_IGNORE_UNUSED,
0),
GATE(CLK_GOUT_PMU_ALIVE_PCLK, "gout_pmu_alive_pclk", "dout_apm_bus",
CLK_CON_GAT_GOUT_APM_APBIF_PMU_ALIVE_PCLK, 21, 0, 0),
CLK_CON_GAT_GOUT_APM_APBIF_PMU_ALIVE_PCLK, 21, CLK_IS_CRITICAL, 0),
GATE(CLK_GOUT_SYSREG_APM_PCLK, "gout_sysreg_apm_pclk", "dout_apm_bus",
CLK_CON_GAT_GOUT_APM_SYSREG_APM_PCLK, 21, 0, 0),
};
@ -653,6 +674,7 @@ static const struct samsung_cmu_info apm_cmu_info __initconst = {
#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF4 0x2014
#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF5 0x2018
#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF6 0x201c
#define CLK_CON_GAT_CLK_AUD_CMU_AUD_PCLK 0x2020
#define CLK_CON_GAT_GOUT_AUD_ABOX_ACLK 0x2048
#define CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_SPDY 0x204c
#define CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_ASB 0x2050
@ -708,6 +730,7 @@ static const unsigned long aud_clk_regs[] __initconst = {
CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF4,
CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF5,
CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_UAIF6,
CLK_CON_GAT_CLK_AUD_CMU_AUD_PCLK,
CLK_CON_GAT_GOUT_AUD_ABOX_ACLK,
CLK_CON_GAT_GOUT_AUD_ABOX_BCLK_SPDY,
CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_ASB,
@ -827,6 +850,9 @@ static const struct samsung_div_clock aud_div_clks[] __initconst = {
};
static const struct samsung_gate_clock aud_gate_clks[] __initconst = {
GATE(CLK_GOUT_AUD_CMU_AUD_PCLK, "gout_aud_cmu_aud_pclk",
"dout_aud_busd",
CLK_CON_GAT_CLK_AUD_CMU_AUD_PCLK, 21, CLK_IGNORE_UNUSED, 0),
GATE(CLK_GOUT_AUD_CA32_CCLK, "gout_aud_ca32_cclk", "mout_aud_cpu_hch",
CLK_CON_GAT_GOUT_AUD_ABOX_CCLK_CA32, 21, 0, 0),
GATE(CLK_GOUT_AUD_ASB_CCLK, "gout_aud_asb_cclk", "dout_aud_cpu_aclk",
@ -992,6 +1018,102 @@ static const struct samsung_cmu_info cmgp_cmu_info __initconst = {
.clk_name = "gout_clkcmu_cmgp_bus",
};
/* ---- CMU_G3D ------------------------------------------------------------- */
/* Register Offset definitions for CMU_G3D (0x11400000) */
#define PLL_LOCKTIME_PLL_G3D 0x0000
#define PLL_CON0_PLL_G3D 0x0100
#define PLL_CON3_PLL_G3D 0x010c
#define PLL_CON0_MUX_CLKCMU_G3D_SWITCH_USER 0x0600
#define CLK_CON_MUX_MUX_CLK_G3D_BUSD 0x1000
#define CLK_CON_DIV_DIV_CLK_G3D_BUSP 0x1804
#define CLK_CON_GAT_CLK_G3D_CMU_G3D_PCLK 0x2000
#define CLK_CON_GAT_CLK_G3D_GPU_CLK 0x2004
#define CLK_CON_GAT_GOUT_G3D_TZPC_PCLK 0x200c
#define CLK_CON_GAT_GOUT_G3D_GRAY2BIN_CLK 0x2010
#define CLK_CON_GAT_GOUT_G3D_BUSD_CLK 0x2024
#define CLK_CON_GAT_GOUT_G3D_BUSP_CLK 0x2028
#define CLK_CON_GAT_GOUT_G3D_SYSREG_PCLK 0x202c
static const unsigned long g3d_clk_regs[] __initconst = {
PLL_LOCKTIME_PLL_G3D,
PLL_CON0_PLL_G3D,
PLL_CON3_PLL_G3D,
PLL_CON0_MUX_CLKCMU_G3D_SWITCH_USER,
CLK_CON_MUX_MUX_CLK_G3D_BUSD,
CLK_CON_DIV_DIV_CLK_G3D_BUSP,
CLK_CON_GAT_CLK_G3D_CMU_G3D_PCLK,
CLK_CON_GAT_CLK_G3D_GPU_CLK,
CLK_CON_GAT_GOUT_G3D_TZPC_PCLK,
CLK_CON_GAT_GOUT_G3D_GRAY2BIN_CLK,
CLK_CON_GAT_GOUT_G3D_BUSD_CLK,
CLK_CON_GAT_GOUT_G3D_BUSP_CLK,
CLK_CON_GAT_GOUT_G3D_SYSREG_PCLK,
};
/* List of parent clocks for Muxes in CMU_G3D */
PNAME(mout_g3d_pll_p) = { "oscclk", "fout_g3d_pll" };
PNAME(mout_g3d_switch_user_p) = { "oscclk", "dout_g3d_switch" };
PNAME(mout_g3d_busd_p) = { "mout_g3d_pll", "mout_g3d_switch_user" };
/*
* Do not provide PLL table to PLL_G3D, as MANUAL_PLL_CTRL bit is not set
* for that PLL by default, so set_rate operation would fail.
*/
static const struct samsung_pll_clock g3d_pll_clks[] __initconst = {
PLL(pll_0818x, CLK_FOUT_G3D_PLL, "fout_g3d_pll", "oscclk",
PLL_LOCKTIME_PLL_G3D, PLL_CON3_PLL_G3D, NULL),
};
static const struct samsung_mux_clock g3d_mux_clks[] __initconst = {
MUX(CLK_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p,
PLL_CON0_PLL_G3D, 4, 1),
MUX(CLK_MOUT_G3D_SWITCH_USER, "mout_g3d_switch_user",
mout_g3d_switch_user_p,
PLL_CON0_MUX_CLKCMU_G3D_SWITCH_USER, 4, 1),
MUX(CLK_MOUT_G3D_BUSD, "mout_g3d_busd", mout_g3d_busd_p,
CLK_CON_MUX_MUX_CLK_G3D_BUSD, 0, 1),
};
static const struct samsung_div_clock g3d_div_clks[] __initconst = {
DIV(CLK_DOUT_G3D_BUSP, "dout_g3d_busp", "mout_g3d_busd",
CLK_CON_DIV_DIV_CLK_G3D_BUSP, 0, 3),
};
static const struct samsung_gate_clock g3d_gate_clks[] __initconst = {
GATE(CLK_GOUT_G3D_CMU_G3D_PCLK, "gout_g3d_cmu_g3d_pclk",
"dout_g3d_busp",
CLK_CON_GAT_CLK_G3D_CMU_G3D_PCLK, 21, CLK_IGNORE_UNUSED, 0),
GATE(CLK_GOUT_G3D_GPU_CLK, "gout_g3d_gpu_clk", "mout_g3d_busd",
CLK_CON_GAT_CLK_G3D_GPU_CLK, 21, 0, 0),
GATE(CLK_GOUT_G3D_TZPC_PCLK, "gout_g3d_tzpc_pclk", "dout_g3d_busp",
CLK_CON_GAT_GOUT_G3D_TZPC_PCLK, 21, 0, 0),
GATE(CLK_GOUT_G3D_GRAY2BIN_CLK, "gout_g3d_gray2bin_clk",
"mout_g3d_busd",
CLK_CON_GAT_GOUT_G3D_GRAY2BIN_CLK, 21, 0, 0),
GATE(CLK_GOUT_G3D_BUSD_CLK, "gout_g3d_busd_clk", "mout_g3d_busd",
CLK_CON_GAT_GOUT_G3D_BUSD_CLK, 21, 0, 0),
GATE(CLK_GOUT_G3D_BUSP_CLK, "gout_g3d_busp_clk", "dout_g3d_busp",
CLK_CON_GAT_GOUT_G3D_BUSP_CLK, 21, 0, 0),
GATE(CLK_GOUT_G3D_SYSREG_PCLK, "gout_g3d_sysreg_pclk", "dout_g3d_busp",
CLK_CON_GAT_GOUT_G3D_SYSREG_PCLK, 21, 0, 0),
};
static const struct samsung_cmu_info g3d_cmu_info __initconst = {
.pll_clks = g3d_pll_clks,
.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks),
.mux_clks = g3d_mux_clks,
.nr_mux_clks = ARRAY_SIZE(g3d_mux_clks),
.div_clks = g3d_div_clks,
.nr_div_clks = ARRAY_SIZE(g3d_div_clks),
.gate_clks = g3d_gate_clks,
.nr_gate_clks = ARRAY_SIZE(g3d_gate_clks),
.nr_clk_ids = G3D_NR_CLK,
.clk_regs = g3d_clk_regs,
.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs),
.clk_name = "dout_g3d_switch",
};
/* ---- CMU_HSI ------------------------------------------------------------- */
/* Register Offset definitions for CMU_HSI (0x13400000) */
@ -999,12 +1121,15 @@ static const struct samsung_cmu_info cmgp_cmu_info __initconst = {
#define PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER 0x0610
#define PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER 0x0620
#define CLK_CON_MUX_MUX_CLK_HSI_RTC 0x1000
#define CLK_CON_GAT_CLK_HSI_CMU_HSI_PCLK 0x2000
#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV 0x2008
#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50 0x200c
#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26 0x2010
#define CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK 0x2018
#define CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK 0x2024
#define CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN 0x2028
#define CLK_CON_GAT_GOUT_HSI_PPMU_ACLK 0x202c
#define CLK_CON_GAT_GOUT_HSI_PPMU_PCLK 0x2030
#define CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK 0x2038
#define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20 0x203c
#define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY 0x2040
@ -1014,12 +1139,15 @@ static const unsigned long hsi_clk_regs[] __initconst = {
PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER,
PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER,
CLK_CON_MUX_MUX_CLK_HSI_RTC,
CLK_CON_GAT_CLK_HSI_CMU_HSI_PCLK,
CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV,
CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50,
CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26,
CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK,
CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK,
CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN,
CLK_CON_GAT_GOUT_HSI_PPMU_ACLK,
CLK_CON_GAT_GOUT_HSI_PPMU_PCLK,
CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK,
CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20,
CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY,
@ -1045,6 +1173,10 @@ static const struct samsung_mux_clock hsi_mux_clks[] __initconst = {
};
static const struct samsung_gate_clock hsi_gate_clks[] __initconst = {
/* TODO: Should be enabled in corresponding driver */
GATE(CLK_GOUT_HSI_CMU_HSI_PCLK, "gout_hsi_cmu_hsi_pclk",
"mout_hsi_bus_user",
CLK_CON_GAT_CLK_HSI_CMU_HSI_PCLK, 21, CLK_IGNORE_UNUSED, 0),
GATE(CLK_GOUT_USB_RTC_CLK, "gout_usb_rtc", "mout_hsi_rtc",
CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV, 21, 0, 0),
GATE(CLK_GOUT_USB_REF_CLK, "gout_usb_ref", "mout_hsi_usb20drd_user",
@ -1059,6 +1191,10 @@ static const struct samsung_gate_clock hsi_gate_clks[] __initconst = {
GATE(CLK_GOUT_MMC_CARD_SDCLKIN, "gout_mmc_card_sdclkin",
"mout_hsi_mmc_card_user",
CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN, 21, CLK_SET_RATE_PARENT, 0),
GATE(CLK_GOUT_HSI_PPMU_ACLK, "gout_hsi_ppmu_aclk", "mout_hsi_bus_user",
CLK_CON_GAT_GOUT_HSI_PPMU_ACLK, 21, 0, 0),
GATE(CLK_GOUT_HSI_PPMU_PCLK, "gout_hsi_ppmu_pclk", "mout_hsi_bus_user",
CLK_CON_GAT_GOUT_HSI_PPMU_PCLK, 21, 0, 0),
GATE(CLK_GOUT_SYSREG_HSI_PCLK, "gout_sysreg_hsi_pclk",
"mout_hsi_bus_user",
CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK, 21, 0, 0),
@ -1700,6 +1836,9 @@ static const struct of_device_id exynos850_cmu_of_match[] = {
}, {
.compatible = "samsung,exynos850-cmu-cmgp",
.data = &cmgp_cmu_info,
}, {
.compatible = "samsung,exynos850-cmu-g3d",
.data = &g3d_cmu_info,
}, {
.compatible = "samsung,exynos850-cmu-hsi",
.data = &hsi_cmu_info,

View File

@ -1259,8 +1259,7 @@ static const struct clk_ops samsung_pll2650xx_clk_min_ops = {
};
static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
const struct samsung_pll_clock *pll_clk,
void __iomem *base)
const struct samsung_pll_clock *pll_clk)
{
struct samsung_clk_pll *pll;
struct clk_init_data init;
@ -1315,6 +1314,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
init.ops = &samsung_pll35xx_clk_ops;
break;
case pll_1417x:
case pll_0818x:
case pll_0822x:
pll->enable_offs = PLL0822X_ENABLE_SHIFT;
pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT;
@ -1395,8 +1395,8 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
pll->hw.init = &init;
pll->type = pll_clk->type;
pll->lock_reg = base + pll_clk->lock_offset;
pll->con_reg = base + pll_clk->con_offset;
pll->lock_reg = ctx->reg_base + pll_clk->lock_offset;
pll->con_reg = ctx->reg_base + pll_clk->con_offset;
ret = clk_hw_register(ctx->dev, &pll->hw);
if (ret) {
@ -1412,10 +1412,10 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
const struct samsung_pll_clock *pll_list,
unsigned int nr_pll, void __iomem *base)
unsigned int nr_pll)
{
int cnt;
for (cnt = 0; cnt < nr_pll; cnt++)
_samsung_clk_register_pll(ctx, &pll_list[cnt], base);
_samsung_clk_register_pll(ctx, &pll_list[cnt]);
}

View File

@ -34,6 +34,7 @@ enum samsung_pll_type {
pll_1451x,
pll_1452x,
pll_1460x,
pll_0818x,
pll_0822x,
pll_0831x,
pll_142xx,

View File

@ -405,7 +405,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
panic("%s: failed to map registers\n", __func__);
}
ctx = samsung_clk_init(np, reg_base, NR_CLKS);
ctx = samsung_clk_init(NULL, reg_base, NR_CLKS);
hws = ctx->clk_data.hws;
/* Register external clocks. */
@ -414,7 +414,7 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
/* Register PLLs. */
samsung_clk_register_pll(ctx, s3c64xx_pll_clks,
ARRAY_SIZE(s3c64xx_pll_clks), reg_base);
ARRAY_SIZE(s3c64xx_pll_clks));
/* Register common internal clocks. */
samsung_clk_register_fixed_rate(ctx, s3c64xx_fixed_rate_clks,

View File

@ -743,7 +743,7 @@ static void __init __s5pv210_clk_init(struct device_node *np,
struct samsung_clk_provider *ctx;
struct clk_hw **hws;
ctx = samsung_clk_init(np, reg_base, NR_CLKS);
ctx = samsung_clk_init(NULL, reg_base, NR_CLKS);
hws = ctx->clk_data.hws;
samsung_clk_register_mux(ctx, early_mux_clks,
@ -753,7 +753,7 @@ static void __init __s5pv210_clk_init(struct device_node *np,
samsung_clk_register_fixed_rate(ctx, s5p6442_frate_clks,
ARRAY_SIZE(s5p6442_frate_clks));
samsung_clk_register_pll(ctx, s5p6442_pll_clks,
ARRAY_SIZE(s5p6442_pll_clks), reg_base);
ARRAY_SIZE(s5p6442_pll_clks));
samsung_clk_register_mux(ctx, s5p6442_mux_clks,
ARRAY_SIZE(s5p6442_mux_clks));
samsung_clk_register_div(ctx, s5p6442_div_clks,
@ -764,7 +764,7 @@ static void __init __s5pv210_clk_init(struct device_node *np,
samsung_clk_register_fixed_rate(ctx, s5pv210_frate_clks,
ARRAY_SIZE(s5pv210_frate_clks));
samsung_clk_register_pll(ctx, s5pv210_pll_clks,
ARRAY_SIZE(s5pv210_pll_clks), reg_base);
ARRAY_SIZE(s5pv210_pll_clks));
samsung_clk_register_mux(ctx, s5pv210_mux_clks,
ARRAY_SIZE(s5pv210_mux_clks));
samsung_clk_register_div(ctx, s5pv210_div_clks,

View File

@ -53,8 +53,18 @@ struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
return rd;
}
/* setup the essentials required to support clock lookup using ccf */
struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np,
/**
* samsung_clk_init() - Create and initialize a clock provider object
* @dev: CMU device to enable runtime PM, or NULL if RPM is not needed
* @base: Start address (mapped) of CMU registers
* @nr_clks: Total clock count to allocate in clock provider object
*
* Setup the essentials required to support clock lookup using Common Clock
* Framework.
*
* Return: Allocated and initialized clock provider object.
*/
struct samsung_clk_provider * __init samsung_clk_init(struct device *dev,
void __iomem *base, unsigned long nr_clks)
{
struct samsung_clk_provider *ctx;
@ -67,6 +77,7 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np,
for (i = 0; i < nr_clks; ++i)
ctx->clk_data.hws[i] = ERR_PTR(-ENOENT);
ctx->dev = dev;
ctx->reg_base = base;
ctx->clk_data.num = nr_clks;
spin_lock_init(&ctx->lock);
@ -324,6 +335,33 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base,
}
#endif
/**
* samsung_cmu_register_clocks() - Register all clocks provided in CMU object
* @ctx: Clock provider object
* @cmu: CMU object with clocks to register
*/
void __init samsung_cmu_register_clocks(struct samsung_clk_provider *ctx,
const struct samsung_cmu_info *cmu)
{
if (cmu->pll_clks)
samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks);
if (cmu->mux_clks)
samsung_clk_register_mux(ctx, cmu->mux_clks, cmu->nr_mux_clks);
if (cmu->div_clks)
samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);
if (cmu->gate_clks)
samsung_clk_register_gate(ctx, cmu->gate_clks,
cmu->nr_gate_clks);
if (cmu->fixed_clks)
samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
cmu->nr_fixed_clks);
if (cmu->fixed_factor_clks)
samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks,
cmu->nr_fixed_factor_clks);
if (cmu->cpu_clks)
samsung_clk_register_cpu(ctx, cmu->cpu_clks, cmu->nr_cpu_clks);
}
/*
* Common function which registers plls, muxes, dividers and gates
* for each CMU. It also add CMU register list to register cache.
@ -341,31 +379,13 @@ struct samsung_clk_provider * __init samsung_cmu_register_one(
return NULL;
}
ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
ctx = samsung_clk_init(NULL, reg_base, cmu->nr_clk_ids);
samsung_cmu_register_clocks(ctx, cmu);
if (cmu->pll_clks)
samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
reg_base);
if (cmu->mux_clks)
samsung_clk_register_mux(ctx, cmu->mux_clks,
cmu->nr_mux_clks);
if (cmu->div_clks)
samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);
if (cmu->gate_clks)
samsung_clk_register_gate(ctx, cmu->gate_clks,
cmu->nr_gate_clks);
if (cmu->fixed_clks)
samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
cmu->nr_fixed_clks);
if (cmu->fixed_factor_clks)
samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks,
cmu->nr_fixed_factor_clks);
if (cmu->clk_regs)
samsung_clk_extended_sleep_init(reg_base,
cmu->clk_regs, cmu->nr_clk_regs,
cmu->suspend_regs, cmu->nr_suspend_regs);
if (cmu->cpu_clks)
samsung_clk_register_cpu(ctx, cmu->cpu_clks, cmu->nr_cpu_clks);
samsung_clk_of_add_provider(np, ctx);

View File

@ -16,6 +16,7 @@
/**
* struct samsung_clk_provider: information about clock provider
* @reg_base: virtual address for the register base.
* @dev: clock provider device needed for runtime PM.
* @lock: maintains exclusion between callbacks for a given clock-provider.
* @clk_data: holds clock related data like clk_hw* and number of clocks.
*/
@ -337,9 +338,8 @@ struct samsung_cmu_info {
const char *clk_name;
};
struct samsung_clk_provider * samsung_clk_init(
struct device_node *np, void __iomem *base,
unsigned long nr_clks);
struct samsung_clk_provider *samsung_clk_init(struct device *dev,
void __iomem *base, unsigned long nr_clks);
void samsung_clk_of_add_provider(struct device_node *np,
struct samsung_clk_provider *ctx);
void samsung_clk_of_register_fixed_ext(
@ -373,10 +373,12 @@ void samsung_clk_register_gate(struct samsung_clk_provider *ctx,
unsigned int nr_clk);
void samsung_clk_register_pll(struct samsung_clk_provider *ctx,
const struct samsung_pll_clock *pll_list,
unsigned int nr_clk, void __iomem *base);
unsigned int nr_clk);
void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
const struct samsung_cpu_clock *list, unsigned int nr_clk);
void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx,
const struct samsung_cmu_info *cmu);
struct samsung_clk_provider *samsung_cmu_register_one(
struct device_node *,
const struct samsung_cmu_info *);

View File

@ -85,7 +85,10 @@
#define CLK_DOUT_MFCMSCL_M2M 73
#define CLK_DOUT_MFCMSCL_MCSC 74
#define CLK_DOUT_MFCMSCL_JPEG 75
#define TOP_NR_CLK 76
#define CLK_MOUT_G3D_SWITCH 76
#define CLK_GOUT_G3D_SWITCH 77
#define CLK_DOUT_G3D_SWITCH 78
#define TOP_NR_CLK 79
/* CMU_APM */
#define CLK_RCO_I3C_PMIC 1
@ -175,7 +178,8 @@
#define IOCLK_AUDIOCDCLK5 58
#define IOCLK_AUDIOCDCLK6 59
#define TICK_USB 60
#define AUD_NR_CLK 61
#define CLK_GOUT_AUD_CMU_AUD_PCLK 61
#define AUD_NR_CLK 62
/* CMU_CMGP */
#define CLK_RCO_CMGP 1
@ -195,6 +199,21 @@
#define CLK_GOUT_SYSREG_CMGP_PCLK 15
#define CMGP_NR_CLK 16
/* CMU_G3D */
#define CLK_FOUT_G3D_PLL 1
#define CLK_MOUT_G3D_PLL 2
#define CLK_MOUT_G3D_SWITCH_USER 3
#define CLK_MOUT_G3D_BUSD 4
#define CLK_DOUT_G3D_BUSP 5
#define CLK_GOUT_G3D_CMU_G3D_PCLK 6
#define CLK_GOUT_G3D_GPU_CLK 7
#define CLK_GOUT_G3D_TZPC_PCLK 8
#define CLK_GOUT_G3D_GRAY2BIN_CLK 9
#define CLK_GOUT_G3D_BUSD_CLK 10
#define CLK_GOUT_G3D_BUSP_CLK 11
#define CLK_GOUT_G3D_SYSREG_PCLK 12
#define G3D_NR_CLK 13
/* CMU_HSI */
#define CLK_MOUT_HSI_BUS_USER 1
#define CLK_MOUT_HSI_MMC_CARD_USER 2
@ -209,7 +228,10 @@
#define CLK_GOUT_MMC_CARD_ACLK 11
#define CLK_GOUT_MMC_CARD_SDCLKIN 12
#define CLK_GOUT_SYSREG_HSI_PCLK 13
#define HSI_NR_CLK 14
#define CLK_GOUT_HSI_PPMU_ACLK 14
#define CLK_GOUT_HSI_PPMU_PCLK 15
#define CLK_GOUT_HSI_CMU_HSI_PCLK 16
#define HSI_NR_CLK 17
/* CMU_IS */
#define CLK_MOUT_IS_BUS_USER 1