162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2004-2016 Synopsys, Inc.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/kernel.h>
762306a36Sopenharmony_ci#include <linux/module.h>
862306a36Sopenharmony_ci#include <linux/of_device.h>
962306a36Sopenharmony_ci#include <linux/usb/of.h>
1062306a36Sopenharmony_ci#include <linux/pci_ids.h>
1162306a36Sopenharmony_ci#include <linux/pci.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include "core.h"
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#define PCI_PRODUCT_ID_HAPS_HSOTG	0xabc0
1662306a36Sopenharmony_ci#define PCI_DEVICE_ID_LOONGSON_DWC2	0x7a04
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistatic void dwc2_set_bcm_params(struct dwc2_hsotg *hsotg)
1962306a36Sopenharmony_ci{
2062306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci	p->host_rx_fifo_size = 774;
2362306a36Sopenharmony_ci	p->max_transfer_size = 65535;
2462306a36Sopenharmony_ci	p->max_packet_count = 511;
2562306a36Sopenharmony_ci	p->ahbcfg = 0x10;
2662306a36Sopenharmony_ci}
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cistatic void dwc2_set_his_params(struct dwc2_hsotg *hsotg)
2962306a36Sopenharmony_ci{
3062306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
3362306a36Sopenharmony_ci	p->otg_caps.srp_support = false;
3462306a36Sopenharmony_ci	p->speed = DWC2_SPEED_PARAM_HIGH;
3562306a36Sopenharmony_ci	p->host_rx_fifo_size = 512;
3662306a36Sopenharmony_ci	p->host_nperio_tx_fifo_size = 512;
3762306a36Sopenharmony_ci	p->host_perio_tx_fifo_size = 512;
3862306a36Sopenharmony_ci	p->max_transfer_size = 65535;
3962306a36Sopenharmony_ci	p->max_packet_count = 511;
4062306a36Sopenharmony_ci	p->host_channels = 16;
4162306a36Sopenharmony_ci	p->phy_type = DWC2_PHY_TYPE_PARAM_UTMI;
4262306a36Sopenharmony_ci	p->phy_utmi_width = 8;
4362306a36Sopenharmony_ci	p->i2c_enable = false;
4462306a36Sopenharmony_ci	p->reload_ctl = false;
4562306a36Sopenharmony_ci	p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
4662306a36Sopenharmony_ci		GAHBCFG_HBSTLEN_SHIFT;
4762306a36Sopenharmony_ci	p->change_speed_quirk = true;
4862306a36Sopenharmony_ci	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cistatic void dwc2_set_jz4775_params(struct dwc2_hsotg *hsotg)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
5662306a36Sopenharmony_ci	p->speed = DWC2_SPEED_PARAM_HIGH;
5762306a36Sopenharmony_ci	p->phy_type = DWC2_PHY_TYPE_PARAM_UTMI;
5862306a36Sopenharmony_ci	p->phy_utmi_width = 16;
5962306a36Sopenharmony_ci	p->activate_ingenic_overcurrent_detection =
6062306a36Sopenharmony_ci		!device_property_read_bool(hsotg->dev, "disable-over-current");
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic void dwc2_set_loongson_params(struct dwc2_hsotg *hsotg)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	p->phy_utmi_width = 8;
6862306a36Sopenharmony_ci	p->power_down = DWC2_POWER_DOWN_PARAM_PARTIAL;
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistatic void dwc2_set_x1600_params(struct dwc2_hsotg *hsotg)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
7662306a36Sopenharmony_ci	p->speed = DWC2_SPEED_PARAM_HIGH;
7762306a36Sopenharmony_ci	p->host_channels = 16;
7862306a36Sopenharmony_ci	p->phy_type = DWC2_PHY_TYPE_PARAM_UTMI;
7962306a36Sopenharmony_ci	p->phy_utmi_width = 16;
8062306a36Sopenharmony_ci	p->activate_ingenic_overcurrent_detection =
8162306a36Sopenharmony_ci		!device_property_read_bool(hsotg->dev, "disable-over-current");
8262306a36Sopenharmony_ci}
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_cistatic void dwc2_set_x2000_params(struct dwc2_hsotg *hsotg)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
8962306a36Sopenharmony_ci	p->speed = DWC2_SPEED_PARAM_HIGH;
9062306a36Sopenharmony_ci	p->host_rx_fifo_size = 1024;
9162306a36Sopenharmony_ci	p->host_nperio_tx_fifo_size = 1024;
9262306a36Sopenharmony_ci	p->host_perio_tx_fifo_size = 1024;
9362306a36Sopenharmony_ci	p->host_channels = 16;
9462306a36Sopenharmony_ci	p->phy_type = DWC2_PHY_TYPE_PARAM_UTMI;
9562306a36Sopenharmony_ci	p->phy_utmi_width = 16;
9662306a36Sopenharmony_ci	p->activate_ingenic_overcurrent_detection =
9762306a36Sopenharmony_ci		!device_property_read_bool(hsotg->dev, "disable-over-current");
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_cistatic void dwc2_set_s3c6400_params(struct dwc2_hsotg *hsotg)
10162306a36Sopenharmony_ci{
10262306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
10562306a36Sopenharmony_ci	p->no_clock_gating = true;
10662306a36Sopenharmony_ci	p->phy_utmi_width = 8;
10762306a36Sopenharmony_ci}
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_cistatic void dwc2_set_socfpga_agilex_params(struct dwc2_hsotg *hsotg)
11062306a36Sopenharmony_ci{
11162306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
11462306a36Sopenharmony_ci	p->no_clock_gating = true;
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic void dwc2_set_rk_params(struct dwc2_hsotg *hsotg)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
12262306a36Sopenharmony_ci	p->otg_caps.srp_support = false;
12362306a36Sopenharmony_ci	p->host_rx_fifo_size = 525;
12462306a36Sopenharmony_ci	p->host_nperio_tx_fifo_size = 128;
12562306a36Sopenharmony_ci	p->host_perio_tx_fifo_size = 256;
12662306a36Sopenharmony_ci	p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
12762306a36Sopenharmony_ci		GAHBCFG_HBSTLEN_SHIFT;
12862306a36Sopenharmony_ci	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
12962306a36Sopenharmony_ci	p->lpm = false;
13062306a36Sopenharmony_ci	p->lpm_clock_gating = false;
13162306a36Sopenharmony_ci	p->besl = false;
13262306a36Sopenharmony_ci	p->hird_threshold_en = false;
13362306a36Sopenharmony_ci}
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic void dwc2_set_ltq_params(struct dwc2_hsotg *hsotg)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
14062306a36Sopenharmony_ci	p->otg_caps.srp_support = false;
14162306a36Sopenharmony_ci	p->host_rx_fifo_size = 288;
14262306a36Sopenharmony_ci	p->host_nperio_tx_fifo_size = 128;
14362306a36Sopenharmony_ci	p->host_perio_tx_fifo_size = 96;
14462306a36Sopenharmony_ci	p->max_transfer_size = 65535;
14562306a36Sopenharmony_ci	p->max_packet_count = 511;
14662306a36Sopenharmony_ci	p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
14762306a36Sopenharmony_ci		GAHBCFG_HBSTLEN_SHIFT;
14862306a36Sopenharmony_ci}
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_cistatic void dwc2_set_amlogic_params(struct dwc2_hsotg *hsotg)
15162306a36Sopenharmony_ci{
15262306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
15562306a36Sopenharmony_ci	p->otg_caps.srp_support = false;
15662306a36Sopenharmony_ci	p->speed = DWC2_SPEED_PARAM_HIGH;
15762306a36Sopenharmony_ci	p->host_rx_fifo_size = 512;
15862306a36Sopenharmony_ci	p->host_nperio_tx_fifo_size = 500;
15962306a36Sopenharmony_ci	p->host_perio_tx_fifo_size = 500;
16062306a36Sopenharmony_ci	p->host_channels = 16;
16162306a36Sopenharmony_ci	p->phy_type = DWC2_PHY_TYPE_PARAM_UTMI;
16262306a36Sopenharmony_ci	p->ahbcfg = GAHBCFG_HBSTLEN_INCR8 <<
16362306a36Sopenharmony_ci		GAHBCFG_HBSTLEN_SHIFT;
16462306a36Sopenharmony_ci	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
16562306a36Sopenharmony_ci}
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_cistatic void dwc2_set_amlogic_g12a_params(struct dwc2_hsotg *hsotg)
16862306a36Sopenharmony_ci{
16962306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	p->lpm = false;
17262306a36Sopenharmony_ci	p->lpm_clock_gating = false;
17362306a36Sopenharmony_ci	p->besl = false;
17462306a36Sopenharmony_ci	p->hird_threshold_en = false;
17562306a36Sopenharmony_ci}
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_cistatic void dwc2_set_amlogic_a1_params(struct dwc2_hsotg *hsotg)
17862306a36Sopenharmony_ci{
17962306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
18262306a36Sopenharmony_ci	p->otg_caps.srp_support = false;
18362306a36Sopenharmony_ci	p->speed = DWC2_SPEED_PARAM_HIGH;
18462306a36Sopenharmony_ci	p->host_rx_fifo_size = 192;
18562306a36Sopenharmony_ci	p->host_nperio_tx_fifo_size = 128;
18662306a36Sopenharmony_ci	p->host_perio_tx_fifo_size = 128;
18762306a36Sopenharmony_ci	p->phy_type = DWC2_PHY_TYPE_PARAM_UTMI;
18862306a36Sopenharmony_ci	p->phy_utmi_width = 8;
18962306a36Sopenharmony_ci	p->ahbcfg = GAHBCFG_HBSTLEN_INCR8 << GAHBCFG_HBSTLEN_SHIFT;
19062306a36Sopenharmony_ci	p->lpm = false;
19162306a36Sopenharmony_ci	p->lpm_clock_gating = false;
19262306a36Sopenharmony_ci	p->besl = false;
19362306a36Sopenharmony_ci	p->hird_threshold_en = false;
19462306a36Sopenharmony_ci}
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_cistatic void dwc2_set_amcc_params(struct dwc2_hsotg *hsotg)
19762306a36Sopenharmony_ci{
19862306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 << GAHBCFG_HBSTLEN_SHIFT;
20162306a36Sopenharmony_ci}
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_cistatic void dwc2_set_stm32f4x9_fsotg_params(struct dwc2_hsotg *hsotg)
20462306a36Sopenharmony_ci{
20562306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
20862306a36Sopenharmony_ci	p->otg_caps.srp_support = false;
20962306a36Sopenharmony_ci	p->speed = DWC2_SPEED_PARAM_FULL;
21062306a36Sopenharmony_ci	p->host_rx_fifo_size = 128;
21162306a36Sopenharmony_ci	p->host_nperio_tx_fifo_size = 96;
21262306a36Sopenharmony_ci	p->host_perio_tx_fifo_size = 96;
21362306a36Sopenharmony_ci	p->max_packet_count = 256;
21462306a36Sopenharmony_ci	p->phy_type = DWC2_PHY_TYPE_PARAM_FS;
21562306a36Sopenharmony_ci	p->i2c_enable = false;
21662306a36Sopenharmony_ci	p->activate_stm_fs_transceiver = true;
21762306a36Sopenharmony_ci}
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cistatic void dwc2_set_stm32f7_hsotg_params(struct dwc2_hsotg *hsotg)
22062306a36Sopenharmony_ci{
22162306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	p->host_rx_fifo_size = 622;
22462306a36Sopenharmony_ci	p->host_nperio_tx_fifo_size = 128;
22562306a36Sopenharmony_ci	p->host_perio_tx_fifo_size = 256;
22662306a36Sopenharmony_ci}
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_cistatic void dwc2_set_stm32mp15_fsotg_params(struct dwc2_hsotg *hsotg)
22962306a36Sopenharmony_ci{
23062306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
23362306a36Sopenharmony_ci	p->otg_caps.srp_support = false;
23462306a36Sopenharmony_ci	p->otg_caps.otg_rev = 0x200;
23562306a36Sopenharmony_ci	p->speed = DWC2_SPEED_PARAM_FULL;
23662306a36Sopenharmony_ci	p->host_rx_fifo_size = 128;
23762306a36Sopenharmony_ci	p->host_nperio_tx_fifo_size = 96;
23862306a36Sopenharmony_ci	p->host_perio_tx_fifo_size = 96;
23962306a36Sopenharmony_ci	p->max_packet_count = 256;
24062306a36Sopenharmony_ci	p->phy_type = DWC2_PHY_TYPE_PARAM_FS;
24162306a36Sopenharmony_ci	p->i2c_enable = false;
24262306a36Sopenharmony_ci	p->activate_stm_fs_transceiver = true;
24362306a36Sopenharmony_ci	p->activate_stm_id_vb_detection = true;
24462306a36Sopenharmony_ci	p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 << GAHBCFG_HBSTLEN_SHIFT;
24562306a36Sopenharmony_ci	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
24662306a36Sopenharmony_ci	p->host_support_fs_ls_low_power = true;
24762306a36Sopenharmony_ci	p->host_ls_low_power_phy_clk = true;
24862306a36Sopenharmony_ci}
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_cistatic void dwc2_set_stm32mp15_hsotg_params(struct dwc2_hsotg *hsotg)
25162306a36Sopenharmony_ci{
25262306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci	p->otg_caps.hnp_support = false;
25562306a36Sopenharmony_ci	p->otg_caps.srp_support = false;
25662306a36Sopenharmony_ci	p->otg_caps.otg_rev = 0x200;
25762306a36Sopenharmony_ci	p->activate_stm_id_vb_detection = !device_property_read_bool(hsotg->dev, "usb-role-switch");
25862306a36Sopenharmony_ci	p->host_rx_fifo_size = 440;
25962306a36Sopenharmony_ci	p->host_nperio_tx_fifo_size = 256;
26062306a36Sopenharmony_ci	p->host_perio_tx_fifo_size = 256;
26162306a36Sopenharmony_ci	p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 << GAHBCFG_HBSTLEN_SHIFT;
26262306a36Sopenharmony_ci	p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
26362306a36Sopenharmony_ci	p->lpm = false;
26462306a36Sopenharmony_ci	p->lpm_clock_gating = false;
26562306a36Sopenharmony_ci	p->besl = false;
26662306a36Sopenharmony_ci	p->hird_threshold_en = false;
26762306a36Sopenharmony_ci}
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ciconst struct of_device_id dwc2_of_match_table[] = {
27062306a36Sopenharmony_ci	{ .compatible = "brcm,bcm2835-usb", .data = dwc2_set_bcm_params },
27162306a36Sopenharmony_ci	{ .compatible = "hisilicon,hi6220-usb", .data = dwc2_set_his_params },
27262306a36Sopenharmony_ci	{ .compatible = "ingenic,jz4775-otg", .data = dwc2_set_jz4775_params },
27362306a36Sopenharmony_ci	{ .compatible = "ingenic,jz4780-otg", .data = dwc2_set_jz4775_params },
27462306a36Sopenharmony_ci	{ .compatible = "ingenic,x1000-otg", .data = dwc2_set_jz4775_params },
27562306a36Sopenharmony_ci	{ .compatible = "ingenic,x1600-otg", .data = dwc2_set_x1600_params },
27662306a36Sopenharmony_ci	{ .compatible = "ingenic,x1700-otg", .data = dwc2_set_x1600_params },
27762306a36Sopenharmony_ci	{ .compatible = "ingenic,x1830-otg", .data = dwc2_set_x1600_params },
27862306a36Sopenharmony_ci	{ .compatible = "ingenic,x2000-otg", .data = dwc2_set_x2000_params },
27962306a36Sopenharmony_ci	{ .compatible = "rockchip,rk3066-usb", .data = dwc2_set_rk_params },
28062306a36Sopenharmony_ci	{ .compatible = "lantiq,arx100-usb", .data = dwc2_set_ltq_params },
28162306a36Sopenharmony_ci	{ .compatible = "lantiq,xrx200-usb", .data = dwc2_set_ltq_params },
28262306a36Sopenharmony_ci	{ .compatible = "snps,dwc2" },
28362306a36Sopenharmony_ci	{ .compatible = "samsung,s3c6400-hsotg",
28462306a36Sopenharmony_ci	  .data = dwc2_set_s3c6400_params },
28562306a36Sopenharmony_ci	{ .compatible = "amlogic,meson8-usb",
28662306a36Sopenharmony_ci	  .data = dwc2_set_amlogic_params },
28762306a36Sopenharmony_ci	{ .compatible = "amlogic,meson8b-usb",
28862306a36Sopenharmony_ci	  .data = dwc2_set_amlogic_params },
28962306a36Sopenharmony_ci	{ .compatible = "amlogic,meson-gxbb-usb",
29062306a36Sopenharmony_ci	  .data = dwc2_set_amlogic_params },
29162306a36Sopenharmony_ci	{ .compatible = "amlogic,meson-g12a-usb",
29262306a36Sopenharmony_ci	  .data = dwc2_set_amlogic_g12a_params },
29362306a36Sopenharmony_ci	{ .compatible = "amlogic,meson-a1-usb",
29462306a36Sopenharmony_ci	  .data = dwc2_set_amlogic_a1_params },
29562306a36Sopenharmony_ci	{ .compatible = "amcc,dwc-otg", .data = dwc2_set_amcc_params },
29662306a36Sopenharmony_ci	{ .compatible = "apm,apm82181-dwc-otg", .data = dwc2_set_amcc_params },
29762306a36Sopenharmony_ci	{ .compatible = "st,stm32f4x9-fsotg",
29862306a36Sopenharmony_ci	  .data = dwc2_set_stm32f4x9_fsotg_params },
29962306a36Sopenharmony_ci	{ .compatible = "st,stm32f4x9-hsotg" },
30062306a36Sopenharmony_ci	{ .compatible = "st,stm32f7-hsotg",
30162306a36Sopenharmony_ci	  .data = dwc2_set_stm32f7_hsotg_params },
30262306a36Sopenharmony_ci	{ .compatible = "st,stm32mp15-fsotg",
30362306a36Sopenharmony_ci	  .data = dwc2_set_stm32mp15_fsotg_params },
30462306a36Sopenharmony_ci	{ .compatible = "st,stm32mp15-hsotg",
30562306a36Sopenharmony_ci	  .data = dwc2_set_stm32mp15_hsotg_params },
30662306a36Sopenharmony_ci	{ .compatible = "intel,socfpga-agilex-hsotg",
30762306a36Sopenharmony_ci	  .data = dwc2_set_socfpga_agilex_params },
30862306a36Sopenharmony_ci	{},
30962306a36Sopenharmony_ci};
31062306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, dwc2_of_match_table);
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ciconst struct acpi_device_id dwc2_acpi_match[] = {
31362306a36Sopenharmony_ci	{ "BCM2848", (kernel_ulong_t)dwc2_set_bcm_params },
31462306a36Sopenharmony_ci	{ },
31562306a36Sopenharmony_ci};
31662306a36Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, dwc2_acpi_match);
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ciconst struct pci_device_id dwc2_pci_ids[] = {
31962306a36Sopenharmony_ci	{
32062306a36Sopenharmony_ci		PCI_DEVICE(PCI_VENDOR_ID_SYNOPSYS, PCI_PRODUCT_ID_HAPS_HSOTG),
32162306a36Sopenharmony_ci	},
32262306a36Sopenharmony_ci	{
32362306a36Sopenharmony_ci		PCI_DEVICE(PCI_VENDOR_ID_STMICRO,
32462306a36Sopenharmony_ci			   PCI_DEVICE_ID_STMICRO_USB_OTG),
32562306a36Sopenharmony_ci	},
32662306a36Sopenharmony_ci	{
32762306a36Sopenharmony_ci		PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, PCI_DEVICE_ID_LOONGSON_DWC2),
32862306a36Sopenharmony_ci		.driver_data = (unsigned long)dwc2_set_loongson_params,
32962306a36Sopenharmony_ci	},
33062306a36Sopenharmony_ci	{ /* end: all zeroes */ }
33162306a36Sopenharmony_ci};
33262306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci, dwc2_pci_ids);
33362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dwc2_pci_ids);
33462306a36Sopenharmony_ci
33562306a36Sopenharmony_cistatic void dwc2_set_param_otg_cap(struct dwc2_hsotg *hsotg)
33662306a36Sopenharmony_ci{
33762306a36Sopenharmony_ci	switch (hsotg->hw_params.op_mode) {
33862306a36Sopenharmony_ci	case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
33962306a36Sopenharmony_ci		hsotg->params.otg_caps.hnp_support = true;
34062306a36Sopenharmony_ci		hsotg->params.otg_caps.srp_support = true;
34162306a36Sopenharmony_ci		break;
34262306a36Sopenharmony_ci	case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
34362306a36Sopenharmony_ci	case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
34462306a36Sopenharmony_ci	case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
34562306a36Sopenharmony_ci		hsotg->params.otg_caps.hnp_support = false;
34662306a36Sopenharmony_ci		hsotg->params.otg_caps.srp_support = true;
34762306a36Sopenharmony_ci		break;
34862306a36Sopenharmony_ci	default:
34962306a36Sopenharmony_ci		hsotg->params.otg_caps.hnp_support = false;
35062306a36Sopenharmony_ci		hsotg->params.otg_caps.srp_support = false;
35162306a36Sopenharmony_ci		break;
35262306a36Sopenharmony_ci	}
35362306a36Sopenharmony_ci}
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_cistatic void dwc2_set_param_phy_type(struct dwc2_hsotg *hsotg)
35662306a36Sopenharmony_ci{
35762306a36Sopenharmony_ci	int val;
35862306a36Sopenharmony_ci	u32 hs_phy_type = hsotg->hw_params.hs_phy_type;
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	val = DWC2_PHY_TYPE_PARAM_FS;
36162306a36Sopenharmony_ci	if (hs_phy_type != GHWCFG2_HS_PHY_TYPE_NOT_SUPPORTED) {
36262306a36Sopenharmony_ci		if (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI ||
36362306a36Sopenharmony_ci		    hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI)
36462306a36Sopenharmony_ci			val = DWC2_PHY_TYPE_PARAM_UTMI;
36562306a36Sopenharmony_ci		else
36662306a36Sopenharmony_ci			val = DWC2_PHY_TYPE_PARAM_ULPI;
36762306a36Sopenharmony_ci	}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	if (dwc2_is_fs_iot(hsotg))
37062306a36Sopenharmony_ci		hsotg->params.phy_type = DWC2_PHY_TYPE_PARAM_FS;
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	hsotg->params.phy_type = val;
37362306a36Sopenharmony_ci}
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_cistatic void dwc2_set_param_speed(struct dwc2_hsotg *hsotg)
37662306a36Sopenharmony_ci{
37762306a36Sopenharmony_ci	int val;
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci	val = hsotg->params.phy_type == DWC2_PHY_TYPE_PARAM_FS ?
38062306a36Sopenharmony_ci		DWC2_SPEED_PARAM_FULL : DWC2_SPEED_PARAM_HIGH;
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci	if (dwc2_is_fs_iot(hsotg))
38362306a36Sopenharmony_ci		val = DWC2_SPEED_PARAM_FULL;
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci	if (dwc2_is_hs_iot(hsotg))
38662306a36Sopenharmony_ci		val = DWC2_SPEED_PARAM_HIGH;
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	hsotg->params.speed = val;
38962306a36Sopenharmony_ci}
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_cistatic void dwc2_set_param_phy_utmi_width(struct dwc2_hsotg *hsotg)
39262306a36Sopenharmony_ci{
39362306a36Sopenharmony_ci	int val;
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci	val = (hsotg->hw_params.utmi_phy_data_width ==
39662306a36Sopenharmony_ci	       GHWCFG4_UTMI_PHY_DATA_WIDTH_8) ? 8 : 16;
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	if (hsotg->phy) {
39962306a36Sopenharmony_ci		/*
40062306a36Sopenharmony_ci		 * If using the generic PHY framework, check if the PHY bus
40162306a36Sopenharmony_ci		 * width is 8-bit and set the phyif appropriately.
40262306a36Sopenharmony_ci		 */
40362306a36Sopenharmony_ci		if (phy_get_bus_width(hsotg->phy) == 8)
40462306a36Sopenharmony_ci			val = 8;
40562306a36Sopenharmony_ci	}
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci	hsotg->params.phy_utmi_width = val;
40862306a36Sopenharmony_ci}
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_cistatic void dwc2_set_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
41162306a36Sopenharmony_ci{
41262306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
41362306a36Sopenharmony_ci	int depth_average;
41462306a36Sopenharmony_ci	int fifo_count;
41562306a36Sopenharmony_ci	int i;
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci	fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci	memset(p->g_tx_fifo_size, 0, sizeof(p->g_tx_fifo_size));
42062306a36Sopenharmony_ci	depth_average = dwc2_hsotg_tx_fifo_average_depth(hsotg);
42162306a36Sopenharmony_ci	for (i = 1; i <= fifo_count; i++)
42262306a36Sopenharmony_ci		p->g_tx_fifo_size[i] = depth_average;
42362306a36Sopenharmony_ci}
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_cistatic void dwc2_set_param_power_down(struct dwc2_hsotg *hsotg)
42662306a36Sopenharmony_ci{
42762306a36Sopenharmony_ci	int val;
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ci	if (hsotg->hw_params.hibernation)
43062306a36Sopenharmony_ci		val = DWC2_POWER_DOWN_PARAM_HIBERNATION;
43162306a36Sopenharmony_ci	else if (hsotg->hw_params.power_optimized)
43262306a36Sopenharmony_ci		val = DWC2_POWER_DOWN_PARAM_PARTIAL;
43362306a36Sopenharmony_ci	else
43462306a36Sopenharmony_ci		val = DWC2_POWER_DOWN_PARAM_NONE;
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	hsotg->params.power_down = val;
43762306a36Sopenharmony_ci}
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_cistatic void dwc2_set_param_lpm(struct dwc2_hsotg *hsotg)
44062306a36Sopenharmony_ci{
44162306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	p->lpm = hsotg->hw_params.lpm_mode;
44462306a36Sopenharmony_ci	if (p->lpm) {
44562306a36Sopenharmony_ci		p->lpm_clock_gating = true;
44662306a36Sopenharmony_ci		p->besl = true;
44762306a36Sopenharmony_ci		p->hird_threshold_en = true;
44862306a36Sopenharmony_ci		p->hird_threshold = 4;
44962306a36Sopenharmony_ci	} else {
45062306a36Sopenharmony_ci		p->lpm_clock_gating = false;
45162306a36Sopenharmony_ci		p->besl = false;
45262306a36Sopenharmony_ci		p->hird_threshold_en = false;
45362306a36Sopenharmony_ci	}
45462306a36Sopenharmony_ci}
45562306a36Sopenharmony_ci
45662306a36Sopenharmony_ci/**
45762306a36Sopenharmony_ci * dwc2_set_default_params() - Set all core parameters to their
45862306a36Sopenharmony_ci * auto-detected default values.
45962306a36Sopenharmony_ci *
46062306a36Sopenharmony_ci * @hsotg: Programming view of the DWC_otg controller
46162306a36Sopenharmony_ci *
46262306a36Sopenharmony_ci */
46362306a36Sopenharmony_cistatic void dwc2_set_default_params(struct dwc2_hsotg *hsotg)
46462306a36Sopenharmony_ci{
46562306a36Sopenharmony_ci	struct dwc2_hw_params *hw = &hsotg->hw_params;
46662306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
46762306a36Sopenharmony_ci	bool dma_capable = !(hw->arch == GHWCFG2_SLAVE_ONLY_ARCH);
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	dwc2_set_param_otg_cap(hsotg);
47062306a36Sopenharmony_ci	dwc2_set_param_phy_type(hsotg);
47162306a36Sopenharmony_ci	dwc2_set_param_speed(hsotg);
47262306a36Sopenharmony_ci	dwc2_set_param_phy_utmi_width(hsotg);
47362306a36Sopenharmony_ci	dwc2_set_param_power_down(hsotg);
47462306a36Sopenharmony_ci	dwc2_set_param_lpm(hsotg);
47562306a36Sopenharmony_ci	p->phy_ulpi_ddr = false;
47662306a36Sopenharmony_ci	p->phy_ulpi_ext_vbus = false;
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci	p->enable_dynamic_fifo = hw->enable_dynamic_fifo;
47962306a36Sopenharmony_ci	p->en_multiple_tx_fifo = hw->en_multiple_tx_fifo;
48062306a36Sopenharmony_ci	p->i2c_enable = hw->i2c_enable;
48162306a36Sopenharmony_ci	p->acg_enable = hw->acg_enable;
48262306a36Sopenharmony_ci	p->ulpi_fs_ls = false;
48362306a36Sopenharmony_ci	p->ts_dline = false;
48462306a36Sopenharmony_ci	p->reload_ctl = (hw->snpsid >= DWC2_CORE_REV_2_92a);
48562306a36Sopenharmony_ci	p->uframe_sched = true;
48662306a36Sopenharmony_ci	p->external_id_pin_ctl = false;
48762306a36Sopenharmony_ci	p->ipg_isoc_en = false;
48862306a36Sopenharmony_ci	p->service_interval = false;
48962306a36Sopenharmony_ci	p->max_packet_count = hw->max_packet_count;
49062306a36Sopenharmony_ci	p->max_transfer_size = hw->max_transfer_size;
49162306a36Sopenharmony_ci	p->ahbcfg = GAHBCFG_HBSTLEN_INCR << GAHBCFG_HBSTLEN_SHIFT;
49262306a36Sopenharmony_ci	p->ref_clk_per = 33333;
49362306a36Sopenharmony_ci	p->sof_cnt_wkup_alert = 100;
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci	if ((hsotg->dr_mode == USB_DR_MODE_HOST) ||
49662306a36Sopenharmony_ci	    (hsotg->dr_mode == USB_DR_MODE_OTG)) {
49762306a36Sopenharmony_ci		p->host_dma = dma_capable;
49862306a36Sopenharmony_ci		p->dma_desc_enable = false;
49962306a36Sopenharmony_ci		p->dma_desc_fs_enable = false;
50062306a36Sopenharmony_ci		p->host_support_fs_ls_low_power = false;
50162306a36Sopenharmony_ci		p->host_ls_low_power_phy_clk = false;
50262306a36Sopenharmony_ci		p->host_channels = hw->host_channels;
50362306a36Sopenharmony_ci		p->host_rx_fifo_size = hw->rx_fifo_size;
50462306a36Sopenharmony_ci		p->host_nperio_tx_fifo_size = hw->host_nperio_tx_fifo_size;
50562306a36Sopenharmony_ci		p->host_perio_tx_fifo_size = hw->host_perio_tx_fifo_size;
50662306a36Sopenharmony_ci	}
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci	if ((hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) ||
50962306a36Sopenharmony_ci	    (hsotg->dr_mode == USB_DR_MODE_OTG)) {
51062306a36Sopenharmony_ci		p->g_dma = dma_capable;
51162306a36Sopenharmony_ci		p->g_dma_desc = hw->dma_desc_enable;
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci		/*
51462306a36Sopenharmony_ci		 * The values for g_rx_fifo_size (2048) and
51562306a36Sopenharmony_ci		 * g_np_tx_fifo_size (1024) come from the legacy s3c
51662306a36Sopenharmony_ci		 * gadget driver. These defaults have been hard-coded
51762306a36Sopenharmony_ci		 * for some time so many platforms depend on these
51862306a36Sopenharmony_ci		 * values. Leave them as defaults for now and only
51962306a36Sopenharmony_ci		 * auto-detect if the hardware does not support the
52062306a36Sopenharmony_ci		 * default.
52162306a36Sopenharmony_ci		 */
52262306a36Sopenharmony_ci		p->g_rx_fifo_size = 2048;
52362306a36Sopenharmony_ci		p->g_np_tx_fifo_size = 1024;
52462306a36Sopenharmony_ci		dwc2_set_param_tx_fifo_sizes(hsotg);
52562306a36Sopenharmony_ci	}
52662306a36Sopenharmony_ci}
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci/**
52962306a36Sopenharmony_ci * dwc2_get_device_properties() - Read in device properties.
53062306a36Sopenharmony_ci *
53162306a36Sopenharmony_ci * @hsotg: Programming view of the DWC_otg controller
53262306a36Sopenharmony_ci *
53362306a36Sopenharmony_ci * Read in the device properties and adjust core parameters if needed.
53462306a36Sopenharmony_ci */
53562306a36Sopenharmony_cistatic void dwc2_get_device_properties(struct dwc2_hsotg *hsotg)
53662306a36Sopenharmony_ci{
53762306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
53862306a36Sopenharmony_ci	int num;
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	if ((hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) ||
54162306a36Sopenharmony_ci	    (hsotg->dr_mode == USB_DR_MODE_OTG)) {
54262306a36Sopenharmony_ci		device_property_read_u32(hsotg->dev, "g-rx-fifo-size",
54362306a36Sopenharmony_ci					 &p->g_rx_fifo_size);
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci		device_property_read_u32(hsotg->dev, "g-np-tx-fifo-size",
54662306a36Sopenharmony_ci					 &p->g_np_tx_fifo_size);
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci		num = device_property_count_u32(hsotg->dev, "g-tx-fifo-size");
54962306a36Sopenharmony_ci		if (num > 0) {
55062306a36Sopenharmony_ci			num = min(num, 15);
55162306a36Sopenharmony_ci			memset(p->g_tx_fifo_size, 0,
55262306a36Sopenharmony_ci			       sizeof(p->g_tx_fifo_size));
55362306a36Sopenharmony_ci			device_property_read_u32_array(hsotg->dev,
55462306a36Sopenharmony_ci						       "g-tx-fifo-size",
55562306a36Sopenharmony_ci						       &p->g_tx_fifo_size[1],
55662306a36Sopenharmony_ci						       num);
55762306a36Sopenharmony_ci		}
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci		of_usb_update_otg_caps(hsotg->dev->of_node, &p->otg_caps);
56062306a36Sopenharmony_ci	}
56162306a36Sopenharmony_ci
56262306a36Sopenharmony_ci	p->oc_disable = of_property_read_bool(hsotg->dev->of_node, "disable-over-current");
56362306a36Sopenharmony_ci}
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_cistatic void dwc2_check_param_otg_cap(struct dwc2_hsotg *hsotg)
56662306a36Sopenharmony_ci{
56762306a36Sopenharmony_ci	int valid = 1;
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	if (hsotg->params.otg_caps.hnp_support && hsotg->params.otg_caps.srp_support) {
57062306a36Sopenharmony_ci		/* check HNP && SRP capable */
57162306a36Sopenharmony_ci		if (hsotg->hw_params.op_mode != GHWCFG2_OP_MODE_HNP_SRP_CAPABLE)
57262306a36Sopenharmony_ci			valid = 0;
57362306a36Sopenharmony_ci	} else if (!hsotg->params.otg_caps.hnp_support) {
57462306a36Sopenharmony_ci		/* check SRP only capable */
57562306a36Sopenharmony_ci		if (hsotg->params.otg_caps.srp_support) {
57662306a36Sopenharmony_ci			switch (hsotg->hw_params.op_mode) {
57762306a36Sopenharmony_ci			case GHWCFG2_OP_MODE_HNP_SRP_CAPABLE:
57862306a36Sopenharmony_ci			case GHWCFG2_OP_MODE_SRP_ONLY_CAPABLE:
57962306a36Sopenharmony_ci			case GHWCFG2_OP_MODE_SRP_CAPABLE_DEVICE:
58062306a36Sopenharmony_ci			case GHWCFG2_OP_MODE_SRP_CAPABLE_HOST:
58162306a36Sopenharmony_ci				break;
58262306a36Sopenharmony_ci			default:
58362306a36Sopenharmony_ci				valid = 0;
58462306a36Sopenharmony_ci				break;
58562306a36Sopenharmony_ci			}
58662306a36Sopenharmony_ci		}
58762306a36Sopenharmony_ci		/* else: NO HNP && NO SRP capable: always valid */
58862306a36Sopenharmony_ci	} else {
58962306a36Sopenharmony_ci		valid = 0;
59062306a36Sopenharmony_ci	}
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	if (!valid)
59362306a36Sopenharmony_ci		dwc2_set_param_otg_cap(hsotg);
59462306a36Sopenharmony_ci}
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_cistatic void dwc2_check_param_phy_type(struct dwc2_hsotg *hsotg)
59762306a36Sopenharmony_ci{
59862306a36Sopenharmony_ci	int valid = 0;
59962306a36Sopenharmony_ci	u32 hs_phy_type;
60062306a36Sopenharmony_ci	u32 fs_phy_type;
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci	hs_phy_type = hsotg->hw_params.hs_phy_type;
60362306a36Sopenharmony_ci	fs_phy_type = hsotg->hw_params.fs_phy_type;
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	switch (hsotg->params.phy_type) {
60662306a36Sopenharmony_ci	case DWC2_PHY_TYPE_PARAM_FS:
60762306a36Sopenharmony_ci		if (fs_phy_type == GHWCFG2_FS_PHY_TYPE_DEDICATED)
60862306a36Sopenharmony_ci			valid = 1;
60962306a36Sopenharmony_ci		break;
61062306a36Sopenharmony_ci	case DWC2_PHY_TYPE_PARAM_UTMI:
61162306a36Sopenharmony_ci		if ((hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI) ||
61262306a36Sopenharmony_ci		    (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI))
61362306a36Sopenharmony_ci			valid = 1;
61462306a36Sopenharmony_ci		break;
61562306a36Sopenharmony_ci	case DWC2_PHY_TYPE_PARAM_ULPI:
61662306a36Sopenharmony_ci		if ((hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI) ||
61762306a36Sopenharmony_ci		    (hs_phy_type == GHWCFG2_HS_PHY_TYPE_UTMI_ULPI))
61862306a36Sopenharmony_ci			valid = 1;
61962306a36Sopenharmony_ci		break;
62062306a36Sopenharmony_ci	default:
62162306a36Sopenharmony_ci		break;
62262306a36Sopenharmony_ci	}
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_ci	if (!valid)
62562306a36Sopenharmony_ci		dwc2_set_param_phy_type(hsotg);
62662306a36Sopenharmony_ci}
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_cistatic void dwc2_check_param_speed(struct dwc2_hsotg *hsotg)
62962306a36Sopenharmony_ci{
63062306a36Sopenharmony_ci	int valid = 1;
63162306a36Sopenharmony_ci	int phy_type = hsotg->params.phy_type;
63262306a36Sopenharmony_ci	int speed = hsotg->params.speed;
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci	switch (speed) {
63562306a36Sopenharmony_ci	case DWC2_SPEED_PARAM_HIGH:
63662306a36Sopenharmony_ci		if ((hsotg->params.speed == DWC2_SPEED_PARAM_HIGH) &&
63762306a36Sopenharmony_ci		    (phy_type == DWC2_PHY_TYPE_PARAM_FS))
63862306a36Sopenharmony_ci			valid = 0;
63962306a36Sopenharmony_ci		break;
64062306a36Sopenharmony_ci	case DWC2_SPEED_PARAM_FULL:
64162306a36Sopenharmony_ci	case DWC2_SPEED_PARAM_LOW:
64262306a36Sopenharmony_ci		break;
64362306a36Sopenharmony_ci	default:
64462306a36Sopenharmony_ci		valid = 0;
64562306a36Sopenharmony_ci		break;
64662306a36Sopenharmony_ci	}
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	if (!valid)
64962306a36Sopenharmony_ci		dwc2_set_param_speed(hsotg);
65062306a36Sopenharmony_ci}
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_cistatic void dwc2_check_param_phy_utmi_width(struct dwc2_hsotg *hsotg)
65362306a36Sopenharmony_ci{
65462306a36Sopenharmony_ci	int valid = 0;
65562306a36Sopenharmony_ci	int param = hsotg->params.phy_utmi_width;
65662306a36Sopenharmony_ci	int width = hsotg->hw_params.utmi_phy_data_width;
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci	switch (width) {
65962306a36Sopenharmony_ci	case GHWCFG4_UTMI_PHY_DATA_WIDTH_8:
66062306a36Sopenharmony_ci		valid = (param == 8);
66162306a36Sopenharmony_ci		break;
66262306a36Sopenharmony_ci	case GHWCFG4_UTMI_PHY_DATA_WIDTH_16:
66362306a36Sopenharmony_ci		valid = (param == 16);
66462306a36Sopenharmony_ci		break;
66562306a36Sopenharmony_ci	case GHWCFG4_UTMI_PHY_DATA_WIDTH_8_OR_16:
66662306a36Sopenharmony_ci		valid = (param == 8 || param == 16);
66762306a36Sopenharmony_ci		break;
66862306a36Sopenharmony_ci	}
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci	if (!valid)
67162306a36Sopenharmony_ci		dwc2_set_param_phy_utmi_width(hsotg);
67262306a36Sopenharmony_ci}
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_cistatic void dwc2_check_param_power_down(struct dwc2_hsotg *hsotg)
67562306a36Sopenharmony_ci{
67662306a36Sopenharmony_ci	int param = hsotg->params.power_down;
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci	switch (param) {
67962306a36Sopenharmony_ci	case DWC2_POWER_DOWN_PARAM_NONE:
68062306a36Sopenharmony_ci		break;
68162306a36Sopenharmony_ci	case DWC2_POWER_DOWN_PARAM_PARTIAL:
68262306a36Sopenharmony_ci		if (hsotg->hw_params.power_optimized)
68362306a36Sopenharmony_ci			break;
68462306a36Sopenharmony_ci		dev_dbg(hsotg->dev,
68562306a36Sopenharmony_ci			"Partial power down isn't supported by HW\n");
68662306a36Sopenharmony_ci		param = DWC2_POWER_DOWN_PARAM_NONE;
68762306a36Sopenharmony_ci		break;
68862306a36Sopenharmony_ci	case DWC2_POWER_DOWN_PARAM_HIBERNATION:
68962306a36Sopenharmony_ci		if (hsotg->hw_params.hibernation)
69062306a36Sopenharmony_ci			break;
69162306a36Sopenharmony_ci		dev_dbg(hsotg->dev,
69262306a36Sopenharmony_ci			"Hibernation isn't supported by HW\n");
69362306a36Sopenharmony_ci		param = DWC2_POWER_DOWN_PARAM_NONE;
69462306a36Sopenharmony_ci		break;
69562306a36Sopenharmony_ci	default:
69662306a36Sopenharmony_ci		dev_err(hsotg->dev,
69762306a36Sopenharmony_ci			"%s: Invalid parameter power_down=%d\n",
69862306a36Sopenharmony_ci			__func__, param);
69962306a36Sopenharmony_ci		param = DWC2_POWER_DOWN_PARAM_NONE;
70062306a36Sopenharmony_ci		break;
70162306a36Sopenharmony_ci	}
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci	hsotg->params.power_down = param;
70462306a36Sopenharmony_ci}
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_cistatic void dwc2_check_param_tx_fifo_sizes(struct dwc2_hsotg *hsotg)
70762306a36Sopenharmony_ci{
70862306a36Sopenharmony_ci	int fifo_count;
70962306a36Sopenharmony_ci	int fifo;
71062306a36Sopenharmony_ci	int min;
71162306a36Sopenharmony_ci	u32 total = 0;
71262306a36Sopenharmony_ci	u32 dptxfszn;
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);
71562306a36Sopenharmony_ci	min = hsotg->hw_params.en_multiple_tx_fifo ? 16 : 4;
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_ci	for (fifo = 1; fifo <= fifo_count; fifo++)
71862306a36Sopenharmony_ci		total += hsotg->params.g_tx_fifo_size[fifo];
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	if (total > dwc2_hsotg_tx_fifo_total_depth(hsotg) || !total) {
72162306a36Sopenharmony_ci		dev_warn(hsotg->dev, "%s: Invalid parameter g-tx-fifo-size, setting to default average\n",
72262306a36Sopenharmony_ci			 __func__);
72362306a36Sopenharmony_ci		dwc2_set_param_tx_fifo_sizes(hsotg);
72462306a36Sopenharmony_ci	}
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_ci	for (fifo = 1; fifo <= fifo_count; fifo++) {
72762306a36Sopenharmony_ci		dptxfszn = hsotg->hw_params.g_tx_fifo_size[fifo];
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci		if (hsotg->params.g_tx_fifo_size[fifo] < min ||
73062306a36Sopenharmony_ci		    hsotg->params.g_tx_fifo_size[fifo] >  dptxfszn) {
73162306a36Sopenharmony_ci			dev_warn(hsotg->dev, "%s: Invalid parameter g_tx_fifo_size[%d]=%d\n",
73262306a36Sopenharmony_ci				 __func__, fifo,
73362306a36Sopenharmony_ci				 hsotg->params.g_tx_fifo_size[fifo]);
73462306a36Sopenharmony_ci			hsotg->params.g_tx_fifo_size[fifo] = dptxfszn;
73562306a36Sopenharmony_ci		}
73662306a36Sopenharmony_ci	}
73762306a36Sopenharmony_ci}
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci#define CHECK_RANGE(_param, _min, _max, _def) do {			\
74062306a36Sopenharmony_ci		if ((int)(hsotg->params._param) < (_min) ||		\
74162306a36Sopenharmony_ci		    (hsotg->params._param) > (_max)) {			\
74262306a36Sopenharmony_ci			dev_warn(hsotg->dev, "%s: Invalid parameter %s=%d\n", \
74362306a36Sopenharmony_ci				 __func__, #_param, hsotg->params._param); \
74462306a36Sopenharmony_ci			hsotg->params._param = (_def);			\
74562306a36Sopenharmony_ci		}							\
74662306a36Sopenharmony_ci	} while (0)
74762306a36Sopenharmony_ci
74862306a36Sopenharmony_ci#define CHECK_BOOL(_param, _check) do {					\
74962306a36Sopenharmony_ci		if (hsotg->params._param && !(_check)) {		\
75062306a36Sopenharmony_ci			dev_warn(hsotg->dev, "%s: Invalid parameter %s=%d\n", \
75162306a36Sopenharmony_ci				 __func__, #_param, hsotg->params._param); \
75262306a36Sopenharmony_ci			hsotg->params._param = false;			\
75362306a36Sopenharmony_ci		}							\
75462306a36Sopenharmony_ci	} while (0)
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_cistatic void dwc2_check_params(struct dwc2_hsotg *hsotg)
75762306a36Sopenharmony_ci{
75862306a36Sopenharmony_ci	struct dwc2_hw_params *hw = &hsotg->hw_params;
75962306a36Sopenharmony_ci	struct dwc2_core_params *p = &hsotg->params;
76062306a36Sopenharmony_ci	bool dma_capable = !(hw->arch == GHWCFG2_SLAVE_ONLY_ARCH);
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci	dwc2_check_param_otg_cap(hsotg);
76362306a36Sopenharmony_ci	dwc2_check_param_phy_type(hsotg);
76462306a36Sopenharmony_ci	dwc2_check_param_speed(hsotg);
76562306a36Sopenharmony_ci	dwc2_check_param_phy_utmi_width(hsotg);
76662306a36Sopenharmony_ci	dwc2_check_param_power_down(hsotg);
76762306a36Sopenharmony_ci	CHECK_BOOL(enable_dynamic_fifo, hw->enable_dynamic_fifo);
76862306a36Sopenharmony_ci	CHECK_BOOL(en_multiple_tx_fifo, hw->en_multiple_tx_fifo);
76962306a36Sopenharmony_ci	CHECK_BOOL(i2c_enable, hw->i2c_enable);
77062306a36Sopenharmony_ci	CHECK_BOOL(ipg_isoc_en, hw->ipg_isoc_en);
77162306a36Sopenharmony_ci	CHECK_BOOL(acg_enable, hw->acg_enable);
77262306a36Sopenharmony_ci	CHECK_BOOL(reload_ctl, (hsotg->hw_params.snpsid > DWC2_CORE_REV_2_92a));
77362306a36Sopenharmony_ci	CHECK_BOOL(lpm, (hsotg->hw_params.snpsid >= DWC2_CORE_REV_2_80a));
77462306a36Sopenharmony_ci	CHECK_BOOL(lpm, hw->lpm_mode);
77562306a36Sopenharmony_ci	CHECK_BOOL(lpm_clock_gating, hsotg->params.lpm);
77662306a36Sopenharmony_ci	CHECK_BOOL(besl, hsotg->params.lpm);
77762306a36Sopenharmony_ci	CHECK_BOOL(besl, (hsotg->hw_params.snpsid >= DWC2_CORE_REV_3_00a));
77862306a36Sopenharmony_ci	CHECK_BOOL(hird_threshold_en, hsotg->params.lpm);
77962306a36Sopenharmony_ci	CHECK_RANGE(hird_threshold, 0, hsotg->params.besl ? 12 : 7, 0);
78062306a36Sopenharmony_ci	CHECK_BOOL(service_interval, hw->service_interval_mode);
78162306a36Sopenharmony_ci	CHECK_RANGE(max_packet_count,
78262306a36Sopenharmony_ci		    15, hw->max_packet_count,
78362306a36Sopenharmony_ci		    hw->max_packet_count);
78462306a36Sopenharmony_ci	CHECK_RANGE(max_transfer_size,
78562306a36Sopenharmony_ci		    2047, hw->max_transfer_size,
78662306a36Sopenharmony_ci		    hw->max_transfer_size);
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_ci	if ((hsotg->dr_mode == USB_DR_MODE_HOST) ||
78962306a36Sopenharmony_ci	    (hsotg->dr_mode == USB_DR_MODE_OTG)) {
79062306a36Sopenharmony_ci		CHECK_BOOL(host_dma, dma_capable);
79162306a36Sopenharmony_ci		CHECK_BOOL(dma_desc_enable, p->host_dma);
79262306a36Sopenharmony_ci		CHECK_BOOL(dma_desc_fs_enable, p->dma_desc_enable);
79362306a36Sopenharmony_ci		CHECK_BOOL(host_ls_low_power_phy_clk,
79462306a36Sopenharmony_ci			   p->phy_type == DWC2_PHY_TYPE_PARAM_FS);
79562306a36Sopenharmony_ci		CHECK_RANGE(host_channels,
79662306a36Sopenharmony_ci			    1, hw->host_channels,
79762306a36Sopenharmony_ci			    hw->host_channels);
79862306a36Sopenharmony_ci		CHECK_RANGE(host_rx_fifo_size,
79962306a36Sopenharmony_ci			    16, hw->rx_fifo_size,
80062306a36Sopenharmony_ci			    hw->rx_fifo_size);
80162306a36Sopenharmony_ci		CHECK_RANGE(host_nperio_tx_fifo_size,
80262306a36Sopenharmony_ci			    16, hw->host_nperio_tx_fifo_size,
80362306a36Sopenharmony_ci			    hw->host_nperio_tx_fifo_size);
80462306a36Sopenharmony_ci		CHECK_RANGE(host_perio_tx_fifo_size,
80562306a36Sopenharmony_ci			    16, hw->host_perio_tx_fifo_size,
80662306a36Sopenharmony_ci			    hw->host_perio_tx_fifo_size);
80762306a36Sopenharmony_ci	}
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci	if ((hsotg->dr_mode == USB_DR_MODE_PERIPHERAL) ||
81062306a36Sopenharmony_ci	    (hsotg->dr_mode == USB_DR_MODE_OTG)) {
81162306a36Sopenharmony_ci		CHECK_BOOL(g_dma, dma_capable);
81262306a36Sopenharmony_ci		CHECK_BOOL(g_dma_desc, (p->g_dma && hw->dma_desc_enable));
81362306a36Sopenharmony_ci		CHECK_RANGE(g_rx_fifo_size,
81462306a36Sopenharmony_ci			    16, hw->rx_fifo_size,
81562306a36Sopenharmony_ci			    hw->rx_fifo_size);
81662306a36Sopenharmony_ci		CHECK_RANGE(g_np_tx_fifo_size,
81762306a36Sopenharmony_ci			    16, hw->dev_nperio_tx_fifo_size,
81862306a36Sopenharmony_ci			    hw->dev_nperio_tx_fifo_size);
81962306a36Sopenharmony_ci		dwc2_check_param_tx_fifo_sizes(hsotg);
82062306a36Sopenharmony_ci	}
82162306a36Sopenharmony_ci}
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci/*
82462306a36Sopenharmony_ci * Gets host hardware parameters. Forces host mode if not currently in
82562306a36Sopenharmony_ci * host mode. Should be called immediately after a core soft reset in
82662306a36Sopenharmony_ci * order to get the reset values.
82762306a36Sopenharmony_ci */
82862306a36Sopenharmony_cistatic void dwc2_get_host_hwparams(struct dwc2_hsotg *hsotg)
82962306a36Sopenharmony_ci{
83062306a36Sopenharmony_ci	struct dwc2_hw_params *hw = &hsotg->hw_params;
83162306a36Sopenharmony_ci	u32 gnptxfsiz;
83262306a36Sopenharmony_ci	u32 hptxfsiz;
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	if (hsotg->dr_mode == USB_DR_MODE_PERIPHERAL)
83562306a36Sopenharmony_ci		return;
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci	dwc2_force_mode(hsotg, true);
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_ci	gnptxfsiz = dwc2_readl(hsotg, GNPTXFSIZ);
84062306a36Sopenharmony_ci	hptxfsiz = dwc2_readl(hsotg, HPTXFSIZ);
84162306a36Sopenharmony_ci
84262306a36Sopenharmony_ci	hw->host_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
84362306a36Sopenharmony_ci				       FIFOSIZE_DEPTH_SHIFT;
84462306a36Sopenharmony_ci	hw->host_perio_tx_fifo_size = (hptxfsiz & FIFOSIZE_DEPTH_MASK) >>
84562306a36Sopenharmony_ci				      FIFOSIZE_DEPTH_SHIFT;
84662306a36Sopenharmony_ci}
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ci/*
84962306a36Sopenharmony_ci * Gets device hardware parameters. Forces device mode if not
85062306a36Sopenharmony_ci * currently in device mode. Should be called immediately after a core
85162306a36Sopenharmony_ci * soft reset in order to get the reset values.
85262306a36Sopenharmony_ci */
85362306a36Sopenharmony_cistatic void dwc2_get_dev_hwparams(struct dwc2_hsotg *hsotg)
85462306a36Sopenharmony_ci{
85562306a36Sopenharmony_ci	struct dwc2_hw_params *hw = &hsotg->hw_params;
85662306a36Sopenharmony_ci	u32 gnptxfsiz;
85762306a36Sopenharmony_ci	int fifo, fifo_count;
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_ci	if (hsotg->dr_mode == USB_DR_MODE_HOST)
86062306a36Sopenharmony_ci		return;
86162306a36Sopenharmony_ci
86262306a36Sopenharmony_ci	dwc2_force_mode(hsotg, false);
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_ci	gnptxfsiz = dwc2_readl(hsotg, GNPTXFSIZ);
86562306a36Sopenharmony_ci
86662306a36Sopenharmony_ci	fifo_count = dwc2_hsotg_tx_fifo_count(hsotg);
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci	for (fifo = 1; fifo <= fifo_count; fifo++) {
86962306a36Sopenharmony_ci		hw->g_tx_fifo_size[fifo] =
87062306a36Sopenharmony_ci			(dwc2_readl(hsotg, DPTXFSIZN(fifo)) &
87162306a36Sopenharmony_ci			 FIFOSIZE_DEPTH_MASK) >> FIFOSIZE_DEPTH_SHIFT;
87262306a36Sopenharmony_ci	}
87362306a36Sopenharmony_ci
87462306a36Sopenharmony_ci	hw->dev_nperio_tx_fifo_size = (gnptxfsiz & FIFOSIZE_DEPTH_MASK) >>
87562306a36Sopenharmony_ci				       FIFOSIZE_DEPTH_SHIFT;
87662306a36Sopenharmony_ci}
87762306a36Sopenharmony_ci
87862306a36Sopenharmony_ci/**
87962306a36Sopenharmony_ci * dwc2_get_hwparams() - During device initialization, read various hardware
88062306a36Sopenharmony_ci *                       configuration registers and interpret the contents.
88162306a36Sopenharmony_ci *
88262306a36Sopenharmony_ci * @hsotg: Programming view of the DWC_otg controller
88362306a36Sopenharmony_ci *
88462306a36Sopenharmony_ci */
88562306a36Sopenharmony_ciint dwc2_get_hwparams(struct dwc2_hsotg *hsotg)
88662306a36Sopenharmony_ci{
88762306a36Sopenharmony_ci	struct dwc2_hw_params *hw = &hsotg->hw_params;
88862306a36Sopenharmony_ci	unsigned int width;
88962306a36Sopenharmony_ci	u32 hwcfg1, hwcfg2, hwcfg3, hwcfg4;
89062306a36Sopenharmony_ci	u32 grxfsiz;
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_ci	hwcfg1 = dwc2_readl(hsotg, GHWCFG1);
89362306a36Sopenharmony_ci	hwcfg2 = dwc2_readl(hsotg, GHWCFG2);
89462306a36Sopenharmony_ci	hwcfg3 = dwc2_readl(hsotg, GHWCFG3);
89562306a36Sopenharmony_ci	hwcfg4 = dwc2_readl(hsotg, GHWCFG4);
89662306a36Sopenharmony_ci	grxfsiz = dwc2_readl(hsotg, GRXFSIZ);
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_ci	/* hwcfg1 */
89962306a36Sopenharmony_ci	hw->dev_ep_dirs = hwcfg1;
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci	/* hwcfg2 */
90262306a36Sopenharmony_ci	hw->op_mode = (hwcfg2 & GHWCFG2_OP_MODE_MASK) >>
90362306a36Sopenharmony_ci		      GHWCFG2_OP_MODE_SHIFT;
90462306a36Sopenharmony_ci	hw->arch = (hwcfg2 & GHWCFG2_ARCHITECTURE_MASK) >>
90562306a36Sopenharmony_ci		   GHWCFG2_ARCHITECTURE_SHIFT;
90662306a36Sopenharmony_ci	hw->enable_dynamic_fifo = !!(hwcfg2 & GHWCFG2_DYNAMIC_FIFO);
90762306a36Sopenharmony_ci	hw->host_channels = 1 + ((hwcfg2 & GHWCFG2_NUM_HOST_CHAN_MASK) >>
90862306a36Sopenharmony_ci				GHWCFG2_NUM_HOST_CHAN_SHIFT);
90962306a36Sopenharmony_ci	hw->hs_phy_type = (hwcfg2 & GHWCFG2_HS_PHY_TYPE_MASK) >>
91062306a36Sopenharmony_ci			  GHWCFG2_HS_PHY_TYPE_SHIFT;
91162306a36Sopenharmony_ci	hw->fs_phy_type = (hwcfg2 & GHWCFG2_FS_PHY_TYPE_MASK) >>
91262306a36Sopenharmony_ci			  GHWCFG2_FS_PHY_TYPE_SHIFT;
91362306a36Sopenharmony_ci	hw->num_dev_ep = (hwcfg2 & GHWCFG2_NUM_DEV_EP_MASK) >>
91462306a36Sopenharmony_ci			 GHWCFG2_NUM_DEV_EP_SHIFT;
91562306a36Sopenharmony_ci	hw->nperio_tx_q_depth =
91662306a36Sopenharmony_ci		(hwcfg2 & GHWCFG2_NONPERIO_TX_Q_DEPTH_MASK) >>
91762306a36Sopenharmony_ci		GHWCFG2_NONPERIO_TX_Q_DEPTH_SHIFT << 1;
91862306a36Sopenharmony_ci	hw->host_perio_tx_q_depth =
91962306a36Sopenharmony_ci		(hwcfg2 & GHWCFG2_HOST_PERIO_TX_Q_DEPTH_MASK) >>
92062306a36Sopenharmony_ci		GHWCFG2_HOST_PERIO_TX_Q_DEPTH_SHIFT << 1;
92162306a36Sopenharmony_ci	hw->dev_token_q_depth =
92262306a36Sopenharmony_ci		(hwcfg2 & GHWCFG2_DEV_TOKEN_Q_DEPTH_MASK) >>
92362306a36Sopenharmony_ci		GHWCFG2_DEV_TOKEN_Q_DEPTH_SHIFT;
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci	/* hwcfg3 */
92662306a36Sopenharmony_ci	width = (hwcfg3 & GHWCFG3_XFER_SIZE_CNTR_WIDTH_MASK) >>
92762306a36Sopenharmony_ci		GHWCFG3_XFER_SIZE_CNTR_WIDTH_SHIFT;
92862306a36Sopenharmony_ci	hw->max_transfer_size = (1 << (width + 11)) - 1;
92962306a36Sopenharmony_ci	width = (hwcfg3 & GHWCFG3_PACKET_SIZE_CNTR_WIDTH_MASK) >>
93062306a36Sopenharmony_ci		GHWCFG3_PACKET_SIZE_CNTR_WIDTH_SHIFT;
93162306a36Sopenharmony_ci	hw->max_packet_count = (1 << (width + 4)) - 1;
93262306a36Sopenharmony_ci	hw->i2c_enable = !!(hwcfg3 & GHWCFG3_I2C);
93362306a36Sopenharmony_ci	hw->total_fifo_size = (hwcfg3 & GHWCFG3_DFIFO_DEPTH_MASK) >>
93462306a36Sopenharmony_ci			      GHWCFG3_DFIFO_DEPTH_SHIFT;
93562306a36Sopenharmony_ci	hw->lpm_mode = !!(hwcfg3 & GHWCFG3_OTG_LPM_EN);
93662306a36Sopenharmony_ci
93762306a36Sopenharmony_ci	/* hwcfg4 */
93862306a36Sopenharmony_ci	hw->en_multiple_tx_fifo = !!(hwcfg4 & GHWCFG4_DED_FIFO_EN);
93962306a36Sopenharmony_ci	hw->num_dev_perio_in_ep = (hwcfg4 & GHWCFG4_NUM_DEV_PERIO_IN_EP_MASK) >>
94062306a36Sopenharmony_ci				  GHWCFG4_NUM_DEV_PERIO_IN_EP_SHIFT;
94162306a36Sopenharmony_ci	hw->num_dev_in_eps = (hwcfg4 & GHWCFG4_NUM_IN_EPS_MASK) >>
94262306a36Sopenharmony_ci			     GHWCFG4_NUM_IN_EPS_SHIFT;
94362306a36Sopenharmony_ci	hw->dma_desc_enable = !!(hwcfg4 & GHWCFG4_DESC_DMA);
94462306a36Sopenharmony_ci	hw->power_optimized = !!(hwcfg4 & GHWCFG4_POWER_OPTIMIZ);
94562306a36Sopenharmony_ci	hw->hibernation = !!(hwcfg4 & GHWCFG4_HIBER);
94662306a36Sopenharmony_ci	hw->utmi_phy_data_width = (hwcfg4 & GHWCFG4_UTMI_PHY_DATA_WIDTH_MASK) >>
94762306a36Sopenharmony_ci				  GHWCFG4_UTMI_PHY_DATA_WIDTH_SHIFT;
94862306a36Sopenharmony_ci	hw->acg_enable = !!(hwcfg4 & GHWCFG4_ACG_SUPPORTED);
94962306a36Sopenharmony_ci	hw->ipg_isoc_en = !!(hwcfg4 & GHWCFG4_IPG_ISOC_SUPPORTED);
95062306a36Sopenharmony_ci	hw->service_interval_mode = !!(hwcfg4 &
95162306a36Sopenharmony_ci				       GHWCFG4_SERVICE_INTERVAL_SUPPORTED);
95262306a36Sopenharmony_ci
95362306a36Sopenharmony_ci	/* fifo sizes */
95462306a36Sopenharmony_ci	hw->rx_fifo_size = (grxfsiz & GRXFSIZ_DEPTH_MASK) >>
95562306a36Sopenharmony_ci				GRXFSIZ_DEPTH_SHIFT;
95662306a36Sopenharmony_ci	/*
95762306a36Sopenharmony_ci	 * Host specific hardware parameters. Reading these parameters
95862306a36Sopenharmony_ci	 * requires the controller to be in host mode. The mode will
95962306a36Sopenharmony_ci	 * be forced, if necessary, to read these values.
96062306a36Sopenharmony_ci	 */
96162306a36Sopenharmony_ci	dwc2_get_host_hwparams(hsotg);
96262306a36Sopenharmony_ci	dwc2_get_dev_hwparams(hsotg);
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_ci	return 0;
96562306a36Sopenharmony_ci}
96662306a36Sopenharmony_ci
96762306a36Sopenharmony_citypedef void (*set_params_cb)(struct dwc2_hsotg *data);
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ciint dwc2_init_params(struct dwc2_hsotg *hsotg)
97062306a36Sopenharmony_ci{
97162306a36Sopenharmony_ci	const struct of_device_id *match;
97262306a36Sopenharmony_ci	set_params_cb set_params;
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ci	dwc2_set_default_params(hsotg);
97562306a36Sopenharmony_ci	dwc2_get_device_properties(hsotg);
97662306a36Sopenharmony_ci
97762306a36Sopenharmony_ci	match = of_match_device(dwc2_of_match_table, hsotg->dev);
97862306a36Sopenharmony_ci	if (match && match->data) {
97962306a36Sopenharmony_ci		set_params = match->data;
98062306a36Sopenharmony_ci		set_params(hsotg);
98162306a36Sopenharmony_ci	} else if (!match) {
98262306a36Sopenharmony_ci		const struct acpi_device_id *amatch;
98362306a36Sopenharmony_ci		const struct pci_device_id *pmatch = NULL;
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci		amatch = acpi_match_device(dwc2_acpi_match, hsotg->dev);
98662306a36Sopenharmony_ci		if (amatch && amatch->driver_data) {
98762306a36Sopenharmony_ci			set_params = (set_params_cb)amatch->driver_data;
98862306a36Sopenharmony_ci			set_params(hsotg);
98962306a36Sopenharmony_ci		} else if (!amatch)
99062306a36Sopenharmony_ci			pmatch = pci_match_id(dwc2_pci_ids, to_pci_dev(hsotg->dev->parent));
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci		if (pmatch && pmatch->driver_data) {
99362306a36Sopenharmony_ci			set_params = (set_params_cb)pmatch->driver_data;
99462306a36Sopenharmony_ci			set_params(hsotg);
99562306a36Sopenharmony_ci		}
99662306a36Sopenharmony_ci	}
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci	dwc2_check_params(hsotg);
99962306a36Sopenharmony_ci
100062306a36Sopenharmony_ci	return 0;
100162306a36Sopenharmony_ci}
1002