From b59889bf344dd261b50d69a5eacfa2874573c7cd Mon Sep 17 00:00:00 2001 From: Pratyush Yadav Date: Tue, 26 May 2020 17:35:57 +0530 Subject: regmap: Check for out-of-range offsets before mapping them In regmap_raw_{read,write}_range(), offsets are checked to make sure they aren't out of range. But this check happens _after_ the address is mapped from physical memory. Input should be sanity-checked before using it. Mapping the address before validating it leaves the door open to passing an invalid address to map_physmem(). So check for out of range offsets _before_ mapping them. This fixes a segmentation fault in sandbox when -1 is used as an offset to regmap_{read,write}(). Signed-off-by: Pratyush Yadav --- drivers/core/regmap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c index 4a214eff7cc..a67a237b88f 100644 --- a/drivers/core/regmap.c +++ b/drivers/core/regmap.c @@ -310,13 +310,13 @@ int regmap_raw_read_range(struct regmap *map, uint range_num, uint offset, } range = &map->ranges[range_num]; - ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE); - if (offset + val_len > range->size) { debug("%s: offset/size combination invalid\n", __func__); return -ERANGE; } + ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE); + switch (val_len) { case REGMAP_SIZE_8: *((u8 *)valp) = __read_8(ptr, map->endianness); @@ -419,13 +419,13 @@ int regmap_raw_write_range(struct regmap *map, uint range_num, uint offset, } range = &map->ranges[range_num]; - ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE); - if (offset + val_len > range->size) { debug("%s: offset/size combination invalid\n", __func__); return -ERANGE; } + ptr = map_physmem(range->start + offset, val_len, MAP_NOCACHE); + switch (val_len) { case REGMAP_SIZE_8: __write_8(ptr, val, map->endianness); -- cgit v1.3.1 From c03b7612ea346ad7454086d1623fb57098faf315 Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Tue, 2 Jun 2020 01:47:07 +0200 Subject: usb: provide a device tree node to USB devices It is possible to specify a device tree node for an USB device. This is useful if you have a static USB setup and want to use aliases which point to these nodes, like on the Raspberry Pi. The nodes are matched against their hub port number, the compatible strings are not matched for now. Signed-off-by: Michael Walle Reviewed-by: Marek Vasut Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 9 +++++++++ drivers/usb/host/usb-uclass.c | 41 ++++++++++++++++++++++++++++++++++++----- test/dm/usb.c | 22 ++++++++++++++++++++++ 3 files changed, 67 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index 5ce5e284764..b9255e4593e 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -810,6 +810,8 @@ hub { compatible = "usb-hub"; usb,device-class = <9>; + #address-cells = <1>; + #size-cells = <0>; hub-emul { compatible = "sandbox,usb-hub"; #address-cells = <1>; @@ -838,6 +840,13 @@ }; }; + + usbstor@1 { + reg = <1>; + }; + usbstor@3 { + reg = <3>; + }; }; }; diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c index cb79dfbbd5b..f42c0625cbf 100644 --- a/drivers/usb/host/usb-uclass.c +++ b/drivers/usb/host/usb-uclass.c @@ -494,6 +494,35 @@ static int usb_match_one_id(struct usb_device_descriptor *desc, return usb_match_one_id_intf(desc, int_desc, id); } +static ofnode usb_get_ofnode(struct udevice *hub, int port) +{ + ofnode node; + u32 reg; + + if (!dev_has_of_node(hub)) + return ofnode_null(); + + /* + * The USB controller and its USB hub are two different udevices, + * but the device tree has only one node for both. Thus we are + * assigning this node to both udevices. + * If port is zero, the controller scans its root hub, thus we + * are using the same ofnode as the controller here. + */ + if (!port) + return dev_ofnode(hub); + + ofnode_for_each_subnode(node, dev_ofnode(hub)) { + if (ofnode_read_u32(node, "reg", ®)) + continue; + + if (reg == port) + return node; + } + + return ofnode_null(); +} + /** * usb_find_and_bind_driver() - Find and bind the right USB driver * @@ -502,13 +531,14 @@ static int usb_match_one_id(struct usb_device_descriptor *desc, static int usb_find_and_bind_driver(struct udevice *parent, struct usb_device_descriptor *desc, struct usb_interface_descriptor *iface, - int bus_seq, int devnum, + int bus_seq, int devnum, int port, struct udevice **devp) { struct usb_driver_entry *start, *entry; int n_ents; int ret; char name[30], *str; + ofnode node = usb_get_ofnode(parent, port); *devp = NULL; debug("%s: Searching for driver\n", __func__); @@ -533,8 +563,8 @@ static int usb_find_and_bind_driver(struct udevice *parent, * find another driver. For now this doesn't seem * necesssary, so just bind the first match. */ - ret = device_bind(parent, drv, drv->name, NULL, -1, - &dev); + ret = device_bind_ofnode(parent, drv, drv->name, NULL, + node, &dev); if (ret) goto error; debug("%s: Match found: %s\n", __func__, drv->name); @@ -651,9 +681,10 @@ int usb_scan_device(struct udevice *parent, int port, if (ret) { if (ret != -ENOENT) return ret; - ret = usb_find_and_bind_driver(parent, &udev->descriptor, iface, + ret = usb_find_and_bind_driver(parent, &udev->descriptor, + iface, udev->controller_dev->seq, - udev->devnum, &dev); + udev->devnum, port, &dev); if (ret) return ret; created = true; diff --git a/test/dm/usb.c b/test/dm/usb.c index a25c2c14820..b273a515efd 100644 --- a/test/dm/usb.c +++ b/test/dm/usb.c @@ -78,6 +78,28 @@ static int dm_test_usb_multi(struct unit_test_state *uts) } DM_TEST(dm_test_usb_multi, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); +/* test that we have an associated ofnode with the usb device */ +static int dm_test_usb_fdt_node(struct unit_test_state *uts) +{ + struct udevice *dev; + ofnode node; + + state_set_skip_delays(true); + ut_assertok(usb_init()); + ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev)); + node = ofnode_path("/usb@1/hub/usbstor@1"); + ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev))); + ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 1, &dev)); + ut_asserteq(1, ofnode_equal(ofnode_null(), dev_ofnode(dev))); + ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 2, &dev)); + node = ofnode_path("/usb@1/hub/usbstor@3"); + ut_asserteq(1, ofnode_equal(node, dev_ofnode(dev))); + ut_assertok(usb_stop()); + + return 0; +} +DM_TEST(dm_test_usb_fdt_node, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); + static int count_usb_devices(void) { struct udevice *hub; -- cgit v1.3.1 From be1a6e94254af205bd67d69e3bdb26b161ccd72f Mon Sep 17 00:00:00 2001 From: Michael Walle Date: Tue, 2 Jun 2020 01:47:09 +0200 Subject: dm: uclass: don't assign aliased seq numbers If there are aliases for an uclass, set the base for the "dynamically" allocated numbers next to the highest alias. Please note, that this might lead to holes in the sequences, depending on the device tree. For example if there is only an alias "ethernet1", the next device seq number would be 2. In particular this fixes a problem with boards which are using ethernet aliases but also might have network add-in cards like the E1000. If the board is started with the add-in card and depending on the order of the drivers, the E1000 might occupy the first ethernet device and mess up all the hardware addresses, because the devices are now shifted by one. Also adapt the test cases to the new handling and add test cases checking the holes in the seq numbers. Signed-off-by: Michael Walle Reviewed-by: Alex Marginean Tested-by: Alex Marginean Acked-by: Vladimir Oltean Reviewed-by: Simon Glass Tested-by: Michal Simek [on zcu102-revA] --- arch/sandbox/dts/test.dts | 4 ++-- drivers/core/uclass.c | 21 +++++++++++++++------ include/configs/sandbox.h | 6 +++--- test/dm/eth.c | 14 +++++++------- test/dm/test-fdt.c | 22 +++++++++++++++++----- 5 files changed, 44 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index b9255e4593e..a6e2bfd082f 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -23,8 +23,8 @@ pci0 = &pci0; pci1 = &pci1; pci2 = &pci2; - remoteproc1 = &rproc_1; - remoteproc2 = &rproc_2; + remoteproc0 = &rproc_1; + remoteproc1 = &rproc_2; rtc0 = &rtc_0; rtc1 = &rtc_1; spi0 = "/spi@0"; diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index 2ab419cfe4d..c3f1b73cd6b 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -689,13 +689,14 @@ int uclass_unbind_device(struct udevice *dev) int uclass_resolve_seq(struct udevice *dev) { + struct uclass *uc = dev->uclass; + struct uclass_driver *uc_drv = uc->uc_drv; struct udevice *dup; - int seq; + int seq = 0; int ret; assert(dev->seq == -1); - ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, dev->req_seq, - false, &dup); + ret = uclass_find_device_by_seq(uc_drv->id, dev->req_seq, false, &dup); if (!ret) { dm_warn("Device '%s': seq %d is in use by '%s'\n", dev->name, dev->req_seq, dup->name); @@ -707,9 +708,17 @@ int uclass_resolve_seq(struct udevice *dev) return ret; } - for (seq = 0; seq < DM_MAX_SEQ; seq++) { - ret = uclass_find_device_by_seq(dev->uclass->uc_drv->id, seq, - false, &dup); + if (CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_SEQ_ALIAS) && + (uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) { + /* + * dev_read_alias_highest_id() will return -1 if there no + * alias. Thus we can always add one. + */ + seq = dev_read_alias_highest_id(uc_drv->name) + 1; + } + + for (; seq < DM_MAX_SEQ; seq++) { + ret = uclass_find_device_by_seq(uc_drv->id, seq, false, &dup); if (ret == -ENODEV) break; if (ret) diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 2a81f3a9bc0..528187e1a68 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -94,9 +94,9 @@ #endif #define SANDBOX_ETH_SETTINGS "ethaddr=00:00:11:22:33:44\0" \ - "eth1addr=00:00:11:22:33:45\0" \ - "eth3addr=00:00:11:22:33:46\0" \ - "eth5addr=00:00:11:22:33:47\0" \ + "eth3addr=00:00:11:22:33:45\0" \ + "eth5addr=00:00:11:22:33:46\0" \ + "eth6addr=00:00:11:22:33:47\0" \ "ipaddr=1.2.3.4\0" #define MEM_LAYOUT_ENV_SETTINGS \ diff --git a/test/dm/eth.c b/test/dm/eth.c index 1fddcaabb09..b58c9640a27 100644 --- a/test/dm/eth.c +++ b/test/dm/eth.c @@ -48,7 +48,7 @@ static int dm_test_eth_alias(struct unit_test_state *uts) ut_assertok(net_loop(PING)); ut_asserteq_str("eth@10002000", env_get("ethact")); - env_set("ethact", "eth1"); + env_set("ethact", "eth6"); ut_assertok(net_loop(PING)); ut_asserteq_str("eth@10004000", env_get("ethact")); @@ -105,7 +105,7 @@ static int dm_test_eth_act(struct unit_test_state *uts) const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000", "sbe5", "eth@10004000"}; const char *addrname[DM_TEST_ETH_NUM] = {"ethaddr", "eth5addr", - "eth3addr", "eth1addr"}; + "eth3addr", "eth6addr"}; char ethaddr[DM_TEST_ETH_NUM][18]; int i; @@ -188,15 +188,15 @@ static int dm_test_eth_rotate(struct unit_test_state *uts) /* Invalidate eth1's MAC address */ memset(ethaddr, '\0', sizeof(ethaddr)); - strncpy(ethaddr, env_get("eth1addr"), 17); - /* Must disable access protection for eth1addr before clearing */ - env_set(".flags", "eth1addr"); - env_set("eth1addr", NULL); + strncpy(ethaddr, env_get("eth6addr"), 17); + /* Must disable access protection for eth6addr before clearing */ + env_set(".flags", "eth6addr"); + env_set("eth6addr", NULL); retval = _dm_test_eth_rotate1(uts); /* Restore the env */ - env_set("eth1addr", ethaddr); + env_set("eth6addr", ethaddr); env_set("ethrotate", NULL); if (!retval) { diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 4fcae03dc5b..51f25474094 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -361,20 +361,32 @@ static int dm_test_fdt_uclass_seq(struct unit_test_state *uts) ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 2, &dev)); ut_asserteq_str("d-test", dev->name); - /* d-test actually gets 0 */ - ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 0, &dev)); + /* + * d-test actually gets 9, because thats the next free one after the + * aliases. + */ + ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 9, &dev)); ut_asserteq_str("d-test", dev->name); - /* initially no one wants seq 1 */ - ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, + /* initially no one wants seq 10 */ + ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_TEST_FDT, 10, &dev)); ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 0, &dev)); ut_assertok(uclass_get_device(UCLASS_TEST_FDT, 4, &dev)); /* But now that it is probed, we can find it */ - ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 1, &dev)); + ut_assertok(uclass_get_device_by_seq(UCLASS_TEST_FDT, 10, &dev)); ut_asserteq_str("f-test", dev->name); + /* + * And we should still have holes in our sequence numbers, that is 2 + * and 4 should not be used. + */ + ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 2, + true, &dev)); + ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_TEST_FDT, 4, + true, &dev)); + return 0; } DM_TEST(dm_test_fdt_uclass_seq, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT); -- cgit v1.3.1 From baafd99d13931312ff3e2c1c75922d8a46222f7f Mon Sep 17 00:00:00 2001 From: Bryan O'Donoghue Date: Thu, 26 Mar 2020 03:54:01 +0000 Subject: net: phy: micrel: ksz8061 implement errata 80000688A fix Linux commit 232ba3a51cc2 ('net: phy: Micrel KSZ8061: link failure after cable connect') implements a fix for the above errata. This patch replicates that errata fix in an ksz8061 specific init routine. Signed-off-by: Bryan O'Donoghue Acked-by: Joe Hershberger --- drivers/net/phy/micrel_ksz8xxx.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/micrel_ksz8xxx.c b/drivers/net/phy/micrel_ksz8xxx.c index 98a0c83e68b..60d42fe9840 100644 --- a/drivers/net/phy/micrel_ksz8xxx.c +++ b/drivers/net/phy/micrel_ksz8xxx.c @@ -82,6 +82,21 @@ static struct phy_driver KSZ8051_driver = { .shutdown = &genphy_shutdown, }; +static int ksz8061_config(struct phy_device *phydev) +{ + return phy_write(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A); +} + +static struct phy_driver KSZ8061_driver = { + .name = "Micrel KSZ8061", + .uid = 0x00221570, + .mask = 0xfffff0, + .features = PHY_BASIC_FEATURES, + .config = &ksz8061_config, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + static int ksz8081_config(struct phy_device *phydev) { int ret; @@ -210,6 +225,7 @@ int phy_micrel_ksz8xxx_init(void) phy_register(&KSZ804_driver); phy_register(&KSZ8031_driver); phy_register(&KSZ8051_driver); + phy_register(&KSZ8061_driver); phy_register(&KSZ8081_driver); phy_register(&KS8721_driver); phy_register(&ksz8895_driver); -- cgit v1.3.1 From a7a435e7d41db6a611427b4cc5fd506a18fb2c2f Mon Sep 17 00:00:00 2001 From: Tom Warren Date: Thu, 26 Mar 2020 15:59:13 -0700 Subject: net: rt8169: WAR for DHCP not getting IP after kernel boot/reboot This is a WAR for DHCP failure after rebooting from the L4T kernel. The r8169.c kernel driver is setting bit 19 of the rt816x HW register 0xF0, which goes by FuncEvent and MISC in various driver source/datasheets. That bit is called RxDv_Gated_En in the r8169.c kernel driver. Clear it here at the end of probe to ensure that U-Boot can get an IP assigned via DHCP. Signed-off-by: Tom Warren --- drivers/net/rtl8169.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 75058fdadc0..fb4fae20e53 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -240,6 +240,9 @@ enum RTL8169_register_content { /*_TBICSRBit*/ TBILinkOK = 0x02000000, + + /* FuncEvent/Misc */ + RxDv_Gated_En = 0x80000, }; static struct { @@ -1210,6 +1213,19 @@ static int rtl8169_eth_probe(struct udevice *dev) return ret; } + /* + * WAR for DHCP failure after rebooting from kernel. + * Clear RxDv_Gated_En bit which was set by kernel driver. + * Without this, U-Boot can't get an IP via DHCP. + * Register (FuncEvent, aka MISC) and RXDV_GATED_EN bit are from + * the r8169.c kernel driver. + */ + + u32 val = RTL_R32(FuncEvent); + debug("%s: FuncEvent/Misc (0xF0) = 0x%08X\n", __func__, val); + val &= ~RxDv_Gated_En; + RTL_W32(FuncEvent, val); + return 0; } -- cgit v1.3.1 From 9c6de508a6362a3ddd4067e90f07ae613f312aa4 Mon Sep 17 00:00:00 2001 From: Florin Chiculita Date: Wed, 29 Apr 2020 14:25:48 +0300 Subject: net: phy: add phyid search in vendor specific space There are devices accesible through mdio clause-45, such as retimers, that do not have PMA or PCS blocks. This patch adds MDIO_MMD_VEND1 on the list of device addresses where phyid is searched. Previous order of devices was kept. Signed-off-by: Florin Chiculita Reviewed-by: Madalin Bucur --- drivers/net/phy/phy.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index cce09c47f9d..67789897c25 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -786,17 +786,27 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus, uint phy_mask, phy_interface_t interface) { - int i; struct phy_device *phydev; - + int devad[] = { + /* Clause-22 */ + MDIO_DEVAD_NONE, + /* Clause-45 */ + MDIO_MMD_PMAPMD, + MDIO_MMD_WIS, + MDIO_MMD_PCS, + MDIO_MMD_PHYXS, + MDIO_MMD_VEND1, + }; + int i, devad_cnt; + + devad_cnt = sizeof(devad)/sizeof(int); phydev = search_for_existing_phy(bus, phy_mask, interface); if (phydev) return phydev; - /* Try Standard (ie Clause 22) access */ - /* Otherwise we have to try Clause 45 */ - for (i = 0; i < 5; i++) { + /* try different access clauses */ + for (i = 0; i < devad_cnt; i++) { phydev = create_phy_by_mask(bus, phy_mask, - i ? i : MDIO_DEVAD_NONE, interface); + devad[i], interface); if (IS_ERR(phydev)) return NULL; if (phydev) -- cgit v1.3.1 From bc0e578f903d24b5291d34959ad534138ced0780 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Mon, 4 May 2020 16:14:39 -0500 Subject: net: phy: Add support for TI PHY init ti_phy_init function was allocated to the DP83867 PHY. This function name is to generic for a specific PHY. The function can be moved to a TI specific file that can register all TI PHYs that are defined in the defconfig. The ti_phy_init file will contain all TI PHYs initialization so that only phy_ti_init can be called from the framework. In addition to the above the config flag for the DP83867 needs to be changed in the Kconfig and dependent defconfig files. The config flag that was used for the DP83867 was also generic in nature so a more specific config flag for the DP83867 was created. Acked-by: Michal Simek Signed-off-by: Dan Murphy --- configs/am65x_evm_a53_defconfig | 2 +- configs/am65x_hs_evm_a53_defconfig | 2 +- configs/dra7xx_evm_defconfig | 2 +- configs/dra7xx_hs_evm_defconfig | 2 +- configs/dra7xx_hs_evm_usb_defconfig | 2 +- configs/j721e_evm_a72_defconfig | 2 +- configs/j721e_hs_evm_a72_defconfig | 2 +- configs/k2g_evm_defconfig | 2 +- configs/xilinx_versal_virt_defconfig | 2 +- configs/xilinx_zynqmp_virt_defconfig | 2 +- drivers/net/phy/Kconfig | 8 ++++++++ drivers/net/phy/Makefile | 3 ++- drivers/net/phy/dp83867.c | 3 ++- drivers/net/phy/ti_phy_init.c | 18 ++++++++++++++++++ drivers/net/phy/ti_phy_init.h | 15 +++++++++++++++ 15 files changed, 55 insertions(+), 12 deletions(-) create mode 100644 drivers/net/phy/ti_phy_init.c create mode 100644 drivers/net/phy/ti_phy_init.h (limited to 'drivers') diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig index d74a2d09309..c5ca4da73a8 100644 --- a/configs/am65x_evm_a53_defconfig +++ b/configs/am65x_evm_a53_defconfig @@ -99,7 +99,7 @@ CONFIG_SPI_FLASH_SFDP_SUPPORT=y CONFIG_SPI_FLASH_STMICRO=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_SPI_FLASH_MTD=y -CONFIG_PHY_TI=y +CONFIG_PHY_TI_DP83867=y CONFIG_PHY_FIXED=y CONFIG_DM_ETH=y CONFIG_E1000=y diff --git a/configs/am65x_hs_evm_a53_defconfig b/configs/am65x_hs_evm_a53_defconfig index 117953817d8..644873d67c7 100644 --- a/configs/am65x_hs_evm_a53_defconfig +++ b/configs/am65x_hs_evm_a53_defconfig @@ -101,7 +101,7 @@ CONFIG_SPI_FLASH_SFDP_SUPPORT=y CONFIG_SPI_FLASH_STMICRO=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_SPI_FLASH_MTD=y -CONFIG_PHY_TI=y +CONFIG_PHY_TI_DP83867=y CONFIG_PHY_FIXED=y CONFIG_DM_ETH=y CONFIG_E1000=y diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig index e4547d9dcc8..73ac3b319b5 100644 --- a/configs/dra7xx_evm_defconfig +++ b/configs/dra7xx_evm_defconfig @@ -86,7 +86,7 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=76800000 CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHY_TI=y +CONFIG_PHY_TI_DP83867=y CONFIG_DM_ETH=y CONFIG_PHY_GIGE=y CONFIG_MII=y diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig index c08bcce9038..40dc554e807 100644 --- a/configs/dra7xx_hs_evm_defconfig +++ b/configs/dra7xx_hs_evm_defconfig @@ -89,7 +89,7 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=76800000 CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHY_TI=y +CONFIG_PHY_TI_DP83867=y CONFIG_DM_ETH=y CONFIG_PHY_GIGE=y CONFIG_MII=y diff --git a/configs/dra7xx_hs_evm_usb_defconfig b/configs/dra7xx_hs_evm_usb_defconfig index 879c2b650be..babd7029c0e 100644 --- a/configs/dra7xx_hs_evm_usb_defconfig +++ b/configs/dra7xx_hs_evm_usb_defconfig @@ -87,7 +87,7 @@ CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=76800000 CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y -CONFIG_PHY_TI=y +CONFIG_PHY_TI_DP83867=y CONFIG_DM_ETH=y CONFIG_PHY_GIGE=y CONFIG_MII=y diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig index 4deb4e219fe..91a05722870 100644 --- a/configs/j721e_evm_a72_defconfig +++ b/configs/j721e_evm_a72_defconfig @@ -123,7 +123,7 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_SPI_FLASH_MTD=y -CONFIG_PHY_TI=y +CONFIG_PHY_TI_DP83867=y CONFIG_PHY_FIXED=y CONFIG_DM_ETH=y CONFIG_TI_AM65_CPSW_NUSS=y diff --git a/configs/j721e_hs_evm_a72_defconfig b/configs/j721e_hs_evm_a72_defconfig index ae540a26a40..9aa3113642c 100644 --- a/configs/j721e_hs_evm_a72_defconfig +++ b/configs/j721e_hs_evm_a72_defconfig @@ -113,7 +113,7 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_SPI_FLASH_MTD=y -CONFIG_PHY_TI=y +CONFIG_PHY_TI_DP83867=y CONFIG_PHY_FIXED=y CONFIG_DM_ETH=y CONFIG_TI_AM65_CPSW_NUSS=y diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig index 5bc7f7f8656..0379021c14c 100644 --- a/configs/k2g_evm_defconfig +++ b/configs/k2g_evm_defconfig @@ -58,7 +58,7 @@ CONFIG_PHYLIB=y CONFIG_PHY_MARVELL=y CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ8XXX=y -CONFIG_PHY_TI=y +CONFIG_PHY_TI_DP83867=y CONFIG_DM_ETH=y CONFIG_MII=y CONFIG_DRIVER_TI_KEYSTONE_NET=y diff --git a/configs/xilinx_versal_virt_defconfig b/configs/xilinx_versal_virt_defconfig index 4ed14f7030c..b3e21ea9037 100644 --- a/configs/xilinx_versal_virt_defconfig +++ b/configs/xilinx_versal_virt_defconfig @@ -63,7 +63,7 @@ CONFIG_SPI_FLASH_WINBOND=y CONFIG_PHY_MARVELL=y CONFIG_PHY_NATSEMI=y CONFIG_PHY_REALTEK=y -CONFIG_PHY_TI=y +CONFIG_PHY_TI_DP83867=y CONFIG_PHY_VITESSE=y CONFIG_PHY_FIXED=y CONFIG_PHY_GIGE=y diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 7886d5a38f2..2b4a0244fa9 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -108,7 +108,7 @@ CONFIG_PHY_MICREL=y CONFIG_PHY_MICREL_KSZ90X1=y CONFIG_PHY_NATSEMI=y CONFIG_PHY_REALTEK=y -CONFIG_PHY_TI=y +CONFIG_PHY_TI_DP83867=y CONFIG_PHY_VITESSE=y CONFIG_PHY_XILINX_GMII2RGMII=y CONFIG_PHY_FIXED=y diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index d1f049e62ab..a5a1ff257f9 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -243,6 +243,14 @@ config PHY_TERANETICS config PHY_TI bool "Texas Instruments Ethernet PHYs support" + ---help--- + Adds PHY registration support for TI PHYs. + +config PHY_TI_DP83867 + select PHY_TI + bool "Texas Instruments Ethernet DP83867 PHY support" + ---help--- + Adds support for the TI DP83867 1Gbit PHY. config PHY_VITESSE bool "Vitesse Ethernet PHYs support" diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 1d81516ecd1..6e722331f1b 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -25,7 +25,8 @@ obj-$(CONFIG_PHY_NATSEMI) += natsemi.o obj-$(CONFIG_PHY_REALTEK) += realtek.o obj-$(CONFIG_PHY_SMSC) += smsc.o obj-$(CONFIG_PHY_TERANETICS) += teranetics.o -obj-$(CONFIG_PHY_TI) += dp83867.o +obj-$(CONFIG_PHY_TI) += ti_phy_init.o +obj-$(CONFIG_PHY_TI_DP83867) += dp83867.o obj-$(CONFIG_PHY_XILINX) += xilinx_phy.o obj-$(CONFIG_PHY_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o obj-$(CONFIG_PHY_VITESSE) += vitesse.o diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index d435cc1e6c5..eada4541c9c 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -14,6 +14,7 @@ #include #include +#include "ti_phy_init.h" /* TI DP83867 */ #define DP83867_DEVADDR 0x1f @@ -430,7 +431,7 @@ static struct phy_driver DP83867_driver = { .shutdown = &genphy_shutdown, }; -int phy_ti_init(void) +int phy_dp83867_init(void) { phy_register(&DP83867_driver); return 0; diff --git a/drivers/net/phy/ti_phy_init.c b/drivers/net/phy/ti_phy_init.c new file mode 100644 index 00000000000..277b29a2634 --- /dev/null +++ b/drivers/net/phy/ti_phy_init.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * TI Generic PHY Init to register any TI Ethernet PHYs + * + * Author: Dan Murphy + * + * Copyright (C) 2019-20 Texas Instruments Inc. + */ + +#include "ti_phy_init.h" + +int phy_ti_init(void) +{ +#ifdef CONFIG_PHY_TI_DP83867 + phy_dp83867_init(); +#endif + return 0; +} diff --git a/drivers/net/phy/ti_phy_init.h b/drivers/net/phy/ti_phy_init.h new file mode 100644 index 00000000000..6c7f6c640a7 --- /dev/null +++ b/drivers/net/phy/ti_phy_init.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * TI Generic Ethernet PHY + * + * Author: Dan Murphy + * + * Copyright (C) 2019-20 Texas Instruments Inc. + */ + +#ifndef _TI_GEN_PHY_H +#define _TI_GEN_PHY_H + +int phy_dp83867_init(void); + +#endif /* _TI_GEN_PHY_H */ -- cgit v1.3.1 From 8882238cc4c1276629c989ea1fe71b15358a5040 Mon Sep 17 00:00:00 2001 From: Dan Murphy Date: Mon, 4 May 2020 16:14:40 -0500 Subject: net: phy: Add DP8382x phy registration to TI PHY init Add the DP8382X generic PHY registration to the TI PHY init file. Acked-by: Michal Simek Signed-off-by: Dan Murphy --- drivers/net/phy/Kconfig | 7 ++++ drivers/net/phy/ti_phy_init.c | 83 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index a5a1ff257f9..b0bd762ac39 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -252,6 +252,13 @@ config PHY_TI_DP83867 ---help--- Adds support for the TI DP83867 1Gbit PHY. +config PHY_TI_GENERIC + select PHY_TI + bool "Texas Instruments Generic Ethernet PHYs support" + ---help--- + Adds support for Generic TI PHYs that don't need special handling but + the PHY name is associated with a PHY ID. + config PHY_VITESSE bool "Vitesse Ethernet PHYs support" diff --git a/drivers/net/phy/ti_phy_init.c b/drivers/net/phy/ti_phy_init.c index 277b29a2634..50eff77692f 100644 --- a/drivers/net/phy/ti_phy_init.c +++ b/drivers/net/phy/ti_phy_init.c @@ -7,12 +7,95 @@ * Copyright (C) 2019-20 Texas Instruments Inc. */ +#include #include "ti_phy_init.h" +#ifdef CONFIG_PHY_TI_GENERIC +static struct phy_driver dp83822_driver = { + .name = "TI DP83822", + .uid = 0x2000a240, + .mask = 0xfffffff0, + .features = PHY_BASIC_FEATURES, + .config = &genphy_config_aneg, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +static struct phy_driver dp83826nc_driver = { + .name = "TI DP83826NC", + .uid = 0x2000a110, + .mask = 0xfffffff0, + .features = PHY_BASIC_FEATURES, + .config = &genphy_config_aneg, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +static struct phy_driver dp83826c_driver = { + .name = "TI DP83826C", + .uid = 0x2000a130, + .mask = 0xfffffff0, + .features = PHY_BASIC_FEATURES, + .config = &genphy_config_aneg, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +static struct phy_driver dp83825s_driver = { + .name = "TI DP83825S", + .uid = 0x2000a140, + .mask = 0xfffffff0, + .features = PHY_BASIC_FEATURES, + .config = &genphy_config_aneg, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +static struct phy_driver dp83825i_driver = { + .name = "TI DP83825I", + .uid = 0x2000a150, + .mask = 0xfffffff0, + .features = PHY_BASIC_FEATURES, + .config = &genphy_config_aneg, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +static struct phy_driver dp83825m_driver = { + .name = "TI DP83825M", + .uid = 0x2000a160, + .mask = 0xfffffff0, + .features = PHY_BASIC_FEATURES, + .config = &genphy_config_aneg, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +static struct phy_driver dp83825cs_driver = { + .name = "TI DP83825CS", + .uid = 0x2000a170, + .mask = 0xfffffff0, + .features = PHY_BASIC_FEATURES, + .config = &genphy_config_aneg, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; +#endif /* CONFIG_PHY_TI_GENERIC */ + int phy_ti_init(void) { #ifdef CONFIG_PHY_TI_DP83867 phy_dp83867_init(); #endif + +#ifdef CONFIG_PHY_TI_GENERIC + phy_register(&dp83822_driver); + phy_register(&dp83825s_driver); + phy_register(&dp83825i_driver); + phy_register(&dp83825m_driver); + phy_register(&dp83825cs_driver); + phy_register(&dp83826c_driver); + phy_register(&dp83826nc_driver); +#endif return 0; } -- cgit v1.3.1 From 9962dd25b1e228c5c8f0b33ef89c48093ca2a311 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2020 22:34:35 +0200 Subject: net: rtl8139: Factor out device name assignment Pull the device name setting into a separate function, as this will be shared between DM/non-DM variants. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 0daeefa489b..cc7fcdfea40 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -524,6 +524,11 @@ static int rtl8139_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, return 0; } +static void rtl8139_name(char *str, int card_number) +{ + sprintf(str, "RTL8139#%u", card_number); +} + static struct pci_device_id supported[] = { { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139 }, { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139 }, @@ -556,7 +561,7 @@ int rtl8139_initialize(bd_t *bis) } memset(dev, 0, sizeof(*dev)); - sprintf(dev->name, "RTL8139#%d", card_number); + rtl8139_name(dev->name, card_number); dev->priv = (void *)devno; dev->iobase = (int)bus_to_phys(iobase); -- cgit v1.3.1 From 1ba8d9844562c74f0d80423d5dac658291d6d2f1 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2020 22:34:36 +0200 Subject: net: rtl8139: Switch from malloc()+memset() to calloc() Replace malloc()+memset() combination with calloc(), no functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index cc7fcdfea40..4874c1aa4ff 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -554,12 +554,11 @@ int rtl8139_initialize(bd_t *bis) debug("rtl8139: REALTEK RTL8139 @0x%x\n", iobase); - dev = (struct eth_device *)malloc(sizeof(*dev)); + dev = calloc(1, sizeof(*dev)); if (!dev) { printf("Can not allocate memory of rtl8139\n"); break; } - memset(dev, 0, sizeof(*dev)); rtl8139_name(dev->name, card_number); -- cgit v1.3.1 From f4385539f1a6b4def6bf74091a2bc11f574d3bd1 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2020 22:34:37 +0200 Subject: net: rtl8139: Use dev->iobase instead of custom ioaddr Replace the use of custom static ioaddr variable with common dev->iobase, no functional change. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 84 +++++++++++++++++++++++---------------------------- 1 file changed, 38 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 4874c1aa4ff..f829e525212 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -192,7 +192,6 @@ #define RTL_STS_RXSTATUSOK BIT(0) static unsigned int cur_rx, cur_tx; -static int ioaddr; /* The RTL8139 can only transmit from a contiguous, aligned memory block. */ static unsigned char tx_buffer[TX_BUF_SIZE] __aligned(4); @@ -223,42 +222,43 @@ static void rtl8139_eeprom_delay(uintptr_t regbase) inl(regbase + RTL_REG_CFG9346); } -static int rtl8139_read_eeprom(unsigned int location, unsigned int addr_len) +static int rtl8139_read_eeprom(struct eth_device *dev, + unsigned int location, unsigned int addr_len) { unsigned int read_cmd = location | (EE_READ_CMD << addr_len); - uintptr_t ee_addr = ioaddr + RTL_REG_CFG9346; + uintptr_t ee_addr = dev->iobase + RTL_REG_CFG9346; unsigned int retval = 0; u8 dataval; int i; outb(EE_ENB & ~EE_CS, ee_addr); outb(EE_ENB, ee_addr); - rtl8139_eeprom_delay(ioaddr); + rtl8139_eeprom_delay(dev->iobase); /* Shift the read command bits out. */ for (i = 4 + addr_len; i >= 0; i--) { dataval = (read_cmd & BIT(i)) ? EE_DATA_WRITE : 0; outb(EE_ENB | dataval, ee_addr); - rtl8139_eeprom_delay(ioaddr); + rtl8139_eeprom_delay(dev->iobase); outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - rtl8139_eeprom_delay(ioaddr); + rtl8139_eeprom_delay(dev->iobase); } outb(EE_ENB, ee_addr); - rtl8139_eeprom_delay(ioaddr); + rtl8139_eeprom_delay(dev->iobase); for (i = 16; i > 0; i--) { outb(EE_ENB | EE_SHIFT_CLK, ee_addr); - rtl8139_eeprom_delay(ioaddr); + rtl8139_eeprom_delay(dev->iobase); retval <<= 1; retval |= inb(ee_addr) & EE_DATA_READ; outb(EE_ENB, ee_addr); - rtl8139_eeprom_delay(ioaddr); + rtl8139_eeprom_delay(dev->iobase); } /* Terminate the EEPROM access. */ outb(~EE_CS, ee_addr); - rtl8139_eeprom_delay(ioaddr); + rtl8139_eeprom_delay(dev->iobase); return retval; } @@ -275,10 +275,10 @@ static void rtl8139_set_rx_mode(struct eth_device *dev) RTL_REG_RXCONFIG_ACCEPTMULTICAST | RTL_REG_RXCONFIG_ACCEPTMYPHYS; - outl(rtl8139_rx_config | rx_mode, ioaddr + RTL_REG_RXCONFIG); + outl(rtl8139_rx_config | rx_mode, dev->iobase + RTL_REG_RXCONFIG); - outl(0xffffffff, ioaddr + RTL_REG_MAR0 + 0); - outl(0xffffffff, ioaddr + RTL_REG_MAR0 + 4); + outl(0xffffffff, dev->iobase + RTL_REG_MAR0 + 0); + outl(0xffffffff, dev->iobase + RTL_REG_MAR0 + 4); } static void rtl8139_hw_reset(struct eth_device *dev) @@ -286,11 +286,11 @@ static void rtl8139_hw_reset(struct eth_device *dev) u8 reg; int i; - outb(RTL_REG_CHIPCMD_CMDRESET, ioaddr + RTL_REG_CHIPCMD); + outb(RTL_REG_CHIPCMD_CMDRESET, dev->iobase + RTL_REG_CHIPCMD); /* Give the chip 10ms to finish the reset. */ for (i = 0; i < 100; i++) { - reg = inb(ioaddr + RTL_REG_CHIPCMD); + reg = inb(dev->iobase + RTL_REG_CHIPCMD); if (!(reg & RTL_REG_CHIPCMD_CMDRESET)) break; @@ -308,15 +308,15 @@ static void rtl8139_reset(struct eth_device *dev) rtl8139_hw_reset(dev); for (i = 0; i < ETH_ALEN; i++) - outb(dev->enetaddr[i], ioaddr + RTL_REG_MAC0 + i); + outb(dev->enetaddr[i], dev->iobase + RTL_REG_MAC0 + i); /* Must enable Tx/Rx before setting transfer thresholds! */ outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB, - ioaddr + RTL_REG_CHIPCMD); + dev->iobase + RTL_REG_CHIPCMD); /* accept no frames yet! */ - outl(rtl8139_rx_config, ioaddr + RTL_REG_RXCONFIG); - outl((TX_DMA_BURST << 8) | 0x03000000, ioaddr + RTL_REG_TXCONFIG); + outl(rtl8139_rx_config, dev->iobase + RTL_REG_RXCONFIG); + outl((TX_DMA_BURST << 8) | 0x03000000, dev->iobase + RTL_REG_TXCONFIG); /* * The Linux driver changes RTL_REG_CONFIG1 here to use a different @@ -331,7 +331,7 @@ static void rtl8139_reset(struct eth_device *dev) debug_cond(DEBUG_RX, "rx ring address is %p\n", rx_ring); flush_cache((unsigned long)rx_ring, RX_BUF_LEN); - outl(phys_to_bus((int)rx_ring), ioaddr + RTL_REG_RXBUF); + outl(phys_to_bus((int)rx_ring), dev->iobase + RTL_REG_RXBUF); /* * If we add multicast support, the RTL_REG_MAR0 register would have @@ -340,17 +340,17 @@ static void rtl8139_reset(struct eth_device *dev) * unicast. */ outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB, - ioaddr + RTL_REG_CHIPCMD); + dev->iobase + RTL_REG_CHIPCMD); - outl(rtl8139_rx_config, ioaddr + RTL_REG_RXCONFIG); + outl(rtl8139_rx_config, dev->iobase + RTL_REG_RXCONFIG); /* Start the chip's Tx and Rx process. */ - outl(0, ioaddr + RTL_REG_RXMISSED); + outl(0, dev->iobase + RTL_REG_RXMISSED); rtl8139_set_rx_mode(dev); /* Disable all known interrupts by setting the interrupt mask. */ - outw(0, ioaddr + RTL_REG_INTRMASK); + outw(0, dev->iobase + RTL_REG_INTRMASK); } static int rtl8139_send(struct eth_device *dev, void *packet, int length) @@ -360,8 +360,6 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length) unsigned int status; int i = 0; - ioaddr = dev->iobase; - memcpy(tx_buffer, packet, length); debug_cond(DEBUG_TX, "sending %d bytes\n", len); @@ -375,12 +373,12 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length) flush_cache((unsigned long)tx_buffer, length); outl(phys_to_bus((unsigned long)tx_buffer), - ioaddr + RTL_REG_TXADDR0 + cur_tx * 4); + dev->iobase + RTL_REG_TXADDR0 + cur_tx * 4); outl(((TX_FIFO_THRESH << 11) & 0x003f0000) | len, - ioaddr + RTL_REG_TXSTATUS0 + cur_tx * 4); + dev->iobase + RTL_REG_TXSTATUS0 + cur_tx * 4); do { - status = inw(ioaddr + RTL_REG_INTRSTATUS); + status = inw(dev->iobase + RTL_REG_INTRSTATUS); /* * Only acknlowledge interrupt sources we can properly * handle here - the RTL_REG_INTRSTATUS_RXOVERFLOW/ @@ -389,14 +387,14 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length) */ status &= RTL_REG_INTRSTATUS_TXOK | RTL_REG_INTRSTATUS_TXERR | RTL_REG_INTRSTATUS_PCIERR; - outw(status, ioaddr + RTL_REG_INTRSTATUS); + outw(status, dev->iobase + RTL_REG_INTRSTATUS); if (status) break; udelay(10); } while (i++ < RTL_TIMEOUT); - txstatus = inl(ioaddr + RTL_REG_TXSTATUS0 + cur_tx * 4); + txstatus = inl(dev->iobase + RTL_REG_TXSTATUS0 + cur_tx * 4); if (!(status & RTL_REG_INTRSTATUS_TXOK)) { debug_cond(DEBUG_TX, @@ -426,14 +424,12 @@ static int rtl8139_recv(struct eth_device *dev) unsigned int status; int length = 0; - ioaddr = dev->iobase; - - if (inb(ioaddr + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_RXBUFEMPTY) + if (inb(dev->iobase + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_RXBUFEMPTY) return 0; - status = inw(ioaddr + RTL_REG_INTRSTATUS); + status = inw(dev->iobase + RTL_REG_INTRSTATUS); /* See below for the rest of the interrupt acknowledges. */ - outw(status & ~rxstat, ioaddr + RTL_REG_INTRSTATUS); + outw(status & ~rxstat, dev->iobase + RTL_REG_INTRSTATUS); debug_cond(DEBUG_RX, "%s: int %hX ", __func__, status); @@ -474,13 +470,13 @@ static int rtl8139_recv(struct eth_device *dev) flush_cache((unsigned long)rx_ring, RX_BUF_LEN); cur_rx = ROUND(cur_rx + rx_size + 4, 4); - outw(cur_rx - 16, ioaddr + RTL_REG_RXBUFPTR); + outw(cur_rx - 16, dev->iobase + RTL_REG_RXBUFPTR); /* * See RTL8139 Programming Guide V0.1 for the official handling of * Rx overflow situations. The document itself contains basically * no usable information, except for a few exception handling rules. */ - outw(status & rxstat, ioaddr + RTL_REG_INTRSTATUS); + outw(status & rxstat, dev->iobase + RTL_REG_INTRSTATUS); return length; } @@ -491,18 +487,16 @@ static int rtl8139_init(struct eth_device *dev, bd_t *bis) int addr_len, i; u8 reg; - ioaddr = dev->iobase; - /* Bring the chip out of low-power mode. */ - outb(0x00, ioaddr + RTL_REG_CONFIG1); + outb(0x00, dev->iobase + RTL_REG_CONFIG1); - addr_len = rtl8139_read_eeprom(0, 8) == 0x8129 ? 8 : 6; + addr_len = rtl8139_read_eeprom(dev, 0, 8) == 0x8129 ? 8 : 6; for (i = 0; i < 3; i++) - *ap++ = le16_to_cpu(rtl8139_read_eeprom(i + 7, addr_len)); + *ap++ = le16_to_cpu(rtl8139_read_eeprom(dev, i + 7, addr_len)); rtl8139_reset(dev); - reg = inb(ioaddr + RTL_REG_MEDIASTATUS); + reg = inb(dev->iobase + RTL_REG_MEDIASTATUS); if (reg & RTL_REG_MEDIASTATUS_MSRLINKFAIL) { printf("Cable not connected or other link failure\n"); return -1; @@ -513,8 +507,6 @@ static int rtl8139_init(struct eth_device *dev, bd_t *bis) static void rtl8139_stop(struct eth_device *dev) { - ioaddr = dev->iobase; - rtl8139_hw_reset(dev); } -- cgit v1.3.1 From 8ff1d4a9c8e629253e43d9d04eccbfa773f81e83 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2020 22:34:38 +0200 Subject: net: rtl8139: Clean up bus_to_phys()/phys_to_bus() macros These macros depended on the dev variable being declared wherever they were used. This is wrong and will not work with DM anyway, so pass only the PCI BFD into these macros, which fixes the dependency and prepares them for DM support as well. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index f829e525212..aa137405424 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -96,8 +96,8 @@ #define DEBUG_TX 0 /* set to 1 to enable debug code */ #define DEBUG_RX 0 /* set to 1 to enable debug code */ -#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a) -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) +#define bus_to_phys(devno, a) pci_mem_to_phys((pci_dev_t)(devno), (a)) +#define phys_to_bus(devno, a) pci_phys_to_mem((pci_dev_t)(devno), (a)) /* Symbolic offsets to registers. */ /* Ethernet hardware address. */ @@ -331,7 +331,7 @@ static void rtl8139_reset(struct eth_device *dev) debug_cond(DEBUG_RX, "rx ring address is %p\n", rx_ring); flush_cache((unsigned long)rx_ring, RX_BUF_LEN); - outl(phys_to_bus((int)rx_ring), dev->iobase + RTL_REG_RXBUF); + outl(phys_to_bus(dev->priv, (int)rx_ring), dev->iobase + RTL_REG_RXBUF); /* * If we add multicast support, the RTL_REG_MAR0 register would have @@ -372,7 +372,7 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length) tx_buffer[len++] = '\0'; flush_cache((unsigned long)tx_buffer, length); - outl(phys_to_bus((unsigned long)tx_buffer), + outl(phys_to_bus(dev->priv, (unsigned long)tx_buffer), dev->iobase + RTL_REG_TXADDR0 + cur_tx * 4); outl(((TX_FIFO_THRESH << 11) & 0x003f0000) | len, dev->iobase + RTL_REG_TXSTATUS0 + cur_tx * 4); @@ -555,7 +555,7 @@ int rtl8139_initialize(bd_t *bis) rtl8139_name(dev->name, card_number); dev->priv = (void *)devno; - dev->iobase = (int)bus_to_phys(iobase); + dev->iobase = (unsigned long)bus_to_phys(devno, iobase); dev->init = rtl8139_init; dev->halt = rtl8139_stop; dev->send = rtl8139_send; -- cgit v1.3.1 From 3feb6f7ff6856e1e903e5a62f6252d37731b6592 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2020 22:34:39 +0200 Subject: net: rtl8139: Introduce device private data Introduce rtl8139_pdata, which is a super-structure around eth_device and tracks per-device state, here the device IO address, PCI BDF, RX and TX ring position. Pass this structure around instead of the old non-DM eth_device in preparation for DM conversion. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 136 +++++++++++++++++++++++++++++--------------------- 1 file changed, 78 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index aa137405424..dff77de06e5 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -191,7 +191,14 @@ #define RTL_STS_RXBADALIGN BIT(1) #define RTL_STS_RXSTATUSOK BIT(0) -static unsigned int cur_rx, cur_tx; +struct rtl8139_priv { + struct eth_device dev; + unsigned int cur_rx; + unsigned int cur_tx; + unsigned long ioaddr; + pci_dev_t devno; + unsigned char enetaddr[6]; +}; /* The RTL8139 can only transmit from a contiguous, aligned memory block. */ static unsigned char tx_buffer[TX_BUF_SIZE] __aligned(4); @@ -222,43 +229,43 @@ static void rtl8139_eeprom_delay(uintptr_t regbase) inl(regbase + RTL_REG_CFG9346); } -static int rtl8139_read_eeprom(struct eth_device *dev, +static int rtl8139_read_eeprom(struct rtl8139_priv *priv, unsigned int location, unsigned int addr_len) { unsigned int read_cmd = location | (EE_READ_CMD << addr_len); - uintptr_t ee_addr = dev->iobase + RTL_REG_CFG9346; + uintptr_t ee_addr = priv->ioaddr + RTL_REG_CFG9346; unsigned int retval = 0; u8 dataval; int i; outb(EE_ENB & ~EE_CS, ee_addr); outb(EE_ENB, ee_addr); - rtl8139_eeprom_delay(dev->iobase); + rtl8139_eeprom_delay(priv->ioaddr); /* Shift the read command bits out. */ for (i = 4 + addr_len; i >= 0; i--) { dataval = (read_cmd & BIT(i)) ? EE_DATA_WRITE : 0; outb(EE_ENB | dataval, ee_addr); - rtl8139_eeprom_delay(dev->iobase); + rtl8139_eeprom_delay(priv->ioaddr); outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - rtl8139_eeprom_delay(dev->iobase); + rtl8139_eeprom_delay(priv->ioaddr); } outb(EE_ENB, ee_addr); - rtl8139_eeprom_delay(dev->iobase); + rtl8139_eeprom_delay(priv->ioaddr); for (i = 16; i > 0; i--) { outb(EE_ENB | EE_SHIFT_CLK, ee_addr); - rtl8139_eeprom_delay(dev->iobase); + rtl8139_eeprom_delay(priv->ioaddr); retval <<= 1; retval |= inb(ee_addr) & EE_DATA_READ; outb(EE_ENB, ee_addr); - rtl8139_eeprom_delay(dev->iobase); + rtl8139_eeprom_delay(priv->ioaddr); } /* Terminate the EEPROM access. */ outb(~EE_CS, ee_addr); - rtl8139_eeprom_delay(dev->iobase); + rtl8139_eeprom_delay(priv->ioaddr); return retval; } @@ -268,29 +275,29 @@ static const unsigned int rtl8139_rx_config = (RX_FIFO_THRESH << 13) | (RX_DMA_BURST << 8); -static void rtl8139_set_rx_mode(struct eth_device *dev) +static void rtl8139_set_rx_mode(struct rtl8139_priv *priv) { /* !IFF_PROMISC */ unsigned int rx_mode = RTL_REG_RXCONFIG_ACCEPTBROADCAST | RTL_REG_RXCONFIG_ACCEPTMULTICAST | RTL_REG_RXCONFIG_ACCEPTMYPHYS; - outl(rtl8139_rx_config | rx_mode, dev->iobase + RTL_REG_RXCONFIG); + outl(rtl8139_rx_config | rx_mode, priv->ioaddr + RTL_REG_RXCONFIG); - outl(0xffffffff, dev->iobase + RTL_REG_MAR0 + 0); - outl(0xffffffff, dev->iobase + RTL_REG_MAR0 + 4); + outl(0xffffffff, priv->ioaddr + RTL_REG_MAR0 + 0); + outl(0xffffffff, priv->ioaddr + RTL_REG_MAR0 + 4); } -static void rtl8139_hw_reset(struct eth_device *dev) +static void rtl8139_hw_reset(struct rtl8139_priv *priv) { u8 reg; int i; - outb(RTL_REG_CHIPCMD_CMDRESET, dev->iobase + RTL_REG_CHIPCMD); + outb(RTL_REG_CHIPCMD_CMDRESET, priv->ioaddr + RTL_REG_CHIPCMD); /* Give the chip 10ms to finish the reset. */ for (i = 0; i < 100; i++) { - reg = inb(dev->iobase + RTL_REG_CHIPCMD); + reg = inb(priv->ioaddr + RTL_REG_CHIPCMD); if (!(reg & RTL_REG_CHIPCMD_CMDRESET)) break; @@ -298,25 +305,25 @@ static void rtl8139_hw_reset(struct eth_device *dev) } } -static void rtl8139_reset(struct eth_device *dev) +static void rtl8139_reset(struct rtl8139_priv *priv) { int i; - cur_rx = 0; - cur_tx = 0; + priv->cur_rx = 0; + priv->cur_tx = 0; - rtl8139_hw_reset(dev); + rtl8139_hw_reset(priv); for (i = 0; i < ETH_ALEN; i++) - outb(dev->enetaddr[i], dev->iobase + RTL_REG_MAC0 + i); + outb(priv->enetaddr[i], priv->ioaddr + RTL_REG_MAC0 + i); /* Must enable Tx/Rx before setting transfer thresholds! */ outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB, - dev->iobase + RTL_REG_CHIPCMD); + priv->ioaddr + RTL_REG_CHIPCMD); /* accept no frames yet! */ - outl(rtl8139_rx_config, dev->iobase + RTL_REG_RXCONFIG); - outl((TX_DMA_BURST << 8) | 0x03000000, dev->iobase + RTL_REG_TXCONFIG); + outl(rtl8139_rx_config, priv->ioaddr + RTL_REG_RXCONFIG); + outl((TX_DMA_BURST << 8) | 0x03000000, priv->ioaddr + RTL_REG_TXCONFIG); /* * The Linux driver changes RTL_REG_CONFIG1 here to use a different @@ -331,7 +338,7 @@ static void rtl8139_reset(struct eth_device *dev) debug_cond(DEBUG_RX, "rx ring address is %p\n", rx_ring); flush_cache((unsigned long)rx_ring, RX_BUF_LEN); - outl(phys_to_bus(dev->priv, (int)rx_ring), dev->iobase + RTL_REG_RXBUF); + outl(phys_to_bus(priv->devno, (int)rx_ring), priv->ioaddr + RTL_REG_RXBUF); /* * If we add multicast support, the RTL_REG_MAR0 register would have @@ -340,21 +347,22 @@ static void rtl8139_reset(struct eth_device *dev) * unicast. */ outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB, - dev->iobase + RTL_REG_CHIPCMD); + priv->ioaddr + RTL_REG_CHIPCMD); - outl(rtl8139_rx_config, dev->iobase + RTL_REG_RXCONFIG); + outl(rtl8139_rx_config, priv->ioaddr + RTL_REG_RXCONFIG); /* Start the chip's Tx and Rx process. */ - outl(0, dev->iobase + RTL_REG_RXMISSED); + outl(0, priv->ioaddr + RTL_REG_RXMISSED); - rtl8139_set_rx_mode(dev); + rtl8139_set_rx_mode(priv); /* Disable all known interrupts by setting the interrupt mask. */ - outw(0, dev->iobase + RTL_REG_INTRMASK); + outw(0, priv->ioaddr + RTL_REG_INTRMASK); } static int rtl8139_send(struct eth_device *dev, void *packet, int length) { + struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); unsigned int len = length; unsigned long txstatus; unsigned int status; @@ -372,13 +380,13 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length) tx_buffer[len++] = '\0'; flush_cache((unsigned long)tx_buffer, length); - outl(phys_to_bus(dev->priv, (unsigned long)tx_buffer), - dev->iobase + RTL_REG_TXADDR0 + cur_tx * 4); + outl(phys_to_bus(priv->devno, (unsigned long)tx_buffer), + priv->ioaddr + RTL_REG_TXADDR0 + priv->cur_tx * 4); outl(((TX_FIFO_THRESH << 11) & 0x003f0000) | len, - dev->iobase + RTL_REG_TXSTATUS0 + cur_tx * 4); + priv->ioaddr + RTL_REG_TXSTATUS0 + priv->cur_tx * 4); do { - status = inw(dev->iobase + RTL_REG_INTRSTATUS); + status = inw(priv->ioaddr + RTL_REG_INTRSTATUS); /* * Only acknlowledge interrupt sources we can properly * handle here - the RTL_REG_INTRSTATUS_RXOVERFLOW/ @@ -387,26 +395,26 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length) */ status &= RTL_REG_INTRSTATUS_TXOK | RTL_REG_INTRSTATUS_TXERR | RTL_REG_INTRSTATUS_PCIERR; - outw(status, dev->iobase + RTL_REG_INTRSTATUS); + outw(status, priv->ioaddr + RTL_REG_INTRSTATUS); if (status) break; udelay(10); } while (i++ < RTL_TIMEOUT); - txstatus = inl(dev->iobase + RTL_REG_TXSTATUS0 + cur_tx * 4); + txstatus = inl(priv->ioaddr + RTL_REG_TXSTATUS0 + priv->cur_tx * 4); if (!(status & RTL_REG_INTRSTATUS_TXOK)) { debug_cond(DEBUG_TX, "tx timeout/error (%d usecs), status %hX txstatus %lX\n", 10 * i, status, txstatus); - rtl8139_reset(dev); + rtl8139_reset(priv); return 0; } - cur_tx = (cur_tx + 1) % NUM_TX_DESC; + priv->cur_tx = (priv->cur_tx + 1) % NUM_TX_DESC; debug_cond(DEBUG_TX, "tx done, status %hX txstatus %lX\n", status, txstatus); @@ -416,6 +424,7 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length) static int rtl8139_recv(struct eth_device *dev) { + struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); const unsigned int rxstat = RTL_REG_INTRSTATUS_RXFIFOOVER | RTL_REG_INTRSTATUS_RXOVERFLOW | RTL_REG_INTRSTATUS_RXOK; @@ -424,16 +433,16 @@ static int rtl8139_recv(struct eth_device *dev) unsigned int status; int length = 0; - if (inb(dev->iobase + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_RXBUFEMPTY) + if (inb(priv->ioaddr + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_RXBUFEMPTY) return 0; - status = inw(dev->iobase + RTL_REG_INTRSTATUS); + status = inw(priv->ioaddr + RTL_REG_INTRSTATUS); /* See below for the rest of the interrupt acknowledges. */ - outw(status & ~rxstat, dev->iobase + RTL_REG_INTRSTATUS); + outw(status & ~rxstat, priv->ioaddr + RTL_REG_INTRSTATUS); debug_cond(DEBUG_RX, "%s: int %hX ", __func__, status); - ring_offs = cur_rx % RX_BUF_LEN; + ring_offs = priv->cur_rx % RX_BUF_LEN; /* ring_offs is guaranteed being 4-byte aligned */ rx_status = le32_to_cpu(*(unsigned int *)(rx_ring + ring_offs)); rx_size = rx_status >> 16; @@ -446,7 +455,7 @@ static int rtl8139_recv(struct eth_device *dev) (rx_size > ETH_FRAME_LEN + 4)) { printf("rx error %hX\n", rx_status); /* this clears all interrupts still pending */ - rtl8139_reset(dev); + rtl8139_reset(priv); return 0; } @@ -469,45 +478,51 @@ static int rtl8139_recv(struct eth_device *dev) } flush_cache((unsigned long)rx_ring, RX_BUF_LEN); - cur_rx = ROUND(cur_rx + rx_size + 4, 4); - outw(cur_rx - 16, dev->iobase + RTL_REG_RXBUFPTR); + priv->cur_rx = ROUND(priv->cur_rx + rx_size + 4, 4); + outw(priv->cur_rx - 16, priv->ioaddr + RTL_REG_RXBUFPTR); /* * See RTL8139 Programming Guide V0.1 for the official handling of * Rx overflow situations. The document itself contains basically * no usable information, except for a few exception handling rules. */ - outw(status & rxstat, dev->iobase + RTL_REG_INTRSTATUS); + outw(status & rxstat, priv->ioaddr + RTL_REG_INTRSTATUS); return length; } static int rtl8139_init(struct eth_device *dev, bd_t *bis) { - unsigned short *ap = (unsigned short *)dev->enetaddr; + struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); + unsigned short *ap = (unsigned short *)priv->enetaddr; int addr_len, i; u8 reg; /* Bring the chip out of low-power mode. */ - outb(0x00, dev->iobase + RTL_REG_CONFIG1); + outb(0x00, priv->ioaddr + RTL_REG_CONFIG1); - addr_len = rtl8139_read_eeprom(dev, 0, 8) == 0x8129 ? 8 : 6; + addr_len = rtl8139_read_eeprom(priv, 0, 8) == 0x8129 ? 8 : 6; for (i = 0; i < 3; i++) - *ap++ = le16_to_cpu(rtl8139_read_eeprom(dev, i + 7, addr_len)); + *ap++ = le16_to_cpu(rtl8139_read_eeprom(priv, i + 7, addr_len)); - rtl8139_reset(dev); + rtl8139_reset(priv); - reg = inb(dev->iobase + RTL_REG_MEDIASTATUS); + reg = inb(priv->ioaddr + RTL_REG_MEDIASTATUS); if (reg & RTL_REG_MEDIASTATUS_MSRLINKFAIL) { printf("Cable not connected or other link failure\n"); return -1; } + /* Non-DM compatibility */ + memcpy(priv->dev.enetaddr, priv->enetaddr, 6); + return 0; } static void rtl8139_stop(struct eth_device *dev) { - rtl8139_hw_reset(dev); + struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); + + rtl8139_hw_reset(priv); } static int rtl8139_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, @@ -529,6 +544,7 @@ static struct pci_device_id supported[] = { int rtl8139_initialize(bd_t *bis) { + struct rtl8139_priv *priv; struct eth_device *dev; int card_number = 0; pci_dev_t devno; @@ -546,16 +562,20 @@ int rtl8139_initialize(bd_t *bis) debug("rtl8139: REALTEK RTL8139 @0x%x\n", iobase); - dev = calloc(1, sizeof(*dev)); - if (!dev) { + priv = calloc(1, sizeof(*priv)); + if (!priv) { printf("Can not allocate memory of rtl8139\n"); break; } + priv->devno = devno; + priv->ioaddr = (unsigned long)bus_to_phys(devno, iobase); + + dev = &priv->dev; + rtl8139_name(dev->name, card_number); - dev->priv = (void *)devno; - dev->iobase = (unsigned long)bus_to_phys(devno, iobase); + dev->iobase = priv->ioaddr; /* Non-DM compatibility */ dev->init = rtl8139_init; dev->halt = rtl8139_stop; dev->send = rtl8139_send; -- cgit v1.3.1 From 26f59c28bdea91617b3acfd132d5affc55e1ef4a Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2020 22:34:40 +0200 Subject: net: rtl8139: Pass private data into rtl8139_eeprom_delay() Instead of always calling rtl8139_eeprom_delay() with priv->ioaddr, call it with priv and let the function access priv->ioaddr. This reduces code duplication and has no impact, since the compiler will inline this as needed anyway. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index dff77de06e5..ae5d1251ae6 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -220,13 +220,13 @@ static unsigned char rx_ring[RX_BUF_LEN + 16] __aligned(4); #define EE_READ_CMD 6 #define EE_ERASE_CMD 7 -static void rtl8139_eeprom_delay(uintptr_t regbase) +static void rtl8139_eeprom_delay(struct rtl8139_priv *priv) { /* * Delay between EEPROM clock transitions. * No extra delay is needed with 33MHz PCI, but 66MHz may change this. */ - inl(regbase + RTL_REG_CFG9346); + inl(priv->ioaddr + RTL_REG_CFG9346); } static int rtl8139_read_eeprom(struct rtl8139_priv *priv, @@ -240,32 +240,32 @@ static int rtl8139_read_eeprom(struct rtl8139_priv *priv, outb(EE_ENB & ~EE_CS, ee_addr); outb(EE_ENB, ee_addr); - rtl8139_eeprom_delay(priv->ioaddr); + rtl8139_eeprom_delay(priv); /* Shift the read command bits out. */ for (i = 4 + addr_len; i >= 0; i--) { dataval = (read_cmd & BIT(i)) ? EE_DATA_WRITE : 0; outb(EE_ENB | dataval, ee_addr); - rtl8139_eeprom_delay(priv->ioaddr); + rtl8139_eeprom_delay(priv); outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); - rtl8139_eeprom_delay(priv->ioaddr); + rtl8139_eeprom_delay(priv); } outb(EE_ENB, ee_addr); - rtl8139_eeprom_delay(priv->ioaddr); + rtl8139_eeprom_delay(priv); for (i = 16; i > 0; i--) { outb(EE_ENB | EE_SHIFT_CLK, ee_addr); - rtl8139_eeprom_delay(priv->ioaddr); + rtl8139_eeprom_delay(priv); retval <<= 1; retval |= inb(ee_addr) & EE_DATA_READ; outb(EE_ENB, ee_addr); - rtl8139_eeprom_delay(priv->ioaddr); + rtl8139_eeprom_delay(priv); } /* Terminate the EEPROM access. */ outb(~EE_CS, ee_addr); - rtl8139_eeprom_delay(priv->ioaddr); + rtl8139_eeprom_delay(priv); return retval; } -- cgit v1.3.1 From 6a4a5c194df8af25390f4ba30250a76fc0256643 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2020 22:34:41 +0200 Subject: net: rtl8139: Split out common and non-DM functions Split the driver into common and non-DM functionality, so that the DM support can later re-use the common code, while we retain the non-DM code until all the platforms are converted. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 92 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index ae5d1251ae6..70b09fb2d2f 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -193,6 +193,7 @@ struct rtl8139_priv { struct eth_device dev; + unsigned int rxstatus; unsigned int cur_rx; unsigned int cur_tx; unsigned long ioaddr; @@ -360,9 +361,9 @@ static void rtl8139_reset(struct rtl8139_priv *priv) outw(0, priv->ioaddr + RTL_REG_INTRMASK); } -static int rtl8139_send(struct eth_device *dev, void *packet, int length) +static int rtl8139_send_common(struct rtl8139_priv *priv, + void *packet, int length) { - struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); unsigned int len = length; unsigned long txstatus; unsigned int status; @@ -422,25 +423,24 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length) return length; } -static int rtl8139_recv(struct eth_device *dev) +static int rtl8139_recv_common(struct rtl8139_priv *priv, unsigned char *rxdata, + uchar **packetp) { - struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); const unsigned int rxstat = RTL_REG_INTRSTATUS_RXFIFOOVER | RTL_REG_INTRSTATUS_RXOVERFLOW | RTL_REG_INTRSTATUS_RXOK; unsigned int rx_size, rx_status; unsigned int ring_offs; - unsigned int status; int length = 0; if (inb(priv->ioaddr + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_RXBUFEMPTY) return 0; - status = inw(priv->ioaddr + RTL_REG_INTRSTATUS); + priv->rxstatus = inw(priv->ioaddr + RTL_REG_INTRSTATUS); /* See below for the rest of the interrupt acknowledges. */ - outw(status & ~rxstat, priv->ioaddr + RTL_REG_INTRSTATUS); + outw(priv->rxstatus & ~rxstat, priv->ioaddr + RTL_REG_INTRSTATUS); - debug_cond(DEBUG_RX, "%s: int %hX ", __func__, status); + debug_cond(DEBUG_RX, "%s: int %hX ", __func__, priv->rxstatus); ring_offs = priv->cur_rx % RX_BUF_LEN; /* ring_offs is guaranteed being 4-byte aligned */ @@ -462,20 +462,30 @@ static int rtl8139_recv(struct eth_device *dev) /* Received a good packet */ length = rx_size - 4; /* no one cares about the FCS */ if (ring_offs + 4 + rx_size - 4 > RX_BUF_LEN) { - unsigned char rxdata[RX_BUF_LEN]; int semi_count = RX_BUF_LEN - ring_offs - 4; memcpy(rxdata, rx_ring + ring_offs + 4, semi_count); memcpy(&rxdata[semi_count], rx_ring, rx_size - 4 - semi_count); - net_process_received_packet(rxdata, length); + *packetp = rxdata; debug_cond(DEBUG_RX, "rx packet %d+%d bytes", semi_count, rx_size - 4 - semi_count); } else { - net_process_received_packet(rx_ring + ring_offs + 4, length); + *packetp = rx_ring + ring_offs + 4; debug_cond(DEBUG_RX, "rx packet %d bytes", rx_size - 4); } + + return length; +} + +static int rtl8139_free_pkt_common(struct rtl8139_priv *priv, unsigned int len) +{ + const unsigned int rxstat = RTL_REG_INTRSTATUS_RXFIFOOVER | + RTL_REG_INTRSTATUS_RXOVERFLOW | + RTL_REG_INTRSTATUS_RXOK; + unsigned int rx_size = len + 4; + flush_cache((unsigned long)rx_ring, RX_BUF_LEN); priv->cur_rx = ROUND(priv->cur_rx + rx_size + 4, 4); @@ -485,14 +495,13 @@ static int rtl8139_recv(struct eth_device *dev) * Rx overflow situations. The document itself contains basically * no usable information, except for a few exception handling rules. */ - outw(status & rxstat, priv->ioaddr + RTL_REG_INTRSTATUS); + outw(priv->rxstatus & rxstat, priv->ioaddr + RTL_REG_INTRSTATUS); - return length; + return 0; } -static int rtl8139_init(struct eth_device *dev, bd_t *bis) +static int rtl8139_init_common(struct rtl8139_priv *priv) { - struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); unsigned short *ap = (unsigned short *)priv->enetaddr; int addr_len, i; u8 reg; @@ -518,19 +527,11 @@ static int rtl8139_init(struct eth_device *dev, bd_t *bis) return 0; } -static void rtl8139_stop(struct eth_device *dev) +static void rtl8139_stop_common(struct rtl8139_priv *priv) { - struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); - rtl8139_hw_reset(priv); } -static int rtl8139_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, - int join) -{ - return 0; -} - static void rtl8139_name(char *str, int card_number) { sprintf(str, "RTL8139#%u", card_number); @@ -542,6 +543,49 @@ static struct pci_device_id supported[] = { { } }; +static int rtl8139_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, + int join) +{ + return 0; +} + +static int rtl8139_init(struct eth_device *dev, bd_t *bis) +{ + struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); + + return rtl8139_init_common(priv); +} + +static void rtl8139_stop(struct eth_device *dev) +{ + struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); + + return rtl8139_stop_common(priv); +} + +static int rtl8139_send(struct eth_device *dev, void *packet, int length) +{ + struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); + + return rtl8139_send_common(priv, packet, length); +} + +static int rtl8139_recv(struct eth_device *dev) +{ + struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev); + unsigned char rxdata[RX_BUF_LEN]; + uchar *packet; + int ret; + + ret = rtl8139_recv_common(priv, rxdata, &packet); + if (ret) { + net_process_received_packet(packet, ret); + rtl8139_free_pkt_common(priv, ret); + } + + return ret; +} + int rtl8139_initialize(bd_t *bis) { struct rtl8139_priv *priv; -- cgit v1.3.1 From 2df3a51510758dc6208ecf36f5e4b929d01f2dd1 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2020 22:34:42 +0200 Subject: net: rtl8139: Use PCI_DEVICE() to define PCI device compat list Use this macro to fully fill the PCI device ID table. This is mandatory for the DM PCI support, which checks all the fields. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 70b09fb2d2f..f3190170d34 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -538,8 +538,8 @@ static void rtl8139_name(char *str, int card_number) } static struct pci_device_id supported[] = { - { PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139 }, - { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139 }, + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139) }, + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139) }, { } }; -- cgit v1.3.1 From d8afb8b28efb5af640d693e7f848732141482cfb Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2020 22:34:43 +0200 Subject: net: rtl8139: Read HW address from EEPROM only on probe Do not re-read the HW address from the EEPROM on every start of transfer, otherwise the user will not be able to adjust ethaddr as needed. Read the address only once, when the card is detected. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index f3190170d34..d7fabdbcf4a 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -502,17 +502,11 @@ static int rtl8139_free_pkt_common(struct rtl8139_priv *priv, unsigned int len) static int rtl8139_init_common(struct rtl8139_priv *priv) { - unsigned short *ap = (unsigned short *)priv->enetaddr; - int addr_len, i; u8 reg; /* Bring the chip out of low-power mode. */ outb(0x00, priv->ioaddr + RTL_REG_CONFIG1); - addr_len = rtl8139_read_eeprom(priv, 0, 8) == 0x8129 ? 8 : 6; - for (i = 0; i < 3; i++) - *ap++ = le16_to_cpu(rtl8139_read_eeprom(priv, i + 7, addr_len)); - rtl8139_reset(priv); reg = inb(priv->ioaddr + RTL_REG_MEDIASTATUS); @@ -521,9 +515,6 @@ static int rtl8139_init_common(struct rtl8139_priv *priv) return -1; } - /* Non-DM compatibility */ - memcpy(priv->dev.enetaddr, priv->enetaddr, 6); - return 0; } @@ -532,6 +523,19 @@ static void rtl8139_stop_common(struct rtl8139_priv *priv) rtl8139_hw_reset(priv); } +static void rtl8139_get_hwaddr(struct rtl8139_priv *priv) +{ + unsigned short *ap = (unsigned short *)priv->enetaddr; + int i, addr_len; + + /* Bring the chip out of low-power mode. */ + outb(0x00, priv->ioaddr + RTL_REG_CONFIG1); + + addr_len = rtl8139_read_eeprom(priv, 0, 8) == 0x8129 ? 8 : 6; + for (i = 0; i < 3; i++) + *ap++ = le16_to_cpu(rtl8139_read_eeprom(priv, i + 7, addr_len)); +} + static void rtl8139_name(char *str, int card_number) { sprintf(str, "RTL8139#%u", card_number); @@ -626,6 +630,11 @@ int rtl8139_initialize(bd_t *bis) dev->recv = rtl8139_recv; dev->mcast = rtl8139_bcast_addr; + rtl8139_get_hwaddr(priv); + + /* Non-DM compatibility */ + memcpy(priv->dev.enetaddr, priv->enetaddr, 6); + eth_register(dev); card_number++; -- cgit v1.3.1 From 46c8b18734d273619174006eef498639c06000d3 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 9 May 2020 22:34:44 +0200 Subject: net: rtl8139: Add DM support Add support for driver model to the driver. Signed-off-by: Marek Vasut Cc: Joe Hershberger --- drivers/net/rtl8139.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index d7fabdbcf4a..8a6f305893b 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -70,6 +70,7 @@ #include #include +#include #include #include #include @@ -96,8 +97,13 @@ #define DEBUG_TX 0 /* set to 1 to enable debug code */ #define DEBUG_RX 0 /* set to 1 to enable debug code */ +#ifdef CONFIG_DM_ETH +#define bus_to_phys(devno, a) dm_pci_mem_to_phys((devno), (a)) +#define phys_to_bus(devno, a) dm_pci_phys_to_mem((devno), (a)) +#else #define bus_to_phys(devno, a) pci_mem_to_phys((pci_dev_t)(devno), (a)) #define phys_to_bus(devno, a) pci_phys_to_mem((pci_dev_t)(devno), (a)) +#endif /* Symbolic offsets to registers. */ /* Ethernet hardware address. */ @@ -192,12 +198,16 @@ #define RTL_STS_RXSTATUSOK BIT(0) struct rtl8139_priv { +#ifndef CONFIG_DM_ETH struct eth_device dev; + pci_dev_t devno; +#else + struct udevice *devno; +#endif unsigned int rxstatus; unsigned int cur_rx; unsigned int cur_tx; unsigned long ioaddr; - pci_dev_t devno; unsigned char enetaddr[6]; }; @@ -547,6 +557,7 @@ static struct pci_device_id supported[] = { { } }; +#ifndef CONFIG_DM_ETH static int rtl8139_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, int join) { @@ -646,3 +657,123 @@ int rtl8139_initialize(bd_t *bis) return card_number; } +#else /* DM_ETH */ +static int rtl8139_start(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct rtl8139_priv *priv = dev_get_priv(dev); + + memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr)); + + return rtl8139_init_common(priv); +} + +static void rtl8139_stop(struct udevice *dev) +{ + struct rtl8139_priv *priv = dev_get_priv(dev); + + rtl8139_stop_common(priv); +} + +static int rtl8139_send(struct udevice *dev, void *packet, int length) +{ + struct rtl8139_priv *priv = dev_get_priv(dev); + int ret; + + ret = rtl8139_send_common(priv, packet, length); + + return ret ? 0 : -ETIMEDOUT; +} + +static int rtl8139_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct rtl8139_priv *priv = dev_get_priv(dev); + static unsigned char rxdata[RX_BUF_LEN]; + + return rtl8139_recv_common(priv, rxdata, packetp); +} + +static int rtl8139_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct rtl8139_priv *priv = dev_get_priv(dev); + + rtl8139_free_pkt_common(priv, length); + + return 0; +} + +static int rtl8139_write_hwaddr(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct rtl8139_priv *priv = dev_get_priv(dev); + + memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr)); + + rtl8139_reset(priv); + + return 0; +} + +static int rtl8139_read_rom_hwaddr(struct udevice *dev) +{ + struct rtl8139_priv *priv = dev_get_priv(dev); + + rtl8139_get_hwaddr(priv); + + return 0; +} + +static int rtl8139_bind(struct udevice *dev) +{ + static int card_number; + char name[16]; + + rtl8139_name(name, card_number++); + + return device_set_name(dev, name); +} + +static int rtl8139_probe(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct rtl8139_priv *priv = dev_get_priv(dev); + u32 iobase; + + dm_pci_read_config32(dev, PCI_BASE_ADDRESS_1, &iobase); + iobase &= ~0xf; + + debug("rtl8139: REALTEK RTL8139 @0x%x\n", iobase); + + priv->devno = dev; + priv->ioaddr = (unsigned long)bus_to_phys(dev, iobase); + + rtl8139_get_hwaddr(priv); + memcpy(plat->enetaddr, priv->enetaddr, sizeof(priv->enetaddr)); + + dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x20); + + return 0; +} + +static const struct eth_ops rtl8139_ops = { + .start = rtl8139_start, + .send = rtl8139_send, + .recv = rtl8139_recv, + .stop = rtl8139_stop, + .free_pkt = rtl8139_free_pkt, + .write_hwaddr = rtl8139_write_hwaddr, + .read_rom_hwaddr = rtl8139_read_rom_hwaddr, +}; + +U_BOOT_DRIVER(eth_rtl8139) = { + .name = "eth_rtl8139", + .id = UCLASS_ETH, + .bind = rtl8139_bind, + .probe = rtl8139_probe, + .ops = &rtl8139_ops, + .priv_auto_alloc_size = sizeof(struct rtl8139_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), +}; + +U_BOOT_PCI_DEVICE(eth_rtl8139, supported); +#endif -- cgit v1.3.1 From c78ae11e07d84c10ad5ee91593e49fcf20b07359 Mon Sep 17 00:00:00 2001 From: Faiz Abbas Date: Fri, 22 May 2020 07:32:28 +0530 Subject: mmc: davinci_mmc: Cleanup to use dt in U-boot and static platdata in SPL Cleanup this driver to use dt in U-boot and static platdata in SPL. This requires the following steps: 1. Move all platdata assignment from probe() to ofdata_to_platdata(). This function is only called in U-boot. 2. Replicate all the platdata assignment being done in ofdata_to_platdata() in the omapl138 board file. This data is used in the SPL case where SPL_OF_CONTROL is not enabled. 3. Remove SPL_OF_CONTROL and related configs from omapl138_lcdk_defconfig This cleanup effectively reverts 3ef94715cc ('mmc: davinci: fix mmc boot in SPL') Signed-off-by: Faiz Abbas Tested-by: Bartosz Golaszewski --- arch/arm/mach-davinci/include/mach/sdmmc_defs.h | 7 +++ board/davinci/da8xxevm/omapl138_lcdk.c | 12 +++++ configs/omapl138_lcdk_defconfig | 4 -- drivers/mmc/davinci_mmc.c | 63 ++++++++++--------------- 4 files changed, 45 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-davinci/include/mach/sdmmc_defs.h b/arch/arm/mach-davinci/include/mach/sdmmc_defs.h index 46f6391aa21..f95a607e526 100644 --- a/arch/arm/mach-davinci/include/mach/sdmmc_defs.h +++ b/arch/arm/mach-davinci/include/mach/sdmmc_defs.h @@ -152,6 +152,13 @@ struct davinci_mmc { struct mmc_config cfg; }; +#define DAVINCI_MAX_BLOCKS (32) +struct davinci_mmc_plat { + struct davinci_mmc_regs *reg_base; /* Register base address */ + struct mmc_config cfg; + struct mmc mmc; +}; + int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host); #endif /* _SDMMC_DEFS_H */ diff --git a/board/davinci/da8xxevm/omapl138_lcdk.c b/board/davinci/da8xxevm/omapl138_lcdk.c index adb56c6c871..84603cb1171 100644 --- a/board/davinci/da8xxevm/omapl138_lcdk.c +++ b/board/davinci/da8xxevm/omapl138_lcdk.c @@ -368,8 +368,20 @@ U_BOOT_DEVICE(omapl138_uart) = { .platdata = &serial_pdata, }; +static const struct davinci_mmc_plat mmc_platdata = { + .reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE, + .cfg = { + .f_min = 200000, + .f_max = 25000000, + .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, + .host_caps = MMC_MODE_4BIT, + .b_max = DAVINCI_MAX_BLOCKS, + .name = "da830-mmc", + }, +}; U_BOOT_DEVICE(omapl138_mmc) = { .name = "davinci_mmc", + .platdata = &mmc_platdata, }; void spl_board_init(void) diff --git a/configs/omapl138_lcdk_defconfig b/configs/omapl138_lcdk_defconfig index 50cf09c7f18..b0a58de03d6 100644 --- a/configs/omapl138_lcdk_defconfig +++ b/configs/omapl138_lcdk_defconfig @@ -40,16 +40,13 @@ CONFIG_CMD_MTDPARTS=y CONFIG_CMD_DIAG=y CONFIG_CMD_UBI=y CONFIG_OF_CONTROL=y -CONFIG_SPL_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="da850-lcdk" -CONFIG_SPL_OF_PLATDATA=y CONFIG_ENV_IS_IN_NAND=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y CONFIG_SPL_DM=y CONFIG_SPL_DM_SEQ_ALIAS=y -CONFIG_SPL_OF_TRANSLATE=y CONFIG_DA8XX_GPIO=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_DAVINCI=y @@ -82,4 +79,3 @@ CONFIG_USB_MUSB_HOST=y CONFIG_USB_MUSB_DA8XX=y CONFIG_USB_MUSB_PIO_ONLY=y CONFIG_USB_STORAGE=y -# CONFIG_SPL_OF_LIBFDT is not set diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index 2408a687d23..4ef9f7cc8bc 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -18,7 +18,6 @@ #include #include -#define DAVINCI_MAX_BLOCKS (32) #define WATCHDOG_COUNT (100000) #define get_val(addr) REG(addr) @@ -34,12 +33,6 @@ struct davinci_mmc_priv { struct gpio_desc cd_gpio; /* Card Detect GPIO */ struct gpio_desc wp_gpio; /* Write Protect GPIO */ }; - -struct davinci_mmc_plat -{ - struct mmc_config cfg; - struct mmc mmc; -}; #endif /* Set davinci clock prescalar value based on the required clock in HZ */ @@ -487,43 +480,16 @@ static int davinci_mmc_probe(struct udevice *dev) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct davinci_mmc_plat *plat = dev_get_platdata(dev); struct davinci_mmc_priv *priv = dev_get_priv(dev); - struct mmc_config *cfg = &plat->cfg; -#ifdef CONFIG_SPL_BUILD - int ret; -#endif - - cfg->f_min = 200000; - cfg->f_max = 25000000; - cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34, - cfg->host_caps = MMC_MODE_4BIT, /* DA850 supports only 4-bit SD/MMC */ - cfg->b_max = DAVINCI_MAX_BLOCKS; - cfg->name = "da830-mmc"; - priv->reg_base = (struct davinci_mmc_regs *)dev_read_addr(dev); + priv->reg_base = plat->reg_base; priv->input_clk = clk_get(DAVINCI_MMCSD_CLKID); - #if CONFIG_IS_ENABLED(DM_GPIO) /* These GPIOs are optional */ gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); #endif - upriv->mmc = &plat->mmc; -#ifdef CONFIG_SPL_BUILD - /* - * FIXME This is a temporary workaround to enable the driver model in - * SPL on omapl138-lcdk. For some reason the bind() callback is not - * being called in SPL for MMC which breaks the mmc boot - the hack - * is to call mmc_bind() from probe(). We also don't have full DT - * support in SPL, hence the hard-coded base register address. - */ - priv->reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE; - ret = mmc_bind(dev, &plat->mmc, &plat->cfg); - if (ret) - return ret; -#endif - return davinci_dm_mmc_init(dev); } @@ -534,21 +500,44 @@ static int davinci_mmc_bind(struct udevice *dev) return mmc_bind(dev, &plat->mmc, &plat->cfg); } +#if CONFIG_IS_ENABLED(OF_CONTROL) +static int davinci_mmc_ofdata_to_platdata(struct udevice *dev) +{ + struct davinci_mmc_plat *plat = dev_get_platdata(dev); + struct mmc_config *cfg = &plat->cfg; + + plat->reg_base = (struct davinci_mmc_regs *)dev_read_addr(dev); + cfg->f_min = 200000; + cfg->f_max = 25000000; + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34, + cfg->host_caps = MMC_MODE_4BIT, /* DA850 supports only 4-bit SD/MMC */ + cfg->b_max = DAVINCI_MAX_BLOCKS; + cfg->name = "da830-mmc"; + + return 0; +} + static const struct udevice_id davinci_mmc_ids[] = { { .compatible = "ti,da830-mmc" }, {}, }; - +#endif U_BOOT_DRIVER(davinci_mmc_drv) = { .name = "davinci_mmc", .id = UCLASS_MMC, +#if CONFIG_IS_ENABLED(OF_CONTROL) .of_match = davinci_mmc_ids, + .platdata_auto_alloc_size = sizeof(struct davinci_mmc_plat), + .ofdata_to_platdata = davinci_mmc_ofdata_to_platdata, +#endif #if CONFIG_BLK .bind = davinci_mmc_bind, #endif .probe = davinci_mmc_probe, .ops = &davinci_mmc_ops, - .platdata_auto_alloc_size = sizeof(struct davinci_mmc_plat), .priv_auto_alloc_size = sizeof(struct davinci_mmc_priv), +#if !CONFIG_IS_ENABLED(OF_CONTROL) + .flags = DM_FLAG_PRE_RELOC, +#endif }; #endif -- cgit v1.3.1 From 5b9ee0fc6f9adb05eefa457a752626cb22cca958 Mon Sep 17 00:00:00 2001 From: Bin Liu Date: Wed, 3 Jun 2020 14:46:22 +0300 Subject: phy: omap-usb2-phy: disable phy charger detect AM654x PG1.0 has a silicon bug that D+ is pulled high after POR, which could cause enumeration failure with some USB hubs. Disabling the USB2_PHY Charger Detect function will put D+ into the normal state. Using property "ti,dis-chg-det-quirk" in the DT usb2-phy node to enable this workaround for AM654x PG1.0. Signed-off-by: Bin Liu Signed-off-by: Vignesh Raghavendra Signed-off-by: Roger Quadros --- drivers/phy/omap-usb2-phy.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/phy/omap-usb2-phy.c b/drivers/phy/omap-usb2-phy.c index 0793b97dd51..adc454ddd48 100644 --- a/drivers/phy/omap-usb2-phy.c +++ b/drivers/phy/omap-usb2-phy.c @@ -17,6 +17,7 @@ #include #define OMAP_USB2_CALIBRATE_FALSE_DISCONNECT BIT(0) +#define OMAP_USB2_DISABLE_CHG_DET BIT(1) #define OMAP_DEV_PHY_PD BIT(0) #define OMAP_USB2_PHY_PD BIT(28) @@ -33,6 +34,10 @@ #define AM654_USB2_VBUS_DET_EN BIT(5) #define AM654_USB2_VBUSVALID_DET_EN BIT(4) +#define USB2PHY_CHRG_DET 0x14 +#define USB2PHY_USE_CHG_DET_REG BIT(29) +#define USB2PHY_DIS_CHG_DET BIT(28) + DECLARE_GLOBAL_DATA_PTR; struct omap_usb2_phy { @@ -160,6 +165,12 @@ static int omap_usb2_phy_init(struct phy *usb_phy) writel(val, priv->phy_base + USB2PHY_ANA_CONFIG1); } + if (priv->flags & OMAP_USB2_DISABLE_CHG_DET) { + val = readl(priv->phy_base + USB2PHY_CHRG_DET); + val |= USB2PHY_USE_CHG_DET_REG | USB2PHY_DIS_CHG_DET; + writel(val, priv->phy_base + USB2PHY_CHRG_DET); + } + return 0; } @@ -197,13 +208,25 @@ int omap_usb2_phy_probe(struct udevice *dev) if (!data) return -EINVAL; - if (data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) { - priv->phy_base = dev_read_addr_ptr(dev); + priv->phy_base = dev_read_addr_ptr(dev); - if (!priv->phy_base) - return -EINVAL; + if (!priv->phy_base) + return -EINVAL; + + if (data->flags & OMAP_USB2_CALIBRATE_FALSE_DISCONNECT) priv->flags |= OMAP_USB2_CALIBRATE_FALSE_DISCONNECT; - } + + /* + * AM654x PG1.0 has a silicon bug that D+ is pulled high after + * POR, which could cause enumeration failure with some USB hubs. + * Disabling the USB2_PHY Charger Detect function will put D+ + * into the normal state. + * + * Using property "ti,dis-chg-det-quirk" in the DT usb2-phy node + * to enable this workaround for AM654x PG1.0. + */ + if (dev_read_bool(dev, "ti,dis-chg-det-quirk")) + priv->flags |= OMAP_USB2_DISABLE_CHG_DET; regmap = syscon_regmap_lookup_by_phandle(dev, "syscon-phy-power"); if (!IS_ERR(regmap)) { -- cgit v1.3.1 From a37f765219870e4cb4ed9590dff77ed8a380a462 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 4 Jun 2020 16:01:39 -0400 Subject: gpio: omap_gpio: Fix unused function warning in non-DM case In the case of non-DM_GPIO the function get_gpio_index() will never be called, and clang will warn about this. Move this to be with the other non-DM code for easier removal later. Cc: Lokesh Vutla Signed-off-by: Tom Rini Reviewed-by: Lokesh Vutla --- drivers/gpio/omap_gpio.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c index 4249850f4bf..c986ef03805 100644 --- a/drivers/gpio/omap_gpio.c +++ b/drivers/gpio/omap_gpio.c @@ -41,11 +41,6 @@ struct gpio_bank { #endif -static inline int get_gpio_index(int gpio) -{ - return gpio & 0x1f; -} - int gpio_is_valid(int gpio) { return (gpio >= 0) && (gpio < OMAP_MAX_GPIO); @@ -122,6 +117,10 @@ static int _get_gpio_value(const struct gpio_bank *bank, int gpio) } #if !CONFIG_IS_ENABLED(DM_GPIO) +static inline int get_gpio_index(int gpio) +{ + return gpio & 0x1f; +} static inline const struct gpio_bank *get_gpio_bank(int gpio) { -- cgit v1.3.1 From 2af17e2573e8f4b949658ac45cad2e825e5aedc0 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 4 Jun 2020 16:03:55 -0400 Subject: mmc: omap_hsmmc: Add guards around omap_hsmmc_get_cfg() We only call the function omap_hsmmc_get_cfg in the case of OMAP34XX or when we have to iodelay recalibration. Add guards for these checks as clang will otherwise warn. Cc: Peng Fan Cc: Lokesh Vutla Signed-off-by: Tom Rini Reviewed-by: Peng Fan Reviewed-by: Lokesh Vutla --- drivers/mmc/omap_hsmmc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 8636cd713a3..0e05fe4cfcb 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -175,6 +175,8 @@ static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc) return (struct omap_hsmmc_data *)mmc->priv; #endif } + +#if defined(CONFIG_OMAP34XX) || defined(CONFIG_IODELAY_RECALIBRATION) static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc) { #if CONFIG_IS_ENABLED(DM_MMC) @@ -184,6 +186,7 @@ static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc) return &((struct omap_hsmmc_data *)mmc->priv)->cfg; #endif } +#endif #if defined(OMAP_HSMMC_USE_GPIO) && !CONFIG_IS_ENABLED(DM_MMC) static int omap_mmc_setup_gpio_in(int gpio, const char *label) -- cgit v1.3.1 From eab48865f93a19e2a196a6c4e3480f16df4027d9 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Thu, 4 Jun 2020 16:05:32 -0400 Subject: net: cpsw: Add __maybe_unused to generated inlines We generate a number of helper inline functions to make accesses easier. However not all permutations of each function will be used and clang will warn about unused ones. Decorate all of them with __maybe_unused because of this. Cc: Lokesh Vutla Signed-off-by: Tom Rini Reviewed-by: Grygorii Strashko --- drivers/net/ti/cpsw.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ti/cpsw.c b/drivers/net/ti/cpsw.c index 95761fffc0f..9d4332f4504 100644 --- a/drivers/net/ti/cpsw.c +++ b/drivers/net/ti/cpsw.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -247,11 +248,11 @@ static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits, } #define DEFINE_ALE_FIELD(name, start, bits) \ -static inline int cpsw_ale_get_##name(u32 *ale_entry) \ +static inline int __maybe_unused cpsw_ale_get_##name(u32 *ale_entry) \ { \ return cpsw_ale_get_field(ale_entry, start, bits); \ } \ -static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \ +static inline void __maybe_unused cpsw_ale_set_##name(u32 *ale_entry, u32 value) \ { \ cpsw_ale_set_field(ale_entry, start, bits, value); \ } -- cgit v1.3.1 From 8d50551dc77bc87dc6c6b3474e094d9203a24144 Mon Sep 17 00:00:00 2001 From: Chuanhua Han Date: Thu, 4 Jun 2020 23:16:30 +0800 Subject: dm: spi: Convert Freescale ESPI driver to driver model Modify the Freescale ESPI driver to support the driver model. Also resolved the following problems: ===================== WARNING ====================== This board does not use CONFIG_DM_SPI. Please update the board before v2019.04 for no dm conversion and v2019.07 for partially dm converted drivers. Failure to update can lead to driver/board removal See doc/driver-model/MIGRATION.txt for more info. ==================================================== ===================== WARNING ====================== This board does not use CONFIG_DM_SPI_FLASH. Please update the board to use CONFIG_SPI_FLASH before the v2019.07 release. Failure to update by the deadline may result in board removal. See doc/driver-model/MIGRATION.txt for more info. ==================================================== Signed-off-by: Chuanhua Han Signed-off-by: Xiaowei Bao Signed-off-by: Hou Zhiqiang Reviewed-by: Jagan Teki --- drivers/spi/fsl_espi.c | 444 ++++++++++++++++++++++++++---------- include/dm/platform_data/fsl_espi.h | 16 ++ 2 files changed, 337 insertions(+), 123 deletions(-) create mode 100644 include/dm/platform_data/fsl_espi.h (limited to 'drivers') diff --git a/drivers/spi/fsl_espi.c b/drivers/spi/fsl_espi.c index 50d194f614b..5c76fd962e9 100644 --- a/drivers/spi/fsl_espi.c +++ b/drivers/spi/fsl_espi.c @@ -3,7 +3,9 @@ * eSPI controller driver. * * Copyright 2010-2011 Freescale Semiconductor, Inc. + * Copyright 2020 NXP * Author: Mingkai Hu (Mingkai.hu@freescale.com) + * Chuanhua Han (chuanhua.han@nxp.com) */ #include @@ -14,10 +16,16 @@ #include #include #include +#include +#include +#include +#include struct fsl_spi_slave { struct spi_slave slave; ccsr_espi_t *espi; + u32 speed_hz; + unsigned int cs; unsigned int div16; unsigned int pm; int tx_timeout; @@ -31,6 +39,9 @@ struct fsl_spi_slave { #define to_fsl_spi_slave(s) container_of(s, struct fsl_spi_slave, slave) #define US_PER_SECOND 1000000UL +/* default SCK frequency, unit: HZ */ +#define FSL_ESPI_DEFAULT_SCK_FREQ 10000000 + #define ESPI_MAX_CS_NUM 4 #define ESPI_FIFO_WIDTH_BIT 32 @@ -65,116 +76,27 @@ struct fsl_spi_slave { #define ESPI_MAX_DATA_TRANSFER_LEN 0xFFF0 -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct fsl_spi_slave *fsl; - sys_info_t sysinfo; - unsigned long spibrg = 0; - unsigned long spi_freq = 0; - unsigned char pm = 0; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - fsl = spi_alloc_slave(struct fsl_spi_slave, bus, cs); - if (!fsl) - return NULL; - - fsl->espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR); - fsl->mode = mode; - fsl->max_transfer_length = ESPI_MAX_DATA_TRANSFER_LEN; - - /* Set eSPI BRG clock source */ - get_sys_info(&sysinfo); - spibrg = sysinfo.freq_systembus / 2; - fsl->div16 = 0; - if ((spibrg / max_hz) > 32) { - fsl->div16 = ESPI_CSMODE_DIV16; - pm = spibrg / (max_hz * 16 * 2); - if (pm > 16) { - pm = 16; - debug("Requested speed is too low: %d Hz, %ld Hz " - "is used.\n", max_hz, spibrg / (32 * 16)); - } - } else - pm = spibrg / (max_hz * 2); - if (pm) - pm--; - fsl->pm = pm; - - if (fsl->div16) - spi_freq = spibrg / ((pm + 1) * 2 * 16); - else - spi_freq = spibrg / ((pm + 1) * 2); - - /* set tx_timeout to 10 times of one espi FIFO entry go out */ - fsl->tx_timeout = DIV_ROUND_UP((US_PER_SECOND * ESPI_FIFO_WIDTH_BIT - * 10), spi_freq); - - return &fsl->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); - free(fsl); -} - -int spi_claim_bus(struct spi_slave *slave) +void fsl_spi_cs_activate(struct spi_slave *slave, uint cs) { struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); ccsr_espi_t *espi = fsl->espi; - unsigned char pm = fsl->pm; - unsigned int cs = slave->cs; - unsigned int mode = fsl->mode; - unsigned int div16 = fsl->div16; - int i; - - debug("%s: bus:%i cs:%i\n", __func__, slave->bus, cs); - - /* Enable eSPI interface */ - out_be32(&espi->mode, ESPI_MODE_RXTHR(3) - | ESPI_MODE_TXTHR(4) | ESPI_MODE_EN); - - out_be32(&espi->event, 0xffffffff); /* Clear all eSPI events */ - out_be32(&espi->mask, 0x00000000); /* Mask all eSPI interrupts */ - - /* Init CS mode interface */ - for (i = 0; i < ESPI_MAX_CS_NUM; i++) - out_be32(&espi->csmode[i], ESPI_CSMODE_INIT_VAL); - - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) & - ~(ESPI_CSMODE_PM(0xF) | ESPI_CSMODE_DIV16 - | ESPI_CSMODE_CI_INACTIVEHIGH | ESPI_CSMODE_CP_BEGIN_EDGCLK - | ESPI_CSMODE_REV_MSB_FIRST | ESPI_CSMODE_LEN(0xF))); - - /* Set eSPI BRG clock source */ - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) - | ESPI_CSMODE_PM(pm) | div16); - - /* Set eSPI mode */ - if (mode & SPI_CPHA) - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) - | ESPI_CSMODE_CP_BEGIN_EDGCLK); - if (mode & SPI_CPOL) - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) - | ESPI_CSMODE_CI_INACTIVEHIGH); - - /* Character bit order: msb first */ - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) - | ESPI_CSMODE_REV_MSB_FIRST); - - /* Character length in bits, between 0x3~0xf, i.e. 4bits~16bits */ - out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) - | ESPI_CSMODE_LEN(7)); + unsigned int com = 0; + size_t data_len = fsl->data_len; - return 0; + com &= ~(ESPI_COM_CS(0x3) | ESPI_COM_TRANLEN(0xFFFF)); + com |= ESPI_COM_CS(cs); + com |= ESPI_COM_TRANLEN(data_len - 1); + out_be32(&espi->com, com); } -void spi_release_bus(struct spi_slave *slave) +void fsl_spi_cs_deactivate(struct spi_slave *slave) { + struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); + ccsr_espi_t *espi = fsl->espi; + /* clear the RXCNT and TXCNT */ + out_be32(&espi->mode, in_be32(&espi->mode) & (~ESPI_MODE_EN)); + out_be32(&espi->mode, in_be32(&espi->mode) | ESPI_MODE_EN); } static void fsl_espi_tx(struct fsl_spi_slave *fsl, const void *dout) @@ -207,7 +129,8 @@ static void fsl_espi_tx(struct fsl_spi_slave *fsl, const void *dout) debug("***spi_xfer:...Tx timeout! event = %08x\n", event); } -static int fsl_espi_rx(struct fsl_spi_slave *fsl, void *din, unsigned int bytes) +static int fsl_espi_rx(struct fsl_spi_slave *fsl, void *din, + unsigned int bytes) { ccsr_espi_t *espi = fsl->espi; unsigned int tmpdin, rx_times; @@ -239,10 +162,17 @@ static int fsl_espi_rx(struct fsl_spi_slave *fsl, void *din, unsigned int bytes) return bytes; } -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, - void *data_in, unsigned long flags) +void espi_release_bus(struct fsl_spi_slave *fsl) { - struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); + /* Disable the SPI hardware */ + out_be32(&fsl->espi->mode, + in_be32(&fsl->espi->mode) & (~ESPI_MODE_EN)); +} + +int espi_xfer(struct fsl_spi_slave *fsl, uint cs, unsigned int bitlen, + const void *data_out, void *data_in, unsigned long flags) +{ + struct spi_slave *slave = &fsl->slave; ccsr_espi_t *espi = fsl->espi; unsigned int event, rx_bytes; const void *dout = NULL; @@ -261,13 +191,14 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, max_tran_len = fsl->max_transfer_length; switch (flags) { case SPI_XFER_BEGIN: - cmd_len = fsl->cmd_len = data_len; + cmd_len = data_len; + fsl->cmd_len = cmd_len; memcpy(cmd_buf, data_out, cmd_len); return 0; case 0: case SPI_XFER_END: if (bitlen == 0) { - spi_cs_deactivate(slave); + fsl_spi_cs_deactivate(slave); return 0; } buf_len = 2 * cmd_len + min(data_len, (size_t)max_tran_len); @@ -307,7 +238,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, num_blks = DIV_ROUND_UP(tran_len + cmd_len, 4); num_bytes = (tran_len + cmd_len) % 4; fsl->data_len = tran_len + cmd_len; - spi_cs_activate(slave); + fsl_spi_cs_activate(slave, cs); /* Clear all eSPI events */ out_be32(&espi->event , 0xffffffff); @@ -350,37 +281,304 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *data_out, *(int *)buffer += tran_len; } } - spi_cs_deactivate(slave); + fsl_spi_cs_deactivate(slave); } free(buffer); return 0; } +void espi_claim_bus(struct fsl_spi_slave *fsl, unsigned int cs) +{ + ccsr_espi_t *espi = fsl->espi; + unsigned char pm = fsl->pm; + unsigned int mode = fsl->mode; + unsigned int div16 = fsl->div16; + int i; + + /* Enable eSPI interface */ + out_be32(&espi->mode, ESPI_MODE_RXTHR(3) + | ESPI_MODE_TXTHR(4) | ESPI_MODE_EN); + + out_be32(&espi->event, 0xffffffff); /* Clear all eSPI events */ + out_be32(&espi->mask, 0x00000000); /* Mask all eSPI interrupts */ + + /* Init CS mode interface */ + for (i = 0; i < ESPI_MAX_CS_NUM; i++) + out_be32(&espi->csmode[i], ESPI_CSMODE_INIT_VAL); + + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) & + ~(ESPI_CSMODE_PM(0xF) | ESPI_CSMODE_DIV16 + | ESPI_CSMODE_CI_INACTIVEHIGH | ESPI_CSMODE_CP_BEGIN_EDGCLK + | ESPI_CSMODE_REV_MSB_FIRST | ESPI_CSMODE_LEN(0xF))); + + /* Set eSPI BRG clock source */ + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) + | ESPI_CSMODE_PM(pm) | div16); + + /* Set eSPI mode */ + if (mode & SPI_CPHA) + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) + | ESPI_CSMODE_CP_BEGIN_EDGCLK); + if (mode & SPI_CPOL) + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) + | ESPI_CSMODE_CI_INACTIVEHIGH); + + /* Character bit order: msb first */ + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) + | ESPI_CSMODE_REV_MSB_FIRST); + + /* Character length in bits, between 0x3~0xf, i.e. 4bits~16bits */ + out_be32(&espi->csmode[cs], in_be32(&espi->csmode[cs]) + | ESPI_CSMODE_LEN(7)); +} + +void espi_setup_slave(struct fsl_spi_slave *fsl) +{ + unsigned int max_hz; + sys_info_t sysinfo; + unsigned long spibrg = 0; + unsigned long spi_freq = 0; + unsigned char pm = 0; + + max_hz = fsl->speed_hz; + + get_sys_info(&sysinfo); + spibrg = sysinfo.freq_systembus / 2; + fsl->div16 = 0; + if ((spibrg / max_hz) > 32) { + fsl->div16 = ESPI_CSMODE_DIV16; + pm = spibrg / (max_hz * 16 * 2); + if (pm > 16) { + pm = 16; + debug("max_hz is too low: %d Hz, %ld Hz is used.\n", + max_hz, spibrg / (32 * 16)); + } + } else { + pm = spibrg / (max_hz * 2); + } + if (pm) + pm--; + fsl->pm = pm; + + if (fsl->div16) + spi_freq = spibrg / ((pm + 1) * 2 * 16); + else + spi_freq = spibrg / ((pm + 1) * 2); + + /* set tx_timeout to 10 times of one espi FIFO entry go out */ + fsl->tx_timeout = DIV_ROUND_UP((US_PER_SECOND * ESPI_FIFO_WIDTH_BIT + * 10), spi_freq);/* Set eSPI BRG clock source */ +} + +#if !CONFIG_IS_ENABLED(DM_SPI) int spi_cs_is_valid(unsigned int bus, unsigned int cs) { return bus == 0 && cs < ESPI_MAX_CS_NUM; } -void spi_cs_activate(struct spi_slave *slave) +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct fsl_spi_slave *fsl; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + fsl = spi_alloc_slave(struct fsl_spi_slave, bus, cs); + if (!fsl) + return NULL; + + fsl->espi = (void *)(CONFIG_SYS_MPC85xx_ESPI_ADDR); + fsl->mode = mode; + fsl->max_transfer_length = ESPI_MAX_DATA_TRANSFER_LEN; + fsl->speed_hz = max_hz; + + espi_setup_slave(fsl); + + return &fsl->slave; +} + +void spi_free_slave(struct spi_slave *slave) { struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); - ccsr_espi_t *espi = fsl->espi; - unsigned int com = 0; - size_t data_len = fsl->data_len; - com &= ~(ESPI_COM_CS(0x3) | ESPI_COM_TRANLEN(0xFFFF)); - com |= ESPI_COM_CS(slave->cs); - com |= ESPI_COM_TRANLEN(data_len - 1); - out_be32(&espi->com, com); + free(fsl); } -void spi_cs_deactivate(struct spi_slave *slave) +int spi_claim_bus(struct spi_slave *slave) { struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); - ccsr_espi_t *espi = fsl->espi; - /* clear the RXCNT and TXCNT */ - out_be32(&espi->mode, in_be32(&espi->mode) & (~ESPI_MODE_EN)); - out_be32(&espi->mode, in_be32(&espi->mode) | ESPI_MODE_EN); + espi_claim_bus(fsl, slave->cs); + + return 0; } + +void spi_release_bus(struct spi_slave *slave) +{ + struct fsl_spi_slave *fsl = to_fsl_spi_slave(slave); + + espi_release_bus(fsl); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, + void *din, unsigned long flags) +{ + struct fsl_spi_slave *fsl = (struct fsl_spi_slave *)slave; + + return espi_xfer(fsl, slave->cs, bitlen, dout, din, flags); +} +#else +static void __espi_set_speed(struct fsl_spi_slave *fsl) +{ + espi_setup_slave(fsl); + + /* Set eSPI BRG clock source */ + out_be32(&fsl->espi->csmode[fsl->cs], + in_be32(&fsl->espi->csmode[fsl->cs]) + | ESPI_CSMODE_PM(fsl->pm) | fsl->div16); +} + +static void __espi_set_mode(struct fsl_spi_slave *fsl) +{ + /* Set eSPI mode */ + if (fsl->mode & SPI_CPHA) + out_be32(&fsl->espi->csmode[fsl->cs], + in_be32(&fsl->espi->csmode[fsl->cs]) + | ESPI_CSMODE_CP_BEGIN_EDGCLK); + if (fsl->mode & SPI_CPOL) + out_be32(&fsl->espi->csmode[fsl->cs], + in_be32(&fsl->espi->csmode[fsl->cs]) + | ESPI_CSMODE_CI_INACTIVEHIGH); +} + +static int fsl_espi_claim_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + espi_claim_bus(fsl, fsl->cs); + + return 0; +} + +static int fsl_espi_release_bus(struct udevice *dev) +{ + struct udevice *bus = dev->parent; + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + espi_release_bus(fsl); + + return 0; +} + +static int fsl_espi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct udevice *bus = dev->parent; + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + return espi_xfer(fsl, fsl->cs, bitlen, dout, din, flags); +} + +static int fsl_espi_set_speed(struct udevice *bus, uint speed) +{ + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + debug("%s speed %u\n", __func__, speed); + fsl->speed_hz = speed; + + __espi_set_speed(fsl); + + return 0; +} + +static int fsl_espi_set_mode(struct udevice *bus, uint mode) +{ + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + debug("%s mode %u\n", __func__, mode); + fsl->mode = mode; + + __espi_set_mode(fsl); + + return 0; +} + +static int fsl_espi_child_pre_probe(struct udevice *dev) +{ + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); + struct udevice *bus = dev->parent; + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + debug("%s cs %u\n", __func__, slave_plat->cs); + fsl->cs = slave_plat->cs; + + return 0; +} + +static int fsl_espi_probe(struct udevice *bus) +{ + struct fsl_espi_platdata *plat = dev_get_platdata(bus); + struct fsl_spi_slave *fsl = dev_get_priv(bus); + + fsl->espi = (ccsr_espi_t *)((u32)plat->regs_addr); + fsl->max_transfer_length = ESPI_MAX_DATA_TRANSFER_LEN; + fsl->speed_hz = plat->speed_hz; + + debug("%s probe done, bus-num %d.\n", bus->name, bus->seq); + + return 0; +} + +static const struct dm_spi_ops fsl_espi_ops = { + .claim_bus = fsl_espi_claim_bus, + .release_bus = fsl_espi_release_bus, + .xfer = fsl_espi_xfer, + .set_speed = fsl_espi_set_speed, + .set_mode = fsl_espi_set_mode, +}; + +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) +static int fsl_espi_ofdata_to_platdata(struct udevice *bus) +{ + fdt_addr_t addr; + struct fsl_espi_platdata *plat = bus->platdata; + const void *blob = gd->fdt_blob; + int node = dev_of_offset(bus); + + addr = dev_read_addr(bus); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + plat->regs_addr = lower_32_bits(addr); + plat->speed_hz = fdtdec_get_int(blob, node, "spi-max-frequency", + FSL_ESPI_DEFAULT_SCK_FREQ); + + debug("ESPI: regs=%p, max-frequency=%d\n", + &plat->regs_addr, plat->speed_hz); + + return 0; +} + +static const struct udevice_id fsl_espi_ids[] = { + { .compatible = "fsl,mpc8536-espi" }, + { } +}; +#endif + +U_BOOT_DRIVER(fsl_espi) = { + .name = "fsl_espi", + .id = UCLASS_SPI, +#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) + .of_match = fsl_espi_ids, + .ofdata_to_platdata = fsl_espi_ofdata_to_platdata, +#endif + .ops = &fsl_espi_ops, + .platdata_auto_alloc_size = sizeof(struct fsl_espi_platdata), + .priv_auto_alloc_size = sizeof(struct fsl_spi_slave), + .probe = fsl_espi_probe, + .child_pre_probe = fsl_espi_child_pre_probe, +}; +#endif diff --git a/include/dm/platform_data/fsl_espi.h b/include/dm/platform_data/fsl_espi.h new file mode 100644 index 00000000000..812933f51cd --- /dev/null +++ b/include/dm/platform_data/fsl_espi.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2019 NXP + */ + +#ifndef __fsl_espi_h +#define __fsl_espi_h + +struct fsl_espi_platdata { + uint flags; + uint speed_hz; + uint num_chipselect; + fdt_addr_t regs_addr; +}; + +#endif /* __fsl_espi_h */ -- cgit v1.3.1 From 39b95556f9b97b0fa824871aef53647d6ea0b44e Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 25 May 2020 21:47:19 +0200 Subject: video: make vidconsole commands optional Converting some boards to DM_VIDEO results in build breakage due to increased code size. Make video console specific commands optional to reduce binary size. Signed-off-by: Anatolij Gustschin Reviewed-by: Simon Glass --- drivers/video/Kconfig | 8 ++++++++ drivers/video/vidconsole-uclass.c | 2 ++ 2 files changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 38123543a53..d0e9563b779 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -35,6 +35,14 @@ config BACKLIGHT_GPIO it understands the standard device tree (leds/backlight/gpio-backlight.txt) +config CMD_VIDCONSOLE + bool "Enable vidconsole commands lcdputs and setcurs" + depends on DM_VIDEO + default y + help + Enabling this will provide 'setcurs' and 'lcdputs' commands which + support cursor positioning and drawing strings on video framebuffer. + config VIDEO_BPP8 bool "Support 8-bit-per-pixel displays" depends on DM_VIDEO diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index d30e6db6f6f..901347c4675 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -613,6 +613,7 @@ UCLASS_DRIVER(vidconsole) = { .per_device_auto_alloc_size = sizeof(struct vidconsole_priv), }; +#if CONFIG_IS_ENABLED(CMD_VIDCONSOLE) void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); @@ -673,3 +674,4 @@ U_BOOT_CMD( "print string on video framebuffer", " " ); +#endif /* CONFIG_IS_ENABLED(CMD_VIDCONSOLE) */ -- cgit v1.3.1 From 0b12f76f7241cb22d4a41ab048b64c8c3a88199d Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 26 May 2020 00:09:22 +0200 Subject: video: ipuv3: fix building with disabled panel driver Panel code might be disabled for some boards, make this driver code optional. Signed-off-by: Anatolij Gustschin --- drivers/video/imx/mxc_ipuv3_fb.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/imx/mxc_ipuv3_fb.c b/drivers/video/imx/mxc_ipuv3_fb.c index 4044473f998..cdef84af0e3 100644 --- a/drivers/video/imx/mxc_ipuv3_fb.c +++ b/drivers/video/imx/mxc_ipuv3_fb.c @@ -645,7 +645,6 @@ static int ipuv3_video_probe(struct udevice *dev) #if defined(CONFIG_DISPLAY) struct udevice *disp_dev; #endif - struct udevice *panel_dev; u32 fb_start, fb_end; int ret; @@ -672,9 +671,13 @@ static int ipuv3_video_probe(struct udevice *dev) return ret; } #endif - ret = uclass_get_device(UCLASS_PANEL, 0, &panel_dev); - if (panel_dev) - panel_enable_backlight(panel_dev); + if (CONFIG_IS_ENABLED(PANEL)) { + struct udevice *panel_dev; + + ret = uclass_get_device(UCLASS_PANEL, 0, &panel_dev); + if (panel_dev) + panel_enable_backlight(panel_dev); + } uc_priv->xsize = gmode->xres; uc_priv->ysize = gmode->yres; -- cgit v1.3.1 From e26e520046a1b551f25acf3d7b6705a37c808deb Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 26 May 2020 00:20:49 +0200 Subject: video: make backlight and panel drivers optional Not all boards use these drivers, so allow to disable them to fix building boards with U-Boot binary image size restrictions. Signed-off-by: Anatolij Gustschin Reviewed-by: Simon Glass --- drivers/video/Kconfig | 27 +++++++++++++++++++++++++-- drivers/video/Makefile | 5 +++-- 2 files changed, 28 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index d0e9563b779..aaea7ce743f 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -14,9 +14,17 @@ config DM_VIDEO option compiles in the video uclass and routes all LCD/video access through this. +config BACKLIGHT + bool "Enable panel backlight uclass support" + depends on DM_VIDEO + default y + help + This provides backlight uclass driver that enables basic panel + backlight support. + config BACKLIGHT_PWM bool "Generic PWM based Backlight Driver" - depends on DM_VIDEO && DM_PWM + depends on BACKLIGHT && DM_PWM default y help If you have a LCD backlight adjustable by PWM, say Y to enable @@ -27,7 +35,7 @@ config BACKLIGHT_PWM config BACKLIGHT_GPIO bool "Generic GPIO based Backlight Driver" - depends on DM_VIDEO + depends on BACKLIGHT help If you have a LCD backlight adjustable by GPIO, say Y to enable this driver. @@ -151,6 +159,21 @@ config NO_FB_CLEAR loads takes over the screen. This, for example, can be used to keep splash image on screen until grub graphical boot menu starts. +config PANEL + bool "Enable panel uclass support" + depends on DM_VIDEO + default y + help + This provides panel uclass driver that enables basic panel support. + +config SIMPLE_PANEL + bool "Enable simple panel support" + depends on PANEL + default y + help + This turns on a simple panel driver that enables a compatible + video panel. + source "drivers/video/fonts/Kconfig" config VIDCONSOLE_AS_LCD diff --git a/drivers/video/Makefile b/drivers/video/Makefile index df7119d62ac..1dbd09a1724 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -4,17 +4,18 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. ifdef CONFIG_DM +obj-$(CONFIG_BACKLIGHT) += backlight-uclass.o obj-$(CONFIG_BACKLIGHT_GPIO) += backlight_gpio.o obj-$(CONFIG_BACKLIGHT_PWM) += pwm_backlight.o obj-$(CONFIG_CONSOLE_NORMAL) += console_normal.o obj-$(CONFIG_CONSOLE_ROTATION) += console_rotate.o obj-$(CONFIG_CONSOLE_TRUETYPE) += console_truetype.o fonts/ obj-$(CONFIG_DISPLAY) += display-uclass.o -obj-$(CONFIG_DM_VIDEO) += backlight-uclass.o obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi-host-uclass.o -obj-$(CONFIG_DM_VIDEO) += panel-uclass.o simple_panel.o obj-$(CONFIG_DM_VIDEO) += video-uclass.o vidconsole-uclass.o obj-$(CONFIG_DM_VIDEO) += video_bmp.o +obj-$(CONFIG_PANEL) += panel-uclass.o +obj-$(CONFIG_SIMPLE_PANEL) += simple_panel.o endif obj-${CONFIG_EXYNOS_FB} += exynos/ -- cgit v1.3.1 From db755b36d2ee240cae30de9cccada8fe398b3eef Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 25 May 2020 14:34:17 +0200 Subject: video: ipuv3: remove some useless code to reduce binary size To enable DM_VIDEO we must decrease binary size to fix build breakage for some boards, so drop not needed code. Also add !DM_VIDEO guards which can be later removed when last non DM users will be converted. Signed-off-by: Anatolij Gustschin --- drivers/video/imx/ipu_disp.c | 12 --------- drivers/video/imx/mxc_ipuv3_fb.c | 57 ++++++++++++++++------------------------ 2 files changed, 22 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/video/imx/ipu_disp.c b/drivers/video/imx/ipu_disp.c index c2f00bff18d..45069897faf 100644 --- a/drivers/video/imx/ipu_disp.c +++ b/drivers/video/imx/ipu_disp.c @@ -1191,9 +1191,6 @@ int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable, else bg_chan = 0; - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); - if (bg_chan) { reg = __raw_readl(DP_COM_CONF()); __raw_writel(reg & ~DP_COM_CONF_GWSEL, DP_COM_CONF()); @@ -1217,9 +1214,6 @@ int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, unsigned char enable, reg = __raw_readl(IPU_SRM_PRI2) | 0x8; __raw_writel(reg, IPU_SRM_PRI2); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); - return 0; } @@ -1246,9 +1240,6 @@ int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable, (channel == MEM_BG_ASYNC1 || channel == MEM_FG_ASYNC1))) return -EINVAL; - if (!g_ipu_clk_enabled) - clk_enable(g_ipu_clk); - color_key_4rgb = 1; /* Transform color key from rgb to yuv if CSC is enabled */ if (((fg_csc_type == RGB2YUV) && (bg_csc_type == YUV2YUV)) || @@ -1286,8 +1277,5 @@ int32_t ipu_disp_set_color_key(ipu_channel_t channel, unsigned char enable, reg = __raw_readl(IPU_SRM_PRI2) | 0x8; __raw_writel(reg, IPU_SRM_PRI2); - if (!g_ipu_clk_enabled) - clk_disable(g_ipu_clk); - return 0; } diff --git a/drivers/video/imx/mxc_ipuv3_fb.c b/drivers/video/imx/mxc_ipuv3_fb.c index cdef84af0e3..6787201bf55 100644 --- a/drivers/video/imx/mxc_ipuv3_fb.c +++ b/drivers/video/imx/mxc_ipuv3_fb.c @@ -38,8 +38,10 @@ DECLARE_GLOBAL_DATA_PTR; static int mxcfb_map_video_memory(struct fb_info *fbi); static int mxcfb_unmap_video_memory(struct fb_info *fbi); +#if !CONFIG_IS_ENABLED(DM_VIDEO) /* graphics setup */ static GraphicDevice panel; +#endif static struct fb_videomode const *gmode; static uint8_t gdisp; static uint32_t gpixfmt; @@ -120,27 +122,6 @@ static uint32_t bpp_to_pixfmt(struct fb_info *fbi) return pixfmt; } -/* - * Set fixed framebuffer parameters based on variable settings. - * - * @param info framebuffer information pointer - */ -static int mxcfb_set_fix(struct fb_info *info) -{ - struct fb_fix_screeninfo *fix = &info->fix; - struct fb_var_screeninfo *var = &info->var; - - fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; - - fix->type = FB_TYPE_PACKED_PIXELS; - fix->accel = FB_ACCEL_NONE; - fix->visual = FB_VISUAL_TRUECOLOR; - fix->xpanstep = 1; - fix->ypanstep = 1; - - return 0; -} - static int setup_disp_channel1(struct fb_info *fbi) { ipu_channel_params_t params; @@ -226,7 +207,6 @@ static int mxcfb_set_par(struct fb_info *fbi) ipu_disable_channel(mxc_fbi->ipu_ch); ipu_uninit_channel(mxc_fbi->ipu_ch); - mxcfb_set_fix(fbi); mem_len = fbi->var.yres_virtual * fbi->fix.line_length; if (!fbi->fix.smem_start || (mem_len > fbi->fix.smem_len)) { @@ -499,6 +479,8 @@ static struct fb_info *mxcfb_init_fbinfo(void) return fbi; } +extern struct clk *g_ipu_clk; + /* * Probe routine for the framebuffer driver. It is called during the * driver binding process. The following functions are performed in @@ -512,16 +494,14 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp, { struct fb_info *fbi; struct mxcfb_info *mxcfbi; - int ret = 0; /* * Initialize FB structures */ fbi = mxcfb_init_fbinfo(); - if (!fbi) { - ret = -ENOMEM; - goto err0; - } + if (!fbi) + return -ENOMEM; + mxcfbi = (struct mxcfb_info *)fbi->par; if (!g_dp_in_use) { @@ -534,9 +514,11 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp, mxcfbi->ipu_di = disp; + if (!ipu_clk_enabled()) + clk_enable(g_ipu_clk); + ipu_disp_set_global_alpha(mxcfbi->ipu_ch, 1, 0x80); ipu_disp_set_color_key(mxcfbi->ipu_ch, 0, 0); - strcpy(fbi->fix.id, "DISP3 BG"); g_dp_in_use = 1; @@ -547,7 +529,8 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp, mxcfbi->ipu_di_pix_fmt = interface_pix_fmt; fb_videomode_to_var(&fbi->var, mode); fbi->var.bits_per_pixel = 16; - fbi->fix.line_length = fbi->var.xres * (fbi->var.bits_per_pixel / 8); + fbi->fix.line_length = fbi->var.xres_virtual * + (fbi->var.bits_per_pixel / 8); fbi->fix.smem_len = fbi->var.yres_virtual * fbi->fix.line_length; mxcfb_check_var(&fbi->var, fbi); @@ -555,14 +538,13 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp, /* Default Y virtual size is 2x panel size */ fbi->var.yres_virtual = fbi->var.yres * 2; - mxcfb_set_fix(fbi); - /* allocate fb first */ if (mxcfb_map_video_memory(fbi) < 0) return -ENOMEM; mxcfb_set_par(fbi); +#if !CONFIG_IS_ENABLED(DM_VIDEO) panel.winSizeX = mode->xres; panel.winSizeY = mode->yres; panel.plnSizeX = mode->xres; @@ -573,13 +555,12 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp, panel.gdfBytesPP = 2; panel.gdfIndex = GDF_16BIT_565RGB; - +#endif +#ifdef DEBUG ipu_dump_registers(); +#endif return 0; - -err0: - return ret; } void ipuv3_fb_shutdown(void) @@ -604,6 +585,7 @@ void ipuv3_fb_shutdown(void) } } +#if !CONFIG_IS_ENABLED(DM_VIDEO) void *video_hw_init(void) { int ret; @@ -618,6 +600,7 @@ void *video_hw_init(void) return (void *)&panel; } +#endif int ipuv3_fb_init(struct fb_videomode const *mode, uint8_t disp, @@ -710,8 +693,12 @@ static int ipuv3_video_bind(struct udevice *dev) } static const struct udevice_id ipuv3_video_ids[] = { +#ifdef CONFIG_ARCH_MX6 { .compatible = "fsl,imx6q-ipu" }, +#endif +#ifdef CONFIG_ARCH_MX5 { .compatible = "fsl,imx53-ipu" }, +#endif { } }; -- cgit v1.3.1 From 22b897a12323364c584b1ff31fe9f5250e0d3481 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Sat, 23 May 2020 17:11:20 +0200 Subject: video: extend stdout video console work-around for 'vga' cfb_console driver uses 'vga' console name and we still have board environments defining this name. Re-use existing DM_VIDEO work- around for console name to support 'vga' name in stdout environment. Signed-off-by: Anatolij Gustschin Tested-by: Soeren Moch Reviewed-by: Simon Glass Reviewed-by: Tom Rini --- arch/arm/mach-tegra/Kconfig | 1 - common/console.c | 7 ++++--- drivers/video/Kconfig | 16 +++++++++------- 3 files changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 00facf492e0..15e76840281 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -58,7 +58,6 @@ config TEGRA_COMMON select MISC select OF_CONTROL select SPI - select VIDCONSOLE_AS_LCD if DM_VIDEO imply CMD_DM imply CRC32_VERIFY diff --git a/common/console.c b/common/console.c index 1deca3cb78f..f149624954a 100644 --- a/common/console.c +++ b/common/console.c @@ -713,7 +713,7 @@ struct stdio_dev *search_device(int flags, const char *name) dev = stdio_get_by_name(name); #ifdef CONFIG_VIDCONSOLE_AS_LCD - if (!dev && !strcmp(name, "lcd")) + if (!dev && !strcmp(name, CONFIG_VIDCONSOLE_AS_LCD)) dev = stdio_get_by_name("vidconsole"); #endif @@ -897,8 +897,9 @@ done: stdio_print_current_devices(); #endif /* CONFIG_SYS_CONSOLE_INFO_QUIET */ #ifdef CONFIG_VIDCONSOLE_AS_LCD - if (strstr(stdoutname, "lcd")) - printf("Warning: Please change 'lcd' to 'vidconsole' in stdout/stderr environment vars\n"); + if (strstr(stdoutname, CONFIG_VIDCONSOLE_AS_LCD)) + printf("Warning: Please change '%s' to 'vidconsole' in stdout/stderr environment vars\n", + CONFIG_VIDCONSOLE_AS_LCD); #endif #ifdef CONFIG_SYS_CONSOLE_ENV_OVERWRITE diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index aaea7ce743f..01e8dbf678b 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -177,14 +177,16 @@ config SIMPLE_PANEL source "drivers/video/fonts/Kconfig" config VIDCONSOLE_AS_LCD - bool "Use 'vidconsole' when 'lcd' is seen in stdout" + string "Use 'vidconsole' when string defined here is seen in stdout" depends on DM_VIDEO - help - This is a work-around for boards which have 'lcd' in their stdout - environment variable, but have moved to use driver model for video. - In this case the console will no-longer work. While it is possible - to update the environment, the breakage may be confusing for users. - This option will be removed around the end of 2016. + default "lcd" if LCD || TEGRA_COMMON + default "vga" if !LCD + help + This is a work-around for boards which have 'lcd' or 'vga' in their + stdout environment variable, but have moved to use driver model for + video. In this case the console will no-longer work. While it is + possible to update the environment, the breakage may be confusing for + users. This option will be removed around the end of 2020. config VIDEO_COREBOOT bool "Enable coreboot framebuffer driver support" -- cgit v1.3.1 From 0a5be6c5fd031fbdcd499500ad02608008329b29 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 13:06:48 +0200 Subject: net: eepro100: Remove EEPRO100_SROM_WRITE This code is never enabled, last board that used it was ELPPC which was removed some 5 years ago, so just remove this code altogether. Signed-off-by: Marek Vasut --- README | 2 - drivers/net/eepro100.c | 87 -------------------------------------------- scripts/config_whitelist.txt | 1 - 3 files changed, 90 deletions(-) (limited to 'drivers') diff --git a/README b/README index bcf19836311..b49154076e9 100644 --- a/README +++ b/README @@ -891,8 +891,6 @@ The following options need to be configured: CONFIG_EEPRO100 Support for Intel 82557/82559/82559ER chips. - Optional CONFIG_EEPRO100_SROM_WRITE enables EEPROM - write routine for first time initialisation. CONFIG_TULIP Support for Digital 2114x chips. diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index e186ab4e5f2..62a0dc75229 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -781,93 +781,6 @@ static int read_eeprom (struct eth_device *dev, int location, int addr_len) return retval; } -#ifdef CONFIG_EEPRO100_SROM_WRITE -int eepro100_write_eeprom (struct eth_device* dev, int location, int addr_len, unsigned short data) -{ - unsigned short dataval; - int enable_cmd = 0x3f | EE_EWENB_CMD; - int write_cmd = location | EE_WRITE_CMD; - int i; - unsigned long datalong, tmplong; - - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB, SCBeeprom); - - /* Shift the enable command bits out. */ - for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--) - { - dataval = (enable_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay(1); - } - - OUTW(dev, EE_ENB, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB, SCBeeprom); - - - /* Shift the write command bits out. */ - for (i = (addr_len+EE_CMD_BITS-1); i >= 0; i--) - { - dataval = (write_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay(1); - } - - /* Write the data */ - datalong= (unsigned long) ((((data) & 0x00ff) << 8) | ( (data) >> 8)); - - for (i = 0; i< EE_DATA_BITS; i++) - { - /* Extract and move data bit to bit DI */ - dataval = ((datalong & 0x8000)>>13) ? EE_DATA_WRITE : 0; - - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); - udelay(1); - OUTW(dev, EE_ENB | dataval, SCBeeprom); - udelay(1); - - datalong = datalong << 1; /* Adjust significant data bit*/ - } - - /* Finish up command (toggle CS) */ - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - udelay(1); /* delay for more than 250 ns */ - OUTW(dev, EE_ENB, SCBeeprom); - - /* Wait for programming ready (D0 = 1) */ - tmplong = 10; - do - { - dataval = INW(dev, SCBeeprom); - if (dataval & EE_DATA_READ) - break; - udelay(10000); - } - while (-- tmplong); - - if (tmplong == 0) - { - printf ("Write i82559 eeprom timed out (100 ms waiting for data ready.\n"); - return -1; - } - - /* Terminate the EEPROM access. */ - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - - return 0; -} -#endif - static void init_rx_ring (struct eth_device *dev) { int i; diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 2210f46e446..86350ab9c85 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -400,7 +400,6 @@ CONFIG_EDB93XX_SDCS1 CONFIG_EDB93XX_SDCS2 CONFIG_EDB93XX_SDCS3 CONFIG_EEPRO100 -CONFIG_EEPRO100_SROM_WRITE CONFIG_EFLASH_PROTSECTORS CONFIG_EHCI_DESC_BIG_ENDIAN CONFIG_EHCI_HCD_INIT_AFTER_RESET -- cgit v1.3.1 From aba283d838bf5e5c227f2b779feba583c3964c90 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 12:49:16 +0200 Subject: net: eepro100: Clean up comments Clean the comments up to they trigger fewer checkpatch warnings, no functional change. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 100 ++++++++++++++++++------------------------------- 1 file changed, 36 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 62a0dc75229..503c44af4c1 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -15,8 +15,7 @@ #undef DEBUG - /* Ethernet chip registers. - */ +/* Ethernet chip registers. */ #define SCBStatus 0 /* Rx/Command Unit Status *Word* */ #define SCBIntAckByte 1 /* Rx/Command Unit STAT/ACK byte */ #define SCBCmd 2 /* Rx/Command Unit Command *Word* */ @@ -30,8 +29,7 @@ #define SCBGenControl 28 /* 82559 General Control Register */ #define SCBGenStatus 29 /* 82559 General Status register */ - /* 82559 SCB status word defnitions - */ +/* 82559 SCB status word defnitions */ #define SCB_STATUS_CX 0x8000 /* CU finished command (transmit) */ #define SCB_STATUS_FR 0x4000 /* frame received */ #define SCB_STATUS_CNA 0x2000 /* CU left active state */ @@ -45,8 +43,7 @@ #define SCB_INTACK_TX (SCB_STATUS_CX | SCB_STATUS_CNA) #define SCB_INTACK_RX (SCB_STATUS_FR | SCB_STATUS_RNR) - /* System control block commands - */ +/* System control block commands */ /* CU Commands */ #define CU_NOP 0x0000 #define CU_START 0x0010 @@ -81,16 +78,14 @@ #define RU_STATUS_NO_RBDS_NORES ((2<<2)|(8<<2)) #define RU_STATUS_NO_RBDS_READY ((4<<2)|(8<<2)) - /* 82559 Port interface commands. - */ +/* 82559 Port interface commands. */ #define I82559_RESET 0x00000000 /* Software reset */ #define I82559_SELFTEST 0x00000001 /* 82559 Selftest command */ #define I82559_SELECTIVE_RESET 0x00000002 #define I82559_DUMP 0x00000003 #define I82559_DUMP_WAKEUP 0x00000007 - /* 82559 Eeprom interface. - */ +/* 82559 Eeprom interface. */ #define EE_SHIFT_CLK 0x01 /* EEPROM shift clock. */ #define EE_CS 0x02 /* EEPROM chip select. */ #define EE_DATA_WRITE 0x04 /* EEPROM chip data in. */ @@ -101,15 +96,13 @@ #define EE_CMD_BITS 3 #define EE_DATA_BITS 16 - /* The EEPROM commands include the alway-set leading bit. - */ +/* The EEPROM commands include the alway-set leading bit. */ #define EE_EWENB_CMD (4 << addr_len) #define EE_WRITE_CMD (5 << addr_len) #define EE_READ_CMD (6 << addr_len) #define EE_ERASE_CMD (7 << addr_len) - /* Receive frame descriptors. - */ +/* Receive frame descriptors. */ struct RxFD { volatile u16 status; volatile u16 control; @@ -143,8 +136,7 @@ struct RxFD { #define RFD_RX_IA_MATCH 0x0002 /* individual address does not match */ #define RFD_RX_TCO 0x0001 /* TCO indication */ - /* Transmit frame descriptors - */ +/* Transmit frame descriptors */ struct TxFD { /* Transmit frame descriptor set. */ volatile u16 status; volatile u16 command; @@ -152,9 +144,9 @@ struct TxFD { /* Transmit frame descriptor set. */ volatile u32 tx_desc_addr; /* Always points to the tx_buf_addr element. */ volatile s32 count; - volatile u32 tx_buf_addr0; /* void *, frame to be transmitted. */ + volatile u32 tx_buf_addr0; /* void *, frame to be transmitted. */ volatile s32 tx_buf_size0; /* Length of Tx frame. */ - volatile u32 tx_buf_addr1; /* void *, frame to be transmitted. */ + volatile u32 tx_buf_addr1; /* void *, frame to be transmitted. */ volatile s32 tx_buf_size1; /* Length of Tx frame. */ }; @@ -168,12 +160,11 @@ struct TxFD { /* Transmit frame descriptor set. */ #define TxCB_COUNT_MASK 0x3fff #define TxCB_COUNT_EOF 0x8000 - /* The Speedo3 Rx and Tx frame/buffer descriptors. - */ +/* The Speedo3 Rx and Tx frame/buffer descriptors. */ struct descriptor { /* A generic descriptor. */ volatile u16 status; volatile u16 command; - volatile u32 link; /* struct descriptor * */ + volatile u32 link; /* struct descriptor * */ unsigned char params[0]; }; @@ -187,15 +178,14 @@ struct descriptor { /* A generic descriptor. */ #define CONFIG_SYS_STATUS_C 0x8000 #define CONFIG_SYS_STATUS_OK 0x2000 - /* Misc. - */ +/* Misc. */ #define NUM_RX_DESC PKTBUFSRX -#define NUM_TX_DESC 1 /* Number of TX descriptors */ +#define NUM_TX_DESC 1 /* Number of TX descriptors */ #define TOUT_LOOP 1000000 -static struct RxFD rx_ring[NUM_RX_DESC]; /* RX descriptor ring */ -static struct TxFD tx_ring[NUM_TX_DESC]; /* TX descriptor ring */ +static struct RxFD rx_ring[NUM_RX_DESC]; /* RX descriptor ring */ +static struct TxFD tx_ring[NUM_TX_DESC]; /* TX descriptor ring */ static int rx_next; /* RX descriptor ring pointer */ static int tx_next; /* TX descriptor ring pointer */ static int tx_threshold; @@ -293,7 +283,8 @@ static int set_phyreg (struct eth_device *dev, unsigned char addr, return 0; } -/* Check if given phyaddr is valid, i.e. there is a PHY connected. +/* + * Check if given phyaddr is valid, i.e. there is a PHY connected. * Do this by checking model value field from ID2 register. */ static struct eth_device* verify_phyaddr (const char *devname, @@ -363,8 +354,7 @@ static int eepro100_miiphy_write(struct mii_dev *bus, int addr, int devad, #endif -/* Wait for the chip get the command. -*/ +/* Wait for the chip get the command. */ static int wait_for_eepro100 (struct eth_device *dev) { int i; @@ -394,8 +384,7 @@ int eepro100_initialize (bd_t * bis) int idx = 0; while (1) { - /* Find PCI device - */ + /* Find PCI device */ if ((devno = pci_find_devices (supported, idx++)) < 0) { break; } @@ -412,8 +401,7 @@ int eepro100_initialize (bd_t * bis) PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - /* Check if I/O accesses and Bus Mastering are enabled. - */ + /* Check if I/O accesses and Bus Mastering are enabled. */ pci_read_config_dword (devno, PCI_COMMAND, &status); if (!(status & PCI_COMMAND_MEMORY)) { printf ("Error: Can not enable MEM access.\n"); @@ -459,8 +447,7 @@ int eepro100_initialize (bd_t * bis) card_number++; - /* Set the latency timer for value. - */ + /* Set the latency timer for value. */ pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20); udelay(10 * 1000); @@ -478,8 +465,7 @@ static int eepro100_init (struct eth_device *dev, bd_t * bis) int tx_cur; struct descriptor *ias_cmd, *cfg_cmd; - /* Reset the ethernet controller - */ + /* Reset the ethernet controller */ OUTL (dev, I82559_SELECTIVE_RESET, SCBPort); udelay(20); @@ -500,13 +486,11 @@ static int eepro100_init (struct eth_device *dev, bd_t * bis) OUTL (dev, 0, SCBPointer); OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd); - /* Initialize Rx and Tx rings. - */ + /* Initialize Rx and Tx rings. */ init_rx_ring (dev); purge_tx_ring (dev); - /* Tell the adapter where the RX ring is located. - */ + /* Tell the adapter where the RX ring is located. */ if (!wait_for_eepro100 (dev)) { printf ("Error: Can not reset ethernet controller.\n"); goto Done; @@ -550,8 +534,7 @@ static int eepro100_init (struct eth_device *dev, bd_t * bis) goto Done; } - /* Send the Individual Address Setup frame - */ + /* Send the Individual Address Setup frame */ tx_cur = tx_next; tx_next = ((tx_next + 1) % NUM_TX_DESC); @@ -562,8 +545,7 @@ static int eepro100_init (struct eth_device *dev, bd_t * bis) memcpy (ias_cmd->params, dev->enetaddr, 6); - /* Tell the adapter where the TX ring is located. - */ + /* Tell the adapter where the TX ring is located. */ if (!wait_for_eepro100 (dev)) { printf ("Error: Can not reset ethernet controller.\n"); goto Done; @@ -626,8 +608,7 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) goto Done; } - /* Send the packet. - */ + /* Send the packet. */ OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer); OUTW (dev, SCB_M | CU_START, SCBCmd); @@ -666,21 +647,16 @@ static int eepro100_recv (struct eth_device *dev) break; } - /* Valid frame status. - */ + /* Valid frame status. */ if ((status & RFD_STATUS_OK)) { - /* A valid frame received. - */ + /* A valid frame received. */ length = le32_to_cpu (rx_ring[rx_next].count) & 0x3fff; - /* Pass the packet up to the protocol - * layers. - */ + /* Pass the packet up to the protocol layers. */ net_process_received_packet((u8 *)rx_ring[rx_next].data, length); } else { - /* There was an error. - */ + /* There was an error. */ printf ("RX error status = 0x%08X\n", status); } @@ -691,8 +667,7 @@ static int eepro100_recv (struct eth_device *dev) rx_prev = (rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC; rx_ring[rx_prev].control = 0; - /* Update entry information. - */ + /* Update entry information. */ rx_next = (rx_next + 1) % NUM_RX_DESC; } @@ -700,8 +675,7 @@ static int eepro100_recv (struct eth_device *dev) printf ("%s: Receiver is not ready, restart it !\n", dev->name); - /* Reinitialize Rx ring. - */ + /* Reinitialize Rx ring. */ init_rx_ring (dev); if (!wait_for_eepro100 (dev)) { @@ -719,8 +693,7 @@ static int eepro100_recv (struct eth_device *dev) static void eepro100_halt (struct eth_device *dev) { - /* Reset the ethernet controller - */ + /* Reset the ethernet controller */ OUTL (dev, I82559_SELECTIVE_RESET, SCBPort); udelay(20); @@ -745,8 +718,7 @@ static void eepro100_halt (struct eth_device *dev) return; } - /* SROM Read. - */ +/* SROM Read. */ static int read_eeprom (struct eth_device *dev, int location, int addr_len) { unsigned short retval = 0; -- cgit v1.3.1 From e5352c6bbe1606b4e2e9845dba54a83af14f3da0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 13:11:48 +0200 Subject: net: eepro100: Use plain debug() Convert all the ifdef DEBUG to plain debug(), no functional change. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 503c44af4c1..dd902386b14 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -13,8 +13,6 @@ #include #include -#undef DEBUG - /* Ethernet chip registers. */ #define SCBStatus 0 /* Rx/Command Unit Status *Word* */ #define SCBIntAckByte 1 /* Rx/Command Unit STAT/ACK byte */ @@ -392,10 +390,8 @@ int eepro100_initialize (bd_t * bis) pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, &iobase); iobase &= ~0xf; -#ifdef DEBUG - printf ("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n", - iobase); -#endif + debug("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n", + iobase); pci_write_config_dword (devno, PCI_COMMAND, @@ -810,10 +806,7 @@ static void read_hw_addr (struct eth_device *dev, bd_t * bis) if (sum != 0xBABA) { memset (dev->enetaddr, 0, ETH_ALEN); -#ifdef DEBUG - printf ("%s: Invalid EEPROM checksum %#4.4x, " - "check settings before activating this device!\n", - dev->name, sum); -#endif + debug("%s: Invalid EEPROM checksum %#4.4x, check settings before activating this device!\n", + dev->name, sum); } } -- cgit v1.3.1 From db9f1818bfc79fd96301b8b4eae1db8b136e7570 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 13:17:03 +0200 Subject: net: eepro100: Fix spacing This is automated cleanup via checkpatch, no functional change. ./scripts/checkpatch.pl --show-types -f drivers/net/eepro100.c ./scripts/checkpatch.pl --types SPACING -f --fix --fix-inplace drivers/net/eepro100.c Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 278 ++++++++++++++++++++++++------------------------- 1 file changed, 139 insertions(+), 139 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index dd902386b14..1b6d5375f81 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -68,13 +68,13 @@ #define CU_STATUS_MASK 0x00C0 #define RU_STATUS_MASK 0x003C -#define RU_STATUS_IDLE (0<<2) -#define RU_STATUS_SUS (1<<2) -#define RU_STATUS_NORES (2<<2) -#define RU_STATUS_READY (4<<2) -#define RU_STATUS_NO_RBDS_SUS ((1<<2)|(8<<2)) -#define RU_STATUS_NO_RBDS_NORES ((2<<2)|(8<<2)) -#define RU_STATUS_NO_RBDS_READY ((4<<2)|(8<<2)) +#define RU_STATUS_IDLE (0 << 2) +#define RU_STATUS_SUS (1 << 2) +#define RU_STATUS_NORES (2 << 2) +#define RU_STATUS_READY (4 << 2) +#define RU_STATUS_NO_RBDS_SUS ((1 << 2) | (8 << 2)) +#define RU_STATUS_NO_RBDS_NORES ((2 << 2) | (8 << 2)) +#define RU_STATUS_NO_RBDS_READY ((4 << 2) | (8 << 2)) /* 82559 Port interface commands. */ #define I82559_RESET 0x00000000 /* Software reset */ @@ -200,15 +200,15 @@ static const char i82558_config_cmd[] = { 0x31, 0x05, }; -static void init_rx_ring (struct eth_device *dev); -static void purge_tx_ring (struct eth_device *dev); +static void init_rx_ring(struct eth_device *dev); +static void purge_tx_ring(struct eth_device *dev); -static void read_hw_addr (struct eth_device *dev, bd_t * bis); +static void read_hw_addr(struct eth_device *dev, bd_t * bis); -static int eepro100_init (struct eth_device *dev, bd_t * bis); +static int eepro100_init(struct eth_device *dev, bd_t * bis); static int eepro100_send(struct eth_device *dev, void *packet, int length); -static int eepro100_recv (struct eth_device *dev); -static void eepro100_halt (struct eth_device *dev); +static int eepro100_recv(struct eth_device *dev); +static void eepro100_halt(struct eth_device *dev); #if defined(CONFIG_E500) #define bus_to_phys(a) (a) @@ -218,28 +218,28 @@ static void eepro100_halt (struct eth_device *dev); #define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) #endif -static inline int INW (struct eth_device *dev, u_long addr) +static inline int INW(struct eth_device *dev, u_long addr) { return le16_to_cpu(*(volatile u16 *)(addr + (u_long)dev->iobase)); } -static inline void OUTW (struct eth_device *dev, int command, u_long addr) +static inline void OUTW(struct eth_device *dev, int command, u_long addr) { *(volatile u16 *)((addr + (u_long)dev->iobase)) = cpu_to_le16(command); } -static inline void OUTL (struct eth_device *dev, int command, u_long addr) +static inline void OUTL(struct eth_device *dev, int command, u_long addr) { *(volatile u32 *)((addr + (u_long)dev->iobase)) = cpu_to_le32(command); } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -static inline int INL (struct eth_device *dev, u_long addr) +static inline int INL(struct eth_device *dev, u_long addr) { return le32_to_cpu(*(volatile u32 *)(addr + (u_long)dev->iobase)); } -static int get_phyreg (struct eth_device *dev, unsigned char addr, +static int get_phyreg(struct eth_device *dev, unsigned char addr, unsigned char reg, unsigned short *value) { int cmd; @@ -247,22 +247,22 @@ static int get_phyreg (struct eth_device *dev, unsigned char addr, /* read requested data */ cmd = (2 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - OUTL (dev, cmd, SCBCtrlMDI); + OUTL(dev, cmd, SCBCtrlMDI); do { udelay(1000); - cmd = INL (dev, SCBCtrlMDI); + cmd = INL(dev, SCBCtrlMDI); } while (!(cmd & (1 << 28)) && (--timeout)); if (timeout == 0) return -1; - *value = (unsigned short) (cmd & 0xffff); + *value = (unsigned short)(cmd & 0xffff); return 0; } -static int set_phyreg (struct eth_device *dev, unsigned char addr, +static int set_phyreg(struct eth_device *dev, unsigned char addr, unsigned char reg, unsigned short value) { int cmd; @@ -270,9 +270,9 @@ static int set_phyreg (struct eth_device *dev, unsigned char addr, /* write requested data */ cmd = (1 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - OUTL (dev, cmd | value, SCBCtrlMDI); + OUTL(dev, cmd | value, SCBCtrlMDI); - while (!(INL (dev, SCBCtrlMDI) & (1 << 28)) && (--timeout)) + while (!(INL(dev, SCBCtrlMDI) & (1 << 28)) && (--timeout)) udelay(1000); if (timeout == 0) @@ -285,7 +285,7 @@ static int set_phyreg (struct eth_device *dev, unsigned char addr, * Check if given phyaddr is valid, i.e. there is a PHY connected. * Do this by checking model value field from ID2 register. */ -static struct eth_device* verify_phyaddr (const char *devname, +static struct eth_device* verify_phyaddr(const char *devname, unsigned char addr) { struct eth_device *dev; @@ -353,11 +353,11 @@ static int eepro100_miiphy_write(struct mii_dev *bus, int addr, int devad, #endif /* Wait for the chip get the command. */ -static int wait_for_eepro100 (struct eth_device *dev) +static int wait_for_eepro100(struct eth_device *dev) { int i; - for (i = 0; INW (dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) { + for (i = 0; INW(dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) { if (i >= TOUT_LOOP) { return 0; } @@ -373,7 +373,7 @@ static struct pci_device_id supported[] = { {} }; -int eepro100_initialize (bd_t * bis) +int eepro100_initialize(bd_t * bis) { pci_dev_t devno; int card_number = 0; @@ -383,50 +383,50 @@ int eepro100_initialize (bd_t * bis) while (1) { /* Find PCI device */ - if ((devno = pci_find_devices (supported, idx++)) < 0) { + if ((devno = pci_find_devices(supported, idx++)) < 0) { break; } - pci_read_config_dword (devno, PCI_BASE_ADDRESS_0, &iobase); + pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase); iobase &= ~0xf; debug("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n", iobase); - pci_write_config_dword (devno, + pci_write_config_dword(devno, PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); /* Check if I/O accesses and Bus Mastering are enabled. */ - pci_read_config_dword (devno, PCI_COMMAND, &status); + pci_read_config_dword(devno, PCI_COMMAND, &status); if (!(status & PCI_COMMAND_MEMORY)) { - printf ("Error: Can not enable MEM access.\n"); + printf("Error: Can not enable MEM access.\n"); continue; } if (!(status & PCI_COMMAND_MASTER)) { - printf ("Error: Can not enable Bus Mastering.\n"); + printf("Error: Can not enable Bus Mastering.\n"); continue; } - dev = (struct eth_device *) malloc (sizeof *dev); + dev = (struct eth_device *)malloc(sizeof *dev); if (!dev) { printf("eepro100: Can not allocate memory\n"); break; } memset(dev, 0, sizeof(*dev)); - sprintf (dev->name, "i82559#%d", card_number); - dev->priv = (void *) devno; /* this have to come before bus_to_phys() */ - dev->iobase = bus_to_phys (iobase); + sprintf(dev->name, "i82559#%d", card_number); + dev->priv = (void *)devno; /* this have to come before bus_to_phys() */ + dev->iobase = bus_to_phys(iobase); dev->init = eepro100_init; dev->halt = eepro100_halt; dev->send = eepro100_send; dev->recv = eepro100_recv; - eth_register (dev); + eth_register(dev); -#if defined (CONFIG_MII) || defined(CONFIG_CMD_MII) +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) /* register mii command access routines */ int retval; struct mii_dev *mdiodev = mdio_alloc(); @@ -444,89 +444,89 @@ int eepro100_initialize (bd_t * bis) card_number++; /* Set the latency timer for value. */ - pci_write_config_byte (devno, PCI_LATENCY_TIMER, 0x20); + pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20); udelay(10 * 1000); - read_hw_addr (dev, bis); + read_hw_addr(dev, bis); } return card_number; } -static int eepro100_init (struct eth_device *dev, bd_t * bis) +static int eepro100_init(struct eth_device *dev, bd_t * bis) { int i, status = -1; int tx_cur; struct descriptor *ias_cmd, *cfg_cmd; /* Reset the ethernet controller */ - OUTL (dev, I82559_SELECTIVE_RESET, SCBPort); + OUTL(dev, I82559_SELECTIVE_RESET, SCBPort); udelay(20); - OUTL (dev, I82559_RESET, SCBPort); + OUTL(dev, I82559_RESET, SCBPort); udelay(20); - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); + if (!wait_for_eepro100(dev)) { + printf("Error: Can not reset ethernet controller.\n"); goto Done; } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd); + OUTL(dev, 0, SCBPointer); + OUTW(dev, SCB_M | RUC_ADDR_LOAD, SCBCmd); - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); + if (!wait_for_eepro100(dev)) { + printf("Error: Can not reset ethernet controller.\n"); goto Done; } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd); + OUTL(dev, 0, SCBPointer); + OUTW(dev, SCB_M | CU_ADDR_LOAD, SCBCmd); /* Initialize Rx and Tx rings. */ - init_rx_ring (dev); - purge_tx_ring (dev); + init_rx_ring(dev); + purge_tx_ring(dev); /* Tell the adapter where the RX ring is located. */ - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); + if (!wait_for_eepro100(dev)) { + printf("Error: Can not reset ethernet controller.\n"); goto Done; } - OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer); - OUTW (dev, SCB_M | RUC_START, SCBCmd); + OUTL(dev, phys_to_bus((u32)&rx_ring[rx_next]), SCBPointer); + OUTW(dev, SCB_M | RUC_START, SCBCmd); /* Send the Configure frame */ tx_cur = tx_next; tx_next = ((tx_next + 1) % NUM_TX_DESC); - cfg_cmd = (struct descriptor *) &tx_ring[tx_cur]; + cfg_cmd = (struct descriptor *)&tx_ring[tx_cur]; cfg_cmd->command = cpu_to_le16 ((CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_CONFIGURE)); cfg_cmd->status = 0; - cfg_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next])); + cfg_cmd->link = cpu_to_le32 (phys_to_bus((u32)&tx_ring[tx_next])); - memcpy (cfg_cmd->params, i82558_config_cmd, - sizeof (i82558_config_cmd)); + memcpy(cfg_cmd->params, i82558_config_cmd, + sizeof(i82558_config_cmd)); - if (!wait_for_eepro100 (dev)) { - printf ("Error---CONFIG_SYS_CMD_CONFIGURE: Can not reset ethernet controller.\n"); + if (!wait_for_eepro100(dev)) { + printf("Error---CONFIG_SYS_CMD_CONFIGURE: Can not reset ethernet controller.\n"); goto Done; } - OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer); - OUTW (dev, SCB_M | CU_START, SCBCmd); + OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCBPointer); + OUTW(dev, SCB_M | CU_START, SCBCmd); for (i = 0; - !(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); + !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); i++) { if (i >= TOUT_LOOP) { - printf ("%s: Tx error buffer not ready\n", dev->name); + printf("%s: Tx error buffer not ready\n", dev->name); goto Done; } } - if (!(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { - printf ("TX error status = 0x%08X\n", - le16_to_cpu (tx_ring[tx_cur].status)); + if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { + printf("TX error status = 0x%08X\n", + le16_to_cpu(tx_ring[tx_cur].status)); goto Done; } @@ -534,34 +534,34 @@ static int eepro100_init (struct eth_device *dev, bd_t * bis) tx_cur = tx_next; tx_next = ((tx_next + 1) % NUM_TX_DESC); - ias_cmd = (struct descriptor *) &tx_ring[tx_cur]; + ias_cmd = (struct descriptor *)&tx_ring[tx_cur]; ias_cmd->command = cpu_to_le16 ((CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_IAS)); ias_cmd->status = 0; - ias_cmd->link = cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next])); + ias_cmd->link = cpu_to_le32 (phys_to_bus((u32)&tx_ring[tx_next])); - memcpy (ias_cmd->params, dev->enetaddr, 6); + memcpy(ias_cmd->params, dev->enetaddr, 6); /* Tell the adapter where the TX ring is located. */ - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); + if (!wait_for_eepro100(dev)) { + printf("Error: Can not reset ethernet controller.\n"); goto Done; } - OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer); - OUTW (dev, SCB_M | CU_START, SCBCmd); + OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCBPointer); + OUTW(dev, SCB_M | CU_START, SCBCmd); - for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); + for (i = 0; !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); i++) { if (i >= TOUT_LOOP) { - printf ("%s: Tx error buffer not ready\n", + printf("%s: Tx error buffer not ready\n", dev->name); goto Done; } } - if (!(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { - printf ("TX error status = 0x%08X\n", - le16_to_cpu (tx_ring[tx_cur].status)); + if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { + printf("TX error status = 0x%08X\n", + le16_to_cpu(tx_ring[tx_cur].status)); goto Done; } @@ -577,48 +577,48 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) int tx_cur; if (length <= 0) { - printf ("%s: bad packet size: %d\n", dev->name, length); + printf("%s: bad packet size: %d\n", dev->name, length); goto Done; } tx_cur = tx_next; tx_next = (tx_next + 1) % NUM_TX_DESC; - tx_ring[tx_cur].command = cpu_to_le16 ( TxCB_CMD_TRANSMIT | + tx_ring[tx_cur].command = cpu_to_le16 (TxCB_CMD_TRANSMIT | TxCB_CMD_SF | TxCB_CMD_S | - TxCB_CMD_EL ); + TxCB_CMD_EL); tx_ring[tx_cur].status = 0; tx_ring[tx_cur].count = cpu_to_le32 (tx_threshold); tx_ring[tx_cur].link = - cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_next])); + cpu_to_le32 (phys_to_bus((u32)&tx_ring[tx_next])); tx_ring[tx_cur].tx_desc_addr = - cpu_to_le32 (phys_to_bus ((u32) & tx_ring[tx_cur].tx_buf_addr0)); + cpu_to_le32 (phys_to_bus((u32)&tx_ring[tx_cur].tx_buf_addr0)); tx_ring[tx_cur].tx_buf_addr0 = - cpu_to_le32 (phys_to_bus ((u_long) packet)); + cpu_to_le32 (phys_to_bus((u_long)packet)); tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32 (length); - if (!wait_for_eepro100 (dev)) { - printf ("%s: Tx error ethernet controller not ready.\n", + if (!wait_for_eepro100(dev)) { + printf("%s: Tx error ethernet controller not ready.\n", dev->name); goto Done; } /* Send the packet. */ - OUTL (dev, phys_to_bus ((u32) & tx_ring[tx_cur]), SCBPointer); - OUTW (dev, SCB_M | CU_START, SCBCmd); + OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCBPointer); + OUTW(dev, SCB_M | CU_START, SCBCmd); - for (i = 0; !(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); + for (i = 0; !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); i++) { if (i >= TOUT_LOOP) { - printf ("%s: Tx error buffer not ready\n", dev->name); + printf("%s: Tx error buffer not ready\n", dev->name); goto Done; } } - if (!(le16_to_cpu (tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { - printf ("TX error status = 0x%08X\n", - le16_to_cpu (tx_ring[tx_cur].status)); + if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { + printf("TX error status = 0x%08X\n", + le16_to_cpu(tx_ring[tx_cur].status)); goto Done; } @@ -628,16 +628,16 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) return status; } -static int eepro100_recv (struct eth_device *dev) +static int eepro100_recv(struct eth_device *dev) { u16 status, stat; int rx_prev, length = 0; - stat = INW (dev, SCBStatus); - OUTW (dev, stat & SCB_STATUS_RNR, SCBStatus); + stat = INW(dev, SCBStatus); + OUTW(dev, stat & SCB_STATUS_RNR, SCBStatus); for (;;) { - status = le16_to_cpu (rx_ring[rx_next].status); + status = le16_to_cpu(rx_ring[rx_next].status); if (!(status & RFD_STATUS_C)) { break; @@ -646,14 +646,14 @@ static int eepro100_recv (struct eth_device *dev) /* Valid frame status. */ if ((status & RFD_STATUS_OK)) { /* A valid frame received. */ - length = le32_to_cpu (rx_ring[rx_next].count) & 0x3fff; + length = le32_to_cpu(rx_ring[rx_next].count) & 0x3fff; /* Pass the packet up to the protocol layers. */ net_process_received_packet((u8 *)rx_ring[rx_next].data, length); } else { /* There was an error. */ - printf ("RX error status = 0x%08X\n", status); + printf("RX error status = 0x%08X\n", status); } rx_ring[rx_next].control = cpu_to_le16 (RFD_CONTROL_S); @@ -669,87 +669,87 @@ static int eepro100_recv (struct eth_device *dev) if (stat & SCB_STATUS_RNR) { - printf ("%s: Receiver is not ready, restart it !\n", dev->name); + printf("%s: Receiver is not ready, restart it !\n", dev->name); /* Reinitialize Rx ring. */ - init_rx_ring (dev); + init_rx_ring(dev); - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not restart ethernet controller.\n"); + if (!wait_for_eepro100(dev)) { + printf("Error: Can not restart ethernet controller.\n"); goto Done; } - OUTL (dev, phys_to_bus ((u32) & rx_ring[rx_next]), SCBPointer); - OUTW (dev, SCB_M | RUC_START, SCBCmd); + OUTL(dev, phys_to_bus((u32)&rx_ring[rx_next]), SCBPointer); + OUTW(dev, SCB_M | RUC_START, SCBCmd); } Done: return length; } -static void eepro100_halt (struct eth_device *dev) +static void eepro100_halt(struct eth_device *dev) { /* Reset the ethernet controller */ - OUTL (dev, I82559_SELECTIVE_RESET, SCBPort); + OUTL(dev, I82559_SELECTIVE_RESET, SCBPort); udelay(20); - OUTL (dev, I82559_RESET, SCBPort); + OUTL(dev, I82559_RESET, SCBPort); udelay(20); - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); + if (!wait_for_eepro100(dev)) { + printf("Error: Can not reset ethernet controller.\n"); goto Done; } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | RUC_ADDR_LOAD, SCBCmd); + OUTL(dev, 0, SCBPointer); + OUTW(dev, SCB_M | RUC_ADDR_LOAD, SCBCmd); - if (!wait_for_eepro100 (dev)) { - printf ("Error: Can not reset ethernet controller.\n"); + if (!wait_for_eepro100(dev)) { + printf("Error: Can not reset ethernet controller.\n"); goto Done; } - OUTL (dev, 0, SCBPointer); - OUTW (dev, SCB_M | CU_ADDR_LOAD, SCBCmd); + OUTL(dev, 0, SCBPointer); + OUTW(dev, SCB_M | CU_ADDR_LOAD, SCBCmd); Done: return; } /* SROM Read. */ -static int read_eeprom (struct eth_device *dev, int location, int addr_len) +static int read_eeprom(struct eth_device *dev, int location, int addr_len) { unsigned short retval = 0; int read_cmd = location | EE_READ_CMD; int i; - OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom); - OUTW (dev, EE_ENB, SCBeeprom); + OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); + OUTW(dev, EE_ENB, SCBeeprom); /* Shift the read command bits out. */ for (i = 12; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW (dev, EE_ENB | dataval, SCBeeprom); + OUTW(dev, EE_ENB | dataval, SCBeeprom); udelay(1); - OUTW (dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); + OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); udelay(1); } - OUTW (dev, EE_ENB, SCBeeprom); + OUTW(dev, EE_ENB, SCBeeprom); for (i = 15; i >= 0; i--) { - OUTW (dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom); + OUTW(dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom); udelay(1); retval = (retval << 1) | - ((INW (dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0); - OUTW (dev, EE_ENB, SCBeeprom); + ((INW(dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0); + OUTW(dev, EE_ENB, SCBeeprom); udelay(1); } /* Terminate the EEPROM access. */ - OUTW (dev, EE_ENB & ~EE_CS, SCBeeprom); + OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); return retval; } -static void init_rx_ring (struct eth_device *dev) +static void init_rx_ring(struct eth_device *dev) { int i; @@ -759,7 +759,7 @@ static void init_rx_ring (struct eth_device *dev) (i == NUM_RX_DESC - 1) ? cpu_to_le16 (RFD_CONTROL_S) : 0; rx_ring[i].link = cpu_to_le32 (phys_to_bus - ((u32) & rx_ring[(i + 1) % NUM_RX_DESC])); + ((u32)&rx_ring[(i + 1) % NUM_RX_DESC])); rx_ring[i].rx_buf_addr = 0xffffffff; rx_ring[i].count = cpu_to_le32 (PKTSIZE_ALIGN << 16); } @@ -767,7 +767,7 @@ static void init_rx_ring (struct eth_device *dev) rx_next = 0; } -static void purge_tx_ring (struct eth_device *dev) +static void purge_tx_ring(struct eth_device *dev) { int i; @@ -788,14 +788,14 @@ static void purge_tx_ring (struct eth_device *dev) } } -static void read_hw_addr (struct eth_device *dev, bd_t * bis) +static void read_hw_addr(struct eth_device *dev, bd_t * bis) { u16 sum = 0; int i, j; - int addr_len = read_eeprom (dev, 0, 6) == 0xffff ? 8 : 6; + int addr_len = read_eeprom(dev, 0, 6) == 0xffff ? 8 : 6; for (j = 0, i = 0; i < 0x40; i++) { - u16 value = read_eeprom (dev, i, addr_len); + u16 value = read_eeprom(dev, i, addr_len); sum += value; if (i < 3) { @@ -805,7 +805,7 @@ static void read_hw_addr (struct eth_device *dev, bd_t * bis) } if (sum != 0xBABA) { - memset (dev->enetaddr, 0, ETH_ALEN); + memset(dev->enetaddr, 0, ETH_ALEN); debug("%s: Invalid EEPROM checksum %#4.4x, check settings before activating this device!\n", dev->name, sum); } -- cgit v1.3.1 From 9b12ff9911ec1a3b89648e0753e1d20d4d0ba2b0 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 13:20:14 +0200 Subject: net: eepro100: Fix braces This is automated cleanup via checkpatch, no functional change. ./scripts/checkpatch.pl --show-types -f drivers/net/eepro100.c ./scripts/checkpatch.pl --types BRACES -f --fix --fix-inplace drivers/net/eepro100.c Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 1b6d5375f81..6dccd59bda6 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -358,9 +358,8 @@ static int wait_for_eepro100(struct eth_device *dev) int i; for (i = 0; INW(dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) { - if (i >= TOUT_LOOP) { + if (i >= TOUT_LOOP) return 0; - } } return 1; @@ -383,9 +382,9 @@ int eepro100_initialize(bd_t * bis) while (1) { /* Find PCI device */ - if ((devno = pci_find_devices(supported, idx++)) < 0) { + devno = pci_find_devices(supported, idx++); + if (devno < 0) break; - } pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase); iobase &= ~0xf; @@ -639,9 +638,8 @@ static int eepro100_recv(struct eth_device *dev) for (;;) { status = le16_to_cpu(rx_ring[rx_next].status); - if (!(status & RFD_STATUS_C)) { + if (!(status & RFD_STATUS_C)) break; - } /* Valid frame status. */ if ((status & RFD_STATUS_OK)) { @@ -668,7 +666,6 @@ static int eepro100_recv(struct eth_device *dev) } if (stat & SCB_STATUS_RNR) { - printf("%s: Receiver is not ready, restart it !\n", dev->name); /* Reinitialize Rx ring. */ -- cgit v1.3.1 From 773af836daee64743a51450ee25d758283d4281f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 13:21:43 +0200 Subject: net: eepro100: Fix parenthesis alignment This is automated cleanup via checkpatch, no functional change. ./scripts/checkpatch.pl --show-types -f drivers/net/eepro100.c ./scripts/checkpatch.pl --types PARENTHESIS_ALIGNMENT -f --fix --fix-inplace drivers/net/eepro100.c Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 6dccd59bda6..d367052cd2a 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -240,7 +240,7 @@ static inline int INL(struct eth_device *dev, u_long addr) } static int get_phyreg(struct eth_device *dev, unsigned char addr, - unsigned char reg, unsigned short *value) + unsigned char reg, unsigned short *value) { int cmd; int timeout = 50; @@ -263,7 +263,7 @@ static int get_phyreg(struct eth_device *dev, unsigned char addr, } static int set_phyreg(struct eth_device *dev, unsigned char addr, - unsigned char reg, unsigned short value) + unsigned char reg, unsigned short value) { int cmd; int timeout = 50; @@ -286,7 +286,7 @@ static int set_phyreg(struct eth_device *dev, unsigned char addr, * Do this by checking model value field from ID2 register. */ static struct eth_device* verify_phyaddr(const char *devname, - unsigned char addr) + unsigned char addr) { struct eth_device *dev; unsigned short value; @@ -393,7 +393,7 @@ int eepro100_initialize(bd_t * bis) iobase); pci_write_config_dword(devno, - PCI_COMMAND, + PCI_COMMAND, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); /* Check if I/O accesses and Bus Mastering are enabled. */ @@ -504,7 +504,7 @@ static int eepro100_init(struct eth_device *dev, bd_t * bis) cfg_cmd->link = cpu_to_le32 (phys_to_bus((u32)&tx_ring[tx_next])); memcpy(cfg_cmd->params, i82558_config_cmd, - sizeof(i82558_config_cmd)); + sizeof(i82558_config_cmd)); if (!wait_for_eepro100(dev)) { printf("Error---CONFIG_SYS_CMD_CONFIGURE: Can not reset ethernet controller.\n"); @@ -525,7 +525,7 @@ static int eepro100_init(struct eth_device *dev, bd_t * bis) if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { printf("TX error status = 0x%08X\n", - le16_to_cpu(tx_ring[tx_cur].status)); + le16_to_cpu(tx_ring[tx_cur].status)); goto Done; } @@ -553,14 +553,14 @@ static int eepro100_init(struct eth_device *dev, bd_t * bis) i++) { if (i >= TOUT_LOOP) { printf("%s: Tx error buffer not ready\n", - dev->name); + dev->name); goto Done; } } if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { printf("TX error status = 0x%08X\n", - le16_to_cpu(tx_ring[tx_cur].status)); + le16_to_cpu(tx_ring[tx_cur].status)); goto Done; } @@ -599,7 +599,7 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) if (!wait_for_eepro100(dev)) { printf("%s: Tx error ethernet controller not ready.\n", - dev->name); + dev->name); goto Done; } @@ -617,7 +617,7 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { printf("TX error status = 0x%08X\n", - le16_to_cpu(tx_ring[tx_cur].status)); + le16_to_cpu(tx_ring[tx_cur].status)); goto Done; } -- cgit v1.3.1 From 7a30873585c9da2221f652c091bab5e66d5d6653 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 13:23:13 +0200 Subject: net: eepro100: Fix pointer location This is automated cleanup via checkpatch, no functional change. ./scripts/checkpatch.pl --show-types -f drivers/net/eepro100.c ./scripts/checkpatch.pl --types POINTER_LOCATION -f --fix --fix-inplace drivers/net/eepro100.c Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index d367052cd2a..2aad124ae5d 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -203,9 +203,9 @@ static const char i82558_config_cmd[] = { static void init_rx_ring(struct eth_device *dev); static void purge_tx_ring(struct eth_device *dev); -static void read_hw_addr(struct eth_device *dev, bd_t * bis); +static void read_hw_addr(struct eth_device *dev, bd_t *bis); -static int eepro100_init(struct eth_device *dev, bd_t * bis); +static int eepro100_init(struct eth_device *dev, bd_t *bis); static int eepro100_send(struct eth_device *dev, void *packet, int length); static int eepro100_recv(struct eth_device *dev); static void eepro100_halt(struct eth_device *dev); @@ -285,7 +285,7 @@ static int set_phyreg(struct eth_device *dev, unsigned char addr, * Check if given phyaddr is valid, i.e. there is a PHY connected. * Do this by checking model value field from ID2 register. */ -static struct eth_device* verify_phyaddr(const char *devname, +static struct eth_device *verify_phyaddr(const char *devname, unsigned char addr) { struct eth_device *dev; @@ -372,7 +372,7 @@ static struct pci_device_id supported[] = { {} }; -int eepro100_initialize(bd_t * bis) +int eepro100_initialize(bd_t *bis) { pci_dev_t devno; int card_number = 0; @@ -454,7 +454,7 @@ int eepro100_initialize(bd_t * bis) } -static int eepro100_init(struct eth_device *dev, bd_t * bis) +static int eepro100_init(struct eth_device *dev, bd_t *bis) { int i, status = -1; int tx_cur; @@ -785,7 +785,7 @@ static void purge_tx_ring(struct eth_device *dev) } } -static void read_hw_addr(struct eth_device *dev, bd_t * bis) +static void read_hw_addr(struct eth_device *dev, bd_t *bis) { u16 sum = 0; int i, j; -- cgit v1.3.1 From 614e95152dd63ac5259cd99c5c90949dcc466123 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 13:26:50 +0200 Subject: net: eepro100: Fix indented label This is automated cleanup via checkpatch, no functional change. ./scripts/checkpatch.pl --show-types -f drivers/net/eepro100.c ./scripts/checkpatch.pl --types INDENTED_LABEL -f --fix --fix-inplace drivers/net/eepro100.c Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 2aad124ae5d..e5bc90f52ce 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -566,7 +566,7 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) status = 0; - Done: +Done: return status; } @@ -623,7 +623,7 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) status = length; - Done: +Done: return status; } @@ -680,7 +680,7 @@ static int eepro100_recv(struct eth_device *dev) OUTW(dev, SCB_M | RUC_START, SCBCmd); } - Done: +Done: return length; } @@ -707,7 +707,7 @@ static void eepro100_halt(struct eth_device *dev) OUTL(dev, 0, SCBPointer); OUTW(dev, SCB_M | CU_ADDR_LOAD, SCBCmd); - Done: +Done: return; } -- cgit v1.3.1 From b0131730795c1ff7994a008d1c68b3b9b200d213 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 13:45:41 +0200 Subject: net: eepro100: Fix remaining checkpatch issues This is automated cleanup via checkpatch, no functional change. ./scripts/checkpatch.pl --show-types -f drivers/net/eepro100.c ./scripts/checkpatch.pl -f --fix --fix-inplace drivers/net/eepro100.c This fixes all the remaining errors except a couple of comments which are longer than 80 characters, all the volatile misuse and all the camelcase, that needs a separate patch. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index e5bc90f52ce..45c013607e9 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -293,7 +293,7 @@ static struct eth_device *verify_phyaddr(const char *devname, unsigned char model; dev = eth_get_dev_by_name(devname); - if (dev == NULL) { + if (!dev) { printf("%s: no such device\n", devname); return NULL; } @@ -322,7 +322,7 @@ static int eepro100_miiphy_read(struct mii_dev *bus, int addr, int devad, struct eth_device *dev; dev = verify_phyaddr(bus->name, addr); - if (dev == NULL) + if (!dev) return -1; if (get_phyreg(dev, addr, reg, &value) != 0) { @@ -339,7 +339,7 @@ static int eepro100_miiphy_write(struct mii_dev *bus, int addr, int devad, struct eth_device *dev; dev = verify_phyaddr(bus->name, addr); - if (dev == NULL) + if (!dev) return -1; if (set_phyreg(dev, addr, reg, value) != 0) { @@ -392,9 +392,8 @@ int eepro100_initialize(bd_t *bis) debug("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n", iobase); - pci_write_config_dword(devno, - PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); + pci_write_config_dword(devno, PCI_COMMAND, + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); /* Check if I/O accesses and Bus Mastering are enabled. */ pci_read_config_dword(devno, PCI_COMMAND, &status); @@ -408,7 +407,7 @@ int eepro100_initialize(bd_t *bis) continue; } - dev = (struct eth_device *)malloc(sizeof *dev); + dev = (struct eth_device *)malloc(sizeof(*dev)); if (!dev) { printf("eepro100: Can not allocate memory\n"); break; @@ -429,6 +428,7 @@ int eepro100_initialize(bd_t *bis) /* register mii command access routines */ int retval; struct mii_dev *mdiodev = mdio_alloc(); + if (!mdiodev) return -ENOMEM; strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); @@ -453,7 +453,6 @@ int eepro100_initialize(bd_t *bis) return card_number; } - static int eepro100_init(struct eth_device *dev, bd_t *bis) { int i, status = -1; @@ -499,9 +498,10 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) tx_next = ((tx_next + 1) % NUM_TX_DESC); cfg_cmd = (struct descriptor *)&tx_ring[tx_cur]; - cfg_cmd->command = cpu_to_le16 ((CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_CONFIGURE)); + cfg_cmd->command = cpu_to_le16(CONFIG_SYS_CMD_SUSPEND | + CONFIG_SYS_CMD_CONFIGURE); cfg_cmd->status = 0; - cfg_cmd->link = cpu_to_le32 (phys_to_bus((u32)&tx_ring[tx_next])); + cfg_cmd->link = cpu_to_le32(phys_to_bus((u32)&tx_ring[tx_next])); memcpy(cfg_cmd->params, i82558_config_cmd, sizeof(i82558_config_cmd)); @@ -534,9 +534,10 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) tx_next = ((tx_next + 1) % NUM_TX_DESC); ias_cmd = (struct descriptor *)&tx_ring[tx_cur]; - ias_cmd->command = cpu_to_le16 ((CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_IAS)); + ias_cmd->command = cpu_to_le16(CONFIG_SYS_CMD_SUSPEND | + CONFIG_SYS_CMD_IAS); ias_cmd->status = 0; - ias_cmd->link = cpu_to_le32 (phys_to_bus((u32)&tx_ring[tx_next])); + ias_cmd->link = cpu_to_le32(phys_to_bus((u32)&tx_ring[tx_next])); memcpy(ias_cmd->params, dev->enetaddr, 6); @@ -549,8 +550,9 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCBPointer); OUTW(dev, SCB_M | CU_START, SCBCmd); - for (i = 0; !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); - i++) { + for (i = 0; + !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); + i++) { if (i >= TOUT_LOOP) { printf("%s: Tx error buffer not ready\n", dev->name); @@ -607,8 +609,9 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCBPointer); OUTW(dev, SCB_M | CU_START, SCBCmd); - for (i = 0; !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); - i++) { + for (i = 0; + !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); + i++) { if (i >= TOUT_LOOP) { printf("%s: Tx error buffer not ready\n", dev->name); goto Done; @@ -752,13 +755,13 @@ static void init_rx_ring(struct eth_device *dev) for (i = 0; i < NUM_RX_DESC; i++) { rx_ring[i].status = 0; - rx_ring[i].control = - (i == NUM_RX_DESC - 1) ? cpu_to_le16 (RFD_CONTROL_S) : 0; + rx_ring[i].control = (i == NUM_RX_DESC - 1) ? + cpu_to_le16 (RFD_CONTROL_S) : 0; rx_ring[i].link = - cpu_to_le32 (phys_to_bus - ((u32)&rx_ring[(i + 1) % NUM_RX_DESC])); + cpu_to_le32(phys_to_bus((u32)&rx_ring[(i + 1) % + NUM_RX_DESC])); rx_ring[i].rx_buf_addr = 0xffffffff; - rx_ring[i].count = cpu_to_le32 (PKTSIZE_ALIGN << 16); + rx_ring[i].count = cpu_to_le32(PKTSIZE_ALIGN << 16); } rx_next = 0; -- cgit v1.3.1 From f3878f5c2821cca2c2587adf522319578ed0c1da Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 13:52:50 +0200 Subject: net: eepro100: Fix camelcase This is automated cleanup via checkpatch, no functional change. ./scripts/checkpatch.pl --show-types -f drivers/net/eepro100.c ./scripts/checkpatch.pl --types INDENTED_LABEL -f --fix --fix-inplace drivers/net/eepro100.c Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 172 ++++++++++++++++++++++++------------------------- 1 file changed, 85 insertions(+), 87 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 45c013607e9..d3ced08761e 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -14,18 +14,18 @@ #include /* Ethernet chip registers. */ -#define SCBStatus 0 /* Rx/Command Unit Status *Word* */ -#define SCBIntAckByte 1 /* Rx/Command Unit STAT/ACK byte */ -#define SCBCmd 2 /* Rx/Command Unit Command *Word* */ -#define SCBIntrCtlByte 3 /* Rx/Command Unit Intr.Control Byte */ -#define SCBPointer 4 /* General purpose pointer. */ -#define SCBPort 8 /* Misc. commands and operands. */ -#define SCBflash 12 /* Flash memory control. */ -#define SCBeeprom 14 /* EEPROM memory control. */ -#define SCBCtrlMDI 16 /* MDI interface control. */ -#define SCBEarlyRx 20 /* Early receive byte count. */ -#define SCBGenControl 28 /* 82559 General Control Register */ -#define SCBGenStatus 29 /* 82559 General Status register */ +#define SCB_STATUS 0 /* Rx/Command Unit Status *Word* */ +#define SCB_INT_ACK_BYTE 1 /* Rx/Command Unit STAT/ACK byte */ +#define SCB_CMD 2 /* Rx/Command Unit Command *Word* */ +#define SCB_INTR_CTL_BYTE 3 /* Rx/Command Unit Intr.Control Byte */ +#define SCB_POINTER 4 /* General purpose pointer. */ +#define SCB_PORT 8 /* Misc. commands and operands. */ +#define SCB_FLASH 12 /* Flash memory control. */ +#define SCB_EEPROM 14 /* EEPROM memory control. */ +#define SCB_CTRL_MDI 16 /* MDI interface control. */ +#define SCB_EARLY_RX 20 /* Early receive byte count. */ +#define SCB_GEN_CONTROL 28 /* 82559 General Control Register */ +#define SCB_GEN_STATUS 29 /* 82559 General Status register */ /* 82559 SCB status word defnitions */ #define SCB_STATUS_CX 0x8000 /* CU finished command (transmit) */ @@ -101,10 +101,10 @@ #define EE_ERASE_CMD (7 << addr_len) /* Receive frame descriptors. */ -struct RxFD { +struct eepro100_rxfd { volatile u16 status; volatile u16 control; - volatile u32 link; /* struct RxFD * */ + volatile u32 link; /* struct eepro100_rxfd * */ volatile u32 rx_buf_addr; /* void * */ volatile u32 count; @@ -135,7 +135,7 @@ struct RxFD { #define RFD_RX_TCO 0x0001 /* TCO indication */ /* Transmit frame descriptors */ -struct TxFD { /* Transmit frame descriptor set. */ +struct eepro100_txfd { /* Transmit frame descriptor set. */ volatile u16 status; volatile u16 command; volatile u32 link; /* void * */ @@ -148,15 +148,15 @@ struct TxFD { /* Transmit frame descriptor set. */ volatile s32 tx_buf_size1; /* Length of Tx frame. */ }; -#define TxCB_CMD_TRANSMIT 0x0004 /* transmit command */ -#define TxCB_CMD_SF 0x0008 /* 0=simplified, 1=flexible mode */ -#define TxCB_CMD_NC 0x0010 /* 0=CRC insert by controller */ -#define TxCB_CMD_I 0x2000 /* generate interrupt on completion */ -#define TxCB_CMD_S 0x4000 /* suspend on completion */ -#define TxCB_CMD_EL 0x8000 /* last command block in CBL */ +#define TXCB_CMD_TRANSMIT 0x0004 /* transmit command */ +#define TXCB_CMD_SF 0x0008 /* 0=simplified, 1=flexible mode */ +#define TXCB_CMD_NC 0x0010 /* 0=CRC insert by controller */ +#define TXCB_CMD_I 0x2000 /* generate interrupt on completion */ +#define TXCB_CMD_S 0x4000 /* suspend on completion */ +#define TXCB_CMD_EL 0x8000 /* last command block in CBL */ -#define TxCB_COUNT_MASK 0x3fff -#define TxCB_COUNT_EOF 0x8000 +#define TXCB_COUNT_MASK 0x3fff +#define TXCB_COUNT_EOF 0x8000 /* The Speedo3 Rx and Tx frame/buffer descriptors. */ struct descriptor { /* A generic descriptor. */ @@ -182,8 +182,8 @@ struct descriptor { /* A generic descriptor. */ #define TOUT_LOOP 1000000 -static struct RxFD rx_ring[NUM_RX_DESC]; /* RX descriptor ring */ -static struct TxFD tx_ring[NUM_TX_DESC]; /* TX descriptor ring */ +static struct eepro100_rxfd rx_ring[NUM_RX_DESC]; /* RX descriptor ring */ +static struct eepro100_txfd tx_ring[NUM_TX_DESC]; /* TX descriptor ring */ static int rx_next; /* RX descriptor ring pointer */ static int tx_next; /* TX descriptor ring pointer */ static int tx_threshold; @@ -247,11 +247,11 @@ static int get_phyreg(struct eth_device *dev, unsigned char addr, /* read requested data */ cmd = (2 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - OUTL(dev, cmd, SCBCtrlMDI); + OUTL(dev, cmd, SCB_CTRL_MDI); do { udelay(1000); - cmd = INL(dev, SCBCtrlMDI); + cmd = INL(dev, SCB_CTRL_MDI); } while (!(cmd & (1 << 28)) && (--timeout)); if (timeout == 0) @@ -270,9 +270,9 @@ static int set_phyreg(struct eth_device *dev, unsigned char addr, /* write requested data */ cmd = (1 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - OUTL(dev, cmd | value, SCBCtrlMDI); + OUTL(dev, cmd | value, SCB_CTRL_MDI); - while (!(INL(dev, SCBCtrlMDI) & (1 << 28)) && (--timeout)) + while (!(INL(dev, SCB_CTRL_MDI) & (1 << 28)) && (--timeout)) udelay(1000); if (timeout == 0) @@ -357,7 +357,7 @@ static int wait_for_eepro100(struct eth_device *dev) { int i; - for (i = 0; INW(dev, SCBCmd) & (CU_CMD_MASK | RU_CMD_MASK); i++) { + for (i = 0; INW(dev, SCB_CMD) & (CU_CMD_MASK | RU_CMD_MASK); i++) { if (i >= TOUT_LOOP) return 0; } @@ -460,25 +460,25 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) struct descriptor *ias_cmd, *cfg_cmd; /* Reset the ethernet controller */ - OUTL(dev, I82559_SELECTIVE_RESET, SCBPort); + OUTL(dev, I82559_SELECTIVE_RESET, SCB_PORT); udelay(20); - OUTL(dev, I82559_RESET, SCBPort); + OUTL(dev, I82559_RESET, SCB_PORT); udelay(20); if (!wait_for_eepro100(dev)) { printf("Error: Can not reset ethernet controller.\n"); - goto Done; + goto done; } - OUTL(dev, 0, SCBPointer); - OUTW(dev, SCB_M | RUC_ADDR_LOAD, SCBCmd); + OUTL(dev, 0, SCB_POINTER); + OUTW(dev, SCB_M | RUC_ADDR_LOAD, SCB_CMD); if (!wait_for_eepro100(dev)) { printf("Error: Can not reset ethernet controller.\n"); - goto Done; + goto done; } - OUTL(dev, 0, SCBPointer); - OUTW(dev, SCB_M | CU_ADDR_LOAD, SCBCmd); + OUTL(dev, 0, SCB_POINTER); + OUTW(dev, SCB_M | CU_ADDR_LOAD, SCB_CMD); /* Initialize Rx and Tx rings. */ init_rx_ring(dev); @@ -487,11 +487,11 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) /* Tell the adapter where the RX ring is located. */ if (!wait_for_eepro100(dev)) { printf("Error: Can not reset ethernet controller.\n"); - goto Done; + goto done; } - OUTL(dev, phys_to_bus((u32)&rx_ring[rx_next]), SCBPointer); - OUTW(dev, SCB_M | RUC_START, SCBCmd); + OUTL(dev, phys_to_bus((u32)&rx_ring[rx_next]), SCB_POINTER); + OUTW(dev, SCB_M | RUC_START, SCB_CMD); /* Send the Configure frame */ tx_cur = tx_next; @@ -508,25 +508,25 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) if (!wait_for_eepro100(dev)) { printf("Error---CONFIG_SYS_CMD_CONFIGURE: Can not reset ethernet controller.\n"); - goto Done; + goto done; } - OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCBPointer); - OUTW(dev, SCB_M | CU_START, SCBCmd); + OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCB_POINTER); + OUTW(dev, SCB_M | CU_START, SCB_CMD); for (i = 0; !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); i++) { if (i >= TOUT_LOOP) { printf("%s: Tx error buffer not ready\n", dev->name); - goto Done; + goto done; } } if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { printf("TX error status = 0x%08X\n", le16_to_cpu(tx_ring[tx_cur].status)); - goto Done; + goto done; } /* Send the Individual Address Setup frame */ @@ -544,11 +544,11 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) /* Tell the adapter where the TX ring is located. */ if (!wait_for_eepro100(dev)) { printf("Error: Can not reset ethernet controller.\n"); - goto Done; + goto done; } - OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCBPointer); - OUTW(dev, SCB_M | CU_START, SCBCmd); + OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCB_POINTER); + OUTW(dev, SCB_M | CU_START, SCB_CMD); for (i = 0; !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); @@ -556,19 +556,19 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) if (i >= TOUT_LOOP) { printf("%s: Tx error buffer not ready\n", dev->name); - goto Done; + goto done; } } if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { printf("TX error status = 0x%08X\n", le16_to_cpu(tx_ring[tx_cur].status)); - goto Done; + goto done; } status = 0; -Done: +done: return status; } @@ -579,16 +579,14 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) if (length <= 0) { printf("%s: bad packet size: %d\n", dev->name, length); - goto Done; + goto done; } tx_cur = tx_next; tx_next = (tx_next + 1) % NUM_TX_DESC; - tx_ring[tx_cur].command = cpu_to_le16 (TxCB_CMD_TRANSMIT | - TxCB_CMD_SF | - TxCB_CMD_S | - TxCB_CMD_EL); + tx_ring[tx_cur].command = cpu_to_le16(TXCB_CMD_TRANSMIT | TXCB_CMD_SF | + TXCB_CMD_S | TXCB_CMD_EL); tx_ring[tx_cur].status = 0; tx_ring[tx_cur].count = cpu_to_le32 (tx_threshold); tx_ring[tx_cur].link = @@ -602,31 +600,31 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) if (!wait_for_eepro100(dev)) { printf("%s: Tx error ethernet controller not ready.\n", dev->name); - goto Done; + goto done; } /* Send the packet. */ - OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCBPointer); - OUTW(dev, SCB_M | CU_START, SCBCmd); + OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCB_POINTER); + OUTW(dev, SCB_M | CU_START, SCB_CMD); for (i = 0; !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); i++) { if (i >= TOUT_LOOP) { printf("%s: Tx error buffer not ready\n", dev->name); - goto Done; + goto done; } } if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { printf("TX error status = 0x%08X\n", le16_to_cpu(tx_ring[tx_cur].status)); - goto Done; + goto done; } status = length; -Done: +done: return status; } @@ -635,8 +633,8 @@ static int eepro100_recv(struct eth_device *dev) u16 status, stat; int rx_prev, length = 0; - stat = INW(dev, SCBStatus); - OUTW(dev, stat & SCB_STATUS_RNR, SCBStatus); + stat = INW(dev, SCB_STATUS); + OUTW(dev, stat & SCB_STATUS_RNR, SCB_STATUS); for (;;) { status = le16_to_cpu(rx_ring[rx_next].status); @@ -676,41 +674,41 @@ static int eepro100_recv(struct eth_device *dev) if (!wait_for_eepro100(dev)) { printf("Error: Can not restart ethernet controller.\n"); - goto Done; + goto done; } - OUTL(dev, phys_to_bus((u32)&rx_ring[rx_next]), SCBPointer); - OUTW(dev, SCB_M | RUC_START, SCBCmd); + OUTL(dev, phys_to_bus((u32)&rx_ring[rx_next]), SCB_POINTER); + OUTW(dev, SCB_M | RUC_START, SCB_CMD); } -Done: +done: return length; } static void eepro100_halt(struct eth_device *dev) { /* Reset the ethernet controller */ - OUTL(dev, I82559_SELECTIVE_RESET, SCBPort); + OUTL(dev, I82559_SELECTIVE_RESET, SCB_PORT); udelay(20); - OUTL(dev, I82559_RESET, SCBPort); + OUTL(dev, I82559_RESET, SCB_PORT); udelay(20); if (!wait_for_eepro100(dev)) { printf("Error: Can not reset ethernet controller.\n"); - goto Done; + goto done; } - OUTL(dev, 0, SCBPointer); - OUTW(dev, SCB_M | RUC_ADDR_LOAD, SCBCmd); + OUTL(dev, 0, SCB_POINTER); + OUTW(dev, SCB_M | RUC_ADDR_LOAD, SCB_CMD); if (!wait_for_eepro100(dev)) { printf("Error: Can not reset ethernet controller.\n"); - goto Done; + goto done; } - OUTL(dev, 0, SCBPointer); - OUTW(dev, SCB_M | CU_ADDR_LOAD, SCBCmd); + OUTL(dev, 0, SCB_POINTER); + OUTW(dev, SCB_M | CU_ADDR_LOAD, SCB_CMD); -Done: +done: return; } @@ -721,31 +719,31 @@ static int read_eeprom(struct eth_device *dev, int location, int addr_len) int read_cmd = location | EE_READ_CMD; int i; - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); - OUTW(dev, EE_ENB, SCBeeprom); + OUTW(dev, EE_ENB & ~EE_CS, SCB_EEPROM); + OUTW(dev, EE_ENB, SCB_EEPROM); /* Shift the read command bits out. */ for (i = 12; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(dev, EE_ENB | dataval, SCBeeprom); + OUTW(dev, EE_ENB | dataval, SCB_EEPROM); udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCBeeprom); + OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCB_EEPROM); udelay(1); } - OUTW(dev, EE_ENB, SCBeeprom); + OUTW(dev, EE_ENB, SCB_EEPROM); for (i = 15; i >= 0; i--) { - OUTW(dev, EE_ENB | EE_SHIFT_CLK, SCBeeprom); + OUTW(dev, EE_ENB | EE_SHIFT_CLK, SCB_EEPROM); udelay(1); retval = (retval << 1) | - ((INW(dev, SCBeeprom) & EE_DATA_READ) ? 1 : 0); - OUTW(dev, EE_ENB, SCBeeprom); + ((INW(dev, SCB_EEPROM) & EE_DATA_READ) ? 1 : 0); + OUTW(dev, EE_ENB, SCB_EEPROM); udelay(1); } /* Terminate the EEPROM access. */ - OUTW(dev, EE_ENB & ~EE_CS, SCBeeprom); + OUTW(dev, EE_ENB & ~EE_CS, SCB_EEPROM); return retval; } -- cgit v1.3.1 From 81bdeea2fe62277922a6bd735f936b168352a49d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 14:14:45 +0200 Subject: net: eepro100: Use standard I/O accessors The current eepro100 driver accesses its memory mapped registers directly instead of using the standard I/O accessors. This can cause problems on some systems as the accesses can get out of order. So convert the direct volatile dereferences to use the normal in/out macros. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index d3ced08761e..5d11665fdc8 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -220,23 +220,23 @@ static void eepro100_halt(struct eth_device *dev); static inline int INW(struct eth_device *dev, u_long addr) { - return le16_to_cpu(*(volatile u16 *)(addr + (u_long)dev->iobase)); + return le16_to_cpu(readw(addr + (void *)dev->iobase)); } static inline void OUTW(struct eth_device *dev, int command, u_long addr) { - *(volatile u16 *)((addr + (u_long)dev->iobase)) = cpu_to_le16(command); + writew(cpu_to_le16(command), addr + (void *)dev->iobase); } static inline void OUTL(struct eth_device *dev, int command, u_long addr) { - *(volatile u32 *)((addr + (u_long)dev->iobase)) = cpu_to_le32(command); + writel(cpu_to_le32(command), addr + (void *)dev->iobase); } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) static inline int INL(struct eth_device *dev, u_long addr) { - return le32_to_cpu(*(volatile u32 *)(addr + (u_long)dev->iobase)); + return le32_to_cpu(readl(addr + (void *)dev->iobase)); } static int get_phyreg(struct eth_device *dev, unsigned char addr, -- cgit v1.3.1 From 46df32ef2f8226434b06b43c51cbd94268b343d9 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 14:26:16 +0200 Subject: net: eepro100: Replace purge_tx_ring() with memset() This function zeroes-out all the descriptors in the TX ring, use memset() instead. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 5d11665fdc8..6fb9192e81e 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -767,23 +767,9 @@ static void init_rx_ring(struct eth_device *dev) static void purge_tx_ring(struct eth_device *dev) { - int i; - tx_next = 0; tx_threshold = 0x01208000; - - for (i = 0; i < NUM_TX_DESC; i++) { - tx_ring[i].status = 0; - tx_ring[i].command = 0; - tx_ring[i].link = 0; - tx_ring[i].tx_desc_addr = 0; - tx_ring[i].count = 0; - - tx_ring[i].tx_buf_addr0 = 0; - tx_ring[i].tx_buf_size0 = 0; - tx_ring[i].tx_buf_addr1 = 0; - tx_ring[i].tx_buf_size1 = 0; - } + memset(tx_ring, 0, sizeof(*tx_ring) * NUM_TX_DESC); } static void read_hw_addr(struct eth_device *dev, bd_t *bis) -- cgit v1.3.1 From 95655b921bdb39aa23a345be13140ab221776705 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 14:30:31 +0200 Subject: net: eepro100: Factor out tx_ring command issuing This code is replicated in the driver thrice almost verbatim, factor it out into a separate function and clean it up. No functional change. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 124 +++++++++++++++++++++---------------------------- 1 file changed, 53 insertions(+), 71 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 6fb9192e81e..03ba9a41a5d 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -453,11 +453,44 @@ int eepro100_initialize(bd_t *bis) return card_number; } +static int eepro100_txcmd_send(struct eth_device *dev, + struct eepro100_txfd *desc) +{ + u16 rstat; + int i = 0; + + if (!wait_for_eepro100(dev)) + return -ETIMEDOUT; + + OUTL(dev, phys_to_bus((u32)desc), SCB_POINTER); + OUTW(dev, SCB_M | CU_START, SCB_CMD); + + while (true) { + rstat = le16_to_cpu(desc->status); + if (rstat & CONFIG_SYS_STATUS_C) + break; + + if (i++ >= TOUT_LOOP) { + printf("%s: Tx error buffer not ready\n", dev->name); + return -EINVAL; + } + } + + rstat = le16_to_cpu(desc->status); + + if (!(rstat & CONFIG_SYS_STATUS_OK)) { + printf("TX error status = 0x%08X\n", rstat); + return -EIO; + } + + return 0; +} + static int eepro100_init(struct eth_device *dev, bd_t *bis) { - int i, status = -1; + struct eepro100_txfd *ias_cmd, *cfg_cmd; + int ret, status = -1; int tx_cur; - struct descriptor *ias_cmd, *cfg_cmd; /* Reset the ethernet controller */ OUTL(dev, I82559_SELECTIVE_RESET, SCB_PORT); @@ -497,35 +530,19 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) tx_cur = tx_next; tx_next = ((tx_next + 1) % NUM_TX_DESC); - cfg_cmd = (struct descriptor *)&tx_ring[tx_cur]; + cfg_cmd = &tx_ring[tx_cur]; cfg_cmd->command = cpu_to_le16(CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_CONFIGURE); cfg_cmd->status = 0; cfg_cmd->link = cpu_to_le32(phys_to_bus((u32)&tx_ring[tx_next])); - memcpy(cfg_cmd->params, i82558_config_cmd, + memcpy(((struct descriptor *)cfg_cmd)->params, i82558_config_cmd, sizeof(i82558_config_cmd)); - if (!wait_for_eepro100(dev)) { - printf("Error---CONFIG_SYS_CMD_CONFIGURE: Can not reset ethernet controller.\n"); - goto done; - } - - OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCB_POINTER); - OUTW(dev, SCB_M | CU_START, SCB_CMD); - - for (i = 0; - !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); - i++) { - if (i >= TOUT_LOOP) { - printf("%s: Tx error buffer not ready\n", dev->name); - goto done; - } - } - - if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { - printf("TX error status = 0x%08X\n", - le16_to_cpu(tx_ring[tx_cur].status)); + ret = eepro100_txcmd_send(dev, cfg_cmd); + if (ret) { + if (ret == -ETIMEDOUT) + printf("Error---CONFIG_SYS_CMD_CONFIGURE: Can not reset ethernet controller.\n"); goto done; } @@ -533,36 +550,18 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) tx_cur = tx_next; tx_next = ((tx_next + 1) % NUM_TX_DESC); - ias_cmd = (struct descriptor *)&tx_ring[tx_cur]; + ias_cmd = &tx_ring[tx_cur]; ias_cmd->command = cpu_to_le16(CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_IAS); ias_cmd->status = 0; ias_cmd->link = cpu_to_le32(phys_to_bus((u32)&tx_ring[tx_next])); - memcpy(ias_cmd->params, dev->enetaddr, 6); - - /* Tell the adapter where the TX ring is located. */ - if (!wait_for_eepro100(dev)) { - printf("Error: Can not reset ethernet controller.\n"); - goto done; - } - - OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCB_POINTER); - OUTW(dev, SCB_M | CU_START, SCB_CMD); - - for (i = 0; - !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); - i++) { - if (i >= TOUT_LOOP) { - printf("%s: Tx error buffer not ready\n", - dev->name); - goto done; - } - } + memcpy(((struct descriptor *)ias_cmd)->params, dev->enetaddr, 6); - if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { - printf("TX error status = 0x%08X\n", - le16_to_cpu(tx_ring[tx_cur].status)); + ret = eepro100_txcmd_send(dev, ias_cmd); + if (ret) { + if (ret == -ETIMEDOUT) + printf("Error: Can not reset ethernet controller.\n"); goto done; } @@ -574,7 +573,7 @@ done: static int eepro100_send(struct eth_device *dev, void *packet, int length) { - int i, status = -1; + int ret, status = -1; int tx_cur; if (length <= 0) { @@ -597,28 +596,11 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) cpu_to_le32 (phys_to_bus((u_long)packet)); tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32 (length); - if (!wait_for_eepro100(dev)) { - printf("%s: Tx error ethernet controller not ready.\n", - dev->name); - goto done; - } - - /* Send the packet. */ - OUTL(dev, phys_to_bus((u32)&tx_ring[tx_cur]), SCB_POINTER); - OUTW(dev, SCB_M | CU_START, SCB_CMD); - - for (i = 0; - !(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_C); - i++) { - if (i >= TOUT_LOOP) { - printf("%s: Tx error buffer not ready\n", dev->name); - goto done; - } - } - - if (!(le16_to_cpu(tx_ring[tx_cur].status) & CONFIG_SYS_STATUS_OK)) { - printf("TX error status = 0x%08X\n", - le16_to_cpu(tx_ring[tx_cur].status)); + ret = eepro100_txcmd_send(dev, &tx_ring[tx_cur]); + if (ret) { + if (ret == -ETIMEDOUT) + printf("%s: Tx error ethernet controller not ready.\n", + dev->name); goto done; } -- cgit v1.3.1 From 5116aae111b317e82c023af911082aa8d3526a4f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 14:55:26 +0200 Subject: net: eepro100: Add cache management Add cache invalidation and flushes wherever the DMA descriptors are written or read, otherwise this driver cannot work reliably on any systems where caches are enabled. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 65 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 03ba9a41a5d..89bfcfba0a8 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -459,6 +460,9 @@ static int eepro100_txcmd_send(struct eth_device *dev, u16 rstat; int i = 0; + flush_dcache_range((unsigned long)desc, + (unsigned long)desc + sizeof(*desc)); + if (!wait_for_eepro100(dev)) return -ETIMEDOUT; @@ -466,6 +470,8 @@ static int eepro100_txcmd_send(struct eth_device *dev, OUTW(dev, SCB_M | CU_START, SCB_CMD); while (true) { + invalidate_dcache_range((unsigned long)desc, + (unsigned long)desc + sizeof(*desc)); rstat = le16_to_cpu(desc->status); if (rstat & CONFIG_SYS_STATUS_C) break; @@ -476,6 +482,8 @@ static int eepro100_txcmd_send(struct eth_device *dev, } } + invalidate_dcache_range((unsigned long)desc, + (unsigned long)desc + sizeof(*desc)); rstat = le16_to_cpu(desc->status); if (!(rstat & CONFIG_SYS_STATUS_OK)) { @@ -523,6 +531,7 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) goto done; } + /* RX ring cache was already flushed in init_rx_ring() */ OUTL(dev, phys_to_bus((u32)&rx_ring[rx_next]), SCB_POINTER); OUTW(dev, SCB_M | RUC_START, SCB_CMD); @@ -573,6 +582,7 @@ done: static int eepro100_send(struct eth_device *dev, void *packet, int length) { + struct eepro100_txfd *desc; int ret, status = -1; int tx_cur; @@ -584,17 +594,15 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) tx_cur = tx_next; tx_next = (tx_next + 1) % NUM_TX_DESC; - tx_ring[tx_cur].command = cpu_to_le16(TXCB_CMD_TRANSMIT | TXCB_CMD_SF | - TXCB_CMD_S | TXCB_CMD_EL); - tx_ring[tx_cur].status = 0; - tx_ring[tx_cur].count = cpu_to_le32 (tx_threshold); - tx_ring[tx_cur].link = - cpu_to_le32 (phys_to_bus((u32)&tx_ring[tx_next])); - tx_ring[tx_cur].tx_desc_addr = - cpu_to_le32 (phys_to_bus((u32)&tx_ring[tx_cur].tx_buf_addr0)); - tx_ring[tx_cur].tx_buf_addr0 = - cpu_to_le32 (phys_to_bus((u_long)packet)); - tx_ring[tx_cur].tx_buf_size0 = cpu_to_le32 (length); + desc = &tx_ring[tx_cur]; + desc->command = cpu_to_le16(TXCB_CMD_TRANSMIT | TXCB_CMD_SF | + TXCB_CMD_S | TXCB_CMD_EL); + desc->status = 0; + desc->count = cpu_to_le32(tx_threshold); + desc->link = cpu_to_le32(phys_to_bus((u32)&tx_ring[tx_next])); + desc->tx_desc_addr = cpu_to_le32(phys_to_bus((u32)&desc->tx_buf_addr0)); + desc->tx_buf_addr0 = cpu_to_le32(phys_to_bus((u_long)packet)); + desc->tx_buf_size0 = cpu_to_le32(length); ret = eepro100_txcmd_send(dev, &tx_ring[tx_cur]); if (ret) { @@ -612,14 +620,18 @@ done: static int eepro100_recv(struct eth_device *dev) { - u16 status, stat; + struct eepro100_rxfd *desc; int rx_prev, length = 0; + u16 status, stat; stat = INW(dev, SCB_STATUS); OUTW(dev, stat & SCB_STATUS_RNR, SCB_STATUS); for (;;) { - status = le16_to_cpu(rx_ring[rx_next].status); + desc = &rx_ring[rx_next]; + invalidate_dcache_range((unsigned long)desc, + (unsigned long)desc + sizeof(*desc)); + status = le16_to_cpu(desc->status); if (!(status & RFD_STATUS_C)) break; @@ -627,22 +639,26 @@ static int eepro100_recv(struct eth_device *dev) /* Valid frame status. */ if ((status & RFD_STATUS_OK)) { /* A valid frame received. */ - length = le32_to_cpu(rx_ring[rx_next].count) & 0x3fff; + length = le32_to_cpu(desc->count) & 0x3fff; /* Pass the packet up to the protocol layers. */ - net_process_received_packet((u8 *)rx_ring[rx_next].data, - length); + net_process_received_packet((u8 *)desc->data, length); } else { /* There was an error. */ printf("RX error status = 0x%08X\n", status); } - rx_ring[rx_next].control = cpu_to_le16 (RFD_CONTROL_S); - rx_ring[rx_next].status = 0; - rx_ring[rx_next].count = cpu_to_le32 (PKTSIZE_ALIGN << 16); + desc->control = cpu_to_le16(RFD_CONTROL_S); + desc->status = 0; + desc->count = cpu_to_le32(PKTSIZE_ALIGN << 16); + flush_dcache_range((unsigned long)desc, + (unsigned long)desc + sizeof(*desc)); rx_prev = (rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC; - rx_ring[rx_prev].control = 0; + desc = &rx_ring[rx_prev]; + desc->control = 0; + flush_dcache_range((unsigned long)desc, + (unsigned long)desc + sizeof(*desc)); /* Update entry information. */ rx_next = (rx_next + 1) % NUM_RX_DESC; @@ -659,6 +675,7 @@ static int eepro100_recv(struct eth_device *dev) goto done; } + /* RX ring cache was already flushed in init_rx_ring() */ OUTL(dev, phys_to_bus((u32)&rx_ring[rx_next]), SCB_POINTER); OUTW(dev, SCB_M | RUC_START, SCB_CMD); } @@ -744,6 +761,10 @@ static void init_rx_ring(struct eth_device *dev) rx_ring[i].count = cpu_to_le32(PKTSIZE_ALIGN << 16); } + flush_dcache_range((unsigned long)rx_ring, + (unsigned long)rx_ring + + (sizeof(*rx_ring) * NUM_RX_DESC)); + rx_next = 0; } @@ -752,6 +773,10 @@ static void purge_tx_ring(struct eth_device *dev) tx_next = 0; tx_threshold = 0x01208000; memset(tx_ring, 0, sizeof(*tx_ring) * NUM_TX_DESC); + + flush_dcache_range((unsigned long)tx_ring, + (unsigned long)tx_ring + + (sizeof(*tx_ring) * NUM_TX_DESC)); } static void read_hw_addr(struct eth_device *dev, bd_t *bis) -- cgit v1.3.1 From d47cf87db9c89eb0cd00d586111b3b6579b6a5ef Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 15:02:47 +0200 Subject: net: eepro100: Remove volatile misuse Remove all the remaining use of the 'volatile' keyword, as this is no longer required. All the accesses which might have needed this use of 'volatile' have been repaired properly. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 89bfcfba0a8..f3bcb0dfe46 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -103,13 +103,13 @@ /* Receive frame descriptors. */ struct eepro100_rxfd { - volatile u16 status; - volatile u16 control; - volatile u32 link; /* struct eepro100_rxfd * */ - volatile u32 rx_buf_addr; /* void * */ - volatile u32 count; + u16 status; + u16 control; + u32 link; /* struct eepro100_rxfd * */ + u32 rx_buf_addr; /* void * */ + u32 count; - volatile u8 data[PKTSIZE_ALIGN]; + u8 data[PKTSIZE_ALIGN]; }; #define RFD_STATUS_C 0x8000 /* completion of received frame */ @@ -136,17 +136,17 @@ struct eepro100_rxfd { #define RFD_RX_TCO 0x0001 /* TCO indication */ /* Transmit frame descriptors */ -struct eepro100_txfd { /* Transmit frame descriptor set. */ - volatile u16 status; - volatile u16 command; - volatile u32 link; /* void * */ - volatile u32 tx_desc_addr; /* Always points to the tx_buf_addr element. */ - volatile s32 count; - - volatile u32 tx_buf_addr0; /* void *, frame to be transmitted. */ - volatile s32 tx_buf_size0; /* Length of Tx frame. */ - volatile u32 tx_buf_addr1; /* void *, frame to be transmitted. */ - volatile s32 tx_buf_size1; /* Length of Tx frame. */ +struct eepro100_txfd { /* Transmit frame descriptor set. */ + u16 status; + u16 command; + u32 link; /* void * */ + u32 tx_desc_addr; /* Always points to the tx_buf_addr element. */ + s32 count; + + u32 tx_buf_addr0; /* void *, frame to be transmitted. */ + s32 tx_buf_size0; /* Length of Tx frame. */ + u32 tx_buf_addr1; /* void *, frame to be transmitted. */ + s32 tx_buf_size1; /* Length of Tx frame. */ }; #define TXCB_CMD_TRANSMIT 0x0004 /* transmit command */ @@ -160,10 +160,10 @@ struct eepro100_txfd { /* Transmit frame descriptor set. */ #define TXCB_COUNT_EOF 0x8000 /* The Speedo3 Rx and Tx frame/buffer descriptors. */ -struct descriptor { /* A generic descriptor. */ - volatile u16 status; - volatile u16 command; - volatile u32 link; /* struct descriptor * */ +struct descriptor { /* A generic descriptor. */ + u16 status; + u16 command; + u32 link; /* struct descriptor * */ unsigned char params[0]; }; -- cgit v1.3.1 From 047a800dd6370c5f004b47751f72bb9d4a5d2af5 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 15:07:30 +0200 Subject: net: eepro100: Reorder functions in the driver Move the functions around in the driver to prepare it for DM conversion. Drop forward declarations which are not necessary anymore. No functional change. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 330 ++++++++++++++++++++++++------------------------- 1 file changed, 160 insertions(+), 170 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index f3bcb0dfe46..9db9367e952 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -5,13 +5,13 @@ */ #include +#include #include #include +#include #include #include -#include #include -#include #include /* Ethernet chip registers. */ @@ -201,16 +201,6 @@ static const char i82558_config_cmd[] = { 0x31, 0x05, }; -static void init_rx_ring(struct eth_device *dev); -static void purge_tx_ring(struct eth_device *dev); - -static void read_hw_addr(struct eth_device *dev, bd_t *bis); - -static int eepro100_init(struct eth_device *dev, bd_t *bis); -static int eepro100_send(struct eth_device *dev, void *packet, int length); -static int eepro100_recv(struct eth_device *dev); -static void eepro100_halt(struct eth_device *dev); - #if defined(CONFIG_E500) #define bus_to_phys(a) (a) #define phys_to_bus(a) (a) @@ -353,105 +343,50 @@ static int eepro100_miiphy_write(struct mii_dev *bus, int addr, int devad, #endif -/* Wait for the chip get the command. */ -static int wait_for_eepro100(struct eth_device *dev) +static void init_rx_ring(struct eth_device *dev) { int i; - for (i = 0; INW(dev, SCB_CMD) & (CU_CMD_MASK | RU_CMD_MASK); i++) { - if (i >= TOUT_LOOP) - return 0; + for (i = 0; i < NUM_RX_DESC; i++) { + rx_ring[i].status = 0; + rx_ring[i].control = (i == NUM_RX_DESC - 1) ? + cpu_to_le16 (RFD_CONTROL_S) : 0; + rx_ring[i].link = + cpu_to_le32(phys_to_bus((u32)&rx_ring[(i + 1) % + NUM_RX_DESC])); + rx_ring[i].rx_buf_addr = 0xffffffff; + rx_ring[i].count = cpu_to_le32(PKTSIZE_ALIGN << 16); } - return 1; -} + flush_dcache_range((unsigned long)rx_ring, + (unsigned long)rx_ring + + (sizeof(*rx_ring) * NUM_RX_DESC)); -static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER}, - {} -}; + rx_next = 0; +} -int eepro100_initialize(bd_t *bis) +static void purge_tx_ring(struct eth_device *dev) { - pci_dev_t devno; - int card_number = 0; - struct eth_device *dev; - u32 iobase, status; - int idx = 0; - - while (1) { - /* Find PCI device */ - devno = pci_find_devices(supported, idx++); - if (devno < 0) - break; - - pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase); - iobase &= ~0xf; - - debug("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n", - iobase); - - pci_write_config_dword(devno, PCI_COMMAND, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - - /* Check if I/O accesses and Bus Mastering are enabled. */ - pci_read_config_dword(devno, PCI_COMMAND, &status); - if (!(status & PCI_COMMAND_MEMORY)) { - printf("Error: Can not enable MEM access.\n"); - continue; - } - - if (!(status & PCI_COMMAND_MASTER)) { - printf("Error: Can not enable Bus Mastering.\n"); - continue; - } - - dev = (struct eth_device *)malloc(sizeof(*dev)); - if (!dev) { - printf("eepro100: Can not allocate memory\n"); - break; - } - memset(dev, 0, sizeof(*dev)); - - sprintf(dev->name, "i82559#%d", card_number); - dev->priv = (void *)devno; /* this have to come before bus_to_phys() */ - dev->iobase = bus_to_phys(iobase); - dev->init = eepro100_init; - dev->halt = eepro100_halt; - dev->send = eepro100_send; - dev->recv = eepro100_recv; - - eth_register(dev); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - /* register mii command access routines */ - int retval; - struct mii_dev *mdiodev = mdio_alloc(); - - if (!mdiodev) - return -ENOMEM; - strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); - mdiodev->read = eepro100_miiphy_read; - mdiodev->write = eepro100_miiphy_write; - - retval = mdio_register(mdiodev); - if (retval < 0) - return retval; -#endif - - card_number++; + tx_next = 0; + tx_threshold = 0x01208000; + memset(tx_ring, 0, sizeof(*tx_ring) * NUM_TX_DESC); - /* Set the latency timer for value. */ - pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20); + flush_dcache_range((unsigned long)tx_ring, + (unsigned long)tx_ring + + (sizeof(*tx_ring) * NUM_TX_DESC)); +} - udelay(10 * 1000); +/* Wait for the chip get the command. */ +static int wait_for_eepro100(struct eth_device *dev) +{ + int i; - read_hw_addr(dev, bis); + for (i = 0; INW(dev, SCB_CMD) & (CU_CMD_MASK | RU_CMD_MASK); i++) { + if (i >= TOUT_LOOP) + return 0; } - return card_number; + return 1; } static int eepro100_txcmd_send(struct eth_device *dev, @@ -494,6 +429,71 @@ static int eepro100_txcmd_send(struct eth_device *dev, return 0; } +/* SROM Read. */ +static int read_eeprom(struct eth_device *dev, int location, int addr_len) +{ + unsigned short retval = 0; + int read_cmd = location | EE_READ_CMD; + int i; + + OUTW(dev, EE_ENB & ~EE_CS, SCB_EEPROM); + OUTW(dev, EE_ENB, SCB_EEPROM); + + /* Shift the read command bits out. */ + for (i = 12; i >= 0; i--) { + short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + + OUTW(dev, EE_ENB | dataval, SCB_EEPROM); + udelay(1); + OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCB_EEPROM); + udelay(1); + } + OUTW(dev, EE_ENB, SCB_EEPROM); + + for (i = 15; i >= 0; i--) { + OUTW(dev, EE_ENB | EE_SHIFT_CLK, SCB_EEPROM); + udelay(1); + retval = (retval << 1) | + ((INW(dev, SCB_EEPROM) & EE_DATA_READ) ? 1 : 0); + OUTW(dev, EE_ENB, SCB_EEPROM); + udelay(1); + } + + /* Terminate the EEPROM access. */ + OUTW(dev, EE_ENB & ~EE_CS, SCB_EEPROM); + return retval; +} + +static struct pci_device_id supported[] = { + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER}, + {} +}; + +static void read_hw_addr(struct eth_device *dev, bd_t *bis) +{ + u16 sum = 0; + int i, j; + int addr_len = read_eeprom(dev, 0, 6) == 0xffff ? 8 : 6; + + for (j = 0, i = 0; i < 0x40; i++) { + u16 value = read_eeprom(dev, i, addr_len); + + sum += value; + if (i < 3) { + dev->enetaddr[j++] = value; + dev->enetaddr[j++] = value >> 8; + } + } + + if (sum != 0xBABA) { + memset(dev->enetaddr, 0, ETH_ALEN); + debug("%s: Invalid EEPROM checksum %#4.4x, check settings before activating this device!\n", + dev->name, sum); + } +} + static int eepro100_init(struct eth_device *dev, bd_t *bis) { struct eepro100_txfd *ias_cmd, *cfg_cmd; @@ -711,93 +711,83 @@ done: return; } -/* SROM Read. */ -static int read_eeprom(struct eth_device *dev, int location, int addr_len) +int eepro100_initialize(bd_t *bis) { - unsigned short retval = 0; - int read_cmd = location | EE_READ_CMD; - int i; + pci_dev_t devno; + int card_number = 0; + struct eth_device *dev; + u32 iobase, status; + int idx = 0; - OUTW(dev, EE_ENB & ~EE_CS, SCB_EEPROM); - OUTW(dev, EE_ENB, SCB_EEPROM); + while (1) { + /* Find PCI device */ + devno = pci_find_devices(supported, idx++); + if (devno < 0) + break; - /* Shift the read command bits out. */ - for (i = 12; i >= 0; i--) { - short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + pci_read_config_dword(devno, PCI_BASE_ADDRESS_0, &iobase); + iobase &= ~0xf; - OUTW(dev, EE_ENB | dataval, SCB_EEPROM); - udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCB_EEPROM); - udelay(1); - } - OUTW(dev, EE_ENB, SCB_EEPROM); + debug("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n", + iobase); - for (i = 15; i >= 0; i--) { - OUTW(dev, EE_ENB | EE_SHIFT_CLK, SCB_EEPROM); - udelay(1); - retval = (retval << 1) | - ((INW(dev, SCB_EEPROM) & EE_DATA_READ) ? 1 : 0); - OUTW(dev, EE_ENB, SCB_EEPROM); - udelay(1); - } + pci_write_config_dword(devno, PCI_COMMAND, + PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER); - /* Terminate the EEPROM access. */ - OUTW(dev, EE_ENB & ~EE_CS, SCB_EEPROM); - return retval; -} + /* Check if I/O accesses and Bus Mastering are enabled. */ + pci_read_config_dword(devno, PCI_COMMAND, &status); + if (!(status & PCI_COMMAND_MEMORY)) { + printf("Error: Can not enable MEM access.\n"); + continue; + } -static void init_rx_ring(struct eth_device *dev) -{ - int i; + if (!(status & PCI_COMMAND_MASTER)) { + printf("Error: Can not enable Bus Mastering.\n"); + continue; + } - for (i = 0; i < NUM_RX_DESC; i++) { - rx_ring[i].status = 0; - rx_ring[i].control = (i == NUM_RX_DESC - 1) ? - cpu_to_le16 (RFD_CONTROL_S) : 0; - rx_ring[i].link = - cpu_to_le32(phys_to_bus((u32)&rx_ring[(i + 1) % - NUM_RX_DESC])); - rx_ring[i].rx_buf_addr = 0xffffffff; - rx_ring[i].count = cpu_to_le32(PKTSIZE_ALIGN << 16); - } + dev = (struct eth_device *)malloc(sizeof(*dev)); + if (!dev) { + printf("eepro100: Can not allocate memory\n"); + break; + } + memset(dev, 0, sizeof(*dev)); - flush_dcache_range((unsigned long)rx_ring, - (unsigned long)rx_ring + - (sizeof(*rx_ring) * NUM_RX_DESC)); + sprintf(dev->name, "i82559#%d", card_number); + dev->priv = (void *)devno; /* this have to come before bus_to_phys() */ + dev->iobase = bus_to_phys(iobase); + dev->init = eepro100_init; + dev->halt = eepro100_halt; + dev->send = eepro100_send; + dev->recv = eepro100_recv; - rx_next = 0; -} + eth_register(dev); -static void purge_tx_ring(struct eth_device *dev) -{ - tx_next = 0; - tx_threshold = 0x01208000; - memset(tx_ring, 0, sizeof(*tx_ring) * NUM_TX_DESC); +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) + /* register mii command access routines */ + int retval; + struct mii_dev *mdiodev = mdio_alloc(); - flush_dcache_range((unsigned long)tx_ring, - (unsigned long)tx_ring + - (sizeof(*tx_ring) * NUM_TX_DESC)); -} + if (!mdiodev) + return -ENOMEM; + strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); + mdiodev->read = eepro100_miiphy_read; + mdiodev->write = eepro100_miiphy_write; -static void read_hw_addr(struct eth_device *dev, bd_t *bis) -{ - u16 sum = 0; - int i, j; - int addr_len = read_eeprom(dev, 0, 6) == 0xffff ? 8 : 6; + retval = mdio_register(mdiodev); + if (retval < 0) + return retval; +#endif - for (j = 0, i = 0; i < 0x40; i++) { - u16 value = read_eeprom(dev, i, addr_len); + card_number++; - sum += value; - if (i < 3) { - dev->enetaddr[j++] = value; - dev->enetaddr[j++] = value >> 8; - } - } + /* Set the latency timer for value. */ + pci_write_config_byte(devno, PCI_LATENCY_TIMER, 0x20); - if (sum != 0xBABA) { - memset(dev->enetaddr, 0, ETH_ALEN); - debug("%s: Invalid EEPROM checksum %#4.4x, check settings before activating this device!\n", - dev->name, sum); + udelay(10 * 1000); + + read_hw_addr(dev, bis); } + + return card_number; } -- cgit v1.3.1 From 3a15684dc6ecc9dcc74e3a9357d8e91ebd50aed7 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 15:11:30 +0200 Subject: net: eepro100: Use PCI_DEVICE() to define PCI device compat list Use this macro to fully fill the PCI device ID table. This is mandatory for the DM PCI support, which checks all the fields. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 9db9367e952..74b09e9afd2 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -465,10 +465,10 @@ static int read_eeprom(struct eth_device *dev, int location, int addr_len) } static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559}, - {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER}, - {} + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559ER) }, + { } }; static void read_hw_addr(struct eth_device *dev, bd_t *bis) -- cgit v1.3.1 From 6c7d3f6b3fb5860f55d1c7733d2b5929e0721e99 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 16:13:30 +0200 Subject: net: eepro100: Switch from malloc()+memset() to calloc() Replace malloc()+memset() combination with calloc(), no functional change. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 74b09e9afd2..8fa665743ae 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -746,12 +746,11 @@ int eepro100_initialize(bd_t *bis) continue; } - dev = (struct eth_device *)malloc(sizeof(*dev)); + dev = calloc(1, sizeof(*dev)); if (!dev) { printf("eepro100: Can not allocate memory\n"); break; } - memset(dev, 0, sizeof(*dev)); sprintf(dev->name, "i82559#%d", card_number); dev->priv = (void *)devno; /* this have to come before bus_to_phys() */ -- cgit v1.3.1 From 66fed7300d250197c24fb54cad7f6cae7df95fe1 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 16:20:25 +0200 Subject: net: eepro100: Factor out MII registration Pull the MII registration code into a separate function. Moreover, properly free memory in case any of the registration or allocation functions fail, so this fixes an existing memleak. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 56 +++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 8fa665743ae..861d39cf9f4 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -464,6 +464,36 @@ static int read_eeprom(struct eth_device *dev, int location, int addr_len) return retval; } +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +static int eepro100_initialize_mii(struct eth_device *dev) +{ + /* register mii command access routines */ + struct mii_dev *mdiodev; + int ret; + + mdiodev = mdio_alloc(); + if (!mdiodev) + return -ENOMEM; + + strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); + mdiodev->read = eepro100_miiphy_read; + mdiodev->write = eepro100_miiphy_write; + + ret = mdio_register(mdiodev); + if (ret < 0) { + mdio_free(mdiodev); + return ret; + } + + return 0; +} +#else +static int eepro100_initialize_mii(struct eth_device *dev) +{ + return 0; +} +#endif + static struct pci_device_id supported[] = { { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82557) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82559) }, @@ -713,11 +743,12 @@ done: int eepro100_initialize(bd_t *bis) { - pci_dev_t devno; - int card_number = 0; struct eth_device *dev; + int card_number = 0; u32 iobase, status; + pci_dev_t devno; int idx = 0; + int ret; while (1) { /* Find PCI device */ @@ -762,21 +793,12 @@ int eepro100_initialize(bd_t *bis) eth_register(dev); -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - /* register mii command access routines */ - int retval; - struct mii_dev *mdiodev = mdio_alloc(); - - if (!mdiodev) - return -ENOMEM; - strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); - mdiodev->read = eepro100_miiphy_read; - mdiodev->write = eepro100_miiphy_write; - - retval = mdio_register(mdiodev); - if (retval < 0) - return retval; -#endif + ret = eepro100_initialize_mii(dev); + if (ret) { + eth_unregister(dev); + free(dev); + return ret; + } card_number++; -- cgit v1.3.1 From a6c06ec8f6598f248ade50d4dd7e5b2f32df2dde Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 16:23:28 +0200 Subject: net: eepro100: Fix EE_*_CMD macros Those macros depended on specific variable names to be declared at their usage sites, fix this by adding an argument to those macros and also protect the argument with braces. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 861d39cf9f4..a8d617c7e81 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -96,10 +96,10 @@ #define EE_DATA_BITS 16 /* The EEPROM commands include the alway-set leading bit. */ -#define EE_EWENB_CMD (4 << addr_len) -#define EE_WRITE_CMD (5 << addr_len) -#define EE_READ_CMD (6 << addr_len) -#define EE_ERASE_CMD (7 << addr_len) +#define EE_EWENB_CMD(addr_len) (4 << (addr_len)) +#define EE_WRITE_CMD(addr_len) (5 << (addr_len)) +#define EE_READ_CMD(addr_len) (6 << (addr_len)) +#define EE_ERASE_CMD(addr_len) (7 << (addr_len)) /* Receive frame descriptors. */ struct eepro100_rxfd { @@ -433,7 +433,7 @@ static int eepro100_txcmd_send(struct eth_device *dev, static int read_eeprom(struct eth_device *dev, int location, int addr_len) { unsigned short retval = 0; - int read_cmd = location | EE_READ_CMD; + int read_cmd = location | EE_READ_CMD(addr_len); int i; OUTW(dev, EE_ENB & ~EE_CS, SCB_EEPROM); -- cgit v1.3.1 From acdf5d88827a0420ed0ceee3e45fa08f9d39b483 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 16:27:37 +0200 Subject: net: eepro100: Drop inline keyword Drop the inline keyword from the static functions, the compiler has a much better overview and can decide how to inline those functions much better. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index a8d617c7e81..4446251e115 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -209,23 +209,23 @@ static const char i82558_config_cmd[] = { #define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) #endif -static inline int INW(struct eth_device *dev, u_long addr) +static int INW(struct eth_device *dev, u_long addr) { return le16_to_cpu(readw(addr + (void *)dev->iobase)); } -static inline void OUTW(struct eth_device *dev, int command, u_long addr) +static void OUTW(struct eth_device *dev, int command, u_long addr) { writew(cpu_to_le16(command), addr + (void *)dev->iobase); } -static inline void OUTL(struct eth_device *dev, int command, u_long addr) +static void OUTL(struct eth_device *dev, int command, u_long addr) { writel(cpu_to_le32(command), addr + (void *)dev->iobase); } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -static inline int INL(struct eth_device *dev, u_long addr) +static int INL(struct eth_device *dev, u_long addr) { return le32_to_cpu(readl(addr + (void *)dev->iobase)); } -- cgit v1.3.1 From fa9e12102dfc6a5f1f10a75fd1804c16a166ded9 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 16:38:41 +0200 Subject: net: eepro100: Pass PCI BDF into bus_to_phys()/phys_to_bus() This is a trick in preparation for adding DM support. By passing in the PCI BDF into the bus_to_phys()/phys_to_bus() macros and calling that dev, we can substitute dev with udevice when DM support lands and do minor adjustment to the macros to support both DM and non-DM operation. No functional change. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 4446251e115..532d7aa649a 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -202,11 +202,11 @@ static const char i82558_config_cmd[] = { }; #if defined(CONFIG_E500) -#define bus_to_phys(a) (a) -#define phys_to_bus(a) (a) +#define bus_to_phys(dev, a) (a) +#define phys_to_bus(dev, a) (a) #else -#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a) -#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a) +#define bus_to_phys(dev, a) pci_mem_to_phys((dev), (a)) +#define phys_to_bus(dev, a) pci_phys_to_mem((dev), (a)) #endif static int INW(struct eth_device *dev, u_long addr) @@ -352,7 +352,8 @@ static void init_rx_ring(struct eth_device *dev) rx_ring[i].control = (i == NUM_RX_DESC - 1) ? cpu_to_le16 (RFD_CONTROL_S) : 0; rx_ring[i].link = - cpu_to_le32(phys_to_bus((u32)&rx_ring[(i + 1) % + cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + (u32)&rx_ring[(i + 1) % NUM_RX_DESC])); rx_ring[i].rx_buf_addr = 0xffffffff; rx_ring[i].count = cpu_to_le32(PKTSIZE_ALIGN << 16); @@ -401,7 +402,7 @@ static int eepro100_txcmd_send(struct eth_device *dev, if (!wait_for_eepro100(dev)) return -ETIMEDOUT; - OUTL(dev, phys_to_bus((u32)desc), SCB_POINTER); + OUTL(dev, phys_to_bus((pci_dev_t)dev->priv, (u32)desc), SCB_POINTER); OUTW(dev, SCB_M | CU_START, SCB_CMD); while (true) { @@ -562,7 +563,8 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) } /* RX ring cache was already flushed in init_rx_ring() */ - OUTL(dev, phys_to_bus((u32)&rx_ring[rx_next]), SCB_POINTER); + OUTL(dev, phys_to_bus((pci_dev_t)dev->priv, (u32)&rx_ring[rx_next]), + SCB_POINTER); OUTW(dev, SCB_M | RUC_START, SCB_CMD); /* Send the Configure frame */ @@ -573,7 +575,8 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) cfg_cmd->command = cpu_to_le16(CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_CONFIGURE); cfg_cmd->status = 0; - cfg_cmd->link = cpu_to_le32(phys_to_bus((u32)&tx_ring[tx_next])); + cfg_cmd->link = cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + (u32)&tx_ring[tx_next])); memcpy(((struct descriptor *)cfg_cmd)->params, i82558_config_cmd, sizeof(i82558_config_cmd)); @@ -593,7 +596,8 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) ias_cmd->command = cpu_to_le16(CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_IAS); ias_cmd->status = 0; - ias_cmd->link = cpu_to_le32(phys_to_bus((u32)&tx_ring[tx_next])); + ias_cmd->link = cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + (u32)&tx_ring[tx_next])); memcpy(((struct descriptor *)ias_cmd)->params, dev->enetaddr, 6); @@ -629,9 +633,12 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) TXCB_CMD_S | TXCB_CMD_EL); desc->status = 0; desc->count = cpu_to_le32(tx_threshold); - desc->link = cpu_to_le32(phys_to_bus((u32)&tx_ring[tx_next])); - desc->tx_desc_addr = cpu_to_le32(phys_to_bus((u32)&desc->tx_buf_addr0)); - desc->tx_buf_addr0 = cpu_to_le32(phys_to_bus((u_long)packet)); + desc->link = cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + (u32)&tx_ring[tx_next])); + desc->tx_desc_addr = cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + (u32)&desc->tx_buf_addr0)); + desc->tx_buf_addr0 = cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + (u_long)packet)); desc->tx_buf_size0 = cpu_to_le32(length); ret = eepro100_txcmd_send(dev, &tx_ring[tx_cur]); @@ -706,7 +713,8 @@ static int eepro100_recv(struct eth_device *dev) } /* RX ring cache was already flushed in init_rx_ring() */ - OUTL(dev, phys_to_bus((u32)&rx_ring[rx_next]), SCB_POINTER); + OUTL(dev, phys_to_bus((pci_dev_t)dev->priv, + (u32)&rx_ring[rx_next]), SCB_POINTER); OUTW(dev, SCB_M | RUC_START, SCB_CMD); } @@ -785,7 +793,7 @@ int eepro100_initialize(bd_t *bis) sprintf(dev->name, "i82559#%d", card_number); dev->priv = (void *)devno; /* this have to come before bus_to_phys() */ - dev->iobase = bus_to_phys(iobase); + dev->iobase = bus_to_phys(devno, iobase); dev->init = eepro100_init; dev->halt = eepro100_halt; dev->send = eepro100_send; -- cgit v1.3.1 From bd159c6185676c87e4a1cdbb33a869d4c1e05f9e Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 16:49:07 +0200 Subject: net: eepro100: Introduce device private data Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 532d7aa649a..2c25307002b 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -201,6 +201,10 @@ static const char i82558_config_cmd[] = { 0x31, 0x05, }; +struct eepro100_priv { + struct eth_device dev; +}; + #if defined(CONFIG_E500) #define bus_to_phys(dev, a) (a) #define phys_to_bus(dev, a) (a) @@ -751,6 +755,7 @@ done: int eepro100_initialize(bd_t *bis) { + struct eepro100_priv *priv; struct eth_device *dev; int card_number = 0; u32 iobase, status; @@ -785,11 +790,12 @@ int eepro100_initialize(bd_t *bis) continue; } - dev = calloc(1, sizeof(*dev)); - if (!dev) { + priv = calloc(1, sizeof(*priv)); + if (!priv) { printf("eepro100: Can not allocate memory\n"); break; } + dev = &priv->dev; sprintf(dev->name, "i82559#%d", card_number); dev->priv = (void *)devno; /* this have to come before bus_to_phys() */ @@ -804,7 +810,7 @@ int eepro100_initialize(bd_t *bis) ret = eepro100_initialize_mii(dev); if (ret) { eth_unregister(dev); - free(dev); + free(priv); return ret; } -- cgit v1.3.1 From 389da9743c269a0c8536f4700c11c333a0309958 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 17:10:03 +0200 Subject: net: eepro100: Pass device private data around This patch replaces the various uses of struct eth_device for accessing device private data with struct eepro100_priv, which is compatible both with DM and non-DM operation. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 264 ++++++++++++++++++++++++++----------------------- 1 file changed, 140 insertions(+), 124 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 2c25307002b..1c33ec3da23 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -203,6 +203,10 @@ static const char i82558_config_cmd[] = { struct eepro100_priv { struct eth_device dev; + pci_dev_t devno; + char *name; + void __iomem *iobase; + u8 *enetaddr; }; #if defined(CONFIG_E500) @@ -213,40 +217,40 @@ struct eepro100_priv { #define phys_to_bus(dev, a) pci_phys_to_mem((dev), (a)) #endif -static int INW(struct eth_device *dev, u_long addr) +static int INW(struct eepro100_priv *priv, u_long addr) { - return le16_to_cpu(readw(addr + (void *)dev->iobase)); + return le16_to_cpu(readw(addr + priv->iobase)); } -static void OUTW(struct eth_device *dev, int command, u_long addr) +static void OUTW(struct eepro100_priv *priv, int command, u_long addr) { - writew(cpu_to_le16(command), addr + (void *)dev->iobase); + writew(cpu_to_le16(command), addr + priv->iobase); } -static void OUTL(struct eth_device *dev, int command, u_long addr) +static void OUTL(struct eepro100_priv *priv, int command, u_long addr) { - writel(cpu_to_le32(command), addr + (void *)dev->iobase); + writel(cpu_to_le32(command), addr + priv->iobase); } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -static int INL(struct eth_device *dev, u_long addr) +static int INL(struct eepro100_priv *priv, u_long addr) { - return le32_to_cpu(readl(addr + (void *)dev->iobase)); + return le32_to_cpu(readl(addr + priv->iobase)); } -static int get_phyreg(struct eth_device *dev, unsigned char addr, +static int get_phyreg(struct eepro100_priv *priv, unsigned char addr, unsigned char reg, unsigned short *value) { - int cmd; int timeout = 50; + int cmd; /* read requested data */ cmd = (2 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - OUTL(dev, cmd, SCB_CTRL_MDI); + OUTL(priv, cmd, SCB_CTRL_MDI); do { udelay(1000); - cmd = INL(dev, SCB_CTRL_MDI); + cmd = INL(priv, SCB_CTRL_MDI); } while (!(cmd & (1 << 28)) && (--timeout)); if (timeout == 0) @@ -257,17 +261,17 @@ static int get_phyreg(struct eth_device *dev, unsigned char addr, return 0; } -static int set_phyreg(struct eth_device *dev, unsigned char addr, +static int set_phyreg(struct eepro100_priv *priv, unsigned char addr, unsigned char reg, unsigned short value) { - int cmd; int timeout = 50; + int cmd; /* write requested data */ cmd = (1 << 26) | ((addr & 0x1f) << 21) | ((reg & 0x1f) << 16); - OUTL(dev, cmd | value, SCB_CTRL_MDI); + OUTL(priv, cmd | value, SCB_CTRL_MDI); - while (!(INL(dev, SCB_CTRL_MDI) & (1 << 28)) && (--timeout)) + while (!(INL(priv, SCB_CTRL_MDI) & (1 << 28)) && (--timeout)) udelay(1000); if (timeout == 0) @@ -280,49 +284,45 @@ static int set_phyreg(struct eth_device *dev, unsigned char addr, * Check if given phyaddr is valid, i.e. there is a PHY connected. * Do this by checking model value field from ID2 register. */ -static struct eth_device *verify_phyaddr(const char *devname, - unsigned char addr) +static int verify_phyaddr(struct eepro100_priv *priv, unsigned char addr) { - struct eth_device *dev; - unsigned short value; - unsigned char model; - - dev = eth_get_dev_by_name(devname); - if (!dev) { - printf("%s: no such device\n", devname); - return NULL; - } + unsigned short value, model; + int ret; /* read id2 register */ - if (get_phyreg(dev, addr, MII_PHYSID2, &value) != 0) { - printf("%s: mii read timeout!\n", devname); - return NULL; + ret = get_phyreg(priv, addr, MII_PHYSID2, &value); + if (ret) { + printf("%s: mii read timeout!\n", priv->name); + return ret; } /* get model */ - model = (unsigned char)((value >> 4) & 0x003f); - - if (model == 0) { - printf("%s: no PHY at address %d\n", devname, addr); - return NULL; + model = (value >> 4) & 0x003f; + if (!model) { + printf("%s: no PHY at address %d\n", priv->name, addr); + return -EINVAL; } - return dev; + return 0; } static int eepro100_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg) { + struct eth_device *dev = eth_get_dev_by_name(bus->name); + struct eepro100_priv *priv = + container_of(dev, struct eepro100_priv, dev); unsigned short value = 0; - struct eth_device *dev; + int ret; - dev = verify_phyaddr(bus->name, addr); - if (!dev) - return -1; + ret = verify_phyaddr(priv, addr); + if (ret) + return ret; - if (get_phyreg(dev, addr, reg, &value) != 0) { + ret = get_phyreg(priv, addr, reg, &value); + if (ret) { printf("%s: mii read timeout!\n", bus->name); - return -1; + return ret; } return value; @@ -331,23 +331,26 @@ static int eepro100_miiphy_read(struct mii_dev *bus, int addr, int devad, static int eepro100_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg, u16 value) { - struct eth_device *dev; + struct eth_device *dev = eth_get_dev_by_name(bus->name); + struct eepro100_priv *priv = + container_of(dev, struct eepro100_priv, dev); + int ret; - dev = verify_phyaddr(bus->name, addr); - if (!dev) - return -1; + ret = verify_phyaddr(priv, addr); + if (ret) + return ret; - if (set_phyreg(dev, addr, reg, value) != 0) { + ret = set_phyreg(priv, addr, reg, value); + if (ret) { printf("%s: mii write timeout!\n", bus->name); - return -1; + return ret; } return 0; } - #endif -static void init_rx_ring(struct eth_device *dev) +static void init_rx_ring(struct eepro100_priv *priv) { int i; @@ -356,7 +359,7 @@ static void init_rx_ring(struct eth_device *dev) rx_ring[i].control = (i == NUM_RX_DESC - 1) ? cpu_to_le16 (RFD_CONTROL_S) : 0; rx_ring[i].link = - cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + cpu_to_le32(phys_to_bus(priv->devno, (u32)&rx_ring[(i + 1) % NUM_RX_DESC])); rx_ring[i].rx_buf_addr = 0xffffffff; @@ -370,7 +373,7 @@ static void init_rx_ring(struct eth_device *dev) rx_next = 0; } -static void purge_tx_ring(struct eth_device *dev) +static void purge_tx_ring(struct eepro100_priv *priv) { tx_next = 0; tx_threshold = 0x01208000; @@ -382,11 +385,11 @@ static void purge_tx_ring(struct eth_device *dev) } /* Wait for the chip get the command. */ -static int wait_for_eepro100(struct eth_device *dev) +static int wait_for_eepro100(struct eepro100_priv *priv) { int i; - for (i = 0; INW(dev, SCB_CMD) & (CU_CMD_MASK | RU_CMD_MASK); i++) { + for (i = 0; INW(priv, SCB_CMD) & (CU_CMD_MASK | RU_CMD_MASK); i++) { if (i >= TOUT_LOOP) return 0; } @@ -394,7 +397,7 @@ static int wait_for_eepro100(struct eth_device *dev) return 1; } -static int eepro100_txcmd_send(struct eth_device *dev, +static int eepro100_txcmd_send(struct eepro100_priv *priv, struct eepro100_txfd *desc) { u16 rstat; @@ -403,11 +406,11 @@ static int eepro100_txcmd_send(struct eth_device *dev, flush_dcache_range((unsigned long)desc, (unsigned long)desc + sizeof(*desc)); - if (!wait_for_eepro100(dev)) + if (!wait_for_eepro100(priv)) return -ETIMEDOUT; - OUTL(dev, phys_to_bus((pci_dev_t)dev->priv, (u32)desc), SCB_POINTER); - OUTW(dev, SCB_M | CU_START, SCB_CMD); + OUTL(priv, phys_to_bus(priv->devno, (u32)desc), SCB_POINTER); + OUTW(priv, SCB_M | CU_START, SCB_CMD); while (true) { invalidate_dcache_range((unsigned long)desc, @@ -417,7 +420,7 @@ static int eepro100_txcmd_send(struct eth_device *dev, break; if (i++ >= TOUT_LOOP) { - printf("%s: Tx error buffer not ready\n", dev->name); + printf("%s: Tx error buffer not ready\n", priv->name); return -EINVAL; } } @@ -435,42 +438,42 @@ static int eepro100_txcmd_send(struct eth_device *dev, } /* SROM Read. */ -static int read_eeprom(struct eth_device *dev, int location, int addr_len) +static int read_eeprom(struct eepro100_priv *priv, int location, int addr_len) { unsigned short retval = 0; int read_cmd = location | EE_READ_CMD(addr_len); int i; - OUTW(dev, EE_ENB & ~EE_CS, SCB_EEPROM); - OUTW(dev, EE_ENB, SCB_EEPROM); + OUTW(priv, EE_ENB & ~EE_CS, SCB_EEPROM); + OUTW(priv, EE_ENB, SCB_EEPROM); /* Shift the read command bits out. */ for (i = 12; i >= 0; i--) { short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; - OUTW(dev, EE_ENB | dataval, SCB_EEPROM); + OUTW(priv, EE_ENB | dataval, SCB_EEPROM); udelay(1); - OUTW(dev, EE_ENB | dataval | EE_SHIFT_CLK, SCB_EEPROM); + OUTW(priv, EE_ENB | dataval | EE_SHIFT_CLK, SCB_EEPROM); udelay(1); } - OUTW(dev, EE_ENB, SCB_EEPROM); + OUTW(priv, EE_ENB, SCB_EEPROM); for (i = 15; i >= 0; i--) { - OUTW(dev, EE_ENB | EE_SHIFT_CLK, SCB_EEPROM); + OUTW(priv, EE_ENB | EE_SHIFT_CLK, SCB_EEPROM); udelay(1); retval = (retval << 1) | - ((INW(dev, SCB_EEPROM) & EE_DATA_READ) ? 1 : 0); - OUTW(dev, EE_ENB, SCB_EEPROM); + !!(INW(priv, SCB_EEPROM) & EE_DATA_READ); + OUTW(priv, EE_ENB, SCB_EEPROM); udelay(1); } /* Terminate the EEPROM access. */ - OUTW(dev, EE_ENB & ~EE_CS, SCB_EEPROM); + OUTW(priv, EE_ENB & ~EE_CS, SCB_EEPROM); return retval; } #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) -static int eepro100_initialize_mii(struct eth_device *dev) +static int eepro100_initialize_mii(struct eepro100_priv *priv) { /* register mii command access routines */ struct mii_dev *mdiodev; @@ -480,7 +483,7 @@ static int eepro100_initialize_mii(struct eth_device *dev) if (!mdiodev) return -ENOMEM; - strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN); + strncpy(mdiodev->name, priv->name, MDIO_NAME_LEN); mdiodev->read = eepro100_miiphy_read; mdiodev->write = eepro100_miiphy_write; @@ -493,7 +496,7 @@ static int eepro100_initialize_mii(struct eth_device *dev) return 0; } #else -static int eepro100_initialize_mii(struct eth_device *dev) +static int eepro100_initialize_mii(struct eepro100_priv *priv) { return 0; } @@ -506,70 +509,72 @@ static struct pci_device_id supported[] = { { } }; -static void read_hw_addr(struct eth_device *dev, bd_t *bis) +static void read_hw_addr(struct eepro100_priv *priv, bd_t *bis) { u16 sum = 0; int i, j; - int addr_len = read_eeprom(dev, 0, 6) == 0xffff ? 8 : 6; + int addr_len = read_eeprom(priv, 0, 6) == 0xffff ? 8 : 6; for (j = 0, i = 0; i < 0x40; i++) { - u16 value = read_eeprom(dev, i, addr_len); + u16 value = read_eeprom(priv, i, addr_len); sum += value; if (i < 3) { - dev->enetaddr[j++] = value; - dev->enetaddr[j++] = value >> 8; + priv->enetaddr[j++] = value; + priv->enetaddr[j++] = value >> 8; } } if (sum != 0xBABA) { - memset(dev->enetaddr, 0, ETH_ALEN); + memset(priv->enetaddr, 0, ETH_ALEN); debug("%s: Invalid EEPROM checksum %#4.4x, check settings before activating this device!\n", - dev->name, sum); + priv->name, sum); } } static int eepro100_init(struct eth_device *dev, bd_t *bis) { + struct eepro100_priv *priv = + container_of(dev, struct eepro100_priv, dev); struct eepro100_txfd *ias_cmd, *cfg_cmd; int ret, status = -1; int tx_cur; /* Reset the ethernet controller */ - OUTL(dev, I82559_SELECTIVE_RESET, SCB_PORT); + OUTL(priv, I82559_SELECTIVE_RESET, SCB_PORT); udelay(20); - OUTL(dev, I82559_RESET, SCB_PORT); + OUTL(priv, I82559_RESET, SCB_PORT); udelay(20); - if (!wait_for_eepro100(dev)) { + if (!wait_for_eepro100(priv)) { printf("Error: Can not reset ethernet controller.\n"); goto done; } - OUTL(dev, 0, SCB_POINTER); - OUTW(dev, SCB_M | RUC_ADDR_LOAD, SCB_CMD); + OUTL(priv, 0, SCB_POINTER); + OUTW(priv, SCB_M | RUC_ADDR_LOAD, SCB_CMD); - if (!wait_for_eepro100(dev)) { + if (!wait_for_eepro100(priv)) { printf("Error: Can not reset ethernet controller.\n"); goto done; } - OUTL(dev, 0, SCB_POINTER); - OUTW(dev, SCB_M | CU_ADDR_LOAD, SCB_CMD); + OUTL(priv, 0, SCB_POINTER); + OUTW(priv, SCB_M | CU_ADDR_LOAD, SCB_CMD); /* Initialize Rx and Tx rings. */ - init_rx_ring(dev); - purge_tx_ring(dev); + init_rx_ring(priv); + purge_tx_ring(priv); /* Tell the adapter where the RX ring is located. */ - if (!wait_for_eepro100(dev)) { + if (!wait_for_eepro100(priv)) { printf("Error: Can not reset ethernet controller.\n"); goto done; } /* RX ring cache was already flushed in init_rx_ring() */ - OUTL(dev, phys_to_bus((pci_dev_t)dev->priv, (u32)&rx_ring[rx_next]), + OUTL(priv, phys_to_bus(priv->devno, (u32)&rx_ring[rx_next]), SCB_POINTER); - OUTW(dev, SCB_M | RUC_START, SCB_CMD); + OUTW(priv, SCB_M | RUC_START, SCB_CMD); /* Send the Configure frame */ tx_cur = tx_next; @@ -579,13 +584,13 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) cfg_cmd->command = cpu_to_le16(CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_CONFIGURE); cfg_cmd->status = 0; - cfg_cmd->link = cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + cfg_cmd->link = cpu_to_le32(phys_to_bus(priv->devno, (u32)&tx_ring[tx_next])); memcpy(((struct descriptor *)cfg_cmd)->params, i82558_config_cmd, sizeof(i82558_config_cmd)); - ret = eepro100_txcmd_send(dev, cfg_cmd); + ret = eepro100_txcmd_send(priv, cfg_cmd); if (ret) { if (ret == -ETIMEDOUT) printf("Error---CONFIG_SYS_CMD_CONFIGURE: Can not reset ethernet controller.\n"); @@ -600,12 +605,12 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) ias_cmd->command = cpu_to_le16(CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_IAS); ias_cmd->status = 0; - ias_cmd->link = cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + ias_cmd->link = cpu_to_le32(phys_to_bus(priv->devno, (u32)&tx_ring[tx_next])); - memcpy(((struct descriptor *)ias_cmd)->params, dev->enetaddr, 6); + memcpy(((struct descriptor *)ias_cmd)->params, priv->enetaddr, 6); - ret = eepro100_txcmd_send(dev, ias_cmd); + ret = eepro100_txcmd_send(priv, ias_cmd); if (ret) { if (ret == -ETIMEDOUT) printf("Error: Can not reset ethernet controller.\n"); @@ -620,12 +625,14 @@ done: static int eepro100_send(struct eth_device *dev, void *packet, int length) { + struct eepro100_priv *priv = + container_of(dev, struct eepro100_priv, dev); struct eepro100_txfd *desc; int ret, status = -1; int tx_cur; if (length <= 0) { - printf("%s: bad packet size: %d\n", dev->name, length); + printf("%s: bad packet size: %d\n", priv->name, length); goto done; } @@ -637,19 +644,19 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) TXCB_CMD_S | TXCB_CMD_EL); desc->status = 0; desc->count = cpu_to_le32(tx_threshold); - desc->link = cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, - (u32)&tx_ring[tx_next])); - desc->tx_desc_addr = cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + desc->link = cpu_to_le32(phys_to_bus(priv->devno, + (u32)&tx_ring[tx_next])); + desc->tx_desc_addr = cpu_to_le32(phys_to_bus(priv->devno, (u32)&desc->tx_buf_addr0)); - desc->tx_buf_addr0 = cpu_to_le32(phys_to_bus((pci_dev_t)dev->priv, + desc->tx_buf_addr0 = cpu_to_le32(phys_to_bus(priv->devno, (u_long)packet)); desc->tx_buf_size0 = cpu_to_le32(length); - ret = eepro100_txcmd_send(dev, &tx_ring[tx_cur]); + ret = eepro100_txcmd_send(priv, &tx_ring[tx_cur]); if (ret) { if (ret == -ETIMEDOUT) printf("%s: Tx error ethernet controller not ready.\n", - dev->name); + priv->name); goto done; } @@ -661,12 +668,14 @@ done: static int eepro100_recv(struct eth_device *dev) { + struct eepro100_priv *priv = + container_of(dev, struct eepro100_priv, dev); struct eepro100_rxfd *desc; int rx_prev, length = 0; u16 status, stat; - stat = INW(dev, SCB_STATUS); - OUTW(dev, stat & SCB_STATUS_RNR, SCB_STATUS); + stat = INW(priv, SCB_STATUS); + OUTW(priv, stat & SCB_STATUS_RNR, SCB_STATUS); for (;;) { desc = &rx_ring[rx_next]; @@ -706,20 +715,20 @@ static int eepro100_recv(struct eth_device *dev) } if (stat & SCB_STATUS_RNR) { - printf("%s: Receiver is not ready, restart it !\n", dev->name); + printf("%s: Receiver is not ready, restart it !\n", priv->name); /* Reinitialize Rx ring. */ - init_rx_ring(dev); + init_rx_ring(priv); - if (!wait_for_eepro100(dev)) { + if (!wait_for_eepro100(priv)) { printf("Error: Can not restart ethernet controller.\n"); goto done; } /* RX ring cache was already flushed in init_rx_ring() */ - OUTL(dev, phys_to_bus((pci_dev_t)dev->priv, - (u32)&rx_ring[rx_next]), SCB_POINTER); - OUTW(dev, SCB_M | RUC_START, SCB_CMD); + OUTL(priv, phys_to_bus(priv->devno, + (u32)&rx_ring[rx_next]), SCB_POINTER); + OUTW(priv, SCB_M | RUC_START, SCB_CMD); } done: @@ -728,26 +737,29 @@ done: static void eepro100_halt(struct eth_device *dev) { + struct eepro100_priv *priv = + container_of(dev, struct eepro100_priv, dev); + /* Reset the ethernet controller */ - OUTL(dev, I82559_SELECTIVE_RESET, SCB_PORT); + OUTL(priv, I82559_SELECTIVE_RESET, SCB_PORT); udelay(20); - OUTL(dev, I82559_RESET, SCB_PORT); + OUTL(priv, I82559_RESET, SCB_PORT); udelay(20); - if (!wait_for_eepro100(dev)) { + if (!wait_for_eepro100(priv)) { printf("Error: Can not reset ethernet controller.\n"); goto done; } - OUTL(dev, 0, SCB_POINTER); - OUTW(dev, SCB_M | RUC_ADDR_LOAD, SCB_CMD); + OUTL(priv, 0, SCB_POINTER); + OUTW(priv, SCB_M | RUC_ADDR_LOAD, SCB_CMD); - if (!wait_for_eepro100(dev)) { + if (!wait_for_eepro100(priv)) { printf("Error: Can not reset ethernet controller.\n"); goto done; } - OUTL(dev, 0, SCB_POINTER); - OUTW(dev, SCB_M | CU_ADDR_LOAD, SCB_CMD); + OUTL(priv, 0, SCB_POINTER); + OUTW(priv, SCB_M | CU_ADDR_LOAD, SCB_CMD); done: return; @@ -798,8 +810,12 @@ int eepro100_initialize(bd_t *bis) dev = &priv->dev; sprintf(dev->name, "i82559#%d", card_number); - dev->priv = (void *)devno; /* this have to come before bus_to_phys() */ - dev->iobase = bus_to_phys(devno, iobase); + priv->name = dev->name; + /* this have to come before bus_to_phys() */ + priv->devno = devno; + priv->iobase = (void __iomem *)bus_to_phys(devno, iobase); + priv->enetaddr = dev->enetaddr; + dev->init = eepro100_init; dev->halt = eepro100_halt; dev->send = eepro100_send; @@ -807,7 +823,7 @@ int eepro100_initialize(bd_t *bis) eth_register(dev); - ret = eepro100_initialize_mii(dev); + ret = eepro100_initialize_mii(priv); if (ret) { eth_unregister(dev); free(priv); @@ -821,7 +837,7 @@ int eepro100_initialize(bd_t *bis) udelay(10 * 1000); - read_hw_addr(dev, bis); + read_hw_addr(priv, bis); } return card_number; -- cgit v1.3.1 From 39daab23768895c32b82e153c21a7955ae7dacb8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 17:55:50 +0200 Subject: net: eepro100: Pass device private data into mdiobus Instead of doing ethernet device lookup by name every time there is an MDIO access, pass the driver private data via mdiobus priv to the MDIO bus accessors. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 1c33ec3da23..78dedbdcc9c 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -309,9 +309,7 @@ static int verify_phyaddr(struct eepro100_priv *priv, unsigned char addr) static int eepro100_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg) { - struct eth_device *dev = eth_get_dev_by_name(bus->name); - struct eepro100_priv *priv = - container_of(dev, struct eepro100_priv, dev); + struct eepro100_priv *priv = bus->priv; unsigned short value = 0; int ret; @@ -331,9 +329,7 @@ static int eepro100_miiphy_read(struct mii_dev *bus, int addr, int devad, static int eepro100_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg, u16 value) { - struct eth_device *dev = eth_get_dev_by_name(bus->name); - struct eepro100_priv *priv = - container_of(dev, struct eepro100_priv, dev); + struct eepro100_priv *priv = bus->priv; int ret; ret = verify_phyaddr(priv, addr); @@ -486,6 +482,7 @@ static int eepro100_initialize_mii(struct eepro100_priv *priv) strncpy(mdiodev->name, priv->name, MDIO_NAME_LEN); mdiodev->read = eepro100_miiphy_read; mdiodev->write = eepro100_miiphy_write; + mdiodev->priv = priv; ret = mdio_register(mdiodev); if (ret < 0) { -- cgit v1.3.1 From fb8307e52af1e9dd4854c7b3addd27ef04a098d4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 17:13:26 +0200 Subject: net: eepro100: Add RX/TX rings into the private data The RX/TX DMA descriptor rings are per-device-instance private data, so move them into the private data. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 59 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 78dedbdcc9c..ed6bbd5cf82 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -183,12 +183,6 @@ struct descriptor { /* A generic descriptor. */ #define TOUT_LOOP 1000000 -static struct eepro100_rxfd rx_ring[NUM_RX_DESC]; /* RX descriptor ring */ -static struct eepro100_txfd tx_ring[NUM_TX_DESC]; /* TX descriptor ring */ -static int rx_next; /* RX descriptor ring pointer */ -static int tx_next; /* TX descriptor ring pointer */ -static int tx_threshold; - /* * The parameters for a CmdConfigure operation. * There are so many options that it would be difficult to document @@ -202,6 +196,15 @@ static const char i82558_config_cmd[] = { }; struct eepro100_priv { + /* RX descriptor ring */ + struct eepro100_rxfd rx_ring[NUM_RX_DESC]; + /* TX descriptor ring */ + struct eepro100_txfd tx_ring[NUM_TX_DESC]; + /* RX descriptor ring pointer */ + int rx_next; + /* TX descriptor ring pointer */ + int tx_next; + int tx_threshold; struct eth_device dev; pci_dev_t devno; char *name; @@ -348,6 +351,7 @@ static int eepro100_miiphy_write(struct mii_dev *bus, int addr, int devad, static void init_rx_ring(struct eepro100_priv *priv) { + struct eepro100_rxfd *rx_ring = priv->rx_ring; int i; for (i = 0; i < NUM_RX_DESC; i++) { @@ -366,13 +370,15 @@ static void init_rx_ring(struct eepro100_priv *priv) (unsigned long)rx_ring + (sizeof(*rx_ring) * NUM_RX_DESC)); - rx_next = 0; + priv->rx_next = 0; } static void purge_tx_ring(struct eepro100_priv *priv) { - tx_next = 0; - tx_threshold = 0x01208000; + struct eepro100_txfd *tx_ring = priv->tx_ring; + + priv->tx_next = 0; + priv->tx_threshold = 0x01208000; memset(tx_ring, 0, sizeof(*tx_ring) * NUM_TX_DESC); flush_dcache_range((unsigned long)tx_ring, @@ -533,6 +539,8 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) { struct eepro100_priv *priv = container_of(dev, struct eepro100_priv, dev); + struct eepro100_rxfd *rx_ring = priv->rx_ring; + struct eepro100_txfd *tx_ring = priv->tx_ring; struct eepro100_txfd *ias_cmd, *cfg_cmd; int ret, status = -1; int tx_cur; @@ -569,20 +577,20 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) } /* RX ring cache was already flushed in init_rx_ring() */ - OUTL(priv, phys_to_bus(priv->devno, (u32)&rx_ring[rx_next]), + OUTL(priv, phys_to_bus(priv->devno, (u32)&rx_ring[priv->rx_next]), SCB_POINTER); OUTW(priv, SCB_M | RUC_START, SCB_CMD); /* Send the Configure frame */ - tx_cur = tx_next; - tx_next = ((tx_next + 1) % NUM_TX_DESC); + tx_cur = priv->tx_next; + priv->tx_next = ((priv->tx_next + 1) % NUM_TX_DESC); cfg_cmd = &tx_ring[tx_cur]; cfg_cmd->command = cpu_to_le16(CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_CONFIGURE); cfg_cmd->status = 0; cfg_cmd->link = cpu_to_le32(phys_to_bus(priv->devno, - (u32)&tx_ring[tx_next])); + (u32)&tx_ring[priv->tx_next])); memcpy(((struct descriptor *)cfg_cmd)->params, i82558_config_cmd, sizeof(i82558_config_cmd)); @@ -595,15 +603,15 @@ static int eepro100_init(struct eth_device *dev, bd_t *bis) } /* Send the Individual Address Setup frame */ - tx_cur = tx_next; - tx_next = ((tx_next + 1) % NUM_TX_DESC); + tx_cur = priv->tx_next; + priv->tx_next = ((priv->tx_next + 1) % NUM_TX_DESC); ias_cmd = &tx_ring[tx_cur]; ias_cmd->command = cpu_to_le16(CONFIG_SYS_CMD_SUSPEND | CONFIG_SYS_CMD_IAS); ias_cmd->status = 0; ias_cmd->link = cpu_to_le32(phys_to_bus(priv->devno, - (u32)&tx_ring[tx_next])); + (u32)&tx_ring[priv->tx_next])); memcpy(((struct descriptor *)ias_cmd)->params, priv->enetaddr, 6); @@ -624,6 +632,7 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) { struct eepro100_priv *priv = container_of(dev, struct eepro100_priv, dev); + struct eepro100_txfd *tx_ring = priv->tx_ring; struct eepro100_txfd *desc; int ret, status = -1; int tx_cur; @@ -633,16 +642,16 @@ static int eepro100_send(struct eth_device *dev, void *packet, int length) goto done; } - tx_cur = tx_next; - tx_next = (tx_next + 1) % NUM_TX_DESC; + tx_cur = priv->tx_next; + priv->tx_next = (priv->tx_next + 1) % NUM_TX_DESC; desc = &tx_ring[tx_cur]; desc->command = cpu_to_le16(TXCB_CMD_TRANSMIT | TXCB_CMD_SF | TXCB_CMD_S | TXCB_CMD_EL); desc->status = 0; - desc->count = cpu_to_le32(tx_threshold); + desc->count = cpu_to_le32(priv->tx_threshold); desc->link = cpu_to_le32(phys_to_bus(priv->devno, - (u32)&tx_ring[tx_next])); + (u32)&tx_ring[priv->tx_next])); desc->tx_desc_addr = cpu_to_le32(phys_to_bus(priv->devno, (u32)&desc->tx_buf_addr0)); desc->tx_buf_addr0 = cpu_to_le32(phys_to_bus(priv->devno, @@ -667,6 +676,7 @@ static int eepro100_recv(struct eth_device *dev) { struct eepro100_priv *priv = container_of(dev, struct eepro100_priv, dev); + struct eepro100_rxfd *rx_ring = priv->rx_ring; struct eepro100_rxfd *desc; int rx_prev, length = 0; u16 status, stat; @@ -675,7 +685,7 @@ static int eepro100_recv(struct eth_device *dev) OUTW(priv, stat & SCB_STATUS_RNR, SCB_STATUS); for (;;) { - desc = &rx_ring[rx_next]; + desc = &rx_ring[priv->rx_next]; invalidate_dcache_range((unsigned long)desc, (unsigned long)desc + sizeof(*desc)); status = le16_to_cpu(desc->status); @@ -701,14 +711,14 @@ static int eepro100_recv(struct eth_device *dev) flush_dcache_range((unsigned long)desc, (unsigned long)desc + sizeof(*desc)); - rx_prev = (rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC; + rx_prev = (priv->rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC; desc = &rx_ring[rx_prev]; desc->control = 0; flush_dcache_range((unsigned long)desc, (unsigned long)desc + sizeof(*desc)); /* Update entry information. */ - rx_next = (rx_next + 1) % NUM_RX_DESC; + priv->rx_next = (priv->rx_next + 1) % NUM_RX_DESC; } if (stat & SCB_STATUS_RNR) { @@ -724,7 +734,8 @@ static int eepro100_recv(struct eth_device *dev) /* RX ring cache was already flushed in init_rx_ring() */ OUTL(priv, phys_to_bus(priv->devno, - (u32)&rx_ring[rx_next]), SCB_POINTER); + (u32)&rx_ring[priv->rx_next]), + SCB_POINTER); OUTW(priv, SCB_M | RUC_START, SCB_CMD); } -- cgit v1.3.1 From 43b738350ce133bc19c2bd4586ecff486e39e835 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 17:20:39 +0200 Subject: net: eepro100: Drop bd_t pointer from read_hw_addr() The pointer is unused, so drop it. Rename the function to start with the eepro100_ prefix. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index ed6bbd5cf82..fb8a68f84c1 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -512,7 +512,7 @@ static struct pci_device_id supported[] = { { } }; -static void read_hw_addr(struct eepro100_priv *priv, bd_t *bis) +static void eepro100_get_hwaddr(struct eepro100_priv *priv) { u16 sum = 0; int i, j; @@ -845,7 +845,7 @@ int eepro100_initialize(bd_t *bis) udelay(10 * 1000); - read_hw_addr(priv, bis); + eepro100_get_hwaddr(priv); } return card_number; -- cgit v1.3.1 From 8835103e24622cefd37a1a8d5011c160da6a34df Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 17:28:20 +0200 Subject: net: eepro100: Split common parts of non-DM functions out Split the common code from the non-DM code, so it can be reused by the DM code later. As always, the recv() function had to be split into the actual receiving part and free_pkt part to fit with the DM. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 162 ++++++++++++++++++++++++++++++------------------- 1 file changed, 100 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index fb8a68f84c1..f4748325524 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -202,6 +202,7 @@ struct eepro100_priv { struct eepro100_txfd tx_ring[NUM_TX_DESC]; /* RX descriptor ring pointer */ int rx_next; + u16 rx_stat; /* TX descriptor ring pointer */ int tx_next; int tx_threshold; @@ -535,10 +536,8 @@ static void eepro100_get_hwaddr(struct eepro100_priv *priv) } } -static int eepro100_init(struct eth_device *dev, bd_t *bis) +static int eepro100_init_common(struct eepro100_priv *priv) { - struct eepro100_priv *priv = - container_of(dev, struct eepro100_priv, dev); struct eepro100_rxfd *rx_ring = priv->rx_ring; struct eepro100_txfd *tx_ring = priv->tx_ring; struct eepro100_txfd *ias_cmd, *cfg_cmd; @@ -628,10 +627,9 @@ done: return status; } -static int eepro100_send(struct eth_device *dev, void *packet, int length) +static int eepro100_send_common(struct eepro100_priv *priv, + void *packet, int length) { - struct eepro100_priv *priv = - container_of(dev, struct eepro100_priv, dev); struct eepro100_txfd *tx_ring = priv->tx_ring; struct eepro100_txfd *desc; int ret, status = -1; @@ -672,82 +670,82 @@ done: return status; } -static int eepro100_recv(struct eth_device *dev) +static int eepro100_recv_common(struct eepro100_priv *priv, uchar **packetp) { - struct eepro100_priv *priv = - container_of(dev, struct eepro100_priv, dev); struct eepro100_rxfd *rx_ring = priv->rx_ring; struct eepro100_rxfd *desc; - int rx_prev, length = 0; - u16 status, stat; + int length; + u16 status; - stat = INW(priv, SCB_STATUS); - OUTW(priv, stat & SCB_STATUS_RNR, SCB_STATUS); + priv->rx_stat = INW(priv, SCB_STATUS); + OUTW(priv, priv->rx_stat & SCB_STATUS_RNR, SCB_STATUS); - for (;;) { - desc = &rx_ring[priv->rx_next]; - invalidate_dcache_range((unsigned long)desc, - (unsigned long)desc + sizeof(*desc)); - status = le16_to_cpu(desc->status); + desc = &rx_ring[priv->rx_next]; + invalidate_dcache_range((unsigned long)desc, + (unsigned long)desc + sizeof(*desc)); + status = le16_to_cpu(desc->status); + + if (!(status & RFD_STATUS_C)) + return 0; + + /* Valid frame status. */ + if (status & RFD_STATUS_OK) { + /* A valid frame received. */ + length = le32_to_cpu(desc->count) & 0x3fff; + /* Pass the packet up to the protocol layers. */ + *packetp = desc->data; + return length; + } - if (!(status & RFD_STATUS_C)) - break; + /* There was an error. */ + printf("RX error status = 0x%08X\n", status); + return -EINVAL; +} - /* Valid frame status. */ - if ((status & RFD_STATUS_OK)) { - /* A valid frame received. */ - length = le32_to_cpu(desc->count) & 0x3fff; +static void eepro100_free_pkt_common(struct eepro100_priv *priv) +{ + struct eepro100_rxfd *rx_ring = priv->rx_ring; + struct eepro100_rxfd *desc; + int rx_prev; - /* Pass the packet up to the protocol layers. */ - net_process_received_packet((u8 *)desc->data, length); - } else { - /* There was an error. */ - printf("RX error status = 0x%08X\n", status); - } + desc = &rx_ring[priv->rx_next]; - desc->control = cpu_to_le16(RFD_CONTROL_S); - desc->status = 0; - desc->count = cpu_to_le32(PKTSIZE_ALIGN << 16); - flush_dcache_range((unsigned long)desc, - (unsigned long)desc + sizeof(*desc)); + desc->control = cpu_to_le16(RFD_CONTROL_S); + desc->status = 0; + desc->count = cpu_to_le32(PKTSIZE_ALIGN << 16); + flush_dcache_range((unsigned long)desc, + (unsigned long)desc + sizeof(*desc)); - rx_prev = (priv->rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC; - desc = &rx_ring[rx_prev]; - desc->control = 0; - flush_dcache_range((unsigned long)desc, - (unsigned long)desc + sizeof(*desc)); + rx_prev = (priv->rx_next + NUM_RX_DESC - 1) % NUM_RX_DESC; + desc = &rx_ring[rx_prev]; + desc->control = 0; + flush_dcache_range((unsigned long)desc, + (unsigned long)desc + sizeof(*desc)); - /* Update entry information. */ - priv->rx_next = (priv->rx_next + 1) % NUM_RX_DESC; - } + /* Update entry information. */ + priv->rx_next = (priv->rx_next + 1) % NUM_RX_DESC; - if (stat & SCB_STATUS_RNR) { - printf("%s: Receiver is not ready, restart it !\n", priv->name); + if (!(priv->rx_stat & SCB_STATUS_RNR)) + return; - /* Reinitialize Rx ring. */ - init_rx_ring(priv); + printf("%s: Receiver is not ready, restart it !\n", priv->name); - if (!wait_for_eepro100(priv)) { - printf("Error: Can not restart ethernet controller.\n"); - goto done; - } + /* Reinitialize Rx ring. */ + init_rx_ring(priv); - /* RX ring cache was already flushed in init_rx_ring() */ - OUTL(priv, phys_to_bus(priv->devno, - (u32)&rx_ring[priv->rx_next]), - SCB_POINTER); - OUTW(priv, SCB_M | RUC_START, SCB_CMD); + if (!wait_for_eepro100(priv)) { + printf("Error: Can not restart ethernet controller.\n"); + return; } -done: - return length; + /* RX ring cache was already flushed in init_rx_ring() */ + OUTL(priv, phys_to_bus(priv->devno, (u32)&rx_ring[priv->rx_next]), + SCB_POINTER); + OUTW(priv, SCB_M | RUC_START, SCB_CMD); } -static void eepro100_halt(struct eth_device *dev) +static void eepro100_halt_common(struct eepro100_priv *priv) { - struct eepro100_priv *priv = - container_of(dev, struct eepro100_priv, dev); - /* Reset the ethernet controller */ OUTL(priv, I82559_SELECTIVE_RESET, SCB_PORT); udelay(20); @@ -773,6 +771,46 @@ done: return; } +static int eepro100_init(struct eth_device *dev, bd_t *bis) +{ + struct eepro100_priv *priv = + container_of(dev, struct eepro100_priv, dev); + + return eepro100_init_common(priv); +} + +static void eepro100_halt(struct eth_device *dev) +{ + struct eepro100_priv *priv = + container_of(dev, struct eepro100_priv, dev); + + eepro100_halt_common(priv); +} + +static int eepro100_send(struct eth_device *dev, void *packet, int length) +{ + struct eepro100_priv *priv = + container_of(dev, struct eepro100_priv, dev); + + return eepro100_send_common(priv, packet, length); +} + +static int eepro100_recv(struct eth_device *dev) +{ + struct eepro100_priv *priv = + container_of(dev, struct eepro100_priv, dev); + uchar *packet; + int ret; + + ret = eepro100_recv_common(priv, &packet); + if (ret > 0) + net_process_received_packet(packet, ret); + if (ret) + eepro100_free_pkt_common(priv); + + return ret; +} + int eepro100_initialize(bd_t *bis) { struct eepro100_priv *priv; -- cgit v1.3.1 From af8ecdf7e5d9ec13581906172a1a9762d9a7a504 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 16:26:20 +0200 Subject: net: eepro100: Add DM support Add support for driver model to the driver. Signed-off-by: Marek Vasut --- drivers/net/eepro100.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index f4748325524..45ea3b70fca 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -206,14 +206,21 @@ struct eepro100_priv { /* TX descriptor ring pointer */ int tx_next; int tx_threshold; +#ifdef CONFIG_DM_ETH + struct udevice *devno; +#else struct eth_device dev; pci_dev_t devno; +#endif char *name; void __iomem *iobase; u8 *enetaddr; }; -#if defined(CONFIG_E500) +#if defined(CONFIG_DM_ETH) +#define bus_to_phys(dev, a) dm_pci_mem_to_phys((dev), (a)) +#define phys_to_bus(dev, a) dm_pci_phys_to_mem((dev), (a)) +#elif defined(CONFIG_E500) #define bus_to_phys(dev, a) (a) #define phys_to_bus(dev, a) (a) #else @@ -771,6 +778,7 @@ done: return; } +#ifndef CONFIG_DM_ETH static int eepro100_init(struct eth_device *dev, bd_t *bis) { struct eepro100_priv *priv = @@ -888,3 +896,122 @@ int eepro100_initialize(bd_t *bis) return card_number; } + +#else /* DM_ETH */ +static int eepro100_start(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct eepro100_priv *priv = dev_get_priv(dev); + + memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr)); + + return eepro100_init_common(priv); +} + +static void eepro100_stop(struct udevice *dev) +{ + struct eepro100_priv *priv = dev_get_priv(dev); + + eepro100_halt_common(priv); +} + +static int eepro100_send(struct udevice *dev, void *packet, int length) +{ + struct eepro100_priv *priv = dev_get_priv(dev); + int ret; + + ret = eepro100_send_common(priv, packet, length); + + return ret ? 0 : -ETIMEDOUT; +} + +static int eepro100_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct eepro100_priv *priv = dev_get_priv(dev); + + return eepro100_recv_common(priv, packetp); +} + +static int eepro100_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct eepro100_priv *priv = dev_get_priv(dev); + + eepro100_free_pkt_common(priv); + + return 0; +} + +static int eepro100_read_rom_hwaddr(struct udevice *dev) +{ + struct eepro100_priv *priv = dev_get_priv(dev); + + eepro100_get_hwaddr(priv); + + return 0; +} + +static int eepro100_bind(struct udevice *dev) +{ + static int card_number; + char name[16]; + + sprintf(name, "eepro100#%u", card_number++); + + return device_set_name(dev, name); +} + +static int eepro100_probe(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct eepro100_priv *priv = dev_get_priv(dev); + u16 command, status; + u32 iobase; + int ret; + + dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &iobase); + iobase &= ~0xf; + + debug("eepro100: Intel i82559 PCI EtherExpressPro @0x%x\n", iobase); + + priv->devno = dev; + priv->enetaddr = plat->enetaddr; + priv->iobase = (void __iomem *)bus_to_phys(dev, iobase); + + command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + dm_pci_write_config16(dev, PCI_COMMAND, command); + dm_pci_read_config16(dev, PCI_COMMAND, &status); + if ((status & command) != command) { + printf("eepro100: Couldn't enable IO access or Bus Mastering\n"); + return -EINVAL; + } + + ret = eepro100_initialize_mii(priv); + if (ret) + return ret; + + dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x20); + + return 0; +} + +static const struct eth_ops eepro100_ops = { + .start = eepro100_start, + .send = eepro100_send, + .recv = eepro100_recv, + .stop = eepro100_stop, + .free_pkt = eepro100_free_pkt, + .read_rom_hwaddr = eepro100_read_rom_hwaddr, +}; + +U_BOOT_DRIVER(eth_eepro100) = { + .name = "eth_eepro100", + .id = UCLASS_ETH, + .bind = eepro100_bind, + .probe = eepro100_probe, + .ops = &eepro100_ops, + .priv_auto_alloc_size = sizeof(struct eepro100_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), +}; + +U_BOOT_PCI_DEVICE(eth_eepro100, supported); +#endif -- cgit v1.3.1 From 6463b73e0b25b058404c52b48c991abf4f8a94ce Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 23 May 2020 18:07:53 +0200 Subject: net: eepro100: Add Kconfig entries Add Kconfig entries for the eepro100 driver and convert various boards. Signed-off-by: Marek Vasut --- README | 3 --- configs/MPC8315ERDB_defconfig | 1 + configs/TQM834x_defconfig | 1 + configs/integratorap_cm720t_defconfig | 1 + configs/integratorap_cm920t_defconfig | 1 + configs/integratorap_cm926ejs_defconfig | 1 + configs/integratorap_cm946es_defconfig | 1 + drivers/net/Kconfig | 6 ++++++ include/configs/MPC8315ERDB.h | 1 - include/configs/MPC8323ERDB.h | 1 - include/configs/MPC832XEMDS.h | 1 - include/configs/MPC8349EMDS.h | 1 - include/configs/MPC8349EMDS_SDRAM.h | 1 - include/configs/MPC837XEMDS.h | 1 - include/configs/MPC8536DS.h | 1 - include/configs/MPC8540ADS.h | 1 - include/configs/MPC8541CDS.h | 1 - include/configs/MPC8544DS.h | 1 - include/configs/MPC8548CDS.h | 1 - include/configs/MPC8555CDS.h | 1 - include/configs/MPC8560ADS.h | 1 - include/configs/MPC8568MDS.h | 1 - include/configs/MPC8569MDS.h | 1 - include/configs/MPC8572DS.h | 1 - include/configs/MPC8641HPCN.h | 1 - include/configs/TQM834x.h | 2 -- include/configs/caddy2.h | 1 - include/configs/integratorap.h | 1 - include/configs/sbc8349.h | 1 - include/configs/sbc8548.h | 1 - include/configs/sbc8641d.h | 1 - include/configs/vme8349.h | 1 - scripts/config_whitelist.txt | 1 - 33 files changed, 12 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/README b/README index b49154076e9..4367ac3798c 100644 --- a/README +++ b/README @@ -889,9 +889,6 @@ The following options need to be configured: Allow generic access to the SPI bus on the Intel 8257x, for example with the "sspi" command. - CONFIG_EEPRO100 - Support for Intel 82557/82559/82559ER chips. - CONFIG_TULIP Support for Digital 2114x chips. diff --git a/configs/MPC8315ERDB_defconfig b/configs/MPC8315ERDB_defconfig index bbb79dff2ed..d7981e9855f 100644 --- a/configs/MPC8315ERDB_defconfig +++ b/configs/MPC8315ERDB_defconfig @@ -147,6 +147,7 @@ CONFIG_PHY_NATSEMI=y CONFIG_PHY_REALTEK=y CONFIG_PHY_SMSC=y CONFIG_PHY_VITESSE=y +CONFIG_EEPRO100=y CONFIG_MII=y CONFIG_TSEC_ENET=y CONFIG_SYS_NS16550=y diff --git a/configs/TQM834x_defconfig b/configs/TQM834x_defconfig index 96ce4de0e68..c29d8a8be1f 100644 --- a/configs/TQM834x_defconfig +++ b/configs/TQM834x_defconfig @@ -159,6 +159,7 @@ CONFIG_PHY_NATSEMI=y CONFIG_PHY_REALTEK=y CONFIG_PHY_SMSC=y CONFIG_PHY_VITESSE=y +CONFIG_EEPRO100=y CONFIG_MII=y CONFIG_TSEC_ENET=y CONFIG_SYS_NS16550=y diff --git a/configs/integratorap_cm720t_defconfig b/configs/integratorap_cm720t_defconfig index f5f9cb28b38..1b7d672bcb8 100644 --- a/configs/integratorap_cm720t_defconfig +++ b/configs/integratorap_cm720t_defconfig @@ -24,6 +24,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_EEPRO100=y CONFIG_PCI=y CONFIG_BAUDRATE=38400 CONFIG_OF_LIBFDT=y diff --git a/configs/integratorap_cm920t_defconfig b/configs/integratorap_cm920t_defconfig index 8a0ad1f9481..116ac015a08 100644 --- a/configs/integratorap_cm920t_defconfig +++ b/configs/integratorap_cm920t_defconfig @@ -24,6 +24,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_EEPRO100=y CONFIG_PCI=y CONFIG_BAUDRATE=38400 CONFIG_OF_LIBFDT=y diff --git a/configs/integratorap_cm926ejs_defconfig b/configs/integratorap_cm926ejs_defconfig index ab61bf2ef46..9c1a3fa2f5d 100644 --- a/configs/integratorap_cm926ejs_defconfig +++ b/configs/integratorap_cm926ejs_defconfig @@ -24,6 +24,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_EEPRO100=y CONFIG_PCI=y CONFIG_BAUDRATE=38400 CONFIG_OF_LIBFDT=y diff --git a/configs/integratorap_cm946es_defconfig b/configs/integratorap_cm946es_defconfig index 7af54331610..ee9c69bce05 100644 --- a/configs/integratorap_cm946es_defconfig +++ b/configs/integratorap_cm946es_defconfig @@ -24,6 +24,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_PROTECTION=y CONFIG_SYS_FLASH_CFI=y +CONFIG_EEPRO100=y CONFIG_PCI=y CONFIG_BAUDRATE=38400 CONFIG_OF_LIBFDT=y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index bb23f73fc23..ed07a78044e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -193,6 +193,12 @@ config CMD_E1000 used on devices with SPI support you can reprogram the EEPROM from U-Boot. +config EEPRO100 + bool "Intel PRO/100 82557/82559/82559ER Fast Ethernet support" + help + This driver supports Intel(R) PRO/100 82557/82559/82559ER fast + ethernet family of adapters. + config ETH_SANDBOX depends on DM_ETH && SANDBOX default y diff --git a/include/configs/MPC8315ERDB.h b/include/configs/MPC8315ERDB.h index da68f3ccca7..21594b4d38d 100644 --- a/include/configs/MPC8315ERDB.h +++ b/include/configs/MPC8315ERDB.h @@ -239,7 +239,6 @@ #define CONFIG_PCI_INDIRECT_BRIDGE #define CONFIG_PCIE -#define CONFIG_EEPRO100 #undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ #define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1957 /* Freescale */ diff --git a/include/configs/MPC8323ERDB.h b/include/configs/MPC8323ERDB.h index eaa95bbeff5..0cd2e084593 100644 --- a/include/configs/MPC8323ERDB.h +++ b/include/configs/MPC8323ERDB.h @@ -172,7 +172,6 @@ #define CONFIG_PCI_INDIRECT_BRIDGE #define CONFIG_PCI_SKIP_HOST_BRIDGE -#undef CONFIG_EEPRO100 #undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ #define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1957 /* Freescale */ diff --git a/include/configs/MPC832XEMDS.h b/include/configs/MPC832XEMDS.h index d2d1b2fa47d..ae79369c6b0 100644 --- a/include/configs/MPC832XEMDS.h +++ b/include/configs/MPC832XEMDS.h @@ -196,7 +196,6 @@ #define CONFIG_83XX_PCI_STREAMING -#undef CONFIG_EEPRO100 #undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ #define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1957 /* Freescale */ diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h index 4707dcf1ab2..41ef3d80e1a 100644 --- a/include/configs/MPC8349EMDS.h +++ b/include/configs/MPC8349EMDS.h @@ -220,7 +220,6 @@ #define CONFIG_83XX_PCI_STREAMING -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #if !defined(CONFIG_PCI_PNP) diff --git a/include/configs/MPC8349EMDS_SDRAM.h b/include/configs/MPC8349EMDS_SDRAM.h index d92312b4083..4b43ee1d448 100644 --- a/include/configs/MPC8349EMDS_SDRAM.h +++ b/include/configs/MPC8349EMDS_SDRAM.h @@ -275,7 +275,6 @@ #define CONFIG_83XX_PCI_STREAMING -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #if !defined(CONFIG_PCI_PNP) diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h index b5660f9ff55..49d4aef9add 100644 --- a/include/configs/MPC837XEMDS.h +++ b/include/configs/MPC837XEMDS.h @@ -238,7 +238,6 @@ extern int board_pci_host_broken(void); #define CONFIG_USB_EHCI_FSL #define CONFIG_EHCI_HCD_INIT_AFTER_RESET -#undef CONFIG_EEPRO100 #undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ #define CONFIG_SYS_PCI_SUBSYS_VENDORID 0x1957 /* Freescale */ #endif /* CONFIG_PCI */ diff --git a/include/configs/MPC8536DS.h b/include/configs/MPC8536DS.h index 340574a9852..62da11e4a12 100644 --- a/include/configs/MPC8536DS.h +++ b/include/configs/MPC8536DS.h @@ -466,7 +466,6 @@ #define CONFIG_SYS_ISA_IO_BASE_ADDRESS CONFIG_SYS_PCIE3_IO_VIRT #endif -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #ifndef CONFIG_PCI_PNP diff --git a/include/configs/MPC8540ADS.h b/include/configs/MPC8540ADS.h index f78782a1c14..19859671cd3 100644 --- a/include/configs/MPC8540ADS.h +++ b/include/configs/MPC8540ADS.h @@ -236,7 +236,6 @@ #define CONFIG_SYS_PCI1_IO_SIZE 0x100000 /* 1M */ #if defined(CONFIG_PCI) -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #if !defined(CONFIG_PCI_PNP) diff --git a/include/configs/MPC8541CDS.h b/include/configs/MPC8541CDS.h index b2a32010720..013bd775ddb 100644 --- a/include/configs/MPC8541CDS.h +++ b/include/configs/MPC8541CDS.h @@ -282,7 +282,6 @@ extern unsigned long get_clock_freq(void); #define CONFIG_MPC85XX_PCI2 -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ diff --git a/include/configs/MPC8544DS.h b/include/configs/MPC8544DS.h index c9f193fc467..1dd030842a1 100644 --- a/include/configs/MPC8544DS.h +++ b/include/configs/MPC8544DS.h @@ -258,7 +258,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_SYS_ISA_IO_BASE_ADDRESS VIDEO_IO_OFFSET #endif -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #ifndef CONFIG_PCI_PNP diff --git a/include/configs/MPC8548CDS.h b/include/configs/MPC8548CDS.h index de2bfd8f2f4..e3044f0ae69 100644 --- a/include/configs/MPC8548CDS.h +++ b/include/configs/MPC8548CDS.h @@ -380,7 +380,6 @@ extern unsigned long get_clock_freq(void); #endif #if defined(CONFIG_PCI) -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #if !defined(CONFIG_DM_PCI) diff --git a/include/configs/MPC8555CDS.h b/include/configs/MPC8555CDS.h index d964b4e1217..70289f570ac 100644 --- a/include/configs/MPC8555CDS.h +++ b/include/configs/MPC8555CDS.h @@ -280,7 +280,6 @@ extern unsigned long get_clock_freq(void); #define CONFIG_MPC85XX_PCI2 -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ diff --git a/include/configs/MPC8560ADS.h b/include/configs/MPC8560ADS.h index 97d8cc48edf..fc4040907ab 100644 --- a/include/configs/MPC8560ADS.h +++ b/include/configs/MPC8560ADS.h @@ -233,7 +233,6 @@ #define CONFIG_SYS_PCI1_IO_SIZE 0x100000 /* 1M */ #if defined(CONFIG_PCI) -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #if !defined(CONFIG_PCI_PNP) diff --git a/include/configs/MPC8568MDS.h b/include/configs/MPC8568MDS.h index a0bd5f4d40f..60caea4a4cb 100644 --- a/include/configs/MPC8568MDS.h +++ b/include/configs/MPC8568MDS.h @@ -290,7 +290,6 @@ extern unsigned long get_clock_freq(void); #endif /* CONFIG_QE */ #if defined(CONFIG_PCI) -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ diff --git a/include/configs/MPC8569MDS.h b/include/configs/MPC8569MDS.h index beba848214e..4d6a3d0a7de 100644 --- a/include/configs/MPC8569MDS.h +++ b/include/configs/MPC8569MDS.h @@ -396,7 +396,6 @@ extern unsigned long get_clock_freq(void); #endif /* CONFIG_QE */ #if defined(CONFIG_PCI) -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #undef CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ diff --git a/include/configs/MPC8572DS.h b/include/configs/MPC8572DS.h index 3243f39df4b..bad91429215 100644 --- a/include/configs/MPC8572DS.h +++ b/include/configs/MPC8572DS.h @@ -443,7 +443,6 @@ #define CONFIG_SYS_ISA_IO_BASE_ADDRESS VIDEO_IO_OFFSET #endif -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #ifndef CONFIG_PCI_PNP diff --git a/include/configs/MPC8641HPCN.h b/include/configs/MPC8641HPCN.h index edbeeefdd4a..78d1dd2c371 100644 --- a/include/configs/MPC8641HPCN.h +++ b/include/configs/MPC8641HPCN.h @@ -334,7 +334,6 @@ extern unsigned long get_board_sys_clk(unsigned long dummy); #define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP /************************************************************ diff --git a/include/configs/TQM834x.h b/include/configs/TQM834x.h index 40fe62fdf0b..d43d2179568 100644 --- a/include/configs/TQM834x.h +++ b/include/configs/TQM834x.h @@ -167,8 +167,6 @@ #define CONFIG_SYS_PCI1_IO_PHYS CONFIG_SYS_PCI1_IO_BASE #define CONFIG_SYS_PCI1_IO_SIZE 0x1000000 /* 16M */ -#undef CONFIG_EEPRO100 -#define CONFIG_EEPRO100 #undef CONFIG_TULIP #if !defined(CONFIG_PCI_PNP) diff --git a/include/configs/caddy2.h b/include/configs/caddy2.h index 35f4b74727f..a7c667711b1 100644 --- a/include/configs/caddy2.h +++ b/include/configs/caddy2.h @@ -155,7 +155,6 @@ #if defined(CONFIG_PCI) -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #if !defined(CONFIG_PCI_PNP) diff --git a/include/configs/integratorap.h b/include/configs/integratorap.h index cc18347ff6c..96c1d53b9bd 100644 --- a/include/configs/integratorap.h +++ b/include/configs/integratorap.h @@ -35,7 +35,6 @@ */ #define CONFIG_TULIP -#define CONFIG_EEPRO100 #define CONFIG_SYS_RX_ETH_BUFFER 8 /* use 8 rx buffer on eepro100 */ /*----------------------------------------------------------------------- diff --git a/include/configs/sbc8349.h b/include/configs/sbc8349.h index 5adf5a8ca40..cca596d43a4 100644 --- a/include/configs/sbc8349.h +++ b/include/configs/sbc8349.h @@ -180,7 +180,6 @@ #if defined(CONFIG_PCI) -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #if !defined(CONFIG_PCI_PNP) diff --git a/include/configs/sbc8548.h b/include/configs/sbc8548.h index 55c4bff28ae..503b9b1cb50 100644 --- a/include/configs/sbc8548.h +++ b/include/configs/sbc8548.h @@ -434,7 +434,6 @@ #endif #if defined(CONFIG_PCI) -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ diff --git a/include/configs/sbc8641d.h b/include/configs/sbc8641d.h index 4ab364ae9a2..66c1f3595ba 100644 --- a/include/configs/sbc8641d.h +++ b/include/configs/sbc8641d.h @@ -276,7 +276,6 @@ #define CONFIG_PCI_SCAN_SHOW /* show pci devices on startup */ -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #if !defined(CONFIG_PCI_PNP) diff --git a/include/configs/vme8349.h b/include/configs/vme8349.h index 3f578720e59..52d632ba0ae 100644 --- a/include/configs/vme8349.h +++ b/include/configs/vme8349.h @@ -155,7 +155,6 @@ #if defined(CONFIG_PCI) -#undef CONFIG_EEPRO100 #undef CONFIG_TULIP #if !defined(CONFIG_PCI_PNP) diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 86350ab9c85..8620a2f0456 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -399,7 +399,6 @@ CONFIG_EDB93XX_SDCS0 CONFIG_EDB93XX_SDCS1 CONFIG_EDB93XX_SDCS2 CONFIG_EDB93XX_SDCS3 -CONFIG_EEPRO100 CONFIG_EFLASH_PROTSECTORS CONFIG_EHCI_DESC_BIG_ENDIAN CONFIG_EHCI_HCD_INIT_AFTER_RESET -- cgit v1.3.1 From 97d5c145592c1d2aa38a8d074fed9aee059ac119 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 15:10:41 +0200 Subject: net: pcnet: Drop typedef struct pcnet_priv_t Use struct pcnet_priv all over the place instead. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 260a5a38cff..c6f080d956b 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -76,15 +76,15 @@ struct pcnet_uncached_priv { struct pcnet_init_block init_block; }; -typedef struct pcnet_priv { +struct pcnet_priv { struct pcnet_uncached_priv *uc; /* Receive Buffer space */ unsigned char (*rx_buf)[RX_RING_SIZE][PKT_BUF_SZ + 4]; int cur_rx; int cur_tx; -} pcnet_priv_t; +}; -static pcnet_priv_t *lp; +static struct pcnet_priv *lp; /* Offsets from base I/O address for WIO mode */ #define PCNET_RDP 0x10 @@ -340,9 +340,9 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * must be aligned on 16-byte boundaries. */ if (lp == NULL) { - addr = (unsigned long)malloc(sizeof(pcnet_priv_t) + 0x10); + addr = (unsigned long)malloc(sizeof(*lp) + 0x10); addr = (addr + 0xf) & ~0xf; - lp = (pcnet_priv_t *)addr; + lp = (struct pcnet_priv *)addr; addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->uc)); -- cgit v1.3.1 From 1524e409ef130e20e6554446d08be967422d27f7 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:12:19 +0200 Subject: net: pcnet: Drop PCNET_HAS_PROM All of one PCNET users has this option set, make this default and drop this config option. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 5 ----- include/configs/malta.h | 1 - 2 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index c6f080d956b..edc4dba24cb 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -241,10 +241,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) { int chip_version; char *chipname; - -#ifdef PCNET_HAS_PROM int i; -#endif /* Reset the PCnet controller */ pcnet_reset(dev); @@ -279,7 +276,6 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) PCNET_DEBUG1("AMD %s\n", chipname); -#ifdef PCNET_HAS_PROM /* * In most chips, after a chip reset, the ethernet address is read from * the station address PROM at the base address and programmed into the @@ -293,7 +289,6 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) dev->enetaddr[2 * i] = val & 0x0ff; dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; } -#endif /* PCNET_HAS_PROM */ return 0; } diff --git a/include/configs/malta.h b/include/configs/malta.h index 773d7c23ed8..82c90042d98 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -16,7 +16,6 @@ #define CONFIG_PCI_GT64120 #define CONFIG_PCI_MSC01 #define CONFIG_PCNET -#define PCNET_HAS_PROM #define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0 -- cgit v1.3.1 From e4797c31612d9c31b7b65fce8c3081ae2d150d00 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 17:33:17 +0200 Subject: net: pcnet: Use PCI_DEVICE() to define PCI device compat list Use this macro to fully fill the PCI device ID table. This is mandatory for the DM PCI support, which checks all the fields. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index edc4dba24cb..e7ce79e952d 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -155,7 +155,7 @@ static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, } static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE}, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE) }, {} }; -- cgit v1.3.1 From 1c38c36eb99abfd1bc46b90c80f7daa5c65f3527 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 16:16:45 +0200 Subject: net: pcnet: Simplify private data allocation The current code is horribly complex. Both the RX and TX buffer descriptors are 16 bytes in size, the init block is 32 bytes in size, so simplify the code such that the entire private data of the driver are allocated cache aligned and the RX and TX buffer descriptors are part of the private data. This removes multiple malloc calls and cache flushes. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index e7ce79e952d..72b93806244 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -74,12 +75,13 @@ struct pcnet_uncached_priv { struct pcnet_rx_head rx_ring[RX_RING_SIZE]; struct pcnet_tx_head tx_ring[TX_RING_SIZE]; struct pcnet_init_block init_block; -}; +} __aligned(ARCH_DMA_MINALIGN); struct pcnet_priv { - struct pcnet_uncached_priv *uc; + struct pcnet_uncached_priv ucp; /* Receive Buffer space */ - unsigned char (*rx_buf)[RX_RING_SIZE][PKT_BUF_SZ + 4]; + unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; + struct pcnet_uncached_priv *uc; int cur_rx; int cur_tx; }; @@ -335,22 +337,11 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * must be aligned on 16-byte boundaries. */ if (lp == NULL) { - addr = (unsigned long)malloc(sizeof(*lp) + 0x10); - addr = (addr + 0xf) & ~0xf; - lp = (struct pcnet_priv *)addr; - - addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, - sizeof(*lp->uc)); - flush_dcache_range(addr, addr + sizeof(*lp->uc)); - addr = (unsigned long)map_physmem(addr, - roundup(sizeof(*lp->uc), ARCH_DMA_MINALIGN), - MAP_NOCACHE); - lp->uc = (struct pcnet_uncached_priv *)addr; - - addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, - sizeof(*lp->rx_buf)); - flush_dcache_range(addr, addr + sizeof(*lp->rx_buf)); - lp->rx_buf = (void *)addr; + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); } uc = lp->uc; @@ -364,7 +355,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ lp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { - addr = pcnet_virt_to_mem(dev, (*lp->rx_buf)[i]); + addr = pcnet_virt_to_mem(dev, lp->rx_buf[i]); uc->rx_ring[i].base = cpu_to_le32(addr); uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); uc->rx_ring[i].status = cpu_to_le16(0x8000); @@ -521,7 +512,7 @@ static int pcnet_recv (struct eth_device *dev) printf("%s: Rx%d: invalid packet length %d\n", dev->name, lp->cur_rx, pkt_len); } else { - buf = (*lp->rx_buf)[lp->cur_rx]; + buf = lp->rx_buf[lp->cur_rx]; invalidate_dcache_range((unsigned long)buf, (unsigned long)buf + pkt_len); net_process_received_packet(buf, pkt_len); -- cgit v1.3.1 From ae38e96c23f3d08e2ec49206a99271252f5b3dc2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 16:26:57 +0200 Subject: net: pcnet: Replace memset+malloc with calloc This combination of functions can be replaced with calloc(), make it so. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 72b93806244..b670cff2aae 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -184,12 +184,11 @@ int pcnet_initialize(bd_t *bis) /* * Allocate and pre-fill the device structure. */ - dev = (struct eth_device *)malloc(sizeof(*dev)); + dev = calloc(1, sizeof(*dev)); if (!dev) { printf("pcnet: Can not allocate memory\n"); break; } - memset(dev, 0, sizeof(*dev)); dev->priv = (void *)(unsigned long)devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr); -- cgit v1.3.1 From 246d2bfcf244326c43dcfffcecfdf684b8a4513d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 16:26:00 +0200 Subject: net: pcnet: Move private data allocation to initialize The private data allocation does not have to be done every time the NIC is initialized at run time, move the allocation to initialize function, which means it will be done only once when the driver starts. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index b670cff2aae..073ffca6b62 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -189,6 +189,20 @@ int pcnet_initialize(bd_t *bis) printf("pcnet: Can not allocate memory\n"); break; } + + /* + * We only maintain one structure because the drivers will + * never be used concurrently. In 32bit mode the RX and TX + * ring entries must be aligned on 16-byte boundaries. + */ + if (!lp) { + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + } + dev->priv = (void *)(unsigned long)devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr); @@ -330,19 +344,6 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) val |= 0x3 << 10; pcnet_write_csr(dev, 80, val); - /* - * We only maintain one structure because the drivers will never - * be used concurrently. In 32bit mode the RX and TX ring entries - * must be aligned on 16-byte boundaries. - */ - if (lp == NULL) { - lp = malloc_cache_aligned(sizeof(*lp)); - lp->uc = map_physmem((phys_addr_t)&lp->ucp, - sizeof(lp->ucp), MAP_NOCACHE); - flush_dcache_range((unsigned long)lp, - (unsigned long)lp + sizeof(*lp)); - } - uc = lp->uc; uc->init_block.mode = cpu_to_le16(0x0000); -- cgit v1.3.1 From 69e08bd735c6d90a00959e0062f587f521f5d3df Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 16:31:41 +0200 Subject: net: pcnet: Move initialize function at the end Move the function at the end of the driver, so we could drop various forward declarations later. No functional change. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 180 ++++++++++++++++++++++++++-------------------------- 1 file changed, 89 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 073ffca6b62..6d464cd0a4e 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -161,97 +161,6 @@ static struct pci_device_id supported[] = { {} }; - -int pcnet_initialize(bd_t *bis) -{ - pci_dev_t devbusfn; - struct eth_device *dev; - u16 command, status; - int dev_nr = 0; - u32 bar; - - PCNET_DEBUG1("\npcnet_initialize...\n"); - - for (dev_nr = 0;; dev_nr++) { - - /* - * Find the PCnet PCI device(s). - */ - devbusfn = pci_find_devices(supported, dev_nr); - if (devbusfn < 0) - break; - - /* - * Allocate and pre-fill the device structure. - */ - dev = calloc(1, sizeof(*dev)); - if (!dev) { - printf("pcnet: Can not allocate memory\n"); - break; - } - - /* - * We only maintain one structure because the drivers will - * never be used concurrently. In 32bit mode the RX and TX - * ring entries must be aligned on 16-byte boundaries. - */ - if (!lp) { - lp = malloc_cache_aligned(sizeof(*lp)); - lp->uc = map_physmem((phys_addr_t)&lp->ucp, - sizeof(lp->ucp), MAP_NOCACHE); - flush_dcache_range((unsigned long)lp, - (unsigned long)lp + sizeof(*lp)); - } - - dev->priv = (void *)(unsigned long)devbusfn; - sprintf(dev->name, "pcnet#%d", dev_nr); - - /* - * Setup the PCI device. - */ - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar); - dev->iobase = pci_mem_to_phys(devbusfn, bar); - dev->iobase &= ~0xf; - - PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", - dev->name, devbusfn, (unsigned long)dev->iobase); - - command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_write_config_word(devbusfn, PCI_COMMAND, command); - pci_read_config_word(devbusfn, PCI_COMMAND, &status); - if ((status & command) != command) { - printf("%s: Couldn't enable IO access or Bus Mastering\n", - dev->name); - free(dev); - continue; - } - - pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40); - - /* - * Probe the PCnet chip. - */ - if (pcnet_probe(dev, bis, dev_nr) < 0) { - free(dev); - continue; - } - - /* - * Setup device structure and register the driver. - */ - dev->init = pcnet_init; - dev->halt = pcnet_halt; - dev->send = pcnet_send; - dev->recv = pcnet_recv; - - eth_register(dev); - } - - udelay(10 * 1000); - - return dev_nr; -} - static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) { int chip_version; @@ -548,3 +457,92 @@ static void pcnet_halt(struct eth_device *dev) if (i <= 0) printf("%s: TIMEOUT: controller reset failed\n", dev->name); } + +int pcnet_initialize(bd_t *bis) +{ + pci_dev_t devbusfn; + struct eth_device *dev; + u16 command, status; + int dev_nr = 0; + u32 bar; + + PCNET_DEBUG1("\npcnet_initialize...\n"); + + for (dev_nr = 0; ; dev_nr++) { + /* + * Find the PCnet PCI device(s). + */ + devbusfn = pci_find_devices(supported, dev_nr); + if (devbusfn < 0) + break; + + /* + * Allocate and pre-fill the device structure. + */ + dev = calloc(1, sizeof(*dev)); + if (!dev) { + printf("pcnet: Can not allocate memory\n"); + break; + } + + /* + * We only maintain one structure because the drivers will + * never be used concurrently. In 32bit mode the RX and TX + * ring entries must be aligned on 16-byte boundaries. + */ + if (!lp) { + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + } + + dev->priv = (void *)(unsigned long)devbusfn; + sprintf(dev->name, "pcnet#%d", dev_nr); + + /* + * Setup the PCI device. + */ + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar); + dev->iobase = pci_mem_to_phys(devbusfn, bar); + dev->iobase &= ~0xf; + + PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", + dev->name, devbusfn, (unsigned long)dev->iobase); + + command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + pci_write_config_word(devbusfn, PCI_COMMAND, command); + pci_read_config_word(devbusfn, PCI_COMMAND, &status); + if ((status & command) != command) { + printf("%s: Couldn't enable IO access or Bus Mastering\n", + dev->name); + free(dev); + continue; + } + + pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40); + + /* + * Probe the PCnet chip. + */ + if (pcnet_probe(dev, bis, dev_nr) < 0) { + free(dev); + continue; + } + + /* + * Setup device structure and register the driver. + */ + dev->init = pcnet_init; + dev->halt = pcnet_halt; + dev->send = pcnet_send; + dev->recv = pcnet_recv; + + eth_register(dev); + } + + udelay(10 * 1000); + + return dev_nr; +} -- cgit v1.3.1 From d20e857e6b60720ff8ca98f8a4411336303e8d5f Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 16:28:41 +0200 Subject: net: pcnet: Drop useless forward declarations Remove those as they are not needed anymore. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 6d464cd0a4e..d8249f0a1cf 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -141,12 +141,6 @@ static int pcnet_check(struct eth_device *dev) return readw(base + PCNET_RAP) == 88; } -static int pcnet_init (struct eth_device *dev, bd_t * bis); -static int pcnet_send(struct eth_device *dev, void *packet, int length); -static int pcnet_recv (struct eth_device *dev); -static void pcnet_halt (struct eth_device *dev); -static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num); - static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, void *addr) { -- cgit v1.3.1 From 60074d9d3ea048ea0ca369687aaaaed65695fc44 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 16:31:04 +0200 Subject: net: pcnet: Wrap devbusfn into private data Instead of using eth_device priv for this PCI devbusfn, free it so it could be used for driver private data, and wrap devbusfn into those driver private data. Note that using the name dev for the variable is a trick left for later, when DM support is in place, so dm_pci_virt_to_mem() can be used with minimal ifdeffery. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index d8249f0a1cf..f7f1b8fc21f 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -82,6 +82,7 @@ struct pcnet_priv { /* Receive Buffer space */ unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; struct pcnet_uncached_priv *uc; + pci_dev_t dev; int cur_rx; int cur_tx; }; @@ -141,13 +142,11 @@ static int pcnet_check(struct eth_device *dev) return readw(base + PCNET_RAP) == 88; } -static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, - void *addr) +static inline pci_addr_t pcnet_virt_to_mem(struct pcnet_priv *lp, void *addr) { - pci_dev_t devbusfn = (pci_dev_t)(unsigned long)dev->priv; void *virt_addr = addr; - return pci_virt_to_mem(devbusfn, virt_addr); + return pci_virt_to_mem(lp->dev, virt_addr); } static struct pci_device_id supported[] = { @@ -258,7 +257,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ lp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { - addr = pcnet_virt_to_mem(dev, lp->rx_buf[i]); + addr = pcnet_virt_to_mem(lp, lp->rx_buf[i]); uc->rx_ring[i].base = cpu_to_le32(addr); uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); uc->rx_ring[i].status = cpu_to_le16(0x8000); @@ -290,9 +289,9 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) uc->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS | RX_RING_LEN_BITS); - addr = pcnet_virt_to_mem(dev, uc->rx_ring); + addr = pcnet_virt_to_mem(lp, uc->rx_ring); uc->init_block.rx_ring = cpu_to_le32(addr); - addr = pcnet_virt_to_mem(dev, uc->tx_ring); + addr = pcnet_virt_to_mem(lp, uc->tx_ring); uc->init_block.tx_ring = cpu_to_le32(addr); PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", @@ -303,7 +302,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * Tell the controller where the Init Block is located. */ barrier(); - addr = pcnet_virt_to_mem(dev, &lp->uc->init_block); + addr = pcnet_virt_to_mem(lp, &lp->uc->init_block); pcnet_write_csr(dev, 1, addr & 0xffff); pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); @@ -361,7 +360,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) * Setup Tx ring. Caution: the write order is important here, * set the status with the "ownership" bits last. */ - addr = pcnet_virt_to_mem(dev, packet); + addr = pcnet_virt_to_mem(lp, packet); writew(-pkt_len, &entry->length); writel(0, &entry->misc); writel(addr, &entry->base); @@ -492,7 +491,7 @@ int pcnet_initialize(bd_t *bis) (unsigned long)lp + sizeof(*lp)); } - dev->priv = (void *)(unsigned long)devbusfn; + lp->dev = devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr); /* -- cgit v1.3.1 From fdf6cbe54d1bdf217bed9b117ed2a823ae5c8dc2 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 16:47:07 +0200 Subject: net: pcnet: Pass private data through dev->priv Get rid of the global point to private data, and rather pass it thought dev->priv. Also remove the unnecessary check for lp being non-NULL, since it is always NULL at this point. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index f7f1b8fc21f..dab08c07add 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -87,8 +87,6 @@ struct pcnet_priv { int cur_tx; }; -static struct pcnet_priv *lp; - /* Offsets from base I/O address for WIO mode */ #define PCNET_RDP 0x10 #define PCNET_RAP 0x12 @@ -212,6 +210,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) static int pcnet_init(struct eth_device *dev, bd_t *bis) { + struct pcnet_priv *lp = dev->priv; struct pcnet_uncached_priv *uc; int i, val; unsigned long addr; @@ -331,6 +330,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) { + struct pcnet_priv *lp = dev->priv; int i, status; u32 addr; struct pcnet_tx_head *entry = &lp->uc->tx_ring[lp->cur_tx]; @@ -379,6 +379,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) static int pcnet_recv (struct eth_device *dev) { + struct pcnet_priv *lp = dev->priv; struct pcnet_rx_head *entry; unsigned char *buf; int pkt_len = 0; @@ -455,6 +456,7 @@ int pcnet_initialize(bd_t *bis) { pci_dev_t devbusfn; struct eth_device *dev; + struct pcnet_priv *lp; u16 command, status; int dev_nr = 0; u32 bar; @@ -483,15 +485,13 @@ int pcnet_initialize(bd_t *bis) * never be used concurrently. In 32bit mode the RX and TX * ring entries must be aligned on 16-byte boundaries. */ - if (!lp) { - lp = malloc_cache_aligned(sizeof(*lp)); - lp->uc = map_physmem((phys_addr_t)&lp->ucp, - sizeof(lp->ucp), MAP_NOCACHE); - flush_dcache_range((unsigned long)lp, - (unsigned long)lp + sizeof(*lp)); - } - + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); lp->dev = devbusfn; + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + dev->priv = lp; sprintf(dev->name, "pcnet#%d", dev_nr); /* -- cgit v1.3.1 From 3b2d63a739f27d8a139f880cc92e66072e1ef5e4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 17:00:42 +0200 Subject: net: pcnet: Wrap iobase into private data Instead of using the non-DM-only iobase in struct eth_device, add one into the private data to make DM and non-DM operation possible. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 103 +++++++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index dab08c07add..b0bd4af2039 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -83,6 +83,7 @@ struct pcnet_priv { unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; struct pcnet_uncached_priv *uc; pci_dev_t dev; + void __iomem *iobase; int cur_rx; int cur_tx; }; @@ -93,51 +94,39 @@ struct pcnet_priv { #define PCNET_RESET 0x14 #define PCNET_BDP 0x16 -static u16 pcnet_read_csr(struct eth_device *dev, int index) +static u16 pcnet_read_csr(struct pcnet_priv *lp, int index) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - return readw(base + PCNET_RDP); + writew(index, lp->iobase + PCNET_RAP); + return readw(lp->iobase + PCNET_RDP); } -static void pcnet_write_csr(struct eth_device *dev, int index, u16 val) +static void pcnet_write_csr(struct pcnet_priv *lp, int index, u16 val) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - writew(val, base + PCNET_RDP); + writew(index, lp->iobase + PCNET_RAP); + writew(val, lp->iobase + PCNET_RDP); } -static u16 pcnet_read_bcr(struct eth_device *dev, int index) +static u16 pcnet_read_bcr(struct pcnet_priv *lp, int index) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - return readw(base + PCNET_BDP); + writew(index, lp->iobase + PCNET_RAP); + return readw(lp->iobase + PCNET_BDP); } -static void pcnet_write_bcr(struct eth_device *dev, int index, u16 val) +static void pcnet_write_bcr(struct pcnet_priv *lp, int index, u16 val) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - writew(val, base + PCNET_BDP); + writew(index, lp->iobase + PCNET_RAP); + writew(val, lp->iobase + PCNET_BDP); } -static void pcnet_reset(struct eth_device *dev) +static void pcnet_reset(struct pcnet_priv *lp) { - void __iomem *base = (void __iomem *)dev->iobase; - - readw(base + PCNET_RESET); + readw(lp->iobase + PCNET_RESET); } -static int pcnet_check(struct eth_device *dev) +static int pcnet_check(struct pcnet_priv *lp) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(88, base + PCNET_RAP); - return readw(base + PCNET_RAP) == 88; + writew(88, lp->iobase + PCNET_RAP); + return readw(lp->iobase + PCNET_RAP) == 88; } static inline pci_addr_t pcnet_virt_to_mem(struct pcnet_priv *lp, void *addr) @@ -154,22 +143,22 @@ static struct pci_device_id supported[] = { static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) { + struct pcnet_priv *lp = dev->priv; int chip_version; char *chipname; int i; /* Reset the PCnet controller */ - pcnet_reset(dev); + pcnet_reset(lp); /* Check if register access is working */ - if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) { + if (pcnet_read_csr(lp, 0) != 4 || !pcnet_check(lp)) { printf("%s: CSR register access check failed\n", dev->name); return -1; } /* Identify the chip */ - chip_version = - pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev, 89) << 16); + chip_version = pcnet_read_csr(lp, 88) | (pcnet_read_csr(lp, 89) << 16); if ((chip_version & 0xfff) != 0x003) return -1; chip_version = (chip_version >> 12) & 0xffff; @@ -199,7 +188,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) for (i = 0; i < 3; i++) { unsigned int val; - val = pcnet_read_csr(dev, i + 12) & 0x0ffff; + val = pcnet_read_csr(lp, i + 12) & 0x0ffff; /* There may be endianness issues here. */ dev->enetaddr[2 * i] = val & 0x0ff; dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; @@ -218,17 +207,17 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) PCNET_DEBUG1("%s: pcnet_init...\n", dev->name); /* Switch pcnet to 32bit mode */ - pcnet_write_bcr(dev, 20, 2); + pcnet_write_bcr(lp, 20, 2); /* Set/reset autoselect bit */ - val = pcnet_read_bcr(dev, 2) & ~2; + val = pcnet_read_bcr(lp, 2) & ~2; val |= 2; - pcnet_write_bcr(dev, 2, val); + pcnet_write_bcr(lp, 2, val); /* Enable auto negotiate, setup, disable fd */ - val = pcnet_read_bcr(dev, 32) & ~0x98; + val = pcnet_read_bcr(lp, 32) & ~0x98; val |= 0x20; - pcnet_write_bcr(dev, 32, val); + pcnet_write_bcr(lp, 32, val); /* * Enable NOUFLO on supported controllers, with the transmit @@ -238,12 +227,12 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * slower devices. Controllers which do not support NOUFLO will * simply be left with a larger transmit FIFO threshold. */ - val = pcnet_read_bcr(dev, 18); + val = pcnet_read_bcr(lp, 18); val |= 1 << 11; - pcnet_write_bcr(dev, 18, val); - val = pcnet_read_csr(dev, 80); + pcnet_write_bcr(lp, 18, val); + val = pcnet_read_csr(lp, 80); val |= 0x3 << 10; - pcnet_write_csr(dev, 80, val); + pcnet_write_csr(lp, 80, val); uc = lp->uc; @@ -302,28 +291,28 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ barrier(); addr = pcnet_virt_to_mem(lp, &lp->uc->init_block); - pcnet_write_csr(dev, 1, addr & 0xffff); - pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); + pcnet_write_csr(lp, 1, addr & 0xffff); + pcnet_write_csr(lp, 2, (addr >> 16) & 0xffff); - pcnet_write_csr(dev, 4, 0x0915); - pcnet_write_csr(dev, 0, 0x0001); /* start */ + pcnet_write_csr(lp, 4, 0x0915); + pcnet_write_csr(lp, 0, 0x0001); /* start */ /* Wait for Init Done bit */ for (i = 10000; i > 0; i--) { - if (pcnet_read_csr(dev, 0) & 0x0100) + if (pcnet_read_csr(lp, 0) & 0x0100) break; udelay(10); } if (i <= 0) { printf("%s: TIMEOUT: controller init failed\n", dev->name); - pcnet_reset(dev); + pcnet_reset(lp); return -1; } /* * Finally start network controller operation. */ - pcnet_write_csr(dev, 0, 0x0002); + pcnet_write_csr(lp, 0, 0x0002); return 0; } @@ -367,7 +356,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) writew(0x8300, &entry->status); /* Trigger an immediate send poll. */ - pcnet_write_csr(dev, 0, 0x0008); + pcnet_write_csr(lp, 0, 0x0008); failure: if (++lp->cur_tx >= TX_RING_SIZE) @@ -435,16 +424,17 @@ static int pcnet_recv (struct eth_device *dev) static void pcnet_halt(struct eth_device *dev) { + struct pcnet_priv *lp = dev->priv; int i; PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name); /* Reset the PCnet controller */ - pcnet_reset(dev); + pcnet_reset(lp); /* Wait for Stop bit */ for (i = 1000; i > 0; i--) { - if (pcnet_read_csr(dev, 0) & 0x4) + if (pcnet_read_csr(lp, 0) & 0x4) break; udelay(10); } @@ -498,11 +488,10 @@ int pcnet_initialize(bd_t *bis) * Setup the PCI device. */ pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar); - dev->iobase = pci_mem_to_phys(devbusfn, bar); - dev->iobase &= ~0xf; + lp->iobase = (void *)(pci_mem_to_phys(devbusfn, bar) & ~0xf); - PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", - dev->name, devbusfn, (unsigned long)dev->iobase); + PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%p: ", + dev->name, devbusfn, lp->iobase); command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, command); -- cgit v1.3.1 From 1023a1e6a9b506c318ee9330d90d3acdf5593f89 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 17:04:19 +0200 Subject: net: pcnet: Wrap name and enetaddr into private data Instead of using the non-DM-only name and enetaddr in struct eth_device, add pointers into the private data which can either point to that non-DM name or a DM one later on. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index b0bd4af2039..669b2561789 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -84,6 +84,8 @@ struct pcnet_priv { struct pcnet_uncached_priv *uc; pci_dev_t dev; void __iomem *iobase; + char *name; + u8 *enetaddr; int cur_rx; int cur_tx; }; @@ -153,7 +155,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) /* Check if register access is working */ if (pcnet_read_csr(lp, 0) != 4 || !pcnet_check(lp)) { - printf("%s: CSR register access check failed\n", dev->name); + printf("%s: CSR register access check failed\n", lp->name); return -1; } @@ -174,7 +176,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) break; default: printf("%s: PCnet version %#x not supported\n", - dev->name, chip_version); + lp->name, chip_version); return -1; } @@ -190,8 +192,8 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) val = pcnet_read_csr(lp, i + 12) & 0x0ffff; /* There may be endianness issues here. */ - dev->enetaddr[2 * i] = val & 0x0ff; - dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; + lp->enetaddr[2 * i] = val & 0x0ff; + lp->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; } return 0; @@ -204,7 +206,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) int i, val; unsigned long addr; - PCNET_DEBUG1("%s: pcnet_init...\n", dev->name); + PCNET_DEBUG1("%s: %s...\n", lp->name, __func__); /* Switch pcnet to 32bit mode */ pcnet_write_bcr(lp, 20, 2); @@ -271,7 +273,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) PCNET_DEBUG1("Init block at 0x%p: MAC", &lp->uc->init_block); for (i = 0; i < 6; i++) { - lp->uc->init_block.phys_addr[i] = dev->enetaddr[i]; + lp->uc->init_block.phys_addr[i] = lp->enetaddr[i]; PCNET_DEBUG1(" %02x", lp->uc->init_block.phys_addr[i]); } @@ -304,7 +306,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) udelay(10); } if (i <= 0) { - printf("%s: TIMEOUT: controller init failed\n", dev->name); + printf("%s: TIMEOUT: controller init failed\n", lp->name); pcnet_reset(lp); return -1; } @@ -340,7 +342,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) } if (i <= 0) { printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n", - dev->name, lp->cur_tx, status); + lp->name, lp->cur_tx, status); pkt_len = 0; goto failure; } @@ -385,7 +387,7 @@ static int pcnet_recv (struct eth_device *dev) err_status = status >> 8; if (err_status != 0x03) { /* There was an error. */ - printf("%s: Rx%d", dev->name, lp->cur_rx); + printf("%s: Rx%d", lp->name, lp->cur_rx); PCNET_DEBUG1(" (status=0x%x)", err_status); if (err_status & 0x20) printf(" Frame"); @@ -402,7 +404,7 @@ static int pcnet_recv (struct eth_device *dev) pkt_len = (readl(&entry->msg_length) & 0xfff) - 4; if (pkt_len < 60) { printf("%s: Rx%d: invalid packet length %d\n", - dev->name, lp->cur_rx, pkt_len); + lp->name, lp->cur_rx, pkt_len); } else { buf = lp->rx_buf[lp->cur_rx]; invalidate_dcache_range((unsigned long)buf, @@ -427,7 +429,7 @@ static void pcnet_halt(struct eth_device *dev) struct pcnet_priv *lp = dev->priv; int i; - PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name); + PCNET_DEBUG1("%s: %s...\n", lp->name, __func__); /* Reset the PCnet controller */ pcnet_reset(lp); @@ -439,7 +441,7 @@ static void pcnet_halt(struct eth_device *dev) udelay(10); } if (i <= 0) - printf("%s: TIMEOUT: controller reset failed\n", dev->name); + printf("%s: TIMEOUT: controller reset failed\n", lp->name); } int pcnet_initialize(bd_t *bis) @@ -451,7 +453,7 @@ int pcnet_initialize(bd_t *bis) int dev_nr = 0; u32 bar; - PCNET_DEBUG1("\npcnet_initialize...\n"); + PCNET_DEBUG1("\n%s...\n", __func__); for (dev_nr = 0; ; dev_nr++) { /* @@ -483,6 +485,8 @@ int pcnet_initialize(bd_t *bis) (unsigned long)lp + sizeof(*lp)); dev->priv = lp; sprintf(dev->name, "pcnet#%d", dev_nr); + lp->name = dev->name; + lp->enetaddr = dev->enetaddr; /* * Setup the PCI device. @@ -491,14 +495,14 @@ int pcnet_initialize(bd_t *bis) lp->iobase = (void *)(pci_mem_to_phys(devbusfn, bar) & ~0xf); PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%p: ", - dev->name, devbusfn, lp->iobase); + lp->name, devbusfn, lp->iobase); command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, command); pci_read_config_word(devbusfn, PCI_COMMAND, &status); if ((status & command) != command) { printf("%s: Couldn't enable IO access or Bus Mastering\n", - dev->name); + lp->name); free(dev); continue; } -- cgit v1.3.1 From dea9b6014b2e8a62b615ebe6f8778e5c624076e4 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 17:28:31 +0200 Subject: net: pcnet: Split common and non-DM functions Pull the common parts of functions out so they can be reused by both DM and non-DM code paths. The recv() function had to be reworked to fit into this scheme and this means it now only receives one packet at a time instead of spinning in an endless loop. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 149 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 94 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 669b2561789..0a4cab82087 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -86,6 +86,7 @@ struct pcnet_priv { void __iomem *iobase; char *name; u8 *enetaddr; + u16 status; int cur_rx; int cur_tx; }; @@ -143,9 +144,8 @@ static struct pci_device_id supported[] = { {} }; -static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) +static int pcnet_probe_common(struct pcnet_priv *lp) { - struct pcnet_priv *lp = dev->priv; int chip_version; char *chipname; int i; @@ -199,9 +199,8 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) return 0; } -static int pcnet_init(struct eth_device *dev, bd_t *bis) +static int pcnet_init_common(struct pcnet_priv *lp) { - struct pcnet_priv *lp = dev->priv; struct pcnet_uncached_priv *uc; int i, val; unsigned long addr; @@ -319,9 +318,8 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) return 0; } -static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) +static int pcnet_send_common(struct pcnet_priv *lp, void *packet, int pkt_len) { - struct pcnet_priv *lp = dev->priv; int i, status; u32 addr; struct pcnet_tx_head *entry = &lp->uc->tx_ring[lp->cur_tx]; @@ -368,65 +366,70 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) return pkt_len; } -static int pcnet_recv (struct eth_device *dev) +static int pcnet_recv_common(struct pcnet_priv *lp, unsigned char **bufp) { - struct pcnet_priv *lp = dev->priv; struct pcnet_rx_head *entry; unsigned char *buf; int pkt_len = 0; - u16 status, err_status; + u16 err_status; - while (1) { - entry = &lp->uc->rx_ring[lp->cur_rx]; - /* - * If we own the next entry, it's a new packet. Send it up. - */ - status = readw(&entry->status); - if ((status & 0x8000) != 0) - break; - err_status = status >> 8; - - if (err_status != 0x03) { /* There was an error. */ - printf("%s: Rx%d", lp->name, lp->cur_rx); - PCNET_DEBUG1(" (status=0x%x)", err_status); - if (err_status & 0x20) - printf(" Frame"); - if (err_status & 0x10) - printf(" Overflow"); - if (err_status & 0x08) - printf(" CRC"); - if (err_status & 0x04) - printf(" Fifo"); - printf(" Error\n"); - status &= 0x03ff; - - } else { - pkt_len = (readl(&entry->msg_length) & 0xfff) - 4; - if (pkt_len < 60) { - printf("%s: Rx%d: invalid packet length %d\n", - lp->name, lp->cur_rx, pkt_len); - } else { - buf = lp->rx_buf[lp->cur_rx]; - invalidate_dcache_range((unsigned long)buf, - (unsigned long)buf + pkt_len); - net_process_received_packet(buf, pkt_len); - PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", - lp->cur_rx, pkt_len, buf); - } - } - - status |= 0x8000; - writew(status, &entry->status); + entry = &lp->uc->rx_ring[lp->cur_rx]; + /* + * If we own the next entry, it's a new packet. Send it up. + */ + lp->status = readw(&entry->status); + if ((lp->status & 0x8000) != 0) + return 0; + err_status = lp->status >> 8; + + if (err_status != 0x03) { /* There was an error. */ + printf("%s: Rx%d", lp->name, lp->cur_rx); + PCNET_DEBUG1(" (status=0x%x)", err_status); + if (err_status & 0x20) + printf(" Frame"); + if (err_status & 0x10) + printf(" Overflow"); + if (err_status & 0x08) + printf(" CRC"); + if (err_status & 0x04) + printf(" Fifo"); + printf(" Error\n"); + lp->status &= 0x03ff; + return 0; + } - if (++lp->cur_rx >= RX_RING_SIZE) - lp->cur_rx = 0; + pkt_len = (readl(&entry->msg_length) & 0xfff) - 4; + if (pkt_len < 60) { + printf("%s: Rx%d: invalid packet length %d\n", + lp->name, lp->cur_rx, pkt_len); + return 0; } + + *bufp = lp->rx_buf[lp->cur_rx]; + invalidate_dcache_range((unsigned long)*bufp, + (unsigned long)*bufp + pkt_len); + + PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", + lp->cur_rx, pkt_len, buf); + return pkt_len; } -static void pcnet_halt(struct eth_device *dev) +static void pcnet_free_pkt_common(struct pcnet_priv *lp, unsigned int len) +{ + struct pcnet_rx_head *entry; + + entry = &lp->uc->rx_ring[lp->cur_rx]; + + lp->status |= 0x8000; + writew(lp->status, &entry->status); + + if (++lp->cur_rx >= RX_RING_SIZE) + lp->cur_rx = 0; +} + +static void pcnet_halt_common(struct pcnet_priv *lp) { - struct pcnet_priv *lp = dev->priv; int i; PCNET_DEBUG1("%s: %s...\n", lp->name, __func__); @@ -444,6 +447,42 @@ static void pcnet_halt(struct eth_device *dev) printf("%s: TIMEOUT: controller reset failed\n", lp->name); } +static int pcnet_init(struct eth_device *dev, bd_t *bis) +{ + struct pcnet_priv *lp = dev->priv; + + return pcnet_init_common(lp); +} + +static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) +{ + struct pcnet_priv *lp = dev->priv; + + return pcnet_send_common(lp, packet, pkt_len); +} + +static int pcnet_recv(struct eth_device *dev) +{ + struct pcnet_priv *lp = dev->priv; + uchar *packet; + int ret; + + ret = pcnet_recv_common(lp, &packet); + if (ret > 0) + net_process_received_packet(packet, ret); + if (ret) + pcnet_free_pkt_common(lp, ret); + + return ret; +} + +static void pcnet_halt(struct eth_device *dev) +{ + struct pcnet_priv *lp = dev->priv; + + pcnet_halt_common(lp); +} + int pcnet_initialize(bd_t *bis) { pci_dev_t devbusfn; @@ -512,7 +551,7 @@ int pcnet_initialize(bd_t *bis) /* * Probe the PCnet chip. */ - if (pcnet_probe(dev, bis, dev_nr) < 0) { + if (pcnet_probe_common(lp) < 0) { free(dev); continue; } -- cgit v1.3.1 From 59edb2668eabf51c8587a786af9eca95e3294806 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 17:43:22 +0200 Subject: net: pcnet: Add DM support With all the changes in place, add support for DM into the pcnet driver. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 0a4cab82087..d9ab37b3366 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -82,9 +83,14 @@ struct pcnet_priv { /* Receive Buffer space */ unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; struct pcnet_uncached_priv *uc; +#ifdef CONFIG_DM_ETH + struct udevice *dev; + const char *name; +#else pci_dev_t dev; - void __iomem *iobase; char *name; +#endif + void __iomem *iobase; u8 *enetaddr; u16 status; int cur_rx; @@ -136,7 +142,11 @@ static inline pci_addr_t pcnet_virt_to_mem(struct pcnet_priv *lp, void *addr) { void *virt_addr = addr; +#ifdef CONFIG_DM_ETH + return dm_pci_virt_to_mem(lp->dev, virt_addr); +#else return pci_virt_to_mem(lp->dev, virt_addr); +#endif } static struct pci_device_id supported[] = { @@ -447,6 +457,7 @@ static void pcnet_halt_common(struct pcnet_priv *lp) printf("%s: TIMEOUT: controller reset failed\n", lp->name); } +#ifndef CONFIG_DM_ETH static int pcnet_init(struct eth_device *dev, bd_t *bis) { struct pcnet_priv *lp = dev->priv; @@ -571,3 +582,117 @@ int pcnet_initialize(bd_t *bis) return dev_nr; } +#else /* DM_ETH */ +static int pcnet_start(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct pcnet_priv *priv = dev_get_priv(dev); + + memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr)); + + return pcnet_init_common(priv); +} + +static void pcnet_stop(struct udevice *dev) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + + pcnet_halt_common(priv); +} + +static int pcnet_send(struct udevice *dev, void *packet, int length) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + int ret; + + ret = pcnet_send_common(priv, packet, length); + + return ret ? 0 : -ETIMEDOUT; +} + +static int pcnet_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + + return pcnet_recv_common(priv, packetp); +} + +static int pcnet_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + + pcnet_free_pkt_common(priv, length); + + return 0; +} + +static int pcnet_bind(struct udevice *dev) +{ + static int card_number; + char name[16]; + + sprintf(name, "pcnet#%u", card_number++); + + return device_set_name(dev, name); +} + +static int pcnet_probe(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct pcnet_priv *lp = dev_get_priv(dev); + u16 command, status; + u32 iobase; + int ret; + + dm_pci_read_config32(dev, PCI_BASE_ADDRESS_1, &iobase); + iobase &= ~0xf; + + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + lp->dev = dev; + lp->name = dev->name; + lp->enetaddr = plat->enetaddr; + lp->iobase = (void *)dm_pci_mem_to_phys(dev, iobase); + + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + + command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + dm_pci_write_config16(dev, PCI_COMMAND, command); + dm_pci_read_config16(dev, PCI_COMMAND, &status); + if ((status & command) != command) { + printf("%s: Couldn't enable IO access or Bus Mastering\n", + lp->name); + return -EINVAL; + } + + dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x20); + + ret = pcnet_probe_common(lp); + if (ret) + return ret; + + return 0; +} + +static const struct eth_ops pcnet_ops = { + .start = pcnet_start, + .send = pcnet_send, + .recv = pcnet_recv, + .stop = pcnet_stop, + .free_pkt = pcnet_free_pkt, +}; + +U_BOOT_DRIVER(eth_pcnet) = { + .name = "eth_pcnet", + .id = UCLASS_ETH, + .bind = pcnet_bind, + .probe = pcnet_probe, + .ops = &pcnet_ops, + .priv_auto_alloc_size = sizeof(struct pcnet_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .flags = DM_UC_FLAG_ALLOC_PRIV_DMA, +}; + +U_BOOT_PCI_DEVICE(eth_pcnet, supported); +#endif -- cgit v1.3.1 From d789a8259e3b3b77e3eb2b090373ab2cbc225629 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:14:17 +0200 Subject: net: pcnet: Add Kconfig entries Add Kconfig entries for the pcnet driver and convert MIPS malta to use those. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- configs/malta64_defconfig | 1 + configs/malta64el_defconfig | 1 + configs/malta_defconfig | 1 + configs/maltael_defconfig | 1 + drivers/net/Kconfig | 6 ++++++ include/configs/malta.h | 1 - 6 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/configs/malta64_defconfig b/configs/malta64_defconfig index e5a19a6e546..a16abc7fa9c 100644 --- a/configs/malta64_defconfig +++ b/configs/malta64_defconfig @@ -27,6 +27,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/configs/malta64el_defconfig b/configs/malta64el_defconfig index e9de5bea6e1..a9efe7736e5 100644 --- a/configs/malta64el_defconfig +++ b/configs/malta64el_defconfig @@ -28,6 +28,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/configs/malta_defconfig b/configs/malta_defconfig index 2b43818c81f..0680f595dbd 100644 --- a/configs/malta_defconfig +++ b/configs/malta_defconfig @@ -26,6 +26,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/configs/maltael_defconfig b/configs/maltael_defconfig index ec984b5a356..31c9ff6a777 100644 --- a/configs/maltael_defconfig +++ b/configs/maltael_defconfig @@ -27,6 +27,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index ed07a78044e..1566b3bda13 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -398,6 +398,12 @@ config MII help Enable support of the Media-Independent Interface (MII) +config PCNET + bool "AMD PCnet series Ethernet controller driver" + help + This driver supports AMD PCnet series fast ethernet family of + PCI chipsets/adapters. + config RTL8139 bool "Realtek 8139 series Ethernet controller driver" help diff --git a/include/configs/malta.h b/include/configs/malta.h index 82c90042d98..9602773ff91 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -15,7 +15,6 @@ #define CONFIG_PCI_GT64120 #define CONFIG_PCI_MSC01 -#define CONFIG_PCNET #define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0 -- cgit v1.3.1 From fb3dd9c005045c2748e30d555d252c6985b97349 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 26 May 2020 09:38:17 +0200 Subject: video: ipuv3: remove non-DM code All ipuv3 users have been converted, drop obsolete code. Signed-off-by: Anatolij Gustschin --- drivers/video/imx/Kconfig | 2 +- drivers/video/imx/mxc_ipuv3_fb.c | 43 ---------------------------------------- 2 files changed, 1 insertion(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/video/imx/Kconfig b/drivers/video/imx/Kconfig index c33620e0750..78eb0f29fb3 100644 --- a/drivers/video/imx/Kconfig +++ b/drivers/video/imx/Kconfig @@ -1,7 +1,7 @@ config VIDEO_IPUV3 bool "i.MX IPUv3 Core video support" - depends on (VIDEO || DM_VIDEO) && (MX5 || MX6) + depends on DM_VIDEO && (MX5 || MX6) help This enables framebuffer driver for i.MX processors working on the IPUv3(Image Processing Unit) internal graphic processor. diff --git a/drivers/video/imx/mxc_ipuv3_fb.c b/drivers/video/imx/mxc_ipuv3_fb.c index 6787201bf55..587d62f2d86 100644 --- a/drivers/video/imx/mxc_ipuv3_fb.c +++ b/drivers/video/imx/mxc_ipuv3_fb.c @@ -38,10 +38,6 @@ DECLARE_GLOBAL_DATA_PTR; static int mxcfb_map_video_memory(struct fb_info *fbi); static int mxcfb_unmap_video_memory(struct fb_info *fbi); -#if !CONFIG_IS_ENABLED(DM_VIDEO) -/* graphics setup */ -static GraphicDevice panel; -#endif static struct fb_videomode const *gmode; static uint8_t gdisp; static uint32_t gpixfmt; @@ -391,12 +387,7 @@ static int mxcfb_map_video_memory(struct fb_info *fbi) } fbi->fix.smem_len = roundup(fbi->fix.smem_len, ARCH_DMA_MINALIGN); -#if CONFIG_IS_ENABLED(DM_VIDEO) fbi->screen_base = (char *)gd->video_bottom; -#else - fbi->screen_base = (char *)memalign(ARCH_DMA_MINALIGN, - fbi->fix.smem_len); -#endif fbi->fix.smem_start = (unsigned long)fbi->screen_base; if (fbi->screen_base == 0) { @@ -410,10 +401,7 @@ static int mxcfb_map_video_memory(struct fb_info *fbi) (uint32_t) fbi->fix.smem_start, fbi->fix.smem_len); fbi->screen_size = fbi->fix.smem_len; - -#if CONFIG_IS_ENABLED(VIDEO) gd->fb_base = fbi->fix.smem_start; -#endif /* Clear the screen */ memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); @@ -544,18 +532,6 @@ static int mxcfb_probe(u32 interface_pix_fmt, uint8_t disp, mxcfb_set_par(fbi); -#if !CONFIG_IS_ENABLED(DM_VIDEO) - panel.winSizeX = mode->xres; - panel.winSizeY = mode->yres; - panel.plnSizeX = mode->xres; - panel.plnSizeY = mode->yres; - - panel.frameAdrs = (u32)fbi->screen_base; - panel.memSize = fbi->screen_size; - - panel.gdfBytesPP = 2; - panel.gdfIndex = GDF_16BIT_565RGB; -#endif #ifdef DEBUG ipu_dump_registers(); #endif @@ -585,23 +561,6 @@ void ipuv3_fb_shutdown(void) } } -#if !CONFIG_IS_ENABLED(DM_VIDEO) -void *video_hw_init(void) -{ - int ret; - - ret = ipu_probe(); - if (ret) - puts("Error initializing IPU\n"); - - ret = mxcfb_probe(gpixfmt, gdisp, gmode); - debug("Framebuffer at 0x%x\n", (unsigned int)panel.frameAdrs); - gd->fb_base = panel.frameAdrs; - - return (void *)&panel; -} -#endif - int ipuv3_fb_init(struct fb_videomode const *mode, uint8_t disp, uint32_t pixfmt) @@ -613,7 +572,6 @@ int ipuv3_fb_init(struct fb_videomode const *mode, return 0; } -#if CONFIG_IS_ENABLED(DM_VIDEO) enum { /* Maximum display size we support */ LCD_MAX_WIDTH = 1920, @@ -711,4 +669,3 @@ U_BOOT_DRIVER(ipuv3_video) = { .priv_auto_alloc_size = sizeof(struct ipuv3_video_priv), .flags = DM_FLAG_PRE_RELOC, }; -#endif /* CONFIG_DM_VIDEO */ -- cgit v1.3.1 From aeb3c386c81017657f4faef34d5c203fe32d3aeb Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 16 Apr 2020 14:48:44 +0200 Subject: mmc: zynq_sdhci: Remove global pointer Driver is not calling gd anywhere that's why there is not need to define it. Signed-off-by: Michal Simek --- drivers/mmc/zynq_sdhci.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index de404aa9560..43b9f215229 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -19,8 +19,6 @@ #include #include -DECLARE_GLOBAL_DATA_PTR; - struct arasan_sdhci_plat { struct mmc_config cfg; struct mmc mmc; -- cgit v1.3.1 From 2b2012d1c1d8515417ba139339d0aa9b47789dca Mon Sep 17 00:00:00 2001 From: Rajan Vaja Date: Mon, 4 May 2020 22:53:56 -0700 Subject: clk: versal: Remove alt_ref_clk from clock sources alt_ref_clk is applicable only for PS extended version. For PS base version there is no separate alt_ref_clk. It is tied with ref_clk, so remove it from driver. Signed-off-by: Rajan Vaja Signed-off-by: Michal Simek --- drivers/clk/clk_versal.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk_versal.c b/drivers/clk/clk_versal.c index 2fb3171d71f..6f82b60f04d 100644 --- a/drivers/clk/clk_versal.c +++ b/drivers/clk/clk_versal.c @@ -117,7 +117,6 @@ struct versal_clk_priv { struct versal_clock *clk; }; -static ulong alt_ref_clk; static ulong pl_alt_ref_clk; static ulong ref_clk; @@ -548,8 +547,7 @@ int soc_clk_dump(void) printf("\n ****** VERSAL CLOCKS *****\n"); - printf("alt_ref_clk:%ld pl_alt_ref_clk:%ld ref_clk:%ld\n", - alt_ref_clk, pl_alt_ref_clk, ref_clk); + printf("pl_alt_ref_clk:%ld ref_clk:%ld\n", pl_alt_ref_clk, ref_clk); for (i = 0; i < clock_max_idx; i++) { debug("%s\n", clock[i].clk_name); ret = versal_get_clock_type(i, &type); @@ -667,10 +665,6 @@ static int versal_clk_probe(struct udevice *dev) debug("%s\n", __func__); - ret = versal_clock_get_freq_by_name("alt_ref_clk", dev, &alt_ref_clk); - if (ret < 0) - return -EINVAL; - ret = versal_clock_get_freq_by_name("pl_alt_ref_clk", dev, &pl_alt_ref_clk); if (ret < 0) -- cgit v1.3.1 From 4c86e0834aeb3ae06389534ccbc90b8bcf5d95bf Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 27 Apr 2020 11:51:40 +0200 Subject: firmware: zynqmp: Change panic logic in zynqmp_pmufw_load_config_object() There is no need to panic all the time when pmufw config object loading failed. The patch improves function logic to report permission deny case and also panic only for SPL case. Signed-off-by: Michal Simek Reviewed-by: Luca Ceresoli --- drivers/firmware/firmware-zynqmp.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 2bdf7771f64..66edc169301 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -18,6 +18,8 @@ #define PMUFW_PAYLOAD_ARG_CNT 8 +#define XST_PM_NO_ACCESS 2002L + struct zynqmp_power { struct mbox_chan tx_chan; struct mbox_chan rx_chan; @@ -99,16 +101,25 @@ void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) PM_SET_CONFIGURATION, (u32)((u64)cfg_obj) }; - u32 response; + u32 response = 0; int err; printf("Loading new PMUFW cfg obj (%ld bytes)\n", size); err = send_req(request, ARRAY_SIZE(request), &response, 1); + if (err == XST_PM_NO_ACCESS) { + printf("PMUFW no permission to change config object\n"); + return; + } + if (err) - panic("Cannot load PMUFW configuration object (%d)\n", err); - if (response != 0) - panic("PMUFW returned 0x%08x status!\n", response); + printf("Cannot load PMUFW configuration object (%d)\n", err); + + if (response) + printf("PMUFW returned 0x%08x status!\n", response); + + if ((err || response) && IS_ENABLED(CONFIG_SPL_BUILD)) + panic("PMUFW config object loading failed in EL3\n"); } static int zynqmp_power_probe(struct udevice *dev) -- cgit v1.3.1 From 3427f4d2045729c8995b19407daf91ea9a50e4f8 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Wed, 9 Dec 2015 18:46:43 +0530 Subject: fpga: zynqpl: Correct PL bitstream loading sequence for zynqaes Correct the PL bitstream loading sequence for zynqaes command by clearing the loaded PL bitstream before loading the new encrypted bitstream using the zynq aes command. This was done by setting the PROG_B same as in case of fpgaload commands. This patch fixes the issue of loading the encrypted PL bitstream onto the PL in which a bitstream has already been loaded successfully. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- board/xilinx/zynq/cmds.c | 7 +++++-- drivers/fpga/zynqpl.c | 7 ++++--- include/zynqpl.h | 3 ++- 3 files changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/board/xilinx/zynq/cmds.c b/board/xilinx/zynq/cmds.c index 0c46de7599c..d5e7d70bdf5 100644 --- a/board/xilinx/zynq/cmds.c +++ b/board/xilinx/zynq/cmds.c @@ -399,7 +399,8 @@ static int zynq_verify_image(u32 src_ptr) status = zynq_decrypt_load(part_load_addr, part_img_len, part_dst_addr, - part_data_len); + part_data_len, + BIT_NONE); if (status != 0) { printf("DECRYPTION_FAIL\n"); return -1; @@ -438,6 +439,7 @@ static int zynq_decrypt_image(struct cmd_tbl *cmdtp, int flag, int argc, char *endp; u32 srcaddr, srclen, dstaddr, dstlen; int status; + u8 imgtype = BIT_NONE; if (argc < 5 && argc > cmdtp->maxargs) return CMD_RET_USAGE; @@ -464,7 +466,8 @@ static int zynq_decrypt_image(struct cmd_tbl *cmdtp, int flag, int argc, if (dstlen % 4) dstlen = roundup(dstlen, 4); - status = zynq_decrypt_load(srcaddr, srclen >> 2, dstaddr, dstlen >> 2); + status = zynq_decrypt_load(srcaddr, srclen >> 2, dstaddr, + dstlen >> 2, imgtype); if (status != 0) return CMD_RET_FAILURE; diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index dcfe513eeb3..4ab354bbba4 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -204,7 +204,7 @@ static int zynq_dma_xfer_init(bitstream_type bstype) /* Clear loopback bit */ clrbits_le32(&devcfg_base->mctrl, DEVCFG_MCTRL_PCAP_LPBK); - if (bstype != BIT_PARTIAL) { + if (bstype != BIT_PARTIAL && bstype != BIT_NONE) { zynq_slcr_devcfg_disable(); /* Setting PCFG_PROG_B signal to high */ @@ -511,7 +511,8 @@ struct xilinx_fpga_op zynq_op = { * Load the encrypted image from src addr and decrypt the image and * place it back the decrypted image into dstaddr. */ -int zynq_decrypt_load(u32 srcaddr, u32 srclen, u32 dstaddr, u32 dstlen) +int zynq_decrypt_load(u32 srcaddr, u32 srclen, u32 dstaddr, u32 dstlen, + u8 bstype) { if (srcaddr < SZ_1M || dstaddr < SZ_1M) { printf("%s: src and dst addr should be > 1M\n", @@ -519,7 +520,7 @@ int zynq_decrypt_load(u32 srcaddr, u32 srclen, u32 dstaddr, u32 dstlen) return FPGA_FAIL; } - if (zynq_dma_xfer_init(BIT_NONE)) { + if (zynq_dma_xfer_init(bstype)) { printf("%s: zynq_dma_xfer_init FAIL\n", __func__); return FPGA_FAIL; } diff --git a/include/zynqpl.h b/include/zynqpl.h index 766e6918cd3..d7dc064585e 100644 --- a/include/zynqpl.h +++ b/include/zynqpl.h @@ -12,7 +12,8 @@ #include #ifdef CONFIG_CMD_ZYNQ_AES -int zynq_decrypt_load(u32 srcaddr, u32 dstaddr, u32 srclen, u32 dstlen); +int zynq_decrypt_load(u32 srcaddr, u32 dstaddr, u32 srclen, u32 dstlen, + u8 bstype); #endif extern struct xilinx_fpga_op zynq_op; -- cgit v1.3.1 From 1d9632a3ccca00638ace1ff6bbce7eba1e15aac7 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Tue, 12 Mar 2019 20:20:20 +0530 Subject: fpga: zynqpl: Check fpga config completion This patch checks fpga config completion when a bitstream is loaded into PL. Signed-off-by: T Karthik Reddy Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- drivers/fpga/zynqpl.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index 4ab354bbba4..de71969399f 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -514,6 +514,8 @@ struct xilinx_fpga_op zynq_op = { int zynq_decrypt_load(u32 srcaddr, u32 srclen, u32 dstaddr, u32 dstlen, u8 bstype) { + u32 isr_status, ts; + if (srcaddr < SZ_1M || dstaddr < SZ_1M) { printf("%s: src and dst addr should be > 1M\n", __func__); @@ -544,8 +546,21 @@ int zynq_decrypt_load(u32 srcaddr, u32 srclen, u32 dstaddr, u32 dstlen, if (zynq_dma_transfer(srcaddr | 1, srclen, dstaddr | 1, dstlen)) return FPGA_FAIL; - writel((readl(&devcfg_base->ctrl) & ~DEVCFG_CTRL_PCAP_RATE_EN_MASK), - &devcfg_base->ctrl); + if (bstype == BIT_FULL) { + isr_status = readl(&devcfg_base->int_sts); + /* Check FPGA configuration completion */ + ts = get_timer(0); + while (!(isr_status & DEVCFG_ISR_PCFG_DONE)) { + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { + printf("%s: Timeout wait for FPGA to config\n", + __func__); + return FPGA_FAIL; + } + isr_status = readl(&devcfg_base->int_sts); + } + printf("%s: FPGA config done\n", __func__); + zynq_slcr_devcfg_enable(); + } return FPGA_SUCCESS; } -- cgit v1.3.1 From c64afba2fb483d416ad5da9dfe3f1f156ccf2366 Mon Sep 17 00:00:00 2001 From: Ibai Erkiaga Date: Thu, 5 Apr 2018 05:19:27 -0700 Subject: fpga: zynqpl: Check if aes engine is enabled AES engine cannot be used if has not been enabled at boot time with an encrypted boot image. Signed-off-by: Ibai Erkiaga Acked-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- drivers/fpga/zynqpl.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index de71969399f..90bb8508331 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -22,6 +22,7 @@ #define DEVCFG_CTRL_PCFG_PROG_B 0x40000000 #define DEVCFG_CTRL_PCFG_AES_EFUSE_MASK 0x00001000 #define DEVCFG_CTRL_PCAP_RATE_EN_MASK 0x02000000 +#define DEVCFG_CTRL_PCFG_AES_EN_MASK 0x00000E00 #define DEVCFG_ISR_FATAL_ERROR_MASK 0x00740040 #define DEVCFG_ISR_ERROR_FLAGS_MASK 0x00340840 #define DEVCFG_ISR_RX_FIFO_OV 0x00040000 @@ -522,6 +523,13 @@ int zynq_decrypt_load(u32 srcaddr, u32 srclen, u32 dstaddr, u32 dstlen, return FPGA_FAIL; } + /* Check AES engine is enabled */ + if (!(readl(&devcfg_base->ctrl) & + DEVCFG_CTRL_PCFG_AES_EN_MASK)) { + printf("%s: AES engine is not enabled\n", __func__); + return FPGA_FAIL; + } + if (zynq_dma_xfer_init(bstype)) { printf("%s: zynq_dma_xfer_init FAIL\n", __func__); return FPGA_FAIL; -- cgit v1.3.1 From ca0c0e07adf3c3baf3851fc17490a0160398c834 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Tue, 12 Mar 2019 20:20:23 +0530 Subject: fpga: zynqpl: Flush dcache only for non-bitstream data In case of aes decryption destination address range must be flushed before transferring decrypted data to destination. Signed-off-by: T Karthik Reddy Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- drivers/fpga/zynqpl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index 90bb8508331..a11e4855253 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -548,8 +548,9 @@ int zynq_decrypt_load(u32 srcaddr, u32 srclen, u32 dstaddr, u32 dstlen, * Flush destination address range only if image is not * bitstream. */ - flush_dcache_range((u32)dstaddr, (u32)dstaddr + - roundup(dstlen << 2, ARCH_DMA_MINALIGN)); + if (bstype == BIT_NONE && dstaddr != 0xFFFFFFFF) + flush_dcache_range((u32)dstaddr, (u32)dstaddr + + roundup(dstlen << 2, ARCH_DMA_MINALIGN)); if (zynq_dma_transfer(srcaddr | 1, srclen, dstaddr | 1, dstlen)) return FPGA_FAIL; -- cgit v1.3.1 From 26e62cc9713ebe728d01826e8c22c3c56f8e3bf4 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 13 May 2020 08:05:01 -0600 Subject: net: gem: Disable PCS autonegotiation in case of fixed-link Disable PCS autonegotiation if fixed-link node is present in device tree. This way systems with multiple GEM instances with a combination of SGMII-fixed and SGMII-PHY will work. Reported-by: Goran Marinkovic Signed-off-by: Michal Simek Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek --- drivers/net/zynq_gem.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 412daf7d58b..da4b6fba9ff 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -451,8 +451,12 @@ static int zynq_gem_init(struct udevice *dev) nwconfig |= ZYNQ_GEM_NWCFG_SGMII_ENBL | ZYNQ_GEM_NWCFG_PCS_SEL; #ifdef CONFIG_ARM64 + if (priv->phydev->phy_id != PHY_FIXED_ID) writel(readl(®s->pcscntrl) | ZYNQ_GEM_PCS_CTL_ANEG_ENBL, ®s->pcscntrl); + else + writel(readl(®s->pcscntrl) & ~ZYNQ_GEM_PCS_CTL_ANEG_ENBL, + ®s->pcscntrl); #endif } -- cgit v1.3.1 From f44bd3bcfd91cd7b1be709c9cfb0824e6a71b9b0 Mon Sep 17 00:00:00 2001 From: Ashok Reddy Soma Date: Mon, 18 May 2020 01:11:00 -0600 Subject: spi: zynq_[q]spi: Convert config's to macro's Remove below config options and convert them to macros. They have never been configured to different values than default one. And also it makes sense to reduce the config_whitelist. CONFIG_SYS_ZYNQ_SPI_WAIT CONFIG_SYS_ZYNQ_QSPI_WAIT CONFIG_XILINX_SPI_IDLE_VAL Signed-off-by: Ashok Reddy Soma Signed-off-by: Michal Simek --- drivers/spi/xilinx_spi.c | 6 ++---- drivers/spi/zynq_qspi.c | 6 ++---- drivers/spi/zynq_spi.c | 6 ++---- scripts/config_whitelist.txt | 3 --- 4 files changed, 6 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 05768eef721..348630faf38 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -76,9 +76,7 @@ SPICR_SPE) #define XILSPI_SPICR_DFLT_OFF (SPICR_MASTER_INHIBIT | SPICR_MANUAL_SS) -#ifndef CONFIG_XILINX_SPI_IDLE_VAL -#define CONFIG_XILINX_SPI_IDLE_VAL GENMASK(7, 0) -#endif +#define XILINX_SPI_IDLE_VAL GENMASK(7, 0) #define XILINX_SPISR_TIMEOUT 10000 /* in milliseconds */ @@ -176,7 +174,7 @@ static u32 xilinx_spi_fill_txfifo(struct udevice *bus, const u8 *txp, while (txbytes && !(readl(®s->spisr) & SPISR_TX_FULL) && i < priv->fifo_depth) { - d = txp ? *txp++ : CONFIG_XILINX_SPI_IDLE_VAL; + d = txp ? *txp++ : XILINX_SPI_IDLE_VAL; debug("spi_xfer: tx:%x ", d); /* write out and wait for processing (receive data) */ writel(d & SPIDTR_8BIT_MASK, ®s->spidtr); diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index db473da6ea8..3f39ef05f2d 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -47,9 +47,7 @@ DECLARE_GLOBAL_DATA_PTR; #define ZYNQ_QSPI_CR_SS_SHIFT 10 /* Slave select shift */ #define ZYNQ_QSPI_FIFO_DEPTH 63 -#ifndef CONFIG_SYS_ZYNQ_QSPI_WAIT -#define CONFIG_SYS_ZYNQ_QSPI_WAIT CONFIG_SYS_HZ/100 /* 10 ms */ -#endif +#define ZYNQ_QSPI_WAIT (CONFIG_SYS_HZ / 100) /* 10 ms */ /* zynq qspi register set */ struct zynq_qspi_regs { @@ -350,7 +348,7 @@ static int zynq_qspi_irq_poll(struct zynq_qspi_priv *priv) do { status = readl(®s->isr); } while ((status == 0) && - (get_timer(timeout) < CONFIG_SYS_ZYNQ_QSPI_WAIT)); + (get_timer(timeout) < ZYNQ_QSPI_WAIT)); if (status == 0) { printf("zynq_qspi_irq_poll: Timeout!\n"); diff --git a/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c index 3e66b34ebbb..78ffd3e2fe0 100644 --- a/drivers/spi/zynq_spi.c +++ b/drivers/spi/zynq_spi.c @@ -36,9 +36,7 @@ DECLARE_GLOBAL_DATA_PTR; #define ZYNQ_SPI_CR_SS_SHIFT 10 /* Slave select shift */ #define ZYNQ_SPI_FIFO_DEPTH 128 -#ifndef CONFIG_SYS_ZYNQ_SPI_WAIT -#define CONFIG_SYS_ZYNQ_SPI_WAIT (CONFIG_SYS_HZ/100) /* 10 ms */ -#endif +#define ZYNQ_SPI_WAIT (CONFIG_SYS_HZ / 100) /* 10 ms */ /* zynq spi register set */ struct zynq_spi_regs { @@ -251,7 +249,7 @@ static int zynq_spi_xfer(struct udevice *dev, unsigned int bitlen, ts = get_timer(0); status = readl(®s->isr); while (!(status & ZYNQ_SPI_IXR_TXOW_MASK)) { - if (get_timer(ts) > CONFIG_SYS_ZYNQ_SPI_WAIT) { + if (get_timer(ts) > ZYNQ_SPI_WAIT) { printf("spi_xfer: Timeout! TX FIFO not full\n"); return -1; } diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 916768f361d..b023806efc2 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -3984,8 +3984,6 @@ CONFIG_SYS_XHCI_USB1_ADDR CONFIG_SYS_XHCI_USB2_ADDR CONFIG_SYS_XHCI_USB3_ADDR CONFIG_SYS_XIMG_LEN -CONFIG_SYS_ZYNQ_QSPI_WAIT -CONFIG_SYS_ZYNQ_SPI_WAIT CONFIG_SYS_i2C_FSL CONFIG_TAM3517_SETTINGS CONFIG_TCA642X @@ -4211,7 +4209,6 @@ CONFIG_X86_MRC_ADDR CONFIG_X86_REFCODE_ADDR CONFIG_X86_REFCODE_RUN_ADDR CONFIG_XGI_XG22_BASE -CONFIG_XILINX_SPI_IDLE_VAL CONFIG_XSENGINE CONFIG_XTFPGA CONFIG_YAFFSFS_PROVIDE_VALUES -- cgit v1.3.1 From 33d3f8e57754f9b498fa7c14408f2bc20be43900 Mon Sep 17 00:00:00 2001 From: T Karthik Reddy Date: Thu, 14 May 2020 07:49:36 -0600 Subject: arm64: xilinx: Print fpga error value in hex Fpga returns error value when fails, error status should be printed in hex format. Signed-off-by: T Karthik Reddy Signed-off-by: Michal Simek --- drivers/fpga/versalpl.c | 2 +- drivers/fpga/zynqmppl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/fpga/versalpl.c b/drivers/fpga/versalpl.c index b96519e1a46..8e2ef4f0da9 100644 --- a/drivers/fpga/versalpl.c +++ b/drivers/fpga/versalpl.c @@ -45,7 +45,7 @@ static int versal_load(xilinx_desc *desc, const void *buf, size_t bsize, ret = xilinx_pm_request(VERSAL_PM_LOAD_PDI, VERSAL_PM_PDI_TYPE, buf_lo, buf_hi, 0, ret_payload); if (ret) - puts("PL FPGA LOAD fail\n"); + printf("PL FPGA LOAD failed with err: 0x%08x\n", ret); return ret; } diff --git a/drivers/fpga/zynqmppl.c b/drivers/fpga/zynqmppl.c index 2ac4e389521..5b103cfeaf1 100644 --- a/drivers/fpga/zynqmppl.c +++ b/drivers/fpga/zynqmppl.c @@ -239,7 +239,7 @@ static int zynqmp_load(xilinx_desc *desc, const void *buf, size_t bsize, buf_hi, (u32)bsize, 0, ret_payload); if (ret) - puts("PL FPGA LOAD fail\n"); + printf("PL FPGA LOAD failed with err: 0x%08x\n", ret); return ret; } -- cgit v1.3.1 From 945a55050dbd2e916724c2db0ac7eb6c3e29518e Mon Sep 17 00:00:00 2001 From: Patrick van Gelder Date: Wed, 3 Jun 2020 14:18:04 +0200 Subject: net: xilinx: axi_emac: Fix endless loop when no PHYs are connected The index used to iterate over the possible PHYs in axiemac_phy_init was an unsigned int and decremented. Therefor it was always >= 0 and never exited the loop. Signed-off-by: Patrick van Gelder Signed-off-by: Michal Simek --- drivers/net/xilinx_axi_emac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index d0683db80d8..2cd55967684 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -244,7 +244,8 @@ static u32 phywrite(struct axidma_priv *priv, u32 phyaddress, u32 registernum, static int axiemac_phy_init(struct udevice *dev) { u16 phyreg; - u32 i, ret; + int i; + u32 ret; struct axidma_priv *priv = dev_get_priv(dev); struct axi_regs *regs = priv->iobase; struct phy_device *phydev; -- cgit v1.3.1 From aef43ea0606deefc97ed085b16618f18a911cdb5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 10 May 2020 14:17:01 -0600 Subject: bdinfo: dm: Update fb_base when using driver model Update this value with the address of a video device so that it shows with the 'bd' command. It would be better to obtain the address from the uclass by looking in struct video_uc_platdata for each device. We can move over to that once DM_VIDEO migration is complete. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/video/video-uclass.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index bf396d10918..1f2874554a3 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -84,6 +84,7 @@ int video_reserve(ulong *addrp) __func__, size, *addrp, dev->name); } gd->video_bottom = *addrp; + gd->fb_base = *addrp; debug("Video frame buffers from %lx to %lx\n", gd->video_bottom, gd->video_top); -- cgit v1.3.1 From 0735ac85224a8b518eec6792bac116781dc67aac Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 16 Jun 2020 19:06:01 -0400 Subject: Convert CONFIG_AM335X_LCD to Kconfig This converts the following to Kconfig: CONFIG_AM335X_LCD Signed-off-by: Tom Rini --- configs/brxre1_defconfig | 1 + drivers/video/Kconfig | 1 - include/configs/brxre1.h | 3 --- 3 files changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/configs/brxre1_defconfig b/configs/brxre1_defconfig index 5d3246ac8c7..456e4507c8c 100644 --- a/configs/brxre1_defconfig +++ b/configs/brxre1_defconfig @@ -89,6 +89,7 @@ CONFIG_USB_MUSB_TI=y CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=y CONFIG_SYS_WHITE_ON_BLACK=y +CONFIG_AM335X_LCD=y CONFIG_LCD=y CONFIG_SPL_TINY_MEMSET=y # CONFIG_OF_LIBFDT_OVERLAY is not set diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 01e8dbf678b..f5f3f28f23a 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -508,7 +508,6 @@ config ATMEL_HLCD config AM335X_LCD bool "Enable AM335x video support" - depends on DM_VIDEO help Supports video output to an attached LCD panel. diff --git a/include/configs/brxre1.h b/include/configs/brxre1.h index 9db011358eb..3a18aec5d33 100644 --- a/include/configs/brxre1.h +++ b/include/configs/brxre1.h @@ -15,9 +15,6 @@ #include #include /* ------------------------------------------------------------------------- */ -#if !defined(CONFIG_AM335X_LCD) -#define CONFIG_AM335X_LCD -#endif #define LCD_BPP LCD_COLOR32 /* memory */ -- cgit v1.3.1 From b40fa972863701dc554e2a4825c048bfc5a8d709 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 16 Jun 2020 19:06:03 -0400 Subject: Convert CONFIG_ARM_PL180_MMCI to Kconfig This converts the following to Kconfig: CONFIG_ARM_PL180_MMCI Signed-off-by: Tom Rini --- configs/vexpress_ca15_tc2_defconfig | 1 + configs/vexpress_ca5x2_defconfig | 1 + configs/vexpress_ca9x4_defconfig | 1 + drivers/mmc/Kconfig | 1 - include/configs/vexpress_common.h | 1 - 5 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/configs/vexpress_ca15_tc2_defconfig b/configs/vexpress_ca15_tc2_defconfig index d2a59774420..2c78e12df6a 100644 --- a/configs/vexpress_ca15_tc2_defconfig +++ b/configs/vexpress_ca15_tc2_defconfig @@ -23,6 +23,7 @@ CONFIG_CMD_MMC=y CONFIG_CMD_UBI=y CONFIG_ENV_IS_IN_FLASH=y CONFIG_ENV_ADDR=0xFF80000 +CONFIG_ARM_PL180_MMCI=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y diff --git a/configs/vexpress_ca5x2_defconfig b/configs/vexpress_ca5x2_defconfig index bedf99a7e16..8395bb74cdb 100644 --- a/configs/vexpress_ca5x2_defconfig +++ b/configs/vexpress_ca5x2_defconfig @@ -22,6 +22,7 @@ CONFIG_CMD_MMC=y CONFIG_CMD_UBI=y CONFIG_ENV_IS_IN_FLASH=y CONFIG_ENV_ADDR=0xFF80000 +CONFIG_ARM_PL180_MMCI=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y diff --git a/configs/vexpress_ca9x4_defconfig b/configs/vexpress_ca9x4_defconfig index 8234b5d1bbc..1811782128f 100644 --- a/configs/vexpress_ca9x4_defconfig +++ b/configs/vexpress_ca9x4_defconfig @@ -23,6 +23,7 @@ CONFIG_CMD_MMC=y CONFIG_CMD_UBI=y CONFIG_ENV_IS_IN_FLASH=y CONFIG_ENV_ADDR=0x47F80000 +CONFIG_ARM_PL180_MMCI=y CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 8f56572c39a..33b128ddc5a 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -66,7 +66,6 @@ config MMC_SPI_CRC_ON config ARM_PL180_MMCI bool "ARM AMBA Multimedia Card Interface and compatible support" - depends on DM_MMC && OF_CONTROL help This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card Interface (PL180, PL181 and compatible) support. diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h index ca765579e82..ffc3b43fc55 100644 --- a/include/configs/vexpress_common.h +++ b/include/configs/vexpress_common.h @@ -135,7 +135,6 @@ #define CONFIG_SYS_SERIAL0 V2M_UART0 #define CONFIG_SYS_SERIAL1 V2M_UART1 -#define CONFIG_ARM_PL180_MMCI #define CONFIG_ARM_PL180_MMCI_BASE V2M_MMCI #define CONFIG_SYS_MMC_MAX_BLK_COUNT 127 #define CONFIG_ARM_PL180_MMCI_CLOCK_FREQ 6250000 -- cgit v1.3.1 From 348d183e546bf28f78fe0ca03b36d8f76526c10c Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 16 Jun 2020 19:06:05 -0400 Subject: Convert CONFIG_AT91_GPIO to Kconfig This converts the following to Kconfig: CONFIG_AT91_GPIO Signed-off-by: Tom Rini --- arch/arm/mach-at91/include/mach/at91rm9200.h | 2 -- configs/at91rm9200ek_defconfig | 1 + configs/at91rm9200ek_ram_defconfig | 1 + configs/axm_defconfig | 1 + configs/corvus_defconfig | 1 + configs/gurnard_defconfig | 1 + configs/picosam9g45_defconfig | 1 + configs/smartweb_defconfig | 1 + configs/snapper9260_defconfig | 1 + configs/snapper9g20_defconfig | 1 + configs/taurus_defconfig | 1 + configs/vinco_defconfig | 1 + configs/wb45n_defconfig | 1 + configs/wb50n_defconfig | 1 + drivers/gpio/Kconfig | 1 - include/configs/at91-sama5_common.h | 5 ----- include/configs/corvus.h | 1 - include/configs/picosam9g45.h | 1 - include/configs/smartweb.h | 1 - include/configs/snapper9260.h | 1 - include/configs/snapper9g45.h | 1 - include/configs/taurus.h | 1 - include/configs/wb45n.h | 1 - include/configs/wb50n.h | 3 --- 24 files changed, 13 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-at91/include/mach/at91rm9200.h b/arch/arm/mach-at91/include/mach/at91rm9200.h index 3412df0f06c..309039347c8 100644 --- a/arch/arm/mach-at91/include/mach/at91rm9200.h +++ b/arch/arm/mach-at91/include/mach/at91rm9200.h @@ -5,8 +5,6 @@ #ifndef __AT91RM9200_H__ #define __AT91RM9200_H__ -#define CONFIG_AT91_GPIO /* and require always gpio features */ - /* Periperial Identifiers */ #define ATMEL_ID_SYS 1 /* System Peripheral */ diff --git a/configs/at91rm9200ek_defconfig b/configs/at91rm9200ek_defconfig index 0b025911d69..2aaf8790456 100644 --- a/configs/at91rm9200ek_defconfig +++ b/configs/at91rm9200ek_defconfig @@ -22,6 +22,7 @@ CONFIG_CMD_PING=y CONFIG_CMD_FAT=y CONFIG_ENV_IS_IN_FLASH=y CONFIG_ENV_ADDR=0x10040000 +CONFIG_AT91_GPIO=y # CONFIG_MMC is not set CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y diff --git a/configs/at91rm9200ek_ram_defconfig b/configs/at91rm9200ek_ram_defconfig index 09c996b8b22..9d2fc473430 100644 --- a/configs/at91rm9200ek_ram_defconfig +++ b/configs/at91rm9200ek_ram_defconfig @@ -23,6 +23,7 @@ CONFIG_CMD_PING=y CONFIG_CMD_FAT=y CONFIG_ENV_IS_IN_FLASH=y CONFIG_ENV_ADDR=0x10040000 +CONFIG_AT91_GPIO=y # CONFIG_MMC is not set CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y diff --git a/configs/axm_defconfig b/configs/axm_defconfig index 78e6c8d3456..1615d8af0eb 100644 --- a/configs/axm_defconfig +++ b/configs/axm_defconfig @@ -58,6 +58,7 @@ CONFIG_BLK=y CONFIG_HAVE_BLOCK_DEVICE=y CONFIG_CLK=y CONFIG_CLK_AT91=y +CONFIG_AT91_GPIO=y # CONFIG_MMC is not set CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y diff --git a/configs/corvus_defconfig b/configs/corvus_defconfig index 0eedaa93667..c6e5955bf32 100644 --- a/configs/corvus_defconfig +++ b/configs/corvus_defconfig @@ -48,6 +48,7 @@ CONFIG_BLK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_DFU_NAND=y +CONFIG_AT91_GPIO=y # CONFIG_MMC is not set CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y diff --git a/configs/gurnard_defconfig b/configs/gurnard_defconfig index 0d1a46315bd..a679c0f6700 100644 --- a/configs/gurnard_defconfig +++ b/configs/gurnard_defconfig @@ -32,6 +32,7 @@ CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="at91sam9g45-gurnard" CONFIG_ENV_IS_IN_NAND=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_AT91_GPIO=y CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y # CONFIG_SYS_NAND_USE_FLASH_BBT is not set diff --git a/configs/picosam9g45_defconfig b/configs/picosam9g45_defconfig index 0157f5172e1..2921f2dfd4f 100644 --- a/configs/picosam9g45_defconfig +++ b/configs/picosam9g45_defconfig @@ -39,6 +39,7 @@ CONFIG_ENV_IS_IN_FAT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM=y CONFIG_SPL_DM=y +CONFIG_AT91_GPIO=y CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_STORAGE=y diff --git a/configs/smartweb_defconfig b/configs/smartweb_defconfig index 8f9a19f695b..4545c7075b3 100644 --- a/configs/smartweb_defconfig +++ b/configs/smartweb_defconfig @@ -49,6 +49,7 @@ CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_DFU_NAND=y +CONFIG_AT91_GPIO=y # CONFIG_MMC is not set CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y diff --git a/configs/snapper9260_defconfig b/configs/snapper9260_defconfig index c684e2b20a1..9e44395f03f 100644 --- a/configs/snapper9260_defconfig +++ b/configs/snapper9260_defconfig @@ -30,6 +30,7 @@ CONFIG_CMD_PING=y CONFIG_CMD_FAT=y CONFIG_ENV_IS_IN_NAND=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_AT91_GPIO=y CONFIG_CMD_PCA953X=y # CONFIG_MMC is not set CONFIG_MTD=y diff --git a/configs/snapper9g20_defconfig b/configs/snapper9g20_defconfig index 3ef091fab48..e1c5c2ef4c1 100644 --- a/configs/snapper9g20_defconfig +++ b/configs/snapper9g20_defconfig @@ -29,6 +29,7 @@ CONFIG_CMD_PING=y CONFIG_CMD_FAT=y CONFIG_ENV_IS_IN_NAND=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_AT91_GPIO=y CONFIG_CMD_PCA953X=y # CONFIG_MMC is not set CONFIG_MTD=y diff --git a/configs/taurus_defconfig b/configs/taurus_defconfig index d9a2d61ecb6..16a804b879f 100644 --- a/configs/taurus_defconfig +++ b/configs/taurus_defconfig @@ -66,6 +66,7 @@ CONFIG_BLK=y CONFIG_CLK=y CONFIG_CLK_AT91=y CONFIG_DFU_NAND=y +CONFIG_AT91_GPIO=y # CONFIG_MMC is not set CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y diff --git a/configs/vinco_defconfig b/configs/vinco_defconfig index 2684324cace..8ca7556772b 100644 --- a/configs/vinco_defconfig +++ b/configs/vinco_defconfig @@ -31,6 +31,7 @@ CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="at91-vinco" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_AT91_GPIO=y CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 diff --git a/configs/wb45n_defconfig b/configs/wb45n_defconfig index 5728cfb4548..d770e007a65 100644 --- a/configs/wb45n_defconfig +++ b/configs/wb45n_defconfig @@ -33,6 +33,7 @@ CONFIG_CMD_MTDPARTS=y CONFIG_ENV_IS_IN_NAND=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_AT91_GPIO=y CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y # CONFIG_SYS_NAND_USE_FLASH_BBT is not set diff --git a/configs/wb50n_defconfig b/configs/wb50n_defconfig index 86a8549406b..e764c303d06 100644 --- a/configs/wb50n_defconfig +++ b/configs/wb50n_defconfig @@ -33,6 +33,7 @@ CONFIG_ENV_IS_IN_NAND=y CONFIG_SYS_REDUNDAND_ENVIRONMENT=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y +CONFIG_AT91_GPIO=y CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y # CONFIG_SYS_NAND_USE_FLASH_BBT is not set diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d87f6cc1051..af608b7b0ef 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -77,7 +77,6 @@ config DWAPB_GPIO config AT91_GPIO bool "AT91 PIO GPIO driver" - depends on DM_GPIO default n help Say yes here to select AT91 PIO GPIO driver. AT91 PIO diff --git a/include/configs/at91-sama5_common.h b/include/configs/at91-sama5_common.h index 624b05ad08c..53629743d9d 100644 --- a/include/configs/at91-sama5_common.h +++ b/include/configs/at91-sama5_common.h @@ -19,11 +19,6 @@ #define CONFIG_SKIP_LOWLEVEL_INIT #endif -/* general purpose I/O */ -#if !CONFIG_IS_ENABLED(DM_GPIO) -#define CONFIG_AT91_GPIO -#endif - /* * BOOTP options */ diff --git a/include/configs/corvus.h b/include/configs/corvus.h index e9064a200d3..1dc946d7899 100644 --- a/include/configs/corvus.h +++ b/include/configs/corvus.h @@ -36,7 +36,6 @@ /* general purpose I/O */ #define CONFIG_ATMEL_LEGACY /* required until (g)pio is fixed */ -#define CONFIG_AT91_GPIO #define CONFIG_AT91_GPIO_PULLUP 1 /* keep pullups on peripheral pins */ /* serial console */ diff --git a/include/configs/picosam9g45.h b/include/configs/picosam9g45.h index 2747c0cb930..94d9111cbaa 100644 --- a/include/configs/picosam9g45.h +++ b/include/configs/picosam9g45.h @@ -28,7 +28,6 @@ /* general purpose I/O */ #define CONFIG_ATMEL_LEGACY /* required until (g)pio is fixed */ -#define CONFIG_AT91_GPIO #define CONFIG_AT91_GPIO_PULLUP 1 /* keep pullups on peripheral pins */ /* serial console */ diff --git a/include/configs/smartweb.h b/include/configs/smartweb.h index aacdd1263e7..8c964087131 100644 --- a/include/configs/smartweb.h +++ b/include/configs/smartweb.h @@ -85,7 +85,6 @@ /* general purpose I/O */ #define CONFIG_ATMEL_LEGACY /* required until (g)pio is fixed */ -#define CONFIG_AT91_GPIO /* enable the GPIO features */ #define CONFIG_AT91_GPIO_PULLUP 1 /* keep pullups on peripheral pins */ /* serial console */ diff --git a/include/configs/snapper9260.h b/include/configs/snapper9260.h index 35cd7f69c1d..32dd544a6c7 100644 --- a/include/configs/snapper9260.h +++ b/include/configs/snapper9260.h @@ -62,7 +62,6 @@ /* GPIOs and IO expander */ #define CONFIG_ATMEL_LEGACY -#define CONFIG_AT91_GPIO #define CONFIG_AT91_GPIO_PULLUP 1 #define CONFIG_PCA953X #define CONFIG_SYS_I2C_PCA953X_ADDR 0x28 diff --git a/include/configs/snapper9g45.h b/include/configs/snapper9g45.h index fcd35b715ce..db4fd9be247 100644 --- a/include/configs/snapper9g45.h +++ b/include/configs/snapper9g45.h @@ -60,7 +60,6 @@ /* GPIOs and IO expander */ #define CONFIG_ATMEL_LEGACY -#define CONFIG_AT91_GPIO #define CONFIG_AT91_GPIO_PULLUP 1 /* UARTs/Serial console */ diff --git a/include/configs/taurus.h b/include/configs/taurus.h index 9990c9340a3..b9b9292502e 100644 --- a/include/configs/taurus.h +++ b/include/configs/taurus.h @@ -41,7 +41,6 @@ /* general purpose I/O */ #define CONFIG_ATMEL_LEGACY /* required until (g)pio is fixed */ -#define CONFIG_AT91_GPIO #define CONFIG_AT91_GPIO_PULLUP 1 /* keep pullups on peripheral pins */ #define CONFIG_USART_BASE ATMEL_BASE_DBGU diff --git a/include/configs/wb45n.h b/include/configs/wb45n.h index d256ce8e4b9..f13ad112f79 100644 --- a/include/configs/wb45n.h +++ b/include/configs/wb45n.h @@ -20,7 +20,6 @@ /* general purpose I/O */ #define CONFIG_ATMEL_LEGACY /* required until (g)pio is fixed */ -#define CONFIG_AT91_GPIO /* serial console */ #define CONFIG_ATMEL_USART diff --git a/include/configs/wb50n.h b/include/configs/wb50n.h index bb4deeac9b7..ffcc9877edd 100644 --- a/include/configs/wb50n.h +++ b/include/configs/wb50n.h @@ -20,9 +20,6 @@ #define CONFIG_SKIP_LOWLEVEL_INIT #endif -/* general purpose I/O */ -#define CONFIG_AT91_GPIO - /* serial console */ #define CONFIG_ATMEL_USART #define CONFIG_USART_BASE ATMEL_BASE_DBGU -- cgit v1.3.1 From a60becc8c7ec06db2c0b8bec3c6ea25850911749 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 16 Jun 2020 19:06:06 -0400 Subject: Convert CONFIG_ATMEL_HLCD to Kconfig This converts the following to Kconfig: CONFIG_ATMEL_HLCD Signed-off-by: Tom Rini --- configs/at91sam9n12ek_mmc_defconfig | 1 + configs/at91sam9n12ek_nandflash_defconfig | 1 + configs/at91sam9n12ek_spiflash_defconfig | 1 + drivers/video/Kconfig | 1 - include/configs/at91sam9n12ek.h | 1 - 5 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/configs/at91sam9n12ek_mmc_defconfig b/configs/at91sam9n12ek_mmc_defconfig index 6f159aaccfa..5a147a0bf62 100644 --- a/configs/at91sam9n12ek_mmc_defconfig +++ b/configs/at91sam9n12ek_mmc_defconfig @@ -61,4 +61,5 @@ CONFIG_ATMEL_PIT_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_ATMEL_HLCD=y CONFIG_LCD=y diff --git a/configs/at91sam9n12ek_nandflash_defconfig b/configs/at91sam9n12ek_nandflash_defconfig index 490addbedfd..8263ffb1312 100644 --- a/configs/at91sam9n12ek_nandflash_defconfig +++ b/configs/at91sam9n12ek_nandflash_defconfig @@ -62,4 +62,5 @@ CONFIG_ATMEL_PIT_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_ATMEL_HLCD=y CONFIG_LCD=y diff --git a/configs/at91sam9n12ek_spiflash_defconfig b/configs/at91sam9n12ek_spiflash_defconfig index 688f0c3a286..0e95cff7336 100644 --- a/configs/at91sam9n12ek_spiflash_defconfig +++ b/configs/at91sam9n12ek_spiflash_defconfig @@ -63,4 +63,5 @@ CONFIG_ATMEL_PIT_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_ATMEL_HLCD=y CONFIG_LCD=y diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index f5f3f28f23a..52f5bc61272 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -502,7 +502,6 @@ config NXP_TDA19988 config ATMEL_HLCD bool "Enable ATMEL video support using HLCDC" - depends on DM_VIDEO help HLCDC supports video output to an attached LCD panel. diff --git a/include/configs/at91sam9n12ek.h b/include/configs/at91sam9n12ek.h index 706217fef9a..c2d4e485a9d 100644 --- a/include/configs/at91sam9n12ek.h +++ b/include/configs/at91sam9n12ek.h @@ -25,7 +25,6 @@ #define CONFIG_LCD_LOGO #define CONFIG_LCD_INFO #define CONFIG_LCD_INFO_BELOW_LOGO -#define CONFIG_ATMEL_HLCD #define CONFIG_ATMEL_LCD_RGB565 /* -- cgit v1.3.1 From 56c404603825a4e3229dcf0d3d88318b20493fa6 Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Thu, 4 Jun 2020 23:11:53 +0800 Subject: spi: Convert CONFIG_DM_SPI* to CONFIG_$(SPL_TPL_)DM_SPI* This change allows more fine tuning of driver model based SPI support in SPL and TPL. It is now possible to explicitly enable/disable the DM_SPI support in SPL and TPL via Kconfig option. Before this change it was necessary to use: /* SPI Flash Configs */ #if defined(CONFIG_SPL_BUILD) #undef CONFIG_DM_SPI #undef CONFIG_DM_SPI_FLASH #undef CONFIG_SPI_FLASH_MTD #endif in the ./include/configs/.h, which is error prone and shall be avoided when we strive to switch to Kconfig. The goal of this patch: Provide distinction for DM_SPI support in both U-Boot proper and SPL (TPL). Valid use case is when U-Boot proper wants to use DM_SPI, but SPL must still support non DM driver. Another use case is the conversion of non DM/DTS SPI driver to support DM/DTS. When such driver needs to work in both SPL and U-Boot proper, the distinction is needed in Kconfig (also if SPL version of the driver supports OF_PLATDATA). In the end of the day one would have to support following use cases (in single driver file - e.g. mxs_spi.c): - U-Boot proper driver supporting DT/DTS - U-Boot proper driver without DT/DTS support (deprecated) - SPL driver without DT/DTS support - SPL (and TPL) driver with DT/DTS (when the SoC has enough resources to run full blown DT/DTS) - SPL driver with DT/DTS and SPL_OF_PLATDATA (when one have constrained environment with no fitImage and OF_LIBFDT support). Some boards do require SPI support (with DM) in SPL (TPL) and some only have DM_SPI{_FLASH} defined to allow compiling SPL. This patch converts #ifdef CONFIG_DM_SPI* to #if CONFIG_IS_ENABLED(DM_SPI) and provides corresponding defines in Kconfig. Signed-off-by: Lukasz Majewski Tested-by: Adam Ford #da850-evm Signed-off-by: Hou Zhiqiang [trini: Fixup a few platforms] Signed-off-by: Tom Rini --- arch/arm/Kconfig | 11 +++++++++++ board/l+g/vinco/vinco.c | 4 ++-- cmd/sf.c | 4 ++-- cmd/spi.c | 6 +++--- common/spl/Kconfig | 20 ++++++++++++++++++++ configs/am57xx_evm_defconfig | 2 ++ configs/am57xx_hs_evm_defconfig | 2 ++ configs/am57xx_hs_evm_usb_defconfig | 2 ++ configs/am65x_evm_a53_defconfig | 1 + configs/am65x_evm_r5_defconfig | 1 + configs/am65x_hs_evm_a53_defconfig | 1 + configs/am65x_hs_evm_r5_defconfig | 1 + configs/axm_defconfig | 2 ++ configs/brppt1_spi_defconfig | 1 + configs/brppt2_defconfig | 1 + configs/brsmarc1_defconfig | 1 + configs/chromebook_coral_defconfig | 1 + configs/chromebook_link64_defconfig | 2 ++ configs/chromebook_samus_tpl_defconfig | 4 ++++ configs/cm_t43_defconfig | 1 + configs/da850evm_defconfig | 1 + configs/dra7xx_evm_defconfig | 2 ++ configs/dra7xx_hs_evm_defconfig | 2 ++ configs/dra7xx_hs_evm_usb_defconfig | 2 ++ configs/imx28_xea_defconfig | 1 + configs/j721e_evm_a72_defconfig | 2 ++ configs/j721e_evm_r5_defconfig | 2 ++ configs/j721e_hs_evm_a72_defconfig | 1 + configs/j721e_hs_evm_r5_defconfig | 1 + configs/k2e_evm_defconfig | 1 + configs/k2hk_evm_defconfig | 1 + configs/k2l_evm_defconfig | 1 + configs/ls1021aiot_qspi_defconfig | 2 ++ configs/ls1021aiot_sdcard_defconfig | 2 ++ configs/ls1021aqds_qspi_defconfig | 1 + configs/ls1021aqds_sdcard_qspi_defconfig | 1 + configs/ls1021atwr_qspi_defconfig | 1 + configs/qemu-x86_64_defconfig | 1 + configs/sama5d27_wlsom1_ek_qspiflash_defconfig | 1 + configs/sama5d2_xplained_spiflash_defconfig | 2 ++ configs/sama5d3xek_spiflash_defconfig | 2 ++ configs/sama5d4_xplained_spiflash_defconfig | 2 ++ configs/sama5d4ek_spiflash_defconfig | 2 ++ configs/stm32mp15_basic_defconfig | 2 ++ configs/stm32mp15_dhcom_basic_defconfig | 1 + configs/stm32mp15_dhcor_basic_defconfig | 1 + configs/taurus_defconfig | 2 ++ drivers/mtd/spi/Makefile | 4 ++-- drivers/mtd/spi/sf_probe.c | 2 +- drivers/net/fm/fm.c | 4 ++-- drivers/spi/Makefile | 2 +- drivers/spi/kirkwood_spi.c | 2 +- drivers/spi/mxc_spi.c | 6 +++--- drivers/spi/omap3_spi.c | 4 ++-- drivers/spi/sh_qspi.c | 4 ++-- env/sf.c | 2 +- include/spi.h | 8 ++++---- include/spi_flash.h | 2 +- test/dm/spi.c | 2 +- 59 files changed, 122 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 54d65f84889..73a27316dfb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -549,6 +549,7 @@ config TARGET_GPLUGD config ARCH_DAVINCI bool "TI DaVinci" select CPU_ARM926EJS + select SPL_DM_SPI if SPL imply CMD_SAVES help Support for TI's DaVinci platform. @@ -566,6 +567,8 @@ config ARCH_MVEBU select DM_SERIAL select DM_SPI select DM_SPI_FLASH + select SPL_DM_SPI if SPL + select SPL_DM_SPI_FLASH if SPL select OF_CONTROL select OF_SEPARATE select SPI @@ -985,6 +988,8 @@ config ARCH_SOCFPGA imply FAT_WRITE imply SPL imply SPL_DM + imply SPL_DM_SPI + imply SPL_DM_SPI_FLASH imply SPL_LIBDISK_SUPPORT imply SPL_MMC_SUPPORT imply SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION @@ -1093,6 +1098,8 @@ config ARCH_ZYNQ select SPL_BOARD_INIT if SPL select SPL_CLK if SPL select SPL_DM if SPL + select SPL_DM_SPI if SPL + select SPL_DM_SPI_FLASH if SPL select SPL_OF_CONTROL if SPL select SPL_SEPARATE_BSS if SPL select SUPPORT_SPL @@ -1131,6 +1138,8 @@ config ARCH_ZYNQMP select OF_CONTROL select SPL_BOARD_INIT if SPL select SPL_CLK if SPL + select SPL_DM_SPI if SPI + select SPL_DM_SPI_FLASH if SPL_DM_SPI select SPL_DM_MAILBOX if SPL select SPL_FIRMWARE if SPL select SPL_SEPARATE_BSS if SPL @@ -1680,6 +1689,8 @@ config ARCH_ROCKCHIP select OF_CONTROL select SPI select SPL_DM if SPL + select SPL_DM_SPI if SPL + select SPL_DM_SPI_FLASH if SPL select SYS_MALLOC_F select SYS_THUMB_BUILD if !ARM64 imply ADC diff --git a/board/l+g/vinco/vinco.c b/board/l+g/vinco/vinco.c index 5a998e37d8a..440838c1124 100644 --- a/board/l+g/vinco/vinco.c +++ b/board/l+g/vinco/vinco.c @@ -34,7 +34,7 @@ DECLARE_GLOBAL_DATA_PTR; /* FIXME gpio code here need to handle through DM_GPIO */ -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) int spi_cs_is_valid(unsigned int bus, unsigned int cs) { return bus == 0 && cs == 0; @@ -167,7 +167,7 @@ int board_init(void) /* adress of boot parameters */ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) vinco_spi0_hw_init(); #endif diff --git a/cmd/sf.c b/cmd/sf.c index d18f6a888ce..c0d6a8f8a06 100644 --- a/cmd/sf.c +++ b/cmd/sf.c @@ -91,7 +91,7 @@ static int do_spi_flash_probe(int argc, char *const argv[]) unsigned int speed = CONFIG_SF_DEFAULT_SPEED; unsigned int mode = CONFIG_SF_DEFAULT_MODE; char *endp; -#ifdef CONFIG_DM_SPI_FLASH +#if CONFIG_IS_ENABLED(DM_SPI_FLASH) struct udevice *new, *bus_dev; int ret; #else @@ -124,7 +124,7 @@ static int do_spi_flash_probe(int argc, char *const argv[]) return -1; } -#ifdef CONFIG_DM_SPI_FLASH +#if CONFIG_IS_ENABLED(DM_SPI_FLASH) /* Remove the old device, otherwise probe will just be a nop */ ret = spi_find_bus_and_cs(bus, cs, &bus_dev, &new); if (!ret) { diff --git a/cmd/spi.c b/cmd/spi.c index aec912167c6..4aea1914129 100644 --- a/cmd/spi.c +++ b/cmd/spi.c @@ -38,7 +38,7 @@ static int do_spi_xfer(int bus, int cs) struct spi_slave *slave; int ret = 0; -#ifdef CONFIG_DM_SPI +#if CONFIG_IS_ENABLED(DM_SPI) char name[30], *str; struct udevice *dev; @@ -63,7 +63,7 @@ static int do_spi_xfer(int bus, int cs) goto done; ret = spi_xfer(slave, bitlen, dout, din, SPI_XFER_BEGIN | SPI_XFER_END); -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) /* We don't get an error code in this case */ if (ret) ret = -EIO; @@ -79,7 +79,7 @@ static int do_spi_xfer(int bus, int cs) } done: spi_release_bus(slave); -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) spi_free_slave(slave); #endif diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 3eae65ebc19..d09e52e88bf 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -756,6 +756,11 @@ config SPL_DM_SPI help Enable support for SPI DM drivers in SPL. +config SPL_DM_SPI_FLASH + bool "Support SPI DM FLASH drivers in SPL" + help + Enable support for SPI DM flash drivers in SPL. + endif if SPL_UBI config SPL_UBI_LOAD_BY_VOLNAME @@ -1092,6 +1097,11 @@ config SPL_SPI_FLASH_SFDP_SUPPORT SPI NOR flashes using Serial Flash Discoverable Parameters (SFDP) tables as per JESD216 standard in SPL. +config SPL_SPI_FLASH_MTD + bool "Support for SPI flash MTD drivers in SPL" + help + Enable support for SPI flash MTD drivers in SPL. + config SPL_SPI_LOAD bool "Support loading from SPI flash" help @@ -1499,6 +1509,16 @@ config TPL_SPI_SUPPORT Enable support for using SPI in TPL. See SPL_SPI_SUPPORT for details. +config TPL_DM_SPI + bool "Support SPI DM drivers in TPL" + help + Enable support for SPI DM drivers in TPL. + +config TPL_DM_SPI_FLASH + bool "Support SPI DM FLASH drivers in TPL" + help + Enable support for SPI DM flash drivers in TPL. + config TPL_YMODEM_SUPPORT bool "Support loading using Ymodem" depends on TPL_SERIAL_SUPPORT diff --git a/configs/am57xx_evm_defconfig b/configs/am57xx_evm_defconfig index 7c907fd3f49..cefed5b0600 100644 --- a/configs/am57xx_evm_defconfig +++ b/configs/am57xx_evm_defconfig @@ -78,6 +78,7 @@ CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_MMC_OMAP_HS=y CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=76800000 CONFIG_SPI_FLASH_SPANSION=y @@ -96,6 +97,7 @@ CONFIG_DM_SCSI=y CONFIG_DM_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_TI_QSPI=y CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/am57xx_hs_evm_defconfig b/configs/am57xx_hs_evm_defconfig index 81bac5592eb..081a48f0380 100644 --- a/configs/am57xx_hs_evm_defconfig +++ b/configs/am57xx_hs_evm_defconfig @@ -74,6 +74,7 @@ CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_MMC_OMAP_HS=y CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=76800000 CONFIG_SPI_FLASH_SPANSION=y @@ -92,6 +93,7 @@ CONFIG_DM_SCSI=y CONFIG_DM_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_TI_QSPI=y CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/am57xx_hs_evm_usb_defconfig b/configs/am57xx_hs_evm_usb_defconfig index ea5215e8cf3..154154c68fb 100644 --- a/configs/am57xx_hs_evm_usb_defconfig +++ b/configs/am57xx_hs_evm_usb_defconfig @@ -80,6 +80,7 @@ CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_MMC_OMAP_HS=y CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=76800000 CONFIG_SPI_FLASH_BAR=y @@ -99,6 +100,7 @@ CONFIG_DM_REGULATOR_PALMAS=y CONFIG_DM_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_TI_QSPI=y CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig index 9d97a488db2..3f2f4e45e32 100644 --- a/configs/am65x_evm_a53_defconfig +++ b/configs/am65x_evm_a53_defconfig @@ -37,6 +37,7 @@ CONFIG_SPL_DMA=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_DM_MAILBOX=y CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_DM_RESET=y CONFIG_SPL_POWER_DOMAIN=y # CONFIG_SPL_SPI_FLASH_TINY is not set diff --git a/configs/am65x_evm_r5_defconfig b/configs/am65x_evm_r5_defconfig index 1e7a7d1e6ee..14466465ab4 100644 --- a/configs/am65x_evm_r5_defconfig +++ b/configs/am65x_evm_r5_defconfig @@ -33,6 +33,7 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400 CONFIG_SPL_DMA=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_DM_RESET=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_POWER_DOMAIN=y diff --git a/configs/am65x_hs_evm_a53_defconfig b/configs/am65x_hs_evm_a53_defconfig index 49fe5a5b6da..373eb4b0093 100644 --- a/configs/am65x_hs_evm_a53_defconfig +++ b/configs/am65x_hs_evm_a53_defconfig @@ -40,6 +40,7 @@ CONFIG_SPL_DMA=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_DM_MAILBOX=y CONFIG_SPL_MTD_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_DM_RESET=y CONFIG_SPL_POWER_DOMAIN=y # CONFIG_SPL_SPI_FLASH_TINY is not set diff --git a/configs/am65x_hs_evm_r5_defconfig b/configs/am65x_hs_evm_r5_defconfig index 9977e97f2b0..6e83f333793 100644 --- a/configs/am65x_hs_evm_r5_defconfig +++ b/configs/am65x_hs_evm_r5_defconfig @@ -35,6 +35,7 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x400 CONFIG_SPL_DMA=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_DM_RESET=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_POWER_DOMAIN=y diff --git a/configs/axm_defconfig b/configs/axm_defconfig index 6a3336c256b..ce3ad9f8b48 100644 --- a/configs/axm_defconfig +++ b/configs/axm_defconfig @@ -65,6 +65,8 @@ CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y # CONFIG_SYS_NAND_USE_FLASH_BBT is not set CONFIG_NAND_ATMEL=y +CONFIG_SPL_DM_SPI=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y diff --git a/configs/brppt1_spi_defconfig b/configs/brppt1_spi_defconfig index aea67c25dc2..be527fd7257 100644 --- a/configs/brppt1_spi_defconfig +++ b/configs/brppt1_spi_defconfig @@ -39,6 +39,7 @@ CONFIG_SPL_SEPARATE_BSS=y # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_NAND_SUPPORT is not set +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_SPI_LOAD=y CONFIG_SPL_WATCHDOG_SUPPORT=y diff --git a/configs/brppt2_defconfig b/configs/brppt2_defconfig index c4eb03bde07..3bfe882c98e 100644 --- a/configs/brppt2_defconfig +++ b/configs/brppt2_defconfig @@ -33,6 +33,7 @@ CONFIG_BOARD_EARLY_INIT_F=y CONFIG_SPL_BOARD_INIT=y # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_SPI_LOAD=y CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y diff --git a/configs/brsmarc1_defconfig b/configs/brsmarc1_defconfig index aac8d17876b..a7778674c0f 100644 --- a/configs/brsmarc1_defconfig +++ b/configs/brsmarc1_defconfig @@ -39,6 +39,7 @@ CONFIG_SPL_SEPARATE_BSS=y # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set CONFIG_SPL_I2C_SUPPORT=y # CONFIG_SPL_NAND_SUPPORT is not set +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_SPI_LOAD=y CONFIG_SPL_YMODEM_SUPPORT=y diff --git a/configs/chromebook_coral_defconfig b/configs/chromebook_coral_defconfig index 6cc3a8469fe..79f9b5a2321 100644 --- a/configs/chromebook_coral_defconfig +++ b/configs/chromebook_coral_defconfig @@ -37,6 +37,7 @@ CONFIG_HANDOFF=y CONFIG_TPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_CPU_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_PCI=y # CONFIG_SPL_SPI_FLASH_TINY is not set CONFIG_HUSH_PARSER=y diff --git a/configs/chromebook_link64_defconfig b/configs/chromebook_link64_defconfig index a80225a11f3..3e760e75ddd 100644 --- a/configs/chromebook_link64_defconfig +++ b/configs/chromebook_link64_defconfig @@ -31,6 +31,8 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_CPU_SUPPORT=y CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_DM_SPI=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_NET_SUPPORT=y CONFIG_SPL_PCI=y CONFIG_SPL_PCH_SUPPORT=y diff --git a/configs/chromebook_samus_tpl_defconfig b/configs/chromebook_samus_tpl_defconfig index 95c9b6e6af5..422bcfd8af4 100644 --- a/configs/chromebook_samus_tpl_defconfig +++ b/configs/chromebook_samus_tpl_defconfig @@ -32,11 +32,15 @@ CONFIG_BLOBLIST_SIZE=0x1000 CONFIG_BLOBLIST_ADDR=0xff7c0000 CONFIG_HANDOFF=y CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_DM_SPI=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_NET_SUPPORT=y CONFIG_SPL_PCI=y CONFIG_SPL_PCH_SUPPORT=y CONFIG_TPL_PCI=y CONFIG_TPL_PCH_SUPPORT=y +CONFIG_TPL_DM_SPI=y +CONFIG_TPL_DM_SPI_FLASH=y CONFIG_HUSH_PARSER=y CONFIG_CMD_CPU=y CONFIG_CMD_GPIO=y diff --git a/configs/cm_t43_defconfig b/configs/cm_t43_defconfig index 4232aaca002..98c50954b6b 100644 --- a/configs/cm_t43_defconfig +++ b/configs/cm_t43_defconfig @@ -31,6 +31,7 @@ CONFIG_SPL_FS_EXT4=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_MTD_SUPPORT=y # CONFIG_SPL_NAND_SUPPORT is not set +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_SPI_LOAD=y CONFIG_SYS_PROMPT="CM-T43 # " diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig index 12768065f3a..2e87637f7e4 100644 --- a/configs/da850evm_defconfig +++ b/configs/da850evm_defconfig @@ -30,6 +30,7 @@ CONFIG_BOARD_EARLY_INIT_F=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_SEPARATE_BSS=y # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_SPI_LOAD=y CONFIG_HUSH_PARSER=y CONFIG_SYS_PROMPT="U-Boot > " diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig index f117077111e..022dfaeb378 100644 --- a/configs/dra7xx_evm_defconfig +++ b/configs/dra7xx_evm_defconfig @@ -84,6 +84,7 @@ CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y CONFIG_SYS_NAND_BUSWIDTH_16BIT=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=76800000 CONFIG_SPI_FLASH_SPANSION=y @@ -106,6 +107,7 @@ CONFIG_DM_SCSI=y CONFIG_DM_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_TI_QSPI=y CONFIG_TIMER=y CONFIG_OMAP_TIMER=y diff --git a/configs/dra7xx_hs_evm_defconfig b/configs/dra7xx_hs_evm_defconfig index 6fa117cfae0..e15f62eded9 100644 --- a/configs/dra7xx_hs_evm_defconfig +++ b/configs/dra7xx_hs_evm_defconfig @@ -87,6 +87,7 @@ CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y CONFIG_SYS_NAND_BUSWIDTH_16BIT=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=76800000 CONFIG_SPI_FLASH_SPANSION=y @@ -109,6 +110,7 @@ CONFIG_DM_SCSI=y CONFIG_DM_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_TI_QSPI=y CONFIG_TIMER=y CONFIG_OMAP_TIMER=y diff --git a/configs/dra7xx_hs_evm_usb_defconfig b/configs/dra7xx_hs_evm_usb_defconfig index 53cf7047553..91e28618923 100644 --- a/configs/dra7xx_hs_evm_usb_defconfig +++ b/configs/dra7xx_hs_evm_usb_defconfig @@ -84,6 +84,7 @@ CONFIG_SPL_MMC_HS200_SUPPORT=y CONFIG_MMC_OMAP_HS=y CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_MODE=0 CONFIG_SF_DEFAULT_SPEED=76800000 CONFIG_SPI_FLASH_BAR=y @@ -106,6 +107,7 @@ CONFIG_DM_SCSI=y CONFIG_DM_SERIAL=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_TI_QSPI=y CONFIG_TIMER=y CONFIG_OMAP_TIMER=y diff --git a/configs/imx28_xea_defconfig b/configs/imx28_xea_defconfig index 592f3e387cc..0001f468ddd 100644 --- a/configs/imx28_xea_defconfig +++ b/configs/imx28_xea_defconfig @@ -33,6 +33,7 @@ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0 CONFIG_SUPPORT_EMMC_BOOT_OVERRIDE_PART_CONFIG=y CONFIG_SPL_DMA=y CONFIG_SPL_MMC_TINY=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_OS_BOOT=y CONFIG_SPL_SPI_LOAD=y CONFIG_HUSH_PARSER=y diff --git a/configs/j721e_evm_a72_defconfig b/configs/j721e_evm_a72_defconfig index 9bf07570b14..7c7b9905f94 100644 --- a/configs/j721e_evm_a72_defconfig +++ b/configs/j721e_evm_a72_defconfig @@ -121,6 +121,7 @@ CONFIG_FLASH_CFI_MTD=y CONFIG_SYS_FLASH_CFI=y CONFIG_HBMC_AM654=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_SPI_FLASH_MTD=y @@ -147,6 +148,7 @@ CONFIG_DM_SERIAL=y CONFIG_SOC_TI=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_CADENCE_QSPI=y CONFIG_SYSRESET=y CONFIG_SPL_SYSRESET=y diff --git a/configs/j721e_evm_r5_defconfig b/configs/j721e_evm_r5_defconfig index c597f830923..822d1fc4869 100644 --- a/configs/j721e_evm_r5_defconfig +++ b/configs/j721e_evm_r5_defconfig @@ -90,6 +90,7 @@ CONFIG_SPL_MMC_SDHCI_ADMA=y CONFIG_MMC_SDHCI_AM654=y CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPI_FLASH_SFDP_SUPPORT=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_PINCTRL=y @@ -113,6 +114,7 @@ CONFIG_DM_SERIAL=y CONFIG_SOC_TI=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_CADENCE_QSPI=y CONFIG_SYSRESET=y CONFIG_SPL_SYSRESET=y diff --git a/configs/j721e_hs_evm_a72_defconfig b/configs/j721e_hs_evm_a72_defconfig index ef4b1149e5c..0bfa4ff23d4 100644 --- a/configs/j721e_hs_evm_a72_defconfig +++ b/configs/j721e_hs_evm_a72_defconfig @@ -35,6 +35,7 @@ CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_DM_RESET=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_POWER_DOMAIN=y diff --git a/configs/j721e_hs_evm_r5_defconfig b/configs/j721e_hs_evm_r5_defconfig index 7bdf3401a1a..b1ee4755754 100644 --- a/configs/j721e_hs_evm_r5_defconfig +++ b/configs/j721e_hs_evm_r5_defconfig @@ -34,6 +34,7 @@ CONFIG_SPL_DMA=y CONFIG_SPL_ENV_SUPPORT=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_DM_MAILBOX=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_DM_RESET=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_POWER_DOMAIN=y diff --git a/configs/k2e_evm_defconfig b/configs/k2e_evm_defconfig index ae07f860e3a..f37644fe2cf 100644 --- a/configs/k2e_evm_defconfig +++ b/configs/k2e_evm_defconfig @@ -24,6 +24,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_VERSION_VARIABLE=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_SPI_LOAD=y CONFIG_CMD_MX_CYCLIC=y diff --git a/configs/k2hk_evm_defconfig b/configs/k2hk_evm_defconfig index 9f992055cae..a14db7db399 100644 --- a/configs/k2hk_evm_defconfig +++ b/configs/k2hk_evm_defconfig @@ -24,6 +24,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_VERSION_VARIABLE=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_SPI_LOAD=y CONFIG_CMD_MX_CYCLIC=y diff --git a/configs/k2l_evm_defconfig b/configs/k2l_evm_defconfig index 3311587c2c1..7180c23cc26 100644 --- a/configs/k2l_evm_defconfig +++ b/configs/k2l_evm_defconfig @@ -24,6 +24,7 @@ CONFIG_SYS_CONSOLE_INFO_QUIET=y CONFIG_VERSION_VARIABLE=y CONFIG_BOARD_EARLY_INIT_F=y CONFIG_SPL_I2C_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_POWER_SUPPORT=y CONFIG_SPL_SPI_LOAD=y CONFIG_CMD_MX_CYCLIC=y diff --git a/configs/ls1021aiot_qspi_defconfig b/configs/ls1021aiot_qspi_defconfig index 85ceeb480ad..f0bf8abaeee 100644 --- a/configs/ls1021aiot_qspi_defconfig +++ b/configs/ls1021aiot_qspi_defconfig @@ -23,6 +23,7 @@ CONFIG_CMD_MII=y CONFIG_CMD_PING=y CONFIG_CMD_EXT2=y CONFIG_CMD_FAT=y +CONFIG_CMD_SF=y CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="ls1021a-iot-duart" CONFIG_ENV_IS_IN_SPI_FLASH=y @@ -50,6 +51,7 @@ CONFIG_DM_SCSI=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_FSL_DSPI=y CONFIG_FSL_QSPI=y CONFIG_USB=y diff --git a/configs/ls1021aiot_sdcard_defconfig b/configs/ls1021aiot_sdcard_defconfig index 11ccf57aad1..9c5dd8a5a16 100644 --- a/configs/ls1021aiot_sdcard_defconfig +++ b/configs/ls1021aiot_sdcard_defconfig @@ -28,6 +28,7 @@ CONFIG_CMD_MII=y CONFIG_CMD_PING=y CONFIG_CMD_EXT2=y CONFIG_CMD_FAT=y +CONFIG_CMD_SF=y # CONFIG_SPL_EFI_PARTITION is not set CONFIG_OF_CONTROL=y CONFIG_DEFAULT_DEVICE_TREE="ls1021a-iot-duart" @@ -56,6 +57,7 @@ CONFIG_DM_SCSI=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_FSL_DSPI=y CONFIG_FSL_QSPI=y CONFIG_USB=y diff --git a/configs/ls1021aqds_qspi_defconfig b/configs/ls1021aqds_qspi_defconfig index f91534cfdd6..0542c5c3036 100644 --- a/configs/ls1021aqds_qspi_defconfig +++ b/configs/ls1021aqds_qspi_defconfig @@ -64,6 +64,7 @@ CONFIG_DM_SCSI=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_FSL_DSPI=y CONFIG_FSL_QSPI=y CONFIG_USB=y diff --git a/configs/ls1021aqds_sdcard_qspi_defconfig b/configs/ls1021aqds_sdcard_qspi_defconfig index 9871c8edf44..fd499175059 100644 --- a/configs/ls1021aqds_sdcard_qspi_defconfig +++ b/configs/ls1021aqds_sdcard_qspi_defconfig @@ -76,6 +76,7 @@ CONFIG_DM_SCSI=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPIy=y CONFIG_FSL_DSPI=y CONFIG_FSL_QSPI=y CONFIG_USB=y diff --git a/configs/ls1021atwr_qspi_defconfig b/configs/ls1021atwr_qspi_defconfig index 4c82d668998..8ef05893342 100644 --- a/configs/ls1021atwr_qspi_defconfig +++ b/configs/ls1021atwr_qspi_defconfig @@ -62,6 +62,7 @@ CONFIG_DM_SCSI=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPI_DM_SPI=y CONFIG_FSL_DSPI=y CONFIG_FSL_QSPI=y CONFIG_USB=y diff --git a/configs/qemu-x86_64_defconfig b/configs/qemu-x86_64_defconfig index a5be09b2ba1..ec126b2d9ae 100644 --- a/configs/qemu-x86_64_defconfig +++ b/configs/qemu-x86_64_defconfig @@ -32,6 +32,7 @@ CONFIG_PCI_INIT_R=y CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_CPU_SUPPORT=y CONFIG_SPL_ENV_SUPPORT=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_NET_SUPPORT=y CONFIG_SPL_PCI=y CONFIG_SPL_PCH_SUPPORT=y diff --git a/configs/sama5d27_wlsom1_ek_qspiflash_defconfig b/configs/sama5d27_wlsom1_ek_qspiflash_defconfig index 58b906ad592..cf949cd7419 100644 --- a/configs/sama5d27_wlsom1_ek_qspiflash_defconfig +++ b/configs/sama5d27_wlsom1_ek_qspiflash_defconfig @@ -33,6 +33,7 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y CONFIG_SPL_SEPARATE_BSS=y CONFIG_SPL_DISPLAY_PRINT=y # CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR is not set +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_SPI_LOAD=y CONFIG_SPL_AT91_MCK_BYPASS=y CONFIG_HUSH_PARSER=y diff --git a/configs/sama5d2_xplained_spiflash_defconfig b/configs/sama5d2_xplained_spiflash_defconfig index e5227b11f50..320175b517a 100644 --- a/configs/sama5d2_xplained_spiflash_defconfig +++ b/configs/sama5d2_xplained_spiflash_defconfig @@ -67,6 +67,8 @@ CONFIG_DM_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ATMEL=y CONFIG_MTD=y +CONFIG_SPL_DM_SPI=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_SPEED=30000000 CONFIG_SPI_FLASH_ATMEL=y diff --git a/configs/sama5d3xek_spiflash_defconfig b/configs/sama5d3xek_spiflash_defconfig index b3bc4b4fe59..8db078abaf7 100644 --- a/configs/sama5d3xek_spiflash_defconfig +++ b/configs/sama5d3xek_spiflash_defconfig @@ -23,6 +23,7 @@ CONFIG_DEBUG_UART_CLOCK=132000000 CONFIG_SPL_SPI_FLASH_SUPPORT=y CONFIG_SPL_SPI_SUPPORT=y CONFIG_SPL_TEXT_BASE=0x300000 +CONFIG_SPL_DM_SPI=y CONFIG_DEBUG_UART=y CONFIG_ENV_VARS_UBOOT_CONFIG=y CONFIG_FIT=y @@ -31,6 +32,7 @@ CONFIG_BOOTDELAY=3 CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 earlyprintk mtdparts=atmel_nand:256k(bootstrap)ro,768k(uboot)ro,256K(env_redundant),256k(env),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=6 root=ubi0:rootfs" # CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPL_SPI_LOAD=y CONFIG_HUSH_PARSER=y CONFIG_CMD_BOOTZ=y diff --git a/configs/sama5d4_xplained_spiflash_defconfig b/configs/sama5d4_xplained_spiflash_defconfig index 2799b69a5d2..4239c050304 100644 --- a/configs/sama5d4_xplained_spiflash_defconfig +++ b/configs/sama5d4_xplained_spiflash_defconfig @@ -68,6 +68,7 @@ CONFIG_MTD_RAW_NAND=y # CONFIG_SYS_NAND_USE_FLASH_BBT is not set CONFIG_NAND_ATMEL=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_SPEED=30000000 CONFIG_SPI_FLASH_ATMEL=y CONFIG_DM_ETH=y @@ -80,6 +81,7 @@ CONFIG_DEBUG_UART_ANNOUNCE=y CONFIG_ATMEL_USART=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_TIMER=y CONFIG_SPL_TIMER=y CONFIG_ATMEL_PIT_TIMER=y diff --git a/configs/sama5d4ek_spiflash_defconfig b/configs/sama5d4ek_spiflash_defconfig index 4b7e825ce02..3e5b2fd8b61 100644 --- a/configs/sama5d4ek_spiflash_defconfig +++ b/configs/sama5d4ek_spiflash_defconfig @@ -65,6 +65,7 @@ CONFIG_MTD_RAW_NAND=y # CONFIG_SYS_NAND_USE_FLASH_BBT is not set CONFIG_NAND_ATMEL=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SF_DEFAULT_SPEED=30000000 CONFIG_SPI_FLASH_ATMEL=y CONFIG_DM_ETH=y @@ -77,6 +78,7 @@ CONFIG_DEBUG_UART_ANNOUNCE=y CONFIG_ATMEL_USART=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_TIMER=y CONFIG_SPL_TIMER=y CONFIG_ATMEL_PIT_TIMER=y diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig index 668cd434f1e..f0abc89a43b 100644 --- a/configs/stm32mp15_basic_defconfig +++ b/configs/stm32mp15_basic_defconfig @@ -91,6 +91,7 @@ CONFIG_MTD_RAW_NAND=y CONFIG_NAND_STM32_FMC2=y CONFIG_MTD_SPI_NAND=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y @@ -121,6 +122,7 @@ CONFIG_RTC_STM32=y CONFIG_SERIAL_RX_BUFFER=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_SPL_DM_SPI=y CONFIG_STM32_QSPI=y CONFIG_STM32_SPI=y CONFIG_USB=y diff --git a/configs/stm32mp15_dhcom_basic_defconfig b/configs/stm32mp15_dhcom_basic_defconfig index 1ac07c5865b..be5926d03a8 100644 --- a/configs/stm32mp15_dhcom_basic_defconfig +++ b/configs/stm32mp15_dhcom_basic_defconfig @@ -93,6 +93,7 @@ CONFIG_STM32_SDMMC2=y CONFIG_MTD=y CONFIG_SYS_MTDPARTS_RUNTIME=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y diff --git a/configs/stm32mp15_dhcor_basic_defconfig b/configs/stm32mp15_dhcor_basic_defconfig index 225d0449794..0344f07daee 100644 --- a/configs/stm32mp15_dhcor_basic_defconfig +++ b/configs/stm32mp15_dhcor_basic_defconfig @@ -89,6 +89,7 @@ CONFIG_SUPPORT_EMMC_BOOT=y CONFIG_STM32_SDMMC2=y CONFIG_MTD=y CONFIG_DM_SPI_FLASH=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y diff --git a/configs/taurus_defconfig b/configs/taurus_defconfig index 953f7784be4..229c97ead5a 100644 --- a/configs/taurus_defconfig +++ b/configs/taurus_defconfig @@ -73,6 +73,8 @@ CONFIG_MTD=y CONFIG_MTD_RAW_NAND=y # CONFIG_SYS_NAND_USE_FLASH_BBT is not set CONFIG_NAND_ATMEL=y +CONFIG_SPL_DM_SPI=y +CONFIG_SPL_DM_SPI_FLASH=y CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_STMICRO=y CONFIG_PHYLIB=y diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile index b5dfa300de4..952fd1e45a1 100644 --- a/drivers/mtd/spi/Makefile +++ b/drivers/mtd/spi/Makefile @@ -3,7 +3,7 @@ # (C) Copyright 2006 # Wolfgang Denk, DENX Software Engineering, wd@denx.de. -obj-$(CONFIG_DM_SPI_FLASH) += sf-uclass.o +obj-$(CONFIG_$(SPL_TPL_)DM_SPI_FLASH) += sf-uclass.o spi-nor-y := sf_probe.o spi-nor-ids.o ifdef CONFIG_SPL_BUILD @@ -19,5 +19,5 @@ endif obj-$(CONFIG_SPI_FLASH) += spi-nor.o obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o -obj-$(CONFIG_$(SPL_)SPI_FLASH_MTD) += sf_mtd.o +obj-$(CONFIG_$(SPL_TPL_)SPI_FLASH_MTD) += sf_mtd.o obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 3548d6319b3..afda241dd06 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -53,7 +53,7 @@ err_read_id: return ret; } -#ifndef CONFIG_DM_SPI_FLASH +#if !CONFIG_IS_ENABLED(DM_SPI_FLASH) struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs, unsigned int max_hz, unsigned int spi_mode) { diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c index 8ab18163954..bbb1738c4bd 100644 --- a/drivers/net/fm/fm.c +++ b/drivers/net/fm/fm.c @@ -383,7 +383,7 @@ int fm_init_common(int index, struct ccsr_fman *reg) addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH); int ret = 0; -#ifdef CONFIG_DM_SPI_FLASH +#if CONFIG_IS_ENABLED(DM_SPI_FLASH) struct udevice *new; /* speed and mode will be read from DT */ @@ -470,7 +470,7 @@ int fm_init_common(int index, struct ccsr_fman *reg) void *addr = malloc(CONFIG_SYS_QE_FMAN_FW_LENGTH); int ret = 0; -#ifdef CONFIG_DM_SPI_FLASH +#if CONFIG_IS_ENABLED(DM_SPI_FLASH) struct udevice *new; /* speed and mode will be read from DT */ diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 54881a74124..9559e938d26 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -4,7 +4,7 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. # There are many options which enable SPI, so make this library available -ifdef CONFIG_DM_SPI +ifdef CONFIG_$(SPL_TPL_)DM_SPI obj-y += spi-uclass.o obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o obj-$(CONFIG_SOFT_SPI) += soft_spi.o diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c index 3986b06b25c..c03923f8749 100644 --- a/drivers/spi/kirkwood_spi.c +++ b/drivers/spi/kirkwood_spi.c @@ -94,7 +94,7 @@ static int _spi_xfer(struct kwspi_registers *reg, unsigned int bitlen, return 0; } -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) static struct kwspi_registers *spireg = (struct kwspi_registers *)MVEBU_SPI_BASE; diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c index f52ebf4d67c..aad37803655 100644 --- a/drivers/spi/mxc_spi.c +++ b/drivers/spi/mxc_spi.c @@ -67,7 +67,7 @@ static inline struct mxc_spi_slave *to_mxc_spi_slave(struct spi_slave *slave) static void mxc_spi_cs_activate(struct mxc_spi_slave *mxcs) { -#if defined(CONFIG_DM_SPI) +#if CONFIG_IS_ENABLED(DM_SPI) struct udevice *dev = mxcs->dev; struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); @@ -85,7 +85,7 @@ static void mxc_spi_cs_activate(struct mxc_spi_slave *mxcs) static void mxc_spi_cs_deactivate(struct mxc_spi_slave *mxcs) { -#if defined(CONFIG_DM_SPI) +#if CONFIG_IS_ENABLED(DM_SPI) struct udevice *dev = mxcs->dev; struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); @@ -415,7 +415,7 @@ static int mxc_spi_claim_bus_internal(struct mxc_spi_slave *mxcs, int cs) return 0; } -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c index 6a615d1498e..ae08531f1ed 100644 --- a/drivers/spi/omap3_spi.c +++ b/drivers/spi/omap3_spi.c @@ -109,7 +109,7 @@ struct mcspi { }; struct omap3_spi_priv { -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) struct spi_slave slave; #endif struct mcspi *regs; @@ -455,7 +455,7 @@ static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv) writel(conf, &priv->regs->modulctrl); } -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) static inline struct omap3_spi_priv *to_omap3_spi(struct spi_slave *slave) { diff --git a/drivers/spi/sh_qspi.c b/drivers/spi/sh_qspi.c index 2839dd1cebd..aa1c03047e2 100644 --- a/drivers/spi/sh_qspi.c +++ b/drivers/spi/sh_qspi.c @@ -68,7 +68,7 @@ struct sh_qspi_regs { }; struct sh_qspi_slave { -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) struct spi_slave slave; #endif struct sh_qspi_regs *regs; @@ -223,7 +223,7 @@ static int sh_qspi_xfer_common(struct sh_qspi_slave *ss, unsigned int bitlen, return ret; } -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) static inline struct sh_qspi_slave *to_sh_qspi(struct spi_slave *slave) { return container_of(slave, struct sh_qspi_slave, slave); diff --git a/env/sf.c b/env/sf.c index 02ed846fc73..3e524f29479 100644 --- a/env/sf.c +++ b/env/sf.c @@ -38,7 +38,7 @@ static struct spi_flash *env_flash; static int setup_flash_device(void) { -#ifdef CONFIG_DM_SPI_FLASH +#if CONFIG_IS_ENABLED(DM_SPI_FLASH) struct udevice *new; int ret; diff --git a/include/spi.h b/include/spi.h index 5cc6d6e0087..9b4fb8dc0b2 100644 --- a/include/spi.h +++ b/include/spi.h @@ -39,7 +39,7 @@ #define SPI_DEFAULT_WORDLEN 8 -#ifdef CONFIG_DM_SPI +#if CONFIG_IS_ENABLED(DM_SPI) /* TODO(sjg@chromium.org): Remove this and use max_hz from struct spi_slave */ struct dm_spi_bus { uint max_hz; @@ -131,7 +131,7 @@ enum spi_polarity { * @flags: Indication of SPI flags. */ struct spi_slave { -#ifdef CONFIG_DM_SPI +#if CONFIG_IS_ENABLED(DM_SPI) struct udevice *dev; /* struct spi_slave is dev->parentdata */ uint max_hz; uint speed; @@ -317,7 +317,7 @@ void spi_flash_copy_mmap(void *data, void *offset, size_t len); */ int spi_cs_is_valid(unsigned int bus, unsigned int cs); -#ifndef CONFIG_DM_SPI +#if !CONFIG_IS_ENABLED(DM_SPI) /** * Activate a SPI chipselect. * This function is provided by the board code when using a driver @@ -367,7 +367,7 @@ static inline int spi_w8r8(struct spi_slave *slave, unsigned char byte) return ret < 0 ? ret : din[1]; } -#ifdef CONFIG_DM_SPI +#if CONFIG_IS_ENABLED(DM_SPI) /** * struct spi_cs_info - Information about a bus chip select diff --git a/include/spi_flash.h b/include/spi_flash.h index d9b2af856c0..b3366194876 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -39,7 +39,7 @@ struct dm_spi_flash_ops { /* Access the serial operations for a device */ #define sf_get_ops(dev) ((struct dm_spi_flash_ops *)(dev)->driver->ops) -#ifdef CONFIG_DM_SPI_FLASH +#if CONFIG_IS_ENABLED(DM_SPI_FLASH) /** * spi_flash_read_dm() - Read data from SPI flash * diff --git a/test/dm/spi.c b/test/dm/spi.c index 8e417acc5f2..474008cde0d 100644 --- a/test/dm/spi.c +++ b/test/dm/spi.c @@ -117,7 +117,7 @@ static int dm_test_spi_xfer(struct unit_test_state *uts) * Since we are about to destroy all devices, we must tell sandbox * to forget the emulation device */ -#ifdef CONFIG_DM_SPI_FLASH +#if CONFIG_IS_ENABLED(DM_SPI_FLASH) sandbox_sf_unbind_emul(state_get_current(), busnum, cs); #endif -- cgit v1.3.1 From 582b4f7f394da21fcb96a56e29dd68115a746b44 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Tue, 16 Jun 2020 19:06:31 -0400 Subject: Convert CONFIG_CADENCE_QSPI to Kconfig This converts the following to Kconfig: CONFIG_CADENCE_QSPI Signed-off-by: Tom Rini --- configs/k2g_evm_defconfig | 1 + configs/k2g_hs_evm_defconfig | 1 + drivers/spi/Makefile | 2 +- include/configs/k2g_evm.h | 1 - 4 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/configs/k2g_evm_defconfig b/configs/k2g_evm_defconfig index 766cae3d5b5..69cd22c7c8b 100644 --- a/configs/k2g_evm_defconfig +++ b/configs/k2g_evm_defconfig @@ -74,6 +74,7 @@ CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/k2g_hs_evm_defconfig b/configs/k2g_hs_evm_defconfig index f089be4f563..adedfddf4f5 100644 --- a/configs/k2g_hs_evm_defconfig +++ b/configs/k2g_hs_evm_defconfig @@ -62,6 +62,7 @@ CONFIG_DM_SERIAL=y CONFIG_SYS_NS16550=y CONFIG_SPI=y CONFIG_DM_SPI=y +CONFIG_CADENCE_QSPI=y CONFIG_DAVINCI_SPI=y CONFIG_USB=y CONFIG_DM_USB=y diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 9559e938d26..4e7461771f2 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -6,6 +6,7 @@ # There are many options which enable SPI, so make this library available ifdef CONFIG_$(SPL_TPL_)DM_SPI obj-y += spi-uclass.o +obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o obj-$(CONFIG_SOFT_SPI) += soft_spi.o obj-$(CONFIG_SPI_MEM) += spi-mem.o @@ -22,7 +23,6 @@ obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o obj-$(CONFIG_BCM63XX_HSSPI) += bcm63xx_hsspi.o obj-$(CONFIG_BCM63XX_SPI) += bcm63xx_spi.o obj-$(CONFIG_BCMSTB_SPI) += bcmstb_spi.o -obj-$(CONFIG_CADENCE_QSPI) += cadence_qspi.o cadence_qspi_apb.o obj-$(CONFIG_CF_SPI) += cf_spi.o obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o obj-$(CONFIG_DESIGNWARE_SPI) += designware_spi.o diff --git a/include/configs/k2g_evm.h b/include/configs/k2g_evm.h index 25f3959533c..83466b9e0cf 100644 --- a/include/configs/k2g_evm.h +++ b/include/configs/k2g_evm.h @@ -82,7 +82,6 @@ #define PHY_ANEG_TIMEOUT 10000 /* PHY needs longer aneg time */ #ifndef CONFIG_SPL_BUILD -#define CONFIG_CADENCE_QSPI #define CONFIG_CQSPI_REF_CLK 384000000 #endif -- cgit v1.3.1 From b9c52c50905cfd5973418e925e72c3bbefc7eb34 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:11 +0200 Subject: net: pcnet: Drop typedef struct pcnet_priv_t Use struct pcnet_priv all over the place instead. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 260a5a38cff..c6f080d956b 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -76,15 +76,15 @@ struct pcnet_uncached_priv { struct pcnet_init_block init_block; }; -typedef struct pcnet_priv { +struct pcnet_priv { struct pcnet_uncached_priv *uc; /* Receive Buffer space */ unsigned char (*rx_buf)[RX_RING_SIZE][PKT_BUF_SZ + 4]; int cur_rx; int cur_tx; -} pcnet_priv_t; +}; -static pcnet_priv_t *lp; +static struct pcnet_priv *lp; /* Offsets from base I/O address for WIO mode */ #define PCNET_RDP 0x10 @@ -340,9 +340,9 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * must be aligned on 16-byte boundaries. */ if (lp == NULL) { - addr = (unsigned long)malloc(sizeof(pcnet_priv_t) + 0x10); + addr = (unsigned long)malloc(sizeof(*lp) + 0x10); addr = (addr + 0xf) & ~0xf; - lp = (pcnet_priv_t *)addr; + lp = (struct pcnet_priv *)addr; addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, sizeof(*lp->uc)); -- cgit v1.3.1 From b92b8f48fb47c48b3f9df91ea1009b5789d55e19 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:12 +0200 Subject: net: pcnet: Drop PCNET_HAS_PROM All of one PCNET users has this option set, make this default and drop this config option. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 5 ----- include/configs/malta.h | 1 - 2 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index c6f080d956b..edc4dba24cb 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -241,10 +241,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) { int chip_version; char *chipname; - -#ifdef PCNET_HAS_PROM int i; -#endif /* Reset the PCnet controller */ pcnet_reset(dev); @@ -279,7 +276,6 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) PCNET_DEBUG1("AMD %s\n", chipname); -#ifdef PCNET_HAS_PROM /* * In most chips, after a chip reset, the ethernet address is read from * the station address PROM at the base address and programmed into the @@ -293,7 +289,6 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) dev->enetaddr[2 * i] = val & 0x0ff; dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; } -#endif /* PCNET_HAS_PROM */ return 0; } diff --git a/include/configs/malta.h b/include/configs/malta.h index 773d7c23ed8..82c90042d98 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -16,7 +16,6 @@ #define CONFIG_PCI_GT64120 #define CONFIG_PCI_MSC01 #define CONFIG_PCNET -#define PCNET_HAS_PROM #define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0 -- cgit v1.3.1 From d3b1df0f396adb2b5c25ff655c3dae8624c41e50 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:13 +0200 Subject: net: pcnet: Use PCI_DEVICE() to define PCI device compat list Use this macro to fully fill the PCI device ID table. This is mandatory for the DM PCI support, which checks all the fields. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index edc4dba24cb..e7ce79e952d 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -155,7 +155,7 @@ static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, } static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE}, + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE) }, {} }; -- cgit v1.3.1 From 89369b0ac2ca0621bfc30baed739bb9d9e7fdcad Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:14 +0200 Subject: net: pcnet: Simplify private data allocation The current code is horribly complex. Both the RX and TX buffer descriptors are 16 bytes in size, the init block is 32 bytes in size, so simplify the code such that the entire private data of the driver are allocated cache aligned and the RX and TX buffer descriptors are part of the private data. This removes multiple malloc calls and cache flushes. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index e7ce79e952d..72b93806244 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -74,12 +75,13 @@ struct pcnet_uncached_priv { struct pcnet_rx_head rx_ring[RX_RING_SIZE]; struct pcnet_tx_head tx_ring[TX_RING_SIZE]; struct pcnet_init_block init_block; -}; +} __aligned(ARCH_DMA_MINALIGN); struct pcnet_priv { - struct pcnet_uncached_priv *uc; + struct pcnet_uncached_priv ucp; /* Receive Buffer space */ - unsigned char (*rx_buf)[RX_RING_SIZE][PKT_BUF_SZ + 4]; + unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; + struct pcnet_uncached_priv *uc; int cur_rx; int cur_tx; }; @@ -335,22 +337,11 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * must be aligned on 16-byte boundaries. */ if (lp == NULL) { - addr = (unsigned long)malloc(sizeof(*lp) + 0x10); - addr = (addr + 0xf) & ~0xf; - lp = (struct pcnet_priv *)addr; - - addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, - sizeof(*lp->uc)); - flush_dcache_range(addr, addr + sizeof(*lp->uc)); - addr = (unsigned long)map_physmem(addr, - roundup(sizeof(*lp->uc), ARCH_DMA_MINALIGN), - MAP_NOCACHE); - lp->uc = (struct pcnet_uncached_priv *)addr; - - addr = (unsigned long)memalign(ARCH_DMA_MINALIGN, - sizeof(*lp->rx_buf)); - flush_dcache_range(addr, addr + sizeof(*lp->rx_buf)); - lp->rx_buf = (void *)addr; + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); } uc = lp->uc; @@ -364,7 +355,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ lp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { - addr = pcnet_virt_to_mem(dev, (*lp->rx_buf)[i]); + addr = pcnet_virt_to_mem(dev, lp->rx_buf[i]); uc->rx_ring[i].base = cpu_to_le32(addr); uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); uc->rx_ring[i].status = cpu_to_le16(0x8000); @@ -521,7 +512,7 @@ static int pcnet_recv (struct eth_device *dev) printf("%s: Rx%d: invalid packet length %d\n", dev->name, lp->cur_rx, pkt_len); } else { - buf = (*lp->rx_buf)[lp->cur_rx]; + buf = lp->rx_buf[lp->cur_rx]; invalidate_dcache_range((unsigned long)buf, (unsigned long)buf + pkt_len); net_process_received_packet(buf, pkt_len); -- cgit v1.3.1 From 0e11d79a533e3c874be1c5975abbc52aaba94d93 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:15 +0200 Subject: net: pcnet: Replace memset+malloc with calloc This combination of functions can be replaced with calloc(), make it so. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 72b93806244..b670cff2aae 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -184,12 +184,11 @@ int pcnet_initialize(bd_t *bis) /* * Allocate and pre-fill the device structure. */ - dev = (struct eth_device *)malloc(sizeof(*dev)); + dev = calloc(1, sizeof(*dev)); if (!dev) { printf("pcnet: Can not allocate memory\n"); break; } - memset(dev, 0, sizeof(*dev)); dev->priv = (void *)(unsigned long)devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr); -- cgit v1.3.1 From ada6a2cea5a0d44c3bd64713babd9d73eaf64863 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:16 +0200 Subject: net: pcnet: Move private data allocation to initialize The private data allocation does not have to be done every time the NIC is initialized at run time, move the allocation to initialize function, which means it will be done only once when the driver starts. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index b670cff2aae..073ffca6b62 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -189,6 +189,20 @@ int pcnet_initialize(bd_t *bis) printf("pcnet: Can not allocate memory\n"); break; } + + /* + * We only maintain one structure because the drivers will + * never be used concurrently. In 32bit mode the RX and TX + * ring entries must be aligned on 16-byte boundaries. + */ + if (!lp) { + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + } + dev->priv = (void *)(unsigned long)devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr); @@ -330,19 +344,6 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) val |= 0x3 << 10; pcnet_write_csr(dev, 80, val); - /* - * We only maintain one structure because the drivers will never - * be used concurrently. In 32bit mode the RX and TX ring entries - * must be aligned on 16-byte boundaries. - */ - if (lp == NULL) { - lp = malloc_cache_aligned(sizeof(*lp)); - lp->uc = map_physmem((phys_addr_t)&lp->ucp, - sizeof(lp->ucp), MAP_NOCACHE); - flush_dcache_range((unsigned long)lp, - (unsigned long)lp + sizeof(*lp)); - } - uc = lp->uc; uc->init_block.mode = cpu_to_le16(0x0000); -- cgit v1.3.1 From 54c6067486e576eea70020d743a0a19d5ad1e603 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:17 +0200 Subject: net: pcnet: Move initialize function at the end Move the function at the end of the driver, so we could drop various forward declarations later. No functional change. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 180 ++++++++++++++++++++++++++-------------------------- 1 file changed, 89 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 073ffca6b62..6d464cd0a4e 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -161,97 +161,6 @@ static struct pci_device_id supported[] = { {} }; - -int pcnet_initialize(bd_t *bis) -{ - pci_dev_t devbusfn; - struct eth_device *dev; - u16 command, status; - int dev_nr = 0; - u32 bar; - - PCNET_DEBUG1("\npcnet_initialize...\n"); - - for (dev_nr = 0;; dev_nr++) { - - /* - * Find the PCnet PCI device(s). - */ - devbusfn = pci_find_devices(supported, dev_nr); - if (devbusfn < 0) - break; - - /* - * Allocate and pre-fill the device structure. - */ - dev = calloc(1, sizeof(*dev)); - if (!dev) { - printf("pcnet: Can not allocate memory\n"); - break; - } - - /* - * We only maintain one structure because the drivers will - * never be used concurrently. In 32bit mode the RX and TX - * ring entries must be aligned on 16-byte boundaries. - */ - if (!lp) { - lp = malloc_cache_aligned(sizeof(*lp)); - lp->uc = map_physmem((phys_addr_t)&lp->ucp, - sizeof(lp->ucp), MAP_NOCACHE); - flush_dcache_range((unsigned long)lp, - (unsigned long)lp + sizeof(*lp)); - } - - dev->priv = (void *)(unsigned long)devbusfn; - sprintf(dev->name, "pcnet#%d", dev_nr); - - /* - * Setup the PCI device. - */ - pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar); - dev->iobase = pci_mem_to_phys(devbusfn, bar); - dev->iobase &= ~0xf; - - PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", - dev->name, devbusfn, (unsigned long)dev->iobase); - - command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_write_config_word(devbusfn, PCI_COMMAND, command); - pci_read_config_word(devbusfn, PCI_COMMAND, &status); - if ((status & command) != command) { - printf("%s: Couldn't enable IO access or Bus Mastering\n", - dev->name); - free(dev); - continue; - } - - pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40); - - /* - * Probe the PCnet chip. - */ - if (pcnet_probe(dev, bis, dev_nr) < 0) { - free(dev); - continue; - } - - /* - * Setup device structure and register the driver. - */ - dev->init = pcnet_init; - dev->halt = pcnet_halt; - dev->send = pcnet_send; - dev->recv = pcnet_recv; - - eth_register(dev); - } - - udelay(10 * 1000); - - return dev_nr; -} - static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) { int chip_version; @@ -548,3 +457,92 @@ static void pcnet_halt(struct eth_device *dev) if (i <= 0) printf("%s: TIMEOUT: controller reset failed\n", dev->name); } + +int pcnet_initialize(bd_t *bis) +{ + pci_dev_t devbusfn; + struct eth_device *dev; + u16 command, status; + int dev_nr = 0; + u32 bar; + + PCNET_DEBUG1("\npcnet_initialize...\n"); + + for (dev_nr = 0; ; dev_nr++) { + /* + * Find the PCnet PCI device(s). + */ + devbusfn = pci_find_devices(supported, dev_nr); + if (devbusfn < 0) + break; + + /* + * Allocate and pre-fill the device structure. + */ + dev = calloc(1, sizeof(*dev)); + if (!dev) { + printf("pcnet: Can not allocate memory\n"); + break; + } + + /* + * We only maintain one structure because the drivers will + * never be used concurrently. In 32bit mode the RX and TX + * ring entries must be aligned on 16-byte boundaries. + */ + if (!lp) { + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + } + + dev->priv = (void *)(unsigned long)devbusfn; + sprintf(dev->name, "pcnet#%d", dev_nr); + + /* + * Setup the PCI device. + */ + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar); + dev->iobase = pci_mem_to_phys(devbusfn, bar); + dev->iobase &= ~0xf; + + PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", + dev->name, devbusfn, (unsigned long)dev->iobase); + + command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + pci_write_config_word(devbusfn, PCI_COMMAND, command); + pci_read_config_word(devbusfn, PCI_COMMAND, &status); + if ((status & command) != command) { + printf("%s: Couldn't enable IO access or Bus Mastering\n", + dev->name); + free(dev); + continue; + } + + pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40); + + /* + * Probe the PCnet chip. + */ + if (pcnet_probe(dev, bis, dev_nr) < 0) { + free(dev); + continue; + } + + /* + * Setup device structure and register the driver. + */ + dev->init = pcnet_init; + dev->halt = pcnet_halt; + dev->send = pcnet_send; + dev->recv = pcnet_recv; + + eth_register(dev); + } + + udelay(10 * 1000); + + return dev_nr; +} -- cgit v1.3.1 From 553286a63ca5e60beb4cf5af68795c7d78a19ceb Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:18 +0200 Subject: net: pcnet: Drop useless forward declarations Remove those as they are not needed anymore. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 6d464cd0a4e..d8249f0a1cf 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -141,12 +141,6 @@ static int pcnet_check(struct eth_device *dev) return readw(base + PCNET_RAP) == 88; } -static int pcnet_init (struct eth_device *dev, bd_t * bis); -static int pcnet_send(struct eth_device *dev, void *packet, int length); -static int pcnet_recv (struct eth_device *dev); -static void pcnet_halt (struct eth_device *dev); -static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num); - static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, void *addr) { -- cgit v1.3.1 From ab6ecbdc3c25761756538129c26d1396dd5b02a9 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:19 +0200 Subject: net: pcnet: Wrap devbusfn into private data Instead of using eth_device priv for this PCI devbusfn, free it so it could be used for driver private data, and wrap devbusfn into those driver private data. Note that using the name dev for the variable is a trick left for later, when DM support is in place, so dm_pci_virt_to_mem() can be used with minimal ifdeffery. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index d8249f0a1cf..f7f1b8fc21f 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -82,6 +82,7 @@ struct pcnet_priv { /* Receive Buffer space */ unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; struct pcnet_uncached_priv *uc; + pci_dev_t dev; int cur_rx; int cur_tx; }; @@ -141,13 +142,11 @@ static int pcnet_check(struct eth_device *dev) return readw(base + PCNET_RAP) == 88; } -static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev, - void *addr) +static inline pci_addr_t pcnet_virt_to_mem(struct pcnet_priv *lp, void *addr) { - pci_dev_t devbusfn = (pci_dev_t)(unsigned long)dev->priv; void *virt_addr = addr; - return pci_virt_to_mem(devbusfn, virt_addr); + return pci_virt_to_mem(lp->dev, virt_addr); } static struct pci_device_id supported[] = { @@ -258,7 +257,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ lp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { - addr = pcnet_virt_to_mem(dev, lp->rx_buf[i]); + addr = pcnet_virt_to_mem(lp, lp->rx_buf[i]); uc->rx_ring[i].base = cpu_to_le32(addr); uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); uc->rx_ring[i].status = cpu_to_le16(0x8000); @@ -290,9 +289,9 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) uc->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS | RX_RING_LEN_BITS); - addr = pcnet_virt_to_mem(dev, uc->rx_ring); + addr = pcnet_virt_to_mem(lp, uc->rx_ring); uc->init_block.rx_ring = cpu_to_le32(addr); - addr = pcnet_virt_to_mem(dev, uc->tx_ring); + addr = pcnet_virt_to_mem(lp, uc->tx_ring); uc->init_block.tx_ring = cpu_to_le32(addr); PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", @@ -303,7 +302,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * Tell the controller where the Init Block is located. */ barrier(); - addr = pcnet_virt_to_mem(dev, &lp->uc->init_block); + addr = pcnet_virt_to_mem(lp, &lp->uc->init_block); pcnet_write_csr(dev, 1, addr & 0xffff); pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); @@ -361,7 +360,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) * Setup Tx ring. Caution: the write order is important here, * set the status with the "ownership" bits last. */ - addr = pcnet_virt_to_mem(dev, packet); + addr = pcnet_virt_to_mem(lp, packet); writew(-pkt_len, &entry->length); writel(0, &entry->misc); writel(addr, &entry->base); @@ -492,7 +491,7 @@ int pcnet_initialize(bd_t *bis) (unsigned long)lp + sizeof(*lp)); } - dev->priv = (void *)(unsigned long)devbusfn; + lp->dev = devbusfn; sprintf(dev->name, "pcnet#%d", dev_nr); /* -- cgit v1.3.1 From 834d5cebe582eb71a2c76fc5c9078a3a85b1cafe Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:20 +0200 Subject: net: pcnet: Pass private data through dev->priv Get rid of the global point to private data, and rather pass it thought dev->priv. Also remove the unnecessary check for lp being non-NULL, since it is always NULL at this point. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index f7f1b8fc21f..dab08c07add 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -87,8 +87,6 @@ struct pcnet_priv { int cur_tx; }; -static struct pcnet_priv *lp; - /* Offsets from base I/O address for WIO mode */ #define PCNET_RDP 0x10 #define PCNET_RAP 0x12 @@ -212,6 +210,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) static int pcnet_init(struct eth_device *dev, bd_t *bis) { + struct pcnet_priv *lp = dev->priv; struct pcnet_uncached_priv *uc; int i, val; unsigned long addr; @@ -331,6 +330,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) { + struct pcnet_priv *lp = dev->priv; int i, status; u32 addr; struct pcnet_tx_head *entry = &lp->uc->tx_ring[lp->cur_tx]; @@ -379,6 +379,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) static int pcnet_recv (struct eth_device *dev) { + struct pcnet_priv *lp = dev->priv; struct pcnet_rx_head *entry; unsigned char *buf; int pkt_len = 0; @@ -455,6 +456,7 @@ int pcnet_initialize(bd_t *bis) { pci_dev_t devbusfn; struct eth_device *dev; + struct pcnet_priv *lp; u16 command, status; int dev_nr = 0; u32 bar; @@ -483,15 +485,13 @@ int pcnet_initialize(bd_t *bis) * never be used concurrently. In 32bit mode the RX and TX * ring entries must be aligned on 16-byte boundaries. */ - if (!lp) { - lp = malloc_cache_aligned(sizeof(*lp)); - lp->uc = map_physmem((phys_addr_t)&lp->ucp, - sizeof(lp->ucp), MAP_NOCACHE); - flush_dcache_range((unsigned long)lp, - (unsigned long)lp + sizeof(*lp)); - } - + lp = malloc_cache_aligned(sizeof(*lp)); + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); lp->dev = devbusfn; + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + dev->priv = lp; sprintf(dev->name, "pcnet#%d", dev_nr); /* -- cgit v1.3.1 From deca77382114364ca476482ad3e8bd431578fea8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:21 +0200 Subject: net: pcnet: Wrap iobase into private data Instead of using the non-DM-only iobase in struct eth_device, add one into the private data to make DM and non-DM operation possible. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 103 +++++++++++++++++++++++----------------------------- 1 file changed, 46 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index dab08c07add..b0bd4af2039 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -83,6 +83,7 @@ struct pcnet_priv { unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; struct pcnet_uncached_priv *uc; pci_dev_t dev; + void __iomem *iobase; int cur_rx; int cur_tx; }; @@ -93,51 +94,39 @@ struct pcnet_priv { #define PCNET_RESET 0x14 #define PCNET_BDP 0x16 -static u16 pcnet_read_csr(struct eth_device *dev, int index) +static u16 pcnet_read_csr(struct pcnet_priv *lp, int index) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - return readw(base + PCNET_RDP); + writew(index, lp->iobase + PCNET_RAP); + return readw(lp->iobase + PCNET_RDP); } -static void pcnet_write_csr(struct eth_device *dev, int index, u16 val) +static void pcnet_write_csr(struct pcnet_priv *lp, int index, u16 val) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - writew(val, base + PCNET_RDP); + writew(index, lp->iobase + PCNET_RAP); + writew(val, lp->iobase + PCNET_RDP); } -static u16 pcnet_read_bcr(struct eth_device *dev, int index) +static u16 pcnet_read_bcr(struct pcnet_priv *lp, int index) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - return readw(base + PCNET_BDP); + writew(index, lp->iobase + PCNET_RAP); + return readw(lp->iobase + PCNET_BDP); } -static void pcnet_write_bcr(struct eth_device *dev, int index, u16 val) +static void pcnet_write_bcr(struct pcnet_priv *lp, int index, u16 val) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(index, base + PCNET_RAP); - writew(val, base + PCNET_BDP); + writew(index, lp->iobase + PCNET_RAP); + writew(val, lp->iobase + PCNET_BDP); } -static void pcnet_reset(struct eth_device *dev) +static void pcnet_reset(struct pcnet_priv *lp) { - void __iomem *base = (void __iomem *)dev->iobase; - - readw(base + PCNET_RESET); + readw(lp->iobase + PCNET_RESET); } -static int pcnet_check(struct eth_device *dev) +static int pcnet_check(struct pcnet_priv *lp) { - void __iomem *base = (void __iomem *)dev->iobase; - - writew(88, base + PCNET_RAP); - return readw(base + PCNET_RAP) == 88; + writew(88, lp->iobase + PCNET_RAP); + return readw(lp->iobase + PCNET_RAP) == 88; } static inline pci_addr_t pcnet_virt_to_mem(struct pcnet_priv *lp, void *addr) @@ -154,22 +143,22 @@ static struct pci_device_id supported[] = { static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) { + struct pcnet_priv *lp = dev->priv; int chip_version; char *chipname; int i; /* Reset the PCnet controller */ - pcnet_reset(dev); + pcnet_reset(lp); /* Check if register access is working */ - if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) { + if (pcnet_read_csr(lp, 0) != 4 || !pcnet_check(lp)) { printf("%s: CSR register access check failed\n", dev->name); return -1; } /* Identify the chip */ - chip_version = - pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev, 89) << 16); + chip_version = pcnet_read_csr(lp, 88) | (pcnet_read_csr(lp, 89) << 16); if ((chip_version & 0xfff) != 0x003) return -1; chip_version = (chip_version >> 12) & 0xffff; @@ -199,7 +188,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) for (i = 0; i < 3; i++) { unsigned int val; - val = pcnet_read_csr(dev, i + 12) & 0x0ffff; + val = pcnet_read_csr(lp, i + 12) & 0x0ffff; /* There may be endianness issues here. */ dev->enetaddr[2 * i] = val & 0x0ff; dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; @@ -218,17 +207,17 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) PCNET_DEBUG1("%s: pcnet_init...\n", dev->name); /* Switch pcnet to 32bit mode */ - pcnet_write_bcr(dev, 20, 2); + pcnet_write_bcr(lp, 20, 2); /* Set/reset autoselect bit */ - val = pcnet_read_bcr(dev, 2) & ~2; + val = pcnet_read_bcr(lp, 2) & ~2; val |= 2; - pcnet_write_bcr(dev, 2, val); + pcnet_write_bcr(lp, 2, val); /* Enable auto negotiate, setup, disable fd */ - val = pcnet_read_bcr(dev, 32) & ~0x98; + val = pcnet_read_bcr(lp, 32) & ~0x98; val |= 0x20; - pcnet_write_bcr(dev, 32, val); + pcnet_write_bcr(lp, 32, val); /* * Enable NOUFLO on supported controllers, with the transmit @@ -238,12 +227,12 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) * slower devices. Controllers which do not support NOUFLO will * simply be left with a larger transmit FIFO threshold. */ - val = pcnet_read_bcr(dev, 18); + val = pcnet_read_bcr(lp, 18); val |= 1 << 11; - pcnet_write_bcr(dev, 18, val); - val = pcnet_read_csr(dev, 80); + pcnet_write_bcr(lp, 18, val); + val = pcnet_read_csr(lp, 80); val |= 0x3 << 10; - pcnet_write_csr(dev, 80, val); + pcnet_write_csr(lp, 80, val); uc = lp->uc; @@ -302,28 +291,28 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) */ barrier(); addr = pcnet_virt_to_mem(lp, &lp->uc->init_block); - pcnet_write_csr(dev, 1, addr & 0xffff); - pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); + pcnet_write_csr(lp, 1, addr & 0xffff); + pcnet_write_csr(lp, 2, (addr >> 16) & 0xffff); - pcnet_write_csr(dev, 4, 0x0915); - pcnet_write_csr(dev, 0, 0x0001); /* start */ + pcnet_write_csr(lp, 4, 0x0915); + pcnet_write_csr(lp, 0, 0x0001); /* start */ /* Wait for Init Done bit */ for (i = 10000; i > 0; i--) { - if (pcnet_read_csr(dev, 0) & 0x0100) + if (pcnet_read_csr(lp, 0) & 0x0100) break; udelay(10); } if (i <= 0) { printf("%s: TIMEOUT: controller init failed\n", dev->name); - pcnet_reset(dev); + pcnet_reset(lp); return -1; } /* * Finally start network controller operation. */ - pcnet_write_csr(dev, 0, 0x0002); + pcnet_write_csr(lp, 0, 0x0002); return 0; } @@ -367,7 +356,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) writew(0x8300, &entry->status); /* Trigger an immediate send poll. */ - pcnet_write_csr(dev, 0, 0x0008); + pcnet_write_csr(lp, 0, 0x0008); failure: if (++lp->cur_tx >= TX_RING_SIZE) @@ -435,16 +424,17 @@ static int pcnet_recv (struct eth_device *dev) static void pcnet_halt(struct eth_device *dev) { + struct pcnet_priv *lp = dev->priv; int i; PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name); /* Reset the PCnet controller */ - pcnet_reset(dev); + pcnet_reset(lp); /* Wait for Stop bit */ for (i = 1000; i > 0; i--) { - if (pcnet_read_csr(dev, 0) & 0x4) + if (pcnet_read_csr(lp, 0) & 0x4) break; udelay(10); } @@ -498,11 +488,10 @@ int pcnet_initialize(bd_t *bis) * Setup the PCI device. */ pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_1, &bar); - dev->iobase = pci_mem_to_phys(devbusfn, bar); - dev->iobase &= ~0xf; + lp->iobase = (void *)(pci_mem_to_phys(devbusfn, bar) & ~0xf); - PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%lx: ", - dev->name, devbusfn, (unsigned long)dev->iobase); + PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%p: ", + dev->name, devbusfn, lp->iobase); command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, command); -- cgit v1.3.1 From 6d76c9f1e6df5338aeaa8699e16ea3bb755f858d Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:22 +0200 Subject: net: pcnet: Wrap name and enetaddr into private data Instead of using the non-DM-only name and enetaddr in struct eth_device, add pointers into the private data which can either point to that non-DM name or a DM one later on. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index b0bd4af2039..669b2561789 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -84,6 +84,8 @@ struct pcnet_priv { struct pcnet_uncached_priv *uc; pci_dev_t dev; void __iomem *iobase; + char *name; + u8 *enetaddr; int cur_rx; int cur_tx; }; @@ -153,7 +155,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) /* Check if register access is working */ if (pcnet_read_csr(lp, 0) != 4 || !pcnet_check(lp)) { - printf("%s: CSR register access check failed\n", dev->name); + printf("%s: CSR register access check failed\n", lp->name); return -1; } @@ -174,7 +176,7 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) break; default: printf("%s: PCnet version %#x not supported\n", - dev->name, chip_version); + lp->name, chip_version); return -1; } @@ -190,8 +192,8 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) val = pcnet_read_csr(lp, i + 12) & 0x0ffff; /* There may be endianness issues here. */ - dev->enetaddr[2 * i] = val & 0x0ff; - dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; + lp->enetaddr[2 * i] = val & 0x0ff; + lp->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; } return 0; @@ -204,7 +206,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) int i, val; unsigned long addr; - PCNET_DEBUG1("%s: pcnet_init...\n", dev->name); + PCNET_DEBUG1("%s: %s...\n", lp->name, __func__); /* Switch pcnet to 32bit mode */ pcnet_write_bcr(lp, 20, 2); @@ -271,7 +273,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) PCNET_DEBUG1("Init block at 0x%p: MAC", &lp->uc->init_block); for (i = 0; i < 6; i++) { - lp->uc->init_block.phys_addr[i] = dev->enetaddr[i]; + lp->uc->init_block.phys_addr[i] = lp->enetaddr[i]; PCNET_DEBUG1(" %02x", lp->uc->init_block.phys_addr[i]); } @@ -304,7 +306,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) udelay(10); } if (i <= 0) { - printf("%s: TIMEOUT: controller init failed\n", dev->name); + printf("%s: TIMEOUT: controller init failed\n", lp->name); pcnet_reset(lp); return -1; } @@ -340,7 +342,7 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) } if (i <= 0) { printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n", - dev->name, lp->cur_tx, status); + lp->name, lp->cur_tx, status); pkt_len = 0; goto failure; } @@ -385,7 +387,7 @@ static int pcnet_recv (struct eth_device *dev) err_status = status >> 8; if (err_status != 0x03) { /* There was an error. */ - printf("%s: Rx%d", dev->name, lp->cur_rx); + printf("%s: Rx%d", lp->name, lp->cur_rx); PCNET_DEBUG1(" (status=0x%x)", err_status); if (err_status & 0x20) printf(" Frame"); @@ -402,7 +404,7 @@ static int pcnet_recv (struct eth_device *dev) pkt_len = (readl(&entry->msg_length) & 0xfff) - 4; if (pkt_len < 60) { printf("%s: Rx%d: invalid packet length %d\n", - dev->name, lp->cur_rx, pkt_len); + lp->name, lp->cur_rx, pkt_len); } else { buf = lp->rx_buf[lp->cur_rx]; invalidate_dcache_range((unsigned long)buf, @@ -427,7 +429,7 @@ static void pcnet_halt(struct eth_device *dev) struct pcnet_priv *lp = dev->priv; int i; - PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name); + PCNET_DEBUG1("%s: %s...\n", lp->name, __func__); /* Reset the PCnet controller */ pcnet_reset(lp); @@ -439,7 +441,7 @@ static void pcnet_halt(struct eth_device *dev) udelay(10); } if (i <= 0) - printf("%s: TIMEOUT: controller reset failed\n", dev->name); + printf("%s: TIMEOUT: controller reset failed\n", lp->name); } int pcnet_initialize(bd_t *bis) @@ -451,7 +453,7 @@ int pcnet_initialize(bd_t *bis) int dev_nr = 0; u32 bar; - PCNET_DEBUG1("\npcnet_initialize...\n"); + PCNET_DEBUG1("\n%s...\n", __func__); for (dev_nr = 0; ; dev_nr++) { /* @@ -483,6 +485,8 @@ int pcnet_initialize(bd_t *bis) (unsigned long)lp + sizeof(*lp)); dev->priv = lp; sprintf(dev->name, "pcnet#%d", dev_nr); + lp->name = dev->name; + lp->enetaddr = dev->enetaddr; /* * Setup the PCI device. @@ -491,14 +495,14 @@ int pcnet_initialize(bd_t *bis) lp->iobase = (void *)(pci_mem_to_phys(devbusfn, bar) & ~0xf); PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%p: ", - dev->name, devbusfn, lp->iobase); + lp->name, devbusfn, lp->iobase); command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; pci_write_config_word(devbusfn, PCI_COMMAND, command); pci_read_config_word(devbusfn, PCI_COMMAND, &status); if ((status & command) != command) { printf("%s: Couldn't enable IO access or Bus Mastering\n", - dev->name); + lp->name); free(dev); continue; } -- cgit v1.3.1 From f5e7df58e0b96f97e1d8ef49415401a51e9f18b8 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:23 +0200 Subject: net: pcnet: Split common and non-DM functions Pull the common parts of functions out so they can be reused by both DM and non-DM code paths. The recv() function had to be reworked to fit into this scheme and this means it now only receives one packet at a time instead of spinning in an endless loop. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 149 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 94 insertions(+), 55 deletions(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 669b2561789..0a4cab82087 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -86,6 +86,7 @@ struct pcnet_priv { void __iomem *iobase; char *name; u8 *enetaddr; + u16 status; int cur_rx; int cur_tx; }; @@ -143,9 +144,8 @@ static struct pci_device_id supported[] = { {} }; -static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) +static int pcnet_probe_common(struct pcnet_priv *lp) { - struct pcnet_priv *lp = dev->priv; int chip_version; char *chipname; int i; @@ -199,9 +199,8 @@ static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) return 0; } -static int pcnet_init(struct eth_device *dev, bd_t *bis) +static int pcnet_init_common(struct pcnet_priv *lp) { - struct pcnet_priv *lp = dev->priv; struct pcnet_uncached_priv *uc; int i, val; unsigned long addr; @@ -319,9 +318,8 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis) return 0; } -static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) +static int pcnet_send_common(struct pcnet_priv *lp, void *packet, int pkt_len) { - struct pcnet_priv *lp = dev->priv; int i, status; u32 addr; struct pcnet_tx_head *entry = &lp->uc->tx_ring[lp->cur_tx]; @@ -368,65 +366,70 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) return pkt_len; } -static int pcnet_recv (struct eth_device *dev) +static int pcnet_recv_common(struct pcnet_priv *lp, unsigned char **bufp) { - struct pcnet_priv *lp = dev->priv; struct pcnet_rx_head *entry; unsigned char *buf; int pkt_len = 0; - u16 status, err_status; + u16 err_status; - while (1) { - entry = &lp->uc->rx_ring[lp->cur_rx]; - /* - * If we own the next entry, it's a new packet. Send it up. - */ - status = readw(&entry->status); - if ((status & 0x8000) != 0) - break; - err_status = status >> 8; - - if (err_status != 0x03) { /* There was an error. */ - printf("%s: Rx%d", lp->name, lp->cur_rx); - PCNET_DEBUG1(" (status=0x%x)", err_status); - if (err_status & 0x20) - printf(" Frame"); - if (err_status & 0x10) - printf(" Overflow"); - if (err_status & 0x08) - printf(" CRC"); - if (err_status & 0x04) - printf(" Fifo"); - printf(" Error\n"); - status &= 0x03ff; - - } else { - pkt_len = (readl(&entry->msg_length) & 0xfff) - 4; - if (pkt_len < 60) { - printf("%s: Rx%d: invalid packet length %d\n", - lp->name, lp->cur_rx, pkt_len); - } else { - buf = lp->rx_buf[lp->cur_rx]; - invalidate_dcache_range((unsigned long)buf, - (unsigned long)buf + pkt_len); - net_process_received_packet(buf, pkt_len); - PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", - lp->cur_rx, pkt_len, buf); - } - } - - status |= 0x8000; - writew(status, &entry->status); + entry = &lp->uc->rx_ring[lp->cur_rx]; + /* + * If we own the next entry, it's a new packet. Send it up. + */ + lp->status = readw(&entry->status); + if ((lp->status & 0x8000) != 0) + return 0; + err_status = lp->status >> 8; + + if (err_status != 0x03) { /* There was an error. */ + printf("%s: Rx%d", lp->name, lp->cur_rx); + PCNET_DEBUG1(" (status=0x%x)", err_status); + if (err_status & 0x20) + printf(" Frame"); + if (err_status & 0x10) + printf(" Overflow"); + if (err_status & 0x08) + printf(" CRC"); + if (err_status & 0x04) + printf(" Fifo"); + printf(" Error\n"); + lp->status &= 0x03ff; + return 0; + } - if (++lp->cur_rx >= RX_RING_SIZE) - lp->cur_rx = 0; + pkt_len = (readl(&entry->msg_length) & 0xfff) - 4; + if (pkt_len < 60) { + printf("%s: Rx%d: invalid packet length %d\n", + lp->name, lp->cur_rx, pkt_len); + return 0; } + + *bufp = lp->rx_buf[lp->cur_rx]; + invalidate_dcache_range((unsigned long)*bufp, + (unsigned long)*bufp + pkt_len); + + PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", + lp->cur_rx, pkt_len, buf); + return pkt_len; } -static void pcnet_halt(struct eth_device *dev) +static void pcnet_free_pkt_common(struct pcnet_priv *lp, unsigned int len) +{ + struct pcnet_rx_head *entry; + + entry = &lp->uc->rx_ring[lp->cur_rx]; + + lp->status |= 0x8000; + writew(lp->status, &entry->status); + + if (++lp->cur_rx >= RX_RING_SIZE) + lp->cur_rx = 0; +} + +static void pcnet_halt_common(struct pcnet_priv *lp) { - struct pcnet_priv *lp = dev->priv; int i; PCNET_DEBUG1("%s: %s...\n", lp->name, __func__); @@ -444,6 +447,42 @@ static void pcnet_halt(struct eth_device *dev) printf("%s: TIMEOUT: controller reset failed\n", lp->name); } +static int pcnet_init(struct eth_device *dev, bd_t *bis) +{ + struct pcnet_priv *lp = dev->priv; + + return pcnet_init_common(lp); +} + +static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) +{ + struct pcnet_priv *lp = dev->priv; + + return pcnet_send_common(lp, packet, pkt_len); +} + +static int pcnet_recv(struct eth_device *dev) +{ + struct pcnet_priv *lp = dev->priv; + uchar *packet; + int ret; + + ret = pcnet_recv_common(lp, &packet); + if (ret > 0) + net_process_received_packet(packet, ret); + if (ret) + pcnet_free_pkt_common(lp, ret); + + return ret; +} + +static void pcnet_halt(struct eth_device *dev) +{ + struct pcnet_priv *lp = dev->priv; + + pcnet_halt_common(lp); +} + int pcnet_initialize(bd_t *bis) { pci_dev_t devbusfn; @@ -512,7 +551,7 @@ int pcnet_initialize(bd_t *bis) /* * Probe the PCnet chip. */ - if (pcnet_probe(dev, bis, dev_nr) < 0) { + if (pcnet_probe_common(lp) < 0) { free(dev); continue; } -- cgit v1.3.1 From 53019cf35b5ccf9cb5ad8269acab494b99a3dc0c Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:24 +0200 Subject: net: pcnet: Add DM support With all the changes in place, add support for DM into the pcnet driver. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- drivers/net/pcnet.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 0a4cab82087..8e3e3dbbcee 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -82,9 +83,14 @@ struct pcnet_priv { /* Receive Buffer space */ unsigned char rx_buf[RX_RING_SIZE][PKT_BUF_SZ + 4]; struct pcnet_uncached_priv *uc; +#ifdef CONFIG_DM_ETH + struct udevice *dev; + const char *name; +#else pci_dev_t dev; - void __iomem *iobase; char *name; +#endif + void __iomem *iobase; u8 *enetaddr; u16 status; int cur_rx; @@ -136,7 +142,11 @@ static inline pci_addr_t pcnet_virt_to_mem(struct pcnet_priv *lp, void *addr) { void *virt_addr = addr; +#ifdef CONFIG_DM_ETH + return dm_pci_virt_to_mem(lp->dev, virt_addr); +#else return pci_virt_to_mem(lp->dev, virt_addr); +#endif } static struct pci_device_id supported[] = { @@ -447,6 +457,7 @@ static void pcnet_halt_common(struct pcnet_priv *lp) printf("%s: TIMEOUT: controller reset failed\n", lp->name); } +#ifndef CONFIG_DM_ETH static int pcnet_init(struct eth_device *dev, bd_t *bis) { struct pcnet_priv *lp = dev->priv; @@ -571,3 +582,117 @@ int pcnet_initialize(bd_t *bis) return dev_nr; } +#else /* DM_ETH */ +static int pcnet_start(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct pcnet_priv *priv = dev_get_priv(dev); + + memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr)); + + return pcnet_init_common(priv); +} + +static void pcnet_stop(struct udevice *dev) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + + pcnet_halt_common(priv); +} + +static int pcnet_send(struct udevice *dev, void *packet, int length) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + int ret; + + ret = pcnet_send_common(priv, packet, length); + + return ret ? 0 : -ETIMEDOUT; +} + +static int pcnet_recv(struct udevice *dev, int flags, uchar **packetp) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + + return pcnet_recv_common(priv, packetp); +} + +static int pcnet_free_pkt(struct udevice *dev, uchar *packet, int length) +{ + struct pcnet_priv *priv = dev_get_priv(dev); + + pcnet_free_pkt_common(priv, length); + + return 0; +} + +static int pcnet_bind(struct udevice *dev) +{ + static int card_number; + char name[16]; + + sprintf(name, "pcnet#%u", card_number++); + + return device_set_name(dev, name); +} + +static int pcnet_probe(struct udevice *dev) +{ + struct eth_pdata *plat = dev_get_platdata(dev); + struct pcnet_priv *lp = dev_get_priv(dev); + u16 command, status; + u32 iobase; + int ret; + + dm_pci_read_config32(dev, PCI_BASE_ADDRESS_1, &iobase); + iobase &= ~0xf; + + lp->uc = map_physmem((phys_addr_t)&lp->ucp, + sizeof(lp->ucp), MAP_NOCACHE); + lp->dev = dev; + lp->name = dev->name; + lp->enetaddr = plat->enetaddr; + lp->iobase = (void *)dm_pci_mem_to_phys(dev, iobase); + + flush_dcache_range((unsigned long)lp, + (unsigned long)lp + sizeof(*lp)); + + command = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + dm_pci_write_config16(dev, PCI_COMMAND, command); + dm_pci_read_config16(dev, PCI_COMMAND, &status); + if ((status & command) != command) { + printf("%s: Couldn't enable IO access or Bus Mastering\n", + lp->name); + return -EINVAL; + } + + dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x20); + + ret = pcnet_probe_common(lp); + if (ret) + return ret; + + return 0; +} + +static const struct eth_ops pcnet_ops = { + .start = pcnet_start, + .send = pcnet_send, + .recv = pcnet_recv, + .stop = pcnet_stop, + .free_pkt = pcnet_free_pkt, +}; + +U_BOOT_DRIVER(eth_pcnet) = { + .name = "eth_pcnet", + .id = UCLASS_ETH, + .bind = pcnet_bind, + .probe = pcnet_probe, + .ops = &pcnet_ops, + .priv_auto_alloc_size = sizeof(struct pcnet_priv), + .platdata_auto_alloc_size = sizeof(struct eth_pdata), + .flags = DM_UC_FLAG_ALLOC_PRIV_DMA, +}; + +U_BOOT_PCI_DEVICE(eth_pcnet, supported); +#endif -- cgit v1.3.1 From d8553d6ee3146bc06b8f86787138293d3f6453c3 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sun, 17 May 2020 18:24:25 +0200 Subject: net: pcnet: Add Kconfig entries Add Kconfig entries for the pcnet driver and convert MIPS malta to use those. Signed-off-by: Marek Vasut Cc: Daniel Schwierzeck Cc: Joe Hershberger --- configs/malta64_defconfig | 1 + configs/malta64el_defconfig | 1 + configs/malta_defconfig | 1 + configs/maltael_defconfig | 1 + drivers/net/Kconfig | 6 ++++++ include/configs/malta.h | 1 - 6 files changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/configs/malta64_defconfig b/configs/malta64_defconfig index e5a19a6e546..a16abc7fa9c 100644 --- a/configs/malta64_defconfig +++ b/configs/malta64_defconfig @@ -27,6 +27,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/configs/malta64el_defconfig b/configs/malta64el_defconfig index e9de5bea6e1..a9efe7736e5 100644 --- a/configs/malta64el_defconfig +++ b/configs/malta64el_defconfig @@ -28,6 +28,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/configs/malta_defconfig b/configs/malta_defconfig index 2b43818c81f..0680f595dbd 100644 --- a/configs/malta_defconfig +++ b/configs/malta_defconfig @@ -26,6 +26,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/configs/maltael_defconfig b/configs/maltael_defconfig index ec984b5a356..31c9ff6a777 100644 --- a/configs/maltael_defconfig +++ b/configs/maltael_defconfig @@ -27,6 +27,7 @@ CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y CONFIG_SYS_FLASH_CFI=y +CONFIG_PCNET=y CONFIG_PCI=y CONFIG_RTC_MC146818=y CONFIG_SYS_NS16550=y diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index bb23f73fc23..19703d42cd6 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -392,6 +392,12 @@ config MII help Enable support of the Media-Independent Interface (MII) +config PCNET + bool "AMD PCnet series Ethernet controller driver" + help + This driver supports AMD PCnet series fast ethernet family of + PCI chipsets/adapters. + config RTL8139 bool "Realtek 8139 series Ethernet controller driver" help diff --git a/include/configs/malta.h b/include/configs/malta.h index 82c90042d98..9602773ff91 100644 --- a/include/configs/malta.h +++ b/include/configs/malta.h @@ -15,7 +15,6 @@ #define CONFIG_PCI_GT64120 #define CONFIG_PCI_MSC01 -#define CONFIG_PCNET #define CONFIG_SYS_ISA_IO_BASE_ADDRESS 0 -- cgit v1.3.1 From f5624b104541a6c198b78958581f7e871ef2bb77 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Mon, 20 May 2019 02:44:53 +0200 Subject: mmc: add missing space before comment delimiter Add missing space before a comment delimiter. Signed-off-by: Marcel Ziswiler Reviewed-by: Peng Fan Reviewed-by: Igor Opaniuk --- drivers/mmc/mmc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 620bb930640..b61ce8db143 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -2824,7 +2824,7 @@ retry: if (err) return err; - /* The internal partition reset to user partition(0) at every CMD0*/ + /* The internal partition reset to user partition(0) at every CMD0 */ mmc_get_blk_desc(mmc)->hwpart = 0; /* Test for SD version 2 */ -- cgit v1.3.1 From 45224e8f26913bbd70960f316401134f3c366d78 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Mon, 20 May 2019 02:44:57 +0200 Subject: dm: core: gracefully handle alias seq without of Gracefully handle alias seq in the platform data rather than OF case. Signed-off-by: Marcel Ziswiler --- drivers/core/read.c | 4 +++- include/dm/read.h | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/core/read.c b/drivers/core/read.c index 047089c8867..85b3b7a5adb 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -275,15 +275,17 @@ int dev_read_alias_seq(const struct udevice *dev, int *devnump) { ofnode node = dev_ofnode(dev); const char *uc_name = dev->uclass->uc_drv->name; - int ret; + int ret = -ENOTSUPP; if (ofnode_is_np(node)) { ret = of_alias_get_id(ofnode_to_np(node), uc_name); if (ret >= 0) *devnump = ret; } else { +#if CONFIG_IS_ENABLED(OF_CONTROL) ret = fdtdec_get_alias_seq(gd->fdt_blob, uc_name, ofnode_to_offset(node), devnump); +#endif } return ret; diff --git a/include/dm/read.h b/include/dm/read.h index 1c1bc3702fd..3711386f513 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -923,8 +923,12 @@ static inline const void *dev_read_prop_by_prop(struct ofprop *prop, static inline int dev_read_alias_seq(const struct udevice *dev, int *devnump) { +#if CONFIG_IS_ENABLED(OF_CONTROL) return fdtdec_get_alias_seq(gd->fdt_blob, dev->uclass->uc_drv->name, dev_of_offset(dev), devnump); +#else + return -ENOTSUPP; +#endif } static inline int dev_read_u32_array(const struct udevice *dev, -- cgit v1.3.1 From 9b515a81be7a09307f1af5be40f6bdf8bc4283fd Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Mon, 20 May 2019 02:44:58 +0200 Subject: kconfig: mmc: move pxa_mmc_generic to kconfig Move CONFIG_PXA_MMC_GENERIC to Kconfig. Signed-off-by: Marcel Ziswiler Reviewed-by: Simon Glass --- configs/colibri_pxa270_defconfig | 1 + drivers/mmc/Kconfig | 8 ++++++++ include/configs/pxa-common.h | 7 ------- scripts/config_whitelist.txt | 1 - 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/configs/colibri_pxa270_defconfig b/configs/colibri_pxa270_defconfig index 153ced707de..4d881201abf 100644 --- a/configs/colibri_pxa270_defconfig +++ b/configs/colibri_pxa270_defconfig @@ -32,6 +32,7 @@ CONFIG_ENV_IS_IN_FLASH=y CONFIG_ENV_ADDR=0x80000 CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y CONFIG_DM=y +CONFIG_PXA_MMC_GENERIC=y CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 33b128ddc5a..ad86c232c43 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -299,6 +299,14 @@ config MMC_PCI If unsure, say N. +config PXA_MMC_GENERIC + bool "Support for MMC controllers on PXA" + help + This selects MMC controllers on PXA. + If you are on a PXA architecture, say Y here. + + If unsure, say N. + config MMC_OMAP_HS bool "TI OMAP High Speed Multimedia Card Interface support" select DM_REGULATOR_PBIAS if DM_MMC && DM_REGULATOR diff --git a/include/configs/pxa-common.h b/include/configs/pxa-common.h index 2632d48cc9c..52d77e06acf 100644 --- a/include/configs/pxa-common.h +++ b/include/configs/pxa-common.h @@ -15,13 +15,6 @@ #define CONFIG_KGDB_BAUDRATE 230400 #endif -/* - * MMC Card Configuration - */ -#ifdef CONFIG_CMD_MMC -#define CONFIG_PXA_MMC_GENERIC -#endif - /* * OHCI USB */ diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index bc3ca6e5b5a..747583089b8 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -1368,7 +1368,6 @@ CONFIG_PRPMC_PCI_ALIAS CONFIG_PSRAM_SCFG CONFIG_PWM CONFIG_PXA_LCD -CONFIG_PXA_MMC_GENERIC CONFIG_PXA_PWR_I2C CONFIG_PXA_STD_I2C CONFIG_PXA_VGA -- cgit v1.3.1 From 290e6bb9585e4bf8c7a20c54ffd707f26ee76329 Mon Sep 17 00:00:00 2001 From: Marcel Ziswiler Date: Mon, 20 May 2019 02:44:59 +0200 Subject: arm: pxa: mmc: add driver model support Add driver model (DM) support. Signed-off-by: Marcel Ziswiler --- drivers/mmc/pxa_mmc_gen.c | 160 +++++++++++++++++++++++++++------ include/dm/platform_data/pxa_mmc_gen.h | 22 +++++ 2 files changed, 154 insertions(+), 28 deletions(-) create mode 100644 include/dm/platform_data/pxa_mmc_gen.h (limited to 'drivers') diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index cc6014703cc..2c081fdc69f 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2010 Marek Vasut * + * Modified to add driver model (DM) support + * Copyright (C) 2019 Marcel Ziswiler + * * Loosely based on the old code and Linux's PXA MMC driver */ @@ -11,6 +14,8 @@ #include #include #include +#include +#include #include #include @@ -96,7 +101,7 @@ static int pxa_mmc_stop_clock(struct mmc *mmc) } static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - uint32_t cmdat) + uint32_t cmdat) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; @@ -143,7 +148,7 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t a, b, c; + u32 a, b, c; int i; int stat; @@ -152,7 +157,7 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) /* * Linux says: - * Did I mention this is Sick. We always need to + * Did I mention this is Sick. We always need to * discard the upper 8 bits of the first 16-bit word. */ a = readl(®s->res) & 0xffff; @@ -164,13 +169,13 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) } /* The command response didn't arrive */ - if (stat & MMC_STAT_TIME_OUT_RESPONSE) + if (stat & MMC_STAT_TIME_OUT_RESPONSE) { return -ETIMEDOUT; - else if (stat & MMC_STAT_RES_CRC_ERROR - && cmd->resp_type & MMC_RSP_CRC) { -#ifdef PXAMMC_CRC_SKIP - if (cmd->resp_type & MMC_RSP_136 - && cmd->response[0] & (1 << 31)) + } else if (stat & MMC_STAT_RES_CRC_ERROR && + cmd->resp_type & MMC_RSP_CRC) { +#ifdef PXAMMC_CRC_SKIP + if (cmd->resp_type & MMC_RSP_136 && + cmd->response[0] & (1 << 31)) printf("Ignoring CRC, this may be dangerous!\n"); else #endif @@ -185,8 +190,8 @@ static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t len; - uint32_t *buf = (uint32_t *)data->dest; + u32 len; + u32 *buf = (uint32_t *)data->dest; int size; int ret; @@ -202,7 +207,6 @@ static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data) /* Read data into the buffer */ while (size--) *buf++ = readl(®s->rxfifo); - } if (readl(®s->stat) & MMC_STAT_ERRORS) @@ -221,8 +225,8 @@ static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t len; - uint32_t *buf = (uint32_t *)data->src; + u32 len; + u32 *buf = (uint32_t *)data->src; int size; int ret; @@ -259,12 +263,11 @@ static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data) return 0; } -static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) +static int pxa_mmc_send_cmd_common(struct pxa_mmc_priv *priv, struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data) { - struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t cmdat = 0; + u32 cmdat = 0; int ret; /* Stop the controller */ @@ -313,12 +316,11 @@ static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, return 0; } -static int pxa_mmc_set_ios(struct mmc *mmc) +static int pxa_mmc_set_ios_common(struct pxa_mmc_priv *priv, struct mmc *mmc) { - struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t tmp; - uint32_t pxa_mmc_clock; + u32 tmp; + u32 pxa_mmc_clock; if (!mmc->clock) { pxa_mmc_stop_clock(mmc); @@ -346,9 +348,8 @@ static int pxa_mmc_set_ios(struct mmc *mmc) return 0; } -static int pxa_mmc_init(struct mmc *mmc) +static int pxa_mmc_init_common(struct pxa_mmc_priv *priv, struct mmc *mmc) { - struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; /* Make sure the clock are stopped */ @@ -362,10 +363,34 @@ static int pxa_mmc_init(struct mmc *mmc) /* Mask all interrupts */ writel(~(MMC_I_MASK_TXFIFO_WR_REQ | MMC_I_MASK_RXFIFO_RD_REQ), - ®s->i_mask); + ®s->i_mask); + return 0; } +#if !CONFIG_IS_ENABLED(DM_MMC) +static int pxa_mmc_init(struct mmc *mmc) +{ + struct pxa_mmc_priv *priv = mmc->priv; + + return pxa_mmc_init_common(priv, mmc); +} + +static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct pxa_mmc_priv *priv = mmc->priv; + + return pxa_mmc_send_cmd_common(priv, mmc, cmd, data); +} + +static int pxa_mmc_set_ios(struct mmc *mmc) +{ + struct pxa_mmc_priv *priv = mmc->priv; + + return pxa_mmc_set_ios_common(priv, mmc); +} + static const struct mmc_ops pxa_mmc_ops = { .send_cmd = pxa_mmc_request, .set_ios = pxa_mmc_set_ios, @@ -386,7 +411,7 @@ int pxa_mmc_register(int card_index) { struct mmc *mmc; struct pxa_mmc_priv *priv; - uint32_t reg; + u32 reg; int ret = -ENOMEM; priv = malloc(sizeof(struct pxa_mmc_priv)); @@ -405,7 +430,7 @@ int pxa_mmc_register(int card_index) default: ret = -EINVAL; printf("PXA MMC: Invalid MMC controller ID (card_index = %d)\n", - card_index); + card_index); goto err1; } @@ -420,7 +445,7 @@ int pxa_mmc_register(int card_index) #endif mmc = mmc_create(&pxa_mmc_cfg, priv); - if (mmc == NULL) + if (!mmc) goto err1; return 0; @@ -430,3 +455,82 @@ err1: err0: return ret; } +#else /* !CONFIG_IS_ENABLED(DM_MMC) */ +static int pxa_mmc_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + struct mmc_config *cfg = &plat->cfg; + struct mmc *mmc = &plat->mmc; + struct pxa_mmc_priv *priv = dev_get_priv(dev); + u32 reg; + + upriv->mmc = mmc; + + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + cfg->f_max = PXAMMC_MAX_SPEED; + cfg->f_min = PXAMMC_MIN_SPEED; + cfg->host_caps = PXAMMC_HOST_CAPS; + cfg->name = dev->name; + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; + + mmc->priv = priv; + + priv->regs = plat->base; + +#ifndef CONFIG_CPU_MONAHANS /* PXA2xx */ + reg = readl(CKEN); + reg |= CKEN12_MMC; + writel(reg, CKEN); +#else /* PXA3xx */ + reg = readl(CKENA); + reg |= CKENA_12_MMC0 | CKENA_13_MMC1; + writel(reg, CKENA); +#endif + + return pxa_mmc_init_common(priv, mmc); +} + +static int pxa_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + struct pxa_mmc_priv *priv = dev_get_priv(dev); + + return pxa_mmc_send_cmd_common(priv, &plat->mmc, cmd, data); +} + +static int pxa_mmc_set_ios(struct udevice *dev) +{ + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + struct pxa_mmc_priv *priv = dev_get_priv(dev); + + return pxa_mmc_set_ios_common(priv, &plat->mmc); +} + +static const struct dm_mmc_ops pxa_mmc_ops = { + .get_cd = NULL, + .send_cmd = pxa_mmc_send_cmd, + .set_ios = pxa_mmc_set_ios, +}; + +#if CONFIG_IS_ENABLED(BLK) +static int pxa_mmc_bind(struct udevice *dev) +{ + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + + return mmc_bind(dev, &plat->mmc, &plat->cfg); +} +#endif + +U_BOOT_DRIVER(pxa_mmc) = { +#if CONFIG_IS_ENABLED(BLK) + .bind = pxa_mmc_bind, +#endif + .id = UCLASS_MMC, + .name = "pxa_mmc", + .ops = &pxa_mmc_ops, + .priv_auto_alloc_size = sizeof(struct pxa_mmc_priv), + .probe = pxa_mmc_probe, +}; +#endif /* !CONFIG_IS_ENABLED(DM_MMC) */ diff --git a/include/dm/platform_data/pxa_mmc_gen.h b/include/dm/platform_data/pxa_mmc_gen.h new file mode 100644 index 00000000000..9875bab2cf4 --- /dev/null +++ b/include/dm/platform_data/pxa_mmc_gen.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2019 Marcel Ziswiler + */ + +#ifndef __PXA_MMC_GEN_H +#define __PXA_MMC_GEN_H + +#include + +/* + * struct pxa_mmc_platdata - information about a PXA MMC controller + * + * @base: MMC controller base register address + */ +struct pxa_mmc_plat { + struct mmc_config cfg; + struct mmc mmc; + struct pxa_mmc_regs *base; +}; + +#endif /* __PXA_MMC_GEN_H */ -- cgit v1.3.1 From 78ce0bd3acafc51e94157ff99aec3ed82e685ef5 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:06 -0400 Subject: clk: Always use the supplied struct clk CCF clocks should always use the struct clock passed to their methods for extracting the driver-specific clock information struct. Previously, many functions would use the clk->dev->priv if the device was bound. This could cause problems with composite clocks. The individual clocks in a composite clock did not have the ->dev field filled in. This was fine, because the device-specific clock information would be used. However, since there was no ->dev, there was no way to get the parent clock. This caused the recalc_rate method of the CCF divider clock to fail. One option would be to use the clk->priv field to get the composite clock and from there get the appropriate parent device. However, this would tie the implementation to the composite clock. In general, different devices should not rely on the contents of ->priv from another device. The simple solution to this problem is to just always use the supplied struct clock. The composite clock now fills in the ->dev pointer of its child clocks. This allows child clocks to make calls like clk_get_parent() without issue. imx avoided the above problem by using a custom get_rate function with composite clocks. Signed-off-by: Sean Anderson Acked-by: Lukasz Majewski --- doc/imx/clk/ccf.txt | 63 +++++++++++++++++++++--------------------- drivers/clk/clk-composite.c | 7 +++++ drivers/clk/clk-divider.c | 6 ++-- drivers/clk/clk-fixed-factor.c | 3 +- drivers/clk/clk-gate.c | 6 ++-- drivers/clk/clk-mux.c | 12 +++----- drivers/clk/imx/clk-gate2.c | 4 +-- 7 files changed, 50 insertions(+), 51 deletions(-) (limited to 'drivers') diff --git a/doc/imx/clk/ccf.txt b/doc/imx/clk/ccf.txt index 36b60dc4389..e40ac360e86 100644 --- a/doc/imx/clk/ccf.txt +++ b/doc/imx/clk/ccf.txt @@ -1,42 +1,37 @@ Introduction: ============= -This documentation entry describes the Common Clock Framework [CCF] -port from Linux kernel (v5.1.12) to U-Boot. +This documentation entry describes the Common Clock Framework [CCF] port from +Linux kernel (v5.1.12) to U-Boot. -This code is supposed to bring CCF to IMX based devices (imx6q, imx7 -imx8). Moreover, it also provides some common clock code, which would -allow easy porting of CCF Linux code to other platforms. +This code is supposed to bring CCF to IMX based devices (imx6q, imx7 imx8). +Moreover, it also provides some common clock code, which would allow easy +porting of CCF Linux code to other platforms. Design decisions: ================= -* U-Boot's driver model [DM] for clk differs from Linux CCF. The most - notably difference is the lack of support for hierarchical clocks and - "clock as a manager driver" (single clock DTS node acts as a starting - point for all other clocks). +* U-Boot's driver model [DM] for clk differs from Linux CCF. The most notably + difference is the lack of support for hierarchical clocks and "clock as a + manager driver" (single clock DTS node acts as a starting point for all other + clocks). -* The clk_get_rate() caches the previously read data if CLK_GET_RATE_NOCACHE - is not set (no need for recursive access). +* The clk_get_rate() caches the previously read data if CLK_GET_RATE_NOCACHE is + not set (no need for recursive access). -* On purpose the "manager" clk driver (clk-imx6q.c) is not using large - table to store pointers to clocks - e.g. clk[IMX6QDL_CLK_USDHC2_SEL] = .... - Instead we use udevice's linked list for the same class (UCLASS_CLK). +* On purpose the "manager" clk driver (clk-imx6q.c) is not using large table to + store pointers to clocks - e.g. clk[IMX6QDL_CLK_USDHC2_SEL] = .... Instead we + use udevice's linked list for the same class (UCLASS_CLK). Rationale: ---------- - When porting the code as is from Linux, one would need ~1KiB of RAM to - store it. This is way too much if we do plan to use this driver in SPL. + When porting the code as is from Linux, one would need ~1KiB of RAM to store + it. This is way too much if we do plan to use this driver in SPL. * The "central" structure of this patch series is struct udevice and its uclass_priv field contains the struct clk pointer (to the originally created one). -* Up till now U-Boot's driver model (DM) CLK operates on udevice (main - access to clock is by udevice ops) - In the CCF the access to struct clk (embodying pointer to *dev) is - possible via dev_get_clk_ptr() (it is a wrapper on dev_get_uclass_priv()). - * To keep things simple the struct udevice's uclass_priv pointer is used to store back pointer to corresponding struct clk. However, it is possible to modify clk-uclass.c file and add there struct uc_clk_priv, which would have @@ -45,13 +40,17 @@ Design decisions: setting .per_device_auto_alloc_size = sizeof(struct uc_clk_priv)) the uclass_priv stores the pointer to struct clk. +* Non-CCF clocks do not have a pointer to a clock in clk->dev->priv. In the case + of composite clocks, clk->dev->priv may not match clk. Drivers should always + use the struct clk which is passed to them, and not clk->dev->priv. + * It is advised to add common clock code (like already added rate and flags) to the struct clk, which is a top level description of the clock. * U-Boot's driver model already provides the facility to automatically allocate - (via private_alloc_size) device private data (accessible via dev->priv). - It may look appealing to use this feature to allocate private structures for - CCF clk devices e.g. divider (struct clk_divider *divider) for IMX6Q clock. + (via private_alloc_size) device private data (accessible via dev->priv). It + may look appealing to use this feature to allocate private structures for CCF + clk devices e.g. divider (struct clk_divider *divider) for IMX6Q clock. The above feature had not been used for following reasons: - The original CCF Linux kernel driver is the "manager" for clocks - it @@ -64,21 +63,23 @@ Design decisions: * I've added the clk_get_parent(), which reads parent's dev->uclass_priv to provide parent's struct clk pointer. This seems the easiest way to get - child/parent relationship for struct clk in U-Boot's udevice based clocks. + child/parent relationship for struct clk in U-Boot's udevice based clocks. In + the future arbitrary parents may be supported by adding a get_parent function + to clk_ops. * Linux's CCF 'struct clk_core' corresponds to U-Boot's udevice in 'struct clk'. Clock IP block agnostic flags from 'struct clk_core' (e.g. NOCACHE) have been - moved from this struct one level up to 'struct clk'. + moved from this struct one level up to 'struct clk'. Many flags are + unimplemented at the moment. * For tests the new ./test/dm/clk_ccf.c and ./drivers/clk/clk_sandbox_ccf.c files have been introduced. The latter setups the CCF clock structure for - sandbox by reusing, if possible, generic clock primitives - like divier - and mux. The former file provides code to tests this setup. + sandbox by reusing, if possible, generic clock primitives - like divier and + mux. The former file provides code to tests this setup. For sandbox new CONFIG_SANDBOX_CLK_CCF Kconfig define has been introduced. - All new primitives added for new architectures must have corresponding test - in the two aforementioned files. - + All new primitives added for new architectures must have corresponding test in + the two aforementioned files. Testing (sandbox): ================== diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 414185031e2..2ff1d6b47f7 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -147,6 +147,13 @@ struct clk *clk_register_composite(struct device *dev, const char *name, goto err; } + if (composite->mux) + composite->mux->dev = clk->dev; + if (composite->rate) + composite->rate->dev = clk->dev; + if (composite->gate) + composite->gate->dev = clk->dev; + return clk; err: diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c index 2a68719eb68..34658536c48 100644 --- a/drivers/clk/clk-divider.c +++ b/drivers/clk/clk-divider.c @@ -73,8 +73,7 @@ unsigned long divider_recalc_rate(struct clk *hw, unsigned long parent_rate, static ulong clk_divider_recalc_rate(struct clk *clk) { - struct clk_divider *divider = to_clk_divider(clk_dev_binded(clk) ? - dev_get_clk_ptr(clk->dev) : clk); + struct clk_divider *divider = to_clk_divider(clk); unsigned long parent_rate = clk_get_parent_rate(clk); unsigned int val; @@ -153,8 +152,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate, static ulong clk_divider_set_rate(struct clk *clk, unsigned long rate) { - struct clk_divider *divider = to_clk_divider(clk_dev_binded(clk) ? - dev_get_clk_ptr(clk->dev) : clk); + struct clk_divider *divider = to_clk_divider(clk); unsigned long parent_rate = clk_get_parent_rate(clk); int value; u32 val; diff --git a/drivers/clk/clk-fixed-factor.c b/drivers/clk/clk-fixed-factor.c index 2ceb6bb171c..0eb24b87fc3 100644 --- a/drivers/clk/clk-fixed-factor.c +++ b/drivers/clk/clk-fixed-factor.c @@ -20,8 +20,7 @@ static ulong clk_factor_recalc_rate(struct clk *clk) { - struct clk_fixed_factor *fix = - to_clk_fixed_factor(dev_get_clk_ptr(clk->dev)); + struct clk_fixed_factor *fix = to_clk_fixed_factor(clk); unsigned long parent_rate = clk_get_parent_rate(clk); unsigned long long int rate; diff --git a/drivers/clk/clk-gate.c b/drivers/clk/clk-gate.c index 23c1f2c4ba9..98e4b80b32f 100644 --- a/drivers/clk/clk-gate.c +++ b/drivers/clk/clk-gate.c @@ -46,8 +46,7 @@ */ static void clk_gate_endisable(struct clk *clk, int enable) { - struct clk_gate *gate = to_clk_gate(clk_dev_binded(clk) ? - dev_get_clk_ptr(clk->dev) : clk); + struct clk_gate *gate = to_clk_gate(clk); int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0; u32 reg; @@ -89,8 +88,7 @@ static int clk_gate_disable(struct clk *clk) int clk_gate_is_enabled(struct clk *clk) { - struct clk_gate *gate = to_clk_gate(clk_dev_binded(clk) ? - dev_get_clk_ptr(clk->dev) : clk); + struct clk_gate *gate = to_clk_gate(clk); u32 reg; #if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF) diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c index c69cce0565d..26991a5bc8f 100644 --- a/drivers/clk/clk-mux.c +++ b/drivers/clk/clk-mux.c @@ -38,8 +38,7 @@ int clk_mux_val_to_index(struct clk *clk, u32 *table, unsigned int flags, unsigned int val) { - struct clk_mux *mux = to_clk_mux(clk_dev_binded(clk) ? - dev_get_clk_ptr(clk->dev) : clk); + struct clk_mux *mux = to_clk_mux(clk); int num_parents = mux->num_parents; if (table) { @@ -82,8 +81,7 @@ unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index) u8 clk_mux_get_parent(struct clk *clk) { - struct clk_mux *mux = to_clk_mux(clk_dev_binded(clk) ? - dev_get_clk_ptr(clk->dev) : clk); + struct clk_mux *mux = to_clk_mux(clk); u32 val; #if CONFIG_IS_ENABLED(SANDBOX_CLK_CCF) @@ -100,8 +98,7 @@ u8 clk_mux_get_parent(struct clk *clk) static int clk_fetch_parent_index(struct clk *clk, struct clk *parent) { - struct clk_mux *mux = to_clk_mux(clk_dev_binded(clk) ? - dev_get_clk_ptr(clk->dev) : clk); + struct clk_mux *mux = to_clk_mux(clk); int i; @@ -118,8 +115,7 @@ static int clk_fetch_parent_index(struct clk *clk, static int clk_mux_set_parent(struct clk *clk, struct clk *parent) { - struct clk_mux *mux = to_clk_mux(clk_dev_binded(clk) ? - dev_get_clk_ptr(clk->dev) : clk); + struct clk_mux *mux = to_clk_mux(clk); int index; u32 val; u32 reg; diff --git a/drivers/clk/imx/clk-gate2.c b/drivers/clk/imx/clk-gate2.c index b38890d5ba5..40b2d4caab4 100644 --- a/drivers/clk/imx/clk-gate2.c +++ b/drivers/clk/imx/clk-gate2.c @@ -39,7 +39,7 @@ struct clk_gate2 { static int clk_gate2_enable(struct clk *clk) { - struct clk_gate2 *gate = to_clk_gate2(dev_get_clk_ptr(clk->dev)); + struct clk_gate2 *gate = to_clk_gate2(clk); u32 reg; reg = readl(gate->reg); @@ -52,7 +52,7 @@ static int clk_gate2_enable(struct clk *clk) static int clk_gate2_disable(struct clk *clk) { - struct clk_gate2 *gate = to_clk_gate2(dev_get_clk_ptr(clk->dev)); + struct clk_gate2 *gate = to_clk_gate2(clk); u32 reg; reg = readl(gate->reg); -- cgit v1.3.1 From 5e8317a9faff472e8b83f5760535e9bf40571a8a Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:07 -0400 Subject: clk: Check that ops of composite clock components exist before calling clk_composite_ops was shared between all devices in the composite clock driver. If one clock had a feature (such as supporting set_parent) which another clock did not, it could call a null pointer dereference. This patch does three things 1. It adds null-pointer checks to all composite clock functions. 2. It makes clk_composite_ops const and sets its functions at compile-time. 3. It adds some basic sanity checks to num_parents. The combined effect of these changes is that any of mux, rate, or gate can be NULL, and composite clocks will still function normally. Previously, at least mux had to exist, since clk_composite_get_parent was used to determine the parent for clk_register. Signed-off-by: Sean Anderson Acked-by: Lukasz Majewski --- drivers/clk/clk-composite.c | 57 ++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 2ff1d6b47f7..819bfca2fcf 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -24,7 +24,10 @@ static u8 clk_composite_get_parent(struct clk *clk) (struct clk *)dev_get_clk_ptr(clk->dev) : clk); struct clk *mux = composite->mux; - return clk_mux_get_parent(mux); + if (mux) + return clk_mux_get_parent(mux); + else + return 0; } static int clk_composite_set_parent(struct clk *clk, struct clk *parent) @@ -34,7 +37,10 @@ static int clk_composite_set_parent(struct clk *clk, struct clk *parent) const struct clk_ops *mux_ops = composite->mux_ops; struct clk *mux = composite->mux; - return mux_ops->set_parent(mux, parent); + if (mux && mux_ops) + return mux_ops->set_parent(mux, parent); + else + return -ENOTSUPP; } static unsigned long clk_composite_recalc_rate(struct clk *clk) @@ -44,7 +50,10 @@ static unsigned long clk_composite_recalc_rate(struct clk *clk) const struct clk_ops *rate_ops = composite->rate_ops; struct clk *rate = composite->rate; - return rate_ops->get_rate(rate); + if (rate && rate_ops) + return rate_ops->get_rate(rate); + else + return clk_get_parent_rate(clk); } static ulong clk_composite_set_rate(struct clk *clk, unsigned long rate) @@ -54,7 +63,10 @@ static ulong clk_composite_set_rate(struct clk *clk, unsigned long rate) const struct clk_ops *rate_ops = composite->rate_ops; struct clk *clk_rate = composite->rate; - return rate_ops->set_rate(clk_rate, rate); + if (rate && rate_ops) + return rate_ops->set_rate(clk_rate, rate); + else + return clk_get_rate(clk); } static int clk_composite_enable(struct clk *clk) @@ -64,7 +76,10 @@ static int clk_composite_enable(struct clk *clk) const struct clk_ops *gate_ops = composite->gate_ops; struct clk *gate = composite->gate; - return gate_ops->enable(gate); + if (gate && gate_ops) + return gate_ops->enable(gate); + else + return 0; } static int clk_composite_disable(struct clk *clk) @@ -74,15 +89,12 @@ static int clk_composite_disable(struct clk *clk) const struct clk_ops *gate_ops = composite->gate_ops; struct clk *gate = composite->gate; - gate_ops->disable(gate); - - return 0; + if (gate && gate_ops) + return gate_ops->disable(gate); + else + return 0; } -struct clk_ops clk_composite_ops = { - /* This will be set according to clk_register_composite */ -}; - struct clk *clk_register_composite(struct device *dev, const char *name, const char * const *parent_names, int num_parents, struct clk *mux, @@ -96,7 +108,9 @@ struct clk *clk_register_composite(struct device *dev, const char *name, struct clk *clk; struct clk_composite *composite; int ret; - struct clk_ops *composite_ops = &clk_composite_ops; + + if (!num_parents || (num_parents != 1 && !mux)) + return ERR_PTR(-EINVAL); composite = kzalloc(sizeof(*composite), GFP_KERNEL); if (!composite) @@ -105,8 +119,6 @@ struct clk *clk_register_composite(struct device *dev, const char *name, if (mux && mux_ops) { composite->mux = mux; composite->mux_ops = mux_ops; - if (mux_ops->set_parent) - composite_ops->set_parent = clk_composite_set_parent; mux->data = (ulong)composite; } @@ -115,11 +127,6 @@ struct clk *clk_register_composite(struct device *dev, const char *name, clk = ERR_PTR(-EINVAL); goto err; } - composite_ops->get_rate = clk_composite_recalc_rate; - - /* .set_rate requires either .round_rate or .determine_rate */ - if (rate_ops->set_rate) - composite_ops->set_rate = clk_composite_set_rate; composite->rate = rate; composite->rate_ops = rate_ops; @@ -134,8 +141,6 @@ struct clk *clk_register_composite(struct device *dev, const char *name, composite->gate = gate; composite->gate_ops = gate_ops; - composite_ops->enable = clk_composite_enable; - composite_ops->disable = clk_composite_disable; gate->data = (ulong)composite; } @@ -161,6 +166,14 @@ err: return clk; } +static const struct clk_ops clk_composite_ops = { + .set_parent = clk_composite_set_parent, + .get_rate = clk_composite_recalc_rate, + .set_rate = clk_composite_set_rate, + .enable = clk_composite_enable, + .disable = clk_composite_disable, +}; + U_BOOT_DRIVER(clk_composite) = { .name = UBOOT_DM_CLK_COMPOSITE, .id = UCLASS_CLK, -- cgit v1.3.1 From 675d79073cc347ba72567668da69aebd1d1915fa Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:08 -0400 Subject: clk: Fix clk_get_by_* handling of index clk_get_by_index_nodev only ever fetched clock 1, due to passing a boolean predicate instead of the index. Other clk_get_by_* functions got the clock correctly, but passed a predicate instead of the index to clk_get_by_tail. This could lead to confusing error messages. Signed-off-by: Sean Anderson CC: Lukasz Majewski --- drivers/clk/clk-uclass.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/clk-uclass.c b/drivers/clk/clk-uclass.c index 9ffc2243cb5..70df9d410f4 100644 --- a/drivers/clk/clk-uclass.c +++ b/drivers/clk/clk-uclass.c @@ -123,7 +123,7 @@ static int clk_get_by_indexed_prop(struct udevice *dev, const char *prop_name, return clk_get_by_index_tail(ret, dev_ofnode(dev), &args, "clocks", - index > 0, clk); + index, clk); } int clk_get_by_index(struct udevice *dev, int index, struct clk *clk) @@ -135,7 +135,7 @@ int clk_get_by_index(struct udevice *dev, int index, struct clk *clk) index, &args); return clk_get_by_index_tail(ret, dev_ofnode(dev), &args, "clocks", - index > 0, clk); + index, clk); } int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk) @@ -144,10 +144,10 @@ int clk_get_by_index_nodev(ofnode node, int index, struct clk *clk) int ret; ret = ofnode_parse_phandle_with_args(node, "clocks", "#clock-cells", 0, - index > 0, &args); + index, &args); return clk_get_by_index_tail(ret, node, &args, "clocks", - index > 0, clk); + index, clk); } int clk_get_bulk(struct udevice *dev, struct clk_bulk *bulk) -- cgit v1.3.1 From 019ef9a3f32642abbf924931ecc9487300e74530 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:09 -0400 Subject: clk: Add K210 pll support This pll code is primarily based on the code from the kendryte standalone sdk in lib/drivers/sysctl.c. k210_pll_calc_config is roughly analogous to the algorithm used to set the pll frequency, but it has been completely rewritten to be fixed-point based. Signed-off-by: Sean Anderson CC: Lukasz Majewski --- drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/kendryte/Kconfig | 12 + drivers/clk/kendryte/Makefile | 1 + drivers/clk/kendryte/pll.c | 601 ++++++++++++++++++++++++++++++++++++++++++ include/kendryte/pll.h | 57 ++++ include/test/export.h | 16 ++ test/dm/Makefile | 1 + test/dm/k210_pll.c | 96 +++++++ 9 files changed, 786 insertions(+) create mode 100644 drivers/clk/kendryte/Kconfig create mode 100644 drivers/clk/kendryte/Makefile create mode 100644 drivers/clk/kendryte/pll.c create mode 100644 include/kendryte/pll.h create mode 100644 include/test/export.h create mode 100644 test/dm/k210_pll.c (limited to 'drivers') diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 8b8b7199995..82cb1874e19 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -156,6 +156,7 @@ source "drivers/clk/analogbits/Kconfig" source "drivers/clk/at91/Kconfig" source "drivers/clk/exynos/Kconfig" source "drivers/clk/imx/Kconfig" +source "drivers/clk/kendryte/Kconfig" source "drivers/clk/meson/Kconfig" source "drivers/clk/mvebu/Kconfig" source "drivers/clk/owl/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index e01783391dc..d9119545810 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_CLK_BOSTON) += clk_boston.o obj-$(CONFIG_CLK_EXYNOS) += exynos/ obj-$(CONFIG_$(SPL_TPL_)CLK_INTEL) += intel/ obj-$(CONFIG_CLK_HSDK) += clk-hsdk-cgu.o +obj-$(CONFIG_CLK_K210) += kendryte/ obj-$(CONFIG_CLK_MPC83XX) += mpc83xx_clk.o obj-$(CONFIG_CLK_OWL) += owl/ obj-$(CONFIG_CLK_RENESAS) += renesas/ diff --git a/drivers/clk/kendryte/Kconfig b/drivers/clk/kendryte/Kconfig new file mode 100644 index 00000000000..7b69c8afaf7 --- /dev/null +++ b/drivers/clk/kendryte/Kconfig @@ -0,0 +1,12 @@ +config CLK_K210 + bool "Clock support for Kendryte K210" + depends on CLK && CLK_CCF + help + This enables support clock driver for Kendryte K210 platforms. + +config CLK_K210_SET_RATE + bool "Enable setting the Kendryte K210 PLL rate" + depends on CLK_K210 + help + Add functionality to calculate new rates for K210 PLLs. Enabling this + feature adds around 1K to U-Boot's final size. diff --git a/drivers/clk/kendryte/Makefile b/drivers/clk/kendryte/Makefile new file mode 100644 index 00000000000..c56d93ea1c5 --- /dev/null +++ b/drivers/clk/kendryte/Makefile @@ -0,0 +1 @@ +obj-y += pll.o diff --git a/drivers/clk/kendryte/pll.c b/drivers/clk/kendryte/pll.c new file mode 100644 index 00000000000..19e358856a8 --- /dev/null +++ b/drivers/clk/kendryte/pll.c @@ -0,0 +1,601 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019-20 Sean Anderson + */ +#define LOG_CATEGORY UCLASS_CLK +#include + +#include +/* For DIV_ROUND_DOWN_ULL, defined in linux/kernel.h */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define CLK_K210_PLL "k210_clk_pll" + +#ifdef CONFIG_CLK_K210_SET_RATE +static int k210_pll_enable(struct clk *clk); +static int k210_pll_disable(struct clk *clk); + +/* + * The PLL included with the Kendryte K210 appears to be a True Circuits, Inc. + * General-Purpose PLL. The logical layout of the PLL with internal feedback is + * approximately the following: + * + * +---------------+ + * |reference clock| + * +---------------+ + * | + * v + * +--+ + * |/r| + * +--+ + * | + * v + * +-------------+ + * |divided clock| + * +-------------+ + * | + * v + * +--------------+ + * |phase detector|<---+ + * +--------------+ | + * | | + * v +--------------+ + * +---+ |feedback clock| + * |VCO| +--------------+ + * +---+ ^ + * | +--+ | + * +--->|/f|---+ + * | +--+ + * v + * +---+ + * |/od| + * +---+ + * | + * v + * +------+ + * |output| + * +------+ + * + * The k210 PLLs have three factors: r, f, and od. Because of the feedback mode, + * the effect of the division by f is to multiply the input frequency. The + * equation for the output rate is + * rate = (rate_in * f) / (r * od). + * Moving knowns to one side of the equation, we get + * rate / rate_in = f / (r * od) + * Rearranging slightly, + * abs_error = abs((rate / rate_in) - (f / (r * od))). + * To get relative, error, we divide by the expected ratio + * error = abs((rate / rate_in) - (f / (r * od))) / (rate / rate_in). + * Simplifying, + * error = abs(1 - f / (r * od)) / (rate / rate_in) + * error = abs(1 - (f * rate_in) / (r * od * rate)) + * Using the constants ratio = rate / rate_in and inv_ratio = rate_in / rate, + * error = abs((f * inv_ratio) / (r * od) - 1) + * This is the error used in evaluating parameters. + * + * r and od are four bits each, while f is six bits. Because r and od are + * multiplied together, instead of the full 256 values possible if both bits + * were used fully, there are only 97 distinct products. Combined with f, there + * are 6208 theoretical settings for the PLL. However, most of these settings + * can be ruled out immediately because they do not have the correct ratio. + * + * In addition to the constraint of approximating the desired ratio, parameters + * must also keep internal pll frequencies within acceptable ranges. The divided + * clock's minimum and maximum frequencies have a ratio of around 128. This + * leaves fairly substantial room to work with, especially since the only + * affected parameter is r. The VCO's minimum and maximum frequency have a ratio + * of 5, which is considerably more restrictive. + * + * The r and od factors are stored in a table. This is to make it easy to find + * the next-largest product. Some products have multiple factorizations, but + * only when one factor has at least a 2.5x ratio to the factors of the other + * factorization. This is because any smaller ratio would not make a difference + * when ensuring the VCO's frequency is within spec. + * + * Throughout the calculation function, fixed point arithmetic is used. Because + * the range of rate and rate_in may be up to 1.75 GHz, or around 2^30, 64-bit + * 32.32 fixed-point numbers are used to represent ratios. In general, to + * implement division, the numerator is first multiplied by 2^32. This gives a + * result where the whole number part is in the upper 32 bits, and the fraction + * is in the lower 32 bits. + * + * In general, rounding is done to the closest integer. This helps find the best + * approximation for the ratio. Rounding in one direction (e.g down) could cause + * the function to miss a better ratio with one of the parameters increased by + * one. + */ + +/* + * The factors table was generated with the following python code: + * + * def p(x, y): + * return (1.0*x/y > 2.5) or (1.0*y/x > 2.5) + * + * factors = {} + * for i in range(1, 17): + * for j in range(1, 17): + * fs = factors.get(i*j) or [] + * if fs == [] or all([ + * (p(i, x) and p(i, y)) or (p(j, x) and p(j, y)) + * for (x, y) in fs]): + * fs.append((i, j)) + * factors[i*j] = fs + * + * for k, l in sorted(factors.items()): + * for v in l: + * print("PACK(%s, %s)," % v) + */ +#define PACK(r, od) (((((r) - 1) & 0xF) << 4) | (((od) - 1) & 0xF)) +#define UNPACK_R(val) ((((val) >> 4) & 0xF) + 1) +#define UNPACK_OD(val) (((val) & 0xF) + 1) +static const u8 factors[] = { + PACK(1, 1), + PACK(1, 2), + PACK(1, 3), + PACK(1, 4), + PACK(1, 5), + PACK(1, 6), + PACK(1, 7), + PACK(1, 8), + PACK(1, 9), + PACK(3, 3), + PACK(1, 10), + PACK(1, 11), + PACK(1, 12), + PACK(3, 4), + PACK(1, 13), + PACK(1, 14), + PACK(1, 15), + PACK(3, 5), + PACK(1, 16), + PACK(4, 4), + PACK(2, 9), + PACK(2, 10), + PACK(3, 7), + PACK(2, 11), + PACK(2, 12), + PACK(5, 5), + PACK(2, 13), + PACK(3, 9), + PACK(2, 14), + PACK(2, 15), + PACK(2, 16), + PACK(3, 11), + PACK(5, 7), + PACK(3, 12), + PACK(3, 13), + PACK(4, 10), + PACK(3, 14), + PACK(4, 11), + PACK(3, 15), + PACK(3, 16), + PACK(7, 7), + PACK(5, 10), + PACK(4, 13), + PACK(6, 9), + PACK(5, 11), + PACK(4, 14), + PACK(4, 15), + PACK(7, 9), + PACK(4, 16), + PACK(5, 13), + PACK(6, 11), + PACK(5, 14), + PACK(6, 12), + PACK(5, 15), + PACK(7, 11), + PACK(6, 13), + PACK(5, 16), + PACK(9, 9), + PACK(6, 14), + PACK(8, 11), + PACK(6, 15), + PACK(7, 13), + PACK(6, 16), + PACK(7, 14), + PACK(9, 11), + PACK(10, 10), + PACK(8, 13), + PACK(7, 15), + PACK(9, 12), + PACK(10, 11), + PACK(7, 16), + PACK(9, 13), + PACK(8, 15), + PACK(11, 11), + PACK(9, 14), + PACK(8, 16), + PACK(10, 13), + PACK(11, 12), + PACK(9, 15), + PACK(10, 14), + PACK(11, 13), + PACK(9, 16), + PACK(10, 15), + PACK(11, 14), + PACK(12, 13), + PACK(10, 16), + PACK(11, 15), + PACK(12, 14), + PACK(13, 13), + PACK(11, 16), + PACK(12, 15), + PACK(13, 14), + PACK(12, 16), + PACK(13, 15), + PACK(14, 14), + PACK(13, 16), + PACK(14, 15), + PACK(14, 16), + PACK(15, 15), + PACK(15, 16), + PACK(16, 16), +}; + +TEST_STATIC int k210_pll_calc_config(u32 rate, u32 rate_in, + struct k210_pll_config *best) +{ + int i; + s64 error, best_error; + u64 ratio, inv_ratio; /* fixed point 32.32 ratio of the rates */ + u64 max_r; + u64 r, f, od; + + /* + * Can't go over 1.75 GHz or under 21.25 MHz due to limitations on the + * VCO frequency. These are not the same limits as below because od can + * reduce the output frequency by 16. + */ + if (rate > 1750000000 || rate < 21250000) + return -EINVAL; + + /* Similar restrictions on the input rate */ + if (rate_in > 1750000000 || rate_in < 13300000) + return -EINVAL; + + ratio = DIV_ROUND_CLOSEST_ULL((u64)rate << 32, rate_in); + inv_ratio = DIV_ROUND_CLOSEST_ULL((u64)rate_in << 32, rate); + /* Can't increase by more than 64 or reduce by more than 256 */ + if (rate > rate_in && ratio > (64ULL << 32)) + return -EINVAL; + else if (rate <= rate_in && inv_ratio > (256ULL << 32)) + return -EINVAL; + + /* + * The divided clock (rate_in / r) must stay between 1.75 GHz and 13.3 + * MHz. There is no minimum, since the only way to get a higher input + * clock than 26 MHz is to use a clock generated by a PLL. Because PLLs + * cannot output frequencies greater than 1.75 GHz, the minimum would + * never be greater than one. + */ + max_r = DIV_ROUND_DOWN_ULL(rate_in, 13300000); + + /* Variables get immediately incremented, so start at -1th iteration */ + i = -1; + f = 0; + r = 0; + od = 0; + best_error = S64_MAX; + error = best_error; + /* do-while here so we always try at least one ratio */ + do { + /* + * Whether we swapped r and od while enforcing frequency limits + */ + bool swapped = false; + u64 last_od = od; + u64 last_r = r; + + /* + * Try the next largest value for f (or r and od) and + * recalculate the other parameters based on that + */ + if (rate > rate_in) { + /* + * Skip factors of the same product if we already tried + * out that product + */ + do { + i++; + r = UNPACK_R(factors[i]); + od = UNPACK_OD(factors[i]); + } while (i + 1 < ARRAY_SIZE(factors) && + r * od == last_r * last_od); + + /* Round close */ + f = (r * od * ratio + BIT(31)) >> 32; + if (f > 64) + f = 64; + } else { + u64 tmp = ++f * inv_ratio; + bool round_up = !!(tmp & BIT(31)); + u32 goal = (tmp >> 32) + round_up; + u32 err, last_err; + + /* Get the next r/od pair in factors */ + while (r * od < goal && i + 1 < ARRAY_SIZE(factors)) { + i++; + r = UNPACK_R(factors[i]); + od = UNPACK_OD(factors[i]); + } + + /* + * This is a case of double rounding. If we rounded up + * above, we need to round down (in cases of ties) here. + * This prevents off-by-one errors resulting from + * choosing X+2 over X when X.Y rounds up to X+1 and + * there is no r * od = X+1. For the converse, when X.Y + * is rounded down to X, we should choose X+1 over X-1. + */ + err = abs(r * od - goal); + last_err = abs(last_r * last_od - goal); + if (last_err < err || (round_up && last_err == err)) { + i--; + r = last_r; + od = last_od; + } + } + + /* + * Enforce limits on internal clock frequencies. If we + * aren't in spec, try swapping r and od. If everything is + * in-spec, calculate the relative error. + */ + while (true) { + /* + * Whether the intermediate frequencies are out-of-spec + */ + bool out_of_spec = false; + + if (r > max_r) { + out_of_spec = true; + } else { + /* + * There is no way to only divide once; we need + * to examine the frequency with and without the + * effect of od. + */ + u64 vco = DIV_ROUND_CLOSEST_ULL(rate_in * f, r); + + if (vco > 1750000000 || vco < 340000000) + out_of_spec = true; + } + + if (out_of_spec) { + if (!swapped) { + u64 tmp = r; + + r = od; + od = tmp; + swapped = true; + continue; + } else { + /* + * Try looking ahead to see if there are + * additional factors for the same + * product. + */ + if (i + 1 < ARRAY_SIZE(factors)) { + u64 new_r, new_od; + + i++; + new_r = UNPACK_R(factors[i]); + new_od = UNPACK_OD(factors[i]); + if (r * od == new_r * new_od) { + r = new_r; + od = new_od; + swapped = false; + continue; + } + i--; + } + break; + } + } + + error = DIV_ROUND_CLOSEST_ULL(f * inv_ratio, r * od); + /* The lower 16 bits are spurious */ + error = abs((error - BIT(32))) >> 16; + + if (error < best_error) { + best->r = r; + best->f = f; + best->od = od; + best_error = error; + } + break; + } + } while (f < 64 && i + 1 < ARRAY_SIZE(factors) && error != 0); + + if (best_error == S64_MAX) + return -EINVAL; + + log_debug("best error %lld\n", best_error); + return 0; +} + +static ulong k210_pll_set_rate(struct clk *clk, ulong rate) +{ + int err; + long long rate_in = clk_get_parent_rate(clk); + struct k210_pll_config config = {}; + struct k210_pll *pll = to_k210_pll(clk); + u32 reg; + + if (rate_in < 0) + return rate_in; + + log_debug("Calculating parameters with rate=%lu and rate_in=%lld\n", + rate, rate_in); + err = k210_pll_calc_config(rate, rate_in, &config); + if (err) + return err; + log_debug("Got r=%u f=%u od=%u\n", config.r, config.f, config.od); + + /* + * Don't use clk_disable as it might not actually disable the pll due to + * refcounting + */ + k210_pll_disable(clk); + + reg = readl(pll->reg); + reg &= ~K210_PLL_CLKR + & ~K210_PLL_CLKF + & ~K210_PLL_CLKOD + & ~K210_PLL_BWADJ; + reg |= FIELD_PREP(K210_PLL_CLKR, config.r - 1) + | FIELD_PREP(K210_PLL_CLKF, config.f - 1) + | FIELD_PREP(K210_PLL_CLKOD, config.od - 1) + | FIELD_PREP(K210_PLL_BWADJ, config.f - 1); + writel(reg, pll->reg); + + err = k210_pll_enable(clk); + if (err) + return err; + + serial_setbrg(); + return clk_get_rate(clk); +} +#endif /* CONFIG_CLK_K210_SET_RATE */ + +static ulong k210_pll_get_rate(struct clk *clk) +{ + long long rate_in = clk_get_parent_rate(clk); + struct k210_pll *pll = to_k210_pll(clk); + u64 r, f, od; + u32 reg = readl(pll->reg); + + if (rate_in < 0 || (reg & K210_PLL_BYPASS)) + return rate_in; + + if (!(reg & K210_PLL_PWRD)) + return 0; + + r = FIELD_GET(K210_PLL_CLKR, reg) + 1; + f = FIELD_GET(K210_PLL_CLKF, reg) + 1; + od = FIELD_GET(K210_PLL_CLKOD, reg) + 1; + + return DIV_ROUND_DOWN_ULL(((u64)rate_in) * f, r * od); +} + +/* + * Wait for the PLL to be locked. If the PLL is not locked, try clearing the + * slip before retrying + */ +static void k210_pll_waitfor_lock(struct k210_pll *pll) +{ + u32 mask = GENMASK(pll->width - 1, 0) << pll->shift; + + while (true) { + u32 reg = readl(pll->lock); + + if ((reg & mask) == mask) + break; + + reg |= BIT(pll->shift + K210_PLL_CLEAR_SLIP); + writel(reg, pll->lock); + } +} + +/* Adapted from sysctl_pll_enable */ +static int k210_pll_enable(struct clk *clk) +{ + struct k210_pll *pll = to_k210_pll(clk); + u32 reg = readl(pll->reg); + + if ((reg | K210_PLL_PWRD) && !(reg | K210_PLL_RESET)) + return 0; + + reg |= K210_PLL_PWRD; + writel(reg, pll->reg); + + /* Ensure reset is low before asserting it */ + reg &= ~K210_PLL_RESET; + writel(reg, pll->reg); + reg |= K210_PLL_RESET; + writel(reg, pll->reg); + nop(); + nop(); + reg &= ~K210_PLL_RESET; + writel(reg, pll->reg); + + k210_pll_waitfor_lock(pll); + + reg &= ~K210_PLL_BYPASS; + writel(reg, pll->reg); + + return 0; +} + +static int k210_pll_disable(struct clk *clk) +{ + struct k210_pll *pll = to_k210_pll(clk); + u32 reg = readl(pll->reg); + + /* + * Bypassing before powering off is important so child clocks don't stop + * working. This is especially important for pll0, the indirect parent + * of the cpu clock. + */ + reg |= K210_PLL_BYPASS; + writel(reg, pll->reg); + + reg &= ~K210_PLL_PWRD; + writel(reg, pll->reg); + return 0; +} + +const struct clk_ops k210_pll_ops = { + .get_rate = k210_pll_get_rate, +#ifdef CONFIG_CLK_K210_SET_RATE + .set_rate = k210_pll_set_rate, +#endif + .enable = k210_pll_enable, + .disable = k210_pll_disable, +}; + +struct clk *k210_register_pll_struct(const char *name, const char *parent_name, + struct k210_pll *pll) +{ + int ret; + struct clk *clk = &pll->clk; + + ret = clk_register(clk, CLK_K210_PLL, name, parent_name); + if (ret) + return ERR_PTR(ret); + return clk; +} + +struct clk *k210_register_pll(const char *name, const char *parent_name, + void __iomem *reg, void __iomem *lock, u8 shift, + u8 width) +{ + struct clk *clk; + struct k210_pll *pll; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + pll->reg = reg; + pll->lock = lock; + pll->shift = shift; + pll->width = width; + + clk = k210_register_pll_struct(name, parent_name, pll); + if (IS_ERR(clk)) + kfree(pll); + return clk; +} + +U_BOOT_DRIVER(k210_pll) = { + .name = CLK_K210_PLL, + .id = UCLASS_CLK, + .ops = &k210_pll_ops, +}; diff --git a/include/kendryte/pll.h b/include/kendryte/pll.h new file mode 100644 index 00000000000..c8e3200799e --- /dev/null +++ b/include/kendryte/pll.h @@ -0,0 +1,57 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019-20 Sean Anderson + */ +#ifndef K210_PLL_H +#define K210_PLL_H + +#include +#include + +#define K210_PLL_CLKR GENMASK(3, 0) +#define K210_PLL_CLKF GENMASK(9, 4) +#define K210_PLL_CLKOD GENMASK(13, 10) /* Output Divider */ +#define K210_PLL_BWADJ GENMASK(19, 14) /* BandWidth Adjust */ +#define K210_PLL_RESET BIT(20) +#define K210_PLL_PWRD BIT(21) /* PoWeReD */ +#define K210_PLL_INTFB BIT(22) /* Internal FeedBack */ +#define K210_PLL_BYPASS BIT(23) +#define K210_PLL_TEST BIT(24) +#define K210_PLL_EN BIT(25) +#define K210_PLL_TEST_EN BIT(26) + +#define K210_PLL_LOCK 0 +#define K210_PLL_CLEAR_SLIP 2 +#define K210_PLL_TEST_OUT 3 + +struct k210_pll { + struct clk clk; + void __iomem *reg; /* Base PLL register */ + void __iomem *lock; /* Common PLL lock register */ + u8 shift; /* Offset of bits in lock register */ + u8 width; /* Width of lock bits to test against */ +}; + +#define to_k210_pll(_clk) container_of(_clk, struct k210_pll, clk) + +struct k210_pll_config { + u8 r; + u8 f; + u8 od; +}; + +#ifdef CONFIG_UNIT_TEST +TEST_STATIC int k210_pll_calc_config(u32 rate, u32 rate_in, + struct k210_pll_config *best); +#define nop() +#endif + +extern const struct clk_ops k210_pll_ops; + +struct clk *k210_register_pll_struct(const char *name, const char *parent_name, + struct k210_pll *pll); +struct clk *k210_register_pll(const char *name, const char *parent_name, + void __iomem *reg, void __iomem *lock, u8 shift, + u8 width); + +#endif /* K210_PLL_H */ diff --git a/include/test/export.h b/include/test/export.h new file mode 100644 index 00000000000..afc755a8ffd --- /dev/null +++ b/include/test/export.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Sean Anderson + */ + +#ifndef TEST_EXPORT_H +#define TEST_EXPORT_H + +/* Declare something static, unless we are doing unit tests */ +#ifdef CONFIG_UNIT_TEST +#define TEST_STATIC +#else +#define TEST_STATIC static +#endif + +#endif /* TEST_EXPORT_H */ diff --git a/test/dm/Makefile b/test/dm/Makefile index 6c18fd04ce1..5094a7866af 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -73,4 +73,5 @@ obj-$(CONFIG_DMA) += dma.o obj-$(CONFIG_DM_MDIO) += mdio.o obj-$(CONFIG_DM_MDIO_MUX) += mdio_mux.o obj-$(CONFIG_DM_RNG) += rng.o +obj-$(CONFIG_CLK_K210_SET_RATE) += k210_pll.o endif diff --git a/test/dm/k210_pll.c b/test/dm/k210_pll.c new file mode 100644 index 00000000000..54764f269c5 --- /dev/null +++ b/test/dm/k210_pll.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Sean Anderson + */ + +#include +/* For DIV_ROUND_DOWN_ULL, defined in linux/kernel.h */ +#include +#include +#include +#include + +static int dm_test_k210_pll_calc_config(u32 rate, u32 rate_in, + struct k210_pll_config *best) +{ + u64 f, r, od, max_r, inv_ratio; + s64 error, best_error; + + best_error = S64_MAX; + error = best_error; + max_r = min(16ULL, DIV_ROUND_DOWN_ULL(rate_in, 13300000)); + inv_ratio = DIV_ROUND_CLOSEST_ULL((u64)rate_in << 32, rate); + + /* Brute force it */ + for (r = 1; r <= max_r; r++) { + for (f = 1; f <= 64; f++) { + for (od = 1; od <= 16; od++) { + u64 vco = DIV_ROUND_CLOSEST_ULL(rate_in * f, r); + + if (vco > 1750000000 || vco < 340000000) + continue; + + error = DIV_ROUND_CLOSEST_ULL(f * inv_ratio, + r * od); + /* The lower 16 bits are spurious */ + error = abs((error - BIT(32))) >> 16; + if (error < best_error) { + best->r = r; + best->f = f; + best->od = od; + best_error = error; + } + } + } + } + + if (best_error == S64_MAX) + return -EINVAL; + return 0; +} + +static int dm_test_k210_pll_compare(struct k210_pll_config *ours, + struct k210_pll_config *theirs) +{ + return (u32)ours->f * theirs->r * theirs->od != + (u32)theirs->f * ours->r * ours->od; +} + +static int dm_test_k210_pll(struct unit_test_state *uts) +{ + struct k210_pll_config ours, theirs; + + /* General range checks */ + ut_asserteq(-EINVAL, k210_pll_calc_config(0, 26000000, &theirs)); + ut_asserteq(-EINVAL, k210_pll_calc_config(390000000, 0, &theirs)); + ut_asserteq(-EINVAL, k210_pll_calc_config(2000000000, 26000000, + &theirs)); + ut_asserteq(-EINVAL, k210_pll_calc_config(390000000, 2000000000, + &theirs)); + ut_asserteq(-EINVAL, k210_pll_calc_config(1500000000, 20000000, + &theirs)); + + /* Verify we get the same output with brute-force */ + ut_assertok(dm_test_k210_pll_calc_config(390000000, 26000000, &ours)); + ut_assertok(k210_pll_calc_config(390000000, 26000000, &theirs)); + ut_assertok(dm_test_k210_pll_compare(&ours, &theirs)); + + ut_assertok(dm_test_k210_pll_calc_config(26000000, 390000000, &ours)); + ut_assertok(k210_pll_calc_config(26000000, 390000000, &theirs)); + ut_assertok(dm_test_k210_pll_compare(&ours, &theirs)); + + ut_assertok(dm_test_k210_pll_calc_config(400000000, 26000000, &ours)); + ut_assertok(k210_pll_calc_config(400000000, 26000000, &theirs)); + ut_assertok(dm_test_k210_pll_compare(&ours, &theirs)); + + ut_assertok(dm_test_k210_pll_calc_config(27000000, 26000000, &ours)); + ut_assertok(k210_pll_calc_config(27000000, 26000000, &theirs)); + ut_assertok(dm_test_k210_pll_compare(&ours, &theirs)); + + ut_assertok(dm_test_k210_pll_calc_config(26000000, 27000000, &ours)); + ut_assertok(k210_pll_calc_config(26000000, 27000000, &theirs)); + ut_assertok(dm_test_k210_pll_compare(&ours, &theirs)); + + return 0; +} +DM_TEST(dm_test_k210_pll, 0); -- cgit v1.3.1 From 1a198cf8862b0540894ba6569c55244b1bd3e824 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:10 -0400 Subject: clk: Add a bypass clock for K210 This is a small driver to do a software bypass of a clock if hardware bypass is not working. I have tried to write this in a generic fashion, so that it could be potentially broken out of the kendryte code at some future date. For the K210, it is used to have aclk bypass pll0 and use in0 instead so that the CPU keeps on working. Signed-off-by: Sean Anderson CC: Lukasz Majewski --- drivers/clk/kendryte/Makefile | 2 +- drivers/clk/kendryte/bypass.c | 270 ++++++++++++++++++++++++++++++++++++++++++ include/kendryte/bypass.h | 31 +++++ 3 files changed, 302 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/kendryte/bypass.c create mode 100644 include/kendryte/bypass.h (limited to 'drivers') diff --git a/drivers/clk/kendryte/Makefile b/drivers/clk/kendryte/Makefile index c56d93ea1c5..47f682fce3e 100644 --- a/drivers/clk/kendryte/Makefile +++ b/drivers/clk/kendryte/Makefile @@ -1 +1 @@ -obj-y += pll.o +obj-y += bypass.o pll.o diff --git a/drivers/clk/kendryte/bypass.c b/drivers/clk/kendryte/bypass.c new file mode 100644 index 00000000000..d1fd28175ba --- /dev/null +++ b/drivers/clk/kendryte/bypass.c @@ -0,0 +1,270 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Sean Anderson + */ + +#define LOG_CATEGORY UCLASS_CLK +#include + +#include +#include +#include +#include + +#define CLK_K210_BYPASS "k210_clk_bypass" + +/* + * This is a small driver to do a software bypass of a clock if hardware bypass + * is not working. I have tried to write this in a generic fashion, so that it + * could be potentially broken out of the kendryte code at some future date. + * + * Say you have the following clock configuration + * + * +---+ +---+ + * |osc| |pll| + * +---+ +---+ + * ^ + * /| + * / | + * / | + * / | + * / | + * +---+ +---+ + * |clk| |clk| + * +---+ +---+ + * + * But the pll does not have a bypass, so when you configure the pll, the + * configuration needs to change to look like + * + * +---+ +---+ + * |osc| |pll| + * +---+ +---+ + * ^ + * |\ + * | \ + * | \ + * | \ + * | \ + * +---+ +---+ + * |clk| |clk| + * +---+ +---+ + * + * To set this up, create a bypass clock with bypassee=pll and alt=osc. When + * creating the child clocks, set their parent to the bypass clock. After + * creating all the children, call k210_bypass_setchildren(). + */ + +static int k210_bypass_dobypass(struct k210_bypass *bypass) +{ + int ret, i; + + /* + * If we already have saved parents, then the children are already + * bypassed + */ + if (bypass->child_count && bypass->saved_parents[0]) + return 0; + + for (i = 0; i < bypass->child_count; i++) { + struct clk *child = bypass->children[i]; + struct clk *parent = clk_get_parent(child); + + if (IS_ERR(parent)) { + for (; i; i--) + bypass->saved_parents[i] = NULL; + return PTR_ERR(parent); + } + bypass->saved_parents[i] = parent; + } + + for (i = 0; i < bypass->child_count; i++) { + struct clk *child = bypass->children[i]; + + ret = clk_set_parent(child, bypass->alt); + if (ret) { + for (; i; i--) + clk_set_parent(bypass->children[i], + bypass->saved_parents[i]); + for (i = 0; i < bypass->child_count; i++) + bypass->saved_parents[i] = NULL; + return ret; + } + } + + return 0; +} + +static int k210_bypass_unbypass(struct k210_bypass *bypass) +{ + int err, ret, i; + + if (!bypass->child_count && !bypass->saved_parents[0]) { + log_warning("Cannot unbypass children; dobypass not called first\n"); + return 0; + } + + ret = 0; + for (i = 0; i < bypass->child_count; i++) { + err = clk_set_parent(bypass->children[i], + bypass->saved_parents[i]); + if (err) + ret = err; + bypass->saved_parents[i] = NULL; + } + return ret; +} + +static ulong k210_bypass_get_rate(struct clk *clk) +{ + struct k210_bypass *bypass = to_k210_bypass(clk); + const struct clk_ops *ops = bypass->bypassee_ops; + + if (ops->get_rate) + return ops->get_rate(bypass->bypassee); + else + return clk_get_parent_rate(bypass->bypassee); +} + +static ulong k210_bypass_set_rate(struct clk *clk, unsigned long rate) +{ + int ret; + struct k210_bypass *bypass = to_k210_bypass(clk); + const struct clk_ops *ops = bypass->bypassee_ops; + + /* Don't bother bypassing if we aren't going to set the rate */ + if (!ops->set_rate) + return k210_bypass_get_rate(clk); + + ret = k210_bypass_dobypass(bypass); + if (ret) + return ret; + + ret = ops->set_rate(bypass->bypassee, rate); + if (ret < 0) + return ret; + + return k210_bypass_unbypass(bypass); +} + +static int k210_bypass_set_parent(struct clk *clk, struct clk *parent) +{ + struct k210_bypass *bypass = to_k210_bypass(clk); + const struct clk_ops *ops = bypass->bypassee_ops; + + if (ops->set_parent) + return ops->set_parent(bypass->bypassee, parent); + else + return -ENOTSUPP; +} + +/* + * For these next two functions, do the bypassing even if there is no + * en-/-disable function, since the bypassing itself can be observed in between + * calls. + */ +static int k210_bypass_enable(struct clk *clk) +{ + int ret; + struct k210_bypass *bypass = to_k210_bypass(clk); + const struct clk_ops *ops = bypass->bypassee_ops; + + ret = k210_bypass_dobypass(bypass); + if (ret) + return ret; + + if (ops->enable) + ret = ops->enable(bypass->bypassee); + else + ret = 0; + if (ret) + return ret; + + return k210_bypass_unbypass(bypass); +} + +static int k210_bypass_disable(struct clk *clk) +{ + int ret; + struct k210_bypass *bypass = to_k210_bypass(clk); + const struct clk_ops *ops = bypass->bypassee_ops; + + ret = k210_bypass_dobypass(bypass); + if (ret) + return ret; + + if (ops->disable) + return ops->disable(bypass->bypassee); + else + return 0; +} + +static const struct clk_ops k210_bypass_ops = { + .get_rate = k210_bypass_get_rate, + .set_rate = k210_bypass_set_rate, + .set_parent = k210_bypass_set_parent, + .enable = k210_bypass_enable, + .disable = k210_bypass_disable, +}; + +int k210_bypass_set_children(struct clk *clk, struct clk **children, + size_t child_count) +{ + struct k210_bypass *bypass = to_k210_bypass(clk); + + kfree(bypass->saved_parents); + if (child_count) { + bypass->saved_parents = + kcalloc(child_count, sizeof(struct clk *), GFP_KERNEL); + if (!bypass->saved_parents) + return -ENOMEM; + } + bypass->child_count = child_count; + bypass->children = children; + + return 0; +} + +struct clk *k210_register_bypass_struct(const char *name, + const char *parent_name, + struct k210_bypass *bypass) +{ + int ret; + struct clk *clk; + + clk = &bypass->clk; + + ret = clk_register(clk, CLK_K210_BYPASS, name, parent_name); + if (ret) + return ERR_PTR(ret); + + bypass->bypassee->dev = clk->dev; + return clk; +} + +struct clk *k210_register_bypass(const char *name, const char *parent_name, + struct clk *bypassee, + const struct clk_ops *bypassee_ops, + struct clk *alt) +{ + struct clk *clk; + struct k210_bypass *bypass; + + bypass = kzalloc(sizeof(*bypass), GFP_KERNEL); + if (!bypass) + return ERR_PTR(-ENOMEM); + + bypass->bypassee = bypassee; + bypass->bypassee_ops = bypassee_ops; + bypass->alt = alt; + + clk = k210_register_bypass_struct(name, parent_name, bypass); + if (IS_ERR(clk)) + kfree(bypass); + return clk; +} + +U_BOOT_DRIVER(k210_bypass) = { + .name = CLK_K210_BYPASS, + .id = UCLASS_CLK, + .ops = &k210_bypass_ops, +}; diff --git a/include/kendryte/bypass.h b/include/kendryte/bypass.h new file mode 100644 index 00000000000..a081cbd12ff --- /dev/null +++ b/include/kendryte/bypass.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Sean Anderson + */ +#ifndef K210_BYPASS_H +#define K210_BYPASS_H + +#include + +struct k210_bypass { + struct clk clk; + struct clk **children; /* Clocks to reparent */ + struct clk **saved_parents; /* Parents saved over en-/dis-able */ + struct clk *bypassee; /* Clock to bypass */ + const struct clk_ops *bypassee_ops; /* Ops of the bypass clock */ + struct clk *alt; /* Clock to set children to when bypassing */ + size_t child_count; +}; + +#define to_k210_bypass(_clk) container_of(_clk, struct k210_bypass, clk) + +int k210_bypass_set_children(struct clk *clk, struct clk **children, + size_t child_count); +struct clk *k210_register_bypass_struct(const char *name, + const char *parent_name, + struct k210_bypass *bypass); +struct clk *k210_register_bypass(const char *name, const char *parent_name, + struct clk *bypassee, + const struct clk_ops *bypassee_ops, + struct clk *alt); +#endif /* K210_BYPASS_H */ -- cgit v1.3.1 From f9c7d4f99f51ac9c1cf513111c21395f93d2dd53 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:11 -0400 Subject: clk: Add K210 clock support Due to the large number of clocks, I decided to use the CCF. The overall structure is modeled after the imx code. Clocks parameters are stored in several arrays, and are then instantiated at run-time. There are some translation macros (FOOIFY()) which allow for more dense packing. Signed-off-by: Sean Anderson CC: Lukasz Majewski --- MAINTAINERS | 7 + .../mfd/kendryte,k210-sysctl.txt | 33 + drivers/clk/kendryte/Kconfig | 2 +- drivers/clk/kendryte/Makefile | 2 +- drivers/clk/kendryte/clk.c | 663 +++++++++++++++++++++ include/dt-bindings/clock/k210-sysctl.h | 59 ++ include/dt-bindings/mfd/k210-sysctl.h | 38 ++ include/kendryte/clk.h | 35 ++ 8 files changed, 837 insertions(+), 2 deletions(-) create mode 100644 doc/device-tree-bindings/mfd/kendryte,k210-sysctl.txt create mode 100644 drivers/clk/kendryte/clk.c create mode 100644 include/dt-bindings/clock/k210-sysctl.h create mode 100644 include/dt-bindings/mfd/k210-sysctl.h create mode 100644 include/kendryte/clk.h (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 0623da095f1..9d2d3a7923e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -874,6 +874,13 @@ F: arch/riscv/ F: cmd/riscv/ F: tools/prelink-riscv.c +RISC-V KENDRYTE +M: Sean Anderson +S: Maintained +F: doc/device-tree-bindings/mfd/kendryte,k210-sysctl.txt +F: drivers/clk/kendryte/ +F: include/kendryte/ + RNG M: Sughosh Ganu R: Heinrich Schuchardt diff --git a/doc/device-tree-bindings/mfd/kendryte,k210-sysctl.txt b/doc/device-tree-bindings/mfd/kendryte,k210-sysctl.txt new file mode 100644 index 00000000000..5b24abcb62c --- /dev/null +++ b/doc/device-tree-bindings/mfd/kendryte,k210-sysctl.txt @@ -0,0 +1,33 @@ +Kendryte K210 Sysctl + +This binding describes the K210 sysctl device, which contains many miscellaneous +registers controlling system functionality. This node is a register map and can +be reference by other bindings which need a phandle to the K210 sysctl regmap. + +Required properties: +- compatible: should be + "kendryte,k210-sysctl", "syscon", "simple-mfd" +- reg: address and length of the sysctl registers +- reg-io-width: must be <4> + +Clock sub-node + +This node is a binding for the clock tree driver + +Required properties: +- compatible: should be "kendryte,k210-clk" +- clocks: phandle to the "in0" external oscillator +- #clock-cells: must be <1> + +Example: +sysctl: syscon@50440000 { + compatible = "kendryte,k210-sysctl", "syscon", "simple-mfd"; + reg = <0x50440000 0x100>; + reg-io-width = <4>; + + sysclk: clock-controller { + compatible = "kendryte,k210-clk"; + clocks = <&in0>; + #clock-cells = <1>; + }; +}; diff --git a/drivers/clk/kendryte/Kconfig b/drivers/clk/kendryte/Kconfig index 7b69c8afaf7..073fca07816 100644 --- a/drivers/clk/kendryte/Kconfig +++ b/drivers/clk/kendryte/Kconfig @@ -1,6 +1,6 @@ config CLK_K210 bool "Clock support for Kendryte K210" - depends on CLK && CLK_CCF + depends on CLK && CLK_CCF && CLK_COMPOSITE_CCF help This enables support clock driver for Kendryte K210 platforms. diff --git a/drivers/clk/kendryte/Makefile b/drivers/clk/kendryte/Makefile index 47f682fce3e..6fb68253ae0 100644 --- a/drivers/clk/kendryte/Makefile +++ b/drivers/clk/kendryte/Makefile @@ -1 +1 @@ -obj-y += bypass.o pll.o +obj-y += bypass.o clk.o pll.o diff --git a/drivers/clk/kendryte/clk.c b/drivers/clk/kendryte/clk.c new file mode 100644 index 00000000000..981b3b7699b --- /dev/null +++ b/drivers/clk/kendryte/clk.c @@ -0,0 +1,663 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019-20 Sean Anderson + */ +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +/* All methods are delegated to CCF clocks */ + +static ulong k210_clk_get_rate(struct clk *clk) +{ + struct clk *c; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + return clk_get_rate(c); +} + +static ulong k210_clk_set_rate(struct clk *clk, unsigned long rate) +{ + struct clk *c; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + return clk_set_rate(c, rate); +} + +static int k210_clk_set_parent(struct clk *clk, struct clk *parent) +{ + struct clk *c, *p; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + + err = clk_get_by_id(parent->id, &p); + if (err) + return err; + + return clk_set_parent(c, p); +} + +static int k210_clk_endisable(struct clk *clk, bool enable) +{ + struct clk *c; + int err = clk_get_by_id(clk->id, &c); + + if (err) + return err; + return enable ? clk_enable(c) : clk_disable(c); +} + +static int k210_clk_enable(struct clk *clk) +{ + return k210_clk_endisable(clk, true); +} + +static int k210_clk_disable(struct clk *clk) +{ + return k210_clk_endisable(clk, false); +} + +static const struct clk_ops k210_clk_ops = { + .set_rate = k210_clk_set_rate, + .get_rate = k210_clk_get_rate, + .set_parent = k210_clk_set_parent, + .enable = k210_clk_enable, + .disable = k210_clk_disable, +}; + +/* Parents for muxed clocks */ +static const char * const generic_sels[] = { "in0_half", "pll0_half" }; +/* The first clock is in0, which is filled in by k210_clk_probe */ +static const char *aclk_sels[] = { NULL, "pll0_half" }; +static const char *pll2_sels[] = { NULL, "pll0", "pll1" }; + +/* + * All parameters for different sub-clocks are collected into parameter arrays. + * These parameters are then initialized by the clock which uses them during + * probe. To save space, ids are automatically generated for each sub-clock by + * using an enum. Instead of storing a parameter struct for each clock, even for + * those clocks which don't use a particular type of sub-clock, we can just + * store the parameters for the clocks which need them. + * + * So why do it like this? Arranging all the sub-clocks together makes it very + * easy to find bugs in the code. + */ + +#define DIV(id, off, shift, width) DIV_FLAGS(id, off, shift, width, 0) +#define DIV_LIST \ + DIV_FLAGS(K210_CLK_ACLK, K210_SYSCTL_SEL0, 1, 2, \ + CLK_DIVIDER_POWER_OF_TWO) \ + DIV(K210_CLK_APB0, K210_SYSCTL_SEL0, 3, 3) \ + DIV(K210_CLK_APB1, K210_SYSCTL_SEL0, 6, 3) \ + DIV(K210_CLK_APB2, K210_SYSCTL_SEL0, 9, 3) \ + DIV(K210_CLK_SRAM0, K210_SYSCTL_THR0, 0, 4) \ + DIV(K210_CLK_SRAM1, K210_SYSCTL_THR0, 4, 4) \ + DIV(K210_CLK_AI, K210_SYSCTL_THR0, 8, 4) \ + DIV(K210_CLK_DVP, K210_SYSCTL_THR0, 12, 4) \ + DIV(K210_CLK_ROM, K210_SYSCTL_THR0, 16, 4) \ + DIV(K210_CLK_SPI0, K210_SYSCTL_THR1, 0, 8) \ + DIV(K210_CLK_SPI1, K210_SYSCTL_THR1, 8, 8) \ + DIV(K210_CLK_SPI2, K210_SYSCTL_THR1, 16, 8) \ + DIV(K210_CLK_SPI3, K210_SYSCTL_THR1, 24, 8) \ + DIV(K210_CLK_TIMER0, K210_SYSCTL_THR2, 0, 8) \ + DIV(K210_CLK_TIMER1, K210_SYSCTL_THR2, 8, 8) \ + DIV(K210_CLK_TIMER2, K210_SYSCTL_THR2, 16, 8) \ + DIV(K210_CLK_I2S0, K210_SYSCTL_THR3, 0, 16) \ + DIV(K210_CLK_I2S1, K210_SYSCTL_THR3, 16, 16) \ + DIV(K210_CLK_I2S2, K210_SYSCTL_THR4, 0, 16) \ + DIV(K210_CLK_I2S0_M, K210_SYSCTL_THR4, 16, 8) \ + DIV(K210_CLK_I2S1_M, K210_SYSCTL_THR4, 24, 8) \ + DIV(K210_CLK_I2S2_M, K210_SYSCTL_THR4, 0, 8) \ + DIV(K210_CLK_I2C0, K210_SYSCTL_THR5, 8, 8) \ + DIV(K210_CLK_I2C1, K210_SYSCTL_THR5, 16, 8) \ + DIV(K210_CLK_I2C2, K210_SYSCTL_THR5, 24, 8) \ + DIV(K210_CLK_WDT0, K210_SYSCTL_THR6, 0, 8) \ + DIV(K210_CLK_WDT1, K210_SYSCTL_THR6, 8, 8) + +#define _DIVIFY(id) K210_CLK_DIV_##id +#define DIVIFY(id) _DIVIFY(id) + +enum k210_div_ids { +#define DIV_FLAGS(id, ...) DIVIFY(id), + DIV_LIST +#undef DIV_FLAGS +}; + +struct k210_div_params { + u8 off; + u8 shift; + u8 width; + u8 flags; +}; + +static const struct k210_div_params k210_divs[] = { +#define DIV_FLAGS(id, _off, _shift, _width, _flags) \ + [DIVIFY(id)] = { \ + .off = (_off), \ + .shift = (_shift), \ + .width = (_width), \ + .flags = (_flags), \ + }, + DIV_LIST +#undef DIV_FLAGS +}; + +#undef DIV +#undef DIV_LIST + +#define GATE_LIST \ + GATE(K210_CLK_CPU, K210_SYSCTL_EN_CENT, 0) \ + GATE(K210_CLK_SRAM0, K210_SYSCTL_EN_CENT, 1) \ + GATE(K210_CLK_SRAM1, K210_SYSCTL_EN_CENT, 2) \ + GATE(K210_CLK_APB0, K210_SYSCTL_EN_CENT, 3) \ + GATE(K210_CLK_APB1, K210_SYSCTL_EN_CENT, 4) \ + GATE(K210_CLK_APB2, K210_SYSCTL_EN_CENT, 5) \ + GATE(K210_CLK_ROM, K210_SYSCTL_EN_PERI, 0) \ + GATE(K210_CLK_DMA, K210_SYSCTL_EN_PERI, 1) \ + GATE(K210_CLK_AI, K210_SYSCTL_EN_PERI, 2) \ + GATE(K210_CLK_DVP, K210_SYSCTL_EN_PERI, 3) \ + GATE(K210_CLK_FFT, K210_SYSCTL_EN_PERI, 4) \ + GATE(K210_CLK_GPIO, K210_SYSCTL_EN_PERI, 5) \ + GATE(K210_CLK_SPI0, K210_SYSCTL_EN_PERI, 6) \ + GATE(K210_CLK_SPI1, K210_SYSCTL_EN_PERI, 7) \ + GATE(K210_CLK_SPI2, K210_SYSCTL_EN_PERI, 8) \ + GATE(K210_CLK_SPI3, K210_SYSCTL_EN_PERI, 9) \ + GATE(K210_CLK_I2S0, K210_SYSCTL_EN_PERI, 10) \ + GATE(K210_CLK_I2S1, K210_SYSCTL_EN_PERI, 11) \ + GATE(K210_CLK_I2S2, K210_SYSCTL_EN_PERI, 12) \ + GATE(K210_CLK_I2C0, K210_SYSCTL_EN_PERI, 13) \ + GATE(K210_CLK_I2C1, K210_SYSCTL_EN_PERI, 14) \ + GATE(K210_CLK_I2C2, K210_SYSCTL_EN_PERI, 15) \ + GATE(K210_CLK_UART1, K210_SYSCTL_EN_PERI, 16) \ + GATE(K210_CLK_UART2, K210_SYSCTL_EN_PERI, 17) \ + GATE(K210_CLK_UART3, K210_SYSCTL_EN_PERI, 18) \ + GATE(K210_CLK_AES, K210_SYSCTL_EN_PERI, 19) \ + GATE(K210_CLK_FPIOA, K210_SYSCTL_EN_PERI, 20) \ + GATE(K210_CLK_TIMER0, K210_SYSCTL_EN_PERI, 21) \ + GATE(K210_CLK_TIMER1, K210_SYSCTL_EN_PERI, 22) \ + GATE(K210_CLK_TIMER2, K210_SYSCTL_EN_PERI, 23) \ + GATE(K210_CLK_WDT0, K210_SYSCTL_EN_PERI, 24) \ + GATE(K210_CLK_WDT1, K210_SYSCTL_EN_PERI, 25) \ + GATE(K210_CLK_SHA, K210_SYSCTL_EN_PERI, 26) \ + GATE(K210_CLK_OTP, K210_SYSCTL_EN_PERI, 27) \ + GATE(K210_CLK_RTC, K210_SYSCTL_EN_PERI, 29) + +#define _GATEIFY(id) K210_CLK_GATE_##id +#define GATEIFY(id) _GATEIFY(id) + +enum k210_gate_ids { +#define GATE(id, ...) GATEIFY(id), + GATE_LIST +#undef GATE +}; + +struct k210_gate_params { + u8 off; + u8 bit_idx; +}; + +static const struct k210_gate_params k210_gates[] = { +#define GATE(id, _off, _idx) \ + [GATEIFY(id)] = { \ + .off = (_off), \ + .bit_idx = (_idx), \ + }, + GATE_LIST +#undef GATE +}; + +#undef GATE_LIST + +#define MUX(id, reg, shift, width) \ + MUX_PARENTS(id, generic_sels, reg, shift, width) +#define MUX_LIST \ + MUX_PARENTS(K210_CLK_PLL2, pll2_sels, K210_SYSCTL_PLL2, 26, 2) \ + MUX_PARENTS(K210_CLK_ACLK, aclk_sels, K210_SYSCTL_SEL0, 0, 1) \ + MUX(K210_CLK_SPI3, K210_SYSCTL_SEL0, 12, 1) \ + MUX(K210_CLK_TIMER0, K210_SYSCTL_SEL0, 13, 1) \ + MUX(K210_CLK_TIMER1, K210_SYSCTL_SEL0, 14, 1) \ + MUX(K210_CLK_TIMER2, K210_SYSCTL_SEL0, 15, 1) + +#define _MUXIFY(id) K210_CLK_MUX_##id +#define MUXIFY(id) _MUXIFY(id) + +enum k210_mux_ids { +#define MUX_PARENTS(id, ...) MUXIFY(id), + MUX_LIST +#undef MUX_PARENTS + K210_CLK_MUX_NONE, +}; + +struct k210_mux_params { + const char *const *parent_names; + u8 num_parents; + u8 off; + u8 shift; + u8 width; +}; + +static const struct k210_mux_params k210_muxes[] = { +#define MUX_PARENTS(id, parents, _off, _shift, _width) \ + [MUXIFY(id)] = { \ + .parent_names = (const char * const *)(parents), \ + .num_parents = ARRAY_SIZE(parents), \ + .off = (_off), \ + .shift = (_shift), \ + .width = (_width), \ + }, + MUX_LIST +#undef MUX_PARENTS +}; + +#undef MUX +#undef MUX_LIST + +struct k210_pll_params { + u8 off; + u8 lock_off; + u8 shift; + u8 width; +}; + +static const struct k210_pll_params k210_plls[] = { +#define PLL(_off, _shift, _width) { \ + .off = (_off), \ + .lock_off = K210_SYSCTL_PLL_LOCK, \ + .shift = (_shift), \ + .width = (_width), \ +} + [0] = PLL(K210_SYSCTL_PLL0, 0, 2), + [1] = PLL(K210_SYSCTL_PLL1, 8, 1), + [2] = PLL(K210_SYSCTL_PLL2, 16, 1), +#undef PLL +}; + +#define COMP(id) \ + COMP_FULL(id, MUXIFY(id), DIVIFY(id), GATEIFY(id)) +#define COMP_NOMUX(id) \ + COMP_FULL(id, K210_CLK_MUX_NONE, DIVIFY(id), GATEIFY(id)) +#define COMP_LIST \ + COMP(K210_CLK_SPI3) \ + COMP(K210_CLK_TIMER0) \ + COMP(K210_CLK_TIMER1) \ + COMP(K210_CLK_TIMER2) \ + COMP_NOMUX(K210_CLK_SRAM0) \ + COMP_NOMUX(K210_CLK_SRAM1) \ + COMP_NOMUX(K210_CLK_ROM) \ + COMP_NOMUX(K210_CLK_DVP) \ + COMP_NOMUX(K210_CLK_APB0) \ + COMP_NOMUX(K210_CLK_APB1) \ + COMP_NOMUX(K210_CLK_APB2) \ + COMP_NOMUX(K210_CLK_AI) \ + COMP_NOMUX(K210_CLK_I2S0) \ + COMP_NOMUX(K210_CLK_I2S1) \ + COMP_NOMUX(K210_CLK_I2S2) \ + COMP_NOMUX(K210_CLK_WDT0) \ + COMP_NOMUX(K210_CLK_WDT1) \ + COMP_NOMUX(K210_CLK_SPI0) \ + COMP_NOMUX(K210_CLK_SPI1) \ + COMP_NOMUX(K210_CLK_SPI2) \ + COMP_NOMUX(K210_CLK_I2C0) \ + COMP_NOMUX(K210_CLK_I2C1) \ + COMP_NOMUX(K210_CLK_I2C2) + +#define _COMPIFY(id) K210_CLK_COMP_##id +#define COMPIFY(id) _COMPIFY(id) + +enum k210_comp_ids { +#define COMP_FULL(id, ...) COMPIFY(id), + COMP_LIST +#undef COMP_FULL +}; + +struct k210_comp_params { + u8 mux; + u8 div; + u8 gate; +}; + +static const struct k210_comp_params k210_comps[] = { +#define COMP_FULL(id, _mux, _div, _gate) \ + [COMPIFY(id)] = { \ + .mux = (_mux), \ + .div = (_div), \ + .gate = (_gate), \ + }, + COMP_LIST +#undef COMP_FULL +}; + +#undef COMP +#undef COMP_ID +#undef COMP_NOMUX +#undef COMP_NOMUX_ID +#undef COMP_LIST + +static struct clk *k210_bypass_children = { + NULL, +}; + +/* Helper functions to create sub-clocks */ +static struct clk_mux *k210_create_mux(const struct k210_mux_params *params, + void *base) +{ + struct clk_mux *mux = kzalloc(sizeof(*mux), GFP_KERNEL); + + if (!mux) + return mux; + + mux->reg = base + params->off; + mux->mask = BIT(params->width) - 1; + mux->shift = params->shift; + mux->parent_names = params->parent_names; + mux->num_parents = params->num_parents; + + return mux; +} + +static struct clk_divider *k210_create_div(const struct k210_div_params *params, + void *base) +{ + struct clk_divider *div = kzalloc(sizeof(*div), GFP_KERNEL); + + if (!div) + return div; + + div->reg = base + params->off; + div->shift = params->shift; + div->width = params->width; + div->flags = params->flags; + + return div; +} + +static struct clk_gate *k210_create_gate(const struct k210_gate_params *params, + void *base) +{ + struct clk_gate *gate = kzalloc(sizeof(*gate), GFP_KERNEL); + + if (!gate) + return gate; + + gate->reg = base + params->off; + gate->bit_idx = params->bit_idx; + + return gate; +} + +static struct k210_pll *k210_create_pll(const struct k210_pll_params *params, + void *base) +{ + struct k210_pll *pll = kzalloc(sizeof(*pll), GFP_KERNEL); + + if (!pll) + return pll; + + pll->reg = base + params->off; + pll->lock = base + params->lock_off; + pll->shift = params->shift; + pll->width = params->width; + + return pll; +} + +/* Create all sub-clocks, and then register the composite clock */ +static struct clk *k210_register_comp(const struct k210_comp_params *params, + void *base, const char *name, + const char *parent) +{ + const char *const *parent_names; + int num_parents; + struct clk *comp; + const struct clk_ops *mux_ops; + struct clk_mux *mux; + struct clk_divider *div; + struct clk_gate *gate; + + if (params->mux == K210_CLK_MUX_NONE) { + if (!parent) + return ERR_PTR(-EINVAL); + + mux_ops = NULL; + mux = NULL; + parent_names = &parent; + num_parents = 1; + } else { + mux_ops = &clk_mux_ops; + mux = k210_create_mux(&k210_muxes[params->mux], base); + if (!mux) + return ERR_PTR(-ENOMEM); + + parent_names = mux->parent_names; + num_parents = mux->num_parents; + } + + div = k210_create_div(&k210_divs[params->div], base); + if (!div) { + comp = ERR_PTR(-ENOMEM); + goto cleanup_mux; + } + + gate = k210_create_gate(&k210_gates[params->gate], base); + if (!gate) { + comp = ERR_PTR(-ENOMEM); + goto cleanup_div; + } + + comp = clk_register_composite(NULL, name, parent_names, num_parents, + &mux->clk, mux_ops, + &div->clk, &clk_divider_ops, + &gate->clk, &clk_gate_ops, 0); + if (IS_ERR(comp)) + goto cleanup_gate; + return comp; + +cleanup_gate: + free(gate); +cleanup_div: + free(div); +cleanup_mux: + if (mux) + free(mux); + return comp; +} + +static bool probed; + +static int k210_clk_probe(struct udevice *dev) +{ + int ret; + const char *in0; + struct clk *in0_clk, *bypass; + struct clk_mux *mux; + struct clk_divider *div; + struct k210_pll *pll; + void *base; + + /* + * Only one instance of this driver allowed. This prevents weird bugs + * when the driver fails part-way through probing. Some clocks will + * already have been registered, and re-probing will register them + * again, creating a bunch of duplicates. Better error-handling/cleanup + * could fix this, but it's Probably Not Worth It (TM). + */ + if (probed) + return -ENOTSUPP; + + base = dev_read_addr_ptr(dev_get_parent(dev)); + if (!base) + return -EINVAL; + + in0_clk = kzalloc(sizeof(*in0_clk), GFP_KERNEL); + if (!in0_clk) + return -ENOMEM; + + ret = clk_get_by_index(dev, 0, in0_clk); + if (ret) + return ret; + in0 = in0_clk->dev->name; + + probed = true; + + aclk_sels[0] = in0; + pll2_sels[0] = in0; + + /* + * All PLLs have a broken bypass, but pll0 has the CPU downstream, so we + * need to manually reparent it whenever we configure pll0 + */ + pll = k210_create_pll(&k210_plls[0], base); + if (pll) { + bypass = k210_register_bypass("pll0", in0, &pll->clk, + &k210_pll_ops, in0_clk); + clk_dm(K210_CLK_PLL0, bypass); + } else { + return -ENOMEM; + } + + { + const struct k210_pll_params *params = &k210_plls[1]; + + clk_dm(K210_CLK_PLL1, + k210_register_pll("pll1", in0, base + params->off, + base + params->lock_off, params->shift, + params->width)); + } + + /* PLL2 is muxed, so set up a composite clock */ + mux = k210_create_mux(&k210_muxes[MUXIFY(K210_CLK_PLL2)], base); + pll = k210_create_pll(&k210_plls[2], base); + if (!mux || !pll) { + free(mux); + free(pll); + } else { + clk_dm(K210_CLK_PLL2, + clk_register_composite(NULL, "pll2", pll2_sels, + ARRAY_SIZE(pll2_sels), + &mux->clk, &clk_mux_ops, + &pll->clk, &k210_pll_ops, + &pll->clk, &k210_pll_ops, 0)); + } + + /* Half-frequency clocks for "even" dividers */ + clk_dm(K210_CLK_IN0_H, k210_clk_half("in0_half", in0)); + clk_dm(K210_CLK_PLL0_H, k210_clk_half("pll0_half", "pll0")); + clk_dm(K210_CLK_PLL2_H, k210_clk_half("pll2_half", "pll2")); + + /* ACLK has no gate */ + mux = k210_create_mux(&k210_muxes[MUXIFY(K210_CLK_ACLK)], base); + div = k210_create_div(&k210_divs[DIVIFY(K210_CLK_ACLK)], base); + if (!mux || !div) { + free(mux); + free(div); + } else { + struct clk *aclk = + clk_register_composite(NULL, "aclk", aclk_sels, + ARRAY_SIZE(aclk_sels), + &mux->clk, &clk_mux_ops, + &div->clk, &clk_divider_ops, + NULL, NULL, 0); + clk_dm(K210_CLK_ACLK, aclk); + if (!IS_ERR(aclk)) { + k210_bypass_children = aclk; + k210_bypass_set_children(bypass, + &k210_bypass_children, 1); + } + } + +#define REGISTER_COMP(id, name) \ + clk_dm(id, \ + k210_register_comp(&k210_comps[COMPIFY(id)], base, name, NULL)) + REGISTER_COMP(K210_CLK_SPI3, "spi3"); + REGISTER_COMP(K210_CLK_TIMER0, "timer0"); + REGISTER_COMP(K210_CLK_TIMER1, "timer1"); + REGISTER_COMP(K210_CLK_TIMER2, "timer2"); +#undef REGISTER_COMP + + /* Dividing clocks, no mux */ +#define REGISTER_COMP_NOMUX(id, name, parent) \ + clk_dm(id, \ + k210_register_comp(&k210_comps[COMPIFY(id)], base, name, parent)) + REGISTER_COMP_NOMUX(K210_CLK_SRAM0, "sram0", "aclk"); + REGISTER_COMP_NOMUX(K210_CLK_SRAM1, "sram1", "aclk"); + REGISTER_COMP_NOMUX(K210_CLK_ROM, "rom", "aclk"); + REGISTER_COMP_NOMUX(K210_CLK_DVP, "dvp", "aclk"); + REGISTER_COMP_NOMUX(K210_CLK_APB0, "apb0", "aclk"); + REGISTER_COMP_NOMUX(K210_CLK_APB1, "apb1", "aclk"); + REGISTER_COMP_NOMUX(K210_CLK_APB2, "apb2", "aclk"); + REGISTER_COMP_NOMUX(K210_CLK_AI, "ai", "pll1"); + REGISTER_COMP_NOMUX(K210_CLK_I2S0, "i2s0", "pll2_half"); + REGISTER_COMP_NOMUX(K210_CLK_I2S1, "i2s1", "pll2_half"); + REGISTER_COMP_NOMUX(K210_CLK_I2S2, "i2s2", "pll2_half"); + REGISTER_COMP_NOMUX(K210_CLK_WDT0, "wdt0", "in0_half"); + REGISTER_COMP_NOMUX(K210_CLK_WDT1, "wdt1", "in0_half"); + REGISTER_COMP_NOMUX(K210_CLK_SPI0, "spi0", "pll0_half"); + REGISTER_COMP_NOMUX(K210_CLK_SPI1, "spi1", "pll0_half"); + REGISTER_COMP_NOMUX(K210_CLK_SPI2, "spi2", "pll0_half"); + REGISTER_COMP_NOMUX(K210_CLK_I2C0, "i2c0", "pll0_half"); + REGISTER_COMP_NOMUX(K210_CLK_I2C1, "i2c1", "pll0_half"); + REGISTER_COMP_NOMUX(K210_CLK_I2C2, "i2c2", "pll0_half"); +#undef REGISTER_COMP_NOMUX + + /* Dividing clocks */ +#define REGISTER_DIV(id, name, parent) do {\ + const struct k210_div_params *params = &k210_divs[DIVIFY(id)]; \ + clk_dm(id, \ + clk_register_divider(NULL, name, parent, 0, base + params->off, \ + params->shift, params->width, 0)); \ +} while (false) + REGISTER_DIV(K210_CLK_I2S0_M, "i2s0_m", "pll2_half"); + REGISTER_DIV(K210_CLK_I2S1_M, "i2s1_m", "pll2_half"); + REGISTER_DIV(K210_CLK_I2S2_M, "i2s2_m", "pll2_half"); +#undef REGISTER_DIV + + /* Gated clocks */ +#define REGISTER_GATE(id, name, parent) do { \ + const struct k210_gate_params *params = &k210_gates[GATEIFY(id)]; \ + clk_dm(id, \ + clk_register_gate(NULL, name, parent, 0, base + params->off, \ + params->bit_idx, 0, NULL)); \ +} while (false) + REGISTER_GATE(K210_CLK_CPU, "cpu", "aclk"); + REGISTER_GATE(K210_CLK_DMA, "dma", "aclk"); + REGISTER_GATE(K210_CLK_FFT, "fft", "aclk"); + REGISTER_GATE(K210_CLK_GPIO, "gpio", "apb0"); + REGISTER_GATE(K210_CLK_UART1, "uart1", "apb0"); + REGISTER_GATE(K210_CLK_UART2, "uart2", "apb0"); + REGISTER_GATE(K210_CLK_UART3, "uart3", "apb0"); + REGISTER_GATE(K210_CLK_FPIOA, "fpioa", "apb0"); + REGISTER_GATE(K210_CLK_SHA, "sha", "apb0"); + REGISTER_GATE(K210_CLK_AES, "aes", "apb1"); + REGISTER_GATE(K210_CLK_OTP, "otp", "apb1"); + REGISTER_GATE(K210_CLK_RTC, "rtc", in0); +#undef REGISTER_GATE + + return 0; +} + +static const struct udevice_id k210_clk_ids[] = { + { .compatible = "kendryte,k210-clk" }, + { }, +}; + +U_BOOT_DRIVER(k210_clk) = { + .name = "k210_clk", + .id = UCLASS_CLK, + .of_match = k210_clk_ids, + .ops = &k210_clk_ops, + .probe = k210_clk_probe, +}; diff --git a/include/dt-bindings/clock/k210-sysctl.h b/include/dt-bindings/clock/k210-sysctl.h new file mode 100644 index 00000000000..0e3ed3fb9fa --- /dev/null +++ b/include/dt-bindings/clock/k210-sysctl.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019-20 Sean Anderson + */ + +#ifndef CLOCK_K210_SYSCTL_H +#define CLOCK_K210_SYSCTL_H + +/* + * Arbitrary identifiers for clocks. + */ +#define K210_CLK_NONE 0 +#define K210_CLK_IN0_H 1 +#define K210_CLK_PLL0_H 2 +#define K210_CLK_PLL0 3 +#define K210_CLK_PLL1 4 +#define K210_CLK_PLL2 5 +#define K210_CLK_PLL2_H 6 +#define K210_CLK_CPU 7 +#define K210_CLK_SRAM0 8 +#define K210_CLK_SRAM1 9 +#define K210_CLK_APB0 10 +#define K210_CLK_APB1 11 +#define K210_CLK_APB2 12 +#define K210_CLK_ROM 13 +#define K210_CLK_DMA 14 +#define K210_CLK_AI 15 +#define K210_CLK_DVP 16 +#define K210_CLK_FFT 17 +#define K210_CLK_GPIO 18 +#define K210_CLK_SPI0 19 +#define K210_CLK_SPI1 20 +#define K210_CLK_SPI2 21 +#define K210_CLK_SPI3 22 +#define K210_CLK_I2S0 23 +#define K210_CLK_I2S1 24 +#define K210_CLK_I2S2 25 +#define K210_CLK_I2S0_M 26 +#define K210_CLK_I2S1_M 27 +#define K210_CLK_I2S2_M 28 +#define K210_CLK_I2C0 29 +#define K210_CLK_I2C1 30 +#define K210_CLK_I2C2 31 +#define K210_CLK_UART1 32 +#define K210_CLK_UART2 33 +#define K210_CLK_UART3 34 +#define K210_CLK_AES 35 +#define K210_CLK_FPIOA 36 +#define K210_CLK_TIMER0 37 +#define K210_CLK_TIMER1 38 +#define K210_CLK_TIMER2 39 +#define K210_CLK_WDT0 40 +#define K210_CLK_WDT1 41 +#define K210_CLK_SHA 42 +#define K210_CLK_OTP 43 +#define K210_CLK_RTC 44 +#define K210_CLK_ACLK 45 + +#endif /* CLOCK_K210_SYSCTL_H */ diff --git a/include/dt-bindings/mfd/k210-sysctl.h b/include/dt-bindings/mfd/k210-sysctl.h new file mode 100644 index 00000000000..bfc918d3ba9 --- /dev/null +++ b/include/dt-bindings/mfd/k210-sysctl.h @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 Sean Anderson + */ + +#ifndef K210_SYSCTL_H +#define K210_SYSCTL_H + +/* Taken from kendryte-standalone-sdk/lib/drivers/include/sysctl.h */ +#define K210_SYSCTL_GIT_ID 0x00 /* Git short commit id */ +#define K210_SYSCTL_UART_BAUD 0x04 /* Default UARTHS baud rate */ +#define K210_SYSCTL_PLL0 0x08 /* PLL0 controller */ +#define K210_SYSCTL_PLL1 0x0C /* PLL1 controller */ +#define K210_SYSCTL_PLL2 0x10 /* PLL2 controller */ +#define K210_SYSCTL_PLL_LOCK 0x18 /* PLL lock tester */ +#define K210_SYSCTL_ROM_ERROR 0x1C /* AXI ROM detector */ +#define K210_SYSCTL_SEL0 0x20 /* Clock select controller 0 */ +#define K210_SYSCTL_SEL1 0x24 /* Clock select controller 1 */ +#define K210_SYSCTL_EN_CENT 0x28 /* Central clock enable */ +#define K210_SYSCTL_EN_PERI 0x2C /* Peripheral clock enable */ +#define K210_SYSCTL_SOFT_RESET 0x30 /* Soft reset ctrl */ +#define K210_SYSCTL_PERI_RESET 0x34 /* Peripheral reset controller */ +#define K210_SYSCTL_THR0 0x38 /* Clock threshold controller 0 */ +#define K210_SYSCTL_THR1 0x3C /* Clock threshold controller 1 */ +#define K210_SYSCTL_THR2 0x40 /* Clock threshold controller 2 */ +#define K210_SYSCTL_THR3 0x44 /* Clock threshold controller 3 */ +#define K210_SYSCTL_THR4 0x48 /* Clock threshold controller 4 */ +#define K210_SYSCTL_THR5 0x4C /* Clock threshold controller 5 */ +#define K210_SYSCTL_THR6 0x50 /* Clock threshold controller 6 */ +#define K210_SYSCTL_MISC 0x54 /* Miscellaneous controller */ +#define K210_SYSCTL_PERI 0x58 /* Peripheral controller */ +#define K210_SYSCTL_SPI_SLEEP 0x5C /* SPI sleep controller */ +#define K210_SYSCTL_RESET_STAT 0x60 /* Reset source status */ +#define K210_SYSCTL_DMA_SEL0 0x64 /* DMA handshake selector 0 */ +#define K210_SYSCTL_DMA_SEL1 0x68 /* DMA handshake selector 1 */ +#define K210_SYSCTL_POWER_SEL 0x6C /* IO Power Mode Select controller */ + +#endif /* K210_SYSCTL_H */ diff --git a/include/kendryte/clk.h b/include/kendryte/clk.h new file mode 100644 index 00000000000..9c6245d468b --- /dev/null +++ b/include/kendryte/clk.h @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2019-20 Sean Anderson + */ + +#ifndef K210_CLK_H +#define K210_CLK_H + +#define LOG_CATEGORY UCLASS_CLK +#include +#include + +static inline struct clk *k210_clk_gate(const char *name, + const char *parent_name, + void __iomem *reg, u8 bit_idx) +{ + return clk_register_gate(NULL, name, parent_name, 0, reg, bit_idx, 0, + NULL); +} + +static inline struct clk *k210_clk_half(const char *name, + const char *parent_name) +{ + return clk_register_fixed_factor(NULL, name, parent_name, 0, 1, 2); +} + +static inline struct clk *k210_clk_div(const char *name, + const char *parent_name, + void __iomem *reg, u8 shift, u8 width) +{ + return clk_register_divider(NULL, name, parent_name, 0, reg, shift, + width, 0); +} + +#endif /* K210_CLK_H */ -- cgit v1.3.1 From 4a3390f1d3b71f0645eb281176f00cd0d5ac2dcb Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:12 -0400 Subject: dm: Add support for simple-pm-bus This type of bus is used in Linux to designate buses which have power domains and/or clocks which need to be enabled before their child devices can be used. Because power domains are automatically enabled before probing in U-Boot, we just need to enable any clocks present. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 6 +++ arch/sandbox/include/asm/clk.h | 1 + configs/sandbox_defconfig | 1 + doc/device-tree-bindings/bus/simple-pm-bus.txt | 44 ++++++++++++++++++++ drivers/core/Kconfig | 7 ++++ drivers/core/Makefile | 1 + drivers/core/simple-pm-bus.c | 56 ++++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/simple-pm-bus.c | 45 +++++++++++++++++++++ 9 files changed, 162 insertions(+) create mode 100644 doc/device-tree-bindings/bus/simple-pm-bus.txt create mode 100644 drivers/core/simple-pm-bus.c create mode 100644 test/dm/simple-pm-bus.c (limited to 'drivers') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index a6e2bfd082f..b59bf157a91 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1038,6 +1038,12 @@ mdio: mdio-test { compatible = "sandbox,mdio"; }; + + pm-bus-test { + compatible = "simple-pm-bus"; + clocks = <&clk_sandbox 4>; + power-domains = <&pwrdom 1>; + }; }; #include "sandbox_pmic.dtsi" diff --git a/arch/sandbox/include/asm/clk.h b/arch/sandbox/include/asm/clk.h index 1573e4a1347..c184c4bffcf 100644 --- a/arch/sandbox/include/asm/clk.h +++ b/arch/sandbox/include/asm/clk.h @@ -21,6 +21,7 @@ enum sandbox_clk_id { SANDBOX_CLK_ID_I2C, SANDBOX_CLK_ID_UART1, SANDBOX_CLK_ID_UART2, + SANDBOX_CLK_ID_BUS, SANDBOX_CLK_ID_COUNT, }; diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 20a81a0350d..692432c7d69 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -96,6 +96,7 @@ CONFIG_REGMAP=y CONFIG_SYSCON=y CONFIG_DEVRES=y CONFIG_DEBUG_DEVRES=y +CONFIG_SIMPLE_PM_BUS=y CONFIG_ADC=y CONFIG_ADC_SANDBOX=y CONFIG_AXI=y diff --git a/doc/device-tree-bindings/bus/simple-pm-bus.txt b/doc/device-tree-bindings/bus/simple-pm-bus.txt new file mode 100644 index 00000000000..6f15037131e --- /dev/null +++ b/doc/device-tree-bindings/bus/simple-pm-bus.txt @@ -0,0 +1,44 @@ +Simple Power-Managed Bus +======================== + +A Simple Power-Managed Bus is a transparent bus that doesn't need a real +driver, as it's typically initialized by the boot loader. + +However, its bus controller is part of a PM domain, or under the control of a +functional clock. Hence, the bus controller's PM domain and/or clock must be +enabled for child devices connected to the bus (either on-SoC or externally) +to function. + +While "simple-pm-bus" follows the "simple-bus" set of properties, as specified +in the Devicetree Specification, it is not an extension of "simple-bus". + + +Required properties: + - compatible: Must contain at least "simple-pm-bus". + Must not contain "simple-bus". + It's recommended to let this be preceded by one or more + vendor-specific compatible values. + - #address-cells, #size-cells, ranges: Must describe the mapping between + parent address and child address spaces. + +Optional platform-specific properties for clock or PM domain control (at least +one of them is required): + - clocks: Must contain a reference to the functional clock(s), + - power-domains: Must contain a reference to the PM domain. +Please refer to the binding documentation for the clock and/or PM domain +providers for more details. + + +Example: + + bsc: bus@fec10000 { + compatible = "renesas,bsc-sh73a0", "renesas,bsc", + "simple-pm-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0 0x20000000>; + reg = <0xfec10000 0x400>; + interrupts = <0 39 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&zb_clk>; + power-domains = <&pd_a4s>; + }; diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index a3b03993423..a594899f371 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -195,6 +195,13 @@ config SPL_SIMPLE_BUS Supports the 'simple-bus' driver, which is used on some systems in SPL. +config SIMPLE_PM_BUS + bool "Support simple-pm-bus driver" + depends on DM && OF_CONTROL && CLK && POWER_DOMAIN + help + Supports the 'simple-pm-bus' driver, which is used for busses that + have power domains and/or clocks which need to be enabled before use. + config OF_TRANSLATE bool "Translate addresses using fdt_translate_address" depends on DM && OF_CONTROL diff --git a/drivers/core/Makefile b/drivers/core/Makefile index c707026a3a0..10f4bece335 100644 --- a/drivers/core/Makefile +++ b/drivers/core/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_$(SPL_TPL_)ACPIGEN) += acpi.o obj-$(CONFIG_DEVRES) += devres.o obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE) += device-remove.o obj-$(CONFIG_$(SPL_)SIMPLE_BUS) += simple-bus.o +obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o obj-$(CONFIG_DM) += dump.o obj-$(CONFIG_$(SPL_TPL_)REGMAP) += regmap.o obj-$(CONFIG_$(SPL_TPL_)SYSCON) += syscon-uclass.o diff --git a/drivers/core/simple-pm-bus.c b/drivers/core/simple-pm-bus.c new file mode 100644 index 00000000000..51dc9b206fd --- /dev/null +++ b/drivers/core/simple-pm-bus.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Sean Anderson + */ + +#include +#include +#include + +/* + * Power domains are taken care of by driver_probe, so we just have to enable + * clocks + */ +static int simple_pm_bus_probe(struct udevice *dev) +{ + int ret; + struct clk_bulk *bulk = dev_get_priv(dev); + + ret = clk_get_bulk(dev, bulk); + if (ret) + return ret; + + ret = clk_enable_bulk(bulk); + if (ret && ret != -ENOSYS && ret != -ENOTSUPP) { + clk_release_bulk(bulk); + return ret; + } + return 0; +} + +static int simple_pm_bus_remove(struct udevice *dev) +{ + int ret; + struct clk_bulk *bulk = dev_get_priv(dev); + + ret = clk_release_bulk(bulk); + if (ret && ret != -ENOSYS && ret != -ENOTSUPP) + return ret; + else + return 0; +} + +static const struct udevice_id simple_pm_bus_ids[] = { + { .compatible = "simple-pm-bus" }, + { } +}; + +U_BOOT_DRIVER(simple_pm_bus_drv) = { + .name = "simple_pm_bus", + .id = UCLASS_SIMPLE_BUS, + .of_match = simple_pm_bus_ids, + .probe = simple_pm_bus_probe, + .remove = simple_pm_bus_remove, + .priv_auto_alloc_size = sizeof(struct clk_bulk), + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/test/dm/Makefile b/test/dm/Makefile index 5094a7866af..518ee8e3773 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -74,4 +74,5 @@ obj-$(CONFIG_DM_MDIO) += mdio.o obj-$(CONFIG_DM_MDIO_MUX) += mdio_mux.o obj-$(CONFIG_DM_RNG) += rng.o obj-$(CONFIG_CLK_K210_SET_RATE) += k210_pll.o +obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o endif diff --git a/test/dm/simple-pm-bus.c b/test/dm/simple-pm-bus.c new file mode 100644 index 00000000000..978c7f191e7 --- /dev/null +++ b/test/dm/simple-pm-bus.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Sean Anderson + */ + +#include +#include +#include +#include +#include +#include +#include + +/* These must match the ids in the device tree */ +#define TEST_CLOCK_ID 4 +#define TEST_POWER_ID 1 + +static int dm_test_simple_pm_bus(struct unit_test_state *uts) +{ + struct udevice *power; + struct udevice *clock; + struct udevice *bus; + + ut_assertok(uclass_get_device_by_name(UCLASS_POWER_DOMAIN, + "power-domain", &power)); + ut_assertok(uclass_get_device_by_name(UCLASS_CLK, "clk-sbox", + &clock)); + ut_asserteq(0, sandbox_power_domain_query(power, TEST_POWER_ID)); + ut_asserteq(0, sandbox_clk_query_enable(clock, TEST_CLOCK_ID)); + + ut_assertok(uclass_get_device_by_name(UCLASS_SIMPLE_BUS, "pm-bus-test", + &bus)); + ut_asserteq(1, sandbox_power_domain_query(power, TEST_POWER_ID)); + ut_asserteq(1, sandbox_clk_query_enable(clock, TEST_CLOCK_ID)); + + ut_assertok(device_remove(bus, DM_REMOVE_NORMAL)); + /* must re-probe since device_remove also removes the power domain */ + ut_assertok(uclass_get_device_by_name(UCLASS_POWER_DOMAIN, + "power-domain", &power)); + ut_asserteq(0, sandbox_power_domain_query(power, TEST_POWER_ID)); + ut_asserteq(0, sandbox_clk_query_enable(clock, TEST_CLOCK_ID)); + + return 0; +} +DM_TEST(dm_test_simple_pm_bus, DM_TESTF_SCAN_FDT); -- cgit v1.3.1 From 082faeb86526b41bb9c5ca8373168e12f2de3a10 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:13 -0400 Subject: dm: Fix error handling for dev_read_addr_ptr dev_read_addr_ptr had different semantics depending on whether OF_LIVE was enabled. This patch converts both implementations to return NULL on error, and converts all call sites which check for FDT_ADDR_T_NONE to check for NULL instead. This patch also removes the call to map_physmem, since we have dev_remap_addr* for those semantics. Signed-off-by: Sean Anderson Reviewed-by: Bin Meng Reviewed-by: Simon Glass --- drivers/clk/imx/clk-imx8mp.c | 2 +- drivers/core/read.c | 2 +- drivers/pinctrl/broadcom/pinctrl-bcm283x.c | 2 +- drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 2 +- include/dm/read.h | 4 +++- 5 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c index 3d7aebb8e56..124138cf512 100644 --- a/drivers/clk/imx/clk-imx8mp.c +++ b/drivers/clk/imx/clk-imx8mp.c @@ -282,7 +282,7 @@ static int imx8mp_clk_probe(struct udevice *dev) clk_dm(IMX8MP_SYS_PLL2_1000M, imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1)); base = dev_read_addr_ptr(dev); - if (base == (void *)FDT_ADDR_T_NONE) + if (!base) return -EINVAL; clk_dm(IMX8MP_CLK_A53_SRC, imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mp_a53_sels, ARRAY_SIZE(imx8mp_a53_sels))); diff --git a/drivers/core/read.c b/drivers/core/read.c index 85b3b7a5adb..8bb456bc3f0 100644 --- a/drivers/core/read.c +++ b/drivers/core/read.c @@ -167,7 +167,7 @@ void *dev_read_addr_ptr(const struct udevice *dev) { fdt_addr_t addr = dev_read_addr(dev); - return (addr == FDT_ADDR_T_NONE) ? NULL : map_sysmem(addr, 0); + return (addr == FDT_ADDR_T_NONE) ? NULL : (void *)(uintptr_t)addr; } void *dev_remap_addr(const struct udevice *dev) diff --git a/drivers/pinctrl/broadcom/pinctrl-bcm283x.c b/drivers/pinctrl/broadcom/pinctrl-bcm283x.c index f44af6cf9ad..c22d534da9a 100644 --- a/drivers/pinctrl/broadcom/pinctrl-bcm283x.c +++ b/drivers/pinctrl/broadcom/pinctrl-bcm283x.c @@ -117,7 +117,7 @@ int bcm283x_pinctl_probe(struct udevice *dev) } priv->base_reg = dev_read_addr_ptr(dev); - if (priv->base_reg == (void *)FDT_ADDR_T_NONE) { + if (!priv->base_reg) { debug("%s: Failed to get base address\n", __func__); return -EINVAL; } diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c index 5fdc150295e..e8187a37808 100644 --- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c @@ -631,7 +631,7 @@ int mtk_pinctrl_common_probe(struct udevice *dev, int ret; priv->base = dev_read_addr_ptr(dev); - if (priv->base == (void *)FDT_ADDR_T_NONE) + if (!priv->base) return -EINVAL; priv->soc = soc; diff --git a/include/dm/read.h b/include/dm/read.h index 3711386f513..f02ec959541 100644 --- a/include/dm/read.h +++ b/include/dm/read.h @@ -799,7 +799,9 @@ static inline fdt_addr_t dev_read_addr(const struct udevice *dev) static inline void *dev_read_addr_ptr(const struct udevice *dev) { - return devfdt_get_addr_ptr(dev); + void *addr = devfdt_get_addr_ptr(dev); + + return ((fdt_addr_t)(uintptr_t)addr == FDT_ADDR_T_NONE) ? NULL : addr; } static inline fdt_addr_t dev_read_addr_pci(const struct udevice *dev) -- cgit v1.3.1 From 038b13ee8134ba755a323732f3b2b838b9dc17a4 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:14 -0400 Subject: reset: Add generic reset driver This patch adds a generic reset driver. It is designed to be useful when one has a register in a regmap which contains bits that reset other devices. I thought this seemed like a very generic use, so here is a generic driver. The overall structure has been modeled on the syscon-reboot driver. Signed-off-by: Sean Anderson Reviewed-by: Simon Glass --- arch/sandbox/dts/test.dts | 15 +++++ configs/sandbox_defconfig | 2 + doc/device-tree-bindings/reset/syscon-reset.txt | 36 +++++++++++ drivers/reset/Kconfig | 5 ++ drivers/reset/Makefile | 1 + drivers/reset/reset-syscon.c | 81 +++++++++++++++++++++++++ test/dm/Makefile | 1 + test/dm/syscon-reset.c | 59 ++++++++++++++++++ 8 files changed, 200 insertions(+) create mode 100644 doc/device-tree-bindings/reset/syscon-reset.txt create mode 100644 drivers/reset/reset-syscon.c create mode 100644 test/dm/syscon-reset.c (limited to 'drivers') diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index b59bf157a91..d2a6af070b2 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -1044,6 +1044,21 @@ clocks = <&clk_sandbox 4>; power-domains = <&pwrdom 1>; }; + + resetc2: syscon-reset { + compatible = "syscon-reset"; + #reset-cells = <1>; + regmap = <&syscon0>; + offset = <1>; + mask = <0x27FFFFFF>; + assert-high = <0>; + }; + + syscon-reset-test { + compatible = "sandbox,misc_sandbox"; + resets = <&resetc2 15>, <&resetc2 30>, <&resetc2 60>; + reset-names = "valid", "no_mask", "out_of_range"; + }; }; #include "sandbox_pmic.dtsi" diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig index 692432c7d69..ee1e6f33330 100644 --- a/configs/sandbox_defconfig +++ b/configs/sandbox_defconfig @@ -196,6 +196,8 @@ CONFIG_REMOTEPROC_SANDBOX=y CONFIG_DM_RESET=y CONFIG_SANDBOX_RESET=y CONFIG_DM_RNG=y +CONFIG_RNG_SANDBOX=y +CONFIG_RESET_SYSCON=y CONFIG_DM_RTC=y CONFIG_RTC_RV8803=y CONFIG_SANDBOX_SERIAL=y diff --git a/doc/device-tree-bindings/reset/syscon-reset.txt b/doc/device-tree-bindings/reset/syscon-reset.txt new file mode 100644 index 00000000000..f136b3d2250 --- /dev/null +++ b/doc/device-tree-bindings/reset/syscon-reset.txt @@ -0,0 +1,36 @@ +Generic SYSCON mapped register reset driver + +This is a generic reset driver using syscon to map the reset register. +The reset is generally performed with a write to the reset register +defined by the register map pointed by syscon reference plus the offset and +shifted by the reset specifier/ + +To assert a reset on some device, the equivalent of the following operation is +performed, where reset_id is the reset specifier from the device's resets +property. + + if (BIT(reset_id) & mask) + regmap[offset][reset_id] = assert-high; + +Required properties: +- compatible: should contain "syscon-reset" +- #reset-cells: must be 1 +- regmap: this is phandle to the register map node +- offset: offset in the register map for the reboot register (in bytes) + +Optional properties: +- mask: accept only the reset specifiers defined by the mask (32 bit) +- assert-high: Bit to write when asserting a reset. Defaults to 1. + +Default will be little endian mode, 32 bit access only. + +Example: + + reset-controller { + compatible = "syscon-reset"; + #reset-cells = <1>; + regmap = <&sysctl>; + offset = <0x20>; + mask = <0x27FFFFFF>; + assert-high = <0>; + }; diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 88d3be1593d..58ba0c686e0 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -148,4 +148,9 @@ config RESET_IMX7 help Support for reset controller on i.MX7/8 SoCs. +config RESET_SYSCON + bool "Enable generic syscon reset driver support" + depends on DM_RESET + help + Support generic syscon mapped register reset devices. endmenu diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 0a044d5d8c8..433f1eca540 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_RESET_MTMIPS) += reset-mtmips.o obj-$(CONFIG_RESET_SUNXI) += reset-sunxi.o obj-$(CONFIG_RESET_HISILICON) += reset-hisilicon.o obj-$(CONFIG_RESET_IMX7) += reset-imx7.o +obj-$(CONFIG_RESET_SYSCON) += reset-syscon.o diff --git a/drivers/reset/reset-syscon.c b/drivers/reset/reset-syscon.c new file mode 100644 index 00000000000..8520227d551 --- /dev/null +++ b/drivers/reset/reset-syscon.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2020 Sean Anderson + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct syscon_reset_priv { + struct regmap *regmap; + uint offset; + uint mask; + bool assert_high; +}; + +static int syscon_reset_request(struct reset_ctl *rst) +{ + struct syscon_reset_priv *priv = dev_get_priv(rst->dev); + + if (BIT(rst->id) & priv->mask) + return 0; + else + return -EINVAL; +} + +static int syscon_reset_assert(struct reset_ctl *rst) +{ + struct syscon_reset_priv *priv = dev_get_priv(rst->dev); + + return regmap_update_bits(priv->regmap, priv->offset, BIT(rst->id), + priv->assert_high ? BIT(rst->id) : 0); +} + +static int syscon_reset_deassert(struct reset_ctl *rst) +{ + struct syscon_reset_priv *priv = dev_get_priv(rst->dev); + + return regmap_update_bits(priv->regmap, priv->offset, BIT(rst->id), + priv->assert_high ? 0 : BIT(rst->id)); +} + +static const struct reset_ops syscon_reset_ops = { + .request = syscon_reset_request, + .rst_assert = syscon_reset_assert, + .rst_deassert = syscon_reset_deassert, +}; + +int syscon_reset_probe(struct udevice *dev) +{ + struct syscon_reset_priv *priv = dev_get_priv(dev); + + priv->regmap = syscon_regmap_lookup_by_phandle(dev, "regmap"); + if (IS_ERR(priv->regmap)) + return -ENODEV; + + priv->offset = dev_read_u32_default(dev, "offset", 0); + priv->mask = dev_read_u32_default(dev, "mask", 0); + priv->assert_high = dev_read_u32_default(dev, "assert-high", true); + + return 0; +} + +static const struct udevice_id syscon_reset_ids[] = { + { .compatible = "syscon-reset" }, + { }, +}; + +U_BOOT_DRIVER(syscon_reset) = { + .name = "syscon_reset", + .id = UCLASS_RESET, + .of_match = syscon_reset_ids, + .probe = syscon_reset_probe, + .priv_auto_alloc_size = sizeof(struct syscon_reset_priv), + .ops = &syscon_reset_ops, +}; diff --git a/test/dm/Makefile b/test/dm/Makefile index 518ee8e3773..0d1c66fa1e6 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -75,4 +75,5 @@ obj-$(CONFIG_DM_MDIO_MUX) += mdio_mux.o obj-$(CONFIG_DM_RNG) += rng.o obj-$(CONFIG_CLK_K210_SET_RATE) += k210_pll.o obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o +obj-$(CONFIG_RESET_SYSCON) += syscon-reset.o endif diff --git a/test/dm/syscon-reset.c b/test/dm/syscon-reset.c new file mode 100644 index 00000000000..edabdb2e781 --- /dev/null +++ b/test/dm/syscon-reset.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 Sean Anderson + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* The following values must match the device tree */ +#define TEST_RESET_REG 1 +#define TEST_RESET_ASSERT_HIGH 0 +#define TEST_RESET_ASSERT (TEST_RESET_ASSERT_HIGH ? (u32)-1 : (u32)0) +#define TEST_RESET_DEASSERT (~TEST_RESET_ASSERT) + +#define TEST_RESET_VALID 15 +#define TEST_RESET_NOMASK 30 +#define TEST_RESET_OUTOFRANGE 60 + +static int dm_test_syscon_reset(struct unit_test_state *uts) +{ + struct regmap *map; + struct reset_ctl rst; + struct udevice *reset; + struct udevice *syscon; + struct udevice *syscon_reset; + uint reg; + + ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "syscon-reset-test", + &reset)); + ut_assertok(uclass_get_device_by_name(UCLASS_SYSCON, "syscon@0", + &syscon)); + ut_assertok(uclass_get_device_by_name(UCLASS_RESET, "syscon-reset", + &syscon_reset)); + ut_assertok_ptr((map = syscon_get_regmap(syscon))); + + ut_asserteq(-EINVAL, reset_get_by_name(reset, "no_mask", &rst)); + ut_asserteq(-EINVAL, reset_get_by_name(reset, "out_of_range", &rst)); + ut_assertok(reset_get_by_name(reset, "valid", &rst)); + + sandbox_set_enable_memio(true); + ut_assertok(regmap_write(map, TEST_RESET_REG, TEST_RESET_DEASSERT)); + ut_assertok(reset_assert(&rst)); + ut_assertok(regmap_read(map, TEST_RESET_REG, ®)); + ut_asserteq(TEST_RESET_DEASSERT ^ BIT(TEST_RESET_VALID), reg); + + ut_assertok(reset_deassert(&rst)); + ut_assertok(regmap_read(map, TEST_RESET_REG, ®)); + ut_asserteq(TEST_RESET_DEASSERT, reg); + + return 0; +} +DM_TEST(dm_test_syscon_reset, DM_TESTF_SCAN_FDT); -- cgit v1.3.1 From ab24017a19b482d9026d21a2ec03416c5c4a388d Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:21 -0400 Subject: riscv: Try to get cpu frequency from a "clocks" node if it exists Instead of always using the "clock-frequency" property to determine cpu frequency, try using a clock in "clocks" if it exists. This patch also fixes a bug where there could be spurious higher frequencies if sizeof(u32) != sizeof(ulong). Signed-off-by: Sean Anderson Reviewed-by: Bin Meng --- drivers/cpu/riscv_cpu.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c index cb04f5638db..2d44d1c17b1 100644 --- a/drivers/cpu/riscv_cpu.c +++ b/drivers/cpu/riscv_cpu.c @@ -3,6 +3,7 @@ * Copyright (C) 2018, Bin Meng */ +#include #include #include #include @@ -11,6 +12,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -29,9 +31,24 @@ static int riscv_cpu_get_desc(struct udevice *dev, char *buf, int size) static int riscv_cpu_get_info(struct udevice *dev, struct cpu_info *info) { + int ret; + struct clk clk; const char *mmu; - dev_read_u32(dev, "clock-frequency", (u32 *)&info->cpu_freq); + /* Zero out the frequency, in case sizeof(ulong) != sizeof(u32) */ + info->cpu_freq = 0; + + /* First try getting the frequency from the assigned clock */ + ret = clk_get_by_index(dev, 0, &clk); + if (!ret) { + ret = clk_get_rate(&clk); + if (!IS_ERR_VALUE(ret)) + info->cpu_freq = ret; + clk_free(&clk); + } + + if (!info->cpu_freq) + dev_read_u32(dev, "clock-frequency", (u32 *)&info->cpu_freq); mmu = dev_read_string(dev, "mmu-type"); if (!mmu) -- cgit v1.3.1 From 627718626b05f715da555cc005426ab10f44bb98 Mon Sep 17 00:00:00 2001 From: Sean Anderson Date: Wed, 24 Jun 2020 06:41:22 -0400 Subject: riscv: Enable cpu clock if it is present The cpu clock is probably already enabled if we are executing code (though we could be executing from a different core). This patch prevents the cpu clock or its parents from being disabled. Signed-off-by: Sean Anderson Reviewed-by: Bin Meng --- drivers/cpu/riscv_cpu.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c index 2d44d1c17b1..76b0489d2a0 100644 --- a/drivers/cpu/riscv_cpu.c +++ b/drivers/cpu/riscv_cpu.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2018, Bin Meng + * Copyright (C) 2020, Sean Anderson */ #include @@ -119,6 +120,24 @@ static int riscv_cpu_bind(struct udevice *dev) return 0; } +static int riscv_cpu_probe(struct udevice *dev) +{ + int ret = 0; + struct clk clk; + + /* Get a clock if it exists */ + ret = clk_get_by_index(dev, 0, &clk); + if (ret) + return 0; + + ret = clk_enable(&clk); + clk_free(&clk); + if (ret == -ENOSYS || ret == -ENOTSUPP) + return 0; + else + return ret; +} + static const struct cpu_ops riscv_cpu_ops = { .get_desc = riscv_cpu_get_desc, .get_info = riscv_cpu_get_info, @@ -135,6 +154,7 @@ U_BOOT_DRIVER(riscv_cpu) = { .id = UCLASS_CPU, .of_match = riscv_cpu_ids, .bind = riscv_cpu_bind, + .probe = riscv_cpu_probe, .ops = &riscv_cpu_ops, .flags = DM_FLAG_PRE_RELOC, }; -- cgit v1.3.1 From 969251a5a4d3515abc233621bc8ca6f1c93d6dd4 Mon Sep 17 00:00:00 2001 From: Sagar Shrikant Kadam Date: Sun, 28 Jun 2020 07:45:01 -0700 Subject: uclass: cpu: fix to display proper CPU features The cmd "cpu detail" fetches uninitialized cpu feature information and thus displays wrong / inconsitent details as below. For eg: FU540-C000 doesn't have any microcode, yet the cmd display's it. => cpu detail 1: cpu@1 rv64imafdc ID = 1, freq = 999.100 MHz: L1 cache, MMU, Microcode, Device ID Microcode version 0x0 Device ID 0x0 2: cpu@2 rv64imafdc ID = 2, freq = 999.100 MHz: L1 cache, MMU, Microcode, Device ID Microcode version 0x0 Device ID 0x0 3: cpu@3 rv64imafdc ID = 3, freq = 999.100 MHz: L1 cache, MMU, Microcode, Device ID Microcode version 0x0 Device ID 0x0 4: cpu@4 rv64imafdc ID = 4, freq = 999.100 MHz: L1 cache, MMU, Microcode, Device ID Microcode version 0x0 Device ID 0x0 The L1 cache or MMU entry seen above is also displayed inconsistently. So initialize cpu information to zero into cpu-uclass itself so that similar issues can be avoided for other CPU drivers. We now see correct features as: => cpu detail 1: cpu@1 rv64imafdc ID = 1, freq = 999.100 MHz 2: cpu@2 rv64imafdc ID = 2, freq = 999.100 MHz 3: cpu@3 rv64imafdc ID = 3, freq = 999.100 MHz 4: cpu@4 rv64imafdc ID = 4, freq = 999.100 MHz Signed-off-by: Sagar Shrikant Kadam Reviewed-by: Pragnesh Patel Reviewed-by: Bin Meng --- drivers/cpu/cpu-uclass.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/cpu/cpu-uclass.c b/drivers/cpu/cpu-uclass.c index 7418c26ed8b..cbb4419ec0c 100644 --- a/drivers/cpu/cpu-uclass.c +++ b/drivers/cpu/cpu-uclass.c @@ -86,6 +86,9 @@ int cpu_get_info(struct udevice *dev, struct cpu_info *info) if (!ops->get_info) return -ENOSYS; + /* Init cpu_info to 0 */ + memset(info, 0, sizeof(struct cpu_info)); + return ops->get_info(dev, info); } -- cgit v1.3.1 From b6b233ddb78205abc76dde60179bd129368dc3e8 Mon Sep 17 00:00:00 2001 From: Sagar Shrikant Kadam Date: Sun, 28 Jun 2020 07:45:02 -0700 Subject: riscv: cpu: correctly handle the setting of CPU_FEAT_MMU bit The conditional check to read "mmu-type" from the device tree is not rightly handled due to which the cpu feature doesn't include CPU_FEAT_MMU even if it's corresponding entry is present in the device tree. The initialization of cpu features is now taken care in cpu-uclass driver, so no need to zero out cpu_freq in riscv_cpu driver and can be removed. Signed-off-by: Sagar Shrikant Kadam Reviewed-by: Pragnesh Patel Reviewed-by: Bin Meng --- drivers/cpu/riscv_cpu.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c index 76b0489d2a0..112690fe3a4 100644 --- a/drivers/cpu/riscv_cpu.c +++ b/drivers/cpu/riscv_cpu.c @@ -36,9 +36,6 @@ static int riscv_cpu_get_info(struct udevice *dev, struct cpu_info *info) struct clk clk; const char *mmu; - /* Zero out the frequency, in case sizeof(ulong) != sizeof(u32) */ - info->cpu_freq = 0; - /* First try getting the frequency from the assigned clock */ ret = clk_get_by_index(dev, 0, &clk); if (!ret) { @@ -52,7 +49,7 @@ static int riscv_cpu_get_info(struct udevice *dev, struct cpu_info *info) dev_read_u32(dev, "clock-frequency", (u32 *)&info->cpu_freq); mmu = dev_read_string(dev, "mmu-type"); - if (!mmu) + if (mmu) info->features |= BIT(CPU_FEAT_MMU); return 0; -- cgit v1.3.1 From add0dc1f7de91112d9e738f9482b09b75fa86acb Mon Sep 17 00:00:00 2001 From: Sagar Shrikant Kadam Date: Sun, 28 Jun 2020 07:45:03 -0700 Subject: riscv: cpu: check and append L1 cache to cpu features All cpu cores within FU540-C000 having split I/D caches. Set the L1 cache feature bit using the i-cache-size or d-cache-size as one of the property from device tree indicating that L1 cache is present on the cpu core. => cpu detail 1: cpu@1 rv64imafdc ID = 1, freq = 999.100 MHz: L1 cache, MMU 2: cpu@2 rv64imafdc ID = 2, freq = 999.100 MHz: L1 cache, MMU 3: cpu@3 rv64imafdc ID = 3, freq = 999.100 MHz: L1 cache, MMU 4: cpu@4 rv64imafdc ID = 4, freq = 999.100 MHz: L1 cache, MMU Signed-off-by: Sagar Shrikant Kadam Reviewed-by: Pragnesh Patel Reviewed-by: Bin Meng --- drivers/cpu/riscv_cpu.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/cpu/riscv_cpu.c b/drivers/cpu/riscv_cpu.c index 112690fe3a4..100fe5542e4 100644 --- a/drivers/cpu/riscv_cpu.c +++ b/drivers/cpu/riscv_cpu.c @@ -35,6 +35,8 @@ static int riscv_cpu_get_info(struct udevice *dev, struct cpu_info *info) int ret; struct clk clk; const char *mmu; + u32 i_cache_size; + u32 d_cache_size; /* First try getting the frequency from the assigned clock */ ret = clk_get_by_index(dev, 0, &clk); @@ -52,6 +54,16 @@ static int riscv_cpu_get_info(struct udevice *dev, struct cpu_info *info) if (mmu) info->features |= BIT(CPU_FEAT_MMU); + /* check if I cache is present */ + ret = dev_read_u32(dev, "i-cache-size", &i_cache_size); + if (ret) + /* if not found check if d-cache is present */ + ret = dev_read_u32(dev, "d-cache-size", &d_cache_size); + + /* if either I or D cache is present set L1 cache feature */ + if (!ret) + info->features |= BIT(CPU_FEAT_L1_CACHE); + return 0; } -- cgit v1.3.1 From 8214791daa290119243134fcfbebe631fd0ed249 Mon Sep 17 00:00:00 2001 From: Tom Rini Date: Wed, 1 Jul 2020 11:46:45 -0400 Subject: pci: rockchip: Mark inline functions as static inline Unless we mark the function as 'static inline' it may end up being non-inlined by the compiled and result in duplicate functions. Cc: Jagan Teki Cc: Kever Yang Signed-off-by: Tom Rini --- drivers/pci/pcie_rockchip.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pcie_rockchip.h b/drivers/pci/pcie_rockchip.h index c3a0a2846d4..845d5059e11 100644 --- a/drivers/pci/pcie_rockchip.h +++ b/drivers/pci/pcie_rockchip.h @@ -130,13 +130,12 @@ struct rockchip_pcie { int rockchip_pcie_phy_get(struct udevice *dev); -inline struct rockchip_pcie_phy *pcie_get_phy(struct rockchip_pcie *pcie) +static inline struct rockchip_pcie_phy *pcie_get_phy(struct rockchip_pcie *pcie) { return pcie->phy; } -inline -struct rockchip_pcie_phy_ops *phy_get_ops(struct rockchip_pcie_phy *phy) +static inline struct rockchip_pcie_phy_ops *phy_get_ops(struct rockchip_pcie_phy *phy) { return (struct rockchip_pcie_phy_ops *)phy->ops; } -- cgit v1.3.1