feeds: resolve conflict
This commit is contained in:
commit
390085a386
146 changed files with 17399 additions and 1735 deletions
8
.github/workflows/Dockerfile.toolchain
vendored
Normal file
8
.github/workflows/Dockerfile.toolchain
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
ARG OWNER_LC
|
||||
ARG CONTAINER_TAG
|
||||
|
||||
FROM ghcr.io/$OWNER_LC/tools:$CONTAINER_TAG
|
||||
|
||||
ARG TOOLCHAIN_NAME
|
||||
|
||||
ADD $TOOLCHAIN_NAME /external-toolchain/
|
114
.github/workflows/build.yml
vendored
114
.github/workflows/build.yml
vendored
|
@ -5,6 +5,9 @@ on:
|
|||
secrets:
|
||||
coverity_api_token:
|
||||
inputs:
|
||||
container_name:
|
||||
type: string
|
||||
default: tools
|
||||
target:
|
||||
required: true
|
||||
type: string
|
||||
|
@ -47,6 +50,10 @@ on:
|
|||
mbedtls
|
||||
wolfssl
|
||||
openssl
|
||||
build_external_toolchain:
|
||||
type: boolean
|
||||
upload_external_toolchain:
|
||||
type: boolean
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -59,6 +66,7 @@ jobs:
|
|||
owner_lc: ${{ steps.lower_owner.outputs.owner_lc }}
|
||||
ccache_hash: ${{ steps.ccache_hash.outputs.ccache_hash }}
|
||||
container_tag: ${{ steps.determine_tools_container.outputs.container_tag }}
|
||||
container_name: ${{ steps.determine_tools_container.outputs.container_name }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
|
@ -92,6 +100,7 @@ jobs:
|
|||
- name: Determine tools container tag
|
||||
id: determine_tools_container
|
||||
run: |
|
||||
CONTAINER_NAME=${{ inputs.container_name }}
|
||||
CONTAINER_TAG=latest
|
||||
if [ -n "${{ github.base_ref }}" ]; then
|
||||
if echo "${{ github.base_ref }}" | grep -q -E '^openwrt-[0-9][0-9]\.[0-9][0-9]$'; then
|
||||
|
@ -108,15 +117,29 @@ jobs:
|
|||
CONTAINER_TAG=openwrt-"$(echo ${{ github.ref_name }} | sed 's/^v\([0-9][0-9]\.[0-9][0-9]\)\..\+/\1/')"
|
||||
fi
|
||||
fi
|
||||
echo "Tools container to use tools:$CONTAINER_TAG"
|
||||
|
||||
if [ "$CONTAINER_NAME" = "toolchain" ]; then
|
||||
GHCR_TOKEN=$(echo ${{ secrets.GITHUB_TOKEN }} | base64)
|
||||
GHCR_HEADER="Authorization: Bearer ${GHCR_TOKEN}"
|
||||
GHCR_MANIFEST_LINK=https://ghcr.io/v2/${{ steps.lower_owner.outputs.owner_lc }}/${{ inputs.container_name }}/manifests/${{ inputs.target }}-${{ inputs.subtarget }}-"$CONTAINER_TAG"
|
||||
# Check if container exist
|
||||
if [ $(curl -s -o /dev/null -w "%{http_code}" -H "$GHCR_HEADER" -I "$GHCR_MANIFEST_LINK") = 200 ]; then
|
||||
CONTAINER_TAG=${{ inputs.target }}-${{ inputs.subtarget }}-"$CONTAINER_TAG"
|
||||
else
|
||||
CONTAINER_NAME=tools
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Tools container to use $CONTAINER_NAME:$CONTAINER_TAG"
|
||||
echo "container_tag=$CONTAINER_TAG" >> $GITHUB_OUTPUT
|
||||
echo "container_name=$CONTAINER_NAME" >> $GITHUB_OUTPUT
|
||||
|
||||
build:
|
||||
name: Build ${{ inputs.target }}/${{ inputs.subtarget }}
|
||||
needs: setup_build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
container: ghcr.io/${{ needs.setup_build.outputs.owner_lc }}/tools:${{ needs.setup_build.outputs.container_tag }}
|
||||
container: ghcr.io/${{ needs.setup_build.outputs.owner_lc }}/${{ needs.setup_build.outputs.container_name }}:${{ needs.setup_build.outputs.container_tag }}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -156,33 +179,16 @@ jobs:
|
|||
repository: openwrt/telephony
|
||||
path: openwrt/feeds/telephony
|
||||
|
||||
- name: Fix permission
|
||||
run: |
|
||||
chown -R buildbot:buildbot openwrt
|
||||
|
||||
- name: Prepare prebuilt tools
|
||||
shell: su buildbot -c "sh -e {0}"
|
||||
working-directory: openwrt
|
||||
run: |
|
||||
mkdir -p staging_dir build_dir
|
||||
ln -s /prebuilt_tools/staging_dir/host staging_dir/host
|
||||
ln -s /prebuilt_tools/build_dir/host build_dir/host
|
||||
|
||||
./scripts/ext-tools.sh --refresh
|
||||
|
||||
- name: Update & Install feeds
|
||||
if: inputs.include_feeds == true
|
||||
shell: su buildbot -c "sh -e {0}"
|
||||
working-directory: openwrt
|
||||
run: |
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
|
||||
- name: Parse toolchain file
|
||||
if: inputs.build_toolchain == false
|
||||
id: parse-toolchain
|
||||
working-directory: openwrt
|
||||
run: |
|
||||
if [ -d /external-toolchain/ ]; then
|
||||
echo "toolchain-type=external_container" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TOOLCHAIN_PATH=snapshots
|
||||
|
||||
if [ -n "${{ github.base_ref }}" ]; then
|
||||
|
@ -227,6 +233,28 @@ jobs:
|
|||
echo "TOOLCHAIN_FILE=$TOOLCHAIN_FILE" >> "$GITHUB_ENV"
|
||||
echo "TOOLCHAIN_PATH=$TOOLCHAIN_PATH" >> "$GITHUB_ENV"
|
||||
|
||||
- name: Fix permission
|
||||
run: |
|
||||
chown -R buildbot:buildbot openwrt
|
||||
|
||||
- name: Prepare prebuilt tools
|
||||
shell: su buildbot -c "sh -e {0}"
|
||||
working-directory: openwrt
|
||||
run: |
|
||||
mkdir -p staging_dir build_dir
|
||||
ln -s /prebuilt_tools/staging_dir/host staging_dir/host
|
||||
ln -s /prebuilt_tools/build_dir/host build_dir/host
|
||||
|
||||
./scripts/ext-tools.sh --refresh
|
||||
|
||||
- name: Update & Install feeds
|
||||
if: inputs.include_feeds == true
|
||||
shell: su buildbot -c "sh -e {0}"
|
||||
working-directory: openwrt
|
||||
run: |
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
|
||||
- name: Cache ccache
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
|
@ -236,7 +264,7 @@ jobs:
|
|||
ccache-kernel-${{ inputs.target }}/${{ inputs.subtarget }}-
|
||||
|
||||
- name: Download external toolchain/sdk
|
||||
if: inputs.build_toolchain == false && steps.parse-toolchain.outputs.toolchain-type != 'internal'
|
||||
if: inputs.build_toolchain == false && steps.parse-toolchain.outputs.toolchain-type != 'internal' && steps.parse-toolchain.outputs.toolchain-type != 'external_container'
|
||||
shell: su buildbot -c "sh -e {0}"
|
||||
working-directory: openwrt
|
||||
run: |
|
||||
|
@ -273,6 +301,20 @@ jobs:
|
|||
echo CONFIG_TARGET_PER_DEVICE_ROOTFS=y >> .config
|
||||
echo CONFIG_TARGET_ALL_PROFILES=y >> .config
|
||||
|
||||
- name: Configure external toolchain in container
|
||||
if: inputs.build_toolchain == false && steps.parse-toolchain.outputs.toolchain-type == 'external_container'
|
||||
shell: su buildbot -c "sh -e {0}"
|
||||
working-directory: openwrt
|
||||
run: |
|
||||
echo CONFIG_DEVEL=y >> .config
|
||||
echo CONFIG_AUTOREMOVE=y >> .config
|
||||
echo CONFIG_CCACHE=y >> .config
|
||||
|
||||
./scripts/ext-toolchain.sh \
|
||||
--toolchain /external-toolchain/$(ls /external-toolchain/ | grep openwrt-toolchain)/toolchain-* \
|
||||
--overwrite-config \
|
||||
--config ${{ inputs.target }}/${{ inputs.subtarget }}
|
||||
|
||||
- name: Configure external toolchain
|
||||
if: inputs.build_toolchain == false && steps.parse-toolchain.outputs.toolchain-type == 'external_toolchain'
|
||||
shell: su buildbot -c "sh -e {0}"
|
||||
|
@ -376,6 +418,12 @@ jobs:
|
|||
working-directory: openwrt
|
||||
run: make -j$(nproc) BUILD_LOG=1 || ret=$? .github/workflows/scripts/show_build_failures.sh
|
||||
|
||||
- name: Build external toolchain
|
||||
if: inputs.build_external_toolchain == true
|
||||
shell: su buildbot -c "sh -e {0}"
|
||||
working-directory: openwrt
|
||||
run: make target/toolchain/compile -j$(nproc) BUILD_LOG=1 || ret=$? .github/workflows/scripts/show_build_failures.sh
|
||||
|
||||
- name: Coverity prepare toolchain
|
||||
if: inputs.coverity_check_packages != ''
|
||||
shell: su buildbot -c "sh -e {0}"
|
||||
|
@ -433,3 +481,19 @@ jobs:
|
|||
with:
|
||||
name: ${{ inputs.target }}-${{ inputs.subtarget }}-logs
|
||||
path: "openwrt/logs"
|
||||
|
||||
- name: Find external toolchain name
|
||||
id: get-toolchain-name
|
||||
if: inputs.upload_external_toolchain == true
|
||||
working-directory: openwrt
|
||||
run: |
|
||||
TOOLCHAIN_NAME=$(ls bin/targets/${{inputs.target }}/${{ inputs.subtarget }} | grep toolchain)
|
||||
echo "toolchain-name=$TOOLCHAIN_NAME" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Upload prebuilt toolchain
|
||||
if: inputs.upload_external_toolchain == true
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ inputs.target }}-${{ inputs.subtarget }}-external-toolchain
|
||||
path: openwrt/bin/targets/${{ inputs.target }}/${{ inputs.subtarget }}/${{ steps.get-toolchain-name.outputs.toolchain-name }}
|
||||
retention-days: 1
|
||||
|
|
1
.github/workflows/coverity.yml
vendored
1
.github/workflows/coverity.yml
vendored
|
@ -17,6 +17,7 @@ jobs:
|
|||
packages: read
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
container_name: toolchain
|
||||
target: x86
|
||||
subtarget: 64
|
||||
build_full: true
|
||||
|
|
3
.github/workflows/kernel.yml
vendored
3
.github/workflows/kernel.yml
vendored
|
@ -17,6 +17,8 @@ on:
|
|||
- 'include/kernel*'
|
||||
- 'package/kernel/**'
|
||||
- 'target/linux/**'
|
||||
branches-ignore:
|
||||
- master
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -109,6 +111,7 @@ jobs:
|
|||
include: ${{fromJson(needs.determine_targets.outputs.targets_subtargets)}}
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
container_name: toolchain
|
||||
target: ${{ matrix.target }}
|
||||
subtarget: ${{ matrix.subtarget }}
|
||||
build_kernel: true
|
||||
|
|
6
.github/workflows/label-kernel.yml
vendored
6
.github/workflows/label-kernel.yml
vendored
|
@ -13,6 +13,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
target: ${{ steps.set_target.outputs.target }}
|
||||
subtarget: ${{ steps.set_target.outputs.subtarget }}
|
||||
|
||||
steps:
|
||||
- name: Set target
|
||||
|
@ -20,7 +21,8 @@ jobs:
|
|||
env:
|
||||
CI_EVENT_LABEL_NAME: ${{ github.event.label.name }}
|
||||
run: |
|
||||
echo "$CI_EVENT_LABEL_NAME" | sed -n 's/.*:\(.*\):\(.*\)$/target="\1\/\2"/p' | tee --append $GITHUB_OUTPUT
|
||||
echo "$CI_EVENT_LABEL_NAME" | sed -n 's/.*:\(.*\):\(.*\)$/target="\1"/p' | tee --append $GITHUB_OUTPUT
|
||||
echo "$CI_EVENT_LABEL_NAME" | sed -n 's/.*:\(.*\):\(.*\)$/subtarget="\2"/p' | tee --append $GITHUB_OUTPUT
|
||||
|
||||
build_kernel:
|
||||
name: Build Kernel with external toolchain
|
||||
|
@ -31,6 +33,7 @@ jobs:
|
|||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
target: ${{ needs.set_target.outputs.target }}
|
||||
subtarget: ${{ needs.set_target.outputs.subtarget }}
|
||||
build_kernel: true
|
||||
build_all_kmods: true
|
||||
|
||||
|
@ -43,3 +46,4 @@ jobs:
|
|||
uses: ./.github/workflows/check-kernel-patches.yml
|
||||
with:
|
||||
target: ${{ needs.set_target.outputs.target }}
|
||||
subtarget: ${{ needs.set_target.outputs.subtarget }}
|
||||
|
|
5
.github/workflows/label-target.yml
vendored
5
.github/workflows/label-target.yml
vendored
|
@ -13,6 +13,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
target: ${{ steps.set_target.outputs.target }}
|
||||
subtarget: ${{ steps.set_target.outputs.subtarget }}
|
||||
|
||||
steps:
|
||||
- name: Set target
|
||||
|
@ -20,7 +21,8 @@ jobs:
|
|||
env:
|
||||
CI_EVENT_LABEL_NAME: ${{ github.event.label.name }}
|
||||
run: |
|
||||
echo "$CI_EVENT_LABEL_NAME" | sed -n 's/.*:\(.*\):\(.*\)$/target="\1\/\2"/p' | tee --append $GITHUB_OUTPUT
|
||||
echo "$CI_EVENT_LABEL_NAME" | sed -n 's/.*:\(.*\):\(.*\)$/target="\1"/p' | tee --append $GITHUB_OUTPUT
|
||||
echo "$CI_EVENT_LABEL_NAME" | sed -n 's/.*:\(.*\):\(.*\)$/subtarget="\2"/p' | tee --append $GITHUB_OUTPUT
|
||||
|
||||
build_target:
|
||||
name: Build target
|
||||
|
@ -31,6 +33,7 @@ jobs:
|
|||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
target: ${{ needs.set_target.outputs.target }}
|
||||
subtarget: ${{ needs.set_target.outputs.subtarget }}
|
||||
build_full: true
|
||||
build_all_kmods: true
|
||||
build_all_boards: true
|
||||
|
|
3
.github/workflows/packages.yml
vendored
3
.github/workflows/packages.yml
vendored
|
@ -19,6 +19,8 @@ on:
|
|||
- 'package/**'
|
||||
- 'target/linux/generic/**'
|
||||
- 'toolchain/**'
|
||||
branches-ignore:
|
||||
- master
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -43,6 +45,7 @@ jobs:
|
|||
subtarget: 64
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
container_name: toolchain
|
||||
target: ${{ matrix.target }}
|
||||
subtarget: ${{ matrix.subtarget }}
|
||||
build_kernel: true
|
||||
|
|
159
.github/workflows/push-containers.yml
vendored
159
.github/workflows/push-containers.yml
vendored
|
@ -3,10 +3,17 @@ name: Build and Push prebuilt tools container
|
|||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'include/version.mk'
|
||||
- 'tools/**'
|
||||
- '.github/workflows/build-tools.yml'
|
||||
- '.github/workflows/push-containers.yml'
|
||||
- '.github/workflows/Dockerfile.tools'
|
||||
- 'toolchain/**'
|
||||
- '.github/workflows/build.yml'
|
||||
- '.github/workflows/toolchain.yml'
|
||||
- '.github/workflows/Dockerfile.toolchain'
|
||||
branches-ignore:
|
||||
- master
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -16,29 +23,21 @@ concurrency:
|
|||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-linux-buildbot:
|
||||
name: Build tools with buildbot container
|
||||
if: ${{ github.repository_owner == 'openwrt' }}
|
||||
uses: ./.github/workflows/build-tools.yml
|
||||
with:
|
||||
generate_prebuilt_artifacts: true
|
||||
|
||||
push-tools-container:
|
||||
needs: build-linux-buildbot
|
||||
name: Push prebuilt tools container
|
||||
determine-container-info:
|
||||
name: Determine needed info to push containers
|
||||
if: ${{ github.repository_owner == 'openwrt' }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
outputs:
|
||||
owner-lc: ${{ steps.generate-owner-lc.outputs.owner-lc }}
|
||||
container-tag: ${{ steps.determine-container-tag.outputs.container-tag }}
|
||||
|
||||
steps:
|
||||
- name: Set lower case owner name
|
||||
id: generate-owner-lc
|
||||
env:
|
||||
OWNER: ${{ github.repository_owner }}
|
||||
run: |
|
||||
echo "OWNER_LC=${OWNER,,}" >> "$GITHUB_ENV"
|
||||
echo "owner-lc=${OWNER,,}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Per branch tools container tag
|
||||
# By default stick to latest
|
||||
|
@ -49,6 +48,7 @@ jobs:
|
|||
# (example branch openwrt-22.03 -> tools:openwrt-22.03)
|
||||
# (example branch openwrt-22.03-test -> tools:openwrt-22.03)
|
||||
- name: Determine tools container tag
|
||||
id: determine-container-tag
|
||||
run: |
|
||||
CONTAINER_TAG=latest
|
||||
|
||||
|
@ -62,9 +62,27 @@ jobs:
|
|||
fi
|
||||
fi
|
||||
|
||||
echo "Tools container to push tools:$CONTAINER_TAG"
|
||||
echo "CONTAINER_TAG=$CONTAINER_TAG" >> "$GITHUB_ENV"
|
||||
echo "Container tag to push for tools and toolchain is $CONTAINER_TAG"
|
||||
echo "container-tag=$CONTAINER_TAG" >> "$GITHUB_OUTPUT"
|
||||
|
||||
build-linux-buildbot:
|
||||
name: Build tools with buildbot container
|
||||
if: ${{ github.repository_owner == 'openwrt' }}
|
||||
uses: ./.github/workflows/build-tools.yml
|
||||
with:
|
||||
generate_prebuilt_artifacts: true
|
||||
|
||||
push-tools-container:
|
||||
needs: [ determine-container-info, build-linux-buildbot ]
|
||||
if: ${{ github.repository_owner == 'openwrt' }}
|
||||
name: Push prebuilt tools container
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
|
@ -92,5 +110,110 @@ jobs:
|
|||
with:
|
||||
context: openwrt
|
||||
push: true
|
||||
tags: ghcr.io/${{ env.OWNER_LC }}/tools:${{ env.CONTAINER_TAG }}
|
||||
tags: ghcr.io/${{ needs.determine-container-info.outputs.owner-lc }}/tools:${{ needs.determine-container-info.outputs.container-tag }}
|
||||
file: openwrt/.github/workflows/Dockerfile.tools
|
||||
|
||||
determine-targets:
|
||||
name: Set targets
|
||||
if: ${{ github.repository_owner == 'openwrt' }}
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
target: ${{ steps.find_targets.outputs.target }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Set targets
|
||||
id: find_targets
|
||||
run: |
|
||||
export TARGETS="$(perl ./scripts/dump-target-info.pl targets 2>/dev/null \
|
||||
| awk '{ print $1 }')"
|
||||
|
||||
JSON='['
|
||||
FIRST=1
|
||||
for TARGET in $TARGETS; do
|
||||
TUPLE='{"target":"'"$(echo $TARGET | cut -d "/" -f 1)"'","subtarget":"'"$(echo $TARGET | cut -d "/" -f 2)"'"}'
|
||||
[[ $FIRST -ne 1 ]] && JSON="$JSON"','
|
||||
JSON="$JSON""$TUPLE"
|
||||
FIRST=0
|
||||
done
|
||||
JSON="$JSON"']'
|
||||
|
||||
echo -e "\n---- targets ----\n"
|
||||
echo "$JSON"
|
||||
echo -e "\n---- targets ----\n"
|
||||
|
||||
echo "target=$JSON" >> $GITHUB_OUTPUT
|
||||
|
||||
build:
|
||||
name: Build Target Toolchain
|
||||
if: ${{ github.repository_owner == 'openwrt' }}
|
||||
needs: [ determine-targets, push-tools-container ]
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
strategy:
|
||||
fail-fast: False
|
||||
matrix:
|
||||
include: ${{fromJson(needs.determine-targets.outputs.target)}}
|
||||
uses: ./.github/workflows/build.yml
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
subtarget: ${{ matrix.subtarget }}
|
||||
build_toolchain: true
|
||||
build_external_toolchain: true
|
||||
upload_external_toolchain: true
|
||||
|
||||
push-toolchain-container:
|
||||
name: Push Target Toolchain container
|
||||
if: ${{ github.repository_owner == 'openwrt' }}
|
||||
needs: [ determine-container-info, determine-targets, build ]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: False
|
||||
matrix:
|
||||
include: ${{fromJson(needs.determine-targets.outputs.target)}}
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: 'openwrt'
|
||||
|
||||
- name: Download external toolchain from build job
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.target }}-${{ matrix.subtarget }}-external-toolchain
|
||||
path: openwrt
|
||||
|
||||
- name: Find external toolchain name
|
||||
id: get-toolchain-name
|
||||
working-directory: openwrt
|
||||
run: |
|
||||
TOOLCHAIN_NAME=$(ls | grep toolchain-${{ matrix.target }}-${{ matrix.subtarget }})
|
||||
echo "toolchain-name=$TOOLCHAIN_NAME" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
context: openwrt
|
||||
push: true
|
||||
tags: ghcr.io/${{ needs.determine-container-info.outputs.owner-lc }}/toolchain:${{ matrix.target }}-${{ matrix.subtarget }}-${{ needs.determine-container-info.outputs.container-tag }}
|
||||
file: openwrt/.github/workflows/Dockerfile.toolchain
|
||||
build-args: |
|
||||
OWNER_LC=${{ needs.determine-container-info.outputs.owner-lc }}
|
||||
CONTAINER_TAG=${{ needs.determine-container-info.outputs.container-tag }}
|
||||
TOOLCHAIN_NAME=${{ steps.get-toolchain-name.outputs.toolchain-name }}
|
||||
|
|
2
.github/workflows/toolchain.yml
vendored
2
.github/workflows/toolchain.yml
vendored
|
@ -11,6 +11,8 @@ on:
|
|||
- '.github/workflows/build.yml'
|
||||
- '.github/workflows/toolchain.yml'
|
||||
- 'toolchain/**'
|
||||
branches-ignore:
|
||||
- master
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
|
4
.github/workflows/tools.yml
vendored
4
.github/workflows/tools.yml
vendored
|
@ -3,14 +3,18 @@ name: Build host tools
|
|||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'include/**'
|
||||
- 'tools/**'
|
||||
- '.github/workflows/build-tools.yml'
|
||||
- '.github/workflows/tools.yml'
|
||||
push:
|
||||
paths:
|
||||
- 'include/**'
|
||||
- 'tools/**'
|
||||
- '.github/workflows/build-tools.yml'
|
||||
- '.github/workflows/tools.yml'
|
||||
branches-ignore:
|
||||
- master
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
|
|
@ -113,7 +113,7 @@ define SetupHostCommand
|
|||
;; \
|
||||
esac; \
|
||||
ln -sf "$$$$$$$$bin" "$(STAGING_DIR_HOST)/bin/$(strip $(1))"; \
|
||||
exit 1; \
|
||||
exit 0; \
|
||||
fi; \
|
||||
fi; \
|
||||
done; \
|
||||
|
|
|
@ -11,7 +11,7 @@ include $(INCLUDE_DIR)/kernel.mk
|
|||
PKG_NAME:=mac80211
|
||||
|
||||
PKG_VERSION:=6.1.24
|
||||
PKG_RELEASE:=3
|
||||
PKG_RELEASE:=4
|
||||
# PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/
|
||||
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources/
|
||||
PKG_HASH:=5d39aca7e34c33cb9b3e366117b2e86841b7bdd37933679d6b1e61be6b150648
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
From 986e43b19ae9176093da35e0a844e65c8bf9ede7 Mon Sep 17 00:00:00 2001
|
||||
From: Felix Fietkau <nbd@nbd.name>
|
||||
Date: Tue, 6 Dec 2022 11:15:02 +0100
|
||||
Date: Mon, 13 Feb 2023 11:08:54 +0100
|
||||
Subject: [PATCH] wifi: mac80211: fix receiving A-MSDU frames on mesh
|
||||
interfaces
|
||||
|
||||
|
@ -33,7 +34,15 @@ For locally received packets, the Mesh Control header is stripped away.
|
|||
For forwarded packets, a new 802.11 header gets added.
|
||||
|
||||
Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
||||
Link: https://lore.kernel.org/r/20230213100855.34315-4-nbd@nbd.name
|
||||
[fix fortify build error]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
.../wireless/marvell/mwifiex/11n_rxreorder.c | 2 +-
|
||||
include/net/cfg80211.h | 27 +-
|
||||
net/mac80211/rx.c | 350 ++++++++++--------
|
||||
net/wireless/util.c | 120 +++---
|
||||
4 files changed, 297 insertions(+), 202 deletions(-)
|
||||
|
||||
--- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
|
||||
+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c
|
||||
|
@ -557,7 +566,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
|
|||
+ memcpy(&payload.eth.h_source, mesh_addr, ETH_ALEN);
|
||||
+ break;
|
||||
+ case MESH_FLAGS_AE_A5_A6:
|
||||
+ memcpy(&payload.eth.h_dest, mesh_addr, 2 * ETH_ALEN);
|
||||
+ memcpy(&payload.eth, mesh_addr, 2 * ETH_ALEN);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=qca-ssdk
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE_URL:=https://git.codelinaro.org/clo/qsdk/oss/lklm/qca-ssdk.git
|
||||
PKG_SOURCE_PROTO:=git
|
||||
|
@ -37,6 +37,8 @@ else
|
|||
TOOLCHAIN_BIN_PATH=$(TOOLCHAIN_DIR)/bin
|
||||
endif
|
||||
|
||||
LNX_CONFIG_OPTS = LNX_MAKEOPTS='$(KERNEL_MAKEOPTS)' MODULE_TYPE=KSLIB modules
|
||||
|
||||
MAKE_FLAGS+= \
|
||||
TARGET_NAME=$(CONFIG_TARGET_NAME) \
|
||||
TOOL_PATH=$(TOOLCHAIN_BIN_PATH) \
|
||||
|
@ -47,7 +49,7 @@ MAKE_FLAGS+= \
|
|||
TARGET_SUFFIX=$(CONFIG_TARGET_SUFFIX) \
|
||||
GCC_VERSION=$(GCC_VERSION) \
|
||||
EXTRA_CFLAGS=-fno-stack-protector -I$(STAGING_DIR)/usr/include \
|
||||
$(KERNEL_MAKE_FLAGS)
|
||||
$(LNX_CONFIG_OPTS)
|
||||
|
||||
ifeq ($(CONFIG_TARGET_BOARD), "ipq807x")
|
||||
MAKE_FLAGS+= CHIP_TYPE=HPPE PTP_FEATURE=disable SWCONFIG_FEATURE=disable
|
||||
|
|
|
@ -0,0 +1,286 @@
|
|||
From edd3d4347cc73a99c7cf59aceeb1e8ad4d4dd303 Mon Sep 17 00:00:00 2001
|
||||
From: crao <quic_crao@quicinc.com>
|
||||
Date: Tue, 15 Nov 2022 18:50:01 +0800
|
||||
Subject: [PATCH] [qca-ssdk]: Support Linux-Style Makefile for SSDK
|
||||
|
||||
Change-Id: I8c4399433b6422ef6192f70bf08b0d3023cc94b6
|
||||
Signed-off-by: crao <quic_crao@quicinc.com>
|
||||
---
|
||||
Makefile | 15 +++++++++++++
|
||||
Makefile.modules | 16 ++++++++++++++
|
||||
make/defs.mk | 1 +
|
||||
make/linux_opt.mk | 54 ++++++++++++++++++++++++++++-------------------
|
||||
make/target.mk | 12 +++++++++++
|
||||
src/api/Makefile | 2 +-
|
||||
6 files changed, 77 insertions(+), 23 deletions(-)
|
||||
mode change 100755 => 100644 Makefile
|
||||
create mode 100644 Makefile.modules
|
||||
mode change 100755 => 100644 make/defs.mk
|
||||
mode change 100755 => 100644 make/linux_opt.mk
|
||||
mode change 100755 => 100644 make/target.mk
|
||||
mode change 100755 => 100644 src/api/Makefile
|
||||
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -12,6 +12,9 @@ include ./make/$(OS)_opt.mk
|
||||
SUB_DIR=$(patsubst %/, %, $(dir $(wildcard src/*/Makefile)))
|
||||
SUB_LIB=$(subst src/, , $(SUB_DIR))
|
||||
|
||||
+####################################################################
|
||||
+# SSDK-Style Makefile
|
||||
+####################################################################
|
||||
all: $(BIN_DIR) kslib
|
||||
mkdir -p ./temp/;cd ./temp;cp ../build/bin/ssdk_ks_km.a ./;ar -x ssdk_ks_km.a; cp ../ko_Makefile ./Makefile;
|
||||
make -C $(SYS_PATH) M=$(PRJ_PATH)/temp/ CROSS_COMPILE=$(TOOLPREFIX) modules
|
||||
@@ -20,6 +23,18 @@ all: $(BIN_DIR) kslib
|
||||
rm -Rf ./temp/*.o ./temp/*.ko ./temp/*.a
|
||||
@echo "---Build [SSDK-$(VERSION)] at $(BUILD_DATE) finished."
|
||||
|
||||
+####################################################################
|
||||
+# LNX Modules-Style Makefile
|
||||
+####################################################################
|
||||
+modules: $(BIN_DIR) kslib_c
|
||||
+ cp Makefile.modules ./Makefile;
|
||||
+ make -C $(SYS_PATH) M=$(PRJ_PATH)/ $(LNX_MAKEOPTS) modules
|
||||
+ cp *.ko build/bin;
|
||||
+ @echo "---Build [SSDK-$(VERSION)] at $(BUILD_DATE) finished."
|
||||
+
|
||||
+kslib_c:
|
||||
+ $(foreach i, $(SUB_LIB), $(MAKE) MODULE_TYPE=KSLIB -C src/$i src_list_loop || exit 1;)
|
||||
+
|
||||
kslib:kslib_o
|
||||
$(AR) -r $(BIN_DIR)/$(KS_MOD)_$(RUNMODE).a $(wildcard $(BLD_DIR)/KSLIB/*.o)
|
||||
|
||||
--- /dev/null
|
||||
+++ b/Makefile.modules
|
||||
@@ -0,0 +1,16 @@
|
||||
+####################################################################
|
||||
+# Add All Local Flags
|
||||
+####################################################################
|
||||
+ccflags-y += $(LNX_LOCAL_CFLAGS) -Wno-error
|
||||
+
|
||||
+####################################################################
|
||||
+# Build Object List
|
||||
+####################################################################
|
||||
+SRC_LIST := $(shell cat $(PRJ_PATH)/src_list.dep)
|
||||
+OBJ_LIST := $(patsubst %.c,%.o,$(SRC_LIST))
|
||||
+
|
||||
+####################################################################
|
||||
+# Linux Kernel Module
|
||||
+####################################################################
|
||||
+obj-m := qca-ssdk.o
|
||||
+qca-ssdk-objs := $(OBJ_LIST)
|
||||
--- a/make/defs.mk
|
||||
+++ b/make/defs.mk
|
||||
@@ -7,6 +7,7 @@ ifeq (,$(findstring $(LIB), $(COMPONENTS
|
||||
endif
|
||||
|
||||
SRC_FILE=$(addprefix $(PRJ_PATH)/$(LOC_DIR)/, $(SRC_LIST))
|
||||
+LOC_SRC_FILE=$(addprefix $(LOC_DIR)/, $(SRC_LIST))
|
||||
|
||||
OBJ_LIST=$(SRC_LIST:.c=.o)
|
||||
OBJ_FILE=$(addprefix $(DST_DIR)/, $(OBJ_LIST))
|
||||
--- a/make/linux_opt.mk
|
||||
+++ b/make/linux_opt.mk
|
||||
@@ -295,7 +295,7 @@ ifeq (TRUE, $(DEBUG_ON))
|
||||
MODULE_CFLAG += -g
|
||||
endif
|
||||
|
||||
-MODULE_CFLAG += $(OPT_FLAG) -Wall -DVERSION=\"$(VERSION)\" -DBUILD_DATE=\"$(BUILD_DATE)\" -DOS=\"$(OS)\" -D"KBUILD_STR(s)=\#s" -D"KBUILD_MODNAME=KBUILD_STR(qca-ssdk)"
|
||||
+MODULE_CFLAG += $(OPT_FLAG) -Wall -DVERSION=\"$(VERSION)\" -DBUILD_DATE=\"$(BUILD_DATE)\" -DOS=\"$(OS)\" -D"KBUILD_STR(s)=\#s"
|
||||
|
||||
MODULE_INC += -I$(PRJ_PATH)/include \
|
||||
-I$(PRJ_PATH)/include/common \
|
||||
@@ -450,7 +450,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
MODULE_CFLAG += -DKVER34
|
||||
MODULE_CFLAG += -DKVER32
|
||||
MODULE_CFLAG += -DLNX26_22
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \
|
||||
-I$(SYS_PATH)/include \
|
||||
-I$(SYS_PATH)/source/include \
|
||||
@@ -473,7 +473,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
MODULE_CFLAG += -DKVER32
|
||||
MODULE_CFLAG += -DLNX26_22
|
||||
ifeq ($(ARCH), arm64)
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \
|
||||
-I$(SYS_PATH)/include \
|
||||
-I$(SYS_PATH)/source \
|
||||
@@ -492,13 +492,13 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
-I$(SYS_PATH)/source/include/uapi
|
||||
|
||||
ifneq ($(wildcard $(SYS_PATH)/include/linux/kconfig.h),)
|
||||
- MODULE_INC += -include $(SYS_PATH)/include/linux/kconfig.h
|
||||
+ SYS_INC += -include $(SYS_PATH)/include/linux/kconfig.h
|
||||
else
|
||||
- MODULE_INC += -include $(KERNEL_SRC)/include/linux/kconfig.h
|
||||
+ SYS_INC += -include $(KERNEL_SRC)/include/linux/kconfig.h
|
||||
endif
|
||||
|
||||
else ifeq ($(ARCH), arm)
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \
|
||||
-I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/7.5.0/include/ \
|
||||
-I$(TOOL_PATH)/../../lib/armv7a-vfp-neon-rdk-linux-gnueabi/gcc/arm-rdk-linux-gnueabi/4.8.4/include/ \
|
||||
@@ -522,13 +522,13 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
-I$(TOOL_PATH)/../../lib/arm-rdk-linux-gnueabi/gcc/arm-rdk-linux-gnueabi/9.3.0/include/
|
||||
|
||||
ifneq ($(wildcard $(SYS_PATH)/include/linux/kconfig.h),)
|
||||
- MODULE_INC += -include $(SYS_PATH)/include/linux/kconfig.h
|
||||
+ SYS_INC += -include $(SYS_PATH)/include/linux/kconfig.h
|
||||
else
|
||||
- MODULE_INC += -include $(KERNEL_SRC)/include/linux/kconfig.h
|
||||
+ SYS_INC += -include $(KERNEL_SRC)/include/linux/kconfig.h
|
||||
endif
|
||||
|
||||
else
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \
|
||||
-I$(SYS_PATH)/include \
|
||||
-I$(SYS_PATH)/source \
|
||||
@@ -564,7 +564,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
MODULE_CFLAG += -DLNX26_22
|
||||
ifeq ($(ARCH), arm64)
|
||||
KCONF_FILE = $(SYS_PATH)/source/include/linux/kconfig.h
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \
|
||||
-I$(SYS_PATH)/include \
|
||||
-I$(SYS_PATH)/source/include \
|
||||
@@ -581,7 +581,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
-I$(SYS_PATH)/source/arch/arm64/include/asm/mach \
|
||||
-include $(KCONF_FILE)
|
||||
else ifeq ($(ARCH), arm)
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \
|
||||
-I$(TOOL_PATH)/../../lib/armv7a-vfp-neon-rdk-linux-gnueabi/gcc/arm-rdk-linux-gnueabi/4.8.4/include/ \
|
||||
-I$(SYS_PATH)/include \
|
||||
@@ -604,7 +604,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
MODULE_CFLAG += -DKVER34
|
||||
MODULE_CFLAG += -DKVER32
|
||||
MODULE_CFLAG += -DLNX26_22
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(TOOL_PATH)/../lib/gcc/$(TARGET_NAME)/$(GCC_VERSION)/include/ \
|
||||
-I$(TOOL_PATH)/../../lib/arm-poky-linux-gnueabi/gcc/arm-poky-linux-gnueabi/5.3.0/include/ \
|
||||
-I$(TOOL_PATH)/../../lib/armv7a-vfp-neon-rdk-linux-gnueabi/gcc/arm-rdk-linux-gnueabi/4.8.4/include/ \
|
||||
@@ -627,10 +627,10 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
-I$(EXT_PATH) \
|
||||
-I$(SYS_PATH)/source/arch/arm/include/asm/mach
|
||||
ifneq ($(wildcard $(SYS_PATH)/include/linux/kconfig.h),)
|
||||
- MODULE_INC += \
|
||||
+ SYS_INC += \
|
||||
-include $(SYS_PATH)/include/linux/kconfig.h
|
||||
else
|
||||
- MODULE_INC += \
|
||||
+ SYS_INC += \
|
||||
-include $(SYS_PATH)/source/include/linux/kconfig.h
|
||||
endif
|
||||
|
||||
@@ -641,7 +641,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
MODULE_CFLAG += -DKVER32
|
||||
MODULE_CFLAG += -DLNX26_22
|
||||
MODULE_CFLAG += -Werror
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(SYS_PATH)/include \
|
||||
-I$(SYS_PATH)/source/include \
|
||||
-I$(SYS_PATH)/source/arch/arm/mach-msm/include \
|
||||
@@ -657,7 +657,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
MODULE_CFLAG += -DKVER32
|
||||
MODULE_CFLAG += -DLNX26_22
|
||||
ifeq (mips, $(CPU))
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(SYS_PATH)/include \
|
||||
-I$(SYS_PATH)/arch/mips/include \
|
||||
-I$(SYS_PATH)/arch/mips/include/asm/mach-ar7240 \
|
||||
@@ -678,7 +678,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
-O2 -fno-pic -pipe -mabi=32 -march=mips32r2 -DMODULE -mlong-calls -DEXPORT_SYMTAB
|
||||
endif
|
||||
else
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(SYS_PATH)/include \
|
||||
-I$(SYS_PATH)/arch/arm/include \
|
||||
-I$(SYS_PATH)/arch/arm/include/asm \
|
||||
@@ -695,7 +695,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
MODULE_CFLAG += -DKVER26
|
||||
MODULE_CFLAG += -DLNX26_22
|
||||
ifeq (mips, $(CPU))
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(SYS_PATH)/include \
|
||||
-I$(SYS_PATH)/arch/mips/include \
|
||||
-I$(SYS_PATH)/arch/mips/include/asm/mach-ar7240 \
|
||||
@@ -708,7 +708,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
-O2 -fno-pic -pipe -mabi=32 -march=mips32r2 -DMODULE -mlong-calls -DEXPORT_SYMTAB
|
||||
endif
|
||||
else
|
||||
- MODULE_INC += -I$(SYS_PATH) \
|
||||
+ SYS_INC += -I$(SYS_PATH) \
|
||||
-I$(SYS_PATH)/include \
|
||||
-I$(SYS_PATH)/arch/arm/include \
|
||||
-I$(SYS_PATH)/arch/arm/include/asm \
|
||||
@@ -721,8 +721,7 @@ ifeq (KSLIB, $(MODULE_TYPE))
|
||||
|
||||
endif
|
||||
|
||||
- MODULE_CFLAG += -D__KERNEL__ -DKERNEL_MODULE $(CPU_CFLAG)
|
||||
-
|
||||
+ MODULE_CFLAG += -D__KERNEL__ -DKERNEL_MODULE
|
||||
|
||||
endif
|
||||
|
||||
@@ -748,4 +747,15 @@ ifneq (TRUE, $(KERNEL_MODE))
|
||||
endif
|
||||
endif
|
||||
|
||||
-LOCAL_CFLAGS += $(MODULE_INC) $(MODULE_CFLAG) $(EXTRA_CFLAGS)
|
||||
+LOCAL_CFLAGS += $(MODULE_INC) $(SYS_INC) $(MODULE_CFLAG) $(EXTRA_CFLAGS)
|
||||
+
|
||||
+####################################################################
|
||||
+# cflags for SSDK-Style Makefile
|
||||
+####################################################################
|
||||
+LOCAL_CFLAGS += $(CPU_CFLAG) -D"KBUILD_MODNAME=KBUILD_STR(qca-ssdk)"
|
||||
+
|
||||
+####################################################################
|
||||
+# cflags for LNX Modules-Style Makefile
|
||||
+####################################################################
|
||||
+LNX_LOCAL_CFLAGS += $(MODULE_INC) $(MODULE_CFLAG) ${EXTRA_INC}
|
||||
+export LNX_LOCAL_CFLAGS
|
||||
--- a/make/target.mk
|
||||
+++ b/make/target.mk
|
||||
@@ -3,6 +3,18 @@ include $(PRJ_PATH)/make/$(OS)_opt.mk
|
||||
|
||||
include $(PRJ_PATH)/make/tools.mk
|
||||
|
||||
+####################################################################
|
||||
+# LNX Modules-Style Makefile
|
||||
+####################################################################
|
||||
+src_list_loop: src_list
|
||||
+ $(foreach i, $(SUB_DIR), $(MAKE) -C $(i) src_list_loop || exit 1;)
|
||||
+
|
||||
+src_list:
|
||||
+ echo -n "$(LOC_SRC_FILE) " >> $(PRJ_PATH)/src_list.dep
|
||||
+
|
||||
+####################################################################
|
||||
+# SSDK-Style Makefile
|
||||
+####################################################################
|
||||
obj: $(OBJ_LIST)
|
||||
$(OBJ_LOOP)
|
||||
|
||||
--- a/src/api/Makefile
|
||||
+++ b/src/api/Makefile
|
||||
@@ -1,4 +1,4 @@
|
||||
-LOC_DIR=src/sal
|
||||
+LOC_DIR=src/api
|
||||
LIB=API
|
||||
|
||||
include $(PRJ_PATH)/make/config.mk
|
|
@ -0,0 +1,27 @@
|
|||
From 3026f89b06049df01d5fe19c5fccc972637aa344 Mon Sep 17 00:00:00 2001
|
||||
From: crao <quic_crao@quicinc.com>
|
||||
Date: Tue, 7 Mar 2023 17:15:07 +0800
|
||||
Subject: [PATCH] [qca-ssdk]: fix compilation issue in Linux-Style Makefile
|
||||
|
||||
Change-Id: If38251fc0a2bf4abc666d30f4812c0d9507310dc
|
||||
Signed-off-by: crao <quic_crao@quicinc.com>
|
||||
---
|
||||
Makefile | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
mode change 100644 => 100755 Makefile
|
||||
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -27,9 +27,9 @@ all: $(BIN_DIR) kslib
|
||||
# LNX Modules-Style Makefile
|
||||
####################################################################
|
||||
modules: $(BIN_DIR) kslib_c
|
||||
- cp Makefile.modules ./Makefile;
|
||||
- make -C $(SYS_PATH) M=$(PRJ_PATH)/ $(LNX_MAKEOPTS) modules
|
||||
- cp *.ko build/bin;
|
||||
+ mkdir -p ./temp/;cp * ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile;
|
||||
+ make -C $(SYS_PATH) M=$(PRJ_PATH)/temp $(LNX_MAKEOPTS) modules
|
||||
+ cp temp/*.ko build/bin;
|
||||
@echo "---Build [SSDK-$(VERSION)] at $(BUILD_DATE) finished."
|
||||
|
||||
kslib_c:
|
|
@ -0,0 +1,23 @@
|
|||
From 6e4efd68e6e560a1994bc273fe6f7a72139f3957 Mon Sep 17 00:00:00 2001
|
||||
From: crao <quic_crao@quicinc.com>
|
||||
Date: Wed, 15 Mar 2023 11:19:39 +0800
|
||||
Subject: [PATCH] [qca-ssdk]: fix compilation issue in Miami yocto
|
||||
|
||||
Change-Id: I8526b9e43667d72ae9afa4ef8a13167088d194ba
|
||||
Signed-off-by: crao <quic_crao@quicinc.com>
|
||||
---
|
||||
Makefile | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -29,7 +29,9 @@ all: $(BIN_DIR) kslib
|
||||
modules: $(BIN_DIR) kslib_c
|
||||
mkdir -p ./temp/;cp * ./temp -a;cd ./temp;cp ../Makefile.modules ./Makefile;
|
||||
make -C $(SYS_PATH) M=$(PRJ_PATH)/temp $(LNX_MAKEOPTS) modules
|
||||
+ cp $(PRJ_PATH)/temp/Module.symvers $(PRJ_PATH)/Module.symvers;
|
||||
cp temp/*.ko build/bin;
|
||||
+ rm -Rf ./temp/*.o ./temp/*.ko ./temp/*.a
|
||||
@echo "---Build [SSDK-$(VERSION)] at $(BUILD_DATE) finished."
|
||||
|
||||
kslib_c:
|
|
@ -20,7 +20,7 @@ define KernelPackage/leds-ubnt-ledbar
|
|||
FILES:= \
|
||||
$(PKG_BUILD_DIR)/leds-ubnt-ledbar.ko
|
||||
AUTOLOAD:=$(call AutoProbe,leds-ubnt-ledbar,1)
|
||||
DEPENDS:=+kmod-i2c-core
|
||||
DEPENDS:=@TARGET_mediatek_mt7622||TARGET_ramips_mt7621 +kmod-i2c-core
|
||||
endef
|
||||
|
||||
define KernelPackage/leds-ubnt-ledbar/description
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/version.h>
|
||||
|
||||
/**
|
||||
* Driver for the Ubiquiti RGB LED controller (LEDBAR).
|
||||
|
@ -218,13 +219,19 @@ static int ubnt_ledbar_probe(struct i2c_client *client,
|
|||
return ubnt_ledbar_apply_state(ledbar);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
|
||||
static int ubnt_ledbar_remove(struct i2c_client *client)
|
||||
#else
|
||||
static void ubnt_ledbar_remove(struct i2c_client *client)
|
||||
#endif
|
||||
{
|
||||
struct ubnt_ledbar *ledbar = i2c_get_clientdata(client);
|
||||
|
||||
mutex_destroy(&ledbar->lock);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 0)
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const struct i2c_device_id ubnt_ledbar_id[] = {
|
||||
|
|
75
package/libs/libbpf/Makefile
Normal file
75
package/libs/libbpf/Makefile
Normal file
|
@ -0,0 +1,75 @@
|
|||
#
|
||||
# Copyright (C) 2020-2023 Tony Ambardar <itugrok@yahoo.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=libbpf
|
||||
PKG_VERSION:=1.2.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL:=https://github.com/libbpf/libbpf
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=fbd60dbff51c870f5e80a17c4f2fd639eb80af90
|
||||
PKG_MIRROR_HASH:=80a80dfba71576e017b596fb28068e2a92de629e426f063e4b37314c8d576336
|
||||
PKG_ABI_VERSION:=$(firstword $(subst .,$(space),$(PKG_VERSION)))
|
||||
|
||||
PKG_MAINTAINER:=Tony Ambardar <itugrok@yahoo.com>
|
||||
|
||||
PKG_BUILD_FLAGS:=no-mips16
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_INSTALL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/nls.mk
|
||||
|
||||
define Package/libbpf
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
TITLE:=libbpf - eBPF helper library
|
||||
LICENSE:=LGPL-2.1 OR BSD-2-Clause
|
||||
ABI_VERSION:=$(PKG_ABI_VERSION)
|
||||
URL:=http://www.kernel.org
|
||||
DEPENDS:=+libelf
|
||||
endef
|
||||
|
||||
define Package/libbpf/description
|
||||
libbpf is a library for loading eBPF programs and reading and manipulating eBPF objects from user-space.
|
||||
endef
|
||||
|
||||
MAKE_VARS = \
|
||||
EXTRA_CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS)"
|
||||
|
||||
MAKE_FLAGS += \
|
||||
$(if $(findstring c,$(OPENWRT_VERBOSE)),V=1,V='') \
|
||||
LIBSUBDIR=lib
|
||||
|
||||
MAKE_PATH = src
|
||||
|
||||
define Build/InstallDev/libbpf
|
||||
$(INSTALL_DIR) $(1)/usr/include/bpf
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/include/bpf/*.h $(1)/usr/include/bpf/
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libbpf.{a,so*} \
|
||||
$(1)/usr/lib/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libbpf.pc \
|
||||
$(1)/usr/lib/pkgconfig/
|
||||
$(SED) 's,/usr/include,$$$${prefix}/include,g' \
|
||||
$(1)/usr/lib/pkgconfig/libbpf.pc
|
||||
$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' \
|
||||
$(1)/usr/lib/pkgconfig/libbpf.pc
|
||||
endef
|
||||
|
||||
Build/InstallDev=$(Build/InstallDev/libbpf)
|
||||
|
||||
define Package/libbpf/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libbpf.so.* $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,libbpf))
|
10
package/libs/libbpf/patches/001-cflags.patch
Normal file
10
package/libs/libbpf/patches/001-cflags.patch
Normal file
|
@ -0,0 +1,10 @@
|
|||
--- a/src/Makefile
|
||||
+++ b/src/Makefile
|
||||
@@ -34,6 +34,7 @@ ALL_CFLAGS := $(INCLUDES)
|
||||
|
||||
SHARED_CFLAGS += -fPIC -fvisibility=hidden -DSHARED
|
||||
|
||||
+CFLAGS = $(EXTRA_CFLAGS)
|
||||
CFLAGS ?= -g -O2 -Werror -Wall -std=gnu89
|
||||
ALL_CFLAGS += $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 $(EXTRA_CFLAGS)
|
||||
ALL_LDFLAGS += $(LDFLAGS) $(EXTRA_LDFLAGS)
|
|
@ -1,5 +1,5 @@
|
|||
#
|
||||
# Copyright (C) 2020 Tony Ambardar <itugrok@yahoo.com>
|
||||
# Copyright (C) 2020-2023 Tony Ambardar <itugrok@yahoo.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
|
@ -8,14 +8,13 @@
|
|||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=bpftools
|
||||
PKG_VERSION:=7.2.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL:=https://github.com/libbpf/bpftool
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_DATE:=7.1.0
|
||||
PKG_SOURCE_VERSION:=b01941c8f7890489f09713348a7d89567538504b
|
||||
PKG_MIRROR_HASH:=641fb337342e25ae784a3efe72c71d8c88600a326300d8d5834e26be21547015
|
||||
PKG_ABI_VERSION:=$(call abi_version_str,$(PKG_SOURCE_DATE))
|
||||
PKG_SOURCE_VERSION:=19ff0564980a7429e730f6987a0b0bf418b3c676
|
||||
PKG_MIRROR_HASH:=f9b9871f64986dd2e5dab7060bb919398256ba93964da49c62efaf0e6bc9bbc4
|
||||
|
||||
PKG_MAINTAINER:=Tony Ambardar <itugrok@yahoo.com>
|
||||
|
||||
|
@ -63,27 +62,8 @@ define Package/bpftool-full/description
|
|||
eBPF programs and jited code.
|
||||
endef
|
||||
|
||||
define Package/libbpf
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
TITLE:=libbpf - eBPF helper library
|
||||
VARIANT:=lib
|
||||
LICENSE:=LGPL-2.1 OR BSD-2-Clause
|
||||
ABI_VERSION:=$(PKG_ABI_VERSION)
|
||||
URL:=http://www.kernel.org
|
||||
DEPENDS:=+libelf
|
||||
endef
|
||||
|
||||
define Package/libbpf/description
|
||||
libbpf is a library for loading eBPF programs and reading and manipulating eBPF objects from user-space.
|
||||
endef
|
||||
|
||||
|
||||
# LTO not compatible with DSO using PIC
|
||||
ifneq ($(BUILD_VARIANT),lib)
|
||||
TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto
|
||||
TARGET_LDFLAGS += -Wl,--gc-sections -flto
|
||||
endif
|
||||
|
||||
ifeq ($(BUILD_VARIANT),full)
|
||||
full:=1
|
||||
|
@ -99,7 +79,6 @@ MAKE_FLAGS += \
|
|||
OUTPUT="$(PKG_BUILD_DIR)/" \
|
||||
prefix="/usr" \
|
||||
$(if $(findstring c,$(OPENWRT_VERBOSE)),V=1,V='') \
|
||||
LIBSUBDIR=lib \
|
||||
check_feat=0 \
|
||||
feature-clang-bpf-co-re=0 \
|
||||
feature-libbfd=$(full) \
|
||||
|
@ -108,30 +87,7 @@ MAKE_FLAGS += \
|
|||
feature-disassembler-four-args=1 \
|
||||
feature-disassembler-init-styled=1
|
||||
|
||||
ifeq ($(BUILD_VARIANT),lib)
|
||||
MAKE_PATH = libbpf/src
|
||||
else
|
||||
MAKE_PATH = src
|
||||
endif
|
||||
|
||||
define Build/InstallDev/libbpf
|
||||
$(INSTALL_DIR) $(1)/usr/include/bpf
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/include/bpf/*.h $(1)/usr/include/bpf/
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libbpf.{a,so*} \
|
||||
$(1)/usr/lib/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/pkgconfig
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libbpf.pc \
|
||||
$(1)/usr/lib/pkgconfig/
|
||||
$(SED) 's,/usr/include,$$$${prefix}/include,g' \
|
||||
$(1)/usr/lib/pkgconfig/libbpf.pc
|
||||
$(SED) 's,/usr/lib,$$$${exec_prefix}/lib,g' \
|
||||
$(1)/usr/lib/pkgconfig/libbpf.pc
|
||||
endef
|
||||
|
||||
ifeq ($(BUILD_VARIANT),lib)
|
||||
Build/InstallDev=$(Build/InstallDev/libbpf)
|
||||
endif
|
||||
|
||||
define Package/bpftool-$(BUILD_VARIANT)/install
|
||||
$(INSTALL_DIR) $(1)/usr/libexec
|
||||
|
@ -139,11 +95,5 @@ define Package/bpftool-$(BUILD_VARIANT)/install
|
|||
$(1)/usr/libexec/bpftool-$(BUILD_VARIANT)
|
||||
endef
|
||||
|
||||
define Package/libbpf/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libbpf.so.* $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,libbpf))
|
||||
$(eval $(call BuildPackage,bpftool-full))
|
||||
$(eval $(call BuildPackage,bpftool-minimal))
|
|
@ -23,7 +23,6 @@ CONFIG_ARM64_ERRATUM_832075=y
|
|||
CONFIG_ARM64_ERRATUM_843419=y
|
||||
CONFIG_ARM64_HW_AFDBM=y
|
||||
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
|
||||
CONFIG_ARM64_MODULE_PLTS=y
|
||||
CONFIG_ARM64_PAGE_SHIFT=12
|
||||
CONFIG_ARM64_PAN=y
|
||||
CONFIG_ARM64_PA_BITS=48
|
||||
|
|
|
@ -27,7 +27,6 @@ CONFIG_ARM64_ERRATUM_832075=y
|
|||
CONFIG_ARM64_ERRATUM_843419=y
|
||||
CONFIG_ARM64_HW_AFDBM=y
|
||||
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
|
||||
CONFIG_ARM64_MODULE_PLTS=y
|
||||
CONFIG_ARM64_PAGE_SHIFT=12
|
||||
CONFIG_ARM64_PAN=y
|
||||
CONFIG_ARM64_PA_BITS=48
|
||||
|
|
|
@ -27,7 +27,6 @@ CONFIG_ARM64_ERRATUM_832075=y
|
|||
CONFIG_ARM64_ERRATUM_843419=y
|
||||
CONFIG_ARM64_HW_AFDBM=y
|
||||
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
|
||||
CONFIG_ARM64_MODULE_PLTS=y
|
||||
CONFIG_ARM64_PAGE_SHIFT=12
|
||||
CONFIG_ARM64_PAN=y
|
||||
CONFIG_ARM64_PA_BITS=48
|
||||
|
|
|
@ -25,7 +25,7 @@ Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
|
|||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -17538,6 +17538,14 @@ T: git git://linuxtv.org/media_tree.git
|
||||
@@ -17541,6 +17541,14 @@ T: git git://linuxtv.org/media_tree.git
|
||||
F: Documentation/devicetree/bindings/media/i2c/sony,imx412.yaml
|
||||
F: drivers/media/i2c/imx412.c
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
|
|||
+...
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -17552,6 +17552,7 @@ M: Raspberry Pi Kernel Maintenance <kern
|
||||
@@ -17555,6 +17555,7 @@ M: Raspberry Pi Kernel Maintenance <kern
|
||||
L: linux-media@vger.kernel.org
|
||||
S: Maintained
|
||||
T: git git://linuxtv.org/media_tree.git
|
||||
|
|
|
@ -132,7 +132,7 @@ Signed-off-by: Lee Jackson <info@arducam.com>
|
|||
+...
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -17556,6 +17556,14 @@ F: Documentation/devicetree/bindings/med
|
||||
@@ -17559,6 +17559,14 @@ F: Documentation/devicetree/bindings/med
|
||||
F: Documentation/devicetree/bindings/media/i2c/imx477.yaml
|
||||
F: drivers/media/i2c/imx477.c
|
||||
|
||||
|
|
|
@ -0,0 +1,266 @@
|
|||
From 087ed25eaf5a78a678508e893f80addab9b1c103 Mon Sep 17 00:00:00 2001
|
||||
From: Kalesh Singh <kaleshsingh@google.com>
|
||||
Date: Thu, 13 Apr 2023 14:43:26 -0700
|
||||
Subject: [PATCH] mm: Multi-gen LRU: remove wait_event_killable()
|
||||
|
||||
Android 14 and later default to MGLRU [1] and field telemetry showed
|
||||
occasional long tail latency (>100ms) in the reclaim path.
|
||||
|
||||
Tracing revealed priority inversion in the reclaim path. In
|
||||
try_to_inc_max_seq(), when high priority tasks were blocked on
|
||||
wait_event_killable(), the preemption of the low priority task to call
|
||||
wake_up_all() caused those high priority tasks to wait longer than
|
||||
necessary. In general, this problem is not different from others of its
|
||||
kind, e.g., one caused by mutex_lock(). However, it is specific to MGLRU
|
||||
because it introduced the new wait queue lruvec->mm_state.wait.
|
||||
|
||||
The purpose of this new wait queue is to avoid the thundering herd
|
||||
problem. If many direct reclaimers rush into try_to_inc_max_seq(), only
|
||||
one can succeed, i.e., the one to wake up the rest, and the rest who
|
||||
failed might cause premature OOM kills if they do not wait. So far there
|
||||
is no evidence supporting this scenario, based on how often the wait has
|
||||
been hit. And this begs the question how useful the wait queue is in
|
||||
practice.
|
||||
|
||||
Based on Minchan's recommendation, which is in line with his commit
|
||||
6d4675e60135 ("mm: don't be stuck to rmap lock on reclaim path") and the
|
||||
rest of the MGLRU code which also uses trylock when possible, remove the
|
||||
wait queue.
|
||||
|
||||
[1] https://android-review.googlesource.com/q/I7ed7fbfd6ef9ce10053347528125dd98c39e50bf
|
||||
|
||||
Link: https://lkml.kernel.org/r/20230413214326.2147568-1-kaleshsingh@google.com
|
||||
Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks")
|
||||
Change-Id: I911f3968fd1adb25171279cc5b6f48ccb7efc8de
|
||||
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
|
||||
Suggested-by: Minchan Kim <minchan@kernel.org>
|
||||
Reported-by: Wei Wang <wvw@google.com>
|
||||
Acked-by: Yu Zhao <yuzhao@google.com>
|
||||
Cc: Minchan Kim <minchan@kernel.org>
|
||||
Cc: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
|
||||
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||
Cc: Suleiman Souhlal <suleiman@google.com>
|
||||
Cc: Suren Baghdasaryan <surenb@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
include/linux/mmzone.h | 8 +--
|
||||
mm/vmscan.c | 111 +++++++++++++++--------------------------
|
||||
2 files changed, 42 insertions(+), 77 deletions(-)
|
||||
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -452,18 +452,14 @@ enum {
|
||||
struct lru_gen_mm_state {
|
||||
/* set to max_seq after each iteration */
|
||||
unsigned long seq;
|
||||
- /* where the current iteration continues (inclusive) */
|
||||
+ /* where the current iteration continues after */
|
||||
struct list_head *head;
|
||||
- /* where the last iteration ended (exclusive) */
|
||||
+ /* where the last iteration ended before */
|
||||
struct list_head *tail;
|
||||
- /* to wait for the last page table walker to finish */
|
||||
- struct wait_queue_head wait;
|
||||
/* Bloom filters flip after each iteration */
|
||||
unsigned long *filters[NR_BLOOM_FILTERS];
|
||||
/* the mm stats for debugging */
|
||||
unsigned long stats[NR_HIST_GENS][NR_MM_STATS];
|
||||
- /* the number of concurrent page table walkers */
|
||||
- int nr_walkers;
|
||||
};
|
||||
|
||||
struct lru_gen_mm_walk {
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -2999,18 +2999,13 @@ void lru_gen_del_mm(struct mm_struct *mm
|
||||
if (!lruvec)
|
||||
continue;
|
||||
|
||||
- /* where the last iteration ended (exclusive) */
|
||||
+ /* where the current iteration continues after */
|
||||
+ if (lruvec->mm_state.head == &mm->lru_gen.list)
|
||||
+ lruvec->mm_state.head = lruvec->mm_state.head->prev;
|
||||
+
|
||||
+ /* where the last iteration ended before */
|
||||
if (lruvec->mm_state.tail == &mm->lru_gen.list)
|
||||
lruvec->mm_state.tail = lruvec->mm_state.tail->next;
|
||||
-
|
||||
- /* where the current iteration continues (inclusive) */
|
||||
- if (lruvec->mm_state.head != &mm->lru_gen.list)
|
||||
- continue;
|
||||
-
|
||||
- lruvec->mm_state.head = lruvec->mm_state.head->next;
|
||||
- /* the deletion ends the current iteration */
|
||||
- if (lruvec->mm_state.head == &mm_list->fifo)
|
||||
- WRITE_ONCE(lruvec->mm_state.seq, lruvec->mm_state.seq + 1);
|
||||
}
|
||||
|
||||
list_del_init(&mm->lru_gen.list);
|
||||
@@ -3194,68 +3189,54 @@ static bool iterate_mm_list(struct lruve
|
||||
struct mm_struct **iter)
|
||||
{
|
||||
bool first = false;
|
||||
- bool last = true;
|
||||
+ bool last = false;
|
||||
struct mm_struct *mm = NULL;
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
struct lru_gen_mm_list *mm_list = get_mm_list(memcg);
|
||||
struct lru_gen_mm_state *mm_state = &lruvec->mm_state;
|
||||
|
||||
/*
|
||||
- * There are four interesting cases for this page table walker:
|
||||
- * 1. It tries to start a new iteration of mm_list with a stale max_seq;
|
||||
- * there is nothing left to do.
|
||||
- * 2. It's the first of the current generation, and it needs to reset
|
||||
- * the Bloom filter for the next generation.
|
||||
- * 3. It reaches the end of mm_list, and it needs to increment
|
||||
- * mm_state->seq; the iteration is done.
|
||||
- * 4. It's the last of the current generation, and it needs to reset the
|
||||
- * mm stats counters for the next generation.
|
||||
+ * mm_state->seq is incremented after each iteration of mm_list. There
|
||||
+ * are three interesting cases for this page table walker:
|
||||
+ * 1. It tries to start a new iteration with a stale max_seq: there is
|
||||
+ * nothing left to do.
|
||||
+ * 2. It started the next iteration: it needs to reset the Bloom filter
|
||||
+ * so that a fresh set of PTE tables can be recorded.
|
||||
+ * 3. It ended the current iteration: it needs to reset the mm stats
|
||||
+ * counters and tell its caller to increment max_seq.
|
||||
*/
|
||||
spin_lock(&mm_list->lock);
|
||||
|
||||
VM_WARN_ON_ONCE(mm_state->seq + 1 < walk->max_seq);
|
||||
- VM_WARN_ON_ONCE(*iter && mm_state->seq > walk->max_seq);
|
||||
- VM_WARN_ON_ONCE(*iter && !mm_state->nr_walkers);
|
||||
|
||||
- if (walk->max_seq <= mm_state->seq) {
|
||||
- if (!*iter)
|
||||
- last = false;
|
||||
+ if (walk->max_seq <= mm_state->seq)
|
||||
goto done;
|
||||
- }
|
||||
|
||||
- if (!mm_state->nr_walkers) {
|
||||
- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo);
|
||||
+ if (!mm_state->head)
|
||||
+ mm_state->head = &mm_list->fifo;
|
||||
|
||||
- mm_state->head = mm_list->fifo.next;
|
||||
+ if (mm_state->head == &mm_list->fifo)
|
||||
first = true;
|
||||
- }
|
||||
-
|
||||
- while (!mm && mm_state->head != &mm_list->fifo) {
|
||||
- mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list);
|
||||
|
||||
+ do {
|
||||
mm_state->head = mm_state->head->next;
|
||||
+ if (mm_state->head == &mm_list->fifo) {
|
||||
+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
|
||||
+ last = true;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
/* force scan for those added after the last iteration */
|
||||
- if (!mm_state->tail || mm_state->tail == &mm->lru_gen.list) {
|
||||
- mm_state->tail = mm_state->head;
|
||||
+ if (!mm_state->tail || mm_state->tail == mm_state->head) {
|
||||
+ mm_state->tail = mm_state->head->next;
|
||||
walk->force_scan = true;
|
||||
}
|
||||
|
||||
+ mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list);
|
||||
if (should_skip_mm(mm, walk))
|
||||
mm = NULL;
|
||||
- }
|
||||
-
|
||||
- if (mm_state->head == &mm_list->fifo)
|
||||
- WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
|
||||
+ } while (!mm);
|
||||
done:
|
||||
- if (*iter && !mm)
|
||||
- mm_state->nr_walkers--;
|
||||
- if (!*iter && mm)
|
||||
- mm_state->nr_walkers++;
|
||||
-
|
||||
- if (mm_state->nr_walkers)
|
||||
- last = false;
|
||||
-
|
||||
if (*iter || last)
|
||||
reset_mm_stats(lruvec, walk, last);
|
||||
|
||||
@@ -3283,9 +3264,9 @@ static bool iterate_mm_list_nowalk(struc
|
||||
|
||||
VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq);
|
||||
|
||||
- if (max_seq > mm_state->seq && !mm_state->nr_walkers) {
|
||||
- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo);
|
||||
-
|
||||
+ if (max_seq > mm_state->seq) {
|
||||
+ mm_state->head = NULL;
|
||||
+ mm_state->tail = NULL;
|
||||
WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
|
||||
reset_mm_stats(lruvec, NULL, true);
|
||||
success = true;
|
||||
@@ -3894,10 +3875,6 @@ restart:
|
||||
|
||||
walk_pmd_range(&val, addr, next, args);
|
||||
|
||||
- /* a racy check to curtail the waiting time */
|
||||
- if (wq_has_sleeper(&walk->lruvec->mm_state.wait))
|
||||
- return 1;
|
||||
-
|
||||
if (need_resched() || walk->batched >= MAX_LRU_BATCH) {
|
||||
end = (addr | ~PUD_MASK) + 1;
|
||||
goto done;
|
||||
@@ -3930,8 +3907,14 @@ static void walk_mm(struct lruvec *lruve
|
||||
walk->next_addr = FIRST_USER_ADDRESS;
|
||||
|
||||
do {
|
||||
+ DEFINE_MAX_SEQ(lruvec);
|
||||
+
|
||||
err = -EBUSY;
|
||||
|
||||
+ /* another thread might have called inc_max_seq() */
|
||||
+ if (walk->max_seq != max_seq)
|
||||
+ break;
|
||||
+
|
||||
/* page_update_gen() requires stable page_memcg() */
|
||||
if (!mem_cgroup_trylock_pages(memcg))
|
||||
break;
|
||||
@@ -4164,25 +4147,12 @@ static bool try_to_inc_max_seq(struct lr
|
||||
success = iterate_mm_list(lruvec, walk, &mm);
|
||||
if (mm)
|
||||
walk_mm(lruvec, mm, walk);
|
||||
-
|
||||
- cond_resched();
|
||||
} while (mm);
|
||||
done:
|
||||
- if (!success) {
|
||||
- if (sc->priority <= DEF_PRIORITY - 2)
|
||||
- wait_event_killable(lruvec->mm_state.wait,
|
||||
- max_seq < READ_ONCE(lrugen->max_seq));
|
||||
- return false;
|
||||
- }
|
||||
+ if (success)
|
||||
+ inc_max_seq(lruvec, can_swap, force_scan);
|
||||
|
||||
- VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
|
||||
-
|
||||
- inc_max_seq(lruvec, can_swap, force_scan);
|
||||
- /* either this sees any waiters or they will see updated max_seq */
|
||||
- if (wq_has_sleeper(&lruvec->mm_state.wait))
|
||||
- wake_up_all(&lruvec->mm_state.wait);
|
||||
-
|
||||
- return true;
|
||||
+ return success;
|
||||
}
|
||||
|
||||
static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
|
||||
@@ -5746,7 +5716,6 @@ void lru_gen_init_lruvec(struct lruvec *
|
||||
INIT_LIST_HEAD(&lrugen->pages[gen][type][zone]);
|
||||
|
||||
lruvec->mm_state.seq = MIN_NR_GENS;
|
||||
- init_waitqueue_head(&lruvec->mm_state.wait);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMCG
|
|
@ -0,0 +1,32 @@
|
|||
From b6f56cddb5f57a0b8da0ce582232a2f1933558c6 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:17:19 +0100
|
||||
Subject: [PATCH 04/16] net: dsa: mt7530: make some noise if register read
|
||||
fails
|
||||
|
||||
Simply returning the negative error value instead of the read value
|
||||
doesn't seem like a good idea. Return 0 instead and add WARN_ON_ONCE(1)
|
||||
so this kind of error will not go unnoticed.
|
||||
|
||||
Suggested-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -224,9 +224,10 @@ mt7530_mii_read(struct mt7530_priv *priv
|
||||
/* MT7530 uses 31 as the pseudo port */
|
||||
ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
if (ret < 0) {
|
||||
+ WARN_ON_ONCE(1);
|
||||
dev_err(&bus->dev,
|
||||
"failed to read mt7530 register\n");
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
lo = bus->read(bus, 0x1f, r);
|
|
@ -0,0 +1,111 @@
|
|||
From 9ecc00164dc2300dfcd40afe549a8ee951dfea9f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:17:30 +0100
|
||||
Subject: [PATCH 05/16] net: dsa: mt7530: refactor SGMII PCS creation
|
||||
|
||||
Instead of macro templates use a dedidated function and allocated
|
||||
regmap_config when creating the regmaps for the pcs-mtk-lynxi
|
||||
instances.
|
||||
This is in preparation to switching to use unlocked regmap accessors
|
||||
and have regmap's locking API handle locking for us.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 74 +++++++++++++++++++++++++++-------------
|
||||
1 file changed, 50 insertions(+), 24 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2926,26 +2926,56 @@ static const struct regmap_bus mt7531_re
|
||||
.reg_update_bits = mt7530_regmap_update_bits,
|
||||
};
|
||||
|
||||
-#define MT7531_PCS_REGMAP_CONFIG(_name, _reg_base) \
|
||||
- { \
|
||||
- .name = _name, \
|
||||
- .reg_bits = 16, \
|
||||
- .val_bits = 32, \
|
||||
- .reg_stride = 4, \
|
||||
- .reg_base = _reg_base, \
|
||||
- .max_register = 0x17c, \
|
||||
+static int
|
||||
+mt7531_create_sgmii(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ struct regmap_config *mt7531_pcs_config[2];
|
||||
+ struct phylink_pcs *pcs;
|
||||
+ struct regmap *regmap;
|
||||
+ int i, ret = 0;
|
||||
+
|
||||
+ for (i = 0; i < 2; i++) {
|
||||
+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
|
||||
+ sizeof(struct regmap_config),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!mt7531_pcs_config[i]) {
|
||||
+ ret = -ENOMEM;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
|
||||
+ mt7531_pcs_config[i]->reg_bits = 16;
|
||||
+ mt7531_pcs_config[i]->val_bits = 32;
|
||||
+ mt7531_pcs_config[i]->reg_stride = 4;
|
||||
+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
|
||||
+ mt7531_pcs_config[i]->max_register = 0x17c;
|
||||
+
|
||||
+ regmap = devm_regmap_init(priv->dev,
|
||||
+ &mt7531_regmap_bus, priv,
|
||||
+ mt7531_pcs_config[i]);
|
||||
+ if (IS_ERR(regmap)) {
|
||||
+ ret = PTR_ERR(regmap);
|
||||
+ break;
|
||||
+ }
|
||||
+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
|
||||
+ MT7531_PHYA_CTRL_SIGNAL3, 0);
|
||||
+ if (!pcs) {
|
||||
+ ret = -ENXIO;
|
||||
+ break;
|
||||
+ }
|
||||
+ priv->ports[5 + i].sgmii_pcs = pcs;
|
||||
}
|
||||
|
||||
-static const struct regmap_config mt7531_pcs_config[] = {
|
||||
- MT7531_PCS_REGMAP_CONFIG("port5", MT7531_SGMII_REG_BASE(5)),
|
||||
- MT7531_PCS_REGMAP_CONFIG("port6", MT7531_SGMII_REG_BASE(6)),
|
||||
-};
|
||||
+ if (ret && i)
|
||||
+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
static int
|
||||
mt753x_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- struct regmap *regmap;
|
||||
int i, ret;
|
||||
|
||||
/* Initialise the PCS devices */
|
||||
@@ -2967,15 +2997,11 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
- if (priv->id == ID_MT7531)
|
||||
- for (i = 0; i < 2; i++) {
|
||||
- regmap = devm_regmap_init(ds->dev,
|
||||
- &mt7531_regmap_bus, priv,
|
||||
- &mt7531_pcs_config[i]);
|
||||
- priv->ports[5 + i].sgmii_pcs =
|
||||
- mtk_pcs_lynxi_create(ds->dev, regmap,
|
||||
- MT7531_PHYA_CTRL_SIGNAL3, 0);
|
||||
- }
|
||||
+ if (priv->id == ID_MT7531) {
|
||||
+ ret = mt7531_create_sgmii(priv);
|
||||
+ if (ret && priv->irq)
|
||||
+ mt7530_free_irq_common(priv);
|
||||
+ }
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
From 1bd099c49f65ed923b9f19b8c4b3cd1ff0024091 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:17:40 +0100
|
||||
Subject: [PATCH 06/16] net: dsa: mt7530: use unlocked regmap accessors
|
||||
|
||||
Instead of wrapping the locked register accessor functions, use the
|
||||
unlocked variants and add locking wrapper functions to let regmap
|
||||
handle the locking.
|
||||
|
||||
This is a preparation towards being able to always use regmap to
|
||||
access switch registers instead of open-coded accessor functions.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 23 ++++++++++++++---------
|
||||
1 file changed, 14 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2899,7 +2899,7 @@ static int mt7530_regmap_read(void *cont
|
||||
{
|
||||
struct mt7530_priv *priv = context;
|
||||
|
||||
- *val = mt7530_read(priv, reg);
|
||||
+ *val = mt7530_mii_read(priv, reg);
|
||||
return 0;
|
||||
};
|
||||
|
||||
@@ -2907,23 +2907,25 @@ static int mt7530_regmap_write(void *con
|
||||
{
|
||||
struct mt7530_priv *priv = context;
|
||||
|
||||
- mt7530_write(priv, reg, val);
|
||||
+ mt7530_mii_write(priv, reg, val);
|
||||
return 0;
|
||||
};
|
||||
|
||||
-static int mt7530_regmap_update_bits(void *context, unsigned int reg,
|
||||
- unsigned int mask, unsigned int val)
|
||||
+static void
|
||||
+mt7530_mdio_regmap_lock(void *mdio_lock)
|
||||
{
|
||||
- struct mt7530_priv *priv = context;
|
||||
+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+}
|
||||
|
||||
- mt7530_rmw(priv, reg, mask, val);
|
||||
- return 0;
|
||||
-};
|
||||
+static void
|
||||
+mt7530_mdio_regmap_unlock(void *mdio_lock)
|
||||
+{
|
||||
+ mutex_unlock(mdio_lock);
|
||||
+}
|
||||
|
||||
static const struct regmap_bus mt7531_regmap_bus = {
|
||||
.reg_write = mt7530_regmap_write,
|
||||
.reg_read = mt7530_regmap_read,
|
||||
- .reg_update_bits = mt7530_regmap_update_bits,
|
||||
};
|
||||
|
||||
static int
|
||||
@@ -2949,6 +2951,9 @@ mt7531_create_sgmii(struct mt7530_priv *
|
||||
mt7531_pcs_config[i]->reg_stride = 4;
|
||||
mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
|
||||
mt7531_pcs_config[i]->max_register = 0x17c;
|
||||
+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
|
||||
+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
|
||||
+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
|
||||
regmap = devm_regmap_init(priv->dev,
|
||||
&mt7531_regmap_bus, priv,
|
|
@ -0,0 +1,224 @@
|
|||
From a08c045580e060a6886bbb656c50ae20b0c780b5 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:17:52 +0100
|
||||
Subject: [PATCH 07/16] net: dsa: mt7530: use regmap to access switch register
|
||||
space
|
||||
|
||||
Use regmap API to access the switch register space.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++++----------------
|
||||
drivers/net/dsa/mt7530.h | 2 +
|
||||
2 files changed, 62 insertions(+), 39 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -183,9 +183,9 @@ core_clear(struct mt7530_priv *priv, u32
|
||||
}
|
||||
|
||||
static int
|
||||
-mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
+ struct mii_bus *bus = context;
|
||||
u16 page, r, lo, hi;
|
||||
int ret;
|
||||
|
||||
@@ -197,24 +197,34 @@ mt7530_mii_write(struct mt7530_priv *pri
|
||||
/* MT7530 uses 31 as the pseudo port */
|
||||
ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
if (ret < 0)
|
||||
- goto err;
|
||||
+ return ret;
|
||||
|
||||
ret = bus->write(bus, 0x1f, r, lo);
|
||||
if (ret < 0)
|
||||
- goto err;
|
||||
+ return ret;
|
||||
|
||||
ret = bus->write(bus, 0x1f, 0x10, hi);
|
||||
-err:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
+{
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = regmap_write(priv->regmap, reg, val);
|
||||
+
|
||||
if (ret < 0)
|
||||
- dev_err(&bus->dev,
|
||||
+ dev_err(priv->dev,
|
||||
"failed to write mt7530 register\n");
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static u32
|
||||
-mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
|
||||
+static int
|
||||
+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
+ struct mii_bus *bus = context;
|
||||
u16 page, r, lo, hi;
|
||||
int ret;
|
||||
|
||||
@@ -223,17 +233,32 @@ mt7530_mii_read(struct mt7530_priv *priv
|
||||
|
||||
/* MT7530 uses 31 as the pseudo port */
|
||||
ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
- if (ret < 0) {
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ lo = bus->read(bus, 0x1f, r);
|
||||
+ hi = bus->read(bus, 0x1f, 0x10);
|
||||
+
|
||||
+ *val = (hi << 16) | (lo & 0xffff);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static u32
|
||||
+mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
|
||||
+{
|
||||
+ int ret;
|
||||
+ u32 val;
|
||||
+
|
||||
+ ret = regmap_read(priv->regmap, reg, &val);
|
||||
+ if (ret) {
|
||||
WARN_ON_ONCE(1);
|
||||
- dev_err(&bus->dev,
|
||||
+ dev_err(priv->dev,
|
||||
"failed to read mt7530 register\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
- lo = bus->read(bus, 0x1f, r);
|
||||
- hi = bus->read(bus, 0x1f, 0x10);
|
||||
-
|
||||
- return (hi << 16) | (lo & 0xffff);
|
||||
+ return val;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -283,14 +308,10 @@ mt7530_rmw(struct mt7530_priv *priv, u32
|
||||
u32 mask, u32 set)
|
||||
{
|
||||
struct mii_bus *bus = priv->bus;
|
||||
- u32 val;
|
||||
|
||||
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
|
||||
- val = mt7530_mii_read(priv, reg);
|
||||
- val &= ~mask;
|
||||
- val |= set;
|
||||
- mt7530_mii_write(priv, reg, val);
|
||||
+ regmap_update_bits(priv->regmap, reg, mask, set);
|
||||
|
||||
mutex_unlock(&bus->mdio_lock);
|
||||
}
|
||||
@@ -298,7 +319,7 @@ mt7530_rmw(struct mt7530_priv *priv, u32
|
||||
static void
|
||||
mt7530_set(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
- mt7530_rmw(priv, reg, 0, val);
|
||||
+ mt7530_rmw(priv, reg, val, val);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2895,22 +2916,6 @@ static const struct phylink_pcs_ops mt75
|
||||
.pcs_an_restart = mt7530_pcs_an_restart,
|
||||
};
|
||||
|
||||
-static int mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
-{
|
||||
- struct mt7530_priv *priv = context;
|
||||
-
|
||||
- *val = mt7530_mii_read(priv, reg);
|
||||
- return 0;
|
||||
-};
|
||||
-
|
||||
-static int mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
-{
|
||||
- struct mt7530_priv *priv = context;
|
||||
-
|
||||
- mt7530_mii_write(priv, reg, val);
|
||||
- return 0;
|
||||
-};
|
||||
-
|
||||
static void
|
||||
mt7530_mdio_regmap_lock(void *mdio_lock)
|
||||
{
|
||||
@@ -2923,7 +2928,7 @@ mt7530_mdio_regmap_unlock(void *mdio_loc
|
||||
mutex_unlock(mdio_lock);
|
||||
}
|
||||
|
||||
-static const struct regmap_bus mt7531_regmap_bus = {
|
||||
+static const struct regmap_bus mt7530_regmap_bus = {
|
||||
.reg_write = mt7530_regmap_write,
|
||||
.reg_read = mt7530_regmap_read,
|
||||
};
|
||||
@@ -2956,7 +2961,7 @@ mt7531_create_sgmii(struct mt7530_priv *
|
||||
mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
|
||||
regmap = devm_regmap_init(priv->dev,
|
||||
- &mt7531_regmap_bus, priv,
|
||||
+ &mt7530_regmap_bus, priv->bus,
|
||||
mt7531_pcs_config[i]);
|
||||
if (IS_ERR(regmap)) {
|
||||
ret = PTR_ERR(regmap);
|
||||
@@ -3121,6 +3126,7 @@ MODULE_DEVICE_TABLE(of, mt7530_of_match)
|
||||
static int
|
||||
mt7530_probe(struct mdio_device *mdiodev)
|
||||
{
|
||||
+ static struct regmap_config *regmap_config;
|
||||
struct mt7530_priv *priv;
|
||||
struct device_node *dn;
|
||||
|
||||
@@ -3200,6 +3206,21 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
mutex_init(&priv->reg_mutex);
|
||||
dev_set_drvdata(&mdiodev->dev, priv);
|
||||
|
||||
+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!regmap_config)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ regmap_config->reg_bits = 16;
|
||||
+ regmap_config->val_bits = 32;
|
||||
+ regmap_config->reg_stride = 4;
|
||||
+ regmap_config->max_register = MT7530_CREV;
|
||||
+ regmap_config->disable_locking = true;
|
||||
+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
|
||||
+ priv->bus, regmap_config);
|
||||
+ if (IS_ERR(priv->regmap))
|
||||
+ return PTR_ERR(priv->regmap);
|
||||
+
|
||||
return dsa_register_switch(priv->ds);
|
||||
}
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -747,6 +747,7 @@ struct mt753x_info {
|
||||
* @dev: The device pointer
|
||||
* @ds: The pointer to the dsa core structure
|
||||
* @bus: The bus used for the device and built-in PHY
|
||||
+ * @regmap: The regmap instance representing all switch registers
|
||||
* @rstc: The pointer to reset control used by MCM
|
||||
* @core_pwr: The power supplied into the core
|
||||
* @io_pwr: The power supplied into the I/O
|
||||
@@ -767,6 +768,7 @@ struct mt7530_priv {
|
||||
struct device *dev;
|
||||
struct dsa_switch *ds;
|
||||
struct mii_bus *bus;
|
||||
+ struct regmap *regmap;
|
||||
struct reset_control *rstc;
|
||||
struct regulator *core_pwr;
|
||||
struct regulator *io_pwr;
|
|
@ -0,0 +1,54 @@
|
|||
From 6de2852297737171ba96b91e89bf302ca1fda869 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:18:04 +0100
|
||||
Subject: [PATCH 08/16] net: dsa: mt7530: move SGMII PCS creation to
|
||||
mt7530_probe function
|
||||
|
||||
Move creating the SGMII PCS from mt753x_setup() to the more appropriate
|
||||
mt7530_probe() function.
|
||||
This is done also in preparation of moving all functions related to
|
||||
MDIO-connected MT753x switches to a separate module.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 13 +++++++------
|
||||
1 file changed, 7 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3007,12 +3007,6 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
- if (priv->id == ID_MT7531) {
|
||||
- ret = mt7531_create_sgmii(priv);
|
||||
- if (ret && priv->irq)
|
||||
- mt7530_free_irq_common(priv);
|
||||
- }
|
||||
-
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3129,6 +3123,7 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
static struct regmap_config *regmap_config;
|
||||
struct mt7530_priv *priv;
|
||||
struct device_node *dn;
|
||||
+ int ret;
|
||||
|
||||
dn = mdiodev->dev.of_node;
|
||||
|
||||
@@ -3221,6 +3216,12 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
+ if (priv->id == ID_MT7531) {
|
||||
+ ret = mt7531_create_sgmii(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
return dsa_register_switch(priv->ds);
|
||||
}
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
From 1557c679f71c82a994eae0baadbaeb62b71e15bf Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:18:16 +0100
|
||||
Subject: [PATCH 09/16] net: dsa: mt7530: introduce mutex helpers
|
||||
|
||||
As the MDIO bus lock only needs to be involved if actually operating
|
||||
on an MDIO-connected switch we will need to skip locking for built-in
|
||||
switches which are accessed via MMIO.
|
||||
Create helper functions which simplify that upcoming change.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 73 ++++++++++++++++++++--------------------
|
||||
1 file changed, 36 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -143,31 +143,40 @@ err:
|
||||
}
|
||||
|
||||
static void
|
||||
-core_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
+mt7530_mutex_lock(struct mt7530_priv *priv)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+}
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+static void
|
||||
+mt7530_mutex_unlock(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ mutex_unlock(&priv->bus->mdio_lock);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+core_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
+{
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
static void
|
||||
core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
u32 val;
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
|
||||
val &= ~mask;
|
||||
val |= set;
|
||||
core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -264,13 +273,11 @@ mt7530_mii_read(struct mt7530_priv *priv
|
||||
static void
|
||||
mt7530_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
-
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
mt7530_mii_write(priv, reg, val);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
static u32
|
||||
@@ -282,14 +289,13 @@ _mt7530_unlocked_read(struct mt7530_dumm
|
||||
static u32
|
||||
_mt7530_read(struct mt7530_dummy_poll *p)
|
||||
{
|
||||
- struct mii_bus *bus = p->priv->bus;
|
||||
u32 val;
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(p->priv);
|
||||
|
||||
val = mt7530_mii_read(p->priv, p->reg);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(p->priv);
|
||||
|
||||
return val;
|
||||
}
|
||||
@@ -307,13 +313,11 @@ static void
|
||||
mt7530_rmw(struct mt7530_priv *priv, u32 reg,
|
||||
u32 mask, u32 set)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
-
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
regmap_update_bits(priv->regmap, reg, mask, set);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -645,14 +649,13 @@ static int
|
||||
mt7531_ind_c45_phy_read(struct mt7530_priv *priv, int port, int devad,
|
||||
int regnum)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
struct mt7530_dummy_poll p;
|
||||
u32 reg, val;
|
||||
int ret;
|
||||
|
||||
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -685,7 +688,7 @@ mt7531_ind_c45_phy_read(struct mt7530_pr
|
||||
|
||||
ret = val & MT7531_MDIO_RW_DATA_MASK;
|
||||
out:
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -694,14 +697,13 @@ static int
|
||||
mt7531_ind_c45_phy_write(struct mt7530_priv *priv, int port, int devad,
|
||||
int regnum, u32 data)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
struct mt7530_dummy_poll p;
|
||||
u32 val, reg;
|
||||
int ret;
|
||||
|
||||
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -733,7 +735,7 @@ mt7531_ind_c45_phy_write(struct mt7530_p
|
||||
}
|
||||
|
||||
out:
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -741,14 +743,13 @@ out:
|
||||
static int
|
||||
mt7531_ind_c22_phy_read(struct mt7530_priv *priv, int port, int regnum)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
struct mt7530_dummy_poll p;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, val,
|
||||
!(val & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -771,7 +772,7 @@ mt7531_ind_c22_phy_read(struct mt7530_pr
|
||||
|
||||
ret = val & MT7531_MDIO_RW_DATA_MASK;
|
||||
out:
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -780,14 +781,13 @@ static int
|
||||
mt7531_ind_c22_phy_write(struct mt7530_priv *priv, int port, int regnum,
|
||||
u16 data)
|
||||
{
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
struct mt7530_dummy_poll p;
|
||||
int ret;
|
||||
u32 reg;
|
||||
|
||||
INIT_MT7530_DUMMY_POLL(&p, priv, MT7531_PHY_IAC);
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
ret = readx_poll_timeout(_mt7530_unlocked_read, &p, reg,
|
||||
!(reg & MT7531_PHY_ACS_ST), 20, 100000);
|
||||
@@ -809,7 +809,7 @@ mt7531_ind_c22_phy_write(struct mt7530_p
|
||||
}
|
||||
|
||||
out:
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1109,7 +1109,6 @@ static int
|
||||
mt7530_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
- struct mii_bus *bus = priv->bus;
|
||||
int length;
|
||||
u32 val;
|
||||
|
||||
@@ -1120,7 +1119,7 @@ mt7530_port_change_mtu(struct dsa_switch
|
||||
if (!dsa_is_cpu_port(ds, port))
|
||||
return 0;
|
||||
|
||||
- mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
|
||||
val = mt7530_mii_read(priv, MT7530_GMACCR);
|
||||
val &= ~MAX_RX_PKT_LEN_MASK;
|
||||
@@ -1141,7 +1140,7 @@ mt7530_port_change_mtu(struct dsa_switch
|
||||
|
||||
mt7530_mii_write(priv, MT7530_GMACCR, val);
|
||||
|
||||
- mutex_unlock(&bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1937,10 +1936,10 @@ mt7530_irq_thread_fn(int irq, void *dev_
|
||||
u32 val;
|
||||
int p;
|
||||
|
||||
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
val = mt7530_mii_read(priv, MT7530_SYS_INT_STS);
|
||||
mt7530_mii_write(priv, MT7530_SYS_INT_STS, val);
|
||||
- mutex_unlock(&priv->bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
|
||||
for (p = 0; p < MT7530_NUM_PHYS; p++) {
|
||||
if (BIT(p) & val) {
|
||||
@@ -1976,7 +1975,7 @@ mt7530_irq_bus_lock(struct irq_data *d)
|
||||
{
|
||||
struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
|
||||
|
||||
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ mt7530_mutex_lock(priv);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1985,7 +1984,7 @@ mt7530_irq_bus_sync_unlock(struct irq_da
|
||||
struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
|
||||
|
||||
mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
|
||||
- mutex_unlock(&priv->bus->mdio_lock);
|
||||
+ mt7530_mutex_unlock(priv);
|
||||
}
|
||||
|
||||
static struct irq_chip mt7530_irq_chip = {
|
|
@ -0,0 +1,75 @@
|
|||
From 25d15dee34a1a40d5fd71636a205e3211f09fd1d Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:18:28 +0100
|
||||
Subject: [PATCH 10/16] net: dsa: mt7530: move p5_intf_modes() function to
|
||||
mt7530.c
|
||||
|
||||
In preparation of splitting mt7530.c into a driver for MDIO-connected
|
||||
as well as MDIO-accessed built-in switches on one hand and MMIO-accessed
|
||||
built-in switches move the p5_inft_modes() function from mt7530.h to
|
||||
mt7530.c. The function is only needed there and will trigger a compiler
|
||||
warning about a defined but unused function otherwise when including
|
||||
mt7530.h in the to-be-introduced bus-specific drivers.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 18 ++++++++++++++++++
|
||||
drivers/net/dsa/mt7530.h | 18 ------------------
|
||||
2 files changed, 18 insertions(+), 18 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -950,6 +950,24 @@ mt7530_set_ageing_time(struct dsa_switch
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static const char *p5_intf_modes(unsigned int p5_interface)
|
||||
+{
|
||||
+ switch (p5_interface) {
|
||||
+ case P5_DISABLED:
|
||||
+ return "DISABLED";
|
||||
+ case P5_INTF_SEL_PHY_P0:
|
||||
+ return "PHY P0";
|
||||
+ case P5_INTF_SEL_PHY_P4:
|
||||
+ return "PHY P4";
|
||||
+ case P5_INTF_SEL_GMAC5:
|
||||
+ return "GMAC5";
|
||||
+ case P5_INTF_SEL_GMAC5_SGMII:
|
||||
+ return "GMAC5_SGMII";
|
||||
+ default:
|
||||
+ return "unknown";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void mt7530_setup_port5(struct dsa_switch *ds, phy_interface_t interface)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -682,24 +682,6 @@ enum p5_interface_select {
|
||||
P5_INTF_SEL_GMAC5_SGMII,
|
||||
};
|
||||
|
||||
-static const char *p5_intf_modes(unsigned int p5_interface)
|
||||
-{
|
||||
- switch (p5_interface) {
|
||||
- case P5_DISABLED:
|
||||
- return "DISABLED";
|
||||
- case P5_INTF_SEL_PHY_P0:
|
||||
- return "PHY P0";
|
||||
- case P5_INTF_SEL_PHY_P4:
|
||||
- return "PHY P4";
|
||||
- case P5_INTF_SEL_GMAC5:
|
||||
- return "GMAC5";
|
||||
- case P5_INTF_SEL_GMAC5_SGMII:
|
||||
- return "GMAC5_SGMII";
|
||||
- default:
|
||||
- return "unknown";
|
||||
- }
|
||||
-}
|
||||
-
|
||||
struct mt7530_priv;
|
||||
|
||||
struct mt753x_pcs {
|
|
@ -0,0 +1,155 @@
|
|||
From 37c9c0d8d0b2e24f8c9af72ecd4edd31537284d3 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:18:39 +0100
|
||||
Subject: [PATCH 11/16] net: dsa: mt7530: introduce mt7530_probe_common helper
|
||||
function
|
||||
|
||||
Move commonly used parts from mt7530_probe into new mt7530_probe_common
|
||||
helper function which will be used by both, mt7530_probe and the
|
||||
to-be-introduced mt7988_probe.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 98 ++++++++++++++++++++++------------------
|
||||
1 file changed, 54 insertions(+), 44 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3135,44 +3135,21 @@ static const struct of_device_id mt7530_
|
||||
MODULE_DEVICE_TABLE(of, mt7530_of_match);
|
||||
|
||||
static int
|
||||
-mt7530_probe(struct mdio_device *mdiodev)
|
||||
+mt7530_probe_common(struct mt7530_priv *priv)
|
||||
{
|
||||
- static struct regmap_config *regmap_config;
|
||||
- struct mt7530_priv *priv;
|
||||
- struct device_node *dn;
|
||||
- int ret;
|
||||
+ struct device *dev = priv->dev;
|
||||
|
||||
- dn = mdiodev->dev.of_node;
|
||||
-
|
||||
- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
- if (!priv)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- priv->ds = devm_kzalloc(&mdiodev->dev, sizeof(*priv->ds), GFP_KERNEL);
|
||||
+ priv->ds = devm_kzalloc(dev, sizeof(*priv->ds), GFP_KERNEL);
|
||||
if (!priv->ds)
|
||||
return -ENOMEM;
|
||||
|
||||
- priv->ds->dev = &mdiodev->dev;
|
||||
+ priv->ds->dev = dev;
|
||||
priv->ds->num_ports = MT7530_NUM_PORTS;
|
||||
|
||||
- /* Use medatek,mcm property to distinguish hardware type that would
|
||||
- * casues a little bit differences on power-on sequence.
|
||||
- */
|
||||
- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
|
||||
- if (priv->mcm) {
|
||||
- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
|
||||
-
|
||||
- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
|
||||
- if (IS_ERR(priv->rstc)) {
|
||||
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
- return PTR_ERR(priv->rstc);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
/* Get the hardware identifier from the devicetree node.
|
||||
* We will need it for some of the clock and regulator setup.
|
||||
*/
|
||||
- priv->info = of_device_get_match_data(&mdiodev->dev);
|
||||
+ priv->info = of_device_get_match_data(dev);
|
||||
if (!priv->info)
|
||||
return -EINVAL;
|
||||
|
||||
@@ -3186,23 +3163,53 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
return -EINVAL;
|
||||
|
||||
priv->id = priv->info->id;
|
||||
+ priv->dev = dev;
|
||||
+ priv->ds->priv = priv;
|
||||
+ priv->ds->ops = &mt7530_switch_ops;
|
||||
+ mutex_init(&priv->reg_mutex);
|
||||
+ dev_set_drvdata(dev, priv);
|
||||
|
||||
- if (priv->id == ID_MT7530) {
|
||||
- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
|
||||
- if (IS_ERR(priv->core_pwr))
|
||||
- return PTR_ERR(priv->core_pwr);
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
|
||||
- if (IS_ERR(priv->io_pwr))
|
||||
- return PTR_ERR(priv->io_pwr);
|
||||
- }
|
||||
+static int
|
||||
+mt7530_probe(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+ static struct regmap_config *regmap_config;
|
||||
+ struct mt7530_priv *priv;
|
||||
+ struct device_node *dn;
|
||||
+ int ret;
|
||||
+
|
||||
+ dn = mdiodev->dev.of_node;
|
||||
+
|
||||
+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
|
||||
- /* Not MCM that indicates switch works as the remote standalone
|
||||
+ priv->bus = mdiodev->bus;
|
||||
+ priv->dev = &mdiodev->dev;
|
||||
+
|
||||
+ ret = mt7530_probe_common(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Use medatek,mcm property to distinguish hardware type that would
|
||||
+ * cause a little bit differences on power-on sequence.
|
||||
+ * Not MCM that indicates switch works as the remote standalone
|
||||
* integrated circuit so the GPIO pin would be used to complete
|
||||
* the reset, otherwise memory-mapped register accessing used
|
||||
* through syscon provides in the case of MCM.
|
||||
*/
|
||||
- if (!priv->mcm) {
|
||||
+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
|
||||
+ if (priv->mcm) {
|
||||
+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
|
||||
+
|
||||
+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
|
||||
+ if (IS_ERR(priv->rstc)) {
|
||||
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
+ return PTR_ERR(priv->rstc);
|
||||
+ }
|
||||
+ } else {
|
||||
priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(priv->reset)) {
|
||||
@@ -3211,12 +3218,15 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
}
|
||||
}
|
||||
|
||||
- priv->bus = mdiodev->bus;
|
||||
- priv->dev = &mdiodev->dev;
|
||||
- priv->ds->priv = priv;
|
||||
- priv->ds->ops = &mt7530_switch_ops;
|
||||
- mutex_init(&priv->reg_mutex);
|
||||
- dev_set_drvdata(&mdiodev->dev, priv);
|
||||
+ if (priv->id == ID_MT7530) {
|
||||
+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
|
||||
+ if (IS_ERR(priv->core_pwr))
|
||||
+ return PTR_ERR(priv->core_pwr);
|
||||
+
|
||||
+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
|
||||
+ if (IS_ERR(priv->io_pwr))
|
||||
+ return PTR_ERR(priv->io_pwr);
|
||||
+ }
|
||||
|
||||
regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
|
||||
GFP_KERNEL);
|
|
@ -0,0 +1,55 @@
|
|||
From 720d736351761574af02ed093658ab60de60576c Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:18:50 +0100
|
||||
Subject: [PATCH 12/16] net: dsa: mt7530: introduce mt7530_remove_common helper
|
||||
function
|
||||
|
||||
Move commonly used parts from mt7530_remove into new
|
||||
mt7530_remove_common helper function which will be used by both,
|
||||
mt7530_remove and the to-be-introduced mt7988_remove.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 18 ++++++++++++------
|
||||
1 file changed, 12 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3253,6 +3253,17 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
}
|
||||
|
||||
static void
|
||||
+mt7530_remove_common(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ if (priv->irq)
|
||||
+ mt7530_free_irq(priv);
|
||||
+
|
||||
+ dsa_unregister_switch(priv->ds);
|
||||
+
|
||||
+ mutex_destroy(&priv->reg_mutex);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
mt7530_remove(struct mdio_device *mdiodev)
|
||||
{
|
||||
struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
@@ -3271,16 +3282,11 @@ mt7530_remove(struct mdio_device *mdiode
|
||||
dev_err(priv->dev, "Failed to disable io pwr: %d\n",
|
||||
ret);
|
||||
|
||||
- if (priv->irq)
|
||||
- mt7530_free_irq(priv);
|
||||
-
|
||||
- dsa_unregister_switch(priv->ds);
|
||||
+ mt7530_remove_common(priv);
|
||||
|
||||
for (i = 0; i < 2; ++i)
|
||||
mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
|
||||
|
||||
- mutex_destroy(&priv->reg_mutex);
|
||||
-
|
||||
dev_set_drvdata(&mdiodev->dev, NULL);
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
From 7f54cc9772ced2d76ac11832f0ada43798443ac9 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:19:02 +0100
|
||||
Subject: [PATCH 13/16] net: dsa: mt7530: split-off common parts from
|
||||
mt7531_setup
|
||||
|
||||
MT7988 shares a significant part of the setup function with MT7531.
|
||||
Split-off those parts into a shared function which is going to be used
|
||||
also by mt7988_setup.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 99 ++++++++++++++++++++++------------------
|
||||
1 file changed, 55 insertions(+), 44 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2348,11 +2348,64 @@ mt7530_setup(struct dsa_switch *ds)
|
||||
}
|
||||
|
||||
static int
|
||||
+mt7531_setup_common(struct dsa_switch *ds)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = ds->priv;
|
||||
+ struct dsa_port *cpu_dp;
|
||||
+ int ret, i;
|
||||
+
|
||||
+ /* BPDU to CPU port */
|
||||
+ dsa_switch_for_each_cpu_port(cpu_dp, ds) {
|
||||
+ mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
|
||||
+ BIT(cpu_dp->index));
|
||||
+ break;
|
||||
+ }
|
||||
+ mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
|
||||
+ MT753X_BPDU_CPU_ONLY);
|
||||
+
|
||||
+ /* Enable and reset MIB counters */
|
||||
+ mt7530_mib_reset(ds);
|
||||
+
|
||||
+ for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
+ /* Disable forwarding by default on all ports */
|
||||
+ mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
|
||||
+ PCR_MATRIX_CLR);
|
||||
+
|
||||
+ /* Disable learning by default on all ports */
|
||||
+ mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
||||
+
|
||||
+ mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
|
||||
+
|
||||
+ if (dsa_is_cpu_port(ds, i)) {
|
||||
+ ret = mt753x_cpu_port_enable(ds, i);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ } else {
|
||||
+ mt7530_port_disable(ds, i);
|
||||
+
|
||||
+ /* Set default PVID to 0 on all user ports */
|
||||
+ mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
|
||||
+ G0_PORT_VID_DEF);
|
||||
+ }
|
||||
+
|
||||
+ /* Enable consistent egress tag */
|
||||
+ mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
|
||||
+ PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
|
||||
+ }
|
||||
+
|
||||
+ /* Flush the FDB table */
|
||||
+ ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
mt7531_setup(struct dsa_switch *ds)
|
||||
{
|
||||
struct mt7530_priv *priv = ds->priv;
|
||||
struct mt7530_dummy_poll p;
|
||||
- struct dsa_port *cpu_dp;
|
||||
u32 val, id;
|
||||
int ret, i;
|
||||
|
||||
@@ -2426,44 +2479,7 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2,
|
||||
CORE_PLL_GROUP4, val);
|
||||
|
||||
- /* BPDU to CPU port */
|
||||
- dsa_switch_for_each_cpu_port(cpu_dp, ds) {
|
||||
- mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
|
||||
- BIT(cpu_dp->index));
|
||||
- break;
|
||||
- }
|
||||
- mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
|
||||
- MT753X_BPDU_CPU_ONLY);
|
||||
-
|
||||
- /* Enable and reset MIB counters */
|
||||
- mt7530_mib_reset(ds);
|
||||
-
|
||||
- for (i = 0; i < MT7530_NUM_PORTS; i++) {
|
||||
- /* Disable forwarding by default on all ports */
|
||||
- mt7530_rmw(priv, MT7530_PCR_P(i), PCR_MATRIX_MASK,
|
||||
- PCR_MATRIX_CLR);
|
||||
-
|
||||
- /* Disable learning by default on all ports */
|
||||
- mt7530_set(priv, MT7530_PSC_P(i), SA_DIS);
|
||||
-
|
||||
- mt7530_set(priv, MT7531_DBG_CNT(i), MT7531_DIS_CLR);
|
||||
-
|
||||
- if (dsa_is_cpu_port(ds, i)) {
|
||||
- ret = mt753x_cpu_port_enable(ds, i);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- } else {
|
||||
- mt7530_port_disable(ds, i);
|
||||
-
|
||||
- /* Set default PVID to 0 on all user ports */
|
||||
- mt7530_rmw(priv, MT7530_PPBV1_P(i), G0_PORT_VID_MASK,
|
||||
- G0_PORT_VID_DEF);
|
||||
- }
|
||||
-
|
||||
- /* Enable consistent egress tag */
|
||||
- mt7530_rmw(priv, MT7530_PVC_P(i), PVC_EG_TAG_MASK,
|
||||
- PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
|
||||
- }
|
||||
+ mt7531_setup_common(ds);
|
||||
|
||||
/* Setup VLAN ID 0 for VLAN-unaware bridges */
|
||||
ret = mt7530_setup_vlan0(priv);
|
||||
@@ -2473,11 +2489,6 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
ds->assisted_learning_on_cpu_port = true;
|
||||
ds->mtu_enforcement_ingress = true;
|
||||
|
||||
- /* Flush the FDB table */
|
||||
- ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,692 @@
|
|||
From cb675afcddbbeb2bfa6596e3bc236bc026cd425f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:19:13 +0100
|
||||
Subject: [PATCH 14/16] net: dsa: mt7530: introduce separate MDIO driver
|
||||
|
||||
Split MT7530 switch driver into a common part and a part specific
|
||||
for MDIO connected switches and multi-chip modules.
|
||||
Move MDIO-specific functions to newly introduced mt7530-mdio.c while
|
||||
keeping the common parts in mt7530.c.
|
||||
Introduce new Kconfig symbol CONFIG_NET_DSA_MT7530_MDIO which is
|
||||
implied by CONFIG_NET_DSA_MT7530.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
MAINTAINERS | 1 +
|
||||
drivers/net/dsa/Kconfig | 15 +-
|
||||
drivers/net/dsa/Makefile | 1 +
|
||||
drivers/net/dsa/mt7530-mdio.c | 271 ++++++++++++++++++++++++++++++++++
|
||||
drivers/net/dsa/mt7530.c | 264 +--------------------------------
|
||||
drivers/net/dsa/mt7530.h | 6 +
|
||||
6 files changed, 300 insertions(+), 258 deletions(-)
|
||||
create mode 100644 drivers/net/dsa/mt7530-mdio.c
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -11901,6 +11901,7 @@ M: Landen Chao <Landen.Chao@mediatek.com
|
||||
M: DENG Qingfang <dqfext@gmail.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
+F: drivers/net/dsa/mt7530-mdio.c
|
||||
F: drivers/net/dsa/mt7530.*
|
||||
F: net/dsa/tag_mtk.c
|
||||
|
||||
--- a/drivers/net/dsa/Kconfig
|
||||
+++ b/drivers/net/dsa/Kconfig
|
||||
@@ -37,10 +37,22 @@ config NET_DSA_MT7530
|
||||
tristate "MediaTek MT753x and MT7621 Ethernet switch support"
|
||||
select NET_DSA_TAG_MTK
|
||||
select MEDIATEK_GE_PHY
|
||||
+ imply NET_DSA_MT7530_MDIO
|
||||
+ help
|
||||
+ This enables support for the MediaTek MT7530 and MT7531 Ethernet
|
||||
+ switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
|
||||
+ MT7621ST and MT7623AI SoCs, and built-in switch in MT7988 SoC are
|
||||
+ supported as well.
|
||||
+
|
||||
+config NET_DSA_MT7530_MDIO
|
||||
+ tristate "MediaTek MT7530 MDIO interface driver"
|
||||
+ depends on NET_DSA_MT7530
|
||||
select PCS_MTK_LYNXI
|
||||
help
|
||||
- This enables support for the MediaTek MT7530, MT7531, and MT7621
|
||||
- Ethernet switch chips.
|
||||
+ This enables support for the MediaTek MT7530 and MT7531 switch
|
||||
+ chips which are connected via MDIO, as well as multi-chip
|
||||
+ module MT7530 which can be found in the MT7621AT, MT7621DAT,
|
||||
+ MT7621ST and MT7623AI SoCs.
|
||||
|
||||
config NET_DSA_MV88E6060
|
||||
tristate "Marvell 88E6060 ethernet switch chip support"
|
||||
--- a/drivers/net/dsa/Makefile
|
||||
+++ b/drivers/net/dsa/Makefile
|
||||
@@ -7,6 +7,7 @@ obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdi
|
||||
endif
|
||||
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
|
||||
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
|
||||
+obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
|
||||
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
|
||||
obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
|
||||
realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/mt7530-mdio.c
|
||||
@@ -0,0 +1,271 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+
|
||||
+#include <linux/gpio/consumer.h>
|
||||
+#include <linux/mdio.h>
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/pcs/pcs-mtk-lynxi.h>
|
||||
+#include <linux/of_irq.h>
|
||||
+#include <linux/of_mdio.h>
|
||||
+#include <linux/of_net.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
+#include <net/dsa.h>
|
||||
+
|
||||
+#include "mt7530.h"
|
||||
+
|
||||
+static int
|
||||
+mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
+{
|
||||
+ struct mii_bus *bus = context;
|
||||
+ u16 page, r, lo, hi;
|
||||
+ int ret;
|
||||
+
|
||||
+ page = (reg >> 6) & 0x3ff;
|
||||
+ r = (reg >> 2) & 0xf;
|
||||
+ lo = val & 0xffff;
|
||||
+ hi = val >> 16;
|
||||
+
|
||||
+ /* MT7530 uses 31 as the pseudo port */
|
||||
+ ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bus->write(bus, 0x1f, r, lo);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = bus->write(bus, 0x1f, 0x10, hi);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
+{
|
||||
+ struct mii_bus *bus = context;
|
||||
+ u16 page, r, lo, hi;
|
||||
+ int ret;
|
||||
+
|
||||
+ page = (reg >> 6) & 0x3ff;
|
||||
+ r = (reg >> 2) & 0xf;
|
||||
+
|
||||
+ /* MT7530 uses 31 as the pseudo port */
|
||||
+ ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
+ if (ret < 0)
|
||||
+ return ret;
|
||||
+
|
||||
+ lo = bus->read(bus, 0x1f, r);
|
||||
+ hi = bus->read(bus, 0x1f, 0x10);
|
||||
+
|
||||
+ *val = (hi << 16) | (lo & 0xffff);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7530_mdio_regmap_lock(void *mdio_lock)
|
||||
+{
|
||||
+ mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7530_mdio_regmap_unlock(void *mdio_lock)
|
||||
+{
|
||||
+ mutex_unlock(mdio_lock);
|
||||
+}
|
||||
+
|
||||
+static const struct regmap_bus mt7530_regmap_bus = {
|
||||
+ .reg_write = mt7530_regmap_write,
|
||||
+ .reg_read = mt7530_regmap_read,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+mt7531_create_sgmii(struct mt7530_priv *priv)
|
||||
+{
|
||||
+ struct regmap_config *mt7531_pcs_config[2];
|
||||
+ struct phylink_pcs *pcs;
|
||||
+ struct regmap *regmap;
|
||||
+ int i, ret = 0;
|
||||
+
|
||||
+ for (i = 0; i < 2; i++) {
|
||||
+ mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
|
||||
+ sizeof(struct regmap_config),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!mt7531_pcs_config[i]) {
|
||||
+ ret = -ENOMEM;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ mt7531_pcs_config[i]->name = i ? "port6" : "port5";
|
||||
+ mt7531_pcs_config[i]->reg_bits = 16;
|
||||
+ mt7531_pcs_config[i]->val_bits = 32;
|
||||
+ mt7531_pcs_config[i]->reg_stride = 4;
|
||||
+ mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
|
||||
+ mt7531_pcs_config[i]->max_register = 0x17c;
|
||||
+ mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
|
||||
+ mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
|
||||
+ mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
+
|
||||
+ regmap = devm_regmap_init(priv->dev,
|
||||
+ &mt7530_regmap_bus, priv->bus,
|
||||
+ mt7531_pcs_config[i]);
|
||||
+ if (IS_ERR(regmap)) {
|
||||
+ ret = PTR_ERR(regmap);
|
||||
+ break;
|
||||
+ }
|
||||
+ pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
|
||||
+ MT7531_PHYA_CTRL_SIGNAL3, 0);
|
||||
+ if (!pcs) {
|
||||
+ ret = -ENXIO;
|
||||
+ break;
|
||||
+ }
|
||||
+ priv->ports[5 + i].sgmii_pcs = pcs;
|
||||
+ }
|
||||
+
|
||||
+ if (ret && i)
|
||||
+ mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static const struct of_device_id mt7530_of_match[] = {
|
||||
+ { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
|
||||
+ { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
|
||||
+ { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mt7530_of_match);
|
||||
+
|
||||
+static int
|
||||
+mt7530_probe(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+ static struct regmap_config *regmap_config;
|
||||
+ struct mt7530_priv *priv;
|
||||
+ struct device_node *dn;
|
||||
+ int ret;
|
||||
+
|
||||
+ dn = mdiodev->dev.of_node;
|
||||
+
|
||||
+ priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ priv->bus = mdiodev->bus;
|
||||
+ priv->dev = &mdiodev->dev;
|
||||
+
|
||||
+ ret = mt7530_probe_common(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ /* Use medatek,mcm property to distinguish hardware type that would
|
||||
+ * cause a little bit differences on power-on sequence.
|
||||
+ * Not MCM that indicates switch works as the remote standalone
|
||||
+ * integrated circuit so the GPIO pin would be used to complete
|
||||
+ * the reset, otherwise memory-mapped register accessing used
|
||||
+ * through syscon provides in the case of MCM.
|
||||
+ */
|
||||
+ priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
|
||||
+ if (priv->mcm) {
|
||||
+ dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
|
||||
+
|
||||
+ priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
|
||||
+ if (IS_ERR(priv->rstc)) {
|
||||
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
+ return PTR_ERR(priv->rstc);
|
||||
+ }
|
||||
+ } else {
|
||||
+ priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
|
||||
+ GPIOD_OUT_LOW);
|
||||
+ if (IS_ERR(priv->reset)) {
|
||||
+ dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
+ return PTR_ERR(priv->reset);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (priv->id == ID_MT7530) {
|
||||
+ priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
|
||||
+ if (IS_ERR(priv->core_pwr))
|
||||
+ return PTR_ERR(priv->core_pwr);
|
||||
+
|
||||
+ priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
|
||||
+ if (IS_ERR(priv->io_pwr))
|
||||
+ return PTR_ERR(priv->io_pwr);
|
||||
+ }
|
||||
+
|
||||
+ regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
|
||||
+ GFP_KERNEL);
|
||||
+ if (!regmap_config)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ regmap_config->reg_bits = 16;
|
||||
+ regmap_config->val_bits = 32;
|
||||
+ regmap_config->reg_stride = 4;
|
||||
+ regmap_config->max_register = MT7530_CREV;
|
||||
+ regmap_config->disable_locking = true;
|
||||
+ priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
|
||||
+ priv->bus, regmap_config);
|
||||
+ if (IS_ERR(priv->regmap))
|
||||
+ return PTR_ERR(priv->regmap);
|
||||
+
|
||||
+ if (priv->id == ID_MT7531) {
|
||||
+ ret = mt7531_create_sgmii(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return dsa_register_switch(priv->ds);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7530_remove(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
+ int ret = 0, i;
|
||||
+
|
||||
+ if (!priv)
|
||||
+ return;
|
||||
+
|
||||
+ ret = regulator_disable(priv->core_pwr);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(priv->dev,
|
||||
+ "Failed to disable core power: %d\n", ret);
|
||||
+
|
||||
+ ret = regulator_disable(priv->io_pwr);
|
||||
+ if (ret < 0)
|
||||
+ dev_err(priv->dev, "Failed to disable io pwr: %d\n",
|
||||
+ ret);
|
||||
+
|
||||
+ mt7530_remove_common(priv);
|
||||
+
|
||||
+ for (i = 0; i < 2; ++i)
|
||||
+ mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
|
||||
+}
|
||||
+
|
||||
+static void mt7530_shutdown(struct mdio_device *mdiodev)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
+
|
||||
+ if (!priv)
|
||||
+ return;
|
||||
+
|
||||
+ dsa_switch_shutdown(priv->ds);
|
||||
+
|
||||
+ dev_set_drvdata(&mdiodev->dev, NULL);
|
||||
+}
|
||||
+
|
||||
+static struct mdio_driver mt7530_mdio_driver = {
|
||||
+ .probe = mt7530_probe,
|
||||
+ .remove = mt7530_remove,
|
||||
+ .shutdown = mt7530_shutdown,
|
||||
+ .mdiodrv.driver = {
|
||||
+ .name = "mt7530-mdio",
|
||||
+ .of_match_table = mt7530_of_match,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+mdio_module_driver(mt7530_mdio_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
|
||||
+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MDIO)");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -14,7 +14,6 @@
|
||||
#include <linux/of_mdio.h>
|
||||
#include <linux/of_net.h>
|
||||
#include <linux/of_platform.h>
|
||||
-#include <linux/pcs/pcs-mtk-lynxi.h>
|
||||
#include <linux/phylink.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
@@ -192,31 +191,6 @@ core_clear(struct mt7530_priv *priv, u32
|
||||
}
|
||||
|
||||
static int
|
||||
-mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
|
||||
-{
|
||||
- struct mii_bus *bus = context;
|
||||
- u16 page, r, lo, hi;
|
||||
- int ret;
|
||||
-
|
||||
- page = (reg >> 6) & 0x3ff;
|
||||
- r = (reg >> 2) & 0xf;
|
||||
- lo = val & 0xffff;
|
||||
- hi = val >> 16;
|
||||
-
|
||||
- /* MT7530 uses 31 as the pseudo port */
|
||||
- ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- ret = bus->write(bus, 0x1f, r, lo);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- ret = bus->write(bus, 0x1f, 0x10, hi);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
-static int
|
||||
mt7530_mii_write(struct mt7530_priv *priv, u32 reg, u32 val)
|
||||
{
|
||||
int ret;
|
||||
@@ -230,29 +204,6 @@ mt7530_mii_write(struct mt7530_priv *pri
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int
|
||||
-mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
|
||||
-{
|
||||
- struct mii_bus *bus = context;
|
||||
- u16 page, r, lo, hi;
|
||||
- int ret;
|
||||
-
|
||||
- page = (reg >> 6) & 0x3ff;
|
||||
- r = (reg >> 2) & 0xf;
|
||||
-
|
||||
- /* MT7530 uses 31 as the pseudo port */
|
||||
- ret = bus->write(bus, 0x1f, 0x1f, page);
|
||||
- if (ret < 0)
|
||||
- return ret;
|
||||
-
|
||||
- lo = bus->read(bus, 0x1f, r);
|
||||
- hi = bus->read(bus, 0x1f, 0x10);
|
||||
-
|
||||
- *val = (hi << 16) | (lo & 0xffff);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static u32
|
||||
mt7530_mii_read(struct mt7530_priv *priv, u32 reg)
|
||||
{
|
||||
@@ -2944,72 +2895,6 @@ static const struct phylink_pcs_ops mt75
|
||||
.pcs_an_restart = mt7530_pcs_an_restart,
|
||||
};
|
||||
|
||||
-static void
|
||||
-mt7530_mdio_regmap_lock(void *mdio_lock)
|
||||
-{
|
||||
- mutex_lock_nested(mdio_lock, MDIO_MUTEX_NESTED);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
-mt7530_mdio_regmap_unlock(void *mdio_lock)
|
||||
-{
|
||||
- mutex_unlock(mdio_lock);
|
||||
-}
|
||||
-
|
||||
-static const struct regmap_bus mt7530_regmap_bus = {
|
||||
- .reg_write = mt7530_regmap_write,
|
||||
- .reg_read = mt7530_regmap_read,
|
||||
-};
|
||||
-
|
||||
-static int
|
||||
-mt7531_create_sgmii(struct mt7530_priv *priv)
|
||||
-{
|
||||
- struct regmap_config *mt7531_pcs_config[2];
|
||||
- struct phylink_pcs *pcs;
|
||||
- struct regmap *regmap;
|
||||
- int i, ret = 0;
|
||||
-
|
||||
- for (i = 0; i < 2; i++) {
|
||||
- mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
|
||||
- sizeof(struct regmap_config),
|
||||
- GFP_KERNEL);
|
||||
- if (!mt7531_pcs_config[i]) {
|
||||
- ret = -ENOMEM;
|
||||
- break;
|
||||
- }
|
||||
-
|
||||
- mt7531_pcs_config[i]->name = i ? "port6" : "port5";
|
||||
- mt7531_pcs_config[i]->reg_bits = 16;
|
||||
- mt7531_pcs_config[i]->val_bits = 32;
|
||||
- mt7531_pcs_config[i]->reg_stride = 4;
|
||||
- mt7531_pcs_config[i]->reg_base = MT7531_SGMII_REG_BASE(5 + i);
|
||||
- mt7531_pcs_config[i]->max_register = 0x17c;
|
||||
- mt7531_pcs_config[i]->lock = mt7530_mdio_regmap_lock;
|
||||
- mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
|
||||
- mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
|
||||
-
|
||||
- regmap = devm_regmap_init(priv->dev,
|
||||
- &mt7530_regmap_bus, priv->bus,
|
||||
- mt7531_pcs_config[i]);
|
||||
- if (IS_ERR(regmap)) {
|
||||
- ret = PTR_ERR(regmap);
|
||||
- break;
|
||||
- }
|
||||
- pcs = mtk_pcs_lynxi_create(priv->dev, regmap,
|
||||
- MT7531_PHYA_CTRL_SIGNAL3, 0);
|
||||
- if (!pcs) {
|
||||
- ret = -ENXIO;
|
||||
- break;
|
||||
- }
|
||||
- priv->ports[5 + i].sgmii_pcs = pcs;
|
||||
- }
|
||||
-
|
||||
- if (ret && i)
|
||||
- mtk_pcs_lynxi_destroy(priv->ports[5].sgmii_pcs);
|
||||
-
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static int
|
||||
mt753x_setup(struct dsa_switch *ds)
|
||||
{
|
||||
@@ -3068,7 +2953,7 @@ static int mt753x_set_mac_eee(struct dsa
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static const struct dsa_switch_ops mt7530_switch_ops = {
|
||||
+const struct dsa_switch_ops mt7530_switch_ops = {
|
||||
.get_tag_protocol = mtk_get_tag_protocol,
|
||||
.setup = mt753x_setup,
|
||||
.get_strings = mt7530_get_strings,
|
||||
@@ -3102,8 +2987,9 @@ static const struct dsa_switch_ops mt753
|
||||
.get_mac_eee = mt753x_get_mac_eee,
|
||||
.set_mac_eee = mt753x_set_mac_eee,
|
||||
};
|
||||
+EXPORT_SYMBOL_GPL(mt7530_switch_ops);
|
||||
|
||||
-static const struct mt753x_info mt753x_table[] = {
|
||||
+const struct mt753x_info mt753x_table[] = {
|
||||
[ID_MT7621] = {
|
||||
.id = ID_MT7621,
|
||||
.pcs_ops = &mt7530_pcs_ops,
|
||||
@@ -3136,16 +3022,9 @@ static const struct mt753x_info mt753x_t
|
||||
.mac_port_config = mt7531_mac_config,
|
||||
},
|
||||
};
|
||||
+EXPORT_SYMBOL_GPL(mt753x_table);
|
||||
|
||||
-static const struct of_device_id mt7530_of_match[] = {
|
||||
- { .compatible = "mediatek,mt7621", .data = &mt753x_table[ID_MT7621], },
|
||||
- { .compatible = "mediatek,mt7530", .data = &mt753x_table[ID_MT7530], },
|
||||
- { .compatible = "mediatek,mt7531", .data = &mt753x_table[ID_MT7531], },
|
||||
- { /* sentinel */ },
|
||||
-};
|
||||
-MODULE_DEVICE_TABLE(of, mt7530_of_match);
|
||||
-
|
||||
-static int
|
||||
+int
|
||||
mt7530_probe_common(struct mt7530_priv *priv)
|
||||
{
|
||||
struct device *dev = priv->dev;
|
||||
@@ -3182,88 +3061,9 @@ mt7530_probe_common(struct mt7530_priv *
|
||||
|
||||
return 0;
|
||||
}
|
||||
+EXPORT_SYMBOL_GPL(mt7530_probe_common);
|
||||
|
||||
-static int
|
||||
-mt7530_probe(struct mdio_device *mdiodev)
|
||||
-{
|
||||
- static struct regmap_config *regmap_config;
|
||||
- struct mt7530_priv *priv;
|
||||
- struct device_node *dn;
|
||||
- int ret;
|
||||
-
|
||||
- dn = mdiodev->dev.of_node;
|
||||
-
|
||||
- priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
- if (!priv)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- priv->bus = mdiodev->bus;
|
||||
- priv->dev = &mdiodev->dev;
|
||||
-
|
||||
- ret = mt7530_probe_common(priv);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
-
|
||||
- /* Use medatek,mcm property to distinguish hardware type that would
|
||||
- * cause a little bit differences on power-on sequence.
|
||||
- * Not MCM that indicates switch works as the remote standalone
|
||||
- * integrated circuit so the GPIO pin would be used to complete
|
||||
- * the reset, otherwise memory-mapped register accessing used
|
||||
- * through syscon provides in the case of MCM.
|
||||
- */
|
||||
- priv->mcm = of_property_read_bool(dn, "mediatek,mcm");
|
||||
- if (priv->mcm) {
|
||||
- dev_info(&mdiodev->dev, "MT7530 adapts as multi-chip module\n");
|
||||
-
|
||||
- priv->rstc = devm_reset_control_get(&mdiodev->dev, "mcm");
|
||||
- if (IS_ERR(priv->rstc)) {
|
||||
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
- return PTR_ERR(priv->rstc);
|
||||
- }
|
||||
- } else {
|
||||
- priv->reset = devm_gpiod_get_optional(&mdiodev->dev, "reset",
|
||||
- GPIOD_OUT_LOW);
|
||||
- if (IS_ERR(priv->reset)) {
|
||||
- dev_err(&mdiodev->dev, "Couldn't get our reset line\n");
|
||||
- return PTR_ERR(priv->reset);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- if (priv->id == ID_MT7530) {
|
||||
- priv->core_pwr = devm_regulator_get(&mdiodev->dev, "core");
|
||||
- if (IS_ERR(priv->core_pwr))
|
||||
- return PTR_ERR(priv->core_pwr);
|
||||
-
|
||||
- priv->io_pwr = devm_regulator_get(&mdiodev->dev, "io");
|
||||
- if (IS_ERR(priv->io_pwr))
|
||||
- return PTR_ERR(priv->io_pwr);
|
||||
- }
|
||||
-
|
||||
- regmap_config = devm_kzalloc(&mdiodev->dev, sizeof(*regmap_config),
|
||||
- GFP_KERNEL);
|
||||
- if (!regmap_config)
|
||||
- return -ENOMEM;
|
||||
-
|
||||
- regmap_config->reg_bits = 16;
|
||||
- regmap_config->val_bits = 32;
|
||||
- regmap_config->reg_stride = 4;
|
||||
- regmap_config->max_register = MT7530_CREV;
|
||||
- regmap_config->disable_locking = true;
|
||||
- priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
|
||||
- priv->bus, regmap_config);
|
||||
- if (IS_ERR(priv->regmap))
|
||||
- return PTR_ERR(priv->regmap);
|
||||
-
|
||||
- if (priv->id == ID_MT7531) {
|
||||
- ret = mt7531_create_sgmii(priv);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
-
|
||||
- return dsa_register_switch(priv->ds);
|
||||
-}
|
||||
-
|
||||
-static void
|
||||
+void
|
||||
mt7530_remove_common(struct mt7530_priv *priv)
|
||||
{
|
||||
if (priv->irq)
|
||||
@@ -3274,57 +3074,6 @@ mt7530_remove_common(struct mt7530_priv
|
||||
mutex_destroy(&priv->reg_mutex);
|
||||
}
|
||||
|
||||
-static void
|
||||
-mt7530_remove(struct mdio_device *mdiodev)
|
||||
-{
|
||||
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
- int ret = 0, i;
|
||||
-
|
||||
- if (!priv)
|
||||
- return;
|
||||
-
|
||||
- ret = regulator_disable(priv->core_pwr);
|
||||
- if (ret < 0)
|
||||
- dev_err(priv->dev,
|
||||
- "Failed to disable core power: %d\n", ret);
|
||||
-
|
||||
- ret = regulator_disable(priv->io_pwr);
|
||||
- if (ret < 0)
|
||||
- dev_err(priv->dev, "Failed to disable io pwr: %d\n",
|
||||
- ret);
|
||||
-
|
||||
- mt7530_remove_common(priv);
|
||||
-
|
||||
- for (i = 0; i < 2; ++i)
|
||||
- mtk_pcs_lynxi_destroy(priv->ports[5 + i].sgmii_pcs);
|
||||
-
|
||||
- dev_set_drvdata(&mdiodev->dev, NULL);
|
||||
-}
|
||||
-
|
||||
-static void mt7530_shutdown(struct mdio_device *mdiodev)
|
||||
-{
|
||||
- struct mt7530_priv *priv = dev_get_drvdata(&mdiodev->dev);
|
||||
-
|
||||
- if (!priv)
|
||||
- return;
|
||||
-
|
||||
- dsa_switch_shutdown(priv->ds);
|
||||
-
|
||||
- dev_set_drvdata(&mdiodev->dev, NULL);
|
||||
-}
|
||||
-
|
||||
-static struct mdio_driver mt7530_mdio_driver = {
|
||||
- .probe = mt7530_probe,
|
||||
- .remove = mt7530_remove,
|
||||
- .shutdown = mt7530_shutdown,
|
||||
- .mdiodrv.driver = {
|
||||
- .name = "mt7530",
|
||||
- .of_match_table = mt7530_of_match,
|
||||
- },
|
||||
-};
|
||||
-
|
||||
-mdio_module_driver(mt7530_mdio_driver);
|
||||
-
|
||||
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
|
||||
MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch");
|
||||
MODULE_LICENSE("GPL");
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -807,4 +807,10 @@ static inline void INIT_MT7530_DUMMY_POL
|
||||
p->reg = reg;
|
||||
}
|
||||
|
||||
+int mt7530_probe_common(struct mt7530_priv *priv);
|
||||
+void mt7530_remove_common(struct mt7530_priv *priv);
|
||||
+
|
||||
+extern const struct dsa_switch_ops mt7530_switch_ops;
|
||||
+extern const struct mt753x_info mt753x_table[];
|
||||
+
|
||||
#endif /* __MT7530_H */
|
|
@ -0,0 +1,47 @@
|
|||
From 54d4147a121cec5004a673a58572da346e4458f8 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:19:28 +0100
|
||||
Subject: [PATCH 15/16] net: dsa: mt7530: skip locking if MDIO bus isn't
|
||||
present
|
||||
|
||||
As MT7530 and MT7531 internally use 32-bit wide registers, each access
|
||||
to any register of the switch requires several operations on the MDIO
|
||||
bus. Hence if there is congruent access, e.g. due to PCS or PHY
|
||||
polling, this can mess up and interfere with another ongoing register
|
||||
access sequence.
|
||||
|
||||
However, the MDIO bus mutex is only relevant for MDIO-connected
|
||||
switches. Prepare switches which have there registers directly mapped
|
||||
into the SoCs register space via MMIO which do not require such
|
||||
locking. There we can simply use regmap's default locking mechanism.
|
||||
|
||||
Hence guard mutex operations to only be performed in case of MDIO
|
||||
connected switches.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/dsa/mt7530.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -144,13 +144,15 @@ err:
|
||||
static void
|
||||
mt7530_mutex_lock(struct mt7530_priv *priv)
|
||||
{
|
||||
- mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
+ if (priv->bus)
|
||||
+ mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
|
||||
}
|
||||
|
||||
static void
|
||||
mt7530_mutex_unlock(struct mt7530_priv *priv)
|
||||
{
|
||||
- mutex_unlock(&priv->bus->mdio_lock);
|
||||
+ if (priv->bus)
|
||||
+ mutex_unlock(&priv->bus->mdio_lock);
|
||||
}
|
||||
|
||||
static void
|
|
@ -0,0 +1,421 @@
|
|||
From 110c18bfed41421edd677935dd33be5e6507ba92 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 3 Apr 2023 02:19:40 +0100
|
||||
Subject: [PATCH 16/16] net: dsa: mt7530: introduce driver for MT7988 built-in
|
||||
switch
|
||||
|
||||
Add driver for the built-in Gigabit Ethernet switch which can be found
|
||||
in the MediaTek MT7988 SoC.
|
||||
|
||||
The switch shares most of its design with MT7530 and MT7531, but has
|
||||
it's registers mapped into the SoCs register space rather than being
|
||||
connected externally or internally via MDIO.
|
||||
|
||||
Introduce a new platform driver to support that.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
MAINTAINERS | 2 +
|
||||
drivers/net/dsa/Kconfig | 12 +++
|
||||
drivers/net/dsa/Makefile | 1 +
|
||||
drivers/net/dsa/mt7530-mmio.c | 101 +++++++++++++++++++++++++
|
||||
drivers/net/dsa/mt7530.c | 137 +++++++++++++++++++++++++++++++++-
|
||||
drivers/net/dsa/mt7530.h | 12 +--
|
||||
6 files changed, 255 insertions(+), 10 deletions(-)
|
||||
create mode 100644 drivers/net/dsa/mt7530-mmio.c
|
||||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -11899,9 +11899,11 @@ MEDIATEK SWITCH DRIVER
|
||||
M: Sean Wang <sean.wang@mediatek.com>
|
||||
M: Landen Chao <Landen.Chao@mediatek.com>
|
||||
M: DENG Qingfang <dqfext@gmail.com>
|
||||
+M: Daniel Golle <daniel@makrotopia.org>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/dsa/mt7530-mdio.c
|
||||
+F: drivers/net/dsa/mt7530-mmio.c
|
||||
F: drivers/net/dsa/mt7530.*
|
||||
F: net/dsa/tag_mtk.c
|
||||
|
||||
--- a/drivers/net/dsa/Kconfig
|
||||
+++ b/drivers/net/dsa/Kconfig
|
||||
@@ -38,6 +38,7 @@ config NET_DSA_MT7530
|
||||
select NET_DSA_TAG_MTK
|
||||
select MEDIATEK_GE_PHY
|
||||
imply NET_DSA_MT7530_MDIO
|
||||
+ imply NET_DSA_MT7530_MMIO
|
||||
help
|
||||
This enables support for the MediaTek MT7530 and MT7531 Ethernet
|
||||
switch chips. Multi-chip module MT7530 in MT7621AT, MT7621DAT,
|
||||
@@ -54,6 +55,17 @@ config NET_DSA_MT7530_MDIO
|
||||
module MT7530 which can be found in the MT7621AT, MT7621DAT,
|
||||
MT7621ST and MT7623AI SoCs.
|
||||
|
||||
+config NET_DSA_MT7530_MMIO
|
||||
+ tristate "MediaTek MT7530 MMIO interface driver"
|
||||
+ depends on NET_DSA_MT7530
|
||||
+ depends on HAS_IOMEM
|
||||
+ help
|
||||
+ This enables support for the built-in Ethernet switch found
|
||||
+ in the MediaTek MT7988 SoC.
|
||||
+ The switch is a similar design as MT7531, but the switch registers
|
||||
+ are directly mapped into the SoCs register space rather than being
|
||||
+ accessible via MDIO.
|
||||
+
|
||||
config NET_DSA_MV88E6060
|
||||
tristate "Marvell 88E6060 ethernet switch chip support"
|
||||
select NET_DSA_TAG_TRAILER
|
||||
--- a/drivers/net/dsa/Makefile
|
||||
+++ b/drivers/net/dsa/Makefile
|
||||
@@ -8,6 +8,7 @@ endif
|
||||
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
|
||||
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
|
||||
obj-$(CONFIG_NET_DSA_MT7530_MDIO) += mt7530-mdio.o
|
||||
+obj-$(CONFIG_NET_DSA_MT7530_MMIO) += mt7530-mmio.o
|
||||
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
|
||||
obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
|
||||
realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o
|
||||
--- /dev/null
|
||||
+++ b/drivers/net/dsa/mt7530-mmio.c
|
||||
@@ -0,0 +1,101 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-only
|
||||
+
|
||||
+#include <linux/module.h>
|
||||
+#include <linux/of_platform.h>
|
||||
+#include <linux/regmap.h>
|
||||
+#include <linux/regulator/consumer.h>
|
||||
+#include <linux/reset.h>
|
||||
+#include <net/dsa.h>
|
||||
+
|
||||
+#include "mt7530.h"
|
||||
+
|
||||
+static const struct of_device_id mt7988_of_match[] = {
|
||||
+ { .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], },
|
||||
+ { /* sentinel */ },
|
||||
+};
|
||||
+MODULE_DEVICE_TABLE(of, mt7988_of_match);
|
||||
+
|
||||
+static int
|
||||
+mt7988_probe(struct platform_device *pdev)
|
||||
+{
|
||||
+ static struct regmap_config *sw_regmap_config;
|
||||
+ struct mt7530_priv *priv;
|
||||
+ void __iomem *base_addr;
|
||||
+ int ret;
|
||||
+
|
||||
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
+ if (!priv)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ priv->bus = NULL;
|
||||
+ priv->dev = &pdev->dev;
|
||||
+
|
||||
+ ret = mt7530_probe_common(priv);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ priv->rstc = devm_reset_control_get(&pdev->dev, NULL);
|
||||
+ if (IS_ERR(priv->rstc)) {
|
||||
+ dev_err(&pdev->dev, "Couldn't get our reset line\n");
|
||||
+ return PTR_ERR(priv->rstc);
|
||||
+ }
|
||||
+
|
||||
+ base_addr = devm_platform_ioremap_resource(pdev, 0);
|
||||
+ if (IS_ERR(base_addr)) {
|
||||
+ dev_err(&pdev->dev, "cannot request I/O memory space\n");
|
||||
+ return -ENXIO;
|
||||
+ }
|
||||
+
|
||||
+ sw_regmap_config = devm_kzalloc(&pdev->dev, sizeof(*sw_regmap_config), GFP_KERNEL);
|
||||
+ if (!sw_regmap_config)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ sw_regmap_config->name = "switch";
|
||||
+ sw_regmap_config->reg_bits = 16;
|
||||
+ sw_regmap_config->val_bits = 32;
|
||||
+ sw_regmap_config->reg_stride = 4;
|
||||
+ sw_regmap_config->max_register = MT7530_CREV;
|
||||
+ priv->regmap = devm_regmap_init_mmio(&pdev->dev, base_addr, sw_regmap_config);
|
||||
+ if (IS_ERR(priv->regmap))
|
||||
+ return PTR_ERR(priv->regmap);
|
||||
+
|
||||
+ return dsa_register_switch(priv->ds);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+mt7988_remove(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (priv)
|
||||
+ mt7530_remove_common(priv);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void mt7988_shutdown(struct platform_device *pdev)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = platform_get_drvdata(pdev);
|
||||
+
|
||||
+ if (!priv)
|
||||
+ return;
|
||||
+
|
||||
+ dsa_switch_shutdown(priv->ds);
|
||||
+
|
||||
+ dev_set_drvdata(&pdev->dev, NULL);
|
||||
+}
|
||||
+
|
||||
+static struct platform_driver mt7988_platform_driver = {
|
||||
+ .probe = mt7988_probe,
|
||||
+ .remove = mt7988_remove,
|
||||
+ .shutdown = mt7988_shutdown,
|
||||
+ .driver = {
|
||||
+ .name = "mt7530-mmio",
|
||||
+ .of_match_table = mt7988_of_match,
|
||||
+ },
|
||||
+};
|
||||
+module_platform_driver(mt7988_platform_driver);
|
||||
+
|
||||
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
|
||||
+MODULE_DESCRIPTION("Driver for Mediatek MT7530 Switch (MMIO)");
|
||||
+MODULE_LICENSE("GPL");
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -1984,6 +1984,47 @@ static const struct irq_domain_ops mt753
|
||||
};
|
||||
|
||||
static void
|
||||
+mt7988_irq_mask(struct irq_data *d)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
|
||||
+
|
||||
+ priv->irq_enable &= ~BIT(d->hwirq);
|
||||
+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+mt7988_irq_unmask(struct irq_data *d)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = irq_data_get_irq_chip_data(d);
|
||||
+
|
||||
+ priv->irq_enable |= BIT(d->hwirq);
|
||||
+ mt7530_mii_write(priv, MT7530_SYS_INT_EN, priv->irq_enable);
|
||||
+}
|
||||
+
|
||||
+static struct irq_chip mt7988_irq_chip = {
|
||||
+ .name = KBUILD_MODNAME,
|
||||
+ .irq_mask = mt7988_irq_mask,
|
||||
+ .irq_unmask = mt7988_irq_unmask,
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+mt7988_irq_map(struct irq_domain *domain, unsigned int irq,
|
||||
+ irq_hw_number_t hwirq)
|
||||
+{
|
||||
+ irq_set_chip_data(irq, domain->host_data);
|
||||
+ irq_set_chip_and_handler(irq, &mt7988_irq_chip, handle_simple_irq);
|
||||
+ irq_set_nested_thread(irq, true);
|
||||
+ irq_set_noprobe(irq);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static const struct irq_domain_ops mt7988_irq_domain_ops = {
|
||||
+ .map = mt7988_irq_map,
|
||||
+ .xlate = irq_domain_xlate_onecell,
|
||||
+};
|
||||
+
|
||||
+static void
|
||||
mt7530_setup_mdio_irq(struct mt7530_priv *priv)
|
||||
{
|
||||
struct dsa_switch *ds = priv->ds;
|
||||
@@ -2017,8 +2058,15 @@ mt7530_setup_irq(struct mt7530_priv *pri
|
||||
return priv->irq ? : -EINVAL;
|
||||
}
|
||||
|
||||
- priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
|
||||
- &mt7530_irq_domain_ops, priv);
|
||||
+ if (priv->id == ID_MT7988)
|
||||
+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
|
||||
+ &mt7988_irq_domain_ops,
|
||||
+ priv);
|
||||
+ else
|
||||
+ priv->irq_domain = irq_domain_add_linear(np, MT7530_NUM_PHYS,
|
||||
+ &mt7530_irq_domain_ops,
|
||||
+ priv);
|
||||
+
|
||||
if (!priv->irq_domain) {
|
||||
dev_err(dev, "failed to create IRQ domain\n");
|
||||
return -ENOMEM;
|
||||
@@ -2507,6 +2555,25 @@ static void mt7531_mac_port_get_caps(str
|
||||
}
|
||||
}
|
||||
|
||||
+static void mt7988_mac_port_get_caps(struct dsa_switch *ds, int port,
|
||||
+ struct phylink_config *config)
|
||||
+{
|
||||
+ phy_interface_zero(config->supported_interfaces);
|
||||
+
|
||||
+ switch (port) {
|
||||
+ case 0 ... 4: /* Internal phy */
|
||||
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
+ config->supported_interfaces);
|
||||
+ break;
|
||||
+
|
||||
+ case 6:
|
||||
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
+ config->supported_interfaces);
|
||||
+ config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
|
||||
+ MAC_10000FD;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int
|
||||
mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
|
||||
{
|
||||
@@ -2583,6 +2650,17 @@ static bool mt753x_is_mac_port(u32 port)
|
||||
}
|
||||
|
||||
static int
|
||||
+mt7988_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
+ phy_interface_t interface)
|
||||
+{
|
||||
+ if (dsa_is_cpu_port(ds, port) &&
|
||||
+ interface == PHY_INTERFACE_MODE_INTERNAL)
|
||||
+ return 0;
|
||||
+
|
||||
+ return -EINVAL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
|
||||
phy_interface_t interface)
|
||||
{
|
||||
@@ -2652,7 +2730,8 @@ mt753x_phylink_mac_config(struct dsa_swi
|
||||
|
||||
switch (port) {
|
||||
case 0 ... 4: /* Internal phy */
|
||||
- if (state->interface != PHY_INTERFACE_MODE_GMII)
|
||||
+ if (state->interface != PHY_INTERFACE_MODE_GMII &&
|
||||
+ state->interface != PHY_INTERFACE_MODE_INTERNAL)
|
||||
goto unsupported;
|
||||
break;
|
||||
case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
|
||||
@@ -2730,7 +2809,8 @@ static void mt753x_phylink_mac_link_up(s
|
||||
/* MT753x MAC works in 1G full duplex mode for all up-clocked
|
||||
* variants.
|
||||
*/
|
||||
- if (interface == PHY_INTERFACE_MODE_TRGMII ||
|
||||
+ if (interface == PHY_INTERFACE_MODE_INTERNAL ||
|
||||
+ interface == PHY_INTERFACE_MODE_TRGMII ||
|
||||
(phy_interface_mode_is_8023z(interface))) {
|
||||
speed = SPEED_1000;
|
||||
duplex = DUPLEX_FULL;
|
||||
@@ -2810,6 +2890,21 @@ mt7531_cpu_port_config(struct dsa_switch
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+mt7988_cpu_port_config(struct dsa_switch *ds, int port)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = ds->priv;
|
||||
+
|
||||
+ mt7530_write(priv, MT7530_PMCR_P(port),
|
||||
+ PMCR_CPU_PORT_SETTING(priv->id));
|
||||
+
|
||||
+ mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED,
|
||||
+ PHY_INTERFACE_MODE_INTERNAL, NULL,
|
||||
+ SPEED_10000, DUPLEX_FULL, true, true);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
|
||||
struct phylink_config *config)
|
||||
{
|
||||
@@ -2955,6 +3050,27 @@ static int mt753x_set_mac_eee(struct dsa
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int mt7988_pad_setup(struct dsa_switch *ds, phy_interface_t interface)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int mt7988_setup(struct dsa_switch *ds)
|
||||
+{
|
||||
+ struct mt7530_priv *priv = ds->priv;
|
||||
+
|
||||
+ /* Reset the switch */
|
||||
+ reset_control_assert(priv->rstc);
|
||||
+ usleep_range(20, 50);
|
||||
+ reset_control_deassert(priv->rstc);
|
||||
+ usleep_range(20, 50);
|
||||
+
|
||||
+ /* Reset the switch PHYs */
|
||||
+ mt7530_write(priv, MT7530_SYS_CTRL, SYS_CTRL_PHY_RST);
|
||||
+
|
||||
+ return mt7531_setup_common(ds);
|
||||
+}
|
||||
+
|
||||
const struct dsa_switch_ops mt7530_switch_ops = {
|
||||
.get_tag_protocol = mtk_get_tag_protocol,
|
||||
.setup = mt753x_setup,
|
||||
@@ -3023,6 +3139,17 @@ const struct mt753x_info mt753x_table[]
|
||||
.mac_port_get_caps = mt7531_mac_port_get_caps,
|
||||
.mac_port_config = mt7531_mac_config,
|
||||
},
|
||||
+ [ID_MT7988] = {
|
||||
+ .id = ID_MT7988,
|
||||
+ .pcs_ops = &mt7530_pcs_ops,
|
||||
+ .sw_setup = mt7988_setup,
|
||||
+ .phy_read = mt7531_ind_phy_read,
|
||||
+ .phy_write = mt7531_ind_phy_write,
|
||||
+ .pad_setup = mt7988_pad_setup,
|
||||
+ .cpu_port_config = mt7988_cpu_port_config,
|
||||
+ .mac_port_get_caps = mt7988_mac_port_get_caps,
|
||||
+ .mac_port_config = mt7988_mac_config,
|
||||
+ },
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(mt753x_table);
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -18,6 +18,7 @@ enum mt753x_id {
|
||||
ID_MT7530 = 0,
|
||||
ID_MT7621 = 1,
|
||||
ID_MT7531 = 2,
|
||||
+ ID_MT7988 = 3,
|
||||
};
|
||||
|
||||
#define NUM_TRGMII_CTRL 5
|
||||
@@ -54,11 +55,11 @@ enum mt753x_id {
|
||||
#define MT7531_MIRROR_PORT_SET(x) (((x) & MIRROR_MASK) << 16)
|
||||
#define MT7531_CPU_PMAP_MASK GENMASK(7, 0)
|
||||
|
||||
-#define MT753X_MIRROR_REG(id) (((id) == ID_MT7531) ? \
|
||||
+#define MT753X_MIRROR_REG(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
MT7531_CFC : MT7530_MFC)
|
||||
-#define MT753X_MIRROR_EN(id) (((id) == ID_MT7531) ? \
|
||||
+#define MT753X_MIRROR_EN(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
MT7531_MIRROR_EN : MIRROR_EN)
|
||||
-#define MT753X_MIRROR_MASK(id) (((id) == ID_MT7531) ? \
|
||||
+#define MT753X_MIRROR_MASK(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
MT7531_MIRROR_MASK : MIRROR_MASK)
|
||||
|
||||
/* Registers for BPDU and PAE frame control*/
|
||||
@@ -295,9 +296,8 @@ enum mt7530_vlan_port_acc_frm {
|
||||
MT7531_FORCE_DPX | \
|
||||
MT7531_FORCE_RX_FC | \
|
||||
MT7531_FORCE_TX_FC)
|
||||
-#define PMCR_FORCE_MODE_ID(id) (((id) == ID_MT7531) ? \
|
||||
- MT7531_FORCE_MODE : \
|
||||
- PMCR_FORCE_MODE)
|
||||
+#define PMCR_FORCE_MODE_ID(id) ((((id) == ID_MT7531) || ((id) == ID_MT7988)) ? \
|
||||
+ MT7531_FORCE_MODE : PMCR_FORCE_MODE)
|
||||
#define PMCR_LINK_SETTINGS_MASK (PMCR_TX_EN | PMCR_FORCE_SPEED_1000 | \
|
||||
PMCR_RX_EN | PMCR_FORCE_SPEED_100 | \
|
||||
PMCR_TX_FC_EN | PMCR_RX_FC_EN | \
|
|
@ -0,0 +1,118 @@
|
|||
From 91daa4f62ce878b6e1ac5908aceb83550332447f Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sun, 16 Apr 2023 13:08:14 +0100
|
||||
Subject: [PATCH] net: dsa: mt7530: fix support for MT7531BE
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
There are two variants of the MT7531 switch IC which got different
|
||||
features (and pins) regarding port 5:
|
||||
* MT7531AE: SGMII/1000Base-X/2500Base-X SerDes PCS
|
||||
* MT7531BE: RGMII
|
||||
|
||||
Moving the creation of the SerDes PCS from mt753x_setup to mt7530_probe
|
||||
with commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation
|
||||
to mt7530_probe function") works fine for MT7531AE which got two
|
||||
instances of mtk-pcs-lynxi, however, MT7531BE requires mt7531_pll_setup
|
||||
to setup clocks before the single PCS on port 6 (usually used as CPU
|
||||
port) starts to work and hence the PCS creation failed on MT7531BE.
|
||||
|
||||
Fix this by introducing a pointer to mt7531_create_sgmii function in
|
||||
struct mt7530_priv and call it again at the end of mt753x_setup like it
|
||||
was before commit 6de285229773 ("net: dsa: mt7530: move SGMII PCS
|
||||
creation to mt7530_probe function").
|
||||
|
||||
Fixes: 6de285229773 ("net: dsa: mt7530: move SGMII PCS creation to mt7530_probe function")
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
Acked-by: Arınç ÜNAL <arinc.unal@arinc9.com>
|
||||
Link: https://lore.kernel.org/r/ZDvlLhhqheobUvOK@makrotopia.org
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
---
|
||||
drivers/net/dsa/mt7530-mdio.c | 16 ++++++++--------
|
||||
drivers/net/dsa/mt7530.c | 6 ++++++
|
||||
drivers/net/dsa/mt7530.h | 4 ++--
|
||||
3 files changed, 16 insertions(+), 10 deletions(-)
|
||||
|
||||
--- a/drivers/net/dsa/mt7530-mdio.c
|
||||
+++ b/drivers/net/dsa/mt7530-mdio.c
|
||||
@@ -81,14 +81,17 @@ static const struct regmap_bus mt7530_re
|
||||
};
|
||||
|
||||
static int
|
||||
-mt7531_create_sgmii(struct mt7530_priv *priv)
|
||||
+mt7531_create_sgmii(struct mt7530_priv *priv, bool dual_sgmii)
|
||||
{
|
||||
- struct regmap_config *mt7531_pcs_config[2];
|
||||
+ struct regmap_config *mt7531_pcs_config[2] = {};
|
||||
struct phylink_pcs *pcs;
|
||||
struct regmap *regmap;
|
||||
int i, ret = 0;
|
||||
|
||||
- for (i = 0; i < 2; i++) {
|
||||
+ /* MT7531AE has two SGMII units for port 5 and port 6
|
||||
+ * MT7531BE has only one SGMII unit for port 6
|
||||
+ */
|
||||
+ for (i = dual_sgmii ? 0 : 1; i < 2; i++) {
|
||||
mt7531_pcs_config[i] = devm_kzalloc(priv->dev,
|
||||
sizeof(struct regmap_config),
|
||||
GFP_KERNEL);
|
||||
@@ -208,11 +211,8 @@ mt7530_probe(struct mdio_device *mdiodev
|
||||
if (IS_ERR(priv->regmap))
|
||||
return PTR_ERR(priv->regmap);
|
||||
|
||||
- if (priv->id == ID_MT7531) {
|
||||
- ret = mt7531_create_sgmii(priv);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
- }
|
||||
+ if (priv->id == ID_MT7531)
|
||||
+ priv->create_sgmii = mt7531_create_sgmii;
|
||||
|
||||
return dsa_register_switch(priv->ds);
|
||||
}
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -3017,6 +3017,12 @@ mt753x_setup(struct dsa_switch *ds)
|
||||
if (ret && priv->irq)
|
||||
mt7530_free_irq_common(priv);
|
||||
|
||||
+ if (priv->create_sgmii) {
|
||||
+ ret = priv->create_sgmii(priv, mt7531_dual_sgmii_supported(priv));
|
||||
+ if (ret && priv->irq)
|
||||
+ mt7530_free_irq(priv);
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
--- a/drivers/net/dsa/mt7530.h
|
||||
+++ b/drivers/net/dsa/mt7530.h
|
||||
@@ -741,10 +741,10 @@ struct mt753x_info {
|
||||
* registers
|
||||
* @p6_interface Holding the current port 6 interface
|
||||
* @p5_intf_sel: Holding the current port 5 interface select
|
||||
- *
|
||||
* @irq: IRQ number of the switch
|
||||
* @irq_domain: IRQ domain of the switch irq_chip
|
||||
* @irq_enable: IRQ enable bits, synced to SYS_INT_EN
|
||||
+ * @create_sgmii: Pointer to function creating SGMII PCS instance(s)
|
||||
*/
|
||||
struct mt7530_priv {
|
||||
struct device *dev;
|
||||
@@ -763,7 +763,6 @@ struct mt7530_priv {
|
||||
unsigned int p5_intf_sel;
|
||||
u8 mirror_rx;
|
||||
u8 mirror_tx;
|
||||
-
|
||||
struct mt7530_port ports[MT7530_NUM_PORTS];
|
||||
struct mt753x_pcs pcs[MT7530_NUM_PORTS];
|
||||
/* protect among processes for registers access*/
|
||||
@@ -771,6 +770,7 @@ struct mt7530_priv {
|
||||
int irq;
|
||||
struct irq_domain *irq_domain;
|
||||
u32 irq_enable;
|
||||
+ int (*create_sgmii)(struct mt7530_priv *priv, bool dual_sgmii);
|
||||
};
|
||||
|
||||
struct mt7530_hw_vlan_entry {
|
|
@ -21,7 +21,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
|
|||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -12697,6 +12697,7 @@ F: include/uapi/linux/meye.h
|
||||
@@ -12700,6 +12700,7 @@ F: include/uapi/linux/meye.h
|
||||
|
||||
MOTORCOMM PHY DRIVER
|
||||
M: Peter Geis <pgwipeout@gmail.com>
|
||||
|
|
|
@ -19,7 +19,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -17962,6 +17962,11 @@ L: netdev@vger.kernel.org
|
||||
@@ -17965,6 +17965,11 @@ L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/dlink/sundance.c
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|||
|
||||
--- a/MAINTAINERS
|
||||
+++ b/MAINTAINERS
|
||||
@@ -12361,6 +12361,14 @@ S: Supported
|
||||
@@ -12364,6 +12364,14 @@ S: Supported
|
||||
F: Documentation/devicetree/bindings/mtd/atmel-nand.txt
|
||||
F: drivers/mtd/nand/raw/atmel/*
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
From 348fdbada9fb3f0bf1a53651be46319105af187f Mon Sep 17 00:00:00 2001
|
||||
From 8c20e2eb5f2a0175b774134685e4d7bd93e85ff8 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Wed, 21 Dec 2022 21:18:59 -0700
|
||||
Subject: [PATCH 21/29] mm: multi-gen LRU: rename lru_gen_struct to
|
||||
Subject: [PATCH 01/19] UPSTREAM: mm: multi-gen LRU: rename lru_gen_struct to
|
||||
lru_gen_folio
|
||||
|
||||
Patch series "mm: multi-gen LRU: memcg LRU", v3.
|
||||
|
@ -115,6 +115,10 @@ Cc: Mike Rapoport <rppt@kernel.org>
|
|||
Cc: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
Cc: Suren Baghdasaryan <surenb@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Bug: 274865848
|
||||
(cherry picked from commit 391655fe08d1f942359a11148aa9aaf3f99d6d6f)
|
||||
Change-Id: I7df67e0e2435ba28f10eaa57d28d98b61a9210a6
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
include/linux/mm_inline.h | 4 ++--
|
||||
include/linux/mmzone.h | 6 +++---
|
||||
|
@ -122,9 +126,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
mm/workingset.c | 4 ++--
|
||||
4 files changed, 24 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index e8ed225d8f7ca..f63968bd7de59 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -178,7 +178,7 @@ static inline void lru_gen_update_size(s
|
||||
@@ -178,7 +178,7 @@ static inline void lru_gen_update_size(struct lruvec *lruvec, struct folio *foli
|
||||
int zone = folio_zonenum(folio);
|
||||
int delta = folio_nr_pages(folio);
|
||||
enum lru_list lru = type * LRU_INACTIVE_FILE;
|
||||
|
@ -133,7 +139,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
VM_WARN_ON_ONCE(old_gen != -1 && old_gen >= MAX_NR_GENS);
|
||||
VM_WARN_ON_ONCE(new_gen != -1 && new_gen >= MAX_NR_GENS);
|
||||
@@ -224,7 +224,7 @@ static inline bool lru_gen_add_folio(str
|
||||
@@ -224,7 +224,7 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
|
||||
int gen = folio_lru_gen(folio);
|
||||
int type = folio_is_file_lru(folio);
|
||||
int zone = folio_zonenum(folio);
|
||||
|
@ -142,6 +148,8 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
VM_WARN_ON_ONCE_FOLIO(gen != -1, folio);
|
||||
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index 5f74891556f33..bd3e4689f72dc 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -404,7 +404,7 @@ enum {
|
||||
|
@ -171,9 +179,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
/* to concurrently iterate lru_gen_mm_list */
|
||||
struct lru_gen_mm_state mm_state;
|
||||
#endif
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index d18296109aa7e..27142caf284c1 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3190,7 +3190,7 @@ static int get_nr_gens(struct lruvec *lr
|
||||
@@ -3190,7 +3190,7 @@ static int get_nr_gens(struct lruvec *lruvec, int type)
|
||||
|
||||
static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
|
||||
{
|
||||
|
@ -191,7 +201,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
int hist = lru_hist_from_seq(lrugen->min_seq[type]);
|
||||
|
||||
pos->refaulted = lrugen->avg_refaulted[type][tier] +
|
||||
@@ -3611,7 +3611,7 @@ static void read_ctrl_pos(struct lruvec
|
||||
@@ -3611,7 +3611,7 @@ static void read_ctrl_pos(struct lruvec *lruvec, int type, int tier, int gain,
|
||||
static void reset_ctrl_pos(struct lruvec *lruvec, int type, bool carryover)
|
||||
{
|
||||
int hist, tier;
|
||||
|
@ -200,7 +210,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
bool clear = carryover ? NR_HIST_GENS == 1 : NR_HIST_GENS > 1;
|
||||
unsigned long seq = carryover ? lrugen->min_seq[type] : lrugen->max_seq + 1;
|
||||
|
||||
@@ -3688,7 +3688,7 @@ static int folio_update_gen(struct folio
|
||||
@@ -3688,7 +3688,7 @@ static int folio_update_gen(struct folio *folio, int gen)
|
||||
static int folio_inc_gen(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
|
||||
{
|
||||
int type = folio_is_file_lru(folio);
|
||||
|
@ -209,7 +219,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
|
||||
unsigned long new_flags, old_flags = READ_ONCE(folio->flags);
|
||||
|
||||
@@ -3733,7 +3733,7 @@ static void update_batch_size(struct lru
|
||||
@@ -3733,7 +3733,7 @@ static void update_batch_size(struct lru_gen_mm_walk *walk, struct folio *folio,
|
||||
static void reset_batch_size(struct lruvec *lruvec, struct lru_gen_mm_walk *walk)
|
||||
{
|
||||
int gen, type, zone;
|
||||
|
@ -218,7 +228,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
walk->batched = 0;
|
||||
|
||||
@@ -4253,7 +4253,7 @@ static bool inc_min_seq(struct lruvec *l
|
||||
@@ -4250,7 +4250,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap)
|
||||
{
|
||||
int zone;
|
||||
int remaining = MAX_LRU_BATCH;
|
||||
|
@ -227,7 +237,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
int new_gen, old_gen = lru_gen_from_seq(lrugen->min_seq[type]);
|
||||
|
||||
if (type == LRU_GEN_ANON && !can_swap)
|
||||
@@ -4289,7 +4289,7 @@ static bool try_to_inc_min_seq(struct lr
|
||||
@@ -4286,7 +4286,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
|
||||
{
|
||||
int gen, type, zone;
|
||||
bool success = false;
|
||||
|
@ -236,7 +246,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
DEFINE_MIN_SEQ(lruvec);
|
||||
|
||||
VM_WARN_ON_ONCE(!seq_is_valid(lruvec));
|
||||
@@ -4310,7 +4310,7 @@ next:
|
||||
@@ -4307,7 +4307,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -245,7 +255,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
if (can_swap) {
|
||||
min_seq[LRU_GEN_ANON] = min(min_seq[LRU_GEN_ANON], min_seq[LRU_GEN_FILE]);
|
||||
min_seq[LRU_GEN_FILE] = max(min_seq[LRU_GEN_ANON], lrugen->min_seq[LRU_GEN_FILE]);
|
||||
@@ -4332,7 +4332,7 @@ static void inc_max_seq(struct lruvec *l
|
||||
@@ -4329,7 +4329,7 @@ static void inc_max_seq(struct lruvec *lruvec, bool can_swap, bool force_scan)
|
||||
{
|
||||
int prev, next;
|
||||
int type, zone;
|
||||
|
@ -254,7 +264,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
spin_lock_irq(&lruvec->lru_lock);
|
||||
|
||||
@@ -4390,7 +4390,7 @@ static bool try_to_inc_max_seq(struct lr
|
||||
@@ -4387,7 +4387,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
bool success;
|
||||
struct lru_gen_mm_walk *walk;
|
||||
struct mm_struct *mm = NULL;
|
||||
|
@ -263,7 +273,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
VM_WARN_ON_ONCE(max_seq > READ_ONCE(lrugen->max_seq));
|
||||
|
||||
@@ -4455,7 +4455,7 @@ static bool should_run_aging(struct lruv
|
||||
@@ -4452,7 +4452,7 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
|
||||
unsigned long old = 0;
|
||||
unsigned long young = 0;
|
||||
unsigned long total = 0;
|
||||
|
@ -272,7 +282,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
|
||||
for (type = !can_swap; type < ANON_AND_FILE; type++) {
|
||||
@@ -4740,7 +4740,7 @@ static bool sort_folio(struct lruvec *lr
|
||||
@@ -4737,7 +4737,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
|
||||
int delta = folio_nr_pages(folio);
|
||||
int refs = folio_lru_refs(folio);
|
||||
int tier = lru_tier_from_refs(refs);
|
||||
|
@ -281,7 +291,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
VM_WARN_ON_ONCE_FOLIO(gen >= MAX_NR_GENS, folio);
|
||||
|
||||
@@ -4840,7 +4840,7 @@ static int scan_folios(struct lruvec *lr
|
||||
@@ -4837,7 +4837,7 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
|
||||
int scanned = 0;
|
||||
int isolated = 0;
|
||||
int remaining = MAX_LRU_BATCH;
|
||||
|
@ -290,7 +300,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
|
||||
VM_WARN_ON_ONCE(!list_empty(list));
|
||||
@@ -5240,7 +5240,7 @@ done:
|
||||
@@ -5237,7 +5237,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
|
||||
static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
|
||||
{
|
||||
|
@ -299,7 +309,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
if (lrugen->enabled) {
|
||||
enum lru_list lru;
|
||||
@@ -5522,7 +5522,7 @@ static void lru_gen_seq_show_full(struct
|
||||
@@ -5519,7 +5519,7 @@ static void lru_gen_seq_show_full(struct seq_file *m, struct lruvec *lruvec,
|
||||
int i;
|
||||
int type, tier;
|
||||
int hist = lru_hist_from_seq(seq);
|
||||
|
@ -308,7 +318,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
for (tier = 0; tier < MAX_NR_TIERS; tier++) {
|
||||
seq_printf(m, " %10d", tier);
|
||||
@@ -5572,7 +5572,7 @@ static int lru_gen_seq_show(struct seq_f
|
||||
@@ -5569,7 +5569,7 @@ static int lru_gen_seq_show(struct seq_file *m, void *v)
|
||||
unsigned long seq;
|
||||
bool full = !debugfs_real_fops(m->file)->write;
|
||||
struct lruvec *lruvec = v;
|
||||
|
@ -317,7 +327,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
int nid = lruvec_pgdat(lruvec)->node_id;
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
DEFINE_MAX_SEQ(lruvec);
|
||||
@@ -5826,7 +5826,7 @@ void lru_gen_init_lruvec(struct lruvec *
|
||||
@@ -5823,7 +5823,7 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
|
||||
{
|
||||
int i;
|
||||
int gen, type, zone;
|
||||
|
@ -326,9 +336,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
lrugen->max_seq = MIN_NR_GENS + 1;
|
||||
lrugen->enabled = lru_gen_enabled();
|
||||
diff --git a/mm/workingset.c b/mm/workingset.c
|
||||
index ae7e984b23c6b..688aaa73f64e8 100644
|
||||
--- a/mm/workingset.c
|
||||
+++ b/mm/workingset.c
|
||||
@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct fol
|
||||
@@ -223,7 +223,7 @@ static void *lru_gen_eviction(struct folio *folio)
|
||||
unsigned long token;
|
||||
unsigned long min_seq;
|
||||
struct lruvec *lruvec;
|
||||
|
@ -337,7 +349,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
int type = folio_is_file_lru(folio);
|
||||
int delta = folio_nr_pages(folio);
|
||||
int refs = folio_lru_refs(folio);
|
||||
@@ -252,7 +252,7 @@ static void lru_gen_refault(struct folio
|
||||
@@ -252,7 +252,7 @@ static void lru_gen_refault(struct folio *folio, void *shadow)
|
||||
unsigned long token;
|
||||
unsigned long min_seq;
|
||||
struct lruvec *lruvec;
|
||||
|
@ -346,3 +358,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
struct mem_cgroup *memcg;
|
||||
struct pglist_data *pgdat;
|
||||
int type = folio_is_file_lru(folio);
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
From afd37e73db04c7e6b47411120ac5f6a7eca51fec Mon Sep 17 00:00:00 2001
|
||||
From 656287d55d9cfc72a4bcd4d9bd098570f12ce409 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Wed, 21 Dec 2022 21:19:00 -0700
|
||||
Subject: [PATCH 22/29] mm: multi-gen LRU: rename lrugen->lists[] to
|
||||
Subject: [PATCH 02/19] UPSTREAM: mm: multi-gen LRU: rename lrugen->lists[] to
|
||||
lrugen->folios[]
|
||||
|
||||
lru_gen_folio will be chained into per-node lists by the coming
|
||||
|
@ -17,15 +17,54 @@ Cc: Mike Rapoport <rppt@kernel.org>
|
|||
Cc: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
Cc: Suren Baghdasaryan <surenb@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Bug: 274865848
|
||||
(cherry picked from commit 6df1b2212950aae2b2188c6645ea18e2a9e3fdd5)
|
||||
Change-Id: I09f53e0fb2cd6b8b3adbb8a80b15dc5efbeae857
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
Documentation/mm/multigen_lru.rst | 8 ++++----
|
||||
include/linux/mm_inline.h | 4 ++--
|
||||
include/linux/mmzone.h | 8 ++++----
|
||||
mm/vmscan.c | 20 ++++++++++----------
|
||||
3 files changed, 16 insertions(+), 16 deletions(-)
|
||||
4 files changed, 20 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
|
||||
index d7062c6a89464..d8f721f98868a 100644
|
||||
--- a/Documentation/mm/multigen_lru.rst
|
||||
+++ b/Documentation/mm/multigen_lru.rst
|
||||
@@ -89,15 +89,15 @@ variables are monotonically increasing.
|
||||
|
||||
Generation numbers are truncated into ``order_base_2(MAX_NR_GENS+1)``
|
||||
bits in order to fit into the gen counter in ``folio->flags``. Each
|
||||
-truncated generation number is an index to ``lrugen->lists[]``. The
|
||||
+truncated generation number is an index to ``lrugen->folios[]``. The
|
||||
sliding window technique is used to track at least ``MIN_NR_GENS`` and
|
||||
at most ``MAX_NR_GENS`` generations. The gen counter stores a value
|
||||
within ``[1, MAX_NR_GENS]`` while a page is on one of
|
||||
-``lrugen->lists[]``; otherwise it stores zero.
|
||||
+``lrugen->folios[]``; otherwise it stores zero.
|
||||
|
||||
Each generation is divided into multiple tiers. A page accessed ``N``
|
||||
times through file descriptors is in tier ``order_base_2(N)``. Unlike
|
||||
-generations, tiers do not have dedicated ``lrugen->lists[]``. In
|
||||
+generations, tiers do not have dedicated ``lrugen->folios[]``. In
|
||||
contrast to moving across generations, which requires the LRU lock,
|
||||
moving across tiers only involves atomic operations on
|
||||
``folio->flags`` and therefore has a negligible cost. A feedback loop
|
||||
@@ -127,7 +127,7 @@ page mapped by this PTE to ``(max_seq%MAX_NR_GENS)+1``.
|
||||
Eviction
|
||||
--------
|
||||
The eviction consumes old generations. Given an ``lruvec``, it
|
||||
-increments ``min_seq`` when ``lrugen->lists[]`` indexed by
|
||||
+increments ``min_seq`` when ``lrugen->folios[]`` indexed by
|
||||
``min_seq%MAX_NR_GENS`` becomes empty. To select a type and a tier to
|
||||
evict from, it first compares ``min_seq[]`` to select the older type.
|
||||
If both types are equally old, it selects the one whose first tier has
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index f63968bd7de59..da38e3d962e2f 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -256,9 +256,9 @@ static inline bool lru_gen_add_folio(str
|
||||
@@ -256,9 +256,9 @@ static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio,
|
||||
lru_gen_update_size(lruvec, folio, -1, gen);
|
||||
/* for folio_rotate_reclaimable() */
|
||||
if (reclaiming)
|
||||
|
@ -37,6 +76,8 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
return true;
|
||||
}
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index bd3e4689f72dc..02e4323744715 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -312,7 +312,7 @@ enum lruvec_flags {
|
||||
|
@ -68,9 +109,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
/* the multi-gen LRU sizes, eventually consistent */
|
||||
long nr_pages[MAX_NR_GENS][ANON_AND_FILE][MAX_NR_ZONES];
|
||||
/* the exponential moving average of refaulted */
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 27142caf284c1..b02fed912f742 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4261,7 +4261,7 @@ static bool inc_min_seq(struct lruvec *l
|
||||
@@ -4258,7 +4258,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap)
|
||||
|
||||
/* prevent cold/hot inversion if force_scan is true */
|
||||
for (zone = 0; zone < MAX_NR_ZONES; zone++) {
|
||||
|
@ -79,7 +122,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
while (!list_empty(head)) {
|
||||
struct folio *folio = lru_to_folio(head);
|
||||
@@ -4272,7 +4272,7 @@ static bool inc_min_seq(struct lruvec *l
|
||||
@@ -4269,7 +4269,7 @@ static bool inc_min_seq(struct lruvec *lruvec, int type, bool can_swap)
|
||||
VM_WARN_ON_ONCE_FOLIO(folio_zonenum(folio) != zone, folio);
|
||||
|
||||
new_gen = folio_inc_gen(lruvec, folio, false);
|
||||
|
@ -88,7 +131,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
if (!--remaining)
|
||||
return false;
|
||||
@@ -4300,7 +4300,7 @@ static bool try_to_inc_min_seq(struct lr
|
||||
@@ -4297,7 +4297,7 @@ static bool try_to_inc_min_seq(struct lruvec *lruvec, bool can_swap)
|
||||
gen = lru_gen_from_seq(min_seq[type]);
|
||||
|
||||
for (zone = 0; zone < MAX_NR_ZONES; zone++) {
|
||||
|
@ -97,7 +140,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
goto next;
|
||||
}
|
||||
|
||||
@@ -4765,7 +4765,7 @@ static bool sort_folio(struct lruvec *lr
|
||||
@@ -4762,7 +4762,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
|
||||
|
||||
/* promoted */
|
||||
if (gen != lru_gen_from_seq(lrugen->min_seq[type])) {
|
||||
|
@ -106,7 +149,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
return true;
|
||||
}
|
||||
|
||||
@@ -4774,7 +4774,7 @@ static bool sort_folio(struct lruvec *lr
|
||||
@@ -4771,7 +4771,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
|
||||
int hist = lru_hist_from_seq(lrugen->min_seq[type]);
|
||||
|
||||
gen = folio_inc_gen(lruvec, folio, false);
|
||||
|
@ -115,7 +158,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
WRITE_ONCE(lrugen->protected[hist][type][tier - 1],
|
||||
lrugen->protected[hist][type][tier - 1] + delta);
|
||||
@@ -4786,7 +4786,7 @@ static bool sort_folio(struct lruvec *lr
|
||||
@@ -4783,7 +4783,7 @@ static bool sort_folio(struct lruvec *lruvec, struct folio *folio, int tier_idx)
|
||||
if (folio_test_locked(folio) || folio_test_writeback(folio) ||
|
||||
(type == LRU_GEN_FILE && folio_test_dirty(folio))) {
|
||||
gen = folio_inc_gen(lruvec, folio, true);
|
||||
|
@ -124,7 +167,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
return true;
|
||||
}
|
||||
|
||||
@@ -4853,7 +4853,7 @@ static int scan_folios(struct lruvec *lr
|
||||
@@ -4850,7 +4850,7 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
|
||||
for (zone = sc->reclaim_idx; zone >= 0; zone--) {
|
||||
LIST_HEAD(moved);
|
||||
int skipped = 0;
|
||||
|
@ -133,7 +176,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
while (!list_empty(head)) {
|
||||
struct folio *folio = lru_to_folio(head);
|
||||
@@ -5253,7 +5253,7 @@ static bool __maybe_unused state_is_vali
|
||||
@@ -5250,7 +5250,7 @@ static bool __maybe_unused state_is_valid(struct lruvec *lruvec)
|
||||
int gen, type, zone;
|
||||
|
||||
for_each_gen_type_zone(gen, type, zone) {
|
||||
|
@ -142,7 +185,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
return false;
|
||||
}
|
||||
}
|
||||
@@ -5298,7 +5298,7 @@ static bool drain_evictable(struct lruve
|
||||
@@ -5295,7 +5295,7 @@ static bool drain_evictable(struct lruvec *lruvec)
|
||||
int remaining = MAX_LRU_BATCH;
|
||||
|
||||
for_each_gen_type_zone(gen, type, zone) {
|
||||
|
@ -151,7 +194,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
while (!list_empty(head)) {
|
||||
bool success;
|
||||
@@ -5835,7 +5835,7 @@ void lru_gen_init_lruvec(struct lruvec *
|
||||
@@ -5832,7 +5832,7 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
|
||||
lrugen->timestamps[i] = jiffies;
|
||||
|
||||
for_each_gen_type_zone(gen, type, zone)
|
||||
|
@ -160,3 +203,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
lruvec->mm_state.seq = MIN_NR_GENS;
|
||||
init_waitqueue_head(&lruvec->mm_state.wait);
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
From ce45f1c4b32cf69b166f56ef5bc6c761e06ed4e5 Mon Sep 17 00:00:00 2001
|
||||
From 14f9a7a15f3d1af351f30e0438fd747b7ac253b0 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Wed, 21 Dec 2022 21:19:01 -0700
|
||||
Subject: [PATCH 23/29] mm: multi-gen LRU: remove eviction fairness safeguard
|
||||
Subject: [PATCH 03/19] UPSTREAM: mm: multi-gen LRU: remove eviction fairness
|
||||
safeguard
|
||||
|
||||
Recall that the eviction consumes the oldest generation: first it
|
||||
bucket-sorts folios whose gen counters were updated by the aging and
|
||||
|
@ -31,13 +32,19 @@ Cc: Mike Rapoport <rppt@kernel.org>
|
|||
Cc: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
Cc: Suren Baghdasaryan <surenb@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Bug: 274865848
|
||||
(cherry picked from commit a579086c99ed70cc4bfc104348dbe3dd8f2787e6)
|
||||
Change-Id: I08ac1b3c90e29cafd0566785aaa4bcdb5db7d22c
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
mm/vmscan.c | 82 +++++++++++++++--------------------------------------
|
||||
1 file changed, 23 insertions(+), 59 deletions(-)
|
||||
mm/vmscan.c | 81 +++++++++++++++--------------------------------------
|
||||
1 file changed, 23 insertions(+), 58 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index b02fed912f742..991961180b320 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -448,6 +448,11 @@ static bool cgroup_reclaim(struct scan_c
|
||||
@@ -448,6 +448,11 @@ static bool cgroup_reclaim(struct scan_control *sc)
|
||||
return sc->target_mem_cgroup;
|
||||
}
|
||||
|
||||
|
@ -49,7 +56,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
/**
|
||||
* writeback_throttling_sane - is the usual dirty throttling mechanism available?
|
||||
* @sc: scan_control in question
|
||||
@@ -498,6 +503,11 @@ static bool cgroup_reclaim(struct scan_c
|
||||
@@ -498,6 +503,11 @@ static bool cgroup_reclaim(struct scan_control *sc)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -61,7 +68,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
static bool writeback_throttling_sane(struct scan_control *sc)
|
||||
{
|
||||
return true;
|
||||
@@ -4996,8 +5006,7 @@ static int isolate_folios(struct lruvec
|
||||
@@ -4993,8 +5003,7 @@ static int isolate_folios(struct lruvec *lruvec, struct scan_control *sc, int sw
|
||||
return scanned;
|
||||
}
|
||||
|
||||
|
@ -71,7 +78,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
{
|
||||
int type;
|
||||
int scanned;
|
||||
@@ -5086,9 +5095,6 @@ retry:
|
||||
@@ -5083,9 +5092,6 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap
|
||||
goto retry;
|
||||
}
|
||||
|
||||
|
@ -81,7 +88,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
return scanned;
|
||||
}
|
||||
|
||||
@@ -5127,67 +5133,26 @@ done:
|
||||
@@ -5124,67 +5130,26 @@ static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *
|
||||
return min_seq[!can_swap] + MIN_NR_GENS <= max_seq ? nr_to_scan : 0;
|
||||
}
|
||||
|
||||
|
@ -158,7 +165,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
lru_add_drain();
|
||||
|
||||
@@ -5211,7 +5176,7 @@ static void lru_gen_shrink_lruvec(struct
|
||||
@@ -5208,7 +5173,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
if (!nr_to_scan)
|
||||
goto done;
|
||||
|
||||
|
@ -167,7 +174,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
if (!delta)
|
||||
goto done;
|
||||
|
||||
@@ -5219,7 +5184,7 @@ static void lru_gen_shrink_lruvec(struct
|
||||
@@ -5216,7 +5181,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
if (scanned >= nr_to_scan)
|
||||
break;
|
||||
|
||||
|
@ -176,7 +183,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
break;
|
||||
|
||||
cond_resched();
|
||||
@@ -5669,7 +5634,7 @@ static int run_eviction(struct lruvec *l
|
||||
@@ -5666,7 +5631,7 @@ static int run_eviction(struct lruvec *lruvec, unsigned long seq, struct scan_co
|
||||
if (sc->nr_reclaimed >= nr_to_reclaim)
|
||||
return 0;
|
||||
|
||||
|
@ -185,3 +192,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
return 0;
|
||||
|
||||
cond_resched();
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
From e20b7386fccc18c791796eb1dc1a91eee3ccf801 Mon Sep 17 00:00:00 2001
|
||||
From f3c93d2e37a3c56593d7ccf4f4bcf1b58426fdd8 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Wed, 21 Dec 2022 21:19:02 -0700
|
||||
Subject: [PATCH 24/29] mm: multi-gen LRU: remove aging fairness safeguard
|
||||
Subject: [PATCH 04/19] BACKPORT: mm: multi-gen LRU: remove aging fairness
|
||||
safeguard
|
||||
|
||||
Recall that the aging produces the youngest generation: first it scans
|
||||
for accessed folios and updates their gen counters; then it increments
|
||||
|
@ -31,10 +32,18 @@ Cc: Mike Rapoport <rppt@kernel.org>
|
|||
Cc: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
Cc: Suren Baghdasaryan <surenb@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Bug: 274865848
|
||||
(cherry picked from commit 7348cc91821b0cb24dfb00e578047f68299a50ab)
|
||||
[TJ: Resolved conflicts with older function signatures for
|
||||
min_cgroup_below_min / min_cgroup_below_low]
|
||||
Change-Id: I6e36ecfbaaefbc0a56d9a9d5d7cbe404ed7f57a5
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
mm/vmscan.c | 126 ++++++++++++++++++++++++----------------------------
|
||||
1 file changed, 59 insertions(+), 67 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 991961180b320..5a2e83e673232 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -136,7 +136,6 @@ struct scan_control {
|
||||
|
@ -45,7 +54,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
unsigned long last_reclaimed;
|
||||
#endif
|
||||
|
||||
@@ -4458,7 +4457,7 @@ done:
|
||||
@@ -4455,7 +4454,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -54,7 +63,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
struct scan_control *sc, bool can_swap, unsigned long *nr_to_scan)
|
||||
{
|
||||
int gen, type, zone;
|
||||
@@ -4467,6 +4466,13 @@ static bool should_run_aging(struct lruv
|
||||
@@ -4464,6 +4463,13 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
|
||||
unsigned long total = 0;
|
||||
struct lru_gen_folio *lrugen = &lruvec->lrugen;
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
|
@ -68,7 +77,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
for (type = !can_swap; type < ANON_AND_FILE; type++) {
|
||||
unsigned long seq;
|
||||
@@ -4495,8 +4501,6 @@ static bool should_run_aging(struct lruv
|
||||
@@ -4492,8 +4498,6 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
|
||||
* stalls when the number of generations reaches MIN_NR_GENS. Hence, the
|
||||
* ideal number of generations is MIN_NR_GENS+1.
|
||||
*/
|
||||
|
@ -77,7 +86,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
if (min_seq[!can_swap] + MIN_NR_GENS < max_seq)
|
||||
return false;
|
||||
|
||||
@@ -4515,40 +4519,54 @@ static bool should_run_aging(struct lruv
|
||||
@@ -4512,40 +4516,54 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq, unsig
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -153,7 +162,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
}
|
||||
|
||||
/* to protect the working set of the last N jiffies */
|
||||
@@ -4557,46 +4575,32 @@ static unsigned long lru_gen_min_ttl __r
|
||||
@@ -4554,46 +4572,32 @@ static unsigned long lru_gen_min_ttl __read_mostly;
|
||||
static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
{
|
||||
struct mem_cgroup *memcg;
|
||||
|
@ -207,7 +216,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
*/
|
||||
if (mutex_trylock(&oom_lock)) {
|
||||
struct oom_control oc = {
|
||||
@@ -5104,33 +5108,27 @@ retry:
|
||||
@@ -5101,33 +5105,27 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap
|
||||
* reclaim.
|
||||
*/
|
||||
static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc,
|
||||
|
@ -247,7 +256,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
}
|
||||
|
||||
static unsigned long get_nr_to_reclaim(struct scan_control *sc)
|
||||
@@ -5149,9 +5147,7 @@ static unsigned long get_nr_to_reclaim(s
|
||||
@@ -5146,9 +5144,7 @@ static unsigned long get_nr_to_reclaim(struct scan_control *sc)
|
||||
static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|
||||
{
|
||||
struct blk_plug plug;
|
||||
|
@ -257,7 +266,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
|
||||
|
||||
lru_add_drain();
|
||||
@@ -5172,13 +5168,13 @@ static void lru_gen_shrink_lruvec(struct
|
||||
@@ -5169,13 +5165,13 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
else
|
||||
swappiness = 0;
|
||||
|
||||
|
@ -274,7 +283,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
scanned += delta;
|
||||
if (scanned >= nr_to_scan)
|
||||
@@ -5190,10 +5186,6 @@ static void lru_gen_shrink_lruvec(struct
|
||||
@@ -5187,10 +5183,6 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
|
@ -285,3 +294,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
clear_mm_walk();
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,12 +1,11 @@
|
|||
From 107d54931df3c28d81648122e219bf0034ef4e99 Mon Sep 17 00:00:00 2001
|
||||
From eca3858631e0cbad2ca6e40f788892749428e4cb Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Wed, 21 Dec 2022 21:19:03 -0700
|
||||
Subject: [PATCH 25/29] mm: multi-gen LRU: shuffle should_run_aging()
|
||||
Subject: [PATCH 05/19] UPSTREAM: mm: multi-gen LRU: shuffle should_run_aging()
|
||||
|
||||
Move should_run_aging() next to its only caller left.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20221222041905.2431096-6-yuzhao@google.com
|
||||
Signed-off-by: Yu Zhao <yuzhao@google.com>
|
||||
Cc: Johannes Weiner <hannes@cmpxchg.org>
|
||||
Cc: Jonathan Corbet <corbet@lwn.net>
|
||||
Cc: Michael Larabel <Michael@MichaelLarabel.com>
|
||||
|
@ -15,13 +14,21 @@ Cc: Mike Rapoport <rppt@kernel.org>
|
|||
Cc: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
Cc: Suren Baghdasaryan <surenb@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Bug: 274865848
|
||||
(cherry picked from commit 77d4459a4a1a472b7309e475f962dda87d950abd)
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
Change-Id: I3b0383fe16b93a783b4d8c0b3a0b325160392576
|
||||
Signed-off-by: Yu Zhao <yuzhao@google.com>
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
mm/vmscan.c | 124 ++++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 62 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 5a2e83e673232..0c47952714b26 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4457,68 +4457,6 @@ done:
|
||||
@@ -4454,68 +4454,6 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -90,7 +97,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
|
||||
{
|
||||
int gen, type, zone;
|
||||
@@ -5102,6 +5040,68 @@ retry:
|
||||
@@ -5099,6 +5037,68 @@ static int evict_folios(struct lruvec *lruvec, struct scan_control *sc, int swap
|
||||
return scanned;
|
||||
}
|
||||
|
||||
|
@ -159,3 +166,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
/*
|
||||
* For future optimizations:
|
||||
* 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
From fa6363828d314e837c5f79e97ea5e8c0d2f7f062 Mon Sep 17 00:00:00 2001
|
||||
From 8ee8571e47aa75221e5fbd4c9c7802fc4244c346 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Wed, 21 Dec 2022 21:19:04 -0700
|
||||
Subject: [PATCH 26/29] mm: multi-gen LRU: per-node lru_gen_folio lists
|
||||
Subject: [PATCH 06/19] BACKPORT: mm: multi-gen LRU: per-node lru_gen_folio
|
||||
lists
|
||||
|
||||
For each node, memcgs are divided into two generations: the old and
|
||||
the young. For each generation, memcgs are randomly sharded into
|
||||
|
@ -58,18 +59,26 @@ Cc: Mike Rapoport <rppt@kernel.org>
|
|||
Cc: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
Cc: Suren Baghdasaryan <surenb@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Bug: 274865848
|
||||
(cherry picked from commit e4dde56cd208674ce899b47589f263499e5b8cdc)
|
||||
[TJ: Resolved conflicts with older function signatures for
|
||||
min_cgroup_below_min / min_cgroup_below_low and includes]
|
||||
Change-Id: Idc8a0f635e035d72dd911f807d1224cb47cbd655
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
include/linux/memcontrol.h | 10 +
|
||||
include/linux/mm_inline.h | 17 ++
|
||||
include/linux/mmzone.h | 117 +++++++++++-
|
||||
mm/memcontrol.c | 16 ++
|
||||
mm/folio_alloc.c | 1 +
|
||||
mm/vmscan.c | 373 +++++++++++++++++++++++++++++++++----
|
||||
6 files changed, 499 insertions(+), 35 deletions(-)
|
||||
mm/page_alloc.c | 1 +
|
||||
mm/vmscan.c | 374 +++++++++++++++++++++++++++++++++----
|
||||
6 files changed, 500 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
|
||||
index e039763029563..82d28b052a9e5 100644
|
||||
--- a/include/linux/memcontrol.h
|
||||
+++ b/include/linux/memcontrol.h
|
||||
@@ -790,6 +790,11 @@ static inline void obj_cgroup_put(struct
|
||||
@@ -790,6 +790,11 @@ static inline void obj_cgroup_put(struct obj_cgroup *objcg)
|
||||
percpu_ref_put(&objcg->refcnt);
|
||||
}
|
||||
|
||||
|
@ -81,7 +90,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
static inline void mem_cgroup_put(struct mem_cgroup *memcg)
|
||||
{
|
||||
if (memcg)
|
||||
@@ -1290,6 +1295,11 @@ static inline void obj_cgroup_put(struct
|
||||
@@ -1290,6 +1295,11 @@ static inline void obj_cgroup_put(struct obj_cgroup *objcg)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -93,9 +102,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
static inline void mem_cgroup_put(struct mem_cgroup *memcg)
|
||||
{
|
||||
}
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index da38e3d962e2f..c1fd3922dc5dd 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -122,6 +122,18 @@ static inline bool lru_gen_in_fault(void
|
||||
@@ -122,6 +122,18 @@ static inline bool lru_gen_in_fault(void)
|
||||
return current->in_lru_fault;
|
||||
}
|
||||
|
||||
|
@ -114,7 +125,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
static inline int lru_gen_from_seq(unsigned long seq)
|
||||
{
|
||||
return seq % MAX_NR_GENS;
|
||||
@@ -297,6 +309,11 @@ static inline bool lru_gen_in_fault(void
|
||||
@@ -297,6 +309,11 @@ static inline bool lru_gen_in_fault(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -126,6 +137,8 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
|
||||
{
|
||||
return false;
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index 02e4323744715..66e067a635682 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -7,6 +7,7 @@
|
||||
|
@ -167,7 +180,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
};
|
||||
|
||||
enum {
|
||||
@@ -479,12 +497,87 @@ void lru_gen_init_lruvec(struct lruvec *
|
||||
@@ -479,12 +497,87 @@ void lru_gen_init_lruvec(struct lruvec *lruvec);
|
||||
void lru_gen_look_around(struct page_vma_mapped_walk *pvmw);
|
||||
|
||||
#ifdef CONFIG_MEMCG
|
||||
|
@ -256,7 +269,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
static inline void lru_gen_init_lruvec(struct lruvec *lruvec)
|
||||
{
|
||||
}
|
||||
@@ -494,6 +587,7 @@ static inline void lru_gen_look_around(s
|
||||
@@ -494,6 +587,7 @@ static inline void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMCG
|
||||
|
@ -264,7 +277,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
|
||||
{
|
||||
}
|
||||
@@ -501,7 +595,24 @@ static inline void lru_gen_init_memcg(st
|
||||
@@ -501,7 +595,24 @@ static inline void lru_gen_init_memcg(struct mem_cgroup *memcg)
|
||||
static inline void lru_gen_exit_memcg(struct mem_cgroup *memcg)
|
||||
{
|
||||
}
|
||||
|
@ -299,9 +312,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
#endif
|
||||
|
||||
CACHELINE_PADDING(_pad2_);
|
||||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
|
||||
index 3e8f1ad0fe9db..7815d556e38cc 100644
|
||||
--- a/mm/memcontrol.c
|
||||
+++ b/mm/memcontrol.c
|
||||
@@ -477,6 +477,16 @@ static void mem_cgroup_update_tree(struc
|
||||
@@ -477,6 +477,16 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, int nid)
|
||||
struct mem_cgroup_per_node *mz;
|
||||
struct mem_cgroup_tree_per_node *mctz;
|
||||
|
||||
|
@ -318,7 +333,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
mctz = soft_limit_tree.rb_tree_per_node[nid];
|
||||
if (!mctz)
|
||||
return;
|
||||
@@ -3522,6 +3532,9 @@ unsigned long mem_cgroup_soft_limit_recl
|
||||
@@ -3522,6 +3532,9 @@ unsigned long mem_cgroup_soft_limit_reclaim(pg_data_t *pgdat, int order,
|
||||
struct mem_cgroup_tree_per_node *mctz;
|
||||
unsigned long excess;
|
||||
|
||||
|
@ -328,7 +343,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
if (order > 0)
|
||||
return 0;
|
||||
|
||||
@@ -5382,6 +5395,7 @@ static int mem_cgroup_css_online(struct
|
||||
@@ -5382,6 +5395,7 @@ static int mem_cgroup_css_online(struct cgroup_subsys_state *css)
|
||||
if (unlikely(mem_cgroup_is_root(memcg)))
|
||||
queue_delayed_work(system_unbound_wq, &stats_flush_dwork,
|
||||
2UL*HZ);
|
||||
|
@ -336,7 +351,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
return 0;
|
||||
offline_kmem:
|
||||
memcg_offline_kmem(memcg);
|
||||
@@ -5413,6 +5427,7 @@ static void mem_cgroup_css_offline(struc
|
||||
@@ -5413,6 +5427,7 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
|
||||
memcg_offline_kmem(memcg);
|
||||
reparent_shrinker_deferred(memcg);
|
||||
wb_memcg_offline(memcg);
|
||||
|
@ -344,7 +359,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
drain_all_stock(memcg);
|
||||
|
||||
@@ -5424,6 +5439,7 @@ static void mem_cgroup_css_released(stru
|
||||
@@ -5424,6 +5439,7 @@ static void mem_cgroup_css_released(struct cgroup_subsys_state *css)
|
||||
struct mem_cgroup *memcg = mem_cgroup_from_css(css);
|
||||
|
||||
invalidate_reclaim_iterators(memcg);
|
||||
|
@ -352,9 +367,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
}
|
||||
|
||||
static void mem_cgroup_css_free(struct cgroup_subsys_state *css)
|
||||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
|
||||
index 69668817fed37..473057b81a9df 100644
|
||||
--- a/mm/page_alloc.c
|
||||
+++ b/mm/page_alloc.c
|
||||
@@ -7957,6 +7957,7 @@ static void __init free_area_init_node(i
|
||||
@@ -7957,6 +7957,7 @@ static void __init free_area_init_node(int nid)
|
||||
pgdat_set_deferred_range(pgdat);
|
||||
|
||||
free_area_init_core(pgdat);
|
||||
|
@ -362,6 +379,8 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
}
|
||||
|
||||
static void __init free_area_init_memoryless_node(int nid)
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 0c47952714b26..65eb28448f216 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -54,6 +54,8 @@
|
||||
|
@ -385,7 +404,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
/* Allocation order */
|
||||
s8 order;
|
||||
|
||||
@@ -3160,6 +3157,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_ca
|
||||
@@ -3160,6 +3157,9 @@ DEFINE_STATIC_KEY_ARRAY_FALSE(lru_gen_caps, NR_LRU_GEN_CAPS);
|
||||
for ((type) = 0; (type) < ANON_AND_FILE; (type)++) \
|
||||
for ((zone) = 0; (zone) < MAX_NR_ZONES; (zone)++)
|
||||
|
||||
|
@ -395,7 +414,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
static struct lruvec *get_lruvec(struct mem_cgroup *memcg, int nid)
|
||||
{
|
||||
struct pglist_data *pgdat = NODE_DATA(nid);
|
||||
@@ -4443,8 +4443,7 @@ done:
|
||||
@@ -4440,8 +4440,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
if (sc->priority <= DEF_PRIORITY - 2)
|
||||
wait_event_killable(lruvec->mm_state.wait,
|
||||
max_seq < READ_ONCE(lrugen->max_seq));
|
||||
|
@ -405,7 +424,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
}
|
||||
|
||||
VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
|
||||
@@ -4517,8 +4516,6 @@ static void lru_gen_age_node(struct pgli
|
||||
@@ -4514,8 +4513,6 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
|
||||
VM_WARN_ON_ONCE(!current_is_kswapd());
|
||||
|
||||
|
@ -414,7 +433,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
/* check the order to exclude compaction-induced reclaim */
|
||||
if (!min_ttl || sc->order || sc->priority == DEF_PRIORITY)
|
||||
return;
|
||||
@@ -5107,8 +5104,7 @@ static bool should_run_aging(struct lruv
|
||||
@@ -5104,8 +5101,7 @@ static bool should_run_aging(struct lruvec *lruvec, unsigned long max_seq,
|
||||
* 1. Defer try_to_inc_max_seq() to workqueues to reduce latency for memcg
|
||||
* reclaim.
|
||||
*/
|
||||
|
@ -424,7 +443,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
{
|
||||
unsigned long nr_to_scan;
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
@@ -5125,10 +5121,8 @@ static unsigned long get_nr_to_scan(stru
|
||||
@@ -5122,10 +5118,8 @@ static unsigned long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *
|
||||
if (sc->priority == DEF_PRIORITY)
|
||||
return nr_to_scan;
|
||||
|
||||
|
@ -436,7 +455,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
}
|
||||
|
||||
static unsigned long get_nr_to_reclaim(struct scan_control *sc)
|
||||
@@ -5137,29 +5131,18 @@ static unsigned long get_nr_to_reclaim(s
|
||||
@@ -5134,29 +5128,18 @@ static unsigned long get_nr_to_reclaim(struct scan_control *sc)
|
||||
if (!global_reclaim(sc))
|
||||
return -1;
|
||||
|
||||
|
@ -468,7 +487,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
if (sc->may_swap)
|
||||
swappiness = get_swappiness(lruvec, sc);
|
||||
@@ -5169,7 +5152,7 @@ static void lru_gen_shrink_lruvec(struct
|
||||
@@ -5166,7 +5149,7 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
swappiness = 0;
|
||||
|
||||
nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
|
||||
|
@ -477,7 +496,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
break;
|
||||
|
||||
delta = evict_folios(lruvec, sc, swappiness);
|
||||
@@ -5186,10 +5169,250 @@ static void lru_gen_shrink_lruvec(struct
|
||||
@@ -5183,11 +5166,252 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
cond_resched();
|
||||
}
|
||||
|
||||
|
@ -515,6 +534,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
+
|
||||
+ shrink_slab(sc->gfp_mask, pgdat->node_id, memcg, sc->priority);
|
||||
+
|
||||
+ if (!sc->proactive)
|
||||
+ vmpressure(sc->gfp_mask, memcg, false, sc->nr_scanned - scanned,
|
||||
+ sc->nr_reclaimed - reclaimed);
|
||||
+
|
||||
|
@ -538,7 +558,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
+ struct mem_cgroup *memcg = NULL;
|
||||
+ unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
|
||||
+
|
||||
+ bin = first_bin = prandom_u32_max(MEMCG_NR_BINS);
|
||||
+ bin = first_bin = get_random_u32_below(MEMCG_NR_BINS);
|
||||
+restart:
|
||||
+ gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
|
||||
+
|
||||
|
@ -601,11 +621,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
+ if (try_to_shrink_lruvec(lruvec, sc))
|
||||
+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
|
||||
+
|
||||
+ clear_mm_walk();
|
||||
+
|
||||
+ blk_finish_plug(&plug);
|
||||
+}
|
||||
+
|
||||
clear_mm_walk();
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
}
|
||||
|
||||
+#else /* !CONFIG_MEMCG */
|
||||
+
|
||||
+static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
|
@ -671,9 +691,9 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
+ if (current_is_kswapd())
|
||||
+ sc->nr_reclaimed += reclaimed;
|
||||
+
|
||||
clear_mm_walk();
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
+ clear_mm_walk();
|
||||
+
|
||||
+ blk_finish_plug(&plug);
|
||||
+
|
||||
+ /* kswapd should never fail */
|
||||
+ pgdat->kswapd_failures = 0;
|
||||
|
@ -684,7 +704,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
+{
|
||||
+ int seg;
|
||||
+ int old, new;
|
||||
+ int bin = prandom_u32_max(MEMCG_NR_BINS);
|
||||
+ int bin = get_random_u32_below(MEMCG_NR_BINS);
|
||||
+ struct pglist_data *pgdat = lruvec_pgdat(lruvec);
|
||||
+
|
||||
+ spin_lock(&pgdat->memcg_lru.lock);
|
||||
|
@ -723,12 +743,13 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
|
||||
+
|
||||
+ spin_unlock(&pgdat->memcg_lru.lock);
|
||||
}
|
||||
+}
|
||||
+#endif
|
||||
|
||||
+
|
||||
/******************************************************************************
|
||||
* state change
|
||||
@@ -5647,11 +5870,11 @@ static int run_cmd(char cmd, int memcg_i
|
||||
******************************************************************************/
|
||||
@@ -5644,11 +5868,11 @@ static int run_cmd(char cmd, int memcg_id, int nid, unsigned long seq,
|
||||
|
||||
if (!mem_cgroup_disabled()) {
|
||||
rcu_read_lock();
|
||||
|
@ -743,7 +764,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
rcu_read_unlock();
|
||||
|
||||
if (!memcg)
|
||||
@@ -5799,6 +6022,19 @@ void lru_gen_init_lruvec(struct lruvec *
|
||||
@@ -5796,6 +6020,19 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMCG
|
||||
|
@ -763,7 +784,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
void lru_gen_init_memcg(struct mem_cgroup *memcg)
|
||||
{
|
||||
INIT_LIST_HEAD(&memcg->mm_list.fifo);
|
||||
@@ -5822,7 +6058,69 @@ void lru_gen_exit_memcg(struct mem_cgrou
|
||||
@@ -5819,7 +6056,69 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -773,7 +794,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
+{
|
||||
+ int gen;
|
||||
+ int nid;
|
||||
+ int bin = prandom_u32_max(MEMCG_NR_BINS);
|
||||
+ int bin = get_random_u32_below(MEMCG_NR_BINS);
|
||||
+
|
||||
+ for_each_node(nid) {
|
||||
+ struct pglist_data *pgdat = NODE_DATA(nid);
|
||||
|
@ -834,7 +855,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
static int __init init_lru_gen(void)
|
||||
{
|
||||
@@ -5849,6 +6147,10 @@ static void lru_gen_shrink_lruvec(struct
|
||||
@@ -5846,6 +6145,10 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -845,7 +866,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
#endif /* CONFIG_LRU_GEN */
|
||||
|
||||
static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|
||||
@@ -5862,7 +6164,7 @@ static void shrink_lruvec(struct lruvec
|
||||
@@ -5859,7 +6162,7 @@ static void shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|
||||
bool proportional_reclaim;
|
||||
struct blk_plug plug;
|
||||
|
||||
|
@ -854,7 +875,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
lru_gen_shrink_lruvec(lruvec, sc);
|
||||
return;
|
||||
}
|
||||
@@ -6105,6 +6407,11 @@ static void shrink_node(pg_data_t *pgdat
|
||||
@@ -6102,6 +6405,11 @@ static void shrink_node(pg_data_t *pgdat, struct scan_control *sc)
|
||||
struct lruvec *target_lruvec;
|
||||
bool reclaimable = false;
|
||||
|
||||
|
@ -866,3 +887,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
target_lruvec = mem_cgroup_lruvec(sc->target_mem_cgroup, pgdat);
|
||||
|
||||
again:
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
From 93147736b5b3a21bea24313bfc7a696829932009 Mon Sep 17 00:00:00 2001
|
||||
From 11b14ee8cbbbebd8204609076a9327a1171cd253 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Wed, 21 Dec 2022 21:19:05 -0700
|
||||
Subject: [PATCH 27/29] mm: multi-gen LRU: clarify scan_control flags
|
||||
Subject: [PATCH 07/19] BACKPORT: mm: multi-gen LRU: clarify scan_control flags
|
||||
|
||||
Among the flags in scan_control:
|
||||
1. sc->may_swap, which indicates swap constraint due to memsw.max, is
|
||||
|
@ -12,7 +12,7 @@ Among the flags in scan_control:
|
|||
3. !(sc->gfp_mask & __GFP_IO), which indicates IO constraint, lowers
|
||||
swappiness to prioritize file LRU, since clean file folios are more
|
||||
likely to exist.
|
||||
4. sc->may_writefolio and sc->may_unmap, which indicates opportunistic
|
||||
4. sc->may_writepage and sc->may_unmap, which indicates opportunistic
|
||||
reclaim, are rejected, since unmapped clean folios are already
|
||||
prioritized. Scanning for more of them is likely futile and can
|
||||
cause high reclaim latency when there is a large number of memcgs.
|
||||
|
@ -29,13 +29,21 @@ Cc: Mike Rapoport <rppt@kernel.org>
|
|||
Cc: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
Cc: Suren Baghdasaryan <surenb@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Bug: 274865848
|
||||
(cherry picked from commit e9d4e1ee788097484606c32122f146d802a9c5fb)
|
||||
[TJ: Resolved conflict with older function signature for min_cgroup_below_min, and over
|
||||
cdded861182142ac4488a4d64c571107aeb77f53 ("ANDROID: MGLRU: Don't skip anon reclaim if swap low")]
|
||||
Change-Id: Ic2e779eaf4e91a3921831b4e2fa10c740dc59d50
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
mm/vmscan.c | 55 +++++++++++++++++++++++++++--------------------------
|
||||
1 file changed, 28 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 65eb28448f216..0a0e1250ffc87 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3185,6 +3185,9 @@ static int get_swappiness(struct lruvec
|
||||
@@ -3185,6 +3185,9 @@ static int get_swappiness(struct lruvec *lruvec, struct scan_control *sc)
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
struct pglist_data *pgdat = lruvec_pgdat(lruvec);
|
||||
|
||||
|
@ -45,7 +53,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
if (!can_demote(pgdat->node_id, sc) &&
|
||||
mem_cgroup_get_nr_swap_pages(memcg) < MIN_LRU_BATCH)
|
||||
return 0;
|
||||
@@ -4226,7 +4229,7 @@ static void walk_mm(struct lruvec *lruve
|
||||
@@ -4223,7 +4226,7 @@ static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_
|
||||
} while (err == -EAGAIN);
|
||||
}
|
||||
|
||||
|
@ -54,7 +62,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
{
|
||||
struct lru_gen_mm_walk *walk = current->reclaim_state->mm_walk;
|
||||
|
||||
@@ -4234,7 +4237,7 @@ static struct lru_gen_mm_walk *set_mm_wa
|
||||
@@ -4231,7 +4234,7 @@ static struct lru_gen_mm_walk *set_mm_walk(struct pglist_data *pgdat)
|
||||
VM_WARN_ON_ONCE(walk);
|
||||
|
||||
walk = &pgdat->mm_walk;
|
||||
|
@ -63,7 +71,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
VM_WARN_ON_ONCE(current_is_kswapd());
|
||||
|
||||
walk = kzalloc(sizeof(*walk), __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
|
||||
@@ -4420,7 +4423,7 @@ static bool try_to_inc_max_seq(struct lr
|
||||
@@ -4417,7 +4420,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -72,7 +80,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
if (!walk) {
|
||||
success = iterate_mm_list_nowalk(lruvec, max_seq);
|
||||
goto done;
|
||||
@@ -4489,8 +4492,6 @@ static bool lruvec_is_reclaimable(struct
|
||||
@@ -4486,8 +4489,6 @@ static bool lruvec_is_reclaimable(struct lruvec *lruvec, struct scan_control *sc
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
DEFINE_MIN_SEQ(lruvec);
|
||||
|
||||
|
@ -81,7 +89,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
/* see the comment on lru_gen_folio */
|
||||
gen = lru_gen_from_seq(min_seq[LRU_GEN_FILE]);
|
||||
birth = READ_ONCE(lruvec->lrugen.timestamps[gen]);
|
||||
@@ -4746,12 +4747,8 @@ static bool isolate_folio(struct lruvec
|
||||
@@ -4743,12 +4744,8 @@ static bool isolate_folio(struct lruvec *lruvec, struct folio *folio, struct sca
|
||||
{
|
||||
bool success;
|
||||
|
||||
|
@ -95,19 +103,19 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
(folio_test_dirty(folio) ||
|
||||
(folio_test_anon(folio) && !folio_test_swapcache(folio))))
|
||||
return false;
|
||||
@@ -4848,9 +4845,8 @@ static int scan_folios(struct lruvec *lr
|
||||
@@ -4845,9 +4842,8 @@ static int scan_folios(struct lruvec *lruvec, struct scan_control *sc,
|
||||
__count_vm_events(PGSCAN_ANON + type, isolated);
|
||||
|
||||
/*
|
||||
- * There might not be eligible pages due to reclaim_idx, may_unmap and
|
||||
- * may_writepage. Check the remaining to prevent livelock if it's not
|
||||
- * making progress.
|
||||
+ * There might not be eligible pages due to reclaim_idx. Check the
|
||||
+ * There might not be eligible folios due to reclaim_idx. Check the
|
||||
+ * remaining to prevent livelock if it's not making progress.
|
||||
*/
|
||||
return isolated || !remaining ? scanned : 0;
|
||||
}
|
||||
@@ -5110,8 +5106,7 @@ static long get_nr_to_scan(struct lruvec
|
||||
@@ -5107,8 +5103,7 @@ static long get_nr_to_scan(struct lruvec *lruvec, struct scan_control *sc, bool
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
DEFINE_MAX_SEQ(lruvec);
|
||||
|
||||
|
@ -117,7 +125,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
return 0;
|
||||
|
||||
if (!should_run_aging(lruvec, max_seq, sc, can_swap, &nr_to_scan))
|
||||
@@ -5139,17 +5134,14 @@ static bool try_to_shrink_lruvec(struct
|
||||
@@ -5136,17 +5131,14 @@ static bool try_to_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|
||||
long nr_to_scan;
|
||||
unsigned long scanned = 0;
|
||||
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
|
||||
|
@ -140,7 +148,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
nr_to_scan = get_nr_to_scan(lruvec, sc, swappiness);
|
||||
if (nr_to_scan <= 0)
|
||||
@@ -5279,12 +5271,13 @@ static void lru_gen_shrink_lruvec(struct
|
||||
@@ -5277,12 +5269,13 @@ static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc
|
||||
struct blk_plug plug;
|
||||
|
||||
VM_WARN_ON_ONCE(global_reclaim(sc));
|
||||
|
@ -155,7 +163,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
|
||||
if (try_to_shrink_lruvec(lruvec, sc))
|
||||
lru_gen_rotate_memcg(lruvec, MEMCG_LRU_YOUNG);
|
||||
@@ -5340,11 +5333,19 @@ static void lru_gen_shrink_node(struct p
|
||||
@@ -5338,11 +5331,19 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *
|
||||
|
||||
VM_WARN_ON_ONCE(!global_reclaim(sc));
|
||||
|
||||
|
@ -172,11 +180,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
blk_start_plug(&plug);
|
||||
|
||||
- set_mm_walk(pgdat);
|
||||
+ set_mm_walk(NULL, sc->proactive);
|
||||
+ set_mm_walk(pgdat, sc->proactive);
|
||||
|
||||
set_initial_priority(pgdat, sc);
|
||||
|
||||
@@ -5362,7 +5363,7 @@ static void lru_gen_shrink_node(struct p
|
||||
@@ -5360,7 +5361,7 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *
|
||||
clear_mm_walk();
|
||||
|
||||
blk_finish_plug(&plug);
|
||||
|
@ -185,7 +193,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
/* kswapd should never fail */
|
||||
pgdat->kswapd_failures = 0;
|
||||
}
|
||||
@@ -5934,7 +5935,7 @@ static ssize_t lru_gen_seq_write(struct
|
||||
@@ -5932,7 +5933,7 @@ static ssize_t lru_gen_seq_write(struct file *file, const char __user *src,
|
||||
set_task_reclaim_state(current, &sc.reclaim_state);
|
||||
flags = memalloc_noreclaim_save();
|
||||
blk_start_plug(&plug);
|
||||
|
@ -194,3 +202,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
err = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
From cf3297e4c7a928da8b2b2f0baff2f9c69ea57952 Mon Sep 17 00:00:00 2001
|
||||
From 25887d48dff860751a06caa4188bfaf6bfb6e4b2 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Wed, 21 Dec 2022 21:19:06 -0700
|
||||
Subject: [PATCH 28/29] mm: multi-gen LRU: simplify arch_has_hw_pte_young()
|
||||
check
|
||||
Subject: [PATCH 08/19] UPSTREAM: mm: multi-gen LRU: simplify
|
||||
arch_has_hw_pte_young() check
|
||||
|
||||
Scanning page tables when hardware does not set the accessed bit has
|
||||
no real use cases.
|
||||
|
@ -17,13 +17,19 @@ Cc: Mike Rapoport <rppt@kernel.org>
|
|||
Cc: Roman Gushchin <roman.gushchin@linux.dev>
|
||||
Cc: Suren Baghdasaryan <surenb@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Bug: 274865848
|
||||
(cherry picked from commit f386e9314025ea99dae639ed2032560a92081430)
|
||||
Change-Id: I84d97ab665b4e3bb862a9bc7d72f50dea7191a6b
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
mm/vmscan.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 0a0e1250ffc87..aa9746f2bc80b 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4418,7 +4418,7 @@ static bool try_to_inc_max_seq(struct lr
|
||||
@@ -4415,7 +4415,7 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
* handful of PTEs. Spreading the work out over a period of time usually
|
||||
* is less efficient, but it avoids bursty page faults.
|
||||
*/
|
||||
|
@ -32,3 +38,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
success = iterate_mm_list_nowalk(lruvec, max_seq);
|
||||
goto done;
|
||||
}
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
From cc67f962cc53f6e1dfa92eb85b7b26fe83a3c66f Mon Sep 17 00:00:00 2001
|
||||
From 620b0ee94455e48d124414cd06d8a53f69fb6453 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Mon, 13 Feb 2023 00:53:22 -0700
|
||||
Subject: [PATCH 29/29] mm: multi-gen LRU: avoid futile retries
|
||||
Subject: [PATCH 09/19] UPSTREAM: mm: multi-gen LRU: avoid futile retries
|
||||
|
||||
Recall that the per-node memcg LRU has two generations and they alternate
|
||||
when the last memcg (of a given node) is moved from one to the other.
|
||||
|
@ -19,13 +19,19 @@ Fixes: e4dde56cd208 ("mm: multi-gen LRU: per-node lru_gen_folio lists")
|
|||
Signed-off-by: Yu Zhao <yuzhao@google.com>
|
||||
Reported-by: T.J. Mercier <tjmercier@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
Bug: 274865848
|
||||
(cherry picked from commit 9f550d78b40da21b4da515db4c37d8d7b12aa1a6)
|
||||
Change-Id: Ie92535676b005ec9e7987632b742fdde8d54436f
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
mm/vmscan.c | 25 +++++++++++++++----------
|
||||
1 file changed, 15 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index aa9746f2bc80b..49da02f841c81 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -5208,18 +5208,20 @@ static int shrink_one(struct lruvec *lru
|
||||
@@ -5206,18 +5206,20 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc)
|
||||
|
||||
static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
{
|
||||
|
@ -41,14 +47,14 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
- struct mem_cgroup *memcg = NULL;
|
||||
unsigned long nr_to_reclaim = get_nr_to_reclaim(sc);
|
||||
|
||||
bin = first_bin = prandom_u32_max(MEMCG_NR_BINS);
|
||||
bin = first_bin = get_random_u32_below(MEMCG_NR_BINS);
|
||||
restart:
|
||||
+ op = 0;
|
||||
+ memcg = NULL;
|
||||
gen = get_memcg_gen(READ_ONCE(pgdat->memcg_lru.seq));
|
||||
|
||||
rcu_read_lock();
|
||||
@@ -5243,14 +5245,22 @@ restart:
|
||||
@@ -5241,14 +5243,22 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
|
||||
op = shrink_one(lruvec, sc);
|
||||
|
||||
|
@ -74,7 +80,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
/* restart if raced with lru_gen_rotate_memcg() */
|
||||
if (gen != get_nulls_value(pos))
|
||||
goto restart;
|
||||
@@ -5259,11 +5269,6 @@ restart:
|
||||
@@ -5257,11 +5267,6 @@ static void shrink_many(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
bin = get_memcg_bin(bin + 1);
|
||||
if (bin != first_bin)
|
||||
goto restart;
|
||||
|
@ -86,3 +92,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
}
|
||||
|
||||
static void lru_gen_shrink_lruvec(struct lruvec *lruvec, struct scan_control *sc)
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
From 6c7f552a48b49a8612786a28a2239fbc24fac289 Mon Sep 17 00:00:00 2001
|
||||
From 70d216c71ff5c5b17dd1da6294f97b91fb6aba7a Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Fri, 30 Dec 2022 14:52:51 -0700
|
||||
Subject: [PATCH 19/29] mm: add vma_has_recency()
|
||||
Subject: [PATCH 10/19] UPSTREAM: mm: add vma_has_recency()
|
||||
|
||||
Add vma_has_recency() to indicate whether a VMA may exhibit temporal
|
||||
locality that the LRU algorithm relies on.
|
||||
|
@ -43,22 +43,28 @@ results are available in that thread.
|
|||
[1] https://lore.kernel.org/r/Y31s%2FK8T85jh05wH@google.com/
|
||||
|
||||
Link: https://lkml.kernel.org/r/20221230215252.2628425-1-yuzhao@google.com
|
||||
Change-Id: I291dcb795197659e40e46539cd32b857677c34ad
|
||||
Signed-off-by: Yu Zhao <yuzhao@google.com>
|
||||
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: Andrea Righi <andrea.righi@canonical.com>
|
||||
Cc: Johannes Weiner <hannes@cmpxchg.org>
|
||||
Cc: Michael Larabel <Michael@MichaelLarabel.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
(cherry picked from commit 8788f6781486769d9598dcaedc3fe0eb12fc3e59)
|
||||
Bug: 274865848
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
include/linux/mm_inline.h | 9 +++++++++
|
||||
mm/memory.c | 8 ++++----
|
||||
include/linux/mm_inline.h | 8 ++++++++
|
||||
mm/memory.c | 7 +++----
|
||||
mm/rmap.c | 42 +++++++++++++++++----------------------
|
||||
mm/vmscan.c | 5 ++++-
|
||||
4 files changed, 35 insertions(+), 29 deletions(-)
|
||||
4 files changed, 33 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index c1fd3922dc5dd..7bb2e5f94734c 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -578,4 +578,12 @@ pte_install_uffd_wp_if_needed(struct vm_
|
||||
@@ -595,4 +595,12 @@ pte_install_uffd_wp_if_needed(struct vm_area_struct *vma, unsigned long addr,
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -71,9 +77,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
+}
|
||||
+
|
||||
#endif
|
||||
diff --git a/mm/memory.c b/mm/memory.c
|
||||
index 747b7ea30f890..c2f48f8003c2e 100644
|
||||
--- a/mm/memory.c
|
||||
+++ b/mm/memory.c
|
||||
@@ -1435,8 +1435,7 @@ again:
|
||||
@@ -1435,8 +1435,7 @@ static unsigned long zap_pte_range(struct mmu_gather *tlb,
|
||||
force_flush = 1;
|
||||
set_page_dirty(page);
|
||||
}
|
||||
|
@ -83,7 +91,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
mark_page_accessed(page);
|
||||
}
|
||||
rss[mm_counter(page)]--;
|
||||
@@ -5170,8 +5169,8 @@ static inline void mm_account_fault(stru
|
||||
@@ -5170,8 +5169,8 @@ static inline void mm_account_fault(struct pt_regs *regs,
|
||||
#ifdef CONFIG_LRU_GEN
|
||||
static void lru_gen_enter_fault(struct vm_area_struct *vma)
|
||||
{
|
||||
|
@ -94,9 +102,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
}
|
||||
|
||||
static void lru_gen_exit_fault(void)
|
||||
diff --git a/mm/rmap.c b/mm/rmap.c
|
||||
index 7da2d8d097d9b..825dac3caa1e5 100644
|
||||
--- a/mm/rmap.c
|
||||
+++ b/mm/rmap.c
|
||||
@@ -823,25 +823,14 @@ static bool folio_referenced_one(struct
|
||||
@@ -823,25 +823,14 @@ static bool folio_referenced_one(struct folio *folio,
|
||||
}
|
||||
|
||||
if (pvmw.pte) {
|
||||
|
@ -125,16 +135,16 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
} else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) {
|
||||
if (pmdp_clear_flush_young_notify(vma, address,
|
||||
pvmw.pmd))
|
||||
@@ -875,7 +864,20 @@ static bool invalid_folio_referenced_vma
|
||||
@@ -875,7 +864,20 @@ static bool invalid_folio_referenced_vma(struct vm_area_struct *vma, void *arg)
|
||||
struct folio_referenced_arg *pra = arg;
|
||||
struct mem_cgroup *memcg = pra->memcg;
|
||||
|
||||
- if (!mm_match_cgroup(vma->vm_mm, memcg))
|
||||
+ /*
|
||||
+ * Ignore references from this mapping if it has no recency. If the
|
||||
+ * page has been used in another mapping, we will catch it; if this
|
||||
+ * folio has been used in another mapping, we will catch it; if this
|
||||
+ * other mapping is already gone, the unmap path will have set the
|
||||
+ * referenced flag or activated the page in zap_pte_range().
|
||||
+ * referenced flag or activated the folio in zap_pte_range().
|
||||
+ */
|
||||
+ if (!vma_has_recency(vma))
|
||||
+ return true;
|
||||
|
@ -147,7 +157,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
return true;
|
||||
|
||||
return false;
|
||||
@@ -906,6 +908,7 @@ int folio_referenced(struct folio *folio
|
||||
@@ -906,6 +908,7 @@ int folio_referenced(struct folio *folio, int is_locked,
|
||||
.arg = (void *)&pra,
|
||||
.anon_lock = folio_lock_anon_vma_read,
|
||||
.try_lock = true,
|
||||
|
@ -155,7 +165,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
};
|
||||
|
||||
*vm_flags = 0;
|
||||
@@ -921,15 +924,6 @@ int folio_referenced(struct folio *folio
|
||||
@@ -921,15 +924,6 @@ int folio_referenced(struct folio *folio, int is_locked,
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -171,9 +181,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
rmap_walk(folio, &rwc);
|
||||
*vm_flags = pra.vm_flags;
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 49da02f841c81..596fed6ae0439 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3766,7 +3766,10 @@ static int should_skip_vma(unsigned long
|
||||
@@ -3778,7 +3778,10 @@ static int should_skip_vma(unsigned long start, unsigned long end, struct mm_wal
|
||||
if (is_vm_hugetlb_page(vma))
|
||||
return true;
|
||||
|
||||
|
@ -185,3 +197,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
return true;
|
||||
|
||||
if (vma == get_gate_vma(vma->vm_mm))
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
From 686c3d4f71de9e0e7a27f03a5617a712385f90cd Mon Sep 17 00:00:00 2001
|
||||
From 9ca4e437a24dfc4ec6c362f319eb9850b9eca497 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Zhao <yuzhao@google.com>
|
||||
Date: Fri, 30 Dec 2022 14:52:52 -0700
|
||||
Subject: [PATCH 20/29] mm: support POSIX_FADV_NOREUSE
|
||||
Subject: [PATCH 11/19] UPSTREAM: mm: support POSIX_FADV_NOREUSE
|
||||
|
||||
This patch adds POSIX_FADV_NOREUSE to vma_has_recency() so that the LRU
|
||||
algorithm can ignore access to mapped files marked by this flag.
|
||||
|
@ -22,7 +22,7 @@ Its limitations are:
|
|||
by two users and one of them having set POSIX_FADV_NOREUSE on the
|
||||
file, this page will be activated upon the second user accessing
|
||||
it. This corner case can be covered by checking POSIX_FADV_NOREUSE
|
||||
before calling mark_page_accessed() on the read path. But it is
|
||||
before calling folio_mark_accessed() on the read path. But it is
|
||||
considered not worth the effort.
|
||||
|
||||
There have been a few attempts to support POSIX_FADV_NOREUSE, e.g., [1].
|
||||
|
@ -67,32 +67,40 @@ which makes it on par with the active/inactive LRU.
|
|||
[2] https://openbenchmarking.org/result/2209259-PTS-MGLRU8GB57
|
||||
|
||||
Link: https://lkml.kernel.org/r/20221230215252.2628425-2-yuzhao@google.com
|
||||
Change-Id: I0b7f5f971d78014ea1ba44cee6a8ec902a4330d0
|
||||
Signed-off-by: Yu Zhao <yuzhao@google.com>
|
||||
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
|
||||
Cc: Andrea Righi <andrea.righi@canonical.com>
|
||||
Cc: Johannes Weiner <hannes@cmpxchg.org>
|
||||
Cc: Michael Larabel <Michael@MichaelLarabel.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
(cherry picked from commit 17e810229cb3068b692fa078bd9b3a6527e0866a)
|
||||
Bug: 274865848
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
include/linux/fs.h | 2 ++
|
||||
include/linux/mm_inline.h | 3 +++
|
||||
mm/fadvise.c | 5 ++++-
|
||||
3 files changed, 9 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/linux/fs.h b/include/linux/fs.h
|
||||
index f14ecbeab2a9d..97f9c41c1a43a 100644
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -166,6 +166,8 @@ typedef int (dio_iodone_t)(struct kiocb
|
||||
@@ -166,6 +166,8 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
|
||||
/* File supports DIRECT IO */
|
||||
#define FMODE_CAN_ODIRECT ((__force fmode_t)0x400000)
|
||||
|
||||
+#define FMODE_NOREUSE ((__force fmode_t)0x400000)
|
||||
+#define FMODE_NOREUSE ((__force fmode_t)0x800000)
|
||||
+
|
||||
/* File was opened by fanotify and shouldn't generate fanotify events */
|
||||
#define FMODE_NONOTIFY ((__force fmode_t)0x4000000)
|
||||
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index 7bb2e5f94734c..9a8e2049333c0 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -583,6 +583,9 @@ static inline bool vma_has_recency(struc
|
||||
@@ -600,6 +600,9 @@ static inline bool vma_has_recency(struct vm_area_struct *vma)
|
||||
if (vma->vm_flags & (VM_SEQ_READ | VM_RAND_READ))
|
||||
return false;
|
||||
|
||||
|
@ -102,9 +110,11 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
return true;
|
||||
}
|
||||
|
||||
diff --git a/mm/fadvise.c b/mm/fadvise.c
|
||||
index c76ee665355a4..2ba24d865bf5f 100644
|
||||
--- a/mm/fadvise.c
|
||||
+++ b/mm/fadvise.c
|
||||
@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, l
|
||||
@@ -80,7 +80,7 @@ int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
|
||||
case POSIX_FADV_NORMAL:
|
||||
file->f_ra.ra_pages = bdi->ra_pages;
|
||||
spin_lock(&file->f_lock);
|
||||
|
@ -113,7 +123,7 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
spin_unlock(&file->f_lock);
|
||||
break;
|
||||
case POSIX_FADV_RANDOM:
|
||||
@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, l
|
||||
@@ -107,6 +107,9 @@ int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
|
||||
force_page_cache_readahead(mapping, file, start_index, nrpages);
|
||||
break;
|
||||
case POSIX_FADV_NOREUSE:
|
||||
|
@ -123,3 +133,6 @@ Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
|||
break;
|
||||
case POSIX_FADV_DONTNEED:
|
||||
__filemap_fdatawrite_range(mapping, offset, endbyte,
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
From 1b5e4c317d80f4826eceb3781702d18d06b14394 Mon Sep 17 00:00:00 2001
|
||||
From: "T.J. Alumbaugh" <talumbau@google.com>
|
||||
Date: Wed, 18 Jan 2023 00:18:21 +0000
|
||||
Subject: [PATCH 12/19] UPSTREAM: mm: multi-gen LRU: section for working set
|
||||
protection
|
||||
|
||||
Patch series "mm: multi-gen LRU: improve".
|
||||
|
||||
This patch series improves a few MGLRU functions, collects related
|
||||
functions, and adds additional documentation.
|
||||
|
||||
This patch (of 7):
|
||||
|
||||
Add a section for working set protection in the code and the design doc.
|
||||
The admin doc already contains its usage.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20230118001827.1040870-1-talumbau@google.com
|
||||
Link: https://lkml.kernel.org/r/20230118001827.1040870-2-talumbau@google.com
|
||||
Change-Id: I65599075fd42951db7739a2ab7cee78516e157b3
|
||||
Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
|
||||
Cc: Yu Zhao <yuzhao@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
(cherry picked from commit 7b8144e63d84716f16a1b929e0c7e03ae5c4d5c1)
|
||||
Bug: 274865848
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
Documentation/mm/multigen_lru.rst | 15 +++++++++++++++
|
||||
mm/vmscan.c | 4 ++++
|
||||
2 files changed, 19 insertions(+)
|
||||
|
||||
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
|
||||
index d8f721f98868a..6e1483e70fdca 100644
|
||||
--- a/Documentation/mm/multigen_lru.rst
|
||||
+++ b/Documentation/mm/multigen_lru.rst
|
||||
@@ -141,6 +141,21 @@ loop has detected outlying refaults from the tier this page is in. To
|
||||
this end, the feedback loop uses the first tier as the baseline, for
|
||||
the reason stated earlier.
|
||||
|
||||
+Working set protection
|
||||
+----------------------
|
||||
+Each generation is timestamped at birth. If ``lru_gen_min_ttl`` is
|
||||
+set, an ``lruvec`` is protected from the eviction when its oldest
|
||||
+generation was born within ``lru_gen_min_ttl`` milliseconds. In other
|
||||
+words, it prevents the working set of ``lru_gen_min_ttl`` milliseconds
|
||||
+from getting evicted. The OOM killer is triggered if this working set
|
||||
+cannot be kept in memory.
|
||||
+
|
||||
+This time-based approach has the following advantages:
|
||||
+
|
||||
+1. It is easier to configure because it is agnostic to applications
|
||||
+ and memory sizes.
|
||||
+2. It is more reliable because it is directly wired to the OOM killer.
|
||||
+
|
||||
Summary
|
||||
-------
|
||||
The multi-gen LRU can be disassembled into the following parts:
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 596fed6ae0439..ab0b8d3b9d88f 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4459,6 +4459,10 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
return true;
|
||||
}
|
||||
|
||||
+/******************************************************************************
|
||||
+ * working set protection
|
||||
+ ******************************************************************************/
|
||||
+
|
||||
static bool lruvec_is_sizable(struct lruvec *lruvec, struct scan_control *sc)
|
||||
{
|
||||
int gen, type, zone;
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
From 5ddf9d53d375e42af49b744bd7c2f8247c6bce15 Mon Sep 17 00:00:00 2001
|
||||
From: "T.J. Alumbaugh" <talumbau@google.com>
|
||||
Date: Wed, 18 Jan 2023 00:18:22 +0000
|
||||
Subject: [PATCH 13/19] UPSTREAM: mm: multi-gen LRU: section for rmap/PT walk
|
||||
feedback
|
||||
|
||||
Add a section for lru_gen_look_around() in the code and the design doc.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20230118001827.1040870-3-talumbau@google.com
|
||||
Change-Id: I5097af63f61b3b69ec2abee6cdbdc33c296df213
|
||||
Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
|
||||
Cc: Yu Zhao <yuzhao@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
(cherry picked from commit db19a43d9b3a8876552f00f656008206ef9a5efa)
|
||||
Bug: 274865848
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
Documentation/mm/multigen_lru.rst | 14 ++++++++++++++
|
||||
mm/vmscan.c | 4 ++++
|
||||
2 files changed, 18 insertions(+)
|
||||
|
||||
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
|
||||
index 6e1483e70fdca..bd988a142bc2f 100644
|
||||
--- a/Documentation/mm/multigen_lru.rst
|
||||
+++ b/Documentation/mm/multigen_lru.rst
|
||||
@@ -156,6 +156,20 @@ This time-based approach has the following advantages:
|
||||
and memory sizes.
|
||||
2. It is more reliable because it is directly wired to the OOM killer.
|
||||
|
||||
+Rmap/PT walk feedback
|
||||
+---------------------
|
||||
+Searching the rmap for PTEs mapping each page on an LRU list (to test
|
||||
+and clear the accessed bit) can be expensive because pages from
|
||||
+different VMAs (PA space) are not cache friendly to the rmap (VA
|
||||
+space). For workloads mostly using mapped pages, searching the rmap
|
||||
+can incur the highest CPU cost in the reclaim path.
|
||||
+
|
||||
+``lru_gen_look_around()`` exploits spatial locality to reduce the
|
||||
+trips into the rmap. It scans the adjacent PTEs of a young PTE and
|
||||
+promotes hot pages. If the scan was done cacheline efficiently, it
|
||||
+adds the PMD entry pointing to the PTE table to the Bloom filter. This
|
||||
+forms a feedback loop between the eviction and the aging.
|
||||
+
|
||||
Summary
|
||||
-------
|
||||
The multi-gen LRU can be disassembled into the following parts:
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index ab0b8d3b9d88f..8fa82630240d6 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4553,6 +4553,10 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
}
|
||||
}
|
||||
|
||||
+/******************************************************************************
|
||||
+ * rmap/PT walk feedback
|
||||
+ ******************************************************************************/
|
||||
+
|
||||
/*
|
||||
* This function exploits spatial locality when shrink_folio_list() walks the
|
||||
* rmap. It scans the adjacent PTEs of a young PTE and promotes hot pages. If
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -0,0 +1,250 @@
|
|||
From 397624e12244ec038f51cb1f178ccb7a2ec562e5 Mon Sep 17 00:00:00 2001
|
||||
From: "T.J. Alumbaugh" <talumbau@google.com>
|
||||
Date: Wed, 18 Jan 2023 00:18:23 +0000
|
||||
Subject: [PATCH 14/19] UPSTREAM: mm: multi-gen LRU: section for Bloom filters
|
||||
|
||||
Move Bloom filters code into a dedicated section. Improve the design doc
|
||||
to explain Bloom filter usage and connection between aging and eviction in
|
||||
their use.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20230118001827.1040870-4-talumbau@google.com
|
||||
Change-Id: I73e866f687c1ed9f5c8538086aa39408b79897db
|
||||
Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
|
||||
Cc: Yu Zhao <yuzhao@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
(cherry picked from commit ccbbbb85945d8f0255aa9dbc1b617017e2294f2c)
|
||||
Bug: 274865848
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
Documentation/mm/multigen_lru.rst | 16 +++
|
||||
mm/vmscan.c | 180 +++++++++++++++---------------
|
||||
2 files changed, 108 insertions(+), 88 deletions(-)
|
||||
|
||||
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
|
||||
index bd988a142bc2f..770b5d539856c 100644
|
||||
--- a/Documentation/mm/multigen_lru.rst
|
||||
+++ b/Documentation/mm/multigen_lru.rst
|
||||
@@ -170,6 +170,22 @@ promotes hot pages. If the scan was done cacheline efficiently, it
|
||||
adds the PMD entry pointing to the PTE table to the Bloom filter. This
|
||||
forms a feedback loop between the eviction and the aging.
|
||||
|
||||
+Bloom Filters
|
||||
+-------------
|
||||
+Bloom filters are a space and memory efficient data structure for set
|
||||
+membership test, i.e., test if an element is not in the set or may be
|
||||
+in the set.
|
||||
+
|
||||
+In the eviction path, specifically, in ``lru_gen_look_around()``, if a
|
||||
+PMD has a sufficient number of hot pages, its address is placed in the
|
||||
+filter. In the aging path, set membership means that the PTE range
|
||||
+will be scanned for young pages.
|
||||
+
|
||||
+Note that Bloom filters are probabilistic on set membership. If a test
|
||||
+is false positive, the cost is an additional scan of a range of PTEs,
|
||||
+which may yield hot pages anyway. Parameters of the filter itself can
|
||||
+control the false positive rate in the limit.
|
||||
+
|
||||
Summary
|
||||
-------
|
||||
The multi-gen LRU can be disassembled into the following parts:
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 8fa82630240d6..74b4f9d660b56 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3208,6 +3208,98 @@ static bool __maybe_unused seq_is_valid(struct lruvec *lruvec)
|
||||
get_nr_gens(lruvec, LRU_GEN_ANON) <= MAX_NR_GENS;
|
||||
}
|
||||
|
||||
+/******************************************************************************
|
||||
+ * Bloom filters
|
||||
+ ******************************************************************************/
|
||||
+
|
||||
+/*
|
||||
+ * Bloom filters with m=1<<15, k=2 and the false positive rates of ~1/5 when
|
||||
+ * n=10,000 and ~1/2 when n=20,000, where, conventionally, m is the number of
|
||||
+ * bits in a bitmap, k is the number of hash functions and n is the number of
|
||||
+ * inserted items.
|
||||
+ *
|
||||
+ * Page table walkers use one of the two filters to reduce their search space.
|
||||
+ * To get rid of non-leaf entries that no longer have enough leaf entries, the
|
||||
+ * aging uses the double-buffering technique to flip to the other filter each
|
||||
+ * time it produces a new generation. For non-leaf entries that have enough
|
||||
+ * leaf entries, the aging carries them over to the next generation in
|
||||
+ * walk_pmd_range(); the eviction also report them when walking the rmap
|
||||
+ * in lru_gen_look_around().
|
||||
+ *
|
||||
+ * For future optimizations:
|
||||
+ * 1. It's not necessary to keep both filters all the time. The spare one can be
|
||||
+ * freed after the RCU grace period and reallocated if needed again.
|
||||
+ * 2. And when reallocating, it's worth scaling its size according to the number
|
||||
+ * of inserted entries in the other filter, to reduce the memory overhead on
|
||||
+ * small systems and false positives on large systems.
|
||||
+ * 3. Jenkins' hash function is an alternative to Knuth's.
|
||||
+ */
|
||||
+#define BLOOM_FILTER_SHIFT 15
|
||||
+
|
||||
+static inline int filter_gen_from_seq(unsigned long seq)
|
||||
+{
|
||||
+ return seq % NR_BLOOM_FILTERS;
|
||||
+}
|
||||
+
|
||||
+static void get_item_key(void *item, int *key)
|
||||
+{
|
||||
+ u32 hash = hash_ptr(item, BLOOM_FILTER_SHIFT * 2);
|
||||
+
|
||||
+ BUILD_BUG_ON(BLOOM_FILTER_SHIFT * 2 > BITS_PER_TYPE(u32));
|
||||
+
|
||||
+ key[0] = hash & (BIT(BLOOM_FILTER_SHIFT) - 1);
|
||||
+ key[1] = hash >> BLOOM_FILTER_SHIFT;
|
||||
+}
|
||||
+
|
||||
+static bool test_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
|
||||
+{
|
||||
+ int key[2];
|
||||
+ unsigned long *filter;
|
||||
+ int gen = filter_gen_from_seq(seq);
|
||||
+
|
||||
+ filter = READ_ONCE(lruvec->mm_state.filters[gen]);
|
||||
+ if (!filter)
|
||||
+ return true;
|
||||
+
|
||||
+ get_item_key(item, key);
|
||||
+
|
||||
+ return test_bit(key[0], filter) && test_bit(key[1], filter);
|
||||
+}
|
||||
+
|
||||
+static void update_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
|
||||
+{
|
||||
+ int key[2];
|
||||
+ unsigned long *filter;
|
||||
+ int gen = filter_gen_from_seq(seq);
|
||||
+
|
||||
+ filter = READ_ONCE(lruvec->mm_state.filters[gen]);
|
||||
+ if (!filter)
|
||||
+ return;
|
||||
+
|
||||
+ get_item_key(item, key);
|
||||
+
|
||||
+ if (!test_bit(key[0], filter))
|
||||
+ set_bit(key[0], filter);
|
||||
+ if (!test_bit(key[1], filter))
|
||||
+ set_bit(key[1], filter);
|
||||
+}
|
||||
+
|
||||
+static void reset_bloom_filter(struct lruvec *lruvec, unsigned long seq)
|
||||
+{
|
||||
+ unsigned long *filter;
|
||||
+ int gen = filter_gen_from_seq(seq);
|
||||
+
|
||||
+ filter = lruvec->mm_state.filters[gen];
|
||||
+ if (filter) {
|
||||
+ bitmap_clear(filter, 0, BIT(BLOOM_FILTER_SHIFT));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ filter = bitmap_zalloc(BIT(BLOOM_FILTER_SHIFT),
|
||||
+ __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
|
||||
+ WRITE_ONCE(lruvec->mm_state.filters[gen], filter);
|
||||
+}
|
||||
+
|
||||
/******************************************************************************
|
||||
* mm_struct list
|
||||
******************************************************************************/
|
||||
@@ -3333,94 +3425,6 @@ void lru_gen_migrate_mm(struct mm_struct *mm)
|
||||
}
|
||||
#endif
|
||||
|
||||
-/*
|
||||
- * Bloom filters with m=1<<15, k=2 and the false positive rates of ~1/5 when
|
||||
- * n=10,000 and ~1/2 when n=20,000, where, conventionally, m is the number of
|
||||
- * bits in a bitmap, k is the number of hash functions and n is the number of
|
||||
- * inserted items.
|
||||
- *
|
||||
- * Page table walkers use one of the two filters to reduce their search space.
|
||||
- * To get rid of non-leaf entries that no longer have enough leaf entries, the
|
||||
- * aging uses the double-buffering technique to flip to the other filter each
|
||||
- * time it produces a new generation. For non-leaf entries that have enough
|
||||
- * leaf entries, the aging carries them over to the next generation in
|
||||
- * walk_pmd_range(); the eviction also report them when walking the rmap
|
||||
- * in lru_gen_look_around().
|
||||
- *
|
||||
- * For future optimizations:
|
||||
- * 1. It's not necessary to keep both filters all the time. The spare one can be
|
||||
- * freed after the RCU grace period and reallocated if needed again.
|
||||
- * 2. And when reallocating, it's worth scaling its size according to the number
|
||||
- * of inserted entries in the other filter, to reduce the memory overhead on
|
||||
- * small systems and false positives on large systems.
|
||||
- * 3. Jenkins' hash function is an alternative to Knuth's.
|
||||
- */
|
||||
-#define BLOOM_FILTER_SHIFT 15
|
||||
-
|
||||
-static inline int filter_gen_from_seq(unsigned long seq)
|
||||
-{
|
||||
- return seq % NR_BLOOM_FILTERS;
|
||||
-}
|
||||
-
|
||||
-static void get_item_key(void *item, int *key)
|
||||
-{
|
||||
- u32 hash = hash_ptr(item, BLOOM_FILTER_SHIFT * 2);
|
||||
-
|
||||
- BUILD_BUG_ON(BLOOM_FILTER_SHIFT * 2 > BITS_PER_TYPE(u32));
|
||||
-
|
||||
- key[0] = hash & (BIT(BLOOM_FILTER_SHIFT) - 1);
|
||||
- key[1] = hash >> BLOOM_FILTER_SHIFT;
|
||||
-}
|
||||
-
|
||||
-static void reset_bloom_filter(struct lruvec *lruvec, unsigned long seq)
|
||||
-{
|
||||
- unsigned long *filter;
|
||||
- int gen = filter_gen_from_seq(seq);
|
||||
-
|
||||
- filter = lruvec->mm_state.filters[gen];
|
||||
- if (filter) {
|
||||
- bitmap_clear(filter, 0, BIT(BLOOM_FILTER_SHIFT));
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- filter = bitmap_zalloc(BIT(BLOOM_FILTER_SHIFT),
|
||||
- __GFP_HIGH | __GFP_NOMEMALLOC | __GFP_NOWARN);
|
||||
- WRITE_ONCE(lruvec->mm_state.filters[gen], filter);
|
||||
-}
|
||||
-
|
||||
-static void update_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
|
||||
-{
|
||||
- int key[2];
|
||||
- unsigned long *filter;
|
||||
- int gen = filter_gen_from_seq(seq);
|
||||
-
|
||||
- filter = READ_ONCE(lruvec->mm_state.filters[gen]);
|
||||
- if (!filter)
|
||||
- return;
|
||||
-
|
||||
- get_item_key(item, key);
|
||||
-
|
||||
- if (!test_bit(key[0], filter))
|
||||
- set_bit(key[0], filter);
|
||||
- if (!test_bit(key[1], filter))
|
||||
- set_bit(key[1], filter);
|
||||
-}
|
||||
-
|
||||
-static bool test_bloom_filter(struct lruvec *lruvec, unsigned long seq, void *item)
|
||||
-{
|
||||
- int key[2];
|
||||
- unsigned long *filter;
|
||||
- int gen = filter_gen_from_seq(seq);
|
||||
-
|
||||
- filter = READ_ONCE(lruvec->mm_state.filters[gen]);
|
||||
- if (!filter)
|
||||
- return true;
|
||||
-
|
||||
- get_item_key(item, key);
|
||||
-
|
||||
- return test_bit(key[0], filter) && test_bit(key[1], filter);
|
||||
-}
|
||||
-
|
||||
static void reset_mm_stats(struct lruvec *lruvec, struct lru_gen_mm_walk *walk, bool last)
|
||||
{
|
||||
int i;
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -0,0 +1,440 @@
|
|||
From 48c916b812652f9453be5bd45a703728926d41ca Mon Sep 17 00:00:00 2001
|
||||
From: "T.J. Alumbaugh" <talumbau@google.com>
|
||||
Date: Wed, 18 Jan 2023 00:18:24 +0000
|
||||
Subject: [PATCH 15/19] UPSTREAM: mm: multi-gen LRU: section for memcg LRU
|
||||
|
||||
Move memcg LRU code into a dedicated section. Improve the design doc to
|
||||
outline its architecture.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20230118001827.1040870-5-talumbau@google.com
|
||||
Change-Id: Id252e420cff7a858acb098cf2b3642da5c40f602
|
||||
Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
|
||||
Cc: Yu Zhao <yuzhao@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
(cherry picked from commit 36c7b4db7c942ae9e1b111f0c6b468c8b2e33842)
|
||||
Bug: 274865848
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
Documentation/mm/multigen_lru.rst | 33 +++-
|
||||
include/linux/mm_inline.h | 17 --
|
||||
include/linux/mmzone.h | 13 +-
|
||||
mm/memcontrol.c | 8 +-
|
||||
mm/vmscan.c | 250 +++++++++++++++++-------------
|
||||
5 files changed, 178 insertions(+), 143 deletions(-)
|
||||
|
||||
diff --git a/Documentation/mm/multigen_lru.rst b/Documentation/mm/multigen_lru.rst
|
||||
index 770b5d539856c..5f1f6ecbb79b9 100644
|
||||
--- a/Documentation/mm/multigen_lru.rst
|
||||
+++ b/Documentation/mm/multigen_lru.rst
|
||||
@@ -186,9 +186,40 @@ is false positive, the cost is an additional scan of a range of PTEs,
|
||||
which may yield hot pages anyway. Parameters of the filter itself can
|
||||
control the false positive rate in the limit.
|
||||
|
||||
+Memcg LRU
|
||||
+---------
|
||||
+An memcg LRU is a per-node LRU of memcgs. It is also an LRU of LRUs,
|
||||
+since each node and memcg combination has an LRU of folios (see
|
||||
+``mem_cgroup_lruvec()``). Its goal is to improve the scalability of
|
||||
+global reclaim, which is critical to system-wide memory overcommit in
|
||||
+data centers. Note that memcg LRU only applies to global reclaim.
|
||||
+
|
||||
+The basic structure of an memcg LRU can be understood by an analogy to
|
||||
+the active/inactive LRU (of folios):
|
||||
+
|
||||
+1. It has the young and the old (generations), i.e., the counterparts
|
||||
+ to the active and the inactive;
|
||||
+2. The increment of ``max_seq`` triggers promotion, i.e., the
|
||||
+ counterpart to activation;
|
||||
+3. Other events trigger similar operations, e.g., offlining an memcg
|
||||
+ triggers demotion, i.e., the counterpart to deactivation.
|
||||
+
|
||||
+In terms of global reclaim, it has two distinct features:
|
||||
+
|
||||
+1. Sharding, which allows each thread to start at a random memcg (in
|
||||
+ the old generation) and improves parallelism;
|
||||
+2. Eventual fairness, which allows direct reclaim to bail out at will
|
||||
+ and reduces latency without affecting fairness over some time.
|
||||
+
|
||||
+In terms of traversing memcgs during global reclaim, it improves the
|
||||
+best-case complexity from O(n) to O(1) and does not affect the
|
||||
+worst-case complexity O(n). Therefore, on average, it has a sublinear
|
||||
+complexity.
|
||||
+
|
||||
Summary
|
||||
-------
|
||||
-The multi-gen LRU can be disassembled into the following parts:
|
||||
+The multi-gen LRU (of folios) can be disassembled into the following
|
||||
+parts:
|
||||
|
||||
* Generations
|
||||
* Rmap walks
|
||||
diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h
|
||||
index 9a8e2049333c0..5567f4850243b 100644
|
||||
--- a/include/linux/mm_inline.h
|
||||
+++ b/include/linux/mm_inline.h
|
||||
@@ -122,18 +122,6 @@ static inline bool lru_gen_in_fault(void)
|
||||
return current->in_lru_fault;
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_MEMCG
|
||||
-static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
|
||||
-{
|
||||
- return READ_ONCE(lruvec->lrugen.seg);
|
||||
-}
|
||||
-#else
|
||||
-static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
|
||||
-{
|
||||
- return 0;
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
static inline int lru_gen_from_seq(unsigned long seq)
|
||||
{
|
||||
return seq % MAX_NR_GENS;
|
||||
@@ -309,11 +297,6 @@ static inline bool lru_gen_in_fault(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
-static inline int lru_gen_memcg_seg(struct lruvec *lruvec)
|
||||
-{
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static inline bool lru_gen_add_folio(struct lruvec *lruvec, struct folio *folio, bool reclaiming)
|
||||
{
|
||||
return false;
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index 66e067a635682..403c7461e7a70 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -368,15 +368,6 @@ struct page_vma_mapped_walk;
|
||||
#define LRU_GEN_MASK ((BIT(LRU_GEN_WIDTH) - 1) << LRU_GEN_PGOFF)
|
||||
#define LRU_REFS_MASK ((BIT(LRU_REFS_WIDTH) - 1) << LRU_REFS_PGOFF)
|
||||
|
||||
-/* see the comment on MEMCG_NR_GENS */
|
||||
-enum {
|
||||
- MEMCG_LRU_NOP,
|
||||
- MEMCG_LRU_HEAD,
|
||||
- MEMCG_LRU_TAIL,
|
||||
- MEMCG_LRU_OLD,
|
||||
- MEMCG_LRU_YOUNG,
|
||||
-};
|
||||
-
|
||||
#ifdef CONFIG_LRU_GEN
|
||||
|
||||
enum {
|
||||
@@ -557,7 +548,7 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg);
|
||||
void lru_gen_online_memcg(struct mem_cgroup *memcg);
|
||||
void lru_gen_offline_memcg(struct mem_cgroup *memcg);
|
||||
void lru_gen_release_memcg(struct mem_cgroup *memcg);
|
||||
-void lru_gen_rotate_memcg(struct lruvec *lruvec, int op);
|
||||
+void lru_gen_soft_reclaim(struct lruvec *lruvec);
|
||||
|
||||
#else /* !CONFIG_MEMCG */
|
||||
|
||||
@@ -608,7 +599,7 @@ static inline void lru_gen_release_memcg(struct mem_cgroup *memcg)
|
||||
{
|
||||
}
|
||||
|
||||
-static inline void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
|
||||
+static inline void lru_gen_soft_reclaim(struct lruvec *lruvec)
|
||||
{
|
||||
}
|
||||
|
||||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
|
||||
index 7815d556e38cc..5397aeb43986d 100644
|
||||
--- a/mm/memcontrol.c
|
||||
+++ b/mm/memcontrol.c
|
||||
@@ -478,12 +478,8 @@ static void mem_cgroup_update_tree(struct mem_cgroup *memcg, int nid)
|
||||
struct mem_cgroup_tree_per_node *mctz;
|
||||
|
||||
if (lru_gen_enabled()) {
|
||||
- struct lruvec *lruvec = &memcg->nodeinfo[nid]->lruvec;
|
||||
-
|
||||
- /* see the comment on MEMCG_NR_GENS */
|
||||
- if (soft_limit_excess(memcg) && lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD)
|
||||
- lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD);
|
||||
-
|
||||
+ if (soft_limit_excess(memcg))
|
||||
+ lru_gen_soft_reclaim(&memcg->nodeinfo[nid]->lruvec);
|
||||
return;
|
||||
}
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 74b4f9d660b56..ccde215c084ca 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4689,6 +4689,148 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
|
||||
mem_cgroup_unlock_pages();
|
||||
}
|
||||
|
||||
+/******************************************************************************
|
||||
+ * memcg LRU
|
||||
+ ******************************************************************************/
|
||||
+
|
||||
+/* see the comment on MEMCG_NR_GENS */
|
||||
+enum {
|
||||
+ MEMCG_LRU_NOP,
|
||||
+ MEMCG_LRU_HEAD,
|
||||
+ MEMCG_LRU_TAIL,
|
||||
+ MEMCG_LRU_OLD,
|
||||
+ MEMCG_LRU_YOUNG,
|
||||
+};
|
||||
+
|
||||
+#ifdef CONFIG_MEMCG
|
||||
+
|
||||
+static int lru_gen_memcg_seg(struct lruvec *lruvec)
|
||||
+{
|
||||
+ return READ_ONCE(lruvec->lrugen.seg);
|
||||
+}
|
||||
+
|
||||
+static void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
|
||||
+{
|
||||
+ int seg;
|
||||
+ int old, new;
|
||||
+ int bin = get_random_u32_below(MEMCG_NR_BINS);
|
||||
+ struct pglist_data *pgdat = lruvec_pgdat(lruvec);
|
||||
+
|
||||
+ spin_lock(&pgdat->memcg_lru.lock);
|
||||
+
|
||||
+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
|
||||
+
|
||||
+ seg = 0;
|
||||
+ new = old = lruvec->lrugen.gen;
|
||||
+
|
||||
+ /* see the comment on MEMCG_NR_GENS */
|
||||
+ if (op == MEMCG_LRU_HEAD)
|
||||
+ seg = MEMCG_LRU_HEAD;
|
||||
+ else if (op == MEMCG_LRU_TAIL)
|
||||
+ seg = MEMCG_LRU_TAIL;
|
||||
+ else if (op == MEMCG_LRU_OLD)
|
||||
+ new = get_memcg_gen(pgdat->memcg_lru.seq);
|
||||
+ else if (op == MEMCG_LRU_YOUNG)
|
||||
+ new = get_memcg_gen(pgdat->memcg_lru.seq + 1);
|
||||
+ else
|
||||
+ VM_WARN_ON_ONCE(true);
|
||||
+
|
||||
+ hlist_nulls_del_rcu(&lruvec->lrugen.list);
|
||||
+
|
||||
+ if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD)
|
||||
+ hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
|
||||
+ else
|
||||
+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
|
||||
+
|
||||
+ pgdat->memcg_lru.nr_memcgs[old]--;
|
||||
+ pgdat->memcg_lru.nr_memcgs[new]++;
|
||||
+
|
||||
+ lruvec->lrugen.gen = new;
|
||||
+ WRITE_ONCE(lruvec->lrugen.seg, seg);
|
||||
+
|
||||
+ if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq))
|
||||
+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
|
||||
+
|
||||
+ spin_unlock(&pgdat->memcg_lru.lock);
|
||||
+}
|
||||
+
|
||||
+void lru_gen_online_memcg(struct mem_cgroup *memcg)
|
||||
+{
|
||||
+ int gen;
|
||||
+ int nid;
|
||||
+ int bin = get_random_u32_below(MEMCG_NR_BINS);
|
||||
+
|
||||
+ for_each_node(nid) {
|
||||
+ struct pglist_data *pgdat = NODE_DATA(nid);
|
||||
+ struct lruvec *lruvec = get_lruvec(memcg, nid);
|
||||
+
|
||||
+ spin_lock(&pgdat->memcg_lru.lock);
|
||||
+
|
||||
+ VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list));
|
||||
+
|
||||
+ gen = get_memcg_gen(pgdat->memcg_lru.seq);
|
||||
+
|
||||
+ hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]);
|
||||
+ pgdat->memcg_lru.nr_memcgs[gen]++;
|
||||
+
|
||||
+ lruvec->lrugen.gen = gen;
|
||||
+
|
||||
+ spin_unlock(&pgdat->memcg_lru.lock);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void lru_gen_offline_memcg(struct mem_cgroup *memcg)
|
||||
+{
|
||||
+ int nid;
|
||||
+
|
||||
+ for_each_node(nid) {
|
||||
+ struct lruvec *lruvec = get_lruvec(memcg, nid);
|
||||
+
|
||||
+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void lru_gen_release_memcg(struct mem_cgroup *memcg)
|
||||
+{
|
||||
+ int gen;
|
||||
+ int nid;
|
||||
+
|
||||
+ for_each_node(nid) {
|
||||
+ struct pglist_data *pgdat = NODE_DATA(nid);
|
||||
+ struct lruvec *lruvec = get_lruvec(memcg, nid);
|
||||
+
|
||||
+ spin_lock(&pgdat->memcg_lru.lock);
|
||||
+
|
||||
+ VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
|
||||
+
|
||||
+ gen = lruvec->lrugen.gen;
|
||||
+
|
||||
+ hlist_nulls_del_rcu(&lruvec->lrugen.list);
|
||||
+ pgdat->memcg_lru.nr_memcgs[gen]--;
|
||||
+
|
||||
+ if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq))
|
||||
+ WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
|
||||
+
|
||||
+ spin_unlock(&pgdat->memcg_lru.lock);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void lru_gen_soft_reclaim(struct lruvec *lruvec)
|
||||
+{
|
||||
+ /* see the comment on MEMCG_NR_GENS */
|
||||
+ if (lru_gen_memcg_seg(lruvec) != MEMCG_LRU_HEAD)
|
||||
+ lru_gen_rotate_memcg(lruvec, MEMCG_LRU_HEAD);
|
||||
+}
|
||||
+
|
||||
+#else /* !CONFIG_MEMCG */
|
||||
+
|
||||
+static int lru_gen_memcg_seg(struct lruvec *lruvec)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
/******************************************************************************
|
||||
* the eviction
|
||||
******************************************************************************/
|
||||
@@ -5386,53 +5528,6 @@ static void lru_gen_shrink_node(struct pglist_data *pgdat, struct scan_control *
|
||||
pgdat->kswapd_failures = 0;
|
||||
}
|
||||
|
||||
-#ifdef CONFIG_MEMCG
|
||||
-void lru_gen_rotate_memcg(struct lruvec *lruvec, int op)
|
||||
-{
|
||||
- int seg;
|
||||
- int old, new;
|
||||
- int bin = get_random_u32_below(MEMCG_NR_BINS);
|
||||
- struct pglist_data *pgdat = lruvec_pgdat(lruvec);
|
||||
-
|
||||
- spin_lock(&pgdat->memcg_lru.lock);
|
||||
-
|
||||
- VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
|
||||
-
|
||||
- seg = 0;
|
||||
- new = old = lruvec->lrugen.gen;
|
||||
-
|
||||
- /* see the comment on MEMCG_NR_GENS */
|
||||
- if (op == MEMCG_LRU_HEAD)
|
||||
- seg = MEMCG_LRU_HEAD;
|
||||
- else if (op == MEMCG_LRU_TAIL)
|
||||
- seg = MEMCG_LRU_TAIL;
|
||||
- else if (op == MEMCG_LRU_OLD)
|
||||
- new = get_memcg_gen(pgdat->memcg_lru.seq);
|
||||
- else if (op == MEMCG_LRU_YOUNG)
|
||||
- new = get_memcg_gen(pgdat->memcg_lru.seq + 1);
|
||||
- else
|
||||
- VM_WARN_ON_ONCE(true);
|
||||
-
|
||||
- hlist_nulls_del_rcu(&lruvec->lrugen.list);
|
||||
-
|
||||
- if (op == MEMCG_LRU_HEAD || op == MEMCG_LRU_OLD)
|
||||
- hlist_nulls_add_head_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
|
||||
- else
|
||||
- hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[new][bin]);
|
||||
-
|
||||
- pgdat->memcg_lru.nr_memcgs[old]--;
|
||||
- pgdat->memcg_lru.nr_memcgs[new]++;
|
||||
-
|
||||
- lruvec->lrugen.gen = new;
|
||||
- WRITE_ONCE(lruvec->lrugen.seg, seg);
|
||||
-
|
||||
- if (!pgdat->memcg_lru.nr_memcgs[old] && old == get_memcg_gen(pgdat->memcg_lru.seq))
|
||||
- WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
|
||||
-
|
||||
- spin_unlock(&pgdat->memcg_lru.lock);
|
||||
-}
|
||||
-#endif
|
||||
-
|
||||
/******************************************************************************
|
||||
* state change
|
||||
******************************************************************************/
|
||||
@@ -6078,67 +6173,6 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
|
||||
}
|
||||
}
|
||||
|
||||
-void lru_gen_online_memcg(struct mem_cgroup *memcg)
|
||||
-{
|
||||
- int gen;
|
||||
- int nid;
|
||||
- int bin = get_random_u32_below(MEMCG_NR_BINS);
|
||||
-
|
||||
- for_each_node(nid) {
|
||||
- struct pglist_data *pgdat = NODE_DATA(nid);
|
||||
- struct lruvec *lruvec = get_lruvec(memcg, nid);
|
||||
-
|
||||
- spin_lock(&pgdat->memcg_lru.lock);
|
||||
-
|
||||
- VM_WARN_ON_ONCE(!hlist_nulls_unhashed(&lruvec->lrugen.list));
|
||||
-
|
||||
- gen = get_memcg_gen(pgdat->memcg_lru.seq);
|
||||
-
|
||||
- hlist_nulls_add_tail_rcu(&lruvec->lrugen.list, &pgdat->memcg_lru.fifo[gen][bin]);
|
||||
- pgdat->memcg_lru.nr_memcgs[gen]++;
|
||||
-
|
||||
- lruvec->lrugen.gen = gen;
|
||||
-
|
||||
- spin_unlock(&pgdat->memcg_lru.lock);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-void lru_gen_offline_memcg(struct mem_cgroup *memcg)
|
||||
-{
|
||||
- int nid;
|
||||
-
|
||||
- for_each_node(nid) {
|
||||
- struct lruvec *lruvec = get_lruvec(memcg, nid);
|
||||
-
|
||||
- lru_gen_rotate_memcg(lruvec, MEMCG_LRU_OLD);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-void lru_gen_release_memcg(struct mem_cgroup *memcg)
|
||||
-{
|
||||
- int gen;
|
||||
- int nid;
|
||||
-
|
||||
- for_each_node(nid) {
|
||||
- struct pglist_data *pgdat = NODE_DATA(nid);
|
||||
- struct lruvec *lruvec = get_lruvec(memcg, nid);
|
||||
-
|
||||
- spin_lock(&pgdat->memcg_lru.lock);
|
||||
-
|
||||
- VM_WARN_ON_ONCE(hlist_nulls_unhashed(&lruvec->lrugen.list));
|
||||
-
|
||||
- gen = lruvec->lrugen.gen;
|
||||
-
|
||||
- hlist_nulls_del_rcu(&lruvec->lrugen.list);
|
||||
- pgdat->memcg_lru.nr_memcgs[gen]--;
|
||||
-
|
||||
- if (!pgdat->memcg_lru.nr_memcgs[gen] && gen == get_memcg_gen(pgdat->memcg_lru.seq))
|
||||
- WRITE_ONCE(pgdat->memcg_lru.seq, pgdat->memcg_lru.seq + 1);
|
||||
-
|
||||
- spin_unlock(&pgdat->memcg_lru.lock);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
#endif /* CONFIG_MEMCG */
|
||||
|
||||
static int __init init_lru_gen(void)
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
From bec433f29537652ed054148edfd7e2183ddcf7c3 Mon Sep 17 00:00:00 2001
|
||||
From: "T.J. Alumbaugh" <talumbau@google.com>
|
||||
Date: Wed, 18 Jan 2023 00:18:25 +0000
|
||||
Subject: [PATCH 16/19] UPSTREAM: mm: multi-gen LRU: improve
|
||||
lru_gen_exit_memcg()
|
||||
|
||||
Add warnings and poison ->next.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20230118001827.1040870-6-talumbau@google.com
|
||||
Change-Id: I53de9e04c1ae941e122b33cd45d2bbb5f34aae0c
|
||||
Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
|
||||
Cc: Yu Zhao <yuzhao@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
(cherry picked from commit 37cc99979d04cca677c0ad5c0acd1149ec165d1b)
|
||||
Bug: 274865848
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
mm/vmscan.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index ccde215c084ca..d5d6f8d94f58a 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -6160,12 +6160,17 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
|
||||
int i;
|
||||
int nid;
|
||||
|
||||
+ VM_WARN_ON_ONCE(!list_empty(&memcg->mm_list.fifo));
|
||||
+
|
||||
for_each_node(nid) {
|
||||
struct lruvec *lruvec = get_lruvec(memcg, nid);
|
||||
|
||||
+ VM_WARN_ON_ONCE(lruvec->mm_state.nr_walkers);
|
||||
VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0,
|
||||
sizeof(lruvec->lrugen.nr_pages)));
|
||||
|
||||
+ lruvec->lrugen.list.next = LIST_POISON1;
|
||||
+
|
||||
for (i = 0; i < NR_BLOOM_FILTERS; i++) {
|
||||
bitmap_free(lruvec->mm_state.filters[i]);
|
||||
lruvec->mm_state.filters[i] = NULL;
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
From fc0e3b06e0f19917b7ecad7967a72f61d4743644 Mon Sep 17 00:00:00 2001
|
||||
From: "T.J. Alumbaugh" <talumbau@google.com>
|
||||
Date: Wed, 18 Jan 2023 00:18:26 +0000
|
||||
Subject: [PATCH 17/19] UPSTREAM: mm: multi-gen LRU: improve walk_pmd_range()
|
||||
|
||||
Improve readability of walk_pmd_range() and walk_pmd_range_locked().
|
||||
|
||||
Link: https://lkml.kernel.org/r/20230118001827.1040870-7-talumbau@google.com
|
||||
Change-Id: Ia084fbf53fe989673b7804ca8ca520af12d7d52a
|
||||
Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
|
||||
Cc: Yu Zhao <yuzhao@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
(cherry picked from commit b5ff4133617d0eced35b685da0bd0929dd9fabb7)
|
||||
Bug: 274865848
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
mm/vmscan.c | 40 ++++++++++++++++++++--------------------
|
||||
1 file changed, 20 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index d5d6f8d94f58a..8f496c2e670a9 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3980,8 +3980,8 @@ static bool walk_pte_range(pmd_t *pmd, unsigned long start, unsigned long end,
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
|
||||
-static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma,
|
||||
- struct mm_walk *args, unsigned long *bitmap, unsigned long *start)
|
||||
+static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area_struct *vma,
|
||||
+ struct mm_walk *args, unsigned long *bitmap, unsigned long *first)
|
||||
{
|
||||
int i;
|
||||
pmd_t *pmd;
|
||||
@@ -3994,18 +3994,19 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area
|
||||
VM_WARN_ON_ONCE(pud_leaf(*pud));
|
||||
|
||||
/* try to batch at most 1+MIN_LRU_BATCH+1 entries */
|
||||
- if (*start == -1) {
|
||||
- *start = next;
|
||||
+ if (*first == -1) {
|
||||
+ *first = addr;
|
||||
+ bitmap_zero(bitmap, MIN_LRU_BATCH);
|
||||
return;
|
||||
}
|
||||
|
||||
- i = next == -1 ? 0 : pmd_index(next) - pmd_index(*start);
|
||||
+ i = addr == -1 ? 0 : pmd_index(addr) - pmd_index(*first);
|
||||
if (i && i <= MIN_LRU_BATCH) {
|
||||
__set_bit(i - 1, bitmap);
|
||||
return;
|
||||
}
|
||||
|
||||
- pmd = pmd_offset(pud, *start);
|
||||
+ pmd = pmd_offset(pud, *first);
|
||||
|
||||
ptl = pmd_lockptr(args->mm, pmd);
|
||||
if (!spin_trylock(ptl))
|
||||
@@ -4016,15 +4017,16 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area
|
||||
do {
|
||||
unsigned long pfn;
|
||||
struct folio *folio;
|
||||
- unsigned long addr = i ? (*start & PMD_MASK) + i * PMD_SIZE : *start;
|
||||
+
|
||||
+ /* don't round down the first address */
|
||||
+ addr = i ? (*first & PMD_MASK) + i * PMD_SIZE : *first;
|
||||
|
||||
pfn = get_pmd_pfn(pmd[i], vma, addr);
|
||||
if (pfn == -1)
|
||||
goto next;
|
||||
|
||||
if (!pmd_trans_huge(pmd[i])) {
|
||||
- if (arch_has_hw_nonleaf_pmd_young() &&
|
||||
- get_cap(LRU_GEN_NONLEAF_YOUNG))
|
||||
+ if (arch_has_hw_nonleaf_pmd_young() && get_cap(LRU_GEN_NONLEAF_YOUNG))
|
||||
pmdp_test_and_clear_young(vma, addr, pmd + i);
|
||||
goto next;
|
||||
}
|
||||
@@ -4053,12 +4055,11 @@ static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area
|
||||
arch_leave_lazy_mmu_mode();
|
||||
spin_unlock(ptl);
|
||||
done:
|
||||
- *start = -1;
|
||||
- bitmap_zero(bitmap, MIN_LRU_BATCH);
|
||||
+ *first = -1;
|
||||
}
|
||||
#else
|
||||
-static void walk_pmd_range_locked(pud_t *pud, unsigned long next, struct vm_area_struct *vma,
|
||||
- struct mm_walk *args, unsigned long *bitmap, unsigned long *start)
|
||||
+static void walk_pmd_range_locked(pud_t *pud, unsigned long addr, struct vm_area_struct *vma,
|
||||
+ struct mm_walk *args, unsigned long *bitmap, unsigned long *first)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@@ -4071,9 +4072,9 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
|
||||
unsigned long next;
|
||||
unsigned long addr;
|
||||
struct vm_area_struct *vma;
|
||||
- unsigned long pos = -1;
|
||||
+ unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)];
|
||||
+ unsigned long first = -1;
|
||||
struct lru_gen_mm_walk *walk = args->private;
|
||||
- unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {};
|
||||
|
||||
VM_WARN_ON_ONCE(pud_leaf(*pud));
|
||||
|
||||
@@ -4115,18 +4116,17 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
|
||||
if (pfn < pgdat->node_start_pfn || pfn >= pgdat_end_pfn(pgdat))
|
||||
continue;
|
||||
|
||||
- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos);
|
||||
+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
walk->mm_stats[MM_NONLEAF_TOTAL]++;
|
||||
|
||||
- if (arch_has_hw_nonleaf_pmd_young() &&
|
||||
- get_cap(LRU_GEN_NONLEAF_YOUNG)) {
|
||||
+ if (arch_has_hw_nonleaf_pmd_young() && get_cap(LRU_GEN_NONLEAF_YOUNG)) {
|
||||
if (!pmd_young(val))
|
||||
continue;
|
||||
|
||||
- walk_pmd_range_locked(pud, addr, vma, args, bitmap, &pos);
|
||||
+ walk_pmd_range_locked(pud, addr, vma, args, bitmap, &first);
|
||||
}
|
||||
|
||||
if (!walk->force_scan && !test_bloom_filter(walk->lruvec, walk->max_seq, pmd + i))
|
||||
@@ -4143,7 +4143,7 @@ static void walk_pmd_range(pud_t *pud, unsigned long start, unsigned long end,
|
||||
update_bloom_filter(walk->lruvec, walk->max_seq + 1, pmd + i);
|
||||
}
|
||||
|
||||
- walk_pmd_range_locked(pud, -1, vma, args, bitmap, &pos);
|
||||
+ walk_pmd_range_locked(pud, -1, vma, args, bitmap, &first);
|
||||
|
||||
if (i < PTRS_PER_PMD && get_next_vma(PUD_MASK, PMD_SIZE, args, &start, &end))
|
||||
goto restart;
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
From e604c3ccb4dfbdde2467fccef9bb36170a392695 Mon Sep 17 00:00:00 2001
|
||||
From: "T.J. Alumbaugh" <talumbau@google.com>
|
||||
Date: Wed, 18 Jan 2023 00:18:27 +0000
|
||||
Subject: [PATCH 18/19] UPSTREAM: mm: multi-gen LRU: simplify
|
||||
lru_gen_look_around()
|
||||
|
||||
Update the folio generation in place with or without
|
||||
current->reclaim_state->mm_walk. The LRU lock is held for longer, if
|
||||
mm_walk is NULL and the number of folios to update is more than
|
||||
PAGEVEC_SIZE.
|
||||
|
||||
This causes a measurable regression from the LRU lock contention during a
|
||||
microbencmark. But a tiny regression is not worth the complexity.
|
||||
|
||||
Link: https://lkml.kernel.org/r/20230118001827.1040870-8-talumbau@google.com
|
||||
Change-Id: I9ce18b4f4062e6c1c13c98ece9422478eb8e1846
|
||||
Signed-off-by: T.J. Alumbaugh <talumbau@google.com>
|
||||
Cc: Yu Zhao <yuzhao@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
(cherry picked from commit abf086721a2f1e6897c57796f7268df1b194c750)
|
||||
Bug: 274865848
|
||||
Signed-off-by: T.J. Mercier <tjmercier@google.com>
|
||||
---
|
||||
mm/vmscan.c | 73 +++++++++++++++++------------------------------------
|
||||
1 file changed, 23 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index 8f496c2e670a9..f6ce7a1fd78a3 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -4571,13 +4571,12 @@ static void lru_gen_age_node(struct pglist_data *pgdat, struct scan_control *sc)
|
||||
void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
|
||||
{
|
||||
int i;
|
||||
- pte_t *pte;
|
||||
unsigned long start;
|
||||
unsigned long end;
|
||||
- unsigned long addr;
|
||||
struct lru_gen_mm_walk *walk;
|
||||
int young = 0;
|
||||
- unsigned long bitmap[BITS_TO_LONGS(MIN_LRU_BATCH)] = {};
|
||||
+ pte_t *pte = pvmw->pte;
|
||||
+ unsigned long addr = pvmw->address;
|
||||
struct folio *folio = pfn_folio(pvmw->pfn);
|
||||
struct mem_cgroup *memcg = folio_memcg(folio);
|
||||
struct pglist_data *pgdat = folio_pgdat(folio);
|
||||
@@ -4594,25 +4593,28 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
|
||||
/* avoid taking the LRU lock under the PTL when possible */
|
||||
walk = current->reclaim_state ? current->reclaim_state->mm_walk : NULL;
|
||||
|
||||
- start = max(pvmw->address & PMD_MASK, pvmw->vma->vm_start);
|
||||
- end = min(pvmw->address | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1;
|
||||
+ start = max(addr & PMD_MASK, pvmw->vma->vm_start);
|
||||
+ end = min(addr | ~PMD_MASK, pvmw->vma->vm_end - 1) + 1;
|
||||
|
||||
if (end - start > MIN_LRU_BATCH * PAGE_SIZE) {
|
||||
- if (pvmw->address - start < MIN_LRU_BATCH * PAGE_SIZE / 2)
|
||||
+ if (addr - start < MIN_LRU_BATCH * PAGE_SIZE / 2)
|
||||
end = start + MIN_LRU_BATCH * PAGE_SIZE;
|
||||
- else if (end - pvmw->address < MIN_LRU_BATCH * PAGE_SIZE / 2)
|
||||
+ else if (end - addr < MIN_LRU_BATCH * PAGE_SIZE / 2)
|
||||
start = end - MIN_LRU_BATCH * PAGE_SIZE;
|
||||
else {
|
||||
- start = pvmw->address - MIN_LRU_BATCH * PAGE_SIZE / 2;
|
||||
- end = pvmw->address + MIN_LRU_BATCH * PAGE_SIZE / 2;
|
||||
+ start = addr - MIN_LRU_BATCH * PAGE_SIZE / 2;
|
||||
+ end = addr + MIN_LRU_BATCH * PAGE_SIZE / 2;
|
||||
}
|
||||
}
|
||||
|
||||
- pte = pvmw->pte - (pvmw->address - start) / PAGE_SIZE;
|
||||
+ /* folio_update_gen() requires stable folio_memcg() */
|
||||
+ if (!mem_cgroup_trylock_pages(memcg))
|
||||
+ return;
|
||||
|
||||
- rcu_read_lock();
|
||||
arch_enter_lazy_mmu_mode();
|
||||
|
||||
+ pte -= (addr - start) / PAGE_SIZE;
|
||||
+
|
||||
for (i = 0, addr = start; addr != end; i++, addr += PAGE_SIZE) {
|
||||
unsigned long pfn;
|
||||
|
||||
@@ -4637,56 +4639,27 @@ void lru_gen_look_around(struct page_vma_mapped_walk *pvmw)
|
||||
!folio_test_swapcache(folio)))
|
||||
folio_mark_dirty(folio);
|
||||
|
||||
+ if (walk) {
|
||||
+ old_gen = folio_update_gen(folio, new_gen);
|
||||
+ if (old_gen >= 0 && old_gen != new_gen)
|
||||
+ update_batch_size(walk, folio, old_gen, new_gen);
|
||||
+
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
old_gen = folio_lru_gen(folio);
|
||||
if (old_gen < 0)
|
||||
folio_set_referenced(folio);
|
||||
else if (old_gen != new_gen)
|
||||
- __set_bit(i, bitmap);
|
||||
+ folio_activate(folio);
|
||||
}
|
||||
|
||||
arch_leave_lazy_mmu_mode();
|
||||
- rcu_read_unlock();
|
||||
+ mem_cgroup_unlock_pages();
|
||||
|
||||
/* feedback from rmap walkers to page table walkers */
|
||||
if (suitable_to_scan(i, young))
|
||||
update_bloom_filter(lruvec, max_seq, pvmw->pmd);
|
||||
-
|
||||
- if (!walk && bitmap_weight(bitmap, MIN_LRU_BATCH) < PAGEVEC_SIZE) {
|
||||
- for_each_set_bit(i, bitmap, MIN_LRU_BATCH) {
|
||||
- folio = pfn_folio(pte_pfn(pte[i]));
|
||||
- folio_activate(folio);
|
||||
- }
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- /* folio_update_gen() requires stable folio_memcg() */
|
||||
- if (!mem_cgroup_trylock_pages(memcg))
|
||||
- return;
|
||||
-
|
||||
- if (!walk) {
|
||||
- spin_lock_irq(&lruvec->lru_lock);
|
||||
- new_gen = lru_gen_from_seq(lruvec->lrugen.max_seq);
|
||||
- }
|
||||
-
|
||||
- for_each_set_bit(i, bitmap, MIN_LRU_BATCH) {
|
||||
- folio = pfn_folio(pte_pfn(pte[i]));
|
||||
- if (folio_memcg_rcu(folio) != memcg)
|
||||
- continue;
|
||||
-
|
||||
- old_gen = folio_update_gen(folio, new_gen);
|
||||
- if (old_gen < 0 || old_gen == new_gen)
|
||||
- continue;
|
||||
-
|
||||
- if (walk)
|
||||
- update_batch_size(walk, folio, old_gen, new_gen);
|
||||
- else
|
||||
- lru_gen_update_size(lruvec, folio, old_gen, new_gen);
|
||||
- }
|
||||
-
|
||||
- if (!walk)
|
||||
- spin_unlock_irq(&lruvec->lru_lock);
|
||||
-
|
||||
- mem_cgroup_unlock_pages();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -0,0 +1,280 @@
|
|||
From 418038c22452df38cde519cc8c662bb15139764a Mon Sep 17 00:00:00 2001
|
||||
From: Kalesh Singh <kaleshsingh@google.com>
|
||||
Date: Thu, 13 Apr 2023 14:43:26 -0700
|
||||
Subject: [PATCH 19/19] mm: Multi-gen LRU: remove wait_event_killable()
|
||||
|
||||
Android 14 and later default to MGLRU [1] and field telemetry showed
|
||||
occasional long tail latency (>100ms) in the reclaim path.
|
||||
|
||||
Tracing revealed priority inversion in the reclaim path. In
|
||||
try_to_inc_max_seq(), when high priority tasks were blocked on
|
||||
wait_event_killable(), the preemption of the low priority task to call
|
||||
wake_up_all() caused those high priority tasks to wait longer than
|
||||
necessary. In general, this problem is not different from others of its
|
||||
kind, e.g., one caused by mutex_lock(). However, it is specific to MGLRU
|
||||
because it introduced the new wait queue lruvec->mm_state.wait.
|
||||
|
||||
The purpose of this new wait queue is to avoid the thundering herd
|
||||
problem. If many direct reclaimers rush into try_to_inc_max_seq(), only
|
||||
one can succeed, i.e., the one to wake up the rest, and the rest who
|
||||
failed might cause premature OOM kills if they do not wait. So far there
|
||||
is no evidence supporting this scenario, based on how often the wait has
|
||||
been hit. And this begs the question how useful the wait queue is in
|
||||
practice.
|
||||
|
||||
Based on Minchan's recommendation, which is in line with his commit
|
||||
6d4675e60135 ("mm: don't be stuck to rmap lock on reclaim path") and the
|
||||
rest of the MGLRU code which also uses trylock when possible, remove the
|
||||
wait queue.
|
||||
|
||||
[1] https://android-review.googlesource.com/q/I7ed7fbfd6ef9ce10053347528125dd98c39e50bf
|
||||
|
||||
Link: https://lkml.kernel.org/r/20230413214326.2147568-1-kaleshsingh@google.com
|
||||
Fixes: bd74fdaea146 ("mm: multi-gen LRU: support page table walks")
|
||||
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
|
||||
Suggested-by: Minchan Kim <minchan@kernel.org>
|
||||
Reported-by: Wei Wang <wvw@google.com>
|
||||
Acked-by: Yu Zhao <yuzhao@google.com>
|
||||
Cc: Minchan Kim <minchan@kernel.org>
|
||||
Cc: Jan Alexander Steffens (heftig) <heftig@archlinux.org>
|
||||
Cc: Oleksandr Natalenko <oleksandr@natalenko.name>
|
||||
Cc: Suleiman Souhlal <suleiman@google.com>
|
||||
Cc: Suren Baghdasaryan <surenb@google.com>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
---
|
||||
include/linux/mmzone.h | 8 +--
|
||||
mm/vmscan.c | 112 +++++++++++++++--------------------------
|
||||
2 files changed, 42 insertions(+), 78 deletions(-)
|
||||
|
||||
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
|
||||
index 403c7461e7a70..d62a5accf1be4 100644
|
||||
--- a/include/linux/mmzone.h
|
||||
+++ b/include/linux/mmzone.h
|
||||
@@ -453,18 +453,14 @@ enum {
|
||||
struct lru_gen_mm_state {
|
||||
/* set to max_seq after each iteration */
|
||||
unsigned long seq;
|
||||
- /* where the current iteration continues (inclusive) */
|
||||
+ /* where the current iteration continues after */
|
||||
struct list_head *head;
|
||||
- /* where the last iteration ended (exclusive) */
|
||||
+ /* where the last iteration ended before */
|
||||
struct list_head *tail;
|
||||
- /* to wait for the last page table walker to finish */
|
||||
- struct wait_queue_head wait;
|
||||
/* Bloom filters flip after each iteration */
|
||||
unsigned long *filters[NR_BLOOM_FILTERS];
|
||||
/* the mm stats for debugging */
|
||||
unsigned long stats[NR_HIST_GENS][NR_MM_STATS];
|
||||
- /* the number of concurrent page table walkers */
|
||||
- int nr_walkers;
|
||||
};
|
||||
|
||||
struct lru_gen_mm_walk {
|
||||
diff --git a/mm/vmscan.c b/mm/vmscan.c
|
||||
index f6ce7a1fd78a3..851758303dbf4 100644
|
||||
--- a/mm/vmscan.c
|
||||
+++ b/mm/vmscan.c
|
||||
@@ -3371,18 +3371,13 @@ void lru_gen_del_mm(struct mm_struct *mm)
|
||||
if (!lruvec)
|
||||
continue;
|
||||
|
||||
- /* where the last iteration ended (exclusive) */
|
||||
+ /* where the current iteration continues after */
|
||||
+ if (lruvec->mm_state.head == &mm->lru_gen.list)
|
||||
+ lruvec->mm_state.head = lruvec->mm_state.head->prev;
|
||||
+
|
||||
+ /* where the last iteration ended before */
|
||||
if (lruvec->mm_state.tail == &mm->lru_gen.list)
|
||||
lruvec->mm_state.tail = lruvec->mm_state.tail->next;
|
||||
-
|
||||
- /* where the current iteration continues (inclusive) */
|
||||
- if (lruvec->mm_state.head != &mm->lru_gen.list)
|
||||
- continue;
|
||||
-
|
||||
- lruvec->mm_state.head = lruvec->mm_state.head->next;
|
||||
- /* the deletion ends the current iteration */
|
||||
- if (lruvec->mm_state.head == &mm_list->fifo)
|
||||
- WRITE_ONCE(lruvec->mm_state.seq, lruvec->mm_state.seq + 1);
|
||||
}
|
||||
|
||||
list_del_init(&mm->lru_gen.list);
|
||||
@@ -3478,68 +3473,54 @@ static bool iterate_mm_list(struct lruvec *lruvec, struct lru_gen_mm_walk *walk,
|
||||
struct mm_struct **iter)
|
||||
{
|
||||
bool first = false;
|
||||
- bool last = true;
|
||||
+ bool last = false;
|
||||
struct mm_struct *mm = NULL;
|
||||
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
|
||||
struct lru_gen_mm_list *mm_list = get_mm_list(memcg);
|
||||
struct lru_gen_mm_state *mm_state = &lruvec->mm_state;
|
||||
|
||||
/*
|
||||
- * There are four interesting cases for this page table walker:
|
||||
- * 1. It tries to start a new iteration of mm_list with a stale max_seq;
|
||||
- * there is nothing left to do.
|
||||
- * 2. It's the first of the current generation, and it needs to reset
|
||||
- * the Bloom filter for the next generation.
|
||||
- * 3. It reaches the end of mm_list, and it needs to increment
|
||||
- * mm_state->seq; the iteration is done.
|
||||
- * 4. It's the last of the current generation, and it needs to reset the
|
||||
- * mm stats counters for the next generation.
|
||||
+ * mm_state->seq is incremented after each iteration of mm_list. There
|
||||
+ * are three interesting cases for this page table walker:
|
||||
+ * 1. It tries to start a new iteration with a stale max_seq: there is
|
||||
+ * nothing left to do.
|
||||
+ * 2. It started the next iteration: it needs to reset the Bloom filter
|
||||
+ * so that a fresh set of PTE tables can be recorded.
|
||||
+ * 3. It ended the current iteration: it needs to reset the mm stats
|
||||
+ * counters and tell its caller to increment max_seq.
|
||||
*/
|
||||
spin_lock(&mm_list->lock);
|
||||
|
||||
VM_WARN_ON_ONCE(mm_state->seq + 1 < walk->max_seq);
|
||||
- VM_WARN_ON_ONCE(*iter && mm_state->seq > walk->max_seq);
|
||||
- VM_WARN_ON_ONCE(*iter && !mm_state->nr_walkers);
|
||||
|
||||
- if (walk->max_seq <= mm_state->seq) {
|
||||
- if (!*iter)
|
||||
- last = false;
|
||||
+ if (walk->max_seq <= mm_state->seq)
|
||||
goto done;
|
||||
- }
|
||||
|
||||
- if (!mm_state->nr_walkers) {
|
||||
- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo);
|
||||
+ if (!mm_state->head)
|
||||
+ mm_state->head = &mm_list->fifo;
|
||||
|
||||
- mm_state->head = mm_list->fifo.next;
|
||||
+ if (mm_state->head == &mm_list->fifo)
|
||||
first = true;
|
||||
- }
|
||||
-
|
||||
- while (!mm && mm_state->head != &mm_list->fifo) {
|
||||
- mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list);
|
||||
|
||||
+ do {
|
||||
mm_state->head = mm_state->head->next;
|
||||
+ if (mm_state->head == &mm_list->fifo) {
|
||||
+ WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
|
||||
+ last = true;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
/* force scan for those added after the last iteration */
|
||||
- if (!mm_state->tail || mm_state->tail == &mm->lru_gen.list) {
|
||||
- mm_state->tail = mm_state->head;
|
||||
+ if (!mm_state->tail || mm_state->tail == mm_state->head) {
|
||||
+ mm_state->tail = mm_state->head->next;
|
||||
walk->force_scan = true;
|
||||
}
|
||||
|
||||
+ mm = list_entry(mm_state->head, struct mm_struct, lru_gen.list);
|
||||
if (should_skip_mm(mm, walk))
|
||||
mm = NULL;
|
||||
- }
|
||||
-
|
||||
- if (mm_state->head == &mm_list->fifo)
|
||||
- WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
|
||||
+ } while (!mm);
|
||||
done:
|
||||
- if (*iter && !mm)
|
||||
- mm_state->nr_walkers--;
|
||||
- if (!*iter && mm)
|
||||
- mm_state->nr_walkers++;
|
||||
-
|
||||
- if (mm_state->nr_walkers)
|
||||
- last = false;
|
||||
-
|
||||
if (*iter || last)
|
||||
reset_mm_stats(lruvec, walk, last);
|
||||
|
||||
@@ -3567,9 +3548,9 @@ static bool iterate_mm_list_nowalk(struct lruvec *lruvec, unsigned long max_seq)
|
||||
|
||||
VM_WARN_ON_ONCE(mm_state->seq + 1 < max_seq);
|
||||
|
||||
- if (max_seq > mm_state->seq && !mm_state->nr_walkers) {
|
||||
- VM_WARN_ON_ONCE(mm_state->head && mm_state->head != &mm_list->fifo);
|
||||
-
|
||||
+ if (max_seq > mm_state->seq) {
|
||||
+ mm_state->head = NULL;
|
||||
+ mm_state->tail = NULL;
|
||||
WRITE_ONCE(mm_state->seq, mm_state->seq + 1);
|
||||
reset_mm_stats(lruvec, NULL, true);
|
||||
success = true;
|
||||
@@ -4172,10 +4153,6 @@ static int walk_pud_range(p4d_t *p4d, unsigned long start, unsigned long end,
|
||||
|
||||
walk_pmd_range(&val, addr, next, args);
|
||||
|
||||
- /* a racy check to curtail the waiting time */
|
||||
- if (wq_has_sleeper(&walk->lruvec->mm_state.wait))
|
||||
- return 1;
|
||||
-
|
||||
if (need_resched() || walk->batched >= MAX_LRU_BATCH) {
|
||||
end = (addr | ~PUD_MASK) + 1;
|
||||
goto done;
|
||||
@@ -4208,8 +4185,14 @@ static void walk_mm(struct lruvec *lruvec, struct mm_struct *mm, struct lru_gen_
|
||||
walk->next_addr = FIRST_USER_ADDRESS;
|
||||
|
||||
do {
|
||||
+ DEFINE_MAX_SEQ(lruvec);
|
||||
+
|
||||
err = -EBUSY;
|
||||
|
||||
+ /* another thread might have called inc_max_seq() */
|
||||
+ if (walk->max_seq != max_seq)
|
||||
+ break;
|
||||
+
|
||||
/* folio_update_gen() requires stable folio_memcg() */
|
||||
if (!mem_cgroup_trylock_pages(memcg))
|
||||
break;
|
||||
@@ -4442,25 +4425,12 @@ static bool try_to_inc_max_seq(struct lruvec *lruvec, unsigned long max_seq,
|
||||
success = iterate_mm_list(lruvec, walk, &mm);
|
||||
if (mm)
|
||||
walk_mm(lruvec, mm, walk);
|
||||
-
|
||||
- cond_resched();
|
||||
} while (mm);
|
||||
done:
|
||||
- if (!success) {
|
||||
- if (sc->priority <= DEF_PRIORITY - 2)
|
||||
- wait_event_killable(lruvec->mm_state.wait,
|
||||
- max_seq < READ_ONCE(lrugen->max_seq));
|
||||
- return false;
|
||||
- }
|
||||
+ if (success)
|
||||
+ inc_max_seq(lruvec, can_swap, force_scan);
|
||||
|
||||
- VM_WARN_ON_ONCE(max_seq != READ_ONCE(lrugen->max_seq));
|
||||
-
|
||||
- inc_max_seq(lruvec, can_swap, force_scan);
|
||||
- /* either this sees any waiters or they will see updated max_seq */
|
||||
- if (wq_has_sleeper(&lruvec->mm_state.wait))
|
||||
- wake_up_all(&lruvec->mm_state.wait);
|
||||
-
|
||||
- return true;
|
||||
+ return success;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@@ -6105,7 +6075,6 @@ void lru_gen_init_lruvec(struct lruvec *lruvec)
|
||||
INIT_LIST_HEAD(&lrugen->folios[gen][type][zone]);
|
||||
|
||||
lruvec->mm_state.seq = MIN_NR_GENS;
|
||||
- init_waitqueue_head(&lruvec->mm_state.wait);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MEMCG
|
||||
@@ -6138,7 +6107,6 @@ void lru_gen_exit_memcg(struct mem_cgroup *memcg)
|
||||
for_each_node(nid) {
|
||||
struct lruvec *lruvec = get_lruvec(memcg, nid);
|
||||
|
||||
- VM_WARN_ON_ONCE(lruvec->mm_state.nr_walkers);
|
||||
VM_WARN_ON_ONCE(memchr_inv(lruvec->lrugen.nr_pages, 0,
|
||||
sizeof(lruvec->lrugen.nr_pages)));
|
||||
|
||||
--
|
||||
2.40.1
|
||||
|
|
@ -343,7 +343,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
|
|||
# CONFIG_ARM64_ERRATUM_858921 is not set
|
||||
# CONFIG_ARM64_HW_AFDBM is not set
|
||||
# CONFIG_ARM64_LSE_ATOMICS is not set
|
||||
# CONFIG_ARM64_MODULE_PLTS is not set
|
||||
CONFIG_ARM64_MODULE_PLTS=y
|
||||
# CONFIG_ARM64_MTE is not set
|
||||
# CONFIG_ARM64_PAN is not set
|
||||
# CONFIG_ARM64_PMEM is not set
|
||||
|
@ -408,7 +408,7 @@ CONFIG_ARM_GIC_MAX_NR=1
|
|||
# CONFIG_ARM_LPAE is not set
|
||||
# CONFIG_ARM_MEDIATEK_CPUFREQ_HW is not set
|
||||
# CONFIG_ARM_MHU is not set
|
||||
# CONFIG_ARM_MODULE_PLTS is not set
|
||||
CONFIG_ARM_MODULE_PLTS=y
|
||||
# CONFIG_ARM_PATCH_PHYS_VIRT is not set
|
||||
# CONFIG_ARM_PSCI is not set
|
||||
# CONFIG_ARM_PSCI_CHECKER is not set
|
||||
|
@ -7262,7 +7262,6 @@ CONFIG_VHOST_MENU=y
|
|||
# CONFIG_VIDEO_HEXIUM_ORION is not set
|
||||
# CONFIG_VIDEO_HI556 is not set
|
||||
# CONFIG_VIDEO_I2C is not set
|
||||
# CONFIG_VIDEO_IMX_PXP is not set
|
||||
# CONFIG_VIDEO_IMX208 is not set
|
||||
# CONFIG_VIDEO_IMX214 is not set
|
||||
# CONFIG_VIDEO_IMX219 is not set
|
||||
|
@ -7276,6 +7275,7 @@ CONFIG_VHOST_MENU=y
|
|||
# CONFIG_VIDEO_IMX412 is not set
|
||||
# CONFIG_VIDEO_IMX477 is not set
|
||||
# CONFIG_VIDEO_IMX8_JPEG is not set
|
||||
# CONFIG_VIDEO_IMX_PXP is not set
|
||||
# CONFIG_VIDEO_IRS1125 is not set
|
||||
# CONFIG_VIDEO_IR_I2C is not set
|
||||
# CONFIG_VIDEO_IVTV is not set
|
||||
|
|
|
@ -277,6 +277,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
|
|||
# CONFIG_ARCH_NOMADIK is not set
|
||||
# CONFIG_ARCH_NPCM is not set
|
||||
# CONFIG_ARCH_NSPIRE is not set
|
||||
# CONFIG_ARCH_NXP is not set
|
||||
# CONFIG_ARCH_OMAP is not set
|
||||
# CONFIG_ARCH_OMAP1 is not set
|
||||
# CONFIG_ARCH_OMAP2 is not set
|
||||
|
@ -367,7 +368,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8
|
|||
# CONFIG_ARM64_ERRATUM_858921 is not set
|
||||
# CONFIG_ARM64_HW_AFDBM is not set
|
||||
# CONFIG_ARM64_LSE_ATOMICS is not set
|
||||
# CONFIG_ARM64_MODULE_PLTS is not set
|
||||
CONFIG_ARM64_MODULE_PLTS=y
|
||||
# CONFIG_ARM64_MTE is not set
|
||||
# CONFIG_ARM64_PAN is not set
|
||||
# CONFIG_ARM64_PMEM is not set
|
||||
|
@ -433,7 +434,7 @@ CONFIG_ARM_GIC_MAX_NR=1
|
|||
# CONFIG_ARM_LPAE is not set
|
||||
# CONFIG_ARM_MEDIATEK_CPUFREQ_HW is not set
|
||||
# CONFIG_ARM_MHU is not set
|
||||
# CONFIG_ARM_MODULE_PLTS is not set
|
||||
CONFIG_ARM_MODULE_PLTS=y
|
||||
# CONFIG_ARM_PATCH_PHYS_VIRT is not set
|
||||
# CONFIG_ARM_PSCI is not set
|
||||
# CONFIG_ARM_PSCI_CHECKER is not set
|
||||
|
@ -912,8 +913,8 @@ CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
|
|||
# CONFIG_CEPH_FS is not set
|
||||
# CONFIG_CEPH_LIB is not set
|
||||
# CONFIG_CFG80211 is not set
|
||||
CONFIG_CFG80211_HEADERS=y
|
||||
# CONFIG_CFG80211_CERTIFICATION_ONUS is not set
|
||||
CONFIG_CFG80211_HEADERS=y
|
||||
# CONFIG_CGROUPS is not set
|
||||
# CONFIG_CGROUP_FAVOR_DYNMODS is not set
|
||||
# CONFIG_CGROUP_MISC is not set
|
||||
|
@ -1070,6 +1071,7 @@ CONFIG_CONSTRUCTORS=y
|
|||
# CONFIG_CPU_IDLE_GOV_TEO is not set
|
||||
# CONFIG_CPU_IDLE_MULTIPLE_DRIVERS is not set
|
||||
# CONFIG_CPU_ISOLATION is not set
|
||||
# CONFIG_CPU_LITTLE_ENDIAN is not set
|
||||
# CONFIG_CPU_NO_EFFICIENT_FFS is not set
|
||||
CONFIG_CPU_SW_DOMAIN_PAN=y
|
||||
# CONFIG_CPU_THERMAL is not set
|
||||
|
@ -2479,6 +2481,7 @@ CONFIG_HIGH_RES_TIMERS=y
|
|||
CONFIG_HPET_MMAP_DEFAULT=y
|
||||
# CONFIG_HPFS_FS is not set
|
||||
# CONFIG_HP_ILO is not set
|
||||
# CONFIG_HP_WATCHDOG is not set
|
||||
# CONFIG_HP_WIRELESS is not set
|
||||
# CONFIG_HSA_AMD is not set
|
||||
# CONFIG_HSI is not set
|
||||
|
@ -4560,6 +4563,7 @@ CONFIG_NMI_LOG_BUF_SHIFT=13
|
|||
# CONFIG_OCFS2_FS is not set
|
||||
# CONFIG_OCTEONTX2_AF is not set
|
||||
# CONFIG_OCTEONTX2_PF is not set
|
||||
# CONFIG_OCTEON_EP is not set
|
||||
# CONFIG_OF_OVERLAY is not set
|
||||
CONFIG_OF_RESERVED_MEM=y
|
||||
# CONFIG_OF_UNITTEST is not set
|
||||
|
@ -6535,6 +6539,7 @@ CONFIG_SUNRPC_DISABLE_INSECURE_ENCTYPES=y
|
|||
# CONFIG_SUNXI_SRAM is not set
|
||||
# CONFIG_SUN_PARTITION is not set
|
||||
# CONFIG_SURFACE_3_BUTTON is not set
|
||||
# CONFIG_SURFACE_PLATFORMS is not set
|
||||
# CONFIG_SUSPEND is not set
|
||||
# CONFIG_SUSPEND_SKIP_SYNC is not set
|
||||
CONFIG_SWAP=y
|
||||
|
@ -7450,7 +7455,6 @@ CONFIG_VHOST_MENU=y
|
|||
# CONFIG_VIDEO_HI846 is not set
|
||||
# CONFIG_VIDEO_HI847 is not set
|
||||
# CONFIG_VIDEO_I2C is not set
|
||||
# CONFIG_VIDEO_IMX_PXP is not set
|
||||
# CONFIG_VIDEO_IMX208 is not set
|
||||
# CONFIG_VIDEO_IMX214 is not set
|
||||
# CONFIG_VIDEO_IMX219 is not set
|
||||
|
@ -7464,6 +7468,7 @@ CONFIG_VHOST_MENU=y
|
|||
# CONFIG_VIDEO_IMX412 is not set
|
||||
# CONFIG_VIDEO_IMX477 is not set
|
||||
# CONFIG_VIDEO_IMX8_JPEG is not set
|
||||
# CONFIG_VIDEO_IMX_PXP is not set
|
||||
# CONFIG_VIDEO_IRS1125 is not set
|
||||
# CONFIG_VIDEO_IR_I2C is not set
|
||||
# CONFIG_VIDEO_ISL7998X is not set
|
||||
|
@ -7605,6 +7610,7 @@ CONFIG_VLAN_8021Q=y
|
|||
CONFIG_VMSPLIT_3G=y
|
||||
# CONFIG_VMSPLIT_3G_OPT is not set
|
||||
# CONFIG_VMWARE_PVSCSI is not set
|
||||
# CONFIG_VMWARE_VMCI is not set
|
||||
# CONFIG_VMXNET3 is not set
|
||||
# CONFIG_VM_EVENT_COUNTERS is not set
|
||||
# CONFIG_VOP_BUS is not set
|
||||
|
|
|
@ -10,6 +10,7 @@ CONFIG_CLANG_VERSION=.*
|
|||
# CONFIG_LD_.* is not set
|
||||
CONFIG_LLD_VERSION=.*
|
||||
CONFIG_PAHOLE_VERSION=.*
|
||||
CONFIG_PAHOLE_HAS_SPLIT_BTF=.*
|
||||
CONFIG_PLUGIN_HOSTCC=".*"
|
||||
# CONFIG_SET_FS is not set
|
||||
# CONFIG_TASKS_.* is not set
|
||||
|
|
|
@ -15,7 +15,7 @@ Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
|
|||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2347,6 +2347,10 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
@@ -2440,6 +2440,10 @@ mt7531_setup(struct dsa_switch *ds)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
From 663fa1b7e0cb2c929008482014a70c6625caad75 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 7 Mar 2023 15:55:13 +0000
|
||||
Subject: [PATCH 1/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V1 capability
|
||||
bit
|
||||
|
||||
Introduce MTK_NETSYS_V1 bit in the device capabilities for
|
||||
MT7621/MT7622/MT7623/MT7628/MT7629 SoCs.
|
||||
Use !MTK_NETSYS_V1 instead of MTK_NETSYS_V2 in the driver codebase.
|
||||
This is a preliminary patch to introduce support for MT7988 SoC.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 +++++++-------
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 45 ++++++++++++---------
|
||||
2 files changed, 41 insertions(+), 34 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -597,7 +597,7 @@ static void mtk_set_queue_speed(struct m
|
||||
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
|
||||
MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
|
||||
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
|
||||
|
||||
if (IS_ENABLED(CONFIG_SOC_MT7621)) {
|
||||
@@ -974,7 +974,7 @@ static bool mtk_rx_get_desc(struct mtk_e
|
||||
rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
|
||||
rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
|
||||
rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
|
||||
rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
|
||||
}
|
||||
@@ -1032,7 +1032,7 @@ static int mtk_init_fq_dma(struct mtk_et
|
||||
|
||||
txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
|
||||
txd->txd4 = 0;
|
||||
- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
|
||||
txd->txd5 = 0;
|
||||
txd->txd6 = 0;
|
||||
txd->txd7 = 0;
|
||||
@@ -1221,7 +1221,7 @@ static void mtk_tx_set_dma_desc(struct n
|
||||
struct mtk_mac *mac = netdev_priv(dev);
|
||||
struct mtk_eth *eth = mac->hw;
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
mtk_tx_set_dma_desc_v2(dev, txd, info);
|
||||
else
|
||||
mtk_tx_set_dma_desc_v1(dev, txd, info);
|
||||
@@ -1902,7 +1902,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
break;
|
||||
|
||||
/* find out which mac the packet come from. values start at 1 */
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
|
||||
else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
|
||||
!(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
|
||||
@@ -1998,7 +1998,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
skb->dev = netdev;
|
||||
bytes += skb->len;
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
|
||||
hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
|
||||
if (hash != MTK_RXD5_FOE_ENTRY)
|
||||
@@ -2023,7 +2023,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
/* When using VLAN untagging in combination with DSA, the
|
||||
* hardware treats the MTK special tag as a VLAN and untags it.
|
||||
*/
|
||||
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2) &&
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1) &&
|
||||
(trxd.rxd2 & RX_DMA_VTAG) && netdev_uses_dsa(netdev)) {
|
||||
unsigned int port = RX_DMA_VPID(trxd.rxd3) & GENMASK(2, 0);
|
||||
|
||||
@@ -2328,7 +2328,7 @@ static int mtk_tx_alloc(struct mtk_eth *
|
||||
txd->txd2 = next_ptr;
|
||||
txd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
|
||||
txd->txd4 = 0;
|
||||
- if (MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(soc->caps, MTK_NETSYS_V1)) {
|
||||
txd->txd5 = 0;
|
||||
txd->txd6 = 0;
|
||||
txd->txd7 = 0;
|
||||
@@ -2381,7 +2381,7 @@ static int mtk_tx_alloc(struct mtk_eth *
|
||||
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_MAN, 1) |
|
||||
FIELD_PREP(MTK_QTX_SCH_MIN_RATE_EXP, 4) |
|
||||
MTK_QTX_SCH_LEAKY_BUCKET_SIZE;
|
||||
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
val |= MTK_QTX_SCH_LEAKY_BUCKET_EN;
|
||||
mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
|
||||
ofs += MTK_QTX_OFFSET;
|
||||
@@ -2515,7 +2515,7 @@ static int mtk_rx_alloc(struct mtk_eth *
|
||||
|
||||
rxd->rxd3 = 0;
|
||||
rxd->rxd4 = 0;
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
rxd->rxd5 = 0;
|
||||
rxd->rxd6 = 0;
|
||||
rxd->rxd7 = 0;
|
||||
@@ -3063,7 +3063,7 @@ static int mtk_start_dma(struct mtk_eth
|
||||
MTK_TX_BT_32DWORDS | MTK_NDP_CO_PRO |
|
||||
MTK_RX_2B_OFFSET | MTK_TX_WB_DDONE;
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
val |= MTK_MUTLI_CNT | MTK_RESV_BUF |
|
||||
MTK_WCOMP_EN | MTK_DMAD_WR_WDONE |
|
||||
MTK_CHK_DDONE_EN | MTK_LEAKY_BUCKET_EN;
|
||||
@@ -3475,7 +3475,7 @@ static void mtk_hw_reset(struct mtk_eth
|
||||
{
|
||||
u32 val;
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN, 0);
|
||||
val = RSTCTRL_PPE0_V2;
|
||||
} else {
|
||||
@@ -3487,7 +3487,7 @@ static void mtk_hw_reset(struct mtk_eth
|
||||
|
||||
ethsys_reset(eth, RSTCTRL_ETH | RSTCTRL_FE | val);
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2))
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
regmap_write(eth->ethsys, ETHSYS_FE_RST_CHK_IDLE_EN,
|
||||
0x3ffffff);
|
||||
}
|
||||
@@ -3683,7 +3683,7 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
else
|
||||
mtk_hw_reset(eth);
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
/* Set FE to PDMAv2 if necessary */
|
||||
val = mtk_r32(eth, MTK_FE_GLO_MISC);
|
||||
mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
|
||||
@@ -3720,7 +3720,7 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
*/
|
||||
val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
|
||||
mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
|
||||
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
|
||||
mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -816,6 +816,7 @@ enum mkt_eth_capabilities {
|
||||
MTK_SHARED_INT_BIT,
|
||||
MTK_TRGMII_MT7621_CLK_BIT,
|
||||
MTK_QDMA_BIT,
|
||||
+ MTK_NETSYS_V1_BIT,
|
||||
MTK_NETSYS_V2_BIT,
|
||||
MTK_SOC_MT7628_BIT,
|
||||
MTK_RSTCTRL_PPE1_BIT,
|
||||
@@ -851,6 +852,7 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
|
||||
#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
|
||||
#define MTK_QDMA BIT(MTK_QDMA_BIT)
|
||||
+#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
|
||||
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
|
||||
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
|
||||
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
|
||||
@@ -913,25 +915,30 @@ enum mkt_eth_capabilities {
|
||||
|
||||
#define MTK_HAS_CAPS(caps, _x) (((caps) & (_x) & ~(MTK_CAP_MASK)) == (_x))
|
||||
|
||||
-#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
|
||||
- MTK_GMAC2_RGMII | MTK_SHARED_INT | \
|
||||
- MTK_TRGMII_MT7621_CLK | MTK_QDMA)
|
||||
-
|
||||
-#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | MTK_GMAC2_RGMII | \
|
||||
- MTK_GMAC2_SGMII | MTK_GDM1_ESW | \
|
||||
- MTK_MUX_GDM1_TO_GMAC1_ESW | \
|
||||
- MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_QDMA)
|
||||
-
|
||||
-#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | MTK_GMAC2_RGMII | \
|
||||
- MTK_QDMA)
|
||||
-
|
||||
-#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628)
|
||||
-
|
||||
-#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
|
||||
- MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW | \
|
||||
- MTK_MUX_GMAC2_GMAC0_TO_GEPHY | \
|
||||
- MTK_MUX_U3_GMAC2_TO_QPHY | \
|
||||
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA)
|
||||
+#define MT7621_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
|
||||
+ MTK_GMAC2_RGMII | MTK_SHARED_INT | \
|
||||
+ MTK_TRGMII_MT7621_CLK | MTK_QDMA | \
|
||||
+ MTK_NETSYS_V1)
|
||||
+
|
||||
+#define MT7622_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_SGMII | \
|
||||
+ MTK_GMAC2_RGMII | MTK_GMAC2_SGMII | \
|
||||
+ MTK_GDM1_ESW | MTK_MUX_GDM1_TO_GMAC1_ESW |\
|
||||
+ MTK_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | \
|
||||
+ MTK_QDMA | MTK_NETSYS_V1)
|
||||
+
|
||||
+#define MT7623_CAPS (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
|
||||
+ MTK_GMAC2_RGMII | MTK_QDMA | \
|
||||
+ MTK_NETSYS_V1)
|
||||
+
|
||||
+#define MT7628_CAPS (MTK_SHARED_INT | MTK_SOC_MT7628 | \
|
||||
+ MTK_NETSYS_V1)
|
||||
+
|
||||
+#define MT7629_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
|
||||
+ MTK_GMAC2_GEPHY | MTK_GDM1_ESW | \
|
||||
+ MTK_MUX_GMAC2_GMAC0_TO_GEPHY | MTK_QDMA | \
|
||||
+ MTK_MUX_U3_GMAC2_TO_QPHY | MTK_NETSYS_V1 |\
|
||||
+ MTK_MUX_GDM1_TO_GMAC1_ESW | \
|
||||
+ MTK_MUX_GMAC12_TO_GEPHY_SGMII)
|
||||
|
||||
#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
|
||||
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
|
|
@ -0,0 +1,181 @@
|
|||
From 5af2b2dc4d6ba0ff7696e79f18e5b2bf862194eb Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 7 Mar 2023 15:55:24 +0000
|
||||
Subject: [PATCH 2/7] net: ethernet: mtk_eth_soc: move MAX_DEVS in mtk_soc_data
|
||||
|
||||
This is a preliminary patch to add MT7988 SoC support since it runs 3
|
||||
macs instead of 2.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 +++++++++++++++++++--
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 11 +++----
|
||||
2 files changed, 36 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -3989,7 +3989,10 @@ static void mtk_sgmii_destroy(struct mtk
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAX_DEVS; i++)
|
||||
+ if (!eth->sgmii_pcs)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++)
|
||||
mtk_pcs_lynxi_destroy(eth->sgmii_pcs[i]);
|
||||
}
|
||||
|
||||
@@ -4432,7 +4435,12 @@ static int mtk_sgmii_init(struct mtk_eth
|
||||
u32 flags;
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAX_DEVS; i++) {
|
||||
+ eth->sgmii_pcs = devm_kzalloc(eth->dev,
|
||||
+ sizeof(*eth->sgmii_pcs) *
|
||||
+ eth->soc->num_devs,
|
||||
+ GFP_KERNEL);
|
||||
+
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
np = of_parse_phandle(eth->dev->of_node, "mediatek,sgmiisys", i);
|
||||
if (!np)
|
||||
break;
|
||||
@@ -4477,6 +4485,18 @@ static int mtk_probe(struct platform_dev
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
|
||||
eth->ip_align = NET_IP_ALIGN;
|
||||
|
||||
+ eth->netdev = devm_kzalloc(eth->dev,
|
||||
+ sizeof(*eth->netdev) * eth->soc->num_devs,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!eth->netdev)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
+ eth->mac = devm_kzalloc(eth->dev,
|
||||
+ sizeof(*eth->mac) * eth->soc->num_devs,
|
||||
+ GFP_KERNEL);
|
||||
+ if (!eth->mac)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
spin_lock_init(ð->page_lock);
|
||||
spin_lock_init(ð->tx_irq_lock);
|
||||
spin_lock_init(ð->rx_irq_lock);
|
||||
@@ -4662,7 +4682,7 @@ static int mtk_probe(struct platform_dev
|
||||
goto err_free_dev;
|
||||
}
|
||||
|
||||
- for (i = 0; i < MTK_MAX_DEVS; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
|
||||
@@ -4739,6 +4759,7 @@ static const struct mtk_soc_data mt2701_
|
||||
.hw_features = MTK_HW_FEATURES,
|
||||
.required_clks = MT7623_CLKS_BITMAP,
|
||||
.required_pctl = true,
|
||||
+ .num_devs = 2,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
.rxd_size = sizeof(struct mtk_rx_dma),
|
||||
@@ -4757,6 +4778,7 @@ static const struct mtk_soc_data mt7621_
|
||||
.required_pctl = false,
|
||||
.offload_version = 1,
|
||||
.hash_offset = 2,
|
||||
+ .num_devs = 2,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
@@ -4778,6 +4800,7 @@ static const struct mtk_soc_data mt7622_
|
||||
.offload_version = 2,
|
||||
.hash_offset = 2,
|
||||
.has_accounting = true,
|
||||
+ .num_devs = 2,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
@@ -4797,6 +4820,7 @@ static const struct mtk_soc_data mt7623_
|
||||
.required_pctl = true,
|
||||
.offload_version = 1,
|
||||
.hash_offset = 2,
|
||||
+ .num_devs = 2,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
@@ -4816,6 +4840,7 @@ static const struct mtk_soc_data mt7629_
|
||||
.required_clks = MT7629_CLKS_BITMAP,
|
||||
.required_pctl = false,
|
||||
.has_accounting = true,
|
||||
+ .num_devs = 2,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
.rxd_size = sizeof(struct mtk_rx_dma),
|
||||
@@ -4837,6 +4862,7 @@ static const struct mtk_soc_data mt7981_
|
||||
.hash_offset = 4,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry),
|
||||
.has_accounting = true,
|
||||
+ .num_devs = 2,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma_v2),
|
||||
.rxd_size = sizeof(struct mtk_rx_dma_v2),
|
||||
@@ -4856,6 +4882,7 @@ static const struct mtk_soc_data mt7986_
|
||||
.required_pctl = false,
|
||||
.offload_version = 2,
|
||||
.hash_offset = 4,
|
||||
+ .num_devs = 2,
|
||||
.foe_entry_size = sizeof(struct mtk_foe_entry),
|
||||
.has_accounting = true,
|
||||
.txrx = {
|
||||
@@ -4874,6 +4901,7 @@ static const struct mtk_soc_data rt5350_
|
||||
.hw_features = MTK_HW_FEATURES_MT7628,
|
||||
.required_clks = MT7628_CLKS_BITMAP,
|
||||
.required_pctl = false,
|
||||
+ .num_devs = 2,
|
||||
.txrx = {
|
||||
.txd_size = sizeof(struct mtk_tx_dma),
|
||||
.rxd_size = sizeof(struct mtk_rx_dma),
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -1018,6 +1018,7 @@ struct mtk_reg_map {
|
||||
* @required_pctl A bool value to show whether the SoC requires
|
||||
* the extra setup for those pins used by GMAC.
|
||||
* @hash_offset Flow table hash offset.
|
||||
+ * @num_devs SoC number of macs.
|
||||
* @foe_entry_size Foe table entry size.
|
||||
* @has_accounting Bool indicating support for accounting of
|
||||
* offloaded flows.
|
||||
@@ -1036,6 +1037,7 @@ struct mtk_soc_data {
|
||||
bool required_pctl;
|
||||
u8 offload_version;
|
||||
u8 hash_offset;
|
||||
+ u8 num_devs;
|
||||
u16 foe_entry_size;
|
||||
netdev_features_t hw_features;
|
||||
bool has_accounting;
|
||||
@@ -1051,9 +1053,6 @@ struct mtk_soc_data {
|
||||
|
||||
#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)
|
||||
|
||||
-/* currently no SoC has more than 2 macs */
|
||||
-#define MTK_MAX_DEVS 2
|
||||
-
|
||||
/* struct mtk_eth - This is the main datasructure for holding the state
|
||||
* of the driver
|
||||
* @dev: The device pointer
|
||||
@@ -1108,14 +1107,14 @@ struct mtk_eth {
|
||||
spinlock_t tx_irq_lock;
|
||||
spinlock_t rx_irq_lock;
|
||||
struct net_device dummy_dev;
|
||||
- struct net_device *netdev[MTK_MAX_DEVS];
|
||||
- struct mtk_mac *mac[MTK_MAX_DEVS];
|
||||
+ struct net_device **netdev;
|
||||
+ struct mtk_mac **mac;
|
||||
int irq[3];
|
||||
u32 msg_enable;
|
||||
unsigned long sysclk;
|
||||
struct regmap *ethsys;
|
||||
struct regmap *infra;
|
||||
- struct phylink_pcs *sgmii_pcs[MTK_MAX_DEVS];
|
||||
+ struct phylink_pcs **sgmii_pcs;
|
||||
struct regmap *pctl;
|
||||
bool hwlro;
|
||||
refcount_t dma_refcnt;
|
|
@ -0,0 +1,153 @@
|
|||
From 4e35e80750b33727e606be9e7ce447bde2e0deb7 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 7 Mar 2023 15:55:35 +0000
|
||||
Subject: [PATCH 3/7] net: ethernet: mtk_eth_soc: rely on num_devs and remove
|
||||
MTK_MAC_COUNT
|
||||
|
||||
Get rid of MTK_MAC_COUNT since it is a duplicated of eth->soc->num_devs.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 30 ++++++++++-----------
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
|
||||
2 files changed, 15 insertions(+), 16 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -900,7 +900,7 @@ static void mtk_stats_update(struct mtk_
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->mac[i] || !eth->mac[i]->hw_stats)
|
||||
continue;
|
||||
if (spin_trylock(ð->mac[i]->hw_stats->stats_lock)) {
|
||||
@@ -1403,7 +1403,7 @@ static int mtk_queue_stopped(struct mtk_
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
if (netif_queue_stopped(eth->netdev[i]))
|
||||
@@ -1417,7 +1417,7 @@ static void mtk_wake_queue(struct mtk_et
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
netif_tx_wake_all_queues(eth->netdev[i]);
|
||||
@@ -1908,7 +1908,7 @@ static int mtk_poll_rx(struct napi_struc
|
||||
!(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
|
||||
mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
|
||||
|
||||
- if (unlikely(mac < 0 || mac >= MTK_MAC_COUNT ||
|
||||
+ if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
|
||||
!eth->netdev[mac]))
|
||||
goto release_desc;
|
||||
|
||||
@@ -2937,7 +2937,7 @@ static void mtk_dma_free(struct mtk_eth
|
||||
const struct mtk_soc_data *soc = eth->soc;
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++)
|
||||
+ for (i = 0; i < soc->num_devs; i++)
|
||||
if (eth->netdev[i])
|
||||
netdev_reset_queue(eth->netdev[i]);
|
||||
if (eth->scratch_ring) {
|
||||
@@ -3091,7 +3091,7 @@ static void mtk_gdm_config(struct mtk_et
|
||||
if (MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628))
|
||||
return;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
u32 val = mtk_r32(eth, MTK_GDMA_FWD_CFG(i));
|
||||
|
||||
/* default setup the forward port to send frame to PDMA */
|
||||
@@ -3704,7 +3704,7 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
* up with the more appropriate value when mtk_mac_config call is being
|
||||
* invoked.
|
||||
*/
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
struct net_device *dev = eth->netdev[i];
|
||||
|
||||
mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
|
||||
@@ -3909,7 +3909,7 @@ static void mtk_pending_work(struct work
|
||||
mtk_prepare_for_reset(eth);
|
||||
|
||||
/* stop all devices to make sure that dma is properly shut down */
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i] || !netif_running(eth->netdev[i]))
|
||||
continue;
|
||||
|
||||
@@ -3925,7 +3925,7 @@ static void mtk_pending_work(struct work
|
||||
mtk_hw_init(eth, true);
|
||||
|
||||
/* restart DMA and enable IRQs */
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!test_bit(i, &restart))
|
||||
continue;
|
||||
|
||||
@@ -3953,7 +3953,7 @@ static int mtk_free_dev(struct mtk_eth *
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
free_netdev(eth->netdev[i]);
|
||||
@@ -3972,7 +3972,7 @@ static int mtk_unreg_dev(struct mtk_eth
|
||||
{
|
||||
int i;
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
struct mtk_mac *mac;
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
@@ -4277,7 +4277,7 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
}
|
||||
|
||||
id = be32_to_cpup(_id);
|
||||
- if (id >= MTK_MAC_COUNT) {
|
||||
+ if (id >= eth->soc->num_devs) {
|
||||
dev_err(eth->dev, "%d is not a valid mac id\n", id);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -4407,7 +4407,7 @@ void mtk_eth_set_dma_device(struct mtk_e
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
dev = eth->netdev[i];
|
||||
|
||||
if (!dev || !(dev->flags & IFF_UP))
|
||||
@@ -4734,7 +4734,7 @@ static int mtk_remove(struct platform_de
|
||||
int i;
|
||||
|
||||
/* stop all devices to make sure that dma is properly shut down */
|
||||
- for (i = 0; i < MTK_MAC_COUNT; i++) {
|
||||
+ for (i = 0; i < eth->soc->num_devs; i++) {
|
||||
if (!eth->netdev[i])
|
||||
continue;
|
||||
mtk_stop(eth->netdev[i]);
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -33,7 +33,6 @@
|
||||
#define MTK_TX_DMA_BUF_LEN_V2 0xffff
|
||||
#define MTK_QDMA_RING_SIZE 2048
|
||||
#define MTK_DMA_SIZE 512
|
||||
-#define MTK_MAC_COUNT 2
|
||||
#define MTK_RX_ETH_HLEN (VLAN_ETH_HLEN + ETH_FCS_LEN)
|
||||
#define MTK_RX_HLEN (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
|
||||
#define MTK_DMA_DUMMY_DESC 0xffffffff
|
|
@ -0,0 +1,292 @@
|
|||
From ab817f559d505329d8a413c7d29250f6d87d77a0 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 7 Mar 2023 15:55:47 +0000
|
||||
Subject: [PATCH 4/7] net: ethernet: mtk_eth_soc: add MTK_NETSYS_V3 capability
|
||||
bit
|
||||
|
||||
Introduce MTK_NETSYS_V3 bit in the device capabilities.
|
||||
This is a preliminary patch to introduce support for MT7988 SoC.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 115 ++++++++++++++++----
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 44 +++++++-
|
||||
2 files changed, 134 insertions(+), 25 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -880,17 +880,32 @@ void mtk_stats_update_mac(struct mtk_mac
|
||||
mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x20 + offs);
|
||||
hw_stats->rx_flow_control_packets +=
|
||||
mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x24 + offs);
|
||||
- hw_stats->tx_skip +=
|
||||
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
|
||||
- hw_stats->tx_collisions +=
|
||||
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
|
||||
- hw_stats->tx_bytes +=
|
||||
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
|
||||
- stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
|
||||
- if (stats)
|
||||
- hw_stats->tx_bytes += (stats << 32);
|
||||
- hw_stats->tx_packets +=
|
||||
- mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
|
||||
+
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
|
||||
+ hw_stats->tx_skip +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x50 + offs);
|
||||
+ hw_stats->tx_collisions +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x54 + offs);
|
||||
+ hw_stats->tx_bytes +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x40 + offs);
|
||||
+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x44 + offs);
|
||||
+ if (stats)
|
||||
+ hw_stats->tx_bytes += (stats << 32);
|
||||
+ hw_stats->tx_packets +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x48 + offs);
|
||||
+ } else {
|
||||
+ hw_stats->tx_skip +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x28 + offs);
|
||||
+ hw_stats->tx_collisions +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x2c + offs);
|
||||
+ hw_stats->tx_bytes +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x30 + offs);
|
||||
+ stats = mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x34 + offs);
|
||||
+ if (stats)
|
||||
+ hw_stats->tx_bytes += (stats << 32);
|
||||
+ hw_stats->tx_packets +=
|
||||
+ mtk_r32(mac->hw, reg_map->gdm1_cnt + 0x38 + offs);
|
||||
+ }
|
||||
}
|
||||
|
||||
u64_stats_update_end(&hw_stats->syncp);
|
||||
@@ -1192,7 +1207,10 @@ static void mtk_tx_set_dma_desc_v2(struc
|
||||
data |= TX_DMA_LS0;
|
||||
WRITE_ONCE(desc->txd3, data);
|
||||
|
||||
- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
|
||||
+ if (mac->id == MTK_GMAC3_ID)
|
||||
+ data = PSE_GDM3_PORT;
|
||||
+ else
|
||||
+ data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
|
||||
data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
|
||||
WRITE_ONCE(desc->txd4, data);
|
||||
|
||||
@@ -1203,6 +1221,9 @@ static void mtk_tx_set_dma_desc_v2(struc
|
||||
/* tx checksum offload */
|
||||
if (info->csum)
|
||||
data |= TX_DMA_CHKSUM_V2;
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3) &&
|
||||
+ netdev_uses_dsa(dev))
|
||||
+ data |= TX_DMA_SPTAG_V3;
|
||||
}
|
||||
WRITE_ONCE(desc->txd5, data);
|
||||
|
||||
@@ -1268,8 +1289,13 @@ static int mtk_tx_map(struct sk_buff *sk
|
||||
mtk_tx_set_dma_desc(dev, itxd, &txd_info);
|
||||
|
||||
itx_buf->flags |= MTK_TX_FLAGS_SINGLE0;
|
||||
- itx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
|
||||
- MTK_TX_FLAGS_FPORT1;
|
||||
+ if (mac->id == MTK_GMAC1_ID)
|
||||
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT0;
|
||||
+ else if (mac->id == MTK_GMAC2_ID)
|
||||
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT1;
|
||||
+ else
|
||||
+ itx_buf->flags |= MTK_TX_FLAGS_FPORT2;
|
||||
+
|
||||
setup_tx_buf(eth, itx_buf, itxd_pdma, txd_info.addr, txd_info.size,
|
||||
k++);
|
||||
|
||||
@@ -1317,8 +1343,13 @@ static int mtk_tx_map(struct sk_buff *sk
|
||||
memset(tx_buf, 0, sizeof(*tx_buf));
|
||||
tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
|
||||
tx_buf->flags |= MTK_TX_FLAGS_PAGE0;
|
||||
- tx_buf->flags |= (!mac->id) ? MTK_TX_FLAGS_FPORT0 :
|
||||
- MTK_TX_FLAGS_FPORT1;
|
||||
+
|
||||
+ if (mac->id == MTK_GMAC1_ID)
|
||||
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT0;
|
||||
+ else if (mac->id == MTK_GMAC2_ID)
|
||||
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT1;
|
||||
+ else
|
||||
+ tx_buf->flags |= MTK_TX_FLAGS_FPORT2;
|
||||
|
||||
setup_tx_buf(eth, tx_buf, txd_pdma, txd_info.addr,
|
||||
txd_info.size, k++);
|
||||
@@ -1902,11 +1933,24 @@ static int mtk_poll_rx(struct napi_struc
|
||||
break;
|
||||
|
||||
/* find out which mac the packet come from. values start at 1 */
|
||||
- if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1))
|
||||
- mac = RX_DMA_GET_SPORT_V2(trxd.rxd5) - 1;
|
||||
- else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
|
||||
- !(trxd.rxd4 & RX_DMA_SPECIAL_TAG))
|
||||
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V1)) {
|
||||
+ u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
|
||||
+
|
||||
+ switch (val) {
|
||||
+ case PSE_GDM1_PORT:
|
||||
+ case PSE_GDM2_PORT:
|
||||
+ mac = val - 1;
|
||||
+ break;
|
||||
+ case PSE_GDM3_PORT:
|
||||
+ mac = MTK_GMAC3_ID;
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ } else if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
|
||||
+ !(trxd.rxd4 & RX_DMA_SPECIAL_TAG)) {
|
||||
mac = RX_DMA_GET_SPORT(trxd.rxd4) - 1;
|
||||
+ }
|
||||
|
||||
if (unlikely(mac < 0 || mac >= eth->soc->num_devs ||
|
||||
!eth->netdev[mac]))
|
||||
@@ -2135,7 +2179,9 @@ static int mtk_poll_tx_qdma(struct mtk_e
|
||||
tx_buf = mtk_desc_to_tx_buf(ring, desc,
|
||||
eth->soc->txrx.txd_size);
|
||||
if (tx_buf->flags & MTK_TX_FLAGS_FPORT1)
|
||||
- mac = 1;
|
||||
+ mac = MTK_GMAC2_ID;
|
||||
+ else if (tx_buf->flags & MTK_TX_FLAGS_FPORT2)
|
||||
+ mac = MTK_GMAC3_ID;
|
||||
|
||||
if (!tx_buf->data)
|
||||
break;
|
||||
@@ -3742,7 +3788,26 @@ static int mtk_hw_init(struct mtk_eth *e
|
||||
mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4);
|
||||
mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
|
||||
|
||||
- if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3)) {
|
||||
+ /* PSE should not drop port1, port8 and port9 packets */
|
||||
+ mtk_w32(eth, 0x00000302, PSE_DROP_CFG);
|
||||
+
|
||||
+ /* GDM and CDM Threshold */
|
||||
+ mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES);
|
||||
+ mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
|
||||
+
|
||||
+ /* Disable GDM1 RX CRC stripping */
|
||||
+ val = mtk_r32(eth, MTK_GDMA_FWD_CFG(0));
|
||||
+ val &= ~MTK_GDMA_STRP_CRC;
|
||||
+ mtk_w32(eth, val, MTK_GDMA_FWD_CFG(0));
|
||||
+
|
||||
+ /* PSE GDM3 MIB counter has incorrect hw default values,
|
||||
+ * so the driver ought to read clear the values beforehand
|
||||
+ * in case ethtool retrieve wrong mib values.
|
||||
+ */
|
||||
+ for (i = 0; i < 0x80; i += 0x4)
|
||||
+ mtk_r32(eth, reg_map->gdm1_cnt + 0x100 + i);
|
||||
+ } else if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V2)) {
|
||||
/* PSE should not drop port8 and port9 packets from WDMA Tx */
|
||||
mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
|
||||
|
||||
@@ -4314,7 +4379,11 @@ static int mtk_add_mac(struct mtk_eth *e
|
||||
}
|
||||
spin_lock_init(&mac->hw_stats->stats_lock);
|
||||
u64_stats_init(&mac->hw_stats->syncp);
|
||||
- mac->hw_stats->reg_offset = id * MTK_STAT_OFFSET;
|
||||
+
|
||||
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_NETSYS_V3))
|
||||
+ mac->hw_stats->reg_offset = id * 0x80;
|
||||
+ else
|
||||
+ mac->hw_stats->reg_offset = id * 0x40;
|
||||
|
||||
/* phylink create */
|
||||
err = of_get_phy_mode(np, &phy_mode);
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -121,6 +121,7 @@
|
||||
#define MTK_GDMA_ICS_EN BIT(22)
|
||||
#define MTK_GDMA_TCS_EN BIT(21)
|
||||
#define MTK_GDMA_UCS_EN BIT(20)
|
||||
+#define MTK_GDMA_STRP_CRC BIT(16)
|
||||
#define MTK_GDMA_TO_PDMA 0x0
|
||||
#define MTK_GDMA_DROP_ALL 0x7777
|
||||
|
||||
@@ -286,8 +287,6 @@
|
||||
/* QDMA Interrupt grouping registers */
|
||||
#define MTK_RLS_DONE_INT BIT(0)
|
||||
|
||||
-#define MTK_STAT_OFFSET 0x40
|
||||
-
|
||||
/* QDMA TX NUM */
|
||||
#define QID_BITS_V2(x) (((x) & 0x3f) << 16)
|
||||
#define MTK_QDMA_GMAC2_QID 8
|
||||
@@ -300,6 +299,8 @@
|
||||
#define TX_DMA_CHKSUM_V2 (0x7 << 28)
|
||||
#define TX_DMA_TSO_V2 BIT(31)
|
||||
|
||||
+#define TX_DMA_SPTAG_V3 BIT(27)
|
||||
+
|
||||
/* QDMA V2 descriptor txd4 */
|
||||
#define TX_DMA_FPORT_SHIFT_V2 8
|
||||
#define TX_DMA_FPORT_MASK_V2 0xf
|
||||
@@ -636,6 +637,7 @@ enum mtk_tx_flags {
|
||||
*/
|
||||
MTK_TX_FLAGS_FPORT0 = 0x04,
|
||||
MTK_TX_FLAGS_FPORT1 = 0x08,
|
||||
+ MTK_TX_FLAGS_FPORT2 = 0x10,
|
||||
};
|
||||
|
||||
/* This enum allows us to identify how the clock is defined on the array of the
|
||||
@@ -721,6 +723,42 @@ enum mtk_dev_state {
|
||||
MTK_RESETTING
|
||||
};
|
||||
|
||||
+/* PSE Port Definition */
|
||||
+enum mtk_pse_port {
|
||||
+ PSE_ADMA_PORT = 0,
|
||||
+ PSE_GDM1_PORT,
|
||||
+ PSE_GDM2_PORT,
|
||||
+ PSE_PPE0_PORT,
|
||||
+ PSE_PPE1_PORT,
|
||||
+ PSE_QDMA_TX_PORT,
|
||||
+ PSE_QDMA_RX_PORT,
|
||||
+ PSE_DROP_PORT,
|
||||
+ PSE_WDMA0_PORT,
|
||||
+ PSE_WDMA1_PORT,
|
||||
+ PSE_TDMA_PORT,
|
||||
+ PSE_NONE_PORT,
|
||||
+ PSE_PPE2_PORT,
|
||||
+ PSE_WDMA2_PORT,
|
||||
+ PSE_EIP197_PORT,
|
||||
+ PSE_GDM3_PORT,
|
||||
+ PSE_PORT_MAX
|
||||
+};
|
||||
+
|
||||
+/* GMAC Identifier */
|
||||
+enum mtk_gmac_id {
|
||||
+ MTK_GMAC1_ID = 0,
|
||||
+ MTK_GMAC2_ID,
|
||||
+ MTK_GMAC3_ID,
|
||||
+ MTK_GMAC_ID_MAX
|
||||
+};
|
||||
+
|
||||
+/* GDM Type */
|
||||
+enum mtk_gdm_type {
|
||||
+ MTK_GDM_TYPE = 0,
|
||||
+ MTK_XGDM_TYPE,
|
||||
+ MTK_GDM_TYPE_MAX
|
||||
+};
|
||||
+
|
||||
enum mtk_tx_buf_type {
|
||||
MTK_TYPE_SKB,
|
||||
MTK_TYPE_XDP_TX,
|
||||
@@ -817,6 +855,7 @@ enum mkt_eth_capabilities {
|
||||
MTK_QDMA_BIT,
|
||||
MTK_NETSYS_V1_BIT,
|
||||
MTK_NETSYS_V2_BIT,
|
||||
+ MTK_NETSYS_V3_BIT,
|
||||
MTK_SOC_MT7628_BIT,
|
||||
MTK_RSTCTRL_PPE1_BIT,
|
||||
MTK_U3_COPHY_V2_BIT,
|
||||
@@ -853,6 +892,7 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_QDMA BIT(MTK_QDMA_BIT)
|
||||
#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
|
||||
#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
|
||||
+#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
|
||||
#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
|
||||
#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
|
||||
#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
|
|
@ -0,0 +1,197 @@
|
|||
From 45b575fd9e6a455090820248bf1b98b1f2c7b6c8 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Tue, 7 Mar 2023 15:56:00 +0000
|
||||
Subject: [PATCH 5/7] net: ethernet: mtk_eth_soc: convert caps in mtk_soc_data
|
||||
struct to u64
|
||||
|
||||
This is a preliminary patch to introduce support for MT7988 SoC.
|
||||
|
||||
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_path.c | 22 +++----
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 62 ++++++++++----------
|
||||
2 files changed, 42 insertions(+), 42 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
|
||||
@@ -15,10 +15,10 @@
|
||||
struct mtk_eth_muxc {
|
||||
const char *name;
|
||||
int cap_bit;
|
||||
- int (*set_path)(struct mtk_eth *eth, int path);
|
||||
+ int (*set_path)(struct mtk_eth *eth, u64 path);
|
||||
};
|
||||
|
||||
-static const char *mtk_eth_path_name(int path)
|
||||
+static const char *mtk_eth_path_name(u64 path)
|
||||
{
|
||||
switch (path) {
|
||||
case MTK_ETH_PATH_GMAC1_RGMII:
|
||||
@@ -40,7 +40,7 @@ static const char *mtk_eth_path_name(int
|
||||
}
|
||||
}
|
||||
|
||||
-static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, int path)
|
||||
+static int set_mux_gdm1_to_gmac1_esw(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
bool updated = true;
|
||||
u32 val, mask, set;
|
||||
@@ -71,7 +71,7 @@ static int set_mux_gdm1_to_gmac1_esw(str
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, int path)
|
||||
+static int set_mux_gmac2_gmac0_to_gephy(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
bool updated = true;
|
||||
@@ -94,7 +94,7 @@ static int set_mux_gmac2_gmac0_to_gephy(
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, int path)
|
||||
+static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
unsigned int val = 0, mask = 0, reg = 0;
|
||||
bool updated = true;
|
||||
@@ -125,7 +125,7 @@ static int set_mux_u3_gmac2_to_qphy(stru
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, int path)
|
||||
+static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
bool updated = true;
|
||||
@@ -163,7 +163,7 @@ static int set_mux_gmac1_gmac2_to_sgmii_
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, int path)
|
||||
+static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
unsigned int val = 0;
|
||||
bool updated = true;
|
||||
@@ -218,7 +218,7 @@ static const struct mtk_eth_muxc mtk_eth
|
||||
},
|
||||
};
|
||||
|
||||
-static int mtk_eth_mux_setup(struct mtk_eth *eth, int path)
|
||||
+static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
|
||||
{
|
||||
int i, err = 0;
|
||||
|
||||
@@ -249,7 +249,7 @@ out:
|
||||
|
||||
int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
|
||||
{
|
||||
- int path;
|
||||
+ u64 path;
|
||||
|
||||
path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_SGMII :
|
||||
MTK_ETH_PATH_GMAC2_SGMII;
|
||||
@@ -260,7 +260,7 @@ int mtk_gmac_sgmii_path_setup(struct mtk
|
||||
|
||||
int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id)
|
||||
{
|
||||
- int path = 0;
|
||||
+ u64 path = 0;
|
||||
|
||||
if (mac_id == 1)
|
||||
path = MTK_ETH_PATH_GMAC2_GEPHY;
|
||||
@@ -274,7 +274,7 @@ int mtk_gmac_gephy_path_setup(struct mtk
|
||||
|
||||
int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id)
|
||||
{
|
||||
- int path;
|
||||
+ u64 path;
|
||||
|
||||
path = (mac_id == 0) ? MTK_ETH_PATH_GMAC1_RGMII :
|
||||
MTK_ETH_PATH_GMAC2_RGMII;
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -878,44 +878,44 @@ enum mkt_eth_capabilities {
|
||||
};
|
||||
|
||||
/* Supported hardware group on SoCs */
|
||||
-#define MTK_RGMII BIT(MTK_RGMII_BIT)
|
||||
-#define MTK_TRGMII BIT(MTK_TRGMII_BIT)
|
||||
-#define MTK_SGMII BIT(MTK_SGMII_BIT)
|
||||
-#define MTK_ESW BIT(MTK_ESW_BIT)
|
||||
-#define MTK_GEPHY BIT(MTK_GEPHY_BIT)
|
||||
-#define MTK_MUX BIT(MTK_MUX_BIT)
|
||||
-#define MTK_INFRA BIT(MTK_INFRA_BIT)
|
||||
-#define MTK_SHARED_SGMII BIT(MTK_SHARED_SGMII_BIT)
|
||||
-#define MTK_HWLRO BIT(MTK_HWLRO_BIT)
|
||||
-#define MTK_SHARED_INT BIT(MTK_SHARED_INT_BIT)
|
||||
-#define MTK_TRGMII_MT7621_CLK BIT(MTK_TRGMII_MT7621_CLK_BIT)
|
||||
-#define MTK_QDMA BIT(MTK_QDMA_BIT)
|
||||
-#define MTK_NETSYS_V1 BIT(MTK_NETSYS_V1_BIT)
|
||||
-#define MTK_NETSYS_V2 BIT(MTK_NETSYS_V2_BIT)
|
||||
-#define MTK_NETSYS_V3 BIT(MTK_NETSYS_V3_BIT)
|
||||
-#define MTK_SOC_MT7628 BIT(MTK_SOC_MT7628_BIT)
|
||||
-#define MTK_RSTCTRL_PPE1 BIT(MTK_RSTCTRL_PPE1_BIT)
|
||||
-#define MTK_U3_COPHY_V2 BIT(MTK_U3_COPHY_V2_BIT)
|
||||
+#define MTK_RGMII BIT_ULL(MTK_RGMII_BIT)
|
||||
+#define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT)
|
||||
+#define MTK_SGMII BIT_ULL(MTK_SGMII_BIT)
|
||||
+#define MTK_ESW BIT_ULL(MTK_ESW_BIT)
|
||||
+#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
|
||||
+#define MTK_MUX BIT_ULL(MTK_MUX_BIT)
|
||||
+#define MTK_INFRA BIT_ULL(MTK_INFRA_BIT)
|
||||
+#define MTK_SHARED_SGMII BIT_ULL(MTK_SHARED_SGMII_BIT)
|
||||
+#define MTK_HWLRO BIT_ULL(MTK_HWLRO_BIT)
|
||||
+#define MTK_SHARED_INT BIT_ULL(MTK_SHARED_INT_BIT)
|
||||
+#define MTK_TRGMII_MT7621_CLK BIT_ULL(MTK_TRGMII_MT7621_CLK_BIT)
|
||||
+#define MTK_QDMA BIT_ULL(MTK_QDMA_BIT)
|
||||
+#define MTK_NETSYS_V1 BIT_ULL(MTK_NETSYS_V1_BIT)
|
||||
+#define MTK_NETSYS_V2 BIT_ULL(MTK_NETSYS_V2_BIT)
|
||||
+#define MTK_NETSYS_V3 BIT_ULL(MTK_NETSYS_V3_BIT)
|
||||
+#define MTK_SOC_MT7628 BIT_ULL(MTK_SOC_MT7628_BIT)
|
||||
+#define MTK_RSTCTRL_PPE1 BIT_ULL(MTK_RSTCTRL_PPE1_BIT)
|
||||
+#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
|
||||
|
||||
#define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
|
||||
- BIT(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
|
||||
+ BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
|
||||
#define MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY \
|
||||
- BIT(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
|
||||
#define MTK_ETH_MUX_U3_GMAC2_TO_QPHY \
|
||||
- BIT(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
|
||||
+ BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
|
||||
#define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII \
|
||||
- BIT(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
|
||||
#define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \
|
||||
- BIT(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
|
||||
|
||||
/* Supported path present on SoCs */
|
||||
-#define MTK_ETH_PATH_GMAC1_RGMII BIT(MTK_ETH_PATH_GMAC1_RGMII_BIT)
|
||||
-#define MTK_ETH_PATH_GMAC1_TRGMII BIT(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
|
||||
-#define MTK_ETH_PATH_GMAC1_SGMII BIT(MTK_ETH_PATH_GMAC1_SGMII_BIT)
|
||||
-#define MTK_ETH_PATH_GMAC2_RGMII BIT(MTK_ETH_PATH_GMAC2_RGMII_BIT)
|
||||
-#define MTK_ETH_PATH_GMAC2_SGMII BIT(MTK_ETH_PATH_GMAC2_SGMII_BIT)
|
||||
-#define MTK_ETH_PATH_GMAC2_GEPHY BIT(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
|
||||
-#define MTK_ETH_PATH_GDM1_ESW BIT(MTK_ETH_PATH_GDM1_ESW_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC1_TRGMII BIT_ULL(MTK_ETH_PATH_GMAC1_TRGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC1_SGMII BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
|
||||
+#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
|
||||
|
||||
#define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
|
||||
#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
|
||||
@@ -1071,7 +1071,7 @@ struct mtk_reg_map {
|
||||
struct mtk_soc_data {
|
||||
const struct mtk_reg_map *reg_map;
|
||||
u32 ana_rgc3;
|
||||
- u32 caps;
|
||||
+ u64 caps;
|
||||
u32 required_clks;
|
||||
bool required_pctl;
|
||||
u8 offload_version;
|
|
@ -0,0 +1,495 @@
|
|||
From 661bacf4363ca68939c15e20056b5f72fbd034e7 Mon Sep 17 00:00:00 2001
|
||||
From: Lorenzo Bianconi <lorenzo@kernel.org>
|
||||
Date: Sat, 25 Feb 2023 00:08:24 +0100
|
||||
Subject: [PATCH 6/7] net: ethernet: mtk_eth_soc: add support for MT7988 SoC
|
||||
|
||||
Introduce support for ethernet chip available in MT7988 SoC to
|
||||
mtk_eth_soc driver.
|
||||
---
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 153 ++++++++++++++--
|
||||
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 193 ++++++++++++++------
|
||||
2 files changed, 279 insertions(+), 67 deletions(-)
|
||||
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
|
||||
@@ -152,6 +152,54 @@ static const struct mtk_reg_map mt7986_r
|
||||
.pse_oq_sta = 0x01a0,
|
||||
};
|
||||
|
||||
+static const struct mtk_reg_map mt7988_reg_map = {
|
||||
+ .tx_irq_mask = 0x461c,
|
||||
+ .tx_irq_status = 0x4618,
|
||||
+ .pdma = {
|
||||
+ .rx_ptr = 0x6900,
|
||||
+ .rx_cnt_cfg = 0x6904,
|
||||
+ .pcrx_ptr = 0x6908,
|
||||
+ .glo_cfg = 0x6a04,
|
||||
+ .rst_idx = 0x6a08,
|
||||
+ .delay_irq = 0x6a0c,
|
||||
+ .irq_status = 0x6a20,
|
||||
+ .irq_mask = 0x6a28,
|
||||
+ .adma_rx_dbg0 = 0x6a38,
|
||||
+ .int_grp = 0x6a50,
|
||||
+ },
|
||||
+ .qdma = {
|
||||
+ .qtx_cfg = 0x4400,
|
||||
+ .qtx_sch = 0x4404,
|
||||
+ .rx_ptr = 0x4500,
|
||||
+ .rx_cnt_cfg = 0x4504,
|
||||
+ .qcrx_ptr = 0x4508,
|
||||
+ .glo_cfg = 0x4604,
|
||||
+ .rst_idx = 0x4608,
|
||||
+ .delay_irq = 0x460c,
|
||||
+ .fc_th = 0x4610,
|
||||
+ .int_grp = 0x4620,
|
||||
+ .hred = 0x4644,
|
||||
+ .ctx_ptr = 0x4700,
|
||||
+ .dtx_ptr = 0x4704,
|
||||
+ .crx_ptr = 0x4710,
|
||||
+ .drx_ptr = 0x4714,
|
||||
+ .fq_head = 0x4720,
|
||||
+ .fq_tail = 0x4724,
|
||||
+ .fq_count = 0x4728,
|
||||
+ .fq_blen = 0x472c,
|
||||
+ .tx_sch_rate = 0x4798,
|
||||
+ },
|
||||
+ .gdm1_cnt = 0x1c00,
|
||||
+ .gdma_to_ppe0 = 0x3333,
|
||||
+ .ppe_base = 0x2200,
|
||||
+ .wdma_base = {
|
||||
+ [0] = 0x4800,
|
||||
+ [1] = 0x4c00,
|
||||
+ },
|
||||
+ .pse_iq_sta = 0x0180,
|
||||
+ .pse_oq_sta = 0x01a0,
|
||||
+};
|
||||
+
|
||||
/* strings used by ethtool */
|
||||
static const struct mtk_ethtool_stats {
|
||||
char str[ETH_GSTRING_LEN];
|
||||
@@ -179,10 +227,54 @@ static const struct mtk_ethtool_stats {
|
||||
};
|
||||
|
||||
static const char * const mtk_clks_source_name[] = {
|
||||
- "ethif", "sgmiitop", "esw", "gp0", "gp1", "gp2", "fe", "trgpll",
|
||||
- "sgmii_tx250m", "sgmii_rx250m", "sgmii_cdr_ref", "sgmii_cdr_fb",
|
||||
- "sgmii2_tx250m", "sgmii2_rx250m", "sgmii2_cdr_ref", "sgmii2_cdr_fb",
|
||||
- "sgmii_ck", "eth2pll", "wocpu0", "wocpu1", "netsys0", "netsys1"
|
||||
+ "ethif",
|
||||
+ "sgmiitop",
|
||||
+ "esw",
|
||||
+ "gp0",
|
||||
+ "gp1",
|
||||
+ "gp2",
|
||||
+ "gp3",
|
||||
+ "xgp1",
|
||||
+ "xgp2",
|
||||
+ "xgp3",
|
||||
+ "crypto",
|
||||
+ "fe",
|
||||
+ "trgpll",
|
||||
+ "sgmii_tx250m",
|
||||
+ "sgmii_rx250m",
|
||||
+ "sgmii_cdr_ref",
|
||||
+ "sgmii_cdr_fb",
|
||||
+ "sgmii2_tx250m",
|
||||
+ "sgmii2_rx250m",
|
||||
+ "sgmii2_cdr_ref",
|
||||
+ "sgmii2_cdr_fb",
|
||||
+ "sgmii_ck",
|
||||
+ "eth2pll",
|
||||
+ "wocpu0",
|
||||
+ "wocpu1",
|
||||
+ "netsys0",
|
||||
+ "netsys1",
|
||||
+ "ethwarp_wocpu2",
|
||||
+ "ethwarp_wocpu1",
|
||||
+ "ethwarp_wocpu0",
|
||||
+ "top_usxgmii0_sel",
|
||||
+ "top_usxgmii1_sel",
|
||||
+ "top_sgm0_sel",
|
||||
+ "top_sgm1_sel",
|
||||
+ "top_xfi_phy0_xtal_sel",
|
||||
+ "top_xfi_phy1_xtal_sel",
|
||||
+ "top_eth_gmii_sel",
|
||||
+ "top_eth_refck_50m_sel",
|
||||
+ "top_eth_sys_200m_sel",
|
||||
+ "top_eth_sys_sel",
|
||||
+ "top_eth_xgmii_sel",
|
||||
+ "top_eth_mii_sel",
|
||||
+ "top_netsys_sel",
|
||||
+ "top_netsys_500m_sel",
|
||||
+ "top_netsys_pao_2x_sel",
|
||||
+ "top_netsys_sync_250m_sel",
|
||||
+ "top_netsys_ppefb_250m_sel",
|
||||
+ "top_netsys_warp_sel",
|
||||
};
|
||||
|
||||
void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg)
|
||||
@@ -1207,10 +1299,19 @@ static void mtk_tx_set_dma_desc_v2(struc
|
||||
data |= TX_DMA_LS0;
|
||||
WRITE_ONCE(desc->txd3, data);
|
||||
|
||||
- if (mac->id == MTK_GMAC3_ID)
|
||||
- data = PSE_GDM3_PORT;
|
||||
- else
|
||||
- data = (mac->id + 1) << TX_DMA_FPORT_SHIFT_V2; /* forward port */
|
||||
+ /* set forward port */
|
||||
+ switch (mac->id) {
|
||||
+ case MTK_GMAC1_ID:
|
||||
+ data = PSE_GDM1_PORT << TX_DMA_FPORT_SHIFT_V2;
|
||||
+ break;
|
||||
+ case MTK_GMAC2_ID:
|
||||
+ data = PSE_GDM2_PORT << TX_DMA_FPORT_SHIFT_V2;
|
||||
+ break;
|
||||
+ case MTK_GMAC3_ID:
|
||||
+ data = PSE_GDM3_PORT << TX_DMA_FPORT_SHIFT_V2;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
data |= TX_DMA_SWC_V2 | QID_BITS_V2(info->qid);
|
||||
WRITE_ONCE(desc->txd4, data);
|
||||
|
||||
@@ -4964,6 +5065,25 @@ static const struct mtk_soc_data mt7986_
|
||||
},
|
||||
};
|
||||
|
||||
+static const struct mtk_soc_data mt7988_data = {
|
||||
+ .reg_map = &mt7988_reg_map,
|
||||
+ .ana_rgc3 = 0x128,
|
||||
+ .caps = MT7988_CAPS,
|
||||
+ .hw_features = MTK_HW_FEATURES,
|
||||
+ .required_clks = MT7988_CLKS_BITMAP,
|
||||
+ .required_pctl = false,
|
||||
+ .num_devs = 3,
|
||||
+ .txrx = {
|
||||
+ .txd_size = sizeof(struct mtk_tx_dma_v2),
|
||||
+ .rxd_size = sizeof(struct mtk_rx_dma_v2),
|
||||
+ .rx_irq_done_mask = MTK_RX_DONE_INT_V2,
|
||||
+ .rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
|
||||
+ .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
|
||||
+ .dma_len_offset = 8,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
+
|
||||
static const struct mtk_soc_data rt5350_data = {
|
||||
.reg_map = &mt7628_reg_map,
|
||||
.caps = MT7628_CAPS,
|
||||
@@ -4982,14 +5102,15 @@ static const struct mtk_soc_data rt5350_
|
||||
};
|
||||
|
||||
const struct of_device_id of_mtk_match[] = {
|
||||
- { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data},
|
||||
- { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data},
|
||||
- { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data},
|
||||
- { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data},
|
||||
- { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data},
|
||||
- { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data},
|
||||
- { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data},
|
||||
- { .compatible = "ralink,rt5350-eth", .data = &rt5350_data},
|
||||
+ { .compatible = "mediatek,mt2701-eth", .data = &mt2701_data },
|
||||
+ { .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },
|
||||
+ { .compatible = "mediatek,mt7622-eth", .data = &mt7622_data },
|
||||
+ { .compatible = "mediatek,mt7623-eth", .data = &mt7623_data },
|
||||
+ { .compatible = "mediatek,mt7629-eth", .data = &mt7629_data },
|
||||
+ { .compatible = "mediatek,mt7981-eth", .data = &mt7981_data },
|
||||
+ { .compatible = "mediatek,mt7986-eth", .data = &mt7986_data },
|
||||
+ { .compatible = "mediatek,mt7988-eth", .data = &mt7988_data },
|
||||
+ { .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_mtk_match);
|
||||
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
|
||||
@@ -116,7 +116,8 @@
|
||||
#define MTK_CDMP_EG_CTRL 0x404
|
||||
|
||||
/* GDM Exgress Control Register */
|
||||
-#define MTK_GDMA_FWD_CFG(x) (0x500 + (x * 0x1000))
|
||||
+#define MTK_GDMA_FWD_CFG(x) ((x == MTK_GMAC3_ID) ? \
|
||||
+ 0x540 : 0x500 + (x * 0x1000))
|
||||
#define MTK_GDMA_SPECIAL_TAG BIT(24)
|
||||
#define MTK_GDMA_ICS_EN BIT(22)
|
||||
#define MTK_GDMA_TCS_EN BIT(21)
|
||||
@@ -650,6 +651,11 @@ enum mtk_clks_map {
|
||||
MTK_CLK_GP0,
|
||||
MTK_CLK_GP1,
|
||||
MTK_CLK_GP2,
|
||||
+ MTK_CLK_GP3,
|
||||
+ MTK_CLK_XGP1,
|
||||
+ MTK_CLK_XGP2,
|
||||
+ MTK_CLK_XGP3,
|
||||
+ MTK_CLK_CRYPTO,
|
||||
MTK_CLK_FE,
|
||||
MTK_CLK_TRGPLL,
|
||||
MTK_CLK_SGMII_TX_250M,
|
||||
@@ -666,57 +672,108 @@ enum mtk_clks_map {
|
||||
MTK_CLK_WOCPU1,
|
||||
MTK_CLK_NETSYS0,
|
||||
MTK_CLK_NETSYS1,
|
||||
+ MTK_CLK_ETHWARP_WOCPU2,
|
||||
+ MTK_CLK_ETHWARP_WOCPU1,
|
||||
+ MTK_CLK_ETHWARP_WOCPU0,
|
||||
+ MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
|
||||
+ MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
|
||||
+ MTK_CLK_TOP_SGM_0_SEL,
|
||||
+ MTK_CLK_TOP_SGM_1_SEL,
|
||||
+ MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
|
||||
+ MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
|
||||
+ MTK_CLK_TOP_ETH_GMII_SEL,
|
||||
+ MTK_CLK_TOP_ETH_REFCK_50M_SEL,
|
||||
+ MTK_CLK_TOP_ETH_SYS_200M_SEL,
|
||||
+ MTK_CLK_TOP_ETH_SYS_SEL,
|
||||
+ MTK_CLK_TOP_ETH_XGMII_SEL,
|
||||
+ MTK_CLK_TOP_ETH_MII_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_500M_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_PAO_2X_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_SYNC_250M_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL,
|
||||
+ MTK_CLK_TOP_NETSYS_WARP_SEL,
|
||||
MTK_CLK_MAX
|
||||
};
|
||||
|
||||
-#define MT7623_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
|
||||
- BIT(MTK_CLK_GP1) | BIT(MTK_CLK_GP2) | \
|
||||
- BIT(MTK_CLK_TRGPLL))
|
||||
-#define MT7622_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
|
||||
- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
|
||||
- BIT(MTK_CLK_GP2) | \
|
||||
- BIT(MTK_CLK_SGMII_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII_CK) | \
|
||||
- BIT(MTK_CLK_ETH2PLL))
|
||||
+#define MT7623_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
|
||||
+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
|
||||
+ BIT_ULL(MTK_CLK_TRGPLL))
|
||||
+#define MT7622_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
|
||||
+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
|
||||
+ BIT_ULL(MTK_CLK_GP2) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CK) | \
|
||||
+ BIT_ULL(MTK_CLK_ETH2PLL))
|
||||
#define MT7621_CLKS_BITMAP (0)
|
||||
#define MT7628_CLKS_BITMAP (0)
|
||||
-#define MT7629_CLKS_BITMAP (BIT(MTK_CLK_ETHIF) | BIT(MTK_CLK_ESW) | \
|
||||
- BIT(MTK_CLK_GP0) | BIT(MTK_CLK_GP1) | \
|
||||
- BIT(MTK_CLK_GP2) | BIT(MTK_CLK_FE) | \
|
||||
- BIT(MTK_CLK_SGMII_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII2_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII_CK) | \
|
||||
- BIT(MTK_CLK_ETH2PLL) | BIT(MTK_CLK_SGMIITOP))
|
||||
-#define MT7981_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
|
||||
- BIT(MTK_CLK_WOCPU0) | \
|
||||
- BIT(MTK_CLK_SGMII_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII2_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII_CK))
|
||||
-#define MT7986_CLKS_BITMAP (BIT(MTK_CLK_FE) | BIT(MTK_CLK_GP2) | BIT(MTK_CLK_GP1) | \
|
||||
- BIT(MTK_CLK_WOCPU1) | BIT(MTK_CLK_WOCPU0) | \
|
||||
- BIT(MTK_CLK_SGMII_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII_CDR_FB) | \
|
||||
- BIT(MTK_CLK_SGMII2_TX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_RX_250M) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
- BIT(MTK_CLK_SGMII2_CDR_FB))
|
||||
+#define MT7629_CLKS_BITMAP (BIT_ULL(MTK_CLK_ETHIF) | BIT_ULL(MTK_CLK_ESW) | \
|
||||
+ BIT_ULL(MTK_CLK_GP0) | BIT_ULL(MTK_CLK_GP1) | \
|
||||
+ BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_FE) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CK) | \
|
||||
+ BIT_ULL(MTK_CLK_ETH2PLL) | BIT_ULL(MTK_CLK_SGMIITOP))
|
||||
+#define MT7981_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \
|
||||
+ BIT_ULL(MTK_CLK_WOCPU0) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CK))
|
||||
+#define MT7986_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_GP2) | BIT_ULL(MTK_CLK_GP1) | \
|
||||
+ BIT_ULL(MTK_CLK_WOCPU1) | BIT_ULL(MTK_CLK_WOCPU0) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_CDR_FB) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_REF) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_CDR_FB))
|
||||
+#define MT7988_CLKS_BITMAP (BIT_ULL(MTK_CLK_FE) | BIT_ULL(MTK_CLK_ESW) | \
|
||||
+ BIT_ULL(MTK_CLK_GP1) | BIT_ULL(MTK_CLK_GP2) | \
|
||||
+ BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
|
||||
+ BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
|
||||
+ BIT_ULL(MTK_CLK_CRYPTO) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
|
||||
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
|
||||
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
|
||||
+ BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_SYS_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_XGMII_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_ETH_MII_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_500M_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_PAO_2X_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_SYNC_250M_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_PPEFB_250M_SEL) | \
|
||||
+ BIT_ULL(MTK_CLK_TOP_NETSYS_WARP_SEL))
|
||||
|
||||
enum mtk_dev_state {
|
||||
MTK_HW_INIT,
|
||||
@@ -844,6 +901,7 @@ enum mkt_eth_capabilities {
|
||||
MTK_RGMII_BIT = 0,
|
||||
MTK_TRGMII_BIT,
|
||||
MTK_SGMII_BIT,
|
||||
+ MTK_USXGMII_BIT,
|
||||
MTK_ESW_BIT,
|
||||
MTK_GEPHY_BIT,
|
||||
MTK_MUX_BIT,
|
||||
@@ -866,6 +924,8 @@ enum mkt_eth_capabilities {
|
||||
MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
|
||||
MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
|
||||
MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
|
||||
+ MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
|
||||
+ MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
|
||||
|
||||
/* PATH BITS */
|
||||
MTK_ETH_PATH_GMAC1_RGMII_BIT,
|
||||
@@ -874,13 +934,18 @@ enum mkt_eth_capabilities {
|
||||
MTK_ETH_PATH_GMAC2_RGMII_BIT,
|
||||
MTK_ETH_PATH_GMAC2_SGMII_BIT,
|
||||
MTK_ETH_PATH_GMAC2_GEPHY_BIT,
|
||||
+ MTK_ETH_PATH_GMAC3_SGMII_BIT,
|
||||
MTK_ETH_PATH_GDM1_ESW_BIT,
|
||||
+ MTK_ETH_PATH_GMAC1_USXGMII_BIT,
|
||||
+ MTK_ETH_PATH_GMAC2_USXGMII_BIT,
|
||||
+ MTK_ETH_PATH_GMAC3_USXGMII_BIT,
|
||||
};
|
||||
|
||||
/* Supported hardware group on SoCs */
|
||||
#define MTK_RGMII BIT_ULL(MTK_RGMII_BIT)
|
||||
#define MTK_TRGMII BIT_ULL(MTK_TRGMII_BIT)
|
||||
#define MTK_SGMII BIT_ULL(MTK_SGMII_BIT)
|
||||
+#define MTK_USXGMII BIT_ULL(MTK_USXGMII_BIT)
|
||||
#define MTK_ESW BIT_ULL(MTK_ESW_BIT)
|
||||
#define MTK_GEPHY BIT_ULL(MTK_GEPHY_BIT)
|
||||
#define MTK_MUX BIT_ULL(MTK_MUX_BIT)
|
||||
@@ -907,6 +972,10 @@ enum mkt_eth_capabilities {
|
||||
BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
|
||||
#define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII \
|
||||
BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
|
||||
+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII \
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
|
||||
+#define MTK_ETH_MUX_GMAC123_TO_USXGMII \
|
||||
+ BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
|
||||
|
||||
/* Supported path present on SoCs */
|
||||
#define MTK_ETH_PATH_GMAC1_RGMII BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
|
||||
@@ -915,7 +984,11 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_ETH_PATH_GMAC2_RGMII BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
|
||||
#define MTK_ETH_PATH_GMAC2_SGMII BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
|
||||
#define MTK_ETH_PATH_GMAC2_GEPHY BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC3_SGMII BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
|
||||
#define MTK_ETH_PATH_GDM1_ESW BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC1_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC2_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
|
||||
+#define MTK_ETH_PATH_GMAC3_USXGMII BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
|
||||
|
||||
#define MTK_GMAC1_RGMII (MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
|
||||
#define MTK_GMAC1_TRGMII (MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
|
||||
@@ -923,7 +996,11 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_GMAC2_RGMII (MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
|
||||
#define MTK_GMAC2_SGMII (MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
|
||||
#define MTK_GMAC2_GEPHY (MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
|
||||
+#define MTK_GMAC3_SGMII (MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
|
||||
#define MTK_GDM1_ESW (MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
|
||||
+#define MTK_GMAC1_USXGMII (MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
|
||||
+#define MTK_GMAC2_USXGMII (MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
|
||||
+#define MTK_GMAC3_USXGMII (MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
|
||||
|
||||
/* MUXes present on SoCs */
|
||||
/* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
|
||||
@@ -946,6 +1023,12 @@ enum mkt_eth_capabilities {
|
||||
#define MTK_MUX_GMAC12_TO_GEPHY_SGMII \
|
||||
(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
|
||||
|
||||
+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII \
|
||||
+ (MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
|
||||
+
|
||||
+#define MTK_MUX_GMAC123_TO_USXGMII \
|
||||
+ (MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
|
||||
+
|
||||
#ifdef CONFIG_SOC_MT7621
|
||||
#define MTK_CAP_MASK MTK_NETSYS_V2
|
||||
#else
|
||||
@@ -984,9 +1067,17 @@ enum mkt_eth_capabilities {
|
||||
MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
|
||||
MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
|
||||
|
||||
-#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
|
||||
- MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
|
||||
- MTK_NETSYS_V2 | MTK_RSTCTRL_PPE1)
|
||||
+#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
|
||||
+ MTK_MUX_GMAC12_TO_GEPHY_SGMII | \
|
||||
+ MTK_QDMA | MTK_NETSYS_V2 | \
|
||||
+ MTK_RSTCTRL_PPE1)
|
||||
+
|
||||
+#define MT7988_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
|
||||
+ MTK_GMAC3_SGMII | MTK_QDMA | \
|
||||
+ MTK_MUX_GMAC123_TO_GEPHY_SGMII | \
|
||||
+ MTK_NETSYS_V3 | MTK_RSTCTRL_PPE1 | \
|
||||
+ MTK_GMAC1_USXGMII | MTK_GMAC2_USXGMII | \
|
||||
+ MTK_GMAC3_USXGMII | MTK_MUX_GMAC123_TO_USXGMII)
|
||||
|
||||
struct mtk_tx_dma_desc_info {
|
||||
dma_addr_t addr;
|
||||
@@ -1072,7 +1163,7 @@ struct mtk_soc_data {
|
||||
const struct mtk_reg_map *reg_map;
|
||||
u32 ana_rgc3;
|
||||
u64 caps;
|
||||
- u32 required_clks;
|
||||
+ u64 required_clks;
|
||||
bool required_pctl;
|
||||
u8 offload_version;
|
||||
u8 hash_offset;
|
File diff suppressed because it is too large
Load diff
|
@ -16,7 +16,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
|
|||
|
||||
--- a/drivers/net/dsa/mt7530.c
|
||||
+++ b/drivers/net/dsa/mt7530.c
|
||||
@@ -2081,10 +2081,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr
|
||||
@@ -2121,10 +2121,13 @@ mt7530_setup_mdio(struct mt7530_priv *pr
|
||||
{
|
||||
struct dsa_switch *ds = priv->ds;
|
||||
struct device *dev = priv->dev;
|
||||
|
@ -30,7 +30,7 @@ Signed-off-by: David Bauer <mail@david-bauer.net>
|
|||
bus = devm_mdiobus_alloc(dev);
|
||||
if (!bus)
|
||||
return -ENOMEM;
|
||||
@@ -2101,7 +2104,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr
|
||||
@@ -2141,7 +2144,9 @@ mt7530_setup_mdio(struct mt7530_priv *pr
|
||||
if (priv->irq)
|
||||
mt7530_setup_mdio_irq(priv);
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ netgear,d7800 |\
|
|||
netgear,r7500 |\
|
||||
netgear,r7500v2 |\
|
||||
netgear,r7800 |\
|
||||
netgear,xr450 |\
|
||||
netgear,xr500)
|
||||
ucidef_set_led_usbport "usb1" "USB 1" "white:usb1" "usb1-port1" "usb2-port1"
|
||||
ucidef_set_led_usbport "usb2" "USB 2" "white:usb2" "usb3-port1" "usb4-port1"
|
||||
|
|
|
@ -59,6 +59,7 @@ nec,wg2600hp3)
|
|||
"2:lan" "3:lan" "4:lan" "5:lan" "0@eth1" "1:wan" "6@eth0"
|
||||
;;
|
||||
netgear,r7800 |\
|
||||
netgear,xr450 |\
|
||||
netgear,xr500 |\
|
||||
tplink,c2600 |\
|
||||
tplink,vr2600v)
|
||||
|
|
|
@ -17,6 +17,7 @@ platform_do_upgrade() {
|
|||
netgear,r7500 |\
|
||||
netgear,r7500v2 |\
|
||||
netgear,r7800 |\
|
||||
netgear,xr450 |\
|
||||
netgear,xr500 |\
|
||||
nokia,ac400i |\
|
||||
qcom,ipq8064-ap148 |\
|
||||
|
|
|
@ -39,7 +39,6 @@ CONFIG_ARM_HAS_SG_CHAIN=y
|
|||
# CONFIG_ARM_KRAIT_CACHE_DEVFREQ is not set
|
||||
CONFIG_ARM_L1_CACHE_SHIFT=6
|
||||
CONFIG_ARM_L1_CACHE_SHIFT_6=y
|
||||
CONFIG_ARM_MODULE_PLTS=y
|
||||
CONFIG_ARM_PATCH_IDIV=y
|
||||
CONFIG_ARM_PATCH_PHYS_VIRT=y
|
||||
# CONFIG_ARM_QCOM_CPUFREQ_HW is not set
|
||||
|
|
|
@ -43,7 +43,6 @@ CONFIG_ARM_HAS_SG_CHAIN=y
|
|||
# CONFIG_ARM_KRAIT_CACHE_DEVFREQ is not set
|
||||
CONFIG_ARM_L1_CACHE_SHIFT=6
|
||||
CONFIG_ARM_L1_CACHE_SHIFT_6=y
|
||||
CONFIG_ARM_MODULE_PLTS=y
|
||||
CONFIG_ARM_PATCH_IDIV=y
|
||||
CONFIG_ARM_PATCH_PHYS_VIRT=y
|
||||
# CONFIG_ARM_QCOM_CPUFREQ_HW is not set
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||
|
||||
#include "qcom-ipq8065-nighthawk.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Netgear Nighthawk XR450";
|
||||
compatible = "netgear,xr450", "qcom,ipq8065", "qcom,ipq8064";
|
||||
|
||||
};
|
||||
|
||||
&leds {
|
||||
usb1 {
|
||||
label = "white:usb1";
|
||||
gpios = <&qcom_pinmux 8 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
usb2 {
|
||||
label = "white:usb2";
|
||||
gpios = <&qcom_pinmux 26 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
&partitions {
|
||||
partition@1880000 {
|
||||
label = "ubi";
|
||||
reg = <0x1880000 0xce00000>;
|
||||
};
|
||||
|
||||
partition@e680000 {
|
||||
label = "reserve";
|
||||
reg = <0xe680000 0x0780000>;
|
||||
read-only;
|
||||
};
|
||||
};
|
||||
|
||||
&wifi0 {
|
||||
nvmem-cells = <&macaddr_art_c>, <&precal_art_1000>;
|
||||
nvmem-cell-names = "mac-address", "pre-calibration";
|
||||
};
|
||||
|
||||
&wifi1 {
|
||||
nvmem-cells = <&macaddr_art_0>, <&precal_art_5000>;
|
||||
nvmem-cell-names = "mac-address", "pre-calibration";
|
||||
};
|
||||
|
||||
&art {
|
||||
macaddr_art_c: macaddr@c {
|
||||
reg = <0xc 0x6>;
|
||||
};
|
||||
};
|
|
@ -320,6 +320,20 @@ define Device/netgear_r7800
|
|||
endef
|
||||
TARGET_DEVICES += netgear_r7800
|
||||
|
||||
define Device/netgear_xr450
|
||||
$(call Device/DniImage)
|
||||
DEVICE_VENDOR := NETGEAR
|
||||
DEVICE_MODEL := Nighthawk XR450
|
||||
SOC := qcom-ipq8065
|
||||
KERNEL_SIZE := 4096k
|
||||
NETGEAR_BOARD_ID := XR450
|
||||
NETGEAR_HW_ID := 29764958+0+256+512+4x4+4x4+cascade
|
||||
BLOCKSIZE := 128k
|
||||
PAGESIZE := 2048
|
||||
DEVICE_PACKAGES := ath10k-firmware-qca9984-ct kmod-ramoops
|
||||
endef
|
||||
TARGET_DEVICES += netgear_xr450
|
||||
|
||||
define Device/netgear_xr500
|
||||
$(call Device/DniImage)
|
||||
DEVICE_VENDOR := NETGEAR
|
||||
|
|
|
@ -30,7 +30,6 @@ CONFIG_ARM64_ERRATUM_832075=y
|
|||
CONFIG_ARM64_ERRATUM_843419=y
|
||||
CONFIG_ARM64_HW_AFDBM=y
|
||||
CONFIG_ARM64_LD_HAS_FIX_ERRATUM_843419=y
|
||||
CONFIG_ARM64_MODULE_PLTS=y
|
||||
CONFIG_ARM64_PAGE_SHIFT=12
|
||||
CONFIG_ARM64_PAN=y
|
||||
CONFIG_ARM64_PA_BITS=48
|
||||
|
|
|
@ -555,14 +555,15 @@
|
|||
"mediatek,mt7981-mmc";
|
||||
reg = <0 0x11230000 0 0x1000>, <0 0x11c20000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&topckgen CLK_TOP_EMMC_208M>,
|
||||
<&topckgen CLK_TOP_EMMC_400M>,
|
||||
<&infracfg CLK_INFRA_MSDC_CK>;
|
||||
clocks = <&infracfg CLK_INFRA_MSDC_CK>,
|
||||
<&infracfg CLK_INFRA_MSDC_HCK_CK>,
|
||||
<&infracfg CLK_INFRA_MSDC_66M_CK>,
|
||||
<&infracfg CLK_INFRA_MSDC_133M_CK>;
|
||||
assigned-clocks = <&topckgen CLK_TOP_EMMC_208M_SEL>,
|
||||
<&topckgen CLK_TOP_EMMC_400M_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_CB_M_D2>,
|
||||
<&topckgen CLK_TOP_CB_NET2_D2>;
|
||||
clock-names = "source", "hclk", "source_cg";
|
||||
clock-names = "source", "hclk", "axi_cg", "ahb_cg";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
@ -640,7 +641,6 @@
|
|||
phys = <&u2port0 PHY_TYPE_USB2>,
|
||||
<&u3port0 PHY_TYPE_USB3>;
|
||||
vusb33-supply = <®_3p3v>;
|
||||
mediatek,u3p-dis-msk = <0x01>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc.
|
||||
* Author: Sam.Shih <sam.shih@mediatek.com>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "mt7988a-rfb-spim-nand.dtsi"
|
||||
#include <dt-bindings/pinctrl/mt65xx.h>
|
||||
|
||||
/ {
|
||||
model = "MediaTek MT7988A DSA 10G SPIM-NAND RFB";
|
||||
compatible = "mediatek,mt7988a-dsa-10g-spim-snand",
|
||||
"mediatek,mt7988a-rfb-snand",
|
||||
"mediatek,mt7988";
|
||||
|
||||
chosen {
|
||||
bootargs = "console=ttyS0,115200n1 loglevel=8 \
|
||||
earlycon=uart8250,mmio32,0x11000000 \
|
||||
pci=pcie_bus_perf";
|
||||
};
|
||||
|
||||
memory {
|
||||
reg = <0 0x40000000 0 0x40000000>;
|
||||
};
|
||||
};
|
||||
|
||||
ð {
|
||||
pinctrl-0 = <&mdio0_pins>;
|
||||
pinctrl-names = "default";
|
||||
status = "okay";
|
||||
|
||||
gmac0: mac@0 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <0>;
|
||||
phy-mode = "internal";
|
||||
|
||||
fixed-link {
|
||||
speed = <10000>;
|
||||
full-duplex;
|
||||
pause;
|
||||
};
|
||||
};
|
||||
|
||||
gmac1: mac@1 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <1>;
|
||||
phy-mode = "internal";
|
||||
phy-connection-type = "internal";
|
||||
phy = <&phy15>;
|
||||
};
|
||||
|
||||
gmac2: mac@2 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <2>;
|
||||
phy-mode = "10gbase-kr";
|
||||
phy-connection-type = "10gbase-kr";
|
||||
phy = <&phy8>;
|
||||
};
|
||||
|
||||
mdio0: mdio-bus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
/* external Aquantia AQR113C */
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reset-gpios = <&pio 72 1>;
|
||||
reset-assert-us = <100000>;
|
||||
reset-deassert-us = <221000>;
|
||||
};
|
||||
|
||||
/* external Aquantia AQR113C */
|
||||
phy8: ethernet-phy@8 {
|
||||
reg = <8>;
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
reset-gpios = <&pio 71 1>;
|
||||
reset-assert-us = <100000>;
|
||||
reset-deassert-us = <221000>;
|
||||
};
|
||||
|
||||
/* external Maxlinear GPY211C */
|
||||
phy5: ethernet-phy@5 {
|
||||
reg = <5>;
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
phy-mode = "2500base-x";
|
||||
};
|
||||
|
||||
/* external Maxlinear GPY211C */
|
||||
phy13: ethernet-phy@13 {
|
||||
reg = <13>;
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
phy-mode = "2500base-x";
|
||||
};
|
||||
|
||||
/* internal 2.5G PHY */
|
||||
phy15: ethernet-phy@15 {
|
||||
reg = <15>;
|
||||
pinctrl-names = "i2p5gbe-led";
|
||||
pinctrl-0 = <&i2p5gbe_led0_pins>;
|
||||
compatible = "ethernet-phy-ieee802.3-c45";
|
||||
phy-mode = "internal";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&switch {
|
||||
status = "okay";
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
label = "lan0";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&gsw_phy0>;
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
label = "lan1";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&gsw_phy1>;
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "lan2";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&gsw_phy2>;
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan3";
|
||||
phy-mode = "internal";
|
||||
phy-handle = <&gsw_phy3>;
|
||||
};
|
||||
|
||||
port@6 {
|
||||
reg = <6>;
|
||||
ethernet = <&gmac0>;
|
||||
phy-mode = "internal";
|
||||
|
||||
fixed-link {
|
||||
speed = <10000>;
|
||||
full-duplex;
|
||||
pause;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
gsw_phy0: ethernet-phy@0 {
|
||||
compatible = "ethernet-phy-id03a2.9481";
|
||||
reg = <0>;
|
||||
phy-mode = "internal";
|
||||
pinctrl-names = "gbe-led";
|
||||
pinctrl-0 = <&gbe0_led0_pins>;
|
||||
nvmem-cells = <&phy_calibration_p0>;
|
||||
nvmem-cell-names = "phy-cal-data";
|
||||
};
|
||||
|
||||
gsw_phy1: ethernet-phy@1 {
|
||||
compatible = "ethernet-phy-id03a2.9481";
|
||||
reg = <1>;
|
||||
phy-mode = "internal";
|
||||
pinctrl-names = "gbe-led";
|
||||
pinctrl-0 = <&gbe1_led0_pins>;
|
||||
nvmem-cells = <&phy_calibration_p1>;
|
||||
nvmem-cell-names = "phy-cal-data";
|
||||
};
|
||||
|
||||
gsw_phy2: ethernet-phy@2 {
|
||||
compatible = "ethernet-phy-id03a2.9481";
|
||||
reg = <2>;
|
||||
phy-mode = "internal";
|
||||
pinctrl-names = "gbe-led";
|
||||
pinctrl-0 = <&gbe2_led0_pins>;
|
||||
nvmem-cells = <&phy_calibration_p2>;
|
||||
nvmem-cell-names = "phy-cal-data";
|
||||
};
|
||||
|
||||
gsw_phy3: ethernet-phy@3 {
|
||||
compatible = "ethernet-phy-id03a2.9481";
|
||||
reg = <3>;
|
||||
phy-mode = "internal";
|
||||
pinctrl-names = "gbe-led";
|
||||
pinctrl-0 = <&gbe3_led0_pins>;
|
||||
nvmem-cells = <&phy_calibration_p3>;
|
||||
nvmem-cell-names = "phy-cal-data";
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,70 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc.
|
||||
* Author: Sam.Shih <sam.shih@mediatek.com>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "mt7988a-rfb.dtsi"
|
||||
|
||||
&pio {
|
||||
spi0_flash_pins: spi0-pins {
|
||||
mux {
|
||||
function = "spi";
|
||||
groups = "spi0", "spi0_wp_hold";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi0_flash_pins>;
|
||||
status = "okay";
|
||||
|
||||
spi_nand: spi_nand@0 {
|
||||
compatible = "spi-nand";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <52000000>;
|
||||
spi-tx-buswidth = <4>;
|
||||
spi-rx-buswidth = <4>;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
&spi_nand {
|
||||
mediatek,nmbm;
|
||||
mediatek,bmt-max-ratio = <1>;
|
||||
mediatek,bmt-max-reserved-blocks = <64>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "BL2";
|
||||
reg = <0x00000 0x0100000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@100000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x0100000 0x0080000>;
|
||||
};
|
||||
|
||||
factory: partition@180000 {
|
||||
label = "Factory";
|
||||
reg = <0x180000 0x0400000>;
|
||||
};
|
||||
|
||||
partition@580000 {
|
||||
label = "FIP";
|
||||
reg = <0x580000 0x0200000>;
|
||||
};
|
||||
|
||||
partition@780000 {
|
||||
label = "ubi";
|
||||
reg = <0x780000 0x7080000>;
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,175 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/*
|
||||
* Copyright (C) 2022 MediaTek Inc.
|
||||
* Author: Sam.Shih <sam.shih@mediatek.com>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "mt7988a.dtsi"
|
||||
#include <dt-bindings/regulator/richtek,rt5190a-regulator.h>
|
||||
|
||||
&cpu0 {
|
||||
proc-supply = <&rt5190_buck3>;
|
||||
};
|
||||
|
||||
&cpu1 {
|
||||
proc-supply = <&rt5190_buck3>;
|
||||
};
|
||||
|
||||
&cpu2 {
|
||||
proc-supply = <&rt5190_buck3>;
|
||||
};
|
||||
|
||||
&cpu3 {
|
||||
proc-supply = <&rt5190_buck3>;
|
||||
};
|
||||
|
||||
&cci {
|
||||
proc-supply = <&rt5190_buck3>;
|
||||
};
|
||||
|
||||
ð {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&i2c0_pins>;
|
||||
status = "okay";
|
||||
|
||||
rt5190a_64: rt5190a@64 {
|
||||
compatible = "richtek,rt5190a";
|
||||
reg = <0x64>;
|
||||
/*interrupts-extended = <&gpio26 0 IRQ_TYPE_LEVEL_LOW>;*/
|
||||
vin2-supply = <&rt5190_buck1>;
|
||||
vin3-supply = <&rt5190_buck1>;
|
||||
vin4-supply = <&rt5190_buck1>;
|
||||
|
||||
regulators {
|
||||
rt5190_buck1: buck1 {
|
||||
regulator-name = "rt5190a-buck1";
|
||||
regulator-min-microvolt = <5090000>;
|
||||
regulator-max-microvolt = <5090000>;
|
||||
regulator-allowed-modes =
|
||||
<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
buck2 {
|
||||
regulator-name = "vcore";
|
||||
regulator-min-microvolt = <600000>;
|
||||
regulator-max-microvolt = <1400000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
rt5190_buck3: buck3 {
|
||||
regulator-name = "vproc";
|
||||
regulator-min-microvolt = <600000>;
|
||||
regulator-max-microvolt = <1400000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
buck4 {
|
||||
regulator-name = "rt5190a-buck4";
|
||||
regulator-min-microvolt = <850000>;
|
||||
regulator-max-microvolt = <850000>;
|
||||
regulator-allowed-modes =
|
||||
<RT5190A_OPMODE_AUTO RT5190A_OPMODE_FPWM>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
ldo {
|
||||
regulator-name = "rt5190a-ldo";
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <1200000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pcie0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pcie0_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie1 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pcie1_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pcie2 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pcie2_pins>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&pcie3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pcie3_pins>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ssusb0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&ssusb1 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&tphy {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&pio {
|
||||
pcie0_pins: pcie0-pins {
|
||||
mux {
|
||||
function = "pcie";
|
||||
groups = "pcie_2l_0_pereset", "pcie_clk_req_n0_0",
|
||||
"pcie_wake_n0_0";
|
||||
};
|
||||
};
|
||||
|
||||
pcie1_pins: pcie1-pins {
|
||||
mux {
|
||||
function = "pcie";
|
||||
groups = "pcie_2l_1_pereset", "pcie_clk_req_n1",
|
||||
"pcie_wake_n1_0";
|
||||
};
|
||||
};
|
||||
|
||||
pcie2_pins: pcie2-pins {
|
||||
mux {
|
||||
function = "pcie";
|
||||
groups = "pcie_1l_0_pereset", "pcie_clk_req_n2_0",
|
||||
"pcie_wake_n2_0";
|
||||
};
|
||||
};
|
||||
|
||||
pcie3_pins: pcie3-pins {
|
||||
mux {
|
||||
function = "pcie";
|
||||
groups = "pcie_1l_1_pereset", "pcie_clk_req_n3",
|
||||
"pcie_wake_n3_0";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&watchdog {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&xphy {
|
||||
status = "okay";
|
||||
};
|
|
@ -0,0 +1,853 @@
|
|||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/*
|
||||
* Copyright (C) 2023 MediaTek Inc.
|
||||
* Author: Sam.Shih <sam.shih@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
#include <dt-bindings/phy/phy.h>
|
||||
#include <dt-bindings/reset/ti-syscon.h>
|
||||
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
|
||||
#include <dt-bindings/pinctrl/mt65xx.h>
|
||||
#include <dt-bindings/thermal/thermal.h>
|
||||
|
||||
/ {
|
||||
compatible = "mediatek,mt7988";
|
||||
interrupt-parent = <&gic>;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
|
||||
clk40m: oscillator@0 {
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <40000000>;
|
||||
#clock-cells = <0>;
|
||||
clock-output-names = "clkxtal";
|
||||
};
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
cpu0: cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a73";
|
||||
enable-method = "psci";
|
||||
reg = <0x0>;
|
||||
clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
|
||||
<&topckgen CLK_TOP_XTAL>;
|
||||
clock-names = "cpu", "intermediate";
|
||||
operating-points-v2 = <&cluster0_opp>;
|
||||
mediatek,cci = <&cci>;
|
||||
};
|
||||
|
||||
cpu1: cpu@1 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a73";
|
||||
enable-method = "psci";
|
||||
reg = <0x1>;
|
||||
clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
|
||||
<&topckgen CLK_TOP_XTAL>;
|
||||
clock-names = "cpu", "intermediate";
|
||||
operating-points-v2 = <&cluster0_opp>;
|
||||
mediatek,cci = <&cci>;
|
||||
};
|
||||
|
||||
cpu2: cpu@2 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a73";
|
||||
enable-method = "psci";
|
||||
reg = <0x2>;
|
||||
clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
|
||||
<&topckgen CLK_TOP_XTAL>;
|
||||
clock-names = "cpu", "intermediate";
|
||||
operating-points-v2 = <&cluster0_opp>;
|
||||
mediatek,cci = <&cci>;
|
||||
};
|
||||
|
||||
cpu3: cpu@3 {
|
||||
device_type = "cpu";
|
||||
compatible = "arm,cortex-a73";
|
||||
enable-method = "psci";
|
||||
reg = <0x3>;
|
||||
clocks = <&mcusys CLK_MCU_ARM_DIV_SEL>,
|
||||
<&topckgen CLK_TOP_XTAL>;
|
||||
clock-names = "cpu", "intermediate";
|
||||
operating-points-v2 = <&cluster0_opp>;
|
||||
mediatek,cci = <&cci>;
|
||||
};
|
||||
|
||||
cluster0_opp: opp_table0 {
|
||||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
opp00 {
|
||||
opp-hz = /bits/ 64 <800000000>;
|
||||
opp-microvolt = <850000>;
|
||||
};
|
||||
opp01 {
|
||||
opp-hz = /bits/ 64 <1100000000>;
|
||||
opp-microvolt = <850000>;
|
||||
};
|
||||
opp02 {
|
||||
opp-hz = /bits/ 64 <1500000000>;
|
||||
opp-microvolt = <850000>;
|
||||
};
|
||||
opp03 {
|
||||
opp-hz = /bits/ 64 <1800000000>;
|
||||
opp-microvolt = <900000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
cci: cci {
|
||||
compatible = "mediatek,mt7988-cci",
|
||||
"mediatek,mt8183-cci";
|
||||
clocks = <&mcusys CLK_MCU_BUS_DIV_SEL>,
|
||||
<&topckgen CLK_TOP_XTAL>;
|
||||
clock-names = "cci", "intermediate";
|
||||
operating-points-v2 = <&cci_opp>;
|
||||
};
|
||||
|
||||
cci_opp: opp_table_cci {
|
||||
compatible = "operating-points-v2";
|
||||
opp-shared;
|
||||
opp00 {
|
||||
opp-hz = /bits/ 64 <480000000>;
|
||||
opp-microvolt = <850000>;
|
||||
};
|
||||
opp01 {
|
||||
opp-hz = /bits/ 64 <660000000>;
|
||||
opp-microvolt = <850000>;
|
||||
};
|
||||
opp02 {
|
||||
opp-hz = /bits/ 64 <900000000>;
|
||||
opp-microvolt = <850000>;
|
||||
};
|
||||
opp03 {
|
||||
opp-hz = /bits/ 64 <1080000000>;
|
||||
opp-microvolt = <900000>;
|
||||
};
|
||||
};
|
||||
|
||||
pmu {
|
||||
compatible = "arm,cortex-a73-pmu";
|
||||
interrupt-parent = <&gic>;
|
||||
interrupt = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
|
||||
psci {
|
||||
compatible = "arm,psci-0.2";
|
||||
method = "smc";
|
||||
};
|
||||
|
||||
reserved-memory {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
|
||||
/* 192 KiB reserved for ARM Trusted Firmware (BL31) */
|
||||
secmon_reserved: secmon@43000000 {
|
||||
reg = <0 0x43000000 0 0x30000>;
|
||||
no-map;
|
||||
};
|
||||
};
|
||||
|
||||
timer {
|
||||
compatible = "arm,armv8-timer";
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
|
||||
<GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
|
||||
<GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
|
||||
<GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
gic: interrupt-controller@c000000 {
|
||||
compatible = "arm,gic-v3";
|
||||
#interrupt-cells = <3>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupt-controller;
|
||||
reg = <0 0x0c000000 0 0x40000>, /* GICD */
|
||||
<0 0x0c080000 0 0x200000>, /* GICR */
|
||||
<0 0x0c400000 0 0x2000>, /* GICC */
|
||||
<0 0x0c410000 0 0x1000>, /* GICH */
|
||||
<0 0x0c420000 0 0x2000>; /* GICV */
|
||||
|
||||
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
|
||||
phyfw: phy-firmware@f000000 {
|
||||
compatible = "mediatek,2p5gphy-fw";
|
||||
reg = <0 0x0f000000 0 0x8000>,
|
||||
<0 0x0f100000 0 0x20000>,
|
||||
<0 0x0f0f0000 0 0x200>;
|
||||
};
|
||||
|
||||
infracfg: infracfg@10001000 {
|
||||
compatible = "mediatek,mt7988-infracfg", "syscon";
|
||||
reg = <0 0x10001000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
topckgen: topckgen@1001b000 {
|
||||
compatible = "mediatek,mt7988-topckgen", "syscon";
|
||||
reg = <0 0x1001b000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
watchdog: watchdog@1001c000 {
|
||||
compatible = "mediatek,mt7988-wdt",
|
||||
"mediatek,mt6589-wdt",
|
||||
"syscon";
|
||||
reg = <0 0x1001c000 0 0x1000>;
|
||||
interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
apmixedsys: apmixedsys@1001e000 {
|
||||
compatible = "mediatek,mt7988-apmixedsys";
|
||||
reg = <0 0x1001e000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
pio: pinctrl@1001f000 {
|
||||
compatible = "mediatek,mt7988-pinctrl";
|
||||
reg = <0 0x1001f000 0 0x1000>,
|
||||
<0 0x11c10000 0 0x1000>,
|
||||
<0 0x11d00000 0 0x1000>,
|
||||
<0 0x11d20000 0 0x1000>,
|
||||
<0 0x11e00000 0 0x1000>,
|
||||
<0 0x11f00000 0 0x1000>,
|
||||
<0 0x1000b000 0 0x1000>;
|
||||
reg-names = "gpio_base", "iocfg_tr_base",
|
||||
"iocfg_br_base", "iocfg_rb_base",
|
||||
"iocfg_lb_base", "iocfg_tl_base", "eint";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
gpio-ranges = <&pio 0 0 83>;
|
||||
interrupt-controller;
|
||||
interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-parent = <&gic>;
|
||||
#interrupt-cells = <2>;
|
||||
|
||||
mdio0_pins: mdio0-pins {
|
||||
mux {
|
||||
function = "eth";
|
||||
groups = "mdc_mdio0";
|
||||
};
|
||||
|
||||
conf {
|
||||
groups = "mdc_mdio0";
|
||||
drive-strength = <MTK_DRIVE_8mA>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c0_pins: i2c0-pins-g0 {
|
||||
mux {
|
||||
function = "i2c";
|
||||
groups = "i2c0_1";
|
||||
};
|
||||
};
|
||||
|
||||
i2c1_pins: i2c1-pins-g0 {
|
||||
mux {
|
||||
function = "i2c";
|
||||
groups = "i2c1_0";
|
||||
};
|
||||
};
|
||||
|
||||
i2c2_pins: i2c2-pins-g0 {
|
||||
mux {
|
||||
function = "i2c";
|
||||
groups = "i2c2_1";
|
||||
};
|
||||
};
|
||||
|
||||
gbe0_led0_pins: gbe0-pins {
|
||||
mux {
|
||||
function = "led";
|
||||
groups = "gbe0_led0";
|
||||
};
|
||||
};
|
||||
|
||||
gbe1_led0_pins: gbe1-pins {
|
||||
mux {
|
||||
function = "led";
|
||||
groups = "gbe1_led0";
|
||||
};
|
||||
};
|
||||
|
||||
gbe2_led0_pins: gbe2-pins {
|
||||
mux {
|
||||
function = "led";
|
||||
groups = "gbe2_led0";
|
||||
};
|
||||
};
|
||||
|
||||
gbe3_led0_pins: gbe3-pins {
|
||||
mux {
|
||||
function = "led";
|
||||
groups = "gbe3_led0";
|
||||
};
|
||||
};
|
||||
|
||||
i2p5gbe_led0_pins: 2p5gbe-pins {
|
||||
mux {
|
||||
function = "led";
|
||||
groups = "2p5gbe_led0";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
boottrap: boottrap@1001f6f0 {
|
||||
compatible = "mediatek,boottrap";
|
||||
reg = <0 0x1001f6f0 0 0x4>;
|
||||
};
|
||||
|
||||
sgmiisys0: syscon@10060000 {
|
||||
compatible = "mediatek,mt7988-sgmiisys",
|
||||
"mediatek,mt7988-sgmiisys_0",
|
||||
"syscon";
|
||||
reg = <0 0x10060000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
sgmiisys1: syscon@10070000 {
|
||||
compatible = "mediatek,mt7988-sgmiisys",
|
||||
"mediatek,mt7988-sgmiisys_1",
|
||||
"syscon";
|
||||
reg = <0 0x10070000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
usxgmiisys0: usxgmiisys@10080000 {
|
||||
compatible = "mediatek,mt7988-usxgmiisys",
|
||||
"mediatek,mt7988-usxgmiisys_0",
|
||||
"syscon";
|
||||
reg = <0 0x10080000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
usxgmiisys1: usxgmiisys@10081000 {
|
||||
compatible = "mediatek,mt7988-usxgmiisys",
|
||||
"mediatek,mt7988-usxgmiisys_1",
|
||||
"syscon";
|
||||
reg = <0 0x10081000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
xfi_pextp0: xfi_pextp@11f20000 {
|
||||
compatible = "mediatek,mt7988-xfi_pextp",
|
||||
"mediatek,mt7988-xfi_pextp_0",
|
||||
"syscon";
|
||||
reg = <0 0x11f20000 0 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
xfi_pextp1: xfi_pextp@11f30000 {
|
||||
compatible = "mediatek,mt7988-xfi_pextp",
|
||||
"mediatek,mt7988-xfi_pextp_1",
|
||||
"syscon";
|
||||
reg = <0 0x11f30000 0 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
xfi_pll: xfi_pll@11f40000 {
|
||||
compatible = "mediatek,mt7988-xfi_pll", "syscon";
|
||||
reg = <0 0x11f40000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
mcusys: mcusys@100e0000 {
|
||||
compatible = "mediatek,mt7988-mcusys", "syscon";
|
||||
reg = <0 0x100e0000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
||||
uart0: serial@11000000 {
|
||||
compatible = "mediatek,mt7986-uart",
|
||||
"mediatek,mt6577-uart";
|
||||
reg = <0 0x11000000 0 0x100>;
|
||||
interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
|
||||
/*
|
||||
* 8250-mtk driver don't control "baud" clock since commit
|
||||
* e32a83c70cf9 (kernel v5.7), but both "baud" and "bus" clocks
|
||||
* still need to be passed to the driver to prevent probe fail
|
||||
*/
|
||||
clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&infracfg CLK_INFRA_52M_UART0_CK>;
|
||||
clock-names = "baud", "bus";
|
||||
assigned-clocks = <&topckgen CLK_TOP_UART_SEL>,
|
||||
<&infracfg CLK_INFRA_MUX_UART0_SEL>;
|
||||
assigned-clock-parents = <&topckgen CLK_TOP_XTAL>,
|
||||
<&topckgen CLK_TOP_UART_SEL>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c0: i2c@11003000 {
|
||||
compatible = "mediatek,mt7988-i2c",
|
||||
"mediatek,mt7981-i2c";
|
||||
reg = <0 0x11003000 0 0x1000>,
|
||||
<0 0x10217080 0 0x80>;
|
||||
interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-div = <1>;
|
||||
clocks = <&infracfg CLK_INFRA_I2C_BCK>,
|
||||
<&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
|
||||
clock-names = "main", "dma";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c1: i2c@11004000 {
|
||||
compatible = "mediatek,mt7988-i2c",
|
||||
"mediatek,mt7981-i2c";
|
||||
reg = <0 0x11004000 0 0x1000>,
|
||||
<0 0x10217100 0 0x80>;
|
||||
interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-div = <1>;
|
||||
clocks = <&infracfg CLK_INFRA_I2C_BCK>,
|
||||
<&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
|
||||
clock-names = "main", "dma";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c2: i2c@11005000 {
|
||||
compatible = "mediatek,mt7988-i2c",
|
||||
"mediatek,mt7981-i2c";
|
||||
reg = <0 0x11005000 0 0x1000>,
|
||||
<0 0x10217180 0 0x80>;
|
||||
interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clock-div = <1>;
|
||||
clocks = <&infracfg CLK_INFRA_I2C_BCK>,
|
||||
<&infracfg CLK_INFRA_66M_AP_DMA_BCK>;
|
||||
clock-names = "main", "dma";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi0: spi@11007000 {
|
||||
compatible = "mediatek,ipm-spi-quad", "mediatek,spi-ipm";
|
||||
reg = <0 0x11007000 0 0x100>;
|
||||
interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&topckgen CLK_TOP_MPLL_D2>,
|
||||
<&topckgen CLK_TOP_SPI_SEL>,
|
||||
<&infracfg CLK_INFRA_104M_SPI0>,
|
||||
<&infracfg CLK_INFRA_66M_SPI0_HCK>;
|
||||
clock-names = "parent-clk", "sel-clk", "spi-clk",
|
||||
"spi-hclk";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
pcie2: pcie@11280000 {
|
||||
compatible = "mediatek,mt7988-pcie",
|
||||
"mediatek,mt7986-pcie",
|
||||
"mediatek,mt8192-pcie";
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
reg = <0 0x11280000 0 0x2000>;
|
||||
reg-names = "pcie-mac";
|
||||
linux,pci-domain = <3>;
|
||||
interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x81000000 0x00 0x20000000 0x00
|
||||
0x20000000 0x00 0x00200000>,
|
||||
<0x82000000 0x00 0x20200000 0x00
|
||||
0x20200000 0x00 0x07e00000>;
|
||||
clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P2>,
|
||||
<&infracfg CLK_INFRA_PCIE_GFMUX_TL_P2>,
|
||||
<&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P2>,
|
||||
<&infracfg CLK_INFRA_133M_PCIE_CK_P2>;
|
||||
clock-names = "pl_250m", "tl_26m", "peri_26m",
|
||||
"top_133m";
|
||||
status = "disabled";
|
||||
|
||||
phys = <&xphyu3port0 PHY_TYPE_PCIE>;
|
||||
phy-names = "pcie-phy";
|
||||
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc2 0>,
|
||||
<0 0 0 2 &pcie_intc2 1>,
|
||||
<0 0 0 3 &pcie_intc2 2>,
|
||||
<0 0 0 4 &pcie_intc2 3>;
|
||||
pcie_intc2: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
pcie3: pcie@11290000 {
|
||||
compatible = "mediatek,mt7988-pcie",
|
||||
"mediatek,mt7986-pcie",
|
||||
"mediatek,mt8192-pcie";
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
reg = <0 0x11290000 0 0x2000>;
|
||||
reg-names = "pcie-mac";
|
||||
linux,pci-domain = <2>;
|
||||
interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x81000000 0x00 0x28000000 0x00
|
||||
0x28000000 0x00 0x00200000>,
|
||||
<0x82000000 0x00 0x28200000 0x00
|
||||
0x28200000 0x00 0x07e00000>;
|
||||
clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P3>,
|
||||
<&infracfg CLK_INFRA_PCIE_GFMUX_TL_P3>,
|
||||
<&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P3>,
|
||||
<&infracfg CLK_INFRA_133M_PCIE_CK_P3>;
|
||||
clock-names = "pl_250m", "tl_26m", "peri_26m",
|
||||
"top_133m";
|
||||
status = "disabled";
|
||||
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc3 0>,
|
||||
<0 0 0 2 &pcie_intc3 1>,
|
||||
<0 0 0 3 &pcie_intc3 2>,
|
||||
<0 0 0 4 &pcie_intc3 3>;
|
||||
pcie_intc3: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
pcie0: pcie@11300000 {
|
||||
compatible = "mediatek,mt7988-pcie",
|
||||
"mediatek,mt7986-pcie",
|
||||
"mediatek,mt8192-pcie";
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
reg = <0 0x11300000 0 0x2000>;
|
||||
reg-names = "pcie-mac";
|
||||
linux,pci-domain = <0>;
|
||||
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x81000000 0x00 0x30000000 0x00
|
||||
0x30000000 0x00 0x00200000>,
|
||||
<0x82000000 0x00 0x30200000 0x00
|
||||
0x30200000 0x00 0x07e00000>;
|
||||
clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P0>,
|
||||
<&infracfg CLK_INFRA_PCIE_GFMUX_TL_P0>,
|
||||
<&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P0>,
|
||||
<&infracfg CLK_INFRA_133M_PCIE_CK_P0>;
|
||||
clock-names = "pl_250m", "tl_26m", "peri_26m",
|
||||
"top_133m";
|
||||
status = "disabled";
|
||||
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc0 0>,
|
||||
<0 0 0 2 &pcie_intc0 1>,
|
||||
<0 0 0 3 &pcie_intc0 2>,
|
||||
<0 0 0 4 &pcie_intc0 3>;
|
||||
pcie_intc0: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
pcie1: pcie@11310000 {
|
||||
compatible = "mediatek,mt7988-pcie",
|
||||
"mediatek,mt7986-pcie",
|
||||
"mediatek,mt8192-pcie";
|
||||
device_type = "pci";
|
||||
#address-cells = <3>;
|
||||
#size-cells = <2>;
|
||||
reg = <0 0x11310000 0 0x2000>;
|
||||
reg-names = "pcie-mac";
|
||||
linux,pci-domain = <1>;
|
||||
interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
|
||||
bus-range = <0x00 0xff>;
|
||||
ranges = <0x81000000 0x00 0x38000000 0x00
|
||||
0x38000000 0x00 0x00200000>,
|
||||
<0x82000000 0x00 0x38200000 0x00
|
||||
0x38200000 0x00 0x07e00000>;
|
||||
clocks = <&infracfg CLK_INFRA_PCIE_PIPE_P1>,
|
||||
<&infracfg CLK_INFRA_PCIE_GFMUX_TL_P1>,
|
||||
<&infracfg CLK_INFRA_PCIE_PERI_26M_CK_P1>,
|
||||
<&infracfg CLK_INFRA_133M_PCIE_CK_P1>;
|
||||
clock-names = "pl_250m", "tl_26m", "peri_26m",
|
||||
"top_133m";
|
||||
status = "disabled";
|
||||
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-map-mask = <0 0 0 0x7>;
|
||||
interrupt-map = <0 0 0 1 &pcie_intc1 0>,
|
||||
<0 0 0 2 &pcie_intc1 1>,
|
||||
<0 0 0 3 &pcie_intc1 2>,
|
||||
<0 0 0 4 &pcie_intc1 3>;
|
||||
pcie_intc1: interrupt-controller {
|
||||
#address-cells = <0>;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
ssusb0: usb@11190000 {
|
||||
compatible = "mediatek,mt7988-xhci",
|
||||
"mediatek,mtk-xhci";
|
||||
reg = <0 0x11190000 0 0x2e00>,
|
||||
<0 0x11193e00 0 0x0100>;
|
||||
reg-names = "mac", "ippc";
|
||||
interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
|
||||
phys = <&xphyu2port0 PHY_TYPE_USB2>,
|
||||
<&xphyu3port0 PHY_TYPE_USB3>;
|
||||
clocks = <&infracfg CLK_INFRA_USB_SYS>,
|
||||
<&infracfg CLK_INFRA_USB_XHCI>,
|
||||
<&infracfg CLK_INFRA_USB_REF>,
|
||||
<&infracfg CLK_INFRA_66M_USB_HCK>,
|
||||
<&infracfg CLK_INFRA_133M_USB_HCK>;
|
||||
clock-names = "sys_ck",
|
||||
"xhci_ck",
|
||||
"ref_ck",
|
||||
"mcu_ck",
|
||||
"dma_ck";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
mediatek,p0_speed_fixup;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
ssusb1: usb@11200000 {
|
||||
compatible = "mediatek,mt7988-xhci",
|
||||
"mediatek,mtk-xhci";
|
||||
reg = <0 0x11200000 0 0x2e00>,
|
||||
<0 0x11203e00 0 0x0100>;
|
||||
reg-names = "mac", "ippc";
|
||||
interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
|
||||
phys = <&tphyu2port0 PHY_TYPE_USB2>,
|
||||
<&tphyu3port0 PHY_TYPE_USB3>;
|
||||
clocks = <&infracfg CLK_INFRA_USB_SYS_CK_P1>,
|
||||
<&infracfg CLK_INFRA_USB_XHCI_CK_P1>,
|
||||
<&infracfg CLK_INFRA_USB_CK_P1>,
|
||||
<&infracfg CLK_INFRA_66M_USB_HCK_CK_P1>,
|
||||
<&infracfg CLK_INFRA_133M_USB_HCK_CK_P1>;
|
||||
clock-names = "sys_ck",
|
||||
"xhci_ck",
|
||||
"ref_ck",
|
||||
"mcu_ck",
|
||||
"dma_ck";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tphy: tphy@11c50000 {
|
||||
compatible = "mediatek,mt7988",
|
||||
"mediatek,generic-tphy-v2";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
status = "disabled";
|
||||
tphyu2port0: usb-phy@11c50000 {
|
||||
reg = <0 0x11c50000 0 0x700>;
|
||||
clocks = <&infracfg CLK_INFRA_USB_UTMI_CK_P1>;
|
||||
clock-names = "ref";
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
tphyu3port0: usb-phy@11c50700 {
|
||||
reg = <0 0x11c50700 0 0x900>;
|
||||
clocks = <&infracfg CLK_INFRA_USB_PIPE_CK_P1>;
|
||||
clock-names = "ref";
|
||||
#phy-cells = <1>;
|
||||
mediatek,usb3-pll-ssc-delta;
|
||||
mediatek,usb3-pll-ssc-delta1;
|
||||
};
|
||||
};
|
||||
|
||||
topmisc: topmisc@11d10000 {
|
||||
compatible = "mediatek,mt7988-topmisc", "syscon",
|
||||
"mediatek,mt7988-power-controller";
|
||||
reg = <0 0x11d10000 0 0x10000>;
|
||||
#clock-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
|
||||
xphy: xphy@11e10000 {
|
||||
compatible = "mediatek,mt7988",
|
||||
"mediatek,xsphy";
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
ranges;
|
||||
status = "disabled";
|
||||
|
||||
xphyu2port0: usb-phy@11e10000 {
|
||||
reg = <0 0x11e10000 0 0x400>;
|
||||
clocks = <&infracfg CLK_INFRA_USB_UTMI>;
|
||||
clock-names = "ref";
|
||||
#phy-cells = <1>;
|
||||
};
|
||||
|
||||
xphyu3port0: usb-phy@11e13000 {
|
||||
reg = <0 0x11e13400 0 0x500>;
|
||||
clocks = <&infracfg CLK_INFRA_USB_PIPE>;
|
||||
clock-names = "ref";
|
||||
#phy-cells = <1>;
|
||||
mediatek,syscon-type = <&topmisc 0x218 0>;
|
||||
};
|
||||
};
|
||||
|
||||
efuse: efuse@11f50000 {
|
||||
compatible = "mediatek,efuse";
|
||||
reg = <0 0x11f50000 0 0x1000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
lvts_calibration: calib@918 {
|
||||
reg = <0x918 0x28>;
|
||||
};
|
||||
phy_calibration_p0: calib@940 {
|
||||
reg = <0x940 0x10>;
|
||||
};
|
||||
phy_calibration_p1: calib@954 {
|
||||
reg = <0x954 0x10>;
|
||||
};
|
||||
phy_calibration_p2: calib@968 {
|
||||
reg = <0x968 0x10>;
|
||||
};
|
||||
phy_calibration_p3: calib@97c {
|
||||
reg = <0x97c 0x10>;
|
||||
};
|
||||
cpufreq_calibration: calib@278 {
|
||||
reg = <0x278 0x1>;
|
||||
};
|
||||
};
|
||||
|
||||
ethsys: syscon@15000000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "mediatek,mt7988-ethsys", "syscon";
|
||||
reg = <0 0x15000000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
switch: switch@15020000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "mediatek,mt7988-switch";
|
||||
reg = <0 0x15020000 0 0x8000>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-parent = <&gic>;
|
||||
interrupts = <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
|
||||
resets = <ðrst 0>;
|
||||
};
|
||||
|
||||
ethwarp: syscon@15031000 {
|
||||
compatible = "mediatek,mt7988-ethwarp", "syscon", "simple-mfd";
|
||||
reg = <0 0x15031000 0 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
|
||||
ethrst: reset-controller {
|
||||
compatible = "ti,syscon-reset";
|
||||
#reset-cells = <1>;
|
||||
ti,reset-bits = <
|
||||
0x8 9 0x8 9 0 0 (ASSERT_SET | DEASSERT_CLEAR | STATUS_NONE)
|
||||
>;
|
||||
};
|
||||
};
|
||||
|
||||
eth: ethernet@15100000 {
|
||||
compatible = "mediatek,mt7988-eth";
|
||||
reg = <0 0x15100000 0 0x80000>,
|
||||
<0 0x15400000 0 0x380000>;
|
||||
interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <ðsys CLK_ETHDMA_XGP1_EN>,
|
||||
<ðsys CLK_ETHDMA_XGP2_EN>,
|
||||
<ðsys CLK_ETHDMA_XGP3_EN>,
|
||||
<ðsys CLK_ETHDMA_FE_EN>,
|
||||
<ðsys CLK_ETHDMA_GP2_EN>,
|
||||
<ðsys CLK_ETHDMA_GP1_EN>,
|
||||
<ðsys CLK_ETHDMA_GP3_EN>,
|
||||
<ðsys CLK_ETHDMA_ESW_EN>,
|
||||
<ðsys CLK_ETHDMA_CRYPT0_EN>,
|
||||
<&sgmiisys0 CLK_SGM0_TX_EN>,
|
||||
<&sgmiisys0 CLK_SGM0_RX_EN>,
|
||||
<&sgmiisys1 CLK_SGM1_TX_EN>,
|
||||
<&sgmiisys1 CLK_SGM1_RX_EN>,
|
||||
<ðwarp CLK_ETHWARP_WOCPU2_EN>,
|
||||
<ðwarp CLK_ETHWARP_WOCPU1_EN>,
|
||||
<ðwarp CLK_ETHWARP_WOCPU0_EN>,
|
||||
<&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
|
||||
<&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
|
||||
<&topckgen CLK_TOP_SGM_0_SEL>,
|
||||
<&topckgen CLK_TOP_SGM_1_SEL>,
|
||||
<&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>,
|
||||
<&topckgen CLK_TOP_XFI_PHY_1_XTAL_SEL>,
|
||||
<&topckgen CLK_TOP_ETH_GMII_SEL>,
|
||||
<&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
|
||||
<&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
|
||||
<&topckgen CLK_TOP_ETH_SYS_SEL>,
|
||||
<&topckgen CLK_TOP_ETH_XGMII_SEL>,
|
||||
<&topckgen CLK_TOP_ETH_MII_SEL>,
|
||||
<&topckgen CLK_TOP_NETSYS_SEL>,
|
||||
<&topckgen CLK_TOP_NETSYS_500M_SEL>,
|
||||
<&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
|
||||
<&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
|
||||
<&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
|
||||
<&topckgen CLK_TOP_NETSYS_WARP_SEL>;
|
||||
clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
|
||||
"gp3", "esw", "crypto", "sgmii_tx250m",
|
||||
"sgmii_rx250m", "sgmii2_tx250m", "sgmii2_rx250m",
|
||||
"ethwarp_wocpu2", "ethwarp_wocpu1",
|
||||
"ethwarp_wocpu0", "top_usxgmii0_sel",
|
||||
"top_usxgmii1_sel", "top_sgm0_sel",
|
||||
"top_sgm1_sel", "top_xfi_phy0_xtal_sel",
|
||||
"top_xfi_phy1_xtal_sel", "top_eth_gmii_sel",
|
||||
"top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
|
||||
"top_eth_sys_sel", "top_eth_xgmii_sel",
|
||||
"top_eth_mii_sel", "top_netsys_sel",
|
||||
"top_netsys_500m_sel", "top_netsys_pao_2x_sel",
|
||||
"top_netsys_sync_250m_sel",
|
||||
"top_netsys_ppefb_250m_sel",
|
||||
"top_netsys_warp_sel";
|
||||
assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
|
||||
<&topckgen CLK_TOP_NETSYS_GSW_SEL>,
|
||||
<&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
|
||||
<&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
|
||||
<&topckgen CLK_TOP_SGM_0_SEL>,
|
||||
<&topckgen CLK_TOP_SGM_1_SEL>;
|
||||
assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
|
||||
<&topckgen CLK_TOP_NET1PLL_D4>,
|
||||
<&topckgen CLK_TOP_NET1PLL_D8_D4>,
|
||||
<&topckgen CLK_TOP_NET1PLL_D8_D4>,
|
||||
<&apmixedsys CLK_APMIXED_SGMPLL>,
|
||||
<&apmixedsys CLK_APMIXED_SGMPLL>;
|
||||
mediatek,ethsys = <ðsys>;
|
||||
mediatek,sgmiisys = <&sgmiisys0>, <&sgmiisys1>;
|
||||
mediatek,usxgmiisys = <&usxgmiisys0>, <&usxgmiisys1>;
|
||||
mediatek,xfi_pextp = <&xfi_pextp0>, <&xfi_pextp1>;
|
||||
mediatek,xfi_pll = <&xfi_pll>;
|
||||
mediatek,infracfg = <&topmisc>;
|
||||
mediatek,toprgu = <&watchdog>;
|
||||
#reset-cells = <1>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
};
|
|
@ -0,0 +1,113 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2023 MediaTek Inc.
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
* Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mux.h"
|
||||
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
|
||||
|
||||
#define MT7988_PLL_FMAX (2500UL * MHZ)
|
||||
#define MT7988_PCW_CHG_SHIFT 2
|
||||
|
||||
#define PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask, \
|
||||
_pcwbits, _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg, \
|
||||
_tuner_en_bit, _pcw_reg, _pcw_shift, _pcw_chg_reg, \
|
||||
_div_table) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .reg = _reg, .pwr_reg = _pwr_reg, \
|
||||
.en_mask = _en_mask, .flags = _flags, \
|
||||
.rst_bar_mask = BIT(_rst_bar_mask), .fmax = MT7988_PLL_FMAX, \
|
||||
.pcwbits = _pcwbits, .pd_reg = _pd_reg, \
|
||||
.pd_shift = _pd_shift, .tuner_reg = _tuner_reg, \
|
||||
.tuner_en_reg = _tuner_en_reg, .tuner_en_bit = _tuner_en_bit, \
|
||||
.pcw_reg = _pcw_reg, .pcw_shift = _pcw_shift, \
|
||||
.pcw_chg_reg = _pcw_chg_reg, \
|
||||
.pcw_chg_shift = MT7988_PCW_CHG_SHIFT, \
|
||||
.div_table = _div_table, .parent_name = "clkxtal", \
|
||||
}
|
||||
|
||||
#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask, \
|
||||
_pcwbits, _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg, \
|
||||
_tuner_en_bit, _pcw_reg, _pcw_shift, _pcw_chg_reg) \
|
||||
PLL_xtal(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask, \
|
||||
_pcwbits, _pd_reg, _pd_shift, _tuner_reg, _tuner_en_reg, \
|
||||
_tuner_en_bit, _pcw_reg, _pcw_shift, _pcw_chg_reg, NULL)
|
||||
|
||||
static const struct mtk_pll_data plls[] = {
|
||||
PLL(CLK_APMIXED_NETSYSPLL, "netsyspll", 0x0104, 0x0110, 0x00000001, 0,
|
||||
0, 32, 0x0104, 4, 0, 0, 0, 0x0108, 0, 0x0104),
|
||||
PLL(CLK_APMIXED_MPLL, "mpll", 0x0114, 0x0120, 0xff000001, HAVE_RST_BAR,
|
||||
23, 32, 0x0114, 4, 0, 0, 0, 0x0118, 0, 0x0114),
|
||||
PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0124, 0x0130, 0xff000001,
|
||||
HAVE_RST_BAR, 23, 32, 0x0124, 4, 0, 0, 0, 0x0128, 0, 0x0124),
|
||||
PLL(CLK_APMIXED_APLL2, "apll2", 0x0134, 0x0140, 0x00000001, 0, 0, 32,
|
||||
0x0134, 4, 0x0704, 0x0700, 1, 0x0138, 0, 0x0134),
|
||||
PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0144, 0x0150, 0xff000001,
|
||||
HAVE_RST_BAR, 23, 32, 0x0144, 4, 0, 0, 0, 0x0148, 0, 0x0144),
|
||||
PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0154, 0x0160, 0xff000001,
|
||||
(HAVE_RST_BAR | PLL_AO), 23, 32, 0x0154, 4, 0, 0, 0, 0x0158, 0,
|
||||
0x0154),
|
||||
PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0164, 0x0170, 0x00000001, 0,
|
||||
0, 32, 0x0164, 4, 0, 0, 0, 0x0168, 0, 0x0164),
|
||||
PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0174, 0x0180, 0x00000001, 0, 0, 32,
|
||||
0x0174, 4, 0, 0, 0, 0x0178, 0, 0x0174),
|
||||
PLL(CLK_APMIXED_ARM_B, "arm_b", 0x0204, 0x0210, 0xff000001,
|
||||
(HAVE_RST_BAR | PLL_AO), 23, 32, 0x0204, 4, 0, 0, 0, 0x0208, 0,
|
||||
0x0204),
|
||||
PLL(CLK_APMIXED_CCIPLL2_B, "ccipll2_b", 0x0214, 0x0220, 0xff000001,
|
||||
HAVE_RST_BAR, 23, 32, 0x0214, 4, 0, 0, 0, 0x0218, 0, 0x0214),
|
||||
PLL(CLK_APMIXED_USXGMIIPLL, "usxgmiipll", 0x0304, 0x0310, 0xff000001,
|
||||
HAVE_RST_BAR, 23, 32, 0x0304, 4, 0, 0, 0, 0x0308, 0, 0x0304),
|
||||
PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0314, 0x0320, 0x00000001, 0, 0,
|
||||
32, 0x0314, 4, 0, 0, 0, 0x0318, 0, 0x0314),
|
||||
};
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7988_apmixed[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt7988-apmixedsys",
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static int clk_mt7988_apmixed_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls));
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_apmixed_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_apmixed_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static struct platform_driver clk_mt7988_apmixed_drv = {
|
||||
.probe = clk_mt7988_apmixed_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7988-apmixed",
|
||||
.of_match_table = of_match_clk_mt7988_apmixed,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7988_apmixed_drv);
|
|
@ -0,0 +1,299 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2023 MediaTek Inc.
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
* Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
|
||||
|
||||
static const struct mtk_gate_regs ethdma_cg_regs = {
|
||||
.set_ofs = 0x30,
|
||||
.clr_ofs = 0x30,
|
||||
.sta_ofs = 0x30,
|
||||
};
|
||||
|
||||
#define GATE_ETHDMA(_id, _name, _parent, _shift) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = ðdma_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate ethdma_clks[] = {
|
||||
GATE_ETHDMA(CLK_ETHDMA_XGP1_EN, "ethdma_xgp1_en", "top_xtal", 0),
|
||||
GATE_ETHDMA(CLK_ETHDMA_XGP2_EN, "ethdma_xgp2_en", "top_xtal", 1),
|
||||
GATE_ETHDMA(CLK_ETHDMA_XGP3_EN, "ethdma_xgp3_en", "top_xtal", 2),
|
||||
GATE_ETHDMA(CLK_ETHDMA_FE_EN, "ethdma_fe_en", "netsys_2x_sel", 6),
|
||||
GATE_ETHDMA(CLK_ETHDMA_GP2_EN, "ethdma_gp2_en", "top_xtal", 7),
|
||||
GATE_ETHDMA(CLK_ETHDMA_GP1_EN, "ethdma_gp1_en", "top_xtal", 8),
|
||||
GATE_ETHDMA(CLK_ETHDMA_GP3_EN, "ethdma_gp3_en", "top_xtal", 10),
|
||||
GATE_ETHDMA(CLK_ETHDMA_ESW_EN, "ethdma_esw_en", "netsys_gsw_sel", 16),
|
||||
GATE_ETHDMA(CLK_ETHDMA_CRYPT0_EN, "ethdma_crypt0_en", "eip197_sel",
|
||||
29),
|
||||
};
|
||||
|
||||
static int clk_mt7988_ethsys_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
void __iomem *base;
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("%s(): ioremap failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(ethdma_clks));
|
||||
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_gates(node, ethdma_clks, ARRAY_SIZE(ethdma_clks),
|
||||
clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct mtk_gate_regs sgmii0_cg_regs = {
|
||||
.set_ofs = 0xe4,
|
||||
.clr_ofs = 0xe4,
|
||||
.sta_ofs = 0xe4,
|
||||
};
|
||||
|
||||
#define GATE_SGMII0(_id, _name, _parent, _shift) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = &sgmii0_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate sgmii0_clks[] = {
|
||||
GATE_SGMII0(CLK_SGM0_TX_EN, "sgm0_tx_en", "top_xtal", 2),
|
||||
GATE_SGMII0(CLK_SGM0_RX_EN, "sgm0_rx_en", "top_xtal", 3),
|
||||
};
|
||||
|
||||
static int clk_mt7988_sgmii0_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
void __iomem *base;
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("%s(): ioremap failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii0_clks));
|
||||
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_gates(node, sgmii0_clks, ARRAY_SIZE(sgmii0_clks),
|
||||
clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct mtk_gate_regs sgmii1_cg_regs = {
|
||||
.set_ofs = 0xe4,
|
||||
.clr_ofs = 0xe4,
|
||||
.sta_ofs = 0xe4,
|
||||
};
|
||||
|
||||
#define GATE_SGMII1(_id, _name, _parent, _shift) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = &sgmii1_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate sgmii1_clks[] = {
|
||||
GATE_SGMII1(CLK_SGM1_TX_EN, "sgm1_tx_en", "top_xtal", 2),
|
||||
GATE_SGMII1(CLK_SGM1_RX_EN, "sgm1_rx_en", "top_xtal", 3),
|
||||
};
|
||||
|
||||
static int clk_mt7988_sgmii1_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
void __iomem *base;
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("%s(): ioremap failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(sgmii1_clks));
|
||||
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_gates(node, sgmii1_clks, ARRAY_SIZE(sgmii1_clks),
|
||||
clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct mtk_gate_regs ethwarp_cg_regs = {
|
||||
.set_ofs = 0x14,
|
||||
.clr_ofs = 0x14,
|
||||
.sta_ofs = 0x14,
|
||||
};
|
||||
|
||||
#define GATE_ETHWARP(_id, _name, _parent, _shift) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = ðwarp_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate ethwarp_clks[] = {
|
||||
GATE_ETHWARP(CLK_ETHWARP_WOCPU2_EN, "ethwarp_wocpu2_en",
|
||||
"netsys_mcu_sel", 13),
|
||||
GATE_ETHWARP(CLK_ETHWARP_WOCPU1_EN, "ethwarp_wocpu1_en",
|
||||
"netsys_mcu_sel", 14),
|
||||
GATE_ETHWARP(CLK_ETHWARP_WOCPU0_EN, "ethwarp_wocpu0_en",
|
||||
"netsys_mcu_sel", 15),
|
||||
};
|
||||
|
||||
static int clk_mt7988_ethwarp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
void __iomem *base;
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("%s(): ioremap failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_data = mtk_alloc_clk_data(ARRAY_SIZE(ethwarp_clks));
|
||||
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_gates(node, ethwarp_clks, ARRAY_SIZE(ethwarp_clks),
|
||||
clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7988_ethsys[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt7988-ethsys",
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt7988_ethsys_drv = {
|
||||
.probe = clk_mt7988_ethsys_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7988-ethsys",
|
||||
.of_match_table = of_match_clk_mt7988_ethsys,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7988_ethsys_drv);
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7988_sgmii0[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt7988-sgmiisys_0",
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt7988_sgmii0_drv = {
|
||||
.probe = clk_mt7988_sgmii0_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7988-sgmiisys_0",
|
||||
.of_match_table = of_match_clk_mt7988_sgmii0,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7988_sgmii0_drv);
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7988_sgmii1[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt7988-sgmiisys_1",
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt7988_sgmii1_drv = {
|
||||
.probe = clk_mt7988_sgmii1_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7988-sgmiisys_1",
|
||||
.of_match_table = of_match_clk_mt7988_sgmii1,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7988_sgmii1_drv);
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7988_ethwarp[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt7988-ethwarp",
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt7988_ethwarp_drv = {
|
||||
.probe = clk_mt7988_ethwarp_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7988-ethwarp",
|
||||
.of_match_table = of_match_clk_mt7988_ethwarp,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7988_ethwarp_drv);
|
|
@ -0,0 +1,399 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2023 MediaTek Inc.
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
* Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mux.h"
|
||||
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
|
||||
|
||||
static DEFINE_SPINLOCK(mt7988_clk_lock);
|
||||
|
||||
static const char *const infra_mux_uart0_parents[] __initconst = {
|
||||
"csw_infra_f26m_sel", "uart_sel"
|
||||
};
|
||||
|
||||
static const char *const infra_mux_uart1_parents[] __initconst = {
|
||||
"csw_infra_f26m_sel", "uart_sel"
|
||||
};
|
||||
|
||||
static const char *const infra_mux_uart2_parents[] __initconst = {
|
||||
"csw_infra_f26m_sel", "uart_sel"
|
||||
};
|
||||
|
||||
static const char *const infra_mux_spi0_parents[] __initconst = { "i2c_sel",
|
||||
"spi_sel" };
|
||||
|
||||
static const char *const infra_mux_spi1_parents[] __initconst = {
|
||||
"i2c_sel", "spim_mst_sel"
|
||||
};
|
||||
|
||||
static const char *const infra_pwm_bck_parents[] __initconst = {
|
||||
"top_rtc_32p7k", "csw_infra_f26m_sel", "sysaxi_sel", "pwm_sel"
|
||||
};
|
||||
|
||||
static const char *const infra_pcie_gfmux_tl_ck_o_p0_parents[] __initconst = {
|
||||
"top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel",
|
||||
"pextp_tl_sel"
|
||||
};
|
||||
|
||||
static const char *const infra_pcie_gfmux_tl_ck_o_p1_parents[] __initconst = {
|
||||
"top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel",
|
||||
"pextp_tl_p1_sel"
|
||||
};
|
||||
|
||||
static const char *const infra_pcie_gfmux_tl_ck_o_p2_parents[] __initconst = {
|
||||
"top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel",
|
||||
"pextp_tl_p2_sel"
|
||||
};
|
||||
|
||||
static const char *const infra_pcie_gfmux_tl_ck_o_p3_parents[] __initconst = {
|
||||
"top_rtc_32p7k", "csw_infra_f26m_sel", "csw_infra_f26m_sel",
|
||||
"pextp_tl_p3_sel"
|
||||
};
|
||||
|
||||
static const struct mtk_mux infra_muxes[] = {
|
||||
/* MODULE_CLK_SEL_0 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART0_SEL, "infra_mux_uart0_sel",
|
||||
infra_mux_uart0_parents, 0x0018, 0x0010, 0x0014,
|
||||
0, 1, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART1_SEL, "infra_mux_uart1_sel",
|
||||
infra_mux_uart1_parents, 0x0018, 0x0010, 0x0014,
|
||||
1, 1, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_UART2_SEL, "infra_mux_uart2_sel",
|
||||
infra_mux_uart2_parents, 0x0018, 0x0010, 0x0014,
|
||||
2, 1, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI0_SEL, "infra_mux_spi0_sel",
|
||||
infra_mux_spi0_parents, 0x0018, 0x0010, 0x0014, 4,
|
||||
1, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI1_SEL, "infra_mux_spi1_sel",
|
||||
infra_mux_spi1_parents, 0x0018, 0x0010, 0x0014, 5,
|
||||
1, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_MUX_SPI2_SEL, "infra_mux_spi2_sel",
|
||||
infra_mux_spi0_parents, 0x0018, 0x0010, 0x0014, 6,
|
||||
1, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_SEL, "infra_pwm_sel",
|
||||
infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 14,
|
||||
2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK1_SEL, "infra_pwm_ck1_sel",
|
||||
infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 16,
|
||||
2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK2_SEL, "infra_pwm_ck2_sel",
|
||||
infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 18,
|
||||
2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK3_SEL, "infra_pwm_ck3_sel",
|
||||
infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 20,
|
||||
2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK4_SEL, "infra_pwm_ck4_sel",
|
||||
infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 22,
|
||||
2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK5_SEL, "infra_pwm_ck5_sel",
|
||||
infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 24,
|
||||
2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK6_SEL, "infra_pwm_ck6_sel",
|
||||
infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 26,
|
||||
2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK7_SEL, "infra_pwm_ck7_sel",
|
||||
infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 28,
|
||||
2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PWM_CK8_SEL, "infra_pwm_ck8_sel",
|
||||
infra_pwm_bck_parents, 0x0018, 0x0010, 0x0014, 30,
|
||||
2, -1, -1, -1),
|
||||
/* MODULE_CLK_SEL_1 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL,
|
||||
"infra_pcie_gfmux_tl_o_p0_sel",
|
||||
infra_pcie_gfmux_tl_ck_o_p0_parents, 0x0028,
|
||||
0x0020, 0x0024, 0, 2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL,
|
||||
"infra_pcie_gfmux_tl_o_p1_sel",
|
||||
infra_pcie_gfmux_tl_ck_o_p1_parents, 0x0028,
|
||||
0x0020, 0x0024, 2, 2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P2_SEL,
|
||||
"infra_pcie_gfmux_tl_o_p2_sel",
|
||||
infra_pcie_gfmux_tl_ck_o_p2_parents, 0x0028,
|
||||
0x0020, 0x0024, 4, 2, -1, -1, -1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_INFRA_PCIE_GFMUX_TL_O_P3_SEL,
|
||||
"infra_pcie_gfmux_tl_o_p3_sel",
|
||||
infra_pcie_gfmux_tl_ck_o_p3_parents, 0x0028,
|
||||
0x0020, 0x0024, 6, 2, -1, -1, -1),
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs infra0_cg_regs = {
|
||||
.set_ofs = 0x10,
|
||||
.clr_ofs = 0x14,
|
||||
.sta_ofs = 0x18,
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs infra1_cg_regs = {
|
||||
.set_ofs = 0x40,
|
||||
.clr_ofs = 0x44,
|
||||
.sta_ofs = 0x48,
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs infra2_cg_regs = {
|
||||
.set_ofs = 0x50,
|
||||
.clr_ofs = 0x54,
|
||||
.sta_ofs = 0x58,
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs infra3_cg_regs = {
|
||||
.set_ofs = 0x60,
|
||||
.clr_ofs = 0x64,
|
||||
.sta_ofs = 0x68,
|
||||
};
|
||||
|
||||
#define GATE_INFRA0_FLAGS(_id, _name, _parent, _shift, _flags) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = &infra0_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, .flags = _flags, \
|
||||
}
|
||||
|
||||
#define GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, _flags) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = &infra1_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, .flags = _flags, \
|
||||
}
|
||||
|
||||
#define GATE_INFRA2_FLAGS(_id, _name, _parent, _shift, _flags) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = &infra2_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, .flags = _flags, \
|
||||
}
|
||||
|
||||
#define GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, _flags) \
|
||||
{ \
|
||||
.id = _id, .name = _name, .parent_name = _parent, \
|
||||
.regs = &infra3_cg_regs, .shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, .flags = _flags, \
|
||||
}
|
||||
|
||||
#define GATE_INFRA0(_id, _name, _parent, _shift) \
|
||||
GATE_INFRA0_FLAGS(_id, _name, _parent, _shift, 0)
|
||||
|
||||
#define GATE_INFRA1(_id, _name, _parent, _shift) \
|
||||
GATE_INFRA1_FLAGS(_id, _name, _parent, _shift, 0)
|
||||
|
||||
#define GATE_INFRA2(_id, _name, _parent, _shift) \
|
||||
GATE_INFRA2_FLAGS(_id, _name, _parent, _shift, 0)
|
||||
|
||||
#define GATE_INFRA3(_id, _name, _parent, _shift) \
|
||||
GATE_INFRA3_FLAGS(_id, _name, _parent, _shift, 0)
|
||||
|
||||
static const struct mtk_gate infra_clks[] = {
|
||||
/* INFRA0 */
|
||||
GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P0,
|
||||
"infra_pcie_peri_ck_26m_ck_p0", "csw_infra_f26m_sel", 7),
|
||||
GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P1,
|
||||
"infra_pcie_peri_ck_26m_ck_p1", "csw_infra_f26m_sel", 8),
|
||||
GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P2,
|
||||
"infra_pcie_peri_ck_26m_ck_p2", "csw_infra_f26m_sel", 9),
|
||||
GATE_INFRA0(CLK_INFRA_PCIE_PERI_26M_CK_P3,
|
||||
"infra_pcie_peri_ck_26m_ck_p3", "csw_infra_f26m_sel", 10),
|
||||
/* INFRA1 */
|
||||
GATE_INFRA1(CLK_INFRA_66M_GPT_BCK, "infra_hf_66m_gpt_bck",
|
||||
"sysaxi_sel", 0),
|
||||
GATE_INFRA1(CLK_INFRA_66M_PWM_HCK, "infra_hf_66m_pwm_hck",
|
||||
"sysaxi_sel", 1),
|
||||
GATE_INFRA1(CLK_INFRA_66M_PWM_BCK, "infra_hf_66m_pwm_bck",
|
||||
"infra_pwm_sel", 2),
|
||||
GATE_INFRA1(CLK_INFRA_66M_PWM_CK1, "infra_hf_66m_pwm_ck1",
|
||||
"infra_pwm_ck1_sel", 3),
|
||||
GATE_INFRA1(CLK_INFRA_66M_PWM_CK2, "infra_hf_66m_pwm_ck2",
|
||||
"infra_pwm_ck2_sel", 4),
|
||||
GATE_INFRA1(CLK_INFRA_66M_PWM_CK3, "infra_hf_66m_pwm_ck3",
|
||||
"infra_pwm_ck3_sel", 5),
|
||||
GATE_INFRA1(CLK_INFRA_66M_PWM_CK4, "infra_hf_66m_pwm_ck4",
|
||||
"infra_pwm_ck4_sel", 6),
|
||||
GATE_INFRA1(CLK_INFRA_66M_PWM_CK5, "infra_hf_66m_pwm_ck5",
|
||||
"infra_pwm_ck5_sel", 7),
|
||||
GATE_INFRA1(CLK_INFRA_66M_PWM_CK6, "infra_hf_66m_pwm_ck6",
|
||||
"infra_pwm_ck6_sel", 8),
|
||||
GATE_INFRA1(CLK_INFRA_66M_PWM_CK7, "infra_hf_66m_pwm_ck7",
|
||||
"infra_pwm_ck7_sel", 9),
|
||||
GATE_INFRA1(CLK_INFRA_66M_PWM_CK8, "infra_hf_66m_pwm_ck8",
|
||||
"infra_pwm_ck8_sel", 10),
|
||||
GATE_INFRA1(CLK_INFRA_133M_CQDMA_BCK, "infra_hf_133m_cqdma_bck",
|
||||
"sysaxi_sel", 12),
|
||||
GATE_INFRA1(CLK_INFRA_66M_AUD_SLV_BCK, "infra_66m_aud_slv_bck",
|
||||
"sysaxi_sel", 13),
|
||||
GATE_INFRA1(CLK_INFRA_AUD_26M, "infra_f_faud_26m",
|
||||
"csw_infra_f26m_sel", 14),
|
||||
GATE_INFRA1(CLK_INFRA_AUD_L, "infra_f_faud_l", "aud_l_sel", 15),
|
||||
GATE_INFRA1(CLK_INFRA_AUD_AUD, "infra_f_aud_aud", "a1sys_sel", 16),
|
||||
GATE_INFRA1(CLK_INFRA_AUD_EG2, "infra_f_faud_eg2", "a_tuner_sel", 18),
|
||||
GATE_INFRA1_FLAGS(CLK_INFRA_DRAMC_F26M, "infra_dramc_f26m",
|
||||
"csw_infra_f26m_sel", 19, CLK_IS_CRITICAL),
|
||||
// JTAG
|
||||
GATE_INFRA1_FLAGS(CLK_INFRA_133M_DBG_ACKM, "infra_hf_133m_dbg_ackm",
|
||||
"sysaxi_sel", 20, CLK_IS_CRITICAL),
|
||||
GATE_INFRA1(CLK_INFRA_66M_AP_DMA_BCK, "infra_66m_ap_dma_bck",
|
||||
"sysaxi_sel", 21),
|
||||
GATE_INFRA1(CLK_INFRA_66M_SEJ_BCK, "infra_hf_66m_sej_bck",
|
||||
"sysaxi_sel", 29),
|
||||
GATE_INFRA1(CLK_INFRA_PRE_CK_SEJ_F13M, "infra_pre_ck_sej_f13m",
|
||||
"csw_infra_f26m_sel", 30),
|
||||
/* INFRA2 */
|
||||
GATE_INFRA2(CLK_INFRA_26M_THERM_SYSTEM, "infra_hf_26m_therm_system",
|
||||
"csw_infra_f26m_sel", 0),
|
||||
GATE_INFRA2(CLK_INFRA_I2C_BCK, "infra_i2c_bck", "i2c_sel", 1),
|
||||
GATE_INFRA2(CLK_INFRA_52M_UART0_CK, "infra_f_52m_uart0",
|
||||
"infra_mux_uart0_sel", 3),
|
||||
GATE_INFRA2(CLK_INFRA_52M_UART1_CK, "infra_f_52m_uart1",
|
||||
"infra_mux_uart1_sel", 4),
|
||||
GATE_INFRA2(CLK_INFRA_52M_UART2_CK, "infra_f_52m_uart2",
|
||||
"infra_mux_uart2_sel", 5),
|
||||
GATE_INFRA2(CLK_INFRA_NFI, "infra_f_fnfi", "nfi1x_sel", 9),
|
||||
GATE_INFRA2(CLK_INFRA_SPINFI, "infra_f_fspinfi", "spinfi_sel", 10),
|
||||
GATE_INFRA2_FLAGS(CLK_INFRA_66M_NFI_HCK, "infra_hf_66m_nfi_hck",
|
||||
"sysaxi_sel", 11, CLK_IS_CRITICAL),
|
||||
GATE_INFRA2_FLAGS(CLK_INFRA_104M_SPI0, "infra_hf_104m_spi0",
|
||||
"infra_mux_spi0_sel", 12, CLK_IS_CRITICAL),
|
||||
GATE_INFRA2(CLK_INFRA_104M_SPI1, "infra_hf_104m_spi1",
|
||||
"infra_mux_spi1_sel", 13),
|
||||
GATE_INFRA2(CLK_INFRA_104M_SPI2_BCK, "infra_hf_104m_spi2_bck",
|
||||
"infra_mux_spi2_sel", 14),
|
||||
GATE_INFRA2_FLAGS(CLK_INFRA_66M_SPI0_HCK, "infra_hf_66m_spi0_hck",
|
||||
"sysaxi_sel", 15, CLK_IS_CRITICAL),
|
||||
GATE_INFRA2(CLK_INFRA_66M_SPI1_HCK, "infra_hf_66m_spi1_hck",
|
||||
"sysaxi_sel", 16),
|
||||
GATE_INFRA2(CLK_INFRA_66M_SPI2_HCK, "infra_hf_66m_spi2_hck",
|
||||
"sysaxi_sel", 17),
|
||||
GATE_INFRA2(CLK_INFRA_66M_FLASHIF_AXI, "infra_hf_66m_flashif_axi",
|
||||
"sysaxi_sel", 18),
|
||||
GATE_INFRA2(CLK_INFRA_RTC, "infra_f_frtc", "top_rtc_32k", 19),
|
||||
GATE_INFRA2(CLK_INFRA_26M_ADC_BCK, "infra_f_26m_adc_bck",
|
||||
"csw_infra_f26m_sel", 20),
|
||||
GATE_INFRA2(CLK_INFRA_RC_ADC, "infra_f_frc_adc", "infra_f_26m_adc_bck",
|
||||
21),
|
||||
GATE_INFRA2(CLK_INFRA_MSDC400, "infra_f_fmsdc400", "emmc_400m_sel",
|
||||
22),
|
||||
GATE_INFRA2(CLK_INFRA_MSDC2_HCK, "infra_f_fmsdc2_hck", "emmc_250m_sel",
|
||||
23),
|
||||
GATE_INFRA2(CLK_INFRA_133M_MSDC_0_HCK, "infra_hf_133m_msdc_0_hck",
|
||||
"sysaxi_sel", 24),
|
||||
GATE_INFRA2(CLK_INFRA_66M_MSDC_0_HCK, "infra_66m_msdc_0_hck",
|
||||
"sysaxi_sel", 25),
|
||||
GATE_INFRA2(CLK_INFRA_133M_CPUM_BCK, "infra_hf_133m_cpum_bck",
|
||||
"sysaxi_sel", 26),
|
||||
GATE_INFRA2(CLK_INFRA_BIST2FPC, "infra_hf_fbist2fpc", "nfi1x_sel", 27),
|
||||
GATE_INFRA2(CLK_INFRA_I2C_X16W_MCK_CK_P1,
|
||||
"infra_hf_i2c_x16w_mck_ck_p1", "sysaxi_sel", 29),
|
||||
GATE_INFRA2(CLK_INFRA_I2C_X16W_PCK_CK_P1,
|
||||
"infra_hf_i2c_x16w_pck_ck_p1", "sysaxi_sel", 31),
|
||||
/* INFRA3 */
|
||||
GATE_INFRA3(CLK_INFRA_133M_USB_HCK, "infra_133m_usb_hck", "sysaxi_sel",
|
||||
0),
|
||||
GATE_INFRA3(CLK_INFRA_133M_USB_HCK_CK_P1, "infra_133m_usb_hck_ck_p1",
|
||||
"sysaxi_sel", 1),
|
||||
GATE_INFRA3(CLK_INFRA_66M_USB_HCK, "infra_66m_usb_hck", "sysaxi_sel",
|
||||
2),
|
||||
GATE_INFRA3(CLK_INFRA_66M_USB_HCK_CK_P1, "infra_66m_usb_hck_ck_p1",
|
||||
"sysaxi_sel", 3),
|
||||
GATE_INFRA3(CLK_INFRA_USB_SYS, "infra_usb_sys", "usb_sys_sel", 4),
|
||||
GATE_INFRA3(CLK_INFRA_USB_SYS_CK_P1, "infra_usb_sys_ck_p1",
|
||||
"usb_sys_p1_sel", 5),
|
||||
GATE_INFRA3(CLK_INFRA_USB_REF, "infra_usb_ref", "top_xtal", 6),
|
||||
GATE_INFRA3(CLK_INFRA_USB_CK_P1, "infra_usb_ck_p1", "top_xtal", 7),
|
||||
GATE_INFRA3_FLAGS(CLK_INFRA_USB_FRMCNT, "infra_usb_frmcnt",
|
||||
"usb_frmcnt_sel", 8, CLK_IS_CRITICAL),
|
||||
GATE_INFRA3_FLAGS(CLK_INFRA_USB_FRMCNT_CK_P1, "infra_usb_frmcnt_ck_p1",
|
||||
"usb_frmcnt_p1_sel", 9, CLK_IS_CRITICAL),
|
||||
GATE_INFRA3(CLK_INFRA_USB_PIPE, "infra_usb_pipe", "sspxtp_sel", 10),
|
||||
GATE_INFRA3(CLK_INFRA_USB_PIPE_CK_P1, "infra_usb_pipe_ck_p1",
|
||||
"usb_phy_sel", 11),
|
||||
GATE_INFRA3(CLK_INFRA_USB_UTMI, "infra_usb_utmi", "top_xtal", 12),
|
||||
GATE_INFRA3(CLK_INFRA_USB_UTMI_CK_P1, "infra_usb_utmi_ck_p1",
|
||||
"top_xtal", 13),
|
||||
GATE_INFRA3(CLK_INFRA_USB_XHCI, "infra_usb_xhci", "usb_xhci_sel", 14),
|
||||
GATE_INFRA3(CLK_INFRA_USB_XHCI_CK_P1, "infra_usb_xhci_ck_p1",
|
||||
"usb_xhci_p1_sel", 15),
|
||||
GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P0, "infra_pcie_gfmux_tl_ck_p0",
|
||||
"infra_pcie_gfmux_tl_o_p0_sel", 20),
|
||||
GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P1, "infra_pcie_gfmux_tl_ck_p1",
|
||||
"infra_pcie_gfmux_tl_o_p1_sel", 21),
|
||||
GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P2, "infra_pcie_gfmux_tl_ck_p2",
|
||||
"infra_pcie_gfmux_tl_o_p2_sel", 22),
|
||||
GATE_INFRA3(CLK_INFRA_PCIE_GFMUX_TL_P3, "infra_pcie_gfmux_tl_ck_p3",
|
||||
"infra_pcie_gfmux_tl_o_p3_sel", 23),
|
||||
GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P0, "infra_pcie_pipe_ck_p0",
|
||||
"top_xtal", 24),
|
||||
GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P1, "infra_pcie_pipe_ck_p1",
|
||||
"top_xtal", 25),
|
||||
GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P2, "infra_pcie_pipe_ck_p2",
|
||||
"top_xtal", 26),
|
||||
GATE_INFRA3(CLK_INFRA_PCIE_PIPE_P3, "infra_pcie_pipe_ck_p3",
|
||||
"top_xtal", 27),
|
||||
GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P0, "infra_133m_pcie_ck_p0",
|
||||
"sysaxi_sel", 28),
|
||||
GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P1, "infra_133m_pcie_ck_p1",
|
||||
"sysaxi_sel", 29),
|
||||
GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P2, "infra_133m_pcie_ck_p2",
|
||||
"sysaxi_sel", 30),
|
||||
GATE_INFRA3(CLK_INFRA_133M_PCIE_CK_P3, "infra_133m_pcie_ck_p3",
|
||||
"sysaxi_sel", 31),
|
||||
};
|
||||
|
||||
static int clk_mt7988_infracfg_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
void __iomem *base;
|
||||
int nr = ARRAY_SIZE(infra_muxes) + ARRAY_SIZE(infra_clks);
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("%s(): ioremap failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_data = mtk_alloc_clk_data(nr);
|
||||
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_muxes(infra_muxes, ARRAY_SIZE(infra_muxes), node,
|
||||
&mt7988_clk_lock, clk_data);
|
||||
|
||||
mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
|
||||
clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_infracfg_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_infracfg_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7988_infracfg[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt7988-infracfg",
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt7988_infracfg_drv = {
|
||||
.probe = clk_mt7988_infracfg_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7988-infracfg",
|
||||
.of_match_table = of_match_clk_mt7988_infracfg,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7988_infracfg_drv);
|
|
@ -0,0 +1,522 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2023 MediaTek Inc.
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
* Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
#include "clk-mux.h"
|
||||
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
|
||||
|
||||
static DEFINE_SPINLOCK(mt7988_clk_lock);
|
||||
|
||||
static const struct mtk_fixed_clk top_fixed_clks[] = {
|
||||
FIXED_CLK(CLK_TOP_XTAL, "top_xtal", "clkxtal", 40000000),
|
||||
};
|
||||
|
||||
static const struct mtk_fixed_factor top_divs[] = {
|
||||
FACTOR(CLK_TOP_XTAL_D2, "top_xtal_d2", "top_xtal", 1, 2),
|
||||
FACTOR(CLK_TOP_RTC_32K, "top_rtc_32k", "top_xtal", 1, 1250),
|
||||
FACTOR(CLK_TOP_RTC_32P7K, "top_rtc_32p7k", "top_xtal", 1, 1220),
|
||||
FACTOR(CLK_TOP_MPLL_D2, "mpll_d2", "mpll", 1, 2),
|
||||
FACTOR(CLK_TOP_MPLL_D3_D2, "mpll_d3_d2", "mpll", 1, 2),
|
||||
FACTOR(CLK_TOP_MPLL_D4, "mpll_d4", "mpll", 1, 4),
|
||||
FACTOR(CLK_TOP_MPLL_D8, "mpll_d8", "mpll", 1, 8),
|
||||
FACTOR(CLK_TOP_MPLL_D8_D2, "mpll_d8_d2", "mpll", 1, 16),
|
||||
FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2),
|
||||
FACTOR(CLK_TOP_MMPLL_D3_D5, "mmpll_d3_d5", "mmpll", 1, 15),
|
||||
FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll", 1, 4),
|
||||
FACTOR(CLK_TOP_MMPLL_D6_D2, "mmpll_d6_d2", "mmpll", 1, 12),
|
||||
FACTOR(CLK_TOP_MMPLL_D8, "mmpll_d8", "mmpll", 1, 8),
|
||||
FACTOR(CLK_TOP_APLL2_D4, "apll2_d4", "apll2", 1, 4),
|
||||
FACTOR(CLK_TOP_NET1PLL_D4, "net1pll_d4", "net1pll", 1, 4),
|
||||
FACTOR(CLK_TOP_NET1PLL_D5, "net1pll_d5", "net1pll", 1, 5),
|
||||
FACTOR(CLK_TOP_NET1PLL_D5_D2, "net1pll_d5_d2", "net1pll", 1, 10),
|
||||
FACTOR(CLK_TOP_NET1PLL_D5_D4, "net1pll_d5_d4", "net1pll", 1, 20),
|
||||
FACTOR(CLK_TOP_NET1PLL_D8, "net1pll_d8", "net1pll", 1, 8),
|
||||
FACTOR(CLK_TOP_NET1PLL_D8_D2, "net1pll_d8_d2", "net1pll", 1, 16),
|
||||
FACTOR(CLK_TOP_NET1PLL_D8_D4, "net1pll_d8_d4", "net1pll", 1, 32),
|
||||
FACTOR(CLK_TOP_NET1PLL_D8_D8, "net1pll_d8_d8", "net1pll", 1, 64),
|
||||
FACTOR(CLK_TOP_NET1PLL_D8_D16, "net1pll_d8_d16", "net1pll", 1, 128),
|
||||
FACTOR(CLK_TOP_NET2PLL_D2, "net2pll_d2", "net2pll", 1, 2),
|
||||
FACTOR(CLK_TOP_NET2PLL_D4, "net2pll_d4", "net2pll", 1, 4),
|
||||
FACTOR(CLK_TOP_NET2PLL_D4_D4, "net2pll_d4_d4", "net2pll", 1, 16),
|
||||
FACTOR(CLK_TOP_NET2PLL_D4_D8, "net2pll_d4_d8", "net2pll", 1, 32),
|
||||
FACTOR(CLK_TOP_NET2PLL_D6, "net2pll_d6", "net2pll", 1, 6),
|
||||
FACTOR(CLK_TOP_NET2PLL_D8, "net2pll_d8", "net2pll", 1, 8),
|
||||
};
|
||||
|
||||
static const char *const netsys_parents[] = { "top_xtal", "net2pll_d2",
|
||||
"mmpll_d2" };
|
||||
|
||||
static const char *const netsys_500m_parents[] = { "top_xtal", "net1pll_d5",
|
||||
"net1pll_d5_d2" };
|
||||
|
||||
static const char *const netsys_2x_parents[] = { "top_xtal", "net2pll",
|
||||
"mmpll" };
|
||||
|
||||
static const char *const netsys_gsw_parents[] = { "top_xtal", "net1pll_d4",
|
||||
"net1pll_d5" };
|
||||
|
||||
static const char *const eth_gmii_parents[] = { "top_xtal", "net1pll_d5_d4" };
|
||||
|
||||
static const char *const netsys_mcu_parents[] = { "top_xtal", "net2pll",
|
||||
"mmpll", "net1pll_d4",
|
||||
"net1pll_d5", "mpll" };
|
||||
|
||||
static const char *const eip197_parents[] = { "top_xtal", "netsyspll",
|
||||
"net2pll", "mmpll",
|
||||
"net1pll_d4", "net1pll_d5" };
|
||||
|
||||
static const char *const axi_infra_parents[] = { "top_xtal", "net1pll_d8_d2" };
|
||||
|
||||
static const char *const uart_parents[] = { "top_xtal", "mpll_d8",
|
||||
"mpll_d8_d2" };
|
||||
|
||||
static const char *const emmc_250m_parents[] = { "top_xtal", "net1pll_d5_d2",
|
||||
"mmpll_d4" };
|
||||
|
||||
static const char *const emmc_400m_parents[] = { "top_xtal", "msdcpll",
|
||||
"mmpll_d2", "mpll_d2",
|
||||
"mmpll_d4", "net1pll_d8_d2" };
|
||||
|
||||
static const char *const spi_parents[] = { "top_xtal", "mpll_d2",
|
||||
"mmpll_d4", "net1pll_d8_d2",
|
||||
"net2pll_d6", "net1pll_d5_d4",
|
||||
"mpll_d4", "net1pll_d8_d4" };
|
||||
|
||||
static const char *const nfi1x_parents[] = { "top_xtal", "mmpll_d4",
|
||||
"net1pll_d8_d2", "net2pll_d6",
|
||||
"mpll_d4", "mmpll_d8",
|
||||
"net1pll_d8_d4", "mpll_d8" };
|
||||
|
||||
static const char *const spinfi_parents[] = { "top_xtal_d2", "top_xtal",
|
||||
"net1pll_d5_d4", "mpll_d4",
|
||||
"mmpll_d8", "net1pll_d8_d4",
|
||||
"mmpll_d6_d2", "mpll_d8" };
|
||||
|
||||
static const char *const pwm_parents[] = { "top_xtal", "net1pll_d8_d2",
|
||||
"net1pll_d5_d4", "mpll_d4",
|
||||
"mpll_d8_d2", "top_rtc_32k" };
|
||||
|
||||
static const char *const i2c_parents[] = { "top_xtal", "net1pll_d5_d4",
|
||||
"mpll_d4", "net1pll_d8_d4" };
|
||||
|
||||
static const char *const pcie_mbist_250m_parents[] = { "top_xtal",
|
||||
"net1pll_d5_d2" };
|
||||
|
||||
static const char *const pextp_tl_ck_parents[] = { "top_xtal", "net2pll_d6",
|
||||
"mmpll_d8", "mpll_d8_d2",
|
||||
"top_rtc_32k" };
|
||||
|
||||
static const char *const usb_frmcnt_parents[] = { "top_xtal", "mmpll_d3_d5" };
|
||||
|
||||
static const char *const aud_parents[] = { "top_xtal", "apll2" };
|
||||
|
||||
static const char *const a1sys_parents[] = { "top_xtal", "apll2_d4" };
|
||||
|
||||
static const char *const aud_l_parents[] = { "top_xtal", "apll2",
|
||||
"mpll_d8_d2" };
|
||||
|
||||
static const char *const sspxtp_parents[] = { "top_xtal_d2", "mpll_d8_d2" };
|
||||
|
||||
static const char *const usxgmii_sbus_0_parents[] = { "top_xtal",
|
||||
"net1pll_d8_d4" };
|
||||
|
||||
static const char *const sgm_0_parents[] = { "top_xtal", "sgmpll" };
|
||||
|
||||
static const char *const sysapb_parents[] = { "top_xtal", "mpll_d3_d2" };
|
||||
|
||||
static const char *const eth_refck_50m_parents[] = { "top_xtal",
|
||||
"net2pll_d4_d4" };
|
||||
|
||||
static const char *const eth_sys_200m_parents[] = { "top_xtal", "net2pll_d4" };
|
||||
|
||||
static const char *const eth_xgmii_parents[] = { "top_xtal_d2",
|
||||
"net1pll_d8_d8",
|
||||
"net1pll_d8_d16" };
|
||||
|
||||
static const char *const bus_tops_parents[] = { "top_xtal", "net1pll_d5",
|
||||
"net2pll_d2" };
|
||||
|
||||
static const char *const npu_tops_parents[] = { "top_xtal", "net2pll" };
|
||||
|
||||
static const char *const dramc_md32_parents[] = { "top_xtal", "mpll_d2",
|
||||
"wedmcupll" };
|
||||
|
||||
static const char *const da_xtp_glb_p0_parents[] = { "top_xtal",
|
||||
"net2pll_d8" };
|
||||
|
||||
static const char *const mcusys_backup_625m_parents[] = { "top_xtal",
|
||||
"net1pll_d4" };
|
||||
|
||||
static const char *const macsec_parents[] = { "top_xtal", "sgmpll",
|
||||
"net1pll_d8" };
|
||||
|
||||
static const char *const netsys_tops_400m_parents[] = { "top_xtal",
|
||||
"net2pll_d2" };
|
||||
|
||||
static const char *const eth_mii_parents[] = { "top_xtal_d2",
|
||||
"net2pll_d4_d8" };
|
||||
|
||||
static const struct mtk_mux top_muxes[] = {
|
||||
/* CLK_CFG_0 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SEL, "netsys_sel", netsys_parents,
|
||||
0x000, 0x004, 0x008, 0, 2, 7, 0x1c0, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_500M_SEL, "netsys_500m_sel",
|
||||
netsys_500m_parents, 0x000, 0x004, 0x008, 8, 2,
|
||||
15, 0x1C0, 1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_2X_SEL, "netsys_2x_sel",
|
||||
netsys_2x_parents, 0x000, 0x004, 0x008, 16, 2, 23,
|
||||
0x1C0, 2),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_GSW_SEL, "netsys_gsw_sel",
|
||||
netsys_gsw_parents, 0x000, 0x004, 0x008, 24, 2,
|
||||
31, 0x1C0, 3),
|
||||
/* CLK_CFG_1 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_GMII_SEL, "eth_gmii_sel",
|
||||
eth_gmii_parents, 0x010, 0x014, 0x018, 0, 1, 7,
|
||||
0x1C0, 4),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_MCU_SEL, "netsys_mcu_sel",
|
||||
netsys_mcu_parents, 0x010, 0x014, 0x018, 8, 3, 15,
|
||||
0x1C0, 5),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_PAO_2X_SEL, "netsys_pao_2x_sel",
|
||||
netsys_mcu_parents, 0x010, 0x014, 0x018, 16, 3,
|
||||
23, 0x1C0, 6),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_EIP197_SEL, "eip197_sel", eip197_parents,
|
||||
0x010, 0x014, 0x018, 24, 3, 31, 0x1c0, 7),
|
||||
/* CLK_CFG_2 */
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_AXI_INFRA_SEL, "axi_infra_sel",
|
||||
axi_infra_parents, 0x020, 0x024, 0x028, 0,
|
||||
1, 7, 0x1C0, 8, CLK_IS_CRITICAL),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x020,
|
||||
0x024, 0x028, 8, 2, 15, 0x1c0, 9),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_250M_SEL, "emmc_250m_sel",
|
||||
emmc_250m_parents, 0x020, 0x024, 0x028, 16, 2, 23,
|
||||
0x1C0, 10),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_EMMC_400M_SEL, "emmc_400m_sel",
|
||||
emmc_400m_parents, 0x020, 0x024, 0x028, 24, 3, 31,
|
||||
0x1C0, 11),
|
||||
/* CLK_CFG_3 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x030,
|
||||
0x034, 0x038, 0, 3, 7, 0x1c0, 12),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPIM_MST_SEL, "spim_mst_sel", spi_parents,
|
||||
0x030, 0x034, 0x038, 8, 3, 15, 0x1c0, 13),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NFI1X_SEL, "nfi1x_sel", nfi1x_parents,
|
||||
0x030, 0x034, 0x038, 16, 3, 23, 0x1c0, 14),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SPINFI_SEL, "spinfi_sel", spinfi_parents,
|
||||
0x030, 0x034, 0x038, 24, 3, 31, 0x1c0, 15),
|
||||
/* CLK_CFG_4 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x040,
|
||||
0x044, 0x048, 0, 3, 7, 0x1c0, 16),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_I2C_SEL, "i2c_sel", i2c_parents, 0x040,
|
||||
0x044, 0x048, 8, 2, 15, 0x1c0, 17),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PCIE_MBIST_250M_SEL,
|
||||
"pcie_mbist_250m_sel", pcie_mbist_250m_parents,
|
||||
0x040, 0x044, 0x048, 16, 1, 23, 0x1C0, 18),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_SEL, "pextp_tl_sel",
|
||||
pextp_tl_ck_parents, 0x040, 0x044, 0x048, 24, 3,
|
||||
31, 0x1C0, 19),
|
||||
/* CLK_CFG_5 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_P1_SEL, "pextp_tl_p1_sel",
|
||||
pextp_tl_ck_parents, 0x050, 0x054, 0x058, 0, 3, 7,
|
||||
0x1C0, 20),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_P2_SEL, "pextp_tl_p2_sel",
|
||||
pextp_tl_ck_parents, 0x050, 0x054, 0x058, 8, 3,
|
||||
15, 0x1C0, 21),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_TL_P3_SEL, "pextp_tl_p3_sel",
|
||||
pextp_tl_ck_parents, 0x050, 0x054, 0x058, 16, 3,
|
||||
23, 0x1C0, 22),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_SYS_SEL, "usb_sys_sel",
|
||||
eth_gmii_parents, 0x050, 0x054, 0x058, 24, 1, 31,
|
||||
0x1C0, 23),
|
||||
/* CLK_CFG_6 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_SYS_P1_SEL, "usb_sys_p1_sel",
|
||||
eth_gmii_parents, 0x060, 0x064, 0x068, 0, 1, 7,
|
||||
0x1C0, 24),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_XHCI_SEL, "usb_xhci_sel",
|
||||
eth_gmii_parents, 0x060, 0x064, 0x068, 8, 1, 15,
|
||||
0x1C0, 25),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_XHCI_P1_SEL, "usb_xhci_p1_sel",
|
||||
eth_gmii_parents, 0x060, 0x064, 0x068, 16, 1, 23,
|
||||
0x1C0, 26),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_FRMCNT_SEL, "usb_frmcnt_sel",
|
||||
usb_frmcnt_parents, 0x060, 0x064, 0x068, 24, 1,
|
||||
31, 0x1C0, 27),
|
||||
/* CLK_CFG_7 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_FRMCNT_P1_SEL, "usb_frmcnt_p1_sel",
|
||||
usb_frmcnt_parents, 0x070, 0x074, 0x078, 0, 1, 7,
|
||||
0x1C0, 28),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_SEL, "aud_sel", aud_parents, 0x070,
|
||||
0x074, 0x078, 8, 1, 15, 0x1c0, 29),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_A1SYS_SEL, "a1sys_sel", a1sys_parents,
|
||||
0x070, 0x074, 0x078, 16, 1, 23, 0x1c0, 30),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_AUD_L_SEL, "aud_l_sel", aud_l_parents,
|
||||
0x070, 0x074, 0x078, 24, 2, 31, 0x1c4, 0),
|
||||
/* CLK_CFG_8 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_A_TUNER_SEL, "a_tuner_sel", a1sys_parents,
|
||||
0x080, 0x084, 0x088, 0, 1, 7, 0x1c4, 1),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SSPXTP_SEL, "sspxtp_sel", sspxtp_parents,
|
||||
0x080, 0x084, 0x088, 8, 1, 15, 0x1c4, 2),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USB_PHY_SEL, "usb_phy_sel",
|
||||
sspxtp_parents, 0x080, 0x084, 0x088, 16, 1, 23,
|
||||
0x1c4, 3),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USXGMII_SBUS_0_SEL, "usxgmii_sbus_0_sel",
|
||||
usxgmii_sbus_0_parents, 0x080, 0x084, 0x088, 24,
|
||||
1, 31, 0x1C4, 4),
|
||||
/* CLK_CFG_9 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_USXGMII_SBUS_1_SEL, "usxgmii_sbus_1_sel",
|
||||
usxgmii_sbus_0_parents, 0x090, 0x094, 0x098, 0, 1,
|
||||
7, 0x1C4, 5),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_0_SEL, "sgm_0_sel", sgm_0_parents,
|
||||
0x090, 0x094, 0x098, 8, 1, 15, 0x1c4, 6),
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_SBUS_0_SEL, "sgm_sbus_0_sel",
|
||||
usxgmii_sbus_0_parents, 0x090, 0x094, 0x098,
|
||||
16, 1, 23, 0x1C4, 7, CLK_IS_CRITICAL),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_SGM_1_SEL, "sgm_1_sel", sgm_0_parents,
|
||||
0x090, 0x094, 0x098, 24, 1, 31, 0x1c4, 8),
|
||||
/* CLK_CFG_10 */
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SGM_SBUS_1_SEL, "sgm_sbus_1_sel",
|
||||
usxgmii_sbus_0_parents, 0x0a0, 0x0a4, 0x0a8,
|
||||
0, 1, 7, 0x1C4, 9, CLK_IS_CRITICAL),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_XFI_PHY_0_XTAL_SEL, "xfi_phy_0_xtal_sel",
|
||||
sspxtp_parents, 0x0a0, 0x0a4, 0x0a8, 8, 1, 15,
|
||||
0x1C4, 10),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_XFI_PHY_1_XTAL_SEL, "xfi_phy_1_xtal_sel",
|
||||
sspxtp_parents, 0x0a0, 0x0a4, 0x0a8, 16, 1, 23,
|
||||
0x1C4, 11),
|
||||
/* CLK_CFG_11 */
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAXI_SEL, "sysaxi_sel",
|
||||
axi_infra_parents, 0x0a0, 0x0a4, 0x0a8, 24,
|
||||
1, 31, 0x1C4, 12, CLK_IS_CRITICAL),
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_SYSAPB_SEL, "sysapb_sel",
|
||||
sysapb_parents, 0x0b0, 0x0b4, 0x0b8, 0, 1,
|
||||
7, 0x1c4, 13, CLK_IS_CRITICAL),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_REFCK_50M_SEL, "eth_refck_50m_sel",
|
||||
eth_refck_50m_parents, 0x0b0, 0x0b4, 0x0b8, 8, 1,
|
||||
15, 0x1C4, 14),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_SYS_200M_SEL, "eth_sys_200m_sel",
|
||||
eth_sys_200m_parents, 0x0b0, 0x0b4, 0x0b8, 16, 1,
|
||||
23, 0x1C4, 15),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_SYS_SEL, "eth_sys_sel",
|
||||
pcie_mbist_250m_parents, 0x0b0, 0x0b4, 0x0b8, 24,
|
||||
1, 31, 0x1C4, 16),
|
||||
/* CLK_CFG_12 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_XGMII_SEL, "eth_xgmii_sel",
|
||||
eth_xgmii_parents, 0x0c0, 0x0c4, 0x0c8, 0, 2, 7,
|
||||
0x1C4, 17),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_BUS_TOPS_SEL, "bus_tops_sel",
|
||||
bus_tops_parents, 0x0c0, 0x0c4, 0x0c8, 8, 2, 15,
|
||||
0x1C4, 18),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NPU_TOPS_SEL, "npu_tops_sel",
|
||||
npu_tops_parents, 0x0c0, 0x0c4, 0x0c8, 16, 1, 23,
|
||||
0x1C4, 19),
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_SEL, "dramc_sel",
|
||||
sspxtp_parents, 0x0c0, 0x0c4, 0x0c8, 24, 1,
|
||||
31, 0x1C4, 20, CLK_IS_CRITICAL),
|
||||
/* CLK_CFG_13 */
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_DRAMC_MD32_SEL, "dramc_md32_sel",
|
||||
dramc_md32_parents, 0x0d0, 0x0d4, 0x0d8, 0,
|
||||
2, 7, 0x1C4, 21, CLK_IS_CRITICAL),
|
||||
MUX_GATE_CLR_SET_UPD_FLAGS(
|
||||
CLK_TOP_INFRA_F26M_SEL, "csw_infra_f26m_sel", sspxtp_parents,
|
||||
0x0d0, 0x0d4, 0x0d8, 8, 1, 15, 0x1C4, 22, CLK_IS_CRITICAL),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P0_SEL, "pextp_p0_sel",
|
||||
sspxtp_parents, 0x0d0, 0x0d4, 0x0d8, 16, 1, 23,
|
||||
0x1C4, 23),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P1_SEL, "pextp_p1_sel",
|
||||
sspxtp_parents, 0x0d0, 0x0d4, 0x0d8, 24, 1, 31,
|
||||
0x1C4, 24),
|
||||
/* CLK_CFG_14 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P2_SEL, "pextp_p2_sel",
|
||||
sspxtp_parents, 0x0e0, 0x0e4, 0x0e8, 0, 1, 7,
|
||||
0x1C4, 25),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_P3_SEL, "pextp_p3_sel",
|
||||
sspxtp_parents, 0x0e0, 0x0e4, 0x0e8, 8, 1, 15,
|
||||
0x1C4, 26),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P0_SEL, "da_xtp_glb_p0_sel",
|
||||
da_xtp_glb_p0_parents, 0x0e0, 0x0e4, 0x0e8, 16, 1,
|
||||
23, 0x1C4, 27),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P1_SEL, "da_xtp_glb_p1_sel",
|
||||
da_xtp_glb_p0_parents, 0x0e0, 0x0e4, 0x0e8, 24, 1,
|
||||
31, 0x1C4, 28),
|
||||
/* CLK_CFG_15 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P2_SEL, "da_xtp_glb_p2_sel",
|
||||
da_xtp_glb_p0_parents, 0x0f0, 0x0f4, 0x0f8, 0, 1,
|
||||
7, 0x1C4, 29),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_XTP_GLB_P3_SEL, "da_xtp_glb_p3_sel",
|
||||
da_xtp_glb_p0_parents, 0x0f0, 0x0f4, 0x0f8, 8, 1,
|
||||
15, 0x1C4, 30),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_CKM_SEL, "ckm_sel", sspxtp_parents, 0x0F0,
|
||||
0x0f4, 0x0f8, 16, 1, 23, 0x1c8, 0),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_DA_SEL, "da_sel", sspxtp_parents, 0x0f0,
|
||||
0x0f4, 0x0f8, 24, 1, 31, 0x1C8, 1),
|
||||
/* CLK_CFG_16 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_PEXTP_SEL, "pextp_sel", sspxtp_parents,
|
||||
0x0100, 0x104, 0x108, 0, 1, 7, 0x1c8, 2),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_TOPS_P2_26M_SEL, "tops_p2_26m_sel",
|
||||
sspxtp_parents, 0x0100, 0x104, 0x108, 8, 1, 15,
|
||||
0x1C8, 3),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_MCUSYS_BACKUP_625M_SEL,
|
||||
"mcusys_backup_625m_sel",
|
||||
mcusys_backup_625m_parents, 0x0100, 0x104, 0x108,
|
||||
16, 1, 23, 0x1C8, 4),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_SYNC_250M_SEL,
|
||||
"netsys_sync_250m_sel", pcie_mbist_250m_parents,
|
||||
0x0100, 0x104, 0x108, 24, 1, 31, 0x1c8, 5),
|
||||
/* CLK_CFG_17 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_MACSEC_SEL, "macsec_sel", macsec_parents,
|
||||
0x0110, 0x114, 0x118, 0, 2, 7, 0x1c8, 6),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_TOPS_400M_SEL,
|
||||
"netsys_tops_400m_sel", netsys_tops_400m_parents,
|
||||
0x0110, 0x114, 0x118, 8, 1, 15, 0x1c8, 7),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_PPEFB_250M_SEL,
|
||||
"netsys_ppefb_250m_sel", pcie_mbist_250m_parents,
|
||||
0x0110, 0x114, 0x118, 16, 1, 23, 0x1c8, 8),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NETSYS_WARP_SEL, "netsys_warp_sel",
|
||||
netsys_parents, 0x0110, 0x114, 0x118, 24, 2, 31,
|
||||
0x1C8, 9),
|
||||
/* CLK_CFG_18 */
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_ETH_MII_SEL, "eth_mii_sel",
|
||||
eth_mii_parents, 0x0120, 0x124, 0x128, 0, 1, 7,
|
||||
0x1c8, 10),
|
||||
MUX_GATE_CLR_SET_UPD(CLK_TOP_NPU_SEL, "ck_npu_sel", netsys_2x_parents,
|
||||
0x0120, 0x124, 0x128, 8, 2, 15, 0x1c8, 11),
|
||||
};
|
||||
|
||||
static const struct mtk_composite top_aud_divs[] = {
|
||||
DIV_GATE(CLK_TOP_AUD_I2S_M, "aud_i2s_m", "aud_sel", 0x0420, 0, 0x0420,
|
||||
8, 8),
|
||||
};
|
||||
|
||||
static int clk_mt7988_topckgen_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
void __iomem *base;
|
||||
int nr = ARRAY_SIZE(top_fixed_clks) + ARRAY_SIZE(top_divs) +
|
||||
ARRAY_SIZE(top_muxes) + ARRAY_SIZE(top_aud_divs);
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("%s(): ioremap failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_data = mtk_alloc_clk_data(nr);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
|
||||
clk_data);
|
||||
|
||||
mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
|
||||
|
||||
mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
|
||||
&mt7988_clk_lock, clk_data);
|
||||
|
||||
mtk_clk_register_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs),
|
||||
base, &mt7988_clk_lock, clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_topckgen_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_topckgen_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const char *const mcu_bus_div_parents[] = { "top_xtal", "ccipll2_b",
|
||||
"net1pll_d4" };
|
||||
|
||||
static const char *const mcu_arm_div_parents[] = { "top_xtal", "arm_b",
|
||||
"net1pll_d4" };
|
||||
|
||||
static struct mtk_composite mcu_muxes[] = {
|
||||
/* bus_pll_divider_cfg */
|
||||
MUX_GATE_FLAGS(CLK_MCU_BUS_DIV_SEL, "mcu_bus_div_sel",
|
||||
mcu_bus_div_parents, 0x7C0, 9, 2, -1, CLK_IS_CRITICAL),
|
||||
/* mp2_pll_divider_cfg */
|
||||
MUX_GATE_FLAGS(CLK_MCU_ARM_DIV_SEL, "mcu_arm_div_sel",
|
||||
mcu_arm_div_parents, 0x7A8, 9, 2, -1, CLK_IS_CRITICAL),
|
||||
};
|
||||
|
||||
static int clk_mt7988_mcusys_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
int r;
|
||||
void __iomem *base;
|
||||
int nr = ARRAY_SIZE(mcu_muxes);
|
||||
|
||||
base = of_iomap(node, 0);
|
||||
if (!base) {
|
||||
pr_err("%s(): ioremap failed\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
clk_data = mtk_alloc_clk_data(nr);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
|
||||
&mt7988_clk_lock, clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
|
||||
if (r) {
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
goto free_mcusys_data;
|
||||
}
|
||||
return r;
|
||||
|
||||
free_mcusys_data:
|
||||
mtk_free_clk_data(clk_data);
|
||||
return r;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7988_topckgen[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt7988-topckgen",
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt7988_topckgen_drv = {
|
||||
.probe = clk_mt7988_topckgen_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7988-topckgen",
|
||||
.of_match_table = of_match_clk_mt7988_topckgen,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7988_topckgen_drv);
|
||||
|
||||
static const struct of_device_id of_match_clk_mt7988_mcusys[] = {
|
||||
{
|
||||
.compatible = "mediatek,mt7988-mcusys",
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver clk_mt7988_mcusys_drv = {
|
||||
.probe = clk_mt7988_mcusys_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt7988-mcusys",
|
||||
.of_match_table = of_match_clk_mt7988_mcusys,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver(clk_mt7988_mcusys_drv);
|
|
@ -0,0 +1,262 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/nvmem-consumer.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#define MEDAITEK_2P5GE_PHY_DMB_FW "mediatek/mediatek-2p5ge-phy-dmb.bin"
|
||||
#define MEDIATEK_2P5GE_PHY_PMB_FW "mediatek/mediatek-2p5ge-phy-pmb.bin"
|
||||
|
||||
#define MD32_EN_CFG 0x18
|
||||
#define MD32_EN BIT(0)
|
||||
|
||||
#define BASE100T_STATUS_EXTEND 0x10
|
||||
#define BASE1000T_STATUS_EXTEND 0x11
|
||||
#define EXTEND_CTRL_AND_STATUS 0x16
|
||||
|
||||
#define PHY_AUX_CTRL_STATUS 0x1d
|
||||
#define PHY_AUX_DPX_MASK GENMASK(5, 5)
|
||||
#define PHY_AUX_SPEED_MASK GENMASK(4, 2)
|
||||
|
||||
/* Registers on MDIO_MMD_VEND1 */
|
||||
#define MTK_PHY_LINK_STATUS_MISC 0xa2
|
||||
#define MTK_PHY_FDX_ENABLE BIT(5)
|
||||
|
||||
/* Registers on MDIO_MMD_VEND2 */
|
||||
#define MTK_PHY_LED0_ON_CTRL 0x24
|
||||
#define MTK_PHY_LED0_ON_LINK1000 BIT(0)
|
||||
#define MTK_PHY_LED0_ON_LINK100 BIT(1)
|
||||
#define MTK_PHY_LED0_ON_LINK10 BIT(2)
|
||||
#define MTK_PHY_LED0_ON_LINK2500 BIT(7)
|
||||
#define MTK_PHY_LED0_POLARITY BIT(14)
|
||||
|
||||
#define MTK_PHY_LED1_ON_CTRL 0x26
|
||||
#define MTK_PHY_LED1_ON_FDX BIT(4)
|
||||
#define MTK_PHY_LED1_ON_HDX BIT(5)
|
||||
#define MTK_PHY_LED1_POLARITY BIT(14)
|
||||
|
||||
enum {
|
||||
PHY_AUX_SPD_10 = 0,
|
||||
PHY_AUX_SPD_100,
|
||||
PHY_AUX_SPD_1000,
|
||||
PHY_AUX_SPD_2500,
|
||||
};
|
||||
|
||||
static int mt798x_2p5ge_phy_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
const struct firmware *fw;
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
struct device_node *np;
|
||||
void __iomem *dmb_addr;
|
||||
void __iomem *pmb_addr;
|
||||
void __iomem *mcucsr_base;
|
||||
u16 reg;
|
||||
struct pinctrl *pinctrl;
|
||||
|
||||
np = of_find_compatible_node(NULL, NULL, "mediatek,2p5gphy-fw");
|
||||
if (!np)
|
||||
return -ENOENT;
|
||||
|
||||
dmb_addr = of_iomap(np, 0);
|
||||
if (!dmb_addr)
|
||||
return -ENOMEM;
|
||||
pmb_addr = of_iomap(np, 1);
|
||||
if (!pmb_addr)
|
||||
return -ENOMEM;
|
||||
mcucsr_base = of_iomap(np, 2);
|
||||
if (!mcucsr_base)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = request_firmware(&fw, MEDAITEK_2P5GE_PHY_DMB_FW, dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to load firmware: %s, ret: %d\n",
|
||||
MEDAITEK_2P5GE_PHY_DMB_FW, ret);
|
||||
return ret;
|
||||
}
|
||||
for (i = 0; i < fw->size - 1; i += 4)
|
||||
writel(*((uint32_t *)(fw->data + i)), dmb_addr + i);
|
||||
release_firmware(fw);
|
||||
|
||||
ret = request_firmware(&fw, MEDIATEK_2P5GE_PHY_PMB_FW, dev);
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to load firmware: %s, ret: %d\n",
|
||||
MEDIATEK_2P5GE_PHY_PMB_FW, ret);
|
||||
return ret;
|
||||
}
|
||||
for (i = 0; i < fw->size - 1; i += 4)
|
||||
writel(*((uint32_t *)(fw->data + i)), pmb_addr + i);
|
||||
release_firmware(fw);
|
||||
|
||||
reg = readw(mcucsr_base + MD32_EN_CFG);
|
||||
writew(reg | MD32_EN, mcucsr_base + MD32_EN_CFG);
|
||||
dev_dbg(dev, "Firmware loading/trigger ok.\n");
|
||||
|
||||
/* Setup LED */
|
||||
phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
|
||||
MTK_PHY_LED0_POLARITY);
|
||||
|
||||
phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED0_ON_CTRL,
|
||||
MTK_PHY_LED0_ON_LINK10 |
|
||||
MTK_PHY_LED0_ON_LINK100 |
|
||||
MTK_PHY_LED0_ON_LINK1000 |
|
||||
MTK_PHY_LED0_ON_LINK2500);
|
||||
|
||||
phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MTK_PHY_LED1_ON_CTRL,
|
||||
MTK_PHY_LED1_ON_FDX | MTK_PHY_LED1_ON_HDX);
|
||||
|
||||
pinctrl = devm_pinctrl_get_select(&phydev->mdio.dev, "i2p5gbe-led");
|
||||
if (IS_ERR(pinctrl)) {
|
||||
dev_err(&phydev->mdio.dev, "Fail to set LED pins!\n");
|
||||
return PTR_ERR(pinctrl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt798x_2p5ge_phy_config_aneg(struct phy_device *phydev)
|
||||
{
|
||||
bool changed = false;
|
||||
u32 adv;
|
||||
int ret;
|
||||
|
||||
if (phydev->autoneg == AUTONEG_DISABLE) {
|
||||
/* Configure half duplex with genphy_setup_forced,
|
||||
* because genphy_c45_pma_setup_forced does not support.
|
||||
*/
|
||||
return phydev->duplex != DUPLEX_FULL
|
||||
? genphy_setup_forced(phydev)
|
||||
: genphy_c45_pma_setup_forced(phydev);
|
||||
}
|
||||
|
||||
ret = genphy_c45_an_config_aneg(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret > 0)
|
||||
changed = true;
|
||||
|
||||
adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
|
||||
ret = phy_modify_changed(phydev, MII_CTRL1000,
|
||||
ADVERTISE_1000FULL | ADVERTISE_1000HALF,
|
||||
adv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (ret > 0)
|
||||
changed = true;
|
||||
|
||||
return genphy_c45_check_and_restart_aneg(phydev, changed);
|
||||
}
|
||||
|
||||
static int mt798x_2p5ge_phy_get_features(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = genphy_read_abilities(phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* We don't support HDX at MAC layer on mt798x.
|
||||
* So mask phy's HDX capabilities, too.
|
||||
*/
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
|
||||
phydev->supported);
|
||||
linkmode_set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt798x_2p5ge_phy_read_status(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = genphy_update_link(phydev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
phydev->speed = SPEED_UNKNOWN;
|
||||
phydev->duplex = DUPLEX_UNKNOWN;
|
||||
phydev->pause = 0;
|
||||
phydev->asym_pause = 0;
|
||||
|
||||
if (!phydev->link)
|
||||
return 0;
|
||||
|
||||
if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
|
||||
ret = genphy_c45_read_lpa(phydev);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Read the link partner's 1G advertisement */
|
||||
ret = phy_read(phydev, MII_STAT1000);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret);
|
||||
} else if (phydev->autoneg == AUTONEG_DISABLE) {
|
||||
linkmode_zero(phydev->lp_advertising);
|
||||
}
|
||||
|
||||
ret = phy_read(phydev, PHY_AUX_CTRL_STATUS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
switch (FIELD_GET(PHY_AUX_SPEED_MASK, ret)) {
|
||||
case PHY_AUX_SPD_10:
|
||||
phydev->speed = SPEED_10;
|
||||
break;
|
||||
case PHY_AUX_SPD_100:
|
||||
phydev->speed = SPEED_100;
|
||||
break;
|
||||
case PHY_AUX_SPD_1000:
|
||||
phydev->speed = SPEED_1000;
|
||||
break;
|
||||
case PHY_AUX_SPD_2500:
|
||||
phydev->speed = SPEED_2500;
|
||||
phydev->duplex = DUPLEX_FULL; /* 2.5G must be FDX */
|
||||
break;
|
||||
}
|
||||
|
||||
ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, MTK_PHY_LINK_STATUS_MISC);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
phydev->duplex = (ret & MTK_PHY_FDX_ENABLE) ? DUPLEX_FULL : DUPLEX_HALF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct phy_driver mtk_gephy_driver[] = {
|
||||
{
|
||||
PHY_ID_MATCH_EXACT(0x00339c11),
|
||||
.name = "MediaTek MT798x 2.5GbE PHY",
|
||||
.config_init = mt798x_2p5ge_phy_config_init,
|
||||
.config_aneg = mt798x_2p5ge_phy_config_aneg,
|
||||
.get_features = mt798x_2p5ge_phy_get_features,
|
||||
.read_status = mt798x_2p5ge_phy_read_status,
|
||||
},
|
||||
};
|
||||
|
||||
module_phy_driver(mtk_gephy_driver);
|
||||
|
||||
static struct mdio_device_id __maybe_unused mtk_2p5ge_phy_tbl[] = {
|
||||
{ PHY_ID_MATCH_VENDOR(0x00339c00) },
|
||||
{ }
|
||||
};
|
||||
|
||||
MODULE_DESCRIPTION("MediaTek 2.5Gb Ethernet PHY driver");
|
||||
MODULE_AUTHOR("SkyLake Huang <SkyLake.Huang@mediatek.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
MODULE_DEVICE_TABLE(mdio, mtk_2p5ge_phy_tbl);
|
||||
MODULE_FIRMWARE(MEDAITEK_2P5GE_PHY_DMB_FW);
|
||||
MODULE_FIRMWARE(MEDIATEK_2P5GE_PHY_PMB_FW);
|
1263
target/linux/mediatek/files-5.15/drivers/net/phy/mediatek-ge-soc.c
Normal file
1263
target/linux/mediatek/files-5.15/drivers/net/phy/mediatek-ge-soc.c
Normal file
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,276 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Copyright (c) 2023 MediaTek Inc.
|
||||
* Author: Sam Shih <sam.shih@mediatek.com>
|
||||
* Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_MT7988_H
|
||||
#define _DT_BINDINGS_CLK_MT7988_H
|
||||
|
||||
/* APMIXEDSYS */
|
||||
|
||||
#define CLK_APMIXED_NETSYSPLL 0
|
||||
#define CLK_APMIXED_MPLL 1
|
||||
#define CLK_APMIXED_MMPLL 2
|
||||
#define CLK_APMIXED_APLL2 3
|
||||
#define CLK_APMIXED_NET1PLL 4
|
||||
#define CLK_APMIXED_NET2PLL 5
|
||||
#define CLK_APMIXED_WEDMCUPLL 6
|
||||
#define CLK_APMIXED_SGMPLL 7
|
||||
#define CLK_APMIXED_ARM_B 8
|
||||
#define CLK_APMIXED_CCIPLL2_B 9
|
||||
#define CLK_APMIXED_USXGMIIPLL 10
|
||||
#define CLK_APMIXED_MSDCPLL 11
|
||||
|
||||
/* TOPCKGEN */
|
||||
|
||||
#define CLK_TOP_XTAL 0
|
||||
#define CLK_TOP_XTAL_D2 1
|
||||
#define CLK_TOP_RTC_32K 2
|
||||
#define CLK_TOP_RTC_32P7K 3
|
||||
#define CLK_TOP_MPLL_D2 4
|
||||
#define CLK_TOP_MPLL_D3_D2 5
|
||||
#define CLK_TOP_MPLL_D4 6
|
||||
#define CLK_TOP_MPLL_D8 7
|
||||
#define CLK_TOP_MPLL_D8_D2 8
|
||||
#define CLK_TOP_MMPLL_D2 9
|
||||
#define CLK_TOP_MMPLL_D3_D5 10
|
||||
#define CLK_TOP_MMPLL_D4 11
|
||||
#define CLK_TOP_MMPLL_D6_D2 12
|
||||
#define CLK_TOP_MMPLL_D8 13
|
||||
#define CLK_TOP_APLL2_D4 14
|
||||
#define CLK_TOP_NET1PLL_D4 15
|
||||
#define CLK_TOP_NET1PLL_D5 16
|
||||
#define CLK_TOP_NET1PLL_D5_D2 17
|
||||
#define CLK_TOP_NET1PLL_D5_D4 18
|
||||
#define CLK_TOP_NET1PLL_D8 19
|
||||
#define CLK_TOP_NET1PLL_D8_D2 20
|
||||
#define CLK_TOP_NET1PLL_D8_D4 21
|
||||
#define CLK_TOP_NET1PLL_D8_D8 22
|
||||
#define CLK_TOP_NET1PLL_D8_D16 23
|
||||
#define CLK_TOP_NET2PLL_D2 24
|
||||
#define CLK_TOP_NET2PLL_D4 25
|
||||
#define CLK_TOP_NET2PLL_D4_D4 26
|
||||
#define CLK_TOP_NET2PLL_D4_D8 27
|
||||
#define CLK_TOP_NET2PLL_D6 28
|
||||
#define CLK_TOP_NET2PLL_D8 29
|
||||
#define CLK_TOP_NETSYS_SEL 30
|
||||
#define CLK_TOP_NETSYS_500M_SEL 31
|
||||
#define CLK_TOP_NETSYS_2X_SEL 32
|
||||
#define CLK_TOP_NETSYS_GSW_SEL 33
|
||||
#define CLK_TOP_ETH_GMII_SEL 34
|
||||
#define CLK_TOP_NETSYS_MCU_SEL 35
|
||||
#define CLK_TOP_NETSYS_PAO_2X_SEL 36
|
||||
#define CLK_TOP_EIP197_SEL 37
|
||||
#define CLK_TOP_AXI_INFRA_SEL 38
|
||||
#define CLK_TOP_UART_SEL 39
|
||||
#define CLK_TOP_EMMC_250M_SEL 40
|
||||
#define CLK_TOP_EMMC_400M_SEL 41
|
||||
#define CLK_TOP_SPI_SEL 42
|
||||
#define CLK_TOP_SPIM_MST_SEL 43
|
||||
#define CLK_TOP_NFI1X_SEL 44
|
||||
#define CLK_TOP_SPINFI_SEL 45
|
||||
#define CLK_TOP_PWM_SEL 46
|
||||
#define CLK_TOP_I2C_SEL 47
|
||||
#define CLK_TOP_PCIE_MBIST_250M_SEL 48
|
||||
#define CLK_TOP_PEXTP_TL_SEL 49
|
||||
#define CLK_TOP_PEXTP_TL_P1_SEL 50
|
||||
#define CLK_TOP_PEXTP_TL_P2_SEL 51
|
||||
#define CLK_TOP_PEXTP_TL_P3_SEL 52
|
||||
#define CLK_TOP_USB_SYS_SEL 53
|
||||
#define CLK_TOP_USB_SYS_P1_SEL 54
|
||||
#define CLK_TOP_USB_XHCI_SEL 55
|
||||
#define CLK_TOP_USB_XHCI_P1_SEL 56
|
||||
#define CLK_TOP_USB_FRMCNT_SEL 57
|
||||
#define CLK_TOP_USB_FRMCNT_P1_SEL 58
|
||||
#define CLK_TOP_AUD_SEL 59
|
||||
#define CLK_TOP_A1SYS_SEL 60
|
||||
#define CLK_TOP_AUD_L_SEL 61
|
||||
#define CLK_TOP_A_TUNER_SEL 62
|
||||
#define CLK_TOP_SSPXTP_SEL 63
|
||||
#define CLK_TOP_USB_PHY_SEL 64
|
||||
#define CLK_TOP_USXGMII_SBUS_0_SEL 65
|
||||
#define CLK_TOP_USXGMII_SBUS_1_SEL 66
|
||||
#define CLK_TOP_SGM_0_SEL 67
|
||||
#define CLK_TOP_SGM_SBUS_0_SEL 68
|
||||
#define CLK_TOP_SGM_1_SEL 69
|
||||
#define CLK_TOP_SGM_SBUS_1_SEL 70
|
||||
#define CLK_TOP_XFI_PHY_0_XTAL_SEL 71
|
||||
#define CLK_TOP_XFI_PHY_1_XTAL_SEL 72
|
||||
#define CLK_TOP_SYSAXI_SEL 73
|
||||
#define CLK_TOP_SYSAPB_SEL 74
|
||||
#define CLK_TOP_ETH_REFCK_50M_SEL 75
|
||||
#define CLK_TOP_ETH_SYS_200M_SEL 76
|
||||
#define CLK_TOP_ETH_SYS_SEL 77
|
||||
#define CLK_TOP_ETH_XGMII_SEL 78
|
||||
#define CLK_TOP_BUS_TOPS_SEL 79
|
||||
#define CLK_TOP_NPU_TOPS_SEL 80
|
||||
#define CLK_TOP_DRAMC_SEL 81
|
||||
#define CLK_TOP_DRAMC_MD32_SEL 82
|
||||
#define CLK_TOP_INFRA_F26M_SEL 83
|
||||
#define CLK_TOP_PEXTP_P0_SEL 84
|
||||
#define CLK_TOP_PEXTP_P1_SEL 85
|
||||
#define CLK_TOP_PEXTP_P2_SEL 86
|
||||
#define CLK_TOP_PEXTP_P3_SEL 87
|
||||
#define CLK_TOP_DA_XTP_GLB_P0_SEL 88
|
||||
#define CLK_TOP_DA_XTP_GLB_P1_SEL 89
|
||||
#define CLK_TOP_DA_XTP_GLB_P2_SEL 90
|
||||
#define CLK_TOP_DA_XTP_GLB_P3_SEL 91
|
||||
#define CLK_TOP_CKM_SEL 92
|
||||
#define CLK_TOP_DA_SEL 93
|
||||
#define CLK_TOP_PEXTP_SEL 94
|
||||
#define CLK_TOP_TOPS_P2_26M_SEL 95
|
||||
#define CLK_TOP_MCUSYS_BACKUP_625M_SEL 96
|
||||
#define CLK_TOP_NETSYS_SYNC_250M_SEL 97
|
||||
#define CLK_TOP_MACSEC_SEL 98
|
||||
#define CLK_TOP_NETSYS_TOPS_400M_SEL 99
|
||||
#define CLK_TOP_NETSYS_PPEFB_250M_SEL 100
|
||||
#define CLK_TOP_NETSYS_WARP_SEL 101
|
||||
#define CLK_TOP_ETH_MII_SEL 102
|
||||
#define CLK_TOP_NPU_SEL 103
|
||||
#define CLK_TOP_AUD_I2S_M 104
|
||||
|
||||
/* MCUSYS */
|
||||
|
||||
#define CLK_MCU_BUS_DIV_SEL 0
|
||||
#define CLK_MCU_ARM_DIV_SEL 1
|
||||
|
||||
/* INFRACFG_AO */
|
||||
|
||||
#define CLK_INFRA_MUX_UART0_SEL 0
|
||||
#define CLK_INFRA_MUX_UART1_SEL 1
|
||||
#define CLK_INFRA_MUX_UART2_SEL 2
|
||||
#define CLK_INFRA_MUX_SPI0_SEL 3
|
||||
#define CLK_INFRA_MUX_SPI1_SEL 4
|
||||
#define CLK_INFRA_MUX_SPI2_SEL 5
|
||||
#define CLK_INFRA_PWM_SEL 6
|
||||
#define CLK_INFRA_PWM_CK1_SEL 7
|
||||
#define CLK_INFRA_PWM_CK2_SEL 8
|
||||
#define CLK_INFRA_PWM_CK3_SEL 9
|
||||
#define CLK_INFRA_PWM_CK4_SEL 10
|
||||
#define CLK_INFRA_PWM_CK5_SEL 11
|
||||
#define CLK_INFRA_PWM_CK6_SEL 12
|
||||
#define CLK_INFRA_PWM_CK7_SEL 13
|
||||
#define CLK_INFRA_PWM_CK8_SEL 14
|
||||
#define CLK_INFRA_PCIE_GFMUX_TL_O_P0_SEL 15
|
||||
#define CLK_INFRA_PCIE_GFMUX_TL_O_P1_SEL 16
|
||||
#define CLK_INFRA_PCIE_GFMUX_TL_O_P2_SEL 17
|
||||
#define CLK_INFRA_PCIE_GFMUX_TL_O_P3_SEL 18
|
||||
|
||||
/* INFRACFG */
|
||||
|
||||
#define CLK_INFRA_PCIE_PERI_26M_CK_P0 19
|
||||
#define CLK_INFRA_PCIE_PERI_26M_CK_P1 20
|
||||
#define CLK_INFRA_PCIE_PERI_26M_CK_P2 21
|
||||
#define CLK_INFRA_PCIE_PERI_26M_CK_P3 22
|
||||
#define CLK_INFRA_66M_GPT_BCK 23
|
||||
#define CLK_INFRA_66M_PWM_HCK 24
|
||||
#define CLK_INFRA_66M_PWM_BCK 25
|
||||
#define CLK_INFRA_66M_PWM_CK1 26
|
||||
#define CLK_INFRA_66M_PWM_CK2 27
|
||||
#define CLK_INFRA_66M_PWM_CK3 28
|
||||
#define CLK_INFRA_66M_PWM_CK4 29
|
||||
#define CLK_INFRA_66M_PWM_CK5 30
|
||||
#define CLK_INFRA_66M_PWM_CK6 31
|
||||
#define CLK_INFRA_66M_PWM_CK7 32
|
||||
#define CLK_INFRA_66M_PWM_CK8 33
|
||||
#define CLK_INFRA_133M_CQDMA_BCK 34
|
||||
#define CLK_INFRA_66M_AUD_SLV_BCK 35
|
||||
#define CLK_INFRA_AUD_26M 36
|
||||
#define CLK_INFRA_AUD_L 37
|
||||
#define CLK_INFRA_AUD_AUD 38
|
||||
#define CLK_INFRA_AUD_EG2 39
|
||||
#define CLK_INFRA_DRAMC_F26M 40
|
||||
#define CLK_INFRA_133M_DBG_ACKM 41
|
||||
#define CLK_INFRA_66M_AP_DMA_BCK 42
|
||||
#define CLK_INFRA_66M_SEJ_BCK 43
|
||||
#define CLK_INFRA_PRE_CK_SEJ_F13M 44
|
||||
#define CLK_INFRA_26M_THERM_SYSTEM 45
|
||||
#define CLK_INFRA_I2C_BCK 46
|
||||
#define CLK_INFRA_52M_UART0_CK 47
|
||||
#define CLK_INFRA_52M_UART1_CK 48
|
||||
#define CLK_INFRA_52M_UART2_CK 49
|
||||
#define CLK_INFRA_NFI 50
|
||||
#define CLK_INFRA_SPINFI 51
|
||||
#define CLK_INFRA_66M_NFI_HCK 52
|
||||
#define CLK_INFRA_104M_SPI0 53
|
||||
#define CLK_INFRA_104M_SPI1 54
|
||||
#define CLK_INFRA_104M_SPI2_BCK 55
|
||||
#define CLK_INFRA_66M_SPI0_HCK 56
|
||||
#define CLK_INFRA_66M_SPI1_HCK 57
|
||||
#define CLK_INFRA_66M_SPI2_HCK 58
|
||||
#define CLK_INFRA_66M_FLASHIF_AXI 59
|
||||
#define CLK_INFRA_RTC 60
|
||||
#define CLK_INFRA_26M_ADC_BCK 61
|
||||
#define CLK_INFRA_RC_ADC 62
|
||||
#define CLK_INFRA_MSDC400 63
|
||||
#define CLK_INFRA_MSDC2_HCK 64
|
||||
#define CLK_INFRA_133M_MSDC_0_HCK 65
|
||||
#define CLK_INFRA_66M_MSDC_0_HCK 66
|
||||
#define CLK_INFRA_133M_CPUM_BCK 67
|
||||
#define CLK_INFRA_BIST2FPC 68
|
||||
#define CLK_INFRA_I2C_X16W_MCK_CK_P1 69
|
||||
#define CLK_INFRA_I2C_X16W_PCK_CK_P1 70
|
||||
#define CLK_INFRA_133M_USB_HCK 71
|
||||
#define CLK_INFRA_133M_USB_HCK_CK_P1 72
|
||||
#define CLK_INFRA_66M_USB_HCK 73
|
||||
#define CLK_INFRA_66M_USB_HCK_CK_P1 74
|
||||
#define CLK_INFRA_USB_SYS 75
|
||||
#define CLK_INFRA_USB_SYS_CK_P1 76
|
||||
#define CLK_INFRA_USB_REF 77
|
||||
#define CLK_INFRA_USB_CK_P1 78
|
||||
#define CLK_INFRA_USB_FRMCNT 79
|
||||
#define CLK_INFRA_USB_FRMCNT_CK_P1 80
|
||||
#define CLK_INFRA_USB_PIPE 81
|
||||
#define CLK_INFRA_USB_PIPE_CK_P1 82
|
||||
#define CLK_INFRA_USB_UTMI 83
|
||||
#define CLK_INFRA_USB_UTMI_CK_P1 84
|
||||
#define CLK_INFRA_USB_XHCI 85
|
||||
#define CLK_INFRA_USB_XHCI_CK_P1 86
|
||||
#define CLK_INFRA_PCIE_GFMUX_TL_P0 87
|
||||
#define CLK_INFRA_PCIE_GFMUX_TL_P1 88
|
||||
#define CLK_INFRA_PCIE_GFMUX_TL_P2 89
|
||||
#define CLK_INFRA_PCIE_GFMUX_TL_P3 90
|
||||
#define CLK_INFRA_PCIE_PIPE_P0 91
|
||||
#define CLK_INFRA_PCIE_PIPE_P1 92
|
||||
#define CLK_INFRA_PCIE_PIPE_P2 93
|
||||
#define CLK_INFRA_PCIE_PIPE_P3 94
|
||||
#define CLK_INFRA_133M_PCIE_CK_P0 95
|
||||
#define CLK_INFRA_133M_PCIE_CK_P1 96
|
||||
#define CLK_INFRA_133M_PCIE_CK_P2 97
|
||||
#define CLK_INFRA_133M_PCIE_CK_P3 98
|
||||
|
||||
/* ETHDMA */
|
||||
|
||||
#define CLK_ETHDMA_XGP1_EN 0
|
||||
#define CLK_ETHDMA_XGP2_EN 1
|
||||
#define CLK_ETHDMA_XGP3_EN 2
|
||||
#define CLK_ETHDMA_FE_EN 3
|
||||
#define CLK_ETHDMA_GP2_EN 4
|
||||
#define CLK_ETHDMA_GP1_EN 5
|
||||
#define CLK_ETHDMA_GP3_EN 6
|
||||
#define CLK_ETHDMA_ESW_EN 7
|
||||
#define CLK_ETHDMA_CRYPT0_EN 8
|
||||
#define CLK_ETHDMA_NR_CLK 9
|
||||
|
||||
/* SGMIISYS_0 */
|
||||
|
||||
#define CLK_SGM0_TX_EN 0
|
||||
#define CLK_SGM0_RX_EN 1
|
||||
#define CLK_SGMII0_NR_CLK 2
|
||||
|
||||
/* SGMIISYS_1 */
|
||||
|
||||
#define CLK_SGM1_TX_EN 0
|
||||
#define CLK_SGM1_RX_EN 1
|
||||
#define CLK_SGMII1_NR_CLK 2
|
||||
|
||||
/* ETHWARP */
|
||||
|
||||
#define CLK_ETHWARP_WOCPU2_EN 0
|
||||
#define CLK_ETHWARP_WOCPU1_EN 1
|
||||
#define CLK_ETHWARP_WOCPU0_EN 2
|
||||
#define CLK_ETHWARP_NR_CLK 3
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_MT7988_H */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue