12e7d35d2SSimon Glass /* 22e7d35d2SSimon Glass * Copyright (c) 2013 Google, Inc 32e7d35d2SSimon Glass * 42e7d35d2SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 52e7d35d2SSimon Glass */ 62e7d35d2SSimon Glass 72e7d35d2SSimon Glass #include <common.h> 82e7d35d2SSimon Glass #include <dm.h> 92e7d35d2SSimon Glass #include <errno.h> 102e7d35d2SSimon Glass #include <fdtdec.h> 112e7d35d2SSimon Glass #include <malloc.h> 122e7d35d2SSimon Glass #include <asm/io.h> 132e7d35d2SSimon Glass #include <dm/test.h> 142e7d35d2SSimon Glass #include <dm/root.h> 152e7d35d2SSimon Glass #include <dm/ut.h> 162e7d35d2SSimon Glass #include <dm/uclass-internal.h> 172e7d35d2SSimon Glass #include <dm/util.h> 182e7d35d2SSimon Glass 192e7d35d2SSimon Glass DECLARE_GLOBAL_DATA_PTR; 202e7d35d2SSimon Glass 2154c5d08aSHeiko Schocher static int testfdt_drv_ping(struct udevice *dev, int pingval, int *pingret) 222e7d35d2SSimon Glass { 232e7d35d2SSimon Glass const struct dm_test_pdata *pdata = dev->platdata; 242e7d35d2SSimon Glass struct dm_test_priv *priv = dev_get_priv(dev); 252e7d35d2SSimon Glass 262e7d35d2SSimon Glass *pingret = pingval + pdata->ping_add; 272e7d35d2SSimon Glass priv->ping_total += *pingret; 282e7d35d2SSimon Glass 292e7d35d2SSimon Glass return 0; 302e7d35d2SSimon Glass } 312e7d35d2SSimon Glass 322e7d35d2SSimon Glass static const struct test_ops test_ops = { 332e7d35d2SSimon Glass .ping = testfdt_drv_ping, 342e7d35d2SSimon Glass }; 352e7d35d2SSimon Glass 3654c5d08aSHeiko Schocher static int testfdt_ofdata_to_platdata(struct udevice *dev) 372e7d35d2SSimon Glass { 382e7d35d2SSimon Glass struct dm_test_pdata *pdata = dev_get_platdata(dev); 392e7d35d2SSimon Glass 402e7d35d2SSimon Glass pdata->ping_add = fdtdec_get_int(gd->fdt_blob, dev->of_offset, 412e7d35d2SSimon Glass "ping-add", -1); 42eb9ef5feSSimon Glass pdata->base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, 43eb9ef5feSSimon Glass "ping-expect"); 442e7d35d2SSimon Glass 452e7d35d2SSimon Glass return 0; 462e7d35d2SSimon Glass } 472e7d35d2SSimon Glass 4854c5d08aSHeiko Schocher static int testfdt_drv_probe(struct udevice *dev) 492e7d35d2SSimon Glass { 502e7d35d2SSimon Glass struct dm_test_priv *priv = dev_get_priv(dev); 512e7d35d2SSimon Glass 522e7d35d2SSimon Glass priv->ping_total += DM_TEST_START_TOTAL; 532e7d35d2SSimon Glass 542e7d35d2SSimon Glass return 0; 552e7d35d2SSimon Glass } 562e7d35d2SSimon Glass 57ae7f4513SSimon Glass static const struct udevice_id testfdt_ids[] = { 582e7d35d2SSimon Glass { 592e7d35d2SSimon Glass .compatible = "denx,u-boot-fdt-test", 602e7d35d2SSimon Glass .data = DM_TEST_TYPE_FIRST }, 612e7d35d2SSimon Glass { 622e7d35d2SSimon Glass .compatible = "google,another-fdt-test", 632e7d35d2SSimon Glass .data = DM_TEST_TYPE_SECOND }, 642e7d35d2SSimon Glass { } 652e7d35d2SSimon Glass }; 662e7d35d2SSimon Glass 672e7d35d2SSimon Glass U_BOOT_DRIVER(testfdt_drv) = { 682e7d35d2SSimon Glass .name = "testfdt_drv", 692e7d35d2SSimon Glass .of_match = testfdt_ids, 702e7d35d2SSimon Glass .id = UCLASS_TEST_FDT, 712e7d35d2SSimon Glass .ofdata_to_platdata = testfdt_ofdata_to_platdata, 722e7d35d2SSimon Glass .probe = testfdt_drv_probe, 732e7d35d2SSimon Glass .ops = &test_ops, 742e7d35d2SSimon Glass .priv_auto_alloc_size = sizeof(struct dm_test_priv), 752e7d35d2SSimon Glass .platdata_auto_alloc_size = sizeof(struct dm_test_pdata), 762e7d35d2SSimon Glass }; 772e7d35d2SSimon Glass 782e7d35d2SSimon Glass /* From here is the testfdt uclass code */ 7954c5d08aSHeiko Schocher int testfdt_ping(struct udevice *dev, int pingval, int *pingret) 802e7d35d2SSimon Glass { 812e7d35d2SSimon Glass const struct test_ops *ops = device_get_ops(dev); 822e7d35d2SSimon Glass 832e7d35d2SSimon Glass if (!ops->ping) 842e7d35d2SSimon Glass return -ENOSYS; 852e7d35d2SSimon Glass 862e7d35d2SSimon Glass return ops->ping(dev, pingval, pingret); 872e7d35d2SSimon Glass } 882e7d35d2SSimon Glass 892e7d35d2SSimon Glass UCLASS_DRIVER(testfdt) = { 902e7d35d2SSimon Glass .name = "testfdt", 912e7d35d2SSimon Glass .id = UCLASS_TEST_FDT, 922e7d35d2SSimon Glass }; 932e7d35d2SSimon Glass 942e7d35d2SSimon Glass /* Test that FDT-based binding works correctly */ 952e7d35d2SSimon Glass static int dm_test_fdt(struct dm_test_state *dms) 962e7d35d2SSimon Glass { 972e7d35d2SSimon Glass const int num_drivers = 3; 9854c5d08aSHeiko Schocher struct udevice *dev; 992e7d35d2SSimon Glass struct uclass *uc; 1002e7d35d2SSimon Glass int ret; 1012e7d35d2SSimon Glass int i; 1022e7d35d2SSimon Glass 103*00606d7eSSimon Glass ret = dm_scan_fdt(gd->fdt_blob, false); 1042e7d35d2SSimon Glass ut_assert(!ret); 1052e7d35d2SSimon Glass 1062e7d35d2SSimon Glass ret = uclass_get(UCLASS_TEST_FDT, &uc); 1072e7d35d2SSimon Glass ut_assert(!ret); 1082e7d35d2SSimon Glass 1092e7d35d2SSimon Glass /* These are num_drivers compatible root-level device tree nodes */ 1102e7d35d2SSimon Glass ut_asserteq(num_drivers, list_count_items(&uc->dev_head)); 1112e7d35d2SSimon Glass 1122e7d35d2SSimon Glass /* Each should have no platdata / priv */ 1132e7d35d2SSimon Glass for (i = 0; i < num_drivers; i++) { 1142e7d35d2SSimon Glass ret = uclass_find_device(UCLASS_TEST_FDT, i, &dev); 1152e7d35d2SSimon Glass ut_assert(!ret); 1162e7d35d2SSimon Glass ut_assert(!dev_get_priv(dev)); 1172e7d35d2SSimon Glass ut_assert(!dev->platdata); 1182e7d35d2SSimon Glass } 1192e7d35d2SSimon Glass 1202e7d35d2SSimon Glass /* 1212e7d35d2SSimon Glass * Now check that the ping adds are what we expect. This is using the 1222e7d35d2SSimon Glass * ping-add property in each node. 1232e7d35d2SSimon Glass */ 1242e7d35d2SSimon Glass for (i = 0; i < num_drivers; i++) { 1252e7d35d2SSimon Glass uint32_t base; 1262e7d35d2SSimon Glass 1272e7d35d2SSimon Glass ret = uclass_get_device(UCLASS_TEST_FDT, i, &dev); 1282e7d35d2SSimon Glass ut_assert(!ret); 1292e7d35d2SSimon Glass 1302e7d35d2SSimon Glass /* 131eb9ef5feSSimon Glass * Get the 'ping-expect' property, which tells us what the 132eb9ef5feSSimon Glass * ping add should be. We don't use the platdata because we 133eb9ef5feSSimon Glass * want to test the code that sets that up 134eb9ef5feSSimon Glass * (testfdt_drv_probe()). 1352e7d35d2SSimon Glass */ 136eb9ef5feSSimon Glass base = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, 137eb9ef5feSSimon Glass "ping-expect"); 1382e7d35d2SSimon Glass debug("dev=%d, base=%d: %s\n", i, base, 1392e7d35d2SSimon Glass fdt_get_name(gd->fdt_blob, dev->of_offset, NULL)); 1402e7d35d2SSimon Glass 1412e7d35d2SSimon Glass ut_assert(!dm_check_operations(dms, dev, base, 1422e7d35d2SSimon Glass dev_get_priv(dev))); 1432e7d35d2SSimon Glass } 1442e7d35d2SSimon Glass 1452e7d35d2SSimon Glass return 0; 1462e7d35d2SSimon Glass } 1472e7d35d2SSimon Glass DM_TEST(dm_test_fdt, 0); 148*00606d7eSSimon Glass 149*00606d7eSSimon Glass static int dm_test_fdt_pre_reloc(struct dm_test_state *dms) 150*00606d7eSSimon Glass { 151*00606d7eSSimon Glass struct uclass *uc; 152*00606d7eSSimon Glass int ret; 153*00606d7eSSimon Glass 154*00606d7eSSimon Glass ret = dm_scan_fdt(gd->fdt_blob, true); 155*00606d7eSSimon Glass ut_assert(!ret); 156*00606d7eSSimon Glass 157*00606d7eSSimon Glass ret = uclass_get(UCLASS_TEST_FDT, &uc); 158*00606d7eSSimon Glass ut_assert(!ret); 159*00606d7eSSimon Glass 160*00606d7eSSimon Glass /* These is only one pre-reloc device */ 161*00606d7eSSimon Glass ut_asserteq(1, list_count_items(&uc->dev_head)); 162*00606d7eSSimon Glass 163*00606d7eSSimon Glass return 0; 164*00606d7eSSimon Glass } 165*00606d7eSSimon Glass DM_TEST(dm_test_fdt_pre_reloc, 0); 166