| .. | .. | 
|---|
| 23 | 23 | #include <linux/platform_device.h> | 
|---|
| 24 | 24 | #include <linux/fsl_devices.h> | 
|---|
| 25 | 25 | #include <linux/of_platform.h> | 
|---|
|  | 26 | +#include <linux/io.h> | 
|---|
| 26 | 27 |  | 
|---|
| 27 | 28 | #include "ehci.h" | 
|---|
| 28 | 29 | #include "ehci-fsl.h" | 
|---|
| .. | .. | 
|---|
| 50 | 51 | struct resource *res; | 
|---|
| 51 | 52 | int irq; | 
|---|
| 52 | 53 | int retval; | 
|---|
|  | 54 | +	u32 tmp; | 
|---|
| 53 | 55 |  | 
|---|
| 54 | 56 | pr_debug("initializing FSL-SOC USB Controller\n"); | 
|---|
| 55 | 57 |  | 
|---|
| .. | .. | 
|---|
| 114 | 116 | } | 
|---|
| 115 | 117 |  | 
|---|
| 116 | 118 | /* Enable USB controller, 83xx or 8536 */ | 
|---|
| 117 |  | -	if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) | 
|---|
| 118 |  | -		clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL, | 
|---|
| 119 |  | -				CONTROL_REGISTER_W1C_MASK, 0x4); | 
|---|
|  | 119 | +	if (pdata->have_sysif_regs && pdata->controller_ver < FSL_USB_VER_1_6) { | 
|---|
|  | 120 | +		tmp = ioread32be(hcd->regs + FSL_SOC_USB_CTRL); | 
|---|
|  | 121 | +		tmp &= ~CONTROL_REGISTER_W1C_MASK; | 
|---|
|  | 122 | +		tmp |= 0x4; | 
|---|
|  | 123 | +		iowrite32be(tmp, hcd->regs + FSL_SOC_USB_CTRL); | 
|---|
|  | 124 | +	} | 
|---|
|  | 125 | + | 
|---|
|  | 126 | +	/* Set USB_EN bit to select ULPI phy for USB controller version 2.5 */ | 
|---|
|  | 127 | +	if (pdata->controller_ver == FSL_USB_VER_2_5 && | 
|---|
|  | 128 | +	    pdata->phy_mode == FSL_USB2_PHY_ULPI) | 
|---|
|  | 129 | +		iowrite32be(USB_CTRL_USB_EN, hcd->regs + FSL_SOC_USB_CTRL); | 
|---|
| 120 | 130 |  | 
|---|
| 121 | 131 | /* | 
|---|
| 122 | 132 | * Enable UTMI phy and program PTS field in UTMI mode before asserting | 
|---|
| 123 | 133 | * controller reset for USB Controller version 2.5 | 
|---|
| 124 | 134 | */ | 
|---|
| 125 | 135 | if (pdata->has_fsl_erratum_a007792) { | 
|---|
| 126 |  | -		clrsetbits_be32(hcd->regs + FSL_SOC_USB_CTRL, | 
|---|
| 127 |  | -				CONTROL_REGISTER_W1C_MASK, CTRL_UTMI_PHY_EN); | 
|---|
|  | 136 | +		tmp = ioread32be(hcd->regs + FSL_SOC_USB_CTRL); | 
|---|
|  | 137 | +		tmp &= ~CONTROL_REGISTER_W1C_MASK; | 
|---|
|  | 138 | +		tmp |= CTRL_UTMI_PHY_EN; | 
|---|
|  | 139 | +		iowrite32be(tmp, hcd->regs + FSL_SOC_USB_CTRL); | 
|---|
|  | 140 | + | 
|---|
| 128 | 141 | writel(PORT_PTS_UTMI, hcd->regs + FSL_SOC_USB_PORTSC1); | 
|---|
| 129 | 142 | } | 
|---|
| 130 | 143 |  | 
|---|
| .. | .. | 
|---|
| 170 | 183 | return retval; | 
|---|
| 171 | 184 | } | 
|---|
| 172 | 185 |  | 
|---|
|  | 186 | +static bool usb_phy_clk_valid(struct usb_hcd *hcd) | 
|---|
|  | 187 | +{ | 
|---|
|  | 188 | +	void __iomem *non_ehci = hcd->regs; | 
|---|
|  | 189 | +	bool ret = true; | 
|---|
|  | 190 | + | 
|---|
|  | 191 | +	if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & PHY_CLK_VALID)) | 
|---|
|  | 192 | +		ret = false; | 
|---|
|  | 193 | + | 
|---|
|  | 194 | +	return ret; | 
|---|
|  | 195 | +} | 
|---|
|  | 196 | + | 
|---|
| 173 | 197 | static int ehci_fsl_setup_phy(struct usb_hcd *hcd, | 
|---|
| 174 | 198 | enum fsl_usb2_phy_modes phy_mode, | 
|---|
| 175 | 199 | unsigned int port_offset) | 
|---|
| 176 | 200 | { | 
|---|
| 177 |  | -	u32 portsc; | 
|---|
|  | 201 | +	u32 portsc, tmp; | 
|---|
| 178 | 202 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | 
|---|
| 179 | 203 | void __iomem *non_ehci = hcd->regs; | 
|---|
| 180 | 204 | struct device *dev = hcd->self.controller; | 
|---|
| .. | .. | 
|---|
| 192 | 216 | case FSL_USB2_PHY_ULPI: | 
|---|
| 193 | 217 | if (pdata->have_sysif_regs && pdata->controller_ver) { | 
|---|
| 194 | 218 | /* controller version 1.6 or above */ | 
|---|
| 195 |  | -			clrbits32(non_ehci + FSL_SOC_USB_CTRL, | 
|---|
| 196 |  | -				  CONTROL_REGISTER_W1C_MASK | UTMI_PHY_EN); | 
|---|
| 197 |  | -			clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, | 
|---|
| 198 |  | -					CONTROL_REGISTER_W1C_MASK, | 
|---|
| 199 |  | -					ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN); | 
|---|
|  | 219 | +			/* turn off UTMI PHY first */ | 
|---|
|  | 220 | +			tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); | 
|---|
|  | 221 | +			tmp &= ~(CONTROL_REGISTER_W1C_MASK | UTMI_PHY_EN); | 
|---|
|  | 222 | +			iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); | 
|---|
|  | 223 | + | 
|---|
|  | 224 | +			/* then turn on ULPI and enable USB controller */ | 
|---|
|  | 225 | +			tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); | 
|---|
|  | 226 | +			tmp &= ~CONTROL_REGISTER_W1C_MASK; | 
|---|
|  | 227 | +			tmp |= ULPI_PHY_CLK_SEL | USB_CTRL_USB_EN; | 
|---|
|  | 228 | +			iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); | 
|---|
| 200 | 229 | } | 
|---|
| 201 | 230 | portsc |= PORT_PTS_ULPI; | 
|---|
| 202 | 231 | break; | 
|---|
| .. | .. | 
|---|
| 205 | 234 | break; | 
|---|
| 206 | 235 | case FSL_USB2_PHY_UTMI_WIDE: | 
|---|
| 207 | 236 | portsc |= PORT_PTS_PTW; | 
|---|
| 208 |  | -		/* fall through */ | 
|---|
|  | 237 | +		fallthrough; | 
|---|
| 209 | 238 | case FSL_USB2_PHY_UTMI: | 
|---|
|  | 239 | +		/* Presence of this node "has_fsl_erratum_a006918" | 
|---|
|  | 240 | +		 * in device-tree is used to stop USB controller | 
|---|
|  | 241 | +		 * initialization in Linux | 
|---|
|  | 242 | +		 */ | 
|---|
|  | 243 | +		if (pdata->has_fsl_erratum_a006918) { | 
|---|
|  | 244 | +			dev_warn(dev, "USB PHY clock invalid\n"); | 
|---|
|  | 245 | +			return -EINVAL; | 
|---|
|  | 246 | +		} | 
|---|
|  | 247 | +		fallthrough; | 
|---|
| 210 | 248 | case FSL_USB2_PHY_UTMI_DUAL: | 
|---|
|  | 249 | +		/* PHY_CLK_VALID bit is de-featured from all controller | 
|---|
|  | 250 | +		 * versions below 2.4 and is to be checked only for | 
|---|
|  | 251 | +		 * internal UTMI phy | 
|---|
|  | 252 | +		 */ | 
|---|
|  | 253 | +		if (pdata->controller_ver > FSL_USB_VER_2_4 && | 
|---|
|  | 254 | +		    pdata->have_sysif_regs && !usb_phy_clk_valid(hcd)) { | 
|---|
|  | 255 | +			dev_err(dev, "USB PHY clock invalid\n"); | 
|---|
|  | 256 | +			return -EINVAL; | 
|---|
|  | 257 | +		} | 
|---|
|  | 258 | + | 
|---|
| 211 | 259 | if (pdata->have_sysif_regs && pdata->controller_ver) { | 
|---|
| 212 | 260 | /* controller version 1.6 or above */ | 
|---|
| 213 |  | -			clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, | 
|---|
| 214 |  | -					CONTROL_REGISTER_W1C_MASK, UTMI_PHY_EN); | 
|---|
|  | 261 | +			tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); | 
|---|
|  | 262 | +			tmp &= ~CONTROL_REGISTER_W1C_MASK; | 
|---|
|  | 263 | +			tmp |= UTMI_PHY_EN; | 
|---|
|  | 264 | +			iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); | 
|---|
|  | 265 | + | 
|---|
| 215 | 266 | mdelay(FSL_UTMI_PHY_DLY);  /* Delay for UTMI PHY CLK to | 
|---|
| 216 | 267 | become stable - 10ms*/ | 
|---|
| 217 | 268 | } | 
|---|
| 218 | 269 | /* enable UTMI PHY */ | 
|---|
| 219 |  | -		if (pdata->have_sysif_regs) | 
|---|
| 220 |  | -			clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, | 
|---|
| 221 |  | -					CONTROL_REGISTER_W1C_MASK, | 
|---|
| 222 |  | -					CTRL_UTMI_PHY_EN); | 
|---|
|  | 270 | +		if (pdata->have_sysif_regs) { | 
|---|
|  | 271 | +			tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); | 
|---|
|  | 272 | +			tmp &= ~CONTROL_REGISTER_W1C_MASK; | 
|---|
|  | 273 | +			tmp |= CTRL_UTMI_PHY_EN; | 
|---|
|  | 274 | +			iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); | 
|---|
|  | 275 | +		} | 
|---|
| 223 | 276 | portsc |= PORT_PTS_UTMI; | 
|---|
| 224 | 277 | break; | 
|---|
| 225 | 278 | case FSL_USB2_PHY_NONE: | 
|---|
| 226 | 279 | break; | 
|---|
| 227 | 280 | } | 
|---|
| 228 | 281 |  | 
|---|
| 229 |  | -	/* | 
|---|
| 230 |  | -	 * check PHY_CLK_VALID to determine phy clock presence before writing | 
|---|
| 231 |  | -	 * to portsc | 
|---|
| 232 |  | -	 */ | 
|---|
| 233 |  | -	if (pdata->check_phy_clk_valid) { | 
|---|
| 234 |  | -		if (!(ioread32be(non_ehci + FSL_SOC_USB_CTRL) & | 
|---|
| 235 |  | -		    PHY_CLK_VALID)) { | 
|---|
| 236 |  | -			dev_warn(hcd->self.controller, | 
|---|
| 237 |  | -				 "USB PHY clock invalid\n"); | 
|---|
| 238 |  | -			return -EINVAL; | 
|---|
| 239 |  | -		} | 
|---|
|  | 282 | +	if (pdata->have_sysif_regs && | 
|---|
|  | 283 | +	    pdata->controller_ver > FSL_USB_VER_1_6 && | 
|---|
|  | 284 | +	    !usb_phy_clk_valid(hcd)) { | 
|---|
|  | 285 | +		dev_warn(hcd->self.controller, "USB PHY clock invalid\n"); | 
|---|
|  | 286 | +		return -EINVAL; | 
|---|
| 240 | 287 | } | 
|---|
| 241 | 288 |  | 
|---|
| 242 | 289 | ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); | 
|---|
| 243 | 290 |  | 
|---|
| 244 |  | -	if (phy_mode != FSL_USB2_PHY_ULPI && pdata->have_sysif_regs) | 
|---|
| 245 |  | -		clrsetbits_be32(non_ehci + FSL_SOC_USB_CTRL, | 
|---|
| 246 |  | -				CONTROL_REGISTER_W1C_MASK, USB_CTRL_USB_EN); | 
|---|
|  | 291 | +	if (phy_mode != FSL_USB2_PHY_ULPI && pdata->have_sysif_regs) { | 
|---|
|  | 292 | +		tmp = ioread32be(non_ehci + FSL_SOC_USB_CTRL); | 
|---|
|  | 293 | +		tmp &= ~CONTROL_REGISTER_W1C_MASK; | 
|---|
|  | 294 | +		tmp |= USB_CTRL_USB_EN; | 
|---|
|  | 295 | +		iowrite32be(tmp, non_ehci + FSL_SOC_USB_CTRL); | 
|---|
|  | 296 | +	} | 
|---|
| 247 | 297 |  | 
|---|
| 248 | 298 | return 0; | 
|---|
| 249 | 299 | } | 
|---|
| .. | .. | 
|---|
| 284 | 334 | return -EINVAL; | 
|---|
| 285 | 335 |  | 
|---|
| 286 | 336 | if (pdata->operating_mode == FSL_USB2_MPH_HOST) { | 
|---|
| 287 |  | -		unsigned int chip, rev, svr; | 
|---|
| 288 |  | - | 
|---|
| 289 |  | -		svr = mfspr(SPRN_SVR); | 
|---|
| 290 |  | -		chip = svr >> 16; | 
|---|
| 291 |  | -		rev = (svr >> 4) & 0xf; | 
|---|
| 292 | 337 |  | 
|---|
| 293 | 338 | /* Deal with USB Erratum #14 on MPC834x Rev 1.0 & 1.1 chips */ | 
|---|
| 294 |  | -		if ((rev == 1) && (chip >= 0x8050) && (chip <= 0x8055)) | 
|---|
|  | 339 | +		if (pdata->has_fsl_erratum_14 == 1) | 
|---|
| 295 | 340 | ehci->has_fsl_port_bug = 1; | 
|---|
| 296 | 341 |  | 
|---|
| 297 | 342 | if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) | 
|---|
| .. | .. | 
|---|
| 638 | 683 |  | 
|---|
| 639 | 684 | /** | 
|---|
| 640 | 685 | * fsl_ehci_drv_remove - shutdown processing for FSL-based HCDs | 
|---|
| 641 |  | - * @dev: USB Host Controller being removed | 
|---|
|  | 686 | + * @pdev: USB Host Controller being removed | 
|---|
| 642 | 687 | * Context: !in_interrupt() | 
|---|
| 643 | 688 | * | 
|---|
| 644 | 689 | * Reverses the effect of usb_hcd_fsl_probe(). | 
|---|