kunpeng_hccs.c (b51878373a81bda3a790fd936507fd0643ef98b3) kunpeng_hccs.c (23fe8112a23106e7dfc2b73fc52a60ea3eb64c20)
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * The Huawei Cache Coherence System (HCCS) is a multi-chip interconnection
4 * bus protocol.
5 *
6 * Copyright (c) 2023 Hisilicon Limited.
7 * Author: Huisong Li <lihuisong@huawei.com>
8 *

--- 7 unchanged lines hidden (view full) ---

16 * - lane mask
17 * - CRC error count
18 *
19 * - Retrieve the following information about all the ports on the chip or
20 * the die:
21 * - if all enabled ports are in linked
22 * - if all linked ports are in full lane
23 * - CRC error count sum
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * The Huawei Cache Coherence System (HCCS) is a multi-chip interconnection
4 * bus protocol.
5 *
6 * Copyright (c) 2023 Hisilicon Limited.
7 * Author: Huisong Li <lihuisong@huawei.com>
8 *

--- 7 unchanged lines hidden (view full) ---

16 * - lane mask
17 * - CRC error count
18 *
19 * - Retrieve the following information about all the ports on the chip or
20 * the die:
21 * - if all enabled ports are in linked
22 * - if all linked ports are in full lane
23 * - CRC error count sum
24 *
25 * - Retrieve all HCCS types used on the platform.
24 */
25#include <linux/acpi.h>
26#include <linux/iopoll.h>
27#include <linux/platform_device.h>
28#include <linux/sysfs.h>
26 */
27#include <linux/acpi.h>
28#include <linux/iopoll.h>
29#include <linux/platform_device.h>
30#include <linux/sysfs.h>
31#include <linux/types.h>
29
30#include <acpi/pcc.h>
31
32#include "kunpeng_hccs.h"
33
34/*
35 * Arbitrary retries in case the remote processor is slow to respond
36 * to PCC commands

--- 11 unchanged lines hidden (view full) ---

48 return container_of(k, struct hccs_die_info, kobj);
49}
50
51static struct hccs_chip_info *kobj_to_chip_info(struct kobject *k)
52{
53 return container_of(k, struct hccs_chip_info, kobj);
54}
55
32
33#include <acpi/pcc.h>
34
35#include "kunpeng_hccs.h"
36
37/*
38 * Arbitrary retries in case the remote processor is slow to respond
39 * to PCC commands

--- 11 unchanged lines hidden (view full) ---

51 return container_of(k, struct hccs_die_info, kobj);
52}
53
54static struct hccs_chip_info *kobj_to_chip_info(struct kobject *k)
55{
56 return container_of(k, struct hccs_chip_info, kobj);
57}
58
59static struct hccs_dev *device_kobj_to_hccs_dev(struct kobject *k)
60{
61 struct device *dev = container_of(k, struct device, kobj);
62 struct platform_device *pdev =
63 container_of(dev, struct platform_device, dev);
64
65 return platform_get_drvdata(pdev);
66}
67
56struct hccs_register_ctx {
57 struct device *dev;
58 u8 chan_id;
59 int err;
60};
61
62static acpi_status hccs_get_register_cb(struct acpi_resource *ares,
63 void *context)

--- 601 unchanged lines hidden (view full) ---

665 dev_err(hdev->dev, "query all port info on platform failed, ret = %d.\n",
666 ret);
667 return ret;
668 }
669
670 return 0;
671}
672
68struct hccs_register_ctx {
69 struct device *dev;
70 u8 chan_id;
71 int err;
72};
73
74static acpi_status hccs_get_register_cb(struct acpi_resource *ares,
75 void *context)

--- 601 unchanged lines hidden (view full) ---

677 dev_err(hdev->dev, "query all port info on platform failed, ret = %d.\n",
678 ret);
679 return ret;
680 }
681
682 return 0;
683}
684
685static u16 hccs_calc_used_type_num(struct hccs_dev *hdev,
686 unsigned long *hccs_ver)
687{
688 struct hccs_chip_info *chip;
689 struct hccs_port_info *port;
690 struct hccs_die_info *die;
691 u16 used_type_num = 0;
692 u16 i, j, k;
693
694 for (i = 0; i < hdev->chip_num; i++) {
695 chip = &hdev->chips[i];
696 for (j = 0; j < chip->die_num; j++) {
697 die = &chip->dies[j];
698 for (k = 0; k < die->port_num; k++) {
699 port = &die->ports[k];
700 set_bit(port->port_type, hccs_ver);
701 }
702 }
703 }
704
705 for_each_set_bit(i, hccs_ver, HCCS_IP_MAX + 1)
706 used_type_num++;
707
708 return used_type_num;
709}
710
711static int hccs_init_type_name_maps(struct hccs_dev *hdev)
712{
713 DECLARE_BITMAP(hccs_ver, HCCS_IP_MAX + 1) = {};
714 unsigned int i;
715 u16 idx = 0;
716
717 hdev->used_type_num = hccs_calc_used_type_num(hdev, hccs_ver);
718 hdev->type_name_maps = devm_kcalloc(hdev->dev, hdev->used_type_num,
719 sizeof(struct hccs_type_name_map),
720 GFP_KERNEL);
721 if (!hdev->type_name_maps)
722 return -ENOMEM;
723
724 for_each_set_bit(i, hccs_ver, HCCS_IP_MAX + 1) {
725 hdev->type_name_maps[idx].type = i;
726 sprintf(hdev->type_name_maps[idx].name,
727 "%s%u", HCCS_IP_PREFIX, i);
728 idx++;
729 }
730
731 return 0;
732}
733
673static int hccs_query_port_link_status(struct hccs_dev *hdev,
674 const struct hccs_port_info *port,
675 struct hccs_link_status *link_status)
676{
677 const struct hccs_die_info *die = port->die;
678 const struct hccs_chip_info *chip = die->chip;
679 struct hccs_port_comm_req_param *req_param;
680 struct hccs_desc desc;

--- 144 unchanged lines hidden (view full) ---

825 .show = hccs_show,
826};
827
828static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr,
829 char *buf)
830{
831 const struct hccs_port_info *port = kobj_to_port_info(kobj);
832
734static int hccs_query_port_link_status(struct hccs_dev *hdev,
735 const struct hccs_port_info *port,
736 struct hccs_link_status *link_status)
737{
738 const struct hccs_die_info *die = port->die;
739 const struct hccs_chip_info *chip = die->chip;
740 struct hccs_port_comm_req_param *req_param;
741 struct hccs_desc desc;

--- 144 unchanged lines hidden (view full) ---

886 .show = hccs_show,
887};
888
889static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr,
890 char *buf)
891{
892 const struct hccs_port_info *port = kobj_to_port_info(kobj);
893
833 return sysfs_emit(buf, "HCCS-v%u\n", port->port_type);
894 return sysfs_emit(buf, "%s%u\n", HCCS_IP_PREFIX, port->port_type);
834}
835static struct kobj_attribute hccs_type_attr = __ATTR_RO(type);
836
837static ssize_t lane_mode_show(struct kobject *kobj, struct kobj_attribute *attr,
838 char *buf)
839{
840 const struct hccs_port_info *port = kobj_to_port_info(kobj);
841

--- 287 unchanged lines hidden (view full) ---

1129};
1130ATTRIBUTE_GROUPS(hccs_chip_default);
1131
1132static const struct kobj_type hccs_chip_type = {
1133 .sysfs_ops = &hccs_comm_ops,
1134 .default_groups = hccs_chip_default_groups,
1135};
1136
895}
896static struct kobj_attribute hccs_type_attr = __ATTR_RO(type);
897
898static ssize_t lane_mode_show(struct kobject *kobj, struct kobj_attribute *attr,
899 char *buf)
900{
901 const struct hccs_port_info *port = kobj_to_port_info(kobj);
902

--- 287 unchanged lines hidden (view full) ---

1190};
1191ATTRIBUTE_GROUPS(hccs_chip_default);
1192
1193static const struct kobj_type hccs_chip_type = {
1194 .sysfs_ops = &hccs_comm_ops,
1195 .default_groups = hccs_chip_default_groups,
1196};
1197
1198
1199static ssize_t used_types_show(struct kobject *kobj,
1200 struct kobj_attribute *attr, char *buf)
1201{
1202 struct hccs_dev *hdev = device_kobj_to_hccs_dev(kobj);
1203 int len = 0;
1204 u16 i;
1205
1206 for (i = 0; i < hdev->used_type_num - 1; i++)
1207 len += sysfs_emit(&buf[len], "%s ", hdev->type_name_maps[i].name);
1208 len += sysfs_emit(&buf[len], "%s\n", hdev->type_name_maps[i].name);
1209
1210 return len;
1211}
1212static struct kobj_attribute used_types_attr =
1213 __ATTR(used_types, 0444, used_types_show, NULL);
1214
1215static void hccs_remove_misc_sysfs(struct hccs_dev *hdev)
1216{
1217 sysfs_remove_file(&hdev->dev->kobj, &used_types_attr.attr);
1218}
1219
1220static int hccs_add_misc_sysfs(struct hccs_dev *hdev)
1221{
1222 return sysfs_create_file(&hdev->dev->kobj, &used_types_attr.attr);
1223}
1224
1137static void hccs_remove_die_dir(struct hccs_die_info *die)
1138{
1139 struct hccs_port_info *port;
1140 u8 i;
1141
1142 for (i = 0; i < die->port_num; i++) {
1143 port = &die->ports[i];
1144 if (port->dir_created)

--- 18 unchanged lines hidden (view full) ---

1163}
1164
1165static void hccs_remove_topo_dirs(struct hccs_dev *hdev)
1166{
1167 u8 i;
1168
1169 for (i = 0; i < hdev->chip_num; i++)
1170 hccs_remove_chip_dir(&hdev->chips[i]);
1225static void hccs_remove_die_dir(struct hccs_die_info *die)
1226{
1227 struct hccs_port_info *port;
1228 u8 i;
1229
1230 for (i = 0; i < die->port_num; i++) {
1231 port = &die->ports[i];
1232 if (port->dir_created)

--- 18 unchanged lines hidden (view full) ---

1251}
1252
1253static void hccs_remove_topo_dirs(struct hccs_dev *hdev)
1254{
1255 u8 i;
1256
1257 for (i = 0; i < hdev->chip_num; i++)
1258 hccs_remove_chip_dir(&hdev->chips[i]);
1259
1260 hccs_remove_misc_sysfs(hdev);
1171}
1172
1173static int hccs_create_hccs_dir(struct hccs_dev *hdev,
1174 struct hccs_die_info *die,
1175 struct hccs_port_info *port)
1176{
1177 int ret;
1178

--- 79 unchanged lines hidden (view full) ---

1258 chip = &hdev->chips[id];
1259 ret = hccs_create_chip_dir(hdev, chip);
1260 if (ret) {
1261 dev_err(hdev->dev, "init chip%u dir failed!\n", id);
1262 goto err;
1263 }
1264 }
1265
1261}
1262
1263static int hccs_create_hccs_dir(struct hccs_dev *hdev,
1264 struct hccs_die_info *die,
1265 struct hccs_port_info *port)
1266{
1267 int ret;
1268

--- 79 unchanged lines hidden (view full) ---

1348 chip = &hdev->chips[id];
1349 ret = hccs_create_chip_dir(hdev, chip);
1350 if (ret) {
1351 dev_err(hdev->dev, "init chip%u dir failed!\n", id);
1352 goto err;
1353 }
1354 }
1355
1356 ret = hccs_add_misc_sysfs(hdev);
1357 if (ret) {
1358 dev_err(hdev->dev, "create misc sysfs interface failed, ret = %d\n", ret);
1359 goto err;
1360 }
1361
1266 return 0;
1267err:
1268 for (k = 0; k < id; k++)
1269 hccs_remove_chip_dir(&hdev->chips[k]);
1270
1271 return ret;
1272}
1273

--- 34 unchanged lines hidden (view full) ---

1308 rc = hccs_get_dev_caps(hdev);
1309 if (rc)
1310 goto unregister_pcc_chan;
1311
1312 rc = hccs_get_hw_info(hdev);
1313 if (rc)
1314 goto unregister_pcc_chan;
1315
1362 return 0;
1363err:
1364 for (k = 0; k < id; k++)
1365 hccs_remove_chip_dir(&hdev->chips[k]);
1366
1367 return ret;
1368}
1369

--- 34 unchanged lines hidden (view full) ---

1404 rc = hccs_get_dev_caps(hdev);
1405 if (rc)
1406 goto unregister_pcc_chan;
1407
1408 rc = hccs_get_hw_info(hdev);
1409 if (rc)
1410 goto unregister_pcc_chan;
1411
1412 rc = hccs_init_type_name_maps(hdev);
1413 if (rc)
1414 goto unregister_pcc_chan;
1415
1316 rc = hccs_create_topo_dirs(hdev);
1317 if (rc)
1318 goto unregister_pcc_chan;
1319
1320 return 0;
1321
1322unregister_pcc_chan:
1323 hccs_unregister_pcc_channel(hdev);

--- 49 unchanged lines hidden ---
1416 rc = hccs_create_topo_dirs(hdev);
1417 if (rc)
1418 goto unregister_pcc_chan;
1419
1420 return 0;
1421
1422unregister_pcc_chan:
1423 hccs_unregister_pcc_channel(hdev);

--- 49 unchanged lines hidden ---