1*a74d5e83SLaura Nao // SPDX-License-Identifier: GPL-2.0-only 2*a74d5e83SLaura Nao /* 3*a74d5e83SLaura Nao * Copyright (c) 2025 MediaTek Inc. 4*a74d5e83SLaura Nao * Guangjie Song <guangjie.song@mediatek.com> 5*a74d5e83SLaura Nao * Copyright (c) 2025 Collabora Ltd. 6*a74d5e83SLaura Nao * Laura Nao <laura.nao@collabora.com> 7*a74d5e83SLaura Nao */ 8*a74d5e83SLaura Nao #include <dt-bindings/clock/mediatek,mt8196-clock.h> 9*a74d5e83SLaura Nao #include <dt-bindings/reset/mediatek,mt8196-resets.h> 10*a74d5e83SLaura Nao 11*a74d5e83SLaura Nao #include <linux/clk-provider.h> 12*a74d5e83SLaura Nao #include <linux/module.h> 13*a74d5e83SLaura Nao #include <linux/of_device.h> 14*a74d5e83SLaura Nao #include <linux/platform_device.h> 15*a74d5e83SLaura Nao 16*a74d5e83SLaura Nao #include "clk-gate.h" 17*a74d5e83SLaura Nao #include "clk-mtk.h" 18*a74d5e83SLaura Nao 19*a74d5e83SLaura Nao #define MT8196_UFSAO_RST0_SET_OFFSET 0x48 20*a74d5e83SLaura Nao #define MT8196_UFSAO_RST1_SET_OFFSET 0x148 21*a74d5e83SLaura Nao 22*a74d5e83SLaura Nao static const struct mtk_gate_regs ufsao0_cg_regs = { 23*a74d5e83SLaura Nao .set_ofs = 0x108, 24*a74d5e83SLaura Nao .clr_ofs = 0x10c, 25*a74d5e83SLaura Nao .sta_ofs = 0x104, 26*a74d5e83SLaura Nao }; 27*a74d5e83SLaura Nao 28*a74d5e83SLaura Nao static const struct mtk_gate_regs ufsao1_cg_regs = { 29*a74d5e83SLaura Nao .set_ofs = 0x8, 30*a74d5e83SLaura Nao .clr_ofs = 0xc, 31*a74d5e83SLaura Nao .sta_ofs = 0x4, 32*a74d5e83SLaura Nao }; 33*a74d5e83SLaura Nao 34*a74d5e83SLaura Nao #define GATE_UFSAO0(_id, _name, _parent, _shift) { \ 35*a74d5e83SLaura Nao .id = _id, \ 36*a74d5e83SLaura Nao .name = _name, \ 37*a74d5e83SLaura Nao .parent_name = _parent, \ 38*a74d5e83SLaura Nao .regs = &ufsao0_cg_regs, \ 39*a74d5e83SLaura Nao .shift = _shift, \ 40*a74d5e83SLaura Nao .ops = &mtk_clk_gate_ops_setclr, \ 41*a74d5e83SLaura Nao } 42*a74d5e83SLaura Nao 43*a74d5e83SLaura Nao #define GATE_UFSAO1(_id, _name, _parent, _shift) { \ 44*a74d5e83SLaura Nao .id = _id, \ 45*a74d5e83SLaura Nao .name = _name, \ 46*a74d5e83SLaura Nao .parent_name = _parent, \ 47*a74d5e83SLaura Nao .regs = &ufsao1_cg_regs, \ 48*a74d5e83SLaura Nao .shift = _shift, \ 49*a74d5e83SLaura Nao .ops = &mtk_clk_gate_ops_setclr, \ 50*a74d5e83SLaura Nao } 51*a74d5e83SLaura Nao 52*a74d5e83SLaura Nao static const struct mtk_gate ufsao_clks[] = { 53*a74d5e83SLaura Nao /* UFSAO0 */ 54*a74d5e83SLaura Nao GATE_UFSAO0(CLK_UFSAO_UFSHCI_UFS, "ufsao_ufshci_ufs", "ufs", 0), 55*a74d5e83SLaura Nao GATE_UFSAO0(CLK_UFSAO_UFSHCI_AES, "ufsao_ufshci_aes", "aes_ufsfde", 1), 56*a74d5e83SLaura Nao /* UFSAO1 */ 57*a74d5e83SLaura Nao GATE_UFSAO1(CLK_UFSAO_UNIPRO_TX_SYM, "ufsao_unipro_tx_sym", "clk26m", 0), 58*a74d5e83SLaura Nao GATE_UFSAO1(CLK_UFSAO_UNIPRO_RX_SYM0, "ufsao_unipro_rx_sym0", "clk26m", 1), 59*a74d5e83SLaura Nao GATE_UFSAO1(CLK_UFSAO_UNIPRO_RX_SYM1, "ufsao_unipro_rx_sym1", "clk26m", 2), 60*a74d5e83SLaura Nao GATE_UFSAO1(CLK_UFSAO_UNIPRO_SYS, "ufsao_unipro_sys", "ufs", 3), 61*a74d5e83SLaura Nao GATE_UFSAO1(CLK_UFSAO_UNIPRO_SAP, "ufsao_unipro_sap", "clk26m", 4), 62*a74d5e83SLaura Nao GATE_UFSAO1(CLK_UFSAO_PHY_SAP, "ufsao_phy_sap", "clk26m", 8), 63*a74d5e83SLaura Nao }; 64*a74d5e83SLaura Nao 65*a74d5e83SLaura Nao static u16 ufsao_rst_ofs[] = { 66*a74d5e83SLaura Nao MT8196_UFSAO_RST0_SET_OFFSET, 67*a74d5e83SLaura Nao MT8196_UFSAO_RST1_SET_OFFSET 68*a74d5e83SLaura Nao }; 69*a74d5e83SLaura Nao 70*a74d5e83SLaura Nao static u16 ufsao_rst_idx_map[] = { 71*a74d5e83SLaura Nao [MT8196_UFSAO_RST0_UFS_MPHY] = 8, 72*a74d5e83SLaura Nao [MT8196_UFSAO_RST1_UFS_UNIPRO] = 1 * RST_NR_PER_BANK + 0, 73*a74d5e83SLaura Nao [MT8196_UFSAO_RST1_UFS_CRYPTO] = 1 * RST_NR_PER_BANK + 1, 74*a74d5e83SLaura Nao [MT8196_UFSAO_RST1_UFSHCI] = 1 * RST_NR_PER_BANK + 2, 75*a74d5e83SLaura Nao }; 76*a74d5e83SLaura Nao 77*a74d5e83SLaura Nao static const struct mtk_clk_rst_desc ufsao_rst_desc = { 78*a74d5e83SLaura Nao .version = MTK_RST_SET_CLR, 79*a74d5e83SLaura Nao .rst_bank_ofs = ufsao_rst_ofs, 80*a74d5e83SLaura Nao .rst_bank_nr = ARRAY_SIZE(ufsao_rst_ofs), 81*a74d5e83SLaura Nao .rst_idx_map = ufsao_rst_idx_map, 82*a74d5e83SLaura Nao .rst_idx_map_nr = ARRAY_SIZE(ufsao_rst_idx_map), 83*a74d5e83SLaura Nao }; 84*a74d5e83SLaura Nao 85*a74d5e83SLaura Nao static const struct mtk_clk_desc ufsao_mcd = { 86*a74d5e83SLaura Nao .clks = ufsao_clks, 87*a74d5e83SLaura Nao .num_clks = ARRAY_SIZE(ufsao_clks), 88*a74d5e83SLaura Nao .rst_desc = &ufsao_rst_desc, 89*a74d5e83SLaura Nao }; 90*a74d5e83SLaura Nao 91*a74d5e83SLaura Nao static const struct of_device_id of_match_clk_mt8196_ufs_ao[] = { 92*a74d5e83SLaura Nao { .compatible = "mediatek,mt8196-ufscfg-ao", .data = &ufsao_mcd }, 93*a74d5e83SLaura Nao { /* sentinel */ } 94*a74d5e83SLaura Nao }; 95*a74d5e83SLaura Nao MODULE_DEVICE_TABLE(of, of_match_clk_mt8196_ufs_ao); 96*a74d5e83SLaura Nao 97*a74d5e83SLaura Nao static struct platform_driver clk_mt8196_ufs_ao_drv = { 98*a74d5e83SLaura Nao .probe = mtk_clk_simple_probe, 99*a74d5e83SLaura Nao .remove = mtk_clk_simple_remove, 100*a74d5e83SLaura Nao .driver = { 101*a74d5e83SLaura Nao .name = "clk-mt8196-ufs-ao", 102*a74d5e83SLaura Nao .of_match_table = of_match_clk_mt8196_ufs_ao, 103*a74d5e83SLaura Nao }, 104*a74d5e83SLaura Nao }; 105*a74d5e83SLaura Nao 106*a74d5e83SLaura Nao module_platform_driver(clk_mt8196_ufs_ao_drv); 107*a74d5e83SLaura Nao MODULE_DESCRIPTION("MediaTek MT8196 ufs_ao clocks driver"); 108*a74d5e83SLaura Nao MODULE_LICENSE("GPL"); 109