forked from torvalds/linux
Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
misc: xilinx-ai-engine: Implement AI engine cleanup sequence
When AI engine partition is released, that is if no one is using the AI engine partition, by default, it will cleanup the partition by doing the following: * reset the columns * reset the SHIMs * clear data and program memory * gate all the tiles If user doesn't want the partition is reset when the partition is released, user can set the control flag to indicate not to reset the partition when the user requests the partition. If partition the not to reset partition control flag is set, it will not execute the above cleanup sequence when the partition is released. Signed-off-by: Wendy Liang <wendy.liang@xilinx.com> Reviewed-by: Hyun Kwon <hyun.kwon@xilinx.com>
- Loading branch information
1 parent
f3bd37b
commit 8345de0ce72a657e48ededa0fed6db62a28cf84a
Showing
7 changed files
with
259 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| // SPDX-License-Identifier: GPL-2.0 | ||
| /* | ||
| * Xilinx AI Engine device driver resets implementation | ||
| * | ||
| * Copyright (C) 2020 Xilinx, Inc. | ||
| */ | ||
|
|
||
| #include <linux/bitfield.h> | ||
| #include <linux/io.h> | ||
|
|
||
| #include "ai-engine-internal.h" | ||
|
|
||
| /** | ||
| * aie_part_set_col_reset() - set AI engine column reset | ||
| * @apart: AI engine partition | ||
| * @col: column to reset | ||
| * @reset: true to assert reset, false to release reset | ||
| */ | ||
| static void aie_part_set_col_reset(struct aie_partition *apart, u32 col, | ||
| bool reset) | ||
| { | ||
| struct aie_device *adev = apart->adev; | ||
| const struct aie_single_reg_field *col_rst = adev->col_rst; | ||
| struct aie_location loc; | ||
| u32 regoff, val; | ||
|
|
||
| loc.row = 0; | ||
| loc.col = col; | ||
|
|
||
| val = aie_get_field_val(col_rst, (reset ? 1 : 0)); | ||
| regoff = aie_cal_regoff(adev, loc, col_rst->regoff); | ||
| iowrite32(val, adev->base + regoff); | ||
| } | ||
|
|
||
| /** | ||
| * aie_part_set_col_clkbuf() - set AI engine column clock buffer | ||
| * @apart: AI engine partition | ||
| * @col: column to reset | ||
| * @enable: true to enable, false to disable | ||
| */ | ||
| static void aie_part_set_col_clkbuf(struct aie_partition *apart, u32 col, | ||
| bool enable) | ||
| { | ||
| struct aie_device *adev = apart->adev; | ||
| const struct aie_single_reg_field *col_clkbuf = adev->col_clkbuf; | ||
| struct aie_location loc; | ||
| u32 regoff, val; | ||
|
|
||
| loc.row = 0; | ||
| loc.col = col; | ||
|
|
||
| val = aie_get_field_val(col_clkbuf, (enable ? 1 : 0)); | ||
| regoff = aie_cal_regoff(adev, loc, col_clkbuf->regoff); | ||
| iowrite32(val, adev->base + regoff); | ||
| } | ||
|
|
||
| /** | ||
| * aie_part_set_cols_reset() - set column reset of every column in a partition | ||
| * @apart: AI engine partition | ||
| * @reset: bool to assert reset, false to release reset | ||
| */ | ||
| static void aie_part_set_cols_reset(struct aie_partition *apart, bool reset) | ||
| { | ||
| struct aie_range *range = &apart->range; | ||
| u32 c; | ||
|
|
||
| for (c = range->start.col; c < range->start.col + range->size.col; | ||
| c++) | ||
| aie_part_set_col_reset(apart, c, reset); | ||
| } | ||
|
|
||
| /** | ||
| * aie_part_set_cols_clkbuf() - set column clock buffer of every column in a | ||
| * partition | ||
| * @apart: AI engine partition | ||
| * @enable: true to enable, false to disable | ||
| */ | ||
| static void aie_part_set_cols_clkbuf(struct aie_partition *apart, bool enable) | ||
| { | ||
| struct aie_range *range = &apart->range; | ||
| u32 c; | ||
|
|
||
| for (c = range->start.col; c < range->start.col + range->size.col; | ||
| c++) | ||
| aie_part_set_col_clkbuf(apart, c, enable); | ||
| } | ||
|
|
||
| /** | ||
| * aie_part_clean() - reset and clear AI engine partition | ||
| * @apart: AI engine partition | ||
| * @return: 0 for success and negative value for failure | ||
| * | ||
| * This function will: | ||
| * * gate all the columns | ||
| * * reset AI engine partition columns | ||
| * * reset AI engine shims | ||
| * * clear the memories | ||
| * * gate all the tiles in a partition. | ||
| * | ||
| * This function will not validate the partition, the caller will need to | ||
| * provide a valid AI engine partition. | ||
| */ | ||
| int aie_part_clean(struct aie_partition *apart) | ||
| { | ||
| struct aie_device *adev = apart->adev; | ||
| int ret; | ||
|
|
||
| if (apart->cntrflag & XAIE_PART_NOT_RST_ON_RELEASE) | ||
| return 0; | ||
|
|
||
| aie_part_set_cols_clkbuf(apart, false); | ||
| aie_part_set_cols_reset(apart, true); | ||
|
|
||
| ret = apart->adev->ops->reset_shim(adev, &apart->range); | ||
| if (ret < 0) | ||
| return ret; | ||
|
|
||
| aie_part_set_cols_clkbuf(apart, false); | ||
|
|
||
| return 0; | ||
| } |
Oops, something went wrong.