device.c (93a40a6d7428921897bb7fed5ffb4ce83df05432) device.c (8c66bbdc4fbf3c297ebc8edf71f359e4a132c9db)
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2019 Intel Corporation. All rights rsvd. */
3#include <linux/init.h>
4#include <linux/kernel.h>
5#include <linux/module.h>
6#include <linux/pci.h>
7#include <linux/io-64-nonatomic-lo-hi.h>
8#include <linux/dmaengine.h>

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

879 return rc;
880
881 rc = idxd_groups_config_write(idxd);
882 if (rc < 0)
883 return rc;
884
885 return 0;
886}
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright(c) 2019 Intel Corporation. All rights rsvd. */
3#include <linux/init.h>
4#include <linux/kernel.h>
5#include <linux/module.h>
6#include <linux/pci.h>
7#include <linux/io-64-nonatomic-lo-hi.h>
8#include <linux/dmaengine.h>

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

879 return rc;
880
881 rc = idxd_groups_config_write(idxd);
882 if (rc < 0)
883 return rc;
884
885 return 0;
886}
887
888static int idxd_wq_load_config(struct idxd_wq *wq)
889{
890 struct idxd_device *idxd = wq->idxd;
891 struct device *dev = &idxd->pdev->dev;
892 int wqcfg_offset;
893 int i;
894
895 wqcfg_offset = WQCFG_OFFSET(idxd, wq->id, 0);
896 memcpy_fromio(wq->wqcfg, idxd->reg_base + wqcfg_offset, idxd->wqcfg_size);
897
898 wq->size = wq->wqcfg->wq_size;
899 wq->threshold = wq->wqcfg->wq_thresh;
900 if (wq->wqcfg->priv)
901 wq->type = IDXD_WQT_KERNEL;
902
903 /* The driver does not support shared WQ mode in read-only config yet */
904 if (wq->wqcfg->mode == 0 || wq->wqcfg->pasid_en)
905 return -EOPNOTSUPP;
906
907 set_bit(WQ_FLAG_DEDICATED, &wq->flags);
908
909 wq->priority = wq->wqcfg->priority;
910
911 for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
912 wqcfg_offset = WQCFG_OFFSET(idxd, wq->id, i);
913 dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n", wq->id, i, wqcfg_offset, wq->wqcfg->bits[i]);
914 }
915
916 return 0;
917}
918
919static void idxd_group_load_config(struct idxd_group *group)
920{
921 struct idxd_device *idxd = group->idxd;
922 struct device *dev = &idxd->pdev->dev;
923 int i, j, grpcfg_offset;
924
925 /*
926 * Load WQS bit fields
927 * Iterate through all 256 bits 64 bits at a time
928 */
929 for (i = 0; i < GRPWQCFG_STRIDES; i++) {
930 struct idxd_wq *wq;
931
932 grpcfg_offset = GRPWQCFG_OFFSET(idxd, group->id, i);
933 group->grpcfg.wqs[i] = ioread64(idxd->reg_base + grpcfg_offset);
934 dev_dbg(dev, "GRPCFG wq[%d:%d: %#x]: %#llx\n",
935 group->id, i, grpcfg_offset, group->grpcfg.wqs[i]);
936
937 if (i * 64 >= idxd->max_wqs)
938 break;
939
940 /* Iterate through all 64 bits and check for wq set */
941 for (j = 0; j < 64; j++) {
942 int id = i * 64 + j;
943
944 /* No need to check beyond max wqs */
945 if (id >= idxd->max_wqs)
946 break;
947
948 /* Set group assignment for wq if wq bit is set */
949 if (group->grpcfg.wqs[i] & BIT(j)) {
950 wq = idxd->wqs[id];
951 wq->group = group;
952 }
953 }
954 }
955
956 grpcfg_offset = GRPENGCFG_OFFSET(idxd, group->id);
957 group->grpcfg.engines = ioread64(idxd->reg_base + grpcfg_offset);
958 dev_dbg(dev, "GRPCFG engs[%d: %#x]: %#llx\n", group->id,
959 grpcfg_offset, group->grpcfg.engines);
960
961 /* Iterate through all 64 bits to check engines set */
962 for (i = 0; i < 64; i++) {
963 if (i >= idxd->max_engines)
964 break;
965
966 if (group->grpcfg.engines & BIT(i)) {
967 struct idxd_engine *engine = idxd->engines[i];
968
969 engine->group = group;
970 }
971 }
972
973 grpcfg_offset = GRPFLGCFG_OFFSET(idxd, group->id);
974 group->grpcfg.flags.bits = ioread32(idxd->reg_base + grpcfg_offset);
975 dev_dbg(dev, "GRPFLAGS flags[%d: %#x]: %#x\n",
976 group->id, grpcfg_offset, group->grpcfg.flags.bits);
977}
978
979int idxd_device_load_config(struct idxd_device *idxd)
980{
981 union gencfg_reg reg;
982 int i, rc;
983
984 reg.bits = ioread32(idxd->reg_base + IDXD_GENCFG_OFFSET);
985 idxd->token_limit = reg.token_limit;
986
987 for (i = 0; i < idxd->max_groups; i++) {
988 struct idxd_group *group = idxd->groups[i];
989
990 idxd_group_load_config(group);
991 }
992
993 for (i = 0; i < idxd->max_wqs; i++) {
994 struct idxd_wq *wq = idxd->wqs[i];
995
996 rc = idxd_wq_load_config(wq);
997 if (rc < 0)
998 return rc;
999 }
1000
1001 return 0;
1002}