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