^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Wrapper driver for SERDES used in J721E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Kishon Vijay Abraham I <kishon@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <dt-bindings/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/clk-provider.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/mux/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/reset-controller.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define WIZ_SERDES_CTRL 0x404
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define WIZ_SERDES_TOP_CTRL 0x408
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define WIZ_SERDES_RST 0x40c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define WIZ_SERDES_TYPEC 0x410
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define WIZ_LANECTL(n) (0x480 + (0x40 * (n)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define WIZ_MAX_LANES 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define WIZ_MUX_NUM_CLOCKS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define WIZ_DIV_NUM_CLOCKS_16G 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define WIZ_DIV_NUM_CLOCKS_10G 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define WIZ_SERDES_TYPEC_LN10_SWAP BIT(30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) enum wiz_lane_standard_mode {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) LANE_MODE_GEN1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) LANE_MODE_GEN2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) LANE_MODE_GEN3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) LANE_MODE_GEN4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) enum wiz_refclk_mux_sel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) PLL0_REFCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) PLL1_REFCLK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) REFCLK_DIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) enum wiz_refclk_div_sel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) CMN_REFCLK_DIG_DIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) CMN_REFCLK1_DIG_DIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static const struct reg_field por_en = REG_FIELD(WIZ_SERDES_CTRL, 31, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) static const struct reg_field phy_reset_n = REG_FIELD(WIZ_SERDES_RST, 31, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static const struct reg_field pll1_refclk_mux_sel =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) REG_FIELD(WIZ_SERDES_RST, 29, 29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static const struct reg_field pll0_refclk_mux_sel =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) REG_FIELD(WIZ_SERDES_RST, 28, 28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static const struct reg_field refclk_dig_sel_16g =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) REG_FIELD(WIZ_SERDES_RST, 24, 25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) static const struct reg_field refclk_dig_sel_10g =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) REG_FIELD(WIZ_SERDES_RST, 24, 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static const struct reg_field pma_cmn_refclk_int_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) REG_FIELD(WIZ_SERDES_TOP_CTRL, 28, 29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static const struct reg_field pma_cmn_refclk_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) REG_FIELD(WIZ_SERDES_TOP_CTRL, 30, 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static const struct reg_field pma_cmn_refclk_dig_div =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) REG_FIELD(WIZ_SERDES_TOP_CTRL, 26, 27);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static const struct reg_field pma_cmn_refclk1_dig_div =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) REG_FIELD(WIZ_SERDES_TOP_CTRL, 24, 25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static const struct reg_field p_enable[WIZ_MAX_LANES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) REG_FIELD(WIZ_LANECTL(0), 30, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) REG_FIELD(WIZ_LANECTL(1), 30, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) REG_FIELD(WIZ_LANECTL(2), 30, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) REG_FIELD(WIZ_LANECTL(3), 30, 31),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) enum p_enable { P_ENABLE = 2, P_ENABLE_FORCE = 1, P_ENABLE_DISABLE = 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static const struct reg_field p_align[WIZ_MAX_LANES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) REG_FIELD(WIZ_LANECTL(0), 29, 29),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) REG_FIELD(WIZ_LANECTL(1), 29, 29),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) REG_FIELD(WIZ_LANECTL(2), 29, 29),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) REG_FIELD(WIZ_LANECTL(3), 29, 29),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static const struct reg_field p_raw_auto_start[WIZ_MAX_LANES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) REG_FIELD(WIZ_LANECTL(0), 28, 28),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) REG_FIELD(WIZ_LANECTL(1), 28, 28),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) REG_FIELD(WIZ_LANECTL(2), 28, 28),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) REG_FIELD(WIZ_LANECTL(3), 28, 28),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) static const struct reg_field p_standard_mode[WIZ_MAX_LANES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) REG_FIELD(WIZ_LANECTL(0), 24, 25),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) REG_FIELD(WIZ_LANECTL(1), 24, 25),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) REG_FIELD(WIZ_LANECTL(2), 24, 25),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) REG_FIELD(WIZ_LANECTL(3), 24, 25),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static const struct reg_field typec_ln10_swap =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) REG_FIELD(WIZ_SERDES_TYPEC, 30, 30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) struct wiz_clk_mux {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct regmap_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u32 *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct clk_init_data clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #define to_wiz_clk_mux(_hw) container_of(_hw, struct wiz_clk_mux, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct wiz_clk_divider {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct clk_hw hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct regmap_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) const struct clk_div_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct clk_init_data clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define to_wiz_clk_div(_hw) container_of(_hw, struct wiz_clk_divider, hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct wiz_clk_mux_sel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) struct regmap_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) u32 table[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) const char *node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct wiz_clk_div_sel {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct regmap_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) const struct clk_div_table *table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) const char *node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static struct wiz_clk_mux_sel clk_mux_sel_16g[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * Mux value to be configured for each of the input clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * in the order populated in device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .table = { 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .node_name = "pll0-refclk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .table = { 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .node_name = "pll1-refclk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .table = { 1, 3, 0, 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .node_name = "refclk-dig",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static struct wiz_clk_mux_sel clk_mux_sel_10g[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * Mux value to be configured for each of the input clocks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * in the order populated in device tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) .table = { 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) .node_name = "pll0-refclk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .table = { 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .node_name = "pll1-refclk",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) .table = { 1, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) .node_name = "refclk-dig",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static const struct clk_div_table clk_div_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) { .val = 0, .div = 1, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) { .val = 1, .div = 2, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { .val = 2, .div = 4, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) { .val = 3, .div = 8, },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static struct wiz_clk_div_sel clk_div_sel[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .table = clk_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .node_name = "cmn-refclk-dig-div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) .table = clk_div_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) .node_name = "cmn-refclk1-dig-div",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) enum wiz_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) J721E_WIZ_16G,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) J721E_WIZ_10G,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define WIZ_TYPEC_DIR_DEBOUNCE_MIN 100 /* ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define WIZ_TYPEC_DIR_DEBOUNCE_MAX 1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct wiz {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) enum wiz_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct wiz_clk_mux_sel *clk_mux_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct wiz_clk_div_sel *clk_div_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned int clk_div_sel_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct regmap_field *por_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct regmap_field *phy_reset_n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) struct regmap_field *p_enable[WIZ_MAX_LANES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) struct regmap_field *p_align[WIZ_MAX_LANES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) struct regmap_field *p_raw_auto_start[WIZ_MAX_LANES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) struct regmap_field *p_standard_mode[WIZ_MAX_LANES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) struct regmap_field *pma_cmn_refclk_int_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) struct regmap_field *pma_cmn_refclk_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) struct regmap_field *pma_cmn_refclk_dig_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct regmap_field *pma_cmn_refclk1_dig_div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct regmap_field *typec_ln10_swap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u32 num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct platform_device *serdes_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) struct reset_controller_dev wiz_phy_reset_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) struct gpio_desc *gpio_typec_dir;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int typec_dir_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) u32 lane_phy_type[WIZ_MAX_LANES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static int wiz_reset(struct wiz *wiz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) ret = regmap_field_write(wiz->por_en, 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ret = regmap_field_write(wiz->por_en, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static int wiz_mode_select(struct wiz *wiz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) u32 num_lanes = wiz->num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) enum wiz_lane_standard_mode mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) for (i = 0; i < num_lanes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (wiz->lane_phy_type[i] == PHY_TYPE_DP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mode = LANE_MODE_GEN1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) mode = LANE_MODE_GEN4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ret = regmap_field_write(wiz->p_standard_mode[i], mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) static int wiz_init_raw_interface(struct wiz *wiz, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) u32 num_lanes = wiz->num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) for (i = 0; i < num_lanes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret = regmap_field_write(wiz->p_align[i], enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ret = regmap_field_write(wiz->p_raw_auto_start[i], enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int wiz_init(struct wiz *wiz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct device *dev = wiz->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) ret = wiz_reset(wiz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) dev_err(dev, "WIZ reset failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ret = wiz_mode_select(wiz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) dev_err(dev, "WIZ mode select failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) ret = wiz_init_raw_interface(wiz, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) dev_err(dev, "WIZ interface initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static int wiz_regfield_init(struct wiz *wiz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct wiz_clk_mux_sel *clk_mux_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct wiz_clk_div_sel *clk_div_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) struct regmap *regmap = wiz->regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int num_lanes = wiz->num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) struct device *dev = wiz->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) wiz->por_en = devm_regmap_field_alloc(dev, regmap, por_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (IS_ERR(wiz->por_en)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) dev_err(dev, "POR_EN reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return PTR_ERR(wiz->por_en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) wiz->phy_reset_n = devm_regmap_field_alloc(dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) phy_reset_n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (IS_ERR(wiz->phy_reset_n)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) dev_err(dev, "PHY_RESET_N reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return PTR_ERR(wiz->phy_reset_n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) wiz->pma_cmn_refclk_int_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_int_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (IS_ERR(wiz->pma_cmn_refclk_int_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) dev_err(dev, "PMA_CMN_REFCLK_INT_MODE reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return PTR_ERR(wiz->pma_cmn_refclk_int_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) wiz->pma_cmn_refclk_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (IS_ERR(wiz->pma_cmn_refclk_mode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) dev_err(dev, "PMA_CMN_REFCLK_MODE reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return PTR_ERR(wiz->pma_cmn_refclk_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) clk_div_sel = &wiz->clk_div_sel[CMN_REFCLK_DIG_DIV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) clk_div_sel->field = devm_regmap_field_alloc(dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pma_cmn_refclk_dig_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (IS_ERR(clk_div_sel->field)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) dev_err(dev, "PMA_CMN_REFCLK_DIG_DIV reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return PTR_ERR(clk_div_sel->field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (wiz->type == J721E_WIZ_16G) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) clk_div_sel = &wiz->clk_div_sel[CMN_REFCLK1_DIG_DIV];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) clk_div_sel->field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) devm_regmap_field_alloc(dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) pma_cmn_refclk1_dig_div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (IS_ERR(clk_div_sel->field)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) dev_err(dev, "PMA_CMN_REFCLK1_DIG_DIV reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) return PTR_ERR(clk_div_sel->field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) clk_mux_sel = &wiz->clk_mux_sel[PLL0_REFCLK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) clk_mux_sel->field = devm_regmap_field_alloc(dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) pll0_refclk_mux_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (IS_ERR(clk_mux_sel->field)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) dev_err(dev, "PLL0_REFCLK_SEL reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) return PTR_ERR(clk_mux_sel->field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) clk_mux_sel = &wiz->clk_mux_sel[PLL1_REFCLK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) clk_mux_sel->field = devm_regmap_field_alloc(dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) pll1_refclk_mux_sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (IS_ERR(clk_mux_sel->field)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) dev_err(dev, "PLL1_REFCLK_SEL reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return PTR_ERR(clk_mux_sel->field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) clk_mux_sel = &wiz->clk_mux_sel[REFCLK_DIG];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (wiz->type == J721E_WIZ_10G)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) clk_mux_sel->field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) devm_regmap_field_alloc(dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) refclk_dig_sel_10g);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) clk_mux_sel->field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) devm_regmap_field_alloc(dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) refclk_dig_sel_16g);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (IS_ERR(clk_mux_sel->field)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) dev_err(dev, "REFCLK_DIG_SEL reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return PTR_ERR(clk_mux_sel->field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) for (i = 0; i < num_lanes; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) wiz->p_enable[i] = devm_regmap_field_alloc(dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) p_enable[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (IS_ERR(wiz->p_enable[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) dev_err(dev, "P%d_ENABLE reg field init failed\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return PTR_ERR(wiz->p_enable[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) wiz->p_align[i] = devm_regmap_field_alloc(dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) p_align[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (IS_ERR(wiz->p_align[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) dev_err(dev, "P%d_ALIGN reg field init failed\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return PTR_ERR(wiz->p_align[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) wiz->p_raw_auto_start[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) devm_regmap_field_alloc(dev, regmap, p_raw_auto_start[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (IS_ERR(wiz->p_raw_auto_start[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) dev_err(dev, "P%d_RAW_AUTO_START reg field init fail\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return PTR_ERR(wiz->p_raw_auto_start[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) wiz->p_standard_mode[i] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) devm_regmap_field_alloc(dev, regmap, p_standard_mode[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (IS_ERR(wiz->p_standard_mode[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) dev_err(dev, "P%d_STANDARD_MODE reg field init fail\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return PTR_ERR(wiz->p_standard_mode[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) wiz->typec_ln10_swap = devm_regmap_field_alloc(dev, regmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) typec_ln10_swap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (IS_ERR(wiz->typec_ln10_swap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) dev_err(dev, "LN10_SWAP reg field init failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return PTR_ERR(wiz->typec_ln10_swap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) static u8 wiz_clk_mux_get_parent(struct clk_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct wiz_clk_mux *mux = to_wiz_clk_mux(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct regmap_field *field = mux->field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) regmap_field_read(field, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) return clk_mux_val_to_index(hw, mux->table, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static int wiz_clk_mux_set_parent(struct clk_hw *hw, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) struct wiz_clk_mux *mux = to_wiz_clk_mux(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct regmap_field *field = mux->field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) val = mux->table[index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return regmap_field_write(field, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) static const struct clk_ops wiz_clk_mux_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) .set_parent = wiz_clk_mux_set_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) .get_parent = wiz_clk_mux_get_parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static int wiz_mux_clk_register(struct wiz *wiz, struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct regmap_field *field, u32 *table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct device *dev = wiz->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct clk_init_data *init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) const char **parent_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) unsigned int num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct wiz_clk_mux *mux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) char clk_name[100];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (!mux)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) num_parents = of_clk_get_parent_count(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (num_parents < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) dev_err(dev, "SERDES clock must have parents\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) parent_names = devm_kzalloc(dev, (sizeof(char *) * num_parents),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (!parent_names)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) of_clk_parent_fill(node, parent_names, num_parents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) node->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) init = &mux->clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) init->ops = &wiz_clk_mux_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) init->flags = CLK_SET_RATE_NO_REPARENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) init->parent_names = parent_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) init->num_parents = num_parents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) init->name = clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) mux->field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) mux->table = table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) mux->hw.init = init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) clk = devm_clk_register(dev, &mux->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) dev_err(dev, "Failed to add clock provider: %s\n", clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static unsigned long wiz_clk_div_recalc_rate(struct clk_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) struct wiz_clk_divider *div = to_wiz_clk_div(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct regmap_field *field = div->field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) regmap_field_read(field, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) return divider_recalc_rate(hw, parent_rate, val, div->table, 0x0, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) static long wiz_clk_div_round_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) unsigned long *prate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct wiz_clk_divider *div = to_wiz_clk_div(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return divider_round_rate(hw, rate, prate, div->table, 2, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) static int wiz_clk_div_set_rate(struct clk_hw *hw, unsigned long rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) unsigned long parent_rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct wiz_clk_divider *div = to_wiz_clk_div(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct regmap_field *field = div->field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) val = divider_get_val(rate, parent_rate, div->table, 2, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) return regmap_field_write(field, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static const struct clk_ops wiz_clk_div_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) .recalc_rate = wiz_clk_div_recalc_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) .round_rate = wiz_clk_div_round_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) .set_rate = wiz_clk_div_set_rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static int wiz_div_clk_register(struct wiz *wiz, struct device_node *node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct regmap_field *field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) const struct clk_div_table *table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) struct device *dev = wiz->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct wiz_clk_divider *div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct clk_init_data *init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) const char **parent_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) char clk_name[100];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (!div)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) node->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) parent_names = devm_kzalloc(dev, sizeof(char *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (!parent_names)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) of_clk_parent_fill(node, parent_names, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) init = &div->clk_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) init->ops = &wiz_clk_div_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) init->flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) init->parent_names = parent_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) init->num_parents = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) init->name = clk_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) div->field = field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) div->table = table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) div->hw.init = init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) clk = devm_clk_register(dev, &div->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) dev_err(dev, "Failed to add clock provider: %s\n", clk_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static void wiz_clock_cleanup(struct wiz *wiz, struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) struct device_node *clk_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) clk_node = of_get_child_by_name(node, clk_mux_sel[i].node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) of_clk_del_provider(clk_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) of_node_put(clk_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) for (i = 0; i < wiz->clk_div_sel_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) clk_node = of_get_child_by_name(node, clk_div_sel[i].node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) of_clk_del_provider(clk_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) of_node_put(clk_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) static int wiz_clock_init(struct wiz *wiz, struct device_node *node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct wiz_clk_mux_sel *clk_mux_sel = wiz->clk_mux_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct device *dev = wiz->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct device_node *clk_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) const char *node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) unsigned long rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) struct clk *clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) clk = devm_clk_get(dev, "core_ref_clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) dev_err(dev, "core_ref_clk clock not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) ret = PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) rate = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) if (rate >= 100000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) regmap_field_write(wiz->pma_cmn_refclk_int_mode, 0x3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) clk = devm_clk_get(dev, "ext_ref_clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (IS_ERR(clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) dev_err(dev, "ext_ref_clk clock not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) ret = PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) rate = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (rate >= 100000000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) regmap_field_write(wiz->pma_cmn_refclk_mode, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) regmap_field_write(wiz->pma_cmn_refclk_mode, 0x2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) for (i = 0; i < WIZ_MUX_NUM_CLOCKS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) node_name = clk_mux_sel[i].node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) clk_node = of_get_child_by_name(node, node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (!clk_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) dev_err(dev, "Unable to get %s node\n", node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ret = wiz_mux_clk_register(wiz, clk_node, clk_mux_sel[i].field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) clk_mux_sel[i].table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) dev_err(dev, "Failed to register %s clock\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) of_node_put(clk_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) of_node_put(clk_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) for (i = 0; i < wiz->clk_div_sel_num; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) node_name = clk_div_sel[i].node_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) clk_node = of_get_child_by_name(node, node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (!clk_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) dev_err(dev, "Unable to get %s node\n", node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) ret = wiz_div_clk_register(wiz, clk_node, clk_div_sel[i].field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) clk_div_sel[i].table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) dev_err(dev, "Failed to register %s clock\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) node_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) of_node_put(clk_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) of_node_put(clk_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) wiz_clock_cleanup(wiz, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) static int wiz_phy_reset_assert(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct device *dev = rcdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) struct wiz *wiz = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (id == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) ret = regmap_field_write(wiz->phy_reset_n, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_DISABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) static int wiz_phy_reset_deassert(struct reset_controller_dev *rcdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) unsigned long id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) struct device *dev = rcdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) struct wiz *wiz = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /* if typec-dir gpio was specified, set LN10 SWAP bit based on that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (id == 0 && wiz->gpio_typec_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) if (wiz->typec_dir_delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) msleep_interruptible(wiz->typec_dir_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (gpiod_get_value_cansleep(wiz->gpio_typec_dir))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) regmap_field_write(wiz->typec_ln10_swap, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) regmap_field_write(wiz->typec_ln10_swap, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (id == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) ret = regmap_field_write(wiz->phy_reset_n, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (wiz->lane_phy_type[id - 1] == PHY_TYPE_DP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ret = regmap_field_write(wiz->p_enable[id - 1], P_ENABLE_FORCE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static const struct reset_control_ops wiz_phy_reset_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) .assert = wiz_phy_reset_assert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) .deassert = wiz_phy_reset_deassert,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) static const struct regmap_config wiz_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) .reg_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) .val_bits = 32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) .reg_stride = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) .fast_io = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) static const struct of_device_id wiz_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) .compatible = "ti,j721e-wiz-16g", .data = (void *)J721E_WIZ_16G
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) .compatible = "ti,j721e-wiz-10g", .data = (void *)J721E_WIZ_10G
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) MODULE_DEVICE_TABLE(of, wiz_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) static int wiz_get_lane_phy_types(struct device *dev, struct wiz *wiz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) struct device_node *serdes, *subnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) serdes = of_get_child_by_name(dev->of_node, "serdes");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (!serdes) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) dev_err(dev, "%s: Getting \"serdes\"-node failed\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) for_each_child_of_node(serdes, subnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) u32 reg, num_lanes = 1, phy_type = PHY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) ret = of_property_read_u32(subnode, "reg", ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) dev_err(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) "%s: Reading \"reg\" from \"%s\" failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) __func__, subnode->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) of_property_read_u32(subnode, "cdns,num-lanes", &num_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) of_property_read_u32(subnode, "cdns,phy-type", &phy_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) dev_dbg(dev, "%s: Lanes %u-%u have phy-type %u\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) reg, reg + num_lanes - 1, phy_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) for (i = reg; i < reg + num_lanes; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) wiz->lane_phy_type[i] = phy_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) static int wiz_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) struct reset_controller_dev *phy_reset_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct platform_device *serdes_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) struct device_node *child_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) struct regmap *regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) void __iomem *base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) struct wiz *wiz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) u32 num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) wiz = devm_kzalloc(dev, sizeof(*wiz), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (!wiz)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) wiz->type = (enum wiz_type)of_device_get_match_data(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) child_node = of_get_child_by_name(node, "serdes");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (!child_node) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) dev_err(dev, "Failed to get SERDES child DT node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) ret = of_address_to_resource(child_node, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) dev_err(dev, "Failed to get memory resource\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) goto err_addr_to_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) base = devm_ioremap(dev, res.start, resource_size(&res));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (!base) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) goto err_addr_to_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) regmap = devm_regmap_init_mmio(dev, base, &wiz_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (IS_ERR(regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) dev_err(dev, "Failed to initialize regmap\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) ret = PTR_ERR(regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) goto err_addr_to_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ret = of_property_read_u32(node, "num-lanes", &num_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) dev_err(dev, "Failed to read num-lanes property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) goto err_addr_to_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (num_lanes > WIZ_MAX_LANES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) dev_err(dev, "Cannot support %d lanes\n", num_lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) goto err_addr_to_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) wiz->gpio_typec_dir = devm_gpiod_get_optional(dev, "typec-dir",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) GPIOD_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (IS_ERR(wiz->gpio_typec_dir)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ret = PTR_ERR(wiz->gpio_typec_dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (ret != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) dev_err(dev, "Failed to request typec-dir gpio: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) goto err_addr_to_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) if (wiz->gpio_typec_dir) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ret = of_property_read_u32(node, "typec-dir-debounce-ms",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) &wiz->typec_dir_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (ret && ret != -EINVAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) dev_err(dev, "Invalid typec-dir-debounce property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) goto err_addr_to_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) /* use min. debounce from Type-C spec if not provided in DT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) if (ret == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) wiz->typec_dir_delay = WIZ_TYPEC_DIR_DEBOUNCE_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) if (wiz->typec_dir_delay < WIZ_TYPEC_DIR_DEBOUNCE_MIN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) wiz->typec_dir_delay > WIZ_TYPEC_DIR_DEBOUNCE_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) dev_err(dev, "Invalid typec-dir-debounce property\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) goto err_addr_to_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) ret = wiz_get_lane_phy_types(dev, wiz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) wiz->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) wiz->regmap = regmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) wiz->num_lanes = num_lanes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (wiz->type == J721E_WIZ_10G)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) wiz->clk_mux_sel = clk_mux_sel_10g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) wiz->clk_mux_sel = clk_mux_sel_16g;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) wiz->clk_div_sel = clk_div_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (wiz->type == J721E_WIZ_10G)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) wiz->clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_10G;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) wiz->clk_div_sel_num = WIZ_DIV_NUM_CLOCKS_16G;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) platform_set_drvdata(pdev, wiz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ret = wiz_regfield_init(wiz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) dev_err(dev, "Failed to initialize regfields\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) goto err_addr_to_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) phy_reset_dev = &wiz->wiz_phy_reset_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) phy_reset_dev->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) phy_reset_dev->ops = &wiz_phy_reset_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) phy_reset_dev->owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) phy_reset_dev->of_node = node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /* Reset for each of the lane and one for the entire SERDES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) phy_reset_dev->nr_resets = num_lanes + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) ret = devm_reset_controller_register(dev, phy_reset_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) dev_warn(dev, "Failed to register reset controller\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) goto err_addr_to_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) ret = pm_runtime_get_sync(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) dev_err(dev, "pm_runtime_get_sync failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) goto err_get_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) ret = wiz_clock_init(wiz, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) dev_warn(dev, "Failed to initialize clocks\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) goto err_get_sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) ret = wiz_init(wiz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dev_err(dev, "WIZ initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) goto err_wiz_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) serdes_pdev = of_platform_device_create(child_node, NULL, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (!serdes_pdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) dev_WARN(dev, "Unable to create SERDES platform device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) goto err_wiz_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) wiz->serdes_pdev = serdes_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) of_node_put(child_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) err_wiz_init:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) wiz_clock_cleanup(wiz, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) err_get_sync:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) pm_runtime_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) err_addr_to_resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) of_node_put(child_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) static int wiz_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) struct platform_device *serdes_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct wiz *wiz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) wiz = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) serdes_pdev = wiz->serdes_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) of_platform_device_destroy(&serdes_pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) wiz_clock_cleanup(wiz, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) pm_runtime_put(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) pm_runtime_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) static struct platform_driver wiz_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) .probe = wiz_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) .remove = wiz_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) .name = "wiz",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) .of_match_table = wiz_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) module_platform_driver(wiz_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) MODULE_AUTHOR("Texas Instruments Inc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) MODULE_DESCRIPTION("TI J721E WIZ driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) MODULE_LICENSE("GPL v2");