|
22 | 22 | #include <linux/mfd/syscon.h>
|
23 | 23 | #include <linux/regmap.h>
|
24 | 24 | #include <linux/of_platform.h>
|
| 25 | +#include <linux/sys_soc.h> |
25 | 26 |
|
26 | 27 | #define USB2PHY_ANA_CONFIG1 0x4c
|
27 | 28 | #define USB2PHY_DISCON_BYP_LATCH BIT(31)
|
28 | 29 |
|
| 30 | +#define USB2PHY_CHRG_DET 0x14 |
| 31 | +#define USB2PHY_CHRG_DET_USE_CHG_DET_REG BIT(29) |
| 32 | +#define USB2PHY_CHRG_DET_DIS_CHG_DET BIT(28) |
| 33 | + |
29 | 34 | /* SoC Specific USB2_OTG register definitions */
|
30 | 35 | #define AM654_USB2_OTG_PD BIT(8)
|
31 | 36 | #define AM654_USB2_VBUS_DET_EN BIT(5)
|
|
43 | 48 | #define OMAP_USB2_HAS_START_SRP BIT(0)
|
44 | 49 | #define OMAP_USB2_HAS_SET_VBUS BIT(1)
|
45 | 50 | #define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT BIT(2)
|
| 51 | +#define OMAP_USB2_DISABLE_CHRG_DET BIT(3) |
46 | 52 |
|
47 | 53 | struct omap_usb {
|
48 | 54 | struct usb_phy phy;
|
@@ -236,6 +242,13 @@ static int omap_usb_init(struct phy *x)
|
236 | 242 | omap_usb_writel(phy->phy_base, USB2PHY_ANA_CONFIG1, val);
|
237 | 243 | }
|
238 | 244 |
|
| 245 | + if (phy->flags & OMAP_USB2_DISABLE_CHRG_DET) { |
| 246 | + val = omap_usb_readl(phy->phy_base, USB2PHY_CHRG_DET); |
| 247 | + val |= USB2PHY_CHRG_DET_USE_CHG_DET_REG | |
| 248 | + USB2PHY_CHRG_DET_DIS_CHG_DET; |
| 249 | + omap_usb_writel(phy->phy_base, USB2PHY_CHRG_DET, val); |
| 250 | + } |
| 251 | + |
239 | 252 | return 0;
|
240 | 253 | }
|
241 | 254 |
|
@@ -329,6 +342,26 @@ static const struct of_device_id omap_usb2_id_table[] = {
|
329 | 342 | };
|
330 | 343 | MODULE_DEVICE_TABLE(of, omap_usb2_id_table);
|
331 | 344 |
|
| 345 | +static void omap_usb2_init_errata(struct omap_usb *phy) |
| 346 | +{ |
| 347 | + static const struct soc_device_attribute am65x_sr10_soc_devices[] = { |
| 348 | + { .family = "AM65X", .revision = "SR1.0" }, |
| 349 | + { /* sentinel */ } |
| 350 | + }; |
| 351 | + |
| 352 | + /* |
| 353 | + * Errata i2075: USB2PHY: USB2PHY Charger Detect is Enabled by |
| 354 | + * Default Without VBUS Presence. |
| 355 | + * |
| 356 | + * AM654x SR1.0 has a silicon bug due to which D+ is pulled high after |
| 357 | + * POR, which could cause enumeration failure with some USB hubs. |
| 358 | + * Disabling the USB2_PHY Charger Detect function will put D+ |
| 359 | + * into the normal state. |
| 360 | + */ |
| 361 | + if (soc_device_match(am65x_sr10_soc_devices)) |
| 362 | + phy->flags |= OMAP_USB2_DISABLE_CHRG_DET; |
| 363 | +} |
| 364 | + |
332 | 365 | static int omap_usb2_probe(struct platform_device *pdev)
|
333 | 366 | {
|
334 | 367 | struct omap_usb *phy;
|
@@ -366,14 +399,14 @@ static int omap_usb2_probe(struct platform_device *pdev)
|
366 | 399 | phy->mask = phy_data->mask;
|
367 | 400 | phy->power_on = phy_data->power_on;
|
368 | 401 | phy->power_off = phy_data->power_off;
|
| 402 | + phy->flags = phy_data->flags; |
369 | 403 |
|
370 |
| - if (phy_data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { |
371 |
| - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
372 |
| - phy->phy_base = devm_ioremap_resource(&pdev->dev, res); |
373 |
| - if (IS_ERR(phy->phy_base)) |
374 |
| - return PTR_ERR(phy->phy_base); |
375 |
| - phy->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT; |
376 |
| - } |
| 404 | + omap_usb2_init_errata(phy); |
| 405 | + |
| 406 | + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 407 | + phy->phy_base = devm_ioremap_resource(&pdev->dev, res); |
| 408 | + if (IS_ERR(phy->phy_base)) |
| 409 | + return PTR_ERR(phy->phy_base); |
377 | 410 |
|
378 | 411 | phy->syscon_phy_power = syscon_regmap_lookup_by_phandle(node,
|
379 | 412 | "syscon-phy-power");
|
|
0 commit comments