Merge branches 'clk-qcom-kconfig', 'clk-qcom-gpucc', 'clk-qcom-qcs404-rpm', 'clk-qcom-spi' and 'clk-qcom-videocc-binding' into clk-next

- Qualcomm SDM845 GPU clock controllers
 - Qualcomm QCS404 RPM clk support

* clk-qcom-kconfig:
  clk: qcom: Move to menuconfig and reduce lines

* clk-qcom-gpucc:
  dt-bindings: clock: qcom: Fix the xo parent in gpucc example
  clk: qcom: gpu_cc_gmu_clk_src has 5 parents, not 6
  clk: qcom: Add a dummy enable function for GX gdsc
  clk: qcom: gdsc: Don't override existing gdsc pd functions
  clk: qcom: Add graphics clock controller driver for SDM845
  dt-bindings: clock: Introduce QCOM Graphics clock bindings

* clk-qcom-qcs404-rpm:
  clk: qcom: smd: Add support for QCS404 rpm clocks

* clk-qcom-spi:
  clk: qcom: msm8916: Additional clock rates for spi

* clk-qcom-videocc-binding:
  dt-bindings: clock: Require #reset-cells in sdm845-videocc
This commit is contained in:
Stephen Boyd 2018-12-14 13:26:21 -08:00
11 changed files with 376 additions and 39 deletions

View File

@ -0,0 +1,22 @@
Qualcomm Graphics Clock & Reset Controller Binding
--------------------------------------------------
Required properties :
- compatible : shall contain "qcom,sdm845-gpucc"
- reg : shall contain base register location and length
- #clock-cells : from common clock binding, shall contain 1
- #reset-cells : from common reset binding, shall contain 1
- #power-domain-cells : from generic power domain binding, shall contain 1
- clocks : shall contain the XO clock
- clock-names : shall be "xo"
Example:
gpucc: clock-controller@5090000 {
compatible = "qcom,sdm845-gpucc";
reg = <0x5090000 0x9000>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
clocks = <&rpmhcc RPMH_CXO_CLK>;
clock-names = "xo";
};

View File

@ -16,6 +16,7 @@ Required properties :
"qcom,rpmcc-msm8974", "qcom,rpmcc"
"qcom,rpmcc-apq8064", "qcom,rpmcc"
"qcom,rpmcc-msm8996", "qcom,rpmcc"
"qcom,rpmcc-qcs404", "qcom,rpmcc"
- #clock-cells : shall contain 1

View File

@ -6,8 +6,6 @@ Required properties :
- reg : shall contain base register location and length
- #clock-cells : from common clock binding, shall contain 1.
- #power-domain-cells : from generic power domain binding, shall contain 1.
Optional properties :
- #reset-cells : from common reset binding, shall contain 1.
Example:
@ -16,4 +14,5 @@ Example:
reg = <0xab00000 0x10000>;
#clock-cells = <1>;
#power-domain-cells = <1>;
#reset-cells = <1>;
};

View File

@ -9,16 +9,17 @@ config QCOM_GDSC
config QCOM_RPMCC
bool
config COMMON_CLK_QCOM
menuconfig COMMON_CLK_QCOM
tristate "Support for Qualcomm's clock controllers"
depends on OF
depends on ARCH_QCOM || COMPILE_TEST
select REGMAP_MMIO
select RESET_CONTROLLER
if COMMON_CLK_QCOM
config QCOM_A53PLL
tristate "MSM8916 A53 PLL"
depends on COMMON_CLK_QCOM
default ARCH_QCOM
help
Support for the A53 PLL on MSM8916 devices. It provides
@ -28,7 +29,6 @@ config QCOM_A53PLL
config QCOM_CLK_APCS_MSM8916
tristate "MSM8916 APCS Clock Controller"
depends on COMMON_CLK_QCOM
depends on QCOM_APCS_IPC || COMPILE_TEST
default ARCH_QCOM
help
@ -39,7 +39,7 @@ config QCOM_CLK_APCS_MSM8916
config QCOM_CLK_RPM
tristate "RPM based Clock Controller"
depends on COMMON_CLK_QCOM && MFD_QCOM_RPM
depends on MFD_QCOM_RPM
select QCOM_RPMCC
help
The RPM (Resource Power Manager) is a dedicated hardware engine for
@ -52,7 +52,7 @@ config QCOM_CLK_RPM
config QCOM_CLK_SMD_RPM
tristate "RPM over SMD based Clock Controller"
depends on COMMON_CLK_QCOM && QCOM_SMD_RPM
depends on QCOM_SMD_RPM
select QCOM_RPMCC
help
The RPM (Resource Power Manager) is a dedicated hardware engine for
@ -65,7 +65,7 @@ config QCOM_CLK_SMD_RPM
config QCOM_CLK_RPMH
tristate "RPMh Clock Driver"
depends on COMMON_CLK_QCOM && QCOM_RPMH
depends on QCOM_RPMH
help
RPMh manages shared resources on some Qualcomm Technologies, Inc.
SoCs. It accepts requests from other hardware subsystems via RSC.
@ -75,7 +75,6 @@ config QCOM_CLK_RPMH
config APQ_GCC_8084
tristate "APQ8084 Global Clock Controller"
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on apq8084 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -85,7 +84,6 @@ config APQ_MMCC_8084
tristate "APQ8084 Multimedia Clock Controller"
select APQ_GCC_8084
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the multimedia clock controller on apq8084 devices.
Say Y if you want to support multimedia devices such as display,
@ -93,7 +91,6 @@ config APQ_MMCC_8084
config IPQ_GCC_4019
tristate "IPQ4019 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on ipq4019 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -101,7 +98,6 @@ config IPQ_GCC_4019
config IPQ_GCC_806X
tristate "IPQ806x Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on ipq806x devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -110,7 +106,6 @@ config IPQ_GCC_806X
config IPQ_LCC_806X
tristate "IPQ806x LPASS Clock Controller"
select IPQ_GCC_806X
depends on COMMON_CLK_QCOM
help
Support for the LPASS clock controller on ipq806x devices.
Say Y if you want to use audio devices such as i2s, pcm,
@ -118,7 +113,6 @@ config IPQ_LCC_806X
config IPQ_GCC_8074
tristate "IPQ8074 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for global clock controller on ipq8074 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -127,7 +121,6 @@ config IPQ_GCC_8074
config MSM_GCC_8660
tristate "MSM8660 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8660 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -136,7 +129,6 @@ config MSM_GCC_8660
config MSM_GCC_8916
tristate "MSM8916 Global Clock Controller"
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8916 devices.
Say Y if you want to use devices such as UART, SPI i2c, USB,
@ -144,7 +136,6 @@ config MSM_GCC_8916
config MSM_GCC_8960
tristate "APQ8064/MSM8960 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on apq8064/msm8960 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -153,7 +144,6 @@ config MSM_GCC_8960
config MSM_LCC_8960
tristate "APQ8064/MSM8960 LPASS Clock Controller"
select MSM_GCC_8960
depends on COMMON_CLK_QCOM
help
Support for the LPASS clock controller on apq8064/msm8960 devices.
Say Y if you want to use audio devices such as i2s, pcm,
@ -161,7 +151,6 @@ config MSM_LCC_8960
config MDM_GCC_9615
tristate "MDM9615 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on mdm9615 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -170,7 +159,6 @@ config MDM_GCC_9615
config MDM_LCC_9615
tristate "MDM9615 LPASS Clock Controller"
select MDM_GCC_9615
depends on COMMON_CLK_QCOM
help
Support for the LPASS clock controller on mdm9615 devices.
Say Y if you want to use audio devices such as i2s, pcm,
@ -179,7 +167,6 @@ config MDM_LCC_9615
config MSM_MMCC_8960
tristate "MSM8960 Multimedia Clock Controller"
select MSM_GCC_8960
depends on COMMON_CLK_QCOM
help
Support for the multimedia clock controller on msm8960 devices.
Say Y if you want to support multimedia devices such as display,
@ -188,7 +175,6 @@ config MSM_MMCC_8960
config MSM_GCC_8974
tristate "MSM8974 Global Clock Controller"
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8974 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -198,7 +184,6 @@ config MSM_MMCC_8974
tristate "MSM8974 Multimedia Clock Controller"
select MSM_GCC_8974
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the multimedia clock controller on msm8974 devices.
Say Y if you want to support multimedia devices such as display,
@ -206,7 +191,6 @@ config MSM_MMCC_8974
config MSM_GCC_8994
tristate "MSM8994 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8994 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -215,7 +199,6 @@ config MSM_GCC_8994
config MSM_GCC_8996
tristate "MSM8996 Global Clock Controller"
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8996 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -225,7 +208,6 @@ config MSM_MMCC_8996
tristate "MSM8996 Multimedia Clock Controller"
select MSM_GCC_8996
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the multimedia clock controller on msm8996 devices.
Say Y if you want to support multimedia devices such as display,
@ -233,7 +215,6 @@ config MSM_MMCC_8996
config MSM_GCC_8998
tristate "MSM8998 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on msm8998 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -241,7 +222,6 @@ config MSM_GCC_8998
config QCS_GCC_404
tristate "QCS404 Global Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on QCS404 devices.
Say Y if you want to use multimedia devices or peripheral
@ -249,7 +229,6 @@ config QCS_GCC_404
config SDM_CAMCC_845
tristate "SDM845 Camera Clock Controller"
depends on COMMON_CLK_QCOM
select SDM_GCC_845
help
Support for the camera clock controller on SDM845 devices.
@ -258,7 +237,6 @@ config SDM_CAMCC_845
config SDM_GCC_660
tristate "SDM660 Global Clock Controller"
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on SDM660 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
@ -267,15 +245,21 @@ config SDM_GCC_660
config SDM_GCC_845
tristate "SDM845 Global Clock Controller"
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on SDM845 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
i2C, USB, UFS, SDDC, PCIe, etc.
config SDM_GPUCC_845
tristate "SDM845 Graphics Clock Controller"
select SDM_GCC_845
help
Support for the graphics clock controller on SDM845 devices.
Say Y if you want to support graphics controller devices and
functionality such as 3D graphics.
config SDM_VIDEOCC_845
tristate "SDM845 Video Clock Controller"
depends on COMMON_CLK_QCOM
select SDM_GCC_845
select QCOM_GDSC
help
@ -286,7 +270,6 @@ config SDM_VIDEOCC_845
config SDM_DISPCC_845
tristate "SDM845 Display Clock Controller"
select SDM_GCC_845
depends on COMMON_CLK_QCOM
help
Support for the display clock controller on Qualcomm Technologies, Inc
SDM845 devices.
@ -295,7 +278,7 @@ config SDM_DISPCC_845
config SPMI_PMIC_CLKDIV
tristate "SPMI PMIC clkdiv Support"
depends on (COMMON_CLK_QCOM && SPMI) || COMPILE_TEST
depends on SPMI || COMPILE_TEST
help
This driver supports the clkdiv functionality on the Qualcomm
Technologies, Inc. SPMI PMIC. It configures the frequency of
@ -304,7 +287,6 @@ config SPMI_PMIC_CLKDIV
config QCOM_HFPLL
tristate "High-Frequency PLL (HFPLL) Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the high-frequency PLLs present on Qualcomm devices.
Say Y if you want to support CPU frequency scaling on devices
@ -312,7 +294,6 @@ config QCOM_HFPLL
config KPSS_XCC
tristate "KPSS Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the Krait ACC and GCC clock controllers. Say Y
if you want to support CPU frequency scaling on devices such
@ -320,8 +301,10 @@ config KPSS_XCC
config KRAITCC
tristate "Krait Clock Controller"
depends on COMMON_CLK_QCOM && ARM
depends on ARM
select KRAIT_CLOCKS
help
Support for the Krait CPU clocks on Qualcomm devices.
Say Y if you want to support CPU frequency scaling.
endif

View File

@ -46,6 +46,7 @@ obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o
obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o

View File

@ -611,10 +611,55 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8996 = {
.num_clks = ARRAY_SIZE(msm8996_clks),
};
/* QCS404 */
DEFINE_CLK_SMD_RPM_QDSS(qcs404, qdss_clk, qdss_a_clk, QCOM_SMD_RPM_MISC_CLK, 1);
DEFINE_CLK_SMD_RPM(qcs404, pnoc_clk, pnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
DEFINE_CLK_SMD_RPM(qcs404, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
DEFINE_CLK_SMD_RPM(qcs404, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
DEFINE_CLK_SMD_RPM(qcs404, bimc_gpu_clk, bimc_gpu_a_clk, QCOM_SMD_RPM_MEM_CLK, 2);
DEFINE_CLK_SMD_RPM(qcs404, qpic_clk, qpic_a_clk, QCOM_SMD_RPM_QPIC_CLK, 0);
DEFINE_CLK_SMD_RPM(qcs404, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0);
DEFINE_CLK_SMD_RPM_XO_BUFFER(qcs404, rf_clk1, rf_clk1_a, 4);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, rf_clk1_pin, rf_clk1_a_pin, 4);
DEFINE_CLK_SMD_RPM_XO_BUFFER(qcs404, ln_bb_clk, ln_bb_a_clk, 8);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, ln_bb_clk_pin, ln_bb_clk_a_pin, 8);
static struct clk_smd_rpm *qcs404_clks[] = {
[RPM_SMD_QDSS_CLK] = &qcs404_qdss_clk,
[RPM_SMD_QDSS_A_CLK] = &qcs404_qdss_a_clk,
[RPM_SMD_PNOC_CLK] = &qcs404_pnoc_clk,
[RPM_SMD_PNOC_A_CLK] = &qcs404_pnoc_a_clk,
[RPM_SMD_SNOC_CLK] = &qcs404_snoc_clk,
[RPM_SMD_SNOC_A_CLK] = &qcs404_snoc_a_clk,
[RPM_SMD_BIMC_CLK] = &qcs404_bimc_clk,
[RPM_SMD_BIMC_A_CLK] = &qcs404_bimc_a_clk,
[RPM_SMD_BIMC_GPU_CLK] = &qcs404_bimc_gpu_clk,
[RPM_SMD_BIMC_GPU_A_CLK] = &qcs404_bimc_gpu_a_clk,
[RPM_SMD_QPIC_CLK] = &qcs404_qpic_clk,
[RPM_SMD_QPIC_CLK_A] = &qcs404_qpic_a_clk,
[RPM_SMD_CE1_CLK] = &qcs404_ce1_clk,
[RPM_SMD_CE1_A_CLK] = &qcs404_ce1_a_clk,
[RPM_SMD_RF_CLK1] = &qcs404_rf_clk1,
[RPM_SMD_RF_CLK1_A] = &qcs404_rf_clk1_a,
[RPM_SMD_LN_BB_CLK] = &qcs404_ln_bb_clk,
[RPM_SMD_LN_BB_A_CLK] = &qcs404_ln_bb_a_clk,
};
static const struct rpm_smd_clk_desc rpm_clk_qcs404 = {
.clks = qcs404_clks,
.num_clks = ARRAY_SIZE(qcs404_clks),
};
static const struct of_device_id rpm_smd_clk_match_table[] = {
{ .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
{ .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
{ .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 },
{ .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 },
{ }
};
MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table);

View File

@ -544,7 +544,11 @@ static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
};
static const struct freq_tbl ftbl_gcc_blsp1_qup1_6_spi_apps_clk[] = {
F(100000, P_XO, 16, 2, 24),
F(250000, P_XO, 16, 5, 24),
F(500000, P_XO, 8, 5, 24),
F(960000, P_XO, 10, 1, 2),
F(1000000, P_XO, 4, 5, 24),
F(4800000, P_XO, 4, 0, 0),
F(9600000, P_XO, 2, 0, 0),
F(16000000, P_GPLL0, 10, 1, 5),

View File

@ -350,8 +350,10 @@ static int gdsc_init(struct gdsc *sc)
else
gdsc_clear_mem_on(sc);
sc->pd.power_off = gdsc_disable;
sc->pd.power_on = gdsc_enable;
if (!sc->pd.power_off)
sc->pd.power_off = gdsc_disable;
if (!sc->pd.power_on)
sc->pd.power_on = gdsc_enable;
pm_genpd_init(&sc->pd, NULL, !on);
return 0;

View File

@ -0,0 +1,252 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/qcom,gpucc-sdm845.h>
#include "common.h"
#include "clk-alpha-pll.h"
#include "clk-branch.h"
#include "clk-pll.h"
#include "clk-rcg.h"
#include "clk-regmap.h"
#include "gdsc.h"
#define CX_GMU_CBCR_SLEEP_MASK 0xf
#define CX_GMU_CBCR_SLEEP_SHIFT 4
#define CX_GMU_CBCR_WAKE_MASK 0xf
#define CX_GMU_CBCR_WAKE_SHIFT 8
#define CLK_DIS_WAIT_SHIFT 12
#define CLK_DIS_WAIT_MASK (0xf << CLK_DIS_WAIT_SHIFT)
enum {
P_BI_TCXO,
P_CORE_BI_PLL_TEST_SE,
P_GPLL0_OUT_MAIN,
P_GPLL0_OUT_MAIN_DIV,
P_GPU_CC_PLL1_OUT_EVEN,
P_GPU_CC_PLL1_OUT_MAIN,
P_GPU_CC_PLL1_OUT_ODD,
};
static const struct parent_map gpu_cc_parent_map_0[] = {
{ P_BI_TCXO, 0 },
{ P_GPU_CC_PLL1_OUT_MAIN, 3 },
{ P_GPLL0_OUT_MAIN, 5 },
{ P_GPLL0_OUT_MAIN_DIV, 6 },
{ P_CORE_BI_PLL_TEST_SE, 7 },
};
static const char * const gpu_cc_parent_names_0[] = {
"bi_tcxo",
"gpu_cc_pll1",
"gcc_gpu_gpll0_clk_src",
"gcc_gpu_gpll0_div_clk_src",
"core_bi_pll_test_se",
};
static const struct alpha_pll_config gpu_cc_pll1_config = {
.l = 0x1a,
.alpha = 0xaab,
};
static struct clk_alpha_pll gpu_cc_pll1 = {
.offset = 0x100,
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
.clkr = {
.hw.init = &(struct clk_init_data){
.name = "gpu_cc_pll1",
.parent_names = (const char *[]){ "bi_tcxo" },
.num_parents = 1,
.ops = &clk_alpha_pll_fabia_ops,
},
},
};
static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
F(19200000, P_BI_TCXO, 1, 0, 0),
F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
F(500000000, P_GPU_CC_PLL1_OUT_MAIN, 1, 0, 0),
{ }
};
static struct clk_rcg2 gpu_cc_gmu_clk_src = {
.cmd_rcgr = 0x1120,
.mnd_width = 0,
.hid_width = 5,
.parent_map = gpu_cc_parent_map_0,
.freq_tbl = ftbl_gpu_cc_gmu_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "gpu_cc_gmu_clk_src",
.parent_names = gpu_cc_parent_names_0,
.num_parents = 5,
.ops = &clk_rcg2_shared_ops,
},
};
static struct clk_branch gpu_cc_cx_gmu_clk = {
.halt_reg = 0x1098,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x1098,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gpu_cc_cx_gmu_clk",
.parent_names = (const char *[]){
"gpu_cc_gmu_clk_src",
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gpu_cc_cxo_clk = {
.halt_reg = 0x109c,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x109c,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gpu_cc_cxo_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct gdsc gpu_cx_gdsc = {
.gdscr = 0x106c,
.gds_hw_ctrl = 0x1540,
.pd = {
.name = "gpu_cx_gdsc",
},
.pwrsts = PWRSTS_OFF_ON,
.flags = VOTABLE,
};
/*
* On SDM845 the GPU GX domain is *almost* entirely controlled by the GMU
* running in the CX domain so the CPU doesn't need to know anything about the
* GX domain EXCEPT....
*
* Hardware constraints dictate that the GX be powered down before the CX. If
* the GMU crashes it could leave the GX on. In order to successfully bring back
* the device the CPU needs to disable the GX headswitch. There being no sane
* way to reach in and touch that register from deep inside the GPU driver we
* need to set up the infrastructure to be able to ensure that the GPU can
* ensure that the GX is off during this super special case. We do this by
* defining a GX gdsc with a dummy enable function and a "default" disable
* function.
*
* This allows us to attach with genpd_dev_pm_attach_by_name() in the GPU
* driver. During power up, nothing will happen from the CPU (and the GMU will
* power up normally but during power down this will ensure that the GX domain
* is *really* off - this gives us a semi standard way of doing what we need.
*/
static int gx_gdsc_enable(struct generic_pm_domain *domain)
{
/* Do nothing but give genpd the impression that we were successful */
return 0;
}
static struct gdsc gpu_gx_gdsc = {
.gdscr = 0x100c,
.clamp_io_ctrl = 0x1508,
.pd = {
.name = "gpu_gx_gdsc",
.power_on = gx_gdsc_enable,
},
.pwrsts = PWRSTS_OFF_ON,
.flags = CLAMP_IO | AON_RESET | POLL_CFG_GDSCR,
};
static struct clk_regmap *gpu_cc_sdm845_clocks[] = {
[GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
[GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
[GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
[GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
};
static struct gdsc *gpu_cc_sdm845_gdscs[] = {
[GPU_CX_GDSC] = &gpu_cx_gdsc,
[GPU_GX_GDSC] = &gpu_gx_gdsc,
};
static const struct regmap_config gpu_cc_sdm845_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = 0x8008,
.fast_io = true,
};
static const struct qcom_cc_desc gpu_cc_sdm845_desc = {
.config = &gpu_cc_sdm845_regmap_config,
.clks = gpu_cc_sdm845_clocks,
.num_clks = ARRAY_SIZE(gpu_cc_sdm845_clocks),
.gdscs = gpu_cc_sdm845_gdscs,
.num_gdscs = ARRAY_SIZE(gpu_cc_sdm845_gdscs),
};
static const struct of_device_id gpu_cc_sdm845_match_table[] = {
{ .compatible = "qcom,sdm845-gpucc" },
{ }
};
MODULE_DEVICE_TABLE(of, gpu_cc_sdm845_match_table);
static int gpu_cc_sdm845_probe(struct platform_device *pdev)
{
struct regmap *regmap;
unsigned int value, mask;
regmap = qcom_cc_map(pdev, &gpu_cc_sdm845_desc);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
/*
* Configure gpu_cc_cx_gmu_clk with recommended
* wakeup/sleep settings
*/
mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT;
mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
value = 0xf << CX_GMU_CBCR_WAKE_SHIFT | 0xf << CX_GMU_CBCR_SLEEP_SHIFT;
regmap_update_bits(regmap, 0x1098, mask, value);
/* Configure clk_dis_wait for gpu_cx_gdsc */
regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
8 << CLK_DIS_WAIT_SHIFT);
return qcom_cc_really_probe(pdev, &gpu_cc_sdm845_desc, regmap);
}
static struct platform_driver gpu_cc_sdm845_driver = {
.probe = gpu_cc_sdm845_probe,
.driver = {
.name = "sdm845-gpucc",
.of_match_table = gpu_cc_sdm845_match_table,
},
};
static int __init gpu_cc_sdm845_init(void)
{
return platform_driver_register(&gpu_cc_sdm845_driver);
}
subsys_initcall(gpu_cc_sdm845_init);
static void __exit gpu_cc_sdm845_exit(void)
{
platform_driver_unregister(&gpu_cc_sdm845_driver);
}
module_exit(gpu_cc_sdm845_exit);
MODULE_DESCRIPTION("QTI GPUCC SDM845 Driver");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#ifndef _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H
#define _DT_BINDINGS_CLK_SDM_GPU_CC_SDM845_H
/* GPU_CC clock registers */
#define GPU_CC_CX_GMU_CLK 0
#define GPU_CC_CXO_CLK 1
#define GPU_CC_GMU_CLK_SRC 2
#define GPU_CC_PLL1 3
/* GPU_CC Resets */
#define GPUCC_GPU_CC_CX_BCR 0
#define GPUCC_GPU_CC_GMU_BCR 1
#define GPUCC_GPU_CC_XO_BCR 2
/* GPU_CC GDSCRs */
#define GPU_CX_GDSC 0
#define GPU_GX_GDSC 1
#endif

View File

@ -123,5 +123,9 @@
#define RPM_SMD_DIV_A_CLK3 73
#define RPM_SMD_LN_BB_CLK 74
#define RPM_SMD_LN_BB_A_CLK 75
#define RPM_SMD_BIMC_GPU_CLK 76
#define RPM_SMD_BIMC_GPU_A_CLK 77
#define RPM_SMD_QPIC_CLK 78
#define RPM_SMD_QPIC_CLK_A 79
#endif