Loading arch/arm/mach-msm/clock-fsm9900.c +105 −1 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -2108,6 +2108,50 @@ static struct gate_clk pcie_1_phy_ldo = { }, }; static struct branch_clk gcc_emac0_axi_clk = { .cbcr_reg = EMAC_0_AXI_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac0_axi_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac0_axi_clk.c), }, }; static struct branch_clk gcc_emac1_axi_clk = { .cbcr_reg = EMAC_1_AXI_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac1_axi_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac1_axi_clk.c), }, }; static struct branch_clk gcc_emac0_ahb_clk = { .cbcr_reg = EMAC_0_AHB_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac0_ahb_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac0_ahb_clk.c), }, }; static struct branch_clk gcc_emac1_ahb_clk = { .cbcr_reg = EMAC_1_AHB_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac1_ahb_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac1_ahb_clk.c), }, }; static struct clk_freq_tbl ftbl_gcc_emac0_1_125m_clk[] = { F( 19200000, xo, 1, 0, 0), F_EXT( 125000000, emac0_125m, 1, 0, 0), Loading Loading @@ -2276,6 +2320,50 @@ static struct branch_clk gcc_emac1_tx_clk = { }, }; static struct branch_clk gcc_emac0_rx_clk = { .cbcr_reg = EMAC_0_RX_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac0_rx_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac0_rx_clk.c), }, }; static struct branch_clk gcc_emac1_rx_clk = { .cbcr_reg = EMAC_1_RX_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac1_rx_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac1_rx_clk.c), }, }; static struct branch_clk gcc_emac0_sys_clk = { .cbcr_reg = EMAC_0_SYS_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac0_sys_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac0_sys_clk.c), }, }; static struct branch_clk gcc_emac1_sys_clk = { .cbcr_reg = EMAC_1_SYS_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac1_sys_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac1_sys_clk.c), }, }; static DEFINE_CLK_MEASURE(l2_m_clk); static DEFINE_CLK_MEASURE(krait0_m_clk); static DEFINE_CLK_MEASURE(krait1_m_clk); Loading Loading @@ -2368,12 +2456,20 @@ struct measure_mux_entry measure_mux[] = { {&gcc_ce3_clk.c, GCC_BASE, 0x0228}, {&gcc_ce3_axi_clk.c, GCC_BASE, 0x0229}, {&gcc_ce3_ahb_clk.c, GCC_BASE, 0x022a}, {&gcc_emac0_axi_clk.c, GCC_BASE, 0x01a8}, {&gcc_emac0_ahb_clk.c, GCC_BASE, 0x01a9}, {&gcc_emac0_sys_25m_clk.c, GCC_BASE, 0x01aa}, {&gcc_emac0_tx_clk.c, GCC_BASE, 0x01ab}, {&gcc_emac0_125m_clk.c, GCC_BASE, 0x01ac}, {&gcc_emac0_rx_clk.c, GCC_BASE, 0x01ad}, {&gcc_emac0_sys_clk.c, GCC_BASE, 0x01ae}, {&gcc_emac1_axi_clk.c, GCC_BASE, 0x01b0}, {&gcc_emac1_ahb_clk.c, GCC_BASE, 0x01b1}, {&gcc_emac1_sys_25m_clk.c, GCC_BASE, 0x01b2}, {&gcc_emac1_tx_clk.c, GCC_BASE, 0x01b3}, {&gcc_emac1_125m_clk.c, GCC_BASE, 0x01b4}, {&gcc_emac1_rx_clk.c, GCC_BASE, 0x01b5}, {&gcc_emac1_sys_clk.c, GCC_BASE, 0x01b6}, {&krait0_clk.c, APCS_BASE, M_ACPU0}, {&krait1_clk.c, APCS_BASE, M_ACPU1}, Loading Loading @@ -2630,12 +2726,20 @@ static struct clk_lookup fsm_clocks_9900[] = { CLK_LOOKUP("xo", xo_usb_hs_host_clk.c, "msm_ehci_host"), /* EMAC clocks */ CLK_LOOKUP("axi_clk", gcc_emac0_axi_clk.c, "feb20000.qcom,emac"), CLK_LOOKUP("cfg_ahb_clk", gcc_emac0_ahb_clk.c, "feb20000.qcom,emac"), CLK_LOOKUP("25m_clk", emac0_sys_25m_clk_src.c, "feb20000.qcom,emac"), CLK_LOOKUP("125m_clk", emac0_125m_clk_src.c, "feb20000.qcom,emac"), CLK_LOOKUP("tx_clk", emac0_tx_clk_src.c, "feb20000.qcom,emac"), CLK_LOOKUP("rx_clk", gcc_emac0_rx_clk.c, "feb20000.qcom,emac"), CLK_LOOKUP("sys_clk", gcc_emac0_sys_clk.c, "feb20000.qcom,emac"), CLK_LOOKUP("axi_clk", gcc_emac1_axi_clk.c, "feb00000.qcom,emac"), CLK_LOOKUP("cfg_ahb_clk", gcc_emac1_ahb_clk.c, "feb00000.qcom,emac"), CLK_LOOKUP("25m_clk", emac1_sys_25m_clk_src.c, "feb00000.qcom,emac"), CLK_LOOKUP("125m_clk", emac1_125m_clk_src.c, "feb00000.qcom,emac"), CLK_LOOKUP("tx_clk", emac1_tx_clk_src.c, "feb00000.qcom,emac"), CLK_LOOKUP("rx_clk", gcc_emac1_rx_clk.c, "feb00000.qcom,emac"), CLK_LOOKUP("sys_clk", gcc_emac1_sys_clk.c, "feb00000.qcom,emac"), /* PCIE clocks */ Loading drivers/net/ethernet/msm/emac/emac.h +13 −7 Original line number Diff line number Diff line Loading @@ -36,11 +36,15 @@ #define EMAC_SGMII_PHY_IRQ 5 #define EMAC_NUM_IRQ 6 /* emac clock */ #define EMAC_SGMII_125M_CLK 0 #define EMAC_SGMII_SYS_25M_CLK 1 #define EMAC_SGMII_TX_CLK 2 #define EMAC_NUM_CLK 3 /* emac clocks */ #define EMAC_AXI_CLK 0 #define EMAC_CFG_AHB_CLK 1 #define EMAC_125M_CLK 2 #define EMAC_SYS_25M_CLK 3 #define EMAC_TX_CLK 4 #define EMAC_RX_CLK 5 #define EMAC_SYS_CLK 6 #define EMAC_NUM_CLK 7 /* mdio/mdc gpios */ #define EMAC_NUM_GPIO 2 Loading Loading @@ -500,6 +504,8 @@ struct emac_gpio_info { struct emac_clk_info { struct clk *clk; char *name; bool enabled; struct emac_adapter *adpt; }; /* emac_ring_header represents a single, contiguous block of DMA space Loading drivers/net/ethernet/msm/emac/emac_hw.c +1 −35 Original line number Diff line number Diff line Loading @@ -29,11 +29,6 @@ #define RXD_TH 0x100 #define SGMII_125M_CLK_RATE 125000000 #define SGMII_25M_CLK_RATE 25000000 #define SGMII_TX_CLK_RATE 125000000 #define SGMII_CXO_CLK_RATE 19200000 static int emac_hw_sgmii_setup_link(struct emac_hw *hw, u32 speed, bool autoneg, bool fc); Loading Loading @@ -256,29 +251,6 @@ int emac_hw_ack_phy_intr(struct emac_hw *hw) return 0; } static int emac_hw_sgmii_setclk(struct emac_hw *hw, bool cxo) { struct clk *clk; int retval; clk = hw->adpt->clk_info[EMAC_SGMII_125M_CLK].clk; retval = clk_set_rate(clk, (cxo) ? SGMII_CXO_CLK_RATE : SGMII_125M_CLK_RATE); if (retval) return retval; clk = hw->adpt->clk_info[EMAC_SGMII_SYS_25M_CLK].clk; retval = clk_set_rate(clk, (cxo) ? SGMII_CXO_CLK_RATE : SGMII_25M_CLK_RATE); if (retval) return retval; clk = hw->adpt->clk_info[EMAC_SGMII_TX_CLK].clk; retval = clk_set_rate(clk, (cxo) ? SGMII_CXO_CLK_RATE : SGMII_TX_CLK_RATE); return retval; } int emac_hw_init_sgmii(struct emac_hw *hw) { int i; Loading Loading @@ -393,17 +365,11 @@ int emac_hw_init_sgmii(struct emac_hw *hw) emac_hw_clear_sgmii_intr_status(hw, SGMII_PHY_INTERRUPT_ERR); return emac_hw_sgmii_setclk(hw, false); return 0; } int emac_hw_reset_sgmii(struct emac_hw *hw) { int retval; retval = emac_hw_sgmii_setclk(hw, true); if (retval) return retval; /* It may take about 100ms to reset the SGMII PHY*/ emac_reg_update32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_CSR2, PHY_RESET, PHY_RESET); Loading drivers/net/ethernet/msm/emac/emac_main.c +119 −16 Original line number Diff line number Diff line Loading @@ -93,11 +93,41 @@ static struct emac_gpio_info emac_gpio[EMAC_NUM_GPIO] = { }; static struct emac_clk_info emac_clk[EMAC_NUM_CLK] = { { 0, "125m_clk" }, { 0, "25m_clk" }, { 0, "tx_clk" }, { NULL, "axi_clk", 0, NULL }, { NULL, "cfg_ahb_clk", 0, NULL }, { NULL, "125m_clk", 0, NULL }, { NULL, "25m_clk", 0, NULL }, { NULL, "tx_clk", 0, NULL }, { NULL, "rx_clk", 0, NULL }, { NULL, "sys_clk", 0, NULL }, }; static int emac_clk_prepare_enable(struct emac_clk_info *clk_info) { int retval; retval = clk_prepare_enable(clk_info->clk); if (retval) emac_err(clk_info->adpt, "can't enable clk %s\n", clk_info->name); else clk_info->enabled = true; return retval; } static int emac_clk_set_rate(struct emac_clk_info *clk_info, unsigned long rate) { int retval; retval = clk_set_rate(clk_info->clk, rate); if (retval) emac_err(clk_info->adpt, "can't set rate for clk %s\n", clk_info->name); return retval; } /* reinitialize */ void emac_reinit_locked(struct emac_adapter *adpt) { Loading @@ -112,8 +142,11 @@ void emac_reinit_locked(struct emac_adapter *adpt) } emac_down(adpt, EMAC_HW_CTRL_RESET_MAC); if (adpt->phy_mode == PHY_INTERFACE_MODE_SGMII) if (adpt->phy_mode == PHY_INTERFACE_MODE_SGMII) { emac_clk_set_rate(&adpt->clk_info[EMAC_125M_CLK], 19200000); emac_hw_reset_sgmii(&adpt->hw); emac_clk_set_rate(&adpt->clk_info[EMAC_125M_CLK], 125000000); } emac_up(adpt); CLI_ADPT_FLAG(STATE_RESETTING); Loading Loading @@ -2127,9 +2160,6 @@ static void emac_init_adapter(struct emac_adapter *adpt) /* others */ hw->preamble = EMAC_PREAMBLE_DEF; adpt->wol = EMAC_WOL_MAGIC | EMAC_WOL_PHY; /* phy */ emac_hw_init_phy(hw); } #ifdef CONFIG_PM_RUNTIME Loading Loading @@ -2266,10 +2296,6 @@ static int emac_get_clk(struct platform_device *pdev, int retval = 0; u8 i; /* currently all clocks are sgmii clocks */ if (adpt->phy_mode != PHY_INTERFACE_MODE_SGMII) return 0; for (i = 0; i < EMAC_NUM_CLK; i++) { clk_info = &adpt->clk_info[i]; clk = clk_get(&pdev->dev, clk_info->name); Loading @@ -2288,15 +2314,74 @@ static int emac_get_clk(struct platform_device *pdev, return retval; } static void emac_prepare_enable_clk(struct emac_adapter *adpt) /* Initialize clocks */ static int emac_init_clks(struct emac_adapter *adpt) { int retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_AXI_CLK]); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_CFG_AHB_CLK]); if (retval) return retval; retval = emac_clk_set_rate(&adpt->clk_info[EMAC_125M_CLK], 19200000); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_125M_CLK]); return retval; } /* Enable clocks; needs emac_init_clks to be called before */ static int emac_enable_clks(struct emac_adapter *adpt) { int retval; retval = emac_clk_set_rate(&adpt->clk_info[EMAC_TX_CLK], 125000000); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_TX_CLK]); if (retval) return retval; retval = emac_clk_set_rate(&adpt->clk_info[EMAC_125M_CLK], 125000000); if (retval) return retval; retval = emac_clk_set_rate(&adpt->clk_info[EMAC_SYS_25M_CLK], 25000000); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_SYS_25M_CLK]); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_RX_CLK]); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_SYS_CLK]); return retval; } /* Disable clocks */ static void emac_disable_clks(struct emac_adapter *adpt) { struct emac_clk_info *clk_info; u8 i; for (i = 0; i < EMAC_NUM_CLK; i++) { clk_info = &adpt->clk_info[i]; if (clk_info->clk) clk_prepare_enable(clk_info->clk); if (clk_info->enabled) { clk_disable_unprepare(clk_info->clk); clk_info->enabled = false; } } } Loading Loading @@ -2482,7 +2567,10 @@ static int emac_probe(struct platform_device *pdev) dma_set_max_seg_size(&pdev->dev, 65536); dma_set_seg_boundary(&pdev->dev, 0xffffffff); memcpy(&adpt->clk_info, emac_clk, sizeof(emac_clk)); memcpy(adpt->clk_info, emac_clk, sizeof(emac_clk)); for (i = 0; i < EMAC_NUM_CLK; i++) adpt->clk_info[i].adpt = adpt; memcpy(adpt->gpio_info, emac_gpio, sizeof(adpt->gpio_info)); memcpy(adpt->irq_info, emac_irq, sizeof(adpt->irq_info)); for (i = 0; i < EMAC_NUM_CORE_IRQ; i++) { Loading @@ -2498,7 +2586,10 @@ static int emac_probe(struct platform_device *pdev) if (retval) goto err_res; emac_prepare_enable_clk(adpt); /* initialize clocks */ retval = emac_init_clks(adpt); if (retval) goto err_clk_init; hw_ver = emac_reg_r32(hw, EMAC, EMAC_CORE_HW_VERSION); Loading Loading @@ -2526,6 +2617,14 @@ static int emac_probe(struct platform_device *pdev) /* init adapter */ emac_init_adapter(adpt); /* init phy */ emac_hw_init_phy(hw); /* enable clocks */ retval = emac_enable_clks(adpt); if (retval) goto err_clk_en; /* reset phy */ emac_hw_reset_phy(hw); Loading Loading @@ -2586,6 +2685,9 @@ static int emac_probe(struct platform_device *pdev) err_register_netdev: err_phy_link: err_clk_en: err_clk_init: emac_disable_clks(adpt); emac_release_resources(adpt); err_res: free_netdev(netdev); Loading @@ -2605,6 +2707,7 @@ static int emac_remove(struct platform_device *pdev) if (CHK_HW_FLAG(PTP_CAP)) emac_ptp_remove(netdev); emac_disable_clks(adpt); emac_release_resources(adpt); free_netdev(netdev); dev_set_drvdata(&pdev->dev, NULL); Loading Loading
arch/arm/mach-msm/clock-fsm9900.c +105 −1 Original line number Diff line number Diff line /* Copyright (c) 2013, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -2108,6 +2108,50 @@ static struct gate_clk pcie_1_phy_ldo = { }, }; static struct branch_clk gcc_emac0_axi_clk = { .cbcr_reg = EMAC_0_AXI_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac0_axi_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac0_axi_clk.c), }, }; static struct branch_clk gcc_emac1_axi_clk = { .cbcr_reg = EMAC_1_AXI_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac1_axi_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac1_axi_clk.c), }, }; static struct branch_clk gcc_emac0_ahb_clk = { .cbcr_reg = EMAC_0_AHB_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac0_ahb_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac0_ahb_clk.c), }, }; static struct branch_clk gcc_emac1_ahb_clk = { .cbcr_reg = EMAC_1_AHB_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac1_ahb_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac1_ahb_clk.c), }, }; static struct clk_freq_tbl ftbl_gcc_emac0_1_125m_clk[] = { F( 19200000, xo, 1, 0, 0), F_EXT( 125000000, emac0_125m, 1, 0, 0), Loading Loading @@ -2276,6 +2320,50 @@ static struct branch_clk gcc_emac1_tx_clk = { }, }; static struct branch_clk gcc_emac0_rx_clk = { .cbcr_reg = EMAC_0_RX_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac0_rx_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac0_rx_clk.c), }, }; static struct branch_clk gcc_emac1_rx_clk = { .cbcr_reg = EMAC_1_RX_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac1_rx_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac1_rx_clk.c), }, }; static struct branch_clk gcc_emac0_sys_clk = { .cbcr_reg = EMAC_0_SYS_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac0_sys_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac0_sys_clk.c), }, }; static struct branch_clk gcc_emac1_sys_clk = { .cbcr_reg = EMAC_1_SYS_CBCR, .has_sibling = 1, .base = &virt_bases[GCC_BASE], .c = { .dbg_name = "gcc_emac1_sys_clk", .ops = &clk_ops_branch, CLK_INIT(gcc_emac1_sys_clk.c), }, }; static DEFINE_CLK_MEASURE(l2_m_clk); static DEFINE_CLK_MEASURE(krait0_m_clk); static DEFINE_CLK_MEASURE(krait1_m_clk); Loading Loading @@ -2368,12 +2456,20 @@ struct measure_mux_entry measure_mux[] = { {&gcc_ce3_clk.c, GCC_BASE, 0x0228}, {&gcc_ce3_axi_clk.c, GCC_BASE, 0x0229}, {&gcc_ce3_ahb_clk.c, GCC_BASE, 0x022a}, {&gcc_emac0_axi_clk.c, GCC_BASE, 0x01a8}, {&gcc_emac0_ahb_clk.c, GCC_BASE, 0x01a9}, {&gcc_emac0_sys_25m_clk.c, GCC_BASE, 0x01aa}, {&gcc_emac0_tx_clk.c, GCC_BASE, 0x01ab}, {&gcc_emac0_125m_clk.c, GCC_BASE, 0x01ac}, {&gcc_emac0_rx_clk.c, GCC_BASE, 0x01ad}, {&gcc_emac0_sys_clk.c, GCC_BASE, 0x01ae}, {&gcc_emac1_axi_clk.c, GCC_BASE, 0x01b0}, {&gcc_emac1_ahb_clk.c, GCC_BASE, 0x01b1}, {&gcc_emac1_sys_25m_clk.c, GCC_BASE, 0x01b2}, {&gcc_emac1_tx_clk.c, GCC_BASE, 0x01b3}, {&gcc_emac1_125m_clk.c, GCC_BASE, 0x01b4}, {&gcc_emac1_rx_clk.c, GCC_BASE, 0x01b5}, {&gcc_emac1_sys_clk.c, GCC_BASE, 0x01b6}, {&krait0_clk.c, APCS_BASE, M_ACPU0}, {&krait1_clk.c, APCS_BASE, M_ACPU1}, Loading Loading @@ -2630,12 +2726,20 @@ static struct clk_lookup fsm_clocks_9900[] = { CLK_LOOKUP("xo", xo_usb_hs_host_clk.c, "msm_ehci_host"), /* EMAC clocks */ CLK_LOOKUP("axi_clk", gcc_emac0_axi_clk.c, "feb20000.qcom,emac"), CLK_LOOKUP("cfg_ahb_clk", gcc_emac0_ahb_clk.c, "feb20000.qcom,emac"), CLK_LOOKUP("25m_clk", emac0_sys_25m_clk_src.c, "feb20000.qcom,emac"), CLK_LOOKUP("125m_clk", emac0_125m_clk_src.c, "feb20000.qcom,emac"), CLK_LOOKUP("tx_clk", emac0_tx_clk_src.c, "feb20000.qcom,emac"), CLK_LOOKUP("rx_clk", gcc_emac0_rx_clk.c, "feb20000.qcom,emac"), CLK_LOOKUP("sys_clk", gcc_emac0_sys_clk.c, "feb20000.qcom,emac"), CLK_LOOKUP("axi_clk", gcc_emac1_axi_clk.c, "feb00000.qcom,emac"), CLK_LOOKUP("cfg_ahb_clk", gcc_emac1_ahb_clk.c, "feb00000.qcom,emac"), CLK_LOOKUP("25m_clk", emac1_sys_25m_clk_src.c, "feb00000.qcom,emac"), CLK_LOOKUP("125m_clk", emac1_125m_clk_src.c, "feb00000.qcom,emac"), CLK_LOOKUP("tx_clk", emac1_tx_clk_src.c, "feb00000.qcom,emac"), CLK_LOOKUP("rx_clk", gcc_emac1_rx_clk.c, "feb00000.qcom,emac"), CLK_LOOKUP("sys_clk", gcc_emac1_sys_clk.c, "feb00000.qcom,emac"), /* PCIE clocks */ Loading
drivers/net/ethernet/msm/emac/emac.h +13 −7 Original line number Diff line number Diff line Loading @@ -36,11 +36,15 @@ #define EMAC_SGMII_PHY_IRQ 5 #define EMAC_NUM_IRQ 6 /* emac clock */ #define EMAC_SGMII_125M_CLK 0 #define EMAC_SGMII_SYS_25M_CLK 1 #define EMAC_SGMII_TX_CLK 2 #define EMAC_NUM_CLK 3 /* emac clocks */ #define EMAC_AXI_CLK 0 #define EMAC_CFG_AHB_CLK 1 #define EMAC_125M_CLK 2 #define EMAC_SYS_25M_CLK 3 #define EMAC_TX_CLK 4 #define EMAC_RX_CLK 5 #define EMAC_SYS_CLK 6 #define EMAC_NUM_CLK 7 /* mdio/mdc gpios */ #define EMAC_NUM_GPIO 2 Loading Loading @@ -500,6 +504,8 @@ struct emac_gpio_info { struct emac_clk_info { struct clk *clk; char *name; bool enabled; struct emac_adapter *adpt; }; /* emac_ring_header represents a single, contiguous block of DMA space Loading
drivers/net/ethernet/msm/emac/emac_hw.c +1 −35 Original line number Diff line number Diff line Loading @@ -29,11 +29,6 @@ #define RXD_TH 0x100 #define SGMII_125M_CLK_RATE 125000000 #define SGMII_25M_CLK_RATE 25000000 #define SGMII_TX_CLK_RATE 125000000 #define SGMII_CXO_CLK_RATE 19200000 static int emac_hw_sgmii_setup_link(struct emac_hw *hw, u32 speed, bool autoneg, bool fc); Loading Loading @@ -256,29 +251,6 @@ int emac_hw_ack_phy_intr(struct emac_hw *hw) return 0; } static int emac_hw_sgmii_setclk(struct emac_hw *hw, bool cxo) { struct clk *clk; int retval; clk = hw->adpt->clk_info[EMAC_SGMII_125M_CLK].clk; retval = clk_set_rate(clk, (cxo) ? SGMII_CXO_CLK_RATE : SGMII_125M_CLK_RATE); if (retval) return retval; clk = hw->adpt->clk_info[EMAC_SGMII_SYS_25M_CLK].clk; retval = clk_set_rate(clk, (cxo) ? SGMII_CXO_CLK_RATE : SGMII_25M_CLK_RATE); if (retval) return retval; clk = hw->adpt->clk_info[EMAC_SGMII_TX_CLK].clk; retval = clk_set_rate(clk, (cxo) ? SGMII_CXO_CLK_RATE : SGMII_TX_CLK_RATE); return retval; } int emac_hw_init_sgmii(struct emac_hw *hw) { int i; Loading Loading @@ -393,17 +365,11 @@ int emac_hw_init_sgmii(struct emac_hw *hw) emac_hw_clear_sgmii_intr_status(hw, SGMII_PHY_INTERRUPT_ERR); return emac_hw_sgmii_setclk(hw, false); return 0; } int emac_hw_reset_sgmii(struct emac_hw *hw) { int retval; retval = emac_hw_sgmii_setclk(hw, true); if (retval) return retval; /* It may take about 100ms to reset the SGMII PHY*/ emac_reg_update32(hw, EMAC_CSR, EMAC_EMAC_WRAPPER_CSR2, PHY_RESET, PHY_RESET); Loading
drivers/net/ethernet/msm/emac/emac_main.c +119 −16 Original line number Diff line number Diff line Loading @@ -93,11 +93,41 @@ static struct emac_gpio_info emac_gpio[EMAC_NUM_GPIO] = { }; static struct emac_clk_info emac_clk[EMAC_NUM_CLK] = { { 0, "125m_clk" }, { 0, "25m_clk" }, { 0, "tx_clk" }, { NULL, "axi_clk", 0, NULL }, { NULL, "cfg_ahb_clk", 0, NULL }, { NULL, "125m_clk", 0, NULL }, { NULL, "25m_clk", 0, NULL }, { NULL, "tx_clk", 0, NULL }, { NULL, "rx_clk", 0, NULL }, { NULL, "sys_clk", 0, NULL }, }; static int emac_clk_prepare_enable(struct emac_clk_info *clk_info) { int retval; retval = clk_prepare_enable(clk_info->clk); if (retval) emac_err(clk_info->adpt, "can't enable clk %s\n", clk_info->name); else clk_info->enabled = true; return retval; } static int emac_clk_set_rate(struct emac_clk_info *clk_info, unsigned long rate) { int retval; retval = clk_set_rate(clk_info->clk, rate); if (retval) emac_err(clk_info->adpt, "can't set rate for clk %s\n", clk_info->name); return retval; } /* reinitialize */ void emac_reinit_locked(struct emac_adapter *adpt) { Loading @@ -112,8 +142,11 @@ void emac_reinit_locked(struct emac_adapter *adpt) } emac_down(adpt, EMAC_HW_CTRL_RESET_MAC); if (adpt->phy_mode == PHY_INTERFACE_MODE_SGMII) if (adpt->phy_mode == PHY_INTERFACE_MODE_SGMII) { emac_clk_set_rate(&adpt->clk_info[EMAC_125M_CLK], 19200000); emac_hw_reset_sgmii(&adpt->hw); emac_clk_set_rate(&adpt->clk_info[EMAC_125M_CLK], 125000000); } emac_up(adpt); CLI_ADPT_FLAG(STATE_RESETTING); Loading Loading @@ -2127,9 +2160,6 @@ static void emac_init_adapter(struct emac_adapter *adpt) /* others */ hw->preamble = EMAC_PREAMBLE_DEF; adpt->wol = EMAC_WOL_MAGIC | EMAC_WOL_PHY; /* phy */ emac_hw_init_phy(hw); } #ifdef CONFIG_PM_RUNTIME Loading Loading @@ -2266,10 +2296,6 @@ static int emac_get_clk(struct platform_device *pdev, int retval = 0; u8 i; /* currently all clocks are sgmii clocks */ if (adpt->phy_mode != PHY_INTERFACE_MODE_SGMII) return 0; for (i = 0; i < EMAC_NUM_CLK; i++) { clk_info = &adpt->clk_info[i]; clk = clk_get(&pdev->dev, clk_info->name); Loading @@ -2288,15 +2314,74 @@ static int emac_get_clk(struct platform_device *pdev, return retval; } static void emac_prepare_enable_clk(struct emac_adapter *adpt) /* Initialize clocks */ static int emac_init_clks(struct emac_adapter *adpt) { int retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_AXI_CLK]); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_CFG_AHB_CLK]); if (retval) return retval; retval = emac_clk_set_rate(&adpt->clk_info[EMAC_125M_CLK], 19200000); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_125M_CLK]); return retval; } /* Enable clocks; needs emac_init_clks to be called before */ static int emac_enable_clks(struct emac_adapter *adpt) { int retval; retval = emac_clk_set_rate(&adpt->clk_info[EMAC_TX_CLK], 125000000); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_TX_CLK]); if (retval) return retval; retval = emac_clk_set_rate(&adpt->clk_info[EMAC_125M_CLK], 125000000); if (retval) return retval; retval = emac_clk_set_rate(&adpt->clk_info[EMAC_SYS_25M_CLK], 25000000); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_SYS_25M_CLK]); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_RX_CLK]); if (retval) return retval; retval = emac_clk_prepare_enable(&adpt->clk_info[EMAC_SYS_CLK]); return retval; } /* Disable clocks */ static void emac_disable_clks(struct emac_adapter *adpt) { struct emac_clk_info *clk_info; u8 i; for (i = 0; i < EMAC_NUM_CLK; i++) { clk_info = &adpt->clk_info[i]; if (clk_info->clk) clk_prepare_enable(clk_info->clk); if (clk_info->enabled) { clk_disable_unprepare(clk_info->clk); clk_info->enabled = false; } } } Loading Loading @@ -2482,7 +2567,10 @@ static int emac_probe(struct platform_device *pdev) dma_set_max_seg_size(&pdev->dev, 65536); dma_set_seg_boundary(&pdev->dev, 0xffffffff); memcpy(&adpt->clk_info, emac_clk, sizeof(emac_clk)); memcpy(adpt->clk_info, emac_clk, sizeof(emac_clk)); for (i = 0; i < EMAC_NUM_CLK; i++) adpt->clk_info[i].adpt = adpt; memcpy(adpt->gpio_info, emac_gpio, sizeof(adpt->gpio_info)); memcpy(adpt->irq_info, emac_irq, sizeof(adpt->irq_info)); for (i = 0; i < EMAC_NUM_CORE_IRQ; i++) { Loading @@ -2498,7 +2586,10 @@ static int emac_probe(struct platform_device *pdev) if (retval) goto err_res; emac_prepare_enable_clk(adpt); /* initialize clocks */ retval = emac_init_clks(adpt); if (retval) goto err_clk_init; hw_ver = emac_reg_r32(hw, EMAC, EMAC_CORE_HW_VERSION); Loading Loading @@ -2526,6 +2617,14 @@ static int emac_probe(struct platform_device *pdev) /* init adapter */ emac_init_adapter(adpt); /* init phy */ emac_hw_init_phy(hw); /* enable clocks */ retval = emac_enable_clks(adpt); if (retval) goto err_clk_en; /* reset phy */ emac_hw_reset_phy(hw); Loading Loading @@ -2586,6 +2685,9 @@ static int emac_probe(struct platform_device *pdev) err_register_netdev: err_phy_link: err_clk_en: err_clk_init: emac_disable_clks(adpt); emac_release_resources(adpt); err_res: free_netdev(netdev); Loading @@ -2605,6 +2707,7 @@ static int emac_remove(struct platform_device *pdev) if (CHK_HW_FLAG(PTP_CAP)) emac_ptp_remove(netdev); emac_disable_clks(adpt); emac_release_resources(adpt); free_netdev(netdev); dev_set_drvdata(&pdev->dev, NULL); Loading