sunxi: ehci: Convert to the driver-model
Convert sunxi-boards which use the sunxi-ehci code to the driver-model. Signed-off-by: Hans de Goede <hdegoede@redhat.com> Acked-by: Simon Glass <sjg@chromium.org> Acked-by: Ian Campbell <ijc@hellion.org.uk>
This commit is contained in:
		
							parent
							
								
									58b4048f64
								
							
						
					
					
						commit
						8d837a1f7d
					
				|  | @ -556,4 +556,7 @@ config DM_ETH | ||||||
| config DM_SERIAL | config DM_SERIAL | ||||||
| 	default y | 	default y | ||||||
| 
 | 
 | ||||||
|  | config DM_USB | ||||||
|  | 	default y if !USB_MUSB_SUNXI | ||||||
|  | 
 | ||||||
| endif | endif | ||||||
|  |  | ||||||
|  | @ -14,53 +14,88 @@ | ||||||
| #include <asm/arch/clock.h> | #include <asm/arch/clock.h> | ||||||
| #include <asm/arch/usb_phy.h> | #include <asm/arch/usb_phy.h> | ||||||
| #include <asm/io.h> | #include <asm/io.h> | ||||||
|  | #include <dm.h> | ||||||
| #include "ehci.h" | #include "ehci.h" | ||||||
| 
 | 
 | ||||||
| int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, | struct ehci_sunxi_priv { | ||||||
| 		struct ehci_hcor **hcor) | 	struct ehci_ctrl ehci; | ||||||
|  | 	int ahb_gate_mask; /* Mask of ahb_gate0 clk gate bits for this hcd */ | ||||||
|  | 	int phy_index;     /* Index of the usb-phy attached to this hcd */ | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static int ehci_usb_probe(struct udevice *dev) | ||||||
| { | { | ||||||
| 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; | 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; | ||||||
| 	int ahb_gate_offset; | 	struct usb_platdata *plat = dev_get_platdata(dev); | ||||||
|  | 	struct ehci_sunxi_priv *priv = dev_get_priv(dev); | ||||||
|  | 	struct ehci_hccr *hccr = (struct ehci_hccr *)dev_get_addr(dev); | ||||||
|  | 	struct ehci_hcor *hcor; | ||||||
| 
 | 
 | ||||||
| 	ahb_gate_offset = index ? AHB_GATE_OFFSET_USB_EHCI1 : | 	/*
 | ||||||
| 				  AHB_GATE_OFFSET_USB_EHCI0; | 	 * This should go away once we've moved to the driver model for | ||||||
| 	setbits_le32(&ccm->ahb_gate0, 1 << ahb_gate_offset); | 	 * clocks resp. phys. | ||||||
|  | 	 */ | ||||||
|  | 	if (hccr == (void *)SUNXI_USB1_BASE) { | ||||||
|  | 		priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0; | ||||||
|  | 		priv->phy_index = 1; | ||||||
|  | 	} else { | ||||||
|  | 		priv->ahb_gate_mask = 1 << AHB_GATE_OFFSET_USB_EHCI1; | ||||||
|  | 		priv->phy_index = 2; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	setbits_le32(&ccm->ahb_gate0, priv->ahb_gate_mask); | ||||||
| #ifdef CONFIG_SUNXI_GEN_SUN6I | #ifdef CONFIG_SUNXI_GEN_SUN6I | ||||||
| 	setbits_le32(&ccm->ahb_reset0_cfg, 1 << ahb_gate_offset); | 	setbits_le32(&ccm->ahb_reset0_cfg, priv->ahb_gate_mask); | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| 	sunxi_usb_phy_init(index + 1); | 	sunxi_usb_phy_init(priv->phy_index); | ||||||
| 	sunxi_usb_phy_power_on(index + 1); | 	sunxi_usb_phy_power_on(priv->phy_index); | ||||||
| 
 | 
 | ||||||
| 	if (index == 0) | 	hcor = (struct ehci_hcor *)((uint32_t)hccr + | ||||||
| 		*hccr = (void *)SUNXI_USB1_BASE; | 				    HC_LENGTH(ehci_readl(&hccr->cr_capbase))); | ||||||
| 	else |  | ||||||
| 		*hccr = (void *)SUNXI_USB2_BASE; |  | ||||||
| 
 | 
 | ||||||
| 	*hcor = (struct ehci_hcor *)((uint32_t) *hccr | 	return ehci_register(dev, hccr, hcor, NULL, 0, plat->init_type); | ||||||
| 				+ HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); | } | ||||||
| 
 | 
 | ||||||
| 	debug("sunxi-ehci: init hccr %x and hcor %x hc_length %d\n", | static int ehci_usb_remove(struct udevice *dev) | ||||||
| 	      (uint32_t)*hccr, (uint32_t)*hcor, | { | ||||||
| 	      (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); | 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; | ||||||
|  | 	struct ehci_sunxi_priv *priv = dev_get_priv(dev); | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	ret = ehci_deregister(dev); | ||||||
|  | 	if (ret) | ||||||
|  | 		return ret; | ||||||
|  | 
 | ||||||
|  | 	sunxi_usb_phy_power_off(priv->phy_index); | ||||||
|  | 	sunxi_usb_phy_exit(priv->phy_index); | ||||||
|  | 
 | ||||||
|  | #ifdef CONFIG_SUNXI_GEN_SUN6I | ||||||
|  | 	clrbits_le32(&ccm->ahb_reset0_cfg, priv->ahb_gate_mask); | ||||||
|  | #endif | ||||||
|  | 	clrbits_le32(&ccm->ahb_gate0, priv->ahb_gate_mask); | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int ehci_hcd_stop(int index) | static const struct udevice_id ehci_usb_ids[] = { | ||||||
| { | 	{ .compatible = "allwinner,sun4i-a10-ehci", }, | ||||||
| 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; | 	{ .compatible = "allwinner,sun5i-a13-ehci", }, | ||||||
| 	int ahb_gate_offset; | 	{ .compatible = "allwinner,sun6i-a31-ehci", }, | ||||||
|  | 	{ .compatible = "allwinner,sun7i-a20-ehci", }, | ||||||
|  | 	{ .compatible = "allwinner,sun8i-a23-ehci", }, | ||||||
|  | 	{ .compatible = "allwinner,sun9i-a80-ehci", }, | ||||||
|  | 	{ } | ||||||
|  | }; | ||||||
| 
 | 
 | ||||||
| 	sunxi_usb_phy_power_off(index + 1); | U_BOOT_DRIVER(usb_ehci) = { | ||||||
| 	sunxi_usb_phy_exit(index + 1); | 	.name	= "ehci_sunxi", | ||||||
| 
 | 	.id	= UCLASS_USB, | ||||||
| 	ahb_gate_offset = index ? AHB_GATE_OFFSET_USB_EHCI1 : | 	.of_match = ehci_usb_ids, | ||||||
| 				  AHB_GATE_OFFSET_USB_EHCI0; | 	.probe = ehci_usb_probe, | ||||||
| #ifdef CONFIG_SUNXI_GEN_SUN6I | 	.remove = ehci_usb_remove, | ||||||
| 	clrbits_le32(&ccm->ahb_reset0_cfg, 1 << ahb_gate_offset); | 	.ops	= &ehci_usb_ops, | ||||||
| #endif | 	.platdata_auto_alloc_size = sizeof(struct usb_platdata), | ||||||
| 	clrbits_le32(&ccm->ahb_gate0, 1 << ahb_gate_offset); | 	.priv_auto_alloc_size = sizeof(struct ehci_sunxi_priv), | ||||||
| 
 | 	.flags	= DM_FLAG_ALLOC_PRIV_DMA, | ||||||
| 	return 0; | }; | ||||||
| } |  | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue