Unverified Commit 7ee97197 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'samsung-clk-6.19' of...

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

Pull more Samsung clk driver updates from Krzysztof Kozlowski:

 - ExynosAutov920: add support for additional clock controllers (M2M and
   MFC)

* tag 'samsung-clk-6.19' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux:
  clk: samsung: clk-pll: simplify samsung_pll_lock_wait()
  clk: samsung: exynosautov920: add block mfc clock support
  clk: samsung: exynosautov920: add clock support
  dt-bindings: clock: exynosautov920: add mfc clock definitions
  dt-bindings: clock: exynosautov920: add m2m clock definitions
  dt-bindings: clock: google,gs101-clock: add power-domains
parents 44244194 d669ec6b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ properties:
  "#clock-cells":
    const: 1

  power-domains:
    maxItems: 1

  reg:
    maxItems: 1

+42 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ properties:
      - samsung,exynosautov920-cmu-hsi0
      - samsung,exynosautov920-cmu-hsi1
      - samsung,exynosautov920-cmu-hsi2
      - samsung,exynosautov920-cmu-m2m
      - samsung,exynosautov920-cmu-mfc
      - samsung,exynosautov920-cmu-misc
      - samsung,exynosautov920-cmu-peric0
      - samsung,exynosautov920-cmu-peric1
@@ -226,6 +228,46 @@ allOf:
            - const: embd
            - const: ethernet

  - if:
      properties:
        compatible:
          contains:
            const: samsung,exynosautov920-cmu-m2m

    then:
      properties:
        clocks:
          items:
            - description: External reference clock (38.4 MHz)
            - description: CMU_M2M NOC clock (from CMU_TOP)
            - description: CMU_M2M JPEG clock (from CMU_TOP)

        clock-names:
          items:
            - const: oscclk
            - const: noc
            - const: jpeg

  - if:
      properties:
        compatible:
          contains:
            const: samsung,exynosautov920-cmu-mfc

    then:
      properties:
        clocks:
          items:
            - description: External reference clock (38.4 MHz)
            - description: CMU_MFC MFC clock (from CMU_TOP)
            - description: CMU_MFC WFD clock (from CMU_TOP)

        clock-names:
          items:
            - const: oscclk
            - const: mfc
            - const: wfd

required:
  - compatible
  - "#clock-cells"
+90 −0
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@
#define CLKS_NR_HSI0			(CLK_DOUT_HSI0_PCIE_APB + 1)
#define CLKS_NR_HSI1			(CLK_MOUT_HSI1_USBDRD + 1)
#define CLKS_NR_HSI2			(CLK_DOUT_HSI2_ETHERNET_PTP + 1)
#define CLKS_NR_M2M                     (CLK_DOUT_M2M_NOCP + 1)
#define CLKS_NR_MFC                     (CLK_DOUT_MFC_NOCP + 1)

/* ---- CMU_TOP ------------------------------------------------------------ */

@@ -1821,6 +1823,88 @@ static const struct samsung_cmu_info hsi2_cmu_info __initconst = {
	.clk_name               = "noc",
};

/* ---- CMU_M2M --------------------------------------------------------- */

/* Register Offset definitions for CMU_M2M (0x1a800000) */
#define PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER       0x600
#define PLL_CON0_MUX_CLKCMU_M2M_NOC_USER        0x610
#define CLK_CON_DIV_DIV_CLK_M2M_NOCP            0x1800

static const unsigned long m2m_clk_regs[] __initconst = {
	PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER,
	PLL_CON0_MUX_CLKCMU_M2M_NOC_USER,
	CLK_CON_DIV_DIV_CLK_M2M_NOCP,
};

/* List of parent clocks for Muxes in CMU_M2M */
PNAME(mout_clkcmu_m2m_noc_user_p) = { "oscclk", "dout_clkcmu_m2m_noc" };
PNAME(mout_clkcmu_m2m_jpeg_user_p) = { "oscclk", "dout_clkcmu_m2m_jpeg" };

static const struct samsung_mux_clock m2m_mux_clks[] __initconst = {
	MUX(CLK_MOUT_M2M_JPEG_USER, "mout_clkcmu_m2m_jpeg_user",
	    mout_clkcmu_m2m_jpeg_user_p, PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER, 4, 1),
	MUX(CLK_MOUT_M2M_NOC_USER, "mout_clkcmu_m2m_noc_user",
	    mout_clkcmu_m2m_noc_user_p, PLL_CON0_MUX_CLKCMU_M2M_NOC_USER, 4, 1),
};

static const struct samsung_div_clock m2m_div_clks[] __initconst = {
	DIV(CLK_DOUT_M2M_NOCP, "dout_m2m_nocp",
	    "mout_clkcmu_m2m_noc_user", CLK_CON_DIV_DIV_CLK_M2M_NOCP,
	    0, 3),
};

static const struct samsung_cmu_info m2m_cmu_info __initconst = {
	.mux_clks               = m2m_mux_clks,
	.nr_mux_clks            = ARRAY_SIZE(m2m_mux_clks),
	.div_clks               = m2m_div_clks,
	.nr_div_clks            = ARRAY_SIZE(m2m_div_clks),
	.nr_clk_ids             = CLKS_NR_M2M,
	.clk_regs               = m2m_clk_regs,
	.nr_clk_regs            = ARRAY_SIZE(m2m_clk_regs),
	.clk_name               = "noc",
};

/* ---- CMU_MFC --------------------------------------------------------- */

/* Register Offset definitions for CMU_MFC (0x19c00000) */
#define PLL_CON0_MUX_CLKCMU_MFC_MFC_USER        0x600
#define PLL_CON0_MUX_CLKCMU_MFC_WFD_USER        0x610
#define CLK_CON_DIV_DIV_CLK_MFC_NOCP            0x1800

static const unsigned long mfc_clk_regs[] __initconst = {
	PLL_CON0_MUX_CLKCMU_MFC_MFC_USER,
	PLL_CON0_MUX_CLKCMU_MFC_WFD_USER,
	CLK_CON_DIV_DIV_CLK_MFC_NOCP,
};

/* List of parent clocks for Muxes in CMU_MFC */
PNAME(mout_clkcmu_mfc_mfc_user_p) = { "oscclk", "dout_clkcmu_mfc_mfc" };
PNAME(mout_clkcmu_mfc_wfd_user_p) = { "oscclk", "dout_clkcmu_mfc_wfd" };

static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
	MUX(CLK_MOUT_MFC_MFC_USER, "mout_clkcmu_mfc_mfc_user",
	    mout_clkcmu_mfc_mfc_user_p, PLL_CON0_MUX_CLKCMU_MFC_MFC_USER, 4, 1),
	MUX(CLK_MOUT_MFC_WFD_USER, "mout_clkcmu_mfc_wfd_user",
	    mout_clkcmu_mfc_wfd_user_p, PLL_CON0_MUX_CLKCMU_MFC_WFD_USER, 4, 1),
};

static const struct samsung_div_clock mfc_div_clks[] __initconst = {
	DIV(CLK_DOUT_MFC_NOCP, "dout_mfc_nocp",
	    "mout_clkcmu_mfc_mfc_user", CLK_CON_DIV_DIV_CLK_MFC_NOCP,
	    0, 3),
};

static const struct samsung_cmu_info mfc_cmu_info __initconst = {
	.mux_clks               = mfc_mux_clks,
	.nr_mux_clks            = ARRAY_SIZE(mfc_mux_clks),
	.div_clks               = mfc_div_clks,
	.nr_div_clks            = ARRAY_SIZE(mfc_div_clks),
	.nr_clk_ids             = CLKS_NR_MFC,
	.clk_regs               = mfc_clk_regs,
	.nr_clk_regs            = ARRAY_SIZE(mfc_clk_regs),
	.clk_name               = "noc",
};

static int __init exynosautov920_cmu_probe(struct platform_device *pdev)
{
	const struct samsung_cmu_info *info;
@@ -1851,6 +1935,12 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = {
	}, {
		.compatible = "samsung,exynosautov920-cmu-hsi2",
		.data = &hsi2_cmu_info,
	}, {
		.compatible = "samsung,exynosautov920-cmu-m2m",
		.data = &m2m_cmu_info,
	}, {
		.compatible = "samsung,exynosautov920-cmu-mfc",
		.data = &mfc_cmu_info,
	},
	{ }
};
+10 −31
Original line number Diff line number Diff line
@@ -11,14 +11,12 @@
#include <linux/iopoll.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/timekeeping.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include "clk.h"
#include "clk-pll.h"

#define PLL_TIMEOUT_US		20000U
#define PLL_TIMEOUT_LOOPS	1000000U
#define PLL_TIMEOUT_LOOPS	20000U

struct samsung_clk_pll {
	struct clk_hw		hw;
@@ -71,20 +69,11 @@ static int samsung_pll_determine_rate(struct clk_hw *hw,
	return 0;
}

static bool pll_early_timeout = true;

static int __init samsung_pll_disable_early_timeout(void)
{
	pll_early_timeout = false;
	return 0;
}
arch_initcall(samsung_pll_disable_early_timeout);

/* Wait until the PLL is locked */
static int samsung_pll_lock_wait(struct samsung_clk_pll *pll,
				 unsigned int reg_mask)
{
	int i, ret;
	int ret;
	u32 val;

	/*
@@ -93,25 +82,15 @@ static int samsung_pll_lock_wait(struct samsung_clk_pll *pll,
	 * initialized, another when the timekeeping is suspended. udelay() also
	 * cannot be used when the clocksource is not running on arm64, since
	 * the current timer is used as cycle counter. So a simple busy loop
	 * is used here in that special cases. The limit of iterations has been
	 * derived from experimental measurements of various PLLs on multiple
	 * Exynos SoC variants. Single register read time was usually in range
	 * 0.4...1.5 us, never less than 0.4 us.
	 * is used here.
	 * The limit of iterations has been derived from experimental
	 * measurements of various PLLs on multiple Exynos SoC variants. Single
	 * register read time was usually in range 0.4...1.5 us, never less than
	 * 0.4 us.
	 */
	if (pll_early_timeout || timekeeping_suspended) {
		i = PLL_TIMEOUT_LOOPS;
		while (i-- > 0) {
			if (readl_relaxed(pll->con_reg) & reg_mask)
				return 0;

			cpu_relax();
		}
		ret = -ETIMEDOUT;
	} else {
	ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val,
					val & reg_mask, 0, PLL_TIMEOUT_US);
	}

						val & reg_mask, 0,
						PLL_TIMEOUT_LOOPS);
	if (ret < 0)
		pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll->hw));

+10 −0
Original line number Diff line number Diff line
@@ -295,4 +295,14 @@
#define CLK_DOUT_HSI2_ETHERNET          6
#define CLK_DOUT_HSI2_ETHERNET_PTP      7

/* CMU_M2M */
#define CLK_MOUT_M2M_JPEG_USER          1
#define CLK_MOUT_M2M_NOC_USER           2
#define CLK_DOUT_M2M_NOCP               3

/* CMU_MFC */
#define CLK_MOUT_MFC_MFC_USER           1
#define CLK_MOUT_MFC_WFD_USER           2
#define CLK_DOUT_MFC_NOCP               3

#endif /* _DT_BINDINGS_CLOCK_EXYNOSAUTOV920_H */