xref: /openbmc/linux/drivers/gpu/drm/i915/display/intel_dkl_phy.c (revision 9f771739a04919226081a107167596de75108fbb)
189cb0ba4SImre Deak // SPDX-License-Identifier: MIT
289cb0ba4SImre Deak /*
389cb0ba4SImre Deak  * Copyright © 2022 Intel Corporation
489cb0ba4SImre Deak  */
589cb0ba4SImre Deak 
689cb0ba4SImre Deak #include "i915_drv.h"
789cb0ba4SImre Deak #include "i915_reg.h"
889cb0ba4SImre Deak 
989cb0ba4SImre Deak #include "intel_de.h"
1089cb0ba4SImre Deak #include "intel_display.h"
1189cb0ba4SImre Deak #include "intel_dkl_phy.h"
12d69813c7SImre Deak #include "intel_dkl_phy_regs.h"
1389cb0ba4SImre Deak 
14*bfa010f6SJosé Roberto de Souza /**
15*bfa010f6SJosé Roberto de Souza  * intel_dkl_phy_init - initialize Dekel PHY
16*bfa010f6SJosé Roberto de Souza  * @i915: i915 device instance
17*bfa010f6SJosé Roberto de Souza  */
intel_dkl_phy_init(struct drm_i915_private * i915)18*bfa010f6SJosé Roberto de Souza void intel_dkl_phy_init(struct drm_i915_private *i915)
19*bfa010f6SJosé Roberto de Souza {
20*bfa010f6SJosé Roberto de Souza 	spin_lock_init(&i915->display.dkl.phy_lock);
21*bfa010f6SJosé Roberto de Souza }
22*bfa010f6SJosé Roberto de Souza 
2389cb0ba4SImre Deak static void
dkl_phy_set_hip_idx(struct drm_i915_private * i915,struct intel_dkl_phy_reg reg)24b8ed5533SImre Deak dkl_phy_set_hip_idx(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
2589cb0ba4SImre Deak {
2689cb0ba4SImre Deak 	enum tc_port tc_port = DKL_REG_TC_PORT(reg);
2789cb0ba4SImre Deak 
2889cb0ba4SImre Deak 	drm_WARN_ON(&i915->drm, tc_port < TC_PORT_1 || tc_port >= I915_MAX_TC_PORTS);
2989cb0ba4SImre Deak 
3089cb0ba4SImre Deak 	intel_de_write(i915,
3189cb0ba4SImre Deak 		       HIP_INDEX_REG(tc_port),
32b8ed5533SImre Deak 		       HIP_INDEX_VAL(tc_port, reg.bank_idx));
3389cb0ba4SImre Deak }
3489cb0ba4SImre Deak 
3589cb0ba4SImre Deak /**
3689cb0ba4SImre Deak  * intel_dkl_phy_read - read a Dekel PHY register
3789cb0ba4SImre Deak  * @i915: i915 device instance
3889cb0ba4SImre Deak  * @reg: Dekel PHY register
3989cb0ba4SImre Deak  *
4089cb0ba4SImre Deak  * Read the @reg Dekel PHY register.
4189cb0ba4SImre Deak  *
4289cb0ba4SImre Deak  * Returns the read value.
4389cb0ba4SImre Deak  */
4489cb0ba4SImre Deak u32
intel_dkl_phy_read(struct drm_i915_private * i915,struct intel_dkl_phy_reg reg)45b8ed5533SImre Deak intel_dkl_phy_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
4689cb0ba4SImre Deak {
4789cb0ba4SImre Deak 	u32 val;
4889cb0ba4SImre Deak 
4989cb0ba4SImre Deak 	spin_lock(&i915->display.dkl.phy_lock);
5089cb0ba4SImre Deak 
51b8ed5533SImre Deak 	dkl_phy_set_hip_idx(i915, reg);
52b8ed5533SImre Deak 	val = intel_de_read(i915, DKL_REG_MMIO(reg));
5389cb0ba4SImre Deak 
5489cb0ba4SImre Deak 	spin_unlock(&i915->display.dkl.phy_lock);
5589cb0ba4SImre Deak 
5689cb0ba4SImre Deak 	return val;
5789cb0ba4SImre Deak }
5889cb0ba4SImre Deak 
5989cb0ba4SImre Deak /**
6089cb0ba4SImre Deak  * intel_dkl_phy_write - write a Dekel PHY register
6189cb0ba4SImre Deak  * @i915: i915 device instance
6289cb0ba4SImre Deak  * @reg: Dekel PHY register
6389cb0ba4SImre Deak  * @val: value to write
6489cb0ba4SImre Deak  *
6589cb0ba4SImre Deak  * Write @val to the @reg Dekel PHY register.
6689cb0ba4SImre Deak  */
6789cb0ba4SImre Deak void
intel_dkl_phy_write(struct drm_i915_private * i915,struct intel_dkl_phy_reg reg,u32 val)68b8ed5533SImre Deak intel_dkl_phy_write(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 val)
6989cb0ba4SImre Deak {
7089cb0ba4SImre Deak 	spin_lock(&i915->display.dkl.phy_lock);
7189cb0ba4SImre Deak 
72b8ed5533SImre Deak 	dkl_phy_set_hip_idx(i915, reg);
73b8ed5533SImre Deak 	intel_de_write(i915, DKL_REG_MMIO(reg), val);
7489cb0ba4SImre Deak 
7589cb0ba4SImre Deak 	spin_unlock(&i915->display.dkl.phy_lock);
7689cb0ba4SImre Deak }
7789cb0ba4SImre Deak 
7889cb0ba4SImre Deak /**
7989cb0ba4SImre Deak  * intel_dkl_phy_rmw - read-modify-write a Dekel PHY register
8089cb0ba4SImre Deak  * @i915: i915 device instance
8189cb0ba4SImre Deak  * @reg: Dekel PHY register
8289cb0ba4SImre Deak  * @clear: mask to clear
8389cb0ba4SImre Deak  * @set: mask to set
8489cb0ba4SImre Deak  *
8589cb0ba4SImre Deak  * Read the @reg Dekel PHY register, clearing then setting the @clear/@set bits in it, and writing
8689cb0ba4SImre Deak  * this value back to the register if the value differs from the read one.
8789cb0ba4SImre Deak  */
8889cb0ba4SImre Deak void
intel_dkl_phy_rmw(struct drm_i915_private * i915,struct intel_dkl_phy_reg reg,u32 clear,u32 set)89b8ed5533SImre Deak intel_dkl_phy_rmw(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg, u32 clear, u32 set)
9089cb0ba4SImre Deak {
9189cb0ba4SImre Deak 	spin_lock(&i915->display.dkl.phy_lock);
9289cb0ba4SImre Deak 
93b8ed5533SImre Deak 	dkl_phy_set_hip_idx(i915, reg);
94b8ed5533SImre Deak 	intel_de_rmw(i915, DKL_REG_MMIO(reg), clear, set);
9589cb0ba4SImre Deak 
9689cb0ba4SImre Deak 	spin_unlock(&i915->display.dkl.phy_lock);
9789cb0ba4SImre Deak }
9889cb0ba4SImre Deak 
9989cb0ba4SImre Deak /**
10089cb0ba4SImre Deak  * intel_dkl_phy_posting_read - do a posting read from a Dekel PHY register
10189cb0ba4SImre Deak  * @i915: i915 device instance
10289cb0ba4SImre Deak  * @reg: Dekel PHY register
10389cb0ba4SImre Deak  *
10489cb0ba4SImre Deak  * Read the @reg Dekel PHY register without returning the read value.
10589cb0ba4SImre Deak  */
10689cb0ba4SImre Deak void
intel_dkl_phy_posting_read(struct drm_i915_private * i915,struct intel_dkl_phy_reg reg)107b8ed5533SImre Deak intel_dkl_phy_posting_read(struct drm_i915_private *i915, struct intel_dkl_phy_reg reg)
10889cb0ba4SImre Deak {
10989cb0ba4SImre Deak 	spin_lock(&i915->display.dkl.phy_lock);
11089cb0ba4SImre Deak 
111b8ed5533SImre Deak 	dkl_phy_set_hip_idx(i915, reg);
112b8ed5533SImre Deak 	intel_de_posting_read(i915, DKL_REG_MMIO(reg));
11389cb0ba4SImre Deak 
11489cb0ba4SImre Deak 	spin_unlock(&i915->display.dkl.phy_lock);
11589cb0ba4SImre Deak }
116