Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright 2013 Emilio López
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Emilio López <emilio@elopez.com.ar>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright 2013 Chen-Yu Tsai
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Chen-Yu Tsai <wens@csie.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) static DEFINE_SPINLOCK(gmac_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * sun7i_a20_gmac_clk_setup - Setup function for A20/A31 GMAC clock module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * This clock looks something like this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  *                               ________________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  *  MII TX clock from PHY >-----|___________    _________|----> to GMAC core
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  *  GMAC Int. RGMII TX clk >----|___________\__/__gate---|----> to PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  *  Ext. 125MHz RGMII TX clk >--|__divider__/            |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  *                              |________________________|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * The external 125 MHz reference is optional, i.e. GMAC can use its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * internal TX clock just fine. The A31 GMAC clock module does not have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * the divider controls for the external reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32)  * To keep it simple, let the GMAC use either the MII TX clock for MII mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33)  * and its internal TX clock for GMII and RGMII modes. The GMAC driver should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)  * select the appropriate source and gate/ungate the output to the PHY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)  * Only the GMAC should use this clock. Altering the clock so that it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37)  * match the GMAC's operation parameters will result in the GMAC not being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * able to send traffic out. The GMAC driver should set the clock rate and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * enable/disable this clock to configure the required state. The clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * driver then responds by auto-reparenting the clock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define SUN7I_A20_GMAC_GPIT	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #define SUN7I_A20_GMAC_MASK	0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define SUN7I_A20_GMAC_PARENTS	2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static u32 sun7i_a20_gmac_mux_table[SUN7I_A20_GMAC_PARENTS] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	0x00, /* Select mii_phy_tx_clk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	0x02, /* Select gmac_int_tx_clk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) static void __init sun7i_a20_gmac_clk_setup(struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	struct clk_mux *mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	struct clk_gate *gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	const char *clk_name = node->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	const char *parents[SUN7I_A20_GMAC_PARENTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	void __iomem *reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	if (of_property_read_string(node, "clock-output-names", &clk_name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	/* allocate mux and gate clock structs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (!mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	if (!gate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		goto free_mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	/* gmac clock requires exactly 2 parents */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (of_clk_parent_fill(node, parents, 2) != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		goto free_gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	reg = of_iomap(node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	if (!reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		goto free_gate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	/* set up gate and fixed rate properties */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	gate->reg = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	gate->bit_idx = SUN7I_A20_GMAC_GPIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	gate->lock = &gmac_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	mux->reg = reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	mux->mask = SUN7I_A20_GMAC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	mux->table = sun7i_a20_gmac_mux_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	mux->lock = &gmac_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	clk = clk_register_composite(NULL, clk_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			parents, SUN7I_A20_GMAC_PARENTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			&mux->hw, &clk_mux_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			&gate->hw, &clk_gate_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		goto iounmap_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	of_clk_add_provider(node, of_clk_src_simple_get, clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) iounmap_reg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	iounmap(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) free_gate:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	kfree(gate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) free_mux:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	kfree(mux);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) CLK_OF_DECLARE(sun7i_a20_gmac, "allwinner,sun7i-a20-gmac-clk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		sun7i_a20_gmac_clk_setup);